[
  {
    "path": ".changes/0.0.0.md",
    "content": "## Previous Releases\n\nFor information on prior major and minor releases, see their changelogs:\n\n\n* [1.10](https://github.com/dbt-labs/dbt-core/blob/1.10.latest/CHANGELOG.md)\n* [1.9](https://github.com/dbt-labs/dbt-core/blob/1.9.latest/CHANGELOG.md)\n* [1.8](https://github.com/dbt-labs/dbt-core/blob/1.8.latest/CHANGELOG.md)\n* [1.7](https://github.com/dbt-labs/dbt-core/blob/1.7.latest/CHANGELOG.md)\n* [1.6](https://github.com/dbt-labs/dbt-core/blob/1.6.latest/CHANGELOG.md)\n* [1.5](https://github.com/dbt-labs/dbt-core/blob/1.5.latest/CHANGELOG.md)\n* [1.4](https://github.com/dbt-labs/dbt-core/blob/1.4.latest/CHANGELOG.md)\n* [1.3](https://github.com/dbt-labs/dbt-core/blob/1.3.latest/CHANGELOG.md)\n* [1.2](https://github.com/dbt-labs/dbt-core/blob/1.2.latest/CHANGELOG.md)\n* [1.1](https://github.com/dbt-labs/dbt-core/blob/1.1.latest/CHANGELOG.md)\n* [1.0](https://github.com/dbt-labs/dbt-core/blob/1.0.latest/CHANGELOG.md)\n* [0.21](https://github.com/dbt-labs/dbt-core/blob/0.21.latest/CHANGELOG.md)\n* [0.20](https://github.com/dbt-labs/dbt-core/blob/0.20.latest/CHANGELOG.md)\n* [0.19](https://github.com/dbt-labs/dbt-core/blob/0.19.latest/CHANGELOG.md)\n* [0.18](https://github.com/dbt-labs/dbt-core/blob/0.18.latest/CHANGELOG.md)\n* [0.17](https://github.com/dbt-labs/dbt-core/blob/0.17.latest/CHANGELOG.md)\n* [0.16](https://github.com/dbt-labs/dbt-core/blob/0.16.latest/CHANGELOG.md)\n* [0.15](https://github.com/dbt-labs/dbt-core/blob/0.15.latest/CHANGELOG.md)\n* [0.14](https://github.com/dbt-labs/dbt-core/blob/0.14.latest/CHANGELOG.md)\n* [0.13](https://github.com/dbt-labs/dbt-core/blob/0.13.latest/CHANGELOG.md)\n* [0.12](https://github.com/dbt-labs/dbt-core/blob/0.12.latest/CHANGELOG.md)\n* [0.11 and earlier](https://github.com/dbt-labs/dbt-core/blob/0.11.latest/CHANGELOG.md)\n"
  },
  {
    "path": ".changes/README.md",
    "content": "# CHANGELOG Automation\n\nWe use [changie](https://changie.dev/) to automate `CHANGELOG` generation.  For installation and format/command specifics, see the documentation.\n\n### Quick Tour\n\n- All new change entries get generated under `/.changes/unreleased` as a yaml file\n- `header.tpl.md` contains the contents of the entire CHANGELOG file\n- `0.0.0.md` contains the contents of the footer for the entire CHANGELOG file.  changie looks to be in the process of supporting a footer file the same as it supports a header file.  Switch to that when available.  For now, the 0.0.0 in the file name forces it to the bottom of the changelog no matter what version we are releasing.\n- `.changie.yaml` contains the fields in a change, the format of a single change, as well as the format of the Contributors section for each version.\n\n### Workflow\n\n#### Daily workflow\nAlmost every code change we make associated with an issue will require a `CHANGELOG` entry.  After you have created the PR in GitHub, run `changie new` and follow the command prompts to generate a yaml file with your change details.  This only needs to be done once per PR.\n\nThe `changie new` command will ensure correct file format and file name.  There is a one to one mapping of issues to changes.  Multiple issues cannot be lumped into a single entry. If you make a mistake, the yaml file may be directly modified and saved as long as the format is preserved.\n\nNote: If your PR has been cleared by the Core Team as not needing a changelog entry, the `Skip Changelog` label may be put on the PR to bypass the GitHub action that blacks PRs from being merged when they are missing a `CHANGELOG` entry.\n\n#### Prerelease Workflow\nThese commands batch up changes in `/.changes/unreleased` to be included in this prerelease and move those files to a directory named for the release version.  The `--move-dir` will be created if it does not exist and is created in `/.changes`.\n\n```\nchangie batch <version>  --move-dir '<version>' --prerelease 'rc1'\nchangie merge\n```\n\nExample\n```\nchangie batch 1.0.5  --move-dir '1.0.5' --prerelease 'rc1'\nchangie merge\n```\n\n#### Final Release Workflow\nThese commands batch up changes in `/.changes/unreleased` as well as `/.changes/<version>` to be included in this final release and delete all prereleases.  This rolls all prereleases up into a single final release.  All `yaml` files in `/unreleased` and `<version>` will be deleted at this point.\n\n```\nchangie batch <version>  --include '<version>' --remove-prereleases\nchangie merge\n```\n\nExample\n```\nchangie batch 1.0.5  --include '1.0.5' --remove-prereleases\nchangie merge\n```\n\n### A Note on Manual Edits & Gotchas\n- Changie generates markdown files in the `.changes` directory that are parsed together with the `changie merge` command.  Every time `changie merge` is run, it regenerates the entire file.  For this reason, any changes made directly to `CHANGELOG.md` will be overwritten on the next run of `changie merge`.\n- If changes need to be made to the `CHANGELOG.md`, make the changes to the relevant `<version>.md` file located in the `/.changes` directory.  You will then run `changie merge` to regenerate the `CHANGELOG.MD`.\n- Do not run `changie batch` again on released versions.  Our final release workflow deletes all of the yaml files associated with individual changes.  If for some reason modifications to the `CHANGELOG.md` are required after we've generated the final release `CHANGELOG.md`, the modifications need to be done manually to the `<version>.md` file in the `/.changes` directory.\n- changie can modify, create and delete files depending on the command you run.  This is expected.  Be sure to commit everything that has been modified and deleted.\n"
  },
  {
    "path": ".changes/header.tpl.md",
    "content": "# dbt Core Changelog\n\n- This file provides a full account of all changes to `dbt-core`\n- Changes are listed under the (pre)release in which they first appear. Subsequent releases include changes from previous releases.\n- \"Breaking changes\" listed under a version may require action from end users or external maintainers when upgrading to that version.\n- Do not edit this file directly. This file is auto-generated using [changie](https://github.com/miniscruff/changie). For details on how to document a change, see [the contributing guide](https://github.com/dbt-labs/dbt-core/blob/main/CONTRIBUTING.md#adding-changelog-entry)\n"
  },
  {
    "path": ".changes/unreleased/.gitkeep",
    "content": ""
  },
  {
    "path": ".changes/unreleased/Dependencies-20251118-155354.yaml",
    "content": "kind: Dependencies\nbody: Use EventCatcher from dbt-common instead of maintaining a local copy\ntime: 2025-11-18T15:53:54.284561+05:30\ncustom:\n    Author: 3loka\n    Issue: \"12124\"\n"
  },
  {
    "path": ".changes/unreleased/Dependencies-20251217-151349.yaml",
    "content": "kind: Dependencies\nbody: Upgrading dbt-semantic-interfaces to 0.10.x\ntime: 2025-12-17T15:13:49.721737-05:00\ncustom:\n    Author: WilliamDee\n    Issue: None\n"
  },
  {
    "path": ".changes/unreleased/Dependencies-20251219-153804.yaml",
    "content": "kind: Dependencies\nbody: Bump minimum click to 8.2.0\ntime: 2025-12-19T15:38:04.785842-06:00\ncustom:\n  Author: QMalcolm\n  Issue: \"12305\"\n"
  },
  {
    "path": ".changes/unreleased/Dependencies-20260113-135442.yaml",
    "content": "kind: Dependencies\nbody: Bump DSI minimum to 0.10.2\ntime: 2026-01-13T13:54:42.340193-06:00\ncustom:\n  Author: QMalcolm\n  Issue: NA\n"
  },
  {
    "path": ".changes/unreleased/Dependencies-20260113-143057.yaml",
    "content": "kind: Dependencies\nbody: Bump dbt-protos minimum to 1.0.418\ntime: 2026-01-13T14:30:57.311017-06:00\ncustom:\n  Author: QMalcolm\n  Issue: NA\n"
  },
  {
    "path": ".changes/unreleased/Dependencies-20260121-171712.yaml",
    "content": "kind: Dependencies\nbody: Move `click` minimum to 8.3.0\ntime: 2026-01-21T17:17:12.251254-06:00\ncustom:\n  Author: QMalcolm\n  Issue: \"12378\"\n"
  },
  {
    "path": ".changes/unreleased/Dependencies-20260302-130425.yaml",
    "content": "kind: Dependencies\nbody: Bump minimum version of dbt-common to 1.37.3\ntime: 2026-03-02T13:04:25.495699-05:00\ncustom:\n  Author: emmyoop\n  Issue: \"12575\"\n"
  },
  {
    "path": ".changes/unreleased/Docs-20240311-140344.yaml",
    "content": "kind: Docs\nbody: Enable display of unit tests\ntime: 2024-03-11T14:03:44.490834-04:00\ncustom:\n  Author: gshank\n  Issue: \"501\"\n"
  },
  {
    "path": ".changes/unreleased/Docs-20240501-021050.yaml",
    "content": "kind: Docs\nbody: Unit tests not rendering\ntime: 2024-05-01T02:10:50.987412+02:00\ncustom:\n  Author: aranke\n  Issue: \"506\"\n"
  },
  {
    "path": ".changes/unreleased/Docs-20240516-223036.yaml",
    "content": "kind: Docs\nbody: Add support for Saved Query node\ntime: 2024-05-16T22:30:36.206492-07:00\ncustom:\n  Author: ChenyuLInx\n  Issue: \"486\"\n"
  },
  {
    "path": ".changes/unreleased/Docs-20240613-151048.yaml",
    "content": "kind: Docs\nbody: Fix npm security vulnerabilities as of June 2024\ntime: 2024-06-13T15:10:48.301989+01:00\ncustom:\n    Author: aranke\n    Issue: \"513\"\n"
  },
  {
    "path": ".changes/unreleased/Docs-20250728-162542.yaml",
    "content": "kind: Docs\nbody: Bump form-data from 3.0.1 to 3.0.4\ntime: 2025-07-28T16:25:42.452808-04:00\ncustom:\n    Author: michelleark\n    Issue: \"554\"\n"
  },
  {
    "path": ".changes/unreleased/Docs-20260319-112630.yaml",
    "content": "kind: Docs\nbody: Add support for UDF (function) resource type in lineage graph\ntime: 2026-03-19T11:26:30.338385+05:30\ncustom:\n    Author: aahel\n    Issue: \"574\"\n"
  },
  {
    "path": ".changes/unreleased/Features-20251006-140352.yaml",
    "content": "kind: Features\nbody: Support partial parsing for function nodes\ntime: 2025-10-06T14:03:52.258104-05:00\ncustom:\n  Author: QMalcolm\n  Issue: \"12072\"\n"
  },
  {
    "path": ".changes/unreleased/Features-20251111-103504.yaml",
    "content": "kind: Features\nbody: Add UnparsedMetricV2 to read in new-style YAML Semantic Layer Metrics.\ntime: 2025-11-11T10:35:04.123144-08:00\ncustom:\n    Author: theyostalservice\n    Issue: \"12157\"\n"
  },
  {
    "path": ".changes/unreleased/Features-20251117-141053.yaml",
    "content": "kind: Features\nbody: Allow for defining funciton arguments with default values\ntime: 2025-11-17T14:10:53.860178-06:00\ncustom:\n  Author: QMalcolm\n  Issue: \"12044\"\n"
  },
  {
    "path": ".changes/unreleased/Features-20251201-165209.yaml",
    "content": "kind: Features\nbody: Raise jsonschema-based deprecation warnings by default\ntime: 2025-12-01T16:52:09.354436-05:00\ncustom:\n    Author: michelleark\n    Issue: 12240\n"
  },
  {
    "path": ".changes/unreleased/Features-20251203-122926.yaml",
    "content": "kind: Features\nbody: ':bug: :snowman: Disable unit tests whose model is disabled'\ntime: 2025-12-03T12:29:26.209248-05:00\ncustom:\n    Author: michelleark\n    Issue: \"10540\"\n"
  },
  {
    "path": ".changes/unreleased/Features-20251210-202001.yaml",
    "content": "kind: Features\nbody: Implement config.meta_get and config.meta_require\ntime: 2025-12-10T20:20:01.354288-05:00\ncustom:\n    Author: gshank\n    Issue: \"12012\"\n"
  },
  {
    "path": ".changes/unreleased/Features-20260115-131115.yaml",
    "content": "kind: Features\nbody: Deprecate null return values from generate_schema_name macro, behind require_valid_schema_from_generate_schema_name flag\ntime: 2026-01-15T13:11:15.787477-05:00\ncustom:\n    Author: michelleark\n    Issue: \"12347\"\n"
  },
  {
    "path": ".changes/unreleased/Features-20260119-210143.yaml",
    "content": "kind: Features\nbody: Add ability to indicate dbt Model also represents a Semantic Model. (Not fully supported yet.)\ntime: 2026-01-19T21:01:43.917805-08:00\ncustom:\n    Author: theyostalservice\n    Issue: .\n"
  },
  {
    "path": ".changes/unreleased/Features-20260123-173805.yaml",
    "content": "kind: Features\nbody: Added ability to parse semantic layer dimensions added to columns as part of new YAML. (Not ready for use until more of the new yaml is implemented.)\ntime: 2026-01-23T17:38:05.847998-08:00\ncustom:\n    Author: theyostalservice\n    Issue: .\n"
  },
  {
    "path": ".changes/unreleased/Features-20260126-164458.yaml",
    "content": "kind: Features\nbody: Add parsing for new YAML for semantic layer entities attached to dbt models.\ntime: 2026-01-26T16:44:58.041234-08:00\ncustom:\n    Author: theyostalservice\n    Issue: \"12395\"\n"
  },
  {
    "path": ".changes/unreleased/Features-20260127-114149.yaml",
    "content": "kind: Features\nbody: Process semantic metrics in v2 YAML if they are not merged into a model.\ntime: 2026-01-27T11:41:49.912438-08:00\ncustom:\n    Author: theyostalservice\n    Issue: \"12161\"\n"
  },
  {
    "path": ".changes/unreleased/Features-20260127-214617.yaml",
    "content": "kind: Features\nbody: Add parsing for v2 metrics on models and finish implementing their dependency behaviors.\ntime: 2026-01-27T21:46:17.985044-08:00\ncustom:\n    Author: theyostalservice\n    Issue: \"12397\"\n"
  },
  {
    "path": ".changes/unreleased/Features-20260128-125727.yaml",
    "content": "kind: Features\nbody: Add the ability to process derived semantic entities to dbt models, as required by new YAML schema.\ntime: 2026-01-28T12:57:27.576354-08:00\ncustom:\n    Author: theyostalservice\n    Issue: \"12401\"\n"
  },
  {
    "path": ".changes/unreleased/Features-20260128-172052.yaml",
    "content": "kind: Features\nbody: Enable parsing derived dimensions for v2 semantic layer YAML.\ntime: 2026-01-28T17:20:52.400188-08:00\ncustom:\n    Author: theyostalservice\n    Issue: \"12404\"\n"
  },
  {
    "path": ".changes/unreleased/Features-20260129-110711.yaml",
    "content": "kind: Features\nbody: Add unit tests to the Jinja `graph` object, enabling tools like dbt-project-evaluator to run checks on unit tests.\ntime: 2026-01-29T11:00:00.000000-08:00\ncustom:\n    Author: b-per\n    Issue: \"12033\"\n"
  },
  {
    "path": ".changes/unreleased/Features-20260129-114832.yaml",
    "content": "kind: Features\nbody: Implement agg_time_dimension for new semantic YAML.\ntime: 2026-01-29T11:48:32.100015-08:00\ncustom:\n    Author: theyostalservice\n    Issue: \"12410\"\n"
  },
  {
    "path": ".changes/unreleased/Features-20260129-175432.yaml",
    "content": "kind: Features\nbody: Implement parsing of semantic model object-style configuration in v2 semantic YAML.\ntime: 2026-01-29T17:54:32.188082-08:00\ncustom:\n    Author: theyostalservice\n    Issue: \"12413\"\n"
  },
  {
    "path": ".changes/unreleased/Features-20260129-185659.yaml",
    "content": "kind: Features\nbody: Implement primary_entity field for semantic models in semantic YAML v2.\ntime: 2026-01-29T18:56:59.184109-08:00\ncustom:\n    Author: theyostalservice\n    Issue: \"12414\"\n"
  },
  {
    "path": ".changes/unreleased/Features-20260205-105228.yaml",
    "content": "kind: Features\nbody: add config.meta_get to python model parsing\ntime: 2026-02-05T10:52:28.269954-08:00\ncustom:\n    Author: venkaa28\n    Issue: \"12458\"\n"
  },
  {
    "path": ".changes/unreleased/Features-20260212-232728.yaml",
    "content": "kind: Features\nbody: Added support for vars.yml to declare project variables\ntime: 2026-02-12T23:27:28.294557+05:30\ncustom:\n    Author: sriramr98\n    Issue: 11144 2955\n"
  },
  {
    "path": ".changes/unreleased/Features-20260219-133321.yaml",
    "content": "kind: Features\nbody: execute dbt debug logic after creating a new project in dbt init\ntime: 2026-02-19T13:33:21.891997+05:30\ncustom:\n    Author: sriramr98\n    Issue: \"12510\"\n"
  },
  {
    "path": ".changes/unreleased/Features-20260302-123311.yaml",
    "content": "kind: Features\nbody: Write compiled SQL for snapshots to target/compiled/ during dbt compile\ntime: 2026-03-02T12:33:11.456829+05:30\ncustom:\n    Author: aahel\n    Issue: \"7867\"\n"
  },
  {
    "path": ".changes/unreleased/Features-20260303-214328.yaml",
    "content": "kind: Features\nbody: Add \"selector\" selector method\ntime: 2026-03-03T21:43:28.02659+05:30\ncustom:\n    Author: ash2shukla\n    Issue: \"5009\"\n"
  },
  {
    "path": ".changes/unreleased/Features-9041.yaml",
    "content": "kind: Features\nbody: Add directory change instruction after dbt init\ntime: 2025-11-20T00:00:00Z\ncustom:\n  Author: kalluripradeep\n  Issue: \"9041\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20250922-151726.yaml",
    "content": "kind: Fixes\nbody: Address Click 8.2+ deprecation warning\ntime: 2025-09-22T15:17:26.983151-06:00\ncustom:\n    Author: edgarrmondragon\n    Issue: \"12038\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20251117-140649.yaml",
    "content": "kind: Fixes\nbody: Include macros in unit test parsing\ntime: 2025-11-17T14:06:49.518566-05:00\ncustom:\n    Author: michelleark nathanskone\n    Issue: \"10157\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20251117-185025.yaml",
    "content": "kind: Fixes\nbody: Allow dbt deps to run when vars lack defaults in dbt_project.yml\ntime: 2025-11-17T18:50:25.759091+05:30\ncustom:\n    Author: 3loka\n    Issue: \"8913\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20251118-171106.yaml",
    "content": "kind: Fixes\nbody: Restore DuplicateResourceNameError for intra-project node name duplication, behind behavior flag `require_unique_project_resource_names`\ntime: 2025-11-18T17:11:06.454784-05:00\ncustom:\n    Author: michelleark\n    Issue: \"12152\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20251119-195034.yaml",
    "content": "kind: Fixes\nbody: Allow the usage of `function` with `--exclude-resource-type` flag\ntime: 2025-11-19T19:50:34.703236-06:00\ncustom:\n  Author: QMalcolm\n  Issue: \"12143\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20251124-155629.yaml",
    "content": "kind: Fixes\nbody: Fix bug where schemas of functions weren't guaranteed to exist\ntime: 2025-11-24T15:56:29.467004-06:00\ncustom:\n  Author: QMalcolm\n  Issue: \"12142\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20251124-155756.yaml",
    "content": "kind: Fixes\nbody: Fix generation of deprecations summary\ntime: 2025-11-24T15:57:56.544123-08:00\ncustom:\n    Author: asiunov\n    Issue: \"12146\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20251124-170855.yaml",
    "content": "kind: Fixes\nbody: ':bug: :snowman: Correctly reference foreign key references when --defer and --state provided'\ntime: 2025-11-24T17:08:55.387946-05:00\ncustom:\n    Author: michellark\n    Issue: \"11885\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20251125-120246.yaml",
    "content": "kind: Fixes\nbody: ':bug: :snowman: Add exception when using --state and referring to a removed\n  test'\ntime: 2025-11-25T12:02:46.635026-05:00\ncustom:\n  Author: emmyoop\n  Issue: \"10630\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20251125-122020.yaml",
    "content": "kind: Fixes\nbody: ':bug: :snowman: Stop emitting `NoNodesForSelectionCriteria` three times during `build` command'\ntime: 2025-11-25T12:20:20.132379-06:00\ncustom:\n  Author: QMalcolm\n  Issue: \"11627\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20251127-141308.yaml",
    "content": "kind: Fixes\nbody: \":bug: :snowman: Fix long Python stack traces appearing when package dependencies have incompatible version requirements\"\ntime: 2025-11-27T14:13:08.082542-05:00\ncustom:\n  Author: emmyoop\n  Issue: \"12049\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20251127-145929.yaml",
    "content": "kind: Fixes\nbody: ':bug: :snowman: Fixed issue where changing data type size/precision/scale (e.g.,\n  varchar(3) to varchar(10)) incorrectly triggered a breaking change error fo'\ntime: 2025-11-27T14:59:29.256274-05:00\ncustom:\n  Author: emmyoop\n  Issue: \"11186\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20251127-170124.yaml",
    "content": "kind: Fixes\nbody: ':bug: :snowman: Support unit testing models that depend on sources with the same name'\ntime: 2025-11-27T17:01:24.193516-05:00\ncustom:\n    Author: michelleark\n    Issue: 11975 10433\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20251128-102129.yaml",
    "content": "kind: Fixes\nbody: Fix bug in partial parsing when updating a model with a schema file that is referenced by a singular test\ntime: 2025-11-28T10:21:29.911147Z\ncustom:\n    Author: mattogburke\n    Issue: \"12223\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20251128-122838.yaml",
    "content": "kind: Fixes\nbody: ':bug: :snowman: Avoid retrying successful run-operation commands'\ntime: 2025-11-28T12:28:38.546261-05:00\ncustom:\n    Author: michelleark\n    Issue: \"11850\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20251128-161937.yaml",
    "content": "kind: Fixes\nbody: ':bug: :snowman: Fix `dbt deps --add-package` crash when packages.yml contains `warn-unpinned:\n  false`'\ntime: 2025-11-28T16:19:37.608722-05:00\ncustom:\n  Author: emmyoop\n  Issue: \"9104\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20251128-163144.yaml",
    "content": "kind: Fixes\nbody: ':bug: :snowman: Improve `dbt deps --add-package` duplicate detection with better\n  cross-source matching and word boundaries'\ntime: 2025-11-28T16:31:44.344099-05:00\ncustom:\n  Author: emmyoop\n  Issue: \"12239\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20251202-133705.yaml",
    "content": "kind: Fixes\nbody: ':bug: :snowman: Fix false positive deprecation warning of pre/post-hook SQL configs'\ntime: 2025-12-02T13:37:05.012112-05:00\ncustom:\n    Author: michelleark\n    Issue: \"12244\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20251204-094753.yaml",
    "content": "kind: Fixes\nbody: ':bug: :snowman: Fix ref resolution within package when duplicate nodes exist, behind require_ref_searches_node_package_before_root behavior change flag'\ntime: 2025-12-04T09:47:53.349428-08:00\ncustom:\n    Author: michelleark\n    Issue: \"11351\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20251209-175031.yaml",
    "content": "kind: Fixes\nbody: Ensure recent deprecation warnings include event name in message\ntime: 2025-12-09T17:50:31.334618-06:00\ncustom:\n  Author: QMalcolm\n  Issue: \"12264\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20251210-143935.yaml",
    "content": "kind: Fixes\nbody: Improve error message clarity when detecting nodes with space in name\ntime: 2025-12-10T14:39:35.107841-08:00\ncustom:\n    Author: michelleark\n    Issue: \"11835\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20251216-120727.yaml",
    "content": "kind: Fixes\nbody: ':bug: :snowman:Propagate exceptions for NodeFinished callbacks in dbtRunner'\ntime: 2025-12-16T12:07:27.576087-05:00\ncustom:\n    Author: michelleark\n    Issue: \"11612\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20251217-002813.yaml",
    "content": "kind: Fixes\nbody: Adds omitted return statement to RuntimeConfigObject.meta_require method\ntime: 2025-12-17T00:28:13.015416197Z\ncustom:\n    Author: mjsqu\n    Issue: \"12288\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20251217-105918.yaml",
    "content": "kind: Fixes\nbody: Do not raise deprecation warning when encountering dataset or project configs for bigquery\ntime: 2025-12-17T10:59:18.372968-05:00\ncustom:\n    Author: michelleark\n    Issue: \"12285\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20251219-184405.yaml",
    "content": "kind: Fixes\nbody: Pin sqlparse <0.5.5 to avoid max tokens issue\ntime: 2025-12-19T18:44:05.216329-05:00\ncustom:\n    Author: michelleark\n    Issue: \"12303\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20260109-141332.yaml",
    "content": "kind: Fixes\nbody: Avoid deadlock edgecases of concurret microbatch/batch execution\ntime: 2026-01-09T14:13:32.777942-06:00\ncustom:\n  Author: QMalcolm\n  Issue: \"11420\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20260113-161742.yaml",
    "content": "kind: Fixes\nbody: Begin emitting deprecation warnings for DSI produced ValidationFutureError issues\ntime: 2026-01-13T16:17:42.988355-06:00\ncustom:\n  Author: QMalcolm\n  Issue: NA\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20260124-212300.yaml",
    "content": "kind: Fixes\nbody: Add @requires.catalogs decorator to compile command to fix REST Catalog-Linked database compilation\ntime: 2026-01-24T21:23:00.00000Z\ncustom:\n  Author: kalluripradeep\n  Issue: \"12353\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20260125-113244.yaml",
    "content": "kind: Fixes\nbody: Validate and filter out non-existent columns from seed column types\ntime: 2026-01-25T11:32:44.5200661+05:30\ncustom:\n    Author: abhishek09827\n    Issue: 12379\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20260126-160659.yaml",
    "content": "kind: Fixes\nbody: 'Fix false deprecation warning '\ntime: 2026-01-26T16:06:59.0157-05:00\ncustom:\n    Author: alexaustin007\n    Issue: \"12327\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20260202-123453.yaml",
    "content": "kind: Fixes\nbody: Return correctly resolved project path when changing dirs\ntime: 2026-02-02T12:34:53.454501+05:30\ncustom:\n    Author: ash2shukla\n    Issue: \"9138\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20260202-153835.yaml",
    "content": "kind: Fixes\nbody: Normalize whitespace prior to computing partial parsing checksum when loading model files\ntime: 2026-02-02T15:38:35.220621-05:00\ncustom:\n    Author: michelleark\n    Issue: \"12432\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20260204-184553.yaml",
    "content": "kind: Fixes\nbody: Stop raising deprecation warnings for internal python model configs\ntime: 2026-02-04T18:45:53.094578-06:00\ncustom:\n  Author: QMalcolm\n  Issue: \"12314\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20260204-211128.yaml",
    "content": "kind: Fixes\nbody: Dont fire config problem event if loaded_at_query is defined for adapters that dont support metadata-based freshness\ntime: 2026-02-04T21:11:28.218659+05:30\ncustom:\n    Author: ash2shukla\n    Issue: \"12451\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20260205-120000.yaml",
    "content": "kind: Fixes\nbody: Fix foreign key constraint ref() resolving to deferred relation even when target model is selected for build\ntime: 2026-02-05T12:00:00.00000Z\ncustom:\n  Author: b-per\n  Issue: \"12455\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20260206-204257.yaml",
    "content": "kind: Fixes\nbody: Skip raising `CustomKeyInConfigDeprecation` for config key alias in sql\ntime: 2026-02-06T20:42:57.134627+05:30\ncustom:\n    Author: ash2shukla\n    Issue: \"12396\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20260210-154042.yaml",
    "content": "kind: Fixes\nbody: Provide user-friendly validations that dimensions with 'validity_params' also have granularities.\ntime: 2026-02-10T15:40:42.808774-08:00\ncustom:\n    Author: theyostalservice\n    Issue: \"12473\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20260216-230817.yaml",
    "content": "kind: Fixes\nbody: Use resolved profile and target names to allow partial parsing for default profile and target\ntime: 2026-02-16T23:08:17.820862+05:30\ncustom:\n    Author: akshatha-code71 ash2shukla\n    Issue: \"7612\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20260219-012414.yaml",
    "content": "kind: Fixes\nbody: Ensure that all locked packages are installed in packages directory\ntime: 2026-02-19T01:24:14.439093+05:30\ncustom:\n    Author: ash2shukla\n    Issue: 12509\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20260219-131833.yaml",
    "content": "kind: Fixes\nbody: Correctly map 'hidden' field of metrics to 'is_private' field in manifests.\ntime: 2026-02-19T13:18:33.912843-08:00\ncustom:\n    Author: theyostalservice\n    Issue: \"12518\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20260219-170000.yaml",
    "content": "kind: Fixes\nbody: Set expr to column name for column-based dimensions and entities when the semantic layer name differs from the column name, so MetricFlow queries the correct warehouse column\ntime: 2026-02-19T17:00:00.000000+00:00\ncustom:\n    Author: b-per\n    Issue: \"12512\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20260223-132342.yaml",
    "content": "kind: Fixes\nbody: Fix Dimension() jinja in nested metric filters (input_metrics, numerator, denominator) being incorrectly rendered during YAML parsing for v2 semantic layer schema\ntime: 2026-02-23T13:23:42.353928-08:00\ncustom:\n    Author: theyostalservice\n    Issue: 12529\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20260223-161820.yaml",
    "content": "kind: Fixes\nbody: Fix dbt retry for microbatch models to use the original invocation time instead of the current time when recomputing batches\ntime: 2026-02-23T16:18:20.714612+05:30\ncustom:\n    Author: aahel\n    Issue: \"11423\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20260224-115546.yaml",
    "content": "kind: Fixes\nbody: Fix v2 metric parsing using model name instead of custom semantic_model.name for generated_from, causing conversion metric validation to fail\ntime: 2026-02-24T11:55:46.515181-08:00\ncustom:\n    Author: theyostalservice\n    Issue: \"12532\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20260224-180000.yaml",
    "content": "kind: Fixes\nbody: Fix doc() Jinja in derived_semantics dimension and entity descriptions being incorrectly rendered during v2 YAML parsing\ntime: 2026-02-24T18:00:00.000000-08:00\ncustom:\n    Author: theyostalservice\n    Issue: 12535\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20260224-231047.yaml",
    "content": "kind: Fixes\nbody: Improve logic for detecting config with missing plus prefix in dbt_project.yml\ntime: 2026-02-24T23:10:47.240471+05:30\ncustom:\n    Author: ash2shukla\n    Issue: \"12371\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20260225-203131.yaml",
    "content": "kind: Fixes\nbody: Enable sql_header config for data tests gated behind require_sql_header_in_test_configs behavior change flag.\ntime: 2026-02-25T20:31:31.854988+05:30\ncustom:\n    Author: aahel\n    Issue: \"9775\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20260226-163836.yaml",
    "content": "kind: Fixes\nbody: Better error formatting for semantic manifest validation errors\ntime: 2026-02-26T16:38:36.858458+05:30\ncustom:\n    Author: sriramr98\n    Issue: \"9849\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20260227-133424.yaml",
    "content": "kind: Fixes\nbody: Allow macros invoked via run-operation to ref() private and protected models\ntime: 2026-02-27T13:34:24.449177+05:30\ncustom:\n    Author: aahel\n    Issue: 8248\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20260227-140009.yaml",
    "content": "kind: Fixes\nbody: Better error and warnings logs with [WARNING] / [ERROR] messages prepended to the logs\ntime: 2026-02-27T14:00:09.850547+05:30\ncustom:\n    Author: sriramr98\n    Issue: \"9849\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20260302-000739.yaml",
    "content": "kind: Fixes\nbody: Add config and allow meta and docs to exist under it for macros\ntime: 2026-03-02T00:07:39.088118+05:30\ncustom:\n    Author: ash2shukla\n    Issue: 12383 9447\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20260303-114528.yaml",
    "content": "kind: Fixes\nbody: '`DBT_ENGINE` prefixed env vars picked up by CLI'\ntime: 2026-03-03T11:45:28.403687-06:00\ncustom:\n  Author: QMalcolm\n  Issue: \"12583\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20260305-133929.yaml",
    "content": "kind: Fixes\nbody: Fix duplicate CTE race condition in ephemeral model compilation\ntime: 2026-03-05T13:39:29.780057-08:00\ncustom:\n  Author: colin-rogers-dbt\n  Issue: \"12602\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20260306-034008.yaml",
    "content": "kind: Fixes\nbody: Allow deferral for UDFs\ntime: 2026-03-06T03:40:08.773781+05:30\ncustom:\n    Author: ash2shukla\n    Issue: \"12080\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20260306-071359.yaml",
    "content": "kind: Fixes\nbody: Update URL and name of behavior change flag for `require_ref_searches_node_package_before_root`\ntime: 2026-03-06T07:13:59.659401-07:00\ncustom:\n    Author: dbeatty10\n    Issue: \"12324\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20260306-192013.yaml",
    "content": "kind: Fixes\nbody: Resolve full node description while running udfs for better logging\ntime: 2026-03-06T19:20:13.395048+05:30\ncustom:\n    Author: ash2shukla\n    Issue: \"12600\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20260310-120000.yaml",
    "content": "kind: Fixes\nbody: Fix list-type metric filters under models key being incorrectly rendered at parse time, causing 'Dimension is undefined' errors\ntime: 2026-03-10T12:00:00.000000-08:00\ncustom:\n    Author: theyostalservice\n    Issue: \"12618\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20260317-094953.yaml",
    "content": "kind: Fixes\nbody: Add @requires.catalogs decorator to test command to fix custom catalog integration support\ntime: 2026-03-17T09:49:53.183758+01:00\ncustom:\n    Author: rrittsteiger\n    Issue: \"12662\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20260318-000000.yaml",
    "content": "kind: Fixes\nbody: Fix IndexError when parsing semantic model that references a disabled or missing model\ntime: 2026-03-18T00:00:00.000000-04:00\ncustom:\n    Author: MichelleArk\n    Issue: 12671\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20260318-091800.yaml",
    "content": "kind: Fixes\nbody: Support custom ref kwargs in unit tests and generic data tests, behind behavior flag `support_custom_ref_kwargs`\ntime: 2026-03-18T09:18:00.000000-05:00\ncustom:\n    Author: aahel\n    Issue: 12148\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20260318-173426.yaml",
    "content": "kind: Fixes\nbody: Fix AttributeError when docs block argument is non-constant\ntime: 2026-03-18T17:34:26.771797-04:00\ncustom:\n    Author: michelleark\n    Issue: \"12673\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20260318-182358.yaml",
    "content": "kind: Fixes\nbody: Fix AttributeError when generic test config is non-dictionary\ntime: 2026-03-18T18:23:58.393692-04:00\ncustom:\n    Author: michelleark\n    Issue: \"12674\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20260318-191153.yaml",
    "content": "kind: Fixes\nbody: handle jinja2.Undefined in msgpack_encoder\ntime: 2026-03-18T19:11:53.734654-04:00\ncustom:\n    Author: michelleark\n    Issue: \"12677\"\n"
  },
  {
    "path": ".changes/unreleased/Fixes-20260318-200626.yaml",
    "content": "kind: Fixes\nbody: Fix inheritance for defaults.agg_time_dimension in semantic models.\ntime: 2026-03-18T20:06:26.155408-07:00\ncustom:\n    Author: theyostalservice\n    Issue: \"12678\"\n"
  },
  {
    "path": ".changes/unreleased/Under the Hood-20250929-151159.yaml",
    "content": "kind: Under the Hood\nbody: Update schema file order test\ntime: 2025-09-29T15:11:59.611595-04:00\ncustom:\n    Author: gshank\n    Issue: \"11869\"\n"
  },
  {
    "path": ".changes/unreleased/Under the Hood-20251119-110110.yaml",
    "content": "kind: Under the Hood\nbody: Update jsonschemas for schema.yml and dbt_project.yml deprecations\ntime: 2025-11-19T11:01:10.616676-05:00\ncustom:\n    Author: michelleark\n    Issue: \"12180\"\n"
  },
  {
    "path": ".changes/unreleased/Under the Hood-20251121-140515.yaml",
    "content": "kind: Under the Hood\nbody: Replace setuptools and tox with hatch for build, test, and environment management.\ntime: 2025-11-21T14:05:15.838252-05:00\ncustom:\n  Author: emmyoop\n  Issue: \"12151\"\n"
  },
  {
    "path": ".changes/unreleased/Under the Hood-20251209-131857.yaml",
    "content": "kind: Under the Hood\nbody: Add add_catalog_integration call even if we have a pre-existing manifest\ntime: 2025-12-09T13:18:57.043254-08:00\ncustom:\n  Author: colin-rogers-dbt\n  Issue: \"12262\"\n"
  },
  {
    "path": ".changes/unreleased/Under the Hood-20251215-155046.yaml",
    "content": "kind: Under the Hood\nbody: Bump lower bound for dbt-common to 1.37.2\ntime: 2025-12-15T15:50:46.857793-05:00\ncustom:\n    Author: michelleark\n    Issue: \"12284\"\n"
  },
  {
    "path": ".changes/unreleased/Under the Hood-20260205-200835.yaml",
    "content": "kind: Under the Hood\nbody: sync JSON schemas from dbt-fusion\ntime: 2026-02-05T20:08:35.515361881Z\ncustom:\n    Author: fa-assistant\n    Issue: N/A\n"
  },
  {
    "path": ".changes/unreleased/Under the Hood-20260210-151244.yaml",
    "content": "kind: Under the Hood\nbody: Handle missing column time granularities during parsing.\ntime: 2026-02-10T15:12:44.460381-08:00\ncustom:\n    Author: theyostalservice\n    Issue: \"12472\"\n"
  },
  {
    "path": ".changes/unreleased/Under the Hood-20260214-181659.yaml",
    "content": "kind: Under the Hood\nbody: sync JSON schemas from dbt-fusion\ntime: 2026-02-14T18:16:59.71097177Z\ncustom:\n    Author: fa-assistant\n    Issue: N/A\n"
  },
  {
    "path": ".changes/unreleased/Under the Hood-20260220-170741.yaml",
    "content": "kind: Under the Hood\nbody: sync JSON schemas from dbt-fusion\ntime: 2026-02-20T17:07:41.802981778Z\ncustom:\n    Author: fa-assistant\n    Issue: N/A\n"
  },
  {
    "path": ".changes/unreleased/Under the Hood-20260223-121653.yaml",
    "content": "kind: Under the Hood\nbody: Make test case for parsing metric filters slightly more robust.\ntime: 2026-02-23T12:16:53.395517-08:00\ncustom:\n    Author: theyostalservice\n    Issue: \"12528\"\n"
  },
  {
    "path": ".changes/unreleased/Under the Hood-20260225-092728.yaml",
    "content": "kind: Under the Hood\nbody: sync JSON schemas from dbt-fusion\ntime: 2026-02-25T09:27:28.498892233Z\ncustom:\n    Author: fa-assistant\n    Issue: N/A\n"
  },
  {
    "path": ".changes/unreleased/Under the Hood-20260302-101022.yaml",
    "content": "kind: Under the Hood\nbody: Unpin sqlparse dependency, and introduce --sqlparse CLI option for configuring sqlparse limits\ntime: 2026-03-02T10:10:22.254214-05:00\ncustom:\n    Author: michelleark\n    Issue: \"12329\"\n"
  },
  {
    "path": ".changes/unreleased/Under the Hood-20260306-182611.yaml",
    "content": "kind: Under the Hood\nbody: sync JSON schemas from dbt-fusion\ntime: 2026-03-06T18:26:11.89001132Z\ncustom:\n    Author: fa-assistant\n    Issue: N/A\n"
  },
  {
    "path": ".changes/unreleased/Under the Hood-20260318-120715.yaml",
    "content": "kind: Under the Hood\nbody: 'Update jsonschemas for more accurate deprecation warnings: macro.config should not warn'\ntime: 2026-03-18T12:07:15.833316-04:00\ncustom:\n    Author: michelleark\n    Issue: \"12670\"\n"
  },
  {
    "path": ".changie.yaml",
    "content": "changesDir: .changes\nunreleasedDir: unreleased\nheaderPath: header.tpl.md\nversionHeaderPath: \"\"\nchangelogPath: CHANGELOG.md\nversionExt: md\nenvPrefix: \"CHANGIE_\"\nversionFormat: '## dbt-core {{.Version}} - {{.Time.Format \"January 02, 2006\"}}'\nkindFormat: '### {{.Kind}}'\nchangeFormat: |-\n  {{- $IssueList := list }}\n  {{- $changes := splitList \" \" $.Custom.Issue }}\n  {{- range $issueNbr := $changes }}\n    {{- $changeLink := \"[#nbr](https://github.com/dbt-labs/dbt-core/issues/nbr)\" | replace \"nbr\" $issueNbr }}\n    {{- $IssueList = append $IssueList $changeLink  }}\n  {{- end -}}\n  - {{.Body}} ({{ range $index, $element := $IssueList }}{{if $index}}, {{end}}{{$element}}{{end}})\n\nkinds:\n  - label: Breaking Changes\n  - label: Features\n  - label: Fixes\n  - label: Docs\n    changeFormat: |-\n      {{- $IssueList := list }}\n      {{- $changes := splitList \" \" $.Custom.Issue }}\n      {{- range $issueNbr := $changes }}\n        {{- $changeLink := \"[dbt-docs/#nbr](https://github.com/dbt-labs/dbt-docs/issues/nbr)\" | replace \"nbr\" $issueNbr }}\n        {{- $IssueList = append $IssueList $changeLink }}\n      {{- end -}}\n      - {{.Body}} ({{ range $index, $element := $IssueList }}{{if $index}}, {{end}}{{$element}}{{end}})\n  - label: Under the Hood\n  - label: Dependencies\n  - label: Security\n\nnewlines:\n  afterChangelogHeader: 1\n  afterKind: 1\n  afterChangelogVersion: 1\n  beforeKind: 1\n  endOfVersion: 1\n\ncustom:\n  - key: Author\n    label: GitHub Username(s) (separated by a single space if multiple)\n    type: string\n    minLength: 3\n  - key: Issue\n    label: GitHub Issue Number (separated by a single space if multiple)\n    type: string\n    minLength: 1\n\nfooterFormat: |\n  {{- $contributorDict := dict }}\n  {{- /* ensure we always skip snyk and dependabot */}}\n  {{- $bots := list \"dependabot[bot]\" \"snyk-bot\"}}\n  {{- range $change := .Changes }}\n    {{- $authorList := splitList \" \" $change.Custom.Author }}\n    {{- /* loop through all authors for a single changelog */}}\n    {{- range $author := $authorList }}\n      {{- $authorLower := lower $author }}\n      {{- /* we only want to include non-bot contributors */}}\n      {{- if not (has $authorLower $bots)}}\n        {{- $changeList := splitList \" \" $change.Custom.Author }}\n          {{- $IssueList := list }}\n          {{- $changeLink := $change.Kind }}\n          {{- $changes := splitList \" \" $change.Custom.Issue }}\n          {{- range $issueNbr := $changes }}\n            {{- $changeLink := \"[#nbr](https://github.com/dbt-labs/dbt-core/issues/nbr)\" | replace \"nbr\" $issueNbr }}\n            {{- $IssueList = append $IssueList $changeLink  }}\n          {{- end }}\n          {{- /* check if this contributor has other changes associated with them already */}}\n          {{- if hasKey $contributorDict $author }}\n            {{- $contributionList := get $contributorDict $author }}\n            {{- $contributionList = concat $contributionList $IssueList  }}\n            {{- $contributorDict := set $contributorDict $author $contributionList }}\n          {{- else }}\n            {{- $contributionList := $IssueList }}\n            {{- $contributorDict := set $contributorDict $author $contributionList }}\n          {{- end }}\n        {{- end}}\n    {{- end}}\n  {{- end }}\n  {{- /* no indentation here for formatting so the final markdown doesn't have unneeded indentations */}}\n  {{- if $contributorDict}}\n  ### Contributors\n  {{- range $k,$v := $contributorDict }}\n  - [@{{$k}}](https://github.com/{{$k}}) ({{ range $index, $element := $v }}{{if $index}}, {{end}}{{$element}}{{end}})\n  {{- end }}\n  {{- end }}\n"
  },
  {
    "path": ".dockerignore",
    "content": "*\n!docker/requirements/*.txt\n!dist\n"
  },
  {
    "path": ".flake8",
    "content": "[flake8]\nselect =\n    E\n    W\n    F\nignore =\n    W503 # makes Flake8 work like black\n    W504\n    E203 # makes Flake8 work like black\n    E704 # makes Flake8 work like black\n    E741\n    E501 # long line checking is done in black\nper-file-ignores =\n    */__init__.py: F401\n"
  },
  {
    "path": ".git-blame-ignore-revs",
    "content": "# Reformatting dbt-core via black, flake8, mypy, and assorted pre-commit hooks.\n43e3fc22c4eae4d3d901faba05e33c40f1f1dc5a\n"
  },
  {
    "path": ".gitattributes",
    "content": "core/dbt/task/docs/index.html binary\ntests/functional/artifacts/data/state/*/manifest.json binary\ncore/dbt/docs/build/html/searchindex.js binary\ncore/dbt/docs/build/html/index.html binary\nperformance/runner/Cargo.lock binary\ncore/dbt/events/types_pb2.py binary\n"
  },
  {
    "path": ".github/CODEOWNERS",
    "content": "# This file contains the code owners for the dbt-core repo.\n# PRs will be automatically assigned for review to the associated\n# team(s) or person(s) that touches any files that are mapped to them.\n#\n# A statement takes precedence over the statements above it so more general\n# assignments are found at the top with specific assignments being lower in\n# the ordering (i.e. catch all assignment should be the first item)\n#\n# Consult GitHub documentation for formatting guidelines:\n# https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners#example-of-a-codeowners-file\n\n# As a default for areas with no assignment,\n# the core team as a whole will be assigned\n*       @dbt-labs/core-team\n\n### ARTIFACTS\n\n/schemas/dbt                    @dbt-labs/cloud-artifacts\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug-report.yml",
    "content": "name: 🐞 Bug\ndescription: Report a bug or an issue you've found with dbt\ntitle: \"[Bug] <title>\"\nlabels: [\"bug\", \"triage\"]\nbody:\n  - type: markdown\n    attributes:\n      value: |\n        Thanks for taking the time to fill out this bug report!\n  - type: checkboxes\n    attributes:\n      label: Is this a new bug in dbt-core?\n      description: >\n        In other words, is this an error, flaw, failure or fault in our software?\n\n        If this is a bug that broke existing functionality that used to work, please open a regression issue.\n        If this is a bug in an adapter plugin, please open an issue in the adapter's repository.\n        If this is a bug experienced while using dbt Cloud, please report to [support](mailto:support@getdbt.com).\n        If this is a request for help or troubleshooting code in your own dbt project, please join our [dbt Community Slack](https://www.getdbt.com/community/join-the-community/) or open a [Discussion question](https://github.com/dbt-labs/docs.getdbt.com/discussions).\n\n        Please search to see if an issue already exists for the bug you encountered.\n      options:\n        - label: I believe this is a new bug in dbt-core\n          required: true\n        - label: I have searched the existing issues, and I could not find an existing issue for this bug\n          required: true\n  - type: textarea\n    attributes:\n      label: Current Behavior\n      description: A concise description of what you're experiencing.\n    validations:\n      required: true\n  - type: textarea\n    attributes:\n      label: Expected Behavior\n      description: A concise description of what you expected to happen.\n    validations:\n      required: true\n  - type: textarea\n    attributes:\n      label: Steps To Reproduce\n      description: Steps to reproduce the behavior.\n      placeholder: |\n        1. In this environment...\n        2. With this config...\n        3. Run '...'\n        4. See error...\n    validations:\n      required: true\n  - type: textarea\n    id: logs\n    attributes:\n      label: Relevant log output\n      description: |\n        If applicable, log output to help explain your problem.\n      render: shell\n    validations:\n      required: false\n  - type: textarea\n    attributes:\n      label: Environment\n      description: |\n        examples:\n          - **OS**: Ubuntu 24.04\n          - **Python**: 3.10.12 (`python3 --version`)\n          - **dbt-core**: 1.1.1 (`dbt --version`)\n      value: |\n        - OS:\n        - Python:\n        - dbt:\n      render: markdown\n    validations:\n      required: false\n  - type: dropdown\n    id: database\n    attributes:\n      label: Which database adapter are you using with dbt?\n      description: If the bug is specific to the database or adapter, please open the issue in that adapter's repository instead\n      multiple: true\n      options:\n        - postgres\n        - redshift\n        - snowflake\n        - bigquery\n        - spark\n        - other (mention it in \"Additional Context\")\n    validations:\n      required: false\n  - type: textarea\n    attributes:\n      label: Additional Context\n      description: |\n        Links? References? Anything that will give us more context about the issue you are encountering!\n\n        Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.\n    validations:\n      required: false\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/code-docs.yml",
    "content": "name: 📄 Code docs\ndescription: Report an issue for markdown files within this repo, such as README, ARCHITECTURE, etc.\ntitle: \"[Code docs] <title>\"\nlabels: [\"triage\"]\nbody:\n  - type: markdown\n    attributes:\n      value: |\n        Thanks for taking the time to fill out this code docs issue!\n  - type: textarea\n    attributes:\n      label: Please describe the issue and your proposals.\n      description: |\n        Links? References? Anything that will give us more context about the issue you are encountering!\n\n        Tip: You can attach images by clicking this area to highlight it and then dragging files in.\n    validations:\n      required: false\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "content": "blank_issues_enabled: false\ncontact_links:\n  - name: Documentation\n    url: https://github.com/dbt-labs/docs.getdbt.com/issues/new/choose\n    about: Problems and issues with dbt product documentation hosted on docs.getdbt.com. Issues for markdown files within this repo, such as README, should be opened using the \"Code docs\" template.\n  - name: Ask the community for help\n    url: https://github.com/dbt-labs/docs.getdbt.com/discussions\n    about: Need help troubleshooting? Check out our guide on how to ask\n  - name: Contact dbt Cloud support\n    url: mailto:support@getdbt.com\n    about: Are you using dbt Cloud? Contact our support team for help!\n  - name: Participate in Discussions\n    url: https://github.com/dbt-labs/dbt-core/discussions\n    about: Do you have a Big Idea for dbt? Read open discussions, or start a new one\n  - name: Create an issue for adapters\n    url: https://github.com/dbt-labs/dbt-adapters/issues/new/choose\n    about: Report a bug or request a feature for an adapter\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature-request.yml",
    "content": "name: ✨ Feature\ndescription: Propose a straightforward extension of dbt functionality\ntitle: \"[Feature] <title>\"\nlabels: [\"enhancement\", \"triage\"]\nbody:\n  - type: markdown\n    attributes:\n      value: |\n        Thanks for taking the time to fill out this feature request!\n  - type: checkboxes\n    attributes:\n      label: Is this your first time submitting a feature request?\n      description: >\n        We want to make sure that features are distinct and discoverable,\n        so that other members of the community can find them and offer their thoughts.\n\n        Issues are the right place to request straightforward extensions of existing dbt functionality.\n        For \"big ideas\" about future capabilities of dbt, we ask that you open a\n        [discussion](https://github.com/dbt-labs/dbt-core/discussions) in the \"Ideas\" category instead.\n      options:\n        - label: I have read the [expectations for open source contributors](https://docs.getdbt.com/docs/contributing/oss-expectations)\n          required: true\n        - label: I have searched the existing issues, and I could not find an existing issue for this feature\n          required: true\n        - label: I am requesting a straightforward extension of existing dbt functionality, rather than a Big Idea better suited to a discussion\n          required: true\n  - type: textarea\n    attributes:\n      label: Describe the feature\n      description: A clear and concise description of what you want to happen.\n    validations:\n      required: true\n  - type: textarea\n    attributes:\n      label: Describe alternatives you've considered\n      description: |\n        A clear and concise description of any alternative solutions or features you've considered.\n    validations:\n      required: false\n  - type: textarea\n    attributes:\n      label: Who will this benefit?\n      description: |\n        What kind of use case will this feature be useful for? Please be specific and provide examples, this will help us prioritize properly.\n    validations:\n      required: false\n  - type: input\n    attributes:\n      label: Are you interested in contributing this feature?\n      description: Let us know if you want to write some code, and how we can help.\n    validations:\n      required: false\n  - type: textarea\n    attributes:\n      label: Anything else?\n      description: |\n        Links? References? Anything that will give us more context about the feature you are suggesting!\n    validations:\n      required: false\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/implementation-ticket.yml",
    "content": "name: 🛠️ Implementation\ndescription: This is an implementation ticket intended for use by the maintainers of dbt-core\ntitle: \"[<project>] <title>\"\nlabels: [\"user docs\"]\nbody:\n  - type: markdown\n    attributes:\n      value: This is an implementation ticket intended for use by the maintainers of dbt-core\n  - type: checkboxes\n    attributes:\n      label: Housekeeping\n      description: >\n        A couple friendly reminders:\n          1. Remove the `user docs` label if the scope of this work does not require changes to https://docs.getdbt.com/docs: no end-user interface (e.g. yml spec, CLI, error messages, etc) or functional changes\n          2. Link any blocking issues in the \"Blocked on\" field under the \"Core devs & maintainers\" project.\n      options:\n        - label: I am a maintainer of dbt-core\n          required: true\n  - type: textarea\n    attributes:\n      label: Short description\n      description: |\n        Describe the scope of the ticket, a high-level implementation approach and any tradeoffs to consider\n    validations:\n      required: true\n  - type: textarea\n    attributes:\n      label: Acceptance criteria\n      description: |\n        What is the definition of done for this ticket? Include any relevant edge cases and/or test cases\n    validations:\n      required: true\n  - type: textarea\n    attributes:\n      label: Suggested Tests\n      description: |\n        Provide scenarios to test.  Link to existing similar tests if appropriate.\n      placeholder: |\n         1. Test with no version specified in the schema file and use selection logic on a versioned model for a specific version.  Expect pass.\n         2. Test with a version specified in the schema file that is no valid.  Expect ParsingError.\n    validations:\n      required: true\n  - type: textarea\n    attributes:\n      label: Impact to Other Teams\n      description: |\n        Will this change impact other teams?  Include details of the kinds of changes required (new tests, code changes, related tickets) and _add the relevant `Impact:[team]` label_.\n      placeholder: |\n        Example: This change impacts `dbt-redshift` because the tests will need to be modified.  The `Impact:[Adapter]` label has been added.\n    validations:\n      required: true\n  - type: textarea\n    attributes:\n      label: Will backports be required?\n      description: |\n        Will this change need to be backported to previous versions?  Add details, possible blockers to backporting and _add the relevant backport labels `backport 1.x.latest`_\n      placeholder: |\n        Example: Backport to 1.6.latest, 1.5.latest and 1.4.latest.  Since 1.4 isn't using click, the backport may be complicated. The `backport 1.6.latest`, `backport 1.5.latest` and `backport 1.4.latest` labels have been added.\n    validations:\n      required: true\n  - type: textarea\n    attributes:\n      label: Context\n      description: |\n        Provide the \"why\", motivation, and alternative approaches considered -- linking to previous refinement issues, spikes and documentation as appropriate\n    validations:\n      required: false\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/regression-report.yml",
    "content": "name: ☣️ Regression\ndescription: Report a regression you've observed in a newer version of dbt\ntitle: \"[Regression] <title>\"\nlabels: [\"bug\", \"regression\", \"triage\"]\nbody:\n  - type: markdown\n    attributes:\n      value: |\n        Thanks for taking the time to fill out this regression report!\n  - type: checkboxes\n    attributes:\n      label: Is this a regression in a recent version of dbt-core?\n      description: >\n        A regression is when documented functionality works as expected in an older version of dbt-core,\n        and no longer works after upgrading to a newer version of dbt-core\n      options:\n        - label: I believe this is a regression in dbt-core functionality\n          required: true\n        - label: I have searched the existing issues, and I could not find an existing issue for this regression\n          required: true\n  - type: textarea\n    attributes:\n      label: Current Behavior\n      description: A concise description of what you're experiencing.\n    validations:\n      required: true\n  - type: textarea\n    attributes:\n      label: Expected/Previous Behavior\n      description: A concise description of what you expected to happen.\n    validations:\n      required: true\n  - type: textarea\n    attributes:\n      label: Steps To Reproduce\n      description: Steps to reproduce the behavior.\n      placeholder: |\n        1. In this environment...\n        2. With this config...\n        3. Run '...'\n        4. See error...\n    validations:\n      required: true\n  - type: textarea\n    id: logs\n    attributes:\n      label: Relevant log output\n      description: |\n        If applicable, log output to help explain your problem.\n      render: shell\n    validations:\n      required: false\n  - type: textarea\n    attributes:\n      label: Environment\n      description: |\n        examples:\n          - **OS**: Ubuntu 24.04\n          - **Python**: 3.10.12 (`python3 --version`)\n          - **dbt-core (working version)**: 1.1.1 (`dbt --version`)\n          - **dbt-core (regression version)**: 1.2.0 (`dbt --version`)\n      value: |\n        - OS:\n        - Python:\n        - dbt (working version):\n        - dbt (regression version):\n      render: markdown\n    validations:\n      required: true\n  - type: dropdown\n    id: database\n    attributes:\n      label: Which database adapter are you using with dbt?\n      description: If the regression is specific to the database or adapter, please open the issue in that adapter's repository instead\n      multiple: true\n      options:\n        - postgres\n        - redshift\n        - snowflake\n        - bigquery\n        - spark\n        - other (mention it in \"Additional Context\")\n    validations:\n      required: false\n  - type: textarea\n    attributes:\n      label: Additional Context\n      description: |\n        Links? References? Anything that will give us more context about the issue you are encountering!\n\n        Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.\n    validations:\n      required: false\n"
  },
  {
    "path": ".github/_README.md",
    "content": "<!-- GitHub will publish this readme on the main repo page if the name is `README.md` so we've added the leading underscore to prevent this -->\n<!-- Do not rename this file `README.md` -->\n<!-- See https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-readmes -->\n\n## What are GitHub Actions?\n\nGitHub Actions are used for many different purposes.  We use them to run tests in CI, validate PRs are in an expected state, and automate processes.\n\n- [Overview of GitHub Actions](https://docs.github.com/en/actions/learn-github-actions/understanding-github-actions)\n- [What's a workflow?](https://docs.github.com/en/actions/using-workflows/about-workflows)\n- [GitHub Actions guides](https://docs.github.com/en/actions/guides)\n\n___\n\n## Where do actions and workflows live\n\nWe try to maintain actions that are shared across repositories in a single place so that necesary changes can be made in a single place.\n\n[dbt-labs/actions](https://github.com/dbt-labs/actions/) is the central repository of actions and workflows we use across repositories.\n\nGitHub Actions also live locally within a repository.  The workflows can be found at `.github/workflows` from the root of the repository.  These should be specific to that code base.\n\nNote: We are actively moving actions into the central Action repository so there is currently some duplication across repositories.\n\n___\n\n## Basics of Using Actions\n\n### Viewing Output\n\n- View the detailed action output for your PR in the **Checks** tab of the PR.  This only shows the most recent run.  You can also view high level **Checks** output at the bottom on the PR.\n\n- View _all_ action output for a repository from the [**Actions**](https://github.com/dbt-labs/dbt-core/actions) tab.  Workflow results last 1 year.  Artifacts last 90 days, unless specified otherwise in individual workflows.\n\n  This view often shows what seem like duplicates of the same workflow.  This occurs when files are renamed but the workflow name has not changed.  These are in fact _not_ duplicates.\n\n  You can see the branch the workflow runs from in this view.  It is listed in the table between the workflow name and the time/duration of the run.  When blank, the workflow is running in the context of the  `main` branch.\n\n### How to view what workflow file is being referenced from a run\n\n- When viewing the output of a specific workflow run, click the 3 dots at the top right of the display.  There will be an option to `View workflow file`.\n\n### How to manually run a workflow\n\n- If a workflow has the `on: workflow_dispatch` trigger, it can be manually triggered\n- From the [**Actions**](https://github.com/dbt-labs/dbt-core/actions) tab, find the workflow you want to run, select it and fill in any inputs requied.  That's it!\n\n### How to re-run jobs\n\n- From the UI you can rerun from failure\n- You can retrigger the cla check by commenting on the PR with `@cla-bot check`\n\n___\n\n## General Standards\n\n### Permissions\n- By default, workflows have read permissions in the repository for the contents scope only when no permissions are explicitly set.\n- It is best practice to always define the permissions explicitly.  This will allow actions to continue to work when the default permissions on the repository are changed.  It also allows explicit grants of the least permissions possible.\n- There are a lot of permissions available.  [Read up on them](https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs) if you're unsure what to use.\n\n```yaml\npermissions:\n  contents: read\n  pull-requests: write\n```\n\n### Secrets\n- When to use a [Personal Access Token (PAT)](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) vs the [GITHUB_TOKEN](https://docs.github.com/en/actions/security-guides/automatic-token-authentication) generated for the action?\n\n    The `GITHUB_TOKEN` is used by default.  In most cases it is sufficient for what you need.\n\n    If you expect the workflow to result in a commit to that should retrigger workflows, you will need to use a Personal Access Token for the bot to commit the file. When using the GITHUB_TOKEN, the resulting commit will not trigger another GitHub Actions Workflow run. This is due to limitations set by GitHub. See [the docs](https://docs.github.com/en/actions/security-guides/automatic-token-authentication#using-the-github_token-in-a-workflow) for a more detailed explanation.\n\n    For example, we must use a PAT in our workflow to commit a new changelog yaml file for bot PRs.  Once the file has been committed to the branch, it should retrigger the check to validate that a changelog exists on the PR.  Otherwise, it would stay in a failed state since the check would never retrigger.\n\n### Triggers\nYou can configure your workflows to run when specific activity on GitHub happens, at a scheduled time, or when an event outside of GitHub occurs.  Read more details in the [GitHub docs](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows).\n\nThese triggers are under the `on` key of the workflow and more than one can be listed.\n\n```yaml\non:\n  push:\n    branches:\n      - \"main\"\n      - \"*.latest\"\n      - \"releases/*\"\n  pull_request:\n    # catch when the PR is opened with the label or when the label is added\n    types: [opened, labeled]\n  workflow_dispatch:\n```\n\nSome triggers of note that we use:\n\n- `push` - Runs your workflow when you push a commit or tag.\n- `pull_request` - Runs your workflow when activity on a pull request in the workflow's repository occurs.  Takes in a list of activity types (opened, labeled, etc) if appropriate.\n- `pull_request_target` - Same as `pull_request` but runs in the context of the PR target branch.\n- `workflow_call` - used with reusable workflows.  Triggered by another workflow calling it.\n- `workflow_dispatch` - Gives the ability to manually trigger a workflow from the GitHub API, GitHub CLI, or GitHub browser interface.\n\n\n### Basic Formatting\n- Add a description of what your workflow does at the top in this format\n\n  ```\n  # **what?**\n  # Describe what the action does.\n\n  # **why?**\n  # Why does this action exist?\n\n  # **when?**\n  # How/when will it be triggered?\n  ```\n\n- Leave blank lines between steps and jobs\n\n  ```yaml\n  jobs:\n    dependency_changelog:\n      runs-on: ${{ vars.UBUNTU_LATEST }}\n\n      steps:\n      - name: Get File Name Timestamp\n        id: filename_time\n        uses: nanzm/get-time-action@v1.1\n        with:\n          format: 'YYYYMMDD-HHmmss'\n\n      - name: Get File Content Timestamp\n        id: file_content_time\n        uses: nanzm/get-time-action@v1.1\n        with:\n          format: 'YYYY-MM-DDTHH:mm:ss.000000-05:00'\n\n      - name: Generate Filepath\n        id: fp\n        run: |\n          FILEPATH=.changes/unreleased/Dependencies-${{ steps.filename_time.outputs.time }}.yaml\n          echo \"FILEPATH=$FILEPATH\" >> $GITHUB_OUTPUT\n  ```\n\n- Print out all variables you will reference as the first step of a job.  This allows for easier debugging.  The first job should log all inputs.  Subsequent jobs should reference outputs of other jobs, if present.\n\n  When possible, generate variables at the top of your workflow in a single place to reference later.  This is not always strictly possible since you may generate a value to be used later mid-workflow.\n\n  Be sure to use quotes around these logs so special characters are not interpreted.\n\n  ```yaml\n  job1:\n    - name: \"[DEBUG] Print Variables\"\n      run: |\n        echo \"all variables defined as inputs\"\n        echo \"The last commit sha in the release: ${{ inputs.sha }}\"\n        echo \"The release version number:         ${{ inputs.version_number }}\"\n        echo \"The changelog_path:                 ${{ inputs.changelog_path }}\"\n        echo \"The build_script_path:              ${{ inputs.build_script_path }}\"\n        echo \"The s3_bucket_name:                 ${{ inputs.s3_bucket_name }}\"\n        echo \"The package_test_command:           ${{ inputs.package_test_command }}\"\n\n    # collect all the variables that need to be used in subsequent jobs\n    - name: Set Variables\n      id: variables\n      run: |\n        echo \"important_path='performance/runner/Cargo.toml'\" >> $GITHUB_OUTPUT\n        echo \"release_id=${{github.event.inputs.release_id}}\" >> $GITHUB_OUTPUT\n        echo \"open_prs=${{github.event.inputs.open_prs}}\" >> $GITHUB_OUTPUT\n\n  job2:\n    needs: [job1]\n      - name: \"[DEBUG] Print Variables\"\n      run: |\n        echo \"all variables defined in job1 > Set Variables > outputs\"\n        echo \"important_path: ${{ needs.job1.outputs.important_path }}\"\n        echo \"release_id:     ${{ needs.job1.outputs.release_id }}\"\n        echo \"open_prs:       ${{ needs.job1.outputs.open_prs }}\"\n  ```\n\n- When it's not obvious what something does, add a comment!\n\n___\n\n## Tips\n\n### Context\n- The [GitHub CLI](https://cli.github.com/) is available in the default runners\n- Actions run in your context.  ie, using an action from the marketplace that uses the GITHUB_TOKEN uses the GITHUB_TOKEN generated by your workflow run.\n\n### Runners\n- We dynamically set runners based on repository vars.  Admins can view repository vars and reset them.  Current values are the following but are subject to change:\n  - `vars.UBUNTU_LATEST` -> `ubuntu-latest`\n  - `vars.WINDOWS_LATEST` -> `windows-latest`\n  - `vars.MACOS_LATEST` -> `macos-14`\n\n### Actions from the Marketplace\n- Don’t use external actions for things that can easily be accomplished manually.\n- Always read through what an external action does before using it!  Often an action in the GitHub Actions Marketplace can be replaced with a few lines in bash.  This is much more maintainable (and won’t change under us) and clear as to what’s actually happening.  It also prevents any\n- Pin actions _we don't control_ to tags.\n\n### Connecting to AWS\n- Authenticate with the aws managed workflow\n\n  ```yaml\n  - name: Configure AWS credentials from Test account\n    uses: aws-actions/configure-aws-credentials@v2\n    with:\n      aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}\n      aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}\n      aws-region: us-east-1\n  ```\n\n- Then access with the aws command that comes installed on the action runner machines\n\n  ```yaml\n  - name: Copy Artifacts from S3 via CLI\n    run: aws s3 cp ${{ env.s3_bucket }} . --recursive\n  ```\n\n### Testing\n\n- Depending on what your action does, you may be able to use [`act`](https://github.com/nektos/act) to test the action locally.  Some features of GitHub Actions do not work with `act`, among those are reusable workflows.  If you can't use `act`, you'll have to push your changes up before being able to test.  This can be slow.\n"
  },
  {
    "path": ".github/actions/latest-wrangler/Dockerfile",
    "content": "FROM python:3-slim AS builder\nADD . /app\nWORKDIR /app\n\n# We are installing a dependency here directly into our app source dir\nRUN pip install --target=/app requests packaging\n\n# A distroless container image with Python and some basics like SSL certificates\n# https://github.com/GoogleContainerTools/distroless\nFROM gcr.io/distroless/python3-debian10\nCOPY --from=builder /app /app\nWORKDIR /app\nENV PYTHONPATH /app\nCMD [\"/app/main.py\"]\n"
  },
  {
    "path": ".github/actions/latest-wrangler/README.md",
    "content": "# Github package 'latest' tag wrangler for containers\n## Usage\n\nPlug in the necessary inputs to determine if the container being built should be tagged 'latest; at the package level, for example `dbt-redshift:latest`.\n\n## Inputs\n| Input | Description |\n| - | - |\n| `package` | Name of the GH package to check against |\n| `new_version` | Semver of new container |\n| `gh_token` | GH token with package read scope|\n| `halt_on_missing` | Return non-zero exit code if requested package does not exist. (defaults to false)|\n\n\n## Outputs\n| Output | Description |\n| - | - |\n| `latest` | Wether or not the new container should be tagged 'latest'|\n| `minor_latest` | Wether or not the new container should be tagged major.minor.latest |\n\n## Example workflow\n```yaml\nname: Ship it!\non:\n  workflow_dispatch:\n    inputs:\n      package:\n       description: The package to publish\n       required: true\n      version_number:\n       description: The version number\n       required: true\n\njobs:\n  build:\n    runs-on: ${{ vars.UBUNTU_LATEST }}\n    steps:\n    - uses: actions/checkout@v3\n    - name: Wrangle latest tag\n      id: is_latest\n      uses: ./.github/actions/latest-wrangler\n      with:\n        package: ${{ github.event.inputs.package }}\n        new_version: ${{ github.event.inputs.new_version }}\n        gh_token: ${{ secrets.GITHUB_TOKEN }}\n    - name: Print the results\n      run: |\n        echo \"Is it latest?  Survey says: ${{ steps.is_latest.outputs.latest }} !\"\n        echo \"Is it minor.latest?  Survey says: ${{ steps.is_latest.outputs.minor_latest }} !\"\n```\n"
  },
  {
    "path": ".github/actions/latest-wrangler/action.yml",
    "content": "name: \"GitHub package `latest` tag wrangler for containers\"\ndescription: \"Determines if the published image should include `latest` tags\"\n\ninputs:\n  package_name:\n    description: \"Package being published (i.e. `dbt-core`, `dbt-redshift`, etc.)\"\n    required: true\n  new_version:\n    description: \"SemVer of the package being published (i.e. 1.7.2, 1.8.0a1, etc.)\"\n    required: true\n  github_token:\n    description: \"Auth token for GitHub (must have view packages scope)\"\n    required: true\n\noutputs:\n  tags:\n    description: \"A list of tags to associate with this version\"\n\nruns:\n  using: \"docker\"\n  image: \"Dockerfile\"\n"
  },
  {
    "path": ".github/actions/latest-wrangler/examples/example_workflow.yml",
    "content": "name: Ship it!\non:\n  workflow_dispatch:\n    inputs:\n      package:\n        description: The package to publish\n        required: true\n      version_number:\n        description: The version number\n        required: true\n\njobs:\n  build:\n    runs-on: ${{ vars.UBUNTU_LATEST }}\n    steps:\n      - uses: actions/checkout@v3\n      - name: Wrangle latest tag\n        id: is_latest\n        uses: ./.github/actions/latest-wrangler\n        with:\n          package: ${{ github.event.inputs.package }}\n          new_version: ${{ github.event.inputs.new_version }}\n          gh_token: ${{ secrets.GITHUB_TOKEN }}\n      - name: Print the results\n        run: |\n          echo \"Is it latest?  Survey says: ${{ steps.is_latest.outputs.latest }} !\"\n"
  },
  {
    "path": ".github/actions/latest-wrangler/examples/example_workflow_dispatch.json",
    "content": "{\n    \"inputs\": {\n      \"version_number\": \"1.0.1\",\n      \"package\": \"dbt-redshift\"\n    }\n}\n"
  },
  {
    "path": ".github/actions/latest-wrangler/main.py",
    "content": "import os\nimport sys\nfrom typing import List\n\nimport requests\nfrom packaging.version import Version, parse\n\n\ndef main():\n    package_name: str = os.environ[\"INPUT_PACKAGE_NAME\"]\n    new_version: Version = parse(os.environ[\"INPUT_NEW_VERSION\"])\n    github_token: str = os.environ[\"INPUT_GITHUB_TOKEN\"]\n\n    response = _package_metadata(package_name, github_token)\n    published_versions = _published_versions(response)\n    new_version_tags = _new_version_tags(new_version, published_versions)\n    _register_tags(new_version_tags, package_name)\n\n\ndef _package_metadata(package_name: str, github_token: str) -> requests.Response:\n    url = f\"https://api.github.com/orgs/dbt-labs/packages/container/{package_name}/versions\"\n    return requests.get(url, auth=(\"\", github_token))\n\n\ndef _published_versions(response: requests.Response) -> List[Version]:\n    package_metadata = response.json()\n    return [\n        parse(tag)\n        for version in package_metadata\n        for tag in version[\"metadata\"][\"container\"][\"tags\"]\n        if \"latest\" not in tag\n    ]\n\n\ndef _new_version_tags(new_version: Version, published_versions: List[Version]) -> List[str]:\n    # the package version is always a tag\n    tags = [str(new_version)]\n\n    # pre-releases don't get tagged with `latest`\n    if new_version.is_prerelease:\n        return tags\n\n    if new_version > max(published_versions):\n        tags.append(\"latest\")\n\n    published_patches = [\n        version\n        for version in published_versions\n        if version.major == new_version.major and version.minor == new_version.minor\n    ]\n    if new_version > max(published_patches):\n        tags.append(f\"{new_version.major}.{new_version.minor}.latest\")\n\n    return tags\n\n\ndef _register_tags(tags: List[str], package_name: str) -> None:\n    fully_qualified_tags = \",\".join([f\"ghcr.io/dbt-labs/{package_name}:{tag}\" for tag in tags])\n    github_output = os.environ.get(\"GITHUB_OUTPUT\")\n    with open(github_output, \"at\", encoding=\"utf-8\") as gh_output:\n        gh_output.write(f\"fully_qualified_tags={fully_qualified_tags}\")\n\n\ndef _validate_response(response: requests.Response) -> None:\n    message = response[\"message\"]\n    if response.status_code != 200:\n        print(f\"Call to GitHub API failed: {response.status_code} - {message}\")\n        sys.exit(1)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": ".github/actions/setup-postgres-windows/action.yml",
    "content": "name: \"Set up postgres (windows)\"\ndescription: \"Set up postgres service on windows vm for dbt integration tests\"\nruns:\n  using: \"composite\"\n  steps:\n    - shell: pwsh\n      run: |\n        Write-Host -Object \"Installing PostgreSQL 16 as windows service...\"\n        $installerArgs = @(\"--install_runtimes 0\", \"--superpassword root\", \"--enable_acledit 1\", \"--unattendedmodeui none\", \"--mode unattended\")\n        $filePath = Invoke-DownloadWithRetry -Url \"https://get.enterprisedb.com/postgresql/postgresql-16.1-1-windows-x64.exe\" -Path \"$env:PGROOT/postgresql-16.1-1-windows-x64.exe\"\n        Start-Process -FilePath $filePath -ArgumentList $installerArgs -Wait -PassThru\n\n        Write-Host -Object \"Validating PostgreSQL 16 Install...\"\n        Get-Service -Name postgresql*\n        $pgReady = Start-Process -FilePath \"$env:PGBIN\\pg_isready\" -Wait -PassThru\n        $exitCode = $pgReady.ExitCode\n        if ($exitCode -ne 0) {\n            Write-Host -Object \"PostgreSQL is not ready. Exitcode: $exitCode\"\n            exit $exitCode\n        }\n\n        Write-Host -Object \"Starting PostgreSQL 16 Service...\"\n        $pgService = Get-Service -Name postgresql-x64-16\n        Set-Service -InputObject $pgService -Status running -StartupType automatic\n        $env:Path += \";$env:PGBIN\"\n        bash ${{ github.action_path }}/setup_db.sh\n"
  },
  {
    "path": ".github/dbt-postgres-testing.yml",
    "content": "# **what?**\n# Runs all tests in dbt-postgres with this branch of dbt-core to ensure nothing is broken\n\n# **why?**\n# Ensure dbt-core changes do not break dbt-postgres, as a basic proxy for other adapters\n\n# **when?**\n# This will run when trying to merge a PR into main.\n# It can also be manually triggered.\n\n# This workflow can be skipped by adding the \"Skip Postgres Testing\" label to the PR.  This is\n# useful when making a change in both `dbt-postgres` and `dbt-core` where the changes are dependant\n# and cause the other repository to break.\n\nname: \"dbt-postgres Tests\"\nrun-name: >-\n  ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call')\n  && format('dbt-postgres@{0} with dbt-core@{1}', inputs.dbt-postgres-ref, inputs.dbt-core-ref)\n  || 'dbt-postgres@main with dbt-core branch' }}\n\non:\n  push:\n    branches:\n      - \"main\"\n      - \"*.latest\"\n      - \"releases/*\"\n  pull_request:\n  merge_group:\n    types: [checks_requested]\n  workflow_dispatch:\n    inputs:\n      dbt-postgres-ref:\n        description: \"The branch of dbt-postgres to test against\"\n        default: \"main\"\n      dbt-core-ref:\n        description: \"The branch of dbt-core to test against\"\n        default: \"main\"\n  workflow_call:\n    inputs:\n      dbt-postgres-ref:\n        description: \"The branch of dbt-postgres to test against\"\n        type: string\n        required: true\n        default: \"main\"\n      dbt-core-ref:\n        description: \"The branch of dbt-core to test against\"\n        type: string\n        required: true\n        default: \"main\"\n\npermissions: read-all\n\n# will cancel previous workflows triggered by the same event\n# and for the same ref for PRs/merges or same SHA otherwise\n# and for the same inputs on workflow_dispatch or workflow_call\nconcurrency:\n  group: ${{ github.workflow }}-${{ github.event_name }}-${{ contains(fromJson('[\"pull_request\", \"merge_group\"]'), github.event_name) && github.event.pull_request.head.ref || github.sha }}-${{ contains(fromJson('[\"workflow_call\", \"workflow_dispatch\"]'), github.event_name) && github.event.inputs.dbt-postgres-ref && github.event.inputs.dbt-core-ref || github.sha }}\n  cancel-in-progress: true\n\ndefaults:\n  run:\n    shell: bash\n\njobs:\n  job-prep:\n    # This allow us to run the workflow on pull_requests as well so we can always run unit tests\n    # and only run integration tests on merge for time purposes\n    name: Setup Repo Refs\n    runs-on: ubuntu-latest\n    outputs:\n      dbt-postgres-ref: ${{ steps.core-ref.outputs.ref }}\n      dbt-core-ref: ${{ steps.common-ref.outputs.ref }}\n\n    steps:\n      - name: \"Input Refs\"\n        id: job-inputs\n        run: |\n          echo \"inputs.dbt-postgres-ref=${{ inputs.dbt-postgres-ref }}\"\n          echo \"inputs.dbt-core-ref=${{ inputs.dbt-core-ref }}\"\n\n      - name: \"Determine dbt-postgres ref\"\n        id: core-ref\n        run: |\n          if [[ -z \"${{ inputs.dbt-postgres-ref }}\" ]]; then\n            REF=\"main\"\n          else\n            REF=${{ inputs.dbt-postgres-ref }}\n          fi\n          echo \"ref=$REF\" >> $GITHUB_OUTPUT\n\n      - name: \"Determine dbt-core ref\"\n        id: common-ref\n        run: |\n          if [[ -z \"${{ inputs.dbt-core-ref }}\" ]]; then\n            # these will be commits instead of branches\n            if [[ \"${{ github.event_name }}\" == \"merge_group\" ]]; then\n              REF=${{ github.event.merge_group.head_sha }}\n            else\n              REF=${{ github.event.pull_request.base.sha }}\n            fi\n          else\n            REF=${{ inputs.dbt-core-ref }}\n          fi\n          echo \"ref=$REF\" >> $GITHUB_OUTPUT\n\n      - name: \"Final Refs\"\n        run: |\n          echo \"dbt-postgres-ref=${{ steps.core-ref.outputs.ref }}\"\n          echo \"dbt-core-ref=${{ steps.common-ref.outputs.ref }}\"\n\n  # integration-tests-postgres:\n  #   name: \"dbt-postgres integration tests\"\n  #   needs: [job-prep]\n  #   runs-on: ubuntu-latest\n  #   defaults:\n  #     run:\n  #       working-directory: \"./dbt-postgres\"\n  #   environment:\n  #     name: \"dbt-postgres\"\n  #   env:\n  #     POSTGRES_TEST_HOST: ${{ vars.POSTGRES_TEST_HOST }}\n  #     POSTGRES_TEST_PORT: ${{ vars.POSTGRES_TEST_PORT }}\n  #     POSTGRES_TEST_USER: ${{ vars.POSTGRES_TEST_USER }}\n  #     POSTGRES_TEST_PASS: ${{ secrets.POSTGRES_TEST_PASS }}\n  #     POSTGRES_TEST_DATABASE: ${{ vars.POSTGRES_TEST_DATABASE }}\n  #     POSTGRES_TEST_THREADS: ${{ vars.POSTGRES_TEST_THREADS }}\n  #   services:\n  #     postgres:\n  #         image: postgres\n  #         env:\n  #           POSTGRES_PASSWORD: postgres\n  #         options: >-\n  #             --health-cmd pg_isready\n  #             --health-interval 10s\n  #             --health-timeout 5s\n  #             --health-retries 5\n  #         ports:\n  #           - ${{ vars.POSTGRES_TEST_PORT }}:5432\n  #   steps:\n  #     - name: \"Check out dbt-adapters@${{ needs.job-prep.outputs.dbt-postgres-ref }}\"\n  #       uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # actions/checkout@v4\n  #       with:\n  #         repository: dbt-labs/dbt-adapters\n  #         ref: ${{ needs.job-prep.outputs.dbt-postgres-ref }}\n\n  #     - name: \"Set up Python\"\n  #       uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # actions/setup-python@v5\n  #       with:\n  #           python-version: ${{ inputs.python-version }}\n\n  #     - name: \"Set environment variables\"\n  #       run: |\n  #           echo \"HATCH_PYTHON=${{ inputs.python-version }}\" >> $GITHUB_ENV\n  #           echo \"PIP_ONLY_BINARY=psycopg2-binary\" >> $GITHUB_ENV\n\n  #     - name: \"Setup test database\"\n  #       run: psql -f ./scripts/setup_test_database.sql\n  #       env:\n  #           PGHOST: ${{ vars.POSTGRES_TEST_HOST }}\n  #           PGPORT: ${{ vars.POSTGRES_TEST_PORT }}\n  #           PGUSER: postgres\n  #           PGPASSWORD: postgres\n  #           PGDATABASE: postgres\n\n  #     - name: \"Install hatch\"\n  #       uses: pypa/hatch@257e27e51a6a5616ed08a39a408a21c35c9931bc # pypa/hatch@install\n\n  #     - name: \"Run integration tests\"\n  #       run: hatch run ${{ inputs.hatch-env }}:integration-tests\n"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "version: 2\nupdates:\n  # python dependencies\n  - package-ecosystem: \"pip\"\n    directory: \"/\"\n    schedule:\n      interval: \"daily\"\n    rebase-strategy: \"disabled\"\n  - package-ecosystem: \"pip\"\n    directory: \"/core\"\n    schedule:\n      interval: \"daily\"\n    rebase-strategy: \"disabled\"\n\n  # docker dependencies\n  - package-ecosystem: \"docker\"\n    directory: \"/\"\n    schedule:\n      interval: \"weekly\"\n    rebase-strategy: \"disabled\"\n  - package-ecosystem: \"docker\"\n    directory: \"/docker\"\n    schedule:\n      interval: \"weekly\"\n    rebase-strategy: \"disabled\"\n\n  # github dependencies\n  - package-ecosystem: \"github-actions\"\n    directory: \"/\"\n    schedule:\n      interval: \"weekly\"\n    rebase-strategy: \"disabled\"\n"
  },
  {
    "path": ".github/pull_request_template.md",
    "content": "Resolves #\n\n<!---\n  Include the number of the issue addressed by this PR above, if applicable.\n  PRs for code changes without an associated issue *will not be merged*.\n  See CONTRIBUTING.md for more information.\n\n  Add the `user docs` label to this PR if it will need docs changes.  An \n  issue will get opened in docs.getdbt.com upon successful merge of this PR.\n-->\n\n### Problem\n\n<!---\n  Describe the problem this PR is solving. What is the application state\n  before this PR is merged?\n-->\n\n### Solution\n\n<!---\n  Describe the way this PR solves the above problem. Add as much detail as you\n  can to help reviewers understand your changes. Include any alternatives and\n  tradeoffs you considered.\n-->\n\n### Checklist\n\n- [ ] I have read [the contributing guide](https://github.com/dbt-labs/dbt-core/blob/main/CONTRIBUTING.md) and understand what's expected of me.\n- [ ] I have run this code in development, and it appears to resolve the stated issue.\n- [ ] This PR includes tests, or tests are not required or relevant for this PR.\n- [ ] This PR has no interface changes (e.g., macros, CLI, logs, JSON artifacts, config files, adapter interface, etc.) or this PR has already received feedback and approval from Product or DX.\n- [ ] This PR includes [type annotations](https://docs.python.org/3/library/typing.html) for new and modified functions.\n"
  },
  {
    "path": ".github/workflows/artifact-reviews.yml",
    "content": "# **what?**\n# Enforces 2 reviews when artifact or validation files are modified.\n\n# **why?**\n# Ensure artifact changes receive proper review from designated team members.  GitHub doesn't support\n# multiple reviews on a single PR based on files changed, so we need to enforce this manually.\n\n# **when?**\n# This will run when reviews are submitted and dismissed.\n\nname: \"Enforce Additional Reviews on Artifact and Validations Changes\"\n\npermissions:\n  checks: write\n  pull-requests: write\n  contents: read\n\non:\n  # trigger check on review events.  use pull_request_target for forks.\n  pull_request_target:\n    types: [opened, reopened, ready_for_review, synchronize, review_requested]\n  pull_request_review:\n    types: [submitted, edited, dismissed]\n\n# only run this once per PR at a time\nconcurrency:\n  group: ${{ github.workflow }}-${{ github.event.pull_request.number }}\n  cancel-in-progress: true\n\nenv:\n    required_approvals: 2\n    team: \"core-group\"\n\njobs:\n  check-reviews:\n    name: \"Validate Additional Reviews\"\n    runs-on: ubuntu-latest\n    steps:\n      - name: \"Get list of changed files\"\n        id: changed_files\n        run: |\n          # Fetch files as JSON and process with jq to sanitize output\n          gh api repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files \\\n            | jq -r '.[].filename' \\\n            | while IFS= read -r file; do\n              # Sanitize the filename by removing any special characters and command injection attempts\n              clean_file=$(echo \"$file\" | sed 's/[^a-zA-Z0-9\\.\\/\\-_]//g')\n              echo \"$clean_file\"\n            done > changed_files.txt\n          echo \"CHANGED_FILES<<EOF\" >> $GITHUB_OUTPUT\n          cat changed_files.txt >> $GITHUB_OUTPUT\n          echo \"EOF\" >> $GITHUB_OUTPUT\n        env:\n          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n\n      - name: \"Check if any artifact files changed\"\n        id: artifact_files_changed\n        run: |\n          artifact_changes=false\n          while IFS= read -r file; do\n            # Only process if file path looks legitimate\n            if [[ \"$file\" =~ ^[a-zA-Z0-9\\.\\/\\-_]+$ ]]; then\n              if [[ \"$file\" == \"core/dbt/artifacts/\"* ]] ; then\n                artifact_changes=true\n                break\n              fi\n            fi\n          done < changed_files.txt\n          echo \"artifact_changes=$artifact_changes\" >> $GITHUB_OUTPUT\n\n      - name: \"Get Core Team Members\"\n        if: steps.artifact_files_changed.outputs.artifact_changes == 'true'\n        id: core_members\n        run: |\n          gh api -H \"Accept: application/vnd.github+json\" \\\n          /orgs/dbt-labs/teams/${{ env.team }}/members > core_members.json\n\n          # Extract usernames and set as multiline output\n          echo \"membership<<EOF\" >> $GITHUB_OUTPUT\n          jq -r '.[].login' core_members.json >> $GITHUB_OUTPUT\n          echo \"EOF\" >> $GITHUB_OUTPUT\n        env:\n          GH_TOKEN: ${{ secrets.IT_TEAM_MEMBERSHIP }}\n\n      - name: \"Verify ${{ env.required_approvals }} core team approvals\"\n        if: steps.artifact_files_changed.outputs.artifact_changes == 'true'\n        id: check_approvals\n        run: |\n\n            # Get all reviews\n            REVIEWS=$(gh api repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/reviews)\n            echo \"All reviews:\"\n            echo \"$REVIEWS\"\n            # Count approved reviews from core team members (only most recent review per user)\n            CORE_APPROVALS=0\n            while IFS= read -r member; do\n              echo \"Checking member: $member\"\n              APPROVED=$(echo \"$REVIEWS\" | jq --arg user \"$member\" '\n                group_by(.user.login) |\n                map(select(.[0].user.login == $user) |\n                    sort_by(.submitted_at) |\n                    last) |\n                map(select(.state == \"APPROVED\" and (.state != \"DISMISSED\"))) |\n                length')\n              echo \"Latest review state for $member: $APPROVED\"\n              CORE_APPROVALS=$((CORE_APPROVALS + APPROVED))\n              echo \"Running total: $CORE_APPROVALS\"\n            done <<< \"${{ steps.core_members.outputs.membership }}\"\n\n            echo \"CORE_APPROVALS=$CORE_APPROVALS\" >> $GITHUB_OUTPUT\n            echo \"CORE_APPROVALS=$CORE_APPROVALS\"\n        env:\n          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n\n      - name: \"Find Comment\"\n        if: steps.artifact_files_changed.outputs.artifact_changes == 'true' && steps.check_approvals.outputs.CORE_APPROVALS < env.required_approvals\n        uses: peter-evans/find-comment@a54c31d7fa095754bfef525c0c8e5e5674c4b4b1 # peter-evans/find-comment@v2\n        id: find-comment\n        with:\n          issue-number: ${{ github.event.pull_request.number }}\n          comment-author: 'github-actions[bot]'\n          body-includes: \"### Additional Artifact Review Required\"\n\n      - name: \"Create Comment\"\n        if: steps.artifact_files_changed.outputs.artifact_changes == 'true' && steps.find-comment.outputs.comment-id == '' && steps.check_approvals.outputs.CORE_APPROVALS < env.required_approvals\n        uses: peter-evans/create-or-update-comment@23ff15729ef2fc348714a3bb66d2f655ca9066f2 # peter-evans/create-or-update-comment@v3\n        with:\n          issue-number: ${{ github.event.pull_request.number }}\n          body: |\n            ### Additional Artifact Review Required\n\n            Changes to artifact directory files requires at least ${{ env.required_approvals }} approvals from core team members.\n\n      - name: \"Notify if not enough approvals\"\n        if: steps.artifact_files_changed.outputs.artifact_changes == 'true'\n        run: |\n          if [[ \"${{ steps.check_approvals.outputs.CORE_APPROVALS }}\" -ge \"${{ env.required_approvals }}\" ]]; then\n            title=\"Extra requirements met\"\n            message=\"Changes to artifact directory files requires at least ${{ env.required_approvals }} approvals from core team members. Current number of core team approvals: ${{ steps.check_approvals.outputs.CORE_APPROVALS }} \"\n            echo \"::notice title=$title::$message\"\n            echo \"REVIEW_STATUS=success\" >> $GITHUB_OUTPUT\n          else\n            title=\"PR Approval Requirements Not Met\"\n            message=\"Changes to artifact directory files requires at least ${{ env.required_approvals }} approvals from core team members. Current number of core team approvals: ${{ steps.check_approvals.outputs.CORE_APPROVALS }} \"\n            echo \"::notice title=$title::$message\"\n            echo \"REVIEW_STATUS=neutral\" >> $GITHUB_OUTPUT\n          fi\n        id: review_check\n\n      - name: \"Set check status\"\n        id: status_check\n        run: |\n          if [[ \"${{ steps.artifact_files_changed.outputs.artifact_changes }}\" == 'false' ]]; then\n            # no extra review required\n            echo \"current_status=success\" >> $GITHUB_OUTPUT\n          elif [[ \"${{ steps.review_check.outputs.REVIEW_STATUS }}\" == \"success\" ]]; then\n            # we have all the required reviews\n            echo \"current_status=success\" >> $GITHUB_OUTPUT\n          else\n            # neutral exit - neither success nor failure\n            # we can't fail here because we use multiple triggers for this workflow and they won't reset the check\n            # workaround is to use a neutral exit to skip the check run until it's actually successful\n            echo \"current_status=neutral\" >> $GITHUB_OUTPUT\n          fi\n\n      - name: \"Post Event\"\n        # This step posts the status of the check because the workflow is triggered by multiple events\n        # and we need to ensure the check is always updated.  Otherwise we would end up with duplicate\n        # checks in the GitHub UI.\n        run: |\n          if [[ \"${{ steps.status_check.outputs.current_status }}\" == \"success\" ]]; then\n            state=\"success\"\n          else\n            state=\"failure\"\n          fi\n\n          gh api \\\n            --method POST \\\n            -H \"Accept: application/vnd.github+json\" \\\n            /repos/${{ github.repository }}/statuses/${{ github.event.pull_request.base.sha }} \\\n            -f state=\"$state\" \\\n            -f description=\"Artifact Review Check\" \\\n            -f context=\"Artifact Review Check\" \\\n            -f target_url=\"${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}\"\n        env:\n          GH_TOKEN: ${{ secrets.FISHTOWN_BOT_PAT }}\n"
  },
  {
    "path": ".github/workflows/auto-respond-bug-reports.yml",
    "content": "# **what?**\n# Check if the an issue is opened near or during an extended holiday period.\n# If so, post an automatically-generated comment about the holiday for bug reports.\n# Also provide specific information to customers of dbt Cloud.\n\n# **why?**\n# Explain why responses will be delayed during our holiday period.\n\n# **when?**\n# This will run when new issues are opened.\n\nname: Auto-Respond to Bug Reports During Holiday Period\n\non:\n  issues:\n    types:\n      - opened\n\npermissions:\n  contents: read\n  issues: write\n\njobs:\n  auto-response:\n    runs-on: ${{ vars.UBUNTU_LATEST }}\n    steps:\n      - name: Check if current date is within holiday period\n        id: date-check\n        run: |\n          current_date=$(date -u +\"%Y-%m-%d\")\n          start_date=\"2024-12-23\"\n          end_date=\"2025-01-05\"\n\n          if [[ \"$current_date\" < \"$start_date\" || \"$current_date\" > \"$end_date\" ]]; then\n            echo \"outside_holiday=true\" >> $GITHUB_ENV\n          else\n            echo \"outside_holiday=false\" >> $GITHUB_ENV\n          fi\n\n      - name: Post comment\n        if: ${{ env.outside_holiday == 'false' && contains(github.event.issue.labels.*.name, 'bug') }}\n        run: |\n          gh issue comment ${{ github.event.issue.number }} --repo ${{ github.repository }} --body \"Thank you for your bug report! Our team is will be out of the office for [Christmas and our Global Week of Rest](https://handbook.getdbt.com/docs/time_off#2024-us-holidays), from December 25, 2024, through January 3, 2025.\n\n          We will review your issue as soon as possible after returning.\n          Thank you for your understanding, and happy holidays! 🎄🎉\n\n          If you are a customer of dbt Cloud, please contact our Customer Support team via the dbt Cloud web interface or email **support@dbtlabs.com**.\"\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/backport.yml",
    "content": "# **what?**\n# When a PR is merged, if it has the backport label, it will create\n# a new PR to backport those changes to the given branch. If it can't\n# cleanly do a backport, it will comment on the merged PR of the failure.\n#\n# Label naming convention: \"backport <branch name to backport to>\"\n# Example: backport 1.0.latest\n#\n# You MUST \"Squash and merge\" the original PR or this won't work.\n\n# **why?**\n# Changes sometimes need to be backported to release branches.\n# This automates the backporting process\n\n# **when?**\n# Once a PR is \"Squash and merge\"'d, by adding a backport label, this is triggered\n\nname: Backport\non:\n  pull_request:\n    types:\n      - labeled\n\npermissions:\n  contents: write\n  pull-requests: write\n\njobs:\n  backport:\n    name: Backport\n    runs-on: ${{ vars.UBUNTU_LATEST }}\n    # Only react to merged PRs for security reasons.\n    # See https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target.\n    if: >\n      github.event.pull_request.merged\n      && contains(github.event.label.name, 'backport')\n    steps:\n      - uses: tibdex/backport@9565281eda0731b1d20c4025c43339fb0a23812e # tibdex/backport@v2.0.4\n        with:\n          github_token: ${{ secrets.GITHUB_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/bot-changelog.yml",
    "content": "# **what?**\n# When bots create a PR, this action will add a corresponding changie yaml file to that\n# PR when a specific label is added.\n#\n# The file is created off a template:\n#\n# kind: <per action matrix>\n# body: <PR title>\n# time: <current timestamp>\n# custom:\n#   Author: <PR User Login (generally the bot)>\n#   Issue: 4904\n#   PR: <PR number>\n#\n# **why?**\n# Automate changelog generation for more visability with automated bot PRs.\n#\n# **when?**\n# Once a PR is created, label should be added to PR before or after creation. You can also\n#  manually trigger this by adding the appropriate label at any time.\n#\n# **how to add another bot?**\n# Add the label and changie kind to the include matrix.  That's it!\n#\n\nname: Bot Changelog\n\non:\n  pull_request:\n    # catch when the PR is opened with the label or when the label is added\n    types: [labeled]\n\npermissions:\n  contents: write\n  pull-requests: read\n\njobs:\n  generate_changelog:\n    strategy:\n      matrix:\n        include:\n          - label: \"dependencies\"\n            changie_kind: \"Dependencies\"\n    runs-on: ${{ vars.UBUNTU_LATEST }}\n\n    steps:\n\n    - name: Create and commit changelog on bot PR\n      if: ${{ contains(github.event.pull_request.labels.*.name, matrix.label) }}\n      id: bot_changelog\n      uses: emmyoop/changie_bot@22b70618b13d0d1c64ea95212bafca2d2bf6b764 # emmyoop/changie_bot@v1.1.0\n      with:\n        GITHUB_TOKEN: ${{ secrets.FISHTOWN_BOT_PAT }}\n        commit_author_name: \"Github Build Bot\"\n        commit_author_email: \"<buildbot@fishtownanalytics.com>\"\n        commit_message: \"Add automated changelog yaml from template for bot PR\"\n        changie_kind: ${{ matrix.changie_kind }}\n        label: ${{ matrix.label }}\n        custom_changelog_string: \"custom:\\n  Author: ${{ github.event.pull_request.user.login }}\\n  Issue: ${{ github.event.pull_request.number }}\"\n"
  },
  {
    "path": ".github/workflows/changelog-existence.yml",
    "content": "# **what?**\n# Checks that a file has been committed under the /.changes directory\n# as a new CHANGELOG entry.  Cannot check for a specific filename as\n# it is dynamically generated by change type and timestamp.\n# This workflow runs on pull_request_target because it requires\n# secrets to post comments.\n\n# **why?**\n# Ensure code change gets reflected in the CHANGELOG.\n\n# **when?**\n# This will run for all PRs going into main and *.latest.  It will\n# run when they are opened, reopened, when any label is added or removed\n# and when new code is pushed to the branch.  The action will then get\n# skipped if the 'Skip Changelog' label is present is any of the labels.\n\nname: Check Changelog Entry\n\non:\n  pull_request_target:\n    types: [opened, reopened, labeled, unlabeled, synchronize]\n    paths-ignore: ['.changes/**', '.github/**', 'tests/**', '**.md', '**.yml']\n\n  workflow_dispatch:\n\ndefaults:\n  run:\n    shell: bash\n\npermissions:\n  contents: read\n  pull-requests: write\n\njobs:\n  changelog:\n    uses: dbt-labs/actions/.github/workflows/changelog-existence.yml@main\n    with:\n      changelog_comment: 'Thank you for your pull request! We could not find a changelog entry for this change. For details on how to document a change, see [the contributing guide](https://github.com/dbt-labs/dbt-core/blob/main/CONTRIBUTING.md#adding-changelog-entry).'\n      skip_label: 'Skip Changelog'\n    secrets: inherit\n"
  },
  {
    "path": ".github/workflows/check-artifact-changes.yml",
    "content": "name: Check Artifact Changes\n\non:\n  pull_request:\n    types: [ opened, reopened, labeled, unlabeled, synchronize ]\n    paths-ignore: [ '.changes/**', '.github/**', 'tests/**', '**.md', '**.yml' ]\n  merge_group:\n    types: [checks_requested]\n  workflow_dispatch:\n\npermissions:\n  contents: read\n\njobs:\n  check-artifact-changes:\n    runs-on: ${{ vars.UBUNTU_LATEST }}\n    if: ${{ !contains(github.event.pull_request.labels.*.name, 'artifact_minor_upgrade') }}\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # actions/checkout@v4\n        with:\n          fetch-depth: 0\n\n      - name: Check for changes in core/dbt/artifacts\n        # https://github.com/marketplace/actions/paths-changes-filter\n        uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # dorny/paths-filter@v3\n        id: check_artifact_changes\n        with:\n          filters: |\n            artifacts_changed:\n              - 'core/dbt/artifacts/**'\n          list-files: shell\n\n      - name: Fail CI if artifacts have changed\n        if: steps.check_artifact_changes.outputs.artifacts_changed == 'true'\n        run: |\n          echo \"CI failure: Artifact changes checked in core/dbt/artifacts directory.\"\n          echo \"Files changed: ${{ steps.check_artifact_changes.outputs.artifacts_changed_files }}\"\n          echo \"To bypass this check, confirm that the change is not breaking (https://github.com/dbt-labs/dbt-core/blob/main/core/dbt/artifacts/README.md#breaking-changes) and add the 'artifact_minor_upgrade' label to the PR. Modifications and additions to all fields require updates to https://github.com/dbt-labs/dbt-jsonschema.\"\n          exit 1\n\n      - name: CI check passed\n        if: steps.check_artifact_changes.outputs.artifacts_changed == 'false'\n        run: |\n          echo \"No prohibited artifact changes found in core/dbt/artifacts. CI check passed.\"\n"
  },
  {
    "path": ".github/workflows/community-label.yml",
    "content": "# **what?**\n# Label a PR with a `community` label when a PR is opened by a user outside core/adapters\n\n# **why?**\n# To streamline triage and ensure that community contributions are recognized and prioritized\n\n# **when?**\n# When a PR is opened, not in draft or moved from draft to ready for review\n\nname: Label community PRs\n\non:\n  # have to use pull_request_target since community PRs come from forks\n  pull_request_target:\n    types: [opened, ready_for_review]\n\ndefaults:\n  run:\n    shell: bash\n\npermissions:\n    pull-requests: write # labels PRs\n    contents: read # reads team membership\n\njobs:\n  open_issues:\n    # If this PR already has the community label, no need to relabel it\n    # If this PR is opened and not draft, determine if it needs to be labeled\n    # if the PR is converted out of draft, determine if it needs to be labeled\n    if: |\n      (\n        !contains(github.event.pull_request.labels.*.name, 'community')\n        && (\n          (github.event.action == 'opened' && github.event.pull_request.draft == false)\n          || github.event.action == 'ready_for_review'\n        )\n        && github.event.pull_request.user.type != 'Bot'\n        && github.event.pull_request.user.login != 'dependabot[bot]'\n      )\n    uses: dbt-labs/actions/.github/workflows/label-community.yml@main\n    with:\n        github_team: 'core-group'\n        label: 'community'\n    secrets: inherit\n"
  },
  {
    "path": ".github/workflows/cut-release-branch.yml",
    "content": "# **what?**\n# Cuts the `*.latest` branch, bumps dependencies on it, cleans up all files in `.changes/unreleased`\n# and `.changes/previous verion on main and bumps main to the input version.\n\n# **why?**\n# Clean up the main branch after a release branch is cut and automate cutting the release branch.\n# Generally reduces the workload of engineers and reducing error.\n\n# **when?**\n# This will run when called manually or when triggered in another workflow.\n\n# Example Usage including required permissions:  TODO: update once finalized\n\n# permissions:\n#   contents: read\n#   pull-requests: write\n#\n# name: Cut Release Branch\n# jobs:\n#   changelog:\n#     uses: dbt-labs/actions/.github/workflows/cut-release-branch.yml@main\n#     with:\n#       new_branch_name: 1.7.latest\n#       PR_title: \"Cleanup main after cutting new 1.7.latest branch\"\n#       PR_body: \"All adapter PRs will fail CI until the dbt-core PR has been merged due to release version conflicts.\"\n#     secrets:\n#       FISHTOWN_BOT_PAT: ${{ secrets.FISHTOWN_BOT_PAT }}\n\n# TODOs\n# add note to eventually commit changes directly and bypass checks - same as release - when we move to this model run test action after merge\n\nname: Cut new release branch\nrun-name: \"Cutting New Branch:  ${{ inputs.new_branch_name }}\"\n\non:\n  workflow_dispatch:\n    inputs:\n      new_branch_name:\n        description: \"The full name of the new branch (ex. 1.5.latest)\"\n        required: true\n        type: string\n\ndefaults:\n  run:\n    shell: bash\n\npermissions:\n  contents: write\n  pull-requests: write\n\nenv:\n  PYTHON_TARGET_VERSION: \"3.10\"\n  PR_TITLE: \"Cleanup main after cutting new ${{ inputs.new_branch_name }} branch\"\n  PR_BODY: \"All adapter PRs will fail CI until the dbt-core PR has been merged due to release version conflicts.\"\n\njobs:\n  prep_work:\n    name: \"Prep Work\"\n    runs-on: ubuntu-latest\n    steps:\n      - name: \"[DEBUG] Print Inputs\"\n        run: |\n          echo \"new_branch_name:        ${{ inputs.new_branch_name }}\"\n          echo \"PR_title:               ${{ env.PR_TITLE }}\"\n          echo \"PR_body:                ${{ env.PR_BODY }}\"\n\n  create_temp_branch:\n    name: \"Create Temp branch off main\"\n    runs-on: ubuntu-latest\n    outputs:\n      temp_branch_name: ${{ steps.variables.outputs.BRANCH_NAME }}\n\n    steps:\n      - name: \"Set Branch Value\"\n        id: variables\n        run: |\n          echo \"BRANCH_NAME=cutting_release_branch/main_cleanup_$GITHUB_RUN_ID\" >> $GITHUB_OUTPUT\n\n      - name: \"Checkout ${{ github.repository }}\"\n        uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # actions/checkout@v4\n        with:\n          ref: \"main\"\n          token: ${{ secrets.FISHTOWN_BOT_PAT }}\n\n      - name: \"Create PR Branch\"\n        run: |\n          user=\"Github Build Bot\"\n          email=\"buildbot@fishtownanalytics.com\"\n          git config user.name \"$user\"\n          git config user.email \"$email\"\n          git checkout -b ${{ steps.variables.outputs.BRANCH_NAME }}\n          git push --set-upstream origin ${{ steps.variables.outputs.BRANCH_NAME }}\n\n      - name: \"[Notification] Temp branch created\"\n        run: |\n          message=\"Temp branch ${{ steps.variables.outputs.BRANCH_NAME }} created\"\n          echo \"::notice title=\"Temporary branch created\": $title::$message\"\n\n  cleanup_changelog:\n    name: \"Clean Up Changelog\"\n    needs: [\"create_temp_branch\"]\n    runs-on: ubuntu-latest\n    outputs:\n      next-version: ${{ steps.semver-current.outputs.next-minor-alpha-version }}\n\n    steps:\n      - name: \"Checkout ${{ github.repository }}\"\n        uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # actions/checkout@v4\n        with:\n          ref: ${{ needs.create_temp_branch.outputs.temp_branch_name }}\n          token: ${{ secrets.FISHTOWN_BOT_PAT }}\n\n      - name: \"Add Homebrew To PATH\"\n        run: |\n          echo \"/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin\" >> $GITHUB_PATH\n\n      - name: \"Install Homebrew Packages\"\n        run: |\n          brew install pre-commit\n          brew tap miniscruff/changie https://github.com/miniscruff/changie\n          brew install changie\n\n      - name: \"Check Current Version In Code\"\n        id: determine_version\n        run: |\n          current_version=$(grep '^version = ' core/pyproject.toml | sed 's/version = \"\\(.*\\)\"/\\1/')\n          echo \"current_version=$current_version\" >> $GITHUB_OUTPUT\n\n      - name: \"[Notification] Check Current Version In Code\"\n        run: |\n          message=\"The current version is ${{ steps.determine_version.outputs.current_version }}\"\n          echo \"::notice title=\"Version Bump Check\": $title::$message\"\n\n      - name: \"Parse Current Version Into Parts for Changelog Directories\"\n        id: semver-current\n        uses: dbt-labs/actions/parse-semver@v1\n        with:\n          version: ${{ steps.determine_version.outputs.current_version }}\n\n      - name: \"[Notification] Next Alpha Version\"\n        run: |\n          message=\"The next alpha version is ${{ steps.semver-current.outputs.next-minor-alpha-version }}\"\n          echo \"::notice title=\"Version Bump Check\": $title::$message\"\n\n      - name: \"Delete Unreleased Changelog YAMLs\"\n        # removal fails if no files exist. OK to continue since we're just cleaning up the files.\n        continue-on-error: true\n        run: |\n          rm .changes/unreleased/*.yaml || true\n\n      - name: \"Delete Pre Release Changelogs and YAMLs\"\n        # removal fails if no files exist. OK to continue since we're just cleaning up the files.\n        continue-on-error: true\n        run: |\n          rm .changes/${{ steps.semver-current.outputs.base-version }}/*.yaml || true\n          rm .changes/${{ steps.semver-current.outputs.major }}.${{ steps.semver-current.outputs.minor }}.*.md || true\n\n      - name: \"Cleanup CHANGELOG.md\"\n        run: |\n          changie merge\n\n      - name: \"Commit Changelog Cleanup to Branch\"\n        run: |\n          user=\"Github Build Bot\"\n          email=\"buildbot@fishtownanalytics.com\"\n          git config user.name \"$user\"\n          git config user.email \"$email\"\n          git status\n          git add .\n          git commit -m \"Clean up changelog on main\"\n          git push\n\n      - name: \"[Notification] Changelog cleaned up\"\n        run: |\n          message=\"Changelog on ${{ needs.create_temp_branch.outputs.temp_branch_name }} cleaned up\"\n          echo \"::notice title=\"Changelog cleaned up\": $title::$message\"\n\n  bump_version:\n    name: \"Bump to next minor version\"\n    needs: [\"cleanup_changelog\", \"create_temp_branch\"]\n    runs-on: ubuntu-latest\n\n    steps:\n      - name: \"Checkout ${{ github.repository }}\"\n        uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # actions/checkout@v4\n        with:\n          ref: ${{ needs.create_temp_branch.outputs.temp_branch_name }}\n          token: ${{ secrets.FISHTOWN_BOT_PAT }}\n\n      - name: \"Set up Python - ${{ env.PYTHON_TARGET_VERSION }}\"\n        uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # actions/setup-python@v5\n        with:\n          python-version: \"${{ env.PYTHON_TARGET_VERSION }}\"\n\n      - name: \"Install Spark Dependencies\"\n        if: ${{ contains(github.repository, 'dbt-labs/dbt-spark') }}\n        run: |\n          sudo apt-get update\n          sudo apt-get install libsasl2-dev\n\n      - name: \"Install hatch\"\n        uses: pypa/hatch@257e27e51a6a5616ed08a39a408a21c35c9931bc # pypa/hatch@install\n\n      - name: \"Bump Version To ${{ needs.cleanup_changelog.outputs.next-version }}\"\n        run: |\n          cd core\n          hatch version ${{ needs.cleanup_changelog.outputs.next-version }}\n          hatch run dev-req\n          dbt --version\n\n      - name: \"Commit Version Bump to Branch\"\n        run: |\n          user=\"Github Build Bot\"\n          email=\"buildbot@fishtownanalytics.com\"\n          git config user.name \"$user\"\n          git config user.email \"$email\"\n          git status\n          git add .\n          git commit -m \"Bumping version to ${{ needs.cleanup_changelog.outputs.next-version }}\"\n          git push\n\n      - name: \"[Notification] Version Bump completed\"\n        run: |\n          message=\"Version on ${{ needs.create_temp_branch.outputs.temp_branch_name }} bumped to ${{ needs.cleanup_changelog.outputs.next-version }}\"\n          echo \"::notice title=\"Version Bump Completed\": $title::$message\"\n\n  cleanup:\n    name: \"Cleanup Code Quality\"\n    needs: [\"create_temp_branch\", \"bump_version\"]\n    runs-on: ubuntu-latest\n    steps:\n      - name: \"Checkout ${{ github.repository }}\"\n        uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # actions/checkout@v4\n        with:\n          ref: ${{ needs.create_temp_branch.outputs.temp_branch_name }}\n          token: ${{ secrets.FISHTOWN_BOT_PAT }}\n\n      - name: \"Add Homebrew To PATH\"\n        run: |\n          echo \"/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin\" >> $GITHUB_PATH\n\n      - name: \"brew install pre-commit\"\n        run: |\n          brew install pre-commit\n\n      # this step will fail on whitespace errors but also correct them\n      - name: \"Cleanup - Remove Trailing Whitespace Via Pre-commit\"\n        continue-on-error: true\n        run: |\n          pre-commit run trailing-whitespace --files CHANGELOG.md .changes/* || true\n\n      # this step will fail on newline errors but also correct them\n      - name: \"Cleanup - Remove Extra Newlines Via Pre-commit\"\n        continue-on-error: true\n        run: |\n          pre-commit run end-of-file-fixer --files CHANGELOG.md .changes/* || true\n\n      - name: \"Commit Version Bump to Branch\"\n        run: |\n          user=\"Github Build Bot\"\n          email=\"buildbot@fishtownanalytics.com\"\n          git config user.name \"$user\"\n          git config user.email \"$email\"\n          git status\n          git add .\n          git commit -m \"Code quality cleanup\"\n          git push\n\n  open_pr:\n    name: \"Open PR Against main\"\n    needs: [\"cleanup_changelog\", \"create_temp_branch\", \"cleanup\"]\n    runs-on: ubuntu-latest\n    outputs:\n      pr_number: ${{ steps.create_pr.outputs.pull-request-number }}\n\n    steps:\n      - name: \"Checkout ${{ github.repository }}\"\n        uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # actions/checkout@v4\n        with:\n          ref: ${{ needs.create_temp_branch.outputs.temp_branch_name }}\n          token: ${{ secrets.FISHTOWN_BOT_PAT }}\n\n      - name: \"Determine PR Title\"\n        id: pr_title\n        run: |\n          echo \"pr_title=${{ env.PR_TITLE }}\" >> $GITHUB_OUTPUT\n          if [${{ env.PR_TITLE }} == \"\"]; then\n            echo \"pr_title='Clean up changelogs and bump to version ${{ needs.cleanup_changelog.outputs.next-version }}'\" >> $GITHUB_OUTPUT\n          fi\n\n      - name: \"Determine PR Body\"\n        id: pr_body\n        run: |\n          echo \"pr_body=${{ env.PR_BODY }}\" >> $GITHUB_OUTPUT\n          if [${{ env.PR_BODY }} == \"\"]; then\n            echo \"pr_body='Clean up changelogs and bump to version ${{ needs.cleanup_changelog.outputs.next-version }}'\" >> $GITHUB_OUTPUT\n          fi\n\n      - name: \"Add Branch Details\"\n        id: pr_body_branch\n        run: |\n          branch_details=\"The workflow that generated this PR also created a new branch: ${{ inputs.new_branch_name }}\"\n          full_body=\"${{ steps.pr_body.outputs.pr_body }} $branch_details\"\n          echo \"pr_full_body=$full_body\" >> $GITHUB_OUTPUT\n\n      - name: \"Open Pull Request\"\n        id: create_pr\n        run: |\n          pr_url=$(gh pr create -B main -H ${{ needs.create_temp_branch.outputs.temp_branch_name }} -l \"Skip Changelog\" -t \"${{ steps.pr_title.outputs.pr_title }}\" -b \"${{ steps.pr_body_branch.outputs.pr_full_body }}\")\n          echo \"pr_url=$pr_url\" >> $GITHUB_OUTPUT\n        env:\n          GH_TOKEN: ${{ secrets.FISHTOWN_BOT_PAT }}\n\n      - name: \"[Notification] Pull Request Opened\"\n        run: |\n          message=\"PR opened at ${{ steps.create_pr.outputs.pr_url }}\"\n          echo \"::notice title=\"Pull Request Opened\": $title::$message\"\n\n  cut_new_branch:\n    # don't cut the new branch until we're done opening the PR against main\n    name: \"Cut New Branch ${{ inputs.new_branch_name }}\"\n    needs: [open_pr]\n    runs-on: ubuntu-latest\n\n    steps:\n      - name: \"Checkout ${{ github.repository }}\"\n        uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # actions/checkout@v4\n        with:\n          token: ${{ secrets.FISHTOWN_BOT_PAT }}\n          fetch-depth: 0\n\n      - name: \"Ensure New Branch Does Not Exist\"\n        id: check_new_branch\n        run: |\n          title=\"Check New Branch Existence\"\n          if git show-ref --quiet ${{ inputs.new_branch_name }}; then\n            message=\"Branch ${{ inputs.new_branch_name }} already exists.  Exiting.\"\n            echo \"::error $title::$message\"\n            exit 1\n          fi\n\n      - name: \"Create New Release Branch\"\n        run: |\n          git checkout -b ${{ inputs.new_branch_name }}\n\n      - name: \"Push up New Branch\"\n        run: |\n          #Data for commit\n          user=\"Github Build Bot\"\n          email=\"buildbot@fishtownanalytics.com\"\n          git config user.name \"$user\"\n          git config user.email \"$email\"\n          git push --set-upstream origin ${{ inputs.new_branch_name }}\n\n      - name: \"[Notification] New branch created\"\n        run: |\n          message=\"New branch ${{ inputs.new_branch_name }} created\"\n          echo \"::notice title=\"New branch created\": $title::$message\"\n\n      - name: \"Bump dependencies via script\"\n        # This bumps the dependency on dbt-core in the adapters\n        if: ${{ !contains(github.repository, 'dbt-core') }}\n        run: |\n          echo ${{ github.repository }}\n          echo \"running update_dependencies script\"\n          bash ${GITHUB_WORKSPACE}/.github/scripts/update_dependencies.sh ${{ inputs.new_branch_name }}\n          commit_message=\"bumping .latest branch variable in update_dependencies.sh to ${{ inputs.new_branch_name }}\"\n          git status\n          git add .\n          git commit -m \"$commit_message\"\n          git push\n\n      - name: \"Bump env variable via script\"\n        # bumps the RELEASE_BRANCH variable in nightly-release.yml in adapters\n        if: ${{ !contains(github.repository, 'dbt-core') }}\n        run: |\n          file=\"./.github/scripts/update_release_branch.sh\"\n          if test -f \"$file\"; then\n            echo ${{ github.repository }}\n            echo \"running some script yet to be written now\"\n            bash $file ${{ inputs.new_branch_name }}\n            commit_message=\"updating env variable to ${{ inputs.new_branch_name }} in nightly-release.yml\"\n            git status\n            git add .\n            git commit -m \"$commit_message\"\n            git push\n          else\n            echo \"no $file seen skipping step\"\n          fi\n"
  },
  {
    "path": ".github/workflows/docs-issue.yml",
    "content": "# **what?**\n# Open an issue in docs.getdbt.com when an issue is labeled `user docs` and closed as completed\n\n# **why?**\n# To reduce barriers for keeping docs up to date\n\n# **when?**\n# When an issue is labeled `user docs` and is closed as completed.  Can be labeled before or after the issue is closed.\n\n\nname: Open issues in docs.getdbt.com repo when an issue is labeled\nrun-name: \"Open an issue in docs.getdbt.com for issue #${{ github.event.issue.number }}\"\n\non:\n  issues:\n    types: [labeled, closed]\n\ndefaults:\n  run:\n    shell: bash\n\npermissions:\n    issues: write # comments on issues\n\njobs:\n  get_pr_info:\n    # we only want to run this when the issue is closed as completed and the label `user docs` has been assigned.\n    # If this logic does not exist in this workflow, it runs the\n    # risk of duplicaton of issues being created due to merge and label both triggering this workflow to run and neither having\n    # generating the comment before the other runs.  This lives here instead of the shared workflow because this is where we\n    # decide if it should run or not.\n    if: |\n      (github.event.issue.state == 'closed' &&\n       github.event.issue.state_reason == 'completed' &&\n       contains( github.event.issue.labels.*.name, 'user docs'))\n    runs-on: ubuntu-latest\n    outputs:\n      pr_url: ${{ steps.find_pr.outputs.pr_url }}\n      pr_title: ${{ steps.find_pr.outputs.pr_title }}\n    steps:\n      - name: Find closing PR via timeline\n        id: find_pr\n        uses: actions/github-script@v7\n        with:\n          script: |\n            const result = await github.graphql(`\n              query($owner: String!, $repo: String!, $number: Int!) {\n                repository(owner: $owner, name: $repo) {\n                  issue(number: $number) {\n                    timelineItems(itemTypes: [CLOSED_EVENT], last: 1) {\n                      nodes {\n                        ... on ClosedEvent {\n                          closer {\n                            ... on PullRequest {\n                              title\n                              url\n                            }\n                          }\n                        }\n                      }\n                    }\n                  }\n                }\n              }`, {\n              owner: context.repo.owner,\n              repo: context.repo.repo,\n              number: context.issue.number,\n            });\n            const closer = result.repository.issue.timelineItems.nodes[0]?.closer;\n            core.setOutput('pr_url', closer?.url || 'No linked PR found');\n            core.setOutput('pr_title', closer?.title || 'N/A');\n\n  open_issues:\n    needs: get_pr_info\n    uses: dbt-labs/actions/.github/workflows/open-issue-in-repo.yml@main\n    with:\n        issue_repository: \"dbt-labs/docs.getdbt.com\"\n        issue_title: \"[Core] Docs Changes Needed from ${{ github.event.repository.name }} Issue #${{ github.event.issue.number }}\"\n        issue_body: \"Originating from this issue: https://github.com/dbt-labs/dbt-core/issues/${{ github.event.issue.number }}\\nRelated PR: ${{ needs.get_pr_info.outputs.pr_url }}\\nPR title: ${{ needs.get_pr_info.outputs.pr_title }}\\n\\nAt a minimum, update body to include a link to the page on docs.getdbt.com requiring updates and what part(s) of the page you would like to see updated.\"\n    secrets: inherit\n"
  },
  {
    "path": ".github/workflows/main.yml",
    "content": "# **what?**\n# Runs code quality checks, unit tests, integration tests and\n# verifies python build on all code commited to the repository. This workflow\n# should not require any secrets since it runs for PRs from forked repos. By\n# default, secrets are not passed to workflows running from a forked repos.\n\n# **why?**\n# Ensure code for dbt meets a certain quality standard.\n\n# **when?**\n# This will run for all PRs, when code is pushed to a release\n# branch, and when manually triggered.\n\nname: Tests and Code Checks\n\non:\n  push:\n    branches:\n      - \"main\"\n      - \"*.latest\"\n      - \"releases/*\"\n  pull_request:\n  merge_group:\n    types: [checks_requested]\n  workflow_dispatch:\n\npermissions: read-all\n\n# will cancel previous workflows triggered by the same event and for the same ref for PRs or same SHA otherwise\nconcurrency:\n  group: ${{ github.workflow }}-${{ github.event_name }}-${{ contains(github.event_name, 'pull_request') && github.event.pull_request.head.ref || github.sha }}\n  cancel-in-progress: true\n\ndefaults:\n  run:\n    shell: bash\n\n# top-level adjustments can be made here\nenv:\n  # number of parallel processes to spawn for python integration testing\n  PYTHON_INTEGRATION_TEST_WORKERS: 15\n\njobs:\n  code-quality:\n    name: code-quality\n\n    runs-on: ubuntu-latest\n    timeout-minutes: 10\n\n    steps:\n      - name: Check out the repository\n        uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # actions/checkout@v4\n\n      - name: Set up Python\n        uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # actions/setup-python@v6\n        with:\n          python-version: \"3.10\"\n\n      - name: \"Install hatch\"\n        uses: pypa/hatch@257e27e51a6a5616ed08a39a408a21c35c9931bc # pypa/hatch@install\n\n      - name: Install python dependencies\n        run: |\n          cd core\n          hatch -v run setup\n\n      - name: Verify dbt installation\n        run: |\n          cd core\n          hatch run dbt --version\n\n      - name: Run pre-commit hooks\n        run: |\n          cd core\n          hatch run code-quality\n\n  unit:\n    name: \"unit test / python ${{ matrix.python-version }}\"\n\n    runs-on: ubuntu-latest\n    timeout-minutes: 10\n\n    strategy:\n      fail-fast: false\n      matrix:\n        python-version: [\"3.10\", \"3.11\", \"3.12\", \"3.13\"]\n\n    steps:\n      - name: Check out the repository\n        uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # actions/checkout@v4\n\n      - name: Set up Python ${{ matrix.python-version }}\n        uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # actions/setup-python@v6\n        with:\n          python-version: ${{ matrix.python-version }}\n\n      - name: \"Install hatch\"\n        uses: pypa/hatch@257e27e51a6a5616ed08a39a408a21c35c9931bc # pypa/hatch@install\n\n      - name: Run unit tests\n        uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # nick-fields/retry@v3\n        with:\n          timeout_minutes: 10\n          max_attempts: 3\n          command: cd core && hatch -v run ci:unit-tests\n\n      - name: Get current date\n        if: always()\n        id: date\n        run: |\n          CURRENT_DATE=$(date +'%Y-%m-%dT%H_%M_%S') # no colons allowed for artifacts\n          echo \"date=$CURRENT_DATE\" >> $GITHUB_OUTPUT\n\n      - name: Upload Unit Test Coverage to Codecov\n        if: ${{ matrix.python-version == '3.11' }}\n        uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # codecov/codecov-action@v5\n        with:\n          token: ${{ secrets.CODECOV_TOKEN }}\n          flags: unit\n          fail_ci_if_error: false\n\n  integration-metadata:\n    name: integration test metadata generation\n    runs-on: ubuntu-latest\n    outputs:\n      split-groups: ${{ steps.generate-split-groups.outputs.split-groups }}\n      include: ${{ steps.generate-include.outputs.include }}\n\n    steps:\n      - name: generate split-groups\n        id: generate-split-groups\n        run: |\n          MATRIX_JSON=\"[\"\n          for B in $(seq 1 ${{ env.PYTHON_INTEGRATION_TEST_WORKERS }}); do\n              MATRIX_JSON+=$(sed 's/^/\"/;s/$/\"/' <<< \"${B}\")\n          done\n          MATRIX_JSON=\"${MATRIX_JSON//\\\"\\\"/\\\", \\\"}\"\n          MATRIX_JSON+=\"]\"\n          echo \"split-groups=${MATRIX_JSON}\"\n          echo \"split-groups=${MATRIX_JSON}\" >> $GITHUB_OUTPUT\n\n      - name: generate include\n        id: generate-include\n        run: |\n          INCLUDE=('\"python-version\":\"3.10\",\"os\":\"windows-latest\"' '\"python-version\":\"3.10\",\"os\":\"macos-14\"' )\n          INCLUDE_GROUPS=\"[\"\n          for include in ${INCLUDE[@]}; do\n              for group in $(seq 1 ${{ env.PYTHON_INTEGRATION_TEST_WORKERS }}); do\n                  INCLUDE_GROUPS+=$(sed 's/$/, /' <<< \"{\\\"split-group\\\":\\\"${group}\\\",${include}}\")\n              done\n          done\n          INCLUDE_GROUPS=$(echo $INCLUDE_GROUPS | sed 's/,*$//g')\n          INCLUDE_GROUPS+=\"]\"\n          echo \"include=${INCLUDE_GROUPS}\"\n          echo \"include=${INCLUDE_GROUPS}\" >> $GITHUB_OUTPUT\n\n  integration-postgres:\n    name: \"(${{ matrix.split-group }}) integration test / python ${{ matrix.python-version }} / ${{ matrix.os }}\"\n\n    runs-on: ${{ matrix.os }}\n    timeout-minutes: 45\n    needs:\n      - integration-metadata\n    strategy:\n      fail-fast: false\n      matrix:\n        python-version: [\"3.10\", \"3.11\", \"3.12\", \"3.13\"]\n        os: [\"ubuntu-latest\"]\n        split-group: ${{ fromJson(needs.integration-metadata.outputs.split-groups) }}\n    env:\n      DBT_INVOCATION_ENV: github-actions\n      DBT_TEST_USER_1: dbt_test_user_1\n      DBT_TEST_USER_2: dbt_test_user_2\n      DBT_TEST_USER_3: dbt_test_user_3\n      DD_CIVISIBILITY_AGENTLESS_ENABLED: true\n      DD_API_KEY: ${{ secrets.DATADOG_API_KEY }}\n      DD_SITE: datadoghq.com\n      DD_ENV: ci\n      DD_SERVICE: ${{ github.event.repository.name }}\n\n    services:\n      # Label used to access the service container\n      postgres:\n        # Docker Hub image\n        image: postgres\n        # Provide the password for postgres\n        env:\n          POSTGRES_PASSWORD: password\n          POSTGRES_USER: postgres\n        # Set health checks to wait until postgres has started\n        options: >-\n          --health-cmd pg_isready\n          --health-interval 10s\n          --health-timeout 5s\n          --health-retries 5\n        ports:\n          - 5432:5432\n\n    steps:\n      - name: Check out the repository\n        uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # actions/checkout@v4\n\n      - name: Set up Python ${{ matrix.python-version }}\n        uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # actions/setup-python@v6\n        with:\n          python-version: ${{ matrix.python-version }}\n\n      - name: Run postgres setup script\n        run: |\n          ./scripts/setup_db.sh\n        env:\n          PGHOST: localhost\n          PGPORT: 5432\n          PGPASSWORD: password\n\n      - name: \"Install hatch\"\n        uses: pypa/hatch@257e27e51a6a5616ed08a39a408a21c35c9931bc # pypa/hatch@install\n\n      - name: Run integration tests\n        uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # nick-fields/retry@v3\n        with:\n          timeout_minutes: 30\n          max_attempts: 3\n          shell: bash\n          command: cd core && hatch -v run ci:integration-tests -- --ddtrace --splits ${{ env.PYTHON_INTEGRATION_TEST_WORKERS }} --group ${{ matrix.split-group }}\n\n      - name: Get current date\n        if: always()\n        id: date\n        run: |\n          CURRENT_DATE=$(date +'%Y-%m-%dT%H_%M_%S') # no colons allowed for artifacts\n          echo \"date=$CURRENT_DATE\" >> $GITHUB_OUTPUT\n\n      - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # actions/upload-artifact@v4\n        if: always()\n        with:\n          name: logs_${{ matrix.python-version }}_${{ matrix.os }}_${{ matrix.split-group }}_${{ steps.date.outputs.date }}\n          path: ./logs\n\n      - name: Upload Integration Test Coverage to Codecov\n        if: ${{ matrix.python-version == '3.11' }}\n        uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # codecov/codecov-action@v5\n        with:\n          token: ${{ secrets.CODECOV_TOKEN }}\n          flags: integration\n          fail_ci_if_error: false\n\n  integration-mac-windows:\n    name: (${{ matrix.split-group }}) integration test / python ${{ matrix.python-version }} / ${{ matrix.os }}\n\n    runs-on: ${{ matrix.os }}\n    timeout-minutes: 45\n    needs:\n      - integration-metadata\n    strategy:\n      fail-fast: false\n      matrix:\n        # already includes split group and runs mac + windows\n        include: ${{ fromJson(needs.integration-metadata.outputs.include) }}\n    env:\n      DBT_INVOCATION_ENV: github-actions\n      DBT_TEST_USER_1: dbt_test_user_1\n      DBT_TEST_USER_2: dbt_test_user_2\n      DBT_TEST_USER_3: dbt_test_user_3\n      DD_CIVISIBILITY_AGENTLESS_ENABLED: true\n      DD_API_KEY: ${{ secrets.DATADOG_API_KEY }}\n      DD_SITE: datadoghq.com\n      DD_ENV: ci\n      DD_SERVICE: ${{ github.event.repository.name }}\n\n    steps:\n      - name: Check out the repository\n        uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # actions/checkout@v4\n\n      - name: Set up Python ${{ matrix.python-version }}\n        uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # actions/setup-python@v6\n        with:\n          python-version: ${{ matrix.python-version }}\n\n      - name: Set up postgres (macos)\n        if: runner.os == 'macOS'\n\n        uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # nick-fields/retry@v3\n        with:\n          timeout_minutes: 10\n          max_attempts: 3\n          command: ./scripts/setup_db.sh\n\n      - name: Set up postgres (windows)\n        if: runner.os == 'Windows'\n        uses: ./.github/actions/setup-postgres-windows\n\n      - name: \"Install hatch\"\n        uses: pypa/hatch@257e27e51a6a5616ed08a39a408a21c35c9931bc # pypa/hatch@install\n\n      - name: Run integration tests\n        uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # nick-fields/retry@v3\n        with:\n          timeout_minutes: 30\n          max_attempts: 3\n          shell: bash\n          command: cd core && hatch -v run ci:integration-tests -- --ddtrace --splits ${{ env.PYTHON_INTEGRATION_TEST_WORKERS }} --group ${{ matrix.split-group }}\n\n      - name: Get current date\n        if: always()\n        id: date\n        run: |\n          CURRENT_DATE=$(date +'%Y-%m-%dT%H_%M_%S') # no colons allowed for artifacts\n          echo \"date=$CURRENT_DATE\" >> $GITHUB_OUTPUT\n\n      - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # actions/upload-artifact@v4\n        if: always()\n        with:\n          name: logs_${{ matrix.python-version }}_${{ matrix.os }}_${{ matrix.split-group }}_${{ steps.date.outputs.date }}\n          path: ./logs\n\n      - name: Upload Integration Test Coverage\n        if: ${{ matrix.python-version == '3.11' }}\n        uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # codecov/codecov-action@v5\n        with:\n          token: ${{ secrets.CODECOV_TOKEN }}\n          flags: integration\n          fail_ci_if_error: false\n\n  integration-report:\n    if: ${{ always() }}\n    name: Integration Test Suite\n    runs-on: ubuntu-latest\n    needs: [integration-mac-windows, integration-postgres]\n    steps:\n      - name: \"Integration Tests Failed\"\n        if: ${{ contains(needs.integration-mac-windows.result, 'failure') || contains(needs.integration-mac-windows.result, 'cancelled') || contains(needs.integration-postgres.result, 'failure') || contains(needs.integration-postgres.result, 'cancelled') }}\n        # when this is true the next step won't execute\n        run: |\n          echo \"::notice title='Integration test suite failed'\"\n          exit 1\n\n      - name: \"Integration Tests Passed\"\n        run: |\n          echo \"::notice title='Integration test suite passed'\"\n\n  build:\n    name: build packages\n\n    runs-on: ubuntu-latest\n\n    steps:\n      - name: Check out the repository\n        uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # actions/checkout@v4\n\n      - name: Set up Python\n        uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # actions/setup-python@v6\n        with:\n          python-version: \"3.10\"\n\n      - name: \"Install hatch\"\n        uses: pypa/hatch@257e27e51a6a5616ed08a39a408a21c35c9931bc # pypa/hatch@install\n\n      - name: Install python dependencies\n        run: |\n          python -m pip install --user --upgrade pip\n          python -m pip install --upgrade twine check-wheel-contents\n          python -m pip --version\n\n      - name: \"Build Distributions\"\n        working-directory: core\n        run: hatch build\n\n      - name: \"Show Distributions\"\n        working-directory: core\n        run: ls -lh dist/\n\n      - name: \"Check and Verify Distributions\"\n        working-directory: core\n        run: hatch -v run build:check-all\n"
  },
  {
    "path": ".github/workflows/nightly-release.yml",
    "content": "# **what?**\n# Nightly releases to GitHub and PyPI. This workflow produces the following outcome:\n# - generate and validate data for night release (commit SHA, version number, release branch);\n# - pass data to release workflow;\n# - night release will be pushed to GitHub as a draft release;\n# - night build will be pushed to test PyPI;\n#\n# **why?**\n# Ensure an automated and tested release process for nightly builds\n#\n# **when?**\n# This workflow runs on schedule or can be run manually on demand.\n\nname: Nightly Test Release to GitHub and PyPI\n\non:\n  workflow_dispatch: # for manual triggering\n  schedule:\n    - cron: 0 9 * * *\n\npermissions:\n  contents: write # this is the permission that allows creating a new release\n  packages: write # this is the permission that allows Docker release\n\ndefaults:\n  run:\n    shell: bash\n\nenv:\n  RELEASE_BRANCH: \"main\"\n\njobs:\n  aggregate-release-data:\n    runs-on: ${{ vars.UBUNTU_LATEST }}\n\n    outputs:\n      version_number: ${{ steps.nightly-release-version.outputs.number }}\n      release_branch: ${{ steps.release-branch.outputs.name }}\n\n    steps:\n      - name: \"Checkout ${{ github.repository }} Branch ${{ env.RELEASE_BRANCH }}\"\n        uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # actions/checkout@v4\n        with:\n          ref: ${{ env.RELEASE_BRANCH }}\n\n      - name: \"Get Current Version Number\"\n        id: version-number-sources\n        run: |\n          current_version=$(grep '^version = ' core/dbt/__version__.py | sed 's/version = \"\\(.*\\)\"/\\1/')\n          echo \"current_version=$current_version\" >> $GITHUB_OUTPUT\n\n      - name: \"Audit Version And Parse Into Parts\"\n        id: semver\n        uses: dbt-labs/actions/parse-semver@v1\n        with:\n          version: ${{ steps.version-number-sources.outputs.current_version }}\n\n      - name: \"Get Current Date\"\n        id: current-date\n        run: echo \"date=$(date +'%Y%m%d')\" >> $GITHUB_OUTPUT\n\n      - name: \"Generate Nightly Release Version Number\"\n        id: nightly-release-version\n        run: |\n          number=\"${{ steps.semver.outputs.version }}.post${{ steps.current-date.outputs.date }}\"\n          echo \"number=$number\" >> $GITHUB_OUTPUT\n\n      - name: \"Audit Nightly Release Version And Parse Into Parts\"\n        uses: dbt-labs/actions/parse-semver@v1\n        with:\n          version: ${{ steps.nightly-release-version.outputs.number }}\n\n      - name: \"Set Release Branch\"\n        id: release-branch\n        run: |\n          echo \"name=${{ env.RELEASE_BRANCH }}\" >> $GITHUB_OUTPUT\n\n  log-outputs-aggregate-release-data:\n    runs-on: ${{ vars.UBUNTU_LATEST }}\n    needs: [aggregate-release-data]\n\n    steps:\n      - name: \"[DEBUG] Log Outputs\"\n        run: |\n          echo version_number: ${{ needs.aggregate-release-data.outputs.version_number }}\n          echo release_branch: ${{ needs.aggregate-release-data.outputs.release_branch }}\n\n  release-github-pypi:\n    needs: [aggregate-release-data]\n\n    uses: ./.github/workflows/release.yml\n    with:\n      target_branch: ${{ needs.aggregate-release-data.outputs.release_branch }}\n      version_number: ${{ needs.aggregate-release-data.outputs.version_number }}\n      test_run: true\n      nightly_release: true\n    secrets: inherit\n"
  },
  {
    "path": ".github/workflows/release-branch-tests.yml",
    "content": "# **what?**\n# The purpose of this workflow is to trigger CI to run for each\n# release branch and main branch on a regular cadence. If the CI workflow\n# fails for a branch, it will post to #dev-core-alerts to raise awareness.\n\n# **why?**\n# Ensures release branches and main are always shippable and not broken.\n# Also, can catch any dependencies shifting beneath us that might\n# introduce breaking changes (could also impact Cloud).\n\n# **when?**\n# Mainly on a schedule of 9:00, 13:00, 18:00 UTC everyday.\n# Manual trigger can also test on demand\n\nname: Release branch scheduled testing\n\non:\n  schedule:\n    - cron: '0 9,13,18 * * *' # 9:00, 13:00, 18:00 UTC\n\n  workflow_dispatch: # for manual triggering\n\n# no special access is needed\npermissions: read-all\n\njobs:\n  run_tests:\n    uses: dbt-labs/actions/.github/workflows/release-branch-tests.yml@main\n    with:\n      workflows_to_run: '[\"main.yml\"]'\n    secrets: inherit\n"
  },
  {
    "path": ".github/workflows/release.yml",
    "content": "# **what?**\n# Release workflow provides the following steps:\n# - checkout the given commit;\n# - validate version in sources and changelog file for given version;\n# - bump the version and generate a changelog if needed;\n# - merge all changes to the target branch if needed;\n# - run unit and integration tests against given commit;\n# - build and package that SHA;\n# - release it to GitHub and PyPI with that specific build;\n# - release it to Docker\n#\n# **why?**\n# Ensure an automated and tested release process\n#\n# **when?**\n# This workflow can be run manually on demand or can be called by other workflows\n\nname: \"Release to GitHub, PyPI & Docker\"\nrun-name: \"Release ${{ inputs.version_number }} to GitHub, PyPI & Docker\"\n\non:\n  workflow_dispatch:\n    inputs:\n      target_branch:\n        description: \"The branch to release from\"\n        type: string\n        required: true\n      version_number:\n        description: \"The release version number (i.e. 1.0.0b1)\"\n        type: string\n        required: true\n      test_run:\n        description: \"Test run (Publish release as draft)\"\n        type: boolean\n        default: true\n        required: false\n      nightly_release:\n        description: \"Nightly release to dev environment\"\n        type: boolean\n        default: false\n        required: false\n      only_docker:\n        description: \"Only release Docker image, skip GitHub & PyPI\"\n        type: boolean\n        default: false\n        required: false\n  workflow_call:\n    inputs:\n      target_branch:\n        description: \"The branch to release from\"\n        type: string\n        required: true\n      version_number:\n        description: \"The release version number (i.e. 1.0.0b1)\"\n        type: string\n        required: true\n      test_run:\n        description: \"Test run (Publish release as draft)\"\n        type: boolean\n        default: true\n        required: false\n      nightly_release:\n        description: \"Nightly release to dev environment\"\n        type: boolean\n        default: false\n        required: false\n\npermissions:\n  contents: write # this is the permission that allows creating a new release\n\ndefaults:\n  run:\n    shell: bash\n\nenv:\n  MIN_HATCH_VERSION: \"1.11.0\"\n\njobs:\n  job-setup:\n    name: Log Inputs\n    runs-on: ${{ vars.UBUNTU_LATEST }}\n    outputs:\n      use_hatch: ${{ steps.use_hatch.outputs.use_hatch }}\n    steps:\n      - name: \"[DEBUG] Print Variables\"\n        run: |\n          echo Inputs\n          echo The branch to release from:         ${{ inputs.target_branch }}\n          echo The release version number:         ${{ inputs.version_number }}\n          echo Test run:                           ${{ inputs.test_run }}\n          echo Nightly release:                    ${{ inputs.nightly_release }}\n          echo Only Docker:                        ${{ inputs.only_docker }}\n\n      # In version env.HATCH_VERSION we started to use hatch for build tooling.  Before that we used setuptools.\n      # This needs to check if we're using hatch or setuptools based on the version being released.  We should\n      # check if the version is greater than or equal to env.HATCH_VERSION.  If it is, we use hatch, otherwise we use setuptools.\n      - name: \"Check if using hatch\"\n        id: use_hatch\n        run: |\n          # Extract major.minor from versions like 1.11.0a1 -> 1.11\n          INPUT_MAJ_MIN=$(echo \"${{ inputs.version_number }}\" | sed -E 's/^([0-9]+\\.[0-9]+).*/\\1/')\n          HATCH_MAJ_MIN=$(echo \"${{ env.MIN_HATCH_VERSION }}\" | sed -E 's/^([0-9]+\\.[0-9]+).*/\\1/')\n\n          if [ $(echo \"$INPUT_MAJ_MIN >= $HATCH_MAJ_MIN\" | bc) -eq 1 ]; then\n            echo \"use_hatch=true\" >> $GITHUB_OUTPUT\n          else\n            echo \"use_hatch=false\" >> $GITHUB_OUTPUT\n          fi\n\n      - name: \"Notify if using hatch\"\n        run: |\n          if [ ${{ steps.use_hatch.outputs.use_hatch }} = \"true\" ]; then\n            echo \"::notice title=\"Using Hatch\": $title::Using Hatch for release\"\n          else\n            echo \"::notice title=\"Using Setuptools\": $title::Using Setuptools for release\"\n          fi\n\n  bump-version-generate-changelog:\n    name: Bump package version, Generate changelog\n    needs: [job-setup]\n    if: ${{ !inputs.only_docker }}\n\n    uses: dbt-labs/dbt-release/.github/workflows/release-prep.yml@main\n\n    with:\n      version_number: ${{ inputs.version_number }}\n      hatch_directory: \"core\"\n      target_branch: ${{ inputs.target_branch }}\n      env_setup_script_path: \"scripts/env-setup.sh\"\n      test_run: ${{ inputs.test_run }}\n      nightly_release: ${{ inputs.nightly_release }}\n      use_hatch: ${{ needs.job-setup.outputs.use_hatch == 'true' }} # workflow outputs are strings...\n\n    secrets: inherit\n\n  log-outputs-bump-version-generate-changelog:\n    name: \"[Log output] Bump package version, Generate changelog\"\n    if: ${{ !failure() && !cancelled() && !inputs.only_docker }}\n\n    needs: [bump-version-generate-changelog]\n\n    runs-on: ${{ vars.UBUNTU_LATEST }}\n\n    steps:\n      - name: Print variables\n        run: |\n          echo Final SHA     : ${{ needs.bump-version-generate-changelog.outputs.final_sha }}\n          echo Changelog path: ${{ needs.bump-version-generate-changelog.outputs.changelog_path }}\n\n  build-test-package:\n    name: Build, Test, Package\n    if: ${{ !failure() && !cancelled() && !inputs.only_docker }}\n    needs: [job-setup, bump-version-generate-changelog]\n\n    uses: dbt-labs/dbt-release/.github/workflows/build.yml@main\n\n    with:\n      sha: ${{ needs.bump-version-generate-changelog.outputs.final_sha }}\n      version_number: ${{ inputs.version_number }}\n      hatch_directory: \"core\"\n      changelog_path: ${{ needs.bump-version-generate-changelog.outputs.changelog_path }}\n      build_script_path: \"scripts/build-dist.sh\"\n      package_test_command: \"dbt --version\"\n      test_run: ${{ inputs.test_run }}\n      nightly_release: ${{ inputs.nightly_release }}\n      use_hatch: ${{ needs.job-setup.outputs.use_hatch == 'true' }} # workflow outputs are strings...\n\n  github-release:\n    name: GitHub Release\n    if: ${{ !failure() && !cancelled() && !inputs.only_docker }}\n\n    needs: [job-setup, bump-version-generate-changelog, build-test-package]\n\n    uses: dbt-labs/dbt-release/.github/workflows/github-release.yml@main\n\n    with:\n      sha: ${{ needs.bump-version-generate-changelog.outputs.final_sha }}\n      version_number: ${{ inputs.version_number }}\n      changelog_path: ${{ needs.bump-version-generate-changelog.outputs.changelog_path }}\n      test_run: ${{ inputs.test_run }}\n      use_hatch: ${{ needs.job-setup.outputs.use_hatch == 'true' }} # workflow outputs are strings...\n\n  pypi-release:\n    name: PyPI Release\n\n    needs: [job-setup, github-release]\n\n    uses: dbt-labs/dbt-release/.github/workflows/pypi-release.yml@main\n\n    with:\n      version_number: ${{ inputs.version_number }}\n      test_run: ${{ inputs.test_run }}\n      use_hatch: ${{ needs.job-setup.outputs.use_hatch == 'true' }} # workflow outputs are strings...\n\n    secrets:\n      PYPI_API_TOKEN: ${{ secrets.PYPI_API_TOKEN }}\n      TEST_PYPI_API_TOKEN: ${{ secrets.TEST_PYPI_API_TOKEN }}\n\n  determine-docker-package:\n    # dbt-postgres exists within dbt-core for versions 1.7 and earlier but is a separate package for 1.8 and later.\n    # determine if we need to release dbt-core or both dbt-core and dbt-postgres\n    name: Determine Docker Package\n    if: ${{ !failure() && !cancelled() }}\n    runs-on: ${{ vars.UBUNTU_LATEST }}\n    needs: [pypi-release]\n    outputs:\n      matrix: ${{ steps.determine-docker-package.outputs.matrix }}\n    steps:\n      - name: \"Audit Version And Parse Into Parts\"\n        id: semver\n        uses: dbt-labs/actions/parse-semver@v1\n        with:\n          version: ${{ inputs.version_number }}\n\n      - name: \"Determine Packages to Release\"\n        id: determine-docker-package\n        run: |\n          if [ ${{ steps.semver.outputs.minor }} -ge 8 ]; then\n            json_output={\\\"package\\\":[\\\"dbt-core\\\"]}\n          else\n            json_output={\\\"package\\\":[\\\"dbt-core\\\",\\\"dbt-postgres\\\"]}\n          fi\n          echo \"matrix=$json_output\" >> $GITHUB_OUTPUT\n\n  docker-release:\n    name: \"Docker Release for ${{ matrix.package }}\"\n    needs: [determine-docker-package]\n    # We cannot release to docker on a test run because it uses the tag in GitHub as\n    # what we need to release but draft releases don't actually tag the commit so it\n    # finds nothing to release\n    if: ${{ !failure() && !cancelled() && (!inputs.test_run || inputs.only_docker) }}\n    strategy:\n      matrix: ${{fromJson(needs.determine-docker-package.outputs.matrix)}}\n\n    permissions:\n      packages: write\n\n    uses: dbt-labs/dbt-release/.github/workflows/release-docker.yml@main\n    with:\n      package: ${{ matrix.package }}\n      version_number: ${{ inputs.version_number }}\n      test_run: ${{ inputs.test_run }}\n\n  slack-notification:\n    name: Slack Notification\n    if: ${{ failure() && (!inputs.test_run || inputs.nightly_release) }}\n\n    needs:\n      [\n        bump-version-generate-changelog,\n        build-test-package,\n        github-release,\n        pypi-release,\n        docker-release,\n      ]\n\n    uses: dbt-labs/dbt-release/.github/workflows/slack-post-notification.yml@main\n    with:\n      status: \"failure\"\n\n    secrets:\n      SLACK_WEBHOOK_URL: ${{ secrets.SLACK_DEV_CORE_ALERTS }}\n\n  testing-slack-notification:\n    # sends notifications to #slackbot-test\n    name: Testing - Slack Notification\n    if: ${{ failure() && inputs.test_run && !inputs.nightly_release }}\n\n    needs:\n      [\n        bump-version-generate-changelog,\n        build-test-package,\n        github-release,\n        pypi-release,\n        docker-release,\n      ]\n\n    uses: dbt-labs/dbt-release/.github/workflows/slack-post-notification.yml@main\n    with:\n      status: \"failure\"\n\n    secrets:\n      SLACK_WEBHOOK_URL: ${{ secrets.SLACK_TESTING_WEBHOOK_URL }}\n"
  },
  {
    "path": ".github/workflows/repository-cleanup.yml",
    "content": "# **what?**\n# Cleanup branches left over from automation and testing.  Also cleanup\n# draft releases from release testing.\n\n# **why?**\n# The automations are leaving behind branches and releases that clutter\n# the repository.  Sometimes we need them to debug processes so we don't\n# want them immediately deleted.  Running on Saturday to avoid running\n# at the same time as an actual release to prevent breaking a release\n# mid-release.\n\n# **when?**\n# Mainly on a schedule of 12:00 Saturday.\n# Manual trigger can also run on demand\n\nname: Repository Cleanup\n\non:\n  schedule:\n    - cron: '0 12 * * SAT' # At 12:00 on Saturday - details in `why` above\n\n  workflow_dispatch: # for manual triggering\n\npermissions:\n  contents: write\n\njobs:\n  cleanup-repo:\n    uses: dbt-labs/actions/.github/workflows/repository-cleanup.yml@main\n    secrets: inherit\n"
  },
  {
    "path": ".github/workflows/schema-check.yml",
    "content": "# **what?**\n# Compares the schema of the dbt version of the given ref vs\n# the latest official schema releases found in schemas.getdbt.com.\n# If there are differences, the workflow will fail and upload the\n# diff as an artifact. The metadata team should be alerted to the change.\n#\n# **why?**\n# Reaction work may need to be done if artifact schema changes\n# occur so we want to proactively alert to it.\n#\n# **when?**\n# Only can be run manually\nname: Artifact Schema Check\n\non:\n  #  pull_request:\n  #    types: [ opened, reopened, labeled, unlabeled, synchronize ]\n  #    paths-ignore: [ '.changes/**', '.github/**', 'tests/**', '**.md', '**.yml' ]\n\n  workflow_dispatch:\n    inputs:\n      target_branch:\n        description: \"The branch to check against\"\n        type: string\n        default: \"main\"\n        required: true\n\n# no special access is needed\npermissions: read-all\n\nenv:\n  LATEST_SCHEMA_PATH: ${{ github.workspace }}/new_schemas\n  SCHEMA_DIFF_ARTIFACT: ${{ github.workspace }}/schema_changes.txt\n  DBT_REPO_DIRECTORY: ${{ github.workspace }}/dbt\n  SCHEMA_REPO_DIRECTORY: ${{ github.workspace }}/schemas.getdbt.com\n\njobs:\n  checking-schemas:\n    name: \"Post-merge schema changes required\"\n    runs-on: ${{ vars.UBUNTU_LATEST }}\n\n    steps:\n      - name: Set up Python\n        uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # actions/setup-python@v6\n        with:\n          python-version: \"3.10\"\n\n      - name: Checkout dbt repo\n        uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # actions/checkout@v4\n        with:\n          path: ${{ env.DBT_REPO_DIRECTORY }}\n          ref: ${{ inputs.target_branch }}\n\n      - name: Check for changes in core/dbt/artifacts\n        # https://github.com/marketplace/actions/paths-changes-filter\n        uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # dorny/paths-filter@v3\n        id: check_artifact_changes\n        with:\n          filters: |\n            artifacts_changed:\n              - 'core/dbt/artifacts/**'\n          list-files: shell\n          working-directory: ${{ env.DBT_REPO_DIRECTORY }}\n\n      - name: Succeed if no artifacts have changed\n        if: steps.check_artifact_changes.outputs.artifacts_changed == 'false'\n        run: |\n          echo \"No artifact changes found in core/dbt/artifacts. CI check passed.\"\n\n      - name: Checkout schemas.getdbt.com repo\n        if: steps.check_artifact_changes.outputs.artifacts_changed == 'true'\n        uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # actions/checkout@v4\n        with:\n          repository: dbt-labs/schemas.getdbt.com\n          ref: \"main\"\n          path: ${{ env.SCHEMA_REPO_DIRECTORY }}\n\n      - name: \"Install hatch\"\n        uses: pypa/hatch@257e27e51a6a5616ed08a39a408a21c35c9931bc # pypa/hatch@install\n\n      - name: Generate current schema\n        if: steps.check_artifact_changes.outputs.artifacts_changed == 'true'\n        run: |\n          cd ${{ env.DBT_REPO_DIRECTORY }}/core\n          hatch run setup\n          hatch run json-schema -- --path ${{ env.LATEST_SCHEMA_PATH }}\n\n      # Copy generated schema files into the schemas.getdbt.com repo\n      # Do a git diff to find any changes\n      # Ignore any lines with date-like (yyyy-mm-dd) or version-like (x.y.z) changes\n      - name: Compare schemas\n        if: steps.check_artifact_changes.outputs.artifacts_changed == 'true'\n        run: |\n          cp -r ${{ env.LATEST_SCHEMA_PATH }}/dbt ${{ env.SCHEMA_REPO_DIRECTORY }}\n          cd ${{ env.SCHEMA_REPO_DIRECTORY }}\n          git diff -I='*[0-9]{4}-[0-9]{2}-[0-9]{2}' -I='*[0-9]+\\.[0-9]+\\.[0-9]+' --exit-code > ${{ env.SCHEMA_DIFF_ARTIFACT }}\n\n      - name: Upload schema diff\n        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # actions/upload-artifact@v4\n        if: ${{ failure() && steps.check_artifact_changes.outputs.artifacts_changed == 'true' }}\n        with:\n          name: \"schema_changes.txt\"\n          path: \"${{ env.SCHEMA_DIFF_ARTIFACT }}\"\n"
  },
  {
    "path": ".github/workflows/stale.yml",
    "content": "name: \"Close stale issues and PRs\"\non:\n  schedule:\n    - cron: \"30 1 * * *\"\n\npermissions:\n  issues: write\n  pull-requests: write\n\njobs:\n  stale:\n    uses: dbt-labs/actions/.github/workflows/stale-bot-matrix.yml@main\n"
  },
  {
    "path": ".github/workflows/structured-logging-schema-check.yml",
    "content": "# This Action checks makes a dbt run to sample json structured logs\n# and checks that they conform to the currently documented schema.\n#\n# If this action fails it either means we have unintentionally deviated\n# from our documented structured logging schema, or we need to bump the\n# version of our structured logging and add new documentation to\n# communicate these changes.\n\nname: Structured Logging Schema Check\non:\n  push:\n    branches:\n      - \"main\"\n      - \"*.latest\"\n      - \"releases/*\"\n  pull_request:\n  merge_group:\n    types: [checks_requested]\n  workflow_dispatch:\n\npermissions: read-all\n\n# top-level adjustments can be made here\nenv:\n  # number of parallel processes to spawn for python testing\n  PYTHON_INTEGRATION_TEST_WORKERS: 15\n\njobs:\n  integration-metadata:\n    name: integration test metadata generation\n    runs-on: ubuntu-latest\n    outputs:\n      split-groups: ${{ steps.generate-split-groups.outputs.split-groups }}\n\n    steps:\n      - name: generate split-groups\n        id: generate-split-groups\n        run: |\n          MATRIX_JSON=\"[\"\n          for B in $(seq 1 ${{ env.PYTHON_INTEGRATION_TEST_WORKERS }}); do\n              MATRIX_JSON+=$(sed 's/^/\"/;s/$/\"/' <<< \"${B}\")\n          done\n          MATRIX_JSON=\"${MATRIX_JSON//\\\"\\\"/\\\", \\\"}\"\n          MATRIX_JSON+=\"]\"\n          echo \"split-groups=${MATRIX_JSON}\" >> $GITHUB_OUTPUT\n\n  # run the performance measurements on the current or default branch\n  test-schema:\n    name: Test Log Schema\n    runs-on: ubuntu-latest\n    timeout-minutes: 45\n    needs:\n      - integration-metadata\n    strategy:\n      fail-fast: false\n      matrix:\n        split-group: ${{ fromJson(needs.integration-metadata.outputs.split-groups) }}\n    env:\n      # turns warnings into errors\n      RUSTFLAGS: \"-D warnings\"\n      # points tests to the log file\n      LOG_DIR: \"/home/runner/work/dbt-core/dbt-core/logs\"\n      # tells integration tests to output into json format\n      DBT_LOG_FORMAT: \"json\"\n      # tell eventmgr to convert logging events into bytes\n      DBT_TEST_BINARY_SERIALIZATION: \"true\"\n      # Additional test users\n      DBT_TEST_USER_1: dbt_test_user_1\n      DBT_TEST_USER_2: dbt_test_user_2\n      DBT_TEST_USER_3: dbt_test_user_3\n\n    services:\n      # Label used to access the service container\n      postgres:\n        # Docker Hub image\n        image: postgres\n        # Provide the password for postgres\n        env:\n          POSTGRES_PASSWORD: password\n          POSTGRES_USER: postgres\n        # Set health checks to wait until postgres has started\n        options: >-\n          --health-cmd pg_isready\n          --health-interval 10s\n          --health-timeout 5s\n          --health-retries 5\n        ports:\n          - 5432:5432\n\n    steps:\n      - name: checkout dev\n        uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # actions/checkout@v4\n        with:\n          persist-credentials: false\n\n      - name: Setup Python\n        uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # actions/setup-python@v6\n        with:\n          python-version: \"3.10\"\n\n      - name: \"Install hatch\"\n        uses: pypa/hatch@257e27e51a6a5616ed08a39a408a21c35c9931bc # pypa/hatch@install\n\n      - name: Run postgres setup script\n        run: |\n          ./scripts/setup_db.sh\n        env:\n          PGHOST: localhost\n          PGPORT: 5432\n          PGPASSWORD: password\n\n      - name: ls\n        run: ls\n\n      # integration tests generate a ton of logs in different files. the next step will find them all.\n      # we actually care if these pass, because the normal test run doesn't usually include many json log outputs\n      - name: Run integration tests\n        uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # nick-fields/retry@v3\n        with:\n          timeout_minutes: 30\n          max_attempts: 3\n          command: cd core && hatch -v run ci:integration-tests -- --splits ${{ env.PYTHON_INTEGRATION_TEST_WORKERS }} --group ${{ matrix.split-group }}\n\n  test-schema-report:\n    name: Log Schema Test Suite\n    runs-on: ubuntu-latest\n    needs: test-schema\n    steps:\n      - name: \"[Notification] Log test suite passes\"\n        run: |\n          echo \"::notice title=\"Log test suite passes\"\"\n"
  },
  {
    "path": ".github/workflows/test-repeater.yml",
    "content": "# **what?**\n# This workflow will test all test(s) at the input path given number of times to determine if it's flaky or not.  You can test with any supported OS/Python combination.\n# This is batched in 10 to allow more test iterations faster.\n\n# **why?**\n# Testing if a test is flaky and if a previously flaky test has been fixed.  This allows easy testing on supported python versions and OS combinations.\n\n# **when?**\n# This is triggered manually from dbt-core.\n\nname: Flaky Tester\n\non:\n  workflow_dispatch:\n    inputs:\n      branch:\n        description: \"Branch to check out\"\n        type: string\n        required: true\n        default: \"main\"\n      test_path:\n        description: \"Path to single test to run (ex: tests/functional/retry/test_retry.py::TestRetry::test_fail_fast)\"\n        type: string\n        required: true\n        default: \"tests/functional/...\"\n      python_version:\n        description: \"Version of Python to Test Against\"\n        type: choice\n        options:\n          - \"3.10\"\n          - \"3.11\"\n      os:\n        description: \"OS to run test in\"\n        type: choice\n        options:\n          - \"ubuntu-latest\"\n          - \"macos-14\"\n          - \"windows-latest\"\n      num_runs_per_batch:\n        description: \"Max number of times to run the test per batch.  We always run 10 batches.\"\n        type: number\n        required: true\n        default: \"50\"\n\npermissions: read-all\n\ndefaults:\n  run:\n    shell: bash\n\njobs:\n  debug:\n    runs-on: ${{ vars.UBUNTU_LATEST }}\n    steps:\n      - name: \"[DEBUG] Output Inputs\"\n        run: |\n          echo \"Branch: ${{ inputs.branch }}\"\n          echo \"test_path: ${{ inputs.test_path }}\"\n          echo \"python_version: ${{ inputs.python_version }}\"\n          echo \"os: ${{ inputs.os }}\"\n          echo \"num_runs_per_batch: ${{ inputs.num_runs_per_batch }}\"\n\n  pytest:\n    runs-on: ${{ inputs.os }}\n    strategy:\n      # run all batches, even if one fails.  This informs how flaky the test may be.\n      fail-fast: false\n      # using a matrix to speed up the jobs since the matrix will run in parallel when runners are available\n      matrix:\n        batch: [\"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"10\"]\n    env:\n      PYTEST_ADDOPTS: \"-v --color=yes -n4 --csv integration_results.csv\"\n      DBT_TEST_USER_1: dbt_test_user_1\n      DBT_TEST_USER_2: dbt_test_user_2\n      DBT_TEST_USER_3: dbt_test_user_3\n      DD_CIVISIBILITY_AGENTLESS_ENABLED: true\n      DD_API_KEY: ${{ secrets.DATADOG_API_KEY }}\n      DD_SITE: datadoghq.com\n      DD_ENV: ci\n      DD_SERVICE: ${{ github.event.repository.name }}\n\n    steps:\n      - name: \"Checkout code\"\n        uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # actions/checkout@v4\n        with:\n          ref: ${{ inputs.branch }}\n\n      - name: \"Setup Python\"\n        uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # actions/setup-python@v6\n        with:\n          python-version: \"${{ inputs.python_version }}\"\n\n      - name: \"Install hatch\"\n        uses: pypa/hatch@257e27e51a6a5616ed08a39a408a21c35c9931bc # pypa/hatch@install\n\n      - name: \"Setup Dev Environment\"\n        run: |\n          cd core\n          hatch run setup\n\n      - name: \"Set up postgres (linux)\"\n        if: inputs.os == '${{ vars.UBUNTU_LATEST }}'\n        run: |\n          cd core\n          hatch run setup-db\n\n        # mac and windows don't use make due to limitations with docker with those runners in GitHub\n      - name: Set up postgres (macos)\n        if: runner.os == 'macOS'\n        uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # nick-fields/retry@v3\n        with:\n          timeout_minutes: 10\n          max_attempts: 3\n          command: ./scripts/setup_db.sh\n\n      - name: \"Set up postgres (windows)\"\n        if: inputs.os == 'windows-latest'\n        uses: ./.github/actions/setup-postgres-windows\n\n      - name: \"Test Command\"\n        id: command\n        run: |\n          test_command=\"python -m pytest ${{ inputs.test_path }}\"\n          echo \"test_command=$test_command\" >> $GITHUB_OUTPUT\n\n      - name: \"Run test ${{ inputs.num_runs_per_batch }} times\"\n        id: pytest\n        run: |\n          set +e\n          for ((i=1; i<=${{ inputs.num_runs_per_batch }}; i++))\n          do\n            echo \"Running pytest iteration $i...\"\n            python -m pytest --ddtrace ${{ inputs.test_path }}\n            exit_code=$?\n\n            if [[ $exit_code -eq 0 ]]; then\n              success=$((success + 1))\n              echo \"Iteration $i: Success\"\n            else\n              failure=$((failure + 1))\n              echo \"Iteration $i: Failure\"\n            fi\n\n            echo\n            echo \"===========================\"\n            echo \"Successful runs: $success\"\n            echo \"Failed runs: $failure\"\n            echo \"===========================\"\n            echo\n          done\n\n          echo \"failure=$failure\" >> $GITHUB_OUTPUT\n\n      - name: \"Success and Failure Summary: ${{ inputs.os }}/Python ${{ inputs.python_version }}\"\n        run: |\n          echo \"Batch: ${{ matrix.batch }}\"\n          echo \"Successful runs: ${{ steps.pytest.outputs.success }}\"\n          echo \"Failed runs: ${{ steps.pytest.outputs.failure }}\"\n\n      - name: \"Error for Failures\"\n        if: ${{ steps.pytest.outputs.failure }}\n        run: |\n          echo \"Batch ${{ matrix.batch }} failed ${{ steps.pytest.outputs.failure }} of ${{ inputs.num_runs_per_batch }} tests\"\n          exit 1\n"
  },
  {
    "path": ".github/workflows/triage-labels.yml",
    "content": "# **what?**\n# When the core team triages, we sometimes need more information from the issue creator.  In\n# those cases we remove the `triage` label and add the `awaiting_response` label.  Once we\n# recieve a response in the form of a comment, we want the `awaiting_response` label removed\n# in favor of the `triage` label so we are aware that the issue needs action.\n\n# **why?**\n# To help with out team triage issue tracking\n\n# **when?**\n# This will run when a comment is added to an issue and that issue has to `awaiting_response` label.\n\nname: Update Triage Label\n\non: issue_comment\n\ndefaults:\n  run:\n    shell: bash\n\npermissions:\n  issues: write\n\njobs:\n  triage_label:\n    if: contains(github.event.issue.labels.*.name, 'awaiting_response')\n    uses: dbt-labs/actions/.github/workflows/swap-labels.yml@main\n    with:\n      add_label: \"triage\"\n      remove_label: \"awaiting_response\"\n    secrets: inherit\n"
  },
  {
    "path": ".github/workflows/update-test-durations.yml",
    "content": "# **what?**\n# Generates pytest-split test duration data for optimized test splitting.\n# It runs tests with pytest-split to generate duration data, and then merges the data\n# into a single file to reduce the time it takes to generate the durations file.  It\n# runs for 5+ hours otherwise. The updated file is committed to a branch and a PR is\n# opened for review. The PR is auto-merged once CI passes.\n\n# **why?**\n# pytest-split uses duration data to balance test workloads across workers.\n# Without this data, tests are split evenly by count which can cause imbalanced runs.\n\n# **when?**\n# Runs weekly on Sunday at midnight UTC, and can be manually triggered as needed.\n\nname: Update Test Durations\n\non:\n  schedule:\n    - cron: \"0 0 * * 0\"\n  workflow_dispatch:\n    inputs:\n      auto-merge-pr:\n        description: \"Auto-merge the PR\"\n        required: true\n        type: boolean\n        default: true\n\npermissions:\n  contents: write\n  pull-requests: write\n\ndefaults:\n  run:\n    shell: bash\n\nenv:\n  # Number of parallel workers - matches main.yml for consistent splitting\n  PYTHON_INTEGRATION_TEST_WORKERS: 15\n\njobs:\n  generate-split-groups:\n    name: \"Generate Split Groups\"\n    runs-on: ubuntu-latest\n    outputs:\n      split-groups: ${{ steps.generate.outputs.split-groups }}\n\n    steps:\n      - name: \"Generate split group matrix\"\n        id: generate\n        run: |\n          MATRIX_JSON=\"[\"\n          for B in $(seq 1 ${{ env.PYTHON_INTEGRATION_TEST_WORKERS }}); do\n              MATRIX_JSON+=$(sed 's/^/\"/;s/$/\"/' <<< \"${B}\")\n          done\n          MATRIX_JSON=\"${MATRIX_JSON//\\\"\\\"/\\\", \\\"}\"\n          MATRIX_JSON+=\"]\"\n          echo \"split-groups=${MATRIX_JSON}\"\n          echo \"split-groups=${MATRIX_JSON}\" >> $GITHUB_OUTPUT\n\n  generate-durations:\n    name: \"Generate Durations (Group ${{ matrix.split-group }})\"\n    runs-on: ubuntu-latest\n    timeout-minutes: 60\n    needs: [generate-split-groups]\n\n    strategy:\n      fail-fast: false\n      matrix:\n        split-group: ${{ fromJson(needs.generate-split-groups.outputs.split-groups) }}\n\n    env:\n      DBT_INVOCATION_ENV: github-actions\n      DBT_TEST_USER_1: dbt_test_user_1\n      DBT_TEST_USER_2: dbt_test_user_2\n      DBT_TEST_USER_3: dbt_test_user_3\n\n    services:\n      postgres:\n        image: postgres\n        env:\n          POSTGRES_PASSWORD: password\n          POSTGRES_USER: postgres\n        options: >-\n          --health-cmd pg_isready\n          --health-interval 10s\n          --health-timeout 5s\n          --health-retries 5\n        ports:\n          - 5432:5432\n\n    steps:\n      - name: \"Check out the repository\"\n        uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # actions/checkout@v5\n\n      - name: \"Set up Python 3.11\"\n        uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # actions/setup-python@v6\n        with:\n          python-version: \"3.11\"\n\n      - name: \"Run postgres setup script\"\n        run: ./scripts/setup_db.sh\n        env:\n          PGHOST: localhost\n          PGPORT: 5432\n          PGPASSWORD: password\n\n      - name: \"Install hatch\"\n        uses: pypa/hatch@257e27e51a6a5616ed08a39a408a21c35c9931bc # pypa/hatch@install\n\n      - name: \"Run integration tests and store durations\"\n        run: |\n          cd core\n          hatch -v run ci:integration-tests-generate-durations -- \\\n            --splits ${{ env.PYTHON_INTEGRATION_TEST_WORKERS }} \\\n            --group ${{ matrix.split-group }} \\\n            || true\n          # Rename to per-group file (pytest-split overwrites with only this group's tests)\n          if [ -f .test_durations ]; then\n            mv .test_durations .test_durations_${{ matrix.split-group }}\n          else\n            echo \"ERROR: .test_durations not created - check pytest output above\"\n            exit 1\n          fi\n\n      - name: \"Upload partial durations file\"\n        uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # actions/upload-artifact@v6\n        with:\n          name: durations-${{ matrix.split-group }}\n          path: core/.test_durations_${{ matrix.split-group }}\n          if-no-files-found: error\n          include-hidden-files: true\n\n  create-pr:\n    name: \"Create Pull Request\"\n    runs-on: ubuntu-latest\n    timeout-minutes: 10\n    needs: [generate-durations]\n    outputs:\n      pr_number: ${{ steps.cpr.outputs.pull-request-number }}\n      pr_url: ${{ steps.cpr.outputs.pull-request-url }}\n\n    steps:\n      - name: \"Check out the repository\"\n        uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # actions/checkout@v5\n\n      - name: \"Import build bot GPG key\"\n        id: import-gpg\n        uses: crazy-max/ghaction-import-gpg@2dc316deee8e90f13e1a351ab510b4d5bc0c82cd # crazy-max/ghaction-import-gpg@v7\n        with:\n          gpg_private_key: ${{ secrets.FISHTOWN_BOT_GPG_PRIVATE_KEY }}\n          passphrase: ${{ secrets.FISHTOWN_BOT_GPG_PASSPHRASE }}\n          git_config_global: true\n          git_user_signingkey: true\n          git_commit_gpgsign: true\n          git_committer_name: \"Github Build Bot\"\n          git_committer_email: \"buildbot@dbtlabs.com\"\n\n      - name: \"Download all partial duration files\"\n        uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # actions/download-artifact@v7\n        with:\n          pattern: durations-*\n          path: partial-durations\n          merge-multiple: true\n\n      - name: \"Set up Python 3.11\"\n        uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # actions/setup-python@v6\n        with:\n          python-version: \"3.11\"\n\n      - name: \"Merge duration files\"\n        run: |\n          python3 << 'EOF'\n          import json\n          import glob\n\n          merged = {}\n          for filepath in glob.glob(\"partial-durations/.test_durations_*\"):\n              print(f\"Processing {filepath}\")\n              with open(filepath, \"r\") as f:\n                  data = json.load(f)\n                  merged.update(data)\n                  print(f\"  Added {len(data)} tests\")\n\n          print(f\"Total tests: {len(merged)}\")\n\n          # Sort by test name for consistent output\n          sorted_merged = dict(sorted(merged.items()))\n\n          with open(\"core/.test_durations\", \"w\") as f:\n              json.dump(sorted_merged, f, indent=4)\n              f.write(\"\\n\")\n          EOF\n\n      - name: \"Install hatch\"\n        uses: pypa/hatch@257e27e51a6a5616ed08a39a408a21c35c9931bc # pypa/hatch@install\n\n      - name: \"Code quality\"\n        run: |\n          cd core\n          git add .test_durations\n          hatch run pre-commit run end-of-file-fixer --files .test_durations || true\n\n      - name: \"Create Pull Request\"\n        id: cpr\n        uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # peter-evans/create-pull-request@v8.1.0\n        with:\n          token: ${{ secrets.FISHTOWN_BOT_PAT }}\n          commit-message: \"Update test durations for pytest-split\"\n          author: \"Github Build Bot <buildbot@dbtlabs.com>\"\n          committer: \"Github Build Bot <buildbot@dbtlabs.com>\"\n          branch: update-test-durations\n          base: main\n          delete-branch: true\n          title: \"Update test durations for pytest-split\"\n          body: |\n            This PR is automatically generated to update the test durations file used by pytest-split.\n\n            The durations are generated by running the full integration test suite and recording how long each test takes. This data is used to balance test workloads across parallel workers.\n          labels: |\n            Skip Changelog\n          add-paths: |\n            core/.test_durations\n\n  await-ci:\n    name: \"Wait for CI\"\n    runs-on: ubuntu-latest\n    needs: [create-pr]\n    if: needs.create-pr.outputs.pr_number != '' && (github.event_name == 'schedule' || inputs.auto-merge-pr == true)\n    env:\n      GH_TOKEN: ${{ secrets.FISHTOWN_BOT_PAT }}\n\n    steps:\n      - name: \"Check out the repository\"\n        uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # actions/checkout@v5\n\n      - name: \"Wait for CI to start\"\n        run: |\n          sleep 60\n\n      - name: \"Wait for CI checks to complete\"\n        run: |\n          gh pr checks ${{ needs.create-pr.outputs.pr_number }} --fail-fast --watch\n\n  merge-pr:\n    name: \"Merge Pull Request\"\n    runs-on: ubuntu-latest\n    needs: [create-pr, await-ci]\n    if: github.event_name == 'schedule' || inputs.auto-merge-pr == true\n    env:\n      GH_TOKEN: ${{ secrets.FISHTOWN_BOT_PAT }}\n\n    steps:\n      - name: \"Check out the repository\"\n        uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # actions/checkout@v5\n\n      - name: \"Merge PR\"\n        run: |\n          gh pr merge ${{ needs.create-pr.outputs.pr_number }} \\\n            --admin \\\n            --squash \\\n            --body \"Update test durations for pytest-split\" \\\n            --delete-branch\n\n  slack-notification:\n    name: \"Slack Notification\"\n    runs-on: ubuntu-latest\n    needs: [create-pr, await-ci, merge-pr]\n    if: always() && contains(join(needs.*.result, ','), 'failure')\n    steps:\n      - name: \"Post Slack Notification\"\n        run: |\n          python3 <<'PY' > slack-payload.json\n          import json\n          import os\n\n          failed_jobs = [\n              job\n              for job in (\"create-pr\", \"await-ci\", \"merge-pr\")\n              if os.environ.get(f\"{job.upper().replace('-', '_')}_RESULT\") == \"failure\"\n          ]\n          failed_summary = \", \".join(failed_jobs) if failed_jobs else \"unknown job\"\n          pr_url = os.environ.get(\"PR_URL\", \"\")\n          pr_text = f\"PR <{pr_url}|opened by the workflow>\" if pr_url else \"The workflow PR\"\n          text = (\n              f\":x: {pr_text} failed to merge for `{os.environ['GITHUB_REPOSITORY']}` \"\n              f\"on `{os.environ['GITHUB_REF_NAME']}`. Failed job(s): {failed_summary}. \"\n              f\"<{os.environ['RUN_URL']}|View workflow run>.\"\n          )\n          print(json.dumps({\"text\": text}))\n          PY\n\n          curl -X POST \\\n            -H \"Content-type: application/json\" \\\n            --data @slack-payload.json \\\n            \"$SLACK_WEBHOOK_URL\"\n        env:\n          CREATE_PR_RESULT: ${{ needs.create-pr.result }}\n          AWAIT_CI_RESULT: ${{ needs.await-ci.result }}\n          MERGE_PR_RESULT: ${{ needs.merge-pr.result }}\n          PR_URL: ${{ needs.create-pr.outputs.pr_url }}\n          RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}\n          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_CORE_PR_CHANNEL_URL }}\n"
  },
  {
    "path": ".gitignore",
    "content": "# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\n\n# C extensions\n*.so\n\n# Distribution / packaging\n.Python\nenv*/\ndbt_env/\nbuild/\n!tests/functional/build\n!core/dbt/docs/build\ndevelop-eggs/\ndist/\ndist-*/\ndownloads/\neggs/\n.eggs/\nlib/\nlib64/\nparts/\nsdist/\nvar/\n*.egg-info/\n.installed.cfg\n*.egg\n.mypy_cache/\n.dmypy.json\nlogs/\n.user.yml\nprofiles.yml\n\n# PyInstaller\n#  Usually these files are written by a python script from a template\n#  before PyInstaller builds the exe, so as to inject date/other infos into it.\n*.manifest\n*.spec\n\n# Installer logs\npip-log.txt\npip-delete-this-directory.txt\n\n# Unit test / coverage reports\nhtmlcov/\n.tox/\n.coverage\n.coverage.*\n.cache\n.env\nnosetests.xml\ncoverage.xml\n*,cover\n.hypothesis/\ntest.env\nmakefile.test.env\n*.pytest_cache/\n\n# Unit test artifacts\nindex.html\n\n\n# Translations\n*.mo\n*.pot\n\n# Django stuff:\n*.log\n\n# Sphinx documentation\ndocs/_build/\n\n# PyBuilder\ntarget/\n\n# Ipython Notebook\n.ipynb_checkpoints\n\n# Emacs\n*~\n\n# Sublime Text\n*.sublime-*\n\n# Vim\n*.sw*\n\n# Pyenv\n.python-version\n\n# Vim\n*.sw*\n\n# pycharm\n.idea/\nvenv/\n.venv*/\n\n# AWS credentials\n.aws/\n\n# MacOS\n.DS_Store\n\n# vscode\n.vscode/\n*.code-workspace\n\n# poetry\npoetry.lock\n\n# asdf\n.tool-versions\n"
  },
  {
    "path": ".pre-commit-config.yaml",
    "content": "# Configuration for pre-commit hooks (see https://pre-commit.com/).\n# Eventually the hooks described here will be run as tests before merging each PR.\n\nexclude: ^(core/dbt/docs/build/|core/dbt/common/events/types_pb2.py|core/dbt/adapters/events/adapter_types_pb2.py)\n\n# Force all unspecified python hooks to run python 3.10\ndefault_language_version:\n  python: python3\n\nrepos:\n  - repo: https://github.com/pre-commit/pre-commit-hooks\n    rev: v3.2.0\n    hooks:\n      - id: check-yaml\n        args: [--unsafe]\n      - id: check-json\n      - id: end-of-file-fixer\n        exclude: schemas/dbt/manifest/\n      - id: trailing-whitespace\n        exclude_types:\n          - \"markdown\"\n      - id: check-case-conflict\n  # local hooks are used to run the hooks in the local environment instead of a pre-commit isolated one.\n  # This ensures that the hooks are run with the same version of the dependencies as the local environment\n  # without having to manually keep them in sync.\n  - repo: local\n    hooks:\n      # Formatter/linter/type-checker pins live in the pyproject.dev optional dependency.\n      - id: isort\n        name: isort\n        entry: python -m isort\n        args: [--settings-path, pyproject.toml]\n        language: system\n        types: [python]\n      - id: black\n        name: black\n        entry: python -m black\n        language: system\n        types: [python]\n      - id: black-check\n        name: black-check\n        entry: python -m black\n        args:\n          - \"--check\"\n          - \"--diff\"\n        language: system\n        stages: [manual]\n        types: [python]\n      - id: flake8\n        name: flake8\n        entry: python -m flake8\n        language: system\n        types: [python]\n      - id: flake8-check\n        name: flake8-check\n        entry: python -m flake8\n        language: system\n        stages: [manual]\n        types: [python]\n      # N.B.: Mypy is... a bit fragile.\n      #\n      # By using `language: system` we run this hook in the local\n      # environment instead of a pre-commit isolated one.  This is needed\n      # to ensure mypy correctly parses the project.\n      #\n      # It may cause trouble\n      # in that it adds environmental variables out of our control to the\n      # mix.  Unfortunately, there's nothing we can do about per pre-commit's\n      # author.\n      # See https://github.com/pre-commit/pre-commit/issues/730 for details.\n      - id: mypy\n        name: mypy\n        entry: python -m mypy\n        args: [--show-error-codes]\n        files: ^core/dbt/\n        language: system\n        types: [python]\n      - id: mypy-check\n        name: mypy-check\n        entry: python -m mypy\n        args: [--show-error-codes, --pretty]\n        files: ^core/dbt/\n        language: system\n        stages: [manual]\n        types: [python]\n      - id: no_versioned_artifact_resource_imports\n        name: no_versioned_artifact_resource_imports\n        entry: python scripts/pre-commit-hooks/no_versioned_artifact_resource_imports.py\n        language: system\n        files: ^core/dbt/\n        types: [python]\n        pass_filenames: true\n"
  },
  {
    "path": "AGENTS.md",
    "content": "# AGENTS.md — AI Coding Agent Guidelines for dbt-core\n\n## Project Overview\n\ndbt-core is the open-source core of [dbt](https://www.getdbt.com/) (data build tool). It transforms data in warehouses by running SQL and Python models, managing dependencies, and producing artifacts. The main Python package lives in `core/` and is built with Hatch/Hatchling.\n\n## Repository Layout\n\n```\ncore/                  # Main dbt-core Python package (pyproject.toml, hatch.toml)\n  dbt/                 # Source code\n    artifacts/         # Artifact schemas and versioned resource definitions\n    cli/               # CLI entry point (Click-based)\n    clients/           # Jinja, YAML, git, registry clients\n    config/            # Profile, project, and runtime configuration\n    context/           # Jinja context providers\n    contracts/         # Project and graph contracts (nodes, manifest)\n    deps/              # Dependency resolution\n    events/            # Structured event logging\n    graph/             # DAG selection and selector methods\n    materializations/  # Materialization strategies (e.g. incremental, microbatch)\n    parser/            # Manifest, model, source, macro parsing\n    task/              # One module per dbt command (run, build, test, compile, etc.)\n    tests/             # Test utilities and fixtures (not the test suite)\ntests/                 # Test suite\n  unit/                # Unit tests — no database required\n  functional/          # Functional tests — require Postgres\nplugins/               # Local Postgres adapter (for integration tests)\nschemas/               # JSON schemas for dbt artifacts\ndocs/                  # Architecture docs and guides\n.changes/              # Changie changelog entries\n```\n\n### Related Repositories\n\ndbt-core depends on packages maintained in separate repos:\n- **dbt-common** (`dbt-labs/dbt-common`) — shared utilities, `dbtClassMixin`\n- **dbt-adapters** (`dbt-labs/dbt-adapters`) — adapter interfaces and Postgres adapter\n- **dbt-semantic-interfaces**, **dbt-extractor**, **dbt-protos** — other ecosystem packages\n\n## Build System and Dev Setup\n\n- **Build backend:** Hatchling (`core/pyproject.toml`)\n- **Python:** ≥3.10 (CI tests 3.10–3.13)\n- **Setup:** `cd core && hatch run setup`\n- **Entry point:** `dbt = dbt.cli.main:cli`\n\n## Code Style and Formatting\n\n- **Formatter:** Black (line length 99)\n- **Import sorting:** isort (profile `\"black\"`)\n- **Linter:** flake8\n- **Type checking:** mypy\n- **Pre-commit:** Runs all of the above via `hatch run code-quality`\n\nImport order should follow isort conventions:\n1. `__future__`\n2. Standard library\n3. Third-party\n4. dbt-internal (`dbt`, `dbt_common`, `dbt_adapters`, `dbt_extractor`, `dbt_semantic_interfaces`)\n\n## Key Architectural Conventions\n\n### Artifact Resources: Import from `dbt.artifacts.resources`, Not Versioned Paths\n\n**Never** import directly from versioned artifact paths like `dbt.artifacts.resources.v1.model`. Instead, import from `dbt.artifacts.resources`:\n\n```python\n# WRONG — will fail pre-commit\nfrom dbt.artifacts.resources.v1.model import Model\n\n# RIGHT\nfrom dbt.artifacts.resources import Model\n```\n\nThe `dbt.artifacts.resources.__init__` re-exports everything from the current version. A pre-commit hook enforces this outside the `artifacts/` module.\n\n### Data Model Layer\n\ndbt-core uses `dataclasses` with `dbtClassMixin` (from `dbt-common`) for serialization, backed by mashumaro. It does **not** use pydantic for its data model hierarchy.\n\nThe node type hierarchy has two layers:\n\n1. **Artifact resources** (`dbt.artifacts.resources`) — serializable data definitions\n2. **Contract nodes** (`dbt.contracts.graph.nodes`) — runtime node classes that inherit from artifact resources and add behavior\n\n```\nBaseResource → GraphResource → BaseNode → GraphNode → ParsedNode → CompiledNode\n                                                                     ├── ModelNode\n                                                                     ├── SnapshotNode\n                                                                     ├── AnalysisNode\n                                                                     ├── SingularTestNode\n                                                                     ├── GenericTestNode\n                                                                     └── ...\n```\n\nEach contract node has a `resource_class()` method returning its corresponding artifact resource type and a `to_resource()` method for conversion.\n\n### Parser Pattern\n\nParsers follow a class hierarchy: `BaseParser → Parser → ConfiguredParser → SQLParser`. The typical flow:\n\n`parse_file()` → `parse_node()` → `_create_parsetime_node()` → `parse_from_dict()` → `render_update()` → `add_result_node()`\n\nSchema-based parsers (`SchemaParser`, `YamlReader` subclasses) read YAML and apply patches to nodes.\n\n## Testing\n\n### Structure\n\n- **Unit tests** (`tests/unit/`): Pure Python, no database. Use mocks and helpers from `tests/unit/utils/`.\n- **Functional tests** (`tests/functional/`): Require Postgres. Use the `project` fixture from `dbt.tests.fixtures.project`.\n\n### Running Tests\n\n```sh\ncd core\nhatch run unit-tests              # Unit tests only\nhatch run integration-tests       # Functional tests (requires Postgres)\nhatch run test                    # Unit tests + code quality checks\nhatch run code-quality            # Pre-commit hooks on all files\n```\n\nOr directly with pytest:\n\n```sh\ncd core\nhatch run python3 -m pytest ../tests/unit/path/to/test_file.py\nhatch run python3 -m pytest ../tests/functional/feature_name\n```\n\n### Functional Test Pattern\n\nFunctional tests use class-scoped fixtures to define project files and run dbt commands:\n\n```python\nclass TestMyFeature:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"my_model.sql\": \"select 1 as id\"}\n\n    def test_run_succeeds(self, project):\n        results = run_dbt([\"run\"])\n        assert len(results) == 1\n```\n\nKey utilities: `run_dbt()`, `run_dbt_and_capture()`, `get_manifest()`, `get_artifact()` from `dbt.tests.util`.\n\nHaving multiple tests in a functional test class will mean that those tests **will share** the underlying dbt project fixture of the class. This means that if a test modifies the underlying project that will affect other tests in the same class. This leads to flakiness and means it is generally best practice to have one test per functional test class.\n\n### Database Setup for Functional Tests\n\n```sh\ncd core && hatch run setup-db\n# or manually:\ndocker-compose up -d database\nPGHOST=localhost PGUSER=root PGPASSWORD=password PGDATABASE=postgres bash scripts/setup_db.sh\n```\n\n## Contributing Guide\n\nGeneral contributing documetatnion can be found in [CONTRIBUTING.md](CONTRIBUTING.md)\n\n## Changelog\n\nUse [changie](https://changie.dev/) — do **not** edit `CHANGELOG.md` directly (it is generated).\n\n```sh\nchangie new\n```\n\nThis creates a YAML entry in `.changes/unreleased/`. Changelog kinds: Breaking Changes, Features, Fixes, Docs, Under the Hood, Dependencies, Security.\n\n## Commit Discipline\n\nSeparate distinct types of changes into their own commits. Do not combine unrelated changes in a single commit, even if they touch the same file. This keeps the history reviewable and individually revertable.\n\nThe following categories of change should each be their own commit:\n\n- **Tidying** — fixing typos, improving variable names, cleaning up whitespace\n- **Abstractions** — extracting duplicated logic into a shared function or module\n- **Refactors** — restructuring code for readability, performance, or maintainability (without changing behavior)\n- **Bug fixes** — correcting incorrect behavior\n- **Features** — adding new functionality\n- **Tests** — adding or improving tests for existing behavior (coverage gaps, edge cases, flaky test fixes). Tests that accompany a new feature or bug fix belong in that commit, but standalone test work is its own category.\n- **Dependencies** — adding, removing, or upgrading dependencies\n- **Configuration** — changes to CI workflows, linter settings, build configs, pre-commit hooks, or other tooling\n\nWhen a task involves more than one of these, make separate commits in a logical order. For example, if a bug fix requires a refactor first, commit the refactor, then commit the fix. If a feature benefits from tidying nearby code, commit the tidying first, then the feature.\n\nEach commit should make sense in isolation: it should pass tests, not break the build, and have a clear message explaining *what* and *why*.\n\nFinally we require all commits to be signed with GPG keys. You can inspect if a GPG is present via `git config --global --get user.signingkey`. If it is not, please help the user setup a github GPG key.\n\n## Pull Requests\n\n- Target the `main` branch\n- Signed commits required (GPG)\n- CLA signature required for external contributors\n- Add a changie entry unless the work done was limited to adding/changing tests, adding/changing comments, adding/changing github actions/workflows, or adding/changing markdown files not used during operation of the engine\n"
  },
  {
    "path": "ARCHITECTURE.md",
    "content": "The core function of dbt is SQL compilation and execution. Users create projects of dbt resources (models, tests, seeds, snapshots, ...), defined in SQL and YAML files, and they invoke dbt to create, update, or query associated views and tables. Today, dbt makes heavy use of Jinja2 to enable the templating of SQL, and to construct a DAG (Directed Acyclic Graph) from all of the resources in a project. Users can also extend their projects by installing resources (including Jinja macros) from other projects, called \"packages.\"\n\n## dbt-core\n\nMost of the python code in the repository is within the `core/dbt` directory.\n- [`single python files`](core/dbt/README.md): A number of individual files, such as 'compilation.py' and 'exceptions.py'\n\nThe main subdirectories of core/dbt:\n- [`clients`](core/dbt/clients/README.md): Interface with dependencies (agate, jinja) or across operating systems\n- [`config`](core/dbt/config/README.md): Reconcile user-supplied configuration from connection profiles, project files, and Jinja macros\n- [`context`](core/dbt/context/README.md): Build and expose dbt-specific Jinja functionality\n- [`contracts`](core/dbt/contracts/README.md): Define Python objects (dataclasses) that dbt expects to create and validate\n- [`deps`](core/dbt/deps/README.md): Package installation and dependency resolution\n- [`events`](core/dbt/events/README.md): Logging events\n- [`graph`](core/dbt/graph/README.md): Produce a `networkx` DAG of project resources, and selecting those resources given user-supplied criteria\n- [`include`](core/dbt/include/README.md): Set up the starter project scaffold.\n- [`parser`](core/dbt/parser/README.md): Read project files, validate, construct python objects\n- [`task`](core/dbt/task/README.md): Set forth the actions that dbt can perform when invoked\n\n### Invoking dbt\n\nThe \"tasks\" map to top-level dbt commands. So `dbt run` => task.run.RunTask, etc. Some are more like abstract base classes (GraphRunnableTask, for example) but all the concrete types outside of task should map to tasks. Currently one executes at a time. The tasks kick off their “Runners” and those do execute in parallel. The parallelism is managed via a thread pool, in GraphRunnableTask.\n\ncore/dbt/task/docs/index.html\nThis is the docs website code. It comes from the dbt-docs repository, and is generated when a release is packaged.\n\n## Adapters\n\ndbt uses an adapter-plugin pattern to extend support to different databases, warehouses, query engines, etc. \nNote: dbt-postgres used to exist in dbt-core but is now in [the dbt-adapters repo](https://github.com/dbt-labs/dbt-adapters/tree/main/dbt-postgres) \n\nEach adapter is a mix of python, Jinja2, and SQL. The adapter code also makes heavy use of Jinja2 to wrap modular chunks of SQL functionality, define default implementations, and allow plugins to override it.\n\nEach adapter plugin is a standalone python package that includes:\n\n- `dbt/include/[name]`: A \"sub-global\" dbt project, of YAML and SQL files, that reimplements Jinja macros to use the adapter's supported SQL syntax\n- `dbt/adapters/[name]`: Python modules that inherit, and optionally reimplement, the base adapter classes defined in dbt-core\n- `pyproject.toml`\n\nThe Postgres adapter code is the most central, and many of its implementations are used as the default defined in the dbt-core global project. The greater the distance of a data technology from Postgres, the more its adapter plugin may need to reimplement.\n\n## Testing dbt\n\nThe [`tests/`](tests/) subdirectory includes unit and fuctional tests that run as continuous integration checks against open pull requests. Unit tests check mock inputs and outputs of specific python functions. Functional tests perform end-to-end dbt invocations against real adapters (Postgres) and assert that the results match expectations. See [the contributing guide](CONTRIBUTING.md) for a step-by-step walkthrough of setting up a local development and testing environment.\n\n## Everything else\n\n- [docker](docker/): All dbt versions are published as Docker images on DockerHub. This subfolder contains the `Dockerfile` (constant) and `requirements.txt` (one for each version).\n- [scripts](scripts/): Helper scripts for testing, releasing, and producing JSON schemas. These are not included in distributions of dbt, nor are they rigorously tested—they're just handy tools for the dbt maintainers :)\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# dbt Core Changelog\n\n- This file provides a full account of all changes to `dbt-core`\n- Changes are listed under the (pre)release in which they first appear. Subsequent releases include changes from previous releases.\n- \"Breaking changes\" listed under a version may require action from end users or external maintainers when upgrading to that version.\n- Do not edit this file directly. This file is auto-generated using [changie](https://github.com/miniscruff/changie). For details on how to document a change, see [the contributing guide](https://github.com/dbt-labs/dbt-core/blob/main/CONTRIBUTING.md#adding-changelog-entry)\n\n## Previous Releases\n\nFor information on prior major and minor releases, see their changelogs:\n\n* [1.11](https://github.com/dbt-labs/dbt-core/blob/1.11.latest/CHANGELOG.md)\n* [1.10](https://github.com/dbt-labs/dbt-core/blob/1.10.latest/CHANGELOG.md)\n* [1.9](https://github.com/dbt-labs/dbt-core/blob/1.9.latest/CHANGELOG.md)\n* [1.8](https://github.com/dbt-labs/dbt-core/blob/1.8.latest/CHANGELOG.md)\n* [1.7](https://github.com/dbt-labs/dbt-core/blob/1.7.latest/CHANGELOG.md)\n* [1.6](https://github.com/dbt-labs/dbt-core/blob/1.6.latest/CHANGELOG.md)\n* [1.5](https://github.com/dbt-labs/dbt-core/blob/1.5.latest/CHANGELOG.md)\n* [1.4](https://github.com/dbt-labs/dbt-core/blob/1.4.latest/CHANGELOG.md)\n* [1.3](https://github.com/dbt-labs/dbt-core/blob/1.3.latest/CHANGELOG.md)\n* [1.2](https://github.com/dbt-labs/dbt-core/blob/1.2.latest/CHANGELOG.md)\n* [1.1](https://github.com/dbt-labs/dbt-core/blob/1.1.latest/CHANGELOG.md)\n* [1.0](https://github.com/dbt-labs/dbt-core/blob/1.0.latest/CHANGELOG.md)\n* [0.21](https://github.com/dbt-labs/dbt-core/blob/0.21.latest/CHANGELOG.md)\n* [0.20](https://github.com/dbt-labs/dbt-core/blob/0.20.latest/CHANGELOG.md)\n* [0.19](https://github.com/dbt-labs/dbt-core/blob/0.19.latest/CHANGELOG.md)\n* [0.18](https://github.com/dbt-labs/dbt-core/blob/0.18.latest/CHANGELOG.md)\n* [0.17](https://github.com/dbt-labs/dbt-core/blob/0.17.latest/CHANGELOG.md)\n* [0.16](https://github.com/dbt-labs/dbt-core/blob/0.16.latest/CHANGELOG.md)\n* [0.15](https://github.com/dbt-labs/dbt-core/blob/0.15.latest/CHANGELOG.md)\n* [0.14](https://github.com/dbt-labs/dbt-core/blob/0.14.latest/CHANGELOG.md)\n* [0.13](https://github.com/dbt-labs/dbt-core/blob/0.13.latest/CHANGELOG.md)\n* [0.12](https://github.com/dbt-labs/dbt-core/blob/0.12.latest/CHANGELOG.md)\n* [0.11 and earlier](https://github.com/dbt-labs/dbt-core/blob/0.11.latest/CHANGELOG.md)\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing to `dbt-core`\n\n`dbt-core` is open source software. It is what it is today because community members have opened issues, provided feedback, and [contributed to the knowledge loop](https://www.getdbt.com/dbt-labs/values/). Whether you are a seasoned open source contributor or a first-time committer, we welcome and encourage you to contribute code, documentation, ideas, or problem statements to this project.\n\n- [Contributing to `dbt-core`](#contributing-to-dbt-core)\n  - [About this document](#about-this-document)\n    - [Notes](#notes)\n  - [Getting the code](#getting-the-code)\n    - [Installing git](#installing-git)\n    - [External contributors](#external-contributors)\n    - [dbt Labs contributors](#dbt-labs-contributors)\n  - [Setting up an environment](#setting-up-an-environment)\n    - [Tools](#tools)\n      - [Virtual environments](#virtual-environments)\n      - [Docker and `docker-compose`](#docker-and-docker-compose)\n      - [Postgres (optional)](#postgres-optional)\n  - [Running `dbt-core` in development](#running-dbt-core-in-development)\n    - [Installation](#installation)\n    - [Running `dbt-core`](#running-dbt-core)\n  - [Testing](#testing)\n    - [Initial setup](#initial-setup)\n    - [Test commands](#test-commands)\n      - [Hatch scripts](#hatch-scripts)\n      - [`pre-commit`](#pre-commit)\n      - [`pytest`](#pytest)\n    - [Unit, Integration, Functional?](#unit-integration-functional)\n  - [Debugging](#debugging)\n    - [Assorted development tips](#assorted-development-tips)\n  - [Adding or modifying a CHANGELOG Entry](#adding-or-modifying-a-changelog-entry)\n  - [Submitting a Pull Request](#submitting-a-pull-request)\n  - [Troubleshooting Tips](#troubleshooting-tips)\n\n## About this document\n\nThere are many ways to contribute to the ongoing development of `dbt-core`, such as by participating in discussions and issues. We encourage you to first read our higher-level document: [\"Expectations for Open Source Contributors\"](https://docs.getdbt.com/docs/contributing/oss-expectations).\n\nThe rest of this document serves as a more granular guide for contributing code changes to `dbt-core` (this repository). It is not intended as a guide for using `dbt-core`, and some pieces assume a level of familiarity with Python development and package managers. Specific code snippets in this guide assume you are using macOS or Linux and are comfortable with the command line.\n\nIf you get stuck, we're happy to help! Drop us a line in the `#dbt-core-development` channel in the [dbt Community Slack](https://community.getdbt.com).\n\n### Notes\n\n- **Adapters:** Is your issue or proposed code change related to a specific [database adapter](https://docs.getdbt.com/docs/available-adapters)? If so, please open issues, PRs, and discussions in that adapter's repository instead.\n- **CLA:** Please note that anyone contributing code to `dbt-core` must sign the [Contributor License Agreement](https://docs.getdbt.com/docs/contributor-license-agreements). If you are unable to sign the CLA, the `dbt-core` maintainers will unfortunately be unable to merge any of your Pull Requests. We welcome you to participate in discussions, open issues, and comment on existing ones.\n- **Commit Signing:** Contributors to `dbt-core` must submit commits with verified signatures. To set up a GPG key via Github, follow their guides on (1) [generating a new GPG key](https://docs.github.com/en/authentication/managing-commit-signature-verification/generating-a-new-gpg-key), (2) [adding a GPG key to your GitHub account](https://docs.github.com/en/authentication/managing-commit-signature-verification/adding-a-gpg-key-to-your-github-account), and (3) [telling Git about your GPG key](https://docs.github.com/en/authentication/managing-commit-signature-verification/telling-git-about-your-signing-key). If you need to sign existing commits on a branch, [this Stack Overflow post](https://stackoverflow.com/questions/41882919/is-there-a-way-to-gpg-sign-all-previous-commits/41883164#41883164) contains helpful guidance.\n- **Branches:** All pull requests from community contributors should target the `main` branch (default). If the change is needed as a patch for a minor version of dbt that has already been released (or is already a release candidate), a maintainer will backport the changes in your PR to the relevant \"latest\" release branch (`1.0.latest`, `1.1.latest`, ...). If an issue fix applies to a release branch, that fix should be first committed to the development branch and then to the release branch (rarely release-branch fixes may not apply to `main`).\n- **Releases**: Before releasing a new minor version of Core, we prepare a series of alphas and release candidates to allow users (especially employees of dbt Labs!) to test the new version in live environments. This is an important quality assurance step, as it exposes the new code to a wide variety of complicated deployments and can surface bugs before official release. Releases are accessible via our [supported installation methods](https://docs.getdbt.com/docs/core/installation-overview#install-dbt-core).\n\n## Getting the code\n\n### Installing git\n\nYou will need `git` in order to download and modify the `dbt-core` source code. On macOS, the best way to download git is to just install [Xcode](https://developer.apple.com/support/xcode/).\n\n### External contributors\n\nIf you are not a member of the `dbt-labs` GitHub organization, you can contribute to `dbt-core` by forking the `dbt-core` repository. For a detailed overview on forking, check out the [GitHub docs on forking](https://help.github.com/en/articles/fork-a-repo). In short, you will need to:\n\n1. Fork the `dbt-core` repository\n2. Clone your fork locally\n3. Check out a new branch for your proposed changes\n4. Push changes to your fork\n5. Open a pull request against `dbt-labs/dbt-core` from your forked repository\n\n### dbt Labs contributors\n\nIf you are a member of the `dbt-labs` GitHub organization, you will have push access to the `dbt-core` repo. Rather than forking `dbt-core` to make your changes, just clone the repository, check out a new branch, and push directly to that branch.\n\n## Setting up an environment\n\nThere are some tools that will be helpful to you in developing locally. While this is the list relevant for `dbt-core` development, many of these tools are used commonly across open-source python projects.\n\n### Tools\n\nThese are the tools used in `dbt-core` development and testing:\n\n- [`hatch`](https://hatch.pypa.io/) for build backend, environment management, and running tests across Python versions (3.10, 3.11, 3.12, and 3.13)\n- [`pytest`](https://docs.pytest.org/en/latest/) to define, discover, and run tests\n- [`flake8`](https://flake8.pycqa.org/en/latest/) for code linting\n- [`black`](https://github.com/psf/black) for code formatting\n- [`mypy`](https://mypy.readthedocs.io/en/stable/) for static type checking\n- [`pre-commit`](https://pre-commit.com) to easily run those checks\n- [`changie`](https://changie.dev/) to create changelog entries, without merge conflicts\n- [GitHub Actions](https://github.com/features/actions) for automating tests and checks, once a PR is pushed to the `dbt-core` repository\n\nA deep understanding of these tools in not required to effectively contribute to `dbt-core`, but we recommend checking out the attached documentation if you're interested in learning more about each one.\n\n#### Virtual environments\n\ndbt-core uses [Hatch](https://hatch.pypa.io/) for dependency and environment management. Hatch automatically creates and manages isolated environments for development, testing, and building, so you don't need to manually create virtual environments.\n\nFor more information on how Hatch manages environments, see the [Hatch environment documentation](https://hatch.pypa.io/latest/environment/).\n\n#### Docker and `docker-compose`\n\nDocker and `docker-compose` are both used in testing. Specific instructions for you OS can be found [here](https://docs.docker.com/get-docker/).\n\n\n#### Postgres (optional)\n\nFor testing, and later in the examples in this document, you may want to have `psql` available so you can poke around in the database and see what happened. We recommend that you use [homebrew](https://brew.sh/) for that on macOS, and your package manager on Linux. You can install any version of the postgres client that you'd like. On macOS, with homebrew setup, you can run:\n\n```sh\nbrew install postgresql\n```\n\n## Running `dbt-core` in development\n\n### Installation\n\nFirst make sure you have Python 3.10 or later installed. Ensure you have the latest version of pip installed with `pip install --upgrade pip`. Next, install `hatch`.  Finally set up `dbt-core` for development:\n\n```sh\ncd core\nhatch run setup\n```\n\nThis will install all development dependencies and set up pre-commit hooks.\n\nBy default, hatch will use whatever Python version is active in your environment. To specify a particular Python version, set the `HATCH_PYTHON` environment variable:\n\n```sh\nexport HATCH_PYTHON=3.12\nhatch env create\n```\n\nOr add it to your shell profile (e.g., `~/.zshrc` or `~/.bashrc`) for persistence.\n\nWhen installed in this way, any changes you make to your local copy of the source code will be reflected immediately in your next `dbt` run.\n\n#### Building dbt-core\n\ndbt-core uses [Hatch](https://hatch.pypa.io/) (specifically `hatchling`) as its build backend. To build distribution packages:\n\n```sh\ncd core\nhatch build\n```\n\nThis will create both wheel (`.whl`) and source distribution (`.tar.gz`) files in the `dist/` directory.\n\nThe build configuration is defined in `core/pyproject.toml`. You can also use the standard `python -m build` command if you prefer.\n\n### Running `dbt-core`\n\nOnce you've run `hatch run setup`, the `dbt` command will be available in your PATH. You can verify this by running `which dbt`.\n\nConfigure your [profile](https://docs.getdbt.com/docs/configure-your-profile) as necessary to connect to your target databases. It may be a good idea to add a new profile pointing to a local Postgres instance, or a specific test sandbox within your data warehouse if appropriate. Make sure to create a profile before running integration tests.\n\n## Testing\n\nOnce you're able to manually test that your code change is working as expected, it's important to run existing automated tests, as well as adding some new ones. These tests will ensure that:\n- Your code changes do not unexpectedly break other established functionality\n- Your code changes can handle all known edge cases\n- The functionality you're adding will _keep_ working in the future\n\nAlthough `dbt-core` works with a number of different databases, you won't need to supply credentials for every one of these databases in your test environment. Instead, you can test most `dbt-core` code changes with Python and Postgres.\n\n### Initial setup\n\nPostgres offers the easiest way to test most `dbt-core` functionality today. They are the fastest to run, and the easiest to set up. To run the Postgres integration tests, you'll have to do one extra step of setting up the test database:\n\n```sh\ncd core\nhatch run setup-db\n```\n\nAlternatively, you can run the setup commands directly:\n\n```sh\ndocker-compose up -d database\nPGHOST=localhost PGUSER=root PGPASSWORD=password PGDATABASE=postgres bash scripts/setup_db.sh\n```\n\n### Test commands\n\nThere are a few methods for running tests locally.\n\n#### Hatch scripts\n\nThe primary way to run tests and checks is using hatch scripts (defined in `core/hatch.toml`):\n\n```sh\ncd core\n\n# Run all unit tests\nhatch run unit-tests\n\n# Run unit tests and all code quality checks\nhatch run test\n\n# Run integration tests\nhatch run integration-tests\n\n# Run integration tests for test class\nhatch run integration-tests -k TestVerifyArtifacts\n\n# Run integration tests for test method name\nhatch run integration-tests -k test_load_artifact\n\n# Run integration tests in fail-fast mode\nhatch run integration-tests-fail-fast\n\n# Run linting checks only\nhatch run lint\nhatch run flake8\nhatch run mypy\nhatch run black\n\n# Run all pre-commit hooks\nhatch run code-quality\n\n# Clean build artifacts\nhatch run clean\n```\n\nHatch manages isolated environments and dependencies automatically. The commands above use the `default` environment which is recommended for most local development.\n\n**Using the `ci` environment (optional)**\n\nIf you need to replicate exactly what runs in GitHub Actions (e.g., with coverage reporting), use the `ci` environment:\n\n```sh\ncd core\n\n# Run unit tests with coverage\nhatch run ci:unit-tests\n\n# Run unit tests with a specific Python version\nhatch run +py=3.11 ci:unit-tests\n```\n\n> **Note:** Most developers should use the default environment (`hatch run unit-tests`). The `ci` environment is primarily for debugging CI failures or running tests with coverage.\n\n#### `pre-commit`\n\n[`pre-commit`](https://pre-commit.com) takes care of running all code-checks for formatting and linting. Run `hatch run setup` to install `pre-commit` in your local environment (we recommend running this command with a python virtual environment active). This installs several pip executables including black, mypy, and flake8. Once installed, hooks will run automatically on `git commit`, or you can run them manually with `hatch run code-quality`.\n\n#### `pytest`\n\nFinally, you can also run a specific test or group of tests using [`pytest`](https://docs.pytest.org/en/latest/) directly. After running `hatch run setup`, you can run pytest commands like:\n\n```sh\n# run all unit tests in a file\npython3 -m pytest tests/unit/test_invocation_id.py\n# run a specific unit test\npython3 -m pytest tests/unit/test_invocation_id.py::TestInvocationId::test_invocation_id\n# run specific Postgres functional tests\npython3 -m pytest tests/functional/sources\n```\n\n> See [pytest usage docs](https://docs.pytest.org/en/6.2.x/usage.html) for an overview of useful command-line options.\n\n### Unit, Integration, Functional?\n\nHere are some general rules for adding tests:\n* unit tests (`tests/unit`) don’t need to access a database; \"pure Python\" tests should be written as unit tests\n* functional tests (`tests/functional`) cover anything that interacts with a database, namely adapter\n\n## Debugging\n\n1. The logs for a `dbt run` have stack traces and other information for debugging errors (in `logs/dbt.log` in your project directory).\n2. Try using a debugger, like `ipdb`. For pytest: `--pdb --pdbcls=IPython.terminal.debugger:pdb`\n3. Sometimes, it’s easier to debug on a single thread: `dbt --single-threaded run`\n4. To make print statements from Jinja macros:  `{{ log(msg, info=true) }}`\n5. You can also add `{{ debug() }}` statements, which will drop you into some auto-generated code that the macro wrote.\n6. The dbt “artifacts” are written out to the ‘target’ directory of your dbt project. They are in unformatted json, which can be hard to read. Format them with:\n> python -m json.tool target/run_results.json > run_results.json\n\n### Assorted development tips\n* Append `# type: ignore` to the end of a line if you need to disable `mypy` on that line.\n* Sometimes flake8 complains about lines that are actually fine, in which case you can put a comment on the line such as: # noqa or # noqa: ANNN, where ANNN is the error code that flake8 issues.\n* To collect output for `CProfile`, run dbt with the `-r` option and the name of an output file, i.e. `dbt -r dbt.cprof run`. If you just want to profile parsing, you can do: `dbt -r dbt.cprof parse`. `pip` install `snakeviz` to view the output. Run `snakeviz dbt.cprof` and output will be rendered in a browser window.\n\n## Adding or modifying a CHANGELOG Entry\n\nWe use [changie](https://changie.dev) to generate `CHANGELOG` entries. **Note:** Do not edit the `CHANGELOG.md` directly. Your modifications will be lost.\n\nFollow the steps to [install `changie`](https://changie.dev/guide/installation/) for your system.\n\nOnce changie is installed and your PR is created for a new feature, simply run the following command and changie will walk you through the process of creating a changelog entry:\n\n```shell\nchangie new\n```\n\nCommit the file that's created and your changelog entry is complete!\n\nIf you are contributing to a feature already in progress, you will modify the changie yaml file in dbt/.changes/unreleased/ related to your change. If you need help finding this file, please ask within the discussion for the pull request!\n\nYou don't need to worry about which `dbt-core` version your change will go into. Just create the changelog entry with `changie`, and open your PR against the `main` branch. All merged changes will be included in the next minor version of `dbt-core`. The Core maintainers _may_ choose to \"backport\" specific changes in order to patch older minor versions. In that case, a maintainer will take care of that backport after merging your PR, before releasing the new version of `dbt-core`.\n\n## Submitting a Pull Request\n\nCode can be merged into the current development branch `main` by opening a pull request. If the proposal looks like it's on the right track, then a `dbt-core` maintainer will triage the PR and label it as `ready_for_review`. From this point, two code reviewers will be assigned with the aim of responding to any updates to the PR within about one week. They may suggest code revision for style or clarity, or request that you add unit or integration test(s). These are good things! We believe that, with a little bit of help, anyone can contribute high-quality code. Once merged, your contribution will be available for the next release of `dbt-core`.\n\nAutomated tests run via GitHub Actions. If you're a first-time contributor, all tests (including code checks and unit tests) will require a maintainer to approve. Changes in the `dbt-core` repository trigger integration tests against Postgres. dbt Labs also provides CI environments in which to test changes to other adapters, triggered by PRs in those adapters' repositories, as well as periodic maintenance checks of each adapter in concert with the latest `dbt-core` code changes.\n\nWe require signed git commits. See docs [here](https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits) for setting up code signing.\n\nOnce all tests are passing, all comments are resolved, and your PR has been approved, a `dbt-core` maintainer will merge your changes into the active development branch. And that's it! Happy developing :tada:\n\n## Troubleshooting Tips\n\nSometimes, the content license agreement auto-check bot doesn't find a user's entry in its roster. If you need to force a rerun, add `@cla-bot check` in a comment on the pull request.\n"
  },
  {
    "path": "Dockerfile.test",
    "content": "##\n#  This dockerfile is used for local development and adapter testing only.\n#  See `/docker` for a generic and production-ready docker file\n##\n\nFROM ubuntu:22.04\n\nENV DEBIAN_FRONTEND noninteractive\n\nRUN apt-get update \\\n    && apt-get install -y --no-install-recommends \\\n    software-properties-common gpg-agent \\\n    && add-apt-repository ppa:git-core/ppa -y \\\n    && apt-get dist-upgrade -y \\\n    && apt-get install -y --no-install-recommends \\\n    netcat \\\n    postgresql \\\n    curl \\\n    git \\\n    ssh \\\n    software-properties-common \\\n    make \\\n    build-essential \\\n    ca-certificates \\\n    libpq-dev \\\n    libsasl2-dev \\\n    libsasl2-2 \\\n    libsasl2-modules-gssapi-mit \\\n    libyaml-dev \\\n    unixodbc-dev \\\n    && add-apt-repository ppa:deadsnakes/ppa \\\n    && apt-get install -y \\\n    python-is-python3 \\\n    python-dev-is-python3 \\\n    python3-pip \\\n    python3.10 \\\n    python3.10-dev \\\n    python3.10-venv \\\n    python3.11 \\\n    python3.11-dev \\\n    python3.11-venv \\\n    && apt-get clean \\\n    && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*\n\nARG DOCKERIZE_VERSION=v0.6.1\nRUN curl -LO https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \\\n    && tar -C /usr/local/bin -xzvf dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \\\n    && rm dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz\n\nRUN pip3 install -U hatch wheel pre-commit\n\n# These args are passed in via docker-compose, which reads then from the .env file.\n# On Linux, run `make .env` to create the .env file for the current user.\n# On MacOS and Windows, these can stay unset.\nARG USER_ID\nARG GROUP_ID\n\nRUN if [ ${USER_ID:-0} -ne 0 ] && [ ${GROUP_ID:-0} -ne 0 ]; then \\\n    groupadd -g ${GROUP_ID} dbt_test_user && \\\n    useradd -m -l -u ${USER_ID} -g ${GROUP_ID} dbt_test_user; \\\n    else \\\n    useradd -mU -l dbt_test_user; \\\n    fi\nRUN mkdir /usr/app && chown dbt_test_user /usr/app\n\nWORKDIR /usr/app\nVOLUME /usr/app\n\nUSER dbt_test_user\n\nENV PYTHONIOENCODING=utf-8\nENV LANG C.UTF-8\n"
  },
  {
    "path": "Makefile",
    "content": "# ============================================================================\n# DEPRECATED: This Makefile is maintained for backwards compatibility only.\n#\n# dbt-core now uses Hatch for task management and development workflows.\n# Please migrate to using hatch commands directly:\n#\n#   make dev               →  cd core && hatch run setup\n#   make unit              →  cd core && hatch run unit-tests\n#   make test              →  cd core && hatch run test\n#   make integration       →  cd core && hatch run integration-tests\n#   make lint              →  cd core && hatch run lint\n#   make code_quality      →  cd core && hatch run code-quality\n#   make setup-db          →  cd core && hatch run setup-db\n#   make clean             →  cd core && hatch run clean\n#\n# See core/pyproject.toml [tool.hatch.envs.default.scripts] for all available\n# commands and CONTRIBUTING.md for detailed usage instructions.\n#\n# This Makefile will be removed in a future version of dbt-core.\n# ============================================================================\n\n.DEFAULT_GOAL:=help\n\n.PHONY: dev_req\ndev_req: ## Installs dbt-* packages in develop mode along with only development dependencies.\n\t@cd core && hatch run dev-req\n\n.PHONY: dev\ndev: ## Installs dbt-* packages in develop mode along with development dependencies and pre-commit.\n\t@cd core && hatch run setup\n\n.PHONY: dev-uninstall\ndev-uninstall: ## Uninstall all packages in venv except for build tools\n\t@pip freeze | grep -v \"^-e\" | cut -d \"@\" -f1 | xargs pip uninstall -y; \\\n\tpip uninstall -y dbt-core\n\n.PHONY: mypy\nmypy: ## Runs mypy against staged changes for static type checking.\n\t@cd core && hatch run mypy\n\n.PHONY: flake8\nflake8: ## Runs flake8 against staged changes to enforce style guide.\n\t@cd core && hatch run flake8\n\n.PHONY: black\nblack: ## Runs black against staged changes to enforce style guide.\n\t@cd core && hatch run black\n\n.PHONY: lint\nlint: ## Runs flake8 and mypy code checks against staged changes.\n\t@cd core && hatch run lint\n\n.PHONY: code_quality\ncode_quality: ## Runs all pre-commit hooks against all files.\n\t@cd core && hatch run code-quality\n\n.PHONY: unit\nunit: ## Runs unit tests with py\n\t@cd core && hatch run unit-tests\n\n.PHONY: test\ntest: ## Runs unit tests with py and code checks against staged changes.\n\t@cd core && hatch run test\n\n.PHONY: integration\nintegration: ## Runs core integration tests using postgres with py-integration\n\t@cd core && hatch run integration-tests\n\n.PHONY: integration-fail-fast\nintegration-fail-fast: ## Runs core integration tests using postgres with py-integration in \"fail fast\" mode.\n\t@cd core && hatch run integration-tests-fail-fast\n\n.PHONY: setup-db\nsetup-db: ## Setup Postgres database with docker-compose for system testing.\n\t@cd core && hatch run setup-db\n\n.PHONY: clean\nclean: ## Resets development environment.\n\t@cd core && hatch run clean\n\n.PHONY: json_schema\njson_schema: ## Update generated JSON schema using code changes.\n\t@cd core && hatch run json-schema\n\n.PHONY: help\nhelp: ## Show this help message.\n\t@echo 'usage: make [target]'\n\t@echo\n\t@echo 'DEPRECATED: This Makefile is a compatibility shim.'\n\t@echo 'Please use \"cd core && hatch run <command>\" directly.'\n\t@echo\n\t@echo 'targets:'\n\t@grep -E '^[8+a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = \":.*?## \"}; {printf \"\\033[36m%-30s\\033[0m %s\\n\", $$1, $$2}'\n\t@echo\n\t@echo 'For more information, see CONTRIBUTING.md'\n"
  },
  {
    "path": "README.md",
    "content": "<p align=\"center\">\n  <img src=\"https://raw.githubusercontent.com/dbt-labs/dbt-core/fa1ea14ddfb1d5ae319d5141844910dd53ab2834/etc/dbt-core.svg\" alt=\"dbt logo\" width=\"750\"/>\n</p>\n<p align=\"center\">\n  <a href=\"https://github.com/dbt-labs/dbt-core/actions/workflows/main.yml\">\n    <img src=\"https://github.com/dbt-labs/dbt-core/actions/workflows/main.yml/badge.svg?event=push\" alt=\"CI Badge\"/>\n  </a>\n  <a href=\"https://www.bestpractices.dev/projects/11095\"><img src=\"https://www.bestpractices.dev/projects/11095/badge\"></a>\n</p>\n\n**[dbt](https://www.getdbt.com/)** enables data analysts and engineers to transform their data using the same practices that software engineers use to build applications.\n\n![architecture](https://github.com/dbt-labs/dbt-core/blob/202cb7e51e218c7b29eb3b11ad058bd56b7739de/etc/dbt-transform.png)\n\n## Understanding dbt\n\nAnalysts using dbt can transform their data by simply writing select statements, while dbt handles turning these statements into tables and views in a data warehouse.\n\nThese select statements, or \"models\", form a dbt project. Models frequently build on top of one another – dbt makes it easy to [manage relationships](https://docs.getdbt.com/docs/ref) between models, and [visualize these relationships](https://docs.getdbt.com/docs/documentation), as well as assure the quality of your transformations through [testing](https://docs.getdbt.com/docs/testing).\n\n![dbt dag](https://raw.githubusercontent.com/dbt-labs/dbt-core/6c6649f9129d5d108aa3b0526f634cd8f3a9d1ed/etc/dbt-dag.png)\n\n## Getting started\n\n- [Install dbt Core](https://docs.getdbt.com/docs/get-started/installation) or explore the [dbt Cloud CLI](https://docs.getdbt.com/docs/cloud/cloud-cli-installation), a command-line interface powered by [dbt Cloud](https://docs.getdbt.com/docs/cloud/about-cloud/dbt-cloud-features) that enhances collaboration.\n- Read the [introduction](https://docs.getdbt.com/docs/introduction/) and [viewpoint](https://docs.getdbt.com/docs/about/viewpoint/)\n\n## Join the dbt Community\n\n- Be part of the conversation in the [dbt Community Slack](http://community.getdbt.com/)\n- Read more on the [dbt Community Discourse](https://discourse.getdbt.com)\n\n## Reporting bugs and contributing code\n\n- Want to report a bug or request a feature? Let us know and open [an issue](https://github.com/dbt-labs/dbt-core/issues/new/choose)\n- Want to help us build dbt? Check out the [Contributing Guide](https://github.com/dbt-labs/dbt-core/blob/HEAD/CONTRIBUTING.md)\n\n## Code of Conduct\n\nEveryone interacting in the dbt project's codebases, issue trackers, chat rooms, and mailing lists is expected to follow the [dbt Code of Conduct](https://docs.getdbt.com/community/resources/code-of-conduct).\n"
  },
  {
    "path": "SECURITY.md",
    "content": "[About dbt Core versions](https://docs.getdbt.com/docs/dbt-versions/core)\n"
  },
  {
    "path": "codecov.yml",
    "content": "ignore:\n  - \".github\"\n  - \".changes\"\n\n# Disable all status checks to prevent red X's in CI\n# Coverage data is still uploaded and PR comments are still posted\ncoverage:\n  status:\n    project: off\n    patch: off\n\ncomment:\n  layout: \"header, diff, flags, components\" # show component info in the PR comment\n\ncomponent_management:\n  individual_components:\n    - component_id: unittests\n      name: \"Unit Tests\"\n      flag_regexes:\n        - \"unit\"\n    - component_id: integrationtests\n      name: \"Integration Tests\"\n      flag_regexes:\n        - \"integration\"\n"
  },
  {
    "path": "core/.test_durations",
    "content": "{\n    \"tests/functional/access/test_access.py::TestAccess::test_access_attribute\": 19.693285994999997,\n    \"tests/functional/access/test_access.py::TestAccessDbtProjectConfig::test_dbt_project_access_config\": 3.759677324999984,\n    \"tests/functional/access/test_access.py::TestGenericTestRestrictAccess::test_generic_tests\": 7.516862858999957,\n    \"tests/functional/access/test_access.py::TestRestrictedPackageAccess::test_restricted_private_ref\": 3.6331608349999556,\n    \"tests/functional/access/test_access.py::TestRestrictedPackageAccess::test_restricted_protected_ref\": 6.427091412000038,\n    \"tests/functional/access/test_access.py::TestUnrestrictedPackageAccess::test_unrestricted_protected_ref\": 6.779408883999963,\n    \"tests/functional/analysis/test_analyses.py::TestAnalyses::test_postgres_analyses\": 1.7279378940000072,\n    \"tests/functional/artifacts/test_artifact_fields.py::TestRelationNameInTests::test_relation_name_in_tests\": 7.938031587000012,\n    \"tests/functional/artifacts/test_artifacts.py::TestVerifyArtifacts::test_load_artifact\": 2.982837594999978,\n    \"tests/functional/artifacts/test_artifacts.py::TestVerifyArtifacts::test_run_and_generate\": 16.822443084999975,\n    \"tests/functional/artifacts/test_artifacts.py::TestVerifyArtifactsReferences::test_references\": 9.926057194999885,\n    \"tests/functional/artifacts/test_artifacts.py::TestVerifyArtifactsVersions::test_versions\": 9.94775005200006,\n    \"tests/functional/artifacts/test_artifacts.py::TestVerifyRunOperation::test_run_model_with_operation\": 3.423703161999981,\n    \"tests/functional/artifacts/test_artifacts.py::TestVerifyRunOperation::test_run_operation\": 8.988266632999967,\n    \"tests/functional/artifacts/test_docs_generate_defer.py::TestDocsGenerateDefer::test_generate_defer\": 1.614032256999991,\n    \"tests/functional/artifacts/test_override.py::TestDocsGenerateOverride::test_override_used\": 9.814491736999969,\n    \"tests/functional/artifacts/test_previous_version_state.py::TestPreviousVersionState::test_backwards_compatible_run_results_versions\": 8.14310199400012,\n    \"tests/functional/artifacts/test_previous_version_state.py::TestPreviousVersionState::test_backwards_compatible_versions\": 27.613001499000006,\n    \"tests/functional/artifacts/test_previous_version_state.py::TestPreviousVersionState::test_compare_results_current\": 3.892034876000025,\n    \"tests/functional/artifacts/test_previous_version_state.py::TestPreviousVersionState::test_compare_state_current\": 3.334224613999993,\n    \"tests/functional/artifacts/test_previous_version_state.py::TestPreviousVersionState::test_get_manifest_schema_version\": 0.03290388900001062,\n    \"tests/functional/artifacts/test_previous_version_state.py::TestPreviousVersionState::test_nonbackwards_compatible_versions\": 10.849718646000042,\n    \"tests/functional/artifacts/test_previous_version_state.py::TestPreviousVersionState::test_project\": 7.619359766999992,\n    \"tests/functional/artifacts/test_run_execution_result.py::test_run_execution_result_compiled_serialization\": 8.298854163000101,\n    \"tests/functional/artifacts/test_run_results.py::TestRunResultsSerializableInContext::test_results_serializable\": 9.274184312000102,\n    \"tests/functional/artifacts/test_run_results.py::TestRunResultsTimingFailure::test_timing_exists\": 8.796365435999974,\n    \"tests/functional/artifacts/test_run_results.py::TestRunResultsTimingSuccess::test_timing_exists\": 8.697306241000092,\n    \"tests/functional/artifacts/test_run_results.py::TestRunResultsWritesFileOnSignal::test_run_results_are_written_on_signal\": 0.0012458909999395473,\n    \"tests/functional/basic/test_basic.py::test_basic\": 9.023939860000155,\n    \"tests/functional/basic/test_invalid_reference.py::test_undefined_value\": 8.499570390999907,\n    \"tests/functional/basic/test_jaffle_shop.py::TestBasic::test_basic\": 17.90248904300006,\n    \"tests/functional/basic/test_jaffle_shop.py::TestBasic::test_execution_time_format_is_humanized\": 12.56305247499995,\n    \"tests/functional/basic/test_mixed_case_db.py::test_basic\": 14.851846751999915,\n    \"tests/functional/basic/test_project.py::TestArchiveNotAllowed::test_archive_not_allowed\": 5.360570413000005,\n    \"tests/functional/basic/test_project.py::TestProjectConfigVersionMissing::test_empty_version\": 10.43638870000018,\n    \"tests/functional/basic/test_project.py::TestProjectDbtCloudConfig::test_dbt_cloud\": 4.401225789000023,\n    \"tests/functional/basic/test_project.py::TestProjectDbtCloudConfigString::test_dbt_cloud_invalid\": 11.372771833000002,\n    \"tests/functional/basic/test_project.py::TestProjectYamlVersionInvalid::test_invalid_version\": 10.449192945999926,\n    \"tests/functional/basic/test_project.py::TestProjectYamlVersionMissing::test_empty_version\": 10.180516065000006,\n    \"tests/functional/basic/test_project.py::TestProjectYamlVersionValid::test_valid_version\": 10.430264007000005,\n    \"tests/functional/basic/test_project.py::TestSchemaYmlVersionMissing::test_empty_version\": 10.775652831999878,\n    \"tests/functional/basic/test_project.py::TestVersionSpecifierChecksComeBeforeYamlValidation::test_version_specifier_checks_before_yaml_validation\": 5.235425129999953,\n    \"tests/functional/basic/test_simple_reference.py::test_simple_ref_with_models\": 20.031065766999973,\n    \"tests/functional/basic/test_simple_reference.py::test_simple_reference\": 37.87860925199993,\n    \"tests/functional/basic/test_simple_reference.py::test_simple_reference_with_models_and_children\": 20.939061037999977,\n    \"tests/functional/basic/test_varchar_widening.py::test_varchar_widening\": 2.2054005790000133,\n    \"tests/functional/build_command/test_build.py::TestCircularRelationshipTestsBuild::test_circular_relationship_test_success\": 14.430405085000075,\n    \"tests/functional/build_command/test_build.py::TestDownstreamSelection::test_downstream_selection\": 14.403590032000125,\n    \"tests/functional/build_command/test_build.py::TestFailingBuild::test_failing_test_skips_downstream\": 14.171351606999906,\n    \"tests/functional/build_command/test_build.py::TestFailingTestsBuild::test_failing_test_skips_downstream\": 3.4541219389999895,\n    \"tests/functional/build_command/test_build.py::TestInterdependentModels::test_interdependent_models\": 15.360765523000055,\n    \"tests/functional/build_command/test_build.py::TestInterdependentModelsFail::test_interdependent_models_fail\": 14.990420995000022,\n    \"tests/functional/build_command/test_build.py::TestLimitedUpstreamSelection::test_limited_upstream_selection\": 14.407232419000024,\n    \"tests/functional/build_command/test_build.py::TestPassingBuild::test_build_happy_path\": 14.911859800999878,\n    \"tests/functional/build_command/test_build.py::TestSimpleBlockingTest::test_simple_blocking_test\": 13.293703752000056,\n    \"tests/functional/catalogs/test_catalogs_parsing.py::TestDuplicateWriteIntegration::test_integration\": 6.7745474119998335,\n    \"tests/functional/catalogs/test_catalogs_parsing.py::TestInvalidWriteIntegration::test_integration\": 0.3199430450000307,\n    \"tests/functional/catalogs/test_catalogs_parsing.py::TestMultipleWriteIntegration::test_integration\": 14.075824718000035,\n    \"tests/functional/catalogs/test_catalogs_parsing.py::TestNoActiveWriteIntegration::test_integration\": 6.72967783799993,\n    \"tests/functional/catalogs/test_catalogs_parsing.py::TestSingleWriteIntegration::test_integration\": 13.811159436000139,\n    \"tests/functional/clean/test_clean.py::TestCleanPathOutsideProjectAbsolute::test_clean_path_outside_project\": 6.962187210000025,\n    \"tests/functional/clean/test_clean.py::TestCleanPathOutsideProjectRelative::test_clean_path_outside_project\": 6.944305652000139,\n    \"tests/functional/clean/test_clean.py::TestCleanPathOutsideProjectWithFlag::test_clean_path_outside_project\": 6.980458942999917,\n    \"tests/functional/clean/test_clean.py::TestCleanRelativeProjectDir::test_clean_relative_project_dir\": 6.891713305000053,\n    \"tests/functional/clean/test_clean.py::TestCleanSourcePath::test_clean_source_path\": 1.763001666000008,\n    \"tests/functional/cli/test_cli_exit_codes.py::TestExitCodeOne::test_exc_thrown\": 15.23298833900003,\n    \"tests/functional/cli/test_cli_exit_codes.py::TestExitCodeZero::test_no_exc_thrown\": 2.4715167580000355,\n    \"tests/functional/cli/test_click_flags.py::TestClickCLIFlagsResolveFalsey::test_resolve_falsey\": 0.6696680100001231,\n    \"tests/functional/cli/test_click_flags.py::TestClickCLIFlagsResolveTruthy::test_resolve_truthy\": 7.186096984999949,\n    \"tests/functional/cli/test_click_flags.py::TestClickEnvVarFlagsResolveFalsey::test_resolve_falsey[0]\": 0.6867838390000429,\n    \"tests/functional/cli/test_click_flags.py::TestClickEnvVarFlagsResolveFalsey::test_resolve_falsey[f]\": 0.9031602569999961,\n    \"tests/functional/cli/test_click_flags.py::TestClickEnvVarFlagsResolveFalsey::test_resolve_falsey[false]\": 7.5558693230000245,\n    \"tests/functional/cli/test_click_flags.py::TestClickEnvVarFlagsResolveFalsey::test_resolve_falsey[n]\": 7.431096890000163,\n    \"tests/functional/cli/test_click_flags.py::TestClickEnvVarFlagsResolveFalsey::test_resolve_falsey[no]\": 15.229194409000229,\n    \"tests/functional/cli/test_click_flags.py::TestClickEnvVarFlagsResolveFalsey::test_resolve_falsey[off]\": 0.6196650370000043,\n    \"tests/functional/cli/test_click_flags.py::TestClickEnvVarFlagsResolveTruthy::test_resolve_truthy[1]\": 0.05747299999984534,\n    \"tests/functional/cli/test_click_flags.py::TestClickEnvVarFlagsResolveTruthy::test_resolve_truthy[on]\": 0.036709330999883605,\n    \"tests/functional/cli/test_click_flags.py::TestClickEnvVarFlagsResolveTruthy::test_resolve_truthy[t]\": 0.2084927049999976,\n    \"tests/functional/cli/test_click_flags.py::TestClickEnvVarFlagsResolveTruthy::test_resolve_truthy[true]\": 0.038485730000047624,\n    \"tests/functional/cli/test_click_flags.py::TestClickEnvVarFlagsResolveTruthy::test_resolve_truthy[y]\": 0.03741321299980882,\n    \"tests/functional/cli/test_click_flags.py::TestClickEnvVarFlagsResolveTruthy::test_resolve_truthy[yes]\": 7.547093960999973,\n    \"tests/functional/cli/test_env_var_deprecations.py::TestDeprecatedEnvVars::test_defer\": 3.296107156000005,\n    \"tests/functional/cli/test_env_var_deprecations.py::TestDeprecatedEnvVars::test_favor_state\": 1.1239154569999528,\n    \"tests/functional/cli/test_env_var_deprecations.py::TestDeprecatedEnvVars::test_print\": 3.9606142529999886,\n    \"tests/functional/cli/test_env_var_deprecations.py::TestDeprecatedEnvVars::test_state\": 1.2487158410000347,\n    \"tests/functional/cli/test_error_handling.py::TestHandledExit::test_fail_fast_failed_run_does_not_throw\": 1.2742476209999154,\n    \"tests/functional/cli/test_error_handling.py::TestHandledExit::test_failed_run_does_not_throw\": 2.3287831530000176,\n    \"tests/functional/cli/test_multioption.py::TestOutputKeys::test_output_key_args\": 1.12989019500003,\n    \"tests/functional/cli/test_multioption.py::TestOutputKeys::test_output_key_nested\": 1.2242512610000063,\n    \"tests/functional/cli/test_multioption.py::TestOutputKeys::test_output_key_nested_deep_meta\": 0.5794108019999982,\n    \"tests/functional/cli/test_multioption.py::TestOutputKeys::test_output_key_nested_deep_nonexistent\": 1.3214415239999653,\n    \"tests/functional/cli/test_multioption.py::TestOutputKeys::test_output_key_nested_mixed_existent_nonexistent\": 0.9375792609999962,\n    \"tests/functional/cli/test_multioption.py::TestOutputKeys::test_output_key_nested_nonexistent\": 1.2864939249999452,\n    \"tests/functional/cli/test_multioption.py::TestOutputKeys::test_output_key_nested_single_arg\": 1.2544720579999762,\n    \"tests/functional/cli/test_multioption.py::TestOutputKeys::test_output_key_nested_whole_meta_object\": 0.32358837599998935,\n    \"tests/functional/cli/test_multioption.py::TestOutputKeys::test_output_key_quoted\": 1.1302335889999995,\n    \"tests/functional/cli/test_multioption.py::TestOutputKeys::test_output_key_single\": 2.645741085999987,\n    \"tests/functional/cli/test_multioption.py::TestResourceType::test_resource_type_args\": 1.0797773520000078,\n    \"tests/functional/cli/test_multioption.py::TestResourceType::test_resource_type_quoted\": 1.2743162830000188,\n    \"tests/functional/cli/test_multioption.py::TestResourceType::test_resource_type_single\": 1.0616604209999991,\n    \"tests/functional/cli/test_multioption.py::TestSelectExclude::test_select_exclude_args\": 6.061109839999972,\n    \"tests/functional/cli/test_multioption.py::TestSelectExclude::test_select_exclude_quoted\": 5.288789140000006,\n    \"tests/functional/cli/test_multioption.py::TestSelectExclude::test_select_exclude_single\": 5.510430188999976,\n    \"tests/functional/cli/test_option_interaction_validations.py::TestEventTimeEndEventTimeStart::test_option_combo[2024-10-01-2024-10-02-True]\": 0.823348368999973,\n    \"tests/functional/cli/test_option_interaction_validations.py::TestEventTimeEndEventTimeStart::test_option_combo[2024-10-02-2024-10-01-False]\": 0.10365628400001015,\n    \"tests/functional/cli/test_option_interaction_validations.py::TestEventTimeEndEventTimeStartMutuallyRequired::test_option_combo[--event-time-end---event-time-start]\": 0.08300517900011073,\n    \"tests/functional/cli/test_option_interaction_validations.py::TestEventTimeEndEventTimeStartMutuallyRequired::test_option_combo[--event-time-start---event-time-end]\": 2.1814881920000175,\n    \"tests/functional/cli/test_requires.py::TestEngineEnvVarPickedUpByClick::test_engine_env_var_picked_up_by_cli_flags\": 10.14885321700001,\n    \"tests/functional/cli/test_requires.py::TestKnownEngineEnvVarsExplicit::test_allow_list_is_correct\": 5.149495886000011,\n    \"tests/functional/cli/test_requires.py::TestOldEngineEnvVarPropagation::test_engine_env_var_propagation[False-False-0]\": 4.447983458999943,\n    \"tests/functional/cli/test_requires.py::TestOldEngineEnvVarPropagation::test_engine_env_var_propagation[False-True-True]\": 0.7585075270000061,\n    \"tests/functional/cli/test_requires.py::TestOldEngineEnvVarPropagation::test_engine_env_var_propagation[True-False-False]\": 0.9553055470000089,\n    \"tests/functional/cli/test_requires.py::TestOldEngineEnvVarPropagation::test_engine_env_var_propagation[True-True-True]\": 3.655993809000023,\n    \"tests/functional/cli/test_resolvers.py::TestDefaultLogPathNoProject::test_default_log_path_no_project\": 0.0020984590000807657,\n    \"tests/functional/cli/test_resolvers.py::TestDefaultLogPathWithProject::test_default_log_path_with_project\": 2.443658099000004,\n    \"tests/functional/cli/test_resolvers.py::TestDefaultLogPathWithProjectNoConfiguredLogPath::test_default_log_path_with_project\": 2.4112458740000307,\n    \"tests/functional/colors/test_colors.py::TestColors::test_no_use_colors\": 1.0433806659999902,\n    \"tests/functional/colors/test_colors.py::TestColors::test_use_colors\": 6.195680938999999,\n    \"tests/functional/column_quoting/test_column_quotes.py::TestColumnQuotingDefault::test_column_quotes\": 2.852184763000025,\n    \"tests/functional/column_quoting/test_column_quotes.py::TestColumnQuotingDisabled::test_column_quotes\": 14.150319632999981,\n    \"tests/functional/column_quoting/test_column_quotes.py::TestColumnQuotingEnabled::test_column_quotes\": 2.5683979560000125,\n    \"tests/functional/compile/test_compile.py::TestCompile::test_compile_inline_not_add_node\": 8.575035064999838,\n    \"tests/functional/compile/test_compile.py::TestCompile::test_compile_inline_ref_node_not_exist\": 4.3541807800000925,\n    \"tests/functional/compile/test_compile.py::TestCompile::test_compile_inline_syntax_error\": 4.393746528999941,\n    \"tests/functional/compile/test_compile.py::TestCompile::test_graph_summary_output\": 4.844826934000025,\n    \"tests/functional/compile/test_compile.py::TestCompile::test_inline_fail\": 3.9648541490000753,\n    \"tests/functional/compile/test_compile.py::TestCompile::test_inline_fail_database_error\": 1.9286313570000004,\n    \"tests/functional/compile/test_compile.py::TestCompile::test_inline_pass\": 4.394097374000012,\n    \"tests/functional/compile/test_compile.py::TestCompile::test_inline_pass_quiet\": 0.6285069539999881,\n    \"tests/functional/compile/test_compile.py::TestCompile::test_multiline_jinja\": 1.7603685540000242,\n    \"tests/functional/compile/test_compile.py::TestCompile::test_none\": 4.513015250999999,\n    \"tests/functional/compile/test_compile.py::TestCompile::test_output_json_inline\": 4.434909527000173,\n    \"tests/functional/compile/test_compile.py::TestCompile::test_output_json_inline_quiet\": 4.501236069000015,\n    \"tests/functional/compile/test_compile.py::TestCompile::test_output_json_select\": 0.7105877959999845,\n    \"tests/functional/compile/test_compile.py::TestCompile::test_output_json_select_quiet\": 4.546718135999981,\n    \"tests/functional/compile/test_compile.py::TestCompile::test_select_pass\": 4.194874711000011,\n    \"tests/functional/compile/test_compile.py::TestCompile::test_select_pass_empty\": 4.22149414099988,\n    \"tests/functional/compile/test_compile.py::TestCompile::test_select_pass_quiet\": 4.167139651999946,\n    \"tests/functional/compile/test_compile.py::TestEphemeralModelWithAlias::test_compile\": 8.302734589999943,\n    \"tests/functional/compile/test_compile.py::TestEphemeralModels::test_first_selector\": 7.3124343530000715,\n    \"tests/functional/compile/test_compile.py::TestEphemeralModels::test_last_selector\": 3.713934369999947,\n    \"tests/functional/compile/test_compile.py::TestEphemeralModels::test_middle_selector\": 3.7627890670000284,\n    \"tests/functional/compile/test_compile.py::TestEphemeralModels::test_no_selector\": 3.8010051750000002,\n    \"tests/functional/compile/test_compile.py::TestEphemeralModels::test_with_recursive_cte\": 3.854703838999967,\n    \"tests/functional/compile/test_compile.py::TestIntrospectFlag::test_default\": 8.733216757000037,\n    \"tests/functional/compile/test_compile.py::TestIntrospectFlag::test_no_introspect\": 3.469682151000029,\n    \"tests/functional/compile/test_compile.py::TestSqlParseGroupingDepthLimit::test_sqlparse_grouping_depth_limit\": 1.723351385000015,\n    \"tests/functional/compile/test_compile.py::TestSqlParseGroupingTokenLimit::test_sqlparse_grouping_token_limit\": 4.526235583999991,\n    \"tests/functional/configs/test_configs.py::TestConfigs::test_config_layering\": 25.892917640000064,\n    \"tests/functional/configs/test_configs.py::TestInvalidSeedsMaterializationProj::test_seeds_materialization_proj_config\": 0.6982047689999717,\n    \"tests/functional/configs/test_configs.py::TestInvalidSeedsMaterializationSchema::test_seeds_materialization_schema_config\": 0.8212266049999641,\n    \"tests/functional/configs/test_configs.py::TestInvalidSnapshotsMaterializationProj::test_snapshots_materialization_proj_config\": 1.0271297680000089,\n    \"tests/functional/configs/test_configs.py::TestInvalidSnapshotsMaterializationSchema::test_snapshots_materialization_schema_config\": 10.64628221800001,\n    \"tests/functional/configs/test_configs.py::TestInvalidTestsMaterializationProj::test_tests_materialization_proj_config\": 9.438830603000042,\n    \"tests/functional/configs/test_configs.py::TestTargetConfigs::test_alternative_target_paths\": 10.385924960000011,\n    \"tests/functional/configs/test_configs_in_schema_files.py::TestLegacySchemaFileConfigs::test_config_layering\": 58.362766896999915,\n    \"tests/functional/configs/test_configs_in_schema_files.py::TestListSchemaFile::test_list_schema\": 11.340628384999945,\n    \"tests/functional/configs/test_configs_in_schema_files.py::TestSchemaFileConfigs::test_config_layering\": 52.898641360000056,\n    \"tests/functional/configs/test_contract_configs.py::TestModelContractEnabledConfigs::test__model_contract\": 13.344759579000083,\n    \"tests/functional/configs/test_contract_configs.py::TestModelContractEnabledConfigsMissingDataTypes::test_undefined_column_type\": 13.544680990999836,\n    \"tests/functional/configs/test_contract_configs.py::TestModelContractMissingYAMLColumns::test__missing_column_contract_error\": 2.5923054649999813,\n    \"tests/functional/configs/test_contract_configs.py::TestModelLevelConstraintsErrorMessages::test__config_errors\": 13.269513075999953,\n    \"tests/functional/configs/test_contract_configs.py::TestModelLevelConstraintsWarningMessages::test__config_warning\": 9.62273693499992,\n    \"tests/functional/configs/test_contract_configs.py::TestModelLevelContractDisabledConfigs::test__model_contract_false\": 13.158855357999869,\n    \"tests/functional/configs/test_contract_configs.py::TestModelLevelContractEnabledConfigs::test__model_contract_true\": 19.71907576199999,\n    \"tests/functional/configs/test_contract_configs.py::TestModelLevelContractErrorMessages::test__config_errors\": 13.356074628999977,\n    \"tests/functional/configs/test_contract_configs.py::TestPrimaryKeysModelAndColumnLevelConstraints::test_model_column_pk_error\": 0.7245696980000105,\n    \"tests/functional/configs/test_contract_configs.py::TestPrimaryKeysMultipleColumns::test_pk_multiple_columns\": 2.177795070000002,\n    \"tests/functional/configs/test_contract_configs.py::TestProjectContractEnabledConfigs::test_defined_column_type\": 12.974213028000122,\n    \"tests/functional/configs/test_contract_configs.py::TestProjectContractEnabledConfigsError::test_undefined_column_type\": 13.282185422000111,\n    \"tests/functional/configs/test_contract_configs.py::TestPythonModelLevelContractErrorMessages::test__python_errors\": 1.6309031109999523,\n    \"tests/functional/configs/test_contract_configs.py::TestSchemaContractEnabledConfigs::test__schema_error\": 1.4336319429999662,\n    \"tests/functional/configs/test_custom_node_colors_configs.py::TestCustomNodeColorIncorrectColorHEXYMLConfig::test__invalid_color_docs_under_config\": 6.099621764000005,\n    \"tests/functional/configs/test_custom_node_colors_configs.py::TestCustomNodeColorIncorrectColorModelConfig::test__invalid_color_config_block\": 3.313332834999983,\n    \"tests/functional/configs/test_custom_node_colors_configs.py::TestCustomNodeColorIncorrectColorNameYMLConfig::test__invalid_color_docs_not_under_config\": 5.256898958999955,\n    \"tests/functional/configs/test_custom_node_colors_configs.py::TestCustomNodeColorIncorrectColorProject::test__invalid_color_project\": 0.6639624049999924,\n    \"tests/functional/configs/test_custom_node_colors_configs.py::TestModelLevelProjectColorConfigs::test__model_override_project\": 2.6884690750000004,\n    \"tests/functional/configs/test_custom_node_colors_configs.py::TestModelLevelSchemaColorConfigs::test__model_override_schema\": 2.911380523000048,\n    \"tests/functional/configs/test_custom_node_colors_configs.py::TestModelOverProjectColorConfigs::test__model_show_overrides_dbt_project\": 3.351814560999969,\n    \"tests/functional/configs/test_custom_node_colors_configs.py::TestSchemaOverProjectColorConfigs::test__schema_override_project\": 1.0244241880000118,\n    \"tests/functional/configs/test_custom_node_colors_configs.py::TestSubdirectoryColorConfigs::test__project_folder_override_project_root\": 3.0257529720000207,\n    \"tests/functional/configs/test_disabled_configs.py::TestDisabledConfigs::test_conditional_model\": 15.415401803999998,\n    \"tests/functional/configs/test_disabled_configs.py::TestDisabledConfigs::test_disable_seed_partial_parse\": 11.202385377999974,\n    \"tests/functional/configs/test_disabled_configs.py::TestDisabledConfigsSameName::test_disabled_analysis\": 4.263107648000073,\n    \"tests/functional/configs/test_disabled_model.py::TestInvalidEnabledConfig::test_invalid_config\": 6.700385677999975,\n    \"tests/functional/configs/test_disabled_model.py::TestManyDisabledNodesSuccess::test_many_disabled_config\": 0.6557107710000025,\n    \"tests/functional/configs/test_disabled_model.py::TestModelDisabledConfigs::test_disabled_config\": 0.6521544539999695,\n    \"tests/functional/configs/test_disabled_model.py::TestMultipleDisabledNodesForUniqueIDFailure::test_disabled_config\": 6.145755412000028,\n    \"tests/functional/configs/test_disabled_model.py::TestMultipleDisabledNodesOverrideModel::test_multiple_disabled_config\": 6.647647699999993,\n    \"tests/functional/configs/test_disabled_model.py::TestMultipleDisabledNodesSuccess::test_multiple_disabled_config\": 0.8877035249999778,\n    \"tests/functional/configs/test_disabled_model.py::TestOverrideFalseYAMLConfigsInSQL::test_override_yaml_sql_config\": 4.020583670000008,\n    \"tests/functional/configs/test_disabled_model.py::TestOverrideProjectConfigsInSQL::test_override_project_sql_config\": 5.595645962000049,\n    \"tests/functional/configs/test_disabled_model.py::TestOverrideProjectConfigsInYaml::test_override_project_yaml_config\": 5.544950577000009,\n    \"tests/functional/configs/test_disabled_model.py::TestOverrideTrueYAMLConfigsInSQL::test_override_yaml_sql_config\": 6.1709249380000415,\n    \"tests/functional/configs/test_disabled_model.py::TestSchemaDisabledConfigs::test_disabled_config\": 5.007815124000047,\n    \"tests/functional/configs/test_disabled_model.py::TestSchemaDisabledConfigsFailure::test_disabled_config\": 5.038891781999951,\n    \"tests/functional/configs/test_dupe_paths.py::TestDupeProjectPaths::test_config_with_dupe_paths\": 11.528093543000011,\n    \"tests/functional/configs/test_dupe_paths.py::TestDupeStrippedProjectPaths::test_config_with_dupe_paths\": 11.66505034100004,\n    \"tests/functional/configs/test_get_default.py::TestConfigGetDefault::test_config_with_get_default\": 7.981411667000032,\n    \"tests/functional/configs/test_get_default.py::TestConfigGetMeta::test_config_with_meta_key\": 12.29262933900003,\n    \"tests/functional/configs/test_get_default.py::TestConfigGetMetaRequire::test_config_with_meta_require\": 1.636889019000023,\n    \"tests/functional/configs/test_grant_configs.py::TestGrantConfigs::test_model_grant_config\": 39.03587114100003,\n    \"tests/functional/configs/test_indiv_tests.py::TestConfigIndivTests::test_configuring_individual_tests\": 37.198720931000025,\n    \"tests/functional/configs/test_unused_configs.py::TestUnusedModelConfigs::test_warn_unused_configuration_paths\": 14.602653407000048,\n    \"tests/functional/configs/test_vars_file.py::TestComplexVarValues::test_complex_var_values\": 12.805695482999909,\n    \"tests/functional/configs/test_vars_file.py::TestDbtProjectVarCliOverridesFile::test_cli_overrides_vars_file\": 10.501770113999896,\n    \"tests/functional/configs/test_vars_file.py::TestDbtProjectVarFromVarsFile::test_dbt_project_var_from_vars_file\": 10.362994761000095,\n    \"tests/functional/configs/test_vars_file.py::TestDbtProjectVarMissingFromVarsFile::test_error_when_var_missing\": 0.04560613100011324,\n    \"tests/functional/configs/test_vars_file.py::TestEmptyVarsFileAllowsProjectVars::test_empty_vars_file_uses_project_vars\": 1.1186558190000113,\n    \"tests/functional/configs/test_vars_file.py::TestMacroVarCliOverridesFile::test_macro_var_cli_overrides_file\": 11.158734076999963,\n    \"tests/functional/configs/test_vars_file.py::TestMacroVarFromVarsFile::test_macro_var_from_file\": 1.1551887620000798,\n    \"tests/functional/configs/test_vars_file.py::TestMutualExclusivityError::test_error_when_both_have_vars\": 0.042660349999991354,\n    \"tests/functional/configs/test_vars_file.py::TestPartialCliOverride::test_partial_cli_override\": 12.100688074000004,\n    \"tests/functional/configs/test_vars_file.py::TestSqlModelVarCliOverridesFile::test_sql_model_cli_overrides_file\": 11.089052496000022,\n    \"tests/functional/configs/test_vars_file.py::TestSqlModelVarFromVarsFile::test_sql_model_var_from_file\": 11.16906512700018,\n    \"tests/functional/configs/test_vars_file.py::TestSqlModelVarMissingFromVarsFile::test_error_when_model_var_missing\": 10.899044949000086,\n    \"tests/functional/configs/test_vars_file.py::TestVarsFileWithoutVarsKeyAllowsProjectVars::test_vars_file_without_vars_key_uses_project_vars\": 11.765256581999893,\n    \"tests/functional/configs/test_versioned_model_constraint.py::TestPrimaryKeysModelAndColumnLevelConstraints::test_model_column_pk_error\": 25.474653758000045,\n    \"tests/functional/configs/test_versioned_model_constraint.py::TestPrimaryKeysMultipleColumns::test_pk_multiple_columns\": 25.615617595999993,\n    \"tests/functional/configs/test_versioned_model_constraint.py::TestVersionedModelConstraints::test_versioned_model_constraints\": 20.631093999999962,\n    \"tests/functional/configs/test_warn_error_options.py::TestEmptyWarnError::test_project_flags\": 14.867306955000004,\n    \"tests/functional/configs/test_warn_error_options.py::TestRequireAllWarningsHandledByWarnErrorBehaviorFlag::test_require_all_warnings_handed_by_warn_error_behavior_flag\": 22.369481161999943,\n    \"tests/functional/configs/test_warn_error_options.py::TestWarnErrorOptionsFromCLICanExcludeSpecificEvent::test_can_exclude_specific_event\": 26.423526234000065,\n    \"tests/functional/configs/test_warn_error_options.py::TestWarnErrorOptionsFromCLICanRaiseWarningToError::test_can_raise_warning_to_error\": 2.04963370400003,\n    \"tests/functional/configs/test_warn_error_options.py::TestWarnErrorOptionsFromCLICanSilence::test_can_silence\": 2.320834074999979,\n    \"tests/functional/configs/test_warn_error_options.py::TestWarnErrorOptionsFromCLICantSetBothIncludeAndError::test_cant_set_both_exclude_and_warn\": 0.06371149100016282,\n    \"tests/functional/configs/test_warn_error_options.py::TestWarnErrorOptionsFromCLICantSetBothIncludeAndError::test_cant_set_both_include_and_error\": 6.304755018999913,\n    \"tests/functional/configs/test_warn_error_options.py::TestWarnErrorOptionsFromProjectCanExcludeSpecificEvent::test_can_exclude_specific_event\": 0.0013343959999474464,\n    \"tests/functional/configs/test_warn_error_options.py::TestWarnErrorOptionsFromProjectCanRaiseWarningToError::test_can_raise_warning_to_error\": 29.41912545699995,\n    \"tests/functional/configs/test_warn_error_options.py::TestWarnErrorOptionsFromProjectCanSilence::test_can_silence\": 5.462176998999979,\n    \"tests/functional/configs/test_warn_error_options.py::TestWarnErrorOptionsFromProjectCantSetBothExcludeAndWarn::test_cant_set_both_exclude_and_warn\": 6.721651358999907,\n    \"tests/functional/configs/test_warn_error_options.py::TestWarnErrorOptionsFromProjectCantSetBothIncludeAndError::test_cant_set_both_include_and_error\": 6.674710779999941,\n    \"tests/functional/constraints/test_foreign_key_constraints.py::TestColumnLevelForeignKeyConstraintRefNotFoundError::test_model_level_fk_to_doesnt_exist\": 0.8127375680000029,\n    \"tests/functional/constraints/test_foreign_key_constraints.py::TestColumnLevelForeignKeyConstraintRefSyntaxError::test_model_level_fk_to\": 15.705302438000217,\n    \"tests/functional/constraints/test_foreign_key_constraints.py::TestColumnLevelForeignKeyConstraintToRef::test_column_level_fk_to\": 23.381145951000008,\n    \"tests/functional/constraints/test_foreign_key_constraints.py::TestColumnLevelForeignKeyConstraintToRefDeferRelation::test_column_level_fk_to_current_relation_when_target_selected\": 18.505497894999962,\n    \"tests/functional/constraints/test_foreign_key_constraints.py::TestColumnLevelForeignKeyConstraintToRefDeferRelation::test_column_level_fk_to_defer_relation_when_target_not_selected\": 26.358900947999928,\n    \"tests/functional/constraints/test_foreign_key_constraints.py::TestColumnLevelForeignKeyConstraintToSource::test_model_level_fk_to\": 23.852429037999855,\n    \"tests/functional/constraints/test_foreign_key_constraints.py::TestModelLevelForeignKeyConstraintRefNotFoundError::test_model_level_fk_to_doesnt_exist\": 15.055457412000123,\n    \"tests/functional/constraints/test_foreign_key_constraints.py::TestModelLevelForeignKeyConstraintRefSyntaxError::test_model_level_fk_to\": 0.9532859090000159,\n    \"tests/functional/constraints/test_foreign_key_constraints.py::TestModelLevelForeignKeyConstraintRefToDeferRelation::test_model_level_fk_to_current_relation_when_target_selected\": 17.989187679999986,\n    \"tests/functional/constraints/test_foreign_key_constraints.py::TestModelLevelForeignKeyConstraintRefToDeferRelation::test_model_level_fk_to_defer_relation_when_target_not_selected\": 25.373925477000284,\n    \"tests/functional/constraints/test_foreign_key_constraints.py::TestModelLevelForeignKeyConstraintToRef::test_model_level_fk_to\": 21.87024449499995,\n    \"tests/functional/constraints/test_foreign_key_constraints.py::TestModelLevelForeignKeyConstraintToSource::test_model_level_fk_to\": 22.921905586999856,\n    \"tests/functional/context_methods/test_builtin_functions.py::TestContextBuiltinExceptions::test_builtin_function_exception\": 0.9633488140000281,\n    \"tests/functional/context_methods/test_builtin_functions.py::TestContextBuiltins::test_builtin_dbt_metadata_envs_function\": 9.203543522000018,\n    \"tests/functional/context_methods/test_builtin_functions.py::TestContextBuiltins::test_builtin_invocation_args_dict_function\": 8.960963966000008,\n    \"tests/functional/context_methods/test_builtin_functions.py::TestContextBuiltins::test_builtin_set_function\": 16.667912322999882,\n    \"tests/functional/context_methods/test_builtin_functions.py::TestContextBuiltins::test_builtin_zip_function\": 8.52785550800013,\n    \"tests/functional/context_methods/test_cli_var_override.py::TestCLIVarOverride::test__override_vars_global\": 29.71246227300003,\n    \"tests/functional/context_methods/test_cli_var_override.py::TestCLIVarOverridePorject::test__override_vars_project_level\": 2.2715008490000628,\n    \"tests/functional/context_methods/test_cli_vars.py::TestCLIVars::test__cli_vars_longform\": 9.405296797999938,\n    \"tests/functional/context_methods/test_cli_vars.py::TestCLIVarsPackages::test_cli_vars_in_packages\": 2.8302657329999192,\n    \"tests/functional/context_methods/test_cli_vars.py::TestCLIVarsProfile::test_cli_vars_in_profile\": 2.5442399249999994,\n    \"tests/functional/context_methods/test_cli_vars.py::TestCLIVarsScrubbing::test__exception_scrubbing\": 4.512491621000095,\n    \"tests/functional/context_methods/test_cli_vars.py::TestCLIVarsScrubbing::test__run_results_scrubbing\": 3.30067886300003,\n    \"tests/functional/context_methods/test_cli_vars.py::TestCLIVarsSelectors::test_vars_in_selectors\": 5.273423541999932,\n    \"tests/functional/context_methods/test_cli_vars.py::TestCLIVarsSimple::test__cli_vars_longer\": 2.859908650999955,\n    \"tests/functional/context_methods/test_cli_vars.py::TestCLIVarsSimple::test__cli_vars_shorthand\": 3.2119398159999832,\n    \"tests/functional/context_methods/test_custom_env_vars.py::TestCustomVarInLogs::test_extra_filled\": 1.0755296460000068,\n    \"tests/functional/context_methods/test_env_vars.py::TestEnvVarInCreateSchema::test_env_var_in_create_schema\": 4.919623683000054,\n    \"tests/functional/context_methods/test_env_vars.py::TestEnvVars::test_env_vars_dev\": 3.473758255000007,\n    \"tests/functional/context_methods/test_env_vars.py::TestEnvVars::test_env_vars_prod\": 2.898812863000103,\n    \"tests/functional/context_methods/test_env_vars.py::TestEnvVars::test_env_vars_secrets\": 1.8596417929999802,\n    \"tests/functional/context_methods/test_secret_env_vars.py::TestAllowSecretProfilePackage::test_allow_secrets\": 7.10889669900007,\n    \"tests/functional/context_methods/test_secret_env_vars.py::TestCloneFailSecretNotRendered::test_fail_clone_with_scrubbing\": 1.6307092519999742,\n    \"tests/functional/context_methods/test_secret_env_vars.py::TestCloneFailSecretScrubbed::test_fail_clone_with_scrubbing\": 1.6996358119999968,\n    \"tests/functional/context_methods/test_secret_env_vars.py::TestDisallowSecretModel::test_disallow_secret\": 5.3389670970000225,\n    \"tests/functional/context_methods/test_var_dependency.py::TestVarConfigDependencyInheritance::test_root_var_overrides_package_var\": 7.180892410999945,\n    \"tests/functional/context_methods/test_var_dependency.py::TestVarDependencyInheritance::test_var_mutual_overrides_v1_conversion\": 7.733033945000045,\n    \"tests/functional/context_methods/test_var_in_generate_name.py::TestMissingVarGenerateNameMacro::test_generate_schema_name_var\": 1.8204441520000216,\n    \"tests/functional/context_methods/test_yaml_functions.py::TestContextVars::test_json_data_tests\": 5.388633751999976,\n    \"tests/functional/contracts/test_contract_enforcement.py::TestIncrementalModelContractEnforcement::test_contracted_incremental\": 8.658500275000051,\n    \"tests/functional/contracts/test_contract_precision.py::TestModelContractNumericNoPrecision::test_contracted_numeric_without_precision\": 8.570239167999944,\n    \"tests/functional/contracts/test_contract_precision.py::TestModelContractNumericPrecision::test_contracted_numeric_with_precision\": 5.931563314999892,\n    \"tests/functional/contracts/test_nonstandard_data_type.py::TestModelContractUnrecognizedTypeCode1::test_nonstandard_data_type\": 6.4560003670000015,\n    \"tests/functional/contracts/test_nonstandard_data_type.py::TestModelContractUnrecognizedTypeCodeActualMismatch::test_nonstandard_data_type\": 6.328724072,\n    \"tests/functional/contracts/test_nonstandard_data_type.py::TestModelContractUnrecognizedTypeCodeExpectedMismatch::test_nonstandard_data_type\": 6.503988707000019,\n    \"tests/functional/custom_aliases/test_custom_aliases.py::TestAliases::test_customer_alias_name\": 9.997058941000091,\n    \"tests/functional/custom_aliases/test_custom_aliases.py::TestAliasesWithConfig::test_customer_alias_name\": 10.64142559000004,\n    \"tests/functional/custom_schemas/test_custom_schemas.py::TestCustomSchema::test_custom_schema\": 6.828831211000079,\n    \"tests/functional/custom_schemas/test_custom_schemas.py::TestCustomSchemaNullReturn::test_custom_schema_null_return\": 6.558580455000026,\n    \"tests/functional/custom_schemas/test_custom_schemas.py::TestCustomSchemaNullReturnDefault::test_custom_schema_null_return_legacy\": 7.017101982999975,\n    \"tests/functional/custom_schemas/test_custom_schemas.py::TestCustomSchemaNullReturnLegacy::test_custom_schema_null_return_legacy\": 6.840425341000014,\n    \"tests/functional/custom_singular_tests/test_custom_singular_tests.py::TestFailingTests::test_data_tests\": 12.523478044,\n    \"tests/functional/custom_singular_tests/test_custom_singular_tests.py::TestPassingTests::test_data_tests\": 1.9780239450001318,\n    \"tests/functional/custom_target_path/test_custom_target_path.py::TestTargetPathCliArg::test_target_path\": 0.9024194590000008,\n    \"tests/functional/custom_target_path/test_custom_target_path.py::TestTargetPathConfig::test_target_path\": 7.930154767000033,\n    \"tests/functional/custom_target_path/test_custom_target_path.py::TestTargetPathEnvVar::test_target_path\": 0.700890194999829,\n    \"tests/functional/cycles/test_cycles.py::TestComplexCycle::test_complex_cycle\": 8.540429685999925,\n    \"tests/functional/cycles/test_cycles.py::TestSimpleCycle::test_simple_cycle\": 0.7245702900000879,\n    \"tests/functional/data_test_patch/test_singular_test_patch.py::TestPatchSingularTest::test_compile\": 13.815726229000006,\n    \"tests/functional/data_test_patch/test_singular_test_patch.py::TestPatchSingularTestInvalidName::test_compile\": 9.17537908700001,\n    \"tests/functional/data_test_patch/test_singular_test_patch.py::TestPatchSingularTestMalformedYaml::test_compile\": 9.368079006000016,\n    \"tests/functional/data_tests/test_hooks.py::TestSingularTestPostHook::test_data_test_runs_adapter_post_hook_fails\": 16.043785289000084,\n    \"tests/functional/data_tests/test_hooks.py::TestSingularTestPostHook::test_data_test_runs_adapter_post_hook_pass\": 21.66079876899994,\n    \"tests/functional/data_tests/test_hooks.py::TestSingularTestPreHook::test_data_test_runs_adapter_pre_hook_fails\": 15.145069180000064,\n    \"tests/functional/data_tests/test_hooks.py::TestSingularTestPreHook::test_data_test_runs_adapter_pre_hook_pass\": 2.5179512160000286,\n    \"tests/functional/dbt_runner/test_dbt_runner.py::TestDbtRunner::test_callback_node_finished_exceptions_are_raised\": 11.009342442000161,\n    \"tests/functional/dbt_runner/test_dbt_runner.py::TestDbtRunner::test_callbacks\": 0.22554276500000014,\n    \"tests/functional/dbt_runner/test_dbt_runner.py::TestDbtRunner::test_command_invalid_option\": 0.004681253999990531,\n    \"tests/functional/dbt_runner/test_dbt_runner.py::TestDbtRunner::test_command_mutually_exclusive_option\": 0.03389066999989154,\n    \"tests/functional/dbt_runner/test_dbt_runner.py::TestDbtRunner::test_directory_does_not_change\": 0.10949237999989236,\n    \"tests/functional/dbt_runner/test_dbt_runner.py::TestDbtRunner::test_group_invalid_option\": 0.006220846000132951,\n    \"tests/functional/dbt_runner/test_dbt_runner.py::TestDbtRunner::test_invalid_command\": 0.003023223000042208,\n    \"tests/functional/dbt_runner/test_dbt_runner.py::TestDbtRunner::test_invoke_kwargs\": 5.595669710999914,\n    \"tests/functional/dbt_runner/test_dbt_runner.py::TestDbtRunner::test_invoke_kwargs_and_flags\": 5.953768584000045,\n    \"tests/functional/dbt_runner/test_dbt_runner.py::TestDbtRunner::test_invoke_kwargs_profiles_dir\": 0.030260843000064597,\n    \"tests/functional/dbt_runner/test_dbt_runner.py::TestDbtRunner::test_invoke_kwargs_project_dir\": 0.37493148299998325,\n    \"tests/functional/dbt_runner/test_dbt_runner.py::TestDbtRunner::test_invoke_version\": 0.16937982699994336,\n    \"tests/functional/dbt_runner/test_dbt_runner.py::TestDbtRunner::test_pass_in_args_variable\": 0.0048483960000567095,\n    \"tests/functional/dbt_runner/test_dbt_runner.py::TestDbtRunner::test_pass_in_manifest\": 10.461992227999872,\n    \"tests/functional/dbt_runner/test_dbt_runner.py::TestDbtRunnerHooks::test_node_info_non_persistence\": 12.267079878000004,\n    \"tests/functional/dbt_runner/test_dbt_runner.py::TestDbtRunnerQueryComments::test_query_comment_saved_manifest\": 22.213837043000012,\n    \"tests/functional/defer_state/test_defer_state.py::TestDeferStateDeletedUpstream::test_run_defer_deleted_upstream\": 61.85776184000008,\n    \"tests/functional/defer_state/test_defer_state.py::TestDeferStateFlag::test_defer_state_flag\": 63.689854235999974,\n    \"tests/functional/defer_state/test_defer_state.py::TestDeferStateUnsupportedCommands::test_no_state\": 12.90576068900009,\n    \"tests/functional/defer_state/test_defer_state.py::TestFunctionDeferral::test_build_with_other_schema_defer\": 3.782861483000005,\n    \"tests/functional/defer_state/test_defer_state.py::TestRunCompileState::test_run_and_compile_defer\": 33.11859059099993,\n    \"tests/functional/defer_state/test_defer_state.py::TestRunDeferState::test_run_and_defer\": 8.286702338999817,\n    \"tests/functional/defer_state/test_defer_state.py::TestRunDeferStateChangedModel::test_run_defer_state_changed_model\": 49.603901488999895,\n    \"tests/functional/defer_state/test_defer_state.py::TestRunDeferStateIFFNotExists::test_run_defer_iff_not_exists\": 59.872256053000115,\n    \"tests/functional/defer_state/test_defer_state.py::TestSnapshotState::test_snapshot_state_defer\": 44.659071827999924,\n    \"tests/functional/defer_state/test_group_updates.py::TestBadGroups::test_changed_groups\": 34.54032022500019,\n    \"tests/functional/defer_state/test_group_updates.py::TestFullyModifiedGroups::test_changed_groups\": 34.23673371799964,\n    \"tests/functional/defer_state/test_group_updates.py::TestPartiallyModifiedGroups::test_changed_groups\": 33.77331539499983,\n    \"tests/functional/defer_state/test_modified_state.py::TestChangedConstraintUnversioned::test_changed_constraint\": 80.60591570499992,\n    \"tests/functional/defer_state/test_modified_state.py::TestChangedContractUnversioned::test_changed_contract\": 115.96679771699996,\n    \"tests/functional/defer_state/test_modified_state.py::TestChangedContractVersioned::test_changed_contract_versioned\": 8.95739512700004,\n    \"tests/functional/defer_state/test_modified_state.py::TestChangedExposure::test_changed_exposure\": 55.413003436000054,\n    \"tests/functional/defer_state/test_modified_state.py::TestChangedMacroContents::test_changed_macro_contents\": 55.10674272599999,\n    \"tests/functional/defer_state/test_modified_state.py::TestChangedMaterializationConstraint::test_changed_materialization\": 93.97664151799995,\n    \"tests/functional/defer_state/test_modified_state.py::TestChangedModelContents::test_changed_model_contents\": 65.11376417299994,\n    \"tests/functional/defer_state/test_modified_state.py::TestChangedSeedConfig::test_changed_seed_config\": 91.34282982499985,\n    \"tests/functional/defer_state/test_modified_state.py::TestChangedSeedContents::test_changed_seed_contents_state\": 185.61396948100014,\n    \"tests/functional/defer_state/test_modified_state.py::TestChangedSemanticModelContents::test_changed_semantic_model_contents\": 51.03010479099976,\n    \"tests/functional/defer_state/test_modified_state.py::TestDeleteUnversionedContractedModel::test_delete_unversioned_contracted_model\": 60.54360014599979,\n    \"tests/functional/defer_state/test_modified_state.py::TestDeleteVersionedContractedModel::test_delete_versioned_contracted_model\": 60.64387756100041,\n    \"tests/functional/defer_state/test_modified_state.py::TestDisableUnversionedContractedModel::test_disable_unversioned_contracted_model\": 28.281863183999917,\n    \"tests/functional/defer_state/test_modified_state.py::TestDisableUnversionedUncontractedModel::test_delete_versioned_contracted_model\": 29.64516934300002,\n    \"tests/functional/defer_state/test_modified_state.py::TestDisableVersionedContractedModel::test_disable_versioned_contracted_model\": 29.084239192999917,\n    \"tests/functional/defer_state/test_modified_state.py::TestDisableVersionedUncontractedModel::test_delete_versioned_contracted_model\": 4.162558392000022,\n    \"tests/functional/defer_state/test_modified_state.py::TestModifiedAccess::test_changed_access\": 54.52696797900012,\n    \"tests/functional/defer_state/test_modified_state.py::TestModifiedBodyAndContract::test_modified_body_and_contract\": 52.127014975000066,\n    \"tests/functional/defer_state/test_modified_state.py::TestModifiedDeprecationDate::test_changed_access\": 56.557062286000246,\n    \"tests/functional/defer_state/test_modified_state.py::TestModifiedLatestVersion::test_changed_access\": 41.55704616800017,\n    \"tests/functional/defer_state/test_modified_state.py::TestModifiedVersion::test_changed_access\": 40.10616760700009,\n    \"tests/functional/defer_state/test_modified_state.py::TestNewMacro::test_new_macro\": 63.77843377400018,\n    \"tests/functional/defer_state/test_modified_state.py::TestUnrenderedConfigSame::test_unrendered_config_same\": 5.892506080000089,\n    \"tests/functional/defer_state/test_modified_state.py::TestUnversionedContractVarcharSizeChange::test_varchar_size_increase_not_breaking_unversioned\": 43.36008621099995,\n    \"tests/functional/defer_state/test_modified_state.py::TestVersionedContractVarcharSizeChange::test_numeric_precision_increase_not_breaking\": 33.203787809999994,\n    \"tests/functional/defer_state/test_modified_state.py::TestVersionedContractVarcharSizeChange::test_varchar_case_sensitivity_not_breaking\": 31.644214640999962,\n    \"tests/functional/defer_state/test_modified_state.py::TestVersionedContractVarcharSizeChange::test_varchar_size_increase_not_breaking\": 42.405480871000236,\n    \"tests/functional/defer_state/test_modified_state_environment_vars.py::TestModelNodeWithEnvVarConfigInProjectYml::test_change_env_var\": 43.25435520199994,\n    \"tests/functional/defer_state/test_modified_state_environment_vars.py::TestModelNodeWithEnvVarConfigInProjectYmlAndSchemaYml::test_change_env_var\": 3.3312798589999915,\n    \"tests/functional/defer_state/test_modified_state_environment_vars.py::TestModelNodeWithEnvVarConfigInSchemaYml::test_change_env_var\": 43.20262111700026,\n    \"tests/functional/defer_state/test_modified_state_environment_vars.py::TestModelNodeWithEnvVarConfigInSqlAndSchemaYml::test_change_env_var\": 44.2378646950001,\n    \"tests/functional/defer_state/test_modified_state_environment_vars.py::TestModelNodeWithEnvVarConfigInSqlFile::test_change_env_var\": 42.95366186099977,\n    \"tests/functional/defer_state/test_modified_state_jinja.py::TestModelNodeWithEnvVarConfigInSchemaYml::test_change_jinja_if\": 46.20371971999998,\n    \"tests/functional/defer_state/test_modified_state_jinja.py::TestModelNodeWithJinjaConfigInProjectYml::test_change_jinja_if\": 46.04059499899995,\n    \"tests/functional/defer_state/test_modified_state_jinja.py::TestModelNodeWithJinjaConfigInProjectYmlAndSchemaYml::test_change_jinja_if\": 48.406280199999856,\n    \"tests/functional/defer_state/test_modified_state_jinja.py::TestModelNodeWithJinjaConfigInSqlAndSchemaYml::test_change_jinja_if\": 48.053867512000124,\n    \"tests/functional/defer_state/test_modified_state_jinja.py::TestModelNodeWithJinjaConfigInSqlFile::test_change_jinja_if\": 44.85347691200013,\n    \"tests/functional/defer_state/test_modified_state_schema_evolution.py::TestModifiedStateSchemaEvolution::test_modified_state_schema_evolution\": 26.930958640000426,\n    \"tests/functional/defer_state/test_modified_state_sources_unrendered.py::TestSourceNodeWithEnvVarConfigInDatabase::test_change_env_var\": 48.514698134999435,\n    \"tests/functional/defer_state/test_modified_state_sources_unrendered.py::TestSourceNodeWithEnvVarConfigInSchema::test_change_env_var\": 61.18177458199989,\n    \"tests/functional/defer_state/test_modified_state_sources_unrendered.py::TestSourceNodeWithJinjaInDatabase::test_change_jinja_if\": 49.90231877100041,\n    \"tests/functional/defer_state/test_modified_state_sources_unrendered.py::TestSourceNodeWithJinjaInSchema::test_change_jinja_if\": 3.6301306659999,\n    \"tests/functional/defer_state/test_modified_state_vars.py::TestStateSelectionVarConfig::test_change_var\": 52.277848013000494,\n    \"tests/functional/defer_state/test_modified_state_vars.py::TestStateSelectionVarConfigLegacy::test_change_var\": 51.33541602200012,\n    \"tests/functional/defer_state/test_removed_test_state.py::TestRemovedGenericTest::test_removed_generic_test_with_state_modified\": 39.73983506500008,\n    \"tests/functional/defer_state/test_removed_test_state.py::TestRemovedGenericTestStateModifiedGracefulError::test_list_with_state_modified_after_test_removal\": 39.7702012460004,\n    \"tests/functional/defer_state/test_run_results_state.py::TestBuildRunResultsState::test_build_run_results_state\": 258.3166066490003,\n    \"tests/functional/defer_state/test_run_results_state.py::TestConcurrentSelectionBuildRunResultsState::test_concurrent_selectors_build_run_results_state\": 113.7115534909999,\n    \"tests/functional/defer_state/test_run_results_state.py::TestConcurrentSelectionRunResultsState::test_concurrent_selection_run_run_results_state\": 78.34525452200023,\n    \"tests/functional/defer_state/test_run_results_state.py::TestConcurrentSelectionTestRunResultsState::test_concurrent_selection_test_run_results_state\": 63.871015166000234,\n    \"tests/functional/defer_state/test_run_results_state.py::TestRunRunResultsState::test_run_run_results_state\": 15.572167158999946,\n    \"tests/functional/defer_state/test_run_results_state.py::TestSeedRunResultsState::test_seed_run_results_state\": 135.52150492200008,\n    \"tests/functional/defer_state/test_run_results_state.py::TestTestRunResultsState::test_test_run_results_state\": 157.52328988399995,\n    \"tests/functional/defer_state/test_unrendered_config.py::TestGenericTestUnrenderedConfig::test_unrendered_config\": 32.03120717100046,\n    \"tests/functional/dependencies/test_add_package_edge_cases.py::TestAddPackageWithWarnUnpinnedInYaml::test_add_package_with_warn_unpinned_in_yaml\": 3.0999666530000525,\n    \"tests/functional/dependencies/test_dependency_inverted_ref.py::TestInvertedRefDependency::test_inverted_ref_dependency\": 32.85723158400015,\n    \"tests/functional/dependencies/test_dependency_inverted_ref.py::TestInvertedRefDependencyLegacy::test_inverted_ref_dependency\": 1.0653438009999832,\n    \"tests/functional/dependencies/test_dependency_options.py::TestDepsOptions::test_deps_add\": 1.596422259999997,\n    \"tests/functional/dependencies/test_dependency_options.py::TestDepsOptions::test_deps_add_without_install\": 0.30580801100040844,\n    \"tests/functional/dependencies/test_dependency_options.py::TestDepsOptions::test_deps_default\": 0.5980374340001617,\n    \"tests/functional/dependencies/test_dependency_options.py::TestDepsOptions::test_deps_lock\": 16.19210886199926,\n    \"tests/functional/dependencies/test_dependency_options.py::TestDepsOptions::test_deps_upgrade\": 0.8616846250000094,\n    \"tests/functional/dependencies/test_dependency_secrets.py::TestSecretInPackage::test_mask_secrets\": 16.269470662000003,\n    \"tests/functional/dependencies/test_local_dependency.py::TestDependencyTestsConfig::test_dependency_tests_config\": 36.580165950000264,\n    \"tests/functional/dependencies/test_local_dependency.py::TestMissingDependency::test_missing_dependency\": 35.868315869999606,\n    \"tests/functional/dependencies/test_local_dependency.py::TestSimpleDependency::test_local_dependency\": 52.54044688499971,\n    \"tests/functional/dependencies/test_local_dependency.py::TestSimpleDependency::test_no_dependency_paths\": 53.56587850400001,\n    \"tests/functional/dependencies/test_local_dependency.py::TestSimpleDependencyDuplicateName::test_local_dependency_same_name\": 0.29325907099999426,\n    \"tests/functional/dependencies/test_local_dependency.py::TestSimpleDependencyDuplicateName::test_local_dependency_same_name_sneaky\": 17.811623147999853,\n    \"tests/functional/dependencies/test_local_dependency.py::TestSimpleDependencyHooks::test_hook_dependency\": 35.63815417500018,\n    \"tests/functional/dependencies/test_local_dependency.py::TestSimpleDependencyNoVersionCheckConfig::test_local_dependency_out_of_date_no_check\": 3.0720469819999607,\n    \"tests/functional/dependencies/test_local_dependency.py::TestSimpleDependencyRelativePath::test_local_dependency_relative_path\": 17.346668812000644,\n    \"tests/functional/dependencies/test_local_dependency.py::TestSimpleDependencyWithSchema::test_local_dependency_out_of_date\": 55.8938258029998,\n    \"tests/functional/dependencies/test_local_dependency.py::TestSimpleDependencyWithSchema::test_local_dependency_out_of_date_no_check\": 36.57688531800022,\n    \"tests/functional/dependencies/test_simple_dependency.py::TestBadTarballDependency::test_malformed_tarball_package_causes_exception\": 8.129406027999948,\n    \"tests/functional/dependencies/test_simple_dependency.py::TestEmptyDependency::test_empty_package\": 8.437200644000086,\n    \"tests/functional/dependencies/test_simple_dependency.py::TestRekeyedDependencyWithSubduplicates::test_simple_dependency_deps\": 3.5478885310000123,\n    \"tests/functional/dependencies/test_simple_dependency.py::TestSimpleDependcyTarball::test_deps_simple_tarball_doesnt_error_out\": 9.077035645000024,\n    \"tests/functional/dependencies/test_simple_dependency.py::TestSimpleDependency::test_simple_dependency\": 59.325854435999645,\n    \"tests/functional/dependencies/test_simple_dependency.py::TestSimpleDependencyBadProfile::test_deps_bad_profile\": 7.960859184000128,\n    \"tests/functional/dependencies/test_simple_dependency.py::TestSimpleDependencyBranch::test_simple_dependency\": 28.913091971000085,\n    \"tests/functional/dependencies/test_simple_dependency.py::TestSimpleDependencyBranchWithEmpty::test_empty_models_not_compiled_in_dependencies\": 3.136219147999995,\n    \"tests/functional/dependencies/test_simple_dependency.py::TestSimpleDependencyNoProfile::test_simple_dependency_no_profile\": 19.026055459999952,\n    \"tests/functional/dependencies/test_simple_dependency.py::TestSimpleDependencyUnpinned::test_simple_dependency\": 20.250789844999417,\n    \"tests/functional/dependencies/test_simple_dependency.py::TestSimpleDependencyWithDependenciesFile::test_dependency_with_dependencies_file\": 40.090405611998904,\n    \"tests/functional/dependencies/test_simple_dependency.py::TestSimpleDependencyWithDuplicates::test_simple_dependency_deps\": 19.765875034999226,\n    \"tests/functional/dependencies/test_simple_dependency.py::TestSimpleDependencyWithEmptyPackagesFile::test_dependency_with_empty_packages_file\": 18.5043594760009,\n    \"tests/functional/dependencies/test_simple_dependency.py::TestSimpleDependencyWithModels::test_simple_dependency_with_models\": 39.69027267199999,\n    \"tests/functional/dependencies/test_simple_dependency.py::TestSimpleDependencyWithSubdirs::test_git_with_multiple_subdir\": 4.301544702999962,\n    \"tests/functional/dependencies/test_simple_dependency.py::TestTarballNestedDependencies::test_simple_dependency_deps\": 9.450593745999868,\n    \"tests/functional/dependencies/test_simple_dependency_with_configs.py::TestSimpleDependencyWithConfigs::test_simple_dependency\": 19.92994181600011,\n    \"tests/functional/dependencies/test_simple_dependency_with_configs.py::TestSimpleDependencyWithOverriddenConfigs::test_simple_dependency\": 20.10618874900001,\n    \"tests/functional/dependencies/test_uninstalled_package_found_error.py::TestNoErrorIfPackageYamlDoesNotExist::test_no_error_raised_if_package_yml_does_not_exist\": 18.524951326000064,\n    \"tests/functional/dependencies/test_uninstalled_package_found_error.py::TestUninstalledPackageWithNestedDependency::test_uninstalled_package_with_nested_dependency\": 18.525517385000057,\n    \"tests/functional/dependencies/test_uninstalled_package_found_error.py::TestUninstalledPackagesErrorRaisedIfPackageLockDoesNotExist::test_error_raised_if_package_lock_does_not_exist\": 18.072258011000258,\n    \"tests/functional/deprecations/test_config_deprecations.py::TestBothProjectTestDeprecation::test_tests_config\": 0.32122242499994513,\n    \"tests/functional/deprecations/test_config_deprecations.py::TestBothSchemaTestDeprecation::test_schema\": 20.38593206399969,\n    \"tests/functional/deprecations/test_config_deprecations.py::TestSchemaTestDeprecation::test_generic_data_test_parsing\": 9.823229470000115,\n    \"tests/functional/deprecations/test_config_deprecations.py::TestSchemaTestDeprecation::test_generic_tests_config\": 19.400463967999713,\n    \"tests/functional/deprecations/test_config_deprecations.py::TestSchemaTestDeprecation::test_generic_tests_fail\": 1.1713902639999105,\n    \"tests/functional/deprecations/test_config_deprecations.py::TestSourceSchemaTestDeprecation::test_generic_data_tests\": 21.072828041000093,\n    \"tests/functional/deprecations/test_config_deprecations.py::TestSourceSchemaTestDeprecation::test_source_tests_config\": 20.13436093900009,\n    \"tests/functional/deprecations/test_config_deprecations.py::TestTestConfigInDependency::test_test_dep\": 2.966434448999962,\n    \"tests/functional/deprecations/test_config_deprecations.py::TestTestsConfigDeprecation::test_project_tests_config\": 5.444153101000097,\n    \"tests/functional/deprecations/test_config_deprecations.py::TestTestsConfigDeprecation::test_project_tests_config_fail\": 9.782367615000112,\n    \"tests/functional/deprecations/test_config_deprecations.py::TestValidateModelConfigOnlyCalledOncePerModel::test_validate_model_config_only_called_once_per_model\": 20.86074519900035,\n    \"tests/functional/deprecations/test_deprecations.py::TestArgumentsPropertyInGenericTestDeprecationBehaviorChangeDefault::test_arguments_property_in_generic_test_deprecation\": 1.1635303539999882,\n    \"tests/functional/deprecations/test_deprecations.py::TestArgumentsPropertyInGenericTestDeprecationFalse::test_arguments_property_in_generic_test_deprecation\": 1.235795113999984,\n    \"tests/functional/deprecations/test_deprecations.py::TestArgumentsPropertyInGenericTestDeprecationTrue::test_arguments_property_in_generic_test_deprecation\": 21.688444249000213,\n    \"tests/functional/deprecations/test_deprecations.py::TestBaseProjectHasNoDeprecations::test_base_project_has_no_deprecations\": 22.609471571000086,\n    \"tests/functional/deprecations/test_deprecations.py::TestConfigPathDeprecation::test_data_path\": 19.1752317280002,\n    \"tests/functional/deprecations/test_deprecations.py::TestConfigPathDeprecation::test_data_path_fail\": 0.055538300999614876,\n    \"tests/functional/deprecations/test_deprecations.py::TestCustomConfigInDbtProjectYmlNoDeprecation::test_missing_plus_prefix_deprecation_sub_path\": 20.275871224999946,\n    \"tests/functional/deprecations/test_deprecations.py::TestCustomKeyInConfigComplexSQLDeprecation::test_custom_key_in_config_sql_deprecation\": 21.364621893999583,\n    \"tests/functional/deprecations/test_deprecations.py::TestCustomKeyInConfigComplexSQLDeprecation::test_custom_key_in_config_sql_deprecation_adapter_specific_config_key_aliases\": 11.324098366999806,\n    \"tests/functional/deprecations/test_deprecations.py::TestCustomKeyInConfigDeprecation::test_custom_key_in_config_deprecation\": 21.478977203000113,\n    \"tests/functional/deprecations/test_deprecations.py::TestCustomKeyInConfigSQLDeprecation::test_custom_key_in_config_sql_deprecation\": 21.542894689000377,\n    \"tests/functional/deprecations/test_deprecations.py::TestCustomKeyInConfigSQLDeprecation::test_custom_key_in_config_sql_deprecation_adapter_specific_config_key_aliases\": 11.379860011000346,\n    \"tests/functional/deprecations/test_deprecations.py::TestCustomKeyInObjectDeprecation::test_custom_key_in_object_deprecation\": 22.23738819099981,\n    \"tests/functional/deprecations/test_deprecations.py::TestCustomOutputPathInSourceFreshnessDeprecation::test_jsonschema_validation_deprecations_arent_run_without_env_var\": 22.433747362000076,\n    \"tests/functional/deprecations/test_deprecations.py::TestDeprecatedInvalidDeprecationDate::test_deprecated_invalid_deprecation_date\": 20.658429606000254,\n    \"tests/functional/deprecations/test_deprecations.py::TestDeprecatedModelExposure::test_exposure_with_deprecated_model\": 1.090100322999973,\n    \"tests/functional/deprecations/test_deprecations.py::TestDeprecationSummary::test_package_redirect\": 10.843696051999814,\n    \"tests/functional/deprecations/test_deprecations.py::TestDuplicateYAMLKeysInSchemaFiles::test_duplicate_yaml_keys_in_schema_files\": 21.06595220400027,\n    \"tests/functional/deprecations/test_deprecations.py::TestEnvironmentVariableNamespaceDeprecation::test_environment_variable_namespace_deprecation\": 20.24838188400031,\n    \"tests/functional/deprecations/test_deprecations.py::TestExposureNameDeprecation::test_exposure_name\": 21.18804540600013,\n    \"tests/functional/deprecations/test_deprecations.py::TestExposureNameDeprecation::test_exposure_name_fail\": 10.275663852999969,\n    \"tests/functional/deprecations/test_deprecations.py::TestGenerateSchemaNameNullValueDeprecation::test_generate_schema_name_null_value_deprecation\": 21.084296618999815,\n    \"tests/functional/deprecations/test_deprecations.py::TestHappyPathProjectHasNoDeprecations::test_happy_path_project_has_no_deprecations\": 3.7107665290000114,\n    \"tests/functional/deprecations/test_deprecations.py::TestJsonSchemaValidationGating::test_jsonschema_validation_gating[False-False-00]\": 10.823479230999965,\n    \"tests/functional/deprecations/test_deprecations.py::TestJsonSchemaValidationGating::test_jsonschema_validation_gating[False-False-01]\": 10.384692801000028,\n    \"tests/functional/deprecations/test_deprecations.py::TestJsonSchemaValidationGating::test_jsonschema_validation_gating[False-True-0]\": 10.804687088000037,\n    \"tests/functional/deprecations/test_deprecations.py::TestJsonSchemaValidationGating::test_jsonschema_validation_gating[True-True-1]\": 20.346035234000055,\n    \"tests/functional/deprecations/test_deprecations.py::TestJsonschemaValidationDeprecationsArentRunWithoutEnvVar::test_jsonschema_validation_deprecations_arent_run_without_env_var\": 22.357440401000076,\n    \"tests/functional/deprecations/test_deprecations.py::TestMParamUsageDeprecation::test_m_usage\": 19.7771351209999,\n    \"tests/functional/deprecations/test_deprecations.py::TestMParamUsageRunnerDeprecation::test_m_usage\": 20.082165067999767,\n    \"tests/functional/deprecations/test_deprecations.py::TestMissingArgumentsPropertyInGenericTestDeprecation::test_missing_arguments_property_in_generic_test_deprecation\": 22.313889760999928,\n    \"tests/functional/deprecations/test_deprecations.py::TestModelParamUsageDeprecation::test_model_usage\": 24.280937054000333,\n    \"tests/functional/deprecations/test_deprecations.py::TestModelParamUsageRunnerDeprecation::test_model_usage\": 23.685321349000333,\n    \"tests/functional/deprecations/test_deprecations.py::TestModelsParamUsageDeprecation::test_models_usage\": 23.59989595800016,\n    \"tests/functional/deprecations/test_deprecations.py::TestModelsParamUsageRunnerDeprecation::test_models_usage\": 23.992864603999806,\n    \"tests/functional/deprecations/test_deprecations.py::TestModulesItertoolsDeprecation::test_models_itertools\": 23.83317090100013,\n    \"tests/functional/deprecations/test_deprecations.py::TestMultipleCustomKeysInConfigDeprecation::test_multiple_custom_keys_in_config_deprecation\": 22.03165513900035,\n    \"tests/functional/deprecations/test_deprecations.py::TestNoModulesItertoolsDeprecation::test_models_itertools\": 24.04908481500047,\n    \"tests/functional/deprecations/test_deprecations.py::TestPackageInstallPathDeprecation::test_package_path\": 9.98883508899985,\n    \"tests/functional/deprecations/test_deprecations.py::TestPackageInstallPathDeprecation::test_package_path_not_set\": 0.04274555200004215,\n    \"tests/functional/deprecations/test_deprecations.py::TestPackageRedirectDeprecation::test_package_redirect\": 10.226628003000087,\n    \"tests/functional/deprecations/test_deprecations.py::TestPackageRedirectDeprecation::test_package_redirect_fail\": 0.6062213699999859,\n    \"tests/functional/deprecations/test_deprecations.py::TestPrePostHookNoFalsePositiveDeprecation::test_pre_post_hook_no_false_positive_deprecation\": 21.38337906300012,\n    \"tests/functional/deprecations/test_deprecations.py::TestProjectFlagsMovedDeprecation::test_profile_config_deprecation\": 22.26252905499996,\n    \"tests/functional/deprecations/test_deprecations.py::TestProjectFlagsMovedDeprecationQuiet::test_profile_config_deprecation\": 21.599223906999896,\n    \"tests/functional/deprecations/test_deprecations.py::TestProjectFlagsMovedDeprecationWarnErrorOptions::test_profile_config_deprecation\": 1.1091793080000798,\n    \"tests/functional/deprecations/test_deprecations.py::TestPropertyMovedToConfigDeprecation::test_property_moved_to_config_deprecation\": 1.6897038079999902,\n    \"tests/functional/deprecations/test_deprecations.py::TestPythonModelConfigAdditionsDontRaiseDeprecations::test_python_model_config_additions_dont_raise_deprecations\": 21.242180384999983,\n    \"tests/functional/deprecations/test_deprecations.py::TestSelectParamNoModelUsageDeprecation::test_select_usage\": 20.4514029139998,\n    \"tests/functional/deprecations/test_deprecations.py::TestSelectParamNoModelUsageRunnerDeprecation::test_select_usage\": 20.375715364999678,\n    \"tests/functional/deprecations/test_deprecations.py::TestShowAllDeprecationsFlag::test_package_redirect\": 1.4262878629999989,\n    \"tests/functional/deprecations/test_deprecations.py::TestWEOIncludeExcludeDeprecation::test_weo_include_exclude_deprecation[error-exclude-1]\": 1.2320054940000205,\n    \"tests/functional/deprecations/test_deprecations.py::TestWEOIncludeExcludeDeprecation::test_weo_include_exclude_deprecation[error-warn-0]\": 11.690115804000243,\n    \"tests/functional/deprecations/test_deprecations.py::TestWEOIncludeExcludeDeprecation::test_weo_include_exclude_deprecation[include-exclude-1]\": 22.840482014999907,\n    \"tests/functional/deprecations/test_deprecations.py::TestWEOIncludeExcludeDeprecation::test_weo_include_exclude_deprecation[include-warn-1]\": 11.459487368000055,\n    \"tests/functional/deprecations/test_missing_plus_in_config_deprecations.py::TestEmptyConfig::test_no_warning\": 21.21550332700008,\n    \"tests/functional/deprecations/test_missing_plus_in_config_deprecations.py::TestEmptyNestedDir::test_no_warning\": 0.8941187810000315,\n    \"tests/functional/deprecations/test_missing_plus_in_config_deprecations.py::TestMissingPlusPrefixDeprecation::test_missing_plus_prefix_deprecation\": 1.0505578570000011,\n    \"tests/functional/deprecations/test_missing_plus_in_config_deprecations.py::TestMissingPlusPrefixDeprecationSubPath::test_missing_plus_prefix_deprecation_sub_path\": 22.438120303999995,\n    \"tests/functional/deprecations/test_missing_plus_in_config_deprecations.py::TestValidConfigKey::test_raises_warning\": 21.765928362000068,\n    \"tests/functional/deprecations/test_missing_plus_in_config_deprecations.py::TestValidConfigKeyWithNonPlusPrefixInNestedDir::test_raises_warning\": 22.186889668000276,\n    \"tests/functional/deprecations/test_missing_plus_in_config_deprecations.py::TestValidPlusPrefixConfigKeyWithNonPlusPrefixProperty::test_no_warning\": 21.55176104899988,\n    \"tests/functional/deprecations/test_missing_plus_in_config_deprecations.py::TestValidPlusPrefixConfigKeyWithPlusPrefixInNestedDir::test_no_warning\": 21.814113762999796,\n    \"tests/functional/deprecations/test_model_deprecations.py::TestDeprecatedReferenceWarning::test_deprecation_warning\": 0.7212648379999962,\n    \"tests/functional/deprecations/test_model_deprecations.py::TestDeprecatedReferenceWarning::test_deprecation_warning_error\": 11.380211667999902,\n    \"tests/functional/deprecations/test_model_deprecations.py::TestDeprecatedReferenceWarning::test_deprecation_warning_error_options\": 11.703597500000114,\n    \"tests/functional/deprecations/test_model_deprecations.py::TestModelDeprecationWarning::test_deprecation_warning\": 1.5684938809999949,\n    \"tests/functional/deprecations/test_model_deprecations.py::TestModelDeprecationWarning::test_deprecation_warning_error\": 11.089154958000108,\n    \"tests/functional/deprecations/test_model_deprecations.py::TestModelDeprecationWarning::test_deprecation_warning_error_options\": 11.218567669999857,\n    \"tests/functional/deprecations/test_model_deprecations.py::TestUpcomingReferenceDeprecationWarning::test_deprecation_warning\": 1.0087990290000164,\n    \"tests/functional/deprecations/test_model_deprecations.py::TestUpcomingReferenceDeprecationWarning::test_deprecation_warning_error\": 11.13699042899998,\n    \"tests/functional/deprecations/test_model_deprecations.py::TestUpcomingReferenceDeprecationWarning::test_deprecation_warning_error_options\": 1.203127640000048,\n    \"tests/functional/deps/test_deps_with_vars.py::TestBuildFailsWithMissingVar::test_build_fails_with_error\": 0.4349237669999866,\n    \"tests/functional/deps/test_deps_with_vars.py::TestCompileFailsWithMissingVar::test_compile_fails_with_error\": 11.764884287000768,\n    \"tests/functional/deps/test_deps_with_vars.py::TestDebugFailsWithMissingVar::test_debug_fails_with_error\": 23.543105118000767,\n    \"tests/functional/deps/test_deps_with_vars.py::TestDebugSucceedsWithVarDefaults::test_debug_succeeds\": 23.202864000999853,\n    \"tests/functional/deps/test_deps_with_vars.py::TestDepsSucceedsEvenWhenVarMissing::test_deps_still_succeeds\": 11.847928248999779,\n    \"tests/functional/deps/test_deps_with_vars.py::TestDepsSucceedsWithVarDefaults::test_deps_succeeds\": 11.50544181400005,\n    \"tests/functional/deps/test_deps_with_vars.py::TestRunFailsWithMissingVar::test_run_fails_with_error\": 11.541906229999768,\n    \"tests/functional/deps/test_deps_with_vars.py::TestRunSucceedsWithExplicitVars::test_run_succeeds_with_vars\": 24.46075694800038,\n    \"tests/functional/deps/test_deps_with_vars.py::TestRunSucceedsWithVarDefaults::test_run_succeeds\": 1.3233242549999886,\n    \"tests/functional/docs/test_doc_blocks_backcompat.py::TestDocBlocksBackCompat::test_doc_blocks_back_compat\": 24.63040471300019,\n    \"tests/functional/docs/test_doc_blocks_formatting.py::TestDocBlocksBackCompat::test_doc_blocks_back_compat\": 24.50814994400025,\n    \"tests/functional/docs/test_duplicate_docs_block.py::TestDuplicateDocsBlock::test_duplicate_doc_ref\": 25.39352328399991,\n    \"tests/functional/docs/test_generate.py::TestGenerateCatalogWithExternalNodes::test_catalog_with_external_node\": 40.900356811000165,\n    \"tests/functional/docs/test_generate.py::TestGenerateCatalogWithSources::test_catalog_with_sources\": 39.81236420900041,\n    \"tests/functional/docs/test_generate.py::TestGenerateEmptyCatalog::test_generate_empty_catalog\": 25.63579633800009,\n    \"tests/functional/docs/test_generate.py::TestGenerateManifestNotCompiled::test_manifest_not_compiled\": 25.082202055999915,\n    \"tests/functional/docs/test_generate.py::TestGenerateSelectLimitsCatalog::test_select_limits_catalog\": 38.77038824200008,\n    \"tests/functional/docs/test_generate.py::TestGenerateSelectLimitsNoMatch::test_select_limits_no_match\": 39.3574689080001,\n    \"tests/functional/docs/test_generate.py::TestGenerateSelectOverMaxSchemaMetadataRelations::test_select_source\": 96.78564224399997,\n    \"tests/functional/docs/test_generate.py::TestGenerateSelectSeed::test_select_seed\": 57.05880871699992,\n    \"tests/functional/docs/test_generate.py::TestGenerateSelectSource::test_select_source\": 53.704723122999894,\n    \"tests/functional/docs/test_good_docs_blocks.py::TestGoodDocsBlocks::test_valid_doc_ref\": 28.075528919000135,\n    \"tests/functional/docs/test_good_docs_blocks.py::TestGoodDocsBlocksAltPath::test_alternative_docs_path\": 28.326438081000106,\n    \"tests/functional/docs/test_invalid_doc_ref.py::TestInvalidDocRef::test_invalid_doc_ref\": 27.698858652000126,\n    \"tests/functional/docs/test_missing_docs_blocks.py::TestMissingDocsBlocks::test_missing_doc_ref\": 28.352783917000124,\n    \"tests/functional/docs/test_model_version_docs_blocks.py::TestVersionedModelDocsBlock::test_versioned_doc_ref\": 0.7920837240000225,\n    \"tests/functional/docs/test_static.py::TestStaticGenerate::test_static_generated\": 28.918235899000138,\n    \"tests/functional/duplicates/test_duplicate_analysis.py::TestDuplicateAnalysis::test_duplicate_model_enabled\": 28.68548046199976,\n    \"tests/functional/duplicates/test_duplicate_exposure.py::TestDuplicateExposure::test_duplicate_exposure\": 1.4647547040000006,\n    \"tests/functional/duplicates/test_duplicate_macro.py::TestDuplicateMacroEnabledDifferentFiles::test_duplicate_macros\": 28.646241817000373,\n    \"tests/functional/duplicates/test_duplicate_macro.py::TestDuplicateMacroEnabledSameFile::test_duplicate_macros\": 28.10583616699978,\n    \"tests/functional/duplicates/test_duplicate_metric.py::TestDuplicateMetric::test_duplicate_metric\": 29.601348011000027,\n    \"tests/functional/duplicates/test_duplicate_model.py::TestDuplicateModelAliasEnabledAcrossPackages::test_duplicate_model_alias_enabled_across_packages\": 0.9249040110000237,\n    \"tests/functional/duplicates/test_duplicate_model.py::TestDuplicateModelDisabled::test_duplicate_model_disabled\": 1.238120804999994,\n    \"tests/functional/duplicates/test_duplicate_model.py::TestDuplicateModelDisabled::test_duplicate_model_disabled_partial_parsing\": 38.269435807000264,\n    \"tests/functional/duplicates/test_duplicate_model.py::TestDuplicateModelDisabledAcrossPackages::test_duplicate_model_disabled_across_packages\": 25.5281680209996,\n    \"tests/functional/duplicates/test_duplicate_model.py::TestDuplicateModelEnabled::test_duplicate_model_enabled\": 23.87504331199989,\n    \"tests/functional/duplicates/test_duplicate_model.py::TestDuplicateModelNameWithTestAcrossPackages::test_duplicate_model_name_with_test_across_packages\": 25.296530750999864,\n    \"tests/functional/duplicates/test_duplicate_model.py::TestDuplicateModelNameWithVersionAcrossPackages::test_duplicate_model_name_with_test_across_packages\": 25.416415819999656,\n    \"tests/functional/duplicates/test_duplicate_model.py::TestModelTestOverlap::test_duplicate_test_model_paths\": 51.639125177000096,\n    \"tests/functional/duplicates/test_duplicate_model.py::TestMultipleDisabledModels::test_multiple_disabled_models\": 1.3385007279999854,\n    \"tests/functional/duplicates/test_duplicate_resource.py::TestDuplicateSchemaResource::test_duplicate_model_and_exposure\": 26.352396291000332,\n    \"tests/functional/duplicates/test_duplicate_resource_names.py::TestDuplicateNamesDefaultBehavior::test_duplicate_names_with_flag_disabled\": 26.858394729999873,\n    \"tests/functional/duplicates/test_duplicate_resource_names.py::TestDuplicateNamesDifferentResourceTypesVersionedUnversioned::test_duplicate_names_versioned_unversioned\": 26.570472865999818,\n    \"tests/functional/duplicates/test_duplicate_resource_names.py::TestDuplicateNamesRequireUniqueResourceNamesFalse::test_duplicate_names_with_flag_disabled\": 26.496836588000406,\n    \"tests/functional/duplicates/test_duplicate_resource_names.py::TestDuplicateNamesRequireUniqueResourceNamesTrue::test_duplicate_names_with_flag_enabled\": 25.893892814000083,\n    \"tests/functional/duplicates/test_duplicate_resource_names.py::TestDuplicateNamesRequireUniqueResourceNamesTrueDifferentPackages::test_duplicate_names_with_flag_enabled_different_packages\": 26.251696481999716,\n    \"tests/functional/duplicates/test_duplicate_source.py::TestDuplicateSourceEnabled::test_duplicate_source_enabled\": 27.157224704999862,\n    \"tests/functional/exit_codes/test_exit_codes.py::TestExitCodes::test_compile\": 14.081638306999594,\n    \"tests/functional/exit_codes/test_exit_codes.py::TestExitCodes::test_exit_code_run_fail\": 1.974118763999968,\n    \"tests/functional/exit_codes/test_exit_codes.py::TestExitCodes::test_exit_code_run_succeed\": 1.7424754859999894,\n    \"tests/functional/exit_codes/test_exit_codes.py::TestExitCodes::test_schema_test_fail\": 28.18309098499958,\n    \"tests/functional/exit_codes/test_exit_codes.py::TestExitCodes::test_schema_test_pass\": 27.7471505780004,\n    \"tests/functional/exit_codes/test_exit_codes.py::TestExitCodes::test_snapshot_pass\": 28.559106527999575,\n    \"tests/functional/exit_codes/test_exit_codes.py::TestExitCodesDeps::test_deps\": 14.88137974700021,\n    \"tests/functional/exit_codes/test_exit_codes.py::TestExitCodesDepsFail::test_deps_fail\": 14.362762309000118,\n    \"tests/functional/exit_codes/test_exit_codes.py::TestExitCodesSeed::test_seed\": 1.3676858219999986,\n    \"tests/functional/exit_codes/test_exit_codes.py::TestExitCodesSeedFail::test_seed\": 29.01156851700034,\n    \"tests/functional/exit_codes/test_exit_codes.py::TestExitCodesSnapshotFail::test_snapshot_fail\": 43.60882749300026,\n    \"tests/functional/experimental_parser/test_all_experimental_parser.py::TestBasicExperimentalParser::test_experimental_parser_basic\": 28.981400720000693,\n    \"tests/functional/experimental_parser/test_all_experimental_parser.py::TestBasicNoStaticParser::test_static_parser_is_disabled\": 29.35429184700024,\n    \"tests/functional/experimental_parser/test_all_experimental_parser.py::TestBasicStaticParser::test_static_parser_basic\": 29.274852511999597,\n    \"tests/functional/exposures/test_exposure_configs.py::TestConfigYamlLevel::test_exposure_config_yaml_level\": 29.964520381000057,\n    \"tests/functional/exposures/test_exposure_configs.py::TestExposureConfigsInheritence::test_exposure_all_configs\": 29.824192048999976,\n    \"tests/functional/exposures/test_exposure_configs.py::TestExposureEnabledConfigProjectLevel::test_enabled_exposure_config_dbt_project\": 46.25001147100011,\n    \"tests/functional/exposures/test_exposure_configs.py::TestInvalidConfig::test_exposure_config_yaml_level\": 29.813378384000316,\n    \"tests/functional/exposures/test_exposures.py::TestBasicExposures::test_compilation_depends_on\": 2.0448871080000117,\n    \"tests/functional/exposures/test_exposures.py::TestBasicExposures::test_compilation_names_with_spaces\": 2.4895492529999927,\n    \"tests/functional/exposures/test_exposures.py::TestBasicExposures::test_execution_default\": 16.112158016000194,\n    \"tests/functional/exposures/test_exposures.py::TestBasicExposures::test_execution_exclude\": 15.807534360000318,\n    \"tests/functional/exposures/test_exposures.py::TestBasicExposures::test_execution_select\": 1.8320979120001084,\n    \"tests/functional/external_reference/test_external_reference.py::TestExternalDependency::test_external_reference\": 1.8692533880000042,\n    \"tests/functional/external_reference/test_external_reference.py::TestExternalReference::test_external_reference\": 2.2516147510000053,\n    \"tests/functional/fail_fast/test_fail_fast_run.py::TestFailFastFromConfig::test_fail_fast_run_project_flags\": 31.91725944700056,\n    \"tests/functional/fail_fast/test_fail_fast_run.py::TestFastFailingDuringRun::test_fail_fast_run\": 1.162760456999976,\n    \"tests/functional/functions/test_udafs.py::TestBasicSQLUDAF::test_basic_sql_udaf_parsing\": 31.75793714099973,\n    \"tests/functional/functions/test_udfs.py::TestBasicPythonUDF::test_basic_parsing\": 65.13051018799979,\n    \"tests/functional/functions/test_udfs.py::TestBasicSQLUDF::test_basic_parsing\": 2.4764980189999903,\n    \"tests/functional/functions/test_udfs.py::TestCanCallUDFInModel::test_can_call_udf_in_model\": 49.52874270300026,\n    \"tests/functional/functions/test_udfs.py::TestCanConfigFunctionsFromProjectConfig::test_can_config_functions_from_project_config\": 52.7539218779998,\n    \"tests/functional/functions/test_udfs.py::TestCanInlineShowUDF::test_can_inline_show_udf\": 48.95041919799996,\n    \"tests/functional/functions/test_udfs.py::TestCanUseRefInUDF::test_can_use_ref_in_udf\": 2.456829693000003,\n    \"tests/functional/functions/test_udfs.py::TestCanUseSourceInUDF::test_can_use_ref_in_udf\": 74.14871335299995,\n    \"tests/functional/functions/test_udfs.py::TestCanUseWithEmptyMode::test_can_use_with_empty_model\": 2.809738839000005,\n    \"tests/functional/functions/test_udfs.py::TestCreationOfUDFs::test_can_create_udf\": 32.91761063800004,\n    \"tests/functional/functions/test_udfs.py::TestDefaultArgumentsBasic::test_udfs\": 35.512634209000225,\n    \"tests/functional/functions/test_udfs.py::TestDefaultArgumentsMustComeLast::test_udfs\": 1.2908535799999754,\n    \"tests/functional/functions/test_udfs.py::TestFunctionsGetSchemaCreatedIfNecessary::test_functions_get_schema_created_if_necessary\": 1.9864689350000049,\n    \"tests/functional/functions/test_udfs.py::TestFunctionsIncludeAndExcludeByResourceType::test_udfs\": 55.128863868999815,\n    \"tests/functional/functions/test_udfs.py::TestPythonFunctionPackagesViaJinjaConfig::test_packages_set_via_jinja_config\": 1.2323887480000053,\n    \"tests/functional/functions/test_udfs.py::TestPythonFunctionPackagesViaProjectConfig::test_packages_set_via_project_config\": 1.219787224000001,\n    \"tests/functional/functions/test_udfs.py::TestPythonFunctionPackagesViaYamlConfig::test_packages_set_via_yaml_config\": 1.611244054999986,\n    \"tests/functional/functions/test_udfs.py::TestPythonFunctionWithJinjaHasCorrectCompiledCode::test_udfs\": 34.40929981100044,\n    \"tests/functional/functions/test_udfs.py::TestPythonFunctionWithoutJinjaHasEquivalentRawCodeAndCompiledCode::test_udfs\": 1.9365318119999984,\n    \"tests/functional/generic_test_description/test_generic_test_description.py::TestBuiltinGenericTestDescription::test_compile\": 37.24881190300039,\n    \"tests/functional/graph_selection/test_graph_selection.py::TestGraphSelection::test_childrens_parents\": 2.508250227000019,\n    \"tests/functional/graph_selection/test_graph_selection.py::TestGraphSelection::test_concat\": 12.909825407999506,\n    \"tests/functional/graph_selection/test_graph_selection.py::TestGraphSelection::test_concat_exclude\": 0.7179012160000013,\n    \"tests/functional/graph_selection/test_graph_selection.py::TestGraphSelection::test_concat_exclude_concat\": 1.600413844000002,\n    \"tests/functional/graph_selection/test_graph_selection.py::TestGraphSelection::test_concat_exclude_multiple\": 13.44328880500052,\n    \"tests/functional/graph_selection/test_graph_selection.py::TestGraphSelection::test_concat_multiple\": 1.8450229519999652,\n    \"tests/functional/graph_selection/test_graph_selection.py::TestGraphSelection::test_exposure_parents\": 2.189637500999993,\n    \"tests/functional/graph_selection/test_graph_selection.py::TestGraphSelection::test_group\": 18.124883124999542,\n    \"tests/functional/graph_selection/test_graph_selection.py::TestGraphSelection::test_locally_qualified_name\": 4.301605815999892,\n    \"tests/functional/graph_selection/test_graph_selection.py::TestGraphSelection::test_locally_qualified_name_model_with_dots\": 25.781206155999826,\n    \"tests/functional/graph_selection/test_graph_selection.py::TestGraphSelection::test_more_childrens_parents\": 25.596005766000417,\n    \"tests/functional/graph_selection/test_graph_selection.py::TestGraphSelection::test_specific_model\": 37.92465308700048,\n    \"tests/functional/graph_selection/test_graph_selection.py::TestGraphSelection::test_specific_model_and_children\": 19.502110650999384,\n    \"tests/functional/graph_selection/test_graph_selection.py::TestGraphSelection::test_specific_model_and_children_limited\": 1.7650639989999775,\n    \"tests/functional/graph_selection/test_graph_selection.py::TestGraphSelection::test_specific_model_and_parents\": 12.409017880000647,\n    \"tests/functional/graph_selection/test_graph_selection.py::TestGraphSelection::test_specific_model_and_parents_limited\": 12.416455977000169,\n    \"tests/functional/graph_selection/test_graph_selection.py::TestGraphSelection::test_specific_model_with_exclusion\": 12.445105512999817,\n    \"tests/functional/graph_selection/test_graph_selection.py::TestGraphSelection::test_tags\": 19.622023160000936,\n    \"tests/functional/graph_selection/test_graph_selection.py::TestGraphSelection::test_tags_and_children\": 19.35943232200043,\n    \"tests/functional/graph_selection/test_graph_selection.py::TestGraphSelection::test_tags_and_children_limited\": 19.2460117920009,\n    \"tests/functional/graph_selection/test_graph_selection.py::TestListPathGraphSelection::test_list_select_with_project_dir\": 26.28520174499954,\n    \"tests/functional/graph_selection/test_group_selection.py::TestGroupSelection::test_select_group_and_children\": 13.167205011999613,\n    \"tests/functional/graph_selection/test_group_selection.py::TestGroupSelection::test_select_group_and_children_selector_str\": 13.272448195999914,\n    \"tests/functional/graph_selection/test_group_selection.py::TestGroupSelection::test_select_group_selector_dict\": 13.171816516000035,\n    \"tests/functional/graph_selection/test_group_selection.py::TestGroupSelection::test_select_group_selector_str\": 13.228674113000125,\n    \"tests/functional/graph_selection/test_group_selection.py::TestGroupSelection::test_select_models_by_group\": 1.361184542999922,\n    \"tests/functional/graph_selection/test_group_selection.py::TestGroupSelection::test_select_models_by_group_and_children\": 13.299145571000281,\n    \"tests/functional/graph_selection/test_group_selection.py::TestGroupSelection::test_select_models_two_groups\": 13.193709012,\n    \"tests/functional/graph_selection/test_inline.py::TestCompileInlineWithSelector::test_inline_selectors\": 42.25843922499962,\n    \"tests/functional/graph_selection/test_intersection_syntax.py::TestIntersectionSyncs::test_intersection_concat\": 14.995229978000225,\n    \"tests/functional/graph_selection/test_intersection_syntax.py::TestIntersectionSyncs::test_intersection_concat_exclude\": 14.83617866700024,\n    \"tests/functional/graph_selection/test_intersection_syntax.py::TestIntersectionSyncs::test_intersection_concat_exclude_concat\": 15.006434442999307,\n    \"tests/functional/graph_selection/test_intersection_syntax.py::TestIntersectionSyncs::test_intersection_concat_exclude_intersection_concat\": 15.115295890000198,\n    \"tests/functional/graph_selection/test_intersection_syntax.py::TestIntersectionSyncs::test_intersection_concat_intersection\": 14.510216172000128,\n    \"tests/functional/graph_selection/test_intersection_syntax.py::TestIntersectionSyncs::test_intersection_exclude_intersection\": 14.356039661999603,\n    \"tests/functional/graph_selection/test_intersection_syntax.py::TestIntersectionSyncs::test_intersection_exclude_intersection_lack\": 2.0308358759999976,\n    \"tests/functional/graph_selection/test_intersection_syntax.py::TestIntersectionSyncs::test_intersection_exclude_intersection_lack_selector\": 14.71992816700049,\n    \"tests/functional/graph_selection/test_intersection_syntax.py::TestIntersectionSyncs::test_intersection_exclude_intersection_selectors\": 14.627233063999483,\n    \"tests/functional/graph_selection/test_intersection_syntax.py::TestIntersectionSyncs::test_intersection_exclude_triple_intersection\": 14.67519316500011,\n    \"tests/functional/graph_selection/test_intersection_syntax.py::TestIntersectionSyncs::test_intersection_triple_ascending\": 14.598907127000075,\n    \"tests/functional/graph_selection/test_intersection_syntax.py::TestIntersectionSyncs::test_intersection_triple_ascending_schema_selectors\": 14.968994184000167,\n    \"tests/functional/graph_selection/test_intersection_syntax.py::TestIntersectionSyncs::test_intersection_triple_descending\": 14.092702379000002,\n    \"tests/functional/graph_selection/test_intersection_syntax.py::TestIntersectionSyncs::test_intersection_triple_descending_schema\": 1.58655805799998,\n    \"tests/functional/graph_selection/test_intersection_syntax.py::TestIntersectionSyncs::test_intersection_triple_descending_schema_selectors\": 14.10705950099964,\n    \"tests/functional/graph_selection/test_intersection_syntax.py::TestIntersectionSyncs::test_intersection_with_exclusion\": 14.351303169000403,\n    \"tests/functional/graph_selection/test_intersection_syntax.py::TestIntersectionSyncs::test_intersection_with_exclusion_selectors\": 2.7241375329999755,\n    \"tests/functional/graph_selection/test_intersection_syntax.py::TestIntersectionSyncs::test_same_model_intersection\": 28.43503246900036,\n    \"tests/functional/graph_selection/test_intersection_syntax.py::TestIntersectionSyncs::test_same_model_intersection_selectors\": 13.844164738000018,\n    \"tests/functional/graph_selection/test_intersection_syntax.py::TestIntersectionSyncs::test_tags_intersection\": 14.036897025000144,\n    \"tests/functional/graph_selection/test_intersection_syntax.py::TestIntersectionSyncs::test_tags_intersection_selectors\": 14.063359466000293,\n    \"tests/functional/graph_selection/test_schema_test_graph_selection.py::TestSchemaTestGraphSelection::test_schema_tests_dep_package_only\": 51.68071550100012,\n    \"tests/functional/graph_selection/test_schema_test_graph_selection.py::TestSchemaTestGraphSelection::test_schema_tests_exclude_pkg\": 52.16865292500006,\n    \"tests/functional/graph_selection/test_schema_test_graph_selection.py::TestSchemaTestGraphSelection::test_schema_tests_model_in_dep_pkg\": 52.11282838900024,\n    \"tests/functional/graph_selection/test_schema_test_graph_selection.py::TestSchemaTestGraphSelection::test_schema_tests_no_specifiers\": 64.64320401700024,\n    \"tests/functional/graph_selection/test_schema_test_graph_selection.py::TestSchemaTestGraphSelection::test_schema_tests_specify_exclude_only\": 4.927788882000016,\n    \"tests/functional/graph_selection/test_schema_test_graph_selection.py::TestSchemaTestGraphSelection::test_schema_tests_specify_model\": 5.523728221999988,\n    \"tests/functional/graph_selection/test_schema_test_graph_selection.py::TestSchemaTestGraphSelection::test_schema_tests_specify_model_and_children\": 50.22854238400032,\n    \"tests/functional/graph_selection/test_schema_test_graph_selection.py::TestSchemaTestGraphSelection::test_schema_tests_specify_model_and_parents\": 50.10652645600021,\n    \"tests/functional/graph_selection/test_schema_test_graph_selection.py::TestSchemaTestGraphSelection::test_schema_tests_specify_model_and_parents_with_exclude\": 4.782106176000013,\n    \"tests/functional/graph_selection/test_schema_test_graph_selection.py::TestSchemaTestGraphSelection::test_schema_tests_specify_model_in_pkg\": 50.37311680499988,\n    \"tests/functional/graph_selection/test_schema_test_graph_selection.py::TestSchemaTestGraphSelection::test_schema_tests_specify_tag\": 49.22179712800016,\n    \"tests/functional/graph_selection/test_schema_test_graph_selection.py::TestSchemaTestGraphSelection::test_schema_tests_specify_tag_and_children\": 4.042665136000011,\n    \"tests/functional/graph_selection/test_schema_test_graph_selection.py::TestSchemaTestGraphSelection::test_schema_tests_with_glob\": 51.697270744000434,\n    \"tests/functional/graph_selection/test_tag_selection.py::TestTagSelection::test_select_tag\": 33.416239341000164,\n    \"tests/functional/graph_selection/test_tag_selection.py::TestTagSelection::test_select_tag_and_children\": 31.180385521000062,\n    \"tests/functional/graph_selection/test_tag_selection.py::TestTagSelection::test_select_tag_and_children_selector_dict\": 15.542415533000167,\n    \"tests/functional/graph_selection/test_tag_selection.py::TestTagSelection::test_select_tag_and_children_selector_str\": 15.557976923000297,\n    \"tests/functional/graph_selection/test_tag_selection.py::TestTagSelection::test_select_tag_in_model_with_project_config\": 15.266220377000991,\n    \"tests/functional/graph_selection/test_tag_selection.py::TestTagSelection::test_select_tag_in_model_with_project_config_parents_children\": 78.16209385299999,\n    \"tests/functional/graph_selection/test_tag_selection.py::TestTagSelection::test_select_tag_in_model_with_project_config_parents_children_selectors\": 79.18678878999981,\n    \"tests/functional/graph_selection/test_tag_selection.py::TestTagSelection::test_select_tag_in_model_with_project_config_selector\": 15.599573576999319,\n    \"tests/functional/graph_selection/test_tag_selection.py::TestTagSelection::test_select_tag_selector_dict\": 18.79408114599937,\n    \"tests/functional/graph_selection/test_tag_selection.py::TestTagSelection::test_select_tag_selector_str\": 17.633430820000285,\n    \"tests/functional/graph_selection/test_tag_selection.py::TestTagSelectionNoMatch::test_no_match\": 62.142076434000046,\n    \"tests/functional/graph_selection/test_version_selection.py::TestVersionSelection::test_select_group_and_children_selector_str\": 1.6655723169999987,\n    \"tests/functional/graph_selection/test_version_selection.py::TestVersionSelection::test_select_latest_versions\": 15.785927988999902,\n    \"tests/functional/graph_selection/test_version_selection.py::TestVersionSelection::test_select_models_by_version_and_children\": 15.688814922000347,\n    \"tests/functional/graph_selection/test_version_selection.py::TestVersionSelection::test_select_models_two_versions\": 15.784008649000043,\n    \"tests/functional/graph_selection/test_version_selection.py::TestVersionSelection::test_select_none_versions\": 31.43017837699972,\n    \"tests/functional/graph_selection/test_version_selection.py::TestVersionSelection::test_select_old_versions\": 15.41188330299974,\n    \"tests/functional/graph_selection/test_version_selection.py::TestVersionSelection::test_select_prerelease_versions\": 15.761585003000619,\n    \"tests/functional/graph_selection/test_version_selection.py::TestVersionSelection::test_select_version_and_children\": 15.621994842999811,\n    \"tests/functional/graph_selection/test_version_selection.py::TestVersionSelection::test_select_version_selector_dict\": 15.54781453500027,\n    \"tests/functional/graph_selection/test_version_selection.py::TestVersionSelection::test_select_version_selector_str\": 15.499085959999775,\n    \"tests/functional/graph_selection/test_version_selection.py::TestVersionZero::test_version_zero\": 32.610576246000164,\n    \"tests/functional/incremental_schema_tests/test_incremental_schema.py::TestIncrementalSchemaChange::test_run_incremental_append_new_columns\": 68.41681122099953,\n    \"tests/functional/incremental_schema_tests/test_incremental_schema.py::TestIncrementalSchemaChange::test_run_incremental_fail_on_schema_change\": 36.856877812999755,\n    \"tests/functional/incremental_schema_tests/test_incremental_schema.py::TestIncrementalSchemaChange::test_run_incremental_ignore\": 50.44773877700027,\n    \"tests/functional/incremental_schema_tests/test_incremental_schema.py::TestIncrementalSchemaChange::test_run_incremental_sync_all_columns\": 69.71002910400057,\n    \"tests/functional/init/test_init.py::TestInitDebugFailureDoesNotFailInit::test_debug_failure_does_not_fail_init\": 0.5791350929999908,\n    \"tests/functional/init/test_init.py::TestInitDebugSkippedWithSkipProfileSetup::test_debug_skipped_with_skip_profile_setup\": 17.2339656070003,\n    \"tests/functional/init/test_init.py::TestInitInsideProjectAndSkipProfileSetup::test_init_inside_project_and_skip_profile_setup\": 17.153582335000465,\n    \"tests/functional/init/test_init.py::TestInitInvalidProfileTemplate::test_init_task_in_project_with_invalid_profile_template\": 18.39949953400037,\n    \"tests/functional/init/test_init.py::TestInitInvalidProjectNameCLI::test_init_invalid_project_name_cli\": 18.422810833000312,\n    \"tests/functional/init/test_init.py::TestInitInvalidProjectNamePrompt::test_init_invalid_project_name_prompt\": 18.742967726999723,\n    \"tests/functional/init/test_init.py::TestInitOutsideOfProject::test_init_task_outside_of_project\": 19.04777491899995,\n    \"tests/functional/init/test_init.py::TestInitOutsideOfProjectSpecifyingInvalidProfile::test_init_task_outside_project_specifying_invalid_profile_errors\": 17.796106995999708,\n    \"tests/functional/init/test_init.py::TestInitOutsideOfProjectSpecifyingProfileNoProfilesYml::test_init_task_outside_project_specifying_profile_no_profiles_yml_errors\": 0.9037674869998682,\n    \"tests/functional/init/test_init.py::TestInitOutsideOfProjectWithSpecifiedProfile::test_init_task_outside_of_project_with_specified_profile\": 17.525682263000363,\n    \"tests/functional/init/test_init.py::TestInitProjectWithExistingProfilesYml::test_init_task_in_project_specifying_profile_errors\": 0.037768407999465126,\n    \"tests/functional/init/test_init.py::TestInitProjectWithExistingProfilesYml::test_init_task_in_project_with_existing_profiles_yml\": 18.100640485999975,\n    \"tests/functional/init/test_init.py::TestInitProjectWithProfileTemplateWithoutExistingProfilesYml::test_init_task_in_project_with_profile_template_without_existing_profiles_yml\": 17.554543131000173,\n    \"tests/functional/init/test_init.py::TestInitProjectWithoutExistingProfilesYml::test_init_task_in_project_without_existing_profiles_yml\": 17.863601771999583,\n    \"tests/functional/init/test_init.py::TestInitProjectWithoutExistingProfilesYml::test_init_task_in_project_without_profile_yml_specifying_profile_errors\": 0.03693259000010585,\n    \"tests/functional/init/test_init.py::TestInitProjectWithoutExistingProfilesYmlOrTemplate::test_init_task_in_project_without_existing_profiles_yml_or_profile_template\": 17.679810812999676,\n    \"tests/functional/init/test_init.py::TestInitProvidedProjectNameAndSkipProfileSetup::test_init_provided_project_name_and_skip_profile_setup\": 0.7673309320000214,\n    \"tests/functional/init/test_init.py::TestInitRunsDebugAfterInit::test_debug_runs_after_init\": 17.08298876900062,\n    \"tests/functional/init/test_init.py::TestInitSkipDebugFlag::test_debug_skipped_with_skip_debug_flag\": 16.945760626000265,\n    \"tests/functional/init/test_init.py::TestInitSkipDebugFlag::test_run_debug_returns_none_when_skip_debug\": 0.0059812630001943035,\n    \"tests/functional/invalid_model_tests/test_invalid_models.py::TestInvalidDisabledSource::test_postgres_source_disabled\": 36.04655223199916,\n    \"tests/functional/invalid_model_tests/test_invalid_models.py::TestInvalidMacroCall::test_with_invalid_macro_call\": 36.61649233600019,\n    \"tests/functional/invalid_model_tests/test_invalid_models.py::TestInvalidMissingSource::test_source_missing\": 37.96848639899963,\n    \"tests/functional/invalid_model_tests/test_invalid_models.py::TestMalformedEnabledParam::test_view_disabled\": 35.979286254000726,\n    \"tests/functional/invalid_model_tests/test_invalid_models.py::TestMissingModelReference::test_models_not_found\": 36.57908891800071,\n    \"tests/functional/invalid_model_tests/test_invalid_models.py::TestReferencingDisabledModel::test_referencing_disabled_model\": 1.6028407899999593,\n    \"tests/functional/invalid_model_tests/test_model_logging.py::TestModelLogging::test_warn\": 38.163236172000325,\n    \"tests/functional/list/test_commands.py::TestRunCommands::test_run_commmand\": 185.6277160159998,\n    \"tests/functional/list/test_commands.py::TestSelectResourceType::test_select_by_resource_type[function]\": 2.7868588799998406,\n    \"tests/functional/list/test_commands.py::TestSelectResourceType::test_select_by_resource_type[metric]\": 3.937126362000015,\n    \"tests/functional/list/test_commands.py::TestSelectResourceType::test_select_by_resource_type[model]\": 40.602950125999996,\n    \"tests/functional/list/test_commands.py::TestSelectResourceType::test_select_by_resource_type[saved_query]\": 18.88520880300075,\n    \"tests/functional/list/test_commands.py::TestSelectResourceType::test_select_by_resource_type[seed]\": 19.36082779299977,\n    \"tests/functional/list/test_commands.py::TestSelectResourceType::test_select_by_resource_type[semantic_model]\": 19.277891276001355,\n    \"tests/functional/list/test_commands.py::TestSelectResourceType::test_select_by_resource_type[snapshot]\": 19.32752205700035,\n    \"tests/functional/list/test_commands.py::TestSelectResourceType::test_select_by_resource_type[source]\": 19.099546781000754,\n    \"tests/functional/list/test_commands.py::TestSelectResourceType::test_select_by_resource_type[test]\": 19.203873597999518,\n    \"tests/functional/list/test_list.py::TestList::test_ls\": 1099.951739444,\n    \"tests/functional/list/test_list.py::TestList::test_packages_install_path_does_not_exist\": 40.05945426699964,\n    \"tests/functional/logging/test_logging.py::TestRunResultErrorGroup::test_node_info_on_results\": 45.281118392998906,\n    \"tests/functional/logging/test_logging.py::TestRunResultErrorNodeInfo::test_node_info_on_results\": 45.6950353000002,\n    \"tests/functional/logging/test_logging.py::TestRunResultFailureGroup::test_node_info_on_results\": 1.7022340180000128,\n    \"tests/functional/logging/test_logging.py::TestRunResultGroupWithMultipleEmails::test_node_info_on_results\": 43.78835089600034,\n    \"tests/functional/logging/test_logging.py::TestRunResultNoGroup::test_node_info_on_results\": 46.46921098799976,\n    \"tests/functional/logging/test_logging.py::TestRunResultWarningGroup::test_node_info_on_results\": 46.4903418340009,\n    \"tests/functional/logging/test_logging.py::test_basic\": 47.53864436300046,\n    \"tests/functional/logging/test_logging.py::test_formatted_logs\": 1.5603004649999832,\n    \"tests/functional/logging/test_logging.py::test_invalid_event_value\": 1.498464998999907,\n    \"tests/functional/logging/test_meta_logging.py::test_checksum\": 44.08258937299979,\n    \"tests/functional/logging/test_meta_logging.py::test_meta\": 44.063530516001265,\n    \"tests/functional/macros/test_macro_annotations.py::TestMacroDefaultArgMetadata::test_macro_default_arg_metadata\": 43.33437836400026,\n    \"tests/functional/macros/test_macro_annotations.py::TestMacroNameWarnings::test_macro_name_enforcement\": 44.30069975100014,\n    \"tests/functional/macros/test_macro_annotations.py::TestMacroNonEnforcement::test_macro_non_enforcement\": 43.817898860998866,\n    \"tests/functional/macros/test_macro_annotations.py::TestMacroTypeWarnings::test_macro_type_warnings\": 1.3724852929999827,\n    \"tests/functional/macros/test_macros.py::TestAdapterMacroDeprecated::test_invalid_macro\": 35.55750028400007,\n    \"tests/functional/macros/test_macros.py::TestAdapterMacroNoDestination::test_invalid_macro\": 44.34371805399951,\n    \"tests/functional/macros/test_macros.py::TestDispatchMacroOverrideBuiltin::test_overrides\": 2.9275026299999922,\n    \"tests/functional/macros/test_macros.py::TestInvalidMacros::test_invalid_macro\": 45.734582750999834,\n    \"tests/functional/macros/test_macros.py::TestMacroMetaDocsMerge::test_both_config_and_top_level_defined\": 1.2182601210000144,\n    \"tests/functional/macros/test_macros.py::TestMacroMetaDocsMerge::test_only_config_defined\": 1.2773016919999804,\n    \"tests/functional/macros/test_macros.py::TestMacroMetaDocsMerge::test_only_top_level_defined\": 1.4264197600000017,\n    \"tests/functional/macros/test_macros.py::TestMacroNotOverridePackage::test_overrides\": 69.28586699799871,\n    \"tests/functional/macros/test_macros.py::TestMacroOverrideBuiltin::test_overrides\": 68.62218654499975,\n    \"tests/functional/macros/test_macros.py::TestMacroOverridePackage::test_overrides\": 68.23813533700104,\n    \"tests/functional/macros/test_macros.py::TestMacros::test_working_macros\": 5.3055779669999765,\n    \"tests/functional/macros/test_macros.py::TestMacrosNamedMaterialization::test_macro_with_materialization_in_name_works\": 44.730292663,\n    \"tests/functional/macros/test_macros.py::TestMisnamedMacroNamespace::test_misnamed_macro_namespace\": 45.5819768120009,\n    \"tests/functional/manifest_validations/test_check_for_spaces_in_model_names.py::TestAllowSpacesInModelNamesFalse::test_require_resource_names_without_spaces\": 51.528736794,\n    \"tests/functional/manifest_validations/test_check_for_spaces_in_model_names.py::TestSpaceInModelNamesWithDebug::tests_debug_when_spaces_in_name\": 2.3961025099999915,\n    \"tests/functional/manifest_validations/test_check_for_spaces_in_model_names.py::TestSpacesInModelNamesHappyPath::test_no_warnings_when_no_spaces_in_name\": 36.15592363399992,\n    \"tests/functional/manifest_validations/test_check_for_spaces_in_model_names.py::TestSpacesInModelNamesSadPath::tests_warning_when_spaces_in_name\": 1.566663277999993,\n    \"tests/functional/materializations/test_custom_materialization.py::TestCustomMaterializationDependency::test_custom_materialization_deopendency\": 1.8580500450000272,\n    \"tests/functional/materializations/test_custom_materialization.py::TestOverrideAdapterDependency::test_adapter_dependency\": 35.41312095300054,\n    \"tests/functional/materializations/test_custom_materialization.py::TestOverrideAdapterDependencyDeprecated::test_adapter_dependency_deprecate_overrides\": 35.24775612900066,\n    \"tests/functional/materializations/test_custom_materialization.py::TestOverrideAdapterDependencyLegacy::test_adapter_dependency\": 36.47106995199965,\n    \"tests/functional/materializations/test_custom_materialization.py::TestOverrideAdapterDependencyPassing::test_default_dependency\": 1.669941439000013,\n    \"tests/functional/materializations/test_custom_materialization.py::TestOverrideAdapterLocal::test_default_dependency\": 37.50113029499971,\n    \"tests/functional/materializations/test_custom_materialization.py::TestOverrideDefaultDependency::test_default_dependency\": 37.01245163500016,\n    \"tests/functional/materializations/test_custom_materialization.py::TestOverrideDefaultDependencyDeprecated::test_default_dependency_deprecated\": 37.905290189000425,\n    \"tests/functional/materializations/test_custom_materialization.py::TestOverrideDefaultDependencyLegacy::test_default_dependency\": 36.938370932,\n    \"tests/functional/materializations/test_custom_materialization.py::TestOverrideDefaultDependencyRootOverride::test_default_dependency_with_root_override\": 37.68423807099953,\n    \"tests/functional/materializations/test_custom_materialization.py::TestOverrideDefaultReturn::test_default_dependency\": 37.78295711999999,\n    \"tests/functional/materializations/test_ephemeral_compilation.py::TestEphemeralCompilation::test__suppress_injected_ctes\": 19.31645506500081,\n    \"tests/functional/materializations/test_ephemeral_compilation.py::TestEphemeralCompilation::test_ephemeral_compilation\": 38.62254519200087,\n    \"tests/functional/materializations/test_ephemeral_compilation.py::TestLargeEphemeralCompilation::test_ephemeral_compilation\": 42.39926495100008,\n    \"tests/functional/materializations/test_incremental.py::test_basic\": 40.398111968000194,\n    \"tests/functional/materializations/test_incremental_with_contract.py::TestIncremental::test_incremental\": 80.8141773289999,\n    \"tests/functional/materializations/test_runtime_materialization.py::TestRuntimeMaterialization::test_delete_dbt_tmp_relation\": 80.14798397899995,\n    \"tests/functional/materializations/test_runtime_materialization.py::TestRuntimeMaterialization::test_full_refresh\": 5.311695101999931,\n    \"tests/functional/materializations/test_runtime_materialization.py::TestRuntimeMaterializationWithConfig::test_delete_dbt_tmp_relation\": 80.55651747700085,\n    \"tests/functional/materializations/test_runtime_materialization.py::TestRuntimeMaterializationWithConfig::test_full_refresh\": 101.39351926700056,\n    \"tests/functional/materializations/test_supported_languages.py::TestSupportedLanguages_SupportsDefault_UsingPython::test_language\": 39.40107029200044,\n    \"tests/functional/materializations/test_supported_languages.py::TestSupportedLanguages_SupportsDefault_UsingSql::test_language\": 40.45087230699937,\n    \"tests/functional/materializations/test_supported_languages.py::TestSupportedLanguages_SupportsSql_UsingSql::test_language\": 40.2894384859992,\n    \"tests/functional/materializations/test_supported_languages.py::TestSupportedLanguages_SuppotsPython_UsingPython::test_language\": 42.44475588000023,\n    \"tests/functional/materializations/test_supported_languages.py::TestSupportedLanguages_SuppotsPython_UsingSql::test_language\": 46.84575000800032,\n    \"tests/functional/materializations/test_supported_languages.py::TestSupportedLanguages_SuppotsSqlAndPython_UsingPython::test_language\": 48.37612609400094,\n    \"tests/functional/materializations/test_supported_languages.py::TestSupportedLanguages_SuppotsSqlAndPython_UsingSql::test_language\": 48.06351188900044,\n    \"tests/functional/materializations/test_supported_languages.py::TestSupportedLanguages_SuppotsSql_UsingPython::test_language\": 43.04030513500038,\n    \"tests/functional/metrics/test_metric_configs.py::TestConfigYamlMetricLevel::test_metric_config_yaml_metric_level\": 1.4210243919999357,\n    \"tests/functional/metrics/test_metric_configs.py::TestDisabledMetric::test_disabling_upstream_metric_errors\": 65.37125230400125,\n    \"tests/functional/metrics/test_metric_configs.py::TestDisabledMetricRef::test_disabled_metric_ref_model\": 74.60683608299951,\n    \"tests/functional/metrics/test_metric_configs.py::TestInvalidMetric::test_invalid_config_metric\": 48.01344038199932,\n    \"tests/functional/metrics/test_metric_configs.py::TestMetricConfigsInheritence::test_metrics_all_configs\": 47.10576063699955,\n    \"tests/functional/metrics/test_metric_configs.py::TestMetricEnabledConfigProjectLevel::test_enabled_metric_config_dbt_project\": 72.71909323699947,\n    \"tests/functional/metrics/test_metric_configs.py::TestMetricMetaConfigLevel::test_meta_metric_config_yaml\": 43.8280317789995,\n    \"tests/functional/metrics/test_metric_configs.py::TestMetricMetaConfigProjectLevel::test_meta_metric_config_dbt_project\": 41.78660000899981,\n    \"tests/functional/metrics/test_metric_configs.py::TestMetricMetaTopLevel::test_meta_metric_config_yaml\": 44.584683468999174,\n    \"tests/functional/metrics/test_metric_deferral.py::TestMetricDeferral::test_metric_deferral\": 0.0005971929995212122,\n    \"tests/functional/metrics/test_metric_helper_functions.py::TestMetricHelperFunctions::test_derived_metric\": 45.06806885900005,\n    \"tests/functional/metrics/test_metrics.py::TestConversionMetric::test_conversion_metric\": 43.48691987300026,\n    \"tests/functional/metrics/test_metrics.py::TestCumulativeMetric::test_cumulative_metric\": 43.55397571700087,\n    \"tests/functional/metrics/test_metrics.py::TestDerivedMetric::test_derived_metric\": 64.41477746099918,\n    \"tests/functional/metrics/test_metrics.py::TestDuplicateInputMeasures::test_duplicate_input_measures\": 43.91750452100041,\n    \"tests/functional/metrics/test_metrics.py::TestFilterParsing::test_filter_parsing\": 1.0805087550000962,\n    \"tests/functional/metrics/test_metrics.py::TestInvalidDerivedMetrics::test_invalid_derived_metrics\": 43.00805767900056,\n    \"tests/functional/metrics/test_metrics.py::TestInvalidMetricMissingExpression::test_simple_metric\": 44.87452756099992,\n    \"tests/functional/metrics/test_metrics.py::TestInvalidMetricMissingModel::test_simple_metric\": 45.318341484001394,\n    \"tests/functional/metrics/test_metrics.py::TestInvalidRefMetrics::test_simple_metric\": 44.94730245499977,\n    \"tests/functional/metrics/test_metrics.py::TestInvalidTimestampTimeGrainsMetrics::test_simple_metric\": 42.52384508099931,\n    \"tests/functional/metrics/test_metrics.py::TestInvalidTimestampWindowMetrics::test_simple_metric\": 42.79619867999918,\n    \"tests/functional/metrics/test_metrics.py::TestLongName::test_long_name\": 46.66394922699965,\n    \"tests/functional/metrics/test_metrics.py::TestMetricDependsOn::test_metric_depends_on\": 2.2376685339999938,\n    \"tests/functional/metrics/test_metrics.py::TestNamesWithLeandingNumber::test_names_with_leading_number\": 1.4239308189999917,\n    \"tests/functional/metrics/test_metrics.py::TestNamesWithSpaces::test_names_with_spaces\": 44.89969814699998,\n    \"tests/functional/metrics/test_metrics.py::TestNamesWithSpecialChar::test_names_with_special_char\": 43.345890454000255,\n    \"tests/functional/metrics/test_metrics.py::TestSimpleMetrics::test_simple_metric\": 46.22732834999897,\n    \"tests/functional/microbatch/test_microbatch.py::TestCanSilenceInvalidConcurrentBatchesConfigWarning::test_microbatch\": 61.68408309000006,\n    \"tests/functional/microbatch/test_microbatch.py::TestCompilationErrorOnSingleBatchRun::test_microbatch\": 1.871858727000017,\n    \"tests/functional/microbatch/test_microbatch.py::TestFirstAndLastBatchAlwaysSequential::test_microbatch\": 2.093803922999996,\n    \"tests/functional/microbatch/test_microbatch.py::TestFirstBatchRunsPreHookLastBatchRunsPostHook::test_microbatch\": 41.844506328000534,\n    \"tests/functional/microbatch/test_microbatch.py::TestMicrbobatchModelsRunWithSameCurrentTime::test_microbatch\": 42.18878241300081,\n    \"tests/functional/microbatch/test_microbatch.py::TestMicroBatchBoundsDefault::test_run_with_event_time\": 6.730546354000012,\n    \"tests/functional/microbatch/test_microbatch.py::TestMicrobatchBuildRetryUsesOriginalInvocationTime::test_build_retry_uses_original_invocation_time\": 70.73094428600052,\n    \"tests/functional/microbatch/test_microbatch.py::TestMicrobatchCLI::test_run_with_event_time\": 68.55835114899946,\n    \"tests/functional/microbatch/test_microbatch.py::TestMicrobatchCLIBuild::test_run_with_event_time\": 71.50381254700096,\n    \"tests/functional/microbatch/test_microbatch.py::TestMicrobatchCLIRunOutputJSON::test_list_output_json\": 45.817936219999865,\n    \"tests/functional/microbatch/test_microbatch.py::TestMicrobatchCanRunParallelOrSequential::test_microbatch\": 60.2004797970003,\n    \"tests/functional/microbatch/test_microbatch.py::TestMicrobatchCompiledRunPaths::test_run_with_event_time\": 40.059524846000386,\n    \"tests/functional/microbatch/test_microbatch.py::TestMicrobatchCompiledRunPathsHourly::test_run_with_event_time\": 51.14564189500015,\n    \"tests/functional/microbatch/test_microbatch.py::TestMicrobatchCompiledRunPathsMonthly::test_run_with_event_time\": 1.6392900529999963,\n    \"tests/functional/microbatch/test_microbatch.py::TestMicrobatchCompiledRunPathsYearly::test_run_with_event_time\": 38.36248339899885,\n    \"tests/functional/microbatch/test_microbatch.py::TestMicrobatchCustomUserStrategyDefault::test_use_custom_microbatch_strategy_by_default\": 68.46613417200024,\n    \"tests/functional/microbatch/test_microbatch.py::TestMicrobatchCustomUserStrategyProjectFlagTrueNoValidBuiltin::test_use_custom_microbatch_strategy_project_flag_true_invalid_incremental_strategy\": 45.130686196999704,\n    \"tests/functional/microbatch/test_microbatch.py::TestMicrobatchCustomUserStrategyProjectFlagTrueValid::test_use_custom_microbatch_strategy_project_flag_true_invalid_incremental_strategy\": 69.53183550499944,\n    \"tests/functional/microbatch/test_microbatch.py::TestMicrobatchFullRefreshConfigFalse::test_run_with_event_time\": 5.763186471999973,\n    \"tests/functional/microbatch/test_microbatch.py::TestMicrobatchIncrementalBatchFailure::test_run_with_event_time\": 48.143064466000396,\n    \"tests/functional/microbatch/test_microbatch.py::TestMicrobatchInitialBatchFailure::test_run_with_event_time\": 39.21413267099979,\n    \"tests/functional/microbatch/test_microbatch.py::TestMicrobatchJinjaContext::test_run_with_event_time\": 47.27746463999938,\n    \"tests/functional/microbatch/test_microbatch.py::TestMicrobatchJinjaContextVarsAvailable::test_run_with_event_time_logs\": 73.00817411300068,\n    \"tests/functional/microbatch/test_microbatch.py::TestMicrobatchModelSkipped::test_microbatch_model_skipped\": 39.17014909500085,\n    \"tests/functional/microbatch/test_microbatch.py::TestMicrobatchMultipleRetries::test_run_with_event_time\": 4.641316007,\n    \"tests/functional/microbatch/test_microbatch.py::TestMicrobatchRetriesPartialSuccesses::test_run_with_event_time\": 73.61377556299976,\n    \"tests/functional/microbatch/test_microbatch.py::TestMicrobatchRetryUsesOriginalInvocationTime::test_retry_uses_original_invocation_time\": 68.02723471199988,\n    \"tests/functional/microbatch/test_microbatch.py::TestMicrobatchSecondBatchFailure::test_run_with_event_time\": 2.079216145999993,\n    \"tests/functional/microbatch/test_microbatch.py::TestMicrobatchUsingRefRenderSkipsFilter::test_run_with_event_time\": 123.13393394800096,\n    \"tests/functional/microbatch/test_microbatch.py::TestMicrobatchWithInputWithoutEventTime::test_run_with_event_time\": 97.51271705899944,\n    \"tests/functional/microbatch/test_microbatch.py::TestMicrobatchWithSource::test_run_with_event_time\": 168.65866677299982,\n    \"tests/functional/microbatch/test_microbatch.py::TestWhenOnlyOneBatchRunBothPostAndPreHooks::test_microbatch\": 1.6867974120000326,\n    \"tests/functional/microbatch/test_microbatch_config_validation.py::TestInvaliBegiFormatMicrobatch::test_parsing_error_raised\": 49.61423995400037,\n    \"tests/functional/microbatch/test_microbatch_config_validation.py::TestInvaliBeginTypeMicrobatch::test_parsing_error_raised\": 45.681478436999896,\n    \"tests/functional/microbatch/test_microbatch_config_validation.py::TestInvalidBatchSizeMicrobatch::test_parsing_error_raised\": 47.00543480400029,\n    \"tests/functional/microbatch/test_microbatch_config_validation.py::TestInvalidEventTimeMicrobatch::test_parsing_error_raised\": 48.23379116000069,\n    \"tests/functional/microbatch/test_microbatch_config_validation.py::TestInvalidInputEventTimeMicrobatch::test_parsing_error_raised\": 1.5324863220000111,\n    \"tests/functional/microbatch/test_microbatch_config_validation.py::TestMissingBatchSizeMicrobatch::test_parsing_error_raised\": 48.58731079300014,\n    \"tests/functional/microbatch/test_microbatch_config_validation.py::TestMissingBeginMicrobatch::test_parsing_error_raised\": 47.37001400600002,\n    \"tests/functional/microbatch/test_microbatch_config_validation.py::TestMissingEventTimeMicrobatch::test_parsing_error_raised\": 47.727783499,\n    \"tests/functional/microbatch/test_microbatch_config_validation.py::TestValidBeginMicrobatch::test_parsing_error_not_raised\": 42.28735269399931,\n    \"tests/functional/minimal_cli/test_minimal_cli.py::TestBuild::test_build\": 47.305377618999955,\n    \"tests/functional/minimal_cli/test_minimal_cli.py::TestBuildFailFast::test_build\": 47.45623747299942,\n    \"tests/functional/minimal_cli/test_minimal_cli.py::TestBuildFailFastDebug::test_build\": 47.646759803999885,\n    \"tests/functional/minimal_cli/test_minimal_cli.py::TestClean::test_clean\": 20.596570561999215,\n    \"tests/functional/minimal_cli/test_minimal_cli.py::TestCleanUpLevel::test_clean_one_level_up\": 21.4884069360005,\n    \"tests/functional/minimal_cli/test_minimal_cli.py::TestDeps::test_deps\": 21.28391110099892,\n    \"tests/functional/minimal_cli/test_minimal_cli.py::TestDocsGenerate::test_docs_generate\": 3.741823138000001,\n    \"tests/functional/minimal_cli/test_minimal_cli.py::TestLS::test_ls\": 46.929066123000666,\n    \"tests/functional/model_config/test_freshness_config.py::TestModelFreshnessConfig::test_model_freshness_configs\": 67.40153810600077,\n    \"tests/functional/model_config/test_freshness_config.py::TestModelFreshnessConfigParseBuildAfterOnly::test_model_freshness_configs\": 43.433466822999435,\n    \"tests/functional/model_config/test_freshness_config.py::TestModelFreshnessConfigParseBuildCountRequiresPeriod::test_model_freshness_configs\": 1.3362374740000007,\n    \"tests/functional/model_config/test_freshness_config.py::TestModelFreshnessConfigParseBuildPeriodHas0Count::test_model_freshness_configs\": 46.19138921600006,\n    \"tests/functional/model_config/test_freshness_config.py::TestModelFreshnessConfigParseBuildPeriodRequiresCount::test_model_freshness_configs\": 45.27474981100022,\n    \"tests/functional/partial_parsing/test_file_diff.py::TestFileDiffPaths::test_file_diffs\": 4.706529336999978,\n    \"tests/functional/partial_parsing/test_file_diff.py::TestFileDiffs::test_no_file_diffs\": 86.154633784,\n    \"tests/functional/partial_parsing/test_partial_parsing.py::TestExplicitDefaultProfileAndTarget::test_explicit_default_profile_allows_partial_parse\": 2.3602917539999737,\n    \"tests/functional/partial_parsing/test_partial_parsing.py::TestExplicitDefaultProfileAndTarget::test_explicit_default_target_allows_partial_parse\": 52.71984343099939,\n    \"tests/functional/partial_parsing/test_partial_parsing.py::TestExternalModels::test_pp_external_models\": 258.72891292200075,\n    \"tests/functional/partial_parsing/test_partial_parsing.py::TestGenericTests::test_pp_generic_tests\": 102.55774969299819,\n    \"tests/functional/partial_parsing/test_partial_parsing.py::TestMacroDescriptionUpdate::test_pp_macro_description_update\": 99.31729125599941,\n    \"tests/functional/partial_parsing/test_partial_parsing.py::TestModels::test_pp_models\": 788.3676428690005,\n    \"tests/functional/partial_parsing/test_partial_parsing.py::TestNestedMacros::test_nested_macros\": 99.08370542399916,\n    \"tests/functional/partial_parsing/test_partial_parsing.py::TestPartialParsingDependency::test_parsing_with_dependency\": 124.51294739700097,\n    \"tests/functional/partial_parsing/test_partial_parsing.py::TestPortablePartialParsing::test_pp_renamed_project_dir_changed_project_contents\": 5.269835572999966,\n    \"tests/functional/partial_parsing/test_partial_parsing.py::TestPortablePartialParsing::test_pp_renamed_project_dir_unchanged_project_contents\": 132.74717698699897,\n    \"tests/functional/partial_parsing/test_partial_parsing.py::TestProfileChanges::test_profile_change\": 4.173779966000097,\n    \"tests/functional/partial_parsing/test_partial_parsing.py::TestSingularTests::test_pp_singular_tests\": 102.38346065500082,\n    \"tests/functional/partial_parsing/test_partial_parsing.py::TestSkipMacros::test_skip_macros\": 176.99414914099998,\n    \"tests/functional/partial_parsing/test_partial_parsing.py::TestSnapshots::test_pp_snapshots\": 151.79003548199762,\n    \"tests/functional/partial_parsing/test_partial_parsing.py::TestSources::test_pp_sources\": 539.2975181890006,\n    \"tests/functional/partial_parsing/test_pp_disabled_config.py::TestDisabled::test_pp_disabled\": 8.966595016000014,\n    \"tests/functional/partial_parsing/test_pp_docs.py::TestDocs::test_pp_docs\": 222.60327147799762,\n    \"tests/functional/partial_parsing/test_pp_docs.py::TestDocsRemoveReplace::test_remove_replace\": 109.55472164000275,\n    \"tests/functional/partial_parsing/test_pp_functions.py::TestPartialParsingFunctions::test_pp_functions\": 145.96800067899858,\n    \"tests/functional/partial_parsing/test_pp_functions.py::TestPartialParsingFunctionsAndCompilationOfDownstreamNodes::test_pp_functions\": 3.0146560549998185,\n    \"tests/functional/partial_parsing/test_pp_groups.py::TestAddingModelsToNewGroups::test_adding_models_to_new_groups\": 86.44163743399986,\n    \"tests/functional/partial_parsing/test_pp_groups.py::TestGroups::test_pp_groups\": 264.66108741899916,\n    \"tests/functional/partial_parsing/test_pp_metrics.py::TestDeleteFileWithMetricsAndSemanticModels::test_metrics\": 2.6493146839999895,\n    \"tests/functional/partial_parsing/test_pp_metrics.py::TestMetrics::test_metrics\": 174.19377571899895,\n    \"tests/functional/partial_parsing/test_pp_schema_file_order.py::TestMoreNewVersionedSchemaFile::test_more_schema_file_new_versions\": 2.7218378849999,\n    \"tests/functional/partial_parsing/test_pp_schema_file_order.py::TestNewVersionedSchemaFile::test_schema_file_order_new_versions\": 61.595369394000045,\n    \"tests/functional/partial_parsing/test_pp_schema_file_order.py::TestSchemaFileOrder::test_schema_file_order\": 3.7725021889999937,\n    \"tests/functional/partial_parsing/test_pp_schema_file_order.py::TestSourcesAndSchemaFiles::test_schema_file_order_new_versions\": 2.6080510789998925,\n    \"tests/functional/partial_parsing/test_pp_vars.py::TestEnvVars::test_env_vars_models\": 446.3164038140003,\n    \"tests/functional/partial_parsing/test_pp_vars.py::TestProfileEnvVars::test_profile_env_vars\": 3.255825217999984,\n    \"tests/functional/partial_parsing/test_pp_vars.py::TestProfileSecretEnvVars::test_profile_secret_env_vars\": 69.24608755400095,\n    \"tests/functional/partial_parsing/test_pp_vars.py::TestProjectEnvVars::test_project_env_vars\": 64.19450306199906,\n    \"tests/functional/partial_parsing/test_pp_vars.py::TestVarsFileBackwardCompatibility::test_cli_vars_still_trigger_reparse\": 51.06528124800025,\n    \"tests/functional/partial_parsing/test_pp_vars.py::TestVarsFileBackwardCompatibility::test_no_vars_file_hash_unchanged\": 69.65441722599917,\n    \"tests/functional/partial_parsing/test_pp_vars.py::TestVarsFilePartialParsing::test_vars_file_partial_parsing\": 147.1975664800002,\n    \"tests/functional/partial_parsing/test_versioned_models.py::TestAddingVersioningToModel::test_pp_newly_versioned_models\": 64.8301448860002,\n    \"tests/functional/partial_parsing/test_versioned_models.py::TestVersionedModels::test_pp_versioned_models\": 139.65943714700006,\n    \"tests/functional/postgres/test_postgres_indexes.py::TestPostgresIndex::test_incremental\": 67.72614272999908,\n    \"tests/functional/postgres/test_postgres_indexes.py::TestPostgresIndex::test_seed\": 67.8726773190001,\n    \"tests/functional/postgres/test_postgres_indexes.py::TestPostgresIndex::test_snapshot\": 47.1734355159997,\n    \"tests/functional/postgres/test_postgres_indexes.py::TestPostgresIndex::test_table\": 43.63496663800106,\n    \"tests/functional/postgres/test_postgres_indexes.py::TestPostgresInvalidIndex::test_invalid_index_configs\": 45.65219084900036,\n    \"tests/functional/postgres/test_postgres_unlogged_table.py::TestPostgresUnloggedTable::test_postgres_unlogged_table_catalog\": 2.3478930989999753,\n    \"tests/functional/primary_keys/test_primary_keys.py::TestInvalidModelCombinationOfColumns::test_invalid_combo_of_columns\": 45.34590656199907,\n    \"tests/functional/primary_keys/test_primary_keys.py::TestInvalidModelUniqueTest::test_invalid_combo_of_columns\": 45.81897478499923,\n    \"tests/functional/primary_keys/test_primary_keys.py::TestSimpleModelCombinationOfColumns::test_versioned_simple_combo_of_columns\": 46.35722870000063,\n    \"tests/functional/primary_keys/test_primary_keys.py::TestSimpleModelConstraints::test_simple_model_constraints\": 1.724696487999978,\n    \"tests/functional/primary_keys/test_primary_keys.py::TestSimpleModelDisabledUniqueTests::test_simple_model_disabled_unique_test\": 1.978174759000126,\n    \"tests/functional/primary_keys/test_primary_keys.py::TestSimpleModelNoYml::test_simple_model_no_yml\": 44.89601107099952,\n    \"tests/functional/primary_keys/test_primary_keys.py::TestSimpleModelUniqueNotNullTests::test_simple_model_unique_not_null_tests\": 46.50997733700024,\n    \"tests/functional/primary_keys/test_primary_keys.py::TestSimpleModelUniqueTests::test_simple_model_unique_test\": 43.63500108600056,\n    \"tests/functional/primary_keys/test_primary_keys.py::TestVersionedSimpleModel::test_versioned_simple_model\": 43.59115875399948,\n    \"tests/functional/primary_keys/test_primary_keys.py::TestVersionedSimpleModelExcludeTests::test_versioned_simple_model_exclude_col\": 43.683859021999524,\n    \"tests/functional/profiles/test_profile_dir.py::TestProfiles::test_profiles[None-cwd]\": 21.77632990299935,\n    \"tests/functional/profiles/test_profile_dir.py::TestProfiles::test_profiles[None-cwd_child]\": 0.200592833999508,\n    \"tests/functional/profiles/test_profile_dir.py::TestProfiles::test_profiles[cwd-cwd_parent]\": 0.2147362299992892,\n    \"tests/functional/profiles/test_profile_dir.py::TestProfilesMayNotExist::test_debug\": 21.4974419880009,\n    \"tests/functional/profiles/test_profile_dir.py::TestProfilesMayNotExist::test_deps\": 0.04147706699950504,\n    \"tests/functional/profiles/test_profiles_yml.py::TestProfileParsing::test_password_jinja_rendered_when_valid\": 21.808817881999857,\n    \"tests/functional/profiles/test_profiles_yml.py::TestProfileParsing::test_password_not_jinja_rendered_when_invalid\": 43.81759927100029,\n    \"tests/functional/record/test_record.py::TestRecord::test_record_when_env_var_set\": 1.696933209000008,\n    \"tests/functional/ref_override/test_ref_override.py::TestAdvancedRefOverride::test_ref_override\": 45.67821476099925,\n    \"tests/functional/ref_override/test_ref_override.py::TestRefOverride::test_ref_override\": 68.1015033879994,\n    \"tests/functional/relation_names/test_relation_name.py::TestGeneratedDDLNameRules::test_long_name_passes_when_temp_tables_are_generated\": 46.6261673680001,\n    \"tests/functional/relation_names/test_relation_name.py::TestGeneratedDDLNameRules::test_name_longer_than_63_does_not_build\": 23.91877252700033,\n    \"tests/functional/relation_names/test_relation_name.py::TestGeneratedDDLNameRules::test_name_shorter_or_equal_to_63_passes\": 3.2090369700000565,\n    \"tests/functional/relation_quoting/test_relation_quoting.py::TestModelQuoting::test_models_respect_global_quoting_configs\": 45.658229018000384,\n    \"tests/functional/relation_quoting/test_relation_quoting.py::TestSourceQuotingGlobalConfigs::test_sources_ignore_global_quoting_configs\": 46.12762554700112,\n    \"tests/functional/retry/test_retry.py::TestCustomTargetRetry::test_custom_target\": 116.06044083400047,\n    \"tests/functional/retry/test_retry.py::TestFailFast::test_fail_fast\": 171.2848509889991,\n    \"tests/functional/retry/test_retry.py::TestFixRetryHook::test_fix_retry_hook\": 4.817213597999995,\n    \"tests/functional/retry/test_retry.py::TestRetryFullRefresh::test_retry\": 74.58556281700021,\n    \"tests/functional/retry/test_retry.py::TestRetryHooksAlwaysRun::test_retry_hooks_always_run\": 71.02669113800039,\n    \"tests/functional/retry/test_retry.py::TestRetryNoPreviousRun::test_no_previous_run\": 23.034873092999987,\n    \"tests/functional/retry/test_retry.py::TestRetryOverridePath::test_retry\": 75.07155892500123,\n    \"tests/functional/retry/test_retry.py::TestRetryPreviousRun::test_previous_run\": 119.87423673899957,\n    \"tests/functional/retry/test_retry.py::TestRetryRemovedFile::test_removed_file\": 71.81053844799953,\n    \"tests/functional/retry/test_retry.py::TestRetryRemovedFileLeafNode::test_removed_file_leaf_node\": 3.2423468590000084,\n    \"tests/functional/retry/test_retry.py::TestRetryResourceType::test_resource_type\": 7.608399299999974,\n    \"tests/functional/retry/test_retry.py::TestRetryRunOperation::test_run_operation\": 71.79979037399971,\n    \"tests/functional/retry/test_retry.py::TestRetrySuccessfulRunOperation::test_run_operation\": 72.19161405999967,\n    \"tests/functional/retry/test_retry.py::TestRetryTargetPathEnvVar::test_retry_target_path_env_var\": 3.576095366000004,\n    \"tests/functional/retry/test_retry.py::TestRetryTargetPathFlag::test_retry_target_path_flag\": 70.39241419799964,\n    \"tests/functional/retry/test_retry.py::TestRetryVars::test_retry\": 125.70006368599934,\n    \"tests/functional/retry/test_retry.py::TestRetryWarnError::test_warn_error\": 119.3829443249997,\n    \"tests/functional/retry/test_retry_threads.py::TestCustomThreadRetry::test_thread_target\": 120.06287057600002,\n    \"tests/functional/run_operations/test_run_operations.py::TestOperations::test_access_graph\": 24.204537547000655,\n    \"tests/functional/run_operations/test_run_operations.py::TestOperations::test_cannot_connect\": 24.515961968001648,\n    \"tests/functional/run_operations/test_run_operations.py::TestOperations::test_macro_args\": 2.457786069000008,\n    \"tests/functional/run_operations/test_run_operations.py::TestOperations::test_macro_exception\": 24.417227221999383,\n    \"tests/functional/run_operations/test_run_operations.py::TestOperations::test_macro_missing\": 24.187153555000805,\n    \"tests/functional/run_operations/test_run_operations.py::TestOperations::test_macro_noargs\": 48.49152819699975,\n    \"tests/functional/run_operations/test_run_operations.py::TestOperations::test_print\": 24.016194951000216,\n    \"tests/functional/run_operations/test_run_operations.py::TestOperations::test_run_operation_local_macro\": 48.87421876600001,\n    \"tests/functional/run_operations/test_run_operations.py::TestOperations::test_select\": 23.988189263000095,\n    \"tests/functional/run_operations/test_run_operations.py::TestOperations::test_vacuum\": 2.6348533470000177,\n    \"tests/functional/run_operations/test_run_operations.py::TestOperations::test_vacuum_ref\": 48.58166951699968,\n    \"tests/functional/run_operations/test_run_operations.py::TestRunOperationRefPrivateModel::test_run_operation_ref_private_model\": 73.2422541599999,\n    \"tests/functional/run_query/test_types.py::TestTypes::test_nested_types\": 48.74362838399975,\n    \"tests/functional/sample_mode/test_sample_mode.py::TestBasicSampleMode::test_sample_mode[build-False-3]\": 25.79151833600008,\n    \"tests/functional/sample_mode/test_sample_mode.py::TestBasicSampleMode::test_sample_mode[build-True-2]\": 25.86342170700118,\n    \"tests/functional/sample_mode/test_sample_mode.py::TestBasicSampleMode::test_sample_mode[run-False-3]\": 26.124693912998737,\n    \"tests/functional/sample_mode/test_sample_mode.py::TestBasicSampleMode::test_sample_mode[run-True-2]\": 50.47248202400078,\n    \"tests/functional/sample_mode/test_sample_mode.py::TestIncrementalModelSampleModeRelative::test_incremental_model_sample[2 days-5]\": 3.4631214850000163,\n    \"tests/functional/sample_mode/test_sample_mode.py::TestIncrementalModelSampleModeRelative::test_incremental_model_sample[3 days-6]\": 5.097192252000127,\n    \"tests/functional/sample_mode/test_sample_mode.py::TestIncrementalModelSampleModeRelative::test_incremental_model_sample[None-6]\": 77.59621588499976,\n    \"tests/functional/sample_mode/test_sample_mode.py::TestIncrementalModelSampleModeSpecific::test_incremental_model_sample[None-6]\": 77.27440746000048,\n    \"tests/functional/sample_mode/test_sample_mode.py::TestIncrementalModelSampleModeSpecific::test_incremental_model_sample[{'start': '2024-12-31', 'end': '2025-01-03'}-3]\": 52.76324909700088,\n    \"tests/functional/sample_mode/test_sample_mode.py::TestIncrementalModelSampleModeSpecific::test_incremental_model_sample[{'start': '2025-01-03', 'end': '2025-01-07'}-6]\": 52.25839509399884,\n    \"tests/functional/sample_mode/test_sample_mode.py::TestIncrementalModelSampleModeSpecific::test_incremental_model_sample[{'start': '2025-01-04', 'end': '2025-01-06'}-5]\": 52.672793392999665,\n    \"tests/functional/sample_mode/test_sample_mode.py::TestIncrementalModelSampleModeSpecific::test_incremental_model_sample[{'start': '2025-01-05', 'end': '2025-01-07'}-5]\": 52.79645216499921,\n    \"tests/functional/sample_mode/test_sample_mode.py::TestMicrobatchSampleMode::test_sample_mode\": 52.2563432930001,\n    \"tests/functional/sample_mode/test_sample_mode.py::TestSampleSeedRefs::test_sample_mode[False-3]\": 52.943739364000066,\n    \"tests/functional/sample_mode/test_sample_mode.py::TestSampleSeedRefs::test_sample_mode[True-2]\": 79.07742516700091,\n    \"tests/functional/sample_mode/test_sample_mode.py::TestSamplingModelFromSnapshot::test_sample_mode[False-3]\": 26.734211156997844,\n    \"tests/functional/sample_mode/test_sample_mode.py::TestSamplingModelFromSnapshot::test_sample_mode[True-2]\": 52.99888501199894,\n    \"tests/functional/sample_mode/test_sample_mode.py::TestSamplingSnapshot::test_sample_mode[False-3]\": 54.98123550700075,\n    \"tests/functional/sample_mode/test_sample_mode.py::TestSamplingSnapshot::test_sample_mode[True-2]\": 4.526776116000065,\n    \"tests/functional/saved_queries/test_configs.py::TestExportConfigsWithAdditionalProperties::test_extra_config_properties_dont_break_parsing\": 53.78055426600076,\n    \"tests/functional/saved_queries/test_configs.py::TestExportConfigsWithDefaultProperties::test_default_properties\": 54.029888948001826,\n    \"tests/functional/saved_queries/test_configs.py::TestInheritingExportConfigFromSavedQueryConfig::test_export_config_inherits_from_saved_query\": 54.18072945200038,\n    \"tests/functional/saved_queries/test_configs.py::TestInheritingExportConfigsFromProject::test_export_config_inherits_from_project\": 82.06402399099898,\n    \"tests/functional/saved_queries/test_configs.py::TestSavedQueryCacheConfigsOverride::test_override_saved_query_config\": 82.90522774700185,\n    \"tests/functional/saved_queries/test_configs.py::TestSavedQueryConfigs::test_basic_saved_query_config\": 80.25600244999987,\n    \"tests/functional/saved_queries/test_configs.py::TestSavedQueryDefaultCacheConfigs::test_basic_saved_query_config\": 53.4602600420003,\n    \"tests/functional/saved_queries/test_configs.py::TestSavedQueryLevelCacheConfigs::test_basic_saved_query_config\": 2.914733303000048,\n    \"tests/functional/saved_queries/test_configs.py::TestSavedQueryTagsAdditiveWithConfig::test_saved_query_tags_are_additive_unique_and_sorted\": 55.44608239599984,\n    \"tests/functional/saved_queries/test_saved_query_build.py::TestSavedQueryBuild::test_build_saved_queries_no_op\": 57.6194285499987,\n    \"tests/functional/saved_queries/test_saved_query_parsing.py::TestSavedQueryParsing::test_saved_query_error\": 30.86176200099908,\n    \"tests/functional/saved_queries/test_saved_query_parsing.py::TestSavedQueryParsing::test_semantic_model_parsing\": 142.43535239000084,\n    \"tests/functional/saved_queries/test_saved_query_parsing.py::TestSavedQueryParsing::test_semantic_model_parsing_change_export\": 112.44188117900012,\n    \"tests/functional/saved_queries/test_saved_query_parsing.py::TestSavedQueryParsing::test_semantic_model_parsing_with_default_schema\": 85.96519105900006,\n    \"tests/functional/saved_queries/test_saved_query_parsing.py::TestSavedQueryPartialParsing::test_saved_query_deleted_partial_parsing\": 3.5346529350000253,\n    \"tests/functional/saved_queries/test_saved_query_parsing.py::TestSavedQueryPartialParsing::test_saved_query_filter_types\": 48.3649142080003,\n    \"tests/functional/saved_queries/test_saved_query_parsing.py::TestSavedQueryPartialParsing::test_saved_query_metrics_changed\": 48.350282712999615,\n    \"tests/functional/schema/test_custom_schema.py::TestCustomSchema::test__postgres_handles__custom_schema_with_no_prefix\": 74.68811275500047,\n    \"tests/functional/schema/test_custom_schema.py::TestCustomSchemaWithCustomMacro::test__postgres_handles__custom_schema_with_custom_macro\": 75.236483701,\n    \"tests/functional/schema/test_custom_schema.py::TestCustomSchemaWithCustomMacroFromModelName::test__postgres__custom_schema_from_model_name\": 74.71315013700041,\n    \"tests/functional/schema/test_custom_schema.py::TestCustomSchemaWithPrefix::test__postgres__custom_schema_with_prefix\": 74.8875480200004,\n    \"tests/functional/schema/test_custom_schema.py::TestCustomSchemaWithPrefixAndDispatch::test__postgres__custom_schema_with_prefix_and_dispatch\": 75.57450148299995,\n    \"tests/functional/schema_tests/test_custom_test_config.py::TestCustomDataTestConfig::test_custom_config\": 126.26984981900023,\n    \"tests/functional/schema_tests/test_custom_test_config.py::TestMixedDataTestConfig::test_mixed_config\": 2.911730610000035,\n    \"tests/functional/schema_tests/test_custom_test_config.py::TestSameKeyErrorDataTestConfig::test_same_key_error\": 50.064547424999546,\n    \"tests/functional/schema_tests/test_schema_v2_tests.py::TestCliVarsSchemaTests::test_argument_rendering\": 3.8451073310000083,\n    \"tests/functional/schema_tests/test_schema_v2_tests.py::TestCommentedSchema::test_quoted_schema_file\": 57.83621720500014,\n    \"tests/functional/schema_tests/test_schema_v2_tests.py::TestConfiguredVarsSchemaTests::test_argument_rendering\": 81.6006363939996,\n    \"tests/functional/schema_tests/test_schema_v2_tests.py::TestCustomConfigSchemaTests::test_config\": 53.53599410499919,\n    \"tests/functional/schema_tests/test_schema_v2_tests.py::TestCustomSchemaTestMacroResolutionOrder::test_macro_resolution_test_namespace\": 71.21326666999994,\n    \"tests/functional/schema_tests/test_schema_v2_tests.py::TestCustomSchemaTests::test_schema_tests\": 81.92847736500153,\n    \"tests/functional/schema_tests/test_schema_v2_tests.py::TestDefaultBoolType::test_limit_schema_tests\": 78.17487069100025,\n    \"tests/functional/schema_tests/test_schema_v2_tests.py::TestGenericTestsCollide::test_generic_test_collision\": 1.43436082300002,\n    \"tests/functional/schema_tests/test_schema_v2_tests.py::TestGenericTestsConfigCustomMacros::test_generic_test_config_custom_macros\": 2.647578959999919,\n    \"tests/functional/schema_tests/test_schema_v2_tests.py::TestGenericTestsCustomNames::test_generic_tests_with_custom_names\": 86.8407421410011,\n    \"tests/functional/schema_tests/test_schema_v2_tests.py::TestGenericTestsCustomNamesAltFormat::test_collision_test_names_get_hash\": 57.46952650899766,\n    \"tests/functional/schema_tests/test_schema_v2_tests.py::TestGenericTestsCustomNamesAltFormat::test_generic_tests_with_custom_names\": 85.75782510700083,\n    \"tests/functional/schema_tests/test_schema_v2_tests.py::TestHooksForWhich::test_these_hooks_dont_run_for_tests\": 53.37430147099985,\n    \"tests/functional/schema_tests/test_schema_v2_tests.py::TestHooksInTests::test_hooks_do_run_for_tests\": 53.391112824998345,\n    \"tests/functional/schema_tests/test_schema_v2_tests.py::TestInvalidSchema::test_invalid_schema_file\": 56.53393813800176,\n    \"tests/functional/schema_tests/test_schema_v2_tests.py::TestLimitedSchemaTests::test_limit_schema_tests\": 78.90498587799993,\n    \"tests/functional/schema_tests/test_schema_v2_tests.py::TestMalformedSchemaTests::test_malformed_schema_will_break_run\": 2.0592564070000208,\n    \"tests/functional/schema_tests/test_schema_v2_tests.py::TestNonBoolType::test_limit_schema_tests\": 79.32257230800133,\n    \"tests/functional/schema_tests/test_schema_v2_tests.py::TestOtherBoolType::test_limit_schema_tests\": 4.101005440000108,\n    \"tests/functional/schema_tests/test_schema_v2_tests.py::TestQuotedSchemaTestColumns::test_quote_required_column\": 192.117170988,\n    \"tests/functional/schema_tests/test_schema_v2_tests.py::TestSchemaCaseInsensitive::test_schema_lowercase_sql\": 85.17666384699987,\n    \"tests/functional/schema_tests/test_schema_v2_tests.py::TestSchemaCaseInsensitive::test_schema_uppercase_sql\": 59.38734428299904,\n    \"tests/functional/schema_tests/test_schema_v2_tests.py::TestSchemaTestContext::test_test_context_tests\": 88.95719864700004,\n    \"tests/functional/schema_tests/test_schema_v2_tests.py::TestSchemaTestContextWhereSubq::test_test_context_tests\": 90.77868880499773,\n    \"tests/functional/schema_tests/test_schema_v2_tests.py::TestSchemaTestContextWithMacroNamespace::test_test_context_with_macro_namespace\": 86.15032830300152,\n    \"tests/functional/schema_tests/test_schema_v2_tests.py::TestSchemaTestNameCollision::test_collision_test_names_get_hash\": 88.17785598999944,\n    \"tests/functional/schema_tests/test_schema_v2_tests.py::TestSchemaTestStoreFailuresFalseHierarchicalParsing::test_parse_store_failures_False_as_ephemeral\": 50.428101429999515,\n    \"tests/functional/schema_tests/test_schema_v2_tests.py::TestSchemaTestStoreFailuresFalseParsing::test_parse_store_failures_False_as_ephemeral\": 59.855075478997605,\n    \"tests/functional/schema_tests/test_schema_v2_tests.py::TestSchemaTestStoreFailuresTrueHierarchicalParsing::test_parse_store_failures_True_as_table\": 62.23745480099933,\n    \"tests/functional/schema_tests/test_schema_v2_tests.py::TestSchemaTestStoreFailuresTrueParsing::test_parse_store_failures_True_as_table\": 62.89721251100127,\n    \"tests/functional/schema_tests/test_schema_v2_tests.py::TestSchemaTests::test_schema_test_exclude_failures\": 79.41838097099935,\n    \"tests/functional/schema_tests/test_schema_v2_tests.py::TestSchemaTests::test_schema_test_selection\": 103.27117732000079,\n    \"tests/functional/schema_tests/test_schema_v2_tests.py::TestSchemaTests::test_schema_tests\": 78.74014660999819,\n    \"tests/functional/schema_tests/test_schema_v2_tests.py::TestWrongSpecificationBlock::test_wrong_specification_block\": 57.86932584399983,\n    \"tests/functional/schema_tests/test_sql_header_config.py::TestGenericDataTestSqlHeader::test_generic_test_sql_header_in_config\": 4.531009937999954,\n    \"tests/functional/schema_tests/test_sql_header_config.py::TestGenericDataTestSqlHeaderDeprecation::test_sql_header_deprecation_warning\": 2.883126579999953,\n    \"tests/functional/schema_tests/test_sql_header_config.py::TestSingularDataTestSqlHeader::test_singular_test_sql_header_in_config\": 4.509966480000031,\n    \"tests/functional/seeds/test_seed_column_type_validation.py::TestSeedColumnTypeValidation::test_seed_with_invalid_column_type\": 51.2292724859999,\n    \"tests/functional/seeds/test_seed_column_type_validation.py::TestSeedColumnTypesBasic::test_seed_basic_column_types\": 50.926622969000164,\n    \"tests/functional/seeds/test_seed_column_type_validation.py::TestSeedColumnTypesWithMismatchedColumns::test_seed_invalid_column_type_warning\": 50.93689672000073,\n    \"tests/functional/selected_resources/test_selected_resources.py::TestSelectedResources::test_selected_resources_build_no_model\": 53.66736683400086,\n    \"tests/functional/selected_resources/test_selected_resources.py::TestSelectedResources::test_selected_resources_build_no_selector\": 54.28850211899953,\n    \"tests/functional/selected_resources/test_selected_resources.py::TestSelectedResources::test_selected_resources_build_selector\": 78.13948855799754,\n    \"tests/functional/selected_resources/test_selected_resources.py::TestSelectedResources::test_selected_resources_build_selector_subgraph\": 7.200015626000095,\n    \"tests/functional/selected_resources/test_selected_resources.py::TestSelectedResources::test_selected_resources_run\": 53.82875841199893,\n    \"tests/functional/selected_resources/test_selected_resources.py::TestSelectedResources::test_selected_resources_test_no_model\": 53.650677725001515,\n    \"tests/functional/selectors/test_default_selectors.py::TestDefaultSelectors::test_model__compile\": 26.289786381998056,\n    \"tests/functional/selectors/test_default_selectors.py::TestDefaultSelectors::test_model__list\": 1.909087535000026,\n    \"tests/functional/selectors/test_default_selectors.py::TestDefaultSelectors::test_source__freshness\": 52.77334636299747,\n    \"tests/functional/semantic_models/test_semantic_model_configs.py::TestConfigProjectLevel::test_project_level\": 107.87842063700009,\n    \"tests/functional/semantic_models/test_semantic_model_configs.py::TestConfigYamlLevel::test_yaml_level\": 52.55584869499944,\n    \"tests/functional/semantic_models/test_semantic_model_configs.py::TestConfigsInheritence::test_project_plus_yaml_level\": 53.62267729099949,\n    \"tests/functional/semantic_models/test_semantic_model_configs.py::TestDisabledConfigYamlLevelEnabledMetric::test_yaml_level\": 52.42467463399953,\n    \"tests/functional/semantic_models/test_semantic_model_configs.py::TestMetaConfig::test_meta_config\": 53.81915100100014,\n    \"tests/functional/semantic_models/test_semantic_model_configs.py::TestMetaConfigClobbering::test_meta_config_clobbering\": 54.51973961499971,\n    \"tests/functional/semantic_models/test_semantic_model_configs.py::TestMetaConfigForComponents::test_component_meta_configs\": 54.46486899999945,\n    \"tests/functional/semantic_models/test_semantic_model_configs.py::TestMismatchesConfigProjectLevel::test_project_level\": 79.81348215199978,\n    \"tests/functional/semantic_models/test_semantic_model_parsing.py::TestSemanticModelParsingErrors::test_semantic_model_error\": 54.541676401000586,\n    \"tests/functional/semantic_models/test_semantic_model_parsing.py::TestSemanticModelParsingForConversionMetrics::test_conversion_metric_parsing\": 54.95357054500164,\n    \"tests/functional/semantic_models/test_semantic_model_parsing.py::TestSemanticModelParsingForCumulativeMetrics::test_cumulative_metric_parsing\": 54.55886833600198,\n    \"tests/functional/semantic_models/test_semantic_model_parsing.py::TestSemanticModelParsingForDerivedMetrics::test_derived_metric_parsing\": 2.266845902,\n    \"tests/functional/semantic_models/test_semantic_model_parsing.py::TestSemanticModelParsingForRatioMetrics::test_ratio_metric_parsing\": 55.11394714800008,\n    \"tests/functional/semantic_models/test_semantic_model_parsing.py::TestSemanticModelParsingWorks::test_semantic_model_parsing\": 55.46526735899897,\n    \"tests/functional/semantic_models/test_semantic_model_parsing.py::TestSemanticModelPartialParsingGeneratedMetrics::test_generated_metrics\": 85.9822180889987,\n    \"tests/functional/semantic_models/test_semantic_model_parsing.py::TestSemanticModelPartialParsingWithModelChanged::test_semantic_model_changed_partial_parsing\": 2.5982234340000048,\n    \"tests/functional/semantic_models/test_semantic_model_parsing.py::TestSemanticModelPartialParsingWithModelDeletedIteratively::test_semantic_model_deleted_partial_parsing\": 4.450409737000001,\n    \"tests/functional/semantic_models/test_semantic_model_parsing.py::TestSemanticModelPartialParsingWithModelFlippingCreateMetric::test_semantic_model_flipping_create_metric_partial_parsing\": 116.06417013899954,\n    \"tests/functional/semantic_models/test_semantic_model_v2_parsing.py::TestConversionMetricNoBaseMetricFails::test_conversion_metric_no_base_metric_parsing_fails\": 58.117637699000625,\n    \"tests/functional/semantic_models/test_semantic_model_v2_parsing.py::TestCumulativeMetricNoInputMetricFails::test_cumulative_metric_no_input_metric_parsing_fails\": 58.761033264001526,\n    \"tests/functional/semantic_models/test_semantic_model_v2_parsing.py::TestDerivedMetricWithInputMetricsFilterDimensionJinja::test_input_metrics_filter_jinja_not_rendered\": 2.15318450700002,\n    \"tests/functional/semantic_models/test_semantic_model_v2_parsing.py::TestDerivedSemanticsParsingWorks::test_derived_semantics_parsing\": 60.010480524999366,\n    \"tests/functional/semantic_models/test_semantic_model_v2_parsing.py::TestDerivedSemanticsWithDocJinjaParsingWorks::test_derived_semantics_doc_jinja_parsing\": 59.43265880900253,\n    \"tests/functional/semantic_models/test_semantic_model_v2_parsing.py::TestMetricHiddenMapsToIsPrivate::test_metric_hidden_yaml_maps_to_is_private\": 62.697041161000016,\n    \"tests/functional/semantic_models/test_semantic_model_v2_parsing.py::TestMetricOnModelParsingWorks::test_metric_on_model_parsing\": 58.188376295000126,\n    \"tests/functional/semantic_models/test_semantic_model_v2_parsing.py::TestMetricOnModelWithCustomSemanticModelName::test_metrics_use_custom_semantic_model_name\": 58.923796237000715,\n    \"tests/functional/semantic_models/test_semantic_model_v2_parsing.py::TestMetricOnModelWithoutCustomSemanticModelName::test_metrics_use_model_name_as_semantic_model_name\": 60.50950170999931,\n    \"tests/functional/semantic_models/test_semantic_model_v2_parsing.py::TestRatioMetricWithNumeratorFilterDimensionJinja::test_numerator_filter_jinja_not_rendered\": 59.21252180999909,\n    \"tests/functional/semantic_models/test_semantic_model_v2_parsing.py::TestSemanticModelConfigDefaultValues::test_semantic_model_parsing_defaults\": 56.969397938999464,\n    \"tests/functional/semantic_models/test_semantic_model_v2_parsing.py::TestSemanticModelConfigDoesNotExistPassesWithoutParsingSemanticModel::test_semantic_model_parsing\": 57.2150586129992,\n    \"tests/functional/semantic_models/test_semantic_model_v2_parsing.py::TestSemanticModelConfigOverrides::test_semantic_model_parsing\": 57.09212184199896,\n    \"tests/functional/semantic_models/test_semantic_model_v2_parsing.py::TestSemanticModelDisabledConfigIsNotParsed::test_semantic_model_parsing\": 57.497695056998054,\n    \"tests/functional/semantic_models/test_semantic_model_v2_parsing.py::TestSemanticModelFalseConfigIsNotParsed::test_semantic_model_parsing\": 57.99841862699941,\n    \"tests/functional/semantic_models/test_semantic_model_v2_parsing.py::TestSemanticModelParsingWorks::test_semantic_model_parsing\": 57.226948847999665,\n    \"tests/functional/semantic_models/test_semantic_model_v2_parsing.py::TestSemanticModelWithPrimaryEntityOnlyOnColumn::test_primary_entity_type_is_id_entity\": 58.07909940200079,\n    \"tests/functional/semantic_models/test_semantic_model_v2_parsing.py::TestSemanticModelWithPrimaryEntityOnlyOnModel::test_primary_entities_empty\": 1.6640911149999624,\n    \"tests/functional/semantic_models/test_semantic_model_v2_parsing.py::TestSimpleSemanticModelWithFilterWithFilterDimensionJinja::test_simple_metric_with_filter_with_filter_dimension_jinja_parsing\": 58.12395009099964,\n    \"tests/functional/semantic_models/test_semantic_model_v2_parsing.py::TestSimpleSemanticModelWithMetricWithDocJinja::test_simple_metric_with_doc_jinja_parsing\": 58.23097795800277,\n    \"tests/functional/semantic_models/test_semantic_model_v2_parsing.py::TestStandaloneMetricParsingSimpleMetricFails::test_standalone_metric_parsing\": 58.324286273000325,\n    \"tests/functional/semantic_models/test_semantic_model_v2_parsing.py::TestStandaloneMetricParsingWorks::test_included_metric_parsing\": 60.19740994200038,\n    \"tests/functional/semantic_models/test_semantic_model_v2_parsing.py::TestTopLevelSemanticsMetricWithDocJinja::test_top_level_metric_with_doc_jinja_parsing\": 58.45057118499972,\n    \"tests/functional/semantic_models/test_semantic_models.py::TestSemanticModelDependsOn::test_depends_on\": 66.67487448200154,\n    \"tests/functional/semantic_models/test_semantic_models.py::TestSemanticModelNestedDocs::test_depends_on\": 71.11769534000086,\n    \"tests/functional/semantic_models/test_semantic_models.py::TestSemanticModelPartialParsing::test_semantic_model_deleted_partial_parsing\": 93.21674462900046,\n    \"tests/functional/semantic_models/test_semantic_models.py::TestSemanticModelUnknownModel::test_unknown_model_raises_issue\": 62.31814279300124,\n    \"tests/functional/severity/test_severity.py::TestSeverity::test_generic_default\": 130.218340368001,\n    \"tests/functional/severity/test_severity.py::TestSeverity::test_generic_strict\": 31.606054487998335,\n    \"tests/functional/severity/test_severity.py::TestSeverity::test_singular_default\": 31.275115849999565,\n    \"tests/functional/severity/test_severity.py::TestSeverity::test_singular_strict\": 31.3837903929998,\n    \"tests/functional/show/test_show.py::TestShowEphemeral::test_ephemeral_model\": 4.770717013999985,\n    \"tests/functional/show/test_show.py::TestShowInline::test_inline_pass\": 6.029213085999999,\n    \"tests/functional/show/test_show.py::TestShowInline::test_inline_pass_quiet\": 11.347032066999986,\n    \"tests/functional/show/test_show.py::TestShowInlineDirect::test_inline_direct_pass\": 4.049902450000019,\n    \"tests/functional/show/test_show.py::TestShowInlineDirect::test_inline_direct_pass_no_limit\": 61.50709874000131,\n    \"tests/functional/show/test_show.py::TestShowInlineDirect::test_inline_direct_pass_quiet\": 5.852711741000036,\n    \"tests/functional/show/test_show.py::TestShowInlineDirectFail::test_inline_fail_database_error\": 124.03751825400104,\n    \"tests/functional/show/test_show.py::TestShowInlineFail::test_inline_fail\": 8.619599016000052,\n    \"tests/functional/show/test_show.py::TestShowInlineFailDB::test_inline_fail_database_error\": 106.22149159899891,\n    \"tests/functional/show/test_show.py::TestShowModelVersions::test_none\": 4.215083011000019,\n    \"tests/functional/show/test_show.py::TestShowModelVersions::test_version_unspecified\": 92.36847730299996,\n    \"tests/functional/show/test_show.py::TestShowMultiple::test_select_multiple_model_text\": 125.00628722700094,\n    \"tests/functional/show/test_show.py::TestShowNone::test_none\": 95.32680707100008,\n    \"tests/functional/show/test_show.py::TestShowNumeric::test_numeric_values\": 4.443285828000029,\n    \"tests/functional/show/test_show.py::TestShowNumericNulls::test_numeric_values_with_nulls\": 5.245788030999989,\n    \"tests/functional/show/test_show.py::TestShowPrivateModel::test_version_unspecified\": 91.5191681999986,\n    \"tests/functional/show/test_show.py::TestShowSecondEphemeral::test_second_ephemeral_model\": 121.40478020699993,\n    \"tests/functional/show/test_show.py::TestShowSeed::test_seed\": 96.91076028799944,\n    \"tests/functional/show/test_show.py::TestShowSelectText::test_select_model_text\": 4.6676790470000356,\n    \"tests/functional/show/test_show.py::TestShowSingle::test_select_single_model_json\": 128.0744835969981,\n    \"tests/functional/show/test_show.py::TestShowSingle::test_select_single_model_json_quiet\": 10.623800169999981,\n    \"tests/functional/snapshots/test_basic_snapshot.py::TestBasicCheckCols::test_basic_snapshot\": 172.89177853699948,\n    \"tests/functional/snapshots/test_basic_snapshot.py::TestBasicConfiguredCheckCols::test_configured_snapshot\": 181.45321795200107,\n    \"tests/functional/snapshots/test_basic_snapshot.py::TestBasicCustomNamespace::test_custom_namespace_snapshot\": 175.5347446980013,\n    \"tests/functional/snapshots/test_basic_snapshot.py::TestBasicCustomSnapshot::test_custom_snapshot\": 173.7060016659998,\n    \"tests/functional/snapshots/test_basic_snapshot.py::TestBasicRef::test_basic_ref\": 91.49162472399985,\n    \"tests/functional/snapshots/test_basic_snapshot.py::TestBasicSnapshot::test_basic_snapshot\": 156.3946062310024,\n    \"tests/functional/snapshots/test_basic_snapshot.py::TestBasicSnapshotYaml::test_basic_snapshot_yaml\": 177.77988468200056,\n    \"tests/functional/snapshots/test_basic_snapshot.py::TestBasicTargetSchemaConfig::test_target_schema\": 101.70318581700121,\n    \"tests/functional/snapshots/test_basic_snapshot.py::TestBasicUpdatedAtCheckCols::test_updated_at_snapshot\": 178.51089828399745,\n    \"tests/functional/snapshots/test_basic_snapshot.py::TestRefCheckCols::test_check_cols_ref\": 104.2334418290011,\n    \"tests/functional/snapshots/test_basic_snapshot.py::TestRefConfiguredCheckCols::test_configured_ref\": 109.90203640600157,\n    \"tests/functional/snapshots/test_basic_snapshot.py::TestRefCustomNamespace::test_custom_namespace_ref\": 101.03401411400046,\n    \"tests/functional/snapshots/test_basic_snapshot.py::TestRefCustomSnapshot::test_custom_ref\": 100.64102044499668,\n    \"tests/functional/snapshots/test_basic_snapshot.py::TestRefUpdatedAtCheckCols::test_updated_at_ref\": 7.190862178000003,\n    \"tests/functional/snapshots/test_basic_snapshot.py::TestYamlSnapshotCompiledPath::test_compiled_path\": 3.4207499540000015,\n    \"tests/functional/snapshots/test_basic_snapshot.py::TestYamlSnapshotPartialParsing::test_snapshot_partial_parsing\": 174.00180803200237,\n    \"tests/functional/snapshots/test_changing_check_cols_snapshot.py::test_check_cols_snapshot_with_schema_change\": 176.6575279610006,\n    \"tests/functional/snapshots/test_changing_check_cols_snapshot.py::test_check_cols_snapshot_with_schema_change_and_mismatched_casing\": 179.87189774700164,\n    \"tests/functional/snapshots/test_changing_strategy_snapshot.py::test_changing_strategy\": 185.9991333229991,\n    \"tests/functional/snapshots/test_check_cols_snapshot.py::test_snapshots\": 196.49388197100052,\n    \"tests/functional/snapshots/test_check_cols_updated_at_snapshot.py::test_snapshots\": 179.94832851899992,\n    \"tests/functional/snapshots/test_comment_ending_snapshot.py::TestSnapshotsWithCommentAtEnd::test_comment_ending\": 102.8516368460023,\n    \"tests/functional/snapshots/test_cross_schema_snapshot.py::test_cross_schema_snapshot\": 90.97828131400092,\n    \"tests/functional/snapshots/test_hard_delete_snapshot.py::test_snapshot_hard_delete\": 127.98918425499869,\n    \"tests/functional/snapshots/test_invalid_namespace_snapshot.py::test_custom_snapshot_invalid_namespace\": 59.70147741200162,\n    \"tests/functional/snapshots/test_long_text_snapshot.py::test_long_text\": 5.868144018000066,\n    \"tests/functional/snapshots/test_missing_strategy_snapshot.py::test_missing_strategy\": 59.14913008400072,\n    \"tests/functional/snapshots/test_renamed_source_snapshot.py::test_renamed_source\": 127.87966662799954,\n    \"tests/functional/snapshots/test_select_exclude_snapshot.py::TestAllBasic::test_all_snapshots\": 94.00559290299861,\n    \"tests/functional/snapshots/test_select_exclude_snapshot.py::TestConfigured::test_all_configured_snapshots\": 95.86023996599943,\n    \"tests/functional/snapshots/test_select_exclude_snapshot.py::TestConfiguredExclude::test_exclude_configured_snapshots\": 2.914373089999998,\n    \"tests/functional/snapshots/test_select_exclude_snapshot.py::TestConfiguredSelect::test_select_configured_snapshots\": 61.21773660799954,\n    \"tests/functional/snapshots/test_select_exclude_snapshot.py::TestExcludeBasic::test_exclude_snapshots\": 61.27532777599845,\n    \"tests/functional/snapshots/test_select_exclude_snapshot.py::TestSelectBasic::test_select_snapshots\": 61.48745696199876,\n    \"tests/functional/snapshots/test_slow_query_snapshot.py::test_slow\": 137.10596646999875,\n    \"tests/functional/snapshots/test_snapshot_column_names.py::TestSnapshotColumnNames::test_snapshot_column_names\": 108.5104148950013,\n    \"tests/functional/snapshots/test_snapshot_column_names.py::TestSnapshotColumnNamesFromDbtProject::test_snapshot_column_names_from_project\": 101.97196625699871,\n    \"tests/functional/snapshots/test_snapshot_column_names.py::TestSnapshotInvalidColumnNames::test_snapshot_invalid_column_names\": 101.64264548700157,\n    \"tests/functional/snapshots/test_snapshot_config.py::TestSnapshotConfig::test_config\": 5.242415402000006,\n    \"tests/functional/snapshots/test_snapshot_empty.py::TestSnapshotEmpty::test_check\": 171.2846070789983,\n    \"tests/functional/snapshots/test_snapshot_timestamps.py::TestSnapshotConfig::test_timestamp_snapshot\": 100.34509776199957,\n    \"tests/functional/source_overrides/test_simple_source_override.py::TestSourceOverride::test_source_overrides\": 294.4178194999986,\n    \"tests/functional/source_overrides/test_source_overrides_duplicate_model.py::TestSourceOverrideDuplicates::test_source_duplicate_overrides\": 73.99079210500167,\n    \"tests/functional/sources/test_name_chars.py::TestNameChars::test_quotes_in_table_names\": 3.0891765860001215,\n    \"tests/functional/sources/test_simple_source.py::TestBasicSource::test_basic_source_def\": 146.38359287000094,\n    \"tests/functional/sources/test_simple_source.py::TestEmptySource::test_empty_source_def\": 105.42350240900123,\n    \"tests/functional/sources/test_simple_source.py::TestMalformedSources::test_malformed_schema_will_break_run\": 2.489531840000012,\n    \"tests/functional/sources/test_simple_source.py::TestRenderingInSourceTests::test_render_in_source_tests\": 123.0788706459989,\n    \"tests/functional/sources/test_simple_source.py::TestSourceChildrenParents::test_source_childrens_parents\": 92.32687404799981,\n    \"tests/functional/sources/test_simple_source.py::TestSourceDef::test_source_only_def\": 127.93349742100145,\n    \"tests/functional/sources/test_simple_source.py::TestSourceRunOperation::test_run_operation_source\": 94.54722535599831,\n    \"tests/functional/sources/test_simple_source.py::TestSourceSelector::test_source_selector\": 285.9180681670023,\n    \"tests/functional/sources/test_simple_source.py::TestUnquotedSources::test_catalog\": 126.18702396299886,\n    \"tests/functional/sources/test_source_configs.py::TestConfigYamlSourceLevel::test_source_config_yaml_source_level\": 60.67554415400082,\n    \"tests/functional/sources/test_source_configs.py::TestConfigYamlSourceTable::test_source_config_yaml_source_table\": 60.86672854400058,\n    \"tests/functional/sources/test_source_configs.py::TestInvalidSourceConfig::test_invalid_config_source\": 69.09736205399895,\n    \"tests/functional/sources/test_source_configs.py::TestSourceConfigsInheritence1::test_source_all_configs_source_table\": 64.43113302399979,\n    \"tests/functional/sources/test_source_configs.py::TestSourceConfigsInheritence2::test_source_two_configs_source_level\": 2.7013750989999608,\n    \"tests/functional/sources/test_source_configs.py::TestSourceConfigsInheritence3::test_source_two_configs_source_table\": 70.98819002899836,\n    \"tests/functional/sources/test_source_configs.py::TestSourceEnabledConfigProjectLevel::test_enabled_source_config_dbt_project\": 3.186755081000001,\n    \"tests/functional/sources/test_source_configs.py::TestSourceLoadedAtFieldConfigLevel::test_loaded_at_field_config\": 67.27026138899964,\n    \"tests/functional/sources/test_source_configs.py::TestSourceLoadedAtFieldTopLevel::test_loaded_at_field_config\": 68.57178109000051,\n    \"tests/functional/sources/test_source_configs.py::TestSourceLoadedAtQueryConfigLevel::test_loaded_at_field_config\": 68.42528675200265,\n    \"tests/functional/sources/test_source_configs.py::TestSourceLoadedAtQueryTopLevel::test_loaded_at_query_config\": 68.70141765400149,\n    \"tests/functional/sources/test_source_configs.py::TestTableLoadedAtFieldConfigLevel::test_loaded_at_field_config\": 68.30800699800056,\n    \"tests/functional/sources/test_source_configs.py::TestTableLoadedAtFieldTopLevel::test_loaded_at_field_config\": 71.25413081100123,\n    \"tests/functional/sources/test_source_configs.py::TestTableLoadedAtQueryConfigLevel::test_loaded_at_field_config\": 71.64398513199922,\n    \"tests/functional/sources/test_source_configs.py::TestTableLoadedAtQueryNoneWhenFieldSetConfigLevel::test_loaded_at_query_config\": 69.18590104799841,\n    \"tests/functional/sources/test_source_configs.py::TestTableLoadedAtQueryNoneWhenFieldSetTopLevel::test_loaded_at_query_config\": 73.25590512099916,\n    \"tests/functional/sources/test_source_configs.py::TestTableLoadedAtQueryTopLevel::test_loaded_at_query_config\": 65.88884472599966,\n    \"tests/functional/sources/test_source_fresher_state.py::TestSourceFresherBuild::test_source_fresher_build_error\": 271.57097632600016,\n    \"tests/functional/sources/test_source_fresher_state.py::TestSourceFresherBuild::test_source_fresher_build_pass\": 188.58403688100225,\n    \"tests/functional/sources/test_source_fresher_state.py::TestSourceFresherBuild::test_source_fresher_build_warn\": 191.41722029599987,\n    \"tests/functional/sources/test_source_fresher_state.py::TestSourceFresherBuildResultSelectors::test_source_fresher_build_state_modified_pass\": 220.9543690240007,\n    \"tests/functional/sources/test_source_fresher_state.py::TestSourceFresherBuildStateModified::test_source_fresher_build_state_modified_pass\": 12.583257703999948,\n    \"tests/functional/sources/test_source_fresher_state.py::TestSourceFresherNoCurrentState::test_intentional_failure_no_previous_state\": 183.0358722639994,\n    \"tests/functional/sources/test_source_fresher_state.py::TestSourceFresherNoPreviousState::test_intentional_failure_no_previous_state\": 147.83519282899942,\n    \"tests/functional/sources/test_source_fresher_state.py::TestSourceFresherNothingToDo::test_source_fresher_nothing_to_do\": 212.98931883800105,\n    \"tests/functional/sources/test_source_fresher_state.py::TestSourceFresherRun::test_source_fresher_run_error\": 263.0144736120001,\n    \"tests/functional/sources/test_source_fresher_state.py::TestSourceFresherRun::test_source_fresher_run_pass\": 11.265075439000043,\n    \"tests/functional/sources/test_source_fresher_state.py::TestSourceFresherRun::test_source_fresher_run_warn\": 185.07422031900023,\n    \"tests/functional/sources/test_source_fresher_state.py::TestSourceFresherRuntimeError::test_runtime_error_states\": 16.039504268,\n    \"tests/functional/sources/test_source_fresher_state.py::TestSourceFresherTest::test_source_fresher_run_error\": 251.44055135300187,\n    \"tests/functional/sources/test_source_fresher_state.py::TestSourceFresherTest::test_source_fresher_test_pass\": 12.874040330000014,\n    \"tests/functional/sources/test_source_fresher_state.py::TestSourceFresherTest::test_source_fresher_test_warn\": 192.31558216200028,\n    \"tests/functional/sources/test_source_freshness.py::TestHooksInSourceFreshness::test_hooks_do_run_for_source_freshness\": 107.76506222799799,\n    \"tests/functional/sources/test_source_freshness.py::TestHooksInSourceFreshnessDefault::test_hooks_do_not_run_for_source_freshness\": 107.34578038799918,\n    \"tests/functional/sources/test_source_freshness.py::TestHooksInSourceFreshnessDisabled::test_hooks_do_not_run_for_source_freshness\": 109.31360336499893,\n    \"tests/functional/sources/test_source_freshness.py::TestHooksInSourceFreshnessError::test_hooks_do_not_run_for_source_freshness\": 70.278961592001,\n    \"tests/functional/sources/test_source_freshness.py::TestMetadataFreshnessFails::test_metadata_freshness_unsupported_error_when_run\": 3.4563143910002054,\n    \"tests/functional/sources/test_source_freshness.py::TestMetadataFreshnessFails::test_metadata_freshness_unsupported_parse_warning\": 71.99134183299975,\n    \"tests/functional/sources/test_source_freshness.py::TestOverrideSourceFreshness::test_override_source_freshness\": 111.01182990599955,\n    \"tests/functional/sources/test_source_freshness.py::TestSourceFreshness::test_source_freshness\": 182.2602920069985,\n    \"tests/functional/sources/test_source_freshness.py::TestSourceFreshnessCustomSQL::test_source_freshness_custom_sql\": 111.69172881000122,\n    \"tests/functional/sources/test_source_freshness.py::TestSourceFreshnessCustomSQLConfig::test_source_freshness_custom_sql\": 115.34302136000042,\n    \"tests/functional/sources/test_source_freshness.py::TestSourceFreshnessCustomSQLSourceConfig::test_source_freshness_custom_sql\": 111.58725815400066,\n    \"tests/functional/sources/test_source_freshness.py::TestSourceFreshnessErrors::test_source_freshness_error\": 113.25015244299902,\n    \"tests/functional/sources/test_source_freshness.py::TestSourceFreshnessExclude::test_source_freshness_selection_exclude\": 142.63405745500313,\n    \"tests/functional/sources/test_source_freshness.py::TestSourceFreshnessExplicitNullInSource::test_source_freshness_explicit_null_in_source\": 4.322688091000003,\n    \"tests/functional/sources/test_source_freshness.py::TestSourceFreshnessExplicitNullInTable::test_source_freshness_explicit_null_in_table\": 119.63315542500095,\n    \"tests/functional/sources/test_source_freshness.py::TestSourceFreshnessFilter::test_source_freshness_all_records\": 183.64217327999904,\n    \"tests/functional/sources/test_source_freshness.py::TestSourceFreshnessGraph::test_source_freshness_selection_graph_operation\": 124.6483720819997,\n    \"tests/functional/sources/test_source_freshness.py::TestSourceFreshnessMacroOverride::test_source_freshness\": 109.51772196400088,\n    \"tests/functional/sources/test_source_freshness.py::TestSourceFreshnessProjectHooksNotRun::test_hooks_do_run_for_source_freshness\": 109.01173660400127,\n    \"tests/functional/sources/test_source_freshness.py::TestSourceFreshnessSelection::test_source_freshness_selection_select\": 119.06506106000234,\n    \"tests/functional/sources/test_source_freshness.py::TestSourceSnapshotFreshness::test_source_snapshot_freshness\": 183.7045984460001,\n    \"tests/functional/sources/test_source_loaded_at_field.py::TestParsingLoadedAtField::test_loaded_at_field\": 7.697236137999994,\n    \"tests/functional/statements/test_statements.py::TestStatements::test_duplicated_load_statements\": 69.434938907998,\n    \"tests/functional/statements/test_statements.py::TestStatements::test_load_statement_on_main_twice\": 7.6714405959999965,\n    \"tests/functional/statements/test_statements.py::TestStatements::test_postgres_statements\": 4.5747430640000175,\n    \"tests/functional/test_empty.py::TestEmptyFlag::test_run_with_empty\": 16.17108102900005,\n    \"tests/functional/test_project.py::TestGenericJsonSchemaValidationDeprecation::test_project\": 0.7298283330000004,\n    \"tests/functional/test_project.py::TestProjectJsonschemaValidatedOnlyOnce::test_project\": 2.9781766890000085,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestExpansionWithSelectors::test_all_tests_no_specifiers\": 141.95065429699935,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestExpansionWithSelectors::test_exclude_column_config_level_tag\": 119.2211366340016,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestExpansionWithSelectors::test_exclude_column_level_tag\": 115.20878721900226,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestExpansionWithSelectors::test_exclude_data_test_tag\": 9.653047574000027,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestExpansionWithSelectors::test_exclude_model_b\": 10.316360483000011,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestExpansionWithSelectors::test_model_a_alone\": 106.81006993200026,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestExpansionWithSelectors::test_model_a_exclude_specific_test\": 106.01301548300034,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestExpansionWithSelectors::test_model_a_exclude_specific_test_buildable\": 108.3335359749999,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestExpansionWithSelectors::test_model_a_exclude_specific_test_cautious\": 106.31086144499932,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestExpansionWithSelectors::test_model_a_indirect_selection\": 8.845961178999971,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestExpansionWithSelectors::test_model_a_indirect_selection_buildable\": 138.03266729499592,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestExpansionWithSelectors::test_model_a_indirect_selection_cautious\": 130.2742062180041,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestExpansionWithSelectors::test_model_a_indirect_selection_eager\": 112.07709329900172,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestExpansionWithSelectors::test_model_a_indirect_selection_empty\": 41.55653875000098,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestExpansionWithSelectors::test_model_a_indirect_selection_exclude_unique_tests\": 10.017910887,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestExpansionWithSelectors::test_model_a_model_b\": 105.78964403699865,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestExpansionWithSelectors::test_model_a_only_singular\": 106.76126584200028,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestExpansionWithSelectors::test_model_a_only_singular_cautious\": 105.15465966299962,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestExpansionWithSelectors::test_model_a_only_singular_eager\": 106.75551636300224,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestExpansionWithSelectors::test_model_a_only_singular_unset\": 106.46711188099835,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestExpansionWithSelectors::test_model_a_sources\": 107.09708416100148,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestExpansionWithSelectors::test_model_tag_test_name_intersection\": 135.82457860499744,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestExpansionWithSelectors::test_only_generic\": 141.4812073539979,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestExpansionWithSelectors::test_only_singular\": 106.70284191899918,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestExpansionWithSelectors::test_select_column_config_level_tag\": 134.20065341100053,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestExpansionWithSelectors::test_select_column_level_tag\": 123.04018047400314,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestExpansionWithSelectors::test_select_source_column_config_level_tag\": 128.33545254800083,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestExpansionWithSelectors::test_selector_model_a_buildable_indirect_selection\": 111.39159516799918,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestExpansionWithSelectors::test_selector_model_a_cautious_indirect_selection\": 118.25005439899905,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestExpansionWithSelectors::test_selector_model_a_eager_indirect_selection\": 111.31943825100097,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestExpansionWithSelectors::test_selector_model_a_unset_indirect_selection\": 7.305125508000003,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestExpansionWithSelectors::test_test_level_tag\": 119.76356488300007,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestExpansionWithSelectors::test_test_name_intersection\": 114.56226429299932,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestSelectionExpansion::test_all_tests_no_specifiers\": 145.75069392099795,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestSelectionExpansion::test_exclude_column_config_level_tag\": 106.40668184999959,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestSelectionExpansion::test_exclude_column_level_tag\": 10.017908178999988,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestSelectionExpansion::test_exclude_data_test_tag\": 107.11427396499857,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestSelectionExpansion::test_exclude_model_b\": 6.252533097999958,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestSelectionExpansion::test_model_a_alone\": 111.18456728799902,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestSelectionExpansion::test_model_a_exclude_specific_test\": 104.05563873400388,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestSelectionExpansion::test_model_a_exclude_specific_test_buildable\": 109.03073197399863,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestSelectionExpansion::test_model_a_exclude_specific_test_cautious\": 108.75725234399943,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestSelectionExpansion::test_model_a_indirect_selection\": 107.01362749700093,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestSelectionExpansion::test_model_a_indirect_selection_buildable\": 108.86712989899752,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestSelectionExpansion::test_model_a_indirect_selection_cautious\": 147.8018395729996,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestSelectionExpansion::test_model_a_indirect_selection_eager\": 113.41239822299758,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestSelectionExpansion::test_model_a_indirect_selection_empty\": 35.97894609500145,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestSelectionExpansion::test_model_a_indirect_selection_exclude_unique_tests\": 7.849806000000029,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestSelectionExpansion::test_model_a_model_b\": 107.81440000299881,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestSelectionExpansion::test_model_a_only_singular\": 9.938911569999988,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestSelectionExpansion::test_model_a_only_singular_cautious\": 5.51844506000009,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestSelectionExpansion::test_model_a_only_singular_eager\": 108.42982389500139,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestSelectionExpansion::test_model_a_only_singular_unset\": 106.49227770000107,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestSelectionExpansion::test_model_a_sources\": 8.371015986999993,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestSelectionExpansion::test_model_tag_test_name_intersection\": 106.67572221400042,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestSelectionExpansion::test_only_generic\": 109.30028827100068,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestSelectionExpansion::test_only_singular\": 146.10128680199887,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestSelectionExpansion::test_select_column_config_level_tag\": 106.68014139099978,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestSelectionExpansion::test_select_column_level_tag\": 108.33668895600022,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestSelectionExpansion::test_select_source_column_config_level_tag\": 105.74667675299861,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestSelectionExpansion::test_test_level_tag\": 106.38651585599837,\n    \"tests/functional/test_selection/test_selection_expansion.py::TestSelectionExpansion::test_test_name_intersection\": 106.9687094639994,\n    \"tests/functional/test_singular_tests.py::TestSingularTestWarnError::test_singular_test_equals_warn_error\": 2.6309978649999834,\n    \"tests/functional/test_singular_tests.py::TestSingularTestWarnError::test_singular_test_warn_error\": 2.868404886999997,\n    \"tests/functional/test_singular_tests.py::TestSingularTestWarnError::test_singular_test_warn_error_options\": 1.2043703990000267,\n    \"tests/functional/threading/test_thread_count.py::TestThreadCount::test_threading_8x\": 76.87732999600121,\n    \"tests/functional/time_spines/test_time_spines.py::TestMissingTimeSpine::test_time_spines\": 78.73946257500211,\n    \"tests/functional/time_spines/test_time_spines.py::TestTimeSpineCustomColumnMissing::test_time_spines\": 2.7540323009999383,\n    \"tests/functional/time_spines/test_time_spines.py::TestTimeSpineGranularityMissing::test_time_spines\": 74.27478839300238,\n    \"tests/functional/time_spines/test_time_spines.py::TestTimeSpineStandardColumnMissing::test_time_spines\": 75.46766035800101,\n    \"tests/functional/time_spines/test_time_spines.py::TestValidLegacyTimeSpine::test_time_spines\": 77.84324479399947,\n    \"tests/functional/time_spines/test_time_spines.py::TestValidTimeSpines::test_time_spines\": 78.52267215500251,\n    \"tests/functional/timezones/test_timezones.py::TestTimezones::test_run_started_at\": 74.4921795759983,\n    \"tests/functional/unit_testing/test_csv_fixtures.py::TestUnitTestsDuplicateCSVFile::test_duplicate\": 78.21052728200084,\n    \"tests/functional/unit_testing/test_csv_fixtures.py::TestUnitTestsFileCSVEmptyValueIsNull::test_unit_test\": 135.5470799370014,\n    \"tests/functional/unit_testing/test_csv_fixtures.py::TestUnitTestsInlineCSVEmptyValueIsNull::test_unit_test\": 136.62697998799922,\n    \"tests/functional/unit_testing/test_csv_fixtures.py::TestUnitTestsMissingCSVFile::test_missing\": 2.3512065299999847,\n    \"tests/functional/unit_testing/test_csv_fixtures.py::TestUnitTestsWithFileCSV::test_unit_test\": 11.741537405000031,\n    \"tests/functional/unit_testing/test_csv_fixtures.py::TestUnitTestsWithInlineCSV::test_unit_test\": 209.6276906710009,\n    \"tests/functional/unit_testing/test_csv_fixtures.py::TestUnitTestsWithMixedCSV::test_unit_test\": 204.17008768099913,\n    \"tests/functional/unit_testing/test_sql_format.py::TestSQLFormat::test_sql_format\": 93.2033532020032,\n    \"tests/functional/unit_testing/test_sql_format.py::TestSQLFormatFixtures::test_sql_format_fixtures\": 97.35245845700047,\n    \"tests/functional/unit_testing/test_state.py::TestUnitTestDeferDoesntOverwrite::test_unit_test_defer_state\": 128.1361204720015,\n    \"tests/functional/unit_testing/test_state.py::TestUnitTestDeferState::test_unit_test_defer_state\": 115.19832038999448,\n    \"tests/functional/unit_testing/test_state.py::TestUnitTestRetry::test_unit_test_retry\": 150.30434907900053,\n    \"tests/functional/unit_testing/test_state.py::TestUnitTestStateModified::test_state_modified\": 10.637249088000004,\n    \"tests/functional/unit_testing/test_unit_testing.py::TestUnitTestExplicitSeed::test_explicit_seed\": 5.671921933999954,\n    \"tests/functional/unit_testing/test_unit_testing.py::TestUnitTestExternalPackageNode::test_unit_test_ext_nodes\": 149.9469526540015,\n    \"tests/functional/unit_testing/test_unit_testing.py::TestUnitTestExternalProjectNode::test_unit_test_ext_nodes\": 149.2960233570011,\n    \"tests/functional/unit_testing/test_unit_testing.py::TestUnitTestImplicitSeed::test_implicit_seed\": 151.22677824200218,\n    \"tests/functional/unit_testing/test_unit_testing.py::TestUnitTestIncrementalModelBasic::test_basic\": 4.994694784000103,\n    \"tests/functional/unit_testing/test_unit_testing.py::TestUnitTestIncrementalModelNoOverride::test_no_override\": 73.79452759800188,\n    \"tests/functional/unit_testing/test_unit_testing.py::TestUnitTestIncrementalModelNoThisInput::test_no_this_input\": 87.73784661399986,\n    \"tests/functional/unit_testing/test_unit_testing.py::TestUnitTestIncrementalModelWithAlias::test_basic\": 119.83722876900356,\n    \"tests/functional/unit_testing/test_unit_testing.py::TestUnitTestIncrementalModelWithVersion::test_basic\": 111.91778518799765,\n    \"tests/functional/unit_testing/test_unit_testing.py::TestUnitTestIncrementalModelWrongOverride::test_str_override\": 2.4922150539999848,\n    \"tests/functional/unit_testing/test_unit_testing.py::TestUnitTestInvalidInputConfiguration::test_invalid_input_configuration\": 148.5784819019973,\n    \"tests/functional/unit_testing/test_unit_testing.py::TestUnitTestModelWithFunction::test_model_with_function\": 111.5390882319989,\n    \"tests/functional/unit_testing/test_unit_testing.py::TestUnitTestNonexistentSeed::test_nonexistent_seed\": 75.89844797499973,\n    \"tests/functional/unit_testing/test_unit_testing.py::TestUnitTestRefMissingVersionModel::test_basic\": 110.59977783200156,\n    \"tests/functional/unit_testing/test_unit_testing.py::TestUnitTestRefWithMissingVersionRef::test_basic\": 110.90968626700123,\n    \"tests/functional/unit_testing/test_unit_testing.py::TestUnitTestRefWithVersion::test_basic\": 111.82149820599443,\n    \"tests/functional/unit_testing/test_unit_testing.py::TestUnitTestRefWithVersionDiffLatest::test_basic\": 111.34391832700203,\n    \"tests/functional/unit_testing/test_unit_testing.py::TestUnitTestRefWithVersionLatestSecond::test_basic\": 109.30726277699796,\n    \"tests/functional/unit_testing/test_unit_testing.py::TestUnitTestRefWithVersionMissingRefTest::test_basic\": 111.00499829599721,\n    \"tests/functional/unit_testing/test_unit_testing.py::TestUnitTestSubfolderPath::test_subfolder_unit_test\": 74.49816818399995,\n    \"tests/functional/unit_testing/test_unit_testing.py::TestUnitTests::test_basic\": 584.8818125420039,\n    \"tests/functional/unit_testing/test_ut_adapter_hooks.py::TestUnitTestAdapterPostHook::test_unit_test_runs_adapter_post_hook_fails\": 112.7039411859987,\n    \"tests/functional/unit_testing/test_ut_adapter_hooks.py::TestUnitTestAdapterPostHook::test_unit_test_runs_adapter_post_hook_pass\": 4.077167386000042,\n    \"tests/functional/unit_testing/test_ut_adapter_hooks.py::TestUnitTestAdapterPreHook::test_unit_test_runs_adapter_pre_hook_fails\": 112.3166918930001,\n    \"tests/functional/unit_testing/test_ut_adapter_hooks.py::TestUnitTestAdapterPreHook::test_unit_test_runs_adapter_pre_hook_passes\": 4.740222096999901,\n    \"tests/functional/unit_testing/test_ut_aliases.py::TestUnitTestInputWithAlias::test_input_with_alias\": 111.69323447400166,\n    \"tests/functional/unit_testing/test_ut_dependency.py::TestUnitTestingInDependency::test_unit_test_in_dependency\": 264.8418194640035,\n    \"tests/functional/unit_testing/test_ut_diffing.py::TestUnitTestingDiffIsOrderAgnostic::test_unit_testing_diff_is_order_insensitive\": 115.13311531499858,\n    \"tests/functional/unit_testing/test_ut_ephemeral.py::TestUnitTestEphemeralInput::test_ephemeral_input\": 5.880983423999993,\n    \"tests/functional/unit_testing/test_ut_list.py::TestUnitTestList::test_unit_test_list\": 268.0300040109978,\n    \"tests/functional/unit_testing/test_ut_list.py::TestUnitTestListDisabled::test_disabled_unit_tests\": 75.15607246699801,\n    \"tests/functional/unit_testing/test_ut_macros.py::TestMacroComposition::test_macro_composition_in_unit_test\": 112.98634323999795,\n    \"tests/functional/unit_testing/test_ut_macros.py::TestMacroWithoutComposition::test_macro_in_unit_test\": 5.1601897329999815,\n    \"tests/functional/unit_testing/test_ut_names.py::TestUnitTestDuplicateTestNamesAcrossModels::test_duplicate_test_names_across_models\": 9.289804296000028,\n    \"tests/functional/unit_testing/test_ut_names.py::TestUnitTestDuplicateTestNamesWithinModel::test_duplicate_test_names_within_model\": 75.4444905829987,\n    \"tests/functional/unit_testing/test_ut_overrides.py::TestUnitTestingMacroOverrides::test_macro_overrides\": 75.99408836699877,\n    \"tests/functional/unit_testing/test_ut_resource_types.py::TestUnitTestResourceTypes::test_unit_test_list\": 616.0432517519985,\n    \"tests/functional/unit_testing/test_ut_snapshot_dependency.py::TestUnitTestSnapshotDependency::test_snapshot_dependency\": 282.3528574000011,\n    \"tests/functional/unit_testing/test_ut_sources.py::TestUnitTestSourceInput::test_source_input\": 243.52973640099663,\n    \"tests/functional/unit_testing/test_ut_sources.py::TestUnitTestSourceInputSameNames::test_source_input_same_names\": 5.345504815999988,\n    \"tests/functional/unit_testing/test_ut_variables.py::TestUnitTestOneVariables::test_one_variable_as_input_to_macro\": 42.851800518001255,\n    \"tests/functional/unit_testing/test_ut_variables.py::TestUnitTestTwoVariables::test_two_variables_as_input_to_macro\": 119.55644928000038,\n    \"tests/functional/unit_testing/test_ut_versions.py::TestIncludeExcludeSpecified::test_include_exclude_specified\": 79.48441015700155,\n    \"tests/functional/unit_testing/test_ut_versions.py::TestIncludeUnversioned::test_include_unversioned\": 1.6705306679999694,\n    \"tests/functional/unit_testing/test_ut_versions.py::TestVersionedFixture::test_versioned_fixture\": 66.60719303299993,\n    \"tests/functional/unit_testing/test_ut_versions.py::TestVersions::test_versions\": 233.78311553499952\n}\n"
  },
  {
    "path": "core/LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"{}\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright 2021 dbt Labs, Inc.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "core/README.md",
    "content": "<p align=\"center\">\n  <img src=\"https://raw.githubusercontent.com/dbt-labs/dbt-core/fa1ea14ddfb1d5ae319d5141844910dd53ab2834/docs/images/dbt-core.svg\" alt=\"dbt logo\" width=\"750\"/>\n</p>\n<p align=\"center\">\n  <a href=\"https://github.com/dbt-labs/dbt-core/actions/workflows/main.yml\">\n    <img src=\"https://github.com/dbt-labs/dbt-core/actions/workflows/main.yml/badge.svg?event=push\" alt=\"CI Badge\"/>\n  </a>\n</p>\n\n**[dbt](https://www.getdbt.com/)** enables data analysts and engineers to transform their data using the same practices that software engineers use to build applications.\n\n![architecture](https://raw.githubusercontent.com/dbt-labs/dbt-core/6c6649f9129d5d108aa3b0526f634cd8f3a9d1ed/docs/images/dbt-arch.png)\n\n## Understanding dbt\n\nAnalysts using dbt can transform their data by simply writing select statements, while dbt handles turning these statements into tables and views in a data warehouse.\n\nThese select statements, or \"models\", form a dbt project. Models frequently build on top of one another – dbt makes it easy to [manage relationships](https://docs.getdbt.com/docs/ref) between models, and [visualize these relationships](https://docs.getdbt.com/docs/documentation), as well as assure the quality of your transformations through [testing](https://docs.getdbt.com/docs/testing).\n\n![dbt dag](https://raw.githubusercontent.com/dbt-labs/dbt-core/6c6649f9129d5d108aa3b0526f634cd8f3a9d1ed/docs/images/dbt-dag.png)\n\n## Getting started\n\n- [Install dbt](https://docs.getdbt.com/docs/installation)\n- Read the [introduction](https://docs.getdbt.com/docs/introduction/) and [viewpoint](https://docs.getdbt.com/docs/about/viewpoint/)\n\n## Join the dbt Community\n\n- Be part of the conversation in the [dbt Community Slack](http://community.getdbt.com/)\n- Read more on the [dbt Community Discourse](https://discourse.getdbt.com)\n\n## Reporting bugs and contributing code\n\n- Want to report a bug or request a feature? Let us know on [Slack](http://community.getdbt.com/), or open [an issue](https://github.com/dbt-labs/dbt-core/issues/new)\n- Want to help us build dbt? Check out the [Contributing Guide](https://github.com/dbt-labs/dbt-core/blob/HEAD/CONTRIBUTING.md)\n\n## Code of Conduct\n\nEveryone interacting in the dbt project's codebases, issue trackers, chat rooms, and mailing lists is expected to follow the [dbt Code of Conduct](https://community.getdbt.com/code-of-conduct).\n"
  },
  {
    "path": "core/dbt/README.md",
    "content": "# core/dbt directory README\n\n## The following are individual files in this directory.\n\n### compilation.py\n\n### constants.py\n\n### dataclass_schema.py\n\n### deprecations.py\n\n### exceptions.py\n\n### flags.py\n\n### helper_types.py\n\n### hooks.py\n\n### lib.py\n\n### links.py\n\n### main.py\n\n### node_types.py\n\n### profiler.py\n\n### selected_resources.py\n\n### semver.py\n\n### tracking.py\n\n### ui.py\n\n### utils.py\n\n### version.py\n\n\n## The subdirectories will be documented in a README in the subdirectory\n* adapters\n* cli\n* clients\n* config\n* context\n* contracts\n* deps\n* docs\n* events\n* graph\n* include\n* parser\n* task\n* tests\n"
  },
  {
    "path": "core/dbt/__init__.py",
    "content": "# N.B.\n# This will add to the package’s __path__ all subdirectories of directories on sys.path named after the package which effectively combines both modules into a single namespace (dbt.adapters)\n# The matching statement is in plugins/postgres/dbt/__init__.py\n\nfrom pkgutil import extend_path\n\n__path__ = extend_path(__path__, __name__)\n"
  },
  {
    "path": "core/dbt/__version__.py",
    "content": "version = \"1.12.0a1\"\n"
  },
  {
    "path": "core/dbt/_pydantic_shim.py",
    "content": "# type: ignore\n\n\"\"\"Shim to allow support for both Pydantic 1 and Pydantic 2.\n\ndbt-core must support both major versions of Pydantic because dbt-core users might be using an environment with\neither version, and we can't restrict them to one or the other. Here, we essentially import all Pydantic objects\nfrom version 1 that we use. Throughout the repo, we import these objects from this file instead of from Pydantic\ndirectly, meaning that we essentially only use Pydantic 1 in dbt-core currently, but without forcing that restriction\non dbt users. The development environment for this repo should be pinned to Pydantic 1 to ensure devs get appropriate\ntype hints.\n\"\"\"\n\nfrom importlib.metadata import version\n\npydantic_version = version(\"pydantic\")\n# Pydantic uses semantic versioning, i.e. <major>.<minor>.<patch>, and we need to know the major\npydantic_major = pydantic_version.split(\".\")[0]\n\nif pydantic_major == \"1\":\n    from pydantic import BaseSettings  # noqa: F401\nelif pydantic_major == \"2\":\n    from pydantic.v1 import BaseSettings  # noqa: F401\nelse:\n    raise RuntimeError(\n        f\"Currently only pydantic 1 and 2 are supported, found pydantic {pydantic_version}\"\n    )\n"
  },
  {
    "path": "core/dbt/artifacts/__init__.py",
    "content": ""
  },
  {
    "path": "core/dbt/artifacts/exceptions/__init__.py",
    "content": "from dbt.artifacts.exceptions.schemas import IncompatibleSchemaError\n"
  },
  {
    "path": "core/dbt/artifacts/exceptions/schemas.py",
    "content": "from typing import Optional\n\nfrom dbt_common.exceptions import DbtRuntimeError\n\n\nclass IncompatibleSchemaError(DbtRuntimeError):\n    def __init__(self, expected: str, found: Optional[str] = None) -> None:\n        self.expected = expected\n        self.found = found\n        self.filename = \"input file\"\n\n        super().__init__(msg=self.get_message())\n\n    def add_filename(self, filename: str):\n        self.filename = filename\n        self.msg = self.get_message()\n\n    def get_message(self) -> str:\n        found_str = \"nothing\"\n        if self.found is not None:\n            found_str = f'\"{self.found}\"'\n\n        msg = (\n            f'Expected a schema version of \"{self.expected}\" in '\n            f\"{self.filename}, but found {found_str}. Are you running with a \"\n            f\"different version of dbt?\"\n        )\n        return msg\n\n    CODE = 10014\n    MESSAGE = \"Incompatible Schema\"\n"
  },
  {
    "path": "core/dbt/artifacts/resources/__init__.py",
    "content": "from dbt.artifacts.resources.base import BaseResource, Docs, FileHash, GraphResource\nfrom dbt.artifacts.resources.v1.analysis import Analysis\nfrom dbt.artifacts.resources.v1.catalog import Catalog, CatalogWriteIntegrationConfig\n\n# alias to latest resource definitions\nfrom dbt.artifacts.resources.v1.components import (\n    ColumnConfig,\n    ColumnDimension,\n    ColumnEntity,\n    ColumnInfo,\n    CompiledResource,\n    Contract,\n    DeferRelation,\n    DependsOn,\n    FreshnessThreshold,\n    HasRelationMetadata,\n    InjectedCTE,\n    NodeVersion,\n    ParsedResource,\n    ParsedResourceMandatory,\n    Quoting,\n    RefArgs,\n    Time,\n)\nfrom dbt.artifacts.resources.v1.config import (\n    Hook,\n    NodeAndTestConfig,\n    NodeConfig,\n    TestConfig,\n    list_str,\n    metas,\n)\nfrom dbt.artifacts.resources.v1.documentation import Documentation\nfrom dbt.artifacts.resources.v1.exposure import (\n    Exposure,\n    ExposureConfig,\n    ExposureType,\n    MaturityType,\n)\nfrom dbt.artifacts.resources.v1.function import (\n    DeferFunction,\n    Function,\n    FunctionArgument,\n    FunctionConfig,\n    FunctionMandatory,\n    FunctionReturns,\n)\nfrom dbt.artifacts.resources.v1.generic_test import GenericTest, TestMetadata\nfrom dbt.artifacts.resources.v1.group import Group, GroupConfig\nfrom dbt.artifacts.resources.v1.hook import HookNode\nfrom dbt.artifacts.resources.v1.macro import (\n    Macro,\n    MacroArgument,\n    MacroConfig,\n    MacroDependsOn,\n)\nfrom dbt.artifacts.resources.v1.metric import (\n    ConstantPropertyInput,\n    ConversionTypeParams,\n    CumulativeTypeParams,\n    Metric,\n    MetricAggregationParams,\n    MetricConfig,\n    MetricInput,\n    MetricInputMeasure,\n    MetricTimeWindow,\n    MetricTypeParams,\n)\nfrom dbt.artifacts.resources.v1.model import (\n    CustomGranularity,\n    Model,\n    ModelConfig,\n    ModelFreshness,\n    TimeSpine,\n)\nfrom dbt.artifacts.resources.v1.owner import Owner\nfrom dbt.artifacts.resources.v1.saved_query import (\n    Export,\n    ExportConfig,\n    QueryParams,\n    SavedQuery,\n    SavedQueryConfig,\n    SavedQueryMandatory,\n)\nfrom dbt.artifacts.resources.v1.seed import Seed, SeedConfig\nfrom dbt.artifacts.resources.v1.semantic_layer_components import (\n    FileSlice,\n    MeasureAggregationParameters,\n    NonAdditiveDimension,\n    SourceFileMetadata,\n    WhereFilter,\n    WhereFilterIntersection,\n)\nfrom dbt.artifacts.resources.v1.semantic_model import (\n    Defaults,\n    Dimension,\n    DimensionTypeParams,\n    DimensionValidityParams,\n    Entity,\n    Measure,\n    NodeRelation,\n    SemanticLayerElementConfig,\n    SemanticModel,\n    SemanticModelConfig,\n)\nfrom dbt.artifacts.resources.v1.singular_test import SingularTest\nfrom dbt.artifacts.resources.v1.snapshot import Snapshot, SnapshotConfig\nfrom dbt.artifacts.resources.v1.source_definition import (\n    ExternalPartition,\n    ExternalTable,\n    ParsedSourceMandatory,\n    SourceConfig,\n    SourceDefinition,\n)\nfrom dbt.artifacts.resources.v1.sql_operation import SqlOperation\nfrom dbt.artifacts.resources.v1.unit_test_definition import (\n    UnitTestConfig,\n    UnitTestDefinition,\n    UnitTestFormat,\n    UnitTestInputFixture,\n    UnitTestNodeVersions,\n    UnitTestOutputFixture,\n    UnitTestOverrides,\n)\n"
  },
  {
    "path": "core/dbt/artifacts/resources/base.py",
    "content": "import hashlib\nfrom dataclasses import dataclass\nfrom typing import List, Optional\n\nfrom dbt.artifacts.resources.types import NodeType\nfrom dbt_common.dataclass_schema import dbtClassMixin\n\n\n@dataclass\nclass BaseResource(dbtClassMixin):\n    name: str\n    resource_type: NodeType\n    package_name: str\n    path: str\n    original_file_path: str\n    unique_id: str\n\n\n@dataclass\nclass GraphResource(BaseResource):\n    fqn: List[str]\n\n\n@dataclass\nclass FileHash(dbtClassMixin):\n    name: str  # the hash type name\n    checksum: str  # the hashlib.hash_type().hexdigest() of the file contents\n\n    @classmethod\n    def empty(cls):\n        return FileHash(name=\"none\", checksum=\"\")\n\n    @classmethod\n    def path(cls, path: str):\n        return FileHash(name=\"path\", checksum=path)\n\n    def __eq__(self, other):\n        if not isinstance(other, FileHash):\n            return NotImplemented\n\n        if self.name == \"none\" or self.name != other.name:\n            return False\n\n        return self.checksum == other.checksum\n\n    def compare(self, contents: str) -> bool:\n        \"\"\"Compare the file contents with the given hash\"\"\"\n        if self.name == \"none\":\n            return False\n\n        return self.from_contents(contents, name=self.name) == self.checksum\n\n    @classmethod\n    def from_contents(cls, contents: str, name=\"sha256\") -> \"FileHash\":\n        \"\"\"Create a file hash from the given file contents. The hash is always\n        the utf-8 encoding of the contents given, because dbt only reads files\n        as utf-8.\n        \"\"\"\n        data = contents.encode(\"utf-8\")\n        checksum = hashlib.new(name, data).hexdigest()\n        return cls(name=name, checksum=checksum)\n\n\n@dataclass\nclass Docs(dbtClassMixin):\n    show: bool = True\n    node_color: Optional[str] = None\n"
  },
  {
    "path": "core/dbt/artifacts/resources/types.py",
    "content": "from dbt_common.dataclass_schema import StrEnum\n\n\nclass AccessType(StrEnum):\n    Private = \"private\"\n    Protected = \"protected\"\n    Public = \"public\"\n\n    @classmethod\n    def is_valid(cls, item):\n        try:\n            cls(item)\n        except ValueError:\n            return False\n        return True\n\n\nclass NodeType(StrEnum):\n    Model = \"model\"\n    Analysis = \"analysis\"\n    Test = \"test\"  # renamed to 'data_test'; preserved as 'test' here for back-compat\n    Snapshot = \"snapshot\"\n    Operation = \"operation\"\n    Seed = \"seed\"\n    # TODO: rm?\n    RPCCall = \"rpc\"\n    SqlOperation = \"sql_operation\"\n    Documentation = \"doc\"\n    Source = \"source\"\n    Macro = \"macro\"\n    Exposure = \"exposure\"\n    Metric = \"metric\"\n    Group = \"group\"\n    SavedQuery = \"saved_query\"\n    SemanticModel = \"semantic_model\"\n    Unit = \"unit_test\"\n    Fixture = \"fixture\"\n    Function = \"function\"\n\n    def pluralize(self) -> str:\n        if self is self.Analysis:\n            return \"analyses\"\n        elif self is self.SavedQuery:\n            return \"saved_queries\"\n        elif self is self.Test:\n            return \"data_tests\"\n        return f\"{self}s\"\n\n\nclass RunHookType(StrEnum):\n    Start = \"on-run-start\"\n    End = \"on-run-end\"\n\n\nclass ModelLanguage(StrEnum):\n    python = \"python\"\n    sql = \"sql\"\n\n\nclass ModelHookType(StrEnum):\n    PreHook = \"pre-hook\"\n    PostHook = \"post-hook\"\n\n\nclass TimePeriod(StrEnum):\n    minute = \"minute\"\n    hour = \"hour\"\n    day = \"day\"\n\n    def plural(self) -> str:\n        return str(self) + \"s\"\n\n\nclass BatchSize(StrEnum):\n    hour = \"hour\"\n    day = \"day\"\n    month = \"month\"\n    year = \"year\"\n\n    def plural(self) -> str:\n        return str(self) + \"s\"\n\n\nclass FunctionType(StrEnum):\n    Scalar = \"scalar\"\n    Aggregate = \"aggregate\"\n    Table = \"table\"\n\n\nclass FunctionVolatility(StrEnum):\n    Deterministic = \"deterministic\"\n    Stable = \"stable\"\n    NonDeterministic = \"non-deterministic\"\n"
  },
  {
    "path": "core/dbt/artifacts/resources/v1/analysis.py",
    "content": "from dataclasses import dataclass\nfrom typing import Literal\n\nfrom dbt.artifacts.resources.types import NodeType\nfrom dbt.artifacts.resources.v1.components import CompiledResource\n\n\n@dataclass\nclass Analysis(CompiledResource):\n    resource_type: Literal[NodeType.Analysis]\n"
  },
  {
    "path": "core/dbt/artifacts/resources/v1/catalog.py",
    "content": "from dataclasses import dataclass, field\nfrom typing import Any, Dict, List, Optional\n\nfrom dbt.adapters.catalogs import CatalogIntegrationConfig\nfrom dbt_common.dataclass_schema import dbtClassMixin\n\n\n@dataclass\nclass CatalogWriteIntegrationConfig(CatalogIntegrationConfig):\n    name: str\n    catalog_type: str\n    external_volume: Optional[str] = None\n    table_format: Optional[str] = None\n    catalog_name: Optional[str] = None\n    file_format: Optional[str] = None\n    adapter_properties: Dict[str, Any] = field(default_factory=dict)\n\n\n@dataclass\nclass Catalog(dbtClassMixin):\n    name: str\n    active_write_integration: Optional[str] = None\n    write_integrations: List[CatalogWriteIntegrationConfig] = field(default_factory=list)\n"
  },
  {
    "path": "core/dbt/artifacts/resources/v1/components.py",
    "content": "import time\nfrom dataclasses import dataclass, field\nfrom datetime import timedelta\nfrom typing import Any, Dict, List, Optional, Union\n\nfrom dbt.artifacts.resources.base import Docs, FileHash, GraphResource\nfrom dbt.artifacts.resources.types import NodeType, TimePeriod\nfrom dbt.artifacts.resources.v1.config import NodeConfig\nfrom dbt_common.contracts.config.base import BaseConfig, MergeBehavior\nfrom dbt_common.contracts.config.properties import AdditionalPropertiesMixin\nfrom dbt_common.contracts.constraints import ColumnLevelConstraint\nfrom dbt_common.contracts.util import Mergeable\nfrom dbt_common.dataclass_schema import ExtensibleDbtClassMixin, dbtClassMixin\nfrom dbt_semantic_interfaces.type_enums import (\n    DimensionType,\n    EntityType,\n    TimeGranularity,\n)\n\nNodeVersion = Union[str, float]\n\n\ndef _backcompat_doc_blocks(doc_blocks: Any) -> List[str]:\n    \"\"\"\n    Make doc_blocks backwards-compatible for scenarios where a user specifies `doc_blocks` on a model or column.\n    Mashumaro will raise a serialization error if the specified `doc_blocks` isn't a list of strings.\n    In such a scenario, this method returns an empty list to avoid a serialization error.\n    Further along, `_get_doc_blocks` in `manifest.py` populates the correct `doc_blocks` for the happy path.\n    \"\"\"\n\n    if isinstance(doc_blocks, list) and all(isinstance(x, str) for x in doc_blocks):\n        return doc_blocks\n\n    return []\n\n\n@dataclass\nclass MacroDependsOn(dbtClassMixin):\n    macros: List[str] = field(default_factory=list)\n\n    # 'in' on lists is O(n) so this is O(n^2) for # of macros\n    def add_macro(self, value: str):\n        if value not in self.macros:\n            self.macros.append(value)\n\n\n@dataclass\nclass DependsOn(MacroDependsOn):\n    nodes: List[str] = field(default_factory=list)\n\n    def add_node(self, value: str):\n        if value not in self.nodes:\n            self.nodes.append(value)\n\n\n@dataclass\nclass RefArgs(dbtClassMixin):\n    name: str\n    package: Optional[str] = None\n    version: Optional[NodeVersion] = None\n\n    @property\n    def positional_args(self) -> List[str]:\n        if self.package:\n            return [self.package, self.name]\n        else:\n            return [self.name]\n\n    @property\n    def keyword_args(self) -> Dict[str, Optional[NodeVersion]]:\n        if self.version:\n            return {\"version\": self.version}\n        else:\n            return {}\n\n\n@dataclass\nclass ColumnConfig(BaseConfig):\n    meta: Dict[str, Any] = field(default_factory=dict, metadata=MergeBehavior.Update.meta())\n    tags: List[str] = field(default_factory=list)\n\n\n@dataclass\nclass ColumnDimension(dbtClassMixin):\n    \"\"\"Used for column-based dimensions for Semantic Models\"\"\"\n\n    @dataclass\n    class ColumnDimensionValidityParams(dbtClassMixin):\n        is_start: bool = False\n        is_end: bool = False\n\n    name: str\n    type: DimensionType\n    description: Optional[str] = None\n    label: Optional[str] = None\n    is_partition: bool = False\n    config: Dict[str, Any] = field(default_factory=dict)\n    validity_params: Optional[ColumnDimensionValidityParams] = None\n\n\n@dataclass\nclass ColumnEntity(dbtClassMixin):\n    name: str\n    type: EntityType\n    description: Optional[str] = None\n    label: Optional[str] = None\n    config: Dict[str, Any] = field(default_factory=dict)\n\n\n@dataclass\nclass ColumnInfo(AdditionalPropertiesMixin, ExtensibleDbtClassMixin):\n    \"\"\"Used in all ManifestNodes and SourceDefinition\"\"\"\n\n    name: str\n    description: str = \"\"\n    meta: Dict[str, Any] = field(default_factory=dict)\n    data_type: Optional[str] = None\n    constraints: List[ColumnLevelConstraint] = field(default_factory=list)\n    quote: Optional[bool] = None\n    config: ColumnConfig = field(default_factory=ColumnConfig)\n    tags: List[str] = field(default_factory=list)\n    _extra: Dict[str, Any] = field(default_factory=dict)\n    granularity: Optional[TimeGranularity] = None\n    dimension: Union[ColumnDimension, DimensionType, None] = None\n    entity: Union[ColumnEntity, EntityType, None] = None\n    doc_blocks: List[str] = field(default_factory=list)\n\n    def __post_serialize__(self, dct: Dict, context: Optional[Dict] = None) -> dict:\n        dct = super().__post_serialize__(dct, context)\n        dct[\"doc_blocks\"] = _backcompat_doc_blocks(dct[\"doc_blocks\"])\n        return dct\n\n\n@dataclass\nclass InjectedCTE(dbtClassMixin):\n    \"\"\"Used in CompiledNodes as part of ephemeral model processing\"\"\"\n\n    id: str\n    sql: str\n\n\n@dataclass\nclass Contract(dbtClassMixin):\n    enforced: bool = False\n    alias_types: bool = True\n    checksum: Optional[str] = None\n\n\n@dataclass\nclass Quoting(dbtClassMixin, Mergeable):\n    database: Optional[bool] = None\n    schema: Optional[bool] = None\n    identifier: Optional[bool] = None\n    column: Optional[bool] = None\n\n\n@dataclass\nclass Time(dbtClassMixin, Mergeable):\n    count: Optional[int] = None\n    period: Optional[TimePeriod] = None\n\n    def exceeded(self, actual_age: float) -> bool:\n        if self.period is None or self.count is None:\n            return False\n        kwargs: Dict[str, int] = {self.period.plural(): self.count}\n        difference = timedelta(**kwargs).total_seconds()\n        return actual_age > difference\n\n    def __bool__(self):\n        return self.count is not None and self.period is not None\n\n\n@dataclass\nclass FreshnessThreshold(dbtClassMixin, Mergeable):\n    warn_after: Optional[Time] = field(default_factory=Time)\n    error_after: Optional[Time] = field(default_factory=Time)\n    filter: Optional[str] = None\n\n    def status(self, age: float) -> \"dbt.artifacts.schemas.results.FreshnessStatus\":  # type: ignore # noqa F821\n        from dbt.artifacts.schemas.results import FreshnessStatus\n\n        if self.error_after and self.error_after.exceeded(age):\n            return FreshnessStatus.Error\n        elif self.warn_after and self.warn_after.exceeded(age):\n            return FreshnessStatus.Warn\n        else:\n            return FreshnessStatus.Pass\n\n    def __bool__(self):\n        return bool(self.warn_after) or bool(self.error_after)\n\n\n@dataclass\nclass HasRelationMetadata(dbtClassMixin):\n    database: Optional[str]\n    schema: str\n\n    # Can't set database to None like it ought to be\n    # because it messes up the subclasses and default parameters\n    # so hack it here\n    @classmethod\n    def __pre_deserialize__(cls, data):\n        data = super().__pre_deserialize__(data)\n        if \"database\" not in data:\n            data[\"database\"] = None\n        return data\n\n    @property\n    def quoting_dict(self) -> Dict[str, bool]:\n        if hasattr(self, \"quoting\"):\n            return self.quoting.to_dict(omit_none=True)\n        else:\n            return {}\n\n\n@dataclass\nclass DeferRelation(HasRelationMetadata):\n    alias: str\n    relation_name: Optional[str]\n    # The rest of these fields match RelationConfig protocol exactly\n    resource_type: NodeType\n    name: str\n    description: str\n    compiled_code: Optional[str]\n    meta: Dict[str, Any]\n    tags: List[str]\n    config: Optional[NodeConfig]\n\n    @property\n    def identifier(self):\n        return self.alias\n\n\n@dataclass\nclass ParsedResourceMandatory(GraphResource, HasRelationMetadata):\n    alias: str\n    checksum: FileHash\n    config: NodeConfig = field(default_factory=NodeConfig)\n\n    @property\n    def identifier(self):\n        return self.alias\n\n\n@dataclass\nclass ParsedResource(ParsedResourceMandatory):\n    tags: List[str] = field(default_factory=list)\n    description: str = field(default=\"\")\n    columns: Dict[str, ColumnInfo] = field(default_factory=dict)\n    meta: Dict[str, Any] = field(default_factory=dict)\n    group: Optional[str] = None\n    docs: Docs = field(default_factory=Docs)\n    patch_path: Optional[str] = None\n    build_path: Optional[str] = None\n    unrendered_config: Dict[str, Any] = field(default_factory=dict)\n    created_at: float = field(default_factory=lambda: time.time())\n    config_call_dict: Dict[str, Any] = field(default_factory=dict)\n    unrendered_config_call_dict: Dict[str, Any] = field(default_factory=dict)\n    relation_name: Optional[str] = None\n    raw_code: str = \"\"\n    doc_blocks: List[str] = field(default_factory=list)\n\n    def __post_serialize__(self, dct: Dict, context: Optional[Dict] = None):\n        dct = super().__post_serialize__(dct, context)\n\n        if context and context.get(\"artifact\") and \"config_call_dict\" in dct:\n            del dct[\"config_call_dict\"]\n        if context and context.get(\"artifact\") and \"unrendered_config_call_dict\" in dct:\n            del dct[\"unrendered_config_call_dict\"]\n\n        dct[\"doc_blocks\"] = _backcompat_doc_blocks(dct[\"doc_blocks\"])\n\n        return dct\n\n\n@dataclass\nclass CompiledResource(ParsedResource):\n    \"\"\"Contains attributes necessary for SQL files and nodes with refs, sources, etc,\n    so all ManifestNodes except SeedNode.\"\"\"\n\n    language: str = \"sql\"\n    refs: List[RefArgs] = field(default_factory=list)\n    sources: List[List[str]] = field(default_factory=list)\n    metrics: List[List[str]] = field(default_factory=list)\n    functions: List[List[str]] = field(default_factory=list)\n    depends_on: DependsOn = field(default_factory=DependsOn)\n    compiled_path: Optional[str] = None\n    compiled: bool = False\n    compiled_code: Optional[str] = None\n    extra_ctes_injected: bool = False\n    extra_ctes: List[InjectedCTE] = field(default_factory=list)\n    _pre_injected_sql: Optional[str] = None\n    contract: Contract = field(default_factory=Contract)\n\n    def __post_serialize__(self, dct: Dict, context: Optional[Dict] = None):\n        dct = super().__post_serialize__(dct, context)\n        if \"_pre_injected_sql\" in dct:\n            del dct[\"_pre_injected_sql\"]\n        # Remove compiled attributes\n        if \"compiled\" in dct and dct[\"compiled\"] is False:\n            del dct[\"compiled\"]\n            del dct[\"extra_ctes_injected\"]\n            del dct[\"extra_ctes\"]\n            # \"omit_none\" means these might not be in the dictionary\n            if \"compiled_code\" in dct:\n                del dct[\"compiled_code\"]\n        return dct\n"
  },
  {
    "path": "core/dbt/artifacts/resources/v1/config.py",
    "content": "import re\nfrom dataclasses import dataclass, field\nfrom typing import Any, Dict, List, Optional, Union\n\nfrom mashumaro.jsonschema.annotations import Pattern\nfrom typing_extensions import Annotated\n\nfrom dbt import hooks\nfrom dbt.artifacts.resources.base import Docs\nfrom dbt.artifacts.resources.types import ModelHookType\nfrom dbt.artifacts.utils.validation import validate_color\nfrom dbt.flags import get_flags\nfrom dbt_common.contracts.config.base import BaseConfig, CompareBehavior, MergeBehavior\nfrom dbt_common.contracts.config.materialization import OnConfigurationChangeOption\nfrom dbt_common.contracts.config.metadata import Metadata, ShowBehavior\nfrom dbt_common.dataclass_schema import ValidationError, dbtClassMixin\n\n\ndef list_str() -> List[str]:\n    return []\n\n\nclass Severity(str):\n    pass\n\n\ndef metas(*metas: Metadata) -> Dict[str, Any]:\n    existing: Dict[str, Any] = {}\n    for m in metas:\n        existing = m.meta(existing)\n    return existing\n\n\n@dataclass\nclass ContractConfig(dbtClassMixin):\n    enforced: bool = False\n    alias_types: bool = True\n\n\n@dataclass\nclass Hook(dbtClassMixin):\n    sql: str\n    transaction: bool = True\n    index: Optional[int] = None\n\n\n@dataclass\nclass NodeAndTestConfig(BaseConfig):\n    enabled: bool = True\n    # these fields are included in serialized output, but are not part of\n    # config comparison (they are part of database_representation)\n    alias: Optional[str] = field(\n        default=None,\n        metadata=CompareBehavior.Exclude.meta(),\n    )\n    schema: Optional[str] = field(\n        default=None,\n        metadata=CompareBehavior.Exclude.meta(),\n    )\n    database: Optional[str] = field(\n        default=None,\n        metadata=CompareBehavior.Exclude.meta(),\n    )\n    tags: Union[List[str], str] = field(\n        default_factory=list_str,\n        metadata=metas(ShowBehavior.Hide, MergeBehavior.Append, CompareBehavior.Exclude),\n    )\n    meta: Dict[str, Any] = field(\n        default_factory=dict,\n        metadata=MergeBehavior.Update.meta(),\n    )\n    group: Optional[str] = field(\n        default=None,\n        metadata=CompareBehavior.Exclude.meta(),\n    )\n\n\n@dataclass\nclass NodeConfig(NodeAndTestConfig):\n    # Note: if any new fields are added with MergeBehavior, also update the\n    # 'mergebehavior' dictionary\n    materialized: str = \"view\"\n    incremental_strategy: Optional[str] = None\n    batch_size: Any = None\n    lookback: Any = 1\n    begin: Any = None\n    persist_docs: Dict[str, Any] = field(default_factory=dict)\n    post_hook: List[Hook] = field(\n        default_factory=list,\n        metadata={\"merge\": MergeBehavior.Append, \"alias\": \"post-hook\"},\n    )\n    pre_hook: List[Hook] = field(\n        default_factory=list,\n        metadata={\"merge\": MergeBehavior.Append, \"alias\": \"pre-hook\"},\n    )\n    quoting: Dict[str, Any] = field(\n        default_factory=dict,\n        metadata=MergeBehavior.Update.meta(),\n    )\n    # This is actually only used by seeds. Should it be available to others?\n    # That would be a breaking change!\n    column_types: Dict[str, Any] = field(\n        default_factory=dict,\n        metadata=MergeBehavior.Update.meta(),\n    )\n    full_refresh: Optional[bool] = None\n    # 'unique_key' doesn't use 'Optional' because typing.get_type_hints was\n    # sometimes getting the Union order wrong, causing serialization failures.\n    unique_key: Union[str, List[str], None] = None\n    on_schema_change: Optional[str] = \"ignore\"\n    on_configuration_change: OnConfigurationChangeOption = field(\n        default_factory=OnConfigurationChangeOption.default\n    )\n    grants: Dict[str, Any] = field(\n        default_factory=dict, metadata=MergeBehavior.DictKeyAppend.meta()\n    )\n    packages: List[str] = field(\n        default_factory=list,\n        metadata=MergeBehavior.Append.meta(),\n    )\n    docs: Docs = field(\n        default_factory=Docs,\n        metadata=MergeBehavior.Update.meta(),\n    )\n    contract: ContractConfig = field(\n        default_factory=ContractConfig,\n        metadata=MergeBehavior.Update.meta(),\n    )\n    event_time: Any = None\n    concurrent_batches: Any = None\n\n    def __post_init__(self):\n        # we validate that node_color has a suitable value to prevent dbt-docs from crashing\n        if self.docs.node_color:\n            node_color = self.docs.node_color\n            if not validate_color(node_color):\n                raise ValidationError(\n                    f\"Invalid color name for docs.node_color: {node_color}. \"\n                    \"It is neither a valid HTML color name nor a valid HEX code.\"\n                )\n\n        if (\n            self.contract.enforced\n            and self.materialized == \"incremental\"\n            and self.on_schema_change not in (\"append_new_columns\", \"fail\")\n        ):\n            raise ValidationError(\n                f\"Invalid value for on_schema_change: {self.on_schema_change}. Models \"\n                \"materialized as incremental with contracts enabled must set \"\n                \"on_schema_change to 'append_new_columns' or 'fail'\"\n            )\n\n    @classmethod\n    def __pre_deserialize__(cls, data):\n        data = super().__pre_deserialize__(data)\n        for key in ModelHookType:\n            if key in data:\n                data[key] = [hooks.get_hook_dict(h) for h in data[key]]\n        return data\n\n\nSEVERITY_PATTERN = r\"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$\"\n\n\n@dataclass\nclass TestConfig(NodeAndTestConfig):\n    __test__ = False\n\n    # this is repeated because of a different default\n    schema: Optional[str] = field(\n        default=\"dbt_test__audit\",\n        metadata=CompareBehavior.Exclude.meta(),\n    )\n    materialized: str = \"test\"\n    # Annotated is used by mashumaro for jsonschema generation\n    severity: Annotated[Severity, Pattern(SEVERITY_PATTERN)] = Severity(\"ERROR\")\n    store_failures: Optional[bool] = None\n    store_failures_as: Optional[str] = None\n    sql_header: Any = None\n    where: Optional[str] = None\n    limit: Optional[int] = None\n    fail_calc: str = \"count(*)\"\n    warn_if: str = \"!= 0\"\n    error_if: str = \"!= 0\"\n\n    def finalize_and_validate(self):\n        \"\"\"\n        The presence of a setting for `store_failures_as` overrides any existing setting for `store_failures`,\n        regardless of level of granularity. If `store_failures_as` is not set, then `store_failures` takes effect.\n        At the time of implementation, `store_failures = True` would always create a table; the user could not\n        configure this. Hence, if `store_failures = True` and `store_failures_as` is not specified, then it\n        should be set to \"table\" to mimic the existing functionality.\n\n        A side effect of this overriding functionality is that `store_failures_as=\"view\"` at the project\n        level cannot be turned off at the model level without setting both `store_failures_as` and\n        `store_failures`. The former would cascade down and override `store_failures=False`. The proposal\n        is to include \"ephemeral\" as a value for `store_failures_as`, which effectively sets\n        `store_failures=False`.\n\n        The exception handling for this is tricky. If we raise an exception here, the entire run fails at\n        parse time. We would rather well-formed models run successfully, leaving only exceptions to be rerun\n        if necessary. Hence, the exception needs to be raised in the test materialization. In order to do so,\n        we need to make sure that we go down the `store_failures = True` route with the invalid setting for\n        `store_failures_as`. This results in the `.get()` defaulted to `True` below, instead of a normal\n        dictionary lookup as is done in the `if` block. Refer to the test materialization for the\n        exception that is raise as a result of an invalid value.\n\n        The intention of this block is to behave as if `store_failures_as` is the only setting,\n        but still allow for backwards compatibility for `store_failures`.\n        See https://github.com/dbt-labs/dbt-core/issues/6914 for more information.\n        \"\"\"\n        super().finalize_and_validate()\n\n        # if `store_failures_as` is not set, it gets set by `store_failures`\n        # the settings below mimic existing behavior prior to `store_failures_as`\n        get_store_failures_as_map = {\n            True: \"table\",\n            False: \"ephemeral\",\n            None: None,\n        }\n\n        # if `store_failures_as` is set, it dictates what `store_failures` gets set to\n        # the settings below overrides whatever `store_failures` is set to by the user\n        get_store_failures_map = {\n            \"ephemeral\": False,\n            \"table\": True,\n            \"view\": True,\n        }\n\n        if self.store_failures_as is None:\n            self.store_failures_as = get_store_failures_as_map[self.store_failures]\n        else:\n            self.store_failures = get_store_failures_map.get(self.store_failures_as, True)\n\n        return self\n\n    @classmethod\n    def same_contents(cls, unrendered: Dict[str, Any], other: Dict[str, Any]) -> bool:\n        \"\"\"This is like __eq__, except it explicitly checks certain fields.\"\"\"\n        modifiers = [\n            \"severity\",\n            \"where\",\n            \"limit\",\n            \"fail_calc\",\n            \"warn_if\",\n            \"error_if\",\n            \"store_failures\",\n            \"store_failures_as\",\n            \"sql_header\",\n        ]\n\n        seen = set()\n        for _, target_name in cls._get_fields():\n            key = target_name\n            seen.add(key)\n            if key in modifiers:\n                if not cls.compare_key(unrendered, other, key):\n                    return False\n        return True\n\n    @classmethod\n    def validate(cls, data):\n        if data.get(\"severity\") and not re.match(SEVERITY_PATTERN, data.get(\"severity\")):\n            raise ValidationError(\n                f\"Severity must be either 'warn' or 'error'. Got '{data.get('severity')}'\"\n            )\n\n        super().validate(data)\n\n        if data.get(\"materialized\") and data.get(\"materialized\") != \"test\":\n            raise ValidationError(\"A test must have a materialized value of 'test'\")\n\n        sql_header = data.get(\"sql_header\")\n        if sql_header is not None and get_flags().require_sql_header_in_test_configs:\n            if not isinstance(sql_header, str):\n                raise ValidationError(\n                    f\"sql_header must be a string. Got '{type(sql_header).__name__}'\"\n                )\n"
  },
  {
    "path": "core/dbt/artifacts/resources/v1/documentation.py",
    "content": "from dataclasses import dataclass\nfrom typing import Literal\n\nfrom dbt.artifacts.resources.base import BaseResource\nfrom dbt.artifacts.resources.types import NodeType\n\n\n@dataclass\nclass Documentation(BaseResource):\n    resource_type: Literal[NodeType.Documentation]\n    block_contents: str\n"
  },
  {
    "path": "core/dbt/artifacts/resources/v1/exposure.py",
    "content": "import time\nfrom dataclasses import dataclass, field\nfrom typing import Any, Dict, List, Literal, Optional\n\nfrom dbt.artifacts.resources.base import GraphResource\nfrom dbt.artifacts.resources.types import NodeType\nfrom dbt.artifacts.resources.v1.components import DependsOn, RefArgs\nfrom dbt.artifacts.resources.v1.owner import Owner\nfrom dbt_common.contracts.config.base import BaseConfig\nfrom dbt_common.dataclass_schema import StrEnum\n\n\nclass ExposureType(StrEnum):\n    Dashboard = \"dashboard\"\n    Notebook = \"notebook\"\n    Analysis = \"analysis\"\n    ML = \"ml\"\n    Application = \"application\"\n\n\nclass MaturityType(StrEnum):\n    Low = \"low\"\n    Medium = \"medium\"\n    High = \"high\"\n\n\n@dataclass\nclass ExposureConfig(BaseConfig):\n    enabled: bool = True\n    tags: List[str] = field(default_factory=list)\n    meta: Dict[str, Any] = field(default_factory=dict)\n\n\n@dataclass\nclass Exposure(GraphResource):\n    type: ExposureType\n    owner: Owner\n    resource_type: Literal[NodeType.Exposure]\n    description: str = \"\"\n    label: Optional[str] = None\n    maturity: Optional[MaturityType] = None\n    meta: Dict[str, Any] = field(default_factory=dict)\n    tags: List[str] = field(default_factory=list)\n    config: ExposureConfig = field(default_factory=ExposureConfig)\n    unrendered_config: Dict[str, Any] = field(default_factory=dict)\n    url: Optional[str] = None\n    depends_on: DependsOn = field(default_factory=DependsOn)\n    refs: List[RefArgs] = field(default_factory=list)\n    sources: List[List[str]] = field(default_factory=list)\n    metrics: List[List[str]] = field(default_factory=list)\n    created_at: float = field(default_factory=lambda: time.time())\n"
  },
  {
    "path": "core/dbt/artifacts/resources/v1/function.py",
    "content": "from dataclasses import dataclass, field\nfrom typing import Any, Dict, List, Literal, Optional\n\nfrom dbt.artifacts.resources.types import FunctionType, FunctionVolatility, NodeType\nfrom dbt.artifacts.resources.v1.components import CompiledResource, HasRelationMetadata\nfrom dbt.artifacts.resources.v1.config import NodeConfig\nfrom dbt_common.dataclass_schema import dbtClassMixin\n\n# =============\n# Function config, and supporting classes\n# =============\n\n\n@dataclass\nclass FunctionConfig(NodeConfig):\n    # The fact that this is a property, that can be changed, seems wrong.\n    # A function's materialization should never be changed, so why allow for it?\n    materialized: str = \"function\"\n    type: FunctionType = FunctionType.Scalar\n    volatility: Optional[FunctionVolatility] = None\n    runtime_version: Optional[str] = None\n    entry_point: Optional[str] = None\n\n\n# =============\n# Function resource, and supporting classes\n# =============\n\n\n@dataclass\nclass FunctionArgument(dbtClassMixin):\n    name: str\n    data_type: str\n    description: Optional[str] = None\n    default_value: Optional[Any] = None\n\n\n@dataclass\nclass FunctionReturns(dbtClassMixin):\n    data_type: str\n    description: Optional[str] = None\n\n\n@dataclass\nclass FunctionMandatory(dbtClassMixin):\n    returns: FunctionReturns\n\n\n@dataclass\nclass DeferFunction(HasRelationMetadata):\n    alias: str\n    resource_type: NodeType\n    name: str\n    description: str\n    compiled_code: Optional[str]\n    meta: Dict[str, Any]\n    tags: List[str]\n    config: Optional[FunctionConfig]\n    arguments: List[FunctionArgument]\n    returns: FunctionReturns\n\n    @property\n    def identifier(self):\n        return self.name\n\n\n@dataclass\nclass Function(CompiledResource, FunctionMandatory):\n    resource_type: Literal[NodeType.Function]\n    config: FunctionConfig\n    arguments: List[FunctionArgument] = field(default_factory=list)\n    defer_function: Optional[DeferFunction] = None\n\n    def __post_serialize__(self, dct: Dict, context: Optional[Dict] = None):\n        dct = super().__post_serialize__(dct, context)\n        if context and context.get(\"artifact\") and \"defer_function\" in dct:\n            del dct[\"defer_function\"]\n        return dct\n"
  },
  {
    "path": "core/dbt/artifacts/resources/v1/generic_test.py",
    "content": "from dataclasses import dataclass, field\nfrom typing import Any, Dict, Literal, Optional\n\nfrom dbt.artifacts.resources.types import NodeType\nfrom dbt.artifacts.resources.v1.components import CompiledResource\nfrom dbt.artifacts.resources.v1.config import TestConfig\nfrom dbt_common.dataclass_schema import dbtClassMixin\n\n\n@dataclass\nclass TestMetadata(dbtClassMixin):\n    __test__ = False\n\n    name: str = \"test\"  # dummy default to allow default in GenericTestNode. Should always be set.\n    # kwargs are the args that are left in the test builder after\n    # removing configs. They are set from the test builder when\n    # the test node is created.\n    kwargs: Dict[str, Any] = field(default_factory=dict)\n    namespace: Optional[str] = None\n\n\n@dataclass\nclass GenericTest(CompiledResource):\n    resource_type: Literal[NodeType.Test]\n    column_name: Optional[str] = None\n    file_key_name: Optional[str] = None\n    # Was not able to make mypy happy and keep the code working. We need to\n    # refactor the various configs.\n    config: TestConfig = field(default_factory=TestConfig)  # type: ignore\n    attached_node: Optional[str] = None\n    test_metadata: TestMetadata = field(default_factory=TestMetadata)\n"
  },
  {
    "path": "core/dbt/artifacts/resources/v1/group.py",
    "content": "from dataclasses import dataclass, field\nfrom typing import Any, Dict, Literal, Optional\n\nfrom dbt.artifacts.resources.base import BaseResource\nfrom dbt.artifacts.resources.types import NodeType\nfrom dbt.artifacts.resources.v1.owner import Owner\nfrom dbt_common.contracts.config.base import BaseConfig, MergeBehavior\n\n\n@dataclass\nclass GroupConfig(BaseConfig):\n    meta: Dict[str, Any] = field(default_factory=dict, metadata=MergeBehavior.Update.meta())\n\n\n@dataclass\nclass Group(BaseResource):\n    name: str\n    owner: Owner\n    resource_type: Literal[NodeType.Group]\n    description: Optional[str] = None\n    config: GroupConfig = field(default_factory=GroupConfig)\n"
  },
  {
    "path": "core/dbt/artifacts/resources/v1/hook.py",
    "content": "from dataclasses import dataclass\nfrom typing import Literal, Optional\n\nfrom dbt.artifacts.resources.types import NodeType\nfrom dbt.artifacts.resources.v1.components import CompiledResource\n\n\n@dataclass\nclass HookNode(CompiledResource):\n    resource_type: Literal[NodeType.Operation]\n    index: Optional[int] = None\n"
  },
  {
    "path": "core/dbt/artifacts/resources/v1/macro.py",
    "content": "import time\nfrom dataclasses import dataclass, field\nfrom typing import Any, Dict, List, Literal, Optional\n\nfrom dbt.artifacts.resources.base import BaseResource, Docs\nfrom dbt.artifacts.resources.types import ModelLanguage, NodeType\nfrom dbt.artifacts.resources.v1.components import MacroDependsOn\nfrom dbt_common.contracts.config.base import BaseConfig\nfrom dbt_common.dataclass_schema import dbtClassMixin\n\n\n@dataclass\nclass MacroArgument(dbtClassMixin):\n    name: str\n    type: Optional[str] = None\n    description: str = \"\"\n\n\n@dataclass\nclass MacroConfig(BaseConfig):\n    meta: Dict[str, Any] = field(default_factory=dict)\n    docs: Docs = field(default_factory=Docs)\n\n\n@dataclass\nclass Macro(BaseResource):\n    macro_sql: str\n    resource_type: Literal[NodeType.Macro]\n    depends_on: MacroDependsOn = field(default_factory=MacroDependsOn)\n    description: str = \"\"\n    meta: Dict[str, Any] = field(default_factory=dict)\n    docs: Docs = field(default_factory=Docs)\n    config: MacroConfig = field(default_factory=MacroConfig)\n    patch_path: Optional[str] = None\n    arguments: List[MacroArgument] = field(default_factory=list)\n    created_at: float = field(default_factory=lambda: time.time())\n    supported_languages: Optional[List[ModelLanguage]] = None\n"
  },
  {
    "path": "core/dbt/artifacts/resources/v1/metric.py",
    "content": "import time\nfrom dataclasses import dataclass, field\nfrom typing import Any, Dict, List, Literal, Optional\n\nfrom dbt.artifacts.resources.base import GraphResource\nfrom dbt.artifacts.resources.types import NodeType\nfrom dbt.artifacts.resources.v1.components import DependsOn, RefArgs\nfrom dbt.artifacts.resources.v1.semantic_layer_components import (\n    MeasureAggregationParameters,\n    NonAdditiveDimension,\n    SourceFileMetadata,\n    WhereFilterIntersection,\n)\nfrom dbt_common.contracts.config.base import BaseConfig, CompareBehavior, MergeBehavior\nfrom dbt_common.dataclass_schema import dbtClassMixin\nfrom dbt_semantic_interfaces.references import MeasureReference, MetricReference\nfrom dbt_semantic_interfaces.type_enums import (\n    AggregationType,\n    ConversionCalculationType,\n    MetricType,\n    PeriodAggregation,\n    TimeGranularity,\n)\n\n\"\"\"\nThe following classes are dataclasses which are used to construct the Metric\nnode in dbt-core. Additionally, these classes need to at a minimum support\nwhat is specified in their protocol definitions in dbt-semantic-interfaces.\nTheir protocol definitions can be found here:\nhttps://github.com/dbt-labs/dbt-semantic-interfaces/blob/main/dbt_semantic_interfaces/protocols/metric.py\n\"\"\"\n\n\n@dataclass\nclass MetricInputMeasure(dbtClassMixin):\n    name: str\n    filter: Optional[WhereFilterIntersection] = None\n    alias: Optional[str] = None\n    join_to_timespine: bool = False\n    fill_nulls_with: Optional[int] = None\n\n    def measure_reference(self) -> MeasureReference:\n        return MeasureReference(element_name=self.name)\n\n    def post_aggregation_measure_reference(self) -> MeasureReference:\n        return MeasureReference(element_name=self.alias or self.name)\n\n\n@dataclass\nclass MetricTimeWindow(dbtClassMixin):\n    count: int\n    granularity: str\n\n    @property\n    def window_string(self) -> str:  # noqa: D\n        return f\"{self.count} {self.granularity}\"\n\n    @property\n    def is_standard_granularity(self) -> bool:  # noqa: D\n        return self.granularity.casefold() in {item.value.casefold() for item in TimeGranularity}\n\n\n@dataclass\nclass MetricInput(dbtClassMixin):\n    name: str\n    filter: Optional[WhereFilterIntersection] = None\n    alias: Optional[str] = None\n    offset_window: Optional[MetricTimeWindow] = None\n    offset_to_grain: Optional[str] = None\n\n    def as_reference(self) -> MetricReference:\n        return MetricReference(element_name=self.name)\n\n    def post_aggregation_reference(self) -> MetricReference:\n        return MetricReference(element_name=self.alias or self.name)\n\n\n@dataclass\nclass ConstantPropertyInput(dbtClassMixin):\n    base_property: str\n    conversion_property: str\n\n\n@dataclass\nclass ConversionTypeParams(dbtClassMixin):\n    entity: str\n    base_measure: Optional[MetricInputMeasure] = None\n    conversion_measure: Optional[MetricInputMeasure] = None\n    base_metric: Optional[MetricInput] = None\n    conversion_metric: Optional[MetricInput] = None\n    calculation: ConversionCalculationType = ConversionCalculationType.CONVERSION_RATE\n    window: Optional[MetricTimeWindow] = None\n    constant_properties: Optional[List[ConstantPropertyInput]] = None\n\n\n@dataclass\nclass CumulativeTypeParams(dbtClassMixin):\n    window: Optional[MetricTimeWindow] = None\n    grain_to_date: Optional[str] = None\n    period_agg: PeriodAggregation = PeriodAggregation.FIRST\n    metric: Optional[MetricInput] = None\n\n\n@dataclass\nclass MetricAggregationParams(dbtClassMixin):\n    semantic_model: str\n    agg: AggregationType\n    agg_params: Optional[MeasureAggregationParameters] = None\n    agg_time_dimension: Optional[str] = None\n    non_additive_dimension: Optional[NonAdditiveDimension] = None\n\n\n@dataclass\nclass MetricTypeParams(dbtClassMixin):\n    # Only used in v1 Semantic YAML\n    measure: Optional[MetricInputMeasure] = None\n    # Only used in v1 Semantic YAML\n    input_measures: List[MetricInputMeasure] = field(default_factory=list)\n\n    numerator: Optional[MetricInput] = None\n    denominator: Optional[MetricInput] = None\n    expr: Optional[str] = None\n    window: Optional[MetricTimeWindow] = None\n    grain_to_date: Optional[TimeGranularity] = (\n        None  # legacy, use cumulative_type_params.grain_to_date\n    )\n    metrics: Optional[List[MetricInput]] = None\n    conversion_type_params: Optional[ConversionTypeParams] = None\n    cumulative_type_params: Optional[CumulativeTypeParams] = None\n    metric_aggregation_params: Optional[MetricAggregationParams] = None\n\n    # Below this point, all fields are only used in v2 Semantic YAML\n    fill_nulls_with: Optional[int] = None\n    join_to_timespine: bool = False\n    is_private: Optional[bool] = None  # populated by \"hidden\" field in YAML\n\n    def get_semantic_model_name(self) -> Optional[str]:\n        \"\"\"Simple helper to avoid having to null check intermediate members.\"\"\"\n        return (\n            self.metric_aggregation_params.semantic_model\n            if self.metric_aggregation_params is not None\n            else None\n        )\n\n\n@dataclass\nclass MetricConfig(BaseConfig):\n    enabled: bool = True\n    group: Optional[str] = field(\n        default=None,\n        metadata=CompareBehavior.Exclude.meta(),\n    )\n\n    meta: Dict[str, Any] = field(default_factory=dict, metadata=MergeBehavior.Update.meta())\n\n\n@dataclass\nclass Metric(GraphResource):\n    name: str\n    description: str\n    label: str\n    type: MetricType\n    type_params: MetricTypeParams\n    filter: Optional[WhereFilterIntersection] = None\n    metadata: Optional[SourceFileMetadata] = None\n    time_granularity: Optional[str] = None\n    resource_type: Literal[NodeType.Metric]\n    config: MetricConfig = field(default_factory=MetricConfig)\n    unrendered_config: Dict[str, Any] = field(default_factory=dict)\n    sources: List[List[str]] = field(default_factory=list)\n    depends_on: DependsOn = field(default_factory=DependsOn)\n    refs: List[RefArgs] = field(default_factory=list)\n    metrics: List[List[str]] = field(default_factory=list)\n    created_at: float = field(default_factory=lambda: time.time())\n    group: Optional[str] = None\n\n    # These fields are only used in v1 metrics.\n    meta: Dict[str, Any] = field(default_factory=dict, metadata=MergeBehavior.Update.meta())\n    tags: List[str] = field(default_factory=list)\n\n    @property\n    def input_metrics(self) -> List[MetricInput]:\n        return self.type_params.metrics or []\n\n    @property\n    def input_measures(self) -> List[MetricInputMeasure]:\n        return self.type_params.input_measures\n\n    @property\n    def measure_references(self) -> List[MeasureReference]:\n        return [x.measure_reference() for x in self.input_measures]\n"
  },
  {
    "path": "core/dbt/artifacts/resources/v1/model.py",
    "content": "import enum\nfrom dataclasses import dataclass, field\nfrom datetime import datetime\nfrom typing import Dict, List, Literal, Optional\n\nfrom dbt.artifacts.resources.types import AccessType, NodeType, TimePeriod\nfrom dbt.artifacts.resources.v1.components import (\n    CompiledResource,\n    DeferRelation,\n    NodeVersion,\n)\nfrom dbt.artifacts.resources.v1.config import NodeConfig\nfrom dbt_common.contracts.config.base import MergeBehavior\nfrom dbt_common.contracts.constraints import ModelLevelConstraint\nfrom dbt_common.contracts.util import Mergeable\nfrom dbt_common.dataclass_schema import (\n    ExtensibleDbtClassMixin,\n    ValidationError,\n    dbtClassMixin,\n)\n\n\nclass ModelFreshnessUpdatesOnOptions(enum.Enum):\n    all = \"all\"\n    any = \"any\"\n\n\n@dataclass\nclass ModelBuildAfter(ExtensibleDbtClassMixin):\n    count: Optional[int] = None\n    period: Optional[TimePeriod] = None\n    updates_on: ModelFreshnessUpdatesOnOptions = ModelFreshnessUpdatesOnOptions.any\n\n\n@dataclass\nclass ModelFreshness(ExtensibleDbtClassMixin, Mergeable):\n    build_after: ModelBuildAfter\n\n\ndef merge_model_freshness(*thresholds: Optional[ModelFreshness]) -> Optional[ModelFreshness]:\n    if not thresholds:\n        return None\n\n    current_merged_value: Optional[ModelFreshness] = thresholds[0]\n\n    for i in range(1, len(thresholds)):\n        base = current_merged_value\n        update = thresholds[i]\n\n        if base is not None and update is not None:\n            # When both base and update freshness are defined,\n            # create a new ModelFreshness instance using the build_after from the 'update'.\n            # This effectively means 'update's build_after configuration takes precedence.\n            merged_freshness_obj = base.merged(update)\n            if (\n                base.build_after.updates_on == ModelFreshnessUpdatesOnOptions.all\n                or update.build_after.updates_on == ModelFreshnessUpdatesOnOptions.all\n            ):\n                merged_freshness_obj.build_after.updates_on = ModelFreshnessUpdatesOnOptions.all\n            current_merged_value = merged_freshness_obj\n        elif base is None and update is not None:\n            # If the current merged value is None but the new update is defined,\n            # take the update.\n            current_merged_value = update\n        else:\n            # This covers cases where 'update' is None (regardless of 'base'),\n            # or both 'base' and 'update' are None.\n            # The result of the pair-merge is None.\n            current_merged_value = base\n\n    return current_merged_value\n\n\n@dataclass\nclass ModelConfig(NodeConfig):\n    access: AccessType = field(\n        default=AccessType.Protected,\n        metadata=MergeBehavior.Clobber.meta(),\n    )\n    freshness: Optional[ModelFreshness] = None\n\n    def __post_init__(self):\n        super().__post_init__()\n        if (\n            self.freshness\n            and self.freshness.build_after.period\n            and self.freshness.build_after.count is None\n        ):\n            raise ValidationError(\n                \"`freshness.build_after` must have a value for `count` if a `period` is provided\"\n            )\n        elif (\n            self.freshness\n            and self.freshness.build_after.count is not None\n            and not self.freshness.build_after.period\n        ):\n            raise ValidationError(\n                \"`freshness.build_after` must have a value for `period` if a `count` is provided\"\n            )\n\n    @classmethod\n    def __pre_deserialize__(cls, data):\n        data = super().__pre_deserialize__(data)\n        # scrub out model configs where \"build_after\" is not defined\n        if (\n            \"freshness\" in data\n            and isinstance(data[\"freshness\"], dict)\n            and \"build_after\" in data[\"freshness\"]\n        ):\n            data[\"freshness\"] = ModelFreshness.from_dict(data[\"freshness\"]).to_dict()\n        else:\n            data.pop(\"freshness\", None)\n        return data\n\n\n@dataclass\nclass CustomGranularity(dbtClassMixin):\n    name: str\n    column_name: Optional[str] = None\n\n\n@dataclass\nclass TimeSpine(dbtClassMixin):\n    standard_granularity_column: str\n    custom_granularities: List[CustomGranularity] = field(default_factory=list)\n\n\n@dataclass\nclass Model(CompiledResource):\n    resource_type: Literal[NodeType.Model]\n    access: AccessType = AccessType.Protected\n    config: ModelConfig = field(default_factory=ModelConfig)\n    constraints: List[ModelLevelConstraint] = field(default_factory=list)\n    version: Optional[NodeVersion] = None\n    latest_version: Optional[NodeVersion] = None\n    deprecation_date: Optional[datetime] = None\n    defer_relation: Optional[DeferRelation] = None\n    primary_key: List[str] = field(default_factory=list)\n    time_spine: Optional[TimeSpine] = None\n\n    def __post_serialize__(self, dct: Dict, context: Optional[Dict] = None):\n        dct = super().__post_serialize__(dct, context)\n        if context and context.get(\"artifact\") and \"defer_relation\" in dct:\n            del dct[\"defer_relation\"]\n        return dct\n"
  },
  {
    "path": "core/dbt/artifacts/resources/v1/owner.py",
    "content": "from dataclasses import dataclass\nfrom typing import List, Optional, Union\n\nfrom dbt_common.contracts.config.properties import AdditionalPropertiesAllowed\n\n\n@dataclass\nclass Owner(AdditionalPropertiesAllowed):\n    email: Union[str, List[str], None] = None\n    name: Optional[str] = None\n"
  },
  {
    "path": "core/dbt/artifacts/resources/v1/saved_query.py",
    "content": "from __future__ import annotations\n\nimport time\nfrom dataclasses import dataclass, field\nfrom typing import Any, Dict, List, Literal, Optional, Union\n\nfrom dbt.artifacts.resources.base import GraphResource\nfrom dbt.artifacts.resources.types import NodeType\nfrom dbt.artifacts.resources.v1.components import DependsOn, RefArgs\nfrom dbt.artifacts.resources.v1.config import list_str, metas\nfrom dbt.artifacts.resources.v1.semantic_layer_components import (\n    SourceFileMetadata,\n    WhereFilterIntersection,\n)\nfrom dbt_common.contracts.config.base import BaseConfig, CompareBehavior, MergeBehavior\nfrom dbt_common.contracts.config.metadata import ShowBehavior\nfrom dbt_common.dataclass_schema import dbtClassMixin\nfrom dbt_semantic_interfaces.type_enums.export_destination_type import (\n    ExportDestinationType,\n)\n\n\n@dataclass\nclass ExportConfig(dbtClassMixin):\n    \"\"\"Nested configuration attributes for exports.\"\"\"\n\n    export_as: ExportDestinationType\n    schema_name: Optional[str] = None\n    alias: Optional[str] = None\n    database: Optional[str] = None\n\n\n@dataclass\nclass Export(dbtClassMixin):\n    \"\"\"Configuration for writing query results to a table.\"\"\"\n\n    name: str\n    config: ExportConfig\n    unrendered_config: Dict[str, str] = field(default_factory=dict)\n\n\n@dataclass\nclass QueryParams(dbtClassMixin):\n    \"\"\"The query parameters for the saved query\"\"\"\n\n    metrics: List[str]\n    group_by: List[str]\n    where: Optional[WhereFilterIntersection]\n    order_by: List[str] = field(default_factory=list)\n    limit: Optional[int] = None\n\n\n@dataclass\nclass SavedQueryCache(dbtClassMixin):\n    enabled: bool = False\n\n\n@dataclass\nclass SavedQueryConfig(BaseConfig):\n    \"\"\"Where config options for SavedQueries are stored.\n\n    This class is much like many other node config classes. It's likely that\n    this class will expand in the direction of what's in the `NodeAndTestConfig`\n    class. It might make sense to clean the various *Config classes into one at\n    some point.\n    \"\"\"\n\n    enabled: bool = True\n    group: Optional[str] = field(\n        default=None,\n        metadata=CompareBehavior.Exclude.meta(),\n    )\n    meta: Dict[str, Any] = field(\n        default_factory=dict,\n        metadata=MergeBehavior.Update.meta(),\n    )\n    export_as: Optional[ExportDestinationType] = None\n    schema: Optional[str] = None\n    cache: SavedQueryCache = field(default_factory=SavedQueryCache)\n\n\n@dataclass\nclass SavedQueryMandatory(GraphResource):\n    query_params: QueryParams\n    exports: List[Export]\n\n\n@dataclass\nclass SavedQuery(SavedQueryMandatory):\n    resource_type: Literal[NodeType.SavedQuery]\n    description: Optional[str] = None\n    label: Optional[str] = None\n    metadata: Optional[SourceFileMetadata] = None\n    config: SavedQueryConfig = field(default_factory=SavedQueryConfig)\n    unrendered_config: Dict[str, Any] = field(default_factory=dict)\n    group: Optional[str] = None\n    depends_on: DependsOn = field(default_factory=DependsOn)\n    created_at: float = field(default_factory=lambda: time.time())\n    refs: List[RefArgs] = field(default_factory=list)\n    tags: Union[List[str], str] = field(\n        default_factory=list_str,\n        metadata=metas(ShowBehavior.Hide, MergeBehavior.Append, CompareBehavior.Exclude),\n    )\n\n    @property\n    def metrics(self) -> List[str]:\n        return self.query_params.metrics\n\n    @property\n    def depends_on_nodes(self):\n        return self.depends_on.nodes\n"
  },
  {
    "path": "core/dbt/artifacts/resources/v1/seed.py",
    "content": "from dataclasses import dataclass, field\nfrom typing import Dict, Literal, Optional\n\nfrom dbt.artifacts.resources.types import NodeType\nfrom dbt.artifacts.resources.v1.components import (\n    DeferRelation,\n    MacroDependsOn,\n    ParsedResource,\n)\nfrom dbt.artifacts.resources.v1.config import NodeConfig\nfrom dbt_common.dataclass_schema import ValidationError\n\n\n@dataclass\nclass SeedConfig(NodeConfig):\n    materialized: str = \"seed\"\n    delimiter: str = \",\"\n    quote_columns: Optional[bool] = None\n\n    @classmethod\n    def validate(cls, data):\n        super().validate(data)\n        if data.get(\"materialized\") and data.get(\"materialized\") != \"seed\":\n            raise ValidationError(\"A seed must have a materialized value of 'seed'\")\n\n\n@dataclass\nclass Seed(ParsedResource):  # No SQLDefaults!\n    resource_type: Literal[NodeType.Seed]\n    config: SeedConfig = field(default_factory=SeedConfig)\n    # seeds need the root_path because the contents are not loaded initially\n    # and we need the root_path to load the seed later\n    root_path: Optional[str] = None\n    depends_on: MacroDependsOn = field(default_factory=MacroDependsOn)\n    defer_relation: Optional[DeferRelation] = None\n\n    def __post_serialize__(self, dct: Dict, context: Optional[Dict] = None):\n        dct = super().__post_serialize__(dct, context)\n        if context and context.get(\"artifact\") and \"defer_relation\" in dct:\n            del dct[\"defer_relation\"]\n        return dct\n"
  },
  {
    "path": "core/dbt/artifacts/resources/v1/semantic_layer_components.py",
    "content": "from dataclasses import dataclass\nfrom typing import List, Optional, Sequence, Tuple\n\nfrom dbt_common.dataclass_schema import dbtClassMixin\nfrom dbt_semantic_interfaces.call_parameter_sets import JinjaCallParameterSets\nfrom dbt_semantic_interfaces.parsing.where_filter.jinja_object_parser import (\n    JinjaObjectParser,\n    QueryItemLocation,\n)\nfrom dbt_semantic_interfaces.type_enums import AggregationType\n\n\n@dataclass\nclass WhereFilter(dbtClassMixin):\n    where_sql_template: str\n\n    def call_parameter_sets(\n        self, custom_granularity_names: Sequence[str]\n    ) -> JinjaCallParameterSets:\n        return JinjaObjectParser.parse_call_parameter_sets(\n            self.where_sql_template,\n            custom_granularity_names=custom_granularity_names,\n            query_item_location=QueryItemLocation.NON_ORDER_BY,\n        )\n\n\n@dataclass\nclass WhereFilterIntersection(dbtClassMixin):\n    where_filters: List[WhereFilter]\n\n    def filter_expression_parameter_sets(\n        self, custom_granularity_names: Sequence[str]\n    ) -> Sequence[Tuple[str, JinjaCallParameterSets]]:\n        raise NotImplementedError\n\n\n@dataclass\nclass FileSlice(dbtClassMixin):\n    \"\"\"Provides file slice level context about what something was created from.\n\n    Implementation of the dbt-semantic-interfaces `FileSlice` protocol\n    \"\"\"\n\n    filename: str\n    content: str\n    start_line_number: int\n    end_line_number: int\n\n\n@dataclass\nclass SourceFileMetadata(dbtClassMixin):\n    \"\"\"Provides file context about what something was created from.\n\n    Implementation of the dbt-semantic-interfaces `Metadata` protocol\n    \"\"\"\n\n    repo_file_path: str\n    file_slice: FileSlice\n\n\n@dataclass\nclass MeasureAggregationParameters(dbtClassMixin):\n    percentile: Optional[float] = None\n    use_discrete_percentile: bool = False\n    use_approximate_percentile: bool = False\n\n\n@dataclass\nclass NonAdditiveDimension(dbtClassMixin):\n    name: str\n    window_choice: AggregationType\n    window_groupings: List[str]\n"
  },
  {
    "path": "core/dbt/artifacts/resources/v1/semantic_model.py",
    "content": "import time\nfrom dataclasses import dataclass, field\nfrom typing import Any, Dict, List, Optional, Sequence\n\nfrom dbt.artifacts.resources import SourceFileMetadata\nfrom dbt.artifacts.resources.base import GraphResource\nfrom dbt.artifacts.resources.v1.components import DependsOn, RefArgs\nfrom dbt.artifacts.resources.v1.metric import Metric\nfrom dbt.artifacts.resources.v1.semantic_layer_components import (\n    MeasureAggregationParameters,\n    NonAdditiveDimension,\n)\nfrom dbt_common.contracts.config.base import BaseConfig, CompareBehavior, MergeBehavior\nfrom dbt_common.dataclass_schema import dbtClassMixin\nfrom dbt_semantic_interfaces.references import (\n    DimensionReference,\n    EntityReference,\n    LinkableElementReference,\n    MeasureReference,\n    SemanticModelReference,\n    TimeDimensionReference,\n)\nfrom dbt_semantic_interfaces.type_enums import (\n    AggregationType,\n    DimensionType,\n    EntityType,\n    MetricType,\n    TimeGranularity,\n)\n\n\"\"\"\nThe classes in this file are dataclasses which are used to construct the Semantic\nModel node in dbt-core. Additionally, these classes need to at a minimum support\nwhat is specified in their protocol definitions in dbt-semantic-interfaces.\nTheir protocol definitions can be found here:\nhttps://github.com/dbt-labs/dbt-semantic-interfaces/blob/main/dbt_semantic_interfaces/protocols/semantic_model.py\n\"\"\"\n\n\n@dataclass\nclass SemanticLayerElementConfig(dbtClassMixin):\n    meta: Dict[str, Any] = field(\n        default_factory=dict,\n        metadata=MergeBehavior.Update.meta(),\n    )\n\n\n@dataclass\nclass Defaults(dbtClassMixin):\n    agg_time_dimension: Optional[str] = None\n\n\n@dataclass\nclass NodeRelation(dbtClassMixin):\n    alias: str\n    schema_name: str  # TODO: Could this be called simply \"schema\" so we could reuse StateRelation?\n    database: Optional[str] = None\n    relation_name: Optional[str] = \"\"\n\n\n# ====================================\n# Dimension objects\n# Dimension protocols: https://github.com/dbt-labs/dbt-semantic-interfaces/blob/main/dbt_semantic_interfaces/protocols/dimension.py\n# ====================================\n\n\n@dataclass\nclass DimensionValidityParams(dbtClassMixin):\n    is_start: bool = False\n    is_end: bool = False\n\n\n@dataclass\nclass DimensionTypeParams(dbtClassMixin):\n    time_granularity: TimeGranularity\n    validity_params: Optional[DimensionValidityParams] = None\n\n\n@dataclass\nclass Dimension(dbtClassMixin):\n    name: str\n    type: DimensionType\n    description: Optional[str] = None\n    label: Optional[str] = None\n    is_partition: bool = False\n    type_params: Optional[DimensionTypeParams] = None\n    expr: Optional[str] = None\n    metadata: Optional[SourceFileMetadata] = None\n    config: Optional[SemanticLayerElementConfig] = None\n\n    @property\n    def reference(self) -> DimensionReference:\n        return DimensionReference(element_name=self.name)\n\n    @property\n    def time_dimension_reference(self) -> Optional[TimeDimensionReference]:\n        if self.type == DimensionType.TIME:\n            return TimeDimensionReference(element_name=self.name)\n        else:\n            return None\n\n    @property\n    def validity_params(self) -> Optional[DimensionValidityParams]:\n        if self.type_params:\n            return self.type_params.validity_params\n        else:\n            return None\n\n\n# ====================================\n# Entity objects\n# Entity protocols: https://github.com/dbt-labs/dbt-semantic-interfaces/blob/main/dbt_semantic_interfaces/protocols/entity.py\n# ====================================\n\n\n@dataclass\nclass Entity(dbtClassMixin):\n    name: str\n    type: EntityType\n    description: Optional[str] = None\n    label: Optional[str] = None\n    role: Optional[str] = None\n    expr: Optional[str] = None\n    config: Optional[SemanticLayerElementConfig] = None\n\n    @property\n    def reference(self) -> EntityReference:\n        return EntityReference(element_name=self.name)\n\n    @property\n    def is_linkable_entity_type(self) -> bool:\n        return self.type in (EntityType.PRIMARY, EntityType.UNIQUE, EntityType.NATURAL)\n\n\n# ====================================\n# Measure object\n# Measure protocols: https://github.com/dbt-labs/dbt-semantic-interfaces/blob/main/dbt_semantic_interfaces/protocols/measure.py\n# ====================================\n\n\n@dataclass\nclass Measure(dbtClassMixin):\n    name: str\n    agg: AggregationType\n    description: Optional[str] = None\n    label: Optional[str] = None\n    create_metric: bool = False\n    expr: Optional[str] = None\n    agg_params: Optional[MeasureAggregationParameters] = None\n    non_additive_dimension: Optional[NonAdditiveDimension] = None\n    agg_time_dimension: Optional[str] = None\n    config: Optional[SemanticLayerElementConfig] = None\n\n    @property\n    def reference(self) -> MeasureReference:\n        return MeasureReference(element_name=self.name)\n\n\n# ====================================\n# SemanticModel final parts\n# ====================================\n\n\n@dataclass\nclass SemanticModelConfig(BaseConfig):\n    enabled: bool = True\n    group: Optional[str] = field(\n        default=None,\n        metadata=CompareBehavior.Exclude.meta(),\n    )\n    meta: Dict[str, Any] = field(\n        default_factory=dict,\n        metadata=MergeBehavior.Update.meta(),\n    )\n\n\n@dataclass\nclass SemanticModel(GraphResource):\n    model: str\n    node_relation: Optional[NodeRelation]\n    description: Optional[str] = None\n    label: Optional[str] = None\n    defaults: Optional[Defaults] = None\n    entities: Sequence[Entity] = field(default_factory=list)\n    measures: Sequence[Measure] = field(default_factory=list)\n    dimensions: Sequence[Dimension] = field(default_factory=list)\n    metadata: Optional[SourceFileMetadata] = None\n    depends_on: DependsOn = field(default_factory=DependsOn)\n    refs: List[RefArgs] = field(default_factory=list)\n    created_at: float = field(default_factory=lambda: time.time())\n    config: SemanticModelConfig = field(default_factory=SemanticModelConfig)\n    unrendered_config: Dict[str, Any] = field(default_factory=dict)\n    primary_entity: Optional[str] = None\n    group: Optional[str] = None\n\n    @property\n    def entity_references(self) -> List[LinkableElementReference]:\n        return [entity.reference for entity in self.entities]\n\n    @property\n    def dimension_references(self) -> List[LinkableElementReference]:\n        return [dimension.reference for dimension in self.dimensions]\n\n    @property\n    def measure_references(self) -> List[MeasureReference]:\n        return [measure.reference for measure in self.measures]\n\n    @property\n    def has_validity_dimensions(self) -> bool:\n        return any([dim.validity_params is not None for dim in self.dimensions])\n\n    @property\n    def validity_start_dimension(self) -> Optional[Dimension]:\n        validity_start_dims = [\n            dim for dim in self.dimensions if dim.validity_params and dim.validity_params.is_start\n        ]\n        if not validity_start_dims:\n            return None\n        return validity_start_dims[0]\n\n    @property\n    def validity_end_dimension(self) -> Optional[Dimension]:\n        validity_end_dims = [\n            dim for dim in self.dimensions if dim.validity_params and dim.validity_params.is_end\n        ]\n        if not validity_end_dims:\n            return None\n        return validity_end_dims[0]\n\n    @property\n    def partitions(self) -> List[Dimension]:  # noqa: D\n        return [dim for dim in self.dimensions or [] if dim.is_partition]\n\n    @property\n    def partition(self) -> Optional[Dimension]:\n        partitions = self.partitions\n        if not partitions:\n            return None\n        return partitions[0]\n\n    @property\n    def reference(self) -> SemanticModelReference:\n        return SemanticModelReference(semantic_model_name=self.name)\n\n    def checked_agg_time_dimension_for_measure(\n        self, measure_reference: MeasureReference\n    ) -> TimeDimensionReference:\n        measure: Optional[Measure] = None\n        for measure in self.measures:\n            if measure.reference == measure_reference:\n                measure = measure\n\n        assert (\n            measure is not None\n        ), f\"No measure with name ({measure_reference.element_name}) in semantic_model with name ({self.name})\"\n\n        default_agg_time_dimension = (\n            self.defaults.agg_time_dimension if self.defaults is not None else None\n        )\n\n        agg_time_dimension_name = measure.agg_time_dimension or default_agg_time_dimension\n        assert agg_time_dimension_name is not None, (\n            f\"Aggregation time dimension for measure {measure.name} on semantic model {self.name} is not set! \"\n            \"To fix this either specify a default `agg_time_dimension` for the semantic model or define an \"\n            \"`agg_time_dimension` on the measure directly.\"\n        )\n        return TimeDimensionReference(element_name=agg_time_dimension_name)\n\n    def checked_agg_time_dimension_for_simple_metric(\n        self, metric: Metric\n    ) -> TimeDimensionReference:\n        assert (\n            metric.type == MetricType.SIMPLE\n        ), \"Only simple metrics can have an agg time dimension.\"\n        metric_agg_params = metric.type_params.metric_aggregation_params\n        # There are validations elsewhere to check this for metrics and provide messaging for it.\n        assert metric_agg_params, \"Simple metrics must have metric_aggregation_params.\"\n        # This indicates a validation bug / dev error, not a user error that should appear\n        # in a user's YAML.\n        assert (\n            metric_agg_params.semantic_model == self.name\n        ), \"Cannot retrieve the agg time dimension for a metric from a different model \"\n        f\"than the one that the metric belongs to. Metric `{metric.name}` belongs to model \"\n        f\"`{metric_agg_params.semantic_model}`, but we requested the agg time dimension from model `{self.name}`.\"\n\n        metric_time_dimension_name = None\n        if (\n            metric.type_params\n            and metric.type_params.metric_aggregation_params\n            and metric.type_params.metric_aggregation_params.agg_time_dimension\n        ):\n            metric_time_dimension_name = (\n                metric.type_params.metric_aggregation_params.agg_time_dimension\n            )\n\n        default_agg_time_dimension = (\n            self.defaults.agg_time_dimension if self.defaults is not None else None\n        )\n        agg_time_dimension_name = metric_time_dimension_name or default_agg_time_dimension\n\n        assert agg_time_dimension_name is not None, (\n            f\"Aggregation time dimension for metric {metric.name} is not set! This should either be set directly on \"\n            f\"the metric specification in the model, or else defaulted to the time dimension in the data \"\n            f\"source containing the metric.\"\n        )\n        return TimeDimensionReference(element_name=agg_time_dimension_name)\n\n    @property\n    def primary_entity_reference(self) -> Optional[EntityReference]:\n        return (\n            EntityReference(element_name=self.primary_entity)\n            if self.primary_entity is not None\n            else None\n        )\n"
  },
  {
    "path": "core/dbt/artifacts/resources/v1/singular_test.py",
    "content": "from dataclasses import dataclass, field\nfrom typing import Literal\n\nfrom dbt.artifacts.resources.types import NodeType\nfrom dbt.artifacts.resources.v1.components import CompiledResource\nfrom dbt.artifacts.resources.v1.config import TestConfig\n\n\n@dataclass\nclass SingularTest(CompiledResource):\n    resource_type: Literal[NodeType.Test]\n    # Was not able to make mypy happy and keep the code working. We need to\n    # refactor the various configs.\n    config: TestConfig = field(default_factory=TestConfig)  # type: ignore\n"
  },
  {
    "path": "core/dbt/artifacts/resources/v1/snapshot.py",
    "content": "from dataclasses import dataclass, field\nfrom typing import Dict, List, Literal, Optional, Union\n\nfrom dbt.artifacts.resources.types import NodeType\nfrom dbt.artifacts.resources.v1.components import CompiledResource, DeferRelation\nfrom dbt.artifacts.resources.v1.config import NodeConfig\nfrom dbt_common.dataclass_schema import ValidationError, dbtClassMixin\n\n\n@dataclass\nclass SnapshotMetaColumnNames(dbtClassMixin):\n    dbt_valid_to: Optional[str] = None\n    dbt_valid_from: Optional[str] = None\n    dbt_scd_id: Optional[str] = None\n    dbt_updated_at: Optional[str] = None\n    dbt_is_deleted: Optional[str] = None\n\n\n@dataclass\nclass SnapshotConfig(NodeConfig):\n    materialized: str = \"snapshot\"\n    strategy: Optional[str] = None\n    unique_key: Union[str, List[str], None] = None\n    target_schema: Optional[str] = None\n    target_database: Optional[str] = None\n    updated_at: Optional[str] = None\n    # Not using Optional because of serialization issues with a Union of str and List[str]\n    check_cols: Union[str, List[str], None] = None\n    snapshot_meta_column_names: SnapshotMetaColumnNames = field(\n        default_factory=SnapshotMetaColumnNames\n    )\n    dbt_valid_to_current: Optional[str] = None\n\n    @property\n    def snapshot_table_column_names(self):\n        return {\n            \"dbt_valid_from\": self.snapshot_meta_column_names.dbt_valid_from or \"dbt_valid_from\",\n            \"dbt_valid_to\": self.snapshot_meta_column_names.dbt_valid_to or \"dbt_valid_to\",\n            \"dbt_scd_id\": self.snapshot_meta_column_names.dbt_scd_id or \"dbt_scd_id\",\n            \"dbt_updated_at\": self.snapshot_meta_column_names.dbt_updated_at or \"dbt_updated_at\",\n            \"dbt_is_deleted\": self.snapshot_meta_column_names.dbt_is_deleted or \"dbt_is_deleted\",\n        }\n\n    def final_validate(self):\n        if not self.strategy or not self.unique_key:\n            raise ValidationError(\n                \"Snapshots must be configured with a 'strategy' and 'unique_key'.\"\n            )\n        if self.strategy == \"check\":\n            if not self.check_cols:\n                raise ValidationError(\n                    \"A snapshot configured with the check strategy must \"\n                    \"specify a check_cols configuration.\"\n                )\n            if isinstance(self.check_cols, str) and self.check_cols != \"all\":\n                raise ValidationError(\n                    f\"Invalid value for 'check_cols': {self.check_cols}. \"\n                    \"Expected 'all' or a list of strings.\"\n                )\n        elif self.strategy == \"timestamp\":\n            if not self.updated_at:\n                raise ValidationError(\n                    \"A snapshot configured with the timestamp strategy \"\n                    \"must specify an updated_at configuration.\"\n                )\n            if self.check_cols:\n                raise ValidationError(\"A 'timestamp' snapshot should not have 'check_cols'\")\n        # If the strategy is not 'check' or 'timestamp' it's a custom strategy,\n        # formerly supported with GenericSnapshotConfig\n\n        if self.materialized and self.materialized != \"snapshot\":\n            raise ValidationError(\"A snapshot must have a materialized value of 'snapshot'\")\n\n    # Called by \"calculate_node_config_dict\" in ContextConfigGenerator\n    def finalize_and_validate(self):\n        data = self.to_dict(omit_none=True)\n        self.validate(data)\n        return self.from_dict(data)\n\n\n@dataclass\nclass Snapshot(CompiledResource):\n    resource_type: Literal[NodeType.Snapshot]\n    config: SnapshotConfig\n    defer_relation: Optional[DeferRelation] = None\n\n    def __post_serialize__(self, dct, context: Optional[Dict] = None):\n        dct = super().__post_serialize__(dct, context)\n        if context and context.get(\"artifact\") and \"defer_relation\" in dct:\n            del dct[\"defer_relation\"]\n        return dct\n"
  },
  {
    "path": "core/dbt/artifacts/resources/v1/source_definition.py",
    "content": "import time\nfrom dataclasses import dataclass, field\nfrom typing import Any, Dict, List, Literal, Optional, Union\n\nfrom dbt.artifacts.resources.base import GraphResource\nfrom dbt.artifacts.resources.types import NodeType\nfrom dbt.artifacts.resources.v1.components import (\n    ColumnInfo,\n    FreshnessThreshold,\n    HasRelationMetadata,\n    Quoting,\n)\nfrom dbt.artifacts.resources.v1.config import BaseConfig, MergeBehavior\nfrom dbt_common.contracts.config.properties import AdditionalPropertiesAllowed\nfrom dbt_common.contracts.util import Mergeable\nfrom dbt_common.exceptions import CompilationError\n\n\n@dataclass\nclass SourceConfig(BaseConfig):\n    enabled: bool = True\n    event_time: Any = None\n    freshness: Optional[FreshnessThreshold] = field(default_factory=FreshnessThreshold)\n    loaded_at_field: Optional[str] = None\n    loaded_at_query: Optional[str] = None\n    meta: Dict[str, Any] = field(default_factory=dict, metadata=MergeBehavior.Update.meta())\n    tags: List[str] = field(default_factory=list)\n\n\n@dataclass\nclass ExternalPartition(AdditionalPropertiesAllowed):\n    name: str = \"\"\n    description: str = \"\"\n    data_type: str = \"\"\n    meta: Dict[str, Any] = field(default_factory=dict)\n\n    def __post_init__(self):\n        if self.name == \"\" or self.data_type == \"\":\n            raise CompilationError(\"External partition columns must have names and data types\")\n\n\n@dataclass\nclass ExternalTable(AdditionalPropertiesAllowed, Mergeable):\n    location: Optional[str] = None\n    file_format: Optional[str] = None\n    row_format: Optional[str] = None\n    tbl_properties: Optional[str] = None\n    partitions: Optional[Union[List[str], List[ExternalPartition]]] = None\n\n    def __bool__(self):\n        return self.location is not None\n\n\n@dataclass\nclass ParsedSourceMandatory(GraphResource, HasRelationMetadata):\n    source_name: str\n    source_description: str\n    loader: str\n    identifier: str\n    resource_type: Literal[NodeType.Source]\n\n\n@dataclass\nclass SourceDefinition(ParsedSourceMandatory):\n    quoting: Quoting = field(default_factory=Quoting)\n    loaded_at_field: Optional[str] = None\n    loaded_at_query: Optional[str] = None\n    freshness: Optional[FreshnessThreshold] = None\n    external: Optional[ExternalTable] = None\n    description: str = \"\"\n    columns: Dict[str, ColumnInfo] = field(default_factory=dict)\n    meta: Dict[str, Any] = field(default_factory=dict)\n    source_meta: Dict[str, Any] = field(default_factory=dict)\n    tags: List[str] = field(default_factory=list)\n    config: SourceConfig = field(default_factory=SourceConfig)\n    patch_path: Optional[str] = None\n    unrendered_config: Dict[str, Any] = field(default_factory=dict)\n    relation_name: Optional[str] = None\n    created_at: float = field(default_factory=lambda: time.time())\n    unrendered_database: Optional[str] = None\n    unrendered_schema: Optional[str] = None\n    doc_blocks: List[str] = field(default_factory=list)\n"
  },
  {
    "path": "core/dbt/artifacts/resources/v1/sql_operation.py",
    "content": "from dataclasses import dataclass\nfrom typing import Literal\n\nfrom dbt.artifacts.resources.types import NodeType\nfrom dbt.artifacts.resources.v1.components import CompiledResource\n\n\n@dataclass\nclass SqlOperation(CompiledResource):\n    resource_type: Literal[NodeType.SqlOperation]\n"
  },
  {
    "path": "core/dbt/artifacts/resources/v1/unit_test_definition.py",
    "content": "import time\nfrom dataclasses import dataclass, field\nfrom typing import Any, Dict, List, Optional, Sequence, Union\n\nfrom dbt.artifacts.resources import DependsOn, NodeVersion\nfrom dbt.artifacts.resources.base import GraphResource\nfrom dbt.artifacts.resources.v1.config import list_str, metas\nfrom dbt_common.contracts.config.base import BaseConfig, CompareBehavior, MergeBehavior\nfrom dbt_common.contracts.config.metadata import ShowBehavior\nfrom dbt_common.dataclass_schema import StrEnum, dbtClassMixin\n\n\n@dataclass\nclass UnitTestConfig(BaseConfig):\n    tags: Union[str, List[str]] = field(\n        default_factory=list_str,\n        metadata=metas(ShowBehavior.Hide, MergeBehavior.Append, CompareBehavior.Exclude),\n    )\n    meta: Dict[str, Any] = field(\n        default_factory=dict,\n        metadata=MergeBehavior.Update.meta(),\n    )\n    enabled: bool = True\n\n\nclass UnitTestFormat(StrEnum):\n    CSV = \"csv\"\n    Dict = \"dict\"\n    SQL = \"sql\"\n\n\n@dataclass\nclass UnitTestInputFixture(dbtClassMixin):\n    input: str\n    rows: Optional[Union[str, List[Dict[str, Any]]]] = None\n    format: UnitTestFormat = UnitTestFormat.Dict\n    fixture: Optional[str] = None\n\n\n@dataclass\nclass UnitTestOverrides(dbtClassMixin):\n    macros: Dict[str, Any] = field(default_factory=dict)\n    vars: Dict[str, Any] = field(default_factory=dict)\n    env_vars: Dict[str, Any] = field(default_factory=dict)\n\n\n@dataclass\nclass UnitTestNodeVersions(dbtClassMixin):\n    include: Optional[List[NodeVersion]] = None\n    exclude: Optional[List[NodeVersion]] = None\n\n\n@dataclass\nclass UnitTestOutputFixture(dbtClassMixin):\n    rows: Optional[Union[str, List[Dict[str, Any]]]] = None\n    format: UnitTestFormat = UnitTestFormat.Dict\n    fixture: Optional[str] = None\n\n\n@dataclass\nclass UnitTestDefinitionMandatory:\n    model: str\n    given: Sequence[UnitTestInputFixture]\n    expect: UnitTestOutputFixture\n\n\n@dataclass\nclass UnitTestDefinition(GraphResource, UnitTestDefinitionMandatory):\n    description: str = \"\"\n    overrides: Optional[UnitTestOverrides] = None\n    depends_on: DependsOn = field(default_factory=DependsOn)\n    config: UnitTestConfig = field(default_factory=UnitTestConfig)\n    checksum: Optional[str] = None\n    schema: Optional[str] = None\n    created_at: float = field(default_factory=lambda: time.time())\n    versions: Optional[UnitTestNodeVersions] = None\n    version: Optional[NodeVersion] = None\n"
  },
  {
    "path": "core/dbt/artifacts/schemas/__init__.py",
    "content": ""
  },
  {
    "path": "core/dbt/artifacts/schemas/base.py",
    "content": "import dataclasses\nimport functools\nfrom datetime import datetime, timezone\nfrom typing import Any, ClassVar, Dict, Optional, Type, TypeVar\n\nfrom mashumaro.jsonschema import build_json_schema\nfrom mashumaro.jsonschema.dialects import DRAFT_2020_12\n\nfrom dbt.artifacts.exceptions import IncompatibleSchemaError\nfrom dbt.version import __version__\nfrom dbt_common.clients.system import read_json, write_json\nfrom dbt_common.dataclass_schema import dbtClassMixin\nfrom dbt_common.events.functions import get_metadata_vars\nfrom dbt_common.exceptions import DbtInternalError, DbtRuntimeError\nfrom dbt_common.invocation import get_invocation_id, get_invocation_started_at\n\nBASE_SCHEMAS_URL = \"https://schemas.getdbt.com/\"\nSCHEMA_PATH = \"dbt/{name}/v{version}.json\"\n\n\n@dataclasses.dataclass\nclass SchemaVersion:\n    name: str\n    version: int\n\n    @property\n    def path(self) -> str:\n        return SCHEMA_PATH.format(name=self.name, version=self.version)\n\n    def __str__(self) -> str:\n        return BASE_SCHEMAS_URL + self.path\n\n\nclass Writable:\n    def write(self, path: str):\n        write_json(path, self.to_dict(omit_none=False, context={\"artifact\": True}))  # type: ignore\n\n\nclass Readable:\n    @classmethod\n    def read(cls, path: str):\n        try:\n            data = read_json(path)\n        except (EnvironmentError, ValueError) as exc:\n            raise DbtRuntimeError(\n                f'Could not read {cls.__name__} at \"{path}\" as JSON: {exc}'\n            ) from exc\n\n        return cls.from_dict(data)  # type: ignore\n\n\n# This is used in the ManifestMetadata, RunResultsMetadata, RunOperationResultMetadata,\n# FreshnessMetadata, and CatalogMetadata classes\n@dataclasses.dataclass\nclass BaseArtifactMetadata(dbtClassMixin):\n    dbt_schema_version: str\n    dbt_version: str = __version__\n    generated_at: datetime = dataclasses.field(\n        default_factory=lambda: datetime.now(timezone.utc).replace(tzinfo=None)\n    )\n    invocation_id: Optional[str] = dataclasses.field(default_factory=get_invocation_id)\n    invocation_started_at: Optional[datetime] = dataclasses.field(\n        default_factory=get_invocation_started_at\n    )\n    env: Dict[str, str] = dataclasses.field(default_factory=get_metadata_vars)\n\n    def __post_serialize__(self, dct: Dict, context: Optional[Dict] = None):\n        dct = super().__post_serialize__(dct, context)\n        if dct[\"generated_at\"] and dct[\"generated_at\"].endswith(\"+00:00\"):\n            dct[\"generated_at\"] = dct[\"generated_at\"].replace(\"+00:00\", \"\") + \"Z\"\n        return dct\n\n\n# This is used as a class decorator to set the schema_version in the\n# 'dbt_schema_version' class attribute. (It's copied into the metadata objects.)\n# Name attributes of SchemaVersion in classes with the 'schema_version' decorator:\n#   manifest\n#   run-results\n#   run-operation-result\n#   sources\n#   catalog\n#   remote-compile-result\n#   remote-execution-result\n#   remote-run-result\nS = TypeVar(\"S\", bound=\"VersionedSchema\")\n\n\ndef schema_version(name: str, version: int):\n    def inner(cls: Type[S]):\n        cls.dbt_schema_version = SchemaVersion(\n            name=name,\n            version=version,\n        )\n        return cls\n\n    return inner\n\n\n# This is used in the ArtifactMixin and RemoteCompileResultMixin classes\n@dataclasses.dataclass\nclass VersionedSchema(dbtClassMixin):\n    dbt_schema_version: ClassVar[SchemaVersion]\n\n    @classmethod\n    @functools.lru_cache\n    def json_schema(cls) -> Dict[str, Any]:\n        json_schema_obj = build_json_schema(cls, dialect=DRAFT_2020_12, with_dialect_uri=True)\n        json_schema = json_schema_obj.to_dict()\n        json_schema[\"$id\"] = str(cls.dbt_schema_version)\n        return json_schema\n\n    @classmethod\n    def is_compatible_version(cls, schema_version):\n        compatible_versions = [str(cls.dbt_schema_version)]\n        if hasattr(cls, \"compatible_previous_versions\"):\n            for name, version in cls.compatible_previous_versions():\n                compatible_versions.append(str(SchemaVersion(name, version)))\n        return str(schema_version) in compatible_versions\n\n    @classmethod\n    def read_and_check_versions(cls, path: str):\n        try:\n            data = read_json(path)\n        except (EnvironmentError, ValueError) as exc:\n            raise DbtRuntimeError(\n                f'Could not read {cls.__name__} at \"{path}\" as JSON: {exc}'\n            ) from exc\n\n        # Check metadata version. There is a class variable 'dbt_schema_version', but\n        # that doesn't show up in artifacts, where it only exists in the 'metadata'\n        # dictionary.\n        if hasattr(cls, \"dbt_schema_version\"):\n            if \"metadata\" in data and \"dbt_schema_version\" in data[\"metadata\"]:\n                previous_schema_version = data[\"metadata\"][\"dbt_schema_version\"]\n                # cls.dbt_schema_version is a SchemaVersion object\n                if not cls.is_compatible_version(previous_schema_version):\n                    raise IncompatibleSchemaError(\n                        expected=str(cls.dbt_schema_version),\n                        found=previous_schema_version,\n                    )\n\n        return cls.upgrade_schema_version(data)\n\n    @classmethod\n    def upgrade_schema_version(cls, data):\n        \"\"\"This will modify the data (dictionary) passed in to match the current\n        artifact schema code, if necessary. This is the default method, which\n        just returns the instantiated object via from_dict.\"\"\"\n        return cls.from_dict(data)\n\n\nT = TypeVar(\"T\", bound=\"ArtifactMixin\")\n\n\n# metadata should really be a Generic[T_M] where T_M is a TypeVar bound to\n# BaseArtifactMetadata. Unfortunately this isn't possible due to a mypy issue:\n# https://github.com/python/mypy/issues/7520\n# This is used in the WritableManifest, RunResultsArtifact, RunOperationResultsArtifact,\n# and CatalogArtifact\n@dataclasses.dataclass(init=False)\nclass ArtifactMixin(VersionedSchema, Writable, Readable):\n    metadata: BaseArtifactMetadata\n\n    @classmethod\n    def validate(cls, data):\n        super().validate(data)\n        if cls.dbt_schema_version is None:\n            raise DbtInternalError(\"Cannot call from_dict with no schema version!\")\n\n\ndef get_artifact_schema_version(dct: dict) -> int:\n    schema_version = dct.get(\"metadata\", {}).get(\"dbt_schema_version\", None)\n    if not schema_version:\n        raise ValueError(\"Artifact is missing schema version\")\n\n    # schema_version is in this format: https://schemas.getdbt.com/dbt/manifest/v10.json\n    # What the code below is doing:\n    # 1. Split on \"/\" – v10.json\n    # 2. Split on \".\" – v10\n    # 3. Skip first character – 10\n    # 4. Convert to int\n    # TODO: If this gets more complicated, turn into a regex\n    return int(schema_version.split(\"/\")[-1].split(\".\")[0][1:])\n\n\ndef get_artifact_dbt_version(dct: dict) -> Optional[str]:\n    dbt_version = dct.get(\"metadata\", {}).get(\"dbt_version\", None)\n    if dbt_version is None:\n        return None\n\n    return str(dbt_version)\n"
  },
  {
    "path": "core/dbt/artifacts/schemas/batch_results.py",
    "content": "from __future__ import annotations\n\nfrom dataclasses import dataclass, field\nfrom datetime import datetime\nfrom typing import List, Tuple\n\nfrom dbt_common.dataclass_schema import dbtClassMixin\n\nBatchType = Tuple[datetime, datetime]\n\n\n@dataclass\nclass BatchResults(dbtClassMixin):\n    successful: List[BatchType] = field(default_factory=list)\n    failed: List[BatchType] = field(default_factory=list)\n\n    def __add__(self, other: BatchResults) -> BatchResults:\n        return BatchResults(\n            successful=self.successful + other.successful,\n            failed=self.failed + other.failed,\n        )\n\n    def __len__(self):\n        return len(self.successful) + len(self.failed)\n"
  },
  {
    "path": "core/dbt/artifacts/schemas/catalog/__init__.py",
    "content": "# alias to latest\nfrom dbt.artifacts.schemas.catalog.v1.catalog import *  # noqa\nfrom dbt_common.contracts.metadata import (\n    CatalogKey,\n    CatalogTable,\n    ColumnMap,\n    ColumnMetadata,\n    StatsDict,\n    StatsItem,\n    TableMetadata,\n)\n"
  },
  {
    "path": "core/dbt/artifacts/schemas/catalog/v1/__init__.py",
    "content": ""
  },
  {
    "path": "core/dbt/artifacts/schemas/catalog/v1/catalog.py",
    "content": "from dataclasses import dataclass, field\nfrom datetime import datetime\nfrom typing import Any, Dict, List, Optional, Union\n\nfrom dbt.artifacts.schemas.base import (\n    ArtifactMixin,\n    BaseArtifactMetadata,\n    schema_version,\n)\nfrom dbt_common.contracts.metadata import CatalogTable\nfrom dbt_common.dataclass_schema import dbtClassMixin\n\nPrimitive = Union[bool, str, float, None]\nPrimitiveDict = Dict[str, Primitive]\n\n\n@dataclass\nclass CatalogMetadata(BaseArtifactMetadata):\n    dbt_schema_version: str = field(\n        default_factory=lambda: str(CatalogArtifact.dbt_schema_version)\n    )\n\n\n@dataclass\nclass CatalogResults(dbtClassMixin):\n    nodes: Dict[str, CatalogTable]\n    sources: Dict[str, CatalogTable]\n    errors: Optional[List[str]] = None\n    _compile_results: Optional[Any] = None\n\n    def __post_serialize__(self, dct: Dict, context: Optional[Dict] = None):\n        dct = super().__post_serialize__(dct, context)\n        if \"_compile_results\" in dct:\n            del dct[\"_compile_results\"]\n        return dct\n\n\n@dataclass\n@schema_version(\"catalog\", 1)\nclass CatalogArtifact(CatalogResults, ArtifactMixin):\n    metadata: CatalogMetadata\n\n    @classmethod\n    def from_results(\n        cls,\n        generated_at: datetime,\n        nodes: Dict[str, CatalogTable],\n        sources: Dict[str, CatalogTable],\n        compile_results: Optional[Any],\n        errors: Optional[List[str]],\n    ) -> \"CatalogArtifact\":\n        meta = CatalogMetadata(generated_at=generated_at)\n        return cls(\n            metadata=meta,\n            nodes=nodes,\n            sources=sources,\n            errors=errors,\n            _compile_results=compile_results,\n        )\n"
  },
  {
    "path": "core/dbt/artifacts/schemas/freshness/__init__.py",
    "content": "from dbt.artifacts.schemas.freshness.v3.freshness import *  # noqa\n"
  },
  {
    "path": "core/dbt/artifacts/schemas/freshness/v3/__init__.py",
    "content": ""
  },
  {
    "path": "core/dbt/artifacts/schemas/freshness/v3/freshness.py",
    "content": "from dataclasses import dataclass, field\nfrom datetime import datetime\nfrom typing import Any, Dict, List, Optional, Sequence, Union\n\nfrom dbt.artifacts.resources import FreshnessThreshold\nfrom dbt.artifacts.schemas.base import (\n    ArtifactMixin,\n    BaseArtifactMetadata,\n    VersionedSchema,\n    schema_version,\n)\nfrom dbt.artifacts.schemas.results import (\n    ExecutionResult,\n    FreshnessStatus,\n    NodeResult,\n    TimingInfo,\n)\nfrom dbt.contracts.graph.nodes import SourceDefinition\nfrom dbt_common.dataclass_schema import StrEnum, dbtClassMixin\nfrom dbt_common.exceptions import DbtInternalError\n\n\n@dataclass\nclass SourceFreshnessResult(NodeResult):\n    node: SourceDefinition\n    status: FreshnessStatus\n    max_loaded_at: datetime\n    snapshotted_at: datetime\n    age: float\n\n    @property\n    def skipped(self):\n        return False\n\n\n@dataclass\nclass PartialSourceFreshnessResult(NodeResult):\n    status: FreshnessStatus\n\n    @property\n    def skipped(self):\n        return False\n\n\nFreshnessNodeResult = Union[PartialSourceFreshnessResult, SourceFreshnessResult]\n\n\n@dataclass\nclass FreshnessMetadata(BaseArtifactMetadata):\n    dbt_schema_version: str = field(\n        default_factory=lambda: str(FreshnessExecutionResultArtifact.dbt_schema_version)\n    )\n\n\n@dataclass\nclass FreshnessResult(ExecutionResult):\n    metadata: FreshnessMetadata\n    results: Sequence[FreshnessNodeResult]\n\n    @classmethod\n    def from_node_results(\n        cls,\n        results: List[FreshnessNodeResult],\n        elapsed_time: float,\n        generated_at: datetime,\n    ):\n        meta = FreshnessMetadata(generated_at=generated_at)\n        return cls(metadata=meta, results=results, elapsed_time=elapsed_time)\n\n    def write(self, path):\n        FreshnessExecutionResultArtifact.from_result(self).write(path)\n\n\n@dataclass\nclass SourceFreshnessOutput(dbtClassMixin):\n    unique_id: str\n    max_loaded_at: datetime\n    snapshotted_at: datetime\n    max_loaded_at_time_ago_in_s: float\n    status: FreshnessStatus\n    criteria: FreshnessThreshold\n    adapter_response: Dict[str, Any]\n    timing: List[TimingInfo]\n    thread_id: str\n    execution_time: float\n\n\nclass FreshnessErrorEnum(StrEnum):\n    runtime_error = \"runtime error\"\n\n\n@dataclass\nclass SourceFreshnessRuntimeError(dbtClassMixin):\n    unique_id: str\n    error: Optional[Union[str, int]]\n    status: FreshnessErrorEnum\n\n\nFreshnessNodeOutput = Union[SourceFreshnessRuntimeError, SourceFreshnessOutput]\n\n\n@dataclass\n@schema_version(\"sources\", 3)\nclass FreshnessExecutionResultArtifact(\n    ArtifactMixin,\n    VersionedSchema,\n):\n    metadata: FreshnessMetadata\n    results: Sequence[FreshnessNodeOutput]\n    elapsed_time: float\n\n    @classmethod\n    def from_result(cls, base: FreshnessResult):\n        processed = [\n            process_freshness_result(r)\n            for r in base.results\n            if isinstance(r, SourceFreshnessResult)\n        ]\n        return cls(\n            metadata=base.metadata,\n            results=processed,\n            elapsed_time=base.elapsed_time,\n        )\n\n\ndef process_freshness_result(result: FreshnessNodeResult) -> FreshnessNodeOutput:\n    unique_id = result.node.unique_id\n    if result.status == FreshnessStatus.RuntimeErr:\n        return SourceFreshnessRuntimeError(\n            unique_id=unique_id,\n            error=result.message,\n            status=FreshnessErrorEnum.runtime_error,\n        )\n\n    # we know that this must be a SourceFreshnessResult\n    if not isinstance(result, SourceFreshnessResult):\n        raise DbtInternalError(\n            \"Got {} instead of a SourceFreshnessResult for a \"\n            \"non-error result in freshness execution!\".format(type(result))\n        )\n    # if we're here, we must have a non-None freshness threshold\n    criteria = result.node.freshness\n    if criteria is None:\n        raise DbtInternalError(\n            \"Somehow evaluated a freshness result for a source that has no freshness criteria!\"\n        )\n    return SourceFreshnessOutput(\n        unique_id=unique_id,\n        max_loaded_at=result.max_loaded_at,\n        snapshotted_at=result.snapshotted_at,\n        max_loaded_at_time_ago_in_s=result.age,\n        status=result.status,\n        criteria=criteria,\n        adapter_response=result.adapter_response,\n        timing=result.timing,\n        thread_id=result.thread_id,\n        execution_time=result.execution_time,\n    )\n"
  },
  {
    "path": "core/dbt/artifacts/schemas/manifest/__init__.py",
    "content": "# alias to latest\nfrom dbt.artifacts.schemas.manifest.v12.manifest import *  # noqa\n"
  },
  {
    "path": "core/dbt/artifacts/schemas/manifest/v12/__init__.py",
    "content": ""
  },
  {
    "path": "core/dbt/artifacts/schemas/manifest/v12/manifest.py",
    "content": "from dataclasses import dataclass, field\nfrom datetime import datetime\nfrom typing import Any, Dict, Iterable, List, Mapping, Optional, Tuple, Union\nfrom uuid import UUID\n\nfrom dbt import tracking\nfrom dbt.artifacts.resources import (\n    Analysis,\n    Documentation,\n    Exposure,\n    Function,\n    GenericTest,\n    Group,\n    HookNode,\n    Macro,\n    Metric,\n    Model,\n    SavedQuery,\n    Seed,\n    SemanticModel,\n    SingularTest,\n    Snapshot,\n    SourceDefinition,\n    SqlOperation,\n    UnitTestDefinition,\n)\nfrom dbt.artifacts.resources.v1.components import Quoting\nfrom dbt.artifacts.schemas.base import (\n    ArtifactMixin,\n    BaseArtifactMetadata,\n    get_artifact_dbt_version,\n    get_artifact_schema_version,\n    schema_version,\n)\nfrom dbt.artifacts.schemas.upgrades import (\n    upgrade_manifest_json,\n    upgrade_manifest_json_dbt_version,\n)\nfrom dbt.version import __version__\nfrom dbt_common.exceptions import DbtInternalError\n\nNodeEdgeMap = Dict[str, List[str]]\nUniqueID = str\nManifestResource = Union[\n    Seed, Analysis, SingularTest, HookNode, Model, SqlOperation, GenericTest, Snapshot, Function\n]\nDisabledManifestResource = Union[\n    ManifestResource,\n    SourceDefinition,\n    Exposure,\n    Metric,\n    SavedQuery,\n    SemanticModel,\n    UnitTestDefinition,\n]\n\n\n@dataclass\nclass ManifestMetadata(BaseArtifactMetadata):\n    \"\"\"Metadata for the manifest.\"\"\"\n\n    dbt_schema_version: str = field(\n        default_factory=lambda: str(WritableManifest.dbt_schema_version)\n    )\n    project_name: Optional[str] = field(\n        default=None,\n        metadata={\n            \"description\": \"Name of the root project\",\n        },\n    )\n    project_id: Optional[str] = field(\n        default=None,\n        metadata={\n            \"description\": \"A unique identifier for the project, hashed from the project name\",\n        },\n    )\n    user_id: Optional[UUID] = field(\n        default=None,\n        metadata={\n            \"description\": \"A unique identifier for the user\",\n        },\n    )\n    send_anonymous_usage_stats: Optional[bool] = field(\n        default=None,\n        metadata=dict(\n            description=(\"Whether dbt is configured to send anonymous usage statistics\")\n        ),\n    )\n    adapter_type: Optional[str] = field(\n        default=None,\n        metadata=dict(description=\"The type name of the adapter\"),\n    )\n    quoting: Optional[Quoting] = field(\n        default_factory=Quoting,\n        metadata=dict(description=\"The quoting configuration for the project\"),\n    )\n    run_started_at: Optional[datetime] = field(\n        default=tracking.active_user.run_started_at if tracking.active_user is not None else None,\n        metadata=dict(description=\"The timestamp when the run started\"),\n    )\n\n    @classmethod\n    def default(cls):\n        return cls(\n            dbt_schema_version=str(WritableManifest.dbt_schema_version),\n        )\n\n\n@dataclass\n@schema_version(\"manifest\", 12)\nclass WritableManifest(ArtifactMixin):\n    nodes: Mapping[UniqueID, ManifestResource] = field(\n        metadata=dict(description=(\"The nodes defined in the dbt project and its dependencies\"))\n    )\n    sources: Mapping[UniqueID, SourceDefinition] = field(\n        metadata=dict(description=(\"The sources defined in the dbt project and its dependencies\"))\n    )\n    macros: Mapping[UniqueID, Macro] = field(\n        metadata=dict(description=(\"The macros defined in the dbt project and its dependencies\"))\n    )\n    docs: Mapping[UniqueID, Documentation] = field(\n        metadata=dict(description=(\"The docs defined in the dbt project and its dependencies\"))\n    )\n    exposures: Mapping[UniqueID, Exposure] = field(\n        metadata=dict(\n            description=(\"The exposures defined in the dbt project and its dependencies\")\n        )\n    )\n    metrics: Mapping[UniqueID, Metric] = field(\n        metadata=dict(description=(\"The metrics defined in the dbt project and its dependencies\"))\n    )\n    groups: Mapping[UniqueID, Group] = field(\n        metadata=dict(description=(\"The groups defined in the dbt project\"))\n    )\n    selectors: Mapping[UniqueID, Any] = field(\n        metadata=dict(description=(\"The selectors defined in selectors.yml\"))\n    )\n    disabled: Optional[Mapping[UniqueID, List[DisabledManifestResource]]] = field(\n        metadata=dict(description=\"A mapping of the disabled nodes in the target\")\n    )\n    parent_map: Optional[NodeEdgeMap] = field(\n        metadata=dict(\n            description=\"A mapping from child nodes to their dependencies\",\n        )\n    )\n    child_map: Optional[NodeEdgeMap] = field(\n        metadata=dict(\n            description=\"A mapping from parent nodes to their dependents\",\n        )\n    )\n    group_map: Optional[NodeEdgeMap] = field(\n        metadata=dict(\n            description=\"A mapping from group names to their nodes\",\n        )\n    )\n    saved_queries: Mapping[UniqueID, SavedQuery] = field(\n        metadata=dict(description=(\"The saved queries defined in the dbt project\"))\n    )\n    semantic_models: Mapping[UniqueID, SemanticModel] = field(\n        metadata=dict(description=(\"The semantic models defined in the dbt project\"))\n    )\n    metadata: ManifestMetadata = field(\n        metadata=dict(\n            description=\"Metadata about the manifest\",\n        )\n    )\n    unit_tests: Mapping[UniqueID, UnitTestDefinition] = field(\n        metadata=dict(\n            description=\"The unit tests defined in the project\",\n        )\n    )\n    functions: Mapping[UniqueID, Function] = field(\n        default_factory=dict,\n        metadata=dict(description=(\"The functions defined in the dbt project\")),\n    )\n\n    @classmethod\n    def compatible_previous_versions(cls) -> Iterable[Tuple[str, int]]:\n        return [\n            (\"manifest\", 4),\n            (\"manifest\", 5),\n            (\"manifest\", 6),\n            (\"manifest\", 7),\n            (\"manifest\", 8),\n            (\"manifest\", 9),\n            (\"manifest\", 10),\n            (\"manifest\", 11),\n        ]\n\n    @classmethod\n    def upgrade_schema_version(cls, data):\n        \"\"\"This overrides the \"upgrade_schema_version\" call in VersionedSchema (via\n        ArtifactMixin) to modify the dictionary passed in from earlier versions of the manifest.\"\"\"\n        manifest_schema_version = get_artifact_schema_version(data)\n        if manifest_schema_version < cls.dbt_schema_version.version:\n            data = upgrade_manifest_json(data, manifest_schema_version)\n\n        manifest_dbt_version = get_artifact_dbt_version(data)\n        if manifest_dbt_version and manifest_dbt_version != __version__:\n            data = upgrade_manifest_json_dbt_version(data)\n        return cls.from_dict(data)\n\n    @classmethod\n    def validate(cls, _):\n        # When dbt try to load an artifact with additional optional fields\n        # that are not present in the schema, from_dict will work fine.\n        # As long as validate is not called, the schema will not be enforced.\n        # This is intentional, as it allows for safer schema upgrades.\n        raise DbtInternalError(\n            \"The WritableManifest should never be validated directly to allow for schema upgrades.\"\n        )\n"
  },
  {
    "path": "core/dbt/artifacts/schemas/results.py",
    "content": "from dataclasses import dataclass\nfrom datetime import datetime, timezone\nfrom typing import Any, Callable, Dict, List, Optional, Sequence, Union\n\nfrom dbt.contracts.graph.nodes import ResultNode\nfrom dbt_common.dataclass_schema import StrEnum, dbtClassMixin\nfrom dbt_common.events.helpers import datetime_to_json_string\nfrom dbt_common.utils import cast_to_int, cast_to_str\n\n\n@dataclass\nclass TimingInfo(dbtClassMixin):\n    \"\"\"\n    Represents a step in the execution of a node.\n    `name` should be one of: compile, execute, or other\n    Do not call directly, use `collect_timing_info` instead.\n    \"\"\"\n\n    name: str\n    started_at: Optional[datetime] = None\n    completed_at: Optional[datetime] = None\n\n    def begin(self):\n        self.started_at = datetime.now(timezone.utc).replace(tzinfo=None)\n\n    def end(self):\n        self.completed_at = datetime.now(timezone.utc).replace(tzinfo=None)\n\n    def to_msg_dict(self):\n        msg_dict = {\"name\": str(self.name)}\n        if self.started_at:\n            msg_dict[\"started_at\"] = datetime_to_json_string(self.started_at)\n        if self.completed_at:\n            msg_dict[\"completed_at\"] = datetime_to_json_string(self.completed_at)\n        return msg_dict\n\n\n# This is a context manager\nclass collect_timing_info:\n    def __init__(self, name: str, callback: Callable[[TimingInfo], None]) -> None:\n        self.timing_info = TimingInfo(name=name)\n        self.callback = callback\n\n    def __enter__(self):\n        self.timing_info.begin()\n\n    def __exit__(self, exc_type, exc_value, traceback):\n        self.timing_info.end()\n        self.callback(self.timing_info)\n\n\nclass RunningStatus(StrEnum):\n    Started = \"started\"\n    Compiling = \"compiling\"\n    Executing = \"executing\"\n\n\nclass NodeStatus(StrEnum):\n    Success = \"success\"\n    Error = \"error\"\n    Fail = \"fail\"\n    Warn = \"warn\"\n    Skipped = \"skipped\"\n    PartialSuccess = \"partial success\"\n    Pass = \"pass\"\n    RuntimeErr = \"runtime error\"\n    NoOp = \"no-op\"\n\n\nclass RunStatus(StrEnum):\n    Success = NodeStatus.Success\n    Error = NodeStatus.Error\n    Skipped = NodeStatus.Skipped\n    PartialSuccess = NodeStatus.PartialSuccess\n    NoOp = NodeStatus.NoOp\n\n\nclass TestStatus(StrEnum):\n    __test__ = False\n    Pass = NodeStatus.Pass\n    Error = NodeStatus.Error\n    Fail = NodeStatus.Fail\n    Warn = NodeStatus.Warn\n    Skipped = NodeStatus.Skipped\n\n\nclass FreshnessStatus(StrEnum):\n    Pass = NodeStatus.Pass\n    Warn = NodeStatus.Warn\n    Error = NodeStatus.Error\n    RuntimeErr = NodeStatus.RuntimeErr\n\n\n@dataclass\nclass BaseResult(dbtClassMixin):\n    status: Union[RunStatus, TestStatus, FreshnessStatus]\n    timing: List[TimingInfo]\n    thread_id: str\n    execution_time: float\n    adapter_response: Dict[str, Any]\n    message: Optional[str]\n    failures: Optional[int]\n\n    @classmethod\n    def __pre_deserialize__(cls, data):\n        data = super().__pre_deserialize__(data)\n        if \"message\" not in data:\n            data[\"message\"] = None\n        if \"failures\" not in data:\n            data[\"failures\"] = None\n        return data\n\n    def to_msg_dict(self):\n        msg_dict = {\n            \"status\": str(self.status),\n            \"message\": cast_to_str(self.message),\n            \"thread\": self.thread_id,\n            \"execution_time\": self.execution_time,\n            \"num_failures\": cast_to_int(self.failures),\n            \"timing_info\": [ti.to_msg_dict() for ti in self.timing],\n            \"adapter_response\": self.adapter_response,\n        }\n        return msg_dict\n\n\n@dataclass\nclass NodeResult(BaseResult):\n    node: ResultNode\n\n\n@dataclass\nclass ExecutionResult(dbtClassMixin):\n    results: Sequence[BaseResult]\n    elapsed_time: float\n\n    def __len__(self):\n        return len(self.results)\n\n    def __iter__(self):\n        return iter(self.results)\n\n    def __getitem__(self, idx):\n        return self.results[idx]\n\n\n# due to issues with typing.Union collapsing subclasses, this can't subclass\n# PartialResult\n"
  },
  {
    "path": "core/dbt/artifacts/schemas/run/__init__.py",
    "content": "# alias to latest\nfrom dbt.artifacts.schemas.run.v5.run import *  # noqa\n"
  },
  {
    "path": "core/dbt/artifacts/schemas/run/v5/__init__.py",
    "content": ""
  },
  {
    "path": "core/dbt/artifacts/schemas/run/v5/run.py",
    "content": "from __future__ import annotations\n\nimport copy\nimport threading\nfrom dataclasses import dataclass, field\nfrom datetime import datetime, timezone\nfrom typing import Any, Dict, Iterable, Optional, Sequence, Tuple\n\n# https://github.com/dbt-labs/dbt-core/issues/10098\n# Needed for Mashumaro serialization of RunResult below\n# TODO: investigate alternative approaches to restore conditional import\n# if TYPE_CHECKING:\nimport agate\n\nfrom dbt.artifacts.resources import CompiledResource\nfrom dbt.artifacts.schemas.base import (\n    ArtifactMixin,\n    BaseArtifactMetadata,\n    get_artifact_schema_version,\n    schema_version,\n)\nfrom dbt.artifacts.schemas.batch_results import BatchResults\nfrom dbt.artifacts.schemas.results import (\n    BaseResult,\n    ExecutionResult,\n    NodeResult,\n    ResultNode,\n    RunStatus,\n)\nfrom dbt.exceptions import scrub_secrets\nfrom dbt_common.clients.system import write_json\nfrom dbt_common.constants import SECRET_ENV_PREFIX\n\n\n@dataclass\nclass RunResult(NodeResult):\n    agate_table: Optional[\"agate.Table\"] = field(\n        default=None, metadata={\"serialize\": lambda x: None, \"deserialize\": lambda x: None}\n    )\n    batch_results: Optional[BatchResults] = None\n\n    @property\n    def skipped(self):\n        return self.status == RunStatus.Skipped\n\n    @classmethod\n    def from_node(cls, node: ResultNode, status: RunStatus, message: Optional[str]):\n        thread_id = threading.current_thread().name\n        return RunResult(\n            status=status,\n            thread_id=thread_id,\n            execution_time=0,\n            timing=[],\n            message=message,\n            node=node,\n            adapter_response={},\n            failures=None,\n            batch_results=None,\n        )\n\n\n@dataclass\nclass RunResultsMetadata(BaseArtifactMetadata):\n    dbt_schema_version: str = field(\n        default_factory=lambda: str(RunResultsArtifact.dbt_schema_version)\n    )\n\n\n@dataclass\nclass RunResultOutput(BaseResult):\n    unique_id: str\n    compiled: Optional[bool]\n    compiled_code: Optional[str]\n    relation_name: Optional[str]\n    batch_results: Optional[BatchResults] = None\n\n\ndef process_run_result(result: RunResult) -> RunResultOutput:\n\n    compiled = isinstance(result.node, CompiledResource)\n\n    return RunResultOutput(\n        unique_id=result.node.unique_id,\n        status=result.status,\n        timing=result.timing,\n        thread_id=result.thread_id,\n        execution_time=result.execution_time,\n        message=result.message,\n        adapter_response=result.adapter_response,\n        failures=result.failures,\n        batch_results=result.batch_results,\n        compiled=result.node.compiled if compiled else None,  # type:ignore\n        compiled_code=result.node.compiled_code if compiled else None,  # type:ignore\n        relation_name=result.node.relation_name if compiled else None,  # type:ignore\n    )\n\n\n@dataclass\nclass RunExecutionResult(\n    ExecutionResult,\n):\n    results: Sequence[RunResult]\n    args: Dict[str, Any] = field(default_factory=dict)\n    generated_at: datetime = field(\n        default_factory=lambda: datetime.now(timezone.utc).replace(tzinfo=None)\n    )\n\n    def write(self, path: str):\n        writable = RunResultsArtifact.from_execution_results(\n            results=self.results,\n            elapsed_time=self.elapsed_time,\n            generated_at=self.generated_at,\n            args=self.args,\n        )\n        writable.write(path)\n\n\n@dataclass\n@schema_version(\"run-results\", 6)\nclass RunResultsArtifact(ExecutionResult, ArtifactMixin):\n    results: Sequence[RunResultOutput]\n    args: Dict[str, Any] = field(default_factory=dict)\n\n    @classmethod\n    def from_execution_results(\n        cls,\n        results: Sequence[RunResult],\n        elapsed_time: float,\n        generated_at: datetime,\n        args: Dict,\n    ):\n        processed_results = [\n            process_run_result(result) for result in results if isinstance(result, RunResult)\n        ]\n        meta = RunResultsMetadata(\n            dbt_schema_version=str(cls.dbt_schema_version),\n            generated_at=generated_at,\n        )\n\n        secret_vars = [\n            v for k, v in args[\"vars\"].items() if k.startswith(SECRET_ENV_PREFIX) and v.strip()\n        ]\n\n        scrubbed_args = copy.deepcopy(args)\n\n        # scrub secrets in invocation command\n        scrubbed_args[\"invocation_command\"] = scrub_secrets(\n            scrubbed_args[\"invocation_command\"], secret_vars\n        )\n\n        # scrub secrets in vars dict\n        scrubbed_args[\"vars\"] = {\n            k: scrub_secrets(v, secret_vars) for k, v in scrubbed_args[\"vars\"].items()\n        }\n\n        return cls(\n            metadata=meta, results=processed_results, elapsed_time=elapsed_time, args=scrubbed_args\n        )\n\n    @classmethod\n    def compatible_previous_versions(cls) -> Iterable[Tuple[str, int]]:\n        return [\n            (\"run-results\", 4),\n            (\"run-results\", 5),\n        ]\n\n    @classmethod\n    def upgrade_schema_version(cls, data):\n        \"\"\"This overrides the \"upgrade_schema_version\" call in VersionedSchema (via\n        ArtifactMixin) to modify the dictionary passed in from earlier versions of the run_results.\n        \"\"\"\n        run_results_schema_version = get_artifact_schema_version(data)\n        # If less than the current version (v5), preprocess contents to match latest schema version\n        if run_results_schema_version <= 5:\n            # In v5, we added 'compiled' attributes to each result entry\n            # Going forward, dbt expects these to be populated\n            for result in data[\"results\"]:\n                result[\"compiled\"] = False\n                result[\"compiled_code\"] = \"\"\n                result[\"relation_name\"] = \"\"\n        return cls.from_dict(data)\n\n    def write(self, path: str):\n        write_json(path, self.to_dict(omit_none=False))\n"
  },
  {
    "path": "core/dbt/artifacts/schemas/upgrades/__init__.py",
    "content": "from dbt.artifacts.schemas.upgrades.upgrade_manifest import upgrade_manifest_json\nfrom dbt.artifacts.schemas.upgrades.upgrade_manifest_dbt_version import (\n    upgrade_manifest_json_dbt_version,\n)\n"
  },
  {
    "path": "core/dbt/artifacts/schemas/upgrades/upgrade_manifest.py",
    "content": "def rename_sql_attr(node_content: dict) -> dict:\n    if \"raw_sql\" in node_content:\n        node_content[\"raw_code\"] = node_content.pop(\"raw_sql\")\n    if \"compiled_sql\" in node_content:\n        node_content[\"compiled_code\"] = node_content.pop(\"compiled_sql\")\n    node_content[\"language\"] = \"sql\"\n    return node_content\n\n\ndef upgrade_ref_content(node_content: dict) -> dict:\n    # In v1.5 we switched Node.refs from List[List[str]] to List[Dict[str, Union[NodeVersion, str]]]\n    # Previous versions did not have a version keyword argument for ref\n    if \"refs\" in node_content:\n        upgraded_refs = []\n        for ref in node_content[\"refs\"]:\n            if isinstance(ref, list):\n                if len(ref) == 1:\n                    upgraded_refs.append({\"package\": None, \"name\": ref[0], \"version\": None})\n                else:\n                    upgraded_refs.append({\"package\": ref[0], \"name\": ref[1], \"version\": None})\n        node_content[\"refs\"] = upgraded_refs\n    return node_content\n\n\ndef upgrade_node_content(node_content):\n    rename_sql_attr(node_content)\n    upgrade_ref_content(node_content)\n    if node_content[\"resource_type\"] != \"seed\" and \"root_path\" in node_content:\n        del node_content[\"root_path\"]\n\n\ndef upgrade_seed_content(node_content):\n    # Remove compilation related attributes\n    for attr_name in (\n        \"language\",\n        \"refs\",\n        \"sources\",\n        \"metrics\",\n        \"compiled_path\",\n        \"compiled\",\n        \"compiled_code\",\n        \"extra_ctes_injected\",\n        \"extra_ctes\",\n        \"relation_name\",\n    ):\n        if attr_name in node_content:\n            del node_content[attr_name]\n        # In v1.4, we switched SeedNode.depends_on from DependsOn to MacroDependsOn\n        node_content.get(\"depends_on\", {}).pop(\"nodes\", None)\n\n\ndef drop_v9_and_prior_metrics(manifest: dict) -> None:\n    manifest[\"metrics\"] = {}\n    filtered_disabled_entries = {}\n    for entry_name, resource_list in manifest.get(\"disabled\", {}).items():\n        filtered_resource_list = []\n        for resource in resource_list:\n            if resource.get(\"resource_type\") != \"metric\":\n                filtered_resource_list.append(resource)\n        filtered_disabled_entries[entry_name] = filtered_resource_list\n\n    manifest[\"disabled\"] = filtered_disabled_entries\n\n\ndef _convert_dct_with_filter(v10_dct_with_opt_filter):\n    \"\"\"Upgrage the filter object from v10 to v11.\n\n    v10 filters from a serialized manifest looked like:\n    {..., 'filter': {'where_sql_template': '<filter_value>'}}\n    whereas v11 filters look like:\n    {..., 'filter': {'where_filters': [{'where_sql_template': '<filter_value>'}, ...]}}\n    \"\"\"\n    if v10_dct_with_opt_filter is not None and v10_dct_with_opt_filter.get(\"filter\") is not None:\n        v10_dct_with_opt_filter[\"filter\"] = {\"where_filters\": [v10_dct_with_opt_filter[\"filter\"]]}\n\n\ndef _convert_metric(v10_metric_dict):\n    \"\"\"Upgrades a v10 metric object to a v11 metric object.\n\n    Specifcally the following properties change\n    1. metric.filter\n    2. metric.type_params.measure.filter\n    3. metric.type_params.input_measures[x].filter\n    4. metric.type_params.numerator.filter\n    5. metric.type_params.denominator.filter\n    6. metric.type_params.metrics[x].filter\"\n    \"\"\"\n\n    # handles top level metric filter\n    _convert_dct_with_filter(v10_metric_dict)\n\n    type_params = v10_metric_dict.get(\"type_params\")\n    if type_params is not None:\n        _convert_dct_with_filter(type_params.get(\"measure\"))\n        _convert_dct_with_filter(type_params.get(\"numerator\"))\n        _convert_dct_with_filter(type_params.get(\"denominator\"))\n\n        # handles metric.type_params.input_measures[x].filter\n        input_measures = type_params.get(\"input_measures\")\n        if input_measures is not None:\n            for input_measure in input_measures:\n                _convert_dct_with_filter(input_measure)\n\n        # handles metric.type_params.metrics[x].filter\n        metrics = type_params.get(\"metrics\")\n        if metrics is not None:\n            for metric in metrics:\n                _convert_dct_with_filter(metric)\n\n\ndef upgrade_v10_metric_filters(manifest: dict):\n    \"\"\"Handles metric filters changes from v10 to v11.\"\"\"\n\n    metrics = manifest.get(\"metrics\", {})\n    for metric in metrics.values():\n        _convert_metric(metric)\n\n    disabled_nodes = manifest.get(\"disabled\", {})\n    for unique_id, nodes in disabled_nodes.items():\n        if unique_id.split(\".\")[0] == \"metric\":\n            for node in nodes:\n                _convert_metric(node)\n\n\ndef upgrade_manifest_json(manifest: dict, manifest_schema_version: int) -> dict:\n    # this should remain 9 while the check in `upgrade_schema_version` may change\n    if manifest_schema_version <= 9:\n        drop_v9_and_prior_metrics(manifest=manifest)\n    elif manifest_schema_version == 10:\n        upgrade_v10_metric_filters(manifest=manifest)\n\n    for node_content in manifest.get(\"nodes\", {}).values():\n        upgrade_node_content(node_content)\n        if node_content[\"resource_type\"] == \"seed\":\n            upgrade_seed_content(node_content)\n    for disabled in manifest.get(\"disabled\", {}).values():\n        # There can be multiple disabled nodes for the same unique_id\n        # so make sure all the nodes get the attr renamed\n        for node_content in disabled:\n            upgrade_node_content(node_content)\n            if node_content[\"resource_type\"] == \"seed\":\n                upgrade_seed_content(node_content)\n    # add group key\n    if \"groups\" not in manifest:\n        manifest[\"groups\"] = {}\n    if \"group_map\" not in manifest:\n        manifest[\"group_map\"] = {}\n    # add unit_tests key\n    if \"unit_tests\" not in manifest:\n        manifest[\"unit_tests\"] = {}\n    for metric_content in manifest.get(\"metrics\", {}).values():\n        # handle attr renames + value translation (\"expression\" -> \"derived\")\n        metric_content = upgrade_ref_content(metric_content)\n        if \"root_path\" in metric_content:\n            del metric_content[\"root_path\"]\n    for exposure_content in manifest.get(\"exposures\", {}).values():\n        exposure_content = upgrade_ref_content(exposure_content)\n        if \"root_path\" in exposure_content:\n            del exposure_content[\"root_path\"]\n    for source_content in manifest.get(\"sources\", {}).values():\n        if \"root_path\" in source_content:\n            del source_content[\"root_path\"]\n    for macro_content in manifest.get(\"macros\", {}).values():\n        if \"root_path\" in macro_content:\n            del macro_content[\"root_path\"]\n    for doc_content in manifest.get(\"docs\", {}).values():\n        if \"root_path\" in doc_content:\n            del doc_content[\"root_path\"]\n        doc_content[\"resource_type\"] = \"doc\"\n    if \"semantic_models\" not in manifest:\n        manifest[\"semantic_models\"] = {}\n    if \"saved_queries\" not in manifest:\n        manifest[\"saved_queries\"] = {}\n    return manifest\n"
  },
  {
    "path": "core/dbt/artifacts/schemas/upgrades/upgrade_manifest_dbt_version.py",
    "content": "def upgrade_manifest_json_dbt_version(manifest: dict) -> dict:\n    return manifest\n"
  },
  {
    "path": "core/dbt/artifacts/utils/validation.py",
    "content": "import re\n\nHTML_COLORS = [\n    \"aliceblue\",\n    \"antiquewhite\",\n    \"aqua\",\n    \"aquamarine\",\n    \"azure\",\n    \"beige\",\n    \"bisque\",\n    \"black\",\n    \"blanchedalmond\",\n    \"blue\",\n    \"blueviolet\",\n    \"brown\",\n    \"burlywood\",\n    \"cadetblue\",\n    \"chartreuse\",\n    \"chocolate\",\n    \"coral\",\n    \"cornflowerblue\",\n    \"cornsilk\",\n    \"crimson\",\n    \"cyan\",\n    \"darkblue\",\n    \"darkcyan\",\n    \"darkgoldenrod\",\n    \"darkgray\",\n    \"darkgreen\",\n    \"darkkhaki\",\n    \"darkmagenta\",\n    \"darkolivegreen\",\n    \"darkorange\",\n    \"darkorchid\",\n    \"darkred\",\n    \"darksalmon\",\n    \"darkseagreen\",\n    \"darkslateblue\",\n    \"darkslategray\",\n    \"darkturquoise\",\n    \"darkviolet\",\n    \"deeppink\",\n    \"deepskyblue\",\n    \"dimgray\",\n    \"dodgerblue\",\n    \"firebrick\",\n    \"floralwhite\",\n    \"forestgreen\",\n    \"fuchsia\",\n    \"gainsboro\",\n    \"ghostwhite\",\n    \"gold\",\n    \"goldenrod\",\n    \"gray\",\n    \"green\",\n    \"greenyellow\",\n    \"honeydew\",\n    \"hotpink\",\n    \"indianred\",\n    \"indigo\",\n    \"ivory\",\n    \"khaki\",\n    \"lavender\",\n    \"lavenderblush\",\n    \"lawngreen\",\n    \"lemonchiffon\",\n    \"lightblue\",\n    \"lightcoral\",\n    \"lightcyan\",\n    \"lightgoldenrodyellow\",\n    \"lightgray\",\n    \"lightgreen\",\n    \"lightpink\",\n    \"lightsalmon\",\n    \"lightsalmon\",\n    \"lightseagreen\",\n    \"lightskyblue\",\n    \"lightslategray\",\n    \"lightsteelblue\",\n    \"lightyellow\",\n    \"lime\",\n    \"limegreen\",\n    \"linen\",\n    \"magenta\",\n    \"maroon\",\n    \"mediumaquamarine\",\n    \"mediumblue\",\n    \"mediumorchid\",\n    \"mediumpurple\",\n    \"mediumseagreen\",\n    \"mediumslateblue\",\n    \"mediumslateblue\",\n    \"mediumspringgreen\",\n    \"mediumturquoise\",\n    \"mediumvioletred\",\n    \"midnightblue\",\n    \"mintcream\",\n    \"mistyrose\",\n    \"moccasin\",\n    \"navajowhite\",\n    \"navy\",\n    \"oldlace\",\n    \"olive\",\n    \"olivedrab\",\n    \"orange\",\n    \"orangered\",\n    \"orchid\",\n    \"palegoldenrod\",\n    \"palegreen\",\n    \"paleturquoise\",\n    \"palevioletred\",\n    \"papayawhip\",\n    \"peachpuff\",\n    \"peru\",\n    \"pink\",\n    \"plum\",\n    \"powderblue\",\n    \"purple\",\n    \"rebeccapurple\",\n    \"red\",\n    \"rosybrown\",\n    \"royalblue\",\n    \"saddlebrown\",\n    \"salmon\",\n    \"sandybrown\",\n    \"seagreen\",\n    \"seashell\",\n    \"sienna\",\n    \"silver\",\n    \"skyblue\",\n    \"slateblue\",\n    \"slategray\",\n    \"snow\",\n    \"springgreen\",\n    \"steelblue\",\n    \"tan\",\n    \"teal\",\n    \"thistle\",\n    \"tomato\",\n    \"turquoise\",\n    \"violet\",\n    \"wheat\",\n    \"white\",\n    \"whitesmoke\",\n    \"yellow\",\n    \"yellowgreen\",\n]\n\n\ndef validate_color(color: str) -> bool:\n    match_hex = re.search(r\"^#(?:[0-9a-f]{3}){1,2}$\", color.lower())\n    match_html_color_name = color.lower() in HTML_COLORS\n    return bool(match_hex or match_html_color_name)\n"
  },
  {
    "path": "core/dbt/cli/__init__.py",
    "content": "from .main import cli as dbt_cli  # noqa\n"
  },
  {
    "path": "core/dbt/cli/context.py",
    "content": "from typing import Optional\n\nimport click\n\nfrom dbt.cli.main import cli as dbt\n\n\ndef make_context(args, command=dbt) -> Optional[click.Context]:\n    try:\n        ctx = command.make_context(command.name, args)\n    except click.exceptions.Exit:\n        return None\n\n    ctx.invoked_subcommand = ctx.protected_args[0] if ctx.protected_args else None\n    ctx.obj = {}\n\n    return ctx\n"
  },
  {
    "path": "core/dbt/cli/exceptions.py",
    "content": "from typing import IO, List, Optional, Union\n\nfrom click.exceptions import ClickException\n\nfrom dbt.artifacts.schemas.catalog import CatalogArtifact\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.contracts.results import RunExecutionResult\nfrom dbt.utils import ExitCodes\n\n\nclass DbtUsageException(Exception):\n    pass\n\n\nclass DbtInternalException(Exception):\n    pass\n\n\nclass CliException(ClickException):\n    \"\"\"The base exception class for our implementation of the click CLI.\n    The exit_code attribute is used by click to determine which exit code to produce\n    after an invocation.\"\"\"\n\n    def __init__(self, exit_code: ExitCodes) -> None:\n        self.exit_code = exit_code.value\n\n    # the typing of _file is to satisfy the signature of ClickException.show\n    # overriding this method prevents click from printing any exceptions to stdout\n    def show(self, _file: Optional[IO] = None) -> None:  # type: ignore[type-arg]\n        pass\n\n\nclass ResultExit(CliException):\n    \"\"\"This class wraps any exception that contains results while invoking dbt, or the\n    results of an invocation that did not succeed but did not throw any exceptions.\"\"\"\n\n    def __init__(\n        self,\n        result: Union[\n            bool,  # debug\n            CatalogArtifact,  # docs generate\n            List[str],  # list/ls\n            Manifest,  # parse\n            None,  # clean, deps, init, source\n            RunExecutionResult,  # build, compile, run, seed, snapshot, test, run-operation\n        ] = None,\n    ) -> None:\n        super().__init__(ExitCodes.ModelError)\n        self.result = result\n\n\nclass ExceptionExit(CliException):\n    \"\"\"This class wraps any exception that does not contain results thrown while invoking dbt.\"\"\"\n\n    def __init__(self, exception: Exception) -> None:\n        super().__init__(ExitCodes.UnhandledError)\n        self.exception = exception\n"
  },
  {
    "path": "core/dbt/cli/flags.py",
    "content": "import os\nimport sys\nfrom dataclasses import dataclass\nfrom datetime import datetime\nfrom importlib import import_module\nfrom pathlib import Path\nfrom pprint import pformat as pf\nfrom typing import Any, Callable, Dict, List, Optional, Set, Union\n\nfrom click import Context, Parameter, get_current_context\nfrom click.core import Command as ClickCommand\nfrom click.core import Group, ParameterSource\n\nfrom dbt.cli.exceptions import DbtUsageException\nfrom dbt.cli.resolvers import default_log_path, default_project_dir\nfrom dbt.cli.types import Command as CliCommand\nfrom dbt.config.project import read_project_flags\nfrom dbt.config.utils import normalize_warn_error_options\nfrom dbt.contracts.project import ProjectFlags\nfrom dbt.deprecations import fire_buffered_deprecations, renamed_env_var, warn\nfrom dbt.events import ALL_EVENT_NAMES\nfrom dbt.events.types import SelectExcludeIgnoredWithSelectorWarning\nfrom dbt_common import ui\nfrom dbt_common.clients import jinja\nfrom dbt_common.events import functions\nfrom dbt_common.events.functions import fire_event\nfrom dbt_common.exceptions import DbtInternalError\nfrom dbt_common.helper_types import WarnErrorOptionsV2\n\nif os.name != \"nt\":\n    # https://bugs.python.org/issue41567\n    import multiprocessing.popen_spawn_posix  # type: ignore  # noqa: F401\n\nFLAGS_DEFAULTS = {\n    \"INDIRECT_SELECTION\": \"eager\",\n    \"TARGET_PATH\": None,\n    \"DEFER_STATE\": None,  # necessary because of retry construction of flags\n    \"WARN_ERROR\": None,\n    # Cli args without project_flags or env var option.\n    \"FULL_REFRESH\": False,\n    \"STRICT_MODE\": False,\n    \"STORE_FAILURES\": False,\n    \"INTROSPECT\": True,\n    \"STATE_MODIFIED_COMPARE_VARS\": False,\n}\n\nDEPRECATED_PARAMS = {\n    \"deprecated_defer\": \"defer\",\n    \"deprecated_favor_state\": \"favor_state\",\n    \"deprecated_print\": \"print\",\n    \"deprecated_state\": \"state\",\n}\n\n\nDEPRECATED_FLAGS_TO_WARNINGS = {(\"--models\", \"--model\", \"-m\"): \"model-param-usage-deprecation\"}\n\nWHICH_KEY = \"which\"\n\n\ndef convert_config(config_name, config_value):\n    \"\"\"Convert the values from config and original set_from_args to the correct type.\"\"\"\n    ret = config_value\n    if config_name.lower() == \"warn_error_options\" and type(config_value) == dict:\n        normalize_warn_error_options(ret)\n        ret = WarnErrorOptionsV2(\n            error=config_value.get(\"error\", []),\n            warn=config_value.get(\"warn\", []),\n            silence=config_value.get(\"silence\", []),\n            valid_error_names=ALL_EVENT_NAMES,\n        )\n    return ret\n\n\ndef args_to_context(args: List[str]) -> Context:\n    \"\"\"Convert a list of args to a click context with proper hierarchy for dbt commands\"\"\"\n    from dbt.cli.main import cli\n\n    cli_ctx = cli.make_context(cli.name, args)\n    # Split args if they're a comma separated string.\n    if len(args) == 1 and \",\" in args[0]:\n        args = args[0].split(\",\")\n    sub_command_name, sub_command, args = cli.resolve_command(cli_ctx, args)\n    # Handle source and docs group.\n    if isinstance(sub_command, Group):\n        sub_command_name, sub_command, args = sub_command.resolve_command(cli_ctx, args)\n\n    assert isinstance(sub_command, ClickCommand)\n    sub_command_ctx = sub_command.make_context(sub_command_name, args)\n    sub_command_ctx.parent = cli_ctx\n    return sub_command_ctx\n\n\n@dataclass(frozen=True)\nclass Flags:\n    \"\"\"Primary configuration artifact for running dbt\"\"\"\n\n    def __init__(\n        self, ctx: Optional[Context] = None, project_flags: Optional[ProjectFlags] = None\n    ) -> None:\n        # Set the default flags.\n        for key, value in FLAGS_DEFAULTS.items():\n            object.__setattr__(self, key, value)\n        # Use to handle duplicate params in _assign_params\n        flags_defaults_list = list(FLAGS_DEFAULTS.keys())\n\n        if ctx is None:\n            ctx = get_current_context()\n\n        def _get_params_by_source(ctx: Context, source_type: ParameterSource):\n            \"\"\"Generates all params of a given source type.\"\"\"\n            yield from [\n                name for name, source in ctx._parameter_source.items() if source is source_type\n            ]\n            if ctx.parent:\n                yield from _get_params_by_source(ctx.parent, source_type)\n\n        # Ensure that any params sourced from the commandline are not present more than once.\n        # Click handles this exclusivity, but only at a per-subcommand level.\n        seen_params = []\n        for param in _get_params_by_source(ctx, ParameterSource.COMMANDLINE):\n            if param in seen_params:\n                raise DbtUsageException(\n                    f\"{param.lower()} was provided both before and after the subcommand, it can only be set either before or after.\",\n                )\n            seen_params.append(param)\n\n        def _assign_params(\n            ctx: Context,\n            params_assigned_from_default: set,\n            params_assigned_from_user: set,\n            deprecated_env_vars: Dict[str, Callable],\n        ):\n            \"\"\"Recursively adds all click params to flag object\"\"\"\n            for param_name, param_value in ctx.params.items():\n                # N.B. You have to use the base MRO method (object.__setattr__) to set attributes\n                # when using frozen dataclasses.\n                # https://docs.python.org/3/library/dataclasses.html#frozen-instances\n\n                # Handle deprecated env vars while still respecting old values\n                # e.g. DBT_NO_PRINT -> DBT_PRINT if DBT_NO_PRINT is set, it is\n                # respected over DBT_PRINT or --print.\n                new_name: Union[str, None] = None\n                if param_name in DEPRECATED_PARAMS:\n                    # Deprecated env vars can only be set via env var.\n                    # We use the deprecated option in click to serialize the value\n                    # from the env var string.\n                    param_source = ctx.get_parameter_source(param_name)\n                    if param_source == ParameterSource.DEFAULT:\n                        continue\n                    elif param_source != ParameterSource.ENVIRONMENT:\n                        raise DbtUsageException(\n                            \"Deprecated parameters can only be set via environment variables\",\n                        )\n\n                    # Rename for clarity.\n                    dep_name = param_name\n                    new_name = DEPRECATED_PARAMS.get(dep_name)\n                    try:\n                        assert isinstance(new_name, str)\n                    except AssertionError:\n                        raise Exception(\n                            f\"No deprecated param name match in DEPRECATED_PARAMS from {dep_name} to {new_name}\"\n                        )\n\n                    # Find param objects for their envvar name.\n                    try:\n                        dep_param = [x for x in ctx.command.params if x.name == dep_name][0]\n                        new_param = [x for x in ctx.command.params if x.name == new_name][0]\n                    except IndexError:\n                        raise Exception(\n                            f\"No deprecated param name match in context from {dep_name} to {new_name}\"\n                        )\n\n                    # Remove param from defaulted set since the deprecated\n                    # value is not set from default, but from an env var.\n                    if new_name in params_assigned_from_default:\n                        params_assigned_from_default.remove(new_name)\n\n                    # Add the deprecation warning function to the set.\n                    # Get the old and new env vars\n                    if isinstance(dep_param.envvar, list):\n                        dep_env_var_without_prefix = dep_param.envvar[1]\n                    elif isinstance(dep_param.envvar, str):\n                        dep_env_var_without_prefix = dep_param.envvar\n                    else:\n                        # Error raised as an assertion error to maintain history of how this was handled in the past\n                        assert (\n                            False\n                        ), f\"Invalid envvar type: {type(dep_param.envvar)}, expected a list or string\"\n\n                    if isinstance(new_param.envvar, list):\n                        new_env_var_with_prefix = new_param.envvar[0]\n                    elif isinstance(new_param.envvar, str):\n                        new_env_var_with_prefix = new_param.envvar\n                    else:\n                        # Error raised as an assertion error to maintain history of how this was handled in the past\n                        assert (\n                            False\n                        ), f\"Invalid envvar type: {type(new_param.envvar)}, expected a list or string\"\n\n                    deprecated_env_vars[new_name] = renamed_env_var(\n                        old_name=dep_env_var_without_prefix,\n                        new_name=new_env_var_with_prefix,\n                    )\n                # end deprecated_params\n\n                # Set the flag value.\n                is_duplicate = (\n                    hasattr(self, param_name.upper())\n                    and param_name.upper() not in flags_defaults_list\n                )\n                # First time through, set as though FLAGS_DEFAULTS hasn't been set, so not a duplicate.\n                # Subsequent pass (to process \"parent\" params) should be treated as duplicates.\n                if param_name.upper() in flags_defaults_list:\n                    flags_defaults_list.remove(param_name.upper())\n                # Note: the following determines whether parameter came from click default,\n                # not from FLAGS_DEFAULTS in __init__.\n                is_default = ctx.get_parameter_source(param_name) == ParameterSource.DEFAULT\n                is_envvar = ctx.get_parameter_source(param_name) == ParameterSource.ENVIRONMENT\n\n                flag_name = (new_name or param_name).upper()\n\n                # envvar flags are assigned in either parent or child context if there\n                # isn't an overriding cli command flag.\n                # If the flag has been encountered as a child cli flag, we don't\n                # want to overwrite with parent envvar, since the commandline flag takes precedence.\n                if (is_duplicate and not (is_default or is_envvar)) or not is_duplicate:\n                    object.__setattr__(self, flag_name, param_value)\n\n                # Track default assigned params.\n                # For flags that are accepted at both 'parent' and 'child' levels,\n                # we need to track user-provided and default values across both,\n                # to support detection of mutually exclusive flags later on.\n                if not is_default:\n                    params_assigned_from_user.add(param_name)\n                    if param_name in params_assigned_from_default:\n                        params_assigned_from_default.remove(param_name)\n                if is_default and param_name not in params_assigned_from_user:\n                    params_assigned_from_default.add(param_name)\n\n            if ctx.parent:\n                _assign_params(\n                    ctx.parent,\n                    params_assigned_from_default,\n                    params_assigned_from_user,\n                    deprecated_env_vars,\n                )\n\n        params_assigned_from_user = set()  # type: Set[str]\n        params_assigned_from_default = set()  # type: Set[str]\n        deprecated_env_vars: Dict[str, Callable] = {}\n        _assign_params(\n            ctx, params_assigned_from_default, params_assigned_from_user, deprecated_env_vars\n        )\n\n        # Set deprecated_env_var_warnings to be fired later after events have been init.\n        object.__setattr__(\n            self, \"deprecated_env_var_warnings\", [x for x in deprecated_env_vars.values()]\n        )\n\n        # Get the invoked command flags.\n        invoked_subcommand_name = (\n            ctx.invoked_subcommand if hasattr(ctx, \"invoked_subcommand\") else None\n        )\n        if invoked_subcommand_name is not None:\n            invoked_subcommand = getattr(import_module(\"dbt.cli.main\"), invoked_subcommand_name)\n            invoked_subcommand.allow_extra_args = True\n            invoked_subcommand.ignore_unknown_options = True\n            invoked_subcommand_ctx = invoked_subcommand.make_context(None, sys.argv)\n            _assign_params(\n                invoked_subcommand_ctx,\n                params_assigned_from_default,\n                params_assigned_from_user,\n                deprecated_env_vars,\n            )\n\n        if not project_flags:\n            project_dir = getattr(self, \"PROJECT_DIR\", str(default_project_dir()))\n            profiles_dir = getattr(self, \"PROFILES_DIR\", None)\n            if profiles_dir and project_dir:\n                project_flags = read_project_flags(project_dir, profiles_dir)\n            else:\n                project_flags = None\n\n        # Add entire invocation command to flags\n        object.__setattr__(self, \"INVOCATION_COMMAND\", \"dbt \" + \" \".join(sys.argv[1:]))\n\n        if project_flags:\n            # Overwrite default assignments with project flags if available.\n            param_assigned_from_default_copy = params_assigned_from_default.copy()\n            for param_assigned_from_default in params_assigned_from_default:\n                project_flags_param_value = getattr(\n                    project_flags, param_assigned_from_default, None\n                )\n                if project_flags_param_value is not None:\n                    object.__setattr__(\n                        self,\n                        param_assigned_from_default.upper(),\n                        convert_config(param_assigned_from_default, project_flags_param_value),\n                    )\n                    param_assigned_from_default_copy.remove(param_assigned_from_default)\n            params_assigned_from_default = param_assigned_from_default_copy\n\n            # Add project-level flags that are not available as CLI options / env vars\n            for (\n                project_level_flag_name,\n                project_level_flag_value,\n            ) in project_flags.project_only_flags.items():\n                object.__setattr__(self, project_level_flag_name.upper(), project_level_flag_value)\n\n        # Set hard coded flags.\n        object.__setattr__(self, \"WHICH\", invoked_subcommand_name or ctx.info_name)\n\n        # Apply the lead/follow relationship between some parameters.\n        self._override_if_set(\"USE_COLORS\", \"USE_COLORS_FILE\", params_assigned_from_default)\n        self._override_if_set(\"LOG_LEVEL\", \"LOG_LEVEL_FILE\", params_assigned_from_default)\n        self._override_if_set(\"LOG_FORMAT\", \"LOG_FORMAT_FILE\", params_assigned_from_default)\n\n        # Set default LOG_PATH from PROJECT_DIR, if available.\n        # Starting in v1.5, if `log-path` is set in `dbt_project.yml`, it will raise a deprecation warning,\n        # with the possibility of removing it in a future release.\n        if getattr(self, \"LOG_PATH\", None) is None:\n            project_dir = getattr(self, \"PROJECT_DIR\", str(default_project_dir()))\n            version_check = getattr(self, \"VERSION_CHECK\", True)\n            object.__setattr__(\n                self, \"LOG_PATH\", default_log_path(Path(project_dir), version_check)\n            )\n\n        # Support console DO NOT TRACK initiative.\n        if os.getenv(\"DO_NOT_TRACK\", \"\").lower() in (\"1\", \"t\", \"true\", \"y\", \"yes\"):\n            object.__setattr__(self, \"SEND_ANONYMOUS_USAGE_STATS\", False)\n\n        # Check mutual exclusivity once all flags are set.\n        self._assert_mutually_exclusive(\n            params_assigned_from_default, [\"WARN_ERROR\", \"WARN_ERROR_OPTIONS\"]\n        )\n\n        # Handle arguments mutually exclusive with INLINE\n        self._assert_mutually_exclusive(params_assigned_from_default, [\"SELECT\", \"INLINE\"])\n        self._assert_mutually_exclusive(params_assigned_from_default, [\"SELECTOR\", \"INLINE\"])\n\n        # Check event_time configs for validity\n        self._validate_event_time_configs()\n\n        # Support lower cased access for legacy code.\n        params = set(\n            x for x in dir(self) if not callable(getattr(self, x)) and not x.startswith(\"__\")\n        )\n        for param in params:\n            object.__setattr__(self, param.lower(), getattr(self, param))\n\n        self.set_common_global_flags()\n\n    def __str__(self) -> str:\n        return str(pf(self.__dict__))\n\n    def _override_if_set(self, lead: str, follow: str, defaulted: Set[str]) -> None:\n        \"\"\"If the value of the lead parameter was set explicitly, apply the value to follow, unless follow was also set explicitly.\"\"\"\n        if lead.lower() not in defaulted and follow.lower() in defaulted:\n            object.__setattr__(self, follow.upper(), getattr(self, lead.upper(), None))\n\n    def _assert_mutually_exclusive(\n        self, params_assigned_from_default: Set[str], group: List[str]\n    ) -> None:\n        \"\"\"\n        Ensure no elements from group are simultaneously provided by a user, as inferred from params_assigned_from_default.\n        Raises click.UsageError if any two elements from group are simultaneously provided by a user.\n        \"\"\"\n        set_flag = None\n        for flag in group:\n            flag_set_by_user = (\n                hasattr(self, flag) and flag.lower() not in params_assigned_from_default\n            )\n            if flag_set_by_user and set_flag:\n                raise DbtUsageException(\n                    f\"{flag.lower()}: not allowed with argument {set_flag.lower()}\"\n                )\n            elif flag_set_by_user:\n                set_flag = flag\n\n    def _validate_event_time_configs(self) -> None:\n        event_time_start: datetime = (\n            getattr(self, \"EVENT_TIME_START\") if hasattr(self, \"EVENT_TIME_START\") else None\n        )\n        event_time_end: datetime = (\n            getattr(self, \"EVENT_TIME_END\") if hasattr(self, \"EVENT_TIME_END\") else None\n        )\n\n        # only do validations if at least one of `event_time_start` or `event_time_end` are specified\n        if event_time_start is not None or event_time_end is not None:\n\n            # These `ifs`, combined with the parent `if` make it so that `event_time_start` and\n            # `event_time_end` are mutually required\n            if event_time_start is None:\n                raise DbtUsageException(\n                    \"The flag `--event-time-end` was specified, but `--event-time-start` was not. \"\n                    \"When specifying `--event-time-end`, `--event-time-start` must also be present.\"\n                )\n            if event_time_end is None:\n                raise DbtUsageException(\n                    \"The flag `--event-time-start` was specified, but `--event-time-end` was not. \"\n                    \"When specifying `--event-time-start`, `--event-time-end` must also be present.\"\n                )\n\n            # This `if` just is a sanity check that `event_time_start` is before `event_time_end`\n            if event_time_start >= event_time_end:\n                raise DbtUsageException(\n                    \"Value for `--event-time-start` must be less than `--event-time-end`\"\n                )\n\n    def fire_deprecations(self, ctx: Optional[Context] = None):\n        \"\"\"Fires events for deprecated env_var usage.\"\"\"\n        [dep_fn() for dep_fn in self.deprecated_env_var_warnings]\n\n        # Warn when --selector is used together with --select or --exclude (they are ignored)\n        if getattr(self, \"SELECTOR\", None) and (\n            getattr(self, \"SELECT\", ()) or getattr(self, \"EXCLUDE\", ())\n        ):\n            fire_event(SelectExcludeIgnoredWithSelectorWarning())\n        # It is necessary to remove this attr from the class so it does\n        # not get pickled when written to disk as json.\n        object.__delattr__(self, \"deprecated_env_var_warnings\")\n\n        fire_buffered_deprecations()\n\n        # Handle firing deprecations of CLI aliases separately using argv or dbtRunner args\n        # because click doesn't make it possible to disambiguite which literal CLI option was used\n        # and only preserves the 'canonical' representation.\n        original_command_args = (\n            ctx.obj[\"dbt_runner_command_args\"]\n            if (ctx and ctx.obj and \"dbt_runner_command_args\" in ctx.obj)\n            else sys.argv\n        )\n        for deprecated_flags, warning in DEPRECATED_FLAGS_TO_WARNINGS.items():\n            for deprecated_flag in deprecated_flags:\n                if deprecated_flag in original_command_args:\n                    warn(warning)\n\n    @classmethod\n    def from_dict(cls, command: CliCommand, args_dict: Dict[str, Any]) -> \"Flags\":\n        command_arg_list = command_params(command, args_dict)\n        ctx = args_to_context(command_arg_list)\n        flags = cls(ctx=ctx)\n        flags.fire_deprecations(ctx=ctx)\n        return flags\n\n    def set_common_global_flags(self):\n        # Set globals for common.ui\n        if getattr(self, \"PRINTER_WIDTH\", None) is not None:\n            ui.PRINTER_WIDTH = getattr(self, \"PRINTER_WIDTH\")\n        if getattr(self, \"USE_COLORS\", None) is not None:\n            ui.USE_COLOR = getattr(self, \"USE_COLORS\")\n\n        # Set globals for common.events.functions\n        functions.WARN_ERROR = getattr(self, \"WARN_ERROR\", False)\n        if getattr(self, \"WARN_ERROR_OPTIONS\", None) is not None:\n            functions.WARN_ERROR_OPTIONS = getattr(self, \"WARN_ERROR_OPTIONS\")\n\n        # Set globals for common.jinja\n        if getattr(self, \"MACRO_DEBUGGING\", None) is not None:\n            jinja.MACRO_DEBUGGING = getattr(self, \"MACRO_DEBUGGING\")\n\n    # This is here to prevent mypy from complaining about all of the\n    # attributes which we added dynamically.\n    def __getattr__(self, name: str) -> Any:\n        return super().__getattribute__(name)  # type: ignore\n\n\nCommandParams = List[str]\n\n\ndef command_params(command: CliCommand, args_dict: Dict[str, Any]) -> CommandParams:\n    \"\"\"Given a command and a dict, returns a list of strings representing\n    the CLI params for that command. The order of this list is consistent with\n    which flags are expected at the parent level vs the command level.\n\n    e.g. fn(\"run\", {\"defer\": True, \"print\": False}) -> [\"--no-print\", \"run\", \"--defer\"]\n\n    The result of this function can be passed in to the args_to_context function\n    to produce a click context to instantiate Flags with.\n    \"\"\"\n\n    cmd_args = set(command_args(command))\n    prnt_args = set(parent_args())\n    default_args = set([x.lower() for x in FLAGS_DEFAULTS.keys()])\n\n    res = command.to_list()\n    for k, v in args_dict.items():\n        k = k.lower()\n        # if a \"which\" value exists in the args dict, it should match the command provided\n        if k == WHICH_KEY:\n            if v != command.value:\n                raise DbtInternalError(\n                    f\"Command '{command.value}' does not match value of which: '{v}'\"\n                )\n            continue\n\n        # param was assigned from defaults and should not be included\n        if k not in (cmd_args | prnt_args) or (\n            k in default_args and v == FLAGS_DEFAULTS[k.upper()]\n        ):\n            continue\n\n        # if the param is in parent args, it should come before the arg name\n        # e.g. [\"--print\", \"run\"] vs [\"run\", \"--print\"]\n        add_fn = res.append\n        if k in prnt_args:\n\n            def add_fn(x):\n                res.insert(0, x)\n\n        spinal_cased = k.replace(\"_\", \"-\")\n\n        # MultiOption flags come back as lists, but we want to pass them as space separated strings\n        if isinstance(v, list):\n            if len(v) > 0:\n                v = \" \".join(v)\n            else:\n                continue\n\n        if k == \"macro\" and command == CliCommand.RUN_OPERATION:\n            add_fn(v)\n        # None is a Singleton, False is a Flyweight, only one instance of each.\n        elif (v is None or v is False) and k not in (\n            # These are None by default but they do not support --no-{flag}\n            \"defer_state\",\n            \"log_format\",\n        ):\n            add_fn(f\"--no-{spinal_cased}\")\n        elif v is True:\n            add_fn(f\"--{spinal_cased}\")\n        else:\n            add_fn(f\"--{spinal_cased}={v}\")\n\n    return res\n\n\nArgsList = List[str]\n\n\ndef parent_args() -> ArgsList:\n    \"\"\"Return a list representing the params the base click command takes.\"\"\"\n    from dbt.cli.main import cli\n\n    return format_params(cli.params)\n\n\ndef command_args(command: CliCommand) -> ArgsList:\n    \"\"\"Given a command, return a list of strings representing the params\n    that command takes. This function only returns params assigned to a\n    specific command, not those of its parent command.\n\n    e.g. fn(\"run\") -> [\"defer\", \"favor_state\", \"exclude\", ...]\n    \"\"\"\n    import dbt.cli.main as cli\n\n    CMD_DICT: Dict[CliCommand, ClickCommand] = {\n        CliCommand.BUILD: cli.build,\n        CliCommand.CLEAN: cli.clean,\n        CliCommand.CLONE: cli.clone,\n        CliCommand.COMPILE: cli.compile,\n        CliCommand.DOCS_GENERATE: cli.docs_generate,\n        CliCommand.DOCS_SERVE: cli.docs_serve,\n        CliCommand.DEBUG: cli.debug,\n        CliCommand.DEPS: cli.deps,\n        CliCommand.INIT: cli.init,\n        CliCommand.LIST: cli.list,\n        CliCommand.PARSE: cli.parse,\n        CliCommand.RUN: cli.run,\n        CliCommand.RUN_OPERATION: cli.run_operation,\n        CliCommand.SEED: cli.seed,\n        CliCommand.SHOW: cli.show,\n        CliCommand.SNAPSHOT: cli.snapshot,\n        CliCommand.SOURCE_FRESHNESS: cli.freshness,\n        CliCommand.TEST: cli.test,\n        CliCommand.RETRY: cli.retry,\n    }\n    click_cmd: Optional[ClickCommand] = CMD_DICT.get(command, None)\n    if click_cmd is None:\n        raise DbtInternalError(f\"No command found for name '{command.name}'\")\n    return format_params(click_cmd.params)\n\n\ndef format_params(params: List[Parameter]) -> ArgsList:\n    return [str(x.name) for x in params if not str(x.name).lower().startswith(\"deprecated_\")]\n"
  },
  {
    "path": "core/dbt/cli/main.py",
    "content": "import functools\nfrom copy import copy\nfrom dataclasses import dataclass\nfrom typing import Callable, List, Optional, Union\n\nimport click\nfrom click.exceptions import BadOptionUsage\nfrom click.exceptions import Exit as ClickExit\nfrom click.exceptions import NoSuchOption, UsageError\n\nfrom dbt.adapters.factory import register_adapter\nfrom dbt.artifacts.schemas.catalog import CatalogArtifact\nfrom dbt.artifacts.schemas.run import RunExecutionResult\nfrom dbt.cli import params as p\nfrom dbt.cli import requires\nfrom dbt.cli.exceptions import DbtInternalException, DbtUsageException\nfrom dbt.cli.requires import setup_manifest\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.mp_context import get_mp_context\nfrom dbt_common.events.base_types import EventMsg\n\n\n@dataclass\nclass dbtRunnerResult:\n    \"\"\"Contains the result of an invocation of the dbtRunner\"\"\"\n\n    success: bool\n\n    exception: Optional[BaseException] = None\n    result: Union[\n        bool,  # debug\n        CatalogArtifact,  # docs generate\n        List[str],  # list/ls\n        Manifest,  # parse\n        None,  # clean, deps, init, source\n        RunExecutionResult,  # build, compile, run, seed, snapshot, test, run-operation\n    ] = None\n\n\n# Programmatic invocation\nclass dbtRunner:\n    def __init__(\n        self,\n        manifest: Optional[Manifest] = None,\n        callbacks: Optional[List[Callable[[EventMsg], None]]] = None,\n    ) -> None:\n        self.manifest = manifest\n\n        if callbacks is None:\n            callbacks = []\n        self.callbacks = callbacks\n\n    def invoke(self, args: List[str], **kwargs) -> dbtRunnerResult:\n        try:\n            dbt_ctx = cli.make_context(cli.name, args.copy())\n            dbt_ctx.obj = {\n                \"manifest\": self.manifest,\n                \"callbacks\": self.callbacks,\n                \"dbt_runner_command_args\": args,\n            }\n\n            for key, value in kwargs.items():\n                dbt_ctx.params[key] = value\n                # Hack to set parameter source to custom string\n                dbt_ctx.set_parameter_source(key, \"kwargs\")  # type: ignore\n\n            result, success = cli.invoke(dbt_ctx)\n            return dbtRunnerResult(\n                result=result,\n                success=success,\n            )\n        except requires.ResultExit as e:\n            return dbtRunnerResult(\n                result=e.result,\n                success=False,\n            )\n        except requires.ExceptionExit as e:\n            return dbtRunnerResult(\n                exception=e.exception,\n                success=False,\n            )\n        except (BadOptionUsage, NoSuchOption, UsageError) as e:\n            return dbtRunnerResult(\n                exception=DbtUsageException(e.message),\n                success=False,\n            )\n        except ClickExit as e:\n            if e.exit_code == 0:\n                return dbtRunnerResult(success=True)\n            return dbtRunnerResult(\n                exception=DbtInternalException(f\"unhandled exit code {e.exit_code}\"),\n                success=False,\n            )\n        except BaseException as e:\n            return dbtRunnerResult(\n                exception=e,\n                success=False,\n            )\n\n\n# approach from https://github.com/pallets/click/issues/108#issuecomment-280489786\ndef global_flags(func):\n    @p.cache_selected_only\n    @p.debug\n    @p.defer\n    @p.deprecated_defer\n    @p.defer_state\n    @p.deprecated_favor_state\n    @p.deprecated_print\n    @p.deprecated_state\n    @p.fail_fast\n    @p.favor_state\n    @p.indirect_selection\n    @p.log_cache_events\n    @p.log_file_max_bytes\n    @p.log_format\n    @p.log_format_file\n    @p.log_level\n    @p.log_level_file\n    @p.log_path\n    @p.macro_debugging\n    @p.partial_parse\n    @p.partial_parse_file_path\n    @p.partial_parse_file_diff\n    @p.populate_cache\n    @p.print\n    @p.printer_width\n    @p.profile\n    @p.quiet\n    @p.record_timing_info\n    @p.send_anonymous_usage_stats\n    @p.single_threaded\n    @p.show_all_deprecations\n    @p.state\n    @p.static_parser\n    @p.target\n    @p.use_colors\n    @p.use_colors_file\n    @p.use_experimental_parser\n    @p.version\n    @p.version_check\n    @p.warn_error\n    @p.warn_error_options\n    @p.write_json\n    @p.use_fast_test_edges\n    @p.upload_artifacts\n    @functools.wraps(func)\n    def wrapper(*args, **kwargs):\n        return func(*args, **kwargs)\n\n    return wrapper\n\n\n# dbt\n@click.group(\n    context_settings={\"help_option_names\": [\"-h\", \"--help\"]},\n    invoke_without_command=True,\n    no_args_is_help=True,\n    epilog=\"Specify one of these sub-commands and you can find more help from there.\",\n)\n@click.pass_context\n@global_flags\n@p.show_resource_report\ndef cli(ctx, **kwargs):\n    \"\"\"An ELT tool for managing your SQL transformations and data models.\n    For more documentation on these commands, visit: docs.getdbt.com\n    \"\"\"\n\n\n# dbt build\n@cli.command(\"build\")\n@click.pass_context\n@global_flags\n@p.empty\n@p.event_time_start\n@p.event_time_end\n@p.exclude\n@p.export_saved_queries\n@p.full_refresh\n@p.deprecated_include_saved_query\n@p.profiles_dir\n@p.project_dir\n@p.resource_type\n@p.exclude_resource_type\n@p.sqlparse_options\n@p.sample\n@p.select\n@p.selector\n@p.show\n@p.store_failures\n@p.target_path\n@p.threads\n@p.vars\n@requires.postflight\n@requires.preflight\n@requires.profile\n@requires.project\n@requires.catalogs\n@requires.runtime_config\n@requires.manifest\ndef build(ctx, **kwargs):\n    \"\"\"Run all seeds, models, snapshots, and tests in DAG order\"\"\"\n    from dbt.task.build import BuildTask\n\n    task = BuildTask(\n        ctx.obj[\"flags\"],\n        ctx.obj[\"runtime_config\"],\n        ctx.obj[\"manifest\"],\n    )\n\n    results = task.run()\n    success = task.interpret_results(results)\n    return results, success\n\n\n# dbt clean\n@cli.command(\"clean\")\n@click.pass_context\n@global_flags\n@p.clean_project_files_only\n@p.profiles_dir\n@p.project_dir\n@p.target_path\n@p.vars\n@requires.postflight\n@requires.preflight\n@requires.unset_profile\n@requires.project\ndef clean(ctx, **kwargs):\n    \"\"\"Delete all folders in the clean-targets list (usually the dbt_packages and target directories.)\"\"\"\n    from dbt.task.clean import CleanTask\n\n    with CleanTask(ctx.obj[\"flags\"], ctx.obj[\"project\"]) as task:\n        results = task.run()\n        success = task.interpret_results(results)\n    return results, success\n\n\n# dbt docs\n@cli.group()\n@click.pass_context\n@global_flags\ndef docs(ctx, **kwargs):\n    \"\"\"Generate or serve the documentation website for your project\"\"\"\n\n\n# dbt docs generate\n@docs.command(\"generate\")\n@click.pass_context\n@global_flags\n@p.compile_docs\n@p.exclude\n@p.sqlparse_options\n@p.profiles_dir\n@p.project_dir\n@p.select\n@p.selector\n@p.empty_catalog\n@p.static\n@p.target_path\n@p.threads\n@p.vars\n@requires.postflight\n@requires.preflight\n@requires.profile\n@requires.project\n@requires.runtime_config\n@requires.manifest(write=False)\ndef docs_generate(ctx, **kwargs):\n    \"\"\"Generate the documentation website for your project\"\"\"\n    from dbt.task.docs.generate import GenerateTask\n\n    task = GenerateTask(\n        ctx.obj[\"flags\"],\n        ctx.obj[\"runtime_config\"],\n        ctx.obj[\"manifest\"],\n    )\n\n    results = task.run()\n    success = task.interpret_results(results)\n    return results, success\n\n\n# dbt docs serve\n@docs.command(\"serve\")\n@click.pass_context\n@global_flags\n@p.browser\n@p.host\n@p.port\n@p.profiles_dir\n@p.project_dir\n@p.target_path\n@p.vars\n@requires.postflight\n@requires.preflight\n@requires.profile\n@requires.project\n@requires.runtime_config\ndef docs_serve(ctx, **kwargs):\n    \"\"\"Serve the documentation website for your project\"\"\"\n    from dbt.task.docs.serve import ServeTask\n\n    task = ServeTask(\n        ctx.obj[\"flags\"],\n        ctx.obj[\"runtime_config\"],\n    )\n\n    results = task.run()\n    success = task.interpret_results(results)\n    return results, success\n\n\n# dbt compile\n@cli.command(\"compile\")\n@click.pass_context\n@global_flags\n@p.exclude\n@p.full_refresh\n@p.show_output_format\n@p.introspect\n@p.profiles_dir\n@p.project_dir\n@p.empty\n@p.select\n@p.selector\n@p.inline\n@p.compile_inject_ephemeral_ctes\n@p.sqlparse_options\n@p.target_path\n@p.threads\n@p.vars\n@requires.postflight\n@requires.preflight\n@requires.profile\n@requires.project\n@requires.catalogs\n@requires.runtime_config\n@requires.manifest\ndef compile(ctx, **kwargs):\n    \"\"\"Generates executable SQL from source, model, test, and analysis files. Compiled SQL files are written to the\n    target/ directory.\"\"\"\n    from dbt.task.compile import CompileTask\n\n    task = CompileTask(\n        ctx.obj[\"flags\"],\n        ctx.obj[\"runtime_config\"],\n        ctx.obj[\"manifest\"],\n    )\n\n    results = task.run()\n    success = task.interpret_results(results)\n    return results, success\n\n\n# dbt show\n@cli.command(\"show\")\n@click.pass_context\n@global_flags\n@p.exclude\n@p.full_refresh\n@p.show_output_format\n@p.show_limit\n@p.introspect\n@p.profiles_dir\n@p.project_dir\n@p.select\n@p.selector\n@p.inline\n@p.inline_direct\n@p.sqlparse_options\n@p.target_path\n@p.threads\n@p.vars\n@requires.postflight\n@requires.preflight\n@requires.profile\n@requires.project\n@requires.runtime_config\ndef show(ctx, **kwargs):\n    \"\"\"Generates executable SQL for a named resource or inline query, runs that SQL, and returns a preview of the\n    results. Does not materialize anything to the warehouse.\"\"\"\n    from dbt.task.show import ShowTask, ShowTaskDirect\n\n    if ctx.obj[\"flags\"].inline_direct:\n        # Issue the inline query directly, with no templating. Does not require\n        # loading the manifest.\n        register_adapter(ctx.obj[\"runtime_config\"], get_mp_context())\n        task = ShowTaskDirect(\n            ctx.obj[\"flags\"],\n            ctx.obj[\"runtime_config\"],\n        )\n    else:\n        setup_manifest(ctx)\n        task = ShowTask(\n            ctx.obj[\"flags\"],\n            ctx.obj[\"runtime_config\"],\n            ctx.obj[\"manifest\"],\n        )\n\n    results = task.run()\n    success = task.interpret_results(results)\n    return results, success\n\n\n# dbt debug\n@cli.command(\"debug\")\n@click.pass_context\n@global_flags\n@p.debug_connection\n@p.config_dir\n@p.profiles_dir_exists_false\n@p.project_dir\n@p.vars\n@requires.postflight\n@requires.preflight\ndef debug(ctx, **kwargs):\n    \"\"\"Show information on the current dbt environment and check dependencies, then test the database connection. Not to be confused with the --debug option which increases verbosity.\"\"\"\n    from dbt.task.debug import DebugTask\n\n    task = DebugTask(\n        ctx.obj[\"flags\"],\n    )\n\n    results = task.run()\n    success = task.interpret_results(results)\n    return results, success\n\n\n# dbt deps\n@cli.command(\"deps\")\n@click.pass_context\n@global_flags\n@p.profiles_dir_exists_false\n@p.project_dir\n@p.vars\n@p.source\n@p.lock\n@p.upgrade\n@p.add_package\n@requires.postflight\n@requires.preflight\n@requires.unset_profile\n@requires.project\ndef deps(ctx, **kwargs):\n    \"\"\"Install dbt packages specified.\n    In the following case, a new `package-lock.yml` will be generated and the packages are installed:\n    - user updated the packages.yml\n    - user specify the flag --update, which means for packages that are specified as a\n      range, dbt-core will try to install the newer version\n    Otherwise, deps will use `package-lock.yml` as source of truth to install packages.\n\n    There is a way to add new packages by providing an `--add-package` flag to deps command\n    which will allow user to specify a package they want to add in the format of packagename@version.\n    \"\"\"\n    from dbt.task.deps import DepsTask\n\n    flags = ctx.obj[\"flags\"]\n    if flags.ADD_PACKAGE:\n        if not flags.ADD_PACKAGE[\"version\"] and flags.SOURCE != \"local\":\n            raise BadOptionUsage(\n                message=f\"Version is required in --add-package when a package when source is {flags.SOURCE}\",\n                option_name=\"--add-package\",\n            )\n    with DepsTask(flags, ctx.obj[\"project\"]) as task:\n        results = task.run()\n        success = task.interpret_results(results)\n    return results, success\n\n\n# dbt init\n@cli.command(\"init\")\n@click.pass_context\n@global_flags\n# for backwards compatibility, accept 'project_name' as an optional positional argument\n@click.argument(\"project_name\", required=False)\n@p.profiles_dir_exists_false\n@p.project_dir\n@p.skip_profile_setup\n@p.skip_debug\n@p.vars\n@requires.postflight\n@requires.preflight\ndef init(ctx, **kwargs):\n    \"\"\"Initialize a new dbt project.\"\"\"\n    from dbt.task.init import InitTask\n\n    with InitTask(ctx.obj[\"flags\"]) as task:\n        results = task.run()\n        success = task.interpret_results(results)\n    return results, success\n\n\n# dbt list\n@cli.command(\"list\")\n@click.pass_context\n@global_flags\n@p.exclude\n@p.models\n@p.output\n@p.output_keys\n@p.profiles_dir\n@p.project_dir\n@p.resource_type\n@p.exclude_resource_type\n@p.raw_select\n@p.selector\n@p.target_path\n@p.vars\n@requires.postflight\n@requires.preflight\n@requires.profile\n@requires.project\n@requires.runtime_config\n@requires.manifest\ndef list(ctx, **kwargs):\n    \"\"\"List the resources in your project\"\"\"\n    from dbt.task.list import ListTask\n\n    task = ListTask(\n        ctx.obj[\"flags\"],\n        ctx.obj[\"runtime_config\"],\n        ctx.obj[\"manifest\"],\n    )\n\n    results = task.run()\n    success = task.interpret_results(results)\n    return results, success\n\n\n# Alias \"list\" to \"ls\"\nls = copy(cli.commands[\"list\"])\nls.hidden = True\ncli.add_command(ls, \"ls\")\n\n\n# dbt parse\n@cli.command(\"parse\")\n@click.pass_context\n@global_flags\n@p.profiles_dir\n@p.project_dir\n@p.target_path\n@p.threads\n@p.vars\n@requires.postflight\n@requires.preflight\n@requires.profile\n@requires.project\n@requires.catalogs\n@requires.runtime_config\n@requires.manifest(write_perf_info=True)\ndef parse(ctx, **kwargs):\n    \"\"\"Parses the project and provides information on performance\"\"\"\n    # manifest generation and writing happens in @requires.manifest\n    return ctx.obj[\"manifest\"], True\n\n\n# dbt run\n@cli.command(\"run\")\n@click.pass_context\n@global_flags\n@p.exclude\n@p.full_refresh\n@p.profiles_dir\n@p.project_dir\n@p.empty\n@p.event_time_start\n@p.event_time_end\n@p.sqlparse_options\n@p.sample\n@p.select\n@p.selector\n@p.target_path\n@p.threads\n@p.vars\n@requires.postflight\n@requires.preflight\n@requires.profile\n@requires.project\n@requires.catalogs\n@requires.runtime_config\n@requires.manifest\ndef run(ctx, **kwargs):\n    \"\"\"Compile SQL and execute against the current target database.\"\"\"\n    from dbt.task.run import RunTask\n\n    task = RunTask(\n        ctx.obj[\"flags\"],\n        ctx.obj[\"runtime_config\"],\n        ctx.obj[\"manifest\"],\n    )\n\n    results = task.run()\n    success = task.interpret_results(results)\n    return results, success\n\n\n# dbt retry\n@cli.command(\"retry\")\n@click.pass_context\n@global_flags\n@p.project_dir\n@p.profiles_dir\n@p.vars\n@p.target_path\n@p.threads\n@p.full_refresh\n@requires.postflight\n@requires.preflight\n@requires.profile\n@requires.project\n@requires.runtime_config\ndef retry(ctx, **kwargs):\n    \"\"\"Retry the nodes that failed in the previous run.\"\"\"\n    from dbt.task.retry import RetryTask\n\n    # Retry will parse manifest inside the task after we consolidate the flags\n    task = RetryTask(\n        ctx.obj[\"flags\"],\n        ctx.obj[\"runtime_config\"],\n    )\n\n    results = task.run()\n    success = task.interpret_results(results)\n    return results, success\n\n\n# dbt clone\n@cli.command(\"clone\")\n@click.pass_context\n@global_flags\n@p.exclude\n@p.full_refresh\n@p.profiles_dir\n@p.project_dir\n@p.resource_type\n@p.exclude_resource_type\n@p.select\n@p.selector\n@p.target_path\n@p.threads\n@p.vars\n@requires.preflight\n@requires.profile\n@requires.project\n@requires.runtime_config\n@requires.manifest\n@requires.postflight\ndef clone(ctx, **kwargs):\n    \"\"\"Create clones of selected nodes based on their location in the manifest provided to --state.\"\"\"\n    from dbt.task.clone import CloneTask\n\n    task = CloneTask(\n        ctx.obj[\"flags\"],\n        ctx.obj[\"runtime_config\"],\n        ctx.obj[\"manifest\"],\n    )\n\n    results = task.run()\n    success = task.interpret_results(results)\n    return results, success\n\n\n# dbt run operation\n@cli.command(\"run-operation\")\n@click.pass_context\n@global_flags\n@click.argument(\"macro\")\n@p.args\n@p.profiles_dir\n@p.project_dir\n@p.target_path\n@p.threads\n@p.vars\n@requires.postflight\n@requires.preflight\n@requires.profile\n@requires.project\n@requires.runtime_config\n@requires.manifest\ndef run_operation(ctx, **kwargs):\n    \"\"\"Run the named macro with any supplied arguments.\"\"\"\n    from dbt.task.run_operation import RunOperationTask\n\n    task = RunOperationTask(\n        ctx.obj[\"flags\"],\n        ctx.obj[\"runtime_config\"],\n        ctx.obj[\"manifest\"],\n    )\n\n    results = task.run()\n    success = task.interpret_results(results)\n    return results, success\n\n\n# dbt seed\n@cli.command(\"seed\")\n@click.pass_context\n@global_flags\n@p.exclude\n@p.full_refresh\n@p.profiles_dir\n@p.project_dir\n@p.sqlparse_options\n@p.select\n@p.selector\n@p.show\n@p.target_path\n@p.threads\n@p.vars\n@requires.postflight\n@requires.preflight\n@requires.profile\n@requires.project\n@requires.catalogs\n@requires.runtime_config\n@requires.manifest\ndef seed(ctx, **kwargs):\n    \"\"\"Load data from csv files into your data warehouse.\"\"\"\n    from dbt.task.seed import SeedTask\n\n    task = SeedTask(\n        ctx.obj[\"flags\"],\n        ctx.obj[\"runtime_config\"],\n        ctx.obj[\"manifest\"],\n    )\n    results = task.run()\n    success = task.interpret_results(results)\n    return results, success\n\n\n# dbt snapshot\n@cli.command(\"snapshot\")\n@click.pass_context\n@global_flags\n@p.empty\n@p.exclude\n@p.profiles_dir\n@p.project_dir\n@p.sqlparse_options\n@p.select\n@p.selector\n@p.target_path\n@p.threads\n@p.vars\n@requires.postflight\n@requires.preflight\n@requires.profile\n@requires.project\n@requires.catalogs\n@requires.runtime_config\n@requires.manifest\ndef snapshot(ctx, **kwargs):\n    \"\"\"Execute snapshots defined in your project\"\"\"\n    from dbt.task.snapshot import SnapshotTask\n\n    task = SnapshotTask(\n        ctx.obj[\"flags\"],\n        ctx.obj[\"runtime_config\"],\n        ctx.obj[\"manifest\"],\n    )\n\n    results = task.run()\n    success = task.interpret_results(results)\n    return results, success\n\n\n# dbt source\n@cli.group()\n@click.pass_context\n@global_flags\ndef source(ctx, **kwargs):\n    \"\"\"Manage your project's sources\"\"\"\n\n\n# dbt source freshness\n@source.command(\"freshness\")\n@click.pass_context\n@global_flags\n@p.exclude\n@p.output_path  # TODO: Is this ok to re-use?  We have three different output params, how much can we consolidate?\n@p.sqlparse_options\n@p.profiles_dir\n@p.project_dir\n@p.select\n@p.selector\n@p.target_path\n@p.threads\n@p.vars\n@requires.postflight\n@requires.preflight\n@requires.profile\n@requires.project\n@requires.runtime_config\n@requires.manifest\ndef freshness(ctx, **kwargs):\n    \"\"\"check the current freshness of the project's sources\"\"\"\n    from dbt.task.freshness import FreshnessTask\n\n    task = FreshnessTask(\n        ctx.obj[\"flags\"],\n        ctx.obj[\"runtime_config\"],\n        ctx.obj[\"manifest\"],\n    )\n\n    results = task.run()\n    success = task.interpret_results(results)\n    return results, success\n\n\n# Alias \"source freshness\" to \"snapshot-freshness\"\nsnapshot_freshness = copy(cli.commands[\"source\"].commands[\"freshness\"])  # type: ignore\nsnapshot_freshness.hidden = True\ncli.commands[\"source\"].add_command(snapshot_freshness, \"snapshot-freshness\")  # type: ignore\n\n\n# dbt test\n@cli.command(\"test\")\n@click.pass_context\n@global_flags\n@p.exclude\n@p.resource_type\n@p.exclude_resource_type\n@p.profiles_dir\n@p.project_dir\n@p.sqlparse_options\n@p.select\n@p.selector\n@p.store_failures\n@p.target_path\n@p.threads\n@p.vars\n@requires.postflight\n@requires.preflight\n@requires.profile\n@requires.project\n@requires.catalogs\n@requires.runtime_config\n@requires.manifest\ndef test(ctx, **kwargs):\n    \"\"\"Runs tests on data in deployed models. Run this after `dbt run`\"\"\"\n    from dbt.task.test import TestTask\n\n    task = TestTask(\n        ctx.obj[\"flags\"],\n        ctx.obj[\"runtime_config\"],\n        ctx.obj[\"manifest\"],\n    )\n\n    results = task.run()\n    success = task.interpret_results(results)\n    return results, success\n\n\n# Support running as a module\nif __name__ == \"__main__\":\n    cli()\n"
  },
  {
    "path": "core/dbt/cli/option_types.py",
    "content": "from typing import Optional\n\nimport pytz\nfrom click import Choice, Context, Parameter, ParamType\n\nfrom dbt.config.utils import normalize_warn_error_options, parse_cli_yaml_string\nfrom dbt.event_time.sample_window import SampleWindow\nfrom dbt.events import ALL_EVENT_NAMES\nfrom dbt.exceptions import OptionNotYamlDictError, ValidationError\nfrom dbt_common.exceptions import DbtValidationError\nfrom dbt_common.helper_types import WarnErrorOptionsV2\n\n\nclass YAML(ParamType):\n    \"\"\"The Click YAML type. Converts YAML strings into objects.\"\"\"\n\n    name = \"YAML\"\n\n    def convert(self, value, param, ctx):\n        # assume non-string values are a problem\n        if not isinstance(value, str):\n            self.fail(f\"Cannot load YAML from type {type(value)}\", param, ctx)\n        try:\n            param_option_name = param.opts[0] if param.opts else param.name\n            return parse_cli_yaml_string(value, param_option_name.strip(\"-\"))\n        except (ValidationError, DbtValidationError, OptionNotYamlDictError):\n            self.fail(f\"String '{value}' is not valid YAML\", param, ctx)\n\n\nclass Package(ParamType):\n    \"\"\"The Click STRING type. Converts string into dict with package name and version.\n    Example package:\n        package-name@1.0.0\n        package-name\n    \"\"\"\n\n    name = \"NewPackage\"\n\n    def convert(self, value, param, ctx):\n        # assume non-string values are a problem\n        if not isinstance(value, str):\n            self.fail(f\"Cannot load Package from type {type(value)}\", param, ctx)\n        try:\n            package_name, package_version = value.split(\"@\")\n            return {\"name\": package_name, \"version\": package_version}\n        except ValueError:\n            return {\"name\": value, \"version\": None}\n\n\nclass WarnErrorOptionsType(YAML):\n    \"\"\"The Click WarnErrorOptions type. Converts YAML strings into objects.\"\"\"\n\n    name = \"WarnErrorOptionsType\"\n\n    def convert(self, value, param, ctx):\n        # this function is being used by param in click\n        warn_error_options = super().convert(value, param, ctx)\n        normalize_warn_error_options(warn_error_options)\n\n        return WarnErrorOptionsV2(\n            error=warn_error_options.get(\"error\", []),\n            warn=warn_error_options.get(\"warn\", []),\n            silence=warn_error_options.get(\"silence\", []),\n            valid_error_names=ALL_EVENT_NAMES,\n        )\n\n\nclass SqlParseOptionsType(YAML):\n    \"\"\"The Click SqlParseOptions type. Parses YAML and applies sqlparse engine settings.\"\"\"\n\n    name = \"SqlParseOptionsType\"\n\n    VALID_KEYS = {\"MAX_GROUPING_DEPTH\", \"MAX_GROUPING_TOKENS\"}\n\n    def convert(self, value, param, ctx):\n        if value is None:\n            return None\n\n        import sqlparse\n\n        options = super().convert(value, param, ctx)\n\n        for key, val in options.items():\n            if key not in self.VALID_KEYS:\n                self.fail(\n                    f\"Unknown sqlparse option: {key}. \"\n                    f\"Valid options: {', '.join(sorted(self.VALID_KEYS))}\",\n                    param,\n                    ctx,\n                )\n            # None params may get stringified during `dbt retry`\n            if val is None or (isinstance(val, str) and val.lower() == \"none\"):\n                setattr(sqlparse.engine.grouping, key, None)\n            else:\n                try:\n                    int_val = int(val)\n                except (TypeError, ValueError):\n                    self.fail(f\"Value for {key} must be an integer, got: {val}\", param, ctx)\n                setattr(sqlparse.engine.grouping, key, int_val)\n\n        return options\n\n\nclass Truthy(ParamType):\n    \"\"\"The Click Truthy type.  Converts strings into a \"truthy\" type\"\"\"\n\n    name = \"TRUTHY\"\n\n    def convert(self, value, param, ctx):\n        # assume non-string / non-None values are a problem\n        if not isinstance(value, (str, None)):\n            self.fail(f\"Cannot load TRUTHY from type {type(value)}\", param, ctx)\n\n        if value is None or value.lower() in (\"0\", \"false\", \"f\"):\n            return None\n        else:\n            return value\n\n\nclass ChoiceTuple(Choice):\n    name = \"CHOICE_TUPLE\"\n\n    def convert(self, value, param, ctx):\n        if not isinstance(value, str):\n            for value_item in value:\n                super().convert(value_item, param, ctx)\n        else:\n            super().convert(value, param, ctx)\n\n        return value\n\n\nclass SampleType(ParamType):\n    name = \"SAMPLE\"\n\n    def convert(\n        self, value, param: Optional[Parameter], ctx: Optional[Context]\n    ) -> Optional[SampleWindow]:\n        if value is None:\n            return None\n\n        if isinstance(value, str):\n            try:\n                # Try and identify if it's a \"dict\" or a \"str\"\n                if value.lstrip()[0] == \"{\":\n                    param_option_name: str = param.opts[0] if param.opts else param.name  # type: ignore\n                    parsed_dict = parse_cli_yaml_string(value, param_option_name.strip(\"-\"))\n                    sample_window = SampleWindow.from_dict(parsed_dict)\n                    sample_window.start = sample_window.start.replace(tzinfo=pytz.UTC)\n                    sample_window.end = sample_window.end.replace(tzinfo=pytz.UTC)\n                    return sample_window\n                else:\n                    return SampleWindow.from_relative_string(value)\n            except Exception as e:\n                self.fail(e.__str__(), param, ctx)\n        else:\n            self.fail(f\"Cannot load SAMPLE_WINDOW from type {type(value)}\", param, ctx)\n"
  },
  {
    "path": "core/dbt/cli/options.py",
    "content": "import inspect\nimport typing as t\n\nimport click\n\nfrom dbt.cli.option_types import ChoiceTuple\n\nif t.TYPE_CHECKING:\n    from click import Context\n    from click.parser import _OptionParser, _ParsingState\n\n\n# Implementation from: https://stackoverflow.com/a/48394004\n# Note MultiOption options must be specified with type=tuple or type=ChoiceTuple (https://github.com/pallets/click/issues/2012)\nclass MultiOption(click.Option):\n    def __init__(self, *args, **kwargs) -> None:\n        self.save_other_options = kwargs.pop(\"save_other_options\", True)\n        nargs = kwargs.pop(\"nargs\", -1)\n        assert nargs == -1, \"nargs, if set, must be -1 not {}\".format(nargs)\n        super(MultiOption, self).__init__(*args, **kwargs)\n        # this makes mypy happy, setting these to None causes mypy failures\n        self._previous_parser_process = lambda *args, **kwargs: None\n        self._eat_all_parser = lambda *args, **kwargs: None\n\n        # validate that multiple=True\n        multiple = kwargs.pop(\"multiple\", None)\n        msg = f\"MultiOption named `{self.name}` must have multiple=True (rather than {multiple})\"\n        assert multiple, msg\n\n        # validate that type=tuple or type=ChoiceTuple\n        option_type = kwargs.pop(\"type\", None)\n        msg = f\"MultiOption named `{self.name}` must be tuple or ChoiceTuple (rather than {option_type})\"\n        if inspect.isclass(option_type):\n            assert issubclass(option_type, tuple), msg\n        else:\n            assert isinstance(option_type, ChoiceTuple), msg\n\n    def add_to_parser(self, parser: \"_OptionParser\", ctx: \"Context\"):\n        def parser_process(value: str, state: \"_ParsingState\"):\n            # method to hook to the parser.process\n            done = False\n            value_list = str.split(value, \" \")\n            if self.save_other_options:\n                # grab everything up to the next option\n                while state.rargs and not done:\n                    for prefix in self._eat_all_parser.prefixes:  # type: ignore[attr-defined]\n                        if state.rargs[0].startswith(prefix):\n                            done = True\n                    if not done:\n                        value_list.append(state.rargs.pop(0))\n            else:\n                # grab everything remaining\n                value_list += state.rargs\n                state.rargs[:] = []\n            value_tuple = tuple(value_list)\n            # call the actual process\n            self._previous_parser_process(value_tuple, state)\n\n        retval = super(MultiOption, self).add_to_parser(parser, ctx)\n        for name in self.opts:\n            our_parser = parser._long_opt.get(name) or parser._short_opt.get(name)\n            if our_parser:\n                self._eat_all_parser = our_parser  # type: ignore[assignment]\n                self._previous_parser_process = our_parser.process\n                # mypy doesnt like assingment to a method see https://github.com/python/mypy/issues/708\n                our_parser.process = parser_process  # type: ignore[method-assign]\n                break\n        return retval\n\n    def type_cast_value(self, ctx: \"Context\", value: t.Any) -> t.Any:\n        def flatten(data):\n            if isinstance(data, tuple):\n                for x in data:\n                    yield from flatten(x)\n            else:\n                yield data\n\n        # there will be nested tuples to flatten when multiple=True\n        value = super(MultiOption, self).type_cast_value(ctx, value)\n        if value:\n            value = tuple(flatten(value))\n        return value\n"
  },
  {
    "path": "core/dbt/cli/params.py",
    "content": "from dataclasses import dataclass\nfrom pathlib import Path\nfrom typing import Any, Callable, List, Optional\n\nimport click\n\nfrom dbt.cli.option_types import (\n    YAML,\n    ChoiceTuple,\n    Package,\n    SampleType,\n    SqlParseOptionsType,\n    WarnErrorOptionsType,\n)\nfrom dbt.cli.options import MultiOption\nfrom dbt.cli.resolvers import default_profiles_dir, default_project_dir\nfrom dbt.version import get_version_information\nfrom dbt_common.constants import ENGINE_ENV_PREFIX\nfrom dbt_common.exceptions import DbtInternalError\n\n# --- shared option specs --- #\nmodel_decls = (\"-m\", \"--models\", \"--model\")\nselect_decls = (\"-s\", \"--select\")\nselect_attrs = {\n    \"envvar\": None,\n    \"help\": \"Specify the nodes to include.\",\n    \"cls\": MultiOption,\n    \"multiple\": True,\n    \"type\": tuple,\n}\n\n\n@dataclass(frozen=True, init=False)\nclass EngineEnvVar:\n    name: str\n    old_name: Optional[str] = None\n\n    def __init__(self, envvar: str) -> None:\n        if envvar.startswith(ENGINE_ENV_PREFIX):\n            object.__setattr__(self, \"name\", envvar)\n            object.__setattr__(self, \"old_name\", None)\n        elif envvar.startswith(\"DBT\"):\n            object.__setattr__(self, \"name\", envvar.replace(\"DBT\", f\"{ENGINE_ENV_PREFIX}\"))\n            object.__setattr__(self, \"old_name\", envvar)\n        else:\n            raise DbtInternalError(\n                f\"Invalid environment variable: {envvar}, this will only happen if we add a new option to dbt that has an envvar that doesn't start with DBT_ or {ENGINE_ENV_PREFIX}\"\n            )\n\n\n# Record of env vars associated with options\nKNOWN_ENV_VARS: List[EngineEnvVar] = []\n\n\ndef _create_option_and_track_env_var(\n    *args: Any, **kwargs: Any\n) -> Callable[[click.decorators.FC], click.decorators.FC]:\n    \"\"\"\n    Abstraction that ensures that all options with env vars are\n    * tracked (used in validation later)\n    * have a `DBT_ENGINE_` prefixed env var\n    \"\"\"\n    global KNOWN_ENV_VARS\n\n    envvar = kwargs.get(\"envvar\", None)\n    if isinstance(envvar, str):\n        engine_env_var = EngineEnvVar(envvar)\n        KNOWN_ENV_VARS.append(engine_env_var)\n        if engine_env_var.old_name is not None:\n            # Order matters, the first envvar in the list is preferred\n            kwargs[\"envvar\"] = [engine_env_var.name, engine_env_var.old_name]\n\n    return click.option(*args, **kwargs)\n\n\n# --- The actual option definitions --- #\nadd_package = _create_option_and_track_env_var(\n    \"--add-package\",\n    help=\"Add a package to current package spec, specify it as package-name@version. Change the source with --source flag.\",\n    envvar=None,\n    type=Package(),\n)\n\nargs = _create_option_and_track_env_var(\n    \"--args\",\n    envvar=None,\n    help=\"Supply arguments to the macro. This dictionary will be mapped to the keyword arguments defined in the selected macro. This argument should be a YAML string, eg. '{my_variable: my_value}'\",\n    type=YAML(),\n)\n\nbrowser = _create_option_and_track_env_var(\n    \"--browser/--no-browser\",\n    envvar=None,\n    help=\"Whether or not to open a local web browser after starting the server\",\n    default=True,\n)\n\ncache_selected_only = _create_option_and_track_env_var(\n    \"--cache-selected-only/--no-cache-selected-only\",\n    envvar=\"DBT_CACHE_SELECTED_ONLY\",\n    help=\"At start of run, populate relational cache only for schemas containing selected nodes, or for all schemas of interest.\",\n)\n\nclean_project_files_only = _create_option_and_track_env_var(\n    \"--clean-project-files-only / --no-clean-project-files-only\",\n    envvar=\"DBT_CLEAN_PROJECT_FILES_ONLY\",\n    help=\"If disabled, dbt clean will delete all paths specified in clean-paths, even if they're outside the dbt project.\",\n    default=True,\n)\n\ncompile_docs = _create_option_and_track_env_var(\n    \"--compile/--no-compile\",\n    envvar=None,\n    help=\"Whether or not to run 'dbt compile' as part of docs generation\",\n    default=True,\n)\n\ncompile_inject_ephemeral_ctes = _create_option_and_track_env_var(\n    \"--inject-ephemeral-ctes/--no-inject-ephemeral-ctes\",\n    envvar=None,\n    help=\"Internal flag controlling injection of referenced ephemeral models' CTEs during `compile`.\",\n    hidden=True,\n    default=True,\n)\n\nconfig_dir = _create_option_and_track_env_var(\n    \"--config-dir\",\n    envvar=None,\n    help=\"Print a system-specific command to access the directory that the current dbt project is searching for a profiles.yml. Then, exit. This flag renders other debug step flags no-ops.\",\n    is_flag=True,\n)\n\ndebug = _create_option_and_track_env_var(\n    \"--debug/--no-debug\",\n    \"-d/ \",\n    envvar=\"DBT_DEBUG\",\n    help=\"Display debug logging during dbt execution. Useful for debugging and making bug reports.\",\n)\n\ndebug_connection = _create_option_and_track_env_var(\n    \"--connection\",\n    envvar=None,\n    help=\"Test the connection to the target database independent of dependency checks.\",\n    is_flag=True,\n)\n\n# flag was previously named DEFER_MODE\ndefer = _create_option_and_track_env_var(\n    \"--defer/--no-defer\",\n    envvar=\"DBT_DEFER\",\n    help=\"If set, resolve unselected nodes by deferring to the manifest within the --state directory.\",\n)\n\ndefer_state = _create_option_and_track_env_var(\n    \"--defer-state\",\n    envvar=\"DBT_DEFER_STATE\",\n    help=\"Override the state directory for deferral only.\",\n    type=click.Path(\n        dir_okay=True,\n        file_okay=False,\n        readable=True,\n        resolve_path=False,\n        path_type=Path,\n    ),\n)\n\ndeprecated_defer = _create_option_and_track_env_var(\n    \"--deprecated-defer\",\n    envvar=\"DBT_DEFER_TO_STATE\",\n    help=\"Internal flag for deprecating old env var.\",\n    default=False,\n    hidden=True,\n)\n\ndeprecated_favor_state = _create_option_and_track_env_var(\n    \"--deprecated-favor-state\",\n    envvar=\"DBT_FAVOR_STATE_MODE\",\n    help=\"Internal flag for deprecating old env var.\",\n)\n\n# Renamed to --export-saved-queries\ndeprecated_include_saved_query = _create_option_and_track_env_var(\n    \"--include-saved-query/--no-include-saved-query\",\n    envvar=\"DBT_INCLUDE_SAVED_QUERY\",\n    help=\"Include saved queries in the list of resources to be selected for build command\",\n    is_flag=True,\n    hidden=True,\n)\n\ndeprecated_print = _create_option_and_track_env_var(\n    \"--deprecated-print/--deprecated-no-print\",\n    envvar=\"DBT_NO_PRINT\",\n    help=\"Internal flag for deprecating old env var.\",\n    default=True,\n    hidden=True,\n    callback=lambda ctx, param, value: not value,\n)\n\ndeprecated_state = _create_option_and_track_env_var(\n    \"--deprecated-state\",\n    envvar=\"DBT_ARTIFACT_STATE_PATH\",\n    help=\"Internal flag for deprecating old env var.\",\n    hidden=True,\n    type=click.Path(\n        dir_okay=True,\n        file_okay=False,\n        readable=True,\n        resolve_path=True,\n        path_type=Path,\n    ),\n)\n\nempty = _create_option_and_track_env_var(\n    \"--empty/--no-empty\",\n    envvar=\"DBT_EMPTY\",\n    help=\"If specified, limit input refs and sources to zero rows.\",\n    is_flag=True,\n)\n\nempty_catalog = _create_option_and_track_env_var(\n    \"--empty-catalog\",\n    help=\"If specified, generate empty catalog.json file during the `dbt docs generate` command.\",\n    default=False,\n    is_flag=True,\n)\n\nevent_time_end = _create_option_and_track_env_var(\n    \"--event-time-end\",\n    envvar=\"DBT_EVENT_TIME_END\",\n    help=\"If specified, the end datetime dbt uses to filter microbatch model inputs (exclusive).\",\n    type=click.DateTime(),\n    default=None,\n)\n\nevent_time_start = _create_option_and_track_env_var(\n    \"--event-time-start\",\n    envvar=\"DBT_EVENT_TIME_START\",\n    help=\"If specified, the start datetime dbt uses to filter microbatch model inputs (inclusive).\",\n    type=click.DateTime(),\n    default=None,\n)\n\nexclude = _create_option_and_track_env_var(\n    \"--exclude\",\n    envvar=None,\n    type=tuple,\n    cls=MultiOption,\n    multiple=True,\n    help=\"Specify the nodes to exclude.\",\n)\n\nexclude_resource_type = _create_option_and_track_env_var(\n    \"--exclude-resource-types\",\n    \"--exclude-resource-type\",\n    envvar=\"DBT_EXCLUDE_RESOURCE_TYPES\",\n    help=\"Specify the types of resources that dbt will exclude\",\n    type=ChoiceTuple(\n        [\n            \"metric\",\n            \"semantic_model\",\n            \"saved_query\",\n            \"source\",\n            \"analysis\",\n            \"model\",\n            \"test\",\n            \"unit_test\",\n            \"exposure\",\n            \"snapshot\",\n            \"seed\",\n            \"function\",\n            \"default\",\n        ],\n        case_sensitive=False,\n    ),\n    cls=MultiOption,\n    multiple=True,\n    default=(),\n)\n\nexport_saved_queries = _create_option_and_track_env_var(\n    \"--export-saved-queries/--no-export-saved-queries\",\n    envvar=\"DBT_EXPORT_SAVED_QUERIES\",\n    help=\"Export saved queries within the 'build' command, otherwise no-op\",\n    is_flag=True,\n    hidden=True,\n)\n\nfail_fast = _create_option_and_track_env_var(\n    \"--fail-fast/--no-fail-fast\",\n    \"-x/ \",\n    envvar=\"DBT_FAIL_FAST\",\n    help=\"Stop execution on first failure.\",\n)\n\nfavor_state = _create_option_and_track_env_var(\n    \"--favor-state/--no-favor-state\",\n    envvar=\"DBT_FAVOR_STATE\",\n    help=\"If set, defer to the argument provided to the state flag for resolving unselected nodes, even if the node(s) exist as a database object in the current environment.\",\n)\n\nfull_refresh = _create_option_and_track_env_var(\n    \"--full-refresh\",\n    \"-f\",\n    envvar=\"DBT_FULL_REFRESH\",\n    help=\"If specified, dbt will drop incremental models and fully-recalculate the incremental table from the model definition.\",\n    is_flag=True,\n)\n\nhost = _create_option_and_track_env_var(\n    \"--host\",\n    envvar=\"DBT_HOST\",\n    help=\"host to serve dbt docs on\",\n    type=click.STRING,\n    default=\"127.0.0.1\",\n)\n\nindirect_selection = _create_option_and_track_env_var(\n    \"--indirect-selection\",\n    envvar=\"DBT_INDIRECT_SELECTION\",\n    help=\"Choose which tests to select that are adjacent to selected resources. Eager is most inclusive, cautious is most exclusive, and buildable is in between. Empty includes no tests at all.\",\n    type=click.Choice([\"eager\", \"cautious\", \"buildable\", \"empty\"], case_sensitive=False),\n    default=\"eager\",\n)\n\ninline = _create_option_and_track_env_var(\n    \"--inline\",\n    envvar=None,\n    help=\"Pass SQL inline to dbt compile and show\",\n)\n\ninline_direct = _create_option_and_track_env_var(\n    \"--inline-direct\",\n    envvar=None,\n    help=\"Internal flag to pass SQL inline to dbt show. Do not load the entire project or apply templating.\",\n    hidden=True,\n)\n\nintrospect = _create_option_and_track_env_var(\n    \"--introspect/--no-introspect\",\n    envvar=\"DBT_INTROSPECT\",\n    help=\"Whether to scaffold introspective queries as part of compilation\",\n    default=True,\n)\n\nlock = _create_option_and_track_env_var(\n    \"--lock\",\n    envvar=None,\n    help=\"Generate the package-lock.yml file without install the packages.\",\n    is_flag=True,\n)\n\nlog_cache_events = _create_option_and_track_env_var(\n    \"--log-cache-events/--no-log-cache-events\",\n    help=\"Enable verbose logging for relational cache events to help when debugging.\",\n    envvar=\"DBT_LOG_CACHE_EVENTS\",\n)\n\nlog_format = _create_option_and_track_env_var(\n    \"--log-format\",\n    envvar=\"DBT_LOG_FORMAT\",\n    help=\"Specify the format of logging to the console and the log file. Use --log-format-file to configure the format for the log file differently than the console.\",\n    type=click.Choice([\"text\", \"debug\", \"json\", \"default\"], case_sensitive=False),\n    default=\"default\",\n)\n\nlog_format_file = _create_option_and_track_env_var(\n    \"--log-format-file\",\n    envvar=\"DBT_LOG_FORMAT_FILE\",\n    help=\"Specify the format of logging to the log file by overriding the default value and the general --log-format setting.\",\n    type=click.Choice([\"text\", \"debug\", \"json\", \"default\"], case_sensitive=False),\n    default=\"debug\",\n)\n\nlog_level = _create_option_and_track_env_var(\n    \"--log-level\",\n    envvar=\"DBT_LOG_LEVEL\",\n    help=\"Specify the minimum severity of events that are logged to the console and the log file. Use --log-level-file to configure the severity for the log file differently than the console.\",\n    type=click.Choice([\"debug\", \"info\", \"warn\", \"error\", \"none\"], case_sensitive=False),\n    default=\"info\",\n)\n\nlog_level_file = _create_option_and_track_env_var(\n    \"--log-level-file\",\n    envvar=\"DBT_LOG_LEVEL_FILE\",\n    help=\"Specify the minimum severity of events that are logged to the log file by overriding the default value and the general --log-level setting.\",\n    type=click.Choice([\"debug\", \"info\", \"warn\", \"error\", \"none\"], case_sensitive=False),\n    default=\"debug\",\n)\n\nlog_file_max_bytes = _create_option_and_track_env_var(\n    \"--log-file-max-bytes\",\n    envvar=\"DBT_LOG_FILE_MAX_BYTES\",\n    help=\"Configure the max file size in bytes for a single dbt.log file, before rolling over. 0 means no limit.\",\n    default=10 * 1024 * 1024,  # 10mb\n    type=click.INT,\n    hidden=True,\n)\n\nlog_path = _create_option_and_track_env_var(\n    \"--log-path\",\n    envvar=\"DBT_LOG_PATH\",\n    help=\"Configure the 'log-path'. Only applies this setting for the current run. Overrides the 'DBT_LOG_PATH' if it is set.\",\n    default=None,\n    type=click.Path(resolve_path=True, path_type=Path),\n)\n\nmacro_debugging = _create_option_and_track_env_var(\n    \"--macro-debugging/--no-macro-debugging\",\n    envvar=\"DBT_MACRO_DEBUGGING\",\n    hidden=True,\n)\n\n\nsqlparse_options = _create_option_and_track_env_var(\n    \"--sqlparse\",\n    envvar=\"DBT_ENGINE_SQLPARSE\",\n    hidden=True,\n    help=\"Set sqlparse options MAX_GROUPING_DEPTH and MAX_GROUPING_TOKENS as YAML.\",\n    type=SqlParseOptionsType(),\n    default='{\"MAX_GROUPING_DEPTH\": null, \"MAX_GROUPING_TOKENS\": null}',\n    is_eager=True,\n)\n\nmodels = _create_option_and_track_env_var(*model_decls, **select_attrs)  # type: ignore[arg-type]\n\n# This less standard usage of --output where output_path below is more standard\noutput = _create_option_and_track_env_var(\n    \"--output\",\n    envvar=None,\n    help=\"Specify the output format: either JSON or a newline-delimited list of selectors, paths, or names\",\n    type=click.Choice([\"json\", \"name\", \"path\", \"selector\"], case_sensitive=False),\n    default=\"selector\",\n)\n\noutput_keys = _create_option_and_track_env_var(\n    \"--output-keys\",\n    envvar=None,\n    help=(\n        \"Space-delimited listing of node properties to include as custom keys for JSON output. \"\n        \"Supports nested keys using dot notation \"\n        \"(e.g. `--output json --output-keys name config.materialized resource_type`)\"\n    ),\n    type=tuple,\n    cls=MultiOption,\n    multiple=True,\n    default=[],\n)\n\noutput_path = _create_option_and_track_env_var(\n    \"--output\",\n    \"-o\",\n    envvar=None,\n    help=\"Specify the output path for the JSON report. By default, outputs to 'target/sources.json'\",\n    type=click.Path(file_okay=True, dir_okay=False, writable=True),\n    default=None,\n)\n\npartial_parse = _create_option_and_track_env_var(\n    \"--partial-parse/--no-partial-parse\",\n    envvar=\"DBT_PARTIAL_PARSE\",\n    help=\"Allow for partial parsing by looking for and writing to a pickle file in the target directory. This overrides the user configuration file.\",\n    default=True,\n)\n\npartial_parse_file_diff = _create_option_and_track_env_var(\n    \"--partial-parse-file-diff/--no-partial-parse-file-diff\",\n    envvar=\"DBT_PARTIAL_PARSE_FILE_DIFF\",\n    help=\"Internal flag for whether to compute a file diff during partial parsing.\",\n    hidden=True,\n    default=True,\n)\n\npartial_parse_file_path = _create_option_and_track_env_var(\n    \"--partial-parse-file-path\",\n    envvar=\"DBT_PARTIAL_PARSE_FILE_PATH\",\n    help=\"Internal flag for path to partial_parse.manifest file.\",\n    default=None,\n    hidden=True,\n    type=click.Path(exists=True, dir_okay=False, resolve_path=True),\n)\n\nprint = _create_option_and_track_env_var(\n    \"--print/--no-print\",\n    envvar=\"DBT_PRINT\",\n    help=\"Output all {{ print() }} macro calls.\",\n    default=True,\n)\n\npopulate_cache = _create_option_and_track_env_var(\n    \"--populate-cache/--no-populate-cache\",\n    envvar=\"DBT_POPULATE_CACHE\",\n    help=\"At start of run, use `show` or `information_schema` queries to populate a relational cache, which can speed up subsequent materializations.\",\n    default=True,\n)\n\nport = _create_option_and_track_env_var(\n    \"--port\",\n    envvar=None,\n    help=\"Specify the port number for the docs server\",\n    default=8080,\n    type=click.INT,\n)\n\nprinter_width = _create_option_and_track_env_var(\n    \"--printer-width\",\n    envvar=\"DBT_PRINTER_WIDTH\",\n    help=\"Sets the width of terminal output\",\n    type=click.INT,\n    default=80,\n)\n\nprofile = _create_option_and_track_env_var(\n    \"--profile\",\n    envvar=\"DBT_PROFILE\",\n    help=\"Which existing profile to load. Overrides setting in dbt_project.yml.\",\n)\n\nprofiles_dir = _create_option_and_track_env_var(\n    \"--profiles-dir\",\n    envvar=\"DBT_PROFILES_DIR\",\n    help=\"Which directory to look in for the profiles.yml file. If not set, dbt will look in the current working directory first, then HOME/.dbt/\",\n    default=default_profiles_dir,\n    type=click.Path(exists=True),\n)\n\n# `dbt debug` uses this because it implements custom behaviour for non-existent profiles.yml directories\n# `dbt deps` does not load a profile at all\n# `dbt init` will write profiles.yml if it doesn't yet exist\nprofiles_dir_exists_false = _create_option_and_track_env_var(\n    \"--profiles-dir\",\n    envvar=\"DBT_PROFILES_DIR\",\n    help=\"Which directory to look in for the profiles.yml file. If not set, dbt will look in the current working directory first, then HOME/.dbt/\",\n    default=default_profiles_dir,\n    type=click.Path(exists=False),\n)\n\nproject_dir = _create_option_and_track_env_var(\n    \"--project-dir\",\n    envvar=\"DBT_PROJECT_DIR\",\n    help=\"Which directory to look in for the dbt_project.yml file. Default is the current working directory and its parents.\",\n    default=default_project_dir,\n    type=click.Path(exists=True),\n)\n\nquiet = _create_option_and_track_env_var(\n    \"--quiet/--no-quiet\",\n    \"-q\",\n    envvar=\"DBT_QUIET\",\n    help=\"Suppress all non-error logging to stdout. Does not affect {{ print() }} macro calls.\",\n)\n\nraw_select = _create_option_and_track_env_var(*select_decls, **select_attrs)  # type: ignore[arg-type]\n\nrecord_timing_info = _create_option_and_track_env_var(\n    \"--record-timing-info\",\n    \"-r\",\n    envvar=None,\n    help=\"When this option is passed, dbt will output low-level timing stats to the specified file. Example: `--record-timing-info output.profile`\",\n    type=click.Path(exists=False),\n)\n\nresource_type = _create_option_and_track_env_var(\n    \"--resource-types\",\n    \"--resource-type\",\n    envvar=\"DBT_RESOURCE_TYPES\",\n    help=\"Restricts the types of resources that dbt will include\",\n    type=ChoiceTuple(\n        [\n            \"metric\",\n            \"semantic_model\",\n            \"saved_query\",\n            \"source\",\n            \"analysis\",\n            \"function\",\n            \"model\",\n            \"test\",\n            \"unit_test\",\n            \"exposure\",\n            \"snapshot\",\n            \"seed\",\n            \"default\",\n            \"all\",\n        ],\n        case_sensitive=False,\n    ),\n    cls=MultiOption,\n    multiple=True,\n    default=(),\n)\n\nsample = _create_option_and_track_env_var(\n    \"--sample\",\n    envvar=\"DBT_SAMPLE\",\n    help=\"Run in sample mode with given SAMPLE_WINDOW spec, such that ref/source calls are sampled by the sample window.\",\n    default=None,\n    type=SampleType(),\n)\n\n# `--select` and `--models` are analogous for most commands except `dbt list` for legacy reasons.\n# Most CLI arguments should use the combined `select` option that aliases `--models` to `--select`.\n# However, if you need to split out these separators (like `dbt ls`), use the `models` and `raw_select` options instead.\n# See https://github.com/dbt-labs/dbt-core/pull/6774#issuecomment-1408476095 for more info.\nselect = _create_option_and_track_env_var(*select_decls, *model_decls, **select_attrs)  # type: ignore[arg-type]\n\nselector = _create_option_and_track_env_var(\n    \"--selector\",\n    envvar=None,\n    help=\"The selector name to use, as defined in selectors.yml\",\n)\n\nsend_anonymous_usage_stats = _create_option_and_track_env_var(\n    \"--send-anonymous-usage-stats/--no-send-anonymous-usage-stats\",\n    envvar=\"DBT_SEND_ANONYMOUS_USAGE_STATS\",\n    help=\"Send anonymous usage stats to dbt Labs.\",\n    default=True,\n)\n\nshow = _create_option_and_track_env_var(\n    \"--show\",\n    envvar=None,\n    help=\"Show a sample of the loaded data in the terminal\",\n    is_flag=True,\n)\n\nshow_limit = _create_option_and_track_env_var(\n    \"--limit\",\n    envvar=None,\n    help=\"Limit the number of results returned by dbt show\",\n    type=click.INT,\n    default=5,\n)\n\nshow_output_format = _create_option_and_track_env_var(\n    \"--output\",\n    envvar=None,\n    help=\"Output format for dbt compile and dbt show\",\n    type=click.Choice([\"json\", \"text\"], case_sensitive=False),\n    default=\"text\",\n)\n\nshow_resource_report = _create_option_and_track_env_var(\n    \"--show-resource-report/--no-show-resource-report\",\n    default=False,\n    envvar=\"DBT_SHOW_RESOURCE_REPORT\",\n    hidden=True,\n)\n\n# TODO:  The env var is a correction!\n# The original env var was `DBT_TEST_SINGLE_THREADED`.\n# This broke the existing naming convention.\n# This will need to be communicated as a change to the community!\n#\n# N.B. This flag is only used for testing, hence it's hidden from help text.\nsingle_threaded = _create_option_and_track_env_var(\n    \"--single-threaded/--no-single-threaded\",\n    envvar=\"DBT_SINGLE_THREADED\",\n    default=False,\n    hidden=True,\n)\n\nshow_all_deprecations = _create_option_and_track_env_var(\n    \"--show-all-deprecations/--no-show-all-deprecations\",\n    envvar=None,\n    help=\"By default, each type of a deprecation warning is only shown once. Use this flag to show all deprecation warning instances.\",\n    is_flag=True,\n    default=False,\n)\n\nskip_profile_setup = _create_option_and_track_env_var(\n    \"--skip-profile-setup\",\n    \"-s\",\n    envvar=None,\n    help=\"Skip interactive profile setup.\",\n    is_flag=True,\n)\n\nskip_debug = _create_option_and_track_env_var(\n    \"--skip-debug\",\n    envvar=None,\n    help=\"Skip running dbt debug after project initialization.\",\n    is_flag=True,\n    default=False,\n)\n\nsource = _create_option_and_track_env_var(\n    \"--source\",\n    envvar=None,\n    help=\"Source to download page from, must be one of hub, git, or local. Defaults to hub.\",\n    type=click.Choice([\"hub\", \"git\", \"local\"], case_sensitive=True),\n    default=\"hub\",\n)\n\nstate = _create_option_and_track_env_var(\n    \"--state\",\n    envvar=\"DBT_STATE\",\n    help=\"Unless overridden, use this state directory for both state comparison and deferral.\",\n    type=click.Path(\n        dir_okay=True,\n        file_okay=False,\n        readable=True,\n        resolve_path=False,\n        path_type=Path,\n    ),\n)\n\nstatic = _create_option_and_track_env_var(\n    \"--static\",\n    help=\"Generate an additional static_index.html with manifest and catalog built-in.\",\n    default=False,\n    is_flag=True,\n)\n\nstatic_parser = _create_option_and_track_env_var(\n    \"--static-parser/--no-static-parser\",\n    envvar=\"DBT_STATIC_PARSER\",\n    help=\"Use the static parser.\",\n    default=True,\n)\n\nstore_failures = _create_option_and_track_env_var(\n    \"--store-failures\",\n    envvar=\"DBT_STORE_FAILURES\",\n    help=\"Store test results (failing rows) in the database\",\n    is_flag=True,\n)\n\ntarget = _create_option_and_track_env_var(\n    \"--target\",\n    \"-t\",\n    envvar=\"DBT_TARGET\",\n    help=\"Which target to load for the given profile\",\n)\n\ntarget_path = _create_option_and_track_env_var(\n    \"--target-path\",\n    envvar=\"DBT_TARGET_PATH\",\n    help=\"Configure the 'target-path'. Only applies this setting for the current run. Overrides the 'DBT_TARGET_PATH' if it is set.\",\n    type=click.Path(),\n)\n\nthreads = _create_option_and_track_env_var(\n    \"--threads\",\n    envvar=None,\n    help=\"Specify number of threads to use while executing models. Overrides settings in profiles.yml.\",\n    default=None,\n    type=click.INT,\n)\n\nupgrade = _create_option_and_track_env_var(\n    \"--upgrade\",\n    envvar=None,\n    help=\"Upgrade packages to the latest version.\",\n    is_flag=True,\n)\n\nuse_colors = _create_option_and_track_env_var(\n    \"--use-colors/--no-use-colors\",\n    envvar=\"DBT_USE_COLORS\",\n    help=\"Specify whether log output is colorized in the console and the log file. Use --use-colors-file/--no-use-colors-file to colorize the log file differently than the console.\",\n    default=True,\n)\n\nuse_colors_file = _create_option_and_track_env_var(\n    \"--use-colors-file/--no-use-colors-file\",\n    envvar=\"DBT_USE_COLORS_FILE\",\n    help=\"Specify whether log file output is colorized by overriding the default value and the general --use-colors/--no-use-colors setting.\",\n    default=True,\n)\n\nuse_experimental_parser = _create_option_and_track_env_var(\n    \"--use-experimental-parser/--no-use-experimental-parser\",\n    envvar=\"DBT_USE_EXPERIMENTAL_PARSER\",\n    help=\"Enable experimental parsing features.\",\n)\n\nuse_fast_test_edges = _create_option_and_track_env_var(\n    \"--use-fast-test-edges/--no-use-fast-test-edges\",\n    envvar=\"DBT_USE_FAST_TEST_EDGES\",\n    default=False,\n    hidden=True,\n)\n\nvars = _create_option_and_track_env_var(\n    \"--vars\",\n    envvar=None,\n    help=\"Supply variables to the project. This argument overrides variables defined in your dbt_project.yml file. This argument should be a YAML string, eg. '{my_variable: my_value}'\",\n    type=YAML(),\n    default=\"{}\",\n)\n\n\n# TODO: when legacy flags are deprecated use\n# click.version_option instead of a callback\ndef _version_callback(ctx, _param, value):\n    if not value or ctx.resilient_parsing:\n        return\n    click.echo(get_version_information())\n    ctx.exit()\n\n\nversion = _create_option_and_track_env_var(\n    \"--version\",\n    \"-V\",\n    \"-v\",\n    callback=_version_callback,\n    envvar=None,\n    expose_value=False,\n    help=\"Show version information and exit\",\n    is_eager=True,\n    is_flag=True,\n)\n\nversion_check = _create_option_and_track_env_var(\n    \"--version-check/--no-version-check\",\n    envvar=\"DBT_VERSION_CHECK\",\n    help=\"If set, ensure the installed dbt version matches the require-dbt-version specified in the dbt_project.yml file (if any). Otherwise, allow them to differ.\",\n    default=True,\n)\n\nwarn_error = _create_option_and_track_env_var(\n    \"--warn-error\",\n    envvar=\"DBT_WARN_ERROR\",\n    help=\"If dbt would normally warn, instead raise an exception. Examples include --select that selects nothing, deprecations, configurations with no associated models, invalid test configurations, and missing sources/refs in tests.\",\n    default=None,\n    is_flag=True,\n)\n\nwarn_error_options = _create_option_and_track_env_var(\n    \"--warn-error-options\",\n    envvar=\"DBT_WARN_ERROR_OPTIONS\",\n    default=\"{}\",\n    help=\"\"\"If dbt would normally warn, instead raise an exception based on error/warn configuration. Examples include --select that selects nothing, deprecations, configurations with no associated models, invalid test configurations,\n    and missing sources/refs in tests. This argument should be a YAML string, with keys 'error' or 'warn'. eg. '{\"error\": \"all\", \"warn\": [\"NoNodesForSelectionCriteria\"]}'\"\"\",\n    type=WarnErrorOptionsType(),\n)\n\nwrite_json = _create_option_and_track_env_var(\n    \"--write-json/--no-write-json\",\n    envvar=\"DBT_WRITE_JSON\",\n    help=\"Whether or not to write the manifest.json and run_results.json files to the target directory\",\n    default=True,\n)\n\nupload_artifacts = _create_option_and_track_env_var(\n    \"--upload-to-artifacts-ingest-api/--no-upload-to-artifacts-ingest-api\",\n    envvar=\"DBT_UPLOAD_TO_ARTIFACTS_INGEST_API\",\n    help=\"Whether or not to upload the artifacts to the dbt Cloud API\",\n    default=False,\n)\n"
  },
  {
    "path": "core/dbt/cli/requires.py",
    "content": "import importlib.util\nimport os\nimport time\nimport traceback\nfrom functools import update_wrapper\nfrom typing import Dict, Optional\n\nfrom click import Context\n\nimport dbt.tracking\nfrom dbt.adapters.factory import adapter_management, get_adapter, register_adapter\nfrom dbt.cli.exceptions import ExceptionExit, ResultExit\nfrom dbt.cli.flags import Flags\nfrom dbt.config import RuntimeConfig\nfrom dbt.config.catalogs import get_active_write_integration, load_catalogs\nfrom dbt.config.runtime import UnsetProfile, load_profile, load_project\nfrom dbt.context.providers import generate_runtime_macro_context\nfrom dbt.context.query_header import generate_query_header_context\nfrom dbt.deprecations import show_deprecations_summary\nfrom dbt.env_vars import KNOWN_ENGINE_ENV_VARS, validate_engine_env_vars\nfrom dbt.events.logging import setup_event_logger\nfrom dbt.events.types import (\n    ArtifactUploadError,\n    CommandCompleted,\n    MainEncounteredError,\n    MainReportArgs,\n    MainReportVersion,\n    MainStackTrace,\n    MainTrackingUserState,\n    ResourceReport,\n)\nfrom dbt.exceptions import DbtProjectError, FailFastError\nfrom dbt.flags import get_flag_dict, get_flags, set_flags\nfrom dbt.mp_context import get_mp_context\nfrom dbt.parser.manifest import parse_manifest\nfrom dbt.plugins import set_up_plugin_manager\nfrom dbt.profiler import profiler\nfrom dbt.tracking import active_user, initialize_from_flags, track_run\nfrom dbt.utils import try_get_max_rss_kb\nfrom dbt.utils.artifact_upload import upload_artifacts\nfrom dbt.version import installed as installed_version\nfrom dbt_common.clients.system import get_env\nfrom dbt_common.context import get_invocation_context, set_invocation_context\nfrom dbt_common.events.base_types import EventLevel\nfrom dbt_common.events.event_manager_client import get_event_manager\nfrom dbt_common.events.functions import LOG_VERSION, fire_event\nfrom dbt_common.events.helpers import get_json_string_utcnow\nfrom dbt_common.exceptions import DbtBaseException as DbtException\nfrom dbt_common.invocation import reset_invocation_id\nfrom dbt_common.record import (\n    Recorder,\n    RecorderMode,\n    get_record_mode_from_env,\n    get_record_types_from_dict,\n    get_record_types_from_env,\n)\nfrom dbt_common.utils import cast_dict_to_dict_of_strings\n\n\ndef _cross_propagate_engine_env_vars(env_dict: Dict[str, str]) -> None:\n    for env_var in KNOWN_ENGINE_ENV_VARS:\n        if env_var.old_name is not None:\n            # If the old name is in the env dict, and not the new name, set the new name based on the old name\n            if env_var.old_name in env_dict and env_var.name not in env_dict:\n                env_dict[env_var.name] = env_dict[env_var.old_name]\n            # If the new name is in the env dict, override the old name with it\n            elif env_var.name in env_dict:\n                env_dict[env_var.old_name] = env_dict[env_var.name]\n\n\ndef preflight(func):\n    def wrapper(*args, **kwargs):\n        ctx = args[0]\n        assert isinstance(ctx, Context)\n        ctx.obj = ctx.obj or {}\n\n        set_invocation_context({})\n\n        # Record/Replay\n        setup_record_replay()\n\n        # Must be set after record/replay is set up so that the env can be\n        # recorded or replayed if needed.\n        env_dict = get_env()\n        _cross_propagate_engine_env_vars(env_dict)\n        get_invocation_context()._env = env_dict\n\n        # Flags\n        flags = Flags(ctx)\n        ctx.obj[\"flags\"] = flags\n        set_flags(flags)\n        get_event_manager().require_warn_or_error_handling = (\n            flags.require_all_warnings_handled_by_warn_error\n        )\n\n        # Reset invocation_id for each 'invocation' of a dbt command (can happen multiple times in a single process)\n        reset_invocation_id()\n\n        # Logging\n        callbacks = ctx.obj.get(\"callbacks\", [])\n        setup_event_logger(flags=flags, callbacks=callbacks)\n\n        # Tracking\n        initialize_from_flags(flags.SEND_ANONYMOUS_USAGE_STATS, flags.PROFILES_DIR)\n        ctx.with_resource(track_run(run_command=flags.WHICH))\n\n        # Now that we have our logger, fire away!\n        fire_event(MainReportVersion(version=str(installed_version), log_version=LOG_VERSION))\n        flags_dict_str = cast_dict_to_dict_of_strings(get_flag_dict())\n        fire_event(MainReportArgs(args=flags_dict_str))\n\n        # Deprecation warnings\n        flags.fire_deprecations(ctx)\n\n        if active_user is not None:  # mypy appeasement, always true\n            fire_event(MainTrackingUserState(user_state=active_user.state()))\n\n        # Profiling\n        if flags.RECORD_TIMING_INFO:\n            ctx.with_resource(profiler(enable=True, outfile=flags.RECORD_TIMING_INFO))\n\n        # Adapter management\n        ctx.with_resource(adapter_management())\n\n        # Validate engine env var restricted name space\n        validate_engine_env_vars()\n\n        return func(*args, **kwargs)\n\n    return update_wrapper(wrapper, func)\n\n\ndef setup_record_replay():\n    rec_mode = get_record_mode_from_env()\n    rec_types = get_record_types_from_env()\n\n    recorder: Optional[Recorder] = None\n    if rec_mode == RecorderMode.REPLAY:\n        previous_recording_path = os.environ.get(\n            \"DBT_ENGINE_RECORDER_FILE_PATH\"\n        ) or os.environ.get(\"DBT_RECORDER_FILE_PATH\")\n        recorder = Recorder(\n            RecorderMode.REPLAY, types=rec_types, previous_recording_path=previous_recording_path\n        )\n    elif rec_mode == RecorderMode.DIFF:\n        previous_recording_path = os.environ.get(\n            \"DBT_ENGINE_RECORDER_FILE_PATH\"\n        ) or os.environ.get(\"DBT_RECORDER_FILE_PATH\")\n        # ensure types match the previous recording\n        types = get_record_types_from_dict(previous_recording_path)\n        recorder = Recorder(\n            RecorderMode.DIFF, types=types, previous_recording_path=previous_recording_path\n        )\n    elif rec_mode == RecorderMode.RECORD:\n        recorder = Recorder(RecorderMode.RECORD, types=rec_types)\n\n    get_invocation_context().recorder = recorder\n\n\ndef tear_down_record_replay():\n    recorder = get_invocation_context().recorder\n    if recorder is not None:\n        if recorder.mode == RecorderMode.RECORD:\n            recorder.write()\n        if recorder.mode == RecorderMode.DIFF:\n            recorder.write()\n            recorder.write_diffs(diff_file_name=\"recording_diffs.json\")\n        elif recorder.mode == RecorderMode.REPLAY:\n            recorder.write_diffs(\"replay_diffs.json\")\n\n\ndef postflight(func):\n    \"\"\"The decorator that handles all exception handling for the click commands.\n    This decorator must be used before any other decorators that may throw an exception.\"\"\"\n\n    def wrapper(*args, **kwargs):\n        ctx = args[0]\n        start_func = time.perf_counter()\n        success = False\n\n        try:\n            result, success = func(*args, **kwargs)\n        except FailFastError as e:\n            fire_event(MainEncounteredError(exc=str(e)))\n            raise ResultExit(e.result)\n        except DbtException as e:\n            fire_event(MainEncounteredError(exc=str(e)))\n            raise ExceptionExit(e)\n        except BaseException as e:\n            fire_event(MainEncounteredError(exc=str(e)))\n            fire_event(MainStackTrace(stack_trace=traceback.format_exc()))\n            raise ExceptionExit(e)\n        finally:\n            # Fire ResourceReport, but only on systems which support the resource\n            # module. (Skip it on Windows).\n            try:\n                if get_flags().upload_to_artifacts_ingest_api:\n                    upload_artifacts(\n                        get_flags().project_dir, get_flags().target_path, ctx.command.name\n                    )\n\n            except Exception as e:\n                fire_event(ArtifactUploadError(msg=str(e)))\n\n            show_deprecations_summary()\n\n            if importlib.util.find_spec(\"resource\") is not None:\n                import resource\n\n                rusage = resource.getrusage(resource.RUSAGE_SELF)\n                fire_event(\n                    ResourceReport(\n                        command_name=ctx.command.name,\n                        command_success=success,\n                        command_wall_clock_time=time.perf_counter() - start_func,\n                        process_user_time=rusage.ru_utime,\n                        process_kernel_time=rusage.ru_stime,\n                        process_mem_max_rss=try_get_max_rss_kb() or rusage.ru_maxrss,\n                        process_in_blocks=rusage.ru_inblock,\n                        process_out_blocks=rusage.ru_oublock,\n                    ),\n                    (\n                        EventLevel.INFO\n                        if \"flags\" in ctx.obj and ctx.obj[\"flags\"].SHOW_RESOURCE_REPORT\n                        else None\n                    ),\n                )\n\n            fire_event(\n                CommandCompleted(\n                    command=ctx.command_path,\n                    success=success,\n                    completed_at=get_json_string_utcnow(),\n                    elapsed=time.perf_counter() - start_func,\n                )\n            )\n\n            tear_down_record_replay()\n\n        if not success:\n            raise ResultExit(result)\n\n        return (result, success)\n\n    return update_wrapper(wrapper, func)\n\n\n# TODO: UnsetProfile is necessary for deps and clean to load a project.\n# This decorator and its usage can be removed once https://github.com/dbt-labs/dbt-core/issues/6257 is closed.\ndef unset_profile(func):\n    def wrapper(*args, **kwargs):\n        ctx = args[0]\n        assert isinstance(ctx, Context)\n\n        profile = UnsetProfile()\n        ctx.obj[\"profile\"] = profile\n\n        return func(*args, **kwargs)\n\n    return update_wrapper(wrapper, func)\n\n\ndef profile(func):\n    def wrapper(*args, **kwargs):\n        ctx = args[0]\n        assert isinstance(ctx, Context)\n\n        flags = ctx.obj[\"flags\"]\n        # TODO: Generalize safe access to flags.THREADS:\n        # https://github.com/dbt-labs/dbt-core/issues/6259\n        threads = getattr(flags, \"THREADS\", None)\n        profile = load_profile(flags.PROJECT_DIR, flags.VARS, flags.PROFILE, flags.TARGET, threads)\n        ctx.obj[\"profile\"] = profile\n        get_invocation_context().uses_adapter(profile.credentials.type)\n\n        return func(*args, **kwargs)\n\n    return update_wrapper(wrapper, func)\n\n\ndef project(func):\n    def wrapper(*args, **kwargs):\n        ctx = args[0]\n        assert isinstance(ctx, Context)\n\n        # TODO: Decouple target from profile, and remove the need for profile here:\n        # https://github.com/dbt-labs/dbt-core/issues/6257\n        if not ctx.obj.get(\"profile\"):\n            raise DbtProjectError(\"profile required for project\")\n\n        flags = ctx.obj[\"flags\"]\n        # TODO deprecations warnings fired from loading the project will lack\n        # the project_id in the snowplow event.\n\n        # Determine if vars should be required during project loading.\n        # Commands that don't need vars evaluated (like 'deps', 'clean')\n        # should use lenient mode (require_vars=False) to allow missing vars.\n        # Commands that validate or execute (like 'run', 'compile', 'build', 'debug') should use\n        # strict mode (require_vars=True) to show helpful \"Required var X not found\" errors.\n        # If adding more commands to lenient mode, update this condition.\n        require_vars = flags.WHICH != \"deps\"\n\n        project = load_project(\n            flags.PROJECT_DIR,\n            flags.VERSION_CHECK,\n            ctx.obj[\"profile\"],\n            flags.VARS,\n            validate=True,\n            require_vars=require_vars,\n        )\n        ctx.obj[\"project\"] = project\n\n        # Plugins\n        set_up_plugin_manager(project_name=project.project_name)\n\n        if dbt.tracking.active_user is not None:\n            project_id = None if project is None else project.hashed_name()\n\n            dbt.tracking.track_project_id({\"project_id\": project_id})\n\n        return func(*args, **kwargs)\n\n    return update_wrapper(wrapper, func)\n\n\ndef runtime_config(func):\n    \"\"\"A decorator used by click command functions for generating a runtime\n    config given a profile and project.\n    \"\"\"\n\n    def wrapper(*args, **kwargs):\n        ctx = args[0]\n        assert isinstance(ctx, Context)\n\n        req_strs = [\"profile\", \"project\"]\n        reqs = [ctx.obj.get(req_str) for req_str in req_strs]\n\n        if None in reqs:\n            raise DbtProjectError(\"profile and project required for runtime_config\")\n\n        config = RuntimeConfig.from_parts(\n            ctx.obj[\"project\"],\n            ctx.obj[\"profile\"],\n            ctx.obj[\"flags\"],\n        )\n\n        ctx.obj[\"runtime_config\"] = config\n\n        if dbt.tracking.active_user is not None:\n            adapter_type = (\n                getattr(config.credentials, \"type\", None)\n                if hasattr(config, \"credentials\")\n                else None\n            )\n            adapter_unique_id = (\n                config.credentials.hashed_unique_field()\n                if hasattr(config, \"credentials\")\n                else None\n            )\n\n            dbt.tracking.track_adapter_info(\n                {\n                    \"adapter_type\": adapter_type,\n                    \"adapter_unique_id\": adapter_unique_id,\n                }\n            )\n\n        return func(*args, **kwargs)\n\n    return update_wrapper(wrapper, func)\n\n\ndef catalogs(func):\n    \"\"\"A decorator used by click command functions for loading catalogs\"\"\"\n\n    def wrapper(*args, **kwargs):\n        ctx = args[0]\n        assert isinstance(ctx, Context)\n\n        req_strs = [\"flags\", \"profile\", \"project\"]\n        reqs = [ctx.obj.get(req_str) for req_str in req_strs]\n        if None in reqs:\n            raise DbtProjectError(\"profile and flags required to load catalogs\")\n\n        flags = ctx.obj[\"flags\"]\n        ctx_project = ctx.obj[\"project\"]\n\n        _catalogs = load_catalogs(flags.PROJECT_DIR, ctx_project.project_name, flags.VARS)\n        ctx.obj[\"catalogs\"] = _catalogs\n\n        return func(*args, **kwargs)\n\n    return update_wrapper(wrapper, func)\n\n\ndef manifest(*args0, write=True, write_perf_info=False):\n    \"\"\"A decorator used by click command functions for generating a manifest\n    given a profile, project, and runtime config. This also registers the adapter\n    from the runtime config and conditionally writes the manifest to disk.\n    \"\"\"\n\n    def outer_wrapper(func):\n        def wrapper(*args, **kwargs):\n            ctx = args[0]\n            assert isinstance(ctx, Context)\n\n            setup_manifest(ctx, write=write, write_perf_info=write_perf_info)\n            return func(*args, **kwargs)\n\n        return update_wrapper(wrapper, func)\n\n    # if there are no args, the decorator was used without params @decorator\n    # otherwise, the decorator was called with params @decorator(arg)\n    if len(args0) == 0:\n        return outer_wrapper\n    return outer_wrapper(args0[0])\n\n\ndef setup_manifest(ctx: Context, write: bool = True, write_perf_info: bool = False):\n    \"\"\"Load the manifest and add it to the context.\"\"\"\n    req_strs = [\"profile\", \"project\", \"runtime_config\"]\n    reqs = [ctx.obj.get(dep) for dep in req_strs]\n\n    if None in reqs:\n        raise DbtProjectError(\"profile, project, and runtime_config required for manifest\")\n\n    runtime_config = ctx.obj[\"runtime_config\"]\n\n    catalogs = ctx.obj[\"catalogs\"] if \"catalogs\" in ctx.obj else []\n    active_integrations = [get_active_write_integration(catalog) for catalog in catalogs]\n\n    # if a manifest has already been set on the context, don't overwrite it\n    if ctx.obj.get(\"manifest\") is None:\n        ctx.obj[\"manifest\"] = parse_manifest(\n            runtime_config,\n            write_perf_info,\n            write,\n            ctx.obj[\"flags\"].write_json,\n            active_integrations,\n        )\n        adapter = get_adapter(runtime_config)\n    else:\n        register_adapter(runtime_config, get_mp_context())\n        adapter = get_adapter(runtime_config)\n        adapter.set_macro_context_generator(generate_runtime_macro_context)  # type: ignore[arg-type]\n        adapter.set_macro_resolver(ctx.obj[\"manifest\"])\n        query_header_context = generate_query_header_context(adapter.config, ctx.obj[\"manifest\"])  # type: ignore[attr-defined]\n        adapter.connections.set_query_header(query_header_context)\n        for integration in active_integrations:\n            adapter.add_catalog_integration(integration)\n"
  },
  {
    "path": "core/dbt/cli/resolvers.py",
    "content": "from pathlib import Path\n\nfrom dbt.config.project import PartialProject\nfrom dbt.exceptions import DbtProjectError\n\n\ndef default_project_dir() -> Path:\n    paths = list(Path.cwd().parents)\n    paths.insert(0, Path.cwd())\n    return next((x for x in paths if (x / \"dbt_project.yml\").exists()), Path.cwd())\n\n\ndef default_profiles_dir() -> Path:\n    return Path.cwd() if (Path.cwd() / \"profiles.yml\").exists() else Path.home() / \".dbt\"\n\n\ndef default_log_path(project_dir: Path, verify_version: bool = False) -> Path:\n    \"\"\"If available, derive a default log path from dbt_project.yml. Otherwise, default to \"logs\".\n    Known limitations:\n    1. Using PartialProject here, so no jinja rendering of log-path.\n    2. Programmatic invocations of the cli via dbtRunner may pass a Project object directly,\n       which is not being taken into consideration here to extract a log-path.\n    \"\"\"\n    default_log_path = Path(\"logs\")\n    try:\n        partial = PartialProject.from_project_root(str(project_dir), verify_version=verify_version)\n        partial_log_path = partial.project_dict.get(\"log-path\") or default_log_path\n        default_log_path = Path(project_dir) / partial_log_path\n    except DbtProjectError:\n        pass\n\n    return default_log_path\n"
  },
  {
    "path": "core/dbt/cli/types.py",
    "content": "from enum import Enum\nfrom typing import List\n\nfrom dbt_common.exceptions import DbtInternalError\n\n\nclass Command(Enum):\n    BUILD = \"build\"\n    CLEAN = \"clean\"\n    COMPILE = \"compile\"\n    CLONE = \"clone\"\n    DOCS_GENERATE = \"generate\"\n    DOCS_SERVE = \"serve\"\n    DEBUG = \"debug\"\n    DEPS = \"deps\"\n    INIT = \"init\"\n    LIST = \"list\"\n    PARSE = \"parse\"\n    RUN = \"run\"\n    RUN_OPERATION = \"run-operation\"\n    SEED = \"seed\"\n    SHOW = \"show\"\n    SNAPSHOT = \"snapshot\"\n    SOURCE_FRESHNESS = \"freshness\"\n    TEST = \"test\"\n    RETRY = \"retry\"\n\n    @classmethod\n    def from_str(cls, s: str) -> \"Command\":\n        try:\n            return cls(s)\n        except ValueError:\n            raise DbtInternalError(f\"No value '{s}' exists in Command enum\")\n\n    def to_list(self) -> List[str]:\n        return {\n            Command.DOCS_GENERATE: [\"docs\", \"generate\"],\n            Command.DOCS_SERVE: [\"docs\", \"serve\"],\n            Command.SOURCE_FRESHNESS: [\"source\", \"freshness\"],\n        }.get(self, [self.value])\n"
  },
  {
    "path": "core/dbt/clients/README.md",
    "content": "# Clients README\n\n### Jinja\n\n#### How are materializations defined\n\nModel materializations are defined by adapters. See the [dbt-adapters](https://github.com/dbt-labs/dbt-adapters) project for [base implementations](https://github.com/dbt-labs/dbt-adapters/tree/main/dbt-adapters/src/dbt/include/global_project/macros/materializations/models). Materializations are defined using syntax that isn't part of the Jinja standard library. These tags are referenced internally, and materializations can be overridden in user projects when users have specific needs.\n\n```\n-- Pseudocode for arguments\n{% materialization <name>, <target name := one_of{default, adapter}> %}'\n…\n{% endmaterialization %}\n```\n\nThese blocks are referred to Jinja extensions. Extensions are defined as part of the accepted Jinja code encapsulated within a dbt project. This includes system code used internally by dbt and user space (i.e. user-defined) macros. Extensions exist to help Jinja users create reusable code blocks or abstract objects--for us, materializations are a great use-case since we pass these around as arguments within dbt system code.\n\nThe code that defines this extension is a class `MaterializationExtension` and a `parse` routine. That code lives in [clients/jinja.py](https://github.com/dbt-labs/dbt-core/blob/main/core/dbt/clients/jinja.py). The routine\nenables Jinja to parse (i.e. recognize) the unique comma separated arg structure our `materialization` tags exhibit (the `table, default` as seen above).\n"
  },
  {
    "path": "core/dbt/clients/__init__.py",
    "content": ""
  },
  {
    "path": "core/dbt/clients/checked_load.py",
    "content": "import collections\nimport dataclasses\nfrom typing import Any, Dict, List, Optional, Tuple\n\nimport yaml\n\nfrom dbt import deprecations\nfrom dbt.clients.yaml_helper import load_yaml_text\n\n# the C version is faster, but it doesn't always exist\ntry:\n    from yaml import CSafeLoader as SafeLoader\nexcept ImportError:\n    from yaml import SafeLoader  # type: ignore  # noqa: F401\n\n\n@dataclasses.dataclass\nclass YamlCheckFailure:\n    failure_type: str\n    message: str\n\n\ndef checked_load(contents) -> Tuple[Optional[Dict[str, Any]], List[YamlCheckFailure]]:\n    # A hacky (but sadly justified) method for modifying a bit of PyYAML. We create\n    # a new local subclass of SafeLoader, since we need to associate state with\n    # the static class, but static classes do not have non-static state. This allows\n    # us to be sure we have exclusive access to the class.\n    class CheckedLoader(SafeLoader):\n        check_failures: List[YamlCheckFailure] = []\n\n        def construct_mapping(self, node, deep=False):\n            if not isinstance(node, yaml.MappingNode):\n                raise yaml.constructor.ConstructorError(\n                    None, None, \"expected a mapping node, but found %s\" % node.id, node.start_mark\n                )\n            is_override = (\n                len(node.value) > 0\n                and len(node.value[0]) > 0\n                and getattr(node.value[0][0], \"value\") == \"<<\"\n            )\n            self.flatten_mapping(node)\n            mapping = {}\n            for key_node, value_node in node.value:\n                key = self.construct_object(key_node, deep=deep)\n                if not isinstance(key, collections.abc.Hashable):\n                    raise yaml.constructor.ConstructorError(\n                        \"while constructing a mapping\",\n                        node.start_mark,\n                        \"found unhashable key\",\n                        key_node.start_mark,\n                    )\n                value = self.construct_object(value_node, deep=deep)\n\n                if not is_override and key in mapping:\n                    start_mark = str(key_node.start_mark)\n                    if start_mark.startswith(\"  in\"):  # this means it was at the top level\n                        message = f\"Duplicate key '{key}' {start_mark.lstrip()}\"\n                    else:\n                        message = f\"Duplicate key '{key}' at {key_node.start_mark}\"\n\n                    self.check_failures.append(YamlCheckFailure(\"duplicate_key\", message))\n\n                mapping[key] = value\n            return mapping\n\n    CheckedLoader.add_constructor(\n        yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG, CheckedLoader.construct_mapping\n    )\n\n    dct = load_yaml_text(contents, loader=CheckedLoader)\n    check_failures = CheckedLoader.check_failures\n\n    return (dct, check_failures)\n\n\ndef issue_deprecation_warnings_for_failures(failures: List[YamlCheckFailure], file: str):\n    for failure in failures:\n        if failure.failure_type == \"duplicate_key\":\n            deprecations.warn(\n                \"duplicate-yaml-keys-deprecation\",\n                duplicate_description=failure.message,\n                file=file,\n            )\n"
  },
  {
    "path": "core/dbt/clients/git.py",
    "content": "import os.path\nimport re\n\nfrom packaging import version\n\nfrom dbt.events.types import (\n    GitNothingToDo,\n    GitProgressCheckedOutAt,\n    GitProgressCheckoutRevision,\n    GitProgressPullingNewDependency,\n    GitProgressUpdatedCheckoutRange,\n    GitProgressUpdatingExistingDependency,\n    GitSparseCheckoutSubdirectory,\n)\nfrom dbt.exceptions import (\n    CommandResultError,\n    DbtRuntimeError,\n    GitCheckoutError,\n    GitCloningError,\n    UnknownGitCloningProblemError,\n)\nfrom dbt_common.clients.system import rmdir, run_cmd\nfrom dbt_common.events.functions import fire_event\n\n\ndef _is_commit(revision: str) -> bool:\n    # match SHA-1 git commit\n    return bool(re.match(r\"\\b[0-9a-f]{40}\\b\", revision))\n\n\ndef clone(repo, cwd, dirname=None, remove_git_dir=False, revision=None, subdirectory=None):\n    has_revision = revision is not None\n    is_commit = _is_commit(revision or \"\")\n\n    clone_cmd = [\"git\", \"clone\", \"--depth\", \"1\"]\n    if subdirectory:\n        fire_event(GitSparseCheckoutSubdirectory(subdir=subdirectory))\n        out, _ = run_cmd(cwd, [\"git\", \"--version\"], env={\"LC_ALL\": \"C\"})\n        git_version = version.parse(re.search(r\"\\d+\\.\\d+\\.\\d+\", out.decode(\"utf-8\")).group(0))\n        if not git_version >= version.parse(\"2.25.0\"):\n            # 2.25.0 introduces --sparse\n            raise RuntimeError(\n                \"Please update your git version to pull a dbt package \"\n                \"from a subdirectory: your version is {}, >= 2.25.0 needed\".format(git_version)\n            )\n        clone_cmd.extend([\"--filter=blob:none\", \"--sparse\"])\n\n    if has_revision and not is_commit:\n        clone_cmd.extend([\"--branch\", revision])\n\n    clone_cmd.append(repo)\n\n    if dirname is not None:\n        clone_cmd.append(dirname)\n    try:\n        result = run_cmd(cwd, clone_cmd, env={\"LC_ALL\": \"C\"})\n    except CommandResultError as exc:\n        raise GitCloningError(repo, revision, exc)\n\n    if subdirectory:\n        cwd_subdir = os.path.join(cwd, dirname or \"\")\n        clone_cmd_subdir = [\"git\", \"sparse-checkout\", \"set\", subdirectory]\n        try:\n            run_cmd(cwd_subdir, clone_cmd_subdir)\n        except CommandResultError as exc:\n            raise GitCloningError(repo, revision, exc)\n\n    if remove_git_dir:\n        rmdir(os.path.join(dirname, \".git\"))\n\n    return result\n\n\ndef list_tags(cwd):\n    out, err = run_cmd(cwd, [\"git\", \"tag\", \"--list\"], env={\"LC_ALL\": \"C\"})\n    tags = out.decode(\"utf-8\").strip().split(\"\\n\")\n    return tags\n\n\ndef _checkout(cwd, repo, revision):\n    fire_event(GitProgressCheckoutRevision(revision=revision))\n\n    fetch_cmd = [\"git\", \"fetch\", \"origin\", \"--depth\", \"1\"]\n\n    if _is_commit(revision):\n        run_cmd(cwd, fetch_cmd + [revision])\n    else:\n        run_cmd(cwd, [\"git\", \"remote\", \"set-branches\", \"origin\", revision])\n        run_cmd(cwd, fetch_cmd + [\"--tags\", revision])\n\n    if _is_commit(revision):\n        spec = revision\n    # Prefer tags to branches if one exists\n    elif revision in list_tags(cwd):\n        spec = \"tags/{}\".format(revision)\n    else:\n        spec = \"origin/{}\".format(revision)\n\n    out, err = run_cmd(cwd, [\"git\", \"reset\", \"--hard\", spec], env={\"LC_ALL\": \"C\"})\n    return out, err\n\n\ndef checkout(cwd, repo, revision=None):\n    if revision is None:\n        revision = \"HEAD\"\n    try:\n        return _checkout(cwd, repo, revision)\n    except CommandResultError as exc:\n        raise GitCheckoutError(repo=repo, revision=revision, error=exc)\n\n\ndef get_current_sha(cwd):\n    out, err = run_cmd(cwd, [\"git\", \"rev-parse\", \"HEAD\"], env={\"LC_ALL\": \"C\"})\n\n    return out.decode(\"utf-8\").strip()\n\n\ndef remove_remote(cwd):\n    return run_cmd(cwd, [\"git\", \"remote\", \"rm\", \"origin\"], env={\"LC_ALL\": \"C\"})\n\n\ndef clone_and_checkout(\n    repo, cwd, dirname=None, remove_git_dir=False, revision=None, subdirectory=None\n):\n    exists = None\n    try:\n        _, err = clone(\n            repo,\n            cwd,\n            dirname=dirname,\n            remove_git_dir=remove_git_dir,\n            subdirectory=subdirectory,\n        )\n    except CommandResultError as exc:\n        err = exc.stderr\n        exists = re.match(\"fatal: destination path '(.+)' already exists\", err)\n        if not exists:\n            raise UnknownGitCloningProblemError(repo)\n\n    directory = None\n    start_sha = None\n    if exists:\n        directory = exists.group(1)\n        fire_event(GitProgressUpdatingExistingDependency(dir=directory))\n    else:\n        matches = re.match(\"Cloning into '(.+)'\", err.decode(\"utf-8\"))\n        if matches is None:\n            raise DbtRuntimeError(f'Error cloning {repo} - never saw \"Cloning into ...\" from git')\n        directory = matches.group(1)\n        fire_event(GitProgressPullingNewDependency(dir=directory))\n    full_path = os.path.join(cwd, directory)\n    start_sha = get_current_sha(full_path)\n    checkout(full_path, repo, revision)\n    end_sha = get_current_sha(full_path)\n    if exists:\n        if start_sha == end_sha:\n            fire_event(GitNothingToDo(sha=start_sha[:7]))\n        else:\n            fire_event(\n                GitProgressUpdatedCheckoutRange(start_sha=start_sha[:7], end_sha=end_sha[:7])\n            )\n    else:\n        fire_event(GitProgressCheckedOutAt(end_sha=end_sha[:7]))\n    return os.path.join(directory, subdirectory or \"\")\n"
  },
  {
    "path": "core/dbt/clients/jinja.py",
    "content": "import re\nimport threading\nfrom contextlib import contextmanager\nfrom typing import Any, Dict, List, NoReturn, Optional, Tuple, Union\n\nimport jinja2\nimport jinja2.ext\nimport jinja2.nativetypes  # type: ignore\nimport jinja2.nodes\nimport jinja2.parser\nimport jinja2.sandbox\n\nfrom dbt.contracts.graph.nodes import GenericTestNode\nfrom dbt.exceptions import (\n    DbtInternalError,\n    MaterializtionMacroNotUsedError,\n    NoSupportedLanguagesFoundError,\n)\nfrom dbt.node_types import ModelLanguage\nfrom dbt_common.clients.jinja import (\n    CallableMacroGenerator,\n    MacroProtocol,\n    get_template,\n    render_template,\n)\nfrom dbt_common.utils import deep_map_render\n\nSUPPORTED_LANG_ARG = jinja2.nodes.Name(\"supported_languages\", \"param\")\n\n\nclass MacroStack(threading.local):\n    def __init__(self):\n        super().__init__()\n        self.call_stack = []\n\n    @property\n    def depth(self) -> int:\n        return len(self.call_stack)\n\n    def push(self, name):\n        self.call_stack.append(name)\n\n    def pop(self, name):\n        got = self.call_stack.pop()\n        if got != name:\n            raise DbtInternalError(f\"popped {got}, expected {name}\")\n\n\nclass MacroGenerator(CallableMacroGenerator):\n    def __init__(\n        self,\n        macro: MacroProtocol,\n        context: Optional[Dict[str, Any]] = None,\n        node: Optional[Any] = None,\n        stack: Optional[MacroStack] = None,\n    ) -> None:\n        super().__init__(macro, context)\n        self.node = node\n        self.stack = stack\n\n    # This adds the macro's unique id to the node's 'depends_on'\n    @contextmanager\n    def track_call(self):\n        # This is only called from __call__\n        if self.stack is None:\n            yield\n        else:\n            unique_id = self.macro.unique_id\n            depth = self.stack.depth\n            # only mark depth=0 as a dependency, when creating this dependency we don't pass in stack\n            if depth == 0 and self.node:\n                self.node.depends_on.add_macro(unique_id)\n            self.stack.push(unique_id)\n            try:\n                yield\n            finally:\n                self.stack.pop(unique_id)\n\n    # this makes MacroGenerator objects callable like functions\n    def __call__(self, *args, **kwargs):\n        with self.track_call():\n            return self.call_macro(*args, **kwargs)\n\n\nclass UnitTestMacroGenerator(MacroGenerator):\n    # this makes UnitTestMacroGenerator objects callable like functions\n    def __init__(\n        self,\n        macro_generator: MacroGenerator,\n        call_return_value: Any,\n    ) -> None:\n        super().__init__(\n            macro_generator.macro,\n            macro_generator.context,\n            macro_generator.node,\n            macro_generator.stack,\n        )\n        self.call_return_value = call_return_value\n\n    def __call__(self, *args, **kwargs):\n        with self.track_call():\n            return self.call_return_value\n\n\n# performance note: Local benmcharking (so take it with a big grain of salt!)\n# on this indicates that it is is on average slightly slower than\n# checking two separate patterns, but the standard deviation is smaller with\n# one pattern. The time difference between the two was ~2 std deviations, which\n# is small enough that I've just chosen the more readable option.\n_HAS_RENDER_CHARS_PAT = re.compile(r\"({[{%#]|[#}%]})\")\n\n_render_cache: Dict[str, Any] = dict()\n\n\ndef get_rendered(\n    string: str,\n    ctx: Dict[str, Any],\n    node=None,\n    capture_macros: bool = False,\n    native: bool = False,\n) -> Any:\n    # performance optimization: if there are no jinja control characters in the\n    # string, we can just return the input. Fall back to jinja if the type is\n    # not a string or if native rendering is enabled (so '1' -> 1, etc...)\n    # If this is desirable in the native env as well, we could handle the\n    # native=True case by passing the input string to ast.literal_eval, like\n    # the native renderer does.\n    has_render_chars = not isinstance(string, str) or _HAS_RENDER_CHARS_PAT.search(string)\n\n    if not has_render_chars:\n        if not native:\n            return string\n        elif string in _render_cache:\n            return _render_cache[string]\n\n    template = get_template(\n        string,\n        ctx,\n        node,\n        capture_macros=capture_macros,\n        native=native,\n    )\n\n    rendered = render_template(template, ctx, node)\n\n    if not has_render_chars and native:\n        _render_cache[string] = rendered\n\n    return rendered\n\n\ndef undefined_error(msg) -> NoReturn:\n    raise jinja2.exceptions.UndefinedError(msg)\n\n\nGENERIC_TEST_KWARGS_NAME = \"_dbt_generic_test_kwargs\"\n\n\ndef add_rendered_test_kwargs(\n    context: Dict[str, Any],\n    node: GenericTestNode,\n    capture_macros: bool = False,\n) -> None:\n    \"\"\"Render each of the test kwargs in the given context using the native\n    renderer, then insert that value into the given context as the special test\n    keyword arguments member.\n    \"\"\"\n    looks_like_func = r\"^\\s*(env_var|ref|var|source|doc)\\s*\\(.+\\)\\s*$\"\n\n    def _convert_function(value: Any, keypath: Tuple[Union[str, int], ...]) -> Any:\n        if isinstance(value, str):\n            if keypath == (\"column_name\",):\n                # special case: Don't render column names as native, make them\n                # be strings\n                return value\n\n            if re.match(looks_like_func, value) is not None:\n                # curly braces to make rendering happy\n                value = f\"{{{{ {value} }}}}\"\n\n            value = get_rendered(value, context, node, capture_macros=capture_macros, native=True)\n\n        return value\n\n    # The test_metadata.kwargs come from the test builder, and were set\n    # when the test node was created in _parse_generic_test.\n    kwargs = deep_map_render(_convert_function, node.test_metadata.kwargs)\n    context[GENERIC_TEST_KWARGS_NAME] = kwargs\n\n\ndef get_supported_languages(node: jinja2.nodes.Macro) -> List[ModelLanguage]:\n    if \"materialization\" not in node.name:\n        raise MaterializtionMacroNotUsedError(node=node)\n\n    no_kwargs = not node.defaults\n    no_langs_found = SUPPORTED_LANG_ARG not in node.args\n\n    if no_kwargs or no_langs_found:\n        raise NoSupportedLanguagesFoundError(node=node)\n\n    lang_idx = node.args.index(SUPPORTED_LANG_ARG)\n    # indexing defaults from the end\n    # since supported_languages is a kwarg, and kwargs are at always after args\n    return [\n        ModelLanguage[item.value] for item in node.defaults[-(len(node.args) - lang_idx)].items\n    ]\n"
  },
  {
    "path": "core/dbt/clients/jinja_static.py",
    "content": "import typing\nfrom typing import Any, Dict, List, Optional, Union\n\nimport jinja2\n\nfrom dbt.artifacts.resources import RefArgs\nfrom dbt.exceptions import MacroNamespaceNotStringError, ParsingError\nfrom dbt_common.clients.jinja import get_environment\nfrom dbt_common.exceptions.macros import MacroNameNotStringError\nfrom dbt_common.tests import test_caching_enabled\nfrom dbt_extractor import ExtractionError, py_extract_from_source  # type: ignore\n\nif typing.TYPE_CHECKING:\n    from dbt.context.providers import ParseDatabaseWrapper\n\n\n_TESTING_MACRO_CACHE: Dict[str, Any] = {}\n\n\ndef statically_extract_has_name_this(source: str) -> bool:\n    \"\"\"Checks whether the raw jinja has any references to `this`\"\"\"\n    env = get_environment(None, capture_macros=True)\n    parsed = env.parse(source)\n    names = tuple(parsed.find_all(jinja2.nodes.Name))\n\n    for name in names:\n        if hasattr(name, \"name\") and name.name == \"this\":\n            return True\n    return False\n\n\ndef statically_extract_macro_calls(\n    source: str, ctx: Dict[str, Any], db_wrapper: Optional[\"ParseDatabaseWrapper\"] = None\n) -> List[str]:\n    # set 'capture_macros' to capture undefined\n    env = get_environment(None, capture_macros=True)\n\n    global _TESTING_MACRO_CACHE\n    if test_caching_enabled() and source in _TESTING_MACRO_CACHE:\n        parsed = _TESTING_MACRO_CACHE.get(source, None)\n        func_calls = getattr(parsed, \"_dbt_cached_calls\")\n    else:\n        parsed = env.parse(source)\n        func_calls = tuple(parsed.find_all(jinja2.nodes.Call))\n\n        if test_caching_enabled():\n            _TESTING_MACRO_CACHE[source] = parsed\n            setattr(parsed, \"_dbt_cached_calls\", func_calls)\n\n    standard_calls = [\"source\", \"ref\", \"config\"]\n    possible_macro_calls = []\n    for func_call in func_calls:\n        func_name = None\n        if hasattr(func_call, \"node\") and hasattr(func_call.node, \"name\"):\n            func_name = func_call.node.name\n        else:\n            if (\n                hasattr(func_call, \"node\")\n                and hasattr(func_call.node, \"node\")\n                and type(func_call.node.node).__name__ == \"Name\"\n                and hasattr(func_call.node, \"attr\")\n            ):\n                package_name = func_call.node.node.name\n                macro_name = func_call.node.attr\n                if package_name == \"adapter\":\n                    if macro_name == \"dispatch\":\n                        ad_macro_calls = statically_parse_adapter_dispatch(\n                            func_call, ctx, db_wrapper\n                        )\n                        possible_macro_calls.extend(ad_macro_calls)\n                    else:\n                        # This skips calls such as adapter.parse_index\n                        continue\n                else:\n                    func_name = f\"{package_name}.{macro_name}\"\n            else:\n                continue\n        if not func_name:\n            continue\n        if func_name in standard_calls:\n            continue\n        elif ctx.get(func_name):\n            continue\n        else:\n            if func_name not in possible_macro_calls:\n                possible_macro_calls.append(func_name)\n\n    return possible_macro_calls\n\n\ndef statically_parse_adapter_dispatch(\n    func_call, ctx: Dict[str, Any], db_wrapper: Optional[\"ParseDatabaseWrapper\"]\n) -> List[str]:\n    possible_macro_calls = []\n    # This captures an adapter.dispatch('<macro_name>') call.\n\n    func_name = None\n    # macro_name positional argument\n    if len(func_call.args) > 0:\n        func_name = func_call.args[0].value\n    if func_name:\n        possible_macro_calls.append(func_name)\n\n    # packages positional argument\n    macro_namespace = None\n    packages_arg = None\n    packages_arg_type = None\n\n    if len(func_call.args) > 1:\n        packages_arg = func_call.args[1]\n        # This can be a List or a Call\n        packages_arg_type = type(func_call.args[1]).__name__\n\n    # keyword arguments\n    if func_call.kwargs:\n        for kwarg in func_call.kwargs:\n            if kwarg.key == \"macro_name\":\n                # This will remain to enable static resolution\n                if type(kwarg.value).__name__ == \"Const\":\n                    func_name = kwarg.value.value\n                    possible_macro_calls.append(func_name)\n                else:\n                    raise MacroNameNotStringError(kwarg_value=kwarg.value.value)\n            elif kwarg.key == \"macro_namespace\":\n                # This will remain to enable static resolution\n                kwarg_type = type(kwarg.value).__name__\n                if kwarg_type == \"Const\":\n                    macro_namespace = kwarg.value.value\n                else:\n                    raise MacroNamespaceNotStringError(kwarg_type)\n\n    # positional arguments\n    if packages_arg:\n        if packages_arg_type == \"List\":\n            # This will remain to enable static resolution\n            packages = []\n            for item in packages_arg.items:\n                packages.append(item.value)\n        elif packages_arg_type == \"Const\":\n            # This will remain to enable static resolution\n            macro_namespace = packages_arg.value\n\n    if db_wrapper:\n        macro = db_wrapper.dispatch(func_name, macro_namespace=macro_namespace).macro\n        func_name = f\"{macro.package_name}.{macro.name}\"  # type: ignore[attr-defined]\n        possible_macro_calls.append(func_name)\n    else:  # this is only for tests/unit/test_macro_calls.py\n        if macro_namespace:\n            packages = [macro_namespace]\n        else:\n            packages = []\n        for package_name in packages:\n            possible_macro_calls.append(f\"{package_name}.{func_name}\")\n\n    return possible_macro_calls\n\n\ndef statically_parse_ref_or_source(expression: str) -> Union[RefArgs, List[str]]:\n    \"\"\"\n    Returns a RefArgs or List[str] object, corresponding to ref or source respectively, given an input jinja expression.\n\n    input: str representing how input node is referenced in tested model sql\n        * examples:\n        - \"ref('my_model_a')\"\n        - \"ref('my_model_a', version=3)\"\n        - \"ref('package', 'my_model_a', version=3)\"\n        - \"source('my_source_schema', 'my_source_name')\"\n\n    If input is not a well-formed jinja ref or source expression, a ParsingError is raised.\n    \"\"\"\n    ref_or_source: Union[RefArgs, List[str]]\n\n    try:\n        statically_parsed = py_extract_from_source(f\"{{{{ {expression} }}}}\")\n    except ExtractionError:\n        raise ParsingError(f\"Invalid jinja expression: {expression}\")\n\n    if statically_parsed.get(\"refs\"):\n        raw_ref = list(statically_parsed[\"refs\"])[0]\n        ref_or_source = RefArgs(\n            package=raw_ref.get(\"package\"),\n            name=raw_ref.get(\"name\"),\n            version=raw_ref.get(\"version\"),\n        )\n    elif statically_parsed.get(\"sources\"):\n        source_name, source_table_name = list(statically_parsed[\"sources\"])[0]\n        ref_or_source = [source_name, source_table_name]\n    else:\n        raise ParsingError(f\"Invalid ref or source expression: {expression}\")\n\n    return ref_or_source\n\n\ndef statically_parse_unrendered_config(string: str) -> Optional[Dict[str, Any]]:\n    \"\"\"\n    Given a string with jinja, extract an unrendered config call.\n    If no config call is present, returns None.\n\n    For example, given:\n    \"{{ config(materialized=env_var('DBT_TEST_STATE_MODIFIED')) }}\\nselect 1 as id\"\n    returns: {'materialized': \"Keyword(key='materialized', value=Call(node=Name(name='env_var', ctx='load'), args=[Const(value='DBT_TEST_STATE_MODIFIED')], kwargs=[], dyn_args=None, dyn_kwargs=None))\"}\n\n    No config call:\n    \"select 1 as id\"\n    returns: None\n    \"\"\"\n    # Return early to avoid creating jinja environemt if no config call in input string\n    if \"config(\" not in string:\n        return None\n\n    # set 'capture_macros' to capture undefined\n    env = get_environment(None, capture_macros=True)\n\n    global _TESTING_MACRO_CACHE\n    if test_caching_enabled() and _TESTING_MACRO_CACHE and string in _TESTING_MACRO_CACHE:\n        parsed = _TESTING_MACRO_CACHE.get(string, None)\n        func_calls = getattr(parsed, \"_dbt_cached_calls\")\n    else:\n        parsed = env.parse(string)\n        func_calls = tuple(parsed.find_all(jinja2.nodes.Call))\n\n    config_func_calls = list(\n        filter(\n            lambda f: hasattr(f, \"node\") and hasattr(f.node, \"name\") and f.node.name == \"config\",\n            func_calls,\n        )\n    )\n    # There should only be one {{ config(...) }} call per input\n    config_func_call = config_func_calls[0] if config_func_calls else None\n\n    if not config_func_call:\n        return None\n\n    unrendered_config = {}\n    for kwarg in config_func_call.kwargs:\n        unrendered_config[kwarg.key] = construct_static_kwarg_value(kwarg)\n\n    return unrendered_config\n\n\ndef construct_static_kwarg_value(kwarg) -> str:\n    # Instead of trying to re-assemble complex kwarg value, simply stringify the value.\n    # This is still useful to be able to detect changes in unrendered configs, even if it is\n    # not an exact representation of the user input.\n    return str(kwarg)\n"
  },
  {
    "path": "core/dbt/clients/registry.py",
    "content": "import functools\nimport os\nfrom typing import Any, Dict, List, Optional\n\nimport requests\n\nfrom dbt import deprecations\nfrom dbt.events.types import (\n    RegistryIndexProgressGETRequest,\n    RegistryIndexProgressGETResponse,\n    RegistryProgressGETRequest,\n    RegistryProgressGETResponse,\n    RegistryResponseExtraNestedKeys,\n    RegistryResponseMissingNestedKeys,\n    RegistryResponseMissingTopKeys,\n    RegistryResponseUnexpectedType,\n)\nfrom dbt.utils import memoized\nfrom dbt_common import semver\nfrom dbt_common.events.functions import fire_event\nfrom dbt_common.utils.connection import connection_exception_retry\n\nif os.getenv(\"DBT_PACKAGE_HUB_URL\"):\n    DEFAULT_REGISTRY_BASE_URL = os.getenv(\"DBT_PACKAGE_HUB_URL\")\nelse:\n    DEFAULT_REGISTRY_BASE_URL = \"https://hub.getdbt.com/\"\n\n\ndef _get_url(name, registry_base_url=None):\n    if registry_base_url is None:\n        registry_base_url = DEFAULT_REGISTRY_BASE_URL\n    url = \"api/v1/{}.json\".format(name)\n\n    return \"{}{}\".format(registry_base_url, url)\n\n\ndef _check_package_redirect(package_name: str, response: Dict[str, Any]) -> None:\n    # Either redirectnamespace or redirectname in the JSON response indicate a redirect\n    # redirectnamespace redirects based on package ownership\n    # redirectname redirects based on package name\n    # Both can be present at the same time, or neither. Fails gracefully to old name\n    if (\"redirectnamespace\" in response) or (\"redirectname\" in response):\n        use_namespace = response.get(\"redirectnamespace\") or response[\"namespace\"]\n        use_name = response.get(\"redirectname\") or response[\"name\"]\n\n        new_nwo = f\"{use_namespace}/{use_name}\"\n        deprecations.warn(\"package-redirect\", old_name=package_name, new_name=new_nwo)\n\n\ndef _get_package_with_retries(\n    package_name: str, registry_base_url: Optional[str] = None\n) -> Dict[str, Any]:\n    get_fn = functools.partial(_get, package_name, registry_base_url)\n    response: Dict[str, Any] = connection_exception_retry(get_fn, 5)\n    _check_package_redirect(package_name, response)\n    return response\n\n\ndef _get(package_name, registry_base_url=None):\n    url = _get_url(package_name, registry_base_url)\n    fire_event(RegistryProgressGETRequest(url=url))\n    # all exceptions from requests get caught in the retry logic so no need to wrap this here\n    resp = requests.get(url, timeout=30)\n    fire_event(RegistryProgressGETResponse(url=url, resp_code=resp.status_code))\n    resp.raise_for_status()\n\n    # The response should always be a dictionary.  Anything else is unexpected, raise error.\n    # Raising this error will cause this function to retry (if called within _get_package_with_retries)\n    # and hopefully get a valid response.  This seems to happen when there's an issue with the Hub.\n    # Since we control what we expect the HUB to return, this is safe.\n    # See https://github.com/dbt-labs/dbt-core/issues/4577\n    # and https://github.com/dbt-labs/dbt-core/issues/4849\n    response = resp.json()\n\n    if not isinstance(response, dict):  # This will also catch Nonetype\n        error_msg = (\n            f\"Request error: Expected a response type of <dict> but got {type(response)} instead\"\n        )\n        fire_event(RegistryResponseUnexpectedType(response=response))\n        raise requests.exceptions.ContentDecodingError(error_msg, response=resp)\n\n    # check for expected top level keys\n    expected_keys = {\"name\", \"versions\"}\n    if not expected_keys.issubset(response):\n        error_msg = (\n            f\"Request error: Expected the response to contain keys {expected_keys} \"\n            f\"but is missing {expected_keys.difference(set(response))}\"\n        )\n        fire_event(RegistryResponseMissingTopKeys(response=response))\n        raise requests.exceptions.ContentDecodingError(error_msg, response=resp)\n\n    # check for the keys we need nested under each version\n    expected_version_keys = {\"name\", \"packages\", \"downloads\"}\n    all_keys = set().union(*(response[\"versions\"][d] for d in response[\"versions\"]))\n    if not expected_version_keys.issubset(all_keys):\n        error_msg = (\n            \"Request error: Expected the response for the version to contain keys \"\n            f\"{expected_version_keys} but is missing {expected_version_keys.difference(all_keys)}\"\n        )\n        fire_event(RegistryResponseMissingNestedKeys(response=response))\n        raise requests.exceptions.ContentDecodingError(error_msg, response=resp)\n\n    # all version responses should contain identical keys.\n    has_extra_keys = set().difference(*(response[\"versions\"][d] for d in response[\"versions\"]))\n    if has_extra_keys:\n        error_msg = (\n            \"Request error: Keys for all versions do not match.  Found extra key(s) \"\n            f\"of {has_extra_keys}.\"\n        )\n        fire_event(RegistryResponseExtraNestedKeys(response=response))\n        raise requests.exceptions.ContentDecodingError(error_msg, response=resp)\n\n    return response\n\n\n_get_cached = memoized(_get_package_with_retries)\n\n\ndef package(package_name, registry_base_url=None) -> Dict[str, Any]:\n    # returns a dictionary of metadata for all versions of a package\n    response = _get_cached(package_name, registry_base_url)\n    return response[\"versions\"]\n\n\ndef package_version(package_name, version, registry_base_url=None) -> Dict[str, Any]:\n    # returns the metadata of a specific version of a package\n    response = package(package_name, registry_base_url)\n    return response[version]\n\n\ndef is_compatible_version(package_spec, dbt_version) -> bool:\n    require_dbt_version = package_spec.get(\"require_dbt_version\")\n    if not require_dbt_version:\n        # if version requirements are missing or empty, assume any version is compatible\n        return True\n    else:\n        # determine whether dbt_version satisfies this package's require-dbt-version config\n        if not isinstance(require_dbt_version, list):\n            require_dbt_version = [require_dbt_version]\n        supported_versions = [\n            semver.VersionSpecifier.from_version_string(v) for v in require_dbt_version\n        ]\n        return semver.versions_compatible(dbt_version, *supported_versions)\n\n\ndef get_compatible_versions(package_name, dbt_version, should_version_check) -> List[\"str\"]:\n    # returns a list of all available versions of a package\n    response = package(package_name)\n\n    # if the user doesn't care about installing compatible versions, just return them all\n    if not should_version_check:\n        return list(response)\n\n    # otherwise, only return versions that are compatible with the installed version of dbt-core\n    else:\n        compatible_versions = [\n            pkg_version\n            for pkg_version, info in response.items()\n            if is_compatible_version(info, dbt_version)\n        ]\n        return compatible_versions\n\n\ndef _get_index(registry_base_url=None):\n    url = _get_url(\"index\", registry_base_url)\n    fire_event(RegistryIndexProgressGETRequest(url=url))\n    # all exceptions from requests get caught in the retry logic so no need to wrap this here\n    resp = requests.get(url, timeout=30)\n    fire_event(RegistryIndexProgressGETResponse(url=url, resp_code=resp.status_code))\n    resp.raise_for_status()\n\n    # The response should be a list.  Anything else is unexpected, raise an error.\n    # Raising this error will cause this function to retry and hopefully get a valid response.\n\n    response = resp.json()\n\n    if not isinstance(response, list):  # This will also catch Nonetype\n        error_msg = (\n            f\"Request error: The response type of {type(response)} is not valid: {resp.text}\"\n        )\n        raise requests.exceptions.ContentDecodingError(error_msg, response=resp)\n\n    return response\n\n\ndef index(registry_base_url=None) -> List[str]:\n    # this returns a list of all packages on the Hub\n    get_index_fn = functools.partial(_get_index, registry_base_url)\n    return connection_exception_retry(get_index_fn, 5)\n\n\nindex_cached = memoized(index)\n"
  },
  {
    "path": "core/dbt/clients/yaml_helper.py",
    "content": "from typing import Any, Dict, Optional\n\nimport yaml\n\nimport dbt_common.exceptions\nimport dbt_common.exceptions.base\n\n# the C version is faster, but it doesn't always exist\ntry:\n    from yaml import CDumper as Dumper\n    from yaml import CLoader as Loader\n    from yaml import CSafeLoader as SafeLoader\nexcept ImportError:\n    from yaml import Dumper, Loader, SafeLoader  # type: ignore  # noqa: F401\n\n\nYAML_ERROR_MESSAGE = \"\"\"\nSyntax error near line {line_number}\n------------------------------\n{nice_error}\n\nRaw Error:\n------------------------------\n{raw_error}\n\"\"\".strip()\n\n\ndef line_no(i, line, width=3):\n    line_number = str(i).ljust(width)\n    return \"{}| {}\".format(line_number, line)\n\n\ndef prefix_with_line_numbers(string, no_start, no_end):\n    line_list = string.split(\"\\n\")\n\n    numbers = range(no_start, no_end)\n    relevant_lines = line_list[no_start:no_end]\n\n    return \"\\n\".join([line_no(i + 1, line) for (i, line) in zip(numbers, relevant_lines)])\n\n\ndef contextualized_yaml_error(raw_contents, error):\n    mark = error.problem_mark\n\n    min_line = max(mark.line - 3, 0)\n    max_line = mark.line + 4\n\n    nice_error = prefix_with_line_numbers(raw_contents, min_line, max_line)\n\n    return YAML_ERROR_MESSAGE.format(\n        line_number=mark.line + 1, nice_error=nice_error, raw_error=error\n    )\n\n\ndef safe_load(contents) -> Optional[Dict[str, Any]]:\n    return yaml.load(contents, Loader=SafeLoader)\n\n\ndef load_yaml_text(contents, path=None, loader=SafeLoader) -> Optional[Dict[str, Any]]:\n    try:\n        return yaml.load(contents, loader)\n    except (yaml.scanner.ScannerError, yaml.YAMLError) as e:\n        if hasattr(e, \"problem_mark\"):\n            error = contextualized_yaml_error(contents, e)\n        else:\n            error = str(e)\n\n        raise dbt_common.exceptions.base.DbtValidationError(error)\n"
  },
  {
    "path": "core/dbt/compilation.py",
    "content": "import dataclasses\nimport json\nimport os\nimport pickle\nfrom collections import defaultdict, deque\nfrom typing import Any, Dict, Iterable, List, Optional, Set, Tuple\n\nimport networkx as nx  # type: ignore\nimport sqlparse\n\nimport dbt.tracking\nfrom dbt.adapters.factory import get_adapter\nfrom dbt.clients import jinja\nfrom dbt.context.providers import (\n    generate_runtime_model_context,\n    generate_runtime_unit_test_context,\n)\nfrom dbt.contracts.graph.manifest import Manifest, UniqueID\nfrom dbt.contracts.graph.nodes import (\n    GenericTestNode,\n    GraphMemberNode,\n    InjectedCTE,\n    ManifestNode,\n    ManifestSQLNode,\n    ModelNode,\n    SeedNode,\n    UnitTestDefinition,\n    UnitTestNode,\n    UnitTestSourceDefinition,\n)\nfrom dbt.events.types import FoundStats, WritingInjectedSQLForNode\nfrom dbt.exceptions import (\n    DbtInternalError,\n    DbtRuntimeError,\n    ForeignKeyConstraintToSyntaxError,\n    GraphDependencyNotFoundError,\n    ParsingError,\n)\nfrom dbt.flags import get_flags\nfrom dbt.graph import Graph\nfrom dbt.node_types import ModelLanguage, NodeType\nfrom dbt_common.clients.system import make_directory\nfrom dbt_common.contracts.constraints import ConstraintType\nfrom dbt_common.events.contextvars import get_node_info\nfrom dbt_common.events.format import pluralize\nfrom dbt_common.events.functions import fire_event\nfrom dbt_common.events.types import Note\nfrom dbt_common.exceptions import CompilationError\nfrom dbt_common.invocation import get_invocation_id\n\ngraph_file_name = \"graph.gpickle\"\n\n\ndef print_compile_stats(stats: Dict[NodeType, int]):\n    # create tracking event for resource_counts\n    if dbt.tracking.active_user is not None:\n        resource_counts = {k.pluralize(): v for k, v in stats.items()}\n        dbt.tracking.track_resource_counts(resource_counts)\n\n    # do not include resource types that are not actually defined in the project\n    stat_line = \", \".join(\n        [pluralize(ct, t).replace(\"_\", \" \") for t, ct in stats.items() if ct != 0]\n    )\n    fire_event(FoundStats(stat_line=stat_line))\n\n\ndef _node_enabled(node: ManifestNode):\n    # Disabled models are already excluded from the manifest\n    if node.resource_type == NodeType.Test and not node.config.enabled:\n        return False\n    else:\n        return True\n\n\ndef _generate_stats(manifest: Manifest) -> Dict[NodeType, int]:\n    stats: Dict[NodeType, int] = defaultdict(int)\n    for node in manifest.nodes.values():\n        if _node_enabled(node):\n            stats[node.resource_type] += 1\n\n    # Disabled nodes don't appear in the following collections, so we don't check.\n    stats[NodeType.Source] += len(manifest.sources)\n    stats[NodeType.Exposure] += len(manifest.exposures)\n    stats[NodeType.Metric] += len(manifest.metrics)\n    stats[NodeType.Macro] += len(manifest.macros)\n    stats[NodeType.Group] += len(manifest.groups)\n    stats[NodeType.SemanticModel] += len(manifest.semantic_models)\n    stats[NodeType.SavedQuery] += len(manifest.saved_queries)\n    stats[NodeType.Unit] += len(manifest.unit_tests)\n\n    # TODO: should we be counting dimensions + entities?\n\n    return stats\n\n\ndef _add_prepended_cte(prepended_ctes, new_cte):\n    for cte in prepended_ctes:\n        if cte.id == new_cte.id and new_cte.sql:\n            cte.sql = new_cte.sql\n            return\n    if new_cte.sql:\n        prepended_ctes.append(new_cte)\n\n\ndef _extend_prepended_ctes(prepended_ctes, new_prepended_ctes):\n    for new_cte in new_prepended_ctes:\n        _add_prepended_cte(prepended_ctes, new_cte)\n\n\ndef _get_tests_for_node(manifest: Manifest, unique_id: UniqueID) -> List[UniqueID]:\n    \"\"\"Get a list of tests that depend on the node with the\n    provided unique id\"\"\"\n\n    tests = []\n    if unique_id in manifest.child_map:\n        for child_unique_id in manifest.child_map[unique_id]:\n            if child_unique_id.startswith(\"test.\"):\n                tests.append(child_unique_id)\n\n    return tests\n\n\n@dataclasses.dataclass\nclass SeenDetails:\n    node_id: UniqueID\n    visits: int = 0\n    ancestors: Set[UniqueID] = dataclasses.field(default_factory=set)\n    awaits_tests: Set[Tuple[UniqueID, Tuple[UniqueID, ...]]] = dataclasses.field(\n        default_factory=set\n    )\n\n\nclass Linker:\n    def __init__(self, data=None) -> None:\n        if data is None:\n            data = {}\n        self.graph: nx.DiGraph = nx.DiGraph(**data)\n\n    def edges(self):\n        return self.graph.edges()\n\n    def nodes(self):\n        return self.graph.nodes()\n\n    def find_cycles(self):\n        try:\n            cycle = nx.find_cycle(self.graph)\n        except nx.NetworkXNoCycle:\n            return None\n        else:\n            # cycles is a List[Tuple[str, ...]]\n            return \" --> \".join(c[0] for c in cycle)\n\n    def dependency(self, node1, node2):\n        \"indicate that node1 depends on node2\"\n        self.graph.add_node(node1)\n        self.graph.add_node(node2)\n        self.graph.add_edge(node2, node1)\n\n    def add_node(self, node):\n        self.graph.add_node(node)\n\n    def write_graph(self, outfile: str, manifest: Manifest):\n        \"\"\"Write the graph to a gpickle file. Before doing so, serialize and\n        include all nodes in their corresponding graph entries.\n        \"\"\"\n        out_graph = self.graph.copy()\n        for node_id in self.graph:\n            data = manifest.expect(node_id).to_dict(omit_none=True)\n            out_graph.add_node(node_id, **data)\n        with open(outfile, \"wb\") as outfh:\n            pickle.dump(out_graph, outfh, protocol=pickle.HIGHEST_PROTOCOL)\n\n    def link_node(self, node: GraphMemberNode, manifest: Manifest):\n        self.add_node(node.unique_id)\n\n        for dependency in node.depends_on_nodes:\n            if dependency in manifest.nodes:\n                self.dependency(node.unique_id, (manifest.nodes[dependency].unique_id))\n            elif dependency in manifest.sources:\n                self.dependency(node.unique_id, (manifest.sources[dependency].unique_id))\n            elif dependency in manifest.metrics:\n                self.dependency(node.unique_id, (manifest.metrics[dependency].unique_id))\n            elif dependency in manifest.semantic_models:\n                self.dependency(node.unique_id, (manifest.semantic_models[dependency].unique_id))\n            elif dependency in manifest.functions:\n                self.dependency(node.unique_id, (manifest.functions[dependency].unique_id))\n            else:\n                raise GraphDependencyNotFoundError(node, dependency)\n\n    def link_graph(self, manifest: Manifest):\n        for source in manifest.sources.values():\n            self.add_node(source.unique_id)\n        for node in manifest.nodes.values():\n            self.link_node(node, manifest)\n        for semantic_model in manifest.semantic_models.values():\n            self.link_node(semantic_model, manifest)\n        for exposure in manifest.exposures.values():\n            self.link_node(exposure, manifest)\n        for function in manifest.functions.values():\n            self.link_node(function, manifest)\n        for metric in manifest.metrics.values():\n            self.link_node(metric, manifest)\n        for unit_test in manifest.unit_tests.values():\n            self.link_node(unit_test, manifest)\n        for saved_query in manifest.saved_queries.values():\n            self.link_node(saved_query, manifest)\n\n        cycle = self.find_cycles()\n\n        if cycle:\n            raise RuntimeError(\"Found a cycle: {}\".format(cycle))\n\n    def add_test_edges(self, manifest: Manifest) -> None:\n        if not get_flags().USE_FAST_TEST_EDGES:\n            self.add_test_edges_1(manifest)\n        else:\n            self.add_test_edges_2(manifest)\n\n    def add_test_edges_1(self, manifest: Manifest) -> None:\n        \"\"\"This method adds additional edges to the DAG. For a given non-test\n        executable node, add an edge from an upstream test to the given node if\n        the set of nodes the test depends on is a subset of the upstream nodes\n        for the given node.\"\"\"\n\n        # HISTORICAL NOTE: To understand the motivation behind this function,\n        # consider a node A with tests and a node B which depends (either directly\n        # or indirectly) on A. It would be nice if B were not executed until\n        # all of the tests on A are finished. After all, we don't want to\n        # propagate bad data. We can enforce that behavior by adding new\n        # dependencies (edges) from tests to nodes that should wait on them.\n        #\n        # This function implements a rough approximation of the behavior just\n        # described. In fact, for tests that only depend on a single node, it\n        # always works.\n        #\n        # Things get trickier for tests that depend on multiple nodes. In that\n        # case, if we are not careful, we will introduce cycles. That seems to\n        # be the reason this function adds dependencies from a downstream node to\n        # an upstream test if and only if the downstream node is already a\n        # descendant of all the nodes the upstream test depends on. By following\n        # that rule, it never makes the node dependent on new upstream nodes other\n        # than the tests themselves, and no cycles will be created.\n        #\n        # One drawback (Drawback 1) of the approach taken in this function is\n        # that it could still allow a downstream node to proceed before all\n        # testing is done on its ancestors, if it happens to have ancestors that\n        # are not also ancestors of a test with multiple dependencies.\n        #\n        # Another drawback (Drawback 2) is that the approach below adds far more\n        # edges than are strictly needed. After all, if we have A -> B -> C,\n        # there is no need to add a new edge A -> C. But this function often does.\n        #\n        # Drawback 2 is resolved in the new add_test_edges_2() implementation\n        # below, which is also typically much faster. Drawback 1 has been left in\n        # place in order to conservatively retain existing behavior, and so that\n        # the new implementation can be verified against this existing\n        # implementation by ensuring both resulting graphs have the same transitive\n        # reduction.\n\n        # MOTIVATING IDEA: Given a graph...\n        #\n        # model1 --> model2 --> model3\n        #   |             |\n        #   |            \\/\n        #  \\/          test 2\n        # test1\n        #\n        # ...produce the following...\n        #\n        # model1 --> model2 --> model3\n        #   |       /\\    |      /\\ /\\\n        #   |       |    \\/      |  |\n        #  \\/       |  test2 ----|  |\n        # test1 ----|---------------|\n\n        for node_id in self.graph:\n            # If node is executable (in manifest.nodes) and does _not_\n            # represent a test, continue.\n            if (\n                node_id in manifest.nodes\n                and manifest.nodes[node_id].resource_type != NodeType.Test\n            ):\n                # Get *everything* upstream of the node\n                all_upstream_nodes = nx.traversal.bfs_tree(self.graph, node_id, reverse=True)\n                # Get the set of upstream nodes not including the current node.\n                upstream_nodes = set([n for n in all_upstream_nodes if n != node_id])\n\n                # Get all tests that depend on any upstream nodes.\n                upstream_tests = []\n                for upstream_node in upstream_nodes:\n                    # This gets tests with unique_ids starting with \"test.\"\n                    upstream_tests += _get_tests_for_node(manifest, upstream_node)\n\n                for upstream_test in upstream_tests:\n                    # Get the set of all nodes that the test depends on\n                    # including the upstream_node itself. This is necessary\n                    # because tests can depend on multiple nodes (ex:\n                    # relationship tests). Test nodes do not distinguish\n                    # between what node the test is \"testing\" and what\n                    # node(s) it depends on.\n                    test_depends_on = set(manifest.nodes[upstream_test].depends_on_nodes)\n\n                    # If the set of nodes that an upstream test depends on\n                    # is a subset of all upstream nodes of the current node,\n                    # add an edge from the upstream test to the current node.\n                    if test_depends_on.issubset(upstream_nodes):\n                        self.graph.add_edge(upstream_test, node_id, edge_type=\"parent_test\")\n\n    def add_test_edges_2(self, manifest: Manifest):\n        graph = self.graph\n        new_edges = self._get_test_edges_2(graph, manifest)\n        for e in new_edges:\n            graph.add_edge(e[0], e[1], edge_type=\"parent_test\")\n\n    @staticmethod\n    def _get_test_edges_2(\n        graph: nx.DiGraph, manifest: Manifest\n    ) -> Iterable[Tuple[UniqueID, UniqueID]]:\n        # This function enforces the same execution behavior as add_test_edges,\n        # but executes far more quickly and adds far fewer edges. See the\n        # HISTORICAL NOTE above.\n        #\n        # The idea is to first scan for \"single-tested\" nodes (which have tests\n        # that depend only upon on that node) and \"multi-tested\" nodes (which\n        # have tests that depend on multiple nodes). Single-tested nodes are\n        # handled quickly and easily.\n        #\n        # The less common but more complex case of multi-tested nodes is handled\n        # by a specialized function.\n\n        new_edges: List[Tuple[UniqueID, UniqueID]] = []\n\n        source_nodes: List[UniqueID] = []\n        executable_nodes: Set[UniqueID] = set()\n        multi_tested_nodes = set()\n        # Dictionary mapping nodes with single-dep tests to a list of those tests.\n        single_tested_nodes: dict[UniqueID, List[UniqueID]] = defaultdict(list)\n        for node_id in graph.nodes:\n            manifest_node = manifest.nodes.get(node_id, None)\n            if manifest_node is None:\n                continue\n\n            if next(graph.predecessors(node_id), None) is None:\n                source_nodes.append(node_id)\n\n            if manifest_node.resource_type != NodeType.Test:\n                executable_nodes.add(node_id)\n            else:\n                test_deps = manifest_node.depends_on_nodes\n                if len(test_deps) == 1:\n                    single_tested_nodes[test_deps[0]].append(node_id)\n                elif len(test_deps) > 1:\n                    multi_tested_nodes.update(manifest_node.depends_on_nodes)\n\n        # Now that we have all the necessary information conveniently organized,\n        # add new edges for single-tested nodes.\n        for node_id, test_ids in single_tested_nodes.items():\n            succs = [s for s in graph.successors(node_id) if s in executable_nodes]\n            for succ_id in succs:\n                for test_id in test_ids:\n                    new_edges.append((test_id, succ_id))\n\n        # Get the edges for multi-tested nodes separately, if needed.\n        if len(multi_tested_nodes) > 0:\n            multi_test_edges = Linker._get_multi_test_edges(\n                graph, manifest, source_nodes, executable_nodes, multi_tested_nodes\n            )\n            new_edges += multi_test_edges\n\n        return new_edges\n\n    @staticmethod\n    def _get_multi_test_edges(\n        graph: nx.DiGraph,\n        manifest: Manifest,\n        source_nodes: Iterable[UniqueID],\n        executable_nodes: Set[UniqueID],\n        multi_tested_nodes,\n    ) -> List[Tuple[UniqueID, UniqueID]]:\n        # Works through the graph in a breadth-first style, processing nodes from\n        # a ready queue which initially consists of nodes with no ancestors,\n        # and adding more nodes to the ready queue after all their ancestors\n        # have been processed. All the while, the relevant details of all nodes\n        # \"seen\" by the search so far are maintained in a SeenDetails record,\n        # including the ancestor set which tests it is \"awaiting\" (i.e. tests of\n        # its ancestors). The processing step adds test edges when every dependency\n        # of an awaited test is an ancestor of a node that is being processed.\n        # Downstream nodes are then exempted from awaiting the test.\n        #\n        # Memory consumption is potentially O(n^2) with n the number of nodes in\n        # the graph, since the average number of ancestors and tests being awaited\n        # for each of the n nodes could itself be O(n) but we only track ancestors\n        # that are multi-tested, which should keep things closer to O(n) in real-\n        # world scenarios.\n\n        new_edges: List[Tuple[UniqueID, UniqueID]] = []\n        ready: deque = deque(source_nodes)\n        details = {node_id: SeenDetails(node_id) for node_id in source_nodes}\n\n        while len(ready) > 0:\n            curr_details: SeenDetails = details[ready.pop()]\n            test_ids = _get_tests_for_node(manifest, curr_details.node_id)\n            new_awaits_for_succs = curr_details.awaits_tests.copy()\n            for test_id in test_ids:\n                deps: List[UniqueID] = sorted(manifest.nodes[test_id].depends_on_nodes)\n                if len(deps) > 1:\n                    # Tests with only one dep were already handled.\n                    new_awaits_for_succs.add((test_id, tuple(deps)))\n\n            for succ_id in [\n                s for s in graph.successors(curr_details.node_id) if s in executable_nodes\n            ]:\n                suc_details = details.get(succ_id, None)\n                if suc_details is None:\n                    suc_details = SeenDetails(succ_id)\n                    details[succ_id] = suc_details\n                suc_details.visits += 1\n                suc_details.awaits_tests.update(new_awaits_for_succs)\n                suc_details.ancestors.update(curr_details.ancestors)\n                if curr_details.node_id in multi_tested_nodes:\n                    # Only track ancestry information for the set of nodes\n                    # we will actually check against later.\n                    suc_details.ancestors.add(curr_details.node_id)\n\n                if suc_details.visits == graph.in_degree(succ_id):\n                    if len(suc_details.awaits_tests) > 0:\n                        removes = set()\n                        for awt in suc_details.awaits_tests:\n                            if not any(True for a in awt[1] if a not in suc_details.ancestors):\n                                removes.add(awt)\n                                new_edges.append((awt[0], succ_id))\n\n                        suc_details.awaits_tests.difference_update(removes)\n                    ready.appendleft(succ_id)\n\n            # We are now done with the current node and all of its ancestors.\n            # Discard its details to save memory.\n            del details[curr_details.node_id]\n\n        return new_edges\n\n    def get_graph(self, manifest: Manifest) -> Graph:\n        self.link_graph(manifest)\n        return Graph(self.graph)\n\n    def get_graph_summary(self, manifest: Manifest) -> Dict[int, Dict[str, Any]]:\n        \"\"\"Create a smaller summary of the graph, suitable for basic diagnostics\n        and performance tuning. The summary includes only the edge structure,\n        node types, and node names. Each of the n nodes is assigned an integer\n        index 0, 1, 2,..., n-1 for compactness\"\"\"\n        graph_nodes = dict()\n        index_dict = dict()\n        for node_index, node_name in enumerate(self.graph):\n            index_dict[node_name] = node_index\n            data = manifest.expect(node_name).to_dict(omit_none=True)\n            graph_nodes[node_index] = {\"name\": node_name, \"type\": data[\"resource_type\"]}\n\n        for node_index, node in graph_nodes.items():\n            successors = [index_dict[n] for n in self.graph.successors(node[\"name\"])]\n            if successors:\n                node[\"succ\"] = [index_dict[n] for n in self.graph.successors(node[\"name\"])]\n\n        return graph_nodes\n\n\nclass Compiler:\n    def __init__(self, config) -> None:\n        self.config = config\n        # Set of unique_ids for nodes selected in the current run.\n        # Used to determine whether FK constraint targets should use\n        # deferred relations or current relations during compilation.\n        self.selected_node_ids: Set[str] = set()\n\n    def initialize(self):\n        make_directory(self.config.project_target_path)\n\n    # creates a ModelContext which is converted to\n    # a dict for jinja rendering of SQL\n    def _create_node_context(\n        self,\n        node: ManifestSQLNode,\n        manifest: Manifest,\n        extra_context: Dict[str, Any],\n    ) -> Dict[str, Any]:\n        if isinstance(node, UnitTestNode):\n            context = generate_runtime_unit_test_context(node, self.config, manifest)\n        else:\n            context = generate_runtime_model_context(node, self.config, manifest)\n        context.update(extra_context)\n\n        if isinstance(node, GenericTestNode):\n            # for test nodes, add a special keyword args value to the context\n            jinja.add_rendered_test_kwargs(context, node)\n\n        return context\n\n    def add_ephemeral_prefix(self, name: str):\n        adapter = get_adapter(self.config)\n        relation_cls = adapter.Relation\n        return relation_cls.add_ephemeral_prefix(name)\n\n    def _recursively_prepend_ctes(\n        self,\n        model: ManifestSQLNode,\n        manifest: Manifest,\n        extra_context: Optional[Dict[str, Any]],\n    ) -> Tuple[ManifestSQLNode, List[InjectedCTE]]:\n        \"\"\"This method is called by the 'compile_node' method. Starting\n        from the node that it is passed in, it will recursively call\n        itself using the 'extra_ctes'.  The 'ephemeral' models do\n        not produce SQL that is executed directly, instead they\n        are rolled up into the models that refer to them by\n        inserting CTEs into the SQL.\n        \"\"\"\n        if model.compiled_code is None:\n            raise DbtRuntimeError(\"Cannot inject ctes into an uncompiled node\", model)\n\n        # tech debt: safe flag/arg access (#6259)\n        if not getattr(self.config.args, \"inject_ephemeral_ctes\", True):\n            return (model, [])\n\n        # extra_ctes_injected flag says that we've already recursively injected the ctes\n        if model.extra_ctes_injected:\n            return (model, model.extra_ctes)\n\n        # Just to make it plain that nothing is actually injected for this case\n        if len(model.extra_ctes) == 0:\n            # SeedNodes don't have compilation attributes\n            if not isinstance(model, SeedNode):\n                model.extra_ctes_injected = True\n            return (model, [])\n\n        # This stores the ctes which will all be recursively\n        # gathered and then \"injected\" into the model.\n        prepended_ctes: List[InjectedCTE] = []\n\n        # extra_ctes are added to the model by\n        # RuntimeRefResolver.create_relation, which adds an\n        # extra_cte for every model relation which is an\n        # ephemeral model. InjectedCTEs have a unique_id and sql.\n        # extra_ctes start out with sql set to None, and the sql is set in this loop.\n        for cte in model.extra_ctes:\n            if cte.id not in manifest.nodes:\n                raise DbtInternalError(\n                    f\"During compilation, found a cte reference that \"\n                    f\"could not be resolved: {cte.id}\"\n                )\n            cte_model = manifest.nodes[cte.id]\n            assert not isinstance(cte_model, SeedNode)\n\n            if not cte_model.is_ephemeral_model:\n                raise DbtInternalError(f\"{cte.id} is not ephemeral\")\n\n            # Lock the ephemeral cte_model to ensure only one thread compiles it.\n            # The lock is scoped to just the compilation step; the recursive\n            # _recursively_prepend_ctes call happens outside the lock to avoid\n            # deadlock (it will re-acquire this node's lock at CTE injection).\n            new_prepended_ctes = None\n            needs_recursion = False\n            with cte_model._lock:\n                # This model has already been compiled and extra_ctes_injected,\n                # so it's been through here before. We already checked above for\n                # extra_ctes_injected, but checking again because updates may\n                # have happened in another thread.\n                if cte_model.compiled is True and cte_model.extra_ctes_injected is True:\n                    new_prepended_ctes = cte_model.extra_ctes\n                elif not cte_model.compiled:\n                    # This is an ephemeral parsed model that we can compile.\n                    # Render the raw_code and set compiled to True\n                    cte_model = self._compile_code(cte_model, manifest, extra_context)\n                    needs_recursion = True\n                else:\n                    # compiled=True but extra_ctes not yet injected; another\n                    # thread compiled it but hasn't finished recursion yet.\n                    # We still need to recurse to get the prepended CTEs.\n                    needs_recursion = True\n\n            if needs_recursion:\n                # recursively call this method, sets extra_ctes_injected to True\n                cte_model, new_prepended_ctes = self._recursively_prepend_ctes(\n                    cte_model, manifest, extra_context\n                )\n                # Write compiled SQL file\n                self._write_node(cte_model)\n\n            if new_prepended_ctes is None:\n                raise DbtInternalError(\n                    f\"Expected extra_ctes to be set for ephemeral model {cte.id}\"\n                )\n            _extend_prepended_ctes(prepended_ctes, new_prepended_ctes)\n\n            cte_name = (\n                cte_model.cte_name\n                if isinstance(cte_model, UnitTestSourceDefinition)\n                else cte_model.identifier\n            )\n            new_cte_name = self.add_ephemeral_prefix(cte_name)\n            rendered_sql = cte_model._pre_injected_sql or cte_model.compiled_code\n            sql = f\" {new_cte_name} as (\\n{rendered_sql}\\n)\"\n\n            _add_prepended_cte(prepended_ctes, InjectedCTE(id=cte.id, sql=sql))\n\n        # Lock the consuming model to prevent duplicate CTE injection\n        with model._lock:\n            if not model.extra_ctes_injected:\n                injected_sql = inject_ctes_into_sql(\n                    model.compiled_code,\n                    prepended_ctes,\n                )\n                model.extra_ctes_injected = True\n                model._pre_injected_sql = model.compiled_code\n                model.compiled_code = injected_sql\n                model.extra_ctes = prepended_ctes\n\n        # if model.extra_ctes is not set to prepended ctes, something went wrong\n        return model, model.extra_ctes\n\n    # Sets compiled_code and compiled flag in the ManifestSQLNode passed in,\n    # creates a \"context\" dictionary for jinja rendering,\n    # and then renders the \"compiled_code\" using the node, the\n    # raw_code and the context.\n    def _compile_code(\n        self,\n        node: ManifestSQLNode,\n        manifest: Manifest,\n        extra_context: Optional[Dict[str, Any]] = None,\n    ) -> ManifestSQLNode:\n        if extra_context is None:\n            extra_context = {}\n\n        if node.language == ModelLanguage.python and node.resource_type == NodeType.Model:\n            context = self._create_node_context(node, manifest, extra_context)\n\n            postfix = jinja.get_rendered(\n                \"{{ py_script_postfix(model) }}\",\n                context,\n                node,\n            )\n            # we should NOT jinja render the python model's 'raw code'\n            node.compiled_code = f\"{node.raw_code}\\n\\n{postfix}\"\n\n        else:\n            context = self._create_node_context(node, manifest, extra_context)\n            node.compiled_code = jinja.get_rendered(\n                node.raw_code,\n                context,\n                node,\n            )\n\n        node.compiled = True\n\n        # relation_name is set at parse time, except for tests without store_failures,\n        # but cli param can turn on store_failures, so we set here.\n        if (\n            node.resource_type == NodeType.Test\n            and node.relation_name is None\n            and node.is_relational\n        ):\n            adapter = get_adapter(self.config)\n            relation_cls = adapter.Relation\n            relation_name = str(relation_cls.create_from(self.config, node))\n            node.relation_name = relation_name\n\n        # Compile 'ref' and 'source' expressions in foreign key constraints\n        if isinstance(node, ModelNode):\n            for constraint in node.all_constraints:\n                if constraint.type == ConstraintType.foreign_key and constraint.to:\n                    constraint.to = self._compile_relation_for_foreign_key_constraint_to(\n                        manifest, node, constraint.to\n                    )\n\n        return node\n\n    def _compile_relation_for_foreign_key_constraint_to(\n        self, manifest: Manifest, node: ManifestSQLNode, to_expression: str\n    ) -> str:\n        try:\n            foreign_key_node = manifest.find_node_from_ref_or_source(to_expression)\n        except ParsingError:\n            raise ForeignKeyConstraintToSyntaxError(node, to_expression)\n\n        if not foreign_key_node:\n            raise GraphDependencyNotFoundError(node, to_expression)\n\n        adapter = get_adapter(self.config)\n\n        # Use deferred relation only if:\n        # 1. The foreign key node has a defer_relation (from previous state)\n        # 2. The --defer flag is set\n        # 3. The foreign key node is NOT being built in the current run\n        #    (i.e., not in selected_node_ids)\n        # This mirrors the logic in RuntimeRefResolver.create_relation() for\n        # model body refs, ensuring FK constraints behave consistently.\n        if (\n            hasattr(foreign_key_node, \"defer_relation\")\n            and foreign_key_node.defer_relation\n            and self.config.args.defer\n            and foreign_key_node.unique_id not in self.selected_node_ids\n        ):\n            return str(adapter.Relation.create_from(self.config, foreign_key_node.defer_relation))\n        else:\n            return str(adapter.Relation.create_from(self.config, foreign_key_node))\n\n    # This method doesn't actually \"compile\" any of the nodes. That is done by the\n    # \"compile_node\" method. This creates a Linker and builds the networkx graph,\n    # writes out the graph.gpickle file, and prints the stats, returning a Graph object.\n    def compile(self, manifest: Manifest, write=True, add_test_edges=False) -> Graph:\n        self.initialize()\n        linker = Linker()\n        linker.link_graph(manifest)\n\n        # Create a file containing basic information about graph structure,\n        # supporting diagnostics and performance analysis.\n        summaries: Dict = dict()\n        summaries[\"_invocation_id\"] = get_invocation_id()\n        summaries[\"linked\"] = linker.get_graph_summary(manifest)\n\n        # This is only called for the \"build\" command\n        if add_test_edges:\n            manifest.build_parent_and_child_maps()\n            linker.add_test_edges(manifest)\n\n            # Create another diagnostic summary, just as above, but this time\n            # including the test edges.\n            summaries[\"with_test_edges\"] = linker.get_graph_summary(manifest)\n\n        with open(\n            os.path.join(self.config.project_target_path, \"graph_summary.json\"), \"w\"\n        ) as out_stream:\n            try:\n                out_stream.write(json.dumps(summaries))\n            except Exception as e:  # This is non-essential information, so merely note failures.\n                fire_event(\n                    Note(\n                        msg=f\"An error was encountered writing the graph summary information: {e}\"\n                    )\n                )\n\n        stats = _generate_stats(manifest)\n\n        if write:\n            self.write_graph_file(linker, manifest)\n\n        # Do not print these for list command\n        if self.config.args.which != \"list\":\n            stats = _generate_stats(manifest)\n            print_compile_stats(stats)\n\n        return Graph(linker.graph)\n\n    def write_graph_file(self, linker: Linker, manifest: Manifest):\n        filename = graph_file_name\n        graph_path = os.path.join(self.config.project_target_path, filename)\n        flags = get_flags()\n        if flags.WRITE_JSON:\n            linker.write_graph(graph_path, manifest)\n\n    # writes the \"compiled_code\" into the target/compiled directory\n    def _write_node(\n        self, node: ManifestSQLNode, split_suffix: Optional[str] = None\n    ) -> ManifestSQLNode:\n        if not node.extra_ctes_injected or node.resource_type in (NodeType.Seed,):\n            return node\n        fire_event(WritingInjectedSQLForNode(node_info=get_node_info()))\n\n        if node.compiled_code:\n            node.compiled_path = node.get_target_write_path(\n                self.config.target_path, \"compiled\", split_suffix\n            )\n            node.write_node(self.config.project_root, node.compiled_path, node.compiled_code)\n        return node\n\n    def compile_node(\n        self,\n        node: ManifestSQLNode,\n        manifest: Manifest,\n        extra_context: Optional[Dict[str, Any]] = None,\n        write: bool = True,\n        split_suffix: Optional[str] = None,\n    ) -> ManifestSQLNode:\n        \"\"\"This is the main entry point into this code. It's called by\n        CompileRunner.compile, GenericRPCRunner.compile, and\n        RunTask.get_hook_sql. It calls '_compile_code' to render\n        the node's raw_code into compiled_code, and then calls the\n        recursive method to \"prepend\" the ctes.\n        \"\"\"\n        # REVIEW: UnitTestDefinition shouldn't be possible here because of the\n        # type of node, and it is likewise an invalid return type.\n        if isinstance(node, UnitTestDefinition):\n            return node\n\n        # Make sure Lexer for sqlparse 0.4.4 is initialized\n        from sqlparse.lexer import Lexer  # type: ignore\n\n        if hasattr(Lexer, \"get_default_instance\"):\n            Lexer.get_default_instance()\n\n        node = self._compile_code(node, manifest, extra_context)\n\n        node, _ = self._recursively_prepend_ctes(node, manifest, extra_context)\n        if write:\n            self._write_node(node, split_suffix=split_suffix)\n        return node\n\n\ndef inject_ctes_into_sql(sql: str, ctes: List[InjectedCTE]) -> str:\n    \"\"\"\n    `ctes` is a list of InjectedCTEs like:\n\n        [\n            InjectedCTE(\n                id=\"cte_id_1\",\n                sql=\"__dbt__cte__ephemeral as (select * from table)\",\n            ),\n            InjectedCTE(\n                id=\"cte_id_2\",\n                sql=\"__dbt__cte__events as (select id, type from events)\",\n            ),\n        ]\n\n    Given `sql` like:\n\n      \"with internal_cte as (select * from sessions)\n       select * from internal_cte\"\n\n    This will spit out:\n\n      \"with __dbt__cte__ephemeral as (select * from table),\n            __dbt__cte__events as (select id, type from events),\n            internal_cte as (select * from sessions)\n       select * from internal_cte\"\n\n    (Whitespace enhanced for readability.)\n    \"\"\"\n    if len(ctes) == 0:\n        return sql\n\n    try:\n        parsed_stmts = sqlparse.parse(sql)\n    except Exception as e:\n        compilation_exception_msg = str(e)\n        if \"grouping depth exceeded\" in compilation_exception_msg.lower():\n            compilation_exception_msg = (\n                f\"{compilation_exception_msg} You may raise the limit via \"\n                f'--sqlparse \\'{{\"MAX_GROUPING_DEPTH\": \"<value>\"}}\\'.'\n            )\n        if \"number of tokens exceeded\" in compilation_exception_msg.lower():\n            compilation_exception_msg = (\n                f\"{compilation_exception_msg} You may raise the limit via \"\n                f'--sqlparse \\'{{\"MAX_GROUPING_TOKENS\": \"<value>\"}}\\'.'\n            )\n        raise CompilationError(compilation_exception_msg)\n\n    parsed = parsed_stmts[0]\n\n    with_stmt = None\n    for token in parsed.tokens:\n        if token.is_keyword and token.normalized == \"WITH\":\n            with_stmt = token\n        elif token.is_keyword and token.normalized == \"RECURSIVE\" and with_stmt is not None:\n            with_stmt = token\n            break\n        elif not token.is_whitespace and with_stmt is not None:\n            break\n\n    if with_stmt is None:\n        # no with stmt, add one, and inject CTEs right at the beginning\n        # [original_sql]\n        first_token = parsed.token_first()\n        with_token = sqlparse.sql.Token(sqlparse.tokens.Keyword, \"with\")\n        parsed.insert_before(first_token, with_token)\n        # [with][original_sql]\n        injected_ctes = \", \".join(c.sql for c in ctes) + \" \"\n        injected_ctes_token = sqlparse.sql.Token(sqlparse.tokens.Keyword, injected_ctes)\n        parsed.insert_after(with_token, injected_ctes_token)\n        # [with][joined_ctes][original_sql]\n    else:\n        # with stmt exists so we don't need to add one, but we do need to add a comma\n        # between the injected ctes and the original sql\n        # [with][original_sql]\n        injected_ctes = \", \".join(c.sql for c in ctes)\n        injected_ctes_token = sqlparse.sql.Token(sqlparse.tokens.Keyword, injected_ctes)\n        parsed.insert_after(with_stmt, injected_ctes_token)\n        # [with][joined_ctes][original_sql]\n        comma_token = sqlparse.sql.Token(sqlparse.tokens.Punctuation, \", \")\n        parsed.insert_after(injected_ctes_token, comma_token)\n        # [with][joined_ctes][, ][original_sql]\n\n    return str(parsed)\n"
  },
  {
    "path": "core/dbt/config/README.md",
    "content": "# Config README\n"
  },
  {
    "path": "core/dbt/config/__init__.py",
    "content": "# all these are just exports, they need \"noqa\" so flake8 will not complain.\nfrom .profile import Profile  # noqa\nfrom .project import IsFQNResource, PartialProject, Project  # noqa\nfrom .runtime import RuntimeConfig  # noqa\n"
  },
  {
    "path": "core/dbt/config/catalogs.py",
    "content": "import os\nfrom copy import deepcopy\nfrom typing import Any, Dict, List, Optional\n\nfrom dbt.artifacts.resources import Catalog, CatalogWriteIntegrationConfig\nfrom dbt.clients.yaml_helper import load_yaml_text\nfrom dbt.config.renderer import SecretRenderer\nfrom dbt.constants import CATALOGS_FILE_NAME\nfrom dbt.exceptions import YamlLoadError\nfrom dbt_common.clients.system import load_file_contents\nfrom dbt_common.exceptions import CompilationError, DbtValidationError\n\n\ndef load_catalogs_yml(project_dir: str, project_name: str) -> Dict[str, Any]:\n    path = os.path.join(project_dir, CATALOGS_FILE_NAME)\n\n    if os.path.isfile(path):\n        try:\n            contents = load_file_contents(path, strip=False)\n            yaml_content = load_yaml_text(contents)\n\n            if not yaml_content:\n                raise DbtValidationError(f\"The file at {path} is empty\")\n\n            return yaml_content\n        except DbtValidationError as e:\n            raise YamlLoadError(project_name=project_name, path=CATALOGS_FILE_NAME, exc=e)\n\n    return {}\n\n\ndef load_single_catalog(raw_catalog: Dict[str, Any], renderer: SecretRenderer) -> Catalog:\n    try:\n        rendered_catalog = renderer.render_data(raw_catalog)\n    except CompilationError as exc:\n        raise DbtValidationError(str(exc)) from exc\n\n    Catalog.validate(rendered_catalog)\n\n    write_integrations = []\n    write_integration_names = set()\n\n    for raw_integration in rendered_catalog.get(\"write_integrations\", []):\n        if raw_integration[\"name\"] in write_integration_names:\n            raise DbtValidationError(\n                f\"Catalog '{rendered_catalog['name']}' cannot have multiple 'write_integrations' with the same name: '{raw_integration['name']}'.\"\n            )\n\n        # We're going to let the adapter validate the integration config\n        write_integrations.append(\n            CatalogWriteIntegrationConfig(**raw_integration, catalog_name=raw_catalog[\"name\"])\n        )\n        write_integration_names.add(raw_integration[\"name\"])\n\n    # Validate + set default active_write_integration if unset\n    active_write_integration = rendered_catalog.get(\"active_write_integration\")\n    valid_write_integration_names = [integration.name for integration in write_integrations]\n\n    if not active_write_integration:\n        if len(valid_write_integration_names) == 1:\n            active_write_integration = write_integrations[0].name\n        else:\n            raise DbtValidationError(\n                f\"Catalog '{rendered_catalog['name']}' must specify an 'active_write_integration' when multiple 'write_integrations' are provided.\"\n            )\n    else:\n        if active_write_integration not in valid_write_integration_names:\n            raise DbtValidationError(\n                f\"Catalog '{rendered_catalog['name']}' must specify an 'active_write_integration' from its set of defined 'write_integrations': {valid_write_integration_names}. Got: '{active_write_integration}'.\"\n            )\n\n    return Catalog(\n        name=raw_catalog[\"name\"],\n        active_write_integration=active_write_integration,\n        write_integrations=write_integrations,\n    )\n\n\ndef load_catalogs(project_dir: str, project_name: str, cli_vars: Dict[str, Any]) -> List[Catalog]:\n    raw_catalogs = load_catalogs_yml(project_dir, project_name).get(\"catalogs\", [])\n    catalogs_renderer = SecretRenderer(cli_vars)\n\n    return [load_single_catalog(raw_catalog, catalogs_renderer) for raw_catalog in raw_catalogs]\n\n\ndef get_active_write_integration(catalog: Catalog) -> Optional[CatalogWriteIntegrationConfig]:\n    for integration in catalog.write_integrations:\n        if integration.name == catalog.active_write_integration:\n            active_integration = deepcopy(integration)\n            active_integration.catalog_name = active_integration.name\n            active_integration.name = catalog.name\n            return active_integration\n\n    return None\n"
  },
  {
    "path": "core/dbt/config/profile.py",
    "content": "import os\nfrom dataclasses import dataclass\nfrom typing import Any, Dict, Optional, Tuple\n\nfrom dbt.adapters.contracts.connection import Credentials, HasCredentials\nfrom dbt.clients.yaml_helper import load_yaml_text\nfrom dbt.contracts.project import ProfileConfig\nfrom dbt.events.types import MissingProfileTarget\nfrom dbt.exceptions import (\n    CompilationError,\n    DbtProfileError,\n    DbtProjectError,\n    DbtRuntimeError,\n    ProfileConfigError,\n)\nfrom dbt.flags import get_flags\nfrom dbt_common.clients.system import load_file_contents\nfrom dbt_common.dataclass_schema import ValidationError\nfrom dbt_common.events.functions import fire_event\nfrom dbt_common.exceptions import DbtValidationError\n\nfrom .renderer import ProfileRenderer\n\nDEFAULT_THREADS = 1\n\nINVALID_PROFILE_MESSAGE = \"\"\"\ndbt encountered an error while trying to read your profiles.yml file.\n\n{error_string}\n\"\"\"\n\n\ndef read_profile(profiles_dir: str) -> Dict[str, Any]:\n    path = os.path.join(profiles_dir, \"profiles.yml\")\n\n    contents = None\n    if os.path.isfile(path):\n        try:\n            contents = load_file_contents(path, strip=False)\n            yaml_content = load_yaml_text(contents)\n            if not yaml_content:\n                msg = f\"The profiles.yml file at {path} is empty\"\n                raise DbtProfileError(INVALID_PROFILE_MESSAGE.format(error_string=msg))\n            return yaml_content\n        except DbtValidationError as e:\n            msg = INVALID_PROFILE_MESSAGE.format(error_string=e)\n            raise DbtValidationError(msg) from e\n\n    return {}\n\n\n# The Profile class is included in RuntimeConfig, so any attribute\n# additions must also be set where the RuntimeConfig class is created\n# `init=False` is a workaround for https://bugs.python.org/issue45081\n@dataclass(init=False)\nclass Profile(HasCredentials):\n    profile_name: str\n    target_name: str\n    threads: int\n    credentials: Credentials\n    profile_env_vars: Dict[str, Any]\n    log_cache_events: bool\n\n    def __init__(\n        self,\n        profile_name: str,\n        target_name: str,\n        threads: int,\n        credentials: Credentials,\n    ) -> None:\n        \"\"\"\n        TODO: Is this no longer needed now that 3.9 is no longer supported?\n        Explicitly defining `__init__` to work around bug in Python 3.9.7\n        https://bugs.python.org/issue45081\n        \"\"\"\n        self.profile_name = profile_name\n        self.target_name = target_name\n        self.threads = threads\n        self.credentials = credentials\n        self.profile_env_vars = {}  # never available on init\n        self.log_cache_events = (\n            get_flags().LOG_CACHE_EVENTS\n        )  # never available on init, set for adapter instantiation via AdapterRequiredConfig\n\n    def to_profile_info(self, serialize_credentials: bool = False) -> Dict[str, Any]:\n        \"\"\"Unlike to_project_config, this dict is not a mirror of any existing\n        on-disk data structure. It's used when creating a new profile from an\n        existing one.\n\n        :param serialize_credentials bool: If True, serialize the credentials.\n            Otherwise, the Credentials object will be copied.\n        :returns dict: The serialized profile.\n        \"\"\"\n        result = {\n            \"profile_name\": self.profile_name,\n            \"target_name\": self.target_name,\n            \"threads\": self.threads,\n            \"credentials\": self.credentials,\n        }\n        if serialize_credentials:\n            result[\"credentials\"] = self.credentials.to_dict(omit_none=True)\n        return result\n\n    def to_target_dict(self) -> Dict[str, Any]:\n        target = dict(self.credentials.connection_info(with_aliases=True))\n        target.update(\n            {\n                \"type\": self.credentials.type,\n                \"threads\": self.threads,\n                \"name\": self.target_name,\n                \"target_name\": self.target_name,\n                \"profile_name\": self.profile_name,\n            }\n        )\n        return target\n\n    def __eq__(self, other: object) -> bool:\n        if not (isinstance(other, self.__class__) and isinstance(self, other.__class__)):\n            return NotImplemented\n        return self.to_profile_info() == other.to_profile_info()\n\n    def validate(self):\n        try:\n            if self.credentials:\n                dct = self.credentials.to_dict(omit_none=True)\n                self.credentials.validate(dct)\n            dct = self.to_profile_info(serialize_credentials=True)\n            ProfileConfig.validate(dct)\n        except ValidationError as exc:\n            raise ProfileConfigError(exc) from exc\n\n    @staticmethod\n    def _credentials_from_profile(\n        profile: Dict[str, Any], profile_name: str, target_name: str\n    ) -> Credentials:\n        # avoid an import cycle\n        from dbt.adapters.factory import load_plugin\n\n        # credentials carry their 'type' in their actual type, not their\n        # attributes. We do want this in order to pick our Credentials class.\n        if \"type\" not in profile:\n            raise DbtProfileError(\n                'required field \"type\" not found in profile {} and target {}'.format(\n                    profile_name, target_name\n                )\n            )\n\n        typename = profile.pop(\"type\")\n        try:\n            cls = load_plugin(typename)\n            data = cls.translate_aliases(profile)\n            cls.validate(data)\n            credentials = cls.from_dict(data)\n        except (DbtRuntimeError, ValidationError) as e:\n            msg = str(e) if isinstance(e, DbtRuntimeError) else e.message\n            raise DbtProfileError(\n                'Credentials in profile \"{}\", target \"{}\" invalid: {}'.format(\n                    profile_name, target_name, msg\n                )\n            ) from e\n\n        return credentials\n\n    @staticmethod\n    def pick_profile_name(\n        args_profile_name: Optional[str],\n        project_profile_name: Optional[str] = None,\n    ) -> str:\n        # TODO: Duplicating this method as direct copy of the implementation in dbt.cli.resolvers\n        # dbt.cli.resolvers implementation can't be used because it causes a circular dependency.\n        # This should be removed and use a safe default access on the Flags module when\n        # https://github.com/dbt-labs/dbt-core/issues/6259 is closed.\n        def default_profiles_dir():\n            from pathlib import Path\n\n            return Path.cwd() if (Path.cwd() / \"profiles.yml\").exists() else Path.home() / \".dbt\"\n\n        profile_name = project_profile_name\n        if args_profile_name is not None:\n            profile_name = args_profile_name\n        if profile_name is None:\n            NO_SUPPLIED_PROFILE_ERROR = \"\"\"\\\ndbt cannot run because no profile was specified for this dbt project.\nTo specify a profile for this project, add a line like the this to\nyour dbt_project.yml file:\n\nprofile: [profile name]\n\nHere, [profile name] should be replaced with a profile name\ndefined in your profiles.yml file. You can find profiles.yml here:\n\n{profiles_file}/profiles.yml\n\"\"\".format(\n                profiles_file=default_profiles_dir()\n            )\n            raise DbtProjectError(NO_SUPPLIED_PROFILE_ERROR)\n        return profile_name\n\n    @staticmethod\n    def _get_profile_data(\n        profile: Dict[str, Any], profile_name: str, target_name: str\n    ) -> Dict[str, Any]:\n        if \"outputs\" not in profile:\n            raise DbtProfileError(\"outputs not specified in profile '{}'\".format(profile_name))\n        outputs = profile[\"outputs\"]\n\n        if target_name not in outputs:\n            outputs = \"\\n\".join(\" - {}\".format(output) for output in outputs)\n            msg = (\n                \"The profile '{}' does not have a target named '{}'. The \"\n                \"valid target names for this profile are:\\n{}\".format(\n                    profile_name, target_name, outputs\n                )\n            )\n            raise DbtProfileError(msg, result_type=\"invalid_target\")\n        profile_data = outputs[target_name]\n\n        if not isinstance(profile_data, dict):\n            msg = (\n                f\"output '{target_name}' of profile '{profile_name}' is \"\n                f\"misconfigured in profiles.yml\"\n            )\n            raise DbtProfileError(msg, result_type=\"invalid_target\")\n\n        return profile_data\n\n    @classmethod\n    def from_credentials(\n        cls,\n        credentials: Credentials,\n        threads: int,\n        profile_name: str,\n        target_name: str,\n    ) -> \"Profile\":\n        \"\"\"Create a profile from an existing set of Credentials and the\n        remaining information.\n\n        :param credentials: The credentials dict for this profile.\n        :param threads: The number of threads to use for connections.\n        :param profile_name: The profile name used for this profile.\n        :param target_name: The target name used for this profile.\n        :raises DbtProfileError: If the profile is invalid.\n        :returns: The new Profile object.\n        \"\"\"\n\n        profile = cls(\n            profile_name=profile_name,\n            target_name=target_name,\n            threads=threads,\n            credentials=credentials,\n        )\n        profile.validate()\n        return profile\n\n    @classmethod\n    def render_profile(\n        cls,\n        raw_profile: Dict[str, Any],\n        profile_name: str,\n        target_override: Optional[str],\n        renderer: ProfileRenderer,\n    ) -> Tuple[str, Dict[str, Any]]:\n        \"\"\"This is a containment zone for the hateful way we're rendering\n        profiles.\n        \"\"\"\n        # rendering profiles is a bit complex. Two constraints cause trouble:\n        # 1) users should be able to use environment/cli variables to specify\n        #    the target in their profile.\n        # 2) Missing environment/cli variables in profiles/targets that don't\n        #    end up getting selected should not cause errors.\n        # so first we'll just render the target name, then we use that rendered\n        # name to extract a profile that we can render.\n        if target_override is not None:\n            target_name = target_override\n        elif \"target\" in raw_profile:\n            # render the target if it was parsed from yaml\n            target_name = renderer.render_value(raw_profile[\"target\"])\n        else:\n            target_name = \"default\"\n            fire_event(MissingProfileTarget(profile_name=profile_name, target_name=target_name))\n\n        raw_profile_data = cls._get_profile_data(raw_profile, profile_name, target_name)\n\n        try:\n            profile_data = renderer.render_data(raw_profile_data)\n        except CompilationError as exc:\n            raise DbtProfileError(str(exc)) from exc\n        return target_name, profile_data\n\n    @classmethod\n    def from_raw_profile_info(\n        cls,\n        raw_profile: Dict[str, Any],\n        profile_name: str,\n        renderer: ProfileRenderer,\n        target_override: Optional[str] = None,\n        threads_override: Optional[int] = None,\n    ) -> \"Profile\":\n        \"\"\"Create a profile from its raw profile information.\n\n         (this is an intermediate step, mostly useful for unit testing)\n\n        :param raw_profile: The profile data for a single profile, from\n            disk as yaml and its values rendered with jinja.\n        :param profile_name: The profile name used.\n        :param renderer: The config renderer.\n        :param target_override: The target to use, if provided on\n            the command line.\n        :param threads_override: The thread count to use, if\n            provided on the command line.\n        :raises DbtProfileError: If the profile is invalid or missing, or the\n            target could not be found\n        :returns: The new Profile object.\n        \"\"\"\n        # TODO: should it be, and the values coerced to bool?\n        target_name, profile_data = cls.render_profile(\n            raw_profile, profile_name, target_override, renderer\n        )\n\n        # valid connections never include the number of threads, but it's\n        # stored on a per-connection level in the raw configs\n        threads = profile_data.pop(\"threads\", DEFAULT_THREADS)\n        if threads_override is not None:\n            threads = threads_override\n\n        credentials: Credentials = cls._credentials_from_profile(\n            profile_data, profile_name, target_name\n        )\n\n        return cls.from_credentials(\n            credentials=credentials,\n            profile_name=profile_name,\n            target_name=target_name,\n            threads=threads,\n        )\n\n    @classmethod\n    def from_raw_profiles(\n        cls,\n        raw_profiles: Dict[str, Any],\n        profile_name: str,\n        renderer: ProfileRenderer,\n        target_override: Optional[str] = None,\n        threads_override: Optional[int] = None,\n    ) -> \"Profile\":\n        \"\"\"\n        :param raw_profiles: The profile data, from disk as yaml.\n        :param profile_name: The profile name to use.\n        :param renderer: The config renderer.\n        :param target_override: The target to use, if provided on the command\n            line.\n        :param threads_override: The thread count to use, if provided on the\n            command line.\n        :raises DbtProjectError: If there is no profile name specified in the\n            project or the command line arguments\n        :raises DbtProfileError: If the profile is invalid or missing, or the\n            target could not be found\n        :returns: The new Profile object.\n        \"\"\"\n        if profile_name not in raw_profiles:\n            raise DbtProjectError(\"Could not find profile named '{}'\".format(profile_name))\n\n        # First, we've already got our final decision on profile name, and we\n        # don't render keys, so we can pluck that out\n        raw_profile = raw_profiles[profile_name]\n        if not raw_profile:\n            msg = f\"Profile {profile_name} in profiles.yml is empty\"\n            raise DbtProfileError(INVALID_PROFILE_MESSAGE.format(error_string=msg))\n\n        return cls.from_raw_profile_info(\n            raw_profile=raw_profile,\n            profile_name=profile_name,\n            renderer=renderer,\n            target_override=target_override,\n            threads_override=threads_override,\n        )\n\n    @classmethod\n    def render(\n        cls,\n        renderer: ProfileRenderer,\n        project_profile_name: Optional[str],\n        profile_name_override: Optional[str] = None,\n        target_override: Optional[str] = None,\n        threads_override: Optional[int] = None,\n    ) -> \"Profile\":\n        \"\"\"Given the raw profiles as read from disk and the name of the desired\n        profile if specified, return the profile component of the runtime\n        config.\n\n        :param args argparse.Namespace: The arguments as parsed from the cli.\n        :param project_profile_name Optional[str]: The profile name, if\n            specified in a project.\n        :raises DbtProjectError: If there is no profile name specified in the\n            project or the command line arguments, or if the specified profile\n            is not found\n        :raises DbtProfileError: If the profile is invalid or missing, or the\n            target could not be found.\n        :returns Profile: The new Profile object.\n        \"\"\"\n        flags = get_flags()\n        raw_profiles = read_profile(flags.PROFILES_DIR)\n        profile_name = cls.pick_profile_name(profile_name_override, project_profile_name)\n        return cls.from_raw_profiles(\n            raw_profiles=raw_profiles,\n            profile_name=profile_name,\n            renderer=renderer,\n            target_override=target_override,\n            threads_override=threads_override,\n        )\n"
  },
  {
    "path": "core/dbt/config/project.py",
    "content": "import os\nfrom copy import deepcopy\nfrom dataclasses import dataclass, field\nfrom itertools import chain\nfrom typing import Any, Dict, List, Mapping, Optional, TypeVar, Union\n\nfrom typing_extensions import Protocol, runtime_checkable\n\nfrom dbt import deprecations\nfrom dbt.adapters.contracts.connection import QueryComment\nfrom dbt.clients.checked_load import (\n    checked_load,\n    issue_deprecation_warnings_for_failures,\n)\nfrom dbt.clients.yaml_helper import load_yaml_text\nfrom dbt.config.selectors import SelectorDict\nfrom dbt.config.utils import normalize_warn_error_options\nfrom dbt.constants import (\n    DBT_PROJECT_FILE_NAME,\n    DEPENDENCIES_FILE_NAME,\n    PACKAGE_LOCK_FILE_NAME,\n    PACKAGE_LOCK_HASH_KEY,\n    PACKAGES_FILE_NAME,\n    VARS_FILE_NAME,\n)\nfrom dbt.contracts.project import PackageConfig\nfrom dbt.contracts.project import Project as ProjectContract\nfrom dbt.contracts.project import ProjectFlags, ProjectPackageMetadata, SemverString\nfrom dbt.exceptions import (\n    DbtExclusivePropertyUseError,\n    DbtProjectError,\n    DbtRuntimeError,\n    ProjectContractBrokenError,\n    ProjectContractError,\n)\nfrom dbt.flags import get_flags\nfrom dbt.graph import SelectionSpec\nfrom dbt.node_types import NodeType\nfrom dbt.utils import MultiDict, coerce_dict_str, md5\nfrom dbt.version import get_installed_version\nfrom dbt_common.clients.system import load_file_contents, path_exists\nfrom dbt_common.dataclass_schema import ValidationError\nfrom dbt_common.exceptions import SemverError\nfrom dbt_common.helper_types import NoValue\nfrom dbt_common.semver import VersionSpecifier, versions_compatible\n\nfrom .renderer import DbtProjectYamlRenderer, PackageRenderer\nfrom .selectors import (\n    SelectorConfig,\n    selector_config_from_data,\n    selector_data_from_root,\n)\n\nINVALID_VERSION_ERROR = \"\"\"\\\nThis version of dbt is not supported with the '{package}' package.\n  Installed version of dbt: {installed}\n  Required version of dbt for '{package}': {version_spec}\nCheck for a different version of the '{package}' package, or run dbt again with \\\n--no-version-check\n\"\"\"\n\n\nIMPOSSIBLE_VERSION_ERROR = \"\"\"\\\nThe package version requirement can never be satisfied for the '{package}\npackage.\n  Required versions of dbt for '{package}': {version_spec}\nCheck for a different version of the '{package}' package, or run dbt again with \\\n--no-version-check\n\"\"\"\n\nMALFORMED_PACKAGE_ERROR = \"\"\"\\\nThe packages.yml file in this project is malformed. Please double check\nthe contents of this file and fix any errors before retrying.\n\nYou can find more information on the syntax for this file here:\nhttps://docs.getdbt.com/docs/package-management\n\nValidator Error:\n{error}\n\"\"\"\n\nMISSING_DBT_PROJECT_ERROR = \"\"\"\\\nNo {DBT_PROJECT_FILE_NAME} found at expected path {path}\nVerify that each entry within packages.yml (and their transitive dependencies) contains a file named {DBT_PROJECT_FILE_NAME}\n\"\"\"\n\n\n@runtime_checkable\nclass IsFQNResource(Protocol):\n    fqn: List[str]\n    resource_type: NodeType\n    package_name: str\n\n\ndef _load_yaml(path, validate: bool = False):\n    contents = load_file_contents(path)\n    if validate:\n        result, failures = checked_load(contents)\n        issue_deprecation_warnings_for_failures(failures=failures, file=path)\n        return result\n    else:\n        return load_yaml_text(contents)\n\n\ndef load_yml_dict(file_path):\n    ret = {}\n    if path_exists(file_path):\n        ret = _load_yaml(file_path) or {}\n    return ret\n\n\ndef vars_data_from_root(project_root: str) -> Dict[str, Any]:\n    \"\"\"Load vars from vars.yml file if it exists.\n\n    Returns the contents of the 'vars' key, or empty dict if file doesn't exist or has no vars key.\n    \"\"\"\n    vars_yml_path = os.path.join(project_root, VARS_FILE_NAME)\n    vars_file_dict = load_yml_dict(vars_yml_path)\n    if not vars_file_dict:\n        return {}\n    return vars_file_dict.get(\"vars\", {})\n\n\ndef validate_vars_not_in_both(\n    project_dict: Dict[str, Any],\n    has_vars_file: bool,\n) -> None:\n    \"\"\"Raise error if vars defined in both vars.yml and dbt_project.yml.\"\"\"\n    has_project_vars = \"vars\" in project_dict and project_dict[\"vars\"]\n\n    if has_vars_file and has_project_vars:\n        raise DbtProjectError(\n            f\"Variables cannot be defined in both {VARS_FILE_NAME} and {DBT_PROJECT_FILE_NAME}. \"\n        )\n\n\ndef package_and_project_data_from_root(project_root):\n    packages_yml_dict = load_yml_dict(f\"{project_root}/{PACKAGES_FILE_NAME}\")\n    dependencies_yml_dict = load_yml_dict(f\"{project_root}/{DEPENDENCIES_FILE_NAME}\")\n\n    if \"packages\" in packages_yml_dict and \"packages\" in dependencies_yml_dict:\n        msg = \"The 'packages' key cannot be specified in both packages.yml and dependencies.yml\"\n        raise DbtProjectError(msg)\n    if \"projects\" in packages_yml_dict:\n        msg = \"The 'projects' key cannot be specified in packages.yml\"\n        raise DbtProjectError(msg)\n\n    packages_specified_path = PACKAGES_FILE_NAME\n    packages_dict = {}\n    if \"packages\" in dependencies_yml_dict:\n        packages_dict[\"packages\"] = dependencies_yml_dict[\"packages\"]\n        packages_specified_path = DEPENDENCIES_FILE_NAME\n    else:  # don't check for \"packages\" here so we capture invalid keys in packages.yml\n        packages_dict = packages_yml_dict\n\n    return packages_dict, packages_specified_path\n\n\ndef package_config_from_data(\n    packages_data: Dict[str, Any],\n    unrendered_packages_data: Optional[Dict[str, Any]] = None,\n) -> PackageConfig:\n    if not packages_data:\n        packages_data = {\"packages\": []}\n\n    # this depends on the two lists being in the same order\n    if unrendered_packages_data:\n        unrendered_packages_data = deepcopy(unrendered_packages_data)\n        for i in range(0, len(packages_data.get(\"packages\", []))):\n            packages_data[\"packages\"][i][\"unrendered\"] = unrendered_packages_data[\"packages\"][i]\n\n    if PACKAGE_LOCK_HASH_KEY in packages_data:\n        packages_data.pop(PACKAGE_LOCK_HASH_KEY)\n    try:\n        PackageConfig.validate(packages_data)\n        packages = PackageConfig.from_dict(packages_data)\n    except ValidationError as e:\n        raise DbtProjectError(MALFORMED_PACKAGE_ERROR.format(error=str(e.message))) from e\n    return packages\n\n\ndef load_package_lock_config(project_root: str) -> PackageConfig:\n    locked_packages = load_yml_dict(f\"{project_root}/{PACKAGE_LOCK_FILE_NAME}\") or {\"packages\": []}\n\n    return PackageConfig.from_dict(locked_packages)\n\n\ndef _parse_versions(versions: Union[List[str], str]) -> List[VersionSpecifier]:\n    \"\"\"Parse multiple versions as read from disk. The versions value may be any\n    one of:\n        - a single version string ('>0.12.1')\n        - a single string specifying multiple comma-separated versions\n            ('>0.11.1,<=0.12.2')\n        - an array of single-version strings (['>0.11.1', '<=0.12.2'])\n\n    Regardless, this will return a list of VersionSpecifiers\n    \"\"\"\n    if isinstance(versions, str):\n        versions = versions.split(\",\")\n    return [VersionSpecifier.from_version_string(v) for v in versions]\n\n\ndef _all_source_paths(*args: List[str]) -> List[str]:\n    paths = chain(*args)\n    # Strip trailing slashes since the path is the same even though the name is not\n    stripped_paths = map(lambda s: s.rstrip(\"/\"), paths)\n    return list(set(stripped_paths))\n\n\nT = TypeVar(\"T\")\n\n\ndef flag_or(flag: Optional[T], value: Optional[T], default: T) -> T:\n    if flag is None:\n        return value_or(value, default)\n    else:\n        return flag\n\n\ndef value_or(value: Optional[T], default: T) -> T:\n    if value is None:\n        return default\n    else:\n        return value\n\n\ndef load_raw_project(project_root: str, validate: bool = False) -> Dict[str, Any]:\n    project_root = os.path.normpath(project_root)\n    project_yaml_filepath = os.path.join(project_root, DBT_PROJECT_FILE_NAME)\n\n    # get the project.yml contents\n    if not path_exists(project_yaml_filepath):\n        raise DbtProjectError(\n            MISSING_DBT_PROJECT_ERROR.format(\n                path=project_yaml_filepath, DBT_PROJECT_FILE_NAME=DBT_PROJECT_FILE_NAME\n            )\n        )\n\n    project_dict = _load_yaml(project_yaml_filepath, validate=validate)\n\n    if validate:\n        from dbt.jsonschemas.jsonschemas import jsonschema_validate, project_schema\n\n        jsonschema_validate(\n            schema=project_schema(), json=project_dict, file_path=project_yaml_filepath\n        )\n\n    if not isinstance(project_dict, dict):\n        raise DbtProjectError(f\"{DBT_PROJECT_FILE_NAME} does not parse to a dictionary\")\n\n    if \"tests\" in project_dict and \"data_tests\" not in project_dict:\n        project_dict[\"data_tests\"] = project_dict.pop(\"tests\")\n\n    return project_dict\n\n\ndef _query_comment_from_cfg(\n    cfg_query_comment: Union[QueryComment, NoValue, str, None]\n) -> QueryComment:\n    if not cfg_query_comment:\n        return QueryComment(comment=\"\")\n\n    if isinstance(cfg_query_comment, str):\n        return QueryComment(comment=cfg_query_comment)\n\n    if isinstance(cfg_query_comment, NoValue):\n        return QueryComment()\n\n    return cfg_query_comment\n\n\ndef validate_version(dbt_version: List[VersionSpecifier], project_name: str):\n    \"\"\"Ensure this package works with the installed version of dbt.\"\"\"\n    installed = get_installed_version()\n    if not versions_compatible(*dbt_version):\n        msg = IMPOSSIBLE_VERSION_ERROR.format(\n            package=project_name, version_spec=[x.to_version_string() for x in dbt_version]\n        )\n        raise DbtProjectError(msg)\n\n    if not versions_compatible(installed, *dbt_version):\n        msg = INVALID_VERSION_ERROR.format(\n            package=project_name,\n            installed=installed.to_version_string(),\n            version_spec=[x.to_version_string() for x in dbt_version],\n        )\n        raise DbtProjectError(msg)\n\n\ndef _get_required_version(\n    project_dict: Dict[str, Any],\n    verify_version: bool,\n) -> List[VersionSpecifier]:\n    dbt_raw_version: Union[List[str], str] = \">=0.0.0\"\n    required = project_dict.get(\"require-dbt-version\")\n    if required is not None:\n        dbt_raw_version = required\n\n    try:\n        dbt_version = _parse_versions(dbt_raw_version)\n    except SemverError as e:\n        raise DbtProjectError(str(e)) from e\n\n    if verify_version:\n        # no name is also an error that we want to raise\n        if \"name\" not in project_dict:\n            raise DbtProjectError(\n                'Required \"name\" field not present in project',\n            )\n        validate_version(dbt_version, project_dict[\"name\"])\n\n    return dbt_version\n\n\n@dataclass\nclass RenderComponents:\n    project_dict: Dict[str, Any] = field(metadata=dict(description=\"The project dictionary\"))\n    packages_dict: Dict[str, Any] = field(metadata=dict(description=\"The packages dictionary\"))\n    selectors_dict: Dict[str, Any] = field(metadata=dict(description=\"The selectors dictionary\"))\n\n\n@dataclass\nclass PartialProject(RenderComponents):\n    # This class includes the project_dict, packages_dict, selectors_dict, etc from RenderComponents\n    profile_name: Optional[str] = field(\n        metadata=dict(description=\"The unrendered profile name in the project, if set\")\n    )\n    project_name: Optional[str] = field(\n        metadata=dict(\n            description=(\n                \"The name of the project. This should always be set and will not be rendered\"\n            )\n        )\n    )\n    project_root: str = field(\n        metadata=dict(description=\"The root directory of the project\"),\n    )\n    verify_version: bool = field(\n        metadata=dict(description=(\"If True, verify the dbt version matches the required version\"))\n    )\n    packages_specified_path: str = field(\n        metadata=dict(description=\"The filename where packages were specified\")\n    )\n\n    def render_profile_name(self, renderer) -> Optional[str]:\n        if self.profile_name is None:\n            return None\n        return renderer.render_value(self.profile_name)\n\n    def get_rendered(\n        self,\n        renderer: DbtProjectYamlRenderer,\n    ) -> RenderComponents:\n        rendered_project = renderer.render_project(self.project_dict, self.project_root)\n        rendered_packages = renderer.render_packages(\n            self.packages_dict, self.packages_specified_path\n        )\n        rendered_selectors = renderer.render_selectors(self.selectors_dict)\n\n        return RenderComponents(\n            project_dict=rendered_project,\n            packages_dict=rendered_packages,\n            selectors_dict=rendered_selectors,\n        )\n\n    # Called by Project.from_project_root which first calls PartialProject.from_project_root\n    def render(\n        self,\n        renderer: DbtProjectYamlRenderer,\n        vars_from_file: Optional[Dict[str, Any]] = None,\n    ) -> \"Project\":\n        try:\n            rendered = self.get_rendered(renderer)\n            return self.create_project(rendered, vars_from_file=vars_from_file)\n        except DbtProjectError as exc:\n            if exc.path is None:\n                exc.path = os.path.join(self.project_root, DBT_PROJECT_FILE_NAME)\n            raise\n\n    def render_package_metadata(self, renderer: PackageRenderer) -> ProjectPackageMetadata:\n        packages_data = renderer.render_data(self.packages_dict)\n        packages_config = package_config_from_data(packages_data, self.packages_dict)\n        if not self.project_name:\n            raise DbtProjectError(f\"Package defined in {DBT_PROJECT_FILE_NAME} must have a name!\")\n        return ProjectPackageMetadata(self.project_name, packages_config.packages)\n\n    def check_config_path(\n        self, project_dict, deprecated_path, expected_path=None, default_value=None\n    ):\n        if deprecated_path in project_dict:\n            if expected_path in project_dict:\n                msg = (\n                    \"{deprecated_path} and {expected_path} cannot both be defined. The \"\n                    \"`{deprecated_path}` config has been deprecated in favor of `{expected_path}`. \"\n                    f\"Please update your `{DBT_PROJECT_FILE_NAME}` configuration to reflect this \"\n                    \"change.\"\n                )\n                raise DbtProjectError(\n                    msg.format(deprecated_path=deprecated_path, expected_path=expected_path)\n                )\n            # this field is no longer supported, but many projects may specify it with the default value\n            # if so, let's only raise this deprecation warning if they set a custom value\n            if not default_value or project_dict[deprecated_path] != default_value:\n                kwargs = {\"deprecated_path\": deprecated_path}\n                if expected_path:\n                    kwargs.update({\"exp_path\": expected_path})\n                deprecations.warn(f\"project-config-{deprecated_path}\", **kwargs)\n\n    def create_project(\n        self,\n        rendered: RenderComponents,\n        vars_from_file: Optional[Dict[str, Any]] = None,\n    ) -> \"Project\":\n        unrendered = RenderComponents(\n            project_dict=self.project_dict,\n            packages_dict=self.packages_dict,\n            selectors_dict=self.selectors_dict,\n        )\n        dbt_version = _get_required_version(\n            rendered.project_dict,\n            verify_version=self.verify_version,\n        )\n\n        self.check_config_path(rendered.project_dict, \"source-paths\", \"model-paths\")\n        self.check_config_path(rendered.project_dict, \"data-paths\", \"seed-paths\")\n        self.check_config_path(rendered.project_dict, \"log-path\", default_value=\"logs\")\n        self.check_config_path(rendered.project_dict, \"target-path\", default_value=\"target\")\n\n        try:\n            ProjectContract.validate(rendered.project_dict)\n            cfg = ProjectContract.from_dict(rendered.project_dict)\n        except ValidationError as e:\n            raise ProjectContractError(e) from e\n        # name/version are required in the Project definition, so we can assume\n        # they are present\n        name = cfg.name\n        version = cfg.version\n        # this is added at project_dict parse time and should always be here\n        # once we see it.\n        if cfg.project_root is None:\n            raise DbtProjectError(\"cfg must have a project root!\")\n        else:\n            project_root = cfg.project_root\n        # this is only optional in the sense that if it's not present, it needs\n        # to have been a cli argument.\n        profile_name = cfg.profile\n        # these are all the defaults\n\n        # `source_paths` is deprecated but still allowed. Copy it into\n        # `model_paths` to simlify logic throughout the rest of the system.\n        model_paths: List[str] = value_or(\n            cfg.model_paths if \"model-paths\" in rendered.project_dict else cfg.source_paths,\n            [\"models\"],\n        )\n        macro_paths: List[str] = value_or(cfg.macro_paths, [\"macros\"])\n        # `data_paths` is deprecated but still allowed. Copy it into\n        # `seed_paths` to simlify logic throughout the rest of the system.\n        seed_paths: List[str] = value_or(\n            cfg.seed_paths if \"seed-paths\" in rendered.project_dict else cfg.data_paths, [\"seeds\"]\n        )\n        test_paths: List[str] = value_or(cfg.test_paths, [\"tests\"])\n        analysis_paths: List[str] = value_or(cfg.analysis_paths, [\"analyses\"])\n        snapshot_paths: List[str] = value_or(cfg.snapshot_paths, [\"snapshots\"])\n        function_paths: List[str] = value_or(cfg.function_paths, [\"functions\"])\n\n        all_source_paths: List[str] = _all_source_paths(\n            model_paths,\n            seed_paths,\n            snapshot_paths,\n            analysis_paths,\n            macro_paths,\n            test_paths,\n            function_paths,\n        )\n\n        docs_paths: List[str] = value_or(cfg.docs_paths, all_source_paths)\n        asset_paths: List[str] = value_or(cfg.asset_paths, [])\n        global_flags = get_flags()\n\n        flag_target_path = str(global_flags.TARGET_PATH) if global_flags.TARGET_PATH else None\n        target_path: str = flag_or(flag_target_path, cfg.target_path, \"target\")\n        log_path: str = str(global_flags.LOG_PATH)\n\n        clean_targets: List[str] = value_or(cfg.clean_targets, [target_path])\n        packages_install_path: str = value_or(cfg.packages_install_path, \"dbt_packages\")\n        # in the default case we'll populate this once we know the adapter type\n        # It would be nice to just pass along a Quoting here, but that would\n        # break many things\n        quoting: Dict[str, Any] = {}\n        if cfg.quoting is not None:\n            quoting = cfg.quoting.to_dict(omit_none=True)\n\n        dispatch: List[Dict[str, Any]]\n        models: Dict[str, Any]\n        seeds: Dict[str, Any]\n        snapshots: Dict[str, Any]\n        sources: Dict[str, Any]\n        data_tests: Dict[str, Any]\n        unit_tests: Dict[str, Any]\n        metrics: Dict[str, Any]\n        semantic_models: Dict[str, Any]\n        saved_queries: Dict[str, Any]\n        exposures: Dict[str, Any]\n        functions: Dict[str, Any]\n        vars_value: VarProvider\n        dbt_cloud: Dict[str, Any]\n\n        dispatch = cfg.dispatch\n        models = cfg.models\n        seeds = cfg.seeds\n        snapshots = cfg.snapshots\n        sources = cfg.sources\n        # the `tests` config is deprecated but still allowed. Copy it into\n        # `data_tests` to simplify logic throughout the rest of the system.\n        data_tests = cfg.data_tests if \"data_tests\" in rendered.project_dict else cfg.tests\n        unit_tests = cfg.unit_tests\n        metrics = cfg.metrics\n        semantic_models = cfg.semantic_models\n        saved_queries = cfg.saved_queries\n        exposures = cfg.exposures\n        functions = cfg.functions\n\n        # Use vars from vars.yml if provided, otherwise use vars from dbt_project.yml\n        # Mutual exclusivity ensures only one source is populated\n        if vars_from_file:\n            vars_dict = vars_from_file\n        else:\n            vars_dict = cfg.vars or {}\n\n        vars_value = VarProvider(vars_dict)\n        # There will never be any project_env_vars when it's first created\n        project_env_vars: Dict[str, Any] = {}\n        on_run_start: List[str] = value_or(cfg.on_run_start, [])\n        on_run_end: List[str] = value_or(cfg.on_run_end, [])\n\n        query_comment = _query_comment_from_cfg(cfg.query_comment)\n        packages: PackageConfig = package_config_from_data(\n            rendered.packages_dict, unrendered.packages_dict\n        )\n        selectors = selector_config_from_data(rendered.selectors_dict)\n        manifest_selectors: Dict[str, Any] = {}\n        if rendered.selectors_dict and rendered.selectors_dict[\"selectors\"]:\n            # this is a dict with a single key 'selectors' pointing to a list\n            # of dicts.\n            manifest_selectors = SelectorDict.parse_from_selectors_list(\n                rendered.selectors_dict[\"selectors\"]\n            )\n        dbt_cloud = cfg.dbt_cloud\n        flags: Dict[str, Any] = cfg.flags\n\n        project = Project(\n            project_name=name,\n            version=version,\n            project_root=project_root,\n            profile_name=profile_name,\n            model_paths=model_paths,\n            macro_paths=macro_paths,\n            seed_paths=seed_paths,\n            test_paths=test_paths,\n            analysis_paths=analysis_paths,\n            docs_paths=docs_paths,\n            asset_paths=asset_paths,\n            target_path=target_path,\n            snapshot_paths=snapshot_paths,\n            function_paths=function_paths,\n            clean_targets=clean_targets,\n            log_path=log_path,\n            packages_install_path=packages_install_path,\n            packages_specified_path=self.packages_specified_path,\n            quoting=quoting,\n            models=models,\n            on_run_start=on_run_start,\n            on_run_end=on_run_end,\n            dispatch=dispatch,\n            seeds=seeds,\n            snapshots=snapshots,\n            dbt_version=dbt_version,\n            packages=packages,\n            manifest_selectors=manifest_selectors,\n            selectors=selectors,\n            query_comment=query_comment,\n            sources=sources,\n            data_tests=data_tests,\n            unit_tests=unit_tests,\n            metrics=metrics,\n            semantic_models=semantic_models,\n            saved_queries=saved_queries,\n            exposures=exposures,\n            functions=functions,\n            vars=vars_value,\n            config_version=cfg.config_version,\n            unrendered=unrendered,\n            project_env_vars=project_env_vars,\n            restrict_access=cfg.restrict_access,\n            dbt_cloud=dbt_cloud,\n            flags=flags,\n            vars_from_file=vars_from_file or {},\n        )\n        # sanity check - this means an internal issue\n        project.validate()\n        return project\n\n    @classmethod\n    def from_dicts(\n        cls,\n        project_root: str,\n        project_dict: Dict[str, Any],\n        packages_dict: Dict[str, Any],\n        selectors_dict: Optional[Dict[str, Any]],\n        *,\n        verify_version: bool = False,\n        packages_specified_path: str = PACKAGES_FILE_NAME,\n    ):\n        \"\"\"Construct a partial project from its constituent dicts.\"\"\"\n        project_name = project_dict.get(\"name\")\n        profile_name = project_dict.get(\"profile\")\n\n        # Create a PartialProject\n        return cls(\n            profile_name=profile_name,\n            project_name=project_name,\n            project_root=project_root,\n            project_dict=project_dict,\n            packages_dict=packages_dict,\n            selectors_dict=selectors_dict,  # type: ignore\n            verify_version=verify_version,\n            packages_specified_path=packages_specified_path,\n        )\n\n    @classmethod\n    def from_project_root(\n        cls, project_root: str, *, verify_version: bool = False, validate: bool = False\n    ) -> \"PartialProject\":\n        project_root = os.path.normpath(project_root)\n        project_dict = load_raw_project(project_root, validate=validate)\n        (\n            packages_dict,\n            packages_specified_path,\n        ) = package_and_project_data_from_root(project_root)\n        selectors_dict = selector_data_from_root(project_root)\n\n        return cls.from_dicts(\n            project_root=project_root,\n            project_dict=project_dict,\n            selectors_dict=selectors_dict,\n            packages_dict=packages_dict,\n            verify_version=verify_version,\n            packages_specified_path=packages_specified_path,\n        )\n\n\nclass VarProvider:\n    \"\"\"Var providers are tied to a particular Project.\"\"\"\n\n    def __init__(self, vars: Dict[str, Dict[str, Any]]) -> None:\n        self.vars = vars\n\n    def vars_for(self, node: IsFQNResource, adapter_type: str) -> Mapping[str, Any]:\n        # in v2, vars are only either project or globally scoped\n        merged = MultiDict([self.vars])\n        merged.add(self.vars.get(node.package_name, {}))\n        return merged\n\n    def to_dict(self):\n        return self.vars\n\n\n# The Project class is included in RuntimeConfig, so any attribute\n# additions must also be set where the RuntimeConfig class is created\n@dataclass\nclass Project:\n    project_name: str\n    version: Optional[Union[SemverString, float]]\n    project_root: str\n    profile_name: Optional[str]\n    model_paths: List[str]\n    macro_paths: List[str]\n    seed_paths: List[str]\n    test_paths: List[str]\n    analysis_paths: List[str]\n    docs_paths: List[str]\n    asset_paths: List[str]\n    target_path: str\n    snapshot_paths: List[str]\n    function_paths: List[str]\n    clean_targets: List[str]\n    log_path: str\n    packages_install_path: str\n    packages_specified_path: str\n    quoting: Dict[str, Any]\n    models: Dict[str, Any]\n    on_run_start: List[str]\n    on_run_end: List[str]\n    dispatch: List[Dict[str, Any]]\n    seeds: Dict[str, Any]\n    snapshots: Dict[str, Any]\n    sources: Dict[str, Any]\n    data_tests: Dict[str, Any]\n    unit_tests: Dict[str, Any]\n    metrics: Dict[str, Any]\n    semantic_models: Dict[str, Any]\n    saved_queries: Dict[str, Any]\n    exposures: Dict[str, Any]\n    functions: Dict[str, Any]\n    vars: VarProvider\n    dbt_version: List[VersionSpecifier]\n    packages: PackageConfig\n    manifest_selectors: Dict[str, Any]\n    selectors: SelectorConfig\n    query_comment: QueryComment\n    config_version: int\n    unrendered: RenderComponents\n    project_env_vars: Dict[str, Any]\n    restrict_access: bool\n    dbt_cloud: Dict[str, Any]\n    flags: Dict[str, Any]\n    vars_from_file: Dict[str, Any]\n\n    @property\n    def all_source_paths(self) -> List[str]:\n        return _all_source_paths(\n            self.model_paths,\n            self.seed_paths,\n            self.snapshot_paths,\n            self.analysis_paths,\n            self.macro_paths,\n            self.test_paths,\n            self.function_paths,\n        )\n\n    @property\n    def generic_test_paths(self):\n        generic_test_paths = []\n        for test_path in self.test_paths:\n            generic_test_paths.append(os.path.join(test_path, \"generic\"))\n        return generic_test_paths\n\n    @property\n    def fixture_paths(self):\n        fixture_paths = []\n        for test_path in self.test_paths:\n            fixture_paths.append(os.path.join(test_path, \"fixtures\"))\n        return fixture_paths\n\n    def __str__(self):\n        cfg = self.to_project_config(with_packages=True)\n        return str(cfg)\n\n    def __eq__(self, other):\n        if not (isinstance(other, self.__class__) and isinstance(self, other.__class__)):\n            return False\n        return self.to_project_config(with_packages=True) == other.to_project_config(\n            with_packages=True\n        )\n\n    def to_project_config(self, with_packages=False):\n        \"\"\"Return a dict representation of the config that could be written to\n        disk with `yaml.safe_dump` to get this configuration.\n\n        :param with_packages bool: If True, include the serialized packages\n            file in the root.\n        :returns dict: The serialized profile.\n        \"\"\"\n        result = deepcopy(\n            {\n                \"name\": self.project_name,\n                \"version\": self.version,\n                \"project-root\": self.project_root,\n                \"profile\": self.profile_name,\n                \"model-paths\": self.model_paths,\n                \"macro-paths\": self.macro_paths,\n                \"seed-paths\": self.seed_paths,\n                \"test-paths\": self.test_paths,\n                \"analysis-paths\": self.analysis_paths,\n                \"docs-paths\": self.docs_paths,\n                \"asset-paths\": self.asset_paths,\n                \"target-path\": self.target_path,\n                \"snapshot-paths\": self.snapshot_paths,\n                \"clean-targets\": self.clean_targets,\n                \"log-path\": self.log_path,\n                \"quoting\": self.quoting,\n                \"models\": self.models,\n                \"on-run-start\": self.on_run_start,\n                \"on-run-end\": self.on_run_end,\n                \"dispatch\": self.dispatch,\n                \"seeds\": self.seeds,\n                \"snapshots\": self.snapshots,\n                \"sources\": self.sources,\n                \"data_tests\": self.data_tests,\n                \"unit_tests\": self.unit_tests,\n                \"metrics\": self.metrics,\n                \"semantic-models\": self.semantic_models,\n                \"saved-queries\": self.saved_queries,\n                \"exposures\": self.exposures,\n                \"functions\": self.functions,\n                \"vars\": self.vars.to_dict(),\n                \"require-dbt-version\": [v.to_version_string() for v in self.dbt_version],\n                \"restrict-access\": self.restrict_access,\n                \"dbt-cloud\": self.dbt_cloud,\n                \"flags\": self.flags,\n            }\n        )\n        if self.query_comment:\n            result[\"query-comment\"] = self.query_comment.to_dict(omit_none=True)\n\n        if with_packages:\n            result.update(self.packages.to_dict(omit_none=True))\n\n        return result\n\n    def validate(self):\n        try:\n            ProjectContract.validate(self.to_project_config())\n        except ValidationError as e:\n            raise ProjectContractBrokenError(e) from e\n\n    # Called by:\n    # RtConfig.load_dependencies => RtConfig.load_projects => RtConfig.new_project => Project.from_project_root\n    # RtConfig.from_args => RtConfig.collect_parts => load_project => Project.from_project_root\n    @classmethod\n    def from_project_root(\n        cls,\n        project_root: str,\n        renderer: DbtProjectYamlRenderer,\n        *,\n        verify_version: bool = False,\n        validate: bool = False,\n        vars_from_file: Optional[Dict[str, Any]] = None,\n    ) -> \"Project\":\n        partial = PartialProject.from_project_root(\n            project_root, verify_version=verify_version, validate=validate\n        )\n\n        # Check mutual exclusivity before rendering\n        validate_vars_not_in_both(partial.project_dict, bool(vars_from_file))\n\n        return partial.render(renderer, vars_from_file=vars_from_file)\n\n    def hashed_name(self):\n        return md5(self.project_name)\n\n    def get_selector(self, name: str) -> Union[SelectionSpec, bool]:\n        if name not in self.selectors:\n            raise DbtRuntimeError(\n                f\"Could not find selector named {name}, expected one of {list(self.selectors)}\"\n            )\n        return self.selectors[name][\"definition\"]\n\n    def get_default_selector_name(self) -> Union[str, None]:\n        \"\"\"This function fetch the default selector to use on `dbt run` (if any)\n        :return: either a selector if default is set or None\n        :rtype: Union[SelectionSpec, None]\n        \"\"\"\n        for selector_name, selector in self.selectors.items():\n            if selector[\"default\"] is True:\n                return selector_name\n\n        return None\n\n    def get_macro_search_order(self, macro_namespace: str):\n        for dispatch_entry in self.dispatch:\n            if dispatch_entry[\"macro_namespace\"] == macro_namespace:\n                return dispatch_entry[\"search_order\"]\n        return None\n\n    @property\n    def project_target_path(self):\n        # If target_path is absolute, project_root will not be included\n        return os.path.join(self.project_root, self.target_path)\n\n\ndef read_project_flags(project_dir: str, profiles_dir: str) -> ProjectFlags:\n    try:\n        project_flags: Dict[str, Any] = {}\n        # Read project_flags from dbt_project.yml first\n        # Flags are instantiated before the project, so we don't\n        # want to throw an error for non-existence of dbt_project.yml here\n        # because it breaks things.\n        project_root = os.path.normpath(project_dir)\n        project_yaml_filepath = os.path.join(project_root, DBT_PROJECT_FILE_NAME)\n        if path_exists(project_yaml_filepath):\n            try:\n                project_dict = load_raw_project(project_root)\n                if \"flags\" in project_dict:\n                    project_flags = project_dict.pop(\"flags\")\n            except Exception:\n                # This is probably a yaml load error.The error will be reported\n                # later, when the project loads.\n                pass\n\n        from dbt.config.profile import read_profile\n\n        profile = read_profile(profiles_dir)\n        profile_project_flags: Optional[Dict[str, Any]] = {}\n        if profile:\n            profile_project_flags = coerce_dict_str(profile.get(\"config\", {}))\n\n        if project_flags and profile_project_flags:\n            raise DbtProjectError(\n                f\"Do not specify both 'config' in profiles.yml and 'flags' in {DBT_PROJECT_FILE_NAME}. \"\n                \"Using 'config' in profiles.yml is deprecated.\"\n            )\n\n        if profile_project_flags:\n            # This can't use WARN_ERROR or WARN_ERROR_OPTIONS because they're in\n            # the config that we're loading. Uses special \"buffer\" method and fired after flags are initialized in preflight.\n            deprecations.buffer(\"project-flags-moved\")\n            project_flags = profile_project_flags\n\n        if project_flags is not None:\n            # handle collapsing `include` and `error` as well as collapsing `exclude` and `warn`\n            # for warn_error_options\n            warn_error_options = project_flags.get(\"warn_error_options\", {})\n            normalize_warn_error_options(warn_error_options)\n\n            ProjectFlags.validate(project_flags)\n            return ProjectFlags.from_dict(project_flags)\n    except (DbtProjectError, DbtExclusivePropertyUseError) as exc:\n        # We don't want to eat the DbtProjectError for UserConfig to ProjectFlags or\n        # DbtConfigError for warn_error_options munging\n        raise exc\n    except (DbtRuntimeError, ValidationError):\n        pass\n    return ProjectFlags()\n"
  },
  {
    "path": "core/dbt/config/renderer.py",
    "content": "import re\nfrom datetime import date\nfrom typing import Any, Callable, Dict, Optional, Tuple, Union\n\nfrom dbt.adapters.contracts.connection import HasCredentials\nfrom dbt.clients.jinja import get_rendered\nfrom dbt.constants import DEPENDENCIES_FILE_NAME, SECRET_PLACEHOLDER\nfrom dbt.context.base import BaseContext\nfrom dbt.context.secret import SecretContext\nfrom dbt.context.target import TargetContext\nfrom dbt.exceptions import DbtProjectError\nfrom dbt_common.clients.jinja import catch_jinja\nfrom dbt_common.constants import SECRET_ENV_PREFIX\nfrom dbt_common.context import get_invocation_context\nfrom dbt_common.exceptions import CompilationError, RecursionError\nfrom dbt_common.utils import deep_map_render\n\nKeypath = Tuple[Union[str, int], ...]\n\n\nclass BaseRenderer:\n    def __init__(self, context: Dict[str, Any]) -> None:\n        self.context = context\n\n    @property\n    def name(self):\n        return \"Rendering\"\n\n    def should_render_keypath(self, keypath: Keypath) -> bool:\n        return True\n\n    def render_entry(self, value: Any, keypath: Keypath) -> Any:\n        if not self.should_render_keypath(keypath):\n            return value\n\n        return self.render_value(value, keypath)\n\n    def render_value(self, value: Any, keypath: Optional[Keypath] = None) -> Any:\n        # keypath is ignored (and someone who knows should explain why here)\n        if not isinstance(value, str):\n            return value if not isinstance(value, date) else value.isoformat()\n\n        try:\n            with catch_jinja():\n                return get_rendered(value, self.context, native=True)\n        except CompilationError as exc:\n            msg = f\"Could not render {value}: {exc.msg}\"\n            raise CompilationError(msg) from exc\n\n    def render_data(self, data: Dict[str, Any]) -> Dict[str, Any]:\n        try:\n            return deep_map_render(self.render_entry, data)\n        except RecursionError:\n            raise DbtProjectError(\n                f\"Cycle detected: {self.name} input has a reference to itself\", project=data\n            )\n\n\ndef _list_if_none(value):\n    if value is None:\n        value = []\n    return value\n\n\ndef _dict_if_none(value):\n    if value is None:\n        value = {}\n    return value\n\n\ndef _list_if_none_or_string(value):\n    value = _list_if_none(value)\n    if isinstance(value, str):\n        return [value]\n    return value\n\n\nclass ProjectPostprocessor(Dict[Keypath, Callable[[Any], Any]]):\n    def __init__(self) -> None:\n        super().__init__()\n\n        self[(\"on-run-start\",)] = _list_if_none_or_string\n        self[(\"on-run-end\",)] = _list_if_none_or_string\n\n        for k in (\"models\", \"seeds\", \"snapshots\"):\n            self[(k,)] = _dict_if_none\n            self[(k, \"vars\")] = _dict_if_none\n            self[(k, \"pre-hook\")] = _list_if_none_or_string\n            self[(k, \"post-hook\")] = _list_if_none_or_string\n        self[(\"seeds\", \"column_types\")] = _dict_if_none\n\n    def postprocess(self, value: Any, key: Keypath) -> Any:\n        if key in self:\n            handler = self[key]\n            return handler(value)\n\n        return value\n\n\nclass DbtProjectYamlRenderer(BaseRenderer):\n    _KEYPATH_HANDLERS = ProjectPostprocessor()\n\n    def __init__(\n        self,\n        profile: Optional[HasCredentials] = None,\n        cli_vars: Optional[Dict[str, Any]] = None,\n        require_vars: bool = True,\n    ) -> None:\n        # Generate contexts here because we want to save the context\n        # object in order to retrieve the env_vars. This is almost always\n        # a TargetContext, but in the debug task we want a project\n        # even when we don't have a profile.\n        if cli_vars is None:\n            cli_vars = {}\n        # Store profile and cli_vars for creating strict context later\n        self.profile = profile\n        self.cli_vars = cli_vars\n\n        # By default, require vars (strict mode) for proper error messages.\n        # Commands that don't need vars (like 'deps') should explicitly pass\n        # require_vars=False for lenient loading.\n        if profile:\n            self.ctx_obj = TargetContext(\n                profile.to_target_dict(), cli_vars, require_vars=require_vars\n            )\n        else:\n            self.ctx_obj = BaseContext(cli_vars, require_vars=require_vars)  # type:ignore\n        context = self.ctx_obj.to_dict()\n        super().__init__(context)\n\n    @property\n    def name(self):\n        \"Project config\"\n\n    # Uses SecretRenderer\n    def get_package_renderer(self) -> BaseRenderer:\n        return PackageRenderer(self.ctx_obj.cli_vars)\n\n    def render_project(\n        self,\n        project: Dict[str, Any],\n        project_root: str,\n    ) -> Dict[str, Any]:\n        \"\"\"Render the project and insert the project root after rendering.\"\"\"\n        rendered_project = self.render_data(project)\n        rendered_project[\"project-root\"] = project_root\n        return rendered_project\n\n    def render_packages(self, packages: Dict[str, Any], packages_specified_path: str):\n        \"\"\"Render the given packages dict\"\"\"\n        packages = packages or {}  # Sometimes this is none in tests\n        package_renderer = self.get_package_renderer()\n        if packages_specified_path == DEPENDENCIES_FILE_NAME:\n            # We don't want to render the \"packages\" dictionary that came from dependencies.yml\n            return packages\n        else:\n            return package_renderer.render_data(packages)\n\n    def render_selectors(self, selectors: Dict[str, Any]):\n        return self.render_data(selectors)\n\n    def render_entry(self, value: Any, keypath: Keypath) -> Any:\n        result = super().render_entry(value, keypath)\n        return self._KEYPATH_HANDLERS.postprocess(result, keypath)\n\n    def should_render_keypath(self, keypath: Keypath) -> bool:\n        if not keypath:\n            return True\n\n        first = keypath[0]\n        # run hooks are not rendered\n        if first in {\"on-run-start\", \"on-run-end\", \"query-comment\"}:\n            return False\n\n        # don't render vars blocks until runtime\n        if first == \"vars\":\n            return False\n\n        if first in {\"seeds\", \"models\", \"snapshots\", \"tests\", \"data_tests\"}:\n            keypath_parts = {(k.lstrip(\"+ \") if isinstance(k, str) else k) for k in keypath}\n            # model-level hooks\n            late_rendered_hooks = {\"pre-hook\", \"post-hook\", \"pre_hook\", \"post_hook\"}\n            if keypath_parts.intersection(late_rendered_hooks):\n                return False\n\n        return True\n\n\nclass SecretRenderer(BaseRenderer):\n    def __init__(self, cli_vars: Dict[str, Any] = {}) -> None:\n        # Generate contexts here because we want to save the context\n        # object in order to retrieve the env_vars.\n        self.ctx_obj = SecretContext(cli_vars)\n        context = self.ctx_obj.to_dict()\n        super().__init__(context)\n\n    @property\n    def name(self):\n        return \"Secret\"\n\n    def render_value(self, value: Any, keypath: Optional[Keypath] = None) -> Any:\n        # First, standard Jinja rendering, with special handling for 'secret' environment variables\n        # \"{{ env_var('DBT_SECRET_ENV_VAR') }}\" -> \"$$$DBT_SECRET_START$$$DBT_SECRET_ENV_{VARIABLE_NAME}$$$DBT_SECRET_END$$$\"\n        # This prevents Jinja manipulation of secrets via macros/filters that might leak partial/modified values in logs\n\n        try:\n            rendered = super().render_value(value, keypath)\n        except Exception as ex:\n            if keypath and \"password\" in keypath:\n                # Passwords sometimes contain jinja-esque characters, but we\n                # don't want to render them if they aren't valid jinja.\n                rendered = value\n            else:\n                raise ex\n\n        # Now, detect instances of the placeholder value ($$$DBT_SECRET_START...DBT_SECRET_END$$$)\n        # and replace them with the actual secret value\n        if SECRET_ENV_PREFIX in str(rendered):\n            search_group = f\"({SECRET_ENV_PREFIX}(.*))\"\n            pattern = SECRET_PLACEHOLDER.format(search_group).replace(\"$\", r\"\\$\")\n            m = re.search(\n                pattern,\n                rendered,\n            )\n            if m:\n                found = m.group(1)\n                value = get_invocation_context().env[found]\n                replace_this = SECRET_PLACEHOLDER.format(found)\n                return rendered.replace(replace_this, value)\n        else:\n            return rendered\n\n\nclass ProfileRenderer(SecretRenderer):\n    @property\n    def name(self):\n        return \"Profile\"\n\n\nclass PackageRenderer(SecretRenderer):\n    @property\n    def name(self):\n        return \"Packages config\"\n"
  },
  {
    "path": "core/dbt/config/runtime.py",
    "content": "import itertools\nimport os\nfrom copy import deepcopy\nfrom dataclasses import dataclass\nfrom pathlib import Path\nfrom typing import (\n    Any,\n    Dict,\n    Iterable,\n    Iterator,\n    Mapping,\n    MutableSet,\n    Optional,\n    Tuple,\n    Type,\n)\n\nfrom dbt import tracking\nfrom dbt.adapters.contracts.connection import (\n    AdapterRequiredConfig,\n    Credentials,\n    HasCredentials,\n)\nfrom dbt.adapters.contracts.relation import ComponentName\nfrom dbt.adapters.factory import get_include_paths, get_relation_class_by_name\nfrom dbt.artifacts.resources import Quoting\nfrom dbt.config.project import (\n    load_package_lock_config,\n    load_raw_project,\n    vars_data_from_root,\n)\nfrom dbt.contracts.graph.manifest import ManifestMetadata\nfrom dbt.contracts.project import Configuration\nfrom dbt.events.types import UnusedResourceConfigPath\nfrom dbt.exceptions import (\n    ConfigContractBrokenError,\n    DbtProjectError,\n    DbtRuntimeError,\n    NonUniquePackageNameError,\n    UninstalledPackagesFoundError,\n)\nfrom dbt.flags import get_flags\nfrom dbt_common.dataclass_schema import ValidationError\nfrom dbt_common.events.functions import warn_or_error\nfrom dbt_common.helper_types import DictDefaultEmptyStr, FQNPath, PathSet\n\nfrom .profile import Profile\nfrom .project import Project\nfrom .renderer import DbtProjectYamlRenderer, ProfileRenderer\n\n\n# Called by RuntimeConfig.collect_parts class method\ndef load_project(\n    project_root: str,\n    version_check: bool,\n    profile: HasCredentials,\n    cli_vars: Optional[Dict[str, Any]] = None,\n    validate: bool = False,\n    require_vars: bool = True,\n) -> Project:\n\n    if cli_vars is None:\n        cli_vars = {}\n\n    # Load vars.yml first (before rendering dbt_project.yml)\n    vars_from_file = vars_data_from_root(project_root)\n\n    # Merge: CLI vars take precedence over file vars\n    merged_vars = {**vars_from_file, **cli_vars}\n\n    # Renderer receives merged vars for Jinja in dbt_project.yml\n    project_renderer = DbtProjectYamlRenderer(profile, merged_vars, require_vars=require_vars)\n    project = Project.from_project_root(\n        project_root,\n        project_renderer,\n        verify_version=version_check,\n        validate=validate,\n        vars_from_file=vars_from_file,\n    )\n\n    # Save env_vars encountered in rendering for partial parsing\n    project.project_env_vars = project_renderer.ctx_obj.env_vars\n    return project\n\n\ndef load_profile(\n    project_root: str,\n    cli_vars: Dict[str, Any],\n    profile_name_override: Optional[str] = None,\n    target_override: Optional[str] = None,\n    threads_override: Optional[int] = None,\n) -> Profile:\n    raw_project = load_raw_project(project_root)\n    raw_profile_name = raw_project.get(\"profile\")\n    profile_renderer = ProfileRenderer(cli_vars)\n    profile_name = profile_renderer.render_value(raw_profile_name)\n    profile = Profile.render(\n        profile_renderer, profile_name, profile_name_override, target_override, threads_override\n    )\n    # Save env_vars encountered in rendering for partial parsing\n    profile.profile_env_vars = profile_renderer.ctx_obj.env_vars\n    return profile\n\n\ndef _project_quoting_dict(proj: Project, profile: Profile) -> Dict[ComponentName, bool]:\n    src: Dict[str, Any] = profile.credentials.translate_aliases(proj.quoting)\n    result: Dict[ComponentName, bool] = {}\n    for key in ComponentName:\n        if key in src:\n            value = src[key]\n            if isinstance(value, bool):\n                result[key] = value\n    return result\n\n\n@dataclass\nclass RuntimeConfig(Project, Profile, AdapterRequiredConfig):\n    args: Any\n    profile_name: str\n    cli_vars: Dict[str, Any]\n    dependencies: Optional[Mapping[str, \"RuntimeConfig\"]] = None\n\n    def __post_init__(self):\n        self.validate()\n\n    @classmethod\n    def get_profile(\n        cls,\n        project_root: str,\n        cli_vars: Dict[str, Any],\n        args: Any,\n    ) -> Profile:\n        return load_profile(\n            project_root,\n            cli_vars,\n            args.profile,\n            args.target,\n            args.threads,\n        )\n\n    # Called by 'new_project' and 'from_args'\n    @classmethod\n    def from_parts(\n        cls,\n        project: Project,\n        profile: Profile,\n        args: Any,\n        dependencies: Optional[Mapping[str, \"RuntimeConfig\"]] = None,\n    ) -> \"RuntimeConfig\":\n        \"\"\"Instantiate a RuntimeConfig from its components.\n\n        :param profile: A parsed dbt Profile.\n        :param project: A parsed dbt Project.\n        :param args: The parsed command-line arguments.\n        :returns RuntimeConfig: The new configuration.\n        \"\"\"\n        quoting: Dict[str, Any] = (\n            get_relation_class_by_name(profile.credentials.type)\n            .get_default_quote_policy()\n            .replace_dict(_project_quoting_dict(project, profile))\n        ).to_dict(omit_none=True)\n\n        cli_vars: Dict[str, Any] = getattr(args, \"vars\", {})\n        log_cache_events: bool = getattr(args, \"log_cache_events\", profile.log_cache_events)\n\n        return cls(\n            project_name=project.project_name,\n            version=project.version,\n            project_root=project.project_root,\n            model_paths=project.model_paths,\n            macro_paths=project.macro_paths,\n            seed_paths=project.seed_paths,\n            test_paths=project.test_paths,\n            analysis_paths=project.analysis_paths,\n            docs_paths=project.docs_paths,\n            asset_paths=project.asset_paths,\n            function_paths=project.function_paths,\n            target_path=project.target_path,\n            snapshot_paths=project.snapshot_paths,\n            clean_targets=project.clean_targets,\n            log_path=project.log_path,\n            packages_install_path=project.packages_install_path,\n            packages_specified_path=project.packages_specified_path,\n            quoting=quoting,\n            models=project.models,\n            on_run_start=project.on_run_start,\n            on_run_end=project.on_run_end,\n            dispatch=project.dispatch,\n            seeds=project.seeds,\n            snapshots=project.snapshots,\n            dbt_version=project.dbt_version,\n            packages=project.packages,\n            manifest_selectors=project.manifest_selectors,\n            selectors=project.selectors,\n            query_comment=project.query_comment,\n            sources=project.sources,\n            data_tests=project.data_tests,\n            unit_tests=project.unit_tests,\n            metrics=project.metrics,\n            semantic_models=project.semantic_models,\n            saved_queries=project.saved_queries,\n            exposures=project.exposures,\n            functions=project.functions,\n            vars=project.vars,\n            config_version=project.config_version,\n            unrendered=project.unrendered,\n            project_env_vars=project.project_env_vars,\n            restrict_access=project.restrict_access,\n            profile_env_vars=profile.profile_env_vars,\n            profile_name=profile.profile_name,\n            target_name=profile.target_name,\n            threads=profile.threads,\n            credentials=profile.credentials,\n            args=args,\n            cli_vars=cli_vars,\n            log_cache_events=log_cache_events,\n            dependencies=dependencies,\n            dbt_cloud=project.dbt_cloud,\n            flags=project.flags,\n            vars_from_file=project.vars_from_file,\n        )\n\n    # Called by 'load_projects' in this class\n    def new_project(self, project_root: str) -> \"RuntimeConfig\":\n        \"\"\"Given a new project root, read in its project dictionary, supply the\n        existing project's profile info, and create a new project file.\n\n        :param project_root: A filepath to a dbt project.\n        :raises DbtProfileError: If the profile is invalid.\n        :raises DbtProjectError: If project is missing or invalid.\n        :returns: The new configuration.\n        \"\"\"\n        # copy profile\n        profile = Profile(**self.to_profile_info())\n        profile.validate()\n\n        # load the new project and its packages. Don't pass cli variables.\n        renderer = DbtProjectYamlRenderer(profile)\n        project = Project.from_project_root(\n            project_root,\n            renderer,\n            verify_version=bool(getattr(self.args, \"VERSION_CHECK\", True)),\n        )\n\n        runtime_config = self.from_parts(\n            project=project,\n            profile=profile,\n            args=deepcopy(self.args),\n        )\n        # force our quoting back onto the new project.\n        runtime_config.quoting = deepcopy(self.quoting)\n        return runtime_config\n\n    def serialize(self) -> Dict[str, Any]:\n        \"\"\"Serialize the full configuration to a single dictionary. For any\n        instance that has passed validate() (which happens in __init__), it\n        matches the Configuration contract.\n\n        Note that args are not serialized.\n\n        :returns dict: The serialized configuration.\n        \"\"\"\n        result = self.to_project_config(with_packages=True)\n        result.update(self.to_profile_info(serialize_credentials=True))\n        result[\"cli_vars\"] = deepcopy(self.cli_vars)\n        return result\n\n    def validate(self):\n        \"\"\"Validate the configuration against its contract.\n\n        :raises DbtProjectError: If the configuration fails validation.\n        \"\"\"\n        try:\n            Configuration.validate(self.serialize())\n        except ValidationError as e:\n            raise ConfigContractBrokenError(e) from e\n\n    # Called by RuntimeConfig.from_args\n    @classmethod\n    def collect_parts(cls: Type[\"RuntimeConfig\"], args: Any) -> Tuple[Project, Profile]:\n        # profile_name from the project\n        project_root = args.project_dir if args.project_dir else os.getcwd()\n        cli_vars: Dict[str, Any] = getattr(args, \"vars\", {})\n        profile = cls.get_profile(\n            project_root,\n            cli_vars,\n            args,\n        )\n        flags = get_flags()\n        # For dbt deps, use lenient var validation to allow missing vars\n        # For all other commands, use strict validation for helpful error messages\n        # If command is not set (e.g., during test setup), default to strict mode\n        # unless the command is explicitly \"deps\"\n        require_vars = getattr(flags, \"WHICH\", None) != \"deps\"\n        project = load_project(\n            project_root, bool(flags.VERSION_CHECK), profile, cli_vars, require_vars=require_vars\n        )\n        return project, profile\n\n    # Called in task/base.py, in BaseTask.from_args\n    @classmethod\n    def from_args(cls, args: Any) -> \"RuntimeConfig\":\n        \"\"\"Given arguments, read in dbt_project.yml from the current directory,\n        read in packages.yml if it exists, and use them to find the profile to\n        load.\n\n        :param args: The arguments as parsed from the cli.\n        :raises DbtProjectError: If the project is invalid or missing.\n        :raises DbtProfileError: If the profile is invalid or missing.\n        :raises DbtValidationError: If the cli variables are invalid.\n        \"\"\"\n        project, profile = cls.collect_parts(args)\n\n        return cls.from_parts(\n            project=project,\n            profile=profile,\n            args=args,\n        )\n\n    def get_metadata(self) -> ManifestMetadata:\n        return ManifestMetadata(\n            project_name=self.project_name,\n            project_id=self.hashed_name(),\n            user_id=tracking.active_user.id if tracking.active_user else None,\n            send_anonymous_usage_stats=(\n                get_flags().SEND_ANONYMOUS_USAGE_STATS if tracking.active_user else None\n            ),\n            adapter_type=self.credentials.type,\n            quoting=Quoting(\n                database=self.quoting.get(\"database\", None),\n                schema=self.quoting.get(\"schema\", None),\n                identifier=self.quoting.get(\"identifier\", None),\n                column=self.quoting.get(\"column\", None),\n            ),\n            run_started_at=(\n                tracking.active_user.run_started_at if tracking.active_user is not None else None\n            ),\n        )\n\n    def _get_v2_config_paths(\n        self,\n        config,\n        path: FQNPath,\n        paths: MutableSet[FQNPath],\n    ) -> PathSet:\n        for key, value in config.items():\n            if isinstance(value, dict) and not key.startswith(\"+\"):\n                self._get_config_paths(value, path + (key,), paths)\n            else:\n                paths.add(path)\n        return frozenset(paths)\n\n    def _get_config_paths(\n        self,\n        config: Dict[str, Any],\n        path: FQNPath = (),\n        paths: Optional[MutableSet[FQNPath]] = None,\n    ) -> PathSet:\n        if paths is None:\n            paths = set()\n\n        for key, value in config.items():\n            if isinstance(value, dict) and not key.startswith(\"+\"):\n                self._get_v2_config_paths(value, path + (key,), paths)\n            else:\n                paths.add(path)\n        return frozenset(paths)\n\n    def get_resource_config_paths(self) -> Dict[str, PathSet]:\n        \"\"\"Return a dictionary with resource type keys whose values are\n        lists of lists of strings, where each inner list of strings represents\n        a configured path in the resource.\n        \"\"\"\n        return {\n            \"models\": self._get_config_paths(self.models),\n            \"seeds\": self._get_config_paths(self.seeds),\n            \"snapshots\": self._get_config_paths(self.snapshots),\n            \"sources\": self._get_config_paths(self.sources),\n            \"data_tests\": self._get_config_paths(self.data_tests),\n            \"unit_tests\": self._get_config_paths(self.unit_tests),\n            \"metrics\": self._get_config_paths(self.metrics),\n            \"semantic_models\": self._get_config_paths(self.semantic_models),\n            \"saved_queries\": self._get_config_paths(self.saved_queries),\n            \"exposures\": self._get_config_paths(self.exposures),\n            \"functions\": self._get_config_paths(self.functions),\n        }\n\n    def warn_for_unused_resource_config_paths(\n        self,\n        resource_fqns: Mapping[str, PathSet],\n        disabled: PathSet,\n    ) -> None:\n        \"\"\"Return a list of lists of strings, where each inner list of strings\n        represents a type + FQN path of a resource configuration that is not\n        used.\n        \"\"\"\n        disabled_fqns = frozenset(tuple(fqn) for fqn in disabled)\n        resource_config_paths = self.get_resource_config_paths()\n        unused_resource_config_paths = []\n        for resource_type, config_paths in resource_config_paths.items():\n            used_fqns = resource_fqns.get(resource_type, frozenset())\n            fqns = used_fqns | disabled_fqns\n\n            for config_path in config_paths:\n                if not _is_config_used(config_path, fqns):\n                    resource_path = \".\".join(i for i in ((resource_type,) + config_path))\n                    unused_resource_config_paths.append(resource_path)\n\n        if len(unused_resource_config_paths) == 0:\n            return\n\n        warn_or_error(UnusedResourceConfigPath(unused_config_paths=unused_resource_config_paths))\n\n    def load_dependencies(self, base_only=False) -> Mapping[str, \"RuntimeConfig\"]:\n        if self.dependencies is None:\n            all_projects = {self.project_name: self}\n            internal_packages = get_include_paths(self.credentials.type)\n            if base_only:\n                # Test setup -- we want to load macros without dependencies\n                project_paths = itertools.chain(internal_packages)\n            else:\n                locked_packages = load_package_lock_config(self.project_root)\n                specified_packages = locked_packages.packages\n\n                if not specified_packages:\n                    specified_packages = self.packages.packages\n\n                specified_package_names = {\n                    p.name for p in locked_packages.packages if p.name is not None\n                }\n                installed_package_names = {p.stem for p in self._get_project_directories()}\n\n                count_packages_specified = len(specified_packages)\n                count_packages_installed = len(installed_package_names)\n\n                uninstalled_packages = specified_package_names - installed_package_names\n\n                # we expect same number of packages specified and installed\n                if count_packages_specified != count_packages_installed:\n                    raise UninstalledPackagesFoundError(\n                        count_packages_installed,\n                        count_packages_specified,\n                        packages_specified_path=self.packages_specified_path,\n                        packages_install_path=self.packages_install_path,\n                        uninstalled_packages=tuple(uninstalled_packages),\n                    )\n                project_paths = itertools.chain(internal_packages, self._get_project_directories())\n            for project_name, project in self.load_projects(project_paths):\n                if project_name in all_projects:\n                    raise NonUniquePackageNameError(project_name)\n                all_projects[project_name] = project\n            self.dependencies = all_projects\n        return self.dependencies\n\n    def clear_dependencies(self):\n        self.dependencies = None\n\n    # Called by 'load_dependencies' in this class\n    def load_projects(self, paths: Iterable[Path]) -> Iterator[Tuple[str, \"RuntimeConfig\"]]:\n        for path in paths:\n            try:\n                project = self.new_project(str(path))\n            except DbtProjectError as e:\n                raise DbtProjectError(\n                    f\"Failed to read package: {e}\",\n                    result_type=\"invalid_project\",\n                    path=path,\n                ) from e\n            else:\n                yield project.project_name, project\n\n    def _get_project_directories(self) -> Iterator[Path]:\n        root = Path(self.project_root) / self.packages_install_path\n\n        if root.exists():\n            for path in root.iterdir():\n                if path.is_dir() and not path.name.startswith(\"__\"):\n                    yield path\n\n\nclass UnsetCredentials(Credentials):\n    def __init__(self) -> None:\n        super().__init__(\"\", \"\")\n\n    @property\n    def type(self):\n        return None\n\n    @property\n    def unique_field(self):\n        return None\n\n    def connection_info(self, *args, **kwargs):\n        return {}\n\n    def _connection_keys(self):\n        return ()\n\n\n# This is used by commands which do not require\n# a profile, i.e. dbt deps and clean\nclass UnsetProfile(Profile):\n    def __init__(self):\n        self.credentials = UnsetCredentials()\n        self.profile_name = \"\"\n        self.target_name = \"\"\n        self.threads = -1\n\n    def to_target_dict(self):\n        return DictDefaultEmptyStr({})\n\n    def __getattribute__(self, name):\n        if name in {\"profile_name\", \"target_name\", \"threads\"}:\n            raise DbtRuntimeError(f'Error: disallowed attribute \"{name}\" - no profile!')\n\n        return Profile.__getattribute__(self, name)\n\n\nUNUSED_RESOURCE_CONFIGURATION_PATH_MESSAGE = \"\"\"\\\nConfiguration paths exist in your dbt_project.yml file which do not \\\napply to any resources.\nThere are {} unused configuration paths:\n{}\n\"\"\"\n\n\ndef _is_config_used(path, fqns):\n    if fqns:\n        for fqn in fqns:\n            if len(path) <= len(fqn) and fqn[: len(path)] == path:\n                return True\n    return False\n"
  },
  {
    "path": "core/dbt/config/selectors.py",
    "content": "from copy import deepcopy\nfrom pathlib import Path\nfrom typing import Any, Dict, Optional, Union\n\nfrom dbt.clients.yaml_helper import Dumper, Loader, load_yaml_text, yaml  # noqa: F401\nfrom dbt.contracts.selection import SelectorFile\nfrom dbt.exceptions import DbtSelectorsError\nfrom dbt.graph import SelectionSpec, parse_from_selectors_definition\nfrom dbt.graph.selector_spec import SelectionCriteria\nfrom dbt_common.clients.system import (\n    load_file_contents,\n    path_exists,\n    resolve_path_from_base,\n)\nfrom dbt_common.dataclass_schema import ValidationError\nfrom dbt_common.exceptions import DbtRuntimeError\n\nfrom .renderer import BaseRenderer\n\nMALFORMED_SELECTOR_ERROR = \"\"\"\\\nThe selectors.yml file in this project is malformed. Please double check\nthe contents of this file and fix any errors before retrying.\n\nYou can find more information on the syntax for this file here:\nhttps://docs.getdbt.com/reference/node-selection/yaml-selectors\n\nValidator Error:\n{error}\n\"\"\"\n\n\nclass SelectorConfig(Dict[str, Dict[str, Union[SelectionSpec, bool]]]):\n    @classmethod\n    def selectors_from_dict(cls, data: Dict[str, Any]) -> \"SelectorConfig\":\n        try:\n            SelectorFile.validate(data)\n            selector_file = SelectorFile.from_dict(data)\n            validate_selector_default(selector_file)\n            selectors = parse_from_selectors_definition(selector_file)\n        except ValidationError as exc:\n            yaml_sel_cfg = yaml.dump(exc.instance)\n            raise DbtSelectorsError(\n                f\"Could not parse selector file data: \\n{yaml_sel_cfg}\\n\"\n                f\"Valid root-level selector definitions: \"\n                f\"union, intersection, string, dictionary. No lists. \"\n                f\"\\nhttps://docs.getdbt.com/reference/node-selection/\"\n                f\"yaml-selectors\",\n                result_type=\"invalid_selector\",\n            ) from exc\n        except DbtRuntimeError as exc:\n            raise DbtSelectorsError(\n                f\"Could not read selector file data: {exc}\",\n                result_type=\"invalid_selector\",\n            ) from exc\n\n        return cls(selectors)\n\n    @classmethod\n    def render_from_dict(\n        cls,\n        data: Dict[str, Any],\n        renderer: BaseRenderer,\n    ) -> \"SelectorConfig\":\n        try:\n            rendered = renderer.render_data(data)\n        except (ValidationError, DbtRuntimeError) as exc:\n            raise DbtSelectorsError(\n                f\"Could not render selector data: {exc}\",\n                result_type=\"invalid_selector\",\n            ) from exc\n        return cls.selectors_from_dict(rendered)\n\n    @classmethod\n    def from_path(\n        cls,\n        path: Path,\n        renderer: BaseRenderer,\n    ) -> \"SelectorConfig\":\n        try:\n            data = load_yaml_text(load_file_contents(str(path)))\n            if data is None:\n                raise ValidationError(\"No data found in selector file at path: {path}\")\n        except (ValidationError, DbtRuntimeError) as exc:\n            raise DbtSelectorsError(\n                f\"Could not read selector file: {exc}\",\n                result_type=\"invalid_selector\",\n                path=path,\n            ) from exc\n\n        try:\n            return cls.render_from_dict(data, renderer)\n        except DbtSelectorsError as exc:\n            exc.path = path\n            raise\n\n\ndef selector_data_from_root(project_root: str) -> Optional[Dict[str, Any]]:\n    selector_filepath = resolve_path_from_base(\"selectors.yml\", project_root)\n\n    if path_exists(selector_filepath):\n        selectors_dict = load_yaml_text(load_file_contents(selector_filepath))\n    else:\n        selectors_dict = None\n    return selectors_dict\n\n\ndef selector_config_from_data(selectors_data: Dict[str, Any]) -> SelectorConfig:\n    if not selectors_data:\n        selectors_data = {\"selectors\": []}\n\n    try:\n        selectors = SelectorConfig.selectors_from_dict(selectors_data)\n    except ValidationError as e:\n        raise DbtSelectorsError(\n            MALFORMED_SELECTOR_ERROR.format(error=str(e.message)),\n            result_type=\"invalid_selector\",\n        ) from e\n    return selectors\n\n\ndef validate_selector_default(selector_file: SelectorFile) -> None:\n    \"\"\"Check if a selector.yml file has more than 1 default key set to true\"\"\"\n    default_set: bool = False\n    default_selector_name: Union[str, None] = None\n\n    for selector in selector_file.selectors:\n        if selector.default is True and default_set is False:\n            default_set = True\n            default_selector_name = selector.name\n            continue\n        if selector.default is True and default_set is True:\n            raise DbtSelectorsError(\n                \"Error when parsing the selector file. \"\n                \"Found multiple selectors with `default: true`:\"\n                f\"{default_selector_name} and {selector.name}\"\n            )\n\n\n# These are utilities to clean up the dictionary created from\n# selectors.yml by turning the cli-string format entries into\n# normalized dictionary entries. It parallels the flow in\n# dbt/graph/cli.py. If changes are made there, it might\n# be necessary to make changes here. Ideally it would be\n# good to combine the two flows into one at some point.\nclass SelectorDict:\n    @classmethod\n    def parse_dict_definition(cls, definition, selector_dict={}):\n        key = list(definition)[0]\n        value = definition[key]\n        if isinstance(value, list):\n            new_values = []\n            for sel_def in value:\n                new_value = cls.parse_from_definition(sel_def, selector_dict=selector_dict)\n                new_values.append(new_value)\n            value = new_values\n        if key == \"exclude\":\n            definition = {key: value}\n        elif len(definition) == 1:\n            definition = {\"method\": key, \"value\": value}\n        return definition\n\n    @classmethod\n    def parse_a_definition(cls, def_type, definition, selector_dict={}):\n        # this definition must be a list\n        new_dict = {def_type: []}\n        for sel_def in definition[def_type]:\n            if isinstance(sel_def, dict):\n                sel_def = cls.parse_from_definition(sel_def, selector_dict=selector_dict)\n                new_dict[def_type].append(sel_def)\n            elif isinstance(sel_def, str):\n                sel_def = SelectionCriteria.dict_from_single_spec(sel_def)\n                new_dict[def_type].append(sel_def)\n            else:\n                new_dict[def_type].append(sel_def)\n        return new_dict\n\n    @classmethod\n    def parse_from_definition(cls, definition, selector_dict={}):\n        if isinstance(definition, str):\n            definition = SelectionCriteria.dict_from_single_spec(definition)\n        elif \"union\" in definition:\n            definition = cls.parse_a_definition(\"union\", definition, selector_dict=selector_dict)\n        elif \"intersection\" in definition:\n            definition = cls.parse_a_definition(\n                \"intersection\", definition, selector_dict=selector_dict\n            )\n        elif isinstance(definition, dict):\n            definition = cls.parse_dict_definition(definition, selector_dict=selector_dict)\n        return definition\n\n    # This is the normal entrypoint of this code. Give it the\n    # list of selectors generated from the selectors.yml file.\n    @classmethod\n    def parse_from_selectors_list(cls, selectors):\n        selector_dict = {}\n        for selector in selectors:\n            sel_name = selector[\"name\"]\n            selector_dict[sel_name] = selector\n            definition = cls.parse_from_definition(\n                selector[\"definition\"], selector_dict=deepcopy(selector_dict)\n            )\n            selector_dict[sel_name][\"definition\"] = definition\n        return selector_dict\n"
  },
  {
    "path": "core/dbt/config/utils.py",
    "content": "from typing import Any, Dict, Optional\n\nfrom dbt import deprecations\nfrom dbt.clients import yaml_helper\nfrom dbt.events.types import InvalidOptionYAML\nfrom dbt.exceptions import DbtExclusivePropertyUseError, OptionNotYamlDictError\nfrom dbt_common.events.functions import fire_event\nfrom dbt_common.exceptions import DbtValidationError\n\n\ndef parse_cli_vars(var_string: str) -> Dict[str, Any]:\n    return parse_cli_yaml_string(var_string, \"vars\")\n\n\ndef parse_cli_yaml_string(var_string: str, cli_option_name: str) -> Dict[str, Any]:\n    try:\n        cli_vars = yaml_helper.load_yaml_text(var_string)\n        var_type = type(cli_vars)\n        if cli_vars is not None and var_type is dict:\n            return cli_vars\n        else:\n            raise OptionNotYamlDictError(var_type, cli_option_name)\n    except (DbtValidationError, OptionNotYamlDictError):\n        fire_event(InvalidOptionYAML(option_name=cli_option_name))\n        raise\n\n\ndef exclusive_primary_alt_value_setting(\n    dictionary: Optional[Dict[str, Any]],\n    primary: str,\n    alt: str,\n    parent_config: Optional[str] = None,\n) -> None:\n    \"\"\"Munges in place under the primary the options for the primary and alt values\n\n    Sometimes we allow setting something via TWO keys, but not at the same time. If both the primary\n    key and alt key have values, an error gets raised. If the alt key has values, then we update\n    the dictionary to ensure the primary key contains the values. If neither are set, nothing happens.\n    \"\"\"\n\n    if dictionary is None:\n        return\n\n    primary_options = dictionary.get(primary)\n    alt_options = dictionary.get(alt)\n\n    if primary_options and alt_options:\n        where = f\" in `{parent_config}`\" if parent_config is not None else \"\"\n        raise DbtExclusivePropertyUseError(\n            f\"Only `{alt}` or `{primary}` can be specified{where}, not both\"\n        )\n\n    if alt in dictionary:\n        alt_value = dictionary.pop(alt)\n        dictionary[primary] = alt_value\n\n\ndef normalize_warn_error_options(warn_error_options: Dict[str, Any]) -> None:\n    has_include = \"include\" in warn_error_options\n    has_exclude = \"exclude\" in warn_error_options\n\n    if has_include or has_exclude:\n        deprecations.buffer(\n            \"weo-include-exclude-deprecation\",\n            found_include=has_include,\n            found_exclude=has_exclude,\n        )\n\n    exclusive_primary_alt_value_setting(\n        warn_error_options, \"error\", \"include\", \"warn_error_options\"\n    )\n    exclusive_primary_alt_value_setting(\n        warn_error_options, \"warn\", \"exclude\", \"warn_error_options\"\n    )\n    for key in (\"error\", \"warn\", \"silence\"):\n        if key in warn_error_options and warn_error_options[key] is None:\n            warn_error_options[key] = []\n"
  },
  {
    "path": "core/dbt/constants.py",
    "content": "from dbt_semantic_interfaces.type_enums import TimeGranularity\n\nDEFAULT_ENV_PLACEHOLDER = \"DBT_DEFAULT_PLACEHOLDER\"\n\nSECRET_PLACEHOLDER = \"$$$DBT_SECRET_START$$${}$$$DBT_SECRET_END$$$\"\n\nMAXIMUM_SEED_SIZE = 1 * 1024 * 1024\nMAXIMUM_SEED_SIZE_NAME = \"1MB\"\n\nPIN_PACKAGE_URL = (\n    \"https://docs.getdbt.com/docs/package-management#section-specifying-package-versions\"\n)\n\nDBT_PROJECT_FILE_NAME = \"dbt_project.yml\"\nVARS_FILE_NAME = \"vars.yml\"\nPACKAGES_FILE_NAME = \"packages.yml\"\nDEPENDENCIES_FILE_NAME = \"dependencies.yml\"\nPACKAGE_LOCK_FILE_NAME = \"package-lock.yml\"\nMANIFEST_FILE_NAME = \"manifest.json\"\nSEMANTIC_MANIFEST_FILE_NAME = \"semantic_manifest.json\"\nLEGACY_TIME_SPINE_MODEL_NAME = \"metricflow_time_spine\"\nLEGACY_TIME_SPINE_GRANULARITY = TimeGranularity.DAY\nMINIMUM_REQUIRED_TIME_SPINE_GRANULARITY = TimeGranularity.DAY\nPARTIAL_PARSE_FILE_NAME = \"partial_parse.msgpack\"\nPACKAGE_LOCK_HASH_KEY = \"sha1_hash\"\nCATALOGS_FILE_NAME = \"catalogs.yml\"\nRUN_RESULTS_FILE_NAME = \"run_results.json\"\nCATALOG_FILENAME = \"catalog.json\"\nSOURCE_RESULT_FILE_NAME = \"sources.json\"\n"
  },
  {
    "path": "core/dbt/context/README.md",
    "content": "# Contexts and Jinja rendering\n\nContexts are used for Jinja rendering. They include context methods, executable macros, and various settings that are available in Jinja. Refer to [YAML tips and tricks}(https://docs.getdbt.com/docs/build/dbt-tips#yaml-tips) for more information.\n\nThe most common entrypoint to Jinja rendering in dbt is a method named `get_rendered`, which takes two arguments: templated code (string), and a context used to render it (dictionary).\n\nThe context is the bundle of information that is in \"scope\" when rendering Jinja-templated code. For instance, imagine a simple Jinja template:\n```\n{% set new_value = some_macro(some_variable) %}\n```\nBoth `some_macro()` and `some_variable` must be defined in that context. Otherwise, it will raise an error when rendering.\n\nDifferent contexts are used in different places because we allow access to different methods and data in different places. Executable SQL, for example, includes all available macros and the model being run. The variables and macros in scope for Jinja defined in yaml files is much more limited.\n\n### Implementation\n\nThe context that is passed to Jinja is always in a dictionary format, not an actual class, so a `to_dict()` is executed on a context class before it is used for rendering.\n\nEach context has a `generate_<name>_context` function to create the context. `ProviderContext` subclasses have different generate functions for parsing and for execution, so that certain functions (notably `ref`, `source`, and `config`) can return different results\n\n### Hierarchy\n\nAll contexts inherit from the `BaseContext`, which includes \"pure\" methods (e.g. `tojson`), `env_var()`, and `var()` (but only CLI values, passed via `--vars`).\n\nMethods available in parent contexts are also available in child contexts.\n\n```\n   BaseContext -- core/dbt/context/base.py\n     SecretContext -- core/dbt/context/secret.py\n     TargetContext -- core/dbt/context/target.py\n       ConfiguredContext -- core/dbt/context/configured.py\n         SchemaYamlContext -- core/dbt/context/configured.py\n           DocsRuntimeContext -- core/dbt/context/configured.py\n         MacroResolvingContext -- core/dbt/context/configured.py\n         ManifestContext -- core/dbt/context/manifest.py\n           QueryHeaderContext -- core/dbt/context/manifest.py\n           ProviderContext -- core/dbt/context/provider.py\n             MacroContext -- core/dbt/context/provider.py\n             ModelContext -- core/dbt/context/provider.py\n             TestContext -- core/dbt/context/provider.py\n```\n\n### Contexts for configuration\n\nContexts for rendering \"special\" `.yml` (configuration) files:\n- `SecretContext`: Supports \"secret\" env vars, which are prefixed with `DBT_ENV_SECRET_`. Used for rendering in `profiles.yml` and `packages.yml` ONLY. Secrets defined elsewhere will raise explicit errors.\n- `TargetContext`: The same as `Base`, plus `target` (connection profile). Used most notably in `dbt_project.yml` and `selectors.yml`.\n\nContexts for other `.yml` files in the project:\n- `SchemaYamlContext`: Supports `vars` declared on the CLI and in `dbt_project.yml`. Does not support custom macros, beyond `var()` + `env_var()` methods. Used for all `.yml` files, to define properties and configuration.\n- `DocsRuntimeContext`: Standard `.yml` file context, plus `doc()` method (with all `docs` blocks in scope). Used to resolve `description` properties.\n"
  },
  {
    "path": "core/dbt/context/__init__.py",
    "content": ""
  },
  {
    "path": "core/dbt/context/base.py",
    "content": "from __future__ import annotations\n\nimport datetime\nimport itertools\nimport json\nimport os\nimport re\nimport threading\nfrom typing import Any, Callable, Dict, Iterable, List, Mapping, NoReturn, Optional, Set\n\n# These modules are added to the context. Consider alternative\n# approaches which will extend well to potentially many modules\nimport pytz\n\nimport dbt.deprecations as deprecations\nimport dbt.flags as flags_module\nfrom dbt import tracking, utils\nfrom dbt.clients.jinja import get_rendered\nfrom dbt.clients.yaml_helper import (  # noqa: F401\n    Dumper,\n    Loader,\n    SafeLoader,\n    safe_load,\n    yaml,\n)\nfrom dbt.constants import DEFAULT_ENV_PLACEHOLDER, SECRET_PLACEHOLDER\nfrom dbt.contracts.graph.nodes import Resource\nfrom dbt.events.types import JinjaLogDebug, JinjaLogInfo\nfrom dbt.exceptions import (\n    EnvVarMissingError,\n    RequiredVarNotFoundError,\n    SecretEnvVarLocationError,\n    SetStrictWrongTypeError,\n    ZipStrictWrongTypeError,\n)\nfrom dbt.flags import get_flags\nfrom dbt.version import __version__ as dbt_version\nfrom dbt_common.constants import SECRET_ENV_PREFIX\nfrom dbt_common.context import get_invocation_context\nfrom dbt_common.events.contextvars import get_node_info\nfrom dbt_common.events.functions import fire_event, get_invocation_id\nfrom dbt_common.events.types import PrintEvent\nfrom dbt_common.exceptions.macros import MacroReturn\n\n# See the `contexts` module README for more information on how contexts work\n\n\ndef get_pytz_module_context() -> Dict[str, Any]:\n    context_exports = pytz.__all__  # type: ignore\n\n    return {name: getattr(pytz, name) for name in context_exports}\n\n\ndef get_datetime_module_context() -> Dict[str, Any]:\n    context_exports = [\"date\", \"datetime\", \"time\", \"timedelta\", \"tzinfo\"]\n\n    return {name: getattr(datetime, name) for name in context_exports}\n\n\ndef get_re_module_context() -> Dict[str, Any]:\n    # TODO CT-211\n    context_exports = re.__all__  # type: ignore[attr-defined]\n\n    return {name: getattr(re, name) for name in context_exports}\n\n\ndef get_itertools_module_context() -> Dict[str, Any]:\n    # Excluded dropwhile, filterfalse, takewhile and groupby;\n    # first 3 illogical for Jinja and last redundant.\n    context_exports = [\n        \"count\",\n        \"cycle\",\n        \"repeat\",\n        \"accumulate\",\n        \"chain\",\n        \"compress\",\n        \"islice\",\n        \"starmap\",\n        \"tee\",\n        \"zip_longest\",\n        \"product\",\n        \"permutations\",\n        \"combinations\",\n        \"combinations_with_replacement\",\n    ]\n\n    def deprecation_wrapper(fn):\n        def deprecation_wrapper_inner(*args, **kwargs):\n            deprecations.warn(\"modules-itertools-usage-deprecation\")\n            return fn(*args, **kwargs)\n\n        return deprecation_wrapper_inner\n\n    return {name: deprecation_wrapper(getattr(itertools, name)) for name in context_exports}\n\n\ndef get_context_modules() -> Dict[str, Dict[str, Any]]:\n    return {\n        \"pytz\": get_pytz_module_context(),\n        \"datetime\": get_datetime_module_context(),\n        \"re\": get_re_module_context(),\n        \"itertools\": get_itertools_module_context(),\n    }\n\n\nclass ContextMember:\n    def __init__(self, value: Any, name: Optional[str] = None) -> None:\n        self.name = name\n        self.inner = value\n\n    def key(self, default: str) -> str:\n        if self.name is None:\n            return default\n        return self.name\n\n\ndef contextmember(value: Optional[str] = None) -> Callable:\n    return lambda v: ContextMember(v, name=value)\n\n\ndef contextproperty(value: Optional[str] = None) -> Callable:\n    return lambda v: ContextMember(property(v), name=value)\n\n\nclass ContextMeta(type):\n    def __new__(mcls, name, bases, dct: Dict[str, Any]) -> ContextMeta:\n        context_members: Dict[str, Any] = {}\n        context_attrs: Dict[str, Any] = {}\n        new_dct: Dict[str, Any] = {}\n\n        for base in bases:\n            context_members.update(getattr(base, \"_context_members_\", {}))\n            context_attrs.update(getattr(base, \"_context_attrs_\", {}))\n\n        for key, value in dct.items():\n            if isinstance(value, ContextMember):\n                context_key = value.key(key)\n                context_members[context_key] = value.inner\n                context_attrs[context_key] = key\n                value = value.inner\n            new_dct[key] = value\n        new_dct[\"_context_members_\"] = context_members\n        new_dct[\"_context_attrs_\"] = context_attrs\n        return type.__new__(mcls, name, bases, new_dct)\n\n\nclass Var:\n    _VAR_NOTSET = object()\n\n    def __init__(\n        self,\n        context: Mapping[str, Any],\n        cli_vars: Mapping[str, Any],\n        node: Optional[Resource] = None,\n        require_vars: bool = True,\n    ) -> None:\n        self._context: Mapping[str, Any] = context\n        self._cli_vars: Mapping[str, Any] = cli_vars\n        self._node: Optional[Resource] = node\n        self._require_vars: bool = require_vars\n        self._merged: Mapping[str, Any] = self._generate_merged()\n\n    def _generate_merged(self) -> Mapping[str, Any]:\n        return self._cli_vars\n\n    @property\n    def node_name(self) -> str:\n        if self._node is not None:\n            return self._node.name\n        else:\n            return \"<Configuration>\"\n\n    def get_missing_var(self, var_name: str) -> None:\n        # Only raise an error if vars are _required_\n        if self._require_vars:\n            # TODO function name implies a non exception resolution\n            raise RequiredVarNotFoundError(var_name, dict(self._merged), self._node)\n\n    def has_var(self, var_name: str) -> bool:\n        return var_name in self._merged\n\n    def get_rendered_var(self, var_name: str) -> Any:\n        raw = self._merged[var_name]\n        # if bool/int/float/etc are passed in, don't compile anything\n        if not isinstance(raw, str):\n            return raw\n\n        return get_rendered(raw, dict(self._context))\n\n    def __call__(self, var_name: str, default: Any = _VAR_NOTSET) -> Any:\n        if self.has_var(var_name):\n            return self.get_rendered_var(var_name)\n        elif default is not self._VAR_NOTSET:\n            return default\n        else:\n            return self.get_missing_var(var_name)\n\n\nclass BaseContext(metaclass=ContextMeta):\n    # Set by ContextMeta\n    _context_members_: Dict[str, Any]\n    _context_attrs_: Dict[str, Any]\n\n    # subclass is TargetContext\n    def __init__(self, cli_vars: Dict[str, Any], require_vars: bool = True) -> None:\n        self._ctx: Dict[str, Any] = {}\n        self.cli_vars: Dict[str, Any] = cli_vars\n        self.env_vars: Dict[str, Any] = {}\n        self.require_vars: bool = require_vars\n\n    def generate_builtins(self) -> Dict[str, Any]:\n        builtins: Dict[str, Any] = {}\n        for key, value in self._context_members_.items():\n            if hasattr(value, \"__get__\"):\n                # handle properties, bound methods, etc\n                value = value.__get__(self)\n            builtins[key] = value\n        return builtins\n\n    # no dbtClassMixin so this is not an actual override\n    def to_dict(self) -> Dict[str, Any]:\n        self._ctx[\"context\"] = self._ctx\n        builtins = self.generate_builtins()\n        self._ctx[\"builtins\"] = builtins\n        self._ctx.update(builtins)\n        return self._ctx\n\n    @contextproperty()\n    def dbt_version(self) -> str:\n        \"\"\"The `dbt_version` variable returns the installed version of dbt that\n        is currently running. It can be used for debugging or auditing\n        purposes.\n\n        > macros/get_version.sql\n\n            {% macro get_version() %}\n              {% set msg = \"The installed version of dbt is: \" ~ dbt_version %}\n              {% do log(msg, info=true) %}\n            {% endmacro %}\n\n        Example output:\n\n            $ dbt run-operation get_version\n            The installed version of dbt is 0.16.0\n        \"\"\"\n        return dbt_version\n\n    @contextproperty()\n    def var(self) -> Var:\n        \"\"\"Variables can be passed from your `dbt_project.yml` file into models\n        during compilation. These variables are useful for configuring packages\n        for deployment in multiple environments, or defining values that should\n        be used across multiple models within a package.\n\n        To add a variable to a model, use the `var()` function:\n\n        > my_model.sql:\n\n            select * from events where event_type = '{{ var(\"event_type\") }}'\n\n        If you try to run this model without supplying an `event_type`\n        variable, you'll receive a compilation error that looks like this:\n\n            Encountered an error:\n            ! Compilation error while compiling model package_name.my_model:\n            ! Required var 'event_type' not found in config:\n            Vars supplied to package_name.my_model = {\n            }\n\n        To supply a variable to a given model, add one or more `vars`\n        dictionaries to the `models` config in your `dbt_project.yml` file.\n        These `vars` are in-scope for all models at or below where they are\n        defined, so place them where they make the most sense. Below are three\n        different placements of the `vars` dict, all of which will make the\n        `my_model` model compile.\n\n        > dbt_project.yml:\n\n            # 1) scoped at the model level\n            models:\n              package_name:\n                my_model:\n                  materialized: view\n                  vars:\n                    event_type: activation\n            # 2) scoped at the package level\n            models:\n              package_name:\n                vars:\n                  event_type: activation\n                my_model:\n                  materialized: view\n            # 3) scoped globally\n            models:\n              vars:\n                event_type: activation\n              package_name:\n                my_model:\n                  materialized: view\n\n        ## Variable default values\n\n        The `var()` function takes an optional second argument, `default`. If\n        this argument is provided, then it will be the default value for the\n        variable if one is not explicitly defined.\n\n        > my_model.sql:\n\n            -- Use 'activation' as the event_type if the variable is not\n            -- defined.\n            select *\n            from events\n            where event_type = '{{ var(\"event_type\", \"activation\") }}'\n        \"\"\"\n        return Var(self._ctx, self.cli_vars, require_vars=self.require_vars)\n\n    @contextmember()\n    def env_var(self, var: str, default: Optional[str] = None) -> str:\n        \"\"\"The env_var() function. Return the environment variable named 'var'.\n        If there is no such environment variable set, return the default.\n\n        If the default is None, raise an exception for an undefined variable.\n        \"\"\"\n        return_value = None\n        if var.startswith(SECRET_ENV_PREFIX):\n            raise SecretEnvVarLocationError(var)\n        env = get_invocation_context().env\n        if var in env:\n            return_value = env[var]\n        elif default is not None:\n            return_value = default\n\n        if return_value is not None:\n            # If the environment variable is set from a default, store a string indicating\n            # that so we can skip partial parsing.  Otherwise the file will be scheduled for\n            # reparsing. If the default changes, the file will have been updated and therefore\n            # will be scheduled for reparsing anyways.\n            self.env_vars[var] = return_value if var in env else DEFAULT_ENV_PLACEHOLDER\n\n            return return_value\n        else:\n            raise EnvVarMissingError(var)\n\n    if os.environ.get(\"DBT_MACRO_DEBUGGING\"):\n\n        @contextmember()\n        @staticmethod\n        def debug():\n            \"\"\"Enter a debugger at this line in the compiled jinja code.\"\"\"\n            import sys\n\n            import ipdb  # type: ignore\n\n            frame = sys._getframe(3)\n            ipdb.set_trace(frame)\n            return \"\"\n\n    @contextmember(\"return\")\n    @staticmethod\n    def _return(data: Any) -> NoReturn:\n        \"\"\"The `return` function can be used in macros to return data to the\n        caller. The type of the data (`dict`, `list`, `int`, etc) will be\n        preserved through the return call.\n\n        :param data: The data to return to the caller\n\n\n        > macros/example.sql:\n\n            {% macro get_data() %}\n              {{ return([1,2,3]) }}\n            {% endmacro %}\n\n        > models/my_model.sql:\n\n            select\n              -- getdata() returns a list!\n              {% for i in getdata() %}\n                {{ i }}\n                {% if not loop.last %},{% endif %}\n              {% endfor %}\n\n        \"\"\"\n        raise MacroReturn(data)\n\n    @contextmember()\n    @staticmethod\n    def fromjson(string: str, default: Any = None) -> Any:\n        \"\"\"The `fromjson` context method can be used to deserialize a json\n        string into a Python object primitive, eg. a `dict` or `list`.\n\n        :param value: The json string to deserialize\n        :param default: A default value to return if the `string` argument\n            cannot be deserialized (optional)\n\n        Usage:\n\n            {% set my_json_str = '{\"abc\": 123}' %}\n            {% set my_dict = fromjson(my_json_str) %}\n            {% do log(my_dict['abc']) %}\n        \"\"\"\n        try:\n            return json.loads(string)\n        except ValueError:\n            return default\n\n    @contextmember()\n    @staticmethod\n    def tojson(value: Any, default: Any = None, sort_keys: bool = False) -> Any:\n        \"\"\"The `tojson` context method can be used to serialize a Python\n        object primitive, eg. a `dict` or `list` to a json string.\n\n        :param value: The value serialize to json\n        :param default: A default value to return if the `value` argument\n            cannot be serialized\n        :param sort_keys: If True, sort the keys.\n\n\n        Usage:\n\n            {% set my_dict = {\"abc\": 123} %}\n            {% set my_json_string = tojson(my_dict) %}\n            {% do log(my_json_string) %}\n        \"\"\"\n        try:\n            return json.dumps(value, sort_keys=sort_keys)\n        except ValueError:\n            return default\n\n    @contextmember()\n    @staticmethod\n    def fromyaml(value: str, default: Any = None) -> Any:\n        \"\"\"The fromyaml context method can be used to deserialize a yaml string\n        into a Python object primitive, eg. a `dict` or `list`.\n\n        :param value: The yaml string to deserialize\n        :param default: A default value to return if the `string` argument\n            cannot be deserialized (optional)\n\n        Usage:\n\n            {% set my_yml_str -%}\n            dogs:\n             - good\n             - bad\n            {%- endset %}\n            {% set my_dict = fromyaml(my_yml_str) %}\n            {% do log(my_dict['dogs'], info=true) %}\n            -- [\"good\", \"bad\"]\n            {% do my_dict['dogs'].pop() }\n            {% do log(my_dict['dogs'], info=true) %}\n            -- [\"good\"]\n        \"\"\"\n        try:\n            return safe_load(value)\n        except (AttributeError, ValueError, yaml.YAMLError):\n            return default\n\n    # safe_dump defaults to sort_keys=True, but we act like json.dumps (the\n    # opposite)\n    @contextmember()\n    @staticmethod\n    def toyaml(\n        value: Any, default: Optional[str] = None, sort_keys: bool = False\n    ) -> Optional[str]:\n        \"\"\"The `tojson` context method can be used to serialize a Python\n        object primitive, eg. a `dict` or `list` to a yaml string.\n\n        :param value: The value serialize to yaml\n        :param default: A default value to return if the `value` argument\n            cannot be serialized\n        :param sort_keys: If True, sort the keys.\n\n\n        Usage:\n\n            {% set my_dict = {\"abc\": 123} %}\n            {% set my_yaml_string = toyaml(my_dict) %}\n            {% do log(my_yaml_string) %}\n        \"\"\"\n        try:\n            return yaml.safe_dump(data=value, sort_keys=sort_keys)\n        except (ValueError, yaml.YAMLError):\n            return default\n\n    @contextmember(\"set\")\n    @staticmethod\n    def _set(value: Iterable[Any], default: Any = None) -> Optional[Set[Any]]:\n        \"\"\"The `set` context method can be used to convert any iterable\n        to a sequence of iterable elements that are unique (a set).\n\n        :param value: The iterable\n        :param default: A default value to return if the `value` argument\n            is not an iterable\n\n        Usage:\n            {% set my_list = [1, 2, 2, 3] %}\n            {% set my_set = set(my_list) %}\n            {% do log(my_set) %}  {# {1, 2, 3} #}\n        \"\"\"\n        try:\n            return set(value)\n        except TypeError:\n            return default\n\n    @contextmember()\n    @staticmethod\n    def set_strict(value: Iterable[Any]) -> Set[Any]:\n        \"\"\"The `set_strict` context method can be used to convert any iterable\n        to a sequence of iterable elements that are unique (a set). The\n        difference to the `set` context method is that the `set_strict` method\n        will raise an exception on a TypeError.\n\n        :param value: The iterable\n\n        Usage:\n            {% set my_list = [1, 2, 2, 3] %}\n            {% set my_set = set_strict(my_list) %}\n            {% do log(my_set) %}  {# {1, 2, 3} #}\n        \"\"\"\n        try:\n            return set(value)\n        except TypeError as e:\n            raise SetStrictWrongTypeError(e)\n\n    @contextmember(\"zip\")\n    @staticmethod\n    def _zip(*args: Iterable[Any], default: Any = None) -> Optional[Iterable[Any]]:\n        \"\"\"The `zip` context method can be used to used to return\n        an iterator of tuples, where the i-th tuple contains the i-th\n        element from each of the argument iterables.\n\n        :param *args: Any number of iterables\n        :param default: A default value to return if `*args` is not\n            iterable\n\n        Usage:\n            {% set my_list_a = [1, 2] %}\n            {% set my_list_b = ['alice', 'bob'] %}\n            {% set my_zip = zip(my_list_a, my_list_b) | list %}\n            {% do log(my_set) %}  {# [(1, 'alice'), (2, 'bob')] #}\n        \"\"\"\n        try:\n            return zip(*args)\n        except TypeError:\n            return default\n\n    @contextmember()\n    @staticmethod\n    def zip_strict(*args: Iterable[Any]) -> Iterable[Any]:\n        \"\"\"The `zip_strict` context method can be used to used to return\n        an iterator of tuples, where the i-th tuple contains the i-th\n        element from each of the argument iterables. The difference to the\n        `zip` context method is that the `zip_strict` method will raise an\n        exception on a TypeError.\n\n        :param *args: Any number of iterables\n\n        Usage:\n            {% set my_list_a = [1, 2] %}\n            {% set my_list_b = ['alice', 'bob'] %}\n            {% set my_zip = zip_strict(my_list_a, my_list_b) | list %}\n            {% do log(my_set) %}  {# [(1, 'alice'), (2, 'bob')] #}\n        \"\"\"\n        try:\n            return zip(*args)\n        except TypeError as e:\n            raise ZipStrictWrongTypeError(e)\n\n    @contextmember()\n    @staticmethod\n    def log(msg: str, info: bool = False) -> str:\n        \"\"\"Logs a line to either the log file or stdout.\n\n        :param msg: The message to log\n        :param info: If `False`, write to the log file. If `True`, write to\n            both the log file and stdout.\n\n        > macros/my_log_macro.sql\n\n            {% macro some_macro(arg1, arg2) %}\n              {{ log(\"Running some_macro: \" ~ arg1 ~ \", \" ~ arg2) }}\n            {% endmacro %}\"\n        \"\"\"\n        # Detect instances of the placeholder value ($$$DBT_SECRET_START...DBT_SECRET_END$$$)\n        # and replace it with the standard mask '*****'\n        if \"DBT_SECRET_START\" in str(msg):\n            search_group = f\"({SECRET_ENV_PREFIX}(.*))\"\n            pattern = SECRET_PLACEHOLDER.format(search_group).replace(\"$\", r\"\\$\")\n            m = re.search(\n                pattern,\n                msg,\n            )\n            if m:\n                msg = re.sub(pattern, \"*****\", msg)\n\n        if info:\n            fire_event(JinjaLogInfo(msg=msg, node_info=get_node_info()))\n        else:\n            fire_event(JinjaLogDebug(msg=msg, node_info=get_node_info()))\n        return \"\"\n\n    @contextproperty()\n    def run_started_at(self) -> Optional[datetime.datetime]:\n        \"\"\"`run_started_at` outputs the timestamp that this run started, e.g.\n        `2017-04-21 01:23:45.678`. The `run_started_at` variable is a Python\n        `datetime` object. As of 0.9.1, the timezone of this variable defaults\n        to UTC.\n\n        > run_started_at_example.sql\n\n            select\n                '{{ run_started_at.strftime(\"%Y-%m-%d\") }}' as date_day\n            from ...\n\n\n        To modify the timezone of this variable, use the the `pytz` module:\n\n        > run_started_at_utc.sql\n\n            {% set est = modules.pytz.timezone(\"America/New_York\") %}\n            select\n                '{{ run_started_at.astimezone(est) }}' as run_started_est\n            from ...\n        \"\"\"\n        if tracking.active_user is not None:\n            return tracking.active_user.run_started_at\n        else:\n            return None\n\n    @contextproperty()\n    def invocation_id(self) -> Optional[str]:\n        \"\"\"invocation_id outputs a UUID generated for this dbt run (useful for\n        auditing)\n        \"\"\"\n        return get_invocation_id()\n\n    @contextproperty()\n    def thread_id(self) -> str:\n        \"\"\"thread_id outputs an ID for the current thread (useful for auditing)\"\"\"\n        return threading.current_thread().name\n\n    @contextproperty()\n    def modules(self) -> Dict[str, Any]:\n        \"\"\"The `modules` variable in the Jinja context contains useful Python\n        modules for operating on data.\n\n        # datetime\n\n        This variable is a pointer to the Python datetime module.\n\n        Usage:\n\n            {% set dt = modules.datetime.datetime.now() %}\n\n        # pytz\n\n        This variable is a pointer to the Python pytz module.\n\n        Usage:\n\n            {% set dt = modules.datetime.datetime(2002, 10, 27, 6, 0, 0) %}\n            {% set dt_local = modules.pytz.timezone('US/Eastern').localize(dt) %}\n            {{ dt_local }}\n        \"\"\"  # noqa\n        return get_context_modules()\n\n    @contextproperty()\n    def flags(self) -> Any:\n        \"\"\"The `flags` variable contains true/false values for flags provided\n        on the command line.\n\n        > flags.sql:\n\n            {% if flags.FULL_REFRESH %}\n            drop table ...\n            {% else %}\n            -- no-op\n            {% endif %}\n\n        This supports all flags defined in flags submodule (core/dbt/flags.py)\n        \"\"\"\n        return flags_module.get_flag_obj()\n\n    @contextmember()\n    @staticmethod\n    def print(msg: str) -> str:\n        \"\"\"Prints a line to stdout.\n\n        :param msg: The message to print\n\n        > macros/my_log_macro.sql\n\n            {% macro some_macro(arg1, arg2) %}\n              {{ print(\"Running some_macro: \" ~ arg1 ~ \", \" ~ arg2) }}\n            {% endmacro %}\"\n        \"\"\"\n\n        if get_flags().PRINT:\n            # No formatting, still get to stdout when --quiet is used\n            fire_event(PrintEvent(msg=msg))\n        return \"\"\n\n    @contextmember()\n    @staticmethod\n    def diff_of_two_dicts(\n        dict_a: Dict[str, List[str]], dict_b: Dict[str, List[str]]\n    ) -> Dict[str, List[str]]:\n        \"\"\"\n        Given two dictionaries of type Dict[str, List[str]]:\n            dict_a = {'key_x': ['value_1', 'VALUE_2'], 'KEY_Y': ['value_3']}\n            dict_b = {'key_x': ['value_1'], 'key_z': ['value_4']}\n        Return the same dictionary representation of dict_a MINUS dict_b,\n        performing a case-insensitive comparison between the strings in each.\n        All keys returned will be in the original case of dict_a.\n            returns {'key_x': ['VALUE_2'], 'KEY_Y': ['value_3']}\n        \"\"\"\n\n        dict_diff = {}\n        dict_b_lowered = {k.casefold(): [x.casefold() for x in v] for k, v in dict_b.items()}\n        for k in dict_a:\n            if k.casefold() in dict_b_lowered.keys():\n                diff = []\n                for v in dict_a[k]:\n                    if v.casefold() not in dict_b_lowered[k.casefold()]:\n                        diff.append(v)\n                if diff:\n                    dict_diff.update({k: diff})\n            else:\n                dict_diff.update({k: dict_a[k]})\n        return dict_diff\n\n    @contextmember()\n    @staticmethod\n    def local_md5(value: str) -> str:\n        \"\"\"Calculates an MD5 hash of the given string.\n        It's called \"local_md5\" to emphasize that it runs locally in dbt (in jinja context) and not an MD5 SQL command.\n\n        :param value: The value to hash\n\n        Usage:\n            {% set value_hash = local_md5(\"hello world\") %}\n        \"\"\"\n        return utils.md5(value)\n\n\ndef generate_base_context(cli_vars: Dict[str, Any]) -> Dict[str, Any]:\n    ctx = BaseContext(cli_vars)\n    # This is not a Mashumaro to_dict call\n    return ctx.to_dict()\n"
  },
  {
    "path": "core/dbt/context/configured.py",
    "content": "from typing import Any, Dict, Optional\n\nfrom dbt.adapters.contracts.connection import AdapterRequiredConfig\nfrom dbt.constants import DEFAULT_ENV_PLACEHOLDER\nfrom dbt.context.base import Var, contextmember, contextproperty\nfrom dbt.context.target import TargetContext\nfrom dbt.exceptions import EnvVarMissingError, SecretEnvVarLocationError\nfrom dbt.node_types import NodeType\nfrom dbt.utils import MultiDict\nfrom dbt_common.constants import SECRET_ENV_PREFIX\nfrom dbt_common.context import get_invocation_context\n\n\nclass ConfiguredContext(TargetContext):\n    # subclasses are SchemaYamlContext, MacroResolvingContext, ManifestContext\n    config: AdapterRequiredConfig\n\n    def __init__(self, config: AdapterRequiredConfig, require_vars: bool = True) -> None:\n        super().__init__(config.to_target_dict(), config.cli_vars, require_vars=require_vars)\n        self.config = config\n\n    @contextproperty()\n    def project_name(self) -> str:\n        return self.config.project_name\n\n\nclass FQNLookup:\n    def __init__(self, package_name: str):\n        self.package_name = package_name\n        self.fqn = [package_name]\n        self.resource_type = NodeType.Model\n\n\nclass ConfiguredVar(Var):\n    def __init__(\n        self,\n        context: Dict[str, Any],\n        config: AdapterRequiredConfig,\n        project_name: str,\n    ):\n        super().__init__(context, config.cli_vars)\n        self._config = config\n        self._project_name = project_name\n\n    def __call__(self, var_name, default=Var._VAR_NOTSET):\n        my_config = self._config.load_dependencies()[self._project_name]\n\n        # cli vars > active project > local project\n        if var_name in self._config.cli_vars:\n            return self._config.cli_vars[var_name]\n\n        adapter_type = self._config.credentials.type\n        lookup = FQNLookup(self._project_name)\n        active_vars = self._config.vars.vars_for(lookup, adapter_type)\n\n        all_vars = MultiDict()\n        if self._config.project_name != my_config.project_name:\n            all_vars.add(my_config.vars.vars_for(lookup, adapter_type))\n        all_vars.add(active_vars)\n\n        if var_name in all_vars:\n            return all_vars[var_name]\n\n        if default is not Var._VAR_NOTSET:\n            return default\n\n        return self.get_missing_var(var_name)\n\n\nclass SchemaYamlVars:\n    def __init__(self):\n        self.env_vars = {}\n        self.vars = {}\n\n\nclass SchemaYamlContext(ConfiguredContext):\n    # subclass is DocsRuntimeContext\n    def __init__(self, config, project_name: str, schema_yaml_vars: Optional[SchemaYamlVars]):\n        super().__init__(config)\n        self._project_name = project_name\n        self.schema_yaml_vars = schema_yaml_vars\n\n    @contextproperty()\n    def var(self) -> ConfiguredVar:\n        return ConfiguredVar(self._ctx, self.config, self._project_name)\n\n    @contextmember()\n    def env_var(self, var: str, default: Optional[str] = None) -> str:\n        return_value = None\n        if var.startswith(SECRET_ENV_PREFIX):\n            raise SecretEnvVarLocationError(var)\n        env = get_invocation_context().env\n        if var in env:\n            return_value = env[var]\n        elif default is not None:\n            return_value = default\n\n        if return_value is not None:\n            if self.schema_yaml_vars:\n                # If the environment variable is set from a default, store a string indicating\n                # that so we can skip partial parsing.  Otherwise the file will be scheduled for\n                # reparsing. If the default changes, the file will have been updated and therefore\n                # will be scheduled for reparsing anyways.\n                self.schema_yaml_vars.env_vars[var] = (\n                    return_value if var in env else DEFAULT_ENV_PLACEHOLDER\n                )\n\n            return return_value\n        else:\n            raise EnvVarMissingError(var)\n\n\nclass MacroResolvingContext(ConfiguredContext):\n    def __init__(self, config):\n        super().__init__(config)\n\n    @contextproperty()\n    def var(self) -> ConfiguredVar:\n        return ConfiguredVar(self._ctx, self.config, self.config.project_name)\n\n\ndef generate_schema_yml_context(\n    config: AdapterRequiredConfig,\n    project_name: str,\n    schema_yaml_vars: Optional[SchemaYamlVars] = None,\n) -> Dict[str, Any]:\n    ctx = SchemaYamlContext(config, project_name, schema_yaml_vars)\n    return ctx.to_dict()\n\n\ndef generate_macro_context(\n    config: AdapterRequiredConfig,\n) -> Dict[str, Any]:\n    ctx = MacroResolvingContext(config)\n    return ctx.to_dict()\n"
  },
  {
    "path": "core/dbt/context/context_config.py",
    "content": "from abc import abstractmethod\nfrom copy import deepcopy\nfrom dataclasses import dataclass\nfrom typing import Any, Dict, Generic, Iterator, List, Optional, TypeVar\n\nfrom dbt.adapters.factory import get_config_class_by_name\nfrom dbt.config import IsFQNResource, Project, RuntimeConfig\nfrom dbt.contracts.graph.model_config import get_config_for\nfrom dbt.exceptions import SchemaConfigError\nfrom dbt.flags import get_flags\nfrom dbt.node_types import NodeType\nfrom dbt.utils import fqn_search\nfrom dbt_common.contracts.config.base import BaseConfig, merge_config_dicts\nfrom dbt_common.dataclass_schema import ValidationError\nfrom dbt_common.exceptions import DbtInternalError\n\n\n@dataclass\nclass ModelParts(IsFQNResource):\n    fqn: List[str]\n    resource_type: NodeType\n    package_name: str\n\n\nT = TypeVar(\"T\")  # any old type\nC = TypeVar(\"C\", bound=BaseConfig)\n\n\nclass ConfigSource:\n    def __init__(self, project):\n        self.project = project\n\n    def get_config_dict(self, resource_type: NodeType): ...\n\n\nclass UnrenderedConfig(ConfigSource):\n    def __init__(self, project: Project):\n        self.project = project\n\n    def get_config_dict(self, resource_type: NodeType) -> Dict[str, Any]:\n        unrendered = self.project.unrendered.project_dict\n        if resource_type == NodeType.Seed:\n            model_configs = unrendered.get(\"seeds\")\n        elif resource_type == NodeType.Snapshot:\n            model_configs = unrendered.get(\"snapshots\")\n        elif resource_type == NodeType.Source:\n            model_configs = unrendered.get(\"sources\")\n        elif resource_type == NodeType.Test:\n            model_configs = unrendered.get(\"data_tests\")\n        elif resource_type == NodeType.Metric:\n            model_configs = unrendered.get(\"metrics\")\n        elif resource_type == NodeType.SemanticModel:\n            model_configs = unrendered.get(\"semantic_models\")\n        elif resource_type == NodeType.SavedQuery:\n            model_configs = unrendered.get(\"saved_queries\")\n        elif resource_type == NodeType.Exposure:\n            model_configs = unrendered.get(\"exposures\")\n        elif resource_type == NodeType.Unit:\n            model_configs = unrendered.get(\"unit_tests\")\n        else:\n            model_configs = unrendered.get(\"models\")\n        if model_configs is None:\n            return {}\n        else:\n            return model_configs\n\n\nclass RenderedConfig(ConfigSource):\n    def __init__(self, project: Project):\n        self.project = project\n\n    def get_config_dict(self, resource_type: NodeType) -> Dict[str, Any]:\n        if resource_type == NodeType.Seed:\n            model_configs = self.project.seeds\n        elif resource_type == NodeType.Snapshot:\n            model_configs = self.project.snapshots\n        elif resource_type == NodeType.Source:\n            model_configs = self.project.sources\n        elif resource_type == NodeType.Test:\n            model_configs = self.project.data_tests\n        elif resource_type == NodeType.Metric:\n            model_configs = self.project.metrics\n        elif resource_type == NodeType.SemanticModel:\n            model_configs = self.project.semantic_models\n        elif resource_type == NodeType.SavedQuery:\n            model_configs = self.project.saved_queries\n        elif resource_type == NodeType.Exposure:\n            model_configs = self.project.exposures\n        elif resource_type == NodeType.Unit:\n            model_configs = self.project.unit_tests\n        elif resource_type == NodeType.Function:\n            model_configs = self.project.functions\n        else:\n            model_configs = self.project.models\n        return model_configs\n\n\nclass BaseContextConfigGenerator(Generic[T]):\n    def __init__(self, active_project: RuntimeConfig):\n        self._active_project = active_project\n\n    def get_config_source(self, project: Project) -> ConfigSource:\n        return RenderedConfig(project)\n\n    def get_node_project(self, project_name: str):\n        if project_name == self._active_project.project_name:\n            return self._active_project\n        dependencies = self._active_project.load_dependencies()\n        if project_name not in dependencies:\n            raise DbtInternalError(\n                f\"Project name {project_name} not found in dependencies \"\n                f\"(found {list(dependencies)})\"\n            )\n        return dependencies[project_name]\n\n    def _project_configs(\n        self, project: Project, fqn: List[str], resource_type: NodeType\n    ) -> Iterator[Dict[str, Any]]:\n        src = self.get_config_source(project)\n        model_configs = src.get_config_dict(resource_type)\n        for level_config in fqn_search(model_configs, fqn):\n            result = {}\n            for key, value in level_config.items():\n                if key.startswith(\"+\"):\n                    result[key[1:].strip()] = deepcopy(value)\n                elif not isinstance(value, dict):\n                    result[key] = deepcopy(value)\n\n            yield result\n\n    def _active_project_configs(\n        self, fqn: List[str], resource_type: NodeType\n    ) -> Iterator[Dict[str, Any]]:\n        return self._project_configs(self._active_project, fqn, resource_type)\n\n    @abstractmethod\n    def _update_from_config(\n        self, result: T, partial: Dict[str, Any], validate: bool = False\n    ) -> T: ...\n\n    @abstractmethod\n    def initial_result(self, resource_type: NodeType, base: bool) -> T: ...\n\n    def calculate_node_config(\n        self,\n        # this is the config from the sql file\n        config_call_dict: Dict[str, Any],\n        fqn: List[str],\n        resource_type: NodeType,\n        project_name: str,\n        base: bool,\n        # this is the config from the schema file\n        patch_config_dict: Optional[Dict[str, Any]] = None,\n    ) -> BaseConfig:\n        own_config = self.get_node_project(project_name)\n\n        result = self.initial_result(resource_type=resource_type, base=base)\n\n        # builds the config from what was specified in the runtime_config, which generally\n        # comes from the project's dbt_project.yml file.\n        project_configs = self._project_configs(own_config, fqn, resource_type)\n        for fqn_config in project_configs:\n            result = self._update_from_config(result, fqn_config)\n\n        # When schema files patch config, it has lower precedence than\n        # config in the models (config_call_dict), so we add the patch_config_dict\n        # before the config_call_dict\n        if patch_config_dict:\n            result = self._update_from_config(result, patch_config_dict)\n\n        # config_calls are created in the 'experimental' model parser and\n        # the ParseConfigObject (via add_config_call)\n        result = self._update_from_config(result, config_call_dict)\n\n        if own_config.project_name != self._active_project.project_name:\n            for fqn_config in self._active_project_configs(fqn, resource_type):\n                result = self._update_from_config(result, fqn_config)\n\n        # this is mostly impactful in the snapshot config case\n        # TODO CT-211\n        return result  # type: ignore[return-value]\n\n    @abstractmethod\n    def calculate_node_config_dict(\n        self,\n        config_call_dict: Dict[str, Any],\n        fqn: List[str],\n        resource_type: NodeType,\n        project_name: str,\n        base: bool,\n        patch_config_dict: Optional[Dict[str, Any]] = None,\n    ) -> Dict[str, Any]: ...\n\n\nclass ContextConfigGenerator(BaseContextConfigGenerator[C]):\n    def __init__(self, active_project: RuntimeConfig):\n        self._active_project = active_project\n\n    def get_config_source(self, project: Project) -> ConfigSource:\n        return RenderedConfig(project)\n\n    def initial_result(self, resource_type: NodeType, base: bool) -> C:\n        # defaults, own_config, config calls, active_config (if != own_config)\n        config_cls = get_config_for(resource_type, base=base)\n        # Calculate the defaults. We don't want to validate the defaults,\n        # because it might be invalid in the case of required config members\n        # (such as on snapshots!)\n        result = config_cls.from_dict({})\n        return result\n\n    def _update_from_config(self, result: C, partial: Dict[str, Any], validate: bool = False) -> C:\n        translated = self._active_project.credentials.translate_aliases(partial)\n        translated = self.translate_hook_names(translated)\n\n        adapter_type = self._active_project.credentials.type\n        adapter_config_cls = get_config_class_by_name(adapter_type)\n\n        updated = result.update_from(translated, adapter_config_cls, validate=validate)\n        return updated\n\n    def translate_hook_names(self, project_dict):\n        # This is a kind of kludge because the fix for #6411 specifically allowed misspelling\n        # the hook field names in dbt_project.yml, which only ever worked because we didn't\n        # run validate on the dbt_project configs.\n        if \"pre_hook\" in project_dict:\n            project_dict[\"pre-hook\"] = project_dict.pop(\"pre_hook\")\n        if \"post_hook\" in project_dict:\n            project_dict[\"post-hook\"] = project_dict.pop(\"post_hook\")\n        return project_dict\n\n    def calculate_node_config_dict(\n        self,\n        config_call_dict: Dict[str, Any],\n        fqn: List[str],\n        resource_type: NodeType,\n        project_name: str,\n        base: bool,\n        patch_config_dict: Optional[dict] = None,\n    ) -> Dict[str, Any]:\n        config = self.calculate_node_config(\n            config_call_dict=config_call_dict,\n            fqn=fqn,\n            resource_type=resource_type,\n            project_name=project_name,\n            base=base,\n            patch_config_dict=patch_config_dict,\n        )\n        try:\n            finalized = config.finalize_and_validate()\n            return finalized.to_dict(omit_none=True)\n        except ValidationError as exc:\n            # we got a ValidationError - probably bad types in config()\n            raise SchemaConfigError(exc, node=config) from exc\n\n\nclass UnrenderedConfigGenerator(BaseContextConfigGenerator[Dict[str, Any]]):\n    def get_config_source(self, project: Project) -> ConfigSource:\n        return UnrenderedConfig(project)\n\n    def calculate_node_config_dict(\n        self,\n        config_call_dict: Dict[str, Any],\n        fqn: List[str],\n        resource_type: NodeType,\n        project_name: str,\n        base: bool,\n        patch_config_dict: Optional[dict] = None,\n    ) -> Dict[str, Any]:\n        # TODO CT-211\n        return self.calculate_node_config(\n            config_call_dict=config_call_dict,\n            fqn=fqn,\n            resource_type=resource_type,\n            project_name=project_name,\n            base=base,\n            patch_config_dict=patch_config_dict,\n        )  # type: ignore[return-value]\n\n    def initial_result(self, resource_type: NodeType, base: bool) -> Dict[str, Any]:\n        return {}\n\n    def _update_from_config(\n        self,\n        result: Dict[str, Any],\n        partial: Dict[str, Any],\n        validate: bool = False,\n    ) -> Dict[str, Any]:\n        translated = self._active_project.credentials.translate_aliases(partial)\n        result.update(translated)\n        return result\n\n\nclass ContextConfig:\n    def __init__(\n        self,\n        active_project: RuntimeConfig,\n        fqn: List[str],\n        resource_type: NodeType,\n        project_name: str,\n    ) -> None:\n        self._config_call_dict: Dict[str, Any] = {}\n        self._unrendered_config_call_dict: Dict[str, Any] = {}\n        self._active_project = active_project\n        self._fqn = fqn\n        self._resource_type = resource_type\n        self._project_name = project_name\n\n    def add_config_call(self, opts: Dict[str, Any]) -> None:\n        dct = self._config_call_dict\n        merge_config_dicts(dct, opts)\n\n    def add_unrendered_config_call(self, opts: Dict[str, Any]) -> None:\n        # Cannot perform complex merge behaviours on unrendered configs as they may not be appropriate types.\n        self._unrendered_config_call_dict.update(opts)\n\n    def build_config_dict(\n        self,\n        base: bool = False,\n        *,\n        rendered: bool = True,\n        patch_config_dict: Optional[dict] = None,\n    ) -> Dict[str, Any]:\n        if rendered:\n            # TODO CT-211\n            src = ContextConfigGenerator(self._active_project)  # type: ignore[var-annotated]\n            config_call_dict = self._config_call_dict\n        else:\n            # TODO CT-211\n            src = UnrenderedConfigGenerator(self._active_project)  # type: ignore[assignment]\n\n            # preserve legacy behaviour - using unreliable (potentially rendered) _config_call_dict\n            if get_flags().state_modified_compare_more_unrendered_values is False:\n                config_call_dict = self._config_call_dict\n            else:\n                # Prefer _config_call_dict if it is available and _unrendered_config_call_dict is not,\n                # as _unrendered_config_call_dict is unreliable for non-sql nodes (e.g. no jinja config block rendered for python models, etc)\n                if self._config_call_dict and not self._unrendered_config_call_dict:\n                    config_call_dict = self._config_call_dict\n                else:\n                    config_call_dict = self._unrendered_config_call_dict\n\n        return src.calculate_node_config_dict(\n            config_call_dict=config_call_dict,\n            fqn=self._fqn,\n            resource_type=self._resource_type,\n            project_name=self._project_name,\n            base=base,\n            patch_config_dict=patch_config_dict,\n        )\n"
  },
  {
    "path": "core/dbt/context/docs.py",
    "content": "from typing import Any, Dict, Union\n\nfrom dbt.config.runtime import RuntimeConfig\nfrom dbt.context.base import contextmember\nfrom dbt.context.configured import SchemaYamlContext\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.contracts.graph.nodes import Macro, ResultNode\nfrom dbt.exceptions import DocArgsError, DocTargetNotFoundError\n\n\nclass DocsRuntimeContext(SchemaYamlContext):\n    def __init__(\n        self,\n        config: RuntimeConfig,\n        node: Union[Macro, ResultNode],\n        manifest: Manifest,\n        current_project: str,\n    ) -> None:\n        super().__init__(config, current_project, None)\n        self.node = node\n        self.manifest = manifest\n\n    @contextmember()\n    def doc(self, *args: str) -> str:\n        \"\"\"The `doc` function is used to reference docs blocks in schema.yml\n        files. It is analogous to the `ref` function. For more information,\n        consult the Documentation guide.\n\n        > orders.md:\n\n            {% docs orders %}\n            # docs\n            - go\n            - here\n            {% enddocs %}\n\n        > schema.yml\n\n            version: 2\n                models:\n                  - name: orders\n                    description: \"{{ doc('orders') }}\"\n        \"\"\"\n        # when you call doc(), this is what happens at runtime\n        if len(args) == 1:\n            doc_package_name = None\n            doc_name = args[0]\n        elif len(args) == 2:\n            doc_package_name, doc_name = args\n        else:\n            raise DocArgsError(self.node, args)\n\n        # Documentation\n        target_doc = self.manifest.resolve_doc(\n            doc_name,\n            doc_package_name,\n            self._project_name,\n            self.node.package_name,\n        )\n        if target_doc:\n            file_id = target_doc.file_id\n            if file_id in self.manifest.files:\n                source_file = self.manifest.files[file_id]\n                # TODO CT-211\n                source_file.add_node(self.node.unique_id)  # type: ignore[union-attr]\n        else:\n            raise DocTargetNotFoundError(\n                node=self.node, target_doc_name=doc_name, target_doc_package=doc_package_name\n            )\n\n        return target_doc.block_contents\n\n\ndef generate_runtime_docs_context(\n    config: RuntimeConfig,\n    target: Any,\n    manifest: Manifest,\n    current_project: str,\n) -> Dict[str, Any]:\n    ctx = DocsRuntimeContext(config, target, manifest, current_project)\n    # This is not a Mashumaro to_dict call\n    return ctx.to_dict()\n"
  },
  {
    "path": "core/dbt/context/exceptions_jinja.py",
    "content": "import functools\nfrom typing import NoReturn\n\nfrom dbt.adapters.exceptions import (\n    ColumnTypeMissingError,\n    MissingConfigError,\n    MissingMaterializationError,\n    RelationWrongTypeError,\n)\nfrom dbt.adapters.exceptions.cache import CacheInconsistencyError\nfrom dbt.events.types import JinjaLogWarning, SnapshotTimestampWarning\nfrom dbt.exceptions import (\n    AmbiguousAliasError,\n    AmbiguousCatalogMatchError,\n    CompilationError,\n    ContractError,\n    DependencyError,\n    DependencyNotFoundError,\n    DuplicatePatchPathError,\n    DuplicateResourceNameError,\n    FailFastError,\n    MissingRelationError,\n    PropertyYMLError,\n    env_secrets,\n    scrub_secrets,\n)\nfrom dbt_common.events.functions import warn_or_error\nfrom dbt_common.exceptions import (\n    DataclassNotDictError,\n    DbtDatabaseError,\n    DbtRuntimeError,\n    NotImplementedError,\n)\n\n\ndef warn(msg, node=None):\n    warn_or_error(JinjaLogWarning(msg=msg), node=node)\n    return \"\"\n\n\ndef missing_config(model, name) -> NoReturn:\n    raise MissingConfigError(unique_id=model.unique_id, name=name)\n\n\ndef missing_materialization(model, adapter_type) -> NoReturn:\n    raise MissingMaterializationError(\n        materialization=model.config.materialized, adapter_type=adapter_type\n    )\n\n\ndef missing_relation(relation, model=None) -> NoReturn:\n    raise MissingRelationError(relation, model)\n\n\ndef raise_ambiguous_alias(node_1, node_2, duped_name=None) -> NoReturn:\n    raise AmbiguousAliasError(node_1, node_2, duped_name)\n\n\ndef raise_ambiguous_catalog_match(unique_id, match_1, match_2) -> NoReturn:\n    raise AmbiguousCatalogMatchError(unique_id, match_1, match_2)\n\n\ndef raise_cache_inconsistent(message) -> NoReturn:\n    raise CacheInconsistencyError(message)\n\n\ndef raise_dataclass_not_dict(obj) -> NoReturn:\n    raise DataclassNotDictError(obj)\n\n\ndef raise_compiler_error(msg, node=None) -> NoReturn:\n    raise CompilationError(msg, node)\n\n\ndef raise_contract_error(yaml_columns, sql_columns) -> NoReturn:\n    raise ContractError(yaml_columns, sql_columns)\n\n\ndef raise_database_error(msg, node=None) -> NoReturn:\n    raise DbtDatabaseError(msg, node)\n\n\ndef raise_dep_not_found(node, node_description, required_pkg) -> NoReturn:\n    raise DependencyNotFoundError(node, node_description, required_pkg)\n\n\ndef raise_dependency_error(msg) -> NoReturn:\n    raise DependencyError(scrub_secrets(msg, env_secrets()))\n\n\ndef raise_duplicate_patch_name(patch_1, existing_patch_path) -> NoReturn:\n    raise DuplicatePatchPathError(patch_1, existing_patch_path)\n\n\ndef raise_duplicate_resource_name(node_1, node_2) -> NoReturn:\n    raise DuplicateResourceNameError(node_1, node_2)\n\n\ndef raise_invalid_property_yml_version(path, issue) -> NoReturn:\n    raise PropertyYMLError(path, issue)\n\n\ndef raise_not_implemented(msg) -> NoReturn:\n    raise NotImplementedError(msg)\n\n\ndef relation_wrong_type(relation, expected_type, model=None) -> NoReturn:\n    raise RelationWrongTypeError(relation, expected_type, model)\n\n\ndef column_type_missing(column_names) -> NoReturn:\n    raise ColumnTypeMissingError(column_names)\n\n\ndef raise_fail_fast_error(msg, node=None) -> NoReturn:\n    raise FailFastError(msg, node=node)\n\n\ndef warn_snapshot_timestamp_data_types(\n    snapshot_time_data_type: str, updated_at_data_type: str\n) -> None:\n    warn_or_error(\n        SnapshotTimestampWarning(\n            snapshot_time_data_type=snapshot_time_data_type,\n            updated_at_data_type=updated_at_data_type,\n        )\n    )\n\n\n# Update this when a new function should be added to the\n# dbt context's `exceptions` key!\nCONTEXT_EXPORTS = {\n    fn.__name__: fn\n    for fn in [\n        warn,\n        missing_config,\n        missing_materialization,\n        missing_relation,\n        raise_ambiguous_alias,\n        raise_ambiguous_catalog_match,\n        raise_cache_inconsistent,\n        raise_dataclass_not_dict,\n        raise_compiler_error,\n        raise_database_error,\n        raise_dep_not_found,\n        raise_dependency_error,\n        raise_duplicate_patch_name,\n        raise_duplicate_resource_name,\n        raise_invalid_property_yml_version,\n        raise_not_implemented,\n        relation_wrong_type,\n        raise_contract_error,\n        column_type_missing,\n        raise_fail_fast_error,\n        warn_snapshot_timestamp_data_types,\n    ]\n}\n\n\n# wraps context based exceptions in node info\ndef wrapper(model):\n    def wrap(func):\n        @functools.wraps(func)\n        def inner(*args, **kwargs):\n            try:\n                return func(*args, **kwargs)\n            except DbtRuntimeError as exc:\n                exc.add_node(model)\n                raise exc\n\n        return inner\n\n    return wrap\n\n\ndef wrapped_exports(model):\n    wrap = wrapper(model)\n    return {name: wrap(export) for name, export in CONTEXT_EXPORTS.items()}\n"
  },
  {
    "path": "core/dbt/context/macro_resolver.py",
    "content": "from typing import Dict, MutableMapping, Optional\n\nfrom dbt.clients.jinja import MacroGenerator\nfrom dbt.contracts.graph.nodes import Macro\nfrom dbt.exceptions import DuplicateMacroNameError, PackageNotFoundForMacroError\nfrom dbt.include.global_project import PROJECT_NAME as GLOBAL_PROJECT_NAME\n\nMacroNamespace = Dict[str, Macro]\n\n\n# This class builds the MacroResolver by adding macros\n# to various categories for finding macros in the right order,\n# so that higher precedence macros are found first.\n# This functionality is also provided by the MacroNamespace,\n# but the intention is to eventually replace that class.\n# This enables us to get the macro unique_id without\n# processing every macro in the project.\n# Note: the root project macros override everything in the\n# dbt internal projects. External projects (dependencies) will\n# use their own macros first, then pull from the root project\n# followed by dbt internal projects.\nclass MacroResolver:\n    def __init__(\n        self,\n        macros: MutableMapping[str, Macro],\n        root_project_name: str,\n        internal_package_names,\n    ) -> None:\n        self.root_project_name = root_project_name\n        self.macros = macros\n        # internal packages comes from get_adapter_package_names\n        self.internal_package_names = internal_package_names\n\n        # To be filled in from macros.\n        self.internal_packages: Dict[str, MacroNamespace] = {}\n        self.packages: Dict[str, MacroNamespace] = {}\n        self.root_package_macros: MacroNamespace = {}\n\n        # add the macros to internal_packages, packages, and root packages\n        self.add_macros()\n        self._build_internal_packages_namespace()\n        self._build_macros_by_name()\n\n    def _build_internal_packages_namespace(self) -> None:\n        # Iterate in reverse-order and overwrite: the packages that are first\n        # in the list are the ones we want to \"win\".\n        self.internal_packages_namespace: MacroNamespace = {}\n        for pkg in reversed(self.internal_package_names):\n            if pkg in self.internal_packages:\n                # Turn the internal packages into a flat namespace\n                self.internal_packages_namespace.update(self.internal_packages[pkg])\n\n    # search order:\n    # local_namespace (package of particular node), not including\n    #    the internal packages or the root package\n    #    This means that within an extra package, it uses its own macros\n    # root package namespace\n    # non-internal packages (that aren't local or root)\n    # dbt internal packages\n    def _build_macros_by_name(self) -> None:\n        macros_by_name = {}\n\n        # all internal packages (already in the right order)\n        for macro in self.internal_packages_namespace.values():\n            macros_by_name[macro.name] = macro\n\n        # non-internal packages\n        for fnamespace in self.packages.values():\n            for macro in fnamespace.values():\n                macros_by_name[macro.name] = macro\n\n        # root package macros\n        for macro in self.root_package_macros.values():\n            macros_by_name[macro.name] = macro\n\n        self.macros_by_name = macros_by_name\n\n    def _add_macro_to(\n        self,\n        package_namespaces: Dict[str, MacroNamespace],\n        macro: Macro,\n    ) -> None:\n        if macro.package_name in package_namespaces:\n            namespace = package_namespaces[macro.package_name]\n        else:\n            namespace = {}\n            package_namespaces[macro.package_name] = namespace\n\n        if macro.name in namespace:\n            raise DuplicateMacroNameError(macro, macro, macro.package_name)\n        package_namespaces[macro.package_name][macro.name] = macro\n\n    def add_macro(self, macro: Macro) -> None:\n        macro_name: str = macro.name\n\n        # internal macros (from plugins) will be processed separately from\n        # project macros, so store them in a different place\n        if macro.package_name in self.internal_package_names:\n            self._add_macro_to(self.internal_packages, macro)\n        else:\n            # if it's not an internal package\n            self._add_macro_to(self.packages, macro)\n            # add to root_package_macros if it's in the root package\n            if macro.package_name == self.root_project_name:\n                self.root_package_macros[macro_name] = macro\n\n    def add_macros(self) -> None:\n        for macro in self.macros.values():\n            self.add_macro(macro)\n\n    def get_macro(self, local_package, macro_name) -> Optional[Macro]:\n        local_package_macros = {}\n        # If the macro is explicitly prefixed with an internal namespace\n        # (e.g. 'dbt.some_macro'), look there first\n        if local_package in self.internal_package_names:\n            local_package_macros = self.internal_packages[local_package]\n        # If the macro is explicitly prefixed with a different package name\n        # (e.g. 'dbt_utils.some_macro'), look there first\n        if local_package not in self.internal_package_names and local_package in self.packages:\n            local_package_macros = self.packages[local_package]\n        # First: search the specified package for this macro\n        if macro_name in local_package_macros:\n            return local_package_macros[macro_name]\n        # Now look up in the standard search order\n        if macro_name in self.macros_by_name:\n            return self.macros_by_name[macro_name]\n        return None\n\n    def get_macro_id(self, local_package, macro_name) -> Optional[str]:\n        macro = self.get_macro(local_package, macro_name)\n        if macro is None:\n            return None\n        else:\n            return macro.unique_id\n\n\n# Currently this is just used by test processing in the schema\n# parser (in connection with the MacroResolver). Future work\n# will extend the use of these classes to other parsing areas.\n# One of the features of this class compared to the MacroNamespace\n# is that you can limit the number of macros provided to the\n# context dictionary in the 'to_dict' manifest method.\nclass TestMacroNamespace:\n    def __init__(self, macro_resolver, ctx, node, thread_ctx, depends_on_macros):\n        self.macro_resolver = macro_resolver\n        self.ctx = ctx\n        self.node = node  # can be none\n        self.thread_ctx = thread_ctx\n        self.local_namespace = {}\n        self.project_namespace = {}\n        if depends_on_macros:\n            dep_macros = []\n            self.recursively_get_depends_on_macros(depends_on_macros, dep_macros)\n            for macro_unique_id in dep_macros:\n                if macro_unique_id in self.macro_resolver.macros:\n                    # Split up the macro unique_id to get the project_name\n                    (_, project_name, macro_name) = macro_unique_id.split(\".\")\n                    # Save the plain macro_name in the local_namespace\n                    macro = self.macro_resolver.macros[macro_unique_id]\n                    macro_gen = MacroGenerator(\n                        macro,\n                        self.ctx,\n                        self.node,\n                        self.thread_ctx,\n                    )\n                    self.local_namespace[macro_name] = macro_gen\n                    # We also need the two part macro name\n                    if project_name not in self.project_namespace:\n                        self.project_namespace[project_name] = {}\n                    self.project_namespace[project_name][macro_name] = macro_gen\n\n    def recursively_get_depends_on_macros(self, depends_on_macros, dep_macros):\n        for macro_unique_id in depends_on_macros:\n            if macro_unique_id in dep_macros:\n                continue\n            dep_macros.append(macro_unique_id)\n            if macro_unique_id in self.macro_resolver.macros:\n                macro = self.macro_resolver.macros[macro_unique_id]\n                if macro.depends_on.macros:\n                    self.recursively_get_depends_on_macros(macro.depends_on.macros, dep_macros)\n\n    def get_from_package(self, package_name: Optional[str], name: str) -> Optional[MacroGenerator]:\n        macro = None\n        if package_name is None:\n            macro = self.macro_resolver.macros_by_name.get(name)\n        elif package_name == GLOBAL_PROJECT_NAME:\n            macro = self.macro_resolver.internal_packages_namespace.get(name)\n        elif package_name in self.macro_resolver.packages:\n            macro = self.macro_resolver.packages[package_name].get(name)\n        else:\n            raise PackageNotFoundForMacroError(package_name)\n        if not macro:\n            return None\n        macro_func = MacroGenerator(macro, self.ctx, self.node, self.thread_ctx)\n        return macro_func\n"
  },
  {
    "path": "core/dbt/context/macros.py",
    "content": "from typing import Any, Dict, Iterable, Iterator, List, Mapping, Optional, Set, Union\n\nfrom dbt.clients.jinja import MacroGenerator, MacroStack\nfrom dbt.contracts.graph.nodes import Macro\nfrom dbt.exceptions import DuplicateMacroNameError, PackageNotFoundForMacroError\nfrom dbt.include.global_project import PROJECT_NAME as GLOBAL_PROJECT_NAME\n\nFlatNamespace = Dict[str, MacroGenerator]\nNamespaceMember = Union[FlatNamespace, MacroGenerator]\nFullNamespace = Dict[str, NamespaceMember]\n\n\n# The point of this class is to collect the various macros\n# and provide the ability to flatten them into the ManifestContexts\n# that are created for jinja, so that macro calls can be resolved.\n# Creates special iterators and _keys methods to flatten the lists.\n# When this class is created it has a static 'local_namespace' which\n# depends on the package of the node, so it only works for one\n# particular local package at a time for \"flattening\" into a context.\n# 'get_by_package' should work for any macro.\nclass MacroNamespace(Mapping):\n    def __init__(\n        self,\n        global_namespace: FlatNamespace,  # root package macros\n        local_namespace: FlatNamespace,  # packages for *this* node\n        global_project_namespace: FlatNamespace,  # internal packages\n        packages: Dict[str, FlatNamespace],  # non-internal packages\n    ):\n        self.global_namespace: FlatNamespace = global_namespace\n        self.local_namespace: FlatNamespace = local_namespace\n        self.packages: Dict[str, FlatNamespace] = packages\n        self.global_project_namespace: FlatNamespace = global_project_namespace\n\n    def _search_order(self) -> Iterable[Union[FullNamespace, FlatNamespace]]:\n        yield self.local_namespace  # local package\n        yield self.global_namespace  # root package\n        # TODO CT-211\n        yield self.packages  # type: ignore[misc] # non-internal packages\n        yield {\n            # TODO CT-211\n            GLOBAL_PROJECT_NAME: self.global_project_namespace,  # type: ignore[misc] # dbt\n        }\n        yield self.global_project_namespace  # other internal project besides dbt\n\n    # provides special keys method for MacroNamespace iterator\n    # returns keys from local_namespace, global_namespace, packages,\n    # global_project_namespace\n    def _keys(self) -> Set[str]:\n        keys: Set[str] = set()\n        for search in self._search_order():\n            keys.update(search)\n        return keys\n\n    # special iterator using special keys\n    def __iter__(self) -> Iterator[str]:\n        for key in self._keys():\n            yield key\n\n    def __len__(self):\n        return len(self._keys())\n\n    def __getitem__(self, key: str) -> NamespaceMember:\n        for dct in self._search_order():\n            if key in dct:\n                return dct[key]\n        raise KeyError(key)\n\n    def get_from_package(self, package_name: Optional[str], name: str) -> Optional[MacroGenerator]:\n        if package_name is None:\n            return self.get(name)\n        elif package_name == GLOBAL_PROJECT_NAME:\n            return self.global_project_namespace.get(name)\n        elif package_name in self.packages:\n            return self.packages[package_name].get(name)\n        else:\n            raise PackageNotFoundForMacroError(package_name)\n\n\n# This class builds the MacroNamespace by adding macros to\n# internal_packages or packages, and locals/globals.\n# Call 'build_namespace' to return a MacroNamespace.\n# This is used by ManifestContext (and subclasses)\nclass MacroNamespaceBuilder:\n    def __init__(\n        self,\n        root_package: str,\n        search_package: str,\n        thread_ctx: MacroStack,\n        internal_packages: List[str],\n        node: Optional[Any] = None,\n    ) -> None:\n        self.root_package = root_package\n        self.search_package = search_package\n        # internal packages comes from get_adapter_package_names\n        self.internal_package_names = set(internal_packages)\n        self.internal_package_names_order = internal_packages\n        # macro_func is added here if in root package, since\n        # the root package acts as a \"global\" namespace, overriding\n        # everything else except local external package macro calls\n        self.globals: FlatNamespace = {}\n        # macro_func is added here if it's the package for this node\n        self.locals: FlatNamespace = {}\n        # Create a dictionary of [package name][macro name] =\n        #     MacroGenerator object which acts like a function\n        self.internal_packages: Dict[str, FlatNamespace] = {}\n        self.packages: Dict[str, FlatNamespace] = {}\n        self.thread_ctx = thread_ctx\n        self.node = node\n\n    def _add_macro_to(\n        self,\n        hierarchy: Dict[str, FlatNamespace],\n        macro: Macro,\n        macro_func: MacroGenerator,\n    ):\n        if macro.package_name in hierarchy:\n            namespace = hierarchy[macro.package_name]\n        else:\n            namespace = {}\n            hierarchy[macro.package_name] = namespace\n\n        if macro.name in namespace:\n            raise DuplicateMacroNameError(macro_func.macro, macro, macro.package_name)\n        hierarchy[macro.package_name][macro.name] = macro_func\n\n    def add_macro(self, macro: Macro, ctx: Dict[str, Any]) -> None:\n        macro_name: str = macro.name\n\n        # MacroGenerator is in clients/jinja.py\n        # a MacroGenerator object is a callable object that will\n        # execute the MacroGenerator.__call__ function\n        macro_func: MacroGenerator = MacroGenerator(macro, ctx, self.node, self.thread_ctx)\n\n        # internal macros (from plugins) will be processed separately from\n        # project macros, so store them in a different place\n        if macro.package_name in self.internal_package_names:\n            self._add_macro_to(self.internal_packages, macro, macro_func)\n        else:\n            # if it's not an internal package\n            self._add_macro_to(self.packages, macro, macro_func)\n            # add to locals if it's the package this node is in\n            if macro.package_name == self.search_package:\n                self.locals[macro_name] = macro_func\n            # add to globals if it's in the root package\n            elif macro.package_name == self.root_package:\n                self.globals[macro_name] = macro_func\n\n    def add_macros(self, macros: Iterable[Macro], ctx: Dict[str, Any]) -> None:\n        for macro in macros:\n            self.add_macro(macro, ctx)\n\n    def build_namespace(\n        self, macros_by_package: Dict[str, Dict[str, Macro]], ctx: Dict[str, Any]\n    ) -> MacroNamespace:\n        for package in macros_by_package.values():\n            self.add_macros(package.values(), ctx)\n\n        # Iterate in reverse-order and overwrite: the packages that are first\n        # in the list are the ones we want to \"win\".\n        global_project_namespace: FlatNamespace = {}\n        for pkg in reversed(self.internal_package_names_order):\n            if pkg in self.internal_packages:\n                # add the macros pointed to by this package name\n                global_project_namespace.update(self.internal_packages[pkg])\n\n        return MacroNamespace(\n            global_namespace=self.globals,  # root package macros\n            local_namespace=self.locals,  # packages for *this* node\n            global_project_namespace=global_project_namespace,  # internal packages\n            packages=self.packages,  # non internal_packages\n        )\n"
  },
  {
    "path": "core/dbt/context/manifest.py",
    "content": "from typing import List\n\nfrom dbt.adapters.contracts.connection import AdapterRequiredConfig\nfrom dbt.clients.jinja import MacroStack\nfrom dbt.context.macro_resolver import TestMacroNamespace\nfrom dbt.contracts.graph.manifest import Manifest\n\nfrom .base import contextproperty\nfrom .configured import ConfiguredContext\nfrom .macros import MacroNamespace, MacroNamespaceBuilder\n\n\nclass ManifestContext(ConfiguredContext):\n    \"\"\"The Macro context has everything in the target context, plus the macros\n    in the manifest.\n\n    The given macros can override any previous context values, which will be\n    available as if they were accessed relative to the package name.\n    \"\"\"\n\n    # subclasses are QueryHeaderContext and ProviderContext\n    def __init__(\n        self,\n        config: AdapterRequiredConfig,\n        manifest: Manifest,\n        search_package: str,\n    ) -> None:\n        super().__init__(config)\n        self.manifest = manifest\n        # this is the package of the node for which this context was built\n        self.search_package = search_package\n        self.macro_stack = MacroStack()\n        # This namespace is used by the BaseDatabaseWrapper in jinja rendering.\n        # The namespace is passed to it when it's constructed. It expects\n        # to be able to do: namespace.get_from_package(..)\n        self.namespace = self._build_namespace()\n\n    def _build_namespace(self) -> MacroNamespace:\n        # this takes all the macros in the manifest and adds them\n        # to the MacroNamespaceBuilder stored in self.namespace\n        builder = self._get_namespace_builder()\n        return builder.build_namespace(self.manifest.get_macros_by_package(), self._ctx)\n\n    def _get_namespace_builder(self) -> MacroNamespaceBuilder:\n        # avoid an import loop\n        from dbt.adapters.factory import get_adapter_package_names\n\n        internal_packages: List[str] = get_adapter_package_names(self.config.credentials.type)\n        return MacroNamespaceBuilder(\n            self.config.project_name,\n            self.search_package,\n            self.macro_stack,\n            internal_packages,\n            None,\n        )\n\n    # This does not use the Mashumaro code\n    def to_dict(self):\n        dct = super().to_dict()\n        # This moves all of the macros in the 'namespace' into top level\n        # keys in the manifest dictionary\n        if isinstance(self.namespace, TestMacroNamespace):\n            dct.update(self.namespace.local_namespace)\n            dct.update(self.namespace.project_namespace)\n        else:\n            dct.update(self.namespace)\n\n        return dct\n\n    @contextproperty()\n    def context_macro_stack(self):\n        return self.macro_stack\n"
  },
  {
    "path": "core/dbt/context/providers.py",
    "content": "import abc\nimport csv\nimport os\nfrom copy import deepcopy\nfrom typing import (\n    TYPE_CHECKING,\n    Any,\n    Callable,\n    Dict,\n    Iterable,\n    List,\n    Mapping,\n    Optional,\n    Set,\n    Tuple,\n    Type,\n    TypeVar,\n    Union,\n)\n\nfrom typing_extensions import Protocol\n\nfrom dbt import selected_resources\nfrom dbt.adapters.base.column import Column\nfrom dbt.adapters.base.relation import EventTimeFilter, RelationType\nfrom dbt.adapters.contracts.connection import AdapterResponse\nfrom dbt.adapters.exceptions import MissingConfigError\nfrom dbt.adapters.factory import (\n    get_adapter,\n    get_adapter_package_names,\n    get_adapter_type_names,\n)\nfrom dbt.artifacts.resources import (\n    NodeConfig,\n    NodeVersion,\n    RefArgs,\n    SeedConfig,\n    SourceConfig,\n)\nfrom dbt.clients.jinja import (\n    MacroGenerator,\n    MacroStack,\n    UnitTestMacroGenerator,\n    get_rendered,\n)\nfrom dbt.clients.jinja_static import statically_parse_unrendered_config\nfrom dbt.config import IsFQNResource, Project, RuntimeConfig\nfrom dbt.constants import DEFAULT_ENV_PLACEHOLDER\nfrom dbt.context.base import Var, contextmember, contextproperty\nfrom dbt.context.configured import FQNLookup\nfrom dbt.context.context_config import ContextConfig\nfrom dbt.context.exceptions_jinja import wrapped_exports\nfrom dbt.context.macro_resolver import MacroResolver, TestMacroNamespace\nfrom dbt.context.macros import MacroNamespace, MacroNamespaceBuilder\nfrom dbt.context.manifest import ManifestContext\nfrom dbt.contracts.graph.manifest import Disabled, Manifest\nfrom dbt.contracts.graph.metrics import MetricReference, ResolvedMetricReference\nfrom dbt.contracts.graph.nodes import (\n    AccessType,\n    Exposure,\n    FunctionNode,\n    Macro,\n    ManifestNode,\n    ModelNode,\n    Resource,\n    SeedNode,\n    SemanticModel,\n    SnapshotNode,\n    SourceDefinition,\n    UnitTestNode,\n)\nfrom dbt.events.types import JinjaLogWarning\nfrom dbt.exceptions import (\n    CompilationError,\n    ConflictingConfigKeysError,\n    DbtReferenceError,\n    EnvVarMissingError,\n    InlineModelConfigError,\n    LoadAgateTableNotSeedError,\n    LoadAgateTableValueError,\n    MacroDispatchArgError,\n    MacroResultAlreadyLoadedError,\n    MetricArgsError,\n    NumberSourceArgsError,\n    OperationsCannotRefEphemeralNodesError,\n    ParsingError,\n    PersistDocsValueTypeError,\n    RefArgsError,\n    RefBadContextError,\n    SecretEnvVarLocationError,\n    TargetNotFoundError,\n)\nfrom dbt.flags import get_flags\nfrom dbt.materializations.incremental.microbatch import MicrobatchBuilder\nfrom dbt.node_types import ModelLanguage, NodeType\nfrom dbt.utils import MultiDict, args_to_dict\nfrom dbt_common.clients.jinja import MacroProtocol\nfrom dbt_common.constants import SECRET_ENV_PREFIX\nfrom dbt_common.context import get_invocation_context\nfrom dbt_common.events.functions import fire_event, get_metadata_vars\nfrom dbt_common.exceptions import (\n    DbtInternalError,\n    DbtRuntimeError,\n    DbtValidationError,\n    MacrosSourcesUnWriteableError,\n)\nfrom dbt_common.utils import AttrDict, cast_to_str, merge\n\nif TYPE_CHECKING:\n    import agate\n\n\n_MISSING = object()\n\n\n# base classes\nclass RelationProxy:\n    def __init__(self, adapter):\n        self._quoting_config = adapter.config.quoting\n        self._relation_type = adapter.Relation\n\n    def __getattr__(self, key):\n        return getattr(self._relation_type, key)\n\n    def create(self, *args, **kwargs):\n        kwargs[\"quote_policy\"] = merge(self._quoting_config, kwargs.pop(\"quote_policy\", {}))\n        return self._relation_type.create(*args, **kwargs)\n\n\nclass BaseDatabaseWrapper:\n    \"\"\"\n    Wrapper for runtime database interaction. Applies the runtime quote policy\n    via a relation proxy.\n    \"\"\"\n\n    def __init__(self, adapter, namespace: MacroNamespace):\n        self._adapter = adapter\n        self.Relation = RelationProxy(adapter)\n        self._namespace = namespace\n\n    def __getattr__(self, name):\n        raise NotImplementedError(\"subclasses need to implement this\")\n\n    @property\n    def config(self):\n        return self._adapter.config\n\n    def type(self):\n        return self._adapter.type()\n\n    def commit(self):\n        return self._adapter.commit_if_has_connection()\n\n    def _get_adapter_macro_prefixes(self) -> List[str]:\n        # order matters for dispatch:\n        #  1. current adapter\n        #  2. any parent adapters (dependencies)\n        #  3. 'default'\n        search_prefixes = get_adapter_type_names(self._adapter.type()) + [\"default\"]\n        return search_prefixes\n\n    def _get_search_packages(self, namespace: Optional[str] = None) -> List[Optional[str]]:\n        search_packages: List[Optional[str]] = [None]\n\n        if namespace is None:\n            search_packages = [None]\n        elif isinstance(namespace, str):\n            macro_search_order = self._adapter.config.get_macro_search_order(namespace)\n            if macro_search_order:\n                search_packages = macro_search_order\n            elif not macro_search_order and namespace in self._adapter.config.dependencies:\n                search_packages = [self.config.project_name, namespace]\n        else:\n            raise CompilationError(\n                f\"In adapter.dispatch, got a {type(namespace)} macro_namespace argument \"\n                f'(\"{namespace}\"), but macro_namespace should be None or a string.'\n            )\n\n        return search_packages\n\n    def dispatch(\n        self,\n        macro_name: str,\n        macro_namespace: Optional[str] = None,\n        packages: Optional[List[str]] = None,  # eventually remove since it's fully deprecated\n    ) -> MacroGenerator:\n        search_packages: List[Optional[str]]\n\n        if \".\" in macro_name:\n            suggest_macro_namespace, suggest_macro_name = macro_name.split(\".\", 1)\n            msg = (\n                f'In adapter.dispatch, got a macro name of \"{macro_name}\", '\n                f'but \".\" is not a valid macro name component. Did you mean '\n                f'`adapter.dispatch(\"{suggest_macro_name}\", '\n                f'macro_namespace=\"{suggest_macro_namespace}\")`?'\n            )\n            raise CompilationError(msg)\n\n        if packages is not None:\n            raise MacroDispatchArgError(macro_name)\n\n        search_packages = self._get_search_packages(macro_namespace)\n\n        attempts = []\n\n        for package_name in search_packages:\n            for prefix in self._get_adapter_macro_prefixes():\n                search_name = f\"{prefix}__{macro_name}\"\n                try:\n                    # this uses the namespace from the context\n                    macro = self._namespace.get_from_package(package_name, search_name)\n                except CompilationError:\n                    # Only raise CompilationError if macro is not found in\n                    # any package\n                    macro = None\n\n                if package_name is None:\n                    attempts.append(search_name)\n                else:\n                    attempts.append(f\"{package_name}.{search_name}\")\n\n                if macro is not None:\n                    return macro\n\n        searched = \", \".join(repr(a) for a in attempts)\n        msg = f\"In dispatch: No macro named '{macro_name}' found within namespace: '{macro_namespace}'\\n    Searched for: {searched}\"\n        raise CompilationError(msg)\n\n\nclass BaseResolver(metaclass=abc.ABCMeta):\n    def __init__(self, db_wrapper, model, config, manifest):\n        self.db_wrapper = db_wrapper\n        self.model = model\n        self.config = config\n        self.manifest = manifest\n\n    @property\n    def current_project(self):\n        return self.config.project_name\n\n    @property\n    def Relation(self):\n        return self.db_wrapper.Relation\n\n    @property\n    def resolve_limit(self) -> Optional[int]:\n        return 0 if getattr(self.config.args, \"EMPTY\", False) else None\n\n    def _resolve_event_time_field_name(self, target: ManifestNode) -> str:\n        \"\"\"Get the event time field name with proper quoting based on configuration.\"\"\"\n        # Default to False for quoting\n        should_quote = False\n        column_found = False\n        column = None\n\n        # Check if config has event_time attribute\n        if not hasattr(target.config, \"event_time\") or target.config.event_time is None:\n            return \"\"\n\n        # Check column-level quote configuration first (overrides source-level)\n        if hasattr(target, \"columns\") and target.columns and isinstance(target.columns, dict):\n            for _, column_info in target.columns.items():\n                if column_info.name == target.config.event_time:\n                    column_found = True\n                    # Create the column object\n                    column = Column.create(\n                        column_info.name, column_info.data_type if column_info.data_type else \"\"\n                    )\n                    # Column-level quote setting takes precedence\n                    if hasattr(column_info, \"quote\") and column_info.quote is not None:\n                        should_quote = column_info.quote\n                    # Fallback to source-level quote setting\n                    elif (\n                        hasattr(target, \"quoting\")\n                        and hasattr(target.quoting, \"column\")\n                        and target.quoting.column is not None\n                    ):\n                        should_quote = target.quoting.column\n                    break\n\n        # If column not found, fall back to source-level quote setting\n        if not column_found:\n            if (\n                hasattr(target, \"quoting\")\n                and hasattr(target.quoting, \"column\")\n                and target.quoting.column is not None\n            ):\n                should_quote = target.quoting.column\n            # Create column object for quoting\n            column = Column.create(target.config.event_time, \"\")\n\n        # Apply quoting logic\n        if should_quote and column is not None:\n            return column.quoted\n        else:\n            return target.config.event_time\n\n    def resolve_event_time_filter(self, target: ManifestNode) -> Optional[EventTimeFilter]:\n        event_time_filter = None\n        sample_mode = getattr(self.config.args, \"sample\", None) is not None\n        field_name = self._resolve_event_time_field_name(target)\n\n        # TODO The number of branches here is getting rough. We should consider ways to simplify\n        # what is going on to make it easier to maintain\n\n        # Only do event time filtering if the base node has the necessary event time configs\n        if (\n            isinstance(target.config, (NodeConfig, SeedConfig, SourceConfig))\n            and target.config.event_time\n            and isinstance(self.model, (ModelNode, SnapshotNode))\n        ):\n\n            # Handling of microbatch models\n            if (\n                isinstance(self.model, ModelNode)\n                and self.model.config.materialized == \"incremental\"\n                and self.model.config.incremental_strategy == \"microbatch\"\n                and self.manifest.use_microbatch_batches(project_name=self.config.project_name)\n                and self.model.batch is not None\n            ):\n                # Sample mode microbatch models\n                if sample_mode:\n                    start = (\n                        self.config.args.sample.start\n                        if self.config.args.sample.start > self.model.batch.event_time_start\n                        else self.model.batch.event_time_start\n                    )\n                    end = (\n                        self.config.args.sample.end\n                        if self.config.args.sample.end < self.model.batch.event_time_end\n                        else self.model.batch.event_time_end\n                    )\n                    event_time_filter = EventTimeFilter(\n                        field_name=field_name,\n                        start=start,\n                        end=end,\n                    )\n\n                # Regular microbatch models\n                else:\n                    event_time_filter = EventTimeFilter(\n                        field_name=field_name,\n                        start=self.model.batch.event_time_start,\n                        end=self.model.batch.event_time_end,\n                    )\n\n            # Sample mode _non_ microbatch models\n            elif sample_mode:\n                event_time_filter = EventTimeFilter(\n                    field_name=field_name,\n                    start=self.config.args.sample.start,\n                    end=self.config.args.sample.end,\n                )\n\n        return event_time_filter\n\n    @abc.abstractmethod\n    def __call__(self, *args: str) -> Union[str, RelationProxy, MetricReference]:\n        pass\n\n\nclass BaseRefResolver(BaseResolver):\n    @abc.abstractmethod\n    def resolve(\n        self, name: str, package: Optional[str] = None, version: Optional[NodeVersion] = None\n    ) -> RelationProxy: ...\n\n    def _repack_args(\n        self, name: str, package: Optional[str], version: Optional[NodeVersion]\n    ) -> RefArgs:\n        return RefArgs(package=package, name=name, version=version)\n\n    def validate_args(self, name: str, package: Optional[str], version: Optional[NodeVersion]):\n        if not isinstance(name, str):\n            raise CompilationError(\n                f\"The name argument to ref() must be a string, got {type(name)}\"\n            )\n\n        if package is not None and not isinstance(package, str):\n            raise CompilationError(\n                f\"The package argument to ref() must be a string or None, got {type(package)}\"\n            )\n\n        if version is not None and not isinstance(version, (str, int, float)):\n            raise CompilationError(\n                f\"The version argument to ref() must be a string, int, float, or None - got {type(version)}\"\n            )\n\n    def __call__(self, *args: str, **kwargs) -> RelationProxy:\n        name: str\n        package: Optional[str] = None\n        version: Optional[NodeVersion] = None\n\n        if len(args) == 1:\n            name = args[0]\n        elif len(args) == 2:\n            package, name = args\n        else:\n            raise RefArgsError(node=self.model, args=args)\n\n        version = kwargs.get(\"version\") or kwargs.get(\"v\")\n        self.validate_args(name, package, version)\n        return self.resolve(name, package, version)\n\n\nclass BaseSourceResolver(BaseResolver):\n    @abc.abstractmethod\n    def resolve(self, source_name: str, table_name: str):\n        pass\n\n    def validate_args(self, source_name: str, table_name: str):\n        if not isinstance(source_name, str):\n            raise CompilationError(\n                f\"The source name (first) argument to source() must be a \"\n                f\"string, got {type(source_name)}\"\n            )\n        if not isinstance(table_name, str):\n            raise CompilationError(\n                f\"The table name (second) argument to source() must be a \"\n                f\"string, got {type(table_name)}\"\n            )\n\n    def __call__(self, *args: str) -> RelationProxy:\n        if len(args) != 2:\n            raise NumberSourceArgsError(args, node=self.model)\n        self.validate_args(args[0], args[1])\n        return self.resolve(args[0], args[1])\n\n\nclass BaseMetricResolver(BaseResolver):\n    @abc.abstractmethod\n    def resolve(self, name: str, package: Optional[str] = None) -> MetricReference: ...\n\n    def _repack_args(self, name: str, package: Optional[str]) -> List[str]:\n        if package is None:\n            return [name]\n        else:\n            return [package, name]\n\n    def validate_args(self, name: str, package: Optional[str]):\n        if not isinstance(name, str):\n            raise CompilationError(\n                f\"The name argument to metric() must be a string, got {type(name)}\"\n            )\n\n        if package is not None and not isinstance(package, str):\n            raise CompilationError(\n                f\"The package argument to metric() must be a string or None, got {type(package)}\"\n            )\n\n    def __call__(self, *args: str) -> MetricReference:\n        name: str\n        package: Optional[str] = None\n\n        if len(args) == 1:\n            name = args[0]\n        elif len(args) == 2:\n            package, name = args\n        else:\n            raise MetricArgsError(node=self.model, args=args)\n        self.validate_args(name, package)\n        return self.resolve(name, package)\n\n\nclass BaseFunctionResolver(BaseResolver):\n    @abc.abstractmethod\n    def resolve(self, name: str, package: Optional[str] = None): ...\n\n    def _repack_args(self, name: str, package: Optional[str]) -> List[str]:\n        if package is None:\n            return [name]\n        else:\n            return [package, name]\n\n    def validate_args(self, name: str, package: Optional[str]):\n        if not isinstance(name, str):\n            raise CompilationError(\n                f\"The name argument to function() must be a string, got {type(name)}\"\n            )\n\n        if package is not None and not isinstance(package, str):\n            raise CompilationError(\n                f\"The package argument to function() must be a string or None, got {type(package)}\"\n            )\n\n    def __call__(self, *args: str):\n        name: str\n        package: Optional[str] = None\n\n        if len(args) == 1:\n            name = args[0]\n        elif len(args) == 2:\n            package, name = args\n        else:\n            raise RefArgsError(node=self.model, args=args)\n        self.validate_args(name, package)\n        return self.resolve(name, package)\n\n\nclass Config(Protocol):\n    def __init__(self, model, context_config: Optional[ContextConfig]): ...\n\n\n# Implementation of \"config(..)\" calls in models\nclass ParseConfigObject(Config):\n    def __init__(self, model, context_config: Optional[ContextConfig]):\n        self.model = model\n        self.context_config = context_config\n\n    def _transform_config(self, config):\n        for oldkey in (\"pre_hook\", \"post_hook\"):\n            if oldkey in config:\n                newkey = oldkey.replace(\"_\", \"-\")\n                if newkey in config:\n                    raise ConflictingConfigKeysError(oldkey, newkey, node=self.model)\n                config[newkey] = config.pop(oldkey)\n        return config\n\n    def __call__(self, *args, **kwargs):\n        if len(args) == 1 and len(kwargs) == 0:\n            opts = args[0]\n        elif len(args) == 0 and len(kwargs) > 0:\n            opts = kwargs\n        else:\n            raise InlineModelConfigError(node=self.model)\n\n        opts = self._transform_config(opts)\n\n        # it's ok to have a parse context with no context config, but you must\n        # not call it!\n        if self.context_config is None:\n            raise DbtRuntimeError(\"At parse time, did not receive a context config\")\n\n        # Track unrendered opts to build parsed node unrendered_config later on\n        if get_flags().state_modified_compare_more_unrendered_values:\n            unrendered_config = statically_parse_unrendered_config(self.model.raw_code)\n            if unrendered_config:\n                self.context_config.add_unrendered_config_call(unrendered_config)\n\n        # Use rendered opts to populate context_config\n        self.context_config.add_config_call(opts)\n        return \"\"\n\n    def set(self, name, value):\n        return self.__call__({name: value})\n\n    def require(self, name, validator=None):\n        return \"\"\n\n    def meta_require(self, name, validator=None):\n        return \"\"\n\n    def get(self, name, default=None, validator=None):\n        return \"\"\n\n    def meta_get(self, name, default=None, validator=None):\n        return \"\"\n\n    def persist_relation_docs(self) -> bool:\n        return False\n\n    def persist_column_docs(self) -> bool:\n        return False\n\n\nclass RuntimeConfigObject(Config):\n    def __init__(self, model, context_config: Optional[ContextConfig] = None):\n        self.model = model\n        # we never use or get a config, only the parser cares\n\n    def __call__(self, *args, **kwargs):\n        return \"\"\n\n    def set(self, name, value):\n        return self.__call__({name: value})\n\n    def _validate(self, validator, value):\n        validator(value)\n\n    def _lookup(self, name, default=_MISSING):\n        # if this is a macro, there might be no `model.config`.\n        if not hasattr(self.model, \"config\"):\n            result = default\n        else:\n            result = self.model.config.get(name, default)\n        if result is _MISSING:\n            raise MissingConfigError(unique_id=self.model.unique_id, name=name)\n        return result\n\n    def _lookup_meta(self, name, default=_MISSING):\n        # if this is a macro, there might be no `model.config`.\n        if not hasattr(self.model, \"config\"):\n            result = default\n        else:\n            result = self.model.config.meta_get(name, default)\n        if result is _MISSING:\n            raise MissingConfigError(unique_id=self.model.unique_id, name=name)\n        return result\n\n    def require(self, name, validator=None):\n        to_return = self._lookup(name)\n\n        if validator is not None:\n            self._validate(validator, to_return)\n\n        return to_return\n\n    def meta_require(self, name, validator=None):\n        to_return = self._lookup_meta(name)\n\n        if validator is not None:\n            self._validate(validator, to_return)\n\n        return to_return\n\n    def get(self, name, default=None, validator=None):\n        to_return = self._lookup(name, default)\n\n        if validator is not None and default is not None:\n            self._validate(validator, to_return)\n\n        return to_return\n\n    def meta_get(self, name, default=None, validator=None):\n        to_return = self._lookup_meta(name, default)\n\n        if validator is not None and default is not None:\n            self._validate(validator, to_return)\n\n        return to_return\n\n    def persist_relation_docs(self) -> bool:\n        persist_docs = self.get(\"persist_docs\", default={})\n        if not isinstance(persist_docs, dict):\n            raise PersistDocsValueTypeError(persist_docs)\n\n        return persist_docs.get(\"relation\", False)\n\n    def persist_column_docs(self) -> bool:\n        persist_docs = self.get(\"persist_docs\", default={})\n        if not isinstance(persist_docs, dict):\n            raise PersistDocsValueTypeError(persist_docs)\n\n        return persist_docs.get(\"columns\", False)\n\n\n# `adapter` implementations\nclass ParseDatabaseWrapper(BaseDatabaseWrapper):\n    \"\"\"The parser subclass of the database wrapper applies any explicit\n    parse-time overrides.\n    \"\"\"\n\n    def __getattr__(self, name):\n        override = name in self._adapter._available_ and name in self._adapter._parse_replacements_\n\n        if override:\n            return self._adapter._parse_replacements_[name]\n        elif name in self._adapter._available_:\n            return getattr(self._adapter, name)\n        else:\n            raise AttributeError(\n                \"'{}' object has no attribute '{}'\".format(self.__class__.__name__, name)\n            )\n\n\nclass RuntimeDatabaseWrapper(BaseDatabaseWrapper):\n    \"\"\"The runtime database wrapper exposes everything the adapter marks\n    available.\n    \"\"\"\n\n    def __getattr__(self, name):\n        if name in self._adapter._available_:\n            return getattr(self._adapter, name)\n        else:\n            raise AttributeError(\n                \"'{}' object has no attribute '{}'\".format(self.__class__.__name__, name)\n            )\n\n\n# `ref` implementations\nclass ParseRefResolver(BaseRefResolver):\n    def resolve(\n        self, name: str, package: Optional[str] = None, version: Optional[NodeVersion] = None\n    ) -> RelationProxy:\n        self.model.refs.append(self._repack_args(name, package, version))\n\n        # This is not the ref for the \"name\" passed in, but for the current model.\n        return self.Relation.create_from(self.config, self.model)\n\n\nResolveRef = Union[Disabled, ManifestNode]\n\n\nclass RuntimeRefResolver(BaseRefResolver):\n    def resolve(\n        self,\n        target_name: str,\n        target_package: Optional[str] = None,\n        target_version: Optional[NodeVersion] = None,\n    ) -> RelationProxy:\n        target_model = self.manifest.resolve_ref(\n            self.model,\n            target_name,\n            target_package,\n            target_version,\n            self.current_project,\n            self.model.package_name,\n        )\n\n        # Raise an error if the reference target is missing\n        if target_model is None or isinstance(target_model, Disabled):\n            raise TargetNotFoundError(\n                node=self.model,\n                target_name=target_name,\n                target_kind=\"node\",\n                target_package=target_package,\n                target_version=target_version,\n                disabled=isinstance(target_model, Disabled),\n            )\n\n        # Raise error if trying to reference a 'private' resource outside its 'group'\n        elif self.manifest.is_invalid_private_ref(\n            self.model, target_model, self.config.dependencies\n        ):\n            raise DbtReferenceError(\n                unique_id=self.model.unique_id,\n                ref_unique_id=target_model.unique_id,\n                access=AccessType.Private,\n                scope=cast_to_str(target_model.group),\n            )\n        # Or a 'protected' resource outside its project/package namespace\n        elif self.manifest.is_invalid_protected_ref(\n            self.model, target_model, self.config.dependencies\n        ):\n            raise DbtReferenceError(\n                unique_id=self.model.unique_id,\n                ref_unique_id=target_model.unique_id,\n                access=AccessType.Protected,\n                scope=target_model.package_name,\n            )\n        self.validate(target_model, target_name, target_package, target_version)\n        return self.create_relation(target_model)\n\n    def create_relation(self, target_model: ManifestNode) -> RelationProxy:\n        if target_model.is_ephemeral_model:\n            self.model.set_cte(target_model.unique_id, None)\n            return self.Relation.create_ephemeral_from(\n                target_model,\n                limit=self.resolve_limit,\n                event_time_filter=self.resolve_event_time_filter(target_model),\n            )\n        elif (\n            hasattr(target_model, \"defer_relation\")\n            and target_model.defer_relation\n            and self.config.args.defer\n            and (\n                # User has explicitly opted to prefer defer_relation for unselected resources\n                (\n                    self.config.args.favor_state\n                    and target_model.unique_id not in selected_resources.SELECTED_RESOURCES\n                )\n                # Or, this node's relation does not exist in the expected target location (cache lookup)\n                or not get_adapter(self.config).get_relation(\n                    target_model.database, target_model.schema, target_model.identifier\n                )\n            )\n        ):\n            return self.Relation.create_from(\n                self.config,\n                target_model.defer_relation,\n                limit=self.resolve_limit,\n                event_time_filter=self.resolve_event_time_filter(target_model),\n            )\n        else:\n            return self.Relation.create_from(\n                self.config,\n                target_model,\n                limit=self.resolve_limit,\n                event_time_filter=self.resolve_event_time_filter(target_model),\n            )\n\n    def validate(\n        self,\n        resolved: ManifestNode,\n        target_name: str,\n        target_package: Optional[str],\n        target_version: Optional[NodeVersion],\n    ) -> None:\n        if resolved.unique_id not in self.model.depends_on.nodes:\n            args = self._repack_args(target_name, target_package, target_version)\n            raise RefBadContextError(node=self.model, args=args)\n\n\nclass OperationRefResolver(RuntimeRefResolver):\n    def validate(\n        self,\n        resolved: ManifestNode,\n        target_name: str,\n        target_package: Optional[str],\n        target_version: Optional[NodeVersion],\n    ) -> None:\n        pass\n\n    def create_relation(self, target_model: ManifestNode) -> RelationProxy:\n        if target_model.is_ephemeral_model:\n            # In operations, we can't ref() ephemeral nodes, because\n            # Macros do not support set_cte\n            raise OperationsCannotRefEphemeralNodesError(target_model.name, node=self.model)\n        else:\n            return super().create_relation(target_model)\n\n\nclass RuntimeUnitTestRefResolver(RuntimeRefResolver):\n    @property\n    def resolve_limit(self) -> Optional[int]:\n        # Unit tests should never respect --empty flag or provide a limit since they are based on fake data.\n        return None\n\n    def resolve(\n        self,\n        target_name: str,\n        target_package: Optional[str] = None,\n        target_version: Optional[NodeVersion] = None,\n    ) -> RelationProxy:\n        return super().resolve(target_name, target_package, target_version)\n\n\n# `source` implementations\nclass ParseSourceResolver(BaseSourceResolver):\n    def resolve(self, source_name: str, table_name: str):\n        # When you call source(), this is what happens at parse time\n        self.model.sources.append([source_name, table_name])\n        return self.Relation.create_from(self.config, self.model)\n\n\nclass RuntimeSourceResolver(BaseSourceResolver):\n    def resolve(self, source_name: str, table_name: str):\n        target_source = self.manifest.resolve_source(\n            source_name,\n            table_name,\n            self.current_project,\n            self.model.package_name,\n        )\n\n        if target_source is None or isinstance(target_source, Disabled):\n            raise TargetNotFoundError(\n                node=self.model,\n                target_name=f\"{source_name}.{table_name}\",\n                target_kind=\"source\",\n                disabled=(isinstance(target_source, Disabled)),\n            )\n\n        # Source quoting does _not_ respect global configs in dbt_project.yml, as documented here:\n        # https://docs.getdbt.com/reference/project-configs/quoting\n        # Use an object with an empty quoting field to bypass any settings in self.\n        class SourceQuotingBaseConfig:\n            quoting: Dict[str, Any] = {}\n\n        return self.Relation.create_from(\n            SourceQuotingBaseConfig(),\n            target_source,\n            limit=self.resolve_limit,\n            event_time_filter=self.resolve_event_time_filter(target_source),\n        )\n\n\nclass RuntimeUnitTestSourceResolver(BaseSourceResolver):\n    @property\n    def resolve_limit(self) -> Optional[int]:\n        # Unit tests should never respect --empty flag or provide a limit since they are based on fake data.\n        return None\n\n    def resolve(self, source_name: str, table_name: str):\n        target_source = self.manifest.resolve_source(\n            source_name,\n            table_name,\n            self.current_project,\n            self.model.package_name,\n        )\n        if target_source is None or isinstance(target_source, Disabled):\n            raise TargetNotFoundError(\n                node=self.model,\n                target_name=f\"{source_name}.{table_name}\",\n                target_kind=\"source\",\n                disabled=(isinstance(target_source, Disabled)),\n            )\n        # For unit tests, this isn't a \"real\" source, it's a ModelNode taking\n        # the place of a source. We don't really need to return the relation here,\n        # we just need to set_cte, but skipping it confuses typing. We *do* need\n        # the relation in the \"this\" property.\n        self.model.set_cte(target_source.unique_id, None)\n\n        identifier = self.Relation.add_ephemeral_prefix(target_source.cte_name)\n        return self.Relation.create(\n            type=self.Relation.CTE,\n            identifier=identifier,\n        ).quote(identifier=False)\n\n\n# metric` implementations\nclass ParseMetricResolver(BaseMetricResolver):\n    def resolve(self, name: str, package: Optional[str] = None) -> MetricReference:\n        self.model.metrics.append(self._repack_args(name, package))\n\n        return MetricReference(name, package)\n\n\nclass RuntimeMetricResolver(BaseMetricResolver):\n    def resolve(self, target_name: str, target_package: Optional[str] = None) -> MetricReference:\n        target_metric = self.manifest.resolve_metric(\n            target_name,\n            target_package,\n            self.current_project,\n            self.model.package_name,\n        )\n\n        if target_metric is None or isinstance(target_metric, Disabled):\n            raise TargetNotFoundError(\n                node=self.model,\n                target_name=target_name,\n                target_kind=\"metric\",\n                target_package=target_package,\n            )\n\n        return ResolvedMetricReference(target_metric, self.manifest)\n\n\n# `var` implementations.\nclass ModelConfiguredVar(Var):\n    def __init__(\n        self,\n        context: Dict[str, Any],\n        config: RuntimeConfig,\n        node: Resource,\n    ) -> None:\n        self._node: Resource\n        self._config: RuntimeConfig = config\n        super().__init__(context, config.cli_vars, node=node)\n\n    def packages_for_node(self) -> Iterable[Project]:\n        dependencies = self._config.load_dependencies()\n        package_name = self._node.package_name\n\n        if package_name != self._config.project_name:\n            if package_name in dependencies:\n                yield dependencies[package_name]\n        yield self._config\n\n    def _generate_merged(self) -> Mapping[str, Any]:\n        search_node: IsFQNResource\n        if isinstance(self._node, IsFQNResource):\n            search_node = self._node\n        else:\n            search_node = FQNLookup(self._node.package_name)\n\n        adapter_type = self._config.credentials.type\n\n        merged = MultiDict()\n        for project in self.packages_for_node():\n            merged.add(project.vars.vars_for(search_node, adapter_type))\n        merged.add(self._cli_vars)\n        return merged\n\n\nclass ParseVar(ModelConfiguredVar):\n    def get_missing_var(self, var_name):\n        # in the parser, just always return None.\n        return None\n\n\nclass RuntimeVar(ModelConfiguredVar):\n    pass\n\n\nclass UnitTestVar(RuntimeVar):\n    def __init__(\n        self,\n        context: Dict[str, Any],\n        config: RuntimeConfig,\n        node: Resource,\n    ) -> None:\n        config_copy = None\n        assert isinstance(node, UnitTestNode)\n        if node.overrides and node.overrides.vars:\n            config_copy = deepcopy(config)\n            config_copy.cli_vars.update(node.overrides.vars)\n\n        super().__init__(context, config_copy or config, node=node)\n\n\n# `function` implementations.\nclass ParseFunctionResolver(BaseFunctionResolver):\n    def resolve(self, name: str, package: Optional[str] = None):\n        # When you call function(), this is what happens at parse time\n        self.model.functions.append(self._repack_args(name, package))\n        return self.Relation.create_from(self.config, self.model, type=RelationType.Function)\n\n\nclass RuntimeFunctionResolver(BaseFunctionResolver):\n    def resolve(self, name: str, package: Optional[str] = None):\n        target_function = self.manifest.resolve_function(\n            name,\n            package,\n            self.current_project,\n            self.model.package_name,\n        )\n\n        if target_function is None or isinstance(target_function, Disabled):\n            raise TargetNotFoundError(\n                node=self.model,\n                target_name=name,\n                target_kind=\"function\",\n                disabled=(isinstance(target_function, Disabled)),\n            )\n        function_node = target_function\n        if (\n            hasattr(target_function, \"defer_function\")\n            and target_function.defer_function\n            and self.config.args.defer\n            and (\n                (\n                    self.config.args.favor_state\n                    and target_function.unique_id not in selected_resources.SELECTED_RESOURCES\n                )\n                or not get_adapter(self.config).get_relation(\n                    target_function.database,\n                    target_function.schema,\n                    target_function.identifier,\n                )\n            )\n        ):\n            function_node = target_function.defer_function\n\n        # Source quoting does _not_ respect global configs in dbt_project.yml, as documented here:\n        # https://docs.getdbt.com/reference/project-configs/quoting\n        # Use an object with an empty quoting field to bypass any settings in self.\n        class SourceQuotingBaseConfig:\n            quoting: Dict[str, Any] = {}\n\n        return self.Relation.create_from(\n            SourceQuotingBaseConfig(),\n            function_node,\n            limit=self.resolve_limit,\n            event_time_filter=self.resolve_event_time_filter(target_function),\n            type=RelationType.Function,\n        )\n\n\n# TODO: Right now the RuntimeUnitTestProvider uses the RuntimeFunctionResolver for functions,\n# but for CT-12025 we'll likely need to create a separate RuntimeUnitTestFunctionResolver to\n# handle function overrides (mocking functions)\n\n\n# Providers\nclass Provider(Protocol):\n    execute: bool\n    Config: Type[Config]\n    DatabaseWrapper: Type[BaseDatabaseWrapper]\n    Var: Type[ModelConfiguredVar]\n    ref: Type[BaseRefResolver]\n    source: Type[BaseSourceResolver]\n    metric: Type[BaseMetricResolver]\n    function: Type[BaseFunctionResolver]\n\n\nclass ParseProvider(Provider):\n    execute = False\n    Config = ParseConfigObject\n    DatabaseWrapper = ParseDatabaseWrapper\n    Var = ParseVar\n    ref = ParseRefResolver\n    source = ParseSourceResolver\n    metric = ParseMetricResolver\n    function = ParseFunctionResolver\n\n\nclass GenerateNameProvider(Provider):\n    execute = False\n    Config = RuntimeConfigObject\n    DatabaseWrapper = ParseDatabaseWrapper\n    Var = RuntimeVar\n    ref = ParseRefResolver\n    source = ParseSourceResolver\n    metric = ParseMetricResolver\n    function = ParseFunctionResolver\n\n\nclass RuntimeProvider(Provider):\n    execute = True\n    Config = RuntimeConfigObject\n    DatabaseWrapper = RuntimeDatabaseWrapper\n    Var = RuntimeVar\n    ref = RuntimeRefResolver\n    source = RuntimeSourceResolver\n    metric = RuntimeMetricResolver\n    function = RuntimeFunctionResolver\n\n\nclass RuntimeUnitTestProvider(Provider):\n    execute = True\n    Config = RuntimeConfigObject\n    DatabaseWrapper = RuntimeDatabaseWrapper\n    Var = UnitTestVar\n    ref = RuntimeUnitTestRefResolver\n    source = RuntimeUnitTestSourceResolver\n    metric = RuntimeMetricResolver\n    function = RuntimeFunctionResolver\n\n\nclass OperationProvider(RuntimeProvider):\n    ref = OperationRefResolver\n\n\nT = TypeVar(\"T\")\n\n\n# Base context collection, used for parsing configs.\nclass ProviderContext(ManifestContext):\n    # subclasses are MacroContext, ModelContext, TestContext, SourceContext\n    def __init__(\n        self,\n        model,\n        config: RuntimeConfig,\n        manifest: Manifest,\n        provider: Provider,\n        context_config: Optional[ContextConfig],\n    ) -> None:\n        if provider is None:\n            raise DbtInternalError(f\"Invalid provider given to context: {provider}\")\n        # mypy appeasement - we know it'll be a RuntimeConfig\n        self.config: RuntimeConfig\n        self.model: Union[Macro, ManifestNode, SourceDefinition] = model\n        super().__init__(config, manifest, model.package_name)\n        self.sql_results: Dict[str, Optional[AttrDict]] = {}\n        self.context_config: Optional[ContextConfig] = context_config\n        self.provider: Provider = provider\n        self.adapter = get_adapter(self.config)\n        # The macro namespace is used in creating the DatabaseWrapper\n        self.db_wrapper = self.provider.DatabaseWrapper(self.adapter, self.namespace)\n\n    # This overrides the method in ManifestContext, and provides\n    # a model, which the ManifestContext builder does not\n    def _get_namespace_builder(self):\n        internal_packages = get_adapter_package_names(self.config.credentials.type)\n        return MacroNamespaceBuilder(\n            self.config.project_name,\n            self.search_package,\n            self.macro_stack,\n            internal_packages,\n            self.model,\n        )\n\n    @contextproperty()\n    def dbt_metadata_envs(self) -> Dict[str, str]:\n        return get_metadata_vars()\n\n    @contextproperty()\n    def invocation_args_dict(self):\n        return args_to_dict(self.config.args)\n\n    @contextproperty()\n    def _sql_results(self) -> Dict[str, Optional[AttrDict]]:\n        return self.sql_results\n\n    @contextmember()\n    def load_result(self, name: str) -> Optional[AttrDict]:\n        if name in self.sql_results:\n            # handle the special case of \"main\" macro\n            # See: https://github.com/dbt-labs/dbt-core/blob/ada8860e48b32ac712d92e8b0977b2c3c9749981/core/dbt/task/run.py#L228\n            if name == \"main\":\n                return self.sql_results[\"main\"]\n\n            # handle a None, which indicates this name was populated but has since been loaded\n            elif self.sql_results[name] is None:\n                raise MacroResultAlreadyLoadedError(name)\n\n            # Handle the regular use case\n            else:\n                ret_val = self.sql_results[name]\n                self.sql_results[name] = None\n                return ret_val\n        else:\n            # Handle trying to load a result that was never stored\n            return None\n\n    @contextmember()\n    def store_result(\n        self, name: str, response: Any, agate_table: Optional[\"agate.Table\"] = None\n    ) -> str:\n        from dbt_common.clients import agate_helper\n\n        if agate_table is None:\n            agate_table = agate_helper.empty_table()\n\n        self.sql_results[name] = AttrDict(\n            {\n                \"response\": response,\n                \"data\": agate_helper.as_matrix(agate_table),\n                \"table\": agate_table,\n            }\n        )\n        return \"\"\n\n    @contextmember()\n    def store_raw_result(\n        self,\n        name: str,\n        message=Optional[str],\n        code=Optional[str],\n        rows_affected=Optional[str],\n        agate_table: Optional[\"agate.Table\"] = None,\n    ) -> str:\n        response = AdapterResponse(_message=message, code=code, rows_affected=rows_affected)\n        return self.store_result(name, response, agate_table)\n\n    @contextproperty()\n    def validation(self):\n        def validate_any(*args) -> Callable[[T], None]:\n            def inner(value: T) -> None:\n                for arg in args:\n                    if isinstance(arg, type) and isinstance(value, arg):\n                        return\n                    elif value == arg:\n                        return\n                raise DbtValidationError(\n                    'Expected value \"{}\" to be one of {}'.format(value, \",\".join(map(str, args)))\n                )\n\n            return inner\n\n        return AttrDict(\n            {\n                \"any\": validate_any,\n            }\n        )\n\n    @contextmember()\n    def write(self, payload: str) -> str:\n        # macros/source defs aren't 'writeable'.\n        if isinstance(self.model, (Macro, SourceDefinition)):\n            raise MacrosSourcesUnWriteableError(node=self.model)\n\n        split_suffix = None\n        if (\n            isinstance(self.model, ModelNode)\n            and self.model.config.get(\"incremental_strategy\") == \"microbatch\"\n            and self.model.batch is not None\n        ):\n            split_suffix = MicrobatchBuilder.format_batch_start(\n                self.model.batch.event_time_start,\n                self.model.config.batch_size,\n            )\n\n        self.model.build_path = self.model.get_target_write_path(\n            self.config.target_path, \"run\", split_suffix=split_suffix\n        )\n        self.model.write_node(self.config.project_root, self.model.build_path, payload)\n        return \"\"\n\n    @contextmember()\n    def render(self, string: str) -> str:\n        return get_rendered(string, self._ctx, self.model)\n\n    @contextmember()\n    def try_or_compiler_error(\n        self, message_if_exception: str, func: Callable, *args, **kwargs\n    ) -> Any:\n        try:\n            return func(*args, **kwargs)\n        except Exception:\n            raise CompilationError(message_if_exception, self.model)\n\n    @staticmethod\n    def _read_csv_header(path: str, delimiter: str) -> Optional[Set[str]]:\n        try:\n            # Use utf-8-sig to handle BOM if present\n            with open(path, \"r\", encoding=\"utf-8-sig\", newline=\"\") as f:\n                reader = csv.reader(f, delimiter=delimiter)\n                header = next(reader)\n                return set(header)\n        except (IOError, StopIteration, TypeError):\n            return None\n\n    @contextmember()\n    def load_agate_table(self) -> \"agate.Table\":\n        from dbt_common.clients import agate_helper\n\n        if not isinstance(self.model, SeedNode):\n            raise LoadAgateTableNotSeedError(self.model.resource_type, node=self.model)\n\n        # include package_path for seeds defined in packages\n        package_path = (\n            os.path.join(self.config.packages_install_path, self.model.package_name)\n            if self.model.package_name != self.config.project_name\n            else \".\"\n        )\n        path = os.path.join(self.config.project_root, package_path, self.model.original_file_path)\n        if not os.path.exists(path):\n            assert self.model.root_path\n            path = os.path.join(self.model.root_path, self.model.original_file_path)\n\n        column_types = self.model.config.column_types or {}\n        delimiter = self.model.config.delimiter\n\n        # Validate that column_types keys exist in the file header\n        filtered_column_types = column_types\n        if column_types:\n            header_set = self._read_csv_header(path, delimiter)\n            if header_set is not None:\n                valid_column_types = set(column_types) & header_set\n                invalid_column_names = set(column_types) - header_set\n\n                if invalid_column_names:\n                    invalid_column_names_str = \", \".join(sorted(invalid_column_names))\n                    msg = (\n                        f\"Column types specified for non-existent columns in seed '{self.model.name}' (file: {path}): \"\n                        f\"{invalid_column_names_str}. These column type overrides will be ignored.\"\n                    )\n                    fire_event(JinjaLogWarning(msg=msg))\n\n                filtered_column_types = {\n                    k: v for k, v in column_types.items() if k in valid_column_types\n                }\n\n        try:\n            table = agate_helper.from_csv(\n                path, text_columns=filtered_column_types, delimiter=delimiter\n            )\n        except ValueError as e:\n            raise LoadAgateTableValueError(e, node=self.model)\n        # this is used by some adapters\n        table.original_abspath = os.path.abspath(path)  # type: ignore\n        return table\n\n    @contextproperty()\n    def ref(self) -> Callable:\n        \"\"\"The most important function in dbt is `ref()`; it's impossible to\n        build even moderately complex models without it. `ref()` is how you\n        reference one model within another. This is a very common behavior, as\n        typically models are built to be \"stacked\" on top of one another. Here\n        is how this looks in practice:\n\n        > model_a.sql:\n\n            select *\n            from public.raw_data\n\n        > model_b.sql:\n\n            select *\n            from {{ref('model_a')}}\n\n\n        `ref()` is, under the hood, actually doing two important things. First,\n        it is interpolating the schema into your model file to allow you to\n        change your deployment schema via configuration. Second, it is using\n        these references between models to automatically build the dependency\n        graph. This will enable dbt to deploy models in the correct order when\n        using dbt run.\n\n        The `ref` function returns a Relation object.\n\n        ## Advanced ref usage\n\n        There is also a two-argument variant of the `ref` function. With this\n        variant, you can pass both a package name and model name to `ref` to\n        avoid ambiguity. This functionality is not commonly required for\n        typical dbt usage.\n\n        > model.sql:\n\n            select * from {{ ref('package_name', 'model_name') }}\"\n        \"\"\"\n        return self.provider.ref(self.db_wrapper, self.model, self.config, self.manifest)\n\n    @contextproperty()\n    def source(self) -> Callable:\n        return self.provider.source(self.db_wrapper, self.model, self.config, self.manifest)\n\n    @contextproperty()\n    def metric(self) -> Callable:\n        return self.provider.metric(self.db_wrapper, self.model, self.config, self.manifest)\n\n    @contextproperty()\n    def function(self) -> Callable:\n        return self.provider.function(self.db_wrapper, self.model, self.config, self.manifest)\n\n    @contextproperty(\"config\")\n    def ctx_config(self) -> Config:\n        \"\"\"The `config` variable exists to handle end-user configuration for\n        custom materializations. Configs like `unique_key` can be implemented\n        using the `config` variable in your own materializations.\n\n        For example, code in the `incremental` materialization like this:\n\n            {% materialization incremental, default -%}\n            {%- set unique_key = config.get('unique_key') -%}\n            ...\n\n        is responsible for handling model code that looks like this:\n\n            {{\n              config(\n                materialized='incremental',\n                unique_key='id'\n              )\n            }}\n\n\n        ## config.get\n\n        name: The name of the configuration variable (required)\n        default: The default value to use if this configuration is not provided\n            (optional)\n\n        The `config.get` function is used to get configurations for a model\n        from the end-user. Configs defined in this way are optional, and a\n        default value can be provided.\n\n        Example usage:\n\n            {% materialization incremental, default -%}\n              -- Example w/ no default. unique_key will be None if the user does not provide this configuration\n              {%- set unique_key = config.get('unique_key') -%}\n              -- Example w/ default value. Default to 'id' if 'unique_key' not provided\n              {%- set unique_key = config.get('unique_key', default='id') -%}\n              ...\n\n        ## config.require\n\n        name: The name of the configuration variable (required)\n\n        The `config.require` function is used to get configurations for a model\n        from the end-user. Configs defined using this function are required,\n        and failure to provide them will result in a compilation error.\n\n        Example usage:\n\n            {% materialization incremental, default -%}\n              {%- set unique_key = config.require('unique_key') -%}\n              ...\n        \"\"\"  # noqa\n        return self.provider.Config(self.model, self.context_config)\n\n    @contextproperty()\n    def execute(self) -> bool:\n        \"\"\"`execute` is a Jinja variable that returns True when dbt is in\n        \"execute\" mode.\n\n        When you execute a dbt compile or dbt run command, dbt:\n\n        - Reads all of the files in your project and generates a \"manifest\"\n            comprised of models, tests, and other graph nodes present in your\n            project. During this phase, dbt uses the `ref` statements it finds\n            to generate the DAG for your project. *No SQL is run during this\n            phase*, and `execute == False`.\n        - Compiles (and runs) each node (eg. building models, or running\n            tests). SQL is run during this phase, and `execute == True`.\n\n        Any Jinja that relies on a result being returned from the database will\n        error during the parse phase. For example, this SQL will return an\n        error:\n\n        > models/order_payment_methods.sql:\n\n            {% set payment_method_query %}\n            select distinct\n            payment_method\n            from {{ ref('raw_payments') }}\n            order by 1\n            {% endset %}\n            {% set results = run_query(relation_query) %}\n            {# Return the first column #}\n            {% set payment_methods = results.columns[0].values() %}\n\n        The error returned by dbt will look as follows:\n\n            Encountered an error:\n                Compilation Error in model order_payment_methods (models/order_payment_methods.sql)\n            'None' has no attribute 'table'\n\n        This is because Line #11 assumes that a table has been returned, when,\n        during the parse phase, this query hasn't been run.\n\n        To work around this, wrap any problematic Jinja in an\n        `{% if execute %}` statement:\n\n        > models/order_payment_methods.sql:\n\n            {% set payment_method_query %}\n            select distinct\n            payment_method\n            from {{ ref('raw_payments') }}\n            order by 1\n            {% endset %}\n            {% set results = run_query(relation_query) %}\n            {% if execute %}\n            {# Return the first column #}\n            {% set payment_methods = results.columns[0].values() %}\n            {% else %}\n            {% set payment_methods = [] %}\n            {% endif %}\n        \"\"\"  # noqa\n        return self.provider.execute\n\n    @contextproperty()\n    def exceptions(self) -> Dict[str, Any]:\n        \"\"\"The exceptions namespace can be used to raise warnings and errors in\n        dbt userspace.\n\n\n        ## raise_compiler_error\n\n        The `exceptions.raise_compiler_error` method will raise a compiler\n        error with the provided message. This is typically only useful in\n        macros or materializations when invalid arguments are provided by the\n        calling model. Note that throwing an exception will cause a model to\n        fail, so please use this variable with care!\n\n        Example usage:\n\n        > exceptions.sql:\n\n            {% if number < 0 or number > 100 %}\n              {{ exceptions.raise_compiler_error(\"Invalid `number`. Got: \" ~ number) }}\n            {% endif %}\n\n        ## warn\n\n        The `exceptions.warn` method will raise a compiler warning with the\n        provided message. If the `--warn-error` flag is provided to dbt, then\n        this warning will be elevated to an exception, which is raised.\n\n        Example usage:\n\n        > warn.sql:\n\n            {% if number < 0 or number > 100 %}\n              {% do exceptions.warn(\"Invalid `number`. Got: \" ~ number) %}\n            {% endif %}\n        \"\"\"  # noqa\n        return wrapped_exports(self.model)\n\n    @contextproperty()\n    def database(self) -> str:\n        return self.config.credentials.database\n\n    @contextproperty()\n    def schema(self) -> str:\n        return self.config.credentials.schema\n\n    @contextproperty()\n    def var(self) -> ModelConfiguredVar:\n        return self.provider.Var(\n            context=self._ctx,\n            config=self.config,\n            node=self.model,\n        )\n\n    @contextproperty(\"adapter\")\n    def ctx_adapter(self) -> BaseDatabaseWrapper:\n        \"\"\"`adapter` is a wrapper around the internal database adapter used by\n        dbt. It allows users to make calls to the database in their dbt models.\n        The adapter methods will be translated into specific SQL statements\n        depending on the type of adapter your project is using.\n        \"\"\"\n        return self.db_wrapper\n\n    @contextproperty()\n    def api(self) -> Dict[str, Any]:\n        return {\n            \"Relation\": self.db_wrapper.Relation,\n            \"Column\": self.adapter.Column,\n        }\n\n    @contextproperty()\n    def column(self) -> Type[Column]:\n        return self.adapter.Column\n\n    @contextproperty()\n    def env(self) -> Dict[str, Any]:\n        return self.target\n\n    @contextproperty()\n    def graph(self) -> Dict[str, Any]:\n        \"\"\"The `graph` context variable contains information about the nodes in\n        your dbt project. Models, sources, tests, and snapshots are all\n        examples of nodes in dbt projects.\n\n        ## The graph context variable\n\n        The graph context variable is a dictionary which maps node ids onto dictionary representations of those nodes. A simplified example might look like:\n\n            {\n              \"model.project_name.model_name\": {\n                \"config\": {\"materialzed\": \"table\", \"sort\": \"id\"},\n                \"tags\": [\"abc\", \"123\"],\n                \"path\": \"models/path/to/model_name.sql\",\n                ...\n              },\n              \"source.project_name.source_name\": {\n                \"path\": \"models/path/to/schema.yml\",\n                \"columns\": {\n                  \"id\": { .... },\n                  \"first_name\": { .... },\n                },\n                ...\n              }\n            }\n\n        The exact contract for these model and source nodes is not currently\n        documented, but that will change in the future.\n\n        ## Accessing models\n\n        The `model` entries in the `graph` dictionary will be incomplete or\n        incorrect during parsing. If accessing the models in your project via\n        the `graph` variable, be sure to use the `execute` flag to ensure that\n        this code only executes at run-time and not at parse-time. Do not use\n        the `graph` variable to build you DAG, as the resulting dbt behavior\n        will be undefined and likely incorrect.\n\n        Example usage:\n\n        > graph-usage.sql:\n\n            /*\n              Print information about all of the models in the Snowplow package\n            */\n            {% if execute %}\n              {% for node in graph.nodes.values()\n                 | selectattr(\"resource_type\", \"equalto\", \"model\")\n                 | selectattr(\"package_name\", \"equalto\", \"snowplow\") %}\n\n                {% do log(node.unique_id ~ \", materialized: \" ~ node.config.materialized, info=true) %}\n\n              {% endfor %}\n            {% endif %}\n            /*\n              Example output\n            ---------------------------------------------------------------\n            model.snowplow.snowplow_id_map, materialized: incremental\n            model.snowplow.snowplow_page_views, materialized: incremental\n            model.snowplow.snowplow_web_events, materialized: incremental\n            model.snowplow.snowplow_web_page_context, materialized: table\n            model.snowplow.snowplow_web_events_scroll_depth, materialized: incremental\n            model.snowplow.snowplow_web_events_time, materialized: incremental\n            model.snowplow.snowplow_web_events_internal_fixed, materialized: ephemeral\n            model.snowplow.snowplow_base_web_page_context, materialized: ephemeral\n            model.snowplow.snowplow_base_events, materialized: ephemeral\n            model.snowplow.snowplow_sessions_tmp, materialized: incremental\n            model.snowplow.snowplow_sessions, materialized: table\n            */\n\n        ## Accessing sources\n\n        To access the sources in your dbt project programatically, use the \"sources\" attribute.\n\n        Example usage:\n\n        > models/events_unioned.sql\n\n            /*\n              Union all of the Snowplow sources defined in the project\n              which begin with the string \"event_\"\n            */\n            {% set sources = [] -%}\n            {% for node in graph.sources.values() -%}\n              {%- if node.name.startswith('event_') and node.source_name == 'snowplow' -%}\n                {%- do sources.append(source(node.source_name, node.name)) -%}\n              {%- endif -%}\n            {%- endfor %}\n            select * from (\n              {%- for source in sources %}\n                {{ source }} {% if not loop.last %} union all {% endif %}\n              {% endfor %}\n            )\n            /*\n              Example compiled SQL\n            ---------------------------------------------------------------\n            select * from (\n              select * from raw.snowplow.event_add_to_cart union all\n              select * from raw.snowplow.event_remove_from_cart union all\n              select * from raw.snowplow.event_checkout\n            )\n            */\n\n        \"\"\"  # noqa\n        return self.manifest.flat_graph\n\n    @contextproperty(\"model\")\n    def ctx_model(self) -> Dict[str, Any]:\n        model_dct = self.model.to_dict(omit_none=True)\n        # Maintain direct use of compiled_sql\n        # TODO add depreciation logic[CT-934]\n        if \"compiled_code\" in model_dct:\n            model_dct[\"compiled_sql\"] = model_dct[\"compiled_code\"]\n\n        if (\n            hasattr(self.model, \"contract\")\n            and self.model.contract.alias_types is True\n            and \"columns\" in model_dct\n        ):\n            for column in model_dct[\"columns\"].values():\n                if \"data_type\" in column:\n                    orig_data_type = column[\"data_type\"]\n                    # translate data_type to value in Column.TYPE_LABELS\n                    new_data_type = self.adapter.Column.translate_type(orig_data_type)\n                    column[\"data_type\"] = new_data_type\n        return model_dct\n\n    @contextproperty()\n    def pre_hooks(self) -> Optional[List[Dict[str, Any]]]:\n        return None\n\n    @contextproperty()\n    def post_hooks(self) -> Optional[List[Dict[str, Any]]]:\n        return None\n\n    @contextproperty()\n    def sql(self) -> Optional[str]:\n        return None\n\n    @contextproperty()\n    def sql_now(self) -> str:\n        return self.adapter.date_function()\n\n    @contextmember()\n    def adapter_macro(self, name: str, *args, **kwargs):\n        \"\"\"This was deprecated in v0.18 in favor of adapter.dispatch\"\"\"\n        msg = (\n            'The \"adapter_macro\" macro has been deprecated. Instead, use '\n            \"the `adapter.dispatch` method to find a macro and call the \"\n            \"result.  For more information, see: \"\n            \"https://docs.getdbt.com/reference/dbt-jinja-functions/dispatch)\"\n            \" adapter_macro was called for: {macro_name}\".format(macro_name=name)\n        )\n        raise CompilationError(msg)\n\n    @contextmember()\n    def env_var(self, var: str, default: Optional[str] = None) -> str:\n        \"\"\"The env_var() function. Return the environment variable named 'var'.\n        If there is no such environment variable set, return the default.\n\n        If the default is None, raise an exception for an undefined variable.\n        \"\"\"\n        return_value = None\n        if var.startswith(SECRET_ENV_PREFIX):\n            raise SecretEnvVarLocationError(var)\n\n        env = get_invocation_context().env\n\n        if var in env:\n            return_value = env[var]\n        elif default is not None:\n            return_value = default\n\n        if return_value is not None:\n            # Save the env_var value in the manifest and the var name in the source_file.\n            # If this is compiling, do not save because it's irrelevant to parsing.\n            compiling = (\n                True\n                if hasattr(self.model, \"compiled\")\n                and getattr(self.model, \"compiled\", False) is True\n                else False\n            )\n            if self.model and not compiling:\n                # If the environment variable is set from a default, store a string indicating\n                # that so we can skip partial parsing.  Otherwise the file will be scheduled for\n                # reparsing. If the default changes, the file will have been updated and therefore\n                # will be scheduled for reparsing anyways.\n                self.manifest.env_vars[var] = (\n                    return_value if var in env else DEFAULT_ENV_PLACEHOLDER\n                )\n\n                # hooks come from dbt_project.yml which doesn't have a real file_id\n                if self.model.file_id in self.manifest.files:\n                    source_file = self.manifest.files[self.model.file_id]\n                    # Schema files should never get here\n                    if source_file.parse_file_type != \"schema\":\n                        # TODO CT-211\n                        source_file.env_vars.append(var)  # type: ignore[union-attr]\n            return return_value\n        else:\n            raise EnvVarMissingError(var)\n\n    @contextproperty()\n    def selected_resources(self) -> List[str]:\n        \"\"\"The `selected_resources` variable contains a list of the resources\n        selected based on the parameters provided to the dbt command.\n        Currently, is not populated for the command `run-operation` that\n        doesn't support `--select`.\n        \"\"\"\n        return selected_resources.SELECTED_RESOURCES\n\n    @contextmember()\n    def submit_python_job(self, parsed_model: Dict, compiled_code: str) -> AdapterResponse:\n        # Check macro_stack and that the unique id is for a materialization macro\n        if not (\n            self.context_macro_stack.depth == 2\n            and self.context_macro_stack.call_stack[1] == \"macro.dbt.statement\"\n            and \"materialization\" in self.context_macro_stack.call_stack[0]\n        ):\n            raise DbtRuntimeError(\n                f\"submit_python_job is not intended to be called here, at model {parsed_model['alias']}, with macro call_stack {self.context_macro_stack.call_stack}.\"\n            )\n        return self.adapter.submit_python_job(parsed_model, compiled_code)\n\n\nclass MacroContext(ProviderContext):\n    \"\"\"Internally, macros can be executed like nodes, with some restrictions:\n\n    - they don't have all values available that nodes do:\n       - 'this', 'pre_hooks', 'post_hooks', and 'sql' are missing\n       - 'schema' does not use any 'model' information\n    - they can't be configured with config() directives\n    \"\"\"\n\n    def __init__(\n        self,\n        model: MacroProtocol,\n        config: RuntimeConfig,\n        manifest: Manifest,\n        provider: Provider,\n        search_package: Optional[str],\n    ) -> None:\n        super().__init__(model, config, manifest, provider, None)\n        # override the model-based package with the given one\n        if search_package is None:\n            # if the search package name isn't specified, use the root project\n            self._search_package = config.project_name\n        else:\n            self._search_package = search_package\n\n\nclass SourceContext(ProviderContext):\n    # SourceContext is being used to render jinja SQL during execution of\n    # custom SQL in source freshness. It is not used for parsing.\n    model: SourceDefinition\n\n    @contextproperty()\n    def this(self) -> Optional[RelationProxy]:\n        return self.db_wrapper.Relation.create_from(self.config, self.model)\n\n    @contextproperty()\n    def source_node(self) -> SourceDefinition:\n        return self.model\n\n\nclass ModelContext(ProviderContext):\n    model: ManifestNode\n\n    @contextproperty()\n    def pre_hooks(self) -> List[Dict[str, Any]]:\n        if self.model.resource_type in [NodeType.Source, NodeType.Test, NodeType.Unit]:\n            return []\n        # TODO CT-211\n        return [\n            h.to_dict(omit_none=True) for h in self.model.config.pre_hook  # type: ignore[union-attr] # noqa\n        ]\n\n    @contextproperty()\n    def post_hooks(self) -> List[Dict[str, Any]]:\n        if self.model.resource_type in [NodeType.Source, NodeType.Test, NodeType.Unit]:\n            return []\n        # TODO CT-211\n        return [\n            h.to_dict(omit_none=True) for h in self.model.config.post_hook  # type: ignore[union-attr] # noqa\n        ]\n\n    @contextproperty()\n    def compiled_code(self) -> Optional[str]:\n        # TODO: avoid routing on args.which if possible\n        if getattr(self.model, \"defer_relation\", None) and self.config.args.which == \"clone\":\n            # TODO https://github.com/dbt-labs/dbt-core/issues/7976\n            return f\"select * from {self.model.defer_relation.relation_name or str(self.defer_relation)}\"  # type: ignore[union-attr]\n        elif getattr(self.model, \"extra_ctes_injected\", None):\n            # TODO CT-211\n            return self.model.compiled_code  # type: ignore[union-attr]\n        else:\n            return None\n\n    @contextproperty()\n    def sql(self) -> Optional[str]:\n        # only set this for sql models, for backward compatibility\n        if self.model.language == ModelLanguage.sql:  # type: ignore[union-attr]\n            return self.compiled_code\n        else:\n            return None\n\n    @contextproperty()\n    def database(self) -> str:\n        return getattr(self.model, \"database\", self.config.credentials.database)\n\n    @contextproperty()\n    def schema(self) -> str:\n        return getattr(self.model, \"schema\", self.config.credentials.schema)\n\n    @contextproperty()\n    def this(self) -> Optional[RelationProxy]:\n        \"\"\"`this` makes available schema information about the currently\n        executing model. It's is useful in any context in which you need to\n        write code that references the current model, for example when defining\n        a `sql_where` clause for an incremental model and for writing pre- and\n        post-model hooks that operate on the model in some way. Developers have\n        options for how to use `this`:\n\n            |------------------|------------------|\n            | dbt Model Syntax | Output           |\n            |------------------|------------------|\n            |     {{this}}     | \"schema\".\"table\" |\n            |------------------|------------------|\n            |  {{this.schema}} | schema           |\n            |------------------|------------------|\n            |  {{this.table}}  | table            |\n            |------------------|------------------|\n            |  {{this.name}}   | table            |\n            |------------------|------------------|\n\n        Here's an example of how to use `this` in `dbt_project.yml` to grant\n        select rights on a table to a different db user.\n\n        > example.yml:\n\n            models:\n              project-name:\n                post-hook:\n                  - \"grant select on {{ this }} to db_reader\"\n        \"\"\"\n        if self.model.resource_type == NodeType.Operation:\n            return None\n        return self.db_wrapper.Relation.create_from(self.config, self.model)\n\n    @contextproperty()\n    def defer_relation(self) -> Optional[RelationProxy]:\n        \"\"\"\n        For commands which add information about this node's corresponding\n        production version (via a --state artifact), access the Relation\n        object for that stateful other\n        \"\"\"\n        if getattr(self.model, \"defer_relation\", None):\n            return self.db_wrapper.Relation.create_from(\n                self.config, self.model.defer_relation  # type: ignore\n            )\n        else:\n            return None\n\n\nclass UnitTestContext(ModelContext):\n    model: UnitTestNode\n\n    @contextmember()\n    def env_var(self, var: str, default: Optional[str] = None) -> str:\n        \"\"\"The env_var() function. Return the overriden unit test environment variable named 'var'.\n\n        If there is no unit test override, return the environment variable named 'var'.\n\n        If there is no such environment variable set, return the default.\n\n        If the default is None, raise an exception for an undefined variable.\n        \"\"\"\n        if self.model.overrides and var in self.model.overrides.env_vars:\n            return self.model.overrides.env_vars[var]\n        else:\n            return super().env_var(var, default)\n\n    @contextproperty()\n    def this(self) -> Optional[str]:\n        if self.model.this_input_node_unique_id:\n            this_node = self.manifest.expect(self.model.this_input_node_unique_id)\n            self.model.set_cte(this_node.unique_id, None)  # type: ignore\n            return self.adapter.Relation.add_ephemeral_prefix(this_node.identifier)  # type: ignore\n        return None\n\n\nclass FunctionContext(ModelContext):\n    model: FunctionNode\n\n    @contextproperty()\n    def this(self) -> Optional[RelationProxy]:\n        return self.db_wrapper.Relation.create_from(self.config, self.model)\n\n\n# This is called by '_context_for', used in 'render_with_context'\ndef generate_parser_model_context(\n    model: ManifestNode,\n    config: RuntimeConfig,\n    manifest: Manifest,\n    context_config: ContextConfig,\n) -> Dict[str, Any]:\n    # The __init__ method of ModelContext also initializes\n    # a ManifestContext object which creates a MacroNamespaceBuilder\n    # which adds every macro in the Manifest.\n    ctx = ModelContext(model, config, manifest, ParseProvider(), context_config)\n    # The 'to_dict' method in ManifestContext moves all of the macro names\n    # in the macro 'namespace' up to top level keys\n    return ctx.to_dict()\n\n\ndef generate_parser_unit_test_context(\n    unit_test: UnitTestNode, config: RuntimeConfig, manifest: Manifest\n) -> Dict[str, Any]:\n    context_config = ContextConfig(\n        config,\n        unit_test.fqn,\n        NodeType.Unit,\n        config.project_name,\n    )\n\n    ctx = UnitTestContext(unit_test, config, manifest, ParseProvider(), context_config)\n\n    return ctx.to_dict()\n\n\ndef generate_generate_name_macro_context(\n    macro: Macro,\n    config: RuntimeConfig,\n    manifest: Manifest,\n) -> Dict[str, Any]:\n    ctx = MacroContext(macro, config, manifest, GenerateNameProvider(), None)\n    return ctx.to_dict()\n\n\ndef generate_runtime_model_context(\n    model: ManifestNode,\n    config: RuntimeConfig,\n    manifest: Manifest,\n) -> Dict[str, Any]:\n    ctx = ModelContext(model, config, manifest, RuntimeProvider(), None)\n    return ctx.to_dict()\n\n\ndef generate_runtime_macro_context(\n    macro: MacroProtocol,\n    config: RuntimeConfig,\n    manifest: Manifest,\n    package_name: Optional[str],\n) -> Dict[str, Any]:\n    ctx = MacroContext(macro, config, manifest, OperationProvider(), package_name)\n    return ctx.to_dict()\n\n\ndef generate_runtime_unit_test_context(\n    unit_test: UnitTestNode,\n    config: RuntimeConfig,\n    manifest: Manifest,\n) -> Dict[str, Any]:\n    ctx = UnitTestContext(unit_test, config, manifest, RuntimeUnitTestProvider(), None)\n    ctx_dict = ctx.to_dict()\n\n    if unit_test.overrides and unit_test.overrides.macros:\n        global_macro_overrides: Dict[str, Any] = {}\n        package_macro_overrides: Dict[Tuple[str, str], Any] = {}\n\n        # split macro overrides into global and package-namespaced collections\n        for macro_name, macro_value in unit_test.overrides.macros.items():\n            macro_name_split = macro_name.split(\".\")\n            macro_package = macro_name_split[0] if len(macro_name_split) == 2 else None\n            macro_name = macro_name_split[-1]\n\n            # macro overrides of global macros\n            if macro_package is None and macro_name in ctx_dict:\n                original_context_value = ctx_dict[macro_name]\n                if isinstance(original_context_value, MacroGenerator):\n                    macro_value = UnitTestMacroGenerator(original_context_value, macro_value)\n                global_macro_overrides[macro_name] = macro_value\n\n            # macro overrides of package-namespaced macros\n            elif (\n                macro_package\n                and macro_package in ctx_dict\n                and macro_name in ctx_dict[macro_package]\n            ):\n                original_context_value = ctx_dict[macro_package][macro_name]\n                if isinstance(original_context_value, MacroGenerator):\n                    macro_value = UnitTestMacroGenerator(original_context_value, macro_value)\n                package_macro_overrides[(macro_package, macro_name)] = macro_value\n\n        # macro overrides of package-namespaced macros\n        for (macro_package, macro_name), macro_override_value in package_macro_overrides.items():\n            ctx_dict[macro_package][macro_name] = macro_override_value\n            # propgate override of namespaced dbt macro to global namespace\n            if macro_package == \"dbt\":\n                ctx_dict[macro_name] = macro_value\n\n        # macro overrides of global macros, which should take precedence over equivalent package-namespaced overrides\n        for macro_name, macro_override_value in global_macro_overrides.items():\n            ctx_dict[macro_name] = macro_override_value\n            # propgate override of global dbt macro to dbt namespace\n            if ctx_dict[\"dbt\"].get(macro_name):\n                ctx_dict[\"dbt\"][macro_name] = macro_override_value\n\n    return ctx_dict\n\n\ndef generate_runtime_function_context(\n    function: FunctionNode,\n    config: RuntimeConfig,\n    manifest: Manifest,\n) -> Dict[str, Any]:\n    ctx = FunctionContext(function, config, manifest, OperationProvider(), None)\n    return ctx.to_dict()\n\n\nclass ExposureRefResolver(BaseResolver):\n    def __call__(self, *args, **kwargs) -> str:\n        package = None\n        if len(args) == 1:\n            name = args[0]\n        elif len(args) == 2:\n            package, name = args\n        else:\n            raise RefArgsError(node=self.model, args=args)\n\n        version = kwargs.get(\"version\") or kwargs.get(\"v\")\n\n        self.model.refs.append(RefArgs(package=package, name=name, version=version))\n        return \"\"\n\n\nclass ExposureSourceResolver(BaseResolver):\n    def __call__(self, *args) -> str:\n        if len(args) != 2:\n            raise NumberSourceArgsError(args, node=self.model)\n        self.model.sources.append(list(args))\n        return \"\"\n\n\nclass ExposureMetricResolver(BaseResolver):\n    def __call__(self, *args) -> str:\n        if len(args) not in (1, 2):\n            raise MetricArgsError(node=self.model, args=args)\n        self.model.metrics.append(list(args))\n        return \"\"\n\n\ndef generate_parse_exposure(\n    exposure: Exposure,\n    config: RuntimeConfig,\n    manifest: Manifest,\n    package_name: str,\n) -> Dict[str, Any]:\n    project = config.load_dependencies()[package_name]\n    return {\n        \"ref\": ExposureRefResolver(\n            None,\n            exposure,\n            project,\n            manifest,\n        ),\n        \"source\": ExposureSourceResolver(\n            None,\n            exposure,\n            project,\n            manifest,\n        ),\n        \"metric\": ExposureMetricResolver(\n            None,\n            exposure,\n            project,\n            manifest,\n        ),\n    }\n\n\n# applies to SemanticModels\nclass SemanticModelRefResolver(BaseResolver):\n    def __call__(self, *args, **kwargs) -> str:\n        package = None\n        if len(args) == 1:\n            name = args[0]\n        elif len(args) == 2:\n            package, name = args\n        else:\n            raise RefArgsError(node=self.model, args=args)\n\n        version = kwargs.get(\"version\") or kwargs.get(\"v\")\n        self.validate_args(name, package, version)\n\n        # \"model\" here is any node\n        self.model.refs.append(RefArgs(package=package, name=name, version=version))\n        return \"\"\n\n    def validate_args(self, name, package, version):\n        if not isinstance(name, str):\n            raise ParsingError(\n                f\"In a semantic model or metrics section in {self.model.original_file_path} \"\n                \"the name argument to ref() must be a string\"\n            )\n\n\n# used for semantic models\ndef generate_parse_semantic_models(\n    semantic_model: SemanticModel,\n    config: RuntimeConfig,\n    manifest: Manifest,\n    package_name: str,\n) -> Dict[str, Any]:\n    project = config.load_dependencies()[package_name]\n    return {\n        \"ref\": SemanticModelRefResolver(\n            None,\n            semantic_model,\n            project,\n            manifest,\n        ),\n    }\n\n\n# This class is currently used by the schema parser in order\n# to limit the number of macros in the context by using\n# the TestMacroNamespace\nclass TestContext(ProviderContext):\n    def __init__(\n        self,\n        model,\n        config: RuntimeConfig,\n        manifest: Manifest,\n        provider: Provider,\n        context_config: Optional[ContextConfig],\n        macro_resolver: MacroResolver,\n    ) -> None:\n        # this must be before super init so that macro_resolver exists for\n        # build_namespace\n        self.macro_resolver = macro_resolver\n        self.thread_ctx = MacroStack()\n        super().__init__(model, config, manifest, provider, context_config)\n        self._build_test_namespace()\n        # We need to rebuild this because it's already been built by\n        # the ProviderContext with the wrong namespace.\n        self.db_wrapper = self.provider.DatabaseWrapper(self.adapter, self.namespace)\n\n    def _build_namespace(self):\n        return {}\n\n    # this overrides _build_namespace in ManifestContext which provides a\n    # complete namespace of all macros to only specify macros in the depends_on\n    # This only provides a namespace with macros in the test node\n    # 'depends_on.macros' by using the TestMacroNamespace\n    def _build_test_namespace(self):\n        depends_on_macros = []\n        # all generic tests use a macro named 'get_where_subquery' to wrap 'model' arg\n        # see generic_test_builders.build_model_str\n        get_where_subquery = self.macro_resolver.macros_by_name.get(\"get_where_subquery\")\n        if get_where_subquery:\n            depends_on_macros.append(get_where_subquery.unique_id)\n        if self.model.depends_on and self.model.depends_on.macros:\n            depends_on_macros.extend(self.model.depends_on.macros)\n\n        # When support_custom_ref_kwargs is enabled, include custom ref/source\n        # macro overrides in the test namespace so that test arguments like\n        # ref('model', custom_kwarg=value) are properly resolved.\n        if getattr(get_flags(), \"SUPPORT_CUSTOM_REF_KWARGS\", False):\n            for macro_name in (\"ref\", \"source\"):\n                macro = self.macro_resolver.macros_by_name.get(macro_name)\n                if macro and macro.unique_id not in depends_on_macros:\n                    # Only include user-defined overrides, not built-in macros\n                    if macro.package_name != \"dbt\":\n                        depends_on_macros.append(macro.unique_id)\n\n        lookup_macros = depends_on_macros.copy()\n        for macro_unique_id in lookup_macros:\n            lookup_macro = self.macro_resolver.macros.get(macro_unique_id)\n            if lookup_macro:\n                depends_on_macros.extend(lookup_macro.depends_on.macros)\n\n        macro_namespace = TestMacroNamespace(\n            self.macro_resolver, self._ctx, self.model, self.thread_ctx, depends_on_macros\n        )\n        self.namespace = macro_namespace\n\n    @contextmember()\n    def env_var(self, var: str, default: Optional[str] = None) -> str:\n        return_value = None\n        if var.startswith(SECRET_ENV_PREFIX):\n            raise SecretEnvVarLocationError(var)\n\n        env = get_invocation_context().env\n        if var in env:\n            return_value = env[var]\n        elif default is not None:\n            return_value = default\n\n        if return_value is not None:\n            # Save the env_var value in the manifest and the var name in the source_file\n            if self.model:\n                # If the environment variable is set from a default, store a string indicating\n                # that so we can skip partial parsing.  Otherwise the file will be scheduled for\n                # reparsing. If the default changes, the file will have been updated and therefore\n                # will be scheduled for reparsing anyways.\n                self.manifest.env_vars[var] = (\n                    return_value if var in env else DEFAULT_ENV_PLACEHOLDER\n                )\n                # the \"model\" should only be test nodes, but just in case, check\n                # TODO CT-211\n                if self.model.resource_type == NodeType.Test and self.model.file_key_name:  # type: ignore[union-attr] # noqa\n                    source_file = self.manifest.files[self.model.file_id]\n                    # TODO CT-211\n                    (yaml_key, name) = self.model.file_key_name.split(\".\")  # type: ignore[union-attr] # noqa\n                    # TODO CT-211\n                    source_file.add_env_var(var, yaml_key, name)  # type: ignore[union-attr]\n            return return_value\n        else:\n            raise EnvVarMissingError(var)\n\n\ndef generate_test_context(\n    model: ManifestNode,\n    config: RuntimeConfig,\n    manifest: Manifest,\n    context_config: ContextConfig,\n    macro_resolver: MacroResolver,\n) -> Dict[str, Any]:\n    ctx = TestContext(model, config, manifest, ParseProvider(), context_config, macro_resolver)\n    # The 'to_dict' method in ManifestContext moves all of the macro names\n    # in the macro 'namespace' up to top level keys\n    return ctx.to_dict()\n"
  },
  {
    "path": "core/dbt/context/query_header.py",
    "content": "from dbt.adapters.contracts.connection import AdapterRequiredConfig\nfrom dbt.context.manifest import ManifestContext\nfrom dbt.contracts.graph.manifest import Manifest\n\n\nclass QueryHeaderContext(ManifestContext):\n    def __init__(self, config: AdapterRequiredConfig, manifest: Manifest) -> None:\n        super().__init__(config, manifest, config.project_name)\n\n\ndef generate_query_header_context(config: AdapterRequiredConfig, manifest: Manifest):\n    ctx = QueryHeaderContext(config, manifest)\n    return ctx.to_dict()\n"
  },
  {
    "path": "core/dbt/context/secret.py",
    "content": "from typing import Any, Dict, Optional\n\nfrom dbt.constants import DEFAULT_ENV_PLACEHOLDER, SECRET_PLACEHOLDER\nfrom dbt.exceptions import EnvVarMissingError\nfrom dbt_common.constants import SECRET_ENV_PREFIX\nfrom dbt_common.context import get_invocation_context\n\nfrom .base import BaseContext, contextmember\n\n\nclass SecretContext(BaseContext):\n    \"\"\"This context is used in profiles.yml + packages.yml. It can render secret\n    env vars that aren't usable elsewhere\"\"\"\n\n    @contextmember()\n    def env_var(self, var: str, default: Optional[str] = None) -> str:\n        \"\"\"The env_var() function. Return the environment variable named 'var'.\n        If there is no such environment variable set, return the default.\n\n        If the default is None, raise an exception for an undefined variable.\n\n        In this context *only*, env_var will accept env vars prefixed with DBT_ENV_SECRET_.\n        It will return the name of the secret env var, wrapped in 'start' and 'end' identifiers.\n        The actual value will be subbed in later in SecretRenderer.render_value()\n        \"\"\"\n        return_value = None\n\n        # if this is a 'secret' env var, just return the name of the env var\n        # instead of rendering the actual value here, to avoid any risk of\n        # Jinja manipulation. it will be subbed out later, in SecretRenderer.render_value\n        env = get_invocation_context().env\n        if var in env and var.startswith(SECRET_ENV_PREFIX):\n            return SECRET_PLACEHOLDER.format(var)\n\n        if var in env:\n            return_value = env[var]\n        elif default is not None:\n            return_value = default\n\n        if return_value is not None:\n            # store env vars in the internal manifest to power partial parsing\n            # if it's a 'secret' env var, we shouldn't even get here\n            # but just to be safe, don't save secrets\n            if not var.startswith(SECRET_ENV_PREFIX):\n                # If the environment variable is set from a default, store a string indicating\n                # that so we can skip partial parsing.  Otherwise the file will be scheduled for\n                # reparsing. If the default changes, the file will have been updated and therefore\n                # will be scheduled for reparsing anyways.\n                self.env_vars[var] = return_value if var in env else DEFAULT_ENV_PLACEHOLDER\n            return return_value\n        else:\n            raise EnvVarMissingError(var)\n\n\ndef generate_secret_context(cli_vars: Dict[str, Any]) -> Dict[str, Any]:\n    ctx = SecretContext(cli_vars)\n    # This is not a Mashumaro to_dict call\n    return ctx.to_dict()\n"
  },
  {
    "path": "core/dbt/context/target.py",
    "content": "from typing import Any, Dict\n\nfrom dbt.context.base import BaseContext, contextproperty\n\n\nclass TargetContext(BaseContext):\n    # subclass is ConfiguredContext\n    def __init__(\n        self, target_dict: Dict[str, Any], cli_vars: Dict[str, Any], require_vars: bool = True\n    ):\n        super().__init__(cli_vars=cli_vars, require_vars=require_vars)\n        self.target_dict = target_dict\n\n    @contextproperty()\n    def target(self) -> Dict[str, Any]:\n        \"\"\"`target` contains information about your connection to the warehouse\n        (specified in profiles.yml). Some configs are shared between all\n        adapters, while others are adapter-specific.\n\n        Common:\n\n            |----------|-----------|------------------------------------------|\n            | Variable |  Example  |                Description               |\n            |----------|-----------|------------------------------------------|\n            |   name   |    dev    | Name of the active target                |\n            |----------|-----------|------------------------------------------|\n            |  schema  | dbt_alice | Name of the dbt schema (or, dataset on   |\n            |          |           | BigQuery)                                |\n            |----------|-----------|------------------------------------------|\n            |   type   |  postgres | The active adapter being used.           |\n            |----------|-----------|------------------------------------------|\n            | threads  |    4      | The number of threads in use by dbt      |\n            |----------|-----------|------------------------------------------|\n\n        Snowflake:\n\n            |----------|-----------|------------------------------------------|\n            | Variable |  Example  |                Description               |\n            |----------|-----------|------------------------------------------|\n            | database |    RAW    | The active target's database.            |\n            |----------|-----------|------------------------------------------|\n            | warehouse| TRANSFORM | The active target's warehouse.           |\n            |----------|-----------|------------------------------------------|\n            |   user   |  USERNAME | The active target's user                 |\n            |----------|-----------|------------------------------------------|\n            | role     |  ROLENAME | The active target's role                 |\n            |----------|-----------|------------------------------------------|\n            | account  |  abc123   | The active target's account              |\n            |----------|-----------|------------------------------------------|\n\n        Postgres/Redshift:\n\n            |----------|-------------------|----------------------------------|\n            | Variable |  Example          |        Description               |\n            |----------|-------------------|----------------------------------|\n            |  dbname  | analytics         | The active target's database.    |\n            |----------|-------------------|----------------------------------|\n            |  host    | abc123.us-west-2. | The active target's host.        |\n            |          | redshift.amazonaws|                                  |\n            |          |  .com             |                                  |\n            |----------|-------------------|----------------------------------|\n            |   user   |  dbt_user         |  The active target's user        |\n            |----------|-------------------|----------------------------------|\n            |   port   |    5439           | The active target's port         |\n            |----------|-------------------|----------------------------------|\n\n        BigQuery:\n\n            |----------|-----------|------------------------------------------|\n            | Variable |  Example  |                Description               |\n            |----------|-----------|------------------------------------------|\n            | project  |  abc-123  | The active target's project.             |\n            |----------|-----------|------------------------------------------|\n\n        \"\"\"\n        return self.target_dict\n"
  },
  {
    "path": "core/dbt/contracts/README.md",
    "content": "# Contracts README\n\n\n## Artifacts\n\n### Generating JSON schemas\nA helper script, `scripts/collect-artifact-schema.py` is available to generate json schemas corresponding to versioned artifacts (`ArtifactMixin`s).\n\nThis script is necessary to run when a new artifact schema version is created, or when changes are made to existing artifact versions, and writes json schema to `schema/dbt/<artifact>/v<version>.json`.\n\nSchemas in `schema/dbt` power the rendering in https://schemas.getdbt.com/ via https://github.com/dbt-labs/schemas.getdbt.com/\n\n#### Example Usage\n\nAvailable arguments:\n```sh\n❯ scripts/collect-artifact-schema.py --help\nusage: Collect and write dbt arfifact schema [-h] [--path PATH] [--artifact {manifest,sources,run-results,catalog}]\n\noptions:\n  -h, --help            show this help message and exit\n  --path PATH           The dir to write artifact schema\n  --artifact {manifest,sources,run-results,catalog}\n                        The name of the artifact to update\n```\n\nGenerate latest version of schemas of all artifacts to `schema/dbt/<artifact>/v<version>.json`\n```sh\n> sripts/collect-artifact-schema.py --path schemas\n```\n\nGenerate latest version of schemas of manifest to `schema/dbt/manifest/v<version>.json`\n```sh\n> sripts/collect-artifact-schema.py --path schemas --artifact manifest\n```\n"
  },
  {
    "path": "core/dbt/contracts/__init__.py",
    "content": ""
  },
  {
    "path": "core/dbt/contracts/files.py",
    "content": "import os\nfrom dataclasses import dataclass, field\nfrom typing import Any, Dict, List, Optional, Union\n\nfrom mashumaro.types import SerializableType\n\nfrom dbt.artifacts.resources.base import FileHash\nfrom dbt.constants import MAXIMUM_SEED_SIZE\nfrom dbt_common.dataclass_schema import StrEnum, dbtClassMixin\n\nfrom .util import SourceKey\n\n\nclass ParseFileType(StrEnum):\n    Macro = \"macro\"\n    Model = \"model\"\n    Snapshot = \"snapshot\"\n    Analysis = \"analysis\"\n    SingularTest = \"singular_test\"\n    GenericTest = \"generic_test\"\n    Seed = \"seed\"\n    Documentation = \"docs\"\n    Schema = \"schema\"\n    Hook = \"hook\"  # not a real filetype, from dbt_project.yml\n    Fixture = \"fixture\"\n    Function = \"function\"\n\n\nparse_file_type_to_parser = {\n    ParseFileType.Macro: \"MacroParser\",\n    ParseFileType.Model: \"ModelParser\",\n    ParseFileType.Snapshot: \"SnapshotParser\",\n    ParseFileType.Analysis: \"AnalysisParser\",\n    ParseFileType.SingularTest: \"SingularTestParser\",\n    ParseFileType.GenericTest: \"GenericTestParser\",\n    ParseFileType.Seed: \"SeedParser\",\n    ParseFileType.Documentation: \"DocumentationParser\",\n    ParseFileType.Schema: \"SchemaParser\",\n    ParseFileType.Hook: \"HookParser\",\n    ParseFileType.Fixture: \"FixtureParser\",\n    ParseFileType.Function: \"FunctionParser\",\n}\n\n\n@dataclass\nclass FilePath(dbtClassMixin):\n    searched_path: str\n    relative_path: str\n    modification_time: float\n    project_root: str\n\n    @property\n    def search_key(self) -> str:\n        # TODO: should this be project name + path relative to project root?\n        return self.absolute_path\n\n    @property\n    def full_path(self) -> str:\n        # useful for symlink preservation\n        return os.path.join(self.project_root, self.searched_path, self.relative_path)\n\n    @property\n    def absolute_path(self) -> str:\n        return os.path.abspath(self.full_path)\n\n    @property\n    def original_file_path(self) -> str:\n        return os.path.join(self.searched_path, self.relative_path)\n\n    def seed_too_large(self) -> bool:\n        \"\"\"Return whether the file this represents is over the seed size limit\"\"\"\n        return os.stat(self.full_path).st_size > MAXIMUM_SEED_SIZE\n\n\n@dataclass\nclass RemoteFile(dbtClassMixin):\n    def __init__(self, language) -> None:\n        if language == \"sql\":\n            self.path_end = \".sql\"\n        elif language == \"python\":\n            self.path_end = \".py\"\n        else:\n            raise RuntimeError(f\"Invalid language for remote File {language}\")\n        self.path = f\"from remote system{self.path_end}\"\n\n    @property\n    def searched_path(self) -> str:\n        return self.path\n\n    @property\n    def relative_path(self) -> str:\n        return self.path\n\n    @property\n    def absolute_path(self) -> str:\n        return self.path\n\n    @property\n    def original_file_path(self):\n        return self.path\n\n    @property\n    def modification_time(self):\n        return self.path\n\n\n@dataclass\nclass BaseSourceFile(dbtClassMixin, SerializableType):\n    \"\"\"Define a source file in dbt\"\"\"\n\n    path: Union[FilePath, RemoteFile]  # the path information\n    checksum: FileHash\n    # Seems like knowing which project the file came from would be useful\n    project_name: Optional[str] = None\n    # Parse file type: i.e. which parser will process this file\n    parse_file_type: Optional[ParseFileType] = None\n    # we don't want to serialize this\n    contents: Optional[str] = None\n\n    @property\n    def file_id(self):\n        if isinstance(self.path, RemoteFile):\n            return None\n        return f\"{self.project_name}://{self.path.original_file_path}\"\n\n    @property\n    def original_file_path(self):\n        return self.path.original_file_path\n\n    def _serialize(self):\n        dct = self.to_dict()\n        return dct\n\n    @classmethod\n    def _deserialize(cls, dct: Dict[str, int]):\n        if dct[\"parse_file_type\"] == \"schema\":\n            sf = SchemaSourceFile.from_dict(dct)\n        elif dct[\"parse_file_type\"] == \"fixture\":\n            sf = FixtureSourceFile.from_dict(dct)\n        else:\n            sf = SourceFile.from_dict(dct)\n        return sf\n\n    def __post_serialize__(self, dct: Dict, context: Optional[Dict] = None):\n        dct = super().__post_serialize__(dct, context)\n        # remove empty lists to save space\n        dct_keys = list(dct.keys())\n        for key in dct_keys:\n            if isinstance(dct[key], list) and not dct[key]:\n                del dct[key]\n        # remove contents. Schema files will still have 'dict_from_yaml'\n        # from the contents\n        if \"contents\" in dct:\n            del dct[\"contents\"]\n        return dct\n\n\n@dataclass\nclass SourceFile(BaseSourceFile):\n    nodes: List[str] = field(default_factory=list)\n    docs: List[str] = field(default_factory=list)\n    macros: List[str] = field(default_factory=list)\n    env_vars: List[str] = field(default_factory=list)\n    functions: List[str] = field(default_factory=list)\n\n    @classmethod\n    def big_seed(cls, path: FilePath) -> \"SourceFile\":\n        \"\"\"Parse seeds over the size limit with just the path\"\"\"\n        self = cls(path=path, checksum=FileHash.path(path.original_file_path))\n        self.contents = \"\"\n        return self\n\n    def add_node(self, value):\n        if value not in self.nodes:\n            self.nodes.append(value)\n\n    # TODO: do this a different way. This remote file kludge isn't going\n    # to work long term\n    @classmethod\n    def remote(cls, contents: str, project_name: str, language: str) -> \"SourceFile\":\n        self = cls(\n            path=RemoteFile(language),\n            checksum=FileHash.from_contents(contents),\n            project_name=project_name,\n            contents=contents,\n        )\n        return self\n\n\n@dataclass\nclass SchemaSourceFile(BaseSourceFile):\n    dfy: Dict[str, Any] = field(default_factory=dict)\n    # these are in the manifest.nodes dictionary\n    data_tests: Dict[str, Any] = field(default_factory=dict)\n    sources: List[str] = field(default_factory=list)\n    exposures: List[str] = field(default_factory=list)\n    functions: List[str] = field(default_factory=list)\n    metrics: List[str] = field(default_factory=list)\n    snapshots: List[str] = field(default_factory=list)\n    # The following field will no longer be used. Leaving\n    # here to avoid breaking existing projects. To be removed\n    # later if possible.\n    generated_metrics: List[str] = field(default_factory=list)\n    # metrics generated from semantic_model measures. The key is\n    # the name of the semantic_model, so that we can find it later.\n    metrics_from_measures: Dict[str, Any] = field(default_factory=dict)\n    groups: List[str] = field(default_factory=list)\n    # node patches contain models, seeds, snapshots, analyses\n    ndp: List[str] = field(default_factory=list)\n    semantic_models: List[str] = field(default_factory=list)\n    unit_tests: List[str] = field(default_factory=list)\n    saved_queries: List[str] = field(default_factory=list)\n    # any macro patches in this file by macro unique_id.\n    mcp: Dict[str, str] = field(default_factory=dict)\n    # any source patches in this file. The entries are package, name pairs\n    # Patches are only against external sources. Sources can be\n    # created too, but those are in 'sources'\n    sop: List[SourceKey] = field(default_factory=list)\n    env_vars: Dict[str, Any] = field(default_factory=dict)\n    unrendered_configs: Dict[str, Any] = field(default_factory=dict)\n    unrendered_databases: Dict[str, Any] = field(default_factory=dict)\n    unrendered_schemas: Dict[str, Any] = field(default_factory=dict)\n    pp_dict: Optional[Dict[str, Any]] = None\n    pp_test_index: Optional[Dict[str, Any]] = None\n\n    @property\n    def dict_from_yaml(self):\n        return self.dfy\n\n    @property\n    def node_patches(self):\n        return self.ndp\n\n    @property\n    def macro_patches(self):\n        return self.mcp\n\n    @property\n    def source_patches(self):\n        return self.sop\n\n    def __post_serialize__(self, dct: Dict, context: Optional[Dict] = None):\n        dct = super().__post_serialize__(dct, context)\n        # Remove partial parsing specific data\n        for key in (\"pp_test_index\", \"pp_dict\"):\n            if key in dct:\n                del dct[key]\n        return dct\n\n    def append_patch(self, yaml_key, unique_id):\n        self.node_patches.append(unique_id)\n\n    def add_test(self, node_unique_id, test_from):\n        name = test_from[\"name\"]\n        key = test_from[\"key\"]\n        if key not in self.data_tests:\n            self.data_tests[key] = {}\n        if name not in self.data_tests[key]:\n            self.data_tests[key][name] = []\n        self.data_tests[key][name].append(node_unique_id)\n\n    # this is only used in tests/unit\n    def remove_tests(self, yaml_key, name):\n        if yaml_key in self.data_tests:\n            if name in self.data_tests[yaml_key]:\n                del self.data_tests[yaml_key][name]\n\n    # this is only used in the tests directory (unit + functional)\n    def get_tests(self, yaml_key, name):\n        if yaml_key in self.data_tests:\n            if name in self.data_tests[yaml_key]:\n                return self.data_tests[yaml_key][name]\n        return []\n\n    def add_metrics_from_measures(self, semantic_model_name: str, metric_unique_id: str):\n        if self.generated_metrics:\n            # Probably not needed, but for safety sake, convert the\n            # old generated_metrics to metrics_from_measures.\n            self.fix_metrics_from_measures()\n        if semantic_model_name not in self.metrics_from_measures:\n            self.metrics_from_measures[semantic_model_name] = []\n        self.metrics_from_measures[semantic_model_name].append(metric_unique_id)\n\n    def fix_metrics_from_measures(self):\n        # Temporary method to fix up existing projects with a partial parse file.\n        # This should only be called if SchemaSourceFile in a msgpack\n        # pack manifest has an existing \"generated_metrics\" list, to turn it\n        # it into a \"metrics_from_measures\" dictionary, so that we can\n        # correctly partially parse.\n        # This code can be removed when \"generated_metrics\" is removed.\n        generated_metrics = self.generated_metrics\n        self.generated_metrics = []  # Should never be needed again\n        # For each metric_unique_id we loop through the semantic models\n        # looking for the name of the \"measure\" which generated the metric.\n        # When it's found, add it to \"metrics_from_measures\", with a key\n        # of the semantic_model name, and a list of metrics.\n        for metric_unique_id in generated_metrics:\n            parts = metric_unique_id.split(\".\")\n            # get the metric_name\n            metric_name = parts[-1]\n            if \"semantic_models\" in self.dict_from_yaml:\n                for sem_model in self.dict_from_yaml[\"semantic_models\"]:\n                    if \"measures\" in sem_model:\n                        for measure in sem_model[\"measures\"]:\n                            if measure[\"name\"] == metric_name:\n                                self.add_metrics_from_measures(sem_model[\"name\"], metric_unique_id)\n                                break\n\n    def get_key_and_name_for_test(self, test_unique_id):\n        yaml_key = None\n        block_name = None\n        for key in self.data_tests.keys():\n            for name in self.data_tests[key]:\n                for unique_id in self.data_tests[key][name]:\n                    if unique_id == test_unique_id:\n                        yaml_key = key\n                        block_name = name\n                        break\n        return (yaml_key, block_name)\n\n    def get_all_test_ids(self):\n        test_ids = []\n        for key in self.data_tests.keys():\n            for name in self.data_tests[key]:\n                test_ids.extend(self.data_tests[key][name])\n        return test_ids\n\n    def add_unrendered_config(self, unrendered_config, yaml_key, name, version=None):\n        versioned_name = f\"{name}_v{version}\" if version is not None else name\n\n        if yaml_key not in self.unrendered_configs:\n            self.unrendered_configs[yaml_key] = {}\n\n        if versioned_name not in self.unrendered_configs[yaml_key]:\n            self.unrendered_configs[yaml_key][versioned_name] = unrendered_config\n\n    def get_unrendered_config(self, yaml_key, name, version=None) -> Optional[Dict[str, Any]]:\n        versioned_name = f\"{name}_v{version}\" if version is not None else name\n\n        if yaml_key not in self.unrendered_configs:\n            return None\n        if versioned_name not in self.unrendered_configs[yaml_key]:\n            return None\n\n        return self.unrendered_configs[yaml_key][versioned_name]\n\n    def delete_from_unrendered_configs(self, yaml_key, name):\n        # We delete all unrendered_configs for this yaml_key/name because the\n        # entry has been scheduled for reparsing.\n        if self.get_unrendered_config(yaml_key, name):\n            del self.unrendered_configs[yaml_key][name]\n            # Delete all versioned keys associated with name\n            version_names_to_delete = []\n            for potential_version_name in self.unrendered_configs[yaml_key]:\n                if potential_version_name.startswith(f\"{name}_v\"):\n                    version_names_to_delete.append(potential_version_name)\n            for version_name in version_names_to_delete:\n                del self.unrendered_configs[yaml_key][version_name]\n\n            if not self.unrendered_configs[yaml_key]:\n                del self.unrendered_configs[yaml_key]\n\n    def add_env_var(self, var, yaml_key, name):\n        if yaml_key not in self.env_vars:\n            self.env_vars[yaml_key] = {}\n        if name not in self.env_vars[yaml_key]:\n            self.env_vars[yaml_key][name] = []\n        if var not in self.env_vars[yaml_key][name]:\n            self.env_vars[yaml_key][name].append(var)\n\n    def delete_from_env_vars(self, yaml_key, name):\n        # We delete all vars for this yaml_key/name because the\n        # entry has been scheduled for reparsing.\n        if yaml_key in self.env_vars and name in self.env_vars[yaml_key]:\n            del self.env_vars[yaml_key][name]\n            if not self.env_vars[yaml_key]:\n                del self.env_vars[yaml_key]\n\n    def add_unrendered_database(self, yaml_key: str, name: str, unrendered_database: str) -> None:\n        if yaml_key not in self.unrendered_databases:\n            self.unrendered_databases[yaml_key] = {}\n\n        self.unrendered_databases[yaml_key][name] = unrendered_database\n\n    def get_unrendered_database(self, yaml_key: str, name: str) -> Optional[str]:\n        if yaml_key not in self.unrendered_databases:\n            return None\n\n        return self.unrendered_databases[yaml_key].get(name)\n\n    def add_unrendered_schema(self, yaml_key: str, name: str, unrendered_schema: str) -> None:\n        if yaml_key not in self.unrendered_schemas:\n            self.unrendered_schemas[yaml_key] = {}\n\n        self.unrendered_schemas[yaml_key][name] = unrendered_schema\n\n    def get_unrendered_schema(self, yaml_key: str, name: str) -> Optional[str]:\n        if yaml_key not in self.unrendered_schemas:\n            return None\n\n        return self.unrendered_schemas[yaml_key].get(name)\n\n\n@dataclass\nclass FixtureSourceFile(BaseSourceFile):\n    fixture: Optional[str] = None\n    unit_tests: List[str] = field(default_factory=list)\n\n    def add_unit_test(self, value):\n        if value not in self.unit_tests:\n            self.unit_tests.append(value)\n\n\nAnySourceFile = Union[SchemaSourceFile, SourceFile, FixtureSourceFile]\n"
  },
  {
    "path": "core/dbt/contracts/graph/__init__.py",
    "content": ""
  },
  {
    "path": "core/dbt/contracts/graph/manifest.py",
    "content": "import enum\nfrom collections import defaultdict\nfrom dataclasses import dataclass, field, replace\nfrom itertools import chain\nfrom multiprocessing.synchronize import Lock\nfrom typing import (\n    Any,\n    Callable,\n    ClassVar,\n    DefaultDict,\n    Dict,\n    Generic,\n    List,\n    Mapping,\n    MutableMapping,\n    Optional,\n    Set,\n    Tuple,\n    TypeVar,\n    Union,\n)\n\nfrom typing_extensions import Protocol\n\nimport dbt_common.exceptions\nimport dbt_common.utils\nfrom dbt import deprecations, tracking\nfrom dbt.adapters.exceptions import (\n    DuplicateMacroInPackageError,\n    DuplicateMaterializationNameError,\n)\nfrom dbt.adapters.factory import get_adapter_package_names\n\n# to preserve import paths\nfrom dbt.artifacts.resources import (\n    BaseResource,\n    DeferFunction,\n    DeferRelation,\n    NodeConfig,\n    NodeVersion,\n    RefArgs,\n)\nfrom dbt.artifacts.schemas.manifest import ManifestMetadata, UniqueID, WritableManifest\nfrom dbt.clients.jinja_static import statically_parse_ref_or_source\nfrom dbt.contracts.files import (\n    AnySourceFile,\n    FileHash,\n    FixtureSourceFile,\n    SchemaSourceFile,\n    SourceFile,\n)\nfrom dbt.contracts.graph.nodes import (\n    RESOURCE_CLASS_TO_NODE_CLASS,\n    BaseNode,\n    Documentation,\n    Exposure,\n    FunctionNode,\n    GenericTestNode,\n    GraphMemberNode,\n    Group,\n    Macro,\n    ManifestNode,\n    Metric,\n    ModelNode,\n    SavedQuery,\n    SeedNode,\n    SemanticModel,\n    SingularTestNode,\n    SnapshotNode,\n    SourceDefinition,\n    UnitTestDefinition,\n    UnitTestFileFixture,\n    UnpatchedSourceDefinition,\n)\nfrom dbt.contracts.graph.unparsed import SourcePatch, UnparsedVersion\nfrom dbt.contracts.util import SourceKey\nfrom dbt.events.types import ArtifactWritten, UnpinnedRefNewVersionAvailable\nfrom dbt.exceptions import (\n    AmbiguousResourceNameRefError,\n    CompilationError,\n    DuplicateResourceNameError,\n)\nfrom dbt.flags import get_flags\nfrom dbt.mp_context import get_mp_context\nfrom dbt.node_types import (\n    REFABLE_NODE_TYPES,\n    VERSIONED_NODE_TYPES,\n    AccessType,\n    NodeType,\n)\nfrom dbt_common.dataclass_schema import dbtClassMixin\nfrom dbt_common.events.contextvars import get_node_info\nfrom dbt_common.events.functions import fire_event\nfrom dbt_common.helper_types import PathSet\n\nPackageName = str\nDocName = str\nRefName = str\n\n\ndef find_unique_id_for_package(storage, key, package: Optional[PackageName]) -> Optional[UniqueID]:\n    if key not in storage:\n        return None\n\n    pkg_dct: Mapping[PackageName, UniqueID] = storage[key]\n\n    if package is None:\n        if not pkg_dct:\n            return None\n        else:\n            return next(iter(pkg_dct.values()))\n    elif package in pkg_dct:\n        return pkg_dct[package]\n    else:\n        return None\n\n\nclass DocLookup(dbtClassMixin):\n    def __init__(self, manifest: \"Manifest\") -> None:\n        self.storage: Dict[str, Dict[PackageName, UniqueID]] = {}\n        self.populate(manifest)\n\n    def get_unique_id(self, key, package: Optional[PackageName]):\n        return find_unique_id_for_package(self.storage, key, package)\n\n    def find(self, key, package: Optional[PackageName], manifest: \"Manifest\"):\n        unique_id = self.get_unique_id(key, package)\n        if unique_id is not None:\n            return self.perform_lookup(unique_id, manifest)\n        return None\n\n    def add_doc(self, doc: Documentation):\n        if doc.name not in self.storage:\n            self.storage[doc.name] = {}\n        self.storage[doc.name][doc.package_name] = doc.unique_id\n\n    def populate(self, manifest):\n        for doc in manifest.docs.values():\n            self.add_doc(doc)\n\n    def perform_lookup(self, unique_id: UniqueID, manifest) -> Documentation:\n        if unique_id not in manifest.docs:\n            raise dbt_common.exceptions.DbtInternalError(\n                f\"Doc {unique_id} found in cache but not found in manifest\"\n            )\n        return manifest.docs[unique_id]\n\n\nclass SourceLookup(dbtClassMixin):\n    def __init__(self, manifest: \"Manifest\") -> None:\n        self.storage: Dict[str, Dict[PackageName, UniqueID]] = {}\n        self.populate(manifest)\n\n    def get_unique_id(self, search_name, package: Optional[PackageName]):\n        return find_unique_id_for_package(self.storage, search_name, package)\n\n    def find(self, search_name, package: Optional[PackageName], manifest: \"Manifest\"):\n        unique_id = self.get_unique_id(search_name, package)\n        if unique_id is not None:\n            return self.perform_lookup(unique_id, manifest)\n        return None\n\n    def add_source(self, source: SourceDefinition):\n        if source.search_name not in self.storage:\n            self.storage[source.search_name] = {}\n\n        self.storage[source.search_name][source.package_name] = source.unique_id\n\n    def populate(self, manifest):\n        for source in manifest.sources.values():\n            if hasattr(source, \"source_name\"):\n                self.add_source(source)\n\n    def perform_lookup(self, unique_id: UniqueID, manifest: \"Manifest\") -> SourceDefinition:\n        if unique_id not in manifest.sources:\n            raise dbt_common.exceptions.DbtInternalError(\n                f\"Source {unique_id} found in cache but not found in manifest\"\n            )\n        return manifest.sources[unique_id]\n\n\nclass FunctionLookup(dbtClassMixin):\n    def __init__(self, manifest: \"Manifest\") -> None:\n        self.storage: Dict[str, Dict[PackageName, UniqueID]] = {}\n        self.populate(manifest)\n\n    def get_unique_id(self, search_name, package: Optional[PackageName]):\n        return find_unique_id_for_package(self.storage, search_name, package)\n\n    def find(self, search_name, package: Optional[PackageName], manifest: \"Manifest\"):\n        unique_id = self.get_unique_id(search_name, package)\n        if unique_id is not None:\n            return self.perform_lookup(unique_id, manifest)\n        return None\n\n    def add_function(self, function: FunctionNode):\n        if function.search_name not in self.storage:\n            self.storage[function.search_name] = {}\n\n        self.storage[function.search_name][function.package_name] = function.unique_id\n\n    def populate(self, manifest):\n        for function in manifest.functions.values():\n            if hasattr(function, \"name\"):\n                self.add_function(function)\n\n    def perform_lookup(self, unique_id: UniqueID, manifest: \"Manifest\") -> FunctionNode:\n        if unique_id not in manifest.functions:\n            raise dbt_common.exceptions.DbtInternalError(\n                f\"Function {unique_id} found in cache but not found in manifest\"\n            )\n        return manifest.functions[unique_id]\n\n\nclass RefableLookup(dbtClassMixin):\n    # model, seed, snapshot, function\n    _lookup_types: ClassVar[set] = set(REFABLE_NODE_TYPES)\n    _versioned_types: ClassVar[set] = set(VERSIONED_NODE_TYPES)\n\n    def __init__(self, manifest: \"Manifest\") -> None:\n        self.storage: Dict[str, Dict[PackageName, UniqueID]] = {}\n        self.populate(manifest)\n\n    def get_unique_id(\n        self,\n        key: str,\n        package: Optional[PackageName],\n        version: Optional[NodeVersion],\n        node: Optional[GraphMemberNode] = None,\n    ):\n        if version:\n            key = f\"{key}.v{version}\"\n\n        unique_ids = self._find_unique_ids_for_package(key, package)\n        if len(unique_ids) > 1:\n            raise AmbiguousResourceNameRefError(key, unique_ids, node)\n        else:\n            return unique_ids[0] if unique_ids else None\n\n    def find(\n        self,\n        key: str,\n        package: Optional[PackageName],\n        version: Optional[NodeVersion],\n        manifest: \"Manifest\",\n        source_node: Optional[GraphMemberNode] = None,\n    ):\n        unique_id = self.get_unique_id(key, package, version, source_node)\n        if unique_id is not None:\n            node = self.perform_lookup(unique_id, manifest)\n            # If this is an unpinned ref (no 'version' arg was passed),\n            # AND this is a versioned node,\n            # AND this ref is being resolved at runtime -- get_node_info != {}\n            # Only ModelNodes can be versioned.\n            if (\n                isinstance(node, ModelNode)\n                and version is None\n                and node.is_versioned\n                and get_node_info()\n            ):\n                # Check to see if newer versions are available, and log an \"FYI\" if so\n                max_version: UnparsedVersion = max(\n                    [\n                        UnparsedVersion(v.version)\n                        for v in manifest.nodes.values()\n                        if isinstance(v, ModelNode)\n                        and v.name == node.name\n                        and v.version is not None\n                    ]\n                )\n                assert node.latest_version is not None  # for mypy, whenever i may find it\n                if max_version > UnparsedVersion(node.latest_version):\n                    fire_event(\n                        UnpinnedRefNewVersionAvailable(\n                            node_info=get_node_info(),\n                            ref_node_name=node.name,\n                            ref_node_package=node.package_name,\n                            ref_node_version=str(node.version),\n                            ref_max_version=str(max_version.v),\n                        )\n                    )\n\n            return node\n        return None\n\n    def add_node(self, node: ManifestNode):\n        if node.resource_type in self._lookup_types:\n            if node.name not in self.storage:\n                self.storage[node.name] = {}\n\n            if node.is_versioned:\n                if node.search_name not in self.storage:\n                    self.storage[node.search_name] = {}\n                self.storage[node.search_name][node.package_name] = node.unique_id\n                if node.is_latest_version:  # type: ignore\n                    self.storage[node.name][node.package_name] = node.unique_id\n            else:\n                self.storage[node.name][node.package_name] = node.unique_id\n\n    def populate(self, manifest):\n        for node in manifest.nodes.values():\n            self.add_node(node)\n\n    def perform_lookup(self, unique_id: UniqueID, manifest) -> ManifestNode:\n        if unique_id in manifest.nodes:\n            node = manifest.nodes[unique_id]\n        else:\n            raise dbt_common.exceptions.DbtInternalError(\n                f\"Node {unique_id} found in cache but not found in manifest\"\n            )\n        return node\n\n    def _find_unique_ids_for_package(self, key, package: Optional[PackageName]) -> List[str]:\n        if key not in self.storage:\n            return []\n\n        pkg_dct: Mapping[PackageName, UniqueID] = self.storage[key]\n\n        if package is None:\n            if not pkg_dct:\n                return []\n            else:\n                return list(pkg_dct.values())\n        elif package in pkg_dct:\n            return [pkg_dct[package]]\n        else:\n            return []\n\n\nclass MetricLookup(dbtClassMixin):\n    def __init__(self, manifest: \"Manifest\") -> None:\n        self.storage: Dict[str, Dict[PackageName, UniqueID]] = {}\n        self.populate(manifest)\n\n    def get_unique_id(self, search_name, package: Optional[PackageName]):\n        return find_unique_id_for_package(self.storage, search_name, package)\n\n    def find(self, search_name, package: Optional[PackageName], manifest: \"Manifest\"):\n        unique_id = self.get_unique_id(search_name, package)\n        if unique_id is not None:\n            return self.perform_lookup(unique_id, manifest)\n        return None\n\n    def add_metric(self, metric: Metric):\n        if metric.search_name not in self.storage:\n            self.storage[metric.search_name] = {}\n\n        self.storage[metric.search_name][metric.package_name] = metric.unique_id\n\n    def populate(self, manifest):\n        for metric in manifest.metrics.values():\n            if hasattr(metric, \"name\"):\n                self.add_metric(metric)\n\n    def perform_lookup(self, unique_id: UniqueID, manifest: \"Manifest\") -> Metric:\n        if unique_id not in manifest.metrics:\n            raise dbt_common.exceptions.DbtInternalError(\n                f\"Metric {unique_id} found in cache but not found in manifest\"\n            )\n        return manifest.metrics[unique_id]\n\n\nclass SavedQueryLookup(dbtClassMixin):\n    \"\"\"Lookup utility for finding SavedQuery nodes\"\"\"\n\n    def __init__(self, manifest: \"Manifest\") -> None:\n        self.storage: Dict[str, Dict[PackageName, UniqueID]] = {}\n        self.populate(manifest)\n\n    def get_unique_id(self, search_name, package: Optional[PackageName]):\n        return find_unique_id_for_package(self.storage, search_name, package)\n\n    def find(self, search_name, package: Optional[PackageName], manifest: \"Manifest\"):\n        unique_id = self.get_unique_id(search_name, package)\n        if unique_id is not None:\n            return self.perform_lookup(unique_id, manifest)\n        return None\n\n    def add_saved_query(self, saved_query: SavedQuery):\n        if saved_query.search_name not in self.storage:\n            self.storage[saved_query.search_name] = {}\n\n        self.storage[saved_query.search_name][saved_query.package_name] = saved_query.unique_id\n\n    def populate(self, manifest):\n        for saved_query in manifest.saved_queries.values():\n            if hasattr(saved_query, \"name\"):\n                self.add_saved_query(saved_query)\n\n    def perform_lookup(self, unique_id: UniqueID, manifest: \"Manifest\") -> SavedQuery:\n        if unique_id not in manifest.saved_queries:\n            raise dbt_common.exceptions.DbtInternalError(\n                f\"SavedQUery {unique_id} found in cache but not found in manifest\"\n            )\n        return manifest.saved_queries[unique_id]\n\n\nclass SemanticModelByMeasureLookup(dbtClassMixin):\n    \"\"\"Lookup utility for finding SemanticModel by measure\n\n    This is possible because measure names are supposed to be unique across\n    the semantic models in a manifest.\n    \"\"\"\n\n    def __init__(self, manifest: \"Manifest\") -> None:\n        self.storage: DefaultDict[str, Dict[PackageName, UniqueID]] = defaultdict(dict)\n        self.populate(manifest)\n\n    def get_unique_id(self, search_name: str, package: Optional[PackageName]):\n        return find_unique_id_for_package(self.storage, search_name, package)\n\n    def find(\n        self, search_name: str, package: Optional[PackageName], manifest: \"Manifest\"\n    ) -> Optional[SemanticModel]:\n        \"\"\"Tries to find a SemanticModel based on a measure name\"\"\"\n        unique_id = self.get_unique_id(search_name, package)\n        if unique_id is not None:\n            return self.perform_lookup(unique_id, manifest)\n        return None\n\n    def add(self, semantic_model: SemanticModel):\n        \"\"\"Sets all measures for a SemanticModel as paths to the SemanticModel's `unique_id`\"\"\"\n        for measure in semantic_model.measures:\n            self.storage[measure.name][semantic_model.package_name] = semantic_model.unique_id\n\n    def populate(self, manifest: \"Manifest\"):\n        \"\"\"Populate storage with all the measure + package paths to the Manifest's SemanticModels\"\"\"\n        for semantic_model in manifest.semantic_models.values():\n            self.add(semantic_model=semantic_model)\n        for disabled in manifest.disabled.values():\n            for node in disabled:\n                if isinstance(node, SemanticModel):\n                    self.add(semantic_model=node)\n\n    def perform_lookup(self, unique_id: UniqueID, manifest: \"Manifest\") -> SemanticModel:\n        \"\"\"Tries to get a SemanticModel from the Manifest\"\"\"\n        enabled_semantic_model: Optional[SemanticModel] = manifest.semantic_models.get(unique_id)\n        disabled_semantic_model: Optional[List] = manifest.disabled.get(unique_id)\n\n        if isinstance(enabled_semantic_model, SemanticModel):\n            return enabled_semantic_model\n        elif disabled_semantic_model is not None and isinstance(\n            disabled_semantic_model[0], SemanticModel\n        ):\n            return disabled_semantic_model[0]\n        else:\n            raise dbt_common.exceptions.DbtInternalError(\n                f\"Semantic model `{unique_id}` found in cache but not found in manifest\"\n            )\n\n\n# This handles both models/seeds/snapshots and sources/metrics/exposures/semantic_models\nclass DisabledLookup(dbtClassMixin):\n    def __init__(self, manifest: \"Manifest\") -> None:\n        self.storage: Dict[str, Dict[PackageName, List[Any]]] = {}\n        self.populate(manifest)\n\n    def populate(self, manifest: \"Manifest\"):\n        for node in list(chain.from_iterable(manifest.disabled.values())):\n            self.add_node(node)\n\n    def add_node(self, node: GraphMemberNode) -> None:\n        if node.search_name not in self.storage:\n            self.storage[node.search_name] = {}\n        if node.package_name not in self.storage[node.search_name]:\n            self.storage[node.search_name][node.package_name] = []\n        self.storage[node.search_name][node.package_name].append(node)\n\n    # This should return a list of disabled nodes. It's different from\n    # the other Lookup functions in that it returns full nodes, not just unique_ids\n    def find(\n        self,\n        search_name,\n        package: Optional[PackageName],\n        version: Optional[NodeVersion] = None,\n        resource_types: Optional[List[NodeType]] = None,\n    ) -> Optional[List[Any]]:\n        if version:\n            search_name = f\"{search_name}.v{version}\"\n\n        if search_name not in self.storage:\n            return None\n\n        pkg_dct: Mapping[PackageName, List[Any]] = self.storage[search_name]\n\n        nodes = []\n        if package is None:\n            if not pkg_dct:\n                return None\n            else:\n                nodes = next(iter(pkg_dct.values()))\n        elif package in pkg_dct:\n            nodes = pkg_dct[package]\n        else:\n            return None\n\n        if resource_types is None:\n            return nodes\n        else:\n            new_nodes = []\n            for node in nodes:\n                if node.resource_type in resource_types:\n                    new_nodes.append(node)\n            if not new_nodes:\n                return None\n            else:\n                return new_nodes\n\n\nclass AnalysisLookup(RefableLookup):\n    _lookup_types: ClassVar[set] = set([NodeType.Analysis])\n    _versioned_types: ClassVar[set] = set()\n\n\nclass SingularTestLookup(dbtClassMixin):\n    def __init__(self, manifest: \"Manifest\") -> None:\n        self.storage: Dict[str, Dict[PackageName, UniqueID]] = {}\n        self.populate(manifest)\n\n    def get_unique_id(self, search_name, package: Optional[PackageName]) -> Optional[UniqueID]:\n        return find_unique_id_for_package(self.storage, search_name, package)\n\n    def find(\n        self, search_name, package: Optional[PackageName], manifest: \"Manifest\"\n    ) -> Optional[SingularTestNode]:\n        unique_id = self.get_unique_id(search_name, package)\n        if unique_id is not None:\n            return self.perform_lookup(unique_id, manifest)\n        return None\n\n    def add_singular_test(self, source: SingularTestNode) -> None:\n        if source.search_name not in self.storage:\n            self.storage[source.search_name] = {}\n\n        self.storage[source.search_name][source.package_name] = source.unique_id\n\n    def populate(self, manifest: \"Manifest\") -> None:\n        for node in manifest.nodes.values():\n            if isinstance(node, SingularTestNode):\n                self.add_singular_test(node)\n\n    def perform_lookup(self, unique_id: UniqueID, manifest: \"Manifest\") -> SingularTestNode:\n        if unique_id not in manifest.nodes:\n            raise dbt_common.exceptions.DbtInternalError(\n                f\"Singular test {unique_id} found in cache but not found in manifest\"\n            )\n        node = manifest.nodes[unique_id]\n        assert isinstance(node, SingularTestNode)\n        return node\n\n\ndef _packages_to_search(\n    current_project: str,\n    node_package: str,\n    target_package: Optional[str] = None,\n) -> List[Optional[str]]:\n    if target_package is not None:\n        return [target_package]\n    elif current_project == node_package:\n        return [current_project, None]\n    else:\n        if get_flags().require_ref_searches_node_package_before_root:\n            return [node_package, current_project, None]\n        else:\n            return [current_project, node_package, None]\n\n\ndef _sort_values(dct):\n    \"\"\"Given a dictionary, sort each value. This makes output deterministic,\n    which helps for tests.\n    \"\"\"\n    return {k: sorted(v) for k, v in dct.items()}\n\n\ndef build_node_edges(nodes: List[ManifestNode]):\n    \"\"\"Build the forward and backward edges on the given list of ManifestNodes\n    and return them as two separate dictionaries, each mapping unique IDs to\n    lists of edges.\n    \"\"\"\n    backward_edges: Dict[str, List[str]] = {}\n    # pre-populate the forward edge dict for simplicity\n    forward_edges: Dict[str, List[str]] = {n.unique_id: [] for n in nodes}\n    for node in nodes:\n        backward_edges[node.unique_id] = node.depends_on_nodes[:]\n        for unique_id in backward_edges[node.unique_id]:\n            if unique_id in forward_edges.keys():\n                forward_edges[unique_id].append(node.unique_id)\n    return _sort_values(forward_edges), _sort_values(backward_edges)\n\n\n# Build a map of children of macros and generic tests\ndef build_macro_edges(nodes: List[Any]):\n    forward_edges: Dict[str, List[str]] = {\n        n.unique_id: [] for n in nodes if n.unique_id.startswith(\"macro\") or n.depends_on_macros\n    }\n    for node in nodes:\n        for unique_id in node.depends_on_macros:\n            if unique_id in forward_edges.keys():\n                forward_edges[unique_id].append(node.unique_id)\n    return _sort_values(forward_edges)\n\n\ndef _deepcopy(value):\n    return value.from_dict(value.to_dict(omit_none=True))\n\n\nclass Locality(enum.IntEnum):\n    Core = 1\n    Imported = 2\n    Root = 3\n\n\n@dataclass\nclass MacroCandidate:\n    locality: Locality\n    macro: Macro\n\n    def __eq__(self, other: object) -> bool:\n        if not isinstance(other, MacroCandidate):\n            return NotImplemented\n        return self.locality == other.locality\n\n    def __lt__(self, other: object) -> bool:\n        if not isinstance(other, MacroCandidate):\n            return NotImplemented\n        if self.locality < other.locality:\n            return True\n        if self.locality > other.locality:\n            return False\n        return False\n\n\n@dataclass\nclass MaterializationCandidate(MacroCandidate):\n    # specificity describes where in the inheritance chain this materialization candidate is\n    # a specificity of 0 means a materialization defined by the current adapter\n    # the highest the specificity describes a default materialization. the value itself depends on\n    # how many adapters there are in the inheritance chain\n    specificity: int\n\n    @classmethod\n    def from_macro(cls, candidate: MacroCandidate, specificity: int) -> \"MaterializationCandidate\":\n        return cls(\n            locality=candidate.locality,\n            macro=candidate.macro,\n            specificity=specificity,\n        )\n\n    def __eq__(self, other: object) -> bool:\n        if not isinstance(other, MaterializationCandidate):\n            return NotImplemented\n        equal = self.specificity == other.specificity and self.locality == other.locality\n        if equal:\n            raise DuplicateMaterializationNameError(self.macro, other)\n\n        return equal\n\n    def __lt__(self, other: object) -> bool:\n        if not isinstance(other, MaterializationCandidate):\n            return NotImplemented\n        if self.specificity > other.specificity:\n            return True\n        if self.specificity < other.specificity:\n            return False\n        if self.locality < other.locality:\n            return True\n        if self.locality > other.locality:\n            return False\n        return False\n\n\nM = TypeVar(\"M\", bound=MacroCandidate)\n\n\nclass CandidateList(List[M]):\n    def last_candidate(\n        self, valid_localities: Optional[List[Locality]] = None\n    ) -> Optional[MacroCandidate]:\n        \"\"\"\n        Obtain the last (highest precedence) MacroCandidate from the CandidateList of any locality in valid_localities.\n        If valid_localities is not specified, return the last MacroCandidate of any locality.\n        \"\"\"\n        if not self:\n            return None\n        self.sort()\n\n        if valid_localities is None:\n            return self[-1]\n\n        for candidate in reversed(self):\n            if candidate.locality in valid_localities:\n                return candidate\n\n        return None\n\n    def last(self) -> Optional[Macro]:\n        last_candidate = self.last_candidate()\n        return last_candidate.macro if last_candidate is not None else None\n\n\ndef _get_locality(macro: Macro, root_project_name: str, internal_packages: Set[str]) -> Locality:\n    if macro.package_name == root_project_name:\n        return Locality.Root\n    elif macro.package_name in internal_packages:\n        return Locality.Core\n    else:\n        return Locality.Imported\n\n\nclass Searchable(Protocol):\n    resource_type: NodeType\n    package_name: str\n\n    @property\n    def search_name(self) -> str:\n        raise NotImplementedError(\"search_name not implemented\")\n\n\nD = TypeVar(\"D\")\n\n\n@dataclass\nclass Disabled(Generic[D]):\n    target: D\n\n\nMaybeFunctionNode = Optional[Union[FunctionNode, Disabled[FunctionNode]]]\n\n\nMaybeMetricNode = Optional[Union[Metric, Disabled[Metric]]]\n\n\nMaybeSavedQueryNode = Optional[Union[SavedQuery, Disabled[SavedQuery]]]\n\n\nMaybeDocumentation = Optional[Documentation]\n\n\nMaybeParsedSource = Optional[\n    Union[\n        SourceDefinition,\n        Disabled[SourceDefinition],\n    ]\n]\n\n\nMaybeNonSource = Optional[Union[ManifestNode, Disabled[ManifestNode]]]\n\n\nT = TypeVar(\"T\", bound=GraphMemberNode)\n\n\n# This contains macro methods that are in both the Manifest\n# and the MacroManifest\nclass MacroMethods:\n    # Just to make mypy happy. There must be a better way.\n    def __init__(self):\n        self.macros = []\n        self.metadata = {}\n        self._macros_by_name = {}\n        self._macros_by_package = {}\n\n    def find_macro_candidate_by_name(\n        self, name: str, root_project_name: str, package: Optional[str]\n    ) -> Optional[MacroCandidate]:\n        \"\"\"Find a MacroCandidate in the graph by its name and package name, or None for\n        any package. The root project name is used to determine priority:\n         - locally defined macros come first\n         - then imported macros\n         - then macros defined in the root project\n        \"\"\"\n        filter: Optional[Callable[[MacroCandidate], bool]] = None\n        if package is not None:\n\n            def filter(candidate: MacroCandidate) -> bool:\n                return package == candidate.macro.package_name\n\n        candidates: CandidateList = self._find_macros_by_name(\n            name=name,\n            root_project_name=root_project_name,\n            filter=filter,\n        )\n\n        return candidates.last_candidate()\n\n    def find_macro_by_name(\n        self, name: str, root_project_name: str, package: Optional[str]\n    ) -> Optional[Macro]:\n        macro_candidate = self.find_macro_candidate_by_name(\n            name=name, root_project_name=root_project_name, package=package\n        )\n        return macro_candidate.macro if macro_candidate else None\n\n    def find_generate_macro_by_name(\n        self, component: str, root_project_name: str, imported_package: Optional[str] = None\n    ) -> Optional[Macro]:\n        \"\"\"\n        The default `generate_X_name` macros are similar to regular ones, but only\n        includes imported packages when searching for a package.\n        - if package is not provided:\n            - if there is a `generate_{component}_name` macro in the root\n              project, return it\n            - return the `generate_{component}_name` macro from the 'dbt'\n              internal project\n        - if package is provided\n            - return the `generate_{component}_name` macro from the imported\n              package, if one exists\n        \"\"\"\n\n        def filter(candidate: MacroCandidate) -> bool:\n            if imported_package:\n                return (\n                    candidate.locality == Locality.Imported\n                    and imported_package == candidate.macro.package_name\n                )\n            else:\n                return candidate.locality != Locality.Imported\n\n        candidates: CandidateList = self._find_macros_by_name(\n            name=f\"generate_{component}_name\",\n            root_project_name=root_project_name,\n            filter=filter,\n        )\n\n        return candidates.last()\n\n    def _find_macros_by_name(\n        self,\n        name: str,\n        root_project_name: str,\n        filter: Optional[Callable[[MacroCandidate], bool]] = None,\n    ) -> CandidateList:\n        \"\"\"Find macros by their name.\"\"\"\n        candidates: CandidateList = CandidateList()\n\n        macros_by_name = self.get_macros_by_name()\n        if name not in macros_by_name:\n            return candidates\n\n        packages = set(get_adapter_package_names(self.metadata.adapter_type))\n        for macro in macros_by_name[name]:\n            candidate = MacroCandidate(\n                locality=_get_locality(macro, root_project_name, packages),\n                macro=macro,\n            )\n            if filter is None or filter(candidate):\n                candidates.append(candidate)\n\n        return candidates\n\n    def get_macros_by_name(self) -> Dict[str, List[Macro]]:\n        if self._macros_by_name is None:\n            # The by-name mapping doesn't exist yet (perhaps because the manifest\n            # was deserialized), so we build it.\n            self._macros_by_name = self._build_macros_by_name(self.macros)\n\n        return self._macros_by_name\n\n    @staticmethod\n    def _build_macros_by_name(macros: Mapping[str, Macro]) -> Dict[str, List[Macro]]:\n        # Convert a macro dictionary keyed on unique id to a flattened version\n        # keyed on macro name for faster lookup by name. Since macro names are\n        # not necessarily unique, the dict value is a list.\n        macros_by_name: Dict[str, List[Macro]] = {}\n        for macro in macros.values():\n            if macro.name not in macros_by_name:\n                macros_by_name[macro.name] = []\n\n            macros_by_name[macro.name].append(macro)\n\n        return macros_by_name\n\n    def get_macros_by_package(self) -> Dict[str, Dict[str, Macro]]:\n        if self._macros_by_package is None:\n            # The by-package mapping doesn't exist yet (perhaps because the manifest\n            # was deserialized), so we build it.\n            self._macros_by_package = self._build_macros_by_package(self.macros)\n\n        return self._macros_by_package\n\n    @staticmethod\n    def _build_macros_by_package(macros: Mapping[str, Macro]) -> Dict[str, Dict[str, Macro]]:\n        # Convert a macro dictionary keyed on unique id to a flattened version\n        # keyed on package name for faster lookup by name.\n        macros_by_package: Dict[str, Dict[str, Macro]] = {}\n        for macro in macros.values():\n            if macro.package_name not in macros_by_package:\n                macros_by_package[macro.package_name] = {}\n            macros_by_name = macros_by_package[macro.package_name]\n            macros_by_name[macro.name] = macro\n\n        return macros_by_package\n\n\n@dataclass\nclass ParsingInfo:\n    static_analysis_parsed_path_count: int = 0\n    static_analysis_path_count: int = 0\n\n\n@dataclass\nclass ManifestStateCheck(dbtClassMixin):\n    vars_hash: FileHash = field(default_factory=FileHash.empty)\n    project_env_vars_hash: FileHash = field(default_factory=FileHash.empty)\n    profile_env_vars_hash: FileHash = field(default_factory=FileHash.empty)\n    profile_hash: FileHash = field(default_factory=FileHash.empty)\n    project_hashes: MutableMapping[str, FileHash] = field(default_factory=dict)\n\n\nNodeClassT = TypeVar(\"NodeClassT\", bound=\"BaseNode\")\nResourceClassT = TypeVar(\"ResourceClassT\", bound=\"BaseResource\")\n\n\n@dataclass\nclass Manifest(MacroMethods, dbtClassMixin):\n    \"\"\"The manifest for the full graph, after parsing and during compilation.\"\"\"\n\n    # These attributes are both positional and by keyword. If an attribute\n    # is added it must all be added in the __reduce_ex__ method in the\n    # args tuple in the right position.\n    nodes: MutableMapping[str, ManifestNode] = field(default_factory=dict)\n    sources: MutableMapping[str, SourceDefinition] = field(default_factory=dict)\n    macros: MutableMapping[str, Macro] = field(default_factory=dict)\n    docs: MutableMapping[str, Documentation] = field(default_factory=dict)\n    exposures: MutableMapping[str, Exposure] = field(default_factory=dict)\n    functions: MutableMapping[str, FunctionNode] = field(default_factory=dict)\n    metrics: MutableMapping[str, Metric] = field(default_factory=dict)\n    groups: MutableMapping[str, Group] = field(default_factory=dict)\n    selectors: MutableMapping[str, Any] = field(default_factory=dict)\n    files: MutableMapping[str, AnySourceFile] = field(default_factory=dict)\n    metadata: ManifestMetadata = field(default_factory=ManifestMetadata)\n    flat_graph: Dict[str, Any] = field(default_factory=dict)\n    state_check: ManifestStateCheck = field(default_factory=ManifestStateCheck)\n    source_patches: MutableMapping[SourceKey, SourcePatch] = field(default_factory=dict)\n    disabled: MutableMapping[str, List[GraphMemberNode]] = field(default_factory=dict)\n    env_vars: MutableMapping[str, str] = field(default_factory=dict)\n    semantic_models: MutableMapping[str, SemanticModel] = field(default_factory=dict)\n    unit_tests: MutableMapping[str, UnitTestDefinition] = field(default_factory=dict)\n    saved_queries: MutableMapping[str, SavedQuery] = field(default_factory=dict)\n    fixtures: MutableMapping[str, UnitTestFileFixture] = field(default_factory=dict)\n\n    _doc_lookup: Optional[DocLookup] = field(\n        default=None, metadata={\"serialize\": lambda x: None, \"deserialize\": lambda x: None}\n    )\n    _source_lookup: Optional[SourceLookup] = field(\n        default=None, metadata={\"serialize\": lambda x: None, \"deserialize\": lambda x: None}\n    )\n    _ref_lookup: Optional[RefableLookup] = field(\n        default=None, metadata={\"serialize\": lambda x: None, \"deserialize\": lambda x: None}\n    )\n    _metric_lookup: Optional[MetricLookup] = field(\n        default=None, metadata={\"serialize\": lambda x: None, \"deserialize\": lambda x: None}\n    )\n    _saved_query_lookup: Optional[SavedQueryLookup] = field(\n        default=None, metadata={\"serialize\": lambda x: None, \"deserialize\": lambda x: None}\n    )\n    _semantic_model_by_measure_lookup: Optional[SemanticModelByMeasureLookup] = field(\n        default=None, metadata={\"serialize\": lambda x: None, \"deserialize\": lambda x: None}\n    )\n    _disabled_lookup: Optional[DisabledLookup] = field(\n        default=None, metadata={\"serialize\": lambda x: None, \"deserialize\": lambda x: None}\n    )\n    _analysis_lookup: Optional[AnalysisLookup] = field(\n        default=None, metadata={\"serialize\": lambda x: None, \"deserialize\": lambda x: None}\n    )\n    _singular_test_lookup: Optional[SingularTestLookup] = field(\n        default=None, metadata={\"serialize\": lambda x: None, \"deserialize\": lambda x: None}\n    )\n    _function_lookup: Optional[FunctionLookup] = field(\n        default=None, metadata={\"serialize\": lambda x: None, \"deserialize\": lambda x: None}\n    )\n    _parsing_info: ParsingInfo = field(\n        default_factory=ParsingInfo,\n        metadata={\"serialize\": lambda x: None, \"deserialize\": lambda x: None},\n    )\n    _lock: Lock = field(\n        default_factory=get_mp_context().Lock,\n        metadata={\"serialize\": lambda x: None, \"deserialize\": lambda x: None},\n    )\n    _macros_by_name: Optional[Dict[str, List[Macro]]] = field(\n        default=None,\n        metadata={\"serialize\": lambda x: None, \"deserialize\": lambda x: None},\n    )\n    _macros_by_package: Optional[Dict[str, Dict[str, Macro]]] = field(\n        default=None,\n        metadata={\"serialize\": lambda x: None, \"deserialize\": lambda x: None},\n    )\n\n    def __pre_serialize__(self, context: Optional[Dict] = None):\n        # serialization won't work with anything except an empty source_patches because\n        # tuple keys are not supported, so ensure it's empty\n        self.source_patches = {}\n        return self\n\n    @classmethod\n    def __post_deserialize__(cls, obj):\n        obj._lock = get_mp_context().Lock()\n        return obj\n\n    def build_flat_graph(self):\n        \"\"\"This attribute is used in context.common by each node, so we want to\n        only build it once and avoid any concurrency issues around it.\n        Make sure you don't call this until you're done with building your\n        manifest!\n        \"\"\"\n        self.flat_graph = {\n            \"exposures\": {k: v.to_dict(omit_none=False) for k, v in self.exposures.items()},\n            \"functions\": {k: v.to_dict(omit_none=False) for k, v in self.functions.items()},\n            \"groups\": {k: v.to_dict(omit_none=False) for k, v in self.groups.items()},\n            \"metrics\": {k: v.to_dict(omit_none=False) for k, v in self.metrics.items()},\n            \"nodes\": {k: v.to_dict(omit_none=False) for k, v in self.nodes.items()},\n            \"sources\": {k: v.to_dict(omit_none=False) for k, v in self.sources.items()},\n            \"semantic_models\": {\n                k: v.to_dict(omit_none=False) for k, v in self.semantic_models.items()\n            },\n            \"saved_queries\": {\n                k: v.to_dict(omit_none=False) for k, v in self.saved_queries.items()\n            },\n            \"unit_tests\": {k: v.to_dict(omit_none=False) for k, v in self.unit_tests.items()},\n        }\n\n    def build_disabled_by_file_id(self):\n        disabled_by_file_id = {}\n        for node_list in self.disabled.values():\n            for node in node_list:\n                disabled_by_file_id[node.file_id] = node\n        return disabled_by_file_id\n\n    def _get_parent_adapter_types(self, adapter_type: str) -> List[str]:\n        # This is duplicated logic from core/dbt/context/providers.py\n        # Ideally this would instead be incorporating actual dispatch logic\n        from dbt.adapters.factory import get_adapter_type_names\n\n        # order matters for dispatch:\n        #  1. current adapter\n        #  2. any parent adapters (dependencies)\n        #  3. 'default'\n        return get_adapter_type_names(adapter_type) + [\"default\"]\n\n    def _materialization_candidates_for(\n        self,\n        project_name: str,\n        materialization_name: str,\n        adapter_type: str,\n        specificity: int,\n    ) -> CandidateList:\n        full_name = dbt_common.utils.get_materialization_macro_name(\n            materialization_name=materialization_name,\n            adapter_type=adapter_type,\n            with_prefix=False,\n        )\n        return CandidateList(\n            MaterializationCandidate.from_macro(m, specificity)\n            for m in self._find_macros_by_name(full_name, project_name)\n        )\n\n    def find_materialization_macro_by_name(\n        self, project_name: str, materialization_name: str, adapter_type: str\n    ) -> Optional[Macro]:\n        candidates: CandidateList = CandidateList(\n            chain.from_iterable(\n                self._materialization_candidates_for(\n                    project_name=project_name,\n                    materialization_name=materialization_name,\n                    adapter_type=atype,\n                    specificity=specificity,  # where in the inheritance chain this candidate is\n                )\n                for specificity, atype in enumerate(self._get_parent_adapter_types(adapter_type))\n            )\n        )\n        core_candidates = [\n            candidate for candidate in candidates if candidate.locality == Locality.Core\n        ]\n\n        materialization_candidate = candidates.last_candidate()\n        # If an imported materialization macro was found that also had a core candidate, fire a deprecation\n        if (\n            materialization_candidate is not None\n            and materialization_candidate.locality == Locality.Imported\n            and core_candidates\n        ):\n            # preserve legacy behaviour - allow materialization override\n            if (\n                get_flags().require_explicit_package_overrides_for_builtin_materializations\n                is False\n            ):\n                deprecations.warn(\n                    \"package-materialization-override\",\n                    package_name=materialization_candidate.macro.package_name,\n                    materialization_name=materialization_name,\n                )\n            else:\n                materialization_candidate = candidates.last_candidate(\n                    valid_localities=[Locality.Core, Locality.Root]\n                )\n\n        return materialization_candidate.macro if materialization_candidate else None\n\n    def get_resource_fqns(self) -> Mapping[str, PathSet]:\n        resource_fqns: Dict[str, Set[Tuple[str, ...]]] = {}\n        all_resources = chain(\n            self.exposures.values(),\n            self.functions.values(),\n            self.nodes.values(),\n            self.sources.values(),\n            self.metrics.values(),\n            self.semantic_models.values(),\n            self.saved_queries.values(),\n            self.unit_tests.values(),\n        )\n        for resource in all_resources:\n            resource_type_plural = resource.resource_type.pluralize()\n            if resource_type_plural not in resource_fqns:\n                resource_fqns[resource_type_plural] = set()\n            resource_fqns[resource_type_plural].add(tuple(resource.fqn))\n        return resource_fqns\n\n    def get_used_schemas(self, resource_types=None):\n        return frozenset(\n            {\n                (node.database, node.schema)\n                for node in chain(self.nodes.values(), self.sources.values())\n                if not resource_types or node.resource_type in resource_types\n            }\n        )\n\n    def get_used_databases(self):\n        return frozenset(x.database for x in chain(self.nodes.values(), self.sources.values()))\n\n    def deepcopy(self):\n        copy = Manifest(\n            nodes={k: _deepcopy(v) for k, v in self.nodes.items()},\n            sources={k: _deepcopy(v) for k, v in self.sources.items()},\n            macros={k: _deepcopy(v) for k, v in self.macros.items()},\n            docs={k: _deepcopy(v) for k, v in self.docs.items()},\n            exposures={k: _deepcopy(v) for k, v in self.exposures.items()},\n            functions={k: _deepcopy(v) for k, v in self.functions.items()},\n            metrics={k: _deepcopy(v) for k, v in self.metrics.items()},\n            groups={k: _deepcopy(v) for k, v in self.groups.items()},\n            selectors={k: _deepcopy(v) for k, v in self.selectors.items()},\n            metadata=self.metadata,\n            disabled={k: _deepcopy(v) for k, v in self.disabled.items()},\n            files={k: _deepcopy(v) for k, v in self.files.items()},\n            state_check=_deepcopy(self.state_check),\n            semantic_models={k: _deepcopy(v) for k, v in self.semantic_models.items()},\n            unit_tests={k: _deepcopy(v) for k, v in self.unit_tests.items()},\n            saved_queries={k: _deepcopy(v) for k, v in self.saved_queries.items()},\n        )\n        copy.build_flat_graph()\n        return copy\n\n    def build_parent_and_child_maps(self):\n        edge_members = list(\n            chain(\n                self.nodes.values(),\n                self.sources.values(),\n                self.exposures.values(),\n                self.functions.values(),\n                self.metrics.values(),\n                self.semantic_models.values(),\n                self.saved_queries.values(),\n                self.unit_tests.values(),\n            )\n        )\n        forward_edges, backward_edges = build_node_edges(edge_members)\n        self.child_map = forward_edges\n        self.parent_map = backward_edges\n\n    def build_macro_child_map(self):\n        edge_members = list(\n            chain(\n                self.nodes.values(),\n                self.macros.values(),\n            )\n        )\n        forward_edges = build_macro_edges(edge_members)\n        return forward_edges\n\n    def build_group_map(self):\n        groupable_nodes = list(\n            chain(\n                self.nodes.values(),\n                self.saved_queries.values(),\n                self.semantic_models.values(),\n                self.metrics.values(),\n            )\n        )\n        group_map = {group.name: [] for group in self.groups.values()}\n        for node in groupable_nodes:\n            if node.group is not None:\n                # group updates are not included with state:modified and\n                # by ignoring the groups that aren't in the group map we\n                # can avoid hitting errors for groups that are not getting\n                # updated.  This is a hack but any groups that are not\n                # valid will be caught in\n                # parser.manifest.ManifestLoader.check_valid_group_config_node\n                if node.group in group_map:\n                    group_map[node.group].append(node.unique_id)\n        self.group_map = group_map\n\n    def fill_tracking_metadata(self):\n        self.metadata.user_id = tracking.active_user.id if tracking.active_user else None\n        self.metadata.send_anonymous_usage_stats = get_flags().SEND_ANONYMOUS_USAGE_STATS\n\n    @classmethod\n    def from_writable_manifest(cls, writable_manifest: WritableManifest) -> \"Manifest\":\n        manifest = Manifest(\n            nodes=cls._map_resources_to_map_nodes(writable_manifest.nodes),\n            disabled=cls._map_list_resources_to_map_list_nodes(writable_manifest.disabled),\n            unit_tests=cls._map_resources_to_map_nodes(writable_manifest.unit_tests),\n            sources=cls._map_resources_to_map_nodes(writable_manifest.sources),\n            macros=cls._map_resources_to_map_nodes(writable_manifest.macros),\n            docs=cls._map_resources_to_map_nodes(writable_manifest.docs),\n            exposures=cls._map_resources_to_map_nodes(writable_manifest.exposures),\n            functions=cls._map_resources_to_map_nodes(writable_manifest.functions),\n            metrics=cls._map_resources_to_map_nodes(writable_manifest.metrics),\n            groups=cls._map_resources_to_map_nodes(writable_manifest.groups),\n            semantic_models=cls._map_resources_to_map_nodes(writable_manifest.semantic_models),\n            saved_queries=cls._map_resources_to_map_nodes(writable_manifest.saved_queries),\n            selectors={\n                selector_id: selector\n                for selector_id, selector in writable_manifest.selectors.items()\n            },\n            metadata=writable_manifest.metadata,\n        )\n\n        return manifest\n\n    def _map_nodes_to_map_resources(cls, nodes_map: MutableMapping[str, NodeClassT]):\n        return {node_id: node.to_resource() for node_id, node in nodes_map.items()}\n\n    def _map_list_nodes_to_map_list_resources(\n        cls, nodes_map: MutableMapping[str, List[NodeClassT]]\n    ):\n        return {\n            node_id: [node.to_resource() for node in node_list]\n            for node_id, node_list in nodes_map.items()\n        }\n\n    @classmethod\n    def _map_resources_to_map_nodes(cls, resources_map: Mapping[str, ResourceClassT]):\n        return {\n            node_id: RESOURCE_CLASS_TO_NODE_CLASS[type(resource)].from_resource(resource)\n            for node_id, resource in resources_map.items()\n        }\n\n    @classmethod\n    def _map_list_resources_to_map_list_nodes(\n        cls, resources_map: Optional[Mapping[str, List[ResourceClassT]]]\n    ):\n        if resources_map is None:\n            return {}\n\n        return {\n            node_id: [\n                RESOURCE_CLASS_TO_NODE_CLASS[type(resource)].from_resource(resource)\n                for resource in resource_list\n            ]\n            for node_id, resource_list in resources_map.items()\n        }\n\n    def writable_manifest(self) -> \"WritableManifest\":\n        self.build_parent_and_child_maps()\n        self.build_group_map()\n        self.fill_tracking_metadata()\n\n        return WritableManifest(\n            nodes=self._map_nodes_to_map_resources(self.nodes),\n            sources=self._map_nodes_to_map_resources(self.sources),\n            macros=self._map_nodes_to_map_resources(self.macros),\n            docs=self._map_nodes_to_map_resources(self.docs),\n            exposures=self._map_nodes_to_map_resources(self.exposures),\n            functions=self._map_nodes_to_map_resources(self.functions),\n            metrics=self._map_nodes_to_map_resources(self.metrics),\n            groups=self._map_nodes_to_map_resources(self.groups),\n            selectors=self.selectors,\n            metadata=self.metadata,\n            disabled=self._map_list_nodes_to_map_list_resources(self.disabled),\n            child_map=self.child_map,\n            parent_map=self.parent_map,\n            group_map=self.group_map,\n            semantic_models=self._map_nodes_to_map_resources(self.semantic_models),\n            unit_tests=self._map_nodes_to_map_resources(self.unit_tests),\n            saved_queries=self._map_nodes_to_map_resources(self.saved_queries),\n        )\n\n    def write(self, path):\n        writable = self.writable_manifest()\n        writable.write(path)\n        fire_event(ArtifactWritten(artifact_type=writable.__class__.__name__, artifact_path=path))\n\n    # Called in dbt.compilation.Linker.write_graph and\n    # dbt.graph.queue.get and ._include_in_cost\n    def expect(self, unique_id: str) -> GraphMemberNode:\n        if unique_id in self.nodes:\n            return self.nodes[unique_id]\n        elif unique_id in self.sources:\n            return self.sources[unique_id]\n        elif unique_id in self.exposures:\n            return self.exposures[unique_id]\n        elif unique_id in self.functions:\n            return self.functions[unique_id]\n        elif unique_id in self.metrics:\n            return self.metrics[unique_id]\n        elif unique_id in self.semantic_models:\n            return self.semantic_models[unique_id]\n        elif unique_id in self.unit_tests:\n            return self.unit_tests[unique_id]\n        elif unique_id in self.saved_queries:\n            return self.saved_queries[unique_id]\n        else:\n            # something terrible has happened\n            raise dbt_common.exceptions.DbtInternalError(\n                \"Expected node {} not found in manifest\".format(unique_id)\n            )\n\n    @property\n    def doc_lookup(self) -> DocLookup:\n        if self._doc_lookup is None:\n            self._doc_lookup = DocLookup(self)\n        return self._doc_lookup\n\n    def rebuild_doc_lookup(self):\n        self._doc_lookup = DocLookup(self)\n\n    @property\n    def source_lookup(self) -> SourceLookup:\n        if self._source_lookup is None:\n            self._source_lookup = SourceLookup(self)\n        return self._source_lookup\n\n    def rebuild_source_lookup(self):\n        self._source_lookup = SourceLookup(self)\n\n    @property\n    def ref_lookup(self) -> RefableLookup:\n        if self._ref_lookup is None:\n            self._ref_lookup = RefableLookup(self)\n        return self._ref_lookup\n\n    @property\n    def metric_lookup(self) -> MetricLookup:\n        if self._metric_lookup is None:\n            self._metric_lookup = MetricLookup(self)\n        return self._metric_lookup\n\n    @property\n    def saved_query_lookup(self) -> SavedQueryLookup:\n        \"\"\"Retuns a SavedQueryLookup, instantiating it first if necessary.\"\"\"\n        if self._saved_query_lookup is None:\n            self._saved_query_lookup = SavedQueryLookup(self)\n        return self._saved_query_lookup\n\n    @property\n    def semantic_model_by_measure_lookup(self) -> SemanticModelByMeasureLookup:\n        \"\"\"Gets (and creates if necessary) the lookup utility for getting SemanticModels by measures\"\"\"\n        if self._semantic_model_by_measure_lookup is None:\n            self._semantic_model_by_measure_lookup = SemanticModelByMeasureLookup(self)\n        return self._semantic_model_by_measure_lookup\n\n    def rebuild_ref_lookup(self):\n        self._ref_lookup = RefableLookup(self)\n\n    @property\n    def disabled_lookup(self) -> DisabledLookup:\n        if self._disabled_lookup is None:\n            self._disabled_lookup = DisabledLookup(self)\n        return self._disabled_lookup\n\n    def rebuild_disabled_lookup(self):\n        self._disabled_lookup = DisabledLookup(self)\n\n    @property\n    def analysis_lookup(self) -> AnalysisLookup:\n        if self._analysis_lookup is None:\n            self._analysis_lookup = AnalysisLookup(self)\n        return self._analysis_lookup\n\n    @property\n    def singular_test_lookup(self) -> SingularTestLookup:\n        if self._singular_test_lookup is None:\n            self._singular_test_lookup = SingularTestLookup(self)\n        return self._singular_test_lookup\n\n    @property\n    def function_lookup(self) -> FunctionLookup:\n        if self._function_lookup is None:\n            self._function_lookup = FunctionLookup(self)\n        return self._function_lookup\n\n    @property\n    def external_node_unique_ids(self):\n        return [node.unique_id for node in self.nodes.values() if node.is_external_node]\n\n    # Called by dbt.parser.manifest._process_refs & ManifestLoader.check_for_model_deprecations\n    def resolve_ref(\n        self,\n        source_node: GraphMemberNode,\n        target_model_name: str,\n        target_model_package: Optional[str],\n        target_model_version: Optional[NodeVersion],\n        current_project: str,\n        node_package: str,\n    ) -> MaybeNonSource:\n\n        node: Optional[ManifestNode] = None\n        disabled: Optional[List[ManifestNode]] = None\n\n        candidates = _packages_to_search(current_project, node_package, target_model_package)\n        for pkg in candidates:\n            node = self.ref_lookup.find(\n                target_model_name, pkg, target_model_version, self, source_node\n            )\n\n            if node is not None and hasattr(node, \"config\") and node.config.enabled:\n                return node\n\n            # it's possible that the node is disabled\n            if disabled is None:\n                disabled = self.disabled_lookup.find(\n                    target_model_name,\n                    pkg,\n                    version=target_model_version,\n                    resource_types=REFABLE_NODE_TYPES,\n                )\n\n        if disabled:\n            return Disabled(disabled[0])\n        return None\n\n    # Called by dbt.parser.manifest._resolve_sources_for_exposure\n    # and dbt.parser.manifest._process_source_for_node\n    def resolve_source(\n        self,\n        target_source_name: str,\n        target_table_name: str,\n        current_project: str,\n        node_package: str,\n    ) -> MaybeParsedSource:\n        search_name = f\"{target_source_name}.{target_table_name}\"\n        candidates = _packages_to_search(current_project, node_package)\n\n        source: Optional[SourceDefinition] = None\n        disabled: Optional[List[SourceDefinition]] = None\n\n        for pkg in candidates:\n            source = self.source_lookup.find(search_name, pkg, self)\n            if source is not None and source.config.enabled:\n                return source\n\n            if disabled is None:\n                disabled = self.disabled_lookup.find(\n                    f\"{target_source_name}.{target_table_name}\", pkg\n                )\n\n        if disabled:\n            return Disabled(disabled[0])\n        return None\n\n    def resolve_function(\n        self,\n        target_function_name: str,\n        target_function_package: Optional[str],\n        current_project: str,\n        node_package: str,\n    ) -> MaybeFunctionNode:\n        package_candidates = _packages_to_search(\n            current_project, node_package, target_function_package\n        )\n        disabled: Optional[List[FunctionNode]] = None\n        for package in package_candidates:\n            function = self.function_lookup.find(target_function_name, package, self)\n            if function is not None and function.config.enabled:\n                return function\n\n            # it's possible that the function is disabled\n            if disabled is None:\n                disabled = self.disabled_lookup.find(target_function_name, package)\n        if disabled:\n            return Disabled(disabled[0])\n        return None\n\n    def resolve_metric(\n        self,\n        target_metric_name: str,\n        target_metric_package: Optional[str],\n        current_project: str,\n        node_package: str,\n    ) -> MaybeMetricNode:\n\n        metric: Optional[Metric] = None\n        disabled: Optional[List[Metric]] = None\n\n        candidates = _packages_to_search(current_project, node_package, target_metric_package)\n        for pkg in candidates:\n            metric = self.metric_lookup.find(target_metric_name, pkg, self)\n\n            if metric is not None and metric.config.enabled:\n                return metric\n\n            # it's possible that the node is disabled\n            if disabled is None:\n                disabled = self.disabled_lookup.find(f\"{target_metric_name}\", pkg)\n        if disabled:\n            return Disabled(disabled[0])\n        return None\n\n    def resolve_saved_query(\n        self,\n        target_saved_query_name: str,\n        target_saved_query_package: Optional[str],\n        current_project: str,\n        node_package: str,\n    ) -> MaybeSavedQueryNode:\n        \"\"\"Tries to find the SavedQuery by name within the available project and packages.\n\n        Will return the first enabled SavedQuery matching the name found while iterating over\n        the scoped packages. If no enabled SavedQuery node match is found, returns the last\n        disabled SavedQuery node. Otherwise it returns None.\n        \"\"\"\n        disabled: Optional[List[SavedQuery]] = None\n        candidates = _packages_to_search(current_project, node_package, target_saved_query_package)\n        for pkg in candidates:\n            saved_query = self.saved_query_lookup.find(target_saved_query_name, pkg, self)\n\n            if saved_query is not None and saved_query.config.enabled:\n                return saved_query\n\n            # it's possible that the node is disabled\n            if disabled is None:\n                disabled = self.disabled_lookup.find(f\"{target_saved_query_name}\", pkg)\n        if disabled:\n            return Disabled(disabled[0])\n\n        return None\n\n    def resolve_semantic_model_for_measure(\n        self,\n        target_measure_name: str,\n        current_project: str,\n        node_package: str,\n        target_package: Optional[str] = None,\n    ) -> Optional[SemanticModel]:\n        \"\"\"Tries to find the SemanticModel that a measure belongs to\"\"\"\n        candidates = _packages_to_search(current_project, node_package, target_package)\n\n        for pkg in candidates:\n            semantic_model = self.semantic_model_by_measure_lookup.find(\n                target_measure_name, pkg, self\n            )\n            # need to return it even if it's disabled so know it's not fully missing\n            if semantic_model is not None:\n                return semantic_model\n\n        return None\n\n    # Called by DocsRuntimeContext.doc\n    def resolve_doc(\n        self,\n        name: str,\n        package: Optional[str],\n        current_project: str,\n        node_package: str,\n    ) -> Optional[Documentation]:\n        \"\"\"Resolve the given documentation. This follows the same algorithm as\n        resolve_ref except the is_enabled checks are unnecessary as docs are\n        always enabled.\n        \"\"\"\n        candidates = _packages_to_search(current_project, node_package, package)\n\n        for pkg in candidates:\n            result = self.doc_lookup.find(name, pkg, self)\n            if result is not None:\n                return result\n        return None\n\n    def is_invalid_private_ref(\n        self, node: GraphMemberNode, target_model: MaybeNonSource, dependencies: Optional[Mapping]\n    ) -> bool:\n        dependencies = dependencies or {}\n        if not isinstance(target_model, ModelNode):\n            return False\n\n        is_private_ref = (\n            target_model.access == AccessType.Private\n            # don't raise this reference error for ad hoc 'preview' queries\n            and node.resource_type != NodeType.SqlOperation\n            and node.resource_type != NodeType.RPCCall  # TODO: rm\n            # macros are outside the group/access system (e.g. run-operation)\n            and node.resource_type != NodeType.Macro\n        )\n        target_dependency = dependencies.get(target_model.package_name)\n        restrict_package_access = target_dependency.restrict_access if target_dependency else False\n\n        # TODO: SemanticModel and SourceDefinition do not have group, and so should not be able to make _any_ private ref.\n        return is_private_ref and (\n            not hasattr(node, \"group\")\n            or not node.group\n            # Invalid reference because group does not match\n            or node.group != target_model.group\n            # Or, invalid because these are different namespaces (project/package) and restrict-access is enforced\n            or (node.package_name != target_model.package_name and restrict_package_access)\n        )\n\n    def is_invalid_protected_ref(\n        self, node: GraphMemberNode, target_model: MaybeNonSource, dependencies: Optional[Mapping]\n    ) -> bool:\n        dependencies = dependencies or {}\n        if not isinstance(target_model, ModelNode):\n            return False\n\n        is_protected_ref = (\n            target_model.access == AccessType.Protected\n            # don't raise this reference error for ad hoc 'preview' queries\n            and node.resource_type != NodeType.SqlOperation\n            and node.resource_type != NodeType.RPCCall  # TODO: rm\n            # macros are outside the group/access system (e.g. run-operation)\n            and node.resource_type != NodeType.Macro\n        )\n        target_dependency = dependencies.get(target_model.package_name)\n        restrict_package_access = target_dependency.restrict_access if target_dependency else False\n\n        return is_protected_ref and (\n            node.package_name != target_model.package_name and restrict_package_access\n        )\n\n    # Called in GraphRunnableTask.before_run, RunTask.before_run, CloneTask.before_run\n    def merge_from_artifact(self, other: \"Manifest\") -> None:\n        \"\"\"Update this manifest by adding the 'defer_relation' attribute to all nodes\n        with a counterpart in the stateful manifest used for deferral.\n\n        Only non-ephemeral refable nodes are examined.\n        Function nodes from the deferred manifest are merged so that models\n        depending on functions can resolve them via deferral.\n        \"\"\"\n        refables = set(REFABLE_NODE_TYPES)\n        for unique_id, node in other.nodes.items():\n            current = self.nodes.get(unique_id)\n            if current and node.resource_type in refables and not node.is_ephemeral:\n                assert isinstance(node.config, NodeConfig)  # this makes mypy happy\n                defer_relation = DeferRelation(\n                    database=node.database,\n                    schema=node.schema,\n                    alias=node.alias,\n                    relation_name=node.relation_name,\n                    resource_type=node.resource_type,\n                    name=node.name,\n                    description=node.description,\n                    compiled_code=(node.compiled_code if not isinstance(node, SeedNode) else None),\n                    meta=node.meta,\n                    tags=node.tags,\n                    config=node.config,\n                )\n                self.nodes[unique_id] = replace(current, defer_relation=defer_relation)\n\n        for unique_id, function in other.functions.items():\n            current = self.functions.get(unique_id)\n            if current:\n                defer_fn = DeferFunction(\n                    database=function.database,\n                    schema=function.schema,\n                    alias=function.alias,\n                    arguments=function.arguments,\n                    returns=function.returns,\n                    resource_type=function.resource_type,\n                    name=function.name,\n                    description=function.description,\n                    compiled_code=function.compiled_code,\n                    meta=function.meta,\n                    tags=function.tags,\n                    config=function.config,\n                )\n                self.functions[unique_id] = replace(current, defer_function=defer_fn)\n            else:\n                self.functions[unique_id] = function\n        # invalidate function lookup cache\n        self._function_lookup = None\n\n        # Rebuild the flat_graph, which powers the 'graph' context variable\n        self.build_flat_graph()\n\n    # Methods that were formerly in ParseResult\n    def add_macro(self, source_file: SourceFile, macro: Macro):\n        if macro.unique_id in self.macros:\n            # detect that the macro exists and emit an error\n            raise DuplicateMacroInPackageError(macro=macro, macro_mapping=self.macros)\n\n        self.macros[macro.unique_id] = macro\n\n        if self._macros_by_name is None:\n            self._macros_by_name = self._build_macros_by_name(self.macros)\n\n        if macro.name not in self._macros_by_name:\n            self._macros_by_name[macro.name] = []\n\n        self._macros_by_name[macro.name].append(macro)\n\n        if self._macros_by_package is None:\n            self._macros_by_package = self._build_macros_by_package(self.macros)\n\n        if macro.package_name not in self._macros_by_package:\n            self._macros_by_package[macro.package_name] = {}\n\n        self._macros_by_package[macro.package_name][macro.name] = macro\n\n        source_file.macros.append(macro.unique_id)\n\n    def has_file(self, source_file: SourceFile) -> bool:\n        key = source_file.file_id\n        if key is None:\n            return False\n        if key not in self.files:\n            return False\n        my_checksum = self.files[key].checksum\n        return my_checksum == source_file.checksum\n\n    def add_source(self, source_file: SchemaSourceFile, source: UnpatchedSourceDefinition):\n        # sources can't be overwritten!\n        _check_duplicates(source, self.sources)\n        self.sources[source.unique_id] = source  # type: ignore\n        source_file.sources.append(source.unique_id)\n\n    def add_node_nofile(self, node: ManifestNode):\n        # nodes can't be overwritten!\n        _check_duplicates(node, self.nodes)\n        self.nodes[node.unique_id] = node\n\n    def add_node(self, source_file: AnySourceFile, node: ManifestNode, test_from=None):\n        self.add_node_nofile(node)\n        if isinstance(source_file, SchemaSourceFile):\n            if isinstance(node, GenericTestNode):\n                assert test_from\n                source_file.add_test(node.unique_id, test_from)\n            elif isinstance(node, Metric):\n                source_file.metrics.append(node.unique_id)\n            elif isinstance(node, Exposure):\n                source_file.exposures.append(node.unique_id)\n            elif isinstance(node, Group):\n                source_file.groups.append(node.unique_id)\n            elif isinstance(node, SnapshotNode):\n                source_file.snapshots.append(node.unique_id)\n        elif isinstance(source_file, FixtureSourceFile):\n            pass\n        else:\n            source_file.nodes.append(node.unique_id)\n\n    def add_exposure(self, source_file: SchemaSourceFile, exposure: Exposure):\n        _check_duplicates(exposure, self.exposures)\n        self.exposures[exposure.unique_id] = exposure\n        source_file.exposures.append(exposure.unique_id)\n\n    def add_function(self, source_file: SourceFile, function: FunctionNode):\n        _check_duplicates(function, self.functions)\n        self.functions[function.unique_id] = function\n        source_file.functions.append(function.unique_id)\n\n    def add_metric(\n        self, source_file: SchemaSourceFile, metric: Metric, generated_from: Optional[str] = None\n    ):\n        _check_duplicates(metric, self.metrics)\n        self.metrics[metric.unique_id] = metric\n        if not generated_from:\n            source_file.metrics.append(metric.unique_id)\n        else:\n            source_file.add_metrics_from_measures(generated_from, metric.unique_id)\n\n    def add_group(self, source_file: SchemaSourceFile, group: Group):\n        _check_duplicates(group, self.groups)\n        self.groups[group.unique_id] = group\n        source_file.groups.append(group.unique_id)\n\n    def add_disabled_nofile(self, node: GraphMemberNode):\n        # There can be multiple disabled nodes for the same unique_id\n        if node.unique_id in self.disabled:\n            self.disabled[node.unique_id].append(node)\n        else:\n            self.disabled[node.unique_id] = [node]\n\n    def add_disabled(self, source_file: AnySourceFile, node: GraphMemberNode, test_from=None):\n        self.add_disabled_nofile(node)\n        if isinstance(source_file, SchemaSourceFile):\n            if isinstance(node, GenericTestNode):\n                assert test_from\n                source_file.add_test(node.unique_id, test_from)\n            if isinstance(node, Metric):\n                source_file.metrics.append(node.unique_id)\n            if isinstance(node, SavedQuery):\n                source_file.saved_queries.append(node.unique_id)\n            if isinstance(node, SemanticModel):\n                source_file.semantic_models.append(node.unique_id)\n            if isinstance(node, Exposure):\n                source_file.exposures.append(node.unique_id)\n            if isinstance(node, FunctionNode):\n                source_file.functions.append(node.unique_id)\n            if isinstance(node, UnitTestDefinition):\n                source_file.unit_tests.append(node.unique_id)\n        elif isinstance(source_file, FixtureSourceFile):\n            pass\n        else:\n            source_file.nodes.append(node.unique_id)\n\n    def add_doc(self, source_file: SourceFile, doc: Documentation):\n        _check_duplicates(doc, self.docs)\n        self.docs[doc.unique_id] = doc\n        source_file.docs.append(doc.unique_id)\n\n    def add_semantic_model(self, source_file: SchemaSourceFile, semantic_model: SemanticModel):\n        _check_duplicates(semantic_model, self.semantic_models)\n        self.semantic_models[semantic_model.unique_id] = semantic_model\n        source_file.semantic_models.append(semantic_model.unique_id)\n\n    def add_unit_test(self, source_file: SchemaSourceFile, unit_test: UnitTestDefinition):\n        if unit_test.unique_id in self.unit_tests:\n            raise DuplicateResourceNameError(unit_test, self.unit_tests[unit_test.unique_id])\n        self.unit_tests[unit_test.unique_id] = unit_test\n        source_file.unit_tests.append(unit_test.unique_id)\n\n    def add_fixture(self, source_file: FixtureSourceFile, fixture: UnitTestFileFixture):\n        if fixture.unique_id in self.fixtures:\n            raise DuplicateResourceNameError(fixture, self.fixtures[fixture.unique_id])\n        self.fixtures[fixture.unique_id] = fixture\n        source_file.fixture = fixture.unique_id\n\n    def add_saved_query(self, source_file: SchemaSourceFile, saved_query: SavedQuery) -> None:\n        _check_duplicates(saved_query, self.saved_queries)\n        self.saved_queries[saved_query.unique_id] = saved_query\n        source_file.saved_queries.append(saved_query.unique_id)\n\n    # end of methods formerly in ParseResult\n\n    def find_node_from_ref_or_source(\n        self, expression: str\n    ) -> Optional[Union[ModelNode, SourceDefinition]]:\n        ref_or_source = statically_parse_ref_or_source(expression)\n\n        node = None\n        if isinstance(ref_or_source, RefArgs):\n            node = self.ref_lookup.find(\n                ref_or_source.name, ref_or_source.package, ref_or_source.version, self\n            )\n        else:\n            source_name, source_table_name = ref_or_source[0], ref_or_source[1]\n            node = self.source_lookup.find(f\"{source_name}.{source_table_name}\", None, self)\n\n        return node\n\n    # Provide support for copy.deepcopy() - we just need to avoid the lock!\n    # pickle and deepcopy use this. It returns a callable object used to\n    # create the initial version of the object and a tuple of arguments\n    # for the object, i.e. the Manifest.\n    # The order of the arguments must match the order of the attributes\n    # in the Manifest class declaration, because they are used as\n    # positional arguments to construct a Manifest.\n    def __reduce_ex__(self, protocol):\n        args = (\n            self.nodes,\n            self.sources,\n            self.macros,\n            self.docs,\n            self.exposures,\n            self.functions,\n            self.metrics,\n            self.groups,\n            self.selectors,\n            self.files,\n            self.metadata,\n            self.flat_graph,\n            self.state_check,\n            self.source_patches,\n            self.disabled,\n            self.env_vars,\n            self.semantic_models,\n            self.unit_tests,\n            self.saved_queries,\n            self._doc_lookup,\n            self._source_lookup,\n            self._ref_lookup,\n            self._metric_lookup,\n            self._semantic_model_by_measure_lookup,\n            self._disabled_lookup,\n            self._analysis_lookup,\n            self._singular_test_lookup,\n        )\n        return self.__class__, args\n\n    def _microbatch_macro_is_core(self, project_name: str) -> bool:\n        microbatch_is_core = False\n        candidate = self.find_macro_candidate_by_name(\n            name=\"get_incremental_microbatch_sql\", root_project_name=project_name, package=None\n        )\n\n        # We want to check for \"Core\", because \"Core\" basically means \"builtin\"\n        if candidate is not None and candidate.locality == Locality.Core:\n            microbatch_is_core = True\n\n        return microbatch_is_core\n\n    def use_microbatch_batches(self, project_name: str) -> bool:\n        return (\n            get_flags().require_batched_execution_for_custom_microbatch_strategy\n            or self._microbatch_macro_is_core(project_name=project_name)\n        )\n\n\nclass MacroManifest(MacroMethods):\n    def __init__(self, macros) -> None:\n        self.macros = macros\n        self.metadata = ManifestMetadata(\n            user_id=tracking.active_user.id if tracking.active_user else None,\n            send_anonymous_usage_stats=(\n                get_flags().SEND_ANONYMOUS_USAGE_STATS if tracking.active_user else None\n            ),\n        )\n        # This is returned by the 'graph' context property\n        # in the ProviderContext class.\n        self.flat_graph: Dict[str, Any] = {}\n        self._macros_by_name: Optional[Dict[str, List[Macro]]] = None\n        self._macros_by_package: Optional[Dict[str, Dict[str, Macro]]] = None\n\n\nAnyManifest = Union[Manifest, MacroManifest]\n\n\ndef _check_duplicates(value: BaseNode, src: Mapping[str, BaseNode]):\n    if value.unique_id in src:\n        raise DuplicateResourceNameError(value, src[value.unique_id])\n\n\nK_T = TypeVar(\"K_T\")\nV_T = TypeVar(\"V_T\")\n\n\ndef _expect_value(key: K_T, src: Mapping[K_T, V_T], old_file: SourceFile, name: str) -> V_T:\n    if key not in src:\n        raise CompilationError(\n            'Expected to find \"{}\" in cached \"result.{}\" based '\n            \"on cached file information: {}!\".format(key, name, old_file)\n        )\n    return src[key]\n"
  },
  {
    "path": "core/dbt/contracts/graph/metrics.py",
    "content": "from typing import Any, Dict, Iterator, List\n\nfrom dbt.contracts.graph.manifest import Manifest, Metric\nfrom dbt_semantic_interfaces.type_enums import MetricType\n\nDERIVED_METRICS = [MetricType.DERIVED, MetricType.RATIO]\nBASE_METRICS = [MetricType.SIMPLE, MetricType.CUMULATIVE, MetricType.CONVERSION]\n\n\nclass MetricReference(object):\n    def __init__(self, metric_name, package_name=None) -> None:\n        self.metric_name = metric_name\n        self.package_name = package_name\n\n    def __str__(self):\n        return f\"{self.metric_name}\"\n\n\nclass ResolvedMetricReference(MetricReference):\n    \"\"\"\n    Simple proxy over a Metric which delegates property\n    lookups to the underlying node. Also adds helper functions\n    for working with metrics (ie. __str__ and templating functions)\n    \"\"\"\n\n    def __init__(self, node: Metric, manifest: Manifest) -> None:\n        super().__init__(node.name, node.package_name)\n        self.node = node\n        self.manifest = manifest\n\n    def __getattr__(self, key) -> Any:\n        return getattr(self.node, key)\n\n    def __str__(self) -> str:\n        return f\"{self.node.name}\"\n\n    @classmethod\n    def parent_metrics(cls, metric_node: Metric, manifest: Manifest) -> Iterator[Metric]:\n        \"\"\"For a given metric, yeilds all upstream metrics.\"\"\"\n        yield metric_node\n\n        for parent_unique_id in metric_node.depends_on.nodes:\n            node = manifest.expect(parent_unique_id)\n            if isinstance(node, Metric):\n                yield from cls.parent_metrics(node, manifest)\n\n    @classmethod\n    def parent_metrics_names(cls, metric_node: Metric, manifest: Manifest) -> Iterator[str]:\n        \"\"\"For a given metric, yeilds all upstream metric names\"\"\"\n        for metric in cls.parent_metrics(metric_node, manifest):\n            yield metric.name\n\n    @classmethod\n    def reverse_dag_parsing(\n        cls, metric_node: Metric, manifest: Manifest, metric_depth_count: int\n    ) -> Iterator[Dict[str, int]]:\n        \"\"\"For the given metric, yeilds dictionaries having {<metric_name>: <depth_from_initial_metric} of upstream derived metrics.\n\n        This function is intended as a helper function for other metric helper functions.\n        \"\"\"\n        if metric_node.type in DERIVED_METRICS:\n            yield {metric_node.name: metric_depth_count}\n\n            for parent_unique_id in metric_node.depends_on.nodes:\n                node = manifest.expect(parent_unique_id)\n                if isinstance(node, Metric):\n                    yield from cls.reverse_dag_parsing(node, manifest, metric_depth_count + 1)\n\n    def full_metric_dependency(self):\n        \"\"\"Returns a unique list of all upstream metric names.\"\"\"\n        to_return = list(set(self.parent_metrics_names(self.node, self.manifest)))\n        return to_return\n\n    def base_metric_dependency(self) -> List[str]:\n        \"\"\"Returns a unique list of names for all upstream non-derived metrics.\"\"\"\n        in_scope_metrics = list(self.parent_metrics(self.node, self.manifest))\n        base_metrics = {\n            metric.name for metric in in_scope_metrics if metric.type not in DERIVED_METRICS\n        }\n\n        return list(base_metrics)\n\n    def derived_metric_dependency(self) -> List[str]:\n        \"\"\"Returns a unique list of names for all upstream derived metrics.\"\"\"\n        in_scope_metrics = list(self.parent_metrics(self.node, self.manifest))\n        derived_metrics = {\n            metric.name for metric in in_scope_metrics if metric.type in DERIVED_METRICS\n        }\n\n        return list(derived_metrics)\n\n    def derived_metric_dependency_depth(self) -> List[Dict[str, int]]:\n        \"\"\"Returns a list of {<metric_name>: <depth_from_initial_metric>} for all upstream metrics.\"\"\"\n        metric_depth_count = 1\n        to_return = list(self.reverse_dag_parsing(self.node, self.manifest, metric_depth_count))\n\n        return to_return\n"
  },
  {
    "path": "core/dbt/contracts/graph/model_config.py",
    "content": "from dataclasses import dataclass, field\nfrom typing import Any, Dict, List, Optional, Type\n\nfrom dbt.artifacts.resources import (\n    ExposureConfig,\n    FunctionConfig,\n    GroupConfig,\n    MetricConfig,\n    ModelConfig,\n    NodeConfig,\n    SavedQueryConfig,\n    SeedConfig,\n    SemanticModelConfig,\n    SnapshotConfig,\n    SourceConfig,\n    TestConfig,\n    UnitTestConfig,\n)\nfrom dbt.node_types import NodeType\nfrom dbt_common.contracts.config.base import BaseConfig\nfrom dbt_common.contracts.config.metadata import Metadata\n\n\ndef metas(*metas: Metadata) -> Dict[str, Any]:\n    existing: Dict[str, Any] = {}\n    for m in metas:\n        existing = m.meta(existing)\n    return existing\n\n\ndef insensitive_patterns(*patterns: str):\n    lowercased = []\n    for pattern in patterns:\n        lowercased.append(\"\".join(\"[{}{}]\".format(s.upper(), s.lower()) for s in pattern))\n    return \"^({})$\".format(\"|\".join(lowercased))\n\n\n@dataclass\nclass UnitTestNodeConfig(NodeConfig):\n    expected_rows: List[Dict[str, Any]] = field(default_factory=list)\n    expected_sql: Optional[str] = None\n\n\nRESOURCE_TYPES: Dict[NodeType, Type[BaseConfig]] = {\n    NodeType.Metric: MetricConfig,\n    NodeType.SemanticModel: SemanticModelConfig,\n    NodeType.SavedQuery: SavedQueryConfig,\n    NodeType.Exposure: ExposureConfig,\n    NodeType.Source: SourceConfig,\n    NodeType.Seed: SeedConfig,\n    NodeType.Test: TestConfig,\n    NodeType.Model: ModelConfig,\n    NodeType.Snapshot: SnapshotConfig,\n    NodeType.Unit: UnitTestConfig,\n    NodeType.Group: GroupConfig,\n    NodeType.Function: FunctionConfig,\n}\n\n\n# base resource types are like resource types, except nothing has mandatory\n# configs.\nBASE_RESOURCE_TYPES: Dict[NodeType, Type[BaseConfig]] = RESOURCE_TYPES.copy()\n\n\ndef get_config_for(resource_type: NodeType, base=False) -> Type[BaseConfig]:\n    if base:\n        lookup = BASE_RESOURCE_TYPES\n    else:\n        lookup = RESOURCE_TYPES\n    return lookup.get(resource_type, NodeConfig)\n"
  },
  {
    "path": "core/dbt/contracts/graph/node_args.py",
    "content": "from dataclasses import dataclass, field\nfrom datetime import datetime, timezone\nfrom typing import List, Optional\n\nfrom dbt.artifacts.resources import NodeVersion\nfrom dbt.node_types import AccessType, NodeType\n\n\n@dataclass\nclass ModelNodeArgs:\n    name: str\n    package_name: str\n    identifier: str\n    schema: str\n    database: Optional[str] = None\n    relation_name: Optional[str] = None\n    version: Optional[NodeVersion] = None\n    latest_version: Optional[NodeVersion] = None\n    deprecation_date: Optional[datetime] = None\n    access: Optional[str] = AccessType.Protected.value\n    generated_at: datetime = field(\n        default_factory=lambda: datetime.now(timezone.utc).replace(tzinfo=None)\n    )\n    depends_on_nodes: List[str] = field(default_factory=list)\n    enabled: bool = True\n\n    @property\n    def unique_id(self) -> str:\n        unique_id = f\"{NodeType.Model}.{self.package_name}.{self.name}\"\n        if self.version:\n            unique_id = f\"{unique_id}.v{self.version}\"\n\n        return unique_id\n\n    @property\n    def fqn(self) -> List[str]:\n        fqn = [self.package_name, self.name]\n        # Test for None explicitly because version can be 0\n        if self.version is not None:\n            fqn.append(f\"v{self.version}\")\n\n        return fqn\n"
  },
  {
    "path": "core/dbt/contracts/graph/nodes.py",
    "content": "import hashlib\nimport os\nimport threading\nfrom dataclasses import dataclass, field\nfrom datetime import datetime\nfrom pathlib import Path\nfrom typing import (\n    Any,\n    Dict,\n    Iterator,\n    List,\n    Literal,\n    Optional,\n    Sequence,\n    Tuple,\n    Type,\n    Union,\n    get_args,\n)\n\nfrom mashumaro.types import SerializableType\n\nfrom dbt.adapters.base import ConstraintSupport\nfrom dbt.adapters.factory import get_adapter_constraint_support\nfrom dbt.artifacts.resources import Analysis as AnalysisResource\nfrom dbt.artifacts.resources import (\n    BaseResource,\n    ColumnInfo,\n    CompiledResource,\n    DependsOn,\n    Docs,\n)\nfrom dbt.artifacts.resources import Documentation as DocumentationResource\nfrom dbt.artifacts.resources import Exposure as ExposureResource\nfrom dbt.artifacts.resources import FileHash\nfrom dbt.artifacts.resources import Function as FunctionResource\nfrom dbt.artifacts.resources import FunctionArgument, FunctionReturns\nfrom dbt.artifacts.resources import GenericTest as GenericTestResource\nfrom dbt.artifacts.resources import GraphResource\nfrom dbt.artifacts.resources import Group as GroupResource\nfrom dbt.artifacts.resources import HasRelationMetadata as HasRelationMetadataResource\nfrom dbt.artifacts.resources import HookNode as HookNodeResource\nfrom dbt.artifacts.resources import InjectedCTE\nfrom dbt.artifacts.resources import Macro as MacroResource\nfrom dbt.artifacts.resources import MacroArgument\nfrom dbt.artifacts.resources import Metric as MetricResource\nfrom dbt.artifacts.resources import MetricInputMeasure\nfrom dbt.artifacts.resources import Model as ModelResource\nfrom dbt.artifacts.resources import (\n    ModelConfig,\n    ModelFreshness,\n    NodeConfig,\n    NodeVersion,\n    ParsedResource,\n    ParsedResourceMandatory,\n)\nfrom dbt.artifacts.resources import Quoting as QuotingResource\nfrom dbt.artifacts.resources import SavedQuery as SavedQueryResource\nfrom dbt.artifacts.resources import Seed as SeedResource\nfrom dbt.artifacts.resources import SemanticModel as SemanticModelResource\nfrom dbt.artifacts.resources import SingularTest as SingularTestResource\nfrom dbt.artifacts.resources import Snapshot as SnapshotResource\nfrom dbt.artifacts.resources import SourceDefinition as SourceDefinitionResource\nfrom dbt.artifacts.resources import SqlOperation as SqlOperationResource\nfrom dbt.artifacts.resources import TimeSpine\nfrom dbt.artifacts.resources import UnitTestDefinition as UnitTestDefinitionResource\nfrom dbt.artifacts.schemas.batch_results import BatchResults\nfrom dbt.clients.jinja_static import statically_extract_has_name_this\nfrom dbt.contracts.graph.model_config import UnitTestNodeConfig\nfrom dbt.contracts.graph.node_args import ModelNodeArgs\nfrom dbt.contracts.graph.unparsed import (\n    HasYamlMetadata,\n    TestDef,\n    UnitTestOverrides,\n    UnparsedColumn,\n    UnparsedDerivedSemantics,\n    UnparsedMetricV2,\n    UnparsedSemanticModelConfig,\n    UnparsedSourceDefinition,\n    UnparsedSourceTableDefinition,\n)\nfrom dbt.events.types import (\n    SeedExceedsLimitAndPathChanged,\n    SeedExceedsLimitChecksumChanged,\n    SeedExceedsLimitSamePath,\n    SeedIncreased,\n    UnversionedBreakingChange,\n)\nfrom dbt.exceptions import ContractBreakingChangeError, ParsingError, ValidationError\nfrom dbt.flags import get_flags\nfrom dbt.node_types import (\n    REFABLE_NODE_TYPES,\n    VERSIONED_NODE_TYPES,\n    AccessType,\n    NodeType,\n)\nfrom dbt_common.clients.system import write_file\nfrom dbt_common.contracts.constraints import (\n    ColumnLevelConstraint,\n    ConstraintType,\n    ModelLevelConstraint,\n)\nfrom dbt_common.dataclass_schema import dbtClassMixin\nfrom dbt_common.events.contextvars import set_log_contextvars\nfrom dbt_common.events.functions import warn_or_error\n\n# =====================================================================\n# This contains the classes for all of the nodes and node-like objects\n# in the manifest. In the \"nodes\" dictionary of the manifest we find\n# all of the objects in the ManifestNode union below. In addition the\n# manifest contains \"macros\", \"sources\", \"metrics\", \"exposures\", \"docs\",\n# and \"disabled\" dictionaries.\n#\n# The SeedNode is a ManifestNode, but can't be compiled because it has\n# no SQL.\n#\n# All objects defined in this file should have BaseNode as a parent\n# class.\n#\n# The two objects which do not show up in the DAG are Macro and\n# Documentation.\n# =====================================================================\n\n\n# ==================================================\n# Various parent classes and node attribute classes\n# ==================================================\n\n\n@dataclass\nclass BaseNode(BaseResource):\n    \"\"\"All nodes or node-like objects in this file should have this as a base class\"\"\"\n\n    # In an ideal world this would be a class property. However, chaining @classmethod and\n    # @property was deprecated in python 3.11 and removed in 3.13. There are more\n    # complicated ways of making a class property, however a class method suits our\n    # purposes well enough\n    @classmethod\n    def resource_class(cls) -> Type[BaseResource]:\n        \"\"\"Should be overriden by any class inheriting BaseNode\"\"\"\n        raise NotImplementedError\n\n    @property\n    def search_name(self):\n        return self.name\n\n    @property\n    def file_id(self):\n        return f\"{self.package_name}://{self.original_file_path}\"\n\n    @property\n    def is_refable(self):\n        return self.resource_type in REFABLE_NODE_TYPES\n\n    @property\n    def should_store_failures(self):\n        return False\n\n    # will this node map to an object in the database?\n    @property\n    def is_relational(self):\n        return self.resource_type in REFABLE_NODE_TYPES\n\n    @property\n    def is_versioned(self):\n        return self.resource_type in VERSIONED_NODE_TYPES and self.version is not None\n\n    @property\n    def is_ephemeral(self):\n        return self.config.materialized == \"ephemeral\"\n\n    @property\n    def is_ephemeral_model(self):\n        return self.is_refable and self.is_ephemeral\n\n    def get_materialization(self):\n        return self.config.materialized\n\n    @classmethod\n    def from_resource(cls, resource_instance: BaseResource):\n        assert isinstance(resource_instance, cls.resource_class())\n        return cls.from_dict(resource_instance.to_dict())\n\n    def to_resource(self):\n        return self.resource_class().from_dict(self.to_dict())\n\n\n@dataclass\nclass GraphNode(GraphResource, BaseNode):\n    \"\"\"Nodes in the DAG. Macro and Documentation don't have fqn.\"\"\"\n\n    def same_fqn(self, other) -> bool:\n        return self.fqn == other.fqn\n\n\n@dataclass\nclass HasRelationMetadata(HasRelationMetadataResource):\n    @classmethod\n    def __pre_deserialize__(cls, data):\n        data = super().__pre_deserialize__(data)\n        if \"database\" not in data:\n            data[\"database\"] = None\n        return data\n\n    @property\n    def quoting_dict(self) -> Dict[str, bool]:\n        if hasattr(self, \"quoting\"):\n            return self.quoting.to_dict(omit_none=True)\n        else:\n            return {}\n\n\n@dataclass\nclass ParsedNodeMandatory(ParsedResourceMandatory, GraphNode, HasRelationMetadata):\n    pass\n\n\n# This needs to be in all ManifestNodes and also in SourceDefinition,\n# because of \"source freshness\". Should not be in artifacts, because we\n# don't write out _event_status.\n@dataclass\nclass NodeInfoMixin:\n    _event_status: Dict[str, Any] = field(default_factory=dict)\n\n    @property\n    def node_info(self):\n        node_info = {\n            \"node_path\": getattr(self, \"path\", None),\n            \"node_name\": getattr(self, \"name\", None),\n            \"unique_id\": getattr(self, \"unique_id\", None),\n            \"resource_type\": str(getattr(self, \"resource_type\", \"\")),\n            \"materialized\": self.config.get(\"materialized\"),\n            \"node_status\": str(self._event_status.get(\"node_status\")),\n            \"node_started_at\": self._event_status.get(\"started_at\"),\n            \"node_finished_at\": self._event_status.get(\"finished_at\"),\n            \"meta\": getattr(self, \"meta\", {}),\n            \"node_relation\": {\n                \"database\": getattr(self, \"database\", None),\n                \"schema\": getattr(self, \"schema\", None),\n                \"alias\": getattr(self, \"alias\", None),\n                \"relation_name\": getattr(self, \"relation_name\", None),\n            },\n            \"node_checksum\": getattr(getattr(self, \"checksum\", None), \"checksum\", None),\n        }\n        return node_info\n\n    def update_event_status(self, **kwargs):\n        for k, v in kwargs.items():\n            self._event_status[k] = v\n        set_log_contextvars(node_info=self.node_info)\n\n    def clear_event_status(self):\n        self._event_status = dict()\n\n\n@dataclass\nclass ParsedNode(ParsedResource, NodeInfoMixin, ParsedNodeMandatory, SerializableType):\n    def get_target_write_path(\n        self, target_path: str, subdirectory: str, split_suffix: Optional[str] = None\n    ):\n        # This is called for both the \"compiled\" subdirectory of \"target\" and the \"run\" subdirectory\n        if os.path.basename(self.path) == os.path.basename(self.original_file_path):\n            # One-to-one relationship of nodes to files.\n            path = self.original_file_path\n        else:\n            #  Many-to-one relationship of nodes to files.\n            path = os.path.join(self.original_file_path, self.path)\n\n        if split_suffix:\n            pathlib_path = Path(path)\n            path = str(\n                pathlib_path.parent\n                / pathlib_path.stem\n                / (pathlib_path.stem + f\"_{split_suffix}\" + pathlib_path.suffix)\n            )\n\n        target_write_path = os.path.join(target_path, subdirectory, self.package_name, path)\n        return target_write_path\n\n    def write_node(self, project_root: str, compiled_path, compiled_code: str):\n        if os.path.isabs(compiled_path):\n            full_path = compiled_path\n        else:\n            full_path = os.path.join(project_root, compiled_path)\n        write_file(full_path, compiled_code)\n\n    def _serialize(self):\n        return self.to_dict()\n\n    def __post_serialize__(self, dct: Dict, context: Optional[Dict] = None):\n        dct = super().__post_serialize__(dct, context)\n        if \"_event_status\" in dct:\n            del dct[\"_event_status\"]\n        return dct\n\n    @classmethod\n    def _deserialize(cls, dct: Dict[str, int]):\n        # The serialized ParsedNodes do not differ from each other\n        # in fields that would allow 'from_dict' to distinguis\n        # between them.\n        resource_type = dct[\"resource_type\"]\n        if resource_type == \"model\":\n            return ModelNode.from_dict(dct)\n        elif resource_type == \"analysis\":\n            return AnalysisNode.from_dict(dct)\n        elif resource_type == \"seed\":\n            return SeedNode.from_dict(dct)\n        elif resource_type == \"sql\":\n            return SqlNode.from_dict(dct)\n        elif resource_type == \"test\":\n            if \"test_metadata\" in dct:\n                return GenericTestNode.from_dict(dct)\n            else:\n                return SingularTestNode.from_dict(dct)\n        elif resource_type == \"operation\":\n            return HookNode.from_dict(dct)\n        elif resource_type == \"seed\":\n            return SeedNode.from_dict(dct)\n        elif resource_type == \"snapshot\":\n            return SnapshotNode.from_dict(dct)\n        else:\n            return cls.from_dict(dct)\n\n    def _persist_column_docs(self) -> bool:\n        if hasattr(self.config, \"persist_docs\"):\n            assert isinstance(self.config, NodeConfig)\n            return bool(self.config.persist_docs.get(\"columns\"))\n        return False\n\n    def _persist_relation_docs(self) -> bool:\n        if hasattr(self.config, \"persist_docs\"):\n            assert isinstance(self.config, NodeConfig)\n            return bool(self.config.persist_docs.get(\"relation\"))\n        return False\n\n    def same_persisted_description(self, other) -> bool:\n        # the check on configs will handle the case where we have different\n        # persist settings, so we only have to care about the cases where they\n        # are the same..\n        if self._persist_relation_docs():\n            if self.description != other.description:\n                return False\n\n        if self._persist_column_docs():\n            # assert other._persist_column_docs()\n            column_descriptions = {k: v.description for k, v in self.columns.items()}\n            other_column_descriptions = {k: v.description for k, v in other.columns.items()}\n            if column_descriptions != other_column_descriptions:\n                return False\n\n        return True\n\n    def same_body(self, other) -> bool:\n        return self.raw_code == other.raw_code\n\n    def same_database_representation(self, other) -> bool:\n        # compare the config representation, not the node's config value. This\n        # compares the configured value, rather than the ultimate value (so\n        # generate_*_name and unset values derived from the target are\n        # ignored)\n        keys = (\"database\", \"schema\", \"alias\")\n        for key in keys:\n            mine = self.unrendered_config.get(key)\n            others = other.unrendered_config.get(key)\n            if mine != others:\n                return False\n        return True\n\n    def same_config(self, old) -> bool:\n        return self.config.same_contents(\n            self.unrendered_config,\n            old.unrendered_config,\n        )\n\n    def build_contract_checksum(self):\n        pass\n\n    def same_contract(self, old, adapter_type=None) -> bool:\n        # This would only apply to seeds\n        return True\n\n    def same_contents(self, old, adapter_type) -> bool:\n        if old is None:\n            return False\n\n        # Need to ensure that same_contract is called because it\n        # could throw an error\n        same_contract = self.same_contract(old, adapter_type)\n        return (\n            self.same_body(old)\n            and self.same_config(old)\n            and self.same_persisted_description(old)\n            and self.same_fqn(old)\n            and self.same_database_representation(old)\n            and same_contract\n            and True\n        )\n\n    @property\n    def is_external_node(self):\n        return False\n\n\n@dataclass\nclass CompiledNode(CompiledResource, ParsedNode):\n    \"\"\"Contains attributes necessary for SQL files and nodes with refs, sources, etc,\n    so all ManifestNodes except SeedNode.\"\"\"\n\n    def __post_init__(self):\n        self._lock = threading.Lock()\n\n    def __getstate__(self):\n        state = self.__dict__.copy()\n        state.pop(\"_lock\", None)\n        return state\n\n    def __setstate__(self, state):\n        self.__dict__.update(state)\n        self._lock = threading.Lock()\n\n    @property\n    def empty(self):\n        return not self.raw_code.strip()\n\n    def set_cte(self, cte_id: str, sql: str):\n        \"\"\"This is the equivalent of what self.extra_ctes[cte_id] = sql would\n        do if extra_ctes were an OrderedDict\n        \"\"\"\n        for cte in self.extra_ctes:\n            # Because it's possible that multiple threads are compiling the\n            # node at the same time, we don't want to overwrite already compiled\n            # sql in the extra_ctes with empty sql.\n            if cte.id == cte_id:\n                break\n        else:\n            self.extra_ctes.append(InjectedCTE(id=cte_id, sql=sql))\n\n    @property\n    def depends_on_nodes(self):\n        return self.depends_on.nodes\n\n    @property\n    def depends_on_macros(self):\n        return self.depends_on.macros\n\n\n# ====================================\n# CompiledNode subclasses\n# ====================================\n\n\n@dataclass\nclass AnalysisNode(AnalysisResource, CompiledNode):\n    @classmethod\n    def resource_class(cls) -> Type[AnalysisResource]:\n        return AnalysisResource\n\n\n@dataclass\nclass HookNode(HookNodeResource, CompiledNode):\n    @classmethod\n    def resource_class(cls) -> Type[HookNodeResource]:\n        return HookNodeResource\n\n\n@dataclass\nclass BatchContext(dbtClassMixin):\n    id: str\n    event_time_start: datetime\n    event_time_end: datetime\n\n    def __post_serialize__(self, data, context):\n        # This is insane, but necessary, I apologize. Mashumaro handles the\n        # dictification of this class via a compile time generated `to_dict`\n        # method based off of the _typing_ of th class. By default `datetime`\n        # types are converted to strings. We don't want that, we want them to\n        # stay datetimes.\n        # Note: This is safe because the `BatchContext` isn't part of the artifact\n        # and thus doesn't get written out.\n        new_data = super().__post_serialize__(data, context)\n        new_data[\"event_time_start\"] = self.event_time_start\n        new_data[\"event_time_end\"] = self.event_time_end\n        return new_data\n\n\n@dataclass\nclass ModelNode(ModelResource, CompiledNode):\n    previous_batch_results: Optional[BatchResults] = None\n    batch: Optional[BatchContext] = None\n    _has_this: Optional[bool] = None\n\n    def __post_serialize__(self, dct: Dict, context: Optional[Dict] = None):\n        dct = super().__post_serialize__(dct, context)\n        if \"_has_this\" in dct:\n            del dct[\"_has_this\"]\n        if \"previous_batch_results\" in dct:\n            del dct[\"previous_batch_results\"]\n        return dct\n\n    @classmethod\n    def resource_class(cls) -> Type[ModelResource]:\n        return ModelResource\n\n    @classmethod\n    def from_args(cls, args: ModelNodeArgs) -> \"ModelNode\":\n        unique_id = args.unique_id\n\n        # build unrendered config -- for usage in ParsedNode.same_contents\n        unrendered_config = {}\n        unrendered_config[\"alias\"] = args.identifier\n        unrendered_config[\"schema\"] = args.schema\n        if args.database:\n            unrendered_config[\"database\"] = args.database\n\n        return cls(\n            resource_type=NodeType.Model,\n            name=args.name,\n            package_name=args.package_name,\n            unique_id=unique_id,\n            fqn=args.fqn,\n            version=args.version,\n            latest_version=args.latest_version,\n            relation_name=args.relation_name,\n            database=args.database,\n            schema=args.schema,\n            alias=args.identifier,\n            deprecation_date=args.deprecation_date,\n            checksum=FileHash.from_contents(f\"{unique_id},{args.generated_at}\"),\n            access=AccessType(args.access),\n            original_file_path=\"\",\n            path=\"\",\n            unrendered_config=unrendered_config,\n            depends_on=DependsOn(nodes=args.depends_on_nodes),\n            config=ModelConfig(enabled=args.enabled),\n        )\n\n    @property\n    def is_external_node(self) -> bool:\n        return not self.original_file_path and not self.path\n\n    @property\n    def is_latest_version(self) -> bool:\n        return self.version is not None and self.version == self.latest_version\n\n    @property\n    def is_past_deprecation_date(self) -> bool:\n        return (\n            self.deprecation_date is not None\n            and self.deprecation_date < datetime.now().astimezone()\n        )\n\n    @property\n    def search_name(self):\n        if self.version is None:\n            return self.name\n        else:\n            return f\"{self.name}.v{self.version}\"\n\n    @property\n    def materialization_enforces_constraints(self) -> bool:\n        return self.config.materialized in [\"table\", \"incremental\"]\n\n    @property\n    def all_constraints(self) -> List[Union[ModelLevelConstraint, ColumnLevelConstraint]]:\n        constraints: List[Union[ModelLevelConstraint, ColumnLevelConstraint]] = []\n        for model_level_constraint in self.constraints:\n            constraints.append(model_level_constraint)\n\n        for column in self.columns.values():\n            for column_level_constraint in column.constraints:\n                constraints.append(column_level_constraint)\n\n        return constraints\n\n    @property\n    def has_this(self) -> bool:\n        if self._has_this is None:\n            self._has_this = statically_extract_has_name_this(self.raw_code)\n        return self._has_this\n\n    def infer_primary_key(self, data_tests: List[\"GenericTestNode\"]) -> List[str]:\n        \"\"\"\n        Infers the columns that can be used as primary key of a model in the following order:\n        1. Columns with primary key constraints\n        2. Columns with unique and not_null data tests\n        3. Columns with enabled unique or dbt_utils.unique_combination_of_columns data tests\n        4. Columns with disabled unique or dbt_utils.unique_combination_of_columns data tests\n        \"\"\"\n        for constraint in self.constraints:\n            if constraint.type == ConstraintType.primary_key:\n                return constraint.columns\n\n        for column, column_info in self.columns.items():\n            for column_constraint in column_info.constraints:\n                if column_constraint.type == ConstraintType.primary_key:\n                    return [column]\n\n        columns_with_enabled_unique_tests = set()\n        columns_with_disabled_unique_tests = set()\n        columns_with_not_null_tests = set()\n        for test in data_tests:\n            columns: List[str] = []\n            # extract columns from test kwargs, ensuring columns is a List[str] given tests can have custom (user or pacakge-defined) kwarg types\n            if \"column_name\" in test.test_metadata.kwargs and isinstance(\n                test.test_metadata.kwargs[\"column_name\"], str\n            ):\n                columns = [test.test_metadata.kwargs[\"column_name\"]]\n            elif \"combination_of_columns\" in test.test_metadata.kwargs and isinstance(\n                test.test_metadata.kwargs[\"combination_of_columns\"], list\n            ):\n                columns = [\n                    column\n                    for column in test.test_metadata.kwargs[\"combination_of_columns\"]\n                    if isinstance(column, str)\n                ]\n\n            for column in columns:\n                if test.test_metadata.name in [\"unique\", \"unique_combination_of_columns\"]:\n                    if test.config.enabled:\n                        columns_with_enabled_unique_tests.add(column)\n                    else:\n                        columns_with_disabled_unique_tests.add(column)\n                elif test.test_metadata.name == \"not_null\":\n                    columns_with_not_null_tests.add(column)\n\n        columns_with_unique_and_not_null_tests = []\n        for column in columns_with_not_null_tests:\n            if (\n                column in columns_with_enabled_unique_tests\n                or column in columns_with_disabled_unique_tests\n            ):\n                columns_with_unique_and_not_null_tests.append(column)\n        if columns_with_unique_and_not_null_tests:\n            return columns_with_unique_and_not_null_tests\n\n        if columns_with_enabled_unique_tests:\n            return list(columns_with_enabled_unique_tests)\n\n        if columns_with_disabled_unique_tests:\n            return list(columns_with_disabled_unique_tests)\n\n        return []\n\n    def same_contents(self, old, adapter_type) -> bool:\n        return super().same_contents(old, adapter_type) and self.same_ref_representation(old)\n\n    def same_ref_representation(self, old) -> bool:\n        return (\n            # Changing the latest_version may break downstream unpinned refs\n            self.latest_version == old.latest_version\n            # Changes to access or deprecation_date may lead to ref-related parsing errors\n            and self.access == old.access\n            and self.deprecation_date == old.deprecation_date\n        )\n\n    def build_contract_checksum(self):\n        # We don't need to construct the checksum if the model does not\n        # have contract enforced, because it won't be used.\n        # This needs to be executed after contract config is set\n\n        # Avoid rebuilding the checksum if it has already been set.\n        if self.contract.checksum is not None:\n            return\n\n        if self.contract.enforced is True:\n            contract_state = \"\"\n            # We need to sort the columns so that order doesn't matter\n            # columns is a str: ColumnInfo dictionary\n            sorted_columns = sorted(self.columns.values(), key=lambda col: col.name)\n            for column in sorted_columns:\n                contract_state += f\"|{column.name}\"\n                contract_state += str(column.data_type)\n                contract_state += str(column.constraints)\n            if self.materialization_enforces_constraints:\n                contract_state += self.config.materialized\n                contract_state += str(self.constraints)\n            data = contract_state.encode(\"utf-8\")\n            self.contract.checksum = hashlib.new(\"sha256\", data).hexdigest()\n\n    def same_contract_removed(self) -> bool:\n        \"\"\"\n        self: the removed (deleted, renamed, or disabled) model node\n        \"\"\"\n        # If the contract wasn't previously enforced, no contract change has occurred\n        if self.contract.enforced is False:\n            return True\n\n        # Removed node is past its deprecation_date, so deletion does not constitute a contract change\n        if self.is_past_deprecation_date:\n            return True\n\n        # Disabled, deleted, or renamed node with previously enforced contract.\n        if not self.config.enabled:\n            breaking_change = f\"Contracted model '{self.unique_id}' was disabled.\"\n        else:\n            breaking_change = f\"Contracted model '{self.unique_id}' was deleted or renamed.\"\n\n        if self.version is None:\n            warn_or_error(\n                UnversionedBreakingChange(\n                    breaking_changes=[breaking_change],\n                    model_name=self.name,\n                    model_file_path=self.original_file_path,\n                ),\n                node=self,\n            )\n            return False\n        else:\n            raise (\n                ContractBreakingChangeError(\n                    breaking_changes=[breaking_change],\n                    node=self,\n                )\n            )\n\n    @staticmethod\n    def _normalize_data_type_for_comparison(data_type: Optional[str]) -> Optional[str]:\n        \"\"\"\n        Normalize a data type string by removing size, precision, and scale parameters.\n        This allows comparison of base types while ignoring non-breaking parameter changes.\n\n        Examples:\n            varchar(10) -> varchar\n            VARCHAR(5) -> varchar\n            numeric(10,2) -> numeric\n            text -> text\n            decimal(5) -> decimal\n            None -> None\n\n        Per dbt documentation, changes to size/precision/scale should not be\n        considered breaking changes for contracts.\n        See: https://docs.getdbt.com/reference/resource-configs/contract#size-precision-and-scale\n\n        Note: Comparison is case-insensitive. Type aliases (e.g., 'varchar' vs\n        'character varying') are not automatically resolved - users should use\n        consistent type names in their contracts to avoid false positives.\n        \"\"\"\n        if not data_type:\n            return data_type\n\n        # Split on the first '(' to get the base type without parameters\n        # Convert to lowercase for case-insensitive comparison\n        base_type, _, _ = data_type.partition(\"(\")\n        return base_type.strip().lower()\n\n    def same_contract(self, old, adapter_type=None) -> bool:\n        # If the contract wasn't previously enforced:\n        if old.contract.enforced is False and self.contract.enforced is False:\n            # No change -- same_contract: True\n            return True\n        if old.contract.enforced is False and self.contract.enforced is True:\n            # Now it's enforced. This is a change, but not a breaking change -- same_contract: False\n            return False\n\n        # Otherwise: The contract was previously enforced, and we need to check for changes.\n        # Happy path: The contract is still being enforced, and the checksums are identical.\n        if self.contract.enforced is True and self.contract.checksum == old.contract.checksum:\n            # No change -- same_contract: True\n            return True\n\n        # Otherwise: There has been a change.\n        # We need to determine if it is a **breaking** change.\n        # These are the categories of breaking changes:\n        contract_enforced_disabled: bool = False\n        columns_removed: List[str] = []\n        column_type_changes: List[Dict[str, str]] = []\n        enforced_column_constraint_removed: List[Dict[str, str]] = (\n            []\n        )  # column_name, constraint_type\n        enforced_model_constraint_removed: List[Dict[str, Any]] = []  # constraint_type, columns\n        materialization_changed: List[str] = []\n\n        if old.contract.enforced is True and self.contract.enforced is False:\n            # Breaking change: the contract was previously enforced, and it no longer is\n            contract_enforced_disabled = True\n\n        constraint_support = get_adapter_constraint_support(adapter_type)\n        column_constraints_exist = False\n\n        # Next, compare each column from the previous contract (old.columns)\n        for old_key, old_value in sorted(old.columns.items()):\n            # Has this column been removed?\n            if old_key not in self.columns.keys():\n                columns_removed.append(old_value.name)\n            # Has this column's data type changed?\n            elif old_value.data_type != self.columns[old_key].data_type:\n                # Compare normalized data types (without size/precision/scale)\n                # to determine if this is a breaking change\n                old_normalized = self._normalize_data_type_for_comparison(old_value.data_type)\n                new_normalized = self._normalize_data_type_for_comparison(\n                    self.columns[old_key].data_type\n                )\n\n                # Only consider it a breaking change if the base types differ\n                # Changes like varchar(3) -> varchar(10) are not breaking\n                if old_normalized != new_normalized:\n                    column_type_changes.append(\n                        {\n                            \"column_name\": str(old_value.name),\n                            \"previous_column_type\": str(old_value.data_type),\n                            \"current_column_type\": str(self.columns[old_key].data_type),\n                        }\n                    )\n\n            # track if there are any column level constraints for the materialization check late\n            if old_value.constraints:\n                column_constraints_exist = True\n\n            # Have enforced columns level constraints changed?\n            # Constraints are only enforced for table and incremental materializations.\n            # We only really care if the old node was one of those materializations for breaking changes\n            if (\n                old_key in self.columns.keys()\n                and old_value.constraints != self.columns[old_key].constraints\n                and old.materialization_enforces_constraints\n            ):\n                for old_constraint in old_value.constraints:\n                    if (\n                        old_constraint not in self.columns[old_key].constraints\n                        and constraint_support[old_constraint.type] == ConstraintSupport.ENFORCED\n                    ):\n                        enforced_column_constraint_removed.append(\n                            {\n                                \"column_name\": old_key,\n                                \"constraint_name\": old_constraint.name,\n                                \"constraint_type\": ConstraintType(old_constraint.type),\n                            }\n                        )\n\n        # Now compare the model level constraints\n        if old.constraints != self.constraints and old.materialization_enforces_constraints:\n            for old_constraint in old.constraints:\n                if (\n                    old_constraint not in self.constraints\n                    and constraint_support[old_constraint.type] == ConstraintSupport.ENFORCED\n                ):\n                    enforced_model_constraint_removed.append(\n                        {\n                            \"constraint_name\": old_constraint.name,\n                            \"constraint_type\": ConstraintType(old_constraint.type),\n                            \"columns\": old_constraint.columns,\n                        }\n                    )\n\n        # Check for relevant materialization changes.\n        if (\n            old.materialization_enforces_constraints\n            and not self.materialization_enforces_constraints\n            and (old.constraints or column_constraints_exist)\n        ):\n            materialization_changed = [old.config.materialized, self.config.materialized]\n\n        # If a column has been added, it will be missing in the old.columns, and present in self.columns\n        # That's a change (caught by the different checksums), but not a breaking change\n\n        # Did we find any changes that we consider breaking? If there's an enforced contract, that's\n        # a warning unless the model is versioned, then it's an error.\n        if (\n            contract_enforced_disabled\n            or columns_removed\n            or column_type_changes\n            or enforced_model_constraint_removed\n            or enforced_column_constraint_removed\n            or materialization_changed\n        ):\n\n            breaking_changes = []\n            if contract_enforced_disabled:\n                breaking_changes.append(\n                    \"Contract enforcement was removed: Previously, this model had an enforced contract. It is no longer configured to enforce its contract, and this is a breaking change.\"\n                )\n            if columns_removed:\n                columns_removed_str = \"\\n    - \".join(columns_removed)\n                breaking_changes.append(f\"Columns were removed: \\n    - {columns_removed_str}\")\n            if column_type_changes:\n                column_type_changes_str = \"\\n    - \".join(\n                    [\n                        f\"{c['column_name']} ({c['previous_column_type']} -> {c['current_column_type']})\"\n                        for c in column_type_changes\n                    ]\n                )\n                breaking_changes.append(\n                    f\"Columns with data_type changes: \\n    - {column_type_changes_str}\"\n                )\n            if enforced_column_constraint_removed:\n                column_constraint_changes_str = \"\\n    - \".join(\n                    [\n                        f\"'{c['constraint_name'] if c['constraint_name'] is not None else c['constraint_type']}' constraint on column {c['column_name']}\"\n                        for c in enforced_column_constraint_removed\n                    ]\n                )\n                breaking_changes.append(\n                    f\"Enforced column level constraints were removed: \\n    - {column_constraint_changes_str}\"\n                )\n            if enforced_model_constraint_removed:\n                model_constraint_changes_str = \"\\n    - \".join(\n                    [\n                        f\"'{c['constraint_name'] if c['constraint_name'] is not None else c['constraint_type']}' constraint on columns {c['columns']}\"\n                        for c in enforced_model_constraint_removed\n                    ]\n                )\n                breaking_changes.append(\n                    f\"Enforced model level constraints were removed: \\n    - {model_constraint_changes_str}\"\n                )\n            if materialization_changed:\n                materialization_changes_str = (\n                    f\"{materialization_changed[0]} -> {materialization_changed[1]}\"\n                )\n\n                breaking_changes.append(\n                    f\"Materialization changed with enforced constraints: \\n    - {materialization_changes_str}\"\n                )\n\n            if self.version is None:\n                warn_or_error(\n                    UnversionedBreakingChange(\n                        contract_enforced_disabled=contract_enforced_disabled,\n                        columns_removed=columns_removed,\n                        column_type_changes=column_type_changes,\n                        enforced_column_constraint_removed=enforced_column_constraint_removed,\n                        enforced_model_constraint_removed=enforced_model_constraint_removed,\n                        breaking_changes=breaking_changes,\n                        model_name=self.name,\n                        model_file_path=self.original_file_path,\n                    ),\n                    node=self,\n                )\n            else:\n                raise (\n                    ContractBreakingChangeError(\n                        breaking_changes=breaking_changes,\n                        node=self,\n                    )\n                )\n\n        # Otherwise, the contract has changed -- same_contract: False\n        return False\n\n\n@dataclass\nclass SqlNode(SqlOperationResource, CompiledNode):\n    @classmethod\n    def resource_class(cls) -> Type[SqlOperationResource]:\n        return SqlOperationResource\n\n\n# ====================================\n# Seed node\n# ====================================\n\n\n@dataclass\nclass SeedNode(SeedResource, ParsedNode):  # No SQLDefaults!\n    @classmethod\n    def resource_class(cls) -> Type[SeedResource]:\n        return SeedResource\n\n    def same_seeds(self, other: \"SeedNode\") -> bool:\n        # for seeds, we check the hashes. If the hashes are different types,\n        # no match. If the hashes are both the same 'path', log a warning and\n        # assume they are the same\n        # if the current checksum is a path, we want to log a warning.\n        result = self.checksum == other.checksum\n\n        if self.checksum.name == \"path\":\n            msg: str\n            if other.checksum.name != \"path\":\n                warn_or_error(\n                    SeedIncreased(package_name=self.package_name, name=self.name), node=self\n                )\n            elif result:\n                warn_or_error(\n                    SeedExceedsLimitSamePath(package_name=self.package_name, name=self.name),\n                    node=self,\n                )\n            elif not result:\n                warn_or_error(\n                    SeedExceedsLimitAndPathChanged(package_name=self.package_name, name=self.name),\n                    node=self,\n                )\n            else:\n                warn_or_error(\n                    SeedExceedsLimitChecksumChanged(\n                        package_name=self.package_name,\n                        name=self.name,\n                        checksum_name=other.checksum.name,\n                    ),\n                    node=self,\n                )\n\n        return result\n\n    @property\n    def empty(self):\n        \"\"\"Seeds are never empty\"\"\"\n        return False\n\n    def _disallow_implicit_dependencies(self):\n        \"\"\"Disallow seeds to take implicit upstream dependencies via pre/post hooks\"\"\"\n        # Seeds are root nodes in the DAG. They cannot depend on other nodes.\n        # However, it's possible to define pre- and post-hooks on seeds, and for those\n        # hooks to include {{ ref(...) }}. This worked in previous versions, but it\n        # was never officially documented or supported behavior. Let's raise an explicit error,\n        # which will surface during parsing if the user has written code such that we attempt\n        # to capture & record a ref/source/metric call on the SeedNode.\n        # For more details: https://github.com/dbt-labs/dbt-core/issues/6806\n        hooks = [f'- pre_hook: \"{hook.sql}\"' for hook in self.config.pre_hook] + [\n            f'- post_hook: \"{hook.sql}\"' for hook in self.config.post_hook\n        ]\n        hook_list = \"\\n\".join(hooks)\n        message = f\"\"\"\nSeeds cannot depend on other nodes. dbt detected a seed with a pre- or post-hook\nthat calls 'ref', 'source', or 'metric', either directly or indirectly via other macros.\n\nError raised for '{self.unique_id}', which has these hooks defined: \\n{hook_list}\n        \"\"\"\n        raise ParsingError(message)\n\n    @property\n    def refs(self):\n        self._disallow_implicit_dependencies()\n\n    @property\n    def sources(self):\n        self._disallow_implicit_dependencies()\n\n    @property\n    def metrics(self):\n        self._disallow_implicit_dependencies()\n\n    def same_body(self, other) -> bool:\n        return self.same_seeds(other)\n\n    @property\n    def depends_on_nodes(self):\n        return []\n\n    @property\n    def depends_on_macros(self) -> List[str]:\n        return self.depends_on.macros\n\n    @property\n    def extra_ctes(self):\n        return []\n\n    @property\n    def extra_ctes_injected(self):\n        return False\n\n    @property\n    def language(self):\n        return \"sql\"\n\n\n#    @property\n#    def compiled_code(self):\n#        return None\n\n\n# ====================================\n# Singular Test node\n# ====================================\n\n\nclass TestShouldStoreFailures:\n    @property\n    def should_store_failures(self):\n        if self.config.store_failures:\n            return self.config.store_failures\n        return get_flags().STORE_FAILURES\n\n    @property\n    def is_relational(self):\n        if self.should_store_failures:\n            return True\n        return False\n\n\n@dataclass\nclass SingularTestNode(SingularTestResource, TestShouldStoreFailures, CompiledNode):\n    @classmethod\n    def resource_class(cls) -> Type[SingularTestResource]:\n        return SingularTestResource\n\n    @property\n    def test_node_type(self):\n        return \"singular\"\n\n\n# ====================================\n# Generic Test node\n# ====================================\n\n\n@dataclass\nclass GenericTestNode(GenericTestResource, TestShouldStoreFailures, CompiledNode):\n    @classmethod\n    def resource_class(cls) -> Type[GenericTestResource]:\n        return GenericTestResource\n\n    def same_contents(self, other, adapter_type: Optional[str]) -> bool:\n        if other is None:\n            return False\n\n        return self.same_config(other) and self.same_fqn(other) and True\n\n    @property\n    def test_node_type(self):\n        return \"generic\"\n\n\n@dataclass\nclass UnitTestSourceDefinition(ModelNode):\n    source_name: str = \"undefined\"\n    quoting: QuotingResource = field(default_factory=QuotingResource)\n\n    @property\n    def cte_name(self):\n        return self.unique_id.split(\".\")[-1]\n\n    @property\n    def search_name(self):\n        return f\"{self.source_name}.{self.name}\"\n\n\n@dataclass\nclass UnitTestNode(CompiledNode):\n    resource_type: Literal[NodeType.Unit]\n    tested_node_unique_id: Optional[str] = None\n    this_input_node_unique_id: Optional[str] = None\n    overrides: Optional[UnitTestOverrides] = None\n    config: UnitTestNodeConfig = field(default_factory=UnitTestNodeConfig)\n\n\n@dataclass\nclass UnitTestDefinition(NodeInfoMixin, GraphNode, UnitTestDefinitionResource):\n    @classmethod\n    def resource_class(cls) -> Type[UnitTestDefinitionResource]:\n        return UnitTestDefinitionResource\n\n    @property\n    def depends_on_nodes(self):\n        return self.depends_on.nodes\n\n    @property\n    def tags(self) -> List[str]:\n        tags = self.config.tags\n        return [tags] if isinstance(tags, str) else tags\n\n    @property\n    def versioned_name(self) -> str:\n        versioned_name = self.name\n        if self.version is not None:\n            versioned_name += f\"_v{self.version}\"\n        return versioned_name\n\n    def build_unit_test_checksum(self):\n        # everything except 'description'\n        data = f\"{self.model}-{self.versions}-{self.given}-{self.expect}-{self.overrides}\"\n\n        # include underlying fixture data\n        for input in self.given:\n            if input.fixture:\n                data += f\"-{input.rows}\"\n\n        self.checksum = hashlib.new(\"sha256\", data.encode(\"utf-8\")).hexdigest()\n\n    def same_contents(self, other: Optional[\"UnitTestDefinition\"]) -> bool:\n        if other is None:\n            return False\n\n        return self.checksum == other.checksum\n\n\n@dataclass\nclass UnitTestFileFixture(BaseNode):\n    resource_type: Literal[NodeType.Fixture]\n    rows: Optional[Union[List[Dict[str, Any]], str]] = None\n\n\n# ====================================\n# Snapshot node\n# ====================================\n\n\n@dataclass\nclass SnapshotNode(SnapshotResource, CompiledNode):\n    @classmethod\n    def resource_class(cls) -> Type[SnapshotResource]:\n        return SnapshotResource\n\n\n# ====================================\n# Macro\n# ====================================\n\n\n@dataclass\nclass Macro(MacroResource, BaseNode):\n    @classmethod\n    def resource_class(cls) -> Type[MacroResource]:\n        return MacroResource\n\n    def same_contents(self, other: Optional[\"Macro\"]) -> bool:\n        if other is None:\n            return False\n        # the only thing that makes one macro different from another with the\n        # same name/package is its content\n        return self.macro_sql == other.macro_sql\n\n    @property\n    def depends_on_macros(self):\n        return self.depends_on.macros\n\n\n# ====================================\n# Documentation node\n# ====================================\n\n\n@dataclass\nclass Documentation(DocumentationResource, BaseNode):\n    @classmethod\n    def resource_class(cls) -> Type[DocumentationResource]:\n        return DocumentationResource\n\n    @property\n    def search_name(self):\n        return self.name\n\n    def same_contents(self, other: Optional[\"Documentation\"]) -> bool:\n        if other is None:\n            return False\n        # the only thing that makes one doc different from another with the\n        # same name/package is its content\n        return self.block_contents == other.block_contents\n\n\n# ====================================\n# Source node\n# ====================================\n\n\ndef normalize_test(testdef: TestDef) -> Dict[str, Any]:\n    if isinstance(testdef, str):\n        return {testdef: {}}\n    else:\n        return testdef\n\n\n@dataclass\nclass UnpatchedSourceDefinition(BaseNode):\n    source: UnparsedSourceDefinition\n    table: UnparsedSourceTableDefinition\n    fqn: List[str]\n    resource_type: Literal[NodeType.Source]\n    patch_path: Optional[str] = None\n\n    def get_full_source_name(self):\n        return f\"{self.source.name}_{self.table.name}\"\n\n    def get_source_representation(self):\n        return f'source(\"{self.source.name}\", \"{self.table.name}\")'\n\n    def validate_data_tests(self, is_root_project: bool):\n        \"\"\"\n        sources parse tests differently than models, so we need to do some validation\n        here where it's done in the PatchParser for other nodes\n        \"\"\"\n        # source table-level tests\n        if self.tests and self.data_tests:\n            raise ValidationError(\n                \"Invalid test config: cannot have both 'tests' and 'data_tests' defined\"\n            )\n        if self.tests:\n            self.data_tests.extend(self.tests)\n            self.tests.clear()\n\n        # column-level tests\n        for column in self.columns:\n            if column.tests and column.data_tests:\n                raise ValidationError(\n                    \"Invalid test config: cannot have both 'tests' and 'data_tests' defined\"\n                )\n            if column.tests:\n                column.data_tests.extend(column.tests)\n                column.tests.clear()\n\n    @property\n    def quote_columns(self) -> Optional[bool]:\n        result = None\n        if self.source.quoting.column is not None:\n            result = self.source.quoting.column\n        if self.table.quoting.column is not None:\n            result = self.table.quoting.column\n        return result\n\n    @property\n    def columns(self) -> Sequence[UnparsedColumn]:\n        return [] if self.table.columns is None else self.table.columns\n\n    def get_tests(self) -> Iterator[Tuple[Dict[str, Any], Optional[UnparsedColumn]]]:\n        for data_test in self.data_tests:\n            yield normalize_test(data_test), None\n\n        for column in self.columns:\n            if column.data_tests is not None:\n                for data_test in column.data_tests:\n                    yield normalize_test(data_test), column\n\n    @property\n    def data_tests(self) -> List[TestDef]:\n        if self.table.data_tests is None:\n            return []\n        else:\n            return self.table.data_tests\n\n    # deprecated\n    @property\n    def tests(self) -> List[TestDef]:\n        if self.table.tests is None:\n            return []\n        else:\n            return self.table.tests\n\n\n@dataclass\nclass SourceDefinition(\n    NodeInfoMixin,\n    GraphNode,\n    SourceDefinitionResource,\n    HasRelationMetadata,\n):\n    @classmethod\n    def resource_class(cls) -> Type[SourceDefinitionResource]:\n        return SourceDefinitionResource\n\n    def same_database_representation(self, other: \"SourceDefinition\") -> bool:\n\n        # preserve legacy behaviour -- use potentially rendered database\n        if get_flags().state_modified_compare_more_unrendered_values is False:\n            same_database = self.database == other.database\n            same_schema = self.schema == other.schema\n        else:\n            same_database = self.unrendered_database == other.unrendered_database\n            same_schema = self.unrendered_schema == other.unrendered_schema\n\n        return same_database and same_schema and self.identifier == other.identifier and True\n\n    def same_quoting(self, other: \"SourceDefinition\") -> bool:\n        return self.quoting == other.quoting\n\n    def same_freshness(self, other: \"SourceDefinition\") -> bool:\n        return (\n            self.freshness == other.freshness\n            and self.loaded_at_field == other.loaded_at_field\n            and True\n        )\n\n    def same_external(self, other: \"SourceDefinition\") -> bool:\n        return self.external == other.external\n\n    def same_config(self, old: \"SourceDefinition\") -> bool:\n        return self.config.same_contents(\n            self.unrendered_config,\n            old.unrendered_config,\n        )\n\n    def same_contents(self, old: Optional[\"SourceDefinition\"]) -> bool:\n        # existing when it didn't before is a change!\n        if old is None:\n            return True\n\n        # config changes are changes (because the only config is \"enforced\", and\n        # enabling a source is a change!)\n        # changing the database/schema/identifier is a change\n        # messing around with external stuff is a change (uh, right?)\n        # quoting changes are changes\n        # freshness changes are changes, I guess\n        # metadata/tags changes are not \"changes\"\n        # patching/description changes are not \"changes\"\n        return (\n            self.same_database_representation(old)\n            and self.same_fqn(old)\n            and self.same_config(old)\n            and self.same_quoting(old)\n            and self.same_freshness(old)\n            and self.same_external(old)\n            and True\n        )\n\n    def get_full_source_name(self):\n        return f\"{self.source_name}_{self.name}\"\n\n    def get_source_representation(self):\n        return f'source(\"{self.source.name}\", \"{self.table.name}\")'\n\n    @property\n    def is_refable(self):\n        return False\n\n    @property\n    def is_ephemeral(self):\n        return False\n\n    @property\n    def is_ephemeral_model(self):\n        return False\n\n    @property\n    def depends_on_nodes(self):\n        return []\n\n    @property\n    def depends_on(self):\n        return DependsOn(macros=[], nodes=[])\n\n    @property\n    def refs(self):\n        return []\n\n    @property\n    def sources(self):\n        return []\n\n    @property\n    def has_freshness(self) -> bool:\n        return bool(self.freshness)\n\n    @property\n    def search_name(self):\n        return f\"{self.source_name}.{self.name}\"\n\n    @property\n    def group(self):\n        return None\n\n\n# ====================================\n# Exposure node\n# ====================================\n\n\n@dataclass\nclass Exposure(NodeInfoMixin, GraphNode, ExposureResource):\n    @property\n    def depends_on_nodes(self):\n        return self.depends_on.nodes\n\n    @property\n    def search_name(self):\n        return self.name\n\n    @classmethod\n    def resource_class(cls) -> Type[ExposureResource]:\n        return ExposureResource\n\n    def same_depends_on(self, old: \"Exposure\") -> bool:\n        return set(self.depends_on.nodes) == set(old.depends_on.nodes)\n\n    def same_description(self, old: \"Exposure\") -> bool:\n        return self.description == old.description\n\n    def same_label(self, old: \"Exposure\") -> bool:\n        return self.label == old.label\n\n    def same_maturity(self, old: \"Exposure\") -> bool:\n        return self.maturity == old.maturity\n\n    def same_owner(self, old: \"Exposure\") -> bool:\n        return self.owner == old.owner\n\n    def same_exposure_type(self, old: \"Exposure\") -> bool:\n        return self.type == old.type\n\n    def same_url(self, old: \"Exposure\") -> bool:\n        return self.url == old.url\n\n    def same_config(self, old: \"Exposure\") -> bool:\n        return self.config.same_contents(\n            self.unrendered_config,\n            old.unrendered_config,\n        )\n\n    def same_contents(self, old: Optional[\"Exposure\"]) -> bool:\n        # existing when it didn't before is a change!\n        # metadata/tags changes are not \"changes\"\n        if old is None:\n            return True\n\n        return (\n            self.same_fqn(old)\n            and self.same_exposure_type(old)\n            and self.same_owner(old)\n            and self.same_maturity(old)\n            and self.same_url(old)\n            and self.same_description(old)\n            and self.same_label(old)\n            and self.same_depends_on(old)\n            and self.same_config(old)\n            and True\n        )\n\n    @property\n    def group(self):\n        return None\n\n    def __post_serialize__(self, dct: Dict, context: Optional[Dict] = None):\n        dct = super().__post_serialize__(dct, context)\n        if \"_event_status\" in dct:\n            del dct[\"_event_status\"]\n        return dct\n\n\n# ====================================\n# Metric node\n# ====================================\n\n\n@dataclass\nclass Metric(GraphNode, MetricResource):\n    @property\n    def depends_on_nodes(self):\n        return self.depends_on.nodes\n\n    @property\n    def search_name(self):\n        return self.name\n\n    @classmethod\n    def resource_class(cls) -> Type[MetricResource]:\n        return MetricResource\n\n    def same_description(self, old: \"Metric\") -> bool:\n        return self.description == old.description\n\n    def same_label(self, old: \"Metric\") -> bool:\n        return self.label == old.label\n\n    def same_config(self, old: \"Metric\") -> bool:\n        return self.config.same_contents(\n            self.unrendered_config,\n            old.unrendered_config,\n        )\n\n    def same_filter(self, old: \"Metric\") -> bool:\n        return True  # TODO\n\n    def same_metadata(self, old: \"Metric\") -> bool:\n        return True  # TODO\n\n    def same_type(self, old: \"Metric\") -> bool:\n        return self.type == old.type\n\n    def same_type_params(self, old: \"Metric\") -> bool:\n        return True  # TODO\n\n    def same_contents(self, old: Optional[\"Metric\"]) -> bool:\n        # existing when it didn't before is a change!\n        # metadata/tags changes are not \"changes\"\n        if old is None:\n            return True\n\n        return (\n            self.same_filter(old)\n            and self.same_metadata(old)\n            and self.same_type(old)\n            and self.same_type_params(old)\n            and self.same_description(old)\n            and self.same_label(old)\n            and self.same_config(old)\n            and True\n        )\n\n    def add_input_measure(self, input_measure: MetricInputMeasure) -> None:\n        for existing_input_measure in self.type_params.input_measures:\n            if input_measure == existing_input_measure:\n                return\n        self.type_params.input_measures.append(input_measure)\n\n\n# ====================================\n# Group node\n# ====================================\n\n\n@dataclass\nclass Group(GroupResource, BaseNode):\n    @classmethod\n    def resource_class(cls) -> Type[GroupResource]:\n        return GroupResource\n\n    def to_logging_dict(self) -> Dict[str, Union[str, Dict[str, str]]]:\n        return {\n            \"name\": self.name,\n            \"package_name\": self.package_name,\n            \"owner\": {k: str(v) for k, v in self.owner.to_dict(omit_none=True).items()},\n        }\n\n\n# ====================================\n# Function node\n# ====================================\n\n\n@dataclass\nclass FunctionNode(CompiledNode, FunctionResource):\n\n    @classmethod\n    def resource_class(cls) -> Type[FunctionResource]:\n        return FunctionResource\n\n\n# ====================================\n# SemanticModel node\n# ====================================\n\n\n@dataclass\nclass SemanticModel(GraphNode, SemanticModelResource):\n    @property\n    def depends_on_nodes(self):\n        return self.depends_on.nodes\n\n    @property\n    def depends_on_macros(self):\n        return self.depends_on.macros\n\n    @classmethod\n    def resource_class(cls) -> Type[SemanticModelResource]:\n        return SemanticModelResource\n\n    def same_model(self, old: \"SemanticModel\") -> bool:\n        return self.model == old.model\n\n    def same_description(self, old: \"SemanticModel\") -> bool:\n        return self.description == old.description\n\n    def same_defaults(self, old: \"SemanticModel\") -> bool:\n        return self.defaults == old.defaults\n\n    def same_entities(self, old: \"SemanticModel\") -> bool:\n        return self.entities == old.entities\n\n    def same_dimensions(self, old: \"SemanticModel\") -> bool:\n        return self.dimensions == old.dimensions\n\n    def same_measures(self, old: \"SemanticModel\") -> bool:\n        return self.measures == old.measures\n\n    def same_config(self, old: \"SemanticModel\") -> bool:\n        return self.config == old.config\n\n    def same_primary_entity(self, old: \"SemanticModel\") -> bool:\n        return self.primary_entity == old.primary_entity\n\n    def same_group(self, old: \"SemanticModel\") -> bool:\n        return self.group == old.group\n\n    def same_contents(self, old: Optional[\"SemanticModel\"]) -> bool:\n        # existing when it didn't before is a change!\n        # metadata/tags changes are not \"changes\"\n        if old is None:\n            return True\n\n        return (\n            self.same_model(old)\n            and self.same_description(old)\n            and self.same_defaults(old)\n            and self.same_entities(old)\n            and self.same_dimensions(old)\n            and self.same_measures(old)\n            and self.same_config(old)\n            and self.same_primary_entity(old)\n            and self.same_group(old)\n            and True\n        )\n\n\n# ====================================\n# SavedQuery\n# ====================================\n\n\n@dataclass\nclass SavedQuery(NodeInfoMixin, GraphNode, SavedQueryResource):\n    @classmethod\n    def resource_class(cls) -> Type[SavedQueryResource]:\n        return SavedQueryResource\n\n    def same_metrics(self, old: \"SavedQuery\") -> bool:\n        return self.query_params.metrics == old.query_params.metrics\n\n    def same_group_by(self, old: \"SavedQuery\") -> bool:\n        return self.query_params.group_by == old.query_params.group_by\n\n    def same_description(self, old: \"SavedQuery\") -> bool:\n        return self.description == old.description\n\n    def same_where(self, old: \"SavedQuery\") -> bool:\n        return self.query_params.where == old.query_params.where\n\n    def same_label(self, old: \"SavedQuery\") -> bool:\n        return self.label == old.label\n\n    def same_config(self, old: \"SavedQuery\") -> bool:\n        return self.config == old.config\n\n    def same_group(self, old: \"SavedQuery\") -> bool:\n        return self.group == old.group\n\n    def same_exports(self, old: \"SavedQuery\") -> bool:\n        if len(self.exports) != len(old.exports):\n            return False\n\n        # exports should be in the same order, so we zip them for easy iteration\n        for old_export, new_export in zip(old.exports, self.exports):\n            if not (old_export.name == new_export.name):\n                return False\n            keys = [\"export_as\", \"schema\", \"alias\"]\n            for key in keys:\n                if old_export.unrendered_config.get(key) != new_export.unrendered_config.get(key):\n                    return False\n\n        return True\n\n    def same_tags(self, old: \"SavedQuery\") -> bool:\n        return self.tags == old.tags\n\n    def same_contents(self, old: Optional[\"SavedQuery\"]) -> bool:\n        # existing when it didn't before is a change!\n        # metadata/tags changes are not \"changes\"\n        if old is None:\n            return True\n\n        return (\n            self.same_metrics(old)\n            and self.same_group_by(old)\n            and self.same_description(old)\n            and self.same_where(old)\n            and self.same_label(old)\n            and self.same_config(old)\n            and self.same_group(old)\n            and self.same_exports(old)\n            and self.same_tags(old)\n            and True\n        )\n\n    def __post_serialize__(self, dct: Dict, context: Optional[Dict] = None):\n        dct = super().__post_serialize__(dct, context)\n        if \"_event_status\" in dct:\n            del dct[\"_event_status\"]\n        return dct\n\n\n# ====================================\n# Patches\n# ====================================\n\n\n@dataclass\nclass ParsedPatch(HasYamlMetadata):\n    name: str\n    description: str\n    meta: Dict[str, Any]\n    docs: Docs\n    config: Dict[str, Any]\n\n\n# The parsed node update is only the 'patch', not the test. The test became a\n# regular parsed node. Note that description and columns must be present, but\n# may be empty.\n@dataclass\nclass ParsedNodePatch(ParsedPatch):\n    columns: Dict[str, ColumnInfo]\n    access: Optional[str]\n    version: Optional[NodeVersion]\n    latest_version: Optional[NodeVersion]\n    constraints: List[Dict[str, Any]]\n    deprecation_date: Optional[datetime]\n    time_spine: Optional[TimeSpine] = None\n    semantic_model: Union[UnparsedSemanticModelConfig, bool, None] = None\n    metrics: Optional[List[UnparsedMetricV2]] = None\n    derived_semantics: Optional[UnparsedDerivedSemantics] = None\n    agg_time_dimension: Optional[str] = None\n    primary_entity: Optional[str] = None\n    freshness: Optional[ModelFreshness] = None\n\n\n@dataclass\nclass ParsedFunctionPatchRequired:\n    returns: FunctionReturns\n\n\n# TODO: Maybe this shouldn't be a subclass of ParsedNodePatch, but ParsedPatch instead\n# Currently, `functions` have the fields like `columns`, `access`, `version`, and etc,\n# but they don't actually do anything. If we remove those properties from FunctionNode,\n# we can remove this class and use ParsedPatch instead.\n@dataclass\nclass ParsedFunctionPatch(ParsedNodePatch, ParsedFunctionPatchRequired):\n    arguments: List[FunctionArgument] = field(default_factory=list)\n\n\n@dataclass\nclass ParsedMacroPatch(ParsedPatch):\n    arguments: List[MacroArgument] = field(default_factory=list)\n\n\n@dataclass\nclass ParsedSingularTestPatch(ParsedPatch):\n    pass\n\n\n# ====================================\n# Node unions/categories\n# ====================================\n\n\n# ManifestNode without SeedNode, which doesn't have the\n# SQL related attributes\nManifestSQLNode = Union[\n    AnalysisNode,\n    FunctionNode,\n    SingularTestNode,\n    HookNode,\n    ModelNode,\n    SqlNode,\n    GenericTestNode,\n    SnapshotNode,\n    UnitTestNode,\n]\n\n# All SQL nodes plus SeedNode (csv files)\nManifestNode = Union[\n    ManifestSQLNode,\n    SeedNode,\n]\n\nResultNode = Union[\n    ManifestNode,\n    SourceDefinition,\n    HookNode,\n]\n\n# All nodes that can be in the DAG\nGraphMemberNode = Union[\n    ResultNode,\n    Exposure,\n    Metric,\n    SavedQuery,\n    SemanticModel,\n    UnitTestDefinition,\n]\n\n# All \"nodes\" (or node-like objects) in this file\nResource = Union[\n    GraphMemberNode,\n    Documentation,\n    Macro,\n    Group,\n]\n\nTestNode = Union[SingularTestNode, GenericTestNode]\n\nSemanticManifestNode = Union[SavedQuery, SemanticModel, Metric]\n\nRESOURCE_CLASS_TO_NODE_CLASS: Dict[Type[BaseResource], Type[BaseNode]] = {\n    node_class.resource_class(): node_class\n    for node_class in get_args(Resource)\n    if node_class is not UnitTestNode\n}\n"
  },
  {
    "path": "core/dbt/contracts/graph/semantic_manifest.py",
    "content": "from typing import List, Optional, Set\n\nfrom dbt import deprecations\nfrom dbt.constants import (\n    LEGACY_TIME_SPINE_GRANULARITY,\n    LEGACY_TIME_SPINE_MODEL_NAME,\n    MINIMUM_REQUIRED_TIME_SPINE_GRANULARITY,\n)\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.contracts.graph.nodes import ModelNode\nfrom dbt.events.types import ArtifactWritten, SemanticValidationFailure\nfrom dbt.exceptions import ParsingError\nfrom dbt.flags import get_flags\nfrom dbt_common.clients.system import write_file\nfrom dbt_common.events.base_types import EventLevel\nfrom dbt_common.events.functions import fire_event\nfrom dbt_semantic_interfaces.implementations.metric import PydanticMetric\nfrom dbt_semantic_interfaces.implementations.node_relation import PydanticNodeRelation\nfrom dbt_semantic_interfaces.implementations.project_configuration import (\n    PydanticProjectConfiguration,\n)\nfrom dbt_semantic_interfaces.implementations.saved_query import PydanticSavedQuery\nfrom dbt_semantic_interfaces.implementations.semantic_manifest import (\n    PydanticSemanticManifest,\n)\nfrom dbt_semantic_interfaces.implementations.semantic_model import PydanticSemanticModel\nfrom dbt_semantic_interfaces.implementations.time_spine import (\n    PydanticTimeSpine,\n    PydanticTimeSpineCustomGranularityColumn,\n    PydanticTimeSpinePrimaryColumn,\n)\nfrom dbt_semantic_interfaces.implementations.time_spine_table_configuration import (\n    PydanticTimeSpineTableConfiguration as LegacyTimeSpine,\n)\nfrom dbt_semantic_interfaces.type_enums import TimeGranularity\nfrom dbt_semantic_interfaces.validations.semantic_manifest_validator import (\n    SemanticManifestValidator,\n)\nfrom dbt_semantic_interfaces.validations.validator_helpers import (\n    FileContext,\n    ValidationError,\n    ValidationIssueContext,\n)\n\n\nclass SemanticManifest:\n    def __init__(self, manifest: Manifest) -> None:\n        self.manifest = manifest\n\n    def validate(self) -> bool:\n\n        # TODO: Enforce this check.\n        # if self.manifest.metrics and not self.manifest.semantic_models:\n        #    fire_event(\n        #        SemanticValidationFailure(\n        #            msg=\"Metrics require semantic models, but none were found.\"\n        #        ),\n        #        EventLevel.ERROR,\n        #    )\n        #    return False\n\n        if not self.manifest.metrics or not self.manifest.semantic_models:\n            return True\n\n        semantic_manifest = self._get_pydantic_semantic_manifest()\n        validator = SemanticManifestValidator[PydanticSemanticManifest]()\n        validation_results = validator.validate_semantic_manifest(semantic_manifest)\n        validation_result_errors = list(validation_results.errors)\n\n        metrics_using_old_params: Set[str] = set()\n        for metric in semantic_manifest.metrics or []:\n            for field in (\"window\", \"grain_to_date\"):\n                type_params_field_value = getattr(metric.type_params, field)\n                # Warn that the old type_params structure has been deprecated.\n                if type_params_field_value:\n                    metrics_using_old_params.add(metric.name)\n        if metrics_using_old_params:\n            if get_flags().require_nested_cumulative_type_params is False:\n                deprecations.warn(\n                    \"mf-cumulative-type-params-deprecation\",\n                )\n            else:\n                names = \", \".join(metrics_using_old_params)\n                validation_result_errors.append(\n                    ValidationError(\n                        context=ValidationIssueContext(\n                            # We don't have the file context at this point.\n                            file_context=FileContext(),\n                            object_name=names,\n                            object_type=\"metric\",\n                        ),\n                        message=f\"Cumulative fields `type_params.window` and `type_params.grain_to_date` should be nested under `type_params.cumulative_type_params.window` and `type_params.cumulative_type_params.grain_to_date`. Invalid metrics: {names}. See documentation on behavior changes: https://docs.getdbt.com/reference/global-configs/behavior-changes.\",\n                    )\n                )\n\n        time_spines = semantic_manifest.project_configuration.time_spines\n        legacy_time_spines = (\n            semantic_manifest.project_configuration.time_spine_table_configurations\n        )\n        # If the time spine contains a day grain then it is functionally equivalent to the legacy time spine.\n        time_spines_contain_day = any(\n            c for c in time_spines if c.primary_column.time_granularity == TimeGranularity.DAY\n        )\n        if (\n            get_flags().require_yaml_configuration_for_mf_time_spines is False\n            and legacy_time_spines\n            and not time_spines_contain_day\n        ):\n            deprecations.warn(\n                \"mf-timespine-without-yaml-configuration\",\n            )\n\n        for warning in validation_results.warnings:\n            fire_event(SemanticValidationFailure(msg=warning.message))\n\n        for deprecation in validation_results.future_errors:\n            if (\n                \"time dimension\" in deprecation.message\n                and \"must have a time granularity set\" in deprecation.message\n            ):\n                deprecations.warn(\n                    \"time-dimensions-require-granularity-deprecation\", deprecation.message\n                )\n            else:\n                # We have three options for this case:\n                # 1. Swallow it (don't send any event)\n                # 2. Raise a generic deprecation\n                # 3. Raise an error about an unknown SL future error\n                #\n                # (1) is the easiest, but useless to the user and also to us for debugging.\n                # (3) is not safe because if a new deprecation is added in a DSI patch, then\n                # suddenly dbt core would be broken.\n                # This leaves (2) only remaining option, which is what we do.\n                deprecations.warn(\"generic-semantic-layer-deprecation\", deprecation.message)\n\n        for error in validation_result_errors:\n            fire_event(SemanticValidationFailure(msg=error.message), EventLevel.ERROR)\n\n        return not validation_result_errors\n\n    def write_json_to_file(self, file_path: str):\n        semantic_manifest = self._get_pydantic_semantic_manifest()\n        json = semantic_manifest.json()\n        write_file(file_path, json)\n        fire_event(ArtifactWritten(artifact_type=self.__class__.__name__, artifact_path=file_path))\n\n    def _get_pydantic_semantic_manifest(self) -> PydanticSemanticManifest:\n        pydantic_time_spines: List[PydanticTimeSpine] = []\n        minimum_time_spine_granularity: Optional[TimeGranularity] = None\n        for node in self.manifest.nodes.values():\n            if not (isinstance(node, ModelNode) and node.time_spine):\n                continue\n            time_spine = node.time_spine\n            standard_granularity_column = None\n            for column in node.columns.values():\n                if column.name == time_spine.standard_granularity_column:\n                    standard_granularity_column = column\n                    break\n            # Assertions needed for type checking\n            if not standard_granularity_column:\n                raise ParsingError(\n                    \"Expected to find time spine standard granularity column in model columns, but did not. \"\n                    \"This should have been caught in YAML parsing.\"\n                )\n            if not standard_granularity_column.granularity:\n                raise ParsingError(\n                    \"Expected to find granularity set for time spine standard granularity column, but did not. \"\n                    \"This should have been caught in YAML parsing.\"\n                )\n            pydantic_time_spine = PydanticTimeSpine(\n                node_relation=PydanticNodeRelation(\n                    alias=node.alias,\n                    schema_name=node.schema,\n                    database=node.database,\n                    relation_name=node.relation_name,\n                ),\n                primary_column=PydanticTimeSpinePrimaryColumn(\n                    name=time_spine.standard_granularity_column,\n                    time_granularity=standard_granularity_column.granularity,\n                ),\n                custom_granularities=[\n                    PydanticTimeSpineCustomGranularityColumn(\n                        name=custom_granularity.name, column_name=custom_granularity.column_name\n                    )\n                    for custom_granularity in time_spine.custom_granularities\n                ],\n            )\n            pydantic_time_spines.append(pydantic_time_spine)\n            if (\n                not minimum_time_spine_granularity\n                or standard_granularity_column.granularity.to_int()\n                < minimum_time_spine_granularity.to_int()\n            ):\n                minimum_time_spine_granularity = standard_granularity_column.granularity\n\n        project_config = PydanticProjectConfiguration(\n            time_spine_table_configurations=[], time_spines=pydantic_time_spines\n        )\n        pydantic_semantic_manifest = PydanticSemanticManifest(\n            metrics=[], semantic_models=[], project_configuration=project_config\n        )\n\n        for semantic_model in self.manifest.semantic_models.values():\n            pydantic_semantic_manifest.semantic_models.append(\n                PydanticSemanticModel.parse_obj(semantic_model.to_dict())\n            )\n\n        for metric in self.manifest.metrics.values():\n            pydantic_semantic_manifest.metrics.append(PydanticMetric.parse_obj(metric.to_dict()))\n\n        for saved_query in self.manifest.saved_queries.values():\n            pydantic_semantic_manifest.saved_queries.append(\n                PydanticSavedQuery.parse_obj(saved_query.to_dict())\n            )\n\n        legacy_time_spine_model: Optional[ModelNode] = None\n        if self.manifest.semantic_models:\n            legacy_time_spine_model = self.manifest.ref_lookup.find(\n                LEGACY_TIME_SPINE_MODEL_NAME, None, None, self.manifest\n            )\n            if legacy_time_spine_model:\n                if (\n                    not minimum_time_spine_granularity\n                    or LEGACY_TIME_SPINE_GRANULARITY.to_int()\n                    < minimum_time_spine_granularity.to_int()\n                ):\n                    minimum_time_spine_granularity = LEGACY_TIME_SPINE_GRANULARITY\n\n            # If no time spines have been configured at DAY or smaller AND legacy time spine model does not exist, error.\n            if (\n                not minimum_time_spine_granularity\n                or minimum_time_spine_granularity.to_int()\n                > MINIMUM_REQUIRED_TIME_SPINE_GRANULARITY.to_int()\n            ):\n                raise ParsingError(\n                    \"The semantic layer requires a time spine model with granularity DAY or smaller in the project, \"\n                    \"but none was found. Guidance on creating this model can be found on our docs site \"\n                    \"(https://docs.getdbt.com/docs/build/metricflow-time-spine).\"\n                )\n\n            # For backward compatibility: if legacy time spine exists without config, include it in the manifest.\n            if legacy_time_spine_model and legacy_time_spine_model.time_spine is None:\n                legacy_time_spine = LegacyTimeSpine(\n                    location=legacy_time_spine_model.relation_name,\n                    column_name=\"date_day\",\n                    grain=LEGACY_TIME_SPINE_GRANULARITY,\n                )\n                pydantic_semantic_manifest.project_configuration.time_spine_table_configurations = [\n                    legacy_time_spine\n                ]\n\n        return pydantic_semantic_manifest\n"
  },
  {
    "path": "core/dbt/contracts/graph/unparsed.py",
    "content": "import datetime\nimport re\nfrom dataclasses import dataclass, field\nfrom enum import Enum\nfrom pathlib import Path\nfrom typing import Any, Dict, List, Literal, Optional, Sequence, Union\n\nfrom typing_extensions import override\n\n# trigger the PathEncoder\nimport dbt_common.helper_types  # noqa:F401\nfrom dbt import deprecations\nfrom dbt.artifacts.resources import (\n    ConstantPropertyInput,\n    Defaults,\n    DimensionValidityParams,\n    Docs,\n    ExposureType,\n    ExternalTable,\n    FreshnessThreshold,\n    FunctionArgument,\n    FunctionReturns,\n    MacroArgument,\n    MaturityType,\n    MeasureAggregationParameters,\n    NodeVersion,\n    Owner,\n    Quoting,\n    TimeSpine,\n    UnitTestInputFixture,\n    UnitTestNodeVersions,\n    UnitTestOutputFixture,\n    UnitTestOverrides,\n    list_str,\n    metas,\n)\nfrom dbt.exceptions import ParsingError\nfrom dbt.node_types import NodeType\nfrom dbt_common.contracts.config.base import CompareBehavior, MergeBehavior\nfrom dbt_common.contracts.config.metadata import ShowBehavior\nfrom dbt_common.contracts.config.properties import AdditionalPropertiesMixin\nfrom dbt_common.contracts.util import Mergeable\nfrom dbt_common.dataclass_schema import (\n    ExtensibleDbtClassMixin,\n    StrEnum,\n    ValidationError,\n    dbtClassMixin,\n)\nfrom dbt_common.exceptions import DbtInternalError\nfrom dbt_semantic_interfaces.type_enums import (\n    ConversionCalculationType,\n    DimensionType,\n    PeriodAggregation,\n)\n\n\n@dataclass\nclass UnparsedBaseNode(dbtClassMixin):\n    package_name: str\n    path: str\n    original_file_path: str\n\n    @property\n    def file_id(self):\n        return f\"{self.package_name}://{self.original_file_path}\"\n\n\n@dataclass\nclass HasCode(dbtClassMixin):\n    raw_code: str\n    language: str\n\n    @property\n    def empty(self):\n        return not self.raw_code.strip()\n\n\n@dataclass\nclass UnparsedMacro(UnparsedBaseNode, HasCode):\n    resource_type: Literal[NodeType.Macro]\n\n\n@dataclass\nclass UnparsedGenericTest(UnparsedBaseNode, HasCode):\n    resource_type: Literal[NodeType.Macro]\n\n\n@dataclass\nclass UnparsedNode(UnparsedBaseNode, HasCode):\n    name: str\n    resource_type: NodeType\n\n    @property\n    def search_name(self):\n        return self.name\n\n\n@dataclass\nclass UnparsedRunHook(UnparsedNode):\n    resource_type: Literal[NodeType.Operation]\n    index: Optional[int] = None\n\n\n@dataclass\nclass HasColumnProps(AdditionalPropertiesMixin, ExtensibleDbtClassMixin):\n    name: str\n    description: str = \"\"\n    meta: Dict[str, Any] = field(default_factory=dict)\n    data_type: Optional[str] = None\n    constraints: List[Dict[str, Any]] = field(default_factory=list)\n    docs: Docs = field(default_factory=Docs)\n    config: Dict[str, Any] = field(default_factory=dict)\n    _extra: Dict[str, Any] = field(default_factory=dict)\n\n\nTestDef = Union[Dict[str, Any], str]\n\n\n@dataclass\nclass HasColumnAndTestProps(HasColumnProps):\n    data_tests: List[TestDef] = field(default_factory=list)\n    tests: List[TestDef] = field(\n        default_factory=list\n    )  # back compat for previous name of 'data_tests'\n\n\n@dataclass\nclass HasColumnDocs(dbtClassMixin):\n    columns: Sequence[HasColumnProps] = field(default_factory=list)\n\n\n@dataclass\nclass HasYamlMetadata(dbtClassMixin):\n    original_file_path: str\n    yaml_key: str\n    package_name: str\n\n    @property\n    def file_id(self):\n        return f\"{self.package_name}://{self.original_file_path}\"\n\n\n@dataclass\nclass HasConfig:\n    config: Dict[str, Any] = field(default_factory=dict)\n\n\n@dataclass\nclass UnparsedDimensionBase(dbtClassMixin):\n    # Should we be limiting name length or otherwise validating this?\n    type: str  # actually a DimensionType enum value\n    name: Optional[str] = None\n    description: Optional[str] = None\n    label: Optional[str] = None\n    is_partition: bool = False\n    config: Dict[str, Any] = field(default_factory=dict)\n\n\n@dataclass\nclass UnparsedDimensionTypeParams(dbtClassMixin):\n    \"\"\"Used for dbt Semantic Layer dimensions (v1 YAML).\"\"\"\n\n    time_granularity: str  # TimeGranularity enum\n    validity_params: Optional[DimensionValidityParams] = None\n\n\n@dataclass(kw_only=True)\nclass UnparsedDimension(UnparsedDimensionBase):\n    \"\"\"Used for dbt Semantic Layer dimensions (v1 YAML).\"\"\"\n\n    name: str\n    type_params: Optional[UnparsedDimensionTypeParams] = None\n    expr: Optional[str] = None\n\n\n@dataclass\nclass UnparsedDimensionV2(UnparsedDimensionBase):\n    \"\"\"Used for dbt Semantic Layer dimensions (v2 YAML).\"\"\"\n\n    validity_params: Optional[DimensionValidityParams] = None\n\n\n@dataclass(kw_only=True)\nclass UnparsedDerivedDimensionV2(UnparsedDimensionV2):\n    \"\"\"Used for dbt Semantic Layer derived dimensions (v2 YAML).\"\"\"\n\n    name: str\n    expr: str\n    granularity: Optional[str] = None  # str is really a TimeGranularity Enum\n\n    @classmethod\n    @override\n    def validate(cls, data):\n        super().validate(data)\n        # validity_params may only be set when the derived dimension has a granularity\n        if data.get(\"validity_params\") is not None and not data.get(\"granularity\"):\n            dim_name = data.get(\"name\")\n            raise ValidationError(\n                f\"Derived dimension {dim_name} has validity_params, \"\n                \"so it must specify a granularity.\"\n            )\n\n\n@dataclass\nclass UnparsedEntityBase(dbtClassMixin):\n    name: str\n    type: str  # EntityType enum\n    description: Optional[str] = None\n    label: Optional[str] = None\n    config: Dict[str, Any] = field(default_factory=dict)\n\n\n@dataclass\nclass UnparsedEntity(UnparsedEntityBase):\n    \"\"\"Used for dbt Semantic Layer entities (v1 YAML only).\"\"\"\n\n    role: Optional[str] = None\n    expr: Optional[str] = None\n\n\n@dataclass\nclass UnparsedColumnEntityV2(UnparsedEntityBase):\n    \"\"\"Used for dbt Semantic Layer column entities (v2 YAML).\"\"\"\n\n    pass\n\n\n# kw_only allows this child to define required fields\n@dataclass(kw_only=True)\nclass UnparsedDerivedEntityV2(UnparsedEntityBase):\n    \"\"\"Used for dbt Semantic Layer derived entities (v2 YAML).\"\"\"\n\n    expr: str\n\n\n@dataclass\nclass UnparsedColumn(HasConfig, HasColumnAndTestProps):\n    quote: Optional[bool] = None\n    tags: List[str] = field(default_factory=list)\n    granularity: Optional[str] = None  # str is really a TimeGranularity Enum\n    # Note 1: Dimension str is a DimensionType enum value\n    # Note 2: Don't ask me why, but str must come after UnparsedDimensionV2 here or else\n    # this will be read as a dict object instead of a UnparsedDimensionV2 object\n    # Only used in v2 semantic layer.\n    dimension: Union[UnparsedDimensionV2, str, None] = None\n    # UnparsedColumnEntityV2 must come before str to parse correctly.  str is assumed to be EntityType enum value\n    # Only used in v2 semantic layer.\n    entity: Union[UnparsedColumnEntityV2, str, None] = None\n\n    @classmethod\n    @override\n    def validate(cls, data):\n        super().validate(data)\n        if (dimension := data.get(\"dimension\")) is not None:\n            if isinstance(dimension, dict):\n                dim_type_str = dimension.get(\"type\")\n                dim_name = dimension.get(\"name\")\n            else:\n                dim_type_str = dimension\n                dim_name = data.get(\"name\")\n            dim_type = DimensionType(dim_type_str) if dim_type_str is not None else None\n            if dim_type is DimensionType.TIME and not data.get(\"granularity\"):\n                raise ValidationError(\n                    f\"Dimension {dim_name} is a time dimension attached to \"\n                    f\"column {data.get('name')}, \"\n                    \"so that column must specify a granularity.\"\n                )\n            # validity_params may only be set when the column has a granularity\n            if (\n                isinstance(dimension, dict)\n                and dimension.get(\"validity_params\") is not None\n                and not data.get(\"granularity\")\n            ):\n                dim_name = dimension.get(\"name\") or data.get(\"name\")\n                raise ValidationError(\n                    f\"Dimension {dim_name} has validity_params attached to \"\n                    f\"column {data.get('name')}, \"\n                    \"so that column must specify a granularity.\"\n                )\n\n\n@dataclass\nclass HasColumnTests(dbtClassMixin):\n    columns: Sequence[UnparsedColumn] = field(default_factory=list)\n\n\n@dataclass\nclass MetricFilter(dbtClassMixin):\n    field: str\n    operator: str\n    # TODO : Can we make this Any?\n    value: str\n\n\nclass MetricTimePeriod(StrEnum):\n    day = \"day\"\n    week = \"week\"\n    month = \"month\"\n    year = \"year\"\n\n    def plural(self) -> str:\n        return str(self) + \"s\"\n\n\n@dataclass\nclass MetricTime(dbtClassMixin, Mergeable):\n    count: Optional[int] = None\n    period: Optional[MetricTimePeriod] = None\n\n    def __bool__(self):\n        return self.count is not None and self.period is not None\n\n\n@dataclass\nclass UnparsedMetricInputMeasure(dbtClassMixin):\n    name: str\n    # Note: `Union` must be the outermost part of the type annotation for serialization to work properly.\n    filter: Union[str, List[str], None] = None\n    alias: Optional[str] = None\n    join_to_timespine: bool = False\n    fill_nulls_with: Optional[int] = None\n\n\n@dataclass\nclass UnparsedMetricInput(dbtClassMixin):\n    name: str\n    # Note: `Union` must be the outermost part of the type annotation for serialization to work properly.\n    filter: Union[str, List[str], None] = None\n    alias: Optional[str] = None\n    offset_window: Optional[str] = None\n    offset_to_grain: Optional[str] = None\n\n\n@dataclass\nclass UnparsedConversionTypeParams(dbtClassMixin):\n    \"\"\"Only used in v1 Semantic YAML\"\"\"\n\n    base_measure: Union[UnparsedMetricInputMeasure, str]\n    conversion_measure: Union[UnparsedMetricInputMeasure, str]\n    entity: str\n    calculation: str = (\n        ConversionCalculationType.CONVERSION_RATE.value\n    )  # ConversionCalculationType Enum\n    window: Optional[str] = None\n    constant_properties: Optional[List[ConstantPropertyInput]] = None\n\n\n@dataclass\nclass UnparsedCumulativeTypeParams(dbtClassMixin):\n    \"\"\"Only used in v1 Semantic YAML\"\"\"\n\n    window: Optional[str] = None\n    grain_to_date: Optional[str] = None\n    period_agg: str = PeriodAggregation.FIRST.value\n\n\n@dataclass\nclass UnparsedMetricTypeParams(dbtClassMixin):\n    \"\"\"Used on v1 Semantic Metric YAML.\"\"\"\n\n    measure: Optional[Union[UnparsedMetricInputMeasure, str]] = None\n    numerator: Optional[Union[UnparsedMetricInput, str]] = None\n    denominator: Optional[Union[UnparsedMetricInput, str]] = None\n    expr: Optional[Union[str, bool]] = None\n    window: Optional[str] = None\n    grain_to_date: Optional[str] = None  # str is really a TimeGranularity Enum\n    metrics: Optional[List[Union[UnparsedMetricInput, str]]] = None\n    conversion_type_params: Optional[UnparsedConversionTypeParams] = None\n    cumulative_type_params: Optional[UnparsedCumulativeTypeParams] = None\n\n\n@dataclass(kw_only=True)\nclass UnparsedMetricBase(dbtClassMixin):\n\n    name: str\n    type: str = \"simple\"\n    label: Optional[str] = None  # in v1 this is required, but in v2 it is optional\n    description: str = \"\"\n    # Note: `Union` must be the outermost part of the type annotation for serialization to work properly.\n    filter: Union[str, List[str], None] = None\n    time_granularity: Optional[str] = None\n\n    config: Dict[str, Any] = field(default_factory=dict)\n\n    @classmethod\n    def validate(cls, data):\n        super().validate(data)\n        if \"name\" in data:\n            errors = []\n            if \" \" in data[\"name\"]:\n                errors.append(\"cannot contain spaces\")\n            # This handles failing queries due to too long metric names.\n            # It only occurs in BigQuery and Snowflake (Postgres/Redshift truncate)\n            if len(data[\"name\"]) > 250:\n                errors.append(\"cannot contain more than 250 characters\")\n            if not (re.match(r\"^[A-Za-z]\", data[\"name\"])):\n                errors.append(\"must begin with a letter\")\n            if not (re.match(r\"[\\w]+$\", data[\"name\"])):\n                errors.append(\"must contain only letters, numbers and underscores\")\n\n            if errors:\n                raise ValidationError(\n                    f\"The metric name '{data['name']}' is invalid.  It {', '.join(e for e in errors)}\"\n                )\n\n\n@dataclass(kw_only=True)\nclass UnparsedMetric(UnparsedMetricBase):\n    \"\"\"Old-style YAML metric; prefer UnparsedMetricV2 instead as of late 2025.\"\"\"\n\n    label: str\n\n    type_params: UnparsedMetricTypeParams  # old-style YAML\n    # metadata: Optional[Unparsedetadata] = None # TODO\n    meta: Dict[str, Any] = field(default_factory=dict)\n    tags: List[str] = field(default_factory=list)\n\n\n@dataclass\nclass UnparsedNonAdditiveDimensionV2(dbtClassMixin):\n    name: str\n    window_agg: str  # AggregationType enum\n    group_by: List[str] = field(default_factory=list)\n\n\n@dataclass\nclass UnparsedMetricV2(UnparsedMetricBase):\n    hidden: bool = False\n    agg: Optional[str] = None\n\n    percentile: Optional[float] = None\n    percentile_type: Optional[str] = None\n\n    join_to_timespine: Optional[bool] = None\n    fill_nulls_with: Optional[int] = None\n    expr: Optional[Union[str, int]] = None\n\n    non_additive_dimension: Optional[UnparsedNonAdditiveDimensionV2] = None\n    agg_time_dimension: Optional[str] = None\n\n    # For cumulative metrics\n    window: Optional[str] = None\n    grain_to_date: Optional[str] = None\n    period_agg: str = PeriodAggregation.FIRST.value\n    input_metric: Optional[Union[UnparsedMetricInput, str]] = None\n\n    # For ratio metrics\n    numerator: Optional[Union[UnparsedMetricInput, str]] = None\n    denominator: Optional[Union[UnparsedMetricInput, str]] = None\n\n    # For derived metrics\n    input_metrics: Optional[List[Union[UnparsedMetricInput, str]]] = None\n\n    # For conversion metrics\n    entity: Optional[str] = None\n    calculation: Optional[str] = None\n    base_metric: Optional[Union[UnparsedMetricInput, str]] = None\n    conversion_metric: Optional[Union[UnparsedMetricInput, str]] = None\n    constant_properties: Optional[List[ConstantPropertyInput]] = None\n\n    @classmethod\n    @override\n    def validate(cls, data):\n        super().validate(data)\n        if data[\"type\"] == \"simple\" and data.get(\"agg\") is None:\n            raise ValidationError(\"Simple metrics must have an agg param.\")\n\n\n@dataclass\nclass UnparsedVersion(dbtClassMixin):\n    v: NodeVersion\n    defined_in: Optional[str] = None\n    description: str = \"\"\n    access: Optional[str] = None\n    config: Dict[str, Any] = field(default_factory=dict)\n    constraints: List[Dict[str, Any]] = field(default_factory=list)\n    docs: Docs = field(default_factory=Docs)\n    data_tests: Optional[List[TestDef]] = None\n    tests: Optional[List[TestDef]] = None  # back compat for previous name of 'data_tests'\n    columns: Sequence[Union[dbt_common.helper_types.IncludeExclude, UnparsedColumn]] = field(\n        default_factory=list\n    )\n    deprecation_date: Optional[datetime.datetime] = None\n\n    def __lt__(self, other):\n        try:\n            return float(self.v) < float(other.v)\n        except ValueError:\n            return str(self.v) < str(other.v)\n\n    @property\n    def include_exclude(self) -> dbt_common.helper_types.IncludeExclude:\n        return self._include_exclude\n\n    @property\n    def unparsed_columns(self) -> List:\n        return self._unparsed_columns\n\n    @property\n    def formatted_v(self) -> str:\n        return f\"v{self.v}\"\n\n    def __post_init__(self):\n        has_include_exclude = False\n        self._include_exclude = dbt_common.helper_types.IncludeExclude(include=\"*\")\n        self._unparsed_columns = []\n        for column in self.columns:\n            if isinstance(column, dbt_common.helper_types.IncludeExclude):\n                if not has_include_exclude:\n                    self._include_exclude = column\n                    has_include_exclude = True\n                else:\n                    raise ParsingError(\"version can have at most one include/exclude element\")\n            else:\n                self._unparsed_columns.append(column)\n\n        self.deprecation_date = normalize_date(self.deprecation_date)\n\n\n@dataclass\nclass UnparsedAnalysisUpdate(HasConfig, HasColumnDocs, HasColumnProps, HasYamlMetadata):\n    access: Optional[str] = None\n\n\n@dataclass\nclass UnparsedSingularTestUpdate(HasConfig, HasColumnProps, HasYamlMetadata):\n    pass\n\n\n@dataclass\nclass UnparsedNodeUpdate(HasConfig, HasColumnTests, HasColumnAndTestProps, HasYamlMetadata):\n    quote_columns: Optional[bool] = None\n    access: Optional[str] = None\n\n\n@dataclass\nclass UnparsedDerivedSemantics(dbtClassMixin):\n    entities: List[UnparsedDerivedEntityV2] = field(default_factory=list)\n    dimensions: List[UnparsedDerivedDimensionV2] = field(default_factory=list)\n\n\n@dataclass\nclass UnparsedSemanticResourceConfig(dbtClassMixin):\n    meta: Dict[str, Any] = field(default_factory=dict)\n\n\n@dataclass(kw_only=True)\nclass UnparsedSemanticModelConfig(dbtClassMixin):\n    name: Optional[str] = None\n    enabled: bool = True\n    group: Optional[str] = None\n    config: Optional[UnparsedSemanticResourceConfig] = None\n\n\n@dataclass\nclass UnparsedModelUpdate(UnparsedNodeUpdate):\n    quote_columns: Optional[bool] = None\n    access: Optional[str] = None\n    latest_version: Optional[NodeVersion] = None\n    versions: Sequence[UnparsedVersion] = field(default_factory=list)\n    deprecation_date: Optional[datetime.datetime] = None\n    time_spine: Optional[TimeSpine] = None\n    # True indicates that the semantic model is enabeld and will have it's values populated\n    # directly from the model.\n    # Using an UnparsedSemanticModelConfig object allows user to override some of the\n    # values instead.\n    semantic_model: Union[UnparsedSemanticModelConfig, bool, None] = None\n    primary_entity: Optional[str] = None\n    agg_time_dimension: Optional[str] = None\n    metrics: Optional[List[UnparsedMetricV2]] = None\n    derived_semantics: Optional[UnparsedDerivedSemantics] = None\n\n    def __post_init__(self) -> None:\n        if self.latest_version:\n            version_values = [version.v for version in self.versions]\n            if self.latest_version not in version_values:\n                raise ParsingError(\n                    f\"latest_version: {self.latest_version} is not one of model '{self.name}' versions: {version_values} \"\n                )\n\n        seen_versions = set()\n        for version in self.versions:\n            if str(version.v) in seen_versions:\n                raise ParsingError(\n                    f\"Found duplicate version: '{version.v}' in versions list of model '{self.name}'\"\n                )\n            seen_versions.add(str(version.v))\n\n        self._version_map = {version.v: version for version in self.versions}\n\n        self.deprecation_date = normalize_date(self.deprecation_date)\n\n        if self.time_spine:\n            columns = (\n                self.get_columns_for_version(self.latest_version)\n                if self.latest_version\n                else self.columns\n            )\n            column_names_to_columns = {column.name: column for column in columns}\n            if self.time_spine.standard_granularity_column not in column_names_to_columns:\n                raise ParsingError(\n                    f\"Time spine standard granularity column must be defined on the model. Got invalid \"\n                    f\"column name '{self.time_spine.standard_granularity_column}' for model '{self.name}'. Valid names\"\n                    f\"{' for latest version' if self.latest_version else ''}: {list(column_names_to_columns.keys())}.\"\n                )\n            standard_column = column_names_to_columns[self.time_spine.standard_granularity_column]\n            if not standard_column.granularity:\n                raise ParsingError(\n                    f\"Time spine standard granularity column must have a granularity defined. Please add one for \"\n                    f\"column '{self.time_spine.standard_granularity_column}' in model '{self.name}'.\"\n                )\n            custom_granularity_columns_not_found = []\n            for custom_granularity in self.time_spine.custom_granularities:\n                column_name = (\n                    custom_granularity.column_name\n                    if custom_granularity.column_name\n                    else custom_granularity.name\n                )\n                if column_name not in column_names_to_columns:\n                    custom_granularity_columns_not_found.append(column_name)\n            if custom_granularity_columns_not_found:\n                raise ParsingError(\n                    \"Time spine custom granularity columns do not exist in the model. \"\n                    f\"Columns not found: {custom_granularity_columns_not_found}; \"\n                    f\"Available columns: {list(column_names_to_columns.keys())}\"\n                )\n\n    def get_columns_for_version(self, version: NodeVersion) -> List[UnparsedColumn]:\n        if version not in self._version_map:\n            raise DbtInternalError(\n                f\"get_columns_for_version called for version '{version}' not in version map\"\n            )\n\n        version_columns = []\n        unparsed_version = self._version_map[version]\n        for base_column in self.columns:\n            if unparsed_version.include_exclude.includes(base_column.name):\n                version_columns.append(base_column)\n\n        for column in unparsed_version.unparsed_columns:\n            version_columns.append(column)\n\n        return version_columns\n\n    def get_tests_for_version(self, version: NodeVersion) -> List[TestDef]:\n        if version not in self._version_map:\n            raise DbtInternalError(\n                f\"get_tests_for_version called for version '{version}' not in version map\"\n            )\n        unparsed_version = self._version_map[version]\n        return (\n            unparsed_version.data_tests\n            if unparsed_version.data_tests is not None\n            else self.data_tests\n        )\n\n\n@dataclass\nclass UnparsedMacroUpdate(HasConfig, HasColumnProps, HasYamlMetadata):\n    arguments: List[MacroArgument] = field(default_factory=list)\n\n\n@dataclass\nclass UnparsedSourceTableDefinition(HasColumnTests, HasColumnAndTestProps):\n    config: Dict[str, Any] = field(default_factory=dict)\n    loaded_at_field: Optional[str] = None\n    loaded_at_field_present: Optional[bool] = None\n    loaded_at_query: Optional[str] = None\n    identifier: Optional[str] = None\n    quoting: Quoting = field(default_factory=Quoting)\n    freshness: Optional[FreshnessThreshold] = field(default_factory=FreshnessThreshold)\n    external: Optional[ExternalTable] = None\n    tags: List[str] = field(default_factory=list)\n\n    def __post_serialize__(self, dct: Dict, context: Optional[Dict] = None):\n        dct = super().__post_serialize__(dct, context)\n        if \"freshness\" not in dct and self.freshness is None:\n            dct[\"freshness\"] = None\n        return dct\n\n\n@dataclass\nclass UnparsedSourceDefinition(dbtClassMixin):\n    name: str\n    description: str = \"\"\n    meta: Dict[str, Any] = field(default_factory=dict)\n    database: Optional[str] = None\n    schema: Optional[str] = None\n    loader: str = \"\"\n    quoting: Quoting = field(default_factory=Quoting)\n    freshness: Optional[FreshnessThreshold] = field(default_factory=FreshnessThreshold)\n    loaded_at_field: Optional[str] = None\n    loaded_at_field_present: Optional[bool] = None\n    loaded_at_query: Optional[str] = None\n    tables: List[UnparsedSourceTableDefinition] = field(default_factory=list)\n    tags: List[str] = field(default_factory=list)\n    config: Dict[str, Any] = field(default_factory=dict)\n    unrendered_database: Optional[str] = None\n    unrendered_schema: Optional[str] = None\n\n    @classmethod\n    def validate(cls, data):\n        super(UnparsedSourceDefinition, cls).validate(data)\n\n        if data.get(\"loaded_at_field\", None) == \"\":\n            raise ValidationError(\"loaded_at_field cannot be an empty string.\")\n        if \"tables\" in data:\n            for table in data[\"tables\"]:\n                if table.get(\"loaded_at_field\", None) == \"\":\n                    raise ValidationError(\"loaded_at_field cannot be an empty string.\")\n\n    @property\n    def yaml_key(self) -> \"str\":\n        return \"sources\"\n\n    def __post_serialize__(self, dct: Dict, context: Optional[Dict] = None):\n        dct = super().__post_serialize__(dct, context)\n        if \"freshness\" not in dct and self.freshness is None:\n            dct[\"freshness\"] = None\n        return dct\n\n\n@dataclass\nclass SourceTablePatch(dbtClassMixin):\n    name: str\n    description: Optional[str] = None\n    meta: Optional[Dict[str, Any]] = None\n    data_type: Optional[str] = None\n    docs: Optional[Docs] = None\n    loaded_at_field: Optional[str] = None\n    loaded_at_field_present: Optional[bool] = None\n    loaded_at_query: Optional[str] = None\n    identifier: Optional[str] = None\n    quoting: Quoting = field(default_factory=Quoting)\n    freshness: Optional[FreshnessThreshold] = field(default_factory=FreshnessThreshold)\n    external: Optional[ExternalTable] = None\n    tags: Optional[List[str]] = None\n    data_tests: Optional[List[TestDef]] = None\n    tests: Optional[List[TestDef]] = None  # back compat for previous name of 'data_tests'\n    columns: Optional[Sequence[UnparsedColumn]] = None\n\n    def to_patch_dict(self) -> Dict[str, Any]:\n        dct = self.to_dict(omit_none=True)\n        remove_keys = \"name\"\n        for key in remove_keys:\n            if key in dct:\n                del dct[key]\n\n        if self.freshness is None:\n            dct[\"freshness\"] = None\n\n        return dct\n\n\n@dataclass\nclass SourcePatch(dbtClassMixin):\n    name: str = field(\n        metadata=dict(description=\"The name of the source to override\"),\n    )\n    overrides: str = field(\n        metadata=dict(description=\"The package of the source to override\"),\n    )\n    path: Path = field(\n        metadata=dict(description=\"The path to the patch-defining yml file\"),\n    )\n    config: Dict[str, Any] = field(default_factory=dict)\n    description: Optional[str] = None\n    meta: Optional[Dict[str, Any]] = None\n    database: Optional[str] = None\n    schema: Optional[str] = None\n    loader: Optional[str] = None\n    quoting: Optional[Quoting] = None\n    freshness: Optional[Optional[FreshnessThreshold]] = field(default_factory=FreshnessThreshold)\n    loaded_at_field: Optional[str] = None\n    loaded_at_field_present: Optional[bool] = None\n    loaded_at_query: Optional[str] = None\n    tables: Optional[List[SourceTablePatch]] = None\n    tags: Optional[List[str]] = None\n\n    def to_patch_dict(self) -> Dict[str, Any]:\n        dct = self.to_dict(omit_none=True)\n        remove_keys = (\"name\", \"overrides\", \"tables\", \"path\")\n        for key in remove_keys:\n            if key in dct:\n                del dct[key]\n\n        if self.freshness is None:\n            dct[\"freshness\"] = None\n\n        return dct\n\n    def get_table_named(self, name: str) -> Optional[SourceTablePatch]:\n        if self.tables is not None:\n            for table in self.tables:\n                if table.name == name:\n                    return table\n        return None\n\n\n@dataclass\nclass UnparsedDocumentation(dbtClassMixin):\n    package_name: str\n    path: str\n    original_file_path: str\n\n    @property\n    def file_id(self):\n        return f\"{self.package_name}://{self.original_file_path}\"\n\n    @property\n    def resource_type(self):\n        return NodeType.Documentation\n\n\n@dataclass\nclass UnparsedDocumentationFile(UnparsedDocumentation):\n    file_contents: str\n\n\n# can't use total_ordering decorator here, as str provides an ordering already\n# and it's not the one we want.\nclass Maturity(StrEnum):\n    low = \"low\"\n    medium = \"medium\"\n    high = \"high\"\n\n    def __lt__(self, other):\n        if not isinstance(other, Maturity):\n            return NotImplemented\n        order = (Maturity.low, Maturity.medium, Maturity.high)\n        return order.index(self) < order.index(other)\n\n    def __gt__(self, other):\n        if not isinstance(other, Maturity):\n            return NotImplemented\n        return self != other and not (self < other)\n\n    def __ge__(self, other):\n        if not isinstance(other, Maturity):\n            return NotImplemented\n        return self == other or not (self < other)\n\n    def __le__(self, other):\n        if not isinstance(other, Maturity):\n            return NotImplemented\n        return self == other or self < other\n\n\n@dataclass\nclass UnparsedExposure(dbtClassMixin):\n    name: str\n    type: ExposureType\n    owner: Owner\n    description: str = \"\"\n    label: Optional[str] = None\n    maturity: Optional[MaturityType] = None\n    meta: Dict[str, Any] = field(default_factory=dict)\n    tags: List[str] = field(default_factory=list)\n    url: Optional[str] = None\n    depends_on: List[str] = field(default_factory=list)\n    config: Dict[str, Any] = field(default_factory=dict)\n\n    @classmethod\n    def validate(cls, data):\n        super(UnparsedExposure, cls).validate(data)\n        if \"name\" in data:\n            # name can only contain alphanumeric chars and underscores\n            if not (re.match(r\"[\\w-]+$\", data[\"name\"])):\n                deprecations.warn(\"exposure-name\", exposure=data[\"name\"])\n\n        if data[\"owner\"].get(\"name\") is None and data[\"owner\"].get(\"email\") is None:\n            raise ValidationError(\"Exposure owner must have at least one of 'name' or 'email'.\")\n\n\n@dataclass\nclass UnparsedGroup(dbtClassMixin):\n    name: str\n    owner: Owner\n    description: Optional[str] = None\n    config: Dict[str, Any] = field(default_factory=dict)\n\n    @classmethod\n    def validate(cls, data):\n        super(UnparsedGroup, cls).validate(data)\n        if data[\"owner\"].get(\"name\") is None and data[\"owner\"].get(\"email\") is None:\n            raise ValidationError(\"Group owner must have at least one of 'name' or 'email'.\")\n        # TODO DI-4413: the following are not strictly necessary (they will be handled\n        #               in dsi validation), but they would be a better user experience\n        #               if we did it at parse time.\n        # TODO: validate that conversion metrics have base_metric, conversion_metric, and entity\n        # TODO: validate that cumulative metrics have all required inputs here\n        # TODO: validate that derived metrics have all required inputs here\n        # TODO: validate that ratio metrics have all required inputs here\n        # TODO: validate that simple metrics have all required inputs here\n\n\n@dataclass\nclass UnparsedFunctionReturns(dbtClassMixin):\n    returns: FunctionReturns\n\n\n@dataclass\nclass UnparsedFunctionUpdate(HasConfig, HasColumnProps, HasYamlMetadata, UnparsedFunctionReturns):\n    access: Optional[str] = None\n    arguments: List[FunctionArgument] = field(default_factory=list)\n\n\n#\n# semantic interfaces unparsed objects\n#\n\n\n@dataclass\nclass UnparsedNonAdditiveDimension(dbtClassMixin):\n    name: str\n    window_choice: str  # AggregationType enum\n    window_groupings: List[str] = field(default_factory=list)\n\n\nclass PercentileType(str, Enum):\n    DISCRETE = \"discrete\"\n    CONTINUOUS = \"continuous\"\n\n\n@dataclass\nclass UnparsedMeasure(dbtClassMixin):\n    name: str\n    agg: str  # actually an enum\n    description: Optional[str] = None\n    label: Optional[str] = None\n    expr: Optional[Union[str, bool, int]] = None\n    agg_params: Optional[MeasureAggregationParameters] = None\n    non_additive_dimension: Optional[UnparsedNonAdditiveDimension] = None\n    agg_time_dimension: Optional[str] = None\n    create_metric: bool = False\n    config: Dict[str, Any] = field(default_factory=dict)\n\n\n@dataclass\nclass UnparsedSemanticModel(dbtClassMixin):\n    name: str\n    model: str  # looks like \"ref(...)\"\n    config: Dict[str, Any] = field(default_factory=dict)\n    description: Optional[str] = None\n    label: Optional[str] = None\n    defaults: Optional[Defaults] = None\n    entities: List[UnparsedEntity] = field(default_factory=list)\n    measures: List[UnparsedMeasure] = field(default_factory=list)\n    dimensions: List[UnparsedDimension] = field(default_factory=list)\n    primary_entity: Optional[str] = None\n\n\n@dataclass\nclass UnparsedQueryParams(dbtClassMixin):\n    metrics: List[str] = field(default_factory=list)\n    group_by: List[str] = field(default_factory=list)\n    # Note: `Union` must be the outermost part of the type annotation for serialization to work properly.\n    where: Union[str, List[str], None] = None\n    order_by: List[str] = field(default_factory=list)\n    limit: Optional[int] = None\n\n\n@dataclass\nclass UnparsedExport(dbtClassMixin):\n    \"\"\"Configuration for writing query results to a table.\"\"\"\n\n    name: str\n    config: Dict[str, Any] = field(default_factory=dict)\n\n\n@dataclass\nclass UnparsedSavedQuery(dbtClassMixin):\n    name: str\n    query_params: UnparsedQueryParams\n    description: Optional[str] = None\n    label: Optional[str] = None\n    exports: List[UnparsedExport] = field(default_factory=list)\n    config: Dict[str, Any] = field(default_factory=dict)\n    # Note: the order of the types is critical; it's the order that they will be checked against inputs.\n    #       if reversed, a single-string tag like `tag: \"good\"` becomes ['g','o','o','d']\n    tags: Union[str, List[str]] = field(\n        default_factory=list_str,\n        metadata=metas(ShowBehavior.Hide, MergeBehavior.Append, CompareBehavior.Exclude),\n    )\n\n\ndef normalize_date(d: Optional[datetime.date]) -> Optional[datetime.datetime]:\n    \"\"\"Convert date to datetime (at midnight), and add local time zone if naive\"\"\"\n    if d is None:\n        return None\n\n    # convert date to datetime\n    dt = d if type(d) == datetime.datetime else datetime.datetime(d.year, d.month, d.day)\n\n    if not dt.tzinfo:\n        # date is naive, re-interpret as system time zone\n        dt = dt.astimezone()\n\n    return dt\n\n\n@dataclass\nclass UnparsedUnitTest(dbtClassMixin):\n    name: str\n    model: str  # name of the model being unit tested\n    given: Sequence[UnitTestInputFixture]\n    expect: UnitTestOutputFixture\n    description: str = \"\"\n    overrides: Optional[UnitTestOverrides] = None\n    config: Dict[str, Any] = field(default_factory=dict)\n    versions: Optional[UnitTestNodeVersions] = None\n\n    @classmethod\n    def validate(cls, data):\n        super(UnparsedUnitTest, cls).validate(data)\n        if data.get(\"versions\", None):\n            if data[\"versions\"].get(\"include\") and data[\"versions\"].get(\"exclude\"):\n                raise ValidationError(\"Unit tests can not both include and exclude versions.\")\n"
  },
  {
    "path": "core/dbt/contracts/project.py",
    "content": "from dataclasses import dataclass, field\nfrom typing import Any, ClassVar, Dict, List, Optional, Union\n\nfrom mashumaro.jsonschema.annotations import Pattern\nfrom mashumaro.types import SerializableType\nfrom typing_extensions import Annotated\n\nfrom dbt.adapters.contracts.connection import QueryComment\nfrom dbt.contracts.util import Identifier, list_str\nfrom dbt_common.contracts.util import Mergeable\nfrom dbt_common.dataclass_schema import (\n    ExtensibleDbtClassMixin,\n    ValidationError,\n    dbtClassMixin,\n    dbtMashConfig,\n)\nfrom dbt_common.helper_types import NoValue\n\nDEFAULT_SEND_ANONYMOUS_USAGE_STATS = True\n\n\nclass SemverString(str, SerializableType):\n    def _serialize(self) -> str:\n        return self\n\n    @classmethod\n    def _deserialize(cls, value: str) -> \"SemverString\":\n        return SemverString(value)\n\n\n# This supports full semver, but also allows for 2 group version numbers, (allows '1.0').\nsem_ver_pattern = r\"^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?)?$\"\n\n\n@dataclass\nclass Quoting(dbtClassMixin, Mergeable):\n    schema: Optional[bool] = None\n    database: Optional[bool] = None\n    project: Optional[bool] = None\n    identifier: Optional[bool] = None\n    snowflake_ignore_case: Optional[bool] = None\n\n\n@dataclass\nclass Package(dbtClassMixin):\n\n    # Exclude {'name': None} from to_dict result to avoid changing sha1_hash result\n    # when user has not changed their 'packages' configuration.\n    def __post_serialize__(self, data, context: Optional[Dict]):\n        if \"name\" in data.keys() and data[\"name\"] is None:\n            data.pop(\"name\")\n            return data\n        return data\n\n\n@dataclass\nclass LocalPackage(Package):\n    local: str\n    unrendered: Dict[str, Any] = field(default_factory=dict)\n    name: Optional[str] = None\n\n\n# `float` also allows `int`, according to PEP484 (and jsonschema!)\nRawVersion = Union[str, float]\n\n\n@dataclass\nclass TarballPackage(Package):\n    tarball: str\n    name: str\n    unrendered: Dict[str, Any] = field(default_factory=dict)\n\n\n@dataclass\nclass GitPackage(Package):\n    git: str\n    revision: Optional[RawVersion] = None\n    warn_unpinned: Optional[bool] = field(default=None, metadata={\"alias\": \"warn-unpinned\"})\n    subdirectory: Optional[str] = None\n    unrendered: Dict[str, Any] = field(default_factory=dict)\n    name: Optional[str] = None\n\n    def get_revisions(self) -> List[str]:\n        if self.revision is None:\n            return []\n        else:\n            return [str(self.revision)]\n\n\n@dataclass\nclass PrivatePackage(Package):\n    private: str\n    provider: Optional[str] = None\n    revision: Optional[RawVersion] = None\n    warn_unpinned: Optional[bool] = field(default=None, metadata={\"alias\": \"warn-unpinned\"})\n    subdirectory: Optional[str] = None\n    unrendered: Dict[str, Any] = field(default_factory=dict)\n    name: Optional[str] = None\n\n\n@dataclass\nclass RegistryPackage(Package):\n    package: str\n    version: Union[RawVersion, List[RawVersion]]\n    install_prerelease: Optional[bool] = False\n    unrendered: Dict[str, Any] = field(default_factory=dict)\n    name: Optional[str] = None\n\n    def get_versions(self) -> List[str]:\n        if isinstance(self.version, list):\n            return [str(v) for v in self.version]\n        else:\n            return [str(self.version)]\n\n\nPackageSpec = Union[LocalPackage, TarballPackage, GitPackage, RegistryPackage, PrivatePackage]\n\n\n@dataclass\nclass PackageConfig(dbtClassMixin):\n    packages: List[PackageSpec]\n\n    @classmethod\n    def validate(cls, data):\n        for package in data.get(\"packages\", data):\n            # This can happen when the target is a variable that is not filled and results in hangs\n            if isinstance(package, dict):\n                if package.get(\"package\") == \"\":\n                    raise ValidationError(\n                        \"A hub package is missing the value. It is a required property.\"\n                    )\n                if package.get(\"local\") == \"\":\n                    raise ValidationError(\n                        \"A local package is missing the value. It is a required property.\"\n                    )\n                if package.get(\"git\") == \"\":\n                    raise ValidationError(\n                        \"A git package is missing the value. It is a required property.\"\n                    )\n            if isinstance(package, dict) and package.get(\"package\"):\n                if not package[\"version\"]:\n                    raise ValidationError(\n                        f\"{package['package']} is missing the version. When installing from the Hub \"\n                        \"package index, version is a required property\"\n                    )\n                if \"/\" not in package[\"package\"]:\n                    raise ValidationError(\n                        f\"{package['package']} was not found in the package index. Packages on the index \"\n                        \"require a namespace, e.g dbt-labs/dbt_utils\"\n                    )\n        super().validate(data)\n\n\n@dataclass\nclass ProjectPackageMetadata:\n    name: str\n    packages: List[PackageSpec]\n\n    @classmethod\n    def from_project(cls, project):\n        return cls(name=project.project_name, packages=project.packages.packages)\n\n\n@dataclass\nclass Downloads(ExtensibleDbtClassMixin):\n    tarball: str\n\n\n@dataclass\nclass RegistryPackageMetadata(\n    ExtensibleDbtClassMixin,\n    ProjectPackageMetadata,\n):\n    downloads: Downloads\n\n\n# A list of all the reserved words that packages may not have as names.\nBANNED_PROJECT_NAMES = {\n    \"_sql_results\",\n    \"adapter\",\n    \"api\",\n    \"column\",\n    \"config\",\n    \"context\",\n    \"database\",\n    \"env\",\n    \"env_var\",\n    \"exceptions\",\n    \"execute\",\n    \"flags\",\n    \"fromjson\",\n    \"fromyaml\",\n    \"graph\",\n    \"invocation_id\",\n    \"load_agate_table\",\n    \"load_result\",\n    \"log\",\n    \"model\",\n    \"modules\",\n    \"post_hooks\",\n    \"pre_hooks\",\n    \"ref\",\n    \"render\",\n    \"return\",\n    \"run_started_at\",\n    \"schema\",\n    \"source\",\n    \"sql\",\n    \"sql_now\",\n    \"store_result\",\n    \"store_raw_result\",\n    \"target\",\n    \"this\",\n    \"tojson\",\n    \"toyaml\",\n    \"try_or_compiler_error\",\n    \"var\",\n    \"write\",\n}\n\n\n@dataclass\nclass Project(dbtClassMixin):\n    _hyphenated: ClassVar[bool] = True\n    # Annotated is used by mashumaro for jsonschema generation\n    name: Annotated[Identifier, Pattern(r\"^[^\\d\\W]\\w*$\")]\n    config_version: Optional[int] = 2\n    # Annotated is used by mashumaro for jsonschema generation\n    version: Optional[Union[Annotated[SemverString, Pattern(sem_ver_pattern)], float]] = None\n    project_root: Optional[str] = None\n    source_paths: Optional[List[str]] = None\n    model_paths: Optional[List[str]] = None\n    macro_paths: Optional[List[str]] = None\n    data_paths: Optional[List[str]] = None  # deprecated\n    seed_paths: Optional[List[str]] = None\n    test_paths: Optional[List[str]] = None\n    analysis_paths: Optional[List[str]] = None\n    docs_paths: Optional[List[str]] = None\n    asset_paths: Optional[List[str]] = None\n    function_paths: Optional[List[str]] = None\n    target_path: Optional[str] = None\n    snapshot_paths: Optional[List[str]] = None\n    clean_targets: Optional[List[str]] = None\n    profile: Optional[str] = None\n    log_path: Optional[str] = None\n    packages_install_path: Optional[str] = None\n    quoting: Optional[Quoting] = None\n    on_run_start: Optional[List[str]] = field(default_factory=list_str)\n    on_run_end: Optional[List[str]] = field(default_factory=list_str)\n    require_dbt_version: Optional[Union[List[str], str]] = None\n    dispatch: List[Dict[str, Any]] = field(default_factory=list)\n    models: Dict[str, Any] = field(default_factory=dict)\n    seeds: Dict[str, Any] = field(default_factory=dict)\n    snapshots: Dict[str, Any] = field(default_factory=dict)\n    analyses: Dict[str, Any] = field(default_factory=dict)\n    sources: Dict[str, Any] = field(default_factory=dict)\n    tests: Dict[str, Any] = field(default_factory=dict)  # deprecated\n    data_tests: Dict[str, Any] = field(default_factory=dict)\n    unit_tests: Dict[str, Any] = field(default_factory=dict)\n    metrics: Dict[str, Any] = field(default_factory=dict)\n    semantic_models: Dict[str, Any] = field(default_factory=dict)\n    saved_queries: Dict[str, Any] = field(default_factory=dict)\n    exposures: Dict[str, Any] = field(default_factory=dict)\n    functions: Dict[str, Any] = field(default_factory=dict)\n    vars: Optional[Dict[str, Any]] = field(\n        default=None,\n        metadata=dict(\n            description=\"map project names to their vars override dicts\",\n        ),\n    )\n    packages: List[PackageSpec] = field(default_factory=list)\n    query_comment: Optional[Union[QueryComment, NoValue, str]] = field(default_factory=NoValue)\n    restrict_access: bool = False\n    dbt_cloud: Optional[Dict[str, Any]] = None\n    flags: Dict[str, Any] = field(default_factory=dict)\n\n    class Config(dbtMashConfig):\n        # These tell mashumaro to use aliases for jsonschema and for \"from_dict\"\n        aliases = {\n            \"config_version\": \"config-version\",\n            \"project_root\": \"project-root\",\n            \"source_paths\": \"source-paths\",\n            \"model_paths\": \"model-paths\",\n            \"macro_paths\": \"macro-paths\",\n            \"data_paths\": \"data-paths\",\n            \"seed_paths\": \"seed-paths\",\n            \"test_paths\": \"test-paths\",\n            \"analysis_paths\": \"analysis-paths\",\n            \"docs_paths\": \"docs-paths\",\n            \"asset_paths\": \"asset-paths\",\n            \"function_paths\": \"function-paths\",\n            \"target_path\": \"target-path\",\n            \"snapshot_paths\": \"snapshot-paths\",\n            \"clean_targets\": \"clean-targets\",\n            \"log_path\": \"log-path\",\n            \"packages_install_path\": \"packages-install-path\",\n            \"on_run_start\": \"on-run-start\",\n            \"on_run_end\": \"on-run-end\",\n            \"require_dbt_version\": \"require-dbt-version\",\n            \"query_comment\": \"query-comment\",\n            \"restrict_access\": \"restrict-access\",\n            \"semantic_models\": \"semantic-models\",\n            \"saved_queries\": \"saved-queries\",\n            \"dbt_cloud\": \"dbt-cloud\",\n        }\n\n    @classmethod\n    def validate(cls, data):\n        super().validate(data)\n        if data[\"name\"] in BANNED_PROJECT_NAMES:\n            raise ValidationError(f\"Invalid project name: {data['name']} is a reserved word\")\n        # validate dispatch config\n        if \"dispatch\" in data and data[\"dispatch\"]:\n            entries = data[\"dispatch\"]\n            for entry in entries:\n                if (\n                    \"macro_namespace\" not in entry\n                    or \"search_order\" not in entry\n                    or not isinstance(entry[\"search_order\"], list)\n                ):\n                    raise ValidationError(f\"Invalid project dispatch config: {entry}\")\n        if \"dbt_cloud\" in data and not isinstance(data[\"dbt_cloud\"], dict):\n            raise ValidationError(\n                f\"Invalid dbt_cloud config. Expected a 'dict' but got '{type(data['dbt_cloud'])}'\"\n            )\n        if data.get(\"tests\", None) and data.get(\"data_tests\", None):\n            raise ValidationError(\n                \"Invalid project config: cannot have both 'tests' and 'data_tests' defined\"\n            )\n\n\n@dataclass\nclass ProjectFlags(ExtensibleDbtClassMixin):\n    cache_selected_only: Optional[bool] = None\n    debug: Optional[bool] = None\n    fail_fast: Optional[bool] = None\n    indirect_selection: Optional[str] = None\n    log_format: Optional[str] = None\n    log_format_file: Optional[str] = None\n    log_level: Optional[str] = None\n    log_level_file: Optional[str] = None\n    partial_parse: Optional[bool] = None\n    populate_cache: Optional[bool] = None\n    printer_width: Optional[int] = None\n    send_anonymous_usage_stats: bool = DEFAULT_SEND_ANONYMOUS_USAGE_STATS\n    static_parser: Optional[bool] = None\n    use_colors: Optional[bool] = None\n    use_colors_file: Optional[bool] = None\n    use_experimental_parser: Optional[bool] = None\n    version_check: Optional[bool] = None\n    warn_error: Optional[bool] = None\n    warn_error_options: Optional[Dict[str, Union[str, List[str]]]] = None\n    write_json: Optional[bool] = None\n\n    # legacy behaviors - https://github.com/dbt-labs/dbt-core/blob/main/docs/guides/behavior-change-flags.md\n    require_batched_execution_for_custom_microbatch_strategy: bool = False\n    require_event_names_in_deprecations: bool = False\n    require_explicit_package_overrides_for_builtin_materializations: bool = True\n    require_resource_names_without_spaces: bool = True\n    source_freshness_run_project_hooks: bool = True\n    skip_nodes_if_on_run_start_fails: bool = False\n    state_modified_compare_more_unrendered_values: bool = False\n    state_modified_compare_vars: bool = False\n    require_yaml_configuration_for_mf_time_spines: bool = False\n    require_nested_cumulative_type_params: bool = False\n    validate_macro_args: bool = False\n    require_all_warnings_handled_by_warn_error: bool = False\n    require_generic_test_arguments_property: bool = True\n    require_unique_project_resource_names: bool = False\n    require_ref_searches_node_package_before_root: bool = False\n    require_valid_schema_from_generate_schema_name: bool = False\n    require_sql_header_in_test_configs: bool = False\n    support_custom_ref_kwargs: bool = False\n\n    @property\n    def project_only_flags(self) -> Dict[str, Any]:\n        return {\n            \"require_batched_execution_for_custom_microbatch_strategy\": self.require_batched_execution_for_custom_microbatch_strategy,\n            \"require_explicit_package_overrides_for_builtin_materializations\": self.require_explicit_package_overrides_for_builtin_materializations,\n            \"require_resource_names_without_spaces\": self.require_resource_names_without_spaces,\n            \"source_freshness_run_project_hooks\": self.source_freshness_run_project_hooks,\n            \"skip_nodes_if_on_run_start_fails\": self.skip_nodes_if_on_run_start_fails,\n            \"state_modified_compare_more_unrendered_values\": self.state_modified_compare_more_unrendered_values,\n            \"state_modified_compare_vars\": self.state_modified_compare_vars,\n            \"require_yaml_configuration_for_mf_time_spines\": self.require_yaml_configuration_for_mf_time_spines,\n            \"require_nested_cumulative_type_params\": self.require_nested_cumulative_type_params,\n            \"validate_macro_args\": self.validate_macro_args,\n            \"require_all_warnings_handled_by_warn_error\": self.require_all_warnings_handled_by_warn_error,\n            \"require_generic_test_arguments_property\": self.require_generic_test_arguments_property,\n            \"require_unique_project_resource_names\": self.require_unique_project_resource_names,\n            \"require_ref_searches_node_package_before_root\": self.require_ref_searches_node_package_before_root,\n            \"require_valid_schema_from_generate_schema_name\": self.require_valid_schema_from_generate_schema_name,\n            \"require_sql_header_in_test_configs\": self.require_sql_header_in_test_configs,\n            \"support_custom_ref_kwargs\": self.support_custom_ref_kwargs,\n        }\n\n\n@dataclass\nclass ProfileConfig(dbtClassMixin):\n    profile_name: str\n    target_name: str\n    threads: int\n    # TODO: make this a dynamic union of some kind?\n    credentials: Optional[Dict[str, Any]]\n\n\n@dataclass\nclass ConfiguredQuoting(Quoting):\n    identifier: bool = True\n    schema: bool = True\n    database: Optional[bool] = None\n    project: Optional[bool] = None\n    snowflake_ignore_case: Optional[bool] = None\n\n\n@dataclass\nclass Configuration(Project, ProfileConfig):\n    cli_vars: Dict[str, Any] = field(\n        default_factory=dict,\n        metadata={\"preserve_underscore\": True},\n    )\n    quoting: Optional[ConfiguredQuoting] = None\n\n\n@dataclass\nclass ProjectList(dbtClassMixin):\n    projects: Dict[str, Project]\n"
  },
  {
    "path": "core/dbt/contracts/results.py",
    "content": "# flake8: noqa\n\n# This file is temporary, in order to not break various adapter tests, etc, until\n# they are updated to use the new locations.\n\nfrom dbt.artifacts.schemas.base import (\n    ArtifactMixin,\n    BaseArtifactMetadata,\n    VersionedSchema,\n    schema_version,\n)\nfrom dbt.artifacts.schemas.catalog import (\n    CatalogArtifact,\n    CatalogKey,\n    CatalogMetadata,\n    CatalogResults,\n    CatalogTable,\n    ColumnMetadata,\n    StatsItem,\n    TableMetadata,\n)\nfrom dbt.artifacts.schemas.freshness import (\n    FreshnessErrorEnum,\n    FreshnessExecutionResultArtifact,\n    FreshnessMetadata,\n    FreshnessNodeOutput,\n    FreshnessNodeResult,\n    FreshnessResult,\n    PartialSourceFreshnessResult,\n    SourceFreshnessOutput,\n    SourceFreshnessResult,\n    SourceFreshnessRuntimeError,\n    process_freshness_result,\n)\nfrom dbt.artifacts.schemas.results import (\n    BaseResult,\n    ExecutionResult,\n    FreshnessStatus,\n    NodeResult,\n    NodeStatus,\n    RunningStatus,\n    RunStatus,\n    TestStatus,\n    TimingInfo,\n    collect_timing_info,\n)\nfrom dbt.artifacts.schemas.run import (\n    RunExecutionResult,\n    RunResult,\n    RunResultsArtifact,\n    RunResultsMetadata,\n    process_run_result,\n)\n"
  },
  {
    "path": "core/dbt/contracts/selection.py",
    "content": "from dataclasses import dataclass\nfrom typing import Any, Dict, List, Union\n\nfrom dbt_common.dataclass_schema import dbtClassMixin\n\n\n@dataclass\nclass SelectorDefinition(dbtClassMixin):\n    name: str\n    definition: Union[str, Dict[str, Any]]\n    description: str = \"\"\n    default: bool = False\n\n\n@dataclass\nclass SelectorFile(dbtClassMixin):\n    selectors: List[SelectorDefinition]\n    version: int = 2\n\n\n# @dataclass\n# class SelectorCollection:\n#     packages: Dict[str, List[SelectorFile]] = field(default_factory=dict)\n"
  },
  {
    "path": "core/dbt/contracts/sql.py",
    "content": "import uuid\nfrom dataclasses import dataclass, field\nfrom datetime import datetime, timezone\nfrom typing import Any, Dict, List, Optional, Sequence\n\nfrom dbt.artifacts.schemas.base import VersionedSchema, schema_version\nfrom dbt.artifacts.schemas.results import ExecutionResult, TimingInfo\nfrom dbt.artifacts.schemas.run import RunExecutionResult, RunResult, RunResultsArtifact\nfrom dbt.contracts.graph.nodes import ResultNode\nfrom dbt.events.types import ArtifactWritten\nfrom dbt_common.dataclass_schema import dbtClassMixin\nfrom dbt_common.events.functions import fire_event\n\nTaskTags = Optional[Dict[str, Any]]\nTaskID = uuid.UUID\n\n# Outputs\n\n\n@dataclass\nclass RemoteCompileResultMixin(VersionedSchema):\n    raw_code: str\n    compiled_code: str\n    node: ResultNode\n    timing: List[TimingInfo]\n\n\n@dataclass\n@schema_version(\"remote-compile-result\", 1)\nclass RemoteCompileResult(RemoteCompileResultMixin):\n    generated_at: datetime = field(\n        default_factory=lambda: datetime.now(timezone.utc).replace(tzinfo=None)\n    )\n\n    @property\n    def error(self) -> None:\n        # TODO: Can we delete this? It's never set anywhere else and never accessed\n        return None\n\n\n@dataclass\n@schema_version(\"remote-execution-result\", 1)\nclass RemoteExecutionResult(ExecutionResult):\n    results: Sequence[RunResult]\n    args: Dict[str, Any] = field(default_factory=dict)\n    generated_at: datetime = field(\n        default_factory=lambda: datetime.now(timezone.utc).replace(tzinfo=None)\n    )\n\n    def write(self, path: str) -> None:\n        writable = RunResultsArtifact.from_execution_results(\n            generated_at=self.generated_at,\n            results=self.results,\n            elapsed_time=self.elapsed_time,\n            args=self.args,\n        )\n        writable.write(path)\n        fire_event(ArtifactWritten(artifact_type=writable.__class__.__name__, artifact_path=path))\n\n    @classmethod\n    def from_local_result(\n        cls,\n        base: RunExecutionResult,\n    ) -> \"RemoteExecutionResult\":\n        return cls(\n            generated_at=base.generated_at,\n            results=base.results,\n            elapsed_time=base.elapsed_time,\n            args=base.args,\n        )\n\n\n@dataclass\nclass ResultTable(dbtClassMixin):\n    column_names: List[str]\n    rows: List[Any]\n\n\n@dataclass\n@schema_version(\"remote-run-result\", 1)\nclass RemoteRunResult(RemoteCompileResultMixin):\n    table: ResultTable\n    generated_at: datetime = field(\n        default_factory=lambda: datetime.now(timezone.utc).replace(tzinfo=None)\n    )\n"
  },
  {
    "path": "core/dbt/contracts/state.py",
    "content": "from pathlib import Path\nfrom typing import Optional\n\nfrom dbt.artifacts.exceptions import IncompatibleSchemaError\nfrom dbt.artifacts.schemas.freshness import FreshnessExecutionResultArtifact\nfrom dbt.artifacts.schemas.manifest import WritableManifest\nfrom dbt.artifacts.schemas.run import RunResultsArtifact\nfrom dbt.constants import RUN_RESULTS_FILE_NAME\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.events.types import WarnStateTargetEqual\nfrom dbt_common.events.functions import fire_event\n\n\ndef load_result_state(results_path) -> Optional[RunResultsArtifact]:\n    if results_path.exists() and results_path.is_file():\n        try:\n            return RunResultsArtifact.read_and_check_versions(str(results_path))\n        except IncompatibleSchemaError as exc:\n            exc.add_filename(str(results_path))\n            raise\n    return None\n\n\nclass PreviousState:\n    def __init__(self, state_path: Path, target_path: Path, project_root: Path) -> None:\n        self.state_path: Path = state_path\n        self.target_path: Path = target_path\n        self.project_root: Path = project_root\n        self.manifest: Optional[Manifest] = None\n        self.results: Optional[RunResultsArtifact] = None\n        self.sources: Optional[FreshnessExecutionResultArtifact] = None\n        self.sources_current: Optional[FreshnessExecutionResultArtifact] = None\n\n        if self.state_path == self.target_path:\n            fire_event(WarnStateTargetEqual(state_path=str(self.state_path)))\n\n        # Note: if state_path is absolute, project_root will be ignored.\n        manifest_path = self.project_root / self.state_path / \"manifest.json\"\n        if manifest_path.exists() and manifest_path.is_file():\n            try:\n                writable_manifest = WritableManifest.read_and_check_versions(str(manifest_path))\n                self.manifest = Manifest.from_writable_manifest(writable_manifest)\n            except IncompatibleSchemaError as exc:\n                exc.add_filename(str(manifest_path))\n                raise\n\n        results_path = self.project_root / self.state_path / RUN_RESULTS_FILE_NAME\n        self.results = load_result_state(results_path)\n\n        sources_path = self.project_root / self.state_path / \"sources.json\"\n        if sources_path.exists() and sources_path.is_file():\n            try:\n                self.sources = FreshnessExecutionResultArtifact.read_and_check_versions(\n                    str(sources_path)\n                )\n            except IncompatibleSchemaError as exc:\n                exc.add_filename(str(sources_path))\n                raise\n\n        sources_current_path = self.project_root / self.target_path / \"sources.json\"\n        if sources_current_path.exists() and sources_current_path.is_file():\n            try:\n                self.sources_current = FreshnessExecutionResultArtifact.read_and_check_versions(\n                    str(sources_current_path)\n                )\n            except IncompatibleSchemaError as exc:\n                exc.add_filename(str(sources_current_path))\n                raise\n"
  },
  {
    "path": "core/dbt/contracts/util.py",
    "content": "from typing import Any, List, Tuple\n\n# Leave imports of `Mergeable` to preserve import paths\nfrom dbt_common.contracts.util import Mergeable  # noqa:F401\nfrom dbt_common.dataclass_schema import ValidatedStringMixin, ValidationError\n\nSourceKey = Tuple[str, str]\n\n\ndef list_str() -> List[str]:\n    \"\"\"Mypy gets upset about stuff like:\n\n    from dataclasses import dataclass, field\n    from typing import Optional, List\n\n    @dataclass\n    class Foo:\n        x: Optional[List[str]] = field(default_factory=list)\n\n\n    Because `list` could be any kind of list, I guess\n    \"\"\"\n    return []\n\n\nclass Identifier(ValidatedStringMixin):\n    \"\"\"Our definition of a valid Identifier is the same as what's valid for an unquoted database table name.\n\n    That is:\n    1. It can contain a-z, A-Z, 0-9, and _\n    1. It cannot start with a number\n    \"\"\"\n\n    ValidationRegex = r\"^[^\\d\\W]\\w*$\"\n\n    @classmethod\n    def is_valid(cls, value: Any) -> bool:\n        if not isinstance(value, str):\n            return False\n\n        try:\n            cls.validate(value)\n        except ValidationError:\n            return False\n\n        return True\n"
  },
  {
    "path": "core/dbt/deprecations.py",
    "content": "import abc\nfrom collections import defaultdict\nfrom dataclasses import dataclass\nfrom typing import Any, Callable, ClassVar, DefaultDict, Dict, List, Optional\n\nimport dbt.tracking\nfrom dbt.events import types as core_types\nfrom dbt.flags import get_flags\nfrom dbt_common.dataclass_schema import dbtClassMixin\nfrom dbt_common.events.functions import fire_event, warn_or_error\nfrom dbt_common.events.types import Note\n\n\nclass DBTDeprecation:\n    _name: ClassVar[Optional[str]] = None\n    _event: ClassVar[Optional[str]] = None\n    _is_preview: ClassVar[bool] = False\n\n    @property\n    def name(self) -> str:\n        if self._name is not None:\n            return self._name\n        raise NotImplementedError(\"name not implemented for {}\".format(self))\n\n    def track_deprecation_warn(self) -> None:\n        if dbt.tracking.active_user is not None:\n            dbt.tracking.track_deprecation_warn({\"deprecation_name\": self.name})\n\n    @property\n    def event(self) -> abc.ABCMeta:\n        if self._event is not None:\n            module_path = core_types\n            class_name = self._event\n\n            try:\n                return getattr(module_path, class_name)\n            except AttributeError:\n                msg = f\"Event Class `{class_name}` is not defined in `{module_path}`\"\n                raise NameError(msg)\n        raise NotImplementedError(\"event not implemented for {}\".format(self._event))\n\n    def preview(self, base_event: abc.ABCMeta) -> None:\n        note_event = Note(msg=base_event.message())  # type: ignore\n        fire_event(note_event)\n\n    def show(self, *args, **kwargs) -> None:\n        if self._is_preview:\n            base_event = self.event(**kwargs)\n            self.preview(base_event)\n        else:\n            flags = get_flags()\n            if self.name not in active_deprecations or flags.show_all_deprecations:\n                event = self.event(**kwargs)\n                warn_or_error(event)\n                self.track_deprecation_warn()\n\n            active_deprecations[self.name] += 1\n\n\nclass PackageRedirectDeprecation(DBTDeprecation):\n    _name = \"package-redirect\"\n    _event = \"PackageRedirectDeprecation\"\n\n\nclass PackageInstallPathDeprecation(DBTDeprecation):\n    _name = \"install-packages-path\"\n    _event = \"PackageInstallPathDeprecation\"\n\n\n# deprecations with a pattern of `project-config-*` for the name are not hardcoded\n# they are called programatically via the pattern below\nclass ConfigSourcePathDeprecation(DBTDeprecation):\n    _name = \"project-config-source-paths\"\n    _event = \"ConfigSourcePathDeprecation\"\n\n\nclass ConfigDataPathDeprecation(DBTDeprecation):\n    _name = \"project-config-data-paths\"\n    _event = \"ConfigDataPathDeprecation\"\n\n\nclass ConfigLogPathDeprecation(DBTDeprecation):\n    _name = \"project-config-log-path\"\n    _event = \"ConfigLogPathDeprecation\"\n\n\nclass ConfigTargetPathDeprecation(DBTDeprecation):\n    _name = \"project-config-target-path\"\n    _event = \"ConfigTargetPathDeprecation\"\n\n\ndef renamed_method(old_name: str, new_name: str):\n    class AdapterDeprecationWarning(DBTDeprecation):\n        _name = \"adapter:{}\".format(old_name)\n        _event = \"AdapterDeprecationWarning\"\n\n    dep = AdapterDeprecationWarning()\n    deprecations_list.append(dep)\n    deprecations[dep.name] = dep\n\n\nclass MetricAttributesRenamed(DBTDeprecation):\n    _name = \"metric-attr-renamed\"\n    _event = \"MetricAttributesRenamed\"\n\n\nclass ExposureNameDeprecation(DBTDeprecation):\n    _name = \"exposure-name\"\n    _event = \"ExposureNameDeprecation\"\n\n\nclass CollectFreshnessReturnSignature(DBTDeprecation):\n    _name = \"collect-freshness-return-signature\"\n    _event = \"CollectFreshnessReturnSignature\"\n\n\nclass ProjectFlagsMovedDeprecation(DBTDeprecation):\n    _name = \"project-flags-moved\"\n    _event = \"ProjectFlagsMovedDeprecation\"\n\n\nclass PackageMaterializationOverrideDeprecation(DBTDeprecation):\n    _name = \"package-materialization-override\"\n    _event = \"PackageMaterializationOverrideDeprecation\"\n\n\nclass ResourceNamesWithSpacesDeprecation(DBTDeprecation):\n    _name = \"resource-names-with-spaces\"\n    _event = \"ResourceNamesWithSpacesDeprecation\"\n\n\nclass SourceFreshnessProjectHooksNotRun(DBTDeprecation):\n    _name = \"source-freshness-project-hooks\"\n    _event = \"SourceFreshnessProjectHooksNotRun\"\n\n\nclass MFTimespineWithoutYamlConfigurationDeprecation(DBTDeprecation):\n    _name = \"mf-timespine-without-yaml-configuration\"\n    _event = \"MFTimespineWithoutYamlConfigurationDeprecation\"\n\n\nclass MFCumulativeTypeParamsDeprecation(DBTDeprecation):\n    _name = \"mf-cumulative-type-params-deprecation\"\n    _event = \"MFCumulativeTypeParamsDeprecation\"\n\n\nclass MicrobatchMacroOutsideOfBatchesDeprecation(DBTDeprecation):\n    _name = \"microbatch-macro-outside-of-batches-deprecation\"\n    _event = \"MicrobatchMacroOutsideOfBatchesDeprecation\"\n\n\nclass GenericJSONSchemaValidationDeprecation(DBTDeprecation):\n    _name = \"generic-json-schema-validation-deprecation\"\n    _event = \"GenericJSONSchemaValidationDeprecation\"\n    _is_preview = True\n\n\nclass UnexpectedJinjaBlockDeprecation(DBTDeprecation):\n    _name = \"unexpected-jinja-block-deprecation\"\n    _event = \"UnexpectedJinjaBlockDeprecation\"\n\n\nclass DuplicateYAMLKeysDeprecation(DBTDeprecation):\n    _name = \"duplicate-yaml-keys-deprecation\"\n    _event = \"DuplicateYAMLKeysDeprecation\"\n\n\nclass CustomTopLevelKeyDeprecation(DBTDeprecation):\n    _name = \"custom-top-level-key-deprecation\"\n    _event = \"CustomTopLevelKeyDeprecation\"\n\n\nclass CustomKeyInConfigDeprecation(DBTDeprecation):\n    _name = \"custom-key-in-config-deprecation\"\n    _event = \"CustomKeyInConfigDeprecation\"\n\n\nclass CustomKeyInObjectDeprecation(DBTDeprecation):\n    _name = \"custom-key-in-object-deprecation\"\n    _event = \"CustomKeyInObjectDeprecation\"\n\n\nclass WEOInlcudeExcludeDeprecation(DBTDeprecation):\n    _name = \"weo-include-exclude-deprecation\"\n    _event = \"WEOIncludeExcludeDeprecation\"\n\n\nclass CustomOutputPathInSourceFreshnessDeprecation(DBTDeprecation):\n    _name = \"custom-output-path-in-source-freshness-deprecation\"\n    _event = \"CustomOutputPathInSourceFreshnessDeprecation\"\n\n\nclass SourceOverrideDeprecation(DBTDeprecation):\n    _name = \"source-override-deprecation\"\n    _event = \"SourceOverrideDeprecation\"\n\n\nclass PropertyMovedToConfigDeprecation(DBTDeprecation):\n    _name = \"property-moved-to-config-deprecation\"\n    _event = \"PropertyMovedToConfigDeprecation\"\n\n\nclass ModelParamUsageDeprecation(DBTDeprecation):\n    _name = \"model-param-usage-deprecation\"\n    _event = \"ModelParamUsageDeprecation\"\n\n\nclass EnvironmentVariableNamespaceDeprecation(DBTDeprecation):\n    _name = \"environment-variable-namespace-deprecation\"\n    _event = \"EnvironmentVariableNamespaceDeprecation\"\n\n\nclass MissingPlusPrefixDeprecation(DBTDeprecation):\n    _name = \"missing-plus-prefix-in-config-deprecation\"\n    _event = \"MissingPlusPrefixDeprecation\"\n\n\nclass ArgumentsPropertyInGenericTestDeprecation(DBTDeprecation):\n    _name = \"arguments-property-in-generic-test-deprecation\"\n    _event = \"ArgumentsPropertyInGenericTestDeprecation\"\n\n\nclass MissingArgumentsPropertyInGenericTestDeprecation(DBTDeprecation):\n    _name = \"missing-arguments-property-in-generic-test-deprecation\"\n    _event = \"MissingArgumentsPropertyInGenericTestDeprecation\"\n\n\nclass ModulesItertoolsUsageDeprecation(DBTDeprecation):\n    _name = \"modules-itertools-usage-deprecation\"\n    _event = \"ModulesItertoolsUsageDeprecation\"\n\n\nclass DuplicateNameDistinctNodeTypesDeprecation(DBTDeprecation):\n    _name = \"duplicate-name-distinct-node-types-deprecation\"\n    _event = \"DuplicateNameDistinctNodeTypesDeprecation\"\n\n\nclass TimeDimensionsRequireGranularityDeprecation(DBTDeprecation):\n    _name = \"time-dimensions-require-granularity-deprecation\"\n    _event = \"TimeDimensionsRequireGranularityDeprecation\"\n\n\nclass GenericSemanticLayerDeprecation(DBTDeprecation):\n    _name = \"generic-semantic-layer-deprecation\"\n    _event = \"GenericSemanticLayerDeprecation\"\n\n\nclass GenerateSchemaNameNullValueDeprecation(DBTDeprecation):\n    _name = \"generate-schema-name-null-value-deprecation\"\n    _event = \"GenerateSchemaNameNullValueDeprecation\"\n\n\ndef renamed_env_var(old_name: str, new_name: str):\n    class EnvironmentVariableRenamed(DBTDeprecation):\n        _name = f\"environment-variable-renamed:{old_name}\"\n        _event = \"EnvironmentVariableRenamed\"\n\n    dep = EnvironmentVariableRenamed()\n    deprecations_list.append(dep)\n    deprecations[dep.name] = dep\n\n    def cb():\n        dep.show(old_name=old_name, new_name=new_name)\n\n    return cb\n\n\ndef warn(name: str, *args, **kwargs) -> None:\n    if name not in deprecations:\n        # this should (hopefully) never happen\n        raise RuntimeError(\"Error showing deprecation warning: {}\".format(name))\n\n    deprecations[name].show(*args, **kwargs)\n\n\ndef buffer(name: str, *args, **kwargs):\n    def show_callback():\n        deprecations[name].show(*args, **kwargs)\n\n    buffered_deprecations.append(show_callback)\n\n\ndef show_deprecations_summary() -> None:\n    summaries: List[Dict[str, Any]] = []\n    for deprecation, occurrences in active_deprecations.items():\n        deprecation_event = deprecations[deprecation].event()\n        summaries.append(\n            DeprecationSummary(\n                event_name=type(deprecation_event).__name__,\n                event_code=deprecation_event.code(),\n                occurrences=occurrences,\n            ).to_msg_dict()\n        )\n\n    if len(summaries) > 0:\n        show_all_hint = not get_flags().show_all_deprecations\n        warn_or_error(\n            core_types.DeprecationsSummary(summaries=summaries, show_all_hint=show_all_hint)\n        )\n\n\n# these are globally available\n# since modules are only imported once, active_deprecations is a singleton\n\nactive_deprecations: DefaultDict[str, int] = defaultdict(int)\n\ndeprecations_list: List[DBTDeprecation] = [\n    PackageRedirectDeprecation(),\n    PackageInstallPathDeprecation(),\n    ConfigSourcePathDeprecation(),\n    ConfigDataPathDeprecation(),\n    ExposureNameDeprecation(),\n    ConfigLogPathDeprecation(),\n    ConfigTargetPathDeprecation(),\n    CollectFreshnessReturnSignature(),\n    ProjectFlagsMovedDeprecation(),\n    PackageMaterializationOverrideDeprecation(),\n    ResourceNamesWithSpacesDeprecation(),\n    SourceFreshnessProjectHooksNotRun(),\n    MFTimespineWithoutYamlConfigurationDeprecation(),\n    MFCumulativeTypeParamsDeprecation(),\n    MicrobatchMacroOutsideOfBatchesDeprecation(),\n    GenericJSONSchemaValidationDeprecation(),\n    UnexpectedJinjaBlockDeprecation(),\n    DuplicateYAMLKeysDeprecation(),\n    CustomTopLevelKeyDeprecation(),\n    CustomKeyInConfigDeprecation(),\n    CustomKeyInObjectDeprecation(),\n    CustomOutputPathInSourceFreshnessDeprecation(),\n    PropertyMovedToConfigDeprecation(),\n    ModelParamUsageDeprecation(),\n    WEOInlcudeExcludeDeprecation(),\n    SourceOverrideDeprecation(),\n    EnvironmentVariableNamespaceDeprecation(),\n    MissingPlusPrefixDeprecation(),\n    ArgumentsPropertyInGenericTestDeprecation(),\n    MissingArgumentsPropertyInGenericTestDeprecation(),\n    ModulesItertoolsUsageDeprecation(),\n    DuplicateNameDistinctNodeTypesDeprecation(),\n    TimeDimensionsRequireGranularityDeprecation(),\n    GenericSemanticLayerDeprecation(),\n    GenerateSchemaNameNullValueDeprecation(),\n]\n\ndeprecations: Dict[str, DBTDeprecation] = {d.name: d for d in deprecations_list}\n\nbuffered_deprecations: List[Callable] = []\n\n\ndef reset_deprecations():\n    active_deprecations.clear()\n\n\ndef fire_buffered_deprecations():\n    [dep_fn() for dep_fn in buffered_deprecations]\n    buffered_deprecations.clear()\n\n\n@dataclass\nclass DeprecationSummary(dbtClassMixin):\n    event_name: str\n    event_code: str\n    occurrences: int\n\n    def to_msg_dict(self) -> Dict[str, Any]:\n        return {\n            \"event_name\": self.event_name,\n            \"event_code\": self.event_code,\n            \"occurrences\": self.occurrences,\n        }\n"
  },
  {
    "path": "core/dbt/deps/README.md",
    "content": "# Deps README\n\nThe deps module is responsible for installing dbt packages into dbt projects.  A dbt package is a standalone dbt project with models and macros that solve a specific problem area.  More specific information on dbt packages is available on the [docs site](https://docs.getdbt.com/docs/building-a-dbt-project/package-management).\n\n\n# What's a package?\n\nSee [How do I specify a package?](https://docs.getdbt.com/docs/building-a-dbt-project/package-management#how-do-i-specify-a-package) on the docs site for a detailed explination of the different types of packages supported and expected formats.\n\n\n# Files\n\n## `base.py`\n\nDefines the base classes of `PinnedPackage` and `UnpinnedPackage`.\n\n`downloads_directory` sets the directory packages will be downloaded to.\n\n`_install` has retry logic if the download or untarring process hit exceptions (see `dbt_common.utils.connection_exception_retry`).\n\n## `git.py`\n\nExtends `PinnedPackage` and `UnpinnedPackage` specific to dbt packages defined with git urls.\n\n## `local.py`\n\nExtends `PinnedPackage` and `UnpinnedPackage` specific to dbt packages defined locally.\n\n## `registry.py`\n\nExtends `PinnedPackage` and `UnpinnedPackage` specific to dbt packages defined on the dbt Hub registry.\n\n\n## `resolver.py`\n\nResolves the package definition into package objects to download.\n\n## `tarball.py`\nExtends `PinnedPackage` and `UnpinnedPackage` specific to dbt packages defined by a URL to a tarball hosted on an HTTP server.\n"
  },
  {
    "path": "core/dbt/deps/__init__.py",
    "content": ""
  },
  {
    "path": "core/dbt/deps/base.py",
    "content": "import abc\nimport functools\nimport os\nimport tempfile\nfrom contextlib import contextmanager\nfrom pathlib import Path\nfrom typing import Dict, Generic, List, Optional, TypeVar\n\nfrom dbt.contracts.project import ProjectPackageMetadata\nfrom dbt.events.types import DepsSetDownloadDirectory\nfrom dbt_common.clients import system\nfrom dbt_common.events.functions import fire_event\nfrom dbt_common.utils.connection import connection_exception_retry\n\nDOWNLOADS_PATH = None\n\n\ndef get_downloads_path():\n    return DOWNLOADS_PATH\n\n\n@contextmanager\ndef downloads_directory():\n    global DOWNLOADS_PATH\n    remove_downloads = False\n    # the user might have set an environment variable. Set it to that, and do\n    # not remove it when finished.\n    if DOWNLOADS_PATH is None:\n        DOWNLOADS_PATH = os.getenv(\"DBT_DOWNLOADS_DIR\")\n        remove_downloads = False\n    # if we are making a per-run temp directory, remove it at the end of\n    # successful runs\n    if DOWNLOADS_PATH is None:\n        DOWNLOADS_PATH = tempfile.mkdtemp(prefix=\"dbt-downloads-\")\n        remove_downloads = True\n\n    system.make_directory(DOWNLOADS_PATH)\n    fire_event(DepsSetDownloadDirectory(path=DOWNLOADS_PATH))\n\n    yield DOWNLOADS_PATH\n\n    if remove_downloads:\n        system.rmtree(DOWNLOADS_PATH)\n        DOWNLOADS_PATH = None\n\n\nclass BasePackage(metaclass=abc.ABCMeta):\n    @abc.abstractproperty\n    def name(self) -> str:\n        raise NotImplementedError\n\n    def all_names(self) -> List[str]:\n        return [self.name]\n\n    @abc.abstractmethod\n    def source_type(self) -> str:\n        raise NotImplementedError\n\n\nclass PinnedPackage(BasePackage):\n    def __init__(self) -> None:\n        self._cached_metadata: Optional[ProjectPackageMetadata] = None\n\n    def __str__(self) -> str:\n        version = self.get_version()\n        if not version:\n            return self.name\n\n        return \"{}@{}\".format(self.name, version)\n\n    @abc.abstractmethod\n    def get_version(self) -> Optional[str]:\n        raise NotImplementedError\n\n    @abc.abstractmethod\n    def _fetch_metadata(self, project, renderer):\n        raise NotImplementedError\n\n    @abc.abstractmethod\n    def install(self, project, renderer):\n        raise NotImplementedError\n\n    @abc.abstractmethod\n    def nice_version_name(self):\n        raise NotImplementedError\n\n    @abc.abstractmethod\n    def to_dict(self) -> Dict[str, str]:\n        raise NotImplementedError\n\n    def fetch_metadata(self, project, renderer):\n        if not self._cached_metadata:\n            self._cached_metadata = self._fetch_metadata(project, renderer)\n        return self._cached_metadata\n\n    def get_project_name(self, project, renderer):\n        metadata = self.fetch_metadata(project, renderer)\n        return metadata.name\n\n    def get_installation_path(self, project, renderer):\n        dest_dirname = self.get_project_name(project, renderer)\n        return os.path.join(project.packages_install_path, dest_dirname)\n\n    def get_subdirectory(self):\n        return None\n\n    def _install(self, project, renderer):\n        metadata = self.fetch_metadata(project, renderer)\n\n        tar_name = f\"{self.package}.{self.version}.tar.gz\"\n        tar_path = (Path(get_downloads_path()) / tar_name).resolve(strict=False)\n        system.make_directory(str(tar_path.parent))\n\n        download_url = metadata.downloads.tarball\n        deps_path = project.packages_install_path\n        package_name = self.get_project_name(project, renderer)\n\n        download_untar_fn = functools.partial(\n            self.download_and_untar, download_url, str(tar_path), deps_path, package_name\n        )\n        connection_exception_retry(download_untar_fn, 5)\n\n    def download_and_untar(self, download_url, tar_path, deps_path, package_name):\n        \"\"\"\n        Sometimes the download of the files fails and we want to retry.  Sometimes the\n        download appears successful but the file did not make it through as expected\n        (generally due to a github incident).  Either way we want to retry downloading\n        and untarring to see if we can get a success.  Call this within\n        `connection_exception_retry`\n        \"\"\"\n\n        system.download(download_url, tar_path)\n        system.untar_package(tar_path, deps_path, package_name)\n\n\nSomePinned = TypeVar(\"SomePinned\", bound=PinnedPackage)\nSomeUnpinned = TypeVar(\"SomeUnpinned\", bound=\"UnpinnedPackage\")\n\n\nclass UnpinnedPackage(Generic[SomePinned], BasePackage):\n    @classmethod\n    @abc.abstractmethod\n    def from_contract(cls, contract):\n        raise NotImplementedError\n\n    @abc.abstractmethod\n    def incorporate(self: SomeUnpinned, other: SomeUnpinned) -> SomeUnpinned:\n        raise NotImplementedError\n\n    @abc.abstractmethod\n    def resolved(self) -> SomePinned:\n        raise NotImplementedError\n"
  },
  {
    "path": "core/dbt/deps/git.py",
    "content": "import os\nfrom typing import Dict, List, Optional\n\nfrom dbt.clients import git\nfrom dbt.config.project import PartialProject, Project\nfrom dbt.config.renderer import PackageRenderer\nfrom dbt.contracts.project import GitPackage, ProjectPackageMetadata\nfrom dbt.deps.base import PinnedPackage, UnpinnedPackage, get_downloads_path\nfrom dbt.events.types import DepsScrubbedPackageName, DepsUnpinned, EnsureGitInstalled\nfrom dbt.exceptions import MultipleVersionGitDepsError\nfrom dbt.utils import md5\nfrom dbt_common.clients import system\nfrom dbt_common.events.functions import (\n    env_secrets,\n    fire_event,\n    scrub_secrets,\n    warn_or_error,\n)\nfrom dbt_common.exceptions import ExecutableError\n\n\ndef md5sum(s: str):\n    return md5(s, \"latin-1\")\n\n\nclass GitPackageMixin:\n    def __init__(\n        self,\n        git: str,\n        git_unrendered: str,\n        subdirectory: Optional[str] = None,\n    ) -> None:\n        super().__init__()\n        self.git = git\n        self.git_unrendered = git_unrendered\n        self.subdirectory = subdirectory\n\n    @property\n    def name(self):\n        return f\"{self.git}/{self.subdirectory}\" if self.subdirectory else self.git\n\n    def source_type(self) -> str:\n        return \"git\"\n\n\nclass GitPinnedPackage(GitPackageMixin, PinnedPackage):\n    def __init__(\n        self,\n        git: str,\n        git_unrendered: str,\n        revision: str,\n        warn_unpinned: bool = True,\n        subdirectory: Optional[str] = None,\n    ) -> None:\n        super().__init__(git, git_unrendered, subdirectory)\n        self.revision = revision\n        self.warn_unpinned = warn_unpinned\n        self.subdirectory = subdirectory\n        self._checkout_name = md5sum(self.name)\n\n    def to_dict(self) -> Dict[str, str]:\n        git_scrubbed = scrub_secrets(self.git_unrendered, env_secrets())\n        if self.git_unrendered != git_scrubbed:\n            warn_or_error(DepsScrubbedPackageName(package_name=git_scrubbed))\n        ret = {\n            \"git\": git_scrubbed,\n            \"revision\": self.revision,\n        }\n        if self.subdirectory:\n            ret[\"subdirectory\"] = self.subdirectory\n        return ret\n\n    def get_version(self):\n        return self.revision\n\n    def get_subdirectory(self):\n        return self.subdirectory\n\n    def nice_version_name(self):\n        if self.revision == \"HEAD\":\n            return \"HEAD (default revision)\"\n        else:\n            return \"revision {}\".format(self.revision)\n\n    def _checkout(self):\n        \"\"\"Performs a shallow clone of the repository into the downloads\n        directory. This function can be called repeatedly. If the project has\n        already been checked out at this version, it will be a no-op. Returns\n        the path to the checked out directory.\"\"\"\n        try:\n            dir_ = git.clone_and_checkout(\n                self.git,\n                get_downloads_path(),\n                revision=self.revision,\n                dirname=self._checkout_name,\n                subdirectory=self.subdirectory,\n            )\n        except ExecutableError as exc:\n            if exc.cmd and exc.cmd[0] == \"git\":\n                fire_event(EnsureGitInstalled())\n            raise\n        return os.path.join(get_downloads_path(), dir_)\n\n    def _fetch_metadata(\n        self, project: Project, renderer: PackageRenderer\n    ) -> ProjectPackageMetadata:\n        path = self._checkout()\n\n        # raise warning (or error) if this package is not pinned\n        if (self.revision == \"HEAD\" or self.revision in (\"main\", \"master\")) and self.warn_unpinned:\n            warn_or_error(DepsUnpinned(revision=self.revision, git=self.git))\n\n        # now overwrite 'revision' with actual commit SHA\n        self.revision = git.get_current_sha(path)\n\n        partial = PartialProject.from_project_root(path)\n        return partial.render_package_metadata(renderer)\n\n    def install(self, project, renderer):\n        dest_path = self.get_installation_path(project, renderer)\n        if os.path.exists(dest_path):\n            if system.path_is_symlink(dest_path):\n                system.remove_file(dest_path)\n            else:\n                system.rmdir(dest_path)\n\n        system.move(self._checkout(), dest_path)\n\n\nclass GitUnpinnedPackage(GitPackageMixin, UnpinnedPackage[GitPinnedPackage]):\n    def __init__(\n        self,\n        git: str,\n        git_unrendered: str,\n        revisions: List[str],\n        warn_unpinned: bool = True,\n        subdirectory: Optional[str] = None,\n    ) -> None:\n        super().__init__(git, git_unrendered, subdirectory)\n        self.revisions = revisions\n        self.warn_unpinned = warn_unpinned\n        self.subdirectory = subdirectory\n\n    @classmethod\n    def from_contract(cls, contract: GitPackage) -> \"GitUnpinnedPackage\":\n        revisions = contract.get_revisions()\n\n        # we want to map None -> True\n        warn_unpinned = contract.warn_unpinned is not False\n        return cls(\n            git=contract.git,\n            git_unrendered=(contract.unrendered.get(\"git\") or contract.git),\n            revisions=revisions,\n            warn_unpinned=warn_unpinned,\n            subdirectory=contract.subdirectory,\n        )\n\n    def all_names(self) -> List[str]:\n        if self.git.endswith(\".git\"):\n            other = self.git[:-4]\n        else:\n            other = self.git + \".git\"\n\n        if self.subdirectory:\n            git_name = f\"{self.git}/{self.subdirectory}\"\n            other = f\"{other}/{self.subdirectory}\"\n        else:\n            git_name = self.git\n\n        return [git_name, other]\n\n    def incorporate(self, other: \"GitUnpinnedPackage\") -> \"GitUnpinnedPackage\":\n        warn_unpinned = self.warn_unpinned and other.warn_unpinned\n\n        return GitUnpinnedPackage(\n            git=self.git,\n            git_unrendered=self.git_unrendered,\n            revisions=self.revisions + other.revisions,\n            warn_unpinned=warn_unpinned,\n            subdirectory=self.subdirectory,\n        )\n\n    def resolved(self) -> GitPinnedPackage:\n        requested = set(self.revisions)\n        if len(requested) == 0:\n            requested = {\"HEAD\"}\n        elif len(requested) > 1:\n            raise MultipleVersionGitDepsError(self.name, requested)\n        return GitPinnedPackage(\n            git=self.git,\n            git_unrendered=self.git_unrendered,\n            revision=requested.pop(),\n            warn_unpinned=self.warn_unpinned,\n            subdirectory=self.subdirectory,\n        )\n"
  },
  {
    "path": "core/dbt/deps/local.py",
    "content": "import shutil\nfrom typing import Dict\n\nfrom dbt.config.project import PartialProject, Project\nfrom dbt.config.renderer import PackageRenderer\nfrom dbt.contracts.project import LocalPackage, ProjectPackageMetadata\nfrom dbt.deps.base import PinnedPackage, UnpinnedPackage\nfrom dbt.events.types import DepsCreatingLocalSymlink, DepsSymlinkNotAvailable\nfrom dbt_common.clients import system\nfrom dbt_common.events.functions import fire_event\n\n\nclass LocalPackageMixin:\n    def __init__(self, local: str) -> None:\n        super().__init__()\n        self.local = local\n\n    @property\n    def name(self):\n        return self.local\n\n    def source_type(self):\n        return \"local\"\n\n\nclass LocalPinnedPackage(LocalPackageMixin, PinnedPackage):\n    def __init__(self, local: str) -> None:\n        super().__init__(local)\n\n    def to_dict(self) -> Dict[str, str]:\n        return {\n            \"local\": self.local,\n        }\n\n    def get_version(self):\n        return None\n\n    def nice_version_name(self):\n        return \"<local @ {}>\".format(self.local)\n\n    def resolve_path(self, project):\n        return system.resolve_path_from_base(\n            self.local,\n            project.project_root,\n        )\n\n    def _fetch_metadata(\n        self, project: Project, renderer: PackageRenderer\n    ) -> ProjectPackageMetadata:\n        partial = PartialProject.from_project_root(self.resolve_path(project))\n        return partial.render_package_metadata(renderer)\n\n    def install(self, project, renderer):\n        src_path = self.resolve_path(project)\n        dest_path = self.get_installation_path(project, renderer)\n\n        if system.path_exists(dest_path):\n            if not system.path_is_symlink(dest_path):\n                system.rmdir(dest_path)\n            else:\n                system.remove_file(dest_path)\n        try:\n            fire_event(DepsCreatingLocalSymlink())\n            system.make_symlink(src_path, dest_path)\n        except OSError:\n            fire_event(DepsSymlinkNotAvailable())\n            shutil.copytree(src_path, dest_path)\n\n\nclass LocalUnpinnedPackage(LocalPackageMixin, UnpinnedPackage[LocalPinnedPackage]):\n    @classmethod\n    def from_contract(cls, contract: LocalPackage) -> \"LocalUnpinnedPackage\":\n        return cls(local=contract.local)\n\n    def incorporate(self, other: \"LocalUnpinnedPackage\") -> \"LocalUnpinnedPackage\":\n        return LocalUnpinnedPackage(local=self.local)\n\n    def resolved(self) -> LocalPinnedPackage:\n        return LocalPinnedPackage(local=self.local)\n"
  },
  {
    "path": "core/dbt/deps/registry.py",
    "content": "from typing import Dict, List\n\nfrom dbt.clients import registry\nfrom dbt.contracts.project import RegistryPackage, RegistryPackageMetadata\nfrom dbt.deps.base import PinnedPackage, UnpinnedPackage\nfrom dbt.exceptions import (\n    DependencyError,\n    PackageNotFoundError,\n    PackageVersionNotFoundError,\n)\nfrom dbt.flags import get_flags\nfrom dbt.version import get_installed_version\nfrom dbt_common import semver\nfrom dbt_common.exceptions import VersionsNotCompatibleError\n\n\nclass RegistryPackageMixin:\n    def __init__(self, package: str) -> None:\n        super().__init__()\n        self.package = package\n\n    @property\n    def name(self):\n        return self.package\n\n    def source_type(self) -> str:\n        return \"hub\"\n\n\nclass RegistryPinnedPackage(RegistryPackageMixin, PinnedPackage):\n    def __init__(self, package: str, version: str, version_latest: str) -> None:\n        super().__init__(package)\n        self.version = version\n        self.version_latest = version_latest\n\n    @property\n    def name(self):\n        return self.package\n\n    def to_dict(self) -> Dict[str, str]:\n        return {\n            \"package\": self.package,\n            \"version\": self.version,\n        }\n\n    def source_type(self):\n        return \"hub\"\n\n    def get_version(self):\n        return self.version\n\n    def get_version_latest(self):\n        return self.version_latest\n\n    def nice_version_name(self):\n        return \"version {}\".format(self.version)\n\n    def _fetch_metadata(self, project, renderer) -> RegistryPackageMetadata:\n        dct = registry.package_version(self.package, self.version)\n        return RegistryPackageMetadata.from_dict(dct)\n\n    def install(self, project, renderer):\n        self._install(project, renderer)\n\n\nclass RegistryUnpinnedPackage(RegistryPackageMixin, UnpinnedPackage[RegistryPinnedPackage]):\n    def __init__(\n        self, package: str, versions: List[semver.VersionSpecifier], install_prerelease: bool\n    ) -> None:\n        super().__init__(package)\n        self.versions = versions\n        self.install_prerelease = install_prerelease\n\n    def _check_in_index(self):\n        index = registry.index_cached()\n        if self.package not in index:\n            raise PackageNotFoundError(self.package)\n\n    @classmethod\n    def from_contract(cls, contract: RegistryPackage) -> \"RegistryUnpinnedPackage\":\n        raw_version = contract.get_versions()\n\n        versions = [semver.VersionSpecifier.from_version_string(v) for v in raw_version]\n        return cls(\n            package=contract.package,\n            versions=versions,\n            install_prerelease=bool(contract.install_prerelease),\n        )\n\n    def incorporate(self, other: \"RegistryUnpinnedPackage\") -> \"RegistryUnpinnedPackage\":\n        return RegistryUnpinnedPackage(\n            package=self.package,\n            install_prerelease=self.install_prerelease,\n            versions=self.versions + other.versions,\n        )\n\n    def resolved(self) -> RegistryPinnedPackage:\n        self._check_in_index()\n        try:\n            range_ = semver.reduce_versions(*self.versions)\n        except VersionsNotCompatibleError as e:\n            new_msg = \"Version error for package {}: {}\".format(self.name, e)\n            raise DependencyError(new_msg) from e\n        flags = get_flags()\n        should_version_check = bool(flags.VERSION_CHECK)\n        dbt_version = get_installed_version()\n        compatible_versions = registry.get_compatible_versions(\n            self.package, dbt_version, should_version_check\n        )\n        prerelease_version_specified = any(bool(version.prerelease) for version in self.versions)\n        installable = semver.filter_installable(\n            compatible_versions, self.install_prerelease or prerelease_version_specified\n        )\n        if installable:\n            # for now, pick a version and then recurse. later on,\n            # we'll probably want to traverse multiple options\n            # so we can match packages. not going to make a difference\n            # right now.\n            target = semver.resolve_to_specific_version(range_, installable)\n        else:\n            target = None\n        if not target:\n            # raise an exception if no installable target version is found\n            raise PackageVersionNotFoundError(\n                self.package, range_, installable, should_version_check\n            )\n        latest_compatible = installable[-1]\n        return RegistryPinnedPackage(\n            package=self.package, version=target, version_latest=latest_compatible\n        )\n"
  },
  {
    "path": "core/dbt/deps/resolver.py",
    "content": "from dataclasses import dataclass, field\nfrom typing import Any, Dict, Iterator, List, NoReturn, Set, Type\n\nfrom dbt.config import Project\nfrom dbt.config.renderer import PackageRenderer\nfrom dbt.contracts.project import (\n    GitPackage,\n    LocalPackage,\n    PackageSpec,\n    PrivatePackage,\n    RegistryPackage,\n    TarballPackage,\n)\nfrom dbt.deps.base import BasePackage, PinnedPackage, UnpinnedPackage\nfrom dbt.deps.git import GitUnpinnedPackage\nfrom dbt.deps.local import LocalUnpinnedPackage\nfrom dbt.deps.registry import RegistryUnpinnedPackage\nfrom dbt.deps.tarball import TarballUnpinnedPackage\nfrom dbt.exceptions import (\n    DependencyError,\n    DuplicateDependencyToRootError,\n    DuplicateProjectDependencyError,\n    MismatchedDependencyTypeError,\n)\n\n\n@dataclass\nclass PackageListing:\n    packages: Dict[str, UnpinnedPackage] = field(default_factory=dict)\n\n    def __len__(self):\n        return len(self.packages)\n\n    def __bool__(self):\n        return bool(self.packages)\n\n    def _pick_key(self, key: BasePackage) -> str:\n        for name in key.all_names():\n            if name in self.packages:\n                return name\n        return key.name\n\n    def __contains__(self, key: BasePackage):\n        for name in key.all_names():\n            if name in self.packages:\n                return True\n\n    def __getitem__(self, key: BasePackage):\n        key_str: str = self._pick_key(key)\n        return self.packages[key_str]\n\n    def __setitem__(self, key: BasePackage, value):\n        key_str: str = self._pick_key(key)\n        self.packages[key_str] = value\n\n    def _mismatched_types(self, old: UnpinnedPackage, new: UnpinnedPackage) -> NoReturn:\n        raise MismatchedDependencyTypeError(new, old)\n\n    def incorporate(self, package: UnpinnedPackage):\n        key: str = self._pick_key(package)\n        if key in self.packages:\n            existing: UnpinnedPackage = self.packages[key]\n            if not isinstance(existing, type(package)):\n                self._mismatched_types(existing, package)\n            self.packages[key] = existing.incorporate(package)\n        else:\n            self.packages[key] = package\n\n    def update_from(self, src: List[PackageSpec]) -> None:\n        pkg: UnpinnedPackage\n        for contract in src:\n            if isinstance(contract, LocalPackage):\n                pkg = LocalUnpinnedPackage.from_contract(contract)\n            elif isinstance(contract, TarballPackage):\n                pkg = TarballUnpinnedPackage.from_contract(contract)\n            elif isinstance(contract, GitPackage):\n                pkg = GitUnpinnedPackage.from_contract(contract)\n            elif isinstance(contract, PrivatePackage):\n                raise DependencyError(\n                    f'Cannot resolve private package {contract.private} because git provider integration is missing. Please use a \"git\" package instead.'\n                )\n            elif isinstance(contract, RegistryPackage):\n                pkg = RegistryUnpinnedPackage.from_contract(contract)\n            else:\n                raise DependencyError(\"Invalid package type {}\".format(type(contract)))\n            self.incorporate(pkg)\n\n    @classmethod\n    def from_contracts(cls: Type[\"PackageListing\"], src: List[PackageSpec]) -> \"PackageListing\":\n        self = cls({})\n        self.update_from(src)\n        return self\n\n    def resolved(self) -> List[PinnedPackage]:\n        return [p.resolved() for p in self.packages.values()]\n\n    def __iter__(self) -> Iterator[UnpinnedPackage]:\n        return iter(self.packages.values())\n\n\ndef _check_for_duplicate_project_names(\n    final_deps: List[PinnedPackage],\n    project: Project,\n    renderer: PackageRenderer,\n):\n    seen: Set[str] = set()\n    for package in final_deps:\n        project_name = package.get_project_name(project, renderer)\n        if project_name in seen:\n            raise DuplicateProjectDependencyError(project_name)\n        elif project_name == project.project_name:\n            raise DuplicateDependencyToRootError(project_name)\n        seen.add(project_name)\n\n\ndef resolve_packages(\n    packages: List[PackageSpec],\n    project: Project,\n    cli_vars: Dict[str, Any],\n) -> List[PinnedPackage]:\n    pending = PackageListing.from_contracts(packages)\n    final = PackageListing()\n\n    renderer = PackageRenderer(cli_vars)\n\n    while pending:\n        next_pending = PackageListing()\n        # resolve the dependency in question\n        for package in pending:\n            final.incorporate(package)\n            target = final[package].resolved().fetch_metadata(project, renderer)\n            next_pending.update_from(target.packages)\n        pending = next_pending\n\n    resolved = final.resolved()\n    _check_for_duplicate_project_names(resolved, project, renderer)\n    return resolved\n\n\ndef resolve_lock_packages(packages: List[PackageSpec]) -> List[PinnedPackage]:\n    lock_packages = PackageListing.from_contracts(packages)\n    final = PackageListing()\n\n    for package in lock_packages:\n        final.incorporate(package)\n\n    resolved = final.resolved()\n\n    return resolved\n"
  },
  {
    "path": "core/dbt/deps/tarball.py",
    "content": "import functools\nimport os\nfrom pathlib import Path\nfrom typing import Dict\n\nfrom dbt.config.project import PartialProject\nfrom dbt.contracts.project import TarballPackage\nfrom dbt.deps.base import PinnedPackage, UnpinnedPackage, get_downloads_path\nfrom dbt.events.types import DepsScrubbedPackageName\nfrom dbt.exceptions import DependencyError, env_secrets, scrub_secrets\nfrom dbt_common.clients import system\nfrom dbt_common.events.functions import warn_or_error\nfrom dbt_common.utils.connection import connection_exception_retry\n\n\nclass TarballPackageMixin:\n    def __init__(self, tarball: str, tarball_unrendered: str) -> None:\n        super().__init__()\n        self.tarball = tarball\n        self.tarball_unrendered = tarball_unrendered\n\n    @property\n    def name(self):\n        return self.tarball\n\n    def source_type(self) -> str:\n        return \"tarball\"\n\n\nclass TarballPinnedPackage(TarballPackageMixin, PinnedPackage):\n    def __init__(self, tarball: str, tarball_unrendered: str, package: str) -> None:\n        super().__init__(tarball, tarball_unrendered)\n        self.package = package\n        self.version = \"tarball\"\n        self.tar_path = os.path.join(Path(get_downloads_path()), self.package)\n        self.untarred_path = f\"{self.tar_path}_untarred\"\n\n    @property\n    def name(self):\n        return self.package\n\n    def to_dict(self) -> Dict[str, str]:\n        tarball_scrubbed = scrub_secrets(self.tarball_unrendered, env_secrets())\n        if self.tarball_unrendered != tarball_scrubbed:\n            warn_or_error(DepsScrubbedPackageName(package_name=tarball_scrubbed))\n        return {\n            \"tarball\": tarball_scrubbed,\n            \"name\": self.package,\n        }\n\n    def get_version(self):\n        return self.version\n\n    def nice_version_name(self):\n        return f\"tarball (url: {self.tarball})\"\n\n    def _fetch_metadata(self, project, renderer):\n        \"\"\"Download and untar the project and parse metadata from the project folder.\"\"\"\n        download_untar_fn = functools.partial(\n            self.download_and_untar, self.tarball, self.tar_path, self.untarred_path, self.name\n        )\n        connection_exception_retry(download_untar_fn, 5)\n\n        tar_contents = os.listdir(self.untarred_path)\n        if len(tar_contents) != 1:\n            raise DependencyError(\n                f\"Incorrect structure for package extracted from {self.tarball}.\"\n                f\"The extracted package needs to follow the structure {self.name}/<package_contents>.\"\n            )\n        child_folder = os.listdir(self.untarred_path)[0]\n\n        self.untarred_path = os.path.join(self.untarred_path, child_folder)\n        partial = PartialProject.from_project_root(self.untarred_path)\n        metadata = partial.render_package_metadata(renderer)\n        metadata.name = self.package if self.package else metadata.name\n        return metadata\n\n    def install(self, project, renderer):\n        download_untar_fn = functools.partial(\n            self.download_and_untar, self.tarball, self.tar_path, self.untarred_path, self.name\n        )\n        connection_exception_retry(download_untar_fn, 5)\n        dest_path = self.get_installation_path(project, renderer)\n        if os.path.exists(dest_path):\n            if system.path_is_symlink(dest_path):\n                system.remove_file(dest_path)\n            else:\n                system.rmdir(dest_path)\n        system.move(self.untarred_path, dest_path)\n\n\nclass TarballUnpinnedPackage(TarballPackageMixin, UnpinnedPackage[TarballPinnedPackage]):\n    def __init__(\n        self,\n        tarball: str,\n        tarball_unrendered: str,\n        package: str,\n    ) -> None:\n        super().__init__(tarball, tarball_unrendered)\n        # setup to recycle RegistryPinnedPackage fns\n        self.package = package\n        self.version = \"tarball\"\n\n    @classmethod\n    def from_contract(cls, contract: TarballPackage) -> \"TarballUnpinnedPackage\":\n        return cls(\n            tarball=contract.tarball,\n            tarball_unrendered=(contract.unrendered.get(\"tarball\") or contract.tarball),\n            package=contract.name,\n        )\n\n    def incorporate(self, other: \"TarballUnpinnedPackage\") -> \"TarballUnpinnedPackage\":\n        return TarballUnpinnedPackage(\n            tarball=self.tarball, tarball_unrendered=self.tarball_unrendered, package=self.package\n        )\n\n    def resolved(self) -> TarballPinnedPackage:\n        return TarballPinnedPackage(\n            tarball=self.tarball, tarball_unrendered=self.tarball_unrendered, package=self.package\n        )\n"
  },
  {
    "path": "core/dbt/docs/Makefile",
    "content": "# Minimal makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line, and also\n# from the environment for the first two.\nSPHINXOPTS    ?=\nSPHINXBUILD   ?= sphinx-build\nSOURCEDIR     = source\nBUILDDIR      = build\n\n# Put it first so that \"make\" without argument is like \"make help\".\nhelp:\n\t@$(SPHINXBUILD) -M help \"$(SOURCEDIR)\" \"$(BUILDDIR)\" $(SPHINXOPTS) $(O)\n\n.PHONY: help Makefile\n\n# Catch-all target: route all unknown targets to Sphinx using the new\n# \"make mode\" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).\n%: Makefile\n\t@$(SPHINXBUILD) -M $@ \"$(SOURCEDIR)\" \"$(BUILDDIR)\" $(SPHINXOPTS) $(O)\n"
  },
  {
    "path": "core/dbt/docs/build/html/.buildinfo",
    "content": "# Sphinx build info version 1\n# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.\nconfig: 0d25ef12a43286020bcd8b805064f01c\ntags: 645f666f9bcd5a90fca523b33c5a78b7\n"
  },
  {
    "path": "core/dbt/docs/build/html/_sources/index.rst.txt",
    "content": "dbt-core's API documentation\n============================\nHow to invoke dbt commands in python runtime\n--------------------------------------------\n\nRight now the best way to invoke a command from python runtime is to use the `dbtRunner` we exposed\n\n.. code-block:: python\n\n    from dbt.cli.main import dbtRunner\n    cli_args = ['run', '--project-dir', 'jaffle_shop']\n\n    # initialize the dbt runner\n    dbt = dbtRunner()\n    # run the command\n    res, success = dbt.invoke(args)\n\nYou can also pass in pre constructed object into dbtRunner, and we will use those objects instead of loading up from the disk.\n\n.. code-block:: python\n\n    # preload profile and project\n    profile = load_profile(project_dir, {}, 'testing-postgres')\n    project = load_project(project_dir, False, profile, {})\n\n    # initialize the runner with pre-loaded profile and project\n    dbt = dbtRunner(profile=profile, project=project)\n    # run the command, this will use the pre-loaded profile and project instead of loading\n    res, success = dbt.invoke(cli_args)\n\n\nFor the full example code, you can refer to `core/dbt/cli/example.py`\n\nAPI documentation\n-----------------\n\n.. dbt_click:: dbt.cli.main:cli\n"
  },
  {
    "path": "core/dbt/docs/build/html/_static/_sphinx_javascript_frameworks_compat.js",
    "content": "/*\n * _sphinx_javascript_frameworks_compat.js\n * ~~~~~~~~~~\n *\n * Compatability shim for jQuery and underscores.js.\n *\n * WILL BE REMOVED IN Sphinx 6.0\n * xref RemovedInSphinx60Warning\n *\n */\n\n/**\n * select a different prefix for underscore\n */\n$u = _.noConflict();\n\n\n/**\n * small helper function to urldecode strings\n *\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL\n */\njQuery.urldecode = function(x) {\n    if (!x) {\n        return x\n    }\n    return decodeURIComponent(x.replace(/\\+/g, ' '));\n};\n\n/**\n * small helper function to urlencode strings\n */\njQuery.urlencode = encodeURIComponent;\n\n/**\n * This function returns the parsed url parameters of the\n * current request. Multiple values per key are supported,\n * it will always return arrays of strings for the value parts.\n */\njQuery.getQueryParameters = function(s) {\n    if (typeof s === 'undefined')\n        s = document.location.search;\n    var parts = s.substr(s.indexOf('?') + 1).split('&');\n    var result = {};\n    for (var i = 0; i < parts.length; i++) {\n        var tmp = parts[i].split('=', 2);\n        var key = jQuery.urldecode(tmp[0]);\n        var value = jQuery.urldecode(tmp[1]);\n        if (key in result)\n            result[key].push(value);\n        else\n            result[key] = [value];\n    }\n    return result;\n};\n\n/**\n * highlight a given string on a jquery object by wrapping it in\n * span elements with the given class name.\n */\njQuery.fn.highlightText = function(text, className) {\n    function highlight(node, addItems) {\n        if (node.nodeType === 3) {\n            var val = node.nodeValue;\n            var pos = val.toLowerCase().indexOf(text);\n            if (pos >= 0 &&\n                !jQuery(node.parentNode).hasClass(className) &&\n                !jQuery(node.parentNode).hasClass(\"nohighlight\")) {\n                var span;\n                var isInSVG = jQuery(node).closest(\"body, svg, foreignObject\").is(\"svg\");\n                if (isInSVG) {\n                    span = document.createElementNS(\"http://www.w3.org/2000/svg\", \"tspan\");\n                } else {\n                    span = document.createElement(\"span\");\n                    span.className = className;\n                }\n                span.appendChild(document.createTextNode(val.substr(pos, text.length)));\n                node.parentNode.insertBefore(span, node.parentNode.insertBefore(\n                    document.createTextNode(val.substr(pos + text.length)),\n                    node.nextSibling));\n                node.nodeValue = val.substr(0, pos);\n                if (isInSVG) {\n                    var rect = document.createElementNS(\"http://www.w3.org/2000/svg\", \"rect\");\n                    var bbox = node.parentElement.getBBox();\n                    rect.x.baseVal.value = bbox.x;\n                    rect.y.baseVal.value = bbox.y;\n                    rect.width.baseVal.value = bbox.width;\n                    rect.height.baseVal.value = bbox.height;\n                    rect.setAttribute('class', className);\n                    addItems.push({\n                        \"parent\": node.parentNode,\n                        \"target\": rect});\n                }\n            }\n        }\n        else if (!jQuery(node).is(\"button, select, textarea\")) {\n            jQuery.each(node.childNodes, function() {\n                highlight(this, addItems);\n            });\n        }\n    }\n    var addItems = [];\n    var result = this.each(function() {\n        highlight(this, addItems);\n    });\n    for (var i = 0; i < addItems.length; ++i) {\n        jQuery(addItems[i].parent).before(addItems[i].target);\n    }\n    return result;\n};\n\n/*\n * backward compatibility for jQuery.browser\n * This will be supported until firefox bug is fixed.\n */\nif (!jQuery.browser) {\n    jQuery.uaMatch = function(ua) {\n        ua = ua.toLowerCase();\n\n        var match = /(chrome)[ \\/]([\\w.]+)/.exec(ua) ||\n            /(webkit)[ \\/]([\\w.]+)/.exec(ua) ||\n            /(opera)(?:.*version|)[ \\/]([\\w.]+)/.exec(ua) ||\n            /(msie) ([\\w.]+)/.exec(ua) ||\n            ua.indexOf(\"compatible\") < 0 && /(mozilla)(?:.*? rv:([\\w.]+)|)/.exec(ua) ||\n            [];\n\n        return {\n            browser: match[ 1 ] || \"\",\n            version: match[ 2 ] || \"0\"\n        };\n    };\n    jQuery.browser = {};\n    jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true;\n}\n"
  },
  {
    "path": "core/dbt/docs/build/html/_static/alabaster.css",
    "content": "@import url(\"basic.css\");\n\n/* -- page layout ----------------------------------------------------------- */\n\nbody {\n    font-family: Georgia, serif;\n    font-size: 17px;\n    background-color: #fff;\n    color: #000;\n    margin: 0;\n    padding: 0;\n}\n\n\ndiv.document {\n    width: 940px;\n    margin: 30px auto 0 auto;\n}\n\ndiv.documentwrapper {\n    float: left;\n    width: 100%;\n}\n\ndiv.bodywrapper {\n    margin: 0 0 0 220px;\n}\n\ndiv.sphinxsidebar {\n    width: 220px;\n    font-size: 14px;\n    line-height: 1.5;\n}\n\nhr {\n    border: 1px solid #B1B4B6;\n}\n\ndiv.body {\n    background-color: #fff;\n    color: #3E4349;\n    padding: 0 30px 0 30px;\n}\n\ndiv.body > .section {\n    text-align: left;\n}\n\ndiv.footer {\n    width: 940px;\n    margin: 20px auto 30px auto;\n    font-size: 14px;\n    color: #888;\n    text-align: right;\n}\n\ndiv.footer a {\n    color: #888;\n}\n\np.caption {\n    font-family: inherit;\n    font-size: inherit;\n}\n\n\ndiv.relations {\n    display: none;\n}\n\n\ndiv.sphinxsidebar a {\n    color: #444;\n    text-decoration: none;\n    border-bottom: 1px dotted #999;\n}\n\ndiv.sphinxsidebar a:hover {\n    border-bottom: 1px solid #999;\n}\n\ndiv.sphinxsidebarwrapper {\n    padding: 18px 10px;\n}\n\ndiv.sphinxsidebarwrapper p.logo {\n    padding: 0;\n    margin: -10px 0 0 0px;\n    text-align: center;\n}\n\ndiv.sphinxsidebarwrapper h1.logo {\n    margin-top: -10px;\n    text-align: center;\n    margin-bottom: 5px;\n    text-align: left;\n}\n\ndiv.sphinxsidebarwrapper h1.logo-name {\n    margin-top: 0px;\n}\n\ndiv.sphinxsidebarwrapper p.blurb {\n    margin-top: 0;\n    font-style: normal;\n}\n\ndiv.sphinxsidebar h3,\ndiv.sphinxsidebar h4 {\n    font-family: Georgia, serif;\n    color: #444;\n    font-size: 24px;\n    font-weight: normal;\n    margin: 0 0 5px 0;\n    padding: 0;\n}\n\ndiv.sphinxsidebar h4 {\n    font-size: 20px;\n}\n\ndiv.sphinxsidebar h3 a {\n    color: #444;\n}\n\ndiv.sphinxsidebar p.logo a,\ndiv.sphinxsidebar h3 a,\ndiv.sphinxsidebar p.logo a:hover,\ndiv.sphinxsidebar h3 a:hover {\n    border: none;\n}\n\ndiv.sphinxsidebar p {\n    color: #555;\n    margin: 10px 0;\n}\n\ndiv.sphinxsidebar ul {\n    margin: 10px 0;\n    padding: 0;\n    color: #000;\n}\n\ndiv.sphinxsidebar ul li.toctree-l1 > a {\n    font-size: 120%;\n}\n\ndiv.sphinxsidebar ul li.toctree-l2 > a {\n    font-size: 110%;\n}\n\ndiv.sphinxsidebar input {\n    border: 1px solid #CCC;\n    font-family: Georgia, serif;\n    font-size: 1em;\n}\n\ndiv.sphinxsidebar hr {\n    border: none;\n    height: 1px;\n    color: #AAA;\n    background: #AAA;\n\n    text-align: left;\n    margin-left: 0;\n    width: 50%;\n}\n\ndiv.sphinxsidebar .badge {\n    border-bottom: none;\n}\n\ndiv.sphinxsidebar .badge:hover {\n    border-bottom: none;\n}\n\n/* To address an issue with donation coming after search */\ndiv.sphinxsidebar h3.donation {\n    margin-top: 10px;\n}\n\n/* -- body styles ----------------------------------------------------------- */\n\na {\n    color: #004B6B;\n    text-decoration: underline;\n}\n\na:hover {\n    color: #6D4100;\n    text-decoration: underline;\n}\n\ndiv.body h1,\ndiv.body h2,\ndiv.body h3,\ndiv.body h4,\ndiv.body h5,\ndiv.body h6 {\n    font-family: Georgia, serif;\n    font-weight: normal;\n    margin: 30px 0px 10px 0px;\n    padding: 0;\n}\n\ndiv.body h1 { margin-top: 0; padding-top: 0; font-size: 240%; }\ndiv.body h2 { font-size: 180%; }\ndiv.body h3 { font-size: 150%; }\ndiv.body h4 { font-size: 130%; }\ndiv.body h5 { font-size: 100%; }\ndiv.body h6 { font-size: 100%; }\n\na.headerlink {\n    color: #DDD;\n    padding: 0 4px;\n    text-decoration: none;\n}\n\na.headerlink:hover {\n    color: #444;\n    background: #EAEAEA;\n}\n\ndiv.body p, div.body dd, div.body li {\n    line-height: 1.4em;\n}\n\ndiv.admonition {\n    margin: 20px 0px;\n    padding: 10px 30px;\n    background-color: #EEE;\n    border: 1px solid #CCC;\n}\n\ndiv.admonition tt.xref, div.admonition code.xref, div.admonition a tt {\n    background-color: #FBFBFB;\n    border-bottom: 1px solid #fafafa;\n}\n\ndiv.admonition p.admonition-title {\n    font-family: Georgia, serif;\n    font-weight: normal;\n    font-size: 24px;\n    margin: 0 0 10px 0;\n    padding: 0;\n    line-height: 1;\n}\n\ndiv.admonition p.last {\n    margin-bottom: 0;\n}\n\ndiv.highlight {\n    background-color: #fff;\n}\n\ndt:target, .highlight {\n    background: #FAF3E8;\n}\n\ndiv.warning {\n    background-color: #FCC;\n    border: 1px solid #FAA;\n}\n\ndiv.danger {\n    background-color: #FCC;\n    border: 1px solid #FAA;\n    -moz-box-shadow: 2px 2px 4px #D52C2C;\n    -webkit-box-shadow: 2px 2px 4px #D52C2C;\n    box-shadow: 2px 2px 4px #D52C2C;\n}\n\ndiv.error {\n    background-color: #FCC;\n    border: 1px solid #FAA;\n    -moz-box-shadow: 2px 2px 4px #D52C2C;\n    -webkit-box-shadow: 2px 2px 4px #D52C2C;\n    box-shadow: 2px 2px 4px #D52C2C;\n}\n\ndiv.caution {\n    background-color: #FCC;\n    border: 1px solid #FAA;\n}\n\ndiv.attention {\n    background-color: #FCC;\n    border: 1px solid #FAA;\n}\n\ndiv.important {\n    background-color: #EEE;\n    border: 1px solid #CCC;\n}\n\ndiv.note {\n    background-color: #EEE;\n    border: 1px solid #CCC;\n}\n\ndiv.tip {\n    background-color: #EEE;\n    border: 1px solid #CCC;\n}\n\ndiv.hint {\n    background-color: #EEE;\n    border: 1px solid #CCC;\n}\n\ndiv.seealso {\n    background-color: #EEE;\n    border: 1px solid #CCC;\n}\n\ndiv.topic {\n    background-color: #EEE;\n}\n\np.admonition-title {\n    display: inline;\n}\n\np.admonition-title:after {\n    content: \":\";\n}\n\npre, tt, code {\n    font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;\n    font-size: 0.9em;\n}\n\n.hll {\n    background-color: #FFC;\n    margin: 0 -12px;\n    padding: 0 12px;\n    display: block;\n}\n\nimg.screenshot {\n}\n\ntt.descname, tt.descclassname, code.descname, code.descclassname {\n    font-size: 0.95em;\n}\n\ntt.descname, code.descname {\n    padding-right: 0.08em;\n}\n\nimg.screenshot {\n    -moz-box-shadow: 2px 2px 4px #EEE;\n    -webkit-box-shadow: 2px 2px 4px #EEE;\n    box-shadow: 2px 2px 4px #EEE;\n}\n\ntable.docutils {\n    border: 1px solid #888;\n    -moz-box-shadow: 2px 2px 4px #EEE;\n    -webkit-box-shadow: 2px 2px 4px #EEE;\n    box-shadow: 2px 2px 4px #EEE;\n}\n\ntable.docutils td, table.docutils th {\n    border: 1px solid #888;\n    padding: 0.25em 0.7em;\n}\n\ntable.field-list, table.footnote {\n    border: none;\n    -moz-box-shadow: none;\n    -webkit-box-shadow: none;\n    box-shadow: none;\n}\n\ntable.footnote {\n    margin: 15px 0;\n    width: 100%;\n    border: 1px solid #EEE;\n    background: #FDFDFD;\n    font-size: 0.9em;\n}\n\ntable.footnote + table.footnote {\n    margin-top: -15px;\n    border-top: none;\n}\n\ntable.field-list th {\n    padding: 0 0.8em 0 0;\n}\n\ntable.field-list td {\n    padding: 0;\n}\n\ntable.field-list p {\n    margin-bottom: 0.8em;\n}\n\n/* Cloned from\n * https://github.com/sphinx-doc/sphinx/commit/ef60dbfce09286b20b7385333d63a60321784e68\n */\n.field-name {\n    -moz-hyphens: manual;\n    -ms-hyphens: manual;\n    -webkit-hyphens: manual;\n    hyphens: manual;\n}\n\ntable.footnote td.label {\n    width: .1px;\n    padding: 0.3em 0 0.3em 0.5em;\n}\n\ntable.footnote td {\n    padding: 0.3em 0.5em;\n}\n\ndl {\n    margin: 0;\n    padding: 0;\n}\n\ndl dd {\n    margin-left: 30px;\n}\n\nblockquote {\n    margin: 0 0 0 30px;\n    padding: 0;\n}\n\nul, ol {\n    /* Matches the 30px from the narrow-screen \"li > ul\" selector below */\n    margin: 10px 0 10px 30px;\n    padding: 0;\n}\n\npre {\n    background: #EEE;\n    padding: 7px 30px;\n    margin: 15px 0px;\n    line-height: 1.3em;\n}\n\ndiv.viewcode-block:target {\n    background: #ffd;\n}\n\ndl pre, blockquote pre, li pre {\n    margin-left: 0;\n    padding-left: 30px;\n}\n\ntt, code {\n    background-color: #ecf0f3;\n    color: #222;\n    /* padding: 1px 2px; */\n}\n\ntt.xref, code.xref, a tt {\n    background-color: #FBFBFB;\n    border-bottom: 1px solid #fff;\n}\n\na.reference {\n    text-decoration: none;\n    border-bottom: 1px dotted #004B6B;\n}\n\n/* Don't put an underline on images */\na.image-reference, a.image-reference:hover {\n    border-bottom: none;\n}\n\na.reference:hover {\n    border-bottom: 1px solid #6D4100;\n}\n\na.footnote-reference {\n    text-decoration: none;\n    font-size: 0.7em;\n    vertical-align: top;\n    border-bottom: 1px dotted #004B6B;\n}\n\na.footnote-reference:hover {\n    border-bottom: 1px solid #6D4100;\n}\n\na:hover tt, a:hover code {\n    background: #EEE;\n}\n\n\n@media screen and (max-width: 870px) {\n\n    div.sphinxsidebar {\n    \tdisplay: none;\n    }\n\n    div.document {\n       width: 100%;\n\n    }\n\n    div.documentwrapper {\n    \tmargin-left: 0;\n    \tmargin-top: 0;\n    \tmargin-right: 0;\n    \tmargin-bottom: 0;\n    }\n\n    div.bodywrapper {\n    \tmargin-top: 0;\n    \tmargin-right: 0;\n    \tmargin-bottom: 0;\n    \tmargin-left: 0;\n    }\n\n    ul {\n    \tmargin-left: 0;\n    }\n\n\tli > ul {\n        /* Matches the 30px from the \"ul, ol\" selector above */\n\t\tmargin-left: 30px;\n\t}\n\n    .document {\n    \twidth: auto;\n    }\n\n    .footer {\n    \twidth: auto;\n    }\n\n    .bodywrapper {\n    \tmargin: 0;\n    }\n\n    .footer {\n    \twidth: auto;\n    }\n\n    .github {\n        display: none;\n    }\n\n\n\n}\n\n\n\n@media screen and (max-width: 875px) {\n\n    body {\n        margin: 0;\n        padding: 20px 30px;\n    }\n\n    div.documentwrapper {\n        float: none;\n        background: #fff;\n    }\n\n    div.sphinxsidebar {\n        display: block;\n        float: none;\n        width: 102.5%;\n        margin: 50px -30px -20px -30px;\n        padding: 10px 20px;\n        background: #333;\n        color: #FFF;\n    }\n\n    div.sphinxsidebar h3, div.sphinxsidebar h4, div.sphinxsidebar p,\n    div.sphinxsidebar h3 a {\n        color: #fff;\n    }\n\n    div.sphinxsidebar a {\n        color: #AAA;\n    }\n\n    div.sphinxsidebar p.logo {\n        display: none;\n    }\n\n    div.document {\n        width: 100%;\n        margin: 0;\n    }\n\n    div.footer {\n        display: none;\n    }\n\n    div.bodywrapper {\n        margin: 0;\n    }\n\n    div.body {\n        min-height: 0;\n        padding: 0;\n    }\n\n    .rtd_doc_footer {\n        display: none;\n    }\n\n    .document {\n        width: auto;\n    }\n\n    .footer {\n        width: auto;\n    }\n\n    .footer {\n        width: auto;\n    }\n\n    .github {\n        display: none;\n    }\n}\n\n\n/* misc. */\n\n.revsys-inline {\n    display: none!important;\n}\n\n/* Make nested-list/multi-paragraph items look better in Releases changelog\n * pages. Without this, docutils' magical list fuckery causes inconsistent\n * formatting between different release sub-lists.\n */\ndiv#changelog > div.section > ul > li > p:only-child {\n    margin-bottom: 0;\n}\n\n/* Hide fugly table cell borders in ..bibliography:: directive output */\ntable.docutils.citation, table.docutils.citation td, table.docutils.citation th {\n  border: none;\n  /* Below needed in some edge cases; if not applied, bottom shadows appear */\n  -moz-box-shadow: none;\n  -webkit-box-shadow: none;\n  box-shadow: none;\n}\n\n\n/* relbar */\n\n.related {\n    line-height: 30px;\n    width: 100%;\n    font-size: 0.9rem;\n}\n\n.related.top {\n    border-bottom: 1px solid #EEE;\n    margin-bottom: 20px;\n}\n\n.related.bottom {\n    border-top: 1px solid #EEE;\n}\n\n.related ul {\n    padding: 0;\n    margin: 0;\n    list-style: none;\n}\n\n.related li {\n    display: inline;\n}\n\nnav#rellinks {\n    float: right;\n}\n\nnav#rellinks li+li:before {\n    content: \"|\";\n}\n\nnav#breadcrumbs li+li:before {\n    content: \"\\00BB\";\n}\n\n/* Hide certain items when printing */\n@media print {\n    div.related {\n        display: none;\n    }\n}"
  },
  {
    "path": "core/dbt/docs/build/html/_static/basic.css",
    "content": "/*\n * basic.css\n * ~~~~~~~~~\n *\n * Sphinx stylesheet -- basic theme.\n *\n * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.\n * :license: BSD, see LICENSE for details.\n *\n */\n\n/* -- main layout ----------------------------------------------------------- */\n\ndiv.clearer {\n    clear: both;\n}\n\ndiv.section::after {\n    display: block;\n    content: '';\n    clear: left;\n}\n\n/* -- relbar ---------------------------------------------------------------- */\n\ndiv.related {\n    width: 100%;\n    font-size: 90%;\n}\n\ndiv.related h3 {\n    display: none;\n}\n\ndiv.related ul {\n    margin: 0;\n    padding: 0 0 0 10px;\n    list-style: none;\n}\n\ndiv.related li {\n    display: inline;\n}\n\ndiv.related li.right {\n    float: right;\n    margin-right: 5px;\n}\n\n/* -- sidebar --------------------------------------------------------------- */\n\ndiv.sphinxsidebarwrapper {\n    padding: 10px 5px 0 10px;\n}\n\ndiv.sphinxsidebar {\n    float: left;\n    width: 230px;\n    margin-left: -100%;\n    font-size: 90%;\n    word-wrap: break-word;\n    overflow-wrap : break-word;\n}\n\ndiv.sphinxsidebar ul {\n    list-style: none;\n}\n\ndiv.sphinxsidebar ul ul,\ndiv.sphinxsidebar ul.want-points {\n    margin-left: 20px;\n    list-style: square;\n}\n\ndiv.sphinxsidebar ul ul {\n    margin-top: 0;\n    margin-bottom: 0;\n}\n\ndiv.sphinxsidebar form {\n    margin-top: 10px;\n}\n\ndiv.sphinxsidebar input {\n    border: 1px solid #98dbcc;\n    font-family: sans-serif;\n    font-size: 1em;\n}\n\ndiv.sphinxsidebar #searchbox form.search {\n    overflow: hidden;\n}\n\ndiv.sphinxsidebar #searchbox input[type=\"text\"] {\n    float: left;\n    width: 80%;\n    padding: 0.25em;\n    box-sizing: border-box;\n}\n\ndiv.sphinxsidebar #searchbox input[type=\"submit\"] {\n    float: left;\n    width: 20%;\n    border-left: none;\n    padding: 0.25em;\n    box-sizing: border-box;\n}\n\n\nimg {\n    border: 0;\n    max-width: 100%;\n}\n\n/* -- search page ----------------------------------------------------------- */\n\nul.search {\n    margin: 10px 0 0 20px;\n    padding: 0;\n}\n\nul.search li {\n    padding: 5px 0 5px 20px;\n    background-image: url(file.png);\n    background-repeat: no-repeat;\n    background-position: 0 7px;\n}\n\nul.search li a {\n    font-weight: bold;\n}\n\nul.search li p.context {\n    color: #888;\n    margin: 2px 0 0 30px;\n    text-align: left;\n}\n\nul.keywordmatches li.goodmatch a {\n    font-weight: bold;\n}\n\n/* -- index page ------------------------------------------------------------ */\n\ntable.contentstable {\n    width: 90%;\n    margin-left: auto;\n    margin-right: auto;\n}\n\ntable.contentstable p.biglink {\n    line-height: 150%;\n}\n\na.biglink {\n    font-size: 1.3em;\n}\n\nspan.linkdescr {\n    font-style: italic;\n    padding-top: 5px;\n    font-size: 90%;\n}\n\n/* -- general index --------------------------------------------------------- */\n\ntable.indextable {\n    width: 100%;\n}\n\ntable.indextable td {\n    text-align: left;\n    vertical-align: top;\n}\n\ntable.indextable ul {\n    margin-top: 0;\n    margin-bottom: 0;\n    list-style-type: none;\n}\n\ntable.indextable > tbody > tr > td > ul {\n    padding-left: 0em;\n}\n\ntable.indextable tr.pcap {\n    height: 10px;\n}\n\ntable.indextable tr.cap {\n    margin-top: 10px;\n    background-color: #f2f2f2;\n}\n\nimg.toggler {\n    margin-right: 3px;\n    margin-top: 3px;\n    cursor: pointer;\n}\n\ndiv.modindex-jumpbox {\n    border-top: 1px solid #ddd;\n    border-bottom: 1px solid #ddd;\n    margin: 1em 0 1em 0;\n    padding: 0.4em;\n}\n\ndiv.genindex-jumpbox {\n    border-top: 1px solid #ddd;\n    border-bottom: 1px solid #ddd;\n    margin: 1em 0 1em 0;\n    padding: 0.4em;\n}\n\n/* -- domain module index --------------------------------------------------- */\n\ntable.modindextable td {\n    padding: 2px;\n    border-collapse: collapse;\n}\n\n/* -- general body styles --------------------------------------------------- */\n\ndiv.body {\n    min-width: 360px;\n    max-width: 800px;\n}\n\ndiv.body p, div.body dd, div.body li, div.body blockquote {\n    -moz-hyphens: auto;\n    -ms-hyphens: auto;\n    -webkit-hyphens: auto;\n    hyphens: auto;\n}\n\na.headerlink {\n    visibility: hidden;\n}\n\nh1:hover > a.headerlink,\nh2:hover > a.headerlink,\nh3:hover > a.headerlink,\nh4:hover > a.headerlink,\nh5:hover > a.headerlink,\nh6:hover > a.headerlink,\ndt:hover > a.headerlink,\ncaption:hover > a.headerlink,\np.caption:hover > a.headerlink,\ndiv.code-block-caption:hover > a.headerlink {\n    visibility: visible;\n}\n\ndiv.body p.caption {\n    text-align: inherit;\n}\n\ndiv.body td {\n    text-align: left;\n}\n\n.first {\n    margin-top: 0 !important;\n}\n\np.rubric {\n    margin-top: 30px;\n    font-weight: bold;\n}\n\nimg.align-left, figure.align-left, .figure.align-left, object.align-left {\n    clear: left;\n    float: left;\n    margin-right: 1em;\n}\n\nimg.align-right, figure.align-right, .figure.align-right, object.align-right {\n    clear: right;\n    float: right;\n    margin-left: 1em;\n}\n\nimg.align-center, figure.align-center, .figure.align-center, object.align-center {\n  display: block;\n  margin-left: auto;\n  margin-right: auto;\n}\n\nimg.align-default, figure.align-default, .figure.align-default {\n  display: block;\n  margin-left: auto;\n  margin-right: auto;\n}\n\n.align-left {\n    text-align: left;\n}\n\n.align-center {\n    text-align: center;\n}\n\n.align-default {\n    text-align: center;\n}\n\n.align-right {\n    text-align: right;\n}\n\n/* -- sidebars -------------------------------------------------------------- */\n\ndiv.sidebar,\naside.sidebar {\n    margin: 0 0 0.5em 1em;\n    border: 1px solid #ddb;\n    padding: 7px;\n    background-color: #ffe;\n    width: 40%;\n    float: right;\n    clear: right;\n    overflow-x: auto;\n}\n\np.sidebar-title {\n    font-weight: bold;\n}\nnav.contents,\naside.topic,\ndiv.admonition, div.topic, blockquote {\n    clear: left;\n}\n\n/* -- topics ---------------------------------------------------------------- */\nnav.contents,\naside.topic,\ndiv.topic {\n    border: 1px solid #ccc;\n    padding: 7px;\n    margin: 10px 0 10px 0;\n}\n\np.topic-title {\n    font-size: 1.1em;\n    font-weight: bold;\n    margin-top: 10px;\n}\n\n/* -- admonitions ----------------------------------------------------------- */\n\ndiv.admonition {\n    margin-top: 10px;\n    margin-bottom: 10px;\n    padding: 7px;\n}\n\ndiv.admonition dt {\n    font-weight: bold;\n}\n\np.admonition-title {\n    margin: 0px 10px 5px 0px;\n    font-weight: bold;\n}\n\ndiv.body p.centered {\n    text-align: center;\n    margin-top: 25px;\n}\n\n/* -- content of sidebars/topics/admonitions -------------------------------- */\n\ndiv.sidebar > :last-child,\naside.sidebar > :last-child,\nnav.contents > :last-child,\naside.topic > :last-child,\ndiv.topic > :last-child,\ndiv.admonition > :last-child {\n    margin-bottom: 0;\n}\n\ndiv.sidebar::after,\naside.sidebar::after,\nnav.contents::after,\naside.topic::after,\ndiv.topic::after,\ndiv.admonition::after,\nblockquote::after {\n    display: block;\n    content: '';\n    clear: both;\n}\n\n/* -- tables ---------------------------------------------------------------- */\n\ntable.docutils {\n    margin-top: 10px;\n    margin-bottom: 10px;\n    border: 0;\n    border-collapse: collapse;\n}\n\ntable.align-center {\n    margin-left: auto;\n    margin-right: auto;\n}\n\ntable.align-default {\n    margin-left: auto;\n    margin-right: auto;\n}\n\ntable caption span.caption-number {\n    font-style: italic;\n}\n\ntable caption span.caption-text {\n}\n\ntable.docutils td, table.docutils th {\n    padding: 1px 8px 1px 5px;\n    border-top: 0;\n    border-left: 0;\n    border-right: 0;\n    border-bottom: 1px solid #aaa;\n}\n\nth {\n    text-align: left;\n    padding-right: 5px;\n}\n\ntable.citation {\n    border-left: solid 1px gray;\n    margin-left: 1px;\n}\n\ntable.citation td {\n    border-bottom: none;\n}\n\nth > :first-child,\ntd > :first-child {\n    margin-top: 0px;\n}\n\nth > :last-child,\ntd > :last-child {\n    margin-bottom: 0px;\n}\n\n/* -- figures --------------------------------------------------------------- */\n\ndiv.figure, figure {\n    margin: 0.5em;\n    padding: 0.5em;\n}\n\ndiv.figure p.caption, figcaption {\n    padding: 0.3em;\n}\n\ndiv.figure p.caption span.caption-number,\nfigcaption span.caption-number {\n    font-style: italic;\n}\n\ndiv.figure p.caption span.caption-text,\nfigcaption span.caption-text {\n}\n\n/* -- field list styles ----------------------------------------------------- */\n\ntable.field-list td, table.field-list th {\n    border: 0 !important;\n}\n\n.field-list ul {\n    margin: 0;\n    padding-left: 1em;\n}\n\n.field-list p {\n    margin: 0;\n}\n\n.field-name {\n    -moz-hyphens: manual;\n    -ms-hyphens: manual;\n    -webkit-hyphens: manual;\n    hyphens: manual;\n}\n\n/* -- hlist styles ---------------------------------------------------------- */\n\ntable.hlist {\n    margin: 1em 0;\n}\n\ntable.hlist td {\n    vertical-align: top;\n}\n\n/* -- object description styles --------------------------------------------- */\n\n.sig {\n\tfont-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;\n}\n\n.sig-name, code.descname {\n    background-color: transparent;\n    font-weight: bold;\n}\n\n.sig-name {\n\tfont-size: 1.1em;\n}\n\ncode.descname {\n    font-size: 1.2em;\n}\n\n.sig-prename, code.descclassname {\n    background-color: transparent;\n}\n\n.optional {\n    font-size: 1.3em;\n}\n\n.sig-paren {\n    font-size: larger;\n}\n\n.sig-param.n {\n\tfont-style: italic;\n}\n\n/* C++ specific styling */\n\n.sig-inline.c-texpr,\n.sig-inline.cpp-texpr {\n\tfont-family: unset;\n}\n\n.sig.c   .k, .sig.c   .kt,\n.sig.cpp .k, .sig.cpp .kt {\n\tcolor: #0033B3;\n}\n\n.sig.c   .m,\n.sig.cpp .m {\n\tcolor: #1750EB;\n}\n\n.sig.c   .s, .sig.c   .sc,\n.sig.cpp .s, .sig.cpp .sc {\n\tcolor: #067D17;\n}\n\n\n/* -- other body styles ----------------------------------------------------- */\n\nol.arabic {\n    list-style: decimal;\n}\n\nol.loweralpha {\n    list-style: lower-alpha;\n}\n\nol.upperalpha {\n    list-style: upper-alpha;\n}\n\nol.lowerroman {\n    list-style: lower-roman;\n}\n\nol.upperroman {\n    list-style: upper-roman;\n}\n\n:not(li) > ol > li:first-child > :first-child,\n:not(li) > ul > li:first-child > :first-child {\n    margin-top: 0px;\n}\n\n:not(li) > ol > li:last-child > :last-child,\n:not(li) > ul > li:last-child > :last-child {\n    margin-bottom: 0px;\n}\n\nol.simple ol p,\nol.simple ul p,\nul.simple ol p,\nul.simple ul p {\n    margin-top: 0;\n}\n\nol.simple > li:not(:first-child) > p,\nul.simple > li:not(:first-child) > p {\n    margin-top: 0;\n}\n\nol.simple p,\nul.simple p {\n    margin-bottom: 0;\n}\naside.footnote > span,\ndiv.citation > span {\n    float: left;\n}\naside.footnote > span:last-of-type,\ndiv.citation > span:last-of-type {\n  padding-right: 0.5em;\n}\naside.footnote > p {\n  margin-left: 2em;\n}\ndiv.citation > p {\n  margin-left: 4em;\n}\naside.footnote > p:last-of-type,\ndiv.citation > p:last-of-type {\n    margin-bottom: 0em;\n}\naside.footnote > p:last-of-type:after,\ndiv.citation > p:last-of-type:after {\n    content: \"\";\n    clear: both;\n}\n\ndl.field-list {\n    display: grid;\n    grid-template-columns: fit-content(30%) auto;\n}\n\ndl.field-list > dt {\n    font-weight: bold;\n    word-break: break-word;\n    padding-left: 0.5em;\n    padding-right: 5px;\n}\n\ndl.field-list > dd {\n    padding-left: 0.5em;\n    margin-top: 0em;\n    margin-left: 0em;\n    margin-bottom: 0em;\n}\n\ndl {\n    margin-bottom: 15px;\n}\n\ndd > :first-child {\n    margin-top: 0px;\n}\n\ndd ul, dd table {\n    margin-bottom: 10px;\n}\n\ndd {\n    margin-top: 3px;\n    margin-bottom: 10px;\n    margin-left: 30px;\n}\n\ndl > dd:last-child,\ndl > dd:last-child > :last-child {\n    margin-bottom: 0;\n}\n\ndt:target, span.highlighted {\n    background-color: #fbe54e;\n}\n\nrect.highlighted {\n    fill: #fbe54e;\n}\n\ndl.glossary dt {\n    font-weight: bold;\n    font-size: 1.1em;\n}\n\n.versionmodified {\n    font-style: italic;\n}\n\n.system-message {\n    background-color: #fda;\n    padding: 5px;\n    border: 3px solid red;\n}\n\n.footnote:target  {\n    background-color: #ffa;\n}\n\n.line-block {\n    display: block;\n    margin-top: 1em;\n    margin-bottom: 1em;\n}\n\n.line-block .line-block {\n    margin-top: 0;\n    margin-bottom: 0;\n    margin-left: 1.5em;\n}\n\n.guilabel, .menuselection {\n    font-family: sans-serif;\n}\n\n.accelerator {\n    text-decoration: underline;\n}\n\n.classifier {\n    font-style: oblique;\n}\n\n.classifier:before {\n    font-style: normal;\n    margin: 0 0.5em;\n    content: \":\";\n    display: inline-block;\n}\n\nabbr, acronym {\n    border-bottom: dotted 1px;\n    cursor: help;\n}\n\n/* -- code displays --------------------------------------------------------- */\n\npre {\n    overflow: auto;\n    overflow-y: hidden;  /* fixes display issues on Chrome browsers */\n}\n\npre, div[class*=\"highlight-\"] {\n    clear: both;\n}\n\nspan.pre {\n    -moz-hyphens: none;\n    -ms-hyphens: none;\n    -webkit-hyphens: none;\n    hyphens: none;\n    white-space: nowrap;\n}\n\ndiv[class*=\"highlight-\"] {\n    margin: 1em 0;\n}\n\ntd.linenos pre {\n    border: 0;\n    background-color: transparent;\n    color: #aaa;\n}\n\ntable.highlighttable {\n    display: block;\n}\n\ntable.highlighttable tbody {\n    display: block;\n}\n\ntable.highlighttable tr {\n    display: flex;\n}\n\ntable.highlighttable td {\n    margin: 0;\n    padding: 0;\n}\n\ntable.highlighttable td.linenos {\n    padding-right: 0.5em;\n}\n\ntable.highlighttable td.code {\n    flex: 1;\n    overflow: hidden;\n}\n\n.highlight .hll {\n    display: block;\n}\n\ndiv.highlight pre,\ntable.highlighttable pre {\n    margin: 0;\n}\n\ndiv.code-block-caption + div {\n    margin-top: 0;\n}\n\ndiv.code-block-caption {\n    margin-top: 1em;\n    padding: 2px 5px;\n    font-size: small;\n}\n\ndiv.code-block-caption code {\n    background-color: transparent;\n}\n\ntable.highlighttable td.linenos,\nspan.linenos,\ndiv.highlight span.gp {  /* gp: Generic.Prompt */\n  user-select: none;\n  -webkit-user-select: text; /* Safari fallback only */\n  -webkit-user-select: none; /* Chrome/Safari */\n  -moz-user-select: none; /* Firefox */\n  -ms-user-select: none; /* IE10+ */\n}\n\ndiv.code-block-caption span.caption-number {\n    padding: 0.1em 0.3em;\n    font-style: italic;\n}\n\ndiv.code-block-caption span.caption-text {\n}\n\ndiv.literal-block-wrapper {\n    margin: 1em 0;\n}\n\ncode.xref, a code {\n    background-color: transparent;\n    font-weight: bold;\n}\n\nh1 code, h2 code, h3 code, h4 code, h5 code, h6 code {\n    background-color: transparent;\n}\n\n.viewcode-link {\n    float: right;\n}\n\n.viewcode-back {\n    float: right;\n    font-family: sans-serif;\n}\n\ndiv.viewcode-block:target {\n    margin: -1px -10px;\n    padding: 0 10px;\n}\n\n/* -- math display ---------------------------------------------------------- */\n\nimg.math {\n    vertical-align: middle;\n}\n\ndiv.body div.math p {\n    text-align: center;\n}\n\nspan.eqno {\n    float: right;\n}\n\nspan.eqno a.headerlink {\n    position: absolute;\n    z-index: 1;\n}\n\ndiv.math:hover a.headerlink {\n    visibility: visible;\n}\n\n/* -- printout stylesheet --------------------------------------------------- */\n\n@media print {\n    div.document,\n    div.documentwrapper,\n    div.bodywrapper {\n        margin: 0 !important;\n        width: 100%;\n    }\n\n    div.sphinxsidebar,\n    div.related,\n    div.footer,\n    #top-link {\n        display: none;\n    }\n}"
  },
  {
    "path": "core/dbt/docs/build/html/_static/custom.css",
    "content": "/* This file intentionally left blank. */\n"
  },
  {
    "path": "core/dbt/docs/build/html/_static/doctools.js",
    "content": "/*\n * doctools.js\n * ~~~~~~~~~~~\n *\n * Base JavaScript utilities for all Sphinx HTML documentation.\n *\n * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.\n * :license: BSD, see LICENSE for details.\n *\n */\n\"use strict\";\n\nconst BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([\n  \"TEXTAREA\",\n  \"INPUT\",\n  \"SELECT\",\n  \"BUTTON\",\n]);\n\nconst _ready = (callback) => {\n  if (document.readyState !== \"loading\") {\n    callback();\n  } else {\n    document.addEventListener(\"DOMContentLoaded\", callback);\n  }\n};\n\n/**\n * Small JavaScript module for the documentation.\n */\nconst Documentation = {\n  init: () => {\n    Documentation.initDomainIndexTable();\n    Documentation.initOnKeyListeners();\n  },\n\n  /**\n   * i18n support\n   */\n  TRANSLATIONS: {},\n  PLURAL_EXPR: (n) => (n === 1 ? 0 : 1),\n  LOCALE: \"unknown\",\n\n  // gettext and ngettext don't access this so that the functions\n  // can safely bound to a different name (_ = Documentation.gettext)\n  gettext: (string) => {\n    const translated = Documentation.TRANSLATIONS[string];\n    switch (typeof translated) {\n      case \"undefined\":\n        return string; // no translation\n      case \"string\":\n        return translated; // translation exists\n      default:\n        return translated[0]; // (singular, plural) translation tuple exists\n    }\n  },\n\n  ngettext: (singular, plural, n) => {\n    const translated = Documentation.TRANSLATIONS[singular];\n    if (typeof translated !== \"undefined\")\n      return translated[Documentation.PLURAL_EXPR(n)];\n    return n === 1 ? singular : plural;\n  },\n\n  addTranslations: (catalog) => {\n    Object.assign(Documentation.TRANSLATIONS, catalog.messages);\n    Documentation.PLURAL_EXPR = new Function(\n      \"n\",\n      `return (${catalog.plural_expr})`\n    );\n    Documentation.LOCALE = catalog.locale;\n  },\n\n  /**\n   * helper function to focus on search bar\n   */\n  focusSearchBar: () => {\n    document.querySelectorAll(\"input[name=q]\")[0]?.focus();\n  },\n\n  /**\n   * Initialise the domain index toggle buttons\n   */\n  initDomainIndexTable: () => {\n    const toggler = (el) => {\n      const idNumber = el.id.substr(7);\n      const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`);\n      if (el.src.substr(-9) === \"minus.png\") {\n        el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`;\n        toggledRows.forEach((el) => (el.style.display = \"none\"));\n      } else {\n        el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`;\n        toggledRows.forEach((el) => (el.style.display = \"\"));\n      }\n    };\n\n    const togglerElements = document.querySelectorAll(\"img.toggler\");\n    togglerElements.forEach((el) =>\n      el.addEventListener(\"click\", (event) => toggler(event.currentTarget))\n    );\n    togglerElements.forEach((el) => (el.style.display = \"\"));\n    if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler);\n  },\n\n  initOnKeyListeners: () => {\n    // only install a listener if it is really needed\n    if (\n      !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS &&\n      !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS\n    )\n      return;\n\n    document.addEventListener(\"keydown\", (event) => {\n      // bail for input elements\n      if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return;\n      // bail with special keys\n      if (event.altKey || event.ctrlKey || event.metaKey) return;\n\n      if (!event.shiftKey) {\n        switch (event.key) {\n          case \"ArrowLeft\":\n            if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break;\n\n            const prevLink = document.querySelector('link[rel=\"prev\"]');\n            if (prevLink && prevLink.href) {\n              window.location.href = prevLink.href;\n              event.preventDefault();\n            }\n            break;\n          case \"ArrowRight\":\n            if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break;\n\n            const nextLink = document.querySelector('link[rel=\"next\"]');\n            if (nextLink && nextLink.href) {\n              window.location.href = nextLink.href;\n              event.preventDefault();\n            }\n            break;\n        }\n      }\n\n      // some keyboard layouts may need Shift to get /\n      switch (event.key) {\n        case \"/\":\n          if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break;\n          Documentation.focusSearchBar();\n          event.preventDefault();\n      }\n    });\n  },\n};\n\n// quick alias for translations\nconst _ = Documentation.gettext;\n\n_ready(Documentation.init);\n"
  },
  {
    "path": "core/dbt/docs/build/html/_static/documentation_options.js",
    "content": "var DOCUMENTATION_OPTIONS = {\n    URL_ROOT: document.getElementById(\"documentation_options\").getAttribute('data-url_root'),\n    VERSION: '',\n    LANGUAGE: 'en',\n    COLLAPSE_INDEX: false,\n    BUILDER: 'html',\n    FILE_SUFFIX: '.html',\n    LINK_SUFFIX: '.html',\n    HAS_SOURCE: true,\n    SOURCELINK_SUFFIX: '.txt',\n    NAVIGATION_WITH_KEYS: false,\n    SHOW_SEARCH_SUMMARY: true,\n    ENABLE_SEARCH_SHORTCUTS: true,\n};"
  },
  {
    "path": "core/dbt/docs/build/html/_static/jquery-3.6.0.js",
    "content": "/*!\n * jQuery JavaScript Library v3.6.0\n * https://jquery.com/\n *\n * Includes Sizzle.js\n * https://sizzlejs.com/\n *\n * Copyright OpenJS Foundation and other contributors\n * Released under the MIT license\n * https://jquery.org/license\n *\n * Date: 2021-03-02T17:08Z\n */\n( function( global, factory ) {\n\n\t\"use strict\";\n\n\tif ( typeof module === \"object\" && typeof module.exports === \"object\" ) {\n\n\t\t// For CommonJS and CommonJS-like environments where a proper `window`\n\t\t// is present, execute the factory and get jQuery.\n\t\t// For environments that do not have a `window` with a `document`\n\t\t// (such as Node.js), expose a factory as module.exports.\n\t\t// This accentuates the need for the creation of a real `window`.\n\t\t// e.g. var jQuery = require(\"jquery\")(window);\n\t\t// See ticket #14549 for more info.\n\t\tmodule.exports = global.document ?\n\t\t\tfactory( global, true ) :\n\t\t\tfunction( w ) {\n\t\t\t\tif ( !w.document ) {\n\t\t\t\t\tthrow new Error( \"jQuery requires a window with a document\" );\n\t\t\t\t}\n\t\t\t\treturn factory( w );\n\t\t\t};\n\t} else {\n\t\tfactory( global );\n\t}\n\n// Pass this if window is not defined yet\n} )( typeof window !== \"undefined\" ? window : this, function( window, noGlobal ) {\n\n// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1\n// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode\n// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common\n// enough that all such attempts are guarded in a try block.\n\"use strict\";\n\nvar arr = [];\n\nvar getProto = Object.getPrototypeOf;\n\nvar slice = arr.slice;\n\nvar flat = arr.flat ? function( array ) {\n\treturn arr.flat.call( array );\n} : function( array ) {\n\treturn arr.concat.apply( [], array );\n};\n\n\nvar push = arr.push;\n\nvar indexOf = arr.indexOf;\n\nvar class2type = {};\n\nvar toString = class2type.toString;\n\nvar hasOwn = class2type.hasOwnProperty;\n\nvar fnToString = hasOwn.toString;\n\nvar ObjectFunctionString = fnToString.call( Object );\n\nvar support = {};\n\nvar isFunction = function isFunction( obj ) {\n\n\t\t// Support: Chrome <=57, Firefox <=52\n\t\t// In some browsers, typeof returns \"function\" for HTML <object> elements\n\t\t// (i.e., `typeof document.createElement( \"object\" ) === \"function\"`).\n\t\t// We don't want to classify *any* DOM node as a function.\n\t\t// Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5\n\t\t// Plus for old WebKit, typeof returns \"function\" for HTML collections\n\t\t// (e.g., `typeof document.getElementsByTagName(\"div\") === \"function\"`). (gh-4756)\n\t\treturn typeof obj === \"function\" && typeof obj.nodeType !== \"number\" &&\n\t\t\ttypeof obj.item !== \"function\";\n\t};\n\n\nvar isWindow = function isWindow( obj ) {\n\t\treturn obj != null && obj === obj.window;\n\t};\n\n\nvar document = window.document;\n\n\n\n\tvar preservedScriptAttributes = {\n\t\ttype: true,\n\t\tsrc: true,\n\t\tnonce: true,\n\t\tnoModule: true\n\t};\n\n\tfunction DOMEval( code, node, doc ) {\n\t\tdoc = doc || document;\n\n\t\tvar i, val,\n\t\t\tscript = doc.createElement( \"script\" );\n\n\t\tscript.text = code;\n\t\tif ( node ) {\n\t\t\tfor ( i in preservedScriptAttributes ) {\n\n\t\t\t\t// Support: Firefox 64+, Edge 18+\n\t\t\t\t// Some browsers don't support the \"nonce\" property on scripts.\n\t\t\t\t// On the other hand, just using `getAttribute` is not enough as\n\t\t\t\t// the `nonce` attribute is reset to an empty string whenever it\n\t\t\t\t// becomes browsing-context connected.\n\t\t\t\t// See https://github.com/whatwg/html/issues/2369\n\t\t\t\t// See https://html.spec.whatwg.org/#nonce-attributes\n\t\t\t\t// The `node.getAttribute` check was added for the sake of\n\t\t\t\t// `jQuery.globalEval` so that it can fake a nonce-containing node\n\t\t\t\t// via an object.\n\t\t\t\tval = node[ i ] || node.getAttribute && node.getAttribute( i );\n\t\t\t\tif ( val ) {\n\t\t\t\t\tscript.setAttribute( i, val );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tdoc.head.appendChild( script ).parentNode.removeChild( script );\n\t}\n\n\nfunction toType( obj ) {\n\tif ( obj == null ) {\n\t\treturn obj + \"\";\n\t}\n\n\t// Support: Android <=2.3 only (functionish RegExp)\n\treturn typeof obj === \"object\" || typeof obj === \"function\" ?\n\t\tclass2type[ toString.call( obj ) ] || \"object\" :\n\t\ttypeof obj;\n}\n/* global Symbol */\n// Defining this global in .eslintrc.json would create a danger of using the global\n// unguarded in another place, it seems safer to define global only for this module\n\n\n\nvar\n\tversion = \"3.6.0\",\n\n\t// Define a local copy of jQuery\n\tjQuery = function( selector, context ) {\n\n\t\t// The jQuery object is actually just the init constructor 'enhanced'\n\t\t// Need init if jQuery is called (just allow error to be thrown if not included)\n\t\treturn new jQuery.fn.init( selector, context );\n\t};\n\njQuery.fn = jQuery.prototype = {\n\n\t// The current version of jQuery being used\n\tjquery: version,\n\n\tconstructor: jQuery,\n\n\t// The default length of a jQuery object is 0\n\tlength: 0,\n\n\ttoArray: function() {\n\t\treturn slice.call( this );\n\t},\n\n\t// Get the Nth element in the matched element set OR\n\t// Get the whole matched element set as a clean array\n\tget: function( num ) {\n\n\t\t// Return all the elements in a clean array\n\t\tif ( num == null ) {\n\t\t\treturn slice.call( this );\n\t\t}\n\n\t\t// Return just the one element from the set\n\t\treturn num < 0 ? this[ num + this.length ] : this[ num ];\n\t},\n\n\t// Take an array of elements and push it onto the stack\n\t// (returning the new matched element set)\n\tpushStack: function( elems ) {\n\n\t\t// Build a new jQuery matched element set\n\t\tvar ret = jQuery.merge( this.constructor(), elems );\n\n\t\t// Add the old object onto the stack (as a reference)\n\t\tret.prevObject = this;\n\n\t\t// Return the newly-formed element set\n\t\treturn ret;\n\t},\n\n\t// Execute a callback for every element in the matched set.\n\teach: function( callback ) {\n\t\treturn jQuery.each( this, callback );\n\t},\n\n\tmap: function( callback ) {\n\t\treturn this.pushStack( jQuery.map( this, function( elem, i ) {\n\t\t\treturn callback.call( elem, i, elem );\n\t\t} ) );\n\t},\n\n\tslice: function() {\n\t\treturn this.pushStack( slice.apply( this, arguments ) );\n\t},\n\n\tfirst: function() {\n\t\treturn this.eq( 0 );\n\t},\n\n\tlast: function() {\n\t\treturn this.eq( -1 );\n\t},\n\n\teven: function() {\n\t\treturn this.pushStack( jQuery.grep( this, function( _elem, i ) {\n\t\t\treturn ( i + 1 ) % 2;\n\t\t} ) );\n\t},\n\n\todd: function() {\n\t\treturn this.pushStack( jQuery.grep( this, function( _elem, i ) {\n\t\t\treturn i % 2;\n\t\t} ) );\n\t},\n\n\teq: function( i ) {\n\t\tvar len = this.length,\n\t\t\tj = +i + ( i < 0 ? len : 0 );\n\t\treturn this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );\n\t},\n\n\tend: function() {\n\t\treturn this.prevObject || this.constructor();\n\t},\n\n\t// For internal use only.\n\t// Behaves like an Array's method, not like a jQuery method.\n\tpush: push,\n\tsort: arr.sort,\n\tsplice: arr.splice\n};\n\njQuery.extend = jQuery.fn.extend = function() {\n\tvar options, name, src, copy, copyIsArray, clone,\n\t\ttarget = arguments[ 0 ] || {},\n\t\ti = 1,\n\t\tlength = arguments.length,\n\t\tdeep = false;\n\n\t// Handle a deep copy situation\n\tif ( typeof target === \"boolean\" ) {\n\t\tdeep = target;\n\n\t\t// Skip the boolean and the target\n\t\ttarget = arguments[ i ] || {};\n\t\ti++;\n\t}\n\n\t// Handle case when target is a string or something (possible in deep copy)\n\tif ( typeof target !== \"object\" && !isFunction( target ) ) {\n\t\ttarget = {};\n\t}\n\n\t// Extend jQuery itself if only one argument is passed\n\tif ( i === length ) {\n\t\ttarget = this;\n\t\ti--;\n\t}\n\n\tfor ( ; i < length; i++ ) {\n\n\t\t// Only deal with non-null/undefined values\n\t\tif ( ( options = arguments[ i ] ) != null ) {\n\n\t\t\t// Extend the base object\n\t\t\tfor ( name in options ) {\n\t\t\t\tcopy = options[ name ];\n\n\t\t\t\t// Prevent Object.prototype pollution\n\t\t\t\t// Prevent never-ending loop\n\t\t\t\tif ( name === \"__proto__\" || target === copy ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Recurse if we're merging plain objects or arrays\n\t\t\t\tif ( deep && copy && ( jQuery.isPlainObject( copy ) ||\n\t\t\t\t\t( copyIsArray = Array.isArray( copy ) ) ) ) {\n\t\t\t\t\tsrc = target[ name ];\n\n\t\t\t\t\t// Ensure proper type for the source value\n\t\t\t\t\tif ( copyIsArray && !Array.isArray( src ) ) {\n\t\t\t\t\t\tclone = [];\n\t\t\t\t\t} else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) {\n\t\t\t\t\t\tclone = {};\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclone = src;\n\t\t\t\t\t}\n\t\t\t\t\tcopyIsArray = false;\n\n\t\t\t\t\t// Never move original objects, clone them\n\t\t\t\t\ttarget[ name ] = jQuery.extend( deep, clone, copy );\n\n\t\t\t\t// Don't bring in undefined values\n\t\t\t\t} else if ( copy !== undefined ) {\n\t\t\t\t\ttarget[ name ] = copy;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return the modified object\n\treturn target;\n};\n\njQuery.extend( {\n\n\t// Unique for each copy of jQuery on the page\n\texpando: \"jQuery\" + ( version + Math.random() ).replace( /\\D/g, \"\" ),\n\n\t// Assume jQuery is ready without the ready module\n\tisReady: true,\n\n\terror: function( msg ) {\n\t\tthrow new Error( msg );\n\t},\n\n\tnoop: function() {},\n\n\tisPlainObject: function( obj ) {\n\t\tvar proto, Ctor;\n\n\t\t// Detect obvious negatives\n\t\t// Use toString instead of jQuery.type to catch host objects\n\t\tif ( !obj || toString.call( obj ) !== \"[object Object]\" ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tproto = getProto( obj );\n\n\t\t// Objects with no prototype (e.g., `Object.create( null )`) are plain\n\t\tif ( !proto ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Objects with prototype are plain iff they were constructed by a global Object function\n\t\tCtor = hasOwn.call( proto, \"constructor\" ) && proto.constructor;\n\t\treturn typeof Ctor === \"function\" && fnToString.call( Ctor ) === ObjectFunctionString;\n\t},\n\n\tisEmptyObject: function( obj ) {\n\t\tvar name;\n\n\t\tfor ( name in obj ) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t},\n\n\t// Evaluates a script in a provided context; falls back to the global one\n\t// if not specified.\n\tglobalEval: function( code, options, doc ) {\n\t\tDOMEval( code, { nonce: options && options.nonce }, doc );\n\t},\n\n\teach: function( obj, callback ) {\n\t\tvar length, i = 0;\n\n\t\tif ( isArrayLike( obj ) ) {\n\t\t\tlength = obj.length;\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tif ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tfor ( i in obj ) {\n\t\t\t\tif ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn obj;\n\t},\n\n\t// results is for internal usage only\n\tmakeArray: function( arr, results ) {\n\t\tvar ret = results || [];\n\n\t\tif ( arr != null ) {\n\t\t\tif ( isArrayLike( Object( arr ) ) ) {\n\t\t\t\tjQuery.merge( ret,\n\t\t\t\t\ttypeof arr === \"string\" ?\n\t\t\t\t\t\t[ arr ] : arr\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tpush.call( ret, arr );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tinArray: function( elem, arr, i ) {\n\t\treturn arr == null ? -1 : indexOf.call( arr, elem, i );\n\t},\n\n\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t// push.apply(_, arraylike) throws on ancient WebKit\n\tmerge: function( first, second ) {\n\t\tvar len = +second.length,\n\t\t\tj = 0,\n\t\t\ti = first.length;\n\n\t\tfor ( ; j < len; j++ ) {\n\t\t\tfirst[ i++ ] = second[ j ];\n\t\t}\n\n\t\tfirst.length = i;\n\n\t\treturn first;\n\t},\n\n\tgrep: function( elems, callback, invert ) {\n\t\tvar callbackInverse,\n\t\t\tmatches = [],\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tcallbackExpect = !invert;\n\n\t\t// Go through the array, only saving the items\n\t\t// that pass the validator function\n\t\tfor ( ; i < length; i++ ) {\n\t\t\tcallbackInverse = !callback( elems[ i ], i );\n\t\t\tif ( callbackInverse !== callbackExpect ) {\n\t\t\t\tmatches.push( elems[ i ] );\n\t\t\t}\n\t\t}\n\n\t\treturn matches;\n\t},\n\n\t// arg is for internal usage only\n\tmap: function( elems, callback, arg ) {\n\t\tvar length, value,\n\t\t\ti = 0,\n\t\t\tret = [];\n\n\t\t// Go through the array, translating each of the items to their new values\n\t\tif ( isArrayLike( elems ) ) {\n\t\t\tlength = elems.length;\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Go through every key on the object,\n\t\t} else {\n\t\t\tfor ( i in elems ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Flatten any nested arrays\n\t\treturn flat( ret );\n\t},\n\n\t// A global GUID counter for objects\n\tguid: 1,\n\n\t// jQuery.support is not used in Core but other projects attach their\n\t// properties to it so it needs to exist.\n\tsupport: support\n} );\n\nif ( typeof Symbol === \"function\" ) {\n\tjQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];\n}\n\n// Populate the class2type map\njQuery.each( \"Boolean Number String Function Array Date RegExp Object Error Symbol\".split( \" \" ),\n\tfunction( _i, name ) {\n\t\tclass2type[ \"[object \" + name + \"]\" ] = name.toLowerCase();\n\t} );\n\nfunction isArrayLike( obj ) {\n\n\t// Support: real iOS 8.2 only (not reproducible in simulator)\n\t// `in` check used to prevent JIT error (gh-2145)\n\t// hasOwn isn't used here due to false negatives\n\t// regarding Nodelist length in IE\n\tvar length = !!obj && \"length\" in obj && obj.length,\n\t\ttype = toType( obj );\n\n\tif ( isFunction( obj ) || isWindow( obj ) ) {\n\t\treturn false;\n\t}\n\n\treturn type === \"array\" || length === 0 ||\n\t\ttypeof length === \"number\" && length > 0 && ( length - 1 ) in obj;\n}\nvar Sizzle =\n/*!\n * Sizzle CSS Selector Engine v2.3.6\n * https://sizzlejs.com/\n *\n * Copyright JS Foundation and other contributors\n * Released under the MIT license\n * https://js.foundation/\n *\n * Date: 2021-02-16\n */\n( function( window ) {\nvar i,\n\tsupport,\n\tExpr,\n\tgetText,\n\tisXML,\n\ttokenize,\n\tcompile,\n\tselect,\n\toutermostContext,\n\tsortInput,\n\thasDuplicate,\n\n\t// Local document vars\n\tsetDocument,\n\tdocument,\n\tdocElem,\n\tdocumentIsHTML,\n\trbuggyQSA,\n\trbuggyMatches,\n\tmatches,\n\tcontains,\n\n\t// Instance-specific data\n\texpando = \"sizzle\" + 1 * new Date(),\n\tpreferredDoc = window.document,\n\tdirruns = 0,\n\tdone = 0,\n\tclassCache = createCache(),\n\ttokenCache = createCache(),\n\tcompilerCache = createCache(),\n\tnonnativeSelectorCache = createCache(),\n\tsortOrder = function( a, b ) {\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t}\n\t\treturn 0;\n\t},\n\n\t// Instance methods\n\thasOwn = ( {} ).hasOwnProperty,\n\tarr = [],\n\tpop = arr.pop,\n\tpushNative = arr.push,\n\tpush = arr.push,\n\tslice = arr.slice,\n\n\t// Use a stripped-down indexOf as it's faster than native\n\t// https://jsperf.com/thor-indexof-vs-for/5\n\tindexOf = function( list, elem ) {\n\t\tvar i = 0,\n\t\t\tlen = list.length;\n\t\tfor ( ; i < len; i++ ) {\n\t\t\tif ( list[ i ] === elem ) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t},\n\n\tbooleans = \"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|\" +\n\t\t\"ismap|loop|multiple|open|readonly|required|scoped\",\n\n\t// Regular expressions\n\n\t// http://www.w3.org/TR/css3-selectors/#whitespace\n\twhitespace = \"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",\n\n\t// https://www.w3.org/TR/css-syntax-3/#ident-token-diagram\n\tidentifier = \"(?:\\\\\\\\[\\\\da-fA-F]{1,6}\" + whitespace +\n\t\t\"?|\\\\\\\\[^\\\\r\\\\n\\\\f]|[\\\\w-]|[^\\0-\\\\x7f])+\",\n\n\t// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors\n\tattributes = \"\\\\[\" + whitespace + \"*(\" + identifier + \")(?:\" + whitespace +\n\n\t\t// Operator (capture 2)\n\t\t\"*([*^$|!~]?=)\" + whitespace +\n\n\t\t// \"Attribute values must be CSS identifiers [capture 5]\n\t\t// or strings [capture 3 or capture 4]\"\n\t\t\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\" + identifier + \"))|)\" +\n\t\twhitespace + \"*\\\\]\",\n\n\tpseudos = \":(\" + identifier + \")(?:\\\\((\" +\n\n\t\t// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:\n\t\t// 1. quoted (capture 3; capture 4 or capture 5)\n\t\t\"('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|\" +\n\n\t\t// 2. simple (capture 6)\n\t\t\"((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\" + attributes + \")*)|\" +\n\n\t\t// 3. anything else (capture 2)\n\t\t\".*\" +\n\t\t\")\\\\)|)\",\n\n\t// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\n\trwhitespace = new RegExp( whitespace + \"+\", \"g\" ),\n\trtrim = new RegExp( \"^\" + whitespace + \"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\" +\n\t\twhitespace + \"+$\", \"g\" ),\n\n\trcomma = new RegExp( \"^\" + whitespace + \"*,\" + whitespace + \"*\" ),\n\trcombinators = new RegExp( \"^\" + whitespace + \"*([>+~]|\" + whitespace + \")\" + whitespace +\n\t\t\"*\" ),\n\trdescend = new RegExp( whitespace + \"|>\" ),\n\n\trpseudo = new RegExp( pseudos ),\n\tridentifier = new RegExp( \"^\" + identifier + \"$\" ),\n\n\tmatchExpr = {\n\t\t\"ID\": new RegExp( \"^#(\" + identifier + \")\" ),\n\t\t\"CLASS\": new RegExp( \"^\\\\.(\" + identifier + \")\" ),\n\t\t\"TAG\": new RegExp( \"^(\" + identifier + \"|[*])\" ),\n\t\t\"ATTR\": new RegExp( \"^\" + attributes ),\n\t\t\"PSEUDO\": new RegExp( \"^\" + pseudos ),\n\t\t\"CHILD\": new RegExp( \"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\" +\n\t\t\twhitespace + \"*(even|odd|(([+-]|)(\\\\d*)n|)\" + whitespace + \"*(?:([+-]|)\" +\n\t\t\twhitespace + \"*(\\\\d+)|))\" + whitespace + \"*\\\\)|)\", \"i\" ),\n\t\t\"bool\": new RegExp( \"^(?:\" + booleans + \")$\", \"i\" ),\n\n\t\t// For use in libraries implementing .is()\n\t\t// We use this for POS matching in `select`\n\t\t\"needsContext\": new RegExp( \"^\" + whitespace +\n\t\t\t\"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\" + whitespace +\n\t\t\t\"*((?:-\\\\d)?\\\\d*)\" + whitespace + \"*\\\\)|)(?=[^-]|$)\", \"i\" )\n\t},\n\n\trhtml = /HTML$/i,\n\trinputs = /^(?:input|select|textarea|button)$/i,\n\trheader = /^h\\d$/i,\n\n\trnative = /^[^{]+\\{\\s*\\[native \\w/,\n\n\t// Easily-parseable/retrievable ID or TAG or CLASS selectors\n\trquickExpr = /^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,\n\n\trsibling = /[+~]/,\n\n\t// CSS escapes\n\t// http://www.w3.org/TR/CSS21/syndata.html#escaped-characters\n\trunescape = new RegExp( \"\\\\\\\\[\\\\da-fA-F]{1,6}\" + whitespace + \"?|\\\\\\\\([^\\\\r\\\\n\\\\f])\", \"g\" ),\n\tfunescape = function( escape, nonHex ) {\n\t\tvar high = \"0x\" + escape.slice( 1 ) - 0x10000;\n\n\t\treturn nonHex ?\n\n\t\t\t// Strip the backslash prefix from a non-hex escape sequence\n\t\t\tnonHex :\n\n\t\t\t// Replace a hexadecimal escape sequence with the encoded Unicode code point\n\t\t\t// Support: IE <=11+\n\t\t\t// For values outside the Basic Multilingual Plane (BMP), manually construct a\n\t\t\t// surrogate pair\n\t\t\thigh < 0 ?\n\t\t\t\tString.fromCharCode( high + 0x10000 ) :\n\t\t\t\tString.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );\n\t},\n\n\t// CSS string/identifier serialization\n\t// https://drafts.csswg.org/cssom/#common-serializing-idioms\n\trcssescape = /([\\0-\\x1f\\x7f]|^-?\\d)|^-$|[^\\0-\\x1f\\x7f-\\uFFFF\\w-]/g,\n\tfcssescape = function( ch, asCodePoint ) {\n\t\tif ( asCodePoint ) {\n\n\t\t\t// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER\n\t\t\tif ( ch === \"\\0\" ) {\n\t\t\t\treturn \"\\uFFFD\";\n\t\t\t}\n\n\t\t\t// Control characters and (dependent upon position) numbers get escaped as code points\n\t\t\treturn ch.slice( 0, -1 ) + \"\\\\\" +\n\t\t\t\tch.charCodeAt( ch.length - 1 ).toString( 16 ) + \" \";\n\t\t}\n\n\t\t// Other potentially-special ASCII characters get backslash-escaped\n\t\treturn \"\\\\\" + ch;\n\t},\n\n\t// Used for iframes\n\t// See setDocument()\n\t// Removing the function wrapper causes a \"Permission Denied\"\n\t// error in IE\n\tunloadHandler = function() {\n\t\tsetDocument();\n\t},\n\n\tinDisabledFieldset = addCombinator(\n\t\tfunction( elem ) {\n\t\t\treturn elem.disabled === true && elem.nodeName.toLowerCase() === \"fieldset\";\n\t\t},\n\t\t{ dir: \"parentNode\", next: \"legend\" }\n\t);\n\n// Optimize for push.apply( _, NodeList )\ntry {\n\tpush.apply(\n\t\t( arr = slice.call( preferredDoc.childNodes ) ),\n\t\tpreferredDoc.childNodes\n\t);\n\n\t// Support: Android<4.0\n\t// Detect silently failing push.apply\n\t// eslint-disable-next-line no-unused-expressions\n\tarr[ preferredDoc.childNodes.length ].nodeType;\n} catch ( e ) {\n\tpush = { apply: arr.length ?\n\n\t\t// Leverage slice if possible\n\t\tfunction( target, els ) {\n\t\t\tpushNative.apply( target, slice.call( els ) );\n\t\t} :\n\n\t\t// Support: IE<9\n\t\t// Otherwise append directly\n\t\tfunction( target, els ) {\n\t\t\tvar j = target.length,\n\t\t\t\ti = 0;\n\n\t\t\t// Can't trust NodeList.length\n\t\t\twhile ( ( target[ j++ ] = els[ i++ ] ) ) {}\n\t\t\ttarget.length = j - 1;\n\t\t}\n\t};\n}\n\nfunction Sizzle( selector, context, results, seed ) {\n\tvar m, i, elem, nid, match, groups, newSelector,\n\t\tnewContext = context && context.ownerDocument,\n\n\t\t// nodeType defaults to 9, since context defaults to document\n\t\tnodeType = context ? context.nodeType : 9;\n\n\tresults = results || [];\n\n\t// Return early from calls with invalid selector or context\n\tif ( typeof selector !== \"string\" || !selector ||\n\t\tnodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {\n\n\t\treturn results;\n\t}\n\n\t// Try to shortcut find operations (as opposed to filters) in HTML documents\n\tif ( !seed ) {\n\t\tsetDocument( context );\n\t\tcontext = context || document;\n\n\t\tif ( documentIsHTML ) {\n\n\t\t\t// If the selector is sufficiently simple, try using a \"get*By*\" DOM method\n\t\t\t// (excepting DocumentFragment context, where the methods don't exist)\n\t\t\tif ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) {\n\n\t\t\t\t// ID selector\n\t\t\t\tif ( ( m = match[ 1 ] ) ) {\n\n\t\t\t\t\t// Document context\n\t\t\t\t\tif ( nodeType === 9 ) {\n\t\t\t\t\t\tif ( ( elem = context.getElementById( m ) ) ) {\n\n\t\t\t\t\t\t\t// Support: IE, Opera, Webkit\n\t\t\t\t\t\t\t// TODO: identify versions\n\t\t\t\t\t\t\t// getElementById can match elements by name instead of ID\n\t\t\t\t\t\t\tif ( elem.id === m ) {\n\t\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t// Element context\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// Support: IE, Opera, Webkit\n\t\t\t\t\t\t// TODO: identify versions\n\t\t\t\t\t\t// getElementById can match elements by name instead of ID\n\t\t\t\t\t\tif ( newContext && ( elem = newContext.getElementById( m ) ) &&\n\t\t\t\t\t\t\tcontains( context, elem ) &&\n\t\t\t\t\t\t\telem.id === m ) {\n\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t// Type selector\n\t\t\t\t} else if ( match[ 2 ] ) {\n\t\t\t\t\tpush.apply( results, context.getElementsByTagName( selector ) );\n\t\t\t\t\treturn results;\n\n\t\t\t\t// Class selector\n\t\t\t\t} else if ( ( m = match[ 3 ] ) && support.getElementsByClassName &&\n\t\t\t\t\tcontext.getElementsByClassName ) {\n\n\t\t\t\t\tpush.apply( results, context.getElementsByClassName( m ) );\n\t\t\t\t\treturn results;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Take advantage of querySelectorAll\n\t\t\tif ( support.qsa &&\n\t\t\t\t!nonnativeSelectorCache[ selector + \" \" ] &&\n\t\t\t\t( !rbuggyQSA || !rbuggyQSA.test( selector ) ) &&\n\n\t\t\t\t// Support: IE 8 only\n\t\t\t\t// Exclude object elements\n\t\t\t\t( nodeType !== 1 || context.nodeName.toLowerCase() !== \"object\" ) ) {\n\n\t\t\t\tnewSelector = selector;\n\t\t\t\tnewContext = context;\n\n\t\t\t\t// qSA considers elements outside a scoping root when evaluating child or\n\t\t\t\t// descendant combinators, which is not what we want.\n\t\t\t\t// In such cases, we work around the behavior by prefixing every selector in the\n\t\t\t\t// list with an ID selector referencing the scope context.\n\t\t\t\t// The technique has to be used as well when a leading combinator is used\n\t\t\t\t// as such selectors are not recognized by querySelectorAll.\n\t\t\t\t// Thanks to Andrew Dupont for this technique.\n\t\t\t\tif ( nodeType === 1 &&\n\t\t\t\t\t( rdescend.test( selector ) || rcombinators.test( selector ) ) ) {\n\n\t\t\t\t\t// Expand context for sibling selectors\n\t\t\t\t\tnewContext = rsibling.test( selector ) && testContext( context.parentNode ) ||\n\t\t\t\t\t\tcontext;\n\n\t\t\t\t\t// We can use :scope instead of the ID hack if the browser\n\t\t\t\t\t// supports it & if we're not changing the context.\n\t\t\t\t\tif ( newContext !== context || !support.scope ) {\n\n\t\t\t\t\t\t// Capture the context ID, setting it first if necessary\n\t\t\t\t\t\tif ( ( nid = context.getAttribute( \"id\" ) ) ) {\n\t\t\t\t\t\t\tnid = nid.replace( rcssescape, fcssescape );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tcontext.setAttribute( \"id\", ( nid = expando ) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prefix every selector in the list\n\t\t\t\t\tgroups = tokenize( selector );\n\t\t\t\t\ti = groups.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tgroups[ i ] = ( nid ? \"#\" + nid : \":scope\" ) + \" \" +\n\t\t\t\t\t\t\ttoSelector( groups[ i ] );\n\t\t\t\t\t}\n\t\t\t\t\tnewSelector = groups.join( \",\" );\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\tpush.apply( results,\n\t\t\t\t\t\tnewContext.querySelectorAll( newSelector )\n\t\t\t\t\t);\n\t\t\t\t\treturn results;\n\t\t\t\t} catch ( qsaError ) {\n\t\t\t\t\tnonnativeSelectorCache( selector, true );\n\t\t\t\t} finally {\n\t\t\t\t\tif ( nid === expando ) {\n\t\t\t\t\t\tcontext.removeAttribute( \"id\" );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// All others\n\treturn select( selector.replace( rtrim, \"$1\" ), context, results, seed );\n}\n\n/**\n * Create key-value caches of limited size\n * @returns {function(string, object)} Returns the Object data after storing it on itself with\n *\tproperty name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)\n *\tdeleting the oldest entry\n */\nfunction createCache() {\n\tvar keys = [];\n\n\tfunction cache( key, value ) {\n\n\t\t// Use (key + \" \") to avoid collision with native prototype properties (see Issue #157)\n\t\tif ( keys.push( key + \" \" ) > Expr.cacheLength ) {\n\n\t\t\t// Only keep the most recent entries\n\t\t\tdelete cache[ keys.shift() ];\n\t\t}\n\t\treturn ( cache[ key + \" \" ] = value );\n\t}\n\treturn cache;\n}\n\n/**\n * Mark a function for special use by Sizzle\n * @param {Function} fn The function to mark\n */\nfunction markFunction( fn ) {\n\tfn[ expando ] = true;\n\treturn fn;\n}\n\n/**\n * Support testing using an element\n * @param {Function} fn Passed the created element and returns a boolean result\n */\nfunction assert( fn ) {\n\tvar el = document.createElement( \"fieldset\" );\n\n\ttry {\n\t\treturn !!fn( el );\n\t} catch ( e ) {\n\t\treturn false;\n\t} finally {\n\n\t\t// Remove from its parent by default\n\t\tif ( el.parentNode ) {\n\t\t\tel.parentNode.removeChild( el );\n\t\t}\n\n\t\t// release memory in IE\n\t\tel = null;\n\t}\n}\n\n/**\n * Adds the same handler for all of the specified attrs\n * @param {String} attrs Pipe-separated list of attributes\n * @param {Function} handler The method that will be applied\n */\nfunction addHandle( attrs, handler ) {\n\tvar arr = attrs.split( \"|\" ),\n\t\ti = arr.length;\n\n\twhile ( i-- ) {\n\t\tExpr.attrHandle[ arr[ i ] ] = handler;\n\t}\n}\n\n/**\n * Checks document order of two siblings\n * @param {Element} a\n * @param {Element} b\n * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b\n */\nfunction siblingCheck( a, b ) {\n\tvar cur = b && a,\n\t\tdiff = cur && a.nodeType === 1 && b.nodeType === 1 &&\n\t\t\ta.sourceIndex - b.sourceIndex;\n\n\t// Use IE sourceIndex if available on both nodes\n\tif ( diff ) {\n\t\treturn diff;\n\t}\n\n\t// Check if b follows a\n\tif ( cur ) {\n\t\twhile ( ( cur = cur.nextSibling ) ) {\n\t\t\tif ( cur === b ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn a ? 1 : -1;\n}\n\n/**\n * Returns a function to use in pseudos for input types\n * @param {String} type\n */\nfunction createInputPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn name === \"input\" && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for buttons\n * @param {String} type\n */\nfunction createButtonPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn ( name === \"input\" || name === \"button\" ) && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for :enabled/:disabled\n * @param {Boolean} disabled true for :disabled; false for :enabled\n */\nfunction createDisabledPseudo( disabled ) {\n\n\t// Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable\n\treturn function( elem ) {\n\n\t\t// Only certain elements can match :enabled or :disabled\n\t\t// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled\n\t\t// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled\n\t\tif ( \"form\" in elem ) {\n\n\t\t\t// Check for inherited disabledness on relevant non-disabled elements:\n\t\t\t// * listed form-associated elements in a disabled fieldset\n\t\t\t//   https://html.spec.whatwg.org/multipage/forms.html#category-listed\n\t\t\t//   https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled\n\t\t\t// * option elements in a disabled optgroup\n\t\t\t//   https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled\n\t\t\t// All such elements have a \"form\" property.\n\t\t\tif ( elem.parentNode && elem.disabled === false ) {\n\n\t\t\t\t// Option elements defer to a parent optgroup if present\n\t\t\t\tif ( \"label\" in elem ) {\n\t\t\t\t\tif ( \"label\" in elem.parentNode ) {\n\t\t\t\t\t\treturn elem.parentNode.disabled === disabled;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn elem.disabled === disabled;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Support: IE 6 - 11\n\t\t\t\t// Use the isDisabled shortcut property to check for disabled fieldset ancestors\n\t\t\t\treturn elem.isDisabled === disabled ||\n\n\t\t\t\t\t// Where there is no isDisabled, check manually\n\t\t\t\t\t/* jshint -W018 */\n\t\t\t\t\telem.isDisabled !== !disabled &&\n\t\t\t\t\tinDisabledFieldset( elem ) === disabled;\n\t\t\t}\n\n\t\t\treturn elem.disabled === disabled;\n\n\t\t// Try to winnow out elements that can't be disabled before trusting the disabled property.\n\t\t// Some victims get caught in our net (label, legend, menu, track), but it shouldn't\n\t\t// even exist on them, let alone have a boolean value.\n\t\t} else if ( \"label\" in elem ) {\n\t\t\treturn elem.disabled === disabled;\n\t\t}\n\n\t\t// Remaining elements are neither :enabled nor :disabled\n\t\treturn false;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for positionals\n * @param {Function} fn\n */\nfunction createPositionalPseudo( fn ) {\n\treturn markFunction( function( argument ) {\n\t\targument = +argument;\n\t\treturn markFunction( function( seed, matches ) {\n\t\t\tvar j,\n\t\t\t\tmatchIndexes = fn( [], seed.length, argument ),\n\t\t\t\ti = matchIndexes.length;\n\n\t\t\t// Match elements found at the specified indexes\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( seed[ ( j = matchIndexes[ i ] ) ] ) {\n\t\t\t\t\tseed[ j ] = !( matches[ j ] = seed[ j ] );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t} );\n}\n\n/**\n * Checks a node for validity as a Sizzle context\n * @param {Element|Object=} context\n * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value\n */\nfunction testContext( context ) {\n\treturn context && typeof context.getElementsByTagName !== \"undefined\" && context;\n}\n\n// Expose support vars for convenience\nsupport = Sizzle.support = {};\n\n/**\n * Detects XML nodes\n * @param {Element|Object} elem An element or a document\n * @returns {Boolean} True iff elem is a non-HTML XML node\n */\nisXML = Sizzle.isXML = function( elem ) {\n\tvar namespace = elem && elem.namespaceURI,\n\t\tdocElem = elem && ( elem.ownerDocument || elem ).documentElement;\n\n\t// Support: IE <=8\n\t// Assume HTML when documentElement doesn't yet exist, such as inside loading iframes\n\t// https://bugs.jquery.com/ticket/4833\n\treturn !rhtml.test( namespace || docElem && docElem.nodeName || \"HTML\" );\n};\n\n/**\n * Sets document-related variables once based on the current document\n * @param {Element|Object} [doc] An element or document object to use to set the document\n * @returns {Object} Returns the current document\n */\nsetDocument = Sizzle.setDocument = function( node ) {\n\tvar hasCompare, subWindow,\n\t\tdoc = node ? node.ownerDocument || node : preferredDoc;\n\n\t// Return early if doc is invalid or already selected\n\t// Support: IE 11+, Edge 17 - 18+\n\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t// two documents; shallow comparisons work.\n\t// eslint-disable-next-line eqeqeq\n\tif ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) {\n\t\treturn document;\n\t}\n\n\t// Update global variables\n\tdocument = doc;\n\tdocElem = document.documentElement;\n\tdocumentIsHTML = !isXML( document );\n\n\t// Support: IE 9 - 11+, Edge 12 - 18+\n\t// Accessing iframe documents after unload throws \"permission denied\" errors (jQuery #13936)\n\t// Support: IE 11+, Edge 17 - 18+\n\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t// two documents; shallow comparisons work.\n\t// eslint-disable-next-line eqeqeq\n\tif ( preferredDoc != document &&\n\t\t( subWindow = document.defaultView ) && subWindow.top !== subWindow ) {\n\n\t\t// Support: IE 11, Edge\n\t\tif ( subWindow.addEventListener ) {\n\t\t\tsubWindow.addEventListener( \"unload\", unloadHandler, false );\n\n\t\t// Support: IE 9 - 10 only\n\t\t} else if ( subWindow.attachEvent ) {\n\t\t\tsubWindow.attachEvent( \"onunload\", unloadHandler );\n\t\t}\n\t}\n\n\t// Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only,\n\t// Safari 4 - 5 only, Opera <=11.6 - 12.x only\n\t// IE/Edge & older browsers don't support the :scope pseudo-class.\n\t// Support: Safari 6.0 only\n\t// Safari 6.0 supports :scope but it's an alias of :root there.\n\tsupport.scope = assert( function( el ) {\n\t\tdocElem.appendChild( el ).appendChild( document.createElement( \"div\" ) );\n\t\treturn typeof el.querySelectorAll !== \"undefined\" &&\n\t\t\t!el.querySelectorAll( \":scope fieldset div\" ).length;\n\t} );\n\n\t/* Attributes\n\t---------------------------------------------------------------------- */\n\n\t// Support: IE<8\n\t// Verify that getAttribute really returns attributes and not properties\n\t// (excepting IE8 booleans)\n\tsupport.attributes = assert( function( el ) {\n\t\tel.className = \"i\";\n\t\treturn !el.getAttribute( \"className\" );\n\t} );\n\n\t/* getElement(s)By*\n\t---------------------------------------------------------------------- */\n\n\t// Check if getElementsByTagName(\"*\") returns only elements\n\tsupport.getElementsByTagName = assert( function( el ) {\n\t\tel.appendChild( document.createComment( \"\" ) );\n\t\treturn !el.getElementsByTagName( \"*\" ).length;\n\t} );\n\n\t// Support: IE<9\n\tsupport.getElementsByClassName = rnative.test( document.getElementsByClassName );\n\n\t// Support: IE<10\n\t// Check if getElementById returns elements by name\n\t// The broken getElementById methods don't pick up programmatically-set names,\n\t// so use a roundabout getElementsByName test\n\tsupport.getById = assert( function( el ) {\n\t\tdocElem.appendChild( el ).id = expando;\n\t\treturn !document.getElementsByName || !document.getElementsByName( expando ).length;\n\t} );\n\n\t// ID filter and find\n\tif ( support.getById ) {\n\t\tExpr.filter[ \"ID\" ] = function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn elem.getAttribute( \"id\" ) === attrId;\n\t\t\t};\n\t\t};\n\t\tExpr.find[ \"ID\" ] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && documentIsHTML ) {\n\t\t\t\tvar elem = context.getElementById( id );\n\t\t\t\treturn elem ? [ elem ] : [];\n\t\t\t}\n\t\t};\n\t} else {\n\t\tExpr.filter[ \"ID\" ] =  function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\tvar node = typeof elem.getAttributeNode !== \"undefined\" &&\n\t\t\t\t\telem.getAttributeNode( \"id\" );\n\t\t\t\treturn node && node.value === attrId;\n\t\t\t};\n\t\t};\n\n\t\t// Support: IE 6 - 7 only\n\t\t// getElementById is not reliable as a find shortcut\n\t\tExpr.find[ \"ID\" ] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && documentIsHTML ) {\n\t\t\t\tvar node, i, elems,\n\t\t\t\t\telem = context.getElementById( id );\n\n\t\t\t\tif ( elem ) {\n\n\t\t\t\t\t// Verify the id attribute\n\t\t\t\t\tnode = elem.getAttributeNode( \"id\" );\n\t\t\t\t\tif ( node && node.value === id ) {\n\t\t\t\t\t\treturn [ elem ];\n\t\t\t\t\t}\n\n\t\t\t\t\t// Fall back on getElementsByName\n\t\t\t\t\telems = context.getElementsByName( id );\n\t\t\t\t\ti = 0;\n\t\t\t\t\twhile ( ( elem = elems[ i++ ] ) ) {\n\t\t\t\t\t\tnode = elem.getAttributeNode( \"id\" );\n\t\t\t\t\t\tif ( node && node.value === id ) {\n\t\t\t\t\t\t\treturn [ elem ];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn [];\n\t\t\t}\n\t\t};\n\t}\n\n\t// Tag\n\tExpr.find[ \"TAG\" ] = support.getElementsByTagName ?\n\t\tfunction( tag, context ) {\n\t\t\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\t\t\treturn context.getElementsByTagName( tag );\n\n\t\t\t// DocumentFragment nodes don't have gEBTN\n\t\t\t} else if ( support.qsa ) {\n\t\t\t\treturn context.querySelectorAll( tag );\n\t\t\t}\n\t\t} :\n\n\t\tfunction( tag, context ) {\n\t\t\tvar elem,\n\t\t\t\ttmp = [],\n\t\t\t\ti = 0,\n\n\t\t\t\t// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too\n\t\t\t\tresults = context.getElementsByTagName( tag );\n\n\t\t\t// Filter out possible comments\n\t\t\tif ( tag === \"*\" ) {\n\t\t\t\twhile ( ( elem = results[ i++ ] ) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\ttmp.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn tmp;\n\t\t\t}\n\t\t\treturn results;\n\t\t};\n\n\t// Class\n\tExpr.find[ \"CLASS\" ] = support.getElementsByClassName && function( className, context ) {\n\t\tif ( typeof context.getElementsByClassName !== \"undefined\" && documentIsHTML ) {\n\t\t\treturn context.getElementsByClassName( className );\n\t\t}\n\t};\n\n\t/* QSA/matchesSelector\n\t---------------------------------------------------------------------- */\n\n\t// QSA and matchesSelector support\n\n\t// matchesSelector(:active) reports false when true (IE9/Opera 11.5)\n\trbuggyMatches = [];\n\n\t// qSa(:focus) reports false when true (Chrome 21)\n\t// We allow this because of a bug in IE8/9 that throws an error\n\t// whenever `document.activeElement` is accessed on an iframe\n\t// So, we allow :focus to pass through QSA all the time to avoid the IE error\n\t// See https://bugs.jquery.com/ticket/13378\n\trbuggyQSA = [];\n\n\tif ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) {\n\n\t\t// Build QSA regex\n\t\t// Regex strategy adopted from Diego Perini\n\t\tassert( function( el ) {\n\n\t\t\tvar input;\n\n\t\t\t// Select is set to empty string on purpose\n\t\t\t// This is to test IE's treatment of not explicitly\n\t\t\t// setting a boolean content attribute,\n\t\t\t// since its presence should be enough\n\t\t\t// https://bugs.jquery.com/ticket/12359\n\t\t\tdocElem.appendChild( el ).innerHTML = \"<a id='\" + expando + \"'></a>\" +\n\t\t\t\t\"<select id='\" + expando + \"-\\r\\\\' msallowcapture=''>\" +\n\t\t\t\t\"<option selected=''></option></select>\";\n\n\t\t\t// Support: IE8, Opera 11-12.16\n\t\t\t// Nothing should be selected when empty strings follow ^= or $= or *=\n\t\t\t// The test attribute must be unknown in Opera but \"safe\" for WinRT\n\t\t\t// https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section\n\t\t\tif ( el.querySelectorAll( \"[msallowcapture^='']\" ).length ) {\n\t\t\t\trbuggyQSA.push( \"[*^$]=\" + whitespace + \"*(?:''|\\\"\\\")\" );\n\t\t\t}\n\n\t\t\t// Support: IE8\n\t\t\t// Boolean attributes and \"value\" are not treated correctly\n\t\t\tif ( !el.querySelectorAll( \"[selected]\" ).length ) {\n\t\t\t\trbuggyQSA.push( \"\\\\[\" + whitespace + \"*(?:value|\" + booleans + \")\" );\n\t\t\t}\n\n\t\t\t// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+\n\t\t\tif ( !el.querySelectorAll( \"[id~=\" + expando + \"-]\" ).length ) {\n\t\t\t\trbuggyQSA.push( \"~=\" );\n\t\t\t}\n\n\t\t\t// Support: IE 11+, Edge 15 - 18+\n\t\t\t// IE 11/Edge don't find elements on a `[name='']` query in some cases.\n\t\t\t// Adding a temporary attribute to the document before the selection works\n\t\t\t// around the issue.\n\t\t\t// Interestingly, IE 10 & older don't seem to have the issue.\n\t\t\tinput = document.createElement( \"input\" );\n\t\t\tinput.setAttribute( \"name\", \"\" );\n\t\t\tel.appendChild( input );\n\t\t\tif ( !el.querySelectorAll( \"[name='']\" ).length ) {\n\t\t\t\trbuggyQSA.push( \"\\\\[\" + whitespace + \"*name\" + whitespace + \"*=\" +\n\t\t\t\t\twhitespace + \"*(?:''|\\\"\\\")\" );\n\t\t\t}\n\n\t\t\t// Webkit/Opera - :checked should return selected option elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !el.querySelectorAll( \":checked\" ).length ) {\n\t\t\t\trbuggyQSA.push( \":checked\" );\n\t\t\t}\n\n\t\t\t// Support: Safari 8+, iOS 8+\n\t\t\t// https://bugs.webkit.org/show_bug.cgi?id=136851\n\t\t\t// In-page `selector#id sibling-combinator selector` fails\n\t\t\tif ( !el.querySelectorAll( \"a#\" + expando + \"+*\" ).length ) {\n\t\t\t\trbuggyQSA.push( \".#.+[+~]\" );\n\t\t\t}\n\n\t\t\t// Support: Firefox <=3.6 - 5 only\n\t\t\t// Old Firefox doesn't throw on a badly-escaped identifier.\n\t\t\tel.querySelectorAll( \"\\\\\\f\" );\n\t\t\trbuggyQSA.push( \"[\\\\r\\\\n\\\\f]\" );\n\t\t} );\n\n\t\tassert( function( el ) {\n\t\t\tel.innerHTML = \"<a href='' disabled='disabled'></a>\" +\n\t\t\t\t\"<select disabled='disabled'><option/></select>\";\n\n\t\t\t// Support: Windows 8 Native Apps\n\t\t\t// The type and name attributes are restricted during .innerHTML assignment\n\t\t\tvar input = document.createElement( \"input\" );\n\t\t\tinput.setAttribute( \"type\", \"hidden\" );\n\t\t\tel.appendChild( input ).setAttribute( \"name\", \"D\" );\n\n\t\t\t// Support: IE8\n\t\t\t// Enforce case-sensitivity of name attribute\n\t\t\tif ( el.querySelectorAll( \"[name=d]\" ).length ) {\n\t\t\t\trbuggyQSA.push( \"name\" + whitespace + \"*[*^$|!~]?=\" );\n\t\t\t}\n\n\t\t\t// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( el.querySelectorAll( \":enabled\" ).length !== 2 ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Support: IE9-11+\n\t\t\t// IE's :disabled selector does not pick up the children of disabled fieldsets\n\t\t\tdocElem.appendChild( el ).disabled = true;\n\t\t\tif ( el.querySelectorAll( \":disabled\" ).length !== 2 ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Support: Opera 10 - 11 only\n\t\t\t// Opera 10-11 does not throw on post-comma invalid pseudos\n\t\t\tel.querySelectorAll( \"*,:x\" );\n\t\t\trbuggyQSA.push( \",.*:\" );\n\t\t} );\n\t}\n\n\tif ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches ||\n\t\tdocElem.webkitMatchesSelector ||\n\t\tdocElem.mozMatchesSelector ||\n\t\tdocElem.oMatchesSelector ||\n\t\tdocElem.msMatchesSelector ) ) ) ) {\n\n\t\tassert( function( el ) {\n\n\t\t\t// Check to see if it's possible to do matchesSelector\n\t\t\t// on a disconnected node (IE 9)\n\t\t\tsupport.disconnectedMatch = matches.call( el, \"*\" );\n\n\t\t\t// This should fail with an exception\n\t\t\t// Gecko does not error, returns false instead\n\t\t\tmatches.call( el, \"[s!='']:x\" );\n\t\t\trbuggyMatches.push( \"!=\", pseudos );\n\t\t} );\n\t}\n\n\trbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( \"|\" ) );\n\trbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( \"|\" ) );\n\n\t/* Contains\n\t---------------------------------------------------------------------- */\n\thasCompare = rnative.test( docElem.compareDocumentPosition );\n\n\t// Element contains another\n\t// Purposefully self-exclusive\n\t// As in, an element does not contain itself\n\tcontains = hasCompare || rnative.test( docElem.contains ) ?\n\t\tfunction( a, b ) {\n\t\t\tvar adown = a.nodeType === 9 ? a.documentElement : a,\n\t\t\t\tbup = b && b.parentNode;\n\t\t\treturn a === bup || !!( bup && bup.nodeType === 1 && (\n\t\t\t\tadown.contains ?\n\t\t\t\t\tadown.contains( bup ) :\n\t\t\t\t\ta.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16\n\t\t\t) );\n\t\t} :\n\t\tfunction( a, b ) {\n\t\t\tif ( b ) {\n\t\t\t\twhile ( ( b = b.parentNode ) ) {\n\t\t\t\t\tif ( b === a ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n\n\t/* Sorting\n\t---------------------------------------------------------------------- */\n\n\t// Document order sorting\n\tsortOrder = hasCompare ?\n\tfunction( a, b ) {\n\n\t\t// Flag for duplicate removal\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\t// Sort on method existence if only one input has compareDocumentPosition\n\t\tvar compare = !a.compareDocumentPosition - !b.compareDocumentPosition;\n\t\tif ( compare ) {\n\t\t\treturn compare;\n\t\t}\n\n\t\t// Calculate position if both inputs belong to the same document\n\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t// two documents; shallow comparisons work.\n\t\t// eslint-disable-next-line eqeqeq\n\t\tcompare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ?\n\t\t\ta.compareDocumentPosition( b ) :\n\n\t\t\t// Otherwise we know they are disconnected\n\t\t\t1;\n\n\t\t// Disconnected nodes\n\t\tif ( compare & 1 ||\n\t\t\t( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) {\n\n\t\t\t// Choose the first element that is related to our preferred document\n\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t// two documents; shallow comparisons work.\n\t\t\t// eslint-disable-next-line eqeqeq\n\t\t\tif ( a == document || a.ownerDocument == preferredDoc &&\n\t\t\t\tcontains( preferredDoc, a ) ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\n\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t// two documents; shallow comparisons work.\n\t\t\t// eslint-disable-next-line eqeqeq\n\t\t\tif ( b == document || b.ownerDocument == preferredDoc &&\n\t\t\t\tcontains( preferredDoc, b ) ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\t// Maintain original order\n\t\t\treturn sortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\t\t}\n\n\t\treturn compare & 4 ? -1 : 1;\n\t} :\n\tfunction( a, b ) {\n\n\t\t// Exit early if the nodes are identical\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\taup = a.parentNode,\n\t\t\tbup = b.parentNode,\n\t\t\tap = [ a ],\n\t\t\tbp = [ b ];\n\n\t\t// Parentless nodes are either documents or disconnected\n\t\tif ( !aup || !bup ) {\n\n\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t// two documents; shallow comparisons work.\n\t\t\t/* eslint-disable eqeqeq */\n\t\t\treturn a == document ? -1 :\n\t\t\t\tb == document ? 1 :\n\t\t\t\t/* eslint-enable eqeqeq */\n\t\t\t\taup ? -1 :\n\t\t\t\tbup ? 1 :\n\t\t\t\tsortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\n\t\t// If the nodes are siblings, we can do a quick check\n\t\t} else if ( aup === bup ) {\n\t\t\treturn siblingCheck( a, b );\n\t\t}\n\n\t\t// Otherwise we need full lists of their ancestors for comparison\n\t\tcur = a;\n\t\twhile ( ( cur = cur.parentNode ) ) {\n\t\t\tap.unshift( cur );\n\t\t}\n\t\tcur = b;\n\t\twhile ( ( cur = cur.parentNode ) ) {\n\t\t\tbp.unshift( cur );\n\t\t}\n\n\t\t// Walk down the tree looking for a discrepancy\n\t\twhile ( ap[ i ] === bp[ i ] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i ?\n\n\t\t\t// Do a sibling check if the nodes have a common ancestor\n\t\t\tsiblingCheck( ap[ i ], bp[ i ] ) :\n\n\t\t\t// Otherwise nodes in our document sort first\n\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t// two documents; shallow comparisons work.\n\t\t\t/* eslint-disable eqeqeq */\n\t\t\tap[ i ] == preferredDoc ? -1 :\n\t\t\tbp[ i ] == preferredDoc ? 1 :\n\t\t\t/* eslint-enable eqeqeq */\n\t\t\t0;\n\t};\n\n\treturn document;\n};\n\nSizzle.matches = function( expr, elements ) {\n\treturn Sizzle( expr, null, null, elements );\n};\n\nSizzle.matchesSelector = function( elem, expr ) {\n\tsetDocument( elem );\n\n\tif ( support.matchesSelector && documentIsHTML &&\n\t\t!nonnativeSelectorCache[ expr + \" \" ] &&\n\t\t( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&\n\t\t( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {\n\n\t\ttry {\n\t\t\tvar ret = matches.call( elem, expr );\n\n\t\t\t// IE 9's matchesSelector returns false on disconnected nodes\n\t\t\tif ( ret || support.disconnectedMatch ||\n\n\t\t\t\t// As well, disconnected nodes are said to be in a document\n\t\t\t\t// fragment in IE 9\n\t\t\t\telem.document && elem.document.nodeType !== 11 ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t} catch ( e ) {\n\t\t\tnonnativeSelectorCache( expr, true );\n\t\t}\n\t}\n\n\treturn Sizzle( expr, document, null, [ elem ] ).length > 0;\n};\n\nSizzle.contains = function( context, elem ) {\n\n\t// Set document vars if needed\n\t// Support: IE 11+, Edge 17 - 18+\n\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t// two documents; shallow comparisons work.\n\t// eslint-disable-next-line eqeqeq\n\tif ( ( context.ownerDocument || context ) != document ) {\n\t\tsetDocument( context );\n\t}\n\treturn contains( context, elem );\n};\n\nSizzle.attr = function( elem, name ) {\n\n\t// Set document vars if needed\n\t// Support: IE 11+, Edge 17 - 18+\n\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t// two documents; shallow comparisons work.\n\t// eslint-disable-next-line eqeqeq\n\tif ( ( elem.ownerDocument || elem ) != document ) {\n\t\tsetDocument( elem );\n\t}\n\n\tvar fn = Expr.attrHandle[ name.toLowerCase() ],\n\n\t\t// Don't get fooled by Object.prototype properties (jQuery #13807)\n\t\tval = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?\n\t\t\tfn( elem, name, !documentIsHTML ) :\n\t\t\tundefined;\n\n\treturn val !== undefined ?\n\t\tval :\n\t\tsupport.attributes || !documentIsHTML ?\n\t\t\telem.getAttribute( name ) :\n\t\t\t( val = elem.getAttributeNode( name ) ) && val.specified ?\n\t\t\t\tval.value :\n\t\t\t\tnull;\n};\n\nSizzle.escape = function( sel ) {\n\treturn ( sel + \"\" ).replace( rcssescape, fcssescape );\n};\n\nSizzle.error = function( msg ) {\n\tthrow new Error( \"Syntax error, unrecognized expression: \" + msg );\n};\n\n/**\n * Document sorting and removing duplicates\n * @param {ArrayLike} results\n */\nSizzle.uniqueSort = function( results ) {\n\tvar elem,\n\t\tduplicates = [],\n\t\tj = 0,\n\t\ti = 0;\n\n\t// Unless we *know* we can detect duplicates, assume their presence\n\thasDuplicate = !support.detectDuplicates;\n\tsortInput = !support.sortStable && results.slice( 0 );\n\tresults.sort( sortOrder );\n\n\tif ( hasDuplicate ) {\n\t\twhile ( ( elem = results[ i++ ] ) ) {\n\t\t\tif ( elem === results[ i ] ) {\n\t\t\t\tj = duplicates.push( i );\n\t\t\t}\n\t\t}\n\t\twhile ( j-- ) {\n\t\t\tresults.splice( duplicates[ j ], 1 );\n\t\t}\n\t}\n\n\t// Clear input after sorting to release objects\n\t// See https://github.com/jquery/sizzle/pull/225\n\tsortInput = null;\n\n\treturn results;\n};\n\n/**\n * Utility function for retrieving the text value of an array of DOM nodes\n * @param {Array|Element} elem\n */\ngetText = Sizzle.getText = function( elem ) {\n\tvar node,\n\t\tret = \"\",\n\t\ti = 0,\n\t\tnodeType = elem.nodeType;\n\n\tif ( !nodeType ) {\n\n\t\t// If no nodeType, this is expected to be an array\n\t\twhile ( ( node = elem[ i++ ] ) ) {\n\n\t\t\t// Do not traverse comment nodes\n\t\t\tret += getText( node );\n\t\t}\n\t} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {\n\n\t\t// Use textContent for elements\n\t\t// innerText usage removed for consistency of new lines (jQuery #11153)\n\t\tif ( typeof elem.textContent === \"string\" ) {\n\t\t\treturn elem.textContent;\n\t\t} else {\n\n\t\t\t// Traverse its children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tret += getText( elem );\n\t\t\t}\n\t\t}\n\t} else if ( nodeType === 3 || nodeType === 4 ) {\n\t\treturn elem.nodeValue;\n\t}\n\n\t// Do not include comment or processing instruction nodes\n\n\treturn ret;\n};\n\nExpr = Sizzle.selectors = {\n\n\t// Can be adjusted by the user\n\tcacheLength: 50,\n\n\tcreatePseudo: markFunction,\n\n\tmatch: matchExpr,\n\n\tattrHandle: {},\n\n\tfind: {},\n\n\trelative: {\n\t\t\">\": { dir: \"parentNode\", first: true },\n\t\t\" \": { dir: \"parentNode\" },\n\t\t\"+\": { dir: \"previousSibling\", first: true },\n\t\t\"~\": { dir: \"previousSibling\" }\n\t},\n\n\tpreFilter: {\n\t\t\"ATTR\": function( match ) {\n\t\t\tmatch[ 1 ] = match[ 1 ].replace( runescape, funescape );\n\n\t\t\t// Move the given value to match[3] whether quoted or unquoted\n\t\t\tmatch[ 3 ] = ( match[ 3 ] || match[ 4 ] ||\n\t\t\t\tmatch[ 5 ] || \"\" ).replace( runescape, funescape );\n\n\t\t\tif ( match[ 2 ] === \"~=\" ) {\n\t\t\t\tmatch[ 3 ] = \" \" + match[ 3 ] + \" \";\n\t\t\t}\n\n\t\t\treturn match.slice( 0, 4 );\n\t\t},\n\n\t\t\"CHILD\": function( match ) {\n\n\t\t\t/* matches from matchExpr[\"CHILD\"]\n\t\t\t\t1 type (only|nth|...)\n\t\t\t\t2 what (child|of-type)\n\t\t\t\t3 argument (even|odd|\\d*|\\d*n([+-]\\d+)?|...)\n\t\t\t\t4 xn-component of xn+y argument ([+-]?\\d*n|)\n\t\t\t\t5 sign of xn-component\n\t\t\t\t6 x of xn-component\n\t\t\t\t7 sign of y-component\n\t\t\t\t8 y of y-component\n\t\t\t*/\n\t\t\tmatch[ 1 ] = match[ 1 ].toLowerCase();\n\n\t\t\tif ( match[ 1 ].slice( 0, 3 ) === \"nth\" ) {\n\n\t\t\t\t// nth-* requires argument\n\t\t\t\tif ( !match[ 3 ] ) {\n\t\t\t\t\tSizzle.error( match[ 0 ] );\n\t\t\t\t}\n\n\t\t\t\t// numeric x and y parameters for Expr.filter.CHILD\n\t\t\t\t// remember that false/true cast respectively to 0/1\n\t\t\t\tmatch[ 4 ] = +( match[ 4 ] ?\n\t\t\t\t\tmatch[ 5 ] + ( match[ 6 ] || 1 ) :\n\t\t\t\t\t2 * ( match[ 3 ] === \"even\" || match[ 3 ] === \"odd\" ) );\n\t\t\t\tmatch[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === \"odd\" );\n\n\t\t\t\t// other types prohibit arguments\n\t\t\t} else if ( match[ 3 ] ) {\n\t\t\t\tSizzle.error( match[ 0 ] );\n\t\t\t}\n\n\t\t\treturn match;\n\t\t},\n\n\t\t\"PSEUDO\": function( match ) {\n\t\t\tvar excess,\n\t\t\t\tunquoted = !match[ 6 ] && match[ 2 ];\n\n\t\t\tif ( matchExpr[ \"CHILD\" ].test( match[ 0 ] ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Accept quoted arguments as-is\n\t\t\tif ( match[ 3 ] ) {\n\t\t\t\tmatch[ 2 ] = match[ 4 ] || match[ 5 ] || \"\";\n\n\t\t\t// Strip excess characters from unquoted arguments\n\t\t\t} else if ( unquoted && rpseudo.test( unquoted ) &&\n\n\t\t\t\t// Get excess from tokenize (recursively)\n\t\t\t\t( excess = tokenize( unquoted, true ) ) &&\n\n\t\t\t\t// advance to the next closing parenthesis\n\t\t\t\t( excess = unquoted.indexOf( \")\", unquoted.length - excess ) - unquoted.length ) ) {\n\n\t\t\t\t// excess is a negative index\n\t\t\t\tmatch[ 0 ] = match[ 0 ].slice( 0, excess );\n\t\t\t\tmatch[ 2 ] = unquoted.slice( 0, excess );\n\t\t\t}\n\n\t\t\t// Return only captures needed by the pseudo filter method (type and argument)\n\t\t\treturn match.slice( 0, 3 );\n\t\t}\n\t},\n\n\tfilter: {\n\n\t\t\"TAG\": function( nodeNameSelector ) {\n\t\t\tvar nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn nodeNameSelector === \"*\" ?\n\t\t\t\tfunction() {\n\t\t\t\t\treturn true;\n\t\t\t\t} :\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === nodeName;\n\t\t\t\t};\n\t\t},\n\n\t\t\"CLASS\": function( className ) {\n\t\t\tvar pattern = classCache[ className + \" \" ];\n\n\t\t\treturn pattern ||\n\t\t\t\t( pattern = new RegExp( \"(^|\" + whitespace +\n\t\t\t\t\t\")\" + className + \"(\" + whitespace + \"|$)\" ) ) && classCache(\n\t\t\t\t\t\tclassName, function( elem ) {\n\t\t\t\t\t\t\treturn pattern.test(\n\t\t\t\t\t\t\t\ttypeof elem.className === \"string\" && elem.className ||\n\t\t\t\t\t\t\t\ttypeof elem.getAttribute !== \"undefined\" &&\n\t\t\t\t\t\t\t\t\telem.getAttribute( \"class\" ) ||\n\t\t\t\t\t\t\t\t\"\"\n\t\t\t\t\t\t\t);\n\t\t\t\t} );\n\t\t},\n\n\t\t\"ATTR\": function( name, operator, check ) {\n\t\t\treturn function( elem ) {\n\t\t\t\tvar result = Sizzle.attr( elem, name );\n\n\t\t\t\tif ( result == null ) {\n\t\t\t\t\treturn operator === \"!=\";\n\t\t\t\t}\n\t\t\t\tif ( !operator ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tresult += \"\";\n\n\t\t\t\t/* eslint-disable max-len */\n\n\t\t\t\treturn operator === \"=\" ? result === check :\n\t\t\t\t\toperator === \"!=\" ? result !== check :\n\t\t\t\t\toperator === \"^=\" ? check && result.indexOf( check ) === 0 :\n\t\t\t\t\toperator === \"*=\" ? check && result.indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"$=\" ? check && result.slice( -check.length ) === check :\n\t\t\t\t\toperator === \"~=\" ? ( \" \" + result.replace( rwhitespace, \" \" ) + \" \" ).indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"|=\" ? result === check || result.slice( 0, check.length + 1 ) === check + \"-\" :\n\t\t\t\t\tfalse;\n\t\t\t\t/* eslint-enable max-len */\n\n\t\t\t};\n\t\t},\n\n\t\t\"CHILD\": function( type, what, _argument, first, last ) {\n\t\t\tvar simple = type.slice( 0, 3 ) !== \"nth\",\n\t\t\t\tforward = type.slice( -4 ) !== \"last\",\n\t\t\t\tofType = what === \"of-type\";\n\n\t\t\treturn first === 1 && last === 0 ?\n\n\t\t\t\t// Shortcut for :nth-*(n)\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn !!elem.parentNode;\n\t\t\t\t} :\n\n\t\t\t\tfunction( elem, _context, xml ) {\n\t\t\t\t\tvar cache, uniqueCache, outerCache, node, nodeIndex, start,\n\t\t\t\t\t\tdir = simple !== forward ? \"nextSibling\" : \"previousSibling\",\n\t\t\t\t\t\tparent = elem.parentNode,\n\t\t\t\t\t\tname = ofType && elem.nodeName.toLowerCase(),\n\t\t\t\t\t\tuseCache = !xml && !ofType,\n\t\t\t\t\t\tdiff = false;\n\n\t\t\t\t\tif ( parent ) {\n\n\t\t\t\t\t\t// :(first|last|only)-(child|of-type)\n\t\t\t\t\t\tif ( simple ) {\n\t\t\t\t\t\t\twhile ( dir ) {\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\twhile ( ( node = node[ dir ] ) ) {\n\t\t\t\t\t\t\t\t\tif ( ofType ?\n\t\t\t\t\t\t\t\t\t\tnode.nodeName.toLowerCase() === name :\n\t\t\t\t\t\t\t\t\t\tnode.nodeType === 1 ) {\n\n\t\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Reverse direction for :only-* (if we haven't yet done so)\n\t\t\t\t\t\t\t\tstart = dir = type === \"only\" && !start && \"nextSibling\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstart = [ forward ? parent.firstChild : parent.lastChild ];\n\n\t\t\t\t\t\t// non-xml :nth-child(...) stores cache data on `parent`\n\t\t\t\t\t\tif ( forward && useCache ) {\n\n\t\t\t\t\t\t\t// Seek `elem` from a previously-cached index\n\n\t\t\t\t\t\t\t// ...in a gzip-friendly way\n\t\t\t\t\t\t\tnode = parent;\n\t\t\t\t\t\t\touterCache = node[ expando ] || ( node[ expando ] = {} );\n\n\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t( outerCache[ node.uniqueID ] = {} );\n\n\t\t\t\t\t\t\tcache = uniqueCache[ type ] || [];\n\t\t\t\t\t\t\tnodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];\n\t\t\t\t\t\t\tdiff = nodeIndex && cache[ 2 ];\n\t\t\t\t\t\t\tnode = nodeIndex && parent.childNodes[ nodeIndex ];\n\n\t\t\t\t\t\t\twhile ( ( node = ++nodeIndex && node && node[ dir ] ||\n\n\t\t\t\t\t\t\t\t// Fallback to seeking `elem` from the start\n\t\t\t\t\t\t\t\t( diff = nodeIndex = 0 ) || start.pop() ) ) {\n\n\t\t\t\t\t\t\t\t// When found, cache indexes on `parent` and break\n\t\t\t\t\t\t\t\tif ( node.nodeType === 1 && ++diff && node === elem ) {\n\t\t\t\t\t\t\t\t\tuniqueCache[ type ] = [ dirruns, nodeIndex, diff ];\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// Use previously-cached element index if available\n\t\t\t\t\t\t\tif ( useCache ) {\n\n\t\t\t\t\t\t\t\t// ...in a gzip-friendly way\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\touterCache = node[ expando ] || ( node[ expando ] = {} );\n\n\t\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t\t( outerCache[ node.uniqueID ] = {} );\n\n\t\t\t\t\t\t\t\tcache = uniqueCache[ type ] || [];\n\t\t\t\t\t\t\t\tnodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];\n\t\t\t\t\t\t\t\tdiff = nodeIndex;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// xml :nth-child(...)\n\t\t\t\t\t\t\t// or :nth-last-child(...) or :nth(-last)?-of-type(...)\n\t\t\t\t\t\t\tif ( diff === false ) {\n\n\t\t\t\t\t\t\t\t// Use the same loop as above to seek `elem` from the start\n\t\t\t\t\t\t\t\twhile ( ( node = ++nodeIndex && node && node[ dir ] ||\n\t\t\t\t\t\t\t\t\t( diff = nodeIndex = 0 ) || start.pop() ) ) {\n\n\t\t\t\t\t\t\t\t\tif ( ( ofType ?\n\t\t\t\t\t\t\t\t\t\tnode.nodeName.toLowerCase() === name :\n\t\t\t\t\t\t\t\t\t\tnode.nodeType === 1 ) &&\n\t\t\t\t\t\t\t\t\t\t++diff ) {\n\n\t\t\t\t\t\t\t\t\t\t// Cache the index of each encountered element\n\t\t\t\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t\t\t\touterCache = node[ expando ] ||\n\t\t\t\t\t\t\t\t\t\t\t\t( node[ expando ] = {} );\n\n\t\t\t\t\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t\t\t\t\t( outerCache[ node.uniqueID ] = {} );\n\n\t\t\t\t\t\t\t\t\t\t\tuniqueCache[ type ] = [ dirruns, diff ];\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tif ( node === elem ) {\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Incorporate the offset, then check against cycle size\n\t\t\t\t\t\tdiff -= last;\n\t\t\t\t\t\treturn diff === first || ( diff % first === 0 && diff / first >= 0 );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t},\n\n\t\t\"PSEUDO\": function( pseudo, argument ) {\n\n\t\t\t// pseudo-class names are case-insensitive\n\t\t\t// http://www.w3.org/TR/selectors/#pseudo-classes\n\t\t\t// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\n\t\t\t// Remember that setFilters inherits from pseudos\n\t\t\tvar args,\n\t\t\t\tfn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||\n\t\t\t\t\tSizzle.error( \"unsupported pseudo: \" + pseudo );\n\n\t\t\t// The user may use createPseudo to indicate that\n\t\t\t// arguments are needed to create the filter function\n\t\t\t// just as Sizzle does\n\t\t\tif ( fn[ expando ] ) {\n\t\t\t\treturn fn( argument );\n\t\t\t}\n\n\t\t\t// But maintain support for old signatures\n\t\t\tif ( fn.length > 1 ) {\n\t\t\t\targs = [ pseudo, pseudo, \"\", argument ];\n\t\t\t\treturn Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?\n\t\t\t\t\tmarkFunction( function( seed, matches ) {\n\t\t\t\t\t\tvar idx,\n\t\t\t\t\t\t\tmatched = fn( seed, argument ),\n\t\t\t\t\t\t\ti = matched.length;\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tidx = indexOf( seed, matched[ i ] );\n\t\t\t\t\t\t\tseed[ idx ] = !( matches[ idx ] = matched[ i ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t} ) :\n\t\t\t\t\tfunction( elem ) {\n\t\t\t\t\t\treturn fn( elem, 0, args );\n\t\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn fn;\n\t\t}\n\t},\n\n\tpseudos: {\n\n\t\t// Potentially complex pseudos\n\t\t\"not\": markFunction( function( selector ) {\n\n\t\t\t// Trim the selector passed to compile\n\t\t\t// to avoid treating leading and trailing\n\t\t\t// spaces as combinators\n\t\t\tvar input = [],\n\t\t\t\tresults = [],\n\t\t\t\tmatcher = compile( selector.replace( rtrim, \"$1\" ) );\n\n\t\t\treturn matcher[ expando ] ?\n\t\t\t\tmarkFunction( function( seed, matches, _context, xml ) {\n\t\t\t\t\tvar elem,\n\t\t\t\t\t\tunmatched = matcher( seed, null, xml, [] ),\n\t\t\t\t\t\ti = seed.length;\n\n\t\t\t\t\t// Match elements unmatched by `matcher`\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( ( elem = unmatched[ i ] ) ) {\n\t\t\t\t\t\t\tseed[ i ] = !( matches[ i ] = elem );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} ) :\n\t\t\t\tfunction( elem, _context, xml ) {\n\t\t\t\t\tinput[ 0 ] = elem;\n\t\t\t\t\tmatcher( input, null, xml, results );\n\n\t\t\t\t\t// Don't keep the element (issue #299)\n\t\t\t\t\tinput[ 0 ] = null;\n\t\t\t\t\treturn !results.pop();\n\t\t\t\t};\n\t\t} ),\n\n\t\t\"has\": markFunction( function( selector ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn Sizzle( selector, elem ).length > 0;\n\t\t\t};\n\t\t} ),\n\n\t\t\"contains\": markFunction( function( text ) {\n\t\t\ttext = text.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn ( elem.textContent || getText( elem ) ).indexOf( text ) > -1;\n\t\t\t};\n\t\t} ),\n\n\t\t// \"Whether an element is represented by a :lang() selector\n\t\t// is based solely on the element's language value\n\t\t// being equal to the identifier C,\n\t\t// or beginning with the identifier C immediately followed by \"-\".\n\t\t// The matching of C against the element's language value is performed case-insensitively.\n\t\t// The identifier C does not have to be a valid language name.\"\n\t\t// http://www.w3.org/TR/selectors/#lang-pseudo\n\t\t\"lang\": markFunction( function( lang ) {\n\n\t\t\t// lang value must be a valid identifier\n\t\t\tif ( !ridentifier.test( lang || \"\" ) ) {\n\t\t\t\tSizzle.error( \"unsupported lang: \" + lang );\n\t\t\t}\n\t\t\tlang = lang.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn function( elem ) {\n\t\t\t\tvar elemLang;\n\t\t\t\tdo {\n\t\t\t\t\tif ( ( elemLang = documentIsHTML ?\n\t\t\t\t\t\telem.lang :\n\t\t\t\t\t\telem.getAttribute( \"xml:lang\" ) || elem.getAttribute( \"lang\" ) ) ) {\n\n\t\t\t\t\t\telemLang = elemLang.toLowerCase();\n\t\t\t\t\t\treturn elemLang === lang || elemLang.indexOf( lang + \"-\" ) === 0;\n\t\t\t\t\t}\n\t\t\t\t} while ( ( elem = elem.parentNode ) && elem.nodeType === 1 );\n\t\t\t\treturn false;\n\t\t\t};\n\t\t} ),\n\n\t\t// Miscellaneous\n\t\t\"target\": function( elem ) {\n\t\t\tvar hash = window.location && window.location.hash;\n\t\t\treturn hash && hash.slice( 1 ) === elem.id;\n\t\t},\n\n\t\t\"root\": function( elem ) {\n\t\t\treturn elem === docElem;\n\t\t},\n\n\t\t\"focus\": function( elem ) {\n\t\t\treturn elem === document.activeElement &&\n\t\t\t\t( !document.hasFocus || document.hasFocus() ) &&\n\t\t\t\t!!( elem.type || elem.href || ~elem.tabIndex );\n\t\t},\n\n\t\t// Boolean properties\n\t\t\"enabled\": createDisabledPseudo( false ),\n\t\t\"disabled\": createDisabledPseudo( true ),\n\n\t\t\"checked\": function( elem ) {\n\n\t\t\t// In CSS3, :checked should return both checked and selected elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\tvar nodeName = elem.nodeName.toLowerCase();\n\t\t\treturn ( nodeName === \"input\" && !!elem.checked ) ||\n\t\t\t\t( nodeName === \"option\" && !!elem.selected );\n\t\t},\n\n\t\t\"selected\": function( elem ) {\n\n\t\t\t// Accessing this property makes selected-by-default\n\t\t\t// options in Safari work properly\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\t// eslint-disable-next-line no-unused-expressions\n\t\t\t\telem.parentNode.selectedIndex;\n\t\t\t}\n\n\t\t\treturn elem.selected === true;\n\t\t},\n\n\t\t// Contents\n\t\t\"empty\": function( elem ) {\n\n\t\t\t// http://www.w3.org/TR/selectors/#empty-pseudo\n\t\t\t// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),\n\t\t\t//   but not by others (comment: 8; processing instruction: 7; etc.)\n\t\t\t// nodeType < 6 works because attributes (2) do not appear as children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tif ( elem.nodeType < 6 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\n\t\t\"parent\": function( elem ) {\n\t\t\treturn !Expr.pseudos[ \"empty\" ]( elem );\n\t\t},\n\n\t\t// Element/input types\n\t\t\"header\": function( elem ) {\n\t\t\treturn rheader.test( elem.nodeName );\n\t\t},\n\n\t\t\"input\": function( elem ) {\n\t\t\treturn rinputs.test( elem.nodeName );\n\t\t},\n\n\t\t\"button\": function( elem ) {\n\t\t\tvar name = elem.nodeName.toLowerCase();\n\t\t\treturn name === \"input\" && elem.type === \"button\" || name === \"button\";\n\t\t},\n\n\t\t\"text\": function( elem ) {\n\t\t\tvar attr;\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" &&\n\t\t\t\telem.type === \"text\" &&\n\n\t\t\t\t// Support: IE<8\n\t\t\t\t// New HTML5 attribute values (e.g., \"search\") appear with elem.type === \"text\"\n\t\t\t\t( ( attr = elem.getAttribute( \"type\" ) ) == null ||\n\t\t\t\t\tattr.toLowerCase() === \"text\" );\n\t\t},\n\n\t\t// Position-in-collection\n\t\t\"first\": createPositionalPseudo( function() {\n\t\t\treturn [ 0 ];\n\t\t} ),\n\n\t\t\"last\": createPositionalPseudo( function( _matchIndexes, length ) {\n\t\t\treturn [ length - 1 ];\n\t\t} ),\n\n\t\t\"eq\": createPositionalPseudo( function( _matchIndexes, length, argument ) {\n\t\t\treturn [ argument < 0 ? argument + length : argument ];\n\t\t} ),\n\n\t\t\"even\": createPositionalPseudo( function( matchIndexes, length ) {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t} ),\n\n\t\t\"odd\": createPositionalPseudo( function( matchIndexes, length ) {\n\t\t\tvar i = 1;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t} ),\n\n\t\t\"lt\": createPositionalPseudo( function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ?\n\t\t\t\targument + length :\n\t\t\t\targument > length ?\n\t\t\t\t\tlength :\n\t\t\t\t\targument;\n\t\t\tfor ( ; --i >= 0; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t} ),\n\n\t\t\"gt\": createPositionalPseudo( function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; ++i < length; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t} )\n\t}\n};\n\nExpr.pseudos[ \"nth\" ] = Expr.pseudos[ \"eq\" ];\n\n// Add button/input type pseudos\nfor ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {\n\tExpr.pseudos[ i ] = createInputPseudo( i );\n}\nfor ( i in { submit: true, reset: true } ) {\n\tExpr.pseudos[ i ] = createButtonPseudo( i );\n}\n\n// Easy API for creating new setFilters\nfunction setFilters() {}\nsetFilters.prototype = Expr.filters = Expr.pseudos;\nExpr.setFilters = new setFilters();\n\ntokenize = Sizzle.tokenize = function( selector, parseOnly ) {\n\tvar matched, match, tokens, type,\n\t\tsoFar, groups, preFilters,\n\t\tcached = tokenCache[ selector + \" \" ];\n\n\tif ( cached ) {\n\t\treturn parseOnly ? 0 : cached.slice( 0 );\n\t}\n\n\tsoFar = selector;\n\tgroups = [];\n\tpreFilters = Expr.preFilter;\n\n\twhile ( soFar ) {\n\n\t\t// Comma and first run\n\t\tif ( !matched || ( match = rcomma.exec( soFar ) ) ) {\n\t\t\tif ( match ) {\n\n\t\t\t\t// Don't consume trailing commas as valid\n\t\t\t\tsoFar = soFar.slice( match[ 0 ].length ) || soFar;\n\t\t\t}\n\t\t\tgroups.push( ( tokens = [] ) );\n\t\t}\n\n\t\tmatched = false;\n\n\t\t// Combinators\n\t\tif ( ( match = rcombinators.exec( soFar ) ) ) {\n\t\t\tmatched = match.shift();\n\t\t\ttokens.push( {\n\t\t\t\tvalue: matched,\n\n\t\t\t\t// Cast descendant combinators to space\n\t\t\t\ttype: match[ 0 ].replace( rtrim, \" \" )\n\t\t\t} );\n\t\t\tsoFar = soFar.slice( matched.length );\n\t\t}\n\n\t\t// Filters\n\t\tfor ( type in Expr.filter ) {\n\t\t\tif ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] ||\n\t\t\t\t( match = preFilters[ type ]( match ) ) ) ) {\n\t\t\t\tmatched = match.shift();\n\t\t\t\ttokens.push( {\n\t\t\t\t\tvalue: matched,\n\t\t\t\t\ttype: type,\n\t\t\t\t\tmatches: match\n\t\t\t\t} );\n\t\t\t\tsoFar = soFar.slice( matched.length );\n\t\t\t}\n\t\t}\n\n\t\tif ( !matched ) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Return the length of the invalid excess\n\t// if we're just parsing\n\t// Otherwise, throw an error or return tokens\n\treturn parseOnly ?\n\t\tsoFar.length :\n\t\tsoFar ?\n\t\t\tSizzle.error( selector ) :\n\n\t\t\t// Cache the tokens\n\t\t\ttokenCache( selector, groups ).slice( 0 );\n};\n\nfunction toSelector( tokens ) {\n\tvar i = 0,\n\t\tlen = tokens.length,\n\t\tselector = \"\";\n\tfor ( ; i < len; i++ ) {\n\t\tselector += tokens[ i ].value;\n\t}\n\treturn selector;\n}\n\nfunction addCombinator( matcher, combinator, base ) {\n\tvar dir = combinator.dir,\n\t\tskip = combinator.next,\n\t\tkey = skip || dir,\n\t\tcheckNonElements = base && key === \"parentNode\",\n\t\tdoneName = done++;\n\n\treturn combinator.first ?\n\n\t\t// Check against closest ancestor/preceding element\n\t\tfunction( elem, context, xml ) {\n\t\t\twhile ( ( elem = elem[ dir ] ) ) {\n\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\treturn matcher( elem, context, xml );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t} :\n\n\t\t// Check against all ancestor/preceding elements\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar oldCache, uniqueCache, outerCache,\n\t\t\t\tnewCache = [ dirruns, doneName ];\n\n\t\t\t// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching\n\t\t\tif ( xml ) {\n\t\t\t\twhile ( ( elem = elem[ dir ] ) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twhile ( ( elem = elem[ dir ] ) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\touterCache = elem[ expando ] || ( elem[ expando ] = {} );\n\n\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\tuniqueCache = outerCache[ elem.uniqueID ] ||\n\t\t\t\t\t\t\t( outerCache[ elem.uniqueID ] = {} );\n\n\t\t\t\t\t\tif ( skip && skip === elem.nodeName.toLowerCase() ) {\n\t\t\t\t\t\t\telem = elem[ dir ] || elem;\n\t\t\t\t\t\t} else if ( ( oldCache = uniqueCache[ key ] ) &&\n\t\t\t\t\t\t\toldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {\n\n\t\t\t\t\t\t\t// Assign to newCache so results back-propagate to previous elements\n\t\t\t\t\t\t\treturn ( newCache[ 2 ] = oldCache[ 2 ] );\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// Reuse newcache so results back-propagate to previous elements\n\t\t\t\t\t\t\tuniqueCache[ key ] = newCache;\n\n\t\t\t\t\t\t\t// A match means we're done; a fail means we have to keep checking\n\t\t\t\t\t\t\tif ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) {\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n}\n\nfunction elementMatcher( matchers ) {\n\treturn matchers.length > 1 ?\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar i = matchers.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( !matchers[ i ]( elem, context, xml ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t} :\n\t\tmatchers[ 0 ];\n}\n\nfunction multipleContexts( selector, contexts, results ) {\n\tvar i = 0,\n\t\tlen = contexts.length;\n\tfor ( ; i < len; i++ ) {\n\t\tSizzle( selector, contexts[ i ], results );\n\t}\n\treturn results;\n}\n\nfunction condense( unmatched, map, filter, context, xml ) {\n\tvar elem,\n\t\tnewUnmatched = [],\n\t\ti = 0,\n\t\tlen = unmatched.length,\n\t\tmapped = map != null;\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( ( elem = unmatched[ i ] ) ) {\n\t\t\tif ( !filter || filter( elem, context, xml ) ) {\n\t\t\t\tnewUnmatched.push( elem );\n\t\t\t\tif ( mapped ) {\n\t\t\t\t\tmap.push( i );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn newUnmatched;\n}\n\nfunction setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {\n\tif ( postFilter && !postFilter[ expando ] ) {\n\t\tpostFilter = setMatcher( postFilter );\n\t}\n\tif ( postFinder && !postFinder[ expando ] ) {\n\t\tpostFinder = setMatcher( postFinder, postSelector );\n\t}\n\treturn markFunction( function( seed, results, context, xml ) {\n\t\tvar temp, i, elem,\n\t\t\tpreMap = [],\n\t\t\tpostMap = [],\n\t\t\tpreexisting = results.length,\n\n\t\t\t// Get initial elements from seed or context\n\t\t\telems = seed || multipleContexts(\n\t\t\t\tselector || \"*\",\n\t\t\t\tcontext.nodeType ? [ context ] : context,\n\t\t\t\t[]\n\t\t\t),\n\n\t\t\t// Prefilter to get matcher input, preserving a map for seed-results synchronization\n\t\t\tmatcherIn = preFilter && ( seed || !selector ) ?\n\t\t\t\tcondense( elems, preMap, preFilter, context, xml ) :\n\t\t\t\telems,\n\n\t\t\tmatcherOut = matcher ?\n\n\t\t\t\t// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,\n\t\t\t\tpostFinder || ( seed ? preFilter : preexisting || postFilter ) ?\n\n\t\t\t\t\t// ...intermediate processing is necessary\n\t\t\t\t\t[] :\n\n\t\t\t\t\t// ...otherwise use results directly\n\t\t\t\t\tresults :\n\t\t\t\tmatcherIn;\n\n\t\t// Find primary matches\n\t\tif ( matcher ) {\n\t\t\tmatcher( matcherIn, matcherOut, context, xml );\n\t\t}\n\n\t\t// Apply postFilter\n\t\tif ( postFilter ) {\n\t\t\ttemp = condense( matcherOut, postMap );\n\t\t\tpostFilter( temp, [], context, xml );\n\n\t\t\t// Un-match failing elements by moving them back to matcherIn\n\t\t\ti = temp.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( ( elem = temp[ i ] ) ) {\n\t\t\t\t\tmatcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( seed ) {\n\t\t\tif ( postFinder || preFilter ) {\n\t\t\t\tif ( postFinder ) {\n\n\t\t\t\t\t// Get the final matcherOut by condensing this intermediate into postFinder contexts\n\t\t\t\t\ttemp = [];\n\t\t\t\t\ti = matcherOut.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( ( elem = matcherOut[ i ] ) ) {\n\n\t\t\t\t\t\t\t// Restore matcherIn since elem is not yet a final match\n\t\t\t\t\t\t\ttemp.push( ( matcherIn[ i ] = elem ) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tpostFinder( null, ( matcherOut = [] ), temp, xml );\n\t\t\t\t}\n\n\t\t\t\t// Move matched elements from seed to results to keep them synchronized\n\t\t\t\ti = matcherOut.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tif ( ( elem = matcherOut[ i ] ) &&\n\t\t\t\t\t\t( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) {\n\n\t\t\t\t\t\tseed[ temp ] = !( results[ temp ] = elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Add elements to results, through postFinder if defined\n\t\t} else {\n\t\t\tmatcherOut = condense(\n\t\t\t\tmatcherOut === results ?\n\t\t\t\t\tmatcherOut.splice( preexisting, matcherOut.length ) :\n\t\t\t\t\tmatcherOut\n\t\t\t);\n\t\t\tif ( postFinder ) {\n\t\t\t\tpostFinder( null, results, matcherOut, xml );\n\t\t\t} else {\n\t\t\t\tpush.apply( results, matcherOut );\n\t\t\t}\n\t\t}\n\t} );\n}\n\nfunction matcherFromTokens( tokens ) {\n\tvar checkContext, matcher, j,\n\t\tlen = tokens.length,\n\t\tleadingRelative = Expr.relative[ tokens[ 0 ].type ],\n\t\timplicitRelative = leadingRelative || Expr.relative[ \" \" ],\n\t\ti = leadingRelative ? 1 : 0,\n\n\t\t// The foundational matcher ensures that elements are reachable from top-level context(s)\n\t\tmatchContext = addCombinator( function( elem ) {\n\t\t\treturn elem === checkContext;\n\t\t}, implicitRelative, true ),\n\t\tmatchAnyContext = addCombinator( function( elem ) {\n\t\t\treturn indexOf( checkContext, elem ) > -1;\n\t\t}, implicitRelative, true ),\n\t\tmatchers = [ function( elem, context, xml ) {\n\t\t\tvar ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (\n\t\t\t\t( checkContext = context ).nodeType ?\n\t\t\t\t\tmatchContext( elem, context, xml ) :\n\t\t\t\t\tmatchAnyContext( elem, context, xml ) );\n\n\t\t\t// Avoid hanging onto element (issue #299)\n\t\t\tcheckContext = null;\n\t\t\treturn ret;\n\t\t} ];\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) {\n\t\t\tmatchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];\n\t\t} else {\n\t\t\tmatcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches );\n\n\t\t\t// Return special upon seeing a positional matcher\n\t\t\tif ( matcher[ expando ] ) {\n\n\t\t\t\t// Find the next relative operator (if any) for proper handling\n\t\t\t\tj = ++i;\n\t\t\t\tfor ( ; j < len; j++ ) {\n\t\t\t\t\tif ( Expr.relative[ tokens[ j ].type ] ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn setMatcher(\n\t\t\t\t\ti > 1 && elementMatcher( matchers ),\n\t\t\t\t\ti > 1 && toSelector(\n\n\t\t\t\t\t// If the preceding token was a descendant combinator, insert an implicit any-element `*`\n\t\t\t\t\ttokens\n\t\t\t\t\t\t.slice( 0, i - 1 )\n\t\t\t\t\t\t.concat( { value: tokens[ i - 2 ].type === \" \" ? \"*\" : \"\" } )\n\t\t\t\t\t).replace( rtrim, \"$1\" ),\n\t\t\t\t\tmatcher,\n\t\t\t\t\ti < j && matcherFromTokens( tokens.slice( i, j ) ),\n\t\t\t\t\tj < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ),\n\t\t\t\t\tj < len && toSelector( tokens )\n\t\t\t\t);\n\t\t\t}\n\t\t\tmatchers.push( matcher );\n\t\t}\n\t}\n\n\treturn elementMatcher( matchers );\n}\n\nfunction matcherFromGroupMatchers( elementMatchers, setMatchers ) {\n\tvar bySet = setMatchers.length > 0,\n\t\tbyElement = elementMatchers.length > 0,\n\t\tsuperMatcher = function( seed, context, xml, results, outermost ) {\n\t\t\tvar elem, j, matcher,\n\t\t\t\tmatchedCount = 0,\n\t\t\t\ti = \"0\",\n\t\t\t\tunmatched = seed && [],\n\t\t\t\tsetMatched = [],\n\t\t\t\tcontextBackup = outermostContext,\n\n\t\t\t\t// We must always have either seed elements or outermost context\n\t\t\t\telems = seed || byElement && Expr.find[ \"TAG\" ]( \"*\", outermost ),\n\n\t\t\t\t// Use integer dirruns iff this is the outermost matcher\n\t\t\t\tdirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ),\n\t\t\t\tlen = elems.length;\n\n\t\t\tif ( outermost ) {\n\n\t\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t\t// two documents; shallow comparisons work.\n\t\t\t\t// eslint-disable-next-line eqeqeq\n\t\t\t\toutermostContext = context == document || context || outermost;\n\t\t\t}\n\n\t\t\t// Add elements passing elementMatchers directly to results\n\t\t\t// Support: IE<9, Safari\n\t\t\t// Tolerate NodeList properties (IE: \"length\"; Safari: <number>) matching elements by id\n\t\t\tfor ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) {\n\t\t\t\tif ( byElement && elem ) {\n\t\t\t\t\tj = 0;\n\n\t\t\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t\t\t// two documents; shallow comparisons work.\n\t\t\t\t\t// eslint-disable-next-line eqeqeq\n\t\t\t\t\tif ( !context && elem.ownerDocument != document ) {\n\t\t\t\t\t\tsetDocument( elem );\n\t\t\t\t\t\txml = !documentIsHTML;\n\t\t\t\t\t}\n\t\t\t\t\twhile ( ( matcher = elementMatchers[ j++ ] ) ) {\n\t\t\t\t\t\tif ( matcher( elem, context || document, xml ) ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( outermost ) {\n\t\t\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Track unmatched elements for set filters\n\t\t\t\tif ( bySet ) {\n\n\t\t\t\t\t// They will have gone through all possible matchers\n\t\t\t\t\tif ( ( elem = !matcher && elem ) ) {\n\t\t\t\t\t\tmatchedCount--;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Lengthen the array for every element, matched or not\n\t\t\t\t\tif ( seed ) {\n\t\t\t\t\t\tunmatched.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// `i` is now the count of elements visited above, and adding it to `matchedCount`\n\t\t\t// makes the latter nonnegative.\n\t\t\tmatchedCount += i;\n\n\t\t\t// Apply set filters to unmatched elements\n\t\t\t// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`\n\t\t\t// equals `i`), unless we didn't visit _any_ elements in the above loop because we have\n\t\t\t// no element matchers and no seed.\n\t\t\t// Incrementing an initially-string \"0\" `i` allows `i` to remain a string only in that\n\t\t\t// case, which will result in a \"00\" `matchedCount` that differs from `i` but is also\n\t\t\t// numerically zero.\n\t\t\tif ( bySet && i !== matchedCount ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( ( matcher = setMatchers[ j++ ] ) ) {\n\t\t\t\t\tmatcher( unmatched, setMatched, context, xml );\n\t\t\t\t}\n\n\t\t\t\tif ( seed ) {\n\n\t\t\t\t\t// Reintegrate element matches to eliminate the need for sorting\n\t\t\t\t\tif ( matchedCount > 0 ) {\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tif ( !( unmatched[ i ] || setMatched[ i ] ) ) {\n\t\t\t\t\t\t\t\tsetMatched[ i ] = pop.call( results );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Discard index placeholder values to get only actual matches\n\t\t\t\t\tsetMatched = condense( setMatched );\n\t\t\t\t}\n\n\t\t\t\t// Add matches to results\n\t\t\t\tpush.apply( results, setMatched );\n\n\t\t\t\t// Seedless set matches succeeding multiple successful matchers stipulate sorting\n\t\t\t\tif ( outermost && !seed && setMatched.length > 0 &&\n\t\t\t\t\t( matchedCount + setMatchers.length ) > 1 ) {\n\n\t\t\t\t\tSizzle.uniqueSort( results );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Override manipulation of globals by nested matchers\n\t\t\tif ( outermost ) {\n\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\toutermostContext = contextBackup;\n\t\t\t}\n\n\t\t\treturn unmatched;\n\t\t};\n\n\treturn bySet ?\n\t\tmarkFunction( superMatcher ) :\n\t\tsuperMatcher;\n}\n\ncompile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {\n\tvar i,\n\t\tsetMatchers = [],\n\t\telementMatchers = [],\n\t\tcached = compilerCache[ selector + \" \" ];\n\n\tif ( !cached ) {\n\n\t\t// Generate a function of recursive functions that can be used to check each element\n\t\tif ( !match ) {\n\t\t\tmatch = tokenize( selector );\n\t\t}\n\t\ti = match.length;\n\t\twhile ( i-- ) {\n\t\t\tcached = matcherFromTokens( match[ i ] );\n\t\t\tif ( cached[ expando ] ) {\n\t\t\t\tsetMatchers.push( cached );\n\t\t\t} else {\n\t\t\t\telementMatchers.push( cached );\n\t\t\t}\n\t\t}\n\n\t\t// Cache the compiled function\n\t\tcached = compilerCache(\n\t\t\tselector,\n\t\t\tmatcherFromGroupMatchers( elementMatchers, setMatchers )\n\t\t);\n\n\t\t// Save selector and tokenization\n\t\tcached.selector = selector;\n\t}\n\treturn cached;\n};\n\n/**\n * A low-level selection function that works with Sizzle's compiled\n *  selector functions\n * @param {String|Function} selector A selector or a pre-compiled\n *  selector function built with Sizzle.compile\n * @param {Element} context\n * @param {Array} [results]\n * @param {Array} [seed] A set of elements to match against\n */\nselect = Sizzle.select = function( selector, context, results, seed ) {\n\tvar i, tokens, token, type, find,\n\t\tcompiled = typeof selector === \"function\" && selector,\n\t\tmatch = !seed && tokenize( ( selector = compiled.selector || selector ) );\n\n\tresults = results || [];\n\n\t// Try to minimize operations if there is only one selector in the list and no seed\n\t// (the latter of which guarantees us context)\n\tif ( match.length === 1 ) {\n\n\t\t// Reduce context if the leading compound selector is an ID\n\t\ttokens = match[ 0 ] = match[ 0 ].slice( 0 );\n\t\tif ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === \"ID\" &&\n\t\t\tcontext.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) {\n\n\t\t\tcontext = ( Expr.find[ \"ID\" ]( token.matches[ 0 ]\n\t\t\t\t.replace( runescape, funescape ), context ) || [] )[ 0 ];\n\t\t\tif ( !context ) {\n\t\t\t\treturn results;\n\n\t\t\t// Precompiled matchers will still verify ancestry, so step up a level\n\t\t\t} else if ( compiled ) {\n\t\t\t\tcontext = context.parentNode;\n\t\t\t}\n\n\t\t\tselector = selector.slice( tokens.shift().value.length );\n\t\t}\n\n\t\t// Fetch a seed set for right-to-left matching\n\t\ti = matchExpr[ \"needsContext\" ].test( selector ) ? 0 : tokens.length;\n\t\twhile ( i-- ) {\n\t\t\ttoken = tokens[ i ];\n\n\t\t\t// Abort if we hit a combinator\n\t\t\tif ( Expr.relative[ ( type = token.type ) ] ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( ( find = Expr.find[ type ] ) ) {\n\n\t\t\t\t// Search, expanding context for leading sibling combinators\n\t\t\t\tif ( ( seed = find(\n\t\t\t\t\ttoken.matches[ 0 ].replace( runescape, funescape ),\n\t\t\t\t\trsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) ||\n\t\t\t\t\t\tcontext\n\t\t\t\t) ) ) {\n\n\t\t\t\t\t// If seed is empty or no tokens remain, we can return early\n\t\t\t\t\ttokens.splice( i, 1 );\n\t\t\t\t\tselector = seed.length && toSelector( tokens );\n\t\t\t\t\tif ( !selector ) {\n\t\t\t\t\t\tpush.apply( results, seed );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Compile and execute a filtering function if one is not provided\n\t// Provide `match` to avoid retokenization if we modified the selector above\n\t( compiled || compile( selector, match ) )(\n\t\tseed,\n\t\tcontext,\n\t\t!documentIsHTML,\n\t\tresults,\n\t\t!context || rsibling.test( selector ) && testContext( context.parentNode ) || context\n\t);\n\treturn results;\n};\n\n// One-time assignments\n\n// Sort stability\nsupport.sortStable = expando.split( \"\" ).sort( sortOrder ).join( \"\" ) === expando;\n\n// Support: Chrome 14-35+\n// Always assume duplicates if they aren't passed to the comparison function\nsupport.detectDuplicates = !!hasDuplicate;\n\n// Initialize against the default document\nsetDocument();\n\n// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)\n// Detached nodes confoundingly follow *each other*\nsupport.sortDetached = assert( function( el ) {\n\n\t// Should return 1, but returns 4 (following)\n\treturn el.compareDocumentPosition( document.createElement( \"fieldset\" ) ) & 1;\n} );\n\n// Support: IE<8\n// Prevent attribute/property \"interpolation\"\n// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx\nif ( !assert( function( el ) {\n\tel.innerHTML = \"<a href='#'></a>\";\n\treturn el.firstChild.getAttribute( \"href\" ) === \"#\";\n} ) ) {\n\taddHandle( \"type|href|height|width\", function( elem, name, isXML ) {\n\t\tif ( !isXML ) {\n\t\t\treturn elem.getAttribute( name, name.toLowerCase() === \"type\" ? 1 : 2 );\n\t\t}\n\t} );\n}\n\n// Support: IE<9\n// Use defaultValue in place of getAttribute(\"value\")\nif ( !support.attributes || !assert( function( el ) {\n\tel.innerHTML = \"<input/>\";\n\tel.firstChild.setAttribute( \"value\", \"\" );\n\treturn el.firstChild.getAttribute( \"value\" ) === \"\";\n} ) ) {\n\taddHandle( \"value\", function( elem, _name, isXML ) {\n\t\tif ( !isXML && elem.nodeName.toLowerCase() === \"input\" ) {\n\t\t\treturn elem.defaultValue;\n\t\t}\n\t} );\n}\n\n// Support: IE<9\n// Use getAttributeNode to fetch booleans when getAttribute lies\nif ( !assert( function( el ) {\n\treturn el.getAttribute( \"disabled\" ) == null;\n} ) ) {\n\taddHandle( booleans, function( elem, name, isXML ) {\n\t\tvar val;\n\t\tif ( !isXML ) {\n\t\t\treturn elem[ name ] === true ? name.toLowerCase() :\n\t\t\t\t( val = elem.getAttributeNode( name ) ) && val.specified ?\n\t\t\t\t\tval.value :\n\t\t\t\t\tnull;\n\t\t}\n\t} );\n}\n\nreturn Sizzle;\n\n} )( window );\n\n\n\njQuery.find = Sizzle;\njQuery.expr = Sizzle.selectors;\n\n// Deprecated\njQuery.expr[ \":\" ] = jQuery.expr.pseudos;\njQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;\njQuery.text = Sizzle.getText;\njQuery.isXMLDoc = Sizzle.isXML;\njQuery.contains = Sizzle.contains;\njQuery.escapeSelector = Sizzle.escape;\n\n\n\n\nvar dir = function( elem, dir, until ) {\n\tvar matched = [],\n\t\ttruncate = until !== undefined;\n\n\twhile ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {\n\t\tif ( elem.nodeType === 1 ) {\n\t\t\tif ( truncate && jQuery( elem ).is( until ) ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tmatched.push( elem );\n\t\t}\n\t}\n\treturn matched;\n};\n\n\nvar siblings = function( n, elem ) {\n\tvar matched = [];\n\n\tfor ( ; n; n = n.nextSibling ) {\n\t\tif ( n.nodeType === 1 && n !== elem ) {\n\t\t\tmatched.push( n );\n\t\t}\n\t}\n\n\treturn matched;\n};\n\n\nvar rneedsContext = jQuery.expr.match.needsContext;\n\n\n\nfunction nodeName( elem, name ) {\n\n\treturn elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();\n\n}\nvar rsingleTag = ( /^<([a-z][^\\/\\0>:\\x20\\t\\r\\n\\f]*)[\\x20\\t\\r\\n\\f]*\\/?>(?:<\\/\\1>|)$/i );\n\n\n\n// Implement the identical functionality for filter and not\nfunction winnow( elements, qualifier, not ) {\n\tif ( isFunction( qualifier ) ) {\n\t\treturn jQuery.grep( elements, function( elem, i ) {\n\t\t\treturn !!qualifier.call( elem, i, elem ) !== not;\n\t\t} );\n\t}\n\n\t// Single element\n\tif ( qualifier.nodeType ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( elem === qualifier ) !== not;\n\t\t} );\n\t}\n\n\t// Arraylike of elements (jQuery, arguments, Array)\n\tif ( typeof qualifier !== \"string\" ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( indexOf.call( qualifier, elem ) > -1 ) !== not;\n\t\t} );\n\t}\n\n\t// Filtered directly for both simple and complex selectors\n\treturn jQuery.filter( qualifier, elements, not );\n}\n\njQuery.filter = function( expr, elems, not ) {\n\tvar elem = elems[ 0 ];\n\n\tif ( not ) {\n\t\texpr = \":not(\" + expr + \")\";\n\t}\n\n\tif ( elems.length === 1 && elem.nodeType === 1 ) {\n\t\treturn jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];\n\t}\n\n\treturn jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {\n\t\treturn elem.nodeType === 1;\n\t} ) );\n};\n\njQuery.fn.extend( {\n\tfind: function( selector ) {\n\t\tvar i, ret,\n\t\t\tlen = this.length,\n\t\t\tself = this;\n\n\t\tif ( typeof selector !== \"string\" ) {\n\t\t\treturn this.pushStack( jQuery( selector ).filter( function() {\n\t\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\t\tif ( jQuery.contains( self[ i ], this ) ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} ) );\n\t\t}\n\n\t\tret = this.pushStack( [] );\n\n\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\tjQuery.find( selector, self[ i ], ret );\n\t\t}\n\n\t\treturn len > 1 ? jQuery.uniqueSort( ret ) : ret;\n\t},\n\tfilter: function( selector ) {\n\t\treturn this.pushStack( winnow( this, selector || [], false ) );\n\t},\n\tnot: function( selector ) {\n\t\treturn this.pushStack( winnow( this, selector || [], true ) );\n\t},\n\tis: function( selector ) {\n\t\treturn !!winnow(\n\t\t\tthis,\n\n\t\t\t// If this is a positional/relative selector, check membership in the returned set\n\t\t\t// so $(\"p:first\").is(\"p:last\") won't return true for a doc with two \"p\".\n\t\t\ttypeof selector === \"string\" && rneedsContext.test( selector ) ?\n\t\t\t\tjQuery( selector ) :\n\t\t\t\tselector || [],\n\t\t\tfalse\n\t\t).length;\n\t}\n} );\n\n\n// Initialize a jQuery object\n\n\n// A central reference to the root jQuery(document)\nvar rootjQuery,\n\n\t// A simple way to check for HTML strings\n\t// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)\n\t// Strict HTML recognition (#11290: must start with <)\n\t// Shortcut simple #id case for speed\n\trquickExpr = /^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]+))$/,\n\n\tinit = jQuery.fn.init = function( selector, context, root ) {\n\t\tvar match, elem;\n\n\t\t// HANDLE: $(\"\"), $(null), $(undefined), $(false)\n\t\tif ( !selector ) {\n\t\t\treturn this;\n\t\t}\n\n\t\t// Method init() accepts an alternate rootjQuery\n\t\t// so migrate can support jQuery.sub (gh-2101)\n\t\troot = root || rootjQuery;\n\n\t\t// Handle HTML strings\n\t\tif ( typeof selector === \"string\" ) {\n\t\t\tif ( selector[ 0 ] === \"<\" &&\n\t\t\t\tselector[ selector.length - 1 ] === \">\" &&\n\t\t\t\tselector.length >= 3 ) {\n\n\t\t\t\t// Assume that strings that start and end with <> are HTML and skip the regex check\n\t\t\t\tmatch = [ null, selector, null ];\n\n\t\t\t} else {\n\t\t\t\tmatch = rquickExpr.exec( selector );\n\t\t\t}\n\n\t\t\t// Match html or make sure no context is specified for #id\n\t\t\tif ( match && ( match[ 1 ] || !context ) ) {\n\n\t\t\t\t// HANDLE: $(html) -> $(array)\n\t\t\t\tif ( match[ 1 ] ) {\n\t\t\t\t\tcontext = context instanceof jQuery ? context[ 0 ] : context;\n\n\t\t\t\t\t// Option to run scripts is true for back-compat\n\t\t\t\t\t// Intentionally let the error be thrown if parseHTML is not present\n\t\t\t\t\tjQuery.merge( this, jQuery.parseHTML(\n\t\t\t\t\t\tmatch[ 1 ],\n\t\t\t\t\t\tcontext && context.nodeType ? context.ownerDocument || context : document,\n\t\t\t\t\t\ttrue\n\t\t\t\t\t) );\n\n\t\t\t\t\t// HANDLE: $(html, props)\n\t\t\t\t\tif ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {\n\t\t\t\t\t\tfor ( match in context ) {\n\n\t\t\t\t\t\t\t// Properties of context are called as methods if possible\n\t\t\t\t\t\t\tif ( isFunction( this[ match ] ) ) {\n\t\t\t\t\t\t\t\tthis[ match ]( context[ match ] );\n\n\t\t\t\t\t\t\t// ...and otherwise set as attributes\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.attr( match, context[ match ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t// HANDLE: $(#id)\n\t\t\t\t} else {\n\t\t\t\t\telem = document.getElementById( match[ 2 ] );\n\n\t\t\t\t\tif ( elem ) {\n\n\t\t\t\t\t\t// Inject the element directly into the jQuery object\n\t\t\t\t\t\tthis[ 0 ] = elem;\n\t\t\t\t\t\tthis.length = 1;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\n\t\t\t// HANDLE: $(expr, $(...))\n\t\t\t} else if ( !context || context.jquery ) {\n\t\t\t\treturn ( context || root ).find( selector );\n\n\t\t\t// HANDLE: $(expr, context)\n\t\t\t// (which is just equivalent to: $(context).find(expr)\n\t\t\t} else {\n\t\t\t\treturn this.constructor( context ).find( selector );\n\t\t\t}\n\n\t\t// HANDLE: $(DOMElement)\n\t\t} else if ( selector.nodeType ) {\n\t\t\tthis[ 0 ] = selector;\n\t\t\tthis.length = 1;\n\t\t\treturn this;\n\n\t\t// HANDLE: $(function)\n\t\t// Shortcut for document ready\n\t\t} else if ( isFunction( selector ) ) {\n\t\t\treturn root.ready !== undefined ?\n\t\t\t\troot.ready( selector ) :\n\n\t\t\t\t// Execute immediately if ready is not present\n\t\t\t\tselector( jQuery );\n\t\t}\n\n\t\treturn jQuery.makeArray( selector, this );\n\t};\n\n// Give the init function the jQuery prototype for later instantiation\ninit.prototype = jQuery.fn;\n\n// Initialize central reference\nrootjQuery = jQuery( document );\n\n\nvar rparentsprev = /^(?:parents|prev(?:Until|All))/,\n\n\t// Methods guaranteed to produce a unique set when starting from a unique set\n\tguaranteedUnique = {\n\t\tchildren: true,\n\t\tcontents: true,\n\t\tnext: true,\n\t\tprev: true\n\t};\n\njQuery.fn.extend( {\n\thas: function( target ) {\n\t\tvar targets = jQuery( target, this ),\n\t\t\tl = targets.length;\n\n\t\treturn this.filter( function() {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tif ( jQuery.contains( this, targets[ i ] ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t},\n\n\tclosest: function( selectors, context ) {\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tmatched = [],\n\t\t\ttargets = typeof selectors !== \"string\" && jQuery( selectors );\n\n\t\t// Positional selectors never match, since there's no _selection_ context\n\t\tif ( !rneedsContext.test( selectors ) ) {\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tfor ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {\n\n\t\t\t\t\t// Always skip document fragments\n\t\t\t\t\tif ( cur.nodeType < 11 && ( targets ?\n\t\t\t\t\t\ttargets.index( cur ) > -1 :\n\n\t\t\t\t\t\t// Don't pass non-elements to Sizzle\n\t\t\t\t\t\tcur.nodeType === 1 &&\n\t\t\t\t\t\t\tjQuery.find.matchesSelector( cur, selectors ) ) ) {\n\n\t\t\t\t\t\tmatched.push( cur );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );\n\t},\n\n\t// Determine the position of an element within the set\n\tindex: function( elem ) {\n\n\t\t// No argument, return index in parent\n\t\tif ( !elem ) {\n\t\t\treturn ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;\n\t\t}\n\n\t\t// Index in selector\n\t\tif ( typeof elem === \"string\" ) {\n\t\t\treturn indexOf.call( jQuery( elem ), this[ 0 ] );\n\t\t}\n\n\t\t// Locate the position of the desired element\n\t\treturn indexOf.call( this,\n\n\t\t\t// If it receives a jQuery object, the first element is used\n\t\t\telem.jquery ? elem[ 0 ] : elem\n\t\t);\n\t},\n\n\tadd: function( selector, context ) {\n\t\treturn this.pushStack(\n\t\t\tjQuery.uniqueSort(\n\t\t\t\tjQuery.merge( this.get(), jQuery( selector, context ) )\n\t\t\t)\n\t\t);\n\t},\n\n\taddBack: function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter( selector )\n\t\t);\n\t}\n} );\n\nfunction sibling( cur, dir ) {\n\twhile ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}\n\treturn cur;\n}\n\njQuery.each( {\n\tparent: function( elem ) {\n\t\tvar parent = elem.parentNode;\n\t\treturn parent && parent.nodeType !== 11 ? parent : null;\n\t},\n\tparents: function( elem ) {\n\t\treturn dir( elem, \"parentNode\" );\n\t},\n\tparentsUntil: function( elem, _i, until ) {\n\t\treturn dir( elem, \"parentNode\", until );\n\t},\n\tnext: function( elem ) {\n\t\treturn sibling( elem, \"nextSibling\" );\n\t},\n\tprev: function( elem ) {\n\t\treturn sibling( elem, \"previousSibling\" );\n\t},\n\tnextAll: function( elem ) {\n\t\treturn dir( elem, \"nextSibling\" );\n\t},\n\tprevAll: function( elem ) {\n\t\treturn dir( elem, \"previousSibling\" );\n\t},\n\tnextUntil: function( elem, _i, until ) {\n\t\treturn dir( elem, \"nextSibling\", until );\n\t},\n\tprevUntil: function( elem, _i, until ) {\n\t\treturn dir( elem, \"previousSibling\", until );\n\t},\n\tsiblings: function( elem ) {\n\t\treturn siblings( ( elem.parentNode || {} ).firstChild, elem );\n\t},\n\tchildren: function( elem ) {\n\t\treturn siblings( elem.firstChild );\n\t},\n\tcontents: function( elem ) {\n\t\tif ( elem.contentDocument != null &&\n\n\t\t\t// Support: IE 11+\n\t\t\t// <object> elements with no `data` attribute has an object\n\t\t\t// `contentDocument` with a `null` prototype.\n\t\t\tgetProto( elem.contentDocument ) ) {\n\n\t\t\treturn elem.contentDocument;\n\t\t}\n\n\t\t// Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only\n\t\t// Treat the template element as a regular one in browsers that\n\t\t// don't support it.\n\t\tif ( nodeName( elem, \"template\" ) ) {\n\t\t\telem = elem.content || elem;\n\t\t}\n\n\t\treturn jQuery.merge( [], elem.childNodes );\n\t}\n}, function( name, fn ) {\n\tjQuery.fn[ name ] = function( until, selector ) {\n\t\tvar matched = jQuery.map( this, fn, until );\n\n\t\tif ( name.slice( -5 ) !== \"Until\" ) {\n\t\t\tselector = until;\n\t\t}\n\n\t\tif ( selector && typeof selector === \"string\" ) {\n\t\t\tmatched = jQuery.filter( selector, matched );\n\t\t}\n\n\t\tif ( this.length > 1 ) {\n\n\t\t\t// Remove duplicates\n\t\t\tif ( !guaranteedUnique[ name ] ) {\n\t\t\t\tjQuery.uniqueSort( matched );\n\t\t\t}\n\n\t\t\t// Reverse order for parents* and prev-derivatives\n\t\t\tif ( rparentsprev.test( name ) ) {\n\t\t\t\tmatched.reverse();\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched );\n\t};\n} );\nvar rnothtmlwhite = ( /[^\\x20\\t\\r\\n\\f]+/g );\n\n\n\n// Convert String-formatted options into Object-formatted ones\nfunction createOptions( options ) {\n\tvar object = {};\n\tjQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {\n\t\tobject[ flag ] = true;\n\t} );\n\treturn object;\n}\n\n/*\n * Create a callback list using the following parameters:\n *\n *\toptions: an optional list of space-separated options that will change how\n *\t\t\tthe callback list behaves or a more traditional option object\n *\n * By default a callback list will act like an event callback list and can be\n * \"fired\" multiple times.\n *\n * Possible options:\n *\n *\tonce:\t\t\twill ensure the callback list can only be fired once (like a Deferred)\n *\n *\tmemory:\t\t\twill keep track of previous values and will call any callback added\n *\t\t\t\t\tafter the list has been fired right away with the latest \"memorized\"\n *\t\t\t\t\tvalues (like a Deferred)\n *\n *\tunique:\t\t\twill ensure a callback can only be added once (no duplicate in the list)\n *\n *\tstopOnFalse:\tinterrupt callings when a callback returns false\n *\n */\njQuery.Callbacks = function( options ) {\n\n\t// Convert options from String-formatted to Object-formatted if needed\n\t// (we check in cache first)\n\toptions = typeof options === \"string\" ?\n\t\tcreateOptions( options ) :\n\t\tjQuery.extend( {}, options );\n\n\tvar // Flag to know if list is currently firing\n\t\tfiring,\n\n\t\t// Last fire value for non-forgettable lists\n\t\tmemory,\n\n\t\t// Flag to know if list was already fired\n\t\tfired,\n\n\t\t// Flag to prevent firing\n\t\tlocked,\n\n\t\t// Actual callback list\n\t\tlist = [],\n\n\t\t// Queue of execution data for repeatable lists\n\t\tqueue = [],\n\n\t\t// Index of currently firing callback (modified by add/remove as needed)\n\t\tfiringIndex = -1,\n\n\t\t// Fire callbacks\n\t\tfire = function() {\n\n\t\t\t// Enforce single-firing\n\t\t\tlocked = locked || options.once;\n\n\t\t\t// Execute callbacks for all pending executions,\n\t\t\t// respecting firingIndex overrides and runtime changes\n\t\t\tfired = firing = true;\n\t\t\tfor ( ; queue.length; firingIndex = -1 ) {\n\t\t\t\tmemory = queue.shift();\n\t\t\t\twhile ( ++firingIndex < list.length ) {\n\n\t\t\t\t\t// Run callback and check for early termination\n\t\t\t\t\tif ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&\n\t\t\t\t\t\toptions.stopOnFalse ) {\n\n\t\t\t\t\t\t// Jump to end and forget the data so .add doesn't re-fire\n\t\t\t\t\t\tfiringIndex = list.length;\n\t\t\t\t\t\tmemory = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Forget the data if we're done with it\n\t\t\tif ( !options.memory ) {\n\t\t\t\tmemory = false;\n\t\t\t}\n\n\t\t\tfiring = false;\n\n\t\t\t// Clean up if we're done firing for good\n\t\t\tif ( locked ) {\n\n\t\t\t\t// Keep an empty list if we have data for future add calls\n\t\t\t\tif ( memory ) {\n\t\t\t\t\tlist = [];\n\n\t\t\t\t// Otherwise, this object is spent\n\t\t\t\t} else {\n\t\t\t\t\tlist = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t// Actual Callbacks object\n\t\tself = {\n\n\t\t\t// Add a callback or a collection of callbacks to the list\n\t\t\tadd: function() {\n\t\t\t\tif ( list ) {\n\n\t\t\t\t\t// If we have memory from a past run, we should fire after adding\n\t\t\t\t\tif ( memory && !firing ) {\n\t\t\t\t\t\tfiringIndex = list.length - 1;\n\t\t\t\t\t\tqueue.push( memory );\n\t\t\t\t\t}\n\n\t\t\t\t\t( function add( args ) {\n\t\t\t\t\t\tjQuery.each( args, function( _, arg ) {\n\t\t\t\t\t\t\tif ( isFunction( arg ) ) {\n\t\t\t\t\t\t\t\tif ( !options.unique || !self.has( arg ) ) {\n\t\t\t\t\t\t\t\t\tlist.push( arg );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if ( arg && arg.length && toType( arg ) !== \"string\" ) {\n\n\t\t\t\t\t\t\t\t// Inspect recursively\n\t\t\t\t\t\t\t\tadd( arg );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} );\n\t\t\t\t\t} )( arguments );\n\n\t\t\t\t\tif ( memory && !firing ) {\n\t\t\t\t\t\tfire();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Remove a callback from the list\n\t\t\tremove: function() {\n\t\t\t\tjQuery.each( arguments, function( _, arg ) {\n\t\t\t\t\tvar index;\n\t\t\t\t\twhile ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {\n\t\t\t\t\t\tlist.splice( index, 1 );\n\n\t\t\t\t\t\t// Handle firing indexes\n\t\t\t\t\t\tif ( index <= firingIndex ) {\n\t\t\t\t\t\t\tfiringIndex--;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Check if a given callback is in the list.\n\t\t\t// If no argument is given, return whether or not list has callbacks attached.\n\t\t\thas: function( fn ) {\n\t\t\t\treturn fn ?\n\t\t\t\t\tjQuery.inArray( fn, list ) > -1 :\n\t\t\t\t\tlist.length > 0;\n\t\t\t},\n\n\t\t\t// Remove all callbacks from the list\n\t\t\tempty: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\tlist = [];\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Disable .fire and .add\n\t\t\t// Abort any current/pending executions\n\t\t\t// Clear all callbacks and values\n\t\t\tdisable: function() {\n\t\t\t\tlocked = queue = [];\n\t\t\t\tlist = memory = \"\";\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tdisabled: function() {\n\t\t\t\treturn !list;\n\t\t\t},\n\n\t\t\t// Disable .fire\n\t\t\t// Also disable .add unless we have memory (since it would have no effect)\n\t\t\t// Abort any pending executions\n\t\t\tlock: function() {\n\t\t\t\tlocked = queue = [];\n\t\t\t\tif ( !memory && !firing ) {\n\t\t\t\t\tlist = memory = \"\";\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tlocked: function() {\n\t\t\t\treturn !!locked;\n\t\t\t},\n\n\t\t\t// Call all callbacks with the given context and arguments\n\t\t\tfireWith: function( context, args ) {\n\t\t\t\tif ( !locked ) {\n\t\t\t\t\targs = args || [];\n\t\t\t\t\targs = [ context, args.slice ? args.slice() : args ];\n\t\t\t\t\tqueue.push( args );\n\t\t\t\t\tif ( !firing ) {\n\t\t\t\t\t\tfire();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Call all the callbacks with the given arguments\n\t\t\tfire: function() {\n\t\t\t\tself.fireWith( this, arguments );\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// To know if the callbacks have already been called at least once\n\t\t\tfired: function() {\n\t\t\t\treturn !!fired;\n\t\t\t}\n\t\t};\n\n\treturn self;\n};\n\n\nfunction Identity( v ) {\n\treturn v;\n}\nfunction Thrower( ex ) {\n\tthrow ex;\n}\n\nfunction adoptValue( value, resolve, reject, noValue ) {\n\tvar method;\n\n\ttry {\n\n\t\t// Check for promise aspect first to privilege synchronous behavior\n\t\tif ( value && isFunction( ( method = value.promise ) ) ) {\n\t\t\tmethod.call( value ).done( resolve ).fail( reject );\n\n\t\t// Other thenables\n\t\t} else if ( value && isFunction( ( method = value.then ) ) ) {\n\t\t\tmethod.call( value, resolve, reject );\n\n\t\t// Other non-thenables\n\t\t} else {\n\n\t\t\t// Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:\n\t\t\t// * false: [ value ].slice( 0 ) => resolve( value )\n\t\t\t// * true: [ value ].slice( 1 ) => resolve()\n\t\t\tresolve.apply( undefined, [ value ].slice( noValue ) );\n\t\t}\n\n\t// For Promises/A+, convert exceptions into rejections\n\t// Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in\n\t// Deferred#then to conditionally suppress rejection.\n\t} catch ( value ) {\n\n\t\t// Support: Android 4.0 only\n\t\t// Strict mode functions invoked without .call/.apply get global-object context\n\t\treject.apply( undefined, [ value ] );\n\t}\n}\n\njQuery.extend( {\n\n\tDeferred: function( func ) {\n\t\tvar tuples = [\n\n\t\t\t\t// action, add listener, callbacks,\n\t\t\t\t// ... .then handlers, argument index, [final state]\n\t\t\t\t[ \"notify\", \"progress\", jQuery.Callbacks( \"memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"memory\" ), 2 ],\n\t\t\t\t[ \"resolve\", \"done\", jQuery.Callbacks( \"once memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"once memory\" ), 0, \"resolved\" ],\n\t\t\t\t[ \"reject\", \"fail\", jQuery.Callbacks( \"once memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"once memory\" ), 1, \"rejected\" ]\n\t\t\t],\n\t\t\tstate = \"pending\",\n\t\t\tpromise = {\n\t\t\t\tstate: function() {\n\t\t\t\t\treturn state;\n\t\t\t\t},\n\t\t\t\talways: function() {\n\t\t\t\t\tdeferred.done( arguments ).fail( arguments );\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\t\t\t\t\"catch\": function( fn ) {\n\t\t\t\t\treturn promise.then( null, fn );\n\t\t\t\t},\n\n\t\t\t\t// Keep pipe for back-compat\n\t\t\t\tpipe: function( /* fnDone, fnFail, fnProgress */ ) {\n\t\t\t\t\tvar fns = arguments;\n\n\t\t\t\t\treturn jQuery.Deferred( function( newDefer ) {\n\t\t\t\t\t\tjQuery.each( tuples, function( _i, tuple ) {\n\n\t\t\t\t\t\t\t// Map tuples (progress, done, fail) to arguments (done, fail, progress)\n\t\t\t\t\t\t\tvar fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];\n\n\t\t\t\t\t\t\t// deferred.progress(function() { bind to newDefer or newDefer.notify })\n\t\t\t\t\t\t\t// deferred.done(function() { bind to newDefer or newDefer.resolve })\n\t\t\t\t\t\t\t// deferred.fail(function() { bind to newDefer or newDefer.reject })\n\t\t\t\t\t\t\tdeferred[ tuple[ 1 ] ]( function() {\n\t\t\t\t\t\t\t\tvar returned = fn && fn.apply( this, arguments );\n\t\t\t\t\t\t\t\tif ( returned && isFunction( returned.promise ) ) {\n\t\t\t\t\t\t\t\t\treturned.promise()\n\t\t\t\t\t\t\t\t\t\t.progress( newDefer.notify )\n\t\t\t\t\t\t\t\t\t\t.done( newDefer.resolve )\n\t\t\t\t\t\t\t\t\t\t.fail( newDefer.reject );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tnewDefer[ tuple[ 0 ] + \"With\" ](\n\t\t\t\t\t\t\t\t\t\tthis,\n\t\t\t\t\t\t\t\t\t\tfn ? [ returned ] : arguments\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t} );\n\t\t\t\t\t\tfns = null;\n\t\t\t\t\t} ).promise();\n\t\t\t\t},\n\t\t\t\tthen: function( onFulfilled, onRejected, onProgress ) {\n\t\t\t\t\tvar maxDepth = 0;\n\t\t\t\t\tfunction resolve( depth, deferred, handler, special ) {\n\t\t\t\t\t\treturn function() {\n\t\t\t\t\t\t\tvar that = this,\n\t\t\t\t\t\t\t\targs = arguments,\n\t\t\t\t\t\t\t\tmightThrow = function() {\n\t\t\t\t\t\t\t\t\tvar returned, then;\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.3\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-59\n\t\t\t\t\t\t\t\t\t// Ignore double-resolution attempts\n\t\t\t\t\t\t\t\t\tif ( depth < maxDepth ) {\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\treturned = handler.apply( that, args );\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.1\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-48\n\t\t\t\t\t\t\t\t\tif ( returned === deferred.promise() ) {\n\t\t\t\t\t\t\t\t\t\tthrow new TypeError( \"Thenable self-resolution\" );\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ sections 2.3.3.1, 3.5\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-54\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-75\n\t\t\t\t\t\t\t\t\t// Retrieve `then` only once\n\t\t\t\t\t\t\t\t\tthen = returned &&\n\n\t\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.4\n\t\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-64\n\t\t\t\t\t\t\t\t\t\t// Only check objects and functions for thenability\n\t\t\t\t\t\t\t\t\t\t( typeof returned === \"object\" ||\n\t\t\t\t\t\t\t\t\t\t\ttypeof returned === \"function\" ) &&\n\t\t\t\t\t\t\t\t\t\treturned.then;\n\n\t\t\t\t\t\t\t\t\t// Handle a returned thenable\n\t\t\t\t\t\t\t\t\tif ( isFunction( then ) ) {\n\n\t\t\t\t\t\t\t\t\t\t// Special processors (notify) just wait for resolution\n\t\t\t\t\t\t\t\t\t\tif ( special ) {\n\t\t\t\t\t\t\t\t\t\t\tthen.call(\n\t\t\t\t\t\t\t\t\t\t\t\treturned,\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Thrower, special )\n\t\t\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\t\t// Normal processors (resolve) also hook into progress\n\t\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\t\t// ...and disregard older resolution values\n\t\t\t\t\t\t\t\t\t\t\tmaxDepth++;\n\n\t\t\t\t\t\t\t\t\t\t\tthen.call(\n\t\t\t\t\t\t\t\t\t\t\t\treturned,\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Thrower, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity,\n\t\t\t\t\t\t\t\t\t\t\t\t\tdeferred.notifyWith )\n\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Handle all other returned values\n\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\t// Only substitute handlers pass on context\n\t\t\t\t\t\t\t\t\t\t// and multiple values (non-spec behavior)\n\t\t\t\t\t\t\t\t\t\tif ( handler !== Identity ) {\n\t\t\t\t\t\t\t\t\t\t\tthat = undefined;\n\t\t\t\t\t\t\t\t\t\t\targs = [ returned ];\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t// Process the value(s)\n\t\t\t\t\t\t\t\t\t\t// Default process is resolve\n\t\t\t\t\t\t\t\t\t\t( special || deferred.resolveWith )( that, args );\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\n\t\t\t\t\t\t\t\t// Only normal processors (resolve) catch and reject exceptions\n\t\t\t\t\t\t\t\tprocess = special ?\n\t\t\t\t\t\t\t\t\tmightThrow :\n\t\t\t\t\t\t\t\t\tfunction() {\n\t\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\t\tmightThrow();\n\t\t\t\t\t\t\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\t\t\t\t\t\t\tif ( jQuery.Deferred.exceptionHook ) {\n\t\t\t\t\t\t\t\t\t\t\t\tjQuery.Deferred.exceptionHook( e,\n\t\t\t\t\t\t\t\t\t\t\t\t\tprocess.stackTrace );\n\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.4.1\n\t\t\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-61\n\t\t\t\t\t\t\t\t\t\t\t// Ignore post-resolution exceptions\n\t\t\t\t\t\t\t\t\t\t\tif ( depth + 1 >= maxDepth ) {\n\n\t\t\t\t\t\t\t\t\t\t\t\t// Only substitute handlers pass on context\n\t\t\t\t\t\t\t\t\t\t\t\t// and multiple values (non-spec behavior)\n\t\t\t\t\t\t\t\t\t\t\t\tif ( handler !== Thrower ) {\n\t\t\t\t\t\t\t\t\t\t\t\t\tthat = undefined;\n\t\t\t\t\t\t\t\t\t\t\t\t\targs = [ e ];\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t\tdeferred.rejectWith( that, args );\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.1\n\t\t\t\t\t\t\t// https://promisesaplus.com/#point-57\n\t\t\t\t\t\t\t// Re-resolve promises immediately to dodge false rejection from\n\t\t\t\t\t\t\t// subsequent errors\n\t\t\t\t\t\t\tif ( depth ) {\n\t\t\t\t\t\t\t\tprocess();\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t// Call an optional hook to record the stack, in case of exception\n\t\t\t\t\t\t\t\t// since it's otherwise lost when execution goes async\n\t\t\t\t\t\t\t\tif ( jQuery.Deferred.getStackHook ) {\n\t\t\t\t\t\t\t\t\tprocess.stackTrace = jQuery.Deferred.getStackHook();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\twindow.setTimeout( process );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\treturn jQuery.Deferred( function( newDefer ) {\n\n\t\t\t\t\t\t// progress_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 0 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tisFunction( onProgress ) ?\n\t\t\t\t\t\t\t\t\tonProgress :\n\t\t\t\t\t\t\t\t\tIdentity,\n\t\t\t\t\t\t\t\tnewDefer.notifyWith\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// fulfilled_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 1 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tisFunction( onFulfilled ) ?\n\t\t\t\t\t\t\t\t\tonFulfilled :\n\t\t\t\t\t\t\t\t\tIdentity\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// rejected_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 2 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tisFunction( onRejected ) ?\n\t\t\t\t\t\t\t\t\tonRejected :\n\t\t\t\t\t\t\t\t\tThrower\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\t\t\t\t\t} ).promise();\n\t\t\t\t},\n\n\t\t\t\t// Get a promise for this deferred\n\t\t\t\t// If obj is provided, the promise aspect is added to the object\n\t\t\t\tpromise: function( obj ) {\n\t\t\t\t\treturn obj != null ? jQuery.extend( obj, promise ) : promise;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdeferred = {};\n\n\t\t// Add list-specific methods\n\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\tvar list = tuple[ 2 ],\n\t\t\t\tstateString = tuple[ 5 ];\n\n\t\t\t// promise.progress = list.add\n\t\t\t// promise.done = list.add\n\t\t\t// promise.fail = list.add\n\t\t\tpromise[ tuple[ 1 ] ] = list.add;\n\n\t\t\t// Handle state\n\t\t\tif ( stateString ) {\n\t\t\t\tlist.add(\n\t\t\t\t\tfunction() {\n\n\t\t\t\t\t\t// state = \"resolved\" (i.e., fulfilled)\n\t\t\t\t\t\t// state = \"rejected\"\n\t\t\t\t\t\tstate = stateString;\n\t\t\t\t\t},\n\n\t\t\t\t\t// rejected_callbacks.disable\n\t\t\t\t\t// fulfilled_callbacks.disable\n\t\t\t\t\ttuples[ 3 - i ][ 2 ].disable,\n\n\t\t\t\t\t// rejected_handlers.disable\n\t\t\t\t\t// fulfilled_handlers.disable\n\t\t\t\t\ttuples[ 3 - i ][ 3 ].disable,\n\n\t\t\t\t\t// progress_callbacks.lock\n\t\t\t\t\ttuples[ 0 ][ 2 ].lock,\n\n\t\t\t\t\t// progress_handlers.lock\n\t\t\t\t\ttuples[ 0 ][ 3 ].lock\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// progress_handlers.fire\n\t\t\t// fulfilled_handlers.fire\n\t\t\t// rejected_handlers.fire\n\t\t\tlist.add( tuple[ 3 ].fire );\n\n\t\t\t// deferred.notify = function() { deferred.notifyWith(...) }\n\t\t\t// deferred.resolve = function() { deferred.resolveWith(...) }\n\t\t\t// deferred.reject = function() { deferred.rejectWith(...) }\n\t\t\tdeferred[ tuple[ 0 ] ] = function() {\n\t\t\t\tdeferred[ tuple[ 0 ] + \"With\" ]( this === deferred ? undefined : this, arguments );\n\t\t\t\treturn this;\n\t\t\t};\n\n\t\t\t// deferred.notifyWith = list.fireWith\n\t\t\t// deferred.resolveWith = list.fireWith\n\t\t\t// deferred.rejectWith = list.fireWith\n\t\t\tdeferred[ tuple[ 0 ] + \"With\" ] = list.fireWith;\n\t\t} );\n\n\t\t// Make the deferred a promise\n\t\tpromise.promise( deferred );\n\n\t\t// Call given func if any\n\t\tif ( func ) {\n\t\t\tfunc.call( deferred, deferred );\n\t\t}\n\n\t\t// All done!\n\t\treturn deferred;\n\t},\n\n\t// Deferred helper\n\twhen: function( singleValue ) {\n\t\tvar\n\n\t\t\t// count of uncompleted subordinates\n\t\t\tremaining = arguments.length,\n\n\t\t\t// count of unprocessed arguments\n\t\t\ti = remaining,\n\n\t\t\t// subordinate fulfillment data\n\t\t\tresolveContexts = Array( i ),\n\t\t\tresolveValues = slice.call( arguments ),\n\n\t\t\t// the primary Deferred\n\t\t\tprimary = jQuery.Deferred(),\n\n\t\t\t// subordinate callback factory\n\t\t\tupdateFunc = function( i ) {\n\t\t\t\treturn function( value ) {\n\t\t\t\t\tresolveContexts[ i ] = this;\n\t\t\t\t\tresolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;\n\t\t\t\t\tif ( !( --remaining ) ) {\n\t\t\t\t\t\tprimary.resolveWith( resolveContexts, resolveValues );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t};\n\n\t\t// Single- and empty arguments are adopted like Promise.resolve\n\t\tif ( remaining <= 1 ) {\n\t\t\tadoptValue( singleValue, primary.done( updateFunc( i ) ).resolve, primary.reject,\n\t\t\t\t!remaining );\n\n\t\t\t// Use .then() to unwrap secondary thenables (cf. gh-3000)\n\t\t\tif ( primary.state() === \"pending\" ||\n\t\t\t\tisFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {\n\n\t\t\t\treturn primary.then();\n\t\t\t}\n\t\t}\n\n\t\t// Multiple arguments are aggregated like Promise.all array elements\n\t\twhile ( i-- ) {\n\t\t\tadoptValue( resolveValues[ i ], updateFunc( i ), primary.reject );\n\t\t}\n\n\t\treturn primary.promise();\n\t}\n} );\n\n\n// These usually indicate a programmer mistake during development,\n// warn about them ASAP rather than swallowing them by default.\nvar rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;\n\njQuery.Deferred.exceptionHook = function( error, stack ) {\n\n\t// Support: IE 8 - 9 only\n\t// Console exists when dev tools are open, which can happen at any time\n\tif ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {\n\t\twindow.console.warn( \"jQuery.Deferred exception: \" + error.message, error.stack, stack );\n\t}\n};\n\n\n\n\njQuery.readyException = function( error ) {\n\twindow.setTimeout( function() {\n\t\tthrow error;\n\t} );\n};\n\n\n\n\n// The deferred used on DOM ready\nvar readyList = jQuery.Deferred();\n\njQuery.fn.ready = function( fn ) {\n\n\treadyList\n\t\t.then( fn )\n\n\t\t// Wrap jQuery.readyException in a function so that the lookup\n\t\t// happens at the time of error handling instead of callback\n\t\t// registration.\n\t\t.catch( function( error ) {\n\t\t\tjQuery.readyException( error );\n\t\t} );\n\n\treturn this;\n};\n\njQuery.extend( {\n\n\t// Is the DOM ready to be used? Set to true once it occurs.\n\tisReady: false,\n\n\t// A counter to track how many items to wait for before\n\t// the ready event fires. See #6781\n\treadyWait: 1,\n\n\t// Handle when the DOM is ready\n\tready: function( wait ) {\n\n\t\t// Abort if there are pending holds or we're already ready\n\t\tif ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Remember that the DOM is ready\n\t\tjQuery.isReady = true;\n\n\t\t// If a normal DOM Ready event fired, decrement, and wait if need be\n\t\tif ( wait !== true && --jQuery.readyWait > 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If there are functions bound, to execute\n\t\treadyList.resolveWith( document, [ jQuery ] );\n\t}\n} );\n\njQuery.ready.then = readyList.then;\n\n// The ready event handler and self cleanup method\nfunction completed() {\n\tdocument.removeEventListener( \"DOMContentLoaded\", completed );\n\twindow.removeEventListener( \"load\", completed );\n\tjQuery.ready();\n}\n\n// Catch cases where $(document).ready() is called\n// after the browser event has already occurred.\n// Support: IE <=9 - 10 only\n// Older IE sometimes signals \"interactive\" too soon\nif ( document.readyState === \"complete\" ||\n\t( document.readyState !== \"loading\" && !document.documentElement.doScroll ) ) {\n\n\t// Handle it asynchronously to allow scripts the opportunity to delay ready\n\twindow.setTimeout( jQuery.ready );\n\n} else {\n\n\t// Use the handy event callback\n\tdocument.addEventListener( \"DOMContentLoaded\", completed );\n\n\t// A fallback to window.onload, that will always work\n\twindow.addEventListener( \"load\", completed );\n}\n\n\n\n\n// Multifunctional method to get and set values of a collection\n// The value/s can optionally be executed if it's a function\nvar access = function( elems, fn, key, value, chainable, emptyGet, raw ) {\n\tvar i = 0,\n\t\tlen = elems.length,\n\t\tbulk = key == null;\n\n\t// Sets many values\n\tif ( toType( key ) === \"object\" ) {\n\t\tchainable = true;\n\t\tfor ( i in key ) {\n\t\t\taccess( elems, fn, i, key[ i ], true, emptyGet, raw );\n\t\t}\n\n\t// Sets one value\n\t} else if ( value !== undefined ) {\n\t\tchainable = true;\n\n\t\tif ( !isFunction( value ) ) {\n\t\t\traw = true;\n\t\t}\n\n\t\tif ( bulk ) {\n\n\t\t\t// Bulk operations run against the entire set\n\t\t\tif ( raw ) {\n\t\t\t\tfn.call( elems, value );\n\t\t\t\tfn = null;\n\n\t\t\t// ...except when executing function values\n\t\t\t} else {\n\t\t\t\tbulk = fn;\n\t\t\t\tfn = function( elem, _key, value ) {\n\t\t\t\t\treturn bulk.call( jQuery( elem ), value );\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tif ( fn ) {\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\tfn(\n\t\t\t\t\telems[ i ], key, raw ?\n\t\t\t\t\t\tvalue :\n\t\t\t\t\t\tvalue.call( elems[ i ], i, fn( elems[ i ], key ) )\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( chainable ) {\n\t\treturn elems;\n\t}\n\n\t// Gets\n\tif ( bulk ) {\n\t\treturn fn.call( elems );\n\t}\n\n\treturn len ? fn( elems[ 0 ], key ) : emptyGet;\n};\n\n\n// Matches dashed string for camelizing\nvar rmsPrefix = /^-ms-/,\n\trdashAlpha = /-([a-z])/g;\n\n// Used by camelCase as callback to replace()\nfunction fcamelCase( _all, letter ) {\n\treturn letter.toUpperCase();\n}\n\n// Convert dashed to camelCase; used by the css and data modules\n// Support: IE <=9 - 11, Edge 12 - 15\n// Microsoft forgot to hump their vendor prefix (#9572)\nfunction camelCase( string ) {\n\treturn string.replace( rmsPrefix, \"ms-\" ).replace( rdashAlpha, fcamelCase );\n}\nvar acceptData = function( owner ) {\n\n\t// Accepts only:\n\t//  - Node\n\t//    - Node.ELEMENT_NODE\n\t//    - Node.DOCUMENT_NODE\n\t//  - Object\n\t//    - Any\n\treturn owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );\n};\n\n\n\n\nfunction Data() {\n\tthis.expando = jQuery.expando + Data.uid++;\n}\n\nData.uid = 1;\n\nData.prototype = {\n\n\tcache: function( owner ) {\n\n\t\t// Check if the owner object already has a cache\n\t\tvar value = owner[ this.expando ];\n\n\t\t// If not, create one\n\t\tif ( !value ) {\n\t\t\tvalue = {};\n\n\t\t\t// We can accept data for non-element nodes in modern browsers,\n\t\t\t// but we should not, see #8335.\n\t\t\t// Always return an empty object.\n\t\t\tif ( acceptData( owner ) ) {\n\n\t\t\t\t// If it is a node unlikely to be stringify-ed or looped over\n\t\t\t\t// use plain assignment\n\t\t\t\tif ( owner.nodeType ) {\n\t\t\t\t\towner[ this.expando ] = value;\n\n\t\t\t\t// Otherwise secure it in a non-enumerable property\n\t\t\t\t// configurable must be true to allow the property to be\n\t\t\t\t// deleted when data is removed\n\t\t\t\t} else {\n\t\t\t\t\tObject.defineProperty( owner, this.expando, {\n\t\t\t\t\t\tvalue: value,\n\t\t\t\t\t\tconfigurable: true\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn value;\n\t},\n\tset: function( owner, data, value ) {\n\t\tvar prop,\n\t\t\tcache = this.cache( owner );\n\n\t\t// Handle: [ owner, key, value ] args\n\t\t// Always use camelCase key (gh-2257)\n\t\tif ( typeof data === \"string\" ) {\n\t\t\tcache[ camelCase( data ) ] = value;\n\n\t\t// Handle: [ owner, { properties } ] args\n\t\t} else {\n\n\t\t\t// Copy the properties one-by-one to the cache object\n\t\t\tfor ( prop in data ) {\n\t\t\t\tcache[ camelCase( prop ) ] = data[ prop ];\n\t\t\t}\n\t\t}\n\t\treturn cache;\n\t},\n\tget: function( owner, key ) {\n\t\treturn key === undefined ?\n\t\t\tthis.cache( owner ) :\n\n\t\t\t// Always use camelCase key (gh-2257)\n\t\t\towner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ];\n\t},\n\taccess: function( owner, key, value ) {\n\n\t\t// In cases where either:\n\t\t//\n\t\t//   1. No key was specified\n\t\t//   2. A string key was specified, but no value provided\n\t\t//\n\t\t// Take the \"read\" path and allow the get method to determine\n\t\t// which value to return, respectively either:\n\t\t//\n\t\t//   1. The entire cache object\n\t\t//   2. The data stored at the key\n\t\t//\n\t\tif ( key === undefined ||\n\t\t\t\t( ( key && typeof key === \"string\" ) && value === undefined ) ) {\n\n\t\t\treturn this.get( owner, key );\n\t\t}\n\n\t\t// When the key is not a string, or both a key and value\n\t\t// are specified, set or extend (existing objects) with either:\n\t\t//\n\t\t//   1. An object of properties\n\t\t//   2. A key and value\n\t\t//\n\t\tthis.set( owner, key, value );\n\n\t\t// Since the \"set\" path can have two possible entry points\n\t\t// return the expected data based on which path was taken[*]\n\t\treturn value !== undefined ? value : key;\n\t},\n\tremove: function( owner, key ) {\n\t\tvar i,\n\t\t\tcache = owner[ this.expando ];\n\n\t\tif ( cache === undefined ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( key !== undefined ) {\n\n\t\t\t// Support array or space separated string of keys\n\t\t\tif ( Array.isArray( key ) ) {\n\n\t\t\t\t// If key is an array of keys...\n\t\t\t\t// We always set camelCase keys, so remove that.\n\t\t\t\tkey = key.map( camelCase );\n\t\t\t} else {\n\t\t\t\tkey = camelCase( key );\n\n\t\t\t\t// If a key with the spaces exists, use it.\n\t\t\t\t// Otherwise, create an array by matching non-whitespace\n\t\t\t\tkey = key in cache ?\n\t\t\t\t\t[ key ] :\n\t\t\t\t\t( key.match( rnothtmlwhite ) || [] );\n\t\t\t}\n\n\t\t\ti = key.length;\n\n\t\t\twhile ( i-- ) {\n\t\t\t\tdelete cache[ key[ i ] ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove the expando if there's no more data\n\t\tif ( key === undefined || jQuery.isEmptyObject( cache ) ) {\n\n\t\t\t// Support: Chrome <=35 - 45\n\t\t\t// Webkit & Blink performance suffers when deleting properties\n\t\t\t// from DOM nodes, so set to undefined instead\n\t\t\t// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)\n\t\t\tif ( owner.nodeType ) {\n\t\t\t\towner[ this.expando ] = undefined;\n\t\t\t} else {\n\t\t\t\tdelete owner[ this.expando ];\n\t\t\t}\n\t\t}\n\t},\n\thasData: function( owner ) {\n\t\tvar cache = owner[ this.expando ];\n\t\treturn cache !== undefined && !jQuery.isEmptyObject( cache );\n\t}\n};\nvar dataPriv = new Data();\n\nvar dataUser = new Data();\n\n\n\n//\tImplementation Summary\n//\n//\t1. Enforce API surface and semantic compatibility with 1.9.x branch\n//\t2. Improve the module's maintainability by reducing the storage\n//\t\tpaths to a single mechanism.\n//\t3. Use the same single mechanism to support \"private\" and \"user\" data.\n//\t4. _Never_ expose \"private\" data to user code (TODO: Drop _data, _removeData)\n//\t5. Avoid exposing implementation details on user objects (eg. expando properties)\n//\t6. Provide a clear path for implementation upgrade to WeakMap in 2014\n\nvar rbrace = /^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,\n\trmultiDash = /[A-Z]/g;\n\nfunction getData( data ) {\n\tif ( data === \"true\" ) {\n\t\treturn true;\n\t}\n\n\tif ( data === \"false\" ) {\n\t\treturn false;\n\t}\n\n\tif ( data === \"null\" ) {\n\t\treturn null;\n\t}\n\n\t// Only convert to a number if it doesn't change the string\n\tif ( data === +data + \"\" ) {\n\t\treturn +data;\n\t}\n\n\tif ( rbrace.test( data ) ) {\n\t\treturn JSON.parse( data );\n\t}\n\n\treturn data;\n}\n\nfunction dataAttr( elem, key, data ) {\n\tvar name;\n\n\t// If nothing was found internally, try to fetch any\n\t// data from the HTML5 data-* attribute\n\tif ( data === undefined && elem.nodeType === 1 ) {\n\t\tname = \"data-\" + key.replace( rmultiDash, \"-$&\" ).toLowerCase();\n\t\tdata = elem.getAttribute( name );\n\n\t\tif ( typeof data === \"string\" ) {\n\t\t\ttry {\n\t\t\t\tdata = getData( data );\n\t\t\t} catch ( e ) {}\n\n\t\t\t// Make sure we set the data so it isn't changed later\n\t\t\tdataUser.set( elem, key, data );\n\t\t} else {\n\t\t\tdata = undefined;\n\t\t}\n\t}\n\treturn data;\n}\n\njQuery.extend( {\n\thasData: function( elem ) {\n\t\treturn dataUser.hasData( elem ) || dataPriv.hasData( elem );\n\t},\n\n\tdata: function( elem, name, data ) {\n\t\treturn dataUser.access( elem, name, data );\n\t},\n\n\tremoveData: function( elem, name ) {\n\t\tdataUser.remove( elem, name );\n\t},\n\n\t// TODO: Now that all calls to _data and _removeData have been replaced\n\t// with direct calls to dataPriv methods, these can be deprecated.\n\t_data: function( elem, name, data ) {\n\t\treturn dataPriv.access( elem, name, data );\n\t},\n\n\t_removeData: function( elem, name ) {\n\t\tdataPriv.remove( elem, name );\n\t}\n} );\n\njQuery.fn.extend( {\n\tdata: function( key, value ) {\n\t\tvar i, name, data,\n\t\t\telem = this[ 0 ],\n\t\t\tattrs = elem && elem.attributes;\n\n\t\t// Gets all values\n\t\tif ( key === undefined ) {\n\t\t\tif ( this.length ) {\n\t\t\t\tdata = dataUser.get( elem );\n\n\t\t\t\tif ( elem.nodeType === 1 && !dataPriv.get( elem, \"hasDataAttrs\" ) ) {\n\t\t\t\t\ti = attrs.length;\n\t\t\t\t\twhile ( i-- ) {\n\n\t\t\t\t\t\t// Support: IE 11 only\n\t\t\t\t\t\t// The attrs elements can be null (#14894)\n\t\t\t\t\t\tif ( attrs[ i ] ) {\n\t\t\t\t\t\t\tname = attrs[ i ].name;\n\t\t\t\t\t\t\tif ( name.indexOf( \"data-\" ) === 0 ) {\n\t\t\t\t\t\t\t\tname = camelCase( name.slice( 5 ) );\n\t\t\t\t\t\t\t\tdataAttr( elem, name, data[ name ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tdataPriv.set( elem, \"hasDataAttrs\", true );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn data;\n\t\t}\n\n\t\t// Sets multiple values\n\t\tif ( typeof key === \"object\" ) {\n\t\t\treturn this.each( function() {\n\t\t\t\tdataUser.set( this, key );\n\t\t\t} );\n\t\t}\n\n\t\treturn access( this, function( value ) {\n\t\t\tvar data;\n\n\t\t\t// The calling jQuery object (element matches) is not empty\n\t\t\t// (and therefore has an element appears at this[ 0 ]) and the\n\t\t\t// `value` parameter was not undefined. An empty jQuery object\n\t\t\t// will result in `undefined` for elem = this[ 0 ] which will\n\t\t\t// throw an exception if an attempt to read a data cache is made.\n\t\t\tif ( elem && value === undefined ) {\n\n\t\t\t\t// Attempt to get data from the cache\n\t\t\t\t// The key will always be camelCased in Data\n\t\t\t\tdata = dataUser.get( elem, key );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// Attempt to \"discover\" the data in\n\t\t\t\t// HTML5 custom data-* attrs\n\t\t\t\tdata = dataAttr( elem, key );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// We tried really hard, but the data doesn't exist.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Set the data...\n\t\t\tthis.each( function() {\n\n\t\t\t\t// We always store the camelCased key\n\t\t\t\tdataUser.set( this, key, value );\n\t\t\t} );\n\t\t}, null, value, arguments.length > 1, null, true );\n\t},\n\n\tremoveData: function( key ) {\n\t\treturn this.each( function() {\n\t\t\tdataUser.remove( this, key );\n\t\t} );\n\t}\n} );\n\n\njQuery.extend( {\n\tqueue: function( elem, type, data ) {\n\t\tvar queue;\n\n\t\tif ( elem ) {\n\t\t\ttype = ( type || \"fx\" ) + \"queue\";\n\t\t\tqueue = dataPriv.get( elem, type );\n\n\t\t\t// Speed up dequeue by getting out quickly if this is just a lookup\n\t\t\tif ( data ) {\n\t\t\t\tif ( !queue || Array.isArray( data ) ) {\n\t\t\t\t\tqueue = dataPriv.access( elem, type, jQuery.makeArray( data ) );\n\t\t\t\t} else {\n\t\t\t\t\tqueue.push( data );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn queue || [];\n\t\t}\n\t},\n\n\tdequeue: function( elem, type ) {\n\t\ttype = type || \"fx\";\n\n\t\tvar queue = jQuery.queue( elem, type ),\n\t\t\tstartLength = queue.length,\n\t\t\tfn = queue.shift(),\n\t\t\thooks = jQuery._queueHooks( elem, type ),\n\t\t\tnext = function() {\n\t\t\t\tjQuery.dequeue( elem, type );\n\t\t\t};\n\n\t\t// If the fx queue is dequeued, always remove the progress sentinel\n\t\tif ( fn === \"inprogress\" ) {\n\t\t\tfn = queue.shift();\n\t\t\tstartLength--;\n\t\t}\n\n\t\tif ( fn ) {\n\n\t\t\t// Add a progress sentinel to prevent the fx queue from being\n\t\t\t// automatically dequeued\n\t\t\tif ( type === \"fx\" ) {\n\t\t\t\tqueue.unshift( \"inprogress\" );\n\t\t\t}\n\n\t\t\t// Clear up the last queue stop function\n\t\t\tdelete hooks.stop;\n\t\t\tfn.call( elem, next, hooks );\n\t\t}\n\n\t\tif ( !startLength && hooks ) {\n\t\t\thooks.empty.fire();\n\t\t}\n\t},\n\n\t// Not public - generate a queueHooks object, or return the current one\n\t_queueHooks: function( elem, type ) {\n\t\tvar key = type + \"queueHooks\";\n\t\treturn dataPriv.get( elem, key ) || dataPriv.access( elem, key, {\n\t\t\tempty: jQuery.Callbacks( \"once memory\" ).add( function() {\n\t\t\t\tdataPriv.remove( elem, [ type + \"queue\", key ] );\n\t\t\t} )\n\t\t} );\n\t}\n} );\n\njQuery.fn.extend( {\n\tqueue: function( type, data ) {\n\t\tvar setter = 2;\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tdata = type;\n\t\t\ttype = \"fx\";\n\t\t\tsetter--;\n\t\t}\n\n\t\tif ( arguments.length < setter ) {\n\t\t\treturn jQuery.queue( this[ 0 ], type );\n\t\t}\n\n\t\treturn data === undefined ?\n\t\t\tthis :\n\t\t\tthis.each( function() {\n\t\t\t\tvar queue = jQuery.queue( this, type, data );\n\n\t\t\t\t// Ensure a hooks for this queue\n\t\t\t\tjQuery._queueHooks( this, type );\n\n\t\t\t\tif ( type === \"fx\" && queue[ 0 ] !== \"inprogress\" ) {\n\t\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t\t}\n\t\t\t} );\n\t},\n\tdequeue: function( type ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.dequeue( this, type );\n\t\t} );\n\t},\n\tclearQueue: function( type ) {\n\t\treturn this.queue( type || \"fx\", [] );\n\t},\n\n\t// Get a promise resolved when queues of a certain type\n\t// are emptied (fx is the type by default)\n\tpromise: function( type, obj ) {\n\t\tvar tmp,\n\t\t\tcount = 1,\n\t\t\tdefer = jQuery.Deferred(),\n\t\t\telements = this,\n\t\t\ti = this.length,\n\t\t\tresolve = function() {\n\t\t\t\tif ( !( --count ) ) {\n\t\t\t\t\tdefer.resolveWith( elements, [ elements ] );\n\t\t\t\t}\n\t\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tobj = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\ttype = type || \"fx\";\n\n\t\twhile ( i-- ) {\n\t\t\ttmp = dataPriv.get( elements[ i ], type + \"queueHooks\" );\n\t\t\tif ( tmp && tmp.empty ) {\n\t\t\t\tcount++;\n\t\t\t\ttmp.empty.add( resolve );\n\t\t\t}\n\t\t}\n\t\tresolve();\n\t\treturn defer.promise( obj );\n\t}\n} );\nvar pnum = ( /[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/ ).source;\n\nvar rcssNum = new RegExp( \"^(?:([+-])=|)(\" + pnum + \")([a-z%]*)$\", \"i\" );\n\n\nvar cssExpand = [ \"Top\", \"Right\", \"Bottom\", \"Left\" ];\n\nvar documentElement = document.documentElement;\n\n\n\n\tvar isAttached = function( elem ) {\n\t\t\treturn jQuery.contains( elem.ownerDocument, elem );\n\t\t},\n\t\tcomposed = { composed: true };\n\n\t// Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only\n\t// Check attachment across shadow DOM boundaries when possible (gh-3504)\n\t// Support: iOS 10.0-10.2 only\n\t// Early iOS 10 versions support `attachShadow` but not `getRootNode`,\n\t// leading to errors. We need to check for `getRootNode`.\n\tif ( documentElement.getRootNode ) {\n\t\tisAttached = function( elem ) {\n\t\t\treturn jQuery.contains( elem.ownerDocument, elem ) ||\n\t\t\t\telem.getRootNode( composed ) === elem.ownerDocument;\n\t\t};\n\t}\nvar isHiddenWithinTree = function( elem, el ) {\n\n\t\t// isHiddenWithinTree might be called from jQuery#filter function;\n\t\t// in that case, element will be second argument\n\t\telem = el || elem;\n\n\t\t// Inline style trumps all\n\t\treturn elem.style.display === \"none\" ||\n\t\t\telem.style.display === \"\" &&\n\n\t\t\t// Otherwise, check computed style\n\t\t\t// Support: Firefox <=43 - 45\n\t\t\t// Disconnected elements can have computed display: none, so first confirm that elem is\n\t\t\t// in the document.\n\t\t\tisAttached( elem ) &&\n\n\t\t\tjQuery.css( elem, \"display\" ) === \"none\";\n\t};\n\n\n\nfunction adjustCSS( elem, prop, valueParts, tween ) {\n\tvar adjusted, scale,\n\t\tmaxIterations = 20,\n\t\tcurrentValue = tween ?\n\t\t\tfunction() {\n\t\t\t\treturn tween.cur();\n\t\t\t} :\n\t\t\tfunction() {\n\t\t\t\treturn jQuery.css( elem, prop, \"\" );\n\t\t\t},\n\t\tinitial = currentValue(),\n\t\tunit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" ),\n\n\t\t// Starting value computation is required for potential unit mismatches\n\t\tinitialInUnit = elem.nodeType &&\n\t\t\t( jQuery.cssNumber[ prop ] || unit !== \"px\" && +initial ) &&\n\t\t\trcssNum.exec( jQuery.css( elem, prop ) );\n\n\tif ( initialInUnit && initialInUnit[ 3 ] !== unit ) {\n\n\t\t// Support: Firefox <=54\n\t\t// Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144)\n\t\tinitial = initial / 2;\n\n\t\t// Trust units reported by jQuery.css\n\t\tunit = unit || initialInUnit[ 3 ];\n\n\t\t// Iteratively approximate from a nonzero starting point\n\t\tinitialInUnit = +initial || 1;\n\n\t\twhile ( maxIterations-- ) {\n\n\t\t\t// Evaluate and update our best guess (doubling guesses that zero out).\n\t\t\t// Finish if the scale equals or crosses 1 (making the old*new product non-positive).\n\t\t\tjQuery.style( elem, prop, initialInUnit + unit );\n\t\t\tif ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) {\n\t\t\t\tmaxIterations = 0;\n\t\t\t}\n\t\t\tinitialInUnit = initialInUnit / scale;\n\n\t\t}\n\n\t\tinitialInUnit = initialInUnit * 2;\n\t\tjQuery.style( elem, prop, initialInUnit + unit );\n\n\t\t// Make sure we update the tween properties later on\n\t\tvalueParts = valueParts || [];\n\t}\n\n\tif ( valueParts ) {\n\t\tinitialInUnit = +initialInUnit || +initial || 0;\n\n\t\t// Apply relative offset (+=/-=) if specified\n\t\tadjusted = valueParts[ 1 ] ?\n\t\t\tinitialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :\n\t\t\t+valueParts[ 2 ];\n\t\tif ( tween ) {\n\t\t\ttween.unit = unit;\n\t\t\ttween.start = initialInUnit;\n\t\t\ttween.end = adjusted;\n\t\t}\n\t}\n\treturn adjusted;\n}\n\n\nvar defaultDisplayMap = {};\n\nfunction getDefaultDisplay( elem ) {\n\tvar temp,\n\t\tdoc = elem.ownerDocument,\n\t\tnodeName = elem.nodeName,\n\t\tdisplay = defaultDisplayMap[ nodeName ];\n\n\tif ( display ) {\n\t\treturn display;\n\t}\n\n\ttemp = doc.body.appendChild( doc.createElement( nodeName ) );\n\tdisplay = jQuery.css( temp, \"display\" );\n\n\ttemp.parentNode.removeChild( temp );\n\n\tif ( display === \"none\" ) {\n\t\tdisplay = \"block\";\n\t}\n\tdefaultDisplayMap[ nodeName ] = display;\n\n\treturn display;\n}\n\nfunction showHide( elements, show ) {\n\tvar display, elem,\n\t\tvalues = [],\n\t\tindex = 0,\n\t\tlength = elements.length;\n\n\t// Determine new display value for elements that need to change\n\tfor ( ; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tdisplay = elem.style.display;\n\t\tif ( show ) {\n\n\t\t\t// Since we force visibility upon cascade-hidden elements, an immediate (and slow)\n\t\t\t// check is required in this first loop unless we have a nonempty display value (either\n\t\t\t// inline or about-to-be-restored)\n\t\t\tif ( display === \"none\" ) {\n\t\t\t\tvalues[ index ] = dataPriv.get( elem, \"display\" ) || null;\n\t\t\t\tif ( !values[ index ] ) {\n\t\t\t\t\telem.style.display = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( elem.style.display === \"\" && isHiddenWithinTree( elem ) ) {\n\t\t\t\tvalues[ index ] = getDefaultDisplay( elem );\n\t\t\t}\n\t\t} else {\n\t\t\tif ( display !== \"none\" ) {\n\t\t\t\tvalues[ index ] = \"none\";\n\n\t\t\t\t// Remember what we're overwriting\n\t\t\t\tdataPriv.set( elem, \"display\", display );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Set the display of the elements in a second loop to avoid constant reflow\n\tfor ( index = 0; index < length; index++ ) {\n\t\tif ( values[ index ] != null ) {\n\t\t\telements[ index ].style.display = values[ index ];\n\t\t}\n\t}\n\n\treturn elements;\n}\n\njQuery.fn.extend( {\n\tshow: function() {\n\t\treturn showHide( this, true );\n\t},\n\thide: function() {\n\t\treturn showHide( this );\n\t},\n\ttoggle: function( state ) {\n\t\tif ( typeof state === \"boolean\" ) {\n\t\t\treturn state ? this.show() : this.hide();\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tif ( isHiddenWithinTree( this ) ) {\n\t\t\t\tjQuery( this ).show();\n\t\t\t} else {\n\t\t\t\tjQuery( this ).hide();\n\t\t\t}\n\t\t} );\n\t}\n} );\nvar rcheckableType = ( /^(?:checkbox|radio)$/i );\n\nvar rtagName = ( /<([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]*)/i );\n\nvar rscriptType = ( /^$|^module$|\\/(?:java|ecma)script/i );\n\n\n\n( function() {\n\tvar fragment = document.createDocumentFragment(),\n\t\tdiv = fragment.appendChild( document.createElement( \"div\" ) ),\n\t\tinput = document.createElement( \"input\" );\n\n\t// Support: Android 4.0 - 4.3 only\n\t// Check state lost if the name is set (#11217)\n\t// Support: Windows Web Apps (WWA)\n\t// `name` and `type` must use .setAttribute for WWA (#14901)\n\tinput.setAttribute( \"type\", \"radio\" );\n\tinput.setAttribute( \"checked\", \"checked\" );\n\tinput.setAttribute( \"name\", \"t\" );\n\n\tdiv.appendChild( input );\n\n\t// Support: Android <=4.1 only\n\t// Older WebKit doesn't clone checked state correctly in fragments\n\tsupport.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;\n\n\t// Support: IE <=11 only\n\t// Make sure textarea (and checkbox) defaultValue is properly cloned\n\tdiv.innerHTML = \"<textarea>x</textarea>\";\n\tsupport.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;\n\n\t// Support: IE <=9 only\n\t// IE <=9 replaces <option> tags with their contents when inserted outside of\n\t// the select element.\n\tdiv.innerHTML = \"<option></option>\";\n\tsupport.option = !!div.lastChild;\n} )();\n\n\n// We have to close these tags to support XHTML (#13200)\nvar wrapMap = {\n\n\t// XHTML parsers do not magically insert elements in the\n\t// same way that tag soup parsers do. So we cannot shorten\n\t// this by omitting <tbody> or other required elements.\n\tthead: [ 1, \"<table>\", \"</table>\" ],\n\tcol: [ 2, \"<table><colgroup>\", \"</colgroup></table>\" ],\n\ttr: [ 2, \"<table><tbody>\", \"</tbody></table>\" ],\n\ttd: [ 3, \"<table><tbody><tr>\", \"</tr></tbody></table>\" ],\n\n\t_default: [ 0, \"\", \"\" ]\n};\n\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\n// Support: IE <=9 only\nif ( !support.option ) {\n\twrapMap.optgroup = wrapMap.option = [ 1, \"<select multiple='multiple'>\", \"</select>\" ];\n}\n\n\nfunction getAll( context, tag ) {\n\n\t// Support: IE <=9 - 11 only\n\t// Use typeof to avoid zero-argument method invocation on host objects (#15151)\n\tvar ret;\n\n\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\tret = context.getElementsByTagName( tag || \"*\" );\n\n\t} else if ( typeof context.querySelectorAll !== \"undefined\" ) {\n\t\tret = context.querySelectorAll( tag || \"*\" );\n\n\t} else {\n\t\tret = [];\n\t}\n\n\tif ( tag === undefined || tag && nodeName( context, tag ) ) {\n\t\treturn jQuery.merge( [ context ], ret );\n\t}\n\n\treturn ret;\n}\n\n\n// Mark scripts as having already been evaluated\nfunction setGlobalEval( elems, refElements ) {\n\tvar i = 0,\n\t\tl = elems.length;\n\n\tfor ( ; i < l; i++ ) {\n\t\tdataPriv.set(\n\t\t\telems[ i ],\n\t\t\t\"globalEval\",\n\t\t\t!refElements || dataPriv.get( refElements[ i ], \"globalEval\" )\n\t\t);\n\t}\n}\n\n\nvar rhtml = /<|&#?\\w+;/;\n\nfunction buildFragment( elems, context, scripts, selection, ignored ) {\n\tvar elem, tmp, tag, wrap, attached, j,\n\t\tfragment = context.createDocumentFragment(),\n\t\tnodes = [],\n\t\ti = 0,\n\t\tl = elems.length;\n\n\tfor ( ; i < l; i++ ) {\n\t\telem = elems[ i ];\n\n\t\tif ( elem || elem === 0 ) {\n\n\t\t\t// Add nodes directly\n\t\t\tif ( toType( elem ) === \"object\" ) {\n\n\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\tjQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );\n\n\t\t\t// Convert non-html into a text node\n\t\t\t} else if ( !rhtml.test( elem ) ) {\n\t\t\t\tnodes.push( context.createTextNode( elem ) );\n\n\t\t\t// Convert html into DOM nodes\n\t\t\t} else {\n\t\t\t\ttmp = tmp || fragment.appendChild( context.createElement( \"div\" ) );\n\n\t\t\t\t// Deserialize a standard representation\n\t\t\t\ttag = ( rtagName.exec( elem ) || [ \"\", \"\" ] )[ 1 ].toLowerCase();\n\t\t\t\twrap = wrapMap[ tag ] || wrapMap._default;\n\t\t\t\ttmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];\n\n\t\t\t\t// Descend through wrappers to the right content\n\t\t\t\tj = wrap[ 0 ];\n\t\t\t\twhile ( j-- ) {\n\t\t\t\t\ttmp = tmp.lastChild;\n\t\t\t\t}\n\n\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\tjQuery.merge( nodes, tmp.childNodes );\n\n\t\t\t\t// Remember the top-level container\n\t\t\t\ttmp = fragment.firstChild;\n\n\t\t\t\t// Ensure the created nodes are orphaned (#12392)\n\t\t\t\ttmp.textContent = \"\";\n\t\t\t}\n\t\t}\n\t}\n\n\t// Remove wrapper from fragment\n\tfragment.textContent = \"\";\n\n\ti = 0;\n\twhile ( ( elem = nodes[ i++ ] ) ) {\n\n\t\t// Skip elements already in the context collection (trac-4087)\n\t\tif ( selection && jQuery.inArray( elem, selection ) > -1 ) {\n\t\t\tif ( ignored ) {\n\t\t\t\tignored.push( elem );\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tattached = isAttached( elem );\n\n\t\t// Append to fragment\n\t\ttmp = getAll( fragment.appendChild( elem ), \"script\" );\n\n\t\t// Preserve script evaluation history\n\t\tif ( attached ) {\n\t\t\tsetGlobalEval( tmp );\n\t\t}\n\n\t\t// Capture executables\n\t\tif ( scripts ) {\n\t\t\tj = 0;\n\t\t\twhile ( ( elem = tmp[ j++ ] ) ) {\n\t\t\t\tif ( rscriptType.test( elem.type || \"\" ) ) {\n\t\t\t\t\tscripts.push( elem );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn fragment;\n}\n\n\nvar rtypenamespace = /^([^.]*)(?:\\.(.+)|)/;\n\nfunction returnTrue() {\n\treturn true;\n}\n\nfunction returnFalse() {\n\treturn false;\n}\n\n// Support: IE <=9 - 11+\n// focus() and blur() are asynchronous, except when they are no-op.\n// So expect focus to be synchronous when the element is already active,\n// and blur to be synchronous when the element is not already active.\n// (focus and blur are always synchronous in other supported browsers,\n// this just defines when we can count on it).\nfunction expectSync( elem, type ) {\n\treturn ( elem === safeActiveElement() ) === ( type === \"focus\" );\n}\n\n// Support: IE <=9 only\n// Accessing document.activeElement can throw unexpectedly\n// https://bugs.jquery.com/ticket/13393\nfunction safeActiveElement() {\n\ttry {\n\t\treturn document.activeElement;\n\t} catch ( err ) { }\n}\n\nfunction on( elem, types, selector, data, fn, one ) {\n\tvar origFn, type;\n\n\t// Types can be a map of types/handlers\n\tif ( typeof types === \"object\" ) {\n\n\t\t// ( types-Object, selector, data )\n\t\tif ( typeof selector !== \"string\" ) {\n\n\t\t\t// ( types-Object, data )\n\t\t\tdata = data || selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tfor ( type in types ) {\n\t\t\ton( elem, type, selector, data, types[ type ], one );\n\t\t}\n\t\treturn elem;\n\t}\n\n\tif ( data == null && fn == null ) {\n\n\t\t// ( types, fn )\n\t\tfn = selector;\n\t\tdata = selector = undefined;\n\t} else if ( fn == null ) {\n\t\tif ( typeof selector === \"string\" ) {\n\n\t\t\t// ( types, selector, fn )\n\t\t\tfn = data;\n\t\t\tdata = undefined;\n\t\t} else {\n\n\t\t\t// ( types, data, fn )\n\t\t\tfn = data;\n\t\t\tdata = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t}\n\tif ( fn === false ) {\n\t\tfn = returnFalse;\n\t} else if ( !fn ) {\n\t\treturn elem;\n\t}\n\n\tif ( one === 1 ) {\n\t\torigFn = fn;\n\t\tfn = function( event ) {\n\n\t\t\t// Can use an empty set, since event contains the info\n\t\t\tjQuery().off( event );\n\t\t\treturn origFn.apply( this, arguments );\n\t\t};\n\n\t\t// Use same guid so caller can remove using origFn\n\t\tfn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );\n\t}\n\treturn elem.each( function() {\n\t\tjQuery.event.add( this, types, fn, data, selector );\n\t} );\n}\n\n/*\n * Helper functions for managing events -- not part of the public interface.\n * Props to Dean Edwards' addEvent library for many of the ideas.\n */\njQuery.event = {\n\n\tglobal: {},\n\n\tadd: function( elem, types, handler, data, selector ) {\n\n\t\tvar handleObjIn, eventHandle, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = dataPriv.get( elem );\n\n\t\t// Only attach events to objects that accept data\n\t\tif ( !acceptData( elem ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Caller can pass in an object of custom data in lieu of the handler\n\t\tif ( handler.handler ) {\n\t\t\thandleObjIn = handler;\n\t\t\thandler = handleObjIn.handler;\n\t\t\tselector = handleObjIn.selector;\n\t\t}\n\n\t\t// Ensure that invalid selectors throw exceptions at attach time\n\t\t// Evaluate against documentElement in case elem is a non-element node (e.g., document)\n\t\tif ( selector ) {\n\t\t\tjQuery.find.matchesSelector( documentElement, selector );\n\t\t}\n\n\t\t// Make sure that the handler has a unique ID, used to find/remove it later\n\t\tif ( !handler.guid ) {\n\t\t\thandler.guid = jQuery.guid++;\n\t\t}\n\n\t\t// Init the element's event structure and main handler, if this is the first\n\t\tif ( !( events = elemData.events ) ) {\n\t\t\tevents = elemData.events = Object.create( null );\n\t\t}\n\t\tif ( !( eventHandle = elemData.handle ) ) {\n\t\t\teventHandle = elemData.handle = function( e ) {\n\n\t\t\t\t// Discard the second event of a jQuery.event.trigger() and\n\t\t\t\t// when an event is called after a page has unloaded\n\t\t\t\treturn typeof jQuery !== \"undefined\" && jQuery.event.triggered !== e.type ?\n\t\t\t\t\tjQuery.event.dispatch.apply( elem, arguments ) : undefined;\n\t\t\t};\n\t\t}\n\n\t\t// Handle multiple events separated by a space\n\t\ttypes = ( types || \"\" ).match( rnothtmlwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[ t ] ) || [];\n\t\t\ttype = origType = tmp[ 1 ];\n\t\t\tnamespaces = ( tmp[ 2 ] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// There *must* be a type, no attaching namespace-only handlers\n\t\t\tif ( !type ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If event changes its type, use the special event handlers for the changed type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// If selector defined, determine special event api type, otherwise given type\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\n\t\t\t// Update special based on newly reset type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// handleObj is passed to all event handlers\n\t\t\thandleObj = jQuery.extend( {\n\t\t\t\ttype: type,\n\t\t\t\torigType: origType,\n\t\t\t\tdata: data,\n\t\t\t\thandler: handler,\n\t\t\t\tguid: handler.guid,\n\t\t\t\tselector: selector,\n\t\t\t\tneedsContext: selector && jQuery.expr.match.needsContext.test( selector ),\n\t\t\t\tnamespace: namespaces.join( \".\" )\n\t\t\t}, handleObjIn );\n\n\t\t\t// Init the event handler queue if we're the first\n\t\t\tif ( !( handlers = events[ type ] ) ) {\n\t\t\t\thandlers = events[ type ] = [];\n\t\t\t\thandlers.delegateCount = 0;\n\n\t\t\t\t// Only use addEventListener if the special events handler returns false\n\t\t\t\tif ( !special.setup ||\n\t\t\t\t\tspecial.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n\n\t\t\t\t\tif ( elem.addEventListener ) {\n\t\t\t\t\t\telem.addEventListener( type, eventHandle );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( special.add ) {\n\t\t\t\tspecial.add.call( elem, handleObj );\n\n\t\t\t\tif ( !handleObj.handler.guid ) {\n\t\t\t\t\thandleObj.handler.guid = handler.guid;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add to the element's handler list, delegates in front\n\t\t\tif ( selector ) {\n\t\t\t\thandlers.splice( handlers.delegateCount++, 0, handleObj );\n\t\t\t} else {\n\t\t\t\thandlers.push( handleObj );\n\t\t\t}\n\n\t\t\t// Keep track of which events have ever been used, for event optimization\n\t\t\tjQuery.event.global[ type ] = true;\n\t\t}\n\n\t},\n\n\t// Detach an event or set of events from an element\n\tremove: function( elem, types, handler, selector, mappedTypes ) {\n\n\t\tvar j, origCount, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = dataPriv.hasData( elem ) && dataPriv.get( elem );\n\n\t\tif ( !elemData || !( events = elemData.events ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Once for each type.namespace in types; type may be omitted\n\t\ttypes = ( types || \"\" ).match( rnothtmlwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[ t ] ) || [];\n\t\t\ttype = origType = tmp[ 1 ];\n\t\t\tnamespaces = ( tmp[ 2 ] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// Unbind all events (on this namespace, if provided) for the element\n\t\t\tif ( !type ) {\n\t\t\t\tfor ( type in events ) {\n\t\t\t\t\tjQuery.event.remove( elem, type + types[ t ], handler, selector, true );\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\t\t\thandlers = events[ type ] || [];\n\t\t\ttmp = tmp[ 2 ] &&\n\t\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join( \"\\\\.(?:.*\\\\.|)\" ) + \"(\\\\.|$)\" );\n\n\t\t\t// Remove matching events\n\t\t\torigCount = j = handlers.length;\n\t\t\twhile ( j-- ) {\n\t\t\t\thandleObj = handlers[ j ];\n\n\t\t\t\tif ( ( mappedTypes || origType === handleObj.origType ) &&\n\t\t\t\t\t( !handler || handler.guid === handleObj.guid ) &&\n\t\t\t\t\t( !tmp || tmp.test( handleObj.namespace ) ) &&\n\t\t\t\t\t( !selector || selector === handleObj.selector ||\n\t\t\t\t\t\tselector === \"**\" && handleObj.selector ) ) {\n\t\t\t\t\thandlers.splice( j, 1 );\n\n\t\t\t\t\tif ( handleObj.selector ) {\n\t\t\t\t\t\thandlers.delegateCount--;\n\t\t\t\t\t}\n\t\t\t\t\tif ( special.remove ) {\n\t\t\t\t\t\tspecial.remove.call( elem, handleObj );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove generic event handler if we removed something and no more handlers exist\n\t\t\t// (avoids potential for endless recursion during removal of special event handlers)\n\t\t\tif ( origCount && !handlers.length ) {\n\t\t\t\tif ( !special.teardown ||\n\t\t\t\t\tspecial.teardown.call( elem, namespaces, elemData.handle ) === false ) {\n\n\t\t\t\t\tjQuery.removeEvent( elem, type, elemData.handle );\n\t\t\t\t}\n\n\t\t\t\tdelete events[ type ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove data and the expando if it's no longer used\n\t\tif ( jQuery.isEmptyObject( events ) ) {\n\t\t\tdataPriv.remove( elem, \"handle events\" );\n\t\t}\n\t},\n\n\tdispatch: function( nativeEvent ) {\n\n\t\tvar i, j, ret, matched, handleObj, handlerQueue,\n\t\t\targs = new Array( arguments.length ),\n\n\t\t\t// Make a writable jQuery.Event from the native event object\n\t\t\tevent = jQuery.event.fix( nativeEvent ),\n\n\t\t\thandlers = (\n\t\t\t\tdataPriv.get( this, \"events\" ) || Object.create( null )\n\t\t\t)[ event.type ] || [],\n\t\t\tspecial = jQuery.event.special[ event.type ] || {};\n\n\t\t// Use the fix-ed jQuery.Event rather than the (read-only) native event\n\t\targs[ 0 ] = event;\n\n\t\tfor ( i = 1; i < arguments.length; i++ ) {\n\t\t\targs[ i ] = arguments[ i ];\n\t\t}\n\n\t\tevent.delegateTarget = this;\n\n\t\t// Call the preDispatch hook for the mapped type, and let it bail if desired\n\t\tif ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine handlers\n\t\thandlerQueue = jQuery.event.handlers.call( this, event, handlers );\n\n\t\t// Run delegates first; they may want to stop propagation beneath us\n\t\ti = 0;\n\t\twhile ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {\n\t\t\tevent.currentTarget = matched.elem;\n\n\t\t\tj = 0;\n\t\t\twhile ( ( handleObj = matched.handlers[ j++ ] ) &&\n\t\t\t\t!event.isImmediatePropagationStopped() ) {\n\n\t\t\t\t// If the event is namespaced, then each handler is only invoked if it is\n\t\t\t\t// specially universal or its namespaces are a superset of the event's.\n\t\t\t\tif ( !event.rnamespace || handleObj.namespace === false ||\n\t\t\t\t\tevent.rnamespace.test( handleObj.namespace ) ) {\n\n\t\t\t\t\tevent.handleObj = handleObj;\n\t\t\t\t\tevent.data = handleObj.data;\n\n\t\t\t\t\tret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||\n\t\t\t\t\t\thandleObj.handler ).apply( matched.elem, args );\n\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\tif ( ( event.result = ret ) === false ) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Call the postDispatch hook for the mapped type\n\t\tif ( special.postDispatch ) {\n\t\t\tspecial.postDispatch.call( this, event );\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\thandlers: function( event, handlers ) {\n\t\tvar i, handleObj, sel, matchedHandlers, matchedSelectors,\n\t\t\thandlerQueue = [],\n\t\t\tdelegateCount = handlers.delegateCount,\n\t\t\tcur = event.target;\n\n\t\t// Find delegate handlers\n\t\tif ( delegateCount &&\n\n\t\t\t// Support: IE <=9\n\t\t\t// Black-hole SVG <use> instance trees (trac-13180)\n\t\t\tcur.nodeType &&\n\n\t\t\t// Support: Firefox <=42\n\t\t\t// Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)\n\t\t\t// https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click\n\t\t\t// Support: IE 11 only\n\t\t\t// ...but not arrow key \"clicks\" of radio inputs, which can have `button` -1 (gh-2343)\n\t\t\t!( event.type === \"click\" && event.button >= 1 ) ) {\n\n\t\t\tfor ( ; cur !== this; cur = cur.parentNode || this ) {\n\n\t\t\t\t// Don't check non-elements (#13208)\n\t\t\t\t// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)\n\t\t\t\tif ( cur.nodeType === 1 && !( event.type === \"click\" && cur.disabled === true ) ) {\n\t\t\t\t\tmatchedHandlers = [];\n\t\t\t\t\tmatchedSelectors = {};\n\t\t\t\t\tfor ( i = 0; i < delegateCount; i++ ) {\n\t\t\t\t\t\thandleObj = handlers[ i ];\n\n\t\t\t\t\t\t// Don't conflict with Object.prototype properties (#13203)\n\t\t\t\t\t\tsel = handleObj.selector + \" \";\n\n\t\t\t\t\t\tif ( matchedSelectors[ sel ] === undefined ) {\n\t\t\t\t\t\t\tmatchedSelectors[ sel ] = handleObj.needsContext ?\n\t\t\t\t\t\t\t\tjQuery( sel, this ).index( cur ) > -1 :\n\t\t\t\t\t\t\t\tjQuery.find( sel, this, null, [ cur ] ).length;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( matchedSelectors[ sel ] ) {\n\t\t\t\t\t\t\tmatchedHandlers.push( handleObj );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( matchedHandlers.length ) {\n\t\t\t\t\t\thandlerQueue.push( { elem: cur, handlers: matchedHandlers } );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Add the remaining (directly-bound) handlers\n\t\tcur = this;\n\t\tif ( delegateCount < handlers.length ) {\n\t\t\thandlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );\n\t\t}\n\n\t\treturn handlerQueue;\n\t},\n\n\taddProp: function( name, hook ) {\n\t\tObject.defineProperty( jQuery.Event.prototype, name, {\n\t\t\tenumerable: true,\n\t\t\tconfigurable: true,\n\n\t\t\tget: isFunction( hook ) ?\n\t\t\t\tfunction() {\n\t\t\t\t\tif ( this.originalEvent ) {\n\t\t\t\t\t\treturn hook( this.originalEvent );\n\t\t\t\t\t}\n\t\t\t\t} :\n\t\t\t\tfunction() {\n\t\t\t\t\tif ( this.originalEvent ) {\n\t\t\t\t\t\treturn this.originalEvent[ name ];\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\tset: function( value ) {\n\t\t\t\tObject.defineProperty( this, name, {\n\t\t\t\t\tenumerable: true,\n\t\t\t\t\tconfigurable: true,\n\t\t\t\t\twritable: true,\n\t\t\t\t\tvalue: value\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\t},\n\n\tfix: function( originalEvent ) {\n\t\treturn originalEvent[ jQuery.expando ] ?\n\t\t\toriginalEvent :\n\t\t\tnew jQuery.Event( originalEvent );\n\t},\n\n\tspecial: {\n\t\tload: {\n\n\t\t\t// Prevent triggered image.load events from bubbling to window.load\n\t\t\tnoBubble: true\n\t\t},\n\t\tclick: {\n\n\t\t\t// Utilize native event to ensure correct state for checkable inputs\n\t\t\tsetup: function( data ) {\n\n\t\t\t\t// For mutual compressibility with _default, replace `this` access with a local var.\n\t\t\t\t// `|| data` is dead code meant only to preserve the variable through minification.\n\t\t\t\tvar el = this || data;\n\n\t\t\t\t// Claim the first handler\n\t\t\t\tif ( rcheckableType.test( el.type ) &&\n\t\t\t\t\tel.click && nodeName( el, \"input\" ) ) {\n\n\t\t\t\t\t// dataPriv.set( el, \"click\", ... )\n\t\t\t\t\tleverageNative( el, \"click\", returnTrue );\n\t\t\t\t}\n\n\t\t\t\t// Return false to allow normal processing in the caller\n\t\t\t\treturn false;\n\t\t\t},\n\t\t\ttrigger: function( data ) {\n\n\t\t\t\t// For mutual compressibility with _default, replace `this` access with a local var.\n\t\t\t\t// `|| data` is dead code meant only to preserve the variable through minification.\n\t\t\t\tvar el = this || data;\n\n\t\t\t\t// Force setup before triggering a click\n\t\t\t\tif ( rcheckableType.test( el.type ) &&\n\t\t\t\t\tel.click && nodeName( el, \"input\" ) ) {\n\n\t\t\t\t\tleverageNative( el, \"click\" );\n\t\t\t\t}\n\n\t\t\t\t// Return non-false to allow normal event-path propagation\n\t\t\t\treturn true;\n\t\t\t},\n\n\t\t\t// For cross-browser consistency, suppress native .click() on links\n\t\t\t// Also prevent it if we're currently inside a leveraged native-event stack\n\t\t\t_default: function( event ) {\n\t\t\t\tvar target = event.target;\n\t\t\t\treturn rcheckableType.test( target.type ) &&\n\t\t\t\t\ttarget.click && nodeName( target, \"input\" ) &&\n\t\t\t\t\tdataPriv.get( target, \"click\" ) ||\n\t\t\t\t\tnodeName( target, \"a\" );\n\t\t\t}\n\t\t},\n\n\t\tbeforeunload: {\n\t\t\tpostDispatch: function( event ) {\n\n\t\t\t\t// Support: Firefox 20+\n\t\t\t\t// Firefox doesn't alert if the returnValue field is not set.\n\t\t\t\tif ( event.result !== undefined && event.originalEvent ) {\n\t\t\t\t\tevent.originalEvent.returnValue = event.result;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Ensure the presence of an event listener that handles manually-triggered\n// synthetic events by interrupting progress until reinvoked in response to\n// *native* events that it fires directly, ensuring that state changes have\n// already occurred before other listeners are invoked.\nfunction leverageNative( el, type, expectSync ) {\n\n\t// Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add\n\tif ( !expectSync ) {\n\t\tif ( dataPriv.get( el, type ) === undefined ) {\n\t\t\tjQuery.event.add( el, type, returnTrue );\n\t\t}\n\t\treturn;\n\t}\n\n\t// Register the controller as a special universal handler for all event namespaces\n\tdataPriv.set( el, type, false );\n\tjQuery.event.add( el, type, {\n\t\tnamespace: false,\n\t\thandler: function( event ) {\n\t\t\tvar notAsync, result,\n\t\t\t\tsaved = dataPriv.get( this, type );\n\n\t\t\tif ( ( event.isTrigger & 1 ) && this[ type ] ) {\n\n\t\t\t\t// Interrupt processing of the outer synthetic .trigger()ed event\n\t\t\t\t// Saved data should be false in such cases, but might be a leftover capture object\n\t\t\t\t// from an async native handler (gh-4350)\n\t\t\t\tif ( !saved.length ) {\n\n\t\t\t\t\t// Store arguments for use when handling the inner native event\n\t\t\t\t\t// There will always be at least one argument (an event object), so this array\n\t\t\t\t\t// will not be confused with a leftover capture object.\n\t\t\t\t\tsaved = slice.call( arguments );\n\t\t\t\t\tdataPriv.set( this, type, saved );\n\n\t\t\t\t\t// Trigger the native event and capture its result\n\t\t\t\t\t// Support: IE <=9 - 11+\n\t\t\t\t\t// focus() and blur() are asynchronous\n\t\t\t\t\tnotAsync = expectSync( this, type );\n\t\t\t\t\tthis[ type ]();\n\t\t\t\t\tresult = dataPriv.get( this, type );\n\t\t\t\t\tif ( saved !== result || notAsync ) {\n\t\t\t\t\t\tdataPriv.set( this, type, false );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult = {};\n\t\t\t\t\t}\n\t\t\t\t\tif ( saved !== result ) {\n\n\t\t\t\t\t\t// Cancel the outer synthetic event\n\t\t\t\t\t\tevent.stopImmediatePropagation();\n\t\t\t\t\t\tevent.preventDefault();\n\n\t\t\t\t\t\t// Support: Chrome 86+\n\t\t\t\t\t\t// In Chrome, if an element having a focusout handler is blurred by\n\t\t\t\t\t\t// clicking outside of it, it invokes the handler synchronously. If\n\t\t\t\t\t\t// that handler calls `.remove()` on the element, the data is cleared,\n\t\t\t\t\t\t// leaving `result` undefined. We need to guard against this.\n\t\t\t\t\t\treturn result && result.value;\n\t\t\t\t\t}\n\n\t\t\t\t// If this is an inner synthetic event for an event with a bubbling surrogate\n\t\t\t\t// (focus or blur), assume that the surrogate already propagated from triggering the\n\t\t\t\t// native event and prevent that from happening again here.\n\t\t\t\t// This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the\n\t\t\t\t// bubbling surrogate propagates *after* the non-bubbling base), but that seems\n\t\t\t\t// less bad than duplication.\n\t\t\t\t} else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) {\n\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t}\n\n\t\t\t// If this is a native event triggered above, everything is now in order\n\t\t\t// Fire an inner synthetic event with the original arguments\n\t\t\t} else if ( saved.length ) {\n\n\t\t\t\t// ...and capture the result\n\t\t\t\tdataPriv.set( this, type, {\n\t\t\t\t\tvalue: jQuery.event.trigger(\n\n\t\t\t\t\t\t// Support: IE <=9 - 11+\n\t\t\t\t\t\t// Extend with the prototype to reset the above stopImmediatePropagation()\n\t\t\t\t\t\tjQuery.extend( saved[ 0 ], jQuery.Event.prototype ),\n\t\t\t\t\t\tsaved.slice( 1 ),\n\t\t\t\t\t\tthis\n\t\t\t\t\t)\n\t\t\t\t} );\n\n\t\t\t\t// Abort handling of the native event\n\t\t\t\tevent.stopImmediatePropagation();\n\t\t\t}\n\t\t}\n\t} );\n}\n\njQuery.removeEvent = function( elem, type, handle ) {\n\n\t// This \"if\" is needed for plain objects\n\tif ( elem.removeEventListener ) {\n\t\telem.removeEventListener( type, handle );\n\t}\n};\n\njQuery.Event = function( src, props ) {\n\n\t// Allow instantiation without the 'new' keyword\n\tif ( !( this instanceof jQuery.Event ) ) {\n\t\treturn new jQuery.Event( src, props );\n\t}\n\n\t// Event object\n\tif ( src && src.type ) {\n\t\tthis.originalEvent = src;\n\t\tthis.type = src.type;\n\n\t\t// Events bubbling up the document may have been marked as prevented\n\t\t// by a handler lower down the tree; reflect the correct value.\n\t\tthis.isDefaultPrevented = src.defaultPrevented ||\n\t\t\t\tsrc.defaultPrevented === undefined &&\n\n\t\t\t\t// Support: Android <=2.3 only\n\t\t\t\tsrc.returnValue === false ?\n\t\t\treturnTrue :\n\t\t\treturnFalse;\n\n\t\t// Create target properties\n\t\t// Support: Safari <=6 - 7 only\n\t\t// Target should not be a text node (#504, #13143)\n\t\tthis.target = ( src.target && src.target.nodeType === 3 ) ?\n\t\t\tsrc.target.parentNode :\n\t\t\tsrc.target;\n\n\t\tthis.currentTarget = src.currentTarget;\n\t\tthis.relatedTarget = src.relatedTarget;\n\n\t// Event type\n\t} else {\n\t\tthis.type = src;\n\t}\n\n\t// Put explicitly provided properties onto the event object\n\tif ( props ) {\n\t\tjQuery.extend( this, props );\n\t}\n\n\t// Create a timestamp if incoming event doesn't have one\n\tthis.timeStamp = src && src.timeStamp || Date.now();\n\n\t// Mark it as fixed\n\tthis[ jQuery.expando ] = true;\n};\n\n// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\njQuery.Event.prototype = {\n\tconstructor: jQuery.Event,\n\tisDefaultPrevented: returnFalse,\n\tisPropagationStopped: returnFalse,\n\tisImmediatePropagationStopped: returnFalse,\n\tisSimulated: false,\n\n\tpreventDefault: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isDefaultPrevented = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.preventDefault();\n\t\t}\n\t},\n\tstopPropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isPropagationStopped = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.stopPropagation();\n\t\t}\n\t},\n\tstopImmediatePropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isImmediatePropagationStopped = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.stopImmediatePropagation();\n\t\t}\n\n\t\tthis.stopPropagation();\n\t}\n};\n\n// Includes all common event props including KeyEvent and MouseEvent specific props\njQuery.each( {\n\taltKey: true,\n\tbubbles: true,\n\tcancelable: true,\n\tchangedTouches: true,\n\tctrlKey: true,\n\tdetail: true,\n\teventPhase: true,\n\tmetaKey: true,\n\tpageX: true,\n\tpageY: true,\n\tshiftKey: true,\n\tview: true,\n\t\"char\": true,\n\tcode: true,\n\tcharCode: true,\n\tkey: true,\n\tkeyCode: true,\n\tbutton: true,\n\tbuttons: true,\n\tclientX: true,\n\tclientY: true,\n\toffsetX: true,\n\toffsetY: true,\n\tpointerId: true,\n\tpointerType: true,\n\tscreenX: true,\n\tscreenY: true,\n\ttargetTouches: true,\n\ttoElement: true,\n\ttouches: true,\n\twhich: true\n}, jQuery.event.addProp );\n\njQuery.each( { focus: \"focusin\", blur: \"focusout\" }, function( type, delegateType ) {\n\tjQuery.event.special[ type ] = {\n\n\t\t// Utilize native event if possible so blur/focus sequence is correct\n\t\tsetup: function() {\n\n\t\t\t// Claim the first handler\n\t\t\t// dataPriv.set( this, \"focus\", ... )\n\t\t\t// dataPriv.set( this, \"blur\", ... )\n\t\t\tleverageNative( this, type, expectSync );\n\n\t\t\t// Return false to allow normal processing in the caller\n\t\t\treturn false;\n\t\t},\n\t\ttrigger: function() {\n\n\t\t\t// Force setup before trigger\n\t\t\tleverageNative( this, type );\n\n\t\t\t// Return non-false to allow normal event-path propagation\n\t\t\treturn true;\n\t\t},\n\n\t\t// Suppress native focus or blur as it's already being fired\n\t\t// in leverageNative.\n\t\t_default: function() {\n\t\t\treturn true;\n\t\t},\n\n\t\tdelegateType: delegateType\n\t};\n} );\n\n// Create mouseenter/leave events using mouseover/out and event-time checks\n// so that event delegation works in jQuery.\n// Do the same for pointerenter/pointerleave and pointerover/pointerout\n//\n// Support: Safari 7 only\n// Safari sends mouseenter too often; see:\n// https://bugs.chromium.org/p/chromium/issues/detail?id=470258\n// for the description of the bug (it existed in older Chrome versions as well).\njQuery.each( {\n\tmouseenter: \"mouseover\",\n\tmouseleave: \"mouseout\",\n\tpointerenter: \"pointerover\",\n\tpointerleave: \"pointerout\"\n}, function( orig, fix ) {\n\tjQuery.event.special[ orig ] = {\n\t\tdelegateType: fix,\n\t\tbindType: fix,\n\n\t\thandle: function( event ) {\n\t\t\tvar ret,\n\t\t\t\ttarget = this,\n\t\t\t\trelated = event.relatedTarget,\n\t\t\t\thandleObj = event.handleObj;\n\n\t\t\t// For mouseenter/leave call the handler if related is outside the target.\n\t\t\t// NB: No relatedTarget if the mouse left/entered the browser window\n\t\t\tif ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {\n\t\t\t\tevent.type = handleObj.origType;\n\t\t\t\tret = handleObj.handler.apply( this, arguments );\n\t\t\t\tevent.type = fix;\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t};\n} );\n\njQuery.fn.extend( {\n\n\ton: function( types, selector, data, fn ) {\n\t\treturn on( this, types, selector, data, fn );\n\t},\n\tone: function( types, selector, data, fn ) {\n\t\treturn on( this, types, selector, data, fn, 1 );\n\t},\n\toff: function( types, selector, fn ) {\n\t\tvar handleObj, type;\n\t\tif ( types && types.preventDefault && types.handleObj ) {\n\n\t\t\t// ( event )  dispatched jQuery.Event\n\t\t\thandleObj = types.handleObj;\n\t\t\tjQuery( types.delegateTarget ).off(\n\t\t\t\thandleObj.namespace ?\n\t\t\t\t\thandleObj.origType + \".\" + handleObj.namespace :\n\t\t\t\t\thandleObj.origType,\n\t\t\t\thandleObj.selector,\n\t\t\t\thandleObj.handler\n\t\t\t);\n\t\t\treturn this;\n\t\t}\n\t\tif ( typeof types === \"object\" ) {\n\n\t\t\t// ( types-object [, selector] )\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.off( type, selector, types[ type ] );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t\tif ( selector === false || typeof selector === \"function\" ) {\n\n\t\t\t// ( types [, fn] )\n\t\t\tfn = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.remove( this, types, fn, selector );\n\t\t} );\n\t}\n} );\n\n\nvar\n\n\t// Support: IE <=10 - 11, Edge 12 - 13 only\n\t// In IE/Edge using regex groups here causes severe slowdowns.\n\t// See https://connect.microsoft.com/IE/feedback/details/1736512/\n\trnoInnerhtml = /<script|<style|<link/i,\n\n\t// checked=\"checked\" or checked\n\trchecked = /checked\\s*(?:[^=]|=\\s*.checked.)/i,\n\trcleanScript = /^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g;\n\n// Prefer a tbody over its parent table for containing new rows\nfunction manipulationTarget( elem, content ) {\n\tif ( nodeName( elem, \"table\" ) &&\n\t\tnodeName( content.nodeType !== 11 ? content : content.firstChild, \"tr\" ) ) {\n\n\t\treturn jQuery( elem ).children( \"tbody\" )[ 0 ] || elem;\n\t}\n\n\treturn elem;\n}\n\n// Replace/restore the type attribute of script elements for safe DOM manipulation\nfunction disableScript( elem ) {\n\telem.type = ( elem.getAttribute( \"type\" ) !== null ) + \"/\" + elem.type;\n\treturn elem;\n}\nfunction restoreScript( elem ) {\n\tif ( ( elem.type || \"\" ).slice( 0, 5 ) === \"true/\" ) {\n\t\telem.type = elem.type.slice( 5 );\n\t} else {\n\t\telem.removeAttribute( \"type\" );\n\t}\n\n\treturn elem;\n}\n\nfunction cloneCopyEvent( src, dest ) {\n\tvar i, l, type, pdataOld, udataOld, udataCur, events;\n\n\tif ( dest.nodeType !== 1 ) {\n\t\treturn;\n\t}\n\n\t// 1. Copy private data: events, handlers, etc.\n\tif ( dataPriv.hasData( src ) ) {\n\t\tpdataOld = dataPriv.get( src );\n\t\tevents = pdataOld.events;\n\n\t\tif ( events ) {\n\t\t\tdataPriv.remove( dest, \"handle events\" );\n\n\t\t\tfor ( type in events ) {\n\t\t\t\tfor ( i = 0, l = events[ type ].length; i < l; i++ ) {\n\t\t\t\t\tjQuery.event.add( dest, type, events[ type ][ i ] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// 2. Copy user data\n\tif ( dataUser.hasData( src ) ) {\n\t\tudataOld = dataUser.access( src );\n\t\tudataCur = jQuery.extend( {}, udataOld );\n\n\t\tdataUser.set( dest, udataCur );\n\t}\n}\n\n// Fix IE bugs, see support tests\nfunction fixInput( src, dest ) {\n\tvar nodeName = dest.nodeName.toLowerCase();\n\n\t// Fails to persist the checked state of a cloned checkbox or radio button.\n\tif ( nodeName === \"input\" && rcheckableType.test( src.type ) ) {\n\t\tdest.checked = src.checked;\n\n\t// Fails to return the selected option to the default selected state when cloning options\n\t} else if ( nodeName === \"input\" || nodeName === \"textarea\" ) {\n\t\tdest.defaultValue = src.defaultValue;\n\t}\n}\n\nfunction domManip( collection, args, callback, ignored ) {\n\n\t// Flatten any nested arrays\n\targs = flat( args );\n\n\tvar fragment, first, scripts, hasScripts, node, doc,\n\t\ti = 0,\n\t\tl = collection.length,\n\t\tiNoClone = l - 1,\n\t\tvalue = args[ 0 ],\n\t\tvalueIsFunction = isFunction( value );\n\n\t// We can't cloneNode fragments that contain checked, in WebKit\n\tif ( valueIsFunction ||\n\t\t\t( l > 1 && typeof value === \"string\" &&\n\t\t\t\t!support.checkClone && rchecked.test( value ) ) ) {\n\t\treturn collection.each( function( index ) {\n\t\t\tvar self = collection.eq( index );\n\t\t\tif ( valueIsFunction ) {\n\t\t\t\targs[ 0 ] = value.call( this, index, self.html() );\n\t\t\t}\n\t\t\tdomManip( self, args, callback, ignored );\n\t\t} );\n\t}\n\n\tif ( l ) {\n\t\tfragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );\n\t\tfirst = fragment.firstChild;\n\n\t\tif ( fragment.childNodes.length === 1 ) {\n\t\t\tfragment = first;\n\t\t}\n\n\t\t// Require either new content or an interest in ignored elements to invoke the callback\n\t\tif ( first || ignored ) {\n\t\t\tscripts = jQuery.map( getAll( fragment, \"script\" ), disableScript );\n\t\t\thasScripts = scripts.length;\n\n\t\t\t// Use the original fragment for the last item\n\t\t\t// instead of the first because it can end up\n\t\t\t// being emptied incorrectly in certain situations (#8070).\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tnode = fragment;\n\n\t\t\t\tif ( i !== iNoClone ) {\n\t\t\t\t\tnode = jQuery.clone( node, true, true );\n\n\t\t\t\t\t// Keep references to cloned scripts for later restoration\n\t\t\t\t\tif ( hasScripts ) {\n\n\t\t\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\t\t\tjQuery.merge( scripts, getAll( node, \"script\" ) );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tcallback.call( collection[ i ], node, i );\n\t\t\t}\n\n\t\t\tif ( hasScripts ) {\n\t\t\t\tdoc = scripts[ scripts.length - 1 ].ownerDocument;\n\n\t\t\t\t// Reenable scripts\n\t\t\t\tjQuery.map( scripts, restoreScript );\n\n\t\t\t\t// Evaluate executable scripts on first document insertion\n\t\t\t\tfor ( i = 0; i < hasScripts; i++ ) {\n\t\t\t\t\tnode = scripts[ i ];\n\t\t\t\t\tif ( rscriptType.test( node.type || \"\" ) &&\n\t\t\t\t\t\t!dataPriv.access( node, \"globalEval\" ) &&\n\t\t\t\t\t\tjQuery.contains( doc, node ) ) {\n\n\t\t\t\t\t\tif ( node.src && ( node.type || \"\" ).toLowerCase()  !== \"module\" ) {\n\n\t\t\t\t\t\t\t// Optional AJAX dependency, but won't run scripts if not present\n\t\t\t\t\t\t\tif ( jQuery._evalUrl && !node.noModule ) {\n\t\t\t\t\t\t\t\tjQuery._evalUrl( node.src, {\n\t\t\t\t\t\t\t\t\tnonce: node.nonce || node.getAttribute( \"nonce\" )\n\t\t\t\t\t\t\t\t}, doc );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tDOMEval( node.textContent.replace( rcleanScript, \"\" ), node, doc );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn collection;\n}\n\nfunction remove( elem, selector, keepData ) {\n\tvar node,\n\t\tnodes = selector ? jQuery.filter( selector, elem ) : elem,\n\t\ti = 0;\n\n\tfor ( ; ( node = nodes[ i ] ) != null; i++ ) {\n\t\tif ( !keepData && node.nodeType === 1 ) {\n\t\t\tjQuery.cleanData( getAll( node ) );\n\t\t}\n\n\t\tif ( node.parentNode ) {\n\t\t\tif ( keepData && isAttached( node ) ) {\n\t\t\t\tsetGlobalEval( getAll( node, \"script\" ) );\n\t\t\t}\n\t\t\tnode.parentNode.removeChild( node );\n\t\t}\n\t}\n\n\treturn elem;\n}\n\njQuery.extend( {\n\thtmlPrefilter: function( html ) {\n\t\treturn html;\n\t},\n\n\tclone: function( elem, dataAndEvents, deepDataAndEvents ) {\n\t\tvar i, l, srcElements, destElements,\n\t\t\tclone = elem.cloneNode( true ),\n\t\t\tinPage = isAttached( elem );\n\n\t\t// Fix IE cloning issues\n\t\tif ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&\n\t\t\t\t!jQuery.isXMLDoc( elem ) ) {\n\n\t\t\t// We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2\n\t\t\tdestElements = getAll( clone );\n\t\t\tsrcElements = getAll( elem );\n\n\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\tfixInput( srcElements[ i ], destElements[ i ] );\n\t\t\t}\n\t\t}\n\n\t\t// Copy the events from the original to the clone\n\t\tif ( dataAndEvents ) {\n\t\t\tif ( deepDataAndEvents ) {\n\t\t\t\tsrcElements = srcElements || getAll( elem );\n\t\t\t\tdestElements = destElements || getAll( clone );\n\n\t\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\t\tcloneCopyEvent( srcElements[ i ], destElements[ i ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcloneCopyEvent( elem, clone );\n\t\t\t}\n\t\t}\n\n\t\t// Preserve script evaluation history\n\t\tdestElements = getAll( clone, \"script\" );\n\t\tif ( destElements.length > 0 ) {\n\t\t\tsetGlobalEval( destElements, !inPage && getAll( elem, \"script\" ) );\n\t\t}\n\n\t\t// Return the cloned set\n\t\treturn clone;\n\t},\n\n\tcleanData: function( elems ) {\n\t\tvar data, elem, type,\n\t\t\tspecial = jQuery.event.special,\n\t\t\ti = 0;\n\n\t\tfor ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {\n\t\t\tif ( acceptData( elem ) ) {\n\t\t\t\tif ( ( data = elem[ dataPriv.expando ] ) ) {\n\t\t\t\t\tif ( data.events ) {\n\t\t\t\t\t\tfor ( type in data.events ) {\n\t\t\t\t\t\t\tif ( special[ type ] ) {\n\t\t\t\t\t\t\t\tjQuery.event.remove( elem, type );\n\n\t\t\t\t\t\t\t// This is a shortcut to avoid jQuery.event.remove's overhead\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.removeEvent( elem, type, data.handle );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Support: Chrome <=35 - 45+\n\t\t\t\t\t// Assign undefined instead of using delete, see Data#remove\n\t\t\t\t\telem[ dataPriv.expando ] = undefined;\n\t\t\t\t}\n\t\t\t\tif ( elem[ dataUser.expando ] ) {\n\n\t\t\t\t\t// Support: Chrome <=35 - 45+\n\t\t\t\t\t// Assign undefined instead of using delete, see Data#remove\n\t\t\t\t\telem[ dataUser.expando ] = undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n} );\n\njQuery.fn.extend( {\n\tdetach: function( selector ) {\n\t\treturn remove( this, selector, true );\n\t},\n\n\tremove: function( selector ) {\n\t\treturn remove( this, selector );\n\t},\n\n\ttext: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\treturn value === undefined ?\n\t\t\t\tjQuery.text( this ) :\n\t\t\t\tthis.empty().each( function() {\n\t\t\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\t\t\tthis.textContent = value;\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t}, null, value, arguments.length );\n\t},\n\n\tappend: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.appendChild( elem );\n\t\t\t}\n\t\t} );\n\t},\n\n\tprepend: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.insertBefore( elem, target.firstChild );\n\t\t\t}\n\t\t} );\n\t},\n\n\tbefore: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this );\n\t\t\t}\n\t\t} );\n\t},\n\n\tafter: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this.nextSibling );\n\t\t\t}\n\t\t} );\n\t},\n\n\tempty: function() {\n\t\tvar elem,\n\t\t\ti = 0;\n\n\t\tfor ( ; ( elem = this[ i ] ) != null; i++ ) {\n\t\t\tif ( elem.nodeType === 1 ) {\n\n\t\t\t\t// Prevent memory leaks\n\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\n\t\t\t\t// Remove any remaining nodes\n\t\t\t\telem.textContent = \"\";\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tclone: function( dataAndEvents, deepDataAndEvents ) {\n\t\tdataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n\t\tdeepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n\t\treturn this.map( function() {\n\t\t\treturn jQuery.clone( this, dataAndEvents, deepDataAndEvents );\n\t\t} );\n\t},\n\n\thtml: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\tvar elem = this[ 0 ] || {},\n\t\t\t\ti = 0,\n\t\t\t\tl = this.length;\n\n\t\t\tif ( value === undefined && elem.nodeType === 1 ) {\n\t\t\t\treturn elem.innerHTML;\n\t\t\t}\n\n\t\t\t// See if we can take a shortcut and just use innerHTML\n\t\t\tif ( typeof value === \"string\" && !rnoInnerhtml.test( value ) &&\n\t\t\t\t!wrapMap[ ( rtagName.exec( value ) || [ \"\", \"\" ] )[ 1 ].toLowerCase() ] ) {\n\n\t\t\t\tvalue = jQuery.htmlPrefilter( value );\n\n\t\t\t\ttry {\n\t\t\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\t\t\telem = this[ i ] || {};\n\n\t\t\t\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t\t\t\t\telem.innerHTML = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\telem = 0;\n\n\t\t\t\t// If using innerHTML throws an exception, use the fallback method\n\t\t\t\t} catch ( e ) {}\n\t\t\t}\n\n\t\t\tif ( elem ) {\n\t\t\t\tthis.empty().append( value );\n\t\t\t}\n\t\t}, null, value, arguments.length );\n\t},\n\n\treplaceWith: function() {\n\t\tvar ignored = [];\n\n\t\t// Make the changes, replacing each non-ignored context element with the new content\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tvar parent = this.parentNode;\n\n\t\t\tif ( jQuery.inArray( this, ignored ) < 0 ) {\n\t\t\t\tjQuery.cleanData( getAll( this ) );\n\t\t\t\tif ( parent ) {\n\t\t\t\t\tparent.replaceChild( elem, this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Force callback invocation\n\t\t}, ignored );\n\t}\n} );\n\njQuery.each( {\n\tappendTo: \"append\",\n\tprependTo: \"prepend\",\n\tinsertBefore: \"before\",\n\tinsertAfter: \"after\",\n\treplaceAll: \"replaceWith\"\n}, function( name, original ) {\n\tjQuery.fn[ name ] = function( selector ) {\n\t\tvar elems,\n\t\t\tret = [],\n\t\t\tinsert = jQuery( selector ),\n\t\t\tlast = insert.length - 1,\n\t\t\ti = 0;\n\n\t\tfor ( ; i <= last; i++ ) {\n\t\t\telems = i === last ? this : this.clone( true );\n\t\t\tjQuery( insert[ i ] )[ original ]( elems );\n\n\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t// .get() because push.apply(_, arraylike) throws on ancient WebKit\n\t\t\tpush.apply( ret, elems.get() );\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n} );\nvar rnumnonpx = new RegExp( \"^(\" + pnum + \")(?!px)[a-z%]+$\", \"i\" );\n\nvar getStyles = function( elem ) {\n\n\t\t// Support: IE <=11 only, Firefox <=30 (#15098, #14150)\n\t\t// IE throws on elements created in popups\n\t\t// FF meanwhile throws on frame elements through \"defaultView.getComputedStyle\"\n\t\tvar view = elem.ownerDocument.defaultView;\n\n\t\tif ( !view || !view.opener ) {\n\t\t\tview = window;\n\t\t}\n\n\t\treturn view.getComputedStyle( elem );\n\t};\n\nvar swap = function( elem, options, callback ) {\n\tvar ret, name,\n\t\told = {};\n\n\t// Remember the old values, and insert the new ones\n\tfor ( name in options ) {\n\t\told[ name ] = elem.style[ name ];\n\t\telem.style[ name ] = options[ name ];\n\t}\n\n\tret = callback.call( elem );\n\n\t// Revert the old values\n\tfor ( name in options ) {\n\t\telem.style[ name ] = old[ name ];\n\t}\n\n\treturn ret;\n};\n\n\nvar rboxStyle = new RegExp( cssExpand.join( \"|\" ), \"i\" );\n\n\n\n( function() {\n\n\t// Executing both pixelPosition & boxSizingReliable tests require only one layout\n\t// so they're executed at the same time to save the second computation.\n\tfunction computeStyleTests() {\n\n\t\t// This is a singleton, we need to execute it only once\n\t\tif ( !div ) {\n\t\t\treturn;\n\t\t}\n\n\t\tcontainer.style.cssText = \"position:absolute;left:-11111px;width:60px;\" +\n\t\t\t\"margin-top:1px;padding:0;border:0\";\n\t\tdiv.style.cssText =\n\t\t\t\"position:relative;display:block;box-sizing:border-box;overflow:scroll;\" +\n\t\t\t\"margin:auto;border:1px;padding:1px;\" +\n\t\t\t\"width:60%;top:1%\";\n\t\tdocumentElement.appendChild( container ).appendChild( div );\n\n\t\tvar divStyle = window.getComputedStyle( div );\n\t\tpixelPositionVal = divStyle.top !== \"1%\";\n\n\t\t// Support: Android 4.0 - 4.3 only, Firefox <=3 - 44\n\t\treliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12;\n\n\t\t// Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3\n\t\t// Some styles come back with percentage values, even though they shouldn't\n\t\tdiv.style.right = \"60%\";\n\t\tpixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36;\n\n\t\t// Support: IE 9 - 11 only\n\t\t// Detect misreporting of content dimensions for box-sizing:border-box elements\n\t\tboxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36;\n\n\t\t// Support: IE 9 only\n\t\t// Detect overflow:scroll screwiness (gh-3699)\n\t\t// Support: Chrome <=64\n\t\t// Don't get tricked when zoom affects offsetWidth (gh-4029)\n\t\tdiv.style.position = \"absolute\";\n\t\tscrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12;\n\n\t\tdocumentElement.removeChild( container );\n\n\t\t// Nullify the div so it wouldn't be stored in the memory and\n\t\t// it will also be a sign that checks already performed\n\t\tdiv = null;\n\t}\n\n\tfunction roundPixelMeasures( measure ) {\n\t\treturn Math.round( parseFloat( measure ) );\n\t}\n\n\tvar pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal,\n\t\treliableTrDimensionsVal, reliableMarginLeftVal,\n\t\tcontainer = document.createElement( \"div\" ),\n\t\tdiv = document.createElement( \"div\" );\n\n\t// Finish early in limited (non-browser) environments\n\tif ( !div.style ) {\n\t\treturn;\n\t}\n\n\t// Support: IE <=9 - 11 only\n\t// Style of cloned element affects source element cloned (#8908)\n\tdiv.style.backgroundClip = \"content-box\";\n\tdiv.cloneNode( true ).style.backgroundClip = \"\";\n\tsupport.clearCloneStyle = div.style.backgroundClip === \"content-box\";\n\n\tjQuery.extend( support, {\n\t\tboxSizingReliable: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn boxSizingReliableVal;\n\t\t},\n\t\tpixelBoxStyles: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn pixelBoxStylesVal;\n\t\t},\n\t\tpixelPosition: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn pixelPositionVal;\n\t\t},\n\t\treliableMarginLeft: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn reliableMarginLeftVal;\n\t\t},\n\t\tscrollboxSize: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn scrollboxSizeVal;\n\t\t},\n\n\t\t// Support: IE 9 - 11+, Edge 15 - 18+\n\t\t// IE/Edge misreport `getComputedStyle` of table rows with width/height\n\t\t// set in CSS while `offset*` properties report correct values.\n\t\t// Behavior in IE 9 is more subtle than in newer versions & it passes\n\t\t// some versions of this test; make sure not to make it pass there!\n\t\t//\n\t\t// Support: Firefox 70+\n\t\t// Only Firefox includes border widths\n\t\t// in computed dimensions. (gh-4529)\n\t\treliableTrDimensions: function() {\n\t\t\tvar table, tr, trChild, trStyle;\n\t\t\tif ( reliableTrDimensionsVal == null ) {\n\t\t\t\ttable = document.createElement( \"table\" );\n\t\t\t\ttr = document.createElement( \"tr\" );\n\t\t\t\ttrChild = document.createElement( \"div\" );\n\n\t\t\t\ttable.style.cssText = \"position:absolute;left:-11111px;border-collapse:separate\";\n\t\t\t\ttr.style.cssText = \"border:1px solid\";\n\n\t\t\t\t// Support: Chrome 86+\n\t\t\t\t// Height set through cssText does not get applied.\n\t\t\t\t// Computed height then comes back as 0.\n\t\t\t\ttr.style.height = \"1px\";\n\t\t\t\ttrChild.style.height = \"9px\";\n\n\t\t\t\t// Support: Android 8 Chrome 86+\n\t\t\t\t// In our bodyBackground.html iframe,\n\t\t\t\t// display for all div elements is set to \"inline\",\n\t\t\t\t// which causes a problem only in Android 8 Chrome 86.\n\t\t\t\t// Ensuring the div is display: block\n\t\t\t\t// gets around this issue.\n\t\t\t\ttrChild.style.display = \"block\";\n\n\t\t\t\tdocumentElement\n\t\t\t\t\t.appendChild( table )\n\t\t\t\t\t.appendChild( tr )\n\t\t\t\t\t.appendChild( trChild );\n\n\t\t\t\ttrStyle = window.getComputedStyle( tr );\n\t\t\t\treliableTrDimensionsVal = ( parseInt( trStyle.height, 10 ) +\n\t\t\t\t\tparseInt( trStyle.borderTopWidth, 10 ) +\n\t\t\t\t\tparseInt( trStyle.borderBottomWidth, 10 ) ) === tr.offsetHeight;\n\n\t\t\t\tdocumentElement.removeChild( table );\n\t\t\t}\n\t\t\treturn reliableTrDimensionsVal;\n\t\t}\n\t} );\n} )();\n\n\nfunction curCSS( elem, name, computed ) {\n\tvar width, minWidth, maxWidth, ret,\n\n\t\t// Support: Firefox 51+\n\t\t// Retrieving style before computed somehow\n\t\t// fixes an issue with getting wrong values\n\t\t// on detached elements\n\t\tstyle = elem.style;\n\n\tcomputed = computed || getStyles( elem );\n\n\t// getPropertyValue is needed for:\n\t//   .css('filter') (IE 9 only, #12537)\n\t//   .css('--customProperty) (#3144)\n\tif ( computed ) {\n\t\tret = computed.getPropertyValue( name ) || computed[ name ];\n\n\t\tif ( ret === \"\" && !isAttached( elem ) ) {\n\t\t\tret = jQuery.style( elem, name );\n\t\t}\n\n\t\t// A tribute to the \"awesome hack by Dean Edwards\"\n\t\t// Android Browser returns percentage for some values,\n\t\t// but width seems to be reliably pixels.\n\t\t// This is against the CSSOM draft spec:\n\t\t// https://drafts.csswg.org/cssom/#resolved-values\n\t\tif ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) {\n\n\t\t\t// Remember the original values\n\t\t\twidth = style.width;\n\t\t\tminWidth = style.minWidth;\n\t\t\tmaxWidth = style.maxWidth;\n\n\t\t\t// Put in the new values to get a computed value out\n\t\t\tstyle.minWidth = style.maxWidth = style.width = ret;\n\t\t\tret = computed.width;\n\n\t\t\t// Revert the changed values\n\t\t\tstyle.width = width;\n\t\t\tstyle.minWidth = minWidth;\n\t\t\tstyle.maxWidth = maxWidth;\n\t\t}\n\t}\n\n\treturn ret !== undefined ?\n\n\t\t// Support: IE <=9 - 11 only\n\t\t// IE returns zIndex value as an integer.\n\t\tret + \"\" :\n\t\tret;\n}\n\n\nfunction addGetHookIf( conditionFn, hookFn ) {\n\n\t// Define the hook, we'll check on the first run if it's really needed.\n\treturn {\n\t\tget: function() {\n\t\t\tif ( conditionFn() ) {\n\n\t\t\t\t// Hook not needed (or it's not possible to use it due\n\t\t\t\t// to missing dependency), remove it.\n\t\t\t\tdelete this.get;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Hook needed; redefine it so that the support test is not executed again.\n\t\t\treturn ( this.get = hookFn ).apply( this, arguments );\n\t\t}\n\t};\n}\n\n\nvar cssPrefixes = [ \"Webkit\", \"Moz\", \"ms\" ],\n\temptyStyle = document.createElement( \"div\" ).style,\n\tvendorProps = {};\n\n// Return a vendor-prefixed property or undefined\nfunction vendorPropName( name ) {\n\n\t// Check for vendor prefixed names\n\tvar capName = name[ 0 ].toUpperCase() + name.slice( 1 ),\n\t\ti = cssPrefixes.length;\n\n\twhile ( i-- ) {\n\t\tname = cssPrefixes[ i ] + capName;\n\t\tif ( name in emptyStyle ) {\n\t\t\treturn name;\n\t\t}\n\t}\n}\n\n// Return a potentially-mapped jQuery.cssProps or vendor prefixed property\nfunction finalPropName( name ) {\n\tvar final = jQuery.cssProps[ name ] || vendorProps[ name ];\n\n\tif ( final ) {\n\t\treturn final;\n\t}\n\tif ( name in emptyStyle ) {\n\t\treturn name;\n\t}\n\treturn vendorProps[ name ] = vendorPropName( name ) || name;\n}\n\n\nvar\n\n\t// Swappable if display is none or starts with table\n\t// except \"table\", \"table-cell\", or \"table-caption\"\n\t// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display\n\trdisplayswap = /^(none|table(?!-c[ea]).+)/,\n\trcustomProp = /^--/,\n\tcssShow = { position: \"absolute\", visibility: \"hidden\", display: \"block\" },\n\tcssNormalTransform = {\n\t\tletterSpacing: \"0\",\n\t\tfontWeight: \"400\"\n\t};\n\nfunction setPositiveNumber( _elem, value, subtract ) {\n\n\t// Any relative (+/-) values have already been\n\t// normalized at this point\n\tvar matches = rcssNum.exec( value );\n\treturn matches ?\n\n\t\t// Guard against undefined \"subtract\", e.g., when used as in cssHooks\n\t\tMath.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || \"px\" ) :\n\t\tvalue;\n}\n\nfunction boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) {\n\tvar i = dimension === \"width\" ? 1 : 0,\n\t\textra = 0,\n\t\tdelta = 0;\n\n\t// Adjustment may not be necessary\n\tif ( box === ( isBorderBox ? \"border\" : \"content\" ) ) {\n\t\treturn 0;\n\t}\n\n\tfor ( ; i < 4; i += 2 ) {\n\n\t\t// Both box models exclude margin\n\t\tif ( box === \"margin\" ) {\n\t\t\tdelta += jQuery.css( elem, box + cssExpand[ i ], true, styles );\n\t\t}\n\n\t\t// If we get here with a content-box, we're seeking \"padding\" or \"border\" or \"margin\"\n\t\tif ( !isBorderBox ) {\n\n\t\t\t// Add padding\n\t\t\tdelta += jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\n\t\t\t// For \"border\" or \"margin\", add border\n\t\t\tif ( box !== \"padding\" ) {\n\t\t\t\tdelta += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\n\t\t\t// But still keep track of it otherwise\n\t\t\t} else {\n\t\t\t\textra += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\n\t\t// If we get here with a border-box (content + padding + border), we're seeking \"content\" or\n\t\t// \"padding\" or \"margin\"\n\t\t} else {\n\n\t\t\t// For \"content\", subtract padding\n\t\t\tif ( box === \"content\" ) {\n\t\t\t\tdelta -= jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\t\t\t}\n\n\t\t\t// For \"content\" or \"padding\", subtract border\n\t\t\tif ( box !== \"margin\" ) {\n\t\t\t\tdelta -= jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Account for positive content-box scroll gutter when requested by providing computedVal\n\tif ( !isBorderBox && computedVal >= 0 ) {\n\n\t\t// offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border\n\t\t// Assuming integer scroll gutter, subtract the rest and round down\n\t\tdelta += Math.max( 0, Math.ceil(\n\t\t\telem[ \"offset\" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -\n\t\t\tcomputedVal -\n\t\t\tdelta -\n\t\t\textra -\n\t\t\t0.5\n\n\t\t// If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter\n\t\t// Use an explicit zero to avoid NaN (gh-3964)\n\t\t) ) || 0;\n\t}\n\n\treturn delta;\n}\n\nfunction getWidthOrHeight( elem, dimension, extra ) {\n\n\t// Start with computed style\n\tvar styles = getStyles( elem ),\n\n\t\t// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322).\n\t\t// Fake content-box until we know it's needed to know the true value.\n\t\tboxSizingNeeded = !support.boxSizingReliable() || extra,\n\t\tisBorderBox = boxSizingNeeded &&\n\t\t\tjQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\tvalueIsBorderBox = isBorderBox,\n\n\t\tval = curCSS( elem, dimension, styles ),\n\t\toffsetProp = \"offset\" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 );\n\n\t// Support: Firefox <=54\n\t// Return a confounding non-pixel value or feign ignorance, as appropriate.\n\tif ( rnumnonpx.test( val ) ) {\n\t\tif ( !extra ) {\n\t\t\treturn val;\n\t\t}\n\t\tval = \"auto\";\n\t}\n\n\n\t// Support: IE 9 - 11 only\n\t// Use offsetWidth/offsetHeight for when box sizing is unreliable.\n\t// In those cases, the computed value can be trusted to be border-box.\n\tif ( ( !support.boxSizingReliable() && isBorderBox ||\n\n\t\t// Support: IE 10 - 11+, Edge 15 - 18+\n\t\t// IE/Edge misreport `getComputedStyle` of table rows with width/height\n\t\t// set in CSS while `offset*` properties report correct values.\n\t\t// Interestingly, in some cases IE 9 doesn't suffer from this issue.\n\t\t!support.reliableTrDimensions() && nodeName( elem, \"tr\" ) ||\n\n\t\t// Fall back to offsetWidth/offsetHeight when value is \"auto\"\n\t\t// This happens for inline elements with no explicit setting (gh-3571)\n\t\tval === \"auto\" ||\n\n\t\t// Support: Android <=4.1 - 4.3 only\n\t\t// Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602)\n\t\t!parseFloat( val ) && jQuery.css( elem, \"display\", false, styles ) === \"inline\" ) &&\n\n\t\t// Make sure the element is visible & connected\n\t\telem.getClientRects().length ) {\n\n\t\tisBorderBox = jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\";\n\n\t\t// Where available, offsetWidth/offsetHeight approximate border box dimensions.\n\t\t// Where not available (e.g., SVG), assume unreliable box-sizing and interpret the\n\t\t// retrieved value as a content box dimension.\n\t\tvalueIsBorderBox = offsetProp in elem;\n\t\tif ( valueIsBorderBox ) {\n\t\t\tval = elem[ offsetProp ];\n\t\t}\n\t}\n\n\t// Normalize \"\" and auto\n\tval = parseFloat( val ) || 0;\n\n\t// Adjust for the element's box model\n\treturn ( val +\n\t\tboxModelAdjustment(\n\t\t\telem,\n\t\t\tdimension,\n\t\t\textra || ( isBorderBox ? \"border\" : \"content\" ),\n\t\t\tvalueIsBorderBox,\n\t\t\tstyles,\n\n\t\t\t// Provide the current computed size to request scroll gutter calculation (gh-3589)\n\t\t\tval\n\t\t)\n\t) + \"px\";\n}\n\njQuery.extend( {\n\n\t// Add in style property hooks for overriding the default\n\t// behavior of getting and setting a style property\n\tcssHooks: {\n\t\topacity: {\n\t\t\tget: function( elem, computed ) {\n\t\t\t\tif ( computed ) {\n\n\t\t\t\t\t// We should always get a number back from opacity\n\t\t\t\t\tvar ret = curCSS( elem, \"opacity\" );\n\t\t\t\t\treturn ret === \"\" ? \"1\" : ret;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t// Don't automatically add \"px\" to these possibly-unitless properties\n\tcssNumber: {\n\t\t\"animationIterationCount\": true,\n\t\t\"columnCount\": true,\n\t\t\"fillOpacity\": true,\n\t\t\"flexGrow\": true,\n\t\t\"flexShrink\": true,\n\t\t\"fontWeight\": true,\n\t\t\"gridArea\": true,\n\t\t\"gridColumn\": true,\n\t\t\"gridColumnEnd\": true,\n\t\t\"gridColumnStart\": true,\n\t\t\"gridRow\": true,\n\t\t\"gridRowEnd\": true,\n\t\t\"gridRowStart\": true,\n\t\t\"lineHeight\": true,\n\t\t\"opacity\": true,\n\t\t\"order\": true,\n\t\t\"orphans\": true,\n\t\t\"widows\": true,\n\t\t\"zIndex\": true,\n\t\t\"zoom\": true\n\t},\n\n\t// Add in properties whose names you wish to fix before\n\t// setting or getting the value\n\tcssProps: {},\n\n\t// Get and set the style property on a DOM Node\n\tstyle: function( elem, name, value, extra ) {\n\n\t\t// Don't set styles on text and comment nodes\n\t\tif ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure that we're working with the right name\n\t\tvar ret, type, hooks,\n\t\t\torigName = camelCase( name ),\n\t\t\tisCustomProp = rcustomProp.test( name ),\n\t\t\tstyle = elem.style;\n\n\t\t// Make sure that we're working with the right name. We don't\n\t\t// want to query the value if it is a CSS custom property\n\t\t// since they are user-defined.\n\t\tif ( !isCustomProp ) {\n\t\t\tname = finalPropName( origName );\n\t\t}\n\n\t\t// Gets hook for the prefixed version, then unprefixed version\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// Check if we're setting a value\n\t\tif ( value !== undefined ) {\n\t\t\ttype = typeof value;\n\n\t\t\t// Convert \"+=\" or \"-=\" to relative numbers (#7345)\n\t\t\tif ( type === \"string\" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {\n\t\t\t\tvalue = adjustCSS( elem, name, ret );\n\n\t\t\t\t// Fixes bug #9237\n\t\t\t\ttype = \"number\";\n\t\t\t}\n\n\t\t\t// Make sure that null and NaN values aren't set (#7116)\n\t\t\tif ( value == null || value !== value ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If a number was passed in, add the unit (except for certain CSS properties)\n\t\t\t// The isCustomProp check can be removed in jQuery 4.0 when we only auto-append\n\t\t\t// \"px\" to a few hardcoded values.\n\t\t\tif ( type === \"number\" && !isCustomProp ) {\n\t\t\t\tvalue += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? \"\" : \"px\" );\n\t\t\t}\n\n\t\t\t// background-* props affect original clone's values\n\t\t\tif ( !support.clearCloneStyle && value === \"\" && name.indexOf( \"background\" ) === 0 ) {\n\t\t\t\tstyle[ name ] = \"inherit\";\n\t\t\t}\n\n\t\t\t// If a hook was provided, use that value, otherwise just set the specified value\n\t\t\tif ( !hooks || !( \"set\" in hooks ) ||\n\t\t\t\t( value = hooks.set( elem, value, extra ) ) !== undefined ) {\n\n\t\t\t\tif ( isCustomProp ) {\n\t\t\t\t\tstyle.setProperty( name, value );\n\t\t\t\t} else {\n\t\t\t\t\tstyle[ name ] = value;\n\t\t\t\t}\n\t\t\t}\n\n\t\t} else {\n\n\t\t\t// If a hook was provided get the non-computed value from there\n\t\t\tif ( hooks && \"get\" in hooks &&\n\t\t\t\t( ret = hooks.get( elem, false, extra ) ) !== undefined ) {\n\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\t// Otherwise just get the value from the style object\n\t\t\treturn style[ name ];\n\t\t}\n\t},\n\n\tcss: function( elem, name, extra, styles ) {\n\t\tvar val, num, hooks,\n\t\t\torigName = camelCase( name ),\n\t\t\tisCustomProp = rcustomProp.test( name );\n\n\t\t// Make sure that we're working with the right name. We don't\n\t\t// want to modify the value if it is a CSS custom property\n\t\t// since they are user-defined.\n\t\tif ( !isCustomProp ) {\n\t\t\tname = finalPropName( origName );\n\t\t}\n\n\t\t// Try prefixed name followed by the unprefixed name\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// If a hook was provided get the computed value from there\n\t\tif ( hooks && \"get\" in hooks ) {\n\t\t\tval = hooks.get( elem, true, extra );\n\t\t}\n\n\t\t// Otherwise, if a way to get the computed value exists, use that\n\t\tif ( val === undefined ) {\n\t\t\tval = curCSS( elem, name, styles );\n\t\t}\n\n\t\t// Convert \"normal\" to computed value\n\t\tif ( val === \"normal\" && name in cssNormalTransform ) {\n\t\t\tval = cssNormalTransform[ name ];\n\t\t}\n\n\t\t// Make numeric if forced or a qualifier was provided and val looks numeric\n\t\tif ( extra === \"\" || extra ) {\n\t\t\tnum = parseFloat( val );\n\t\t\treturn extra === true || isFinite( num ) ? num || 0 : val;\n\t\t}\n\n\t\treturn val;\n\t}\n} );\n\njQuery.each( [ \"height\", \"width\" ], function( _i, dimension ) {\n\tjQuery.cssHooks[ dimension ] = {\n\t\tget: function( elem, computed, extra ) {\n\t\t\tif ( computed ) {\n\n\t\t\t\t// Certain elements can have dimension info if we invisibly show them\n\t\t\t\t// but it must have a current display style that would benefit\n\t\t\t\treturn rdisplayswap.test( jQuery.css( elem, \"display\" ) ) &&\n\n\t\t\t\t\t// Support: Safari 8+\n\t\t\t\t\t// Table columns in Safari have non-zero offsetWidth & zero\n\t\t\t\t\t// getBoundingClientRect().width unless display is changed.\n\t\t\t\t\t// Support: IE <=11 only\n\t\t\t\t\t// Running getBoundingClientRect on a disconnected node\n\t\t\t\t\t// in IE throws an error.\n\t\t\t\t\t( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?\n\t\t\t\t\tswap( elem, cssShow, function() {\n\t\t\t\t\t\treturn getWidthOrHeight( elem, dimension, extra );\n\t\t\t\t\t} ) :\n\t\t\t\t\tgetWidthOrHeight( elem, dimension, extra );\n\t\t\t}\n\t\t},\n\n\t\tset: function( elem, value, extra ) {\n\t\t\tvar matches,\n\t\t\t\tstyles = getStyles( elem ),\n\n\t\t\t\t// Only read styles.position if the test has a chance to fail\n\t\t\t\t// to avoid forcing a reflow.\n\t\t\t\tscrollboxSizeBuggy = !support.scrollboxSize() &&\n\t\t\t\t\tstyles.position === \"absolute\",\n\n\t\t\t\t// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991)\n\t\t\t\tboxSizingNeeded = scrollboxSizeBuggy || extra,\n\t\t\t\tisBorderBox = boxSizingNeeded &&\n\t\t\t\t\tjQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\t\t\tsubtract = extra ?\n\t\t\t\t\tboxModelAdjustment(\n\t\t\t\t\t\telem,\n\t\t\t\t\t\tdimension,\n\t\t\t\t\t\textra,\n\t\t\t\t\t\tisBorderBox,\n\t\t\t\t\t\tstyles\n\t\t\t\t\t) :\n\t\t\t\t\t0;\n\n\t\t\t// Account for unreliable border-box dimensions by comparing offset* to computed and\n\t\t\t// faking a content-box to get border and padding (gh-3699)\n\t\t\tif ( isBorderBox && scrollboxSizeBuggy ) {\n\t\t\t\tsubtract -= Math.ceil(\n\t\t\t\t\telem[ \"offset\" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -\n\t\t\t\t\tparseFloat( styles[ dimension ] ) -\n\t\t\t\t\tboxModelAdjustment( elem, dimension, \"border\", false, styles ) -\n\t\t\t\t\t0.5\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Convert to pixels if value adjustment is needed\n\t\t\tif ( subtract && ( matches = rcssNum.exec( value ) ) &&\n\t\t\t\t( matches[ 3 ] || \"px\" ) !== \"px\" ) {\n\n\t\t\t\telem.style[ dimension ] = value;\n\t\t\t\tvalue = jQuery.css( elem, dimension );\n\t\t\t}\n\n\t\t\treturn setPositiveNumber( elem, value, subtract );\n\t\t}\n\t};\n} );\n\njQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,\n\tfunction( elem, computed ) {\n\t\tif ( computed ) {\n\t\t\treturn ( parseFloat( curCSS( elem, \"marginLeft\" ) ) ||\n\t\t\t\telem.getBoundingClientRect().left -\n\t\t\t\t\tswap( elem, { marginLeft: 0 }, function() {\n\t\t\t\t\t\treturn elem.getBoundingClientRect().left;\n\t\t\t\t\t} )\n\t\t\t) + \"px\";\n\t\t}\n\t}\n);\n\n// These hooks are used by animate to expand properties\njQuery.each( {\n\tmargin: \"\",\n\tpadding: \"\",\n\tborder: \"Width\"\n}, function( prefix, suffix ) {\n\tjQuery.cssHooks[ prefix + suffix ] = {\n\t\texpand: function( value ) {\n\t\t\tvar i = 0,\n\t\t\t\texpanded = {},\n\n\t\t\t\t// Assumes a single number if not a string\n\t\t\t\tparts = typeof value === \"string\" ? value.split( \" \" ) : [ value ];\n\n\t\t\tfor ( ; i < 4; i++ ) {\n\t\t\t\texpanded[ prefix + cssExpand[ i ] + suffix ] =\n\t\t\t\t\tparts[ i ] || parts[ i - 2 ] || parts[ 0 ];\n\t\t\t}\n\n\t\t\treturn expanded;\n\t\t}\n\t};\n\n\tif ( prefix !== \"margin\" ) {\n\t\tjQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;\n\t}\n} );\n\njQuery.fn.extend( {\n\tcss: function( name, value ) {\n\t\treturn access( this, function( elem, name, value ) {\n\t\t\tvar styles, len,\n\t\t\t\tmap = {},\n\t\t\t\ti = 0;\n\n\t\t\tif ( Array.isArray( name ) ) {\n\t\t\t\tstyles = getStyles( elem );\n\t\t\t\tlen = name.length;\n\n\t\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t\tmap[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\t\t\t}\n\n\t\t\treturn value !== undefined ?\n\t\t\t\tjQuery.style( elem, name, value ) :\n\t\t\t\tjQuery.css( elem, name );\n\t\t}, name, value, arguments.length > 1 );\n\t}\n} );\n\n\nfunction Tween( elem, options, prop, end, easing ) {\n\treturn new Tween.prototype.init( elem, options, prop, end, easing );\n}\njQuery.Tween = Tween;\n\nTween.prototype = {\n\tconstructor: Tween,\n\tinit: function( elem, options, prop, end, easing, unit ) {\n\t\tthis.elem = elem;\n\t\tthis.prop = prop;\n\t\tthis.easing = easing || jQuery.easing._default;\n\t\tthis.options = options;\n\t\tthis.start = this.now = this.cur();\n\t\tthis.end = end;\n\t\tthis.unit = unit || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" );\n\t},\n\tcur: function() {\n\t\tvar hooks = Tween.propHooks[ this.prop ];\n\n\t\treturn hooks && hooks.get ?\n\t\t\thooks.get( this ) :\n\t\t\tTween.propHooks._default.get( this );\n\t},\n\trun: function( percent ) {\n\t\tvar eased,\n\t\t\thooks = Tween.propHooks[ this.prop ];\n\n\t\tif ( this.options.duration ) {\n\t\t\tthis.pos = eased = jQuery.easing[ this.easing ](\n\t\t\t\tpercent, this.options.duration * percent, 0, 1, this.options.duration\n\t\t\t);\n\t\t} else {\n\t\t\tthis.pos = eased = percent;\n\t\t}\n\t\tthis.now = ( this.end - this.start ) * eased + this.start;\n\n\t\tif ( this.options.step ) {\n\t\t\tthis.options.step.call( this.elem, this.now, this );\n\t\t}\n\n\t\tif ( hooks && hooks.set ) {\n\t\t\thooks.set( this );\n\t\t} else {\n\t\t\tTween.propHooks._default.set( this );\n\t\t}\n\t\treturn this;\n\t}\n};\n\nTween.prototype.init.prototype = Tween.prototype;\n\nTween.propHooks = {\n\t_default: {\n\t\tget: function( tween ) {\n\t\t\tvar result;\n\n\t\t\t// Use a property on the element directly when it is not a DOM element,\n\t\t\t// or when there is no matching style property that exists.\n\t\t\tif ( tween.elem.nodeType !== 1 ||\n\t\t\t\ttween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {\n\t\t\t\treturn tween.elem[ tween.prop ];\n\t\t\t}\n\n\t\t\t// Passing an empty string as a 3rd parameter to .css will automatically\n\t\t\t// attempt a parseFloat and fallback to a string if the parse fails.\n\t\t\t// Simple values such as \"10px\" are parsed to Float;\n\t\t\t// complex values such as \"rotate(1rad)\" are returned as-is.\n\t\t\tresult = jQuery.css( tween.elem, tween.prop, \"\" );\n\n\t\t\t// Empty strings, null, undefined and \"auto\" are converted to 0.\n\t\t\treturn !result || result === \"auto\" ? 0 : result;\n\t\t},\n\t\tset: function( tween ) {\n\n\t\t\t// Use step hook for back compat.\n\t\t\t// Use cssHook if its there.\n\t\t\t// Use .style if available and use plain properties where available.\n\t\t\tif ( jQuery.fx.step[ tween.prop ] ) {\n\t\t\t\tjQuery.fx.step[ tween.prop ]( tween );\n\t\t\t} else if ( tween.elem.nodeType === 1 && (\n\t\t\t\tjQuery.cssHooks[ tween.prop ] ||\n\t\t\t\t\ttween.elem.style[ finalPropName( tween.prop ) ] != null ) ) {\n\t\t\t\tjQuery.style( tween.elem, tween.prop, tween.now + tween.unit );\n\t\t\t} else {\n\t\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Support: IE <=9 only\n// Panic based approach to setting things on disconnected nodes\nTween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {\n\tset: function( tween ) {\n\t\tif ( tween.elem.nodeType && tween.elem.parentNode ) {\n\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t}\n\t}\n};\n\njQuery.easing = {\n\tlinear: function( p ) {\n\t\treturn p;\n\t},\n\tswing: function( p ) {\n\t\treturn 0.5 - Math.cos( p * Math.PI ) / 2;\n\t},\n\t_default: \"swing\"\n};\n\njQuery.fx = Tween.prototype.init;\n\n// Back compat <1.8 extension point\njQuery.fx.step = {};\n\n\n\n\nvar\n\tfxNow, inProgress,\n\trfxtypes = /^(?:toggle|show|hide)$/,\n\trrun = /queueHooks$/;\n\nfunction schedule() {\n\tif ( inProgress ) {\n\t\tif ( document.hidden === false && window.requestAnimationFrame ) {\n\t\t\twindow.requestAnimationFrame( schedule );\n\t\t} else {\n\t\t\twindow.setTimeout( schedule, jQuery.fx.interval );\n\t\t}\n\n\t\tjQuery.fx.tick();\n\t}\n}\n\n// Animations created synchronously will run synchronously\nfunction createFxNow() {\n\twindow.setTimeout( function() {\n\t\tfxNow = undefined;\n\t} );\n\treturn ( fxNow = Date.now() );\n}\n\n// Generate parameters to create a standard animation\nfunction genFx( type, includeWidth ) {\n\tvar which,\n\t\ti = 0,\n\t\tattrs = { height: type };\n\n\t// If we include width, step value is 1 to do all cssExpand values,\n\t// otherwise step value is 2 to skip over Left and Right\n\tincludeWidth = includeWidth ? 1 : 0;\n\tfor ( ; i < 4; i += 2 - includeWidth ) {\n\t\twhich = cssExpand[ i ];\n\t\tattrs[ \"margin\" + which ] = attrs[ \"padding\" + which ] = type;\n\t}\n\n\tif ( includeWidth ) {\n\t\tattrs.opacity = attrs.width = type;\n\t}\n\n\treturn attrs;\n}\n\nfunction createTween( value, prop, animation ) {\n\tvar tween,\n\t\tcollection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ \"*\" ] ),\n\t\tindex = 0,\n\t\tlength = collection.length;\n\tfor ( ; index < length; index++ ) {\n\t\tif ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {\n\n\t\t\t// We're done with this property\n\t\t\treturn tween;\n\t\t}\n\t}\n}\n\nfunction defaultPrefilter( elem, props, opts ) {\n\tvar prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,\n\t\tisBox = \"width\" in props || \"height\" in props,\n\t\tanim = this,\n\t\torig = {},\n\t\tstyle = elem.style,\n\t\thidden = elem.nodeType && isHiddenWithinTree( elem ),\n\t\tdataShow = dataPriv.get( elem, \"fxshow\" );\n\n\t// Queue-skipping animations hijack the fx hooks\n\tif ( !opts.queue ) {\n\t\thooks = jQuery._queueHooks( elem, \"fx\" );\n\t\tif ( hooks.unqueued == null ) {\n\t\t\thooks.unqueued = 0;\n\t\t\toldfire = hooks.empty.fire;\n\t\t\thooks.empty.fire = function() {\n\t\t\t\tif ( !hooks.unqueued ) {\n\t\t\t\t\toldfire();\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\thooks.unqueued++;\n\n\t\tanim.always( function() {\n\n\t\t\t// Ensure the complete handler is called before this completes\n\t\t\tanim.always( function() {\n\t\t\t\thooks.unqueued--;\n\t\t\t\tif ( !jQuery.queue( elem, \"fx\" ).length ) {\n\t\t\t\t\thooks.empty.fire();\n\t\t\t\t}\n\t\t\t} );\n\t\t} );\n\t}\n\n\t// Detect show/hide animations\n\tfor ( prop in props ) {\n\t\tvalue = props[ prop ];\n\t\tif ( rfxtypes.test( value ) ) {\n\t\t\tdelete props[ prop ];\n\t\t\ttoggle = toggle || value === \"toggle\";\n\t\t\tif ( value === ( hidden ? \"hide\" : \"show\" ) ) {\n\n\t\t\t\t// Pretend to be hidden if this is a \"show\" and\n\t\t\t\t// there is still data from a stopped show/hide\n\t\t\t\tif ( value === \"show\" && dataShow && dataShow[ prop ] !== undefined ) {\n\t\t\t\t\thidden = true;\n\n\t\t\t\t// Ignore all other no-op show/hide data\n\t\t\t\t} else {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\torig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );\n\t\t}\n\t}\n\n\t// Bail out if this is a no-op like .hide().hide()\n\tpropTween = !jQuery.isEmptyObject( props );\n\tif ( !propTween && jQuery.isEmptyObject( orig ) ) {\n\t\treturn;\n\t}\n\n\t// Restrict \"overflow\" and \"display\" styles during box animations\n\tif ( isBox && elem.nodeType === 1 ) {\n\n\t\t// Support: IE <=9 - 11, Edge 12 - 15\n\t\t// Record all 3 overflow attributes because IE does not infer the shorthand\n\t\t// from identically-valued overflowX and overflowY and Edge just mirrors\n\t\t// the overflowX value there.\n\t\topts.overflow = [ style.overflow, style.overflowX, style.overflowY ];\n\n\t\t// Identify a display type, preferring old show/hide data over the CSS cascade\n\t\trestoreDisplay = dataShow && dataShow.display;\n\t\tif ( restoreDisplay == null ) {\n\t\t\trestoreDisplay = dataPriv.get( elem, \"display\" );\n\t\t}\n\t\tdisplay = jQuery.css( elem, \"display\" );\n\t\tif ( display === \"none\" ) {\n\t\t\tif ( restoreDisplay ) {\n\t\t\t\tdisplay = restoreDisplay;\n\t\t\t} else {\n\n\t\t\t\t// Get nonempty value(s) by temporarily forcing visibility\n\t\t\t\tshowHide( [ elem ], true );\n\t\t\t\trestoreDisplay = elem.style.display || restoreDisplay;\n\t\t\t\tdisplay = jQuery.css( elem, \"display\" );\n\t\t\t\tshowHide( [ elem ] );\n\t\t\t}\n\t\t}\n\n\t\t// Animate inline elements as inline-block\n\t\tif ( display === \"inline\" || display === \"inline-block\" && restoreDisplay != null ) {\n\t\t\tif ( jQuery.css( elem, \"float\" ) === \"none\" ) {\n\n\t\t\t\t// Restore the original display value at the end of pure show/hide animations\n\t\t\t\tif ( !propTween ) {\n\t\t\t\t\tanim.done( function() {\n\t\t\t\t\t\tstyle.display = restoreDisplay;\n\t\t\t\t\t} );\n\t\t\t\t\tif ( restoreDisplay == null ) {\n\t\t\t\t\t\tdisplay = style.display;\n\t\t\t\t\t\trestoreDisplay = display === \"none\" ? \"\" : display;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tstyle.display = \"inline-block\";\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( opts.overflow ) {\n\t\tstyle.overflow = \"hidden\";\n\t\tanim.always( function() {\n\t\t\tstyle.overflow = opts.overflow[ 0 ];\n\t\t\tstyle.overflowX = opts.overflow[ 1 ];\n\t\t\tstyle.overflowY = opts.overflow[ 2 ];\n\t\t} );\n\t}\n\n\t// Implement show/hide animations\n\tpropTween = false;\n\tfor ( prop in orig ) {\n\n\t\t// General show/hide setup for this element animation\n\t\tif ( !propTween ) {\n\t\t\tif ( dataShow ) {\n\t\t\t\tif ( \"hidden\" in dataShow ) {\n\t\t\t\t\thidden = dataShow.hidden;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tdataShow = dataPriv.access( elem, \"fxshow\", { display: restoreDisplay } );\n\t\t\t}\n\n\t\t\t// Store hidden/visible for toggle so `.stop().toggle()` \"reverses\"\n\t\t\tif ( toggle ) {\n\t\t\t\tdataShow.hidden = !hidden;\n\t\t\t}\n\n\t\t\t// Show elements before animating them\n\t\t\tif ( hidden ) {\n\t\t\t\tshowHide( [ elem ], true );\n\t\t\t}\n\n\t\t\t/* eslint-disable no-loop-func */\n\n\t\t\tanim.done( function() {\n\n\t\t\t\t/* eslint-enable no-loop-func */\n\n\t\t\t\t// The final step of a \"hide\" animation is actually hiding the element\n\t\t\t\tif ( !hidden ) {\n\t\t\t\t\tshowHide( [ elem ] );\n\t\t\t\t}\n\t\t\t\tdataPriv.remove( elem, \"fxshow\" );\n\t\t\t\tfor ( prop in orig ) {\n\t\t\t\t\tjQuery.style( elem, prop, orig[ prop ] );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\t// Per-property setup\n\t\tpropTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );\n\t\tif ( !( prop in dataShow ) ) {\n\t\t\tdataShow[ prop ] = propTween.start;\n\t\t\tif ( hidden ) {\n\t\t\t\tpropTween.end = propTween.start;\n\t\t\t\tpropTween.start = 0;\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction propFilter( props, specialEasing ) {\n\tvar index, name, easing, value, hooks;\n\n\t// camelCase, specialEasing and expand cssHook pass\n\tfor ( index in props ) {\n\t\tname = camelCase( index );\n\t\teasing = specialEasing[ name ];\n\t\tvalue = props[ index ];\n\t\tif ( Array.isArray( value ) ) {\n\t\t\teasing = value[ 1 ];\n\t\t\tvalue = props[ index ] = value[ 0 ];\n\t\t}\n\n\t\tif ( index !== name ) {\n\t\t\tprops[ name ] = value;\n\t\t\tdelete props[ index ];\n\t\t}\n\n\t\thooks = jQuery.cssHooks[ name ];\n\t\tif ( hooks && \"expand\" in hooks ) {\n\t\t\tvalue = hooks.expand( value );\n\t\t\tdelete props[ name ];\n\n\t\t\t// Not quite $.extend, this won't overwrite existing keys.\n\t\t\t// Reusing 'index' because we have the correct \"name\"\n\t\t\tfor ( index in value ) {\n\t\t\t\tif ( !( index in props ) ) {\n\t\t\t\t\tprops[ index ] = value[ index ];\n\t\t\t\t\tspecialEasing[ index ] = easing;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tspecialEasing[ name ] = easing;\n\t\t}\n\t}\n}\n\nfunction Animation( elem, properties, options ) {\n\tvar result,\n\t\tstopped,\n\t\tindex = 0,\n\t\tlength = Animation.prefilters.length,\n\t\tdeferred = jQuery.Deferred().always( function() {\n\n\t\t\t// Don't match elem in the :animated selector\n\t\t\tdelete tick.elem;\n\t\t} ),\n\t\ttick = function() {\n\t\t\tif ( stopped ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar currentTime = fxNow || createFxNow(),\n\t\t\t\tremaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),\n\n\t\t\t\t// Support: Android 2.3 only\n\t\t\t\t// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)\n\t\t\t\ttemp = remaining / animation.duration || 0,\n\t\t\t\tpercent = 1 - temp,\n\t\t\t\tindex = 0,\n\t\t\t\tlength = animation.tweens.length;\n\n\t\t\tfor ( ; index < length; index++ ) {\n\t\t\t\tanimation.tweens[ index ].run( percent );\n\t\t\t}\n\n\t\t\tdeferred.notifyWith( elem, [ animation, percent, remaining ] );\n\n\t\t\t// If there's more to do, yield\n\t\t\tif ( percent < 1 && length ) {\n\t\t\t\treturn remaining;\n\t\t\t}\n\n\t\t\t// If this was an empty animation, synthesize a final progress notification\n\t\t\tif ( !length ) {\n\t\t\t\tdeferred.notifyWith( elem, [ animation, 1, 0 ] );\n\t\t\t}\n\n\t\t\t// Resolve the animation and report its conclusion\n\t\t\tdeferred.resolveWith( elem, [ animation ] );\n\t\t\treturn false;\n\t\t},\n\t\tanimation = deferred.promise( {\n\t\t\telem: elem,\n\t\t\tprops: jQuery.extend( {}, properties ),\n\t\t\topts: jQuery.extend( true, {\n\t\t\t\tspecialEasing: {},\n\t\t\t\teasing: jQuery.easing._default\n\t\t\t}, options ),\n\t\t\toriginalProperties: properties,\n\t\t\toriginalOptions: options,\n\t\t\tstartTime: fxNow || createFxNow(),\n\t\t\tduration: options.duration,\n\t\t\ttweens: [],\n\t\t\tcreateTween: function( prop, end ) {\n\t\t\t\tvar tween = jQuery.Tween( elem, animation.opts, prop, end,\n\t\t\t\t\tanimation.opts.specialEasing[ prop ] || animation.opts.easing );\n\t\t\t\tanimation.tweens.push( tween );\n\t\t\t\treturn tween;\n\t\t\t},\n\t\t\tstop: function( gotoEnd ) {\n\t\t\t\tvar index = 0,\n\n\t\t\t\t\t// If we are going to the end, we want to run all the tweens\n\t\t\t\t\t// otherwise we skip this part\n\t\t\t\t\tlength = gotoEnd ? animation.tweens.length : 0;\n\t\t\t\tif ( stopped ) {\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t\tstopped = true;\n\t\t\t\tfor ( ; index < length; index++ ) {\n\t\t\t\t\tanimation.tweens[ index ].run( 1 );\n\t\t\t\t}\n\n\t\t\t\t// Resolve when we played the last frame; otherwise, reject\n\t\t\t\tif ( gotoEnd ) {\n\t\t\t\t\tdeferred.notifyWith( elem, [ animation, 1, 0 ] );\n\t\t\t\t\tdeferred.resolveWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t} else {\n\t\t\t\t\tdeferred.rejectWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t}\n\t\t} ),\n\t\tprops = animation.props;\n\n\tpropFilter( props, animation.opts.specialEasing );\n\n\tfor ( ; index < length; index++ ) {\n\t\tresult = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );\n\t\tif ( result ) {\n\t\t\tif ( isFunction( result.stop ) ) {\n\t\t\t\tjQuery._queueHooks( animation.elem, animation.opts.queue ).stop =\n\t\t\t\t\tresult.stop.bind( result );\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t}\n\n\tjQuery.map( props, createTween, animation );\n\n\tif ( isFunction( animation.opts.start ) ) {\n\t\tanimation.opts.start.call( elem, animation );\n\t}\n\n\t// Attach callbacks from options\n\tanimation\n\t\t.progress( animation.opts.progress )\n\t\t.done( animation.opts.done, animation.opts.complete )\n\t\t.fail( animation.opts.fail )\n\t\t.always( animation.opts.always );\n\n\tjQuery.fx.timer(\n\t\tjQuery.extend( tick, {\n\t\t\telem: elem,\n\t\t\tanim: animation,\n\t\t\tqueue: animation.opts.queue\n\t\t} )\n\t);\n\n\treturn animation;\n}\n\njQuery.Animation = jQuery.extend( Animation, {\n\n\ttweeners: {\n\t\t\"*\": [ function( prop, value ) {\n\t\t\tvar tween = this.createTween( prop, value );\n\t\t\tadjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );\n\t\t\treturn tween;\n\t\t} ]\n\t},\n\n\ttweener: function( props, callback ) {\n\t\tif ( isFunction( props ) ) {\n\t\t\tcallback = props;\n\t\t\tprops = [ \"*\" ];\n\t\t} else {\n\t\t\tprops = props.match( rnothtmlwhite );\n\t\t}\n\n\t\tvar prop,\n\t\t\tindex = 0,\n\t\t\tlength = props.length;\n\n\t\tfor ( ; index < length; index++ ) {\n\t\t\tprop = props[ index ];\n\t\t\tAnimation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];\n\t\t\tAnimation.tweeners[ prop ].unshift( callback );\n\t\t}\n\t},\n\n\tprefilters: [ defaultPrefilter ],\n\n\tprefilter: function( callback, prepend ) {\n\t\tif ( prepend ) {\n\t\t\tAnimation.prefilters.unshift( callback );\n\t\t} else {\n\t\t\tAnimation.prefilters.push( callback );\n\t\t}\n\t}\n} );\n\njQuery.speed = function( speed, easing, fn ) {\n\tvar opt = speed && typeof speed === \"object\" ? jQuery.extend( {}, speed ) : {\n\t\tcomplete: fn || !fn && easing ||\n\t\t\tisFunction( speed ) && speed,\n\t\tduration: speed,\n\t\teasing: fn && easing || easing && !isFunction( easing ) && easing\n\t};\n\n\t// Go to the end state if fx are off\n\tif ( jQuery.fx.off ) {\n\t\topt.duration = 0;\n\n\t} else {\n\t\tif ( typeof opt.duration !== \"number\" ) {\n\t\t\tif ( opt.duration in jQuery.fx.speeds ) {\n\t\t\t\topt.duration = jQuery.fx.speeds[ opt.duration ];\n\n\t\t\t} else {\n\t\t\t\topt.duration = jQuery.fx.speeds._default;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Normalize opt.queue - true/undefined/null -> \"fx\"\n\tif ( opt.queue == null || opt.queue === true ) {\n\t\topt.queue = \"fx\";\n\t}\n\n\t// Queueing\n\topt.old = opt.complete;\n\n\topt.complete = function() {\n\t\tif ( isFunction( opt.old ) ) {\n\t\t\topt.old.call( this );\n\t\t}\n\n\t\tif ( opt.queue ) {\n\t\t\tjQuery.dequeue( this, opt.queue );\n\t\t}\n\t};\n\n\treturn opt;\n};\n\njQuery.fn.extend( {\n\tfadeTo: function( speed, to, easing, callback ) {\n\n\t\t// Show any hidden elements after setting opacity to 0\n\t\treturn this.filter( isHiddenWithinTree ).css( \"opacity\", 0 ).show()\n\n\t\t\t// Animate to the value specified\n\t\t\t.end().animate( { opacity: to }, speed, easing, callback );\n\t},\n\tanimate: function( prop, speed, easing, callback ) {\n\t\tvar empty = jQuery.isEmptyObject( prop ),\n\t\t\toptall = jQuery.speed( speed, easing, callback ),\n\t\t\tdoAnimation = function() {\n\n\t\t\t\t// Operate on a copy of prop so per-property easing won't be lost\n\t\t\t\tvar anim = Animation( this, jQuery.extend( {}, prop ), optall );\n\n\t\t\t\t// Empty animations, or finishing resolves immediately\n\t\t\t\tif ( empty || dataPriv.get( this, \"finish\" ) ) {\n\t\t\t\t\tanim.stop( true );\n\t\t\t\t}\n\t\t\t};\n\n\t\tdoAnimation.finish = doAnimation;\n\n\t\treturn empty || optall.queue === false ?\n\t\t\tthis.each( doAnimation ) :\n\t\t\tthis.queue( optall.queue, doAnimation );\n\t},\n\tstop: function( type, clearQueue, gotoEnd ) {\n\t\tvar stopQueue = function( hooks ) {\n\t\t\tvar stop = hooks.stop;\n\t\t\tdelete hooks.stop;\n\t\t\tstop( gotoEnd );\n\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tgotoEnd = clearQueue;\n\t\t\tclearQueue = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\tif ( clearQueue ) {\n\t\t\tthis.queue( type || \"fx\", [] );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar dequeue = true,\n\t\t\t\tindex = type != null && type + \"queueHooks\",\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tdata = dataPriv.get( this );\n\n\t\t\tif ( index ) {\n\t\t\t\tif ( data[ index ] && data[ index ].stop ) {\n\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( index in data ) {\n\t\t\t\t\tif ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {\n\t\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this &&\n\t\t\t\t\t( type == null || timers[ index ].queue === type ) ) {\n\n\t\t\t\t\ttimers[ index ].anim.stop( gotoEnd );\n\t\t\t\t\tdequeue = false;\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Start the next in the queue if the last step wasn't forced.\n\t\t\t// Timers currently will call their complete callbacks, which\n\t\t\t// will dequeue but only if they were gotoEnd.\n\t\t\tif ( dequeue || !gotoEnd ) {\n\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t}\n\t\t} );\n\t},\n\tfinish: function( type ) {\n\t\tif ( type !== false ) {\n\t\t\ttype = type || \"fx\";\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tvar index,\n\t\t\t\tdata = dataPriv.get( this ),\n\t\t\t\tqueue = data[ type + \"queue\" ],\n\t\t\t\thooks = data[ type + \"queueHooks\" ],\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tlength = queue ? queue.length : 0;\n\n\t\t\t// Enable finishing flag on private data\n\t\t\tdata.finish = true;\n\n\t\t\t// Empty the queue first\n\t\t\tjQuery.queue( this, type, [] );\n\n\t\t\tif ( hooks && hooks.stop ) {\n\t\t\t\thooks.stop.call( this, true );\n\t\t\t}\n\n\t\t\t// Look for any active animations, and finish them\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && timers[ index ].queue === type ) {\n\t\t\t\t\ttimers[ index ].anim.stop( true );\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Look for any animations in the old queue and finish them\n\t\t\tfor ( index = 0; index < length; index++ ) {\n\t\t\t\tif ( queue[ index ] && queue[ index ].finish ) {\n\t\t\t\t\tqueue[ index ].finish.call( this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Turn off finishing flag\n\t\t\tdelete data.finish;\n\t\t} );\n\t}\n} );\n\njQuery.each( [ \"toggle\", \"show\", \"hide\" ], function( _i, name ) {\n\tvar cssFn = jQuery.fn[ name ];\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn speed == null || typeof speed === \"boolean\" ?\n\t\t\tcssFn.apply( this, arguments ) :\n\t\t\tthis.animate( genFx( name, true ), speed, easing, callback );\n\t};\n} );\n\n// Generate shortcuts for custom animations\njQuery.each( {\n\tslideDown: genFx( \"show\" ),\n\tslideUp: genFx( \"hide\" ),\n\tslideToggle: genFx( \"toggle\" ),\n\tfadeIn: { opacity: \"show\" },\n\tfadeOut: { opacity: \"hide\" },\n\tfadeToggle: { opacity: \"toggle\" }\n}, function( name, props ) {\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn this.animate( props, speed, easing, callback );\n\t};\n} );\n\njQuery.timers = [];\njQuery.fx.tick = function() {\n\tvar timer,\n\t\ti = 0,\n\t\ttimers = jQuery.timers;\n\n\tfxNow = Date.now();\n\n\tfor ( ; i < timers.length; i++ ) {\n\t\ttimer = timers[ i ];\n\n\t\t// Run the timer and safely remove it when done (allowing for external removal)\n\t\tif ( !timer() && timers[ i ] === timer ) {\n\t\t\ttimers.splice( i--, 1 );\n\t\t}\n\t}\n\n\tif ( !timers.length ) {\n\t\tjQuery.fx.stop();\n\t}\n\tfxNow = undefined;\n};\n\njQuery.fx.timer = function( timer ) {\n\tjQuery.timers.push( timer );\n\tjQuery.fx.start();\n};\n\njQuery.fx.interval = 13;\njQuery.fx.start = function() {\n\tif ( inProgress ) {\n\t\treturn;\n\t}\n\n\tinProgress = true;\n\tschedule();\n};\n\njQuery.fx.stop = function() {\n\tinProgress = null;\n};\n\njQuery.fx.speeds = {\n\tslow: 600,\n\tfast: 200,\n\n\t// Default speed\n\t_default: 400\n};\n\n\n// Based off of the plugin by Clint Helfers, with permission.\n// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/\njQuery.fn.delay = function( time, type ) {\n\ttime = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;\n\ttype = type || \"fx\";\n\n\treturn this.queue( type, function( next, hooks ) {\n\t\tvar timeout = window.setTimeout( next, time );\n\t\thooks.stop = function() {\n\t\t\twindow.clearTimeout( timeout );\n\t\t};\n\t} );\n};\n\n\n( function() {\n\tvar input = document.createElement( \"input\" ),\n\t\tselect = document.createElement( \"select\" ),\n\t\topt = select.appendChild( document.createElement( \"option\" ) );\n\n\tinput.type = \"checkbox\";\n\n\t// Support: Android <=4.3 only\n\t// Default value for a checkbox should be \"on\"\n\tsupport.checkOn = input.value !== \"\";\n\n\t// Support: IE <=11 only\n\t// Must access selectedIndex to make default options select\n\tsupport.optSelected = opt.selected;\n\n\t// Support: IE <=11 only\n\t// An input loses its value after becoming a radio\n\tinput = document.createElement( \"input\" );\n\tinput.value = \"t\";\n\tinput.type = \"radio\";\n\tsupport.radioValue = input.value === \"t\";\n} )();\n\n\nvar boolHook,\n\tattrHandle = jQuery.expr.attrHandle;\n\njQuery.fn.extend( {\n\tattr: function( name, value ) {\n\t\treturn access( this, jQuery.attr, name, value, arguments.length > 1 );\n\t},\n\n\tremoveAttr: function( name ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.removeAttr( this, name );\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tattr: function( elem, name, value ) {\n\t\tvar ret, hooks,\n\t\t\tnType = elem.nodeType;\n\n\t\t// Don't get/set attributes on text, comment and attribute nodes\n\t\tif ( nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Fallback to prop when attributes are not supported\n\t\tif ( typeof elem.getAttribute === \"undefined\" ) {\n\t\t\treturn jQuery.prop( elem, name, value );\n\t\t}\n\n\t\t// Attribute hooks are determined by the lowercase version\n\t\t// Grab necessary hook if one is defined\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\t\t\thooks = jQuery.attrHooks[ name.toLowerCase() ] ||\n\t\t\t\t( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( value === null ) {\n\t\t\t\tjQuery.removeAttr( elem, name );\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( hooks && \"set\" in hooks &&\n\t\t\t\t( ret = hooks.set( elem, value, name ) ) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\telem.setAttribute( name, value + \"\" );\n\t\t\treturn value;\n\t\t}\n\n\t\tif ( hooks && \"get\" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\tret = jQuery.find.attr( elem, name );\n\n\t\t// Non-existent attributes return null, we normalize to undefined\n\t\treturn ret == null ? undefined : ret;\n\t},\n\n\tattrHooks: {\n\t\ttype: {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( !support.radioValue && value === \"radio\" &&\n\t\t\t\t\tnodeName( elem, \"input\" ) ) {\n\t\t\t\t\tvar val = elem.value;\n\t\t\t\t\telem.setAttribute( \"type\", value );\n\t\t\t\t\tif ( val ) {\n\t\t\t\t\t\telem.value = val;\n\t\t\t\t\t}\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tremoveAttr: function( elem, value ) {\n\t\tvar name,\n\t\t\ti = 0,\n\n\t\t\t// Attribute names can contain non-HTML whitespace characters\n\t\t\t// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2\n\t\t\tattrNames = value && value.match( rnothtmlwhite );\n\n\t\tif ( attrNames && elem.nodeType === 1 ) {\n\t\t\twhile ( ( name = attrNames[ i++ ] ) ) {\n\t\t\t\telem.removeAttribute( name );\n\t\t\t}\n\t\t}\n\t}\n} );\n\n// Hooks for boolean attributes\nboolHook = {\n\tset: function( elem, value, name ) {\n\t\tif ( value === false ) {\n\n\t\t\t// Remove boolean attributes when set to false\n\t\t\tjQuery.removeAttr( elem, name );\n\t\t} else {\n\t\t\telem.setAttribute( name, name );\n\t\t}\n\t\treturn name;\n\t}\n};\n\njQuery.each( jQuery.expr.match.bool.source.match( /\\w+/g ), function( _i, name ) {\n\tvar getter = attrHandle[ name ] || jQuery.find.attr;\n\n\tattrHandle[ name ] = function( elem, name, isXML ) {\n\t\tvar ret, handle,\n\t\t\tlowercaseName = name.toLowerCase();\n\n\t\tif ( !isXML ) {\n\n\t\t\t// Avoid an infinite loop by temporarily removing this function from the getter\n\t\t\thandle = attrHandle[ lowercaseName ];\n\t\t\tattrHandle[ lowercaseName ] = ret;\n\t\t\tret = getter( elem, name, isXML ) != null ?\n\t\t\t\tlowercaseName :\n\t\t\t\tnull;\n\t\t\tattrHandle[ lowercaseName ] = handle;\n\t\t}\n\t\treturn ret;\n\t};\n} );\n\n\n\n\nvar rfocusable = /^(?:input|select|textarea|button)$/i,\n\trclickable = /^(?:a|area)$/i;\n\njQuery.fn.extend( {\n\tprop: function( name, value ) {\n\t\treturn access( this, jQuery.prop, name, value, arguments.length > 1 );\n\t},\n\n\tremoveProp: function( name ) {\n\t\treturn this.each( function() {\n\t\t\tdelete this[ jQuery.propFix[ name ] || name ];\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tprop: function( elem, name, value ) {\n\t\tvar ret, hooks,\n\t\t\tnType = elem.nodeType;\n\n\t\t// Don't get/set properties on text, comment and attribute nodes\n\t\tif ( nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\n\t\t\t// Fix name and attach hooks\n\t\t\tname = jQuery.propFix[ name ] || name;\n\t\t\thooks = jQuery.propHooks[ name ];\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( hooks && \"set\" in hooks &&\n\t\t\t\t( ret = hooks.set( elem, value, name ) ) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\treturn ( elem[ name ] = value );\n\t\t}\n\n\t\tif ( hooks && \"get\" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\treturn elem[ name ];\n\t},\n\n\tpropHooks: {\n\t\ttabIndex: {\n\t\t\tget: function( elem ) {\n\n\t\t\t\t// Support: IE <=9 - 11 only\n\t\t\t\t// elem.tabIndex doesn't always return the\n\t\t\t\t// correct value when it hasn't been explicitly set\n\t\t\t\t// https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/\n\t\t\t\t// Use proper attribute retrieval(#12072)\n\t\t\t\tvar tabindex = jQuery.find.attr( elem, \"tabindex\" );\n\n\t\t\t\tif ( tabindex ) {\n\t\t\t\t\treturn parseInt( tabindex, 10 );\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\trfocusable.test( elem.nodeName ) ||\n\t\t\t\t\trclickable.test( elem.nodeName ) &&\n\t\t\t\t\telem.href\n\t\t\t\t) {\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t},\n\n\tpropFix: {\n\t\t\"for\": \"htmlFor\",\n\t\t\"class\": \"className\"\n\t}\n} );\n\n// Support: IE <=11 only\n// Accessing the selectedIndex property\n// forces the browser to respect setting selected\n// on the option\n// The getter ensures a default option is selected\n// when in an optgroup\n// eslint rule \"no-unused-expressions\" is disabled for this code\n// since it considers such accessions noop\nif ( !support.optSelected ) {\n\tjQuery.propHooks.selected = {\n\t\tget: function( elem ) {\n\n\t\t\t/* eslint no-unused-expressions: \"off\" */\n\n\t\t\tvar parent = elem.parentNode;\n\t\t\tif ( parent && parent.parentNode ) {\n\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t\tset: function( elem ) {\n\n\t\t\t/* eslint no-unused-expressions: \"off\" */\n\n\t\t\tvar parent = elem.parentNode;\n\t\t\tif ( parent ) {\n\t\t\t\tparent.selectedIndex;\n\n\t\t\t\tif ( parent.parentNode ) {\n\t\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\njQuery.each( [\n\t\"tabIndex\",\n\t\"readOnly\",\n\t\"maxLength\",\n\t\"cellSpacing\",\n\t\"cellPadding\",\n\t\"rowSpan\",\n\t\"colSpan\",\n\t\"useMap\",\n\t\"frameBorder\",\n\t\"contentEditable\"\n], function() {\n\tjQuery.propFix[ this.toLowerCase() ] = this;\n} );\n\n\n\n\n\t// Strip and collapse whitespace according to HTML spec\n\t// https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace\n\tfunction stripAndCollapse( value ) {\n\t\tvar tokens = value.match( rnothtmlwhite ) || [];\n\t\treturn tokens.join( \" \" );\n\t}\n\n\nfunction getClass( elem ) {\n\treturn elem.getAttribute && elem.getAttribute( \"class\" ) || \"\";\n}\n\nfunction classesToArray( value ) {\n\tif ( Array.isArray( value ) ) {\n\t\treturn value;\n\t}\n\tif ( typeof value === \"string\" ) {\n\t\treturn value.match( rnothtmlwhite ) || [];\n\t}\n\treturn [];\n}\n\njQuery.fn.extend( {\n\taddClass: function( value ) {\n\t\tvar classes, elem, cur, curValue, clazz, j, finalValue,\n\t\t\ti = 0;\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( j ) {\n\t\t\t\tjQuery( this ).addClass( value.call( this, j, getClass( this ) ) );\n\t\t\t} );\n\t\t}\n\n\t\tclasses = classesToArray( value );\n\n\t\tif ( classes.length ) {\n\t\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\t\tcurValue = getClass( elem );\n\t\t\t\tcur = elem.nodeType === 1 && ( \" \" + stripAndCollapse( curValue ) + \" \" );\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( ( clazz = classes[ j++ ] ) ) {\n\t\t\t\t\t\tif ( cur.indexOf( \" \" + clazz + \" \" ) < 0 ) {\n\t\t\t\t\t\t\tcur += clazz + \" \";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = stripAndCollapse( cur );\n\t\t\t\t\tif ( curValue !== finalValue ) {\n\t\t\t\t\t\telem.setAttribute( \"class\", finalValue );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tremoveClass: function( value ) {\n\t\tvar classes, elem, cur, curValue, clazz, j, finalValue,\n\t\t\ti = 0;\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( j ) {\n\t\t\t\tjQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );\n\t\t\t} );\n\t\t}\n\n\t\tif ( !arguments.length ) {\n\t\t\treturn this.attr( \"class\", \"\" );\n\t\t}\n\n\t\tclasses = classesToArray( value );\n\n\t\tif ( classes.length ) {\n\t\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\t\tcurValue = getClass( elem );\n\n\t\t\t\t// This expression is here for better compressibility (see addClass)\n\t\t\t\tcur = elem.nodeType === 1 && ( \" \" + stripAndCollapse( curValue ) + \" \" );\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( ( clazz = classes[ j++ ] ) ) {\n\n\t\t\t\t\t\t// Remove *all* instances\n\t\t\t\t\t\twhile ( cur.indexOf( \" \" + clazz + \" \" ) > -1 ) {\n\t\t\t\t\t\t\tcur = cur.replace( \" \" + clazz + \" \", \" \" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = stripAndCollapse( cur );\n\t\t\t\t\tif ( curValue !== finalValue ) {\n\t\t\t\t\t\telem.setAttribute( \"class\", finalValue );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\ttoggleClass: function( value, stateVal ) {\n\t\tvar type = typeof value,\n\t\t\tisValidValue = type === \"string\" || Array.isArray( value );\n\n\t\tif ( typeof stateVal === \"boolean\" && isValidValue ) {\n\t\t\treturn stateVal ? this.addClass( value ) : this.removeClass( value );\n\t\t}\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( i ) {\n\t\t\t\tjQuery( this ).toggleClass(\n\t\t\t\t\tvalue.call( this, i, getClass( this ), stateVal ),\n\t\t\t\t\tstateVal\n\t\t\t\t);\n\t\t\t} );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar className, i, self, classNames;\n\n\t\t\tif ( isValidValue ) {\n\n\t\t\t\t// Toggle individual class names\n\t\t\t\ti = 0;\n\t\t\t\tself = jQuery( this );\n\t\t\t\tclassNames = classesToArray( value );\n\n\t\t\t\twhile ( ( className = classNames[ i++ ] ) ) {\n\n\t\t\t\t\t// Check each className given, space separated list\n\t\t\t\t\tif ( self.hasClass( className ) ) {\n\t\t\t\t\t\tself.removeClass( className );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself.addClass( className );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Toggle whole class name\n\t\t\t} else if ( value === undefined || type === \"boolean\" ) {\n\t\t\t\tclassName = getClass( this );\n\t\t\t\tif ( className ) {\n\n\t\t\t\t\t// Store className if set\n\t\t\t\t\tdataPriv.set( this, \"__className__\", className );\n\t\t\t\t}\n\n\t\t\t\t// If the element has a class name or if we're passed `false`,\n\t\t\t\t// then remove the whole classname (if there was one, the above saved it).\n\t\t\t\t// Otherwise bring back whatever was previously saved (if anything),\n\t\t\t\t// falling back to the empty string if nothing was stored.\n\t\t\t\tif ( this.setAttribute ) {\n\t\t\t\t\tthis.setAttribute( \"class\",\n\t\t\t\t\t\tclassName || value === false ?\n\t\t\t\t\t\t\t\"\" :\n\t\t\t\t\t\t\tdataPriv.get( this, \"__className__\" ) || \"\"\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t},\n\n\thasClass: function( selector ) {\n\t\tvar className, elem,\n\t\t\ti = 0;\n\n\t\tclassName = \" \" + selector + \" \";\n\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\tif ( elem.nodeType === 1 &&\n\t\t\t\t( \" \" + stripAndCollapse( getClass( elem ) ) + \" \" ).indexOf( className ) > -1 ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n} );\n\n\n\n\nvar rreturn = /\\r/g;\n\njQuery.fn.extend( {\n\tval: function( value ) {\n\t\tvar hooks, ret, valueIsFunction,\n\t\t\telem = this[ 0 ];\n\n\t\tif ( !arguments.length ) {\n\t\t\tif ( elem ) {\n\t\t\t\thooks = jQuery.valHooks[ elem.type ] ||\n\t\t\t\t\tjQuery.valHooks[ elem.nodeName.toLowerCase() ];\n\n\t\t\t\tif ( hooks &&\n\t\t\t\t\t\"get\" in hooks &&\n\t\t\t\t\t( ret = hooks.get( elem, \"value\" ) ) !== undefined\n\t\t\t\t) {\n\t\t\t\t\treturn ret;\n\t\t\t\t}\n\n\t\t\t\tret = elem.value;\n\n\t\t\t\t// Handle most common string cases\n\t\t\t\tif ( typeof ret === \"string\" ) {\n\t\t\t\t\treturn ret.replace( rreturn, \"\" );\n\t\t\t\t}\n\n\t\t\t\t// Handle cases where value is null/undef or number\n\t\t\t\treturn ret == null ? \"\" : ret;\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tvalueIsFunction = isFunction( value );\n\n\t\treturn this.each( function( i ) {\n\t\t\tvar val;\n\n\t\t\tif ( this.nodeType !== 1 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( valueIsFunction ) {\n\t\t\t\tval = value.call( this, i, jQuery( this ).val() );\n\t\t\t} else {\n\t\t\t\tval = value;\n\t\t\t}\n\n\t\t\t// Treat null/undefined as \"\"; convert numbers to string\n\t\t\tif ( val == null ) {\n\t\t\t\tval = \"\";\n\n\t\t\t} else if ( typeof val === \"number\" ) {\n\t\t\t\tval += \"\";\n\n\t\t\t} else if ( Array.isArray( val ) ) {\n\t\t\t\tval = jQuery.map( val, function( value ) {\n\t\t\t\t\treturn value == null ? \"\" : value + \"\";\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\thooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];\n\n\t\t\t// If set returns undefined, fall back to normal setting\n\t\t\tif ( !hooks || !( \"set\" in hooks ) || hooks.set( this, val, \"value\" ) === undefined ) {\n\t\t\t\tthis.value = val;\n\t\t\t}\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tvalHooks: {\n\t\toption: {\n\t\t\tget: function( elem ) {\n\n\t\t\t\tvar val = jQuery.find.attr( elem, \"value\" );\n\t\t\t\treturn val != null ?\n\t\t\t\t\tval :\n\n\t\t\t\t\t// Support: IE <=10 - 11 only\n\t\t\t\t\t// option.text throws exceptions (#14686, #14858)\n\t\t\t\t\t// Strip and collapse whitespace\n\t\t\t\t\t// https://html.spec.whatwg.org/#strip-and-collapse-whitespace\n\t\t\t\t\tstripAndCollapse( jQuery.text( elem ) );\n\t\t\t}\n\t\t},\n\t\tselect: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar value, option, i,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tindex = elem.selectedIndex,\n\t\t\t\t\tone = elem.type === \"select-one\",\n\t\t\t\t\tvalues = one ? null : [],\n\t\t\t\t\tmax = one ? index + 1 : options.length;\n\n\t\t\t\tif ( index < 0 ) {\n\t\t\t\t\ti = max;\n\n\t\t\t\t} else {\n\t\t\t\t\ti = one ? index : 0;\n\t\t\t\t}\n\n\t\t\t\t// Loop through all the selected options\n\t\t\t\tfor ( ; i < max; i++ ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t// IE8-9 doesn't update selected after form reset (#2551)\n\t\t\t\t\tif ( ( option.selected || i === index ) &&\n\n\t\t\t\t\t\t\t// Don't return options that are disabled or in a disabled optgroup\n\t\t\t\t\t\t\t!option.disabled &&\n\t\t\t\t\t\t\t( !option.parentNode.disabled ||\n\t\t\t\t\t\t\t\t!nodeName( option.parentNode, \"optgroup\" ) ) ) {\n\n\t\t\t\t\t\t// Get the specific value for the option\n\t\t\t\t\t\tvalue = jQuery( option ).val();\n\n\t\t\t\t\t\t// We don't need an array for one selects\n\t\t\t\t\t\tif ( one ) {\n\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Multi-Selects return an array\n\t\t\t\t\t\tvalues.push( value );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\t\t\t},\n\n\t\t\tset: function( elem, value ) {\n\t\t\t\tvar optionSet, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tvalues = jQuery.makeArray( value ),\n\t\t\t\t\ti = options.length;\n\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t/* eslint-disable no-cond-assign */\n\n\t\t\t\t\tif ( option.selected =\n\t\t\t\t\t\tjQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1\n\t\t\t\t\t) {\n\t\t\t\t\t\toptionSet = true;\n\t\t\t\t\t}\n\n\t\t\t\t\t/* eslint-enable no-cond-assign */\n\t\t\t\t}\n\n\t\t\t\t// Force browsers to behave consistently when non-matching value is set\n\t\t\t\tif ( !optionSet ) {\n\t\t\t\t\telem.selectedIndex = -1;\n\t\t\t\t}\n\t\t\t\treturn values;\n\t\t\t}\n\t\t}\n\t}\n} );\n\n// Radios and checkboxes getter/setter\njQuery.each( [ \"radio\", \"checkbox\" ], function() {\n\tjQuery.valHooks[ this ] = {\n\t\tset: function( elem, value ) {\n\t\t\tif ( Array.isArray( value ) ) {\n\t\t\t\treturn ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );\n\t\t\t}\n\t\t}\n\t};\n\tif ( !support.checkOn ) {\n\t\tjQuery.valHooks[ this ].get = function( elem ) {\n\t\t\treturn elem.getAttribute( \"value\" ) === null ? \"on\" : elem.value;\n\t\t};\n\t}\n} );\n\n\n\n\n// Return jQuery for attributes-only inclusion\n\n\nsupport.focusin = \"onfocusin\" in window;\n\n\nvar rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,\n\tstopPropagationCallback = function( e ) {\n\t\te.stopPropagation();\n\t};\n\njQuery.extend( jQuery.event, {\n\n\ttrigger: function( event, data, elem, onlyHandlers ) {\n\n\t\tvar i, cur, tmp, bubbleType, ontype, handle, special, lastElement,\n\t\t\teventPath = [ elem || document ],\n\t\t\ttype = hasOwn.call( event, \"type\" ) ? event.type : event,\n\t\t\tnamespaces = hasOwn.call( event, \"namespace\" ) ? event.namespace.split( \".\" ) : [];\n\n\t\tcur = lastElement = tmp = elem = elem || document;\n\n\t\t// Don't do events on text and comment nodes\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// focus/blur morphs to focusin/out; ensure we're not firing them right now\n\t\tif ( rfocusMorph.test( type + jQuery.event.triggered ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( type.indexOf( \".\" ) > -1 ) {\n\n\t\t\t// Namespaced trigger; create a regexp to match event type in handle()\n\t\t\tnamespaces = type.split( \".\" );\n\t\t\ttype = namespaces.shift();\n\t\t\tnamespaces.sort();\n\t\t}\n\t\tontype = type.indexOf( \":\" ) < 0 && \"on\" + type;\n\n\t\t// Caller can pass in a jQuery.Event object, Object, or just an event type string\n\t\tevent = event[ jQuery.expando ] ?\n\t\t\tevent :\n\t\t\tnew jQuery.Event( type, typeof event === \"object\" && event );\n\n\t\t// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)\n\t\tevent.isTrigger = onlyHandlers ? 2 : 3;\n\t\tevent.namespace = namespaces.join( \".\" );\n\t\tevent.rnamespace = event.namespace ?\n\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join( \"\\\\.(?:.*\\\\.|)\" ) + \"(\\\\.|$)\" ) :\n\t\t\tnull;\n\n\t\t// Clean up the event in case it is being reused\n\t\tevent.result = undefined;\n\t\tif ( !event.target ) {\n\t\t\tevent.target = elem;\n\t\t}\n\n\t\t// Clone any incoming data and prepend the event, creating the handler arg list\n\t\tdata = data == null ?\n\t\t\t[ event ] :\n\t\t\tjQuery.makeArray( data, [ event ] );\n\n\t\t// Allow special events to draw outside the lines\n\t\tspecial = jQuery.event.special[ type ] || {};\n\t\tif ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine event propagation path in advance, per W3C events spec (#9951)\n\t\t// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)\n\t\tif ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) {\n\n\t\t\tbubbleType = special.delegateType || type;\n\t\t\tif ( !rfocusMorph.test( bubbleType + type ) ) {\n\t\t\t\tcur = cur.parentNode;\n\t\t\t}\n\t\t\tfor ( ; cur; cur = cur.parentNode ) {\n\t\t\t\teventPath.push( cur );\n\t\t\t\ttmp = cur;\n\t\t\t}\n\n\t\t\t// Only add window if we got to document (e.g., not plain obj or detached DOM)\n\t\t\tif ( tmp === ( elem.ownerDocument || document ) ) {\n\t\t\t\teventPath.push( tmp.defaultView || tmp.parentWindow || window );\n\t\t\t}\n\t\t}\n\n\t\t// Fire handlers on the event path\n\t\ti = 0;\n\t\twhile ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {\n\t\t\tlastElement = cur;\n\t\t\tevent.type = i > 1 ?\n\t\t\t\tbubbleType :\n\t\t\t\tspecial.bindType || type;\n\n\t\t\t// jQuery handler\n\t\t\thandle = ( dataPriv.get( cur, \"events\" ) || Object.create( null ) )[ event.type ] &&\n\t\t\t\tdataPriv.get( cur, \"handle\" );\n\t\t\tif ( handle ) {\n\t\t\t\thandle.apply( cur, data );\n\t\t\t}\n\n\t\t\t// Native handler\n\t\t\thandle = ontype && cur[ ontype ];\n\t\t\tif ( handle && handle.apply && acceptData( cur ) ) {\n\t\t\t\tevent.result = handle.apply( cur, data );\n\t\t\t\tif ( event.result === false ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tevent.type = type;\n\n\t\t// If nobody prevented the default action, do it now\n\t\tif ( !onlyHandlers && !event.isDefaultPrevented() ) {\n\n\t\t\tif ( ( !special._default ||\n\t\t\t\tspecial._default.apply( eventPath.pop(), data ) === false ) &&\n\t\t\t\tacceptData( elem ) ) {\n\n\t\t\t\t// Call a native DOM method on the target with the same name as the event.\n\t\t\t\t// Don't do default actions on window, that's where global variables be (#6170)\n\t\t\t\tif ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) {\n\n\t\t\t\t\t// Don't re-trigger an onFOO event when we call its FOO() method\n\t\t\t\t\ttmp = elem[ ontype ];\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = null;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prevent re-triggering of the same event, since we already bubbled it above\n\t\t\t\t\tjQuery.event.triggered = type;\n\n\t\t\t\t\tif ( event.isPropagationStopped() ) {\n\t\t\t\t\t\tlastElement.addEventListener( type, stopPropagationCallback );\n\t\t\t\t\t}\n\n\t\t\t\t\telem[ type ]();\n\n\t\t\t\t\tif ( event.isPropagationStopped() ) {\n\t\t\t\t\t\tlastElement.removeEventListener( type, stopPropagationCallback );\n\t\t\t\t\t}\n\n\t\t\t\t\tjQuery.event.triggered = undefined;\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = tmp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\t// Piggyback on a donor event to simulate a different one\n\t// Used only for `focus(in | out)` events\n\tsimulate: function( type, elem, event ) {\n\t\tvar e = jQuery.extend(\n\t\t\tnew jQuery.Event(),\n\t\t\tevent,\n\t\t\t{\n\t\t\t\ttype: type,\n\t\t\t\tisSimulated: true\n\t\t\t}\n\t\t);\n\n\t\tjQuery.event.trigger( e, null, elem );\n\t}\n\n} );\n\njQuery.fn.extend( {\n\n\ttrigger: function( type, data ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.trigger( type, data, this );\n\t\t} );\n\t},\n\ttriggerHandler: function( type, data ) {\n\t\tvar elem = this[ 0 ];\n\t\tif ( elem ) {\n\t\t\treturn jQuery.event.trigger( type, data, elem, true );\n\t\t}\n\t}\n} );\n\n\n// Support: Firefox <=44\n// Firefox doesn't have focus(in | out) events\n// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787\n//\n// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1\n// focus(in | out) events fire after focus & blur events,\n// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order\n// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857\nif ( !support.focusin ) {\n\tjQuery.each( { focus: \"focusin\", blur: \"focusout\" }, function( orig, fix ) {\n\n\t\t// Attach a single capturing handler on the document while someone wants focusin/focusout\n\t\tvar handler = function( event ) {\n\t\t\tjQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );\n\t\t};\n\n\t\tjQuery.event.special[ fix ] = {\n\t\t\tsetup: function() {\n\n\t\t\t\t// Handle: regular nodes (via `this.ownerDocument`), window\n\t\t\t\t// (via `this.document`) & document (via `this`).\n\t\t\t\tvar doc = this.ownerDocument || this.document || this,\n\t\t\t\t\tattaches = dataPriv.access( doc, fix );\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.addEventListener( orig, handler, true );\n\t\t\t\t}\n\t\t\t\tdataPriv.access( doc, fix, ( attaches || 0 ) + 1 );\n\t\t\t},\n\t\t\tteardown: function() {\n\t\t\t\tvar doc = this.ownerDocument || this.document || this,\n\t\t\t\t\tattaches = dataPriv.access( doc, fix ) - 1;\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.removeEventListener( orig, handler, true );\n\t\t\t\t\tdataPriv.remove( doc, fix );\n\n\t\t\t\t} else {\n\t\t\t\t\tdataPriv.access( doc, fix, attaches );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t} );\n}\nvar location = window.location;\n\nvar nonce = { guid: Date.now() };\n\nvar rquery = ( /\\?/ );\n\n\n\n// Cross-browser xml parsing\njQuery.parseXML = function( data ) {\n\tvar xml, parserErrorElem;\n\tif ( !data || typeof data !== \"string\" ) {\n\t\treturn null;\n\t}\n\n\t// Support: IE 9 - 11 only\n\t// IE throws on parseFromString with invalid input.\n\ttry {\n\t\txml = ( new window.DOMParser() ).parseFromString( data, \"text/xml\" );\n\t} catch ( e ) {}\n\n\tparserErrorElem = xml && xml.getElementsByTagName( \"parsererror\" )[ 0 ];\n\tif ( !xml || parserErrorElem ) {\n\t\tjQuery.error( \"Invalid XML: \" + (\n\t\t\tparserErrorElem ?\n\t\t\t\tjQuery.map( parserErrorElem.childNodes, function( el ) {\n\t\t\t\t\treturn el.textContent;\n\t\t\t\t} ).join( \"\\n\" ) :\n\t\t\t\tdata\n\t\t) );\n\t}\n\treturn xml;\n};\n\n\nvar\n\trbracket = /\\[\\]$/,\n\trCRLF = /\\r?\\n/g,\n\trsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,\n\trsubmittable = /^(?:input|select|textarea|keygen)/i;\n\nfunction buildParams( prefix, obj, traditional, add ) {\n\tvar name;\n\n\tif ( Array.isArray( obj ) ) {\n\n\t\t// Serialize array item.\n\t\tjQuery.each( obj, function( i, v ) {\n\t\t\tif ( traditional || rbracket.test( prefix ) ) {\n\n\t\t\t\t// Treat each array item as a scalar.\n\t\t\t\tadd( prefix, v );\n\n\t\t\t} else {\n\n\t\t\t\t// Item is non-scalar (array or object), encode its numeric index.\n\t\t\t\tbuildParams(\n\t\t\t\t\tprefix + \"[\" + ( typeof v === \"object\" && v != null ? i : \"\" ) + \"]\",\n\t\t\t\t\tv,\n\t\t\t\t\ttraditional,\n\t\t\t\t\tadd\n\t\t\t\t);\n\t\t\t}\n\t\t} );\n\n\t} else if ( !traditional && toType( obj ) === \"object\" ) {\n\n\t\t// Serialize object item.\n\t\tfor ( name in obj ) {\n\t\t\tbuildParams( prefix + \"[\" + name + \"]\", obj[ name ], traditional, add );\n\t\t}\n\n\t} else {\n\n\t\t// Serialize scalar item.\n\t\tadd( prefix, obj );\n\t}\n}\n\n// Serialize an array of form elements or a set of\n// key/values into a query string\njQuery.param = function( a, traditional ) {\n\tvar prefix,\n\t\ts = [],\n\t\tadd = function( key, valueOrFunction ) {\n\n\t\t\t// If value is a function, invoke it and use its return value\n\t\t\tvar value = isFunction( valueOrFunction ) ?\n\t\t\t\tvalueOrFunction() :\n\t\t\t\tvalueOrFunction;\n\n\t\t\ts[ s.length ] = encodeURIComponent( key ) + \"=\" +\n\t\t\t\tencodeURIComponent( value == null ? \"\" : value );\n\t\t};\n\n\tif ( a == null ) {\n\t\treturn \"\";\n\t}\n\n\t// If an array was passed in, assume that it is an array of form elements.\n\tif ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {\n\n\t\t// Serialize the form elements\n\t\tjQuery.each( a, function() {\n\t\t\tadd( this.name, this.value );\n\t\t} );\n\n\t} else {\n\n\t\t// If traditional, encode the \"old\" way (the way 1.3.2 or older\n\t\t// did it), otherwise encode params recursively.\n\t\tfor ( prefix in a ) {\n\t\t\tbuildParams( prefix, a[ prefix ], traditional, add );\n\t\t}\n\t}\n\n\t// Return the resulting serialization\n\treturn s.join( \"&\" );\n};\n\njQuery.fn.extend( {\n\tserialize: function() {\n\t\treturn jQuery.param( this.serializeArray() );\n\t},\n\tserializeArray: function() {\n\t\treturn this.map( function() {\n\n\t\t\t// Can add propHook for \"elements\" to filter or add form elements\n\t\t\tvar elements = jQuery.prop( this, \"elements\" );\n\t\t\treturn elements ? jQuery.makeArray( elements ) : this;\n\t\t} ).filter( function() {\n\t\t\tvar type = this.type;\n\n\t\t\t// Use .is( \":disabled\" ) so that fieldset[disabled] works\n\t\t\treturn this.name && !jQuery( this ).is( \":disabled\" ) &&\n\t\t\t\trsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&\n\t\t\t\t( this.checked || !rcheckableType.test( type ) );\n\t\t} ).map( function( _i, elem ) {\n\t\t\tvar val = jQuery( this ).val();\n\n\t\t\tif ( val == null ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tif ( Array.isArray( val ) ) {\n\t\t\t\treturn jQuery.map( val, function( val ) {\n\t\t\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t} ).get();\n\t}\n} );\n\n\nvar\n\tr20 = /%20/g,\n\trhash = /#.*$/,\n\trantiCache = /([?&])_=[^&]*/,\n\trheaders = /^(.*?):[ \\t]*([^\\r\\n]*)$/mg,\n\n\t// #7653, #8125, #8152: local protocol detection\n\trlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,\n\trnoContent = /^(?:GET|HEAD)$/,\n\trprotocol = /^\\/\\//,\n\n\t/* Prefilters\n\t * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)\n\t * 2) These are called:\n\t *    - BEFORE asking for a transport\n\t *    - AFTER param serialization (s.data is a string if s.processData is true)\n\t * 3) key is the dataType\n\t * 4) the catchall symbol \"*\" can be used\n\t * 5) execution will start with transport dataType and THEN continue down to \"*\" if needed\n\t */\n\tprefilters = {},\n\n\t/* Transports bindings\n\t * 1) key is the dataType\n\t * 2) the catchall symbol \"*\" can be used\n\t * 3) selection will start with transport dataType and THEN go to \"*\" if needed\n\t */\n\ttransports = {},\n\n\t// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression\n\tallTypes = \"*/\".concat( \"*\" ),\n\n\t// Anchor tag for parsing the document origin\n\toriginAnchor = document.createElement( \"a\" );\n\noriginAnchor.href = location.href;\n\n// Base \"constructor\" for jQuery.ajaxPrefilter and jQuery.ajaxTransport\nfunction addToPrefiltersOrTransports( structure ) {\n\n\t// dataTypeExpression is optional and defaults to \"*\"\n\treturn function( dataTypeExpression, func ) {\n\n\t\tif ( typeof dataTypeExpression !== \"string\" ) {\n\t\t\tfunc = dataTypeExpression;\n\t\t\tdataTypeExpression = \"*\";\n\t\t}\n\n\t\tvar dataType,\n\t\t\ti = 0,\n\t\t\tdataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];\n\n\t\tif ( isFunction( func ) ) {\n\n\t\t\t// For each dataType in the dataTypeExpression\n\t\t\twhile ( ( dataType = dataTypes[ i++ ] ) ) {\n\n\t\t\t\t// Prepend if requested\n\t\t\t\tif ( dataType[ 0 ] === \"+\" ) {\n\t\t\t\t\tdataType = dataType.slice( 1 ) || \"*\";\n\t\t\t\t\t( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );\n\n\t\t\t\t// Otherwise append\n\t\t\t\t} else {\n\t\t\t\t\t( structure[ dataType ] = structure[ dataType ] || [] ).push( func );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n// Base inspection function for prefilters and transports\nfunction inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {\n\n\tvar inspected = {},\n\t\tseekingTransport = ( structure === transports );\n\n\tfunction inspect( dataType ) {\n\t\tvar selected;\n\t\tinspected[ dataType ] = true;\n\t\tjQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {\n\t\t\tvar dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );\n\t\t\tif ( typeof dataTypeOrTransport === \"string\" &&\n\t\t\t\t!seekingTransport && !inspected[ dataTypeOrTransport ] ) {\n\n\t\t\t\toptions.dataTypes.unshift( dataTypeOrTransport );\n\t\t\t\tinspect( dataTypeOrTransport );\n\t\t\t\treturn false;\n\t\t\t} else if ( seekingTransport ) {\n\t\t\t\treturn !( selected = dataTypeOrTransport );\n\t\t\t}\n\t\t} );\n\t\treturn selected;\n\t}\n\n\treturn inspect( options.dataTypes[ 0 ] ) || !inspected[ \"*\" ] && inspect( \"*\" );\n}\n\n// A special extend for ajax options\n// that takes \"flat\" options (not to be deep extended)\n// Fixes #9887\nfunction ajaxExtend( target, src ) {\n\tvar key, deep,\n\t\tflatOptions = jQuery.ajaxSettings.flatOptions || {};\n\n\tfor ( key in src ) {\n\t\tif ( src[ key ] !== undefined ) {\n\t\t\t( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];\n\t\t}\n\t}\n\tif ( deep ) {\n\t\tjQuery.extend( true, target, deep );\n\t}\n\n\treturn target;\n}\n\n/* Handles responses to an ajax request:\n * - finds the right dataType (mediates between content-type and expected dataType)\n * - returns the corresponding response\n */\nfunction ajaxHandleResponses( s, jqXHR, responses ) {\n\n\tvar ct, type, finalDataType, firstDataType,\n\t\tcontents = s.contents,\n\t\tdataTypes = s.dataTypes;\n\n\t// Remove auto dataType and get content-type in the process\n\twhile ( dataTypes[ 0 ] === \"*\" ) {\n\t\tdataTypes.shift();\n\t\tif ( ct === undefined ) {\n\t\t\tct = s.mimeType || jqXHR.getResponseHeader( \"Content-Type\" );\n\t\t}\n\t}\n\n\t// Check if we're dealing with a known content-type\n\tif ( ct ) {\n\t\tfor ( type in contents ) {\n\t\t\tif ( contents[ type ] && contents[ type ].test( ct ) ) {\n\t\t\t\tdataTypes.unshift( type );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check to see if we have a response for the expected dataType\n\tif ( dataTypes[ 0 ] in responses ) {\n\t\tfinalDataType = dataTypes[ 0 ];\n\t} else {\n\n\t\t// Try convertible dataTypes\n\t\tfor ( type in responses ) {\n\t\t\tif ( !dataTypes[ 0 ] || s.converters[ type + \" \" + dataTypes[ 0 ] ] ) {\n\t\t\t\tfinalDataType = type;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( !firstDataType ) {\n\t\t\t\tfirstDataType = type;\n\t\t\t}\n\t\t}\n\n\t\t// Or just use first one\n\t\tfinalDataType = finalDataType || firstDataType;\n\t}\n\n\t// If we found a dataType\n\t// We add the dataType to the list if needed\n\t// and return the corresponding response\n\tif ( finalDataType ) {\n\t\tif ( finalDataType !== dataTypes[ 0 ] ) {\n\t\t\tdataTypes.unshift( finalDataType );\n\t\t}\n\t\treturn responses[ finalDataType ];\n\t}\n}\n\n/* Chain conversions given the request and the original response\n * Also sets the responseXXX fields on the jqXHR instance\n */\nfunction ajaxConvert( s, response, jqXHR, isSuccess ) {\n\tvar conv2, current, conv, tmp, prev,\n\t\tconverters = {},\n\n\t\t// Work with a copy of dataTypes in case we need to modify it for conversion\n\t\tdataTypes = s.dataTypes.slice();\n\n\t// Create converters map with lowercased keys\n\tif ( dataTypes[ 1 ] ) {\n\t\tfor ( conv in s.converters ) {\n\t\t\tconverters[ conv.toLowerCase() ] = s.converters[ conv ];\n\t\t}\n\t}\n\n\tcurrent = dataTypes.shift();\n\n\t// Convert to each sequential dataType\n\twhile ( current ) {\n\n\t\tif ( s.responseFields[ current ] ) {\n\t\t\tjqXHR[ s.responseFields[ current ] ] = response;\n\t\t}\n\n\t\t// Apply the dataFilter if provided\n\t\tif ( !prev && isSuccess && s.dataFilter ) {\n\t\t\tresponse = s.dataFilter( response, s.dataType );\n\t\t}\n\n\t\tprev = current;\n\t\tcurrent = dataTypes.shift();\n\n\t\tif ( current ) {\n\n\t\t\t// There's only work to do if current dataType is non-auto\n\t\t\tif ( current === \"*\" ) {\n\n\t\t\t\tcurrent = prev;\n\n\t\t\t// Convert response if prev dataType is non-auto and differs from current\n\t\t\t} else if ( prev !== \"*\" && prev !== current ) {\n\n\t\t\t\t// Seek a direct converter\n\t\t\t\tconv = converters[ prev + \" \" + current ] || converters[ \"* \" + current ];\n\n\t\t\t\t// If none found, seek a pair\n\t\t\t\tif ( !conv ) {\n\t\t\t\t\tfor ( conv2 in converters ) {\n\n\t\t\t\t\t\t// If conv2 outputs current\n\t\t\t\t\t\ttmp = conv2.split( \" \" );\n\t\t\t\t\t\tif ( tmp[ 1 ] === current ) {\n\n\t\t\t\t\t\t\t// If prev can be converted to accepted input\n\t\t\t\t\t\t\tconv = converters[ prev + \" \" + tmp[ 0 ] ] ||\n\t\t\t\t\t\t\t\tconverters[ \"* \" + tmp[ 0 ] ];\n\t\t\t\t\t\t\tif ( conv ) {\n\n\t\t\t\t\t\t\t\t// Condense equivalence converters\n\t\t\t\t\t\t\t\tif ( conv === true ) {\n\t\t\t\t\t\t\t\t\tconv = converters[ conv2 ];\n\n\t\t\t\t\t\t\t\t// Otherwise, insert the intermediate dataType\n\t\t\t\t\t\t\t\t} else if ( converters[ conv2 ] !== true ) {\n\t\t\t\t\t\t\t\t\tcurrent = tmp[ 0 ];\n\t\t\t\t\t\t\t\t\tdataTypes.unshift( tmp[ 1 ] );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Apply converter (if not an equivalence)\n\t\t\t\tif ( conv !== true ) {\n\n\t\t\t\t\t// Unless errors are allowed to bubble, catch and return them\n\t\t\t\t\tif ( conv && s.throws ) {\n\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tstate: \"parsererror\",\n\t\t\t\t\t\t\t\terror: conv ? e : \"No conversion from \" + prev + \" to \" + current\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { state: \"success\", data: response };\n}\n\njQuery.extend( {\n\n\t// Counter for holding the number of active queries\n\tactive: 0,\n\n\t// Last-Modified header cache for next request\n\tlastModified: {},\n\tetag: {},\n\n\tajaxSettings: {\n\t\turl: location.href,\n\t\ttype: \"GET\",\n\t\tisLocal: rlocalProtocol.test( location.protocol ),\n\t\tglobal: true,\n\t\tprocessData: true,\n\t\tasync: true,\n\t\tcontentType: \"application/x-www-form-urlencoded; charset=UTF-8\",\n\n\t\t/*\n\t\ttimeout: 0,\n\t\tdata: null,\n\t\tdataType: null,\n\t\tusername: null,\n\t\tpassword: null,\n\t\tcache: null,\n\t\tthrows: false,\n\t\ttraditional: false,\n\t\theaders: {},\n\t\t*/\n\n\t\taccepts: {\n\t\t\t\"*\": allTypes,\n\t\t\ttext: \"text/plain\",\n\t\t\thtml: \"text/html\",\n\t\t\txml: \"application/xml, text/xml\",\n\t\t\tjson: \"application/json, text/javascript\"\n\t\t},\n\n\t\tcontents: {\n\t\t\txml: /\\bxml\\b/,\n\t\t\thtml: /\\bhtml/,\n\t\t\tjson: /\\bjson\\b/\n\t\t},\n\n\t\tresponseFields: {\n\t\t\txml: \"responseXML\",\n\t\t\ttext: \"responseText\",\n\t\t\tjson: \"responseJSON\"\n\t\t},\n\n\t\t// Data converters\n\t\t// Keys separate source (or catchall \"*\") and destination types with a single space\n\t\tconverters: {\n\n\t\t\t// Convert anything to text\n\t\t\t\"* text\": String,\n\n\t\t\t// Text to html (true = no transformation)\n\t\t\t\"text html\": true,\n\n\t\t\t// Evaluate text as a json expression\n\t\t\t\"text json\": JSON.parse,\n\n\t\t\t// Parse text as xml\n\t\t\t\"text xml\": jQuery.parseXML\n\t\t},\n\n\t\t// For options that shouldn't be deep extended:\n\t\t// you can add your own custom options here if\n\t\t// and when you create one that shouldn't be\n\t\t// deep extended (see ajaxExtend)\n\t\tflatOptions: {\n\t\t\turl: true,\n\t\t\tcontext: true\n\t\t}\n\t},\n\n\t// Creates a full fledged settings object into target\n\t// with both ajaxSettings and settings fields.\n\t// If target is omitted, writes into ajaxSettings.\n\tajaxSetup: function( target, settings ) {\n\t\treturn settings ?\n\n\t\t\t// Building a settings object\n\t\t\tajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :\n\n\t\t\t// Extending ajaxSettings\n\t\t\tajaxExtend( jQuery.ajaxSettings, target );\n\t},\n\n\tajaxPrefilter: addToPrefiltersOrTransports( prefilters ),\n\tajaxTransport: addToPrefiltersOrTransports( transports ),\n\n\t// Main method\n\tajax: function( url, options ) {\n\n\t\t// If url is an object, simulate pre-1.5 signature\n\t\tif ( typeof url === \"object\" ) {\n\t\t\toptions = url;\n\t\t\turl = undefined;\n\t\t}\n\n\t\t// Force options to be an object\n\t\toptions = options || {};\n\n\t\tvar transport,\n\n\t\t\t// URL without anti-cache param\n\t\t\tcacheURL,\n\n\t\t\t// Response headers\n\t\t\tresponseHeadersString,\n\t\t\tresponseHeaders,\n\n\t\t\t// timeout handle\n\t\t\ttimeoutTimer,\n\n\t\t\t// Url cleanup var\n\t\t\turlAnchor,\n\n\t\t\t// Request state (becomes false upon send and true upon completion)\n\t\t\tcompleted,\n\n\t\t\t// To know if global events are to be dispatched\n\t\t\tfireGlobals,\n\n\t\t\t// Loop variable\n\t\t\ti,\n\n\t\t\t// uncached part of the url\n\t\t\tuncached,\n\n\t\t\t// Create the final options object\n\t\t\ts = jQuery.ajaxSetup( {}, options ),\n\n\t\t\t// Callbacks context\n\t\t\tcallbackContext = s.context || s,\n\n\t\t\t// Context for global events is callbackContext if it is a DOM node or jQuery collection\n\t\t\tglobalEventContext = s.context &&\n\t\t\t\t( callbackContext.nodeType || callbackContext.jquery ) ?\n\t\t\t\tjQuery( callbackContext ) :\n\t\t\t\tjQuery.event,\n\n\t\t\t// Deferreds\n\t\t\tdeferred = jQuery.Deferred(),\n\t\t\tcompleteDeferred = jQuery.Callbacks( \"once memory\" ),\n\n\t\t\t// Status-dependent callbacks\n\t\t\tstatusCode = s.statusCode || {},\n\n\t\t\t// Headers (they are sent all at once)\n\t\t\trequestHeaders = {},\n\t\t\trequestHeadersNames = {},\n\n\t\t\t// Default abort message\n\t\t\tstrAbort = \"canceled\",\n\n\t\t\t// Fake xhr\n\t\t\tjqXHR = {\n\t\t\t\treadyState: 0,\n\n\t\t\t\t// Builds headers hashtable if needed\n\t\t\t\tgetResponseHeader: function( key ) {\n\t\t\t\t\tvar match;\n\t\t\t\t\tif ( completed ) {\n\t\t\t\t\t\tif ( !responseHeaders ) {\n\t\t\t\t\t\t\tresponseHeaders = {};\n\t\t\t\t\t\t\twhile ( ( match = rheaders.exec( responseHeadersString ) ) ) {\n\t\t\t\t\t\t\t\tresponseHeaders[ match[ 1 ].toLowerCase() + \" \" ] =\n\t\t\t\t\t\t\t\t\t( responseHeaders[ match[ 1 ].toLowerCase() + \" \" ] || [] )\n\t\t\t\t\t\t\t\t\t\t.concat( match[ 2 ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmatch = responseHeaders[ key.toLowerCase() + \" \" ];\n\t\t\t\t\t}\n\t\t\t\t\treturn match == null ? null : match.join( \", \" );\n\t\t\t\t},\n\n\t\t\t\t// Raw string\n\t\t\t\tgetAllResponseHeaders: function() {\n\t\t\t\t\treturn completed ? responseHeadersString : null;\n\t\t\t\t},\n\n\t\t\t\t// Caches the header\n\t\t\t\tsetRequestHeader: function( name, value ) {\n\t\t\t\t\tif ( completed == null ) {\n\t\t\t\t\t\tname = requestHeadersNames[ name.toLowerCase() ] =\n\t\t\t\t\t\t\trequestHeadersNames[ name.toLowerCase() ] || name;\n\t\t\t\t\t\trequestHeaders[ name ] = value;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Overrides response content-type header\n\t\t\t\toverrideMimeType: function( type ) {\n\t\t\t\t\tif ( completed == null ) {\n\t\t\t\t\t\ts.mimeType = type;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Status-dependent callbacks\n\t\t\t\tstatusCode: function( map ) {\n\t\t\t\t\tvar code;\n\t\t\t\t\tif ( map ) {\n\t\t\t\t\t\tif ( completed ) {\n\n\t\t\t\t\t\t\t// Execute the appropriate callbacks\n\t\t\t\t\t\t\tjqXHR.always( map[ jqXHR.status ] );\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// Lazy-add the new callbacks in a way that preserves old ones\n\t\t\t\t\t\t\tfor ( code in map ) {\n\t\t\t\t\t\t\t\tstatusCode[ code ] = [ statusCode[ code ], map[ code ] ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Cancel the request\n\t\t\t\tabort: function( statusText ) {\n\t\t\t\t\tvar finalText = statusText || strAbort;\n\t\t\t\t\tif ( transport ) {\n\t\t\t\t\t\ttransport.abort( finalText );\n\t\t\t\t\t}\n\t\t\t\t\tdone( 0, finalText );\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\n\t\t// Attach deferreds\n\t\tdeferred.promise( jqXHR );\n\n\t\t// Add protocol if not provided (prefilters might expect it)\n\t\t// Handle falsy url in the settings object (#10093: consistency with old signature)\n\t\t// We also use the url parameter if available\n\t\ts.url = ( ( url || s.url || location.href ) + \"\" )\n\t\t\t.replace( rprotocol, location.protocol + \"//\" );\n\n\t\t// Alias method option to type as per ticket #12004\n\t\ts.type = options.method || options.type || s.method || s.type;\n\n\t\t// Extract dataTypes list\n\t\ts.dataTypes = ( s.dataType || \"*\" ).toLowerCase().match( rnothtmlwhite ) || [ \"\" ];\n\n\t\t// A cross-domain request is in order when the origin doesn't match the current origin.\n\t\tif ( s.crossDomain == null ) {\n\t\t\turlAnchor = document.createElement( \"a\" );\n\n\t\t\t// Support: IE <=8 - 11, Edge 12 - 15\n\t\t\t// IE throws exception on accessing the href property if url is malformed,\n\t\t\t// e.g. http://example.com:80x/\n\t\t\ttry {\n\t\t\t\turlAnchor.href = s.url;\n\n\t\t\t\t// Support: IE <=8 - 11 only\n\t\t\t\t// Anchor's host property isn't correctly set when s.url is relative\n\t\t\t\turlAnchor.href = urlAnchor.href;\n\t\t\t\ts.crossDomain = originAnchor.protocol + \"//\" + originAnchor.host !==\n\t\t\t\t\turlAnchor.protocol + \"//\" + urlAnchor.host;\n\t\t\t} catch ( e ) {\n\n\t\t\t\t// If there is an error parsing the URL, assume it is crossDomain,\n\t\t\t\t// it can be rejected by the transport if it is invalid\n\t\t\t\ts.crossDomain = true;\n\t\t\t}\n\t\t}\n\n\t\t// Convert data if not already a string\n\t\tif ( s.data && s.processData && typeof s.data !== \"string\" ) {\n\t\t\ts.data = jQuery.param( s.data, s.traditional );\n\t\t}\n\n\t\t// Apply prefilters\n\t\tinspectPrefiltersOrTransports( prefilters, s, options, jqXHR );\n\n\t\t// If request was aborted inside a prefilter, stop there\n\t\tif ( completed ) {\n\t\t\treturn jqXHR;\n\t\t}\n\n\t\t// We can fire global events as of now if asked to\n\t\t// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)\n\t\tfireGlobals = jQuery.event && s.global;\n\n\t\t// Watch for a new set of requests\n\t\tif ( fireGlobals && jQuery.active++ === 0 ) {\n\t\t\tjQuery.event.trigger( \"ajaxStart\" );\n\t\t}\n\n\t\t// Uppercase the type\n\t\ts.type = s.type.toUpperCase();\n\n\t\t// Determine if request has content\n\t\ts.hasContent = !rnoContent.test( s.type );\n\n\t\t// Save the URL in case we're toying with the If-Modified-Since\n\t\t// and/or If-None-Match header later on\n\t\t// Remove hash to simplify url manipulation\n\t\tcacheURL = s.url.replace( rhash, \"\" );\n\n\t\t// More options handling for requests with no content\n\t\tif ( !s.hasContent ) {\n\n\t\t\t// Remember the hash so we can put it back\n\t\t\tuncached = s.url.slice( cacheURL.length );\n\n\t\t\t// If data is available and should be processed, append data to url\n\t\t\tif ( s.data && ( s.processData || typeof s.data === \"string\" ) ) {\n\t\t\t\tcacheURL += ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + s.data;\n\n\t\t\t\t// #9682: remove data so that it's not used in an eventual retry\n\t\t\t\tdelete s.data;\n\t\t\t}\n\n\t\t\t// Add or update anti-cache param if needed\n\t\t\tif ( s.cache === false ) {\n\t\t\t\tcacheURL = cacheURL.replace( rantiCache, \"$1\" );\n\t\t\t\tuncached = ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + \"_=\" + ( nonce.guid++ ) +\n\t\t\t\t\tuncached;\n\t\t\t}\n\n\t\t\t// Put hash and anti-cache on the URL that will be requested (gh-1732)\n\t\t\ts.url = cacheURL + uncached;\n\n\t\t// Change '%20' to '+' if this is encoded form body content (gh-2658)\n\t\t} else if ( s.data && s.processData &&\n\t\t\t( s.contentType || \"\" ).indexOf( \"application/x-www-form-urlencoded\" ) === 0 ) {\n\t\t\ts.data = s.data.replace( r20, \"+\" );\n\t\t}\n\n\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\tif ( s.ifModified ) {\n\t\t\tif ( jQuery.lastModified[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-Modified-Since\", jQuery.lastModified[ cacheURL ] );\n\t\t\t}\n\t\t\tif ( jQuery.etag[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-None-Match\", jQuery.etag[ cacheURL ] );\n\t\t\t}\n\t\t}\n\n\t\t// Set the correct header, if data is being sent\n\t\tif ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {\n\t\t\tjqXHR.setRequestHeader( \"Content-Type\", s.contentType );\n\t\t}\n\n\t\t// Set the Accepts header for the server, depending on the dataType\n\t\tjqXHR.setRequestHeader(\n\t\t\t\"Accept\",\n\t\t\ts.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?\n\t\t\t\ts.accepts[ s.dataTypes[ 0 ] ] +\n\t\t\t\t\t( s.dataTypes[ 0 ] !== \"*\" ? \", \" + allTypes + \"; q=0.01\" : \"\" ) :\n\t\t\t\ts.accepts[ \"*\" ]\n\t\t);\n\n\t\t// Check for headers option\n\t\tfor ( i in s.headers ) {\n\t\t\tjqXHR.setRequestHeader( i, s.headers[ i ] );\n\t\t}\n\n\t\t// Allow custom headers/mimetypes and early abort\n\t\tif ( s.beforeSend &&\n\t\t\t( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {\n\n\t\t\t// Abort if not done already and return\n\t\t\treturn jqXHR.abort();\n\t\t}\n\n\t\t// Aborting is no longer a cancellation\n\t\tstrAbort = \"abort\";\n\n\t\t// Install callbacks on deferreds\n\t\tcompleteDeferred.add( s.complete );\n\t\tjqXHR.done( s.success );\n\t\tjqXHR.fail( s.error );\n\n\t\t// Get transport\n\t\ttransport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );\n\n\t\t// If no transport, we auto-abort\n\t\tif ( !transport ) {\n\t\t\tdone( -1, \"No Transport\" );\n\t\t} else {\n\t\t\tjqXHR.readyState = 1;\n\n\t\t\t// Send global event\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxSend\", [ jqXHR, s ] );\n\t\t\t}\n\n\t\t\t// If request was aborted inside ajaxSend, stop there\n\t\t\tif ( completed ) {\n\t\t\t\treturn jqXHR;\n\t\t\t}\n\n\t\t\t// Timeout\n\t\t\tif ( s.async && s.timeout > 0 ) {\n\t\t\t\ttimeoutTimer = window.setTimeout( function() {\n\t\t\t\t\tjqXHR.abort( \"timeout\" );\n\t\t\t\t}, s.timeout );\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tcompleted = false;\n\t\t\t\ttransport.send( requestHeaders, done );\n\t\t\t} catch ( e ) {\n\n\t\t\t\t// Rethrow post-completion exceptions\n\t\t\t\tif ( completed ) {\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\n\t\t\t\t// Propagate others as results\n\t\t\t\tdone( -1, e );\n\t\t\t}\n\t\t}\n\n\t\t// Callback for when everything is done\n\t\tfunction done( status, nativeStatusText, responses, headers ) {\n\t\t\tvar isSuccess, success, error, response, modified,\n\t\t\t\tstatusText = nativeStatusText;\n\n\t\t\t// Ignore repeat invocations\n\t\t\tif ( completed ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tcompleted = true;\n\n\t\t\t// Clear timeout if it exists\n\t\t\tif ( timeoutTimer ) {\n\t\t\t\twindow.clearTimeout( timeoutTimer );\n\t\t\t}\n\n\t\t\t// Dereference transport for early garbage collection\n\t\t\t// (no matter how long the jqXHR object will be used)\n\t\t\ttransport = undefined;\n\n\t\t\t// Cache response headers\n\t\t\tresponseHeadersString = headers || \"\";\n\n\t\t\t// Set readyState\n\t\t\tjqXHR.readyState = status > 0 ? 4 : 0;\n\n\t\t\t// Determine if successful\n\t\t\tisSuccess = status >= 200 && status < 300 || status === 304;\n\n\t\t\t// Get response data\n\t\t\tif ( responses ) {\n\t\t\t\tresponse = ajaxHandleResponses( s, jqXHR, responses );\n\t\t\t}\n\n\t\t\t// Use a noop converter for missing script but not if jsonp\n\t\t\tif ( !isSuccess &&\n\t\t\t\tjQuery.inArray( \"script\", s.dataTypes ) > -1 &&\n\t\t\t\tjQuery.inArray( \"json\", s.dataTypes ) < 0 ) {\n\t\t\t\ts.converters[ \"text script\" ] = function() {};\n\t\t\t}\n\n\t\t\t// Convert no matter what (that way responseXXX fields are always set)\n\t\t\tresponse = ajaxConvert( s, response, jqXHR, isSuccess );\n\n\t\t\t// If successful, handle type chaining\n\t\t\tif ( isSuccess ) {\n\n\t\t\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\t\t\tif ( s.ifModified ) {\n\t\t\t\t\tmodified = jqXHR.getResponseHeader( \"Last-Modified\" );\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.lastModified[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t\tmodified = jqXHR.getResponseHeader( \"etag\" );\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.etag[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// if no content\n\t\t\t\tif ( status === 204 || s.type === \"HEAD\" ) {\n\t\t\t\t\tstatusText = \"nocontent\";\n\n\t\t\t\t// if not modified\n\t\t\t\t} else if ( status === 304 ) {\n\t\t\t\t\tstatusText = \"notmodified\";\n\n\t\t\t\t// If we have data, let's convert it\n\t\t\t\t} else {\n\t\t\t\t\tstatusText = response.state;\n\t\t\t\t\tsuccess = response.data;\n\t\t\t\t\terror = response.error;\n\t\t\t\t\tisSuccess = !error;\n\t\t\t\t}\n\t\t\t} else {\n\n\t\t\t\t// Extract error from statusText and normalize for non-aborts\n\t\t\t\terror = statusText;\n\t\t\t\tif ( status || !statusText ) {\n\t\t\t\t\tstatusText = \"error\";\n\t\t\t\t\tif ( status < 0 ) {\n\t\t\t\t\t\tstatus = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set data for the fake xhr object\n\t\t\tjqXHR.status = status;\n\t\t\tjqXHR.statusText = ( nativeStatusText || statusText ) + \"\";\n\n\t\t\t// Success/Error\n\t\t\tif ( isSuccess ) {\n\t\t\t\tdeferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );\n\t\t\t} else {\n\t\t\t\tdeferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );\n\t\t\t}\n\n\t\t\t// Status-dependent callbacks\n\t\t\tjqXHR.statusCode( statusCode );\n\t\t\tstatusCode = undefined;\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( isSuccess ? \"ajaxSuccess\" : \"ajaxError\",\n\t\t\t\t\t[ jqXHR, s, isSuccess ? success : error ] );\n\t\t\t}\n\n\t\t\t// Complete\n\t\t\tcompleteDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxComplete\", [ jqXHR, s ] );\n\n\t\t\t\t// Handle the global AJAX counter\n\t\t\t\tif ( !( --jQuery.active ) ) {\n\t\t\t\t\tjQuery.event.trigger( \"ajaxStop\" );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jqXHR;\n\t},\n\n\tgetJSON: function( url, data, callback ) {\n\t\treturn jQuery.get( url, data, callback, \"json\" );\n\t},\n\n\tgetScript: function( url, callback ) {\n\t\treturn jQuery.get( url, undefined, callback, \"script\" );\n\t}\n} );\n\njQuery.each( [ \"get\", \"post\" ], function( _i, method ) {\n\tjQuery[ method ] = function( url, data, callback, type ) {\n\n\t\t// Shift arguments if data argument was omitted\n\t\tif ( isFunction( data ) ) {\n\t\t\ttype = type || callback;\n\t\t\tcallback = data;\n\t\t\tdata = undefined;\n\t\t}\n\n\t\t// The url can be an options object (which then must have .url)\n\t\treturn jQuery.ajax( jQuery.extend( {\n\t\t\turl: url,\n\t\t\ttype: method,\n\t\t\tdataType: type,\n\t\t\tdata: data,\n\t\t\tsuccess: callback\n\t\t}, jQuery.isPlainObject( url ) && url ) );\n\t};\n} );\n\njQuery.ajaxPrefilter( function( s ) {\n\tvar i;\n\tfor ( i in s.headers ) {\n\t\tif ( i.toLowerCase() === \"content-type\" ) {\n\t\t\ts.contentType = s.headers[ i ] || \"\";\n\t\t}\n\t}\n} );\n\n\njQuery._evalUrl = function( url, options, doc ) {\n\treturn jQuery.ajax( {\n\t\turl: url,\n\n\t\t// Make this explicit, since user can override this through ajaxSetup (#11264)\n\t\ttype: \"GET\",\n\t\tdataType: \"script\",\n\t\tcache: true,\n\t\tasync: false,\n\t\tglobal: false,\n\n\t\t// Only evaluate the response if it is successful (gh-4126)\n\t\t// dataFilter is not invoked for failure responses, so using it instead\n\t\t// of the default converter is kludgy but it works.\n\t\tconverters: {\n\t\t\t\"text script\": function() {}\n\t\t},\n\t\tdataFilter: function( response ) {\n\t\t\tjQuery.globalEval( response, options, doc );\n\t\t}\n\t} );\n};\n\n\njQuery.fn.extend( {\n\twrapAll: function( html ) {\n\t\tvar wrap;\n\n\t\tif ( this[ 0 ] ) {\n\t\t\tif ( isFunction( html ) ) {\n\t\t\t\thtml = html.call( this[ 0 ] );\n\t\t\t}\n\n\t\t\t// The elements to wrap the target around\n\t\t\twrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );\n\n\t\t\tif ( this[ 0 ].parentNode ) {\n\t\t\t\twrap.insertBefore( this[ 0 ] );\n\t\t\t}\n\n\t\t\twrap.map( function() {\n\t\t\t\tvar elem = this;\n\n\t\t\t\twhile ( elem.firstElementChild ) {\n\t\t\t\t\telem = elem.firstElementChild;\n\t\t\t\t}\n\n\t\t\t\treturn elem;\n\t\t\t} ).append( this );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\twrapInner: function( html ) {\n\t\tif ( isFunction( html ) ) {\n\t\t\treturn this.each( function( i ) {\n\t\t\t\tjQuery( this ).wrapInner( html.call( this, i ) );\n\t\t\t} );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar self = jQuery( this ),\n\t\t\t\tcontents = self.contents();\n\n\t\t\tif ( contents.length ) {\n\t\t\t\tcontents.wrapAll( html );\n\n\t\t\t} else {\n\t\t\t\tself.append( html );\n\t\t\t}\n\t\t} );\n\t},\n\n\twrap: function( html ) {\n\t\tvar htmlIsFunction = isFunction( html );\n\n\t\treturn this.each( function( i ) {\n\t\t\tjQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html );\n\t\t} );\n\t},\n\n\tunwrap: function( selector ) {\n\t\tthis.parent( selector ).not( \"body\" ).each( function() {\n\t\t\tjQuery( this ).replaceWith( this.childNodes );\n\t\t} );\n\t\treturn this;\n\t}\n} );\n\n\njQuery.expr.pseudos.hidden = function( elem ) {\n\treturn !jQuery.expr.pseudos.visible( elem );\n};\njQuery.expr.pseudos.visible = function( elem ) {\n\treturn !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );\n};\n\n\n\n\njQuery.ajaxSettings.xhr = function() {\n\ttry {\n\t\treturn new window.XMLHttpRequest();\n\t} catch ( e ) {}\n};\n\nvar xhrSuccessStatus = {\n\n\t\t// File protocol always yields status code 0, assume 200\n\t\t0: 200,\n\n\t\t// Support: IE <=9 only\n\t\t// #1450: sometimes IE returns 1223 when it should be 204\n\t\t1223: 204\n\t},\n\txhrSupported = jQuery.ajaxSettings.xhr();\n\nsupport.cors = !!xhrSupported && ( \"withCredentials\" in xhrSupported );\nsupport.ajax = xhrSupported = !!xhrSupported;\n\njQuery.ajaxTransport( function( options ) {\n\tvar callback, errorCallback;\n\n\t// Cross domain only allowed if supported through XMLHttpRequest\n\tif ( support.cors || xhrSupported && !options.crossDomain ) {\n\t\treturn {\n\t\t\tsend: function( headers, complete ) {\n\t\t\t\tvar i,\n\t\t\t\t\txhr = options.xhr();\n\n\t\t\t\txhr.open(\n\t\t\t\t\toptions.type,\n\t\t\t\t\toptions.url,\n\t\t\t\t\toptions.async,\n\t\t\t\t\toptions.username,\n\t\t\t\t\toptions.password\n\t\t\t\t);\n\n\t\t\t\t// Apply custom fields if provided\n\t\t\t\tif ( options.xhrFields ) {\n\t\t\t\t\tfor ( i in options.xhrFields ) {\n\t\t\t\t\t\txhr[ i ] = options.xhrFields[ i ];\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Override mime type if needed\n\t\t\t\tif ( options.mimeType && xhr.overrideMimeType ) {\n\t\t\t\t\txhr.overrideMimeType( options.mimeType );\n\t\t\t\t}\n\n\t\t\t\t// X-Requested-With header\n\t\t\t\t// For cross-domain requests, seeing as conditions for a preflight are\n\t\t\t\t// akin to a jigsaw puzzle, we simply never set it to be sure.\n\t\t\t\t// (it can always be set on a per-request basis or even using ajaxSetup)\n\t\t\t\t// For same-domain requests, won't change header if already provided.\n\t\t\t\tif ( !options.crossDomain && !headers[ \"X-Requested-With\" ] ) {\n\t\t\t\t\theaders[ \"X-Requested-With\" ] = \"XMLHttpRequest\";\n\t\t\t\t}\n\n\t\t\t\t// Set headers\n\t\t\t\tfor ( i in headers ) {\n\t\t\t\t\txhr.setRequestHeader( i, headers[ i ] );\n\t\t\t\t}\n\n\t\t\t\t// Callback\n\t\t\t\tcallback = function( type ) {\n\t\t\t\t\treturn function() {\n\t\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\t\tcallback = errorCallback = xhr.onload =\n\t\t\t\t\t\t\t\txhr.onerror = xhr.onabort = xhr.ontimeout =\n\t\t\t\t\t\t\t\t\txhr.onreadystatechange = null;\n\n\t\t\t\t\t\t\tif ( type === \"abort\" ) {\n\t\t\t\t\t\t\t\txhr.abort();\n\t\t\t\t\t\t\t} else if ( type === \"error\" ) {\n\n\t\t\t\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t\t\t\t// On a manual native abort, IE9 throws\n\t\t\t\t\t\t\t\t// errors on any property access that is not readyState\n\t\t\t\t\t\t\t\tif ( typeof xhr.status !== \"number\" ) {\n\t\t\t\t\t\t\t\t\tcomplete( 0, \"error\" );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tcomplete(\n\n\t\t\t\t\t\t\t\t\t\t// File: protocol always yields status 0; see #8605, #14207\n\t\t\t\t\t\t\t\t\t\txhr.status,\n\t\t\t\t\t\t\t\t\t\txhr.statusText\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tcomplete(\n\t\t\t\t\t\t\t\t\txhrSuccessStatus[ xhr.status ] || xhr.status,\n\t\t\t\t\t\t\t\t\txhr.statusText,\n\n\t\t\t\t\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t\t\t\t\t// IE9 has no XHR2 but throws on binary (trac-11426)\n\t\t\t\t\t\t\t\t\t// For XHR2 non-text, let the caller handle it (gh-2498)\n\t\t\t\t\t\t\t\t\t( xhr.responseType || \"text\" ) !== \"text\"  ||\n\t\t\t\t\t\t\t\t\ttypeof xhr.responseText !== \"string\" ?\n\t\t\t\t\t\t\t\t\t\t{ binary: xhr.response } :\n\t\t\t\t\t\t\t\t\t\t{ text: xhr.responseText },\n\t\t\t\t\t\t\t\t\txhr.getAllResponseHeaders()\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t};\n\n\t\t\t\t// Listen to events\n\t\t\t\txhr.onload = callback();\n\t\t\t\terrorCallback = xhr.onerror = xhr.ontimeout = callback( \"error\" );\n\n\t\t\t\t// Support: IE 9 only\n\t\t\t\t// Use onreadystatechange to replace onabort\n\t\t\t\t// to handle uncaught aborts\n\t\t\t\tif ( xhr.onabort !== undefined ) {\n\t\t\t\t\txhr.onabort = errorCallback;\n\t\t\t\t} else {\n\t\t\t\t\txhr.onreadystatechange = function() {\n\n\t\t\t\t\t\t// Check readyState before timeout as it changes\n\t\t\t\t\t\tif ( xhr.readyState === 4 ) {\n\n\t\t\t\t\t\t\t// Allow onerror to be called first,\n\t\t\t\t\t\t\t// but that will not handle a native abort\n\t\t\t\t\t\t\t// Also, save errorCallback to a variable\n\t\t\t\t\t\t\t// as xhr.onerror cannot be accessed\n\t\t\t\t\t\t\twindow.setTimeout( function() {\n\t\t\t\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\t\t\t\terrorCallback();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\t// Create the abort callback\n\t\t\t\tcallback = callback( \"abort\" );\n\n\t\t\t\ttry {\n\n\t\t\t\t\t// Do send the request (this may raise an exception)\n\t\t\t\t\txhr.send( options.hasContent && options.data || null );\n\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\t// #14683: Only rethrow if this hasn't been notified as an error yet\n\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\tthrow e;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n} );\n\n\n\n\n// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)\njQuery.ajaxPrefilter( function( s ) {\n\tif ( s.crossDomain ) {\n\t\ts.contents.script = false;\n\t}\n} );\n\n// Install script dataType\njQuery.ajaxSetup( {\n\taccepts: {\n\t\tscript: \"text/javascript, application/javascript, \" +\n\t\t\t\"application/ecmascript, application/x-ecmascript\"\n\t},\n\tcontents: {\n\t\tscript: /\\b(?:java|ecma)script\\b/\n\t},\n\tconverters: {\n\t\t\"text script\": function( text ) {\n\t\t\tjQuery.globalEval( text );\n\t\t\treturn text;\n\t\t}\n\t}\n} );\n\n// Handle cache's special case and crossDomain\njQuery.ajaxPrefilter( \"script\", function( s ) {\n\tif ( s.cache === undefined ) {\n\t\ts.cache = false;\n\t}\n\tif ( s.crossDomain ) {\n\t\ts.type = \"GET\";\n\t}\n} );\n\n// Bind script tag hack transport\njQuery.ajaxTransport( \"script\", function( s ) {\n\n\t// This transport only deals with cross domain or forced-by-attrs requests\n\tif ( s.crossDomain || s.scriptAttrs ) {\n\t\tvar script, callback;\n\t\treturn {\n\t\t\tsend: function( _, complete ) {\n\t\t\t\tscript = jQuery( \"<script>\" )\n\t\t\t\t\t.attr( s.scriptAttrs || {} )\n\t\t\t\t\t.prop( { charset: s.scriptCharset, src: s.url } )\n\t\t\t\t\t.on( \"load error\", callback = function( evt ) {\n\t\t\t\t\t\tscript.remove();\n\t\t\t\t\t\tcallback = null;\n\t\t\t\t\t\tif ( evt ) {\n\t\t\t\t\t\t\tcomplete( evt.type === \"error\" ? 404 : 200, evt.type );\n\t\t\t\t\t\t}\n\t\t\t\t\t} );\n\n\t\t\t\t// Use native DOM manipulation to avoid our domManip AJAX trickery\n\t\t\t\tdocument.head.appendChild( script[ 0 ] );\n\t\t\t},\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n} );\n\n\n\n\nvar oldCallbacks = [],\n\trjsonp = /(=)\\?(?=&|$)|\\?\\?/;\n\n// Default jsonp settings\njQuery.ajaxSetup( {\n\tjsonp: \"callback\",\n\tjsonpCallback: function() {\n\t\tvar callback = oldCallbacks.pop() || ( jQuery.expando + \"_\" + ( nonce.guid++ ) );\n\t\tthis[ callback ] = true;\n\t\treturn callback;\n\t}\n} );\n\n// Detect, normalize options and install callbacks for jsonp requests\njQuery.ajaxPrefilter( \"json jsonp\", function( s, originalSettings, jqXHR ) {\n\n\tvar callbackName, overwritten, responseContainer,\n\t\tjsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?\n\t\t\t\"url\" :\n\t\t\ttypeof s.data === \"string\" &&\n\t\t\t\t( s.contentType || \"\" )\n\t\t\t\t\t.indexOf( \"application/x-www-form-urlencoded\" ) === 0 &&\n\t\t\t\trjsonp.test( s.data ) && \"data\"\n\t\t);\n\n\t// Handle iff the expected data type is \"jsonp\" or we have a parameter to set\n\tif ( jsonProp || s.dataTypes[ 0 ] === \"jsonp\" ) {\n\n\t\t// Get callback name, remembering preexisting value associated with it\n\t\tcallbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ?\n\t\t\ts.jsonpCallback() :\n\t\t\ts.jsonpCallback;\n\n\t\t// Insert callback into url or form data\n\t\tif ( jsonProp ) {\n\t\t\ts[ jsonProp ] = s[ jsonProp ].replace( rjsonp, \"$1\" + callbackName );\n\t\t} else if ( s.jsonp !== false ) {\n\t\t\ts.url += ( rquery.test( s.url ) ? \"&\" : \"?\" ) + s.jsonp + \"=\" + callbackName;\n\t\t}\n\n\t\t// Use data converter to retrieve json after script execution\n\t\ts.converters[ \"script json\" ] = function() {\n\t\t\tif ( !responseContainer ) {\n\t\t\t\tjQuery.error( callbackName + \" was not called\" );\n\t\t\t}\n\t\t\treturn responseContainer[ 0 ];\n\t\t};\n\n\t\t// Force json dataType\n\t\ts.dataTypes[ 0 ] = \"json\";\n\n\t\t// Install callback\n\t\toverwritten = window[ callbackName ];\n\t\twindow[ callbackName ] = function() {\n\t\t\tresponseContainer = arguments;\n\t\t};\n\n\t\t// Clean-up function (fires after converters)\n\t\tjqXHR.always( function() {\n\n\t\t\t// If previous value didn't exist - remove it\n\t\t\tif ( overwritten === undefined ) {\n\t\t\t\tjQuery( window ).removeProp( callbackName );\n\n\t\t\t// Otherwise restore preexisting value\n\t\t\t} else {\n\t\t\t\twindow[ callbackName ] = overwritten;\n\t\t\t}\n\n\t\t\t// Save back as free\n\t\t\tif ( s[ callbackName ] ) {\n\n\t\t\t\t// Make sure that re-using the options doesn't screw things around\n\t\t\t\ts.jsonpCallback = originalSettings.jsonpCallback;\n\n\t\t\t\t// Save the callback name for future use\n\t\t\t\toldCallbacks.push( callbackName );\n\t\t\t}\n\n\t\t\t// Call if it was a function and we have a response\n\t\t\tif ( responseContainer && isFunction( overwritten ) ) {\n\t\t\t\toverwritten( responseContainer[ 0 ] );\n\t\t\t}\n\n\t\t\tresponseContainer = overwritten = undefined;\n\t\t} );\n\n\t\t// Delegate to script\n\t\treturn \"script\";\n\t}\n} );\n\n\n\n\n// Support: Safari 8 only\n// In Safari 8 documents created via document.implementation.createHTMLDocument\n// collapse sibling forms: the second one becomes a child of the first one.\n// Because of that, this security measure has to be disabled in Safari 8.\n// https://bugs.webkit.org/show_bug.cgi?id=137337\nsupport.createHTMLDocument = ( function() {\n\tvar body = document.implementation.createHTMLDocument( \"\" ).body;\n\tbody.innerHTML = \"<form></form><form></form>\";\n\treturn body.childNodes.length === 2;\n} )();\n\n\n// Argument \"data\" should be string of html\n// context (optional): If specified, the fragment will be created in this context,\n// defaults to document\n// keepScripts (optional): If true, will include scripts passed in the html string\njQuery.parseHTML = function( data, context, keepScripts ) {\n\tif ( typeof data !== \"string\" ) {\n\t\treturn [];\n\t}\n\tif ( typeof context === \"boolean\" ) {\n\t\tkeepScripts = context;\n\t\tcontext = false;\n\t}\n\n\tvar base, parsed, scripts;\n\n\tif ( !context ) {\n\n\t\t// Stop scripts or inline event handlers from being executed immediately\n\t\t// by using document.implementation\n\t\tif ( support.createHTMLDocument ) {\n\t\t\tcontext = document.implementation.createHTMLDocument( \"\" );\n\n\t\t\t// Set the base href for the created document\n\t\t\t// so any parsed elements with URLs\n\t\t\t// are based on the document's URL (gh-2965)\n\t\t\tbase = context.createElement( \"base\" );\n\t\t\tbase.href = document.location.href;\n\t\t\tcontext.head.appendChild( base );\n\t\t} else {\n\t\t\tcontext = document;\n\t\t}\n\t}\n\n\tparsed = rsingleTag.exec( data );\n\tscripts = !keepScripts && [];\n\n\t// Single tag\n\tif ( parsed ) {\n\t\treturn [ context.createElement( parsed[ 1 ] ) ];\n\t}\n\n\tparsed = buildFragment( [ data ], context, scripts );\n\n\tif ( scripts && scripts.length ) {\n\t\tjQuery( scripts ).remove();\n\t}\n\n\treturn jQuery.merge( [], parsed.childNodes );\n};\n\n\n/**\n * Load a url into a page\n */\njQuery.fn.load = function( url, params, callback ) {\n\tvar selector, type, response,\n\t\tself = this,\n\t\toff = url.indexOf( \" \" );\n\n\tif ( off > -1 ) {\n\t\tselector = stripAndCollapse( url.slice( off ) );\n\t\turl = url.slice( 0, off );\n\t}\n\n\t// If it's a function\n\tif ( isFunction( params ) ) {\n\n\t\t// We assume that it's the callback\n\t\tcallback = params;\n\t\tparams = undefined;\n\n\t// Otherwise, build a param string\n\t} else if ( params && typeof params === \"object\" ) {\n\t\ttype = \"POST\";\n\t}\n\n\t// If we have elements to modify, make the request\n\tif ( self.length > 0 ) {\n\t\tjQuery.ajax( {\n\t\t\turl: url,\n\n\t\t\t// If \"type\" variable is undefined, then \"GET\" method will be used.\n\t\t\t// Make value of this field explicit since\n\t\t\t// user can override it through ajaxSetup method\n\t\t\ttype: type || \"GET\",\n\t\t\tdataType: \"html\",\n\t\t\tdata: params\n\t\t} ).done( function( responseText ) {\n\n\t\t\t// Save response for use in complete callback\n\t\t\tresponse = arguments;\n\n\t\t\tself.html( selector ?\n\n\t\t\t\t// If a selector was specified, locate the right elements in a dummy div\n\t\t\t\t// Exclude scripts to avoid IE 'Permission Denied' errors\n\t\t\t\tjQuery( \"<div>\" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :\n\n\t\t\t\t// Otherwise use the full result\n\t\t\t\tresponseText );\n\n\t\t// If the request succeeds, this function gets \"data\", \"status\", \"jqXHR\"\n\t\t// but they are ignored because response was set above.\n\t\t// If it fails, this function gets \"jqXHR\", \"status\", \"error\"\n\t\t} ).always( callback && function( jqXHR, status ) {\n\t\t\tself.each( function() {\n\t\t\t\tcallback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );\n\t\t\t} );\n\t\t} );\n\t}\n\n\treturn this;\n};\n\n\n\n\njQuery.expr.pseudos.animated = function( elem ) {\n\treturn jQuery.grep( jQuery.timers, function( fn ) {\n\t\treturn elem === fn.elem;\n\t} ).length;\n};\n\n\n\n\njQuery.offset = {\n\tsetOffset: function( elem, options, i ) {\n\t\tvar curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,\n\t\t\tposition = jQuery.css( elem, \"position\" ),\n\t\t\tcurElem = jQuery( elem ),\n\t\t\tprops = {};\n\n\t\t// Set position first, in-case top/left are set even on static elem\n\t\tif ( position === \"static\" ) {\n\t\t\telem.style.position = \"relative\";\n\t\t}\n\n\t\tcurOffset = curElem.offset();\n\t\tcurCSSTop = jQuery.css( elem, \"top\" );\n\t\tcurCSSLeft = jQuery.css( elem, \"left\" );\n\t\tcalculatePosition = ( position === \"absolute\" || position === \"fixed\" ) &&\n\t\t\t( curCSSTop + curCSSLeft ).indexOf( \"auto\" ) > -1;\n\n\t\t// Need to be able to calculate position if either\n\t\t// top or left is auto and position is either absolute or fixed\n\t\tif ( calculatePosition ) {\n\t\t\tcurPosition = curElem.position();\n\t\t\tcurTop = curPosition.top;\n\t\t\tcurLeft = curPosition.left;\n\n\t\t} else {\n\t\t\tcurTop = parseFloat( curCSSTop ) || 0;\n\t\t\tcurLeft = parseFloat( curCSSLeft ) || 0;\n\t\t}\n\n\t\tif ( isFunction( options ) ) {\n\n\t\t\t// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)\n\t\t\toptions = options.call( elem, i, jQuery.extend( {}, curOffset ) );\n\t\t}\n\n\t\tif ( options.top != null ) {\n\t\t\tprops.top = ( options.top - curOffset.top ) + curTop;\n\t\t}\n\t\tif ( options.left != null ) {\n\t\t\tprops.left = ( options.left - curOffset.left ) + curLeft;\n\t\t}\n\n\t\tif ( \"using\" in options ) {\n\t\t\toptions.using.call( elem, props );\n\n\t\t} else {\n\t\t\tcurElem.css( props );\n\t\t}\n\t}\n};\n\njQuery.fn.extend( {\n\n\t// offset() relates an element's border box to the document origin\n\toffset: function( options ) {\n\n\t\t// Preserve chaining for setter\n\t\tif ( arguments.length ) {\n\t\t\treturn options === undefined ?\n\t\t\t\tthis :\n\t\t\t\tthis.each( function( i ) {\n\t\t\t\t\tjQuery.offset.setOffset( this, options, i );\n\t\t\t\t} );\n\t\t}\n\n\t\tvar rect, win,\n\t\t\telem = this[ 0 ];\n\n\t\tif ( !elem ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Return zeros for disconnected and hidden (display: none) elements (gh-2310)\n\t\t// Support: IE <=11 only\n\t\t// Running getBoundingClientRect on a\n\t\t// disconnected node in IE throws an error\n\t\tif ( !elem.getClientRects().length ) {\n\t\t\treturn { top: 0, left: 0 };\n\t\t}\n\n\t\t// Get document-relative position by adding viewport scroll to viewport-relative gBCR\n\t\trect = elem.getBoundingClientRect();\n\t\twin = elem.ownerDocument.defaultView;\n\t\treturn {\n\t\t\ttop: rect.top + win.pageYOffset,\n\t\t\tleft: rect.left + win.pageXOffset\n\t\t};\n\t},\n\n\t// position() relates an element's margin box to its offset parent's padding box\n\t// This corresponds to the behavior of CSS absolute positioning\n\tposition: function() {\n\t\tif ( !this[ 0 ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar offsetParent, offset, doc,\n\t\t\telem = this[ 0 ],\n\t\t\tparentOffset = { top: 0, left: 0 };\n\n\t\t// position:fixed elements are offset from the viewport, which itself always has zero offset\n\t\tif ( jQuery.css( elem, \"position\" ) === \"fixed\" ) {\n\n\t\t\t// Assume position:fixed implies availability of getBoundingClientRect\n\t\t\toffset = elem.getBoundingClientRect();\n\n\t\t} else {\n\t\t\toffset = this.offset();\n\n\t\t\t// Account for the *real* offset parent, which can be the document or its root element\n\t\t\t// when a statically positioned element is identified\n\t\t\tdoc = elem.ownerDocument;\n\t\t\toffsetParent = elem.offsetParent || doc.documentElement;\n\t\t\twhile ( offsetParent &&\n\t\t\t\t( offsetParent === doc.body || offsetParent === doc.documentElement ) &&\n\t\t\t\tjQuery.css( offsetParent, \"position\" ) === \"static\" ) {\n\n\t\t\t\toffsetParent = offsetParent.parentNode;\n\t\t\t}\n\t\t\tif ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) {\n\n\t\t\t\t// Incorporate borders into its offset, since they are outside its content origin\n\t\t\t\tparentOffset = jQuery( offsetParent ).offset();\n\t\t\t\tparentOffset.top += jQuery.css( offsetParent, \"borderTopWidth\", true );\n\t\t\t\tparentOffset.left += jQuery.css( offsetParent, \"borderLeftWidth\", true );\n\t\t\t}\n\t\t}\n\n\t\t// Subtract parent offsets and element margins\n\t\treturn {\n\t\t\ttop: offset.top - parentOffset.top - jQuery.css( elem, \"marginTop\", true ),\n\t\t\tleft: offset.left - parentOffset.left - jQuery.css( elem, \"marginLeft\", true )\n\t\t};\n\t},\n\n\t// This method will return documentElement in the following cases:\n\t// 1) For the element inside the iframe without offsetParent, this method will return\n\t//    documentElement of the parent window\n\t// 2) For the hidden or detached element\n\t// 3) For body or html element, i.e. in case of the html node - it will return itself\n\t//\n\t// but those exceptions were never presented as a real life use-cases\n\t// and might be considered as more preferable results.\n\t//\n\t// This logic, however, is not guaranteed and can change at any point in the future\n\toffsetParent: function() {\n\t\treturn this.map( function() {\n\t\t\tvar offsetParent = this.offsetParent;\n\n\t\t\twhile ( offsetParent && jQuery.css( offsetParent, \"position\" ) === \"static\" ) {\n\t\t\t\toffsetParent = offsetParent.offsetParent;\n\t\t\t}\n\n\t\t\treturn offsetParent || documentElement;\n\t\t} );\n\t}\n} );\n\n// Create scrollLeft and scrollTop methods\njQuery.each( { scrollLeft: \"pageXOffset\", scrollTop: \"pageYOffset\" }, function( method, prop ) {\n\tvar top = \"pageYOffset\" === prop;\n\n\tjQuery.fn[ method ] = function( val ) {\n\t\treturn access( this, function( elem, method, val ) {\n\n\t\t\t// Coalesce documents and windows\n\t\t\tvar win;\n\t\t\tif ( isWindow( elem ) ) {\n\t\t\t\twin = elem;\n\t\t\t} else if ( elem.nodeType === 9 ) {\n\t\t\t\twin = elem.defaultView;\n\t\t\t}\n\n\t\t\tif ( val === undefined ) {\n\t\t\t\treturn win ? win[ prop ] : elem[ method ];\n\t\t\t}\n\n\t\t\tif ( win ) {\n\t\t\t\twin.scrollTo(\n\t\t\t\t\t!top ? val : win.pageXOffset,\n\t\t\t\t\ttop ? val : win.pageYOffset\n\t\t\t\t);\n\n\t\t\t} else {\n\t\t\t\telem[ method ] = val;\n\t\t\t}\n\t\t}, method, val, arguments.length );\n\t};\n} );\n\n// Support: Safari <=7 - 9.1, Chrome <=37 - 49\n// Add the top/left cssHooks using jQuery.fn.position\n// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084\n// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347\n// getComputedStyle returns percent when specified for top/left/bottom/right;\n// rather than make the css module depend on the offset module, just check for it here\njQuery.each( [ \"top\", \"left\" ], function( _i, prop ) {\n\tjQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,\n\t\tfunction( elem, computed ) {\n\t\t\tif ( computed ) {\n\t\t\t\tcomputed = curCSS( elem, prop );\n\n\t\t\t\t// If curCSS returns percentage, fallback to offset\n\t\t\t\treturn rnumnonpx.test( computed ) ?\n\t\t\t\t\tjQuery( elem ).position()[ prop ] + \"px\" :\n\t\t\t\t\tcomputed;\n\t\t\t}\n\t\t}\n\t);\n} );\n\n\n// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods\njQuery.each( { Height: \"height\", Width: \"width\" }, function( name, type ) {\n\tjQuery.each( {\n\t\tpadding: \"inner\" + name,\n\t\tcontent: type,\n\t\t\"\": \"outer\" + name\n\t}, function( defaultExtra, funcName ) {\n\n\t\t// Margin is only for outerHeight, outerWidth\n\t\tjQuery.fn[ funcName ] = function( margin, value ) {\n\t\t\tvar chainable = arguments.length && ( defaultExtra || typeof margin !== \"boolean\" ),\n\t\t\t\textra = defaultExtra || ( margin === true || value === true ? \"margin\" : \"border\" );\n\n\t\t\treturn access( this, function( elem, type, value ) {\n\t\t\t\tvar doc;\n\n\t\t\t\tif ( isWindow( elem ) ) {\n\n\t\t\t\t\t// $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)\n\t\t\t\t\treturn funcName.indexOf( \"outer\" ) === 0 ?\n\t\t\t\t\t\telem[ \"inner\" + name ] :\n\t\t\t\t\t\telem.document.documentElement[ \"client\" + name ];\n\t\t\t\t}\n\n\t\t\t\t// Get document width or height\n\t\t\t\tif ( elem.nodeType === 9 ) {\n\t\t\t\t\tdoc = elem.documentElement;\n\n\t\t\t\t\t// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],\n\t\t\t\t\t// whichever is greatest\n\t\t\t\t\treturn Math.max(\n\t\t\t\t\t\telem.body[ \"scroll\" + name ], doc[ \"scroll\" + name ],\n\t\t\t\t\t\telem.body[ \"offset\" + name ], doc[ \"offset\" + name ],\n\t\t\t\t\t\tdoc[ \"client\" + name ]\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn value === undefined ?\n\n\t\t\t\t\t// Get width or height on the element, requesting but not forcing parseFloat\n\t\t\t\t\tjQuery.css( elem, type, extra ) :\n\n\t\t\t\t\t// Set width or height on the element\n\t\t\t\t\tjQuery.style( elem, type, value, extra );\n\t\t\t}, type, chainable ? margin : undefined, chainable );\n\t\t};\n\t} );\n} );\n\n\njQuery.each( [\n\t\"ajaxStart\",\n\t\"ajaxStop\",\n\t\"ajaxComplete\",\n\t\"ajaxError\",\n\t\"ajaxSuccess\",\n\t\"ajaxSend\"\n], function( _i, type ) {\n\tjQuery.fn[ type ] = function( fn ) {\n\t\treturn this.on( type, fn );\n\t};\n} );\n\n\n\n\njQuery.fn.extend( {\n\n\tbind: function( types, data, fn ) {\n\t\treturn this.on( types, null, data, fn );\n\t},\n\tunbind: function( types, fn ) {\n\t\treturn this.off( types, null, fn );\n\t},\n\n\tdelegate: function( selector, types, data, fn ) {\n\t\treturn this.on( types, selector, data, fn );\n\t},\n\tundelegate: function( selector, types, fn ) {\n\n\t\t// ( namespace ) or ( selector, types [, fn] )\n\t\treturn arguments.length === 1 ?\n\t\t\tthis.off( selector, \"**\" ) :\n\t\t\tthis.off( types, selector || \"**\", fn );\n\t},\n\n\thover: function( fnOver, fnOut ) {\n\t\treturn this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );\n\t}\n} );\n\njQuery.each(\n\t( \"blur focus focusin focusout resize scroll click dblclick \" +\n\t\"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave \" +\n\t\"change select submit keydown keypress keyup contextmenu\" ).split( \" \" ),\n\tfunction( _i, name ) {\n\n\t\t// Handle event binding\n\t\tjQuery.fn[ name ] = function( data, fn ) {\n\t\t\treturn arguments.length > 0 ?\n\t\t\t\tthis.on( name, null, data, fn ) :\n\t\t\t\tthis.trigger( name );\n\t\t};\n\t}\n);\n\n\n\n\n// Support: Android <=4.0 only\n// Make sure we trim BOM and NBSP\nvar rtrim = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g;\n\n// Bind a function to a context, optionally partially applying any\n// arguments.\n// jQuery.proxy is deprecated to promote standards (specifically Function#bind)\n// However, it is not slated for removal any time soon\njQuery.proxy = function( fn, context ) {\n\tvar tmp, args, proxy;\n\n\tif ( typeof context === \"string\" ) {\n\t\ttmp = fn[ context ];\n\t\tcontext = fn;\n\t\tfn = tmp;\n\t}\n\n\t// Quick check to determine if target is callable, in the spec\n\t// this throws a TypeError, but we will just return undefined.\n\tif ( !isFunction( fn ) ) {\n\t\treturn undefined;\n\t}\n\n\t// Simulated bind\n\targs = slice.call( arguments, 2 );\n\tproxy = function() {\n\t\treturn fn.apply( context || this, args.concat( slice.call( arguments ) ) );\n\t};\n\n\t// Set the guid of unique handler to the same of original handler, so it can be removed\n\tproxy.guid = fn.guid = fn.guid || jQuery.guid++;\n\n\treturn proxy;\n};\n\njQuery.holdReady = function( hold ) {\n\tif ( hold ) {\n\t\tjQuery.readyWait++;\n\t} else {\n\t\tjQuery.ready( true );\n\t}\n};\njQuery.isArray = Array.isArray;\njQuery.parseJSON = JSON.parse;\njQuery.nodeName = nodeName;\njQuery.isFunction = isFunction;\njQuery.isWindow = isWindow;\njQuery.camelCase = camelCase;\njQuery.type = toType;\n\njQuery.now = Date.now;\n\njQuery.isNumeric = function( obj ) {\n\n\t// As of jQuery 3.0, isNumeric is limited to\n\t// strings and numbers (primitives or objects)\n\t// that can be coerced to finite numbers (gh-2662)\n\tvar type = jQuery.type( obj );\n\treturn ( type === \"number\" || type === \"string\" ) &&\n\n\t\t// parseFloat NaNs numeric-cast false positives (\"\")\n\t\t// ...but misinterprets leading-number strings, particularly hex literals (\"0x...\")\n\t\t// subtraction forces infinities to NaN\n\t\t!isNaN( obj - parseFloat( obj ) );\n};\n\njQuery.trim = function( text ) {\n\treturn text == null ?\n\t\t\"\" :\n\t\t( text + \"\" ).replace( rtrim, \"\" );\n};\n\n\n\n// Register as a named AMD module, since jQuery can be concatenated with other\n// files that may use define, but not via a proper concatenation script that\n// understands anonymous AMD modules. A named AMD is safest and most robust\n// way to register. Lowercase jquery is used because AMD module names are\n// derived from file names, and jQuery is normally delivered in a lowercase\n// file name. Do this after creating the global so that if an AMD module wants\n// to call noConflict to hide this version of jQuery, it will work.\n\n// Note that for maximum portability, libraries that are not jQuery should\n// declare themselves as anonymous modules, and avoid setting a global if an\n// AMD loader is present. jQuery is a special case. For more information, see\n// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon\n\nif ( typeof define === \"function\" && define.amd ) {\n\tdefine( \"jquery\", [], function() {\n\t\treturn jQuery;\n\t} );\n}\n\n\n\n\nvar\n\n\t// Map over jQuery in case of overwrite\n\t_jQuery = window.jQuery,\n\n\t// Map over the $ in case of overwrite\n\t_$ = window.$;\n\njQuery.noConflict = function( deep ) {\n\tif ( window.$ === jQuery ) {\n\t\twindow.$ = _$;\n\t}\n\n\tif ( deep && window.jQuery === jQuery ) {\n\t\twindow.jQuery = _jQuery;\n\t}\n\n\treturn jQuery;\n};\n\n// Expose jQuery and $ identifiers, even in AMD\n// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)\n// and CommonJS for browser emulators (#13566)\nif ( typeof noGlobal === \"undefined\" ) {\n\twindow.jQuery = window.$ = jQuery;\n}\n\n\n\n\nreturn jQuery;\n} );\n"
  },
  {
    "path": "core/dbt/docs/build/html/_static/jquery.js",
    "content": "/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */\n!function(e,t){\"use strict\";\"object\"==typeof module&&\"object\"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error(\"jQuery requires a window with a document\");return t(e)}:t(e)}(\"undefined\"!=typeof window?window:this,function(C,e){\"use strict\";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return\"function\"==typeof e&&\"number\"!=typeof e.nodeType&&\"function\"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement(\"script\");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+\"\":\"object\"==typeof e||\"function\"==typeof e?n[o.call(e)]||\"object\":typeof e}var f=\"3.6.0\",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&\"length\"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&(\"array\"===n||0===t||\"number\"==typeof t&&0<t&&t-1 in e)}S.fn=S.prototype={jquery:f,constructor:S,length:0,toArray:function(){return s.call(this)},get:function(e){return null==e?s.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=S.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return S.each(this,e)},map:function(n){return this.pushStack(S.map(this,function(e,t){return n.call(e,t,e)}))},slice:function(){return this.pushStack(s.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(S.grep(this,function(e,t){return(t+1)%2}))},odd:function(){return this.pushStack(S.grep(this,function(e,t){return t%2}))},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(0<=n&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:u,sort:t.sort,splice:t.splice},S.extend=S.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for(\"boolean\"==typeof a&&(l=a,a=arguments[s]||{},s++),\"object\"==typeof a||m(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)r=e[t],\"__proto__\"!==t&&a!==r&&(l&&r&&(S.isPlainObject(r)||(i=Array.isArray(r)))?(n=a[t],o=i&&!Array.isArray(n)?[]:i||S.isPlainObject(n)?n:{},i=!1,a[t]=S.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},S.extend({expando:\"jQuery\"+(f+Math.random()).replace(/\\D/g,\"\"),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||\"[object Object]\"!==o.call(e))&&(!(t=r(e))||\"function\"==typeof(n=v.call(t,\"constructor\")&&t.constructor)&&a.call(n)===l)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e,t,n){b(e,{nonce:t&&t.nonce},n)},each:function(e,t){var n,r=0;if(p(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},makeArray:function(e,t){var n=t||[];return null!=e&&(p(Object(e))?S.merge(n,\"string\"==typeof e?[e]:e):u.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:i.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r=[],i=0,o=e.length,a=!n;i<o;i++)!t(e[i],i)!==a&&r.push(e[i]);return r},map:function(e,t,n){var r,i,o=0,a=[];if(p(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&a.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&a.push(i);return g(a)},guid:1,support:y}),\"function\"==typeof Symbol&&(S.fn[Symbol.iterator]=t[Symbol.iterator]),S.each(\"Boolean Number String Function Array Date RegExp Object Error Symbol\".split(\" \"),function(e,t){n[\"[object \"+t+\"]\"]=t.toLowerCase()});var d=function(n){var e,d,b,o,i,h,f,g,w,u,l,T,C,a,E,v,s,c,y,S=\"sizzle\"+1*new Date,p=n.document,k=0,r=0,m=ue(),x=ue(),A=ue(),N=ue(),j=function(e,t){return e===t&&(l=!0),0},D={}.hasOwnProperty,t=[],q=t.pop,L=t.push,H=t.push,O=t.slice,P=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},R=\"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",M=\"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",I=\"(?:\\\\\\\\[\\\\da-fA-F]{1,6}\"+M+\"?|\\\\\\\\[^\\\\r\\\\n\\\\f]|[\\\\w-]|[^\\0-\\\\x7f])+\",W=\"\\\\[\"+M+\"*(\"+I+\")(?:\"+M+\"*([*^$|!~]?=)\"+M+\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\"+I+\"))|)\"+M+\"*\\\\]\",F=\":(\"+I+\")(?:\\\\((('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\"+W+\")*)|.*)\\\\)|)\",B=new RegExp(M+\"+\",\"g\"),$=new RegExp(\"^\"+M+\"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\"+M+\"+$\",\"g\"),_=new RegExp(\"^\"+M+\"*,\"+M+\"*\"),z=new RegExp(\"^\"+M+\"*([>+~]|\"+M+\")\"+M+\"*\"),U=new RegExp(M+\"|>\"),X=new RegExp(F),V=new RegExp(\"^\"+I+\"$\"),G={ID:new RegExp(\"^#(\"+I+\")\"),CLASS:new RegExp(\"^\\\\.(\"+I+\")\"),TAG:new RegExp(\"^(\"+I+\"|[*])\"),ATTR:new RegExp(\"^\"+W),PSEUDO:new RegExp(\"^\"+F),CHILD:new RegExp(\"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\"+M+\"*(even|odd|(([+-]|)(\\\\d*)n|)\"+M+\"*(?:([+-]|)\"+M+\"*(\\\\d+)|))\"+M+\"*\\\\)|)\",\"i\"),bool:new RegExp(\"^(?:\"+R+\")$\",\"i\"),needsContext:new RegExp(\"^\"+M+\"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\"+M+\"*((?:-\\\\d)?\\\\d*)\"+M+\"*\\\\)|)(?=[^-]|$)\",\"i\")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\\d$/i,K=/^[^{]+\\{\\s*\\[native \\w/,Z=/^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,ee=/[+~]/,te=new RegExp(\"\\\\\\\\[\\\\da-fA-F]{1,6}\"+M+\"?|\\\\\\\\([^\\\\r\\\\n\\\\f])\",\"g\"),ne=function(e,t){var n=\"0x\"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\\0-\\x1f\\x7f]|^-?\\d)|^-$|[^\\0-\\x1f\\x7f-\\uFFFF\\w-]/g,ie=function(e,t){return t?\"\\0\"===e?\"\\ufffd\":e.slice(0,-1)+\"\\\\\"+e.charCodeAt(e.length-1).toString(16)+\" \":\"\\\\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&\"fieldset\"===e.nodeName.toLowerCase()},{dir:\"parentNode\",next:\"legend\"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],\"string\"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+\" \"]&&(!v||!v.test(t))&&(1!==p||\"object\"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute(\"id\"))?s=s.replace(re,ie):e.setAttribute(\"id\",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?\"#\"+s:\":scope\")+\" \"+xe(l[o]);c=l.join(\",\")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute(\"id\")}}}return g(t.replace($,\"$1\"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+\" \")>b.cacheLength&&delete e[r.shift()],e[t+\" \"]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement(\"fieldset\");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split(\"|\"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return\"input\"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return(\"input\"===t||\"button\"===t)&&e.type===n}}function ge(t){return function(e){return\"form\"in e?e.parentNode&&!1===e.disabled?\"label\"in e?\"label\"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:\"label\"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&\"undefined\"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||\"HTML\")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener(\"unload\",oe,!1):n.attachEvent&&n.attachEvent(\"onunload\",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement(\"div\")),\"undefined\"!=typeof e.querySelectorAll&&!e.querySelectorAll(\":scope fieldset div\").length}),d.attributes=ce(function(e){return e.className=\"i\",!e.getAttribute(\"className\")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment(\"\")),!e.getElementsByTagName(\"*\").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute(\"id\")===t}},b.find.ID=function(e,t){if(\"undefined\"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t=\"undefined\"!=typeof e.getAttributeNode&&e.getAttributeNode(\"id\");return t&&t.value===n}},b.find.ID=function(e,t){if(\"undefined\"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode(\"id\"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode(\"id\"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return\"undefined\"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if(\"*\"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if(\"undefined\"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML=\"<a id='\"+S+\"'></a><select id='\"+S+\"-\\r\\\\' msallowcapture=''><option selected=''></option></select>\",e.querySelectorAll(\"[msallowcapture^='']\").length&&v.push(\"[*^$]=\"+M+\"*(?:''|\\\"\\\")\"),e.querySelectorAll(\"[selected]\").length||v.push(\"\\\\[\"+M+\"*(?:value|\"+R+\")\"),e.querySelectorAll(\"[id~=\"+S+\"-]\").length||v.push(\"~=\"),(t=C.createElement(\"input\")).setAttribute(\"name\",\"\"),e.appendChild(t),e.querySelectorAll(\"[name='']\").length||v.push(\"\\\\[\"+M+\"*name\"+M+\"*=\"+M+\"*(?:''|\\\"\\\")\"),e.querySelectorAll(\":checked\").length||v.push(\":checked\"),e.querySelectorAll(\"a#\"+S+\"+*\").length||v.push(\".#.+[+~]\"),e.querySelectorAll(\"\\\\\\f\"),v.push(\"[\\\\r\\\\n\\\\f]\")}),ce(function(e){e.innerHTML=\"<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>\";var t=C.createElement(\"input\");t.setAttribute(\"type\",\"hidden\"),e.appendChild(t).setAttribute(\"name\",\"D\"),e.querySelectorAll(\"[name=d]\").length&&v.push(\"name\"+M+\"*[*^$|!~]?=\"),2!==e.querySelectorAll(\":enabled\").length&&v.push(\":enabled\",\":disabled\"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(\":disabled\").length&&v.push(\":enabled\",\":disabled\"),e.querySelectorAll(\"*,:x\"),v.push(\",.*:\")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,\"*\"),c.call(e,\"[s!='']:x\"),s.push(\"!=\",F)}),v=v.length&&new RegExp(v.join(\"|\")),s=s.length&&new RegExp(s.join(\"|\")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+\" \"]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0<se(t,C,null,[e]).length},se.contains=function(e,t){return(e.ownerDocument||e)!=C&&T(e),y(e,t)},se.attr=function(e,t){(e.ownerDocument||e)!=C&&T(e);var n=b.attrHandle[t.toLowerCase()],r=n&&D.call(b.attrHandle,t.toLowerCase())?n(e,t,!E):void 0;return void 0!==r?r:d.attributes||!E?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},se.escape=function(e){return(e+\"\").replace(re,ie)},se.error=function(e){throw new Error(\"Syntax error, unrecognized expression: \"+e)},se.uniqueSort=function(e){var t,n=[],r=0,i=0;if(l=!d.detectDuplicates,u=!d.sortStable&&e.slice(0),e.sort(j),l){while(t=e[i++])t===e[i]&&(r=n.push(i));while(r--)e.splice(n[r],1)}return u=null,e},o=se.getText=function(e){var t,n=\"\",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if(\"string\"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else while(t=e[r++])n+=o(t);return n},(b=se.selectors={cacheLength:50,createPseudo:le,match:G,attrHandle:{},find:{},relative:{\">\":{dir:\"parentNode\",first:!0},\" \":{dir:\"parentNode\"},\"+\":{dir:\"previousSibling\",first:!0},\"~\":{dir:\"previousSibling\"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||\"\").replace(te,ne),\"~=\"===e[2]&&(e[3]=\" \"+e[3]+\" \"),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),\"nth\"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*(\"even\"===e[3]||\"odd\"===e[3])),e[5]=+(e[7]+e[8]||\"odd\"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||\"\":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(\")\",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return\"*\"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+\" \"];return t||(t=new RegExp(\"(^|\"+M+\")\"+e+\"(\"+M+\"|$)\"))&&m(e,function(e){return t.test(\"string\"==typeof e.className&&e.className||\"undefined\"!=typeof e.getAttribute&&e.getAttribute(\"class\")||\"\")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?\"!=\"===r:!r||(t+=\"\",\"=\"===r?t===i:\"!=\"===r?t!==i:\"^=\"===r?i&&0===t.indexOf(i):\"*=\"===r?i&&-1<t.indexOf(i):\"$=\"===r?i&&t.slice(-i.length)===i:\"~=\"===r?-1<(\" \"+t.replace(B,\" \")+\" \").indexOf(i):\"|=\"===r&&(t===i||t.slice(0,i.length+1)===i+\"-\"))}},CHILD:function(h,e,t,g,v){var y=\"nth\"!==h.slice(0,3),m=\"last\"!==h.slice(-4),x=\"of-type\"===e;return 1===g&&0===v?function(e){return!!e.parentNode}:function(e,t,n){var r,i,o,a,s,u,l=y!==m?\"nextSibling\":\"previousSibling\",c=e.parentNode,f=x&&e.nodeName.toLowerCase(),p=!n&&!x,d=!1;if(c){if(y){while(l){a=e;while(a=a[l])if(x?a.nodeName.toLowerCase()===f:1===a.nodeType)return!1;u=l=\"only\"===h&&!u&&\"nextSibling\"}return!0}if(u=[m?c.firstChild:c.lastChild],m&&p){d=(s=(r=(i=(o=(a=c)[S]||(a[S]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===k&&r[1])&&r[2],a=s&&c.childNodes[s];while(a=++s&&a&&a[l]||(d=s=0)||u.pop())if(1===a.nodeType&&++d&&a===e){i[h]=[k,s,d];break}}else if(p&&(d=s=(r=(i=(o=(a=e)[S]||(a[S]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===k&&r[1]),!1===d)while(a=++s&&a&&a[l]||(d=s=0)||u.pop())if((x?a.nodeName.toLowerCase()===f:1===a.nodeType)&&++d&&(p&&((i=(o=a[S]||(a[S]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]=[k,d]),a===e))break;return(d-=v)===g||d%g==0&&0<=d/g}}},PSEUDO:function(e,o){var t,a=b.pseudos[e]||b.setFilters[e.toLowerCase()]||se.error(\"unsupported pseudo: \"+e);return a[S]?a(o):1<a.length?(t=[e,e,\"\",o],b.setFilters.hasOwnProperty(e.toLowerCase())?le(function(e,t){var n,r=a(e,o),i=r.length;while(i--)e[n=P(e,r[i])]=!(t[n]=r[i])}):function(e){return a(e,0,t)}):a}},pseudos:{not:le(function(e){var r=[],i=[],s=f(e.replace($,\"$1\"));return s[S]?le(function(e,t,n,r){var i,o=s(e,null,r,[]),a=e.length;while(a--)(i=o[a])&&(e[a]=!(t[a]=i))}):function(e,t,n){return r[0]=e,s(r,null,n,i),r[0]=null,!i.pop()}}),has:le(function(t){return function(e){return 0<se(t,e).length}}),contains:le(function(t){return t=t.replace(te,ne),function(e){return-1<(e.textContent||o(e)).indexOf(t)}}),lang:le(function(n){return V.test(n||\"\")||se.error(\"unsupported lang: \"+n),n=n.replace(te,ne).toLowerCase(),function(e){var t;do{if(t=E?e.lang:e.getAttribute(\"xml:lang\")||e.getAttribute(\"lang\"))return(t=t.toLowerCase())===n||0===t.indexOf(n+\"-\")}while((e=e.parentNode)&&1===e.nodeType);return!1}}),target:function(e){var t=n.location&&n.location.hash;return t&&t.slice(1)===e.id},root:function(e){return e===a},focus:function(e){return e===C.activeElement&&(!C.hasFocus||C.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:ge(!1),disabled:ge(!0),checked:function(e){var t=e.nodeName.toLowerCase();return\"input\"===t&&!!e.checked||\"option\"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!b.pseudos.empty(e)},header:function(e){return J.test(e.nodeName)},input:function(e){return Q.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return\"input\"===t&&\"button\"===e.type||\"button\"===t},text:function(e){var t;return\"input\"===e.nodeName.toLowerCase()&&\"text\"===e.type&&(null==(t=e.getAttribute(\"type\"))||\"text\"===t.toLowerCase())},first:ve(function(){return[0]}),last:ve(function(e,t){return[t-1]}),eq:ve(function(e,t,n){return[n<0?n+t:n]}),even:ve(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:ve(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:ve(function(e,t,n){for(var r=n<0?n+t:t<n?t:n;0<=--r;)e.push(r);return e}),gt:ve(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}}).pseudos.nth=b.pseudos.eq,{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})b.pseudos[e]=de(e);for(e in{submit:!0,reset:!0})b.pseudos[e]=he(e);function me(){}function xe(e){for(var t=0,n=e.length,r=\"\";t<n;t++)r+=e[t].value;return r}function be(s,e,t){var u=e.dir,l=e.next,c=l||u,f=t&&\"parentNode\"===c,p=r++;return e.first?function(e,t,n){while(e=e[u])if(1===e.nodeType||f)return s(e,t,n);return!1}:function(e,t,n){var r,i,o,a=[k,p];if(n){while(e=e[u])if((1===e.nodeType||f)&&s(e,t,n))return!0}else while(e=e[u])if(1===e.nodeType||f)if(i=(o=e[S]||(e[S]={}))[e.uniqueID]||(o[e.uniqueID]={}),l&&l===e.nodeName.toLowerCase())e=e[u]||e;else{if((r=i[c])&&r[0]===k&&r[1]===p)return a[2]=r[2];if((i[c]=a)[2]=s(e,t,n))return!0}return!1}}function we(i){return 1<i.length?function(e,t,n){var r=i.length;while(r--)if(!i[r](e,t,n))return!1;return!0}:i[0]}function Te(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s<u;s++)(o=e[s])&&(n&&!n(o,r,i)||(a.push(o),l&&t.push(s)));return a}function Ce(d,h,g,v,y,e){return v&&!v[S]&&(v=Ce(v)),y&&!y[S]&&(y=Ce(y,e)),le(function(e,t,n,r){var i,o,a,s=[],u=[],l=t.length,c=e||function(e,t,n){for(var r=0,i=t.length;r<i;r++)se(e,t[r],n);return n}(h||\"*\",n.nodeType?[n]:n,[]),f=!d||!e&&h?c:Te(c,s,d,n,r),p=g?y||(e?d:l||v)?[]:t:f;if(g&&g(f,p,n,r),v){i=Te(p,u),v(i,[],n,r),o=i.length;while(o--)(a=i[o])&&(p[u[o]]=!(f[u[o]]=a))}if(e){if(y||d){if(y){i=[],o=p.length;while(o--)(a=p[o])&&i.push(f[o]=a);y(null,p=[],i,r)}o=p.length;while(o--)(a=p[o])&&-1<(i=y?P(e,a):s[o])&&(e[i]=!(t[i]=a))}}else p=Te(p===t?p.splice(l,p.length):p),y?y(null,t,p,r):H.apply(t,p)})}function Ee(e){for(var i,t,n,r=e.length,o=b.relative[e[0].type],a=o||b.relative[\" \"],s=o?1:0,u=be(function(e){return e===i},a,!0),l=be(function(e){return-1<P(i,e)},a,!0),c=[function(e,t,n){var r=!o&&(n||t!==w)||((i=t).nodeType?u(e,t,n):l(e,t,n));return i=null,r}];s<r;s++)if(t=b.relative[e[s].type])c=[be(we(c),t)];else{if((t=b.filter[e[s].type].apply(null,e[s].matches))[S]){for(n=++s;n<r;n++)if(b.relative[e[n].type])break;return Ce(1<s&&we(c),1<s&&xe(e.slice(0,s-1).concat({value:\" \"===e[s-2].type?\"*\":\"\"})).replace($,\"$1\"),t,s<n&&Ee(e.slice(s,n)),n<r&&Ee(e=e.slice(n)),n<r&&xe(e))}c.push(t)}return we(c)}return me.prototype=b.filters=b.pseudos,b.setFilters=new me,h=se.tokenize=function(e,t){var n,r,i,o,a,s,u,l=x[e+\" \"];if(l)return t?0:l.slice(0);a=e,s=[],u=b.preFilter;while(a){for(o in n&&!(r=_.exec(a))||(r&&(a=a.slice(r[0].length)||a),s.push(i=[])),n=!1,(r=z.exec(a))&&(n=r.shift(),i.push({value:n,type:r[0].replace($,\" \")}),a=a.slice(n.length)),b.filter)!(r=G[o].exec(a))||u[o]&&!(r=u[o](r))||(n=r.shift(),i.push({value:n,type:o,matches:r}),a=a.slice(n.length));if(!n)break}return t?a.length:a?se.error(e):x(e,s).slice(0)},f=se.compile=function(e,t){var n,v,y,m,x,r,i=[],o=[],a=A[e+\" \"];if(!a){t||(t=h(e)),n=t.length;while(n--)(a=Ee(t[n]))[S]?i.push(a):o.push(a);(a=A(e,(v=o,m=0<(y=i).length,x=0<v.length,r=function(e,t,n,r,i){var o,a,s,u=0,l=\"0\",c=e&&[],f=[],p=w,d=e||x&&b.find.TAG(\"*\",i),h=k+=null==p?1:Math.random()||.1,g=d.length;for(i&&(w=t==C||t||i);l!==g&&null!=(o=d[l]);l++){if(x&&o){a=0,t||o.ownerDocument==C||(T(o),n=!E);while(s=v[a++])if(s(o,t||C,n)){r.push(o);break}i&&(k=h)}m&&((o=!s&&o)&&u--,e&&c.push(o))}if(u+=l,m&&l!==u){a=0;while(s=y[a++])s(c,f,t,n);if(e){if(0<u)while(l--)c[l]||f[l]||(f[l]=q.call(r));f=Te(f)}H.apply(r,f),i&&!e&&0<f.length&&1<u+y.length&&se.uniqueSort(r)}return i&&(k=h,w=p),c},m?le(r):r))).selector=e}return a},g=se.select=function(e,t,n,r){var i,o,a,s,u,l=\"function\"==typeof e&&e,c=!r&&h(e=l.selector||e);if(n=n||[],1===c.length){if(2<(o=c[0]=c[0].slice(0)).length&&\"ID\"===(a=o[0]).type&&9===t.nodeType&&E&&b.relative[o[1].type]){if(!(t=(b.find.ID(a.matches[0].replace(te,ne),t)||[])[0]))return n;l&&(t=t.parentNode),e=e.slice(o.shift().value.length)}i=G.needsContext.test(e)?0:o.length;while(i--){if(a=o[i],b.relative[s=a.type])break;if((u=b.find[s])&&(r=u(a.matches[0].replace(te,ne),ee.test(o[0].type)&&ye(t.parentNode)||t))){if(o.splice(i,1),!(e=r.length&&xe(o)))return H.apply(n,r),n;break}}}return(l||f(e,c))(r,t,!E,n,!t||ee.test(e)&&ye(t.parentNode)||t),n},d.sortStable=S.split(\"\").sort(j).join(\"\")===S,d.detectDuplicates=!!l,T(),d.sortDetached=ce(function(e){return 1&e.compareDocumentPosition(C.createElement(\"fieldset\"))}),ce(function(e){return e.innerHTML=\"<a href='#'></a>\",\"#\"===e.firstChild.getAttribute(\"href\")})||fe(\"type|href|height|width\",function(e,t,n){if(!n)return e.getAttribute(t,\"type\"===t.toLowerCase()?1:2)}),d.attributes&&ce(function(e){return e.innerHTML=\"<input/>\",e.firstChild.setAttribute(\"value\",\"\"),\"\"===e.firstChild.getAttribute(\"value\")})||fe(\"value\",function(e,t,n){if(!n&&\"input\"===e.nodeName.toLowerCase())return e.defaultValue}),ce(function(e){return null==e.getAttribute(\"disabled\")})||fe(R,function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),se}(C);S.find=d,S.expr=d.selectors,S.expr[\":\"]=S.expr.pseudos,S.uniqueSort=S.unique=d.uniqueSort,S.text=d.getText,S.isXMLDoc=d.isXML,S.contains=d.contains,S.escapeSelector=d.escape;var h=function(e,t,n){var r=[],i=void 0!==n;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&S(e).is(n))break;r.push(e)}return r},T=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},k=S.expr.match.needsContext;function A(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var N=/^<([a-z][^\\/\\0>:\\x20\\t\\r\\n\\f]*)[\\x20\\t\\r\\n\\f]*\\/?>(?:<\\/\\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):\"string\"!=typeof n?S.grep(e,function(e){return-1<i.call(n,e)!==r}):S.filter(n,e,r)}S.filter=function(e,t,n){var r=t[0];return n&&(e=\":not(\"+e+\")\"),1===t.length&&1===r.nodeType?S.find.matchesSelector(r,e)?[r]:[]:S.find.matches(e,S.grep(t,function(e){return 1===e.nodeType}))},S.fn.extend({find:function(e){var t,n,r=this.length,i=this;if(\"string\"!=typeof e)return this.pushStack(S(e).filter(function(){for(t=0;t<r;t++)if(S.contains(i[t],this))return!0}));for(n=this.pushStack([]),t=0;t<r;t++)S.find(e,i[t],n);return 1<r?S.uniqueSort(n):n},filter:function(e){return this.pushStack(j(this,e||[],!1))},not:function(e){return this.pushStack(j(this,e||[],!0))},is:function(e){return!!j(this,\"string\"==typeof e&&k.test(e)?S(e):e||[],!1).length}});var D,q=/^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,\"string\"==typeof e){if(!(r=\"<\"===e[0]&&\">\"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e<n;e++)if(S.contains(this,t[e]))return!0})},closest:function(e,t){var n,r=0,i=this.length,o=[],a=\"string\"!=typeof e&&S(e);if(!k.test(e))for(;r<i;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(a?-1<a.index(n):1===n.nodeType&&S.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(1<o.length?S.uniqueSort(o):o)},index:function(e){return e?\"string\"==typeof e?i.call(S(e),this[0]):i.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(S.uniqueSort(S.merge(this.get(),S(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),S.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return h(e,\"parentNode\")},parentsUntil:function(e,t,n){return h(e,\"parentNode\",n)},next:function(e){return O(e,\"nextSibling\")},prev:function(e){return O(e,\"previousSibling\")},nextAll:function(e){return h(e,\"nextSibling\")},prevAll:function(e){return h(e,\"previousSibling\")},nextUntil:function(e,t,n){return h(e,\"nextSibling\",n)},prevUntil:function(e,t,n){return h(e,\"previousSibling\",n)},siblings:function(e){return T((e.parentNode||{}).firstChild,e)},children:function(e){return T(e.firstChild)},contents:function(e){return null!=e.contentDocument&&r(e.contentDocument)?e.contentDocument:(A(e,\"template\")&&(e=e.content||e),S.merge([],e.childNodes))}},function(r,i){S.fn[r]=function(e,t){var n=S.map(this,i,e);return\"Until\"!==r.slice(-5)&&(t=e),t&&\"string\"==typeof t&&(n=S.filter(t,n)),1<this.length&&(H[r]||S.uniqueSort(n),L.test(r)&&n.reverse()),this.pushStack(n)}});var P=/[^\\x20\\t\\r\\n\\f]+/g;function R(e){return e}function M(e){throw e}function I(e,t,n,r){var i;try{e&&m(i=e.promise)?i.call(e).done(t).fail(n):e&&m(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}S.Callbacks=function(r){var e,n;r=\"string\"==typeof r?(e=r,n={},S.each(e.match(P)||[],function(e,t){n[t]=!0}),n):S.extend({},r);var i,t,o,a,s=[],u=[],l=-1,c=function(){for(a=a||r.once,o=i=!0;u.length;l=-1){t=u.shift();while(++l<s.length)!1===s[l].apply(t[0],t[1])&&r.stopOnFalse&&(l=s.length,t=!1)}r.memory||(t=!1),i=!1,a&&(s=t?[]:\"\")},f={add:function(){return s&&(t&&!i&&(l=s.length-1,u.push(t)),function n(e){S.each(e,function(e,t){m(t)?r.unique&&f.has(t)||s.push(t):t&&t.length&&\"string\"!==w(t)&&n(t)})}(arguments),t&&!i&&c()),this},remove:function(){return S.each(arguments,function(e,t){var n;while(-1<(n=S.inArray(t,s,n)))s.splice(n,1),n<=l&&l--}),this},has:function(e){return e?-1<S.inArray(e,s):0<s.length},empty:function(){return s&&(s=[]),this},disable:function(){return a=u=[],s=t=\"\",this},disabled:function(){return!s},lock:function(){return a=u=[],t||i||(s=t=\"\"),this},locked:function(){return!!a},fireWith:function(e,t){return a||(t=[e,(t=t||[]).slice?t.slice():t],u.push(t),i||c()),this},fire:function(){return f.fireWith(this,arguments),this},fired:function(){return!!o}};return f},S.extend({Deferred:function(e){var o=[[\"notify\",\"progress\",S.Callbacks(\"memory\"),S.Callbacks(\"memory\"),2],[\"resolve\",\"done\",S.Callbacks(\"once memory\"),S.Callbacks(\"once memory\"),0,\"resolved\"],[\"reject\",\"fail\",S.Callbacks(\"once memory\"),S.Callbacks(\"once memory\"),1,\"rejected\"]],i=\"pending\",a={state:function(){return i},always:function(){return s.done(arguments).fail(arguments),this},\"catch\":function(e){return a.then(null,e)},pipe:function(){var i=arguments;return S.Deferred(function(r){S.each(o,function(e,t){var n=m(i[t[4]])&&i[t[4]];s[t[1]](function(){var e=n&&n.apply(this,arguments);e&&m(e.promise)?e.promise().progress(r.notify).done(r.resolve).fail(r.reject):r[t[0]+\"With\"](this,n?[e]:arguments)})}),i=null}).promise()},then:function(t,n,r){var u=0;function l(i,o,a,s){return function(){var n=this,r=arguments,e=function(){var e,t;if(!(i<u)){if((e=a.apply(n,r))===o.promise())throw new TypeError(\"Thenable self-resolution\");t=e&&(\"object\"==typeof e||\"function\"==typeof e)&&e.then,m(t)?s?t.call(e,l(u,o,R,s),l(u,o,M,s)):(u++,t.call(e,l(u,o,R,s),l(u,o,M,s),l(u,o,R,o.notifyWith))):(a!==R&&(n=void 0,r=[e]),(s||o.resolveWith)(n,r))}},t=s?e:function(){try{e()}catch(e){S.Deferred.exceptionHook&&S.Deferred.exceptionHook(e,t.stackTrace),u<=i+1&&(a!==M&&(n=void 0,r=[e]),o.rejectWith(n,r))}};i?t():(S.Deferred.getStackHook&&(t.stackTrace=S.Deferred.getStackHook()),C.setTimeout(t))}}return S.Deferred(function(e){o[0][3].add(l(0,e,m(r)?r:R,e.notifyWith)),o[1][3].add(l(0,e,m(t)?t:R)),o[2][3].add(l(0,e,m(n)?n:M))}).promise()},promise:function(e){return null!=e?S.extend(e,a):a}},s={};return S.each(o,function(e,t){var n=t[2],r=t[5];a[t[1]]=n.add,r&&n.add(function(){i=r},o[3-e][2].disable,o[3-e][3].disable,o[0][2].lock,o[0][3].lock),n.add(t[3].fire),s[t[0]]=function(){return s[t[0]+\"With\"](this===s?void 0:this,arguments),this},s[t[0]+\"With\"]=n.fireWith}),a.promise(s),e&&e.call(s,s),s},when:function(e){var n=arguments.length,t=n,r=Array(t),i=s.call(arguments),o=S.Deferred(),a=function(t){return function(e){r[t]=this,i[t]=1<arguments.length?s.call(arguments):e,--n||o.resolveWith(r,i)}};if(n<=1&&(I(e,o.done(a(t)).resolve,o.reject,!n),\"pending\"===o.state()||m(i[t]&&i[t].then)))return o.then();while(t--)I(i[t],a(t),o.reject);return o.promise()}});var W=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;S.Deferred.exceptionHook=function(e,t){C.console&&C.console.warn&&e&&W.test(e.name)&&C.console.warn(\"jQuery.Deferred exception: \"+e.message,e.stack,t)},S.readyException=function(e){C.setTimeout(function(){throw e})};var F=S.Deferred();function B(){E.removeEventListener(\"DOMContentLoaded\",B),C.removeEventListener(\"load\",B),S.ready()}S.fn.ready=function(e){return F.then(e)[\"catch\"](function(e){S.readyException(e)}),this},S.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--S.readyWait:S.isReady)||(S.isReady=!0)!==e&&0<--S.readyWait||F.resolveWith(E,[S])}}),S.ready.then=F.then,\"complete\"===E.readyState||\"loading\"!==E.readyState&&!E.documentElement.doScroll?C.setTimeout(S.ready):(E.addEventListener(\"DOMContentLoaded\",B),C.addEventListener(\"load\",B));var $=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if(\"object\"===w(n))for(s in i=!0,n)$(e,t,s,n[s],!0,o,a);else if(void 0!==r&&(i=!0,m(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(S(e),n)})),t))for(;s<u;s++)t(e[s],n,a?r:r.call(e[s],s,t(e[s],n)));return i?e:l?t.call(e):u?t(e[0],n):o},_=/^-ms-/,z=/-([a-z])/g;function U(e,t){return t.toUpperCase()}function X(e){return e.replace(_,\"ms-\").replace(z,U)}var V=function(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType};function G(){this.expando=S.expando+G.uid++}G.uid=1,G.prototype={cache:function(e){var t=e[this.expando];return t||(t={},V(e)&&(e.nodeType?e[this.expando]=t:Object.defineProperty(e,this.expando,{value:t,configurable:!0}))),t},set:function(e,t,n){var r,i=this.cache(e);if(\"string\"==typeof t)i[X(t)]=n;else for(r in t)i[X(r)]=t[r];return i},get:function(e,t){return void 0===t?this.cache(e):e[this.expando]&&e[this.expando][X(t)]},access:function(e,t,n){return void 0===t||t&&\"string\"==typeof t&&void 0===n?this.get(e,t):(this.set(e,t,n),void 0!==n?n:t)},remove:function(e,t){var n,r=e[this.expando];if(void 0!==r){if(void 0!==t){n=(t=Array.isArray(t)?t.map(X):(t=X(t))in r?[t]:t.match(P)||[]).length;while(n--)delete r[t[n]]}(void 0===t||S.isEmptyObject(r))&&(e.nodeType?e[this.expando]=void 0:delete e[this.expando])}},hasData:function(e){var t=e[this.expando];return void 0!==t&&!S.isEmptyObject(t)}};var Y=new G,Q=new G,J=/^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,K=/[A-Z]/g;function Z(e,t,n){var r,i;if(void 0===n&&1===e.nodeType)if(r=\"data-\"+t.replace(K,\"-$&\").toLowerCase(),\"string\"==typeof(n=e.getAttribute(r))){try{n=\"true\"===(i=n)||\"false\"!==i&&(\"null\"===i?null:i===+i+\"\"?+i:J.test(i)?JSON.parse(i):i)}catch(e){}Q.set(e,t,n)}else n=void 0;return n}S.extend({hasData:function(e){return Q.hasData(e)||Y.hasData(e)},data:function(e,t,n){return Q.access(e,t,n)},removeData:function(e,t){Q.remove(e,t)},_data:function(e,t,n){return Y.access(e,t,n)},_removeData:function(e,t){Y.remove(e,t)}}),S.fn.extend({data:function(n,e){var t,r,i,o=this[0],a=o&&o.attributes;if(void 0===n){if(this.length&&(i=Q.get(o),1===o.nodeType&&!Y.get(o,\"hasDataAttrs\"))){t=a.length;while(t--)a[t]&&0===(r=a[t].name).indexOf(\"data-\")&&(r=X(r.slice(5)),Z(o,r,i[r]));Y.set(o,\"hasDataAttrs\",!0)}return i}return\"object\"==typeof n?this.each(function(){Q.set(this,n)}):$(this,function(e){var t;if(o&&void 0===e)return void 0!==(t=Q.get(o,n))?t:void 0!==(t=Z(o,n))?t:void 0;this.each(function(){Q.set(this,n,e)})},null,e,1<arguments.length,null,!0)},removeData:function(e){return this.each(function(){Q.remove(this,e)})}}),S.extend({queue:function(e,t,n){var r;if(e)return t=(t||\"fx\")+\"queue\",r=Y.get(e,t),n&&(!r||Array.isArray(n)?r=Y.access(e,t,S.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||\"fx\";var n=S.queue(e,t),r=n.length,i=n.shift(),o=S._queueHooks(e,t);\"inprogress\"===i&&(i=n.shift(),r--),i&&(\"fx\"===t&&n.unshift(\"inprogress\"),delete o.stop,i.call(e,function(){S.dequeue(e,t)},o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+\"queueHooks\";return Y.get(e,n)||Y.access(e,n,{empty:S.Callbacks(\"once memory\").add(function(){Y.remove(e,[t+\"queue\",n])})})}}),S.fn.extend({queue:function(t,n){var e=2;return\"string\"!=typeof t&&(n=t,t=\"fx\",e--),arguments.length<e?S.queue(this[0],t):void 0===n?this:this.each(function(){var e=S.queue(this,t,n);S._queueHooks(this,t),\"fx\"===t&&\"inprogress\"!==e[0]&&S.dequeue(this,t)})},dequeue:function(e){return this.each(function(){S.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||\"fx\",[])},promise:function(e,t){var n,r=1,i=S.Deferred(),o=this,a=this.length,s=function(){--r||i.resolveWith(o,[o])};\"string\"!=typeof e&&(t=e,e=void 0),e=e||\"fx\";while(a--)(n=Y.get(o[a],e+\"queueHooks\"))&&n.empty&&(r++,n.empty.add(s));return s(),i.promise(t)}});var ee=/[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/.source,te=new RegExp(\"^(?:([+-])=|)(\"+ee+\")([a-z%]*)$\",\"i\"),ne=[\"Top\",\"Right\",\"Bottom\",\"Left\"],re=E.documentElement,ie=function(e){return S.contains(e.ownerDocument,e)},oe={composed:!0};re.getRootNode&&(ie=function(e){return S.contains(e.ownerDocument,e)||e.getRootNode(oe)===e.ownerDocument});var ae=function(e,t){return\"none\"===(e=t||e).style.display||\"\"===e.style.display&&ie(e)&&\"none\"===S.css(e,\"display\")};function se(e,t,n,r){var i,o,a=20,s=r?function(){return r.cur()}:function(){return S.css(e,t,\"\")},u=s(),l=n&&n[3]||(S.cssNumber[t]?\"\":\"px\"),c=e.nodeType&&(S.cssNumber[t]||\"px\"!==l&&+u)&&te.exec(S.css(e,t));if(c&&c[3]!==l){u/=2,l=l||c[3],c=+u||1;while(a--)S.style(e,t,c+l),(1-o)*(1-(o=s()/u||.5))<=0&&(a=0),c/=o;c*=2,S.style(e,t,c+l),n=n||[]}return n&&(c=+c||+u||0,i=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=i)),i}var ue={};function le(e,t){for(var n,r,i,o,a,s,u,l=[],c=0,f=e.length;c<f;c++)(r=e[c]).style&&(n=r.style.display,t?(\"none\"===n&&(l[c]=Y.get(r,\"display\")||null,l[c]||(r.style.display=\"\")),\"\"===r.style.display&&ae(r)&&(l[c]=(u=a=o=void 0,a=(i=r).ownerDocument,s=i.nodeName,(u=ue[s])||(o=a.body.appendChild(a.createElement(s)),u=S.css(o,\"display\"),o.parentNode.removeChild(o),\"none\"===u&&(u=\"block\"),ue[s]=u)))):\"none\"!==n&&(l[c]=\"none\",Y.set(r,\"display\",n)));for(c=0;c<f;c++)null!=l[c]&&(e[c].style.display=l[c]);return e}S.fn.extend({show:function(){return le(this,!0)},hide:function(){return le(this)},toggle:function(e){return\"boolean\"==typeof e?e?this.show():this.hide():this.each(function(){ae(this)?S(this).show():S(this).hide()})}});var ce,fe,pe=/^(?:checkbox|radio)$/i,de=/<([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]*)/i,he=/^$|^module$|\\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement(\"div\")),(fe=E.createElement(\"input\")).setAttribute(\"type\",\"radio\"),fe.setAttribute(\"checked\",\"checked\"),fe.setAttribute(\"name\",\"t\"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML=\"<textarea>x</textarea>\",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML=\"<option></option>\",y.option=!!ce.lastChild;var ge={thead:[1,\"<table>\",\"</table>\"],col:[2,\"<table><colgroup>\",\"</colgroup></table>\"],tr:[2,\"<table><tbody>\",\"</tbody></table>\"],td:[3,\"<table><tbody><tr>\",\"</tr></tbody></table>\"],_default:[0,\"\",\"\"]};function ve(e,t){var n;return n=\"undefined\"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||\"*\"):\"undefined\"!=typeof e.querySelectorAll?e.querySelectorAll(t||\"*\"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n<r;n++)Y.set(e[n],\"globalEval\",!t||Y.get(t[n],\"globalEval\"))}ge.tbody=ge.tfoot=ge.colgroup=ge.caption=ge.thead,ge.th=ge.td,y.option||(ge.optgroup=ge.option=[1,\"<select multiple='multiple'>\",\"</select>\"]);var me=/<|&#?\\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d<h;d++)if((o=e[d])||0===o)if(\"object\"===w(o))S.merge(p,o.nodeType?[o]:o);else if(me.test(o)){a=a||f.appendChild(t.createElement(\"div\")),s=(de.exec(o)||[\"\",\"\"])[1].toLowerCase(),u=ge[s]||ge._default,a.innerHTML=u[1]+S.htmlPrefilter(o)+u[2],c=u[0];while(c--)a=a.lastChild;S.merge(p,a.childNodes),(a=f.firstChild).textContent=\"\"}else p.push(t.createTextNode(o));f.textContent=\"\",d=0;while(o=p[d++])if(r&&-1<S.inArray(o,r))i&&i.push(o);else if(l=ie(o),a=ve(f.appendChild(o),\"script\"),l&&ye(a),n){c=0;while(o=a[c++])he.test(o.type||\"\")&&n.push(o)}return f}var be=/^([^.]*)(?:\\.(.+)|)/;function we(){return!0}function Te(){return!1}function Ce(e,t){return e===function(){try{return E.activeElement}catch(e){}}()==(\"focus\"===t)}function Ee(e,t,n,r,i,o){var a,s;if(\"object\"==typeof t){for(s in\"string\"!=typeof n&&(r=r||n,n=void 0),t)Ee(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&(\"string\"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Te;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return S().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=S.guid++)),e.each(function(){S.event.add(this,t,i,r,n)})}function Se(e,i,o){o?(Y.set(e,i,!1),S.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=Y.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(S.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),Y.set(this,i,r),t=o(this,i),this[i](),r!==(n=Y.get(this,i))||t?Y.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n&&n.value}else r.length&&(Y.set(this,i,{value:S.event.trigger(S.extend(r[0],S.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Y.get(e,i)&&S.event.add(e,i,we)}S.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Y.get(t);if(V(t)){n.handler&&(n=(o=n).handler,i=o.selector),i&&S.find.matchesSelector(re,i),n.guid||(n.guid=S.guid++),(u=v.events)||(u=v.events=Object.create(null)),(a=v.handle)||(a=v.handle=function(e){return\"undefined\"!=typeof S&&S.event.triggered!==e.type?S.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||\"\").match(P)||[\"\"]).length;while(l--)d=g=(s=be.exec(e[l])||[])[1],h=(s[2]||\"\").split(\".\").sort(),d&&(f=S.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=S.event.special[d]||{},c=S.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&S.expr.match.needsContext.test(i),namespace:h.join(\".\")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),S.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Y.hasData(e)&&Y.get(e);if(v&&(u=v.events)){l=(t=(t||\"\").match(P)||[\"\"]).length;while(l--)if(d=g=(s=be.exec(t[l])||[])[1],h=(s[2]||\"\").split(\".\").sort(),d){f=S.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp(\"(^|\\\\.)\"+h.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&(\"**\"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||S.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)S.event.remove(e,d+t[l],n,r,!0);S.isEmptyObject(u)&&Y.remove(e,\"handle events\")}},dispatch:function(e){var t,n,r,i,o,a,s=new Array(arguments.length),u=S.event.fix(e),l=(Y.get(this,\"events\")||Object.create(null))[u.type]||[],c=S.event.special[u.type]||{};for(s[0]=u,t=1;t<arguments.length;t++)s[t]=arguments[t];if(u.delegateTarget=this,!c.preDispatch||!1!==c.preDispatch.call(this,u)){a=S.event.handlers.call(this,u,l),t=0;while((i=a[t++])&&!u.isPropagationStopped()){u.currentTarget=i.elem,n=0;while((o=i.handlers[n++])&&!u.isImmediatePropagationStopped())u.rnamespace&&!1!==o.namespace&&!u.rnamespace.test(o.namespace)||(u.handleObj=o,u.data=o.data,void 0!==(r=((S.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,s))&&!1===(u.result=r)&&(u.preventDefault(),u.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,u),u.result}},handlers:function(e,t){var n,r,i,o,a,s=[],u=t.delegateCount,l=e.target;if(u&&l.nodeType&&!(\"click\"===e.type&&1<=e.button))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&(\"click\"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n<u;n++)void 0===a[i=(r=t[n]).selector+\" \"]&&(a[i]=r.needsContext?-1<S(i,this).index(l):S.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u<t.length&&s.push({elem:l,handlers:t.slice(u)}),s},addProp:function(t,e){Object.defineProperty(S.Event.prototype,t,{enumerable:!0,configurable:!0,get:m(e)?function(){if(this.originalEvent)return e(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[t]},set:function(e){Object.defineProperty(this,t,{enumerable:!0,configurable:!0,writable:!0,value:e})}})},fix:function(e){return e[S.expando]?e:new S.Event(e)},special:{load:{noBubble:!0},click:{setup:function(e){var t=this||e;return pe.test(t.type)&&t.click&&A(t,\"input\")&&Se(t,\"click\",we),!1},trigger:function(e){var t=this||e;return pe.test(t.type)&&t.click&&A(t,\"input\")&&Se(t,\"click\"),!0},_default:function(e){var t=e.target;return pe.test(t.type)&&t.click&&A(t,\"input\")&&Y.get(t,\"click\")||A(t,\"a\")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}}},S.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)},S.Event=function(e,t){if(!(this instanceof S.Event))return new S.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&!1===e.returnValue?we:Te,this.target=e.target&&3===e.target.nodeType?e.target.parentNode:e.target,this.currentTarget=e.currentTarget,this.relatedTarget=e.relatedTarget):this.type=e,t&&S.extend(this,t),this.timeStamp=e&&e.timeStamp||Date.now(),this[S.expando]=!0},S.Event.prototype={constructor:S.Event,isDefaultPrevented:Te,isPropagationStopped:Te,isImmediatePropagationStopped:Te,isSimulated:!1,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=we,e&&!this.isSimulated&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=we,e&&!this.isSimulated&&e.stopPropagation()},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=we,e&&!this.isSimulated&&e.stopImmediatePropagation(),this.stopPropagation()}},S.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,\"char\":!0,code:!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:!0},S.event.addProp),S.each({focus:\"focusin\",blur:\"focusout\"},function(e,t){S.event.special[e]={setup:function(){return Se(this,e,Ce),!1},trigger:function(){return Se(this,e),!0},_default:function(){return!0},delegateType:t}}),S.each({mouseenter:\"mouseover\",mouseleave:\"mouseout\",pointerenter:\"pointerover\",pointerleave:\"pointerout\"},function(e,i){S.event.special[e]={delegateType:i,bindType:i,handle:function(e){var t,n=e.relatedTarget,r=e.handleObj;return n&&(n===this||S.contains(this,n))||(e.type=r.origType,t=r.handler.apply(this,arguments),e.type=i),t}}}),S.fn.extend({on:function(e,t,n,r){return Ee(this,e,t,n,r)},one:function(e,t,n,r){return Ee(this,e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,S(e.delegateTarget).off(r.namespace?r.origType+\".\"+r.namespace:r.origType,r.selector,r.handler),this;if(\"object\"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return!1!==t&&\"function\"!=typeof t||(n=t,t=void 0),!1===n&&(n=Te),this.each(function(){S.event.remove(this,e,n,t)})}});var ke=/<script|<style|<link/i,Ae=/checked\\s*(?:[^=]|=\\s*.checked.)/i,Ne=/^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g;function je(e,t){return A(e,\"table\")&&A(11!==t.nodeType?t:t.firstChild,\"tr\")&&S(e).children(\"tbody\")[0]||e}function De(e){return e.type=(null!==e.getAttribute(\"type\"))+\"/\"+e.type,e}function qe(e){return\"true/\"===(e.type||\"\").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute(\"type\"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,\"handle events\"),s)for(n=0,r=s[i].length;n<r;n++)S.event.add(t,i,s[i][n]);Q.hasData(e)&&(o=Q.access(e),a=S.extend({},o),Q.set(t,a))}}function He(n,r,i,o){r=g(r);var e,t,a,s,u,l,c=0,f=n.length,p=f-1,d=r[0],h=m(d);if(h||1<f&&\"string\"==typeof d&&!y.checkClone&&Ae.test(d))return n.each(function(e){var t=n.eq(e);h&&(r[0]=d.call(this,e,t.html())),He(t,r,i,o)});if(f&&(t=(e=xe(r,n[0].ownerDocument,!1,n,o)).firstChild,1===e.childNodes.length&&(e=t),t||o)){for(s=(a=S.map(ve(e,\"script\"),De)).length;c<f;c++)u=e,c!==p&&(u=S.clone(u,!0,!0),s&&S.merge(a,ve(u,\"script\"))),i.call(n[c],u,c);if(s)for(l=a[a.length-1].ownerDocument,S.map(a,qe),c=0;c<s;c++)u=a[c],he.test(u.type||\"\")&&!Y.access(u,\"globalEval\")&&S.contains(l,u)&&(u.src&&\"module\"!==(u.type||\"\").toLowerCase()?S._evalUrl&&!u.noModule&&S._evalUrl(u.src,{nonce:u.nonce||u.getAttribute(\"nonce\")},l):b(u.textContent.replace(Ne,\"\"),u,l))}return n}function Oe(e,t,n){for(var r,i=t?S.filter(t,e):e,o=0;null!=(r=i[o]);o++)n||1!==r.nodeType||S.cleanData(ve(r)),r.parentNode&&(n&&ie(r)&&ye(ve(r,\"script\")),r.parentNode.removeChild(r));return e}S.extend({htmlPrefilter:function(e){return e},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=ie(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||S.isXMLDoc(e)))for(a=ve(c),r=0,i=(o=ve(e)).length;r<i;r++)s=o[r],u=a[r],void 0,\"input\"===(l=u.nodeName.toLowerCase())&&pe.test(s.type)?u.checked=s.checked:\"input\"!==l&&\"textarea\"!==l||(u.defaultValue=s.defaultValue);if(t)if(n)for(o=o||ve(e),a=a||ve(c),r=0,i=o.length;r<i;r++)Le(o[r],a[r]);else Le(e,c);return 0<(a=ve(c,\"script\")).length&&ye(a,!f&&ve(e,\"script\")),c},cleanData:function(e){for(var t,n,r,i=S.event.special,o=0;void 0!==(n=e[o]);o++)if(V(n)){if(t=n[Y.expando]){if(t.events)for(r in t.events)i[r]?S.event.remove(n,r):S.removeEvent(n,r,t.handle);n[Y.expando]=void 0}n[Q.expando]&&(n[Q.expando]=void 0)}}}),S.fn.extend({detach:function(e){return Oe(this,e,!0)},remove:function(e){return Oe(this,e)},text:function(e){return $(this,function(e){return void 0===e?S.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return He(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||je(this,e).appendChild(e)})},prepend:function(){return He(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=je(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return He(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return He(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(S.cleanData(ve(e,!1)),e.textContent=\"\");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return S.clone(this,e,t)})},html:function(e){return $(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if(\"string\"==typeof e&&!ke.test(e)&&!ge[(de.exec(e)||[\"\",\"\"])[1].toLowerCase()]){e=S.htmlPrefilter(e);try{for(;n<r;n++)1===(t=this[n]||{}).nodeType&&(S.cleanData(ve(t,!1)),t.innerHTML=e);t=0}catch(e){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var n=[];return He(this,arguments,function(e){var t=this.parentNode;S.inArray(this,n)<0&&(S.cleanData(ve(this)),t&&t.replaceChild(e,this))},n)}}),S.each({appendTo:\"append\",prependTo:\"prepend\",insertBefore:\"before\",insertAfter:\"after\",replaceAll:\"replaceWith\"},function(e,a){S.fn[e]=function(e){for(var t,n=[],r=S(e),i=r.length-1,o=0;o<=i;o++)t=o===i?this:this.clone(!0),S(r[o])[a](t),u.apply(n,t.get());return this.pushStack(n)}});var Pe=new RegExp(\"^(\"+ee+\")(?!px)[a-z%]+$\",\"i\"),Re=function(e){var t=e.ownerDocument.defaultView;return t&&t.opener||(t=C),t.getComputedStyle(e)},Me=function(e,t,n){var r,i,o={};for(i in t)o[i]=e.style[i],e.style[i]=t[i];for(i in r=n.call(e),t)e.style[i]=o[i];return r},Ie=new RegExp(ne.join(\"|\"),\"i\");function We(e,t,n){var r,i,o,a,s=e.style;return(n=n||Re(e))&&(\"\"!==(a=n.getPropertyValue(t)||n[t])||ie(e)||(a=S.style(e,t)),!y.pixelBoxStyles()&&Pe.test(a)&&Ie.test(t)&&(r=s.width,i=s.minWidth,o=s.maxWidth,s.minWidth=s.maxWidth=s.width=a,a=n.width,s.width=r,s.minWidth=i,s.maxWidth=o)),void 0!==a?a+\"\":a}function Fe(e,t){return{get:function(){if(!e())return(this.get=t).apply(this,arguments);delete this.get}}}!function(){function e(){if(l){u.style.cssText=\"position:absolute;left:-11111px;width:60px;margin-top:1px;padding:0;border:0\",l.style.cssText=\"position:relative;display:block;box-sizing:border-box;overflow:scroll;margin:auto;border:1px;padding:1px;width:60%;top:1%\",re.appendChild(u).appendChild(l);var e=C.getComputedStyle(l);n=\"1%\"!==e.top,s=12===t(e.marginLeft),l.style.right=\"60%\",o=36===t(e.right),r=36===t(e.width),l.style.position=\"absolute\",i=12===t(l.offsetWidth/3),re.removeChild(u),l=null}}function t(e){return Math.round(parseFloat(e))}var n,r,i,o,a,s,u=E.createElement(\"div\"),l=E.createElement(\"div\");l.style&&(l.style.backgroundClip=\"content-box\",l.cloneNode(!0).style.backgroundClip=\"\",y.clearCloneStyle=\"content-box\"===l.style.backgroundClip,S.extend(y,{boxSizingReliable:function(){return e(),r},pixelBoxStyles:function(){return e(),o},pixelPosition:function(){return e(),n},reliableMarginLeft:function(){return e(),s},scrollboxSize:function(){return e(),i},reliableTrDimensions:function(){var e,t,n,r;return null==a&&(e=E.createElement(\"table\"),t=E.createElement(\"tr\"),n=E.createElement(\"div\"),e.style.cssText=\"position:absolute;left:-11111px;border-collapse:separate\",t.style.cssText=\"border:1px solid\",t.style.height=\"1px\",n.style.height=\"9px\",n.style.display=\"block\",re.appendChild(e).appendChild(t).appendChild(n),r=C.getComputedStyle(t),a=parseInt(r.height,10)+parseInt(r.borderTopWidth,10)+parseInt(r.borderBottomWidth,10)===t.offsetHeight,re.removeChild(e)),a}}))}();var Be=[\"Webkit\",\"Moz\",\"ms\"],$e=E.createElement(\"div\").style,_e={};function ze(e){var t=S.cssProps[e]||_e[e];return t||(e in $e?e:_e[e]=function(e){var t=e[0].toUpperCase()+e.slice(1),n=Be.length;while(n--)if((e=Be[n]+t)in $e)return e}(e)||e)}var Ue=/^(none|table(?!-c[ea]).+)/,Xe=/^--/,Ve={position:\"absolute\",visibility:\"hidden\",display:\"block\"},Ge={letterSpacing:\"0\",fontWeight:\"400\"};function Ye(e,t,n){var r=te.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||\"px\"):t}function Qe(e,t,n,r,i,o){var a=\"width\"===t?1:0,s=0,u=0;if(n===(r?\"border\":\"content\"))return 0;for(;a<4;a+=2)\"margin\"===n&&(u+=S.css(e,n+ne[a],!0,i)),r?(\"content\"===n&&(u-=S.css(e,\"padding\"+ne[a],!0,i)),\"margin\"!==n&&(u-=S.css(e,\"border\"+ne[a]+\"Width\",!0,i))):(u+=S.css(e,\"padding\"+ne[a],!0,i),\"padding\"!==n?u+=S.css(e,\"border\"+ne[a]+\"Width\",!0,i):s+=S.css(e,\"border\"+ne[a]+\"Width\",!0,i));return!r&&0<=o&&(u+=Math.max(0,Math.ceil(e[\"offset\"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))||0),u}function Je(e,t,n){var r=Re(e),i=(!y.boxSizingReliable()||n)&&\"border-box\"===S.css(e,\"boxSizing\",!1,r),o=i,a=We(e,t,r),s=\"offset\"+t[0].toUpperCase()+t.slice(1);if(Pe.test(a)){if(!n)return a;a=\"auto\"}return(!y.boxSizingReliable()&&i||!y.reliableTrDimensions()&&A(e,\"tr\")||\"auto\"===a||!parseFloat(a)&&\"inline\"===S.css(e,\"display\",!1,r))&&e.getClientRects().length&&(i=\"border-box\"===S.css(e,\"boxSizing\",!1,r),(o=s in e)&&(a=e[s])),(a=parseFloat(a)||0)+Qe(e,t,n||(i?\"border\":\"content\"),o,r,a)+\"px\"}function Ke(e,t,n,r,i){return new Ke.prototype.init(e,t,n,r,i)}S.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=We(e,\"opacity\");return\"\"===n?\"1\":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=X(t),u=Xe.test(t),l=e.style;if(u||(t=ze(s)),a=S.cssHooks[t]||S.cssHooks[s],void 0===n)return a&&\"get\"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];\"string\"===(o=typeof n)&&(i=te.exec(n))&&i[1]&&(n=se(e,t,i),o=\"number\"),null!=n&&n==n&&(\"number\"!==o||u||(n+=i&&i[3]||(S.cssNumber[s]?\"\":\"px\")),y.clearCloneStyle||\"\"!==n||0!==t.indexOf(\"background\")||(l[t]=\"inherit\"),a&&\"set\"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,s=X(t);return Xe.test(t)||(t=ze(s)),(a=S.cssHooks[t]||S.cssHooks[s])&&\"get\"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=We(e,t,r)),\"normal\"===i&&t in Ge&&(i=Ge[t]),\"\"===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),S.each([\"height\",\"width\"],function(e,u){S.cssHooks[u]={get:function(e,t,n){if(t)return!Ue.test(S.css(e,\"display\"))||e.getClientRects().length&&e.getBoundingClientRect().width?Je(e,u,n):Me(e,Ve,function(){return Je(e,u,n)})},set:function(e,t,n){var r,i=Re(e),o=!y.scrollboxSize()&&\"absolute\"===i.position,a=(o||n)&&\"border-box\"===S.css(e,\"boxSizing\",!1,i),s=n?Qe(e,u,n,a,i):0;return a&&o&&(s-=Math.ceil(e[\"offset\"+u[0].toUpperCase()+u.slice(1)]-parseFloat(i[u])-Qe(e,u,\"border\",!1,i)-.5)),s&&(r=te.exec(t))&&\"px\"!==(r[3]||\"px\")&&(e.style[u]=t,t=S.css(e,u)),Ye(0,t,s)}}}),S.cssHooks.marginLeft=Fe(y.reliableMarginLeft,function(e,t){if(t)return(parseFloat(We(e,\"marginLeft\"))||e.getBoundingClientRect().left-Me(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+\"px\"}),S.each({margin:\"\",padding:\"\",border:\"Width\"},function(i,o){S.cssHooks[i+o]={expand:function(e){for(var t=0,n={},r=\"string\"==typeof e?e.split(\" \"):[e];t<4;t++)n[i+ne[t]+o]=r[t]||r[t-2]||r[0];return n}},\"margin\"!==i&&(S.cssHooks[i+o].set=Ye)}),S.fn.extend({css:function(e,t){return $(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=Re(e),i=t.length;a<i;a++)o[t[a]]=S.css(e,t[a],!1,r);return o}return void 0!==n?S.style(e,t,n):S.css(e,t)},e,t,1<arguments.length)}}),((S.Tween=Ke).prototype={constructor:Ke,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||S.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(S.cssNumber[n]?\"\":\"px\")},cur:function(){var e=Ke.propHooks[this.prop];return e&&e.get?e.get(this):Ke.propHooks._default.get(this)},run:function(e){var t,n=Ke.propHooks[this.prop];return this.options.duration?this.pos=t=S.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):Ke.propHooks._default.set(this),this}}).init.prototype=Ke.prototype,(Ke.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=S.css(e.elem,e.prop,\"\"))&&\"auto\"!==t?t:0},set:function(e){S.fx.step[e.prop]?S.fx.step[e.prop](e):1!==e.elem.nodeType||!S.cssHooks[e.prop]&&null==e.elem.style[ze(e.prop)]?e.elem[e.prop]=e.now:S.style(e.elem,e.prop,e.now+e.unit)}}}).scrollTop=Ke.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},S.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:\"swing\"},S.fx=Ke.prototype.init,S.fx.step={};var Ze,et,tt,nt,rt=/^(?:toggle|show|hide)$/,it=/queueHooks$/;function ot(){et&&(!1===E.hidden&&C.requestAnimationFrame?C.requestAnimationFrame(ot):C.setTimeout(ot,S.fx.interval),S.fx.tick())}function at(){return C.setTimeout(function(){Ze=void 0}),Ze=Date.now()}function st(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i[\"margin\"+(n=ne[r])]=i[\"padding\"+n]=e;return t&&(i.opacity=i.width=e),i}function ut(e,t,n){for(var r,i=(lt.tweeners[t]||[]).concat(lt.tweeners[\"*\"]),o=0,a=i.length;o<a;o++)if(r=i[o].call(n,t,e))return r}function lt(o,e,t){var n,a,r=0,i=lt.prefilters.length,s=S.Deferred().always(function(){delete u.elem}),u=function(){if(a)return!1;for(var e=Ze||at(),t=Math.max(0,l.startTime+l.duration-e),n=1-(t/l.duration||0),r=0,i=l.tweens.length;r<i;r++)l.tweens[r].run(n);return s.notifyWith(o,[l,n,t]),n<1&&i?t:(i||s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l]),!1)},l=s.promise({elem:o,props:S.extend({},e),opts:S.extend(!0,{specialEasing:{},easing:S.easing._default},t),originalProperties:e,originalOptions:t,startTime:Ze||at(),duration:t.duration,tweens:[],createTween:function(e,t){var n=S.Tween(o,l.opts,e,t,l.opts.specialEasing[e]||l.opts.easing);return l.tweens.push(n),n},stop:function(e){var t=0,n=e?l.tweens.length:0;if(a)return this;for(a=!0;t<n;t++)l.tweens[t].run(1);return e?(s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l,e])):s.rejectWith(o,[l,e]),this}}),c=l.props;for(!function(e,t){var n,r,i,o,a;for(n in e)if(i=t[r=X(n)],o=e[n],Array.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),(a=S.cssHooks[r])&&\"expand\"in a)for(n in o=a.expand(o),delete e[r],o)n in e||(e[n]=o[n],t[n]=i);else t[r]=i}(c,l.opts.specialEasing);r<i;r++)if(n=lt.prefilters[r].call(l,o,c,l.opts))return m(n.stop)&&(S._queueHooks(l.elem,l.opts.queue).stop=n.stop.bind(n)),n;return S.map(c,ut,l),m(l.opts.start)&&l.opts.start.call(o,l),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always),S.fx.timer(S.extend(u,{elem:o,anim:l,queue:l.opts.queue})),l}S.Animation=S.extend(lt,{tweeners:{\"*\":[function(e,t){var n=this.createTween(e,t);return se(n.elem,e,te.exec(t),n),n}]},tweener:function(e,t){m(e)?(t=e,e=[\"*\"]):e=e.match(P);for(var n,r=0,i=e.length;r<i;r++)n=e[r],lt.tweeners[n]=lt.tweeners[n]||[],lt.tweeners[n].unshift(t)},prefilters:[function(e,t,n){var r,i,o,a,s,u,l,c,f=\"width\"in t||\"height\"in t,p=this,d={},h=e.style,g=e.nodeType&&ae(e),v=Y.get(e,\"fxshow\");for(r in n.queue||(null==(a=S._queueHooks(e,\"fx\")).unqueued&&(a.unqueued=0,s=a.empty.fire,a.empty.fire=function(){a.unqueued||s()}),a.unqueued++,p.always(function(){p.always(function(){a.unqueued--,S.queue(e,\"fx\").length||a.empty.fire()})})),t)if(i=t[r],rt.test(i)){if(delete t[r],o=o||\"toggle\"===i,i===(g?\"hide\":\"show\")){if(\"show\"!==i||!v||void 0===v[r])continue;g=!0}d[r]=v&&v[r]||S.style(e,r)}if((u=!S.isEmptyObject(t))||!S.isEmptyObject(d))for(r in f&&1===e.nodeType&&(n.overflow=[h.overflow,h.overflowX,h.overflowY],null==(l=v&&v.display)&&(l=Y.get(e,\"display\")),\"none\"===(c=S.css(e,\"display\"))&&(l?c=l:(le([e],!0),l=e.style.display||l,c=S.css(e,\"display\"),le([e]))),(\"inline\"===c||\"inline-block\"===c&&null!=l)&&\"none\"===S.css(e,\"float\")&&(u||(p.done(function(){h.display=l}),null==l&&(c=h.display,l=\"none\"===c?\"\":c)),h.display=\"inline-block\")),n.overflow&&(h.overflow=\"hidden\",p.always(function(){h.overflow=n.overflow[0],h.overflowX=n.overflow[1],h.overflowY=n.overflow[2]})),u=!1,d)u||(v?\"hidden\"in v&&(g=v.hidden):v=Y.access(e,\"fxshow\",{display:l}),o&&(v.hidden=!g),g&&le([e],!0),p.done(function(){for(r in g||le([e]),Y.remove(e,\"fxshow\"),d)S.style(e,r,d[r])})),u=ut(g?v[r]:0,r,p),r in v||(v[r]=u.start,g&&(u.end=u.start,u.start=0))}],prefilter:function(e,t){t?lt.prefilters.unshift(e):lt.prefilters.push(e)}}),S.speed=function(e,t,n){var r=e&&\"object\"==typeof e?S.extend({},e):{complete:n||!n&&t||m(e)&&e,duration:e,easing:n&&t||t&&!m(t)&&t};return S.fx.off?r.duration=0:\"number\"!=typeof r.duration&&(r.duration in S.fx.speeds?r.duration=S.fx.speeds[r.duration]:r.duration=S.fx.speeds._default),null!=r.queue&&!0!==r.queue||(r.queue=\"fx\"),r.old=r.complete,r.complete=function(){m(r.old)&&r.old.call(this),r.queue&&S.dequeue(this,r.queue)},r},S.fn.extend({fadeTo:function(e,t,n,r){return this.filter(ae).css(\"opacity\",0).show().end().animate({opacity:t},e,n,r)},animate:function(t,e,n,r){var i=S.isEmptyObject(t),o=S.speed(e,n,r),a=function(){var e=lt(this,S.extend({},t),o);(i||Y.get(this,\"finish\"))&&e.stop(!0)};return a.finish=a,i||!1===o.queue?this.each(a):this.queue(o.queue,a)},stop:function(i,e,o){var a=function(e){var t=e.stop;delete e.stop,t(o)};return\"string\"!=typeof i&&(o=e,e=i,i=void 0),e&&this.queue(i||\"fx\",[]),this.each(function(){var e=!0,t=null!=i&&i+\"queueHooks\",n=S.timers,r=Y.get(this);if(t)r[t]&&r[t].stop&&a(r[t]);else for(t in r)r[t]&&r[t].stop&&it.test(t)&&a(r[t]);for(t=n.length;t--;)n[t].elem!==this||null!=i&&n[t].queue!==i||(n[t].anim.stop(o),e=!1,n.splice(t,1));!e&&o||S.dequeue(this,i)})},finish:function(a){return!1!==a&&(a=a||\"fx\"),this.each(function(){var e,t=Y.get(this),n=t[a+\"queue\"],r=t[a+\"queueHooks\"],i=S.timers,o=n?n.length:0;for(t.finish=!0,S.queue(this,a,[]),r&&r.stop&&r.stop.call(this,!0),e=i.length;e--;)i[e].elem===this&&i[e].queue===a&&(i[e].anim.stop(!0),i.splice(e,1));for(e=0;e<o;e++)n[e]&&n[e].finish&&n[e].finish.call(this);delete t.finish})}}),S.each([\"toggle\",\"show\",\"hide\"],function(e,r){var i=S.fn[r];S.fn[r]=function(e,t,n){return null==e||\"boolean\"==typeof e?i.apply(this,arguments):this.animate(st(r,!0),e,t,n)}}),S.each({slideDown:st(\"show\"),slideUp:st(\"hide\"),slideToggle:st(\"toggle\"),fadeIn:{opacity:\"show\"},fadeOut:{opacity:\"hide\"},fadeToggle:{opacity:\"toggle\"}},function(e,r){S.fn[e]=function(e,t,n){return this.animate(r,e,t,n)}}),S.timers=[],S.fx.tick=function(){var e,t=0,n=S.timers;for(Ze=Date.now();t<n.length;t++)(e=n[t])()||n[t]!==e||n.splice(t--,1);n.length||S.fx.stop(),Ze=void 0},S.fx.timer=function(e){S.timers.push(e),S.fx.start()},S.fx.interval=13,S.fx.start=function(){et||(et=!0,ot())},S.fx.stop=function(){et=null},S.fx.speeds={slow:600,fast:200,_default:400},S.fn.delay=function(r,e){return r=S.fx&&S.fx.speeds[r]||r,e=e||\"fx\",this.queue(e,function(e,t){var n=C.setTimeout(e,r);t.stop=function(){C.clearTimeout(n)}})},tt=E.createElement(\"input\"),nt=E.createElement(\"select\").appendChild(E.createElement(\"option\")),tt.type=\"checkbox\",y.checkOn=\"\"!==tt.value,y.optSelected=nt.selected,(tt=E.createElement(\"input\")).value=\"t\",tt.type=\"radio\",y.radioValue=\"t\"===tt.value;var ct,ft=S.expr.attrHandle;S.fn.extend({attr:function(e,t){return $(this,S.attr,e,t,1<arguments.length)},removeAttr:function(e){return this.each(function(){S.removeAttr(this,e)})}}),S.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return\"undefined\"==typeof e.getAttribute?S.prop(e,t,n):(1===o&&S.isXMLDoc(e)||(i=S.attrHooks[t.toLowerCase()]||(S.expr.match.bool.test(t)?ct:void 0)),void 0!==n?null===n?void S.removeAttr(e,t):i&&\"set\"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+\"\"),n):i&&\"get\"in i&&null!==(r=i.get(e,t))?r:null==(r=S.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!y.radioValue&&\"radio\"===t&&A(e,\"input\")){var n=e.value;return e.setAttribute(\"type\",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(P);if(i&&1===e.nodeType)while(n=i[r++])e.removeAttribute(n)}}),ct={set:function(e,t,n){return!1===t?S.removeAttr(e,n):e.setAttribute(n,n),n}},S.each(S.expr.match.bool.source.match(/\\w+/g),function(e,t){var a=ft[t]||S.find.attr;ft[t]=function(e,t,n){var r,i,o=t.toLowerCase();return n||(i=ft[o],ft[o]=r,r=null!=a(e,t,n)?o:null,ft[o]=i),r}});var pt=/^(?:input|select|textarea|button)$/i,dt=/^(?:a|area)$/i;function ht(e){return(e.match(P)||[]).join(\" \")}function gt(e){return e.getAttribute&&e.getAttribute(\"class\")||\"\"}function vt(e){return Array.isArray(e)?e:\"string\"==typeof e&&e.match(P)||[]}S.fn.extend({prop:function(e,t){return $(this,S.prop,e,t,1<arguments.length)},removeProp:function(e){return this.each(function(){delete this[S.propFix[e]||e]})}}),S.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&S.isXMLDoc(e)||(t=S.propFix[t]||t,i=S.propHooks[t]),void 0!==n?i&&\"set\"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&\"get\"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=S.find.attr(e,\"tabindex\");return t?parseInt(t,10):pt.test(e.nodeName)||dt.test(e.nodeName)&&e.href?0:-1}}},propFix:{\"for\":\"htmlFor\",\"class\":\"className\"}}),y.optSelected||(S.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),S.each([\"tabIndex\",\"readOnly\",\"maxLength\",\"cellSpacing\",\"cellPadding\",\"rowSpan\",\"colSpan\",\"useMap\",\"frameBorder\",\"contentEditable\"],function(){S.propFix[this.toLowerCase()]=this}),S.fn.extend({addClass:function(t){var e,n,r,i,o,a,s,u=0;if(m(t))return this.each(function(e){S(this).addClass(t.call(this,e,gt(this)))});if((e=vt(t)).length)while(n=this[u++])if(i=gt(n),r=1===n.nodeType&&\" \"+ht(i)+\" \"){a=0;while(o=e[a++])r.indexOf(\" \"+o+\" \")<0&&(r+=o+\" \");i!==(s=ht(r))&&n.setAttribute(\"class\",s)}return this},removeClass:function(t){var e,n,r,i,o,a,s,u=0;if(m(t))return this.each(function(e){S(this).removeClass(t.call(this,e,gt(this)))});if(!arguments.length)return this.attr(\"class\",\"\");if((e=vt(t)).length)while(n=this[u++])if(i=gt(n),r=1===n.nodeType&&\" \"+ht(i)+\" \"){a=0;while(o=e[a++])while(-1<r.indexOf(\" \"+o+\" \"))r=r.replace(\" \"+o+\" \",\" \");i!==(s=ht(r))&&n.setAttribute(\"class\",s)}return this},toggleClass:function(i,t){var o=typeof i,a=\"string\"===o||Array.isArray(i);return\"boolean\"==typeof t&&a?t?this.addClass(i):this.removeClass(i):m(i)?this.each(function(e){S(this).toggleClass(i.call(this,e,gt(this),t),t)}):this.each(function(){var e,t,n,r;if(a){t=0,n=S(this),r=vt(i);while(e=r[t++])n.hasClass(e)?n.removeClass(e):n.addClass(e)}else void 0!==i&&\"boolean\"!==o||((e=gt(this))&&Y.set(this,\"__className__\",e),this.setAttribute&&this.setAttribute(\"class\",e||!1===i?\"\":Y.get(this,\"__className__\")||\"\"))})},hasClass:function(e){var t,n,r=0;t=\" \"+e+\" \";while(n=this[r++])if(1===n.nodeType&&-1<(\" \"+ht(gt(n))+\" \").indexOf(t))return!0;return!1}});var yt=/\\r/g;S.fn.extend({val:function(n){var r,e,i,t=this[0];return arguments.length?(i=m(n),this.each(function(e){var t;1===this.nodeType&&(null==(t=i?n.call(this,e,S(this).val()):n)?t=\"\":\"number\"==typeof t?t+=\"\":Array.isArray(t)&&(t=S.map(t,function(e){return null==e?\"\":e+\"\"})),(r=S.valHooks[this.type]||S.valHooks[this.nodeName.toLowerCase()])&&\"set\"in r&&void 0!==r.set(this,t,\"value\")||(this.value=t))})):t?(r=S.valHooks[t.type]||S.valHooks[t.nodeName.toLowerCase()])&&\"get\"in r&&void 0!==(e=r.get(t,\"value\"))?e:\"string\"==typeof(e=t.value)?e.replace(yt,\"\"):null==e?\"\":e:void 0}}),S.extend({valHooks:{option:{get:function(e){var t=S.find.attr(e,\"value\");return null!=t?t:ht(S.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a=\"select-one\"===e.type,s=a?null:[],u=a?o+1:i.length;for(r=o<0?u:a?o:0;r<u;r++)if(((n=i[r]).selected||r===o)&&!n.disabled&&(!n.parentNode.disabled||!A(n.parentNode,\"optgroup\"))){if(t=S(n).val(),a)return t;s.push(t)}return s},set:function(e,t){var n,r,i=e.options,o=S.makeArray(t),a=i.length;while(a--)((r=i[a]).selected=-1<S.inArray(S.valHooks.option.get(r),o))&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),S.each([\"radio\",\"checkbox\"],function(){S.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=-1<S.inArray(S(e).val(),t)}},y.checkOn||(S.valHooks[this].get=function(e){return null===e.getAttribute(\"value\")?\"on\":e.value})}),y.focusin=\"onfocusin\"in C;var mt=/^(?:focusinfocus|focusoutblur)$/,xt=function(e){e.stopPropagation()};S.extend(S.event,{trigger:function(e,t,n,r){var i,o,a,s,u,l,c,f,p=[n||E],d=v.call(e,\"type\")?e.type:e,h=v.call(e,\"namespace\")?e.namespace.split(\".\"):[];if(o=f=a=n=n||E,3!==n.nodeType&&8!==n.nodeType&&!mt.test(d+S.event.triggered)&&(-1<d.indexOf(\".\")&&(d=(h=d.split(\".\")).shift(),h.sort()),u=d.indexOf(\":\")<0&&\"on\"+d,(e=e[S.expando]?e:new S.Event(d,\"object\"==typeof e&&e)).isTrigger=r?2:3,e.namespace=h.join(\".\"),e.rnamespace=e.namespace?new RegExp(\"(^|\\\\.)\"+h.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"):null,e.result=void 0,e.target||(e.target=n),t=null==t?[e]:S.makeArray(t,[e]),c=S.event.special[d]||{},r||!c.trigger||!1!==c.trigger.apply(n,t))){if(!r&&!c.noBubble&&!x(n)){for(s=c.delegateType||d,mt.test(s+d)||(o=o.parentNode);o;o=o.parentNode)p.push(o),a=o;a===(n.ownerDocument||E)&&p.push(a.defaultView||a.parentWindow||C)}i=0;while((o=p[i++])&&!e.isPropagationStopped())f=o,e.type=1<i?s:c.bindType||d,(l=(Y.get(o,\"events\")||Object.create(null))[e.type]&&Y.get(o,\"handle\"))&&l.apply(o,t),(l=u&&o[u])&&l.apply&&V(o)&&(e.result=l.apply(o,t),!1===e.result&&e.preventDefault());return e.type=d,r||e.isDefaultPrevented()||c._default&&!1!==c._default.apply(p.pop(),t)||!V(n)||u&&m(n[d])&&!x(n)&&((a=n[u])&&(n[u]=null),S.event.triggered=d,e.isPropagationStopped()&&f.addEventListener(d,xt),n[d](),e.isPropagationStopped()&&f.removeEventListener(d,xt),S.event.triggered=void 0,a&&(n[u]=a)),e.result}},simulate:function(e,t,n){var r=S.extend(new S.Event,n,{type:e,isSimulated:!0});S.event.trigger(r,null,t)}}),S.fn.extend({trigger:function(e,t){return this.each(function(){S.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return S.event.trigger(e,t,n,!0)}}),y.focusin||S.each({focus:\"focusin\",blur:\"focusout\"},function(n,r){var i=function(e){S.event.simulate(r,e.target,S.event.fix(e))};S.event.special[r]={setup:function(){var e=this.ownerDocument||this.document||this,t=Y.access(e,r);t||e.addEventListener(n,i,!0),Y.access(e,r,(t||0)+1)},teardown:function(){var e=this.ownerDocument||this.document||this,t=Y.access(e,r)-1;t?Y.access(e,r,t):(e.removeEventListener(n,i,!0),Y.remove(e,r))}}});var bt=C.location,wt={guid:Date.now()},Tt=/\\?/;S.parseXML=function(e){var t,n;if(!e||\"string\"!=typeof e)return null;try{t=(new C.DOMParser).parseFromString(e,\"text/xml\")}catch(e){}return n=t&&t.getElementsByTagName(\"parsererror\")[0],t&&!n||S.error(\"Invalid XML: \"+(n?S.map(n.childNodes,function(e){return e.textContent}).join(\"\\n\"):e)),t};var Ct=/\\[\\]$/,Et=/\\r?\\n/g,St=/^(?:submit|button|image|reset|file)$/i,kt=/^(?:input|select|textarea|keygen)/i;function At(n,e,r,i){var t;if(Array.isArray(e))S.each(e,function(e,t){r||Ct.test(n)?i(n,t):At(n+\"[\"+(\"object\"==typeof t&&null!=t?e:\"\")+\"]\",t,r,i)});else if(r||\"object\"!==w(e))i(n,e);else for(t in e)At(n+\"[\"+t+\"]\",e[t],r,i)}S.param=function(e,t){var n,r=[],i=function(e,t){var n=m(t)?t():t;r[r.length]=encodeURIComponent(e)+\"=\"+encodeURIComponent(null==n?\"\":n)};if(null==e)return\"\";if(Array.isArray(e)||e.jquery&&!S.isPlainObject(e))S.each(e,function(){i(this.name,this.value)});else for(n in e)At(n,e[n],t,i);return r.join(\"&\")},S.fn.extend({serialize:function(){return S.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=S.prop(this,\"elements\");return e?S.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!S(this).is(\":disabled\")&&kt.test(this.nodeName)&&!St.test(e)&&(this.checked||!pe.test(e))}).map(function(e,t){var n=S(this).val();return null==n?null:Array.isArray(n)?S.map(n,function(e){return{name:t.name,value:e.replace(Et,\"\\r\\n\")}}):{name:t.name,value:n.replace(Et,\"\\r\\n\")}}).get()}});var Nt=/%20/g,jt=/#.*$/,Dt=/([?&])_=[^&]*/,qt=/^(.*?):[ \\t]*([^\\r\\n]*)$/gm,Lt=/^(?:GET|HEAD)$/,Ht=/^\\/\\//,Ot={},Pt={},Rt=\"*/\".concat(\"*\"),Mt=E.createElement(\"a\");function It(o){return function(e,t){\"string\"!=typeof e&&(t=e,e=\"*\");var n,r=0,i=e.toLowerCase().match(P)||[];if(m(t))while(n=i[r++])\"+\"===n[0]?(n=n.slice(1)||\"*\",(o[n]=o[n]||[]).unshift(t)):(o[n]=o[n]||[]).push(t)}}function Wt(t,i,o,a){var s={},u=t===Pt;function l(e){var r;return s[e]=!0,S.each(t[e]||[],function(e,t){var n=t(i,o,a);return\"string\"!=typeof n||u||s[n]?u?!(r=n):void 0:(i.dataTypes.unshift(n),l(n),!1)}),r}return l(i.dataTypes[0])||!s[\"*\"]&&l(\"*\")}function Ft(e,t){var n,r,i=S.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&S.extend(!0,e,r),e}Mt.href=bt.href,S.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:bt.href,type:\"GET\",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(bt.protocol),global:!0,processData:!0,async:!0,contentType:\"application/x-www-form-urlencoded; charset=UTF-8\",accepts:{\"*\":Rt,text:\"text/plain\",html:\"text/html\",xml:\"application/xml, text/xml\",json:\"application/json, text/javascript\"},contents:{xml:/\\bxml\\b/,html:/\\bhtml/,json:/\\bjson\\b/},responseFields:{xml:\"responseXML\",text:\"responseText\",json:\"responseJSON\"},converters:{\"* text\":String,\"text html\":!0,\"text json\":JSON.parse,\"text xml\":S.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?Ft(Ft(e,S.ajaxSettings),t):Ft(S.ajaxSettings,e)},ajaxPrefilter:It(Ot),ajaxTransport:It(Pt),ajax:function(e,t){\"object\"==typeof e&&(t=e,e=void 0),t=t||{};var c,f,p,n,d,r,h,g,i,o,v=S.ajaxSetup({},t),y=v.context||v,m=v.context&&(y.nodeType||y.jquery)?S(y):S.event,x=S.Deferred(),b=S.Callbacks(\"once memory\"),w=v.statusCode||{},a={},s={},u=\"canceled\",T={readyState:0,getResponseHeader:function(e){var t;if(h){if(!n){n={};while(t=qt.exec(p))n[t[1].toLowerCase()+\" \"]=(n[t[1].toLowerCase()+\" \"]||[]).concat(t[2])}t=n[e.toLowerCase()+\" \"]}return null==t?null:t.join(\", \")},getAllResponseHeaders:function(){return h?p:null},setRequestHeader:function(e,t){return null==h&&(e=s[e.toLowerCase()]=s[e.toLowerCase()]||e,a[e]=t),this},overrideMimeType:function(e){return null==h&&(v.mimeType=e),this},statusCode:function(e){var t;if(e)if(h)T.always(e[T.status]);else for(t in e)w[t]=[w[t],e[t]];return this},abort:function(e){var t=e||u;return c&&c.abort(t),l(0,t),this}};if(x.promise(T),v.url=((e||v.url||bt.href)+\"\").replace(Ht,bt.protocol+\"//\"),v.type=t.method||t.type||v.method||v.type,v.dataTypes=(v.dataType||\"*\").toLowerCase().match(P)||[\"\"],null==v.crossDomain){r=E.createElement(\"a\");try{r.href=v.url,r.href=r.href,v.crossDomain=Mt.protocol+\"//\"+Mt.host!=r.protocol+\"//\"+r.host}catch(e){v.crossDomain=!0}}if(v.data&&v.processData&&\"string\"!=typeof v.data&&(v.data=S.param(v.data,v.traditional)),Wt(Ot,v,t,T),h)return T;for(i in(g=S.event&&v.global)&&0==S.active++&&S.event.trigger(\"ajaxStart\"),v.type=v.type.toUpperCase(),v.hasContent=!Lt.test(v.type),f=v.url.replace(jt,\"\"),v.hasContent?v.data&&v.processData&&0===(v.contentType||\"\").indexOf(\"application/x-www-form-urlencoded\")&&(v.data=v.data.replace(Nt,\"+\")):(o=v.url.slice(f.length),v.data&&(v.processData||\"string\"==typeof v.data)&&(f+=(Tt.test(f)?\"&\":\"?\")+v.data,delete v.data),!1===v.cache&&(f=f.replace(Dt,\"$1\"),o=(Tt.test(f)?\"&\":\"?\")+\"_=\"+wt.guid+++o),v.url=f+o),v.ifModified&&(S.lastModified[f]&&T.setRequestHeader(\"If-Modified-Since\",S.lastModified[f]),S.etag[f]&&T.setRequestHeader(\"If-None-Match\",S.etag[f])),(v.data&&v.hasContent&&!1!==v.contentType||t.contentType)&&T.setRequestHeader(\"Content-Type\",v.contentType),T.setRequestHeader(\"Accept\",v.dataTypes[0]&&v.accepts[v.dataTypes[0]]?v.accepts[v.dataTypes[0]]+(\"*\"!==v.dataTypes[0]?\", \"+Rt+\"; q=0.01\":\"\"):v.accepts[\"*\"]),v.headers)T.setRequestHeader(i,v.headers[i]);if(v.beforeSend&&(!1===v.beforeSend.call(y,T,v)||h))return T.abort();if(u=\"abort\",b.add(v.complete),T.done(v.success),T.fail(v.error),c=Wt(Pt,v,t,T)){if(T.readyState=1,g&&m.trigger(\"ajaxSend\",[T,v]),h)return T;v.async&&0<v.timeout&&(d=C.setTimeout(function(){T.abort(\"timeout\")},v.timeout));try{h=!1,c.send(a,l)}catch(e){if(h)throw e;l(-1,e)}}else l(-1,\"No Transport\");function l(e,t,n,r){var i,o,a,s,u,l=t;h||(h=!0,d&&C.clearTimeout(d),c=void 0,p=r||\"\",T.readyState=0<e?4:0,i=200<=e&&e<300||304===e,n&&(s=function(e,t,n){var r,i,o,a,s=e.contents,u=e.dataTypes;while(\"*\"===u[0])u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader(\"Content-Type\"));if(r)for(i in s)if(s[i]&&s[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+\" \"+u[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==u[0]&&u.unshift(o),n[o]}(v,T,n)),!i&&-1<S.inArray(\"script\",v.dataTypes)&&S.inArray(\"json\",v.dataTypes)<0&&(v.converters[\"text script\"]=function(){}),s=function(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if(\"*\"===o)o=u;else if(\"*\"!==u&&u!==o){if(!(a=l[u+\" \"+o]||l[\"* \"+o]))for(i in l)if((s=i.split(\" \"))[1]===o&&(a=l[u+\" \"+s[0]]||l[\"* \"+s[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e[\"throws\"])t=a(t);else try{t=a(t)}catch(e){return{state:\"parsererror\",error:a?e:\"No conversion from \"+u+\" to \"+o}}}return{state:\"success\",data:t}}(v,s,T,i),i?(v.ifModified&&((u=T.getResponseHeader(\"Last-Modified\"))&&(S.lastModified[f]=u),(u=T.getResponseHeader(\"etag\"))&&(S.etag[f]=u)),204===e||\"HEAD\"===v.type?l=\"nocontent\":304===e?l=\"notmodified\":(l=s.state,o=s.data,i=!(a=s.error))):(a=l,!e&&l||(l=\"error\",e<0&&(e=0))),T.status=e,T.statusText=(t||l)+\"\",i?x.resolveWith(y,[o,l,T]):x.rejectWith(y,[T,l,a]),T.statusCode(w),w=void 0,g&&m.trigger(i?\"ajaxSuccess\":\"ajaxError\",[T,v,i?o:a]),b.fireWith(y,[T,l]),g&&(m.trigger(\"ajaxComplete\",[T,v]),--S.active||S.event.trigger(\"ajaxStop\")))}return T},getJSON:function(e,t,n){return S.get(e,t,n,\"json\")},getScript:function(e,t){return S.get(e,void 0,t,\"script\")}}),S.each([\"get\",\"post\"],function(e,i){S[i]=function(e,t,n,r){return m(t)&&(r=r||n,n=t,t=void 0),S.ajax(S.extend({url:e,type:i,dataType:r,data:t,success:n},S.isPlainObject(e)&&e))}}),S.ajaxPrefilter(function(e){var t;for(t in e.headers)\"content-type\"===t.toLowerCase()&&(e.contentType=e.headers[t]||\"\")}),S._evalUrl=function(e,t,n){return S.ajax({url:e,type:\"GET\",dataType:\"script\",cache:!0,async:!1,global:!1,converters:{\"text script\":function(){}},dataFilter:function(e){S.globalEval(e,t,n)}})},S.fn.extend({wrapAll:function(e){var t;return this[0]&&(m(e)&&(e=e.call(this[0])),t=S(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(n){return m(n)?this.each(function(e){S(this).wrapInner(n.call(this,e))}):this.each(function(){var e=S(this),t=e.contents();t.length?t.wrapAll(n):e.append(n)})},wrap:function(t){var n=m(t);return this.each(function(e){S(this).wrapAll(n?t.call(this,e):t)})},unwrap:function(e){return this.parent(e).not(\"body\").each(function(){S(this).replaceWith(this.childNodes)}),this}}),S.expr.pseudos.hidden=function(e){return!S.expr.pseudos.visible(e)},S.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},S.ajaxSettings.xhr=function(){try{return new C.XMLHttpRequest}catch(e){}};var Bt={0:200,1223:204},$t=S.ajaxSettings.xhr();y.cors=!!$t&&\"withCredentials\"in $t,y.ajax=$t=!!$t,S.ajaxTransport(function(i){var o,a;if(y.cors||$t&&!i.crossDomain)return{send:function(e,t){var n,r=i.xhr();if(r.open(i.type,i.url,i.async,i.username,i.password),i.xhrFields)for(n in i.xhrFields)r[n]=i.xhrFields[n];for(n in i.mimeType&&r.overrideMimeType&&r.overrideMimeType(i.mimeType),i.crossDomain||e[\"X-Requested-With\"]||(e[\"X-Requested-With\"]=\"XMLHttpRequest\"),e)r.setRequestHeader(n,e[n]);o=function(e){return function(){o&&(o=a=r.onload=r.onerror=r.onabort=r.ontimeout=r.onreadystatechange=null,\"abort\"===e?r.abort():\"error\"===e?\"number\"!=typeof r.status?t(0,\"error\"):t(r.status,r.statusText):t(Bt[r.status]||r.status,r.statusText,\"text\"!==(r.responseType||\"text\")||\"string\"!=typeof r.responseText?{binary:r.response}:{text:r.responseText},r.getAllResponseHeaders()))}},r.onload=o(),a=r.onerror=r.ontimeout=o(\"error\"),void 0!==r.onabort?r.onabort=a:r.onreadystatechange=function(){4===r.readyState&&C.setTimeout(function(){o&&a()})},o=o(\"abort\");try{r.send(i.hasContent&&i.data||null)}catch(e){if(o)throw e}},abort:function(){o&&o()}}}),S.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),S.ajaxSetup({accepts:{script:\"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript\"},contents:{script:/\\b(?:java|ecma)script\\b/},converters:{\"text script\":function(e){return S.globalEval(e),e}}}),S.ajaxPrefilter(\"script\",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type=\"GET\")}),S.ajaxTransport(\"script\",function(n){var r,i;if(n.crossDomain||n.scriptAttrs)return{send:function(e,t){r=S(\"<script>\").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on(\"load error\",i=function(e){r.remove(),i=null,e&&t(\"error\"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\\?(?=&|$)|\\?\\?/;S.ajaxSetup({jsonp:\"callback\",jsonpCallback:function(){var e=zt.pop()||S.expando+\"_\"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter(\"json jsonp\",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?\"url\":\"string\"==typeof e.data&&0===(e.contentType||\"\").indexOf(\"application/x-www-form-urlencoded\")&&Ut.test(e.data)&&\"data\");if(a||\"jsonp\"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,\"$1\"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?\"&\":\"?\")+e.jsonp+\"=\"+r),e.converters[\"script json\"]=function(){return o||S.error(r+\" was not called\"),o[0]},e.dataTypes[0]=\"json\",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),\"script\"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument(\"\").body).innerHTML=\"<form></form><form></form>\",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return\"string\"!=typeof e?[]:(\"boolean\"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument(\"\")).createElement(\"base\")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(\" \");return-1<s&&(r=ht(e.slice(s)),e=e.slice(0,s)),m(t)?(n=t,t=void 0):t&&\"object\"==typeof t&&(i=\"POST\"),0<a.length&&S.ajax({url:e,type:i||\"GET\",dataType:\"html\",data:t}).done(function(e){o=arguments,a.html(r?S(\"<div>\").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,\"position\"),c=S(e),f={};\"static\"===l&&(e.style.position=\"relative\"),s=c.offset(),o=S.css(e,\"top\"),u=S.css(e,\"left\"),(\"absolute\"===l||\"fixed\"===l)&&-1<(o+u).indexOf(\"auto\")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),\"using\"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if(\"fixed\"===S.css(r,\"position\"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&\"static\"===S.css(e,\"position\"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,\"borderTopWidth\",!0),i.left+=S.css(e,\"borderLeftWidth\",!0))}return{top:t.top-i.top-S.css(r,\"marginTop\",!0),left:t.left-i.left-S.css(r,\"marginLeft\",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&\"static\"===S.css(e,\"position\"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:\"pageXOffset\",scrollTop:\"pageYOffset\"},function(t,i){var o=\"pageYOffset\"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each([\"top\",\"left\"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+\"px\":t})}),S.each({Height:\"height\",Width:\"width\"},function(a,s){S.each({padding:\"inner\"+a,content:s,\"\":\"outer\"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||\"boolean\"!=typeof e),i=r||(!0===e||!0===t?\"margin\":\"border\");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf(\"outer\")?e[\"inner\"+a]:e.document.documentElement[\"client\"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body[\"scroll\"+a],r[\"scroll\"+a],e.body[\"offset\"+a],r[\"offset\"+a],r[\"client\"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each([\"ajaxStart\",\"ajaxStop\",\"ajaxComplete\",\"ajaxError\",\"ajaxSuccess\",\"ajaxSend\"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,\"**\"):this.off(t,e||\"**\",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each(\"blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu\".split(\" \"),function(e,n){S.fn[n]=function(e,t){return 0<arguments.length?this.on(n,null,e,t):this.trigger(n)}});var Xt=/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g;S.proxy=function(e,t){var n,r,i;if(\"string\"==typeof t&&(n=e[t],t=e,e=n),m(e))return r=s.call(arguments,2),(i=function(){return e.apply(t||this,r.concat(s.call(arguments)))}).guid=e.guid=e.guid||S.guid++,i},S.holdReady=function(e){e?S.readyWait++:S.ready(!0)},S.isArray=Array.isArray,S.parseJSON=JSON.parse,S.nodeName=A,S.isFunction=m,S.isWindow=x,S.camelCase=X,S.type=w,S.now=Date.now,S.isNumeric=function(e){var t=S.type(e);return(\"number\"===t||\"string\"===t)&&!isNaN(e-parseFloat(e))},S.trim=function(e){return null==e?\"\":(e+\"\").replace(Xt,\"\")},\"function\"==typeof define&&define.amd&&define(\"jquery\",[],function(){return S});var Vt=C.jQuery,Gt=C.$;return S.noConflict=function(e){return C.$===S&&(C.$=Gt),e&&C.jQuery===S&&(C.jQuery=Vt),S},\"undefined\"==typeof e&&(C.jQuery=C.$=S),S});\n"
  },
  {
    "path": "core/dbt/docs/build/html/_static/language_data.js",
    "content": "/*\n * language_data.js\n * ~~~~~~~~~~~~~~~~\n *\n * This script contains the language-specific data used by searchtools.js,\n * namely the list of stopwords, stemmer, scorer and splitter.\n *\n * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.\n * :license: BSD, see LICENSE for details.\n *\n */\n\nvar stopwords = [\"a\", \"and\", \"are\", \"as\", \"at\", \"be\", \"but\", \"by\", \"for\", \"if\", \"in\", \"into\", \"is\", \"it\", \"near\", \"no\", \"not\", \"of\", \"on\", \"or\", \"such\", \"that\", \"the\", \"their\", \"then\", \"there\", \"these\", \"they\", \"this\", \"to\", \"was\", \"will\", \"with\"];\n\n\n/* Non-minified version is copied as a separate JS file, is available */\n\n/**\n * Porter Stemmer\n */\nvar Stemmer = function() {\n\n  var step2list = {\n    ational: 'ate',\n    tional: 'tion',\n    enci: 'ence',\n    anci: 'ance',\n    izer: 'ize',\n    bli: 'ble',\n    alli: 'al',\n    entli: 'ent',\n    eli: 'e',\n    ousli: 'ous',\n    ization: 'ize',\n    ation: 'ate',\n    ator: 'ate',\n    alism: 'al',\n    iveness: 'ive',\n    fulness: 'ful',\n    ousness: 'ous',\n    aliti: 'al',\n    iviti: 'ive',\n    biliti: 'ble',\n    logi: 'log'\n  };\n\n  var step3list = {\n    icate: 'ic',\n    ative: '',\n    alize: 'al',\n    iciti: 'ic',\n    ical: 'ic',\n    ful: '',\n    ness: ''\n  };\n\n  var c = \"[^aeiou]\";          // consonant\n  var v = \"[aeiouy]\";          // vowel\n  var C = c + \"[^aeiouy]*\";    // consonant sequence\n  var V = v + \"[aeiou]*\";      // vowel sequence\n\n  var mgr0 = \"^(\" + C + \")?\" + V + C;                      // [C]VC... is m>0\n  var meq1 = \"^(\" + C + \")?\" + V + C + \"(\" + V + \")?$\";    // [C]VC[V] is m=1\n  var mgr1 = \"^(\" + C + \")?\" + V + C + V + C;              // [C]VCVC... is m>1\n  var s_v   = \"^(\" + C + \")?\" + v;                         // vowel in stem\n\n  this.stemWord = function (w) {\n    var stem;\n    var suffix;\n    var firstch;\n    var origword = w;\n\n    if (w.length < 3)\n      return w;\n\n    var re;\n    var re2;\n    var re3;\n    var re4;\n\n    firstch = w.substr(0,1);\n    if (firstch == \"y\")\n      w = firstch.toUpperCase() + w.substr(1);\n\n    // Step 1a\n    re = /^(.+?)(ss|i)es$/;\n    re2 = /^(.+?)([^s])s$/;\n\n    if (re.test(w))\n      w = w.replace(re,\"$1$2\");\n    else if (re2.test(w))\n      w = w.replace(re2,\"$1$2\");\n\n    // Step 1b\n    re = /^(.+?)eed$/;\n    re2 = /^(.+?)(ed|ing)$/;\n    if (re.test(w)) {\n      var fp = re.exec(w);\n      re = new RegExp(mgr0);\n      if (re.test(fp[1])) {\n        re = /.$/;\n        w = w.replace(re,\"\");\n      }\n    }\n    else if (re2.test(w)) {\n      var fp = re2.exec(w);\n      stem = fp[1];\n      re2 = new RegExp(s_v);\n      if (re2.test(stem)) {\n        w = stem;\n        re2 = /(at|bl|iz)$/;\n        re3 = new RegExp(\"([^aeiouylsz])\\\\1$\");\n        re4 = new RegExp(\"^\" + C + v + \"[^aeiouwxy]$\");\n        if (re2.test(w))\n          w = w + \"e\";\n        else if (re3.test(w)) {\n          re = /.$/;\n          w = w.replace(re,\"\");\n        }\n        else if (re4.test(w))\n          w = w + \"e\";\n      }\n    }\n\n    // Step 1c\n    re = /^(.+?)y$/;\n    if (re.test(w)) {\n      var fp = re.exec(w);\n      stem = fp[1];\n      re = new RegExp(s_v);\n      if (re.test(stem))\n        w = stem + \"i\";\n    }\n\n    // Step 2\n    re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;\n    if (re.test(w)) {\n      var fp = re.exec(w);\n      stem = fp[1];\n      suffix = fp[2];\n      re = new RegExp(mgr0);\n      if (re.test(stem))\n        w = stem + step2list[suffix];\n    }\n\n    // Step 3\n    re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;\n    if (re.test(w)) {\n      var fp = re.exec(w);\n      stem = fp[1];\n      suffix = fp[2];\n      re = new RegExp(mgr0);\n      if (re.test(stem))\n        w = stem + step3list[suffix];\n    }\n\n    // Step 4\n    re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;\n    re2 = /^(.+?)(s|t)(ion)$/;\n    if (re.test(w)) {\n      var fp = re.exec(w);\n      stem = fp[1];\n      re = new RegExp(mgr1);\n      if (re.test(stem))\n        w = stem;\n    }\n    else if (re2.test(w)) {\n      var fp = re2.exec(w);\n      stem = fp[1] + fp[2];\n      re2 = new RegExp(mgr1);\n      if (re2.test(stem))\n        w = stem;\n    }\n\n    // Step 5\n    re = /^(.+?)e$/;\n    if (re.test(w)) {\n      var fp = re.exec(w);\n      stem = fp[1];\n      re = new RegExp(mgr1);\n      re2 = new RegExp(meq1);\n      re3 = new RegExp(\"^\" + C + v + \"[^aeiouwxy]$\");\n      if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))\n        w = stem;\n    }\n    re = /ll$/;\n    re2 = new RegExp(mgr1);\n    if (re.test(w) && re2.test(w)) {\n      re = /.$/;\n      w = w.replace(re,\"\");\n    }\n\n    // and turn initial Y back to y\n    if (firstch == \"y\")\n      w = firstch.toLowerCase() + w.substr(1);\n    return w;\n  }\n}\n\n"
  },
  {
    "path": "core/dbt/docs/build/html/_static/pygments.css",
    "content": "pre { line-height: 125%; }\ntd.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\nspan.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\ntd.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\nspan.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n.highlight .hll { background-color: #ffffcc }\n.highlight { background: #f8f8f8; }\n.highlight .c { color: #8f5902; font-style: italic } /* Comment */\n.highlight .err { color: #a40000; border: 1px solid #ef2929 } /* Error */\n.highlight .g { color: #000000 } /* Generic */\n.highlight .k { color: #004461; font-weight: bold } /* Keyword */\n.highlight .l { color: #000000 } /* Literal */\n.highlight .n { color: #000000 } /* Name */\n.highlight .o { color: #582800 } /* Operator */\n.highlight .x { color: #000000 } /* Other */\n.highlight .p { color: #000000; font-weight: bold } /* Punctuation */\n.highlight .ch { color: #8f5902; font-style: italic } /* Comment.Hashbang */\n.highlight .cm { color: #8f5902; font-style: italic } /* Comment.Multiline */\n.highlight .cp { color: #8f5902 } /* Comment.Preproc */\n.highlight .cpf { color: #8f5902; font-style: italic } /* Comment.PreprocFile */\n.highlight .c1 { color: #8f5902; font-style: italic } /* Comment.Single */\n.highlight .cs { color: #8f5902; font-style: italic } /* Comment.Special */\n.highlight .gd { color: #a40000 } /* Generic.Deleted */\n.highlight .ge { color: #000000; font-style: italic } /* Generic.Emph */\n.highlight .gr { color: #ef2929 } /* Generic.Error */\n.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n.highlight .gi { color: #00A000 } /* Generic.Inserted */\n.highlight .go { color: #888888 } /* Generic.Output */\n.highlight .gp { color: #745334 } /* Generic.Prompt */\n.highlight .gs { color: #000000; font-weight: bold } /* Generic.Strong */\n.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n.highlight .gt { color: #a40000; font-weight: bold } /* Generic.Traceback */\n.highlight .kc { color: #004461; font-weight: bold } /* Keyword.Constant */\n.highlight .kd { color: #004461; font-weight: bold } /* Keyword.Declaration */\n.highlight .kn { color: #004461; font-weight: bold } /* Keyword.Namespace */\n.highlight .kp { color: #004461; font-weight: bold } /* Keyword.Pseudo */\n.highlight .kr { color: #004461; font-weight: bold } /* Keyword.Reserved */\n.highlight .kt { color: #004461; font-weight: bold } /* Keyword.Type */\n.highlight .ld { color: #000000 } /* Literal.Date */\n.highlight .m { color: #990000 } /* Literal.Number */\n.highlight .s { color: #4e9a06 } /* Literal.String */\n.highlight .na { color: #c4a000 } /* Name.Attribute */\n.highlight .nb { color: #004461 } /* Name.Builtin */\n.highlight .nc { color: #000000 } /* Name.Class */\n.highlight .no { color: #000000 } /* Name.Constant */\n.highlight .nd { color: #888888 } /* Name.Decorator */\n.highlight .ni { color: #ce5c00 } /* Name.Entity */\n.highlight .ne { color: #cc0000; font-weight: bold } /* Name.Exception */\n.highlight .nf { color: #000000 } /* Name.Function */\n.highlight .nl { color: #f57900 } /* Name.Label */\n.highlight .nn { color: #000000 } /* Name.Namespace */\n.highlight .nx { color: #000000 } /* Name.Other */\n.highlight .py { color: #000000 } /* Name.Property */\n.highlight .nt { color: #004461; font-weight: bold } /* Name.Tag */\n.highlight .nv { color: #000000 } /* Name.Variable */\n.highlight .ow { color: #004461; font-weight: bold } /* Operator.Word */\n.highlight .w { color: #f8f8f8; text-decoration: underline } /* Text.Whitespace */\n.highlight .mb { color: #990000 } /* Literal.Number.Bin */\n.highlight .mf { color: #990000 } /* Literal.Number.Float */\n.highlight .mh { color: #990000 } /* Literal.Number.Hex */\n.highlight .mi { color: #990000 } /* Literal.Number.Integer */\n.highlight .mo { color: #990000 } /* Literal.Number.Oct */\n.highlight .sa { color: #4e9a06 } /* Literal.String.Affix */\n.highlight .sb { color: #4e9a06 } /* Literal.String.Backtick */\n.highlight .sc { color: #4e9a06 } /* Literal.String.Char */\n.highlight .dl { color: #4e9a06 } /* Literal.String.Delimiter */\n.highlight .sd { color: #8f5902; font-style: italic } /* Literal.String.Doc */\n.highlight .s2 { color: #4e9a06 } /* Literal.String.Double */\n.highlight .se { color: #4e9a06 } /* Literal.String.Escape */\n.highlight .sh { color: #4e9a06 } /* Literal.String.Heredoc */\n.highlight .si { color: #4e9a06 } /* Literal.String.Interpol */\n.highlight .sx { color: #4e9a06 } /* Literal.String.Other */\n.highlight .sr { color: #4e9a06 } /* Literal.String.Regex */\n.highlight .s1 { color: #4e9a06 } /* Literal.String.Single */\n.highlight .ss { color: #4e9a06 } /* Literal.String.Symbol */\n.highlight .bp { color: #3465a4 } /* Name.Builtin.Pseudo */\n.highlight .fm { color: #000000 } /* Name.Function.Magic */\n.highlight .vc { color: #000000 } /* Name.Variable.Class */\n.highlight .vg { color: #000000 } /* Name.Variable.Global */\n.highlight .vi { color: #000000 } /* Name.Variable.Instance */\n.highlight .vm { color: #000000 } /* Name.Variable.Magic */\n.highlight .il { color: #990000 } /* Literal.Number.Integer.Long */"
  },
  {
    "path": "core/dbt/docs/build/html/_static/searchtools.js",
    "content": "/*\n * searchtools.js\n * ~~~~~~~~~~~~~~~~\n *\n * Sphinx JavaScript utilities for the full-text search.\n *\n * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.\n * :license: BSD, see LICENSE for details.\n *\n */\n\"use strict\";\n\n/**\n * Simple result scoring code.\n */\nif (typeof Scorer === \"undefined\") {\n  var Scorer = {\n    // Implement the following function to further tweak the score for each result\n    // The function takes a result array [docname, title, anchor, descr, score, filename]\n    // and returns the new score.\n    /*\n    score: result => {\n      const [docname, title, anchor, descr, score, filename] = result\n      return score\n    },\n    */\n\n    // query matches the full name of an object\n    objNameMatch: 11,\n    // or matches in the last dotted part of the object name\n    objPartialMatch: 6,\n    // Additive scores depending on the priority of the object\n    objPrio: {\n      0: 15, // used to be importantResults\n      1: 5, // used to be objectResults\n      2: -5, // used to be unimportantResults\n    },\n    //  Used when the priority is not in the mapping.\n    objPrioDefault: 0,\n\n    // query found in title\n    title: 15,\n    partialTitle: 7,\n    // query found in terms\n    term: 5,\n    partialTerm: 2,\n  };\n}\n\nconst _removeChildren = (element) => {\n  while (element && element.lastChild) element.removeChild(element.lastChild);\n};\n\n/**\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping\n */\nconst _escapeRegExp = (string) =>\n  string.replace(/[.*+\\-?^${}()|[\\]\\\\]/g, \"\\\\$&\"); // $& means the whole matched string\n\nconst _displayItem = (item, searchTerms) => {\n  const docBuilder = DOCUMENTATION_OPTIONS.BUILDER;\n  const docUrlRoot = DOCUMENTATION_OPTIONS.URL_ROOT;\n  const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX;\n  const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX;\n  const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY;\n\n  const [docName, title, anchor, descr, score, _filename] = item;\n\n  let listItem = document.createElement(\"li\");\n  let requestUrl;\n  let linkUrl;\n  if (docBuilder === \"dirhtml\") {\n    // dirhtml builder\n    let dirname = docName + \"/\";\n    if (dirname.match(/\\/index\\/$/))\n      dirname = dirname.substring(0, dirname.length - 6);\n    else if (dirname === \"index/\") dirname = \"\";\n    requestUrl = docUrlRoot + dirname;\n    linkUrl = requestUrl;\n  } else {\n    // normal html builders\n    requestUrl = docUrlRoot + docName + docFileSuffix;\n    linkUrl = docName + docLinkSuffix;\n  }\n  let linkEl = listItem.appendChild(document.createElement(\"a\"));\n  linkEl.href = linkUrl + anchor;\n  linkEl.dataset.score = score;\n  linkEl.innerHTML = title;\n  if (descr)\n    listItem.appendChild(document.createElement(\"span\")).innerHTML =\n      \" (\" + descr + \")\";\n  else if (showSearchSummary)\n    fetch(requestUrl)\n      .then((responseData) => responseData.text())\n      .then((data) => {\n        if (data)\n          listItem.appendChild(\n            Search.makeSearchSummary(data, searchTerms)\n          );\n      });\n  Search.output.appendChild(listItem);\n};\nconst _finishSearch = (resultCount) => {\n  Search.stopPulse();\n  Search.title.innerText = _(\"Search Results\");\n  if (!resultCount)\n    Search.status.innerText = Documentation.gettext(\n      \"Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories.\"\n    );\n  else\n    Search.status.innerText = _(\n      `Search finished, found ${resultCount} page(s) matching the search query.`\n    );\n};\nconst _displayNextItem = (\n  results,\n  resultCount,\n  searchTerms\n) => {\n  // results left, load the summary and display it\n  // this is intended to be dynamic (don't sub resultsCount)\n  if (results.length) {\n    _displayItem(results.pop(), searchTerms);\n    setTimeout(\n      () => _displayNextItem(results, resultCount, searchTerms),\n      5\n    );\n  }\n  // search finished, update title and status message\n  else _finishSearch(resultCount);\n};\n\n/**\n * Default splitQuery function. Can be overridden in ``sphinx.search`` with a\n * custom function per language.\n *\n * The regular expression works by splitting the string on consecutive characters\n * that are not Unicode letters, numbers, underscores, or emoji characters.\n * This is the same as ``\\W+`` in Python, preserving the surrogate pair area.\n */\nif (typeof splitQuery === \"undefined\") {\n  var splitQuery = (query) => query\n      .split(/[^\\p{Letter}\\p{Number}_\\p{Emoji_Presentation}]+/gu)\n      .filter(term => term)  // remove remaining empty strings\n}\n\n/**\n * Search Module\n */\nconst Search = {\n  _index: null,\n  _queued_query: null,\n  _pulse_status: -1,\n\n  htmlToText: (htmlString) => {\n    const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html');\n    htmlElement.querySelectorAll(\".headerlink\").forEach((el) => { el.remove() });\n    const docContent = htmlElement.querySelector('[role=\"main\"]');\n    if (docContent !== undefined) return docContent.textContent;\n    console.warn(\n      \"Content block not found. Sphinx search tries to obtain it via '[role=main]'. Could you check your theme or template.\"\n    );\n    return \"\";\n  },\n\n  init: () => {\n    const query = new URLSearchParams(window.location.search).get(\"q\");\n    document\n      .querySelectorAll('input[name=\"q\"]')\n      .forEach((el) => (el.value = query));\n    if (query) Search.performSearch(query);\n  },\n\n  loadIndex: (url) =>\n    (document.body.appendChild(document.createElement(\"script\")).src = url),\n\n  setIndex: (index) => {\n    Search._index = index;\n    if (Search._queued_query !== null) {\n      const query = Search._queued_query;\n      Search._queued_query = null;\n      Search.query(query);\n    }\n  },\n\n  hasIndex: () => Search._index !== null,\n\n  deferQuery: (query) => (Search._queued_query = query),\n\n  stopPulse: () => (Search._pulse_status = -1),\n\n  startPulse: () => {\n    if (Search._pulse_status >= 0) return;\n\n    const pulse = () => {\n      Search._pulse_status = (Search._pulse_status + 1) % 4;\n      Search.dots.innerText = \".\".repeat(Search._pulse_status);\n      if (Search._pulse_status >= 0) window.setTimeout(pulse, 500);\n    };\n    pulse();\n  },\n\n  /**\n   * perform a search for something (or wait until index is loaded)\n   */\n  performSearch: (query) => {\n    // create the required interface elements\n    const searchText = document.createElement(\"h2\");\n    searchText.textContent = _(\"Searching\");\n    const searchSummary = document.createElement(\"p\");\n    searchSummary.classList.add(\"search-summary\");\n    searchSummary.innerText = \"\";\n    const searchList = document.createElement(\"ul\");\n    searchList.classList.add(\"search\");\n\n    const out = document.getElementById(\"search-results\");\n    Search.title = out.appendChild(searchText);\n    Search.dots = Search.title.appendChild(document.createElement(\"span\"));\n    Search.status = out.appendChild(searchSummary);\n    Search.output = out.appendChild(searchList);\n\n    const searchProgress = document.getElementById(\"search-progress\");\n    // Some themes don't use the search progress node\n    if (searchProgress) {\n      searchProgress.innerText = _(\"Preparing search...\");\n    }\n    Search.startPulse();\n\n    // index already loaded, the browser was quick!\n    if (Search.hasIndex()) Search.query(query);\n    else Search.deferQuery(query);\n  },\n\n  /**\n   * execute search (requires search index to be loaded)\n   */\n  query: (query) => {\n    const filenames = Search._index.filenames;\n    const docNames = Search._index.docnames;\n    const titles = Search._index.titles;\n    const allTitles = Search._index.alltitles;\n    const indexEntries = Search._index.indexentries;\n\n    // stem the search terms and add them to the correct list\n    const stemmer = new Stemmer();\n    const searchTerms = new Set();\n    const excludedTerms = new Set();\n    const highlightTerms = new Set();\n    const objectTerms = new Set(splitQuery(query.toLowerCase().trim()));\n    splitQuery(query.trim()).forEach((queryTerm) => {\n      const queryTermLower = queryTerm.toLowerCase();\n\n      // maybe skip this \"word\"\n      // stopwords array is from language_data.js\n      if (\n        stopwords.indexOf(queryTermLower) !== -1 ||\n        queryTerm.match(/^\\d+$/)\n      )\n        return;\n\n      // stem the word\n      let word = stemmer.stemWord(queryTermLower);\n      // select the correct list\n      if (word[0] === \"-\") excludedTerms.add(word.substr(1));\n      else {\n        searchTerms.add(word);\n        highlightTerms.add(queryTermLower);\n      }\n    });\n\n    if (SPHINX_HIGHLIGHT_ENABLED) {  // set in sphinx_highlight.js\n      localStorage.setItem(\"sphinx_highlight_terms\", [...highlightTerms].join(\" \"))\n    }\n\n    // console.debug(\"SEARCH: searching for:\");\n    // console.info(\"required: \", [...searchTerms]);\n    // console.info(\"excluded: \", [...excludedTerms]);\n\n    // array of [docname, title, anchor, descr, score, filename]\n    let results = [];\n    _removeChildren(document.getElementById(\"search-progress\"));\n\n    const queryLower = query.toLowerCase();\n    for (const [title, foundTitles] of Object.entries(allTitles)) {\n      if (title.toLowerCase().includes(queryLower) && (queryLower.length >= title.length/2)) {\n        for (const [file, id] of foundTitles) {\n          let score = Math.round(100 * queryLower.length / title.length)\n          results.push([\n            docNames[file],\n            titles[file] !== title ? `${titles[file]} > ${title}` : title,\n            id !== null ? \"#\" + id : \"\",\n            null,\n            score,\n            filenames[file],\n          ]);\n        }\n      }\n    }\n\n    // search for explicit entries in index directives\n    for (const [entry, foundEntries] of Object.entries(indexEntries)) {\n      if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) {\n        for (const [file, id] of foundEntries) {\n          let score = Math.round(100 * queryLower.length / entry.length)\n          results.push([\n            docNames[file],\n            titles[file],\n            id ? \"#\" + id : \"\",\n            null,\n            score,\n            filenames[file],\n          ]);\n        }\n      }\n    }\n\n    // lookup as object\n    objectTerms.forEach((term) =>\n      results.push(...Search.performObjectSearch(term, objectTerms))\n    );\n\n    // lookup as search terms in fulltext\n    results.push(...Search.performTermsSearch(searchTerms, excludedTerms));\n\n    // let the scorer override scores with a custom scoring function\n    if (Scorer.score) results.forEach((item) => (item[4] = Scorer.score(item)));\n\n    // now sort the results by score (in opposite order of appearance, since the\n    // display function below uses pop() to retrieve items) and then\n    // alphabetically\n    results.sort((a, b) => {\n      const leftScore = a[4];\n      const rightScore = b[4];\n      if (leftScore === rightScore) {\n        // same score: sort alphabetically\n        const leftTitle = a[1].toLowerCase();\n        const rightTitle = b[1].toLowerCase();\n        if (leftTitle === rightTitle) return 0;\n        return leftTitle > rightTitle ? -1 : 1; // inverted is intentional\n      }\n      return leftScore > rightScore ? 1 : -1;\n    });\n\n    // remove duplicate search results\n    // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept\n    let seen = new Set();\n    results = results.reverse().reduce((acc, result) => {\n      let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(',');\n      if (!seen.has(resultStr)) {\n        acc.push(result);\n        seen.add(resultStr);\n      }\n      return acc;\n    }, []);\n\n    results = results.reverse();\n\n    // for debugging\n    //Search.lastresults = results.slice();  // a copy\n    // console.info(\"search results:\", Search.lastresults);\n\n    // print the results\n    _displayNextItem(results, results.length, searchTerms);\n  },\n\n  /**\n   * search for object names\n   */\n  performObjectSearch: (object, objectTerms) => {\n    const filenames = Search._index.filenames;\n    const docNames = Search._index.docnames;\n    const objects = Search._index.objects;\n    const objNames = Search._index.objnames;\n    const titles = Search._index.titles;\n\n    const results = [];\n\n    const objectSearchCallback = (prefix, match) => {\n      const name = match[4]\n      const fullname = (prefix ? prefix + \".\" : \"\") + name;\n      const fullnameLower = fullname.toLowerCase();\n      if (fullnameLower.indexOf(object) < 0) return;\n\n      let score = 0;\n      const parts = fullnameLower.split(\".\");\n\n      // check for different match types: exact matches of full name or\n      // \"last name\" (i.e. last dotted part)\n      if (fullnameLower === object || parts.slice(-1)[0] === object)\n        score += Scorer.objNameMatch;\n      else if (parts.slice(-1)[0].indexOf(object) > -1)\n        score += Scorer.objPartialMatch; // matches in last name\n\n      const objName = objNames[match[1]][2];\n      const title = titles[match[0]];\n\n      // If more than one term searched for, we require other words to be\n      // found in the name/title/description\n      const otherTerms = new Set(objectTerms);\n      otherTerms.delete(object);\n      if (otherTerms.size > 0) {\n        const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase();\n        if (\n          [...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0)\n        )\n          return;\n      }\n\n      let anchor = match[3];\n      if (anchor === \"\") anchor = fullname;\n      else if (anchor === \"-\") anchor = objNames[match[1]][1] + \"-\" + fullname;\n\n      const descr = objName + _(\", in \") + title;\n\n      // add custom score for some objects according to scorer\n      if (Scorer.objPrio.hasOwnProperty(match[2]))\n        score += Scorer.objPrio[match[2]];\n      else score += Scorer.objPrioDefault;\n\n      results.push([\n        docNames[match[0]],\n        fullname,\n        \"#\" + anchor,\n        descr,\n        score,\n        filenames[match[0]],\n      ]);\n    };\n    Object.keys(objects).forEach((prefix) =>\n      objects[prefix].forEach((array) =>\n        objectSearchCallback(prefix, array)\n      )\n    );\n    return results;\n  },\n\n  /**\n   * search for full-text terms in the index\n   */\n  performTermsSearch: (searchTerms, excludedTerms) => {\n    // prepare search\n    const terms = Search._index.terms;\n    const titleTerms = Search._index.titleterms;\n    const filenames = Search._index.filenames;\n    const docNames = Search._index.docnames;\n    const titles = Search._index.titles;\n\n    const scoreMap = new Map();\n    const fileMap = new Map();\n\n    // perform the search on the required terms\n    searchTerms.forEach((word) => {\n      const files = [];\n      const arr = [\n        { files: terms[word], score: Scorer.term },\n        { files: titleTerms[word], score: Scorer.title },\n      ];\n      // add support for partial matches\n      if (word.length > 2) {\n        const escapedWord = _escapeRegExp(word);\n        Object.keys(terms).forEach((term) => {\n          if (term.match(escapedWord) && !terms[word])\n            arr.push({ files: terms[term], score: Scorer.partialTerm });\n        });\n        Object.keys(titleTerms).forEach((term) => {\n          if (term.match(escapedWord) && !titleTerms[word])\n            arr.push({ files: titleTerms[word], score: Scorer.partialTitle });\n        });\n      }\n\n      // no match but word was a required one\n      if (arr.every((record) => record.files === undefined)) return;\n\n      // found search word in contents\n      arr.forEach((record) => {\n        if (record.files === undefined) return;\n\n        let recordFiles = record.files;\n        if (recordFiles.length === undefined) recordFiles = [recordFiles];\n        files.push(...recordFiles);\n\n        // set score for the word in each file\n        recordFiles.forEach((file) => {\n          if (!scoreMap.has(file)) scoreMap.set(file, {});\n          scoreMap.get(file)[word] = record.score;\n        });\n      });\n\n      // create the mapping\n      files.forEach((file) => {\n        if (fileMap.has(file) && fileMap.get(file).indexOf(word) === -1)\n          fileMap.get(file).push(word);\n        else fileMap.set(file, [word]);\n      });\n    });\n\n    // now check if the files don't contain excluded terms\n    const results = [];\n    for (const [file, wordList] of fileMap) {\n      // check if all requirements are matched\n\n      // as search terms with length < 3 are discarded\n      const filteredTermCount = [...searchTerms].filter(\n        (term) => term.length > 2\n      ).length;\n      if (\n        wordList.length !== searchTerms.size &&\n        wordList.length !== filteredTermCount\n      )\n        continue;\n\n      // ensure that none of the excluded terms is in the search result\n      if (\n        [...excludedTerms].some(\n          (term) =>\n            terms[term] === file ||\n            titleTerms[term] === file ||\n            (terms[term] || []).includes(file) ||\n            (titleTerms[term] || []).includes(file)\n        )\n      )\n        break;\n\n      // select one (max) score for the file.\n      const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w]));\n      // add result to the result list\n      results.push([\n        docNames[file],\n        titles[file],\n        \"\",\n        null,\n        score,\n        filenames[file],\n      ]);\n    }\n    return results;\n  },\n\n  /**\n   * helper function to return a node containing the\n   * search summary for a given text. keywords is a list\n   * of stemmed words.\n   */\n  makeSearchSummary: (htmlText, keywords) => {\n    const text = Search.htmlToText(htmlText);\n    if (text === \"\") return null;\n\n    const textLower = text.toLowerCase();\n    const actualStartPosition = [...keywords]\n      .map((k) => textLower.indexOf(k.toLowerCase()))\n      .filter((i) => i > -1)\n      .slice(-1)[0];\n    const startWithContext = Math.max(actualStartPosition - 120, 0);\n\n    const top = startWithContext === 0 ? \"\" : \"...\";\n    const tail = startWithContext + 240 < text.length ? \"...\" : \"\";\n\n    let summary = document.createElement(\"p\");\n    summary.classList.add(\"context\");\n    summary.textContent = top + text.substr(startWithContext, 240).trim() + tail;\n\n    return summary;\n  },\n};\n\n_ready(Search.init);\n"
  },
  {
    "path": "core/dbt/docs/build/html/_static/sphinx_highlight.js",
    "content": "/* Highlighting utilities for Sphinx HTML documentation. */\n\"use strict\";\n\nconst SPHINX_HIGHLIGHT_ENABLED = true\n\n/**\n * highlight a given string on a node by wrapping it in\n * span elements with the given class name.\n */\nconst _highlight = (node, addItems, text, className) => {\n  if (node.nodeType === Node.TEXT_NODE) {\n    const val = node.nodeValue;\n    const parent = node.parentNode;\n    const pos = val.toLowerCase().indexOf(text);\n    if (\n      pos >= 0 &&\n      !parent.classList.contains(className) &&\n      !parent.classList.contains(\"nohighlight\")\n    ) {\n      let span;\n\n      const closestNode = parent.closest(\"body, svg, foreignObject\");\n      const isInSVG = closestNode && closestNode.matches(\"svg\");\n      if (isInSVG) {\n        span = document.createElementNS(\"http://www.w3.org/2000/svg\", \"tspan\");\n      } else {\n        span = document.createElement(\"span\");\n        span.classList.add(className);\n      }\n\n      span.appendChild(document.createTextNode(val.substr(pos, text.length)));\n      parent.insertBefore(\n        span,\n        parent.insertBefore(\n          document.createTextNode(val.substr(pos + text.length)),\n          node.nextSibling\n        )\n      );\n      node.nodeValue = val.substr(0, pos);\n\n      if (isInSVG) {\n        const rect = document.createElementNS(\n          \"http://www.w3.org/2000/svg\",\n          \"rect\"\n        );\n        const bbox = parent.getBBox();\n        rect.x.baseVal.value = bbox.x;\n        rect.y.baseVal.value = bbox.y;\n        rect.width.baseVal.value = bbox.width;\n        rect.height.baseVal.value = bbox.height;\n        rect.setAttribute(\"class\", className);\n        addItems.push({ parent: parent, target: rect });\n      }\n    }\n  } else if (node.matches && !node.matches(\"button, select, textarea\")) {\n    node.childNodes.forEach((el) => _highlight(el, addItems, text, className));\n  }\n};\nconst _highlightText = (thisNode, text, className) => {\n  let addItems = [];\n  _highlight(thisNode, addItems, text, className);\n  addItems.forEach((obj) =>\n    obj.parent.insertAdjacentElement(\"beforebegin\", obj.target)\n  );\n};\n\n/**\n * Small JavaScript module for the documentation.\n */\nconst SphinxHighlight = {\n\n  /**\n   * highlight the search words provided in localstorage in the text\n   */\n  highlightSearchWords: () => {\n    if (!SPHINX_HIGHLIGHT_ENABLED) return;  // bail if no highlight\n\n    // get and clear terms from localstorage\n    const url = new URL(window.location);\n    const highlight =\n        localStorage.getItem(\"sphinx_highlight_terms\")\n        || url.searchParams.get(\"highlight\")\n        || \"\";\n    localStorage.removeItem(\"sphinx_highlight_terms\")\n    url.searchParams.delete(\"highlight\");\n    window.history.replaceState({}, \"\", url);\n\n    // get individual terms from highlight string\n    const terms = highlight.toLowerCase().split(/\\s+/).filter(x => x);\n    if (terms.length === 0) return; // nothing to do\n\n    // There should never be more than one element matching \"div.body\"\n    const divBody = document.querySelectorAll(\"div.body\");\n    const body = divBody.length ? divBody[0] : document.querySelector(\"body\");\n    window.setTimeout(() => {\n      terms.forEach((term) => _highlightText(body, term, \"highlighted\"));\n    }, 10);\n\n    const searchBox = document.getElementById(\"searchbox\");\n    if (searchBox === null) return;\n    searchBox.appendChild(\n      document\n        .createRange()\n        .createContextualFragment(\n          '<p class=\"highlight-link\">' +\n            '<a href=\"javascript:SphinxHighlight.hideSearchWords()\">' +\n            _(\"Hide Search Matches\") +\n            \"</a></p>\"\n        )\n    );\n  },\n\n  /**\n   * helper function to hide the search marks again\n   */\n  hideSearchWords: () => {\n    document\n      .querySelectorAll(\"#searchbox .highlight-link\")\n      .forEach((el) => el.remove());\n    document\n      .querySelectorAll(\"span.highlighted\")\n      .forEach((el) => el.classList.remove(\"highlighted\"));\n    localStorage.removeItem(\"sphinx_highlight_terms\")\n  },\n\n  initEscapeListener: () => {\n    // only install a listener if it is really needed\n    if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return;\n\n    document.addEventListener(\"keydown\", (event) => {\n      // bail for input elements\n      if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return;\n      // bail with special keys\n      if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return;\n      if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === \"Escape\")) {\n        SphinxHighlight.hideSearchWords();\n        event.preventDefault();\n      }\n    });\n  },\n};\n\n_ready(SphinxHighlight.highlightSearchWords);\n_ready(SphinxHighlight.initEscapeListener);\n"
  },
  {
    "path": "core/dbt/docs/build/html/_static/underscore-1.13.1.js",
    "content": "(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n  typeof define === 'function' && define.amd ? define('underscore', factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, (function () {\n    var current = global._;\n    var exports = global._ = factory();\n    exports.noConflict = function () { global._ = current; return exports; };\n  }()));\n}(this, (function () {\n  //     Underscore.js 1.13.1\n  //     https://underscorejs.org\n  //     (c) 2009-2021 Jeremy Ashkenas, Julian Gonggrijp, and DocumentCloud and Investigative Reporters & Editors\n  //     Underscore may be freely distributed under the MIT license.\n\n  // Current version.\n  var VERSION = '1.13.1';\n\n  // Establish the root object, `window` (`self`) in the browser, `global`\n  // on the server, or `this` in some virtual machines. We use `self`\n  // instead of `window` for `WebWorker` support.\n  var root = typeof self == 'object' && self.self === self && self ||\n            typeof global == 'object' && global.global === global && global ||\n            Function('return this')() ||\n            {};\n\n  // Save bytes in the minified (but not gzipped) version:\n  var ArrayProto = Array.prototype, ObjProto = Object.prototype;\n  var SymbolProto = typeof Symbol !== 'undefined' ? Symbol.prototype : null;\n\n  // Create quick reference variables for speed access to core prototypes.\n  var push = ArrayProto.push,\n      slice = ArrayProto.slice,\n      toString = ObjProto.toString,\n      hasOwnProperty = ObjProto.hasOwnProperty;\n\n  // Modern feature detection.\n  var supportsArrayBuffer = typeof ArrayBuffer !== 'undefined',\n      supportsDataView = typeof DataView !== 'undefined';\n\n  // All **ECMAScript 5+** native function implementations that we hope to use\n  // are declared here.\n  var nativeIsArray = Array.isArray,\n      nativeKeys = Object.keys,\n      nativeCreate = Object.create,\n      nativeIsView = supportsArrayBuffer && ArrayBuffer.isView;\n\n  // Create references to these builtin functions because we override them.\n  var _isNaN = isNaN,\n      _isFinite = isFinite;\n\n  // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed.\n  var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString');\n  var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',\n    'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];\n\n  // The largest integer that can be represented exactly.\n  var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;\n\n  // Some functions take a variable number of arguments, or a few expected\n  // arguments at the beginning and then a variable number of values to operate\n  // on. This helper accumulates all remaining arguments past the function’s\n  // argument length (or an explicit `startIndex`), into an array that becomes\n  // the last argument. Similar to ES6’s \"rest parameter\".\n  function restArguments(func, startIndex) {\n    startIndex = startIndex == null ? func.length - 1 : +startIndex;\n    return function() {\n      var length = Math.max(arguments.length - startIndex, 0),\n          rest = Array(length),\n          index = 0;\n      for (; index < length; index++) {\n        rest[index] = arguments[index + startIndex];\n      }\n      switch (startIndex) {\n        case 0: return func.call(this, rest);\n        case 1: return func.call(this, arguments[0], rest);\n        case 2: return func.call(this, arguments[0], arguments[1], rest);\n      }\n      var args = Array(startIndex + 1);\n      for (index = 0; index < startIndex; index++) {\n        args[index] = arguments[index];\n      }\n      args[startIndex] = rest;\n      return func.apply(this, args);\n    };\n  }\n\n  // Is a given variable an object?\n  function isObject(obj) {\n    var type = typeof obj;\n    return type === 'function' || type === 'object' && !!obj;\n  }\n\n  // Is a given value equal to null?\n  function isNull(obj) {\n    return obj === null;\n  }\n\n  // Is a given variable undefined?\n  function isUndefined(obj) {\n    return obj === void 0;\n  }\n\n  // Is a given value a boolean?\n  function isBoolean(obj) {\n    return obj === true || obj === false || toString.call(obj) === '[object Boolean]';\n  }\n\n  // Is a given value a DOM element?\n  function isElement(obj) {\n    return !!(obj && obj.nodeType === 1);\n  }\n\n  // Internal function for creating a `toString`-based type tester.\n  function tagTester(name) {\n    var tag = '[object ' + name + ']';\n    return function(obj) {\n      return toString.call(obj) === tag;\n    };\n  }\n\n  var isString = tagTester('String');\n\n  var isNumber = tagTester('Number');\n\n  var isDate = tagTester('Date');\n\n  var isRegExp = tagTester('RegExp');\n\n  var isError = tagTester('Error');\n\n  var isSymbol = tagTester('Symbol');\n\n  var isArrayBuffer = tagTester('ArrayBuffer');\n\n  var isFunction = tagTester('Function');\n\n  // Optimize `isFunction` if appropriate. Work around some `typeof` bugs in old\n  // v8, IE 11 (#1621), Safari 8 (#1929), and PhantomJS (#2236).\n  var nodelist = root.document && root.document.childNodes;\n  if (typeof /./ != 'function' && typeof Int8Array != 'object' && typeof nodelist != 'function') {\n    isFunction = function(obj) {\n      return typeof obj == 'function' || false;\n    };\n  }\n\n  var isFunction$1 = isFunction;\n\n  var hasObjectTag = tagTester('Object');\n\n  // In IE 10 - Edge 13, `DataView` has string tag `'[object Object]'`.\n  // In IE 11, the most common among them, this problem also applies to\n  // `Map`, `WeakMap` and `Set`.\n  var hasStringTagBug = (\n        supportsDataView && hasObjectTag(new DataView(new ArrayBuffer(8)))\n      ),\n      isIE11 = (typeof Map !== 'undefined' && hasObjectTag(new Map));\n\n  var isDataView = tagTester('DataView');\n\n  // In IE 10 - Edge 13, we need a different heuristic\n  // to determine whether an object is a `DataView`.\n  function ie10IsDataView(obj) {\n    return obj != null && isFunction$1(obj.getInt8) && isArrayBuffer(obj.buffer);\n  }\n\n  var isDataView$1 = (hasStringTagBug ? ie10IsDataView : isDataView);\n\n  // Is a given value an array?\n  // Delegates to ECMA5's native `Array.isArray`.\n  var isArray = nativeIsArray || tagTester('Array');\n\n  // Internal function to check whether `key` is an own property name of `obj`.\n  function has$1(obj, key) {\n    return obj != null && hasOwnProperty.call(obj, key);\n  }\n\n  var isArguments = tagTester('Arguments');\n\n  // Define a fallback version of the method in browsers (ahem, IE < 9), where\n  // there isn't any inspectable \"Arguments\" type.\n  (function() {\n    if (!isArguments(arguments)) {\n      isArguments = function(obj) {\n        return has$1(obj, 'callee');\n      };\n    }\n  }());\n\n  var isArguments$1 = isArguments;\n\n  // Is a given object a finite number?\n  function isFinite$1(obj) {\n    return !isSymbol(obj) && _isFinite(obj) && !isNaN(parseFloat(obj));\n  }\n\n  // Is the given value `NaN`?\n  function isNaN$1(obj) {\n    return isNumber(obj) && _isNaN(obj);\n  }\n\n  // Predicate-generating function. Often useful outside of Underscore.\n  function constant(value) {\n    return function() {\n      return value;\n    };\n  }\n\n  // Common internal logic for `isArrayLike` and `isBufferLike`.\n  function createSizePropertyCheck(getSizeProperty) {\n    return function(collection) {\n      var sizeProperty = getSizeProperty(collection);\n      return typeof sizeProperty == 'number' && sizeProperty >= 0 && sizeProperty <= MAX_ARRAY_INDEX;\n    }\n  }\n\n  // Internal helper to generate a function to obtain property `key` from `obj`.\n  function shallowProperty(key) {\n    return function(obj) {\n      return obj == null ? void 0 : obj[key];\n    };\n  }\n\n  // Internal helper to obtain the `byteLength` property of an object.\n  var getByteLength = shallowProperty('byteLength');\n\n  // Internal helper to determine whether we should spend extensive checks against\n  // `ArrayBuffer` et al.\n  var isBufferLike = createSizePropertyCheck(getByteLength);\n\n  // Is a given value a typed array?\n  var typedArrayPattern = /\\[object ((I|Ui)nt(8|16|32)|Float(32|64)|Uint8Clamped|Big(I|Ui)nt64)Array\\]/;\n  function isTypedArray(obj) {\n    // `ArrayBuffer.isView` is the most future-proof, so use it when available.\n    // Otherwise, fall back on the above regular expression.\n    return nativeIsView ? (nativeIsView(obj) && !isDataView$1(obj)) :\n                  isBufferLike(obj) && typedArrayPattern.test(toString.call(obj));\n  }\n\n  var isTypedArray$1 = supportsArrayBuffer ? isTypedArray : constant(false);\n\n  // Internal helper to obtain the `length` property of an object.\n  var getLength = shallowProperty('length');\n\n  // Internal helper to create a simple lookup structure.\n  // `collectNonEnumProps` used to depend on `_.contains`, but this led to\n  // circular imports. `emulatedSet` is a one-off solution that only works for\n  // arrays of strings.\n  function emulatedSet(keys) {\n    var hash = {};\n    for (var l = keys.length, i = 0; i < l; ++i) hash[keys[i]] = true;\n    return {\n      contains: function(key) { return hash[key]; },\n      push: function(key) {\n        hash[key] = true;\n        return keys.push(key);\n      }\n    };\n  }\n\n  // Internal helper. Checks `keys` for the presence of keys in IE < 9 that won't\n  // be iterated by `for key in ...` and thus missed. Extends `keys` in place if\n  // needed.\n  function collectNonEnumProps(obj, keys) {\n    keys = emulatedSet(keys);\n    var nonEnumIdx = nonEnumerableProps.length;\n    var constructor = obj.constructor;\n    var proto = isFunction$1(constructor) && constructor.prototype || ObjProto;\n\n    // Constructor is a special case.\n    var prop = 'constructor';\n    if (has$1(obj, prop) && !keys.contains(prop)) keys.push(prop);\n\n    while (nonEnumIdx--) {\n      prop = nonEnumerableProps[nonEnumIdx];\n      if (prop in obj && obj[prop] !== proto[prop] && !keys.contains(prop)) {\n        keys.push(prop);\n      }\n    }\n  }\n\n  // Retrieve the names of an object's own properties.\n  // Delegates to **ECMAScript 5**'s native `Object.keys`.\n  function keys(obj) {\n    if (!isObject(obj)) return [];\n    if (nativeKeys) return nativeKeys(obj);\n    var keys = [];\n    for (var key in obj) if (has$1(obj, key)) keys.push(key);\n    // Ahem, IE < 9.\n    if (hasEnumBug) collectNonEnumProps(obj, keys);\n    return keys;\n  }\n\n  // Is a given array, string, or object empty?\n  // An \"empty\" object has no enumerable own-properties.\n  function isEmpty(obj) {\n    if (obj == null) return true;\n    // Skip the more expensive `toString`-based type checks if `obj` has no\n    // `.length`.\n    var length = getLength(obj);\n    if (typeof length == 'number' && (\n      isArray(obj) || isString(obj) || isArguments$1(obj)\n    )) return length === 0;\n    return getLength(keys(obj)) === 0;\n  }\n\n  // Returns whether an object has a given set of `key:value` pairs.\n  function isMatch(object, attrs) {\n    var _keys = keys(attrs), length = _keys.length;\n    if (object == null) return !length;\n    var obj = Object(object);\n    for (var i = 0; i < length; i++) {\n      var key = _keys[i];\n      if (attrs[key] !== obj[key] || !(key in obj)) return false;\n    }\n    return true;\n  }\n\n  // If Underscore is called as a function, it returns a wrapped object that can\n  // be used OO-style. This wrapper holds altered versions of all functions added\n  // through `_.mixin`. Wrapped objects may be chained.\n  function _$1(obj) {\n    if (obj instanceof _$1) return obj;\n    if (!(this instanceof _$1)) return new _$1(obj);\n    this._wrapped = obj;\n  }\n\n  _$1.VERSION = VERSION;\n\n  // Extracts the result from a wrapped and chained object.\n  _$1.prototype.value = function() {\n    return this._wrapped;\n  };\n\n  // Provide unwrapping proxies for some methods used in engine operations\n  // such as arithmetic and JSON stringification.\n  _$1.prototype.valueOf = _$1.prototype.toJSON = _$1.prototype.value;\n\n  _$1.prototype.toString = function() {\n    return String(this._wrapped);\n  };\n\n  // Internal function to wrap or shallow-copy an ArrayBuffer,\n  // typed array or DataView to a new view, reusing the buffer.\n  function toBufferView(bufferSource) {\n    return new Uint8Array(\n      bufferSource.buffer || bufferSource,\n      bufferSource.byteOffset || 0,\n      getByteLength(bufferSource)\n    );\n  }\n\n  // We use this string twice, so give it a name for minification.\n  var tagDataView = '[object DataView]';\n\n  // Internal recursive comparison function for `_.isEqual`.\n  function eq(a, b, aStack, bStack) {\n    // Identical objects are equal. `0 === -0`, but they aren't identical.\n    // See the [Harmony `egal` proposal](https://wiki.ecmascript.org/doku.php?id=harmony:egal).\n    if (a === b) return a !== 0 || 1 / a === 1 / b;\n    // `null` or `undefined` only equal to itself (strict comparison).\n    if (a == null || b == null) return false;\n    // `NaN`s are equivalent, but non-reflexive.\n    if (a !== a) return b !== b;\n    // Exhaust primitive checks\n    var type = typeof a;\n    if (type !== 'function' && type !== 'object' && typeof b != 'object') return false;\n    return deepEq(a, b, aStack, bStack);\n  }\n\n  // Internal recursive comparison function for `_.isEqual`.\n  function deepEq(a, b, aStack, bStack) {\n    // Unwrap any wrapped objects.\n    if (a instanceof _$1) a = a._wrapped;\n    if (b instanceof _$1) b = b._wrapped;\n    // Compare `[[Class]]` names.\n    var className = toString.call(a);\n    if (className !== toString.call(b)) return false;\n    // Work around a bug in IE 10 - Edge 13.\n    if (hasStringTagBug && className == '[object Object]' && isDataView$1(a)) {\n      if (!isDataView$1(b)) return false;\n      className = tagDataView;\n    }\n    switch (className) {\n      // These types are compared by value.\n      case '[object RegExp]':\n        // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')\n      case '[object String]':\n        // Primitives and their corresponding object wrappers are equivalent; thus, `\"5\"` is\n        // equivalent to `new String(\"5\")`.\n        return '' + a === '' + b;\n      case '[object Number]':\n        // `NaN`s are equivalent, but non-reflexive.\n        // Object(NaN) is equivalent to NaN.\n        if (+a !== +a) return +b !== +b;\n        // An `egal` comparison is performed for other numeric values.\n        return +a === 0 ? 1 / +a === 1 / b : +a === +b;\n      case '[object Date]':\n      case '[object Boolean]':\n        // Coerce dates and booleans to numeric primitive values. Dates are compared by their\n        // millisecond representations. Note that invalid dates with millisecond representations\n        // of `NaN` are not equivalent.\n        return +a === +b;\n      case '[object Symbol]':\n        return SymbolProto.valueOf.call(a) === SymbolProto.valueOf.call(b);\n      case '[object ArrayBuffer]':\n      case tagDataView:\n        // Coerce to typed array so we can fall through.\n        return deepEq(toBufferView(a), toBufferView(b), aStack, bStack);\n    }\n\n    var areArrays = className === '[object Array]';\n    if (!areArrays && isTypedArray$1(a)) {\n        var byteLength = getByteLength(a);\n        if (byteLength !== getByteLength(b)) return false;\n        if (a.buffer === b.buffer && a.byteOffset === b.byteOffset) return true;\n        areArrays = true;\n    }\n    if (!areArrays) {\n      if (typeof a != 'object' || typeof b != 'object') return false;\n\n      // Objects with different constructors are not equivalent, but `Object`s or `Array`s\n      // from different frames are.\n      var aCtor = a.constructor, bCtor = b.constructor;\n      if (aCtor !== bCtor && !(isFunction$1(aCtor) && aCtor instanceof aCtor &&\n                               isFunction$1(bCtor) && bCtor instanceof bCtor)\n                          && ('constructor' in a && 'constructor' in b)) {\n        return false;\n      }\n    }\n    // Assume equality for cyclic structures. The algorithm for detecting cyclic\n    // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.\n\n    // Initializing stack of traversed objects.\n    // It's done here since we only need them for objects and arrays comparison.\n    aStack = aStack || [];\n    bStack = bStack || [];\n    var length = aStack.length;\n    while (length--) {\n      // Linear search. Performance is inversely proportional to the number of\n      // unique nested structures.\n      if (aStack[length] === a) return bStack[length] === b;\n    }\n\n    // Add the first object to the stack of traversed objects.\n    aStack.push(a);\n    bStack.push(b);\n\n    // Recursively compare objects and arrays.\n    if (areArrays) {\n      // Compare array lengths to determine if a deep comparison is necessary.\n      length = a.length;\n      if (length !== b.length) return false;\n      // Deep compare the contents, ignoring non-numeric properties.\n      while (length--) {\n        if (!eq(a[length], b[length], aStack, bStack)) return false;\n      }\n    } else {\n      // Deep compare objects.\n      var _keys = keys(a), key;\n      length = _keys.length;\n      // Ensure that both objects contain the same number of properties before comparing deep equality.\n      if (keys(b).length !== length) return false;\n      while (length--) {\n        // Deep compare each member\n        key = _keys[length];\n        if (!(has$1(b, key) && eq(a[key], b[key], aStack, bStack))) return false;\n      }\n    }\n    // Remove the first object from the stack of traversed objects.\n    aStack.pop();\n    bStack.pop();\n    return true;\n  }\n\n  // Perform a deep comparison to check if two objects are equal.\n  function isEqual(a, b) {\n    return eq(a, b);\n  }\n\n  // Retrieve all the enumerable property names of an object.\n  function allKeys(obj) {\n    if (!isObject(obj)) return [];\n    var keys = [];\n    for (var key in obj) keys.push(key);\n    // Ahem, IE < 9.\n    if (hasEnumBug) collectNonEnumProps(obj, keys);\n    return keys;\n  }\n\n  // Since the regular `Object.prototype.toString` type tests don't work for\n  // some types in IE 11, we use a fingerprinting heuristic instead, based\n  // on the methods. It's not great, but it's the best we got.\n  // The fingerprint method lists are defined below.\n  function ie11fingerprint(methods) {\n    var length = getLength(methods);\n    return function(obj) {\n      if (obj == null) return false;\n      // `Map`, `WeakMap` and `Set` have no enumerable keys.\n      var keys = allKeys(obj);\n      if (getLength(keys)) return false;\n      for (var i = 0; i < length; i++) {\n        if (!isFunction$1(obj[methods[i]])) return false;\n      }\n      // If we are testing against `WeakMap`, we need to ensure that\n      // `obj` doesn't have a `forEach` method in order to distinguish\n      // it from a regular `Map`.\n      return methods !== weakMapMethods || !isFunction$1(obj[forEachName]);\n    };\n  }\n\n  // In the interest of compact minification, we write\n  // each string in the fingerprints only once.\n  var forEachName = 'forEach',\n      hasName = 'has',\n      commonInit = ['clear', 'delete'],\n      mapTail = ['get', hasName, 'set'];\n\n  // `Map`, `WeakMap` and `Set` each have slightly different\n  // combinations of the above sublists.\n  var mapMethods = commonInit.concat(forEachName, mapTail),\n      weakMapMethods = commonInit.concat(mapTail),\n      setMethods = ['add'].concat(commonInit, forEachName, hasName);\n\n  var isMap = isIE11 ? ie11fingerprint(mapMethods) : tagTester('Map');\n\n  var isWeakMap = isIE11 ? ie11fingerprint(weakMapMethods) : tagTester('WeakMap');\n\n  var isSet = isIE11 ? ie11fingerprint(setMethods) : tagTester('Set');\n\n  var isWeakSet = tagTester('WeakSet');\n\n  // Retrieve the values of an object's properties.\n  function values(obj) {\n    var _keys = keys(obj);\n    var length = _keys.length;\n    var values = Array(length);\n    for (var i = 0; i < length; i++) {\n      values[i] = obj[_keys[i]];\n    }\n    return values;\n  }\n\n  // Convert an object into a list of `[key, value]` pairs.\n  // The opposite of `_.object` with one argument.\n  function pairs(obj) {\n    var _keys = keys(obj);\n    var length = _keys.length;\n    var pairs = Array(length);\n    for (var i = 0; i < length; i++) {\n      pairs[i] = [_keys[i], obj[_keys[i]]];\n    }\n    return pairs;\n  }\n\n  // Invert the keys and values of an object. The values must be serializable.\n  function invert(obj) {\n    var result = {};\n    var _keys = keys(obj);\n    for (var i = 0, length = _keys.length; i < length; i++) {\n      result[obj[_keys[i]]] = _keys[i];\n    }\n    return result;\n  }\n\n  // Return a sorted list of the function names available on the object.\n  function functions(obj) {\n    var names = [];\n    for (var key in obj) {\n      if (isFunction$1(obj[key])) names.push(key);\n    }\n    return names.sort();\n  }\n\n  // An internal function for creating assigner functions.\n  function createAssigner(keysFunc, defaults) {\n    return function(obj) {\n      var length = arguments.length;\n      if (defaults) obj = Object(obj);\n      if (length < 2 || obj == null) return obj;\n      for (var index = 1; index < length; index++) {\n        var source = arguments[index],\n            keys = keysFunc(source),\n            l = keys.length;\n        for (var i = 0; i < l; i++) {\n          var key = keys[i];\n          if (!defaults || obj[key] === void 0) obj[key] = source[key];\n        }\n      }\n      return obj;\n    };\n  }\n\n  // Extend a given object with all the properties in passed-in object(s).\n  var extend = createAssigner(allKeys);\n\n  // Assigns a given object with all the own properties in the passed-in\n  // object(s).\n  // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)\n  var extendOwn = createAssigner(keys);\n\n  // Fill in a given object with default properties.\n  var defaults = createAssigner(allKeys, true);\n\n  // Create a naked function reference for surrogate-prototype-swapping.\n  function ctor() {\n    return function(){};\n  }\n\n  // An internal function for creating a new object that inherits from another.\n  function baseCreate(prototype) {\n    if (!isObject(prototype)) return {};\n    if (nativeCreate) return nativeCreate(prototype);\n    var Ctor = ctor();\n    Ctor.prototype = prototype;\n    var result = new Ctor;\n    Ctor.prototype = null;\n    return result;\n  }\n\n  // Creates an object that inherits from the given prototype object.\n  // If additional properties are provided then they will be added to the\n  // created object.\n  function create(prototype, props) {\n    var result = baseCreate(prototype);\n    if (props) extendOwn(result, props);\n    return result;\n  }\n\n  // Create a (shallow-cloned) duplicate of an object.\n  function clone(obj) {\n    if (!isObject(obj)) return obj;\n    return isArray(obj) ? obj.slice() : extend({}, obj);\n  }\n\n  // Invokes `interceptor` with the `obj` and then returns `obj`.\n  // The primary purpose of this method is to \"tap into\" a method chain, in\n  // order to perform operations on intermediate results within the chain.\n  function tap(obj, interceptor) {\n    interceptor(obj);\n    return obj;\n  }\n\n  // Normalize a (deep) property `path` to array.\n  // Like `_.iteratee`, this function can be customized.\n  function toPath$1(path) {\n    return isArray(path) ? path : [path];\n  }\n  _$1.toPath = toPath$1;\n\n  // Internal wrapper for `_.toPath` to enable minification.\n  // Similar to `cb` for `_.iteratee`.\n  function toPath(path) {\n    return _$1.toPath(path);\n  }\n\n  // Internal function to obtain a nested property in `obj` along `path`.\n  function deepGet(obj, path) {\n    var length = path.length;\n    for (var i = 0; i < length; i++) {\n      if (obj == null) return void 0;\n      obj = obj[path[i]];\n    }\n    return length ? obj : void 0;\n  }\n\n  // Get the value of the (deep) property on `path` from `object`.\n  // If any property in `path` does not exist or if the value is\n  // `undefined`, return `defaultValue` instead.\n  // The `path` is normalized through `_.toPath`.\n  function get(object, path, defaultValue) {\n    var value = deepGet(object, toPath(path));\n    return isUndefined(value) ? defaultValue : value;\n  }\n\n  // Shortcut function for checking if an object has a given property directly on\n  // itself (in other words, not on a prototype). Unlike the internal `has`\n  // function, this public version can also traverse nested properties.\n  function has(obj, path) {\n    path = toPath(path);\n    var length = path.length;\n    for (var i = 0; i < length; i++) {\n      var key = path[i];\n      if (!has$1(obj, key)) return false;\n      obj = obj[key];\n    }\n    return !!length;\n  }\n\n  // Keep the identity function around for default iteratees.\n  function identity(value) {\n    return value;\n  }\n\n  // Returns a predicate for checking whether an object has a given set of\n  // `key:value` pairs.\n  function matcher(attrs) {\n    attrs = extendOwn({}, attrs);\n    return function(obj) {\n      return isMatch(obj, attrs);\n    };\n  }\n\n  // Creates a function that, when passed an object, will traverse that object’s\n  // properties down the given `path`, specified as an array of keys or indices.\n  function property(path) {\n    path = toPath(path);\n    return function(obj) {\n      return deepGet(obj, path);\n    };\n  }\n\n  // Internal function that returns an efficient (for current engines) version\n  // of the passed-in callback, to be repeatedly applied in other Underscore\n  // functions.\n  function optimizeCb(func, context, argCount) {\n    if (context === void 0) return func;\n    switch (argCount == null ? 3 : argCount) {\n      case 1: return function(value) {\n        return func.call(context, value);\n      };\n      // The 2-argument case is omitted because we’re not using it.\n      case 3: return function(value, index, collection) {\n        return func.call(context, value, index, collection);\n      };\n      case 4: return function(accumulator, value, index, collection) {\n        return func.call(context, accumulator, value, index, collection);\n      };\n    }\n    return function() {\n      return func.apply(context, arguments);\n    };\n  }\n\n  // An internal function to generate callbacks that can be applied to each\n  // element in a collection, returning the desired result — either `_.identity`,\n  // an arbitrary callback, a property matcher, or a property accessor.\n  function baseIteratee(value, context, argCount) {\n    if (value == null) return identity;\n    if (isFunction$1(value)) return optimizeCb(value, context, argCount);\n    if (isObject(value) && !isArray(value)) return matcher(value);\n    return property(value);\n  }\n\n  // External wrapper for our callback generator. Users may customize\n  // `_.iteratee` if they want additional predicate/iteratee shorthand styles.\n  // This abstraction hides the internal-only `argCount` argument.\n  function iteratee(value, context) {\n    return baseIteratee(value, context, Infinity);\n  }\n  _$1.iteratee = iteratee;\n\n  // The function we call internally to generate a callback. It invokes\n  // `_.iteratee` if overridden, otherwise `baseIteratee`.\n  function cb(value, context, argCount) {\n    if (_$1.iteratee !== iteratee) return _$1.iteratee(value, context);\n    return baseIteratee(value, context, argCount);\n  }\n\n  // Returns the results of applying the `iteratee` to each element of `obj`.\n  // In contrast to `_.map` it returns an object.\n  function mapObject(obj, iteratee, context) {\n    iteratee = cb(iteratee, context);\n    var _keys = keys(obj),\n        length = _keys.length,\n        results = {};\n    for (var index = 0; index < length; index++) {\n      var currentKey = _keys[index];\n      results[currentKey] = iteratee(obj[currentKey], currentKey, obj);\n    }\n    return results;\n  }\n\n  // Predicate-generating function. Often useful outside of Underscore.\n  function noop(){}\n\n  // Generates a function for a given object that returns a given property.\n  function propertyOf(obj) {\n    if (obj == null) return noop;\n    return function(path) {\n      return get(obj, path);\n    };\n  }\n\n  // Run a function **n** times.\n  function times(n, iteratee, context) {\n    var accum = Array(Math.max(0, n));\n    iteratee = optimizeCb(iteratee, context, 1);\n    for (var i = 0; i < n; i++) accum[i] = iteratee(i);\n    return accum;\n  }\n\n  // Return a random integer between `min` and `max` (inclusive).\n  function random(min, max) {\n    if (max == null) {\n      max = min;\n      min = 0;\n    }\n    return min + Math.floor(Math.random() * (max - min + 1));\n  }\n\n  // A (possibly faster) way to get the current timestamp as an integer.\n  var now = Date.now || function() {\n    return new Date().getTime();\n  };\n\n  // Internal helper to generate functions for escaping and unescaping strings\n  // to/from HTML interpolation.\n  function createEscaper(map) {\n    var escaper = function(match) {\n      return map[match];\n    };\n    // Regexes for identifying a key that needs to be escaped.\n    var source = '(?:' + keys(map).join('|') + ')';\n    var testRegexp = RegExp(source);\n    var replaceRegexp = RegExp(source, 'g');\n    return function(string) {\n      string = string == null ? '' : '' + string;\n      return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;\n    };\n  }\n\n  // Internal list of HTML entities for escaping.\n  var escapeMap = {\n    '&': '&amp;',\n    '<': '&lt;',\n    '>': '&gt;',\n    '\"': '&quot;',\n    \"'\": '&#x27;',\n    '`': '&#x60;'\n  };\n\n  // Function for escaping strings to HTML interpolation.\n  var _escape = createEscaper(escapeMap);\n\n  // Internal list of HTML entities for unescaping.\n  var unescapeMap = invert(escapeMap);\n\n  // Function for unescaping strings from HTML interpolation.\n  var _unescape = createEscaper(unescapeMap);\n\n  // By default, Underscore uses ERB-style template delimiters. Change the\n  // following template settings to use alternative delimiters.\n  var templateSettings = _$1.templateSettings = {\n    evaluate: /<%([\\s\\S]+?)%>/g,\n    interpolate: /<%=([\\s\\S]+?)%>/g,\n    escape: /<%-([\\s\\S]+?)%>/g\n  };\n\n  // When customizing `_.templateSettings`, if you don't want to define an\n  // interpolation, evaluation or escaping regex, we need one that is\n  // guaranteed not to match.\n  var noMatch = /(.)^/;\n\n  // Certain characters need to be escaped so that they can be put into a\n  // string literal.\n  var escapes = {\n    \"'\": \"'\",\n    '\\\\': '\\\\',\n    '\\r': 'r',\n    '\\n': 'n',\n    '\\u2028': 'u2028',\n    '\\u2029': 'u2029'\n  };\n\n  var escapeRegExp = /\\\\|'|\\r|\\n|\\u2028|\\u2029/g;\n\n  function escapeChar(match) {\n    return '\\\\' + escapes[match];\n  }\n\n  // In order to prevent third-party code injection through\n  // `_.templateSettings.variable`, we test it against the following regular\n  // expression. It is intentionally a bit more liberal than just matching valid\n  // identifiers, but still prevents possible loopholes through defaults or\n  // destructuring assignment.\n  var bareIdentifier = /^\\s*(\\w|\\$)+\\s*$/;\n\n  // JavaScript micro-templating, similar to John Resig's implementation.\n  // Underscore templating handles arbitrary delimiters, preserves whitespace,\n  // and correctly escapes quotes within interpolated code.\n  // NB: `oldSettings` only exists for backwards compatibility.\n  function template(text, settings, oldSettings) {\n    if (!settings && oldSettings) settings = oldSettings;\n    settings = defaults({}, settings, _$1.templateSettings);\n\n    // Combine delimiters into one regular expression via alternation.\n    var matcher = RegExp([\n      (settings.escape || noMatch).source,\n      (settings.interpolate || noMatch).source,\n      (settings.evaluate || noMatch).source\n    ].join('|') + '|$', 'g');\n\n    // Compile the template source, escaping string literals appropriately.\n    var index = 0;\n    var source = \"__p+='\";\n    text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {\n      source += text.slice(index, offset).replace(escapeRegExp, escapeChar);\n      index = offset + match.length;\n\n      if (escape) {\n        source += \"'+\\n((__t=(\" + escape + \"))==null?'':_.escape(__t))+\\n'\";\n      } else if (interpolate) {\n        source += \"'+\\n((__t=(\" + interpolate + \"))==null?'':__t)+\\n'\";\n      } else if (evaluate) {\n        source += \"';\\n\" + evaluate + \"\\n__p+='\";\n      }\n\n      // Adobe VMs need the match returned to produce the correct offset.\n      return match;\n    });\n    source += \"';\\n\";\n\n    var argument = settings.variable;\n    if (argument) {\n      // Insure against third-party code injection. (CVE-2021-23358)\n      if (!bareIdentifier.test(argument)) throw new Error(\n        'variable is not a bare identifier: ' + argument\n      );\n    } else {\n      // If a variable is not specified, place data values in local scope.\n      source = 'with(obj||{}){\\n' + source + '}\\n';\n      argument = 'obj';\n    }\n\n    source = \"var __t,__p='',__j=Array.prototype.join,\" +\n      \"print=function(){__p+=__j.call(arguments,'');};\\n\" +\n      source + 'return __p;\\n';\n\n    var render;\n    try {\n      render = new Function(argument, '_', source);\n    } catch (e) {\n      e.source = source;\n      throw e;\n    }\n\n    var template = function(data) {\n      return render.call(this, data, _$1);\n    };\n\n    // Provide the compiled source as a convenience for precompilation.\n    template.source = 'function(' + argument + '){\\n' + source + '}';\n\n    return template;\n  }\n\n  // Traverses the children of `obj` along `path`. If a child is a function, it\n  // is invoked with its parent as context. Returns the value of the final\n  // child, or `fallback` if any child is undefined.\n  function result(obj, path, fallback) {\n    path = toPath(path);\n    var length = path.length;\n    if (!length) {\n      return isFunction$1(fallback) ? fallback.call(obj) : fallback;\n    }\n    for (var i = 0; i < length; i++) {\n      var prop = obj == null ? void 0 : obj[path[i]];\n      if (prop === void 0) {\n        prop = fallback;\n        i = length; // Ensure we don't continue iterating.\n      }\n      obj = isFunction$1(prop) ? prop.call(obj) : prop;\n    }\n    return obj;\n  }\n\n  // Generate a unique integer id (unique within the entire client session).\n  // Useful for temporary DOM ids.\n  var idCounter = 0;\n  function uniqueId(prefix) {\n    var id = ++idCounter + '';\n    return prefix ? prefix + id : id;\n  }\n\n  // Start chaining a wrapped Underscore object.\n  function chain(obj) {\n    var instance = _$1(obj);\n    instance._chain = true;\n    return instance;\n  }\n\n  // Internal function to execute `sourceFunc` bound to `context` with optional\n  // `args`. Determines whether to execute a function as a constructor or as a\n  // normal function.\n  function executeBound(sourceFunc, boundFunc, context, callingContext, args) {\n    if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);\n    var self = baseCreate(sourceFunc.prototype);\n    var result = sourceFunc.apply(self, args);\n    if (isObject(result)) return result;\n    return self;\n  }\n\n  // Partially apply a function by creating a version that has had some of its\n  // arguments pre-filled, without changing its dynamic `this` context. `_` acts\n  // as a placeholder by default, allowing any combination of arguments to be\n  // pre-filled. Set `_.partial.placeholder` for a custom placeholder argument.\n  var partial = restArguments(function(func, boundArgs) {\n    var placeholder = partial.placeholder;\n    var bound = function() {\n      var position = 0, length = boundArgs.length;\n      var args = Array(length);\n      for (var i = 0; i < length; i++) {\n        args[i] = boundArgs[i] === placeholder ? arguments[position++] : boundArgs[i];\n      }\n      while (position < arguments.length) args.push(arguments[position++]);\n      return executeBound(func, bound, this, this, args);\n    };\n    return bound;\n  });\n\n  partial.placeholder = _$1;\n\n  // Create a function bound to a given object (assigning `this`, and arguments,\n  // optionally).\n  var bind = restArguments(function(func, context, args) {\n    if (!isFunction$1(func)) throw new TypeError('Bind must be called on a function');\n    var bound = restArguments(function(callArgs) {\n      return executeBound(func, bound, context, this, args.concat(callArgs));\n    });\n    return bound;\n  });\n\n  // Internal helper for collection methods to determine whether a collection\n  // should be iterated as an array or as an object.\n  // Related: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength\n  // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094\n  var isArrayLike = createSizePropertyCheck(getLength);\n\n  // Internal implementation of a recursive `flatten` function.\n  function flatten$1(input, depth, strict, output) {\n    output = output || [];\n    if (!depth && depth !== 0) {\n      depth = Infinity;\n    } else if (depth <= 0) {\n      return output.concat(input);\n    }\n    var idx = output.length;\n    for (var i = 0, length = getLength(input); i < length; i++) {\n      var value = input[i];\n      if (isArrayLike(value) && (isArray(value) || isArguments$1(value))) {\n        // Flatten current level of array or arguments object.\n        if (depth > 1) {\n          flatten$1(value, depth - 1, strict, output);\n          idx = output.length;\n        } else {\n          var j = 0, len = value.length;\n          while (j < len) output[idx++] = value[j++];\n        }\n      } else if (!strict) {\n        output[idx++] = value;\n      }\n    }\n    return output;\n  }\n\n  // Bind a number of an object's methods to that object. Remaining arguments\n  // are the method names to be bound. Useful for ensuring that all callbacks\n  // defined on an object belong to it.\n  var bindAll = restArguments(function(obj, keys) {\n    keys = flatten$1(keys, false, false);\n    var index = keys.length;\n    if (index < 1) throw new Error('bindAll must be passed function names');\n    while (index--) {\n      var key = keys[index];\n      obj[key] = bind(obj[key], obj);\n    }\n    return obj;\n  });\n\n  // Memoize an expensive function by storing its results.\n  function memoize(func, hasher) {\n    var memoize = function(key) {\n      var cache = memoize.cache;\n      var address = '' + (hasher ? hasher.apply(this, arguments) : key);\n      if (!has$1(cache, address)) cache[address] = func.apply(this, arguments);\n      return cache[address];\n    };\n    memoize.cache = {};\n    return memoize;\n  }\n\n  // Delays a function for the given number of milliseconds, and then calls\n  // it with the arguments supplied.\n  var delay = restArguments(function(func, wait, args) {\n    return setTimeout(function() {\n      return func.apply(null, args);\n    }, wait);\n  });\n\n  // Defers a function, scheduling it to run after the current call stack has\n  // cleared.\n  var defer = partial(delay, _$1, 1);\n\n  // Returns a function, that, when invoked, will only be triggered at most once\n  // during a given window of time. Normally, the throttled function will run\n  // as much as it can, without ever going more than once per `wait` duration;\n  // but if you'd like to disable the execution on the leading edge, pass\n  // `{leading: false}`. To disable execution on the trailing edge, ditto.\n  function throttle(func, wait, options) {\n    var timeout, context, args, result;\n    var previous = 0;\n    if (!options) options = {};\n\n    var later = function() {\n      previous = options.leading === false ? 0 : now();\n      timeout = null;\n      result = func.apply(context, args);\n      if (!timeout) context = args = null;\n    };\n\n    var throttled = function() {\n      var _now = now();\n      if (!previous && options.leading === false) previous = _now;\n      var remaining = wait - (_now - previous);\n      context = this;\n      args = arguments;\n      if (remaining <= 0 || remaining > wait) {\n        if (timeout) {\n          clearTimeout(timeout);\n          timeout = null;\n        }\n        previous = _now;\n        result = func.apply(context, args);\n        if (!timeout) context = args = null;\n      } else if (!timeout && options.trailing !== false) {\n        timeout = setTimeout(later, remaining);\n      }\n      return result;\n    };\n\n    throttled.cancel = function() {\n      clearTimeout(timeout);\n      previous = 0;\n      timeout = context = args = null;\n    };\n\n    return throttled;\n  }\n\n  // When a sequence of calls of the returned function ends, the argument\n  // function is triggered. The end of a sequence is defined by the `wait`\n  // parameter. If `immediate` is passed, the argument function will be\n  // triggered at the beginning of the sequence instead of at the end.\n  function debounce(func, wait, immediate) {\n    var timeout, previous, args, result, context;\n\n    var later = function() {\n      var passed = now() - previous;\n      if (wait > passed) {\n        timeout = setTimeout(later, wait - passed);\n      } else {\n        timeout = null;\n        if (!immediate) result = func.apply(context, args);\n        // This check is needed because `func` can recursively invoke `debounced`.\n        if (!timeout) args = context = null;\n      }\n    };\n\n    var debounced = restArguments(function(_args) {\n      context = this;\n      args = _args;\n      previous = now();\n      if (!timeout) {\n        timeout = setTimeout(later, wait);\n        if (immediate) result = func.apply(context, args);\n      }\n      return result;\n    });\n\n    debounced.cancel = function() {\n      clearTimeout(timeout);\n      timeout = args = context = null;\n    };\n\n    return debounced;\n  }\n\n  // Returns the first function passed as an argument to the second,\n  // allowing you to adjust arguments, run code before and after, and\n  // conditionally execute the original function.\n  function wrap(func, wrapper) {\n    return partial(wrapper, func);\n  }\n\n  // Returns a negated version of the passed-in predicate.\n  function negate(predicate) {\n    return function() {\n      return !predicate.apply(this, arguments);\n    };\n  }\n\n  // Returns a function that is the composition of a list of functions, each\n  // consuming the return value of the function that follows.\n  function compose() {\n    var args = arguments;\n    var start = args.length - 1;\n    return function() {\n      var i = start;\n      var result = args[start].apply(this, arguments);\n      while (i--) result = args[i].call(this, result);\n      return result;\n    };\n  }\n\n  // Returns a function that will only be executed on and after the Nth call.\n  function after(times, func) {\n    return function() {\n      if (--times < 1) {\n        return func.apply(this, arguments);\n      }\n    };\n  }\n\n  // Returns a function that will only be executed up to (but not including) the\n  // Nth call.\n  function before(times, func) {\n    var memo;\n    return function() {\n      if (--times > 0) {\n        memo = func.apply(this, arguments);\n      }\n      if (times <= 1) func = null;\n      return memo;\n    };\n  }\n\n  // Returns a function that will be executed at most one time, no matter how\n  // often you call it. Useful for lazy initialization.\n  var once = partial(before, 2);\n\n  // Returns the first key on an object that passes a truth test.\n  function findKey(obj, predicate, context) {\n    predicate = cb(predicate, context);\n    var _keys = keys(obj), key;\n    for (var i = 0, length = _keys.length; i < length; i++) {\n      key = _keys[i];\n      if (predicate(obj[key], key, obj)) return key;\n    }\n  }\n\n  // Internal function to generate `_.findIndex` and `_.findLastIndex`.\n  function createPredicateIndexFinder(dir) {\n    return function(array, predicate, context) {\n      predicate = cb(predicate, context);\n      var length = getLength(array);\n      var index = dir > 0 ? 0 : length - 1;\n      for (; index >= 0 && index < length; index += dir) {\n        if (predicate(array[index], index, array)) return index;\n      }\n      return -1;\n    };\n  }\n\n  // Returns the first index on an array-like that passes a truth test.\n  var findIndex = createPredicateIndexFinder(1);\n\n  // Returns the last index on an array-like that passes a truth test.\n  var findLastIndex = createPredicateIndexFinder(-1);\n\n  // Use a comparator function to figure out the smallest index at which\n  // an object should be inserted so as to maintain order. Uses binary search.\n  function sortedIndex(array, obj, iteratee, context) {\n    iteratee = cb(iteratee, context, 1);\n    var value = iteratee(obj);\n    var low = 0, high = getLength(array);\n    while (low < high) {\n      var mid = Math.floor((low + high) / 2);\n      if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;\n    }\n    return low;\n  }\n\n  // Internal function to generate the `_.indexOf` and `_.lastIndexOf` functions.\n  function createIndexFinder(dir, predicateFind, sortedIndex) {\n    return function(array, item, idx) {\n      var i = 0, length = getLength(array);\n      if (typeof idx == 'number') {\n        if (dir > 0) {\n          i = idx >= 0 ? idx : Math.max(idx + length, i);\n        } else {\n          length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1;\n        }\n      } else if (sortedIndex && idx && length) {\n        idx = sortedIndex(array, item);\n        return array[idx] === item ? idx : -1;\n      }\n      if (item !== item) {\n        idx = predicateFind(slice.call(array, i, length), isNaN$1);\n        return idx >= 0 ? idx + i : -1;\n      }\n      for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) {\n        if (array[idx] === item) return idx;\n      }\n      return -1;\n    };\n  }\n\n  // Return the position of the first occurrence of an item in an array,\n  // or -1 if the item is not included in the array.\n  // If the array is large and already in sort order, pass `true`\n  // for **isSorted** to use binary search.\n  var indexOf = createIndexFinder(1, findIndex, sortedIndex);\n\n  // Return the position of the last occurrence of an item in an array,\n  // or -1 if the item is not included in the array.\n  var lastIndexOf = createIndexFinder(-1, findLastIndex);\n\n  // Return the first value which passes a truth test.\n  function find(obj, predicate, context) {\n    var keyFinder = isArrayLike(obj) ? findIndex : findKey;\n    var key = keyFinder(obj, predicate, context);\n    if (key !== void 0 && key !== -1) return obj[key];\n  }\n\n  // Convenience version of a common use case of `_.find`: getting the first\n  // object containing specific `key:value` pairs.\n  function findWhere(obj, attrs) {\n    return find(obj, matcher(attrs));\n  }\n\n  // The cornerstone for collection functions, an `each`\n  // implementation, aka `forEach`.\n  // Handles raw objects in addition to array-likes. Treats all\n  // sparse array-likes as if they were dense.\n  function each(obj, iteratee, context) {\n    iteratee = optimizeCb(iteratee, context);\n    var i, length;\n    if (isArrayLike(obj)) {\n      for (i = 0, length = obj.length; i < length; i++) {\n        iteratee(obj[i], i, obj);\n      }\n    } else {\n      var _keys = keys(obj);\n      for (i = 0, length = _keys.length; i < length; i++) {\n        iteratee(obj[_keys[i]], _keys[i], obj);\n      }\n    }\n    return obj;\n  }\n\n  // Return the results of applying the iteratee to each element.\n  function map(obj, iteratee, context) {\n    iteratee = cb(iteratee, context);\n    var _keys = !isArrayLike(obj) && keys(obj),\n        length = (_keys || obj).length,\n        results = Array(length);\n    for (var index = 0; index < length; index++) {\n      var currentKey = _keys ? _keys[index] : index;\n      results[index] = iteratee(obj[currentKey], currentKey, obj);\n    }\n    return results;\n  }\n\n  // Internal helper to create a reducing function, iterating left or right.\n  function createReduce(dir) {\n    // Wrap code that reassigns argument variables in a separate function than\n    // the one that accesses `arguments.length` to avoid a perf hit. (#1991)\n    var reducer = function(obj, iteratee, memo, initial) {\n      var _keys = !isArrayLike(obj) && keys(obj),\n          length = (_keys || obj).length,\n          index = dir > 0 ? 0 : length - 1;\n      if (!initial) {\n        memo = obj[_keys ? _keys[index] : index];\n        index += dir;\n      }\n      for (; index >= 0 && index < length; index += dir) {\n        var currentKey = _keys ? _keys[index] : index;\n        memo = iteratee(memo, obj[currentKey], currentKey, obj);\n      }\n      return memo;\n    };\n\n    return function(obj, iteratee, memo, context) {\n      var initial = arguments.length >= 3;\n      return reducer(obj, optimizeCb(iteratee, context, 4), memo, initial);\n    };\n  }\n\n  // **Reduce** builds up a single result from a list of values, aka `inject`,\n  // or `foldl`.\n  var reduce = createReduce(1);\n\n  // The right-associative version of reduce, also known as `foldr`.\n  var reduceRight = createReduce(-1);\n\n  // Return all the elements that pass a truth test.\n  function filter(obj, predicate, context) {\n    var results = [];\n    predicate = cb(predicate, context);\n    each(obj, function(value, index, list) {\n      if (predicate(value, index, list)) results.push(value);\n    });\n    return results;\n  }\n\n  // Return all the elements for which a truth test fails.\n  function reject(obj, predicate, context) {\n    return filter(obj, negate(cb(predicate)), context);\n  }\n\n  // Determine whether all of the elements pass a truth test.\n  function every(obj, predicate, context) {\n    predicate = cb(predicate, context);\n    var _keys = !isArrayLike(obj) && keys(obj),\n        length = (_keys || obj).length;\n    for (var index = 0; index < length; index++) {\n      var currentKey = _keys ? _keys[index] : index;\n      if (!predicate(obj[currentKey], currentKey, obj)) return false;\n    }\n    return true;\n  }\n\n  // Determine if at least one element in the object passes a truth test.\n  function some(obj, predicate, context) {\n    predicate = cb(predicate, context);\n    var _keys = !isArrayLike(obj) && keys(obj),\n        length = (_keys || obj).length;\n    for (var index = 0; index < length; index++) {\n      var currentKey = _keys ? _keys[index] : index;\n      if (predicate(obj[currentKey], currentKey, obj)) return true;\n    }\n    return false;\n  }\n\n  // Determine if the array or object contains a given item (using `===`).\n  function contains(obj, item, fromIndex, guard) {\n    if (!isArrayLike(obj)) obj = values(obj);\n    if (typeof fromIndex != 'number' || guard) fromIndex = 0;\n    return indexOf(obj, item, fromIndex) >= 0;\n  }\n\n  // Invoke a method (with arguments) on every item in a collection.\n  var invoke = restArguments(function(obj, path, args) {\n    var contextPath, func;\n    if (isFunction$1(path)) {\n      func = path;\n    } else {\n      path = toPath(path);\n      contextPath = path.slice(0, -1);\n      path = path[path.length - 1];\n    }\n    return map(obj, function(context) {\n      var method = func;\n      if (!method) {\n        if (contextPath && contextPath.length) {\n          context = deepGet(context, contextPath);\n        }\n        if (context == null) return void 0;\n        method = context[path];\n      }\n      return method == null ? method : method.apply(context, args);\n    });\n  });\n\n  // Convenience version of a common use case of `_.map`: fetching a property.\n  function pluck(obj, key) {\n    return map(obj, property(key));\n  }\n\n  // Convenience version of a common use case of `_.filter`: selecting only\n  // objects containing specific `key:value` pairs.\n  function where(obj, attrs) {\n    return filter(obj, matcher(attrs));\n  }\n\n  // Return the maximum element (or element-based computation).\n  function max(obj, iteratee, context) {\n    var result = -Infinity, lastComputed = -Infinity,\n        value, computed;\n    if (iteratee == null || typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null) {\n      obj = isArrayLike(obj) ? obj : values(obj);\n      for (var i = 0, length = obj.length; i < length; i++) {\n        value = obj[i];\n        if (value != null && value > result) {\n          result = value;\n        }\n      }\n    } else {\n      iteratee = cb(iteratee, context);\n      each(obj, function(v, index, list) {\n        computed = iteratee(v, index, list);\n        if (computed > lastComputed || computed === -Infinity && result === -Infinity) {\n          result = v;\n          lastComputed = computed;\n        }\n      });\n    }\n    return result;\n  }\n\n  // Return the minimum element (or element-based computation).\n  function min(obj, iteratee, context) {\n    var result = Infinity, lastComputed = Infinity,\n        value, computed;\n    if (iteratee == null || typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null) {\n      obj = isArrayLike(obj) ? obj : values(obj);\n      for (var i = 0, length = obj.length; i < length; i++) {\n        value = obj[i];\n        if (value != null && value < result) {\n          result = value;\n        }\n      }\n    } else {\n      iteratee = cb(iteratee, context);\n      each(obj, function(v, index, list) {\n        computed = iteratee(v, index, list);\n        if (computed < lastComputed || computed === Infinity && result === Infinity) {\n          result = v;\n          lastComputed = computed;\n        }\n      });\n    }\n    return result;\n  }\n\n  // Sample **n** random values from a collection using the modern version of the\n  // [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher–Yates_shuffle).\n  // If **n** is not specified, returns a single random element.\n  // The internal `guard` argument allows it to work with `_.map`.\n  function sample(obj, n, guard) {\n    if (n == null || guard) {\n      if (!isArrayLike(obj)) obj = values(obj);\n      return obj[random(obj.length - 1)];\n    }\n    var sample = isArrayLike(obj) ? clone(obj) : values(obj);\n    var length = getLength(sample);\n    n = Math.max(Math.min(n, length), 0);\n    var last = length - 1;\n    for (var index = 0; index < n; index++) {\n      var rand = random(index, last);\n      var temp = sample[index];\n      sample[index] = sample[rand];\n      sample[rand] = temp;\n    }\n    return sample.slice(0, n);\n  }\n\n  // Shuffle a collection.\n  function shuffle(obj) {\n    return sample(obj, Infinity);\n  }\n\n  // Sort the object's values by a criterion produced by an iteratee.\n  function sortBy(obj, iteratee, context) {\n    var index = 0;\n    iteratee = cb(iteratee, context);\n    return pluck(map(obj, function(value, key, list) {\n      return {\n        value: value,\n        index: index++,\n        criteria: iteratee(value, key, list)\n      };\n    }).sort(function(left, right) {\n      var a = left.criteria;\n      var b = right.criteria;\n      if (a !== b) {\n        if (a > b || a === void 0) return 1;\n        if (a < b || b === void 0) return -1;\n      }\n      return left.index - right.index;\n    }), 'value');\n  }\n\n  // An internal function used for aggregate \"group by\" operations.\n  function group(behavior, partition) {\n    return function(obj, iteratee, context) {\n      var result = partition ? [[], []] : {};\n      iteratee = cb(iteratee, context);\n      each(obj, function(value, index) {\n        var key = iteratee(value, index, obj);\n        behavior(result, value, key);\n      });\n      return result;\n    };\n  }\n\n  // Groups the object's values by a criterion. Pass either a string attribute\n  // to group by, or a function that returns the criterion.\n  var groupBy = group(function(result, value, key) {\n    if (has$1(result, key)) result[key].push(value); else result[key] = [value];\n  });\n\n  // Indexes the object's values by a criterion, similar to `_.groupBy`, but for\n  // when you know that your index values will be unique.\n  var indexBy = group(function(result, value, key) {\n    result[key] = value;\n  });\n\n  // Counts instances of an object that group by a certain criterion. Pass\n  // either a string attribute to count by, or a function that returns the\n  // criterion.\n  var countBy = group(function(result, value, key) {\n    if (has$1(result, key)) result[key]++; else result[key] = 1;\n  });\n\n  // Split a collection into two arrays: one whose elements all pass the given\n  // truth test, and one whose elements all do not pass the truth test.\n  var partition = group(function(result, value, pass) {\n    result[pass ? 0 : 1].push(value);\n  }, true);\n\n  // Safely create a real, live array from anything iterable.\n  var reStrSymbol = /[^\\ud800-\\udfff]|[\\ud800-\\udbff][\\udc00-\\udfff]|[\\ud800-\\udfff]/g;\n  function toArray(obj) {\n    if (!obj) return [];\n    if (isArray(obj)) return slice.call(obj);\n    if (isString(obj)) {\n      // Keep surrogate pair characters together.\n      return obj.match(reStrSymbol);\n    }\n    if (isArrayLike(obj)) return map(obj, identity);\n    return values(obj);\n  }\n\n  // Return the number of elements in a collection.\n  function size(obj) {\n    if (obj == null) return 0;\n    return isArrayLike(obj) ? obj.length : keys(obj).length;\n  }\n\n  // Internal `_.pick` helper function to determine whether `key` is an enumerable\n  // property name of `obj`.\n  function keyInObj(value, key, obj) {\n    return key in obj;\n  }\n\n  // Return a copy of the object only containing the allowed properties.\n  var pick = restArguments(function(obj, keys) {\n    var result = {}, iteratee = keys[0];\n    if (obj == null) return result;\n    if (isFunction$1(iteratee)) {\n      if (keys.length > 1) iteratee = optimizeCb(iteratee, keys[1]);\n      keys = allKeys(obj);\n    } else {\n      iteratee = keyInObj;\n      keys = flatten$1(keys, false, false);\n      obj = Object(obj);\n    }\n    for (var i = 0, length = keys.length; i < length; i++) {\n      var key = keys[i];\n      var value = obj[key];\n      if (iteratee(value, key, obj)) result[key] = value;\n    }\n    return result;\n  });\n\n  // Return a copy of the object without the disallowed properties.\n  var omit = restArguments(function(obj, keys) {\n    var iteratee = keys[0], context;\n    if (isFunction$1(iteratee)) {\n      iteratee = negate(iteratee);\n      if (keys.length > 1) context = keys[1];\n    } else {\n      keys = map(flatten$1(keys, false, false), String);\n      iteratee = function(value, key) {\n        return !contains(keys, key);\n      };\n    }\n    return pick(obj, iteratee, context);\n  });\n\n  // Returns everything but the last entry of the array. Especially useful on\n  // the arguments object. Passing **n** will return all the values in\n  // the array, excluding the last N.\n  function initial(array, n, guard) {\n    return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));\n  }\n\n  // Get the first element of an array. Passing **n** will return the first N\n  // values in the array. The **guard** check allows it to work with `_.map`.\n  function first(array, n, guard) {\n    if (array == null || array.length < 1) return n == null || guard ? void 0 : [];\n    if (n == null || guard) return array[0];\n    return initial(array, array.length - n);\n  }\n\n  // Returns everything but the first entry of the `array`. Especially useful on\n  // the `arguments` object. Passing an **n** will return the rest N values in the\n  // `array`.\n  function rest(array, n, guard) {\n    return slice.call(array, n == null || guard ? 1 : n);\n  }\n\n  // Get the last element of an array. Passing **n** will return the last N\n  // values in the array.\n  function last(array, n, guard) {\n    if (array == null || array.length < 1) return n == null || guard ? void 0 : [];\n    if (n == null || guard) return array[array.length - 1];\n    return rest(array, Math.max(0, array.length - n));\n  }\n\n  // Trim out all falsy values from an array.\n  function compact(array) {\n    return filter(array, Boolean);\n  }\n\n  // Flatten out an array, either recursively (by default), or up to `depth`.\n  // Passing `true` or `false` as `depth` means `1` or `Infinity`, respectively.\n  function flatten(array, depth) {\n    return flatten$1(array, depth, false);\n  }\n\n  // Take the difference between one array and a number of other arrays.\n  // Only the elements present in just the first array will remain.\n  var difference = restArguments(function(array, rest) {\n    rest = flatten$1(rest, true, true);\n    return filter(array, function(value){\n      return !contains(rest, value);\n    });\n  });\n\n  // Return a version of the array that does not contain the specified value(s).\n  var without = restArguments(function(array, otherArrays) {\n    return difference(array, otherArrays);\n  });\n\n  // Produce a duplicate-free version of the array. If the array has already\n  // been sorted, you have the option of using a faster algorithm.\n  // The faster algorithm will not work with an iteratee if the iteratee\n  // is not a one-to-one function, so providing an iteratee will disable\n  // the faster algorithm.\n  function uniq(array, isSorted, iteratee, context) {\n    if (!isBoolean(isSorted)) {\n      context = iteratee;\n      iteratee = isSorted;\n      isSorted = false;\n    }\n    if (iteratee != null) iteratee = cb(iteratee, context);\n    var result = [];\n    var seen = [];\n    for (var i = 0, length = getLength(array); i < length; i++) {\n      var value = array[i],\n          computed = iteratee ? iteratee(value, i, array) : value;\n      if (isSorted && !iteratee) {\n        if (!i || seen !== computed) result.push(value);\n        seen = computed;\n      } else if (iteratee) {\n        if (!contains(seen, computed)) {\n          seen.push(computed);\n          result.push(value);\n        }\n      } else if (!contains(result, value)) {\n        result.push(value);\n      }\n    }\n    return result;\n  }\n\n  // Produce an array that contains the union: each distinct element from all of\n  // the passed-in arrays.\n  var union = restArguments(function(arrays) {\n    return uniq(flatten$1(arrays, true, true));\n  });\n\n  // Produce an array that contains every item shared between all the\n  // passed-in arrays.\n  function intersection(array) {\n    var result = [];\n    var argsLength = arguments.length;\n    for (var i = 0, length = getLength(array); i < length; i++) {\n      var item = array[i];\n      if (contains(result, item)) continue;\n      var j;\n      for (j = 1; j < argsLength; j++) {\n        if (!contains(arguments[j], item)) break;\n      }\n      if (j === argsLength) result.push(item);\n    }\n    return result;\n  }\n\n  // Complement of zip. Unzip accepts an array of arrays and groups\n  // each array's elements on shared indices.\n  function unzip(array) {\n    var length = array && max(array, getLength).length || 0;\n    var result = Array(length);\n\n    for (var index = 0; index < length; index++) {\n      result[index] = pluck(array, index);\n    }\n    return result;\n  }\n\n  // Zip together multiple lists into a single array -- elements that share\n  // an index go together.\n  var zip = restArguments(unzip);\n\n  // Converts lists into objects. Pass either a single array of `[key, value]`\n  // pairs, or two parallel arrays of the same length -- one of keys, and one of\n  // the corresponding values. Passing by pairs is the reverse of `_.pairs`.\n  function object(list, values) {\n    var result = {};\n    for (var i = 0, length = getLength(list); i < length; i++) {\n      if (values) {\n        result[list[i]] = values[i];\n      } else {\n        result[list[i][0]] = list[i][1];\n      }\n    }\n    return result;\n  }\n\n  // Generate an integer Array containing an arithmetic progression. A port of\n  // the native Python `range()` function. See\n  // [the Python documentation](https://docs.python.org/library/functions.html#range).\n  function range(start, stop, step) {\n    if (stop == null) {\n      stop = start || 0;\n      start = 0;\n    }\n    if (!step) {\n      step = stop < start ? -1 : 1;\n    }\n\n    var length = Math.max(Math.ceil((stop - start) / step), 0);\n    var range = Array(length);\n\n    for (var idx = 0; idx < length; idx++, start += step) {\n      range[idx] = start;\n    }\n\n    return range;\n  }\n\n  // Chunk a single array into multiple arrays, each containing `count` or fewer\n  // items.\n  function chunk(array, count) {\n    if (count == null || count < 1) return [];\n    var result = [];\n    var i = 0, length = array.length;\n    while (i < length) {\n      result.push(slice.call(array, i, i += count));\n    }\n    return result;\n  }\n\n  // Helper function to continue chaining intermediate results.\n  function chainResult(instance, obj) {\n    return instance._chain ? _$1(obj).chain() : obj;\n  }\n\n  // Add your own custom functions to the Underscore object.\n  function mixin(obj) {\n    each(functions(obj), function(name) {\n      var func = _$1[name] = obj[name];\n      _$1.prototype[name] = function() {\n        var args = [this._wrapped];\n        push.apply(args, arguments);\n        return chainResult(this, func.apply(_$1, args));\n      };\n    });\n    return _$1;\n  }\n\n  // Add all mutator `Array` functions to the wrapper.\n  each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {\n    var method = ArrayProto[name];\n    _$1.prototype[name] = function() {\n      var obj = this._wrapped;\n      if (obj != null) {\n        method.apply(obj, arguments);\n        if ((name === 'shift' || name === 'splice') && obj.length === 0) {\n          delete obj[0];\n        }\n      }\n      return chainResult(this, obj);\n    };\n  });\n\n  // Add all accessor `Array` functions to the wrapper.\n  each(['concat', 'join', 'slice'], function(name) {\n    var method = ArrayProto[name];\n    _$1.prototype[name] = function() {\n      var obj = this._wrapped;\n      if (obj != null) obj = method.apply(obj, arguments);\n      return chainResult(this, obj);\n    };\n  });\n\n  // Named Exports\n\n  var allExports = {\n    __proto__: null,\n    VERSION: VERSION,\n    restArguments: restArguments,\n    isObject: isObject,\n    isNull: isNull,\n    isUndefined: isUndefined,\n    isBoolean: isBoolean,\n    isElement: isElement,\n    isString: isString,\n    isNumber: isNumber,\n    isDate: isDate,\n    isRegExp: isRegExp,\n    isError: isError,\n    isSymbol: isSymbol,\n    isArrayBuffer: isArrayBuffer,\n    isDataView: isDataView$1,\n    isArray: isArray,\n    isFunction: isFunction$1,\n    isArguments: isArguments$1,\n    isFinite: isFinite$1,\n    isNaN: isNaN$1,\n    isTypedArray: isTypedArray$1,\n    isEmpty: isEmpty,\n    isMatch: isMatch,\n    isEqual: isEqual,\n    isMap: isMap,\n    isWeakMap: isWeakMap,\n    isSet: isSet,\n    isWeakSet: isWeakSet,\n    keys: keys,\n    allKeys: allKeys,\n    values: values,\n    pairs: pairs,\n    invert: invert,\n    functions: functions,\n    methods: functions,\n    extend: extend,\n    extendOwn: extendOwn,\n    assign: extendOwn,\n    defaults: defaults,\n    create: create,\n    clone: clone,\n    tap: tap,\n    get: get,\n    has: has,\n    mapObject: mapObject,\n    identity: identity,\n    constant: constant,\n    noop: noop,\n    toPath: toPath$1,\n    property: property,\n    propertyOf: propertyOf,\n    matcher: matcher,\n    matches: matcher,\n    times: times,\n    random: random,\n    now: now,\n    escape: _escape,\n    unescape: _unescape,\n    templateSettings: templateSettings,\n    template: template,\n    result: result,\n    uniqueId: uniqueId,\n    chain: chain,\n    iteratee: iteratee,\n    partial: partial,\n    bind: bind,\n    bindAll: bindAll,\n    memoize: memoize,\n    delay: delay,\n    defer: defer,\n    throttle: throttle,\n    debounce: debounce,\n    wrap: wrap,\n    negate: negate,\n    compose: compose,\n    after: after,\n    before: before,\n    once: once,\n    findKey: findKey,\n    findIndex: findIndex,\n    findLastIndex: findLastIndex,\n    sortedIndex: sortedIndex,\n    indexOf: indexOf,\n    lastIndexOf: lastIndexOf,\n    find: find,\n    detect: find,\n    findWhere: findWhere,\n    each: each,\n    forEach: each,\n    map: map,\n    collect: map,\n    reduce: reduce,\n    foldl: reduce,\n    inject: reduce,\n    reduceRight: reduceRight,\n    foldr: reduceRight,\n    filter: filter,\n    select: filter,\n    reject: reject,\n    every: every,\n    all: every,\n    some: some,\n    any: some,\n    contains: contains,\n    includes: contains,\n    include: contains,\n    invoke: invoke,\n    pluck: pluck,\n    where: where,\n    max: max,\n    min: min,\n    shuffle: shuffle,\n    sample: sample,\n    sortBy: sortBy,\n    groupBy: groupBy,\n    indexBy: indexBy,\n    countBy: countBy,\n    partition: partition,\n    toArray: toArray,\n    size: size,\n    pick: pick,\n    omit: omit,\n    first: first,\n    head: first,\n    take: first,\n    initial: initial,\n    last: last,\n    rest: rest,\n    tail: rest,\n    drop: rest,\n    compact: compact,\n    flatten: flatten,\n    without: without,\n    uniq: uniq,\n    unique: uniq,\n    union: union,\n    intersection: intersection,\n    difference: difference,\n    unzip: unzip,\n    transpose: unzip,\n    zip: zip,\n    object: object,\n    range: range,\n    chunk: chunk,\n    mixin: mixin,\n    'default': _$1\n  };\n\n  // Default Export\n\n  // Add all of the Underscore functions to the wrapper object.\n  var _ = mixin(allExports);\n  // Legacy Node.js API.\n  _._ = _;\n\n  return _;\n\n})));\n//# sourceMappingURL=underscore-umd.js.map\n"
  },
  {
    "path": "core/dbt/docs/build/html/_static/underscore.js",
    "content": "!function(n,r){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=r():\"function\"==typeof define&&define.amd?define(\"underscore\",r):(n=\"undefined\"!=typeof globalThis?globalThis:n||self,function(){var t=n._,e=n._=r();e.noConflict=function(){return n._=t,e}}())}(this,(function(){\n//     Underscore.js 1.13.1\n//     https://underscorejs.org\n//     (c) 2009-2021 Jeremy Ashkenas, Julian Gonggrijp, and DocumentCloud and Investigative Reporters & Editors\n//     Underscore may be freely distributed under the MIT license.\nvar n=\"1.13.1\",r=\"object\"==typeof self&&self.self===self&&self||\"object\"==typeof global&&global.global===global&&global||Function(\"return this\")()||{},t=Array.prototype,e=Object.prototype,u=\"undefined\"!=typeof Symbol?Symbol.prototype:null,o=t.push,i=t.slice,a=e.toString,f=e.hasOwnProperty,c=\"undefined\"!=typeof ArrayBuffer,l=\"undefined\"!=typeof DataView,s=Array.isArray,p=Object.keys,v=Object.create,h=c&&ArrayBuffer.isView,y=isNaN,d=isFinite,g=!{toString:null}.propertyIsEnumerable(\"toString\"),b=[\"valueOf\",\"isPrototypeOf\",\"toString\",\"propertyIsEnumerable\",\"hasOwnProperty\",\"toLocaleString\"],m=Math.pow(2,53)-1;function j(n,r){return r=null==r?n.length-1:+r,function(){for(var t=Math.max(arguments.length-r,0),e=Array(t),u=0;u<t;u++)e[u]=arguments[u+r];switch(r){case 0:return n.call(this,e);case 1:return n.call(this,arguments[0],e);case 2:return n.call(this,arguments[0],arguments[1],e)}var o=Array(r+1);for(u=0;u<r;u++)o[u]=arguments[u];return o[r]=e,n.apply(this,o)}}function _(n){var r=typeof n;return\"function\"===r||\"object\"===r&&!!n}function w(n){return void 0===n}function A(n){return!0===n||!1===n||\"[object Boolean]\"===a.call(n)}function x(n){var r=\"[object \"+n+\"]\";return function(n){return a.call(n)===r}}var S=x(\"String\"),O=x(\"Number\"),M=x(\"Date\"),E=x(\"RegExp\"),B=x(\"Error\"),N=x(\"Symbol\"),I=x(\"ArrayBuffer\"),T=x(\"Function\"),k=r.document&&r.document.childNodes;\"function\"!=typeof/./&&\"object\"!=typeof Int8Array&&\"function\"!=typeof k&&(T=function(n){return\"function\"==typeof n||!1});var D=T,R=x(\"Object\"),F=l&&R(new DataView(new ArrayBuffer(8))),V=\"undefined\"!=typeof Map&&R(new Map),P=x(\"DataView\");var q=F?function(n){return null!=n&&D(n.getInt8)&&I(n.buffer)}:P,U=s||x(\"Array\");function W(n,r){return null!=n&&f.call(n,r)}var z=x(\"Arguments\");!function(){z(arguments)||(z=function(n){return W(n,\"callee\")})}();var L=z;function $(n){return O(n)&&y(n)}function C(n){return function(){return n}}function K(n){return function(r){var t=n(r);return\"number\"==typeof t&&t>=0&&t<=m}}function J(n){return function(r){return null==r?void 0:r[n]}}var G=J(\"byteLength\"),H=K(G),Q=/\\[object ((I|Ui)nt(8|16|32)|Float(32|64)|Uint8Clamped|Big(I|Ui)nt64)Array\\]/;var X=c?function(n){return h?h(n)&&!q(n):H(n)&&Q.test(a.call(n))}:C(!1),Y=J(\"length\");function Z(n,r){r=function(n){for(var r={},t=n.length,e=0;e<t;++e)r[n[e]]=!0;return{contains:function(n){return r[n]},push:function(t){return r[t]=!0,n.push(t)}}}(r);var t=b.length,u=n.constructor,o=D(u)&&u.prototype||e,i=\"constructor\";for(W(n,i)&&!r.contains(i)&&r.push(i);t--;)(i=b[t])in n&&n[i]!==o[i]&&!r.contains(i)&&r.push(i)}function nn(n){if(!_(n))return[];if(p)return p(n);var r=[];for(var t in n)W(n,t)&&r.push(t);return g&&Z(n,r),r}function rn(n,r){var t=nn(r),e=t.length;if(null==n)return!e;for(var u=Object(n),o=0;o<e;o++){var i=t[o];if(r[i]!==u[i]||!(i in u))return!1}return!0}function tn(n){return n instanceof tn?n:this instanceof tn?void(this._wrapped=n):new tn(n)}function en(n){return new Uint8Array(n.buffer||n,n.byteOffset||0,G(n))}tn.VERSION=n,tn.prototype.value=function(){return this._wrapped},tn.prototype.valueOf=tn.prototype.toJSON=tn.prototype.value,tn.prototype.toString=function(){return String(this._wrapped)};var un=\"[object DataView]\";function on(n,r,t,e){if(n===r)return 0!==n||1/n==1/r;if(null==n||null==r)return!1;if(n!=n)return r!=r;var o=typeof n;return(\"function\"===o||\"object\"===o||\"object\"==typeof r)&&function n(r,t,e,o){r instanceof tn&&(r=r._wrapped);t instanceof tn&&(t=t._wrapped);var i=a.call(r);if(i!==a.call(t))return!1;if(F&&\"[object Object]\"==i&&q(r)){if(!q(t))return!1;i=un}switch(i){case\"[object RegExp]\":case\"[object String]\":return\"\"+r==\"\"+t;case\"[object Number]\":return+r!=+r?+t!=+t:0==+r?1/+r==1/t:+r==+t;case\"[object Date]\":case\"[object Boolean]\":return+r==+t;case\"[object Symbol]\":return u.valueOf.call(r)===u.valueOf.call(t);case\"[object ArrayBuffer]\":case un:return n(en(r),en(t),e,o)}var f=\"[object Array]\"===i;if(!f&&X(r)){if(G(r)!==G(t))return!1;if(r.buffer===t.buffer&&r.byteOffset===t.byteOffset)return!0;f=!0}if(!f){if(\"object\"!=typeof r||\"object\"!=typeof t)return!1;var c=r.constructor,l=t.constructor;if(c!==l&&!(D(c)&&c instanceof c&&D(l)&&l instanceof l)&&\"constructor\"in r&&\"constructor\"in t)return!1}o=o||[];var s=(e=e||[]).length;for(;s--;)if(e[s]===r)return o[s]===t;if(e.push(r),o.push(t),f){if((s=r.length)!==t.length)return!1;for(;s--;)if(!on(r[s],t[s],e,o))return!1}else{var p,v=nn(r);if(s=v.length,nn(t).length!==s)return!1;for(;s--;)if(p=v[s],!W(t,p)||!on(r[p],t[p],e,o))return!1}return e.pop(),o.pop(),!0}(n,r,t,e)}function an(n){if(!_(n))return[];var r=[];for(var t in n)r.push(t);return g&&Z(n,r),r}function fn(n){var r=Y(n);return function(t){if(null==t)return!1;var e=an(t);if(Y(e))return!1;for(var u=0;u<r;u++)if(!D(t[n[u]]))return!1;return n!==hn||!D(t[cn])}}var cn=\"forEach\",ln=\"has\",sn=[\"clear\",\"delete\"],pn=[\"get\",ln,\"set\"],vn=sn.concat(cn,pn),hn=sn.concat(pn),yn=[\"add\"].concat(sn,cn,ln),dn=V?fn(vn):x(\"Map\"),gn=V?fn(hn):x(\"WeakMap\"),bn=V?fn(yn):x(\"Set\"),mn=x(\"WeakSet\");function jn(n){for(var r=nn(n),t=r.length,e=Array(t),u=0;u<t;u++)e[u]=n[r[u]];return e}function _n(n){for(var r={},t=nn(n),e=0,u=t.length;e<u;e++)r[n[t[e]]]=t[e];return r}function wn(n){var r=[];for(var t in n)D(n[t])&&r.push(t);return r.sort()}function An(n,r){return function(t){var e=arguments.length;if(r&&(t=Object(t)),e<2||null==t)return t;for(var u=1;u<e;u++)for(var o=arguments[u],i=n(o),a=i.length,f=0;f<a;f++){var c=i[f];r&&void 0!==t[c]||(t[c]=o[c])}return t}}var xn=An(an),Sn=An(nn),On=An(an,!0);function Mn(n){if(!_(n))return{};if(v)return v(n);var r=function(){};r.prototype=n;var t=new r;return r.prototype=null,t}function En(n){return _(n)?U(n)?n.slice():xn({},n):n}function Bn(n){return U(n)?n:[n]}function Nn(n){return tn.toPath(n)}function In(n,r){for(var t=r.length,e=0;e<t;e++){if(null==n)return;n=n[r[e]]}return t?n:void 0}function Tn(n,r,t){var e=In(n,Nn(r));return w(e)?t:e}function kn(n){return n}function Dn(n){return n=Sn({},n),function(r){return rn(r,n)}}function Rn(n){return n=Nn(n),function(r){return In(r,n)}}function Fn(n,r,t){if(void 0===r)return n;switch(null==t?3:t){case 1:return function(t){return n.call(r,t)};case 3:return function(t,e,u){return n.call(r,t,e,u)};case 4:return function(t,e,u,o){return n.call(r,t,e,u,o)}}return function(){return n.apply(r,arguments)}}function Vn(n,r,t){return null==n?kn:D(n)?Fn(n,r,t):_(n)&&!U(n)?Dn(n):Rn(n)}function Pn(n,r){return Vn(n,r,1/0)}function qn(n,r,t){return tn.iteratee!==Pn?tn.iteratee(n,r):Vn(n,r,t)}function Un(){}function Wn(n,r){return null==r&&(r=n,n=0),n+Math.floor(Math.random()*(r-n+1))}tn.toPath=Bn,tn.iteratee=Pn;var zn=Date.now||function(){return(new Date).getTime()};function Ln(n){var r=function(r){return n[r]},t=\"(?:\"+nn(n).join(\"|\")+\")\",e=RegExp(t),u=RegExp(t,\"g\");return function(n){return n=null==n?\"\":\"\"+n,e.test(n)?n.replace(u,r):n}}var $n={\"&\":\"&amp;\",\"<\":\"&lt;\",\">\":\"&gt;\",'\"':\"&quot;\",\"'\":\"&#x27;\",\"`\":\"&#x60;\"},Cn=Ln($n),Kn=Ln(_n($n)),Jn=tn.templateSettings={evaluate:/<%([\\s\\S]+?)%>/g,interpolate:/<%=([\\s\\S]+?)%>/g,escape:/<%-([\\s\\S]+?)%>/g},Gn=/(.)^/,Hn={\"'\":\"'\",\"\\\\\":\"\\\\\",\"\\r\":\"r\",\"\\n\":\"n\",\"\\u2028\":\"u2028\",\"\\u2029\":\"u2029\"},Qn=/\\\\|'|\\r|\\n|\\u2028|\\u2029/g;function Xn(n){return\"\\\\\"+Hn[n]}var Yn=/^\\s*(\\w|\\$)+\\s*$/;var Zn=0;function nr(n,r,t,e,u){if(!(e instanceof r))return n.apply(t,u);var o=Mn(n.prototype),i=n.apply(o,u);return _(i)?i:o}var rr=j((function(n,r){var t=rr.placeholder,e=function(){for(var u=0,o=r.length,i=Array(o),a=0;a<o;a++)i[a]=r[a]===t?arguments[u++]:r[a];for(;u<arguments.length;)i.push(arguments[u++]);return nr(n,e,this,this,i)};return e}));rr.placeholder=tn;var tr=j((function(n,r,t){if(!D(n))throw new TypeError(\"Bind must be called on a function\");var e=j((function(u){return nr(n,e,r,this,t.concat(u))}));return e})),er=K(Y);function ur(n,r,t,e){if(e=e||[],r||0===r){if(r<=0)return e.concat(n)}else r=1/0;for(var u=e.length,o=0,i=Y(n);o<i;o++){var a=n[o];if(er(a)&&(U(a)||L(a)))if(r>1)ur(a,r-1,t,e),u=e.length;else for(var f=0,c=a.length;f<c;)e[u++]=a[f++];else t||(e[u++]=a)}return e}var or=j((function(n,r){var t=(r=ur(r,!1,!1)).length;if(t<1)throw new Error(\"bindAll must be passed function names\");for(;t--;){var e=r[t];n[e]=tr(n[e],n)}return n}));var ir=j((function(n,r,t){return setTimeout((function(){return n.apply(null,t)}),r)})),ar=rr(ir,tn,1);function fr(n){return function(){return!n.apply(this,arguments)}}function cr(n,r){var t;return function(){return--n>0&&(t=r.apply(this,arguments)),n<=1&&(r=null),t}}var lr=rr(cr,2);function sr(n,r,t){r=qn(r,t);for(var e,u=nn(n),o=0,i=u.length;o<i;o++)if(r(n[e=u[o]],e,n))return e}function pr(n){return function(r,t,e){t=qn(t,e);for(var u=Y(r),o=n>0?0:u-1;o>=0&&o<u;o+=n)if(t(r[o],o,r))return o;return-1}}var vr=pr(1),hr=pr(-1);function yr(n,r,t,e){for(var u=(t=qn(t,e,1))(r),o=0,i=Y(n);o<i;){var a=Math.floor((o+i)/2);t(n[a])<u?o=a+1:i=a}return o}function dr(n,r,t){return function(e,u,o){var a=0,f=Y(e);if(\"number\"==typeof o)n>0?a=o>=0?o:Math.max(o+f,a):f=o>=0?Math.min(o+1,f):o+f+1;else if(t&&o&&f)return e[o=t(e,u)]===u?o:-1;if(u!=u)return(o=r(i.call(e,a,f),$))>=0?o+a:-1;for(o=n>0?a:f-1;o>=0&&o<f;o+=n)if(e[o]===u)return o;return-1}}var gr=dr(1,vr,yr),br=dr(-1,hr);function mr(n,r,t){var e=(er(n)?vr:sr)(n,r,t);if(void 0!==e&&-1!==e)return n[e]}function jr(n,r,t){var e,u;if(r=Fn(r,t),er(n))for(e=0,u=n.length;e<u;e++)r(n[e],e,n);else{var o=nn(n);for(e=0,u=o.length;e<u;e++)r(n[o[e]],o[e],n)}return n}function _r(n,r,t){r=qn(r,t);for(var e=!er(n)&&nn(n),u=(e||n).length,o=Array(u),i=0;i<u;i++){var a=e?e[i]:i;o[i]=r(n[a],a,n)}return o}function wr(n){var r=function(r,t,e,u){var o=!er(r)&&nn(r),i=(o||r).length,a=n>0?0:i-1;for(u||(e=r[o?o[a]:a],a+=n);a>=0&&a<i;a+=n){var f=o?o[a]:a;e=t(e,r[f],f,r)}return e};return function(n,t,e,u){var o=arguments.length>=3;return r(n,Fn(t,u,4),e,o)}}var Ar=wr(1),xr=wr(-1);function Sr(n,r,t){var e=[];return r=qn(r,t),jr(n,(function(n,t,u){r(n,t,u)&&e.push(n)})),e}function Or(n,r,t){r=qn(r,t);for(var e=!er(n)&&nn(n),u=(e||n).length,o=0;o<u;o++){var i=e?e[o]:o;if(!r(n[i],i,n))return!1}return!0}function Mr(n,r,t){r=qn(r,t);for(var e=!er(n)&&nn(n),u=(e||n).length,o=0;o<u;o++){var i=e?e[o]:o;if(r(n[i],i,n))return!0}return!1}function Er(n,r,t,e){return er(n)||(n=jn(n)),(\"number\"!=typeof t||e)&&(t=0),gr(n,r,t)>=0}var Br=j((function(n,r,t){var e,u;return D(r)?u=r:(r=Nn(r),e=r.slice(0,-1),r=r[r.length-1]),_r(n,(function(n){var o=u;if(!o){if(e&&e.length&&(n=In(n,e)),null==n)return;o=n[r]}return null==o?o:o.apply(n,t)}))}));function Nr(n,r){return _r(n,Rn(r))}function Ir(n,r,t){var e,u,o=-1/0,i=-1/0;if(null==r||\"number\"==typeof r&&\"object\"!=typeof n[0]&&null!=n)for(var a=0,f=(n=er(n)?n:jn(n)).length;a<f;a++)null!=(e=n[a])&&e>o&&(o=e);else r=qn(r,t),jr(n,(function(n,t,e){((u=r(n,t,e))>i||u===-1/0&&o===-1/0)&&(o=n,i=u)}));return o}function Tr(n,r,t){if(null==r||t)return er(n)||(n=jn(n)),n[Wn(n.length-1)];var e=er(n)?En(n):jn(n),u=Y(e);r=Math.max(Math.min(r,u),0);for(var o=u-1,i=0;i<r;i++){var a=Wn(i,o),f=e[i];e[i]=e[a],e[a]=f}return e.slice(0,r)}function kr(n,r){return function(t,e,u){var o=r?[[],[]]:{};return e=qn(e,u),jr(t,(function(r,u){var i=e(r,u,t);n(o,r,i)})),o}}var Dr=kr((function(n,r,t){W(n,t)?n[t].push(r):n[t]=[r]})),Rr=kr((function(n,r,t){n[t]=r})),Fr=kr((function(n,r,t){W(n,t)?n[t]++:n[t]=1})),Vr=kr((function(n,r,t){n[t?0:1].push(r)}),!0),Pr=/[^\\ud800-\\udfff]|[\\ud800-\\udbff][\\udc00-\\udfff]|[\\ud800-\\udfff]/g;function qr(n,r,t){return r in t}var Ur=j((function(n,r){var t={},e=r[0];if(null==n)return t;D(e)?(r.length>1&&(e=Fn(e,r[1])),r=an(n)):(e=qr,r=ur(r,!1,!1),n=Object(n));for(var u=0,o=r.length;u<o;u++){var i=r[u],a=n[i];e(a,i,n)&&(t[i]=a)}return t})),Wr=j((function(n,r){var t,e=r[0];return D(e)?(e=fr(e),r.length>1&&(t=r[1])):(r=_r(ur(r,!1,!1),String),e=function(n,t){return!Er(r,t)}),Ur(n,e,t)}));function zr(n,r,t){return i.call(n,0,Math.max(0,n.length-(null==r||t?1:r)))}function Lr(n,r,t){return null==n||n.length<1?null==r||t?void 0:[]:null==r||t?n[0]:zr(n,n.length-r)}function $r(n,r,t){return i.call(n,null==r||t?1:r)}var Cr=j((function(n,r){return r=ur(r,!0,!0),Sr(n,(function(n){return!Er(r,n)}))})),Kr=j((function(n,r){return Cr(n,r)}));function Jr(n,r,t,e){A(r)||(e=t,t=r,r=!1),null!=t&&(t=qn(t,e));for(var u=[],o=[],i=0,a=Y(n);i<a;i++){var f=n[i],c=t?t(f,i,n):f;r&&!t?(i&&o===c||u.push(f),o=c):t?Er(o,c)||(o.push(c),u.push(f)):Er(u,f)||u.push(f)}return u}var Gr=j((function(n){return Jr(ur(n,!0,!0))}));function Hr(n){for(var r=n&&Ir(n,Y).length||0,t=Array(r),e=0;e<r;e++)t[e]=Nr(n,e);return t}var Qr=j(Hr);function Xr(n,r){return n._chain?tn(r).chain():r}function Yr(n){return jr(wn(n),(function(r){var t=tn[r]=n[r];tn.prototype[r]=function(){var n=[this._wrapped];return o.apply(n,arguments),Xr(this,t.apply(tn,n))}})),tn}jr([\"pop\",\"push\",\"reverse\",\"shift\",\"sort\",\"splice\",\"unshift\"],(function(n){var r=t[n];tn.prototype[n]=function(){var t=this._wrapped;return null!=t&&(r.apply(t,arguments),\"shift\"!==n&&\"splice\"!==n||0!==t.length||delete t[0]),Xr(this,t)}})),jr([\"concat\",\"join\",\"slice\"],(function(n){var r=t[n];tn.prototype[n]=function(){var n=this._wrapped;return null!=n&&(n=r.apply(n,arguments)),Xr(this,n)}}));var Zr=Yr({__proto__:null,VERSION:n,restArguments:j,isObject:_,isNull:function(n){return null===n},isUndefined:w,isBoolean:A,isElement:function(n){return!(!n||1!==n.nodeType)},isString:S,isNumber:O,isDate:M,isRegExp:E,isError:B,isSymbol:N,isArrayBuffer:I,isDataView:q,isArray:U,isFunction:D,isArguments:L,isFinite:function(n){return!N(n)&&d(n)&&!isNaN(parseFloat(n))},isNaN:$,isTypedArray:X,isEmpty:function(n){if(null==n)return!0;var r=Y(n);return\"number\"==typeof r&&(U(n)||S(n)||L(n))?0===r:0===Y(nn(n))},isMatch:rn,isEqual:function(n,r){return on(n,r)},isMap:dn,isWeakMap:gn,isSet:bn,isWeakSet:mn,keys:nn,allKeys:an,values:jn,pairs:function(n){for(var r=nn(n),t=r.length,e=Array(t),u=0;u<t;u++)e[u]=[r[u],n[r[u]]];return e},invert:_n,functions:wn,methods:wn,extend:xn,extendOwn:Sn,assign:Sn,defaults:On,create:function(n,r){var t=Mn(n);return r&&Sn(t,r),t},clone:En,tap:function(n,r){return r(n),n},get:Tn,has:function(n,r){for(var t=(r=Nn(r)).length,e=0;e<t;e++){var u=r[e];if(!W(n,u))return!1;n=n[u]}return!!t},mapObject:function(n,r,t){r=qn(r,t);for(var e=nn(n),u=e.length,o={},i=0;i<u;i++){var a=e[i];o[a]=r(n[a],a,n)}return o},identity:kn,constant:C,noop:Un,toPath:Bn,property:Rn,propertyOf:function(n){return null==n?Un:function(r){return Tn(n,r)}},matcher:Dn,matches:Dn,times:function(n,r,t){var e=Array(Math.max(0,n));r=Fn(r,t,1);for(var u=0;u<n;u++)e[u]=r(u);return e},random:Wn,now:zn,escape:Cn,unescape:Kn,templateSettings:Jn,template:function(n,r,t){!r&&t&&(r=t),r=On({},r,tn.templateSettings);var e=RegExp([(r.escape||Gn).source,(r.interpolate||Gn).source,(r.evaluate||Gn).source].join(\"|\")+\"|$\",\"g\"),u=0,o=\"__p+='\";n.replace(e,(function(r,t,e,i,a){return o+=n.slice(u,a).replace(Qn,Xn),u=a+r.length,t?o+=\"'+\\n((__t=(\"+t+\"))==null?'':_.escape(__t))+\\n'\":e?o+=\"'+\\n((__t=(\"+e+\"))==null?'':__t)+\\n'\":i&&(o+=\"';\\n\"+i+\"\\n__p+='\"),r})),o+=\"';\\n\";var i,a=r.variable;if(a){if(!Yn.test(a))throw new Error(\"variable is not a bare identifier: \"+a)}else o=\"with(obj||{}){\\n\"+o+\"}\\n\",a=\"obj\";o=\"var __t,__p='',__j=Array.prototype.join,\"+\"print=function(){__p+=__j.call(arguments,'');};\\n\"+o+\"return __p;\\n\";try{i=new Function(a,\"_\",o)}catch(n){throw n.source=o,n}var f=function(n){return i.call(this,n,tn)};return f.source=\"function(\"+a+\"){\\n\"+o+\"}\",f},result:function(n,r,t){var e=(r=Nn(r)).length;if(!e)return D(t)?t.call(n):t;for(var u=0;u<e;u++){var o=null==n?void 0:n[r[u]];void 0===o&&(o=t,u=e),n=D(o)?o.call(n):o}return n},uniqueId:function(n){var r=++Zn+\"\";return n?n+r:r},chain:function(n){var r=tn(n);return r._chain=!0,r},iteratee:Pn,partial:rr,bind:tr,bindAll:or,memoize:function(n,r){var t=function(e){var u=t.cache,o=\"\"+(r?r.apply(this,arguments):e);return W(u,o)||(u[o]=n.apply(this,arguments)),u[o]};return t.cache={},t},delay:ir,defer:ar,throttle:function(n,r,t){var e,u,o,i,a=0;t||(t={});var f=function(){a=!1===t.leading?0:zn(),e=null,i=n.apply(u,o),e||(u=o=null)},c=function(){var c=zn();a||!1!==t.leading||(a=c);var l=r-(c-a);return u=this,o=arguments,l<=0||l>r?(e&&(clearTimeout(e),e=null),a=c,i=n.apply(u,o),e||(u=o=null)):e||!1===t.trailing||(e=setTimeout(f,l)),i};return c.cancel=function(){clearTimeout(e),a=0,e=u=o=null},c},debounce:function(n,r,t){var e,u,o,i,a,f=function(){var c=zn()-u;r>c?e=setTimeout(f,r-c):(e=null,t||(i=n.apply(a,o)),e||(o=a=null))},c=j((function(c){return a=this,o=c,u=zn(),e||(e=setTimeout(f,r),t&&(i=n.apply(a,o))),i}));return c.cancel=function(){clearTimeout(e),e=o=a=null},c},wrap:function(n,r){return rr(r,n)},negate:fr,compose:function(){var n=arguments,r=n.length-1;return function(){for(var t=r,e=n[r].apply(this,arguments);t--;)e=n[t].call(this,e);return e}},after:function(n,r){return function(){if(--n<1)return r.apply(this,arguments)}},before:cr,once:lr,findKey:sr,findIndex:vr,findLastIndex:hr,sortedIndex:yr,indexOf:gr,lastIndexOf:br,find:mr,detect:mr,findWhere:function(n,r){return mr(n,Dn(r))},each:jr,forEach:jr,map:_r,collect:_r,reduce:Ar,foldl:Ar,inject:Ar,reduceRight:xr,foldr:xr,filter:Sr,select:Sr,reject:function(n,r,t){return Sr(n,fr(qn(r)),t)},every:Or,all:Or,some:Mr,any:Mr,contains:Er,includes:Er,include:Er,invoke:Br,pluck:Nr,where:function(n,r){return Sr(n,Dn(r))},max:Ir,min:function(n,r,t){var e,u,o=1/0,i=1/0;if(null==r||\"number\"==typeof r&&\"object\"!=typeof n[0]&&null!=n)for(var a=0,f=(n=er(n)?n:jn(n)).length;a<f;a++)null!=(e=n[a])&&e<o&&(o=e);else r=qn(r,t),jr(n,(function(n,t,e){((u=r(n,t,e))<i||u===1/0&&o===1/0)&&(o=n,i=u)}));return o},shuffle:function(n){return Tr(n,1/0)},sample:Tr,sortBy:function(n,r,t){var e=0;return r=qn(r,t),Nr(_r(n,(function(n,t,u){return{value:n,index:e++,criteria:r(n,t,u)}})).sort((function(n,r){var t=n.criteria,e=r.criteria;if(t!==e){if(t>e||void 0===t)return 1;if(t<e||void 0===e)return-1}return n.index-r.index})),\"value\")},groupBy:Dr,indexBy:Rr,countBy:Fr,partition:Vr,toArray:function(n){return n?U(n)?i.call(n):S(n)?n.match(Pr):er(n)?_r(n,kn):jn(n):[]},size:function(n){return null==n?0:er(n)?n.length:nn(n).length},pick:Ur,omit:Wr,first:Lr,head:Lr,take:Lr,initial:zr,last:function(n,r,t){return null==n||n.length<1?null==r||t?void 0:[]:null==r||t?n[n.length-1]:$r(n,Math.max(0,n.length-r))},rest:$r,tail:$r,drop:$r,compact:function(n){return Sr(n,Boolean)},flatten:function(n,r){return ur(n,r,!1)},without:Kr,uniq:Jr,unique:Jr,union:Gr,intersection:function(n){for(var r=[],t=arguments.length,e=0,u=Y(n);e<u;e++){var o=n[e];if(!Er(r,o)){var i;for(i=1;i<t&&Er(arguments[i],o);i++);i===t&&r.push(o)}}return r},difference:Cr,unzip:Hr,transpose:Hr,zip:Qr,object:function(n,r){for(var t={},e=0,u=Y(n);e<u;e++)r?t[n[e]]=r[e]:t[n[e][0]]=n[e][1];return t},range:function(n,r,t){null==r&&(r=n||0,n=0),t||(t=r<n?-1:1);for(var e=Math.max(Math.ceil((r-n)/t),0),u=Array(e),o=0;o<e;o++,n+=t)u[o]=n;return u},chunk:function(n,r){if(null==r||r<1)return[];for(var t=[],e=0,u=n.length;e<u;)t.push(i.call(n,e,e+=r));return t},mixin:Yr,default:tn});return Zr._=Zr,Zr}));"
  },
  {
    "path": "core/dbt/docs/build/html/genindex.html",
    "content": "\n<!DOCTYPE html>\n\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>Index &#8212; dbt-core  documentation</title>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"_static/pygments.css\" />\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"_static/alabaster.css\" />\n    <script data-url_root=\"./\" id=\"documentation_options\" src=\"_static/documentation_options.js\"></script>\n    <script src=\"_static/jquery.js\"></script>\n    <script src=\"_static/underscore.js\"></script>\n    <script src=\"_static/_sphinx_javascript_frameworks_compat.js\"></script>\n    <script src=\"_static/doctools.js\"></script>\n    <script src=\"_static/sphinx_highlight.js\"></script>\n    <link rel=\"index\" title=\"Index\" href=\"#\" />\n    <link rel=\"search\" title=\"Search\" href=\"search.html\" />\n   \n  <link rel=\"stylesheet\" href=\"_static/custom.css\" type=\"text/css\" />\n  \n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=0.9, maximum-scale=0.9\" />\n\n  </head><body>\n  \n\n    <div class=\"document\">\n      <div class=\"documentwrapper\">\n        <div class=\"bodywrapper\">\n          \n\n          <div class=\"body\" role=\"main\">\n            \n\n<h1 id=\"index\">Index</h1>\n\n<div class=\"genindex-jumpbox\">\n \n</div>\n\n\n          </div>\n          \n        </div>\n      </div>\n      <div class=\"sphinxsidebar\" role=\"navigation\" aria-label=\"main navigation\">\n        <div class=\"sphinxsidebarwrapper\">\n<h1 class=\"logo\"><a href=\"index.html\">dbt-core</a></h1>\n\n\n\n\n\n\n\n\n<h3>Navigation</h3>\n\n<div class=\"relations\">\n<h3>Related Topics</h3>\n<ul>\n  <li><a href=\"index.html\">Documentation overview</a><ul>\n  </ul></li>\n</ul>\n</div>\n<div id=\"searchbox\" style=\"display: none\" role=\"search\">\n  <h3 id=\"searchlabel\">Quick search</h3>\n    <div class=\"searchformwrapper\">\n    <form class=\"search\" action=\"search.html\" method=\"get\">\n      <input type=\"text\" name=\"q\" aria-labelledby=\"searchlabel\" autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\"/>\n      <input type=\"submit\" value=\"Go\" />\n    </form>\n    </div>\n</div>\n<script>document.getElementById('searchbox').style.display = \"block\"</script>\n\n\n\n\n\n\n\n\n        </div>\n      </div>\n      <div class=\"clearer\"></div>\n    </div>\n    <div class=\"footer\">\n      &copy;2022, dbt Labs.\n      \n      |\n      Powered by <a href=\"http://sphinx-doc.org/\">Sphinx 5.2.3</a>\n      &amp; <a href=\"https://github.com/bitprophet/alabaster\">Alabaster 0.7.12</a>\n      \n    </div>\n\n    \n\n    \n  </body>\n</html>"
  },
  {
    "path": "core/dbt/docs/build/html/search.html",
    "content": "\n<!DOCTYPE html>\n\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>Search &#8212; dbt-core  documentation</title>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"_static/pygments.css\" />\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"_static/alabaster.css\" />\n    \n    <script data-url_root=\"./\" id=\"documentation_options\" src=\"_static/documentation_options.js\"></script>\n    <script src=\"_static/jquery.js\"></script>\n    <script src=\"_static/underscore.js\"></script>\n    <script src=\"_static/_sphinx_javascript_frameworks_compat.js\"></script>\n    <script src=\"_static/doctools.js\"></script>\n    <script src=\"_static/sphinx_highlight.js\"></script>\n    <script src=\"_static/searchtools.js\"></script>\n    <script src=\"_static/language_data.js\"></script>\n    <link rel=\"index\" title=\"Index\" href=\"genindex.html\" />\n    <link rel=\"search\" title=\"Search\" href=\"#\" />\n  <script src=\"searchindex.js\" defer></script>\n  \n   \n  <link rel=\"stylesheet\" href=\"_static/custom.css\" type=\"text/css\" />\n  \n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=0.9, maximum-scale=0.9\" />\n\n\n  </head><body>\n  \n\n    <div class=\"document\">\n      <div class=\"documentwrapper\">\n        <div class=\"bodywrapper\">\n          \n\n          <div class=\"body\" role=\"main\">\n            \n  <h1 id=\"search-documentation\">Search</h1>\n  \n  <noscript>\n  <div class=\"admonition warning\">\n  <p>\n    Please activate JavaScript to enable the search\n    functionality.\n  </p>\n  </div>\n  </noscript>\n  \n  \n  <p>\n    Searching for multiple words only shows matches that contain\n    all words.\n  </p>\n  \n  \n  <form action=\"\" method=\"get\">\n    <input type=\"text\" name=\"q\" aria-labelledby=\"search-documentation\" value=\"\" autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\"/>\n    <input type=\"submit\" value=\"search\" />\n    <span id=\"search-progress\" style=\"padding-left: 10px\"></span>\n  </form>\n  \n  \n  \n  <div id=\"search-results\">\n  \n  </div>\n  \n\n          </div>\n          \n        </div>\n      </div>\n      <div class=\"sphinxsidebar\" role=\"navigation\" aria-label=\"main navigation\">\n        <div class=\"sphinxsidebarwrapper\">\n<h1 class=\"logo\"><a href=\"index.html\">dbt-core</a></h1>\n\n\n\n\n\n\n\n\n<h3>Navigation</h3>\n\n<div class=\"relations\">\n<h3>Related Topics</h3>\n<ul>\n  <li><a href=\"index.html\">Documentation overview</a><ul>\n  </ul></li>\n</ul>\n</div>\n\n\n\n\n\n\n\n\n        </div>\n      </div>\n      <div class=\"clearer\"></div>\n    </div>\n    <div class=\"footer\">\n      &copy;2022, dbt Labs.\n      \n      |\n      Powered by <a href=\"http://sphinx-doc.org/\">Sphinx 5.2.3</a>\n      &amp; <a href=\"https://github.com/bitprophet/alabaster\">Alabaster 0.7.12</a>\n      \n    </div>\n\n    \n\n    \n  </body>\n</html>"
  },
  {
    "path": "core/dbt/docs/build/html/searchindex.js",
    "content": "Search.setIndex({\"docnames\": [\"index\"], \"filenames\": [\"index.rst\"], \"titles\": [\"dbt-core\\u2019s API documentation\"], \"terms\": {\"right\": 0, \"now\": 0, \"best\": 0, \"wai\": 0, \"from\": 0, \"i\": 0, \"us\": 0, \"dbtrunner\": 0, \"we\": 0, \"expos\": 0, \"cli\": 0, \"main\": 0, \"import\": 0, \"cli_arg\": 0, \"project\": 0, \"dir\": 0, \"jaffle_shop\": 0, \"initi\": 0, \"runner\": 0, \"re\": 0, \"success\": 0, \"you\": 0, \"can\": 0, \"also\": 0, \"pass\": 0, \"pre\": 0, \"construct\": 0, \"object\": 0, \"those\": 0, \"instead\": 0, \"load\": 0, \"up\": 0, \"disk\": 0, \"preload\": 0, \"load_profil\": 0, \"postgr\": 0, \"load_project\": 0, \"fals\": 0, \"thi\": 0, \"For\": 0, \"full\": 0, \"exampl\": 0, \"code\": 0, \"refer\": 0, \"py\": 0, \"type\": 0, \"boolean\": 0, \"If\": 0, \"set\": 0, \"variabl\": 0, \"resolv\": 0, \"unselect\": 0, \"node\": 0, \"unknown\": 0, \"specifi\": 0, \"stop\": 0, \"execut\": 0, \"first\": 0, \"failur\": 0, \"argument\": 0, \"provid\": 0, \"flag\": 0, \"even\": 0, \"exist\": 0, \"databas\": 0, \"current\": 0, \"environ\": 0, \"drop\": 0, \"increment\": 0, \"fulli\": 0, \"recalcul\": 0, \"tabl\": 0, \"definit\": 0, \"choic\": 0, \"eager\": 0, \"cautiou\": 0, \"buildabl\": 0, \"all\": 0, \"ar\": 0, \"adjac\": 0, \"resourc\": 0, \"thei\": 0, \"have\": 0, \"been\": 0, \"explicitli\": 0, \"string\": 0, \"which\": 0, \"overrid\": 0, \"dbt_project\": 0, \"yml\": 0, \"path\": 0, \"directori\": 0, \"look\": 0, \"file\": 0, \"work\": 0, \"home\": 0, \"default\": 0, \"its\": 0, \"parent\": 0, \"todo\": 0, \"No\": 0, \"help\": 0, \"text\": 0, \"includ\": 0, \"The\": 0, \"name\": 0, \"defin\": 0, \"sampl\": 0, \"data\": 0, \"termin\": 0, \"given\": 0, \"json\": 0, \"compar\": 0, \"store\": 0, \"result\": 0, \"fail\": 0, \"row\": 0, \"configur\": 0, \"onli\": 0, \"appli\": 0, \"dbt_target_path\": 0, \"int\": 0, \"number\": 0, \"while\": 0, \"yaml\": 0, \"suppli\": 0, \"your\": 0, \"should\": 0, \"eg\": 0, \"my_vari\": 0, \"my_valu\": 0, \"ensur\": 0, \"version\": 0, \"match\": 0, \"one\": 0, \"requir\": 0, \"whether\": 0, \"scaffold\": 0, \"queri\": 0, \"part\": 0, \"avail\": 0, \"inform\": 0, \"skip\": 0, \"interact\": 0, \"setup\": 0, \"dictionari\": 0, \"map\": 0, \"keyword\": 0}, \"objects\": {}, \"objtypes\": {}, \"objnames\": {}, \"titleterms\": {\"dbt\": 0, \"core\": 0, \"\": 0, \"api\": 0, \"document\": 0, \"how\": 0, \"invok\": 0, \"command\": 0, \"python\": 0, \"runtim\": 0, \"build\": 0, \"defer\": 0, \"exclud\": 0, \"fail_fast\": 0, \"favor_st\": 0, \"full_refresh\": 0, \"indirect_select\": 0, \"profil\": 0, \"profiles_dir\": 0, \"project_dir\": 0, \"resource_typ\": 0, \"select\": 0, \"selector\": 0, \"show\": 0, \"state\": 0, \"store_failur\": 0, \"target\": 0, \"target_path\": 0, \"thread\": 0, \"var\": 0, \"version_check\": 0, \"clean\": 0, \"compil\": 0, \"introspect\": 0, \"parse_onli\": 0, \"debug\": 0, \"config_dir\": 0, \"dep\": 0, \"doc\": 0, \"init\": 0, \"project_nam\": 0, \"skip_profile_setup\": 0, \"list\": 0, \"model\": 0, \"output\": 0, \"output_kei\": 0, \"pars\": 0, \"write_manifest\": 0, \"run\": 0, \"run_oper\": 0, \"macro\": 0, \"arg\": 0, \"seed\": 0, \"snapshot\": 0, \"sourc\": 0, \"test\": 0}, \"envversion\": {\"sphinx.domains.c\": 2, \"sphinx.domains.changeset\": 1, \"sphinx.domains.citation\": 1, \"sphinx.domains.cpp\": 8, \"sphinx.domains.index\": 1, \"sphinx.domains.javascript\": 2, \"sphinx.domains.math\": 2, \"sphinx.domains.python\": 3, \"sphinx.domains.rst\": 2, \"sphinx.domains.std\": 2, \"sphinx\": 57}, \"alltitles\": {\"dbt-core\\u2019s API documentation\": [[0, \"dbt-core-s-api-documentation\"]], \"How to invoke dbt commands in python runtime\": [[0, \"how-to-invoke-dbt-commands-in-python-runtime\"]], \"API documentation\": [[0, \"api-documentation\"]], \"Command: build\": [[0, \"dbt-section\"]], \"defer\": [[0, \"build|defer\"], [0, \"compile|defer\"], [0, \"run|defer\"], [0, \"snapshot|defer\"], [0, \"test|defer\"]], \"exclude\": [[0, \"build|exclude\"], [0, \"compile|exclude\"], [0, \"list|exclude\"], [0, \"list|exclude\"], [0, \"run|exclude\"], [0, \"seed|exclude\"], [0, \"snapshot|exclude\"], [0, \"test|exclude\"]], \"fail_fast\": [[0, \"build|fail_fast\"], [0, \"run|fail_fast\"], [0, \"test|fail_fast\"]], \"favor_state\": [[0, \"build|favor_state\"], [0, \"compile|favor_state\"], [0, \"run|favor_state\"], [0, \"snapshot|favor_state\"], [0, \"test|favor_state\"]], \"full_refresh\": [[0, \"build|full_refresh\"], [0, \"compile|full_refresh\"], [0, \"run|full_refresh\"], [0, \"seed|full_refresh\"]], \"indirect_selection\": [[0, \"build|indirect_selection\"], [0, \"list|indirect_selection\"], [0, \"list|indirect_selection\"], [0, \"test|indirect_selection\"]], \"profile\": [[0, \"build|profile\"], [0, \"clean|profile\"], [0, \"compile|profile\"], [0, \"debug|profile\"], [0, \"deps|profile\"], [0, \"init|profile\"], [0, \"list|profile\"], [0, \"list|profile\"], [0, \"parse|profile\"], [0, \"run|profile\"], [0, \"run-operation|profile\"], [0, \"seed|profile\"], [0, \"snapshot|profile\"], [0, \"test|profile\"]], \"profiles_dir\": [[0, \"build|profiles_dir\"], [0, \"clean|profiles_dir\"], [0, \"compile|profiles_dir\"], [0, \"debug|profiles_dir\"], [0, \"deps|profiles_dir\"], [0, \"init|profiles_dir\"], [0, \"list|profiles_dir\"], [0, \"list|profiles_dir\"], [0, \"parse|profiles_dir\"], [0, \"run|profiles_dir\"], [0, \"run-operation|profiles_dir\"], [0, \"seed|profiles_dir\"], [0, \"snapshot|profiles_dir\"], [0, \"test|profiles_dir\"]], \"project_dir\": [[0, \"build|project_dir\"], [0, \"clean|project_dir\"], [0, \"compile|project_dir\"], [0, \"debug|project_dir\"], [0, \"deps|project_dir\"], [0, \"init|project_dir\"], [0, \"list|project_dir\"], [0, \"list|project_dir\"], [0, \"parse|project_dir\"], [0, \"run|project_dir\"], [0, \"run-operation|project_dir\"], [0, \"seed|project_dir\"], [0, \"snapshot|project_dir\"], [0, \"test|project_dir\"]], \"resource_types\": [[0, \"build|resource_types\"], [0, \"list|resource_types\"], [0, \"list|resource_types\"]], \"select\": [[0, \"build|select\"], [0, \"compile|select\"], [0, \"list|select\"], [0, \"list|select\"], [0, \"run|select\"], [0, \"seed|select\"], [0, \"snapshot|select\"], [0, \"test|select\"]], \"selector\": [[0, \"build|selector\"], [0, \"compile|selector\"], [0, \"list|selector\"], [0, \"list|selector\"], [0, \"run|selector\"], [0, \"seed|selector\"], [0, \"snapshot|selector\"], [0, \"test|selector\"]], \"show\": [[0, \"build|show\"], [0, \"seed|show\"]], \"state\": [[0, \"build|state\"], [0, \"compile|state\"], [0, \"list|state\"], [0, \"list|state\"], [0, \"run|state\"], [0, \"seed|state\"], [0, \"snapshot|state\"], [0, \"test|state\"]], \"store_failures\": [[0, \"build|store_failures\"], [0, \"test|store_failures\"]], \"target\": [[0, \"build|target\"], [0, \"clean|target\"], [0, \"compile|target\"], [0, \"debug|target\"], [0, \"deps|target\"], [0, \"init|target\"], [0, \"list|target\"], [0, \"list|target\"], [0, \"parse|target\"], [0, \"run|target\"], [0, \"run-operation|target\"], [0, \"seed|target\"], [0, \"snapshot|target\"], [0, \"test|target\"]], \"target_path\": [[0, \"build|target_path\"], [0, \"compile|target_path\"], [0, \"parse|target_path\"], [0, \"run|target_path\"], [0, \"seed|target_path\"], [0, \"test|target_path\"]], \"threads\": [[0, \"build|threads\"], [0, \"compile|threads\"], [0, \"parse|threads\"], [0, \"run|threads\"], [0, \"seed|threads\"], [0, \"snapshot|threads\"], [0, \"test|threads\"]], \"vars\": [[0, \"build|vars\"], [0, \"clean|vars\"], [0, \"compile|vars\"], [0, \"debug|vars\"], [0, \"deps|vars\"], [0, \"init|vars\"], [0, \"list|vars\"], [0, \"list|vars\"], [0, \"parse|vars\"], [0, \"run|vars\"], [0, \"run-operation|vars\"], [0, \"seed|vars\"], [0, \"snapshot|vars\"], [0, \"test|vars\"]], \"version_check\": [[0, \"build|version_check\"], [0, \"compile|version_check\"], [0, \"debug|version_check\"], [0, \"parse|version_check\"], [0, \"run|version_check\"], [0, \"seed|version_check\"], [0, \"test|version_check\"]], \"Command: clean\": [[0, \"dbt-section\"]], \"Command: compile\": [[0, \"dbt-section\"]], \"introspect\": [[0, \"compile|introspect\"]], \"parse_only\": [[0, \"compile|parse_only\"]], \"Command: debug\": [[0, \"dbt-section\"]], \"config_dir\": [[0, \"debug|config_dir\"]], \"Command: deps\": [[0, \"dbt-section\"]], \"Command: docs\": [[0, \"dbt-section\"]], \"Command: init\": [[0, \"dbt-section\"]], \"project_name\": [[0, \"init|project_name\"]], \"skip_profile_setup\": [[0, \"init|skip_profile_setup\"]], \"Command: list\": [[0, \"dbt-section\"], [0, \"dbt-section\"]], \"models\": [[0, \"list|models\"], [0, \"list|models\"]], \"output\": [[0, \"list|output\"], [0, \"list|output\"]], \"output_keys\": [[0, \"list|output_keys\"], [0, \"list|output_keys\"]], \"Command: parse\": [[0, \"dbt-section\"]], \"compile\": [[0, \"parse|compile\"]], \"write_manifest\": [[0, \"parse|write_manifest\"]], \"Command: run\": [[0, \"dbt-section\"]], \"Command: run_operation\": [[0, \"dbt-section\"]], \"macro\": [[0, \"run-operation|macro\"]], \"args\": [[0, \"run-operation|args\"]], \"Command: seed\": [[0, \"dbt-section\"]], \"Command: snapshot\": [[0, \"dbt-section\"]], \"Command: source\": [[0, \"dbt-section\"]], \"Command: test\": [[0, \"dbt-section\"]]}, \"indexentries\": {}})"
  },
  {
    "path": "core/dbt/docs/make.bat",
    "content": "@ECHO OFF\r\n\r\npushd %~dp0\r\n\r\nREM Command file for Sphinx documentation\r\n\r\nif \"%SPHINXBUILD%\" == \"\" (\r\n\tset SPHINXBUILD=sphinx-build\r\n)\r\nset SOURCEDIR=source\r\nset BUILDDIR=build\r\n\r\n%SPHINXBUILD% >NUL 2>NUL\r\nif errorlevel 9009 (\r\n\techo.\r\n\techo.The 'sphinx-build' command was not found. Make sure you have Sphinx\r\n\techo.installed, then set the SPHINXBUILD environment variable to point\r\n\techo.to the full path of the 'sphinx-build' executable. Alternatively you\r\n\techo.may add the Sphinx directory to PATH.\r\n\techo.\r\n\techo.If you don't have Sphinx installed, grab it from\r\n\techo.https://www.sphinx-doc.org/\r\n\texit /b 1\r\n)\r\n\r\nif \"%1\" == \"\" goto help\r\n\r\n%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%\r\ngoto end\r\n\r\n:help\r\n%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%\r\n\r\n:end\r\npopd\r\n"
  },
  {
    "path": "core/dbt/docs/source/_ext/dbt_click.py",
    "content": "import traceback\nimport typing as t\n\nimport click\nimport click.types as click_t\nfrom docutils import nodes\nfrom docutils.parsers.rst import Directive\n\nimport dbt.cli.option_types as dbt_t\n\nPARAM_TYPE_MAP = {\n    click_t.BoolParamType: lambda _: \"boolean\",\n    click_t.Choice: lambda c: f\"choice: {c.choices}\",\n    click_t.IntParamType: lambda _: \"int\",\n    click_t.Path: lambda _: \"path\",\n    click_t.StringParamType: lambda _: \"string\",\n    dbt_t.YAML: lambda _: \"YAML\",\n}\n\n\ndef format_command(cmd) -> nodes.section:\n    cmd_name = cmd.name.replace(\"-\", \"_\")\n    section = nodes.section(\n        \"\",\n        nodes.title(text=f\"Command: {cmd_name}\"),\n        ids=[cmd_name],\n        names=[cmd_name],\n    )\n    section.extend(format_params(cmd))\n    return section\n\n\ndef format_params(cmd) -> t.List[nodes.section]:\n    lines = []\n    for param in cmd.params:\n        uid = f\"{cmd.name}|{param.name}\"\n        param_section = nodes.section(\n            \"\",\n            nodes.title(text=param.name),\n            ids=[uid],\n            names=[uid],\n        )\n\n        get_type_str = PARAM_TYPE_MAP.get(type(param.type), lambda _: \"unknown\")\n        type_str = get_type_str(param.type)\n\n        param_section.append(nodes.paragraph(text=f\"Type: {type_str}\"))\n        help_txt = getattr(param, \"help\", None)\n        if help_txt is not None:\n            param_section.append(nodes.paragraph(text=help_txt))\n        lines.append(param_section)\n    return lines\n\n\ndef load_module(module_path: str, error) -> t.Union[click.Command, click.Group]:\n    try:\n        module_name, attr_name = module_path.split(\":\", 1)\n    except ValueError:  # noqa\n        raise error(f'\"{module_path}\" is not of format \"module:parser\"')\n\n    try:\n        mod = __import__(module_name, globals(), locals(), [attr_name])\n    except Exception:  # noqa\n        raise error(\n            f'Failed to import \"{attr_name}\" from \"{module_name}\". '\n            f\"The following exception was raised:\\n{traceback.format_exc()}\"\n        )\n\n    if not hasattr(mod, attr_name):\n        raise error(f'Module \"{module_name}\" has no attribute \"{attr_name}\"')\n\n    parser = getattr(mod, attr_name)\n\n    if not isinstance(parser, (click.Command, click.Group)):\n        raise error(\n            f'\"{type(parser)}\" of type \"{module_path}\" is not click.Command'\n            ' or click.Group.\"click.BaseCommand\"'\n        )\n    return parser\n\n\nclass DBTClick(Directive):\n    has_content = False\n    required_arguments = 1\n\n    def run(self):\n        section = nodes.section(\n            \"\",\n            ids=[\"dbt-section\"],\n            names=[\"dbt-section\"],\n        )\n        cmds = self._get_commands(self.arguments[0])\n        for cmd in cmds:\n            command_section = format_command(cmd)\n            section.extend(command_section)\n        return [section]\n\n    def _get_commands(self, module: str) -> t.List[click.Command]:\n        click_group = load_module(module, self.error)\n        if type(click_group) is not click.Group:\n            raise self.error('Type \"click.Group\" not supported in dbt_click extension')\n        cmd_strs = [cmd for cmd in click_group.commands]\n        cmd_strs.sort()\n        cmds = []\n        for cmd_str in cmd_strs:\n            cmd = click_group.commands.get(cmd_str)\n            if cmd is not None:\n                cmds.append(cmd)\n        return cmds\n\n\ndef setup(app) -> t.Dict[str, t.Any]:\n    app.add_directive(\"dbt_click\", DBTClick)\n\n    return {\n        \"version\": \"0.1\",\n        \"parallel_read_safe\": True,\n        \"parallel_write_safe\": True,\n    }\n"
  },
  {
    "path": "core/dbt/docs/source/conf.py",
    "content": "import os\nimport sys\nimport typing as t\n\n# Configuration file for the Sphinx documentation builder.\n#\n# For the full list of built-in configuration values, see the documentation:\n# https://www.sphinx-doc.org/en/master/usage/configuration.html\n\nsys.path.insert(0, os.path.abspath(\"../../..\"))\nsys.path.insert(0, os.path.abspath(\"./_ext\"))\n\n# -- Project information -----------------------------------------------------\n# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information\n\nproject = \"dbt-core\"\ncopyright = \"2022, dbt Labs\"\nauthor = \"dbt Labs\"\n\n# -- General configuration ---------------------------------------------------\n# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration\n\nextensions = [\"dbt_click\"]\n\ntemplates_path = [\"_templates\"]\nexclude_patterns: t.List[str] = []\n\n# -- Options for HTML output -------------------------------------------------\n# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output\n\nhtml_theme = \"alabaster\"\nhtml_static_path = [\"_static\"]\n"
  },
  {
    "path": "core/dbt/docs/source/index.rst",
    "content": "dbt-core's API documentation\n============================\nProgrammatic invocations\n--------------------------------------------\n\nIn v1.5, dbt-core added support for programmatic invocations. The intent of this entry point is provide **exact parity** with CLI functionality, callable from within a Python script or application.\n\nThe main entry point is a ``dbtRunner`` class that wraps around ``dbt-core``'s CLI, and allows you to \"invoke\" CLI commands as Python methods. Each command returns a `dbtRunnerResult` object, which has three attributes:\n\n* ``success`` (bool): Whether the command succeeded.\n* ``result``: If the command completed (successfully or with handled errors), its result(s). Return type varies by command.\n* ``exception``: If the dbt invocation encountered an unhandled error and did not complete, the exception it encountered.\n\n.. code-block:: python\n\n    from dbt.cli.main import dbtRunner, dbtRunnerResult\n\n    # initialize\n    dbt = dbtRunner()\n\n    # create CLI args as a list of strings\n    cli_args = [\"run\", \"--select\", \"tag:my_tag\"]\n\n    # run the command\n    res: dbtRunnerResult = dbt.invoke(cli_args)\n\n    # inspect the results\n    for r in res.result:\n        print(f\"{r.node.name}: {r.status}\")\n\n\nFor more information and examples, consult the documentation: https://docs.getdbt.com/reference/programmatic-invocations\n\nAPI documentation\n-----------------\n\n.. dbt_click:: dbt.cli.main:cli\n"
  },
  {
    "path": "core/dbt/env_vars.py",
    "content": "from typing import List\n\nfrom dbt.cli import params\nfrom dbt.deprecations import warn\nfrom dbt_common.constants import ENGINE_ENV_PREFIX\nfrom dbt_common.context import get_invocation_context\n\n# These are env vars that are not in the params module, but are still allowed to be set.\n# New additions to this list should use the new naming scheme, unless they are being added because\n# they already existed, but we didn't know about them previously.\n# TODO: Should at least some of these become (undocumented) cli param options?\n_ADDITIONAL_ENGINE_ENV_VARS: List[str] = [\n    \"DBT_INVOCATION_ENV\",\n    \"DBT_RECORDED_FILE_PATH\",\n    \"DBT_TEST_STATE_MODIFIED\",  # TODO: This is testing related, should we do this differently?\n    \"DBT_PACKAGE_HUB_URL\",\n    \"DBT_DOWNLOAD_DIR\",\n    \"DBT_PP_FILE_DIFF_TEST\",  # TODO: This is testing related, should we do this differently?\n    \"DBT_PP_TEST\",  # TODO: This is testing related, should we do this differently?\n]\n\n\n# Here we are creating a set of all known engine env vars. This is used in this moduleto create an allow list of dbt\n# engine env vars. We also use it in the cli flags module to cross propagate engine env vars with their old non-engine prefixed names.\nKNOWN_ENGINE_ENV_VARS: set[params.EngineEnvVar] = set(params.KNOWN_ENV_VARS).union(\n    {params.EngineEnvVar(envvar=envvar) for envvar in _ADDITIONAL_ENGINE_ENV_VARS}\n)\n_ALLOWED_ENV_VARS: set[str] = {engine_env_var.name for engine_env_var in KNOWN_ENGINE_ENV_VARS}\n\n\ndef validate_engine_env_vars() -> None:\n    \"\"\"\n    Validate that any set environment variables that begin with the engine prefix are allowed.\n    \"\"\"\n    env_vars = get_invocation_context()._env\n    for env_var in env_vars.keys():\n        if env_var.startswith(ENGINE_ENV_PREFIX) and env_var not in _ALLOWED_ENV_VARS:\n            warn(\n                \"environment-variable-namespace-deprecation\",\n                env_var=env_var,\n                reserved_prefix=ENGINE_ENV_PREFIX,\n            )\n"
  },
  {
    "path": "core/dbt/event_time/event_time.py",
    "content": "from datetime import datetime\n\nfrom dateutil.relativedelta import relativedelta\n\nfrom dbt.artifacts.resources.types import BatchSize\nfrom dbt_common.exceptions import DbtRuntimeError\n\n\ndef offset_timestamp(timestamp=datetime, batch_size=BatchSize, offset=int) -> datetime:\n    \"\"\"Offsets the passed in timestamp based on the batch_size and offset.\n\n    Note: THIS IS DIFFERENT FROM MicrobatchBuilder.offset_timestamp. That function first\n    `truncates` the timestamp, and then does delta addition subtraction from there. This\n    function _doesn't_ truncate the timestamp and uses `relativedelta` for specific edge\n    case handling (months, years), which may produce different results than the delta math\n    done in `MicrobatchBuilder.offset_timestamp`\n\n    Examples\n    2024-09-17 16:06:00 + Batchsize.hour -1 -> 2024-09-17 15:06:00\n    2024-09-17 16:06:00 + Batchsize.hour +1 -> 2024-09-17 17:06:00\n    2024-09-17 16:06:00 + Batchsize.day -1 -> 2024-09-16 16:06:00\n    2024-09-17 16:06:00 + Batchsize.day +1 -> 2024-09-18 16:06:00\n    2024-09-17 16:06:00 + Batchsize.month -1 -> 2024-08-17 16:06:00\n    2024-09-17 16:06:00 + Batchsize.month +1 -> 2024-10-17 16:06:00\n    2024-09-17 16:06:00 + Batchsize.year -1 -> 2023-09-17 16:06:00\n    2024-09-17 16:06:00 + Batchsize.year +1 -> 2025-09-17 16:06:00\n    2024-01-31 16:06:00 + Batchsize.month +1 -> 2024-02-29 16:06:00\n    2024-02-29 16:06:00 + Batchsize.year +1 -> 2025-02-28 16:06:00\n    \"\"\"\n\n    if batch_size == BatchSize.hour:\n        return timestamp + relativedelta(hours=offset)\n    elif batch_size == BatchSize.day:\n        return timestamp + relativedelta(days=offset)\n    elif batch_size == BatchSize.month:\n        return timestamp + relativedelta(months=offset)\n    elif batch_size == BatchSize.year:\n        return timestamp + relativedelta(years=offset)\n    else:\n        raise DbtRuntimeError(f\"Unhandled batch_size '{batch_size}'\")\n"
  },
  {
    "path": "core/dbt/event_time/sample_window.py",
    "content": "from __future__ import annotations\n\nfrom datetime import datetime\n\nimport pytz\nfrom attr import dataclass\n\nfrom dbt.artifacts.resources.types import BatchSize\nfrom dbt.event_time.event_time import offset_timestamp\nfrom dbt_common.dataclass_schema import dbtClassMixin\nfrom dbt_common.exceptions import DbtRuntimeError\n\n\n@dataclass\nclass SampleWindow(dbtClassMixin):\n    start: datetime\n    end: datetime\n\n    def __post_serialize__(self, data, context):\n        # This is insane, but necessary, I apologize. Mashumaro handles the\n        # dictification of this class via a compile time generated `to_dict`\n        # method based off of the _typing_ of th class. By default `datetime`\n        # types are converted to strings. We don't want that, we want them to\n        # stay datetimes.\n        # Note: This is safe because the `SampleWindow` isn't part of the artifact\n        # and thus doesn't get written out.\n        new_data = super().__post_serialize__(data, context)\n        new_data[\"start\"] = self.start\n        new_data[\"end\"] = self.end\n        return new_data\n\n    @classmethod\n    def from_relative_string(cls, relative_string: str) -> SampleWindow:\n        end = datetime.now(tz=pytz.UTC)\n\n        relative_window = relative_string.split(\" \")\n        if len(relative_window) != 2:\n            raise DbtRuntimeError(\n                f\"Cannot load SAMPLE_WINDOW from '{relative_string}'. Must be of form 'DAYS_INT GRAIN_SIZE'.\"\n            )\n\n        try:\n            lookback = int(relative_window[0])\n        except Exception:\n            raise DbtRuntimeError(f\"Unable to convert '{relative_window[0]}' to an integer.\")\n\n        try:\n            batch_size_string = relative_window[1].lower().rstrip(\"s\")\n            batch_size = BatchSize[batch_size_string]\n        except Exception:\n            grains = [size.value for size in BatchSize]\n            grain_plurals = [BatchSize.plural(size) for size in BatchSize]\n            valid_grains = grains + grain_plurals\n            raise DbtRuntimeError(\n                f\"Invalid grain size '{relative_window[1]}'. Must be one of {valid_grains}.\"\n            )\n\n        start = offset_timestamp(timestamp=end, batch_size=batch_size, offset=-1 * lookback)\n\n        return cls(start=start, end=end)\n"
  },
  {
    "path": "core/dbt/events/README.md",
    "content": "# Events Module\nThe Events module is responsible for communicating internal dbt structures into a consumable interface. Because the \"event\" classes are based entirely on protobuf definitions, the interface is really clearly defined, whether or not protobufs are used to consume it. We use protoc for compiling the protobuf message definitions into Python classes.\n\n# Using the Events Module\nThe event module provides types that represent what is happening in dbt in `events.types`. These types are intended to represent an exhaustive list of all things happening within dbt that will need to be logged, streamed, or printed. To fire an event, `common.events.functions::fire_event` is the entry point to the module from everywhere in dbt.\n\n# Logging\nWhen events are processed via `fire_event`, nearly everything is logged. Whether or not the user has enabled the debug flag, all debug messages are still logged to the file. However, some events are particularly time consuming to construct because they return a huge amount of data. Today, the only messages in this category are cache events and are only logged if the `--log-cache-events` flag is on. This is important because these messages should not be created unless they are going to be logged, because they cause a noticable performance degredation. These events use a \"fire_event_if\" functions.\n\n# Adding a New Event\nAll protos have been moved into the central protos repository. To edit an event proto, edit https://github.com/dbt-labs/proto-python-public or open an issue on that repository.\n\n## Required for Every Event\n\n- a method `code`, that's unique across events\n- assign a log level by using the Level mixin: `DebugLevel`, `InfoLevel`, `WarnLevel`, or `ErrorLevel`\n- a message()\n\nExample\n```\nclass PartialParsingDeletedExposure(DebugLevel):\n    def code(self):\n        return \"I049\"\n\n    def message(self) -> str:\n        return f\"Partial parsing: deleted exposure {self.unique_id}\"\n\n```\n\n\n## Compiling core_types.proto\n\nAfter adding a new message in `core_types.proto`, either:\n- In the repository root directory: `make core_proto_types`\n- In the `core/dbt/events` directory: `protoc -I=. --python_out=. types.proto`\n"
  },
  {
    "path": "core/dbt/events/__init__.py",
    "content": "from typing import Any, Dict, Set\n\nimport dbt.adapters.events.types as adapter_dbt_event_types\nimport dbt.events.types as core_dbt_event_types\nimport dbt_common.events.types as dbt_event_types\n\nALL_EVENT_TYPES: Dict[str, Any] = {\n    **dbt_event_types.__dict__,\n    **core_dbt_event_types.__dict__,\n    **adapter_dbt_event_types.__dict__,\n}\n\nALL_EVENT_NAMES: Set[str] = set(\n    [name for name, cls in ALL_EVENT_TYPES.items() if isinstance(cls, type)]\n)\n"
  },
  {
    "path": "core/dbt/events/base_types.py",
    "content": "from dbt.events import core_types_pb2\nfrom dbt_common.events.base_types import BaseEvent\nfrom dbt_common.events.base_types import DebugLevel as CommonDebugLevel\nfrom dbt_common.events.base_types import DynamicLevel as CommonDyanicLevel\nfrom dbt_common.events.base_types import ErrorLevel as CommonErrorLevel\nfrom dbt_common.events.base_types import InfoLevel as CommonInfoLevel\nfrom dbt_common.events.base_types import TestLevel as CommonTestLevel\nfrom dbt_common.events.base_types import WarnLevel as CommonWarnLevel\n\n\nclass CoreBaseEvent(BaseEvent):\n    PROTO_TYPES_MODULE = core_types_pb2\n\n\nclass DynamicLevel(CommonDyanicLevel, CoreBaseEvent):\n    pass\n\n\nclass TestLevel(CommonTestLevel, CoreBaseEvent):\n    pass\n\n\nclass DebugLevel(CommonDebugLevel, CoreBaseEvent):\n    pass\n\n\nclass InfoLevel(CommonInfoLevel, CoreBaseEvent):\n    pass\n\n\nclass WarnLevel(CommonWarnLevel, CoreBaseEvent):\n    pass\n\n\nclass ErrorLevel(CommonErrorLevel, CoreBaseEvent):\n    pass\n"
  },
  {
    "path": "core/dbt/events/core_types_pb2.py",
    "content": "# preserving import path during dbtlabs.proto refactor\nfrom dbtlabs.proto.public.v1.fields.core_types_pb2 import *  # noqa\n"
  },
  {
    "path": "core/dbt/events/logging.py",
    "content": "import os\nfrom functools import partial\nfrom typing import Callable, List\n\nfrom dbt.tracking import track_behavior_change_warn\nfrom dbt_common.events.base_types import EventLevel, EventMsg\nfrom dbt_common.events.event_manager_client import (\n    add_callback_to_manager,\n    add_logger_to_manager,\n    cleanup_event_logger,\n    get_event_manager,\n)\nfrom dbt_common.events.functions import (\n    env_scrubber,\n    get_capture_stream,\n    get_stdout_config,\n    make_log_dir_if_missing,\n)\nfrom dbt_common.events.logger import LineFormat, LoggerConfig\nfrom dbt_common.invocation import get_invocation_id\n\n# These are the logging events issued by the \"clean\" command,\n# where we can't count on having a log directory. We've removed\n# the \"class\" flags on the events in types.py. If necessary we\n# could still use class or method flags, but we'd have to get\n# the type class from the msg and then get the information from the class.\n_NOFILE_CODES = [\"Z012\", \"Z013\", \"Z014\", \"Z015\"]\n\n\ndef _line_format_from_str(format_str: str, default: LineFormat) -> LineFormat:\n    if format_str == \"text\":\n        return LineFormat.PlainText\n    elif format_str == \"debug\":\n        return LineFormat.DebugText\n    elif format_str == \"json\":\n        return LineFormat.Json\n\n    return default\n\n\ndef _get_logfile_config(\n    log_path: str,\n    use_colors: bool,\n    line_format: LineFormat,\n    level: EventLevel,\n    log_file_max_bytes: int,\n    log_cache_events: bool = False,\n) -> LoggerConfig:\n    return LoggerConfig(\n        name=\"file_log\",\n        line_format=line_format,\n        use_colors=use_colors,\n        level=level,  # File log is *always* debug level\n        scrubber=env_scrubber,\n        filter=partial(_logfile_filter, log_cache_events, line_format),\n        invocation_id=get_invocation_id(),\n        output_file_name=log_path,\n        output_file_max_bytes=log_file_max_bytes,\n    )\n\n\ndef _logfile_filter(log_cache_events: bool, line_format: LineFormat, msg: EventMsg) -> bool:\n    return msg.info.code not in _NOFILE_CODES and not (\n        msg.info.name in [\"CacheAction\", \"CacheDumpGraph\"] and not log_cache_events\n    )\n\n\ndef setup_event_logger(flags, callbacks: List[Callable[[EventMsg], None]] = []) -> None:\n    cleanup_event_logger()\n    make_log_dir_if_missing(flags.LOG_PATH)\n    event_manager = get_event_manager()\n    event_manager.callbacks = callbacks.copy()\n    add_callback_to_manager(track_behavior_change_warn)\n\n    if flags.LOG_LEVEL != \"none\":\n        line_format = _line_format_from_str(flags.LOG_FORMAT, LineFormat.PlainText)\n        log_level = (\n            EventLevel.ERROR\n            if flags.QUIET\n            else EventLevel.DEBUG if flags.DEBUG else EventLevel(flags.LOG_LEVEL)\n        )\n        console_config = get_stdout_config(\n            line_format,\n            flags.USE_COLORS,\n            log_level,\n            flags.LOG_CACHE_EVENTS,\n        )\n\n        if get_capture_stream():\n            # Create second stdout logger to support test which want to know what's\n            # being sent to stdout.\n            console_config.output_stream = get_capture_stream()\n        add_logger_to_manager(console_config)\n\n    if flags.LOG_LEVEL_FILE != \"none\":\n        # create and add the file logger to the event manager\n        log_file = os.path.join(flags.LOG_PATH, \"dbt.log\")\n        log_file_format = _line_format_from_str(flags.LOG_FORMAT_FILE, LineFormat.DebugText)\n        log_level_file = EventLevel.DEBUG if flags.DEBUG else EventLevel(flags.LOG_LEVEL_FILE)\n        add_logger_to_manager(\n            _get_logfile_config(\n                log_file,\n                flags.USE_COLORS_FILE,\n                log_file_format,\n                log_level_file,\n                flags.LOG_FILE_MAX_BYTES,\n            )\n        )\n"
  },
  {
    "path": "core/dbt/events/types.py",
    "content": "import json\nimport os\nfrom typing import List\n\nfrom dbt.constants import MAXIMUM_SEED_SIZE_NAME, PIN_PACKAGE_URL\nfrom dbt.events.base_types import (\n    DebugLevel,\n    DynamicLevel,\n    ErrorLevel,\n    InfoLevel,\n    WarnLevel,\n)\nfrom dbt.flags import get_flags\nfrom dbt_common.events.base_types import EventLevel\nfrom dbt_common.events.format import (\n    format_fancy_output_line,\n    pluralize,\n    timestamp_to_datetime_string,\n)\nfrom dbt_common.ui import deprecation_tag as deprecation_tag_less_strict\nfrom dbt_common.ui import error_tag, green, line_wrap_message, red, warning_tag, yellow\n\n\n# This makes it so that mypy will complain if a deprecation tag is used without an event name\ndef _deprecation_tag(description: str, event_name: str) -> str:\n    return deprecation_tag_less_strict(description, event_name)\n\n\n# Event codes have prefixes which follow this table\n#\n# | Code |     Description     |\n# |:----:|:-------------------:|\n# | A    | Pre-project loading |\n# | D    | Deprecations        |\n# | E    | DB adapter          |\n# | I    | Project parsing     |\n# | M    | Deps generation     |\n# | P    | Artifacts           |\n# | Q    | Node execution      |\n# | W    | Node testing        |\n# | Z    | Misc                |\n# | T    | Test only           |\n#\n# The basic idea is that event codes roughly translate to the natural order of running a dbt task\n\n# =======================================================\n# A - Pre-project loading\n# =======================================================\n\n\nclass MainReportVersion(InfoLevel):\n    def code(self) -> str:\n        return \"A001\"\n\n    def message(self) -> str:\n        return f\"Running with dbt{self.version}\"\n\n\nclass MainReportArgs(DebugLevel):\n    def code(self) -> str:\n        return \"A002\"\n\n    def message(self) -> str:\n        return f\"running dbt with arguments {str(self.args)}\"\n\n\nclass MainTrackingUserState(DebugLevel):\n    def code(self) -> str:\n        return \"A003\"\n\n    def message(self) -> str:\n        return f\"Tracking: {self.user_state}\"\n\n\n# Removed A004: MergedFromState\n\n\nclass MissingProfileTarget(InfoLevel):\n    def code(self) -> str:\n        return \"A005\"\n\n    def message(self) -> str:\n        return f\"target not specified in profile '{self.profile_name}', using '{self.target_name}'\"\n\n\n# Skipped A006, A007\n\n\nclass InvalidOptionYAML(ErrorLevel):\n    def code(self) -> str:\n        return \"A008\"\n\n    def message(self) -> str:\n        return error_tag(f\"The YAML provided in the --{self.option_name} argument is not valid.\")\n\n\nclass LogDbtProjectError(ErrorLevel):\n    def code(self) -> str:\n        return \"A009\"\n\n    def message(self) -> str:\n        msg = \"Encountered an error while reading the project:\"\n        if self.exc:\n            msg += f\"\\n  {str(self.exc)}\"\n        return error_tag(msg)\n\n\n# Skipped A010\n\n\nclass LogDbtProfileError(ErrorLevel):\n    def code(self) -> str:\n        return \"A011\"\n\n    def message(self) -> str:\n        msg = \"Encountered an error while reading profiles:\\n\" f\"  {str(self.exc)}\"\n        if self.profiles:\n            msg += \"Defined profiles:\\n\"\n            for profile in self.profiles:\n                msg += f\" - {profile}\"\n        else:\n            msg += \"There are no profiles defined in your profiles.yml file\"\n\n        msg += \"\"\"\nFor more information on configuring profiles, please consult the dbt docs:\n\nhttps://docs.getdbt.com/docs/configure-your-profile\n\"\"\"\n        return error_tag(msg)\n\n\nclass StarterProjectPath(DebugLevel):\n    def code(self) -> str:\n        return \"A017\"\n\n    def message(self) -> str:\n        return f\"Starter project path: {self.dir}\"\n\n\nclass ConfigFolderDirectory(InfoLevel):\n    def code(self) -> str:\n        return \"A018\"\n\n    def message(self) -> str:\n        return f\"Creating dbt configuration folder at {self.dir}\"\n\n\nclass NoSampleProfileFound(InfoLevel):\n    def code(self) -> str:\n        return \"A019\"\n\n    def message(self) -> str:\n        return f\"No sample profile found for {self.adapter}.\"\n\n\nclass ProfileWrittenWithSample(InfoLevel):\n    def code(self) -> str:\n        return \"A020\"\n\n    def message(self) -> str:\n        return (\n            f\"Profile {self.name} written to {self.path} \"\n            \"using target's sample configuration. Once updated, you'll be able to \"\n            \"start developing with dbt.\"\n        )\n\n\nclass ProfileWrittenWithTargetTemplateYAML(InfoLevel):\n    def code(self) -> str:\n        return \"A021\"\n\n    def message(self) -> str:\n        return (\n            f\"Profile {self.name} written to {self.path} using target's \"\n            \"profile_template.yml and your supplied values.\"\n        )\n\n\nclass ProfileWrittenWithProjectTemplateYAML(InfoLevel):\n    def code(self) -> str:\n        return \"A022\"\n\n    def message(self) -> str:\n        return (\n            f\"Profile {self.name} written to {self.path} using project's \"\n            \"profile_template.yml and your supplied values.\"\n        )\n\n\nclass SettingUpProfile(InfoLevel):\n    def code(self) -> str:\n        return \"A023\"\n\n    def message(self) -> str:\n        return \"Setting up your profile.\"\n\n\nclass InvalidProfileTemplateYAML(InfoLevel):\n    def code(self) -> str:\n        return \"A024\"\n\n    def message(self) -> str:\n        return \"Invalid profile_template.yml in project.\"\n\n\nclass ProjectNameAlreadyExists(InfoLevel):\n    def code(self) -> str:\n        return \"A025\"\n\n    def message(self) -> str:\n        return f\"A project called {self.name} already exists here.\"\n\n\nclass ProjectCreated(InfoLevel):\n    def code(self) -> str:\n        return \"A026\"\n\n    def message(self) -> str:\n        return f\"\"\"Your new dbt project \"{self.project_name}\" was created!\nInitialized new project in {os.path.abspath(self.project_name)}\n\nFor more information on how to configure the profiles.yml file,\nplease consult the dbt documentation here:\n\n  {self.docs_url}\n\nOne more thing:\n\nNeed help? Don't hesitate to reach out to us via GitHub issues or on Slack:\n\n  {self.slack_url}\n\nHappy modeling!\n\"\"\"\n\n\n# =======================================================\n# D - Deprecations\n# =======================================================\n\n\ndef require_event_names_in_deprecations():\n    # The require_event_names_in_deprecations flag isn't guaranteed to be set by the\n    # time some deprecations are fired. We could have done the following ever single deprecation\n    # that needs it, but this makes it simpler to flip the flag later.\n    return getattr(get_flags(), \"require_event_names_in_deprecations\", False)\n\n\nclass DeprecatedModel(WarnLevel):\n    def code(self) -> str:\n        return \"I065\"\n\n    def message(self) -> str:\n        version = \".v\" + self.model_version if self.model_version else \"\"\n        msg = (\n            f\"Model {self.model_name}{version} has passed its deprecation date of {self.deprecation_date}. \"\n            \"This model should be disabled or removed.\"\n        )\n\n        if require_event_names_in_deprecations():\n            return line_wrap_message(_deprecation_tag(msg, self.__class__.__name__))\n        else:\n            return warning_tag(msg)\n\n\nclass PackageRedirectDeprecation(WarnLevel):\n    def code(self) -> str:\n        return \"D001\"\n\n    def message(self) -> str:\n        description = (\n            f\"The `{self.old_name}` package is deprecated in favor of `{self.new_name}`. Please \"\n            f\"update your `packages.yml` configuration to use `{self.new_name}` instead.\"\n        )\n\n        if require_event_names_in_deprecations():\n            return line_wrap_message(_deprecation_tag(description, self.__class__.__name__))\n        else:\n            return line_wrap_message(deprecation_tag_less_strict(description))\n\n\nclass PackageInstallPathDeprecation(WarnLevel):\n    def code(self) -> str:\n        return \"D002\"\n\n    def message(self) -> str:\n        description = \"\"\"\\\n        The default package install path has changed from `dbt_modules` to `dbt_packages`.\n        Please update `clean-targets` in `dbt_project.yml` and check `.gitignore` as well.\n        Or, set `packages-install-path: dbt_modules` if you'd like to keep the current value.\n        \"\"\"\n\n        if require_event_names_in_deprecations():\n            return line_wrap_message(_deprecation_tag(description, self.__class__.__name__))\n        else:\n            return line_wrap_message(deprecation_tag_less_strict(description))\n\n\nclass ConfigSourcePathDeprecation(WarnLevel):\n    def code(self) -> str:\n        return \"D003\"\n\n    def message(self) -> str:\n        description = (\n            f\"The `{self.deprecated_path}` config has been renamed to `{self.exp_path}`. \"\n            \"Please update your `dbt_project.yml` configuration to reflect this change.\"\n        )\n\n        if require_event_names_in_deprecations():\n            return line_wrap_message(_deprecation_tag(description, self.__class__.__name__))\n        else:\n            return line_wrap_message(deprecation_tag_less_strict(description))\n\n\nclass ConfigDataPathDeprecation(WarnLevel):\n    def code(self) -> str:\n        return \"D004\"\n\n    def message(self) -> str:\n        description = (\n            f\"The `{self.deprecated_path}` config has been renamed to `{self.exp_path}`. \"\n            \"Please update your `dbt_project.yml` configuration to reflect this change.\"\n        )\n\n        if require_event_names_in_deprecations():\n            return line_wrap_message(_deprecation_tag(description, self.__class__.__name__))\n        else:\n            return line_wrap_message(deprecation_tag_less_strict(description))\n\n\nclass MetricAttributesRenamed(WarnLevel):\n    def code(self) -> str:\n        return \"D006\"\n\n    def message(self) -> str:\n        description = (\n            \"dbt-core v1.3 renamed attributes for metrics:\"\n            \"\\n  'sql'              -> 'expression'\"\n            \"\\n  'type'             -> 'calculation_method'\"\n            \"\\n  'type: expression' -> 'calculation_method: derived'\"\n            f\"\\nPlease remove them from the metric definition of metric '{self.metric_name}'\"\n            \"\\nRelevant issue here: https://github.com/dbt-labs/dbt-core/issues/5849\"\n        )\n\n        if require_event_names_in_deprecations():\n            return line_wrap_message(_deprecation_tag(description, self.__class__.__name__))\n        else:\n            return deprecation_tag_less_strict(description)\n\n\nclass ExposureNameDeprecation(WarnLevel):\n    def code(self) -> str:\n        return \"D007\"\n\n    def message(self) -> str:\n        description = (\n            \"Starting in v1.3, the 'name' of an exposure should contain only letters, \"\n            \"numbers, and underscores. Exposures support a new property, 'label', which may \"\n            f\"contain spaces, capital letters, and special characters. {self.exposure} does not \"\n            \"follow this pattern. Please update the 'name', and use the 'label' property for a \"\n            \"human-friendly title. This will raise an error in a future version of dbt-core.\"\n        )\n\n        if require_event_names_in_deprecations():\n            return line_wrap_message(_deprecation_tag(description, self.__class__.__name__))\n        else:\n            return line_wrap_message(deprecation_tag_less_strict(description))\n\n\nclass InternalDeprecation(WarnLevel):\n    def code(self) -> str:\n        return \"D008\"\n\n    def message(self) -> str:\n        extra_reason = \"\"\n        if self.reason:\n            extra_reason = f\"\\n{self.reason}\"\n        msg = (\n            f\"`{self.name}` is deprecated and will be removed in dbt-core version {self.version}\\n\\n\"\n            f\"Adapter maintainers can resolve this deprecation by {self.suggested_action}. {extra_reason}\"\n        )\n\n        if require_event_names_in_deprecations():\n            return _deprecation_tag(msg, self.__class__.__name__)\n        else:\n            return warning_tag(msg)\n\n\nclass EnvironmentVariableRenamed(WarnLevel):\n    def code(self) -> str:\n        return \"D009\"\n\n    def message(self) -> str:\n        description = (\n            f\"The environment variable `{self.old_name}` has been renamed as `{self.new_name}`.\\n\"\n            f\"If `{self.old_name}` is currently set, its value will be used instead of `{self.new_name}`.\\n\"\n            f\"Set `{self.new_name}` and unset `{self.old_name}` to avoid this deprecation warning and \"\n            \"ensure it works properly in a future release.\"\n        )\n\n        if require_event_names_in_deprecations():\n            return line_wrap_message(_deprecation_tag(description, self.__class__.__name__))\n        else:\n            return line_wrap_message(deprecation_tag_less_strict(description))\n\n\nclass ConfigLogPathDeprecation(WarnLevel):\n    def code(self) -> str:\n        return \"D010\"\n\n    def message(self) -> str:\n        output = \"logs\"\n        cli_flag = \"--log-path\"\n        env_var = \"DBT_LOG_PATH\"\n        description = (\n            f\"The `{self.deprecated_path}` config in `dbt_project.yml` has been deprecated, \"\n            f\"and will no longer be supported in a future version of dbt-core. \"\n            f\"If you wish to write dbt {output} to a custom directory, please use \"\n            f\"the {cli_flag} CLI flag or {env_var} env var instead.\"\n        )\n\n        if require_event_names_in_deprecations():\n            return line_wrap_message(_deprecation_tag(description, self.__class__.__name__))\n        else:\n            return line_wrap_message(deprecation_tag_less_strict(description))\n\n\nclass ConfigTargetPathDeprecation(WarnLevel):\n    def code(self) -> str:\n        return \"D011\"\n\n    def message(self) -> str:\n        output = \"artifacts\"\n        cli_flag = \"--target-path\"\n        env_var = \"DBT_TARGET_PATH\"\n        description = (\n            f\"The `{self.deprecated_path}` config in `dbt_project.yml` has been deprecated, \"\n            f\"and will no longer be supported in a future version of dbt-core. \"\n            f\"If you wish to write dbt {output} to a custom directory, please use \"\n            f\"the {cli_flag} CLI flag or {env_var} env var instead.\"\n        )\n\n        if require_event_names_in_deprecations():\n            return line_wrap_message(_deprecation_tag(description, self.__class__.__name__))\n        else:\n            return line_wrap_message(deprecation_tag_less_strict(description))\n\n\n# Note: this deprecation has been removed, but we are leaving\n# the event class here, because users may have specified it in\n# warn_error_options.\nclass TestsConfigDeprecation(WarnLevel):\n    def code(self) -> str:\n        return \"D012\"\n\n    def message(self) -> str:\n        description = (\n            f\"The `{self.deprecated_path}` config has been renamed to `{self.exp_path}`. \"\n            \"Please see https://docs.getdbt.com/docs/build/data-tests#new-data_tests-syntax for more information.\"\n        )\n\n        if require_event_names_in_deprecations():\n            return line_wrap_message(_deprecation_tag(description, self.__class__.__name__))\n        else:\n            return line_wrap_message(deprecation_tag_less_strict(description))\n\n\nclass ProjectFlagsMovedDeprecation(WarnLevel):\n    def code(self) -> str:\n        return \"D013\"\n\n    def message(self) -> str:\n        description = (\n            \"User config should be moved from the 'config' key in profiles.yml to the 'flags' \"\n            \"key in dbt_project.yml.\"\n        )\n        # Can't use line_wrap_message here because flags.printer_width isn't available yet\n        if require_event_names_in_deprecations():\n            return _deprecation_tag(description, self.__class__.__name__)\n        else:\n            return deprecation_tag_less_strict(description)\n\n\nclass SpacesInResourceNameDeprecation(DynamicLevel):\n    def code(self) -> str:\n        return \"D014\"\n\n    def message(self) -> str:\n        description = f\"Found spaces in the name of `{self.unique_id}`\"\n\n        if self.level == EventLevel.ERROR.value:\n            description = error_tag(description)\n        elif self.level == EventLevel.WARN.value:\n            description = warning_tag(description)\n\n        if require_event_names_in_deprecations():\n            return line_wrap_message(_deprecation_tag(description, self.__class__.__name__))\n        else:\n            return line_wrap_message(description)\n\n\nclass ResourceNamesWithSpacesDeprecation(WarnLevel):\n    def code(self) -> str:\n        return \"D015\"\n\n    def message(self) -> str:\n        description = f\"Spaces found in {self.count_invalid_names} resource name(s). This is deprecated, and may lead to errors when using dbt.\"\n\n        if self.show_debug_hint:\n            description += \" Run again with `--debug` to see them all.\"\n\n        description += \" For more information: https://docs.getdbt.com/reference/global-configs/legacy-behaviors\"\n\n        if require_event_names_in_deprecations():\n            return line_wrap_message(_deprecation_tag(description, self.__class__.__name__))\n        else:\n            return line_wrap_message(warning_tag(description))\n\n\nclass PackageMaterializationOverrideDeprecation(WarnLevel):\n    def code(self) -> str:\n        return \"D016\"\n\n    def message(self) -> str:\n        description = f\"Installed package '{self.package_name}' is overriding the built-in materialization '{self.materialization_name}'. Overrides of built-in materializations from installed packages will be deprecated in future versions of dbt. For more information: https://docs.getdbt.com/reference/global-configs/legacy-behaviors\"\n\n        if require_event_names_in_deprecations():\n            return line_wrap_message(_deprecation_tag(description, self.__class__.__name__))\n        else:\n            return line_wrap_message(warning_tag(description))\n\n\nclass SourceFreshnessProjectHooksNotRun(WarnLevel):\n    def code(self) -> str:\n        return \"D017\"\n\n    def message(self) -> str:\n        description = \"In a future version of dbt, the `source freshness` command will start running `on-run-start` and `on-run-end` hooks by default. For more information: https://docs.getdbt.com/reference/global-configs/legacy-behaviors\"\n\n        if require_event_names_in_deprecations():\n            return line_wrap_message(_deprecation_tag(description, self.__class__.__name__))\n        else:\n            return line_wrap_message(warning_tag(description))\n\n\nclass MFTimespineWithoutYamlConfigurationDeprecation(WarnLevel):\n    def code(self) -> str:\n        return \"D018\"\n\n    def message(self) -> str:\n        description = \"Time spines without YAML configuration are in the process of deprecation. Please add YAML configuration for your 'metricflow_time_spine' model. See documentation on MetricFlow time spines: https://docs.getdbt.com/docs/build/metricflow-time-spine and behavior change documentation: https://docs.getdbt.com/reference/global-configs/behavior-changes.\"\n\n        if require_event_names_in_deprecations():\n            return line_wrap_message(_deprecation_tag(description, self.__class__.__name__))\n        else:\n            return line_wrap_message(warning_tag(description))\n\n\nclass MFCumulativeTypeParamsDeprecation(WarnLevel):\n    def code(self) -> str:\n        return \"D019\"\n\n    def message(self) -> str:\n        description = \"Cumulative fields `type_params.window` and `type_params.grain_to_date` have been moved and will soon be deprecated. Please nest those values under `type_params.cumulative_type_params.window` and `type_params.cumulative_type_params.grain_to_date`. See documentation on behavior changes: https://docs.getdbt.com/reference/global-configs/behavior-changes.\"\n\n        if require_event_names_in_deprecations():\n            return line_wrap_message(_deprecation_tag(description, self.__class__.__name__))\n        else:\n            return line_wrap_message(warning_tag(description))\n\n\nclass MicrobatchMacroOutsideOfBatchesDeprecation(WarnLevel):\n    def code(self) -> str:\n        return \"D020\"\n\n    def message(self) -> str:\n        description = \"The use of a custom microbatch macro outside of batched execution is deprecated. To use it with batched execution, set `flags.require_batched_execution_for_custom_microbatch_strategy` to `True` in `dbt_project.yml`. In the future this will be the default behavior.\"\n\n        if require_event_names_in_deprecations():\n            return line_wrap_message(_deprecation_tag(description, self.__class__.__name__))\n        else:\n            return line_wrap_message(warning_tag(description))\n\n\n# Skipping D021. It belonged to the now deleted PackageRedirectDeprecationSummary event.\n\n\nclass GenericJSONSchemaValidationDeprecation(WarnLevel):\n    def code(self) -> str:\n        return \"D022\"\n\n    def message(self) -> str:\n        possible_causes = \"This generally means that either we failed to catch this as a more specific deprecation type OR our JSONSchema had a regression (and this deprecation was erroneous).\"\n\n        if self.key_path == \"\":\n            description = f\"{self.violation} at top level in file `{self.file}` is possibly a deprecation. {possible_causes}\"\n        else:\n            description = f\"{self.violation} in file `{self.file}` at path `{self.key_path}` is possibly a deprecation. {possible_causes}\"\n\n        return line_wrap_message(_deprecation_tag(description, self.__class__.__name__))\n\n\nclass UnexpectedJinjaBlockDeprecation(WarnLevel):\n    def code(self) -> str:\n        return \"D023\"\n\n    def message(self) -> str:\n        description = f\"{self.msg} in file `{self.file}`\"\n        return line_wrap_message(_deprecation_tag(description, self.__class__.__name__))\n\n\nclass DuplicateYAMLKeysDeprecation(WarnLevel):\n    def code(self) -> str:\n        return \"D024\"\n\n    def message(self) -> str:\n        description = f\"{self.duplicate_description} in file `{self.file}`\"\n        return line_wrap_message(_deprecation_tag(description, self.__class__.__name__))\n\n\nclass CustomTopLevelKeyDeprecation(WarnLevel):\n    def code(self) -> str:\n        return \"D025\"\n\n    def message(self) -> str:\n        description = f\"{self.msg} in file `{self.file}`\"\n        return line_wrap_message(_deprecation_tag(description, self.__class__.__name__))\n\n\nclass CustomKeyInConfigDeprecation(WarnLevel):\n    def code(self) -> str:\n        return \"D026\"\n\n    def message(self) -> str:\n        path_specification = \"\"\n        if self.key_path != \"\":\n            path_specification = f\" at path `{self.key_path}`\"\n\n        description = f\"Custom key `{self.key}` found in `config`{path_specification} in file `{self.file}`. Custom config keys should move into the `config.meta`.\"\n        return line_wrap_message(_deprecation_tag(description, self.__class__.__name__))\n\n\nclass CustomKeyInObjectDeprecation(WarnLevel):\n    def code(self) -> str:\n        return \"D027\"\n\n    def message(self) -> str:\n        description = f\"Custom key `{self.key}` found at `{self.key_path}` in file `{self.file}`. This may mean the key is a typo, or is simply not a key supported by the object.\"\n        return line_wrap_message(_deprecation_tag(description, self.__class__.__name__))\n\n\nclass DeprecationsSummary(WarnLevel):\n    def code(self) -> str:\n        return \"D028\"\n\n    def message(self) -> str:\n        description = \"Summary of encountered deprecations:\"\n        for summary in self.summaries:\n            description += (\n                f\"\\n\\n- {summary.event_name}: {pluralize(summary.occurrences, 'occurrence')}\"\n            )\n\n        if self.show_all_hint:\n            description += \"\\n\\nTo see all deprecation instances instead of just the first occurrence of each, run command again with the `--show-all-deprecations` flag. You may also need to run with `--no-partial-parse` as some deprecations are only encountered during parsing.\"\n\n        return line_wrap_message(_deprecation_tag(description, self.__class__.__name__))\n\n\nclass CustomOutputPathInSourceFreshnessDeprecation(WarnLevel):\n    def code(self) -> str:\n        return \"D029\"\n\n    def message(self) -> str:\n        description = f\"Custom output path usage `--output {self.path}` usage detected in `dbt source freshness` command.\"\n        return line_wrap_message(_deprecation_tag(description, self.__class__.__name__))\n\n\nclass PropertyMovedToConfigDeprecation(WarnLevel):\n    def code(self) -> str:\n        return \"D030\"\n\n    def message(self) -> str:\n        description = f\"Found `{self.key}` as a top-level property of `{self.key_path}` in file `{self.file}`. The `{self.key}` top-level property should be moved into the `config` of `{self.key_path}`.\"\n        return line_wrap_message(_deprecation_tag(description, self.__class__.__name__))\n\n\nclass WEOIncludeExcludeDeprecation(WarnLevel):\n    def code(self) -> str:\n        return \"D031\"\n\n    def message(self) -> str:\n        found_keys: List[str] = []\n        if self.found_include:\n            found_keys.append(\"`include`\")\n        if self.found_exclude:\n            found_keys.append(\"`exclude`\")\n\n        description = f\"Found {' and '.join(found_keys)} in `warn_error_options` specification.\"\n        if self.found_include:\n            description += \" Please use `error` instead of `include`.\"\n        if self.found_exclude:\n            description += \" Please use `warn` instead of `exclude`.\"\n\n        return line_wrap_message(_deprecation_tag(description, self.__class__.__name__))\n\n\nclass ModelParamUsageDeprecation(WarnLevel):\n    def code(self) -> str:\n        return \"D032\"\n\n    def message(self) -> str:\n        description = \"Usage of `--models`, `--model`, and `-m` is deprecated in favor of `--select` or `-s`.\"\n        return line_wrap_message(_deprecation_tag(description, self.__class__.__name__))\n\n\nclass ModulesItertoolsUsageDeprecation(WarnLevel):\n    def code(self) -> str:\n        return \"D034\"\n\n    def message(self) -> str:\n        description = (\n            \"Usage of itertools modules is deprecated. Please use the built-in functions instead.\"\n        )\n        return line_wrap_message(_deprecation_tag(description, self.__class__.__name__))\n\n\nclass SourceOverrideDeprecation(WarnLevel):\n    def code(self) -> str:\n        return \"D035\"\n\n    def message(self) -> str:\n        description = f\"The source property `overrides` is deprecated but was found on source `{self.source_name}` in file `{self.file}`. Instead, `enabled` should be used to disable the unwanted source.\"\n        return line_wrap_message(_deprecation_tag(description, self.__class__.__name__))\n\n\nclass EnvironmentVariableNamespaceDeprecation(WarnLevel):\n    def code(self) -> str:\n        return \"D036\"\n\n    def message(self) -> str:\n        description = f\"Found custom environment variable `{self.env_var}` in the environment. The prefix `{self.reserved_prefix}` is reserved for dbt engine environment variables. Custom environment variables with the prefix `{self.reserved_prefix}` may cause collisions and runtime errors.\"\n        return line_wrap_message(_deprecation_tag(description, self.__class__.__name__))\n\n\nclass MissingPlusPrefixDeprecation(WarnLevel):\n    def code(self) -> str:\n        return \"D037\"\n\n    def message(self) -> str:\n        description = f\"Missing '+' prefix on `{self.key}` found at `{self.key_path}` in file `{self.file}`. Hierarchical config values without a '+' prefix are deprecated in dbt_project.yml.\"\n        return line_wrap_message(_deprecation_tag(description, self.__class__.__name__))\n\n\nclass ArgumentsPropertyInGenericTestDeprecation(WarnLevel):\n    def code(self) -> str:\n        return \"D038\"\n\n    def message(self) -> str:\n        description = f\"Found `arguments` property in test definition of {self.test_name} without usage of `require_generic_test_arguments_property` behavior change flag. The `arguments` property is deprecated for custom usage and will be used to nest keyword arguments in future versions of dbt.\"\n        return line_wrap_message(_deprecation_tag(description, self.__class__.__name__))\n\n\nclass MissingArgumentsPropertyInGenericTestDeprecation(WarnLevel):\n    def code(self) -> str:\n        return \"D039\"\n\n    def message(self) -> str:\n        description = f\"Found top-level arguments to test {self.test_name}. Arguments to generic tests should be nested under the `arguments` property.\"\n        return line_wrap_message(_deprecation_tag(description, self.__class__.__name__))\n\n\nclass DuplicateNameDistinctNodeTypesDeprecation(WarnLevel):\n    def code(self) -> str:\n        return \"D040\"\n\n    def message(self) -> str:\n        description = f\"Found resources with the same name '{self.resource_name}' in package '{self.package_name}': '{self.unique_id1}' and '{self.unique_id2}'. Please update one of the resources to have a unique name.\"\n        return line_wrap_message(_deprecation_tag(description, self.__class__.__name__))\n\n\nclass TimeDimensionsRequireGranularityDeprecation(WarnLevel):\n    def code(self) -> str:\n        return \"D041\"\n\n    def message(self) -> str:\n        return line_wrap_message(_deprecation_tag(self.msg, self.__class__.__name__))\n\n\nclass GenericSemanticLayerDeprecation(WarnLevel):\n    def code(self) -> str:\n        return \"D042\"\n\n    def message(self) -> str:\n        return line_wrap_message(_deprecation_tag(self.msg, self.__class__.__name__))\n\n\nclass GenerateSchemaNameNullValueDeprecation(WarnLevel):\n    def code(self) -> str:\n        return \"D044\"\n\n    def message(self) -> str:\n        description = f\"Node '{self.resource_unique_id}' has a schema set to None as a result of a generate_schema_name call. Please set a valid schema name.\"\n        return line_wrap_message(_deprecation_tag(description, self.__class__.__name__))\n\n\n# =======================================================\n# I - Project parsing\n# =======================================================\n\n\nclass InputFileDiffError(DebugLevel):\n    def code(self) -> str:\n        return \"I001\"\n\n    def message(self) -> str:\n        return f\"Error processing file diff: {self.category}, {self.file_id}\"\n\n\n# Skipping I003, I004, I005, I006, I007\n\n\nclass InvalidValueForField(WarnLevel):\n    def code(self) -> str:\n        return \"I008\"\n\n    def message(self) -> str:\n        return warning_tag(f\"Invalid value ({self.field_value}) for field {self.field_name}\")\n\n\nclass ValidationWarning(WarnLevel):\n    def code(self) -> str:\n        return \"I009\"\n\n    def message(self) -> str:\n        return warning_tag(\n            f\"Field {self.field_name} is not valid for {self.resource_type} ({self.node_name})\"\n        )\n\n\nclass ParsePerfInfoPath(InfoLevel):\n    def code(self) -> str:\n        return \"I010\"\n\n    def message(self) -> str:\n        return f\"Performance info: {self.path}\"\n\n\n# Removed I011: GenericTestFileParse\n\n\n# Removed I012: MacroFileParse\n\n\n# Skipping I013\n\n\nclass PartialParsingErrorProcessingFile(DebugLevel):\n    def code(self) -> str:\n        return \"I014\"\n\n    def message(self) -> str:\n        return f\"Partial parsing exception processing file {self.file}\"\n\n\n# Skipped I015\n\n\nclass PartialParsingError(DebugLevel):\n    def code(self) -> str:\n        return \"I016\"\n\n    def message(self) -> str:\n        return f\"PP exception info: {self.exc_info}\"\n\n\nclass PartialParsingSkipParsing(DebugLevel):\n    def code(self) -> str:\n        return \"I017\"\n\n    def message(self) -> str:\n        return \"Partial parsing enabled, no changes found, skipping parsing\"\n\n\n# Skipped I018, I019, I020, I021, I022, I023\n\n\nclass UnableToPartialParse(InfoLevel):\n    def code(self) -> str:\n        return \"I024\"\n\n    def message(self) -> str:\n        return f\"Unable to do partial parsing because {self.reason}\"\n\n\nclass StateCheckVarsHash(DebugLevel):\n    def code(self) -> str:\n        return \"I025\"\n\n    def message(self) -> str:\n        return f\"checksum: {self.checksum}, vars: {self.vars}, profile: {self.profile}, target: {self.target}, version: {self.version}\"\n\n\n# Skipped I025, I026, I026, I027\n\n\nclass PartialParsingNotEnabled(DebugLevel):\n    def code(self) -> str:\n        return \"I028\"\n\n    def message(self) -> str:\n        return \"Partial parsing not enabled\"\n\n\nclass ParsedFileLoadFailed(DebugLevel):\n    def code(self) -> str:\n        return \"I029\"\n\n    def message(self) -> str:\n        return f\"Failed to load parsed file from disk at {self.path}: {self.exc}\"\n\n\n# Skipped I030-I039\n\n\nclass PartialParsingEnabled(DebugLevel):\n    def code(self) -> str:\n        return \"I040\"\n\n    def message(self) -> str:\n        return (\n            f\"Partial parsing enabled: \"\n            f\"{self.deleted} files deleted, \"\n            f\"{self.added} files added, \"\n            f\"{self.changed} files changed.\"\n        )\n\n\nclass PartialParsingFile(DebugLevel):\n    def code(self) -> str:\n        return \"I041\"\n\n    def message(self) -> str:\n        return f\"Partial parsing: {self.operation} file: {self.file_id}\"\n\n\n# Skipped I042, I043, I044, I045, I046, I047, I048, I049\n\n\nclass InvalidDisabledTargetInTestNode(DebugLevel):\n    def code(self) -> str:\n        return \"I050\"\n\n    def message(self) -> str:\n        target_package_string = \"\"\n\n        if self.target_package != target_package_string:\n            target_package_string = f\"in package '{self.target_package}' \"\n\n        msg = (\n            f\"{self.resource_type_title} '{self.unique_id}' \"\n            f\"({self.original_file_path}) depends on a {self.target_kind} \"\n            f\"named '{self.target_name}' {target_package_string}which is disabled\"\n        )\n\n        return warning_tag(msg)\n\n\nclass UnusedResourceConfigPath(WarnLevel):\n    def code(self) -> str:\n        return \"I051\"\n\n    def message(self) -> str:\n        path_list = \"\\n\".join(f\"- {u}\" for u in self.unused_config_paths)\n        msg = (\n            \"Configuration paths exist in your dbt_project.yml file which do not \"\n            \"apply to any resources.\\n\"\n            f\"There are {len(self.unused_config_paths)} unused configuration paths:\\n{path_list}\"\n        )\n        return warning_tag(msg)\n\n\nclass SeedIncreased(WarnLevel):\n    def code(self) -> str:\n        return \"I052\"\n\n    def message(self) -> str:\n        msg = (\n            f\"Found a seed ({self.package_name}.{self.name}) \"\n            f\">{MAXIMUM_SEED_SIZE_NAME} in size. The previous file was \"\n            f\"<={MAXIMUM_SEED_SIZE_NAME}, so it has changed\"\n        )\n        return warning_tag(msg)\n\n\nclass SeedExceedsLimitSamePath(WarnLevel):\n    def code(self) -> str:\n        return \"I053\"\n\n    def message(self) -> str:\n        msg = (\n            f\"Found a seed ({self.package_name}.{self.name}) \"\n            f\">{MAXIMUM_SEED_SIZE_NAME} in size at the same path, dbt \"\n            f\"cannot tell if it has changed: assuming they are the same\"\n        )\n        return warning_tag(msg)\n\n\nclass SeedExceedsLimitAndPathChanged(WarnLevel):\n    def code(self) -> str:\n        return \"I054\"\n\n    def message(self) -> str:\n        msg = (\n            f\"Found a seed ({self.package_name}.{self.name}) \"\n            f\">{MAXIMUM_SEED_SIZE_NAME} in size. The previous file was in \"\n            f\"a different location, assuming it has changed\"\n        )\n        return warning_tag(msg)\n\n\nclass SeedExceedsLimitChecksumChanged(WarnLevel):\n    def code(self) -> str:\n        return \"I055\"\n\n    def message(self) -> str:\n        msg = (\n            f\"Found a seed ({self.package_name}.{self.name}) \"\n            f\">{MAXIMUM_SEED_SIZE_NAME} in size. The previous file had a \"\n            f\"checksum type of {self.checksum_name}, so it has changed\"\n        )\n        return warning_tag(msg)\n\n\nclass UnusedTables(WarnLevel):\n    def code(self) -> str:\n        return \"I056\"\n\n    def message(self) -> str:\n        msg = [\n            \"During parsing, dbt encountered source overrides that had no target:\",\n        ]\n        msg += self.unused_tables\n        msg.append(\"\")\n        return warning_tag(\"\\n\".join(msg))\n\n\nclass WrongResourceSchemaFile(WarnLevel):\n    def code(self) -> str:\n        return \"I057\"\n\n    def message(self) -> str:\n        msg = line_wrap_message(\n            f\"\"\"\\\n            '{self.patch_name}' is a {self.resource_type} node, but it is\n            specified in the {self.yaml_key} section of\n            {self.file_path}.\n            To fix this error, place the `{self.patch_name}`\n            specification under the {self.plural_resource_type} key instead.\n            \"\"\"\n        )\n        return warning_tag(msg)\n\n\nclass NoNodeForYamlKey(WarnLevel):\n    def code(self) -> str:\n        return \"I058\"\n\n    def message(self) -> str:\n        msg = (\n            f\"Did not find matching node for patch with name '{self.patch_name}' \"\n            f\"in the '{self.yaml_key}' section of \"\n            f\"file '{self.file_path}'\"\n        )\n        return warning_tag(msg)\n\n\nclass MacroNotFoundForPatch(WarnLevel):\n    def code(self) -> str:\n        return \"I059\"\n\n    def message(self) -> str:\n        msg = f'Found patch for macro \"{self.patch_name}\" which was not found'\n        return warning_tag(msg)\n\n\nclass NodeNotFoundOrDisabled(WarnLevel):\n    def code(self) -> str:\n        return \"I060\"\n\n    def message(self) -> str:\n        # this is duplicated logic from exceptions.get_not_found_or_disabled_msg\n        # when we convert exceptions to be structured maybe it can be combined?\n        # converting the bool to a string since None is also valid\n        if self.disabled == \"None\":\n            reason = \"was not found or is disabled\"\n        elif self.disabled == \"True\":\n            reason = \"is disabled\"\n        else:\n            reason = \"was not found\"\n\n        target_package_string = \"\"\n\n        if self.target_package is not None:\n            target_package_string = f\"in package '{self.target_package}' \"\n\n        msg = (\n            f\"{self.resource_type_title} '{self.unique_id}' \"\n            f\"({self.original_file_path}) depends on a {self.target_kind} \"\n            f\"named '{self.target_name}' {target_package_string}which {reason}\"\n        )\n\n        return warning_tag(msg)\n\n\nclass JinjaLogWarning(WarnLevel):\n    def code(self) -> str:\n        return \"I061\"\n\n    def message(self) -> str:\n        return warning_tag(self.msg)\n\n\nclass JinjaLogInfo(InfoLevel):\n    def code(self) -> str:\n        return \"I062\"\n\n    def message(self) -> str:\n        # This is for the log method used in macros so msg cannot be built here\n        return self.msg\n\n\nclass JinjaLogDebug(DebugLevel):\n    def code(self) -> str:\n        return \"I063\"\n\n    def message(self) -> str:\n        # This is for the log method used in macros so msg cannot be built here\n        return self.msg\n\n\nclass UnpinnedRefNewVersionAvailable(InfoLevel):\n    def code(self) -> str:\n        return \"I064\"\n\n    def message(self) -> str:\n        msg = (\n            f\"While compiling '{self.node_info.node_name}':\\n\"\n            f\"Found an unpinned reference to versioned model '{self.ref_node_name}' in project '{self.ref_node_package}'.\\n\"\n            f\"Resolving to latest version: {self.ref_node_name}.v{self.ref_node_version}\\n\"\n            f\"A prerelease version {self.ref_max_version} is available. It has not yet been marked 'latest' by its maintainer.\\n\"\n            f\"When that happens, this reference will resolve to {self.ref_node_name}.v{self.ref_max_version} instead.\\n\\n\"\n            f\"  Try out v{self.ref_max_version}: {{{{ ref('{self.ref_node_package}', '{self.ref_node_name}', v='{self.ref_max_version}') }}}}\\n\"\n            f\"  Pin to  v{self.ref_node_version}: {{{{ ref('{self.ref_node_package}', '{self.ref_node_name}', v='{self.ref_node_version}') }}}}\\n\"\n        )\n        return msg\n\n\nclass UpcomingReferenceDeprecation(WarnLevel):\n    def code(self) -> str:\n        return \"I066\"\n\n    def message(self) -> str:\n        ref_model_version = \".v\" + self.ref_model_version if self.ref_model_version else \"\"\n        msg = (\n            f\"While compiling '{self.model_name}': Found a reference to {self.ref_model_name}{ref_model_version}, \"\n            f\"which is slated for deprecation on '{self.ref_model_deprecation_date}'. \"\n        )\n\n        if self.ref_model_version and self.ref_model_version != self.ref_model_latest_version:\n            coda = (\n                f\"A new version of '{self.ref_model_name}' is available. Try it out: \"\n                f\"{{{{ ref('{self.ref_model_package}', '{self.ref_model_name}', \"\n                f\"v='{self.ref_model_latest_version}') }}}}.\"\n            )\n            msg = msg + coda\n\n        return warning_tag(msg)\n\n\nclass DeprecatedReference(WarnLevel):\n    def code(self) -> str:\n        return \"I067\"\n\n    def message(self) -> str:\n        ref_model_version = \".v\" + self.ref_model_version if self.ref_model_version else \"\"\n        msg = (\n            f\"While compiling '{self.model_name}': Found a reference to {self.ref_model_name}{ref_model_version}, \"\n            f\"which was deprecated on '{self.ref_model_deprecation_date}'. \"\n        )\n\n        if self.ref_model_version and self.ref_model_version != self.ref_model_latest_version:\n            coda = (\n                f\"A new version of '{self.ref_model_name}' is available. Migrate now: \"\n                f\"{{{{ ref('{self.ref_model_package}', '{self.ref_model_name}', \"\n                f\"v='{self.ref_model_latest_version}') }}}}.\"\n            )\n            msg = msg + coda\n\n        return warning_tag(msg)\n\n\nclass UnsupportedConstraintMaterialization(WarnLevel):\n    def code(self) -> str:\n        return \"I068\"\n\n    def message(self) -> str:\n        msg = (\n            f\"Constraint types are not supported for {self.materialized} materializations and will \"\n            \"be ignored.  Set 'warn_unsupported: false' on this constraint to ignore this warning.\"\n        )\n\n        return line_wrap_message(warning_tag(msg))\n\n\nclass ParseInlineNodeError(ErrorLevel):\n    def code(self) -> str:\n        return \"I069\"\n\n    def message(self) -> str:\n        return error_tag(\"Error while parsing node: \" + self.node_info.node_name + \"\\n\" + self.exc)\n\n\nclass SemanticValidationFailure(WarnLevel):\n    def code(self) -> str:\n        return \"I070\"\n\n    def message(self) -> str:\n        return warning_tag(self.msg)\n\n\nclass UnversionedBreakingChange(WarnLevel):\n    def code(self) -> str:\n        return \"I071\"\n\n    def message(self) -> str:\n        reasons = \"\\n  - \".join(self.breaking_changes)\n\n        msg = (\n            f\"Breaking change to contracted, unversioned model {self.model_name} ({self.model_file_path})\"\n            \"\\nWhile comparing to previous project state, dbt detected a breaking change to an unversioned model.\"\n            f\"\\n  - {reasons}\\n\"\n        )\n\n        return warning_tag(msg)\n\n\nclass WarnStateTargetEqual(WarnLevel):\n    def code(self) -> str:\n        return \"I072\"\n\n    def message(self) -> str:\n        return warning_tag(\n            f\"The state and target directories are the same: '{self.state_path}'. \"\n            f\"This could lead to missing changes due to overwritten state including non-idempotent retries.\"\n        )\n\n\nclass FreshnessConfigProblem(WarnLevel):\n    def code(self) -> str:\n        return \"I073\"\n\n    def message(self) -> str:\n        return warning_tag(self.msg)\n\n\nclass MicrobatchModelNoEventTimeInputs(WarnLevel):\n    def code(self) -> str:\n        return \"I074\"\n\n    def message(self) -> str:\n        msg = (\n            f\"The microbatch model '{self.model_name}' has no 'ref' or 'source' input with an 'event_time' configuration. \"\n            \"\\nThis means no filtering can be applied and can result in unexpected duplicate records in the resulting microbatch model.\"\n        )\n\n        return warning_tag(msg)\n\n\nclass InvalidConcurrentBatchesConfig(WarnLevel):\n    def code(self) -> str:\n        return \"I075\"\n\n    def message(self) -> str:\n        maybe_plural_count_of_models = pluralize(self.num_models, \"microbatch model\")\n        description = f\"Found {maybe_plural_count_of_models} with the `concurrent_batches` config set to true, but the {self.adapter_type} adapter does not support running batches concurrently. Batches will be run sequentially.\"\n        return line_wrap_message(warning_tag(description))\n\n\nclass InvalidMacroAnnotation(WarnLevel):\n    def code(self) -> str:\n        return \"I076\"\n\n    def message(self) -> str:\n        return warning_tag(self.msg)\n\n\nclass PackageNodeDependsOnRootProjectNode(WarnLevel):\n    def code(self) -> str:\n        return \"I077\"\n\n    def message(self) -> str:\n        msg = (\n            f\"The node '{self.node_name}'in package '{self.package_name}' depends on the root project node '{self.root_project_unique_id}'.\"\n            \"This may lead to unexpected cycles downstream. Please set the 'require_ref_searches_node_package_before_root' behavior change flag to True to avoid this issue.\"\n            \"For more information, see the documentation at https://docs.getdbt.com/reference/global-configs/behavior-changes#package-ref-search-order\"\n        )\n        return warning_tag(msg)\n\n\n# =======================================================\n# M - Deps generation\n# =======================================================\n\n\nclass GitSparseCheckoutSubdirectory(DebugLevel):\n    def code(self) -> str:\n        return \"M001\"\n\n    def message(self) -> str:\n        return f\"Subdirectory specified: {self.subdir}, using sparse checkout.\"\n\n\nclass GitProgressCheckoutRevision(DebugLevel):\n    def code(self) -> str:\n        return \"M002\"\n\n    def message(self) -> str:\n        return f\"Checking out revision {self.revision}.\"\n\n\nclass GitProgressUpdatingExistingDependency(DebugLevel):\n    def code(self) -> str:\n        return \"M003\"\n\n    def message(self) -> str:\n        return f\"Updating existing dependency {self.dir}.\"\n\n\nclass GitProgressPullingNewDependency(DebugLevel):\n    def code(self) -> str:\n        return \"M004\"\n\n    def message(self) -> str:\n        return f\"Pulling new dependency {self.dir}.\"\n\n\nclass GitNothingToDo(DebugLevel):\n    def code(self) -> str:\n        return \"M005\"\n\n    def message(self) -> str:\n        return f\"Already at {self.sha}, nothing to do.\"\n\n\nclass GitProgressUpdatedCheckoutRange(DebugLevel):\n    def code(self) -> str:\n        return \"M006\"\n\n    def message(self) -> str:\n        return f\"Updated checkout from {self.start_sha} to {self.end_sha}.\"\n\n\nclass GitProgressCheckedOutAt(DebugLevel):\n    def code(self) -> str:\n        return \"M007\"\n\n    def message(self) -> str:\n        return f\"Checked out at {self.end_sha}.\"\n\n\nclass RegistryProgressGETRequest(DebugLevel):\n    def code(self) -> str:\n        return \"M008\"\n\n    def message(self) -> str:\n        return f\"Making package registry request: GET {self.url}\"\n\n\nclass RegistryProgressGETResponse(DebugLevel):\n    def code(self) -> str:\n        return \"M009\"\n\n    def message(self) -> str:\n        return f\"Response from registry: GET {self.url} {self.resp_code}\"\n\n\nclass SelectorReportInvalidSelector(InfoLevel):\n    def code(self) -> str:\n        return \"M010\"\n\n    def message(self) -> str:\n        return (\n            f\"The '{self.spec_method}' selector specified in {self.raw_spec} is \"\n            f\"invalid. Must be one of [{self.valid_selectors}]\"\n        )\n\n\nclass DepsNoPackagesFound(InfoLevel):\n    def code(self) -> str:\n        return \"M013\"\n\n    def message(self) -> str:\n        return \"Warning: No packages were found in packages.yml\"\n\n\nclass DepsStartPackageInstall(InfoLevel):\n    def code(self) -> str:\n        return \"M014\"\n\n    def message(self) -> str:\n        return f\"Installing {self.package_name}\"\n\n\nclass DepsInstallInfo(InfoLevel):\n    def code(self) -> str:\n        return \"M015\"\n\n    def message(self) -> str:\n        return f\"Installed from {self.version_name}\"\n\n\nclass DepsUpdateAvailable(InfoLevel):\n    def code(self) -> str:\n        return \"M016\"\n\n    def message(self) -> str:\n        return f\"Updated version available: {self.version_latest}\"\n\n\nclass DepsUpToDate(InfoLevel):\n    def code(self) -> str:\n        return \"M017\"\n\n    def message(self) -> str:\n        return \"Up to date!\"\n\n\nclass DepsListSubdirectory(InfoLevel):\n    def code(self) -> str:\n        return \"M018\"\n\n    def message(self) -> str:\n        return f\"and subdirectory {self.subdirectory}\"\n\n\nclass DepsNotifyUpdatesAvailable(InfoLevel):\n    def code(self) -> str:\n        return \"M019\"\n\n    def message(self) -> str:\n        return f\"Updates available for packages: {self.packages} \\\n                \\nUpdate your versions in packages.yml, then run dbt deps\"\n\n\nclass RegistryIndexProgressGETRequest(DebugLevel):\n    def code(self) -> str:\n        return \"M022\"\n\n    def message(self) -> str:\n        return f\"Making package index registry request: GET {self.url}\"\n\n\nclass RegistryIndexProgressGETResponse(DebugLevel):\n    def code(self) -> str:\n        return \"M023\"\n\n    def message(self) -> str:\n        return f\"Response from registry index: GET {self.url} {self.resp_code}\"\n\n\nclass RegistryResponseUnexpectedType(DebugLevel):\n    def code(self) -> str:\n        return \"M024\"\n\n    def message(self) -> str:\n        return f\"Response was None: {self.response}\"\n\n\nclass RegistryResponseMissingTopKeys(DebugLevel):\n    def code(self) -> str:\n        return \"M025\"\n\n    def message(self) -> str:\n        # expected/actual keys logged in exception\n        return f\"Response missing top level keys: {self.response}\"\n\n\nclass RegistryResponseMissingNestedKeys(DebugLevel):\n    def code(self) -> str:\n        return \"M026\"\n\n    def message(self) -> str:\n        # expected/actual keys logged in exception\n        return f\"Response missing nested keys: {self.response}\"\n\n\nclass RegistryResponseExtraNestedKeys(DebugLevel):\n    def code(self) -> str:\n        return \"M027\"\n\n    def message(self) -> str:\n        # expected/actual keys logged in exception\n        return f\"Response contained inconsistent keys: {self.response}\"\n\n\nclass DepsSetDownloadDirectory(DebugLevel):\n    def code(self) -> str:\n        return \"M028\"\n\n    def message(self) -> str:\n        return f\"Set downloads directory='{self.path}'\"\n\n\nclass DepsUnpinned(WarnLevel):\n    def code(self) -> str:\n        return \"M029\"\n\n    def message(self) -> str:\n        if self.revision == \"HEAD\":\n            unpinned_msg = \"not pinned, using HEAD (default branch)\"\n        elif self.revision in (\"main\", \"master\"):\n            unpinned_msg = f'pinned to the \"{self.revision}\" branch'\n        else:\n            unpinned_msg = None\n\n        msg = (\n            f'The git package \"{self.git}\" \\n\\tis {unpinned_msg}.\\n\\tThis can introduce '\n            f\"breaking changes into your project without warning!\\n\\nSee {PIN_PACKAGE_URL}\"\n        )\n        return warning_tag(msg)\n\n\nclass NoNodesForSelectionCriteria(WarnLevel):\n    def code(self) -> str:\n        return \"M030\"\n\n    def message(self) -> str:\n        return warning_tag(\n            f\"The selection criterion '{self.spec_raw}' does not match any enabled nodes\"\n        )\n\n\nclass DepsLockUpdating(InfoLevel):\n    def code(self):\n        return \"M031\"\n\n    def message(self) -> str:\n        return f\"Updating lock file in file path: {self.lock_filepath}\"\n\n\nclass DepsAddPackage(InfoLevel):\n    def code(self):\n        return \"M032\"\n\n    def message(self) -> str:\n        return f\"Added new package {self.package_name}@{self.version} to {self.packages_filepath}\"\n\n\nclass DepsFoundDuplicatePackage(InfoLevel):\n    def code(self):\n        return \"M033\"\n\n    def message(self) -> str:\n        return f\"Found duplicate package in packages.yml, removing: {self.removed_package}\"\n\n\nclass DepsScrubbedPackageName(WarnLevel):\n    def code(self):\n        return \"M035\"\n\n    def message(self) -> str:\n        return warning_tag(\n            f\"Detected secret env var in {self.package_name}. dbt will write a scrubbed representation to the lock file. This will cause issues with subsequent 'dbt deps' using the lock file, requiring 'dbt deps --upgrade'\"\n        )\n\n\n# =======================================================\n# P - Artifacts\n# =======================================================\n\n\nclass ArtifactWritten(DebugLevel):\n    def code(self):\n        return \"P001\"\n\n    def message(self) -> str:\n        return f\"Wrote artifact {self.artifact_type} to {self.artifact_path}\"\n\n\n# =======================================================\n# Q - Node execution\n# =======================================================\n\n\nclass RunningOperationCaughtError(ErrorLevel):\n    def code(self) -> str:\n        return \"Q001\"\n\n    def message(self) -> str:\n        return error_tag(f\"Encountered an error while running operation: {self.exc}\")\n\n\nclass CompileComplete(InfoLevel):\n    def code(self) -> str:\n        return \"Q002\"\n\n    def message(self) -> str:\n        return \"Done.\"\n\n\nclass FreshnessCheckComplete(InfoLevel):\n    def code(self) -> str:\n        return \"Q003\"\n\n    def message(self) -> str:\n        return \"Done.\"\n\n\nclass SeedHeader(InfoLevel):\n    def code(self) -> str:\n        return \"Q004\"\n\n    def message(self) -> str:\n        return self.header\n\n\nclass SQLRunnerException(DebugLevel):\n    def code(self) -> str:\n        return \"Q006\"\n\n    def message(self) -> str:\n        return f\"Got an exception: {self.exc}\"\n\n\nclass LogTestResult(DynamicLevel):\n    def code(self) -> str:\n        return \"Q007\"\n\n    def message(self) -> str:\n        if self.status == \"error\":\n            info = \"ERROR\"\n            status = red(\n                info,\n            )\n        elif self.status == \"pass\":\n            info = \"PASS\"\n            status = green(info)\n        elif self.status == \"warn\":\n            info = f\"WARN {self.num_failures}\"\n            status = yellow(info)\n        else:  # self.status == \"fail\":\n            info = f\"FAIL {self.num_failures}\"\n            status = red(info)\n        msg = f\"{info} {self.name}\"\n\n        return format_fancy_output_line(\n            msg=msg,\n            status=status,\n            index=self.index,\n            total=self.num_models,\n            execution_time=self.execution_time,\n        )\n\n    @classmethod\n    def status_to_level(cls, status):\n        # The statuses come from TestStatus\n        level_lookup = {\n            \"fail\": EventLevel.ERROR,\n            \"pass\": EventLevel.INFO,\n            \"warn\": EventLevel.WARN,\n            \"error\": EventLevel.ERROR,\n        }\n        if status in level_lookup:\n            return level_lookup[status]\n        else:\n            return EventLevel.INFO\n\n\nclass LogNodeResult(DynamicLevel):\n    def code(self) -> str:\n        return \"Q008\"\n\n    def message(self) -> str:\n        return self.msg\n\n\n# Skipped Q009, Q010\n\n\nclass LogStartLine(InfoLevel):\n    def code(self) -> str:\n        return \"Q011\"\n\n    def message(self) -> str:\n        msg = f\"START {self.description}\"\n        return format_fancy_output_line(msg=msg, status=\"RUN\", index=self.index, total=self.total)\n\n\nclass LogModelResult(DynamicLevel):\n    def code(self) -> str:\n        return \"Q012\"\n\n    def message(self) -> str:\n        if self.status == \"error\":\n            info = \"ERROR creating\"\n            status = red(self.status.upper())\n        elif \"PARTIAL SUCCESS\" in self.status:\n            info = \"PARTIALLY created\"\n            status = yellow(self.status.upper())\n        else:\n            info = \"OK created\"\n            status = green(self.status)\n\n        msg = f\"{info} {self.description}\"\n        return format_fancy_output_line(\n            msg=msg,\n            status=status,\n            index=self.index,\n            total=self.total,\n            execution_time=self.execution_time,\n        )\n\n\n# Skipped Q013, Q014\n\n\nclass LogSnapshotResult(DynamicLevel):\n    def code(self) -> str:\n        return \"Q015\"\n\n    def message(self) -> str:\n        if self.status == \"error\":\n            info = \"ERROR snapshotting\"\n            status = red(self.status.upper())\n        else:\n            info = \"OK snapshotted\"\n            status = green(self.result_message)\n\n        msg = \"{info} {description}\".format(info=info, description=self.description, **self.cfg)\n        return format_fancy_output_line(\n            msg=msg,\n            status=status,\n            index=self.index,\n            total=self.total,\n            execution_time=self.execution_time,\n        )\n\n\nclass LogSeedResult(DynamicLevel):\n    def code(self) -> str:\n        return \"Q016\"\n\n    def message(self) -> str:\n        if self.status == \"error\":\n            info = \"ERROR loading\"\n            status = red(self.status.upper())\n        else:\n            info = \"OK loaded\"\n            status = green(self.result_message)\n        msg = f\"{info} seed file {self.schema}.{self.relation}\"\n        return format_fancy_output_line(\n            msg=msg,\n            status=status,\n            index=self.index,\n            total=self.total,\n            execution_time=self.execution_time,\n        )\n\n\n# Skipped Q017\n\n\nclass LogFreshnessResult(DynamicLevel):\n    def code(self) -> str:\n        return \"Q018\"\n\n    def message(self) -> str:\n        if self.status == \"runtime error\":\n            info = \"ERROR\"\n            status = red(info)\n        elif self.status == \"error\":\n            info = \"ERROR STALE\"\n            status = red(info)\n        elif self.status == \"warn\":\n            info = \"WARN\"\n            status = yellow(info)\n        else:\n            info = \"PASS\"\n            status = green(info)\n        msg = f\"{info} freshness of {self.source_name}.{self.table_name}\"\n        return format_fancy_output_line(\n            msg=msg,\n            status=status,\n            index=self.index,\n            total=self.total,\n            execution_time=self.execution_time,\n        )\n\n    @classmethod\n    def status_to_level(cls, status):\n        # The statuses come from FreshnessStatus\n        # TODO should this return EventLevel enum instead?\n        level_lookup = {\n            \"runtime error\": EventLevel.ERROR,\n            \"pass\": EventLevel.INFO,\n            \"warn\": EventLevel.WARN,\n            \"error\": EventLevel.ERROR,\n        }\n        if status in level_lookup:\n            return level_lookup[status]\n        else:\n            return EventLevel.INFO\n\n\nclass LogNodeNoOpResult(InfoLevel):\n    def code(self) -> str:\n        return \"Q019\"\n\n    def message(self) -> str:\n        msg = f\"NO-OP {self.description}\"\n        return format_fancy_output_line(\n            msg=msg,\n            status=yellow(\"NO-OP\"),\n            index=self.index,\n            total=self.total,\n            execution_time=self.execution_time,\n        )\n\n\n# Skipped Q020, Q021\n\n\nclass LogCancelLine(ErrorLevel):\n    def code(self) -> str:\n        return \"Q022\"\n\n    def message(self) -> str:\n        msg = f\"CANCEL query {self.conn_name}\"\n        return format_fancy_output_line(msg=msg, status=red(\"CANCEL\"), index=None, total=None)\n\n\nclass DefaultSelector(InfoLevel):\n    def code(self) -> str:\n        return \"Q023\"\n\n    def message(self) -> str:\n        return f\"Using default selector {self.name}\"\n\n\nclass NodeStart(DebugLevel):\n    def code(self) -> str:\n        return \"Q024\"\n\n    def message(self) -> str:\n        return f\"Began running node {self.node_info.unique_id}\"\n\n\nclass NodeFinished(DebugLevel):\n    def code(self) -> str:\n        return \"Q025\"\n\n    def message(self) -> str:\n        return f\"Finished running node {self.node_info.unique_id}\"\n\n\nclass QueryCancelationUnsupported(InfoLevel):\n    def code(self) -> str:\n        return \"Q026\"\n\n    def message(self) -> str:\n        msg = (\n            f\"The {self.type} adapter does not support query \"\n            \"cancellation. Some queries may still be \"\n            \"running!\"\n        )\n        return yellow(msg)\n\n\nclass ConcurrencyLine(InfoLevel):\n    def code(self) -> str:\n        return \"Q027\"\n\n    def message(self) -> str:\n        return f\"Concurrency: {self.num_threads} threads (target='{self.target_name}')\"\n\n\nclass WritingInjectedSQLForNode(DebugLevel):\n    def code(self) -> str:\n        return \"Q029\"\n\n    def message(self) -> str:\n        return f'Writing injected SQL for node \"{self.node_info.unique_id}\"'\n\n\nclass NodeCompiling(DebugLevel):\n    def code(self) -> str:\n        return \"Q030\"\n\n    def message(self) -> str:\n        return f\"Began compiling node {self.node_info.unique_id}\"\n\n\nclass NodeExecuting(DebugLevel):\n    def code(self) -> str:\n        return \"Q031\"\n\n    def message(self) -> str:\n        return f\"Began executing node {self.node_info.unique_id}\"\n\n\nclass LogHookStartLine(InfoLevel):\n    def code(self) -> str:\n        return \"Q032\"\n\n    def message(self) -> str:\n        msg = f\"START hook: {self.statement}\"\n        return format_fancy_output_line(\n            msg=msg, status=\"RUN\", index=self.index, total=self.total, truncate=True\n        )\n\n\nclass LogHookEndLine(InfoLevel):\n    def code(self) -> str:\n        return \"Q033\"\n\n    def message(self) -> str:\n        if self.status == \"success\":\n            info = \"OK\"\n            status = green(info)\n        elif self.status == \"skipped\":\n            info = \"SKIP\"\n            status = yellow(info)\n        else:\n            info = \"ERROR\"\n            status = red(info)\n        msg = f\"{info} hook: {self.statement}\"\n\n        return format_fancy_output_line(\n            msg=msg,\n            status=status,\n            index=self.index,\n            total=self.total,\n            execution_time=self.execution_time,\n            truncate=True,\n        )\n\n\nclass SkippingDetails(InfoLevel):\n    def code(self) -> str:\n        return \"Q034\"\n\n    def message(self) -> str:\n        # ToDo: move to core or figure out NodeType\n        if self.resource_type in [\"model\", \"seed\", \"snapshot\"]:\n            msg = f\"SKIP relation {self.schema}.{self.node_name}\"\n        else:\n            msg = f\"SKIP {self.resource_type} {self.node_name}\"\n        return format_fancy_output_line(\n            msg=msg, status=yellow(\"SKIP\"), index=self.index, total=self.total\n        )\n\n\nclass NothingToDo(WarnLevel):\n    def code(self) -> str:\n        return \"Q035\"\n\n    def message(self) -> str:\n        return warning_tag(\n            \"Nothing to do. Try checking your model configs and model specification args\"\n        )\n\n\nclass RunningOperationUncaughtError(ErrorLevel):\n    def code(self) -> str:\n        return \"Q036\"\n\n    def message(self) -> str:\n        return error_tag(f\"Encountered an error while running operation: {self.exc}\")\n\n\nclass EndRunResult(DebugLevel):\n    def code(self) -> str:\n        return \"Q037\"\n\n    def message(self) -> str:\n        return \"Command end result\"\n\n\nclass NoNodesSelected(WarnLevel):\n    def code(self) -> str:\n        return \"Q038\"\n\n    def message(self) -> str:\n        return warning_tag(\"No nodes selected!\")\n\n\nclass CommandCompleted(DebugLevel):\n    def code(self) -> str:\n        return \"Q039\"\n\n    def message(self) -> str:\n        status = \"succeeded\" if self.success else \"failed\"\n        completed_at = timestamp_to_datetime_string(self.completed_at)\n        return f\"Command `{self.command}` {status} at {completed_at} after {self.elapsed:0.2f} seconds\"\n\n\nclass ShowNode(InfoLevel):\n    def code(self) -> str:\n        return \"Q041\"\n\n    def message(self) -> str:\n        if self.output_format == \"json\":\n            if self.is_inline:\n                return json.dumps({\"show\": json.loads(self.preview)}, indent=2)\n            else:\n                return json.dumps(\n                    {\"node\": self.node_name, \"show\": json.loads(self.preview)}, indent=2\n                )\n        else:\n            if self.quiet:\n                return self.preview\n            elif self.is_inline:\n                return f\"Previewing inline node:\\n{self.preview}\"\n            else:\n                return f\"Previewing node '{self.node_name}':\\n{self.preview}\"\n\n\nclass CompiledNode(InfoLevel):\n    def code(self) -> str:\n        return \"Q042\"\n\n    def message(self) -> str:\n        if self.output_format == \"json\":\n            if self.is_inline:\n                return json.dumps({\"compiled\": self.compiled}, indent=2)\n            else:\n                return json.dumps({\"node\": self.node_name, \"compiled\": self.compiled}, indent=2)\n        else:\n            if self.quiet:\n                return self.compiled\n            elif self.is_inline:\n                return f\"Compiled inline node is:\\n{self.compiled}\"\n            else:\n                return f\"Compiled node '{self.node_name}' is:\\n{self.compiled}\"\n\n\nclass SnapshotTimestampWarning(WarnLevel):\n    def code(self) -> str:\n        return \"Q043\"\n\n    def message(self) -> str:\n        msg = (\n            f\"Data type of snapshot table timestamp columns ({self.snapshot_time_data_type}) \"\n            f\"doesn't match derived column 'updated_at' ({self.updated_at_data_type}). \"\n            \"Please update snapshot config 'updated_at'.\"\n        )\n        return warning_tag(msg)\n\n\nclass MicrobatchExecutionDebug(DebugLevel):\n    def code(self) -> str:\n        return \"Q044\"\n\n    def message(self) -> str:\n        return self.msg\n\n\nclass LogStartBatch(InfoLevel):\n    def code(self) -> str:\n        return \"Q045\"\n\n    def message(self) -> str:\n        msg = f\"START {self.description}\"\n\n        # TODO update common so that we can append \"batch\" in `format_fancy_output_line`\n        formatted = format_fancy_output_line(\n            msg=msg,\n            status=\"RUN\",\n            index=self.batch_index,\n            total=self.total_batches,\n        )\n        return f\"Batch {formatted}\"\n\n\nclass LogBatchResult(DynamicLevel):\n    def code(self) -> str:\n        return \"Q046\"\n\n    def message(self) -> str:\n        if self.status == \"error\":\n            info = \"ERROR creating\"\n            status = red(self.status.upper())\n        elif self.status == \"skipped\":\n            info = \"SKIP\"\n            status = yellow(self.status.upper())\n        else:\n            info = \"OK created\"\n            status = green(self.status)\n\n        msg = f\"{info} {self.description}\"\n\n        # TODO update common so that we can append \"batch\" in `format_fancy_output_line`\n        formatted = format_fancy_output_line(\n            msg=msg,\n            status=status,\n            index=self.batch_index,\n            total=self.total_batches,\n            execution_time=self.execution_time,\n        )\n        return f\"Batch {formatted}\"\n\n\nclass LogFunctionResult(DynamicLevel):\n    def code(self) -> str:\n        return \"Q047\"\n\n    def message(self) -> str:\n        if self.status == \"error\":\n            info = \"ERROR creating\"\n            status = red(self.status.upper())\n        elif self.status == \"skipped\":\n            info = \"SKIP\"\n            status = yellow(self.status.upper())\n        else:\n            info = \"OK created\"\n            status = green(self.status.upper())\n\n        msg = f\"{info} {self.description}\"\n        return format_fancy_output_line(\n            msg=msg,\n            status=status,\n            index=self.index,\n            total=self.total,\n            execution_time=self.execution_time,\n        )\n\n\n# =======================================================\n# W - Node testing\n# =======================================================\n\n# Skipped W001\n\n\nclass CatchableExceptionOnRun(DebugLevel):\n    def code(self) -> str:\n        return \"W002\"\n\n    def message(self) -> str:\n        return str(self.exc)\n\n\nclass InternalErrorOnRun(DebugLevel):\n    def code(self) -> str:\n        return \"W003\"\n\n    def message(self) -> str:\n        prefix = f\"Internal error executing {self.build_path}\"\n\n        internal_error_string = \"\"\"This is an error in dbt. Please try again. If \\\nthe error persists, open an issue at https://github.com/dbt-labs/dbt-core\n\"\"\".strip()\n\n        return f\"{red(prefix)}\\n\" f\"{str(self.exc).strip()}\\n\\n\" f\"{internal_error_string}\"\n\n\nclass GenericExceptionOnRun(ErrorLevel):\n    def code(self) -> str:\n        return \"W004\"\n\n    def message(self) -> str:\n        node_description = self.build_path\n        if node_description is None:\n            node_description = self.unique_id\n        msg = f\"Unhandled error while executing {node_description}\\n{str(self.exc).strip()}\"\n        return error_tag(msg)\n\n\nclass NodeConnectionReleaseError(DebugLevel):\n    def code(self) -> str:\n        return \"W005\"\n\n    def message(self) -> str:\n        return f\"Error releasing connection for node {self.node_name}: {str(self.exc)}\"\n\n\nclass FoundStats(InfoLevel):\n    def code(self) -> str:\n        return \"W006\"\n\n    def message(self) -> str:\n        return f\"Found {self.stat_line}\"\n\n\n# =======================================================\n# Z - Misc\n# =======================================================\n\n\nclass MainKeyboardInterrupt(InfoLevel):\n    def code(self) -> str:\n        return \"Z001\"\n\n    def message(self) -> str:\n        return \"ctrl-c\"\n\n\nclass MainEncounteredError(ErrorLevel):\n    def code(self) -> str:\n        return \"Z002\"\n\n    def message(self) -> str:\n        return error_tag(f\"Encountered an error:\\n{self.exc}\")\n\n\nclass MainStackTrace(ErrorLevel):\n    def code(self) -> str:\n        return \"Z003\"\n\n    def message(self) -> str:\n        return self.stack_trace\n\n\n# Skipped Z004\n\n\nclass TimingInfoCollected(DebugLevel):\n    def code(self) -> str:\n        return \"Z010\"\n\n    def message(self) -> str:\n        started_at = timestamp_to_datetime_string(self.timing_info.started_at)\n        completed_at = timestamp_to_datetime_string(self.timing_info.completed_at)\n        return f\"Timing info for {self.node_info.unique_id} ({self.timing_info.name}): {started_at} => {completed_at}\"\n\n\n# This prints the stack trace at the debug level while allowing just the nice exception message\n# at the error level - or whatever other level chosen.  Used in multiple places.\n\n\nclass LogDebugStackTrace(DebugLevel):\n    def code(self) -> str:\n        return \"Z011\"\n\n    def message(self) -> str:\n        return f\"{self.exc_info}\"\n\n\n# We don't write \"clean\" events to the log, because the clean command\n# may have removed the log directory.\n\n\nclass CheckCleanPath(InfoLevel):\n    def code(self) -> str:\n        return \"Z012\"\n\n    def message(self) -> str:\n        return f\"Checking {self.path}/*\"\n\n\nclass ConfirmCleanPath(InfoLevel):\n    def code(self) -> str:\n        return \"Z013\"\n\n    def message(self) -> str:\n        return f\"Cleaned {self.path}/*\"\n\n\nclass ProtectedCleanPath(InfoLevel):\n    def code(self) -> str:\n        return \"Z014\"\n\n    def message(self) -> str:\n        return f\"ERROR: not cleaning {self.path}/* because it is protected\"\n\n\nclass FinishedCleanPaths(InfoLevel):\n    def code(self) -> str:\n        return \"Z015\"\n\n    def message(self) -> str:\n        return \"Finished cleaning all paths.\"\n\n\nclass OpenCommand(InfoLevel):\n    def code(self) -> str:\n        return \"Z016\"\n\n    def message(self) -> str:\n        msg = f\"\"\"To view your profiles.yml file, run:\n\n{self.open_cmd} {self.profiles_dir}\"\"\"\n\n        return msg\n\n\nclass RunResultWarning(WarnLevel):\n    def code(self) -> str:\n        return \"Z021\"\n\n    def message(self) -> str:\n        return warning_tag(f\"in {self.resource_type} {self.node_name} ({self.path})\")\n\n\nclass RunResultFailure(ErrorLevel):\n    def code(self) -> str:\n        return \"Z022\"\n\n    def message(self) -> str:\n        return error_tag(f\"in {self.resource_type} {self.node_name} ({self.path})\")\n\n\nclass StatsLine(InfoLevel):\n    def code(self) -> str:\n        return \"Z023\"\n\n    def message(self) -> str:\n        stats_line = (\n            \"Done. PASS={pass} WARN={warn} ERROR={error} SKIP={skip} NO-OP={noop} TOTAL={total}\"\n        )\n        return stats_line.format(**self.stats)\n\n\nclass RunResultError(ErrorLevel):\n    def code(self) -> str:\n        return \"Z024\"\n\n    def message(self) -> str:\n        # This is the message on the result object, cannot be built here\n        return f\"  {self.msg}\"\n\n\nclass RunResultErrorNoMessage(ErrorLevel):\n    def code(self) -> str:\n        return \"Z025\"\n\n    def message(self) -> str:\n        return f\"  Status: {self.status}\"\n\n\nclass SQLCompiledPath(InfoLevel):\n    def code(self) -> str:\n        return \"Z026\"\n\n    def message(self) -> str:\n        return f\"  compiled code at {self.path}\"\n\n\nclass CheckNodeTestFailure(InfoLevel):\n    def code(self) -> str:\n        return \"Z027\"\n\n    def message(self) -> str:\n        msg = f\"select * from {self.relation_name}\"\n        border = \"-\" * len(msg)\n        return f\"  See test failures:\\n  {border}\\n  {msg}\\n  {border}\"\n\n\n# Skipped Z028, Z029\n\n\nclass EndOfRunSummary(InfoLevel):\n    def code(self) -> str:\n        return \"Z030\"\n\n    def message(self) -> str:\n        error_plural = pluralize(self.num_errors, \"error\")\n        warn_plural = pluralize(self.num_warnings, \"warning\")\n        partial_success_plural = f\"\"\"{self.num_partial_success} partial {\"success\" if self.num_partial_success == 1 else \"successes\"}\"\"\"\n\n        if self.keyboard_interrupt:\n            message = yellow(\"Exited because of keyboard interrupt\")\n        elif self.num_errors > 0:\n            message = red(\n                f\"Completed with {error_plural}, {partial_success_plural}, and {warn_plural}:\"\n            )\n        elif self.num_partial_success > 0:\n            message = yellow(f\"Completed with {partial_success_plural} and {warn_plural}\")\n        elif self.num_warnings > 0:\n            message = yellow(f\"Completed with {warn_plural}:\")\n        else:\n            message = green(\"Completed successfully\")\n        return message\n\n\n# Skipped Z031, Z032\n\n\nclass MarkSkippedChildren(DebugLevel):\n    def code(self) -> str:\n        return \"Z033\"\n\n    def message(self) -> str:\n        msg = (\n            f\"Marking all children of '{self.unique_id}' to be skipped \"\n            f\"because of status '{self.status}'. \"\n        )\n        if self.run_result.message:\n            msg = msg + f\" Reason: {self.run_result.message}.\"\n        return msg\n\n\nclass LogSkipBecauseError(ErrorLevel):\n    def code(self) -> str:\n        return \"Z034\"\n\n    def message(self) -> str:\n        msg = f\"SKIP relation {self.schema}.{self.relation} due to ephemeral model status '{self.status}'\"\n        return format_fancy_output_line(\n            msg=msg, status=red(\"ERROR SKIP\"), index=self.index, total=self.total\n        )\n\n\n# Skipped Z035\n\n\nclass EnsureGitInstalled(ErrorLevel):\n    def code(self) -> str:\n        return \"Z036\"\n\n    def message(self) -> str:\n        return error_tag(\n            \"Make sure git is installed on your machine. More \"\n            \"information: \"\n            \"https://docs.getdbt.com/docs/package-management\"\n        )\n\n\nclass DepsCreatingLocalSymlink(DebugLevel):\n    def code(self) -> str:\n        return \"Z037\"\n\n    def message(self) -> str:\n        return \"Creating symlink to local dependency.\"\n\n\nclass DepsSymlinkNotAvailable(DebugLevel):\n    def code(self) -> str:\n        return \"Z038\"\n\n    def message(self) -> str:\n        return \"Symlinks are not available on this OS, copying dependency.\"\n\n\nclass DisableTracking(DebugLevel):\n    def code(self) -> str:\n        return \"Z039\"\n\n    def message(self) -> str:\n        return (\n            \"Error sending anonymous usage statistics. Disabling tracking for this execution. \"\n            \"If you wish to permanently disable tracking, see: \"\n            \"https://docs.getdbt.com/reference/global-configs#send-anonymous-usage-stats.\"\n        )\n\n\nclass SendingEvent(DebugLevel):\n    def code(self) -> str:\n        return \"Z040\"\n\n    def message(self) -> str:\n        return f\"Sending event: {self.kwargs}\"\n\n\nclass SendEventFailure(DebugLevel):\n    def code(self) -> str:\n        return \"Z041\"\n\n    def message(self) -> str:\n        return \"An error was encountered while trying to send an event\"\n\n\nclass FlushEvents(DebugLevel):\n    def code(self) -> str:\n        return \"Z042\"\n\n    def message(self) -> str:\n        return \"Flushing usage events\"\n\n\nclass FlushEventsFailure(DebugLevel):\n    def code(self) -> str:\n        return \"Z043\"\n\n    def message(self) -> str:\n        return \"An error was encountered while trying to flush usage events\"\n\n\nclass TrackingInitializeFailure(DebugLevel):\n    def code(self) -> str:\n        return \"Z044\"\n\n    def message(self) -> str:\n        return \"Got an exception trying to initialize tracking\"\n\n\n# this is the message from the result object\n\n\nclass RunResultWarningMessage(WarnLevel):\n    def code(self) -> str:\n        return \"Z046\"\n\n    def message(self) -> str:\n        # This is the message on the result object, cannot be formatted in event\n        return warning_tag(self.msg)\n\n\nclass DebugCmdOut(InfoLevel):\n    def code(self) -> str:\n        return \"Z047\"\n\n    def message(self) -> str:\n        return self.msg\n\n\nclass DebugCmdResult(InfoLevel):\n    def code(self) -> str:\n        return \"Z048\"\n\n    def message(self) -> str:\n        return self.msg\n\n\nclass ListCmdOut(InfoLevel):\n    # No longer in use, switching to Z051 PrintEvent in dbt-common\n    def code(self) -> str:\n        return \"Z049\"\n\n    def message(self) -> str:\n        return self.msg\n\n\nclass ResourceReport(DebugLevel):\n    def code(self) -> str:\n        return \"Z051\"\n\n    def message(self) -> str:\n        return f\"Resource report: {self.to_json()}\"\n\n\n# Artifact Upload Events #\n\n\nclass ArtifactUploadError(ErrorLevel):\n    def code(self) -> str:\n        return \"Z061\"\n\n    def message(self) -> str:\n        return error_tag(f\"Error uploading artifacts to artifact ingestion API: {self.msg}\")\n\n\nclass ArtifactUploadSuccess(InfoLevel):\n    def code(self) -> str:\n        return \"Z062\"\n\n    def message(self) -> str:\n        return f\"Artifacts uploaded successfully to artifact ingestion API: {self.msg}\"\n\n\nclass ArtifactUploadSkipped(DebugLevel):\n    def code(self) -> str:\n        return \"Z063\"\n\n    def message(self) -> str:\n        return f\"Artifacts skipped for command : {self.msg}\"\n\n\nclass SelectExcludeIgnoredWithSelectorWarning(WarnLevel):\n    def code(self) -> str:\n        return \"Z064\"\n\n    def message(self) -> str:\n        return \"The --select and --exclude arguments are being ignored for node selection because --selector is provided\"\n"
  },
  {
    "path": "core/dbt/exceptions.py",
    "content": "import io\nimport json\nimport re\nfrom typing import TYPE_CHECKING, Any, Dict, List, Mapping, Optional, Tuple, Union\n\nfrom dbt.node_types import REFABLE_NODE_TYPES, AccessType, NodeType\nfrom dbt_common.constants import SECRET_ENV_PREFIX\nfrom dbt_common.dataclass_schema import ValidationError\nfrom dbt_common.exceptions import (\n    CommandResultError,\n    CompilationError,\n    DbtConfigError,\n    DbtInternalError,\n    DbtRuntimeError,\n    DbtValidationError,\n    env_secrets,\n    scrub_secrets,\n)\n\nif TYPE_CHECKING:\n    import agate\n\n\nclass ContractBreakingChangeError(DbtRuntimeError):\n    CODE = 10016\n    MESSAGE = \"Breaking Change to Contract\"\n\n    def __init__(\n        self,\n        breaking_changes: List[str],\n        node=None,\n    ) -> None:\n        self.breaking_changes = breaking_changes\n        super().__init__(self.message(), node)\n\n    @property\n    def type(self):\n        return \"Breaking change to contract\"\n\n    def message(self):\n        reasons = \"\\n  - \".join(self.breaking_changes)\n\n        return (\n            \"While comparing to previous project state, dbt detected a breaking change to an enforced contract.\"\n            f\"\\n  - {reasons}\\n\"\n            \"Consider making an additive (non-breaking) change instead, if possible.\\n\"\n            \"Otherwise, create a new model version: https://docs.getdbt.com/docs/collaborate/govern/model-versions\"\n        )\n\n\nclass ParsingError(DbtRuntimeError):\n    CODE = 10015\n    MESSAGE = \"Parsing Error\"\n\n    @property\n    def type(self):\n        return \"Parsing\"\n\n\nclass dbtPluginError(DbtRuntimeError):\n    CODE = 10020\n    MESSAGE = \"Plugin Error\"\n\n\n# TODO: this isn't raised in the core codebase.  Is it raised elsewhere?\nclass JSONValidationError(DbtValidationError):\n    def __init__(self, typename, errors) -> None:\n        self.typename = typename\n        self.errors = errors\n        self.errors_message = \", \".join(errors)\n        msg = f'Invalid arguments passed to \"{self.typename}\" instance: {self.errors_message}'\n        super().__init__(msg)\n\n    def __reduce__(self):\n        # see https://stackoverflow.com/a/36342588 for why this is necessary\n        return (JSONValidationError, (self.typename, self.errors))\n\n\nclass AliasError(DbtValidationError):\n    pass\n\n\nclass DependencyError(DbtRuntimeError):\n    CODE = 10006\n    MESSAGE = \"Dependency Error\"\n\n\nclass FailFastError(DbtRuntimeError):\n    CODE = 10013\n    MESSAGE = \"FailFast Error\"\n\n    def __init__(self, msg: str, result=None, node=None) -> None:\n        super().__init__(msg=msg, node=node)\n        self.result = result\n\n    @property\n    def type(self):\n        return \"FailFast\"\n\n\nclass DbtProjectError(DbtConfigError):\n    pass\n\n\nclass DbtSelectorsError(DbtConfigError):\n    pass\n\n\nclass DbtProfileError(DbtConfigError):\n    pass\n\n\nclass DbtExclusivePropertyUseError(DbtConfigError):\n    pass\n\n\nclass InvalidSelectorError(DbtRuntimeError):\n    def __init__(self, name: str) -> None:\n        self.name = name\n        super().__init__(name)\n\n\nclass DuplicateYamlKeyError(CompilationError):\n    pass\n\n\n# compilation level exceptions\nclass GraphDependencyNotFoundError(CompilationError):\n    def __init__(self, node, dependency: str) -> None:\n        self.node = node\n        self.dependency = dependency\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        msg = f\"'{self.node.unique_id}' depends on '{self.dependency}' which is not in the graph!\"\n        return msg\n\n\nclass ForeignKeyConstraintToSyntaxError(CompilationError):\n    def __init__(self, node, expression: str) -> None:\n        self.expression = expression\n        self.node = node\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        msg = f\"'{self.node.unique_id}' defines a foreign key constraint 'to' expression which is not valid 'ref' or 'source' syntax: {self.expression}.\"\n\n        return msg\n\n\n# client level exceptions\n\n\nclass NoSupportedLanguagesFoundError(CompilationError):\n    def __init__(self, node) -> None:\n        self.node = node\n        self.msg = f\"No supported_languages found in materialization macro {self.node.name}\"\n        super().__init__(msg=self.msg)\n\n\nclass MaterializtionMacroNotUsedError(CompilationError):\n    def __init__(self, node) -> None:\n        self.node = node\n        self.msg = \"Only materialization macros can be used with this function\"\n        super().__init__(msg=self.msg)\n\n\nclass MacroNamespaceNotStringError(CompilationError):\n    def __init__(self, kwarg_type: Any) -> None:\n        self.kwarg_type = kwarg_type\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        msg = (\n            \"The macro_namespace parameter to adapter.dispatch \"\n            f\"is a {self.kwarg_type}, not a string\"\n        )\n        return msg\n\n\nclass UnknownGitCloningProblemError(DbtRuntimeError):\n    def __init__(self, repo: str) -> None:\n        self.repo = scrub_secrets(repo, env_secrets())\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        msg = f\"\"\"\\\n        Something went wrong while cloning {self.repo}\n        Check the debug logs for more information\n        \"\"\"\n        return msg\n\n\nclass NoAdaptersAvailableError(DbtRuntimeError):\n    def __init__(self) -> None:\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        msg = \"No adapters available. Learn how to install an adapter by going to https://docs.getdbt.com/docs/connect-adapters#install-using-the-cli\"\n        return msg\n\n\nclass BadSpecError(DbtInternalError):\n    def __init__(self, repo, revision, error) -> None:\n        self.repo = repo\n        self.revision = revision\n        self.stderr = scrub_secrets(error.stderr.strip(), env_secrets())\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        msg = f\"Error checking out spec='{self.revision}' for repo {self.repo}\\n{self.stderr}\"\n        return msg\n\n\nclass GitCloningError(DbtInternalError):\n    def __init__(self, repo: str, revision: str, error: CommandResultError) -> None:\n        self.repo = repo\n        self.revision = revision\n        self.error = error\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        stderr = self.error.stderr.strip()\n        if \"usage: git\" in stderr:\n            stderr = stderr.split(\"\\nusage: git\")[0]\n        if re.match(\"fatal: destination path '(.+)' already exists\", stderr):\n            self.error.cmd = list(scrub_secrets(str(self.error.cmd), env_secrets()))\n            raise self.error\n\n        msg = f\"Error checking out spec='{self.revision}' for repo {self.repo}\\n{stderr}\"\n        return scrub_secrets(msg, env_secrets())\n\n\nclass GitCheckoutError(BadSpecError):\n    pass\n\n\nclass OperationError(CompilationError):\n    def __init__(self, operation_name) -> None:\n        self.operation_name = operation_name\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        msg = (\n            f\"dbt encountered an error when attempting to create a {self.operation_name}. \"\n            \"If this error persists, please create an issue at: \\n\\n\"\n            \"https://github.com/dbt-labs/dbt-core\"\n        )\n\n        return msg\n\n\n# context level exceptions\nclass ZipStrictWrongTypeError(CompilationError):\n    def __init__(self, exc) -> None:\n        self.exc = exc\n        msg = str(self.exc)\n        super().__init__(msg=msg)\n\n\nclass SetStrictWrongTypeError(CompilationError):\n    def __init__(self, exc) -> None:\n        self.exc = exc\n        msg = str(self.exc)\n        super().__init__(msg=msg)\n\n\nclass LoadAgateTableValueError(CompilationError):\n    def __init__(self, exc: ValueError, node) -> None:\n        self.exc = exc\n        self.node = node\n        msg = str(self.exc)\n        super().__init__(msg=msg)\n\n\nclass LoadAgateTableNotSeedError(CompilationError):\n    def __init__(self, resource_type, node) -> None:\n        self.resource_type = resource_type\n        self.node = node\n        msg = f\"can only load_agate_table for seeds (got a {self.resource_type})\"\n        super().__init__(msg=msg)\n\n\nclass PackageNotInDepsError(CompilationError):\n    def __init__(self, package_name: str, node) -> None:\n        self.package_name = package_name\n        self.node = node\n        msg = f\"Node package named {self.package_name} not found!\"\n        super().__init__(msg=msg)\n\n\nclass OperationsCannotRefEphemeralNodesError(CompilationError):\n    def __init__(self, target_name: str, node) -> None:\n        self.target_name = target_name\n        self.node = node\n        msg = f\"Operations can not ref() ephemeral nodes, but {target_name} is ephemeral\"\n        super().__init__(msg=msg)\n\n\nclass PersistDocsValueTypeError(CompilationError):\n    def __init__(self, persist_docs: Any) -> None:\n        self.persist_docs = persist_docs\n        msg = (\n            \"Invalid value provided for 'persist_docs'. Expected dict \"\n            f\"but received {type(self.persist_docs)}\"\n        )\n        super().__init__(msg=msg)\n\n\nclass InlineModelConfigError(CompilationError):\n    def __init__(self, node) -> None:\n        self.node = node\n        msg = \"Invalid inline model config\"\n        super().__init__(msg=msg)\n\n\nclass ConflictingConfigKeysError(CompilationError):\n    def __init__(self, oldkey: str, newkey: str, node) -> None:\n        self.oldkey = oldkey\n        self.newkey = newkey\n        self.node = node\n        msg = f'Invalid config, has conflicting keys \"{self.oldkey}\" and \"{self.newkey}\"'\n        super().__init__(msg=msg)\n\n\nclass NumberSourceArgsError(CompilationError):\n    def __init__(self, args, node) -> None:\n        self.args = args\n        self.node = node\n        msg = f\"source() takes exactly two arguments ({len(self.args)} given)\"\n        super().__init__(msg=msg)\n\n\nclass RequiredVarNotFoundError(CompilationError):\n    def __init__(self, var_name: str, merged: Dict, node) -> None:\n        self.var_name = var_name\n        self.merged = merged\n        self.node = node\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        if self.node is not None:\n            node_name = self.node.name\n        else:\n            node_name = \"<Configuration>\"\n\n        dct = {k: self.merged[k] for k in self.merged}\n        pretty_vars = json.dumps(dct, sort_keys=True, indent=4)\n\n        msg = f\"Required var '{self.var_name}' not found in config:\\nVars supplied to {node_name} = {pretty_vars}\"\n        return scrub_secrets(msg, self.var_secrets())\n\n    def var_secrets(self) -> List[str]:\n        return [v for k, v in self.merged.items() if k.startswith(SECRET_ENV_PREFIX) and v.strip()]\n\n\nclass PackageNotFoundForMacroError(CompilationError):\n    def __init__(self, package_name: str) -> None:\n        self.package_name = package_name\n        msg = f\"Could not find package '{self.package_name}'\"\n        super().__init__(msg=msg)\n\n\nclass SecretEnvVarLocationError(ParsingError):\n    def __init__(self, env_var_name: str) -> None:\n        self.env_var_name = env_var_name\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        msg = (\n            \"Secret env vars are allowed only in profiles.yml or packages.yml. \"\n            f\"Found '{self.env_var_name}' referenced elsewhere.\"\n        )\n        return msg\n\n\nclass BooleanError(CompilationError):\n    def __init__(self, return_value: Any, macro_name: str) -> None:\n        self.return_value = return_value\n        self.macro_name = macro_name\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        msg = (\n            f\"Macro '{self.macro_name}' returns '{self.return_value}'.  It is not type 'bool' \"\n            \"and cannot not be converted reliably to a bool.\"\n        )\n        return msg\n\n\nclass RefArgsError(CompilationError):\n    def __init__(self, node, args) -> None:\n        self.node = node\n        self.args = args\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        msg = f\"ref() takes at most two arguments ({len(self.args)} given)\"\n        return msg\n\n\nclass MetricArgsError(CompilationError):\n    def __init__(self, node, args) -> None:\n        self.node = node\n        self.args = args\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        msg = f\"metric() takes at most two arguments ({len(self.args)} given)\"\n        return msg\n\n\nclass RefBadContextError(CompilationError):\n    def __init__(self, node, args) -> None:\n        self.node = node\n        self.args = args.positional_args  # type: ignore\n        self.kwargs = args.keyword_args  # type: ignore\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        # This explicitly references model['name'], instead of model['alias'], for\n        # better error messages. Ex. If models foo_users and bar_users are aliased\n        # to 'users', in their respective schemas, then you would want to see\n        # 'bar_users' in your error messge instead of just 'users'.\n        if isinstance(self.node, dict):\n            model_name = self.node[\"name\"]\n        else:\n            model_name = self.node.name\n\n        ref_args = \", \".join(\"'{}'\".format(a) for a in self.args)\n\n        keyword_args = \"\"\n        if self.kwargs:\n            keyword_args = \", \".join(\n                \"{}='{}'\".format(k, v) for k, v in self.kwargs.items()  # type: ignore\n            )\n            keyword_args = \",\" + keyword_args\n\n        ref_string = f\"{{{{ ref({ref_args}{keyword_args}) }}}}\"\n\n        msg = f\"\"\"dbt was unable to infer all dependencies for the model \"{model_name}\".\nThis typically happens when ref() is placed within a conditional block.\n\nTo fix this, add the following hint to the top of the model \"{model_name}\":\n\n-- depends_on: {ref_string}\"\"\"\n\n        return msg\n\n\nclass DocArgsError(CompilationError):\n    def __init__(self, node, args) -> None:\n        self.node = node\n        self.args = args\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        msg = f\"doc() takes at most two arguments ({len(self.args)} given)\"\n        return msg\n\n\nclass DocTargetNotFoundError(CompilationError):\n    def __init__(\n        self, node, target_doc_name: str, target_doc_package: Optional[str] = None\n    ) -> None:\n        self.node = node\n        self.target_doc_name = target_doc_name\n        self.target_doc_package = target_doc_package\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        target_package_string = \"\"\n        if self.target_doc_package is not None:\n            target_package_string = f\"in package '{self.target_doc_package}' \"\n        msg = f\"Documentation for '{self.node.unique_id}' depends on doc '{self.target_doc_name}' {target_package_string} which was not found\"\n        return msg\n\n\nclass MacroDispatchArgError(CompilationError):\n    def __init__(self, macro_name: str) -> None:\n        self.macro_name = macro_name\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        msg = f\"\"\"\\\n        The \"packages\" argument of adapter.dispatch() has been deprecated.\n        Use the \"macro_namespace\" argument instead.\n\n        Raised during dispatch for: {self.macro_name}\n\n        For more information, see:\n\n        https://docs.getdbt.com/reference/dbt-jinja-functions/dispatch\n        \"\"\"\n        return msg\n\n\nclass DuplicateMacroNameError(CompilationError):\n    def __init__(self, node_1, node_2, namespace: str) -> None:\n        self.node_1 = node_1\n        self.node_2 = node_2\n        self.namespace = namespace\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        duped_name = self.node_1.name\n        if self.node_1.package_name != self.node_2.package_name:\n            extra = f' (\"{self.node_1.package_name}\" and \"{self.node_2.package_name}\" are both in the \"{self.namespace}\" namespace)'\n        else:\n            extra = \"\"\n\n        msg = (\n            f'dbt found two macros with the name \"{duped_name}\" in the namespace \"{self.namespace}\"{extra}. '\n            \"Since these macros have the same name and exist in the same \"\n            \"namespace, dbt will be unable to decide which to call. To fix this, \"\n            f\"change the name of one of these macros:\\n- {self.node_1.unique_id} \"\n            f\"({self.node_1.original_file_path})\\n- {self.node_2.unique_id} ({self.node_2.original_file_path})\"\n        )\n\n        return msg\n\n\nclass MacroResultAlreadyLoadedError(CompilationError):\n    def __init__(self, result_name) -> None:\n        self.result_name = result_name\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        msg = f\"The 'statement' result named '{self.result_name}' has already been loaded into a variable\"\n\n        return msg\n\n\n# parser level exceptions\nclass DictParseError(ParsingError):\n    def __init__(self, exc: ValidationError, node) -> None:\n        self.exc = exc\n        self.node = node\n        msg = self.validator_error_message(exc)\n        super().__init__(msg=msg)\n\n\nclass ConfigUpdateError(ParsingError):\n    def __init__(self, exc: ValidationError, node) -> None:\n        self.exc = exc\n        self.node = node\n        msg = self.validator_error_message(exc)\n        super().__init__(msg=msg)\n\n\nclass PythonParsingError(ParsingError):\n    def __init__(self, exc: SyntaxError, node) -> None:\n        self.exc = exc\n        self.node = node\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        validated_exc = self.validator_error_message(self.exc)\n        msg = f\"{validated_exc}\\n{self.exc.text}\"\n        return msg\n\n\nclass PythonLiteralEvalError(ParsingError):\n    def __init__(self, exc: Exception, node) -> None:\n        self.exc = exc\n        self.node = node\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        msg = (\n            f\"Error when trying to literal_eval an arg to dbt.ref(), dbt.source(), dbt.config() or dbt.config.get() \\n{self.exc}\\n\"\n            \"https://docs.python.org/3/library/ast.html#ast.literal_eval\\n\"\n            \"In dbt python model, `dbt.ref`, `dbt.source`, `dbt.config`, `dbt.config.get` function args only support Python literal structures\"\n        )\n\n        return msg\n\n\nclass ModelConfigError(ParsingError):\n    def __init__(self, exc: ValidationError, node) -> None:\n        self.msg = self.validator_error_message(exc)\n        self.node = node\n        super().__init__(msg=self.msg)\n\n\nclass YamlParseListError(ParsingError):\n    def __init__(\n        self,\n        path: str,\n        key: str,\n        yaml_data: List,\n        cause,\n    ) -> None:\n        self.path = path\n        self.key = key\n        self.yaml_data = yaml_data\n        self.cause = cause\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        if isinstance(self.cause, str):\n            reason = self.cause\n        elif isinstance(self.cause, ValidationError):\n            reason = self.validator_error_message(self.cause)\n        else:\n            reason = self.cause.msg\n        msg = f\"Invalid {self.key} config given in {self.path} @ {self.key}: {self.yaml_data} - {reason}\"\n        return msg\n\n\nclass YamlParseDictError(ParsingError):\n    def __init__(\n        self,\n        path: str,\n        key: str,\n        yaml_data: Dict[str, Any],\n        cause,\n    ) -> None:\n        self.path = path\n        self.key = key\n        self.yaml_data = yaml_data\n        self.cause = cause\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        if isinstance(self.cause, str):\n            reason = self.cause\n        elif isinstance(self.cause, ValidationError):\n            reason = self.validator_error_message(self.cause)\n        else:\n            reason = self.cause.msg\n        msg = f\"Invalid {self.key} config given in {self.path} @ {self.key}: {self.yaml_data} - {reason}\"\n        return msg\n\n\nclass YamlLoadError(ParsingError):\n    def __init__(\n        self,\n        path: str,\n        exc: DbtValidationError,\n        project_name: Optional[str] = None,\n    ) -> None:\n        self.project_name = project_name\n        self.path = path\n        self.exc = exc\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        reason = self.validator_error_message(self.exc)\n\n        msg = f\"Error reading {self.project_name}: {self.path} - {reason}\"\n\n        return msg\n\n\nclass TestConfigError(ParsingError):\n    def __init__(self, exc: ValidationError, node) -> None:\n        self.msg = self.validator_error_message(exc)\n        self.node = node\n        super().__init__(msg=self.msg)\n\n\nclass SchemaConfigError(ParsingError):\n    def __init__(self, exc: ValidationError, node) -> None:\n        self.msg = self.validator_error_message(exc)\n        self.node = node\n        super().__init__(msg=self.msg)\n\n\nclass SnapshopConfigError(ParsingError):\n    def __init__(self, exc: ValidationError, node) -> None:\n        self.msg = self.validator_error_message(exc)\n        self.node = node\n        super().__init__(msg=self.msg)\n\n\nclass DbtReferenceError(ParsingError):\n    def __init__(self, unique_id: str, ref_unique_id: str, access: AccessType, scope: str) -> None:\n        self.unique_id = unique_id\n        self.ref_unique_id = ref_unique_id\n        self.access = access\n        self.scope = scope\n        self.scope_type = \"group\" if self.access == AccessType.Private else \"package\"\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        return (\n            f\"Node {self.unique_id} attempted to reference node {self.ref_unique_id}, \"\n            f\"which is not allowed because the referenced node is {self.access} to the '{self.scope}' {self.scope_type}.\"\n        )\n\n\nclass InvalidAccessTypeError(ParsingError):\n    def __init__(\n        self, unique_id: str, field_value: str, materialization: Optional[str] = None\n    ) -> None:\n        self.unique_id = unique_id\n        self.field_value = field_value\n        self.materialization = materialization\n\n        with_materialization = (\n            f\"with '{self.materialization}' materialization \" if self.materialization else \"\"\n        )\n        msg = f\"Node {self.unique_id} {with_materialization}has an invalid value ({self.field_value}) for the access field\"\n        super().__init__(msg=msg)\n\n\nclass InvalidUnitTestGivenInput(ParsingError):\n    def __init__(self, input: str) -> None:\n        msg = f\"Unit test given inputs must be either a 'ref', 'source' or 'this' call. Got: '{input}'.\"\n        super().__init__(msg=msg)\n\n\nclass SameKeyNestedError(CompilationError):\n    def __init__(self) -> None:\n        msg = \"Test cannot have the same key at the top-level and in config\"\n        super().__init__(msg=msg)\n\n\nclass TestArgIncludesModelError(CompilationError):\n    def __init__(self) -> None:\n        msg = 'Test arguments include \"model\", which is a reserved argument'\n        super().__init__(msg=msg)\n\n\nclass UnexpectedTestNamePatternError(CompilationError):\n    def __init__(self, test_name: str) -> None:\n        self.test_name = test_name\n        msg = f\"Test name string did not match expected pattern: {self.test_name}\"\n        super().__init__(msg=msg)\n\n\nclass CustomMacroPopulatingConfigValueError(CompilationError):\n    def __init__(\n        self,\n        target_name: str,\n        name: str,\n        key: str,\n        err_msg: str,\n        column_name: Optional[str] = None,\n    ) -> None:\n        self.target_name = target_name\n        self.column_name = column_name\n        self.name = name\n        self.key = key\n        self.err_msg = err_msg\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        # Generic tests do not include custom macros in the Jinja\n        # rendering context, so this will almost always fail. As it\n        # currently stands, the error message is inscrutable, which\n        # has caused issues for some projects migrating from\n        # pre-0.20.0 to post-0.20.0.\n        # See https://github.com/dbt-labs/dbt-core/issues/4103\n        # and https://github.com/dbt-labs/dbt-core/issues/5294\n\n        msg = (\n            f\"The {self.target_name}.{self.column_name} column's \"\n            f'\"{self.name}\" test references an undefined '\n            f\"macro in its {self.key} configuration argument. \"\n            f\"The macro {self.err_msg}.\\n\"\n            \"Please note that the generic test configuration parser \"\n            \"currently does not support using custom macros to \"\n            \"populate configuration values\"\n        )\n        return msg\n\n\nclass TagsNotListOfStringsError(CompilationError):\n    def __init__(self, tags: Any) -> None:\n        self.tags = tags\n        msg = f\"got {self.tags} ({type(self.tags)}) for tags, expected a list of strings\"\n        super().__init__(msg=msg)\n\n\nclass TagNotStringError(CompilationError):\n    def __init__(self, tag: Any) -> None:\n        self.tag = tag\n        msg = f\"got {self.tag} ({type(self.tag)}) for tag, expected a str\"\n        super().__init__(msg=msg)\n\n\nclass TestNameNotStringError(ParsingError):\n    def __init__(self, test_name: Any) -> None:\n        self.test_name = test_name\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        msg = f\"test name must be a str, got {type(self.test_name)} (value {self.test_name})\"\n        return msg\n\n\nclass TestArgsNotDictError(ParsingError):\n    def __init__(self, test_args: Any) -> None:\n        self.test_args = test_args\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        msg = f\"test arguments must be a dict, got {type(self.test_args)} (value {self.test_args})\"\n        return msg\n\n\nclass TestConfigNotDictError(ParsingError):\n    def __init__(self, config: Any) -> None:\n        self.config = config\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        msg = f\"'config' must be a dict, got {type(self.config)} (value {self.config})\"\n        return msg\n\n\nclass TestDefinitionDictLengthError(ParsingError):\n    def __init__(self, test):\n        self.test = test\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        msg = (\n            \"test definition dictionary must have exactly one key, got\"\n            f\" {self.test} instead ({len(self.test)} keys)\"\n        )\n        return msg\n\n\nclass TestTypeError(ParsingError):\n    def __init__(self, test: Any):\n        self.test = test\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        msg = f\"test must be dict or str, got {type(self.test)} (value {self.test})\"\n        return msg\n\n\n# This is triggered across multiple files\nclass EnvVarMissingError(ParsingError):\n    def __init__(self, var: str):\n        self.var = var\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        msg = f\"Env var required but not provided: '{self.var}'\"\n        return msg\n\n\nclass TargetNotFoundError(CompilationError):\n    def __init__(\n        self,\n        node,\n        target_name: str,\n        target_kind: str,\n        target_package: Optional[str] = None,\n        target_version: Optional[Union[str, float]] = None,\n        disabled: Optional[bool] = None,\n    ):\n        self.node = node\n        self.target_name = target_name\n        self.target_kind = target_kind\n        self.target_package = target_package\n        self.target_version = target_version\n        self.disabled = disabled\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        original_file_path = self.node.original_file_path\n        unique_id = self.node.unique_id\n        resource_type_title = self.node.resource_type.title()\n\n        if self.disabled is None:\n            reason = \"was not found or is disabled\"\n        elif self.disabled is True:\n            reason = \"is disabled\"\n        else:\n            reason = \"was not found\"\n\n        target_version_string = \"\"\n        if self.target_version is not None:\n            target_version_string = f\"with version '{self.target_version}' \"\n\n        target_package_string = \"\"\n        if self.target_package is not None:\n            target_package_string = f\"in package or project '{self.target_package}' \"\n\n        msg = (\n            f\"{resource_type_title} '{unique_id}' ({original_file_path}) depends on a \"\n            f\"{self.target_kind} named '{self.target_name}' {target_version_string}{target_package_string}which {reason}\"\n        )\n        return msg\n\n\nclass DuplicateSourcePatchNameError(CompilationError):\n    def __init__(self, patch_1, patch_2):\n        self.patch_1 = patch_1\n        self.patch_2 = patch_2\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        name = f\"{self.patch_1.overrides}.{self.patch_1.name}\"\n        fix = self._fix_dupe_msg(\n            self.patch_1.path,\n            self.patch_2.path,\n            name,\n            \"sources\",\n        )\n        msg = (\n            f\"dbt found two schema.yml entries for the same source named \"\n            f\"{self.patch_1.name} in package {self.patch_1.overrides}. Sources may only be \"\n            f\"overridden a single time. To fix this, {fix}\"\n        )\n        return msg\n\n\nclass DuplicateMacroPatchNameError(CompilationError):\n    def __init__(self, patch_1, existing_patch_path):\n        self.patch_1 = patch_1\n        self.existing_patch_path = existing_patch_path\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        package_name = self.patch_1.package_name\n        name = self.patch_1.name\n        fix = self._fix_dupe_msg(\n            self.patch_1.original_file_path, self.existing_patch_path, name, \"macros\"\n        )\n        msg = (\n            f\"dbt found two schema.yml entries for the same macro in package \"\n            f\"{package_name} named {name}. Macros may only be described a single \"\n            f\"time. To fix this, {fix}\"\n        )\n        return msg\n\n\n# core level exceptions\nclass DuplicateAliasError(AliasError):\n    def __init__(self, kwargs: Mapping[str, Any], aliases: Mapping[str, str], canonical_key: str):\n        self.kwargs = kwargs\n        self.aliases = aliases\n        self.canonical_key = canonical_key\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        # dupe found: go through the dict so we can have a nice-ish error\n        key_names = \", \".join(\n            \"{}\".format(k) for k in self.kwargs if self.aliases.get(k) == self.canonical_key\n        )\n        msg = f'Got duplicate keys: ({key_names}) all map to \"{self.canonical_key}\"'\n        return msg\n\n\n# deps exceptions\nclass MultipleVersionGitDepsError(DependencyError):\n    def __init__(self, git: str, requested):\n        self.git = git\n        self.requested = requested\n        msg = (\n            \"git dependencies should contain exactly one version. \"\n            f\"{self.git} contains: {self.requested}\"\n        )\n        super().__init__(msg)\n\n\nclass DuplicateProjectDependencyError(DependencyError):\n    def __init__(self, project_name: str):\n        self.project_name = project_name\n        msg = (\n            f'Found duplicate project \"{self.project_name}\". This occurs when '\n            \"a dependency has the same project name as some other dependency.\"\n        )\n        super().__init__(msg)\n\n\nclass DuplicateDependencyToRootError(DependencyError):\n    def __init__(self, project_name: str):\n        self.project_name = project_name\n        msg = (\n            \"Found a dependency with the same name as the root project \"\n            f'\"{self.project_name}\". Package names must be unique in a project.'\n            \" Please rename one of these packages.\"\n        )\n        super().__init__(msg)\n\n\nclass MismatchedDependencyTypeError(DependencyError):\n    def __init__(self, new, old):\n        self.new = new\n        self.old = old\n        msg = (\n            f\"Cannot incorporate {self.new} ({self.new.__class__.__name__}) in {self.old} \"\n            f\"({self.old.__class__.__name__}): mismatched types\"\n        )\n        super().__init__(msg)\n\n\nclass PackageVersionNotFoundError(DependencyError):\n    def __init__(\n        self,\n        package_name: str,\n        version_range,\n        available_versions: List[str],\n        should_version_check: bool,\n    ):\n        self.package_name = package_name\n        self.version_range = version_range\n        self.available_versions = available_versions\n        self.should_version_check = should_version_check\n        super().__init__(self.get_message())\n\n    def get_message(self) -> str:\n        base_msg = (\n            \"Could not find a matching compatible version for package {}\\n\"\n            \"  Requested range: {}\\n\"\n            \"  Compatible versions: {}\\n\"\n        )\n        addendum = (\n            (\n                \"\\n\"\n                \"  Not shown: package versions incompatible with installed version of dbt-core\\n\"\n                \"  To include them, run 'dbt --no-version-check deps'\"\n            )\n            if self.should_version_check\n            else \"\"\n        )\n        msg = (\n            base_msg.format(self.package_name, self.version_range, self.available_versions)\n            + addendum\n        )\n        return msg\n\n\nclass PackageNotFoundError(DependencyError):\n    def __init__(self, package_name: str):\n        self.package_name = package_name\n        msg = f\"Package {self.package_name} was not found in the package index\"\n        super().__init__(msg)\n\n\n# config level exceptions\nclass ProfileConfigError(DbtProfileError):\n    def __init__(self, exc: ValidationError):\n        self.exc = exc\n        msg = self.validator_error_message(self.exc)\n        super().__init__(msg=msg)\n\n\nclass ProjectContractError(DbtProjectError):\n    def __init__(self, exc: ValidationError):\n        self.exc = exc\n        msg = self.validator_error_message(self.exc)\n        super().__init__(msg=msg)\n\n\nclass ProjectContractBrokenError(DbtProjectError):\n    def __init__(self, exc: ValidationError):\n        self.exc = exc\n        msg = self.validator_error_message(self.exc)\n        super().__init__(msg=msg)\n\n\nclass ConfigContractBrokenError(DbtProjectError):\n    def __init__(self, exc: ValidationError):\n        self.exc = exc\n        msg = self.validator_error_message(self.exc)\n        super().__init__(msg=msg)\n\n\nclass NonUniquePackageNameError(CompilationError):\n    def __init__(self, project_name: str):\n        self.project_name = project_name\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        msg = (\n            \"dbt found more than one package with the name \"\n            f'\"{self.project_name}\" included in this project. Package '\n            \"names must be unique in a project. Please rename \"\n            \"one of these packages.\"\n        )\n        return msg\n\n\nclass UninstalledPackagesFoundError(CompilationError):\n    def __init__(\n        self,\n        count_packages_installed: int,\n        count_packages_specified: int,\n        packages_specified_path: str,\n        packages_install_path: str,\n        uninstalled_packages: Tuple[str, ...] = tuple(),\n    ):\n        self.count_packages_specified = count_packages_specified\n        self.count_packages_installed = count_packages_installed\n        self.uninstalled_packages = uninstalled_packages\n        self.packages_specified_path = packages_specified_path\n        self.packages_install_path = packages_install_path\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        uninstalled_packages_str = \", \".join(self.uninstalled_packages)\n        msg = (\n            f\"dbt expects {self.count_packages_specified} package(s) \"\n            f\"based on packages specified in {self.packages_specified_path}, but \"\n            f\"found only {self.count_packages_installed} package(s) installed \"\n            f\"in {self.packages_install_path}. \"\n        )\n        if self.uninstalled_packages:\n            msg += f\"Following packages were not found: {uninstalled_packages_str}. \"\n\n        msg += 'Run \"dbt deps\" to install package dependencies.'\n        return msg\n\n\nclass OptionNotYamlDictError(CompilationError):\n    def __init__(self, var_type, option_name):\n        self.var_type = var_type\n        self.option_name = option_name\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        type_name = self.var_type.__name__\n\n        msg = f\"The --{self.option_name} argument must be a YAML dictionary, but was of type '{type_name}'\"\n        return msg\n\n\n# contracts level\nclass UnrecognizedCredentialTypeError(CompilationError):\n    def __init__(self, typename: str, supported_types: List):\n        self.typename = typename\n        self.supported_types = supported_types\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        msg = 'Unrecognized credentials type \"{}\" - supported types are ({})'.format(\n            self.typename, \", \".join('\"{}\"'.format(t) for t in self.supported_types)\n        )\n        return msg\n\n\n# jinja exceptions\n\n\nclass PatchTargetNotFoundError(CompilationError):\n    def __init__(self, patches: Dict):\n        self.patches = patches\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        patch_list = \"\\n\\t\".join(\n            f\"model {p.name} (referenced in path {p.original_file_path})\"\n            for p in self.patches.values()\n        )\n        msg = f\"dbt could not find models for the following patches:\\n\\t{patch_list}\"\n        return msg\n\n\nclass MissingRelationError(CompilationError):\n    def __init__(self, relation, model=None):\n        self.relation = relation\n        self.model = model\n        msg = f\"Relation {self.relation} not found!\"\n        super().__init__(msg=msg)\n\n\nclass AmbiguousAliasError(CompilationError):\n    def __init__(self, node_1, node_2, duped_name=None):\n        self.node_1 = node_1\n        self.node_2 = node_2\n        if duped_name is None:\n            self.duped_name = f\"{self.node_1.database}.{self.node_1.schema}.{self.node_1.alias}\"\n        else:\n            self.duped_name = duped_name\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n\n        msg = (\n            f'dbt found two resources with the database representation \"{self.duped_name}\".\\ndbt '\n            \"cannot create two resources with identical database representations. \"\n            \"To fix this,\\nchange the configuration of one of these resources:\"\n            f\"\\n- {self.node_1.unique_id} ({self.node_1.original_file_path})\\n- {self.node_2.unique_id} ({self.node_2.original_file_path})\"\n        )\n        return msg\n\n\nclass AmbiguousResourceNameRefError(CompilationError):\n    def __init__(self, duped_name, unique_ids, node=None):\n        self.duped_name = duped_name\n        self.unique_ids = unique_ids\n        self.packages = [unique_id.split(\".\")[1] for unique_id in unique_ids]\n        super().__init__(msg=self.get_message(), node=node)\n\n    def get_message(self) -> str:\n        formatted_unique_ids = \"'{0}'\".format(\"', '\".join(self.unique_ids))\n        formatted_packages = \"'{0}'\".format(\"' or '\".join(self.packages))\n        msg = (\n            f\"When referencing '{self.duped_name}', dbt found nodes in multiple packages: {formatted_unique_ids}\"\n            f\"\\nTo fix this, use two-argument 'ref', with the package name first: {formatted_packages}\"\n        )\n        return msg\n\n\nclass AmbiguousCatalogMatchError(CompilationError):\n    def __init__(self, unique_id: str, match_1, match_2):\n        self.unique_id = unique_id\n        self.match_1 = match_1\n        self.match_2 = match_2\n        super().__init__(msg=self.get_message())\n\n    def get_match_string(self, match):\n        match_schema = match.get(\"metadata\", {}).get(\"schema\")\n        match_name = match.get(\"metadata\", {}).get(\"name\")\n        return f\"{match_schema}.{match_name}\"\n\n    def get_message(self) -> str:\n        msg = (\n            \"dbt found two relations in your warehouse with similar database identifiers. \"\n            \"dbt\\nis unable to determine which of these relations was created by the model \"\n            f'\"{self.unique_id}\".\\nIn order for dbt to correctly generate the catalog, one '\n            \"of the following relations must be deleted or renamed:\\n\\n - \"\n            f\"{self.get_match_string(self.match_1)}\\n - {self.get_match_string(self.match_2)}\"\n        )\n\n        return msg\n\n\nclass DependencyNotFoundError(CompilationError):\n    def __init__(self, node, node_description, required_pkg):\n        self.node = node\n        self.node_description = node_description\n        self.required_pkg = required_pkg\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        msg = (\n            f\"Error while parsing {self.node_description}.\\nThe required package \"\n            f'\"{self.required_pkg}\" was not found. Is the package installed?\\n'\n            \"Hint: You may need to run `dbt deps`.\"\n        )\n\n        return msg\n\n\nclass DuplicatePatchPathError(CompilationError):\n    def __init__(self, patch_1, existing_patch_path):\n        self.patch_1 = patch_1\n        self.existing_patch_path = existing_patch_path\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        name = self.patch_1.name\n        fix = self._fix_dupe_msg(\n            self.patch_1.original_file_path,\n            self.existing_patch_path,\n            name,\n            \"resource\",\n        )\n        msg = (\n            f\"dbt found two schema.yml entries for the same resource named \"\n            f\"{name}. Resources and their associated columns may only be \"\n            f\"described a single time. To fix this, {fix}\"\n        )\n        return msg\n\n\n# should this inherit ParsingError instead?\nclass DuplicateResourceNameError(CompilationError):\n    def __init__(self, node_1, node_2):\n        self.node_1 = node_1\n        self.node_2 = node_2\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        duped_name = self.node_1.name\n        node_type = NodeType(self.node_1.resource_type)\n        pluralized = (\n            node_type.pluralize()\n            if self.node_1.resource_type == self.node_2.resource_type\n            else \"resources\"  # still raise if ref() collision, e.g. model + seed\n        )\n\n        action = \"looking for\"\n        # duplicate 'ref' targets\n        if node_type in REFABLE_NODE_TYPES:\n            formatted_name = f'ref(\"{duped_name}\")'\n        # duplicate sources\n        elif node_type == NodeType.Source:\n            duped_name = self.node_1.get_full_source_name()\n            formatted_name = self.node_1.get_source_representation()\n        # duplicate docs blocks\n        elif node_type == NodeType.Documentation:\n            formatted_name = f'doc(\"{duped_name}\")'\n        # duplicate generic tests\n        elif node_type == NodeType.Test and hasattr(self.node_1, \"test_metadata\"):\n            column_name = (\n                f'column \"{self.node_1.column_name}\" in ' if self.node_1.column_name else \"\"\n            )\n            model_name = self.node_1.file_key_name\n            duped_name = f'{self.node_1.name}\" defined on {column_name}\"{model_name}'\n            action = \"running\"\n            formatted_name = \"tests\"\n        # all other resource types\n        else:\n            formatted_name = duped_name\n\n        msg = f\"\"\"\ndbt found two {pluralized} with the name \"{duped_name}\".\n\nSince these resources have the same name, dbt will be unable to find the correct resource\nwhen {action} {formatted_name}.\n\nTo fix this, change the name of one of these resources:\n- {self.node_1.unique_id} ({self.node_1.original_file_path})\n- {self.node_2.unique_id} ({self.node_2.original_file_path})\n    \"\"\".strip()\n        return msg\n\n\nclass DuplicateVersionedUnversionedError(ParsingError):\n    def __init__(self, versioned_node, unversioned_node):\n        self.versioned_node = versioned_node\n        self.unversioned_node = unversioned_node\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        msg = f\"\"\"\ndbt found versioned and unversioned models with the name \"{self.versioned_node.name}\".\n\nSince these resources have the same name, dbt will be unable to find the correct resource\nwhen looking for ref('{self.versioned_node.name}').\n\nTo fix this, change the name of the unversioned resource\n{self.unversioned_node.unique_id} ({self.unversioned_node.original_file_path})\nor add the unversioned model to the versions in {self.versioned_node.patch_path}\n    \"\"\".strip()\n        return msg\n\n\nclass PropertyYMLError(CompilationError):\n    def __init__(self, path: str, issue: str):\n        self.path = path\n        self.issue = issue\n        super().__init__(msg=self.get_message())\n\n    def get_message(self) -> str:\n        msg = (\n            f\"The yml property file at {self.path} is invalid because {self.issue}. \"\n            \"Please consult the documentation for more information on yml property file \"\n            \"syntax:\\n\\nhttps://docs.getdbt.com/reference/configs-and-properties\"\n        )\n        return msg\n\n\nclass ContractError(CompilationError):\n    def __init__(self, yaml_columns, sql_columns):\n        self.yaml_columns = yaml_columns\n        self.sql_columns = sql_columns\n        super().__init__(msg=self.get_message())\n\n    def get_mismatches(self) -> \"agate.Table\":\n        # avoid a circular import\n        from dbt_common.clients.agate_helper import table_from_data_flat\n\n        column_names = [\"column_name\", \"definition_type\", \"contract_type\", \"mismatch_reason\"]\n        # list of mismatches\n        mismatches: List[Dict[str, str]] = []\n        # track sql cols so we don't need another for loop later\n        sql_col_set = set()\n        # for each sql col list\n        for sql_col in self.sql_columns:\n            # add sql col to set\n            sql_col_set.add(sql_col[\"name\"])\n            # for each yaml col list\n            for i, yaml_col in enumerate(self.yaml_columns):\n                # if name matches\n                if sql_col[\"name\"] == yaml_col[\"name\"]:\n                    # if type matches\n                    if sql_col[\"data_type\"] == yaml_col[\"data_type\"]:\n                        # its a perfect match! don't include in mismatch table\n                        break\n                    else:\n                        # same name, diff type\n                        row = [\n                            sql_col[\"name\"],\n                            sql_col[\"data_type\"],\n                            yaml_col[\"data_type\"],\n                            \"data type mismatch\",\n                        ]\n                        mismatches += [dict(zip(column_names, row))]\n                        break\n                # if last loop, then no name match\n                if i == len(self.yaml_columns) - 1:\n                    row = [sql_col[\"name\"], sql_col[\"data_type\"], \"\", \"missing in contract\"]\n                    mismatches += [dict(zip(column_names, row))]\n\n        # now add all yaml cols without a match\n        for yaml_col in self.yaml_columns:\n            if yaml_col[\"name\"] not in sql_col_set:\n                row = [yaml_col[\"name\"], \"\", yaml_col[\"data_type\"], \"missing in definition\"]\n                mismatches += [dict(zip(column_names, row))]\n\n        mismatches_sorted = sorted(mismatches, key=lambda d: d[\"column_name\"])\n        return table_from_data_flat(mismatches_sorted, column_names)\n\n    def get_message(self) -> str:\n        if not self.yaml_columns:\n            return (\n                \"This model has an enforced contract, and its 'columns' specification is missing\"\n            )\n\n        table: \"agate.Table\" = self.get_mismatches()\n        # Hack to get Agate table output as string\n        output = io.StringIO()\n        table.print_table(output=output, max_rows=None, max_column_width=50)  # type: ignore\n        mismatches = output.getvalue()\n\n        msg = (\n            \"This model has an enforced contract that failed.\\n\"\n            \"Please ensure the name, data_type, and number of columns in your contract \"\n            \"match the columns in your model's definition.\\n\\n\"\n            f\"{mismatches}\"\n        )\n\n        return msg\n\n\n# not modifying these since rpc should be deprecated soon\nclass UnknownAsyncIDException(Exception):\n    CODE = 10012\n    MESSAGE = \"RPC server got an unknown async ID\"\n\n    def __init__(self, task_id):\n        self.task_id = task_id\n\n    def __str__(self):\n        return f\"{self.MESSAGE}: {self.task_id}\"\n\n\nclass RPCFailureResult(DbtRuntimeError):\n    CODE = 10002\n    MESSAGE = \"RPC execution error\"\n\n\nclass RPCTimeoutException(DbtRuntimeError):\n    CODE = 10008\n    MESSAGE = \"RPC timeout error\"\n\n    def __init__(self, timeout: Optional[float] = None):\n        super().__init__(self.MESSAGE)\n        self.timeout = timeout\n\n    def data(self):\n        result = super().data()\n        result.update(\n            {\n                \"timeout\": self.timeout,\n                \"message\": f\"RPC timed out after {self.timeout}s\",\n            }\n        )\n        return result\n\n\nclass RPCKilledException(DbtRuntimeError):\n    CODE = 10009\n    MESSAGE = \"RPC process killed\"\n\n    def __init__(self, signum: int):\n        self.signum = signum\n        self.msg = f\"RPC process killed by signal {self.signum}\"\n        super().__init__(self.msg)\n\n    def data(self):\n        return {\n            \"signum\": self.signum,\n            \"message\": self.msg,\n        }\n\n\nclass RPCCompiling(DbtRuntimeError):\n    CODE = 10010\n    MESSAGE = 'RPC server is compiling the project, call the \"status\" method for' \" compile status\"\n\n    def __init__(self, msg: Optional[str] = None, node=None):\n        if msg is None:\n            msg = \"compile in progress\"\n        super().__init__(msg, node)\n\n\nclass RPCLoadException(DbtRuntimeError):\n    CODE = 10011\n    MESSAGE = (\n        'RPC server failed to compile project, call the \"status\" method for' \" compile status\"\n    )\n\n    def __init__(self, cause: Dict[str, Any]):\n        self.cause = cause\n        self.msg = f'{self.MESSAGE}: {self.cause[\"message\"]}'\n        super().__init__(self.msg)\n\n    def data(self):\n        return {\"cause\": self.cause, \"message\": self.msg}\n"
  },
  {
    "path": "core/dbt/flags.py",
    "content": "# Do not import the os package because we expose this package in jinja\nfrom argparse import Namespace\nfrom pathlib import Path\n\n# this roughly follows the patten of EVENT_MANAGER in dbt/common/events/functions.py\n# During de-globlization, we'll need to handle both similarly\n# Match USE_COLORS default with default in dbt.cli.params.use_colors for use in --version\nGLOBAL_FLAGS = Namespace(USE_COLORS=True)  # type: ignore\n\n\ndef set_flags(flags):\n    global GLOBAL_FLAGS\n    GLOBAL_FLAGS = flags\n\n\ndef get_flags():\n    return GLOBAL_FLAGS\n\n\ndef set_from_args(args: Namespace, project_flags):\n    global GLOBAL_FLAGS\n    from dbt.cli.flags import Flags, convert_config\n    from dbt.cli.main import cli\n\n    # we set attributes of args after initialize the flags, but project_flags\n    # is being read in the Flags constructor, so we need to read it here and pass in\n    # to make sure we use the correct project_flags\n    profiles_dir = getattr(args, \"PROFILES_DIR\", None) or getattr(args, \"profiles_dir\", None)\n    project_dir = getattr(args, \"PROJECT_DIR\", None) or getattr(args, \"project_dir\", None)\n    if profiles_dir and project_dir:\n        from dbt.config.project import read_project_flags\n\n        project_flags = read_project_flags(project_dir, profiles_dir)\n\n    # make a dummy context to get the flags, totally arbitrary\n    ctx = cli.make_context(\"run\", [\"run\"])\n    flags = Flags(ctx, project_flags)\n    for arg_name, args_param_value in vars(args).items():\n        args_param_value = convert_config(arg_name, args_param_value)\n        object.__setattr__(flags, arg_name.upper(), args_param_value)\n        object.__setattr__(flags, arg_name.lower(), args_param_value)\n    flags.set_common_global_flags()\n    GLOBAL_FLAGS = flags  # type: ignore\n\n\ndef get_flag_dict():\n    flag_attr = {\n        \"use_experimental_parser\",\n        \"static_parser\",\n        \"warn_error\",\n        \"warn_error_options\",\n        \"write_json\",\n        \"partial_parse\",\n        \"use_colors\",\n        \"profiles_dir\",\n        \"debug\",\n        \"log_format\",\n        \"version_check\",\n        \"fail_fast\",\n        \"send_anonymous_usage_stats\",\n        \"printer_width\",\n        \"indirect_selection\",\n        \"log_cache_events\",\n        \"quiet\",\n        \"no_print\",\n        \"cache_selected_only\",\n        \"introspect\",\n        \"target_path\",\n        \"log_path\",\n        \"invocation_command\",\n        \"empty\",\n    }\n    return {key: getattr(GLOBAL_FLAGS, key.upper(), None) for key in flag_attr}\n\n\n# This is used by core/dbt/context/base.py to return a flag object\n# in Jinja.\ndef get_flag_obj():\n    new_flags = Namespace()\n    for key, val in get_flag_dict().items():\n        if isinstance(val, Path):\n            val = str(val)\n        setattr(new_flags, key.upper(), val)\n    # The following 3 are CLI arguments only so they're not full-fledged flags,\n    # but we put in flags for users.\n    setattr(new_flags, \"FULL_REFRESH\", getattr(GLOBAL_FLAGS, \"FULL_REFRESH\", None))\n    setattr(new_flags, \"STORE_FAILURES\", getattr(GLOBAL_FLAGS, \"STORE_FAILURES\", None))\n    setattr(new_flags, \"WHICH\", getattr(GLOBAL_FLAGS, \"WHICH\", None))\n    # Project-level behavior change flag, exposed to Jinja for gating in adapter macros.\n    setattr(\n        new_flags,\n        \"REQUIRE_SQL_HEADER_IN_TEST_CONFIGS\",\n        getattr(GLOBAL_FLAGS, \"REQUIRE_SQL_HEADER_IN_TEST_CONFIGS\", False),\n    )\n    return new_flags\n"
  },
  {
    "path": "core/dbt/graph/README.md",
    "content": "# Graph README\n\n## Graph Selector Creation\n\n### Selector Loading\nDuring dbt execution, the `@requires.project` decorator creates the final selector objects used in the graph. The `SelectorConfig` class loads selectors from the project configuration, while the `selector_config_from_data` function parses these selectors.\n\n#### Indirect Selection Default Value\nIn `@requires.preflight`, dbt reads CLI flags, environment variables, and the parameter's default value. It resolves these inputs based on their precedence order and stores the resolved value in global flags. When loading selectors, the [`selection_criteria_from_dict`](https://github.com/dbt-labs/dbt-core/blob/b316c5f18021fef3d7fd6ec255427054b7d2205e/core/dbt/graph/selector_spec.py#L111) function resolves the indirect selection value to the global flags value if not set. This ensures correct resolution of the indirect selection value.\n"
  },
  {
    "path": "core/dbt/graph/__init__.py",
    "content": "from .cli import parse_difference, parse_from_selectors_definition  # noqa: F401\nfrom .graph import Graph, UniqueId  # noqa: F401\nfrom .queue import GraphQueue  # noqa: F401\nfrom .selector import NodeSelector, ResourceTypeSelector  # noqa: F401\nfrom .selector_spec import (  # noqa: F401\n    SelectionCriteria,\n    SelectionDifference,\n    SelectionIntersection,\n    SelectionSpec,\n    SelectionUnion,\n)\n"
  },
  {
    "path": "core/dbt/graph/cli.py",
    "content": "# special support for CLI argument parsing.\n# TODO: Remove as part of https://github.com/dbt-labs/dbt-core/issues/6701\nimport itertools\nfrom copy import deepcopy\nfrom typing import Any, Dict, List, Optional, Tuple, Union\n\nfrom dbt.clients.yaml_helper import Dumper, Loader, yaml  # noqa: F401\nfrom dbt.contracts.selection import SelectorDefinition, SelectorFile\nfrom dbt.flags import get_flags\nfrom dbt_common.exceptions import DbtInternalError, DbtValidationError\n\nfrom .selector_spec import (\n    IndirectSelection,\n    SelectionCriteria,\n    SelectionDifference,\n    SelectionIntersection,\n    SelectionSpec,\n    SelectionUnion,\n)\n\nINTERSECTION_DELIMITER = \",\"\n\nDEFAULT_INCLUDES: List[str] = [\"fqn:*\", \"source:*\", \"exposure:*\", \"metric:*\", \"semantic_model:*\"]\nDEFAULT_EXCLUDES: List[str] = []\n\n\ndef parse_union(\n    components: List[str],\n    expect_exists: bool,\n) -> SelectionUnion:\n    # turn ['a b', 'c'] -> ['a', 'b', 'c']\n    raw_specs = itertools.chain.from_iterable(r.split(\" \") for r in components)\n    union_components: List[SelectionSpec] = []\n    flags = get_flags()\n    # ['a', 'b', 'c,d'] -> union('a', 'b', intersection('c', 'd'))\n    for raw_spec in raw_specs:\n        intersection_components: List[SelectionSpec] = [\n            SelectionCriteria.from_single_spec(part)\n            for part in raw_spec.split(INTERSECTION_DELIMITER)\n        ]\n        union_components.append(\n            SelectionIntersection(\n                components=intersection_components,\n                expect_exists=expect_exists,\n                raw=raw_spec,\n                indirect_selection=IndirectSelection(flags.INDIRECT_SELECTION),\n            )\n        )\n    return SelectionUnion(\n        components=union_components,\n        expect_exists=False,\n        raw=components,\n        indirect_selection=IndirectSelection(flags.INDIRECT_SELECTION),\n    )\n\n\ndef parse_union_from_default(raw: Optional[List[str]], default: List[str]) -> SelectionUnion:\n    components: List[str]\n    expect_exists: bool\n    if raw is None:\n        return parse_union(components=default, expect_exists=False)\n    else:\n        return parse_union(components=raw, expect_exists=True)\n\n\ndef parse_difference(\n    include: Optional[List[str]], exclude: Optional[List[str]]\n) -> SelectionDifference:\n\n    if include == ():\n        include = None\n\n    included = parse_union_from_default(include, DEFAULT_INCLUDES)\n    excluded = parse_union_from_default(exclude, DEFAULT_EXCLUDES)\n    return SelectionDifference(components=[included, excluded])\n\n\nRawDefinition = Union[str, Dict[str, Any]]\n\n\ndef _get_list_dicts(dct: Dict[str, Any], key: str) -> List[RawDefinition]:\n    result: List[RawDefinition] = []\n    if key not in dct:\n        raise DbtInternalError(f\"Expected to find key {key} in dict, only found {list(dct)}\")\n    values = dct[key]\n    if not isinstance(values, list):\n        raise DbtValidationError(f'Invalid value for key \"{key}\". Expected a list.')\n    for value in values:\n        if isinstance(value, dict):\n            for value_key in value:\n                if not isinstance(value_key, str):\n                    raise DbtValidationError(\n                        f'Expected all keys to \"{key}\" dict to be strings, '\n                        f'but \"{value_key}\" is a \"{type(value_key)}\"'\n                    )\n            result.append(value)\n        elif isinstance(value, str):\n            result.append(value)\n        else:\n            raise DbtValidationError(\n                f'Invalid value type {type(value)} in key \"{key}\", expected '\n                f\"dict or str (value: {value}).\"\n            )\n\n    return result\n\n\ndef _parse_exclusions(definition, result={}) -> Optional[SelectionSpec]:\n    exclusions = _get_list_dicts(definition, \"exclude\")\n    parsed_exclusions = [parse_from_definition(excl, result=result) for excl in exclusions]\n    if len(parsed_exclusions) == 1:\n        return parsed_exclusions[0]\n    elif len(parsed_exclusions) > 1:\n        return SelectionUnion(components=parsed_exclusions, raw=exclusions)\n    else:\n        return None\n\n\ndef _parse_include_exclude_subdefs(\n    definitions: List[RawDefinition], result={}\n) -> Tuple[List[SelectionSpec], Optional[SelectionSpec]]:\n    include_parts: List[SelectionSpec] = []\n    diff_arg: Optional[SelectionSpec] = None\n\n    for definition in definitions:\n        if isinstance(definition, dict) and \"exclude\" in definition:\n            # do not allow multiple exclude: defs at the same level\n            if diff_arg is not None:\n                yaml_sel_cfg = yaml.dump(definition)\n                raise DbtValidationError(\n                    f\"You cannot provide multiple exclude arguments to the \"\n                    f\"same selector set operator:\\n{yaml_sel_cfg}\"\n                )\n            diff_arg = _parse_exclusions(definition, result=result)\n        else:\n            include_parts.append(parse_from_definition(definition, result=result))\n\n    return (include_parts, diff_arg)\n\n\ndef parse_union_definition(definition: Dict[str, Any], result={}) -> SelectionSpec:\n    union_def_parts = _get_list_dicts(definition, \"union\")\n    include, exclude = _parse_include_exclude_subdefs(union_def_parts, result=result)\n\n    union = SelectionUnion(components=include)\n\n    if exclude is None:\n        union.raw = definition\n        return union\n    else:\n        return SelectionDifference(components=[union, exclude], raw=definition)\n\n\ndef parse_intersection_definition(definition: Dict[str, Any], result={}) -> SelectionSpec:\n    intersection_def_parts = _get_list_dicts(definition, \"intersection\")\n    include, exclude = _parse_include_exclude_subdefs(intersection_def_parts, result=result)\n    intersection = SelectionIntersection(components=include)\n\n    if exclude is None:\n        intersection.raw = definition\n        return intersection\n    else:\n        return SelectionDifference(components=[intersection, exclude], raw=definition)\n\n\ndef parse_dict_definition(definition: Dict[str, Any], result={}) -> SelectionSpec:\n    diff_arg: Optional[SelectionSpec] = None\n    if len(definition) == 1:\n        key = list(definition)[0]\n        value = definition[key]\n        if not isinstance(key, str):\n            raise DbtValidationError(\n                f'Expected definition key to be a \"str\", got one of type ' f'\"{type(key)}\" ({key})'\n            )\n        dct = {\n            \"method\": key,\n            \"value\": value,\n        }\n    elif \"method\" in definition and \"value\" in definition:\n        dct = definition\n        if \"exclude\" in definition:\n            diff_arg = _parse_exclusions(definition, result=result)\n            dct = {k: v for k, v in dct.items() if k != \"exclude\"}\n    else:\n        raise DbtValidationError(\n            f'Expected either 1 key or else \"method\" '\n            f'and \"value\" keys, but got {list(definition)}'\n        )\n\n    # if key isn't a valid method name, this will raise\n    base = SelectionCriteria.selection_criteria_from_dict(definition, dct)\n    if diff_arg is None:\n        return base\n    else:\n        return SelectionDifference(components=[base, diff_arg])\n\n\ndef parse_from_definition(\n    definition: RawDefinition,\n    rootlevel=False,\n    result: Dict[str, Dict[str, Union[SelectionSpec, bool]]] = {},\n) -> SelectionSpec:\n\n    if (\n        isinstance(definition, dict)\n        and (\"union\" in definition or \"intersection\" in definition)\n        and rootlevel\n        and len(definition) > 1\n    ):\n        keys = \",\".join(definition.keys())\n        raise DbtValidationError(\n            f\"Only a single 'union' or 'intersection' key is allowed \"\n            f\"in a root level selector definition; found {keys}.\"\n        )\n    if isinstance(definition, str):\n        return SelectionCriteria.from_single_spec(definition)\n    elif \"union\" in definition:\n        return parse_union_definition(definition, result=result)\n    elif \"intersection\" in definition:\n        return parse_intersection_definition(definition, result=result)\n    elif isinstance(definition, dict):\n        return parse_dict_definition(definition, result=result)\n    else:\n        raise DbtValidationError(\n            f\"Expected to find union, intersection, str or dict, instead \"\n            f\"found {type(definition)}: {definition}\"\n        )\n\n\ndef parse_from_selectors_definition(\n    source: SelectorFile,\n) -> Dict[str, Dict[str, Union[SelectionSpec, bool]]]:\n    result: Dict[str, Dict[str, Union[SelectionSpec, bool]]] = {}\n    selector: SelectorDefinition\n    for selector in source.selectors:\n        result[selector.name] = {\n            \"default\": selector.default,\n            \"definition\": parse_from_definition(\n                selector.definition, rootlevel=True, result=deepcopy(result)\n            ),\n        }\n    return result\n"
  },
  {
    "path": "core/dbt/graph/graph.py",
    "content": "from functools import partial\nfrom itertools import product\nfrom typing import Iterable, Iterator, NewType, Optional, Set\n\nimport networkx as nx  # type: ignore\n\nfrom dbt_common.exceptions import DbtInternalError\n\nUniqueId = NewType(\"UniqueId\", str)\n\n\nclass Graph:\n    \"\"\"A wrapper around the networkx graph that understands SelectionCriteria\n    and how they interact with the graph.\n    \"\"\"\n\n    def __init__(self, graph) -> None:\n        self.graph: nx.DiGraph = graph\n\n    def nodes(self) -> Set[UniqueId]:\n        return set(self.graph.nodes())\n\n    def edges(self):\n        return self.graph.edges()\n\n    def __iter__(self) -> Iterator[UniqueId]:\n        return iter(self.graph.nodes())\n\n    def ancestors(self, node: UniqueId, max_depth: Optional[int] = None) -> Set[UniqueId]:\n        \"\"\"Returns all nodes having a path to `node` in `graph`\"\"\"\n        if not self.graph.has_node(node):\n            raise DbtInternalError(f\"Node {node} not found in the graph!\")\n        filtered_graph = self.exclude_edge_type(\"parent_test\")\n        return {\n            child\n            for _, child in nx.bfs_edges(filtered_graph, node, reverse=True, depth_limit=max_depth)\n        }\n\n    def descendants(self, node: UniqueId, max_depth: Optional[int] = None) -> Set[UniqueId]:\n        \"\"\"Returns all nodes reachable from `node` in `graph`\"\"\"\n        if not self.graph.has_node(node):\n            raise DbtInternalError(f\"Node {node} not found in the graph!\")\n        filtered_graph = self.exclude_edge_type(\"parent_test\")\n        return {child for _, child in nx.bfs_edges(filtered_graph, node, depth_limit=max_depth)}\n\n    def exclude_edge_type(self, edge_type_to_exclude):\n        return nx.subgraph_view(\n            self.graph,\n            filter_edge=partial(self.filter_edges_by_type, edge_type=edge_type_to_exclude),\n        )\n\n    def filter_edges_by_type(self, first_node, second_node, edge_type):\n        return self.graph.get_edge_data(first_node, second_node).get(\"edge_type\") != edge_type\n\n    def select_childrens_parents(self, selected: Set[UniqueId]) -> Set[UniqueId]:\n        ancestors_for = self.select_children(selected) | selected\n        return self.select_parents(ancestors_for) | ancestors_for\n\n    def select_children(\n        self, selected: Set[UniqueId], max_depth: Optional[int] = None\n    ) -> Set[UniqueId]:\n        \"\"\"Returns all nodes which are descendants of the 'selected' set.\n        Nodes in the 'selected' set are counted as children only if\n        they are descendants of other nodes in the 'selected' set.\"\"\"\n        children: Set[UniqueId] = set()\n        i = 0\n        while len(selected) > 0 and (max_depth is None or i < max_depth):\n            next_layer: Set[UniqueId] = set()\n            for node in selected:\n                next_layer.update(\n                    iter(\n                        e[1]\n                        for e in self.graph.out_edges(node)\n                        if e[1] not in children\n                        and self.filter_edges_by_type(e[0], e[1], \"parent_test\")\n                    )\n                )\n            children.update(next_layer)\n            selected = next_layer\n            i += 1\n\n        return children\n\n    def select_parents(\n        self, selected: Set[UniqueId], max_depth: Optional[int] = None\n    ) -> Set[UniqueId]:\n        \"\"\"Returns all nodes which are ancestors of the 'selected' set.\n        Nodes in the 'selected' set are counted as parents only if\n        they are ancestors of other nodes in the 'selected' set.\"\"\"\n        parents: Set[UniqueId] = set()\n        i = 0\n        while len(selected) > 0 and (max_depth is None or i < max_depth):\n            next_layer: Set[UniqueId] = set()\n            for node in selected:\n                next_layer.update(\n                    iter(\n                        e[0]\n                        for e in self.graph.in_edges(node)\n                        if e[0] not in parents\n                        and self.filter_edges_by_type(e[0], e[1], \"parent_test\")\n                    )\n                )\n            parents.update(next_layer)\n            selected = next_layer\n            i += 1\n\n        return parents\n\n    def select_successors(self, selected: Set[UniqueId]) -> Set[UniqueId]:\n        successors: Set[UniqueId] = set()\n        for node in selected:\n            successors.update(self.graph.successors(node))\n        return successors\n\n    def get_subset_graph(self, selected: Iterable[UniqueId]) -> \"Graph\":\n        \"\"\"Create and return a new graph that is a shallow copy of the graph,\n        but with only the nodes in include_nodes. Transitive edges across\n        removed nodes are preserved as explicit new edges.\n        \"\"\"\n\n        new_graph: nx.DiGraph = self.graph.copy()\n        include_nodes: Set[UniqueId] = set(selected)\n\n        still_removing: bool = True\n        while still_removing:\n            nodes_to_remove = list(\n                node\n                for node in new_graph\n                if node not in include_nodes\n                and (new_graph.in_degree(node) * new_graph.out_degree(node)) == 0\n            )\n            if len(nodes_to_remove) == 0:\n                still_removing = False\n            else:\n                new_graph.remove_nodes_from(nodes_to_remove)\n\n        # sort remaining nodes by degree\n        remaining_nodes = list(new_graph.nodes())\n        remaining_nodes.sort(\n            key=lambda node: new_graph.in_degree(node) * new_graph.out_degree(node)\n        )\n\n        for node in remaining_nodes:\n            if node not in include_nodes:\n                source_nodes = [x for x, _ in new_graph.in_edges(node)]\n                target_nodes = [x for _, x in new_graph.out_edges(node)]\n\n                new_edges = product(source_nodes, target_nodes)\n                non_cyclic_new_edges = [\n                    (source, target)\n                    for source, target in new_edges\n                    if source != target and not new_graph.has_edge(source, target)\n                ]  # removes cyclic refs and edges already existing in new graph\n\n                new_graph.add_edges_from(non_cyclic_new_edges)\n                new_graph.remove_node(node)\n\n        for node in include_nodes:\n            if node not in new_graph:\n                raise ValueError(\n                    \"Couldn't find model '{}' -- does it exist or is it disabled?\".format(node)\n                )\n\n        return Graph(new_graph)\n\n    def subgraph(self, nodes: Iterable[UniqueId]) -> \"Graph\":\n        # Take the original networkx graph and return a subgraph containing only\n        # the selected unique_id nodes.\n        return Graph(self.graph.subgraph(nodes))\n\n    def get_dependent_nodes(self, node: UniqueId):\n        return nx.descendants(self.graph, node)\n"
  },
  {
    "path": "core/dbt/graph/queue.py",
    "content": "import threading\nfrom queue import PriorityQueue\nfrom typing import Dict, Generator, List, Optional, Set\n\nimport networkx as nx  # type: ignore\n\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.contracts.graph.nodes import (\n    Exposure,\n    GraphMemberNode,\n    Metric,\n    ModelNode,\n    SourceDefinition,\n)\nfrom dbt.node_types import NodeType\n\nfrom .graph import UniqueId\n\n\nclass GraphQueue:\n    \"\"\"A fancy queue that is backed by the dependency graph.\n    Note: this will mutate input!\n\n    This queue is thread-safe for `mark_done` calls, though you must ensure\n    that separate threads do not call `.empty()` or `__len__()` and `.get()` at\n    the same time, as there is an unlocked race!\n    \"\"\"\n\n    def __init__(\n        self,\n        graph: nx.DiGraph,\n        manifest: Manifest,\n        selected: Set[UniqueId],\n        preserve_edges: bool = True,\n    ) -> None:\n        # 'create_empty_copy' returns a copy of the graph G with all of the edges removed, and leaves nodes intact.\n        self.graph = graph if preserve_edges else nx.classes.function.create_empty_copy(graph)\n        self.manifest = manifest\n        self._selected = selected\n        # store the queue as a priority queue.\n        self.inner: PriorityQueue = PriorityQueue()\n        # things that have been popped off the queue but not finished\n        # and worker thread reservations\n        self.in_progress: Set[UniqueId] = set()\n        # microbatch nodes that have been popped off the queue but not finished\n        self.in_progress_microbatch: Set[UniqueId] = set()\n        # things that are in the queue\n        self.queued: Set[UniqueId] = set()\n        # this lock controls most things\n        self.lock = threading.Lock()\n        # store the 'score' of each node as a number. Lower is higher priority.\n        self._scores = self._get_scores(self.graph)\n        # populate the initial queue\n        self._find_new_additions(list(self.graph.nodes()))\n        # awaits after task end\n        self.some_task_done = threading.Condition(self.lock)\n\n    def get_selected_nodes(self) -> Set[UniqueId]:\n        return self._selected.copy()\n\n    def _include_in_cost(self, node_id: UniqueId) -> bool:\n        node = self.manifest.expect(node_id)\n        if node.resource_type != NodeType.Model:\n            return False\n        # must be a Model - tell mypy this won't be a Source or Exposure or Metric\n        assert not isinstance(node, (SourceDefinition, Exposure, Metric))\n        if node.is_ephemeral:\n            return False\n        return True\n\n    @staticmethod\n    def _grouped_topological_sort(\n        graph: nx.DiGraph,\n    ) -> Generator[List[str], None, None]:\n        \"\"\"Topological sort of given graph that groups ties.\n\n        Adapted from `nx.topological_sort`, this function returns a topo sort of a graph however\n        instead of arbitrarily ordering ties in the sort order, ties are grouped together in\n        lists.\n\n        Args:\n            graph: The graph to be sorted.\n\n        Returns:\n            A generator that yields lists of nodes, one list per graph depth level.\n        \"\"\"\n        indegree_map = {v: d for v, d in graph.in_degree() if d > 0}\n        zero_indegree = [v for v, d in graph.in_degree() if d == 0]\n\n        while zero_indegree:\n            yield zero_indegree\n            new_zero_indegree = []\n            for v in zero_indegree:\n                for _, child in graph.edges(v):\n                    indegree_map[child] -= 1\n                    if not indegree_map[child]:\n                        new_zero_indegree.append(child)\n            zero_indegree = new_zero_indegree\n\n    def _get_scores(self, graph: nx.DiGraph) -> Dict[str, int]:\n        \"\"\"Scoring nodes for processing order.\n\n        Scores are calculated by the graph depth level. Lowest score (0) should be processed first.\n\n        Args:\n            graph: The graph to be scored.\n\n        Returns:\n            A dictionary consisting of `node name`:`score` pairs.\n        \"\"\"\n        # split graph by connected subgraphs\n        subgraphs = (graph.subgraph(x) for x in nx.connected_components(nx.Graph(graph)))\n\n        # score all nodes in all subgraphs\n        scores = {}\n        for subgraph in subgraphs:\n            grouped_nodes = self._grouped_topological_sort(subgraph)\n            for level, group in enumerate(grouped_nodes):\n                for node in group:\n                    scores[node] = level\n\n        return scores\n\n    def get(self, block: bool = True, timeout: Optional[float] = None) -> GraphMemberNode:\n        \"\"\"Get a node off the inner priority queue. By default, this blocks.\n\n        This takes the lock, but only for part of it.\n\n        :param block: If True, block until the inner queue has data\n        :param timeout: If set, block for timeout seconds waiting for data.\n        :return: The node as present in the manifest.\n\n        See `queue.PriorityQueue` for more information on `get()` behavior and\n        exceptions.\n        \"\"\"\n        _, node_id = self.inner.get(block=block, timeout=timeout)\n        node = self.manifest.expect(node_id)\n        is_microbatch = (\n            isinstance(node, ModelNode) and node.config.incremental_strategy == \"microbatch\"\n        )\n\n        with self.lock:\n            self._mark_in_progress(node_id, is_microbatch=is_microbatch)\n\n        return node\n\n    def __len__(self) -> int:\n        \"\"\"The length of the queue is the number of tasks left for the queue to\n        give out, regardless of where they are. Incomplete tasks are not part\n        of the length.\n\n        This takes the lock.\n        \"\"\"\n        with self.lock:\n            return len(self.graph) - len(self.in_progress)\n\n    def empty(self) -> bool:\n        \"\"\"The graph queue is 'empty' if it all remaining nodes in the graph\n        are in progress.\n\n        This takes the lock.\n        \"\"\"\n        return len(self) == 0\n\n    def _already_known(self, node: UniqueId) -> bool:\n        \"\"\"Decide if a node is already known (either handed out as a task, or\n        in the queue).\n\n        Callers must hold the lock.\n\n        :param str node: The node ID to check\n        :returns bool: If the node is in progress/queued.\n        \"\"\"\n        return node in self.in_progress or node in self.queued\n\n    def _find_new_additions(self, candidates) -> None:\n        \"\"\"Find any nodes in the graph that need to be added to the internal\n        queue and add them.\n        \"\"\"\n        for node in candidates:\n            if self.graph.in_degree(node) == 0 and not self._already_known(node):\n                self.inner.put((self._scores[node], node))\n                self.queued.add(node)\n\n    def mark_done(self, node_id: UniqueId) -> None:\n        \"\"\"Given a node's unique ID, mark it as done.\n\n        This method takes the lock.\n\n        :param str node_id: The node ID to mark as complete.\n        \"\"\"\n        with self.lock:\n            self.in_progress.remove(node_id)\n            if node_id in self.in_progress_microbatch:\n                self.in_progress_microbatch.remove(node_id)\n            successors = list(self.graph.successors(node_id))\n            self.graph.remove_node(node_id)\n            self._find_new_additions(successors)\n            self.inner.task_done()\n            self.some_task_done.notify_all()\n\n    def _mark_in_progress(self, node_id: UniqueId, is_microbatch: bool = False) -> None:\n        \"\"\"Mark the node as 'in progress'.\n\n        Callers must hold the lock.\n\n        :param str node_id: The node ID to mark as in progress.\n        :param bool is_microbatch: Whether the node is a microbatch model.\n        \"\"\"\n        self.queued.remove(node_id)\n        self.in_progress.add(node_id)\n        if is_microbatch:\n            self.in_progress_microbatch.add(node_id)\n\n    def join(self) -> None:\n        \"\"\"Join the queue. Blocks until all tasks are marked as done.\n\n        Make sure not to call this before the queue reports that it is empty.\n        \"\"\"\n        self.inner.join()\n\n    def wait_until_something_was_done(self) -> int:\n        \"\"\"Block until a task is done, then return the number of unfinished\n        tasks.\n        \"\"\"\n        with self.lock:\n            self.some_task_done.wait()\n            return self.inner.unfinished_tasks\n"
  },
  {
    "path": "core/dbt/graph/selector.py",
    "content": "from typing import Any, Dict, List, Optional, Set, Tuple\n\nfrom dbt import selected_resources\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.contracts.graph.nodes import GraphMemberNode\nfrom dbt.contracts.state import PreviousState\nfrom dbt.events.types import NoNodesForSelectionCriteria, SelectorReportInvalidSelector\nfrom dbt.exceptions import DbtInternalError, InvalidSelectorError\nfrom dbt.node_types import NodeType\nfrom dbt_common.events.functions import fire_event, warn_or_error\n\nfrom .graph import Graph, UniqueId\nfrom .queue import GraphQueue\nfrom .selector_methods import MethodManager, MethodName\nfrom .selector_spec import IndirectSelection, SelectionCriteria, SelectionSpec\n\n\ndef get_package_names(nodes):\n    return set([node.split(\".\")[1] for node in nodes])\n\n\ndef can_select_indirectly(node):\n    \"\"\"If a node is not selected itself, but its parent(s) are, it may qualify\n    for indirect selection.\n    Today, only Test nodes can be indirectly selected. In the future,\n    other node types or invocation flags might qualify.\n    \"\"\"\n    if node.resource_type == NodeType.Test:\n        return True\n    elif node.resource_type == NodeType.Unit:\n        return True\n    else:\n        return False\n\n\nclass NodeSelector(MethodManager):\n    \"\"\"The node selector is aware of the graph and manifest\"\"\"\n\n    def __init__(\n        self,\n        graph: Graph,\n        manifest: Manifest,\n        previous_state: Optional[PreviousState] = None,\n        include_empty_nodes: bool = False,\n        selectors: Optional[Dict[str, Any]] = None,\n    ) -> None:\n        super().__init__(manifest, previous_state)\n        self.full_graph: Graph = graph\n        self.include_empty_nodes: bool = include_empty_nodes\n        self._selectors: Optional[Dict[str, Any]] = selectors\n\n        # build a subgraph containing only non-empty, enabled nodes and enabled\n        # sources.\n        graph_members = {\n            unique_id for unique_id in self.full_graph.nodes() if self._is_graph_member(unique_id)\n        }\n        self.graph = self.full_graph.subgraph(graph_members)\n\n    def get_method(self, method: MethodName, method_arguments: List[str], **kwargs: Any):\n        return super().get_method(\n            method,\n            method_arguments,\n            selectors=self._selectors,\n            get_selected_callback=self.get_selected,\n        )\n\n    def select_included(\n        self,\n        included_nodes: Set[UniqueId],\n        spec: SelectionCriteria,\n    ) -> Set[UniqueId]:\n        \"\"\"Select the explicitly included nodes, using the given spec. Return\n        the selected set of unique IDs.\n        \"\"\"\n        method = self.get_method(\n            spec.method,\n            spec.method_arguments,\n            selectors=self._selectors,\n            get_selected_callback=self.get_selected,\n        )\n        return set(method.search(included_nodes, spec.value))\n\n    def get_nodes_from_criteria(\n        self, spec: SelectionCriteria\n    ) -> Tuple[Set[UniqueId], Set[UniqueId]]:\n        \"\"\"Get all nodes specified by the single selection criteria.\n\n        - collect the directly included nodes\n        - find their specified relatives\n        - perform any selector-specific expansion\n        \"\"\"\n\n        nodes = self.graph.nodes()\n        try:\n            collected = self.select_included(nodes, spec)\n        except InvalidSelectorError:\n            valid_selectors = \", \".join(self.SELECTOR_METHODS)\n            fire_event(\n                SelectorReportInvalidSelector(\n                    valid_selectors=valid_selectors, spec_method=spec.method, raw_spec=spec.raw\n                )\n            )\n            return set(), set()\n\n        neighbors = self.collect_specified_neighbors(spec, collected)\n        selected = collected | neighbors\n\n        # if --indirect-selection EMPTY, do not expand to adjacent tests\n        if spec.indirect_selection == IndirectSelection.Empty:\n            return selected, set()\n        else:\n            direct_nodes, indirect_nodes = self.expand_selection(\n                selected=selected, indirect_selection=spec.indirect_selection\n            )\n            return direct_nodes, indirect_nodes\n\n    def collect_specified_neighbors(\n        self, spec: SelectionCriteria, selected: Set[UniqueId]\n    ) -> Set[UniqueId]:\n        \"\"\"Given the set of models selected by the explicit part of the\n        selector (like \"tag:foo\"), apply the modifiers on the spec (\"+\"/\"@\").\n        Return the set of additional nodes that should be collected (which may\n        overlap with the selected set).\n        \"\"\"\n        additional: Set[UniqueId] = set()\n        if spec.childrens_parents:\n            additional.update(self.graph.select_childrens_parents(selected))\n\n        if spec.parents:\n            depth = spec.parents_depth\n            additional.update(self.graph.select_parents(selected, depth))\n\n        if spec.children:\n            depth = spec.children_depth\n            additional.update(self.graph.select_children(selected, depth))\n        return additional\n\n    def select_nodes_recursively(\n        self, spec: SelectionSpec, warn_on_no_nodes: bool = True\n    ) -> Tuple[Set[UniqueId], Set[UniqueId]]:\n        \"\"\"If the spec is a composite spec (a union, difference, or intersection),\n        recurse into its selections and combine them. If the spec is a concrete\n        selection criteria, resolve that using the given graph.\n        \"\"\"\n        if isinstance(spec, SelectionCriteria):\n            direct_nodes, indirect_nodes = self.get_nodes_from_criteria(spec)\n        else:\n            bundles = [\n                self.select_nodes_recursively(spec=component, warn_on_no_nodes=warn_on_no_nodes)\n                for component in spec.components\n            ]\n\n            direct_sets = []\n            indirect_sets = []\n\n            for direct, indirect in bundles:\n                direct_sets.append(direct)\n                indirect_sets.append(direct | indirect)\n\n            initial_direct = spec.combined(direct_sets)\n            indirect_nodes = spec.combined(indirect_sets)\n\n            direct_nodes = self.incorporate_indirect_nodes(\n                initial_direct, indirect_nodes, spec.indirect_selection\n            )\n\n            if spec.expect_exists and len(direct_nodes) == 0 and warn_on_no_nodes:\n                warn_or_error(NoNodesForSelectionCriteria(spec_raw=str(spec.raw)))\n\n        return direct_nodes, indirect_nodes\n\n    def select_nodes(\n        self, spec: SelectionSpec, warn_on_no_nodes: bool = True\n    ) -> Tuple[Set[UniqueId], Set[UniqueId]]:\n        \"\"\"Select the nodes in the graph according to the spec.\n\n        This is the main point of entry for turning a spec into a set of nodes:\n        - Recurse through spec, select by criteria, combine by set operation\n        - Return final (unfiltered) selection set\n        \"\"\"\n        direct_nodes, indirect_nodes = self.select_nodes_recursively(\n            spec=spec, warn_on_no_nodes=warn_on_no_nodes\n        )\n        indirect_only = indirect_nodes.difference(direct_nodes)\n        return direct_nodes, indirect_only\n\n    def _is_graph_member(self, unique_id: UniqueId) -> bool:\n        if unique_id in self.manifest.sources:\n            source = self.manifest.sources[unique_id]\n            return source.config.enabled\n        elif unique_id in self.manifest.exposures:\n            return True\n        elif unique_id in self.manifest.functions:\n            function = self.manifest.functions[unique_id]\n            return function.config.enabled\n        elif unique_id in self.manifest.metrics:\n            metric = self.manifest.metrics[unique_id]\n            return metric.config.enabled\n        elif unique_id in self.manifest.semantic_models:\n            semantic_model = self.manifest.semantic_models[unique_id]\n            return semantic_model.config.enabled\n        elif unique_id in self.manifest.unit_tests:\n            unit_test = self.manifest.unit_tests[unique_id]\n            return unit_test.config.enabled\n        elif unique_id in self.manifest.saved_queries:\n            saved_query = self.manifest.saved_queries[unique_id]\n            return saved_query.config.enabled\n        elif unique_id in self.manifest.exposures:\n            exposure = self.manifest.exposures[unique_id]\n            return exposure.config.enabled\n        else:\n            node = self.manifest.nodes[unique_id]\n            return node.config.enabled\n\n    def _is_empty_node(self, unique_id: UniqueId) -> bool:\n        if unique_id in self.manifest.nodes:\n            node = self.manifest.nodes[unique_id]\n            return node.empty\n        else:\n            return False\n\n    def node_is_match(self, node: GraphMemberNode) -> bool:\n        \"\"\"Determine if a node is a match for the selector. Non-match nodes\n        will be excluded from results during filtering.\n        \"\"\"\n        return True\n\n    def _is_match(self, unique_id: UniqueId) -> bool:\n        node: GraphMemberNode\n        if unique_id in self.manifest.nodes:\n            node = self.manifest.nodes[unique_id]\n        elif unique_id in self.manifest.sources:\n            node = self.manifest.sources[unique_id]\n        elif unique_id in self.manifest.exposures:\n            node = self.manifest.exposures[unique_id]\n        elif unique_id in self.manifest.functions:\n            node = self.manifest.functions[unique_id]\n        elif unique_id in self.manifest.metrics:\n            node = self.manifest.metrics[unique_id]\n        elif unique_id in self.manifest.semantic_models:\n            node = self.manifest.semantic_models[unique_id]\n        elif unique_id in self.manifest.unit_tests:\n            node = self.manifest.unit_tests[unique_id]\n        elif unique_id in self.manifest.saved_queries:\n            node = self.manifest.saved_queries[unique_id]\n        else:\n            raise DbtInternalError(f\"Node {unique_id} not found in the manifest!\")\n        return self.node_is_match(node)\n\n    def filter_selection(self, selected: Set[UniqueId]) -> Set[UniqueId]:\n        \"\"\"Return the subset of selected nodes that is a match for this\n        selector.\n        \"\"\"\n        return {\n            unique_id\n            for unique_id in selected\n            if self._is_match(unique_id)\n            and (self.include_empty_nodes or not self._is_empty_node(unique_id))\n        }\n\n    def expand_selection(\n        self,\n        selected: Set[UniqueId],\n        indirect_selection: IndirectSelection = IndirectSelection.Eager,\n    ) -> Tuple[Set[UniqueId], Set[UniqueId]]:\n        # Test selection by default expands to include an implicitly/indirectly selected tests.\n        # `dbt test -m model_a` also includes tests that directly depend on `model_a`.\n        # Expansion has four modes, EAGER, CAUTIOUS and BUILDABLE, EMPTY.\n        #\n        # EAGER mode: If ANY parent is selected, select the test.\n        #\n        # CAUTIOUS mode:\n        #  - If ALL parents are selected, select the test.\n        #  - If ANY parent is missing, return it separately. We'll keep it around\n        #    for later and see if its other parents show up.\n        #\n        # BUILDABLE mode:\n        #  - If ALL parents are selected, or the parents of the test are themselves parents of the selected, select the test.\n        #  - If ANY parent is missing, return it separately. We'll keep it around\n        #    for later and see if its other parents show up.\n        #\n        # EMPTY mode: Only select the given node and ignore attached nodes (i.e. ignore tests attached to a model)\n        #\n        # Users can opt out of inclusive EAGER mode by passing --indirect-selection cautious\n        # CLI argument or by specifying `indirect_selection: true` in a yaml selector\n\n        direct_nodes = set(selected)\n        indirect_nodes = set()\n        selected_and_parents = set()\n        if indirect_selection == IndirectSelection.Buildable:\n            selected_and_parents = selected.union(self.graph.select_parents(selected)).union(\n                self.manifest.sources\n            )\n\n        for unique_id in self.graph.select_successors(selected):\n            if unique_id in self.manifest.nodes or unique_id in self.manifest.unit_tests:\n                if unique_id in self.manifest.nodes:\n                    node = self.manifest.nodes[unique_id]\n                elif unique_id in self.manifest.unit_tests:\n                    node = self.manifest.unit_tests[unique_id]  # type: ignore\n                # Test nodes that are not selected themselves, but whose parents are selected.\n                # (Does not include unit tests because they can only have one parent.)\n                if can_select_indirectly(node):\n                    # should we add it in directly?\n                    if indirect_selection == IndirectSelection.Eager or set(\n                        node.depends_on_nodes\n                    ) <= set(selected):\n                        direct_nodes.add(unique_id)\n                    elif indirect_selection == IndirectSelection.Buildable and set(\n                        node.depends_on_nodes\n                    ) <= set(selected_and_parents):\n                        direct_nodes.add(unique_id)\n                    elif indirect_selection == IndirectSelection.Empty:\n                        pass\n                    else:\n                        indirect_nodes.add(unique_id)\n\n        return direct_nodes, indirect_nodes\n\n    def incorporate_indirect_nodes(\n        self,\n        direct_nodes: Set[UniqueId],\n        indirect_nodes: Set[UniqueId] = set(),\n        indirect_selection: IndirectSelection = IndirectSelection.Eager,\n    ) -> Set[UniqueId]:\n        # Check tests previously selected indirectly to see if ALL their\n        # parents are now present.\n\n        # performance: if identical, skip the processing below\n        if set(direct_nodes) == set(indirect_nodes):\n            return direct_nodes\n\n        selected = set(direct_nodes)\n\n        if indirect_selection == IndirectSelection.Cautious:\n            for unique_id in indirect_nodes:\n                if unique_id in self.manifest.nodes:\n                    node = self.manifest.nodes[unique_id]\n                    if set(node.depends_on_nodes) <= set(selected):\n                        selected.add(unique_id)\n        elif indirect_selection == IndirectSelection.Buildable:\n            selected_and_parents = selected.union(self.graph.select_parents(selected))\n            for unique_id in indirect_nodes:\n                if unique_id in self.manifest.nodes:\n                    node = self.manifest.nodes[unique_id]\n                    if set(node.depends_on_nodes) <= set(selected_and_parents):\n                        selected.add(unique_id)\n\n        return selected\n\n    def get_selected(self, spec: SelectionSpec, warn_on_no_nodes: bool = True) -> Set[UniqueId]:\n        \"\"\"get_selected runs through the node selection process:\n\n        - node selection. Based on the include/exclude sets, the set\n            of matched unique IDs is returned\n            - includes direct + indirect selection (for tests)\n        - filtering:\n            - selectors can filter the nodes after all of them have been\n              selected\n        \"\"\"\n        selected_nodes, indirect_only = self.select_nodes(\n            spec=spec, warn_on_no_nodes=warn_on_no_nodes\n        )\n        filtered_nodes = self.filter_selection(selected_nodes)\n\n        return filtered_nodes\n\n    def get_graph_queue(self, spec: SelectionSpec, preserve_edges: bool = True) -> GraphQueue:\n        \"\"\"Returns a queue over nodes in the graph that tracks progress of\n        dependencies.\n        \"\"\"\n        # Filtering happens in get_selected\n        selected_nodes = self.get_selected(spec)\n        # Save to global variable\n        selected_resources.set_selected_resources(selected_nodes)\n        # Construct a new graph using the selected_nodes\n        new_graph = self.full_graph.get_subset_graph(selected_nodes)\n        # should we give a way here for consumers to mutate the graph?\n        return GraphQueue(new_graph.graph, self.manifest, selected_nodes, preserve_edges)\n\n\nclass ResourceTypeSelector(NodeSelector):\n    def __init__(\n        self,\n        graph: Graph,\n        manifest: Manifest,\n        previous_state: Optional[PreviousState],\n        resource_types: List[NodeType],\n        include_empty_nodes: bool = False,\n        selectors: Optional[Dict[str, Any]] = None,\n    ) -> None:\n        super().__init__(\n            graph=graph,\n            manifest=manifest,\n            previous_state=previous_state,\n            include_empty_nodes=include_empty_nodes,\n            selectors=selectors,\n        )\n        self.resource_types: Set[NodeType] = set(resource_types)\n\n    def node_is_match(self, node):\n        return node.resource_type in self.resource_types\n"
  },
  {
    "path": "core/dbt/graph/selector_methods.py",
    "content": "import abc\nfrom fnmatch import fnmatch\nfrom itertools import chain\nfrom pathlib import Path\nfrom typing import (\n    TYPE_CHECKING,\n    Any,\n    Callable,\n    Dict,\n    Iterator,\n    List,\n    Optional,\n    Set,\n    Tuple,\n    Type,\n    Union,\n)\n\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.contracts.graph.nodes import (\n    Exposure,\n    FunctionNode,\n    GenericTestNode,\n    ManifestNode,\n    Metric,\n    ModelNode,\n    ResultNode,\n    SavedQuery,\n    SemanticModel,\n    SingularTestNode,\n    SourceDefinition,\n    UnitTestDefinition,\n)\nfrom dbt.contracts.graph.unparsed import UnparsedVersion\nfrom dbt.contracts.state import PreviousState\nfrom dbt.exceptions import DbtSelectorsError\nfrom dbt.node_types import NodeType\nfrom dbt_common.dataclass_schema import StrEnum\nfrom dbt_common.events.contextvars import get_project_root\nfrom dbt_common.exceptions import CompilationError, DbtInternalError, DbtRuntimeError\nfrom dbt_common.exceptions import RecursionError as DbtRecursionError\n\nfrom .graph import UniqueId\n\nif TYPE_CHECKING:\n    from .selector_spec import SelectionSpec\n\nSELECTOR_GLOB = \"*\"\nSELECTOR_DELIMITER = \":\"\n\n\nclass MethodName(StrEnum):\n    FQN = \"fqn\"\n    Tag = \"tag\"\n    Group = \"group\"\n    Access = \"access\"\n    Source = \"source\"\n    Path = \"path\"\n    File = \"file\"\n    Package = \"package\"\n    Config = \"config\"\n    TestName = \"test_name\"\n    TestType = \"test_type\"\n    ResourceType = \"resource_type\"\n    State = \"state\"\n    Exposure = \"exposure\"\n    Metric = \"metric\"\n    Result = \"result\"\n    SourceStatus = \"source_status\"\n    Version = \"version\"\n    SemanticModel = \"semantic_model\"\n    SavedQuery = \"saved_query\"\n    UnitTest = \"unit_test\"\n    Selector = \"selector\"\n\n\ndef is_selected_node(fqn: List[str], node_selector: str, is_versioned: bool) -> bool:\n    # If qualified_name exactly matches model name (fqn's leaf), return True\n    if is_versioned:\n        flat_node_selector = node_selector.split(\".\")\n        if fqn[-2] == node_selector:\n            return True\n        # If this is a versioned model, then the last two segments should be allowed to exactly match on either the '.' or '_' delimiter\n        elif \"_\".join(fqn[-2:]) == \"_\".join(flat_node_selector[-2:]):\n            return True\n    else:\n        if fqn[-1] == node_selector:\n            return True\n    # Flatten node parts. Dots in model names act as namespace separators\n    flat_fqn = [item for segment in fqn for item in segment.split(\".\")]\n    # Selector components cannot be more than fqn's\n    if len(flat_fqn) < len(node_selector.split(\".\")):\n        return False\n\n    slurp_from_ix: Optional[int] = None\n    for i, selector_part in enumerate(node_selector.split(\".\")):\n        if any(wildcard in selector_part for wildcard in (\"*\", \"?\", \"[\", \"]\")):\n            slurp_from_ix = i\n            break\n        elif flat_fqn[i] == selector_part:\n            continue\n        else:\n            return False\n\n    if slurp_from_ix is not None:\n        # If we have a wildcard, we need to make sure that the selector matches the\n        # rest of the fqn, this is 100% backwards compatible with the old behavior of\n        # encountering a wildcard but more expressive in naturally allowing you to\n        # match the rest of the fqn with more advanced patterns\n        return fnmatch(\n            \".\".join(flat_fqn[slurp_from_ix:]),\n            \".\".join(node_selector.split(\".\")[slurp_from_ix:]),\n        )\n\n    # if we get all the way down here, then the node is a match\n    return True\n\n\nSelectorTarget = Union[\n    SourceDefinition, ManifestNode, Exposure, Metric, SemanticModel, UnitTestDefinition, SavedQuery\n]\n\n\nclass SelectorMethod(metaclass=abc.ABCMeta):\n    def __init__(\n        self,\n        manifest: Manifest,\n        previous_state: Optional[PreviousState],\n        arguments: List[str],\n        **kwargs: Any,\n    ) -> None:\n        self.manifest: Manifest = manifest\n        self.previous_state = previous_state\n        self.arguments: List[str] = arguments\n\n    def parsed_nodes(\n        self, included_nodes: Set[UniqueId]\n    ) -> Iterator[Tuple[UniqueId, ManifestNode]]:\n\n        for key, node in self.manifest.nodes.items():\n            unique_id = UniqueId(key)\n            if unique_id not in included_nodes:\n                continue\n            yield unique_id, node\n\n    def source_nodes(\n        self, included_nodes: Set[UniqueId]\n    ) -> Iterator[Tuple[UniqueId, SourceDefinition]]:\n\n        for key, source in self.manifest.sources.items():\n            unique_id = UniqueId(key)\n            if unique_id not in included_nodes:\n                continue\n            yield unique_id, source\n\n    def exposure_nodes(self, included_nodes: Set[UniqueId]) -> Iterator[Tuple[UniqueId, Exposure]]:\n\n        for key, exposure in self.manifest.exposures.items():\n            unique_id = UniqueId(key)\n            if unique_id not in included_nodes:\n                continue\n            yield unique_id, exposure\n\n    def metric_nodes(self, included_nodes: Set[UniqueId]) -> Iterator[Tuple[UniqueId, Metric]]:\n\n        for key, metric in self.manifest.metrics.items():\n            unique_id = UniqueId(key)\n            if unique_id not in included_nodes:\n                continue\n            yield unique_id, metric\n\n    def unit_tests(\n        self, included_nodes: Set[UniqueId]\n    ) -> Iterator[Tuple[UniqueId, UnitTestDefinition]]:\n        for unique_id, unit_test in self.manifest.unit_tests.items():\n            unique_id = UniqueId(unique_id)\n            if unique_id not in included_nodes:\n                continue\n            yield unique_id, unit_test\n\n    def parsed_and_unit_nodes(self, included_nodes: Set[UniqueId]):\n        yield from chain(\n            self.parsed_nodes(included_nodes),\n            self.unit_tests(included_nodes),\n        )\n\n    def semantic_model_nodes(\n        self, included_nodes: Set[UniqueId]\n    ) -> Iterator[Tuple[UniqueId, SemanticModel]]:\n\n        for key, semantic_model in self.manifest.semantic_models.items():\n            unique_id = UniqueId(key)\n            if unique_id not in included_nodes:\n                continue\n            yield unique_id, semantic_model\n\n    def saved_query_nodes(\n        self, included_nodes: Set[UniqueId]\n    ) -> Iterator[Tuple[UniqueId, SavedQuery]]:\n\n        for key, saved_query in self.manifest.saved_queries.items():\n            unique_id = UniqueId(key)\n            if unique_id not in included_nodes:\n                continue\n            yield unique_id, saved_query\n\n    def function_nodes(\n        self, included_nodes: Set[UniqueId]\n    ) -> Iterator[Tuple[UniqueId, FunctionNode]]:\n        for key, function in self.manifest.functions.items():\n            unique_id = UniqueId(key)\n            if unique_id not in included_nodes:\n                continue\n            yield unique_id, function\n\n    def all_nodes(\n        self, included_nodes: Set[UniqueId]\n    ) -> Iterator[Tuple[UniqueId, SelectorTarget]]:\n        yield from chain(\n            self.parsed_nodes(included_nodes),\n            self.source_nodes(included_nodes),\n            self.exposure_nodes(included_nodes),\n            self.metric_nodes(included_nodes),\n            self.unit_tests(included_nodes),\n            self.semantic_model_nodes(included_nodes),\n            self.saved_query_nodes(included_nodes),\n            self.function_nodes(included_nodes),\n        )\n\n    def configurable_nodes(\n        self, included_nodes: Set[UniqueId]\n    ) -> Iterator[Tuple[UniqueId, ResultNode]]:\n        yield from chain(self.parsed_nodes(included_nodes), self.source_nodes(included_nodes))\n\n    def non_source_nodes(\n        self,\n        included_nodes: Set[UniqueId],\n    ) -> Iterator[Tuple[UniqueId, Union[Exposure, ManifestNode, Metric]]]:\n        yield from chain(\n            self.parsed_nodes(included_nodes),\n            self.exposure_nodes(included_nodes),\n            self.metric_nodes(included_nodes),\n            self.unit_tests(included_nodes),\n            self.semantic_model_nodes(included_nodes),\n            self.saved_query_nodes(included_nodes),\n            self.function_nodes(included_nodes),\n        )\n\n    def groupable_nodes(\n        self,\n        included_nodes: Set[UniqueId],\n    ) -> Iterator[Tuple[UniqueId, Union[ManifestNode, Metric]]]:\n        yield from chain(\n            self.parsed_nodes(included_nodes),\n            self.metric_nodes(included_nodes),\n        )\n\n    @abc.abstractmethod\n    def search(\n        self,\n        included_nodes: Set[UniqueId],\n        selector: str,\n    ) -> Iterator[UniqueId]:\n        raise NotImplementedError(\"subclasses should implement this\")\n\n\nclass QualifiedNameSelectorMethod(SelectorMethod):\n    def node_is_match(self, qualified_name: str, fqn: List[str], is_versioned: bool) -> bool:\n        \"\"\"Determine if a qualified name matches an fqn for all package\n        names in the graph.\n\n        :param str qualified_name: The qualified name to match the nodes with\n        :param List[str] fqn: The node's fully qualified name in the graph.\n        \"\"\"\n        unscoped_fqn = fqn[1:]\n\n        if is_selected_node(fqn, qualified_name, is_versioned):\n            return True\n        # Match nodes across different packages\n        elif is_selected_node(unscoped_fqn, qualified_name, is_versioned):\n            return True\n\n        return False\n\n    def search(self, included_nodes: Set[UniqueId], selector: str) -> Iterator[UniqueId]:\n        \"\"\"Yield all nodes in the graph that match the selector.\n\n        :param str selector: The selector or node name\n        \"\"\"\n        non_source_nodes = list(self.non_source_nodes(included_nodes))\n        for unique_id, node in non_source_nodes:\n            if self.node_is_match(selector, node.fqn, node.is_versioned):\n                yield unique_id\n\n\nclass TagSelectorMethod(SelectorMethod):\n    def search(self, included_nodes: Set[UniqueId], selector: str) -> Iterator[UniqueId]:\n        \"\"\"yields nodes from included that have the specified tag\"\"\"\n        for unique_id, node in self.all_nodes(included_nodes):\n            if hasattr(node, \"tags\") and any(fnmatch(tag, selector) for tag in node.tags):\n                yield unique_id\n\n\nclass GroupSelectorMethod(SelectorMethod):\n    def search(self, included_nodes: Set[UniqueId], selector: str) -> Iterator[UniqueId]:\n        \"\"\"yields nodes from included in the specified group\"\"\"\n        for unique_id, node in self.groupable_nodes(included_nodes):\n            node_group = node.config.get(\"group\")\n            if node_group and fnmatch(node_group, selector):\n                yield unique_id\n\n\nclass AccessSelectorMethod(SelectorMethod):\n    def search(self, included_nodes: Set[UniqueId], selector: str) -> Iterator[UniqueId]:\n        \"\"\"yields model nodes matching the specified access level\"\"\"\n        for unique_id, node in self.parsed_nodes(included_nodes):\n            if not isinstance(node, ModelNode):\n                continue\n            if selector == node.access:\n                yield unique_id\n\n\nclass SourceSelectorMethod(SelectorMethod):\n    def search(self, included_nodes: Set[UniqueId], selector: str) -> Iterator[UniqueId]:\n        \"\"\"yields nodes from included are the specified source.\"\"\"\n        parts = selector.split(\".\")\n        target_package = SELECTOR_GLOB\n        if len(parts) == 1:\n            target_source, target_table = parts[0], SELECTOR_GLOB\n        elif len(parts) == 2:\n            target_source, target_table = parts\n        elif len(parts) == 3:\n            target_package, target_source, target_table = parts\n        else:  # len(parts) > 3 or len(parts) == 0\n            msg = (\n                'Invalid source selector value \"{}\". Sources must be of the '\n                \"form `${{source_name}}`, \"\n                \"`${{source_name}}.${{target_name}}`, or \"\n                \"`${{package_name}}.${{source_name}}.${{target_name}}\"\n            ).format(selector)\n            raise DbtRuntimeError(msg)\n\n        for unique_id, node in self.source_nodes(included_nodes):\n            if not fnmatch(node.package_name, target_package):\n                continue\n            if not fnmatch(node.source_name, target_source):\n                continue\n            if not fnmatch(node.name, target_table):\n                continue\n            yield unique_id\n\n\nclass ExposureSelectorMethod(SelectorMethod):\n    def search(self, included_nodes: Set[UniqueId], selector: str) -> Iterator[UniqueId]:\n        parts = selector.split(\".\")\n        target_package = SELECTOR_GLOB\n        if len(parts) == 1:\n            target_name = parts[0]\n        elif len(parts) == 2:\n            target_package, target_name = parts\n        else:\n            msg = (\n                'Invalid exposure selector value \"{}\". Exposures must be of '\n                \"the form ${{exposure_name}} or \"\n                \"${{exposure_package.exposure_name}}\"\n            ).format(selector)\n            raise DbtRuntimeError(msg)\n\n        for unique_id, node in self.exposure_nodes(included_nodes):\n            if not fnmatch(node.package_name, target_package):\n                continue\n            if not fnmatch(node.name, target_name):\n                continue\n\n            yield unique_id\n\n\nclass MetricSelectorMethod(SelectorMethod):\n    def search(self, included_nodes: Set[UniqueId], selector: str) -> Iterator[UniqueId]:\n        parts = selector.split(\".\")\n        target_package = SELECTOR_GLOB\n        if len(parts) == 1:\n            target_name = parts[0]\n        elif len(parts) == 2:\n            target_package, target_name = parts\n        else:\n            msg = (\n                'Invalid metric selector value \"{}\". Metrics must be of '\n                \"the form ${{metric_name}} or \"\n                \"${{metric_package.metric_name}}\"\n            ).format(selector)\n            raise DbtRuntimeError(msg)\n\n        for unique_id, node in self.metric_nodes(included_nodes):\n            if not fnmatch(node.package_name, target_package):\n                continue\n            if not fnmatch(node.name, target_name):\n                continue\n\n            yield unique_id\n\n\nclass SemanticModelSelectorMethod(SelectorMethod):\n    def search(self, included_nodes: Set[UniqueId], selector: str) -> Iterator[UniqueId]:\n        parts = selector.split(\".\")\n        target_package = SELECTOR_GLOB\n        if len(parts) == 1:\n            target_name = parts[0]\n        elif len(parts) == 2:\n            target_package, target_name = parts\n        else:\n            msg = (\n                'Invalid semantic model selector value \"{}\". Semantic models must be of '\n                \"the form ${{semantic_model_name}} or \"\n                \"${{semantic_model_package.semantic_model_name}}\"\n            ).format(selector)\n            raise DbtRuntimeError(msg)\n\n        for unique_id, node in self.semantic_model_nodes(included_nodes):\n            if not fnmatch(node.package_name, target_package):\n                continue\n            if not fnmatch(node.name, target_name):\n                continue\n\n            yield unique_id\n\n\nclass SavedQuerySelectorMethod(SelectorMethod):\n    def search(self, included_nodes: Set[UniqueId], selector: str) -> Iterator[UniqueId]:\n        parts = selector.split(\".\")\n        target_package = SELECTOR_GLOB\n        if len(parts) == 1:\n            target_name = parts[0]\n        elif len(parts) == 2:\n            target_package, target_name = parts\n        else:\n            msg = (\n                'Invalid saved query selector value \"{}\". Saved queries must be of '\n                \"the form ${{saved_query_name}} or \"\n                \"${{saved_query_package.saved_query_name}}\"\n            ).format(selector)\n            raise DbtRuntimeError(msg)\n\n        for unique_id, node in self.saved_query_nodes(included_nodes):\n            if not fnmatch(node.package_name, target_package):\n                continue\n            if not fnmatch(node.name, target_name):\n                continue\n\n            yield unique_id\n\n\nclass UnitTestSelectorMethod(SelectorMethod):\n    def search(self, included_nodes: Set[UniqueId], selector: str) -> Iterator[UniqueId]:\n        parts = selector.split(\".\")\n        target_package = SELECTOR_GLOB\n        if len(parts) == 1:\n            target_name = parts[0]\n        elif len(parts) == 2:\n            target_package, target_name = parts\n        else:\n            msg = (\n                'Invalid unit test selector value \"{}\". Saved queries must be of '\n                \"the form ${{unit_test_name}} or \"\n                \"${{unit_test_package_name.unit_test_name}}\"\n            ).format(selector)\n            raise DbtRuntimeError(msg)\n\n        for unique_id, node in self.unit_tests(included_nodes):\n            if not fnmatch(node.package_name, target_package):\n                continue\n            if not fnmatch(node.name, target_name):\n                continue\n\n            yield unique_id\n\n\nclass PathSelectorMethod(SelectorMethod):\n    def search(self, included_nodes: Set[UniqueId], selector: str) -> Iterator[UniqueId]:\n        \"\"\"Yields nodes from included that match the given path.\"\"\"\n        # get project root from contextvar\n        project_root = get_project_root()\n        if project_root:\n            root = Path(project_root)\n        else:\n            root = Path.cwd()\n        paths = set(p.relative_to(root) for p in root.glob(selector))\n        for unique_id, node in self.all_nodes(included_nodes):\n            ofp = Path(node.original_file_path)\n            if ofp in paths:\n                yield unique_id\n            if hasattr(node, \"patch_path\") and node.patch_path:  # type: ignore\n                pfp = node.patch_path.split(\"://\")[1]  # type: ignore\n                ymlfp = Path(pfp)\n                if ymlfp in paths:\n                    yield unique_id\n            if any(parent in paths for parent in ofp.parents):\n                yield unique_id\n\n\nclass FileSelectorMethod(SelectorMethod):\n    def search(self, included_nodes: Set[UniqueId], selector: str) -> Iterator[UniqueId]:\n        \"\"\"Yields nodes from included that match the given file name.\"\"\"\n        for unique_id, node in self.all_nodes(included_nodes):\n            if fnmatch(Path(node.original_file_path).name, selector):\n                yield unique_id\n            elif fnmatch(Path(node.original_file_path).stem, selector):\n                yield unique_id\n\n\nclass PackageSelectorMethod(SelectorMethod):\n    def search(self, included_nodes: Set[UniqueId], selector: str) -> Iterator[UniqueId]:\n        \"\"\"Yields nodes from included that have the specified package\"\"\"\n        # `this` is an alias for the current dbt project name\n        if selector == \"this\" and self.manifest.metadata.project_name is not None:\n            selector = self.manifest.metadata.project_name\n\n        for unique_id, node in self.all_nodes(included_nodes):\n            if fnmatch(node.package_name, selector):\n                yield unique_id\n\n\ndef _getattr_descend(obj: Any, attrs: List[str]) -> Any:\n    value = obj\n    for attr in attrs:\n        try:\n            value = getattr(value, attr)\n        except AttributeError:\n            # if it implements getitem (dict, list, ...), use that. On failure,\n            # raise an attribute error instead of the KeyError, TypeError, etc.\n            # that arbitrary getitem calls might raise\n            try:\n                value = value[attr]\n            except Exception as exc:\n                raise AttributeError(f\"'{type(value)}' object has no attribute '{attr}'\") from exc\n    return value\n\n\nclass CaseInsensitive(str):\n    def __eq__(self, other):\n        if isinstance(other, str):\n            return self.upper() == other.upper()\n        else:\n            return self.upper() == other\n\n\nclass ConfigSelectorMethod(SelectorMethod):\n    def search(\n        self,\n        included_nodes: Set[UniqueId],\n        selector: Any,\n    ) -> Iterator[UniqueId]:\n        parts = self.arguments\n        # special case: if the user wanted to compare test severity,\n        # make the comparison case-insensitive\n        if parts == [\"severity\"]:\n            selector = CaseInsensitive(selector)\n\n        # search sources is kind of useless now source configs only have\n        # 'enabled', which you can't really filter on anyway, but maybe we'll\n        # add more someday, so search them anyway.\n        for unique_id, node in self.configurable_nodes(included_nodes):\n            try:\n                value = _getattr_descend(node.config, parts)\n            except AttributeError:\n                continue\n            else:\n                if isinstance(value, list):\n                    if (\n                        (selector in value)\n                        or (CaseInsensitive(selector) == \"true\" and True in value)\n                        or (CaseInsensitive(selector) == \"false\" and False in value)\n                    ):\n                        yield unique_id\n                else:\n                    if (\n                        (selector == value)\n                        or (CaseInsensitive(selector) == \"true\" and value is True)\n                        or (CaseInsensitive(selector) == \"false\")\n                        and value is False\n                    ):\n                        yield unique_id\n\n\nclass ResourceTypeSelectorMethod(SelectorMethod):\n    def search(self, included_nodes: Set[UniqueId], selector: str) -> Iterator[UniqueId]:\n        try:\n            resource_type = NodeType(selector)\n        except ValueError as exc:\n            raise DbtRuntimeError(f'Invalid resource_type selector \"{selector}\"') from exc\n        for unique_id, node in self.all_nodes(included_nodes):\n            if node.resource_type == resource_type:\n                yield unique_id\n\n\nclass TestNameSelectorMethod(SelectorMethod):\n    __test__ = False\n\n    def search(self, included_nodes: Set[UniqueId], selector: str) -> Iterator[UniqueId]:\n        for unique_id, node in self.parsed_and_unit_nodes(included_nodes):\n            if node.resource_type == NodeType.Test and hasattr(node, \"test_metadata\"):\n                if fnmatch(node.test_metadata.name, selector):  # type: ignore[union-attr]\n                    yield unique_id\n            elif node.resource_type == NodeType.Unit:\n                if fnmatch(node.name, selector):\n                    yield unique_id\n\n\nclass TestTypeSelectorMethod(SelectorMethod):\n    __test__ = False\n\n    def search(self, included_nodes: Set[UniqueId], selector: str) -> Iterator[UniqueId]:\n        search_types: List[Any]\n        # continue supporting 'schema' + 'data' for backwards compatibility\n        if selector in (\"generic\", \"schema\"):\n            search_types = [GenericTestNode]\n        elif selector in (\"data\"):\n            search_types = [GenericTestNode, SingularTestNode]\n        elif selector in (\"singular\"):\n            search_types = [SingularTestNode]\n        elif selector in (\"unit\"):\n            search_types = [UnitTestDefinition]\n        else:\n            raise DbtRuntimeError(\n                f'Invalid test type selector {selector}: expected \"generic\", \"singular\", \"unit\", or \"data\"'\n            )\n\n        for unique_id, node in self.parsed_and_unit_nodes(included_nodes):\n            if isinstance(node, tuple(search_types)):\n                yield unique_id\n\n\nclass StateSelectorMethod(SelectorMethod):\n    def __init__(self, *args, **kwargs) -> None:\n        super().__init__(*args, **kwargs)\n        self.modified_macros: Optional[List[str]] = None\n\n    def _macros_modified(self) -> List[str]:\n        # we checked in the caller!\n        if self.previous_state is None or self.previous_state.manifest is None:\n            raise DbtInternalError(\"No comparison manifest in _macros_modified\")\n        old_macros = self.previous_state.manifest.macros\n        new_macros = self.manifest.macros\n\n        modified = []\n        for uid, macro in new_macros.items():\n            if uid in old_macros:\n                old_macro = old_macros[uid]\n                if macro.macro_sql != old_macro.macro_sql:\n                    modified.append(uid)\n            else:\n                modified.append(uid)\n\n        for uid, _ in old_macros.items():\n            if uid not in new_macros:\n                modified.append(uid)\n\n        return modified\n\n    def recursively_check_macros_modified(self, node, visited_macros):\n        if not hasattr(node, \"depends_on\"):\n            return False\n\n        for macro_uid in node.depends_on.macros:\n            if macro_uid in visited_macros:\n                continue\n            visited_macros.append(macro_uid)\n\n            # If macro_uid is None, it means the macro/test was removed but is still referenced.\n            # Raise a clear error to match the behavior of regular dbt run.\n            if macro_uid is None:\n                raise CompilationError(\n                    f\"Node '{node.name}' (in {node.original_file_path}) depends on a macro or test \"\n                    f\"that does not exist. This can happen when a macro or generic test is removed \"\n                    f\"but is still referenced. Check for typos and/or install package dependencies \"\n                    f\"with 'dbt deps'.\"\n                )\n\n            if macro_uid in self.modified_macros:\n                return True\n\n            # this macro hasn't been modified, but depends on other\n            # macros which each need to be tested for modification\n            macro_node = self.manifest.macros[macro_uid]\n            if len(macro_node.depends_on.macros) > 0:\n                upstream_macros_changed = self.recursively_check_macros_modified(\n                    macro_node, visited_macros\n                )\n                if upstream_macros_changed:\n                    return True\n                continue\n\n            # this macro hasn't been modified, but we haven't checked\n            # the other macros the node depends on, so keep looking\n            if len(node.depends_on.macros) > len(visited_macros):\n                continue\n\n        return False\n\n    def check_macros_modified(self, node):\n        # check if there are any changes in macros the first time\n        if self.modified_macros is None:\n            self.modified_macros = self._macros_modified()\n        # no macros have been modified, skip looping entirely\n        if not self.modified_macros:\n            return False\n        # recursively loop through upstream macros to see if any is modified\n        else:\n            visited_macros = []\n            return self.recursively_check_macros_modified(node, visited_macros)\n\n    # TODO check modifed_content and check_modified macro seems a bit redundent\n    def check_modified_content(\n        self, old: Optional[SelectorTarget], new: SelectorTarget, adapter_type: str\n    ) -> bool:\n        different_contents = False\n        if isinstance(\n            new,\n            (SourceDefinition, Exposure, Metric, SemanticModel, UnitTestDefinition, SavedQuery),\n        ):\n            # these all overwrite `same_contents`\n            different_contents = not new.same_contents(old)  # type: ignore\n        elif new:  # because we also pull in deleted/disabled nodes, this could be None\n            different_contents = not new.same_contents(old, adapter_type)  # type: ignore\n\n        upstream_macro_change = self.check_macros_modified(new)\n\n        check_modified_contract = False\n        if isinstance(old, ModelNode):\n            func = self.check_modified_contract(\"same_contract\", adapter_type)\n            check_modified_contract = func(old, new)\n\n        return different_contents or upstream_macro_change or check_modified_contract\n\n    def check_unmodified_content(\n        self, old: Optional[SelectorTarget], new: SelectorTarget, adapter_type: str\n    ) -> bool:\n        return not self.check_modified_content(old, new, adapter_type)\n\n    def check_modified_macros(self, old, new: SelectorTarget) -> bool:\n        return self.check_macros_modified(new)\n\n    @staticmethod\n    def check_modified_factory(\n        compare_method: str,\n    ) -> Callable[[Optional[SelectorTarget], SelectorTarget], bool]:\n        # get a function that compares two selector target based on compare method provided\n        def check_modified_things(old: Optional[SelectorTarget], new: SelectorTarget) -> bool:\n            if hasattr(new, compare_method):\n                # when old body does not exist or old and new are not the same\n                return not old or not getattr(new, compare_method)(old)  # type: ignore\n            else:\n                return False\n\n        return check_modified_things\n\n    @staticmethod\n    def check_modified_contract(\n        compare_method: str,\n        adapter_type: Optional[str],\n    ) -> Callable[[Optional[SelectorTarget], SelectorTarget], bool]:\n        # get a function that compares two selector target based on compare method provided\n        def check_modified_contract(old: Optional[SelectorTarget], new: SelectorTarget) -> bool:\n            if new is None and hasattr(old, compare_method + \"_removed\"):\n                return getattr(old, compare_method + \"_removed\")()\n            elif hasattr(new, compare_method):\n                # when old body does not exist or old and new are not the same\n                return not old or not getattr(new, compare_method)(old, adapter_type)  # type: ignore\n            else:\n                return False\n\n        return check_modified_contract\n\n    def search(self, included_nodes: Set[UniqueId], selector: str) -> Iterator[UniqueId]:\n        if self.previous_state is None or self.previous_state.manifest is None:\n            raise DbtRuntimeError(\"Got a state selector method, but no comparison manifest\")\n\n        adapter_type = self.manifest.metadata.adapter_type\n\n        state_checks = {\n            # it's new if there is no old version\n            \"new\": lambda old, new: old is None,\n            \"old\": lambda old, new: old is not None,\n            # use methods defined above to compare properties of old + new\n            \"modified\": self.check_modified_content,\n            \"unmodified\": self.check_unmodified_content,\n            \"modified.body\": self.check_modified_factory(\"same_body\"),\n            \"modified.configs\": self.check_modified_factory(\"same_config\"),\n            \"modified.persisted_descriptions\": self.check_modified_factory(\n                \"same_persisted_description\"\n            ),\n            \"modified.relation\": self.check_modified_factory(\"same_database_representation\"),\n            \"modified.macros\": self.check_modified_macros,\n            \"modified.contract\": self.check_modified_contract(\"same_contract\", adapter_type),\n        }\n        if selector in state_checks:\n            checker = state_checks[selector]\n        else:\n            raise DbtRuntimeError(\n                f'Got an invalid selector \"{selector}\", expected one of ' f'\"{list(state_checks)}\"'\n            )\n\n        manifest: Manifest = self.previous_state.manifest\n\n        keyword_args = {}  # initialize here to handle disabled node check below\n        for unique_id, node in self.all_nodes(included_nodes):\n            previous_node: Optional[SelectorTarget] = None\n\n            if unique_id in manifest.nodes:\n                previous_node = manifest.nodes[unique_id]\n            elif unique_id in manifest.sources:\n                previous_node = SourceDefinition.from_resource(manifest.sources[unique_id])\n            elif unique_id in manifest.exposures:\n                previous_node = Exposure.from_resource(manifest.exposures[unique_id])\n            elif unique_id in manifest.metrics:\n                previous_node = Metric.from_resource(manifest.metrics[unique_id])\n            elif unique_id in manifest.semantic_models:\n                previous_node = SemanticModel.from_resource(manifest.semantic_models[unique_id])\n            elif unique_id in manifest.unit_tests:\n                previous_node = UnitTestDefinition.from_resource(manifest.unit_tests[unique_id])\n            elif unique_id in manifest.saved_queries:\n                previous_node = SavedQuery.from_resource(manifest.saved_queries[unique_id])\n            elif unique_id in manifest.functions:\n                previous_node = FunctionNode.from_resource(manifest.functions[unique_id])\n\n            if checker.__name__ in [\n                \"same_contract\",\n                \"check_modified_content\",\n                \"check_unmodified_content\",\n            ]:\n                keyword_args[\"adapter_type\"] = adapter_type  # type: ignore\n\n            if checker(previous_node, node, **keyword_args):  # type: ignore\n                yield unique_id\n\n        # checkers that can handle removed nodes\n        if checker.__name__ in [\n            \"check_modified_contract\",\n            \"check_modified_content\",\n            \"check_unmodified_content\",\n        ]:\n            # ignore included_nodes, since those cannot contain removed nodes\n            for previous_unique_id, previous_node in manifest.nodes.items():\n                # detect removed (deleted, renamed, or disabled) nodes\n                removed_node = None\n                if previous_unique_id in self.manifest.disabled.keys():\n                    removed_node = self.manifest.disabled[previous_unique_id][0]\n                elif previous_unique_id not in self.manifest.nodes.keys():\n                    removed_node = previous_node\n\n                if removed_node:\n                    # do not yield -- removed nodes should never be selected for downstream execution\n                    # as they are not part of the current project's manifest.nodes\n                    checker(removed_node, None, **keyword_args)  # type: ignore\n\n\nclass ResultSelectorMethod(SelectorMethod):\n    def search(self, included_nodes: Set[UniqueId], selector: str) -> Iterator[UniqueId]:\n        if self.previous_state is None or self.previous_state.results is None:\n            raise DbtInternalError(\"No comparison run_results\")\n        matches = set(\n            result.unique_id for result in self.previous_state.results if result.status == selector\n        )\n        for unique_id, node in self.all_nodes(included_nodes):\n            if unique_id in matches:\n                yield unique_id\n\n\nclass SourceStatusSelectorMethod(SelectorMethod):\n    def search(self, included_nodes: Set[UniqueId], selector: str) -> Iterator[UniqueId]:\n\n        if self.previous_state is None or self.previous_state.sources is None:\n            raise DbtInternalError(\n                \"No previous state comparison freshness results in sources.json\"\n            )\n        elif self.previous_state.sources_current is None:\n            raise DbtInternalError(\"No current state comparison freshness results in sources.json\")\n\n        current_state_sources = {\n            result.unique_id: getattr(result, \"max_loaded_at\", 0)\n            for result in self.previous_state.sources_current.results\n            if hasattr(result, \"max_loaded_at\")\n        }\n\n        current_state_sources_runtime_error = {\n            result.unique_id\n            for result in self.previous_state.sources_current.results\n            if not hasattr(result, \"max_loaded_at\")\n        }\n\n        previous_state_sources = {\n            result.unique_id: getattr(result, \"max_loaded_at\", 0)\n            for result in self.previous_state.sources.results\n            if hasattr(result, \"max_loaded_at\")\n        }\n\n        previous_state_sources_runtime_error = {\n            result.unique_id\n            for result in self.previous_state.sources_current.results\n            if not hasattr(result, \"max_loaded_at\")\n        }\n\n        matches = set()\n        if selector == \"fresher\":\n            for unique_id in current_state_sources:\n                if unique_id not in previous_state_sources:\n                    matches.add(unique_id)\n                elif current_state_sources[unique_id] > previous_state_sources[unique_id]:\n                    matches.add(unique_id)\n\n            for unique_id in matches:\n                if (\n                    unique_id in previous_state_sources_runtime_error\n                    or unique_id in current_state_sources_runtime_error\n                ):\n                    matches.remove(unique_id)\n\n        for unique_id, node in self.all_nodes(included_nodes):\n            if unique_id in matches:\n                yield unique_id\n\n\nclass VersionSelectorMethod(SelectorMethod):\n    def search(self, included_nodes: Set[UniqueId], selector: str) -> Iterator[UniqueId]:\n        for unique_id, node in self.parsed_nodes(included_nodes):\n            if isinstance(node, ModelNode):\n                if selector == \"latest\":\n                    if node.is_latest_version:\n                        yield unique_id\n                elif selector == \"prerelease\":\n                    if (\n                        node.version\n                        and node.latest_version\n                        and UnparsedVersion(v=node.version)\n                        > UnparsedVersion(v=node.latest_version)\n                    ):\n                        yield unique_id\n                elif selector == \"old\":\n                    if (\n                        node.version\n                        and node.latest_version\n                        and UnparsedVersion(v=node.version)\n                        < UnparsedVersion(v=node.latest_version)\n                    ):\n                        yield unique_id\n                elif selector == \"none\":\n                    if node.version is None:\n                        yield unique_id\n                else:\n                    raise DbtRuntimeError(\n                        f'Invalid version type selector {selector}: expected one of: \"latest\", \"prerelease\", \"old\", or \"none\"'\n                    )\n\n\nclass SelectorSelectorMethod(SelectorMethod):\n    def __init__(\n        self,\n        manifest: Manifest,\n        previous_state: Optional[PreviousState],\n        arguments: List[str],\n        *,\n        get_selected_callback: Callable[..., Set[UniqueId]],\n        selectors: Optional[Dict[str, Any]] = None,\n    ) -> None:\n        super().__init__(manifest, previous_state, arguments)\n        self._selectors = selectors\n        self._get_selected_callback = get_selected_callback\n\n    def _search_for_matched_selector(\n        self, included_nodes: Set[UniqueId], selection_spec: \"SelectionSpec\"\n    ) -> Iterator[UniqueId]:\n        selected = self._get_selected_callback(selection_spec)\n        for unique_id in selected:\n            if unique_id in included_nodes:\n                yield unique_id\n\n    def search(self, included_nodes: Set[UniqueId], selector: str) -> Iterator[UniqueId]:\n        if self._selectors is None or self._get_selected_callback is None:\n            raise DbtSelectorsError(\"Cannot use selector: method if selectors.yml is not provided\")\n        matched_selector_dfns = []\n\n        # ensure that selectors are sorted to make the execution deterministic\n        # this will ensure that when circular depdencies are detected\n        # the same selector is used as the \"head\" of the circular dependency on every run\n        sorted_selectors = sorted(self._selectors.items(), key=lambda x: x[0])\n\n        for s_name, s_value in sorted_selectors:\n            if fnmatch(s_name, selector):\n                matched_selector_dfns.append(s_value[\"definition\"])\n\n        if not matched_selector_dfns:\n            raise DbtSelectorsError(\n                f\"Selector '{selector}' did not match any selector in selectors.yml\"\n            )\n\n        for matched_selector_dfn in matched_selector_dfns:\n            try:\n                yield from self._search_for_matched_selector(included_nodes, matched_selector_dfn)\n            except RecursionError as e:\n                raise DbtRecursionError(\n                    f\"Circular dependency detected in selector: {matched_selector_dfn.raw}\"\n                ) from e\n\n\nclass MethodManager:\n    SELECTOR_METHODS: Dict[MethodName, Type[SelectorMethod]] = {\n        MethodName.FQN: QualifiedNameSelectorMethod,\n        MethodName.Tag: TagSelectorMethod,\n        MethodName.Group: GroupSelectorMethod,\n        MethodName.Access: AccessSelectorMethod,\n        MethodName.Source: SourceSelectorMethod,\n        MethodName.Path: PathSelectorMethod,\n        MethodName.File: FileSelectorMethod,\n        MethodName.Package: PackageSelectorMethod,\n        MethodName.Config: ConfigSelectorMethod,\n        MethodName.TestName: TestNameSelectorMethod,\n        MethodName.TestType: TestTypeSelectorMethod,\n        MethodName.ResourceType: ResourceTypeSelectorMethod,\n        MethodName.State: StateSelectorMethod,\n        MethodName.Exposure: ExposureSelectorMethod,\n        MethodName.Metric: MetricSelectorMethod,\n        MethodName.Result: ResultSelectorMethod,\n        MethodName.SourceStatus: SourceStatusSelectorMethod,\n        MethodName.Version: VersionSelectorMethod,\n        MethodName.SemanticModel: SemanticModelSelectorMethod,\n        MethodName.SavedQuery: SavedQuerySelectorMethod,\n        MethodName.UnitTest: UnitTestSelectorMethod,\n        MethodName.Selector: SelectorSelectorMethod,\n    }\n\n    def __init__(\n        self,\n        manifest: Manifest,\n        previous_state: Optional[PreviousState],\n    ) -> None:\n        self.manifest = manifest\n        self.previous_state = previous_state\n\n    def get_method(\n        self, method: MethodName, method_arguments: List[str], **kwargs: Any\n    ) -> SelectorMethod:\n\n        if method not in self.SELECTOR_METHODS:\n            raise DbtInternalError(\n                f'Method name \"{method}\" is a valid node selection '\n                f\"method name, but it is not handled\"\n            )\n\n        cls: Type[SelectorMethod] = self.SELECTOR_METHODS[method]\n        return cls(self.manifest, self.previous_state, method_arguments, **kwargs)\n"
  },
  {
    "path": "core/dbt/graph/selector_spec.py",
    "content": "import os\nimport re\nfrom abc import ABCMeta, abstractmethod\nfrom dataclasses import dataclass\nfrom typing import Any, Dict, Iterable, Iterator, List, Optional, Set, Tuple, Union\n\nfrom dbt.exceptions import InvalidSelectorError\nfrom dbt.flags import get_flags\nfrom dbt_common.dataclass_schema import StrEnum, dbtClassMixin\nfrom dbt_common.exceptions import DbtRuntimeError\n\nfrom .graph import UniqueId\nfrom .selector_methods import MethodName\n\nRAW_SELECTOR_PATTERN = re.compile(\n    r\"\\A\"\n    r\"(?P<childrens_parents>(\\@))?\"\n    r\"(?P<parents>((?P<parents_depth>(\\d*))\\+))?\"\n    r\"((?P<method>([\\w.]+)):)?(?P<value>(.*?))\"\n    r\"(?P<children>(\\+(?P<children_depth>(\\d*))))?\"\n    r\"\\Z\"\n)\nSELECTOR_METHOD_SEPARATOR = \".\"\n\n\nclass IndirectSelection(StrEnum):\n    Eager = \"eager\"\n    Cautious = \"cautious\"\n    Buildable = \"buildable\"\n    Empty = \"empty\"\n\n\ndef _probably_path(value: str):\n    \"\"\"Decide if the value is probably a path. Windows has two path separators, so\n    we should check both sep ('\\\\') and altsep ('/') there.\n    \"\"\"\n    if os.path.sep in value:\n        return True\n    elif os.path.altsep is not None and os.path.altsep in value:\n        return True\n    else:\n        return False\n\n\ndef _match_to_int(match: Dict[str, str], key: str) -> Optional[int]:\n    raw = match.get(key)\n    # turn the empty string into None, too.\n    if not raw:\n        return None\n    try:\n        return int(raw)\n    except ValueError as exc:\n        raise DbtRuntimeError(f\"Invalid node spec - could not handle parent depth {raw}\") from exc\n\n\nSelectionSpec = Union[\n    \"SelectionCriteria\",\n    \"SelectionIntersection\",\n    \"SelectionDifference\",\n    \"SelectionUnion\",\n]\n\n\n@dataclass\nclass SelectionCriteria:\n    raw: Any\n    method: MethodName\n    method_arguments: List[str]\n    value: Any\n    childrens_parents: bool\n    parents: bool\n    parents_depth: Optional[int]\n    children: bool\n    children_depth: Optional[int]\n    indirect_selection: IndirectSelection = IndirectSelection.Eager\n\n    def __post_init__(self):\n        if self.children and self.childrens_parents:\n            raise DbtRuntimeError(\n                f'Invalid node spec {self.raw} - \"@\" prefix and \"+\" suffix ' \"are incompatible\"\n            )\n\n    @classmethod\n    def default_method(cls, value: str) -> MethodName:\n        if _probably_path(value):\n            return MethodName.Path\n        elif value.lower().endswith((\".sql\", \".py\", \".csv\")):\n            return MethodName.File\n        else:\n            return MethodName.FQN\n\n    @classmethod\n    def parse_method(cls, groupdict: Dict[str, Any]) -> Tuple[MethodName, List[str]]:\n        raw_method = groupdict.get(\"method\")\n        if raw_method is None:\n            return cls.default_method(groupdict[\"value\"]), []\n\n        method_parts: List[str] = raw_method.split(SELECTOR_METHOD_SEPARATOR)\n        try:\n            method_name = MethodName(method_parts[0])\n        except ValueError as exc:\n            raise InvalidSelectorError(f\"'{method_parts[0]}' is not a valid method name\") from exc\n\n        # Following is for cases like config.severity and config.materialized\n        method_arguments: List[str] = method_parts[1:]\n\n        return method_name, method_arguments\n\n    @classmethod\n    def selection_criteria_from_dict(\n        cls,\n        raw: Any,\n        dct: Dict[str, Any],\n    ) -> \"SelectionCriteria\":\n        if \"value\" not in dct:\n            raise DbtRuntimeError(f'Invalid node spec \"{raw}\" - no search value!')\n        method_name, method_arguments = cls.parse_method(dct)\n\n        parents_depth = _match_to_int(dct, \"parents_depth\")\n        children_depth = _match_to_int(dct, \"children_depth\")\n\n        # If defined field in selector, override CLI flag\n        indirect_selection = IndirectSelection(\n            dct.get(\"indirect_selection\", get_flags().INDIRECT_SELECTION)\n        )\n\n        return cls(\n            raw=raw,\n            method=method_name,\n            method_arguments=method_arguments,\n            value=dct[\"value\"],\n            childrens_parents=bool(dct.get(\"childrens_parents\")),\n            parents=bool(dct.get(\"parents\")),\n            parents_depth=parents_depth,\n            children=bool(dct.get(\"children\")),\n            children_depth=children_depth,\n            indirect_selection=indirect_selection,\n        )\n\n    @classmethod\n    def dict_from_single_spec(cls, raw: str):\n        result = RAW_SELECTOR_PATTERN.match(raw)\n        if result is None:\n            return {\"error\": \"Invalid selector spec\"}\n        dct: Dict[str, Any] = result.groupdict()\n        method_name, method_arguments = cls.parse_method(dct)\n        meth_name = str(method_name)\n        if method_arguments:\n            meth_name += \".\" + \".\".join(method_arguments)\n        dct[\"method\"] = meth_name\n        dct = {k: v for k, v in dct.items() if (v is not None and v != \"\")}\n        if \"childrens_parents\" in dct:\n            dct[\"childrens_parents\"] = bool(dct.get(\"childrens_parents\"))\n        if \"parents\" in dct:\n            dct[\"parents\"] = bool(dct.get(\"parents\"))\n        if \"children\" in dct:\n            dct[\"children\"] = bool(dct.get(\"children\"))\n        return dct\n\n    @classmethod\n    def from_single_spec(cls, raw: str) -> \"SelectionCriteria\":\n        result = RAW_SELECTOR_PATTERN.match(raw)\n        if result is None:\n            # bad spec!\n            raise DbtRuntimeError(f'Invalid selector spec \"{raw}\"')\n\n        return cls.selection_criteria_from_dict(raw, result.groupdict())\n\n\nclass BaseSelectionGroup(dbtClassMixin, Iterable[SelectionSpec], metaclass=ABCMeta):\n    def __init__(\n        self,\n        components: Iterable[SelectionSpec],\n        indirect_selection: IndirectSelection = IndirectSelection.Eager,\n        expect_exists: bool = False,\n        raw: Any = None,\n    ) -> None:\n        self.components: List[SelectionSpec] = list(components)\n        self.expect_exists = expect_exists\n        self.raw = raw\n        self.indirect_selection = indirect_selection\n\n    def __iter__(self) -> Iterator[SelectionSpec]:\n        for component in self.components:\n            yield component\n\n    @abstractmethod\n    def combine_selections(\n        self,\n        selections: List[Set[UniqueId]],\n    ) -> Set[UniqueId]:\n        raise NotImplementedError(\"_combine_selections not implemented!\")\n\n    def combined(self, selections: List[Set[UniqueId]]) -> Set[UniqueId]:\n        if not selections:\n            return set()\n\n        return self.combine_selections(selections)\n\n\nclass SelectionIntersection(BaseSelectionGroup):\n    def combine_selections(\n        self,\n        selections: List[Set[UniqueId]],\n    ) -> Set[UniqueId]:\n        return set.intersection(*selections)\n\n\nclass SelectionDifference(BaseSelectionGroup):\n    def combine_selections(\n        self,\n        selections: List[Set[UniqueId]],\n    ) -> Set[UniqueId]:\n        return set.difference(*selections)\n\n\nclass SelectionUnion(BaseSelectionGroup):\n    def combine_selections(\n        self,\n        selections: List[Set[UniqueId]],\n    ) -> Set[UniqueId]:\n        return set.union(*selections)\n"
  },
  {
    "path": "core/dbt/graph/thread_pool.py",
    "content": "from __future__ import annotations\n\nfrom math import floor\nfrom multiprocessing.pool import ThreadPool\n\n\nclass DbtThreadPool(ThreadPool):\n    \"\"\"A ThreadPool that tracks whether or not it's been closed\"\"\"\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self.closed = False\n        # The maximum number of threads that can be used by the pool\n        # Used for determining how MicrobatchBatchRungners should be run\n        self.max_threads = kwargs.get(\"processes\") if kwargs.get(\"processes\") else args[0]\n        # The maximum number of microbatch models that can be run concurrently\n        # Used for determining if a MicrobatchModelRunner can be submitted to the pool\n        self.max_microbatch_models = max(1, floor(self.max_threads / 2))\n\n    def close(self):\n        self.closed = True\n        super().close()\n\n    def is_closed(self):\n        return self.closed\n"
  },
  {
    "path": "core/dbt/hooks.py",
    "content": "import json\nfrom typing import Any, Dict, Union\n\nfrom dbt_common.dataclass_schema import StrEnum\n\n\nclass ModelHookType(StrEnum):\n    PreHook = \"pre-hook\"\n    PostHook = \"post-hook\"\n\n\ndef get_hook_dict(source: Union[str, Dict[str, Any]]) -> Dict[str, Any]:\n    \"\"\"From a source string-or-dict, get a dictionary that can be passed to\n    Hook.from_dict\n    \"\"\"\n    if isinstance(source, dict):\n        return source\n    try:\n        return json.loads(source)\n    except ValueError:\n        return {\"sql\": source}\n"
  },
  {
    "path": "core/dbt/include/README.md",
    "content": "# Include Module\n\nThe Include module is responsible for the starter project scaffold.\n\n# Directories\n\n## `starter_project`\nProduces the default project after running the `dbt init` command for the CLI. `dbt-cloud` initializes the project by using [dbt-starter-project](https://github.com/dbt-labs/dbt-starter-project).\n\n# adapter.dispatch\nPackages (e.g. `include` directories of adapters, any [hub](https://hub.getdbt.com/)-hosted package) can be interpreted as namespaces of functions a.k.a macros. In `dbt`'s macrospace, we take advantage of the multiple dispatch programming language concept. In short, multiple dispatch supports dynamic searching for a function across several namespaces—usually in a manually specified manner/order.\n\nAdapters can have their own implementation of the same macro X. For example, a macro executed by `dbt-redshift` may need a specific implementation different from `dbt-snowflake`'s macro. We use multiple dispatch via `adapter.dispatch`, a Jinja function, which enables polymorphic macro invocations. The chosen implementation is selected according to what the `adapter` object is set to at runtime (it could be for redshift, postgres, and so on).\n\nFor more on this object, check out the dbt docs [here](https://docs.getdbt.com/reference/dbt-jinja-functions/adapter).\n\n# dbt and database adapter python package interop\n\nLet’s say we have a fictional python app named `dbt-core` with this structure\n\n```\ndbt\n├── adapters\n│   └── base.py\n├── cli.py\n└── main.py\n```\n\n`pip install dbt-core` will install this application in my python environment, maintaining the same structure. Note that `dbt.adapters` only contains a `base.py`. In this example, we can assume that base.py includes an abstract class for creating connections. Let’s say we wanted to create an postgres adapter that this app could use, and can be installed independently. We can create a python package with the following structure called `dbt-postgres`\n```\ndbt\n└── adapters\n    └── postgres\n        └── impl.py\n```\n\n`pip install dbt-postgres` will install this package in the python environment, maintaining the same structure again. Let’s say `impl.py` imports `dbt.adapters.base` and implements a concrete class inheriting from the abstract class in `base.py` from the `dbt-core` package. Since our top level package is named the same in both packages, `pip` will put this in the same place. We end up with this installed in our python environment.\n\n```\ndbt\n├── adapters\n│   ├── base.py\n│   └── postgres\n│       └── impl.py\n├── cli.py\n└── main.py\n```\n\n`dbt.adapters` now has a postgres module that dbt can easily find and call directly. dbt and its adapters follows the same type of file structure convention. This is the magic that allows you to import `dbt.*` in database adapters, and using a factory pattern in dbt-core, we can create instances of concrete classes defined in the database adapter packages (for creating connections, defining database configuration, defining credentials, etc.)\n"
  },
  {
    "path": "core/dbt/include/__init__.py",
    "content": "from pkgutil import extend_path\n\n__path__ = extend_path(__path__, __name__)\n"
  },
  {
    "path": "core/dbt/include/starter_project/.gitignore",
    "content": "\ntarget/\ndbt_packages/\nlogs/\n"
  },
  {
    "path": "core/dbt/include/starter_project/README.md",
    "content": "Welcome to your new dbt project!\n\n### Using the starter project\n\nTry running the following commands:\n- dbt run\n- dbt test\n\n\n### Resources:\n- Learn more about dbt [in the docs](https://docs.getdbt.com/docs/introduction)\n- Check out [Discourse](https://discourse.getdbt.com/) for commonly asked questions and answers\n- Join the [chat](https://community.getdbt.com/) on Slack for live discussions and support\n- Find [dbt events](https://events.getdbt.com) near you\n- Check out [the blog](https://blog.getdbt.com/) for the latest news on dbt's development and best practices\n"
  },
  {
    "path": "core/dbt/include/starter_project/__init__.py",
    "content": "import os\n\nPACKAGE_PATH = os.path.dirname(__file__)\n"
  },
  {
    "path": "core/dbt/include/starter_project/analyses/.gitkeep",
    "content": ""
  },
  {
    "path": "core/dbt/include/starter_project/dbt_project.yml",
    "content": "\n# Name your project! Project names should contain only lowercase characters\n# and underscores. A good package name should reflect your organization's\n# name or the intended use of these models\nname: '{project_name}'\nversion: '1.0.0'\n\n# This setting configures which \"profile\" dbt uses for this project.\nprofile: '{profile_name}'\n\n# These configurations specify where dbt should look for different types of files.\n# The `model-paths` config, for example, states that models in this project can be\n# found in the \"models/\" directory. You probably won't need to change these!\nmodel-paths: [\"models\"]\nanalysis-paths: [\"analyses\"]\ntest-paths: [\"tests\"]\nseed-paths: [\"seeds\"]\nmacro-paths: [\"macros\"]\nsnapshot-paths: [\"snapshots\"]\n\nclean-targets:         # directories to be removed by `dbt clean`\n  - \"target\"\n  - \"dbt_packages\"\n\n\n# Configuring models\n# Full documentation: https://docs.getdbt.com/docs/configuring-models\n\n# In this example config, we tell dbt to build all models in the example/\n# directory as views. These settings can be overridden in the individual model\n# files using the `{{{{ config(...) }}}}` macro.\nmodels:\n  {project_name}:\n    # Config indicated by + and applies to all files under models/example/\n    example:\n      +materialized: view\n"
  },
  {
    "path": "core/dbt/include/starter_project/macros/.gitkeep",
    "content": ""
  },
  {
    "path": "core/dbt/include/starter_project/models/example/my_first_dbt_model.sql",
    "content": "\n/*\n    Welcome to your first dbt model!\n    Did you know that you can also configure models directly within SQL files?\n    This will override configurations stated in dbt_project.yml\n\n    Try changing \"table\" to \"view\" below\n*/\n\n{{ config(materialized='table') }}\n\nwith source_data as (\n\n    select 1 as id\n    union all\n    select null as id\n\n)\n\nselect *\nfrom source_data\n\n/*\n    Uncomment the line below to remove records with null `id` values\n*/\n\n-- where id is not null\n"
  },
  {
    "path": "core/dbt/include/starter_project/models/example/my_second_dbt_model.sql",
    "content": "\n-- Use the `ref` function to select from other models\n\nselect *\nfrom {{ ref('my_first_dbt_model') }}\nwhere id = 1\n"
  },
  {
    "path": "core/dbt/include/starter_project/models/example/schema.yml",
    "content": "\nversion: 2\n\nmodels:\n  - name: my_first_dbt_model\n    description: \"A starter dbt model\"\n    columns:\n      - name: id\n        description: \"The primary key for this table\"\n        data_tests:\n          - unique\n          - not_null\n\n  - name: my_second_dbt_model\n    description: \"A starter dbt model\"\n    columns:\n      - name: id\n        description: \"The primary key for this table\"\n        data_tests:\n          - unique\n          - not_null\n"
  },
  {
    "path": "core/dbt/include/starter_project/seeds/.gitkeep",
    "content": ""
  },
  {
    "path": "core/dbt/include/starter_project/snapshots/.gitkeep",
    "content": ""
  },
  {
    "path": "core/dbt/include/starter_project/tests/.gitkeep",
    "content": ""
  },
  {
    "path": "core/dbt/internal_deprecations.py",
    "content": "import functools\nfrom typing import Optional\n\nfrom dbt.events.types import InternalDeprecation\nfrom dbt_common.events.functions import warn_or_error\n\n\ndef deprecated(suggested_action: str, version: str, reason: Optional[str]):\n    def inner(func):\n        @functools.wraps(func)\n        def wrapped(*args, **kwargs):\n            name = func.__name__\n\n            warn_or_error(\n                InternalDeprecation(\n                    name=name,\n                    suggested_action=suggested_action,\n                    version=version,\n                    reason=reason,\n                )\n            )  # TODO: pass in event?\n            return func(*args, **kwargs)\n\n        return wrapped\n\n    return inner\n"
  },
  {
    "path": "core/dbt/jsonschemas/__init__.py",
    "content": "import os\n\nJSONSCHEMAS_PATH = os.path.dirname(__file__)\n"
  },
  {
    "path": "core/dbt/jsonschemas/jsonschemas.py",
    "content": "import json\nimport re\nfrom datetime import date, datetime\nfrom pathlib import Path\nfrom typing import Any, Dict, Iterator, List, Optional, Union\n\nimport jsonschema\nfrom jsonschema import ValidationError\nfrom jsonschema._keywords import type as type_rule\nfrom jsonschema.validators import Draft7Validator, extend\n\nfrom dbt import deprecations\nfrom dbt.jsonschemas import JSONSCHEMAS_PATH\nfrom dbt_common.context import get_invocation_context\n\n_PROJECT_SCHEMA: Optional[Dict[str, Any]] = None\n_RESOURCES_SCHEMA: Optional[Dict[str, Any]] = None\n\n_JSONSCHEMA_SUPPORTED_ADAPTERS = {\n    \"bigquery\",\n    \"databricks\",\n    \"redshift\",\n    \"snowflake\",\n}\n\n_HIERARCHICAL_CONFIG_KEYS = {\n    \"seeds\",\n    \"sources\",\n    \"models\",\n    \"snapshots\",\n    \"tests\",\n    \"exposures\",\n    \"data_tests\",\n    \"metrics\",\n    \"saved_queries\",\n    \"semantic_models\",\n    \"unit_tests\",\n}\n\n_ADAPTER_TO_CONFIG_ALIASES = {\n    \"bigquery\": [\"dataset\", \"project\"],\n}\n\n\ndef load_json_from_package(jsonschema_type: str, filename: str) -> Dict[str, Any]:\n    \"\"\"Loads a JSON file from within a package.\"\"\"\n\n    path = Path(JSONSCHEMAS_PATH).joinpath(jsonschema_type, filename)\n    data = path.read_bytes()\n    return json.loads(data)\n\n\ndef project_schema() -> Dict[str, Any]:\n    global _PROJECT_SCHEMA\n\n    if _PROJECT_SCHEMA is None:\n        _PROJECT_SCHEMA = load_json_from_package(\n            jsonschema_type=\"project\", filename=\"0.0.110.json\"\n        )\n    return _PROJECT_SCHEMA\n\n\ndef resources_schema() -> Dict[str, Any]:\n    global _RESOURCES_SCHEMA\n\n    if _RESOURCES_SCHEMA is None:\n        _RESOURCES_SCHEMA = load_json_from_package(\n            jsonschema_type=\"resources\", filename=\"latest.json\"\n        )\n\n    return _RESOURCES_SCHEMA\n\n\ndef custom_type_rule(validator, types, instance, schema):\n    \"\"\"This is necessary because PyYAML loads things that look like dates or datetimes as those\n    python objects. Then jsonschema.validate() fails because it expects strings.\n    \"\"\"\n    if \"string\" in types and (isinstance(instance, datetime) or isinstance(instance, date)):\n        return\n    else:\n        return type_rule(validator, types, instance, schema)\n\n\nCustomDraft7Validator = extend(Draft7Validator, validators={\"type\": custom_type_rule})\n\n\ndef error_path_to_string(error: jsonschema.ValidationError) -> str:\n    if len(error.path) == 0:\n        return \"\"\n    else:\n        path = str(error.path.popleft())\n        for part in error.path:\n            if isinstance(part, int):\n                path += f\"[{part}]\"\n            else:\n                path += f\".{part}\"\n\n        return path\n\n\ndef _additional_properties_violation_keys(error: ValidationError) -> List[str]:\n    found_keys = re.findall(r\"'\\S+'\", error.message)\n    return [key.strip(\"'\") for key in found_keys]\n\n\ndef _validate_with_schema(\n    schema: Dict[str, Any], json: Dict[str, Any]\n) -> Iterator[ValidationError]:\n    validator = CustomDraft7Validator(schema)\n    return validator.iter_errors(json)\n\n\ndef _get_allowed_config_key_aliases() -> List[str]:\n    config_aliases = []\n    invocation_context = get_invocation_context()\n    for adapter in invocation_context.adapter_types:\n        if adapter in _ADAPTER_TO_CONFIG_ALIASES:\n            config_aliases.extend(_ADAPTER_TO_CONFIG_ALIASES[adapter])\n\n    return config_aliases\n\n\ndef _get_allowed_config_fields_for_project_property(schema, property_field_name) -> List[str]:\n    property_defn = schema[\"properties\"].get(property_field_name)\n    property_defn_name = None\n    if property_defn and \"anyOf\" in property_defn:\n        for any_of_item in property_defn[\"anyOf\"]:\n            if \"$ref\" in any_of_item:\n                property_defn_name = any_of_item[\"$ref\"].split(\"/\")[-1]\n                break\n\n    if property_defn_name is None:\n        return []\n\n    allowed_config_fields = set(schema[\"definitions\"][property_defn_name][\"properties\"])\n    allowed_config_fields.update(_get_allowed_config_key_aliases())\n    return list(allowed_config_fields)\n\n\ndef _get_allowed_config_fields_from_error_path(\n    yml_schema: Dict[str, Any], error_path: List[Union[str, int]]\n) -> Optional[List[str]]:\n    property_field_name = None\n    node_schema = yml_schema[\"properties\"]\n    for part in error_path:\n        if isinstance(part, str):\n            if part in node_schema:\n                if \"items\" not in node_schema[part]:\n                    break\n\n                # Update property field name\n                property_field_name = node_schema[part][\"items\"][\"$ref\"].split(\"/\")[-1]\n\n                # Jump to the next level of the schema\n                item_definition = node_schema[part][\"items\"][\"$ref\"].split(\"/\")[-1]\n                node_schema = yml_schema[\"definitions\"][item_definition][\"properties\"]\n\n    if not property_field_name:\n        return None\n\n    if \"config\" not in yml_schema[\"definitions\"][property_field_name][\"properties\"]:\n        return None\n\n    config_field_name = yml_schema[\"definitions\"][property_field_name][\"properties\"][\"config\"][\n        \"anyOf\"\n    ][0][\"$ref\"].split(\"/\")[-1]\n\n    allowed_config_fields = list(set(yml_schema[\"definitions\"][config_field_name][\"properties\"]))\n    allowed_config_fields.extend(_get_allowed_config_key_aliases())\n\n    return allowed_config_fields\n\n\ndef _can_run_validations() -> bool:\n    invocation_context = get_invocation_context()\n    return invocation_context.adapter_types.issubset(_JSONSCHEMA_SUPPORTED_ADAPTERS)\n\n\ndef jsonschema_validate(schema: Dict[str, Any], json: Dict[str, Any], file_path: str) -> None:\n    if not _can_run_validations():\n        return\n\n    errors = _validate_with_schema(schema, json)\n    for error in errors:\n        # Listify the error path to make it easier to work with (it's a deque in the ValidationError object)\n        error_path = list(error.path)\n        if error.validator == \"additionalProperties\":\n            keys = _additional_properties_violation_keys(error)\n            if len(error.path) == 0:\n                for key in keys:\n                    deprecations.warn(\n                        \"custom-top-level-key-deprecation\",\n                        msg=\"Unexpected top-level key\" + (\" \" + key if key else \"\"),\n                        file=file_path,\n                    )\n            else:\n                key_path = error_path_to_string(error)\n                for key in keys:\n                    # Type params are not in the metrics v2 jsonschema from fusion, but dbt-core continues to maintain support for them in v1.\n                    if key == \"type_params\":\n                        continue\n\n                    # 'dataset' and 'project' are valid top-level source properties for BigQuery\n                    if (\n                        len(error_path) == 2\n                        and error_path[0] == \"sources\"\n                        and isinstance(error_path[1], int)\n                        and key in _get_allowed_config_key_aliases()\n                    ):\n                        continue\n\n                    if key == \"overrides\" and key_path.startswith(\"sources\"):\n                        deprecations.warn(\n                            \"source-override-deprecation\",\n                            source_name=key_path.split(\".\")[-1],\n                            file=file_path,\n                        )\n                    else:\n                        allowed_config_fields = _get_allowed_config_fields_from_error_path(\n                            schema, error_path\n                        )\n                        if allowed_config_fields and key in allowed_config_fields:\n                            deprecations.warn(\n                                \"property-moved-to-config-deprecation\",\n                                key=key,\n                                file=file_path,\n                                key_path=key_path,\n                            )\n                        else:\n                            deprecations.warn(\n                                \"custom-key-in-object-deprecation\",\n                                key=key,\n                                file=file_path,\n                                key_path=key_path,\n                            )\n        elif error.validator == \"anyOf\" and len(error_path) > 0:\n            sub_errors = error.context or []\n            # schema yaml resource configs\n            if error_path[-1] == \"config\":\n                for sub_error in sub_errors:\n                    if (\n                        isinstance(sub_error, ValidationError)\n                        and sub_error.validator == \"additionalProperties\"\n                    ):\n                        keys = _additional_properties_violation_keys(sub_error)\n                        key_path = error_path_to_string(error)\n                        for key in keys:\n                            if key in _get_allowed_config_key_aliases():\n                                continue\n\n                            deprecations.warn(\n                                \"custom-key-in-config-deprecation\",\n                                key=key,\n                                file=file_path,\n                                key_path=key_path,\n                            )\n            # dbt_project.yml configs\n            elif \"dbt_project.yml\" in file_path and error_path[0] in _HIERARCHICAL_CONFIG_KEYS:\n                for sub_error in sub_errors:\n                    if isinstance(sub_error, ValidationError) and sub_error.validator == \"type\":\n                        allowed_config_fields = _get_allowed_config_fields_for_project_property(\n                            schema, property_field_name=error_path[0]\n                        )\n                        is_missing_plus_prefix = (\n                            len(sub_error.path) > 0\n                            and isinstance(sub_error.path[-1], str)\n                            and not sub_error.path[-1].startswith(\"+\")\n                        )\n                        had_valid_config_key_in_path = any(\n                            k in allowed_config_fields for k in sub_error.path\n                        )\n                        is_maybe_config_key = (\n                            len(sub_error.path) > 0\n                            and isinstance(sub_error.path[-1], str)\n                            and f\"+{sub_error.path[-1]}\" in allowed_config_fields\n                        )\n\n                        # if its missing a plus prefix, does not have valid config key in path\n                        # and the last part of the error path might be a valid config key\n                        if (\n                            is_missing_plus_prefix\n                            and is_maybe_config_key\n                            and not had_valid_config_key_in_path\n                        ):\n                            deprecations.warn(\n                                \"missing-plus-prefix-in-config-deprecation\",\n                                key=sub_error.path[-1],\n                                file=file_path,\n                                key_path=error_path_to_string(sub_error),\n                            )\n        elif error.validator == \"type\":\n            # Not deprecating invalid types yet\n            pass\n        else:\n            deprecations.warn(\n                \"generic-json-schema-validation-deprecation\",\n                violation=error.message,\n                file=file_path,\n                key_path=error_path_to_string(error),\n            )\n\n\ndef validate_model_config(\n    config: Dict[str, Any], file_path: str, is_python_model: bool = False\n) -> None:\n    if not _can_run_validations():\n        return\n\n    resources_jsonschema = resources_schema()\n    nested_definition_name = \"ModelConfig\"\n\n    model_config_schema = {\n        \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n        \"title\": nested_definition_name,\n        **resources_jsonschema[\"definitions\"][nested_definition_name],\n        \"definitions\": {\n            k: v\n            for k, v in resources_jsonschema[\"definitions\"].items()\n            if k != nested_definition_name\n        },\n    }\n\n    errors = _validate_with_schema(model_config_schema, config)\n    for error in errors:\n        error_path = list(error.path)\n        if error.validator == \"additionalProperties\":\n            keys = _additional_properties_violation_keys(error)\n            if len(error.path) == 0:\n                key_path = error_path_to_string(error)\n                for key in keys:\n                    # Special case for pre/post hook keys as they are updated during config parsing\n                    # from the user-provided pre_hook/post_hook to pre-hook/post-hook keys.\n                    # Avoids false positives as described in https://github.com/dbt-labs/dbt-core/issues/12087\n                    if key in (\"post-hook\", \"pre-hook\"):\n                        continue\n\n                    # Special case for python model internal key additions\n                    # These keys are added during python model parsing and are not user-provided\n                    python_model_internal_keys = (\n                        \"config_keys_used\",\n                        \"config_keys_defaults\",\n                        \"meta_keys_used\",\n                        \"meta_keys_defaults\",\n                    )\n                    if key in python_model_internal_keys and is_python_model:\n                        continue\n\n                    # Dont raise deprecation warnings for adapter specific config key aliases\n                    if key in _get_allowed_config_key_aliases():\n                        continue\n\n                    # For everything else, emit deprecation warning\n                    deprecations.warn(\n                        \"custom-key-in-config-deprecation\",\n                        key=key,\n                        file=file_path,\n                        key_path=key_path,\n                    )\n            else:\n                error.path.appendleft(\"config\")\n                key_path = error_path_to_string(error)\n                for key in keys:\n                    deprecations.warn(\n                        \"custom-key-in-object-deprecation\",\n                        key=key,\n                        file=file_path,\n                        key_path=key_path,\n                    )\n        elif error.validator == \"type\":\n            # Not deprecating invalid types yet, except for pre-existing deprecation_date deprecation\n            pass\n        elif error.validator == \"anyOf\" and len(error_path) > 0:\n            for sub_error in error.context or []:\n                if (\n                    isinstance(sub_error, ValidationError)\n                    and sub_error.validator == \"additionalProperties\"\n                ):\n                    error.path.appendleft(\"config\")\n                    keys = _additional_properties_violation_keys(sub_error)\n                    key_path = error_path_to_string(error)\n                    for key in keys:\n                        deprecations.warn(\n                            \"custom-key-in-object-deprecation\",\n                            key=key,\n                            file=file_path,\n                            key_path=key_path,\n                        )\n        else:\n            deprecations.warn(\n                \"generic-json-schema-validation-deprecation\",\n                violation=error.message,\n                file=file_path,\n                key_path=error_path_to_string(error),\n            )\n"
  },
  {
    "path": "core/dbt/jsonschemas/project/0.0.110.json",
    "content": "{\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n  \"title\": \"DbtProject\",\n  \"type\": \"object\",\n  \"required\": [\n    \"name\"\n  ],\n  \"properties\": {\n    \"analyses\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/ProjectAnalysisConfig\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"analysis-paths\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"type\": \"string\"\n      }\n    },\n    \"asset-paths\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"type\": \"string\"\n      }\n    },\n    \"clean-targets\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"type\": \"string\"\n      }\n    },\n    \"config-version\": {\n      \"type\": [\n        \"integer\",\n        \"null\"\n      ],\n      \"format\": \"int32\"\n    },\n    \"data_tests\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/ProjectDataTestConfig\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"dbt-cloud\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/ProjectDbtCloudConfig\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"dispatch\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/_Dispatch\"\n      }\n    },\n    \"docs-paths\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"type\": \"string\"\n      }\n    },\n    \"exposures\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/ProjectExposureConfig\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"flags\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/AnyValue\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"function-paths\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"type\": \"string\"\n      }\n    },\n    \"functions\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/ProjectFunctionConfig\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"log-path\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/LogPath\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"macro-paths\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"type\": \"string\"\n      }\n    },\n    \"metrics\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/ProjectMetricConfigs\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"model-paths\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"type\": \"string\"\n      }\n    },\n    \"models\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/ProjectModelConfig\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"name\": {\n      \"type\": \"string\"\n    },\n    \"on-run-end\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/SpannedStringOrArrayOfStrings\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"on-run-start\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/SpannedStringOrArrayOfStrings\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"packages-install-path\": {\n      \"type\": [\n        \"string\",\n        \"null\"\n      ]\n    },\n    \"profile\": {\n      \"type\": [\n        \"string\",\n        \"null\"\n      ]\n    },\n    \"query-comment\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/QueryComment\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"quoting\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/DbtQuoting\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"require-dbt-version\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"restrict-access\": {\n      \"type\": [\n        \"boolean\",\n        \"null\"\n      ]\n    },\n    \"saved-queries\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/ProjectSavedQueryConfig\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"seed-paths\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"type\": \"string\"\n      }\n    },\n    \"seeds\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/ProjectSeedConfig\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"semantic-models\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/ProjectSemanticModelConfig\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"snapshot-paths\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"type\": \"string\"\n      }\n    },\n    \"snapshots\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/ProjectSnapshotConfig\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"sources\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/ProjectSourceConfig\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"sync\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/SyncConfig\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"target-path\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/TargetPath\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"test-paths\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"type\": \"string\"\n      }\n    },\n    \"tests\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/ProjectDataTestConfig\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"unit_tests\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/ProjectUnitTestConfig\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"vars\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/AnyValue\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"version\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/FloatOrString\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    }\n  },\n  \"additionalProperties\": false,\n  \"definitions\": {\n    \"Access\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"private\",\n        \"protected\",\n        \"public\"\n      ]\n    },\n    \"AnyValue\": true,\n    \"BigqueryPartitionConfig\": {\n      \"description\": \"reference: https://github.com/dbt-labs/dbt-adapters/blob/main/dbt-bigquery/src/dbt/adapters/bigquery/relation_configs/_partition.py#L12-L13\",\n      \"type\": \"object\",\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/RangeConfig\"\n        },\n        {\n          \"$ref\": \"#/definitions/TimeConfig\"\n        }\n      ],\n      \"required\": [\n        \"field\"\n      ],\n      \"properties\": {\n        \"copy_partitions\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"data_type\": {\n          \"default\": \"date\",\n          \"type\": \"string\"\n        },\n        \"field\": {\n          \"type\": \"string\"\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"ClusterConfig\": {\n      \"description\": \"Configuration for cluster by columns.\\n\\ndbt-core allows either of the variants for the `cluster_by` to allow cluster on a single column or on multiple columns\",\n      \"anyOf\": [\n        {\n          \"type\": \"string\"\n        },\n        {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        }\n      ]\n    },\n    \"DataLakeObjectCategory\": {\n      \"description\": \"See `category` from https://developer.salesforce.com/docs/data/connectapi/references/spec?meta=postDataLakeObject\",\n      \"type\": \"string\",\n      \"enum\": [\n        \"Profile\",\n        \"Engagement\",\n        \"Directory_Table\",\n        \"Insights\",\n        \"Other\"\n      ]\n    },\n    \"DbtBatchSize\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"hour\",\n        \"day\",\n        \"month\",\n        \"year\"\n      ]\n    },\n    \"DbtContract\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"alias_types\": {\n          \"default\": true,\n          \"type\": \"boolean\"\n        },\n        \"checksum\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/AnyValue\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"enforced\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"DbtIncrementalStrategy\": {\n      \"oneOf\": [\n        {\n          \"type\": \"string\",\n          \"enum\": [\n            \"append\",\n            \"merge\",\n            \"delete+insert\",\n            \"insert_overwrite\",\n            \"microbatch\"\n          ]\n        },\n        {\n          \"description\": \"replace_where (Databricks only) see https://docs.getdbt.com/reference/resource-configs/databricks-configs\",\n          \"type\": \"string\",\n          \"enum\": [\n            \"replace_where\"\n          ]\n        },\n        {\n          \"type\": \"object\",\n          \"required\": [\n            \"custom\"\n          ],\n          \"properties\": {\n            \"custom\": {\n              \"type\": \"string\"\n            }\n          },\n          \"additionalProperties\": false\n        }\n      ]\n    },\n    \"DbtMaterialization\": {\n      \"oneOf\": [\n        {\n          \"type\": \"string\",\n          \"enum\": [\n            \"snapshot\",\n            \"seed\",\n            \"view\",\n            \"table\",\n            \"incremental\",\n            \"materialized_view\",\n            \"external\",\n            \"test\",\n            \"ephemeral\",\n            \"unit\",\n            \"analysis\",\n            \"function\"\n          ]\n        },\n        {\n          \"description\": \"only for databricks\",\n          \"type\": \"string\",\n          \"enum\": [\n            \"streaming_table\"\n          ]\n        },\n        {\n          \"description\": \"only for snowflake\",\n          \"type\": \"string\",\n          \"enum\": [\n            \"dynamic_table\"\n          ]\n        },\n        {\n          \"description\": \"for inline SQL compilation\",\n          \"type\": \"string\",\n          \"enum\": [\n            \"inline\"\n          ]\n        },\n        {\n          \"type\": \"object\",\n          \"required\": [\n            \"unknown\"\n          ],\n          \"properties\": {\n            \"unknown\": {\n              \"type\": \"string\"\n            }\n          },\n          \"additionalProperties\": false\n        }\n      ]\n    },\n    \"DbtQuoting\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"database\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"identifier\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"schema\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"snowflake_ignore_case\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"DbtUniqueKey\": {\n      \"anyOf\": [\n        {\n          \"type\": \"string\"\n        },\n        {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        }\n      ]\n    },\n    \"DocsConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"node_color\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"show\": {\n          \"default\": true,\n          \"type\": \"boolean\"\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"ExportConfigExportAs\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"table\",\n        \"view\",\n        \"cache\"\n      ]\n    },\n    \"FloatOrString\": {\n      \"anyOf\": [\n        {\n          \"type\": \"number\",\n          \"format\": \"float\"\n        },\n        {\n          \"type\": \"string\"\n        }\n      ]\n    },\n    \"FreshnessDefinition\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"error_after\": {\n          \"default\": {\n            \"count\": null,\n            \"period\": null\n          },\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/FreshnessRules\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"filter\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"warn_after\": {\n          \"default\": {\n            \"count\": null,\n            \"period\": null\n          },\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/FreshnessRules\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"FreshnessPeriod\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"minute\",\n        \"hour\",\n        \"day\"\n      ]\n    },\n    \"FreshnessRules\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"count\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"int64\"\n        },\n        \"period\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/FreshnessPeriod\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"FunctionKind\": {\n      \"description\": \"Function kind enum with same values as UDFKind\",\n      \"type\": \"string\",\n      \"enum\": [\n        \"scalar\",\n        \"aggregate\",\n        \"table\"\n      ]\n    },\n    \"GrantAccessToTarget\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"dataset\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"project\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"GrantConfig\": {\n      \"description\": \"Wrapper type for grant configurations that normalizes values to arrays during serialization.\\n\\nThis type handles grant configurations with the following behavior: - Normalizes string values to arrays during serialization - Preserves insertion order using IndexMap\",\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n      }\n    },\n    \"HardDeletes\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"ignore\",\n        \"invalidate\",\n        \"new_record\"\n      ]\n    },\n    \"HookConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"index\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"sql\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"transaction\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"Hooks\": {\n      \"anyOf\": [\n        {\n          \"type\": \"string\"\n        },\n        {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        {\n          \"$ref\": \"#/definitions/HookConfig\"\n        },\n        {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/HookConfig\"\n          }\n        }\n      ]\n    },\n    \"IndexesConfig\": {\n      \"description\": \"A wrapper type for the `indexes` config field that handles flexible deserialization.\\n\\ndbt-core accepts both list and dictionary formats for indexes. This type accepts either format on input but always serializes as a list.\\n\\n# Example\\n\\n```ignore // Input (list): [{columns: [\\\"id\\\"], unique: true}] // Serializes as: [{columns: [\\\"id\\\"], unique: true}]\\n\\n// Input (dict): {\\\"my_index\\\": {columns: [\\\"id\\\"], unique: true}} // Serializes as: [{columns: [\\\"id\\\"], unique: true}]  (keys are discarded) ```\",\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/PostgresIndex\"\n      }\n    },\n    \"LogPath\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"logs\"\n      ]\n    },\n    \"ModelFreshness\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"build_after\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/ModelFreshnessRules\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"ModelFreshnessRules\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"count\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"int64\"\n        },\n        \"period\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/FreshnessPeriod\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"updates_on\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/UpdatesOn\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"OnConfigurationChange\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"apply\",\n        \"continue\",\n        \"fail\",\n        \"unknown\"\n      ]\n    },\n    \"OnSchemaChange\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"ignore\",\n        \"append_new_columns\",\n        \"fail\",\n        \"sync_all_columns\",\n        \"unknown\"\n      ]\n    },\n    \"PartitionConfig\": {\n      \"description\": \"Configuration for partition by columns.\\n\\ndbt-core allows either of the variants for the `partition_by` in the model config but the bigquery-adapter throws RunTime error the behaviors are tested from the latest dbt-core + bigquery-adapter as this is written we're conformant to this behavior via here and via the `into_bigquery()` method\",\n      \"anyOf\": [\n        {\n          \"type\": \"string\"\n        },\n        {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        {\n          \"$ref\": \"#/definitions/BigqueryPartitionConfig\"\n        }\n      ]\n    },\n    \"PersistDocsConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"columns\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"relation\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"PostgresIndex\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"columns\"\n      ],\n      \"properties\": {\n        \"columns\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"unique\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"PrimaryKeyConfig\": {\n      \"description\": \"A wrapper type for the `primary_key` config field that normalizes serialization.\\n\\nIn dbt-core, primary_key values are \\\"listified\\\" - single strings are converted to single-element arrays. This type accepts either format on input but always serializes as arrays.\\n\\n# Example\\n\\n```ignore // Input: \\\"id\\\" // Serializes as: [\\\"id\\\"]\\n\\n// Input: [\\\"id\\\", \\\"tenant_id\\\"] // Serializes as: [\\\"id\\\", \\\"tenant_id\\\"] ```\",\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"ProjectAnalysisConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"+docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+enabled\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+group\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+meta\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"+static_analysis\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StaticAnalysisKind\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/ProjectAnalysisConfig\"\n      }\n    },\n    \"ProjectDataTestConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"+adapter_properties\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"+alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+as_columnstore\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+auto_liquid_cluster\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+auto_refresh\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+automatic_clustering\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+backup\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+base_location_root\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+base_location_subpath\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+bind\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+buckets\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"int64\"\n        },\n        \"+catalog\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+catalog_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+cluster_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/ClusterConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+clustered_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+compression\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+copy_grants\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+database\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+databricks_compute\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+databricks_tags\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"+dist\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+enable_refresh\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+enabled\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+error_if\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+external_volume\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+fail_calc\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+file_format\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+full_refresh\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+grant_access_to\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/GrantAccessToTarget\"\n          }\n        },\n        \"+group\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+hours_to_expiration\": {\n          \"default\": null,\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"+include_full_name_in_path\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+indexes\": {\n          \"default\": null,\n          \"allOf\": [\n            {\n              \"$ref\": \"#/definitions/IndexesConfig\"\n            }\n          ]\n        },\n        \"+initialize\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+job_execution_timeout_seconds\": {\n          \"default\": null,\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"+kms_key_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+labels\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          }\n        },\n        \"+labels_from_meta\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+limit\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"int32\"\n        },\n        \"+liquid_clustered_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+location_root\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+matched_condition\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+max_staleness\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+merge_with_schema_evolution\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+meta\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"+not_matched_by_source_action\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+not_matched_by_source_condition\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+not_matched_condition\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+partition_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/PartitionConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+partition_expiration_days\": {\n          \"default\": null,\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"+partitions\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"+query_tag\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/QueryTag\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+quoting\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DbtQuoting\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+refresh_interval_minutes\": {\n          \"default\": null,\n          \"type\": [\n            \"number\",\n            \"null\"\n          ],\n          \"format\": \"double\"\n        },\n        \"+refresh_mode\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+require_partition_filter\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+row_access_policy\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+schedule\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Schedule\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+schema\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+secure\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+severity\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Severity\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+skip_matched_step\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+skip_not_matched_step\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+snowflake_warehouse\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+sort\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+sort_type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+source_alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+sql_header\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+static_analysis\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StaticAnalysisKind\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+store_failures\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+store_failures_as\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StoreFailuresAs\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+table_tag\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+table_type\": {\n          \"default\": null,\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+target_alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+target_lag\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+tblproperties\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"+tmp_relation_type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+transient\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+warn_if\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+where\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/ProjectDataTestConfig\"\n      }\n    },\n    \"ProjectDbtCloudConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"account-host\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"account_id\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrInteger\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"api_key\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrInteger\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"application\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrInteger\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"defer-env-id\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrInteger\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"environment\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrInteger\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"job-id\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrInteger\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"project-id\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrInteger\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"run-id\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrInteger\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tenant_hostname\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"ProjectExposureConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"+enabled\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+meta\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"+tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/ProjectExposureConfig\"\n      }\n    },\n    \"ProjectFunctionConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"+access\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Access\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+database\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+enabled\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+entry_point\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+grants\": {\n          \"$ref\": \"#/definitions/GrantConfig\"\n        },\n        \"+group\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+meta\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"+on_configuration_change\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+quoting\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DbtQuoting\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+runtime_version\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+schema\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+static_analysis\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StaticAnalysisKind\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+type\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/FunctionKind\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+volatility\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Volatility\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/ProjectFunctionConfig\"\n      }\n    },\n    \"ProjectMetricConfigs\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"+enabled\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+group\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+meta\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"+tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/ProjectMetricConfigs\"\n      }\n    },\n    \"ProjectModelConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"+access\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Access\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+adapter_properties\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"+additional_libs\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"+alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+as_columnstore\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+auto_liquid_cluster\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+auto_refresh\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+automatic_clustering\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+backup\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+base_location_root\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+base_location_subpath\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+batch_id\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+batch_size\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DbtBatchSize\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+begin\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+bind\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+buckets\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"int64\"\n        },\n        \"+catalog\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+catalog_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+category\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DataLakeObjectCategory\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+cluster_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/ClusterConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+cluster_id\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+clustered_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+column_types\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          }\n        },\n        \"+compression\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+concurrent_batches\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+contract\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DbtContract\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+copy_grants\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+create_notebook\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+database\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+databricks_compute\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+databricks_tags\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"+dataproc_cluster_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+dist\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+enable_list_inference\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+enable_refresh\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+enabled\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+event_time\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+external_access_integrations\": {\n          \"description\": \"Snowflake Python model config: external access integrations for network access\",\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+external_volume\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+file_format\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+freshness\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/ModelFreshness\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+full_refresh\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+grant_access_to\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/GrantAccessToTarget\"\n          }\n        },\n        \"+grants\": {\n          \"$ref\": \"#/definitions/GrantConfig\"\n        },\n        \"+group\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+hours_to_expiration\": {\n          \"default\": null,\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"+http_path\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+imports\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+include_full_name_in_path\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+incremental_predicates\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"+incremental_strategy\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DbtIncrementalStrategy\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+index_url\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+indexes\": {\n          \"default\": null,\n          \"allOf\": [\n            {\n              \"$ref\": \"#/definitions/IndexesConfig\"\n            }\n          ]\n        },\n        \"+initialize\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+intermediate_format\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+jar_file_uri\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+job_cluster_config\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"+job_execution_timeout_seconds\": {\n          \"default\": null,\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"+kms_key_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+labels\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          }\n        },\n        \"+labels_from_meta\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+liquid_clustered_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+location\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+location_root\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+lookback\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"int32\"\n        },\n        \"+matched_condition\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+materialized\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DbtMaterialization\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+max_staleness\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+merge_exclude_columns\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+merge_update_columns\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+merge_with_schema_evolution\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+meta\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"+not_matched_by_source_action\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+not_matched_by_source_condition\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+not_matched_condition\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+notebook_template_id\": {\n          \"default\": null,\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"+on_configuration_change\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/OnConfigurationChange\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+on_schema_change\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/OnSchemaChange\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+packages\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+partition_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/PartitionConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+partition_expiration_days\": {\n          \"default\": null,\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"+partitions\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"+persist_docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/PersistDocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+post-hook\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Hooks\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+pre-hook\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Hooks\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+predicates\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"+primary_key\": {\n          \"default\": null,\n          \"allOf\": [\n            {\n              \"$ref\": \"#/definitions/PrimaryKeyConfig\"\n            }\n          ]\n        },\n        \"+python_job_config\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"+python_version\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+query_tag\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/QueryTag\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+quoting\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DbtQuoting\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+refresh_interval_minutes\": {\n          \"default\": null,\n          \"type\": [\n            \"number\",\n            \"null\"\n          ],\n          \"format\": \"double\"\n        },\n        \"+refresh_mode\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+require_partition_filter\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+resource_tags\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          }\n        },\n        \"+row_access_policy\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+schedule\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Schedule\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+schema\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+secrets\": {\n          \"description\": \"Snowflake Python model config: secrets to pass to stored procedure\",\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"+secure\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+skip_matched_step\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+skip_not_matched_step\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+snowflake_warehouse\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+sort\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+sort_type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+source_alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+sql_header\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+static_analysis\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StaticAnalysisKind\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+submission_method\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+sync\": {\n          \"description\": \"Schema synchronization configuration\",\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/SyncConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+table_format\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+table_tag\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+table_type\": {\n          \"default\": null,\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+tags\": {\n          \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n        },\n        \"+target_alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+target_lag\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+tblproperties\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"+timeout\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"+tmp_relation_type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+transient\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+unique_key\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DbtUniqueKey\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+use_anonymous_sproc\": {\n          \"description\": \"Snowflake Python model config: use anonymous stored procedure (default: true)\",\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+user_folder_for_python\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/ProjectModelConfig\"\n      }\n    },\n    \"ProjectSavedQueryConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"+cache\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/SavedQueryCache\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+enabled\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+export_as\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/ExportConfigExportAs\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+group\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+meta\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"+schema\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/ProjectSavedQueryConfig\"\n      }\n    },\n    \"ProjectSeedConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"+adapter_properties\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"+alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+as_columnstore\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+auto_liquid_cluster\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+auto_refresh\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+automatic_clustering\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+backup\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+base_location_root\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+base_location_subpath\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+bind\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+buckets\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"int64\"\n        },\n        \"+catalog\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+catalog_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+cluster_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/ClusterConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+clustered_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+column_types\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          }\n        },\n        \"+compression\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+copy_grants\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+database\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+databricks_compute\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+databricks_tags\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"+delimiter\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+dist\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+enable_refresh\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+enabled\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+event_time\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+external_volume\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+file_format\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+full_refresh\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+grant_access_to\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/GrantAccessToTarget\"\n          }\n        },\n        \"+grants\": {\n          \"$ref\": \"#/definitions/GrantConfig\"\n        },\n        \"+group\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+hours_to_expiration\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"+include_full_name_in_path\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+indexes\": {\n          \"default\": null,\n          \"allOf\": [\n            {\n              \"$ref\": \"#/definitions/IndexesConfig\"\n            }\n          ]\n        },\n        \"+initialize\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+job_execution_timeout_seconds\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"+kms_key_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+labels\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          }\n        },\n        \"+labels_from_meta\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+liquid_clustered_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+location_root\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+matched_condition\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+max_staleness\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+merge_with_schema_evolution\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+meta\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"+not_matched_by_source_action\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+not_matched_by_source_condition\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+not_matched_condition\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+partition_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/PartitionConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+partition_expiration_days\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"+partitions\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"+persist_docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/PersistDocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+post-hook\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Hooks\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+pre-hook\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Hooks\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+query_tag\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/QueryTag\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+quote_columns\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+quoting\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DbtQuoting\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+refresh_interval_minutes\": {\n          \"type\": [\n            \"number\",\n            \"null\"\n          ],\n          \"format\": \"double\"\n        },\n        \"+refresh_mode\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+require_partition_filter\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+row_access_policy\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+schedule\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Schedule\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+schema\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+secure\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+skip_matched_step\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+skip_not_matched_step\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+snowflake_warehouse\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+sort\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+sort_type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+source_alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+static_analysis\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StaticAnalysisKind\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+table_tag\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+table_type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+target_alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+target_lag\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+tblproperties\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"+tmp_relation_type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+transient\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/ProjectSeedConfig\"\n      }\n    },\n    \"ProjectSemanticModelConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"+enabled\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+group\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+meta\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"+tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/ProjectSemanticModelConfig\"\n      }\n    },\n    \"ProjectSnapshotConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"+adapter_properties\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"+alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+as_columnstore\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+auto_liquid_cluster\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+auto_refresh\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+automatic_clustering\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+backup\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+base_location_root\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+base_location_subpath\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+bind\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+buckets\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"int64\"\n        },\n        \"+catalog\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+catalog_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+check_cols\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+cluster_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/ClusterConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+clustered_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+compression\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+copy_grants\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+database\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+databricks_compute\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+databricks_tags\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"+dbt_valid_to_current\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+dist\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+enable_refresh\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+enabled\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+event_time\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+external_volume\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+file_format\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+full_refresh\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+grant_access_to\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/GrantAccessToTarget\"\n          }\n        },\n        \"+grants\": {\n          \"$ref\": \"#/definitions/GrantConfig\"\n        },\n        \"+group\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+hard_deletes\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/HardDeletes\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+hours_to_expiration\": {\n          \"default\": null,\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"+include_full_name_in_path\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+indexes\": {\n          \"default\": null,\n          \"allOf\": [\n            {\n              \"$ref\": \"#/definitions/IndexesConfig\"\n            }\n          ]\n        },\n        \"+initialize\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+invalidate_hard_deletes\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+job_execution_timeout_seconds\": {\n          \"default\": null,\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"+kms_key_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+labels\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          }\n        },\n        \"+labels_from_meta\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+liquid_clustered_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+location_root\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+matched_condition\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+materialized\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DbtMaterialization\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+max_staleness\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+merge_with_schema_evolution\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+meta\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"+not_matched_by_source_action\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+not_matched_by_source_condition\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+not_matched_condition\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+partition_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/PartitionConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+partition_expiration_days\": {\n          \"default\": null,\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"+partitions\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"+persist_docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/PersistDocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+post-hook\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Hooks\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+pre-hook\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Hooks\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+query_tag\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/QueryTag\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+quote_columns\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+quoting\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DbtQuoting\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+refresh_interval_minutes\": {\n          \"default\": null,\n          \"type\": [\n            \"number\",\n            \"null\"\n          ],\n          \"format\": \"double\"\n        },\n        \"+refresh_mode\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+require_partition_filter\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+row_access_policy\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+schedule\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Schedule\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+schema\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+secure\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+skip_matched_step\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+skip_not_matched_step\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+snapshot_meta_column_names\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/SnapshotMetaColumnNames\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+snowflake_warehouse\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+sort\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+sort_type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+source_alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+static_analysis\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StaticAnalysisKind\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+strategy\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+sync\": {\n          \"description\": \"Schema synchronization configuration\",\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/SyncConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+table_tag\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+table_type\": {\n          \"default\": null,\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+target_alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+target_database\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+target_lag\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+target_schema\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+tblproperties\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"+tmp_relation_type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+transient\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+unique_key\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+updated_at\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/ProjectSnapshotConfig\"\n      }\n    },\n    \"ProjectSourceConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"+adapter_properties\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"+as_columnstore\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+auto_liquid_cluster\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+auto_refresh\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+automatic_clustering\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+backup\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+base_location_root\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+base_location_subpath\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+bind\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+buckets\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"int64\"\n        },\n        \"+catalog\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+catalog_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+cluster_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/ClusterConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+clustered_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+compression\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+copy_grants\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+databricks_compute\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+databricks_tags\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"+dist\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+enable_refresh\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+enabled\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+event_time\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+external_volume\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+file_format\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+freshness\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/FreshnessDefinition\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+grant_access_to\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/GrantAccessToTarget\"\n          }\n        },\n        \"+hours_to_expiration\": {\n          \"default\": null,\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"+include_full_name_in_path\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+indexes\": {\n          \"default\": null,\n          \"allOf\": [\n            {\n              \"$ref\": \"#/definitions/IndexesConfig\"\n            }\n          ]\n        },\n        \"+initialize\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+job_execution_timeout_seconds\": {\n          \"default\": null,\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"+kms_key_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+labels\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          }\n        },\n        \"+labels_from_meta\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+liquid_clustered_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+loaded_at_field\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+loaded_at_query\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+location_root\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+matched_condition\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+max_staleness\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+merge_with_schema_evolution\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+meta\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"+not_matched_by_source_action\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+not_matched_by_source_condition\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+not_matched_condition\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+partition_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/PartitionConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+partition_expiration_days\": {\n          \"default\": null,\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"+partitions\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"+query_tag\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/QueryTag\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+quoting\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DbtQuoting\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+refresh_interval_minutes\": {\n          \"default\": null,\n          \"type\": [\n            \"number\",\n            \"null\"\n          ],\n          \"format\": \"double\"\n        },\n        \"+refresh_mode\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+require_partition_filter\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+row_access_policy\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+schedule\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Schedule\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+schema_origin\": {\n          \"description\": \"Specifies where the schema metadata originates: 'remote' (default) or 'local'\",\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/SchemaOrigin\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+secure\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+skip_matched_step\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+skip_not_matched_step\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+snowflake_warehouse\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+sort\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+sort_type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+source_alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+static_analysis\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StaticAnalysisKind\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+sync\": {\n          \"description\": \"Schema synchronization configuration\",\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/SyncConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+table_tag\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+table_type\": {\n          \"default\": null,\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+target_alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+target_lag\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+tblproperties\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"+tmp_relation_type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+transient\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/ProjectSourceConfig\"\n      }\n    },\n    \"ProjectUnitTestConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"+adapter_properties\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"+as_columnstore\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+auto_liquid_cluster\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+auto_refresh\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+automatic_clustering\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+backup\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+base_location_root\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+base_location_subpath\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+bind\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+buckets\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"int64\"\n        },\n        \"+catalog\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+catalog_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+cluster_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/ClusterConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+clustered_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+compression\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+copy_grants\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+databricks_compute\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+databricks_tags\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"+dist\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+enable_refresh\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+enabled\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+external_volume\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+file_format\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+grant_access_to\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/GrantAccessToTarget\"\n          }\n        },\n        \"+hours_to_expiration\": {\n          \"default\": null,\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"+include_full_name_in_path\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+indexes\": {\n          \"default\": null,\n          \"allOf\": [\n            {\n              \"$ref\": \"#/definitions/IndexesConfig\"\n            }\n          ]\n        },\n        \"+initialize\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+job_execution_timeout_seconds\": {\n          \"default\": null,\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"+kms_key_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+labels\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          }\n        },\n        \"+labels_from_meta\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+liquid_clustered_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+location_root\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+matched_condition\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+max_staleness\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+merge_with_schema_evolution\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+meta\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"+not_matched_by_source_action\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+not_matched_by_source_condition\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+not_matched_condition\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+partition_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/PartitionConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+partition_expiration_days\": {\n          \"default\": null,\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"+partitions\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"+query_tag\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/QueryTag\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+refresh_interval_minutes\": {\n          \"default\": null,\n          \"type\": [\n            \"number\",\n            \"null\"\n          ],\n          \"format\": \"double\"\n        },\n        \"+refresh_mode\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+require_partition_filter\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+row_access_policy\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+schedule\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Schedule\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+secure\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+skip_matched_step\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+skip_not_matched_step\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"+snowflake_warehouse\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+sort\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+sort_type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+source_alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+static_analysis\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StaticAnalysisKind\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+table_tag\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+table_type\": {\n          \"default\": null,\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+target_alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+target_lag\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+tblproperties\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"+tmp_relation_type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+transient\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/ProjectUnitTestConfig\"\n      }\n    },\n    \"QueryComment\": {\n      \"anyOf\": [\n        {\n          \"type\": \"string\"\n        },\n        {\n          \"$ref\": \"#/definitions/AnyValue\"\n        }\n      ]\n    },\n    \"QueryTag\": {\n      \"description\": \"A wrapper type for the `query_tag` config field that handles flexible deserialization.\\n\\nAccepts strings, dictionaries, or sequences for query_tag. Maps and sequences are JSON-serialized to strings.\\n\\n# Example\\n\\n```ignore // Input: \\\"my-tag\\\" // Stores as: \\\"my-tag\\\"\\n\\n// Input: {\\\"project\\\": \\\"foo\\\", \\\"env\\\": \\\"prod\\\"} // Stores as: \\\"{\\\\\\\"project\\\\\\\":\\\\\\\"foo\\\\\\\",\\\\\\\"env\\\\\\\":\\\\\\\"prod\\\\\\\"}\\\" ```\",\n      \"type\": \"string\"\n    },\n    \"Range\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"end\",\n        \"interval\",\n        \"start\"\n      ],\n      \"properties\": {\n        \"end\": {\n          \"type\": \"integer\",\n          \"format\": \"int64\"\n        },\n        \"interval\": {\n          \"type\": \"integer\",\n          \"format\": \"int64\"\n        },\n        \"start\": {\n          \"type\": \"integer\",\n          \"format\": \"int64\"\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"RangeConfig\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"range\"\n      ],\n      \"properties\": {\n        \"range\": {\n          \"$ref\": \"#/definitions/Range\"\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"SavedQueryCache\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"enabled\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"Schedule\": {\n      \"description\": \"Schedule configuration that accepts both string and structured formats. This allows users to specify schedule as either: - A string: `schedule: \\\"USING CRON 0,15,30,45 * * * * UTC\\\"` - A structured config: `schedule: { cron: \\\"0 * * * *\\\", time_zone_value: \\\"UTC\\\" }`\",\n      \"anyOf\": [\n        {\n          \"type\": \"string\"\n        },\n        {\n          \"$ref\": \"#/definitions/ScheduleConfig\"\n        }\n      ]\n    },\n    \"ScheduleConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"cron\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"time_zone_value\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"SchemaOrigin\": {\n      \"description\": \"Indicates where schema metadata originates from.\\n\\n- `Remote` (default): Schema is fetched from the remote warehouse - `Local`: Schema is derived from YAML column definitions\",\n      \"oneOf\": [\n        {\n          \"description\": \"Schema metadata comes from the remote warehouse (default)\",\n          \"type\": \"string\",\n          \"enum\": [\n            \"remote\"\n          ]\n        },\n        {\n          \"description\": \"Schema metadata is derived from YAML column definitions\",\n          \"type\": \"string\",\n          \"enum\": [\n            \"local\"\n          ]\n        }\n      ]\n    },\n    \"SchemaRefreshInterval\": {\n      \"description\": \"Schema refresh interval: '30m', '2h', '1d', or 'never'\",\n      \"type\": \"string\"\n    },\n    \"Severity\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"Error\",\n        \"Warn\"\n      ]\n    },\n    \"SnapshotMetaColumnNames\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"dbt_is_deleted\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"dbt_scd_id\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"dbt_updated_at\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"dbt_valid_from\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"dbt_valid_to\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"SpannedStringOrArrayOfStrings\": {\n      \"anyOf\": [\n        {\n          \"type\": \"string\"\n        },\n        {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        }\n      ]\n    },\n    \"StaticAnalysisKind\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"unsafe\",\n        \"off\",\n        \"strict\",\n        \"baseline\",\n        \"on\"\n      ]\n    },\n    \"StoreFailuresAs\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"ephemeral\",\n        \"table\",\n        \"view\"\n      ]\n    },\n    \"StringOrArrayOfStrings\": {\n      \"anyOf\": [\n        {\n          \"type\": \"string\"\n        },\n        {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        }\n      ]\n    },\n    \"StringOrInteger\": {\n      \"anyOf\": [\n        {\n          \"type\": \"string\"\n        },\n        {\n          \"type\": \"integer\",\n          \"format\": \"int64\"\n        }\n      ]\n    },\n    \"SyncConfig\": {\n      \"description\": \"Configuration for schema synchronization behavior.\\n\\nThis can be specified at source level (default for all tables) or at individual table level (overrides source-level settings).\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"schema_refresh_interval\": {\n          \"description\": \"How often to refresh the schema from the warehouse. Examples: \\\"30m\\\", \\\"2h\\\", \\\"1d\\\", \\\"never\\\"\",\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/SchemaRefreshInterval\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"TargetPath\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"target\"\n      ]\n    },\n    \"TimeConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"granularity\": {\n          \"default\": \"day\",\n          \"type\": \"string\"\n        },\n        \"time_ingestion_partitioning\": {\n          \"description\": \"When this is true, the [`BigqueryPartitionConfig::field`] will be used as the `_PARTITIONTIME` pseudo column _PARTITIONTIME: https://cloud.google.com/bigquery/docs/partitioned-tables#ingestion_time https://docs.getdbt.com/reference/resource-configs/bigquery-configs#partitioning-by-an-ingestion-date-or-timestamp\",\n          \"default\": false,\n          \"type\": \"boolean\"\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"UpdatesOn\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"any\",\n        \"all\"\n      ]\n    },\n    \"Volatility\": {\n      \"description\": \"Function volatility enum - defines the function's eligibility for certain optimizations Matches the Python Volatility enum from dbt-core\",\n      \"oneOf\": [\n        {\n          \"type\": \"string\",\n          \"enum\": [\n            \"stable\"\n          ]\n        },\n        {\n          \"description\": \"Deterministic - An deterministic function will always return the same output when given the same input.\",\n          \"type\": \"string\",\n          \"enum\": [\n            \"deterministic\"\n          ]\n        },\n        {\n          \"description\": \"NonDeterministic - A non-deterministic function may change the return value from evaluation to evaluation. Multiple invocations of a non-deterministic function may return different results when used in the same query.\",\n          \"type\": \"string\",\n          \"enum\": [\n            \"non-deterministic\"\n          ]\n        }\n      ]\n    },\n    \"_Dispatch\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"macro_namespace\",\n        \"search_order\"\n      ],\n      \"properties\": {\n        \"macro_namespace\": {\n          \"type\": \"string\"\n        },\n        \"search_order\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        }\n      },\n      \"additionalProperties\": false\n    }\n  }\n}\n"
  },
  {
    "path": "core/dbt/jsonschemas/project/0.0.85.json",
    "content": "{\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n  \"title\": \"DbtProject\",\n  \"type\": \"object\",\n  \"required\": [\n    \"name\"\n  ],\n  \"properties\": {\n    \"analysis-paths\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"type\": \"string\"\n      }\n    },\n    \"asset-paths\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"type\": \"string\"\n      }\n    },\n    \"clean-targets\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"type\": \"string\"\n      }\n    },\n    \"config-version\": {\n      \"type\": [\n        \"integer\",\n        \"null\"\n      ],\n      \"format\": \"int32\"\n    },\n    \"data_tests\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/DataTestConfigs\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"dbt-cloud\": true,\n    \"dispatch\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/_Dispatch\"\n      }\n    },\n    \"docs-paths\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"type\": \"string\"\n      }\n    },\n    \"flags\": true,\n    \"log-path\": {\n      \"type\": [\n        \"string\",\n        \"null\"\n      ]\n    },\n    \"macro-paths\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"type\": \"string\"\n      }\n    },\n    \"metrics\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/MetricConfigs\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"model-paths\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"type\": \"string\"\n      }\n    },\n    \"models\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/ModelConfigs\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"name\": {\n      \"type\": \"string\"\n    },\n    \"on-run-end\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/StringOrVecString\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"on-run-start\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/StringOrVecString\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"packages-install-path\": {\n      \"type\": [\n        \"string\",\n        \"null\"\n      ]\n    },\n    \"profile\": {\n      \"type\": [\n        \"string\",\n        \"null\"\n      ]\n    },\n    \"query-comment\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/QueryComment\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"quoting\": true,\n    \"require-dbt-version\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"restrict-access\": {\n      \"type\": [\n        \"boolean\",\n        \"null\"\n      ]\n    },\n    \"saved-queries\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/SavedQueriesConfigs\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"seed-paths\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"type\": \"string\"\n      }\n    },\n    \"seeds\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/SeedConfigs\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"semantic-models\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/ModelConfigs\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"snapshot-paths\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"type\": \"string\"\n      }\n    },\n    \"snapshots\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/SnapshotConfigs\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"sources\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/SourceConfigs\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"target-path\": {\n      \"type\": [\n        \"string\",\n        \"null\"\n      ]\n    },\n    \"test-paths\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"type\": \"string\"\n      }\n    },\n    \"tests\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/DataTestConfigs\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"unit_tests\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/UnitTestConfigs\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"vars\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/AnyValue\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"version\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/FloatOrString\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    }\n  },\n  \"definitions\": {\n    \"Access\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"private\",\n        \"protected\",\n        \"public\"\n      ]\n    },\n    \"AnyValue\": true,\n    \"BooleanOrJinjaString\": {\n      \"anyOf\": [\n        {\n          \"type\": \"string\"\n        },\n        {\n          \"type\": \"boolean\"\n        }\n      ]\n    },\n    \"Contract\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"enforced\"\n      ],\n      \"properties\": {\n        \"alias_types\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"enforced\": {\n          \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n        }\n      }\n    },\n    \"DataTestConfigs\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"+alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+database\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+enabled\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+error_if\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+fail_calc\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+group\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+limit\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"int32\"\n        },\n        \"+meta\": true,\n        \"+schema\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+severity\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Severity\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+store_failures\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+warn_if\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"__additional_properties__\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"database\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"enabled\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"error_if\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"fail_calc\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"group\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"limit\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"int32\"\n        },\n        \"meta\": true,\n        \"schema\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"severity\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Severity\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"store_failures\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"warn_if\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      }\n    },\n    \"DocsConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"node_color\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"show\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        }\n      }\n    },\n    \"FloatOrString\": {\n      \"anyOf\": [\n        {\n          \"type\": \"number\",\n          \"format\": \"float\"\n        },\n        {\n          \"type\": \"string\"\n        }\n      ]\n    },\n    \"HookConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"sql\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"transaction\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        }\n      }\n    },\n    \"Hooks\": {\n      \"anyOf\": [\n        {\n          \"type\": \"string\"\n        },\n        {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        {\n          \"$ref\": \"#/definitions/HookConfig\"\n        },\n        {\n          \"type\": \"array\",\n          \"items\": true\n        }\n      ]\n    },\n    \"MetricConfigs\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"+meta\": true,\n        \"enabled\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": true\n    },\n    \"ModelConfigs\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"+access\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Access\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+auto_refresh\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+backup\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+bind\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+contract\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Contract\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+copy_grants\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+database\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+enabled\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+file_format\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+full_refresh\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+grant_access_to\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": true\n        },\n        \"+grants\": true,\n        \"+group\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+hours_to_expiration\": {\n          \"type\": [\n            \"number\",\n            \"null\"\n          ],\n          \"format\": \"float\"\n        },\n        \"+include_full_name_in_path\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+incremental_predicates\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"+incremental_strategy\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+kms_key_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+labels\": true,\n        \"+location\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+location_root\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+materialized\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+meta\": true,\n        \"+on_configuration_change\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/OnConfigurationChange\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+on_schema_change\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/OnSchemaChange\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+persist_docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/PersistDocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+post-hook\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Hooks\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+pre-hook\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Hooks\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+predicates\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"+query_tag\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+schema\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+secure\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+snowflake_warehouse\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+sql_header\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+table_format\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+target_lag\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+tblproperties\": true,\n        \"+transient\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"__additional_properties__\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"access\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Access\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"auto_refresh\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"backup\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"bind\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"contract\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Contract\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"copy_grants\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"database\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"enabled\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"file_format\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"full_refresh\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"grant_access_to\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": true\n        },\n        \"grants\": true,\n        \"group\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"hours_to_expiration\": {\n          \"type\": [\n            \"number\",\n            \"null\"\n          ],\n          \"format\": \"float\"\n        },\n        \"include_full_name_in_path\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"incremental_strategy\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"kms_key_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"labels\": true,\n        \"location\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"location_root\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"materialized\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"meta\": true,\n        \"on_configuration_change\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/OnConfigurationChange\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"on_schema_change\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/OnSchemaChange\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"persist_docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/PersistDocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"post-hook\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Hooks\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"pre-hook\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Hooks\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"query_tag\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"schema\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"secure\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"snowflake_warehouse\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"sql_header\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"table_format\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"target_lag\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"tblproperties\": true,\n        \"transient\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      }\n    },\n    \"OnConfigurationChange\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"apply\",\n        \"continue\",\n        \"fail\"\n      ]\n    },\n    \"OnSchemaChange\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"append_new_columns\",\n        \"fail\",\n        \"ignore\",\n        \"sync_all_columns\"\n      ]\n    },\n    \"PersistDocsConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"columns\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"relation\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      }\n    },\n    \"QueryComment\": {\n      \"anyOf\": [\n        {\n          \"type\": \"string\"\n        },\n        true\n      ]\n    },\n    \"SavedQueriesConfigs\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"+schema\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      }\n    },\n    \"SeedConfigs\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"+column_types\": true,\n        \"+copy_grants\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+database\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+enabled\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+full_refresh\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+grants\": true,\n        \"+group\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+meta\": true,\n        \"+persist_docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/PersistDocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+post-hook\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Hooks\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+pre-hook\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Hooks\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+quote_columns\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+schema\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+snowflake_warehouse\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+transient\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"column_types\": true,\n        \"copy_grants\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"database\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"delimiter\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"enabled\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"full_refresh\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"grants\": true,\n        \"group\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"meta\": true,\n        \"persist_docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/PersistDocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"post-hook\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Hooks\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"pre-hook\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Hooks\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"quote_columns\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"snowflake_warehouse\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"transient\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": true\n    },\n    \"Severity\": {\n      \"anyOf\": [\n        {\n          \"type\": \"string\"\n        },\n        {\n          \"type\": \"string\"\n        }\n      ]\n    },\n    \"SnapshotConfigs\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"+alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+check_cols\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+enabled\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+grants\": true,\n        \"+group\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+invalidate_hard_deletes\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+meta\": true,\n        \"+persist_docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/PersistDocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+post-hook\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Hooks\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+pre-hook\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Hooks\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+quote_columns\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+snapshot_meta_column_names\": true,\n        \"+strategy\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+target_database\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+target_schema\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"+transient\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+unique_key\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+updated_at\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"__additional_properties__\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"check_cols\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"enabled\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"grants\": true,\n        \"group\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"invalidate_hard_deletes\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"meta\": true,\n        \"persist_docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/PersistDocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"post-hook\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Hooks\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"pre-hook\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Hooks\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"quote_columns\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"snapshot_meta_column_names\": true,\n        \"strategy\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"target_database\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"target_schema\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"transient\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"unique_key\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"updated_at\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      }\n    },\n    \"SourceConfigs\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"+enabled\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+meta\": true,\n        \"+tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"enabled\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"meta\": true,\n        \"tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": true\n    },\n    \"StringOrArrayOfStrings\": {\n      \"anyOf\": [\n        {\n          \"type\": \"string\"\n        },\n        {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        }\n      ]\n    },\n    \"StringOrVecString\": {\n      \"anyOf\": [\n        {\n          \"type\": \"string\"\n        },\n        {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        }\n      ]\n    },\n    \"UnitTestConfigs\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"+enabled\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"+meta\": true,\n        \"+tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"enabled\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"meta\": true,\n        \"tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": true\n    },\n    \"_Dispatch\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"macro_namespace\",\n        \"search_order\"\n      ],\n      \"properties\": {\n        \"macro_namespace\": {\n          \"type\": \"string\"\n        },\n        \"search_order\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "core/dbt/jsonschemas/resources/0.0.110.json",
    "content": "{\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n  \"title\": \"DbtPropertiesFile\",\n  \"type\": \"object\",\n  \"additionalProperties\": false,\n  \"properties\": {\n    \"analyses\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/_Analyses\"\n      }\n    },\n    \"exposures\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/_Exposures\"\n      }\n    },\n    \"groups\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/_Groups\"\n      }\n    },\n    \"macros\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/_Macros\"\n      }\n    },\n    \"metrics\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/_Metrics\"\n      }\n    },\n    \"models\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/_Models\"\n      }\n    },\n    \"saved_queries\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/_SavedQueries\"\n      }\n    },\n    \"seeds\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/_Seeds\"\n      }\n    },\n    \"semantic_models\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/_SemanticModels\"\n      }\n    },\n    \"snapshots\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/_Snapshots\"\n      }\n    },\n    \"sources\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/_Sources\"\n      }\n    },\n    \"unit_tests\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/_UnitTests\"\n      }\n    },\n    \"version\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/FloatOrString\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    }\n  },\n  \"definitions\": {\n    \"AcceptedValuesTest\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"accepted_values\"\n      ],\n      \"properties\": {\n        \"accepted_values\": true\n      }\n    },\n    \"AggregationTypeParams\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"percentile\": {\n          \"type\": [\n            \"number\",\n            \"null\"\n          ],\n          \"format\": \"float\"\n        },\n        \"use_approximate_percentile\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"use_discrete_percentile\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        }\n      }\n    },\n    \"AnyValue\": true,\n    \"BooleanOrJinjaString\": {\n      \"anyOf\": [\n        {\n          \"type\": \"string\"\n        },\n        {\n          \"type\": \"boolean\"\n        }\n      ]\n    },\n    \"ColumnProperties\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"constraints\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": true\n        },\n        \"data_tests\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/DataTests\"\n          }\n        },\n        \"data_type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"granularity\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/_ColumnPropertiesGranularity\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"meta\": true,\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"policy_tags\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"quote\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tests\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/DataTests\"\n          }\n        }\n      }\n    },\n    \"CustomGranularity\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"column_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"DataTests\": {\n      \"anyOf\": [\n        {\n          \"type\": \"string\"\n        },\n        {\n          \"$ref\": \"#/definitions/UniqueTest\"\n        },\n        {\n          \"$ref\": \"#/definitions/NotNullTest\"\n        },\n        {\n          \"$ref\": \"#/definitions/RelationshipsTest\"\n        },\n        {\n          \"$ref\": \"#/definitions/AcceptedValuesTest\"\n        },\n        true\n      ]\n    },\n    \"Dimension\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\",\n        \"type\"\n      ],\n      \"properties\": {\n        \"config\": true,\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"expr\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/_DimensionExpr\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"is_partition\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"label\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"type\": {\n          \"$ref\": \"#/definitions/_DimensionType_\"\n        },\n        \"type_params\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DimensionTypeParams\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      }\n    },\n    \"DimensionTypeParams\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"time_granularity\"\n      ],\n      \"properties\": {\n        \"time_granularity\": {\n          \"type\": \"string\"\n        },\n        \"validity_params\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/ValidityParams\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      }\n    },\n    \"DocsConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"node_color\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"show\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        }\n      }\n    },\n    \"Entity\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\",\n        \"type\"\n      ],\n      \"properties\": {\n        \"config\": true,\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"entity\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"expr\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/_EntityExpr\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"label\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"type\": {\n          \"$ref\": \"#/definitions/_EntityType_\"\n        }\n      }\n    },\n    \"Export\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/_ExportConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"ExposurePropertiesConfigs\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"properties\": {\n        \"enabled\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"meta\": true\n      }\n    },\n    \"FloatOrString\": {\n      \"anyOf\": [\n        {\n          \"type\": \"number\",\n          \"format\": \"float\"\n        },\n        {\n          \"type\": \"string\"\n        }\n      ]\n    },\n    \"FreshnessDefinition\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"error_after\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/FreshnessRules\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"warn_after\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/FreshnessRules\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      }\n    },\n    \"FreshnessPeriod\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"minute\",\n        \"hour\",\n        \"day\"\n      ]\n    },\n    \"FreshnessRules\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"count\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/NumberOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"period\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/FreshnessPeriod\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      }\n    },\n    \"HookConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"sql\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"transaction\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        }\n      }\n    },\n    \"Hooks\": {\n      \"anyOf\": [\n        {\n          \"type\": \"string\"\n        },\n        {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        {\n          \"$ref\": \"#/definitions/HookConfig\"\n        },\n        {\n          \"type\": \"array\",\n          \"items\": true\n        }\n      ]\n    },\n    \"Measure\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"agg\",\n        \"name\"\n      ],\n      \"properties\": {\n        \"agg\": {\n          \"$ref\": \"#/definitions/_MeasureAgg\"\n        },\n        \"agg_params\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/AggregationTypeParams\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"agg_time_dimension\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"config\": true,\n        \"create_metric\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"create_metric_display_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"expr\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/_MeasureExpr\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"label\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"non_additive_dimension\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/NonAdditiveDimension\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      }\n    },\n    \"ModelPropertiesConfigs\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"properties\": {\n        \"auto_refresh\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"backup\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"batch_size\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"begin\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"contract\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/_ModelPropertiesConfigsContract\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"enabled\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"event_time\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"file_format\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"grant_access_to\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/_GrantAccessTo\"\n          }\n        },\n        \"grants\": true,\n        \"group\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"hours_to_expiration\": {\n          \"type\": [\n            \"number\",\n            \"null\"\n          ],\n          \"format\": \"float\"\n        },\n        \"include_full_name_in_path\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"incremental_strategy\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"kms_key_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"labels\": true,\n        \"location\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"location_root\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"lookback\": {\n          \"type\": [\n            \"number\",\n            \"null\"\n          ],\n          \"format\": \"float\"\n        },\n        \"materialized\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"meta\": true,\n        \"on_configuration_change\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"on_schema_change\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"snowflake_warehouse\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"sql_header\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"table_format\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"target_lag\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"tblproperties\": true,\n        \"unique_key\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      }\n    },\n    \"NonAdditiveDimension\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"window_choice\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/_NonAdditiveDimensionWindowChoice\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"window_groupings\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"type\": \"string\"\n          }\n        }\n      }\n    },\n    \"NotNullTest\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"not_null\"\n      ],\n      \"properties\": {\n        \"not_null\": true\n      }\n    },\n    \"NumberOrJinjaString\": {\n      \"anyOf\": [\n        {\n          \"type\": \"string\"\n        },\n        {\n          \"type\": \"integer\",\n          \"format\": \"int32\"\n        }\n      ]\n    },\n    \"PersistDocsConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"columns\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"relation\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      }\n    },\n    \"RelationshipsTest\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"relationships\"\n      ],\n      \"properties\": {\n        \"relationships\": true\n      }\n    },\n    \"StringOrArrayOfStrings\": {\n      \"anyOf\": [\n        {\n          \"type\": \"string\"\n        },\n        {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        }\n      ]\n    },\n    \"UniqueTest\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"unique\"\n      ],\n      \"properties\": {\n        \"unique\": true\n      }\n    },\n    \"ValidityParams\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"is_end\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"is_start\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        }\n      }\n    },\n    \"_Analyses\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"columns\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/_Columns\"\n          }\n        },\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/__AnalysesConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"group\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"_Arguments\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      }\n    },\n    \"_ColumnPropertiesGranularity\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"nanosecond\",\n        \"microsecond\",\n        \"millisecond\",\n        \"second\",\n        \"minute\",\n        \"hour\",\n        \"day\",\n        \"week\",\n        \"month\",\n        \"quarter\",\n        \"year\"\n      ]\n    },\n    \"_Columns\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"data_type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"_DimensionExpr\": {\n      \"anyOf\": [\n        {\n          \"type\": \"string\"\n        },\n        {\n          \"type\": \"boolean\"\n        }\n      ]\n    },\n    \"_DimensionType_\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"CATEGORICAL\",\n        \"TIME\",\n        \"categorical\",\n        \"time\"\n      ]\n    },\n    \"_EntityExpr\": {\n      \"anyOf\": [\n        {\n          \"type\": \"string\"\n        },\n        {\n          \"type\": \"boolean\"\n        }\n      ]\n    },\n    \"_EntityType_\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"PRIMARY\",\n        \"UNIQUE\",\n        \"FOREIGN\",\n        \"NATURAL\",\n        \"primary\",\n        \"unique\",\n        \"foreign\",\n        \"natural\"\n      ]\n    },\n    \"_ExportConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"export_as\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/__ExportConfigExportAs\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": true\n    },\n    \"_Exposures\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\",\n        \"owner\",\n        \"type\"\n      ],\n      \"additionalProperties\": false,\n      \"properties\": {\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/ExposurePropertiesConfigs\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"depends_on\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"label\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"maturity\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"meta\": true,\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"owner\": {\n          \"$ref\": \"#/definitions/__ExposuresOwner\"\n        },\n        \"tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"type\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      }\n    },\n    \"_Given\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"fixture\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"format\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"input\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"rows\": true\n      }\n    },\n    \"_GrantAccessTo\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"dataset\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"project\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      }\n    },\n    \"_Groups\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\",\n        \"owner\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"owner\": {\n          \"$ref\": \"#/definitions/__GroupsOwner\"\n        }\n      }\n    },\n    \"_Macros\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"additionalProperties\": false,\n      \"properties\": {\n        \"arguments\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/_Arguments\"\n          }\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"_MeasureAgg\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"SUM\",\n        \"MIN\",\n        \"MAX\",\n        \"AVERAGE\",\n        \"COUNT_DISTINCT\",\n        \"SUM_BOOLEAN\",\n        \"COUNT\",\n        \"PERCENTILE\",\n        \"MEDIAN\",\n        \"sum\",\n        \"min\",\n        \"max\",\n        \"average\",\n        \"count_distinct\",\n        \"sum_boolean\",\n        \"count\",\n        \"percentile\",\n        \"median\"\n      ]\n    },\n    \"_MeasureExpr\": {\n      \"anyOf\": [\n        {\n          \"type\": \"string\"\n        },\n        {\n          \"type\": \"integer\",\n          \"format\": \"int32\"\n        },\n        {\n          \"type\": \"boolean\"\n        }\n      ]\n    },\n    \"_Metrics\": {\n      \"type\": \"object\"\n    },\n    \"_ModelPropertiesConfigsContract\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"alias_types\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"enforced\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      }\n    },\n    \"_Models\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"additionalProperties\": false,\n      \"properties\": {\n        \"access\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"columns\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/ColumnProperties\"\n          }\n        },\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/ModelPropertiesConfigs\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"constraints\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": true\n        },\n        \"data_tests\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/DataTests\"\n          }\n        },\n        \"deprecation_date\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"group\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"identifier\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"latest_version\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/FloatOrString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"meta\": true,\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"tests\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/DataTests\"\n          }\n        },\n        \"time_spine\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/__ModelsTimeSpine\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"versions\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/_Versions\"\n          }\n        }\n      }\n    },\n    \"_NonAdditiveDimensionWindowChoice\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"MIN\",\n        \"MAX\",\n        \"min\",\n        \"max\"\n      ]\n    },\n    \"_SavedQueries\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\",\n        \"query_params\"\n      ],\n      \"additionalProperties\": false,\n      \"properties\": {\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/__SavedQueriesConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"exports\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/Export\"\n          }\n        },\n        \"label\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"query_params\": {\n          \"$ref\": \"#/definitions/__SavedQueriesQueryParams\"\n        }\n      }\n    },\n    \"_Seeds\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"additionalProperties\": false,\n      \"properties\": {\n        \"columns\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/ColumnProperties\"\n          }\n        },\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/__SeedsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"data_tests\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/DataTests\"\n          }\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"group\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"tests\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/DataTests\"\n          }\n        }\n      }\n    },\n    \"_SemanticModels\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"model\",\n        \"name\"\n      ],\n      \"additionalProperties\": false,\n      \"properties\": {\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/ModelPropertiesConfigs\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"defaults\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/__SemanticModelsDefaults\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"dimensions\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/Dimension\"\n          }\n        },\n        \"entities\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/Entity\"\n          }\n        },\n        \"label\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"measures\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/Measure\"\n          }\n        },\n        \"model\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"primary_entity\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      }\n    },\n    \"_Snapshots\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"additionalProperties\": false,\n      \"properties\": {\n        \"columns\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/ColumnProperties\"\n          }\n        },\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/__SnapshotsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"data_tests\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/DataTests\"\n          }\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"group\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"meta\": true,\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"relation\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"tests\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/DataTests\"\n          }\n        }\n      }\n    },\n    \"_Sources\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"additionalProperties\": false,\n      \"properties\": {\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/__SourcesConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"database\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"freshness\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/FreshnessDefinition\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"loaded_at_field\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"loaded_at_query\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"loader\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"meta\": true,\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"overrides\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"quoting\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/__SourcesQuoting\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"tables\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/_Tables\"\n          }\n        },\n        \"tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      }\n    },\n    \"_Tables\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"additionalProperties\": false,\n      \"properties\": {\n        \"columns\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/ColumnProperties\"\n          }\n        },\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/__TablesConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"data_tests\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/DataTests\"\n          }\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"external\": true,\n        \"freshness\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/FreshnessDefinition\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"identifier\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"loaded_at_field\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"loaded_at_query\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"loader\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"meta\": true,\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"quoting\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/__TablesQuoting\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tests\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/DataTests\"\n          }\n        }\n      }\n    },\n    \"_UnitTests\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"expect\",\n        \"model\",\n        \"name\"\n      ],\n      \"additionalProperties\": false,\n      \"properties\": {\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/__UnitTestsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"expect\": {\n          \"$ref\": \"#/definitions/__UnitTestsExpect\"\n        },\n        \"given\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/_Given\"\n          }\n        },\n        \"model\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"overrides\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/__UnitTestsOverrides\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"versions\": true\n      }\n    },\n    \"_Versions\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"v\"\n      ],\n      \"properties\": {\n        \"v\": true\n      },\n      \"additionalProperties\": true\n    },\n    \"__AnalysesConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      }\n    },\n    \"__ExportConfigExportAs\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"table\",\n        \"view\",\n        \"cache\"\n      ]\n    },\n    \"__ExposuresOwner\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"email\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      }\n    },\n    \"__GroupsOwner\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"email\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": true\n    },\n    \"__ModelsTimeSpine\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"standard_granularity_column\"\n      ],\n      \"properties\": {\n        \"custom_granularities\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/CustomGranularity\"\n          }\n        },\n        \"standard_granularity_column\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"__SavedQueriesConfig\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"properties\": {\n        \"cache\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/___SavedQueriesConfigCache\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"enabled\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"meta\": true\n      }\n    },\n    \"__SavedQueriesQueryParams\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"dimensions\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"group_by\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"metrics\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"where\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"type\": \"string\"\n          }\n        }\n      }\n    },\n    \"__SeedsConfig\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"properties\": {\n        \"column_types\": true,\n        \"copy_grants\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"database\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"enabled\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"grants\": true,\n        \"quote_columns\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      }\n    },\n    \"__SemanticModelsDefaults\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"agg_time_dimension\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      }\n    },\n    \"__SnapshotsConfig\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"properties\": {\n        \"alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"check_cols\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"dbt_valid_to_current\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"enabled\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"grants\": true,\n        \"meta\": true,\n        \"persist_docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/PersistDocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"post-hook\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Hooks\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"pre-hook\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Hooks\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"quote_columns\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"snapshot_meta_column_names\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/___SnapshotsConfigSnapshotMetaColumnNames\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"strategy\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"target_database\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"target_schema\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"unique_key\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"updated_at\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      }\n    },\n    \"__SourcesConfig\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"properties\": {\n        \"enabled\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"event_time\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      }\n    },\n    \"__SourcesQuoting\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"database\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"identifier\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      }\n    },\n    \"__TablesConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"event_time\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": true\n    },\n    \"__TablesQuoting\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"database\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"identifier\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      }\n    },\n    \"__UnitTestsConfig\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"properties\": {\n        \"enabled\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"meta\": true,\n        \"tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      }\n    },\n    \"__UnitTestsExpect\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"fixture\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"format\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"rows\": true\n      }\n    },\n    \"__UnitTestsOverrides\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"env_vars\": true,\n        \"macros\": true,\n        \"vars\": true\n      }\n    },\n    \"___SavedQueriesConfigCache\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"enabled\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      }\n    },\n    \"___SnapshotsConfigSnapshotMetaColumnNames\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"dbt_scd_id\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"dbt_updated_at\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"dbt_valid_from\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"dbt_valid_to\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "core/dbt/jsonschemas/resources/0.0.85.json",
    "content": "{\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n  \"title\": \"DbtSchemaFiles\",\n  \"type\": \"object\",\n  \"additionalProperties\": false,\n  \"properties\": {\n    \"analyses\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/_Analyses\"\n      }\n    },\n    \"exposures\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/_Exposures\"\n      }\n    },\n    \"groups\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/_Groups\"\n      }\n    },\n    \"macros\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/_Macros\"\n      }\n    },\n    \"metrics\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/_Metrics\"\n      }\n    },\n    \"models\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/_Models\"\n      }\n    },\n    \"saved_queries\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/_SavedQueries\"\n      }\n    },\n    \"seeds\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/_Seeds\"\n      }\n    },\n    \"semantic_models\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/_SemanticModels\"\n      }\n    },\n    \"snapshots\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/_Snapshots\"\n      }\n    },\n    \"sources\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/_Sources\"\n      }\n    },\n    \"unit_tests\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/_UnitTests\"\n      }\n    },\n    \"version\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/FloatOrString\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    }\n  },\n  \"definitions\": {\n    \"AcceptedValuesTest\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"accepted_values\"\n      ],\n      \"properties\": {\n        \"accepted_values\": true\n      }\n    },\n    \"AggregationTypeParams\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"percentile\": {\n          \"type\": [\n            \"number\",\n            \"null\"\n          ],\n          \"format\": \"float\"\n        },\n        \"use_approximate_percentile\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"use_discrete_percentile\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        }\n      }\n    },\n    \"AnyValue\": true,\n    \"BooleanOrJinjaString\": {\n      \"anyOf\": [\n        {\n          \"type\": \"string\"\n        },\n        {\n          \"type\": \"boolean\"\n        }\n      ]\n    },\n    \"ColumnProperties\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"constraints\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": true\n        },\n        \"data_tests\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/DataTests\"\n          }\n        },\n        \"data_type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"granularity\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/_ColumnPropertiesGranularity\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"meta\": true,\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"policy_tags\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"quote\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tests\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/DataTests\"\n          }\n        }\n      }\n    },\n    \"CustomGranularity\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"column_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"DataTests\": {\n      \"anyOf\": [\n        {\n          \"type\": \"string\"\n        },\n        {\n          \"$ref\": \"#/definitions/UniqueTest\"\n        },\n        {\n          \"$ref\": \"#/definitions/NotNullTest\"\n        },\n        {\n          \"$ref\": \"#/definitions/RelationshipsTest\"\n        },\n        {\n          \"$ref\": \"#/definitions/AcceptedValuesTest\"\n        },\n        true\n      ]\n    },\n    \"Dimension\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\",\n        \"type\"\n      ],\n      \"properties\": {\n        \"config\": true,\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"expr\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/_DimensionExpr\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"is_partition\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"label\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"type\": {\n          \"$ref\": \"#/definitions/_DimensionType_\"\n        },\n        \"type_params\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DimensionTypeParams\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      }\n    },\n    \"DimensionTypeParams\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"time_granularity\"\n      ],\n      \"properties\": {\n        \"time_granularity\": {\n          \"type\": \"string\"\n        },\n        \"validity_params\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/ValidityParams\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      }\n    },\n    \"DocsConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"node_color\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"show\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        }\n      }\n    },\n    \"Entity\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\",\n        \"type\"\n      ],\n      \"properties\": {\n        \"config\": true,\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"entity\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"expr\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/_EntityExpr\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"label\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"type\": {\n          \"$ref\": \"#/definitions/_EntityType_\"\n        }\n      }\n    },\n    \"Export\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/_ExportConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"ExposurePropertiesConfigs\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"properties\": {\n        \"enabled\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"meta\": true\n      }\n    },\n    \"FloatOrString\": {\n      \"anyOf\": [\n        {\n          \"type\": \"number\",\n          \"format\": \"float\"\n        },\n        {\n          \"type\": \"string\"\n        }\n      ]\n    },\n    \"FreshnessDefinition\": {\n      \"anyOf\": [\n        true\n      ]\n    },\n    \"HookConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"sql\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"transaction\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        }\n      }\n    },\n    \"Hooks\": {\n      \"anyOf\": [\n        {\n          \"type\": \"string\"\n        },\n        {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        {\n          \"$ref\": \"#/definitions/HookConfig\"\n        },\n        {\n          \"type\": \"array\",\n          \"items\": true\n        }\n      ]\n    },\n    \"Measure\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"agg\",\n        \"name\"\n      ],\n      \"properties\": {\n        \"agg\": {\n          \"$ref\": \"#/definitions/_MeasureAgg\"\n        },\n        \"agg_params\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/AggregationTypeParams\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"agg_time_dimension\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"config\": true,\n        \"create_metric\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"create_metric_display_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"expr\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/_MeasureExpr\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"label\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"non_additive_dimension\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/NonAdditiveDimension\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      }\n    },\n    \"ModelPropertiesConfigs\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"properties\": {\n        \"auto_refresh\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"backup\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"batch_size\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"begin\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"contract\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/_ModelPropertiesConfigsContract\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"enabled\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"event_time\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"file_format\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"grant_access_to\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/_GrantAccessTo\"\n          }\n        },\n        \"grants\": true,\n        \"group\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"hours_to_expiration\": {\n          \"type\": [\n            \"number\",\n            \"null\"\n          ],\n          \"format\": \"float\"\n        },\n        \"include_full_name_in_path\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"incremental_strategy\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"kms_key_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"labels\": true,\n        \"location\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"location_root\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"lookback\": {\n          \"type\": [\n            \"number\",\n            \"null\"\n          ],\n          \"format\": \"float\"\n        },\n        \"materialized\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"meta\": true,\n        \"on_configuration_change\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"on_schema_change\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"snowflake_warehouse\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"sql_header\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"table_format\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"target_lag\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"tblproperties\": true,\n        \"unique_key\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      }\n    },\n    \"NonAdditiveDimension\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"window_choice\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/_NonAdditiveDimensionWindowChoice\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"window_groupings\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"type\": \"string\"\n          }\n        }\n      }\n    },\n    \"NotNullTest\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"not_null\"\n      ],\n      \"properties\": {\n        \"not_null\": true\n      }\n    },\n    \"PersistDocsConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"columns\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"relation\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      }\n    },\n    \"RelationshipsTest\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"relationships\"\n      ],\n      \"properties\": {\n        \"relationships\": true\n      }\n    },\n    \"StringOrArrayOfStrings\": {\n      \"anyOf\": [\n        {\n          \"type\": \"string\"\n        },\n        {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        }\n      ]\n    },\n    \"UniqueTest\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"unique\"\n      ],\n      \"properties\": {\n        \"unique\": true\n      }\n    },\n    \"ValidityParams\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"is_end\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"is_start\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        }\n      }\n    },\n    \"_Analyses\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"columns\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/_Columns\"\n          }\n        },\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/__AnalysesConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"group\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"_Arguments\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      }\n    },\n    \"_ColumnPropertiesGranularity\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"nanosecond\",\n        \"microsecond\",\n        \"millisecond\",\n        \"second\",\n        \"minute\",\n        \"hour\",\n        \"day\",\n        \"week\",\n        \"month\",\n        \"quarter\",\n        \"year\"\n      ]\n    },\n    \"_Columns\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"data_type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"_DimensionExpr\": {\n      \"anyOf\": [\n        {\n          \"type\": \"string\"\n        },\n        {\n          \"type\": \"boolean\"\n        }\n      ]\n    },\n    \"_DimensionType_\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"CATEGORICAL\",\n        \"TIME\",\n        \"categorical\",\n        \"time\"\n      ]\n    },\n    \"_EntityExpr\": {\n      \"anyOf\": [\n        {\n          \"type\": \"string\"\n        },\n        {\n          \"type\": \"boolean\"\n        }\n      ]\n    },\n    \"_EntityType_\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"PRIMARY\",\n        \"UNIQUE\",\n        \"FOREIGN\",\n        \"NATURAL\",\n        \"primary\",\n        \"unique\",\n        \"foreign\",\n        \"natural\"\n      ]\n    },\n    \"_ExportConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"export_as\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/__ExportConfigExportAs\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": true\n    },\n    \"_Exposures\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"required\": [\n        \"name\",\n        \"owner\",\n        \"type\"\n      ],\n      \"properties\": {\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/ExposurePropertiesConfigs\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"depends_on\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"label\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"maturity\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"meta\": true,\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"owner\": {\n          \"$ref\": \"#/definitions/__ExposuresOwner\"\n        },\n        \"tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"type\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      }\n    },\n    \"_Given\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"fixture\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"format\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"input\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"rows\": true\n      }\n    },\n    \"_GrantAccessTo\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"dataset\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"project\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      }\n    },\n    \"_Groups\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\",\n        \"owner\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"owner\": {\n          \"$ref\": \"#/definitions/__GroupsOwner\"\n        }\n      }\n    },\n    \"_Macros\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"arguments\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/_Arguments\"\n          }\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"_MeasureAgg\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"SUM\",\n        \"MIN\",\n        \"MAX\",\n        \"AVERAGE\",\n        \"COUNT_DISTINCT\",\n        \"SUM_BOOLEAN\",\n        \"COUNT\",\n        \"PERCENTILE\",\n        \"MEDIAN\",\n        \"sum\",\n        \"min\",\n        \"max\",\n        \"average\",\n        \"count_distinct\",\n        \"sum_boolean\",\n        \"count\",\n        \"percentile\",\n        \"median\"\n      ]\n    },\n    \"_MeasureExpr\": {\n      \"anyOf\": [\n        {\n          \"type\": \"string\"\n        },\n        {\n          \"type\": \"integer\",\n          \"format\": \"int32\"\n        },\n        {\n          \"type\": \"boolean\"\n        }\n      ]\n    },\n    \"_Metrics\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"__additional_properties__\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        }\n      }\n    },\n    \"_ModelPropertiesConfigsContract\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"alias_types\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"enforced\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      }\n    },\n    \"_Models\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"access\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"columns\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/ColumnProperties\"\n          }\n        },\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/ModelPropertiesConfigs\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"constraints\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": true\n        },\n        \"data_tests\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/DataTests\"\n          }\n        },\n        \"deprecation_date\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"group\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"identifier\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"latest_version\": {\n          \"type\": [\n            \"number\",\n            \"null\"\n          ],\n          \"format\": \"float\"\n        },\n        \"meta\": true,\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"tests\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/DataTests\"\n          }\n        },\n        \"time_spine\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/__ModelsTimeSpine\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"versions\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/_Versions\"\n          }\n        }\n      }\n    },\n    \"_NonAdditiveDimensionWindowChoice\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"MIN\",\n        \"MAX\",\n        \"min\",\n        \"max\"\n      ]\n    },\n    \"_SavedQueries\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"required\": [\n        \"name\",\n        \"query_params\"\n      ],\n      \"properties\": {\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/__SavedQueriesConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"exports\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/Export\"\n          }\n        },\n        \"label\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"query_params\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"dimensions\": {\n              \"type\": [\n                \"array\",\n                \"null\"\n              ],\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            \"group_by\": {\n              \"type\": [\n                \"array\",\n                \"null\"\n              ],\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            \"metrics\": {\n              \"type\": [\n                \"array\",\n                \"null\"\n              ],\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            \"where\": {\n              \"type\": [\n                \"array\",\n                \"null\"\n              ],\n              \"items\": {\n                \"type\": \"string\"\n              }\n            }\n          }\n        }\n      }\n    },\n    \"_Seeds\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"columns\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/ColumnProperties\"\n          }\n        },\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/__SeedsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"data_tests\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/DataTests\"\n          }\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"group\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"tests\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/DataTests\"\n          }\n        }\n      }\n    },\n    \"_SemanticModels\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"required\": [\n        \"model\",\n        \"name\"\n      ],\n      \"properties\": {\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/ModelPropertiesConfigs\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"defaults\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/__SemanticModelsDefaults\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"dimensions\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/Dimension\"\n          }\n        },\n        \"entities\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/Entity\"\n          }\n        },\n        \"label\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"measures\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/Measure\"\n          }\n        },\n        \"model\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"primary_entity\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      }\n    },\n    \"_Snapshots\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"columns\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/ColumnProperties\"\n          }\n        },\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/__SnapshotsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"data_tests\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/DataTests\"\n          }\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"group\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"meta\": true,\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"relation\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"tests\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/DataTests\"\n          }\n        }\n      }\n    },\n    \"_Sources\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"config\": true,\n        \"database\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"freshness\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/FreshnessDefinition\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"loaded_at_field\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"loaded_at_query\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"loader\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"meta\": true,\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"overrides\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"quoting\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/__SourcesQuoting\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"tables\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/_Tables\"\n          }\n        },\n        \"tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      }\n    },\n    \"_Tables\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"columns\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/ColumnProperties\"\n          }\n        },\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/__TablesConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"data_tests\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/DataTests\"\n          }\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"external\": true,\n        \"freshness\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/FreshnessDefinition\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"identifier\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"loaded_at_field\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"loaded_at_query\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"loader\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"meta\": true,\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"quoting\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/__TablesQuoting\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tests\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/DataTests\"\n          }\n        }\n      }\n    },\n    \"_UnitTests\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"required\": [\n        \"expect\",\n        \"model\",\n        \"name\"\n      ],\n      \"properties\": {\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/__UnitTestsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"expect\": {\n          \"$ref\": \"#/definitions/__UnitTestsExpect\"\n        },\n        \"given\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/_Given\"\n          }\n        },\n        \"model\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"overrides\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/__UnitTestsOverrides\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"versions\": true\n      }\n    },\n    \"_Versions\": {\n      \"type\": \"object\",\n      \"additionalProperties\": true\n    },\n    \"__AnalysesConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      }\n    },\n    \"__ExportConfigExportAs\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"table\",\n        \"view\",\n        \"cache\"\n      ]\n    },\n    \"__ExposuresOwner\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"email\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      }\n    },\n    \"__GroupsOwner\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"email\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": true\n    },\n    \"__ModelsTimeSpine\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"standard_granularity_column\"\n      ],\n      \"properties\": {\n        \"custom_granularities\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/CustomGranularity\"\n          }\n        },\n        \"standard_granularity_column\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"__SavedQueriesConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"cache\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/___SavedQueriesConfigCache\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"enabled\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"meta\": true\n      },\n      \"additionalProperties\": false\n    },\n    \"__SeedsConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"column_types\": true,\n        \"copy_grants\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"database\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"enabled\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"grants\": true,\n        \"quote_columns\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      }\n    },\n    \"__SemanticModelsDefaults\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"agg_time_dimension\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      }\n    },\n    \"__SnapshotsConfig\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"properties\": {\n        \"alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"check_cols\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"dbt_valid_to_current\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"enabled\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"grants\": true,\n        \"meta\": true,\n        \"persist_docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/PersistDocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"post-hook\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Hooks\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"pre-hook\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Hooks\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"quote_columns\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"snapshot_meta_column_names\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/___SnapshotsConfigSnapshotMetaColumnNames\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"strategy\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"target_database\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"target_schema\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"unique_key\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"updated_at\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      }\n    },\n    \"__SourcesQuoting\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"database\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"identifier\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      }\n    },\n    \"__TablesConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"event_time\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": true\n    },\n    \"__TablesQuoting\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"database\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"identifier\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      }\n    },\n    \"__UnitTestsConfig\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"properties\": {\n        \"enabled\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"meta\": true,\n        \"tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      }\n    },\n    \"__UnitTestsExpect\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"fixture\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"format\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"rows\": true\n      }\n    },\n    \"__UnitTestsOverrides\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"env_vars\": true,\n        \"macros\": true,\n        \"vars\": true\n      }\n    },\n    \"___SavedQueriesConfigCache\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"enabled\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/BooleanOrJinjaString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      }\n    },\n    \"___SnapshotsConfigSnapshotMetaColumnNames\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"dbt_scd_id\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"dbt_updated_at\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"dbt_valid_from\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"dbt_valid_to\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "core/dbt/jsonschemas/resources/latest.json",
    "content": "{\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n  \"title\": \"DbtPropertiesFile\",\n  \"type\": \"object\",\n  \"properties\": {\n    \"analyses\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/AnalysesProperties\"\n      }\n    },\n    \"anchors\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/AnyValue\"\n      }\n    },\n    \"data_tests\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/DataTestProperties\"\n      }\n    },\n    \"exposures\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/ExposureProperties\"\n      }\n    },\n    \"functions\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/FunctionProperties\"\n      }\n    },\n    \"groups\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/GroupProperties\"\n      }\n    },\n    \"macros\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/MacrosProperties\"\n      }\n    },\n    \"metrics\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/MetricsProperties\"\n      }\n    },\n    \"models\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/ModelProperties\"\n      }\n    },\n    \"saved_queries\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/SavedQueriesProperties\"\n      }\n    },\n    \"seeds\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/SeedProperties\"\n      }\n    },\n    \"semantic_models\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/AnyValue\"\n      }\n    },\n    \"snapshots\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/SnapshotProperties\"\n      }\n    },\n    \"sources\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/SourceProperties\"\n      }\n    },\n    \"tests\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/DataTestProperties\"\n      }\n    },\n    \"unit_tests\": {\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/UnitTestProperties\"\n      }\n    },\n    \"version\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/FloatOrString\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    }\n  },\n  \"additionalProperties\": false,\n  \"definitions\": {\n    \"Access\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"private\",\n        \"protected\",\n        \"public\"\n      ]\n    },\n    \"AggregationType\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"sum\",\n        \"min\",\n        \"max\",\n        \"count_distinct\",\n        \"sum_boolean\",\n        \"average\",\n        \"percentile\",\n        \"median\",\n        \"count\"\n      ]\n    },\n    \"AnalysesConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"enabled\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"group\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"meta\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"static_analysis\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StaticAnalysisKind\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"AnalysesProperties\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"columns\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/ColumnProperties\"\n          }\n        },\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/AnalysesConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"static_analysis_off_reason\": {\n          \"readOnly\": true,\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StaticAnalysisOffReason\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"AnyValue\": true,\n    \"BigqueryPartitionConfig\": {\n      \"description\": \"reference: https://github.com/dbt-labs/dbt-adapters/blob/main/dbt-bigquery/src/dbt/adapters/bigquery/relation_configs/_partition.py#L12-L13\",\n      \"type\": \"object\",\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/RangeConfig\"\n        },\n        {\n          \"$ref\": \"#/definitions/TimeConfig\"\n        }\n      ],\n      \"required\": [\n        \"field\"\n      ],\n      \"properties\": {\n        \"copy_partitions\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"data_type\": {\n          \"default\": \"date\",\n          \"type\": \"string\"\n        },\n        \"field\": {\n          \"type\": \"string\"\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"ClusterConfig\": {\n      \"description\": \"Configuration for cluster by columns.\\n\\ndbt-core allows either of the variants for the `cluster_by` to allow cluster on a single column or on multiple columns\",\n      \"anyOf\": [\n        {\n          \"type\": \"string\"\n        },\n        {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        }\n      ]\n    },\n    \"ColumnConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"databricks_tags\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"meta\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"ColumnMask\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"function\"\n      ],\n      \"properties\": {\n        \"function\": {\n          \"type\": \"string\"\n        },\n        \"using_columns\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"ColumnProperties\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"column_mask\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/ColumnMask\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/ColumnConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"constraints\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/Constraint\"\n          }\n        },\n        \"data_tests\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/DataTests\"\n          }\n        },\n        \"data_type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"databricks_tags\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"dimension\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/ColumnPropertiesDimension\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"entity\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Entity\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"granularity\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Granularity\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"policy_tags\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"quote\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"tests\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/DataTests\"\n          }\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"ColumnPropertiesDimension\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/ColumnPropertiesDimensionConfig\"\n        },\n        {\n          \"$ref\": \"#/definitions/ColumnPropertiesDimensionType\"\n        }\n      ]\n    },\n    \"ColumnPropertiesDimensionConfig\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"type\"\n      ],\n      \"properties\": {\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/SemanticLayerElementConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"is_partition\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"label\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"type\": {\n          \"$ref\": \"#/definitions/ColumnPropertiesDimensionType\"\n        },\n        \"validity_params\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DimensionValidityParams\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"ColumnPropertiesDimensionType\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"categorical\",\n        \"time\"\n      ]\n    },\n    \"ColumnPropertiesEntityType\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"foreign\",\n        \"natural\",\n        \"primary\",\n        \"unique\"\n      ]\n    },\n    \"ConstantProperty\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"base_property\",\n        \"conversion_property\"\n      ],\n      \"properties\": {\n        \"base_property\": {\n          \"type\": \"string\"\n        },\n        \"conversion_property\": {\n          \"type\": \"string\"\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"Constraint\": {\n      \"description\": \"Constraints (model level or column level)\",\n      \"type\": \"object\",\n      \"required\": [\n        \"type\"\n      ],\n      \"properties\": {\n        \"expression\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"to\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"to_columns\": {\n          \"description\": \"Only ForeignKey constraints accept: a list columns in that table containing the corresponding primary or unique key.\",\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"type\": {\n          \"$ref\": \"#/definitions/ConstraintType\"\n        },\n        \"warn_unenforced\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"warn_unsupported\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"ConstraintType\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"not_null\",\n        \"unique\",\n        \"primary_key\",\n        \"foreign_key\",\n        \"check\",\n        \"custom\"\n      ]\n    },\n    \"ConversionCalculationType\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"conversions\",\n        \"conversion_rate\"\n      ]\n    },\n    \"CustomTest\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/CustomTestMultiKey\"\n        },\n        {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/CustomTestInner\"\n          }\n        }\n      ]\n    },\n    \"CustomTestInner\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"arguments\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/AnyValue\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"column_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DataTestConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"CustomTestMultiKey\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"test_name\"\n      ],\n      \"properties\": {\n        \"arguments\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/AnyValue\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"column_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DataTestConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"test_name\": {\n          \"type\": \"string\"\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"DataLakeObjectCategory\": {\n      \"description\": \"See `category` from https://developer.salesforce.com/docs/data/connectapi/references/spec?meta=postDataLakeObject\",\n      \"type\": \"string\",\n      \"enum\": [\n        \"Profile\",\n        \"Engagement\",\n        \"Directory_Table\",\n        \"Insights\",\n        \"Other\"\n      ]\n    },\n    \"DataTestConfig\": {\n      \"description\": \"This configuration is a superset of all warehouse specific configurations that users can set\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"adapter_properties\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"as_columnstore\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"auto_liquid_cluster\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"auto_refresh\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"automatic_clustering\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"backup\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"base_location_root\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"base_location_subpath\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"batch_id\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"bind\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"buckets\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"int64\"\n        },\n        \"catalog\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"catalog_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"category\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DataLakeObjectCategory\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"cluster_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/ClusterConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"clustered_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compression\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"copy_grants\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"database\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"databricks_compute\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"databricks_tags\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"dataproc_cluster_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"dist\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"enable_list_inference\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"enable_refresh\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"enabled\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"error_if\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"external_volume\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"fail_calc\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"file_format\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"full_refresh\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"grant_access_to\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/GrantAccessToTarget\"\n          }\n        },\n        \"group\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"hours_to_expiration\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"include_full_name_in_path\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"indexes\": {\n          \"default\": null,\n          \"allOf\": [\n            {\n              \"$ref\": \"#/definitions/IndexesConfig\"\n            }\n          ]\n        },\n        \"initialize\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"intermediate_format\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"jar_file_uri\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"job_execution_timeout_seconds\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"kms_key_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"labels\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          }\n        },\n        \"labels_from_meta\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"limit\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"int32\"\n        },\n        \"liquid_clustered_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"location_root\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"matched_condition\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"materialized\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DbtMaterialization\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"max_staleness\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"merge_with_schema_evolution\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"meta\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"not_matched_by_source_action\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"not_matched_by_source_condition\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"not_matched_condition\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"notebook_template_id\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"partition_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/PartitionConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"partition_expiration_days\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"partitions\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"primary_key\": {\n          \"default\": null,\n          \"allOf\": [\n            {\n              \"$ref\": \"#/definitions/PrimaryKeyConfig\"\n            }\n          ]\n        },\n        \"query_tag\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/QueryTag\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"quoting\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DbtQuoting\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"refresh_interval_minutes\": {\n          \"type\": [\n            \"number\",\n            \"null\"\n          ],\n          \"format\": \"double\"\n        },\n        \"refresh_mode\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"require_partition_filter\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"resource_tags\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          }\n        },\n        \"row_access_policy\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"schedule\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Schedule\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"secure\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"severity\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Severity\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"skip_matched_step\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"skip_not_matched_step\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"snowflake_warehouse\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"sort\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"sort_type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"source_alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"sql_header\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"static_analysis\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StaticAnalysisKind\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"store_failures\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"store_failures_as\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StoreFailuresAs\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"table_tag\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"table_type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"tags\": {\n          \"default\": [],\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"target_alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"target_lag\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"tblproperties\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"timeout\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"tmp_relation_type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"transient\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"warn_if\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"where\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"DataTestProperties\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DataTestConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"static_analysis_off_reason\": {\n          \"readOnly\": true,\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StaticAnalysisOffReason\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"DataTests\": {\n      \"anyOf\": [\n        {\n          \"type\": \"string\"\n        },\n        {\n          \"$ref\": \"#/definitions/CustomTest\"\n        }\n      ]\n    },\n    \"DbtBatchSize\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"hour\",\n        \"day\",\n        \"month\",\n        \"year\"\n      ]\n    },\n    \"DbtContract\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"alias_types\": {\n          \"default\": true,\n          \"type\": \"boolean\"\n        },\n        \"checksum\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/AnyValue\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"enforced\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"DbtIncrementalStrategy\": {\n      \"oneOf\": [\n        {\n          \"type\": \"string\",\n          \"enum\": [\n            \"append\",\n            \"merge\",\n            \"delete+insert\",\n            \"insert_overwrite\",\n            \"microbatch\"\n          ]\n        },\n        {\n          \"description\": \"replace_where (Databricks only) see https://docs.getdbt.com/reference/resource-configs/databricks-configs\",\n          \"type\": \"string\",\n          \"enum\": [\n            \"replace_where\"\n          ]\n        },\n        {\n          \"type\": \"object\",\n          \"required\": [\n            \"custom\"\n          ],\n          \"properties\": {\n            \"custom\": {\n              \"type\": \"string\"\n            }\n          },\n          \"additionalProperties\": false\n        }\n      ]\n    },\n    \"DbtMaterialization\": {\n      \"oneOf\": [\n        {\n          \"type\": \"string\",\n          \"enum\": [\n            \"snapshot\",\n            \"seed\",\n            \"view\",\n            \"table\",\n            \"incremental\",\n            \"materialized_view\",\n            \"external\",\n            \"test\",\n            \"ephemeral\",\n            \"unit\",\n            \"analysis\",\n            \"function\"\n          ]\n        },\n        {\n          \"description\": \"only for databricks\",\n          \"type\": \"string\",\n          \"enum\": [\n            \"streaming_table\"\n          ]\n        },\n        {\n          \"description\": \"only for snowflake\",\n          \"type\": \"string\",\n          \"enum\": [\n            \"dynamic_table\"\n          ]\n        },\n        {\n          \"description\": \"for inline SQL compilation\",\n          \"type\": \"string\",\n          \"enum\": [\n            \"inline\"\n          ]\n        },\n        {\n          \"type\": \"object\",\n          \"required\": [\n            \"unknown\"\n          ],\n          \"properties\": {\n            \"unknown\": {\n              \"type\": \"string\"\n            }\n          },\n          \"additionalProperties\": false\n        }\n      ]\n    },\n    \"DbtOwner\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"email\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"DbtQuoting\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"database\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"identifier\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"schema\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"snowflake_ignore_case\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"DbtUniqueKey\": {\n      \"anyOf\": [\n        {\n          \"type\": \"string\"\n        },\n        {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        }\n      ]\n    },\n    \"DerivedDimension\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"expr\",\n        \"name\",\n        \"type\"\n      ],\n      \"properties\": {\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/SemanticLayerElementConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"expr\": {\n          \"type\": \"string\"\n        },\n        \"granularity\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Granularity\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"is_partition\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"label\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"type\": {\n          \"$ref\": \"#/definitions/ColumnPropertiesDimensionType\"\n        },\n        \"validity_params\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DimensionValidityParams\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"DerivedEntity\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"expr\",\n        \"name\",\n        \"type\"\n      ],\n      \"properties\": {\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/SemanticLayerElementConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"expr\": {\n          \"type\": \"string\"\n        },\n        \"label\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"type\": {\n          \"$ref\": \"#/definitions/ColumnPropertiesEntityType\"\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"DerivedSemantics\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"dimensions\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/DerivedDimension\"\n          }\n        },\n        \"entities\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/DerivedEntity\"\n          }\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"DimensionValidityParams\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"is_end\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"is_start\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"DocsConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"node_color\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"show\": {\n          \"default\": true,\n          \"type\": \"boolean\"\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"Entity\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/EntityConfig\"\n        },\n        {\n          \"$ref\": \"#/definitions/ColumnPropertiesEntityType\"\n        }\n      ]\n    },\n    \"EntityConfig\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"type\"\n      ],\n      \"properties\": {\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/SemanticLayerElementConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"label\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"type\": {\n          \"$ref\": \"#/definitions/ColumnPropertiesEntityType\"\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"Expect\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"fixture\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"format\": {\n          \"default\": \"dict\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/definitions/Formats\"\n            }\n          ]\n        },\n        \"rows\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Rows\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"Export\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/ExportConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"ExportConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"export_as\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/ExportConfigExportAs\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"ExportConfigExportAs\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"table\",\n        \"view\",\n        \"cache\"\n      ]\n    },\n    \"ExposureConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"enabled\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"meta\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"tags\": {\n          \"default\": [],\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"ExposureProperties\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\",\n        \"owner\",\n        \"type\"\n      ],\n      \"properties\": {\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/ExposureConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"depends_on\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"label\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"maturity\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"owner\": {\n          \"$ref\": \"#/definitions/DbtOwner\"\n        },\n        \"type\": {\n          \"$ref\": \"#/definitions/ExposureType\"\n        },\n        \"url\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"ExposureType\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"dashboard\",\n        \"notebook\",\n        \"analysis\",\n        \"ml\",\n        \"application\"\n      ]\n    },\n    \"FloatOrString\": {\n      \"anyOf\": [\n        {\n          \"type\": \"number\",\n          \"format\": \"float\"\n        },\n        {\n          \"type\": \"string\"\n        }\n      ]\n    },\n    \"Formats\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"dict\",\n        \"csv\",\n        \"sql\"\n      ]\n    },\n    \"FreshnessDefinition\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"error_after\": {\n          \"default\": {\n            \"count\": null,\n            \"period\": null\n          },\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/FreshnessRules\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"filter\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"warn_after\": {\n          \"default\": {\n            \"count\": null,\n            \"period\": null\n          },\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/FreshnessRules\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"FreshnessPeriod\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"minute\",\n        \"hour\",\n        \"day\"\n      ]\n    },\n    \"FreshnessRules\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"count\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"int64\"\n        },\n        \"period\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/FreshnessPeriod\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"FunctionArgument\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"data_type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"default_value\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"FunctionConfig\": {\n      \"description\": \"This configuration is a superset of all warehouse specific configurations that users can set\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"access\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Access\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"adapter_properties\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"as_columnstore\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"auto_liquid_cluster\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"auto_refresh\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"automatic_clustering\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"backup\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"base_location_root\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"base_location_subpath\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"batch_id\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"bind\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"buckets\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"int64\"\n        },\n        \"catalog\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"catalog_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"category\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DataLakeObjectCategory\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"cluster_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/ClusterConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"clustered_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compression\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"copy_grants\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"database\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"databricks_compute\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"databricks_tags\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"dataproc_cluster_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"dist\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"enable_list_inference\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"enable_refresh\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"enabled\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"entry_point\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"external_volume\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"file_format\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"grant_access_to\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/GrantAccessToTarget\"\n          }\n        },\n        \"grants\": {\n          \"$ref\": \"#/definitions/GrantConfig\"\n        },\n        \"group\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"hours_to_expiration\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"include_full_name_in_path\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"indexes\": {\n          \"default\": null,\n          \"allOf\": [\n            {\n              \"$ref\": \"#/definitions/IndexesConfig\"\n            }\n          ]\n        },\n        \"initialize\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"intermediate_format\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"jar_file_uri\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"job_execution_timeout_seconds\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"kms_key_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"labels\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          }\n        },\n        \"labels_from_meta\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"liquid_clustered_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"location_root\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"matched_condition\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"max_staleness\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"merge_with_schema_evolution\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"meta\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"not_matched_by_source_action\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"not_matched_by_source_condition\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"not_matched_condition\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"notebook_template_id\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"on_configuration_change\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"partition_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/PartitionConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"partition_expiration_days\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"partitions\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"primary_key\": {\n          \"default\": null,\n          \"allOf\": [\n            {\n              \"$ref\": \"#/definitions/PrimaryKeyConfig\"\n            }\n          ]\n        },\n        \"query_tag\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/QueryTag\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"quoting\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DbtQuoting\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"refresh_interval_minutes\": {\n          \"type\": [\n            \"number\",\n            \"null\"\n          ],\n          \"format\": \"double\"\n        },\n        \"refresh_mode\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"require_partition_filter\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"resource_tags\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          }\n        },\n        \"row_access_policy\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"runtime_version\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"schedule\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Schedule\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"secure\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"skip_matched_step\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"skip_not_matched_step\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"snowflake_warehouse\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"sort\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"sort_type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"source_alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"static_analysis\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StaticAnalysisKind\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"table_tag\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"table_type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"target_alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"target_lag\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"tblproperties\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"timeout\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"tmp_relation_type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"transient\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"type\": {\n          \"default\": \"scalar\",\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/FunctionKind\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"volatility\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Volatility\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"FunctionKind\": {\n      \"description\": \"Function kind enum with same values as UDFKind\",\n      \"type\": \"string\",\n      \"enum\": [\n        \"scalar\",\n        \"aggregate\",\n        \"table\"\n      ]\n    },\n    \"FunctionProperties\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"arguments\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/FunctionArgument\"\n          }\n        },\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/FunctionConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"data_tests\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/DataTests\"\n          }\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"identifier\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"language\": {\n          \"default\": \"sql\",\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"returns\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/FunctionReturnType\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"static_analysis_off_reason\": {\n          \"readOnly\": true,\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StaticAnalysisOffReason\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tests\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/DataTests\"\n          }\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"FunctionReturnType\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"data_type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"Given\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"input\"\n      ],\n      \"properties\": {\n        \"fixture\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"format\": {\n          \"default\": \"dict\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/definitions/Formats\"\n            }\n          ]\n        },\n        \"input\": {\n          \"type\": \"string\"\n        },\n        \"rows\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Rows\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"GrantAccessToTarget\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"dataset\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"project\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"GrantConfig\": {\n      \"description\": \"Wrapper type for grant configurations that normalizes values to arrays during serialization.\\n\\nThis type handles grant configurations with the following behavior: - Normalizes string values to arrays during serialization - Preserves insertion order using IndexMap\",\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n      }\n    },\n    \"Granularity\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"nanosecond\",\n        \"microsecond\",\n        \"millisecond\",\n        \"second\",\n        \"minute\",\n        \"hour\",\n        \"day\",\n        \"week\",\n        \"month\",\n        \"quarter\",\n        \"year\"\n      ]\n    },\n    \"GroupConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"meta\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"GroupProperties\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\",\n        \"owner\"\n      ],\n      \"properties\": {\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/GroupConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"owner\": {\n          \"$ref\": \"#/definitions/DbtOwner\"\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"HardDeletes\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"ignore\",\n        \"invalidate\",\n        \"new_record\"\n      ]\n    },\n    \"HookConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"index\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"sql\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"transaction\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"Hooks\": {\n      \"anyOf\": [\n        {\n          \"type\": \"string\"\n        },\n        {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        {\n          \"$ref\": \"#/definitions/HookConfig\"\n        },\n        {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/HookConfig\"\n          }\n        }\n      ]\n    },\n    \"IndexesConfig\": {\n      \"description\": \"A wrapper type for the `indexes` config field that handles flexible deserialization.\\n\\ndbt-core accepts both list and dictionary formats for indexes. This type accepts either format on input but always serializes as a list.\\n\\n# Example\\n\\n```ignore // Input (list): [{columns: [\\\"id\\\"], unique: true}] // Serializes as: [{columns: [\\\"id\\\"], unique: true}]\\n\\n// Input (dict): {\\\"my_index\\\": {columns: [\\\"id\\\"], unique: true}} // Serializes as: [{columns: [\\\"id\\\"], unique: true}]  (keys are discarded) ```\",\n      \"type\": [\n        \"array\",\n        \"null\"\n      ],\n      \"items\": {\n        \"$ref\": \"#/definitions/PostgresIndex\"\n      }\n    },\n    \"MacrosArguments\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"MacrosConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"meta\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"MacrosProperties\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"arguments\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/MacrosArguments\"\n          }\n        },\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/MacrosConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"meta\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"name\": {\n          \"type\": \"string\"\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"MetricConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"enabled\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"group\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"meta\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"tags\": {\n          \"default\": [],\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"MetricExpr\": {\n      \"anyOf\": [\n        {\n          \"type\": \"string\"\n        },\n        {\n          \"type\": \"integer\",\n          \"format\": \"int32\"\n        }\n      ]\n    },\n    \"MetricPropertiesMetricInput\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"filter\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"offset_to_grain\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"offset_window\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"MetricPropertiesNonAdditiveDimension\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\",\n        \"window_agg\"\n      ],\n      \"properties\": {\n        \"group_by\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"window_agg\": {\n          \"$ref\": \"#/definitions/WindowChoice\"\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"MetricType\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"simple\",\n        \"ratio\",\n        \"cumulative\",\n        \"derived\",\n        \"conversion\"\n      ]\n    },\n    \"MetricsProperties\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"agg\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/AggregationType\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"agg_time_dimension\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"base_metric\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrMetricPropertiesMetricInput\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"calculation\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/ConversionCalculationType\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/MetricConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"constant_properties\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/ConstantProperty\"\n          }\n        },\n        \"conversion_metric\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrMetricPropertiesMetricInput\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"denominator\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrMetricPropertiesMetricInput\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"entity\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"expr\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/MetricExpr\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"fill_nulls_with\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"int32\"\n        },\n        \"filter\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"grain_to_date\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Granularity\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"hidden\": {\n          \"default\": false,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"input_metric\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrMetricPropertiesMetricInput\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"input_metrics\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/MetricPropertiesMetricInput\"\n          }\n        },\n        \"join_to_timespine\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"label\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"non_additive_dimension\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/MetricPropertiesNonAdditiveDimension\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"numerator\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrMetricPropertiesMetricInput\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"percentile\": {\n          \"type\": [\n            \"number\",\n            \"null\"\n          ],\n          \"format\": \"float\"\n        },\n        \"percentile_type\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/PercentileType\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"period_agg\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/PeriodAggregationType\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"time_granularity\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Granularity\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"type\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/MetricType\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"window\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"ModelConfig\": {\n      \"description\": \"This configuration is a superset of all warehouse specific configurations that users can set\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"access\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Access\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"adapter_properties\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"additional_libs\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"as_columnstore\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"auto_liquid_cluster\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"auto_refresh\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"automatic_clustering\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"backup\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"base_location_root\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"base_location_subpath\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"batch_id\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"batch_size\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DbtBatchSize\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"begin\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"bind\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"buckets\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"int64\"\n        },\n        \"catalog\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"catalog_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"category\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DataLakeObjectCategory\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"cluster_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/ClusterConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"cluster_id\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"clustered_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"column_types\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          }\n        },\n        \"compression\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"concurrent_batches\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"contract\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DbtContract\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"copy_grants\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"create_notebook\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"database\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"databricks_compute\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"databricks_tags\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"dataproc_cluster_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"dist\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"enable_list_inference\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"enable_refresh\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"enabled\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"event_time\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"external_access_integrations\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"external_volume\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"file_format\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"freshness\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/ModelFreshness\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"full_refresh\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"grant_access_to\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/GrantAccessToTarget\"\n          }\n        },\n        \"grants\": {\n          \"$ref\": \"#/definitions/GrantConfig\"\n        },\n        \"group\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"hours_to_expiration\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"http_path\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"imports\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"include_full_name_in_path\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"incremental_predicates\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"incremental_strategy\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DbtIncrementalStrategy\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"index_url\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"indexes\": {\n          \"default\": null,\n          \"allOf\": [\n            {\n              \"$ref\": \"#/definitions/IndexesConfig\"\n            }\n          ]\n        },\n        \"initialize\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"intermediate_format\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"jar_file_uri\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"job_cluster_config\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"job_execution_timeout_seconds\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"kms_key_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"labels\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          }\n        },\n        \"labels_from_meta\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"liquid_clustered_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"location\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"location_root\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"lookback\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"int32\"\n        },\n        \"matched_condition\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"materialized\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DbtMaterialization\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"max_staleness\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"merge_exclude_columns\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"merge_update_columns\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"merge_with_schema_evolution\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"meta\": {\n          \"default\": {},\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"not_matched_by_source_action\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"not_matched_by_source_condition\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"not_matched_condition\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"notebook_template_id\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"on_configuration_change\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/OnConfigurationChange\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"on_schema_change\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/OnSchemaChange\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"packages\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"partition_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/PartitionConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"partition_expiration_days\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"partitions\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"persist_docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/PersistDocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"post_hook\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Hooks\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"pre_hook\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Hooks\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"predicates\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"primary_key\": {\n          \"default\": null,\n          \"allOf\": [\n            {\n              \"$ref\": \"#/definitions/PrimaryKeyConfig\"\n            }\n          ]\n        },\n        \"python_job_config\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"python_version\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"query_tag\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/QueryTag\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"quoting\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DbtQuoting\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"refresh_interval_minutes\": {\n          \"type\": [\n            \"number\",\n            \"null\"\n          ],\n          \"format\": \"double\"\n        },\n        \"refresh_mode\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"require_partition_filter\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"resource_tags\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          }\n        },\n        \"row_access_policy\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"schedule\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Schedule\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"secrets\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"secure\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"skip_matched_step\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"skip_not_matched_step\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"snowflake_warehouse\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"sort\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"sort_type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"source_alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"sql_header\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"static_analysis\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StaticAnalysisKind\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"submission_method\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"sync\": {\n          \"description\": \"Schema synchronization configuration\",\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/SyncConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"table_format\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"table_tag\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"table_type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"tags\": {\n          \"default\": [],\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"target_alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"target_lag\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"tblproperties\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"timeout\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"tmp_relation_type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"transient\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"unique_key\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DbtUniqueKey\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"use_anonymous_sproc\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"user_folder_for_python\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"ModelConstraint\": {\n      \"description\": \"Model level contraint\",\n      \"type\": \"object\",\n      \"required\": [\n        \"type\"\n      ],\n      \"properties\": {\n        \"columns\": {\n          \"default\": null,\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"expression\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"to\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"to_columns\": {\n          \"description\": \"Only ForeignKey constraints accept: a list columns in that table containing the corresponding primary or unique key.\",\n          \"default\": null,\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"type\": {\n          \"$ref\": \"#/definitions/ConstraintType\"\n        },\n        \"warn_unenforced\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"warn_unsupported\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"ModelFreshness\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"build_after\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/ModelFreshnessRules\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"ModelFreshnessRules\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"count\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"int64\"\n        },\n        \"period\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/FreshnessPeriod\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"updates_on\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/UpdatesOn\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"ModelProperties\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"agg_time_dimension\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"columns\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/ColumnProperties\"\n          }\n        },\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/ModelConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"constraints\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/ModelConstraint\"\n          }\n        },\n        \"data_tests\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/DataTests\"\n          }\n        },\n        \"deprecation_date\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"derived_semantics\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DerivedSemantics\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"identifier\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"latest_version\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/FloatOrString\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"metrics\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/MetricsProperties\"\n          }\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"primary_entity\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"semantic_model\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/ModelPropertiesSemanticModelConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"static_analysis_off_reason\": {\n          \"readOnly\": true,\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StaticAnalysisOffReason\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tests\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/DataTests\"\n          }\n        },\n        \"time_spine\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/ModelPropertiesTimeSpine\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"versions\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/Versions\"\n          }\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"ModelPropertiesSemanticModelConfig\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"enabled\"\n      ],\n      \"properties\": {\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/SemanticLayerElementConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"enabled\": {\n          \"type\": \"boolean\"\n        },\n        \"group\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"ModelPropertiesTimeSpine\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"standard_granularity_column\"\n      ],\n      \"properties\": {\n        \"custom_granularities\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/TimeSpineCustomGranularity\"\n          }\n        },\n        \"standard_granularity_column\": {\n          \"type\": \"string\"\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"OnConfigurationChange\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"apply\",\n        \"continue\",\n        \"fail\",\n        \"unknown\"\n      ]\n    },\n    \"OnSchemaChange\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"ignore\",\n        \"append_new_columns\",\n        \"fail\",\n        \"sync_all_columns\",\n        \"unknown\"\n      ]\n    },\n    \"PartitionConfig\": {\n      \"description\": \"Configuration for partition by columns.\\n\\ndbt-core allows either of the variants for the `partition_by` in the model config but the bigquery-adapter throws RunTime error the behaviors are tested from the latest dbt-core + bigquery-adapter as this is written we're conformant to this behavior via here and via the `into_bigquery()` method\",\n      \"anyOf\": [\n        {\n          \"type\": \"string\"\n        },\n        {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        {\n          \"$ref\": \"#/definitions/BigqueryPartitionConfig\"\n        }\n      ]\n    },\n    \"PercentileType\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"discrete\",\n        \"continuous\"\n      ]\n    },\n    \"PeriodAggregationType\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"first\",\n        \"last\",\n        \"average\"\n      ]\n    },\n    \"PersistDocsConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"columns\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"relation\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"PostgresIndex\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"columns\"\n      ],\n      \"properties\": {\n        \"columns\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"unique\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"PrimaryKeyConfig\": {\n      \"description\": \"A wrapper type for the `primary_key` config field that normalizes serialization.\\n\\nIn dbt-core, primary_key values are \\\"listified\\\" - single strings are converted to single-element arrays. This type accepts either format on input but always serializes as arrays.\\n\\n# Example\\n\\n```ignore // Input: \\\"id\\\" // Serializes as: [\\\"id\\\"]\\n\\n// Input: [\\\"id\\\", \\\"tenant_id\\\"] // Serializes as: [\\\"id\\\", \\\"tenant_id\\\"] ```\",\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"QueryTag\": {\n      \"description\": \"A wrapper type for the `query_tag` config field that handles flexible deserialization.\\n\\nAccepts strings, dictionaries, or sequences for query_tag. Maps and sequences are JSON-serialized to strings.\\n\\n# Example\\n\\n```ignore // Input: \\\"my-tag\\\" // Stores as: \\\"my-tag\\\"\\n\\n// Input: {\\\"project\\\": \\\"foo\\\", \\\"env\\\": \\\"prod\\\"} // Stores as: \\\"{\\\\\\\"project\\\\\\\":\\\\\\\"foo\\\\\\\",\\\\\\\"env\\\\\\\":\\\\\\\"prod\\\\\\\"}\\\" ```\",\n      \"type\": \"string\"\n    },\n    \"Range\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"end\",\n        \"interval\",\n        \"start\"\n      ],\n      \"properties\": {\n        \"end\": {\n          \"type\": \"integer\",\n          \"format\": \"int64\"\n        },\n        \"interval\": {\n          \"type\": \"integer\",\n          \"format\": \"int64\"\n        },\n        \"start\": {\n          \"type\": \"integer\",\n          \"format\": \"int64\"\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"RangeConfig\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"range\"\n      ],\n      \"properties\": {\n        \"range\": {\n          \"$ref\": \"#/definitions/Range\"\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"Rows\": {\n      \"anyOf\": [\n        {\n          \"type\": \"string\"\n        },\n        {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"object\",\n            \"additionalProperties\": {\n              \"$ref\": \"#/definitions/AnyValue\"\n            }\n          }\n        }\n      ]\n    },\n    \"SavedQueriesProperties\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\",\n        \"query_params\"\n      ],\n      \"properties\": {\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/SavedQueryConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"exports\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/Export\"\n          }\n        },\n        \"label\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"query_params\": {\n          \"$ref\": \"#/definitions/SavedQueriesQueryParams\"\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"SavedQueriesQueryParams\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"group_by\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"metrics\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"where\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"type\": \"string\"\n          }\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"SavedQueryCache\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"enabled\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"SavedQueryConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"cache\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/SavedQueryCache\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"enabled\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"export_as\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/ExportConfigExportAs\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"group\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"meta\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"schema\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"tags\": {\n          \"default\": [],\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"Schedule\": {\n      \"description\": \"Schedule configuration that accepts both string and structured formats. This allows users to specify schedule as either: - A string: `schedule: \\\"USING CRON 0,15,30,45 * * * * UTC\\\"` - A structured config: `schedule: { cron: \\\"0 * * * *\\\", time_zone_value: \\\"UTC\\\" }`\",\n      \"anyOf\": [\n        {\n          \"type\": \"string\"\n        },\n        {\n          \"$ref\": \"#/definitions/ScheduleConfig\"\n        }\n      ]\n    },\n    \"ScheduleConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"cron\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"time_zone_value\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"SchemaOrigin\": {\n      \"description\": \"Indicates where schema metadata originates from.\\n\\n- `Remote` (default): Schema is fetched from the remote warehouse - `Local`: Schema is derived from YAML column definitions\",\n      \"oneOf\": [\n        {\n          \"description\": \"Schema metadata comes from the remote warehouse (default)\",\n          \"type\": \"string\",\n          \"enum\": [\n            \"remote\"\n          ]\n        },\n        {\n          \"description\": \"Schema metadata is derived from YAML column definitions\",\n          \"type\": \"string\",\n          \"enum\": [\n            \"local\"\n          ]\n        }\n      ]\n    },\n    \"SchemaRefreshInterval\": {\n      \"description\": \"Schema refresh interval: '30m', '2h', '1d', or 'never'\",\n      \"type\": \"string\"\n    },\n    \"SeedConfig\": {\n      \"description\": \"This configuration is a superset of all warehouse specific configurations that users can set\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"adapter_properties\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"as_columnstore\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"auto_liquid_cluster\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"auto_refresh\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"automatic_clustering\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"backup\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"base_location_root\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"base_location_subpath\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"batch_id\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"bind\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"buckets\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"int64\"\n        },\n        \"catalog\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"catalog_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"category\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DataLakeObjectCategory\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"cluster_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/ClusterConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"clustered_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"column_types\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          }\n        },\n        \"compression\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"copy_grants\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"database\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"databricks_compute\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"databricks_tags\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"dataproc_cluster_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"delimiter\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"dist\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"enable_list_inference\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"enable_refresh\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"enabled\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"event_time\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"external_volume\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"file_format\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"full_refresh\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"grant_access_to\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/GrantAccessToTarget\"\n          }\n        },\n        \"grants\": {\n          \"default\": {},\n          \"allOf\": [\n            {\n              \"$ref\": \"#/definitions/GrantConfig\"\n            }\n          ]\n        },\n        \"group\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"hours_to_expiration\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"include_full_name_in_path\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"indexes\": {\n          \"default\": null,\n          \"allOf\": [\n            {\n              \"$ref\": \"#/definitions/IndexesConfig\"\n            }\n          ]\n        },\n        \"initialize\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"intermediate_format\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"jar_file_uri\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"job_execution_timeout_seconds\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"kms_key_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"labels\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          }\n        },\n        \"labels_from_meta\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"liquid_clustered_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"location_root\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"matched_condition\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"materialized\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DbtMaterialization\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"max_staleness\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"merge_with_schema_evolution\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"meta\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"not_matched_by_source_action\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"not_matched_by_source_condition\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"not_matched_condition\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"notebook_template_id\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"partition_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/PartitionConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"partition_expiration_days\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"partitions\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"persist_docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/PersistDocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"post_hook\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Hooks\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"pre_hook\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Hooks\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"primary_key\": {\n          \"default\": null,\n          \"allOf\": [\n            {\n              \"$ref\": \"#/definitions/PrimaryKeyConfig\"\n            }\n          ]\n        },\n        \"query_tag\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/QueryTag\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"quote_columns\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"quoting\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DbtQuoting\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"refresh_interval_minutes\": {\n          \"type\": [\n            \"number\",\n            \"null\"\n          ],\n          \"format\": \"double\"\n        },\n        \"refresh_mode\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"require_partition_filter\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"resource_tags\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          }\n        },\n        \"row_access_policy\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"schedule\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Schedule\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"secure\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"skip_matched_step\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"skip_not_matched_step\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"snowflake_warehouse\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"sort\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"sort_type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"source_alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"static_analysis\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StaticAnalysisKind\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"table_tag\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"table_type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"tags\": {\n          \"default\": [],\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"target_alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"target_lag\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"tblproperties\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"timeout\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"tmp_relation_type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"transient\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"SeedProperties\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"columns\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/ColumnProperties\"\n          }\n        },\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/SeedConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"data_tests\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/DataTests\"\n          }\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"static_analysis_off_reason\": {\n          \"readOnly\": true,\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StaticAnalysisOffReason\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tests\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/DataTests\"\n          }\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"SemanticLayerElementConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"meta\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"Severity\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"Error\",\n        \"Warn\"\n      ]\n    },\n    \"SnapshotConfig\": {\n      \"description\": \"This configuration is a superset of all warehouse specific configurations that users can set\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"adapter_properties\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"as_columnstore\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"auto_liquid_cluster\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"auto_refresh\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"automatic_clustering\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"backup\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"base_location_root\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"base_location_subpath\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"batch_id\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"bind\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"buckets\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"int64\"\n        },\n        \"catalog\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"catalog_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"category\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DataLakeObjectCategory\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"check_cols\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"cluster_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/ClusterConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"clustered_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compression\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"copy_grants\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"database\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"databricks_compute\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"databricks_tags\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"dataproc_cluster_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"dbt_valid_to_current\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"dist\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"enable_list_inference\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"enable_refresh\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"enabled\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"event_time\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"external_volume\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"file_format\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"full_refresh\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"grant_access_to\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/GrantAccessToTarget\"\n          }\n        },\n        \"grants\": {\n          \"default\": {},\n          \"allOf\": [\n            {\n              \"$ref\": \"#/definitions/GrantConfig\"\n            }\n          ]\n        },\n        \"group\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"hard_deletes\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/HardDeletes\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"hours_to_expiration\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"include_full_name_in_path\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"indexes\": {\n          \"default\": null,\n          \"allOf\": [\n            {\n              \"$ref\": \"#/definitions/IndexesConfig\"\n            }\n          ]\n        },\n        \"initialize\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"intermediate_format\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"invalidate_hard_deletes\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"jar_file_uri\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"job_execution_timeout_seconds\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"kms_key_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"labels\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          }\n        },\n        \"labels_from_meta\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"liquid_clustered_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"location_root\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"matched_condition\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"materialized\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DbtMaterialization\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"max_staleness\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"merge_with_schema_evolution\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"meta\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"not_matched_by_source_action\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"not_matched_by_source_condition\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"not_matched_condition\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"notebook_template_id\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"partition_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/PartitionConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"partition_expiration_days\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"partitions\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"persist_docs\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/PersistDocsConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"post_hook\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Hooks\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"pre_hook\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Hooks\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"primary_key\": {\n          \"default\": null,\n          \"allOf\": [\n            {\n              \"$ref\": \"#/definitions/PrimaryKeyConfig\"\n            }\n          ]\n        },\n        \"query_tag\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/QueryTag\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"quote_columns\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"quoting\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DbtQuoting\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"refresh_interval_minutes\": {\n          \"type\": [\n            \"number\",\n            \"null\"\n          ],\n          \"format\": \"double\"\n        },\n        \"refresh_mode\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"require_partition_filter\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"resource_tags\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          }\n        },\n        \"row_access_policy\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"schedule\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Schedule\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"secure\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"skip_matched_step\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"skip_not_matched_step\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"snapshot_meta_column_names\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/SnapshotMetaColumnNames\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"snowflake_warehouse\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"sort\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"sort_type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"source_alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"static_analysis\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StaticAnalysisKind\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"strategy\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"sync\": {\n          \"description\": \"Schema synchronization configuration\",\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/SyncConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"table_tag\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"table_type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"tags\": {\n          \"default\": [],\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"target_alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"target_database\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"target_lag\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"target_schema\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"tblproperties\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"timeout\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"tmp_relation_type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"transient\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"unique_key\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"updated_at\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"SnapshotMetaColumnNames\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"dbt_is_deleted\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"dbt_scd_id\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"dbt_updated_at\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"dbt_valid_from\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"dbt_valid_to\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"SnapshotProperties\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"columns\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/ColumnProperties\"\n          }\n        },\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/SnapshotConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"data_tests\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/DataTests\"\n          }\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"relation\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"static_analysis_off_reason\": {\n          \"readOnly\": true,\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StaticAnalysisOffReason\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tests\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/DataTests\"\n          }\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"SourceConfig\": {\n      \"description\": \"This configuration is a superset of all warehouse specific configurations that users can set\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"adapter_properties\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"as_columnstore\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"auto_liquid_cluster\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"auto_refresh\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"automatic_clustering\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"backup\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"base_location_root\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"base_location_subpath\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"batch_id\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"bind\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"buckets\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"int64\"\n        },\n        \"catalog\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"catalog_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"category\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DataLakeObjectCategory\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"cluster_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/ClusterConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"clustered_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compression\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"copy_grants\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"databricks_compute\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"databricks_tags\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"dataproc_cluster_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"dist\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"enable_list_inference\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"enable_refresh\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"enabled\": {\n          \"default\": null,\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"event_time\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"external_volume\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"file_format\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"freshness\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/FreshnessDefinition\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"grant_access_to\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/GrantAccessToTarget\"\n          }\n        },\n        \"hours_to_expiration\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"include_full_name_in_path\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"indexes\": {\n          \"default\": null,\n          \"allOf\": [\n            {\n              \"$ref\": \"#/definitions/IndexesConfig\"\n            }\n          ]\n        },\n        \"initialize\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"intermediate_format\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"jar_file_uri\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"job_execution_timeout_seconds\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"kms_key_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"labels\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          }\n        },\n        \"labels_from_meta\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"liquid_clustered_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"loaded_at_field\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"loaded_at_query\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"location_root\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"matched_condition\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"max_staleness\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"merge_with_schema_evolution\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"meta\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"not_matched_by_source_action\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"not_matched_by_source_condition\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"not_matched_condition\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"notebook_template_id\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"partition_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/PartitionConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"partition_expiration_days\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"partitions\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"primary_key\": {\n          \"default\": null,\n          \"allOf\": [\n            {\n              \"$ref\": \"#/definitions/PrimaryKeyConfig\"\n            }\n          ]\n        },\n        \"query_tag\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/QueryTag\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"quoting\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DbtQuoting\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"refresh_interval_minutes\": {\n          \"type\": [\n            \"number\",\n            \"null\"\n          ],\n          \"format\": \"double\"\n        },\n        \"refresh_mode\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"require_partition_filter\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"resource_tags\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          }\n        },\n        \"row_access_policy\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"schedule\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Schedule\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema_origin\": {\n          \"description\": \"Specifies where the schema metadata originates: 'remote' (default) or 'local'\",\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/SchemaOrigin\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"secure\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"skip_matched_step\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"skip_not_matched_step\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"snowflake_warehouse\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"sort\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"sort_type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"source_alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"static_analysis\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StaticAnalysisKind\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"sync\": {\n          \"description\": \"Schema synchronization configuration\",\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/SyncConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"table_tag\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"table_type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"tags\": {\n          \"default\": [],\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"target_alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"target_lag\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"tblproperties\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"timeout\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"tmp_relation_type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"transient\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"SourceProperties\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"catalog\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/SourceConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"database\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"loader\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"quoting\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DbtQuoting\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"tables\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/Tables\"\n          }\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"StaticAnalysisKind\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"unsafe\",\n        \"off\",\n        \"strict\",\n        \"baseline\",\n        \"on\"\n      ]\n    },\n    \"StaticAnalysisOffReason\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"configuredoff\",\n        \"unabletofetchschema\",\n        \"nodownstream\"\n      ]\n    },\n    \"StoreFailuresAs\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"ephemeral\",\n        \"table\",\n        \"view\"\n      ]\n    },\n    \"StringOrArrayOfStrings\": {\n      \"anyOf\": [\n        {\n          \"type\": \"string\"\n        },\n        {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        }\n      ]\n    },\n    \"StringOrMetricPropertiesMetricInput\": {\n      \"anyOf\": [\n        {\n          \"type\": \"string\"\n        },\n        {\n          \"$ref\": \"#/definitions/MetricPropertiesMetricInput\"\n        }\n      ]\n    },\n    \"SyncConfig\": {\n      \"description\": \"Configuration for schema synchronization behavior.\\n\\nThis can be specified at source level (default for all tables) or at individual table level (overrides source-level settings).\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"schema_refresh_interval\": {\n          \"description\": \"How often to refresh the schema from the warehouse. Examples: \\\"30m\\\", \\\"2h\\\", \\\"1d\\\", \\\"never\\\"\",\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/SchemaRefreshInterval\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"Tables\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"columns\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/ColumnProperties\"\n          }\n        },\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/TablesConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"data_tests\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/DataTests\"\n          }\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"external\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/AnyValue\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"identifier\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"loader\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"quoting\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DbtQuoting\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tests\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/DataTests\"\n          }\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"TablesConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"enabled\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"event_time\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"freshness\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/FreshnessDefinition\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"loaded_at_field\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"loaded_at_query\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"meta\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"schema_origin\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/SchemaOrigin\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"sync\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/SyncConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"TimeConfig\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"granularity\": {\n          \"default\": \"day\",\n          \"type\": \"string\"\n        },\n        \"time_ingestion_partitioning\": {\n          \"description\": \"When this is true, the [`BigqueryPartitionConfig::field`] will be used as the `_PARTITIONTIME` pseudo column _PARTITIONTIME: https://cloud.google.com/bigquery/docs/partitioned-tables#ingestion_time https://docs.getdbt.com/reference/resource-configs/bigquery-configs#partitioning-by-an-ingestion-date-or-timestamp\",\n          \"default\": false,\n          \"type\": \"boolean\"\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"TimeSpineCustomGranularity\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"column_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"UnitTestConfig\": {\n      \"description\": \"This configuration is a superset of all warehouse specific configurations that users can set\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"adapter_properties\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"as_columnstore\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"auto_liquid_cluster\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"auto_refresh\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"automatic_clustering\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"backup\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"base_location_root\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"base_location_subpath\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"batch_id\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"bind\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"buckets\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"int64\"\n        },\n        \"catalog\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"catalog_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"category\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/DataLakeObjectCategory\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"cluster_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/ClusterConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"clustered_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compression\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"copy_grants\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"databricks_compute\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"databricks_tags\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"dataproc_cluster_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"dist\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"enable_list_inference\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"enable_refresh\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"enabled\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"external_volume\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"file_format\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"grant_access_to\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/GrantAccessToTarget\"\n          }\n        },\n        \"hours_to_expiration\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"include_full_name_in_path\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"indexes\": {\n          \"default\": null,\n          \"allOf\": [\n            {\n              \"$ref\": \"#/definitions/IndexesConfig\"\n            }\n          ]\n        },\n        \"initialize\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"intermediate_format\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"jar_file_uri\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"job_execution_timeout_seconds\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"kms_key_name\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"labels\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          }\n        },\n        \"labels_from_meta\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"liquid_clustered_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"location_root\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"matched_condition\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"max_staleness\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"merge_with_schema_evolution\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"meta\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"not_matched_by_source_action\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"not_matched_by_source_condition\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"not_matched_condition\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"notebook_template_id\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"partition_by\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/PartitionConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"partition_expiration_days\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"partitions\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"primary_key\": {\n          \"default\": null,\n          \"allOf\": [\n            {\n              \"$ref\": \"#/definitions/PrimaryKeyConfig\"\n            }\n          ]\n        },\n        \"query_tag\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/QueryTag\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"refresh_interval_minutes\": {\n          \"type\": [\n            \"number\",\n            \"null\"\n          ],\n          \"format\": \"double\"\n        },\n        \"refresh_mode\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"require_partition_filter\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"resource_tags\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          }\n        },\n        \"row_access_policy\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"schedule\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/Schedule\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"secure\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"skip_matched_step\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"skip_not_matched_step\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        },\n        \"snowflake_warehouse\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"sort\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"sort_type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"source_alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"static_analysis\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StaticAnalysisKind\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"table_tag\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"table_type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"tags\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StringOrArrayOfStrings\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"target_alias\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"target_lag\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"tblproperties\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"timeout\": {\n          \"type\": [\n            \"integer\",\n            \"null\"\n          ],\n          \"format\": \"uint64\",\n          \"minimum\": 0.0\n        },\n        \"tmp_relation_type\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"transient\": {\n          \"type\": [\n            \"boolean\",\n            \"null\"\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"UnitTestOverrides\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"env_vars\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"macros\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        },\n        \"vars\": {\n          \"type\": [\n            \"object\",\n            \"null\"\n          ],\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/AnyValue\"\n          }\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"UnitTestProperties\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"expect\",\n        \"model\",\n        \"name\"\n      ],\n      \"properties\": {\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/UnitTestConfig\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"description\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"expect\": {\n          \"$ref\": \"#/definitions/Expect\"\n        },\n        \"given\": {\n          \"type\": [\n            \"array\",\n            \"null\"\n          ],\n          \"items\": {\n            \"$ref\": \"#/definitions/Given\"\n          }\n        },\n        \"model\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"overrides\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/UnitTestOverrides\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"static_analysis_off_reason\": {\n          \"readOnly\": true,\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/StaticAnalysisOffReason\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"versions\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/AnyValue\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"UpdatesOn\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"any\",\n        \"all\"\n      ]\n    },\n    \"Versions\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"v\"\n      ],\n      \"properties\": {\n        \"config\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/AnyValue\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deprecation_date\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"v\": {\n          \"$ref\": \"#/definitions/AnyValue\"\n        }\n      },\n      \"additionalProperties\": {\n        \"type\": \"object\",\n        \"additionalProperties\": {\n          \"$ref\": \"#/definitions/AnyValue\"\n        }\n      }\n    },\n    \"Volatility\": {\n      \"description\": \"Function volatility enum - defines the function's eligibility for certain optimizations Matches the Python Volatility enum from dbt-core\",\n      \"oneOf\": [\n        {\n          \"type\": \"string\",\n          \"enum\": [\n            \"stable\"\n          ]\n        },\n        {\n          \"description\": \"Deterministic - An deterministic function will always return the same output when given the same input.\",\n          \"type\": \"string\",\n          \"enum\": [\n            \"deterministic\"\n          ]\n        },\n        {\n          \"description\": \"NonDeterministic - A non-deterministic function may change the return value from evaluation to evaluation. Multiple invocations of a non-deterministic function may return different results when used in the same query.\",\n          \"type\": \"string\",\n          \"enum\": [\n            \"non-deterministic\"\n          ]\n        }\n      ]\n    },\n    \"WindowChoice\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"min\",\n        \"max\"\n      ]\n    }\n  }\n}\n"
  },
  {
    "path": "core/dbt/links.py",
    "content": "ProfileConfigDocs = \"https://docs.getdbt.com/docs/configure-your-profile\"\nSnowflakeQuotingDocs = \"https://docs.getdbt.com/v0.10/docs/configuring-quoting\"\nIncrementalDocs = \"https://docs.getdbt.com/docs/configuring-incremental-models\"\nBigQueryNewPartitionBy = \"https://docs.getdbt.com/docs/upgrading-to-0-16-0\"\n"
  },
  {
    "path": "core/dbt/materializations/__init__.py",
    "content": ""
  },
  {
    "path": "core/dbt/materializations/incremental/__init__.py",
    "content": ""
  },
  {
    "path": "core/dbt/materializations/incremental/microbatch.py",
    "content": "from datetime import datetime, timedelta\nfrom typing import Any, Dict, List, Optional\n\nimport pytz\n\nfrom dbt.artifacts.resources.types import BatchSize\nfrom dbt.artifacts.schemas.batch_results import BatchType\nfrom dbt.contracts.graph.nodes import ModelNode, NodeConfig\nfrom dbt.exceptions import DbtInternalError, DbtRuntimeError\n\n\nclass MicrobatchBuilder:\n    \"\"\"A utility class for building microbatch definitions associated with a specific model\"\"\"\n\n    def __init__(\n        self,\n        model: ModelNode,\n        is_incremental: bool,\n        event_time_start: Optional[datetime],\n        event_time_end: Optional[datetime],\n        default_end_time: Optional[datetime] = None,\n    ):\n        if model.config.incremental_strategy != \"microbatch\":\n            raise DbtInternalError(\n                f\"Model '{model.name}' does not use 'microbatch' incremental_strategy.\"\n            )\n        self.model = model\n\n        if self.model.config.batch_size is None:\n            raise DbtRuntimeError(\n                f\"Microbatch model '{self.model.name}' does not have a 'batch_size' config (one of {[batch_size.value for batch_size in BatchSize]}) specificed.\"\n            )\n\n        self.is_incremental = is_incremental\n        self.event_time_start = (\n            event_time_start.replace(tzinfo=pytz.UTC) if event_time_start else None\n        )\n        self.event_time_end = event_time_end.replace(tzinfo=pytz.UTC) if event_time_end else None\n        self.default_end_time = default_end_time or datetime.now(pytz.UTC)\n\n    def build_end_time(self):\n        \"\"\"Defaults the end_time to the current time in UTC unless a non `None` event_time_end was provided\"\"\"\n        end_time = self.event_time_end or self.default_end_time\n        return MicrobatchBuilder.ceiling_timestamp(end_time, self.model.config.batch_size)\n\n    def build_start_time(self, checkpoint: Optional[datetime]):\n        \"\"\"Create a start time based off the passed in checkpoint.\n\n        If the checkpoint is `None`, or this is the first run of a microbatch model, then the\n        model's configured `begin` value will be returned as a checkpoint is necessary\n        to build a start time. This is because we build the start time relative to the checkpoint\n        via the batchsize and offset, and we cannot offset a checkpoint if there is no checkpoint.\n        \"\"\"\n        assert isinstance(self.model.config, NodeConfig)\n        batch_size = self.model.config.batch_size\n\n        # Use event_time_start if it is provided.\n        if self.event_time_start:\n            return MicrobatchBuilder.truncate_timestamp(self.event_time_start, batch_size)\n\n        # First run, use model's configured 'begin' as start.\n        if not self.is_incremental or checkpoint is None:\n            if not self.model.config.begin:\n                raise DbtRuntimeError(\n                    f\"Microbatch model '{self.model.name}' requires a 'begin' configuration.\"\n                )\n\n            return MicrobatchBuilder.truncate_timestamp(self.model.config.begin, batch_size)\n\n        lookback = self.model.config.lookback\n\n        # If the checkpoint is equivalent to itself truncated then the checkpoint stradles\n        # the batch line. In this case the last batch will end with the checkpoint, but start\n        # should be the previous hour/day/month/year. Thus we need to increase the lookback by\n        # 1 to get this affect properly.\n        if checkpoint == MicrobatchBuilder.truncate_timestamp(checkpoint, batch_size):\n            lookback += 1\n\n        return MicrobatchBuilder.offset_timestamp(checkpoint, batch_size, -1 * lookback)\n\n    def build_batches(self, start: datetime, end: datetime) -> List[BatchType]:\n        \"\"\"\n        Given a start and end datetime, builds a list of batches where each batch is\n        the size of the model's batch_size.\n        \"\"\"\n        batch_size = self.model.config.batch_size\n        curr_batch_start: datetime = start\n        curr_batch_end: datetime = MicrobatchBuilder.offset_timestamp(\n            curr_batch_start, batch_size, 1\n        )\n\n        batches: List[BatchType] = [(curr_batch_start, curr_batch_end)]\n        while curr_batch_end < end:\n            curr_batch_start = curr_batch_end\n            curr_batch_end = MicrobatchBuilder.offset_timestamp(curr_batch_start, batch_size, 1)\n            batches.append((curr_batch_start, curr_batch_end))\n\n        # use exact end value as stop\n        batches[-1] = (batches[-1][0], end)\n\n        return batches\n\n    @staticmethod\n    def build_jinja_context_for_batch(model: ModelNode, incremental_batch: bool) -> Dict[str, Any]:\n        \"\"\"\n        Create context with entries that reflect microbatch model + incremental execution state\n\n        Assumes self.model has been (re)-compiled with necessary batch filters applied.\n        \"\"\"\n        jinja_context: Dict[str, Any] = {}\n\n        # Microbatch model properties\n        jinja_context[\"model\"] = model.to_dict()\n        jinja_context[\"sql\"] = model.compiled_code\n        jinja_context[\"compiled_code\"] = model.compiled_code\n\n        # Add incremental context variables for batches running incrementally\n        if incremental_batch:\n            jinja_context[\"is_incremental\"] = lambda: True\n            jinja_context[\"should_full_refresh\"] = lambda: False\n\n        return jinja_context\n\n    @staticmethod\n    def offset_timestamp(timestamp: datetime, batch_size: BatchSize, offset: int) -> datetime:\n        \"\"\"Truncates the passed in timestamp based on the batch_size and then applies the offset by the batch_size.\n\n        Note: It's important to understand that the offset applies to the truncated timestamp, not\n        the origin timestamp. Thus being offset by a day isn't relative to the any given hour that day,\n        but relative to the start of the day. So if the timestamp is the very end of a day, 2024-09-17 23:59:59,\n        you have a batch size of a day, and an offset of +1, then the returned value ends up being only one\n        second later, 2024-09-18 00:00:00.\n\n        2024-09-17 16:06:00 + Batchsize.hour -1 -> 2024-09-17 15:00:00\n        2024-09-17 16:06:00 + Batchsize.hour +1 -> 2024-09-17 17:00:00\n        2024-09-17 16:06:00 + Batchsize.day -1 -> 2024-09-16 00:00:00\n        2024-09-17 16:06:00 + Batchsize.day +1 -> 2024-09-18 00:00:00\n        2024-09-17 16:06:00 + Batchsize.month -1 -> 2024-08-01 00:00:00\n        2024-09-17 16:06:00 + Batchsize.month +1 -> 2024-10-01 00:00:00\n        2024-09-17 16:06:00 + Batchsize.year -1 -> 2023-01-01 00:00:00\n        2024-09-17 16:06:00 + Batchsize.year +1 -> 2025-01-01 00:00:00\n        \"\"\"\n        truncated = MicrobatchBuilder.truncate_timestamp(timestamp, batch_size)\n\n        offset_timestamp: datetime\n        if batch_size == BatchSize.hour:\n            offset_timestamp = truncated + timedelta(hours=offset)\n        elif batch_size == BatchSize.day:\n            offset_timestamp = truncated + timedelta(days=offset)\n        elif batch_size == BatchSize.month:\n            offset_timestamp = truncated\n            for _ in range(abs(offset)):\n                if offset < 0:\n                    offset_timestamp = offset_timestamp - timedelta(days=1)\n                else:\n                    offset_timestamp = offset_timestamp + timedelta(days=31)\n                offset_timestamp = MicrobatchBuilder.truncate_timestamp(\n                    offset_timestamp, batch_size\n                )\n        elif batch_size == BatchSize.year:\n            offset_timestamp = truncated.replace(year=truncated.year + offset)\n\n        return offset_timestamp\n\n    @staticmethod\n    def truncate_timestamp(timestamp: datetime, batch_size: BatchSize) -> datetime:\n        \"\"\"Truncates the passed in timestamp based on the batch_size.\n\n        2024-09-17 16:06:00 + Batchsize.hour -> 2024-09-17 16:00:00\n        2024-09-17 16:06:00 + Batchsize.day -> 2024-09-17 00:00:00\n        2024-09-17 16:06:00 + Batchsize.month -> 2024-09-01 00:00:00\n        2024-09-17 16:06:00 + Batchsize.year -> 2024-01-01 00:00:00\n        \"\"\"\n        if batch_size == BatchSize.hour:\n            truncated = datetime(\n                timestamp.year,\n                timestamp.month,\n                timestamp.day,\n                timestamp.hour,\n                0,\n                0,\n                0,\n                pytz.utc,\n            )\n        elif batch_size == BatchSize.day:\n            truncated = datetime(\n                timestamp.year, timestamp.month, timestamp.day, 0, 0, 0, 0, pytz.utc\n            )\n        elif batch_size == BatchSize.month:\n            truncated = datetime(timestamp.year, timestamp.month, 1, 0, 0, 0, 0, pytz.utc)\n        elif batch_size == BatchSize.year:\n            truncated = datetime(timestamp.year, 1, 1, 0, 0, 0, 0, pytz.utc)\n\n        return truncated\n\n    @staticmethod\n    def batch_id(start_time: datetime, batch_size: BatchSize) -> str:\n        return MicrobatchBuilder.format_batch_start(start_time, batch_size).replace(\"-\", \"\")\n\n    @staticmethod\n    def format_batch_start(batch_start: datetime, batch_size: BatchSize) -> str:\n        \"\"\"Format the passed in datetime based on the batch_size.\n\n        2024-09-17 16:06:00 + Batchsize.hour  -> 2024-09-17T16\n        2024-09-17 16:06:00 + Batchsize.day   -> 2024-09-17\n        2024-09-17 16:06:00 + Batchsize.month -> 2024-09\n        2024-09-17 16:06:00 + Batchsize.year  -> 2024\n        \"\"\"\n        if batch_size == BatchSize.year:\n            return batch_start.strftime(\"%Y\")\n        elif batch_size == BatchSize.month:\n            return batch_start.strftime(\"%Y-%m\")\n        elif batch_size == BatchSize.day:\n            return batch_start.strftime(\"%Y-%m-%d\")\n        else:  # batch_size == BatchSize.hour\n            return batch_start.strftime(\"%Y-%m-%dT%H\")\n\n    @staticmethod\n    def ceiling_timestamp(timestamp: datetime, batch_size: BatchSize) -> datetime:\n        \"\"\"Takes the given timestamp and moves it to the ceiling for the given batch size\n\n        Note, if the timestamp is already the batch size ceiling, that is returned\n        2024-09-17 16:06:00 + BatchSize.hour -> 2024-09-17 17:00:00\n        2024-09-17 16:00:00 + BatchSize.hour -> 2024-09-17 16:00:00\n        2024-09-17 16:06:00 + BatchSize.day -> 2024-09-18 00:00:00\n        2024-09-17 00:00:00 + BatchSize.day -> 2024-09-17 00:00:00\n        2024-09-17 16:06:00 + BatchSize.month -> 2024-10-01 00:00:00\n        2024-09-01 00:00:00 + BatchSize.month -> 2024-09-01 00:00:00\n        2024-09-17 16:06:00 + BatchSize.year -> 2025-01-01 00:00:00\n        2024-01-01 00:00:00 + BatchSize.year -> 2024-01-01 00:00:00\n\n        \"\"\"\n        ceiling = truncated = MicrobatchBuilder.truncate_timestamp(timestamp, batch_size)\n        if truncated != timestamp:\n            ceiling = MicrobatchBuilder.offset_timestamp(truncated, batch_size, 1)\n        return ceiling\n"
  },
  {
    "path": "core/dbt/mp_context.py",
    "content": "from multiprocessing import get_context\nfrom multiprocessing.context import SpawnContext\n\n_MP_CONTEXT = get_context(\"spawn\")\n\n\ndef get_mp_context() -> SpawnContext:\n    return _MP_CONTEXT\n"
  },
  {
    "path": "core/dbt/node_types.py",
    "content": "from typing import List\n\n# preserving import path during dbt/artifacts refactor\nfrom dbt.artifacts.resources.types import (  # noqa\n    AccessType,\n    ModelLanguage,\n    NodeType,\n    RunHookType,\n)\n\nEXECUTABLE_NODE_TYPES: List[\"NodeType\"] = [\n    NodeType.Model,\n    NodeType.Test,\n    NodeType.Snapshot,\n    NodeType.Analysis,\n    NodeType.Operation,\n    NodeType.Seed,\n    NodeType.Documentation,\n    NodeType.RPCCall,\n    NodeType.SqlOperation,\n    NodeType.Function,\n]\n\nREFABLE_NODE_TYPES: List[\"NodeType\"] = [\n    NodeType.Model,\n    NodeType.Seed,\n    NodeType.Snapshot,\n]\n\nTEST_NODE_TYPES: List[\"NodeType\"] = [\n    NodeType.Test,\n    NodeType.Unit,\n]\n\nVERSIONED_NODE_TYPES: List[\"NodeType\"] = [\n    NodeType.Model,\n]\n"
  },
  {
    "path": "core/dbt/parser/README.md",
    "content": "# Parser README\n\nThe parsing stage of dbt produces:\n* the 'manifest', a Python structure in the code\n* the project `target/manifest.json` file\n\n## Top Level Parsing steps\n\n1. Load the macro manifest (MacroManifest):\n\n* Inputs: SQL files in the 'macros' directory\n* Outputs: the MacroManifest encapsulated in a BaseAdapter; a pared down Manifest-type file which contains only macros and files (to be copied into the full Manifest)\n\nThe macro manifest takes the place of the full-fledged Manifest and contains only macros, which are used for resolving tests during parsing. The 'adapter' code retains a MacroManifest, while the mainline parsing code will have a full manifest. The class MacroParser assists in this process.\n\n2. Loads all internal 'projects' (i.e. has a `dbt_project.yml`) and all projects in the project path.\n\n3. Create a ManifestLoader object from the project dependencies and the current config.\n\n4. Read and parse the project files. Results are loaded into the ManifestLoader.  ManifestLoader loads the MacroManifest object into a BaseAdapter object.\n\n5. Write the partial parse results (the pickle file). This writes out the 'results' from the ManifestLoader, so the \"create the manifest\" step has not occured yet. Things yet to happen include patching the nodes, patching the macros, and processing refs, sources, and docs.\n\n6. Sources are patched. First, source tests are parsed. Nodes, sources, macros, docs, exposures, metadata, files, and selectors are copied into the Manifest by the ManifestLoader. And finally, nodes (from `results.patches`) are \"patched\" and macros too (from `results.macro_patches`).\n\n7. Process the manifest (refs, sources, docs).\n\t* Loops through all nodes, for each node find the node that matches\n\t* the sources refs, and adds the unique id of the source to each\n\t* node's 'depends_on'\n\n8. Check the Manifest and check for resource uniqueness.\n\n9. Build the flat graph\n\n10. Write out the target/manifest.json file.\n\n## Parse the project files\n\nThere are several parser-type objects. Each \"parser\" gets a list of of matching files specified by directory and ('dbt_project.yml', '*.sql', '*.yml', *.csv, or *.md)\n\n### ModelParser\n\ncode: core/dbt/parser/models.py. Most of the code is in SimpleSQLParser.\n\npaths: source\\_paths + `*.sql`\n\nManifest: nodes\n\n### SnapshotParser\n\ncode: core/dbt/parser/snapshots.py\n\npaths:  snapshot\\_paths + `*.sql`\n\n### AnalysisParser\n\ncode: core/dbt/parser/analysis.py\n\npaths: analysis\\_paths + `*.sql`\n\nManifest: nodes\n\n### DataTestParser\n\ncode: core/dbt/parser/data\\_test.py\n\npaths: test\\_paths + `*.sql`\n\nManifest: nodes\n\n### HookParser\n\ncode: core/dbt/parser/hooks.py\n\npaths: 'dbt\\_project.yml'\n\n### SeedParser\n\ncode: core/dbt/parser/seeds.py\n\npaths: data\\_paths + `*.csv`\n\n### DocumentationParser\n\ncode: core/dbt/parser/docs.py\n\npaths: docs\\_paths, `*.md`\n\nManifest: docs\n\n### SchemaParser\n\n* Input: yaml files\n* Output: various nodes in the Manifest and 'patch' files in the ParseResult/Manifest\n\ncode: core/dbt/parser/schemas.py\n\npaths: all\\_source\\_paths = source\\_paths, data\\_paths, snapshot\\_paths, analysis\\_paths, macro\\_paths,  `*.yml`\n\nThis \"parses\" the `.yml` (property) files in the dbt project. It loops through each yaml file and pulls out the tests in the various config sections and jinja renders them.\n\nA different sub-parser is called for each main dictionary key in the yaml.\n\n* 'models' - TestablePatchParser\n\t* plus 'patches' at create manifest time\n\t* Manifest: nodes\n* 'seeds' - TestablePatchParser\n* 'snapshots' - TestablePatchParser\n* 'sources' - SourceParser\n\t* plus 'patch\\_sources' at create manifest times\n\t* Manifest: sources\n* 'macros' - MacroPatchParser\n\t* plus 'macro\\_patches' at create manifest time\n\t* Manifest: macros\n* 'analyses' - AnalysisPatchParser\n* 'exposures' - SchemaParser.parse\\_exposures\n\t* no 'patches'\n\t* Manifest: exposures\n* 'groups' - SchemaParser.parse\\_groups\n\t* no 'patches'\n\t* Manifest: groups\n\n# dbt Manifest\n\n### nodes\n\nThese have executable SQL attached.\n\nModels\n- Are generated from SQL files in the 'models' directory\n- have a unique_id starting with 'model.'\n- Final object is a ModelNode\n\nSingular Tests\n- Are generated from SQL files in 'tests' directory\n- have a unique_id starting with 'test.'\n- Final object is a SingularTestNode\n\nGeneric Tests\n- Are generated from 'tests' in schema yaml files, which ultimately derive from tests in the 'macros' directory\n- Have a unique_id starting with 'test.'\n- Final object is a GenericTestNode\n- fqn is <project>.schema_test.<generated name>\n\nHooks\n- come from 'on-run-start' and 'on-run-end' config attributes.\n- have a unique_id starting with 'operation.'\n- FQN is of the form: [\"dbt_labs_internal_analytics\",\"hooks\",\"dbt_labs_internal_analytics-on-run-end-0\"]\n\nAnalysis\n- comes from SQL files in 'analysis' directory\n- Final object is a AnalysisNode\n\nRPC Node\n- This is a \"node\" representing the bit of Jinja-SQL that gets passed into the run_sql or compile_sql methods. When you're using the Cloud IDE, and you're working in a scratch tab, and you just want to compile/run what you have there: it needs to be parsed and executed, but it's not actually a model/node in the project, so it's this special thing. This is a temporary addition to the running manifest.\n\n- Object is a RPCNode\n\n### sources\n\n- comes from 'sources' sections in yaml files\n- Final object is a SourceDefinition node\n- have a unique_id starting with 'source.'\n\n### macros\n\n- comes from SQL files in 'macros' directory\n- Final object is a Macro node\n- have a unique_id starting with 'macro.'\n- Test macros are used in schema tests\n\n### docs\n\n- comes from .md files in 'docs' directory\n- Final object is a Documentation\n\n### exposures\n\n- comes from 'exposures' sections in yaml files\n- Final object is a Exposure node\n\n## Temporary patch files\n\nThe information in these structures is stored here by the schema parser, but should be resolved before the final manifest is written and do not show up in the written manifest. Ideally we'd like to skip this step and apply the changes directly to the nodes, macros, and sources instead. With the current staged parser we have to save this with the manifest information.\n\n### patches\n\n### macro_patches\n\n### source_patches\n\n## Other\n\n### selectors\n\nSelectors are set in config yaml files and can be used to determine which nodes should be 'compiled' and run. Selectors can also be done on the command line and will be in cli args.\n\n### disabled\n\nModels, sources, or other nodes that the user has disabled by setting enabled: false. They should be completely ignored by dbt, as if they don't exist. In its simplest/silliest form, it's a way to keep code around without deleting it. Some folks do cleverer things, like dynamically enabling/disabling certain models based on the database adapter type or the value of --vars.\n\n### files\n\nThis contains a list of all of the files that were processed with links to the nodes, docs, macros, sources, exposures, patches, macro_patches, source_patches, i.e. all of the other places that data is stored in the manifest. It also has a checksum of the contents. The 'files' structure is in the saved manifest, but not in the manifest.json file that is written out. It is used in partial parsing to determine whether to use previously generated nodes.\n\n### metadata\n\nFrom the ManifestMetadata class. Contains dbt_schema_version, project_id, user_id, send_anonymous_usage_stats, adapter_type\n\n### flat_graph\n\nUsed during execution in context.common (?). Builds dictionaries of nodes and sources. Not sure why this is used instead of the original nodes and sources. Not in the written manifest.\n\n### state_check\n\nThis used to be in ParseResults (not committed yet). The saved version of this is compared against the current version to see if we can use the saved Manifest. Contains var_hash, profile_hash, and project_hashes, to compare to the saved Manifest to see if things have changed that would invalidate it.\n\n## Written Manifest only\n\n### child_map\n\n### parent_map\n"
  },
  {
    "path": "core/dbt/parser/__init__.py",
    "content": "from . import (  # noqa\n    analysis,\n    base,\n    docs,\n    generic_test,\n    hooks,\n    macros,\n    models,\n    schemas,\n    singular_test,\n    snapshots,\n)\nfrom .analysis import AnalysisParser  # noqa\nfrom .base import ConfiguredParser, Parser  # noqa\nfrom .docs import DocumentationParser  # noqa\nfrom .generic_test import GenericTestParser  # noqa\nfrom .hooks import HookParser  # noqa\nfrom .macros import MacroParser  # noqa\nfrom .models import ModelParser  # noqa\nfrom .schemas import SchemaParser  # noqa\nfrom .seeds import SeedParser  # noqa\nfrom .singular_test import SingularTestParser  # noqa\nfrom .snapshots import SnapshotParser  # noqa\n"
  },
  {
    "path": "core/dbt/parser/analysis.py",
    "content": "import os\n\nfrom dbt.contracts.graph.nodes import AnalysisNode\nfrom dbt.node_types import NodeType\nfrom dbt.parser.base import SimpleSQLParser\nfrom dbt.parser.search import FileBlock\n\n\nclass AnalysisParser(SimpleSQLParser[AnalysisNode]):\n    def parse_from_dict(self, dct, validate=True) -> AnalysisNode:\n        if validate:\n            AnalysisNode.validate(dct)\n        return AnalysisNode.from_dict(dct)\n\n    @property\n    def resource_type(self) -> NodeType:\n        return NodeType.Analysis\n\n    @classmethod\n    def get_compiled_path(cls, block: FileBlock):\n        return os.path.join(\"analysis\", block.path.relative_path)\n"
  },
  {
    "path": "core/dbt/parser/base.py",
    "content": "import abc\nimport itertools\nimport os\nfrom typing import Any, Dict, Generic, List, Optional, TypeVar\n\nfrom dbt import deprecations, hooks, utils\nfrom dbt.adapters.factory import get_adapter  # noqa: F401\nfrom dbt.artifacts.resources import Contract, Export\nfrom dbt.clients.jinja import MacroGenerator, get_rendered\nfrom dbt.config import RuntimeConfig\nfrom dbt.context.context_config import ContextConfig\nfrom dbt.context.providers import (\n    generate_generate_name_macro_context,\n    generate_parser_model_context,\n)\nfrom dbt.contracts.files import SchemaSourceFile\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.contracts.graph.nodes import BaseNode, ManifestNode\nfrom dbt.contracts.graph.unparsed import Docs, UnparsedNode\nfrom dbt.exceptions import (\n    ConfigUpdateError,\n    DbtInternalError,\n    DictParseError,\n    InvalidAccessTypeError,\n    ParsingError,\n)\nfrom dbt.flags import get_flags\nfrom dbt.jsonschemas.jsonschemas import validate_model_config\nfrom dbt.node_types import AccessType, ModelLanguage, NodeType\nfrom dbt.parser.common import resource_types_to_schema_file_keys\nfrom dbt.parser.search import FileBlock\nfrom dbt_common.clients._jinja_blocks import ExtractWarning\nfrom dbt_common.dataclass_schema import ValidationError\nfrom dbt_common.utils import deep_merge\n\n# internally, the parser may store a less-restrictive type that will be\n# transformed into the final type. But it will have to be derived from\n# ParsedNode to be operable.\nFinalValue = TypeVar(\"FinalValue\", bound=BaseNode)\nIntermediateValue = TypeVar(\"IntermediateValue\", bound=BaseNode)\n\nFinalNode = TypeVar(\"FinalNode\", bound=ManifestNode)\n\n\nConfiguredBlockType = TypeVar(\"ConfiguredBlockType\", bound=FileBlock)\n\n\nclass BaseParser(Generic[FinalValue]):\n    def __init__(self, project: RuntimeConfig, manifest: Manifest) -> None:\n        self.project: RuntimeConfig = project\n        self.manifest: Manifest = manifest\n\n    @abc.abstractmethod\n    def parse_file(self, block: FileBlock) -> None:\n        pass\n\n    @abc.abstractproperty\n    def resource_type(self) -> NodeType:\n        pass\n\n    def generate_unique_id(self, resource_name: str, hash: Optional[str] = None) -> str:\n        \"\"\"Returns a unique identifier for a resource\n        An optional hash may be passed in to ensure uniqueness for edge cases\"\"\"\n\n        return \".\".join(\n            filter(None, [self.resource_type, self.project.project_name, resource_name, hash])\n        )\n\n    def _handle_extract_warning(self, warning: ExtractWarning, file: str) -> None:\n        deprecations.warn(\"unexpected-jinja-block-deprecation\", msg=warning.msg, file=file)\n\n\nclass Parser(BaseParser[FinalValue], Generic[FinalValue]):\n    def __init__(\n        self,\n        project: RuntimeConfig,\n        manifest: Manifest,\n        root_project: RuntimeConfig,\n    ) -> None:\n        super().__init__(project, manifest)\n        self.root_project = root_project\n\n\nclass RelationUpdate:\n    # \"component\" is database, schema or alias\n    def __init__(self, config: RuntimeConfig, manifest: Manifest, component: str) -> None:\n        default_macro = manifest.find_generate_macro_by_name(\n            component=component,\n            root_project_name=config.project_name,\n        )\n        if default_macro is None:\n            raise DbtInternalError(f\"No macro with name generate_{component}_name found\")\n\n        default_macro_context = generate_generate_name_macro_context(\n            default_macro, config, manifest\n        )\n        self.default_updater = MacroGenerator(default_macro, default_macro_context)\n\n        package_names = config.dependencies.keys() if config.dependencies else {}\n        package_updaters = {}\n        for package_name in package_names:\n            package_macro = manifest.find_generate_macro_by_name(\n                component=component,\n                root_project_name=config.project_name,\n                imported_package=package_name,\n            )\n            if package_macro:\n                imported_macro_context = generate_generate_name_macro_context(\n                    package_macro, config, manifest\n                )\n                package_updaters[package_macro.package_name] = MacroGenerator(\n                    package_macro, imported_macro_context\n                )\n\n        self.package_updaters = package_updaters\n        self.component = component\n\n    def __call__(self, parsed_node: Any, override: Optional[str]) -> None:\n        if getattr(parsed_node, \"package_name\", None) in self.package_updaters:\n            new_value = self.package_updaters[parsed_node.package_name](override, parsed_node)\n        else:\n            new_value = self.default_updater(override, parsed_node)\n\n        if isinstance(new_value, str):\n            new_value = new_value.strip()\n        setattr(parsed_node, self.component, new_value)\n\n\nclass ConfiguredParser(\n    Parser[FinalNode],\n    Generic[ConfiguredBlockType, FinalNode],\n):\n    def __init__(\n        self,\n        project: RuntimeConfig,\n        manifest: Manifest,\n        root_project: RuntimeConfig,\n    ) -> None:\n        super().__init__(project, manifest, root_project)\n\n        # this sets callables from RelationUpdate\n        self._update_node_database = RelationUpdate(\n            manifest=manifest, config=root_project, component=\"database\"\n        )\n        self._update_node_schema = RelationUpdate(\n            manifest=manifest, config=root_project, component=\"schema\"\n        )\n        self._update_node_alias = RelationUpdate(\n            manifest=manifest, config=root_project, component=\"alias\"\n        )\n\n    @classmethod\n    @abc.abstractmethod\n    def get_compiled_path(cls, block: ConfiguredBlockType) -> str:\n        pass\n\n    @abc.abstractmethod\n    def parse_from_dict(self, dict, validate=True) -> FinalNode:\n        pass\n\n    @abc.abstractproperty\n    def resource_type(self) -> NodeType:\n        pass\n\n    @property\n    def default_schema(self):\n        return self.root_project.credentials.schema\n\n    @property\n    def default_database(self):\n        return self.root_project.credentials.database\n\n    def get_fqn_prefix(self, path: str) -> List[str]:\n        no_ext = os.path.splitext(path)[0]\n        fqn = [self.project.project_name]\n        fqn.extend(utils.split_path(no_ext)[:-1])\n        return fqn\n\n    def get_fqn(self, path: str, name: str) -> List[str]:\n        \"\"\"Get the FQN for the node. This impacts node selection and config\n        application.\n        \"\"\"\n        fqn = self.get_fqn_prefix(path)\n        fqn.append(name)\n        return fqn\n\n    def _mangle_hooks(self, config):\n        \"\"\"Given a config dict that may have `pre-hook`/`post-hook` keys,\n        convert it from the yucky maybe-a-string, maybe-a-dict to a dict.\n        \"\"\"\n        # Like most of parsing, this is a horrible hack :(\n        for key in hooks.ModelHookType:\n            if key in config:\n                config[key] = [hooks.get_hook_dict(h) for h in config[key]]\n\n    def _create_error_node(\n        self, name: str, path: str, original_file_path: str, raw_code: str, language: str = \"sql\"\n    ) -> UnparsedNode:\n        \"\"\"If we hit an error before we've actually parsed a node, provide some\n        level of useful information by attaching this to the exception.\n        \"\"\"\n        # this is a bit silly, but build an UnparsedNode just for error\n        # message reasons\n        return UnparsedNode(\n            name=name,\n            resource_type=self.resource_type,\n            path=path,\n            original_file_path=original_file_path,\n            package_name=self.project.project_name,\n            raw_code=raw_code,\n            language=language,\n        )\n\n    def _create_parsetime_node(\n        self,\n        block: ConfiguredBlockType,\n        path: str,\n        config: ContextConfig,\n        fqn: List[str],\n        name=None,\n        **kwargs,\n    ) -> FinalNode:\n        \"\"\"Create the node that will be passed in to the parser context for\n        \"rendering\". Some information may be partial, as it'll be updated by\n        config() and any ref()/source() calls discovered during rendering.\n        \"\"\"\n        if name is None:\n            name = block.name\n        if block.path.relative_path.endswith(\".py\"):\n            language = ModelLanguage.python\n        else:\n            # this is not ideal but we have a lot of tests to adjust if don't do it\n            language = ModelLanguage.sql\n\n        dct = {\n            \"alias\": name,\n            \"schema\": self.default_schema,\n            \"database\": self.default_database,\n            \"fqn\": fqn,\n            \"name\": name,\n            \"resource_type\": self.resource_type,\n            \"path\": path,\n            \"original_file_path\": block.path.original_file_path,\n            \"package_name\": self.project.project_name,\n            \"raw_code\": block.contents or \"\",\n            \"language\": language,\n            \"unique_id\": self.generate_unique_id(name),\n            \"config\": self.config_dict(config),\n            \"checksum\": block.file.checksum.to_dict(omit_none=True),\n        }\n        dct.update(kwargs)\n\n        # TODO: we're doing this becaus return type is _required_ for the FunctionNode\n        # but we don't get the return type until we patch the node with the yml definition\n        # so we need to set it to a default value here.\n        if self.resource_type == NodeType.Function:\n            dct[\"returns\"] = {\"data_type\": \"INVALID_TYPE\"}\n\n        try:\n            return self.parse_from_dict(dct, validate=True)\n        except ValidationError as exc:\n            # this is a bit silly, but build an UnparsedNode just for error\n            # message reasons\n            node = self._create_error_node(\n                name=block.name,\n                path=path,\n                original_file_path=block.path.original_file_path,\n                raw_code=block.contents,\n            )\n            raise DictParseError(exc, node=node)\n\n    def _context_for(self, parsed_node: FinalNode, config: ContextConfig) -> Dict[str, Any]:\n        return generate_parser_model_context(parsed_node, self.root_project, self.manifest, config)\n\n    def render_with_context(self, parsed_node: FinalNode, config: ContextConfig):\n        # Given the parsed node and a ContextConfig to use during parsing,\n        # render the node's sql with macro capture enabled.\n        # Note: this mutates the config object when config calls are rendered.\n        context = self._context_for(parsed_node, config)\n\n        # this goes through the process of rendering, but just throws away\n        # the rendered result. The \"macro capture\" is the point?\n        get_rendered(parsed_node.raw_code, context, parsed_node, capture_macros=True)\n        return context\n\n    # This is taking the original config for the node, converting it to a dict,\n    # updating the config with new config passed in, then re-creating the\n    # config from the dict in the node.\n    def update_parsed_node_config_dict(\n        self, parsed_node: FinalNode, config_dict: Dict[str, Any]\n    ) -> None:\n        # Overwrite node config\n        final_config_dict = parsed_node.config.to_dict(omit_none=True)\n        final_config_dict.update({k.strip(): v for (k, v) in config_dict.items()})\n        # re-mangle hooks, in case we got new ones\n        self._mangle_hooks(final_config_dict)\n        parsed_node.config = parsed_node.config.from_dict(final_config_dict)\n\n    def update_parsed_node_relation_names(\n        self, parsed_node: FinalNode, config_dict: Dict[str, Any]\n    ) -> None:\n\n        # These call the RelationUpdate callable to go through generate_name macros\n        self._update_node_database(parsed_node, config_dict.get(\"database\"))\n        self._update_node_schema(parsed_node, config_dict.get(\"schema\"))\n        if not isinstance(parsed_node, Export) and parsed_node.schema is None:\n            if not get_flags().require_valid_schema_from_generate_schema_name:\n                deprecations.warn(\n                    \"generate-schema-name-null-value-deprecation\",\n                    resource_unique_id=parsed_node.unique_id,\n                )\n            else:\n                raise ParsingError(\n                    f\"Node '{parsed_node.unique_id}' has a schema set to None as a result of a generate_schema_name call.\\nPlease set a valid schema name, or preserve the legacy behavior by setting the behavior flag 'require_valid_schema_from_generate_schema_name' to True.\"\n                )\n\n        self._update_node_alias(parsed_node, config_dict.get(\"alias\"))\n\n        # Snapshot nodes use special \"target_database\" and \"target_schema\" fields\n        # for backward compatibility\n        # We have to do getattr here because saved_query parser calls this method with\n        # Export object instead of a node.\n        if getattr(parsed_node, \"resource_type\", None) == NodeType.Snapshot:\n            if \"target_database\" in config_dict and config_dict[\"target_database\"]:\n                parsed_node.database = config_dict[\"target_database\"]\n            if \"target_schema\" in config_dict and config_dict[\"target_schema\"]:\n                parsed_node.schema = config_dict[\"target_schema\"]\n\n        self._update_node_relation_name(parsed_node)\n\n    def update_parsed_node_config(\n        self,\n        parsed_node: FinalNode,\n        config: ContextConfig,\n        context=None,\n        patch_config_dict=None,\n        patch_file_id=None,\n        validate_config_call_dict: bool = False,\n    ) -> None:\n        \"\"\"Given the ContextConfig used for parsing and the parsed node,\n        generate and set the true values to use, overriding the temporary parse\n        values set in _build_intermediate_parsed_node.\n        \"\"\"\n\n        # build_config_dict takes the config_call_dict in the ContextConfig object\n        # and calls calculate_node_config to combine dbt_project configs and\n        # config calls from SQL files, plus patch configs (from schema files)\n        # This normalize the config for a model node due #8520; should be improved latter\n        if not patch_config_dict:\n            patch_config_dict = {}\n        if (\n            parsed_node.resource_type == NodeType.Model\n            and parsed_node.language == ModelLanguage.python\n        ):\n            if \"materialized\" not in patch_config_dict:\n                patch_config_dict[\"materialized\"] = \"table\"\n        config_dict = config.build_config_dict(patch_config_dict=patch_config_dict)\n\n        # Set tags on node provided in config blocks. Tags are additive, so even if\n        # config has been built before, we don't have to reset tags in the parsed_node.\n        model_tags = config_dict.get(\"tags\", [])\n        for tag in model_tags:\n            if tag not in parsed_node.tags:\n                parsed_node.tags.append(tag)\n\n        # If we have meta in the config, copy to node level, for backwards\n        # compatibility with earlier node-only config.\n        if \"meta\" in config_dict and config_dict[\"meta\"]:\n            parsed_node.meta = config_dict[\"meta\"]\n\n        # If we have group in the config, copy to node level\n        if \"group\" in config_dict and config_dict[\"group\"]:\n            parsed_node.group = config_dict[\"group\"]\n\n        # If we have access in the config, copy to node level\n        if parsed_node.resource_type == NodeType.Model and config_dict.get(\"access\", None):\n            if AccessType.is_valid(config_dict[\"access\"]):\n                assert hasattr(parsed_node, \"access\")\n                parsed_node.access = AccessType(config_dict[\"access\"])\n            else:\n                raise InvalidAccessTypeError(\n                    unique_id=parsed_node.unique_id, field_value=config_dict[\"access\"]\n                )\n\n        # If we have docs in the config, merge with the node level, for backwards\n        # compatibility with earlier node-only config.\n        if \"docs\" in config_dict and config_dict[\"docs\"]:\n            # we set show at the value of the config if it is set, otherwise, inherit the value\n            docs_show = (\n                config_dict[\"docs\"][\"show\"]\n                if \"show\" in config_dict[\"docs\"]\n                else parsed_node.docs.show\n            )\n            if \"node_color\" in config_dict[\"docs\"]:\n                parsed_node.docs = Docs(\n                    show=docs_show, node_color=config_dict[\"docs\"][\"node_color\"]\n                )\n            else:\n                parsed_node.docs = Docs(show=docs_show)\n\n        # If we have contract in the config, copy to node level\n        if \"contract\" in config_dict and config_dict[\"contract\"]:\n            contract_dct = config_dict[\"contract\"]\n            Contract.validate(contract_dct)\n            # Seed node has contract config (from NodeConfig) but no contract in SeedNode\n            if hasattr(parsed_node, \"contract\"):\n                parsed_node.contract = Contract.from_dict(contract_dct)\n\n        if get_flags().state_modified_compare_more_unrendered_values:\n            # Use the patch_file.unrendered_configs if available to update patch_dict_config,\n            # as provided patch_config_dict may actually already be rendered and thus sensitive to jinja evaluations\n            if patch_file_id:\n                patch_file = self.manifest.files.get(patch_file_id, None)\n                if patch_file and isinstance(patch_file, SchemaSourceFile):\n                    schema_key = resource_types_to_schema_file_keys.get(parsed_node.resource_type)\n                    if schema_key:\n                        if unrendered_patch_config := patch_file.get_unrendered_config(\n                            schema_key, parsed_node.name, getattr(parsed_node, \"version\", None)\n                        ):\n                            patch_config_dict = deep_merge(\n                                patch_config_dict, unrendered_patch_config\n                            )\n\n        # unrendered_config is used to compare the original database/schema/alias\n        # values and to handle 'same_config' and 'same_contents' calls\n        parsed_node.unrendered_config = config.build_config_dict(\n            rendered=False, patch_config_dict=patch_config_dict\n        )\n\n        # We validate the _config_call_dict here because there is more than\n        # one way that the _config_call_dict can be set and also, later it gets\n        # read multiple times. Doing the validation here ensures that the config\n        # is only validated once.\n        if parsed_node.resource_type == NodeType.Model and validate_config_call_dict:\n            python_model = parsed_node.language == ModelLanguage.python\n            validate_model_config(\n                config._config_call_dict,\n                parsed_node.original_file_path,\n                is_python_model=python_model,\n            )\n\n        parsed_node.config_call_dict = config._config_call_dict\n        parsed_node.unrendered_config_call_dict = config._unrendered_config_call_dict\n\n        # do this once before we parse the node database/schema/alias, so\n        # parsed_node.config is what it would be if they did nothing\n        self.update_parsed_node_config_dict(parsed_node, config_dict)\n        # This updates the node database/schema/alias/relation_name\n        self.update_parsed_node_relation_names(parsed_node, config_dict)\n\n        # tests don't have hooks\n        if parsed_node.resource_type == NodeType.Test:\n            return\n\n        # at this point, we've collected our hooks. Use the node context to\n        # render each hook and collect refs/sources\n        assert hasattr(parsed_node.config, \"pre_hook\") and hasattr(parsed_node.config, \"post_hook\")\n        hooks = list(itertools.chain(parsed_node.config.pre_hook, parsed_node.config.post_hook))\n        # skip context rebuilding if there aren't any hooks\n        if not hooks:\n            return\n        if not context:\n            context = self._context_for(parsed_node, config)\n        for hook in hooks:\n            get_rendered(hook.sql, context, parsed_node, capture_macros=True)\n\n    def initial_config(self, fqn: List[str]) -> ContextConfig:\n        config_version = min([self.project.config_version, self.root_project.config_version])\n        if config_version == 2:\n            return ContextConfig(\n                self.root_project,\n                fqn,\n                self.resource_type,\n                self.project.project_name,\n            )\n        else:\n            raise DbtInternalError(\n                f\"Got an unexpected project version={config_version}, expected 2\"\n            )\n\n    def config_dict(\n        self,\n        config: ContextConfig,\n    ) -> Dict[str, Any]:\n        config_dict = config.build_config_dict(base=True)\n        self._mangle_hooks(config_dict)\n        return config_dict\n\n    def render_update(\n        self, node: FinalNode, config: ContextConfig, validate_config_call_dict: bool = False\n    ) -> None:\n        try:\n            context = self.render_with_context(node, config)\n            self.update_parsed_node_config(\n                node, config, context=context, validate_config_call_dict=validate_config_call_dict\n            )\n        except ValidationError as exc:\n            # we got a ValidationError - probably bad types in config()\n            raise ConfigUpdateError(exc, node=node) from exc\n\n    def add_result_node(self, block: FileBlock, node: ManifestNode):\n        if node.config.enabled:\n            self.manifest.add_node(block.file, node)\n        else:\n            self.manifest.add_disabled(block.file, node)\n\n    def parse_node(self, block: ConfiguredBlockType) -> FinalNode:\n        compiled_path: str = self.get_compiled_path(block)\n        fqn = self.get_fqn(compiled_path, block.name)\n\n        config: ContextConfig = self.initial_config(fqn)\n\n        node = self._create_parsetime_node(\n            block=block,\n            path=compiled_path,\n            config=config,\n            fqn=fqn,\n        )\n        self.render_update(node, config)\n        self.add_result_node(block, node)\n        return node\n\n    def _update_node_relation_name(self, node: ManifestNode):\n        # Seed and Snapshot nodes and Models that are not ephemeral,\n        # and TestNodes that store_failures.\n        # TestNodes do not get a relation_name without store failures\n        # because no schema is created.\n        if getattr(node, \"is_relational\", None) and not getattr(node, \"is_ephemeral_model\", None):\n            adapter = get_adapter(self.root_project)\n            relation_cls = adapter.Relation\n            node.relation_name = str(relation_cls.create_from(self.root_project, node))\n        else:\n            # Set it to None in case it changed with a config update\n            node.relation_name = None\n\n    @abc.abstractmethod\n    def parse_file(self, file_block: FileBlock) -> None:\n        pass\n\n\nclass SimpleParser(\n    ConfiguredParser[ConfiguredBlockType, FinalNode],\n    Generic[ConfiguredBlockType, FinalNode],\n):\n    pass\n\n\nclass SQLParser(ConfiguredParser[FileBlock, FinalNode], Generic[FinalNode]):\n    def parse_file(self, file_block: FileBlock) -> None:\n        self.parse_node(file_block)\n\n\nclass SimpleSQLParser(SQLParser[FinalNode]):\n    pass\n"
  },
  {
    "path": "core/dbt/parser/common.py",
    "content": "from dataclasses import dataclass\nfrom typing import Any, Dict, Generic, List, Optional, TypeVar, Union\n\nfrom dbt.artifacts.resources import (\n    ColumnConfig,\n    ColumnDimension,\n    ColumnEntity,\n    ColumnInfo,\n    NodeVersion,\n)\nfrom dbt.contracts.graph.nodes import UnpatchedSourceDefinition\nfrom dbt.contracts.graph.unparsed import (\n    HasColumnDocs,\n    HasColumnProps,\n    HasColumnTests,\n    UnparsedAnalysisUpdate,\n    UnparsedColumn,\n    UnparsedColumnEntityV2,\n    UnparsedDimensionV2,\n    UnparsedExposure,\n    UnparsedFunctionUpdate,\n    UnparsedMacroUpdate,\n    UnparsedModelUpdate,\n    UnparsedNodeUpdate,\n    UnparsedSingularTestUpdate,\n)\nfrom dbt.exceptions import ParsingError\nfrom dbt.node_types import NodeType\nfrom dbt.parser.search import FileBlock\nfrom dbt_common.contracts.constraints import ColumnLevelConstraint, ConstraintType\nfrom dbt_common.exceptions import DbtInternalError\nfrom dbt_semantic_interfaces.type_enums import (\n    DimensionType,\n    EntityType,\n    TimeGranularity,\n)\n\nschema_file_keys_to_resource_types = {\n    \"models\": NodeType.Model,\n    \"seeds\": NodeType.Seed,\n    \"snapshots\": NodeType.Snapshot,\n    \"sources\": NodeType.Source,\n    \"macros\": NodeType.Macro,\n    \"analyses\": NodeType.Analysis,\n    \"exposures\": NodeType.Exposure,\n    \"metrics\": NodeType.Metric,\n    \"semantic_models\": NodeType.SemanticModel,\n    \"saved_queries\": NodeType.SavedQuery,\n    \"functions\": NodeType.Function,\n}\n\nresource_types_to_schema_file_keys = {\n    v: k for (k, v) in schema_file_keys_to_resource_types.items()\n}\n\nschema_file_keys = list(schema_file_keys_to_resource_types.keys())\n\n\ndef trimmed(inp: str) -> str:\n    if len(inp) < 50:\n        return inp\n    return inp[:44] + \"...\" + inp[-3:]\n\n\nTestDef = Union[str, Dict[str, Any]]\n\n\nTarget = TypeVar(\n    \"Target\",\n    UnparsedNodeUpdate,\n    UnparsedMacroUpdate,\n    UnparsedAnalysisUpdate,\n    UnpatchedSourceDefinition,\n    UnparsedExposure,\n    UnparsedModelUpdate,\n    UnparsedFunctionUpdate,\n    UnparsedSingularTestUpdate,\n)\n\n\nColumnTarget = TypeVar(\n    \"ColumnTarget\",\n    UnparsedModelUpdate,\n    UnparsedNodeUpdate,\n    UnparsedAnalysisUpdate,\n    UnpatchedSourceDefinition,\n)\n\nVersioned = TypeVar(\"Versioned\", bound=UnparsedModelUpdate)\n\nTestable = TypeVar(\"Testable\", UnparsedNodeUpdate, UnpatchedSourceDefinition, UnparsedModelUpdate)\n\n\n@dataclass\nclass YamlBlock(FileBlock):\n    data: Dict[str, Any]\n\n    @classmethod\n    def from_file_block(cls, src: FileBlock, data: Dict[str, Any]):\n        return cls(\n            file=src.file,\n            data=data,\n        )\n\n\n@dataclass\nclass TargetBlock(YamlBlock, Generic[Target]):\n    target: Target\n\n    @property\n    def name(self):\n        return self.target.name\n\n    @property\n    def columns(self):\n        return []\n\n    @property\n    def data_tests(self) -> List[TestDef]:\n        return []\n\n    @property\n    def tests(self) -> List[TestDef]:\n        return []\n\n    @classmethod\n    def from_yaml_block(cls, src: YamlBlock, target: Target) -> \"TargetBlock[Target]\":\n        return cls(\n            file=src.file,\n            data=src.data,\n            target=target,\n        )\n\n\n@dataclass\nclass TargetColumnsBlock(TargetBlock[ColumnTarget], Generic[ColumnTarget]):\n    @property\n    def columns(self):\n        if self.target.columns is None:\n            return []\n        else:\n            return self.target.columns\n\n\n@dataclass\nclass TestBlock(TargetColumnsBlock[Testable], Generic[Testable]):\n    @property\n    def data_tests(self) -> List[TestDef]:\n        if self.target.data_tests is None:\n            return []\n        else:\n            return self.target.data_tests\n\n    @property\n    def quote_columns(self) -> Optional[bool]:\n        return self.target.quote_columns\n\n    @classmethod\n    def from_yaml_block(cls, src: YamlBlock, target: Testable) -> \"TestBlock[Testable]\":\n        return cls(\n            file=src.file,\n            data=src.data,\n            target=target,\n        )\n\n\n@dataclass\nclass VersionedTestBlock(TestBlock, Generic[Versioned]):\n    @property\n    def columns(self):\n        if not self.target.versions:\n            return super().columns\n        else:\n            raise DbtInternalError(\".columns for VersionedTestBlock with versions\")\n\n    @property\n    def data_tests(self) -> List[TestDef]:\n        if not self.target.versions:\n            return super().data_tests\n        else:\n            raise DbtInternalError(\".data_tests for VersionedTestBlock with versions\")\n\n    @classmethod\n    def from_yaml_block(cls, src: YamlBlock, target: Versioned) -> \"VersionedTestBlock[Versioned]\":\n        return cls(\n            file=src.file,\n            data=src.data,\n            target=target,\n        )\n\n\n@dataclass\nclass GenericTestBlock(TestBlock[Testable], Generic[Testable]):\n    data_test: Dict[str, Any]\n    column_name: Optional[str]\n    tags: List[str]\n    version: Optional[NodeVersion]\n\n    @classmethod\n    def from_test_block(\n        cls,\n        src: TestBlock,\n        data_test: Dict[str, Any],\n        column_name: Optional[str],\n        tags: List[str],\n        version: Optional[NodeVersion],\n    ) -> \"GenericTestBlock\":\n        return cls(\n            file=src.file,\n            data=src.data,\n            target=src.target,\n            data_test=data_test,\n            column_name=column_name,\n            tags=tags,\n            version=version,\n        )\n\n\nclass ParserRef:\n    \"\"\"A helper object to hold parse-time references.\"\"\"\n\n    def __init__(self) -> None:\n        self.column_info: Dict[str, ColumnInfo] = {}\n\n    def _add(self, column: HasColumnProps) -> None:\n        tags: List[str] = getattr(column, \"tags\", [])\n        quote: Optional[bool] = None\n        granularity: Optional[TimeGranularity] = None\n        dimension: Optional[Union[DimensionType, ColumnDimension]] = None\n        entity: Optional[Union[EntityType, ColumnEntity]] = None\n        if isinstance(column, UnparsedColumn):\n            quote = column.quote\n            granularity = TimeGranularity(column.granularity) if column.granularity else None\n            if isinstance(column.dimension, UnparsedDimensionV2):\n                dimension = ColumnDimension(\n                    name=column.dimension.name or column.name,\n                    type=(DimensionType(column.dimension.type)),\n                    description=column.dimension.description or column.description,\n                    label=column.dimension.label,\n                    is_partition=column.dimension.is_partition,\n                    config=column.dimension.config or {},\n                    validity_params=(\n                        ColumnDimension.ColumnDimensionValidityParams(\n                            is_start=column.dimension.validity_params.is_start,\n                            is_end=column.dimension.validity_params.is_end,\n                        )\n                        if column.dimension.validity_params\n                        else None\n                    ),\n                )\n            elif isinstance(column.dimension, str):\n                dimension = DimensionType(column.dimension)\n\n            if isinstance(column.entity, UnparsedColumnEntityV2):\n                entity = ColumnEntity(\n                    name=column.entity.name,\n                    type=EntityType(column.entity.type),\n                    description=column.entity.description or column.description,\n                    label=column.entity.label,\n                    config=column.entity.config or {},\n                )\n            elif isinstance(column.entity, str):\n                entity = EntityType(column.entity)\n\n        if any(\n            c\n            for c in column.constraints\n            if \"type\" not in c or not ConstraintType.is_valid(c[\"type\"])\n        ):\n            raise ParsingError(f\"Invalid constraint type on column {column.name}\")\n\n        # Merge meta and tags from column and config\n        column_config_meta = (\n            column.config[\"meta\"] if isinstance(column.config.get(\"meta\"), dict) else {}\n        )\n        column_config_tags = []\n        if \"tags\" in column.config:\n            if isinstance(column.config[\"tags\"], list):\n                column_config_tags = column.config[\"tags\"]\n            elif isinstance(column.config[\"tags\"], str):\n                column_config_tags = [column.config[\"tags\"]]\n\n        column_meta = {**column.meta, **column_config_meta}\n        column_tags = list(set(tags + column_config_tags))\n        self.column_info[column.name] = ColumnInfo(\n            name=column.name,\n            description=column.description,\n            data_type=column.data_type,\n            constraints=[ColumnLevelConstraint.from_dict(c) for c in column.constraints],\n            meta=column_meta,\n            tags=column_tags,\n            quote=quote,\n            _extra=column.extra,\n            granularity=granularity,\n            dimension=dimension,\n            entity=entity,\n            config=ColumnConfig(meta=column_meta, tags=column_tags),\n        )\n\n    @classmethod\n    def from_target(cls, target: Union[HasColumnDocs, HasColumnTests]) -> \"ParserRef\":\n        refs = cls()\n        for column in target.columns:\n            refs._add(column)\n        return refs\n\n    @classmethod\n    def from_versioned_target(cls, target: Versioned, version: NodeVersion) -> \"ParserRef\":\n        refs = cls()\n        for base_column in target.get_columns_for_version(version):\n            refs._add(base_column)\n        return refs\n"
  },
  {
    "path": "core/dbt/parser/docs.py",
    "content": "import re\nfrom typing import Iterable, Optional\n\nfrom dbt.clients.jinja import get_rendered\nfrom dbt.contracts.files import SourceFile\nfrom dbt.contracts.graph.nodes import Documentation\nfrom dbt.node_types import NodeType\nfrom dbt.parser.base import Parser\nfrom dbt.parser.search import BlockContents, BlockSearcher, FileBlock\n\nSHOULD_PARSE_RE = re.compile(r\"{[{%]\")\n\n\nclass DocumentationParser(Parser[Documentation]):\n    @property\n    def resource_type(self) -> NodeType:\n        return NodeType.Documentation\n\n    @classmethod\n    def get_compiled_path(cls, block: FileBlock):\n        return block.path.relative_path\n\n    def generate_unique_id(self, resource_name: str, _: Optional[str] = None) -> str:\n        # For consistency, use the same format for doc unique_ids\n        return f\"doc.{self.project.project_name}.{resource_name}\"\n\n    def parse_block(self, block: BlockContents) -> Iterable[Documentation]:\n        unique_id = self.generate_unique_id(block.name)\n        contents = get_rendered(block.contents, {}).strip()\n\n        doc = Documentation(\n            path=block.file.path.relative_path,\n            original_file_path=block.path.original_file_path,\n            package_name=self.project.project_name,\n            unique_id=unique_id,\n            name=block.name,\n            block_contents=contents,\n            resource_type=NodeType.Documentation,\n        )\n        return [doc]\n\n    def parse_file(self, file_block: FileBlock):\n        assert isinstance(file_block.file, SourceFile)\n        searcher: Iterable[BlockContents] = BlockSearcher(\n            source=[file_block],\n            allowed_blocks={\"docs\"},\n            source_tag_factory=BlockContents,\n            check_jinja=False,\n        )\n        for block in searcher:\n            for parsed in self.parse_block(block):\n                self.manifest.add_doc(file_block.file, parsed)\n"
  },
  {
    "path": "core/dbt/parser/fixtures.py",
    "content": "import csv\nfrom io import StringIO\nfrom typing import Any, Dict, List, Optional\n\nfrom dbt.contracts.files import FixtureSourceFile\nfrom dbt.contracts.graph.nodes import UnitTestFileFixture\nfrom dbt.node_types import NodeType\nfrom dbt.parser.base import Parser\nfrom dbt.parser.search import FileBlock\n\n\nclass FixtureParser(Parser[UnitTestFileFixture]):\n    @property\n    def resource_type(self) -> NodeType:\n        return NodeType.Fixture\n\n    @classmethod\n    def get_compiled_path(cls, block: FileBlock):\n        # Is this necessary?\n        return block.path.relative_path\n\n    def generate_unique_id(self, resource_name: str, _: Optional[str] = None) -> str:\n        return f\"fixture.{self.project.project_name}.{resource_name}\"\n\n    def parse_file(self, file_block: FileBlock):\n        assert isinstance(file_block.file, FixtureSourceFile)\n        unique_id = self.generate_unique_id(file_block.name)\n\n        if file_block.file.path.relative_path.endswith(\".sql\"):\n            rows = file_block.file.contents  # type: ignore\n        else:  # endswith('.csv')\n            rows = self.get_rows(file_block.file.contents)  # type: ignore\n\n        fixture = UnitTestFileFixture(\n            name=file_block.name,\n            path=file_block.file.path.relative_path,\n            original_file_path=file_block.path.original_file_path,\n            package_name=self.project.project_name,\n            unique_id=unique_id,\n            resource_type=NodeType.Fixture,\n            rows=rows,\n        )\n        self.manifest.add_fixture(file_block.file, fixture)\n\n    def get_rows(self, contents) -> List[Dict[str, Any]]:\n        rows = []\n        dummy_file = StringIO(contents)\n        reader = csv.DictReader(dummy_file)\n        for row in reader:\n            rows.append(row)\n        return rows\n"
  },
  {
    "path": "core/dbt/parser/functions.py",
    "content": "from dbt.artifacts.resources.types import NodeType\nfrom dbt.contracts.files import SourceFile\nfrom dbt.contracts.graph.nodes import FunctionNode, ManifestNode\nfrom dbt.parser.base import SimpleParser\nfrom dbt.parser.search import FileBlock\n\n\nclass FunctionParser(SimpleParser[FileBlock, FunctionNode]):\n    def parse_from_dict(self, dct, validate=True) -> FunctionNode:\n        if validate:\n            FunctionNode.validate(dct)\n        return FunctionNode.from_dict(dct)\n\n    @property\n    def resource_type(self) -> NodeType:\n        return NodeType.Function\n\n    @classmethod\n    def get_compiled_path(cls, block: FileBlock):\n        return block.path.relative_path\n\n    # overrides SimpleSQLParser.add_result_node\n    def add_result_node(self, block: FileBlock, node: ManifestNode):\n        assert isinstance(node, FunctionNode), \"Got non FunctionNode in FunctionParser\"\n        file = block.file\n        assert isinstance(file, SourceFile)\n        if node.config.enabled:\n            self.manifest.add_function(file, node)\n        else:\n            self.manifest.add_disabled(file, node)\n\n    def parse_file(self, file_block: FileBlock) -> None:\n        self.parse_node(file_block)\n"
  },
  {
    "path": "core/dbt/parser/generic_test.py",
    "content": "from typing import Iterable, List\n\nimport jinja2\n\nfrom dbt.contracts.files import SourceFile\nfrom dbt.contracts.graph.nodes import GenericTestNode, Macro\nfrom dbt.contracts.graph.unparsed import UnparsedMacro\nfrom dbt.exceptions import ParsingError\nfrom dbt.node_types import NodeType\nfrom dbt.parser.base import BaseParser\nfrom dbt.parser.search import FileBlock\nfrom dbt_common.clients import jinja\nfrom dbt_common.utils import MACRO_PREFIX\n\n\nclass GenericTestParser(BaseParser[GenericTestNode]):\n    @property\n    def resource_type(self) -> NodeType:\n        return NodeType.Macro\n\n    @classmethod\n    def get_compiled_path(cls, block: FileBlock):\n        return block.path.relative_path\n\n    def create_generic_test_macro(\n        self, block: jinja.BlockTag, base_node: UnparsedMacro, name: str\n    ) -> Macro:\n        unique_id = self.generate_unique_id(name)\n        macro_sql = block.full_block or \"\"\n\n        return Macro(\n            path=base_node.path,\n            macro_sql=macro_sql,\n            original_file_path=base_node.original_file_path,\n            package_name=base_node.package_name,\n            resource_type=base_node.resource_type,\n            name=name,\n            unique_id=unique_id,\n        )\n\n    def parse_unparsed_generic_test(self, base_node: UnparsedMacro) -> Iterable[Macro]:\n        try:\n            blocks: List[jinja.BlockTag] = [\n                t\n                for t in jinja.extract_toplevel_blocks(\n                    base_node.raw_code,\n                    allowed_blocks={\"test\", \"data_test\"},\n                    collect_raw_data=False,\n                )\n                if isinstance(t, jinja.BlockTag)\n            ]\n        except ParsingError as exc:\n            exc.add_node(base_node)\n            raise\n\n        for block in blocks:\n            try:\n                ast = jinja.parse(block.full_block)\n            except ParsingError as e:\n                e.add_node(base_node)\n                raise\n\n            # generic tests are structured as macros so we want to count the number of macro blocks\n            generic_test_nodes = list(ast.find_all(jinja2.nodes.Macro))\n\n            if len(generic_test_nodes) != 1:\n                # things have gone disastrously wrong, we thought we only\n                # parsed one block!\n                raise ParsingError(\n                    f\"Found multiple generic tests in {block.full_block}, expected 1\",\n                    node=base_node,\n                )\n\n            generic_test_name = generic_test_nodes[0].name\n\n            if not generic_test_name.startswith(MACRO_PREFIX):\n                continue\n\n            name: str = generic_test_name.replace(MACRO_PREFIX, \"\")\n            node = self.create_generic_test_macro(block, base_node, name)\n            yield node\n\n    def parse_file(self, block: FileBlock):\n        assert isinstance(block.file, SourceFile)\n        source_file = block.file\n        assert isinstance(source_file.contents, str)\n        original_file_path = source_file.path.original_file_path\n\n        # this is really only used for error messages\n        base_node = UnparsedMacro(\n            path=original_file_path,\n            original_file_path=original_file_path,\n            package_name=self.project.project_name,\n            raw_code=source_file.contents,\n            resource_type=NodeType.Macro,\n            language=\"sql\",\n        )\n\n        for node in self.parse_unparsed_generic_test(base_node):\n            self.manifest.add_macro(block.file, node)\n"
  },
  {
    "path": "core/dbt/parser/generic_test_builders.py",
    "content": "import re\nfrom copy import deepcopy\nfrom typing import Any, Dict, Generic, List, Optional, Tuple\n\nfrom dbt import deprecations\nfrom dbt.artifacts.resources import NodeVersion\nfrom dbt.clients.jinja import GENERIC_TEST_KWARGS_NAME, get_rendered\nfrom dbt.contracts.graph.nodes import UnpatchedSourceDefinition\nfrom dbt.contracts.graph.unparsed import UnparsedModelUpdate, UnparsedNodeUpdate\nfrom dbt.exceptions import (\n    CustomMacroPopulatingConfigValueError,\n    SameKeyNestedError,\n    TagNotStringError,\n    TagsNotListOfStringsError,\n    TestArgIncludesModelError,\n    TestArgsNotDictError,\n    TestConfigNotDictError,\n    TestDefinitionDictLengthError,\n    TestNameNotStringError,\n    TestTypeError,\n    UnexpectedTestNamePatternError,\n)\nfrom dbt.flags import get_flags\nfrom dbt.parser.common import Testable\nfrom dbt.utils import md5\nfrom dbt_common.exceptions.macros import UndefinedMacroError\n\n\ndef synthesize_generic_test_names(\n    test_type: str, test_name: str, args: Dict[str, Any]\n) -> Tuple[str, str]:\n    # Using the type, name, and arguments to this generic test, synthesize a (hopefully) unique name\n    # Will not be unique if multiple tests have same name + arguments, and only configs differ\n    # Returns a shorter version (hashed/truncated, for the compiled file)\n    # as well as the full name (for the unique_id + FQN)\n    flat_args = []\n    for arg_name in sorted(args):\n        # the model is already embedded in the name, so skip it\n        if arg_name == \"model\":\n            continue\n        arg_val = args[arg_name]\n\n        if isinstance(arg_val, dict):\n            parts = list(arg_val.values())\n        elif isinstance(arg_val, (list, tuple)):\n            parts = list(arg_val)\n        else:\n            parts = [arg_val]\n\n        flat_args.extend([str(part) for part in parts])\n\n    clean_flat_args = [re.sub(\"[^0-9a-zA-Z_]+\", \"_\", arg) for arg in flat_args]\n    unique = \"__\".join(clean_flat_args)\n\n    # for the file path + alias, the name must be <64 characters\n    # if the full name is too long, include the first 30 identifying chars plus\n    # a 32-character hash of the full contents\n\n    test_identifier = \"{}_{}\".format(test_type, test_name)\n    full_name = \"{}_{}\".format(test_identifier, unique)\n\n    if len(full_name) >= 64:\n        test_trunc_identifier = test_identifier[:30]\n        label = md5(full_name)\n        short_name = \"{}_{}\".format(test_trunc_identifier, label)\n    else:\n        short_name = full_name\n\n    return short_name, full_name\n\n\nclass TestBuilder(Generic[Testable]):\n    \"\"\"An object to hold assorted test settings and perform basic parsing\n\n    Test names have the following pattern:\n        - the test name itself may be namespaced (package.test)\n        - or it may not be namespaced (test)\n\n    \"\"\"\n\n    # The 'test_name' is used to find the 'macro' that implements the test\n    TEST_NAME_PATTERN = re.compile(\n        r\"((?P<test_namespace>([a-zA-Z_][0-9a-zA-Z_]*))\\.)?\"\n        r\"(?P<test_name>([a-zA-Z_][0-9a-zA-Z_]*))\"\n    )\n    # args in the test entry representing test configs\n    CONFIG_ARGS = (\n        \"severity\",\n        \"tags\",\n        \"enabled\",\n        \"where\",\n        \"limit\",\n        \"warn_if\",\n        \"error_if\",\n        \"fail_calc\",\n        \"store_failures\",\n        \"store_failures_as\",\n        \"sql_header\",\n        \"meta\",\n        \"database\",\n        \"schema\",\n        \"alias\",\n    )\n\n    def __init__(\n        self,\n        data_test: Dict[str, Any],\n        target: Testable,\n        package_name: str,\n        render_ctx: Dict[str, Any],\n        column_name: Optional[str] = None,\n        version: Optional[NodeVersion] = None,\n    ) -> None:\n        test_name, test_args = self.extract_test_args(\n            data_test, target.original_file_path, target.name, column_name, package_name\n        )\n        self.args: Dict[str, Any] = test_args\n        if \"model\" in self.args:\n            raise TestArgIncludesModelError()\n        self.package_name: str = package_name\n        self.target: Testable = target\n        self.version: Optional[NodeVersion] = version\n        self.render_ctx: Dict[str, Any] = render_ctx\n        self.column_name: Optional[str] = column_name\n        self.args[\"model\"] = self.build_model_str()\n\n        match = self.TEST_NAME_PATTERN.match(test_name)\n        if match is None:\n            raise UnexpectedTestNamePatternError(test_name)\n\n        groups = match.groupdict()\n        self.name: str = groups[\"test_name\"]\n        self.namespace: str = groups[\"test_namespace\"]\n        self.config: Dict[str, Any] = {}\n        # Process legacy args\n        self.config.update(self._process_legacy_args())\n\n        # Process config args if present\n        if \"config\" in self.args:\n            self.config.update(self._render_values(self.args.pop(\"config\", {})))\n\n        # Gate sql_header behind behavior change flag\n        if (\n            self.config.get(\"sql_header\") is not None\n            and not get_flags().require_sql_header_in_test_configs\n        ):\n            deprecations.warn(\n                \"custom-key-in-config-deprecation\",\n                key=\"sql_header\",\n                file=target.original_file_path,\n                key_path=\"models.config\",\n            )\n\n        if self.namespace is not None:\n            self.package_name = self.namespace\n\n        # If the user has provided a description for this generic test, use it\n        # Then delete the \"description\" argument to:\n        # 1. Avoid passing it into the test macro\n        # 2. Avoid passing it into the test name synthesis\n        # Otherwise, use an empty string\n        self.description: str = \"\"\n\n        if \"description\" in self.args:\n            self.description = self.args[\"description\"]\n            del self.args[\"description\"]\n\n        # If the user has provided a custom name for this generic test, use it\n        # Then delete the \"name\" argument to avoid passing it into the test macro\n        # Otherwise, use an auto-generated name synthesized from test inputs\n        self.compiled_name: str = \"\"\n        self.fqn_name: str = \"\"\n\n        if \"name\" in self.args:\n            # Assign the user-defined name here, which will be checked for uniqueness later\n            # we will raise an error if two tests have same name for same model + column combo\n            self.compiled_name = self.args[\"name\"]\n            self.fqn_name = self.args[\"name\"]\n            del self.args[\"name\"]\n        else:\n            short_name, full_name = self.get_synthetic_test_names()\n            self.compiled_name = short_name\n            self.fqn_name = full_name\n            # use hashed name as alias if full name is too long\n            if short_name != full_name and \"alias\" not in self.config:\n                self.config[\"alias\"] = short_name\n\n    def _process_legacy_args(self):\n        config = {}\n        if \"config\" in self.args and not isinstance(self.args[\"config\"], dict):\n            raise TestConfigNotDictError(self.args[\"config\"])\n        for key in self.CONFIG_ARGS:\n            value = self.args.pop(key, None)\n            if value and \"config\" in self.args and key in self.args[\"config\"]:\n                raise SameKeyNestedError()\n            if not value and \"config\" in self.args:\n                value = self.args[\"config\"].pop(key, None)\n            config[key] = value\n\n        return self._render_values(config)\n\n    def _render_values(self, config: Dict[str, Any]) -> Dict[str, Any]:\n        rendered_config = {}\n        for key, value in config.items():\n            if isinstance(value, str):\n                try:\n                    value = get_rendered(value, self.render_ctx, native=True)\n                except UndefinedMacroError as e:\n                    raise CustomMacroPopulatingConfigValueError(\n                        target_name=self.target.name,\n                        column_name=self.column_name,\n                        name=self.name,\n                        key=key,\n                        err_msg=e.msg,\n                    )\n            if value is not None:\n                rendered_config[key] = value\n        return rendered_config\n\n    def _bad_type(self) -> TypeError:\n        return TypeError('invalid target type \"{}\"'.format(type(self.target)))\n\n    @staticmethod\n    def extract_test_args(\n        data_test, file_path, resource_name=None, column_name=None, package_name=None\n    ) -> Tuple[str, Dict[str, Any]]:\n        if not isinstance(data_test, dict):\n            raise TestTypeError(data_test)\n\n        # If the test is a dictionary with top-level keys, the test name is \"test_name\"\n        # and the rest are arguments\n        # {'name': 'my_favorite_test', 'test_name': 'unique', 'config': {'where': '1=1'}}\n        if \"test_name\" in data_test.keys():\n            test_name = data_test.pop(\"test_name\")\n            test_args = data_test\n        # If the test is a nested dictionary with one top-level key, the test name\n        # is the dict name, and nested keys are arguments\n        # {'unique': {'name': 'my_favorite_test', 'config': {'where': '1=1'}}}\n        else:\n            data_test = list(data_test.items())\n            if len(data_test) != 1:\n                raise TestDefinitionDictLengthError(data_test)\n            test_name, test_args = data_test[0]\n\n        if not isinstance(test_args, dict):\n            raise TestArgsNotDictError(test_args)\n        if not isinstance(test_name, str):\n            raise TestNameNotStringError(test_name)\n        test_args = deepcopy(test_args)\n        if column_name is not None:\n            test_args[\"column_name\"] = column_name\n\n        # Extract kwargs when they are nested under new 'arguments' property separately from 'config' if require_generic_test_arguments_property is enabled\n        if get_flags().require_generic_test_arguments_property:\n            arguments = test_args.pop(\"arguments\", {})\n            if not arguments and any(\n                k not in (\"config\", \"column_name\", \"description\", \"name\") for k in test_args.keys()\n            ):\n                resource = (\n                    f\"'{resource_name}' in package '{package_name}'\"\n                    if package_name\n                    else f\"'{resource_name}'\"\n                )\n                deprecations.warn(\n                    \"missing-arguments-property-in-generic-test-deprecation\",\n                    test_name=f\"`{test_name}` defined on {resource} ({file_path})\",\n                )\n            if isinstance(arguments, dict):\n                test_args = {**test_args, **arguments}\n        elif \"arguments\" in test_args:\n            deprecations.warn(\n                \"arguments-property-in-generic-test-deprecation\",\n                test_name=f\"`{test_name}` ({test_args['arguments']})\",\n            )\n\n        return test_name, test_args\n\n    def tags(self) -> List[str]:\n        tags = self.config.get(\"tags\", [])\n        if isinstance(tags, str):\n            tags = [tags]\n        if not isinstance(tags, list):\n            raise TagsNotListOfStringsError(tags)\n        for tag in tags:\n            if not isinstance(tag, str):\n                raise TagNotStringError(tag)\n        return tags[:]\n\n    def macro_name(self) -> str:\n        macro_name = \"test_{}\".format(self.name)\n        if self.namespace is not None:\n            macro_name = \"{}.{}\".format(self.namespace, macro_name)\n        return macro_name\n\n    def get_synthetic_test_names(self) -> Tuple[str, str]:\n        # Returns two names: shorter (for the compiled file), full (for the unique_id + FQN)\n        target_name = self.target.name\n        if isinstance(self.target, UnparsedModelUpdate):\n            name = self.name\n            if self.version:\n                target_name = f\"{self.target.name}_v{self.version}\"\n        elif isinstance(self.target, UnparsedNodeUpdate):\n            name = self.name\n        elif isinstance(self.target, UnpatchedSourceDefinition):\n            name = \"source_\" + self.name\n        else:\n            raise self._bad_type()\n        if self.namespace is not None:\n            name = \"{}_{}\".format(self.namespace, name)\n        return synthesize_generic_test_names(name, target_name, self.args)\n\n    def construct_config(self) -> str:\n        configs = \",\".join(\n            [\n                f\"{key}=\"\n                + (\n                    ('\"' + value.replace('\"', '\\\\\"') + '\"')\n                    if isinstance(value, str)\n                    else str(value)\n                )\n                for key, value in self.config.items()\n            ]\n        )\n        if configs:\n            return f\"{{{{ config({configs}) }}}}\"\n        else:\n            return \"\"\n\n    # this is the 'raw_code' that's used in 'render_update' and execution\n    # of the test macro\n    def build_raw_code(self) -> str:\n        return (\"{{{{ {macro}(**{kwargs_name}) }}}}{config}\").format(\n            macro=self.macro_name(),\n            config=self.construct_config(),\n            kwargs_name=GENERIC_TEST_KWARGS_NAME,\n        )\n\n    def build_model_str(self):\n        targ = self.target\n        if isinstance(self.target, UnparsedModelUpdate):\n            if self.version:\n                target_str = f\"ref('{targ.name}', version='{self.version}')\"\n            else:\n                target_str = f\"ref('{targ.name}')\"\n        elif isinstance(self.target, UnparsedNodeUpdate):\n            target_str = f\"ref('{targ.name}')\"\n        elif isinstance(self.target, UnpatchedSourceDefinition):\n            target_str = f\"source('{targ.source.name}', '{targ.table.name}')\"\n        return f\"{{{{ get_where_subquery({target_str}) }}}}\"\n"
  },
  {
    "path": "core/dbt/parser/hooks.py",
    "content": "from dataclasses import dataclass\nfrom typing import Iterable, Iterator, List, Tuple, Union\n\nfrom dbt.context.context_config import ContextConfig\nfrom dbt.contracts.files import FilePath\nfrom dbt.contracts.graph.nodes import HookNode\nfrom dbt.node_types import NodeType, RunHookType\nfrom dbt.parser.base import SimpleParser\nfrom dbt.parser.search import FileBlock\nfrom dbt.utils import get_pseudo_hook_path\nfrom dbt_common.exceptions import DbtInternalError\n\n\n@dataclass\nclass HookBlock(FileBlock):\n    project: str\n    value: str\n    index: int\n    hook_type: RunHookType\n\n    @property\n    def contents(self):\n        return self.value\n\n    @property\n    def name(self):\n        return \"{}-{!s}-{!s}\".format(self.project, self.hook_type, self.index)\n\n\nclass HookSearcher(Iterable[HookBlock]):\n    def __init__(self, project, source_file, hook_type) -> None:\n        self.project = project\n        self.source_file = source_file\n        self.hook_type = hook_type\n\n    def _hook_list(self, hooks: Union[str, List[str], Tuple[str, ...]]) -> List[str]:\n        if isinstance(hooks, tuple):\n            hooks = list(hooks)\n        elif not isinstance(hooks, list):\n            hooks = [hooks]\n        return hooks\n\n    def get_hook_defs(self) -> List[str]:\n        if self.hook_type == RunHookType.Start:\n            hooks = self.project.on_run_start\n        elif self.hook_type == RunHookType.End:\n            hooks = self.project.on_run_end\n        else:\n            raise DbtInternalError(\n                'hook_type must be one of \"{}\" or \"{}\" (got {})'.format(\n                    RunHookType.Start, RunHookType.End, self.hook_type\n                )\n            )\n        return self._hook_list(hooks)\n\n    def __iter__(self) -> Iterator[HookBlock]:\n        hooks = self.get_hook_defs()\n        for index, hook in enumerate(hooks):\n            yield HookBlock(\n                file=self.source_file,\n                project=self.project.project_name,\n                value=hook,\n                index=index,\n                hook_type=self.hook_type,\n            )\n\n\nclass HookParser(SimpleParser[HookBlock, HookNode]):\n\n    # Hooks are only in the dbt_project.yml file for the project\n    def get_path(self) -> FilePath:\n        # There ought to be an existing file object for this, but\n        # until that is implemented use a dummy modification time\n        path = FilePath(\n            project_root=self.project.project_root,\n            searched_path=\".\",\n            relative_path=\"dbt_project.yml\",\n            modification_time=0.0,\n        )\n        return path\n\n    def parse_from_dict(self, dct, validate=True) -> HookNode:\n        if validate:\n            HookNode.validate(dct)\n        return HookNode.from_dict(dct)\n\n    @classmethod\n    def get_compiled_path(cls, block: HookBlock):\n        return get_pseudo_hook_path(block.name)\n\n    def _create_parsetime_node(\n        self,\n        block: HookBlock,\n        path: str,\n        config: ContextConfig,\n        fqn: List[str],\n        name=None,\n        **kwargs,\n    ) -> HookNode:\n\n        return super()._create_parsetime_node(\n            block=block,\n            path=path,\n            config=config,\n            fqn=fqn,\n            index=block.index,\n            name=name,\n            tags=[str(block.hook_type)],\n        )\n\n    @property\n    def resource_type(self) -> NodeType:\n        return NodeType.Operation\n\n    def parse_file(self, block: FileBlock) -> None:\n        for hook_type in RunHookType:\n            for hook in HookSearcher(self.project, block.file, hook_type):\n                self.parse_node(hook)\n"
  },
  {
    "path": "core/dbt/parser/macros.py",
    "content": "from typing import Iterable, List\n\nimport jinja2\n\nfrom dbt.artifacts.resources import MacroArgument\nfrom dbt.clients.jinja import get_supported_languages\nfrom dbt.contracts.files import FilePath, SourceFile\nfrom dbt.contracts.graph.nodes import Macro\nfrom dbt.contracts.graph.unparsed import UnparsedMacro\nfrom dbt.exceptions import ParsingError\nfrom dbt.flags import get_flags\nfrom dbt.node_types import NodeType\nfrom dbt.parser.base import BaseParser\nfrom dbt.parser.search import FileBlock, filesystem_search\nfrom dbt_common.clients import jinja\nfrom dbt_common.clients._jinja_blocks import ExtractWarning\nfrom dbt_common.utils import MACRO_PREFIX\n\n\nclass MacroParser(BaseParser[Macro]):\n    # This is only used when creating a MacroManifest separate\n    # from the normal parsing flow.\n    def get_paths(self) -> List[FilePath]:\n        return filesystem_search(\n            project=self.project, relative_dirs=self.project.macro_paths, extension=\".sql\"\n        )\n\n    @property\n    def resource_type(self) -> NodeType:\n        return NodeType.Macro\n\n    @classmethod\n    def get_compiled_path(cls, block: FileBlock):\n        return block.path.relative_path\n\n    def parse_macro(self, block: jinja.BlockTag, base_node: UnparsedMacro, name: str) -> Macro:\n        unique_id = self.generate_unique_id(name)\n        macro_sql = block.full_block or \"\"\n\n        return Macro(\n            path=base_node.path,\n            macro_sql=macro_sql,\n            original_file_path=base_node.original_file_path,\n            package_name=base_node.package_name,\n            resource_type=base_node.resource_type,\n            name=name,\n            unique_id=unique_id,\n        )\n\n    def parse_unparsed_macros(self, base_node: UnparsedMacro) -> Iterable[Macro]:\n        # This is a bit of a hack to get the file path to the deprecation\n        def wrap_handle_extract_warning(warning: ExtractWarning) -> None:\n            self._handle_extract_warning(warning=warning, file=base_node.original_file_path)\n\n        try:\n            blocks: List[jinja.BlockTag] = [\n                t\n                for t in jinja.extract_toplevel_blocks(\n                    base_node.raw_code,\n                    allowed_blocks={\"macro\", \"materialization\", \"test\", \"data_test\"},\n                    collect_raw_data=False,\n                    warning_callback=wrap_handle_extract_warning,\n                )\n                if isinstance(t, jinja.BlockTag)\n            ]\n        except ParsingError as exc:\n            exc.add_node(base_node)\n            raise\n\n        for block in blocks:\n            try:\n                ast = jinja.parse(block.full_block)\n            except ParsingError as e:\n                e.add_node(base_node)\n                raise\n\n            if (\n                isinstance(ast, jinja2.nodes.Template)\n                and hasattr(ast, \"body\")\n                and len(ast.body) == 1\n                and isinstance(ast.body[0], jinja2.nodes.Macro)\n            ):\n                # If the top level node in the Template is a Macro, things look\n                # good and this is much faster than traversing the full ast, as\n                # in the following else clause. It's not clear if that traversal\n                # is ever really needed.\n                macro = ast.body[0]\n            else:\n                macro_nodes = list(ast.find_all(jinja2.nodes.Macro))\n\n                if len(macro_nodes) != 1:\n                    # things have gone disastrously wrong, we thought we only\n                    # parsed one block!\n                    raise ParsingError(\n                        f\"Found multiple macros in {block.full_block}, expected 1\", node=base_node\n                    )\n\n                macro = macro_nodes[0]\n\n            if not macro.name.startswith(MACRO_PREFIX):\n                continue\n\n            name: str = macro.name.replace(MACRO_PREFIX, \"\")\n            node = self.parse_macro(block, base_node, name)\n\n            if getattr(get_flags(), \"validate_macro_args\", False):\n                node.arguments = self._extract_args(macro)\n\n            # get supported_languages for materialization macro\n            if block.block_type_name == \"materialization\":\n                node.supported_languages = get_supported_languages(macro)\n            yield node\n\n    def _extract_args(self, macro) -> List[MacroArgument]:\n        try:\n            return list([MacroArgument(name=arg.name) for arg in macro.args])\n        except Exception:\n            return []\n\n    def parse_file(self, block: FileBlock):\n        assert isinstance(block.file, SourceFile)\n        source_file = block.file\n        assert isinstance(source_file.contents, str)\n        original_file_path = source_file.path.original_file_path\n\n        # this is really only used for error messages\n        base_node = UnparsedMacro(\n            path=original_file_path,\n            original_file_path=original_file_path,\n            package_name=self.project.project_name,\n            raw_code=source_file.contents,\n            resource_type=NodeType.Macro,\n            language=\"sql\",\n        )\n\n        for node in self.parse_unparsed_macros(base_node):\n            self.manifest.add_macro(block.file, node)\n"
  },
  {
    "path": "core/dbt/parser/manifest.py",
    "content": "import json\nimport os\nimport pprint\nimport time\nimport traceback\nfrom copy import deepcopy\nfrom dataclasses import dataclass, field\nfrom datetime import date, datetime, timezone\nfrom itertools import chain\nfrom typing import Any, Callable, Dict, List, Mapping, Optional, Set, Tuple, Type, Union\n\nimport jinja2\nimport msgpack\nfrom jinja2.nodes import Call, Const\n\nimport dbt.deprecations\nimport dbt.exceptions\nimport dbt.tracking\nimport dbt.utils\nimport dbt_common.utils\nfrom dbt import plugins\nfrom dbt.adapters.capability import Capability\nfrom dbt.adapters.factory import (\n    get_adapter,\n    get_adapter_package_names,\n    get_relation_class_by_name,\n    register_adapter,\n)\nfrom dbt.artifacts.resources import (\n    CatalogWriteIntegrationConfig,\n    FileHash,\n    MetricInput,\n    NodeRelation,\n    NodeVersion,\n)\nfrom dbt.artifacts.resources.types import BatchSize\nfrom dbt.artifacts.schemas.base import Writable\nfrom dbt.clients.jinja import MacroStack, get_rendered\nfrom dbt.clients.jinja_static import statically_extract_macro_calls\nfrom dbt.config import Project, RuntimeConfig\nfrom dbt.constants import (\n    MANIFEST_FILE_NAME,\n    PARTIAL_PARSE_FILE_NAME,\n    SEMANTIC_MANIFEST_FILE_NAME,\n)\nfrom dbt.context.configured import generate_macro_context\nfrom dbt.context.docs import generate_runtime_docs_context\nfrom dbt.context.macro_resolver import MacroResolver, TestMacroNamespace\nfrom dbt.context.providers import ParseProvider, generate_runtime_macro_context\nfrom dbt.context.query_header import generate_query_header_context\nfrom dbt.contracts.files import ParseFileType, SchemaSourceFile\nfrom dbt.contracts.graph.manifest import (\n    Disabled,\n    MacroManifest,\n    Manifest,\n    ManifestStateCheck,\n    ParsingInfo,\n)\nfrom dbt.contracts.graph.nodes import (\n    Exposure,\n    GenericTestNode,\n    Macro,\n    ManifestNode,\n    Metric,\n    ModelNode,\n    ResultNode,\n    SavedQuery,\n    SeedNode,\n    SemanticManifestNode,\n    SemanticModel,\n    SourceDefinition,\n)\nfrom dbt.contracts.graph.semantic_manifest import SemanticManifest\nfrom dbt.events.types import (\n    ArtifactWritten,\n    DeprecatedModel,\n    DeprecatedReference,\n    InvalidConcurrentBatchesConfig,\n    InvalidDisabledTargetInTestNode,\n    MicrobatchModelNoEventTimeInputs,\n    NodeNotFoundOrDisabled,\n    PackageNodeDependsOnRootProjectNode,\n    ParsedFileLoadFailed,\n    ParsePerfInfoPath,\n    PartialParsingError,\n    PartialParsingErrorProcessingFile,\n    PartialParsingNotEnabled,\n    PartialParsingSkipParsing,\n    SpacesInResourceNameDeprecation,\n    StateCheckVarsHash,\n    UnableToPartialParse,\n    UpcomingReferenceDeprecation,\n)\nfrom dbt.exceptions import (\n    AmbiguousAliasError,\n    DuplicateResourceNameError,\n    InvalidAccessTypeError,\n    TargetNotFoundError,\n    scrub_secrets,\n)\nfrom dbt.flags import get_flags\nfrom dbt.mp_context import get_mp_context\nfrom dbt.node_types import AccessType, NodeType\nfrom dbt.parser.analysis import AnalysisParser\nfrom dbt.parser.base import Parser\nfrom dbt.parser.docs import DocumentationParser\nfrom dbt.parser.fixtures import FixtureParser\nfrom dbt.parser.functions import FunctionParser\nfrom dbt.parser.generic_test import GenericTestParser\nfrom dbt.parser.hooks import HookParser\nfrom dbt.parser.macros import MacroParser\nfrom dbt.parser.models import ModelParser\nfrom dbt.parser.partial import PartialParsing, special_override_macros\nfrom dbt.parser.read_files import (\n    FileDiff,\n    ReadFiles,\n    ReadFilesFromDiff,\n    ReadFilesFromFileSystem,\n    load_source_file,\n)\nfrom dbt.parser.schemas import SchemaParser\nfrom dbt.parser.search import FileBlock\nfrom dbt.parser.seeds import SeedParser\nfrom dbt.parser.singular_test import SingularTestParser\nfrom dbt.parser.snapshots import SnapshotParser\nfrom dbt.parser.sources import SourcePatcher\nfrom dbt.parser.unit_tests import process_models_for_unit_test\nfrom dbt.utils.artifact_upload import add_artifact_produced\nfrom dbt.version import __version__\nfrom dbt_common.clients.jinja import parse\nfrom dbt_common.clients.system import make_directory, path_exists, read_json, write_file\nfrom dbt_common.constants import SECRET_ENV_PREFIX\nfrom dbt_common.dataclass_schema import StrEnum, dbtClassMixin\nfrom dbt_common.events.base_types import EventLevel\nfrom dbt_common.events.functions import fire_event, get_invocation_id, warn_or_error\nfrom dbt_common.events.types import Note\nfrom dbt_common.exceptions.base import DbtValidationError\nfrom dbt_common.helper_types import PathSet\nfrom dbt_semantic_interfaces.enum_extension import assert_values_exhausted\nfrom dbt_semantic_interfaces.type_enums import MetricType\n\nPERF_INFO_FILE_NAME = \"perf_info.json\"\n\n\ndef extended_mashumaro_encoder(data):\n    return msgpack.packb(data, default=extended_msgpack_encoder, use_bin_type=True)\n\n\ndef extended_msgpack_encoder(obj):\n    if type(obj) is date:\n        date_bytes = msgpack.ExtType(1, obj.isoformat().encode())\n        return date_bytes\n    elif type(obj) is datetime:\n        datetime_bytes = msgpack.ExtType(2, obj.isoformat().encode())\n        return datetime_bytes\n    elif isinstance(obj, jinja2.Undefined):\n        return None\n\n    return obj\n\n\ndef extended_mashumuro_decoder(data):\n    return msgpack.unpackb(data, ext_hook=extended_msgpack_decoder, raw=False)\n\n\ndef extended_msgpack_decoder(code, data):\n    if code == 1:\n        d = date.fromisoformat(data.decode())\n        return d\n    elif code == 2:\n        dt = datetime.fromisoformat(data.decode())\n        return dt\n    else:\n        return msgpack.ExtType(code, data)\n\n\ndef version_to_str(version: Optional[Union[str, int]]) -> str:\n    if isinstance(version, int):\n        return str(version)\n    elif isinstance(version, str):\n        return version\n\n    return \"\"\n\n\nclass ReparseReason(StrEnum):\n    version_mismatch = \"01_version_mismatch\"\n    file_not_found = \"02_file_not_found\"\n    vars_changed = \"03_vars_changed\"\n    profile_changed = \"04_profile_changed\"\n    deps_changed = \"05_deps_changed\"\n    project_config_changed = \"06_project_config_changed\"\n    load_file_failure = \"07_load_file_failure\"\n    exception = \"08_exception\"\n    proj_env_vars_changed = \"09_project_env_vars_changed\"\n    prof_env_vars_changed = \"10_profile_env_vars_changed\"\n\n\n# Part of saved performance info\n@dataclass\nclass ParserInfo(dbtClassMixin):\n    parser: str\n    elapsed: float\n    parsed_path_count: int = 0\n\n\n# Part of saved performance info\n@dataclass\nclass ProjectLoaderInfo(dbtClassMixin):\n    project_name: str\n    elapsed: float\n    parsers: List[ParserInfo] = field(default_factory=list)\n    parsed_path_count: int = 0\n\n\n# Part of saved performance info\n@dataclass\nclass ManifestLoaderInfo(dbtClassMixin, Writable):\n    path_count: int = 0\n    parsed_path_count: int = 0\n    static_analysis_path_count: int = 0\n    static_analysis_parsed_path_count: int = 0\n    is_partial_parse_enabled: Optional[bool] = None\n    is_static_analysis_enabled: Optional[bool] = None\n    read_files_elapsed: Optional[float] = None\n    load_macros_elapsed: Optional[float] = None\n    parse_project_elapsed: Optional[float] = None\n    patch_sources_elapsed: Optional[float] = None\n    process_manifest_elapsed: Optional[float] = None\n    load_all_elapsed: Optional[float] = None\n    projects: List[ProjectLoaderInfo] = field(default_factory=list)\n    _project_index: Dict[str, ProjectLoaderInfo] = field(default_factory=dict)\n\n    def __post_serialize__(self, dct: Dict, context: Optional[Dict] = None):\n        del dct[\"_project_index\"]\n        return dct\n\n\n# The ManifestLoader loads the manifest. The standard way to use the\n# ManifestLoader is using the 'get_full_manifest' class method, but\n# many tests use abbreviated processes.\nclass ManifestLoader:\n    def __init__(\n        self,\n        root_project: RuntimeConfig,\n        all_projects: Mapping[str, RuntimeConfig],\n        macro_hook: Optional[Callable[[Manifest], Any]] = None,\n        file_diff: Optional[FileDiff] = None,\n    ) -> None:\n        self.root_project: RuntimeConfig = root_project\n        self.all_projects: Mapping[str, RuntimeConfig] = all_projects\n        self.file_diff = file_diff\n        self.manifest: Manifest = Manifest()\n        self.new_manifest = self.manifest\n        self.manifest.metadata = root_project.get_metadata()\n        self.macro_resolver = None  # built after macros are loaded\n        self.started_at = time.time()\n        # This is a MacroQueryStringSetter callable, which is called\n        # later after we set the MacroManifest in the adapter. It sets\n        # up the query headers.\n        self.macro_hook: Callable[[Manifest], Any]\n        if macro_hook is None:\n            self.macro_hook = lambda m: None\n        else:\n            self.macro_hook = macro_hook\n\n        self._perf_info = self.build_perf_info()\n\n        # State check determines whether the saved_manifest and the current\n        # manifest match well enough to do partial parsing\n        self.manifest.state_check = self.build_manifest_state_check()\n        # We need to know if we're actually partially parsing. It could\n        # have been enabled, but not happening because of some issue.\n        self.partially_parsing = False\n        self.partial_parser: Optional[PartialParsing] = None\n        self.skip_parsing = False\n\n        # This is a saved manifest from a previous run that's used for partial parsing\n        self.saved_manifest: Optional[Manifest] = self.read_manifest_for_partial_parse()\n\n    # This is the method that builds a complete manifest. We sometimes\n    # use an abbreviated process in tests.\n    @classmethod\n    def get_full_manifest(\n        cls,\n        config: RuntimeConfig,\n        *,\n        file_diff: Optional[FileDiff] = None,\n        reset: bool = False,\n        write_perf_info=False,\n    ) -> Manifest:\n        adapter = get_adapter(config)  # type: ignore\n        # reset is set in a TaskManager load_manifest call, since\n        # the config and adapter may be persistent.\n        if reset:\n            config.clear_dependencies()\n            adapter.clear_macro_resolver()\n        macro_hook = adapter.connections.set_query_header\n\n        flags = get_flags()\n        if not flags.PARTIAL_PARSE_FILE_DIFF:\n            file_diff = FileDiff.from_dict(\n                {\n                    \"deleted\": [],\n                    \"changed\": [],\n                    \"added\": [],\n                }\n            )\n        # Hack to test file_diffs\n        elif os.environ.get(\"DBT_PP_FILE_DIFF_TEST\"):\n            file_diff_path = \"file_diff.json\"\n            if path_exists(file_diff_path):\n                file_diff_dct = read_json(file_diff_path)\n                file_diff = FileDiff.from_dict(file_diff_dct)\n\n        # Start performance counting\n        start_load_all = time.perf_counter()\n\n        projects = config.load_dependencies()\n        loader = cls(\n            config,\n            projects,\n            macro_hook=macro_hook,\n            file_diff=file_diff,\n        )\n\n        manifest = loader.load()\n\n        _check_manifest(manifest, config)\n        manifest.build_flat_graph()\n\n        # This needs to happen after loading from a partial parse,\n        # so that the adapter has the query headers from the macro_hook.\n        loader.save_macros_to_adapter(adapter)\n\n        # Save performance info\n        loader._perf_info.load_all_elapsed = time.perf_counter() - start_load_all\n        loader.track_project_load()\n\n        if write_perf_info:\n            loader.write_perf_info(config.project_target_path)\n\n        return manifest\n\n    # This is where the main action happens\n    def load(self) -> Manifest:\n        start_read_files = time.perf_counter()\n\n        # This updates the \"files\" dictionary in self.manifest, and creates\n        # the partial_parser_files dictionary (see read_files.py),\n        # which is a dictionary of projects to a dictionary\n        # of parsers to lists of file strings. The file strings are\n        # used to get the SourceFiles from the manifest files.\n        saved_files = self.saved_manifest.files if self.saved_manifest else {}\n        file_reader: Optional[ReadFiles] = None\n        if self.file_diff:\n            # We're getting files from a file diff\n            file_reader = ReadFilesFromDiff(\n                all_projects=self.all_projects,\n                files=self.manifest.files,\n                saved_files=saved_files,\n                root_project_name=self.root_project.project_name,\n                file_diff=self.file_diff,\n            )\n        else:\n            # We're getting files from the file system\n            file_reader = ReadFilesFromFileSystem(\n                all_projects=self.all_projects,\n                files=self.manifest.files,\n                saved_files=saved_files,\n            )\n\n        # Set the files in the manifest and save the project_parser_files\n        file_reader.read_files()\n        self.manifest.files = file_reader.files\n        project_parser_files = orig_project_parser_files = file_reader.project_parser_files\n        self._perf_info.path_count = len(self.manifest.files)\n        self._perf_info.read_files_elapsed = time.perf_counter() - start_read_files\n\n        self.skip_parsing = False\n        project_parser_files = self.safe_update_project_parser_files_partially(\n            project_parser_files\n        )\n\n        if self.manifest._parsing_info is None:\n            self.manifest._parsing_info = ParsingInfo()\n\n        if self.skip_parsing:\n            fire_event(PartialParsingSkipParsing())\n        else:\n            # Load Macros and tests\n            # We need to parse the macros first, so they're resolvable when\n            # the other files are loaded.  Also need to parse tests, specifically\n            # generic tests\n            start_load_macros = time.perf_counter()\n            self.load_and_parse_macros(project_parser_files)\n\n            # If we're partially parsing check that certain macros have not been changed\n            if self.partially_parsing and self.skip_partial_parsing_because_of_macros():\n                fire_event(\n                    UnableToPartialParse(\n                        reason=\"change detected to override macro. Starting full parse.\"\n                    )\n                )\n\n                # Get new Manifest with original file records and move over the macros\n                self.manifest = self.new_manifest  # contains newly read files\n                project_parser_files = orig_project_parser_files\n                self.partially_parsing = False\n                self.load_and_parse_macros(project_parser_files)\n\n            self._perf_info.load_macros_elapsed = time.perf_counter() - start_load_macros\n\n            # Now that the macros are parsed, parse the rest of the files.\n            # This is currently done on a per project basis.\n            start_parse_projects = time.perf_counter()\n\n            # Load the rest of the files except for schema yaml files\n            parser_types: List[Type[Parser]] = [\n                ModelParser,\n                SnapshotParser,\n                AnalysisParser,\n                SingularTestParser,\n                SeedParser,\n                DocumentationParser,\n                HookParser,\n                FixtureParser,\n                FunctionParser,\n            ]\n            for project in self.all_projects.values():\n                if project.project_name not in project_parser_files:\n                    continue\n                self.parse_project(\n                    project, project_parser_files[project.project_name], parser_types\n                )\n\n            # Now that we've loaded most of the nodes (except for schema tests, sources, metrics)\n            # load up the Lookup objects to resolve them by name, so the SourceFiles store\n            # the unique_id instead of the name. Sources are loaded from yaml files, so\n            # aren't in place yet\n            self.manifest.rebuild_ref_lookup()\n            self.manifest.rebuild_doc_lookup()\n            self.manifest.rebuild_disabled_lookup()\n\n            # Load yaml files\n            parser_types = [SchemaParser]  # type: ignore\n            for project in self.all_projects.values():\n                if project.project_name not in project_parser_files:\n                    continue\n                self.parse_project(\n                    project, project_parser_files[project.project_name], parser_types\n                )\n\n            self.cleanup_disabled()\n\n            self._perf_info.parse_project_elapsed = time.perf_counter() - start_parse_projects\n\n            # patch_sources converts the UnparsedSourceDefinitions in the\n            # Manifest.sources to SourceDefinition via 'patch_source'\n            # in SourcePatcher\n            start_patch = time.perf_counter()\n            patcher = SourcePatcher(self.root_project, self.manifest)\n            patcher.construct_sources()\n            self.manifest.sources = patcher.sources\n            self._perf_info.patch_sources_elapsed = time.perf_counter() - start_patch\n\n            # We need to rebuild disabled in order to include disabled sources\n            self.manifest.rebuild_disabled_lookup()\n\n            # copy the selectors from the root_project to the manifest\n            self.manifest.selectors = self.root_project.manifest_selectors\n\n            # inject any available external nodes\n            self.manifest.build_parent_and_child_maps()\n            external_nodes_modified = self.inject_external_nodes()\n            if external_nodes_modified:\n                self.manifest.rebuild_ref_lookup()\n\n            # update the refs, sources, docs and metrics depends_on.nodes\n            # These check the created_at time on the nodes to\n            # determine whether they need processing.\n            start_process = time.perf_counter()\n            self.process_sources(self.root_project.project_name)\n            self.process_refs(self.root_project.project_name, self.root_project.dependencies)\n            self.process_unit_tests(self.root_project.project_name)\n            self.process_docs(self.root_project)\n            self.process_metrics(self.root_project)\n            self.process_saved_queries(self.root_project)\n            self.process_model_inferred_primary_keys()\n            self.process_functions(self.root_project.project_name)\n            self.check_valid_group_config()\n            self.check_valid_access_property()\n            self.check_valid_snapshot_config()\n            self.check_valid_microbatch_config()\n\n            semantic_manifest = SemanticManifest(self.manifest)\n            if not semantic_manifest.validate():\n                raise dbt.exceptions.ParsingError(\"Semantic Manifest validation failed.\")\n\n            # update tracking data\n            self._perf_info.process_manifest_elapsed = time.perf_counter() - start_process\n            self._perf_info.static_analysis_parsed_path_count = (\n                self.manifest._parsing_info.static_analysis_parsed_path_count\n            )\n            self._perf_info.static_analysis_path_count = (\n                self.manifest._parsing_info.static_analysis_path_count\n            )\n\n        # Inject any available external nodes, reprocess refs if changes to the manifest were made.\n        external_nodes_modified = False\n        if self.skip_parsing:\n            # If we didn't skip parsing, this will have already run because it must run\n            # before process_refs. If we did skip parsing, then it's possible that only\n            # external nodes have changed and we need to run this to capture that.\n            self.manifest.build_parent_and_child_maps()\n            external_nodes_modified = self.inject_external_nodes()\n            if external_nodes_modified:\n                self.manifest.rebuild_ref_lookup()\n                self.process_refs(\n                    self.root_project.project_name,\n                    self.root_project.dependencies,\n                )\n                # parent and child maps will be rebuilt by write_manifest\n\n        if not self.skip_parsing or external_nodes_modified:\n            # write out the fully parsed manifest\n            self.write_manifest_for_partial_parse()\n\n        self.check_for_model_deprecations()\n        self.check_for_spaces_in_resource_names()\n        self.check_for_microbatch_deprecations()\n        self.check_forcing_batch_concurrency()\n        self.check_microbatch_model_has_a_filtered_input()\n        self.check_function_default_arguments_ordering()\n\n        return self.manifest\n\n    def safe_update_project_parser_files_partially(self, project_parser_files: Dict) -> Dict:\n        if self.saved_manifest is None:\n            return project_parser_files\n\n        self.partial_parser = PartialParsing(self.saved_manifest, self.manifest.files)  # type: ignore[arg-type]\n        self.skip_parsing = self.partial_parser.skip_parsing()\n        if self.skip_parsing:\n            # nothing changed, so we don't need to generate project_parser_files\n            fire_event(\n                Note(msg=\"Nothing changed, skipping partial parsing.\"), level=EventLevel.DEBUG\n            )\n            self.manifest = self.saved_manifest  # type: ignore[assignment]\n        else:\n            # create child_map and parent_map\n            self.saved_manifest.build_parent_and_child_maps()  # type: ignore[union-attr]\n            # create group_map\n            self.saved_manifest.build_group_map()  # type: ignore[union-attr]\n            # files are different, we need to create a new set of\n            # project_parser_files.\n            try:\n                project_parser_files = self.partial_parser.get_parsing_files()\n                self.partially_parsing = True\n                self.manifest = self.saved_manifest  # type: ignore[assignment]\n            except Exception as exc:\n                # pp_files should still be the full set and manifest is new manifest,\n                # since get_parsing_files failed\n                fire_event(\n                    UnableToPartialParse(reason=\"an error occurred. Switching to full reparse.\")\n                )\n\n                # Get traceback info\n                tb_info = traceback.format_exc()\n                # index last stack frame in traceback (i.e. lastest exception and its context)\n                tb_last_frame = traceback.extract_tb(exc.__traceback__)[-1]\n                exc_info = {\n                    \"traceback\": tb_info,\n                    \"exception\": tb_info.splitlines()[-1],\n                    \"code\": tb_last_frame.line,  # if the source is not available, it is None\n                    \"location\": f\"line {tb_last_frame.lineno} in {tb_last_frame.name}\",\n                }\n\n                # get file info for local logs\n                parse_file_type: str = \"\"\n                file_id = self.partial_parser.processing_file\n                if file_id:\n                    source_file = None\n                    if file_id in self.saved_manifest.files:\n                        source_file = self.saved_manifest.files[file_id]\n                    elif file_id in self.manifest.files:\n                        source_file = self.manifest.files[file_id]\n                    if source_file:\n                        parse_file_type = source_file.parse_file_type\n                        fire_event(PartialParsingErrorProcessingFile(file=file_id))\n                exc_info[\"parse_file_type\"] = parse_file_type\n                fire_event(PartialParsingError(exc_info=exc_info))\n                # Send event\n                if dbt.tracking.active_user is not None:\n                    exc_info[\"full_reparse_reason\"] = ReparseReason.exception\n                    dbt.tracking.track_partial_parser(exc_info)\n\n                if os.environ.get(\"DBT_PP_TEST\"):\n                    raise exc\n\n        return project_parser_files\n\n    def check_for_model_deprecations(self):\n        # build parent and child_maps\n        self.manifest.build_parent_and_child_maps()\n        for node in self.manifest.nodes.values():\n            if isinstance(node, ModelNode) and node.deprecation_date:\n                if node.is_past_deprecation_date:\n                    warn_or_error(\n                        DeprecatedModel(\n                            model_name=node.name,\n                            model_version=version_to_str(node.version),\n                            deprecation_date=node.deprecation_date.isoformat(),\n                        )\n                    )\n                # At this point _process_refs should already have been called, and\n                # we just rebuilt the parent and child maps.\n                # Get the child_nodes and check for deprecations.\n                child_nodes = self.manifest.child_map[node.unique_id]\n                for child_unique_id in child_nodes:\n                    child_node = self.manifest.nodes.get(child_unique_id)\n                    if not isinstance(child_node, ModelNode):\n                        continue\n                    if node.is_past_deprecation_date:\n                        event_cls = DeprecatedReference\n                    else:\n                        event_cls = UpcomingReferenceDeprecation\n\n                    warn_or_error(\n                        event_cls(\n                            model_name=child_node.name,\n                            ref_model_package=node.package_name,\n                            ref_model_name=node.name,\n                            ref_model_version=version_to_str(node.version),\n                            ref_model_latest_version=str(node.latest_version),\n                            ref_model_deprecation_date=node.deprecation_date.isoformat(),\n                        )\n                    )\n\n    def check_for_spaces_in_resource_names(self):\n        \"\"\"Validates that resource names do not contain spaces\n\n        If `DEBUG` flag is `False`, logs only first bad model name, unless `REQUIRE_RESOURCE_NAMES_WITHOUT_SPACES` is `True` as error will indicate all bad model names\n        If `DEBUG` flag is `True`, logs every bad model name\n        If `REQUIRE_RESOURCE_NAMES_WITHOUT_SPACES` is `True`, logs are `ERROR` level and an exception is raised if any names are bad\n        If `REQUIRE_RESOURCE_NAMES_WITHOUT_SPACES` is `False`, logs are `WARN` level\n        \"\"\"\n        improper_resource_names_unique_ids = set()\n        error_on_invalid_resource_name = (\n            self.root_project.args.REQUIRE_RESOURCE_NAMES_WITHOUT_SPACES\n        )\n        level = EventLevel.ERROR if error_on_invalid_resource_name else EventLevel.WARN\n\n        flags = get_flags()\n\n        for node in self.manifest.nodes.values():\n            if \" \" in node.name:\n                if (\n                    not improper_resource_names_unique_ids and not error_on_invalid_resource_name\n                ) or flags.DEBUG:\n                    fire_event(\n                        SpacesInResourceNameDeprecation(\n                            unique_id=node.unique_id,\n                            level=level.value,\n                        ),\n                        level=level,\n                    )\n                improper_resource_names_unique_ids.add(node.unique_id)\n\n        if improper_resource_names_unique_ids:\n            if level == EventLevel.WARN:\n                dbt.deprecations.warn(\n                    \"resource-names-with-spaces\",\n                    count_invalid_names=len(improper_resource_names_unique_ids),\n                    show_debug_hint=(not flags.DEBUG),\n                )\n            else:  # ERROR level\n                formatted_resources_with_spaces = \"\\n\".join(\n                    f\"  * '{unique_id}' ({self.manifest.nodes[unique_id].original_file_path})\"\n                    for unique_id in improper_resource_names_unique_ids\n                )\n                raise DbtValidationError(\n                    f\"Resource names cannot contain spaces:\\n{formatted_resources_with_spaces}\\nPlease rename the invalid model(s) so that their name(s) do not contain any spaces.\"\n                )\n\n    def check_for_microbatch_deprecations(self) -> None:\n        if not get_flags().require_batched_execution_for_custom_microbatch_strategy:\n            has_microbatch_model = False\n            for _, node in self.manifest.nodes.items():\n                if (\n                    isinstance(node, ModelNode)\n                    and node.config.materialized == \"incremental\"\n                    and node.config.incremental_strategy == \"microbatch\"\n                ):\n                    has_microbatch_model = True\n                    break\n\n            if has_microbatch_model and not self.manifest._microbatch_macro_is_core(\n                self.root_project.project_name\n            ):\n                dbt.deprecations.warn(\"microbatch-macro-outside-of-batches-deprecation\")\n\n    def load_and_parse_macros(self, project_parser_files):\n        for project in self.all_projects.values():\n            if project.project_name not in project_parser_files:\n                continue\n            parser_files = project_parser_files[project.project_name]\n            if \"MacroParser\" in parser_files:\n                parser = MacroParser(project, self.manifest)\n                for file_id in parser_files[\"MacroParser\"]:\n                    block = FileBlock(self.manifest.files[file_id])\n                    parser.parse_file(block)\n                    # increment parsed path count for performance tracking\n                    self._perf_info.parsed_path_count += 1\n            # generic tests hisotrically lived in the macros directoy but can now be nested\n            # in a /generic directory under /tests so we want to process them here as well\n            if \"GenericTestParser\" in parser_files:\n                parser = GenericTestParser(project, self.manifest)\n                for file_id in parser_files[\"GenericTestParser\"]:\n                    block = FileBlock(self.manifest.files[file_id])\n                    parser.parse_file(block)\n                    # increment parsed path count for performance tracking\n                    self._perf_info.parsed_path_count += 1\n\n        self.build_macro_resolver()\n        # Look at changed macros and update the macro.depends_on.macros\n        self.macro_depends_on()\n\n    # Parse the files in the 'parser_files' dictionary, for parsers listed in\n    # 'parser_types'\n    def parse_project(\n        self,\n        project: RuntimeConfig,\n        parser_files,\n        parser_types: List[Type[Parser]],\n    ) -> None:\n\n        project_loader_info = self._perf_info._project_index[project.project_name]\n        start_timer = time.perf_counter()\n        total_parsed_path_count = 0\n\n        # Loop through parsers with loaded files.\n        for parser_cls in parser_types:\n            parser_name = parser_cls.__name__\n            # No point in creating a parser if we don't have files for it\n            if parser_name not in parser_files or not parser_files[parser_name]:\n                continue\n\n            # Initialize timing info\n            project_parsed_path_count = 0\n            parser_start_timer = time.perf_counter()\n\n            # Parse the project files for this parser\n            parser: Parser = parser_cls(project, self.manifest, self.root_project)\n            for file_id in parser_files[parser_name]:\n                block = FileBlock(self.manifest.files[file_id])\n                if isinstance(parser, SchemaParser):\n                    assert isinstance(block.file, SchemaSourceFile)\n                    if self.partially_parsing:\n                        dct = block.file.pp_dict\n                    else:\n                        dct = block.file.dict_from_yaml\n                    # this is where the schema file gets parsed\n                    parser.parse_file(block, dct=dct)\n                    # Came out of here with UnpatchedSourceDefinition containing configs at the source level\n                    # and not configs at the table level (as expected)\n                else:\n                    parser.parse_file(block)\n                project_parsed_path_count += 1\n\n            # Save timing info\n            project_loader_info.parsers.append(\n                ParserInfo(\n                    parser=parser.resource_type,\n                    parsed_path_count=project_parsed_path_count,\n                    elapsed=time.perf_counter() - parser_start_timer,\n                )\n            )\n            total_parsed_path_count += project_parsed_path_count\n\n        # HookParser doesn't run from loaded files, just dbt_project.yml,\n        # so do separately\n        # This shouldn't need to be parsed again if we're starting from\n        # a saved manifest, because that won't be allowed if dbt_project.yml\n        # changed, but leave for now.\n        if not self.partially_parsing and HookParser in parser_types:\n            hook_parser = HookParser(project, self.manifest, self.root_project)\n            path = hook_parser.get_path()\n            file = load_source_file(path, ParseFileType.Hook, project.project_name, {})\n            if file:\n                file_block = FileBlock(file)\n                hook_parser.parse_file(file_block)\n\n        # Store the performance info\n        elapsed = time.perf_counter() - start_timer\n        project_loader_info.parsed_path_count = (\n            project_loader_info.parsed_path_count + total_parsed_path_count\n        )\n        project_loader_info.elapsed += elapsed\n        self._perf_info.parsed_path_count = (\n            self._perf_info.parsed_path_count + total_parsed_path_count\n        )\n\n    # This should only be called after the macros have been loaded\n    def build_macro_resolver(self):\n        internal_package_names = get_adapter_package_names(self.root_project.credentials.type)\n        self.macro_resolver = MacroResolver(\n            self.manifest.macros, self.root_project.project_name, internal_package_names\n        )\n\n    # Loop through macros in the manifest and statically parse\n    # the 'macro_sql' to find depends_on.macros\n    def macro_depends_on(self):\n        macro_ctx = generate_macro_context(self.root_project)\n        macro_namespace = TestMacroNamespace(self.macro_resolver, {}, None, MacroStack(), [])\n        adapter = get_adapter(self.root_project)\n        db_wrapper = ParseProvider().DatabaseWrapper(adapter, macro_namespace)\n        for macro in self.manifest.macros.values():\n            if macro.created_at < self.started_at:\n                continue\n            possible_macro_calls = statically_extract_macro_calls(\n                macro.macro_sql, macro_ctx, db_wrapper\n            )\n            for macro_name in possible_macro_calls:\n                # adapter.dispatch calls can generate a call with the same name as the macro\n                # it ought to be an adapter prefix (postgres_) or default_\n                if macro_name == macro.name:\n                    continue\n                package_name = macro.package_name\n                if \".\" in macro_name:\n                    package_name, macro_name = macro_name.split(\".\")\n                dep_macro_id = self.macro_resolver.get_macro_id(package_name, macro_name)\n                if dep_macro_id:\n                    macro.depends_on.add_macro(dep_macro_id)  # will check for dupes\n\n    def write_manifest_for_partial_parse(self):\n        path = os.path.join(self.root_project.project_target_path, PARTIAL_PARSE_FILE_NAME)\n        try:\n            # This shouldn't be necessary, but we have gotten bug reports (#3757) of the\n            # saved manifest not matching the code version.\n            if self.manifest.metadata.dbt_version != __version__:\n                fire_event(\n                    UnableToPartialParse(reason=\"saved manifest contained the wrong version\")\n                )\n                self.manifest.metadata.dbt_version = __version__\n            manifest_msgpack = self.manifest.to_msgpack(extended_mashumaro_encoder)\n            make_directory(os.path.dirname(path))\n            with open(path, \"wb\") as fp:\n                fp.write(manifest_msgpack)\n        except Exception:\n            raise\n\n    def inject_external_nodes(self) -> bool:\n        # Remove previously existing external nodes since we are regenerating them\n        manifest_nodes_modified = False\n        # Remove all dependent nodes before removing referencing nodes\n        for unique_id in self.manifest.external_node_unique_ids:\n            remove_dependent_project_references(self.manifest, unique_id)\n            manifest_nodes_modified = True\n        for unique_id in self.manifest.external_node_unique_ids:\n            # remove external nodes from manifest only after dependent project references safely removed\n            self.manifest.nodes.pop(unique_id)\n\n        # Inject any newly-available external nodes\n        pm = plugins.get_plugin_manager(self.root_project.project_name)\n        plugin_model_nodes = pm.get_nodes().models\n        for node_arg in plugin_model_nodes.values():\n            node = ModelNode.from_args(node_arg)\n            # node may already exist from package or running project (even if it is disabled),\n            # in which case we should avoid clobbering it with an external node\n            if (\n                node.unique_id not in self.manifest.nodes\n                and node.unique_id not in self.manifest.disabled\n            ):\n                self.manifest.add_node_nofile(node)\n                manifest_nodes_modified = True\n\n        return manifest_nodes_modified\n\n    def is_partial_parsable(self, manifest: Manifest) -> Tuple[bool, Optional[str]]:\n        \"\"\"Compare the global hashes of the read-in parse results' values to\n        the known ones, and return if it is ok to re-use the results.\n        \"\"\"\n        valid = True\n        reparse_reason = None\n\n        if manifest.metadata.dbt_version != __version__:\n            # #3757 log both versions because of reports of invalid cases of mismatch.\n            fire_event(UnableToPartialParse(reason=\"of a version mismatch\"))\n            # If the version is wrong, the other checks might not work\n            return False, ReparseReason.version_mismatch\n        if self.manifest.state_check.vars_hash != manifest.state_check.vars_hash:\n            fire_event(\n                UnableToPartialParse(\n                    reason=\"config vars, config profile, or config target have changed\"\n                )\n            )\n            fire_event(\n                Note(\n                    msg=f\"previous checksum: {self.manifest.state_check.vars_hash.checksum}, current checksum: {manifest.state_check.vars_hash.checksum}\"\n                ),\n                level=EventLevel.DEBUG,\n            )\n            valid = False\n            reparse_reason = ReparseReason.vars_changed\n        if self.manifest.state_check.profile_hash != manifest.state_check.profile_hash:\n            # Note: This should be made more granular. We shouldn't need to invalidate\n            # partial parsing if a non-used profile section has changed.\n            fire_event(UnableToPartialParse(reason=\"profile has changed\"))\n            valid = False\n            reparse_reason = ReparseReason.profile_changed\n        if (\n            self.manifest.state_check.project_env_vars_hash\n            != manifest.state_check.project_env_vars_hash\n        ):\n            fire_event(\n                UnableToPartialParse(reason=\"env vars used in dbt_project.yml have changed\")\n            )\n            valid = False\n            reparse_reason = ReparseReason.proj_env_vars_changed\n\n        missing_keys = {\n            k\n            for k in self.manifest.state_check.project_hashes\n            if k not in manifest.state_check.project_hashes\n        }\n        if missing_keys:\n            fire_event(UnableToPartialParse(reason=\"a project dependency has been added\"))\n            valid = False\n            reparse_reason = ReparseReason.deps_changed\n\n        for key, new_value in self.manifest.state_check.project_hashes.items():\n            if key in manifest.state_check.project_hashes:\n                old_value = manifest.state_check.project_hashes[key]\n                if new_value != old_value:\n                    fire_event(UnableToPartialParse(reason=\"a project config has changed\"))\n                    valid = False\n                    reparse_reason = ReparseReason.project_config_changed\n        return valid, reparse_reason\n\n    def skip_partial_parsing_because_of_macros(self):\n        if not self.partial_parser:\n            return False\n        if self.partial_parser.deleted_special_override_macro:\n            return True\n        # Check for custom versions of these special macros\n        for macro_name in special_override_macros:\n            macro = self.macro_resolver.get_macro(None, macro_name)\n            if macro and macro.package_name != \"dbt\":\n                if (\n                    macro.file_id in self.partial_parser.file_diff[\"changed\"]\n                    or macro.file_id in self.partial_parser.file_diff[\"added\"]\n                ):\n                    # The file with the macro in it has changed\n                    return True\n        return False\n\n    def read_manifest_for_partial_parse(self) -> Optional[Manifest]:\n        flags = get_flags()\n        if not flags.PARTIAL_PARSE:\n            fire_event(PartialParsingNotEnabled())\n            return None\n        path = flags.PARTIAL_PARSE_FILE_PATH or os.path.join(\n            self.root_project.project_target_path, PARTIAL_PARSE_FILE_NAME\n        )\n\n        reparse_reason = None\n\n        if os.path.exists(path):\n            try:\n                with open(path, \"rb\") as fp:\n                    manifest_mp = fp.read()\n                manifest: Manifest = Manifest.from_msgpack(manifest_mp, decoder=extended_mashumuro_decoder)  # type: ignore\n                # keep this check inside the try/except in case something about\n                # the file has changed in weird ways, perhaps due to being a\n                # different version of dbt\n                is_partial_parsable, reparse_reason = self.is_partial_parsable(manifest)\n                if is_partial_parsable:\n                    # We don't want to have stale generated_at dates\n                    manifest.metadata.generated_at = datetime.now(timezone.utc).replace(\n                        tzinfo=None\n                    )\n                    # or invocation_ids\n                    manifest.metadata.invocation_id = get_invocation_id()\n                    return manifest\n            except Exception as exc:\n                fire_event(\n                    ParsedFileLoadFailed(path=path, exc=str(exc), exc_info=traceback.format_exc())\n                )\n                reparse_reason = ReparseReason.load_file_failure\n        else:\n            fire_event(\n                UnableToPartialParse(reason=\"saved manifest not found. Starting full parse.\")\n            )\n            reparse_reason = ReparseReason.file_not_found\n\n        # this event is only fired if a full reparse is needed\n        if dbt.tracking.active_user is not None:  # no active_user if doing load_macros\n            dbt.tracking.track_partial_parser({\"full_reparse_reason\": reparse_reason})\n\n        return None\n\n    def build_perf_info(self):\n        flags = get_flags()\n        mli = ManifestLoaderInfo(\n            is_partial_parse_enabled=flags.PARTIAL_PARSE,\n            is_static_analysis_enabled=flags.STATIC_PARSER,\n        )\n        for project in self.all_projects.values():\n            project_info = ProjectLoaderInfo(\n                project_name=project.project_name,\n                elapsed=0,\n            )\n            mli.projects.append(project_info)\n            mli._project_index[project.project_name] = project_info\n        return mli\n\n    # TODO: handle --vars in the same way we handle env_var\n    # https://github.com/dbt-labs/dbt-core/issues/6323\n    def build_manifest_state_check(self):\n        config = self.root_project\n        all_projects = self.all_projects\n        # if any of these change, we need to reject the parser\n\n        # Create a FileHash of vars string, profile name and target name\n        # This does not capture vars in dbt_project, just the command line\n        # arg vars, but since any changes to that file will cause state_check\n        # to not pass, it doesn't matter.  If we move to more granular checking\n        # of env_vars, that would need to change.\n        # We are using the parsed cli_vars instead of config.args.vars, in order\n        # to sort them and avoid reparsing because of ordering issues.\n        secret_vars = [\n            v for k, v in config.cli_vars.items() if k.startswith(SECRET_ENV_PREFIX) and v.strip()\n        ]\n        stringified_cli_vars = pprint.pformat(config.cli_vars)\n        vars_hash_contents = [\n            stringified_cli_vars,\n            config.profile_name,\n            config.target_name,\n            __version__,\n        ]\n\n        # We only add vars from `vars.yml` if it's present to prevent affecting users not using vars.yml from getting fully parsed.\n        if config.vars_from_file:\n            vars_hash_contents.append(pprint.pformat(config.vars_from_file))\n\n        vars_hash = FileHash.from_contents(\"\\x00\".join(vars_hash_contents))\n        fire_event(\n            StateCheckVarsHash(\n                checksum=vars_hash.checksum,\n                vars=scrub_secrets(stringified_cli_vars, secret_vars),\n                profile=config.profile_name,\n                target=config.target_name,\n                version=__version__,\n            )\n        )\n\n        # Create a FileHash of the env_vars in the project\n        key_list = list(config.project_env_vars.keys())\n        key_list.sort()\n        env_var_str = \"\"\n        for key in key_list:\n            env_var_str += f\"{key}:{config.project_env_vars[key]}|\"\n        project_env_vars_hash = FileHash.from_contents(env_var_str)\n\n        # Create a hash of the connection_info, which user has access to in\n        # jinja context. Thus attributes here may affect the parsing result.\n        # Ideally we should not expose all of the connection info to the jinja.\n\n        # Renaming this variable mean that we will have to do a whole lot more\n        # change to make sure the previous manifest can be loaded correctly.\n        # This is an example of naming should be chosen based on the functionality\n        # rather than the implementation details.\n        connection_keys = list(config.credentials.connection_info())\n        # avoid reparsing because of ordering issues\n        connection_keys.sort()\n        profile_hash = FileHash.from_contents(pprint.pformat(connection_keys))\n\n        # Create a FileHashes for dbt_project for all dependencies\n        project_hashes = {}\n        for name, project in all_projects.items():\n            path = os.path.join(project.project_root, \"dbt_project.yml\")\n            with open(path) as fp:\n                project_hashes[name] = FileHash.from_contents(fp.read())\n\n        # Create the ManifestStateCheck object\n        state_check = ManifestStateCheck(\n            project_env_vars_hash=project_env_vars_hash,\n            vars_hash=vars_hash,\n            profile_hash=profile_hash,\n            project_hashes=project_hashes,\n        )\n        return state_check\n\n    def save_macros_to_adapter(self, adapter):\n        adapter.set_macro_resolver(self.manifest)\n        # This executes the callable macro_hook and sets the\n        # query headers\n        # This executes the callable macro_hook and sets the query headers\n        query_header_context = generate_query_header_context(adapter.config, self.manifest)\n        self.macro_hook(query_header_context)\n\n    # This creates a MacroManifest which contains the macros in\n    # the adapter. Only called by the load_macros call from the\n    # adapter.\n    def create_macro_manifest(self):\n        for project in self.all_projects.values():\n            # what is the manifest passed in actually used for?\n            macro_parser = MacroParser(project, self.manifest)\n            for path in macro_parser.get_paths():\n                source_file = load_source_file(path, ParseFileType.Macro, project.project_name, {})\n                block = FileBlock(source_file)\n                # This does not add the file to the manifest.files,\n                # but that shouldn't be necessary here.\n                macro_parser.parse_file(block)\n        macro_manifest = MacroManifest(self.manifest.macros)\n        return macro_manifest\n\n    # This is called by the adapter code only, to create the\n    # MacroManifest that's stored in the adapter.\n    # 'get_full_manifest' uses a persistent ManifestLoader while this\n    # creates a temporary ManifestLoader and throws it away.\n    # Not sure when this would actually get used except in tests.\n    # The ManifestLoader loads macros with other files, then copies\n    # into the adapter MacroManifest.\n    @classmethod\n    def load_macros(\n        cls,\n        root_config: RuntimeConfig,\n        macro_hook: Callable[[Manifest], Any],\n        base_macros_only=False,\n    ) -> Manifest:\n        # base_only/base_macros_only: for testing only,\n        # allows loading macros without running 'dbt deps' first\n        projects = root_config.load_dependencies(base_only=base_macros_only)\n\n        # This creates a loader object, including result,\n        # and then throws it away, returning only the\n        # manifest\n        loader = cls(root_config, projects, macro_hook)\n\n        return loader.create_macro_manifest()\n\n    # Create tracking event for saving performance info\n    def track_project_load(self):\n        invocation_id = get_invocation_id()\n        dbt.tracking.track_project_load(\n            {\n                \"invocation_id\": invocation_id,\n                \"project_id\": self.root_project.hashed_name(),\n                \"path_count\": self._perf_info.path_count,\n                \"parsed_path_count\": self._perf_info.parsed_path_count,\n                \"read_files_elapsed\": self._perf_info.read_files_elapsed,\n                \"load_macros_elapsed\": self._perf_info.load_macros_elapsed,\n                \"parse_project_elapsed\": self._perf_info.parse_project_elapsed,\n                \"patch_sources_elapsed\": self._perf_info.patch_sources_elapsed,\n                \"process_manifest_elapsed\": (self._perf_info.process_manifest_elapsed),\n                \"load_all_elapsed\": self._perf_info.load_all_elapsed,\n                \"is_partial_parse_enabled\": (self._perf_info.is_partial_parse_enabled),\n                \"is_static_analysis_enabled\": self._perf_info.is_static_analysis_enabled,\n                \"static_analysis_path_count\": self._perf_info.static_analysis_path_count,\n                \"static_analysis_parsed_path_count\": self._perf_info.static_analysis_parsed_path_count,  # noqa: E501\n            }\n        )\n\n    # Takes references in 'refs' array of nodes and exposures, finds the target\n    # node, and updates 'depends_on.nodes' with the unique id\n    def process_refs(self, current_project: str, dependencies: Optional[Mapping[str, Project]]):\n        for node in self.manifest.nodes.values():\n            if node.created_at < self.started_at:\n                continue\n            _process_refs(self.manifest, current_project, node, dependencies)\n        for exposure in self.manifest.exposures.values():\n            if exposure.created_at < self.started_at:\n                continue\n            _process_refs(self.manifest, current_project, exposure, dependencies)\n        for metric in self.manifest.metrics.values():\n            if metric.created_at < self.started_at:\n                continue\n            _process_refs(self.manifest, current_project, metric, dependencies)\n        for semantic_model in self.manifest.semantic_models.values():\n            if semantic_model.created_at < self.started_at:\n                continue\n            _process_refs(self.manifest, current_project, semantic_model, dependencies)\n            self.update_semantic_model(semantic_model)\n        for function in self.manifest.functions.values():\n            if function.created_at < self.started_at:\n                continue\n            _process_refs(self.manifest, current_project, function, dependencies)\n\n    # Takes references in 'metrics' array of nodes and exposures, finds the target\n    # node, and updates 'depends_on.nodes' with the unique id\n    def process_metrics(self, config: RuntimeConfig):\n        current_project = config.project_name\n        for metric in self.manifest.metrics.values():\n            if metric.created_at < self.started_at:\n                continue\n            _process_metric_node(self.manifest, current_project, metric)\n            _process_metrics_for_node(self.manifest, current_project, metric)\n        for node in self.manifest.nodes.values():\n            if node.created_at < self.started_at:\n                continue\n            _process_metrics_for_node(self.manifest, current_project, node)\n        for exposure in self.manifest.exposures.values():\n            if exposure.created_at < self.started_at:\n                continue\n            _process_metrics_for_node(self.manifest, current_project, exposure)\n\n    def process_saved_queries(self, config: RuntimeConfig):\n        \"\"\"Processes SavedQuery nodes to populate their `depends_on`.\"\"\"\n        # Note: This will also capture various nodes which have been re-parsed\n        # because they refer to some other changed node, so there will be\n        # false positives. Ideally we would compare actual changes.\n        semantic_manifest_changed = False\n        semantic_manifest_nodes: chain[SemanticManifestNode] = chain(\n            self.manifest.saved_queries.values(),\n            self.manifest.semantic_models.values(),\n            self.manifest.metrics.values(),\n        )\n        for node in semantic_manifest_nodes:\n            # Check if this node has been modified in this parsing run\n            if node.created_at > self.started_at:\n                semantic_manifest_changed = True\n                break  # as soon as we run into one changed node we can stop\n        if semantic_manifest_changed is False:\n            return\n\n        current_project = config.project_name\n        for saved_query in self.manifest.saved_queries.values():\n            # TODO:\n            # 1. process `where` of SavedQuery for `depends_on`s\n            # 2. process `group_by` of SavedQuery for `depends_on``\n            _process_metrics_for_node(self.manifest, current_project, saved_query)\n\n    def process_model_inferred_primary_keys(self):\n        \"\"\"Processes Model nodes to populate their `primary_key`.\"\"\"\n        model_to_generic_test_map: Dict[str, List[GenericTestNode]] = {}\n        for node in self.manifest.nodes.values():\n            if not isinstance(node, ModelNode):\n                continue\n            if node.created_at < self.started_at:\n                continue\n            if not model_to_generic_test_map:\n                model_to_generic_test_map = self.build_model_to_generic_tests_map()\n            generic_tests: List[GenericTestNode] = []\n            if node.unique_id in model_to_generic_test_map:\n                generic_tests = model_to_generic_test_map[node.unique_id]\n            primary_key = node.infer_primary_key(generic_tests)\n            node.primary_key = sorted(primary_key)\n\n    def update_semantic_model(self, semantic_model) -> None:\n        # This has to be done at the end of parsing because the referenced model\n        # might have alias/schema/database fields that are updated by yaml config.\n        if semantic_model.depends_on_nodes:\n            refd_node = self.manifest.nodes[semantic_model.depends_on_nodes[0]]\n            semantic_model.node_relation = NodeRelation(\n                relation_name=refd_node.relation_name,\n                alias=refd_node.alias,\n                schema_name=refd_node.schema,\n                database=refd_node.database,\n            )\n\n    # nodes: node and column descriptions, version columns descriptions\n    # sources: source and table descriptions, column descriptions\n    # macros: macro argument descriptions\n    # exposures: exposure descriptions\n    # metrics: metric descriptions\n    # semantic_models: semantic model descriptions\n    def process_docs(self, config: RuntimeConfig):\n        for node in self.manifest.nodes.values():\n            if node.created_at < self.started_at:\n                continue\n            ctx = generate_runtime_docs_context(\n                config,\n                node,\n                self.manifest,\n                config.project_name,\n            )\n            _process_docs_for_node(ctx, node, self.manifest)\n        for source in self.manifest.sources.values():\n            if source.created_at < self.started_at:\n                continue\n            ctx = generate_runtime_docs_context(\n                config,\n                source,\n                self.manifest,\n                config.project_name,\n            )\n            _process_docs_for_source(ctx, source, self.manifest)\n        for macro in self.manifest.macros.values():\n            if macro.created_at < self.started_at:\n                continue\n            ctx = generate_runtime_docs_context(\n                config,\n                macro,\n                self.manifest,\n                config.project_name,\n            )\n            _process_docs_for_macro(ctx, macro)\n        for exposure in self.manifest.exposures.values():\n            if exposure.created_at < self.started_at:\n                continue\n            ctx = generate_runtime_docs_context(\n                config,\n                exposure,\n                self.manifest,\n                config.project_name,\n            )\n            _process_docs_for_exposure(ctx, exposure)\n        for metric in self.manifest.metrics.values():\n            if metric.created_at < self.started_at:\n                continue\n            ctx = generate_runtime_docs_context(\n                config,\n                metric,\n                self.manifest,\n                config.project_name,\n            )\n            _process_docs_for_metrics(ctx, metric)\n        for semantic_model in self.manifest.semantic_models.values():\n            if semantic_model.created_at < self.started_at:\n                continue\n            ctx = generate_runtime_docs_context(\n                config,\n                semantic_model,\n                self.manifest,\n                config.project_name,\n            )\n            _process_docs_for_semantic_model(ctx, semantic_model)\n        for saved_query in self.manifest.saved_queries.values():\n            if saved_query.created_at < self.started_at:\n                continue\n            ctx = generate_runtime_docs_context(\n                config, saved_query, self.manifest, config.project_name\n            )\n            _process_docs_for_saved_query(ctx, saved_query)\n\n    # Loops through all nodes and exposures, for each element in\n    # 'sources' array finds the source node and updates the\n    # 'depends_on.nodes' array with the unique id\n    def process_sources(self, current_project: str):\n        for node in self.manifest.nodes.values():\n            if node.resource_type == NodeType.Source:\n                continue\n            assert not isinstance(node, SourceDefinition)\n            if node.created_at < self.started_at:\n                continue\n            _process_sources_for_node(self.manifest, current_project, node)\n        for exposure in self.manifest.exposures.values():\n            if exposure.created_at < self.started_at:\n                continue\n            _process_sources_for_exposure(self.manifest, current_project, exposure)\n\n    # Loops through all nodes, for each element in\n    # 'unit_test' array finds the node and updates the\n    # 'depends_on.nodes' array with the unique id\n    def process_unit_tests(self, current_project: str):\n        models_to_versions = None\n        unit_test_unique_ids = list(self.manifest.unit_tests.keys())\n        for unit_test_unique_id in unit_test_unique_ids:\n            # This is because some unit tests will be removed when processing\n            # and the list of unit_test_unique_ids won't have changed\n            if unit_test_unique_id in self.manifest.unit_tests:\n                unit_test = self.manifest.unit_tests[unit_test_unique_id]\n            else:\n                continue\n            if unit_test.created_at < self.started_at:\n                continue\n            if not models_to_versions:\n                models_to_versions = _build_model_names_to_versions(self.manifest)\n            process_models_for_unit_test(\n                self.manifest, current_project, unit_test, models_to_versions\n            )\n\n    # Loops through all nodes, for each element in\n    # 'functions' array finds the node and updates the\n    # 'depends_on.nodes' array with the unique id\n    def process_functions(self, current_project: str):\n        for node in self.manifest.nodes.values():\n            if node.created_at < self.started_at:\n                continue\n            _process_functions_for_node(self.manifest, current_project, node)\n\n        for function in self.manifest.functions.values():\n            if function.created_at < self.started_at:\n                continue\n            _process_functions_for_node(self.manifest, current_project, function)\n\n    def cleanup_disabled(self):\n        # make sure the nodes are in the manifest.nodes or the disabled dict,\n        # correctly now that the schema files are also parsed\n        disabled_nodes = []\n        for node in self.manifest.nodes.values():\n            if not node.config.enabled:\n                disabled_nodes.append(node.unique_id)\n                self.manifest.add_disabled_nofile(node)\n        for unique_id in disabled_nodes:\n            self.manifest.nodes.pop(unique_id)\n\n        disabled_copy = deepcopy(self.manifest.disabled)\n        for disabled in disabled_copy.values():\n            for node in disabled:\n                if node.config.enabled:\n                    for dis_index, dis_node in enumerate(disabled):\n                        # Remove node from disabled and unique_id from disabled dict if necessary\n                        del self.manifest.disabled[node.unique_id][dis_index]\n                        if not self.manifest.disabled[node.unique_id]:\n                            self.manifest.disabled.pop(node.unique_id)\n\n                    self.manifest.add_node_nofile(node)\n\n        self.manifest.rebuild_ref_lookup()\n\n    def check_valid_group_config(self):\n        manifest = self.manifest\n        group_names = {group.name for group in manifest.groups.values()}\n\n        for metric in manifest.metrics.values():\n            self.check_valid_group_config_node(metric, group_names)\n\n        for semantic_model in manifest.semantic_models.values():\n            self.check_valid_group_config_node(semantic_model, group_names)\n\n        for saved_query in manifest.saved_queries.values():\n            self.check_valid_group_config_node(saved_query, group_names)\n\n        for node in manifest.nodes.values():\n            self.check_valid_group_config_node(node, group_names)\n\n    def check_valid_group_config_node(\n        self,\n        groupable_node: Union[Metric, SavedQuery, SemanticModel, ManifestNode],\n        valid_group_names: Set[str],\n    ):\n        groupable_node_group = groupable_node.group\n        if groupable_node_group and groupable_node_group not in valid_group_names:\n            raise dbt.exceptions.ParsingError(\n                f\"Invalid group '{groupable_node_group}', expected one of {sorted(list(valid_group_names))}\",\n                node=groupable_node,\n            )\n\n    def check_valid_access_property(self):\n        for node in self.manifest.nodes.values():\n            if (\n                isinstance(node, ModelNode)\n                and node.access == AccessType.Public\n                and node.get_materialization() == \"ephemeral\"\n            ):\n                raise InvalidAccessTypeError(\n                    unique_id=node.unique_id,\n                    field_value=node.access,\n                    materialization=node.get_materialization(),\n                )\n\n    def check_valid_snapshot_config(self):\n        # Snapshot config can be set in either SQL files or yaml files,\n        # so we need to validate afterward.\n        for node in self.manifest.nodes.values():\n            if node.resource_type != NodeType.Snapshot:\n                continue\n            if node.created_at < self.started_at:\n                continue\n            node.config.final_validate()\n\n    def check_valid_microbatch_config(self):\n        if self.manifest.use_microbatch_batches(project_name=self.root_project.project_name):\n            for node in self.manifest.nodes.values():\n                if (\n                    node.config.materialized == \"incremental\"\n                    and node.config.incremental_strategy == \"microbatch\"\n                ):\n                    # Required configs: event_time, batch_size, begin\n                    event_time = node.config.event_time\n                    if event_time is None:\n                        raise dbt.exceptions.ParsingError(\n                            f\"Microbatch model '{node.name}' must provide an 'event_time' (string) config that indicates the name of the event time column.\"\n                        )\n                    if not isinstance(event_time, str):\n                        raise dbt.exceptions.ParsingError(\n                            f\"Microbatch model '{node.name}' must provide an 'event_time' config of type string, but got: {type(event_time)}.\"\n                        )\n\n                    begin = node.config.begin\n                    if begin is None:\n                        raise dbt.exceptions.ParsingError(\n                            f\"Microbatch model '{node.name}' must provide a 'begin' (datetime) config that indicates the earliest timestamp the microbatch model should be built from.\"\n                        )\n\n                    # Try to cast begin to a datetime using same format as mashumaro for consistency with other yaml-provided datetimes\n                    # Mashumaro default: https://github.com/Fatal1ty/mashumaro/blob/4ac16fd060a6c651053475597b58b48f958e8c5c/README.md?plain=1#L1186\n                    if isinstance(begin, str):\n                        try:\n                            begin = datetime.fromisoformat(begin)\n                            node.config.begin = begin\n                        except Exception:\n                            raise dbt.exceptions.ParsingError(\n                                f\"Microbatch model '{node.name}' must provide a 'begin' config of valid datetime (ISO format), but got: {begin}.\"\n                            )\n\n                    if not isinstance(begin, datetime):\n                        raise dbt.exceptions.ParsingError(\n                            f\"Microbatch model '{node.name}' must provide a 'begin' config of type datetime, but got: {type(begin)}.\"\n                        )\n\n                    batch_size = node.config.batch_size\n                    valid_batch_sizes = [size.value for size in BatchSize]\n                    if batch_size not in valid_batch_sizes:\n                        raise dbt.exceptions.ParsingError(\n                            f\"Microbatch model '{node.name}' must provide a 'batch_size' config that is one of {valid_batch_sizes}, but got: {batch_size}.\"\n                        )\n\n                    # Optional config: lookback (int)\n                    lookback = node.config.lookback\n                    if not isinstance(lookback, int) and lookback is not None:\n                        raise dbt.exceptions.ParsingError(\n                            f\"Microbatch model '{node.name}' must provide the optional 'lookback' config as type int, but got: {type(lookback)}).\"\n                        )\n\n                    # optional config: concurrent_batches (bool)\n                    concurrent_batches = node.config.concurrent_batches\n                    if not isinstance(concurrent_batches, bool) and concurrent_batches is not None:\n                        raise dbt.exceptions.ParsingError(\n                            f\"Microbatch model '{node.name}' optional 'concurrent_batches' config must be of type `bool` if specified, but got: {type(concurrent_batches)}).\"\n                        )\n\n    def check_forcing_batch_concurrency(self) -> None:\n        if self.manifest.use_microbatch_batches(project_name=self.root_project.project_name):\n            adapter = get_adapter(self.root_project)\n\n            if not adapter.supports(Capability.MicrobatchConcurrency):\n                models_forcing_concurrent_batches = 0\n                for node in self.manifest.nodes.values():\n                    if (\n                        hasattr(node.config, \"concurrent_batches\")\n                        and node.config.concurrent_batches is True\n                    ):\n                        models_forcing_concurrent_batches += 1\n\n                if models_forcing_concurrent_batches > 0:\n                    warn_or_error(\n                        InvalidConcurrentBatchesConfig(\n                            num_models=models_forcing_concurrent_batches,\n                            adapter_type=adapter.type(),\n                        )\n                    )\n\n    def check_microbatch_model_has_a_filtered_input(self):\n        if self.manifest.use_microbatch_batches(project_name=self.root_project.project_name):\n            for node in self.manifest.nodes.values():\n                if (\n                    node.config.materialized == \"incremental\"\n                    and node.config.incremental_strategy == \"microbatch\"\n                ):\n                    # Validate upstream node event_time (if configured)\n                    has_input_with_event_time_config = False\n                    for input_unique_id in node.depends_on.nodes:\n                        input_node = self.manifest.expect(unique_id=input_unique_id)\n                        input_event_time = input_node.config.event_time\n                        if input_event_time:\n                            if not isinstance(input_event_time, str):\n                                raise dbt.exceptions.ParsingError(\n                                    f\"Microbatch model '{node.name}' depends on an input node '{input_node.name}' with an 'event_time' config of invalid (non-string) type: {type(input_event_time)}.\"\n                                )\n                            has_input_with_event_time_config = True\n\n                    if not has_input_with_event_time_config:\n                        fire_event(MicrobatchModelNoEventTimeInputs(model_name=node.name))\n\n    def check_function_default_arguments_ordering(self):\n        for function in self.manifest.functions.values():\n            found_default_value = False\n            for argument in function.arguments:\n                if not found_default_value and argument.default_value is not None:\n                    found_default_value = True\n                elif found_default_value and argument.default_value is None:\n                    raise dbt.exceptions.ParsingError(\n                        f\"Non-defaulted argument '{argument.name}' of function '{function.name}' comes after a defaulted argument. Non-defaulted arguments cannot come after defaulted arguments. \"\n                    )\n\n    def write_perf_info(self, target_path: str):\n        path = os.path.join(target_path, PERF_INFO_FILE_NAME)\n        write_file(path, json.dumps(self._perf_info, cls=dbt.utils.JSONEncoder, indent=4))\n        fire_event(ParsePerfInfoPath(path=path))\n\n    def build_model_to_generic_tests_map(self) -> Dict[str, List[GenericTestNode]]:\n        \"\"\"Return a list of generic tests that are attached to the given model, including disabled tests\"\"\"\n        model_to_generic_tests_map: Dict[str, List[GenericTestNode]] = {}\n        for _, node in self.manifest.nodes.items():\n            if isinstance(node, GenericTestNode) and node.attached_node:\n                if node.attached_node not in model_to_generic_tests_map:\n                    model_to_generic_tests_map[node.attached_node] = []\n                model_to_generic_tests_map[node.attached_node].append(node)\n        for _, nodes in self.manifest.disabled.items():\n            for disabled_node in nodes:\n                if isinstance(disabled_node, GenericTestNode) and disabled_node.attached_node:\n                    if disabled_node.attached_node not in model_to_generic_tests_map:\n                        model_to_generic_tests_map[disabled_node.attached_node] = []\n                    model_to_generic_tests_map[disabled_node.attached_node].append(disabled_node)\n        return model_to_generic_tests_map\n\n\ndef invalid_target_fail_unless_test(\n    node,\n    target_name: str,\n    target_kind: str,\n    target_package: Optional[str] = None,\n    target_version: Optional[NodeVersion] = None,\n    disabled: Optional[bool] = None,\n    should_warn_if_disabled: bool = True,\n):\n    if node.resource_type == NodeType.Test:\n        if disabled:\n            event = InvalidDisabledTargetInTestNode(\n                resource_type_title=node.resource_type.title(),\n                unique_id=node.unique_id,\n                original_file_path=node.original_file_path,\n                target_kind=target_kind,\n                target_name=target_name,\n                target_package=target_package if target_package else \"\",\n            )\n\n            fire_event(event, EventLevel.WARN if should_warn_if_disabled else None)\n        else:\n            warn_or_error(\n                NodeNotFoundOrDisabled(\n                    original_file_path=node.original_file_path,\n                    unique_id=node.unique_id,\n                    resource_type_title=node.resource_type.title(),\n                    target_name=target_name,\n                    target_kind=target_kind,\n                    target_package=target_package if target_package else \"\",\n                    disabled=str(disabled),\n                )\n            )\n    else:\n        raise TargetNotFoundError(\n            node=node,\n            target_name=target_name,\n            target_kind=target_kind,\n            target_package=target_package,\n            target_version=target_version,\n            disabled=disabled,\n        )\n\n\ndef warn_if_package_node_depends_on_root_project_node(\n    node: ManifestNode,\n    target_model: ManifestNode,\n    ref_package_name: Optional[str],\n    current_project: str,\n) -> None:\n    \"\"\"\n    Args:\n        node: The node that specifies the ref\n        target_model: The node that is being ref'd to\n        ref_package_name: The package name specified in the ref\n        current_project: The root project\n    \"\"\"\n    if (\n        node.package_name != current_project\n        and target_model.package_name == current_project\n        and ref_package_name != current_project\n    ):\n        warn_or_error(\n            PackageNodeDependsOnRootProjectNode(\n                node_name=node.name,\n                package_name=node.package_name,\n                root_project_unique_id=target_model.unique_id,\n            )\n        )\n\n\ndef _build_model_names_to_versions(manifest: Manifest) -> Dict[str, Dict]:\n    model_names_to_versions: Dict[str, Dict] = {}\n    for node in manifest.nodes.values():\n        if node.resource_type != NodeType.Model:\n            continue\n        if not node.is_versioned:\n            continue\n        if node.package_name not in model_names_to_versions:\n            model_names_to_versions[node.package_name] = {}\n        if node.name not in model_names_to_versions[node.package_name]:\n            model_names_to_versions[node.package_name][node.name] = []\n        model_names_to_versions[node.package_name][node.name].append(node.unique_id)\n    return model_names_to_versions\n\n\ndef _check_resource_uniqueness(\n    manifest: Manifest,\n    config: RuntimeConfig,\n) -> None:\n    alias_resources: Dict[str, ManifestNode] = {}\n    name_resources: Dict[str, Dict] = {}\n\n    for _, node in manifest.nodes.items():\n        if not node.is_relational:\n            continue\n\n        if node.package_name not in name_resources:\n            name_resources[node.package_name] = {\"ver\": {}, \"unver\": {}}\n\n        existing_unversioned_node = name_resources[node.package_name][\"unver\"].get(node.name)\n        if existing_unversioned_node is not None and not node.is_versioned:\n            if get_flags().require_unique_project_resource_names:\n                raise DuplicateResourceNameError(existing_unversioned_node, node)\n            else:\n                dbt.deprecations.warn(\n                    \"duplicate-name-distinct-node-types-deprecation\",\n                    resource_name=node.name,\n                    unique_id1=existing_unversioned_node.unique_id,\n                    unique_id2=node.unique_id,\n                    package_name=node.package_name,\n                )\n\n        if node.is_versioned:\n            name_resources[node.package_name][\"ver\"][node.name] = node\n        else:\n            name_resources[node.package_name][\"unver\"][node.name] = node\n\n        # the full node name is really defined by the adapter's relation\n        relation_cls = get_relation_class_by_name(config.credentials.type)\n        relation = relation_cls.create_from(quoting=config, relation_config=node)  # type: ignore[arg-type]\n        full_node_name = str(relation)\n\n        existing_alias = alias_resources.get(full_node_name)\n        if existing_alias is not None:\n            raise AmbiguousAliasError(\n                node_1=existing_alias, node_2=node, duped_name=full_node_name\n            )\n\n        alias_resources[full_node_name] = node\n\n    for ver_unver_dict in name_resources.values():\n        versioned_names = ver_unver_dict[\"ver\"].keys()\n        unversioned_names = ver_unver_dict[\"unver\"].keys()\n        intersection_versioned = set(versioned_names).intersection(set(unversioned_names))\n        if intersection_versioned:\n            for name in intersection_versioned:\n                versioned_node = ver_unver_dict[\"ver\"][name]\n                unversioned_node = ver_unver_dict[\"unver\"][name]\n                raise dbt.exceptions.DuplicateVersionedUnversionedError(\n                    versioned_node, unversioned_node\n                )\n\n\ndef _warn_for_unused_resource_config_paths(manifest: Manifest, config: RuntimeConfig) -> None:\n    resource_fqns: Mapping[str, PathSet] = manifest.get_resource_fqns()\n    disabled_fqns: PathSet = frozenset(\n        tuple(n.fqn) for n in list(chain.from_iterable(manifest.disabled.values()))\n    )\n    config.warn_for_unused_resource_config_paths(resource_fqns, disabled_fqns)\n\n\ndef _check_manifest(manifest: Manifest, config: RuntimeConfig) -> None:\n    _check_resource_uniqueness(manifest, config)\n    _warn_for_unused_resource_config_paths(manifest, config)\n\n\nDocsContextCallback = Callable[[ResultNode], Dict[str, Any]]\n\n\ndef _get_doc_blocks(description: str, manifest: Manifest, node_package: str) -> List[str]:\n    ast = parse(description)\n    doc_blocks: List[str] = []\n\n    if not hasattr(ast, \"body\"):\n        return doc_blocks\n\n    for statement in ast.body:\n        for node in statement.nodes:\n            if (\n                isinstance(node, Call)\n                and hasattr(node, \"node\")\n                and hasattr(node, \"args\")\n                and hasattr(node.node, \"name\")\n                and node.node.name == \"doc\"\n            ):\n                # Only Const is statically resolvable to a block name at parse time.\n                #    * It does have a \"value\" attribute but mypy is unconvinced so the hasattr is to make it extra happy.\n                # Filter out Const values to avoid raising an unhandled exception attempting\n                # to statically parseother jinja expression nodes (ie Concat, CondExpr)\n                doc_args = [\n                    arg.value\n                    for arg in node.args\n                    if isinstance(arg, Const) and hasattr(arg, \"value\")\n                ]\n\n                if len(doc_args) == 1:\n                    package, name = None, doc_args[0]\n                elif len(doc_args) == 2:\n                    package, name = doc_args\n                else:\n                    continue\n\n                if not manifest.metadata.project_name:\n                    continue\n\n                resolved_doc = manifest.resolve_doc(\n                    name, package, manifest.metadata.project_name, node_package\n                )\n\n                if resolved_doc:\n                    doc_blocks.append(resolved_doc.unique_id)\n\n    return doc_blocks\n\n\n# node and column descriptions\ndef _process_docs_for_node(\n    context: Dict[str, Any],\n    node: ManifestNode,\n    manifest: Manifest,\n):\n    node.doc_blocks = _get_doc_blocks(node.description, manifest, node.package_name)\n    node.description = get_rendered(node.description, context)\n\n    for column_name, column in node.columns.items():\n        column.doc_blocks = _get_doc_blocks(column.description, manifest, node.package_name)\n        column.description = get_rendered(column.description, context)\n\n\n# source and table descriptions, column descriptions\ndef _process_docs_for_source(\n    context: Dict[str, Any],\n    source: SourceDefinition,\n    manifest: Manifest,\n):\n    source.doc_blocks = _get_doc_blocks(source.description, manifest, source.package_name)\n    source.description = get_rendered(source.description, context)\n\n    source.source_description = get_rendered(source.source_description, context)\n\n    for column in source.columns.values():\n        column.doc_blocks = _get_doc_blocks(column.description, manifest, source.package_name)\n        column.description = get_rendered(column.description, context)\n\n\n# macro argument descriptions\ndef _process_docs_for_macro(context: Dict[str, Any], macro: Macro) -> None:\n    macro.description = get_rendered(macro.description, context)\n    for arg in macro.arguments:\n        arg.description = get_rendered(arg.description, context)\n\n\n# exposure descriptions\ndef _process_docs_for_exposure(context: Dict[str, Any], exposure: Exposure) -> None:\n    exposure.description = get_rendered(exposure.description, context)\n\n\ndef _process_docs_for_metrics(context: Dict[str, Any], metric: Metric) -> None:\n    metric.description = get_rendered(metric.description, context)\n\n\ndef _process_docs_for_semantic_model(\n    context: Dict[str, Any], semantic_model: SemanticModel\n) -> None:\n    if semantic_model.description:\n        semantic_model.description = get_rendered(semantic_model.description, context)\n\n    for dimension in semantic_model.dimensions:\n        if dimension.description:\n            dimension.description = get_rendered(dimension.description, context)\n\n    for measure in semantic_model.measures:\n        if measure.description:\n            measure.description = get_rendered(measure.description, context)\n\n    for entity in semantic_model.entities:\n        if entity.description:\n            entity.description = get_rendered(entity.description, context)\n\n\ndef _process_docs_for_saved_query(context: Dict[str, Any], saved_query: SavedQuery) -> None:\n    if saved_query.description:\n        saved_query.description = get_rendered(saved_query.description, context)\n\n\ndef _process_refs(\n    manifest: Manifest, current_project: str, node, dependencies: Optional[Mapping[str, Project]]\n) -> None:\n    \"\"\"Given a manifest and node in that manifest, process its refs\"\"\"\n\n    dependencies = dependencies or {}\n\n    if isinstance(node, SeedNode):\n        return\n\n    for ref in node.refs:\n        target_model: Optional[Union[Disabled, ManifestNode]] = None\n        target_model_name: str = ref.name\n        target_model_package: Optional[str] = ref.package\n        target_model_version: Optional[NodeVersion] = ref.version\n\n        if len(ref.positional_args) < 1 or len(ref.positional_args) > 2:\n            raise dbt.exceptions.DbtInternalError(\n                f\"Refs should always be 1 or 2 arguments - got {len(ref.positional_args)}\"\n            )\n\n        target_model = manifest.resolve_ref(\n            node,\n            target_model_name,\n            target_model_package,\n            target_model_version,\n            current_project,\n            node.package_name,\n        )\n\n        if target_model is None or isinstance(target_model, Disabled):\n            # This may raise. Even if it doesn't, we don't want to add\n            # this exposure to the graph b/c there is no destination exposure\n            node.config.enabled = False\n            invalid_target_fail_unless_test(\n                node=node,\n                target_name=target_model_name,\n                target_kind=\"node\",\n                target_package=target_model_package,\n                target_version=target_model_version,\n                disabled=(isinstance(target_model, Disabled)),\n                should_warn_if_disabled=False,\n            )\n\n            continue\n        elif manifest.is_invalid_private_ref(node, target_model, dependencies):\n            raise dbt.exceptions.DbtReferenceError(\n                unique_id=node.unique_id,\n                ref_unique_id=target_model.unique_id,\n                access=AccessType.Private,\n                scope=dbt_common.utils.cast_to_str(target_model.group),\n            )\n        elif manifest.is_invalid_protected_ref(node, target_model, dependencies):\n            raise dbt.exceptions.DbtReferenceError(\n                unique_id=node.unique_id,\n                ref_unique_id=target_model.unique_id,\n                access=AccessType.Protected,\n                scope=target_model.package_name,\n            )\n\n        if not get_flags().require_ref_searches_node_package_before_root:\n            warn_if_package_node_depends_on_root_project_node(\n                node, target_model, ref.package, current_project\n            )\n\n        target_model_id = target_model.unique_id\n        node.depends_on.add_node(target_model_id)\n\n\ndef _add_depends_on_metrics_to_v2_metric(\n    metric: Metric,\n    input_metrics: List[MetricInput],\n    manifest: Manifest,\n    current_project: str,\n) -> None:\n    \"\"\"Set the depends_on property for a v2 metric that depends on other metrics\"\"\"\n    for input_metric in input_metrics:\n        target_metric = manifest.resolve_metric(\n            target_metric_name=input_metric.name,\n            target_metric_package=None,\n            current_project=current_project,\n            node_package=metric.package_name,\n        )\n\n        if target_metric is None:\n            raise dbt.exceptions.ParsingError(\n                f\"The metric `{input_metric.name}` does not exist but was referenced.\",\n                node=metric,\n            )\n        elif isinstance(target_metric, Disabled):\n            raise dbt.exceptions.ParsingError(\n                f\"The metric `{input_metric.name}` is disabled and thus cannot be referenced.\",\n                node=metric,\n            )\n\n        _process_metric_node(\n            manifest=manifest,\n            current_project=current_project,\n            metric=target_metric,\n        )\n        metric.depends_on.add_node(target_metric.unique_id)\n\n\ndef _process_metric_depends_on_semantic_models_for_measures(\n    manifest: Manifest,\n    current_project: str,\n    metric: Metric,\n) -> None:\n    \"\"\"For a given v1 metric, set the `depends_on` property\"\"\"\n\n    assert (\n        len(metric.type_params.input_measures) > 0\n        or metric.type_params.metric_aggregation_params is not None\n    ), f\"{metric} should have a measure or agg type defined, but it does not.\"\n    for input_measure in metric.type_params.input_measures:\n        target_semantic_model = manifest.resolve_semantic_model_for_measure(\n            target_measure_name=input_measure.name,\n            current_project=current_project,\n            node_package=metric.package_name,\n        )\n        if target_semantic_model is None:\n            raise dbt.exceptions.ParsingError(\n                f\"A semantic model having a measure `{input_measure.name}` does not exist but was referenced.\",\n                node=metric,\n            )\n        if target_semantic_model.config.enabled is False:\n            raise dbt.exceptions.ParsingError(\n                f\"The measure `{input_measure.name}` is referenced on disabled semantic model `{target_semantic_model.name}`.\",\n                node=metric,\n            )\n\n        metric.depends_on.add_node(target_semantic_model.unique_id)\n\n\ndef _process_multiple_metric_inputs(\n    manifest: Manifest,\n    current_project: str,\n    metric: Metric,\n    metric_inputs: List[MetricInput],\n) -> None:\n    for input_metric in metric_inputs:\n        target_metric = manifest.resolve_metric(\n            target_metric_name=input_metric.name,\n            target_metric_package=None,\n            current_project=current_project,\n            node_package=metric.package_name,\n        )\n\n        if target_metric is None:\n            raise dbt.exceptions.ParsingError(\n                f\"The metric `{input_metric.name}` does not exist but was referenced.\",\n                node=metric,\n            )\n        elif isinstance(target_metric, Disabled):\n            raise dbt.exceptions.ParsingError(\n                f\"The metric `{input_metric.name}` is disabled and thus cannot be referenced.\",\n                node=metric,\n            )\n\n        _process_metric_node(\n            manifest=manifest, current_project=current_project, metric=target_metric\n        )\n        for input_measure in target_metric.type_params.input_measures:\n            metric.add_input_measure(input_measure)\n        metric.depends_on.add_node(target_metric.unique_id)\n\n\ndef _process_metric_node(\n    manifest: Manifest,\n    current_project: str,\n    metric: Metric,\n) -> None:\n    \"\"\"Sets a metric's `input_measures` and `depends_on` properties\"\"\"\n    # This ensures that if this metrics input_measures have already been set\n    # we skip the work. This could happen either due to recursion or if multiple\n    # metrics derive from another given metric.\n    # NOTE: This does not protect against infinite loops\n    if len(metric.type_params.input_measures) > 0:\n        return\n        # TODO DI-4613: we need a v2 equivalent to avoid unnecessary work!  (This will\n        # probably require passing through / maintaining a \"processed\" set of metric names)\n\n    if metric.type is MetricType.SIMPLE or metric.type is MetricType.CUMULATIVE:\n        if metric.type is MetricType.SIMPLE and (\n            metric.type_params.measure is None\n            and metric.type_params.metric_aggregation_params is None\n        ):\n            # This should be caught earlier, but just in case, we assert here to avoid\n            # any unexpected behaviors.\n            raise dbt.exceptions.ParsingError(\n                f\"Simple metric {metric} should have a measure or agg type defined, but it does not.\",\n                node=metric,\n            )\n        elif metric.type is MetricType.CUMULATIVE and (\n            metric.type_params.measure is None\n            and (\n                metric.type_params.cumulative_type_params is None\n                or metric.type_params.cumulative_type_params.metric is None\n            )\n        ):\n            raise dbt.exceptions.ParsingError(\n                f\"Cumulative metric {metric} should have a measure or input_metric defined, but it does not.\",\n                node=metric,\n            )\n        if metric.type_params.measure is not None:\n            # v1 dependencies\n            metric.add_input_measure(metric.type_params.measure)\n            _process_metric_depends_on_semantic_models_for_measures(\n                manifest=manifest, current_project=current_project, metric=metric\n            )\n        else:\n            # v2 dependencies\n            if metric.type is MetricType.SIMPLE:\n                semantic_model_dependency = metric.type_params.get_semantic_model_name()\n                if semantic_model_dependency is None:\n                    raise dbt.exceptions.ParsingError(\n                        f\"Simple metric `{metric.name}` must be attached to a semantic model.\",\n                        node=metric,\n                    )\n                unique_id = (\n                    f\"{NodeType.SemanticModel}.{current_project}.{semantic_model_dependency}\"\n                )\n                metric.depends_on.add_node(unique_id)\n            if metric.type is MetricType.CUMULATIVE:\n                cumulative_type_params = metric.type_params.cumulative_type_params\n                input_metric = (\n                    cumulative_type_params.metric if cumulative_type_params is not None else None\n                )\n                assert (\n                    input_metric is not None\n                ), f\"Cumulative metric `{metric.name}` must have a metric as an input.\"\n                _add_depends_on_metrics_to_v2_metric(\n                    metric,\n                    input_metrics=[input_metric],\n                    manifest=manifest,\n                    current_project=current_project,\n                )\n    elif metric.type is MetricType.CONVERSION:\n        conversion_type_params = metric.type_params.conversion_type_params\n        assert (\n            conversion_type_params\n        ), f\"{metric.name} is a conversion metric and must have conversion_type_params defined.\"\n        # Handle old-style YAML measure inputs\n        base_measure = conversion_type_params.base_measure\n        conversion_measure = conversion_type_params.conversion_measure\n        base_metric = conversion_type_params.base_metric\n        conversion_metric = conversion_type_params.conversion_metric\n        if base_measure is not None or conversion_measure is not None:\n            # v1 dependencies\n            assert base_measure is not None and conversion_measure is not None, (\n                f\"Conversion metric `{metric.name}` cannot have only one of base measure \"\n                + \"and conversion measure defined.\"\n            )\n            metric.add_input_measure(base_measure)\n            metric.add_input_measure(conversion_measure)\n            _process_metric_depends_on_semantic_models_for_measures(\n                manifest=manifest,\n                current_project=current_project,\n                metric=metric,\n            )\n        elif base_metric is not None or conversion_metric is not None:\n            # v2 dependencies\n            assert base_metric is not None and conversion_metric is not None, (\n                f\"Conversion metric `{metric.name}` cannot have only one of base metric \"\n                + \"and conversion metric defined.\"\n            )\n            _add_depends_on_metrics_to_v2_metric(\n                metric,\n                input_metrics=[base_metric, conversion_metric],\n                manifest=manifest,\n                current_project=current_project,\n            )\n        else:\n            raise dbt.exceptions.ParsingError(\n                f\"Depending the version of YAML being used, conversion metric `{metric.name}` \"\n                + \"must have base and conversion measures or base and conversion metrics defined.\",\n                node=metric,\n            )\n\n    elif metric.type is MetricType.DERIVED or metric.type is MetricType.RATIO:\n        input_metrics = metric.input_metrics\n        if metric.type is MetricType.RATIO:\n            if metric.type_params.numerator is None or metric.type_params.denominator is None:\n                raise dbt.exceptions.ParsingError(\n                    \"Invalid ratio metric. Both a numerator and denominator must be specified\",\n                    node=metric,\n                )\n            input_metrics = [metric.type_params.numerator, metric.type_params.denominator]\n\n        for input_metric in input_metrics:\n            target_metric = manifest.resolve_metric(\n                target_metric_name=input_metric.name,\n                target_metric_package=None,\n                current_project=current_project,\n                node_package=metric.package_name,\n            )\n            if target_metric is None:\n                raise dbt.exceptions.ParsingError(\n                    f\"The metric `{input_metric.name}` does not exist but was referenced by metric `{metric.name}`.\",\n                    node=metric,\n                )\n            elif isinstance(target_metric, Disabled):\n                raise dbt.exceptions.ParsingError(\n                    f\"The metric `{input_metric.name}` is disabled and thus cannot be referenced.\",\n                    node=metric,\n                )\n            _process_metric_node(\n                manifest=manifest, current_project=current_project, metric=target_metric\n            )\n            for input_measure in target_metric.type_params.input_measures:\n                metric.add_input_measure(input_measure)\n            metric.depends_on.add_node(target_metric.unique_id)\n    else:\n        assert_values_exhausted(metric.type)\n\n\ndef _process_metrics_for_node(\n    manifest: Manifest,\n    current_project: str,\n    node: Union[ManifestNode, Metric, Exposure, SavedQuery],\n):\n    \"\"\"Given a manifest and a node in that manifest, process its metrics\"\"\"\n\n    metrics: List[List[str]]\n    if isinstance(node, SeedNode):\n        return\n    elif isinstance(node, SavedQuery):\n        metrics = [[metric] for metric in node.metrics]\n    else:\n        metrics = node.metrics\n\n    for metric in metrics:\n        target_metric: Optional[Union[Disabled, Metric]] = None\n        target_metric_name: str\n        target_metric_package: Optional[str] = None\n\n        if len(metric) == 1:\n            target_metric_name = metric[0]\n        elif len(metric) == 2:\n            target_metric_package, target_metric_name = metric\n        else:\n            raise dbt.exceptions.DbtInternalError(\n                f\"Metric references should always be 1 or 2 arguments - got {len(metric)}\"\n            )\n\n        target_metric = manifest.resolve_metric(\n            target_metric_name,\n            target_metric_package,\n            current_project,\n            node.package_name,\n        )\n\n        if target_metric is None or isinstance(target_metric, Disabled):\n            # This may raise. Even if it doesn't, we don't want to add\n            # this node to the graph b/c there is no destination node\n            node.config.enabled = False\n            invalid_target_fail_unless_test(\n                node=node,\n                target_name=target_metric_name,\n                target_kind=\"metric\",\n                target_package=target_metric_package,\n                disabled=(isinstance(target_metric, Disabled)),\n            )\n            continue\n\n        target_metric_id = target_metric.unique_id\n\n        node.depends_on.add_node(target_metric_id)\n\n\ndef remove_dependent_project_references(manifest, external_node_unique_id):\n    for child_id in manifest.child_map[external_node_unique_id]:\n        node = manifest.expect(child_id)\n        # child node may have been modified and already recreated its depends_on.nodes list\n        if external_node_unique_id in node.depends_on_nodes:\n            node.depends_on_nodes.remove(external_node_unique_id)\n        node.created_at = time.time()\n\n\ndef _process_sources_for_exposure(manifest: Manifest, current_project: str, exposure: Exposure):\n    target_source: Optional[Union[Disabled, SourceDefinition]] = None\n    for source_name, table_name in exposure.sources:\n        target_source = manifest.resolve_source(\n            source_name,\n            table_name,\n            current_project,\n            exposure.package_name,\n        )\n        if target_source is None or isinstance(target_source, Disabled):\n            exposure.config.enabled = False\n            invalid_target_fail_unless_test(\n                node=exposure,\n                target_name=f\"{source_name}.{table_name}\",\n                target_kind=\"source\",\n                disabled=(isinstance(target_source, Disabled)),\n            )\n            continue\n        target_source_id = target_source.unique_id\n        exposure.depends_on.add_node(target_source_id)\n\n\ndef _process_sources_for_metric(manifest: Manifest, current_project: str, metric: Metric):\n    target_source: Optional[Union[Disabled, SourceDefinition]] = None\n    for source_name, table_name in metric.sources:\n        target_source = manifest.resolve_source(\n            source_name,\n            table_name,\n            current_project,\n            metric.package_name,\n        )\n        if target_source is None or isinstance(target_source, Disabled):\n            metric.config.enabled = False\n            invalid_target_fail_unless_test(\n                node=metric,\n                target_name=f\"{source_name}.{table_name}\",\n                target_kind=\"source\",\n                disabled=(isinstance(target_source, Disabled)),\n            )\n            continue\n        target_source_id = target_source.unique_id\n        metric.depends_on.add_node(target_source_id)\n\n\ndef _process_sources_for_node(manifest: Manifest, current_project: str, node: ManifestNode):\n    if isinstance(node, SeedNode):\n        return\n\n    target_source: Optional[Union[Disabled, SourceDefinition]] = None\n    for source_name, table_name in node.sources:\n        target_source = manifest.resolve_source(\n            source_name,\n            table_name,\n            current_project,\n            node.package_name,\n        )\n\n        if target_source is None or isinstance(target_source, Disabled):\n            # this follows the same pattern as refs\n            node.config.enabled = False\n            invalid_target_fail_unless_test(\n                node=node,\n                target_name=f\"{source_name}.{table_name}\",\n                target_kind=\"source\",\n                disabled=(isinstance(target_source, Disabled)),\n            )\n            continue\n        target_source_id = target_source.unique_id\n        node.depends_on.add_node(target_source_id)\n\n\ndef _process_functions_for_node(\n    manifest: Manifest, current_project: str, node: ManifestNode\n) -> None:\n    \"\"\"Given a manifest and node in that manifest, process its functions\"\"\"\n\n    if isinstance(node, SeedNode):\n        return\n\n    for function_args in node.functions:\n        target_function_name: str\n        target_function_package: Optional[str] = None\n        if len(function_args) == 1:\n            target_function_name = function_args[0]\n        elif len(function_args) == 2:\n            target_function_package, target_function_name = function_args\n        else:\n            raise dbt.exceptions.DbtInternalError(\n                f\"Functions should always be 1 or 2 arguments - got {len(function_args)}\"\n            )\n\n        target_function = manifest.resolve_function(\n            target_function_name,\n            target_function_package,\n            current_project,\n            node.package_name,\n        )\n\n        if target_function is None or isinstance(target_function, Disabled):\n            node.config.enabled = False\n            invalid_target_fail_unless_test(\n                node=node,\n                target_name=target_function_name,\n                target_kind=\"function\",\n                target_package=target_function_package,\n                disabled=(isinstance(target_function, Disabled)),\n                should_warn_if_disabled=False,\n            )\n\n            continue\n\n        node.depends_on.add_node(target_function.unique_id)\n\n\n# This is called in task.rpc.sql_commands when a \"dynamic\" node is\n# created in the manifest, in 'add_refs'\ndef process_macro(config: RuntimeConfig, manifest: Manifest, macro: Macro) -> None:\n    ctx = generate_runtime_docs_context(\n        config,\n        macro,\n        manifest,\n        config.project_name,\n    )\n    _process_docs_for_macro(ctx, macro)\n\n\n# This is called in task.rpc.sql_commands when a \"dynamic\" node is\n# created in the manifest, in 'add_refs'\ndef process_node(config: RuntimeConfig, manifest: Manifest, node: ManifestNode):\n    _process_sources_for_node(manifest, config.project_name, node)\n    _process_refs(manifest, config.project_name, node, config.dependencies)\n    ctx = generate_runtime_docs_context(config, node, manifest, config.project_name)\n    _process_docs_for_node(ctx, node, manifest)\n\n\ndef write_semantic_manifest(manifest: Manifest, target_path: str) -> None:\n    path = os.path.join(target_path, SEMANTIC_MANIFEST_FILE_NAME)\n    semantic_manifest = SemanticManifest(manifest)\n    semantic_manifest.write_json_to_file(path)\n\n\ndef write_manifest(manifest: Manifest, target_path: str, which: Optional[str] = None):\n    file_name = MANIFEST_FILE_NAME\n    path = os.path.join(target_path, file_name)\n    manifest.write(path)\n    add_artifact_produced(path)\n\n    write_semantic_manifest(manifest=manifest, target_path=target_path)\n\n\ndef parse_manifest(\n    runtime_config: RuntimeConfig,\n    write_perf_info: bool,\n    write: bool,\n    write_json: bool,\n    active_integrations: List[Optional[CatalogWriteIntegrationConfig]],\n) -> Manifest:\n    register_adapter(runtime_config, get_mp_context())\n    adapter = get_adapter(runtime_config)\n    adapter.set_macro_context_generator(generate_runtime_macro_context)\n    for integration in active_integrations:\n        adapter.add_catalog_integration(integration)\n    manifest = ManifestLoader.get_full_manifest(\n        runtime_config,\n        write_perf_info=write_perf_info,\n    )\n\n    # If we should (over)write the manifest in the target path, do that now\n    if write and write_json:\n        write_manifest(manifest, runtime_config.project_target_path)\n        pm = plugins.get_plugin_manager(runtime_config.project_name)\n        plugin_artifacts = pm.get_manifest_artifacts(manifest)\n        for path, plugin_artifact in plugin_artifacts.items():\n            plugin_artifact.write(path)\n            fire_event(\n                ArtifactWritten(\n                    artifact_type=plugin_artifact.__class__.__name__, artifact_path=path\n                )\n            )\n    return manifest\n"
  },
  {
    "path": "core/dbt/parser/models.py",
    "content": "# New for Python models :p\nimport ast\nimport random\nfrom copy import deepcopy\nfrom functools import reduce\nfrom itertools import chain\nfrom typing import Any, Dict, Iterator, List, Optional, Tuple, Union\n\nimport dbt.tracking as tracking\nfrom dbt import utils\nfrom dbt.artifacts.resources import RefArgs\nfrom dbt.clients.jinja import get_rendered\nfrom dbt.context.context_config import ContextConfig\nfrom dbt.contracts.graph.nodes import ModelNode\nfrom dbt.exceptions import (\n    ModelConfigError,\n    ParsingError,\n    PythonLiteralEvalError,\n    PythonParsingError,\n)\nfrom dbt.flags import get_flags\nfrom dbt.node_types import ModelLanguage, NodeType\nfrom dbt.parser.base import SimpleSQLParser\nfrom dbt.parser.search import FileBlock\nfrom dbt_common.contracts.config.base import merge_config_dicts\nfrom dbt_common.dataclass_schema import ValidationError\nfrom dbt_common.exceptions.macros import UndefinedMacroError\nfrom dbt_extractor import ExtractionError, py_extract_from_source  # type: ignore\n\ndbt_function_key_words = set([\"ref\", \"source\", \"config\", \"get\", \"meta_get\"])\ndbt_function_full_names = set(\n    [\"dbt.ref\", \"dbt.source\", \"dbt.config\", \"dbt.config.get\", \"dbt.config.meta_get\"]\n)\n\n\nclass PythonValidationVisitor(ast.NodeVisitor):\n    def __init__(self) -> None:\n        super().__init__()\n        self.dbt_errors: List[str] = []\n        self.num_model_def = 0\n\n    def visit_FunctionDef(self, node: ast.FunctionDef) -> None:\n        if node.name == \"model\":\n            self.num_model_def += 1\n            if node.args.args and not node.args.args[0].arg == \"dbt\":\n                self.dbt_errors.append(\"'dbt' not provided for model as the first argument\")\n            if len(node.args.args) != 2:\n                self.dbt_errors.append(\n                    \"model function should have two args, `dbt` and a session to current warehouse\"\n                )\n            # check we have a return and only one\n            if not isinstance(node.body[-1], ast.Return) or isinstance(\n                node.body[-1].value, ast.Tuple\n            ):\n                self.dbt_errors.append(\n                    \"In current version, model function should return only one dataframe object\"\n                )\n\n    def check_error(self, node):\n        if self.num_model_def != 1:\n            raise ParsingError(\n                f\"dbt allows exactly one model defined per python file, found {self.num_model_def}\",\n                node=node,\n            )\n\n        if len(self.dbt_errors) != 0:\n            raise ParsingError(\"\\n\".join(self.dbt_errors), node=node)\n\n\nclass PythonParseVisitor(ast.NodeVisitor):\n    def __init__(self, dbt_node):\n        super().__init__()\n\n        self.dbt_node = dbt_node\n        self.dbt_function_calls = []\n        self.packages = []\n\n    @classmethod\n    def _flatten_attr(cls, node):\n        if isinstance(node, ast.Attribute):\n            return str(cls._flatten_attr(node.value)) + \".\" + node.attr\n        elif isinstance(node, ast.Name):\n            return str(node.id)\n        else:\n            pass\n\n    def _safe_eval(self, node):\n        try:\n            return ast.literal_eval(node)\n        except (SyntaxError, ValueError, TypeError, MemoryError, RecursionError) as exc:\n            raise PythonLiteralEvalError(exc, node=self.dbt_node) from exc\n\n    def _get_call_literals(self, node):\n        # List of literals\n        arg_literals = []\n        kwarg_literals = {}\n\n        # TODO : Make sure this throws (and that we catch it)\n        # for non-literal inputs\n        for arg in node.args:\n            rendered = self._safe_eval(arg)\n            arg_literals.append(rendered)\n\n        for keyword in node.keywords:\n            key = keyword.arg\n            rendered = self._safe_eval(keyword.value)\n            kwarg_literals[key] = rendered\n\n        return arg_literals, kwarg_literals\n\n    def visit_Call(self, node: ast.Call) -> None:\n        # check weather the current call could be a dbt function call\n        if isinstance(node.func, ast.Attribute) and node.func.attr in dbt_function_key_words:\n            func_name = self._flatten_attr(node.func)\n            # check weather the current call really is a dbt function call\n            if func_name in dbt_function_full_names:\n                # drop the dot-dbt prefix\n                func_name = func_name.split(\".\")[-1]\n                args, kwargs = self._get_call_literals(node)\n                self.dbt_function_calls.append((func_name, args, kwargs))\n\n        # no matter what happened above, we should keep visiting the rest of the tree\n        # visit args and kwargs to see if there's call in it\n        for obj in node.args + [kwarg.value for kwarg in node.keywords]:\n            if isinstance(obj, ast.Call):\n                self.visit_Call(obj)\n            # support dbt.ref in list args, kwargs\n            elif isinstance(obj, ast.List) or isinstance(obj, ast.Tuple):\n                for el in obj.elts:\n                    if isinstance(el, ast.Call):\n                        self.visit_Call(el)\n            # support dbt.ref in dict args, kwargs\n            elif isinstance(obj, ast.Dict):\n                for value in obj.values:\n                    if isinstance(value, ast.Call):\n                        self.visit_Call(value)\n            # support dbt function calls in f-strings\n            elif isinstance(obj, ast.JoinedStr):\n                for value in obj.values:\n                    if isinstance(value, ast.FormattedValue) and isinstance(value.value, ast.Call):\n                        self.visit_Call(value.value)\n\n        # visit node.func.value if we are at an call attr\n        if isinstance(node.func, ast.Attribute):\n            self.attribute_helper(node.func)\n\n    def attribute_helper(self, node: ast.Attribute) -> None:\n        while isinstance(node, ast.Attribute):\n            node = node.value  # type: ignore\n        if isinstance(node, ast.Call):\n            self.visit_Call(node)\n\n    def visit_Import(self, node: ast.Import) -> None:\n        for n in node.names:\n            self.packages.append(n.name.split(\".\")[0])\n\n    def visit_ImportFrom(self, node: ast.ImportFrom) -> None:\n        if node.module:\n            self.packages.append(node.module.split(\".\")[0])\n\n\ndef verify_python_model_code(node):\n    # TODO: add a test for this\n    try:\n        rendered_python = get_rendered(\n            node.raw_code,\n            {},\n            node,\n        )\n        if rendered_python != node.raw_code:\n            raise ParsingError(\"\")\n    except (UndefinedMacroError, ParsingError):\n        raise ParsingError(\"No jinja in python model code is allowed\", node=node)\n\n\nclass ModelParser(SimpleSQLParser[ModelNode]):\n    def parse_from_dict(self, dct, validate=True) -> ModelNode:\n        if validate:\n            ModelNode.validate(dct)\n        return ModelNode.from_dict(dct)\n\n    @property\n    def resource_type(self) -> NodeType:\n        return NodeType.Model\n\n    @classmethod\n    def get_compiled_path(cls, block: FileBlock):\n        return block.path.relative_path\n\n    def parse_python_model(self, node, config, context):\n        config_keys_used = []\n        config_keys_defaults = []\n        meta_keys_used = []\n        meta_keys_defaults = []\n\n        try:\n            tree = ast.parse(node.raw_code, filename=node.original_file_path)\n        except SyntaxError as exc:\n            raise PythonParsingError(exc, node=node) from exc\n\n        # Only parse if AST tree has instructions in body\n        if tree.body:\n            # We are doing a validator and a parser because visit_FunctionDef in parser\n            # would actually make the parser not doing the visit_Calls any more\n            dbt_validator = PythonValidationVisitor()\n            dbt_validator.visit(tree)\n            dbt_validator.check_error(node)\n\n            dbt_parser = PythonParseVisitor(node)\n            dbt_parser.visit(tree)\n\n            for func, args, kwargs in dbt_parser.dbt_function_calls:\n                if func == \"get\":\n                    num_args = len(args)\n                    if num_args == 0:\n                        raise ParsingError(\n                            \"dbt.config.get() requires at least one argument\",\n                            node=node,\n                        )\n                    if num_args > 2:\n                        raise ParsingError(\n                            f\"dbt.config.get() takes at most 2 arguments ({num_args} given)\",\n                            node=node,\n                        )\n                    key = args[0]\n                    default_value = args[1] if num_args == 2 else None\n                    config_keys_used.append(key)\n                    config_keys_defaults.append(default_value)\n                    continue\n\n                if func == \"meta_get\":\n                    num_args = len(args)\n                    if num_args == 0:\n                        raise ParsingError(\n                            \"dbt.config.meta_get() requires at least one argument\",\n                            node=node,\n                        )\n                    if num_args > 2:\n                        raise ParsingError(\n                            f\"dbt.config.meta_get() takes at most 2 arguments ({num_args} given)\",\n                            node=node,\n                        )\n                    key = args[0]\n                    default_value = args[1] if num_args == 2 else None\n                    meta_keys_used.append(key)\n                    meta_keys_defaults.append(default_value)\n                    continue\n\n                context[func](*args, **kwargs)\n\n        if config_keys_used or meta_keys_used:\n            # this is being used in macro build_config_dict\n            context[\"config\"](\n                config_keys_used=config_keys_used,\n                config_keys_defaults=config_keys_defaults,\n                meta_keys_used=meta_keys_used,\n                meta_keys_defaults=meta_keys_defaults,\n            )\n\n    def render_update(\n        self, node: ModelNode, config: ContextConfig, validate_config_call_dict: bool = False\n    ) -> None:\n        self.manifest._parsing_info.static_analysis_path_count += 1\n        flags = get_flags()\n        if node.language == ModelLanguage.python:\n            try:\n                verify_python_model_code(node)\n                context = self._context_for(node, config)\n                self.parse_python_model(node, config, context)\n                self.update_parsed_node_config(\n                    node, config, context=context, validate_config_call_dict=True\n                )\n\n            except ValidationError as exc:\n                # we got a ValidationError - probably bad types in config()\n                raise ModelConfigError(exc, node=node) from exc\n            return\n\n        elif not flags.STATIC_PARSER:\n            # jinja rendering\n            super().render_update(node, config)\n            return\n\n        # only sample for experimental parser correctness on normal runs,\n        # not when the experimental parser flag is on.\n        exp_sample: bool = False\n        # sampling the stable static parser against jinja is significantly\n        # more expensive and therefore done far less frequently.\n        stable_sample: bool = False\n        # there are two samples above, and it is perfectly fine if both happen\n        # at the same time. If that happens, the experimental parser, stable\n        # parser, and jinja rendering will run on the same model file and\n        # send back codes for experimental v stable, and stable v jinja.\n        if not flags.USE_EXPERIMENTAL_PARSER:\n            # `True` roughly 1/5000 times this function is called\n            # sample = random.randint(1, 5001) == 5000\n            stable_sample = random.randint(1, 5001) == 5000\n            # sampling the experimental parser is explicitly disabled here, but use the following\n            # commented code to sample a fraction of the time when new\n            # experimental features are added.\n            # `True` roughly 1/100 times this function is called\n            # exp_sample = random.randint(1, 101) == 100\n\n        # top-level declaration of variables\n        statically_parsed: Optional[Union[str, Dict[str, List[Any]]]] = None\n        experimental_sample: Optional[Union[str, Dict[str, List[Any]]]] = None\n        exp_sample_node: Optional[ModelNode] = None\n        exp_sample_config: Optional[ContextConfig] = None\n        jinja_sample_node: Optional[ModelNode] = None\n        jinja_sample_config: Optional[ContextConfig] = None\n        result: List[str] = []\n\n        # sample the experimental parser only during a normal run\n        if exp_sample and not flags.USE_EXPERIMENTAL_PARSER:\n            experimental_sample = self.run_experimental_parser(node)\n            # if the experimental parser succeeded, make a full copy of model parser\n            # and populate _everything_ into it so it can be compared apples-to-apples\n            # with a fully jinja-rendered project. This is necessary because the experimental\n            # parser will likely add features that the existing static parser will fail on\n            # so comparing those directly would give us bad results. The comparison will be\n            # conducted after this model has been fully rendered either by the static parser\n            # or by full jinja rendering\n            if isinstance(experimental_sample, dict):\n                model_parser_copy = self.partial_deepcopy()\n                exp_sample_node = deepcopy(node)\n                exp_sample_config = deepcopy(config)\n                model_parser_copy.populate(exp_sample_node, exp_sample_config, experimental_sample)\n        # use the experimental parser exclusively if the flag is on\n        if flags.USE_EXPERIMENTAL_PARSER:\n            statically_parsed = self.run_experimental_parser(node)\n        # run the stable static parser unless it is explicitly turned off\n        else:\n            statically_parsed = self.run_static_parser(node)\n\n        # if the static parser succeeded, extract some data in easy-to-compare formats\n        if isinstance(statically_parsed, dict):\n            # only sample jinja for the purpose of comparing with the stable static parser\n            # if we know we don't need to fall back to jinja (i.e. - nothing to compare\n            # with jinja v jinja).\n            # This means we skip sampling for 40% of the 1/5000 samples. We could run the\n            # sampling rng here, but the effect would be the same since we would only roll\n            # it 40% of the time. So I've opted to keep all the rng code colocated above.\n            if stable_sample and not flags.USE_EXPERIMENTAL_PARSER:\n                # if this will _never_ mutate anything `self` we could avoid these deep copies,\n                # but we can't really guarantee that going forward.\n                model_parser_copy = self.partial_deepcopy()\n                jinja_sample_node = deepcopy(node)\n                jinja_sample_config = deepcopy(config)\n                # rendering mutates the node and the config\n                super(ModelParser, model_parser_copy).render_update(\n                    jinja_sample_node, jinja_sample_config\n                )\n\n            # update the unrendered config with values from the static parser.\n            # values from yaml files are in there already\n            self.populate(node, config, statically_parsed)\n\n            # if we took a jinja sample, compare now that the base node has been populated\n            if jinja_sample_node is not None and jinja_sample_config is not None:\n                result = _get_stable_sample_result(\n                    jinja_sample_node, jinja_sample_config, node, config\n                )\n\n            # if we took an experimental sample, compare now that the base node has been populated\n            if exp_sample_node is not None and exp_sample_config is not None:\n                result = _get_exp_sample_result(\n                    exp_sample_node,\n                    exp_sample_config,\n                    node,\n                    config,\n                )\n\n            self.manifest._parsing_info.static_analysis_parsed_path_count += 1\n        # if the static parser didn't succeed, fall back to jinja\n        else:\n            # jinja rendering\n            super().render_update(node, config, validate_config_call_dict=True)\n\n            # if sampling, add the correct messages for tracking\n            if exp_sample and isinstance(experimental_sample, str):\n                if experimental_sample == \"cannot_parse\":\n                    result += [\"01_experimental_parser_cannot_parse\"]\n                elif experimental_sample == \"has_banned_macro\":\n                    result += [\"08_has_banned_macro\"]\n            elif stable_sample and isinstance(statically_parsed, str):\n                if statically_parsed == \"cannot_parse\":\n                    result += [\"81_stable_parser_cannot_parse\"]\n                elif statically_parsed == \"has_banned_macro\":\n                    result += [\"88_has_banned_macro\"]\n\n        # only send the tracking event if there is at least one result code\n        if result:\n            # fire a tracking event. this fires one event for every sample\n            # so that we have data on a per file basis. Not only can we expect\n            # no false positives or misses, we can expect the number model\n            # files parseable by the experimental parser to match our internal\n            # testing.\n            if tracking.active_user is not None:  # None in some tests\n                tracking.track_experimental_parser_sample(\n                    {\n                        \"project_id\": self.root_project.hashed_name(),\n                        \"file_id\": utils.get_hash(node),\n                        \"status\": result,\n                    }\n                )\n\n    def run_static_parser(self, node: ModelNode) -> Optional[Union[str, Dict[str, List[Any]]]]:\n        # if any banned macros have been overridden by the user, we cannot use the static parser.\n        if self._has_banned_macro(node):\n            return \"has_banned_macro\"\n\n        # run the stable static parser and return the results\n        try:\n            statically_parsed = py_extract_from_source(node.raw_code)\n            return _shift_sources(statically_parsed)\n        # if we want information on what features are barring the static\n        # parser from reading model files, this is where we would add that\n        # since that information is stored in the `ExtractionError`.\n        except ExtractionError:\n            return \"cannot_parse\"\n\n    def run_experimental_parser(\n        self, node: ModelNode\n    ) -> Optional[Union[str, Dict[str, List[Any]]]]:\n        # if any banned macros have been overridden by the user, we cannot use the static parser.\n        if self._has_banned_macro(node):\n            return \"has_banned_macro\"\n\n        # run the experimental parser and return the results\n        try:\n            # for now, this line calls the stable static parser since there are no\n            # experimental features. Change `py_extract_from_source` to the new\n            # experimental call when we add additional features.\n            experimentally_parsed = py_extract_from_source(node.raw_code)\n            return _shift_sources(experimentally_parsed)\n        # if we want information on what features are barring the experimental\n        # parser from reading model files, this is where we would add that\n        # since that information is stored in the `ExtractionError`.\n        except ExtractionError:\n            return \"cannot_parse\"\n\n    # checks for banned macros\n    def _has_banned_macro(self, node: ModelNode) -> bool:\n        # first check if there is a banned macro defined in scope for this model file\n        root_project_name = self.root_project.project_name\n        project_name = node.package_name\n        banned_macros = [\"ref\", \"source\", \"config\"]\n\n        all_banned_macro_keys: Iterator[str] = chain.from_iterable(\n            map(\n                lambda name: [f\"macro.{project_name}.{name}\", f\"macro.{root_project_name}.{name}\"],\n                banned_macros,\n            )\n        )\n\n        return reduce(\n            lambda z, key: z or (key in self.manifest.macros), all_banned_macro_keys, False\n        )\n\n    # this method updates the model node rendered and unrendered config as well\n    # as the node object. Used to populate these values when circumventing jinja\n    # rendering like the static parser.\n    def populate(self, node: ModelNode, config: ContextConfig, statically_parsed: Dict[str, Any]):\n        # manually fit configs in\n        config._config_call_dict = _get_config_call_dict(statically_parsed)\n\n        # if there are hooks present this, it WILL render jinja. Will need to change\n        # when the experimental parser supports hooks\n        self.update_parsed_node_config(node, config, validate_config_call_dict=True)\n\n        # update the unrendered config with values from the file.\n        # values from yaml files are in there already\n        node.unrendered_config.update(dict(statically_parsed[\"configs\"]))\n\n        # set refs and sources on the node object\n        refs: List[RefArgs] = []\n        for ref in statically_parsed[\"refs\"]:\n            name = ref.get(\"name\")\n            package = ref.get(\"package\")\n            version = ref.get(\"version\")\n            refs.append(RefArgs(name, package, version))\n\n        node.refs += refs\n        node.sources += statically_parsed[\"sources\"]\n\n        # configs don't need to be merged into the node because they\n        # are read from config._config_call_dict\n\n    # the manifest is often huge so this method avoids deepcopying it\n    def partial_deepcopy(self):\n        return ModelParser(deepcopy(self.project), self.manifest, deepcopy(self.root_project))\n\n\n# pure function. safe to use elsewhere, but unlikely to be useful outside this file.\ndef _get_config_call_dict(static_parser_result: Dict[str, Any]) -> Dict[str, Any]:\n    config_call_dict: Dict[str, Any] = {}\n\n    for c in static_parser_result[\"configs\"]:\n        merge_config_dicts(config_call_dict, {c[0]: c[1]})\n\n    return config_call_dict\n\n\n# TODO if we format sources in the extractor to match this type, we won't need this function.\ndef _shift_sources(static_parser_result: Dict[str, List[Any]]) -> Dict[str, List[Any]]:\n    shifted_result = deepcopy(static_parser_result)\n    source_calls = []\n\n    for s in static_parser_result[\"sources\"]:\n        source_calls.append([s[0], s[1]])\n    shifted_result[\"sources\"] = source_calls\n\n    return shifted_result\n\n\n# returns a list of string codes to be sent as a tracking event\ndef _get_exp_sample_result(\n    sample_node: ModelNode,\n    sample_config: ContextConfig,\n    node: ModelNode,\n    config: ContextConfig,\n) -> List[str]:\n    result: List[Tuple[int, str]] = _get_sample_result(sample_node, sample_config, node, config)\n\n    def process(codemsg):\n        code, msg = codemsg\n        return f\"0{code}_experimental_{msg}\"\n\n    return list(map(process, result))\n\n\n# returns a list of string codes to be sent as a tracking event\ndef _get_stable_sample_result(\n    sample_node: ModelNode,\n    sample_config: ContextConfig,\n    node: ModelNode,\n    config: ContextConfig,\n) -> List[str]:\n    result: List[Tuple[int, str]] = _get_sample_result(sample_node, sample_config, node, config)\n\n    def process(codemsg):\n        code, msg = codemsg\n        return f\"8{code}_stable_{msg}\"\n\n    return list(map(process, result))\n\n\n# returns a list of string codes that need a single digit prefix to be prepended\n# before being sent as a tracking event\ndef _get_sample_result(\n    sample_node: ModelNode,\n    sample_config: ContextConfig,\n    node: ModelNode,\n    config: ContextConfig,\n) -> List[Tuple[int, str]]:\n    result: List[Tuple[int, str]] = []\n    # look for false positive configs\n    for k in sample_config._config_call_dict.keys():\n        if k not in config._config_call_dict.keys():\n            result += [(2, \"false_positive_config_value\")]\n            break\n\n    # look for missed configs\n    for k in config._config_call_dict.keys():\n        if k not in sample_config._config_call_dict.keys():\n            result += [(3, \"missed_config_value\")]\n            break\n\n    # look for false positive sources\n    for s in sample_node.sources:\n        if s not in node.sources:\n            result += [(4, \"false_positive_source_value\")]\n            break\n\n    # look for missed sources\n    for s in node.sources:\n        if s not in sample_node.sources:\n            result += [(5, \"missed_source_value\")]\n            break\n\n    # look for false positive refs\n    for r in sample_node.refs:\n        if r not in node.refs:\n            result += [(6, \"false_positive_ref_value\")]\n            break\n\n    # look for missed refs\n    for r in node.refs:\n        if r not in sample_node.refs:\n            result += [(7, \"missed_ref_value\")]\n            break\n\n    # if there are no errors, return a success value\n    if not result:\n        result = [(0, \"exact_match\")]\n\n    return result\n"
  },
  {
    "path": "core/dbt/parser/partial.py",
    "content": "import os\nfrom copy import deepcopy\nfrom typing import Callable, Dict, List, MutableMapping, Union\n\nfrom dbt.constants import DEFAULT_ENV_PLACEHOLDER\nfrom dbt.contracts.files import (\n    AnySourceFile,\n    ParseFileType,\n    SchemaSourceFile,\n    SourceFile,\n    parse_file_type_to_parser,\n)\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.contracts.graph.nodes import (\n    AnalysisNode,\n    GenericTestNode,\n    ModelNode,\n    SeedNode,\n    SnapshotNode,\n)\nfrom dbt.events.types import PartialParsingEnabled, PartialParsingFile\nfrom dbt.node_types import NodeType\nfrom dbt_common.context import get_invocation_context\nfrom dbt_common.events.base_types import EventLevel\nfrom dbt_common.events.functions import fire_event\n\nmssat_files = (\n    ParseFileType.Model,\n    ParseFileType.Seed,\n    ParseFileType.Snapshot,\n    ParseFileType.Analysis,\n    ParseFileType.SingularTest,\n)\n\nmg_files = (\n    ParseFileType.Macro,\n    ParseFileType.GenericTest,\n)\n\n\nkey_to_prefix = {\n    \"models\": \"model\",\n    \"seeds\": \"seed\",\n    \"snapshots\": \"snapshot\",\n    \"analyses\": \"analysis\",\n    \"sources\": \"source\",\n}\n\n\nparse_file_type_to_key = {\n    ParseFileType.Model: \"models\",\n    ParseFileType.Seed: \"seeds\",\n    ParseFileType.Snapshot: \"snapshots\",\n    ParseFileType.Analysis: \"analyses\",\n}\n\n\n# These macro names have special treatment in the ManifestLoader and\n# partial parsing. If they have changed we will skip partial parsing\nspecial_override_macros = [\n    \"ref\",\n    \"source\",\n    \"config\",\n    \"generate_schema_name\",\n    \"generate_database_name\",\n    \"generate_alias_name\",\n    \"function\",\n]\n\n\n# Partial parsing. Create a diff of files from saved manifest and current\n# files and produce a project_parser_file dictionary to drive parsing of\n# only the necessary changes.\n# Will produce a 'skip_parsing' method, and a project_parser_file dictionary\n# All file objects from the new manifest are deepcopied, because we need\n# to preserve an unchanged file object in case we need to drop back to a\n# a full parse (such as for certain macro changes)\nclass PartialParsing:\n    def __init__(\n        self, saved_manifest: Manifest, new_files: MutableMapping[str, AnySourceFile]\n    ) -> None:\n        self.saved_manifest = saved_manifest\n        self.new_files = new_files\n        self.project_parser_files: Dict = {}\n        self.saved_files = self.saved_manifest.files\n        self.project_parser_files = {}\n        self.macro_child_map: Dict[str, List[str]] = {}\n        (\n            self.env_vars_changed_source_files,\n            self.env_vars_changed_schema_files,\n        ) = self.build_env_vars_to_files()\n        self.build_file_diff()\n        self.processing_file = None\n        self.deleted_special_override_macro = False\n        self.disabled_by_file_id = self.saved_manifest.build_disabled_by_file_id()\n\n    def skip_parsing(self):\n        return (\n            not self.file_diff[\"deleted\"]\n            and not self.file_diff[\"added\"]\n            and not self.file_diff[\"changed\"]\n            and not self.file_diff[\"changed_schema_files\"]\n            and not self.file_diff[\"deleted_schema_files\"]\n        )\n\n    # Compare the previously saved manifest files and the just-loaded manifest\n    # files to see if anything changed\n    def build_file_diff(self):\n        saved_file_ids = set(self.saved_files.keys())\n        new_file_ids = set(self.new_files.keys())\n        deleted_all_files = saved_file_ids.difference(new_file_ids)\n        added = new_file_ids.difference(saved_file_ids)\n        common = saved_file_ids.intersection(new_file_ids)\n        changed_or_deleted_macro_file = False\n\n        # separate out deleted schema files\n        deleted_schema_files = []\n        deleted = []\n        for file_id in deleted_all_files:\n            if self.saved_files[file_id].parse_file_type == ParseFileType.Schema:\n                deleted_schema_files.append(file_id)\n            else:\n                if self.saved_files[file_id].parse_file_type in mg_files:\n                    changed_or_deleted_macro_file = True\n                deleted.append(file_id)\n\n        changed = []\n        changed_schema_files = []\n        unchanged = []\n        for file_id in common:\n            if self.saved_files[file_id].checksum == self.new_files[file_id].checksum:\n                unchanged.append(file_id)\n            else:\n                # separate out changed schema files\n                if self.saved_files[file_id].parse_file_type == ParseFileType.Schema:\n                    sf = self.saved_files[file_id]\n                    if type(sf).__name__ != \"SchemaSourceFile\":\n                        raise Exception(f\"Serialization failure for {file_id}\")\n                    changed_schema_files.append(file_id)\n                else:\n                    if self.saved_files[file_id].parse_file_type in mg_files:\n                        changed_or_deleted_macro_file = True\n                    changed.append(file_id)\n\n        # handle changed env_vars for non-schema-files\n        for file_id in self.env_vars_changed_source_files:\n            if file_id in deleted or file_id in changed:\n                continue\n            changed.append(file_id)\n\n        # handle changed env_vars for schema files\n        for file_id in self.env_vars_changed_schema_files.keys():\n            if file_id in deleted_schema_files or file_id in changed_schema_files:\n                continue\n            changed_schema_files.append(file_id)\n\n        file_diff = {\n            \"deleted\": deleted,\n            \"deleted_schema_files\": deleted_schema_files,\n            \"added\": added,\n            \"changed\": changed,\n            \"changed_schema_files\": changed_schema_files,\n            \"unchanged\": unchanged,\n        }\n        if changed_or_deleted_macro_file:\n            self.macro_child_map = self.saved_manifest.build_macro_child_map()\n        deleted = len(deleted) + len(deleted_schema_files)\n        changed = len(changed) + len(changed_schema_files)\n        event = PartialParsingEnabled(deleted=deleted, added=len(added), changed=changed)\n\n        if get_invocation_context().env.get(\"DBT_PP_TEST\"):\n            fire_event(event, level=EventLevel.INFO)\n        else:\n            fire_event(event)\n        self.file_diff = file_diff\n\n    # generate the list of files that need parsing\n    # uses self.manifest.files generated by 'read_files'\n    def get_parsing_files(self):\n        if self.skip_parsing():\n            return {}\n        # Need to add new files first, because changes in schema files\n        # might refer to them\n        for file_id in self.file_diff[\"added\"]:\n            self.processing_file = file_id\n            self.add_to_saved(file_id)\n        # Need to process schema files next, because the dictionaries\n        # need to be in place for handling SQL file changes\n        # The reverse sort here is just to ensure that the schema file\n        # processing order test case works, because otherwise the order\n        # of processing the schema files is not guaranteed.\n        self.file_diff[\"changed_schema_files\"].sort(reverse=True)\n        for file_id in self.file_diff[\"changed_schema_files\"]:\n            self.processing_file = file_id\n            self.change_schema_file(file_id)\n        for file_id in self.file_diff[\"deleted_schema_files\"]:\n            self.processing_file = file_id\n            self.delete_schema_file(file_id)\n        for file_id in self.file_diff[\"deleted\"]:\n            self.processing_file = file_id\n            self.delete_from_saved(file_id)\n        for file_id in self.file_diff[\"changed\"]:\n            self.processing_file = file_id\n            self.update_in_saved(file_id)\n        return self.project_parser_files\n\n    # Add the file to the project parser dictionaries to schedule parsing\n    def add_to_pp_files(self, source_file):\n        file_id = source_file.file_id\n        parser_name = parse_file_type_to_parser[source_file.parse_file_type]\n        project_name = source_file.project_name\n        if not parser_name or not project_name:\n            raise Exception(\n                f\"Did not find parse_file_type or project_name \"\n                f\"in SourceFile for {source_file.file_id}\"\n            )\n        if project_name not in self.project_parser_files:\n            self.project_parser_files[project_name] = {}\n        if parser_name not in self.project_parser_files[project_name]:\n            self.project_parser_files[project_name][parser_name] = []\n        if (\n            file_id not in self.project_parser_files[project_name][parser_name]\n            and file_id not in self.file_diff[\"deleted\"]\n            and file_id not in self.file_diff[\"deleted_schema_files\"]\n        ):\n            self.project_parser_files[project_name][parser_name].append(file_id)\n\n    def already_scheduled_for_parsing(self, source_file):\n        file_id = source_file.file_id\n        project_name = source_file.project_name\n        if project_name not in self.project_parser_files:\n            return False\n        parser_name = parse_file_type_to_parser[source_file.parse_file_type]\n        if parser_name not in self.project_parser_files[project_name]:\n            return False\n        if file_id not in self.project_parser_files[project_name][parser_name]:\n            return False\n        return True\n\n    # Add new files, including schema files\n    def add_to_saved(self, file_id):\n        # add file object to saved manifest.files\n        source_file = deepcopy(self.new_files[file_id])\n        if source_file.parse_file_type == ParseFileType.Schema:\n            self.handle_added_schema_file(source_file)\n        self.saved_files[file_id] = source_file\n        # update pp_files to parse\n        self.add_to_pp_files(source_file)\n        fire_event(PartialParsingFile(operation=\"added\", file_id=file_id))\n\n    def handle_added_schema_file(self, source_file):\n        source_file.pp_dict = source_file.dict_from_yaml.copy()\n        if \"sources\" in source_file.pp_dict:\n            for source in source_file.pp_dict[\"sources\"]:\n                # We need to remove the original source, so it can\n                # be properly patched\n                if \"overrides\" in source:\n                    self.remove_source_override_target(source)\n        if \"models\" in source_file.pp_dict:\n            for model in source_file.pp_dict[\"models\"]:\n                if \"versions\" in model:\n                    self.versioned_model_delete_schema_mssa_links(source_file, \"models\", model)\n\n    def delete_disabled(self, unique_id, file_id):\n        # This node/metric/exposure is disabled. Find it and remove it from disabled dictionary.\n        for dis_index, dis_node in enumerate(self.saved_manifest.disabled[unique_id]):\n            if dis_node.file_id == file_id:\n                node = dis_node\n                index = dis_index\n                break\n        # Remove node from disabled\n        del self.saved_manifest.disabled[unique_id][index]\n        # if all nodes were removed for the unique id, delete the unique_id\n        # from the disabled dict\n        if not self.saved_manifest.disabled[unique_id]:\n            self.saved_manifest.disabled.pop(unique_id)\n\n        return node\n\n    # Deletes for all non-schema files\n    def delete_from_saved(self, file_id):\n        # Look at all things touched by file, remove those\n        # nodes, and update pp_files to parse unless the\n        # file creating those nodes has also been deleted\n        saved_source_file = self.saved_files[file_id]\n\n        # SQL file: models, seeds, snapshots, analyses, tests: SQL files, except\n        # macros/tests\n        if saved_source_file.parse_file_type in mssat_files:\n            self.remove_mssat_file(saved_source_file)\n            self.saved_manifest.files.pop(file_id)\n\n        # macros\n        if saved_source_file.parse_file_type in mg_files:\n            self.delete_macro_file(saved_source_file, follow_references=True)\n\n        # docs\n        if saved_source_file.parse_file_type == ParseFileType.Documentation:\n            self.delete_doc_node(saved_source_file)\n\n        # fixtures\n        if saved_source_file.parse_file_type == ParseFileType.Fixture:\n            self.delete_fixture_node(saved_source_file)\n\n        # functions\n        if saved_source_file.parse_file_type == ParseFileType.Function:\n            self.delete_function_node(saved_source_file)\n\n        fire_event(PartialParsingFile(operation=\"deleted\", file_id=file_id))\n\n    # Updates for non-schema files\n    def update_in_saved(self, file_id):\n        new_source_file = deepcopy(self.new_files[file_id])\n        old_source_file = self.saved_files[file_id]\n\n        if new_source_file.parse_file_type in mssat_files:\n            self.update_mssat_in_saved(new_source_file, old_source_file)\n        elif new_source_file.parse_file_type in mg_files:\n            self.update_macro_in_saved(new_source_file, old_source_file)\n        elif new_source_file.parse_file_type == ParseFileType.Documentation:\n            self.update_doc_in_saved(new_source_file, old_source_file)\n        elif new_source_file.parse_file_type == ParseFileType.Fixture:\n            self.update_fixture_in_saved(new_source_file, old_source_file)\n        elif new_source_file.parse_file_type == ParseFileType.Function:\n            self.update_function_in_saved(new_source_file, old_source_file)\n        else:\n            raise Exception(f\"Invalid parse_file_type in source_file {file_id}\")\n        fire_event(PartialParsingFile(operation=\"updated\", file_id=file_id))\n\n    # Models, seeds, snapshots: patches and tests\n    # analyses: patches, no tests\n    # tests: not touched by schema files (no patches, no tests)\n    # Updated schema files should have been processed already.\n    def update_mssat_in_saved(self, new_source_file, old_source_file):\n\n        if self.already_scheduled_for_parsing(old_source_file):\n            return\n\n        # These files only have one node except for snapshots\n        unique_ids = []\n        if old_source_file.nodes:\n            unique_ids = old_source_file.nodes\n\n        # replace source_file in saved and add to parsing list\n        file_id = new_source_file.file_id\n        self.saved_files[file_id] = deepcopy(new_source_file)\n        self.add_to_pp_files(new_source_file)\n        for unique_id in unique_ids:\n            self.remove_node_in_saved(new_source_file, unique_id)\n\n    def remove_node_in_saved(self, source_file, unique_id):\n        if unique_id in self.saved_manifest.nodes:\n            # delete node in saved\n            node = self.saved_manifest.nodes.pop(unique_id)\n        elif (\n            source_file.file_id in self.disabled_by_file_id\n            and unique_id in self.saved_manifest.disabled\n        ):\n            # This node is disabled. Find the node and remove it from disabled dictionary.\n            node = self.delete_disabled(unique_id, source_file.file_id)\n        else:\n            # Has already been deleted by another action\n            return\n\n        # look at patch_path in model node to see if we need\n        # to reapply a patch from a schema_file.\n        if node.patch_path:\n            file_id = node.patch_path\n            # it might be changed...  then what?\n            if (\n                file_id not in self.file_diff[\"deleted\"]\n                and file_id in self.saved_files\n                and source_file.parse_file_type in parse_file_type_to_key\n            ):\n                # Schema files should already be updated if this comes from a node,\n                # but this code is also called when updating groups and exposures.\n                # This might save the old schema file element, so when the schema file\n                # is processed, it should overwrite it by passing True to \"merge_patch\"\n                schema_file = self.saved_files[file_id]\n                dict_key = parse_file_type_to_key[source_file.parse_file_type]\n                # look for a matching list dictionary\n                elem_patch = None\n                if dict_key in schema_file.dict_from_yaml:\n                    for elem in schema_file.dict_from_yaml[dict_key]:\n                        if elem[\"name\"] == node.name:\n                            elem_patch = elem\n                            break\n                if elem_patch:\n                    self.delete_schema_mssa_links(schema_file, dict_key, elem_patch)\n                    self.merge_patch(schema_file, dict_key, elem_patch)\n                    if unique_id in schema_file.node_patches:\n                        schema_file.node_patches.remove(unique_id)\n            if unique_id in self.saved_manifest.disabled:\n                # We have a patch_path in disabled nodes with a patch so\n                # that we can connect the patch to the node\n                for node in self.saved_manifest.disabled[unique_id]:\n                    node.patch_path = None\n\n    def update_macro_in_saved(self, new_source_file, old_source_file):\n        if self.already_scheduled_for_parsing(old_source_file):\n            return\n        self.handle_macro_file_links(old_source_file, follow_references=True)\n        file_id = new_source_file.file_id\n        self.saved_files[file_id] = deepcopy(new_source_file)\n        self.add_to_pp_files(new_source_file)\n\n    def update_doc_in_saved(self, new_source_file, old_source_file):\n        if self.already_scheduled_for_parsing(old_source_file):\n            return\n        self.delete_doc_node(old_source_file)\n        self.saved_files[new_source_file.file_id] = deepcopy(new_source_file)\n        self.add_to_pp_files(new_source_file)\n\n    def update_fixture_in_saved(self, new_source_file, old_source_file):\n        if self.already_scheduled_for_parsing(old_source_file):\n            return\n        self.delete_fixture_node(old_source_file)\n        self.saved_files[new_source_file.file_id] = deepcopy(new_source_file)\n        self.add_to_pp_files(new_source_file)\n\n    def update_function_in_saved(\n        self, new_source_file: SourceFile, old_source_file: SourceFile\n    ) -> None:\n        if self.already_scheduled_for_parsing(old_source_file):\n            return\n        self.delete_function_node(old_source_file)\n        self.saved_files[new_source_file.file_id] = deepcopy(new_source_file)\n        self.add_to_pp_files(new_source_file)\n\n    def remove_mssat_file(self, source_file: AnySourceFile):\n        # nodes [unique_ids] -- SQL files\n        # There should always be a node for a SQL file\n        if not isinstance(source_file, SourceFile) or not source_file.nodes:\n            return\n        # There is generally only 1 node for SQL files, except for macros and snapshots\n        for unique_id in source_file.nodes:\n            self.remove_node_in_saved(source_file, unique_id)\n            self.schedule_referencing_nodes_for_parsing(unique_id)\n\n    # We need to re-parse nodes that reference another removed node\n    def schedule_referencing_nodes_for_parsing(self, unique_id):\n        # Look at \"children\", i.e. nodes that reference this node\n        if unique_id in self.saved_manifest.child_map:\n            self.schedule_nodes_for_parsing(self.saved_manifest.child_map[unique_id])\n\n    def schedule_nodes_for_parsing(self, unique_ids):\n        for unique_id in unique_ids:\n            if unique_id in self.saved_manifest.nodes:\n                node = self.saved_manifest.nodes[unique_id]\n                if node.resource_type == NodeType.Test and node.test_node_type == \"generic\":\n                    # test nodes are handled separately. Must be removed from schema file\n                    continue\n                file_id = node.file_id\n                if file_id in self.saved_files and file_id not in self.file_diff[\"deleted\"]:\n                    source_file = self.saved_files[file_id]\n                    self.remove_mssat_file(source_file)\n                    # content of non-schema files is only in new files\n                    self.saved_files[file_id] = deepcopy(self.new_files[file_id])\n                    self.add_to_pp_files(self.saved_files[file_id])\n            elif unique_id in self.saved_manifest.sources:\n                source = self.saved_manifest.sources[unique_id]\n                self._schedule_for_parsing(\n                    \"sources\", source, source.source_name, self.delete_schema_source\n                )\n            elif unique_id in self.saved_manifest.exposures:\n                exposure = self.saved_manifest.exposures[unique_id]\n                self._schedule_for_parsing(\n                    \"exposures\", exposure, exposure.name, self.delete_schema_exposure\n                )\n            elif unique_id in self.saved_manifest.metrics:\n                metric = self.saved_manifest.metrics[unique_id]\n                self._schedule_for_parsing(\n                    \"metrics\", metric, metric.name, self.delete_schema_metric\n                )\n            elif unique_id in self.saved_manifest.semantic_models:\n                semantic_model = self.saved_manifest.semantic_models[unique_id]\n                self._schedule_for_parsing(\n                    \"semantic_models\",\n                    semantic_model,\n                    semantic_model.name,\n                    self.delete_schema_semantic_model,\n                )\n            elif unique_id in self.saved_manifest.saved_queries:\n                saved_query = self.saved_manifest.saved_queries[unique_id]\n                self._schedule_for_parsing(\n                    \"saved_queries\", saved_query, saved_query.name, self.delete_schema_saved_query\n                )\n            elif unique_id in self.saved_manifest.macros:\n                macro = self.saved_manifest.macros[unique_id]\n                file_id = macro.file_id\n                if file_id in self.saved_files and file_id not in self.file_diff[\"deleted\"]:\n                    source_file = self.saved_files[file_id]\n                    self.delete_macro_file(source_file)\n                    self.saved_files[file_id] = deepcopy(self.new_files[file_id])\n                    self.add_to_pp_files(self.saved_files[file_id])\n            elif unique_id in self.saved_manifest.unit_tests:\n                unit_test = self.saved_manifest.unit_tests[unique_id]\n                self._schedule_for_parsing(\n                    \"unit_tests\", unit_test, unit_test.name, self.delete_schema_unit_test\n                )\n\n    def _schedule_for_parsing(self, dict_key: str, element, name, delete: Callable) -> None:\n        file_id = element.file_id\n        if (\n            file_id in self.saved_files\n            and file_id not in self.file_diff[\"deleted\"]\n            and file_id not in self.file_diff[\"deleted_schema_files\"]\n        ):\n            schema_file = self.saved_files[file_id]\n            elements = []\n            assert isinstance(schema_file, SchemaSourceFile)\n            if dict_key in schema_file.dict_from_yaml:\n                elements = schema_file.dict_from_yaml[dict_key]\n            schema_element = self.get_schema_element(elements, name)\n            if schema_element:\n                delete(schema_file, schema_element)\n                self.merge_patch(schema_file, dict_key, schema_element)\n\n    def delete_macro_file(self, source_file, follow_references=False):\n        self.check_for_special_deleted_macros(source_file)\n        self.handle_macro_file_links(source_file, follow_references)\n        file_id = source_file.file_id\n        # It's not clear when this file_id would not exist in saved_files\n        if file_id in self.saved_files:\n            self.saved_files.pop(file_id)\n\n    def check_for_special_deleted_macros(self, source_file):\n        for unique_id in source_file.macros:\n            if unique_id in self.saved_manifest.macros:\n                package_name = unique_id.split(\".\")[1]\n                if package_name == \"dbt\":\n                    continue\n                macro = self.saved_manifest.macros[unique_id]\n                if macro.name in special_override_macros:\n                    self.deleted_special_override_macro = True\n\n    def recursively_gather_macro_references(self, macro_unique_id, referencing_nodes):\n        for unique_id in self.macro_child_map[macro_unique_id]:\n            if unique_id in referencing_nodes:\n                continue\n            referencing_nodes.append(unique_id)\n            if unique_id.startswith(\"macro.\"):\n                self.recursively_gather_macro_references(unique_id, referencing_nodes)\n\n    def handle_macro_file_links(self, source_file, follow_references=False):\n        # remove the macros in the 'macros' dictionary\n        macros = source_file.macros.copy()\n        for unique_id in macros:\n            if unique_id not in self.saved_manifest.macros:\n                # This happens when a macro has already been removed\n                if unique_id in source_file.macros:\n                    source_file.macros.remove(unique_id)\n                continue\n\n            base_macro = self.saved_manifest.macros.pop(unique_id)\n\n            # Recursively check children of this macro\n            # The macro_child_map might not exist if a macro is removed by\n            # schedule_nodes_for parsing. We only want to follow\n            # references if the macro file itself has been updated or\n            # deleted, not if we're just updating referenced nodes.\n            if self.macro_child_map and follow_references:\n                referencing_nodes = []\n                self.recursively_gather_macro_references(unique_id, referencing_nodes)\n                self.schedule_macro_nodes_for_parsing(referencing_nodes)\n\n            if base_macro.patch_path:\n                file_id = base_macro.patch_path\n                if file_id in self.saved_files:\n                    schema_file = self.saved_files[file_id]\n                    macro_patches = []\n                    if \"macros\" in schema_file.dict_from_yaml:\n                        macro_patches = schema_file.dict_from_yaml[\"macros\"]\n                    macro_patch = self.get_schema_element(macro_patches, base_macro.name)\n                    self.delete_schema_macro_patch(schema_file, macro_patch)\n                    self.merge_patch(schema_file, \"macros\", macro_patch)\n            # The macro may have already been removed by handling macro children\n            if unique_id in source_file.macros:\n                source_file.macros.remove(unique_id)\n\n    # similar to schedule_nodes_for_parsing but doesn't do sources and exposures\n    # and handles schema tests\n    def schedule_macro_nodes_for_parsing(self, unique_ids):\n        for unique_id in unique_ids:\n            if unique_id in self.saved_manifest.nodes:\n                node = self.saved_manifest.nodes[unique_id]\n                # Both generic tests from yaml files and singular tests have NodeType.Test\n                # so check for generic test.\n                if node.resource_type == NodeType.Test and node.test_node_type == \"generic\":\n                    schema_file_id = node.file_id\n                    schema_file = self.saved_manifest.files[schema_file_id]\n                    (key, name) = schema_file.get_key_and_name_for_test(node.unique_id)\n                    if key and name:\n                        patch_list = []\n                        if key in schema_file.dict_from_yaml:\n                            patch_list = schema_file.dict_from_yaml[key]\n                        patch = self.get_schema_element(patch_list, name)\n                        if patch:\n                            if key in [\"models\", \"seeds\", \"snapshots\"]:\n                                self.delete_schema_mssa_links(schema_file, key, patch)\n                                self.merge_patch(schema_file, key, patch)\n                                if unique_id in schema_file.node_patches:\n                                    schema_file.node_patches.remove(unique_id)\n                            elif key == \"sources\":\n                                # re-schedule source\n                                if \"overrides\" in patch:\n                                    # This is a source patch; need to re-parse orig source\n                                    self.remove_source_override_target(patch)\n                                self.delete_schema_source(schema_file, patch)\n                                self.merge_patch(schema_file, \"sources\", patch)\n                else:\n                    file_id = node.file_id\n                    if file_id in self.saved_files and file_id not in self.file_diff[\"deleted\"]:\n                        source_file = self.saved_files[file_id]\n                        self.remove_mssat_file(source_file)\n                        # content of non-schema files is only in new files\n                        self.saved_files[file_id] = deepcopy(self.new_files[file_id])\n                        self.add_to_pp_files(self.saved_files[file_id])\n            elif unique_id in self.saved_manifest.macros:\n                macro = self.saved_manifest.macros[unique_id]\n                file_id = macro.file_id\n                if file_id in self.saved_files and file_id not in self.file_diff[\"deleted\"]:\n                    source_file = self.saved_files[file_id]\n                    self.delete_macro_file(source_file)\n                    self.saved_files[file_id] = deepcopy(self.new_files[file_id])\n                    self.add_to_pp_files(self.saved_files[file_id])\n\n    def delete_doc_node(self, source_file):\n        # remove the nodes in the 'docs' dictionary\n        docs = source_file.docs.copy()\n        for unique_id in docs:\n            self.saved_manifest.docs.pop(unique_id)\n            source_file.docs.remove(unique_id)\n        # The unique_id of objects that contain a doc call are stored in the\n        # doc source_file.nodes\n        self.schedule_nodes_for_parsing(source_file.nodes)\n        source_file.nodes = []\n        # Remove the file object\n        self.saved_manifest.files.pop(source_file.file_id)\n\n    def delete_fixture_node(self, source_file):\n        # remove fixtures from the \"fixtures\" dictionary\n        fixture_unique_id = source_file.fixture\n        self.saved_manifest.fixtures.pop(fixture_unique_id)\n        unit_tests = source_file.unit_tests.copy()\n        for unique_id in unit_tests:\n            unit_test = self.saved_manifest.unit_tests.pop(unique_id)\n            # schedule unit_test for parsing\n            self._schedule_for_parsing(\n                \"unit_tests\", unit_test, unit_test.name, self.delete_schema_unit_test\n            )\n            source_file.unit_tests.remove(unique_id)\n        self.saved_manifest.files.pop(source_file.file_id)\n\n    def delete_function_node(self, source_file: SourceFile) -> None:\n        # There should always be a node for a Function file\n        if not isinstance(source_file, SourceFile) or not source_file.functions:\n            return\n\n        # There can only be one node of a function\n        function_unique_id = source_file.functions[0]\n\n        # Remove the function node from the saved manifest\n        function_node = self.saved_manifest.functions.pop(function_unique_id)\n\n        # Remove the function node from the source file so that it's not viewed as a\n        # duplicate when it's re-added\n        source_file.functions.remove(function_unique_id)\n\n        # If this function had a schema patch, schedule that schema element to be reapplied.\n        patch_path = function_node.patch_path\n        if (\n            patch_path is not None\n            and patch_path in self.saved_files\n            and patch_path not in self.file_diff[\"deleted_schema_files\"]\n        ):\n            schema_file = self.saved_files[patch_path]\n            # Only proceed if this is a schema file\n            if isinstance(schema_file, SchemaSourceFile):\n                elements = schema_file.dict_from_yaml.get(\"functions\", [])\n                schema_element = self.get_schema_element(elements, function_node.name)\n                if schema_element:\n                    # Remove any previous links and re-merge the patch to pp_dict so it gets reparsed\n                    self.delete_schema_function(schema_file, schema_element)\n                    self.merge_patch(schema_file, \"functions\", schema_element)\n\n        # Finally, remove the deleted function file from saved files\n        if source_file.file_id in self.saved_manifest.files:\n            self.saved_manifest.files.pop(source_file.file_id)\n\n    # Schema files -----------------------\n    # Changed schema files\n    def change_schema_file(self, file_id):\n        saved_schema_file = self.saved_files[file_id]\n        new_schema_file = deepcopy(self.new_files[file_id])\n        saved_yaml_dict = saved_schema_file.dict_from_yaml\n        new_yaml_dict = new_schema_file.dict_from_yaml\n        if saved_schema_file.pp_dict is None:\n            saved_schema_file.pp_dict = {}\n        self.handle_schema_file_changes(saved_schema_file, saved_yaml_dict, new_yaml_dict)\n\n        # copy from new schema_file to saved_schema_file to preserve references\n        # that weren't removed\n        saved_schema_file.contents = new_schema_file.contents\n        saved_schema_file.checksum = new_schema_file.checksum\n        saved_schema_file.dfy = new_schema_file.dfy\n        # schedule parsing\n        self.add_to_pp_files(saved_schema_file)\n        # schema_file pp_dict should have been generated already\n        fire_event(PartialParsingFile(operation=\"updated\", file_id=file_id))\n\n    # Delete schema files -- a variation on change_schema_file\n    def delete_schema_file(self, file_id):\n        saved_schema_file = self.saved_files[file_id]\n        saved_yaml_dict = saved_schema_file.dict_from_yaml\n        new_yaml_dict = {}\n        self.handle_schema_file_changes(saved_schema_file, saved_yaml_dict, new_yaml_dict)\n        self.saved_manifest.files.pop(file_id)\n\n    # For each key in a schema file dictionary, process the changed, deleted, and added\n    # elements for the key lists\n    def handle_schema_file_changes(self, schema_file, saved_yaml_dict, new_yaml_dict):\n        # loop through comparing previous dict_from_yaml with current dict_from_yaml\n        # Need to do the deleted/added/changed thing, just like the files lists\n\n        env_var_changes = {}\n        if schema_file.file_id in self.env_vars_changed_schema_files:\n            env_var_changes = self.env_vars_changed_schema_files[schema_file.file_id]\n\n        # models, seeds, snapshots, analyses\n        for dict_key in [\"models\", \"seeds\", \"snapshots\", \"analyses\"]:\n            key_diff = self.get_diff_for(dict_key, saved_yaml_dict, new_yaml_dict)\n            if key_diff[\"changed\"]:\n                for elem in key_diff[\"changed\"]:\n                    if dict_key == \"snapshots\" and \"relation\" in elem:\n                        self.delete_yaml_snapshot(schema_file, elem)\n                    self.delete_schema_mssa_links(schema_file, dict_key, elem)\n                    self.merge_patch(schema_file, dict_key, elem, True)\n            if key_diff[\"deleted\"]:\n                for elem in key_diff[\"deleted\"]:\n                    if dict_key == \"snapshots\" and \"relation\" in elem:\n                        self.delete_yaml_snapshot(schema_file, elem)\n                    self.delete_schema_mssa_links(schema_file, dict_key, elem)\n            if key_diff[\"added\"]:\n                for elem in key_diff[\"added\"]:\n                    if dict_key == \"models\" and \"versions\" in elem:\n                        self.versioned_model_delete_schema_mssa_links(schema_file, dict_key, elem)\n                    self.merge_patch(schema_file, dict_key, elem, True)\n            # Handle schema file updates due to env_var changes\n            if dict_key in env_var_changes and dict_key in new_yaml_dict:\n                for name in env_var_changes[dict_key]:\n                    if name in key_diff[\"changed_or_deleted_names\"]:\n                        continue\n                    elem = self.get_schema_element(new_yaml_dict[dict_key], name)\n                    if elem:\n                        if dict_key == \"snapshots\" and \"relation\" in elem:\n                            self.delete_yaml_snapshot(schema_file, elem)\n                        self.delete_schema_mssa_links(schema_file, dict_key, elem)\n                        self.merge_patch(schema_file, dict_key, elem, True)\n\n        # sources\n        dict_key = \"sources\"\n        source_diff = self.get_diff_for(dict_key, saved_yaml_dict, new_yaml_dict)\n        if source_diff[\"changed\"]:\n            for source in source_diff[\"changed\"]:\n                if \"overrides\" in source:  # This is a source patch; need to re-parse orig source\n                    self.remove_source_override_target(source)\n                self.delete_schema_source(schema_file, source)\n                self.merge_patch(schema_file, dict_key, source, True)\n        if source_diff[\"deleted\"]:\n            for source in source_diff[\"deleted\"]:\n                if \"overrides\" in source:  # This is a source patch; need to re-parse orig source\n                    self.remove_source_override_target(source)\n                self.delete_schema_source(schema_file, source)\n        if source_diff[\"added\"]:\n            for source in source_diff[\"added\"]:\n                if \"overrides\" in source:  # This is a source patch; need to re-parse orig source\n                    self.remove_source_override_target(source)\n                self.merge_patch(schema_file, dict_key, source, True)\n        # Handle schema file updates due to env_var changes\n        if dict_key in env_var_changes and dict_key in new_yaml_dict:\n            for name in env_var_changes[dict_key]:\n                if name in source_diff[\"changed_or_deleted_names\"]:\n                    continue\n                source = self.get_schema_element(new_yaml_dict[dict_key], name)\n                if source:\n                    if \"overrides\" in source:\n                        self.remove_source_override_target(source)\n                    self.delete_schema_source(schema_file, source)\n                    self.merge_patch(schema_file, dict_key, source, True)\n\n        def handle_change(key: str, delete: Callable):\n            self._handle_element_change(\n                schema_file, saved_yaml_dict, new_yaml_dict, env_var_changes, key, delete\n            )\n\n        handle_change(\"macros\", self.delete_schema_macro_patch)\n        handle_change(\"exposures\", self.delete_schema_exposure)\n        handle_change(\"metrics\", self.delete_schema_metric)\n        handle_change(\"groups\", self.delete_schema_group)\n        handle_change(\"semantic_models\", self.delete_schema_semantic_model)\n        handle_change(\"unit_tests\", self.delete_schema_unit_test)\n        handle_change(\"saved_queries\", self.delete_schema_saved_query)\n        handle_change(\"data_tests\", self.delete_schema_data_test_patch)\n        handle_change(\"functions\", self.delete_schema_function)\n\n    def _handle_element_change(\n        self, schema_file, saved_yaml_dict, new_yaml_dict, env_var_changes, dict_key: str, delete\n    ):\n        element_diff = self.get_diff_for(dict_key, saved_yaml_dict, new_yaml_dict)\n        if element_diff[\"changed\"]:\n            for element in element_diff[\"changed\"]:\n                delete(schema_file, element)\n                self.merge_patch(schema_file, dict_key, element, True)\n        if element_diff[\"deleted\"]:\n            for element in element_diff[\"deleted\"]:\n                delete(schema_file, element)\n        if element_diff[\"added\"]:\n            for element in element_diff[\"added\"]:\n                self.merge_patch(schema_file, dict_key, element, True)\n        # Handle schema file updates due to env_var changes\n        if dict_key in env_var_changes and dict_key in new_yaml_dict:\n            for name in env_var_changes[dict_key]:\n                if name in element_diff[\"changed_or_deleted_names\"]:\n                    continue\n                elem = self.get_schema_element(new_yaml_dict[dict_key], name)\n                if elem:\n                    delete(schema_file, elem)\n                    self.merge_patch(schema_file, dict_key, elem, True)\n\n    # Take a \"section\" of the schema file yaml dictionary from saved and new schema files\n    # and determine which parts have changed\n    def get_diff_for(self, key, saved_yaml_dict, new_yaml_dict):\n        if key in saved_yaml_dict or key in new_yaml_dict:\n            saved_elements = saved_yaml_dict[key] if key in saved_yaml_dict else []\n            new_elements = new_yaml_dict[key] if key in new_yaml_dict else []\n        else:\n            return {\"deleted\": [], \"added\": [], \"changed\": []}\n        # for each set of keys, need to create a dictionary of names pointing to entry\n        saved_elements_by_name = {}\n        new_elements_by_name = {}\n        # sources have two part names?\n        for element in saved_elements:\n            saved_elements_by_name[element[\"name\"]] = element\n        for element in new_elements:\n            new_elements_by_name[element[\"name\"]] = element\n\n        # now determine which elements, by name, are added, deleted or changed\n        saved_element_names = set(saved_elements_by_name.keys())\n        new_element_names = set(new_elements_by_name.keys())\n        deleted = saved_element_names.difference(new_element_names)\n        added = new_element_names.difference(saved_element_names)\n        common = saved_element_names.intersection(new_element_names)\n        changed = []\n        for element_name in common:\n            if saved_elements_by_name[element_name] != new_elements_by_name[element_name]:\n                changed.append(element_name)\n\n        # make lists of yaml elements to return as diffs\n        deleted_elements = [saved_elements_by_name[name].copy() for name in deleted]\n        added_elements = [new_elements_by_name[name].copy() for name in added]\n        changed_elements = [new_elements_by_name[name].copy() for name in changed]\n\n        diff = {\n            \"deleted\": deleted_elements,\n            \"added\": added_elements,\n            \"changed\": changed_elements,\n            \"changed_or_deleted_names\": list(changed) + list(deleted),\n        }\n        return diff\n\n    # Merge a patch file into the pp_dict in a schema file. The \"new_patch\"\n    # flag indicates that we're processing a schema file, so if a matching\n    # patch has already been scheduled, replace it.\n    def merge_patch(self, schema_file, key, patch, new_patch=False):\n        if schema_file.pp_dict is None:\n            schema_file.pp_dict = {}\n        pp_dict = schema_file.pp_dict\n        if key not in pp_dict:\n            pp_dict[key] = [patch]\n        else:\n            # check that this patch hasn't already been saved\n            found_elem = None\n            for elem in pp_dict[key]:\n                if elem[\"name\"] == patch[\"name\"]:\n                    found_elem = elem\n            if not found_elem:\n                pp_dict[key].append(patch)\n            elif found_elem and new_patch:\n                # remove patch and replace with new one\n                pp_dict[key].remove(found_elem)\n                pp_dict[key].append(patch)\n\n        schema_file.delete_from_env_vars(key, patch[\"name\"])\n        schema_file.delete_from_unrendered_configs(key, patch[\"name\"])\n        self.add_to_pp_files(schema_file)\n\n    # For model, seed, snapshot, analysis schema dictionary keys,\n    # delete the patches and tests from the patch\n    def delete_schema_mssa_links(self, schema_file, dict_key, elem) -> None:\n        # find elem node unique_id in node_patches\n        prefix = key_to_prefix[dict_key]\n        elem_unique_ids = []\n        for unique_id in schema_file.node_patches:\n            if not unique_id.startswith(prefix):\n                continue\n            parts = unique_id.split(\".\")\n            elem_name = parts[2]\n            if elem_name == elem[\"name\"]:\n                elem_unique_ids.append(unique_id)\n        self._delete_schema_mssa_links(schema_file, dict_key, elem, elem_unique_ids)\n\n    def versioned_model_delete_schema_mssa_links(self, schema_file, dict_key, elem) -> None:\n        elem_unique_ids = []\n        # We need to look up possible existing models that this new or modified patch applies to\n        unique_id = f\"model.{schema_file.project_name}.{elem['name']}\"\n        if unique_id in self.saved_manifest.nodes:\n            elem_unique_ids.append(unique_id)\n        if not elem_unique_ids:\n            return\n        self._delete_schema_mssa_links(schema_file, dict_key, elem, elem_unique_ids)\n\n    def _delete_schema_mssa_links(self, schema_file, dict_key, elem, elem_unique_ids):\n        # remove elem node and remove unique_id from node_patches\n        for elem_unique_id in elem_unique_ids:\n            # might have been already removed\n            # For all-yaml snapshots, we don't do this, since the node\n            # should have already been removed.\n            if (\n                elem_unique_id in self.saved_manifest.nodes\n                or elem_unique_id in self.saved_manifest.disabled\n            ):\n                nodes: List[Union[ModelNode, SeedNode, SnapshotNode, AnalysisNode]] = []\n                if elem_unique_id in self.saved_manifest.nodes:\n                    nodes = [self.saved_manifest.nodes.pop(elem_unique_id)]  # type: ignore[list-item]\n                else:\n                    # The value of disabled items is a list of nodes\n                    nodes = self.saved_manifest.disabled.pop(elem_unique_id)  # type: ignore[assignment]\n                # need to add the node source_file to pp_files\n                for node in nodes:\n                    file_id = node.file_id\n                    # need to copy new file to saved files in order to get content\n                    if file_id in self.new_files:\n                        self.saved_files[file_id] = deepcopy(self.new_files[file_id])\n                    if self.saved_files[file_id]:\n                        source_file = self.saved_files[file_id]\n                        self.add_to_pp_files(source_file)\n                    # if the node's group has changed - need to reparse all referencing nodes to ensure valid ref access\n                    if node.group != elem.get(\"group\"):\n                        self.schedule_referencing_nodes_for_parsing(node.unique_id)\n                    # If the latest version has changed, a version has been removed, or a version has been added,\n                    #  we need to reparse referencing nodes.\n                    if node.is_versioned or elem.get(\"versions\"):\n                        self.schedule_referencing_nodes_for_parsing(node.unique_id)\n            # remove from patches\n            # For versioned models, the schedule_referencing_nodes_for_parsing call above\n            # could have caused a recursive visit to this file.\n            if elem_unique_id in schema_file.node_patches:\n                schema_file.node_patches.remove(elem_unique_id)\n\n        # for models, seeds, snapshots (not analyses)\n        if dict_key in [\"models\", \"seeds\", \"snapshots\"]:\n            # find related tests and remove them\n            self.remove_tests(schema_file, dict_key, elem[\"name\"])\n\n    def remove_tests(self, schema_file, dict_key, name):\n        tests = schema_file.get_tests(dict_key, name)\n        for test_unique_id in tests:\n            if test_unique_id in self.saved_manifest.nodes:\n                self.saved_manifest.nodes.pop(test_unique_id)\n        schema_file.remove_tests(dict_key, name)\n        # We also need to remove tests in other schema files that\n        # reference this node.\n        unique_id = f\"{key_to_prefix[dict_key]}.{schema_file.project_name}.{name}\"\n        if unique_id in self.saved_manifest.child_map:\n            for child_id in self.saved_manifest.child_map[unique_id]:\n                if child_id.startswith(\"test\") and child_id in self.saved_manifest.nodes:\n                    child_test = self.saved_manifest.nodes[child_id]\n                    if isinstance(child_test, GenericTestNode) and child_test.attached_node:\n                        if child_test.attached_node in self.saved_manifest.nodes:\n                            attached_node = self.saved_manifest.nodes[child_test.attached_node]\n                            self.update_in_saved(attached_node.file_id)\n\n    def delete_yaml_snapshot(self, schema_file, snapshot_dict):\n        snapshot_name = snapshot_dict[\"name\"]\n        snapshots = schema_file.snapshots.copy()\n        for unique_id in snapshots:\n            if unique_id in self.saved_manifest.nodes:\n                snapshot = self.saved_manifest.nodes[unique_id]\n                if snapshot.name == snapshot_name:\n                    self.saved_manifest.nodes.pop(unique_id)\n                    schema_file.snapshots.remove(unique_id)\n            elif unique_id in self.saved_manifest.disabled:\n                self.delete_disabled(unique_id, schema_file.file_id)\n                schema_file.snapshots.remove(unique_id)\n\n    def delete_schema_source(self, schema_file, source_dict):\n        # both patches, tests, and source nodes\n        source_name = source_dict[\"name\"]\n        # There may be multiple sources for each source dict, since\n        # there will be a separate source node for each table.\n        # SourceDefinition name = table name, dict name is source_name\n        sources = schema_file.sources.copy()\n        for unique_id in sources:\n            if unique_id in self.saved_manifest.sources:\n                source = self.saved_manifest.sources[unique_id]\n                if source.source_name == source_name:\n                    source = self.saved_manifest.sources.pop(unique_id)\n                    schema_file.sources.remove(unique_id)\n                    self.schedule_referencing_nodes_for_parsing(unique_id)\n\n        self.remove_tests(schema_file, \"sources\", source_name)\n\n    def delete_schema_macro_patch(self, schema_file, macro):\n        # This is just macro patches that need to be reapplied\n        macro_unique_id = None\n        if macro[\"name\"] in schema_file.macro_patches:\n            macro_unique_id = schema_file.macro_patches[macro[\"name\"]]\n            del schema_file.macro_patches[macro[\"name\"]]\n        # Need to delete all macros in the same file\n        # and then reapply all schema file updates for those macros\n        if macro_unique_id and macro_unique_id in self.saved_manifest.macros:\n            macro = self.saved_manifest.macros.pop(macro_unique_id)\n            macro_file_id = macro.file_id\n            if macro_file_id in self.new_files:\n                source_file = self.saved_files[macro_file_id]\n                self.delete_macro_file(source_file)\n                self.saved_files[macro_file_id] = deepcopy(self.new_files[macro_file_id])\n                self.add_to_pp_files(self.saved_files[macro_file_id])\n\n    def delete_schema_data_test_patch(self, schema_file, data_test):\n        data_test_unique_id = None\n        for unique_id in schema_file.node_patches:\n            if not unique_id.startswith(\"test\"):\n                continue\n            parts = unique_id.split(\".\")\n            elem_name = parts[2]\n            if elem_name == data_test[\"name\"]:\n                data_test_unique_id = unique_id\n                break\n        if data_test_unique_id and data_test_unique_id in self.saved_manifest.nodes:\n            singular_data_test = self.saved_manifest.nodes.pop(data_test_unique_id)\n            file_id = singular_data_test.file_id\n            if file_id in self.new_files:\n                self.saved_files[file_id] = deepcopy(self.new_files[file_id])\n                self.add_to_pp_files(self.saved_files[file_id])\n\n    # exposures are created only from schema files, so just delete\n    # the exposure or the disabled exposure.\n    def delete_schema_exposure(self, schema_file, exposure_dict):\n        exposure_name = exposure_dict[\"name\"]\n        exposures = schema_file.exposures.copy()\n        for unique_id in exposures:\n            if unique_id in self.saved_manifest.exposures:\n                exposure = self.saved_manifest.exposures[unique_id]\n                if exposure.name == exposure_name:\n                    self.saved_manifest.exposures.pop(unique_id)\n                    schema_file.exposures.remove(unique_id)\n            elif unique_id in self.saved_manifest.disabled:\n                self.delete_disabled(unique_id, schema_file.file_id)\n\n    # groups are created only from schema files, so just delete the group\n    def delete_schema_group(self, schema_file, group_dict):\n        group_name = group_dict[\"name\"]\n        groups = schema_file.groups.copy()\n        for unique_id in groups:\n            if unique_id in self.saved_manifest.groups:\n                group = self.saved_manifest.groups[unique_id]\n                if group.name == group_name:\n                    self.schedule_nodes_for_parsing(self.saved_manifest.group_map[group.name])\n                    self.saved_manifest.groups.pop(unique_id)\n                    schema_file.groups.remove(unique_id)\n\n    # metrics are created only from schema files, but also can be referred to by other nodes\n    def delete_schema_metric(self, schema_file, metric_dict):\n        metric_name = metric_dict[\"name\"]\n        metrics = schema_file.metrics.copy()\n        for unique_id in metrics:\n            if unique_id in self.saved_manifest.metrics:\n                metric = self.saved_manifest.metrics[unique_id]\n                if metric.name == metric_name:\n                    # Need to find everything that referenced this metric and schedule for parsing\n                    if unique_id in self.saved_manifest.child_map:\n                        self.schedule_nodes_for_parsing(self.saved_manifest.child_map[unique_id])\n                    self.saved_manifest.metrics.pop(unique_id)\n                    schema_file.metrics.remove(unique_id)\n            elif unique_id in self.saved_manifest.disabled:\n                self.delete_disabled(unique_id, schema_file.file_id)\n\n    def delete_schema_saved_query(self, schema_file, saved_query_dict):\n        saved_query_name = saved_query_dict[\"name\"]\n        saved_queries = schema_file.saved_queries.copy()\n        for unique_id in saved_queries:\n            if unique_id in self.saved_manifest.saved_queries:\n                saved_query = self.saved_manifest.saved_queries[unique_id]\n                if saved_query.name == saved_query_name:\n                    # Need to find everything that referenced this saved_query and schedule for parsing\n                    if unique_id in self.saved_manifest.child_map:\n                        self.schedule_nodes_for_parsing(self.saved_manifest.child_map[unique_id])\n                    self.saved_manifest.saved_queries.pop(unique_id)\n            elif unique_id in self.saved_manifest.disabled:\n                self.delete_disabled(unique_id, schema_file.file_id)\n\n    def delete_schema_semantic_model(self, schema_file, semantic_model_dict):\n        semantic_model_name = semantic_model_dict[\"name\"]\n        semantic_models = schema_file.semantic_models.copy()\n        for unique_id in semantic_models:\n            if unique_id in self.saved_manifest.semantic_models:\n                semantic_model = self.saved_manifest.semantic_models[unique_id]\n                if semantic_model.name == semantic_model_name:\n                    # Need to find everything that referenced this semantic model and schedule for parsing\n                    if unique_id in self.saved_manifest.child_map:\n                        self.schedule_nodes_for_parsing(self.saved_manifest.child_map[unique_id])\n                    self.saved_manifest.semantic_models.pop(unique_id)\n                    schema_file.semantic_models.remove(unique_id)\n            elif unique_id in self.saved_manifest.disabled:\n                self.delete_disabled(unique_id, schema_file.file_id)\n\n        if schema_file.generated_metrics:\n            # If this partial parse file has an old \"generated_metrics\" list,\n            # call code to fix it up before processing.\n            schema_file.fix_metrics_from_measures()\n        if semantic_model_name in schema_file.metrics_from_measures:\n            for unique_id in schema_file.metrics_from_measures[semantic_model_name]:\n                if unique_id in self.saved_manifest.metrics:\n                    self.saved_manifest.metrics.pop(unique_id)\n                elif unique_id in self.saved_manifest.disabled:\n                    self.delete_disabled(unique_id, schema_file.file_id)\n            del schema_file.metrics_from_measures[semantic_model_name]\n\n    def delete_schema_unit_test(self, schema_file, unit_test_dict):\n        unit_test_name = unit_test_dict[\"name\"]\n        unit_tests = schema_file.unit_tests.copy()\n        for unique_id in unit_tests:\n            if unique_id in self.saved_manifest.unit_tests:\n                unit_test = self.saved_manifest.unit_tests[unique_id]\n                if unit_test.name == unit_test_name:\n                    self.saved_manifest.unit_tests.pop(unique_id)\n                    schema_file.unit_tests.remove(unique_id)\n            # No disabled unit tests yet\n\n    def delete_schema_function(self, schema_file: SchemaSourceFile, function_dict: dict) -> None:\n        function_name = function_dict[\"name\"]\n        functions = schema_file.node_patches.copy()\n        for unique_id in functions:\n            if unique_id in self.saved_manifest.functions:\n                function = self.saved_manifest.functions[unique_id]\n                if function.name == function_name:\n                    removed_function = self.saved_manifest.functions.pop(unique_id)\n                    # For schema patches, recorded unique_ids live in node_patches (ndp)\n                    if unique_id in schema_file.node_patches:\n                        schema_file.node_patches.remove(unique_id)\n                    # Schedule the function's SQL file for reparsing so the node is re-added\n                    file_id = removed_function.file_id\n                    if file_id and file_id in self.new_files:\n                        self.saved_files[file_id] = deepcopy(self.new_files[file_id])\n                    if file_id and file_id in self.saved_files:\n                        self.add_to_pp_files(self.saved_files[file_id])\n\n    def get_schema_element(self, elem_list, elem_name):\n        for element in elem_list:\n            if \"name\" in element and element[\"name\"] == elem_name:\n                return element\n        return None\n\n    def get_schema_file_for_source(self, package_name, source_name):\n        schema_file = None\n        for source in self.saved_manifest.sources.values():\n            if source.package_name == package_name and source.source_name == source_name:\n                file_id = source.file_id\n                if file_id in self.saved_files:\n                    schema_file = self.saved_files[file_id]\n                break\n        return schema_file\n\n    def get_source_override_file_and_dict(self, source):\n        package = source[\"overrides\"]\n        source_name = source[\"name\"]\n        orig_source_schema_file = self.get_schema_file_for_source(package, source_name)\n        orig_sources = orig_source_schema_file.dict_from_yaml[\"sources\"]\n        orig_source = self.get_schema_element(orig_sources, source_name)\n        return (orig_source_schema_file, orig_source)\n\n    def remove_source_override_target(self, source_dict):\n        (orig_file, orig_source) = self.get_source_override_file_and_dict(source_dict)\n        if orig_source:\n            self.delete_schema_source(orig_file, orig_source)\n            self.merge_patch(orig_file, \"sources\", orig_source)\n            self.add_to_pp_files(orig_file)\n\n    # This builds a dictionary of files that need to be scheduled for parsing\n    # because the env var has changed.\n    # source_files\n    #   env_vars_changed_source_files: [file_id, file_id...]\n    # schema_files\n    #   env_vars_changed_schema_files: {file_id: {\"yaml_key\": [name, ..]}}\n    def build_env_vars_to_files(self):\n        unchanged_vars = []\n        changed_vars = []\n        delete_vars = []\n        # Check whether the env_var has changed and add it to\n        # an unchanged or changed list\n        for env_var in self.saved_manifest.env_vars:\n            prev_value = self.saved_manifest.env_vars[env_var]\n            current_value = os.getenv(env_var)\n            if current_value is None:\n                # This will be true when depending on the default value.\n                # We store env vars set by defaults as a static string so we can recognize they have\n                # defaults.  We depend on default changes triggering reparsing by file change. If\n                # the file has not changed we can assume the default has not changed.\n                if prev_value == DEFAULT_ENV_PLACEHOLDER:\n                    unchanged_vars.append(env_var)\n                    continue\n                # env_var no longer set, remove from manifest\n                delete_vars.append(env_var)\n            if prev_value == current_value:\n                unchanged_vars.append(env_var)\n            else:  # prev_value != current_value\n                changed_vars.append(env_var)\n        for env_var in delete_vars:\n            del self.saved_manifest.env_vars[env_var]\n\n        env_vars_changed_source_files = []\n        env_vars_changed_schema_files = {}\n        # The SourceFiles contain a list of env_vars that were used in the file.\n        # The SchemaSourceFiles contain a dictionary of yaml_key to schema entry names to\n        # a list of vars.\n        # Create a list of file_ids for source_files that need to be reparsed, and\n        # a dictionary of file_ids to yaml_keys to names.\n        for source_file in self.saved_files.values():\n            if source_file.parse_file_type == ParseFileType.Fixture:\n                continue\n            file_id = source_file.file_id\n            if not source_file.env_vars:\n                continue\n            if source_file.parse_file_type == ParseFileType.Schema:\n                for yaml_key in source_file.env_vars.keys():\n                    for name in source_file.env_vars[yaml_key].keys():\n                        for env_var in source_file.env_vars[yaml_key][name]:\n                            if env_var in changed_vars:\n                                if file_id not in env_vars_changed_schema_files:\n                                    env_vars_changed_schema_files[file_id] = {}\n                                if yaml_key not in env_vars_changed_schema_files[file_id]:\n                                    env_vars_changed_schema_files[file_id][yaml_key] = []\n                                if name not in env_vars_changed_schema_files[file_id][yaml_key]:\n                                    env_vars_changed_schema_files[file_id][yaml_key].append(name)\n                                break  # if one env_var is changed we can stop\n\n            else:\n                for env_var in source_file.env_vars:\n                    if env_var in changed_vars:\n                        env_vars_changed_source_files.append(file_id)\n                        break  # if one env_var is changed we can stop\n\n        return (env_vars_changed_source_files, env_vars_changed_schema_files)\n"
  },
  {
    "path": "core/dbt/parser/read_files.py",
    "content": "import os\nimport pathlib\nfrom dataclasses import dataclass, field\nfrom typing import Dict, List, Mapping, MutableMapping, Optional, Protocol\n\nimport pathspec  # type: ignore\n\nfrom dbt.config import Project\nfrom dbt.contracts.files import (\n    AnySourceFile,\n    FileHash,\n    FilePath,\n    FixtureSourceFile,\n    ParseFileType,\n    SchemaSourceFile,\n    SourceFile,\n)\nfrom dbt.events.types import InputFileDiffError\nfrom dbt.exceptions import ParsingError\nfrom dbt.parser.common import schema_file_keys\nfrom dbt.parser.schemas import yaml_from_file\nfrom dbt.parser.search import filesystem_search\nfrom dbt_common.clients.system import load_file_contents\nfrom dbt_common.dataclass_schema import dbtClassMixin\nfrom dbt_common.events.functions import fire_event\n\n\n@dataclass\nclass InputFile(dbtClassMixin):\n    path: str\n    content: str\n    modification_time: float = 0.0\n\n\n@dataclass\nclass FileDiff(dbtClassMixin):\n    deleted: List[str]\n    # Note: it would be possible to not distinguish between\n    # added and changed files, but we would lose some error handling.\n    changed: List[InputFile]\n    added: List[InputFile]\n\n\ndef normalize_file_contents(contents: str) -> str:\n    \"\"\"Normalize file contents by compacting whitespace and newlines to a single whitespace.\n    This ensures consistent checksums regardless of formatting differences.\n    \"\"\"\n    return \" \".join(contents.split())\n\n\n# This loads the files contents and creates the SourceFile object\ndef load_source_file(\n    path: FilePath,\n    parse_file_type: ParseFileType,\n    project_name: str,\n    saved_files,\n) -> Optional[AnySourceFile]:\n\n    if parse_file_type == ParseFileType.Schema:\n        sf_cls = SchemaSourceFile\n    elif parse_file_type == ParseFileType.Fixture:\n        sf_cls = FixtureSourceFile  # type:ignore[assignment]\n    else:\n        sf_cls = SourceFile  # type:ignore[assignment]\n\n    source_file = sf_cls(\n        path=path,\n        checksum=FileHash.empty(),\n        parse_file_type=parse_file_type,\n        project_name=project_name,\n    )\n\n    skip_loading_schema_file = False\n    if (\n        parse_file_type == ParseFileType.Schema\n        and saved_files\n        and source_file.file_id in saved_files\n    ):\n        old_source_file = saved_files[source_file.file_id]\n        if (\n            source_file.path.modification_time != 0.0\n            and old_source_file.path.modification_time == source_file.path.modification_time\n        ):\n            source_file.checksum = old_source_file.checksum\n            source_file.dfy = old_source_file.dfy\n            skip_loading_schema_file = True\n\n    if not skip_loading_schema_file:\n        # We strip the file_contents before generating the checksum because we want\n        # the checksum to match the stored file contents\n        file_contents = load_file_contents(path.absolute_path, strip=True)\n        source_file.contents = file_contents\n        normalized_contents = normalize_file_contents(file_contents)\n        source_file.checksum = FileHash.from_contents(normalized_contents)\n\n    if parse_file_type == ParseFileType.Schema and source_file.contents:\n        dfy = yaml_from_file(source_file=source_file, validate=True)\n        if dfy:\n            validate_yaml(source_file.path.original_file_path, dfy)\n            source_file.dfy = dfy\n    return source_file\n\n\n# Do some minimal validation of the yaml in a schema file.\n# Check version, that key values are lists and that each element in\n# the lists has a 'name' key\ndef validate_yaml(file_path, dct):\n    for key in schema_file_keys:\n        if key in dct:\n            if not isinstance(dct[key], list):\n                msg = (\n                    f\"The schema file at {file_path} is \"\n                    f\"invalid because the value of '{key}' is not a list\"\n                )\n                raise ParsingError(msg)\n            for element in dct[key]:\n                if not isinstance(element, dict):\n                    msg = (\n                        f\"The schema file at {file_path} is \"\n                        f\"invalid because a list element for '{key}' is not a dictionary\"\n                    )\n                    raise ParsingError(msg)\n                if \"name\" not in element:\n                    msg = (\n                        f\"The schema file at {file_path} is \"\n                        f\"invalid because a list element for '{key}' does not have a \"\n                        \"name attribute.\"\n                    )\n                    raise ParsingError(msg)\n\n\n# Special processing for big seed files\ndef load_seed_source_file(match: FilePath, project_name) -> SourceFile:\n    if match.seed_too_large():\n        # We don't want to calculate a hash of this file. Use the path.\n        source_file = SourceFile.big_seed(match)\n    else:\n        file_contents = load_file_contents(match.absolute_path, strip=True)\n        checksum = FileHash.from_contents(file_contents)\n        source_file = SourceFile(path=match, checksum=checksum)\n        source_file.contents = \"\"\n    source_file.parse_file_type = ParseFileType.Seed\n    source_file.project_name = project_name\n    return source_file\n\n\n# Use the FilesystemSearcher to get a bunch of FilePaths, then turn\n# them into a bunch of FileSource objects\ndef get_source_files(project, paths, extension, parse_file_type, saved_files, ignore_spec):\n    # file path list\n    fp_list = filesystem_search(project, paths, extension, ignore_spec)\n    # file block list\n    fb_list = []\n    for fp in fp_list:\n        if parse_file_type == ParseFileType.Seed:\n            fb_list.append(load_seed_source_file(fp, project.project_name))\n        # singular tests live in /tests but only generic tests live\n        # in /tests/generic and fixtures in /tests/fixture so we want to skip those\n        else:\n            if parse_file_type == ParseFileType.SingularTest:\n                path = pathlib.Path(fp.relative_path)\n                if path.parts[0] in [\"generic\", \"fixtures\"]:\n                    continue\n            file = load_source_file(fp, parse_file_type, project.project_name, saved_files)\n            # only append the list if it has contents. added to fix #3568\n            if file:\n                fb_list.append(file)\n    return fb_list\n\n\ndef read_files_for_parser(project, files, parse_ft, file_type_info, saved_files, ignore_spec):\n    dirs = file_type_info[\"paths\"]\n    parser_files = []\n    for extension in file_type_info[\"extensions\"]:\n        source_files = get_source_files(\n            project, dirs, extension, parse_ft, saved_files, ignore_spec\n        )\n        for sf in source_files:\n            files[sf.file_id] = sf\n            parser_files.append(sf.file_id)\n    return parser_files\n\n\ndef generate_dbt_ignore_spec(project_root):\n    ignore_file_path = os.path.join(project_root, \".dbtignore\")\n\n    ignore_spec = None\n    if os.path.exists(ignore_file_path):\n        with open(ignore_file_path) as f:\n            ignore_spec = pathspec.PathSpec.from_lines(pathspec.patterns.GitWildMatchPattern, f)\n    return ignore_spec\n\n\n# Protocol for the ReadFiles... classes\nclass ReadFiles(Protocol):\n    files: MutableMapping[str, AnySourceFile]\n    project_parser_files: Dict\n\n    def read_files(self):\n        pass\n\n\n@dataclass\nclass ReadFilesFromFileSystem:\n    all_projects: Mapping[str, Project]\n    files: MutableMapping[str, AnySourceFile] = field(default_factory=dict)\n    # saved_files is only used to compare schema files\n    saved_files: MutableMapping[str, AnySourceFile] = field(default_factory=dict)\n    # project_parser_files = {\n    #   \"my_project\": {\n    #     \"ModelParser\": [\"my_project://models/my_model.sql\"]\n    #   }\n    # }\n    #\n    project_parser_files: Dict = field(default_factory=dict)\n\n    def read_files(self):\n        for project in self.all_projects.values():\n            file_types = get_file_types_for_project(project)\n            self.read_files_for_project(project, file_types)\n\n    def read_files_for_project(self, project, file_types):\n        dbt_ignore_spec = generate_dbt_ignore_spec(project.project_root)\n        project_files = self.project_parser_files[project.project_name] = {}\n\n        for parse_ft, file_type_info in file_types.items():\n            project_files[file_type_info[\"parser\"]] = read_files_for_parser(\n                project,\n                self.files,\n                parse_ft,\n                file_type_info,\n                self.saved_files,\n                dbt_ignore_spec,\n            )\n\n\n@dataclass\nclass ReadFilesFromDiff:\n    root_project_name: str\n    all_projects: Mapping[str, Project]\n    file_diff: FileDiff\n    files: MutableMapping[str, AnySourceFile] = field(default_factory=dict)\n    # saved_files is used to construct a fresh copy of files, without\n    # additional information from parsing\n    saved_files: MutableMapping[str, AnySourceFile] = field(default_factory=dict)\n    project_parser_files: Dict = field(default_factory=dict)\n    project_file_types: Dict = field(default_factory=dict)\n    local_package_dirs: Optional[List[str]] = None\n\n    def read_files(self):\n        # Copy the base file information from the existing manifest.\n        # We will do deletions, adds, changes from the file_diff to emulate\n        # a complete read of the project file system.\n        for file_id, source_file in self.saved_files.items():\n            if isinstance(source_file, SchemaSourceFile):\n                file_cls = SchemaSourceFile\n            else:\n                file_cls = SourceFile\n            new_source_file = file_cls(\n                path=source_file.path,\n                checksum=source_file.checksum,\n                project_name=source_file.project_name,\n                parse_file_type=source_file.parse_file_type,\n                contents=source_file.contents,\n            )\n            self.files[file_id] = new_source_file\n\n        # Now that we have a copy of the files, remove deleted files\n        # For now, we assume that all files are in the root_project, until\n        # we've determined whether project name will be provided or deduced\n        # from the directory.\n        for input_file_path in self.file_diff.deleted:\n            project_name = self.get_project_name(input_file_path)\n            file_id = f\"{project_name}://{input_file_path}\"\n            if file_id in self.files:\n                self.files.pop(file_id)\n            else:\n                fire_event(InputFileDiffError(category=\"deleted file not found\", file_id=file_id))\n\n        # Now we do the changes\n        for input_file in self.file_diff.changed:\n            project_name = self.get_project_name(input_file.path)\n            file_id = f\"{project_name}://{input_file.path}\"\n            if file_id in self.files:\n                # Get the existing source_file object and update the contents and mod time\n                source_file = self.files[file_id]\n                source_file.contents = input_file.content\n                source_file.checksum = FileHash.from_contents(input_file.content)\n                source_file.path.modification_time = input_file.modification_time\n                # Handle creation of dictionary version of schema file content\n                if isinstance(source_file, SchemaSourceFile) and source_file.contents:\n                    dfy = yaml_from_file(source_file)\n                    if dfy:\n                        validate_yaml(source_file.path.original_file_path, dfy)\n                        source_file.dfy = dfy\n                    # TODO: ensure we have a file object even for empty files, such as schema files\n\n        # Now the new files\n        for input_file in self.file_diff.added:\n            project_name = self.get_project_name(input_file.path)\n            # FilePath\n            #   searched_path  i.e. \"models\"\n            #   relative_path  i.e. the part after searched_path, or \"model.sql\"\n            #   modification_time  float, default 0.0...\n            #   project_root\n            # We use PurePath because there's no actual filesystem to look at\n            input_file_path = pathlib.PurePath(input_file.path)\n            extension = input_file_path.suffix\n            searched_path = input_file_path.parts[0]\n            # check what happens with generic tests... searched_path/relative_path\n\n            relative_path_parts = input_file_path.parts[1:]\n            relative_path = pathlib.PurePath(\"\").joinpath(*relative_path_parts)\n            # Create FilePath object\n            input_file_path = FilePath(\n                searched_path=searched_path,\n                relative_path=str(relative_path),\n                modification_time=input_file.modification_time,\n                project_root=self.all_projects[project_name].project_root,\n            )\n\n            # Now use the extension and \"searched_path\" to determine which file_type\n            (file_types, file_type_lookup) = self.get_project_file_types(project_name)\n            parse_ft_for_extension = set()\n            parse_ft_for_path = set()\n            if extension in file_type_lookup[\"extensions\"]:\n                parse_ft_for_extension = file_type_lookup[\"extensions\"][extension]\n            if searched_path in file_type_lookup[\"paths\"]:\n                parse_ft_for_path = file_type_lookup[\"paths\"][searched_path]\n            if len(parse_ft_for_extension) == 0 or len(parse_ft_for_path) == 0:\n                fire_event(InputFileDiffError(category=\"not a project file\", file_id=file_id))\n                continue\n            parse_ft_set = parse_ft_for_extension.intersection(parse_ft_for_path)\n            if (\n                len(parse_ft_set) != 1\n            ):  # There should only be one result for a path/extension combination\n                fire_event(\n                    InputFileDiffError(\n                        category=\"unable to resolve diff file location\", file_id=file_id\n                    )\n                )\n                continue\n            parse_ft = parse_ft_set.pop()\n            source_file_cls = SourceFile\n            if parse_ft == ParseFileType.Schema:\n                source_file_cls = SchemaSourceFile\n            source_file = source_file_cls(\n                path=input_file_path,\n                contents=input_file.content,\n                checksum=FileHash.from_contents(input_file.content),\n                project_name=project_name,\n                parse_file_type=parse_ft,\n            )\n            if source_file_cls == SchemaSourceFile:\n                dfy = yaml_from_file(source_file)\n                if dfy:\n                    validate_yaml(source_file.path.original_file_path, dfy)\n                    source_file.dfy = dfy\n                else:\n                    # don't include in files because no content\n                    continue\n            self.files[source_file.file_id] = source_file\n\n    def get_project_name(self, path):\n        # It's not currently possible to recognize any other project files,\n        # and it's an open issue how to handle deps.\n        return self.root_project_name\n\n    def get_project_file_types(self, project_name):\n        if project_name not in self.project_file_types:\n            file_types = get_file_types_for_project(self.all_projects[project_name])\n            file_type_lookup = self.get_file_type_lookup(file_types)\n            self.project_file_types[project_name] = {\n                \"file_types\": file_types,\n                \"file_type_lookup\": file_type_lookup,\n            }\n        file_types = self.project_file_types[project_name][\"file_types\"]\n        file_type_lookup = self.project_file_types[project_name][\"file_type_lookup\"]\n        return (file_types, file_type_lookup)\n\n    def get_file_type_lookup(self, file_types):\n        file_type_lookup = {\"paths\": {}, \"extensions\": {}}\n        for parse_ft, file_type in file_types.items():\n            for path in file_type[\"paths\"]:\n                if path not in file_type_lookup[\"paths\"]:\n                    file_type_lookup[\"paths\"][path] = set()\n                file_type_lookup[\"paths\"][path].add(parse_ft)\n            for extension in file_type[\"extensions\"]:\n                if extension not in file_type_lookup[\"extensions\"]:\n                    file_type_lookup[\"extensions\"][extension] = set()\n                file_type_lookup[\"extensions\"][extension].add(parse_ft)\n        return file_type_lookup\n\n\ndef get_file_types_for_project(project):\n    file_types = {\n        ParseFileType.Macro: {\n            \"paths\": project.macro_paths,\n            \"extensions\": [\".sql\"],\n            \"parser\": \"MacroParser\",\n        },\n        ParseFileType.Model: {\n            \"paths\": project.model_paths,\n            \"extensions\": [\".sql\", \".py\"],\n            \"parser\": \"ModelParser\",\n        },\n        ParseFileType.Snapshot: {\n            \"paths\": project.snapshot_paths,\n            \"extensions\": [\".sql\"],\n            \"parser\": \"SnapshotParser\",\n        },\n        ParseFileType.Analysis: {\n            \"paths\": project.analysis_paths,\n            \"extensions\": [\".sql\"],\n            \"parser\": \"AnalysisParser\",\n        },\n        ParseFileType.SingularTest: {\n            \"paths\": project.test_paths,\n            \"extensions\": [\".sql\"],\n            \"parser\": \"SingularTestParser\",\n        },\n        ParseFileType.GenericTest: {\n            \"paths\": project.generic_test_paths,\n            \"extensions\": [\".sql\"],\n            \"parser\": \"GenericTestParser\",\n        },\n        ParseFileType.Seed: {\n            \"paths\": project.seed_paths,\n            \"extensions\": [\".csv\"],\n            \"parser\": \"SeedParser\",\n        },\n        ParseFileType.Documentation: {\n            \"paths\": project.docs_paths,\n            \"extensions\": [\".md\"],\n            \"parser\": \"DocumentationParser\",\n        },\n        ParseFileType.Schema: {\n            \"paths\": project.all_source_paths,\n            \"extensions\": [\".yml\", \".yaml\"],\n            \"parser\": \"SchemaParser\",\n        },\n        ParseFileType.Fixture: {\n            \"paths\": project.fixture_paths,\n            \"extensions\": [\".csv\", \".sql\"],\n            \"parser\": \"FixtureParser\",\n        },\n        ParseFileType.Function: {\n            \"paths\": project.function_paths,\n            \"extensions\": [\".sql\", \".py\"],\n            \"parser\": \"FunctionParser\",\n        },\n    }\n    return file_types\n"
  },
  {
    "path": "core/dbt/parser/schema_generic_tests.py",
    "content": "import itertools\nimport os\nimport pathlib\nfrom typing import Any, Dict, List, Optional, Union\n\nfrom dbt.adapters.factory import get_adapter, get_adapter_package_names\nfrom dbt.artifacts.resources import NodeVersion, RefArgs\nfrom dbt.clients.jinja import add_rendered_test_kwargs, get_rendered\nfrom dbt.context.configured import SchemaYamlVars, generate_schema_yml_context\nfrom dbt.context.context_config import ContextConfig\nfrom dbt.context.macro_resolver import MacroResolver\nfrom dbt.context.providers import generate_test_context\nfrom dbt.contracts.files import FileHash\nfrom dbt.contracts.graph.nodes import (\n    GenericTestNode,\n    GraphMemberNode,\n    ManifestNode,\n    UnpatchedSourceDefinition,\n)\nfrom dbt.contracts.graph.unparsed import UnparsedColumn, UnparsedNodeUpdate\nfrom dbt.exceptions import (\n    CompilationError,\n    ParsingError,\n    SchemaConfigError,\n    TestConfigError,\n)\nfrom dbt.node_types import NodeType\nfrom dbt.parser.base import SimpleParser\nfrom dbt.parser.common import (\n    GenericTestBlock,\n    Testable,\n    TestBlock,\n    TestDef,\n    VersionedTestBlock,\n    trimmed,\n)\nfrom dbt.parser.generic_test_builders import TestBuilder\nfrom dbt.parser.search import FileBlock\nfrom dbt.utils import get_pseudo_test_path, md5\nfrom dbt_common.dataclass_schema import ValidationError\n\n\n# This parser handles the tests that are defined in \"schema\" (yaml) files, on models,\n# sources, etc. The base generic test is handled by the GenericTestParser\nclass SchemaGenericTestParser(SimpleParser):\n    def __init__(\n        self,\n        project,\n        manifest,\n        root_project,\n    ) -> None:\n        super().__init__(project, manifest, root_project)\n        self.schema_yaml_vars = SchemaYamlVars()\n        self.render_ctx = generate_schema_yml_context(\n            self.root_project, self.project.project_name, self.schema_yaml_vars\n        )\n        internal_package_names = get_adapter_package_names(self.root_project.credentials.type)\n        self.macro_resolver = MacroResolver(\n            self.manifest.macros, self.root_project.project_name, internal_package_names\n        )\n\n    @property\n    def resource_type(self) -> NodeType:\n        return NodeType.Test\n\n    @classmethod\n    def get_compiled_path(cls, block: FileBlock) -> str:\n        return block.path.relative_path\n\n    def parse_file(self, block: FileBlock, dct: Optional[Dict] = None) -> None:\n        pass\n\n    def parse_from_dict(self, dct, validate=True) -> GenericTestNode:\n        if validate:\n            GenericTestNode.validate(dct)\n        return GenericTestNode.from_dict(dct)\n\n    def parse_column_tests(\n        self, block: TestBlock, column: UnparsedColumn, version: Optional[NodeVersion]\n    ) -> None:\n        if not column.data_tests:\n            return\n\n        for data_test in column.data_tests:\n            self.parse_test(block, data_test, column, version)\n\n    def create_test_node(\n        self,\n        target: Union[UnpatchedSourceDefinition, UnparsedNodeUpdate],\n        path: str,\n        config: ContextConfig,\n        tags: List[str],\n        fqn: List[str],\n        name: str,\n        raw_code: str,\n        test_metadata: Dict[str, Any],\n        file_key_name: str,\n        column_name: Optional[str],\n        description: str,\n    ) -> GenericTestNode:\n\n        HASH_LENGTH = 10\n\n        # N.B: This function builds a hashable string from any given test_metadata dict.\n        #   it's a bit fragile for general use (only supports str, int, float, List, Dict)\n        #   but it gets the job done here without the overhead of complete ser(de).\n        def get_hashable_md(data: Union[str, int, float, List, Dict]) -> Union[str, List, Dict]:\n            if type(data) == dict:\n                return {k: get_hashable_md(data[k]) for k in sorted(data.keys())}  # type: ignore\n            elif type(data) == list:\n                return [get_hashable_md(val) for val in data]  # type: ignore\n            else:\n                return str(data)\n\n        hashable_metadata = repr(get_hashable_md(test_metadata))\n        hash_string = \"\".join([name, hashable_metadata])\n        test_hash = md5(hash_string)[-HASH_LENGTH:]\n\n        dct = {\n            \"alias\": name,\n            \"schema\": self.default_schema,\n            \"database\": self.default_database,\n            \"fqn\": fqn,\n            \"name\": name,\n            \"resource_type\": self.resource_type,\n            \"tags\": tags,\n            \"path\": path,\n            \"original_file_path\": target.original_file_path,\n            \"package_name\": self.project.project_name,\n            \"raw_code\": raw_code,\n            \"language\": \"sql\",\n            \"unique_id\": self.generate_unique_id(name, test_hash),\n            \"config\": self.config_dict(config),\n            \"test_metadata\": test_metadata,\n            \"column_name\": column_name,\n            \"checksum\": FileHash.empty().to_dict(omit_none=True),\n            \"file_key_name\": file_key_name,\n            \"description\": description,\n        }\n        try:\n            GenericTestNode.validate(dct)\n            return GenericTestNode.from_dict(dct)\n        except ValidationError as exc:\n            # this is a bit silly, but build an UnparsedNode just for error\n            # message reasons\n            node = self._create_error_node(\n                name=target.name,\n                path=path,\n                original_file_path=target.original_file_path,\n                raw_code=raw_code,\n            )\n            raise TestConfigError(exc, node)\n\n    # This is called directly in the SourcePatcher and by the \"parse_node\"\n    # command which is called by the SchemaParser.\n    def parse_generic_test(\n        self,\n        target: Testable,\n        data_test: Dict[str, Any],\n        tags: List[str],\n        column_name: Optional[str],\n        schema_file_id: str,\n        version: Optional[NodeVersion],\n    ) -> GenericTestNode:\n        try:\n            builder = TestBuilder(\n                data_test=data_test,\n                target=target,\n                column_name=column_name,\n                version=version,\n                package_name=target.package_name,\n                render_ctx=self.render_ctx,\n            )\n            if self.schema_yaml_vars.env_vars:\n                self.store_env_vars(target, schema_file_id, self.schema_yaml_vars.env_vars)\n                self.schema_yaml_vars.env_vars = {}\n\n        except ParsingError as exc:\n            context = trimmed(str(target))\n            msg = \"Invalid test config given in {}:\\n\\t{}\\n\\t@: {}\".format(\n                target.original_file_path, exc.msg, context\n            )\n            raise ParsingError(msg) from exc\n\n        except CompilationError as exc:\n            context = trimmed(str(target))\n            msg = (\n                \"Invalid generic test configuration given in \"\n                f\"{target.original_file_path}: \\n{exc.msg}\\n\\t@: {context}\"\n            )\n            raise CompilationError(msg) from exc\n\n        original_name = os.path.basename(target.original_file_path)\n        compiled_path = get_pseudo_test_path(builder.compiled_name, original_name)\n\n        # fqn is the relative path of the yaml file where this generic test is defined,\n        # minus the project-level directory and the file name itself\n        # TODO pass a consistent path object from both UnparsedNode and UnpatchedSourceDefinition\n        path = pathlib.Path(target.original_file_path)\n        relative_path = str(path.relative_to(*path.parts[:1]))\n        fqn = self.get_fqn(relative_path, builder.fqn_name)\n\n        # this is the ContextConfig that is used in render_update\n        config: ContextConfig = self.initial_config(fqn)\n        # Adding the builder's config to the ContextConfig\n        # is needed to ensure the config makes it to the pre_model hook which dbt-snowflake needs\n        config.add_config_call(builder.config)\n        # builder.args contains keyword args for the test macro,\n        # not configs which have been separated out in the builder.\n        # The keyword args are not completely rendered until compilation.\n        metadata = {\n            \"namespace\": builder.namespace,\n            \"name\": builder.name,\n            \"kwargs\": builder.args,\n        }\n        tags = sorted(set(itertools.chain(tags, builder.tags())))\n\n        if isinstance(target, UnpatchedSourceDefinition):\n            file_key_name = f\"{target.source.yaml_key}.{target.source.name}\"\n        else:\n            file_key_name = f\"{target.yaml_key}.{target.name}\"\n\n        node = self.create_test_node(\n            target=target,\n            path=compiled_path,\n            config=config,\n            fqn=fqn,\n            tags=tags,\n            name=builder.fqn_name,\n            raw_code=builder.build_raw_code(),\n            column_name=column_name,\n            test_metadata=metadata,\n            file_key_name=file_key_name,\n            description=builder.description,\n        )\n        self.render_test_update(node, config, builder, schema_file_id)\n\n        return node\n\n    def _lookup_attached_node(\n        self, target: Testable, version: Optional[NodeVersion]\n    ) -> Optional[Union[ManifestNode, GraphMemberNode]]:\n        \"\"\"Look up attached node for Testable target nodes other than sources. Can be None if generic test attached to SQL node with no corresponding .sql file.\"\"\"\n        attached_node = None  # type: Optional[Union[ManifestNode, GraphMemberNode]]\n        if not isinstance(target, UnpatchedSourceDefinition):\n            attached_node_unique_id = self.manifest.ref_lookup.get_unique_id(\n                target.name, target.package_name, version\n            )\n            if attached_node_unique_id:\n                attached_node = self.manifest.nodes[attached_node_unique_id]\n            else:\n                disabled_node = self.manifest.disabled_lookup.find(\n                    target.name, None\n                ) or self.manifest.disabled_lookup.find(target.name.upper(), None)\n                if disabled_node:\n                    attached_node = self.manifest.disabled[disabled_node[0].unique_id][0]\n        return attached_node\n\n    def store_env_vars(self, target, schema_file_id, env_vars):\n        self.manifest.env_vars.update(env_vars)\n        if schema_file_id in self.manifest.files:\n            schema_file = self.manifest.files[schema_file_id]\n            if isinstance(target, UnpatchedSourceDefinition):\n                search_name = target.source.name\n                yaml_key = target.source.yaml_key\n                if \".\" in search_name:  # source file definitions\n                    (search_name, _) = search_name.split(\".\")\n            else:\n                search_name = target.name\n                yaml_key = target.yaml_key\n            for var in env_vars.keys():\n                schema_file.add_env_var(var, yaml_key, search_name)\n\n    # This does special shortcut processing for the two\n    # most common internal macros, not_null and unique,\n    # which avoids the jinja rendering to resolve config\n    # and variables, etc, which might be in the macro.\n    # In the future we will look at generalizing this\n    # more to handle additional macros or to use static\n    # parsing to avoid jinja overhead.\n    def render_test_update(self, node, config, builder, schema_file_id):\n        macro_unique_id = self.macro_resolver.get_macro_id(\n            node.package_name, \"test_\" + builder.name\n        )\n        # Add the depends_on here so we can limit the macros added\n        # to the context in rendering processing\n        node.depends_on.add_macro(macro_unique_id)\n        if macro_unique_id in [\"macro.dbt.test_not_null\", \"macro.dbt.test_unique\"]:\n            config_call_dict = builder.config\n            config._config_call_dict = config_call_dict\n            # This sets the config from dbt_project\n            self.update_parsed_node_config(node, config)\n            # source node tests are processed at patch_source time\n            if isinstance(builder.target, UnpatchedSourceDefinition):\n                sources = [builder.target.fqn[-2], builder.target.fqn[-1]]\n                node.sources.append(sources)\n            else:  # all other nodes\n                node.refs.append(RefArgs(name=builder.target.name, version=builder.version))\n        else:\n            try:\n                # make a base context that doesn't have the magic kwargs field\n                context = generate_test_context(\n                    node,\n                    self.root_project,\n                    self.manifest,\n                    config,\n                    self.macro_resolver,\n                )\n                # update with rendered test kwargs (which collects any refs)\n                # Note: This does not actually update the kwargs with the rendered\n                # values. That happens in compilation.\n                add_rendered_test_kwargs(context, node, capture_macros=True)\n                # the parsed node is not rendered in the native context.\n                get_rendered(node.raw_code, context, node, capture_macros=True)\n                self.update_parsed_node_config(node, config)\n                # env_vars should have been updated in the context env_var method\n            except ValidationError as exc:\n                # we got a ValidationError - probably bad types in config()\n                raise SchemaConfigError(exc, node=node) from exc\n\n        # Set attached_node for generic test nodes, if available.\n        # Generic test node inherits attached node's group config value.\n        attached_node = self._lookup_attached_node(builder.target, builder.version)\n        if attached_node:\n            node.attached_node = attached_node.unique_id\n            node.group, node.group = attached_node.group, attached_node.group\n\n    def parse_node(self, block: GenericTestBlock) -> GenericTestNode:\n        \"\"\"In schema parsing, we rewrite most of the part of parse_node that\n        builds the initial node to be parsed, but rendering is basically the\n        same\n        \"\"\"\n        node = self.parse_generic_test(\n            target=block.target,\n            data_test=block.data_test,\n            tags=block.tags,\n            column_name=block.column_name,\n            schema_file_id=block.file.file_id,\n            version=block.version,\n        )\n        self.add_test_node(block, node)\n        return node\n\n    def add_test_node(self, block: GenericTestBlock, node: GenericTestNode):\n        test_from = {\"key\": block.target.yaml_key, \"name\": block.target.name}\n        if node.config.enabled:\n            self.manifest.add_node(block.file, node, test_from)\n        else:\n            self.manifest.add_disabled(block.file, node, test_from)\n\n    def render_with_context(\n        self,\n        node: GenericTestNode,\n        config: ContextConfig,\n    ) -> None:\n        \"\"\"Given the parsed node and a ContextConfig to use during\n        parsing, collect all the refs that might be squirreled away in the test\n        arguments. This includes the implicit \"model\" argument.\n        \"\"\"\n        # make a base context that doesn't have the magic kwargs field\n        context = self._context_for(node, config)\n        # update it with the rendered test kwargs (which collects any refs)\n        add_rendered_test_kwargs(context, node, capture_macros=True)\n\n        # the parsed node is not rendered in the native context.\n        get_rendered(node.raw_code, context, node, capture_macros=True)\n\n    def parse_test(\n        self,\n        target_block: TestBlock,\n        data_test: TestDef,\n        column: Optional[UnparsedColumn],\n        version: Optional[NodeVersion],\n    ) -> None:\n        if isinstance(data_test, str):\n            data_test = {data_test: {}}\n\n        if column is None:\n            column_name: Optional[str] = None\n            column_tags: List[str] = []\n        else:\n            column_name = column.name\n            should_quote = column.quote or (column.quote is None and target_block.quote_columns)\n            if should_quote:\n                column_name = get_adapter(self.root_project).quote(column_name)\n\n            column_config_tags = column.config.get(\"tags\", [])\n            if isinstance(column_config_tags, str):\n                column_config_tags = [column_config_tags]\n            column_tags = list(set(column.tags + column_config_tags))\n\n        block = GenericTestBlock.from_test_block(\n            src=target_block,\n            data_test=data_test,\n            column_name=column_name,\n            tags=column_tags,\n            version=version,\n        )\n        self.parse_node(block)\n\n    def parse_tests(self, block: TestBlock) -> None:\n        for column in block.columns:\n            self.parse_column_tests(block, column, None)\n\n        for data_test in block.data_tests:\n            self.parse_test(block, data_test, None, None)\n\n    def parse_versioned_tests(self, block: VersionedTestBlock) -> None:\n        if not block.target.versions:\n            self.parse_tests(block)\n        else:\n            for version in block.target.versions:\n                for column in block.target.get_columns_for_version(version.v):\n                    self.parse_column_tests(block, column, version.v)\n\n                for test in block.target.get_tests_for_version(version.v):\n                    self.parse_test(block, test, None, version.v)\n\n    def generate_unique_id(self, resource_name: str, hash: Optional[str] = None) -> str:\n        return \".\".join(\n            filter(None, [self.resource_type, self.project.project_name, resource_name, hash])\n        )\n"
  },
  {
    "path": "core/dbt/parser/schema_renderer.py",
    "content": "from typing import Any, Dict\n\nfrom dbt.config.renderer import BaseRenderer, Keypath\n\n\n# This class renders dictionaries derived from \"schema\" yaml files.\n# It calls Jinja on strings (in deep_map_render), except for certain\n# keys which are skipped because they need to be rendered later\n# (tests and description). Test configs are rendered in the\n# generic test builder code, but skips the keyword args. The test\n# keyword args are rendered to capture refs in render_test_update.\n# Keyword args are finally rendered at compilation time.\n# Descriptions are not rendered until 'process_docs'.\n# Pre- and post-hooks in configs are late-rendered.\nclass SchemaYamlRenderer(BaseRenderer):\n    def __init__(self, context: Dict[str, Any], key: str) -> None:\n        super().__init__(context)\n        self.key = key\n\n    @property\n    def name(self):\n        return \"Rendering yaml\"\n\n    def _is_norender_key(self, keypath: Keypath) -> bool:\n        \"\"\"\n        models:\n            - name: blah\n              description: blah\n              data_tests: ...\n              columns:\n                - name:\n                  description: blah\n                  data_tests: ...\n\n        Return True if it's tests, data_tests or description - those aren't rendered now\n        because they're rendered later in parse_generic_tests or process_docs.\n        \"tests\" and \"data_tests\" are both currently supported but \"tests\" has been deprecated\n        \"\"\"\n        # top level descriptions and data_tests\n        if len(keypath) >= 1 and keypath[0] in (\n            \"tests\",\n            \"data_tests\",\n            \"description\",\n            \"loaded_at_query\",\n        ):\n            return True\n\n        # columns descriptions and data_tests\n        if len(keypath) == 2 and keypath[1] in (\n            \"tests\",\n            \"data_tests\",\n            \"description\",\n            \"loaded_at_query\",\n        ):\n            return True\n\n        # config: pre- and post-hooks, and loaded_at_query\n        if (\n            len(keypath) >= 2\n            and keypath[0] == \"config\"\n            and keypath[1] in (\"pre_hook\", \"post_hook\", \"loaded_at_query\")\n        ):\n            return True\n\n        # versions\n        if len(keypath) == 5 and keypath[4] == \"description\":\n            return True\n\n        if (\n            len(keypath) >= 3\n            and keypath[0] in (\"columns\", \"dimensions\", \"measures\", \"entities\", \"metrics\")\n            and keypath[2] in (\"tests\", \"data_tests\", \"description\")\n        ):\n            return True\n\n        # derived_semantics descriptions (v2 semantic layer)\n        if (\n            len(keypath) >= 4\n            and keypath[0] == \"derived_semantics\"\n            and keypath[1] in (\"dimensions\", \"entities\")\n            and keypath[3] in (\"tests\", \"data_tests\", \"description\")\n        ):\n            return True\n\n        return False\n\n    # don't render descriptions or test keyword arguments\n    def should_render_keypath(self, keypath: Keypath) -> bool:\n        if len(keypath) < 1:\n            return True\n        if self.key == \"sources\":\n            if keypath[0] in (\"description\", \"loaded_at_query\"):\n                return False\n            if len(keypath) >= 2 and keypath[0] == \"config\" and keypath[1] == \"loaded_at_query\":\n                return False\n            if keypath[0] == \"tables\":\n                if self._is_norender_key(keypath[2:]):\n                    return False\n        elif self.key == \"macros\":\n            if keypath[0] == \"arguments\":\n                if self._is_norender_key(keypath[1:]):\n                    return False\n            elif self._is_norender_key(keypath[0:]):\n                return False\n        elif self.key == \"metrics\":\n            # This ensures that metric filters are skipped\n            if keypath[-1] == \"filter\" or len(keypath) > 1 and keypath[-2] == \"filter\":\n                return False\n            elif self._is_norender_key(keypath[0:]):\n                return False\n        elif self.key == \"saved_queries\":\n            # This ensures that saved query filters are skipped\n            if keypath[0] == \"query_params\" and len(keypath) > 1 and keypath[1] == \"where\":\n                return False\n            elif self._is_norender_key(keypath[0:]):\n                return False\n        else:  # models, seeds, snapshots, analyses\n            # Skip metric filters — consistent with the \"metrics\" branch above,\n            # using positional checks to avoid over-matching.\n            # metrics is always at keypath[0] in this branch (model-relative path),\n            # and filter is always at [-1] (string) or [-2] (list item).\n            if keypath[0] == \"metrics\" and (\n                keypath[-1] == \"filter\" or (len(keypath) > 1 and keypath[-2] == \"filter\")\n            ):\n                return False\n            if self._is_norender_key(keypath[0:]):\n                return False\n        return True\n"
  },
  {
    "path": "core/dbt/parser/schema_yaml_readers.py",
    "content": "from collections.abc import Sequence\nfrom typing import Any, Dict, List, Optional, Union\n\nfrom dbt.artifacts.resources import (\n    ColumnDimension,\n    ColumnEntity,\n    ColumnInfo,\n    ConversionTypeParams,\n    CumulativeTypeParams,\n    Defaults,\n    Dimension,\n    DimensionTypeParams,\n    DimensionValidityParams,\n    Entity,\n    Export,\n    ExportConfig,\n    ExposureConfig,\n    Measure,\n    MeasureAggregationParameters,\n    MetricAggregationParams,\n    MetricConfig,\n    MetricInput,\n    MetricInputMeasure,\n    MetricTimeWindow,\n    MetricTypeParams,\n    NonAdditiveDimension,\n    QueryParams,\n    SavedQueryConfig,\n    SemanticLayerElementConfig,\n    WhereFilter,\n    WhereFilterIntersection,\n)\nfrom dbt.clients.jinja import get_rendered\nfrom dbt.context.context_config import (\n    BaseContextConfigGenerator,\n    ContextConfigGenerator,\n    UnrenderedConfigGenerator,\n)\nfrom dbt.context.providers import (\n    generate_parse_exposure,\n    generate_parse_semantic_models,\n)\nfrom dbt.contracts.files import SchemaSourceFile\nfrom dbt.contracts.graph.nodes import (\n    Exposure,\n    Group,\n    Metric,\n    ModelNode,\n    ParsedNodePatch,\n    SavedQuery,\n    SemanticModel,\n)\nfrom dbt.contracts.graph.unparsed import (\n    PercentileType,\n    UnparsedConversionTypeParams,\n    UnparsedCumulativeTypeParams,\n    UnparsedDerivedDimensionV2,\n    UnparsedDerivedSemantics,\n    UnparsedDimension,\n    UnparsedDimensionTypeParams,\n    UnparsedEntity,\n    UnparsedExport,\n    UnparsedExposure,\n    UnparsedGroup,\n    UnparsedMeasure,\n    UnparsedMetric,\n    UnparsedMetricBase,\n    UnparsedMetricInput,\n    UnparsedMetricInputMeasure,\n    UnparsedMetricTypeParams,\n    UnparsedMetricV2,\n    UnparsedNonAdditiveDimension,\n    UnparsedNonAdditiveDimensionV2,\n    UnparsedQueryParams,\n    UnparsedSavedQuery,\n    UnparsedSemanticModel,\n    UnparsedSemanticModelConfig,\n    UnparsedSemanticResourceConfig,\n)\nfrom dbt.exceptions import JSONValidationError, YamlParseDictError\nfrom dbt.node_types import NodeType\nfrom dbt.parser.common import YamlBlock\nfrom dbt.parser.schemas import ParseResult, SchemaParser, YamlReader\nfrom dbt_common.dataclass_schema import ValidationError\nfrom dbt_common.exceptions import DbtInternalError\nfrom dbt_semantic_interfaces.type_enums import (\n    AggregationType,\n    ConversionCalculationType,\n    DimensionType,\n    EntityType,\n    MetricType,\n    PeriodAggregation,\n    TimeGranularity,\n)\n\n\ndef parse_where_filter(\n    where: Optional[Union[List[str], str]],\n) -> Optional[WhereFilterIntersection]:\n    if where is None:\n        return None\n    elif isinstance(where, str):\n        return WhereFilterIntersection([WhereFilter(where)])\n    else:\n        return WhereFilterIntersection([WhereFilter(where_str) for where_str in where])\n\n\nclass ExposureParser(YamlReader):\n    def __init__(self, schema_parser: SchemaParser, yaml: YamlBlock) -> None:\n        super().__init__(schema_parser, yaml, NodeType.Exposure.pluralize())\n        self.schema_parser = schema_parser\n        self.yaml = yaml\n\n    def parse_exposure(self, unparsed: UnparsedExposure) -> None:\n        package_name = self.project.project_name\n        unique_id = f\"{NodeType.Exposure}.{package_name}.{unparsed.name}\"\n        path = self.yaml.path.relative_path\n\n        fqn = self.schema_parser.get_fqn_prefix(path)\n        fqn.append(unparsed.name)\n\n        config = self._generate_exposure_config(\n            target=unparsed,\n            fqn=fqn,\n            package_name=package_name,\n            rendered=True,\n        )\n\n        config = config.finalize_and_validate()\n\n        unrendered_config = self._generate_exposure_config(\n            target=unparsed,\n            fqn=fqn,\n            package_name=package_name,\n            rendered=False,\n        )\n\n        if not isinstance(config, ExposureConfig):\n            raise DbtInternalError(\n                f\"Calculated a {type(config)} for an exposure, but expected an ExposureConfig\"\n            )\n\n        tags = sorted(set(self.project.exposures.get(\"tags\", []) + unparsed.tags + config.tags))\n        meta = {**self.project.exposures.get(\"meta\", {}), **unparsed.meta, **config.meta}\n\n        config.tags = tags\n        config.meta = meta\n\n        parsed = Exposure(\n            resource_type=NodeType.Exposure,\n            package_name=package_name,\n            path=path,\n            original_file_path=self.yaml.path.original_file_path,\n            unique_id=unique_id,\n            fqn=fqn,\n            name=unparsed.name,\n            type=unparsed.type,\n            url=unparsed.url,\n            meta=meta,\n            tags=tags,\n            description=unparsed.description,\n            label=unparsed.label,\n            owner=unparsed.owner,\n            maturity=unparsed.maturity,\n            config=config,\n            unrendered_config=unrendered_config,\n        )\n        ctx = generate_parse_exposure(\n            parsed,\n            self.root_project,\n            self.schema_parser.manifest,\n            package_name,\n        )\n        depends_on_jinja = \"\\n\".join(\"{{ \" + line + \"}}\" for line in unparsed.depends_on)\n        get_rendered(depends_on_jinja, ctx, parsed, capture_macros=True)\n        # parsed now has a populated refs/sources/metrics\n\n        assert isinstance(self.yaml.file, SchemaSourceFile)\n        if parsed.config.enabled:\n            self.manifest.add_exposure(self.yaml.file, parsed)\n        else:\n            self.manifest.add_disabled(self.yaml.file, parsed)\n\n    def _generate_exposure_config(\n        self, target: UnparsedExposure, fqn: List[str], package_name: str, rendered: bool\n    ):\n        generator: BaseContextConfigGenerator\n        if rendered:\n            generator = ContextConfigGenerator(self.root_project)\n        else:\n            generator = UnrenderedConfigGenerator(self.root_project)\n\n        # configs with precendence set\n        precedence_configs = dict()\n        # apply exposure configs\n        precedence_configs.update(target.config)\n\n        return generator.calculate_node_config(\n            config_call_dict={},\n            fqn=fqn,\n            resource_type=NodeType.Exposure,\n            project_name=package_name,\n            base=False,\n            patch_config_dict=precedence_configs,\n        )\n\n    def parse(self) -> None:\n        for data in self.get_key_dicts():\n            try:\n                UnparsedExposure.validate(data)\n                unparsed = UnparsedExposure.from_dict(data)\n            except (ValidationError, JSONValidationError) as exc:\n                raise YamlParseDictError(self.yaml.path, self.key, data, exc)\n\n            self.parse_exposure(unparsed)\n\n\nclass MetricParser(YamlReader):\n    def __init__(self, schema_parser: SchemaParser, yaml: YamlBlock) -> None:\n        super().__init__(schema_parser, yaml, NodeType.Metric.pluralize())\n        self.schema_parser = schema_parser\n        self.yaml = yaml\n\n    def _get_input_measure(\n        self,\n        unparsed_input_measure: Union[UnparsedMetricInputMeasure, str],\n    ) -> MetricInputMeasure:\n        if isinstance(unparsed_input_measure, str):\n            return MetricInputMeasure(name=unparsed_input_measure)\n        else:\n            return MetricInputMeasure(\n                name=unparsed_input_measure.name,\n                filter=parse_where_filter(unparsed_input_measure.filter),\n                alias=unparsed_input_measure.alias,\n                join_to_timespine=unparsed_input_measure.join_to_timespine,\n                fill_nulls_with=unparsed_input_measure.fill_nulls_with,\n            )\n\n    def _get_optional_input_measure(\n        self,\n        unparsed_input_measure: Optional[Union[UnparsedMetricInputMeasure, str]],\n    ) -> Optional[MetricInputMeasure]:\n        if unparsed_input_measure is not None:\n            return self._get_input_measure(unparsed_input_measure)\n        else:\n            return None\n\n    def _get_input_measures(\n        self,\n        unparsed_input_measures: Optional[List[Union[UnparsedMetricInputMeasure, str]]],\n    ) -> List[MetricInputMeasure]:\n        input_measures: List[MetricInputMeasure] = []\n        if unparsed_input_measures is not None:\n            for unparsed_input_measure in unparsed_input_measures:\n                input_measures.append(self._get_input_measure(unparsed_input_measure))\n\n        return input_measures\n\n    def _get_period_agg(self, unparsed_period_agg: str) -> PeriodAggregation:\n        return PeriodAggregation(unparsed_period_agg)\n\n    def _get_optional_time_window(\n        self, unparsed_window: Optional[str]\n    ) -> Optional[MetricTimeWindow]:\n        if unparsed_window is not None:\n            parts = unparsed_window.lower().split(\" \")\n            if len(parts) != 2:\n                raise YamlParseDictError(\n                    self.yaml.path,\n                    \"window\",\n                    {\"window\": unparsed_window},\n                    f\"Invalid window ({unparsed_window}) in cumulative/conversion metric. Should be of the form `<count> <granularity>`, \"\n                    \"e.g., `28 days`\",\n                )\n\n            granularity = parts[1]\n            # once we drop python 3.8 this could just be `granularity = parts[0].removesuffix('s')\n            if granularity.endswith(\"s\") and granularity[:-1] in [\n                item.value for item in TimeGranularity\n            ]:\n                # Can only remove the `s` if it's a standard grain, months -> month\n                granularity = granularity[:-1]\n\n            count = parts[0]\n            if not count.isdigit():\n                raise YamlParseDictError(\n                    self.yaml.path,\n                    \"window\",\n                    {\"window\": unparsed_window},\n                    f\"Invalid count ({count}) in cumulative/conversion metric window string: ({unparsed_window})\",\n                )\n\n            return MetricTimeWindow(\n                count=int(count),\n                granularity=granularity,\n            )\n        else:\n            return None\n\n    def _get_metric_input(self, unparsed: Union[UnparsedMetricInput, str]) -> MetricInput:\n        if isinstance(unparsed, str):\n            return MetricInput(name=unparsed)\n        else:\n            return MetricInput(\n                name=unparsed.name,\n                filter=parse_where_filter(unparsed.filter),\n                alias=unparsed.alias,\n                offset_window=self._get_optional_time_window(unparsed.offset_window),\n                offset_to_grain=unparsed.offset_to_grain,\n            )\n\n    def _get_optional_metric_input(\n        self,\n        unparsed: Optional[Union[UnparsedMetricInput, str]],\n    ) -> Optional[MetricInput]:\n        if unparsed is not None:\n            return self._get_metric_input(unparsed)\n        else:\n            return None\n\n    def _get_metric_inputs(\n        self,\n        unparsed_metric_inputs: Optional[List[Union[UnparsedMetricInput, str]]],\n    ) -> List[MetricInput]:\n        metric_inputs: List[MetricInput] = []\n        if unparsed_metric_inputs is not None:\n            for unparsed_metric_input in unparsed_metric_inputs:\n                metric_inputs.append(self._get_metric_input(unparsed=unparsed_metric_input))\n\n        return metric_inputs\n\n    def _get_optional_v1_conversion_type_params(\n        self, unparsed: Optional[UnparsedConversionTypeParams]\n    ) -> Optional[ConversionTypeParams]:\n        if unparsed is None:\n            return None\n        if unparsed.base_measure is None:\n            raise ValidationError(\n                \"base_measure is required for conversion metrics that use type_params.\"\n            )\n        if unparsed.conversion_measure is None:\n            raise ValidationError(\n                \"conversion_measure is required for conversion metrics that use type_params.\"\n            )\n        return ConversionTypeParams(\n            base_measure=self._get_input_measure(unparsed.base_measure),\n            conversion_measure=self._get_input_measure(unparsed.conversion_measure),\n            entity=unparsed.entity,\n            calculation=ConversionCalculationType(unparsed.calculation),\n            window=self._get_optional_time_window(unparsed.window),\n            constant_properties=unparsed.constant_properties,\n        )\n\n    def _get_optional_v2_conversion_type_params(\n        self,\n        unparsed_metric: UnparsedMetricV2,\n    ) -> Optional[ConversionTypeParams]:\n        if MetricType(unparsed_metric.type) is not MetricType.CONVERSION:\n            return None\n\n        if unparsed_metric.base_metric is None:\n            raise ValidationError(\"base_metric is required for conversion metrics.\")\n        if unparsed_metric.conversion_metric is None:\n            raise ValidationError(\"conversion_metric is required for conversion metrics.\")\n        if unparsed_metric.entity is None:\n            raise ValidationError(\"entity is required for conversion metrics.\")\n\n        return ConversionTypeParams(\n            base_metric=self._get_metric_input(unparsed_metric.base_metric),\n            conversion_metric=self._get_metric_input(unparsed_metric.conversion_metric),\n            entity=unparsed_metric.entity,\n            calculation=ConversionCalculationType(unparsed_metric.calculation),\n            window=self._get_optional_time_window(unparsed_metric.window),\n            constant_properties=unparsed_metric.constant_properties,\n        )\n\n    def _get_optional_v1_cumulative_type_params(\n        self, unparsed_metric: UnparsedMetric\n    ) -> Optional[CumulativeTypeParams]:\n        unparsed_type_params = unparsed_metric.type_params\n        if unparsed_metric.type.lower() == MetricType.CUMULATIVE.value:\n            if not unparsed_type_params.cumulative_type_params:\n                unparsed_type_params.cumulative_type_params = UnparsedCumulativeTypeParams()\n\n            if (\n                unparsed_type_params.window\n                and not unparsed_type_params.cumulative_type_params.window\n            ):\n                unparsed_type_params.cumulative_type_params.window = unparsed_type_params.window\n            if (\n                unparsed_type_params.grain_to_date\n                and not unparsed_type_params.cumulative_type_params.grain_to_date\n            ):\n                unparsed_type_params.cumulative_type_params.grain_to_date = (\n                    unparsed_type_params.grain_to_date\n                )\n\n            return CumulativeTypeParams(\n                window=self._get_optional_time_window(\n                    unparsed_type_params.cumulative_type_params.window\n                ),\n                grain_to_date=unparsed_type_params.cumulative_type_params.grain_to_date,\n                period_agg=self._get_period_agg(\n                    unparsed_type_params.cumulative_type_params.period_agg\n                ),\n            )\n\n        return None\n\n    def _get_optional_v2_cumulative_type_params(\n        self,\n        unparsed_metric: UnparsedMetricV2,\n    ) -> Optional[CumulativeTypeParams]:\n        if MetricType(unparsed_metric.type) is not MetricType.CUMULATIVE:\n            return None\n        input_metric = unparsed_metric.input_metric\n        if input_metric is None:\n            raise ValidationError(\"input_metric is required for cumulative metrics.\")\n        return CumulativeTypeParams(\n            window=self._get_optional_time_window(unparsed_metric.window),\n            grain_to_date=unparsed_metric.grain_to_date,\n            period_agg=self._get_period_agg(unparsed_metric.period_agg),\n            metric=self._get_metric_input(input_metric),\n        )\n\n    def _get_v2_non_additive_dimension(\n        self,\n        unparsed_non_additive_dimension: Optional[UnparsedNonAdditiveDimensionV2],\n    ) -> Optional[NonAdditiveDimension]:\n        if unparsed_non_additive_dimension is None:\n            return None\n        return NonAdditiveDimension(\n            name=unparsed_non_additive_dimension.name,\n            window_choice=AggregationType(unparsed_non_additive_dimension.window_agg),\n            window_groupings=unparsed_non_additive_dimension.group_by,\n        )\n\n    def _get_metric_type_params(\n        self,\n        unparsed_metric: UnparsedMetricBase,\n        generated_from: Optional[str] = None,\n        default_agg_time_dimension: Optional[str] = None,\n    ) -> MetricTypeParams:\n        if isinstance(unparsed_metric, UnparsedMetric):\n            type_params = unparsed_metric.type_params\n\n            grain_to_date: Optional[TimeGranularity] = None\n            if type_params.grain_to_date is not None:\n                # This should've been changed to a string (to support custom grain), but since this\n                # is a legacy field waiting to be deprecated, we will not support custom grain here\n                # in order to force customers off of using this field. The field to use should be\n                # `cumulative_type_params.grain_to_date`\n                grain_to_date = TimeGranularity(type_params.grain_to_date)\n\n            return MetricTypeParams(\n                measure=self._get_optional_input_measure(type_params.measure),\n                numerator=self._get_optional_metric_input(type_params.numerator),\n                denominator=self._get_optional_metric_input(type_params.denominator),\n                expr=str(type_params.expr) if type_params.expr is not None else None,\n                window=self._get_optional_time_window(type_params.window),\n                grain_to_date=grain_to_date,\n                metrics=self._get_metric_inputs(type_params.metrics),\n                conversion_type_params=self._get_optional_v1_conversion_type_params(\n                    type_params.conversion_type_params\n                ),\n                cumulative_type_params=self._get_optional_v1_cumulative_type_params(\n                    unparsed_metric=unparsed_metric,\n                ),\n                # input measures are calculated via metric processing post parsing\n                # input_measures=?,\n            )\n        elif isinstance(unparsed_metric, UnparsedMetricV2):\n            if unparsed_metric.agg is not None:\n                if generated_from is None:\n                    raise YamlParseDictError(\n                        self.yaml.path,\n                        self.key,\n                        yaml_data=unparsed_metric.to_dict(),\n                        cause=\"simple metrics in v2 YAML must be attached to semantic_model\",\n                    )\n                metric_aggregation_params = MetricAggregationParams(\n                    semantic_model=generated_from,\n                    agg=AggregationType(unparsed_metric.agg),\n                    agg_params=MeasureAggregationParameters(\n                        percentile=unparsed_metric.percentile,\n                        use_discrete_percentile=(unparsed_metric.percentile_type or \"\").lower()\n                        == PercentileType.DISCRETE,\n                        use_approximate_percentile=(unparsed_metric.percentile_type or \"\").lower()\n                        == PercentileType.CONTINUOUS,\n                    ),\n                    agg_time_dimension=unparsed_metric.agg_time_dimension\n                    or default_agg_time_dimension,\n                    non_additive_dimension=self._get_v2_non_additive_dimension(\n                        unparsed_non_additive_dimension=unparsed_metric.non_additive_dimension,\n                    ),\n                )\n            else:\n                metric_aggregation_params = None\n            return MetricTypeParams(\n                numerator=self._get_optional_metric_input(unparsed_metric.numerator),\n                denominator=self._get_optional_metric_input(unparsed_metric.denominator),\n                expr=str(unparsed_metric.expr) if unparsed_metric.expr is not None else None,\n                window=self._get_optional_time_window(unparsed_metric.window),\n                metrics=self._get_metric_inputs(unparsed_metric.input_metrics),\n                conversion_type_params=self._get_optional_v2_conversion_type_params(\n                    unparsed_metric=unparsed_metric,\n                ),\n                cumulative_type_params=self._get_optional_v2_cumulative_type_params(\n                    unparsed_metric=unparsed_metric,\n                ),\n                metric_aggregation_params=metric_aggregation_params,\n                join_to_timespine=unparsed_metric.join_to_timespine or False,\n                is_private=unparsed_metric.hidden,\n            )\n        else:\n            raise DbtInternalError(\n                f\"Tried to parse type params for a {type(unparsed_metric)}, but expected \"\n                \"an UnparsedMetric or UnparsedMetricV2\",\n            )\n\n    def parse_metric(\n        self,\n        unparsed: UnparsedMetricBase,\n        generated_from: Optional[str] = None,\n        default_agg_time_dimension: Optional[str] = None,\n    ) -> None:\n        package_name = self.project.project_name\n        unique_id = f\"{NodeType.Metric}.{package_name}.{unparsed.name}\"\n        path = self.yaml.path.relative_path\n\n        fqn = self.schema_parser.get_fqn_prefix(path)\n        fqn.append(unparsed.name)\n\n        config = self._generate_metric_config(\n            target=unparsed,\n            fqn=fqn,\n            package_name=package_name,\n            rendered=True,\n        )\n\n        config = config.finalize_and_validate()\n\n        unrendered_config = self._generate_metric_config(\n            target=unparsed,\n            fqn=fqn,\n            package_name=package_name,\n            rendered=False,\n        )\n\n        if not isinstance(config, MetricConfig):\n            raise DbtInternalError(\n                f\"Calculated a {type(config)} for a metric, but expected a MetricConfig\"\n            )\n\n        if isinstance(unparsed, UnparsedMetric):\n            # If we have meta in the config, copy to node level, for backwards\n            # compatibility with earlier node-only config.\n            if \"meta\" in config and config[\"meta\"]:\n                unparsed.meta = config[\"meta\"]\n            meta = unparsed.meta\n            tags = unparsed.tags\n        elif isinstance(unparsed, UnparsedMetricV2):\n            # V2 Metrics do not have a top-level meta field; this should be part of\n            # the config.\n            meta = {}\n            tags = []\n        else:\n            raise DbtInternalError(\n                f\"Tried to parse a {type(unparsed)} into a metric, but expected \"\n                \"an UnparsedMetric or UnparsedMetricV2\",\n            )\n\n        parsed = Metric(\n            resource_type=NodeType.Metric,\n            package_name=package_name,\n            path=path,\n            original_file_path=self.yaml.path.original_file_path,\n            unique_id=unique_id,\n            fqn=fqn,\n            name=unparsed.name,\n            description=unparsed.description,\n            label=unparsed.label or unparsed.name,\n            type=MetricType(unparsed.type),\n            type_params=self._get_metric_type_params(\n                unparsed,\n                generated_from=generated_from,\n                default_agg_time_dimension=default_agg_time_dimension,\n            ),\n            time_granularity=unparsed.time_granularity,\n            filter=parse_where_filter(unparsed.filter),\n            meta=meta,\n            tags=tags,\n            config=config,\n            unrendered_config=unrendered_config,\n            group=config.group,\n        )\n\n        # if the metric is disabled we do not want it included in the manifest, only in the disabled dict\n        assert isinstance(self.yaml.file, SchemaSourceFile)\n        if parsed.config.enabled:\n            self.manifest.add_metric(self.yaml.file, parsed, generated_from)\n        else:\n            self.manifest.add_disabled(self.yaml.file, parsed)\n\n    def _generate_metric_config(\n        self, target: UnparsedMetricBase, fqn: List[str], package_name: str, rendered: bool\n    ):\n        generator: BaseContextConfigGenerator\n        if rendered:\n            generator = ContextConfigGenerator(self.root_project)\n        else:\n            generator = UnrenderedConfigGenerator(self.root_project)\n\n        # configs with precendence set\n        precedence_configs = dict()\n        # first apply metric configs\n        precedence_configs.update(target.config)\n\n        config = generator.calculate_node_config(\n            config_call_dict={},\n            fqn=fqn,\n            resource_type=NodeType.Metric,\n            project_name=package_name,\n            base=False,\n            patch_config_dict=precedence_configs,\n        )\n        return config\n\n    def _parse_v2_metric(\n        self, data: dict[str, Any], semantic_model_name: Optional[str] = None\n    ) -> None:\n        try:\n            UnparsedMetricV2.validate(data)\n            unparsed = UnparsedMetricV2.from_dict(data)\n        except (ValidationError, JSONValidationError) as exc:\n            raise YamlParseDictError(self.yaml.path, self.key, data, exc)\n        self.parse_metric(unparsed=unparsed)\n\n    def parse_v2_metrics_from_dbt_model_patch(self, model_patch: ParsedNodePatch) -> None:\n        if model_patch.metrics is None:\n            return\n        # Resolve the semantic model name, respecting custom name overrides\n        semantic_model_name = model_patch.name\n        if isinstance(model_patch.semantic_model, UnparsedSemanticModelConfig):\n            if model_patch.semantic_model.name is not None:\n                semantic_model_name = model_patch.semantic_model.name\n        for metric in model_patch.metrics:\n            is_simple = MetricType(metric.type) == MetricType.SIMPLE\n            semantic_model = semantic_model_name if is_simple else None\n            self.parse_metric(\n                metric,\n                generated_from=semantic_model,\n                default_agg_time_dimension=model_patch.agg_time_dimension if is_simple else None,\n            )\n\n    def parse(self) -> None:\n        for data in self.get_key_dicts():\n            # The main differentiator of old-style yaml and new-style is \"type_params\",\n            # so if that is missing, we'll assume you're using the newer yaml.\n            if \"type_params\" in data:\n                try:\n                    UnparsedMetric.validate(data)\n                    unparsed = UnparsedMetric.from_dict(data)\n                except (ValidationError, JSONValidationError) as exc:\n                    raise YamlParseDictError(self.yaml.path, self.key, data, exc)\n                self.parse_metric(unparsed)\n            else:\n                self._parse_v2_metric(data)\n\n\nclass GroupParser(YamlReader):\n    def __init__(self, schema_parser: SchemaParser, yaml: YamlBlock) -> None:\n        super().__init__(schema_parser, yaml, NodeType.Group.pluralize())\n        self.schema_parser = schema_parser\n        self.yaml = yaml\n\n    def parse_group(self, unparsed: UnparsedGroup) -> None:\n        package_name = self.project.project_name\n        unique_id = f\"{NodeType.Group}.{package_name}.{unparsed.name}\"\n        path = self.yaml.path.relative_path\n\n        fqn = self.schema_parser.get_fqn_prefix(path)\n        fqn.append(unparsed.name)\n        config = self._generate_group_config(unparsed, fqn, package_name, True)\n\n        parsed = Group(\n            resource_type=NodeType.Group,\n            package_name=package_name,\n            path=path,\n            original_file_path=self.yaml.path.original_file_path,\n            unique_id=unique_id,\n            name=unparsed.name,\n            owner=unparsed.owner,\n            description=unparsed.description,\n            config=config,\n        )\n\n        assert isinstance(self.yaml.file, SchemaSourceFile)\n        self.manifest.add_group(self.yaml.file, parsed)\n\n    def parse(self):\n        for data in self.get_key_dicts():\n            try:\n                UnparsedGroup.validate(data)\n                unparsed = UnparsedGroup.from_dict(data)\n            except (ValidationError, JSONValidationError) as exc:\n                raise YamlParseDictError(self.yaml.path, self.key, data, exc)\n\n            self.parse_group(unparsed)\n\n    def _generate_group_config(\n        self, target: UnparsedGroup, fqn: List[str], package_name: str, rendered: bool\n    ):\n        generator: BaseContextConfigGenerator\n        if rendered:\n            generator = ContextConfigGenerator(self.root_project)\n        else:\n            generator = UnrenderedConfigGenerator(self.root_project)\n\n        # configs with precendence set\n        precedence_configs = dict()\n        # first apply metric configs\n        precedence_configs.update(target.config)\n\n        config = generator.calculate_node_config(\n            config_call_dict={},\n            fqn=fqn,\n            resource_type=NodeType.Group,\n            project_name=package_name,\n            base=False,\n            patch_config_dict=precedence_configs,\n        )\n        return config\n\n\nclass SemanticModelParser(YamlReader):\n    def __init__(self, schema_parser: SchemaParser, yaml: YamlBlock) -> None:\n        super().__init__(schema_parser, yaml, \"semantic_models\")\n        self.schema_parser = schema_parser\n        self.yaml = yaml\n\n    def _get_dimension_type_params(\n        self, unparsed: Optional[UnparsedDimensionTypeParams]\n    ) -> Optional[DimensionTypeParams]:\n        if unparsed is not None:\n            return DimensionTypeParams(\n                time_granularity=TimeGranularity(unparsed.time_granularity),\n                validity_params=unparsed.validity_params,\n            )\n        else:\n            return None\n\n    def _get_dimensions(self, unparsed_dimensions: List[UnparsedDimension]) -> List[Dimension]:\n        dimensions: List[Dimension] = []\n        for unparsed in unparsed_dimensions:\n            dimensions.append(\n                Dimension(\n                    name=unparsed.name,\n                    type=DimensionType(unparsed.type),\n                    description=unparsed.description,\n                    label=unparsed.label,\n                    is_partition=unparsed.is_partition,\n                    type_params=self._get_dimension_type_params(unparsed=unparsed.type_params),\n                    expr=unparsed.expr,\n                    metadata=None,  # TODO: requires a fair bit of parsing context\n                    config=SemanticLayerElementConfig(meta=unparsed.config.get(\"meta\", {})),\n                )\n            )\n        return dimensions\n\n    def _get_entities(self, unparsed_entities: List[UnparsedEntity]) -> List[Entity]:\n        entities: List[Entity] = []\n        for unparsed in unparsed_entities:\n            entities.append(\n                Entity(\n                    name=unparsed.name,\n                    type=EntityType(unparsed.type),\n                    description=unparsed.description,\n                    label=unparsed.label,\n                    role=unparsed.role,\n                    expr=unparsed.expr,\n                    config=SemanticLayerElementConfig(meta=unparsed.config.get(\"meta\", {})),\n                )\n            )\n\n        return entities\n\n    def _get_non_additive_dimension(\n        self, unparsed: Optional[UnparsedNonAdditiveDimension]\n    ) -> Optional[NonAdditiveDimension]:\n        if unparsed is not None:\n            return NonAdditiveDimension(\n                name=unparsed.name,\n                window_choice=AggregationType(unparsed.window_choice),\n                window_groupings=unparsed.window_groupings,\n            )\n        else:\n            return None\n\n    def _get_measures(self, unparsed_measures: List[UnparsedMeasure]) -> List[Measure]:\n        measures: List[Measure] = []\n        for unparsed in unparsed_measures:\n            measures.append(\n                Measure(\n                    name=unparsed.name,\n                    agg=AggregationType(unparsed.agg),\n                    description=unparsed.description,\n                    label=unparsed.label,\n                    expr=str(unparsed.expr) if unparsed.expr is not None else None,\n                    agg_params=unparsed.agg_params,\n                    non_additive_dimension=self._get_non_additive_dimension(\n                        unparsed.non_additive_dimension\n                    ),\n                    agg_time_dimension=unparsed.agg_time_dimension,\n                    config=SemanticLayerElementConfig(meta=unparsed.config.get(\"meta\", {})),\n                )\n            )\n        return measures\n\n    def _create_metric(\n        self,\n        measure: UnparsedMeasure,\n        enabled: bool,\n        semantic_model_name: str,\n        meta: Optional[Dict[str, Any]] = None,\n    ) -> None:\n        config: Dict[str, Any] = {\"enabled\": enabled}\n        if meta is not None:\n            # Need to propagate meta to metric from measure during create_metric: True\n            config[\"meta\"] = meta\n        unparsed_metric = UnparsedMetric(\n            name=measure.name,\n            label=measure.label or measure.name,\n            type=\"simple\",\n            type_params=UnparsedMetricTypeParams(\n                measure=measure.name, expr=measure.expr or measure.name  # type: ignore\n            ),\n            description=measure.description or f\"Metric created from measure {measure.name}\",\n            config=config,\n        )\n\n        parser = MetricParser(self.schema_parser, yaml=self.yaml)\n        parser.parse_metric(unparsed=unparsed_metric, generated_from=semantic_model_name)\n\n    def _generate_semantic_model_config(\n        self,\n        target_config: Dict[str, Any],\n        fqn: List[str],\n        package_name: str,\n        rendered: bool,\n    ):\n        generator: BaseContextConfigGenerator\n        if rendered:\n            generator = ContextConfigGenerator(self.root_project)\n        else:\n            generator = UnrenderedConfigGenerator(self.root_project)\n\n        # configs with precendence set\n        precedence_configs = dict()\n        # first apply semantic model configs\n        precedence_configs.update(target_config)\n\n        config = generator.calculate_node_config(\n            config_call_dict={},\n            fqn=fqn,\n            resource_type=NodeType.SemanticModel,\n            project_name=package_name,\n            base=False,\n            patch_config_dict=precedence_configs,\n        )\n\n        return config\n\n    def _parse_semantic_model_v1(self, unparsed: UnparsedSemanticModel) -> None:\n        entities = self._get_entities(unparsed.entities)\n        measures = self._get_measures(unparsed.measures)\n        dimensions = self._get_dimensions(unparsed.dimensions)\n\n        self._parse_semantic_model_helper(\n            semantic_model_name=unparsed.name,\n            semantic_model_config=unparsed.config,\n            description=unparsed.description,\n            label=unparsed.label,\n            model=unparsed.model,\n            defaults=unparsed.defaults,\n            primary_entity=unparsed.primary_entity,\n            entities=entities,\n            measures=measures,\n            unparsed_measures=unparsed.measures,\n            dimensions=dimensions,\n        )\n\n    def _parse_v2_column_dimensions(self, columns: Dict[str, ColumnInfo]) -> List[Dimension]:\n        dimensions: List[Dimension] = []\n        for column in columns.values():\n            if column.dimension is None:\n                continue\n            elif isinstance(column.dimension, DimensionType):\n                dimensions.append(\n                    Dimension(\n                        name=column.name,\n                        type=column.dimension,\n                        description=column.description,\n                        metadata=None,  # Not yet supported in v1 or v2 YAML\n                        config=SemanticLayerElementConfig(meta=column.config.get(\"meta\", {})),\n                    )\n                )\n            elif isinstance(column.dimension, ColumnDimension):\n                type_params = (\n                    (\n                        DimensionTypeParams(\n                            time_granularity=column.granularity,\n                            validity_params=(\n                                DimensionValidityParams(\n                                    is_start=column.dimension.validity_params.is_start,\n                                    is_end=column.dimension.validity_params.is_end,\n                                )\n                                if column.dimension.validity_params is not None\n                                else None\n                            ),\n                        )\n                        if column.granularity is not None\n                        else None\n                    )\n                    if column.granularity is not None\n                    else None\n                )\n                meta = dict(column.config.get(\"meta\", {}))\n                meta.update((column.dimension.config or {}).get(\"meta\", {}))\n                config = SemanticLayerElementConfig(meta=meta)\n                dimension_name = column.dimension.name or column.name\n                dimensions.append(\n                    Dimension(\n                        # required\n                        type=DimensionType(column.dimension.type),\n                        # fields that use column's values as fallback values\n                        name=dimension_name,\n                        description=column.dimension.description or column.description,\n                        config=config,\n                        # optional fields\n                        label=column.dimension.label,\n                        is_partition=column.dimension.is_partition,\n                        type_params=type_params,\n                        metadata=None,  # Not yet supported in v1 or v2 YAML\n                        # When the dimension name differs from the column name, set expr\n                        # to the column name so MetricFlow queries the correct warehouse column.\n                        expr=column.name if dimension_name != column.name else None,\n                    )\n                )\n        return dimensions\n\n    def _parse_v2_derived_dimensions(\n        self,\n        derived_dimensions: List[UnparsedDerivedDimensionV2],\n    ) -> List[Dimension]:\n        dimensions: List[Dimension] = []\n        for derived_dimension in derived_dimensions:\n            type_params = None\n            if derived_dimension.granularity is not None:\n                type_params = DimensionTypeParams(\n                    time_granularity=TimeGranularity(derived_dimension.granularity),\n                    validity_params=(\n                        DimensionValidityParams(\n                            is_start=derived_dimension.validity_params.is_start,\n                            is_end=derived_dimension.validity_params.is_end,\n                        )\n                        if derived_dimension.validity_params is not None\n                        else None\n                    ),\n                )\n            dimensions.append(\n                Dimension(\n                    type=DimensionType(derived_dimension.type),\n                    name=derived_dimension.name,\n                    description=derived_dimension.description,\n                    label=derived_dimension.label,\n                    is_partition=derived_dimension.is_partition,\n                    config=SemanticLayerElementConfig(\n                        meta=derived_dimension.config.get(\"meta\", {})\n                    ),\n                    type_params=type_params,\n                    # fields unique to derived dimensions\n                    expr=derived_dimension.expr,\n                )\n            )\n        return dimensions\n\n    def _parse_v2_column_entities(self, columns: Dict[str, ColumnInfo]) -> List[Entity]:\n        entities: List[Entity] = []\n        for column in columns.values():\n            if column.entity is None:\n                continue\n            elif isinstance(column.entity, ColumnEntity):\n                entities.append(\n                    Entity(\n                        name=column.entity.name,\n                        type=column.entity.type,\n                        description=column.entity.description,\n                        label=column.entity.label,\n                        # When the entity name differs from the column name, set expr\n                        # to the column name so MetricFlow queries the correct warehouse column.\n                        expr=column.name if column.entity.name != column.name else None,\n                        config=SemanticLayerElementConfig(\n                            meta=column.entity.config.get(\"meta\", column.config.get(\"meta\", {}))\n                        ),\n                    )\n                )\n            elif isinstance(column.entity, EntityType):\n                entities.append(\n                    Entity(\n                        name=column.name,\n                        type=column.entity,\n                        description=column.description,\n                        label=None,  # there's no label to carry through from columns\n                        config=SemanticLayerElementConfig(meta=column.config.get(\"meta\", {})),\n                    )\n                )\n        return entities\n\n    def _parse_v2_derived_semantics_entities(\n        self, derived_semantics: UnparsedDerivedSemantics\n    ) -> List[Entity]:\n        entities: List[Entity] = []\n        for unparsed_entity in derived_semantics.entities:\n            entities.append(\n                Entity(\n                    name=unparsed_entity.name,\n                    type=EntityType(unparsed_entity.type),\n                    description=unparsed_entity.description,\n                    label=unparsed_entity.label,\n                    expr=unparsed_entity.expr,\n                    config=SemanticLayerElementConfig(meta=unparsed_entity.config.get(\"meta\", {})),\n                )\n            )\n        return entities\n\n    def parse_v2_semantic_model_from_dbt_model_patch(\n        self,\n        node: ModelNode,\n        patch: ParsedNodePatch,\n    ) -> None:\n        if patch.semantic_model is None:\n            # We shouldn't be calling this method in this case, but for safety\n            # and typechecking, we'll return early here.\n            return\n\n        dimensions = self._parse_v2_column_dimensions(patch.columns)\n        if patch.derived_semantics is not None:\n            dimensions.extend(\n                self._parse_v2_derived_dimensions(patch.derived_semantics.dimensions)\n            )\n        entities = self._parse_v2_column_entities(patch.columns)\n        if patch.derived_semantics is not None:\n            entities.extend(self._parse_v2_derived_semantics_entities(patch.derived_semantics))\n\n        name = node.name\n        config: Dict[str, Any] = {}\n        if isinstance(patch.semantic_model, UnparsedSemanticModelConfig):\n            if patch.semantic_model.name is not None:\n                name = patch.semantic_model.name\n            if patch.semantic_model.config is not None:\n                unparsed_sub_config = patch.semantic_model.config\n                if isinstance(unparsed_sub_config, UnparsedSemanticResourceConfig):\n                    if unparsed_sub_config.meta is not None:\n                        config[\"meta\"] = unparsed_sub_config.meta\n                if patch.semantic_model.enabled is not None:\n                    config[\"enabled\"] = patch.semantic_model.enabled\n                if patch.semantic_model.group is not None:\n                    config[\"group\"] = patch.semantic_model.group\n        elif isinstance(patch.semantic_model, bool):\n            # boolean value just indicates that the model has a semantic model,\n            # so nothing to do here.\n            pass\n        else:\n            # this should be unreachable, but just in case\n            raise ValueError(f\"Invalid semantic model config: {patch.semantic_model}\")\n\n        self._parse_semantic_model_helper(\n            semantic_model_name=name,\n            semantic_model_config=config,\n            description=node.description,\n            label=None,  # does not seem to be available in v2 YAML, unless it is part of the semantic model config's 'group'?\n            model=f\"ref('{patch.name}')\",\n            defaults=Defaults(agg_time_dimension=patch.agg_time_dimension),\n            primary_entity=patch.primary_entity,\n            entities=entities,\n            dimensions=dimensions,\n            # Measures are not part of the v2 YAML design.\n            measures=[],\n            unparsed_measures=[],\n        )\n\n    def _parse_semantic_model_helper(\n        self,\n        semantic_model_name: str,\n        semantic_model_config: Dict[str, Any],\n        description: Optional[str],\n        label: Optional[str],\n        model: str,\n        defaults,\n        primary_entity,\n        entities: List[Entity],\n        dimensions: List[Dimension],\n        measures: List[Measure],  # v1 only\n        unparsed_measures: List[UnparsedMeasure] = [],  # v1 only\n    ) -> None:\n        package_name = self.project.project_name\n        unique_id = f\"{NodeType.SemanticModel}.{package_name}.{semantic_model_name}\"\n        path = self.yaml.path.relative_path\n\n        fqn = self.schema_parser.get_fqn_prefix(path)\n        fqn.append(semantic_model_name)\n\n        config = self._generate_semantic_model_config(\n            target_config=semantic_model_config,\n            fqn=fqn,\n            package_name=package_name,\n            rendered=True,\n        )\n\n        # Combine configs according to the behavior documented here https://docs.getdbt.com/reference/configs-and-properties#combining-configs\n        elements: Sequence[Union[Dimension, Entity, Measure]] = [\n            *dimensions,\n            *entities,\n            *measures,\n        ]\n        for element in elements:\n            if config is not None:\n                if element.config is None:\n                    element.config = SemanticLayerElementConfig(meta=config.meta)\n                else:\n                    element.config.meta = {**config.get(\"meta\", {}), **element.config.meta}\n\n        config = config.finalize_and_validate()\n\n        unrendered_config = self._generate_semantic_model_config(\n            target_config=semantic_model_config,\n            fqn=fqn,\n            package_name=package_name,\n            rendered=False,\n        )\n\n        parsed = SemanticModel(\n            description=description,\n            label=label,\n            fqn=fqn,\n            model=model,\n            name=semantic_model_name,\n            node_relation=None,  # Resolved from the value of \"model\" after parsing\n            original_file_path=self.yaml.path.original_file_path,\n            package_name=package_name,\n            path=path,\n            resource_type=NodeType.SemanticModel,\n            unique_id=unique_id,\n            entities=entities,\n            measures=measures,\n            dimensions=dimensions,\n            defaults=defaults,\n            primary_entity=primary_entity,\n            config=config,\n            unrendered_config=unrendered_config,\n            group=config.group,\n        )\n\n        ctx = generate_parse_semantic_models(\n            parsed,\n            self.root_project,\n            self.schema_parser.manifest,\n            package_name,\n        )\n\n        if parsed.model is not None:\n            model_ref = \"{{ \" + parsed.model + \" }}\"\n            # This sets the \"refs\" in the SemanticModel from the SemanticModelRefResolver in context/providers.py\n            get_rendered(model_ref, ctx, parsed)\n\n        # if the semantic model is disabled we do not want it included in the manifest,\n        # only in the disabled dict\n        assert isinstance(self.yaml.file, SchemaSourceFile)\n        if parsed.config.enabled:\n            self.manifest.add_semantic_model(self.yaml.file, parsed)\n        else:\n            self.manifest.add_disabled(self.yaml.file, parsed)\n\n        # Create a metric for each measure with `create_metric = True`\n        # This is only relevant for v1 SL YAML; v2 does not include measures at all.\n        for measure in unparsed_measures:\n            if measure.create_metric is True:\n                self._create_metric(\n                    measure=measure,\n                    enabled=parsed.config.enabled,\n                    semantic_model_name=parsed.name,\n                    meta=config.meta if config is not None else None,\n                )\n\n    def parse(self) -> None:\n        for data in self.get_key_dicts():\n            try:\n                UnparsedSemanticModel.validate(data)\n                unparsed = UnparsedSemanticModel.from_dict(data)\n            except (ValidationError, JSONValidationError) as exc:\n                raise YamlParseDictError(self.yaml.path, self.key, data, exc)\n\n            self._parse_semantic_model_v1(unparsed)\n\n\nclass SavedQueryParser(YamlReader):\n    def __init__(self, schema_parser: SchemaParser, yaml: YamlBlock) -> None:\n        super().__init__(schema_parser, yaml, \"saved_queries\")\n        self.schema_parser = schema_parser\n        self.yaml = yaml\n\n    def _generate_saved_query_config(\n        self, target: UnparsedSavedQuery, fqn: List[str], package_name: str, rendered: bool\n    ):\n        generator: BaseContextConfigGenerator\n        if rendered:\n            generator = ContextConfigGenerator(self.root_project)\n        else:\n            generator = UnrenderedConfigGenerator(self.root_project)\n\n        # configs with precendence set\n        precedence_configs = dict()\n        # first apply semantic model configs\n        precedence_configs.update(target.config)\n\n        config = generator.calculate_node_config(\n            config_call_dict={},\n            fqn=fqn,\n            resource_type=NodeType.SavedQuery,\n            project_name=package_name,\n            base=False,\n            patch_config_dict=precedence_configs,\n        )\n\n        return config\n\n    def _get_export_config(\n        self, unparsed_export_config: Dict[str, Any], saved_query_config: SavedQueryConfig\n    ) -> ExportConfig:\n        # Combine the two dictionaries using dictionary unpacking\n        # the second dictionary is the one whose keys take priority\n        combined = {**saved_query_config.__dict__, **unparsed_export_config}\n        # `schema` is the user facing attribute, but for DSI protocol purposes we track it as `schema_name`\n        if combined.get(\"schema\") is not None and combined.get(\"schema_name\") is None:\n            combined[\"schema_name\"] = combined[\"schema\"]\n\n        return ExportConfig.from_dict(combined)\n\n    def _get_export(\n        self, unparsed: UnparsedExport, saved_query_config: SavedQueryConfig\n    ) -> Export:\n        return Export(\n            name=unparsed.name,\n            config=self._get_export_config(unparsed.config, saved_query_config),\n            unrendered_config=unparsed.config,\n        )\n\n    def _get_query_params(self, unparsed: UnparsedQueryParams) -> QueryParams:\n        return QueryParams(\n            group_by=unparsed.group_by,\n            metrics=unparsed.metrics,\n            where=parse_where_filter(unparsed.where),\n            order_by=unparsed.order_by,\n            limit=unparsed.limit,\n        )\n\n    def parse_saved_query(self, unparsed: UnparsedSavedQuery) -> None:\n        package_name = self.project.project_name\n        unique_id = f\"{NodeType.SavedQuery}.{package_name}.{unparsed.name}\"\n        path = self.yaml.path.relative_path\n\n        fqn = self.schema_parser.get_fqn_prefix(path)\n        fqn.append(unparsed.name)\n\n        config = self._generate_saved_query_config(\n            target=unparsed,\n            fqn=fqn,\n            package_name=package_name,\n            rendered=True,\n        )\n\n        config = config.finalize_and_validate()\n\n        unrendered_config = self._generate_saved_query_config(\n            target=unparsed,\n            fqn=fqn,\n            package_name=package_name,\n            rendered=False,\n        )\n\n        # The parser handles plain strings just fine, but we need to be able\n        # to join two lists, remove duplicates, and sort, so we have to wrap things here.\n        def wrap_tags(s: Union[List[str], str]) -> List[str]:\n            if s is None:\n                return []\n            return [s] if isinstance(s, str) else s\n\n        config_tags = wrap_tags(config.get(\"tags\"))\n        unparsed_tags = wrap_tags(unparsed.tags)\n        tags = list(set([*unparsed_tags, *config_tags]))\n        tags.sort()\n\n        parsed = SavedQuery(\n            description=unparsed.description,\n            label=unparsed.label,\n            fqn=fqn,\n            name=unparsed.name,\n            original_file_path=self.yaml.path.original_file_path,\n            package_name=package_name,\n            path=path,\n            resource_type=NodeType.SavedQuery,\n            unique_id=unique_id,\n            query_params=self._get_query_params(unparsed.query_params),\n            exports=[self._get_export(export, config) for export in unparsed.exports],\n            config=config,\n            unrendered_config=unrendered_config,\n            group=config.group,\n            tags=tags,\n        )\n\n        for export in parsed.exports:\n            self.schema_parser.update_parsed_node_relation_names(export, export.config.to_dict())  # type: ignore\n\n            if not export.config.schema_name:\n                export.config.schema_name = getattr(export, \"schema\", None)\n            delattr(export, \"schema\")\n\n            export.config.database = getattr(export, \"database\", None) or export.config.database\n            delattr(export, \"database\")\n\n            if not export.config.alias:\n                export.config.alias = getattr(export, \"alias\", None)\n            delattr(export, \"alias\")\n\n            delattr(export, \"relation_name\")\n\n        # Only add thes saved query if it's enabled, otherwise we track it with other diabled nodes\n        assert isinstance(self.yaml.file, SchemaSourceFile)\n        if parsed.config.enabled:\n            self.manifest.add_saved_query(self.yaml.file, parsed)\n        else:\n            self.manifest.add_disabled(self.yaml.file, parsed)\n\n    def parse(self) -> ParseResult:\n        for data in self.get_key_dicts():\n            try:\n                UnparsedSavedQuery.validate(data)\n                unparsed = UnparsedSavedQuery.from_dict(data)\n            except (ValidationError, JSONValidationError) as exc:\n                raise YamlParseDictError(self.yaml.path, self.key, data, exc)\n\n            self.parse_saved_query(unparsed)\n\n        # The supertype (YamlReader) requires `parse` to return a ParseResult, so\n        # we return an empty one because we don't have one to actually return.\n        return ParseResult()\n"
  },
  {
    "path": "core/dbt/parser/schemas.py",
    "content": "import datetime\nimport re\nimport time\nfrom abc import ABCMeta, abstractmethod\nfrom dataclasses import dataclass, field\nfrom typing import (\n    Any,\n    Callable,\n    Dict,\n    Generic,\n    Iterable,\n    List,\n    Optional,\n    Tuple,\n    Type,\n    TypeVar,\n)\n\nfrom dbt.artifacts.resources import CustomGranularity, Docs, RefArgs, TimeSpine\nfrom dbt.clients.checked_load import (\n    checked_load,\n    issue_deprecation_warnings_for_failures,\n)\nfrom dbt.clients.jinja_static import statically_parse_ref_or_source\nfrom dbt.clients.yaml_helper import load_yaml_text\nfrom dbt.config import RuntimeConfig\nfrom dbt.context.configured import SchemaYamlVars, generate_schema_yml_context\nfrom dbt.context.context_config import ContextConfig\nfrom dbt.contracts.files import SchemaSourceFile, SourceFile\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.contracts.graph.nodes import (\n    FunctionNode,\n    Macro,\n    ModelNode,\n    ParsedFunctionPatch,\n    ParsedMacroPatch,\n    ParsedNodePatch,\n    ParsedSingularTestPatch,\n    UnpatchedSourceDefinition,\n)\nfrom dbt.contracts.graph.unparsed import (\n    HasColumnDocs,\n    HasColumnTests,\n    SourcePatch,\n    UnparsedAnalysisUpdate,\n    UnparsedFunctionUpdate,\n    UnparsedMacroUpdate,\n    UnparsedModelUpdate,\n    UnparsedNodeUpdate,\n    UnparsedSingularTestUpdate,\n    UnparsedSourceDefinition,\n)\nfrom dbt.events.types import (\n    InvalidMacroAnnotation,\n    MacroNotFoundForPatch,\n    NoNodeForYamlKey,\n    UnsupportedConstraintMaterialization,\n    ValidationWarning,\n    WrongResourceSchemaFile,\n)\nfrom dbt.exceptions import (\n    DbtInternalError,\n    DuplicateMacroPatchNameError,\n    DuplicatePatchPathError,\n    DuplicateSourcePatchNameError,\n    InvalidAccessTypeError,\n    JSONValidationError,\n    ParsingError,\n    YamlLoadError,\n    YamlParseDictError,\n    YamlParseListError,\n)\nfrom dbt.flags import get_flags\nfrom dbt.node_types import AccessType, NodeType\nfrom dbt.parser.base import SimpleParser\nfrom dbt.parser.common import (\n    ParserRef,\n    TargetBlock,\n    TestBlock,\n    VersionedTestBlock,\n    YamlBlock,\n    schema_file_keys_to_resource_types,\n    trimmed,\n)\nfrom dbt.parser.schema_generic_tests import SchemaGenericTestParser\nfrom dbt.parser.schema_renderer import SchemaYamlRenderer\nfrom dbt.parser.search import FileBlock\nfrom dbt.utils import coerce_dict_str\nfrom dbt_common.contracts.constraints import ConstraintType, ModelLevelConstraint\nfrom dbt_common.dataclass_schema import ValidationError, dbtClassMixin\nfrom dbt_common.events import EventLevel\nfrom dbt_common.events.functions import fire_event, warn_or_error\nfrom dbt_common.events.types import Note\nfrom dbt_common.exceptions import DbtValidationError\nfrom dbt_common.utils import deep_merge\n\n# ===============================================================================\n#  Schema Parser classes\n#\n# The SchemaParser is a subclass of the SimpleParser from base.py, as is\n# the SchemaGenericTestParser. The schema sub-parsers are all subclasses of\n# the YamlReader parsing class. Most of the action in creating SourceDefinition\n# nodes actually happens in the SourcePatcher class, in sources.py, which is\n# called as a late-stage parsing step in manifest.py.\n#\n# The \"patch\" parsers read yaml config and properties and apply them to\n# nodes that were already created from sql files.\n#\n# The SchemaParser and SourcePatcher both use the SchemaGenericTestParser\n# (in schema_generic_tests.py) to create generic test nodes.\n#\n#  YamlReader\n#      MetricParser (metrics) [schema_yaml_readers.py]\n#      ExposureParser (exposures) [schema_yaml_readers.py]\n#      GroupParser  (groups) [schema_yaml_readers.py]\n#      SourceParser (sources)\n#      PatchParser\n#          MacroPatchParser (macros)\n#          NodePatchParser\n#              ModelPatchParser (models)\n#              AnalysisPatchParser (analyses)\n#              TestablePatchParser (seeds, snapshots)\n#\n# ===============================================================================\n\n\ndef yaml_from_file(\n    source_file: SchemaSourceFile, validate: bool = False\n) -> Optional[Dict[str, Any]]:\n    \"\"\"If loading the yaml fails, raise an exception.\"\"\"\n    try:\n        # source_file.contents can sometimes be None\n        to_load = source_file.contents or \"\"\n\n        if validate:\n            contents, failures = checked_load(to_load)\n            issue_deprecation_warnings_for_failures(\n                failures=failures, file=source_file.path.original_file_path\n            )\n            if contents is not None:\n                from dbt.jsonschemas.jsonschemas import (\n                    jsonschema_validate,\n                    resources_schema,\n                )\n\n                # Validate the yaml against the jsonschema to raise deprecation warnings\n                # for invalid fields.\n                jsonschema_validate(\n                    schema=resources_schema(),\n                    json=contents,\n                    file_path=source_file.path.original_file_path,\n                )\n        else:\n            contents = load_yaml_text(to_load, source_file.path)\n\n        if contents is None:\n            return contents\n\n        if not isinstance(contents, dict):\n            raise DbtValidationError(\n                f\"Contents of file '{source_file.original_file_path}' are not valid. Dictionary expected.\"\n            )\n\n        # When loaded_at_field is defined as None or null, it shows up in\n        # the dict but when it is not defined, it does not show up in the dict\n        # We need to capture this to be able to override source level settings later.\n        for source in contents.get(\"sources\", []):\n            for table in source.get(\"tables\", []):\n                if \"loaded_at_field\" in table or (\n                    \"config\" in table\n                    and table[\"config\"] is not None\n                    and table[\"config\"].get(\"loaded_at_field\")\n                ):\n                    table[\"loaded_at_field_present\"] = True\n\n        return contents\n    except DbtValidationError as e:\n        raise YamlLoadError(\n            project_name=source_file.project_name, path=source_file.path.relative_path, exc=e\n        )\n\n\n# This is the main schema file parser, but almost everything happens in the\n# the schema sub-parsers.\nclass SchemaParser(SimpleParser[YamlBlock, ModelNode]):\n    def __init__(\n        self,\n        project: RuntimeConfig,\n        manifest: Manifest,\n        root_project: RuntimeConfig,\n    ) -> None:\n        super().__init__(project, manifest, root_project)\n\n        self.generic_test_parser = SchemaGenericTestParser(project, manifest, root_project)\n\n        self.schema_yaml_vars = SchemaYamlVars()\n        self.render_ctx = generate_schema_yml_context(\n            self.root_project, self.project.project_name, self.schema_yaml_vars\n        )\n\n    # This is unnecessary, but mypy was requiring it. Clean up parser code so\n    # we don't have to do this.\n    def parse_from_dict(self, dct):\n        pass\n\n    @classmethod\n    def get_compiled_path(cls, block: FileBlock) -> str:\n        # should this raise an error?\n        return block.path.relative_path\n\n    @property\n    def resource_type(self) -> NodeType:\n        return NodeType.Test\n\n    def parse_file(self, block: FileBlock, dct: Optional[Dict] = None) -> None:\n        assert isinstance(block.file, SchemaSourceFile)\n\n        # If partially parsing, dct should be from pp_dict, otherwise\n        # dict_from_yaml\n        if dct:\n            # contains the FileBlock and the data (dictionary)\n            yaml_block = YamlBlock.from_file_block(block, dct)\n            parser: YamlReader\n\n            # There are 9 different yaml lists which are parsed by different parsers:\n            # Model, Seed, Snapshot, Source, Macro, Analysis, Exposure, Metric, Group\n\n            # ModelPatchParser.parse()\n            if \"models\" in dct:\n                # the models are already in the manifest as nodes when we reach this code,\n                # even if they are disabled in the schema file\n                model_parse_result = ModelPatchParser(self, yaml_block, \"models\").parse()\n                for versioned_test_block in model_parse_result.versioned_test_blocks:\n                    self.generic_test_parser.parse_versioned_tests(versioned_test_block)\n\n            # PatchParser.parse()\n            if \"seeds\" in dct:\n                seed_parse_result = TestablePatchParser(self, yaml_block, \"seeds\").parse()\n                for test_block in seed_parse_result.test_blocks:\n                    self.generic_test_parser.parse_tests(test_block)\n\n            # PatchParser.parse()\n            if \"snapshots\" in dct:\n                self._add_yaml_snapshot_nodes_to_manifest(dct[\"snapshots\"], block)\n                snapshot_parse_result = TestablePatchParser(self, yaml_block, \"snapshots\").parse()\n                for test_block in snapshot_parse_result.test_blocks:\n                    self.generic_test_parser.parse_tests(test_block)\n\n            # This parser uses SourceParser.parse() which doesn't return\n            # any test blocks. Source tests are handled at a later point\n            # in the process.\n            if \"sources\" in dct:\n                parser = SourceParser(self, yaml_block, \"sources\")\n                parser.parse()\n\n            # PatchParser.parse() (but never test_blocks)\n            if \"macros\" in dct:\n                parser = MacroPatchParser(self, yaml_block, \"macros\")\n                parser.parse()\n\n            if \"data_tests\" in dct:\n                parser = SingularTestPatchParser(self, yaml_block, \"data_tests\")\n                try:\n                    parser.parse()\n                except ParsingError as e:\n                    fire_event(\n                        Note(\n                            msg=f\"Unable to parse 'data_tests' section of file '{block.path.original_file_path}'\\n{e}\",\n                        ),\n                        EventLevel.WARN,\n                    )\n\n            # PatchParser.parse() (but never test_blocks)\n            if \"analyses\" in dct:\n                parser = AnalysisPatchParser(self, yaml_block, \"analyses\")\n                parser.parse()\n\n            # ExposureParser.parse()\n            if \"exposures\" in dct:\n                from dbt.parser.schema_yaml_readers import ExposureParser\n\n                exp_parser = ExposureParser(self, yaml_block)\n                exp_parser.parse()\n\n            # FunctionPatchParser.parse()\n            if \"functions\" in dct:\n                function_parser = FunctionPatchParser(self, yaml_block, \"functions\")\n                function_parser.parse()\n\n            # MetricParser.parse()\n            if \"metrics\" in dct:\n                from dbt.parser.schema_yaml_readers import MetricParser\n\n                metric_parser = MetricParser(self, yaml_block)\n                metric_parser.parse()\n\n            # GroupParser.parse()\n            if \"groups\" in dct:\n                from dbt.parser.schema_yaml_readers import GroupParser\n\n                group_parser = GroupParser(self, yaml_block)\n                group_parser.parse()\n\n            if \"semantic_models\" in dct:\n                from dbt.parser.schema_yaml_readers import SemanticModelParser\n\n                semantic_model_parser = SemanticModelParser(self, yaml_block)\n                semantic_model_parser.parse()\n\n            if \"unit_tests\" in dct:\n                from dbt.parser.unit_tests import UnitTestParser\n\n                unit_test_parser = UnitTestParser(self, yaml_block)\n                unit_test_parser.parse()\n\n            if \"saved_queries\" in dct:\n                from dbt.parser.schema_yaml_readers import SavedQueryParser\n\n                saved_query_parser = SavedQueryParser(self, yaml_block)\n                saved_query_parser.parse()\n\n    def _add_yaml_snapshot_nodes_to_manifest(\n        self, snapshots: List[Dict[str, Any]], block: FileBlock\n    ) -> None:\n        \"\"\"We support the creation of simple snapshots in yaml, without an\n        accompanying SQL definition. For such snapshots, the user must supply\n        a 'relation' property to indicate the target of the snapshot. This\n        function looks for such snapshots and adds a node to manifest for each\n        one we find, since they were not added during SQL parsing.\"\"\"\n\n        rebuild_refs = False\n        for snapshot in snapshots:\n            if \"relation\" in snapshot:\n                from dbt.parser import SnapshotParser\n\n                if \"name\" not in snapshot:\n                    raise ParsingError(\"A snapshot must define the 'name' property. \")\n\n                # Reuse the logic of SnapshotParser as far as possible to create\n                # a new node we can add to the manifest.\n                parser = SnapshotParser(self.project, self.manifest, self.root_project)\n                fqn = parser.get_fqn_prefix(block.path.relative_path)\n                fqn.append(snapshot[\"name\"])\n\n                compiled_path = snapshot[\"name\"] + \".sql\"\n                snapshot_node = parser._create_parsetime_node(\n                    block,\n                    compiled_path,\n                    parser.initial_config(fqn),\n                    fqn,\n                    snapshot[\"name\"],\n                )\n\n                # Parse the expected ref() or source() expression given by\n                # 'relation' so that we know what we are snapshotting.\n                source_or_ref = statically_parse_ref_or_source(snapshot[\"relation\"])\n                if isinstance(source_or_ref, RefArgs):\n                    snapshot_node.refs.append(source_or_ref)\n                else:\n                    snapshot_node.sources.append(source_or_ref)\n\n                # Implement the snapshot SQL as a simple select *\n                snapshot_node.raw_code = \"select * from {{ \" + snapshot[\"relation\"] + \" }}\"\n\n                # Add our new node to the manifest, and note that ref lookup collections\n                # will need to be rebuilt. This adds the node unique_id to the \"snapshots\"\n                # list in the SchemaSourceFile.\n                self.manifest.add_node(block.file, snapshot_node)\n                rebuild_refs = True\n\n        if rebuild_refs:\n            self.manifest.rebuild_ref_lookup()\n\n\nParsed = TypeVar(\n    \"Parsed\", UnpatchedSourceDefinition, ParsedNodePatch, ParsedMacroPatch, ParsedSingularTestPatch\n)\nNodeTarget = TypeVar(\n    \"NodeTarget\",\n    UnparsedNodeUpdate,\n    UnparsedAnalysisUpdate,\n    UnparsedModelUpdate,\n    UnparsedFunctionUpdate,\n)\nNonSourceTarget = TypeVar(\n    \"NonSourceTarget\",\n    UnparsedNodeUpdate,\n    UnparsedAnalysisUpdate,\n    UnparsedMacroUpdate,\n    UnparsedModelUpdate,\n    UnparsedFunctionUpdate,\n    UnparsedSingularTestUpdate,\n)\n\n\n@dataclass\nclass ParseResult:\n    test_blocks: List[TestBlock] = field(default_factory=list)\n    versioned_test_blocks: List[VersionedTestBlock] = field(default_factory=list)\n\n\n# abstract base class (ABCMeta)\n# Many subclasses: MetricParser, ExposureParser, GroupParser, SourceParser,\n# PatchParser, SemanticModelParser, SavedQueryParser, UnitTestParser\nclass YamlReader(metaclass=ABCMeta):\n    def __init__(self, schema_parser: SchemaParser, yaml: YamlBlock, key: str) -> None:\n        self.schema_parser: SchemaParser = schema_parser\n        # key: models, seeds, snapshots, sources, macros,\n        # analyses, exposures, unit_tests\n        self.key: str = key\n        self.yaml: YamlBlock = yaml\n        self.schema_yaml_vars: SchemaYamlVars = SchemaYamlVars()\n        self.render_ctx = generate_schema_yml_context(\n            self.schema_parser.root_project,\n            self.schema_parser.project.project_name,\n            self.schema_yaml_vars,\n        )\n        self.renderer: SchemaYamlRenderer = SchemaYamlRenderer(self.render_ctx, self.key)\n\n    @property\n    def manifest(self) -> Manifest:\n        return self.schema_parser.manifest\n\n    @property\n    def project(self) -> RuntimeConfig:\n        return self.schema_parser.project\n\n    @property\n    def default_database(self) -> str:\n        return self.schema_parser.default_database\n\n    @property\n    def root_project(self) -> RuntimeConfig:\n        return self.schema_parser.root_project\n\n    # for the different schema subparsers ('models', 'source', etc)\n    # get the list of dicts pointed to by the key in the yaml config,\n    # ensure that the dicts have string keys\n    def get_key_dicts(self) -> Iterable[Dict[str, Any]]:\n        data = self.yaml.data.get(self.key, [])\n        if not isinstance(data, list):\n            raise ParsingError(\n                \"{} must be a list, got {} instead: ({})\".format(\n                    self.key, type(data), trimmed(str(data))\n                )\n            )\n        path = self.yaml.path.original_file_path\n\n        # for each dict in the data (which is a list of dicts)\n        for entry in data:\n\n            # check that entry is a dict and that all dict values\n            # are strings\n            if coerce_dict_str(entry) is None:\n                raise YamlParseListError(path, self.key, data, \"expected a dict with string keys\")\n\n            if \"name\" not in entry and \"model\" not in entry:\n                raise ParsingError(\"Entry did not contain a name\")\n\n            unrendered_config = {}\n            if \"config\" in entry:\n                unrendered_config = entry[\"config\"]\n\n            unrendered_version_configs = {}\n            if \"versions\" in entry:\n                for version in entry[\"versions\"]:\n                    if \"v\" in version:\n                        unrendered_version_configs[version[\"v\"]] = version.get(\"config\", {})\n\n            # For sources\n            unrendered_database = entry.get(\"database\", None)\n            unrendered_schema = entry.get(\"schema\", None)\n\n            # Render the data (except for tests, data_tests and descriptions).\n            # See the SchemaYamlRenderer\n            entry = self.render_entry(entry)\n\n            schema_file = self.yaml.file\n            assert isinstance(schema_file, SchemaSourceFile)\n\n            if unrendered_config:\n                schema_file.add_unrendered_config(unrendered_config, self.key, entry[\"name\"])\n\n            for version, unrendered_version_config in unrendered_version_configs.items():\n                schema_file.add_unrendered_config(\n                    unrendered_version_config, self.key, entry[\"name\"], version\n                )\n\n            if unrendered_database:\n                schema_file.add_unrendered_database(self.key, entry[\"name\"], unrendered_database)\n            if unrendered_schema:\n                schema_file.add_unrendered_schema(self.key, entry[\"name\"], unrendered_schema)\n\n            if self.schema_yaml_vars.env_vars:\n                self.schema_parser.manifest.env_vars.update(self.schema_yaml_vars.env_vars)\n                for var in self.schema_yaml_vars.env_vars.keys():\n                    schema_file.add_env_var(var, self.key, entry[\"name\"])\n                self.schema_yaml_vars.env_vars = {}\n\n            yield entry\n\n    def render_entry(self, dct):\n        try:\n            # This does a deep_map which will fail if there are circular references\n            dct = self.renderer.render_data(dct)\n        except ParsingError as exc:\n            raise ParsingError(\n                f\"Failed to render {self.yaml.file.path.original_file_path} from \"\n                f\"project {self.project.project_name}: {exc}\"\n            ) from exc\n        return dct\n\n    @abstractmethod\n    def parse(self) -> Optional[ParseResult]:\n        raise NotImplementedError(\"parse is abstract\")\n\n\nT = TypeVar(\"T\", bound=dbtClassMixin)\n\n\n# This parses the 'sources' keys in yaml files.\nclass SourceParser(YamlReader):\n    def _target_from_dict(self, cls: Type[T], data: Dict[str, Any]) -> T:\n        path = self.yaml.path.original_file_path\n        try:\n            cls.validate(data)\n            return cls.from_dict(data)\n        except (ValidationError, JSONValidationError) as exc:\n            raise YamlParseDictError(path, self.key, data, exc)\n\n    # This parse method takes the yaml dictionaries in 'sources' keys and uses them\n    # to create UnparsedSourceDefinition objects. They are then turned\n    # into UnpatchedSourceDefinition objects in 'add_source_definitions'\n    # or SourcePatch objects in 'add_source_patch'\n    def parse(self) -> ParseResult:\n        # get a verified list of dicts for the key handled by this parser\n        for data in self.get_key_dicts():\n            data = self.project.credentials.translate_aliases(data, recurse=True)\n\n            is_override = \"overrides\" in data\n            if is_override:\n                data[\"path\"] = self.yaml.path.original_file_path\n                patch = self._target_from_dict(SourcePatch, data)\n                assert isinstance(self.yaml.file, SchemaSourceFile)\n                source_file = self.yaml.file\n                # source patches must be unique\n                key = (patch.overrides, patch.name)\n                if key in self.manifest.source_patches:\n                    raise DuplicateSourcePatchNameError(patch, self.manifest.source_patches[key])\n                self.manifest.source_patches[key] = patch\n                source_file.source_patches.append(key)\n            else:\n                source = self._target_from_dict(UnparsedSourceDefinition, data)\n                # Store unrendered_database and unrendered_schema for state:modified comparisons\n                if isinstance(self.yaml.file, SchemaSourceFile):\n                    source.unrendered_database = self.yaml.file.get_unrendered_database(\n                        \"sources\", source.name\n                    )\n                    source.unrendered_schema = self.yaml.file.get_unrendered_schema(\n                        \"sources\", source.name\n                    )\n\n                self.add_source_definitions(source)\n        return ParseResult()\n\n    def add_source_definitions(self, source: UnparsedSourceDefinition) -> None:\n        package_name = self.project.project_name\n        original_file_path = self.yaml.path.original_file_path\n        fqn_path = self.yaml.path.relative_path\n        for table in source.tables:\n            unique_id = \".\".join([NodeType.Source, package_name, source.name, table.name])\n\n            # the FQN is project name / path elements /source_name /table_name\n            fqn = self.schema_parser.get_fqn_prefix(fqn_path)\n            fqn.extend([source.name, table.name])\n\n            source_def = UnpatchedSourceDefinition(\n                source=source,\n                table=table,\n                path=original_file_path,\n                original_file_path=original_file_path,\n                package_name=package_name,\n                unique_id=unique_id,\n                resource_type=NodeType.Source,\n                fqn=fqn,\n                name=f\"{source.name}_{table.name}\",\n            )\n            assert isinstance(self.yaml.file, SchemaSourceFile)\n            source_file: SchemaSourceFile = self.yaml.file\n            self.manifest.add_source(source_file, source_def)\n\n\n# This class has two subclasses: NodePatchParser and MacroPatchParser\nclass PatchParser(YamlReader, Generic[NonSourceTarget, Parsed]):\n    @abstractmethod\n    def _target_type(self) -> Type[NonSourceTarget]:\n        raise NotImplementedError(\"_target_type not implemented\")\n\n    @abstractmethod\n    def get_block(self, node: NonSourceTarget) -> TargetBlock:\n        raise NotImplementedError(\"get_block is abstract\")\n\n    @abstractmethod\n    def parse_patch(self, block: TargetBlock[NonSourceTarget], refs: ParserRef) -> None:\n        raise NotImplementedError(\"parse_patch is abstract\")\n\n    def parse(self) -> ParseResult:\n        node: NonSourceTarget\n        # This will always be empty if the node a macro or analysis\n        test_blocks: List[TestBlock] = []\n        # This will always be empty if the node is _not_ a model\n        versioned_test_blocks: List[VersionedTestBlock] = []\n\n        # get list of 'node' objects\n        # UnparsedNodeUpdate (TestablePatchParser, models, seeds, snapshots)\n        #      = HasColumnTests, HasTests\n        # UnparsedAnalysisUpdate (UnparsedAnalysisParser, analyses)\n        #      = HasColumnDocs, HasDocs\n        # UnparsedMacroUpdate (MacroPatchParser, 'macros')\n        #      = HasDocs\n        # correspond to this parser's 'key'\n        for node in self.get_unparsed_target():\n            # node_block is a TargetBlock (Macro or Analysis)\n            # or a TestBlock (all of the others)\n            node_block = self.get_block(node)\n            if isinstance(node_block, TestBlock):\n                # TestablePatchParser = seeds, snapshots\n                test_blocks.append(node_block)\n            if isinstance(node_block, VersionedTestBlock):\n                # models\n                versioned_test_blocks.append(node_block)\n            if isinstance(node, (HasColumnDocs, HasColumnTests)):\n                # UnparsedNodeUpdate and UnparsedAnalysisUpdate\n                refs: ParserRef = ParserRef.from_target(node)\n            else:\n                refs = ParserRef()\n\n            # There's no unique_id on the node yet so cannot add to disabled dict\n            self.parse_patch(node_block, refs)\n\n        return ParseResult(test_blocks, versioned_test_blocks)\n\n    def get_unparsed_target(self) -> Iterable[NonSourceTarget]:\n        path = self.yaml.path.original_file_path\n\n        # get verified list of dicts for the 'key' that this\n        # parser handles\n        key_dicts = self.get_key_dicts()\n        for data in key_dicts:\n            # add extra data to each dict. This updates the dicts\n            # in the parser yaml\n            data.update(\n                {\n                    \"original_file_path\": path,\n                    \"yaml_key\": self.key,\n                    \"package_name\": self.project.project_name,\n                }\n            )\n            try:\n                # target_type: UnparsedNodeUpdate, UnparsedAnalysisUpdate,\n                # or UnparsedMacroUpdate, UnparsedFunctionUpdate\n                self._target_type().validate(data)\n                if self.key != \"macros\":\n                    # macros don't have the 'config' key support yet\n                    self.normalize_meta_attribute(data, path)\n                    self.normalize_docs_attribute(data, path)\n                    self.normalize_group_attribute(data, path)\n                    self.normalize_contract_attribute(data, path)\n                    self.normalize_access_attribute(data, path)\n                # `tests` has been deprecated, convert to `data_tests` here if present\n                self.validate_data_tests(data)\n                node = self._target_type().from_dict(data)\n            except (ValidationError, JSONValidationError) as exc:\n                raise YamlParseDictError(path, self.key, data, exc)\n            else:\n                yield node\n\n    # We want to raise an error if some attributes are in two places, and move them\n    # from toplevel to config if necessary\n    def normalize_attribute(self, data, path, attribute) -> None:\n        if attribute in data:\n            if \"config\" in data and attribute in data[\"config\"]:\n                raise ParsingError(\n                    f\"\"\"\n                    In {path}: found {attribute} dictionary in 'config' dictionary and as top-level key.\n                    Remove the top-level key and define it under 'config' dictionary only.\n                \"\"\".strip()\n                )\n            else:\n                if \"config\" not in data:\n                    data[\"config\"] = {}\n                data[\"config\"][attribute] = data.pop(attribute)\n\n    def normalize_meta_attribute(self, data, path) -> None:\n        return self.normalize_attribute(data, path, \"meta\")\n\n    def normalize_docs_attribute(self, data, path) -> None:\n        return self.normalize_attribute(data, path, \"docs\")\n\n    def normalize_group_attribute(self, data, path) -> None:\n        return self.normalize_attribute(data, path, \"group\")\n\n    def normalize_contract_attribute(self, data, path) -> None:\n        return self.normalize_attribute(data, path, \"contract\")\n\n    def normalize_access_attribute(self, data, path) -> None:\n        return self.normalize_attribute(data, path, \"access\")\n\n    @property\n    def is_root_project(self) -> bool:\n        if self.root_project.project_name == self.project.project_name:\n            return True\n        return False\n\n    def validate_data_tests(self, data) -> None:\n        # Rename 'tests' -> 'data_tests' at both model-level and column-level\n        # Raise a validation error if the user has defined both names\n        def validate_and_rename(data, is_root_project: bool) -> None:\n            if data.get(\"tests\"):\n                if \"tests\" in data and \"data_tests\" in data:\n                    raise ValidationError(\n                        \"Invalid test config: cannot have both 'tests' and 'data_tests' defined\"\n                    )\n                data[\"data_tests\"] = data.pop(\"tests\")\n\n        # model-level tests\n        validate_and_rename(data, self.is_root_project)\n\n        # column-level tests\n        if data.get(\"columns\"):\n            for column in data[\"columns\"]:\n                validate_and_rename(column, self.is_root_project)\n\n        # versioned models\n        if data.get(\"versions\"):\n            for version in data[\"versions\"]:\n                validate_and_rename(version, self.is_root_project)\n                if version.get(\"columns\"):\n                    for column in version[\"columns\"]:\n                        validate_and_rename(column, self.is_root_project)\n\n    def patch_node_config(self, node, patch) -> None:\n        if \"access\" in patch.config:\n            if AccessType.is_valid(patch.config[\"access\"]):\n                patch.config[\"access\"] = AccessType(patch.config[\"access\"])\n            else:\n                raise InvalidAccessTypeError(\n                    unique_id=node.unique_id,\n                    field_value=patch.config[\"access\"],\n                )\n        # Get the ContextConfig that's used in calculating the config\n        # This must match the model resource_type that's being patched\n        config = ContextConfig(\n            self.schema_parser.root_project,\n            node.fqn,\n            node.resource_type,\n            self.schema_parser.project.project_name,\n        )\n        # We need to re-apply the config_call_dict after the patch config\n        config._config_call_dict = node.config_call_dict\n        config._unrendered_config_call_dict = node.unrendered_config_call_dict\n        self.schema_parser.update_parsed_node_config(\n            node,\n            config,\n            patch_config_dict=patch.config,\n            patch_file_id=patch.file_id,\n        )\n\n\n# Subclasses of NodePatchParser: TestablePatchParser, ModelPatchParser, AnalysisPatchParser, FunctionPatchParser\n# so models, seeds, snapshots, analyses, functions\nclass NodePatchParser(PatchParser[NodeTarget, ParsedNodePatch], Generic[NodeTarget]):\n    def _get_node_patch(self, block: TargetBlock[NodeTarget], refs: ParserRef) -> ParsedNodePatch:\n        # We're not passing the ParsedNodePatch around anymore, so we\n        # could possibly skip creating one. Leaving here for now for\n        # code consistency.\n        deprecation_date: Optional[datetime.datetime] = None\n        time_spine: Optional[TimeSpine] = None\n        semantic_model = None\n        metrics = None\n        derived_semantics = None\n        agg_time_dimension = None\n        primary_entity = None\n\n        if isinstance(block.target, UnparsedModelUpdate):\n            deprecation_date = block.target.deprecation_date\n            time_spine = (\n                TimeSpine(\n                    standard_granularity_column=block.target.time_spine.standard_granularity_column,\n                    custom_granularities=[\n                        CustomGranularity(\n                            name=custom_granularity.name,\n                            column_name=custom_granularity.column_name,\n                        )\n                        for custom_granularity in block.target.time_spine.custom_granularities\n                    ],\n                )\n                if block.target.time_spine\n                else None\n            )\n            semantic_model = block.target.semantic_model\n            metrics = block.target.metrics\n            derived_semantics = block.target.derived_semantics\n            agg_time_dimension = block.target.agg_time_dimension\n            primary_entity = block.target.primary_entity\n        return ParsedNodePatch(\n            name=block.target.name,\n            original_file_path=block.target.original_file_path,\n            yaml_key=block.target.yaml_key,\n            package_name=block.target.package_name,\n            description=block.target.description,\n            columns=refs.column_info,\n            meta=block.target.meta,\n            docs=block.target.docs,\n            config=block.target.config,\n            access=block.target.access,\n            version=None,\n            latest_version=None,\n            constraints=block.target.constraints,\n            deprecation_date=deprecation_date,\n            time_spine=time_spine,\n            semantic_model=semantic_model,\n            metrics=metrics,\n            derived_semantics=derived_semantics,\n            agg_time_dimension=agg_time_dimension,\n            primary_entity=primary_entity,\n        )\n\n    def parse_patch(self, block: TargetBlock[NodeTarget], refs: ParserRef) -> None:\n        patch = self._get_node_patch(block, refs)\n\n        assert isinstance(self.yaml.file, SchemaSourceFile)\n        source_file: SchemaSourceFile = self.yaml.file\n\n        # TODO: I'd like to refactor this out but the early return makes doing so a bit messy\n        if patch.yaml_key in [\"models\", \"seeds\", \"snapshots\"]:\n            unique_id = self.manifest.ref_lookup.get_unique_id(\n                patch.name, self.project.project_name, None\n            ) or self.manifest.ref_lookup.get_unique_id(patch.name, None, None)\n\n            if unique_id:\n                resource_type = NodeType(unique_id.split(\".\")[0])\n                if resource_type.pluralize() != patch.yaml_key:\n                    warn_or_error(\n                        WrongResourceSchemaFile(\n                            patch_name=patch.name,\n                            resource_type=resource_type,\n                            plural_resource_type=resource_type.pluralize(),\n                            yaml_key=patch.yaml_key,\n                            file_path=patch.original_file_path,\n                        )\n                    )\n                    return\n        elif patch.yaml_key == \"functions\":\n            unique_id = self.manifest.function_lookup.get_unique_id(patch.name, None)\n        elif patch.yaml_key == \"analyses\":\n            unique_id = self.manifest.analysis_lookup.get_unique_id(patch.name, None, None)\n        else:\n            raise DbtInternalError(\n                f\"Unexpected yaml_key {patch.yaml_key} for patch in \"\n                f\"file {source_file.path.original_file_path}\"\n            )\n        # handle disabled nodes\n        if unique_id is None:\n            # Node might be disabled. Following call returns list of matching disabled nodes\n            resource_type = schema_file_keys_to_resource_types[patch.yaml_key]\n            found_nodes = self.manifest.disabled_lookup.find(\n                patch.name, patch.package_name, resource_types=[resource_type]\n            )\n            if found_nodes:\n                if len(found_nodes) > 1 and patch.config.get(\"enabled\"):\n                    # There are multiple disabled nodes for this model and the schema file wants to enable one.\n                    # We have no way to know which one to enable.\n                    resource_type = found_nodes[0].unique_id.split(\".\")[0]\n                    msg = (\n                        f\"Found {len(found_nodes)} matching disabled nodes for \"\n                        f\"{resource_type} '{patch.name}'. Multiple nodes for the same \"\n                        \"unique id cannot be enabled in the schema file. They must be enabled \"\n                        \"in `dbt_project.yml` or in the sql files.\"\n                    )\n                    raise ParsingError(msg)\n\n                # all nodes in the disabled dict have the same unique_id so just grab the first one\n                # to append with the unique id\n                source_file.append_patch(patch.yaml_key, found_nodes[0].unique_id)\n                for node in found_nodes:\n                    node.patch_path = source_file.file_id\n                    # re-calculate the node config with the patch config.  Always do this\n                    # for the case when no config is set to ensure the default of true gets captured\n                    if patch.config:\n                        self.patch_node_config(node, patch)\n\n                    self.patch_node_properties(node, patch)\n            else:\n                warn_or_error(\n                    NoNodeForYamlKey(\n                        patch_name=patch.name,\n                        yaml_key=patch.yaml_key,\n                        file_path=source_file.path.original_file_path,\n                    )\n                )\n                return  # we only return early if no disabled early nodes are found. Why don't we return after patching the disabled nodes?\n\n        if patch.yaml_key == \"functions\":\n            node = self.manifest.functions.get(unique_id)\n        else:\n            node = self.manifest.nodes.get(unique_id)\n\n        if node:\n            # patches can't be overwritten\n            if node.patch_path:\n                package_name, existing_file_path = node.patch_path.split(\"://\")\n                raise DuplicatePatchPathError(patch, existing_file_path)\n\n            source_file.append_patch(patch.yaml_key, node.unique_id)\n            # re-calculate the node config with the patch config.  Always do this\n            # for the case when no config is set to ensure the default of true gets captured\n            if patch.config:\n                self.patch_node_config(node, patch)\n\n            self.patch_node_properties(node, patch)\n\n    def patch_node_properties(self, node, patch: \"ParsedNodePatch\") -> None:\n        \"\"\"Given a ParsedNodePatch, add the new information to the node.\"\"\"\n        # explicitly pick out the parts to update so we don't inadvertently\n        # step on the model name or anything\n        # Note: config should already be updated\n        node.patch_path = patch.file_id\n        # update created_at so process_docs will run in partial parsing\n        node.created_at = time.time()\n        node.description = patch.description\n        node.columns = patch.columns\n        node.name = patch.name\n\n        if not isinstance(node, ModelNode):\n            for attr in [\"latest_version\", \"access\", \"version\", \"constraints\"]:\n                if getattr(patch, attr):\n                    warn_or_error(\n                        ValidationWarning(\n                            field_name=attr,\n                            resource_type=node.resource_type.value,\n                            node_name=patch.name,\n                        )\n                    )\n\n\n# TestablePatchParser = seeds, snapshots\nclass TestablePatchParser(NodePatchParser[UnparsedNodeUpdate]):\n    __test__ = False\n\n    def get_block(self, node: UnparsedNodeUpdate) -> TestBlock:\n        return TestBlock.from_yaml_block(self.yaml, node)\n\n    def _target_type(self) -> Type[UnparsedNodeUpdate]:\n        return UnparsedNodeUpdate\n\n\nclass ModelPatchParser(NodePatchParser[UnparsedModelUpdate]):\n    def get_block(self, node: UnparsedModelUpdate) -> VersionedTestBlock:\n        return VersionedTestBlock.from_yaml_block(self.yaml, node)\n\n    def parse_patch(self, block: TargetBlock[UnparsedModelUpdate], refs: ParserRef) -> None:\n        target = block.target\n        if NodeType.Model.pluralize() != target.yaml_key:\n            warn_or_error(\n                WrongResourceSchemaFile(\n                    patch_name=target.name,\n                    resource_type=NodeType.Model,\n                    plural_resource_type=NodeType.Model.pluralize(),\n                    yaml_key=target.yaml_key,\n                    file_path=target.original_file_path,\n                )\n            )\n            return\n\n        versions = target.versions\n        if not versions:\n            super().parse_patch(block, refs)\n        else:\n            assert isinstance(self.yaml.file, SchemaSourceFile)\n            source_file: SchemaSourceFile = self.yaml.file\n            latest_version = (\n                target.latest_version if target.latest_version is not None else max(versions).v\n            )\n            for unparsed_version in versions:\n                versioned_model_name = (\n                    unparsed_version.defined_in or f\"{block.name}_{unparsed_version.formatted_v}\"\n                )\n                # ref lookup without version - version is not set yet\n                versioned_model_unique_id = self.manifest.ref_lookup.get_unique_id(\n                    versioned_model_name, target.package_name, None\n                )\n\n                versioned_model_node: Optional[ModelNode] = None\n                add_node_nofile_fn: Callable\n\n                # If this is the latest version, it's allowed to define itself in a model file name that doesn't have a suffix\n                if versioned_model_unique_id is None and unparsed_version.v == latest_version:\n                    versioned_model_unique_id = self.manifest.ref_lookup.get_unique_id(\n                        block.name, target.package_name, None\n                    )\n\n                if versioned_model_unique_id is None:\n                    # Node might be disabled. Following call returns list of matching disabled nodes\n                    found_nodes = self.manifest.disabled_lookup.find(\n                        versioned_model_name, None, resource_types=[NodeType.Model]\n                    )\n                    if found_nodes:\n                        if len(found_nodes) > 1 and target.config.get(\"enabled\"):\n                            # There are multiple disabled nodes for this model and the schema file wants to enable one.\n                            # We have no way to know which one to enable.\n                            resource_type = found_nodes[0].unique_id.split(\".\")[0]\n                            msg = (\n                                f\"Found {len(found_nodes)} matching disabled nodes for \"\n                                f\"{resource_type} '{target.name}'. Multiple nodes for the same \"\n                                \"unique id cannot be enabled in the schema file. They must be enabled \"\n                                \"in `dbt_project.yml` or in the sql files.\"\n                            )\n                            raise ParsingError(msg)\n                        # We know that there's only one node in the disabled list because\n                        # otherwise we would have raised the error above\n                        found_node = found_nodes[0]\n                        self.manifest.disabled.pop(found_node.unique_id)\n                        assert isinstance(found_node, ModelNode)\n                        versioned_model_node = found_node\n                        add_node_nofile_fn = self.manifest.add_disabled_nofile\n                else:\n                    found_node = self.manifest.nodes.pop(versioned_model_unique_id)\n                    assert isinstance(found_node, ModelNode)\n                    versioned_model_node = found_node\n                    add_node_nofile_fn = self.manifest.add_node_nofile\n\n                if versioned_model_node is None:\n                    warn_or_error(\n                        NoNodeForYamlKey(\n                            patch_name=versioned_model_name,\n                            yaml_key=target.yaml_key,\n                            file_path=source_file.path.original_file_path,\n                        )\n                    )\n                    continue\n\n                # update versioned node unique_id\n                versioned_model_node_unique_id_old = versioned_model_node.unique_id\n                versioned_model_node.unique_id = (\n                    f\"model.{target.package_name}.{target.name}.{unparsed_version.formatted_v}\"\n                )\n                # update source file.nodes with new unique_id\n                model_source_file = self.manifest.files[versioned_model_node.file_id]\n                assert isinstance(model_source_file, SourceFile)\n                # because of incomplete test setup, check before removing\n                if versioned_model_node_unique_id_old in model_source_file.nodes:\n                    model_source_file.nodes.remove(versioned_model_node_unique_id_old)\n                model_source_file.nodes.append(versioned_model_node.unique_id)\n\n                # update versioned node fqn\n                versioned_model_node.fqn[-1] = target.name\n                versioned_model_node.fqn.append(unparsed_version.formatted_v)\n\n                # add versioned node back to nodes/disabled\n                add_node_nofile_fn(versioned_model_node)\n\n                # flatten columns based on include/exclude\n                version_refs: ParserRef = ParserRef.from_versioned_target(\n                    block.target, unparsed_version.v\n                )\n\n                versioned_model_patch = ParsedNodePatch(\n                    name=target.name,\n                    original_file_path=target.original_file_path,\n                    yaml_key=target.yaml_key,\n                    package_name=target.package_name,\n                    description=unparsed_version.description or target.description,\n                    columns=version_refs.column_info,\n                    meta=target.meta,\n                    docs=unparsed_version.docs or target.docs,\n                    config=deep_merge(target.config, unparsed_version.config),\n                    access=unparsed_version.access or target.access,\n                    version=unparsed_version.v,\n                    latest_version=latest_version,\n                    constraints=unparsed_version.constraints or target.constraints,\n                    deprecation_date=unparsed_version.deprecation_date,\n                )\n                # Node patched before config because config patching depends on model name,\n                # which may have been updated in the version patch\n                # versioned_model_node.patch(versioned_model_patch)\n                self.patch_node_properties(versioned_model_node, versioned_model_patch)\n\n                # Includes alias recomputation\n                self.patch_node_config(versioned_model_node, versioned_model_patch)\n\n                # Need to reapply setting constraints and contract checksum here, because\n                # they depend on node.contract.enabled, which wouldn't be set when\n                # patch_node_properties was called if it wasn't set in the model file.\n                self.patch_constraints(versioned_model_node, versioned_model_patch.constraints)\n                versioned_model_node.build_contract_checksum()\n                source_file.append_patch(\n                    versioned_model_patch.yaml_key, versioned_model_node.unique_id\n                )\n            self.manifest.rebuild_ref_lookup()\n            self.manifest.rebuild_disabled_lookup()\n\n    def _target_type(self) -> Type[UnparsedModelUpdate]:\n        return UnparsedModelUpdate\n\n    def patch_node_properties(self, node, patch: \"ParsedNodePatch\") -> None:\n        super().patch_node_properties(node, patch)\n\n        # Remaining patch properties are only relevant to ModelNode objects\n        if not isinstance(node, ModelNode):\n            return\n\n        node.version = patch.version\n        node.latest_version = patch.latest_version\n        node.deprecation_date = patch.deprecation_date\n        if patch.access:\n            if AccessType.is_valid(patch.access):\n                node.access = AccessType(patch.access)\n            else:\n                raise InvalidAccessTypeError(\n                    unique_id=node.unique_id,\n                    field_value=patch.access,\n                )\n        # breaking out False and None here is wordy but extra clear\n        semantic_model_enabled = patch.semantic_model is True or (\n            patch.semantic_model is not False\n            and patch.semantic_model is not None\n            and patch.semantic_model.enabled is not False\n        )\n        if semantic_model_enabled:\n            from dbt.parser.schema_yaml_readers import SemanticModelParser\n\n            semantic_model_parser = SemanticModelParser(self.schema_parser, self.yaml)\n            semantic_model_parser.parse_v2_semantic_model_from_dbt_model_patch(\n                node=node,\n                patch=patch,\n            )\n\n            from dbt.parser.schema_yaml_readers import MetricParser\n\n            MetricParser(self.schema_parser, self.yaml).parse_v2_metrics_from_dbt_model_patch(\n                patch\n            )\n\n        # These two will have to be reapplied after config is built for versioned models\n        self.patch_constraints(node, patch.constraints)\n        self.patch_time_spine(node, patch.time_spine)\n        node.build_contract_checksum()\n\n    def patch_constraints(self, node: ModelNode, constraints: List[Dict[str, Any]]) -> None:\n        contract_config = node.config.get(\"contract\")\n        if contract_config.enforced is True:\n            self._validate_constraint_prerequisites(node)\n\n            if any(\n                c for c in constraints if \"type\" not in c or not ConstraintType.is_valid(c[\"type\"])\n            ):\n                raise ParsingError(\n                    f\"Invalid constraint type on model {node.name}: \"\n                    f\"Type must be one of {[ct.value for ct in ConstraintType]}\"\n                )\n\n        self._validate_pk_constraints(node, constraints)\n        node.constraints = [ModelLevelConstraint.from_dict(c) for c in constraints]\n        self._process_constraints_refs_and_sources(node)\n\n    def _process_constraints_refs_and_sources(self, model_node: ModelNode) -> None:\n        \"\"\"\n        Populate model_node.refs and model_node.sources based on foreign-key constraint references,\n        whether defined at the model-level or column-level.\n        \"\"\"\n        for constraint in model_node.all_constraints:\n            if constraint.type == ConstraintType.foreign_key and constraint.to:\n                try:\n                    ref_or_source = statically_parse_ref_or_source(constraint.to)\n                except ParsingError:\n                    raise ParsingError(\n                        f\"Invalid 'ref' or 'source' syntax on foreign key constraint 'to' on model {model_node.name}: {constraint.to}.\"\n                    )\n\n                if isinstance(ref_or_source, RefArgs):\n                    model_node.refs.append(ref_or_source)\n                else:\n                    model_node.sources.append(ref_or_source)\n\n    def patch_time_spine(self, node: ModelNode, time_spine: Optional[TimeSpine]) -> None:\n        node.time_spine = time_spine\n\n    def _validate_pk_constraints(\n        self, model_node: ModelNode, constraints: List[Dict[str, Any]]\n    ) -> None:\n        errors = []\n        # check for primary key constraints defined at the column level\n        pk_col: List[str] = []\n        for col in model_node.columns.values():\n            for constraint in col.constraints:\n                if constraint.type == ConstraintType.primary_key:\n                    pk_col.append(col.name)\n\n        if len(pk_col) > 1:\n            errors.append(\n                f\"Found {len(pk_col)} columns ({pk_col}) with primary key constraints defined. \"\n                \"Primary keys for multiple columns must be defined as a model level constraint.\"\n            )\n\n        if len(pk_col) > 0 and (\n            any(\n                constraint.type == ConstraintType.primary_key\n                for constraint in model_node.constraints\n            )\n            or any(constraint[\"type\"] == ConstraintType.primary_key for constraint in constraints)\n        ):\n            errors.append(\n                \"Primary key constraints defined at the model level and the columns level. \"\n                \"Primary keys can be defined at the model level or the column level, not both.\"\n            )\n\n        if errors:\n            raise ParsingError(\n                f\"Primary key constraint error: ({model_node.original_file_path})\\n\"\n                + \"\\n\".join(errors)\n            )\n\n    def _validate_constraint_prerequisites(self, model_node: ModelNode) -> None:\n        column_warn_unsupported = [\n            constraint.warn_unsupported\n            for column in model_node.columns.values()\n            for constraint in column.constraints\n        ]\n        model_warn_unsupported = [\n            constraint.warn_unsupported for constraint in model_node.constraints\n        ]\n        warn_unsupported = column_warn_unsupported + model_warn_unsupported\n\n        # if any constraint has `warn_unsupported` as True then send the warning\n        if any(warn_unsupported) and not model_node.materialization_enforces_constraints:\n            warn_or_error(\n                UnsupportedConstraintMaterialization(materialized=model_node.config.materialized),\n                node=model_node,\n            )\n\n        errors = []\n        if not model_node.columns:\n            errors.append(\n                \"Constraints must be defined in a `yml` schema configuration file like `schema.yml`.\"\n            )\n\n        if str(model_node.language) != \"sql\":\n            errors.append(f\"Language Error: Expected 'sql' but found '{model_node.language}'\")\n\n        if errors:\n            raise ParsingError(\n                f\"Contract enforcement failed for: ({model_node.original_file_path})\\n\"\n                + \"\\n\".join(errors)\n            )\n\n\nclass AnalysisPatchParser(NodePatchParser[UnparsedAnalysisUpdate]):\n    def get_block(self, node: UnparsedAnalysisUpdate) -> TargetBlock:\n        return TargetBlock.from_yaml_block(self.yaml, node)\n\n    def _target_type(self) -> Type[UnparsedAnalysisUpdate]:\n        return UnparsedAnalysisUpdate\n\n\nclass SingularTestPatchParser(PatchParser[UnparsedSingularTestUpdate, ParsedSingularTestPatch]):\n    def get_block(self, node: UnparsedSingularTestUpdate) -> TargetBlock:\n        return TargetBlock.from_yaml_block(self.yaml, node)\n\n    def _target_type(self) -> Type[UnparsedSingularTestUpdate]:\n        return UnparsedSingularTestUpdate\n\n    def parse_patch(self, block: TargetBlock[UnparsedSingularTestUpdate], refs: ParserRef) -> None:\n        patch = ParsedSingularTestPatch(\n            name=block.target.name,\n            description=block.target.description,\n            meta=block.target.meta,\n            docs=block.target.docs,\n            config=block.target.config,\n            original_file_path=block.target.original_file_path,\n            yaml_key=block.target.yaml_key,\n            package_name=block.target.package_name,\n        )\n\n        assert isinstance(self.yaml.file, SchemaSourceFile)\n        source_file: SchemaSourceFile = self.yaml.file\n\n        unique_id = self.manifest.singular_test_lookup.get_unique_id(\n            block.name, block.target.package_name\n        )\n        if not unique_id:\n            warn_or_error(\n                NoNodeForYamlKey(\n                    patch_name=patch.name,\n                    yaml_key=patch.yaml_key,\n                    file_path=source_file.path.original_file_path,\n                )\n            )\n            return\n\n        node = self.manifest.nodes.get(unique_id)\n        assert node is not None\n\n        source_file.append_patch(patch.yaml_key, unique_id)\n        if patch.config:\n            self.patch_node_config(node, patch)\n\n        node.patch_path = patch.file_id\n        node.description = patch.description\n        node.created_at = time.time()\n\n\nclass FunctionPatchParser(NodePatchParser[UnparsedFunctionUpdate]):\n    def get_block(self, node: UnparsedFunctionUpdate) -> TargetBlock:\n        return TargetBlock.from_yaml_block(self.yaml, node)\n\n    def _target_type(self) -> Type[UnparsedFunctionUpdate]:\n        return UnparsedFunctionUpdate\n\n    def patch_node_properties(self, node, patch: \"ParsedNodePatch\") -> None:\n        super().patch_node_properties(node, patch)\n\n        assert isinstance(patch, ParsedFunctionPatch)\n        assert isinstance(node, FunctionNode)\n\n        node.arguments = patch.arguments\n        node.returns = patch.returns\n\n    def _get_node_patch(self, block: TargetBlock[NodeTarget], refs: ParserRef) -> ParsedNodePatch:\n        target = block.target\n        assert isinstance(target, UnparsedFunctionUpdate)\n\n        return ParsedFunctionPatch(\n            name=target.name,\n            original_file_path=target.original_file_path,\n            yaml_key=target.yaml_key,\n            package_name=target.package_name,\n            description=target.description,\n            columns=refs.column_info,\n            meta=target.meta,\n            docs=target.docs,\n            config=target.config,\n            access=target.access,\n            version=None,\n            latest_version=None,\n            constraints=target.constraints,\n            deprecation_date=None,\n            time_spine=None,\n            arguments=target.arguments,\n            returns=target.returns,\n        )\n\n\nclass MacroPatchParser(PatchParser[UnparsedMacroUpdate, ParsedMacroPatch]):\n    def get_block(self, node: UnparsedMacroUpdate) -> TargetBlock:\n        return TargetBlock.from_yaml_block(self.yaml, node)\n\n    def _target_type(self) -> Type[UnparsedMacroUpdate]:\n        return UnparsedMacroUpdate\n\n    def parse_patch(self, block: TargetBlock[UnparsedMacroUpdate], refs: ParserRef) -> None:\n        patch = ParsedMacroPatch(\n            name=block.target.name,\n            original_file_path=block.target.original_file_path,\n            yaml_key=block.target.yaml_key,\n            package_name=block.target.package_name,\n            arguments=block.target.arguments,\n            description=block.target.description,\n            meta=block.target.meta,\n            docs=block.target.docs,\n            config=block.target.config,\n        )\n        assert isinstance(self.yaml.file, SchemaSourceFile)\n        source_file = self.yaml.file\n        # macros are fully namespaced\n        unique_id = f\"macro.{patch.package_name}.{patch.name}\"\n        macro = self.manifest.macros.get(unique_id)\n        if not macro:\n            warn_or_error(MacroNotFoundForPatch(patch_name=patch.name))\n            return\n        if macro.patch_path:\n            package_name, existing_file_path = macro.patch_path.split(\"://\")\n            raise DuplicateMacroPatchNameError(patch, existing_file_path)\n        source_file.macro_patches[patch.name] = unique_id\n\n        # former macro.patch code\n        macro.patch_path = patch.file_id\n        macro.description = patch.description\n        macro.created_at = time.time()\n\n        meta = {**(patch.meta or {}), **(patch.config.get(\"meta\") or {})}\n        docs = patch.config.get(\"docs\") or patch.docs\n\n        # config inherits from HasConfig which is a dict so we need to cast it to Docs\n        if isinstance(docs, dict):\n            docs = Docs(**docs)\n\n        macro.meta = meta\n        macro.docs = docs\n        macro.config.meta = meta\n        macro.config.docs = docs\n\n        if getattr(get_flags(), \"validate_macro_args\", False):\n            self._check_patch_arguments(macro, patch)\n            macro.arguments = patch.arguments if patch.arguments else macro.arguments\n        else:\n            macro.arguments = patch.arguments\n\n    def _check_patch_arguments(self, macro: Macro, patch: ParsedMacroPatch) -> None:\n        if not patch.arguments:\n            return\n\n        for macro_arg, patch_arg in zip(macro.arguments, patch.arguments):\n            if patch_arg.name != macro_arg.name:\n                msg = f\"Argument {patch_arg.name} in yaml for macro {macro.name} does not match the jinja definition.\"\n                self._fire_macro_arg_warning(msg, macro)\n\n        if len(patch.arguments) != len(macro.arguments):\n            msg = f\"The number of arguments in the yaml for macro {macro.name} does not match the jinja definition.\"\n            self._fire_macro_arg_warning(msg, macro)\n\n        for patch_arg in patch.arguments:\n            arg_type = patch_arg.type\n            if arg_type is not None and arg_type.strip() != \"\" and not is_valid_type(arg_type):\n                msg = f\"Argument {patch_arg.name} in the yaml for macro {macro.name} has an invalid type.\"\n                self._fire_macro_arg_warning(msg, macro)\n\n    def _fire_macro_arg_warning(self, msg: str, macro: Macro) -> None:\n        warn_or_error(\n            InvalidMacroAnnotation(\n                msg=msg, macro_unique_id=macro.unique_id, macro_file_path=macro.original_file_path\n            )\n        )\n\n\n# valid type names, along with the number of parameters they require\nmacro_types: Dict[str, int] = {\n    \"str\": 0,\n    \"string\": 0,\n    \"bool\": 0,\n    \"int\": 0,\n    \"integer\": 0,\n    \"float\": 0,\n    \"any\": 0,\n    \"list\": 1,\n    \"dict\": 2,\n    \"optional\": 1,\n    \"relation\": 0,\n    \"column\": 0,\n}\n\n\ndef is_valid_type(buffer: str) -> bool:\n    buffer = buffer.replace(\" \", \"\").replace(\"\\t\", \"\")\n    type_desc, remainder = match_type_desc(buffer)\n    return type_desc is not None and remainder == \"\"\n\n\ndef match_type_desc(buffer: str) -> Tuple[Optional[str], str]:\n    \"\"\"A matching buffer is a type name followed by an argument list with\n    the correct number of arguments.\"\"\"\n    type_name, remainder = match_type_name(buffer)\n    if type_name is None:\n        return None, buffer\n    attr_list, remainder = match_arg_list(remainder, macro_types[type_name])\n    if attr_list is None:\n        return None, buffer\n    return type_name + attr_list, remainder\n\n\nalpha_pattern = re.compile(r\"[a-z]+\")\n\n\ndef match_type_name(buffer: str) -> Tuple[Optional[str], str]:\n    \"\"\"A matching buffer starts with one of the valid type names from macro_types\"\"\"\n    match = alpha_pattern.match(buffer)\n    if match is not None and buffer[: match.end(0)] in macro_types:\n        return buffer[: match.end(0)], buffer[match.end(0) :]\n    else:\n        return None, buffer\n\n\ndef match_arg_list(buffer: str, arg_count: int) -> Tuple[Optional[str], str]:\n    \"\"\"A matching buffer must begin with '[', followed by exactly arg_count type\n    specs, followed by ']'\"\"\"\n\n    if arg_count == 0:\n        return \"\", buffer\n\n    if not buffer.startswith(\"[\"):\n        return None, buffer\n\n    remainder = buffer[1:]\n    for i in range(arg_count):\n        type_desc, remainder = match_type_desc(remainder)\n        if type_desc is None:\n            return None, buffer\n        if i != arg_count - 1:\n            if not remainder.startswith(\",\"):\n                return None, buffer\n            remainder = remainder[1:]\n\n    if not remainder.startswith(\"]\"):\n        return None, buffer\n    else:\n        return \"\", remainder[1:]\n"
  },
  {
    "path": "core/dbt/parser/search.py",
    "content": "import os\nfrom dataclasses import dataclass\nfrom typing import (\n    Callable,\n    Generic,\n    Iterable,\n    Iterator,\n    List,\n    Optional,\n    Set,\n    TypeVar,\n    Union,\n)\n\nfrom pathspec import PathSpec  # type: ignore\n\nfrom dbt import deprecations\nfrom dbt.config import Project\nfrom dbt.contracts.files import AnySourceFile, FilePath\nfrom dbt.exceptions import DbtInternalError, ParsingError\nfrom dbt_common.clients._jinja_blocks import ExtractWarning\nfrom dbt_common.clients.jinja import BlockTag, extract_toplevel_blocks\nfrom dbt_common.clients.system import find_matching\n\n\n# What's the point of wrapping a SourceFile with this class?\n# Could it be removed?\n@dataclass\nclass FileBlock:\n    file: AnySourceFile\n\n    @property\n    def name(self):\n        base = os.path.basename(self.file.path.relative_path)\n        name, _ = os.path.splitext(base)\n        return name\n\n    @property\n    def contents(self):\n        return self.file.contents\n\n    @property\n    def path(self):\n        return self.file.path\n\n\n# The BlockTag is used in Jinja processing\n# Why do we have different classes where the only\n# difference is what 'contents' returns?\n@dataclass\nclass BlockContents(FileBlock):\n    file: AnySourceFile  # if you remove this, mypy will get upset\n    block: BlockTag\n\n    @property\n    def name(self):\n        return self.block.block_name\n\n    @property\n    def contents(self):\n        return self.block.contents\n\n\n@dataclass\nclass FullBlock(FileBlock):\n    file: AnySourceFile  # if you remove this, mypy will get upset\n    block: BlockTag\n\n    @property\n    def name(self):\n        return self.block.block_name\n\n    @property\n    def contents(self):\n        return self.block.full_block\n\n\ndef filesystem_search(\n    project: Project,\n    relative_dirs: List[str],\n    extension: str,\n    ignore_spec: Optional[PathSpec] = None,\n):\n    ext = \"[!.#~]*\" + extension\n    root = project.project_root\n    file_path_list = []\n    for result in find_matching(root, relative_dirs, ext, ignore_spec):\n        if \"searched_path\" not in result or \"relative_path\" not in result:\n            raise DbtInternalError(\"Invalid result from find_matching: {}\".format(result))\n        file_match = FilePath(\n            searched_path=result[\"searched_path\"],\n            relative_path=result[\"relative_path\"],\n            modification_time=result[\"modification_time\"],\n            project_root=root,\n        )\n        file_path_list.append(file_match)\n\n    return file_path_list\n\n\nBlock = Union[BlockContents, FullBlock]\n\nBlockSearchResult = TypeVar(\"BlockSearchResult\", BlockContents, FullBlock)\n\nBlockSearchResultFactory = Callable[[AnySourceFile, BlockTag], BlockSearchResult]\n\n\nclass BlockSearcher(Generic[BlockSearchResult], Iterable[BlockSearchResult]):\n    def __init__(\n        self,\n        source: List[FileBlock],\n        allowed_blocks: Set[str],\n        source_tag_factory: BlockSearchResultFactory,\n        check_jinja: bool = True,\n    ) -> None:\n        self.source = source\n        self.allowed_blocks = allowed_blocks\n        self.source_tag_factory: BlockSearchResultFactory = source_tag_factory\n        self.check_jinja = check_jinja\n\n    def extract_blocks(self, source_file: FileBlock) -> Iterable[BlockTag]:\n        # This is a bit of a hack to get the file path to the deprecation\n        def wrap_handle_extract_warning(warning: ExtractWarning) -> None:\n            self._handle_extract_warning(warning=warning, file=source_file.path.relative_path)\n\n        try:\n            blocks = extract_toplevel_blocks(\n                source_file.contents,\n                allowed_blocks=self.allowed_blocks,\n                collect_raw_data=False,\n                warning_callback=wrap_handle_extract_warning if self.check_jinja else None,\n            )\n            # this makes mypy happy, and this is an invariant we really need\n            for block in blocks:\n                assert isinstance(block, BlockTag)\n                yield block\n\n        except ParsingError as exc:\n            if exc.node is None:\n                exc.add_node(source_file)\n            raise\n\n    def _handle_extract_warning(self, warning: ExtractWarning, file: str) -> None:\n        deprecations.warn(\"unexpected-jinja-block-deprecation\", msg=warning.msg, file=file)\n\n    def __iter__(self) -> Iterator[BlockSearchResult]:\n        for entry in self.source:\n            for block in self.extract_blocks(entry):\n                yield self.source_tag_factory(entry.file, block)\n"
  },
  {
    "path": "core/dbt/parser/seeds.py",
    "content": "from dbt.context.context_config import ContextConfig\nfrom dbt.contracts.graph.nodes import SeedNode\nfrom dbt.node_types import NodeType\nfrom dbt.parser.base import SimpleSQLParser\nfrom dbt.parser.search import FileBlock\n\n\nclass SeedParser(SimpleSQLParser[SeedNode]):\n    def parse_from_dict(self, dct, validate=True) -> SeedNode:\n        # seeds need the root_path because the contents are not loaded\n        dct[\"root_path\"] = self.project.project_root\n        if \"language\" in dct:\n            del dct[\"language\"]\n        # raw_code is not currently used, but it might be in the future\n        if validate:\n            SeedNode.validate(dct)\n        return SeedNode.from_dict(dct)\n\n    @property\n    def resource_type(self) -> NodeType:\n        return NodeType.Seed\n\n    @classmethod\n    def get_compiled_path(cls, block: FileBlock):\n        return block.path.relative_path\n\n    def render_with_context(self, parsed_node: SeedNode, config: ContextConfig) -> None:\n        \"\"\"Seeds don't need to do any rendering.\"\"\"\n"
  },
  {
    "path": "core/dbt/parser/singular_test.py",
    "content": "from dbt.contracts.graph.nodes import SingularTestNode\nfrom dbt.node_types import NodeType\nfrom dbt.parser.base import SimpleSQLParser\nfrom dbt.parser.search import FileBlock\nfrom dbt.utils import get_pseudo_test_path\n\n\nclass SingularTestParser(SimpleSQLParser[SingularTestNode]):\n    def parse_from_dict(self, dct, validate=True) -> SingularTestNode:\n        if validate:\n            SingularTestNode.validate(dct)\n        return SingularTestNode.from_dict(dct)\n\n    @property\n    def resource_type(self) -> NodeType:\n        return NodeType.Test\n\n    @classmethod\n    def get_compiled_path(cls, block: FileBlock):\n        return get_pseudo_test_path(block.name, block.path.relative_path)\n"
  },
  {
    "path": "core/dbt/parser/snapshots.py",
    "content": "import os\nfrom typing import List\n\nfrom dbt.context.context_config import ContextConfig\nfrom dbt.contracts.graph.nodes import SnapshotNode\nfrom dbt.node_types import NodeType\nfrom dbt.parser.base import SQLParser\nfrom dbt.parser.search import BlockContents, BlockSearcher, FileBlock\nfrom dbt.utils import split_path\n\n\nclass SnapshotParser(SQLParser[SnapshotNode]):\n    def parse_from_dict(self, dct, validate=True) -> SnapshotNode:\n        if validate:\n            SnapshotNode.validate(dct)\n        return SnapshotNode.from_dict(dct)\n\n    @property\n    def resource_type(self) -> NodeType:\n        return NodeType.Snapshot\n\n    @classmethod\n    def get_compiled_path(cls, block: FileBlock):\n        return block.name + \".sql\"\n\n    def get_fqn(self, path: str, name: str) -> List[str]:\n        \"\"\"Get the FQN for the node. This impacts node selection and config\n        application.\n\n        On snapshots, the fqn includes the filename.\n        \"\"\"\n        no_ext = os.path.splitext(path)[0]\n        fqn = [self.project.project_name]\n        fqn.extend(split_path(no_ext))\n        fqn.append(name)\n        return fqn\n\n    def parse_node(self, block: FileBlock) -> SnapshotNode:\n        compiled_path: str = self.get_compiled_path(block)\n        # Use the file's relative_path for FQN computation (not the compiled_path)\n        # to maintain backward compatibility. The compiled_path is based on the\n        # snapshot name for uniqueness (multiple snapshots can share one file),\n        # but the FQN should still reflect the file structure.\n        fqn = self.get_fqn(block.path.relative_path, block.name)\n\n        config: ContextConfig = self.initial_config(fqn)\n\n        node = self._create_parsetime_node(\n            block=block,\n            path=compiled_path,\n            config=config,\n            fqn=fqn,\n        )\n        self.render_update(node, config)\n        self.add_result_node(block, node)\n        return node\n\n    def parse_file(self, file_block: FileBlock) -> None:\n        blocks = BlockSearcher(\n            source=[file_block],\n            allowed_blocks={\"snapshot\"},\n            source_tag_factory=BlockContents,\n        )\n        for block in blocks:\n            self.parse_node(block)\n"
  },
  {
    "path": "core/dbt/parser/sources.py",
    "content": "import itertools\nfrom dataclasses import replace\nfrom pathlib import Path\nfrom typing import Any, Dict, Iterable, List, Optional, Set, Tuple\n\nfrom dbt.adapters.capability import Capability\nfrom dbt.adapters.factory import get_adapter\nfrom dbt.artifacts.resources import FreshnessThreshold, SourceConfig, Time\nfrom dbt.config import RuntimeConfig\nfrom dbt.context.context_config import (\n    BaseContextConfigGenerator,\n    ContextConfigGenerator,\n    UnrenderedConfigGenerator,\n)\nfrom dbt.contracts.graph.manifest import Manifest, SourceKey\nfrom dbt.contracts.graph.nodes import (\n    GenericTestNode,\n    SourceDefinition,\n    UnpatchedSourceDefinition,\n)\nfrom dbt.contracts.graph.unparsed import (\n    SourcePatch,\n    SourceTablePatch,\n    UnparsedColumn,\n    UnparsedSourceDefinition,\n    UnparsedSourceTableDefinition,\n)\nfrom dbt.events.types import FreshnessConfigProblem, UnusedTables, ValidationWarning\nfrom dbt.exceptions import ParsingError\nfrom dbt.node_types import NodeType\nfrom dbt.parser.common import ParserRef\nfrom dbt.parser.schema_generic_tests import SchemaGenericTestParser\nfrom dbt_common.events.functions import fire_event, warn_or_error\nfrom dbt_common.exceptions import DbtInternalError\n\n\n# An UnparsedSourceDefinition is taken directly from the yaml\n# file. It can affect multiple tables, all of which will eventually\n# have their own source node. An UnparsedSourceDefinition will\n# generate multiple UnpatchedSourceDefinition nodes (one per\n# table) in the SourceParser.add_source_definitions. The\n# SourcePatcher takes an UnparsedSourceDefinition and the\n# SourcePatch and produces a SourceDefinition. Each\n# SourcePatch can be applied to multiple UnpatchedSourceDefinitions.\nclass SourcePatcher:\n    def __init__(\n        self,\n        root_project: RuntimeConfig,\n        manifest: Manifest,\n    ) -> None:\n        self.root_project = root_project\n        self.manifest = manifest\n        self.generic_test_parsers: Dict[str, SchemaGenericTestParser] = {}\n        self.patches_used: Dict[SourceKey, Set[str]] = {}\n        self.sources: Dict[str, SourceDefinition] = {}\n        self._deprecations: Set[Any] = set()\n\n    # This method calls the 'parse_source' method which takes\n    # the UnpatchedSourceDefinitions in the manifest and combines them\n    # with SourcePatches to produce SourceDefinitions.\n    def construct_sources(self) -> None:\n        for unique_id, unpatched in self.manifest.sources.items():\n            schema_file = self.manifest.files[unpatched.file_id]\n            if isinstance(unpatched, SourceDefinition):\n                # In partial parsing, there will be SourceDefinitions\n                # which must be retained.\n                self.sources[unpatched.unique_id] = unpatched\n                continue\n            # returns None if there is no patch\n            patch = self.get_patch_for(unpatched)\n\n            # returns unpatched if there is no patch\n            patched = self.patch_source(unpatched, patch)\n\n            # now use the patched UnpatchedSourceDefinition to extract test data.\n            for test in self.get_source_tests(patched):\n                if test.config.enabled:\n                    self.manifest.add_node_nofile(test)\n                else:\n                    self.manifest.add_disabled_nofile(test)\n                # save the test unique_id in the schema_file, so we can\n                # process in partial parsing\n                test_from = {\"key\": \"sources\", \"name\": patched.source.name}\n                schema_file.add_test(test.unique_id, test_from)\n\n            # Convert UnpatchedSourceDefinition to a SourceDefinition\n            parsed = self.parse_source(patched)\n            if parsed.config.enabled:\n                self.sources[unique_id] = parsed\n            else:\n                self.manifest.add_disabled_nofile(parsed)\n\n        self.warn_unused()\n\n    def patch_source(\n        self,\n        unpatched: UnpatchedSourceDefinition,\n        patch: Optional[SourcePatch],\n    ) -> UnpatchedSourceDefinition:\n\n        # This skips patching if no patch exists because of the\n        # performance overhead of converting to and from dicts\n        if patch is None:\n            return unpatched\n\n        source_dct = unpatched.source.to_dict(omit_none=True)\n        table_dct = unpatched.table.to_dict(omit_none=True)\n        patch_path: Optional[Path] = None\n\n        source_table_patch: Optional[SourceTablePatch] = None\n\n        if patch is not None:\n            source_table_patch = patch.get_table_named(unpatched.table.name)\n            source_dct.update(patch.to_patch_dict())\n            patch_path = patch.path\n\n        if source_table_patch is not None:\n            table_dct.update(source_table_patch.to_patch_dict())\n\n        source = UnparsedSourceDefinition.from_dict(source_dct)\n        table = UnparsedSourceTableDefinition.from_dict(table_dct)\n        return replace(unpatched, source=source, table=table, patch_path=patch_path)\n\n    # This converts an UnpatchedSourceDefinition to a SourceDefinition\n    def parse_source(self, target: UnpatchedSourceDefinition) -> SourceDefinition:\n        source = target.source\n        table = target.table\n        refs = ParserRef.from_target(table)\n        unique_id = target.unique_id\n        description = table.description or \"\"\n        source_description = source.description or \"\"\n\n        quoting = source.quoting.merged(table.quoting)\n        # Retain original source meta prior to merge with table meta\n        source_meta = {**source.meta, **source.config.get(\"meta\", {})}\n\n        config = self._generate_source_config(\n            target=target,\n            rendered=True,\n        )\n\n        config = config.finalize_and_validate()\n\n        unrendered_config = self._generate_source_config(\n            target=target,\n            rendered=False,\n        )\n\n        if not isinstance(config, SourceConfig):\n            raise DbtInternalError(\n                f\"Calculated a {type(config)} for a source, but expected a SourceConfig\"\n            )\n\n        default_database = self.root_project.credentials.database\n\n        parsed_source = SourceDefinition(\n            package_name=target.package_name,\n            database=(source.database or default_database),\n            unrendered_database=source.unrendered_database,\n            schema=(source.schema or source.name),\n            unrendered_schema=source.unrendered_schema,\n            identifier=(table.identifier or table.name),\n            path=target.path,\n            original_file_path=target.original_file_path,\n            columns=refs.column_info,\n            unique_id=unique_id,\n            name=table.name,\n            description=description,\n            external=table.external,\n            source_name=source.name,\n            source_description=source_description,\n            source_meta=source_meta,\n            meta=config.meta,\n            loader=source.loader,\n            loaded_at_field=config.loaded_at_field,\n            loaded_at_query=config.loaded_at_query,\n            freshness=config.freshness,\n            quoting=quoting,\n            resource_type=NodeType.Source,\n            fqn=target.fqn,\n            tags=config.tags,\n            config=config,\n            unrendered_config=unrendered_config,\n        )\n\n        if (\n            parsed_source.freshness\n            and not parsed_source.loaded_at_field\n            and not parsed_source.loaded_at_query\n            and not get_adapter(self.root_project).supports(Capability.TableLastModifiedMetadata)\n        ):\n            # Metadata-based freshness is being used by default for this node,\n            # but is not available through the configured adapter, so warn the\n            # user that freshness info will not be collected for this node at\n            # runtime.\n            fire_event(\n                FreshnessConfigProblem(\n                    msg=f\"The configured adapter does not support metadata-based freshness. A loaded_at_field must be specified for source '{source.name}.{table.name}'.\"\n                )\n            )\n\n        # relation name is added after instantiation because the adapter does\n        # not provide the relation name for a UnpatchedSourceDefinition object\n        parsed_source.relation_name = self._get_relation_name(parsed_source)\n        return parsed_source\n\n    # Use the SchemaGenericTestParser to parse the source tests\n    def get_generic_test_parser_for(self, package_name: str) -> \"SchemaGenericTestParser\":\n        if package_name in self.generic_test_parsers:\n            generic_test_parser = self.generic_test_parsers[package_name]\n        else:\n            all_projects = self.root_project.load_dependencies()\n            project = all_projects[package_name]\n            generic_test_parser = SchemaGenericTestParser(\n                project, self.manifest, self.root_project\n            )\n            self.generic_test_parsers[package_name] = generic_test_parser\n        return generic_test_parser\n\n    def get_source_tests(self, target: UnpatchedSourceDefinition) -> Iterable[GenericTestNode]:\n        is_root_project = True if self.root_project.project_name == target.package_name else False\n        target.validate_data_tests(is_root_project)\n        for data_test, column in target.get_tests():\n            yield self.parse_source_test(\n                target=target,\n                data_test=data_test,\n                column=column,\n            )\n\n    def get_patch_for(\n        self,\n        unpatched: UnpatchedSourceDefinition,\n    ) -> Optional[SourcePatch]:\n        if isinstance(unpatched, SourceDefinition):\n            return None\n        key = (unpatched.package_name, unpatched.source.name)\n        patch: Optional[SourcePatch] = self.manifest.source_patches.get(key)\n        if patch is None:\n            return None\n        if key not in self.patches_used:\n            # mark the key as used\n            self.patches_used[key] = set()\n        if patch.get_table_named(unpatched.table.name) is not None:\n            self.patches_used[key].add(unpatched.table.name)\n        return patch\n\n    # This calls parse_generic_test in the SchemaGenericTestParser\n    def parse_source_test(\n        self,\n        target: UnpatchedSourceDefinition,\n        data_test: Dict[str, Any],\n        column: Optional[UnparsedColumn],\n    ) -> GenericTestNode:\n        column_name: Optional[str]\n        if column is None:\n            column_name = None\n        else:\n            column_name = column.name\n            should_quote = column.quote or (column.quote is None and target.quote_columns)\n            if should_quote:\n                column_name = get_adapter(self.root_project).quote(column_name)\n\n        tags_sources = [target.source.tags, target.table.tags]\n        if column is not None:\n            tags_sources.append(column.tags)\n            if column_config_tags := column.config.get(\"tags\", []):\n                if isinstance(column_config_tags, list):\n                    tags_sources.append(column_config_tags)\n                elif isinstance(column_config_tags, str):\n                    tags_sources.append([column_config_tags])\n        tags = list(itertools.chain.from_iterable(tags_sources))\n\n        generic_test_parser = self.get_generic_test_parser_for(target.package_name)\n        node = generic_test_parser.parse_generic_test(\n            target=target,\n            data_test=data_test,\n            tags=tags,\n            column_name=column_name,\n            schema_file_id=target.file_id,\n            version=None,\n        )\n        return node\n\n    def _generate_source_config(self, target: UnpatchedSourceDefinition, rendered: bool):\n        generator: BaseContextConfigGenerator\n        if rendered:\n            generator = ContextConfigGenerator(self.root_project)\n        else:\n            generator = UnrenderedConfigGenerator(self.root_project)\n\n        # configs with precendence set\n        precedence_configs = dict()\n        # first apply source configs\n        precedence_configs.update(target.source.config)\n        # then overrite anything that is defined on source tables\n        # this is not quite complex enough for configs that can be set as top-level node keys, but\n        # it works while source configs can only include `enabled`.\n        precedence_configs.update(target.table.config)\n\n        precedence_freshness = self.calculate_freshness_from_raw_target(target)\n        if precedence_freshness:\n            precedence_configs[\"freshness\"] = precedence_freshness.to_dict()\n        elif precedence_freshness is None:\n            precedence_configs[\"freshness\"] = None\n        else:\n            # this means that the user did not set a freshness threshold in the source schema file, as such\n            # there should be no freshness precedence\n            precedence_configs.pop(\"freshness\", None)\n\n        precedence_loaded_at_field, precedence_loaded_at_query = (\n            self.calculate_loaded_at_field_query_from_raw_target(target)\n        )\n        precedence_configs[\"loaded_at_field\"] = precedence_loaded_at_field\n        precedence_configs[\"loaded_at_query\"] = precedence_loaded_at_query\n\n        # Handle merges across source, table, and config for meta and tags\n        precedence_meta = self.calculate_meta_from_raw_target(target)\n        precedence_configs[\"meta\"] = precedence_meta\n\n        precedence_tags = self.calculate_tags_from_raw_target(target)\n        precedence_configs[\"tags\"] = precedence_tags\n\n        # Because freshness is a \"object\" config, the freshness from the dbt_project.yml and the freshness\n        # from the schema file _won't_ get merged by this process. The result will be that the freshness will\n        # come from the schema file if provided, and if not, it'll fall back to the dbt_project.yml freshness.\n        return generator.calculate_node_config(\n            config_call_dict={},\n            fqn=target.fqn,\n            resource_type=NodeType.Source,\n            project_name=target.package_name,\n            base=False,\n            patch_config_dict=precedence_configs,\n        )\n\n    def _get_relation_name(self, node: SourceDefinition):\n        adapter = get_adapter(self.root_project)\n        relation_cls = adapter.Relation\n        return str(relation_cls.create_from(self.root_project, node))\n\n    def warn_unused(self) -> None:\n        unused_tables: Dict[SourceKey, Optional[Set[str]]] = {}\n        for patch in self.manifest.source_patches.values():\n            key = (patch.overrides, patch.name)\n            if key not in self.patches_used:\n                unused_tables[key] = None\n            elif patch.tables is not None:\n                table_patches = {t.name for t in patch.tables}\n                unused = table_patches - self.patches_used[key]\n                # don't add unused tables, the\n                if unused:\n                    # because patches are required to be unique, we can safely\n                    # write without looking\n                    unused_tables[key] = unused\n\n        if unused_tables:\n            unused_tables_formatted = self.get_unused_msg(unused_tables)\n            warn_or_error(UnusedTables(unused_tables=unused_tables_formatted))\n\n        self.manifest.source_patches = {}\n\n    def get_unused_msg(\n        self,\n        unused_tables: Dict[SourceKey, Optional[Set[str]]],\n    ) -> List:\n        unused_tables_formatted = []\n        for key, table_names in unused_tables.items():\n            patch = self.manifest.source_patches[key]\n            patch_name = f\"{patch.overrides}.{patch.name}\"\n            if table_names is None:\n                unused_tables_formatted.append(f\"  - Source {patch_name} (in {patch.path})\")\n            else:\n                for table_name in sorted(table_names):\n                    unused_tables_formatted.append(\n                        f\"  - Source table {patch_name}.{table_name} \" f\"(in {patch.path})\"\n                    )\n        return unused_tables_formatted\n\n    def calculate_freshness_from_raw_target(\n        self,\n        target: UnpatchedSourceDefinition,\n    ) -> Optional[FreshnessThreshold]:\n        source: UnparsedSourceDefinition = target.source\n\n        source_freshness = source.freshness\n\n        source_config_freshness_raw: Optional[Dict] = source.config.get(\n            \"freshness\", {}\n        )  # Will only be None if the user explicitly set it to null\n        source_config_freshness: Optional[FreshnessThreshold] = (\n            FreshnessThreshold.from_dict(source_config_freshness_raw)\n            if source_config_freshness_raw is not None\n            else None\n        )\n\n        table: UnparsedSourceTableDefinition = target.table\n        table_freshness = table.freshness\n\n        table_config_freshness_raw: Optional[Dict] = table.config.get(\n            \"freshness\", {}\n        )  # Will only be None if the user explicitly set it to null\n        table_config_freshness: Optional[FreshnessThreshold] = (\n            FreshnessThreshold.from_dict(table_config_freshness_raw)\n            if table_config_freshness_raw is not None\n            else None\n        )\n\n        return merge_source_freshness(\n            source_freshness,\n            source_config_freshness,\n            table_freshness,\n            table_config_freshness,\n        )\n\n    def calculate_loaded_at_field_query_from_raw_target(\n        self, target: UnpatchedSourceDefinition\n    ) -> Tuple[Optional[str], Optional[str]]:\n        # We need to be able to tell the difference between explicitly setting the loaded_at_field to None/null\n        # and when it's simply not set.  This allows a user to override the source level loaded_at_field so that\n        # specific table can default to metadata-based freshness.\n\n        # loaded_at_field and loaded_at_query are supported both at top-level (deprecated) and config-level (preferred) on sources and tables.\n        if target.table.loaded_at_field_present and (\n            target.table.loaded_at_query or target.table.config.get(\"loaded_at_query\")\n        ):\n            raise ParsingError(\n                \"Cannot specify both loaded_at_field and loaded_at_query at table level.\"\n            )\n        if (target.source.loaded_at_field or target.source.config.get(\"loaded_at_field\")) and (\n            target.source.loaded_at_query or target.source.config.get(\"loaded_at_query\")\n        ):\n            raise ParsingError(\n                \"Cannot specify both loaded_at_field and loaded_at_query at source level.\"\n            )\n\n        if (\n            target.table.loaded_at_field_present\n            or target.table.loaded_at_field is not None\n            or target.table.config.get(\"loaded_at_field\") is not None\n        ):\n            loaded_at_field = target.table.loaded_at_field or target.table.config.get(\n                \"loaded_at_field\"\n            )\n        else:\n            loaded_at_field = target.source.loaded_at_field or target.source.config.get(\n                \"loaded_at_field\"\n            )  # may be None, that's okay\n\n        loaded_at_query: Optional[str]\n        if (\n            target.table.loaded_at_query is not None\n            or target.table.config.get(\"loaded_at_query\") is not None\n        ):\n            loaded_at_query = target.table.loaded_at_query or target.table.config.get(\n                \"loaded_at_query\"\n            )\n        else:\n            if target.table.loaded_at_field_present:\n                loaded_at_query = None\n            else:\n                loaded_at_query = target.source.loaded_at_query or target.source.config.get(\n                    \"loaded_at_query\"\n                )\n\n        return loaded_at_field, loaded_at_query\n\n    def calculate_meta_from_raw_target(self, target: UnpatchedSourceDefinition) -> Dict[str, Any]:\n        source_meta = target.source.meta or {}\n        source_config_meta = target.source.config.get(\"meta\", {})\n        source_config_meta = source_config_meta if isinstance(source_config_meta, dict) else {}\n\n        table_meta = target.table.meta or {}\n        table_config_meta = target.table.config.get(\"meta\", {})\n        table_config_meta = table_config_meta if isinstance(table_config_meta, dict) else {}\n\n        return {**source_meta, **source_config_meta, **table_meta, **table_config_meta}\n\n    def calculate_tags_from_raw_target(self, target: UnpatchedSourceDefinition) -> List[str]:\n        source_tags = target.source.tags or []\n        source_config_tags = self._get_config_tags(\n            target.source.config.get(\"tags\", []), target.source.name\n        )\n\n        table_tags = target.table.tags or []\n        table_config_tags = self._get_config_tags(\n            target.table.config.get(\"tags\", []), target.table.name\n        )\n\n        return sorted(\n            set(itertools.chain(source_tags, source_config_tags, table_tags, table_config_tags))\n        )\n\n    def _get_config_tags(self, tags: Any, source_name: str) -> List[str]:\n        config_tags = tags if isinstance(tags, list) else [tags]\n\n        config_tags_valid: List[str] = []\n        for tag in config_tags:\n            if not isinstance(tag, str):\n                warn_or_error(\n                    ValidationWarning(\n                        field_name=f\"`config.tags`: {tags}\",\n                        resource_type=NodeType.Source.value,\n                        node_name=source_name,\n                    )\n                )\n            else:\n                config_tags_valid.append(tag)\n\n        return config_tags_valid\n\n\ndef merge_freshness_time_thresholds(\n    base: Optional[Time], update: Optional[Time]\n) -> Optional[Time]:\n    if base and update:\n        return base.merged(update)\n    elif update is None:\n        return None\n    else:\n        return update or base\n\n\ndef merge_source_freshness(\n    *thresholds: Optional[FreshnessThreshold],\n) -> Optional[FreshnessThreshold]:\n    if not thresholds:\n        return None\n\n    # Initialize with the first threshold.\n    # If the first threshold is None, current_merged_value will be None,\n    # and subsequent merges will correctly follow the original logic.\n    current_merged_value: Optional[FreshnessThreshold] = thresholds[0]\n\n    # Iterate through the rest of the thresholds, applying the original pairwise logic\n    for i in range(1, len(thresholds)):\n        base = current_merged_value\n        update = thresholds[i]\n\n        if base is not None and update is not None:\n            merged_freshness_obj = base.merged(update)\n            # merge one level deeper the error_after and warn_after thresholds\n            merged_error_after = merge_freshness_time_thresholds(\n                base.error_after, update.error_after\n            )\n            merged_warn_after = merge_freshness_time_thresholds(base.warn_after, update.warn_after)\n\n            merged_freshness_obj.error_after = merged_error_after\n            merged_freshness_obj.warn_after = merged_warn_after\n            current_merged_value = merged_freshness_obj\n        elif base is None and bool(update):\n            # If current_merged_value (base) is None, the update becomes the new value\n            current_merged_value = update\n        else:  # This covers cases where 'update' is None, or both 'base' and 'update' are None.\n            # Following original logic, if 'update' is None, the result of the pair-merge is None.\n            current_merged_value = None\n\n    return current_merged_value\n"
  },
  {
    "path": "core/dbt/parser/sql.py",
    "content": "import os\nfrom dataclasses import dataclass\nfrom typing import Iterable\n\nfrom dbt.contracts.graph.manifest import SourceFile\nfrom dbt.contracts.graph.nodes import Macro, SqlNode\nfrom dbt.contracts.graph.unparsed import UnparsedMacro\nfrom dbt.node_types import NodeType\nfrom dbt.parser.base import SimpleSQLParser\nfrom dbt.parser.macros import MacroParser\nfrom dbt.parser.search import FileBlock\nfrom dbt_common.exceptions import DbtInternalError\n\n\n@dataclass\nclass SqlBlock(FileBlock):\n    block_name: str\n\n    @property\n    def name(self):\n        return self.block_name\n\n\nclass SqlBlockParser(SimpleSQLParser[SqlNode]):\n    def parse_from_dict(self, dct, validate=True) -> SqlNode:\n        if validate:\n            SqlNode.validate(dct)\n        return SqlNode.from_dict(dct)\n\n    @property\n    def resource_type(self) -> NodeType:\n        return NodeType.SqlOperation\n\n    @staticmethod\n    def get_compiled_path(block: FileBlock):\n        # we do it this way to make mypy happy\n        if not isinstance(block, SqlBlock):\n            raise DbtInternalError(\n                \"While parsing SQL operation, got an actual file block instead of \"\n                \"an SQL block: {}\".format(block)\n            )\n\n        return os.path.join(\"sql\", block.name)\n\n    def parse_remote(self, sql: str, name: str) -> SqlNode:\n        source_file = SourceFile.remote(sql, self.project.project_name, \"sql\")\n        contents = SqlBlock(block_name=name, file=source_file)\n        return self.parse_node(contents)\n\n\nclass SqlMacroParser(MacroParser):\n    def parse_remote(self, contents) -> Iterable[Macro]:\n        base = UnparsedMacro(\n            path=\"from remote system\",\n            original_file_path=\"from remote system\",\n            package_name=self.project.project_name,\n            raw_code=contents,\n            language=\"sql\",\n            resource_type=NodeType.Macro,\n        )\n        for node in self.parse_unparsed_macros(base):\n            yield node\n"
  },
  {
    "path": "core/dbt/parser/unit_tests.py",
    "content": "import csv\nimport os\nfrom copy import deepcopy\nfrom csv import DictReader\nfrom io import StringIO\nfrom pathlib import Path\nfrom typing import Any, Dict, List, Optional, Set\n\nfrom dbt import utils\nfrom dbt.artifacts.resources import ModelConfig, UnitTestConfig, UnitTestFormat\nfrom dbt.config import RuntimeConfig\nfrom dbt.context.context_config import ContextConfig\nfrom dbt.context.providers import generate_parser_unit_test_context, get_rendered\nfrom dbt.contracts.files import FileHash, SchemaSourceFile\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.contracts.graph.model_config import UnitTestNodeConfig\nfrom dbt.contracts.graph.nodes import (\n    DependsOn,\n    ModelNode,\n    UnitTestDefinition,\n    UnitTestNode,\n    UnitTestSourceDefinition,\n)\nfrom dbt.contracts.graph.unparsed import UnparsedUnitTest\nfrom dbt.exceptions import InvalidUnitTestGivenInput, ParsingError\nfrom dbt.flags import get_flags\nfrom dbt.graph import UniqueId\nfrom dbt.node_types import NodeType\nfrom dbt.parser.schemas import (\n    JSONValidationError,\n    ParseResult,\n    SchemaParser,\n    ValidationError,\n    YamlBlock,\n    YamlParseDictError,\n    YamlReader,\n)\nfrom dbt.utils import get_pseudo_test_path\nfrom dbt_common.events.functions import fire_event\nfrom dbt_common.events.types import SystemStdErr\nfrom dbt_extractor import ExtractionError, py_extract_from_source  # type: ignore\n\n\nclass UnitTestManifestLoader:\n    def __init__(self, manifest, root_project, selected) -> None:\n        self.manifest: Manifest = manifest\n        self.root_project: RuntimeConfig = root_project\n        # selected comes from the initial selection against a \"regular\" manifest\n        self.selected: Set[UniqueId] = selected\n        self.unit_test_manifest = Manifest(macros=manifest.macros)\n\n    def load(self) -> Manifest:\n        for unique_id in self.selected:\n            if unique_id in self.manifest.unit_tests:\n                unit_test_case: UnitTestDefinition = self.manifest.unit_tests[unique_id]\n                if not unit_test_case.config.enabled:\n                    continue\n                self.parse_unit_test_case(unit_test_case)\n        return self.unit_test_manifest\n\n    def parse_unit_test_case(self, test_case: UnitTestDefinition):\n        # Create unit test node based on the node being tested\n        # The tested_node has already been resolved and is in depends_on.nodes\n        tested_node_unique_id = test_case.depends_on.nodes[0]\n        tested_node = self.manifest.nodes[tested_node_unique_id]\n        assert isinstance(tested_node, ModelNode)\n\n        # Create UnitTestNode based on model being tested. Since selection has\n        # already been done, we don't have to care about fields that are necessary\n        # for selection.\n        # Note: no depends_on, that's added later using input nodes\n        name = test_case.name\n        if tested_node.is_versioned:\n            name = name + f\"_v{tested_node.version}\"\n        expected_sql: Optional[str] = None\n        if test_case.expect.format == UnitTestFormat.SQL:\n            expected_rows: List[Dict[str, Any]] = []\n            expected_sql = test_case.expect.rows  # type: ignore\n        else:\n            assert isinstance(test_case.expect.rows, List)\n            expected_rows = deepcopy(test_case.expect.rows)\n\n        assert isinstance(expected_rows, List)\n        unit_test_node = UnitTestNode(\n            name=name,\n            resource_type=NodeType.Unit,\n            package_name=test_case.package_name,\n            path=get_pseudo_test_path(name, test_case.original_file_path),\n            original_file_path=test_case.original_file_path,\n            unique_id=test_case.unique_id,\n            config=UnitTestNodeConfig(\n                materialized=\"unit\", expected_rows=expected_rows, expected_sql=expected_sql\n            ),\n            raw_code=tested_node.raw_code,\n            database=tested_node.database,\n            schema=tested_node.schema,\n            alias=name,\n            fqn=test_case.unique_id.split(\".\"),\n            checksum=FileHash.empty(),\n            tested_node_unique_id=tested_node.unique_id,\n            overrides=test_case.overrides,\n        )\n\n        ctx = generate_parser_unit_test_context(unit_test_node, self.root_project, self.manifest)\n        get_rendered(unit_test_node.raw_code, ctx, unit_test_node, capture_macros=True)\n        # unit_test_node now has a populated refs/sources\n\n        self.unit_test_manifest.nodes[unit_test_node.unique_id] = unit_test_node\n        # Now create input_nodes for the test inputs\n        \"\"\"\n        given:\n          - input: ref('my_model_a')\n            rows: []\n          - input: ref('my_model_b')\n            rows:\n              - {id: 1, b: 2}\n              - {id: 2, b: 2}\n        \"\"\"\n        # Add the model \"input\" nodes, consisting of all referenced models in the unit test.\n        # This creates an ephemeral model for every input in every test, so there may be multiple\n        # input models substituting for the same input ref'd model. Note that since these are\n        # always \"ephemeral\" they just wrap the tested_node SQL in additional CTEs. No actual table\n        # or view is created.\n        for given in test_case.given:\n            # extract the original_input_node from the ref in the \"input\" key of the given list\n            original_input_node = self._get_original_input_node(\n                given.input, tested_node, test_case.name, ctx, unit_test_node\n            )\n            input_name = original_input_node.name\n            common_fields = {\n                \"resource_type\": NodeType.Model,\n                # root directory for input and output fixtures\n                \"original_file_path\": unit_test_node.original_file_path,\n                \"config\": ModelConfig(materialized=\"ephemeral\"),\n                \"database\": original_input_node.database,\n                \"alias\": original_input_node.identifier,\n                \"schema\": original_input_node.schema,\n                \"fqn\": original_input_node.fqn,\n                \"checksum\": FileHash.empty(),\n                \"raw_code\": self._build_fixture_raw_code(given.rows, None, given.format),\n                \"package_name\": original_input_node.package_name,\n                \"unique_id\": f\"model.{original_input_node.package_name}.{input_name}\",\n                \"name\": input_name,\n                \"path\": f\"{input_name}.sql\",\n            }\n            resource_type = original_input_node.resource_type\n\n            if resource_type in (\n                NodeType.Model,\n                NodeType.Seed,\n                NodeType.Snapshot,\n            ):\n\n                input_node = ModelNode(\n                    **common_fields,\n                    defer_relation=original_input_node.defer_relation,\n                )\n                if resource_type == NodeType.Model:\n                    if original_input_node.version:\n                        input_node.version = original_input_node.version\n                    if original_input_node.latest_version:\n                        input_node.latest_version = original_input_node.latest_version\n\n            elif resource_type == NodeType.Source:\n                # We are reusing the database/schema/identifier from the original source,\n                # but that shouldn't matter since this acts as an ephemeral model which just\n                # wraps a CTE around the unit test node.\n                input_node = UnitTestSourceDefinition(\n                    **common_fields,\n                    source_name=original_input_node.source_name,  # needed for source lookup\n                )\n                # In the case of multiple sources with the same name, we add the source schema name to the unique id.\n                # This additionally prevents duplicate CTE names during compilation.\n                input_node.unique_id = f\"model.{original_input_node.package_name}.{original_input_node.source_name}__{input_name}\"\n\n                # Sources need to go in the sources dictionary in order to create the right lookup\n                self.unit_test_manifest.sources[input_node.unique_id] = input_node  # type: ignore\n\n            # Both ModelNode and UnitTestSourceDefinition need to go in nodes dictionary\n            self.unit_test_manifest.nodes[input_node.unique_id] = input_node\n\n            # Populate this_input_node_unique_id if input fixture represents node being tested\n            if original_input_node == tested_node:\n                unit_test_node.this_input_node_unique_id = input_node.unique_id\n\n            # Add unique ids of input_nodes to depends_on\n            unit_test_node.depends_on.nodes.append(input_node.unique_id)\n\n        # Add functions to the manifest and depends_on\n        for unique_id in tested_node.depends_on.nodes:\n            if unique_id in self.manifest.functions:\n                unit_test_node.depends_on.nodes.append(unique_id)\n                self.unit_test_manifest.functions[unique_id] = self.manifest.functions[unique_id]\n\n    def _build_fixture_raw_code(self, rows, column_name_to_data_types, fixture_format) -> str:\n        # We're not currently using column_name_to_data_types, but leaving here for\n        # possible future use.\n        if fixture_format == UnitTestFormat.SQL:\n            return rows\n        else:\n            return (\"{{{{ get_fixture_sql({rows}, {column_name_to_data_types}) }}}}\").format(\n                rows=rows, column_name_to_data_types=column_name_to_data_types\n            )\n\n    def _get_original_input_node(\n        self,\n        input: str,\n        tested_node: ModelNode,\n        test_case_name: str,\n        ctx: Optional[Dict[str, Any]] = None,\n        unit_test_node: Optional[UnitTestNode] = None,\n    ):\n        \"\"\"\n        Returns the original input node as defined in the project given an input reference\n        and the node being tested.\n\n        input: str representing how input node is referenced in tested model sql\n          * examples:\n            - \"ref('my_model_a')\"\n            - \"source('my_source_schema', 'my_source_name')\"\n            - \"this\"\n        tested_node: ModelNode of representing node being tested\n        \"\"\"\n        if input.strip() == \"this\":\n            original_input_node = tested_node\n        else:\n            try:\n                statically_parsed = py_extract_from_source(f\"{{{{ {input} }}}}\")\n            except ExtractionError:\n                if (\n                    getattr(get_flags(), \"SUPPORT_CUSTOM_REF_KWARGS\", False)\n                    and ctx is not None\n                    and unit_test_node is not None\n                ):\n                    statically_parsed = self._extract_ref_or_source_via_jinja(\n                        input, ctx, unit_test_node\n                    )\n                else:\n                    raise InvalidUnitTestGivenInput(input=input)\n\n            if statically_parsed[\"refs\"]:\n                ref = list(statically_parsed[\"refs\"])[0]\n                name = ref.get(\"name\")\n                package = ref.get(\"package\")\n                version = ref.get(\"version\")\n                # TODO: disabled lookup, versioned lookup, public models\n                original_input_node = self.manifest.ref_lookup.find(\n                    name, package, version, self.manifest\n                )\n            elif statically_parsed[\"sources\"]:\n                source = list(statically_parsed[\"sources\"])[0]\n                input_source_name, input_name = source\n                original_input_node = self.manifest.source_lookup.find(\n                    f\"{input_source_name}.{input_name}\",\n                    None,\n                    self.manifest,\n                )\n            else:\n                raise InvalidUnitTestGivenInput(input=input)\n\n        if not original_input_node:\n            msg = f\"Unit test '{test_case_name}' had an input ({input}) which was not found in the manifest.\"\n            raise ParsingError(msg)\n\n        return original_input_node\n\n    def _extract_ref_or_source_via_jinja(\n        self,\n        input_str: str,\n        ctx: Dict[str, Any],\n        unit_test_node: UnitTestNode,\n    ) -> Dict[str, Any]:\n        \"\"\"Fall back to Jinja rendering to resolve ref() calls with custom kwargs.\n\n        When py_extract_from_source cannot handle custom keyword arguments\n        (e.g., ref('model', revision=2) via a custom ref macro), this method\n        renders the input through Jinja so the custom macro can map custom\n        kwargs to standard ones (like version).\n        \"\"\"\n        # Save current refs/sources to restore after rendering\n        original_refs = list(unit_test_node.refs)\n        original_sources = list(unit_test_node.sources)\n\n        try:\n            get_rendered(f\"{{{{ {input_str} }}}}\", ctx, unit_test_node, capture_macros=True)\n        except Exception:\n            raise InvalidUnitTestGivenInput(input=input_str)\n\n        # Extract newly captured refs/sources\n        new_refs = unit_test_node.refs[len(original_refs) :]\n        new_sources = unit_test_node.sources[len(original_sources) :]\n\n        # Restore original refs/sources\n        unit_test_node.refs = original_refs\n        unit_test_node.sources = original_sources\n\n        result: Dict[str, Any] = {\"refs\": [], \"sources\": []}\n        for ref_arg in new_refs:\n            result[\"refs\"].append(\n                {\"name\": ref_arg.name, \"package\": ref_arg.package, \"version\": ref_arg.version}\n            )\n        for source in new_sources:\n            result[\"sources\"].append(source)\n\n        if not result[\"refs\"] and not result[\"sources\"]:\n            raise InvalidUnitTestGivenInput(input=input_str)\n\n        return result\n\n\nclass UnitTestParser(YamlReader):\n    def __init__(self, schema_parser: SchemaParser, yaml: YamlBlock) -> None:\n        super().__init__(schema_parser, yaml, \"unit_tests\")\n        self.schema_parser = schema_parser\n        self.yaml = yaml\n\n    def parse(self) -> ParseResult:\n        for data in self.get_key_dicts():\n            unit_test: UnparsedUnitTest = self._get_unit_test(data)\n            tested_model_node = find_tested_model_node(\n                self.manifest, self.project.project_name, unit_test.model\n            )\n            unit_test_case_unique_id = (\n                f\"{NodeType.Unit}.{self.project.project_name}.{unit_test.model}.{unit_test.name}\"\n            )\n            unit_test_fqn = self._build_fqn(\n                self.project.project_name,\n                self.yaml.path.original_file_path,\n                unit_test.model,\n                unit_test.name,\n            )\n            unit_test_config = self._build_unit_test_config(unit_test_fqn, unit_test.config)\n\n            unit_test_definition = UnitTestDefinition(\n                name=unit_test.name,\n                model=unit_test.model,\n                resource_type=NodeType.Unit,\n                package_name=self.project.project_name,\n                path=self.yaml.path.relative_path,\n                original_file_path=self.yaml.path.original_file_path,\n                unique_id=unit_test_case_unique_id,\n                given=unit_test.given,\n                expect=unit_test.expect,\n                description=unit_test.description,\n                overrides=unit_test.overrides,\n                depends_on=DependsOn(),\n                fqn=unit_test_fqn,\n                config=unit_test_config,\n                versions=unit_test.versions,\n            )\n\n            if tested_model_node:\n                if tested_model_node.config.enabled:\n                    unit_test_definition.depends_on.nodes.append(tested_model_node.unique_id)\n                    unit_test_definition.schema = tested_model_node.schema\n                else:\n                    unit_test_definition.config.enabled = False\n\n            # Check that format and type of rows matches for each given input,\n            # convert rows to a list of dictionaries, and add the unique_id of\n            # the unit_test_definition to the fixture source_file for partial parsing.\n            self._validate_and_normalize_given(unit_test_definition)\n            self._validate_and_normalize_expect(unit_test_definition)\n\n            # for calculating state:modified\n            unit_test_definition.build_unit_test_checksum()\n            assert isinstance(self.yaml.file, SchemaSourceFile)\n            if unit_test_definition.config.enabled:\n                self.manifest.add_unit_test(self.yaml.file, unit_test_definition)\n            else:\n                self.manifest.add_disabled(self.yaml.file, unit_test_definition)\n\n        return ParseResult()\n\n    def _get_unit_test(self, data: Dict[str, Any]) -> UnparsedUnitTest:\n        try:\n            UnparsedUnitTest.validate(data)\n            return UnparsedUnitTest.from_dict(data)\n        except (ValidationError, JSONValidationError) as exc:\n            raise YamlParseDictError(self.yaml.path, self.key, data, exc)\n\n    def _build_unit_test_config(\n        self, unit_test_fqn: List[str], config_dict: Dict[str, Any]\n    ) -> UnitTestConfig:\n        config = ContextConfig(\n            self.schema_parser.root_project,\n            unit_test_fqn,\n            NodeType.Unit,\n            self.schema_parser.project.project_name,\n        )\n        unit_test_config_dict = config.build_config_dict(patch_config_dict=config_dict)\n        unit_test_config_dict = self.render_entry(unit_test_config_dict)\n\n        return UnitTestConfig.from_dict(unit_test_config_dict)\n\n    def _build_fqn(self, package_name, original_file_path, model_name, test_name):\n        # This code comes from \"get_fqn\" and \"get_fqn_prefix\" in the base parser.\n        # We need to get the directories underneath the model-path.\n        path = Path(original_file_path)\n        relative_path = str(path.relative_to(*path.parts[:1]))\n        no_ext = os.path.splitext(relative_path)[0]\n        fqn = [package_name]\n        fqn.extend(utils.split_path(no_ext)[:-1])\n        fqn.append(model_name)\n        fqn.append(test_name)\n        return fqn\n\n    def _get_fixture(self, fixture_name: str, project_name: str):\n        fixture_unique_id = f\"{NodeType.Fixture}.{project_name}.{fixture_name}\"\n        if fixture_unique_id in self.manifest.fixtures:\n            fixture = self.manifest.fixtures[fixture_unique_id]\n            return fixture\n        else:\n            raise ParsingError(\n                f\"File not found for fixture '{fixture_name}' in unit tests in {self.yaml.path.original_file_path}\"\n            )\n\n    def _validate_and_normalize_given(self, unit_test_definition):\n        for ut_input in unit_test_definition.given:\n            self._validate_and_normalize_rows(ut_input, unit_test_definition, \"input\")\n\n    def _validate_and_normalize_expect(self, unit_test_definition):\n        self._validate_and_normalize_rows(\n            unit_test_definition.expect, unit_test_definition, \"expected\"\n        )\n\n    def _validate_and_normalize_rows(self, ut_fixture, unit_test_definition, fixture_type) -> None:\n        if ut_fixture.format == UnitTestFormat.Dict:\n            if ut_fixture.rows is None and ut_fixture.fixture is None:  # This is a seed\n                ut_fixture.rows = self._load_rows_from_seed(ut_fixture.input)\n            if not isinstance(ut_fixture.rows, list):\n                raise ParsingError(\n                    f\"Unit test {unit_test_definition.name} has {fixture_type} rows \"\n                    f\"which do not match format {ut_fixture.format}\"\n                )\n        elif ut_fixture.format == UnitTestFormat.CSV:\n            if not (isinstance(ut_fixture.rows, str) or isinstance(ut_fixture.fixture, str)):\n                raise ParsingError(\n                    f\"Unit test {unit_test_definition.name} has {fixture_type} rows or fixtures \"\n                    f\"which do not match format {ut_fixture.format}.  Expected string.\"\n                )\n\n            if ut_fixture.fixture:\n                csv_rows = self.get_fixture_file_rows(\n                    ut_fixture.fixture, self.project.project_name, unit_test_definition.unique_id\n                )\n            else:\n                csv_rows = self._convert_csv_to_list_of_dicts(ut_fixture.rows)\n\n            # Empty values (e.g. ,,) in a csv fixture should default to null, not \"\"\n            ut_fixture.rows = [\n                {k: (None if v == \"\" else v) for k, v in row.items()} for row in csv_rows\n            ]\n\n        elif ut_fixture.format == UnitTestFormat.SQL:\n            if not (isinstance(ut_fixture.rows, str) or isinstance(ut_fixture.fixture, str)):\n                raise ParsingError(\n                    f\"Unit test {unit_test_definition.name} has {fixture_type} rows or fixtures \"\n                    f\"which do not match format {ut_fixture.format}.  Expected string.\"\n                )\n\n            if ut_fixture.fixture:\n                ut_fixture.rows = self.get_fixture_file_rows(\n                    ut_fixture.fixture, self.project.project_name, unit_test_definition.unique_id\n                )\n\n        # sanitize order of input\n        if ut_fixture.rows and (\n            ut_fixture.format == UnitTestFormat.Dict or ut_fixture.format == UnitTestFormat.CSV\n        ):\n            self._promote_first_non_none_row(ut_fixture)\n\n    def _promote_first_non_none_row(self, ut_fixture):\n        \"\"\"\n        Promote the first row with no None values to the top of the ut_fixture.rows list.\n\n        This function modifies the ut_fixture object in place.\n\n        Needed for databases like Redshift which uses the first value in a column to determine\n        the column type. If the first value is None, the type is assumed to be VARCHAR(1).\n        This leads to obscure type mismatch errors centered on a unit test fixture's `expect`.\n        See https://github.com/dbt-labs/dbt-redshift/issues/821 for more info.\n        \"\"\"\n        non_none_row_index = None\n\n        # Iterate through each row and its index\n        for index, row in enumerate(ut_fixture.rows):\n            # Check if all values in the row are not None\n            if all(value is not None for value in row.values()):\n                non_none_row_index = index\n                break\n\n        if non_none_row_index is None:\n            fire_event(\n                SystemStdErr(\n                    bmsg=\"Unit Test fixtures benefit from having at least one row free of Null values to ensure consistent column types. Failure to meet this recommendation can result in type mismatch errors between unit test source models and `expected` fixtures.\"\n                )\n            )\n        else:\n            ut_fixture.rows[0], ut_fixture.rows[non_none_row_index] = (\n                ut_fixture.rows[non_none_row_index],\n                ut_fixture.rows[0],\n            )\n\n    def get_fixture_file_rows(self, fixture_name, project_name, utdef_unique_id):\n        # find fixture file object and store unit_test_definition unique_id\n        fixture = self._get_fixture(fixture_name, project_name)\n        fixture_source_file = self.manifest.files[fixture.file_id]\n        fixture_source_file.unit_tests.append(utdef_unique_id)\n        return fixture.rows\n\n    def _convert_csv_to_list_of_dicts(self, csv_string: str) -> List[Dict[str, Any]]:\n        dummy_file = StringIO(csv_string)\n        reader = csv.DictReader(dummy_file)\n        rows = []\n        for row in reader:\n            rows.append(row)\n        return rows\n\n    def _load_rows_from_seed(self, ref_str: str) -> List[Dict[str, Any]]:\n        \"\"\"Read rows from seed file on disk if not specified in YAML config. If seed file doesn't exist, return empty list.\"\"\"\n        ref = py_extract_from_source(\"{{ \" + ref_str + \" }}\")[\"refs\"][0]\n\n        rows: List[Dict[str, Any]] = []\n\n        seed_name = ref[\"name\"]\n        package_name = ref.get(\"package\", self.project.project_name)\n\n        seed_node = self.manifest.ref_lookup.find(seed_name, package_name, None, self.manifest)\n\n        if not seed_node or seed_node.resource_type != NodeType.Seed:\n            # Seed not found in custom package specified\n            if package_name != self.project.project_name:\n                raise ParsingError(\n                    f\"Unable to find seed '{package_name}.{seed_name}' for unit tests in '{package_name}' package\"\n                )\n            else:\n                raise ParsingError(\n                    f\"Unable to find seed '{package_name}.{seed_name}' for unit tests in directories: {self.project.seed_paths}\"\n                )\n\n        seed_path = Path(self.project.project_root) / seed_node.original_file_path\n        with open(seed_path, \"r\") as f:\n            for row in DictReader(f):\n                rows.append(row)\n\n        return rows\n\n\ndef find_tested_model_node(\n    manifest: Manifest, current_project: str, unit_test_model: str\n) -> Optional[ModelNode]:\n    model_name_split = unit_test_model.split()\n    model_name = model_name_split[0]\n    model_version = model_name_split[1] if len(model_name_split) == 2 else None\n\n    tested_node = manifest.ref_lookup.find(model_name, current_project, model_version, manifest)\n    if not tested_node:\n        disabled_node = manifest.disabled_lookup.find(\n            model_name, current_project, model_version, [NodeType.Model]\n        )\n        if disabled_node:\n            tested_node = disabled_node[0]\n\n    return tested_node\n\n\n# This is called by the ManifestLoader after other processing has been done,\n# so that model versions are available.\ndef process_models_for_unit_test(\n    manifest: Manifest, current_project: str, unit_test_def: UnitTestDefinition, models_to_versions\n):\n    # If the unit tests doesn't have a depends_on.nodes[0] then we weren't able to resolve\n    # the model, either because versions hadn't been processed yet, or it's not a valid model name\n    if not unit_test_def.depends_on.nodes:\n        tested_node = find_tested_model_node(manifest, current_project, unit_test_def.model)\n        if not tested_node:\n            raise ParsingError(\n                f\"Unable to find model '{current_project}.{unit_test_def.model}' for \"\n                f\"unit test '{unit_test_def.name}' in {unit_test_def.original_file_path}\"\n            )\n        if tested_node.config.enabled:\n            unit_test_def.depends_on.nodes.append(tested_node.unique_id)\n            unit_test_def.schema = tested_node.schema\n        else:\n            # If the model is disabled, the unit test should be disabled\n            unit_test_def.config.enabled = False\n\n    # The UnitTestDefinition should only have one \"depends_on\" at this point,\n    # the one that's found by the \"model\" field.\n    target_model_id = unit_test_def.depends_on.nodes[0]\n    if target_model_id not in manifest.nodes:\n        if target_model_id in manifest.disabled:\n            # If the model is disabled, the unit test should be disabled\n            unit_test_def.config.enabled = False\n        else:\n            # If we've reached here and the model is not disabled, throw an error\n            raise ParsingError(\n                f\"Unit test '{unit_test_def.name}' references a model that does not exist: {target_model_id}\"\n            )\n\n    if not unit_test_def.config.enabled:\n        # Ensure the unit test is disabled in the manifest\n        if unit_test_def.unique_id in manifest.unit_tests:\n            manifest.unit_tests.pop(unit_test_def.unique_id)\n        if unit_test_def.unique_id not in manifest.disabled:\n            manifest.add_disabled(manifest.files[unit_test_def.file_id], unit_test_def)\n\n        # The unit test is disabled, so we don't need to do any further processing (#10540)\n        return\n\n    target_model = manifest.nodes[target_model_id]\n    assert isinstance(target_model, ModelNode)\n\n    target_model_is_incremental = \"macro.dbt.is_incremental\" in target_model.depends_on.macros\n    unit_test_def_has_incremental_override = unit_test_def.overrides and isinstance(\n        unit_test_def.overrides.macros.get(\"is_incremental\"), bool\n    )\n\n    if target_model_is_incremental and (not unit_test_def_has_incremental_override):\n        raise ParsingError(\n            f\"Boolean override for 'is_incremental' must be provided for unit test '{unit_test_def.name}' in model '{target_model.name}'\"\n        )\n\n    unit_test_def_incremental_override_true = (\n        unit_test_def.overrides and unit_test_def.overrides.macros.get(\"is_incremental\")\n    )\n    unit_test_def_has_this_input = \"this\" in [i.input for i in unit_test_def.given]\n\n    if (\n        target_model_is_incremental\n        and unit_test_def_incremental_override_true\n        and (not unit_test_def_has_this_input)\n    ):\n        raise ParsingError(\n            f\"Unit test '{unit_test_def.name}' for incremental model '{target_model.name}' must have a 'this' input\"\n        )\n\n    # unit_test_versions = unit_test_def.versions\n    # We're setting up unit tests for versioned models, so if\n    # the model isn't versioned, we don't need to do anything\n    if not target_model.is_versioned:\n        if unit_test_def.versions and (\n            unit_test_def.versions.include or unit_test_def.versions.exclude\n        ):\n            # If model is  not versioned, we should not have an include or exclude\n            msg = (\n                f\"Unit test '{unit_test_def.name}' should not have a versions include or exclude \"\n                f\"when referencing non-versioned model '{target_model.name}'\"\n            )\n            raise ParsingError(msg)\n        else:\n            return\n    versioned_models = []\n    if (\n        target_model.package_name in models_to_versions\n        and target_model.name in models_to_versions[target_model.package_name]\n    ):\n        versioned_models = models_to_versions[target_model.package_name][target_model.name]\n\n    versions_to_test = []\n    if unit_test_def.versions is None:\n        versions_to_test = versioned_models\n    elif unit_test_def.versions.exclude:\n        for model_unique_id in versioned_models:\n            model = manifest.nodes[model_unique_id]\n            assert isinstance(model, ModelNode)\n            if model.version in unit_test_def.versions.exclude:\n                continue\n            else:\n                versions_to_test.append(model.unique_id)\n    elif unit_test_def.versions.include:\n        for model_unique_id in versioned_models:\n            model = manifest.nodes[model_unique_id]\n            assert isinstance(model, ModelNode)\n            if model.version in unit_test_def.versions.include:\n                versions_to_test.append(model.unique_id)\n            else:\n                continue\n\n    if not versions_to_test:\n        msg = (\n            f\"Unit test '{unit_test_def.name}' referenced a version of '{target_model.name}' \"\n            \"which was not found.\"\n        )\n        raise ParsingError(msg)\n    else:\n        # Create unit test definitions that match the model versions\n        original_unit_test_def = manifest.unit_tests.pop(unit_test_def.unique_id)\n        original_unit_test_dict = original_unit_test_def.to_dict()\n        schema_file = manifest.files[original_unit_test_def.file_id]\n        assert isinstance(schema_file, SchemaSourceFile)\n        schema_file.unit_tests.remove(original_unit_test_def.unique_id)\n        for versioned_model_unique_id in versions_to_test:\n            versioned_model = manifest.nodes[versioned_model_unique_id]\n            assert isinstance(versioned_model, ModelNode)\n            versioned_unit_test_unique_id = f\"{NodeType.Unit}.{unit_test_def.package_name}.{unit_test_def.model}.{unit_test_def.name}_v{versioned_model.version}\"\n            new_unit_test_def = UnitTestDefinition.from_dict(original_unit_test_dict)\n            new_unit_test_def.unique_id = versioned_unit_test_unique_id\n            new_unit_test_def.depends_on.nodes[0] = versioned_model_unique_id\n            new_unit_test_def.version = versioned_model.version\n            schema_file.unit_tests.append(versioned_unit_test_unique_id)\n            # fqn?\n            manifest.unit_tests[versioned_unit_test_unique_id] = new_unit_test_def\n"
  },
  {
    "path": "core/dbt/plugins/__init__.py",
    "content": "from typing import Optional\n\n# these are just exports, they need \"noqa\" so flake8 will not complain.\nfrom .manager import PluginManager, dbt_hook, dbtPlugin  # noqa\n\nPLUGIN_MANAGER: Optional[PluginManager] = None\n\n\ndef set_up_plugin_manager(project_name: str):\n    global PLUGIN_MANAGER\n    PLUGIN_MANAGER = PluginManager.from_modules(project_name)\n\n\ndef get_plugin_manager(project_name: str) -> PluginManager:\n    global PLUGIN_MANAGER\n    if not PLUGIN_MANAGER:\n        set_up_plugin_manager(project_name)\n\n    assert PLUGIN_MANAGER\n    return PLUGIN_MANAGER\n"
  },
  {
    "path": "core/dbt/plugins/contracts.py",
    "content": "from typing import Dict\n\n# just exports, they need \"noqa\" so flake8 will not complain.\nfrom dbt.artifacts.schemas.base import ArtifactMixin as PluginArtifact  # noqa\nfrom dbt.artifacts.schemas.base import BaseArtifactMetadata  # noqa\nfrom dbt.artifacts.schemas.base import schema_version  # noqa\nfrom dbt_common.dataclass_schema import ExtensibleDbtClassMixin, dbtClassMixin  # noqa\n\nPluginArtifacts = Dict[str, PluginArtifact]\n"
  },
  {
    "path": "core/dbt/plugins/exceptions.py",
    "content": "# just exports, they need \"noqa\" so flake8 will not complain.\nfrom dbt.exceptions import dbtPluginError  # noqa\n"
  },
  {
    "path": "core/dbt/plugins/manager.py",
    "content": "import functools\nimport importlib\nimport pkgutil\nfrom types import ModuleType\nfrom typing import Callable, Dict, List, Mapping\n\nimport dbt.tracking\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.plugins.contracts import PluginArtifacts\nfrom dbt.plugins.manifest import PluginNodes\nfrom dbt_common.exceptions import DbtRuntimeError\nfrom dbt_common.tests import test_caching_enabled\n\n\ndef dbt_hook(func):\n    def inner(*args, **kwargs):\n        try:\n            return func(*args, **kwargs)\n        except Exception as e:\n            raise DbtRuntimeError(f\"{func.__name__}: {e}\")\n\n    setattr(inner, \"is_dbt_hook\", True)\n    return inner\n\n\nclass dbtPlugin:\n    \"\"\"\n    EXPERIMENTAL: dbtPlugin is the base class for creating plugins.\n    Its interface is **not** stable and will likely change between dbt-core versions.\n    \"\"\"\n\n    def __init__(self, project_name: str) -> None:\n        self.project_name = project_name\n        try:\n            self.initialize()\n        except DbtRuntimeError as e:\n            # Remove the first line of DbtRuntimeError to avoid redundant \"Runtime Error\" line\n            raise DbtRuntimeError(\"\\n\".join(str(e).split(\"\\n\")[1:]))\n        except Exception as e:\n            raise DbtRuntimeError(str(e))\n\n    @property\n    def name(self) -> str:\n        return self.__class__.__name__\n\n    def initialize(self) -> None:\n        \"\"\"\n        Initialize the plugin. This function may be overridden by subclasses that have\n        additional initialization steps.\n        \"\"\"\n        pass\n\n    def get_nodes(self) -> PluginNodes:\n        \"\"\"\n        Provide PluginNodes to dbt for injection into dbt's DAG.\n        Currently the only node types that are accepted are model nodes.\n        \"\"\"\n        raise NotImplementedError(f\"get_nodes hook not implemented for {self.name}\")\n\n    def get_manifest_artifacts(self, manifest: Manifest) -> PluginArtifacts:\n        \"\"\"\n        Given a manifest, provide PluginArtifacts derived for writing by core.\n        PluginArtifacts share the same lifecycle as the manifest.json file -- they\n        will either be written or not depending on whether the manifest is written.\n        \"\"\"\n        raise NotImplementedError(f\"get_manifest_artifacts hook not implemented for {self.name}\")\n\n\n@functools.lru_cache(maxsize=None)\ndef _get_dbt_modules() -> Mapping[str, ModuleType]:\n    # This is an expensive function, especially in the context of testing, when\n    # it is called repeatedly, so we break it out and cache the result globally.\n    return {\n        name: importlib.import_module(name)\n        for _, name, _ in pkgutil.iter_modules()\n        if name.startswith(PluginManager.PLUGIN_MODULE_PREFIX)\n    }\n\n\n_MODULES_CACHE = None\n\n\nclass PluginManager:\n    PLUGIN_MODULE_PREFIX = \"dbt_\"\n    PLUGIN_ATTR_NAME = \"plugins\"\n\n    def __init__(self, plugins: List[dbtPlugin]) -> None:\n        self._plugins = plugins\n        self._valid_hook_names = set()\n        # default hook implementations from dbtPlugin\n        for hook_name in dir(dbtPlugin):\n            if not hook_name.startswith(\"_\"):\n                self._valid_hook_names.add(hook_name)\n\n        self.hooks: Dict[str, List[Callable]] = {}\n        for plugin in self._plugins:\n            for hook_name in dir(plugin):\n                hook = getattr(plugin, hook_name)\n                if (\n                    callable(hook)\n                    and hasattr(hook, \"is_dbt_hook\")\n                    and hook_name in self._valid_hook_names\n                ):\n                    if hook_name in self.hooks:\n                        self.hooks[hook_name].append(hook)\n                    else:\n                        self.hooks[hook_name] = [hook]\n\n    @classmethod\n    def from_modules(cls, project_name: str) -> \"PluginManager\":\n\n        if test_caching_enabled():\n            global _MODULES_CACHE\n            if _MODULES_CACHE is None:\n                discovered_dbt_modules = cls.get_prefixed_modules()\n                _MODULES_CACHE = discovered_dbt_modules\n            else:\n                discovered_dbt_modules = _MODULES_CACHE\n        else:\n            discovered_dbt_modules = cls.get_prefixed_modules()\n\n        plugins = []\n        for name, module in discovered_dbt_modules.items():\n            if hasattr(module, cls.PLUGIN_ATTR_NAME):\n                available_plugins = getattr(module, cls.PLUGIN_ATTR_NAME, [])\n                for plugin_cls in available_plugins:\n                    assert issubclass(\n                        plugin_cls, dbtPlugin\n                    ), f\"'plugin' in {name} must be subclass of dbtPlugin\"\n                    plugin = plugin_cls(project_name=project_name)\n                    plugins.append(plugin)\n        return cls(plugins=plugins)\n\n    @classmethod\n    def get_prefixed_modules(cls):\n        return {\n            name: importlib.import_module(name)\n            for _, name, _ in pkgutil.iter_modules()\n            if name.startswith(cls.PLUGIN_MODULE_PREFIX)\n        }\n\n    def get_manifest_artifacts(self, manifest: Manifest) -> PluginArtifacts:\n        all_plugin_artifacts = {}\n        for hook_method in self.hooks.get(\"get_manifest_artifacts\", []):\n            plugin_artifacts = hook_method(manifest)\n            all_plugin_artifacts.update(plugin_artifacts)\n        return all_plugin_artifacts\n\n    def get_nodes(self) -> PluginNodes:\n        all_plugin_nodes = PluginNodes()\n        for hook_method in self.hooks.get(\"get_nodes\", []):\n            plugin_nodes = hook_method()\n            dbt.tracking.track_plugin_get_nodes(\n                {\n                    \"plugin_name\": hook_method.__self__.name,  # type: ignore\n                    \"num_model_nodes\": len(plugin_nodes.models),\n                    \"num_model_packages\": len(\n                        {model.package_name for model in plugin_nodes.models.values()}\n                    ),\n                }\n            )\n            all_plugin_nodes.update(plugin_nodes)\n        return all_plugin_nodes\n"
  },
  {
    "path": "core/dbt/plugins/manifest.py",
    "content": "from dataclasses import dataclass, field\nfrom typing import Dict\n\nfrom dbt.artifacts.resources import NodeVersion  # noqa\n\n# all these are just exports, they need \"noqa\" so flake8 will not complain.\nfrom dbt.contracts.graph.manifest import Manifest  # noqa\nfrom dbt.contracts.graph.node_args import ModelNodeArgs\nfrom dbt.graph.graph import UniqueId  # noqa\nfrom dbt.node_types import AccessType, NodeType  # noqa\n\n\n@dataclass\nclass PluginNodes:\n    models: Dict[str, ModelNodeArgs] = field(default_factory=dict)\n\n    def add_model(self, model_args: ModelNodeArgs) -> None:\n        self.models[model_args.unique_id] = model_args\n\n    def update(self, other: \"PluginNodes\") -> None:\n        self.models.update(other.models)\n"
  },
  {
    "path": "core/dbt/profiler.py",
    "content": "from contextlib import contextmanager\nfrom cProfile import Profile\nfrom pstats import Stats\nfrom typing import Any, Generator\n\n\n@contextmanager\ndef profiler(enable: bool, outfile: str) -> Generator[Any, None, None]:\n    try:\n        if enable:\n            profiler = Profile()\n            profiler.enable()\n\n        yield\n    finally:\n        if enable:\n            profiler.disable()\n            stats = Stats(profiler)\n            stats.sort_stats(\"tottime\")\n            stats.dump_stats(str(outfile))\n"
  },
  {
    "path": "core/dbt/py.typed",
    "content": "# dummy file, our types are defined inline\n"
  },
  {
    "path": "core/dbt/runners/__init__.py",
    "content": "from .exposure_runner import ExposureRunner\nfrom .saved_query_runner import SavedQueryRunner\n"
  },
  {
    "path": "core/dbt/runners/exposure_runner.py",
    "content": "from dbt.runners.no_op_runner import NoOpRunner\n\n\nclass ExposureRunner(NoOpRunner):\n    @property\n    def description(self) -> str:\n        return f\"exposure {self.node.name}\"\n"
  },
  {
    "path": "core/dbt/runners/no_op_runner.py",
    "content": "import threading\n\nfrom dbt.artifacts.schemas.results import RunStatus\nfrom dbt.artifacts.schemas.run import RunResult\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.events.types import LogNodeNoOpResult\nfrom dbt.task.base import BaseRunner\nfrom dbt_common.events.functions import fire_event\n\n\nclass NoOpRunner(BaseRunner):\n    @property\n    def description(self) -> str:\n        raise NotImplementedError(\"description not implemented\")\n\n    def before_execute(self) -> None:\n        pass\n\n    def compile(self, manifest: Manifest):\n        return self.node\n\n    def after_execute(self, result) -> None:\n        fire_event(\n            LogNodeNoOpResult(\n                description=self.description,\n                index=self.node_index,\n                total=self.num_nodes,\n                node_info=self.node.node_info,\n            )\n        )\n\n    def execute(self, compiled_node, manifest):\n        # no-op\n        return RunResult(\n            node=compiled_node,\n            status=RunStatus.NoOp,\n            timing=[],\n            thread_id=threading.current_thread().name,\n            execution_time=0,\n            message=\"NO-OP\",\n            adapter_response={},\n            failures=0,\n            batch_results=None,\n            agate_table=None,\n        )\n"
  },
  {
    "path": "core/dbt/runners/saved_query_runner.py",
    "content": "from dbt.runners.no_op_runner import NoOpRunner\n\n\nclass SavedQueryRunner(NoOpRunner):\n    @property\n    def description(self) -> str:\n        return f\"saved query {self.node.name}\"\n"
  },
  {
    "path": "core/dbt/selected_resources.py",
    "content": "from typing import Any, Set\n\nSELECTED_RESOURCES = []\n\n\ndef set_selected_resources(selected_resources: Set[Any]) -> None:\n    global SELECTED_RESOURCES\n    SELECTED_RESOURCES = list(selected_resources)\n"
  },
  {
    "path": "core/dbt/task/README.md",
    "content": "# Task README\n\n### Task Hierarchy\n```\nBaseTask\n ┣ CleanTask\n ┣ ConfiguredTask\n ┃ ┣ GraphRunnableTask\n ┃ ┃  ┣ CloneTask\n ┃ ┃  ┣ CompileTask\n ┃ ┃  ┃ ┣ GenerateTask\n ┃ ┃  ┃ ┣ RunTask\n ┃ ┃  ┃ ┃ ┣ BuildTask\n ┃ ┃  ┃ ┃ ┣ FreshnessTask\n ┃ ┃  ┃ ┃ ┣ SeedTask\n ┃ ┃  ┃ ┃ ┣ SnapshotTask\n ┃ ┃  ┃ ┃ ┗ TestTask \n ┃ ┃  ┃ ┗ ShowTask\n ┃ ┃  ┗ ListTask\n ┃ ┣ RetryTask \n ┃ ┣ RunOperationTask\n ┃ ┗ ServeTask\n ┣ DebugTask\n ┣ DepsTask\n ┗ InitTask\n```\n\n### Runner Hierarchy\n```\nBaseRunner\n ┣ CloneRunner\n ┣ CompileRunner\n ┃ ┣ GenericSqlRunner\n ┃ ┃  ┣ SqlCompileRunner\n ┃ ┃  ┗ SqlExecuteRunner\n ┃ ┣ ModelRunner\n ┃ ┃ ┣ SeedRunner\n ┃ ┃ ┗ SnapshotRunner\n ┃ ┣ ShowRunner\n ┃ ┗ TestRunner\n ┣ FreshnessRunner\n ┗ SavedQueryRunner\n```\n"
  },
  {
    "path": "core/dbt/task/__init__.py",
    "content": ""
  },
  {
    "path": "core/dbt/task/base.py",
    "content": "import os\nimport threading\nimport time\nimport traceback\nfrom abc import ABCMeta, abstractmethod\nfrom contextlib import nullcontext\nfrom datetime import datetime, timezone\nfrom pathlib import Path\nfrom typing import Any, Dict, List, Optional, Set\n\nimport dbt.exceptions\nimport dbt_common.exceptions.base\nfrom dbt import tracking\nfrom dbt.artifacts.resources.types import NodeType\nfrom dbt.artifacts.schemas.results import (\n    NodeStatus,\n    RunningStatus,\n    RunStatus,\n    TimingInfo,\n    collect_timing_info,\n)\nfrom dbt.artifacts.schemas.run import RunResult\nfrom dbt.cli.flags import Flags\nfrom dbt.compilation import Compiler\nfrom dbt.config import RuntimeConfig\nfrom dbt.config.profile import read_profile\nfrom dbt.constants import DBT_PROJECT_FILE_NAME\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.events.types import (\n    CatchableExceptionOnRun,\n    GenericExceptionOnRun,\n    InternalErrorOnRun,\n    LogDbtProfileError,\n    LogDbtProjectError,\n    LogDebugStackTrace,\n    LogSkipBecauseError,\n    NodeCompiling,\n    NodeConnectionReleaseError,\n    NodeExecuting,\n    SkippingDetails,\n)\nfrom dbt.flags import get_flags\nfrom dbt.graph import Graph\nfrom dbt.task import group_lookup\nfrom dbt.task.printer import print_run_result_error\nfrom dbt_common.events.contextvars import get_node_info\nfrom dbt_common.events.functions import fire_event\nfrom dbt_common.exceptions import DbtInternalError, DbtRuntimeError, NotImplementedError\n\n\ndef read_profiles(profiles_dir: Optional[str] = None) -> Dict[str, Any]:\n    \"\"\"This is only used for some error handling\"\"\"\n    if profiles_dir is None:\n        profiles_dir = get_flags().PROFILES_DIR\n\n    raw_profiles = read_profile(profiles_dir)\n\n    if raw_profiles is None:\n        profiles = {}\n    else:\n        profiles = {k: v for (k, v) in raw_profiles.items() if k != \"config\"}\n\n    return profiles\n\n\nclass BaseTask(metaclass=ABCMeta):\n    def __init__(self, args: Flags) -> None:\n        self.args = args\n\n    def __enter__(self):\n        self.orig_dir = os.getcwd()\n        return self\n\n    def __exit__(self, exc_type, exc_value, traceback):\n        os.chdir(self.orig_dir)\n\n    @abstractmethod\n    def run(self):\n        raise dbt_common.exceptions.base.NotImplementedError(\"Not Implemented\")\n\n    def interpret_results(self, results):\n        return True\n\n\ndef get_nearest_project_dir(project_dir: Optional[str]) -> Path:\n    # If the user provides an explicit project directory, use that\n    # but don't look at parent directories.\n    if project_dir:\n        cur_dir = Path(project_dir)\n        project_file = Path(project_dir) / DBT_PROJECT_FILE_NAME\n        if project_file.is_file():\n            return cur_dir\n        else:\n            raise dbt_common.exceptions.DbtRuntimeError(\n                \"fatal: Invalid --project-dir flag. Not a dbt project. \"\n                \"Missing dbt_project.yml file\"\n            )\n\n    cur_dir = Path.cwd()\n    project_file = cur_dir / DBT_PROJECT_FILE_NAME\n    if project_file.is_file():\n        return cur_dir\n    else:\n        raise dbt_common.exceptions.DbtRuntimeError(\n            \"fatal: Not a dbt project (or any of the parent directories). \"\n            \"Missing dbt_project.yml file\"\n        )\n\n\ndef move_to_nearest_project_dir(project_dir: Optional[str]) -> Path:\n    nearest_project_dir = get_nearest_project_dir(project_dir)\n    resolved_nearest_project_dir = nearest_project_dir.resolve()\n    os.chdir(resolved_nearest_project_dir)\n    return resolved_nearest_project_dir\n\n\n# TODO: look into deprecating this class in favor of several small functions that\n# produce the same behavior. currently this class only contains manifest compilation,\n# holding a manifest, and moving direcories.\nclass ConfiguredTask(BaseTask):\n    def __init__(\n        self, args: Flags, config: RuntimeConfig, manifest: Optional[Manifest] = None\n    ) -> None:\n        super().__init__(args)\n        self.config = config\n        self.graph: Optional[Graph] = None\n        self.manifest = manifest\n        self.compiler = Compiler(self.config)\n\n    def compile_manifest(self) -> None:\n        if self.manifest is None:\n            raise DbtInternalError(\"compile_manifest called before manifest was loaded\")\n\n        start_compile_manifest = time.perf_counter()\n\n        self.graph = self.compiler.compile(self.manifest)\n\n        compile_time = time.perf_counter() - start_compile_manifest\n        if dbt.tracking.active_user is not None:\n            dbt.tracking.track_runnable_timing({\"graph_compilation_elapsed\": compile_time})\n\n    @classmethod\n    def from_args(cls, args: Flags, *pargs, **kwargs):\n        move_to_nearest_project_dir(args.project_dir)\n        try:\n            # This is usually RuntimeConfig\n            config = RuntimeConfig.from_args(args)\n        except dbt.exceptions.DbtProjectError as exc:\n            fire_event(LogDbtProjectError(exc=str(exc)))\n\n            tracking.track_invalid_invocation(args=args, result_type=exc.result_type)\n            raise dbt_common.exceptions.DbtRuntimeError(\"Could not run dbt\") from exc\n        except dbt.exceptions.DbtProfileError as exc:\n            all_profile_names = list(read_profiles(get_flags().PROFILES_DIR).keys())\n            fire_event(LogDbtProfileError(exc=str(exc), profiles=all_profile_names))\n            tracking.track_invalid_invocation(args=args, result_type=exc.result_type)\n            raise dbt_common.exceptions.DbtRuntimeError(\"Could not run dbt\") from exc\n        return cls(args, config, *pargs, **kwargs)\n\n\nclass ExecutionContext:\n    \"\"\"During execution and error handling, dbt makes use of mutable state:\n    timing information and the newest (compiled vs executed) form of the node.\n    \"\"\"\n\n    def __init__(self, node) -> None:\n        self.timing: List[TimingInfo] = []\n        self.node = node\n\n\nclass BaseRunner(metaclass=ABCMeta):\n    def __init__(self, config, adapter, node, node_index: int, num_nodes: int) -> None:\n        self.config = config\n        self.compiler = Compiler(config)\n        self.adapter = adapter\n        self.node = node\n        self.node_index = node_index\n        self.num_nodes = num_nodes\n\n        self.skip = False\n        self.skip_cause: Optional[RunResult] = None\n\n        self.run_ephemeral_models = False\n\n    @abstractmethod\n    def compile(self, manifest: Manifest) -> Any:\n        pass\n\n    def _node_build_path(self) -> Optional[str]:\n        return self.node.build_path if hasattr(self.node, \"build_path\") else None\n\n    def get_result_status(self, result) -> Dict[str, str]:\n        if result.status == NodeStatus.Error:\n            return {\"node_status\": \"error\", \"node_error\": str(result.message)}\n        elif result.status == NodeStatus.Skipped:\n            return {\"node_status\": \"skipped\"}\n        elif result.status == NodeStatus.Fail:\n            return {\"node_status\": \"failed\"}\n        elif result.status == NodeStatus.Warn:\n            return {\"node_status\": \"warn\"}\n        else:\n            return {\"node_status\": \"passed\"}\n\n    def run_with_hooks(self, manifest):\n        if self.skip:\n            return self.on_skip()\n\n        # no before/after printing for ephemeral mdoels\n        if not self.node.is_ephemeral_model:\n            self.before_execute()\n\n        result = self.safe_run(manifest)\n        self.node.update_event_status(\n            node_status=result.status,\n            finished_at=datetime.now(timezone.utc).replace(tzinfo=None).isoformat(),\n        )\n\n        if not self.node.is_ephemeral_model:\n            self.after_execute(result)\n\n        return result\n\n    def _build_run_result(\n        self,\n        node,\n        start_time,\n        status,\n        timing_info,\n        message,\n        agate_table=None,\n        adapter_response=None,\n        failures=None,\n        batch_results=None,\n    ):\n        execution_time = time.time() - start_time\n        thread_id = threading.current_thread().name\n        if adapter_response is None:\n            adapter_response = {}\n        return RunResult(\n            status=status,\n            thread_id=thread_id,\n            execution_time=execution_time,\n            timing=timing_info,\n            message=message,\n            node=node,\n            agate_table=agate_table,\n            adapter_response=adapter_response,\n            failures=failures,\n            batch_results=batch_results,\n        )\n\n    def error_result(self, node, message, start_time, timing_info):\n        return self._build_run_result(\n            node=node,\n            start_time=start_time,\n            status=RunStatus.Error,\n            timing_info=timing_info,\n            message=message,\n        )\n\n    def ephemeral_result(self, node, start_time, timing_info):\n        return self._build_run_result(\n            node=node,\n            start_time=start_time,\n            status=RunStatus.Success,\n            timing_info=timing_info,\n            message=None,\n        )\n\n    def from_run_result(self, result, start_time, timing_info):\n        return self._build_run_result(\n            node=result.node,\n            start_time=start_time,\n            status=result.status,\n            timing_info=timing_info,\n            message=result.message,\n            agate_table=result.agate_table,\n            adapter_response=result.adapter_response,\n            failures=result.failures,\n            batch_results=result.batch_results,\n        )\n\n    def compile_and_execute(self, manifest: Manifest, ctx: ExecutionContext):\n        result = None\n        with (\n            self.adapter.connection_named(self.node.unique_id, self.node)\n            if get_flags().INTROSPECT\n            else nullcontext()\n        ):\n            ctx.node.update_event_status(node_status=RunningStatus.Compiling)\n            fire_event(\n                NodeCompiling(\n                    node_info=ctx.node.node_info,\n                )\n            )\n            with collect_timing_info(\"compile\", ctx.timing.append):\n                # if we fail here, we still have a compiled node to return\n                # this has the benefit of showing a build path for the errant\n                # model.  This calls the 'compile' method in CompileTask\n                ctx.node = self.compile(manifest)\n\n            # for ephemeral nodes, we only want to compile, not run\n            if not ctx.node.is_ephemeral_model or self.run_ephemeral_models:\n                ctx.node.update_event_status(node_status=RunningStatus.Executing)\n                fire_event(\n                    NodeExecuting(\n                        node_info=ctx.node.node_info,\n                    )\n                )\n                with collect_timing_info(\"execute\", ctx.timing.append):\n                    result = self.run(ctx.node, manifest)\n                    ctx.node = result.node\n\n        return result\n\n    def _handle_catchable_exception(self, e: DbtRuntimeError, ctx: ExecutionContext) -> str:\n        if e.node is None:\n            e.add_node(ctx.node)\n\n        fire_event(\n            CatchableExceptionOnRun(\n                exc=str(e), exc_info=traceback.format_exc(), node_info=get_node_info()\n            )\n        )\n        return str(e)\n\n    def _handle_internal_exception(self, e: DbtInternalError, ctx: ExecutionContext) -> str:\n        fire_event(\n            InternalErrorOnRun(\n                build_path=self._node_build_path(), exc=str(e), node_info=get_node_info()\n            )\n        )\n        return str(e)\n\n    def _handle_generic_exception(self, e: Exception, ctx: ExecutionContext) -> str:\n        fire_event(\n            GenericExceptionOnRun(\n                build_path=self._node_build_path(),\n                unique_id=self.node.unique_id,\n                exc=str(e),\n                node_info=get_node_info(),\n            )\n        )\n        fire_event(LogDebugStackTrace(exc_info=traceback.format_exc()))\n\n        return str(e)\n\n    def handle_exception(self, e: Exception, ctx: ExecutionContext) -> str:\n        if isinstance(e, DbtRuntimeError):\n            error = self._handle_catchable_exception(e, ctx)\n        elif isinstance(e, DbtInternalError):\n            error = self._handle_internal_exception(e, ctx)\n        else:\n            error = self._handle_generic_exception(e, ctx)\n        return error\n\n    def safe_run(self, manifest: Manifest):\n        started = time.time()\n        ctx = ExecutionContext(self.node)\n        error = None\n        result = None\n\n        try:\n            result = self.compile_and_execute(manifest, ctx)\n        except Exception as e:\n            error = self.handle_exception(e, ctx)\n        finally:\n            exc_str = self._safe_release_connection()\n\n            # if releasing failed and the result doesn't have an error yet, set\n            # an error\n            if (\n                exc_str is not None\n                and result is not None\n                and result.status != NodeStatus.Error\n                and error is None\n            ):\n                error = exc_str\n\n        if error is not None:\n            result = self.error_result(ctx.node, error, started, ctx.timing)\n        elif result is not None:\n            result = self.from_run_result(result, started, ctx.timing)\n        else:\n            result = self.ephemeral_result(ctx.node, started, ctx.timing)\n        return result\n\n    def _safe_release_connection(self):\n        \"\"\"Try to release a connection. If an exception is hit, log and return\n        the error string.\n        \"\"\"\n        try:\n            self.adapter.release_connection()\n        except Exception as exc:\n            fire_event(\n                NodeConnectionReleaseError(\n                    node_name=self.node.name, exc=str(exc), exc_info=traceback.format_exc()\n                )\n            )\n            return str(exc)\n\n        return None\n\n    def before_execute(self) -> None:\n        raise NotImplementedError(\"before_execute is not implemented\")\n\n    def execute(self, compiled_node, manifest):\n        raise NotImplementedError(\"execute is not implemented\")\n\n    def run(self, compiled_node, manifest):\n        return self.execute(compiled_node, manifest)\n\n    def after_execute(self, result) -> None:\n        raise NotImplementedError(\"after_execute is not implemented\")\n\n    def _skip_caused_by_ephemeral_failure(self) -> bool:\n        if self.skip_cause is None or self.skip_cause.node is None:\n            return False\n        return self.skip_cause.node.is_ephemeral_model\n\n    def on_skip(self):\n        schema_name = getattr(self.node, \"schema\", \"\")\n        node_name = self.node.name\n\n        error_message = None\n        if not self.node.is_ephemeral_model:\n            # if this model was skipped due to an upstream ephemeral model\n            # failure, print a special 'error skip' message.\n            # Include skip_cause NodeStatus\n            group = group_lookup.get(self.node.unique_id)\n\n            if self._skip_caused_by_ephemeral_failure():\n                fire_event(\n                    LogSkipBecauseError(\n                        schema=schema_name,\n                        relation=node_name,\n                        index=self.node_index,\n                        total=self.num_nodes,\n                        status=self.skip_cause.status,\n                        group=group,\n                    )\n                )\n                # skip_cause here should be the run_result from the ephemeral model\n                print_run_result_error(result=self.skip_cause, newline=False)\n                if self.skip_cause is None:  # mypy appeasement\n                    raise DbtInternalError(\n                        \"Skip cause not set but skip was somehow caused by an ephemeral failure\"\n                    )\n                # set an error so dbt will exit with an error code\n                error_message = (\n                    \"Compilation Error in {}, caused by compilation error \"\n                    \"in referenced ephemeral model {}\".format(\n                        self.node.unique_id, self.skip_cause.node.unique_id\n                    )\n                )\n            else:\n                # 'skipped' nodes should not have a value for 'node_finished_at'\n                # they do have 'node_started_at', which is set in GraphRunnableTask.call_runner\n                self.node.update_event_status(node_status=RunStatus.Skipped)\n                fire_event(\n                    SkippingDetails(\n                        resource_type=self.node.resource_type,\n                        schema=schema_name,\n                        node_name=node_name,\n                        index=self.node_index,\n                        total=self.num_nodes,\n                        node_info=self.node.node_info,\n                        group=group,\n                    )\n                )\n\n        node_result = RunResult.from_node(self.node, RunStatus.Skipped, error_message)\n        return node_result\n\n    def do_skip(self, cause=None) -> None:\n        self.skip = True\n        self.skip_cause = cause\n\n\ndef resource_types_from_args(\n    args: Flags, all_resource_values: Set[NodeType], default_resource_values: Set[NodeType]\n) -> Set[NodeType]:\n\n    if not args.resource_types:\n        resource_types = default_resource_values\n    else:\n        # This is a list of strings, not NodeTypes\n        arg_resource_types = set(args.resource_types)\n\n        if \"all\" in arg_resource_types:\n            arg_resource_types.remove(\"all\")\n            arg_resource_types.update(all_resource_values)\n        if \"default\" in arg_resource_types:\n            arg_resource_types.remove(\"default\")\n            arg_resource_types.update(default_resource_values)\n        # Convert to a set of NodeTypes now that the non-NodeType strings are gone\n        resource_types = set([NodeType(rt) for rt in list(arg_resource_types)])\n\n    if args.exclude_resource_types:\n        # Convert from a list of strings to a set of NodeTypes\n        exclude_resource_types = set([NodeType(rt) for rt in args.exclude_resource_types])\n        resource_types = resource_types - exclude_resource_types\n\n    return resource_types\n"
  },
  {
    "path": "core/dbt/task/build.py",
    "content": "from typing import Dict, Iterable, List, Optional, Set, Type\n\nfrom dbt.adapters.base import BaseRelation\nfrom dbt.artifacts.schemas.results import NodeStatus\nfrom dbt.artifacts.schemas.run import RunResult\nfrom dbt.cli.flags import Flags\nfrom dbt.config.runtime import RuntimeConfig\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.exceptions import DbtInternalError\nfrom dbt.graph import Graph, GraphQueue, ResourceTypeSelector\nfrom dbt.node_types import NodeType\nfrom dbt.runners import ExposureRunner as exposure_runner\nfrom dbt.runners import SavedQueryRunner as saved_query_runner\nfrom dbt.task.base import BaseRunner, resource_types_from_args\nfrom dbt.task.run import MicrobatchModelRunner\n\nfrom .function import FunctionRunner as function_runner\nfrom .run import ModelRunner as run_model_runner\nfrom .run import RunTask\nfrom .seed import SeedRunner as seed_runner\nfrom .snapshot import SnapshotRunner as snapshot_model_runner\nfrom .test import TestRunner as test_runner\n\n\nclass BuildTask(RunTask):\n    \"\"\"The Build task processes all assets of a given process and attempts to\n    'build' them in an opinionated fashion.  Every resource type outlined in\n    RUNNER_MAP will be processed by the mapped runners class.\n\n    I.E. a resource of type Model is handled by the ModelRunner which is\n    imported as run_model_runner.\"\"\"\n\n    MARK_DEPENDENT_ERRORS_STATUSES = [\n        NodeStatus.Error,\n        NodeStatus.Fail,\n        NodeStatus.Skipped,\n        NodeStatus.PartialSuccess,\n    ]\n\n    RUNNER_MAP = {\n        NodeType.Model: run_model_runner,\n        NodeType.Snapshot: snapshot_model_runner,\n        NodeType.Seed: seed_runner,\n        NodeType.Test: test_runner,\n        NodeType.Unit: test_runner,\n        NodeType.SavedQuery: saved_query_runner,\n        NodeType.Exposure: exposure_runner,\n        NodeType.Function: function_runner,\n    }\n    ALL_RESOURCE_VALUES = frozenset({x for x in RUNNER_MAP.keys()})\n\n    def __init__(self, args: Flags, config: RuntimeConfig, manifest: Manifest) -> None:\n        super().__init__(args, config, manifest)\n        self.selected_unit_tests: Set = set()\n        self.model_to_unit_test_map: Dict[str, List] = {}\n\n    def resource_types(self, no_unit_tests: bool = False) -> List[NodeType]:\n        resource_types = resource_types_from_args(\n            self.args, set(self.ALL_RESOURCE_VALUES), set(self.ALL_RESOURCE_VALUES)\n        )\n\n        # First we get selected_nodes including unit tests, then without,\n        # and do a set difference.\n        if no_unit_tests is True and NodeType.Unit in resource_types:\n            resource_types.remove(NodeType.Unit)\n        return list(resource_types)\n\n    def get_model_schemas(self, adapter, selected_uids: Iterable[str]) -> Set[BaseRelation]:\n\n        # Get model schemas as usual\n        model_schemas = super().get_model_schemas(adapter, selected_uids)\n\n        # Get function schemas\n        function_schemas: Set[BaseRelation] = set()\n        for function in (\n            self.manifest.functions.values() if self.manifest else []\n        ):  # functionally the manifest will never be None as we do an assert in super().get_model_schemas(...)\n            if function.unique_id in selected_uids:\n                relation = adapter.Relation.create_from(self.config, function)\n                function_schemas.add(relation.without_identifier())\n\n        return model_schemas.union(function_schemas)\n\n    # overrides get_graph_queue in runnable.py\n    def get_graph_queue(self) -> GraphQueue:\n        # Following uses self.selection_arg and self.exclusion_arg\n        spec = self.get_selection_spec()\n\n        # selector including unit tests\n        full_selector = self.get_node_selector(no_unit_tests=False)\n        # selected node unique_ids with unit_tests\n        full_selected_nodes = full_selector.get_selected(spec=spec, warn_on_no_nodes=False)\n\n        # This selector removes the unit_tests from the selector\n        selector_wo_unit_tests = self.get_node_selector(no_unit_tests=True)\n        # selected node unique_ids without unit_tests\n        selected_nodes_wo_unit_tests = selector_wo_unit_tests.get_selected(\n            spec=spec, warn_on_no_nodes=False\n        )\n\n        # Get the difference in the sets of nodes with and without unit tests and\n        # save it\n        selected_unit_tests = full_selected_nodes - selected_nodes_wo_unit_tests\n        self.selected_unit_tests = selected_unit_tests\n        self.build_model_to_unit_test_map(selected_unit_tests)\n\n        # get_graph_queue in the selector will remove NodeTypes not specified\n        # in the node_selector (filter_selection).\n        return selector_wo_unit_tests.get_graph_queue(spec)\n\n    # overrides handle_job_queue in runnable.py\n    def handle_job_queue(self, pool, callback):\n        if self.run_count == 0:\n            self.num_nodes = self.num_nodes + len(self.selected_unit_tests)\n        node = self.job_queue.get()\n        if (\n            node.resource_type == NodeType.Model\n            and self.model_to_unit_test_map\n            and node.unique_id in self.model_to_unit_test_map\n        ):\n            self.handle_model_with_unit_tests_node(node, pool, callback)\n\n        else:\n            self.handle_job_queue_node(node, pool, callback)\n\n    def handle_model_with_unit_tests_node(self, node, pool, callback):\n        self._raise_set_error()\n        args = [node, pool]\n        if self.config.args.single_threaded:\n            callback(self.call_model_and_unit_tests_runner(*args))\n        else:\n            pool.apply_async(self.call_model_and_unit_tests_runner, args=args, callback=callback)\n\n    def call_model_and_unit_tests_runner(self, node, pool) -> RunResult:\n        assert self.manifest\n        for unit_test_unique_id in self.model_to_unit_test_map[node.unique_id]:\n            unit_test_node = self.manifest.unit_tests[unit_test_unique_id]\n            unit_test_runner = self.get_runner(unit_test_node)\n            # If the model is marked skip, also skip the unit tests\n            if node.unique_id in self._skipped_children:\n                # cause is only for ephemeral nodes\n                unit_test_runner.do_skip(cause=None)\n            result = self.call_runner(unit_test_runner)\n            self._handle_result(result)\n            if result.status in self.MARK_DEPENDENT_ERRORS_STATUSES:\n                # The _skipped_children dictionary can contain a run_result for ephemeral nodes,\n                # but that should never be the case here.\n                self._skipped_children[node.unique_id] = None\n        runner = self.get_runner(node)\n        if runner.node.unique_id in self._skipped_children:\n            cause = self._skipped_children.pop(runner.node.unique_id)\n            runner.do_skip(cause=cause)\n\n        if isinstance(runner, MicrobatchModelRunner):\n            runner.set_parent_task(self)\n            runner.set_pool(pool)\n\n        return self.call_runner(runner)\n\n    # handle non-model-plus-unit-tests nodes\n    def handle_job_queue_node(self, node, pool, callback):\n        self._raise_set_error()\n        runner = self.get_runner(node)\n        # we finally know what we're running! Make sure we haven't decided\n        # to skip it due to upstream failures\n        if runner.node.unique_id in self._skipped_children:\n            cause = self._skipped_children.pop(runner.node.unique_id)\n            runner.do_skip(cause=cause)\n\n        if isinstance(runner, MicrobatchModelRunner):\n            runner.set_parent_task(self)\n            runner.set_pool(pool)\n\n        args = [runner]\n        self._submit(pool, args, callback)\n\n    # Make a map of model unique_ids to selected unit test unique_ids,\n    # for processing before the model.\n    def build_model_to_unit_test_map(self, selected_unit_tests):\n        dct = {}\n        for unit_test_unique_id in selected_unit_tests:\n            unit_test = self.manifest.unit_tests[unit_test_unique_id]\n            model_unique_id = unit_test.depends_on.nodes[0]\n            if model_unique_id not in dct:\n                dct[model_unique_id] = []\n            dct[model_unique_id].append(unit_test.unique_id)\n        self.model_to_unit_test_map = dct\n\n    # We return two different kinds of selectors, one with unit tests and one without\n    def get_node_selector(self, no_unit_tests=False) -> ResourceTypeSelector:\n        if self.manifest is None or self.graph is None:\n            raise DbtInternalError(\"manifest and graph must be set to get node selection\")\n\n        resource_types = self.resource_types(no_unit_tests)\n\n        return ResourceTypeSelector(\n            graph=self.graph,\n            manifest=self.manifest,\n            previous_state=self.previous_state,\n            resource_types=resource_types,\n            selectors=self.config.selectors,\n        )\n\n    def get_runner_type(self, node) -> Optional[Type[BaseRunner]]:\n        if (\n            node.resource_type == NodeType.Model\n            and super().get_runner_type(node) == MicrobatchModelRunner\n        ):\n            return MicrobatchModelRunner\n\n        return self.RUNNER_MAP.get(node.resource_type)\n\n    # Special build compile_manifest method to pass add_test_edges to the compiler\n    def compile_manifest(self) -> None:\n        if self.manifest is None:\n            raise DbtInternalError(\"compile_manifest called before manifest was loaded\")\n        self.graph: Graph = self.compiler.compile(self.manifest, add_test_edges=True)\n"
  },
  {
    "path": "core/dbt/task/clean.py",
    "content": "from pathlib import Path\nfrom shutil import rmtree\n\nfrom dbt import deprecations\nfrom dbt.cli.flags import Flags\nfrom dbt.config.project import Project\nfrom dbt.events.types import CheckCleanPath, ConfirmCleanPath, FinishedCleanPaths\nfrom dbt.task.base import BaseTask, move_to_nearest_project_dir\nfrom dbt_common.events.functions import fire_event\nfrom dbt_common.exceptions import DbtRuntimeError\n\n\nclass CleanTask(BaseTask):\n    def __init__(self, args: Flags, config: Project):\n        super().__init__(args)\n        self.config = config\n        self.project = config\n\n    def run(self) -> None:\n        \"\"\"\n        This function takes all the paths in the target file\n        and cleans the project paths that are not protected.\n        \"\"\"\n        project_dir = move_to_nearest_project_dir(self.args.project_dir)\n\n        potential_clean_paths = set(Path(p).resolve() for p in self.project.clean_targets)\n        source_paths = set(\n            Path(p).resolve() for p in (*self.project.all_source_paths, *self.project.test_paths)\n        )\n        clean_paths = potential_clean_paths.difference(source_paths)\n\n        if potential_clean_paths != clean_paths:\n            raise DbtRuntimeError(\n                f\"dbt will not clean the following source paths: {[str(s) for s in source_paths.intersection(potential_clean_paths)]}\"\n            )\n\n        paths_outside_project = set(\n            path for path in clean_paths if project_dir not in path.absolute().parents\n        )\n        if paths_outside_project and self.args.clean_project_files_only:\n            raise DbtRuntimeError(\n                f\"dbt will not clean the following directories outside the project: {[str(p) for p in paths_outside_project]}\"\n            )\n\n        if (\n            \"dbt_modules\" in self.project.clean_targets\n            and self.config.packages_install_path not in self.config.clean_targets\n        ):\n            deprecations.warn(\"install-packages-path\")\n\n        for path in clean_paths:\n            fire_event(CheckCleanPath(path=str(path)))\n            rmtree(path, True)\n            fire_event(ConfirmCleanPath(path=str(path)))\n\n        fire_event(FinishedCleanPaths())\n"
  },
  {
    "path": "core/dbt/task/clone.py",
    "content": "import threading\nfrom typing import AbstractSet, Any, Collection, Iterable, List, Optional, Set, Type\n\nfrom dbt.adapters.base import BaseAdapter, BaseRelation\nfrom dbt.artifacts.resources.types import NodeType\nfrom dbt.artifacts.schemas.run import RunResult, RunStatus\nfrom dbt.clients.jinja import MacroGenerator\nfrom dbt.context.providers import generate_runtime_model_context\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.graph import ResourceTypeSelector\nfrom dbt.node_types import REFABLE_NODE_TYPES\nfrom dbt.task.base import BaseRunner, resource_types_from_args\nfrom dbt.task.run import _validate_materialization_relations_dict\nfrom dbt.task.runnable import GraphRunnableMode, GraphRunnableTask\nfrom dbt_common.dataclass_schema import dbtClassMixin\nfrom dbt_common.exceptions import CompilationError, DbtInternalError\n\n\nclass CloneRunner(BaseRunner):\n    def before_execute(self) -> None:\n        pass\n\n    def after_execute(self, result) -> None:\n        pass\n\n    def _build_run_model_result(self, model, context):\n        result = context[\"load_result\"](\"main\")\n        if result:\n            status = RunStatus.Success\n            message = str(result.response)\n        else:\n            status = RunStatus.Success\n            message = \"No-op\"\n        adapter_response = {}\n        if result and isinstance(result.response, dbtClassMixin):\n            adapter_response = result.response.to_dict(omit_none=True)\n        return RunResult(\n            node=model,\n            status=status,\n            timing=[],\n            thread_id=threading.current_thread().name,\n            execution_time=0,\n            message=message,\n            adapter_response=adapter_response,\n            failures=None,\n            batch_results=None,\n        )\n\n    def compile(self, manifest: Manifest):\n        # no-op\n        return self.node\n\n    def _materialization_relations(self, result: Any, model) -> List[BaseRelation]:\n        if isinstance(result, str):\n            msg = (\n                'The materialization (\"{}\") did not explicitly return a '\n                \"list of relations to add to the cache.\".format(str(model.get_materialization()))\n            )\n            raise CompilationError(msg, node=model)\n\n        if isinstance(result, dict):\n            return _validate_materialization_relations_dict(result, model)\n\n        msg = (\n            \"Invalid return value from materialization, expected a dict \"\n            'with key \"relations\", got: {}'.format(str(result))\n        )\n        raise CompilationError(msg, node=model)\n\n    def execute(self, model, manifest):\n        context = generate_runtime_model_context(model, self.config, manifest)\n        materialization_macro = manifest.find_materialization_macro_by_name(\n            self.config.project_name, \"clone\", self.adapter.type()\n        )\n\n        if \"config\" not in context:\n            raise DbtInternalError(\n                \"Invalid materialization context generated, missing config: {}\".format(context)\n            )\n\n        context_config = context[\"config\"]\n\n        hook_ctx = self.adapter.pre_model_hook(context_config)\n        try:\n            result = MacroGenerator(materialization_macro, context)()\n        finally:\n            self.adapter.post_model_hook(context_config, hook_ctx)\n\n        for relation in self._materialization_relations(result, model):\n            self.adapter.cache_added(relation.incorporate(dbt_created=True))\n\n        return self._build_run_model_result(model, context)\n\n\nclass CloneTask(GraphRunnableTask):\n    def raise_on_first_error(self) -> bool:\n        return False\n\n    def get_run_mode(self) -> GraphRunnableMode:\n        return GraphRunnableMode.Independent\n\n    def _get_deferred_manifest(self) -> Optional[Manifest]:\n        # Unlike other commands, 'clone' always requires a state manifest\n        # Load previous state, regardless of whether --defer flag has been set\n        return self._get_previous_state()\n\n    def get_model_schemas(self, adapter, selected_uids: Iterable[str]) -> Set[BaseRelation]:\n        if self.manifest is None:\n            raise DbtInternalError(\"manifest was None in get_model_schemas\")\n        result: Set[BaseRelation] = set()\n\n        for node in self.manifest.nodes.values():\n            if node.unique_id not in selected_uids:\n                continue\n            if node.is_relational and not node.is_ephemeral:\n                relation = adapter.Relation.create_from(self.config, node)\n                result.add(relation.without_identifier())\n\n                # cache the 'other' schemas too!\n                if node.defer_relation:  # type: ignore\n                    other_relation = adapter.Relation.create_from(\n                        self.config, node.defer_relation  # type: ignore\n                    )\n                    result.add(other_relation.without_identifier())\n\n        return result\n\n    def before_run(self, adapter: BaseAdapter, selected_uids: AbstractSet[str]) -> RunStatus:\n        with adapter.connection_named(\"master\"):\n            self.defer_to_manifest()\n            # only create target schemas, but also cache defer_relation schemas\n            schemas_to_create = super().get_model_schemas(adapter, selected_uids)\n            self.create_schemas(adapter, schemas_to_create)\n            schemas_to_cache = self.get_model_schemas(adapter, selected_uids)\n            self.populate_adapter_cache(adapter, schemas_to_cache)\n            return RunStatus.Success\n\n    @property\n    def resource_types(self) -> List[NodeType]:\n        resource_types: Collection[NodeType] = resource_types_from_args(\n            self.args, set(REFABLE_NODE_TYPES), set(REFABLE_NODE_TYPES)\n        )\n\n        # filter out any non-refable node types\n        resource_types = [rt for rt in resource_types if rt in REFABLE_NODE_TYPES]\n        return list(resource_types)\n\n    def get_node_selector(self) -> ResourceTypeSelector:\n        resource_types = self.resource_types\n\n        if self.manifest is None or self.graph is None:\n            raise DbtInternalError(\"manifest and graph must be set to get perform node selection\")\n        return ResourceTypeSelector(\n            graph=self.graph,\n            manifest=self.manifest,\n            previous_state=self.previous_state,\n            resource_types=resource_types,\n            selectors=self.config.selectors,\n        )\n\n    def get_runner_type(self, _) -> Optional[Type[BaseRunner]]:\n        return CloneRunner\n"
  },
  {
    "path": "core/dbt/task/compile.py",
    "content": "import threading\nfrom typing import Optional, Type\n\nfrom dbt.artifacts.schemas.run import RunResult, RunStatus\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.events.types import CompiledNode, ParseInlineNodeError\nfrom dbt.flags import get_flags\nfrom dbt.graph import ResourceTypeSelector\nfrom dbt.node_types import EXECUTABLE_NODE_TYPES, NodeType\nfrom dbt.parser.manifest import process_node\nfrom dbt.parser.sql import SqlBlockParser\nfrom dbt.task.base import BaseRunner\nfrom dbt.task.runnable import GraphRunnableTask\nfrom dbt_common.events.base_types import EventLevel\nfrom dbt_common.events.functions import fire_event\nfrom dbt_common.events.types import Note\nfrom dbt_common.exceptions import CompilationError\nfrom dbt_common.exceptions import DbtBaseException as DbtException\nfrom dbt_common.exceptions import DbtInternalError\n\n\nclass CompileRunner(BaseRunner):\n    def before_execute(self) -> None:\n        pass\n\n    def after_execute(self, result) -> None:\n        pass\n\n    def execute(self, compiled_node, manifest):\n        return RunResult(\n            node=compiled_node,\n            status=RunStatus.Success,\n            timing=[],\n            thread_id=threading.current_thread().name,\n            execution_time=0,\n            message=None,\n            adapter_response={},\n            failures=None,\n            batch_results=None,\n        )\n\n    def compile(self, manifest: Manifest):\n        return self.compiler.compile_node(self.node, manifest, {})\n\n    def get_node_representation(self):\n        display_quote_policy = {\"database\": False, \"schema\": False, \"identifier\": False}\n        relation = self.adapter.Relation.create_from(\n            self.config, self.node, quote_policy=display_quote_policy\n        )\n        # exclude the database from output if it's the default\n        if self.node.database == self.config.credentials.database:\n            relation = relation.include(database=False)\n        return str(relation)\n\n\nclass CompileTask(GraphRunnableTask):\n    # We add a new inline node to the manifest during initialization\n    # it should be removed before the task is complete\n    _inline_node_id = None\n\n    def raise_on_first_error(self) -> bool:\n        return True\n\n    def get_node_selector(self) -> ResourceTypeSelector:\n        if getattr(self.args, \"inline\", None):\n            resource_types = [NodeType.SqlOperation]\n        else:\n            resource_types = EXECUTABLE_NODE_TYPES\n\n        if self.manifest is None or self.graph is None:\n            raise DbtInternalError(\"manifest and graph must be set to get perform node selection\")\n        return ResourceTypeSelector(\n            graph=self.graph,\n            manifest=self.manifest,\n            previous_state=self.previous_state,\n            resource_types=resource_types,\n            selectors=self.config.selectors,\n        )\n\n    def get_runner_type(self, _) -> Optional[Type[BaseRunner]]:\n        return CompileRunner\n\n    def task_end_messages(self, results) -> None:\n        is_inline = bool(getattr(self.args, \"inline\", None))\n        output_format = getattr(self.args, \"output\", \"text\")\n\n        if is_inline:\n            matched_results = [result for result in results if result.node.name == \"inline_query\"]\n        elif self.selection_arg:\n            matched_results = []\n            for result in results:\n                if result.node.name in self.selection_arg[0]:\n                    matched_results.append(result)\n                else:\n                    fire_event(\n                        Note(msg=f\"Excluded node '{result.node.name}' from results\"),\n                        EventLevel.DEBUG,\n                    )\n        # No selector passed, compiling all nodes\n        else:\n            matched_results = []\n\n        for result in matched_results:\n            fire_event(\n                CompiledNode(\n                    node_name=result.node.name,\n                    compiled=result.node.compiled_code,\n                    is_inline=is_inline,\n                    output_format=output_format,\n                    unique_id=result.node.unique_id,\n                    quiet=get_flags().QUIET,\n                )\n            )\n\n    def _runtime_initialize(self):\n        if getattr(self.args, \"inline\", None):\n            try:\n                block_parser = SqlBlockParser(\n                    project=self.config, manifest=self.manifest, root_project=self.config\n                )\n                sql_node = block_parser.parse_remote(self.args.inline, \"inline_query\")\n                process_node(self.config, self.manifest, sql_node)\n                # Special hack to remove disabled, if it's there. This would only happen\n                # if all models are disabled in dbt_project\n                if sql_node.config.enabled is False:\n                    sql_node.config.enabled = True\n                    self.manifest.disabled.pop(sql_node.unique_id)\n                    self.manifest.nodes[sql_node.unique_id] = sql_node\n                # keep track of the node added to the manifest\n                self._inline_node_id = sql_node.unique_id\n            except CompilationError as exc:\n                fire_event(\n                    ParseInlineNodeError(\n                        exc=str(exc.msg),\n                        node_info={\n                            \"node_path\": \"sql/inline_query\",\n                            \"node_name\": \"inline_query\",\n                            \"unique_id\": \"sqloperation.test.inline_query\",\n                            \"node_status\": \"failed\",\n                        },\n                    )\n                )\n                raise DbtException(\"Error parsing inline query\")\n        super()._runtime_initialize()\n\n    def after_run(self, adapter, results) -> None:\n        # remove inline node from manifest\n        if self._inline_node_id:\n            self.manifest.nodes.pop(self._inline_node_id)\n            self._inline_node_id = None\n        super().after_run(adapter, results)\n\n    def _handle_result(self, result) -> None:\n        super()._handle_result(result)\n\n        if (\n            result.node.is_ephemeral_model\n            and type(self) is CompileTask\n            and (self.args.select or getattr(self.args, \"inline\", None))\n        ):\n            self.node_results.append(result)\n"
  },
  {
    "path": "core/dbt/task/debug.py",
    "content": "# coding=utf-8\nimport importlib\nimport os\nimport platform\nimport sys\nfrom collections import namedtuple\nfrom enum import Flag\nfrom pathlib import Path\nfrom typing import Any, Dict, List, Optional, Tuple\n\nimport dbt.exceptions\nimport dbt_common.clients.system\nimport dbt_common.exceptions\nfrom dbt.adapters.factory import get_adapter, register_adapter\nfrom dbt.artifacts.schemas.results import RunStatus\nfrom dbt.cli.flags import Flags\nfrom dbt.clients.yaml_helper import load_yaml_text\nfrom dbt.config import PartialProject, Profile, Project\nfrom dbt.config.renderer import DbtProjectYamlRenderer, ProfileRenderer\nfrom dbt.events.types import DebugCmdOut, DebugCmdResult, OpenCommand\nfrom dbt.links import ProfileConfigDocs\nfrom dbt.mp_context import get_mp_context\nfrom dbt.task.base import BaseTask, get_nearest_project_dir\nfrom dbt.version import get_installed_version\nfrom dbt_common.events.format import pluralize\nfrom dbt_common.events.functions import fire_event\nfrom dbt_common.ui import green, red\n\nONLY_PROFILE_MESSAGE = \"\"\"\nA `dbt_project.yml` file was not found in this directory.\nUsing the only profile `{}`.\n\"\"\".lstrip()\n\nMULTIPLE_PROFILE_MESSAGE = \"\"\"\nA `dbt_project.yml` file was not found in this directory.\ndbt found the following profiles:\n{}\n\nTo debug one of these profiles, run:\ndbt debug --profile [profile-name]\n\"\"\".lstrip()\n\nCOULD_NOT_CONNECT_MESSAGE = \"\"\"\ndbt was unable to connect to the specified database.\nThe database returned the following error:\n\n  >{err}\n\nCheck your database credentials and try again. For more information, visit:\n{url}\n\"\"\".lstrip()\n\nMISSING_PROFILE_MESSAGE = \"\"\"\ndbt looked for a profiles.yml file in {path}, but did\nnot find one. For more information on configuring your profile, consult the\ndocumentation:\n\n{url}\n\"\"\".lstrip()\n\nFILE_NOT_FOUND = \"file not found\"\n\n\nSubtaskStatus = namedtuple(\n    \"SubtaskStatus\", [\"log_msg\", \"run_status\", \"details\", \"summary_message\"]\n)\n\n\nclass DebugRunStatus(Flag):\n    SUCCESS = True\n    FAIL = False\n\n\nclass DebugTask(BaseTask):\n    def __init__(self, args: Flags) -> None:\n        super().__init__(args)\n        self.profiles_dir = args.PROFILES_DIR\n        self.profile_path = os.path.join(self.profiles_dir, \"profiles.yml\")\n        try:\n            self.project_dir = get_nearest_project_dir(self.args.project_dir)\n        except dbt_common.exceptions.DbtBaseException:\n            # we probably couldn't find a project directory. Set project dir\n            # to whatever was given, or default to the current directory.\n            if args.project_dir:\n                self.project_dir = args.project_dir\n            else:\n                self.project_dir = Path.cwd()\n        self.project_path = os.path.join(self.project_dir, \"dbt_project.yml\")\n        self.cli_vars: Dict[str, Any] = args.vars\n\n        # set by _load_*\n        self.profile: Optional[Profile] = None\n        self.raw_profile_data: Optional[Dict[str, Any]] = None\n        self.profile_name: Optional[str] = None\n\n    def run(self) -> bool:\n        # WARN: this is a legacy workflow that is not compatible with other runtime flags\n        if getattr(self.args, \"config_dir\", None):\n            fire_event(\n                OpenCommand(\n                    open_cmd=dbt_common.clients.system.open_dir_cmd(),\n                    profiles_dir=str(self.profiles_dir),\n                )\n            )\n            return DebugRunStatus.SUCCESS.value\n\n        version: str = get_installed_version().to_version_string(skip_matcher=True)\n        fire_event(DebugCmdOut(msg=\"dbt version: {}\".format(version)))\n        fire_event(DebugCmdOut(msg=\"python version: {}\".format(sys.version.split()[0])))\n        fire_event(DebugCmdOut(msg=\"python path: {}\".format(sys.executable)))\n        fire_event(DebugCmdOut(msg=\"os info: {}\".format(platform.platform())))\n\n        # Load profile if possible, then load adapter info (which requires the profile)\n        load_profile_status: SubtaskStatus = self._load_profile()\n        fire_event(DebugCmdOut(msg=\"Using profiles dir at {}\".format(self.profiles_dir)))\n        fire_event(DebugCmdOut(msg=\"Using profiles.yml file at {}\".format(self.profile_path)))\n        fire_event(DebugCmdOut(msg=\"Using dbt_project.yml file at {}\".format(self.project_path)))\n        if load_profile_status.run_status == RunStatus.Success:\n            if self.profile is None:\n                raise dbt_common.exceptions.DbtInternalError(\n                    \"Profile should not be None if loading profile completed\"\n                )\n            else:\n                adapter_type: str = self.profile.credentials.type\n\n            adapter_version: str = self._read_adapter_version(\n                f\"dbt.adapters.{adapter_type}.__version__\"\n            )\n            fire_event(DebugCmdOut(msg=\"adapter type: {}\".format(adapter_type)))\n            fire_event(DebugCmdOut(msg=\"adapter version: {}\".format(adapter_version)))\n\n        # Get project loaded to do additional checks\n        load_project_status: SubtaskStatus = self._load_project()\n\n        dependencies_statuses: List[SubtaskStatus] = []\n        if getattr(self.args, \"connection\", False):\n            fire_event(DebugCmdOut(msg=\"Skipping steps before connection verification\"))\n        else:\n            # this job's status not logged since already accounted for in _load_* commands\n            self.test_configuration(load_profile_status.log_msg, load_project_status.log_msg)\n            dependencies_statuses = self.test_dependencies()\n\n        # Test connection\n        connection_status = self.test_connection()\n\n        # Log messages from any fails\n        all_statuses: List[SubtaskStatus] = [\n            load_profile_status,\n            load_project_status,\n            *dependencies_statuses,\n            connection_status,\n        ]\n        all_failing_statuses: List[SubtaskStatus] = list(\n            filter(lambda status: status.run_status == RunStatus.Error, all_statuses)\n        )\n\n        failure_count: int = len(all_failing_statuses)\n        if failure_count > 0:\n            fire_event(DebugCmdResult(msg=red(f\"{(pluralize(failure_count, 'check'))} failed:\")))\n            for status in all_failing_statuses:\n                fire_event(DebugCmdResult(msg=f\"{status.summary_message}\\n\"))\n            return DebugRunStatus.FAIL.value\n        else:\n            fire_event(DebugCmdResult(msg=green(\"All checks passed!\")))\n            return DebugRunStatus.SUCCESS.value\n\n    # ==============================\n    # Override for elsewhere in core\n    # ==============================\n\n    def interpret_results(self, results):\n        return results\n\n    # ===============\n    # Loading profile\n    # ===============\n\n    def _load_profile(self) -> SubtaskStatus:\n        \"\"\"\n        Side effects: load self.profile\n                      load self.target_name\n                      load self.raw_profile_data\n        \"\"\"\n        if not os.path.exists(self.profile_path):\n            return SubtaskStatus(\n                log_msg=red(\"ERROR not found\"),\n                run_status=RunStatus.Error,\n                details=FILE_NOT_FOUND,\n                summary_message=MISSING_PROFILE_MESSAGE.format(\n                    path=self.profile_path, url=ProfileConfigDocs\n                ),\n            )\n\n        raw_profile_data = load_yaml_text(\n            dbt_common.clients.system.load_file_contents(self.profile_path)\n        )\n        if isinstance(raw_profile_data, dict):\n            self.raw_profile_data = raw_profile_data\n\n        profile_errors = []\n        profile_names, summary_message = self._choose_profile_names()\n        renderer = ProfileRenderer(self.cli_vars)\n        for profile_name in profile_names:\n            try:\n                profile: Profile = Profile.render(\n                    renderer,\n                    profile_name,\n                    self.args.profile,\n                    self.args.target,\n                    # TODO: Generalize safe access to flags.THREADS:\n                    # https://github.com/dbt-labs/dbt-core/issues/6259\n                    getattr(self.args, \"threads\", None),\n                )\n            except dbt_common.exceptions.DbtConfigError as exc:\n                profile_errors.append(str(exc))\n            else:\n                if len(profile_names) == 1:\n                    # if a profile was specified, set it on the task\n                    self.target_name = self._choose_target_name(profile_name)\n                    self.profile = profile\n\n        if profile_errors:\n            details = \"\\n\\n\".join(profile_errors)\n            return SubtaskStatus(\n                log_msg=red(\"ERROR invalid\"),\n                run_status=RunStatus.Error,\n                details=details,\n                summary_message=(\n                    summary_message + f\"Profile loading failed for the following reason:\"\n                    f\"\\n{details}\"\n                    f\"\\n\"\n                ),\n            )\n        else:\n            return SubtaskStatus(\n                log_msg=green(\"OK found and valid\"),\n                run_status=RunStatus.Success,\n                details=\"\",\n                summary_message=\"Profile is valid\",\n            )\n\n    def _choose_profile_names(self) -> Tuple[List[str], str]:\n        project_profile: Optional[str] = None\n        if os.path.exists(self.project_path):\n            try:\n                partial = PartialProject.from_project_root(\n                    os.path.dirname(self.project_path),\n                    verify_version=bool(self.args.VERSION_CHECK),\n                )\n                renderer = DbtProjectYamlRenderer(None, self.cli_vars)\n                project_profile = partial.render_profile_name(renderer)\n            except dbt.exceptions.DbtProjectError:\n                pass\n\n        args_profile: Optional[str] = getattr(self.args, \"profile\", None)\n\n        try:\n            return [Profile.pick_profile_name(args_profile, project_profile)], \"\"\n        except dbt_common.exceptions.DbtConfigError:\n            pass\n        # try to guess\n\n        profiles = []\n        if self.raw_profile_data:\n            profiles = [k for k in self.raw_profile_data if k != \"config\"]\n            if project_profile is None:\n                summary_message = \"Could not load dbt_project.yml\\n\"\n            elif len(profiles) == 0:\n                summary_message = \"The profiles.yml has no profiles\\n\"\n            elif len(profiles) == 1:\n                summary_message = ONLY_PROFILE_MESSAGE.format(profiles[0])\n            else:\n                summary_message = MULTIPLE_PROFILE_MESSAGE.format(\n                    \"\\n\".join(\" - {}\".format(o) for o in profiles)\n                )\n        return profiles, summary_message\n\n    def _read_adapter_version(self, module) -> str:\n        \"\"\"read the version out of a standard adapter file\"\"\"\n        try:\n            version = importlib.import_module(module).version\n        except ModuleNotFoundError:\n            version = red(\"ERROR not found\")\n        except Exception as exc:\n            version = red(\"ERROR {}\".format(exc))\n            raise dbt.exceptions.DbtInternalError(\n                f\"Error when reading adapter version from {module}: {exc}\"\n            )\n\n        return version\n\n    def _choose_target_name(self, profile_name: str):\n        has_raw_profile = (\n            self.raw_profile_data is not None and profile_name in self.raw_profile_data\n        )\n\n        if not has_raw_profile:\n            return None\n\n        # mypy appeasement, we checked just above\n        assert self.raw_profile_data is not None\n        raw_profile = self.raw_profile_data[profile_name]\n\n        renderer = ProfileRenderer(self.cli_vars)\n\n        target_name, _ = Profile.render_profile(\n            raw_profile=raw_profile,\n            profile_name=profile_name,\n            target_override=getattr(self.args, \"target\", None),\n            renderer=renderer,\n        )\n        return target_name\n\n    # ===============\n    # Loading project\n    # ===============\n\n    def _load_project(self) -> SubtaskStatus:\n        \"\"\"\n        Side effect: load self.project\n        \"\"\"\n        if not os.path.exists(self.project_path):\n            return SubtaskStatus(\n                log_msg=red(\"ERROR not found\"),\n                run_status=RunStatus.Error,\n                details=FILE_NOT_FOUND,\n                summary_message=(\n                    f\"Project loading failed for the following reason:\"\n                    f\"\\n project path <{self.project_path}> not found\"\n                ),\n            )\n\n        renderer = DbtProjectYamlRenderer(self.profile, self.cli_vars)\n\n        try:\n            self.project = Project.from_project_root(\n                str(self.project_dir),\n                renderer,\n                verify_version=self.args.VERSION_CHECK,\n            )\n        except dbt_common.exceptions.DbtConfigError as exc:\n            return SubtaskStatus(\n                log_msg=red(\"ERROR invalid\"),\n                run_status=RunStatus.Error,\n                details=str(exc),\n                summary_message=(\n                    f\"Project loading failed for the following reason:\" f\"\\n{str(exc)}\" f\"\\n\"\n                ),\n            )\n        else:\n            return SubtaskStatus(\n                log_msg=green(\"OK found and valid\"),\n                run_status=RunStatus.Success,\n                details=\"\",\n                summary_message=\"Project is valid\",\n            )\n\n    def _profile_found(self) -> str:\n        if not self.raw_profile_data:\n            return red(\"ERROR not found\")\n        assert self.raw_profile_data is not None\n        if self.profile_name in self.raw_profile_data:\n            return green(\"OK found\")\n        else:\n            return red(\"ERROR not found\")\n\n    def _target_found(self) -> str:\n        requirements = self.raw_profile_data and self.profile_name and self.target_name\n        if not requirements:\n            return red(\"ERROR not found\")\n        # mypy appeasement, we checked just above\n        assert self.raw_profile_data is not None\n        assert self.profile_name is not None\n        assert self.target_name is not None\n        if self.profile_name not in self.raw_profile_data:\n            return red(\"ERROR not found\")\n        profiles = self.raw_profile_data[self.profile_name][\"outputs\"]\n        if self.target_name not in profiles:\n            return red(\"ERROR not found\")\n        else:\n            return green(\"OK found\")\n\n    # ============\n    # Config tests\n    # ============\n\n    def test_git(self) -> SubtaskStatus:\n        try:\n            dbt_common.clients.system.run_cmd(os.getcwd(), [\"git\", \"--help\"])\n        except dbt_common.exceptions.ExecutableError as exc:\n            return SubtaskStatus(\n                log_msg=red(\"ERROR\"),\n                run_status=RunStatus.Error,\n                details=\"git error\",\n                summary_message=\"Error from git --help: {!s}\".format(exc),\n            )\n        else:\n            return SubtaskStatus(\n                log_msg=green(\"OK found\"),\n                run_status=RunStatus.Success,\n                details=\"\",\n                summary_message=\"git is installed and on the path\",\n            )\n\n    def test_dependencies(self) -> List[SubtaskStatus]:\n        fire_event(DebugCmdOut(msg=\"Required dependencies:\"))\n\n        git_test_status = self.test_git()\n        fire_event(DebugCmdResult(msg=f\" - git [{git_test_status.log_msg}]\\n\"))\n\n        return [git_test_status]\n\n    def test_configuration(self, profile_status_msg, project_status_msg):\n        fire_event(DebugCmdOut(msg=\"Configuration:\"))\n        fire_event(DebugCmdOut(msg=f\"  profiles.yml file [{profile_status_msg}]\"))\n        fire_event(DebugCmdOut(msg=f\"  dbt_project.yml file [{project_status_msg}]\"))\n\n        # skip profile stuff if we can't find a profile name\n        if self.profile_name is not None:\n            fire_event(\n                DebugCmdOut(\n                    msg=\"  profile: {} [{}]\\n\".format(self.profile_name, self._profile_found())\n                )\n            )\n            fire_event(\n                DebugCmdOut(\n                    msg=\"  target: {} [{}]\\n\".format(self.target_name, self._target_found())\n                )\n            )\n\n    # ===============\n    # Connection test\n    # ===============\n\n    @staticmethod\n    def attempt_connection(profile) -> Optional[str]:\n        \"\"\"Return a string containing the error message, or None if there was no error.\"\"\"\n        register_adapter(profile, get_mp_context())\n        adapter = get_adapter(profile)\n        try:\n            with adapter.connection_named(\"debug\"):\n                # is defined in adapter class\n                adapter.debug_query()\n        except Exception as exc:\n            return COULD_NOT_CONNECT_MESSAGE.format(\n                err=str(exc),\n                url=ProfileConfigDocs,\n            )\n        return None\n\n    def test_connection(self) -> SubtaskStatus:\n        if self.profile is None:\n            fire_event(DebugCmdOut(msg=\"Connection test skipped since no profile was found\"))\n            return SubtaskStatus(\n                log_msg=red(\"SKIPPED\"),\n                run_status=RunStatus.Skipped,\n                details=\"No profile found\",\n                summary_message=\"Connection test skipped since no profile was found\",\n            )\n\n        fire_event(DebugCmdOut(msg=\"Connection:\"))\n        for k, v in self.profile.credentials.connection_info():\n            fire_event(DebugCmdOut(msg=f\"  {k}: {v}\"))\n\n        connection_result = self.attempt_connection(self.profile)\n        if connection_result is None:\n            status = SubtaskStatus(\n                log_msg=green(\"OK connection ok\"),\n                run_status=RunStatus.Success,\n                details=\"\",\n                summary_message=\"Connection test passed\",\n            )\n        else:\n            status = SubtaskStatus(\n                log_msg=red(\"ERROR\"),\n                run_status=RunStatus.Error,\n                details=\"Failure in connecting to db\",\n                summary_message=connection_result,\n            )\n        fire_event(DebugCmdOut(msg=f\"  Connection test: [{status.log_msg}]\\n\"))\n        return status\n\n    @classmethod\n    def validate_connection(cls, target_dict) -> None:\n        \"\"\"Validate a connection dictionary. On error, raises a DbtConfigError.\"\"\"\n        target_name = \"test\"\n        # make a fake profile that we can parse\n        profile_data = {\n            \"outputs\": {\n                target_name: target_dict,\n            },\n        }\n        # this will raise a DbtConfigError on failure\n        profile = Profile.from_raw_profile_info(\n            raw_profile=profile_data,\n            profile_name=\"\",\n            target_override=target_name,\n            renderer=ProfileRenderer({}),\n        )\n        result = cls.attempt_connection(profile)\n        if result is not None:\n            raise dbt.exceptions.DbtProfileError(result, result_type=\"connection_failure\")\n"
  },
  {
    "path": "core/dbt/task/deps.py",
    "content": "import json\nfrom hashlib import sha1\nfrom pathlib import Path\nfrom typing import Any, Dict, List, Optional\n\nimport yaml\n\nimport dbt.deprecations\nimport dbt.exceptions\nimport dbt.utils\nfrom dbt.config import Project\nfrom dbt.config.project import load_yml_dict, package_config_from_data\nfrom dbt.config.renderer import PackageRenderer\nfrom dbt.constants import PACKAGE_LOCK_FILE_NAME, PACKAGE_LOCK_HASH_KEY\nfrom dbt.contracts.project import PackageSpec\nfrom dbt.deps.base import downloads_directory\nfrom dbt.deps.registry import RegistryPinnedPackage\nfrom dbt.deps.resolver import resolve_lock_packages, resolve_packages\nfrom dbt.events.types import (\n    DepsAddPackage,\n    DepsFoundDuplicatePackage,\n    DepsInstallInfo,\n    DepsListSubdirectory,\n    DepsLockUpdating,\n    DepsNoPackagesFound,\n    DepsNotifyUpdatesAvailable,\n    DepsStartPackageInstall,\n    DepsUpdateAvailable,\n    DepsUpToDate,\n)\nfrom dbt.task.base import BaseTask, move_to_nearest_project_dir\nfrom dbt_common.clients import system\nfrom dbt_common.events.functions import fire_event\nfrom dbt_common.events.types import Formatting\n\n\nclass dbtPackageDumper(yaml.Dumper):\n    def increase_indent(self, flow=False, indentless=False):\n        return super(dbtPackageDumper, self).increase_indent(flow, False)\n\n\ndef _create_sha1_hash(packages: List[PackageSpec]) -> str:\n    \"\"\"Create a SHA1 hash of the packages list,\n    this is used to determine if the packages for current execution matches\n    the previous lock.\n\n    Args:\n        list[Packages]: list of packages specified that are already rendered\n\n    Returns:\n        str: SHA1 hash of the packages list\n    \"\"\"\n    package_strs = [json.dumps(package.to_dict(), sort_keys=True) for package in packages]\n    package_strs = sorted(package_strs)\n\n    return sha1(\"\\n\".join(package_strs).encode(\"utf-8\")).hexdigest()\n\n\ndef _create_packages_yml_entry(package: str, version: Optional[str], source: str) -> dict:\n    \"\"\"Create a formatted entry to add to `packages.yml` or `package-lock.yml` file\n\n    Args:\n        package (str): Name of package to download\n        version (str): Version of package to download\n        source (str): Source of where to download package from\n\n    Returns:\n        dict: Formatted dict to write to `packages.yml` or `package-lock.yml` file\n    \"\"\"\n    package_key = source\n    version_key = \"version\"\n\n    if source == \"hub\":\n        package_key = \"package\"\n\n    packages_yml_entry = {package_key: package}\n\n    if source == \"git\":\n        version_key = \"revision\"\n\n    if version:\n        if \",\" in version:\n            version = version.split(\",\")  # type: ignore\n\n        packages_yml_entry[version_key] = version\n\n    return packages_yml_entry\n\n\nclass DepsTask(BaseTask):\n    def __init__(self, args: Any, project: Project) -> None:\n        super().__init__(args=args)\n        # N.B. This is a temporary fix for a bug when using relative paths via\n        # --project-dir with deps.  A larger overhaul of our path handling methods\n        # is needed to fix this the \"right\" way.\n        # See GH-7615\n        project.project_root = str(Path(project.project_root).resolve())\n        self.project = project\n        self.cli_vars = args.vars\n\n    def track_package_install(\n        self, package_name: str, source_type: str, version: Optional[str]\n    ) -> None:\n        # Hub packages do not need to be hashed, as they are public\n        if source_type == \"local\":\n            package_name = dbt.utils.md5(package_name)\n            version = \"local\"\n        elif source_type == \"tarball\":\n            package_name = dbt.utils.md5(package_name)\n            version = \"tarball\"\n        elif source_type != \"hub\":\n            package_name = dbt.utils.md5(package_name)\n            version = dbt.utils.md5(version)\n\n        dbt.tracking.track_package_install(\n            \"deps\",\n            self.project.hashed_name(),\n            {\"name\": package_name, \"source\": source_type, \"version\": version},\n        )\n\n    def check_for_duplicate_packages(self, packages_yml):\n        \"\"\"Loop through contents of `packages.yml` to remove entries that match the package being added.\n\n        This method is called only during `dbt deps --add-package` to check if the package\n        being added already exists in packages.yml. It uses substring matching to identify\n        duplicates, which means it will match across different package sources. For example,\n        adding a hub package \"dbt-labs/dbt_utils\" will remove an existing git package\n        \"https://github.com/dbt-labs/dbt-utils.git\" since both contain \"dbt_utils\" or \"dbt-utils\".\n\n        The matching is flexible to handle both underscore and hyphen variants of package names,\n        as git repos often use hyphens (dbt-utils) while package names use underscores (dbt_utils).\n        Word boundaries (/, .) are enforced to prevent false matches like \"dbt-core\" matching\n        \"dbt-core-utils\".\n\n        Args:\n            packages_yml (dict): In-memory read of `packages.yml` contents\n\n        Returns:\n            dict: Updated packages_yml contents with matching packages removed\n        \"\"\"\n        # Extract the package name for matching\n        package_name = self.args.add_package[\"name\"]\n\n        # Create variants for flexible matching (handle _ vs -)\n        # Check multiple variants to handle naming inconsistencies between hub and git\n        package_name_parts = [\n            package_name,  # Original: \"dbt-labs/dbt_utils\"\n            package_name.replace(\"_\", \"-\"),  # Hyphens: \"dbt-labs/dbt-utils\"\n            package_name.replace(\"-\", \"_\"),  # Underscores: \"dbt_labs/dbt_utils\"\n        ]\n        # Extract just the package name without org (after last /)\n        if \"/\" in package_name:\n            short_name = package_name.split(\"/\")[-1]\n            package_name_parts.extend(\n                [\n                    short_name,  # \"dbt_utils\"\n                    short_name.replace(\"_\", \"-\"),  # \"dbt-utils\"\n                    short_name.replace(\"-\", \"_\"),  # \"dbt_utils\" (deduplicated)\n                ]\n            )\n\n        # Remove duplicates from package_name_parts\n        package_name_parts = list(set(package_name_parts))\n\n        # Iterate backwards to safely delete items without index shifting issues\n        for i in range(len(packages_yml[\"packages\"]) - 1, -1, -1):\n            pkg_entry = packages_yml[\"packages\"][i]\n\n            # Get the package identifier key (package type determines which key exists)\n            # This avoids iterating over non-string values like warn-unpinned: false\n            package_identifier = (\n                pkg_entry.get(\"package\")  # hub/registry package\n                or pkg_entry.get(\"git\")  # git package\n                or pkg_entry.get(\"local\")  # local package\n                or pkg_entry.get(\"tarball\")  # tarball package\n                or pkg_entry.get(\"private\")  # private package\n            )\n\n            # Check if any variant of the package name appears in the identifier\n            # Use word boundaries to avoid false matches (e.g., \"dbt-core\" shouldn't match \"dbt-core-utils\")\n            # Word boundaries are: start/end of string, /, or .\n            # Note: - and _ are NOT boundaries since they're used within compound package names\n            if package_identifier:\n                is_duplicate = False\n                for name_variant in package_name_parts:\n                    if name_variant in package_identifier:\n                        # Found a match, now verify it's not a substring of a larger word\n                        # Check characters before and after the match\n                        idx = package_identifier.find(name_variant)\n                        start_ok = idx == 0 or package_identifier[idx - 1] in \"/.\"\n                        end_idx = idx + len(name_variant)\n                        end_ok = (\n                            end_idx == len(package_identifier)\n                            or package_identifier[end_idx] in \"/.\"\n                        )\n\n                        if start_ok and end_ok:\n                            is_duplicate = True\n                            break\n\n                if is_duplicate:\n                    del packages_yml[\"packages\"][i]\n                    # Filter out non-string values (like warn-unpinned boolean) before logging\n                    # Note: Check for bool first since bool is a subclass of int in Python\n                    loggable_package = {\n                        k: v\n                        for k, v in pkg_entry.items()\n                        if not isinstance(v, bool)\n                        and isinstance(v, (str, int, float))\n                        and k != \"unrendered\"\n                    }\n                    fire_event(DepsFoundDuplicatePackage(removed_package=loggable_package))\n\n        return packages_yml\n\n    def add(self):\n        packages_yml_filepath = (\n            f\"{self.project.project_root}/{self.project.packages_specified_path}\"\n        )\n        if not system.path_exists(packages_yml_filepath):\n            with open(packages_yml_filepath, \"w\") as package_yml:\n                yaml.safe_dump({\"packages\": []}, package_yml)\n            fire_event(Formatting(\"Created packages.yml\"))\n\n        new_package_entry = _create_packages_yml_entry(\n            self.args.add_package[\"name\"], self.args.add_package[\"version\"], self.args.source\n        )\n\n        with open(packages_yml_filepath, \"r\") as user_yml_obj:\n            packages_yml = yaml.safe_load(user_yml_obj)\n            packages_yml = self.check_for_duplicate_packages(packages_yml)\n            packages_yml[\"packages\"].append(new_package_entry)\n\n        self.project.packages.packages = package_config_from_data(packages_yml).packages\n\n        if packages_yml:\n            with open(packages_yml_filepath, \"w\") as pkg_obj:\n                pkg_obj.write(\n                    yaml.dump(packages_yml, Dumper=dbtPackageDumper, default_flow_style=False)\n                )\n\n                fire_event(\n                    DepsAddPackage(\n                        package_name=self.args.add_package[\"name\"],\n                        version=self.args.add_package[\"version\"],\n                        packages_filepath=packages_yml_filepath,\n                    )\n                )\n\n    def lock(self) -> None:\n        lock_filepath = f\"{self.project.project_root}/{PACKAGE_LOCK_FILE_NAME}\"\n\n        packages = self.project.packages.packages\n        packages_installed: Dict[str, Any] = {\"packages\": []}\n\n        if not packages:\n            fire_event(DepsNoPackagesFound())\n            return\n\n        with downloads_directory():\n            resolved_deps = resolve_packages(packages, self.project, self.cli_vars)\n\n        # this loop is to create the package-lock.yml in the same format as original packages.yml\n        # package-lock.yml includes both the stated packages in packages.yml along with dependent packages\n        renderer = PackageRenderer(self.cli_vars)\n        for package in resolved_deps:\n            package_dict = package.to_dict()\n            package_dict[\"name\"] = package.get_project_name(self.project, renderer)\n            packages_installed[\"packages\"].append(package_dict)\n\n        packages_installed[PACKAGE_LOCK_HASH_KEY] = _create_sha1_hash(\n            self.project.packages.packages\n        )\n\n        with open(lock_filepath, \"w\") as lock_obj:\n            yaml.dump(packages_installed, lock_obj, Dumper=dbtPackageDumper)\n\n        fire_event(DepsLockUpdating(lock_filepath=lock_filepath))\n\n    def run(self) -> None:\n        move_to_nearest_project_dir(self.args.project_dir)\n        if self.args.add_package:\n            self.add()\n\n        # Check lock file exist and generated by the same packages.yml\n        # or dependencies.yml.\n        lock_file_path = f\"{self.project.project_root}/{PACKAGE_LOCK_FILE_NAME}\"\n        if not system.path_exists(lock_file_path):\n            self.lock()\n        elif self.args.upgrade:\n            self.lock()\n        else:\n            # Check dependency definition is modified or not.\n            current_hash = _create_sha1_hash(self.project.packages.packages)\n            previous_hash = load_yml_dict(lock_file_path).get(PACKAGE_LOCK_HASH_KEY, None)\n            if previous_hash != current_hash:\n                self.lock()\n\n        # Early return when 'dbt deps --lock'\n        # Just resolve packages and write lock file, don't actually install packages\n        if self.args.lock:\n            return\n\n        if system.path_exists(self.project.packages_install_path):\n            system.rmtree(self.project.packages_install_path)\n\n        system.make_directory(self.project.packages_install_path)\n\n        packages_lock_dict = load_yml_dict(f\"{self.project.project_root}/{PACKAGE_LOCK_FILE_NAME}\")\n\n        renderer = PackageRenderer(self.cli_vars)\n        packages_lock_config = package_config_from_data(\n            renderer.render_data(packages_lock_dict), packages_lock_dict\n        ).packages\n\n        if not packages_lock_config:\n            fire_event(DepsNoPackagesFound())\n            return\n\n        with downloads_directory():\n            lock_defined_deps = resolve_lock_packages(packages_lock_config)\n            renderer = PackageRenderer(self.cli_vars)\n\n            packages_to_upgrade = []\n\n            for package in lock_defined_deps:\n                package_name = package.name\n                source_type = package.source_type()\n                version = package.get_version()\n\n                fire_event(DepsStartPackageInstall(package_name=package_name))\n                package.install(self.project, renderer)\n\n                fire_event(DepsInstallInfo(version_name=package.nice_version_name()))\n\n                if isinstance(package, RegistryPinnedPackage):\n                    version_latest = package.get_version_latest()\n\n                    if version_latest != version:\n                        packages_to_upgrade.append(package_name)\n                        fire_event(DepsUpdateAvailable(version_latest=version_latest))\n                    else:\n                        fire_event(DepsUpToDate())\n\n                if package.get_subdirectory():\n                    fire_event(DepsListSubdirectory(subdirectory=package.get_subdirectory()))\n\n                self.track_package_install(\n                    package_name=package_name, source_type=source_type, version=version\n                )\n\n            if packages_to_upgrade:\n                fire_event(Formatting(\"\"))\n                fire_event(DepsNotifyUpdatesAvailable(packages=packages_to_upgrade))\n"
  },
  {
    "path": "core/dbt/task/docs/__init__.py",
    "content": "import os\n\nDOCS_INDEX_FILE_PATH = os.path.normpath(os.path.join(os.path.dirname(__file__), \"index.html\"))\n"
  },
  {
    "path": "core/dbt/task/docs/generate.py",
    "content": "import os\nimport shutil\nfrom dataclasses import replace\nfrom datetime import datetime, timezone\nfrom itertools import chain\nfrom typing import Any, Dict, Iterable, List, Optional, Set, Tuple\n\nimport agate\n\nimport dbt.compilation\nimport dbt.exceptions\nimport dbt.utils\nimport dbt_common.utils.formatting\nfrom dbt.adapters.events.types import (\n    BuildingCatalog,\n    CannotGenerateDocs,\n    CatalogWritten,\n    WriteCatalogFailure,\n)\nfrom dbt.adapters.factory import get_adapter\nfrom dbt.artifacts.schemas.catalog import (\n    CatalogArtifact,\n    CatalogKey,\n    CatalogResults,\n    CatalogTable,\n    ColumnMetadata,\n    PrimitiveDict,\n    StatsDict,\n    StatsItem,\n    TableMetadata,\n)\nfrom dbt.artifacts.schemas.results import NodeStatus\nfrom dbt.constants import CATALOG_FILENAME, MANIFEST_FILE_NAME\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.contracts.graph.nodes import ResultNode\nfrom dbt.events.types import ArtifactWritten\nfrom dbt.exceptions import AmbiguousCatalogMatchError\nfrom dbt.graph import ResourceTypeSelector\nfrom dbt.graph.graph import UniqueId\nfrom dbt.node_types import EXECUTABLE_NODE_TYPES, NodeType\nfrom dbt.parser.manifest import write_manifest\nfrom dbt.task.compile import CompileTask\nfrom dbt.task.docs import DOCS_INDEX_FILE_PATH\nfrom dbt.utils.artifact_upload import add_artifact_produced\nfrom dbt_common.clients.system import load_file_contents\nfrom dbt_common.dataclass_schema import ValidationError\nfrom dbt_common.events.functions import fire_event\nfrom dbt_common.exceptions import DbtInternalError\n\n\ndef get_stripped_prefix(source: Dict[str, Any], prefix: str) -> Dict[str, Any]:\n    \"\"\"Go through the source, extracting every key/value pair where the key starts\n    with the given prefix.\n    \"\"\"\n    cut = len(prefix)\n    return {k[cut:]: v for k, v in source.items() if k.startswith(prefix)}\n\n\ndef build_catalog_table(data) -> CatalogTable:\n    # build the new table's metadata + stats\n    metadata = TableMetadata.from_dict(get_stripped_prefix(data, \"table_\"))\n    stats = format_stats(get_stripped_prefix(data, \"stats:\"))\n\n    return CatalogTable(\n        metadata=metadata,\n        stats=stats,\n        columns={},\n    )\n\n\n# keys are database name, schema name, table name\nclass Catalog(Dict[CatalogKey, CatalogTable]):\n    def __init__(self, columns: List[PrimitiveDict]) -> None:\n        super().__init__()\n        for col in columns:\n            self.add_column(col)\n\n    def get_table(self, data: PrimitiveDict) -> CatalogTable:\n        database = data.get(\"table_database\")\n        if database is None:\n            dkey: Optional[str] = None\n        else:\n            dkey = str(database)\n\n        try:\n            key = CatalogKey(\n                dkey,\n                str(data[\"table_schema\"]),\n                str(data[\"table_name\"]),\n            )\n        except KeyError as exc:\n            raise dbt_common.exceptions.CompilationError(\n                \"Catalog information missing required key {} (got {})\".format(exc, data)\n            )\n        table: CatalogTable\n        if key in self:\n            table = self[key]\n        else:\n            table = build_catalog_table(data)\n            self[key] = table\n        return table\n\n    def add_column(self, data: PrimitiveDict):\n        table = self.get_table(data)\n        column_data = get_stripped_prefix(data, \"column_\")\n        # the index should really never be that big so it's ok to end up\n        # serializing this to JSON (2^53 is the max safe value there)\n        column_data[\"index\"] = int(column_data[\"index\"])\n\n        column = ColumnMetadata.from_dict(column_data)\n        table.columns[column.name] = column\n\n    def make_unique_id_map(\n        self, manifest: Manifest, selected_node_ids: Optional[Set[UniqueId]] = None\n    ) -> Tuple[Dict[str, CatalogTable], Dict[str, CatalogTable]]:\n        \"\"\"\n        Create mappings between CatalogKeys and CatalogTables for nodes and sources, filtered by selected_node_ids.\n\n        By default, selected_node_ids is None and all nodes and sources defined in the manifest are included in the mappings.\n        \"\"\"\n        nodes: Dict[str, CatalogTable] = {}\n        sources: Dict[str, CatalogTable] = {}\n\n        node_map, source_map = get_unique_id_mapping(manifest)\n        table: CatalogTable\n        for table in self.values():\n            key = table.key()\n            if key in node_map:\n                unique_id = node_map[key]\n                if selected_node_ids is None or unique_id in selected_node_ids:\n                    nodes[unique_id] = replace(table, unique_id=unique_id)\n\n            unique_ids = source_map.get(table.key(), set())\n            for unique_id in unique_ids:\n                if unique_id in sources:\n                    raise AmbiguousCatalogMatchError(\n                        unique_id,\n                        sources[unique_id].to_dict(omit_none=True),\n                        table.to_dict(omit_none=True),\n                    )\n                elif selected_node_ids is None or unique_id in selected_node_ids:\n                    sources[unique_id] = replace(table, unique_id=unique_id)\n        return nodes, sources\n\n\ndef format_stats(stats: PrimitiveDict) -> StatsDict:\n    \"\"\"Given a dictionary following this layout:\n\n        {\n            'encoded:label': 'Encoded',\n            'encoded:value': 'Yes',\n            'encoded:description': 'Indicates if the column is encoded',\n            'encoded:include': True,\n\n            'size:label': 'Size',\n            'size:value': 128,\n            'size:description': 'Size of the table in MB',\n            'size:include': True,\n        }\n\n    format_stats will convert the dict into a StatsDict with keys of 'encoded'\n    and 'size'.\n    \"\"\"\n    stats_collector: StatsDict = {}\n\n    base_keys = {k.split(\":\")[0] for k in stats}\n    for key in base_keys:\n        dct: PrimitiveDict = {\"id\": key}\n        for subkey in (\"label\", \"value\", \"description\", \"include\"):\n            dct[subkey] = stats[\"{}:{}\".format(key, subkey)]\n\n        try:\n            stats_item = StatsItem.from_dict(dct)\n        except ValidationError:\n            continue\n        if stats_item.include:\n            stats_collector[key] = stats_item\n\n    # we always have a 'has_stats' field, it's never included\n    has_stats = StatsItem(\n        id=\"has_stats\",\n        label=\"Has Stats?\",\n        value=len(stats_collector) > 0,\n        description=\"Indicates whether there are statistics for this table\",\n        include=False,\n    )\n    stats_collector[\"has_stats\"] = has_stats\n    return stats_collector\n\n\ndef mapping_key(node: ResultNode) -> CatalogKey:\n    dkey = dbt_common.utils.formatting.lowercase(node.database)\n    return CatalogKey(dkey, node.schema.lower(), node.identifier.lower())\n\n\ndef get_unique_id_mapping(\n    manifest: Manifest,\n) -> Tuple[Dict[CatalogKey, str], Dict[CatalogKey, Set[str]]]:\n    # A single relation could have multiple unique IDs pointing to it if a\n    # source were also a node.\n    node_map: Dict[CatalogKey, str] = {}\n    source_map: Dict[CatalogKey, Set[str]] = {}\n    for unique_id, node in manifest.nodes.items():\n        key = mapping_key(node)\n        node_map[key] = unique_id\n\n    for unique_id, source in manifest.sources.items():\n        key = mapping_key(source)\n        if key not in source_map:\n            source_map[key] = set()\n        source_map[key].add(unique_id)\n    return node_map, source_map\n\n\nclass GenerateTask(CompileTask):\n    def run(self) -> CatalogArtifact:\n        compile_results = None\n        if self.args.compile:\n            compile_results = CompileTask.run(self)\n            if any(r.status == NodeStatus.Error for r in compile_results):\n                fire_event(CannotGenerateDocs())\n                return CatalogArtifact.from_results(\n                    nodes={},\n                    sources={},\n                    generated_at=datetime.now(timezone.utc).replace(tzinfo=None),\n                    errors=None,\n                    compile_results=compile_results,\n                )\n\n        shutil.copyfile(\n            DOCS_INDEX_FILE_PATH, os.path.join(self.config.project_target_path, \"index.html\")\n        )\n\n        for asset_path in self.config.asset_paths:\n            to_asset_path = os.path.join(self.config.project_target_path, asset_path)\n\n            if os.path.exists(to_asset_path):\n                shutil.rmtree(to_asset_path)\n\n            from_asset_path = os.path.join(self.config.project_root, asset_path)\n\n            if os.path.exists(from_asset_path):\n                shutil.copytree(from_asset_path, to_asset_path)\n\n        if self.manifest is None:\n            raise DbtInternalError(\"self.manifest was None in run!\")\n\n        selected_node_ids: Optional[Set[UniqueId]] = None\n        if self.args.empty_catalog:\n            catalog_table: agate.Table = agate.Table([])\n            exceptions: List[Exception] = []\n            selected_node_ids = set()\n        else:\n            adapter = get_adapter(self.config)\n            with adapter.connection_named(\"generate_catalog\"):\n                fire_event(BuildingCatalog())\n                # Get a list of relations we need from the catalog\n                relations = None\n                if self.job_queue is not None:\n                    selected_node_ids = self.job_queue.get_selected_nodes()\n                    selected_nodes = self._get_nodes_from_ids(self.manifest, selected_node_ids)\n\n                    # Source selection is handled separately from main job_queue selection because\n                    # SourceDefinition nodes cannot be safely compiled / run by the CompileRunner / CompileTask,\n                    # but should still be included in the catalog based on the selection spec\n                    selected_source_ids = self._get_selected_source_ids()\n                    selected_source_nodes = self._get_nodes_from_ids(\n                        self.manifest, selected_source_ids\n                    )\n                    selected_node_ids.update(selected_source_ids)\n                    selected_nodes.extend(selected_source_nodes)\n\n                    relations = {\n                        adapter.Relation.create_from(adapter.config, node)\n                        for node in selected_nodes\n                    }\n\n                # This generates the catalog as an agate.Table\n                catalogable_nodes = chain(\n                    [\n                        node\n                        for node in self.manifest.nodes.values()\n                        if (node.is_relational and not node.is_ephemeral_model)\n                    ],\n                    self.manifest.sources.values(),\n                )\n                used_schemas = self.manifest.get_used_schemas()\n                catalog_table, exceptions = adapter.get_filtered_catalog(\n                    catalogable_nodes, used_schemas, relations\n                )\n\n        catalog_data: List[PrimitiveDict] = [\n            dict(zip(catalog_table.column_names, map(dbt.utils._coerce_decimal, row)))\n            for row in catalog_table\n        ]\n\n        catalog = Catalog(catalog_data)\n\n        errors: Optional[List[str]] = None\n        if exceptions:\n            errors = [str(e) for e in exceptions]\n\n        nodes, sources = catalog.make_unique_id_map(self.manifest, selected_node_ids)\n        results = self.get_catalog_results(\n            nodes=nodes,\n            sources=sources,\n            generated_at=datetime.now(timezone.utc).replace(tzinfo=None),\n            compile_results=compile_results,\n            errors=errors,\n        )\n\n        catalog_path = os.path.join(self.config.project_target_path, CATALOG_FILENAME)\n        results.write(catalog_path)\n        add_artifact_produced(catalog_path)\n        fire_event(\n            ArtifactWritten(artifact_type=results.__class__.__name__, artifact_path=catalog_path)\n        )\n\n        if self.args.compile:\n            write_manifest(self.manifest, self.config.project_target_path)\n\n        if self.args.static:\n\n            # Read manifest.json and catalog.json\n            read_manifest_data = load_file_contents(\n                os.path.join(self.config.project_target_path, MANIFEST_FILE_NAME)\n            )\n            read_catalog_data = load_file_contents(catalog_path)\n\n            # Create new static index file contents\n            index_data = load_file_contents(DOCS_INDEX_FILE_PATH)\n            index_data = index_data.replace('\"MANIFEST.JSON INLINE DATA\"', read_manifest_data)\n            index_data = index_data.replace('\"CATALOG.JSON INLINE DATA\"', read_catalog_data)\n\n            # Write out the new index file\n            static_index_path = os.path.join(self.config.project_target_path, \"static_index.html\")\n            with open(static_index_path, \"wb\") as static_index_file:\n                static_index_file.write(bytes(index_data, \"utf8\"))\n\n        if exceptions:\n            fire_event(WriteCatalogFailure(num_exceptions=len(exceptions)))\n        fire_event(CatalogWritten(path=os.path.abspath(catalog_path)))\n        return results\n\n    def get_node_selector(self) -> ResourceTypeSelector:\n        if self.manifest is None or self.graph is None:\n            raise DbtInternalError(\"manifest and graph must be set to perform node selection\")\n        return ResourceTypeSelector(\n            graph=self.graph,\n            manifest=self.manifest,\n            previous_state=self.previous_state,\n            resource_types=EXECUTABLE_NODE_TYPES,\n            include_empty_nodes=True,\n            selectors=self.config.selectors,\n        )\n\n    def get_catalog_results(\n        self,\n        nodes: Dict[str, CatalogTable],\n        sources: Dict[str, CatalogTable],\n        generated_at: datetime,\n        compile_results: Optional[Any],\n        errors: Optional[List[str]],\n    ) -> CatalogArtifact:\n        return CatalogArtifact.from_results(\n            generated_at=generated_at,\n            nodes=nodes,\n            sources=sources,\n            compile_results=compile_results,\n            errors=errors,\n        )\n\n    @classmethod\n    def interpret_results(self, results: Optional[CatalogResults]) -> bool:\n        if results is None:\n            return False\n        if results.errors:\n            return False\n        compile_results = results._compile_results\n        if compile_results is None:\n            return True\n\n        return super().interpret_results(compile_results)\n\n    @staticmethod\n    def _get_nodes_from_ids(manifest: Manifest, node_ids: Iterable[str]) -> List[ResultNode]:\n        selected: List[ResultNode] = []\n        for unique_id in node_ids:\n            if unique_id in manifest.nodes:\n                node = manifest.nodes[unique_id]\n                if node.is_relational and not node.is_ephemeral_model:\n                    selected.append(node)\n            elif unique_id in manifest.sources:\n                source = manifest.sources[unique_id]\n                selected.append(source)\n        return selected\n\n    def _get_selected_source_ids(self) -> Set[UniqueId]:\n        if self.manifest is None or self.graph is None:\n            raise DbtInternalError(\"manifest and graph must be set to perform node selection\")\n\n        source_selector = ResourceTypeSelector(\n            graph=self.graph,\n            manifest=self.manifest,\n            previous_state=self.previous_state,\n            resource_types=[NodeType.Source],\n            selectors=self.config.selectors,\n        )\n\n        return source_selector.get_graph_queue(self.get_selection_spec()).get_selected_nodes()\n"
  },
  {
    "path": "core/dbt/task/docs/serve.py",
    "content": "import os\nimport shutil\nimport socketserver\nimport webbrowser\nfrom http.server import SimpleHTTPRequestHandler\n\nimport click\n\nfrom dbt.task.base import ConfiguredTask\nfrom dbt.task.docs import DOCS_INDEX_FILE_PATH\n\n\nclass ServeTask(ConfiguredTask):\n    def run(self):\n        os.chdir(self.config.project_target_path)\n        shutil.copyfile(DOCS_INDEX_FILE_PATH, \"index.html\")\n\n        port = self.args.port\n        host = self.args.host\n\n        if self.args.browser:\n            webbrowser.open_new_tab(f\"http://localhost:{port}\")\n\n        with socketserver.TCPServer((host, port), SimpleHTTPRequestHandler) as httpd:\n            click.echo(f\"Serving docs at {port}\")\n            click.echo(f\"To access from your browser, navigate to: http://localhost:{port}\")\n            click.echo(\"\\n\\n\")\n            click.echo(\"Press Ctrl+C to exit.\")\n            httpd.serve_forever()\n"
  },
  {
    "path": "core/dbt/task/freshness.py",
    "content": "import os\nimport threading\nimport time\nfrom typing import AbstractSet, Dict, List, Optional, Type\n\nfrom dbt import deprecations\nfrom dbt.adapters.base import BaseAdapter\nfrom dbt.adapters.base.impl import FreshnessResponse\nfrom dbt.adapters.base.relation import BaseRelation\nfrom dbt.adapters.capability import Capability\nfrom dbt.adapters.contracts.connection import AdapterResponse\nfrom dbt.artifacts.schemas.freshness import (\n    FreshnessResult,\n    FreshnessStatus,\n    PartialSourceFreshnessResult,\n    SourceFreshnessResult,\n)\nfrom dbt.clients import jinja\nfrom dbt.constants import SOURCE_RESULT_FILE_NAME\nfrom dbt.context.providers import RuntimeProvider, SourceContext\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.contracts.graph.nodes import HookNode, SourceDefinition\nfrom dbt.contracts.results import RunStatus\nfrom dbt.events.types import FreshnessCheckComplete, LogFreshnessResult, LogStartLine\nfrom dbt.graph import ResourceTypeSelector\nfrom dbt.node_types import NodeType, RunHookType\nfrom dbt_common.events.base_types import EventLevel\nfrom dbt_common.events.functions import fire_event\nfrom dbt_common.events.types import Note\nfrom dbt_common.exceptions import DbtInternalError, DbtRuntimeError\n\nfrom .base import BaseRunner\nfrom .printer import print_run_result_error\nfrom .run import RunTask\n\n\nclass FreshnessRunner(BaseRunner):\n    def __init__(self, config, adapter, node, node_index, num_nodes) -> None:\n        super().__init__(config, adapter, node, node_index, num_nodes)\n        self._metadata_freshness_cache: Dict[BaseRelation, FreshnessResult] = {}\n\n    def set_metadata_freshness_cache(\n        self, metadata_freshness_cache: Dict[BaseRelation, FreshnessResult]\n    ) -> None:\n        self._metadata_freshness_cache = metadata_freshness_cache\n\n    def on_skip(self):\n        raise DbtRuntimeError(\"Freshness: nodes cannot be skipped!\")\n\n    def before_execute(self) -> None:\n        description = \"freshness of {0.source_name}.{0.name}\".format(self.node)\n        fire_event(\n            LogStartLine(\n                description=description,\n                index=self.node_index,\n                total=self.num_nodes,\n                node_info=self.node.node_info,\n            )\n        )\n\n    def after_execute(self, result) -> None:\n        if hasattr(result, \"node\"):\n            source_name = result.node.source_name\n            table_name = result.node.name\n        else:\n            source_name = result.source_name\n            table_name = result.table_name\n        level = LogFreshnessResult.status_to_level(str(result.status))\n        fire_event(\n            LogFreshnessResult(\n                status=result.status,\n                source_name=source_name,\n                table_name=table_name,\n                index=self.node_index,\n                total=self.num_nodes,\n                execution_time=result.execution_time,\n                node_info=self.node.node_info,\n            ),\n            level=level,\n        )\n\n    def error_result(self, node, message, start_time, timing_info):\n        return self._build_run_result(\n            node=node,\n            start_time=start_time,\n            status=FreshnessStatus.RuntimeErr,\n            timing_info=timing_info,\n            message=message,\n        )\n\n    def _build_run_result(self, node, start_time, status, timing_info, message):\n        execution_time = time.time() - start_time\n        thread_id = threading.current_thread().name\n        return PartialSourceFreshnessResult(\n            status=status,\n            thread_id=thread_id,\n            execution_time=execution_time,\n            timing=timing_info,\n            message=message,\n            node=node,\n            adapter_response={},\n            failures=None,\n        )\n\n    def from_run_result(self, result, start_time, timing_info):\n        result.execution_time = time.time() - start_time\n        result.timing.extend(timing_info)\n        return result\n\n    def execute(self, compiled_node, manifest):\n        relation = self.adapter.Relation.create_from(self.config, compiled_node)\n        # given a Source, calculate its freshness.\n        with self.adapter.connection_named(compiled_node.unique_id, compiled_node):\n            self.adapter.clear_transaction()\n            adapter_response: Optional[AdapterResponse] = None\n            freshness: Optional[FreshnessResponse] = None\n\n            if compiled_node.loaded_at_query is not None:\n                # within the context user can have access to `this`, `source_node`(`model` will point to the same thing),  etc\n                compiled_code = jinja.get_rendered(\n                    compiled_node.loaded_at_query,\n                    SourceContext(\n                        compiled_node, self.config, manifest, RuntimeProvider(), None\n                    ).to_dict(),\n                    compiled_node,\n                )\n                adapter_response, freshness = self.adapter.calculate_freshness_from_custom_sql(\n                    relation,\n                    compiled_code,\n                    macro_resolver=manifest,\n                )\n                status = compiled_node.freshness.status(freshness[\"age\"])\n            elif compiled_node.loaded_at_field is not None:\n                adapter_response, freshness = self.adapter.calculate_freshness(\n                    relation,\n                    compiled_node.loaded_at_field,\n                    compiled_node.freshness.filter,\n                    macro_resolver=manifest,\n                )\n\n                status = compiled_node.freshness.status(freshness[\"age\"])\n            elif self.adapter.supports(Capability.TableLastModifiedMetadata):\n                if compiled_node.freshness.filter is not None:\n                    fire_event(\n                        Note(\n                            msg=f\"A filter cannot be applied to a metadata freshness check on source '{compiled_node.name}'.\"\n                        ),\n                        EventLevel.WARN,\n                    )\n\n                metadata_source = self.adapter.Relation.create_from(self.config, compiled_node)\n                if metadata_source in self._metadata_freshness_cache:\n                    freshness = self._metadata_freshness_cache[metadata_source]\n                else:\n                    adapter_response, freshness = self.adapter.calculate_freshness_from_metadata(\n                        relation,\n                        macro_resolver=manifest,\n                    )\n\n                status = compiled_node.freshness.status(freshness[\"age\"])\n            else:\n                raise DbtRuntimeError(\n                    f\"Could not compute freshness for source {compiled_node.name}: no 'loaded_at_field' provided and {self.adapter.type()} adapter does not support metadata-based freshness checks.\"\n                )\n        # adapter_response was not returned in previous versions, so this will be None\n        # we cannot call to_dict() on NoneType\n        if adapter_response:\n            adapter_response = adapter_response.to_dict(omit_none=True)\n\n        return SourceFreshnessResult(\n            node=compiled_node,\n            status=status,\n            thread_id=threading.current_thread().name,\n            timing=[],\n            execution_time=0,\n            message=None,\n            adapter_response=adapter_response or {},\n            failures=None,\n            **freshness,\n        )\n\n    def compile(self, manifest: Manifest):\n        if self.node.resource_type != NodeType.Source:\n            # should be unreachable...\n            raise DbtRuntimeError(\"freshness runner: got a non-Source\")\n        # we don't do anything interesting when we compile a source node\n        return self.node\n\n\nclass FreshnessSelector(ResourceTypeSelector):\n    def node_is_match(self, node):\n        if not super().node_is_match(node):\n            return False\n        if not isinstance(node, SourceDefinition):\n            return False\n        return node.has_freshness\n\n\nclass FreshnessTask(RunTask):\n    def __init__(self, args, config, manifest) -> None:\n        super().__init__(args, config, manifest)\n\n        if self.args.output:\n            deprecations.warn(\n                \"custom-output-path-in-source-freshness-deprecation\", path=str(self.args.output)\n            )\n\n        self._metadata_freshness_cache: Dict[BaseRelation, FreshnessResult] = {}\n\n    def result_path(self) -> str:\n        if self.args.output:\n            return os.path.realpath(self.args.output)\n        else:\n            return os.path.join(self.config.project_target_path, SOURCE_RESULT_FILE_NAME)\n\n    def raise_on_first_error(self) -> bool:\n        return False\n\n    def get_node_selector(self):\n        if self.manifest is None or self.graph is None:\n            raise DbtInternalError(\"manifest and graph must be set to get perform node selection\")\n        return FreshnessSelector(\n            graph=self.graph,\n            manifest=self.manifest,\n            previous_state=self.previous_state,\n            resource_types=[NodeType.Source],\n        )\n\n    def before_run(self, adapter: BaseAdapter, selected_uids: AbstractSet[str]) -> RunStatus:\n        populate_metadata_freshness_cache_status = RunStatus.Success\n\n        before_run_status = super().before_run(adapter, selected_uids)\n\n        if before_run_status == RunStatus.Success and adapter.supports(\n            Capability.TableLastModifiedMetadataBatch\n        ):\n            populate_metadata_freshness_cache_status = self.populate_metadata_freshness_cache(\n                adapter, selected_uids\n            )\n\n        if (\n            before_run_status == RunStatus.Success\n            and populate_metadata_freshness_cache_status == RunStatus.Success\n        ):\n            return RunStatus.Success\n        else:\n            return RunStatus.Error\n\n    def get_runner(self, node) -> BaseRunner:\n        freshness_runner = super().get_runner(node)\n        assert isinstance(freshness_runner, FreshnessRunner)\n        freshness_runner.set_metadata_freshness_cache(self._metadata_freshness_cache)\n        return freshness_runner\n\n    def get_runner_type(self, _) -> Optional[Type[BaseRunner]]:\n        return FreshnessRunner\n\n    def get_result(self, results, elapsed_time, generated_at):\n        return FreshnessResult.from_node_results(\n            elapsed_time=elapsed_time, generated_at=generated_at, results=results\n        )\n\n    def task_end_messages(self, results) -> None:\n        for result in results:\n            if result.status in (\n                FreshnessStatus.Error,\n                FreshnessStatus.RuntimeErr,\n                RunStatus.Error,\n            ):\n                print_run_result_error(result)\n\n        fire_event(FreshnessCheckComplete())\n\n    def get_hooks_by_type(self, hook_type: RunHookType) -> List[HookNode]:\n        hooks = super().get_hooks_by_type(hook_type)\n        if self.args.source_freshness_run_project_hooks:\n            return hooks\n        else:\n            if hooks:\n                deprecations.warn(\"source-freshness-project-hooks\")\n            return []\n\n    def populate_metadata_freshness_cache(\n        self, adapter, selected_uids: AbstractSet[str]\n    ) -> RunStatus:\n        if self.manifest is None:\n            raise DbtInternalError(\"Manifest must be set to populate metadata freshness cache\")\n\n        batch_metadata_sources: List[BaseRelation] = []\n        for selected_source_uid in list(selected_uids):\n            source = self.manifest.sources.get(selected_source_uid)\n            if source and source.loaded_at_field is None:\n                metadata_source = adapter.Relation.create_from(self.config, source)\n                batch_metadata_sources.append(metadata_source)\n\n        fire_event(\n            Note(\n                msg=f\"Pulling freshness from warehouse metadata tables for {len(batch_metadata_sources)} sources\"\n            ),\n            EventLevel.INFO,\n        )\n\n        try:\n            _, metadata_freshness_results = adapter.calculate_freshness_from_metadata_batch(\n                batch_metadata_sources\n            )\n            self._metadata_freshness_cache.update(metadata_freshness_results)\n            return RunStatus.Success\n        except Exception as e:\n            # This error handling is intentionally very coarse.\n            # If anything goes wrong during batch metadata calculation, we can safely\n            # leave _metadata_freshness_cache unpopulated.\n            # Downstream, this will be gracefully handled as a cache miss and non-batch\n            # metadata-based freshness will still be performed on a source-by-source basis.\n            fire_event(\n                Note(msg=f\"Metadata freshness could not be computed in batch: {e}\"),\n                EventLevel.WARN,\n            )\n            return RunStatus.Error\n\n    def get_freshness_metadata_cache(self) -> Dict[BaseRelation, FreshnessResult]:\n        return self._metadata_freshness_cache\n"
  },
  {
    "path": "core/dbt/task/function.py",
    "content": "import threading\nfrom typing import Any, Dict\n\nfrom dbt.adapters.exceptions import MissingMaterializationError\nfrom dbt.artifacts.schemas.results import NodeStatus, RunStatus\nfrom dbt.artifacts.schemas.run import RunResult\nfrom dbt.clients.jinja import MacroGenerator\nfrom dbt.context.providers import generate_runtime_function_context\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.contracts.graph.nodes import FunctionNode\nfrom dbt.events.types import LogFunctionResult, LogStartLine\nfrom dbt.task import group_lookup\nfrom dbt.task.compile import CompileRunner\nfrom dbt_common.clients.jinja import MacroProtocol\nfrom dbt_common.events.base_types import EventLevel\nfrom dbt_common.events.functions import fire_event\nfrom dbt_common.exceptions import DbtValidationError\n\n\nclass FunctionRunner(CompileRunner):\n\n    def __init__(self, config, adapter, node, node_index: int, num_nodes: int) -> None:\n        super().__init__(config, adapter, node, node_index, num_nodes)\n\n        # doing this gives us type hints for the node :D\n        assert isinstance(node, FunctionNode)\n        self.node = node\n\n    def describe_node(self) -> str:\n        return f\"function {self.get_node_representation()}\"\n\n    def before_execute(self) -> None:\n        fire_event(\n            LogStartLine(\n                description=self.describe_node(),\n                index=self.node_index,\n                total=self.num_nodes,\n                node_info=self.node.node_info,\n            )\n        )\n\n    def _get_materialization_macro(\n        self, compiled_node: FunctionNode, manifest: Manifest\n    ) -> MacroProtocol:\n        materialization_macro = manifest.find_materialization_macro_by_name(\n            self.config.project_name, compiled_node.get_materialization(), self.adapter.type()\n        )\n        if materialization_macro is None:\n            raise MissingMaterializationError(\n                materialization=compiled_node.get_materialization(),\n                adapter_type=self.adapter.type(),\n            )\n\n        return materialization_macro\n\n    def _check_lang_supported(\n        self, compiled_node: FunctionNode, materialization_macro: MacroProtocol\n    ) -> None:\n        # TODO: This function and its typing is a bit wonky, we should fix it\n        # Specifically, a MacroProtocol doesn't have a supported_languags attribute, but a macro does. We're acting\n        # like the materialization_macro might not have a supported_languages attribute, but we access it in an unguarded manner.\n        # So are we guaranteed to always have a Macro here? (because a Macro always has a supported_languages attribute)\n        # This logic is a copy of of the logic in the run.py file, so the same logical conundrum applies there. Also perhaps\n        # we can refactor to having one definition, and maybe a logically consistent one...\n        mat_has_supported_langs = hasattr(materialization_macro, \"supported_languages\")\n        function_lang_supported = compiled_node.language in materialization_macro.supported_languages  # type: ignore\n        if mat_has_supported_langs and not function_lang_supported:\n            str_langs = [str(lang) for lang in materialization_macro.supported_languages]  # type: ignore\n            raise DbtValidationError(\n                f'Materialization \"{materialization_macro.name}\" only supports languages {str_langs}; '\n                f'got \"{compiled_node.language}\"'\n            )\n\n    def build_result(self, compiled_node: FunctionNode, context: Dict[str, Any]) -> RunResult:\n        loaded_result = context[\"load_result\"](\"main\")\n\n        return RunResult(\n            node=compiled_node,\n            status=RunStatus.Success,\n            timing=[],\n            thread_id=threading.current_thread().name,\n            # This gets set later in `from_run_result` called by `BaseRunner.safe_run`\n            execution_time=0.0,\n            message=str(loaded_result.response),\n            adapter_response=loaded_result.response.to_dict(omit_none=True),\n            failures=loaded_result.get(\"failures\"),\n            batch_results=None,\n        )\n\n    def execute(self, compiled_node: FunctionNode, manifest: Manifest) -> RunResult:\n        materialization_macro = self._get_materialization_macro(compiled_node, manifest)\n        self._check_lang_supported(compiled_node, materialization_macro)\n        context = generate_runtime_function_context(compiled_node, self.config, manifest)\n\n        MacroGenerator(materialization_macro, context=context)()\n\n        return self.build_result(compiled_node, context)\n\n    def after_execute(self, result: RunResult) -> None:\n        self.print_result_line(result)\n\n    # def compile() defined on CompileRunner\n\n    def print_result_line(self, result: RunResult) -> None:\n        node = result.node\n        assert isinstance(node, FunctionNode)\n\n        group = group_lookup.get(node.unique_id)\n        level = EventLevel.ERROR if result.status == NodeStatus.Error else EventLevel.INFO\n        fire_event(\n            LogFunctionResult(\n                description=self.describe_node(),\n                status=result.status,\n                index=self.node_index,\n                total=self.num_nodes,\n                execution_time=result.execution_time,\n                node_info=self.node.node_info,\n                group=group,\n            ),\n            level=level,\n        )\n"
  },
  {
    "path": "core/dbt/task/group_lookup.py",
    "content": "from typing import AbstractSet, Dict, Optional, Union\n\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.contracts.graph.nodes import Group\n\n_node_id_to_group_name_map: Dict[str, str] = {}\n_group_name_to_group_map: Dict[str, Group] = {}\n\n\ndef init(manifest: Optional[Manifest], selected_ids: AbstractSet[str]) -> None:\n    if not manifest:\n        return\n\n    if not manifest.groups:\n        return\n\n    if not hasattr(manifest, \"group_map\"):\n        manifest.build_group_map()\n\n    _every_group_name_to_group_map = {v.name: v for v in manifest.groups.values()}\n\n    for group_name, node_ids in manifest.group_map.items():\n        for node_id in node_ids:\n            # only add node to lookup if it's selected\n            if node_id in selected_ids:\n                _node_id_to_group_name_map[node_id] = group_name\n\n                # only add group to lookup if it's not already there and if node is selected\n                if group_name not in _group_name_to_group_map:\n                    _group_name_to_group_map[group_name] = _every_group_name_to_group_map[\n                        group_name\n                    ]\n\n\ndef get(node_id: str) -> Optional[Dict[str, Union[str, Dict[str, str]]]]:\n    group_name = _node_id_to_group_name_map.get(node_id)\n\n    if group_name is None:\n        return None\n\n    group = _group_name_to_group_map.get(group_name)\n\n    if group is None:\n        return None\n\n    return group.to_logging_dict()\n"
  },
  {
    "path": "core/dbt/task/init.py",
    "content": "import copy\nimport os\nimport re\nimport shutil\nfrom pathlib import Path\nfrom typing import Optional\n\nimport click\nimport yaml\n\nimport dbt.config\nimport dbt_common.clients.system\nfrom dbt.adapters.factory import get_include_paths, load_plugin\nfrom dbt.config.profile import read_profile\nfrom dbt.contracts.util import Identifier as ProjectName\nfrom dbt.events.types import (\n    ConfigFolderDirectory,\n    InvalidProfileTemplateYAML,\n    NoSampleProfileFound,\n    ProfileWrittenWithProjectTemplateYAML,\n    ProfileWrittenWithSample,\n    ProfileWrittenWithTargetTemplateYAML,\n    ProjectCreated,\n    ProjectNameAlreadyExists,\n    SettingUpProfile,\n    StarterProjectPath,\n)\nfrom dbt.flags import get_flags\nfrom dbt.task.base import BaseTask, move_to_nearest_project_dir\nfrom dbt.version import _get_adapter_plugin_names\nfrom dbt_common.events.functions import fire_event\nfrom dbt_common.events.types import Note\nfrom dbt_common.exceptions import DbtRuntimeError\nfrom dbt_common.ui import red\n\nDOCS_URL = \"https://docs.getdbt.com/docs/configure-your-profile\"\nSLACK_URL = \"https://community.getdbt.com/\"\n\n# This file is not needed for the starter project but exists for finding the resource path\nIGNORE_FILES = [\"__init__.py\", \"__pycache__\"]\n\n\n# https://click.palletsprojects.com/en/8.0.x/api/#types\n# click v7.0 has UNPROCESSED, STRING, INT, FLOAT, BOOL, and UUID available.\nclick_type_mapping = {\n    \"string\": click.STRING,\n    \"int\": click.INT,\n    \"float\": click.FLOAT,\n    \"bool\": click.BOOL,\n    None: None,\n}\n\n\nclass InitTask(BaseTask):\n    def copy_starter_repo(self, project_name: str) -> None:\n        # Lazy import to avoid ModuleNotFoundError\n        from dbt.include.starter_project import (\n            PACKAGE_PATH as starter_project_directory,\n        )\n\n        fire_event(StarterProjectPath(dir=starter_project_directory))\n        shutil.copytree(\n            starter_project_directory, project_name, ignore=shutil.ignore_patterns(*IGNORE_FILES)\n        )\n\n    def create_profiles_dir(self, profiles_dir: str) -> bool:\n        \"\"\"Create the user's profiles directory if it doesn't already exist.\"\"\"\n        profiles_path = Path(profiles_dir)\n        if not profiles_path.exists():\n            fire_event(ConfigFolderDirectory(dir=str(profiles_dir)))\n            dbt_common.clients.system.make_directory(profiles_dir)\n            return True\n        return False\n\n    def create_profile_from_sample(self, adapter: str, profile_name: str):\n        \"\"\"Create a profile entry using the adapter's sample_profiles.yml\n\n        Renames the profile in sample_profiles.yml to match that of the project.\"\"\"\n        # Line below raises an exception if the specified adapter is not found\n        load_plugin(adapter)\n        adapter_path = get_include_paths(adapter)[0]\n        sample_profiles_path = adapter_path / \"sample_profiles.yml\"\n\n        if not sample_profiles_path.exists():\n            fire_event(NoSampleProfileFound(adapter=adapter))\n        else:\n            with open(sample_profiles_path, \"r\") as f:\n                sample_profile = f.read()\n            sample_profile_name = list(yaml.safe_load(sample_profile).keys())[0]\n            # Use a regex to replace the name of the sample_profile with\n            # that of the project without losing any comments from the sample\n            sample_profile = re.sub(f\"^{sample_profile_name}:\", f\"{profile_name}:\", sample_profile)\n            profiles_filepath = Path(get_flags().PROFILES_DIR) / Path(\"profiles.yml\")\n            if profiles_filepath.exists():\n                with open(profiles_filepath, \"a\") as f:\n                    f.write(\"\\n\" + sample_profile)\n            else:\n                with open(profiles_filepath, \"w\") as f:\n                    f.write(sample_profile)\n                fire_event(\n                    ProfileWrittenWithSample(name=profile_name, path=str(profiles_filepath))\n                )\n\n    def generate_target_from_input(self, profile_template: dict, target: dict = {}) -> dict:\n        \"\"\"Generate a target configuration from profile_template and user input.\"\"\"\n        profile_template_local = copy.deepcopy(profile_template)\n        for key, value in profile_template_local.items():\n            if key.startswith(\"_choose\"):\n                choice_type = key[8:].replace(\"_\", \" \")\n                option_list = list(value.keys())\n                prompt_msg = (\n                    \"\\n\".join([f\"[{n+1}] {v}\" for n, v in enumerate(option_list)])\n                    + f\"\\nDesired {choice_type} option (enter a number)\"\n                )\n                numeric_choice = click.prompt(prompt_msg, type=click.INT)\n                choice = option_list[numeric_choice - 1]\n                # Complete the chosen option's values in a recursive call\n                target = self.generate_target_from_input(\n                    profile_template_local[key][choice], target\n                )\n            else:\n                if key.startswith(\"_fixed\"):\n                    # _fixed prefixed keys are not presented to the user\n                    target[key[7:]] = value\n                else:\n                    hide_input = value.get(\"hide_input\", False)\n                    default = value.get(\"default\", None)\n                    hint = value.get(\"hint\", None)\n                    type = click_type_mapping[value.get(\"type\", None)]\n                    text = key + (f\" ({hint})\" if hint else \"\")\n                    target[key] = click.prompt(\n                        text, default=default, hide_input=hide_input, type=type\n                    )\n        return target\n\n    def get_profile_name_from_current_project(self) -> str:\n        \"\"\"Reads dbt_project.yml in the current directory to retrieve the\n        profile name.\n        \"\"\"\n        with open(\"dbt_project.yml\") as f:\n            dbt_project = yaml.safe_load(f)\n        return dbt_project[\"profile\"]\n\n    def write_profile(self, profile: dict, profile_name: str):\n        \"\"\"Given a profile, write it to the current project's profiles.yml.\n        This will overwrite any profile with a matching name.\"\"\"\n        # Create the profile directory if it doesn't exist\n        profiles_filepath = Path(get_flags().PROFILES_DIR) / Path(\"profiles.yml\")\n\n        profiles = {profile_name: profile}\n\n        if profiles_filepath.exists():\n            with open(profiles_filepath, \"r\") as f:\n                profiles = yaml.safe_load(f) or {}\n                profiles[profile_name] = profile\n\n        # Write the profiles dictionary to a brand-new or pre-existing file\n        with open(profiles_filepath, \"w\") as f:\n            yaml.dump(profiles, f)\n\n    def create_profile_from_profile_template(self, profile_template: dict, profile_name: str):\n        \"\"\"Create and write a profile using the supplied profile_template.\"\"\"\n        initial_target = profile_template.get(\"fixed\", {})\n        prompts = profile_template.get(\"prompts\", {})\n        target = self.generate_target_from_input(prompts, initial_target)\n        target_name = target.pop(\"target\", \"dev\")\n        profile = {\"outputs\": {target_name: target}, \"target\": target_name}\n        self.write_profile(profile, profile_name)\n\n    def create_profile_from_target(self, adapter: str, profile_name: str):\n        \"\"\"Create a profile without defaults using target's profile_template.yml if available, or\n        sample_profiles.yml as a fallback.\"\"\"\n        # Line below raises an exception if the specified adapter is not found\n        load_plugin(adapter)\n        adapter_path = get_include_paths(adapter)[0]\n        profile_template_path = adapter_path / \"profile_template.yml\"\n\n        if profile_template_path.exists():\n            with open(profile_template_path) as f:\n                profile_template = yaml.safe_load(f)\n            self.create_profile_from_profile_template(profile_template, profile_name)\n            profiles_filepath = Path(get_flags().PROFILES_DIR) / Path(\"profiles.yml\")\n            fire_event(\n                ProfileWrittenWithTargetTemplateYAML(\n                    name=profile_name, path=str(profiles_filepath)\n                )\n            )\n        else:\n            # For adapters without a profile_template.yml defined, fallback on\n            # sample_profiles.yml\n            self.create_profile_from_sample(adapter, profile_name)\n\n    def check_if_profile_exists(self, profile_name: str) -> bool:\n        \"\"\"\n        Validate that the specified profile exists. Can't use the regular profile validation\n        routine because it assumes the project file exists\n        \"\"\"\n        profiles_dir = get_flags().PROFILES_DIR\n        raw_profiles = read_profile(profiles_dir)\n        return profile_name in raw_profiles\n\n    def check_if_can_write_profile(self, profile_name: Optional[str] = None) -> bool:\n        \"\"\"Using either a provided profile name or that specified in dbt_project.yml,\n        check if the profile already exists in profiles.yml, and if so ask the\n        user whether to proceed and overwrite it.\"\"\"\n        profiles_file = Path(get_flags().PROFILES_DIR) / Path(\"profiles.yml\")\n        if not profiles_file.exists():\n            return True\n        profile_name = profile_name or self.get_profile_name_from_current_project()\n        with open(profiles_file, \"r\") as f:\n            profiles = yaml.safe_load(f) or {}\n        if profile_name in profiles.keys():\n            response = click.confirm(\n                f\"The profile {profile_name} already exists in \"\n                f\"{profiles_file}. Continue and overwrite it?\"\n            )\n            return response\n        else:\n            return True\n\n    def create_profile_using_project_profile_template(self, profile_name):\n        \"\"\"Create a profile using the project's profile_template.yml\"\"\"\n        with open(\"profile_template.yml\") as f:\n            profile_template = yaml.safe_load(f)\n        self.create_profile_from_profile_template(profile_template, profile_name)\n        profiles_filepath = Path(get_flags().PROFILES_DIR) / Path(\"profiles.yml\")\n        fire_event(\n            ProfileWrittenWithProjectTemplateYAML(name=profile_name, path=str(profiles_filepath))\n        )\n\n    def ask_for_adapter_choice(self) -> str:\n        \"\"\"Ask the user which adapter (database) they'd like to use.\"\"\"\n        available_adapters = list(_get_adapter_plugin_names())\n\n        if not available_adapters:\n            raise dbt.exceptions.NoAdaptersAvailableError()\n\n        prompt_msg = (\n            \"Which database would you like to use?\\n\"\n            + \"\\n\".join([f\"[{n+1}] {v}\" for n, v in enumerate(available_adapters)])\n            + \"\\n\\n(Don't see the one you want? https://docs.getdbt.com/docs/available-adapters)\"\n            + \"\\n\\nEnter a number\"\n        )\n        numeric_choice = click.prompt(prompt_msg, type=click.INT)\n        return available_adapters[numeric_choice - 1]\n\n    def setup_profile(self, profile_name: str) -> None:\n        \"\"\"Set up a new profile for a project\"\"\"\n        fire_event(SettingUpProfile())\n        if not self.check_if_can_write_profile(profile_name=profile_name):\n            return\n        # If a profile_template.yml exists in the project root, that effectively\n        # overrides the profile_template.yml for the given target.\n        profile_template_path = Path(\"profile_template.yml\")\n        if profile_template_path.exists():\n            try:\n                # This relies on a valid profile_template.yml from the user,\n                # so use a try: except to fall back to the default on failure\n                self.create_profile_using_project_profile_template(profile_name)\n                return\n            except Exception:\n                fire_event(InvalidProfileTemplateYAML())\n        adapter = self.ask_for_adapter_choice()\n        self.create_profile_from_target(adapter, profile_name=profile_name)\n\n    def get_valid_project_name(self) -> str:\n        \"\"\"Returns a valid project name, either from CLI arg or user prompt.\"\"\"\n\n        # Lazy import to avoid ModuleNotFoundError\n        from dbt.include.global_project import PROJECT_NAME as GLOBAL_PROJECT_NAME\n\n        name = self.args.project_name\n        internal_package_names = {GLOBAL_PROJECT_NAME}\n        available_adapters = list(_get_adapter_plugin_names())\n        for adapter_name in available_adapters:\n            internal_package_names.update(f\"dbt_{adapter_name}\")\n        while not ProjectName.is_valid(name) or name in internal_package_names:\n            if name:\n                click.echo(name + \" is not a valid project name.\")\n            name = click.prompt(\"Enter a name for your project (letters, digits, underscore)\")\n\n        return name\n\n    def _run_debug(self) -> Optional[bool]:\n        if self.args.skip_debug:\n            return None\n\n        from dbt.task.debug import DebugTask\n\n        fire_event(Note(msg=\"Running dbt debug to validate the project...\"))\n\n        try:\n            debug_task = DebugTask(self.args)\n            debug_task.project_dir = Path.cwd()\n            debug_task.project_path = os.path.join(Path.cwd(), \"dbt_project.yml\")\n            return debug_task.run()\n        except Exception:\n            fire_event(Note(msg=\"Debug validation encountered an error\"))\n            return False\n\n    def create_new_project(self, project_name: str, profile_name: str):\n        self.copy_starter_repo(project_name)\n        os.chdir(project_name)\n        with open(\"dbt_project.yml\", \"r\") as f:\n            content = f\"{f.read()}\".format(project_name=project_name, profile_name=profile_name)\n        with open(\"dbt_project.yml\", \"w\") as f:\n            f.write(content)\n\n    def run(self):\n        \"\"\"Entry point for the init task.\"\"\"\n        profiles_dir = get_flags().PROFILES_DIR\n        self.create_profiles_dir(profiles_dir)\n\n        try:\n            move_to_nearest_project_dir(self.args.project_dir)\n            in_project = True\n        except dbt_common.exceptions.DbtRuntimeError:\n            in_project = False\n\n        if in_project:\n            # If --profile was specified, it means use an existing profile, which is not\n            # applicable to this case\n            if self.args.profile:\n                raise DbtRuntimeError(\n                    msg=\"Can not init existing project with specified profile, edit dbt_project.yml instead\"\n                )\n\n            # When dbt init is run inside an existing project,\n            # just setup the user's profile.\n            if not self.args.skip_profile_setup:\n                profile_name = self.get_profile_name_from_current_project()\n                self.setup_profile(profile_name)\n                self._run_debug()\n        else:\n            # When dbt init is run outside of an existing project,\n            # create a new project and set up the user's profile.\n            project_name = self.get_valid_project_name()\n            project_path = Path(project_name)\n            if project_path.exists():\n                fire_event(ProjectNameAlreadyExists(name=project_name))\n                return\n\n            # If the user specified an existing profile to use, use it instead of generating a new one\n            user_profile_name = self.args.profile\n            if user_profile_name:\n                if not self.check_if_profile_exists(user_profile_name):\n                    raise DbtRuntimeError(\n                        msg=\"Could not find profile named '{}'\".format(user_profile_name)\n                    )\n                self.create_new_project(project_name, user_profile_name)\n                debug_success = self._run_debug()\n            else:\n                profile_name = project_name\n                # Create the profile after creating the project to avoid leaving a random profile\n                # if the former fails.\n                self.create_new_project(project_name, profile_name)\n\n                # Ask for adapter only if skip_profile_setup flag is not provided\n                if not self.args.skip_profile_setup:\n                    self.setup_profile(profile_name)\n                    debug_success = self._run_debug()\n                else:\n                    debug_success = None\n\n            fire_event(\n                ProjectCreated(\n                    project_name=project_name,\n                    docs_url=DOCS_URL,\n                    slack_url=SLACK_URL,\n                )\n            )\n            if debug_success is False:\n                fire_event(\n                    Note(\n                        msg=red(\n                            \"Your profile may need adjustments. You can find the logs of `dbt debug` above\"\n                        )\n                    )\n                )\n"
  },
  {
    "path": "core/dbt/task/list.py",
    "content": "import json\nfrom typing import Iterator, List\n\nfrom dbt.cli.flags import Flags\nfrom dbt.config.runtime import RuntimeConfig\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.contracts.graph.nodes import (\n    Exposure,\n    Metric,\n    SavedQuery,\n    SemanticModel,\n    SourceDefinition,\n    UnitTestDefinition,\n)\nfrom dbt.events.types import NoNodesSelected\nfrom dbt.graph import ResourceTypeSelector\nfrom dbt.node_types import NodeType\nfrom dbt.task.base import resource_types_from_args\nfrom dbt.task.runnable import GraphRunnableTask\nfrom dbt.utils import JSONEncoder\nfrom dbt_common.events.contextvars import task_contextvars\nfrom dbt_common.events.functions import fire_event, warn_or_error\nfrom dbt_common.events.types import PrintEvent\nfrom dbt_common.exceptions import DbtInternalError, DbtRuntimeError\n\n\nclass ListTask(GraphRunnableTask):\n    DEFAULT_RESOURCE_VALUES = frozenset(\n        (\n            NodeType.Model,\n            NodeType.Snapshot,\n            NodeType.Seed,\n            NodeType.Test,\n            NodeType.Source,\n            NodeType.Exposure,\n            NodeType.Metric,\n            NodeType.SavedQuery,\n            NodeType.SemanticModel,\n            NodeType.Unit,\n            NodeType.Function,\n        )\n    )\n    ALL_RESOURCE_VALUES = DEFAULT_RESOURCE_VALUES | frozenset((NodeType.Analysis,))\n    ALLOWED_KEYS = frozenset(\n        (\n            \"alias\",\n            \"name\",\n            \"package_name\",\n            \"depends_on\",\n            \"tags\",\n            \"config\",\n            \"resource_type\",\n            \"source_name\",\n            \"original_file_path\",\n            \"unique_id\",\n        )\n    )\n\n    def __init__(self, args: Flags, config: RuntimeConfig, manifest: Manifest) -> None:\n        super().__init__(args, config, manifest)\n        if self.args.models:\n            if self.args.select:\n                raise DbtRuntimeError('\"models\" and \"select\" are mutually exclusive arguments')\n            if self.args.resource_types:\n                raise DbtRuntimeError(\n                    '\"models\" and \"resource_type\" are mutually exclusive ' \"arguments\"\n                )\n\n    def _iterate_selected_nodes(self):\n        selector = self.get_node_selector()\n        spec = self.get_selection_spec()\n        unique_ids = sorted(selector.get_selected(spec))\n        if not unique_ids:\n            warn_or_error(NoNodesSelected())\n            return\n        if self.manifest is None:\n            raise DbtInternalError(\"manifest is None in _iterate_selected_nodes\")\n        for unique_id in unique_ids:\n            if unique_id in self.manifest.nodes:\n                yield self.manifest.nodes[unique_id]\n            elif unique_id in self.manifest.sources:\n                yield self.manifest.sources[unique_id]\n            elif unique_id in self.manifest.exposures:\n                yield self.manifest.exposures[unique_id]\n            elif unique_id in self.manifest.metrics:\n                yield self.manifest.metrics[unique_id]\n            elif unique_id in self.manifest.semantic_models:\n                yield self.manifest.semantic_models[unique_id]\n            elif unique_id in self.manifest.unit_tests:\n                yield self.manifest.unit_tests[unique_id]\n            elif unique_id in self.manifest.saved_queries:\n                yield self.manifest.saved_queries[unique_id]\n            elif unique_id in self.manifest.functions:\n                yield self.manifest.functions[unique_id]\n            else:\n                raise DbtRuntimeError(\n                    f'Got an unexpected result from node selection: \"{unique_id}\"'\n                    f\"Listing this node type is not yet supported!\"\n                )\n\n    def generate_selectors(self):\n        for node in self._iterate_selected_nodes():\n            if node.resource_type == NodeType.Source:\n                assert isinstance(node, SourceDefinition)\n                # sources are searched for by pkg.source_name.table_name\n                source_selector = \".\".join([node.package_name, node.source_name, node.name])\n                yield f\"source:{source_selector}\"\n            elif node.resource_type == NodeType.Exposure:\n                assert isinstance(node, Exposure)\n                # exposures are searched for by pkg.exposure_name\n                exposure_selector = \".\".join([node.package_name, node.name])\n                yield f\"exposure:{exposure_selector}\"\n            elif node.resource_type == NodeType.Metric:\n                assert isinstance(node, Metric)\n                # metrics are searched for by pkg.metric_name\n                metric_selector = \".\".join([node.package_name, node.name])\n                yield f\"metric:{metric_selector}\"\n            elif node.resource_type == NodeType.SavedQuery:\n                assert isinstance(node, SavedQuery)\n                saved_query_selector = \".\".join([node.package_name, node.name])\n                yield f\"saved_query:{saved_query_selector}\"\n            elif node.resource_type == NodeType.SemanticModel:\n                assert isinstance(node, SemanticModel)\n                semantic_model_selector = \".\".join([node.package_name, node.name])\n                yield f\"semantic_model:{semantic_model_selector}\"\n            elif node.resource_type == NodeType.Unit:\n                assert isinstance(node, UnitTestDefinition)\n                unit_test_selector = \".\".join([node.package_name, node.versioned_name])\n                yield f\"unit_test:{unit_test_selector}\"\n            else:\n                # everything else is from `fqn`\n                yield \".\".join(node.fqn)\n\n    def generate_names(self):\n        for node in self._iterate_selected_nodes():\n            yield node.search_name\n\n    def _get_nested_value(self, data, key_path):\n        \"\"\"Get nested value using dot notation (e.g., 'config.materialized')\"\"\"\n        keys = key_path.split(\".\")\n        current = data\n        for key in keys:\n            if isinstance(current, dict) and key in current:\n                current = current[key]\n            else:\n                return None\n        return current\n\n    def generate_json(self):\n        for node in self._iterate_selected_nodes():\n            node_dict = node.to_dict(omit_none=False)\n\n            if self.args.output_keys:\n                # Handle both nested and regular keys\n                result = {}\n                for key in self.args.output_keys:\n                    if \".\" in key:\n                        # Handle nested key (e.g., 'config.materialized')\n                        value = self._get_nested_value(node_dict, key)\n                        if value is not None:\n                            result[key] = value\n                    else:\n                        # Handle regular key\n                        if key in node_dict:\n                            result[key] = node_dict[key]\n            else:\n                # Use default allowed keys\n                result = {k: v for k, v in node_dict.items() if k in self.ALLOWED_KEYS}\n\n            yield json.dumps(result, cls=JSONEncoder)\n\n    def generate_paths(self) -> Iterator[str]:\n        for node in self._iterate_selected_nodes():\n            yield node.original_file_path\n\n    def run(self):\n        # We set up a context manager here with \"task_contextvars\" because we\n        # we need the project_root in compile_manifest.\n        with task_contextvars(project_root=self.config.project_root):\n            self.compile_manifest()\n            output = self.args.output\n            if output == \"selector\":\n                generator = self.generate_selectors\n            elif output == \"name\":\n                generator = self.generate_names\n            elif output == \"json\":\n                generator = self.generate_json\n            elif output == \"path\":\n                generator = self.generate_paths\n            else:\n                raise DbtInternalError(\"Invalid output {}\".format(output))\n\n            return self.output_results(generator())\n\n    def output_results(self, results):\n        \"\"\"Log, or output a plain, newline-delimited, and ready-to-pipe list of nodes found.\"\"\"\n        for result in results:\n            self.node_results.append(result)\n            # No formatting, still get to stdout when --quiet is used\n            fire_event(PrintEvent(msg=result))\n        return self.node_results\n\n    @property\n    def resource_types(self) -> List[NodeType]:\n        if self.args.models:\n            return [NodeType.Model]\n\n        resource_types = resource_types_from_args(\n            self.args, set(self.ALL_RESOURCE_VALUES), set(self.DEFAULT_RESOURCE_VALUES)\n        )\n\n        return list(resource_types)\n\n    @property\n    def selection_arg(self):\n        # for backwards compatibility, list accepts both --models and --select,\n        # with slightly different behavior: --models implies --resource-type model\n        if self.args.models:\n            return self.args.models\n        else:\n            return self.args.select\n\n    def get_node_selector(self) -> ResourceTypeSelector:\n        if self.manifest is None or self.graph is None:\n            raise DbtInternalError(\"manifest and graph must be set to get perform node selection\")\n        return ResourceTypeSelector(\n            graph=self.graph,\n            manifest=self.manifest,\n            previous_state=self.previous_state,\n            resource_types=self.resource_types,\n            include_empty_nodes=True,\n            selectors=self.config.selectors,\n        )\n\n    def interpret_results(self, results):\n        # list command should always return 0 as exit code\n        return True\n"
  },
  {
    "path": "core/dbt/task/printer.py",
    "content": "from typing import Dict, Optional, Union\n\nfrom dbt.artifacts.schemas.results import NodeStatus\nfrom dbt.contracts.graph.nodes import Exposure\nfrom dbt.events.types import (\n    CheckNodeTestFailure,\n    EndOfRunSummary,\n    RunResultError,\n    RunResultErrorNoMessage,\n    RunResultFailure,\n    RunResultWarning,\n    RunResultWarningMessage,\n    SQLCompiledPath,\n    StatsLine,\n)\nfrom dbt.node_types import NodeType\nfrom dbt.task import group_lookup\nfrom dbt_common.events.base_types import EventLevel\nfrom dbt_common.events.format import pluralize\nfrom dbt_common.events.functions import fire_event\nfrom dbt_common.events.types import Formatting\n\n\ndef get_counts(flat_nodes) -> str:\n    counts: Dict[str, int] = {}\n\n    for node in flat_nodes:\n        t = node.resource_type\n\n        if node.resource_type == NodeType.Model:\n            t = \"{} {}\".format(node.get_materialization(), t)\n        elif node.resource_type == NodeType.Operation:\n            t = \"project hook\"\n\n        counts[t] = counts.get(t, 0) + 1\n\n    sorted_items = sorted(counts.items(), key=lambda x: x[0])\n    stat_line = \", \".join([pluralize(v, k).replace(\"_\", \" \") for k, v in sorted_items])\n\n    return stat_line\n\n\ndef interpret_run_result(result) -> str:\n    if result.status in (NodeStatus.Error, NodeStatus.Fail, NodeStatus.PartialSuccess):\n        return \"error\"\n    elif result.status == NodeStatus.Skipped:\n        return \"skip\"\n    elif result.status == NodeStatus.Warn:\n        return \"warn\"\n    elif result.status in (NodeStatus.Pass, NodeStatus.Success):\n        return \"pass\"\n    elif result.status == NodeStatus.NoOp:\n        return \"noop\"\n    else:\n        raise RuntimeError(f\"unhandled result {result}\")\n\n\ndef print_run_status_line(results) -> None:\n    stats = {\n        \"error\": 0,\n        \"skip\": 0,\n        \"pass\": 0,\n        \"warn\": 0,\n        \"noop\": 0,\n        \"total\": 0,\n    }\n\n    for r in results:\n        result_type = interpret_run_result(r)\n        stats[result_type] += 1\n        stats[\"total\"] += 1\n\n    fire_event(Formatting(\"\"))\n    fire_event(StatsLine(stats=stats))\n\n\ndef print_run_result_error(\n    result,\n    newline: bool = True,\n    is_warning: bool = False,\n    group: Optional[Dict[str, Union[str, Dict[str, str]]]] = None,\n) -> None:\n    # set node_info for logging events\n    node_info = None\n    if hasattr(result, \"node\") and result.node:\n        node_info = result.node.node_info\n    if result.status in (NodeStatus.Fail, NodeStatus.Error) or (\n        is_warning and result.status == NodeStatus.Warn\n    ):\n        if newline:\n            fire_event(Formatting(\"\"))\n        if is_warning:\n            fire_event(\n                RunResultWarning(\n                    resource_type=result.node.resource_type,\n                    node_name=result.node.name,\n                    path=result.node.original_file_path,\n                    node_info=node_info,\n                    group=group,\n                )\n            )\n        else:\n            fire_event(\n                RunResultFailure(\n                    resource_type=result.node.resource_type,\n                    node_name=result.node.name,\n                    path=result.node.original_file_path,\n                    node_info=node_info,\n                    group=group,\n                )\n            )\n\n        if result.message:\n            if is_warning:\n                fire_event(RunResultWarningMessage(msg=result.message, node_info=node_info))\n            else:\n                fire_event(RunResultError(msg=result.message, node_info=node_info, group=group))\n        else:\n            fire_event(RunResultErrorNoMessage(status=result.status, node_info=node_info))\n\n        if getattr(result.node, \"compiled_path\", None):\n            fire_event(Formatting(\"\"))\n            fire_event(SQLCompiledPath(path=result.node.compiled_path, node_info=node_info))\n\n        if getattr(result.node, \"should_store_failures\", None):\n            fire_event(Formatting(\"\"))\n            fire_event(\n                CheckNodeTestFailure(relation_name=result.node.relation_name, node_info=node_info)\n            )\n    elif result.status == NodeStatus.Skipped and result.message is not None:\n        if newline:\n            fire_event(Formatting(\"\"), level=EventLevel.DEBUG)\n        fire_event(RunResultError(msg=result.message), level=EventLevel.DEBUG)\n    elif result.message is not None:\n        if newline:\n            fire_event(Formatting(\"\"))\n        fire_event(RunResultError(msg=result.message, node_info=node_info, group=group))\n\n\ndef print_run_end_messages(results, keyboard_interrupt: bool = False) -> None:\n    errors, warnings, partial_successes = [], [], []\n    for r in results:\n        if r.status in (NodeStatus.RuntimeErr, NodeStatus.Error, NodeStatus.Fail):\n            errors.append(r)\n        elif r.status == NodeStatus.Skipped and r.message:\n            if isinstance(r.node, Exposure):\n                # Don't include exposure skips in errors list\n                continue\n            else:\n                # This means we skipped a node because of an issue upstream, so include it as an error\n                errors.append(r)\n        elif r.status == NodeStatus.Warn:\n            warnings.append(r)\n        elif r.status == NodeStatus.PartialSuccess:\n            partial_successes.append(r)\n\n    fire_event(Formatting(\"\"))\n    fire_event(\n        EndOfRunSummary(\n            num_errors=len(errors),\n            num_warnings=len(warnings),\n            num_partial_success=len(partial_successes),\n            keyboard_interrupt=keyboard_interrupt,\n        )\n    )\n\n    for error in errors:\n        group = group_lookup.get(error.node.unique_id) if hasattr(error, \"node\") else None\n        print_run_result_error(error, is_warning=False, group=group)\n\n    for warning in warnings:\n        group = group_lookup.get(warning.node.unique_id) if hasattr(warning, \"node\") else None\n        print_run_result_error(warning, is_warning=True, group=group)\n\n    print_run_status_line(results)\n"
  },
  {
    "path": "core/dbt/task/retry.py",
    "content": "from pathlib import Path\n\nfrom click import get_current_context\nfrom click.core import ParameterSource\n\nfrom dbt.artifacts.schemas.results import NodeStatus\nfrom dbt.cli.flags import Flags\nfrom dbt.cli.types import Command as CliCommand\nfrom dbt.config import RuntimeConfig\nfrom dbt.constants import RUN_RESULTS_FILE_NAME\nfrom dbt.contracts.state import load_result_state\nfrom dbt.flags import get_flags, set_flags\nfrom dbt.graph import GraphQueue\nfrom dbt.parser.manifest import parse_manifest\nfrom dbt.task.base import ConfiguredTask\nfrom dbt.task.build import BuildTask\nfrom dbt.task.clone import CloneTask\nfrom dbt.task.compile import CompileTask\nfrom dbt.task.docs.generate import GenerateTask\nfrom dbt.task.run import RunTask\nfrom dbt.task.run_operation import RunOperationTask\nfrom dbt.task.seed import SeedTask\nfrom dbt.task.snapshot import SnapshotTask\nfrom dbt.task.test import TestTask\nfrom dbt_common.exceptions import DbtRuntimeError\n\nRETRYABLE_STATUSES = {\n    NodeStatus.Error,\n    NodeStatus.Fail,\n    NodeStatus.Skipped,\n    NodeStatus.RuntimeErr,\n    NodeStatus.PartialSuccess,\n}\nIGNORE_PARENT_FLAGS = {\n    \"log_path\",\n    \"output_path\",\n    \"profiles_dir\",\n    \"profiles_dir_exists_false\",\n    \"project_dir\",\n    \"defer_state\",\n    \"deprecated_state\",\n    \"target_path\",\n    \"warn_error\",\n}\n\nALLOW_CLI_OVERRIDE_FLAGS = {\"vars\", \"threads\"}\n\nTASK_DICT = {\n    \"build\": BuildTask,\n    \"compile\": CompileTask,\n    \"clone\": CloneTask,\n    \"generate\": GenerateTask,\n    \"seed\": SeedTask,\n    \"snapshot\": SnapshotTask,\n    \"test\": TestTask,\n    \"run\": RunTask,\n    \"run-operation\": RunOperationTask,\n}\n\nCMD_DICT = {\n    \"build\": CliCommand.BUILD,\n    \"compile\": CliCommand.COMPILE,\n    \"clone\": CliCommand.CLONE,\n    \"generate\": CliCommand.DOCS_GENERATE,\n    \"seed\": CliCommand.SEED,\n    \"snapshot\": CliCommand.SNAPSHOT,\n    \"test\": CliCommand.TEST,\n    \"run\": CliCommand.RUN,\n    \"run-operation\": CliCommand.RUN_OPERATION,\n}\n\n\nclass RetryTask(ConfiguredTask):\n    def __init__(self, args: Flags, config: RuntimeConfig) -> None:\n        # load previous run results\n        state_path = args.state or config.target_path\n        self.previous_results = load_result_state(\n            Path(config.project_root) / Path(state_path) / RUN_RESULTS_FILE_NAME\n        )\n        if not self.previous_results:\n            raise DbtRuntimeError(\n                f\"Could not find previous run in '{state_path}' target directory\"\n            )\n        self.previous_args = self.previous_results.args\n        self.previous_command_name = self.previous_args.get(\"which\")\n\n        # Reslove flags and config\n        if args.warn_error:\n            RETRYABLE_STATUSES.add(NodeStatus.Warn)\n\n        cli_command = CMD_DICT.get(self.previous_command_name)  # type: ignore\n        # Remove these args when their default values are present, otherwise they'll raise an exception\n        args_to_remove = {\n            \"show\": lambda x: True,\n            \"resource_types\": lambda x: x == [],\n            \"warn_error_options\": lambda x: x == {\"warn\": [], \"error\": [], \"silence\": []},\n        }\n        for k, v in args_to_remove.items():\n            if k in self.previous_args and v(self.previous_args[k]):\n                del self.previous_args[k]\n        previous_args = {\n            k: v for k, v in self.previous_args.items() if k not in IGNORE_PARENT_FLAGS\n        }\n        click_context = get_current_context()\n        current_args = {\n            k: v\n            for k, v in args.__dict__.items()\n            if k in IGNORE_PARENT_FLAGS\n            or (\n                click_context.get_parameter_source(k) == ParameterSource.COMMANDLINE\n                and k in ALLOW_CLI_OVERRIDE_FLAGS\n            )\n        }\n        combined_args = {**previous_args, **current_args}\n        retry_flags = Flags.from_dict(cli_command, combined_args)  # type: ignore\n        set_flags(retry_flags)\n        retry_config = RuntimeConfig.from_args(args=retry_flags)\n\n        # Parse manifest using resolved config/flags\n        manifest = parse_manifest(retry_config, False, True, retry_flags.write_json, [])  # type: ignore\n        super().__init__(args, retry_config, manifest)\n        self.task_class = TASK_DICT.get(self.previous_command_name)  # type: ignore\n\n    def run(self):\n        unique_ids = {\n            result.unique_id\n            for result in self.previous_results.results\n            if result.status in RETRYABLE_STATUSES\n            # Avoid retrying operation nodes unless we are retrying the run-operation command\n            and not (\n                self.previous_command_name != \"run-operation\"\n                and result.unique_id.startswith(\"operation.\")\n            )\n        }\n\n        # We need this so that re-running of a microbatch model will only rerun\n        # batches that previously failed. Note _explicitly_ do no pass the\n        # batch info if there were _no_ successful batches previously. This is\n        # because passing the batch info _forces_ the microbatch process into\n        # _incremental_ model, and it may be that we need to be in full refresh\n        # mode which is only handled if previous_batch_results _isn't_ passed for a node\n        batch_map = {\n            result.unique_id: result.batch_results\n            for result in self.previous_results.results\n            if result.batch_results is not None\n            and len(result.batch_results.successful) != 0\n            and len(result.batch_results.failed) > 0\n            and not (\n                self.previous_command_name != \"run-operation\"\n                and result.unique_id.startswith(\"operation.\")\n            )\n        }\n\n        # Tasks without get_graph_queue (e.g. run-operation) and no failed nodes to retry.\n        if not unique_ids and not hasattr(self.task_class, \"get_graph_queue\"):\n            # Return early with the previous results as the past invocation was successful\n            return self.previous_results\n\n        class TaskWrapper(self.task_class):\n            def get_graph_queue(self):\n                new_graph = self.graph.get_subset_graph(unique_ids)\n                return GraphQueue(\n                    new_graph.graph,\n                    self.manifest,\n                    unique_ids,\n                )\n\n        task = TaskWrapper(\n            get_flags(),\n            self.config,\n            self.manifest,\n        )\n\n        if self.task_class == RunTask or self.task_class == BuildTask:\n            task.batch_map = batch_map\n            task.original_invocation_started_at = (\n                self.previous_results.metadata.invocation_started_at\n                or self.previous_results.metadata.generated_at\n            )\n\n        return_value = task.run()\n        return return_value\n\n    def interpret_results(self, *args, **kwargs):\n        return self.task_class.interpret_results(*args, **kwargs)\n"
  },
  {
    "path": "core/dbt/task/run.py",
    "content": "from __future__ import annotations\n\nimport functools\nimport threading\nimport time\nfrom copy import deepcopy\nfrom dataclasses import asdict\nfrom datetime import datetime, timezone\nfrom typing import (\n    AbstractSet,\n    Any,\n    Callable,\n    Dict,\n    Iterable,\n    List,\n    Optional,\n    Set,\n    Tuple,\n    Type,\n)\n\nfrom dbt import tracking, utils\nfrom dbt.adapters.base import BaseAdapter, BaseRelation\nfrom dbt.adapters.capability import Capability\nfrom dbt.adapters.events.types import FinishedRunningStats\nfrom dbt.adapters.exceptions import MissingMaterializationError\nfrom dbt.artifacts.resources import Hook\nfrom dbt.artifacts.schemas.batch_results import BatchResults, BatchType\nfrom dbt.artifacts.schemas.results import (\n    NodeStatus,\n    RunningStatus,\n    RunStatus,\n    TimingInfo,\n    collect_timing_info,\n)\nfrom dbt.artifacts.schemas.run import RunResult\nfrom dbt.cli.flags import Flags\nfrom dbt.clients.jinja import MacroGenerator\nfrom dbt.config import RuntimeConfig\nfrom dbt.context.providers import generate_runtime_model_context\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.contracts.graph.nodes import BatchContext, HookNode, ModelNode, ResultNode\nfrom dbt.events.types import (\n    GenericExceptionOnRun,\n    LogBatchResult,\n    LogHookEndLine,\n    LogHookStartLine,\n    LogModelResult,\n    LogStartBatch,\n    LogStartLine,\n    MicrobatchExecutionDebug,\n)\nfrom dbt.exceptions import CompilationError, DbtInternalError, DbtRuntimeError\nfrom dbt.graph import ResourceTypeSelector\nfrom dbt.graph.thread_pool import DbtThreadPool\nfrom dbt.hooks import get_hook_dict\nfrom dbt.materializations.incremental.microbatch import MicrobatchBuilder\nfrom dbt.node_types import NodeType, RunHookType\nfrom dbt.task import group_lookup\nfrom dbt.task.base import BaseRunner\nfrom dbt.task.compile import CompileRunner, CompileTask\nfrom dbt.task.printer import get_counts, print_run_end_messages\nfrom dbt.utils.artifact_upload import add_artifact_produced\nfrom dbt_common.clients.jinja import MacroProtocol\nfrom dbt_common.dataclass_schema import dbtClassMixin\nfrom dbt_common.events.base_types import EventLevel\nfrom dbt_common.events.contextvars import log_contextvars\nfrom dbt_common.events.functions import fire_event, get_invocation_id\nfrom dbt_common.events.types import Formatting\nfrom dbt_common.exceptions import DbtValidationError\nfrom dbt_common.invocation import get_invocation_started_at\n\n\n@functools.total_ordering\nclass BiggestName(str):\n    def __lt__(self, other):\n        return True\n\n    def __eq__(self, other):\n        return isinstance(other, self.__class__)\n\n\ndef _hook_list() -> List[HookNode]:\n    return []\n\n\ndef get_hooks_by_tags(\n    nodes: Iterable[ResultNode],\n    match_tags: Set[str],\n) -> List[HookNode]:\n    matched_nodes = []\n    for node in nodes:\n        if not isinstance(node, HookNode):\n            continue\n        node_tags = node.tags\n        if len(set(node_tags) & match_tags):\n            matched_nodes.append(node)\n    return matched_nodes\n\n\ndef get_hook(source, index):\n    hook_dict = get_hook_dict(source)\n    hook_dict.setdefault(\"index\", index)\n    Hook.validate(hook_dict)\n    return Hook.from_dict(hook_dict)\n\n\ndef get_execution_status(sql: str, adapter: BaseAdapter) -> Tuple[RunStatus, str]:\n    if not sql.strip():\n        return RunStatus.Success, \"OK\"\n\n    try:\n        response, _ = adapter.execute(sql, auto_begin=False, fetch=False)\n        status = RunStatus.Success\n        message = response._message\n    except (KeyboardInterrupt, SystemExit):\n        raise\n    except DbtRuntimeError as exc:\n        status = RunStatus.Error\n        message = exc.msg\n    except Exception as exc:\n        status = RunStatus.Error\n        message = str(exc)\n\n    return (status, message)\n\n\ndef _get_adapter_info(adapter, run_model_result) -> Dict[str, Any]:\n    \"\"\"Each adapter returns a dataclass with a flexible dictionary for\n    adapter-specific fields. Only the non-'model_adapter_details' fields\n    are guaranteed cross adapter.\"\"\"\n    return asdict(adapter.get_adapter_run_info(run_model_result.node.config)) if adapter else {}\n\n\ndef track_model_run(index, num_nodes, run_model_result, adapter=None):\n    if tracking.active_user is None:\n        raise DbtInternalError(\"cannot track model run with no active user\")\n    invocation_id = get_invocation_id()\n    node = run_model_result.node\n    has_group = True if hasattr(node, \"group\") and node.group else False\n    if node.resource_type == NodeType.Model:\n        access = node.access.value if node.access is not None else None\n        contract_enforced = node.contract.enforced\n        versioned = True if node.version else False\n        incremental_strategy = node.config.incremental_strategy\n    else:\n        access = None\n        contract_enforced = False\n        versioned = False\n        incremental_strategy = None\n\n    tracking.track_model_run(\n        {\n            \"invocation_id\": invocation_id,\n            \"index\": index,\n            \"total\": num_nodes,\n            \"execution_time\": run_model_result.execution_time,\n            \"run_status\": str(run_model_result.status).upper(),\n            \"run_skipped\": run_model_result.status == NodeStatus.Skipped,\n            \"run_error\": run_model_result.status == NodeStatus.Error,\n            \"model_materialization\": node.get_materialization(),\n            \"model_incremental_strategy\": incremental_strategy,\n            \"model_id\": utils.get_hash(node),\n            \"hashed_contents\": utils.get_hashed_contents(node),\n            \"timing\": [t.to_dict(omit_none=True) for t in run_model_result.timing],\n            \"language\": str(node.language),\n            \"has_group\": has_group,\n            \"contract_enforced\": contract_enforced,\n            \"access\": access,\n            \"versioned\": versioned,\n            \"adapter_info\": _get_adapter_info(adapter, run_model_result),\n        }\n    )\n\n\n# make sure that we got an ok result back from a materialization\ndef _validate_materialization_relations_dict(inp: Dict[Any, Any], model) -> List[BaseRelation]:\n    try:\n        relations_value = inp[\"relations\"]\n    except KeyError:\n        msg = (\n            'Invalid return value from materialization, \"relations\" '\n            \"not found, got keys: {}\".format(list(inp))\n        )\n        raise CompilationError(msg, node=model) from None\n\n    if not isinstance(relations_value, list):\n        msg = (\n            'Invalid return value from materialization, \"relations\" '\n            \"not a list, got: {}\".format(relations_value)\n        )\n        raise CompilationError(msg, node=model) from None\n\n    relations: List[BaseRelation] = []\n    for relation in relations_value:\n        if not isinstance(relation, BaseRelation):\n            msg = (\n                \"Invalid return value from materialization, \"\n                '\"relations\" contains non-Relation: {}'.format(relation)\n            )\n            raise CompilationError(msg, node=model)\n\n        assert isinstance(relation, BaseRelation)\n        relations.append(relation)\n    return relations\n\n\nclass ModelRunner(CompileRunner):\n    def describe_node(self) -> str:\n        # TODO CL 'language' will be moved to node level when we change representation\n        return f\"{self.node.language} {self.node.get_materialization()} model {self.get_node_representation()}\"\n\n    def print_start_line(self):\n        fire_event(\n            LogStartLine(\n                description=self.describe_node(),\n                index=self.node_index,\n                total=self.num_nodes,\n                node_info=self.node.node_info,\n            )\n        )\n\n    def print_result_line(self, result):\n        description = self.describe_node()\n        group = group_lookup.get(self.node.unique_id)\n        if result.status == NodeStatus.Error:\n            status = result.status\n            level = EventLevel.ERROR\n        else:\n            status = result.message\n            level = EventLevel.INFO\n        fire_event(\n            LogModelResult(\n                description=description,\n                status=status,\n                index=self.node_index,\n                total=self.num_nodes,\n                execution_time=result.execution_time,\n                node_info=self.node.node_info,\n                group=group,\n            ),\n            level=level,\n        )\n\n    def before_execute(self) -> None:\n        self.print_start_line()\n\n    def after_execute(self, result) -> None:\n        track_model_run(self.node_index, self.num_nodes, result, adapter=self.adapter)\n        self.print_result_line(result)\n\n    def _build_run_model_result(self, model, context, elapsed_time: float = 0.0):\n        result = context[\"load_result\"](\"main\")\n        if not result:\n            raise DbtRuntimeError(\"main is not being called during running model\")\n        adapter_response = {}\n        if isinstance(result.response, dbtClassMixin):\n            adapter_response = result.response.to_dict(omit_none=True)\n        return RunResult(\n            node=model,\n            status=RunStatus.Success,\n            timing=[],\n            thread_id=threading.current_thread().name,\n            execution_time=elapsed_time,\n            message=str(result.response),\n            adapter_response=adapter_response,\n            failures=result.get(\"failures\"),\n            batch_results=None,\n        )\n\n    def _materialization_relations(self, result: Any, model) -> List[BaseRelation]:\n        if isinstance(result, str):\n            msg = (\n                'The materialization (\"{}\") did not explicitly return a '\n                \"list of relations to add to the cache.\".format(str(model.get_materialization()))\n            )\n            raise CompilationError(msg, node=model)\n\n        if isinstance(result, dict):\n            return _validate_materialization_relations_dict(result, model)\n\n        msg = (\n            \"Invalid return value from materialization, expected a dict \"\n            'with key \"relations\", got: {}'.format(str(result))\n        )\n        raise CompilationError(msg, node=model)\n\n    def _execute_model(\n        self,\n        hook_ctx: Any,\n        context_config: Any,\n        model: ModelNode,\n        context: Dict[str, Any],\n        materialization_macro: MacroProtocol,\n    ) -> RunResult:\n        try:\n            result = MacroGenerator(\n                materialization_macro, context, stack=context[\"context_macro_stack\"]\n            )()\n        finally:\n            self.adapter.post_model_hook(context_config, hook_ctx)\n\n        for relation in self._materialization_relations(result, model):\n            self.adapter.cache_added(relation.incorporate(dbt_created=True))\n\n        return self._build_run_model_result(model, context)\n\n    def execute(self, model, manifest):\n        context = generate_runtime_model_context(model, self.config, manifest)\n\n        materialization_macro = manifest.find_materialization_macro_by_name(\n            self.config.project_name, model.get_materialization(), self.adapter.type()\n        )\n\n        if materialization_macro is None:\n            raise MissingMaterializationError(\n                materialization=model.get_materialization(), adapter_type=self.adapter.type()\n            )\n\n        if \"config\" not in context:\n            raise DbtInternalError(\n                \"Invalid materialization context generated, missing config: {}\".format(context)\n            )\n        context_config = context[\"config\"]\n\n        mat_has_supported_langs = hasattr(materialization_macro, \"supported_languages\")\n        model_lang_supported = model.language in materialization_macro.supported_languages\n        if mat_has_supported_langs and not model_lang_supported:\n            str_langs = [str(lang) for lang in materialization_macro.supported_languages]\n            raise DbtValidationError(\n                f'Materialization \"{materialization_macro.name}\" only supports languages {str_langs}; '\n                f'got \"{model.language}\"'\n            )\n\n        hook_ctx = self.adapter.pre_model_hook(context_config)\n\n        return self._execute_model(hook_ctx, context_config, model, context, materialization_macro)\n\n\nclass MicrobatchBatchRunner(ModelRunner):\n    \"\"\"Handles the running of individual batches\"\"\"\n\n    def __init__(\n        self,\n        config,\n        adapter,\n        node,\n        node_index: int,\n        num_nodes: int,\n        batch_idx: int,\n        batches: Dict[int, BatchType],\n        relation_exists: bool,\n        incremental_batch: bool,\n    ):\n        super().__init__(config, adapter, node, node_index, num_nodes)\n\n        self.batch_idx = batch_idx\n        self.batches = batches\n        self.relation_exists = relation_exists\n        self.incremental_batch = incremental_batch\n\n    def describe_batch(self) -> str:\n        batch_start = self.batches[self.batch_idx][0]\n        formatted_batch_start = MicrobatchBuilder.format_batch_start(\n            batch_start, self.node.config.batch_size\n        )\n        return f\"batch {formatted_batch_start} of {self.get_node_representation()}\"\n\n    def print_result_line(self, result: RunResult):\n        if result.status == NodeStatus.Error:\n            status = result.status\n            level = EventLevel.ERROR\n        elif result.status == NodeStatus.Skipped:\n            status = result.status\n            level = EventLevel.INFO\n        else:\n            status = result.message\n            level = EventLevel.INFO\n\n        fire_event(\n            LogBatchResult(\n                description=self.describe_batch(),\n                status=status,\n                batch_index=self.batch_idx + 1,\n                total_batches=len(self.batches),\n                execution_time=result.execution_time,\n                node_info=self.node.node_info,\n                group=group_lookup.get(self.node.unique_id),\n            ),\n            level=level,\n        )\n\n    def print_start_line(self) -> None:\n        fire_event(\n            LogStartBatch(\n                description=self.describe_batch(),\n                batch_index=self.batch_idx + 1,\n                total_batches=len(self.batches),\n                node_info=self.node.node_info,\n            )\n        )\n\n    def should_run_in_parallel(self) -> bool:\n        if not self.adapter.supports(Capability.MicrobatchConcurrency):\n            run_in_parallel = False\n        elif not self.relation_exists:\n            # If the relation doesn't exist, we can't run in parallel\n            run_in_parallel = False\n        elif self.node.config.concurrent_batches is not None:\n            # If the relation exists and the `concurrent_batches` config isn't None, use the config value\n            run_in_parallel = self.node.config.concurrent_batches\n        else:\n            # If the relation exists, the `concurrent_batches` config is None, check if the model self references `this`.\n            # If the model self references `this` then we assume the model batches _can't_ be run in parallel\n            run_in_parallel = not self.node.has_this\n\n        return run_in_parallel\n\n    def on_skip(self):\n        result = RunResult(\n            node=self.node,\n            status=RunStatus.Skipped,\n            timing=[],\n            thread_id=threading.current_thread().name,\n            execution_time=0.0,\n            message=\"SKIPPED\",\n            adapter_response={},\n            failures=1,\n            batch_results=BatchResults(failed=[self.batches[self.batch_idx]]),\n        )\n        self.print_result_line(result=result)\n        return result\n\n    def error_result(self, node, message, start_time, timing_info):\n        \"\"\"Necessary to return a result with a batch result\n\n        Called by `BaseRunner.safe_run` when an error occurs\n        \"\"\"\n        return self._build_run_result(\n            node=node,\n            start_time=start_time,\n            status=RunStatus.Error,\n            timing_info=timing_info,\n            message=message,\n            batch_results=BatchResults(failed=[self.batches[self.batch_idx]]),\n        )\n\n    def compile(self, manifest: Manifest):\n        batch = self.batches[self.batch_idx]\n\n        # LEGACY: Set start/end in context prior to re-compiling (Will be removed for 1.10+)\n        # TODO: REMOVE before 1.10 GA\n        self.node.config[\"__dbt_internal_microbatch_event_time_start\"] = batch[0]\n        self.node.config[\"__dbt_internal_microbatch_event_time_end\"] = batch[1]\n        # Create batch context on model node prior to re-compiling\n        self.node.batch = BatchContext(\n            id=MicrobatchBuilder.batch_id(batch[0], self.node.config.batch_size),\n            event_time_start=batch[0],\n            event_time_end=batch[1],\n        )\n        # Recompile node to re-resolve refs with event time filters rendered, update context\n        self.compiler.compile_node(\n            self.node,\n            manifest,\n            {},\n            split_suffix=MicrobatchBuilder.format_batch_start(\n                batch[0], self.node.config.batch_size\n            ),\n        )\n\n        return self.node\n\n    def _build_succesful_run_batch_result(\n        self,\n        model: ModelNode,\n        context: Dict[str, Any],\n        batch: BatchType,\n        elapsed_time: float = 0.0,\n    ) -> RunResult:\n        run_result = self._build_run_model_result(model, context, elapsed_time)\n        run_result.batch_results = BatchResults(successful=[batch])\n        return run_result\n\n    def _build_failed_run_batch_result(\n        self,\n        model: ModelNode,\n        batch: BatchType,\n        elapsed_time: float = 0.0,\n    ) -> RunResult:\n        return RunResult(\n            node=model,\n            status=RunStatus.Error,\n            timing=[],\n            thread_id=threading.current_thread().name,\n            execution_time=elapsed_time,\n            message=\"ERROR\",\n            adapter_response={},\n            failures=1,\n            batch_results=BatchResults(failed=[batch]),\n        )\n\n    def _execute_microbatch_materialization(\n        self,\n        model: ModelNode,\n        context: Dict[str, Any],\n        materialization_macro: MacroProtocol,\n    ) -> RunResult:\n\n        batch = self.batches[self.batch_idx]\n        # call materialization_macro to get a batch-level run result\n        start_time = time.perf_counter()\n        try:\n            # Update jinja context with batch context members\n            jinja_context = MicrobatchBuilder.build_jinja_context_for_batch(\n                model=model,\n                incremental_batch=self.incremental_batch,\n            )\n            context.update(jinja_context)\n\n            # Materialize batch and cache any materialized relations\n            result = MacroGenerator(\n                materialization_macro, context, stack=context[\"context_macro_stack\"]\n            )()\n            for relation in self._materialization_relations(result, model):\n                self.adapter.cache_added(relation.incorporate(dbt_created=True))\n\n            # Build result of executed batch\n            batch_run_result = self._build_succesful_run_batch_result(\n                model, context, batch, time.perf_counter() - start_time\n            )\n            batch_result = batch_run_result\n\n            # At least one batch has been inserted successfully!\n            # Can proceed incrementally + in parallel\n            self.relation_exists = True\n\n        except (KeyboardInterrupt, SystemExit):\n            # reraise it for GraphRunnableTask.execute_nodes to handle\n            raise\n        except Exception as e:\n            fire_event(\n                GenericExceptionOnRun(\n                    unique_id=self.node.unique_id,\n                    exc=f\"Exception on worker thread. {str(e)}\",\n                    node_info=self.node.node_info,\n                )\n            )\n            batch_run_result = self._build_failed_run_batch_result(\n                model, batch, time.perf_counter() - start_time\n            )\n\n        batch_result = batch_run_result\n\n        return batch_result\n\n    def _execute_model(\n        self,\n        hook_ctx: Any,\n        context_config: Any,\n        model: ModelNode,\n        context: Dict[str, Any],\n        materialization_macro: MacroProtocol,\n    ) -> RunResult:\n        try:\n            batch_result = self._execute_microbatch_materialization(\n                model, context, materialization_macro\n            )\n        finally:\n            self.adapter.post_model_hook(context_config, hook_ctx)\n\n        return batch_result\n\n\nclass MicrobatchModelRunner(ModelRunner):\n    \"\"\"Handles the orchestration of batches to run for a given microbatch model\"\"\"\n\n    def __init__(self, config, adapter, node, node_index: int, num_nodes: int):\n        super().__init__(config, adapter, node, node_index, num_nodes)\n\n        # The parent task is necessary because we need access to the `_submit_batch` and `submit` methods\n        self._parent_task: Optional[RunTask] = None\n        # The pool is necessary because we need to batches to be executed within the same thread pool\n        self._pool: Optional[DbtThreadPool] = None\n\n    def set_parent_task(self, parent_task: RunTask) -> None:\n        self._parent_task = parent_task\n\n    def set_pool(self, pool: DbtThreadPool) -> None:\n        self._pool = pool\n\n    @property\n    def parent_task(self) -> RunTask:\n        if self._parent_task is None:\n            raise DbtInternalError(\n                msg=\"Tried to access `parent_task` of `MicrobatchModelRunner` before it was set\"\n            )\n\n        return self._parent_task\n\n    @property\n    def pool(self) -> DbtThreadPool:\n        if self._pool is None:\n            raise DbtInternalError(\n                msg=\"Tried to access `pool` of `MicrobatchModelRunner` before it was set\"\n            )\n\n        return self._pool\n\n    def _has_relation(self, model: ModelNode) -> bool:\n        \"\"\"Check whether the relation for the model exists in the data warehouse\"\"\"\n        relation_info = self.adapter.Relation.create_from(self.config, model)\n        relation = self.adapter.get_relation(\n            relation_info.database, relation_info.schema, relation_info.name\n        )\n        return relation is not None\n\n    def _is_incremental(self, model) -> bool:\n        \"\"\"Check whether the model should be run `incrementally` or as `full refresh`\"\"\"\n        # TODO: Remove this whole function. This should be a temporary method. We're working with adapters on\n        # a strategy to ensure we can access the `is_incremental` logic without drift\n        relation_info = self.adapter.Relation.create_from(self.config, model)\n        relation = self.adapter.get_relation(\n            relation_info.database, relation_info.schema, relation_info.name\n        )\n        if (\n            relation is not None\n            and relation.type == \"table\"\n            and model.config.materialized == \"incremental\"\n        ):\n            if model.config.full_refresh is not None:\n                return not model.config.full_refresh\n            else:\n                return not getattr(self.config.args, \"FULL_REFRESH\", False)\n        else:\n            return False\n\n    def _initial_run_microbatch_model_result(self, model: ModelNode) -> RunResult:\n        return RunResult(\n            node=model,\n            status=RunStatus.Success,\n            timing=[],\n            thread_id=threading.current_thread().name,\n            # The execution_time here doesn't get propagated to logs because\n            # `safe_run_hooks` handles the elapsed time at the node level\n            execution_time=0,\n            message=\"\",\n            adapter_response={},\n            failures=0,\n            batch_results=BatchResults(),\n        )\n\n    def describe_node(self) -> str:\n        return f\"{self.node.language} microbatch model {self.get_node_representation()}\"\n\n    def merge_batch_results(self, result: RunResult, batch_results: List[RunResult]):\n        \"\"\"merge batch_results into result\"\"\"\n        if result.batch_results is None:\n            result.batch_results = BatchResults()\n\n        for batch_result in batch_results:\n            if batch_result.batch_results is not None:\n                result.batch_results += batch_result.batch_results\n            result.execution_time += batch_result.execution_time\n\n        num_successes = len(result.batch_results.successful)\n        num_failures = len(result.batch_results.failed)\n        if num_failures == 0:\n            status = RunStatus.Success\n            msg = \"SUCCESS\"\n        elif num_successes == 0:\n            status = RunStatus.Error\n            msg = \"ERROR\"\n        else:\n            status = RunStatus.PartialSuccess\n            msg = f\"PARTIAL SUCCESS ({num_successes}/{num_successes + num_failures})\"\n        result.status = status\n        result.message = msg\n\n        result.batch_results.successful = sorted(result.batch_results.successful)\n        result.batch_results.failed = sorted(result.batch_results.failed)\n\n        # # If retrying, propagate previously successful batches into final result, even thoguh they were not run in this invocation\n        if self.node.previous_batch_results is not None:\n            result.batch_results.successful += self.node.previous_batch_results.successful\n\n    def _update_result_with_unfinished_batches(\n        self, result: RunResult, batches: Dict[int, BatchType]\n    ) -> None:\n        \"\"\"This method is really only to be used when the execution of a microbatch model is halted before all batches have had a chance to run\"\"\"\n        batches_finished: Set[BatchType] = set()\n\n        if result.batch_results:\n            # build list of finished batches\n            batches_finished = batches_finished.union(set(result.batch_results.successful))\n            batches_finished = batches_finished.union(set(result.batch_results.failed))\n        else:\n            # instantiate `batch_results` if it was `None`\n            result.batch_results = BatchResults()\n\n        # skipped batches are any batch that was expected but didn't finish\n        batches_expected = {batch for _, batch in batches.items()}\n        skipped_batches = batches_expected.difference(batches_finished)\n\n        result.batch_results.failed.extend(list(skipped_batches))\n\n        # We call this method, even though we are merging no new results, as it updates\n        # the result witht he appropriate status (Success/Partial/Failed)\n        self.merge_batch_results(result, [])\n\n    def get_microbatch_builder(self, model: ModelNode) -> MicrobatchBuilder:\n        # Intially set the start/end to values from args\n        event_time_start = getattr(self.config.args, \"EVENT_TIME_START\", None)\n        event_time_end = getattr(self.config.args, \"EVENT_TIME_END\", None)\n\n        # If we're in sample mode, alter start/end to sample values\n        if getattr(self.config.args, \"SAMPLE\", None) is not None:\n            event_time_start = self.config.args.sample.start\n            event_time_end = self.config.args.sample.end\n\n        # During retry, use the original invocation time so that the same\n        # batches are recomputed rather than batches relative to \"now\".\n        default_end_time = (\n            self.parent_task.original_invocation_started_at or get_invocation_started_at()\n        )\n\n        return MicrobatchBuilder(\n            model=model,\n            is_incremental=self._is_incremental(model),\n            event_time_start=event_time_start,\n            event_time_end=event_time_end,\n            default_end_time=default_end_time,\n        )\n\n    def get_batches(self, model: ModelNode) -> Dict[int, BatchType]:\n        \"\"\"Get the batches that should be run for the model\"\"\"\n\n        # Note currently (02/23/2025) model.previous_batch_results is only ever _not_ `None`\n        # IFF `dbt retry` is being run and the microbatch model had batches which\n        # failed on the run of the model (which is being retried)\n        if model.previous_batch_results is None:\n            microbatch_builder = self.get_microbatch_builder(model)\n            end = microbatch_builder.build_end_time()\n            start = microbatch_builder.build_start_time(end)\n            batches = microbatch_builder.build_batches(start, end)\n        else:\n            batches = model.previous_batch_results.failed\n\n        return {batch_idx: batches[batch_idx] for batch_idx in range(len(batches))}\n\n    def compile(self, manifest: Manifest):\n        \"\"\"Don't do anything here because this runner doesn't need to compile anything\"\"\"\n        return self.node\n\n    def execute(self, model: ModelNode, manifest: Manifest) -> RunResult:\n        # Execution really means orchestration in this case\n\n        batches = self.get_batches(model=model)\n        relation_exists = self._has_relation(model=model)\n        result = self._initial_run_microbatch_model_result(model=model)\n\n        # No batches to run, so return initial result\n        if len(batches) == 0:\n            return result\n\n        batch_results: List[RunResult] = []\n        batch_idx = 0\n\n        # Run first batch not in parallel\n        relation_exists = self.parent_task._submit_batch(\n            node=model,\n            adapter=self.adapter,\n            relation_exists=relation_exists,\n            batches=batches,\n            batch_idx=batch_idx,\n            batch_results=batch_results,\n            pool=self.pool,\n            force_sequential_run=True,\n            incremental_batch=self._is_incremental(model=model),\n        )\n        batch_idx += 1\n        skip_batches = batch_results[0].status != RunStatus.Success\n\n        # Run all batches except first and last batch, in parallel if possible\n        while batch_idx < len(batches) - 1:\n            relation_exists = self.parent_task._submit_batch(\n                node=model,\n                adapter=self.adapter,\n                relation_exists=relation_exists,\n                batches=batches,\n                batch_idx=batch_idx,\n                batch_results=batch_results,\n                pool=self.pool,\n                skip=skip_batches,\n            )\n            batch_idx += 1\n\n        # Wait until all submitted batches have completed\n        while len(batch_results) != batch_idx:\n            # Check if the pool was closed, because if it was, then the main thread is trying to exit.\n            # If the main thread is trying to exit, we need to shutdown. If we _don't_ shutdown, then\n            # batches will continue to execute and we'll delay the run from stopping\n            if self.pool.is_closed():\n                # It's technically possible for more results to come in while we clean up\n                # instead we're going to say the didn't finish, regardless of if they finished\n                # or not. Thus, lets get a copy of the results as they exist right \"now\".\n                frozen_batch_results = deepcopy(batch_results)\n                self.merge_batch_results(result, frozen_batch_results)\n                self._update_result_with_unfinished_batches(result, batches)\n                return result\n\n            # breifly sleep so that this thread doesn't go brrrrr while waiting\n            time.sleep(0.1)\n\n        # Only run \"last\" batch if there is more than one batch\n        if len(batches) != 1:\n            # Final batch runs once all others complete to ensure post_hook runs at the end\n            self.parent_task._submit_batch(\n                node=model,\n                adapter=self.adapter,\n                relation_exists=relation_exists,\n                batches=batches,\n                batch_idx=batch_idx,\n                batch_results=batch_results,\n                pool=self.pool,\n                force_sequential_run=True,\n                skip=skip_batches,\n            )\n\n        # Finalize run: merge results, track model run, and print final result line\n        self.merge_batch_results(result, batch_results)\n\n        return result\n\n\nclass RunTask(CompileTask):\n    def __init__(\n        self,\n        args: Flags,\n        config: RuntimeConfig,\n        manifest: Manifest,\n        batch_map: Optional[Dict[str, BatchResults]] = None,\n    ) -> None:\n        super().__init__(args, config, manifest)\n        self.batch_map = batch_map\n        self.original_invocation_started_at: Optional[datetime] = None\n\n    def raise_on_first_error(self) -> bool:\n        return False\n\n    def get_hook_sql(self, adapter, hook, idx, num_hooks, extra_context) -> str:\n        if self.manifest is None:\n            raise DbtInternalError(\"compile_node called before manifest was loaded\")\n\n        compiled = self.compiler.compile_node(hook, self.manifest, extra_context)\n        statement = compiled.compiled_code\n        hook_index = hook.index or num_hooks\n        hook_obj = get_hook(statement, index=hook_index)\n        return hook_obj.sql or \"\"\n\n    def handle_job_queue(self, pool: DbtThreadPool, callback: Callable) -> None:\n        assert self.job_queue is not None\n        node = self.job_queue.get()\n        self._raise_set_error()\n        runner = self.get_runner(node)\n        # we finally know what we're running! Make sure we haven't decided\n        # to skip it due to upstream failures\n        if runner.node.unique_id in self._skipped_children:\n            cause = self._skipped_children.pop(runner.node.unique_id)\n            runner.do_skip(cause=cause)\n\n        if isinstance(runner, MicrobatchModelRunner):\n            runner.set_parent_task(self)\n            runner.set_pool(pool)\n\n        args = [runner]\n\n        # Ensure we don't submit more MicrobatchModelRunners than the pool allows\n        self._maybe_wait_for_microbatch(pool, runner)\n        self._submit(pool, args, callback)\n\n    def _maybe_wait_for_microbatch(self, pool: DbtThreadPool, runner: BaseRunner) -> None:\n        \"\"\"\n        Checks if the runner is a MicrobatchModelRunner, and waits until the\n        number of microbatch models in progress is less than the max number\n        of microbatch models allowed by the pool.\n        \"\"\"\n\n        if isinstance(runner, MicrobatchModelRunner) and self.job_queue is not None:\n            fire_event(\n                MicrobatchExecutionDebug(\n                    msg=f\"Waiting for microbatch model to be run: {runner.node.name}.\\n\\tpool.max_microbatch_models: {pool.max_microbatch_models}\\n\\tlen(self.job_queue.in_progress_microbatch): {len(self.job_queue.in_progress_microbatch)}\"\n                )\n            )\n            while pool.max_microbatch_models < len(self.job_queue.in_progress_microbatch):\n                time.sleep(0.1)\n\n        return\n\n    def _submit_batch(\n        self,\n        node: ModelNode,\n        adapter: BaseAdapter,\n        relation_exists: bool,\n        batches: Dict[int, BatchType],\n        batch_idx: int,\n        batch_results: List[RunResult],\n        pool: DbtThreadPool,\n        force_sequential_run: bool = False,\n        skip: bool = False,\n        incremental_batch: bool = True,\n    ):\n        node_copy = deepcopy(node)\n        # Only run pre_hook(s) for first batch\n        if batch_idx != 0:\n            node_copy.config.pre_hook = []\n\n        # Only run post_hook(s) for last batch\n        if batch_idx != len(batches) - 1:\n            node_copy.config.post_hook = []\n\n        # TODO: We should be doing self.get_runner, however doing so\n        # currently causes the tracking of how many nodes there are to\n        # increment when we don't want it to\n        batch_runner = MicrobatchBatchRunner(\n            self.config,\n            adapter,\n            node_copy,\n            self.run_count,\n            self.num_nodes,\n            batch_idx,\n            batches,\n            relation_exists,\n            incremental_batch,\n        )\n\n        if skip:\n            batch_runner.do_skip()\n\n        if not pool.is_closed():\n            # Only run the batch in parallel IFF:\n            # 1. The batch runner is not forced to run sequentially\n            # 2. The batch runner should be run in parallel\n            # 3. There are available threads in the pool\n            #   a. This prevents deadlocks from occurring --threads=1\n            if (\n                not force_sequential_run\n                and batch_runner.should_run_in_parallel()\n                and self.job_queue is not None\n                and len(self.job_queue.in_progress) < pool.max_threads\n            ):\n                fire_event(\n                    MicrobatchExecutionDebug(\n                        msg=f\"{batch_runner.describe_batch()} is being run concurrently\"\n                    )\n                )\n                self._submit(pool, [batch_runner], batch_results.append)\n            else:\n                fire_event(\n                    MicrobatchExecutionDebug(\n                        msg=f\"{batch_runner.describe_batch()} is being run sequentially\"\n                    )\n                )\n                batch_results.append(self.call_runner(batch_runner))\n                relation_exists = batch_runner.relation_exists\n        else:\n            batch_results.append(\n                batch_runner._build_failed_run_batch_result(node_copy, batches[batch_idx])\n            )\n\n        return relation_exists\n\n    def _hook_keyfunc(self, hook: HookNode) -> Tuple[str, Optional[int]]:\n        package_name = hook.package_name\n        if package_name == self.config.project_name:\n            package_name = BiggestName(\"\")\n        return package_name, hook.index\n\n    def get_hooks_by_type(self, hook_type: RunHookType) -> List[HookNode]:\n\n        if self.manifest is None:\n            raise DbtInternalError(\"self.manifest was None in get_hooks_by_type\")\n\n        nodes = self.manifest.nodes.values()\n        # find all hooks defined in the manifest (could be multiple projects)\n        hooks: List[HookNode] = get_hooks_by_tags(nodes, {hook_type})\n        hooks.sort(key=self._hook_keyfunc)\n        return hooks\n\n    def safe_run_hooks(\n        self, adapter: BaseAdapter, hook_type: RunHookType, extra_context: Dict[str, Any]\n    ) -> RunStatus:\n        ordered_hooks = self.get_hooks_by_type(hook_type)\n\n        if hook_type == RunHookType.End and ordered_hooks:\n            fire_event(Formatting(\"\"))\n\n        # on-run-* hooks should run outside a transaction. This happens because psycopg2 automatically begins a transaction when a connection is created.\n        adapter.clear_transaction()\n        if not ordered_hooks:\n            return RunStatus.Success\n\n        status = RunStatus.Success\n        failed = False\n        num_hooks = len(ordered_hooks)\n\n        for idx, hook in enumerate(ordered_hooks, 1):\n            with log_contextvars(node_info=hook.node_info):\n                hook.index = idx\n                hook_name = f\"{hook.package_name}.{hook_type}.{hook.index - 1}\"\n                execution_time = 0.0\n                timing: List[TimingInfo] = []\n                failures = 1\n\n                if not failed:\n                    with collect_timing_info(\"compile\", timing.append):\n                        sql = self.get_hook_sql(\n                            adapter, hook, hook.index, num_hooks, extra_context\n                        )\n\n                    started_at = timing[0].started_at or datetime.now(timezone.utc).replace(\n                        tzinfo=None\n                    )\n                    hook.update_event_status(\n                        started_at=started_at.isoformat(), node_status=RunningStatus.Started\n                    )\n\n                    fire_event(\n                        LogHookStartLine(\n                            statement=hook_name,\n                            index=hook.index,\n                            total=num_hooks,\n                            node_info=hook.node_info,\n                        )\n                    )\n\n                    with collect_timing_info(\"execute\", timing.append):\n                        status, message = get_execution_status(sql, adapter)\n\n                    finished_at = timing[1].completed_at or datetime.now(timezone.utc).replace(\n                        tzinfo=None\n                    )\n                    hook.update_event_status(finished_at=finished_at.isoformat())\n                    execution_time = (finished_at - started_at).total_seconds()\n                    failures = 0 if status == RunStatus.Success else 1\n\n                    if status == RunStatus.Success:\n                        message = f\"{hook_name} passed\"\n                    else:\n                        message = f\"{hook_name} failed, error:\\n {message}\"\n                        failed = True\n                else:\n                    status = RunStatus.Skipped\n                    message = f\"{hook_name} skipped\"\n\n                hook.update_event_status(node_status=status)\n\n                self.node_results.append(\n                    RunResult(\n                        status=status,\n                        thread_id=\"main\",\n                        timing=timing,\n                        message=message,\n                        adapter_response={},\n                        execution_time=execution_time,\n                        failures=failures,\n                        node=hook,\n                    )\n                )\n\n                fire_event(\n                    LogHookEndLine(\n                        statement=hook_name,\n                        status=status,\n                        index=hook.index,\n                        total=num_hooks,\n                        execution_time=execution_time,\n                        node_info=hook.node_info,\n                    )\n                )\n\n        if hook_type == RunHookType.Start and ordered_hooks:\n            fire_event(Formatting(\"\"))\n\n        return status\n\n    def print_results_line(self, results, execution_time) -> None:\n        nodes = [r.node for r in results if hasattr(r, \"node\")]\n        stat_line = get_counts(nodes)\n\n        execution = \"\"\n\n        if execution_time is not None:\n            execution = utils.humanize_execution_time(execution_time=execution_time)\n\n        fire_event(Formatting(\"\"))\n        fire_event(\n            FinishedRunningStats(\n                stat_line=stat_line, execution=execution, execution_time=execution_time\n            )\n        )\n\n    def populate_microbatch_batches(self, selected_uids: AbstractSet[str]):\n        if self.batch_map is not None and self.manifest is not None:\n            for uid in selected_uids:\n                if uid in self.batch_map:\n                    node = self.manifest.ref_lookup.perform_lookup(uid, self.manifest)\n                    if isinstance(node, ModelNode):\n                        node.previous_batch_results = self.batch_map[uid]\n\n    def before_run(self, adapter: BaseAdapter, selected_uids: AbstractSet[str]) -> RunStatus:\n        with adapter.connection_named(\"master\"):\n            self.defer_to_manifest()\n            required_schemas = self.get_model_schemas(adapter, selected_uids)\n            self.create_schemas(adapter, required_schemas)\n            self.populate_adapter_cache(adapter, required_schemas)\n            self.populate_microbatch_batches(selected_uids)\n            group_lookup.init(self.manifest, selected_uids)\n            run_hooks_status = self.safe_run_hooks(adapter, RunHookType.Start, {})\n            return run_hooks_status\n\n    def after_run(self, adapter, results) -> None:\n        # in on-run-end hooks, provide the value 'database_schemas', which is a\n        # list of unique (database, schema) pairs that successfully executed\n        # models were in. For backwards compatibility, include the old\n        # 'schemas', which did not include database information.\n\n        database_schema_set: Set[Tuple[Optional[str], str]] = {\n            (r.node.database, r.node.schema)\n            for r in results\n            if (hasattr(r, \"node\") and r.node.is_relational)\n            and r.status not in (NodeStatus.Error, NodeStatus.Fail, NodeStatus.Skipped)\n        }\n\n        extras = {\n            \"schemas\": list({s for _, s in database_schema_set}),\n            \"results\": [\n                r for r in results if r.thread_id != \"main\" or r.status == RunStatus.Error\n            ],  # exclude that didn't fail to preserve backwards compatibility\n            \"database_schemas\": list(database_schema_set),\n        }\n\n        try:\n            with adapter.connection_named(\"master\"):\n                self.safe_run_hooks(adapter, RunHookType.End, extras)\n        except (KeyboardInterrupt, SystemExit, DbtRuntimeError):\n            run_result = self.get_result(\n                results=self.node_results,\n                elapsed_time=time.time() - self.started_at,\n                generated_at=datetime.now(timezone.utc).replace(tzinfo=None),\n            )\n\n            if self.args.write_json and hasattr(run_result, \"write\"):\n                run_result.write(self.result_path())\n                add_artifact_produced(self.result_path())\n\n            print_run_end_messages(self.node_results, keyboard_interrupt=True)\n\n            raise\n\n    def get_node_selector(self) -> ResourceTypeSelector:\n        if self.manifest is None or self.graph is None:\n            raise DbtInternalError(\"manifest and graph must be set to get perform node selection\")\n        return ResourceTypeSelector(\n            graph=self.graph,\n            manifest=self.manifest,\n            previous_state=self.previous_state,\n            resource_types=[NodeType.Model],\n            selectors=self.config.selectors,\n        )\n\n    def get_runner_type(self, node) -> Optional[Type[BaseRunner]]:\n        if self.manifest is None:\n            raise DbtInternalError(\"manifest must be set prior to calling get_runner_type\")\n\n        if (\n            node.config.materialized == \"incremental\"\n            and node.config.incremental_strategy == \"microbatch\"\n            and self.manifest.use_microbatch_batches(project_name=self.config.project_name)\n        ):\n            return MicrobatchModelRunner\n        else:\n            return ModelRunner\n\n    def task_end_messages(self, results) -> None:\n        if results:\n            print_run_end_messages(results)\n"
  },
  {
    "path": "core/dbt/task/run_operation.py",
    "content": "import os\nimport threading\nimport traceback\nfrom datetime import datetime, timezone\nfrom typing import TYPE_CHECKING, List\n\nimport dbt_common.exceptions\nfrom dbt.adapters.factory import get_adapter\nfrom dbt.artifacts.schemas.results import RunStatus, TimingInfo, collect_timing_info\nfrom dbt.artifacts.schemas.run import RunResult, RunResultsArtifact\nfrom dbt.constants import RUN_RESULTS_FILE_NAME\nfrom dbt.contracts.files import FileHash\nfrom dbt.contracts.graph.nodes import HookNode\nfrom dbt.events.types import (\n    ArtifactWritten,\n    LogDebugStackTrace,\n    RunningOperationCaughtError,\n    RunningOperationUncaughtError,\n)\nfrom dbt.node_types import NodeType\nfrom dbt.task.base import ConfiguredTask\nfrom dbt_common.events.functions import fire_event\n\nif TYPE_CHECKING:\n    import agate\n\n\nclass RunOperationTask(ConfiguredTask):\n    def _get_macro_parts(self):\n        macro_name = self.args.macro\n        if \".\" in macro_name:\n            package_name, macro_name = macro_name.split(\".\", 1)\n        else:\n            package_name = None\n\n        return package_name, macro_name\n\n    def _run_unsafe(self, package_name, macro_name) -> \"agate.Table\":\n        adapter = get_adapter(self.config)\n\n        macro_kwargs = self.args.args\n\n        with adapter.connection_named(\"macro_{}\".format(macro_name)):\n            adapter.clear_transaction()\n            res = adapter.execute_macro(\n                macro_name, project=package_name, kwargs=macro_kwargs, macro_resolver=self.manifest\n            )\n\n        return res\n\n    def run(self) -> RunResultsArtifact:\n        timing: List[TimingInfo] = []\n\n        with collect_timing_info(\"compile\", timing.append):\n            self.compile_manifest()\n\n        start = timing[0].started_at\n\n        success = True\n        package_name, macro_name = self._get_macro_parts()\n\n        with collect_timing_info(\"execute\", timing.append):\n            try:\n                self._run_unsafe(package_name, macro_name)\n            except dbt_common.exceptions.DbtBaseException as exc:\n                fire_event(RunningOperationCaughtError(exc=str(exc)))\n                fire_event(LogDebugStackTrace(exc_info=traceback.format_exc()))\n                success = False\n            except Exception as exc:\n                fire_event(RunningOperationUncaughtError(exc=str(exc)))\n                fire_event(LogDebugStackTrace(exc_info=traceback.format_exc()))\n                success = False\n\n        end = timing[1].completed_at\n\n        macro = (\n            self.manifest.find_macro_by_name(macro_name, self.config.project_name, package_name)\n            if self.manifest\n            else None\n        )\n\n        if macro:\n            unique_id = macro.unique_id\n            fqn = unique_id.split(\".\")\n        else:\n            raise dbt_common.exceptions.UndefinedMacroError(\n                f\"dbt could not find a macro with the name '{macro_name}' in any package\"\n            )\n\n        execution_time = (end - start).total_seconds() if start and end else 0.0\n\n        run_result = RunResult(\n            adapter_response={},\n            status=RunStatus.Success if success else RunStatus.Error,\n            execution_time=execution_time,\n            failures=0 if success else 1,\n            message=None,\n            node=HookNode(\n                alias=macro_name,\n                checksum=FileHash.from_contents(unique_id),\n                database=self.config.credentials.database,\n                schema=self.config.credentials.schema,\n                resource_type=NodeType.Operation,\n                fqn=fqn,\n                name=macro_name,\n                unique_id=unique_id,\n                package_name=package_name,\n                path=\"\",\n                original_file_path=\"\",\n            ),\n            thread_id=threading.current_thread().name,\n            timing=timing,\n            batch_results=None,\n        )\n\n        results = RunResultsArtifact.from_execution_results(\n            generated_at=end or datetime.now(timezone.utc).replace(tzinfo=None),\n            elapsed_time=execution_time,\n            args={\n                k: v\n                for k, v in self.args.__dict__.items()\n                if k.islower() and type(v) in (str, int, float, bool, list, dict)\n            },\n            results=[run_result],\n        )\n\n        result_path = os.path.join(self.config.project_target_path, RUN_RESULTS_FILE_NAME)\n\n        if self.args.write_json:\n            results.write(result_path)\n            fire_event(\n                ArtifactWritten(\n                    artifact_type=results.__class__.__name__, artifact_path=result_path\n                )\n            )\n\n        return results\n\n    @classmethod\n    def interpret_results(cls, results):\n        return results.results[0].status == RunStatus.Success\n"
  },
  {
    "path": "core/dbt/task/runnable.py",
    "content": "import os\nimport time\nfrom abc import abstractmethod\nfrom concurrent.futures import as_completed\nfrom datetime import datetime, timezone\nfrom pathlib import Path\nfrom typing import (\n    AbstractSet,\n    Any,\n    Callable,\n    Dict,\n    Iterable,\n    List,\n    Optional,\n    Set,\n    Tuple,\n    Type,\n    Union,\n)\n\nimport dbt.exceptions\nimport dbt.tracking\nimport dbt.utils\nimport dbt_common.utils.formatting\nfrom dbt.adapters.base import BaseAdapter, BaseRelation\nfrom dbt.adapters.factory import get_adapter\nfrom dbt.artifacts.schemas.results import (\n    BaseResult,\n    NodeStatus,\n    RunningStatus,\n    RunStatus,\n)\nfrom dbt.artifacts.schemas.run import RunExecutionResult, RunResult\nfrom dbt.cli.flags import Flags\nfrom dbt.config.runtime import RuntimeConfig\nfrom dbt.constants import RUN_RESULTS_FILE_NAME\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.contracts.graph.nodes import Exposure, ResultNode\nfrom dbt.contracts.state import PreviousState\nfrom dbt.events.types import (\n    ArtifactWritten,\n    ConcurrencyLine,\n    DefaultSelector,\n    EndRunResult,\n    GenericExceptionOnRun,\n    LogCancelLine,\n    MarkSkippedChildren,\n    NodeFinished,\n    NodeStart,\n    NothingToDo,\n    QueryCancelationUnsupported,\n    SkippingDetails,\n)\nfrom dbt.exceptions import DbtInternalError, DbtRuntimeError, FailFastError\nfrom dbt.flags import get_flags\nfrom dbt.graph import (\n    GraphQueue,\n    NodeSelector,\n    SelectionSpec,\n    UniqueId,\n    parse_difference,\n)\nfrom dbt.graph.thread_pool import DbtThreadPool\nfrom dbt.parser.manifest import write_manifest\nfrom dbt.task import group_lookup\nfrom dbt.task.base import BaseRunner, ConfiguredTask\nfrom dbt.task.printer import print_run_end_messages, print_run_result_error\nfrom dbt.utils.artifact_upload import add_artifact_produced\nfrom dbt_common.context import _INVOCATION_CONTEXT_VAR, get_invocation_context\nfrom dbt_common.dataclass_schema import StrEnum\nfrom dbt_common.events.contextvars import log_contextvars, task_contextvars\nfrom dbt_common.events.functions import fire_event, warn_or_error\nfrom dbt_common.events.types import Formatting\nfrom dbt_common.exceptions import NotImplementedError\n\n\nclass GraphRunnableMode(StrEnum):\n    Topological = \"topological\"\n    Independent = \"independent\"\n\n\ndef mark_node_as_skipped(\n    node: ResultNode, executed_node_ids: Set[str], message: Optional[str]\n) -> Optional[RunResult]:\n    if node.unique_id not in executed_node_ids:\n        return RunResult.from_node(node, RunStatus.Skipped, message)\n    return None\n\n\nclass GraphRunnableTask(ConfiguredTask):\n    MARK_DEPENDENT_ERRORS_STATUSES = [NodeStatus.Error, NodeStatus.PartialSuccess]\n\n    def __init__(self, args: Flags, config: RuntimeConfig, manifest: Manifest) -> None:\n        super().__init__(args, config, manifest)\n        self.config = config\n        self._flattened_nodes: Optional[List[ResultNode]] = None\n        self._raise_next_tick: Optional[DbtRuntimeError] = None\n        self._skipped_children: Dict[str, Optional[RunResult]] = {}\n        self.job_queue: Optional[GraphQueue] = None\n        self.node_results: List[BaseResult] = []\n        self.num_nodes: int = 0\n        self.previous_state: Optional[PreviousState] = None\n        self.previous_defer_state: Optional[PreviousState] = None\n        self.run_count: int = 0\n        self.started_at: float = 0\n\n        if self.args.state:\n            self.previous_state = PreviousState(\n                state_path=self.args.state,\n                target_path=Path(self.config.target_path),\n                project_root=Path(self.config.project_root),\n            )\n\n        if self.args.defer_state:\n            self.previous_defer_state = PreviousState(\n                state_path=self.args.defer_state,\n                target_path=Path(self.config.target_path),\n                project_root=Path(self.config.project_root),\n            )\n\n    def index_offset(self, value: int) -> int:\n        return value\n\n    @property\n    def selection_arg(self):\n        return self.args.select\n\n    @property\n    def exclusion_arg(self):\n        return self.args.exclude\n\n    def get_selection_spec(self) -> SelectionSpec:\n        default_selector_name = self.config.get_default_selector_name()\n        spec: Union[SelectionSpec, bool]\n        if hasattr(self.args, \"inline\") and self.args.inline:\n            # We want an empty selection spec.\n            spec = parse_difference(None, None)\n        elif self.args.selector:\n            # use pre-defined selector (--selector)\n            spec = self.config.get_selector(self.args.selector)\n        elif not (self.selection_arg or self.exclusion_arg) and default_selector_name:\n            # use pre-defined selector (--selector) with default: true\n            fire_event(DefaultSelector(name=default_selector_name))\n            spec = self.config.get_selector(default_selector_name)\n        else:\n            # This is what's used with no default selector and no selection\n            # use --select and --exclude args\n            spec = parse_difference(self.selection_arg, self.exclusion_arg)\n        # mypy complains because the return values of get_selector and parse_difference\n        # are different\n        return spec  # type: ignore\n\n    @abstractmethod\n    def get_node_selector(self) -> NodeSelector:\n        raise NotImplementedError(f\"get_node_selector not implemented for task {type(self)}\")\n\n    def defer_to_manifest(self):\n        deferred_manifest = self._get_deferred_manifest()\n        if deferred_manifest is None:\n            return\n        if self.manifest is None:\n            raise DbtInternalError(\n                \"Expected to defer to manifest, but there is no runtime manifest to defer from!\"\n            )\n        self.manifest.merge_from_artifact(other=deferred_manifest)\n\n    def get_graph_queue(self) -> GraphQueue:\n        selector = self.get_node_selector()\n        # Following uses self.selection_arg and self.exclusion_arg\n        spec = self.get_selection_spec()\n\n        preserve_edges = True\n        if self.get_run_mode() == GraphRunnableMode.Independent:\n            preserve_edges = False\n\n        return selector.get_graph_queue(spec, preserve_edges)\n\n    def get_run_mode(self) -> GraphRunnableMode:\n        return GraphRunnableMode.Topological\n\n    def _runtime_initialize(self):\n        self.compile_manifest()\n        if self.manifest is None or self.graph is None:\n            raise DbtInternalError(\"_runtime_initialize never loaded the graph!\")\n\n        self.job_queue = self.get_graph_queue()\n\n        # Set selected node IDs on the compiler so FK constraint compilation\n        # can determine whether to use deferred relations or current relations.\n        # FK targets that ARE selected should use current relations (being built now).\n        # FK targets that are NOT selected should use deferred relations (from state).\n        self.compiler.selected_node_ids = set(self.job_queue.get_selected_nodes())\n\n        # we use this a couple of times. order does not matter.\n        self._flattened_nodes = []\n        for uid in self.job_queue.get_selected_nodes():\n            if uid in self.manifest.nodes:\n                self._flattened_nodes.append(self.manifest.nodes[uid])\n            elif uid in self.manifest.sources:\n                self._flattened_nodes.append(self.manifest.sources[uid])\n            elif uid in self.manifest.saved_queries:\n                self._flattened_nodes.append(self.manifest.saved_queries[uid])\n            elif uid in self.manifest.unit_tests:\n                self._flattened_nodes.append(self.manifest.unit_tests[uid])\n            elif uid in self.manifest.exposures:\n                self._flattened_nodes.append(self.manifest.exposures[uid])\n            elif uid in self.manifest.functions:\n                self._flattened_nodes.append(self.manifest.functions[uid])\n            else:\n                raise DbtInternalError(\n                    f\"Node selection returned {uid}, expected an exposure, a function, a node, a saved query, a source, or a unit test\"\n                )\n\n        self.num_nodes = len([n for n in self._flattened_nodes if not n.is_ephemeral_model])\n\n    def raise_on_first_error(self) -> bool:\n        return False\n\n    def get_runner_type(self, node) -> Optional[Type[BaseRunner]]:\n        raise NotImplementedError(\"Not Implemented\")\n\n    def result_path(self) -> str:\n        return os.path.join(self.config.project_target_path, RUN_RESULTS_FILE_NAME)\n\n    def get_runner(self, node) -> BaseRunner:\n        adapter = get_adapter(self.config)\n        run_count: int = 0\n        num_nodes: int = 0\n\n        if node.is_ephemeral_model:\n            run_count = 0\n            num_nodes = 0\n        else:\n            self.run_count += 1\n            run_count = self.run_count\n            num_nodes = self.num_nodes\n\n        cls = self.get_runner_type(node)\n\n        if cls is None:\n            raise DbtInternalError(\"Could not find runner type for node.\")\n\n        runner = cls(self.config, adapter, node, run_count, num_nodes)\n        # Propagate selected node IDs to the runner's compiler for FK constraint resolution\n        runner.compiler.selected_node_ids = self.compiler.selected_node_ids\n        return runner\n\n    def call_runner(self, runner: BaseRunner) -> RunResult:\n        with log_contextvars(node_info=runner.node.node_info):\n            runner.node.update_event_status(\n                started_at=datetime.now(timezone.utc).replace(tzinfo=None).isoformat(),\n                node_status=RunningStatus.Started,\n            )\n            fire_event(\n                NodeStart(\n                    node_info=runner.node.node_info,\n                )\n            )\n\n            result = None\n            thread_exception: Optional[Union[KeyboardInterrupt, SystemExit, Exception]] = None\n            try:\n                result = runner.run_with_hooks(self.manifest)\n            except (KeyboardInterrupt, SystemExit) as exe:\n                result = None\n                thread_exception = exe\n                raise\n            except Exception as e:\n                result = None\n                thread_exception = e\n            finally:\n                if result is not None:\n                    try:\n                        fire_event(\n                            NodeFinished(\n                                node_info=runner.node.node_info,\n                                run_result=result.to_msg_dict(),\n                            )\n                        )\n                    except Exception as e:\n                        result = self._handle_thread_exception(runner, e)\n                else:\n                    result = self._handle_thread_exception(runner, thread_exception)\n\n            # `_event_status` dict is only used for logging.  Make sure\n            # it gets deleted when we're done with it\n            runner.node.clear_event_status()\n\n        fail_fast = get_flags().FAIL_FAST\n\n        if (\n            result.status in (NodeStatus.Error, NodeStatus.Fail, NodeStatus.PartialSuccess)\n            and fail_fast\n        ):\n            self._raise_next_tick = FailFastError(\n                msg=\"Failing early due to test failure or runtime error\",\n                result=result,\n                node=getattr(result, \"node\", None),\n            )\n        elif result.status == NodeStatus.Error and self.raise_on_first_error():\n            # if we raise inside a thread, it'll just get silently swallowed.\n            # stash the error message we want here, and it will check the\n            # next 'tick' - should be soon since our thread is about to finish!\n            self._raise_next_tick = DbtRuntimeError(result.message)\n\n        return result\n\n    def _submit(self, pool: DbtThreadPool, args: List[Any], callback: Callable) -> None:\n        \"\"\"If the caller has passed the magic 'single-threaded' flag, call the\n        function directly instead of pool.apply_async. The single-threaded flag\n         is intended for gathering more useful performance information about\n        what happens beneath `call_runner`, since python's default profiling\n        tools ignore child threads.\n\n        This does still go through the callback path for result collection.\n        \"\"\"\n        if self.config.args.single_threaded:\n            callback(self.call_runner(*args))\n        else:\n            pool.apply_async(self.call_runner, args=args, callback=callback)\n\n    def _raise_set_error(self):\n        if self._raise_next_tick is not None:\n            raise self._raise_next_tick\n\n    def run_queue(self, pool: DbtThreadPool) -> None:\n        \"\"\"Given a pool, submit jobs from the queue to the pool.\"\"\"\n        if self.job_queue is None:\n            raise DbtInternalError(\"Got to run_queue with no job queue set\")\n\n        def callback(result):\n            \"\"\"Note: mark_done, at a minimum, must happen here or dbt will\n            deadlock during ephemeral result error handling!\n            \"\"\"\n            self._handle_result(result)\n\n            if self.job_queue is None:\n                raise DbtInternalError(\"Got to run_queue callback with no job queue set\")\n            self.job_queue.mark_done(result.node.unique_id)\n\n        while not self.job_queue.empty():\n            self.handle_job_queue(pool, callback)\n\n        # block on completion\n        if get_flags().FAIL_FAST:\n            # checkout for an errors after task completion in case of\n            # fast failure\n            while self.job_queue.wait_until_something_was_done():\n                self._raise_set_error()\n        else:\n            # wait until every task will be complete\n            self.job_queue.join()\n\n        # if an error got set during join(), raise it.\n        self._raise_set_error()\n\n        return\n\n    # The build command overrides this\n    def handle_job_queue(self, pool: DbtThreadPool, callback: Callable) -> None:\n        assert self.job_queue is not None\n        node = self.job_queue.get()\n        self._raise_set_error()\n        runner = self.get_runner(node)\n        # we finally know what we're running! Make sure we haven't decided\n        # to skip it due to upstream failures\n        if runner.node.unique_id in self._skipped_children:\n            cause = self._skipped_children.pop(runner.node.unique_id)\n            runner.do_skip(cause=cause)\n        args = [runner]\n        self._submit(pool, args, callback)\n\n    def _handle_thread_exception(\n        self,\n        runner: BaseRunner,\n        thread_exception: Optional[Union[KeyboardInterrupt, SystemExit, Exception]],\n    ) -> RunResult:\n        msg = f\"Exception on worker thread. {thread_exception}\"\n        fire_event(\n            GenericExceptionOnRun(\n                unique_id=runner.node.unique_id,\n                exc=str(thread_exception),\n                node_info=runner.node.node_info,\n            )\n        )\n\n        return RunResult(\n            status=RunStatus.Error,  # type: ignore\n            timing=[],\n            thread_id=\"\",\n            execution_time=0.0,\n            adapter_response={},\n            message=msg,\n            failures=None,\n            batch_results=None,\n            node=runner.node,\n        )\n\n    def _handle_result(self, result: RunResult) -> None:\n        \"\"\"Mark the result as completed, insert the `CompileResultNode` into\n        the manifest, and mark any descendants (potentially with a 'cause' if\n        the result was an ephemeral model) as skipped.\n        \"\"\"\n        is_ephemeral = result.node.is_ephemeral_model\n        if not is_ephemeral:\n            self.node_results.append(result)\n\n        node = result.node\n\n        if self.manifest is None:\n            raise DbtInternalError(\"manifest was None in _handle_result\")\n\n        # If result.status == NodeStatus.Error, plus Fail for build command\n        if result.status in self.MARK_DEPENDENT_ERRORS_STATUSES:\n            if is_ephemeral:\n                cause = result\n            else:\n                cause = None\n            self._mark_dependent_errors(node.unique_id, result, cause)\n\n    def _cancel_connections(self, pool):\n        \"\"\"Given a pool, cancel all adapter connections and wait until all\n        runners gentle terminates.\n        \"\"\"\n        pool.close()\n        pool.terminate()\n\n        adapter = get_adapter(self.config)\n\n        if not adapter.is_cancelable():\n            fire_event(QueryCancelationUnsupported(type=adapter.type()))\n        else:\n            with adapter.connection_named(\"master\"):\n                for conn_name in adapter.cancel_open_connections():\n                    if self.manifest is not None:\n                        node = self.manifest.nodes.get(conn_name)\n                        if node is not None and node.is_ephemeral_model:\n                            continue\n                    # if we don't have a manifest/don't have a node, print\n                    # anyway.\n                    fire_event(LogCancelLine(conn_name=conn_name))\n\n        pool.join()\n\n    def execute_nodes(self):\n        num_threads = self.config.threads\n\n        pool = DbtThreadPool(\n            num_threads, self._pool_thread_initializer, [get_invocation_context()]\n        )\n        try:\n            self.run_queue(pool)\n        except FailFastError as failure:\n            self._cancel_connections(pool)\n\n            executed_node_ids = {r.node.unique_id for r in self.node_results}\n            message = \"Skipping due to fail_fast\"\n\n            for node in self._flattened_nodes:\n                if node.unique_id not in executed_node_ids:\n                    self.node_results.append(\n                        mark_node_as_skipped(node, executed_node_ids, message)\n                    )\n\n            print_run_result_error(failure.result)\n            # ensure information about all nodes is propagated to run results when failing fast\n            return self.node_results\n        except (KeyboardInterrupt, SystemExit):\n            run_result = self.get_result(\n                results=self.node_results,\n                elapsed_time=time.time() - self.started_at,\n                generated_at=datetime.now(timezone.utc).replace(tzinfo=None),\n            )\n\n            if self.args.write_json and hasattr(run_result, \"write\"):\n                run_result.write(self.result_path())\n                add_artifact_produced(self.result_path())\n                fire_event(\n                    ArtifactWritten(\n                        artifact_type=run_result.__class__.__name__,\n                        artifact_path=self.result_path(),\n                    )\n                )\n\n            self._cancel_connections(pool)\n            print_run_end_messages(self.node_results, keyboard_interrupt=True)\n\n            raise\n\n        pool.close()\n        pool.join()\n\n        return self.node_results\n\n    @staticmethod\n    def _pool_thread_initializer(invocation_context):\n        _INVOCATION_CONTEXT_VAR.set(invocation_context)\n\n    def _mark_dependent_errors(\n        self, node_id: str, result: RunResult, cause: Optional[RunResult]\n    ) -> None:\n        if self.graph is None:\n            raise DbtInternalError(\"graph is None in _mark_dependent_errors\")\n        fire_event(\n            MarkSkippedChildren(\n                unique_id=node_id,\n                status=result.status,\n                run_result=result.to_msg_dict(),\n            )\n        )\n        for dep_node_id in self.graph.get_dependent_nodes(UniqueId(node_id)):\n            self._skipped_children[dep_node_id] = cause\n\n    def populate_adapter_cache(\n        self, adapter, required_schemas: Optional[Set[BaseRelation]] = None\n    ):\n        if not self.args.populate_cache:\n            return\n\n        if self.manifest is None:\n            raise DbtInternalError(\"manifest was None in populate_adapter_cache\")\n\n        start_populate_cache = time.perf_counter()\n        # the cache only cares about executable nodes\n        cachable_nodes = [\n            node\n            for node in self.manifest.nodes.values()\n            if (node.is_relational and not node.is_ephemeral_model and not node.is_external_node)\n        ]\n\n        if get_flags().CACHE_SELECTED_ONLY is True:\n            adapter.set_relations_cache(cachable_nodes, required_schemas=required_schemas)\n        else:\n            adapter.set_relations_cache(cachable_nodes)\n        cache_populate_time = time.perf_counter() - start_populate_cache\n        if dbt.tracking.active_user is not None:\n            dbt.tracking.track_runnable_timing(\n                {\"adapter_cache_construction_elapsed\": cache_populate_time}\n            )\n\n    def before_run(self, adapter: BaseAdapter, selected_uids: AbstractSet[str]) -> RunStatus:\n        with adapter.connection_named(\"master\"):\n            self.defer_to_manifest()\n            self.populate_adapter_cache(adapter)\n            return RunStatus.Success\n\n    def after_run(self, adapter, results) -> None:\n        pass\n\n    def print_results_line(self, node_results, elapsed):\n        pass\n\n    def execute_with_hooks(self, selected_uids: AbstractSet[str]):\n        adapter = get_adapter(self.config)\n\n        fire_event(Formatting(\"\"))\n        fire_event(\n            ConcurrencyLine(\n                num_threads=self.config.threads,\n                target_name=self.config.target_name,\n                node_count=self.num_nodes,\n            )\n        )\n        fire_event(Formatting(\"\"))\n\n        self.started_at = time.time()\n        try:\n            before_run_status = self.before_run(adapter, selected_uids)\n            if before_run_status == RunStatus.Success or (\n                not get_flags().skip_nodes_if_on_run_start_fails\n            ):\n                res = self.execute_nodes()\n            else:\n                executed_node_ids = {\n                    r.node.unique_id for r in self.node_results if hasattr(r, \"node\")\n                }\n\n                res = []\n\n                for index, node in enumerate(self._flattened_nodes or []):\n                    group = group_lookup.get(node.unique_id)\n\n                    if node.unique_id not in executed_node_ids:\n                        fire_event(\n                            SkippingDetails(\n                                resource_type=node.resource_type,\n                                schema=node.schema,\n                                node_name=node.name,\n                                index=index + 1,\n                                total=self.num_nodes,\n                                node_info=node.node_info,\n                                group=group,\n                            )\n                        )\n                        skipped_node_result = mark_node_as_skipped(node, executed_node_ids, None)\n                        if skipped_node_result:\n                            self.node_results.append(skipped_node_result)\n\n            self.after_run(adapter, res)\n        finally:\n            adapter.cleanup_connections()\n            elapsed = time.time() - self.started_at\n            self.print_results_line(self.node_results, elapsed)\n            result = self.get_result(\n                results=self.node_results,\n                elapsed_time=elapsed,\n                generated_at=datetime.now(timezone.utc).replace(tzinfo=None),\n            )\n\n        return result\n\n    def run(self):\n        \"\"\"\n        Run dbt for the query, based on the graph.\n        \"\"\"\n        # We set up a context manager here with \"task_contextvars\" because we\n        # need the project_root in runtime_initialize.\n        with task_contextvars(project_root=self.config.project_root):\n            self._runtime_initialize()\n\n            if self._flattened_nodes is None:\n                raise DbtInternalError(\n                    \"after _runtime_initialize, _flattened_nodes was still None\"\n                )\n\n            if len(self._flattened_nodes) == 0:\n                warn_or_error(NothingToDo())\n                result = self.get_result(\n                    results=[],\n                    generated_at=datetime.now(timezone.utc).replace(tzinfo=None),\n                    elapsed_time=0.0,\n                )\n            else:\n                selected_uids = frozenset(n.unique_id for n in self._flattened_nodes)\n                result = self.execute_with_hooks(selected_uids)\n\n        # We have other result types here too, including FreshnessResult\n        if isinstance(result, RunExecutionResult):\n            result_msgs = [result.to_msg_dict() for result in result.results]\n            fire_event(\n                EndRunResult(\n                    results=result_msgs,\n                    generated_at=result.generated_at.strftime(\"%Y-%m-%dT%H:%M:%SZ\"),\n                    elapsed_time=result.elapsed_time,\n                    success=GraphRunnableTask.interpret_results(result.results),\n                )\n            )\n\n        if self.args.write_json:\n            write_manifest(self.manifest, self.config.project_target_path)\n            if hasattr(result, \"write\"):\n                result.write(self.result_path())\n                add_artifact_produced(self.result_path())\n                fire_event(\n                    ArtifactWritten(\n                        artifact_type=result.__class__.__name__, artifact_path=self.result_path()\n                    )\n                )\n\n        self.task_end_messages(result.results)\n        return result\n\n    @classmethod\n    def interpret_results(cls, results):\n        if results is None:\n            return False\n\n        num_runtime_errors = len([r for r in results if r.status == NodeStatus.RuntimeErr])\n        num_errors = len([r for r in results if r.status == NodeStatus.Error])\n        num_fails = len([r for r in results if r.status == NodeStatus.Fail])\n        num_skipped = len(\n            [\n                r\n                for r in results\n                if r.status == NodeStatus.Skipped and not isinstance(r.node, Exposure)\n            ]\n        )\n        num_partial_success = len([r for r in results if r.status == NodeStatus.PartialSuccess])\n        num_total = num_runtime_errors + num_errors + num_fails + num_skipped + num_partial_success\n        return num_total == 0\n\n    def get_model_schemas(self, adapter, selected_uids: Iterable[str]) -> Set[BaseRelation]:\n        if self.manifest is None:\n            raise DbtInternalError(\"manifest was None in get_model_schemas\")\n        result: Set[BaseRelation] = set()\n\n        for node in self.manifest.nodes.values():\n            if node.unique_id not in selected_uids:\n                continue\n            if node.is_relational and not node.is_ephemeral:\n                relation = adapter.Relation.create_from(self.config, node)\n                result.add(relation.without_identifier())\n\n        return result\n\n    def create_schemas(self, adapter, required_schemas: Set[BaseRelation]):\n        # we want the string form of the information schema database\n        required_databases: Set[BaseRelation] = set()\n        for required in required_schemas:\n            db_only = required.include(database=True, schema=False, identifier=False)\n            required_databases.add(db_only)\n\n        existing_schemas_lowered: Set[Tuple[Optional[str], Optional[str]]]\n        existing_schemas_lowered = set()\n\n        def list_schemas(db_only: BaseRelation) -> List[Tuple[Optional[str], str]]:\n            # the database can be None on some warehouses that don't support it\n            database_quoted: Optional[str]\n            db_lowercase = dbt_common.utils.formatting.lowercase(db_only.database)\n            if db_only.database is None:\n                database_quoted = None\n            else:\n                database_quoted = str(db_only)\n\n            # we should never create a null schema, so just filter them out\n            return [\n                (db_lowercase, s.lower())\n                for s in adapter.list_schemas(database_quoted)\n                if s is not None\n            ]\n\n        def create_schema(relation: BaseRelation) -> None:\n            db = relation.database or \"\"\n            schema = relation.schema\n            with adapter.connection_named(f\"create_{db}_{schema}\"):\n                adapter.create_schema(relation)\n\n        list_futures = []\n        create_futures = []\n\n        # TODO: following has a mypy issue because profile and project config\n        # defines threads as int and HasThreadingConfig defines it as Optional[int]\n        with dbt_common.utils.executor(self.config) as tpe:  # type: ignore\n            for req in required_databases:\n                if req.database is None:\n                    name = \"list_schemas\"\n                else:\n                    name = f\"list_{req.database}\"\n                fut = tpe.submit_connected(adapter, name, list_schemas, req)\n                list_futures.append(fut)\n\n            for ls_future in as_completed(list_futures):\n                existing_schemas_lowered.update(ls_future.result())\n\n            for info in required_schemas:\n                if info.schema is None:\n                    # we are not in the business of creating null schemas, so\n                    # skip this\n                    continue\n                db: Optional[str] = info.database\n                db_lower: Optional[str] = dbt_common.utils.formatting.lowercase(db)\n                schema: str = info.schema\n\n                db_schema = (db_lower, schema.lower())\n                if db_schema not in existing_schemas_lowered:\n                    existing_schemas_lowered.add(db_schema)\n                    fut = tpe.submit_connected(\n                        adapter, f'create_{info.database or \"\"}_{info.schema}', create_schema, info\n                    )\n                    create_futures.append(fut)\n\n            for create_future in as_completed(create_futures):\n                # trigger/re-raise any exceptions while creating schemas\n                create_future.result()\n\n    def get_result(self, results, elapsed_time, generated_at):\n        return RunExecutionResult(\n            results=results,\n            elapsed_time=elapsed_time,\n            generated_at=generated_at,\n            args=dbt.utils.args_to_dict(self.args),\n        )\n\n    def task_end_messages(self, results) -> None:\n        print_run_end_messages(results)\n\n    def _get_previous_state(self) -> Optional[Manifest]:\n        state = self.previous_defer_state or self.previous_state\n        if not state:\n            raise DbtRuntimeError(\n                \"--state or --defer-state are required for deferral, but neither was provided\"\n            )\n\n        if not state.manifest:\n            raise DbtRuntimeError(f'Could not find manifest in --state path: \"{state.state_path}\"')\n        return state.manifest\n\n    def _get_deferred_manifest(self) -> Optional[Manifest]:\n        return self._get_previous_state() if self.args.defer else None\n"
  },
  {
    "path": "core/dbt/task/seed.py",
    "content": "import random\nfrom typing import Optional, Type\n\nfrom dbt.artifacts.schemas.results import NodeStatus, RunStatus\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.events.types import LogSeedResult, LogStartLine, SeedHeader\nfrom dbt.graph import ResourceTypeSelector\nfrom dbt.node_types import NodeType\nfrom dbt.task import group_lookup\nfrom dbt.task.base import BaseRunner\nfrom dbt.task.printer import print_run_end_messages\nfrom dbt.task.run import ModelRunner, RunTask\nfrom dbt_common.events.base_types import EventLevel\nfrom dbt_common.events.functions import fire_event\nfrom dbt_common.events.types import Formatting\nfrom dbt_common.exceptions import DbtInternalError\n\n\nclass SeedRunner(ModelRunner):\n    def describe_node(self) -> str:\n        return \"seed file {}\".format(self.get_node_representation())\n\n    def before_execute(self) -> None:\n        fire_event(\n            LogStartLine(\n                description=self.describe_node(),\n                index=self.node_index,\n                total=self.num_nodes,\n                node_info=self.node.node_info,\n            )\n        )\n\n    def _build_run_model_result(self, model, context):\n        result = super()._build_run_model_result(model, context)\n        agate_result = context[\"load_result\"](\"agate_table\")\n        result.agate_table = agate_result.table\n        return result\n\n    def compile(self, manifest: Manifest):\n        return self.node\n\n    def print_result_line(self, result):\n        model = result.node\n        group = group_lookup.get(model.unique_id)\n        level = EventLevel.ERROR if result.status == NodeStatus.Error else EventLevel.INFO\n        fire_event(\n            LogSeedResult(\n                status=result.status,\n                result_message=result.message,\n                index=self.node_index,\n                total=self.num_nodes,\n                execution_time=result.execution_time,\n                schema=self.node.schema,\n                relation=model.alias,\n                node_info=model.node_info,\n                group=group,\n            ),\n            level=level,\n        )\n\n\nclass SeedTask(RunTask):\n    def raise_on_first_error(self) -> bool:\n        return False\n\n    def get_node_selector(self):\n        if self.manifest is None or self.graph is None:\n            raise DbtInternalError(\"manifest and graph must be set to get perform node selection\")\n        return ResourceTypeSelector(\n            graph=self.graph,\n            manifest=self.manifest,\n            previous_state=self.previous_state,\n            resource_types=[NodeType.Seed],\n            selectors=self.config.selectors,\n        )\n\n    def get_runner_type(self, _) -> Optional[Type[BaseRunner]]:\n        return SeedRunner\n\n    def task_end_messages(self, results) -> None:\n        if self.args.show:\n            self.show_tables(results)\n\n        print_run_end_messages(results)\n\n    def show_table(self, result):\n        table = result.agate_table\n        rand_table = table.order_by(lambda x: random.random())\n\n        schema = result.node.schema\n        alias = result.node.alias\n\n        header = \"Random sample of table: {}.{}\".format(schema, alias)\n        fire_event(Formatting(\"\"))\n        fire_event(SeedHeader(header=header))\n        fire_event(Formatting(\"-\" * len(header)))\n\n        rand_table.print_table(max_rows=10, max_columns=None)\n        fire_event(Formatting(\"\"))\n\n    def show_tables(self, results):\n        for result in results:\n            if result.status != RunStatus.Error:\n                self.show_table(result)\n"
  },
  {
    "path": "core/dbt/task/show.py",
    "content": "import io\nimport threading\nimport time\n\nfrom dbt.adapters.factory import get_adapter\nfrom dbt.artifacts.schemas.run import RunResult, RunStatus\nfrom dbt.context.providers import generate_runtime_model_context\nfrom dbt.contracts.graph.nodes import SeedNode\nfrom dbt.events.types import ShowNode\nfrom dbt.flags import get_flags\nfrom dbt.task.base import ConfiguredTask\nfrom dbt.task.compile import CompileRunner, CompileTask\nfrom dbt.task.seed import SeedRunner\nfrom dbt_common.events.base_types import EventLevel\nfrom dbt_common.events.functions import fire_event\nfrom dbt_common.events.types import Note\nfrom dbt_common.exceptions import DbtRuntimeError\n\n\nclass ShowRunner(CompileRunner):\n    def __init__(self, config, adapter, node, node_index, num_nodes) -> None:\n        super().__init__(config, adapter, node, node_index, num_nodes)\n        self.run_ephemeral_models = True\n\n    def execute(self, compiled_node, manifest):\n        start_time = time.time()\n\n        # Allow passing in -1 (or any negative number) to get all rows\n        limit = None if self.config.args.limit < 0 else self.config.args.limit\n\n        model_context = generate_runtime_model_context(compiled_node, self.config, manifest)\n        compiled_node.compiled_code = self.adapter.execute_macro(\n            macro_name=\"get_show_sql\",\n            macro_resolver=manifest,\n            context_override=model_context,\n            kwargs={\n                \"compiled_code\": model_context[\"compiled_code\"],\n                \"sql_header\": model_context[\"config\"].get(\"sql_header\"),\n                \"limit\": limit,\n            },\n        )\n        adapter_response, execute_result = self.adapter.execute(\n            compiled_node.compiled_code, fetch=True\n        )\n\n        end_time = time.time()\n\n        return RunResult(\n            node=compiled_node,\n            status=RunStatus.Success,\n            timing=[],\n            thread_id=threading.current_thread().name,\n            execution_time=end_time - start_time,\n            message=None,\n            adapter_response=adapter_response.to_dict(),\n            agate_table=execute_result,\n            failures=None,\n            batch_results=None,\n        )\n\n\nclass ShowTask(CompileTask):\n    def _runtime_initialize(self):\n        if not (self.args.select or getattr(self.args, \"inline\", None)):\n            raise DbtRuntimeError(\"Either --select or --inline must be passed to show\")\n        super()._runtime_initialize()\n\n    def get_runner_type(self, node):\n        if isinstance(node, SeedNode):\n            return SeedRunner\n        else:\n            return ShowRunner\n\n    def task_end_messages(self, results) -> None:\n        is_inline = bool(getattr(self.args, \"inline\", None))\n\n        if is_inline:\n            matched_results = [result for result in results if result.node.name == \"inline_query\"]\n        else:\n            matched_results = []\n            for result in results:\n                if result.node.name in self.selection_arg[0]:\n                    matched_results.append(result)\n                else:\n                    fire_event(\n                        Note(msg=f\"Excluded node '{result.node.name}' from results\"),\n                        EventLevel.DEBUG,\n                    )\n\n        for result in matched_results:\n            table = result.agate_table\n\n            # Hack to get Agate table output as string\n            output = io.StringIO()\n            if self.args.output == \"json\":\n                table.to_json(path=output)\n            else:\n                table.print_table(output=output, max_rows=None)\n\n            node_name = result.node.name\n\n            if hasattr(result.node, \"version\") and result.node.version:\n                node_name += f\".v{result.node.version}\"\n\n            fire_event(\n                ShowNode(\n                    node_name=node_name,\n                    preview=output.getvalue(),\n                    is_inline=is_inline,\n                    output_format=self.args.output,\n                    unique_id=result.node.unique_id,\n                    quiet=get_flags().QUIET,\n                )\n            )\n\n    def _handle_result(self, result) -> None:\n        super()._handle_result(result)\n\n        if (\n            result.node.is_ephemeral_model\n            and type(self) is ShowTask\n            and (self.args.select or getattr(self.args, \"inline\", None))\n        ):\n            self.node_results.append(result)\n\n\nclass ShowTaskDirect(ConfiguredTask):\n    def run(self):\n        adapter = get_adapter(self.config)\n        with adapter.connection_named(\"show\", should_release_connection=False):\n            limit = None if self.args.limit < 0 else self.args.limit\n            response, table = adapter.execute(self.args.inline_direct, fetch=True, limit=limit)\n\n            output = io.StringIO()\n            if self.args.output == \"json\":\n                table.to_json(path=output)\n            else:\n                table.print_table(output=output, max_rows=None)\n\n            fire_event(\n                ShowNode(\n                    node_name=\"direct-query\",\n                    preview=output.getvalue(),\n                    is_inline=True,\n                    output_format=self.args.output,\n                    unique_id=\"direct-query\",\n                    quiet=get_flags().QUIET,\n                )\n            )\n"
  },
  {
    "path": "core/dbt/task/snapshot.py",
    "content": "from typing import Optional, Type\n\nfrom dbt.artifacts.schemas.results import NodeStatus\nfrom dbt.events.types import LogSnapshotResult\nfrom dbt.graph import ResourceTypeSelector\nfrom dbt.node_types import NodeType\nfrom dbt.task import group_lookup\nfrom dbt.task.base import BaseRunner\nfrom dbt.task.run import ModelRunner, RunTask\nfrom dbt_common.events.base_types import EventLevel\nfrom dbt_common.events.functions import fire_event\nfrom dbt_common.exceptions import DbtInternalError\nfrom dbt_common.utils import cast_dict_to_dict_of_strings\n\n\nclass SnapshotRunner(ModelRunner):\n    def describe_node(self) -> str:\n        return \"snapshot {}\".format(self.get_node_representation())\n\n    def print_result_line(self, result):\n        model = result.node\n        group = group_lookup.get(model.unique_id)\n        cfg = model.config.to_dict(omit_none=True)\n        level = EventLevel.ERROR if result.status == NodeStatus.Error else EventLevel.INFO\n        fire_event(\n            LogSnapshotResult(\n                status=result.status,\n                description=self.get_node_representation(),\n                cfg=cast_dict_to_dict_of_strings(cfg),\n                index=self.node_index,\n                total=self.num_nodes,\n                execution_time=result.execution_time,\n                node_info=model.node_info,\n                result_message=result.message,\n                group=group,\n            ),\n            level=level,\n        )\n\n\nclass SnapshotTask(RunTask):\n    def raise_on_first_error(self) -> bool:\n        return False\n\n    def get_node_selector(self):\n        if self.manifest is None or self.graph is None:\n            raise DbtInternalError(\"manifest and graph must be set to get perform node selection\")\n        return ResourceTypeSelector(\n            graph=self.graph,\n            manifest=self.manifest,\n            previous_state=self.previous_state,\n            resource_types=[NodeType.Snapshot],\n            selectors=self.config.selectors,\n        )\n\n    def get_runner_type(self, _) -> Optional[Type[BaseRunner]]:\n        return SnapshotRunner\n"
  },
  {
    "path": "core/dbt/task/sql.py",
    "content": "import traceback\nfrom abc import abstractmethod\nfrom datetime import datetime, timezone\nfrom typing import Generic, TypeVar\n\nimport dbt.exceptions\nimport dbt_common.exceptions.base\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.contracts.sql import (\n    RemoteCompileResult,\n    RemoteCompileResultMixin,\n    RemoteRunResult,\n    ResultTable,\n)\nfrom dbt.events.types import SQLRunnerException\nfrom dbt.task.compile import CompileRunner\nfrom dbt_common.events.functions import fire_event\n\nSQLResult = TypeVar(\"SQLResult\", bound=RemoteCompileResultMixin)\n\n\nclass GenericSqlRunner(CompileRunner, Generic[SQLResult]):\n    def __init__(self, config, adapter, node, node_index, num_nodes) -> None:\n        CompileRunner.__init__(self, config, adapter, node, node_index, num_nodes)\n\n    def handle_exception(self, e, ctx):\n        fire_event(\n            SQLRunnerException(\n                exc=str(e), exc_info=traceback.format_exc(), node_info=self.node.node_info\n            )\n        )\n        # REVIEW: This code is invalid and will always throw.\n        if isinstance(e, dbt.exceptions.Exception):\n            if isinstance(e, dbt_common.exceptions.DbtRuntimeError):\n                e.add_node(ctx.node)\n            return e\n\n    def before_execute(self) -> None:\n        pass\n\n    def after_execute(self, result) -> None:\n        pass\n\n    def compile(self, manifest: Manifest):\n        return self.compiler.compile_node(self.node, manifest, {}, write=False)\n\n    @abstractmethod\n    def execute(self, compiled_node, manifest) -> SQLResult:\n        pass\n\n    @abstractmethod\n    def from_run_result(self, result, start_time, timing_info) -> SQLResult:\n        pass\n\n    def error_result(self, node, error, start_time, timing_info):\n        raise error\n\n    def ephemeral_result(self, node, start_time, timing_info):\n        raise dbt_common.exceptions.base.NotImplementedError(\n            \"cannot execute ephemeral nodes remotely!\"\n        )\n\n\nclass SqlCompileRunner(GenericSqlRunner[RemoteCompileResult]):\n    def execute(self, compiled_node, manifest) -> RemoteCompileResult:\n        return RemoteCompileResult(\n            raw_code=compiled_node.raw_code,\n            compiled_code=compiled_node.compiled_code,\n            node=compiled_node,\n            timing=[],  # this will get added later\n            generated_at=datetime.now(timezone.utc).replace(tzinfo=None),\n        )\n\n    def from_run_result(self, result, start_time, timing_info) -> RemoteCompileResult:\n        return RemoteCompileResult(\n            raw_code=result.raw_code,\n            compiled_code=result.compiled_code,\n            node=result.node,\n            timing=timing_info,\n            generated_at=datetime.now(timezone.utc).replace(tzinfo=None),\n        )\n\n\nclass SqlExecuteRunner(GenericSqlRunner[RemoteRunResult]):\n    def execute(self, compiled_node, manifest) -> RemoteRunResult:\n        _, execute_result = self.adapter.execute(compiled_node.compiled_code, fetch=True)\n\n        table = ResultTable(\n            column_names=list(execute_result.column_names),\n            rows=[list(row) for row in execute_result],\n        )\n\n        return RemoteRunResult(\n            raw_code=compiled_node.raw_code,\n            compiled_code=compiled_node.compiled_code,\n            node=compiled_node,\n            table=table,\n            timing=[],\n            generated_at=datetime.now(timezone.utc).replace(tzinfo=None),\n        )\n\n    def from_run_result(self, result, start_time, timing_info) -> RemoteRunResult:\n        return RemoteRunResult(\n            raw_code=result.raw_code,\n            compiled_code=result.compiled_code,\n            node=result.node,\n            table=result.table,\n            timing=timing_info,\n            generated_at=datetime.now(timezone.utc).replace(tzinfo=None),\n        )\n"
  },
  {
    "path": "core/dbt/task/test.py",
    "content": "import io\nimport json\nimport re\nimport threading\nfrom dataclasses import dataclass\nfrom typing import (\n    TYPE_CHECKING,\n    Any,\n    Collection,\n    Dict,\n    List,\n    Optional,\n    Tuple,\n    Type,\n    Union,\n)\n\nimport daff\n\nfrom dbt.adapters.exceptions import MissingMaterializationError\nfrom dbt.artifacts.schemas.catalog import PrimitiveDict\nfrom dbt.artifacts.schemas.results import TestStatus\nfrom dbt.artifacts.schemas.run import RunResult\nfrom dbt.clients.jinja import MacroGenerator\nfrom dbt.context.providers import generate_runtime_model_context\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.contracts.graph.nodes import (\n    GenericTestNode,\n    SingularTestNode,\n    TestNode,\n    UnitTestDefinition,\n    UnitTestNode,\n)\nfrom dbt.events.types import LogStartLine, LogTestResult\nfrom dbt.exceptions import BooleanError, DbtInternalError\nfrom dbt.flags import get_flags\nfrom dbt.graph import ResourceTypeSelector\nfrom dbt.node_types import TEST_NODE_TYPES, NodeType\nfrom dbt.parser.unit_tests import UnitTestManifestLoader\nfrom dbt.task import group_lookup\nfrom dbt.task.base import BaseRunner, resource_types_from_args\nfrom dbt.task.compile import CompileRunner\nfrom dbt.task.run import RunTask\nfrom dbt.utils import _coerce_decimal, strtobool\nfrom dbt_common.dataclass_schema import dbtClassMixin\nfrom dbt_common.events.format import pluralize\nfrom dbt_common.events.functions import fire_event\nfrom dbt_common.exceptions import DbtBaseException, DbtRuntimeError\nfrom dbt_common.ui import green, red\n\nif TYPE_CHECKING:\n    import agate\n\n\n@dataclass\nclass UnitTestDiff(dbtClassMixin):\n    actual: List[Dict[str, Any]]\n    expected: List[Dict[str, Any]]\n    rendered: str\n\n\n@dataclass\nclass TestResultData(dbtClassMixin):\n    failures: int\n    should_warn: bool\n    should_error: bool\n    adapter_response: Dict[str, Any]\n\n    @classmethod\n    def validate(cls, data):\n        data[\"should_warn\"] = cls.convert_bool_type(data[\"should_warn\"])\n        data[\"should_error\"] = cls.convert_bool_type(data[\"should_error\"])\n        super().validate(data)\n\n    def convert_bool_type(field) -> bool:\n        # if it's type string let python decide if it's a valid value to convert to bool\n        if isinstance(field, str):\n            try:\n                return bool(strtobool(field))  # type: ignore\n            except ValueError:\n                raise BooleanError(field, \"get_test_sql\")\n\n        # need this so we catch both true bools and 0/1\n        return bool(field)\n\n\n@dataclass\nclass UnitTestResultData(dbtClassMixin):\n    should_error: bool\n    adapter_response: Dict[str, Any]\n    diff: Optional[UnitTestDiff] = None\n\n\nclass TestRunner(CompileRunner):\n    _ANSI_ESCAPE = re.compile(r\"\\x1B(?:[@-Z\\\\-_]|\\[[0-?]*[ -/]*[@-~])\")\n\n    def describe_node_name(self) -> str:\n        if self.node.resource_type == NodeType.Unit:\n            name = f\"{self.node.model}::{self.node.versioned_name}\"\n            return name\n        else:\n            return self.node.name\n\n    def describe_node(self) -> str:\n        return f\"{self.node.resource_type} {self.describe_node_name()}\"\n\n    def print_result_line(self, result):\n        model = result.node\n        group = group_lookup.get(model.unique_id)\n        attached_node = (\n            result.node.attached_node if isinstance(result.node, GenericTestNode) else None\n        )\n\n        fire_event(\n            LogTestResult(\n                name=self.describe_node_name(),\n                status=str(result.status),\n                index=self.node_index,\n                num_models=self.num_nodes,\n                execution_time=result.execution_time,\n                node_info=model.node_info,\n                num_failures=result.failures,\n                group=group,\n                attached_node=attached_node,\n            ),\n            level=LogTestResult.status_to_level(str(result.status)),\n        )\n\n    def print_start_line(self):\n        fire_event(\n            LogStartLine(\n                description=self.describe_node(),\n                index=self.node_index,\n                total=self.num_nodes,\n                node_info=self.node.node_info,\n            )\n        )\n\n    def before_execute(self) -> None:\n        self.print_start_line()\n\n    def execute_data_test(self, data_test: TestNode, manifest: Manifest) -> TestResultData:\n        context = generate_runtime_model_context(data_test, self.config, manifest)\n\n        hook_ctx = self.adapter.pre_model_hook(context[\"config\"])\n\n        materialization_macro = manifest.find_materialization_macro_by_name(\n            self.config.project_name, data_test.get_materialization(), self.adapter.type()\n        )\n\n        if materialization_macro is None:\n            raise MissingMaterializationError(\n                materialization=data_test.get_materialization(), adapter_type=self.adapter.type()\n            )\n\n        if \"config\" not in context:\n            raise DbtInternalError(\n                \"Invalid materialization context generated, missing config: {}\".format(context)\n            )\n\n        # generate materialization macro\n        macro_func = MacroGenerator(materialization_macro, context)\n        try:\n            # execute materialization macro\n            macro_func()\n        finally:\n            self.adapter.post_model_hook(context, hook_ctx)\n\n        # load results from context\n        # could eventually be returned directly by materialization\n        result = context[\"load_result\"](\"main\")\n        table = result[\"table\"]\n        num_rows = len(table.rows)\n        if num_rows != 1:\n            raise DbtInternalError(\n                f\"dbt internally failed to execute {data_test.unique_id}: \"\n                f\"Returned {num_rows} rows, but expected \"\n                f\"1 row\"\n            )\n        num_cols = len(table.columns)\n        if num_cols != 3:\n            raise DbtInternalError(\n                f\"dbt internally failed to execute {data_test.unique_id}: \"\n                f\"Returned {num_cols} columns, but expected \"\n                f\"3 columns\"\n            )\n\n        test_result_dct: PrimitiveDict = dict(\n            zip(\n                [column_name.lower() for column_name in table.column_names],\n                map(_coerce_decimal, table.rows[0]),\n            )\n        )\n        test_result_dct[\"adapter_response\"] = result[\"response\"].to_dict(omit_none=True)\n        TestResultData.validate(test_result_dct)\n        return TestResultData.from_dict(test_result_dct)\n\n    def build_unit_test_manifest_from_test(\n        self, unit_test_def: UnitTestDefinition, manifest: Manifest\n    ) -> Manifest:\n        # build a unit test manifest with only the test from this UnitTestDefinition\n        loader = UnitTestManifestLoader(manifest, self.config, {unit_test_def.unique_id})\n        return loader.load()\n\n    def execute_unit_test(\n        self, unit_test_def: UnitTestDefinition, manifest: Manifest\n    ) -> Tuple[UnitTestNode, UnitTestResultData]:\n\n        unit_test_manifest = self.build_unit_test_manifest_from_test(unit_test_def, manifest)\n\n        # The unit test node and definition have the same unique_id\n        unit_test_node = unit_test_manifest.nodes[unit_test_def.unique_id]\n        assert isinstance(unit_test_node, UnitTestNode)\n\n        # Compile the node\n        unit_test_node = self.compiler.compile_node(unit_test_node, unit_test_manifest, {})\n        assert isinstance(unit_test_node, UnitTestNode)\n\n        # generate_runtime_unit_test_context not strictly needed - this is to run the 'unit'\n        # materialization, not compile the node.compiled_code\n        context = generate_runtime_model_context(unit_test_node, self.config, unit_test_manifest)\n\n        hook_ctx = self.adapter.pre_model_hook(context[\"config\"])\n\n        materialization_macro = unit_test_manifest.find_materialization_macro_by_name(\n            self.config.project_name, unit_test_node.get_materialization(), self.adapter.type()\n        )\n\n        if materialization_macro is None:\n            raise MissingMaterializationError(\n                materialization=unit_test_node.get_materialization(),\n                adapter_type=self.adapter.type(),\n            )\n\n        if \"config\" not in context:\n            raise DbtInternalError(\n                \"Invalid materialization context generated, missing config: {}\".format(context)\n            )\n\n        # generate materialization macro\n        macro_func = MacroGenerator(materialization_macro, context)\n        try:\n            # execute materialization macro\n            macro_func()\n        except DbtBaseException as e:\n            raise DbtRuntimeError(\n                f\"An error occurred during execution of unit test '{unit_test_def.name}'. \"\n                f\"There may be an error in the unit test definition: check the data types.\\n {e}\"\n            )\n        finally:\n            self.adapter.post_model_hook(context, hook_ctx)\n\n        # load results from context\n        # could eventually be returned directly by materialization\n        result = context[\"load_result\"](\"main\")\n        adapter_response = result[\"response\"].to_dict(omit_none=True)\n        table = result[\"table\"]\n        actual = self._get_unit_test_agate_table(table, \"actual\")\n        expected = self._get_unit_test_agate_table(table, \"expected\")\n\n        # generate diff, if exists\n        should_error, diff = False, None\n        daff_diff = self._get_daff_diff(expected, actual)\n        if daff_diff.hasDifference():\n            should_error = True\n            rendered = self._render_daff_diff(daff_diff)\n            rendered = f\"\\n\\n{green('actual')} differs from {red('expected')}:\\n\\n{rendered}\\n\"\n\n            diff = UnitTestDiff(\n                actual=json_rows_from_table(actual),\n                expected=json_rows_from_table(expected),\n                rendered=rendered,\n            )\n\n        unit_test_result_data = UnitTestResultData(\n            diff=diff,\n            should_error=should_error,\n            adapter_response=adapter_response,\n        )\n\n        return unit_test_node, unit_test_result_data\n\n    def execute(self, test: Union[TestNode, UnitTestNode], manifest: Manifest):\n        if isinstance(test, UnitTestDefinition):\n            unit_test_node, unit_test_result = self.execute_unit_test(test, manifest)\n            return self.build_unit_test_run_result(unit_test_node, unit_test_result)\n        else:\n            # Note: manifest here is a normal manifest\n            assert isinstance(test, (SingularTestNode, GenericTestNode))\n            test_result = self.execute_data_test(test, manifest)\n            return self.build_test_run_result(test, test_result)\n\n    def build_test_run_result(self, test: TestNode, result: TestResultData) -> RunResult:\n        severity = test.config.severity.upper()\n        thread_id = threading.current_thread().name\n        num_errors = pluralize(result.failures, \"result\")\n        status = None\n        message = None\n        failures = 0\n        if severity == \"ERROR\" and result.should_error:\n            status = TestStatus.Fail\n            message = f\"Got {num_errors}, configured to fail if {test.config.error_if}\"\n            failures = result.failures\n        elif result.should_warn:\n            if get_flags().WARN_ERROR or get_flags().WARN_ERROR_OPTIONS.includes(\n                LogTestResult.__name__\n            ):\n                status = TestStatus.Fail\n                message = f\"Got {num_errors}, configured to fail if {test.config.warn_if}\"\n            else:\n                status = TestStatus.Warn\n                message = f\"Got {num_errors}, configured to warn if {test.config.warn_if}\"\n            failures = result.failures\n        else:\n            status = TestStatus.Pass\n\n        run_result = RunResult(\n            node=test,\n            status=status,\n            timing=[],\n            thread_id=thread_id,\n            execution_time=0,\n            message=message,\n            adapter_response=result.adapter_response,\n            failures=failures,\n            batch_results=None,\n        )\n        return run_result\n\n    def build_unit_test_run_result(\n        self, test: UnitTestNode, result: UnitTestResultData\n    ) -> RunResult:\n        thread_id = threading.current_thread().name\n\n        status = TestStatus.Pass\n        message = None\n        failures = 0\n        if result.should_error:\n            status = TestStatus.Fail\n            message = result.diff.rendered if result.diff else None\n            failures = 1\n\n        return RunResult(\n            node=test,\n            status=status,\n            timing=[],\n            thread_id=thread_id,\n            execution_time=0,\n            message=message,\n            adapter_response=result.adapter_response,\n            failures=failures,\n            batch_results=None,\n        )\n\n    def after_execute(self, result) -> None:\n        self.print_result_line(result)\n\n    def _get_unit_test_agate_table(self, result_table, actual_or_expected: str):\n        # lower case the column names as platforms like snowflake can sometimes return columns in uppercase\n        result_table = result_table.rename([col.lower() for col in result_table.column_names])\n        unit_test_table = result_table.where(\n            lambda row: row[\"actual_or_expected\"] == actual_or_expected\n        )\n        columns = list(unit_test_table.columns.keys())\n        columns.remove(\"actual_or_expected\")\n        return unit_test_table.select(columns)\n\n    def _get_daff_diff(\n        self, expected: \"agate.Table\", actual: \"agate.Table\", ordered: bool = False\n    ) -> daff.TableDiff:\n        # Sort expected and actual inputs prior to creating daff diff to ensure order insensitivity\n        # https://github.com/paulfitz/daff/issues/200\n        expected_daff_table = daff.PythonTableView(list_rows_from_table(expected, sort=True))\n        actual_daff_table = daff.PythonTableView(list_rows_from_table(actual, sort=True))\n\n        flags = daff.CompareFlags()\n        flags.ordered = ordered\n\n        alignment = daff.Coopy.compareTables(expected_daff_table, actual_daff_table, flags).align()\n        result = daff.PythonTableView([])\n\n        diff = daff.TableDiff(alignment, flags)\n        diff.hilite(result)\n        return diff\n\n    def _render_daff_diff(self, daff_diff: daff.TableDiff) -> str:\n        result = daff.PythonTableView([])\n        daff_diff.hilite(result)\n        rendered = daff.TerminalDiffRender().render(result)\n        # strip colors if necessary\n        if not self.config.args.use_colors:\n            rendered = self._ANSI_ESCAPE.sub(\"\", rendered)\n\n        return rendered\n\n\nclass TestTask(RunTask):\n    \"\"\"\n    Testing:\n        Read schema files + custom data tests and validate that\n        constraints are satisfied.\n    \"\"\"\n\n    __test__ = False\n\n    def raise_on_first_error(self) -> bool:\n        return False\n\n    @property\n    def resource_types(self) -> List[NodeType]:\n        resource_types: Collection[NodeType] = resource_types_from_args(\n            self.args, set(TEST_NODE_TYPES), set(TEST_NODE_TYPES)\n        )\n\n        # filter out any non-test node types\n        resource_types = [rt for rt in resource_types if rt in TEST_NODE_TYPES]\n        return list(resource_types)\n\n    def get_node_selector(self) -> ResourceTypeSelector:\n        if self.manifest is None or self.graph is None:\n            raise DbtInternalError(\"manifest and graph must be set to get perform node selection\")\n        return ResourceTypeSelector(\n            graph=self.graph,\n            manifest=self.manifest,\n            previous_state=self.previous_state,\n            resource_types=self.resource_types,\n            selectors=self.config.selectors,\n        )\n\n    def get_runner_type(self, _) -> Optional[Type[BaseRunner]]:\n        return TestRunner\n\n\n# This was originally in agate_helper, but that was moved out into dbt_common\ndef json_rows_from_table(table: \"agate.Table\") -> List[Dict[str, Any]]:\n    \"Convert a table to a list of row dict objects\"\n    output = io.StringIO()\n    table.to_json(path=output)  # type: ignore\n\n    return json.loads(output.getvalue())\n\n\n# This was originally in agate_helper, but that was moved out into dbt_common\ndef list_rows_from_table(table: \"agate.Table\", sort: bool = False) -> List[Any]:\n    \"\"\"\n    Convert given table to a list of lists, where the first element represents the header\n\n    By default, sort is False and no sort order is applied to the non-header rows of the given table.\n\n    If sort is True, sort the non-header rows hierarchically, treating None values as lower in order.\n    Examples:\n        * [['a','b','c'],[4,5,6],[1,2,3]] -> [['a','b','c'],[1,2,3],[4,5,6]]\n        * [['a','b','c'],[4,5,6],[1,null,3]] -> [['a','b','c'],[1,null,3],[4,5,6]]\n        * [['a','b','c'],[4,5,6],[null,2,3]] -> [['a','b','c'],[4,5,6],[null,2,3]]\n    \"\"\"\n    header = [col.name for col in table.columns]\n\n    rows = []\n    for row in table.rows:\n        rows.append(list(row.values()))\n\n    if sort:\n        rows = sorted(rows, key=lambda x: [(elem is None, elem) for elem in x])\n\n    return [header] + rows\n"
  },
  {
    "path": "core/dbt/tests/fixtures/__init__.py",
    "content": "# dbt.tests.fixtures directory\n"
  },
  {
    "path": "core/dbt/tests/fixtures/project.py",
    "content": "import os\nimport random\nfrom argparse import Namespace\nfrom datetime import datetime, timezone\nfrom pathlib import Path\nfrom typing import Dict, Mapping\n\nimport pytest  # type: ignore\nimport yaml\n\nimport dbt.flags as flags\nfrom dbt.adapters.factory import (\n    get_adapter,\n    get_adapter_by_type,\n    register_adapter,\n    reset_adapters,\n)\nfrom dbt.config.runtime import RuntimeConfig\nfrom dbt.context.providers import generate_runtime_macro_context\nfrom dbt.deprecations import reset_deprecations\nfrom dbt.events.logging import setup_event_logger\nfrom dbt.mp_context import get_mp_context\nfrom dbt.parser.manifest import ManifestLoader\nfrom dbt.tests.util import (\n    TestProcessingException,\n    get_connection,\n    run_sql_with_adapter,\n    write_file,\n)\nfrom dbt_common.context import set_invocation_context\nfrom dbt_common.events.event_manager_client import cleanup_event_logger\nfrom dbt_common.exceptions import CompilationError, DbtDatabaseError\nfrom dbt_common.tests import enable_test_caching\n\n# These are the fixtures that are used in dbt core functional tests\n#\n# The main functional test fixture is the 'project' fixture, which combines\n# other fixtures, writes out a dbt project in a temporary directory, creates a temp\n# schema in the testing database, and returns a `TestProjInfo` object that\n# contains information from the other fixtures for convenience.\n#\n# The models, macros, seeds, snapshots, tests, and analyses fixtures all\n# represent directories in a dbt project, and are all dictionaries with\n# file name keys and file contents values.\n#\n# The other commonly used fixture is 'project_config_update'. Other\n# occasionally used fixtures are 'profiles_config_update', 'packages',\n# and 'selectors'.\n#\n# Most test cases have fairly small files which are best included in\n# the test case file itself as string variables, to make it easy to\n# understand what is happening in the test. Files which are used\n# in multiple test case files can be included in a common file, such as\n# files.py or fixtures.py. Large files, such as seed files, which would\n# just clutter the test file can be pulled in from 'data' subdirectories\n# in the test directory.\n#\n# Test logs are written in the 'logs' directory in the root of the repo.\n# Every test case writes to a log directory with the same 'prefix' as the\n# test's unique schema.\n#\n# These fixture have \"class\" scope. Class scope fixtures can be used both\n# in classes and in single test functions (which act as classes for this\n# purpose). Pytest will collect all classes starting with 'Test', so if\n# you have a class that you want to be subclassed, it's generally best to\n# not start the class name with 'Test'. All standalone functions starting with\n# 'test_' and methods in classes starting with 'test_' (in classes starting\n# with 'Test') will be collected.\n#\n# Please see the pytest docs for further information:\n#     https://docs.pytest.org\n\n\n# Used in constructing the unique_schema and logs_dir\n@pytest.fixture(scope=\"class\")\ndef prefix():\n    # create a directory name that will be unique per test session\n    _randint = random.randint(0, 9999)\n    _runtime_timedelta = datetime.now(timezone.utc).replace(tzinfo=None) - datetime(\n        1970, 1, 1, 0, 0, 0\n    )\n    _runtime = (int(_runtime_timedelta.total_seconds() * 1e6)) + _runtime_timedelta.microseconds\n    prefix = f\"test{_runtime}{_randint:04}\"\n    return prefix\n\n\n# Every test has a unique schema\n@pytest.fixture(scope=\"class\")\ndef unique_schema(request, prefix) -> str:\n    test_file = request.module.__name__\n    # We only want the last part of the name\n    test_file = test_file.split(\".\")[-1]\n    unique_schema = f\"{prefix}_{test_file}\"\n    return unique_schema\n\n\n# Create a directory for the profile using tmpdir fixture\n@pytest.fixture(scope=\"class\")\ndef profiles_root(tmpdir_factory):\n    return tmpdir_factory.mktemp(\"profile\")\n\n\n# Create a directory for the project using tmpdir fixture\n@pytest.fixture(scope=\"class\")\ndef project_root(tmpdir_factory):\n    # tmpdir docs - https://docs.pytest.org/en/6.2.x/tmpdir.html\n    project_root = tmpdir_factory.mktemp(\"project\")\n    print(f\"\\n=== Test project_root: {project_root}\")\n    return project_root\n\n\n# This is for data used by multiple tests, in the 'tests/data' directory\n@pytest.fixture(scope=\"session\")\ndef shared_data_dir(request):\n    return os.path.join(request.config.rootdir, \"tests\", \"data\")\n\n\n# This is for data for a specific test directory, i.e. tests/basic/data\n@pytest.fixture(scope=\"module\")\ndef test_data_dir(request):\n    return os.path.join(request.fspath.dirname, \"data\")\n\n\n# This contains the profile target information, for simplicity in setting\n# up different profiles, particularly in the adapter repos.\n# Note: because we load the profile to create the adapter, this\n# fixture can't be used to test vars and env_vars or errors. The\n# profile must be written out after the test starts.\n@pytest.fixture(scope=\"class\")\ndef dbt_profile_target():\n    return {\n        \"type\": \"postgres\",\n        \"threads\": 4,\n        \"host\": \"localhost\",\n        \"port\": int(os.getenv(\"POSTGRES_TEST_PORT\", 5432)),\n        \"user\": os.getenv(\"POSTGRES_TEST_USER\", \"root\"),\n        \"pass\": os.getenv(\"POSTGRES_TEST_PASS\", \"password\"),\n        \"dbname\": os.getenv(\"POSTGRES_TEST_DATABASE\", \"dbt\"),\n    }\n\n\n@pytest.fixture(scope=\"class\")\ndef profile_user(dbt_profile_target):\n    return dbt_profile_target[\"user\"]\n\n\n# This fixture can be overridden in a project. The data provided in this\n# fixture will be merged into the default project dictionary via a python 'update'.\n@pytest.fixture(scope=\"class\")\ndef profiles_config_update():\n    return {}\n\n\n# The profile dictionary, used to write out profiles.yml. It will pull in updates\n# from two separate sources, the 'profile_target' and 'profiles_config_update'.\n# The second one is useful when using alternative targets, etc.\n@pytest.fixture(scope=\"class\")\ndef dbt_profile_data(unique_schema, dbt_profile_target, profiles_config_update):\n    profile = {\n        \"test\": {\n            \"outputs\": {\n                \"default\": {},\n            },\n            \"target\": \"default\",\n        },\n    }\n    target = dbt_profile_target\n    target[\"schema\"] = unique_schema\n    profile[\"test\"][\"outputs\"][\"default\"] = target\n\n    if profiles_config_update:\n        profile.update(profiles_config_update)\n    return profile\n\n\n# Write out the profile data as a yaml file\n@pytest.fixture(scope=\"class\")\ndef profiles_yml(profiles_root, dbt_profile_data):\n    os.environ[\"DBT_PROFILES_DIR\"] = str(profiles_root)\n    write_file(yaml.safe_dump(dbt_profile_data), profiles_root, \"profiles.yml\")\n    yield dbt_profile_data\n    del os.environ[\"DBT_PROFILES_DIR\"]\n\n\n# Data used to update the dbt_project config data.\n@pytest.fixture(scope=\"class\")\ndef project_config_update():\n    return {}\n\n\n# Combines the project_config_update dictionary with project_config defaults to\n# produce a project_yml config and write it out as dbt_project.yml\n@pytest.fixture(scope=\"class\")\ndef dbt_project_yml(project_root, project_config_update, vars_yml):\n    project_config = {\n        \"name\": \"test\",\n        \"profile\": \"test\",\n        \"flags\": {\"send_anonymous_usage_stats\": False},\n    }\n    if project_config_update:\n        if isinstance(project_config_update, dict):\n            project_config.update(project_config_update)\n        elif isinstance(project_config_update, str):\n            updates = yaml.safe_load(project_config_update)\n            project_config.update(updates)\n    write_file(yaml.safe_dump(project_config), project_root, \"dbt_project.yml\")\n    return project_config\n\n\n# Fixture to provide dependencies\n@pytest.fixture(scope=\"class\")\ndef dependencies():\n    return {}\n\n\n# Write out the dependencies.yml file\n# Write out the packages.yml file\n@pytest.fixture(scope=\"class\")\ndef dependencies_yml(project_root, dependencies):\n    if dependencies:\n        if isinstance(dependencies, str):\n            data = dependencies\n        else:\n            data = yaml.safe_dump(dependencies)\n        write_file(data, project_root, \"dependencies.yml\")\n\n\n# Fixture to provide packages as either yaml or dictionary\n@pytest.fixture(scope=\"class\")\ndef packages():\n    return {}\n\n\n# Write out the packages.yml file\n@pytest.fixture(scope=\"class\")\ndef packages_yml(project_root, packages):\n    if packages:\n        if isinstance(packages, str):\n            data = packages\n        else:\n            data = yaml.safe_dump(packages)\n        write_file(data, project_root, \"packages.yml\")\n\n\n# Fixture to provide selectors as either yaml or dictionary\n@pytest.fixture(scope=\"class\")\ndef selectors():\n    return {}\n\n\n# Write out the selectors.yml file\n@pytest.fixture(scope=\"class\")\ndef selectors_yml(project_root, selectors):\n    if selectors:\n        if isinstance(selectors, str):\n            data = selectors\n        else:\n            data = yaml.safe_dump(selectors)\n        write_file(data, project_root, \"selectors.yml\")\n\n\n# Fixture to provide vars as either yaml or dictionary\n@pytest.fixture(scope=\"class\")\ndef vars_yml_update():\n    return {}\n\n\n# Write out the vars.yml file\n@pytest.fixture(scope=\"class\")\ndef vars_yml(project_root, vars_yml_update):\n    if vars_yml_update:\n        if isinstance(vars_yml_update, str):\n            data = vars_yml_update\n        else:\n            data = yaml.safe_dump(vars_yml_update)\n        write_file(data, project_root, \"vars.yml\")\n\n\n# This fixture ensures that the logging infrastructure does not accidentally\n# reuse streams configured on previous test runs, which might now be closed.\n# It should be run before (and so included as a parameter by) any other fixture\n# which runs dbt-core functions that might fire events.\n@pytest.fixture(scope=\"class\")\ndef clean_up_logging():\n    cleanup_event_logger()\n\n\n# This creates an adapter that is used for running test setup, such as creating\n# the test schema, and sql commands that are run in tests prior to the first\n# dbt command. After a dbt command is run, the project.adapter property will\n# return the current adapter (for this adapter type) from the adapter factory.\n# The adapter produced by this fixture will contain the \"base\" macros (not including\n# macros from dependencies).\n#\n# Anything used here must be actually working (dbt_project, profile, project and internal macros),\n# otherwise this will fail. So to test errors in those areas, you need to copy the files\n# into the project in the tests instead of putting them in the fixtures.\n@pytest.fixture(scope=\"class\")\ndef adapter(\n    logs_dir,\n    unique_schema,\n    project_root,\n    profiles_root,\n    profiles_yml,\n    clean_up_logging,\n    dbt_project_yml,\n):\n    # The profiles.yml and dbt_project.yml should already be written out\n    args = Namespace(\n        profiles_dir=str(profiles_root),\n        project_dir=str(project_root),\n        target=None,\n        profile=None,\n        threads=None,\n    )\n    flags.set_from_args(args, {})\n    runtime_config = RuntimeConfig.from_args(args)\n    register_adapter(runtime_config, get_mp_context())\n    adapter = get_adapter(runtime_config)\n    # We only need the base macros, not macros from dependencies, and don't want\n    # to run 'dbt deps' here.\n    manifest = ManifestLoader.load_macros(\n        runtime_config,\n        adapter.connections.set_query_header,\n        base_macros_only=True,\n    )\n\n    adapter.set_macro_resolver(manifest)\n    adapter.set_macro_context_generator(generate_runtime_macro_context)\n    yield adapter\n    adapter.cleanup_connections()\n    reset_adapters()\n\n\n# Start at directory level.\ndef write_project_files(project_root, dir_name, file_dict):\n    path = project_root.mkdir(dir_name)\n    if file_dict:\n        write_project_files_recursively(path, file_dict)\n\n\n# Write files out from file_dict. Can be nested directories...\ndef write_project_files_recursively(path, file_dict):\n    if type(file_dict) is not dict:\n        raise TestProcessingException(f\"File dict is not a dict: '{file_dict}' for path '{path}'\")\n    suffix_list = [\".sql\", \".csv\", \".md\", \".txt\", \".py\"]\n    for name, value in file_dict.items():\n        if name.endswith(\".yml\") or name.endswith(\".yaml\"):\n            if isinstance(value, str):\n                data = value\n            else:\n                data = yaml.safe_dump(value)\n            write_file(data, path, name)\n        elif name.endswith(tuple(suffix_list)):\n            write_file(value, path, name)\n        else:\n            write_project_files_recursively(path.mkdir(name), value)\n\n\n# models, macros, seeds, snapshots, tests, analyses\n# Provide a dictionary of file names to contents. Nested directories\n# are handle by nested dictionaries.\n\n\n# models directory\n@pytest.fixture(scope=\"class\")\ndef models():\n    return {}\n\n\n# macros directory\n@pytest.fixture(scope=\"class\")\ndef macros():\n    return {}\n\n\n# properties directory\n@pytest.fixture(scope=\"class\")\ndef properties():\n    return {}\n\n\n# seeds directory\n@pytest.fixture(scope=\"class\")\ndef seeds():\n    return {}\n\n\n# snapshots directory\n@pytest.fixture(scope=\"class\")\ndef snapshots():\n    return {}\n\n\n# tests directory\n@pytest.fixture(scope=\"class\")\ndef tests():\n    return {}\n\n\n# analyses directory\n@pytest.fixture(scope=\"class\")\ndef analyses():\n    return {}\n\n\n@pytest.fixture(scope=\"class\")\ndef functions() -> Dict[str, str]:\n    return {}\n\n\n# Write out the files provided by models, macros, properties, snapshots, seeds, tests, analyses\n@pytest.fixture(scope=\"class\")\ndef project_files(\n    project_root,\n    models,\n    macros,\n    snapshots,\n    properties,\n    seeds,\n    tests,\n    analyses,\n    functions,\n    selectors_yml,\n    dependencies_yml,\n    packages_yml,\n    vars_yml,\n    dbt_project_yml,\n):\n    write_project_files(project_root, \"models\", {**models, **properties})\n    write_project_files(project_root, \"macros\", macros)\n    write_project_files(project_root, \"snapshots\", snapshots)\n    write_project_files(project_root, \"seeds\", seeds)\n    write_project_files(project_root, \"tests\", tests)\n    write_project_files(project_root, \"analyses\", analyses)\n    write_project_files(project_root, \"functions\", functions)\n\n\n# We have a separate logs dir for every test\n@pytest.fixture(scope=\"class\")\ndef logs_dir(request, prefix):\n    dbt_log_dir = os.path.join(request.config.rootdir, \"logs\", prefix)\n    os.environ[\"DBT_LOG_PATH\"] = str(dbt_log_dir)\n    yield str(Path(dbt_log_dir))\n    del os.environ[\"DBT_LOG_PATH\"]\n\n\n# This fixture is for customizing tests that need overrides in adapter\n# repos. Example in tests.functional.adapter.basic.test_base.\n@pytest.fixture(scope=\"class\")\ndef test_config():\n    return {}\n\n\n# This class is returned from the 'project' fixture, and contains information\n# from the pytest fixtures that may be needed in the test functions, including\n# a 'run_sql' method.\nclass TestProjInfo:\n    __test__ = False\n\n    def __init__(\n        self,\n        project_root,\n        profiles_dir,\n        adapter_type,\n        test_dir,\n        shared_data_dir,\n        test_data_dir,\n        test_schema,\n        database,\n        test_config,\n    ):\n        self.project_root = project_root\n        self.profiles_dir = profiles_dir\n        self.adapter_type = adapter_type\n        self.test_dir = test_dir\n        self.shared_data_dir = shared_data_dir\n        self.test_data_dir = test_data_dir\n        self.test_schema = test_schema\n        self.database = database\n        self.test_config = test_config\n        self.created_schemas = []\n\n    @property\n    def adapter(self):\n        # This returns the last created \"adapter\" from the adapter factory. Each\n        # dbt command will create a new one. This allows us to avoid patching the\n        # providers 'get_adapter' function.\n        return get_adapter_by_type(self.adapter_type)\n\n    # Run sql from a path\n    def run_sql_file(self, sql_path, fetch=None):\n        with open(sql_path, \"r\") as f:\n            statements = f.read().split(\";\")\n            for statement in statements:\n                self.run_sql(statement, fetch)\n\n    # Run sql from a string, using adapter saved at test startup\n    def run_sql(self, sql, fetch=None):\n        return run_sql_with_adapter(self.adapter, sql, fetch=fetch)\n\n    # Create the unique test schema. Used in test setup, so that we're\n    # ready for initial sql prior to a run_dbt command.\n    def create_test_schema(self, schema_name=None):\n        if schema_name is None:\n            schema_name = self.test_schema\n        with get_connection(self.adapter):\n            relation = self.adapter.Relation.create(database=self.database, schema=schema_name)\n            self.adapter.create_schema(relation)\n            self.created_schemas.append(schema_name)\n\n    # Drop the unique test schema, usually called in test cleanup\n    def drop_test_schema(self):\n        if self.adapter.get_macro_resolver() is None:\n            manifest = ManifestLoader.load_macros(\n                self.adapter.config,\n                self.adapter.connections.set_query_header,\n                base_macros_only=True,\n            )\n            self.adapter.set_macro_resolver(manifest)\n\n        with get_connection(self.adapter):\n            for schema_name in self.created_schemas:\n                relation = self.adapter.Relation.create(database=self.database, schema=schema_name)\n                self.adapter.drop_schema(relation)\n            self.created_schemas = []\n\n    # This return a dictionary of table names to 'view' or 'table' values.\n    def get_tables_in_schema(self):\n        sql = \"\"\"\n                select table_name,\n                        case when table_type = 'BASE TABLE' then 'table'\n                             when table_type = 'VIEW' then 'view'\n                             else table_type\n                        end as materialization\n                from information_schema.tables\n                where {}\n                order by table_name\n                \"\"\"\n        sql = sql.format(\"{} ilike '{}'\".format(\"table_schema\", self.test_schema))\n        result = self.run_sql(sql, fetch=\"all\")\n        return {model_name: materialization for (model_name, materialization) in result}\n\n\n@pytest.fixture(scope=\"class\")\ndef environment() -> Mapping[str, str]:\n    # By default, fixture initialization is done with the following environment\n    # from the os, but this fixture provides a way to customize the environment.\n    return os.environ\n\n\n# Housekeeping that needs to be done before we start setting up any test fixtures.\n@pytest.fixture(scope=\"class\")\ndef initialization(environment) -> None:\n    # Create an \"invocation context,\" which dbt application code relies on.\n    set_invocation_context(environment)\n\n    # Enable caches used between test runs, for better testing performance.\n    enable_test_caching()\n\n\n@pytest.fixture(scope=\"class\")\ndef project_setup(\n    initialization,\n    clean_up_logging,\n    project_root,\n    profiles_root,\n    request,\n    unique_schema,\n    profiles_yml,\n    adapter,\n    shared_data_dir,\n    test_data_dir,\n    logs_dir,\n    test_config,\n):\n    log_flags = Namespace(\n        LOG_PATH=logs_dir,\n        LOG_FORMAT=\"json\",\n        LOG_FORMAT_FILE=\"json\",\n        USE_COLORS=False,\n        USE_COLORS_FILE=False,\n        LOG_LEVEL=\"info\",\n        LOG_LEVEL_FILE=\"debug\",\n        DEBUG=False,\n        LOG_CACHE_EVENTS=False,\n        QUIET=False,\n        LOG_FILE_MAX_BYTES=1000000,\n    )\n    setup_event_logger(log_flags)\n    orig_cwd = os.getcwd()\n    os.chdir(project_root)\n    # Return whatever is needed later in tests but can only come from fixtures, so we can keep\n    # the signatures in the test signature to a minimum.\n    project = TestProjInfo(\n        project_root=project_root,\n        profiles_dir=profiles_root,\n        adapter_type=adapter.type(),\n        test_dir=request.fspath.dirname,\n        shared_data_dir=shared_data_dir,\n        test_data_dir=test_data_dir,\n        test_schema=unique_schema,\n        database=adapter.config.credentials.database,\n        test_config=test_config,\n    )\n    project.drop_test_schema()\n    project.create_test_schema()\n\n    yield project\n\n    # deps, debug and clean commands will not have an installed adapter when running and will raise\n    # a KeyError here.  Just pass for now.\n    # See https://github.com/dbt-labs/dbt-core/issues/5041\n    # The debug command also results in an AttributeError since `Profile` doesn't have\n    # a `load_dependencies` method.\n    # Macros gets executed as part of drop_scheme in core/dbt/adapters/sql/impl.py.  When\n    # the macros have errors (which is what we're actually testing for...) they end up\n    # throwing CompilationErrorss or DatabaseErrors\n    try:\n        project.drop_test_schema()\n    except (KeyError, AttributeError, CompilationError, DbtDatabaseError):\n        pass\n    os.chdir(orig_cwd)\n    cleanup_event_logger()\n    reset_deprecations()\n\n\n# This is the main fixture that is used in all functional tests. It pulls in the other\n# fixtures that are necessary to set up a dbt project, and saves some of the information\n# in a TestProjInfo class, which it returns, so that individual test cases do not have\n# to pull in the other fixtures individually to access their information.\n# The order of arguments here determine which steps runs first.\n@pytest.fixture(scope=\"class\")\ndef project(\n    project_setup: TestProjInfo,\n    project_files,\n):\n    return project_setup\n"
  },
  {
    "path": "core/dbt/tests/util.py",
    "content": "import json\nimport os\nimport shutil\nfrom contextlib import contextmanager\nfrom contextvars import ContextVar, copy_context\nfrom datetime import datetime, timezone\nfrom io import StringIO\nfrom typing import Any, Callable, Dict, List, Optional\nfrom unittest import mock\n\nimport pytz\nimport yaml\n\nfrom dbt.adapters.base.relation import BaseRelation\nfrom dbt.adapters.factory import Adapter\nfrom dbt.cli.main import dbtRunner\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.materializations.incremental.microbatch import MicrobatchBuilder\nfrom dbt_common.context import _INVOCATION_CONTEXT_VAR, InvocationContext\nfrom dbt_common.events.base_types import EventLevel, EventMsg\nfrom dbt_common.events.functions import (\n    capture_stdout_logs,\n    fire_event,\n    reset_metadata_vars,\n    stop_capture_stdout_logs,\n)\nfrom dbt_common.events.types import Note\n\n# =============================================================================\n# Test utilities\n#   run_dbt\n#   run_dbt_and_capture\n#   get_manifest\n#   copy_file\n#   rm_file\n#   write_file\n#   read_file\n#   mkdir\n#   rm_dir\n#   get_artifact\n#   update_config_file\n#   write_config_file\n#   get_unique_ids_in_results\n#   check_result_nodes_by_name\n#   check_result_nodes_by_unique_id\n\n# SQL related utilities that use the adapter\n#   run_sql_with_adapter\n#   relation_from_name\n#   check_relation_types (table/view)\n#   check_relations_equal\n#   check_relation_has_expected_schema\n#   check_relations_equal_with_relations\n#   check_table_does_exist\n#   check_table_does_not_exist\n#   get_relation_columns\n#   update_rows\n#      generate_update_clause\n#\n# Classes for comparing fields in dictionaries\n#   AnyFloat\n#   AnyInteger\n#   AnyString\n#   AnyStringWith\n# =============================================================================\n\n\n# 'run_dbt' is used in pytest tests to run dbt commands. It will return\n# different objects depending on the command that is executed.\n# For a run command (and most other commands) it will return a list\n# of results. For the 'docs generate' command it returns a CatalogArtifact.\n# The first parameter is a list of dbt command line arguments, such as\n#   run_dbt([\"run\", \"--vars\", \"seed_name: base\"])\n# If the command is expected to fail, pass in \"expect_pass=False\"):\n#   run_dbt([\"test\"], expect_pass=False)\ndef run_dbt(\n    args: Optional[List[str]] = None,\n    expect_pass: bool = True,\n    callbacks: Optional[List[Callable[[EventMsg], None]]] = None,\n):\n    # reset global vars\n    reset_metadata_vars()\n\n    if args is None:\n        args = [\"run\"]\n\n    print(\"\\n\\nInvoking dbt with {}\".format(args))\n    from dbt.flags import get_flags\n\n    flags = get_flags()\n    project_dir = getattr(flags, \"PROJECT_DIR\", None)\n    profiles_dir = getattr(flags, \"PROFILES_DIR\", None)\n    if project_dir and \"--project-dir\" not in args:\n        args.extend([\"--project-dir\", project_dir])\n    if profiles_dir and \"--profiles-dir\" not in args:\n        args.extend([\"--profiles-dir\", profiles_dir])\n    dbt = dbtRunner(callbacks=callbacks)\n\n    res = dbt.invoke(args)\n\n    # the exception is immediately raised to be caught in tests\n    # using a pattern like `with pytest.raises(SomeException):`\n    if res.exception is not None:\n        raise res.exception\n\n    if expect_pass is not None:\n        assert res.success == expect_pass, \"dbt exit state did not match expected\"\n\n    return res.result\n\n\n# Use this if you need to capture the command logs in a test.\n# If you want the logs that are normally written to a file, you must\n# start with the \"--debug\" flag. The structured schema log CI test\n# will turn the logs into json, so you have to be prepared for that.\ndef run_dbt_and_capture(\n    args: Optional[List[str]] = None,\n    expect_pass: bool = True,\n):\n    try:\n        stringbuf = StringIO()\n        capture_stdout_logs(stringbuf)\n        res = run_dbt(args, expect_pass=expect_pass)\n        stdout = stringbuf.getvalue()\n\n    finally:\n        stop_capture_stdout_logs()\n\n    return res, stdout\n\n\ndef get_logging_events(log_output, event_name):\n    logging_events = []\n    for log_line in log_output.split(\"\\n\"):\n        # skip empty lines\n        if len(log_line) == 0:\n            continue\n        # The adapter logging also shows up, so skip non-json lines\n        if not log_line.startswith(\"{\"):\n            continue\n        if event_name in log_line:\n            log_dct = json.loads(log_line)\n            if log_dct[\"info\"][\"name\"] == event_name:\n                logging_events.append(log_dct)\n    return logging_events\n\n\n# Used in test cases to get the manifest from the partial parsing file\n# Note: this uses an internal version of the manifest, and in the future\n# parts of it will not be supported for external use.\ndef get_manifest(project_root) -> Optional[Manifest]:\n    path = os.path.join(project_root, \"target\", \"partial_parse.msgpack\")\n    if os.path.exists(path):\n        with open(path, \"rb\") as fp:\n            manifest_mp = fp.read()\n        manifest: Manifest = Manifest.from_msgpack(manifest_mp)  # type: ignore[attr-defined]\n        return manifest\n    else:\n        return None\n\n\n# Used in test cases to get the run_results.json file.\ndef get_run_results(project_root) -> Any:\n    path = os.path.join(project_root, \"target\", \"run_results.json\")\n    if os.path.exists(path):\n        with open(path) as run_result_text:\n            return json.load(run_result_text)\n    else:\n        return None\n\n\n# Used in tests to copy a file, usually from a data directory to the project directory\ndef copy_file(src_path, src, dest_path, dest) -> None:\n    # dest is a list, so that we can provide nested directories, like 'models' etc.\n    # copy files from the data_dir to appropriate project directory\n    shutil.copyfile(\n        os.path.join(src_path, src),\n        os.path.join(dest_path, *dest),\n    )\n\n\n# Used in tests when you want to remove a file from the project directory\ndef rm_file(*paths) -> None:\n    # remove files from proj_path\n    os.remove(os.path.join(*paths))\n\n\n# Used in tests to write out the string contents of a file to a\n# file in the project directory.\n# We need to explicitly use encoding=\"utf-8\" because otherwise on\n# Windows we'll get codepage 1252 and things might break\ndef write_file(contents, *paths):\n    with open(os.path.join(*paths), \"w\", encoding=\"utf-8\") as fp:\n        fp.write(contents)\n\n\ndef file_exists(*paths):\n    \"\"\"Check if file exists at path\"\"\"\n    return os.path.exists(os.path.join(*paths))\n\n\n# Used in test utilities\ndef read_file(*paths):\n    contents = \"\"\n    with open(os.path.join(*paths), \"r\") as fp:\n        contents = fp.read()\n    return contents\n\n\n# To create a directory\ndef mkdir(directory_path):\n    try:\n        os.makedirs(directory_path)\n    except FileExistsError:\n        raise FileExistsError(f\"{directory_path} already exists.\")\n\n\n# To remove a directory\ndef rm_dir(directory_path):\n    try:\n        shutil.rmtree(directory_path)\n    except FileNotFoundError:\n        raise FileNotFoundError(f\"{directory_path} does not exist.\")\n\n\ndef rename_dir(src_directory_path, dest_directory_path):\n    os.rename(src_directory_path, dest_directory_path)\n\n\n# Get an artifact (usually from the target directory) such as\n# manifest.json or catalog.json to use in a test\ndef get_artifact(*paths):\n    contents = read_file(*paths)\n    dct = json.loads(contents)\n    return dct\n\n\ndef write_artifact(dct, *paths):\n    json_output = json.dumps(dct)\n    write_file(json_output, *paths)\n\n\n# For updating yaml config files\ndef update_config_file(updates, *paths):\n    current_yaml = read_file(*paths)\n    config = yaml.safe_load(current_yaml)\n    config.update(updates)\n    new_yaml = yaml.safe_dump(config)\n    write_file(new_yaml, *paths)\n\n\n# Write new config file\ndef write_config_file(data, *paths):\n    if type(data) is dict:\n        data = yaml.safe_dump(data)\n    write_file(data, *paths)\n\n\n# Get the unique_ids in dbt command results\ndef get_unique_ids_in_results(results):\n    unique_ids = []\n    for result in results:\n        unique_ids.append(result.node.unique_id)\n    return unique_ids\n\n\n# Check the nodes in the results returned by a dbt run command\ndef check_result_nodes_by_name(results, names):\n    result_names = []\n    for result in results:\n        result_names.append(result.node.name)\n    assert set(names) == set(result_names)\n\n\n# Check the nodes in the results returned by a dbt run command\ndef check_result_nodes_by_unique_id(results, unique_ids):\n    result_unique_ids = []\n    for result in results:\n        result_unique_ids.append(result.node.unique_id)\n    assert set(unique_ids) == set(result_unique_ids)\n\n\n# Check datetime is between start and end/now\ndef check_datetime_between(timestr, start, end=None):\n    datefmt = \"%Y-%m-%dT%H:%M:%S.%fZ\"\n    if end is None:\n        end = datetime.now(timezone.utc).replace(tzinfo=None)\n    parsed = datetime.strptime(timestr, datefmt)\n    assert start <= parsed\n    assert end >= parsed\n\n\nclass TestProcessingException(Exception):\n    pass\n\n\n# Testing utilities that use adapter code\n\n\n# Uses:\n#    adapter.config.credentials\n#    adapter.quote\n#    adapter.run_sql_for_tests\ndef run_sql_with_adapter(adapter, sql, fetch=None):\n    if sql.strip() == \"\":\n        return\n\n    # substitute schema and database in sql\n    kwargs = {\n        \"schema\": adapter.config.credentials.schema,\n        \"database\": adapter.quote(adapter.config.credentials.database),\n    }\n    sql = sql.format(**kwargs)\n\n    msg = f'test connection \"__test\" executing: {sql}'\n    fire_event(Note(msg=msg), level=EventLevel.DEBUG)\n    with get_connection(adapter) as conn:\n        return adapter.run_sql_for_tests(sql, fetch, conn)\n\n\n# Get a Relation object from the identifier (name of table/view).\n# Uses the default database and schema. If you need a relation\n# with a different schema, it should be constructed in the test.\n# Uses:\n#    adapter.Relation\n#    adapter.config.credentials\n#    Relation.get_default_quote_policy\n#    Relation.get_default_include_policy\ndef relation_from_name(adapter, name: str):\n    \"\"\"reverse-engineer a relation from a given name and\n    the adapter. The relation name is split by the '.' character.\n    \"\"\"\n\n    # Different adapters have different Relation classes\n    cls = adapter.Relation\n    credentials = adapter.config.credentials\n    quote_policy = cls.get_default_quote_policy().to_dict()\n    include_policy = cls.get_default_include_policy().to_dict()\n\n    # Make sure we have database/schema/identifier parts, even if\n    # only identifier was supplied.\n    relation_parts = name.split(\".\")\n    if len(relation_parts) == 1:\n        relation_parts.insert(0, credentials.schema)\n    if len(relation_parts) == 2:\n        relation_parts.insert(0, credentials.database)\n    kwargs = {\n        \"database\": relation_parts[0],\n        \"schema\": relation_parts[1],\n        \"identifier\": relation_parts[2],\n    }\n\n    relation = cls.create(\n        include_policy=include_policy,\n        quote_policy=quote_policy,\n        **kwargs,\n    )\n    return relation\n\n\n# Ensure that models with different materialiations have the\n# current table/view.\n# Uses:\n#   adapter.list_relations_without_caching\ndef check_relation_types(adapter, relation_to_type):\n    \"\"\"\n    Relation name to table/view\n    {\n        \"base\": \"table\",\n        \"other\": \"view\",\n    }\n    \"\"\"\n\n    expected_relation_values = {}\n    found_relations = []\n    schemas = set()\n\n    for key, value in relation_to_type.items():\n        relation = relation_from_name(adapter, key)\n        expected_relation_values[relation] = value\n        schemas.add(relation.without_identifier())\n\n        with get_connection(adapter):\n            for schema in schemas:\n                found_relations.extend(adapter.list_relations_without_caching(schema))\n\n    for key, value in relation_to_type.items():\n        for relation in found_relations:\n            # this might be too broad\n            if relation.identifier == key:\n                assert relation.type == value, (\n                    f\"Got an unexpected relation type of {relation.type} \"\n                    f\"for relation {key}, expected {value}\"\n                )\n\n\n# Replaces assertTablesEqual. assertManyTablesEqual can be replaced\n# by doing a separate call for each set of tables/relations.\n# Wraps check_relations_equal_with_relations by creating relations\n# from the list of names passed in.\ndef check_relations_equal(adapter, relation_names: List, compare_snapshot_cols=False):\n    if len(relation_names) < 2:\n        raise TestProcessingException(\n            \"Not enough relations to compare\",\n        )\n    relations = [relation_from_name(adapter, name) for name in relation_names]\n    return check_relations_equal_with_relations(\n        adapter, relations, compare_snapshot_cols=compare_snapshot_cols\n    )\n\n\n# Used to check that a particular relation has an expected schema\n# expected_schema should look like {\"column_name\": \"expected datatype\"}\ndef check_relation_has_expected_schema(adapter, relation_name, expected_schema: Dict):\n    relation = relation_from_name(adapter, relation_name)\n    with get_connection(adapter):\n        actual_columns = {c.name: c.data_type for c in adapter.get_columns_in_relation(relation)}\n    assert (\n        actual_columns == expected_schema\n    ), f\"Actual schema did not match expected, actual: {json.dumps(actual_columns)}\"\n\n\n# This can be used when checking relations in different schemas, by supplying\n# a list of relations. Called by 'check_relations_equal'.\n# Uses:\n#    adapter.get_columns_in_relation\n#    adapter.get_rows_different_sql\n#    adapter.execute\ndef check_relations_equal_with_relations(\n    adapter: Adapter, relations: List, compare_snapshot_cols=False\n):\n    with get_connection(adapter):\n        basis, compares = relations[0], relations[1:]\n        # Skip columns starting with \"dbt_\" because we don't want to\n        # compare those, since they are time sensitive\n        # (unless comparing \"dbt_\" snapshot columns is explicitly enabled)\n        column_names = [\n            c.name\n            for c in adapter.get_columns_in_relation(basis)  # type: ignore\n            if not c.name.lower().startswith(\"dbt_\") or compare_snapshot_cols\n        ]\n\n        for relation in compares:\n            sql = adapter.get_rows_different_sql(basis, relation, column_names=column_names)  # type: ignore\n            _, tbl = adapter.execute(sql, fetch=True)\n            num_rows = len(tbl)\n            assert (\n                num_rows == 1\n            ), f\"Invalid sql query from get_rows_different_sql: incorrect number of rows ({num_rows})\"\n            num_cols = len(tbl[0])\n            assert (\n                num_cols == 2\n            ), f\"Invalid sql query from get_rows_different_sql: incorrect number of cols ({num_cols})\"\n            row_count_difference = tbl[0][0]\n            assert (\n                row_count_difference == 0\n            ), f\"Got {row_count_difference} difference in row count betwen {basis} and {relation}\"\n            rows_mismatched = tbl[0][1]\n            assert (\n                rows_mismatched == 0\n            ), f\"Got {rows_mismatched} different rows between {basis} and {relation}\"\n\n\n# Uses:\n#    adapter.update_column_sql\n#    adapter.execute\n#    adapter.commit_if_has_connection\ndef update_rows(adapter, update_rows_config):\n    \"\"\"\n    {\n      \"name\": \"base\",\n      \"dst_col\": \"some_date\"\n      \"clause\": {\n          \"type\": \"add_timestamp\",\n          \"src_col\": \"some_date\",\n       \"where\" \"id > 10\"\n    }\n    \"\"\"\n    for key in [\"name\", \"dst_col\", \"clause\"]:\n        if key not in update_rows_config:\n            raise TestProcessingException(f\"Invalid update_rows: no {key}\")\n\n    clause = update_rows_config[\"clause\"]\n    clause = generate_update_clause(adapter, clause)\n\n    where = None\n    if \"where\" in update_rows_config:\n        where = update_rows_config[\"where\"]\n\n    name = update_rows_config[\"name\"]\n    dst_col = update_rows_config[\"dst_col\"]\n    relation = relation_from_name(adapter, name)\n\n    with get_connection(adapter):\n        sql = adapter.update_column_sql(\n            dst_name=str(relation),\n            dst_column=dst_col,\n            clause=clause,\n            where_clause=where,\n        )\n        adapter.execute(sql, auto_begin=True)\n        adapter.commit_if_has_connection()\n\n\n# This is called by the 'update_rows' function.\n# Uses:\n#    adapter.timestamp_add_sql\n#    adapter.string_add_sql\ndef generate_update_clause(adapter, clause) -> str:\n    \"\"\"\n    Called by update_rows function. Expects the \"clause\" dictionary\n    documented in 'update_rows.\n    \"\"\"\n\n    if \"type\" not in clause or clause[\"type\"] not in [\"add_timestamp\", \"add_string\"]:\n        raise TestProcessingException(\"invalid update_rows clause: type missing or incorrect\")\n    clause_type = clause[\"type\"]\n\n    if clause_type == \"add_timestamp\":\n        if \"src_col\" not in clause:\n            raise TestProcessingException(\"Invalid update_rows clause: no src_col\")\n        add_to = clause[\"src_col\"]\n        kwargs = {k: v for k, v in clause.items() if k in (\"interval\", \"number\")}\n        with get_connection(adapter):\n            return adapter.timestamp_add_sql(add_to=add_to, **kwargs)\n    elif clause_type == \"add_string\":\n        for key in [\"src_col\", \"value\"]:\n            if key not in clause:\n                raise TestProcessingException(f\"Invalid update_rows clause: no {key}\")\n        src_col = clause[\"src_col\"]\n        value = clause[\"value\"]\n        location = clause.get(\"location\", \"append\")\n        with get_connection(adapter):\n            return adapter.string_add_sql(src_col, value, location)\n    return \"\"\n\n\n@contextmanager\ndef get_connection(adapter, name=\"_test\"):\n    with adapter.connection_named(name):\n        conn = adapter.connections.get_thread_connection()\n        yield conn\n\n\n# Uses:\n#    adapter.get_columns_in_relation\ndef get_relation_columns(adapter, name):\n    relation = relation_from_name(adapter, name)\n    with get_connection(adapter):\n        columns = adapter.get_columns_in_relation(relation)\n        return sorted(((c.name, c.dtype, c.char_size) for c in columns), key=lambda x: x[0])\n\n\ndef check_table_does_not_exist(adapter, name):\n    columns = get_relation_columns(adapter, name)\n    assert len(columns) == 0\n\n\ndef check_table_does_exist(adapter, name):\n    columns = get_relation_columns(adapter, name)\n    assert len(columns) > 0\n\n\n# Utility classes for enabling comparison of dictionaries\n\n\nclass AnyFloat:\n    \"\"\"Any float. Use this in assert calls\"\"\"\n\n    def __eq__(self, other):\n        return isinstance(other, float)\n\n\nclass AnyInteger:\n    \"\"\"Any Integer. Use this in assert calls\"\"\"\n\n    def __eq__(self, other):\n        return isinstance(other, int)\n\n\nclass AnyString:\n    \"\"\"Any string. Use this in assert calls\"\"\"\n\n    def __eq__(self, other):\n        return isinstance(other, str)\n\n\nclass AnyStringWith:\n    \"\"\"AnyStringWith(\"AUTO\")\"\"\"\n\n    def __init__(self, contains=None):\n        self.contains = contains\n\n    def __eq__(self, other):\n        if not isinstance(other, str):\n            return False\n\n        if self.contains is None:\n            return True\n\n        return self.contains in other\n\n    def __repr__(self):\n        return \"AnyStringWith<{!r}>\".format(self.contains)\n\n\ndef assert_message_in_logs(message: str, logs: str, expected_pass: bool = True):\n    # if the logs are json strings, then 'jsonify' the message because of things like escape quotes\n    if os.environ.get(\"DBT_LOG_FORMAT\", \"\") == \"json\":\n        message = message.replace(r'\"', r\"\\\"\")\n\n    if expected_pass:\n        assert message in logs\n    else:\n        assert message not in logs\n\n\ndef get_project_config(project):\n    file_yaml = read_file(project.project_root, \"dbt_project.yml\")\n    return yaml.safe_load(file_yaml)\n\n\ndef set_project_config(project, config):\n    config_yaml = yaml.safe_dump(config)\n    write_file(config_yaml, project.project_root, \"dbt_project.yml\")\n\n\ndef get_model_file(project, relation: BaseRelation) -> str:\n    return read_file(project.project_root, \"models\", f\"{relation.name}.sql\")\n\n\ndef set_model_file(project, relation: BaseRelation, model_sql: str):\n    write_file(model_sql, project.project_root, \"models\", f\"{relation.name}.sql\")\n\n\ndef safe_set_invocation_context():\n    \"\"\"In order to deal with a problem with the way the pytest runner interacts\n    with ContextVars, this function provides a mechanism for setting the\n    invocation context reliably, using its name rather than the reference\n    variable, which may have been loaded in a separate context.\"\"\"\n    invocation_var: Optional[ContextVar] = next(\n        iter([cv for cv in copy_context() if cv.name == _INVOCATION_CONTEXT_VAR.name]), None\n    )\n    if invocation_var is None:\n        invocation_var = _INVOCATION_CONTEXT_VAR\n    invocation_var.set(InvocationContext(os.environ))\n\n\ndef patch_microbatch_end_time(dt_str: str):\n    dt = datetime.strptime(dt_str, \"%Y-%m-%d %H:%M:%S\").replace(tzinfo=pytz.UTC)\n    return mock.patch.object(MicrobatchBuilder, \"build_end_time\", return_value=dt)\n"
  },
  {
    "path": "core/dbt/tracking.py",
    "content": "import os\nimport platform\nimport traceback\nimport uuid\nfrom contextlib import contextmanager\nfrom datetime import datetime\nfrom typing import Optional\n\nimport pytz\nimport requests\nfrom packaging.version import Version\nfrom snowplow_tracker import Emitter, SelfDescribingJson, Subject, Tracker\nfrom snowplow_tracker import __version__ as snowplow_version  # type: ignore\nfrom snowplow_tracker import logger as sp_logger\nfrom snowplow_tracker.events import StructuredEvent\n\nfrom dbt import version as dbt_version\nfrom dbt.adapters.exceptions import FailedToConnectError\nfrom dbt.clients.yaml_helper import safe_load, yaml  # noqa:F401\nfrom dbt.events.types import (\n    DisableTracking,\n    FlushEvents,\n    FlushEventsFailure,\n    MainEncounteredError,\n    SendEventFailure,\n    SendingEvent,\n    TrackingInitializeFailure,\n)\nfrom dbt_common.events.base_types import EventMsg\nfrom dbt_common.events.functions import fire_event, get_invocation_id, msg_to_dict\nfrom dbt_common.exceptions import NotImplementedError\n\nsp_logger.setLevel(100)\n\nCOLLECTOR_URL = \"fishtownanalytics.sinter-collect.com\"\nCOLLECTOR_PROTOCOL = \"https\"\nDBT_INVOCATION_ENV = \"DBT_INVOCATION_ENV\"\n\nADAPTER_INFO_SPEC = \"iglu:com.dbt/adapter_info/jsonschema/1-0-1\"\nDEPRECATION_WARN_SPEC = \"iglu:com.dbt/deprecation_warn/jsonschema/1-0-0\"\nBEHAVIOR_CHANGE_WARN_SPEC = \"iglu:com.dbt/behavior_change_warn/jsonschema/1-0-0\"\nEXPERIMENTAL_PARSER = \"iglu:com.dbt/experimental_parser/jsonschema/1-0-0\"\nINVOCATION_ENV_SPEC = \"iglu:com.dbt/invocation_env/jsonschema/1-0-0\"\nINVOCATION_SPEC = \"iglu:com.dbt/invocation/jsonschema/1-0-2\"\nLOAD_ALL_TIMING_SPEC = \"iglu:com.dbt/load_all_timing/jsonschema/1-0-3\"\nPACKAGE_INSTALL_SPEC = \"iglu:com.dbt/package_install/jsonschema/1-0-0\"\nPARTIAL_PARSER = \"iglu:com.dbt/partial_parser/jsonschema/1-0-1\"\nPLATFORM_SPEC = \"iglu:com.dbt/platform/jsonschema/1-0-0\"\nPROJECT_ID_SPEC = \"iglu:com.dbt/project_id/jsonschema/1-0-1\"\nRESOURCE_COUNTS = \"iglu:com.dbt/resource_counts/jsonschema/1-0-1\"\nRPC_REQUEST_SPEC = \"iglu:com.dbt/rpc_request/jsonschema/1-0-1\"\nRUNNABLE_TIMING = \"iglu:com.dbt/runnable/jsonschema/1-0-0\"\nRUN_MODEL_SPEC = \"iglu:com.dbt/run_model/jsonschema/1-1-0\"\nPLUGIN_GET_NODES = \"iglu:com.dbt/plugin_get_nodes/jsonschema/1-0-0\"\nARTIFACT_UPLOAD = \"iglu:com.dbt/artifact_upload/jsonschema/1-0-0\"\n\nSNOWPLOW_TRACKER_VERSION = Version(snowplow_version)\n\n# workaround in case real snowplow tracker is in the env\n# the argument was renamed in https://github.com/snowplow/snowplow-python-tracker/commit/39fd50a3aff98a5efdd5c5c7fb5518fe4761305b\nINIT_KW_ARGS = (\n    {\"buffer_size\": 30} if SNOWPLOW_TRACKER_VERSION < Version(\"0.13.0\") else {\"batch_size\": 30}\n)\n\n\nclass TimeoutEmitter(Emitter):\n    def __init__(self) -> None:\n        super().__init__(\n            COLLECTOR_URL,\n            protocol=COLLECTOR_PROTOCOL,\n            on_failure=self.handle_failure,\n            method=\"post\",\n            # don't set this.\n            byte_limit=None,\n            **INIT_KW_ARGS,\n        )\n\n    @staticmethod\n    def handle_failure(num_ok, unsent):\n        # num_ok will always be 0, unsent will always be 1 entry long, because\n        # the buffer is length 1, so not much to talk about\n        fire_event(DisableTracking())\n        disable_tracking()\n\n    def _log_request(self, request, payload):\n        sp_logger.info(f\"Sending {request} request to {self.endpoint}...\")\n        sp_logger.debug(f\"Payload: {payload}\")\n\n    def _log_result(self, request, status_code):\n        msg = f\"{request} request finished with status code: {status_code}\"\n        if self.is_good_status_code(status_code):\n            sp_logger.info(msg)\n        else:\n            sp_logger.warning(msg)\n\n    def http_post(self, payload):\n        self._log_request(\"POST\", payload)\n\n        r = requests.post(\n            self.endpoint,\n            data=payload,\n            headers={\"content-type\": \"application/json; charset=utf-8\"},\n            timeout=5.0,\n        )\n\n        self._log_result(\"GET\", r.status_code)\n        return r\n\n    def http_get(self, payload):\n        self._log_request(\"GET\", payload)\n\n        r = requests.get(self.endpoint, params=payload, timeout=5.0)\n\n        self._log_result(\"GET\", r.status_code)\n        return r\n\n\nemitter = TimeoutEmitter()\ntracker = Tracker(\n    emitters=emitter,\n    namespace=\"cf\",\n    app_id=\"dbt\",\n)\n\n\nclass User:\n    def __init__(self, cookie_dir) -> None:\n        self.do_not_track = True\n        self.cookie_dir = cookie_dir\n\n        self.id = None\n        self.invocation_id = get_invocation_id()\n        self.run_started_at = datetime.now(tz=pytz.utc)\n\n    def state(self):\n        return \"do not track\" if self.do_not_track else \"tracking\"\n\n    @property\n    def cookie_path(self):\n        return os.path.join(self.cookie_dir, \".user.yml\")\n\n    def initialize(self):\n        self.do_not_track = False\n\n        cookie = self.get_cookie()\n        self.id = cookie.get(\"id\")\n\n        subject = Subject()\n        subject.set_user_id(self.id)\n        tracker.set_subject(subject)\n\n    def disable_tracking(self):\n        self.do_not_track = True\n        self.id = None\n        self.cookie_dir = None\n        tracker.set_subject(None)\n\n    def set_cookie(self):\n        # If the user points dbt to a profile directory which exists AND\n        # contains a profiles.yml file, then we can set a cookie. If the\n        # specified folder does not exist, or if there is not a profiles.yml\n        # file in this folder, then an inconsistent cookie can be used. This\n        # will change in every dbt invocation until the user points to a\n        # profile dir file which contains a valid profiles.yml file.\n        #\n        # See: https://github.com/dbt-labs/dbt-core/issues/1645\n\n        user = {\"id\": str(uuid.uuid4())}\n\n        cookie_path = os.path.abspath(self.cookie_dir)\n        profiles_file = os.path.join(cookie_path, \"profiles.yml\")\n        if os.path.exists(cookie_path) and os.path.exists(profiles_file):\n            with open(self.cookie_path, \"w\") as fh:\n                yaml.dump(user, fh)\n\n        return user\n\n    def get_cookie(self):\n        if not os.path.isfile(self.cookie_path):\n            user = self.set_cookie()\n        else:\n            with open(self.cookie_path, \"r\") as fh:\n                try:\n                    user = safe_load(fh)\n                    if user is None:\n                        user = self.set_cookie()\n                except yaml.reader.ReaderError:\n                    user = self.set_cookie()\n        return user\n\n\nactive_user: Optional[User] = None\n\n\ndef get_platform_context():\n    data = {\n        \"platform\": platform.platform(),\n        \"python\": platform.python_version(),\n        \"python_version\": platform.python_implementation(),\n    }\n\n    return SelfDescribingJson(PLATFORM_SPEC, data)\n\n\ndef get_dbt_env_context():\n    default = \"manual\"\n\n    dbt_invocation_env = os.getenv(DBT_INVOCATION_ENV, default)\n    if dbt_invocation_env == \"\":\n        dbt_invocation_env = default\n\n    data = {\n        \"environment\": dbt_invocation_env,\n    }\n\n    return SelfDescribingJson(INVOCATION_ENV_SPEC, data)\n\n\ndef track(user, *args, **kwargs):\n    if user.do_not_track:\n        return\n\n    fire_event(SendingEvent(kwargs=str(kwargs)))\n    try:\n        tracker.track(StructuredEvent(*args, **kwargs))\n    except Exception:\n        fire_event(SendEventFailure())\n\n\ndef track_project_id(options):\n    assert active_user is not None, \"Cannot track project_id when active user is None\"\n    context = [SelfDescribingJson(PROJECT_ID_SPEC, options)]\n\n    track(\n        active_user,\n        category=\"dbt\",\n        action=\"project_id\",\n        label=get_invocation_id(),\n        context=context,\n    )\n\n\ndef track_adapter_info(options):\n    assert active_user is not None, \"Cannot track adapter_info when active user is None\"\n    context = [SelfDescribingJson(ADAPTER_INFO_SPEC, options)]\n\n    track(\n        active_user,\n        category=\"dbt\",\n        action=\"adapter_info\",\n        label=get_invocation_id(),\n        context=context,\n    )\n\n\ndef track_invocation_start(invocation_context):\n    data = {\"progress\": \"start\", \"result_type\": None, \"result\": None}\n    data.update(invocation_context)\n    context = [\n        SelfDescribingJson(INVOCATION_SPEC, data),\n        get_platform_context(),\n        get_dbt_env_context(),\n    ]\n\n    track(active_user, category=\"dbt\", action=\"invocation\", label=\"start\", context=context)\n\n\ndef track_project_load(options):\n    context = [SelfDescribingJson(LOAD_ALL_TIMING_SPEC, options)]\n    assert active_user is not None, \"Cannot track project loading time when active user is None\"\n\n    track(\n        active_user,\n        category=\"dbt\",\n        action=\"load_project\",\n        label=get_invocation_id(),\n        context=context,\n    )\n\n\ndef track_resource_counts(resource_counts):\n    context = [SelfDescribingJson(RESOURCE_COUNTS, resource_counts)]\n    assert active_user is not None, \"Cannot track resource counts when active user is None\"\n\n    track(\n        active_user,\n        category=\"dbt\",\n        action=\"resource_counts\",\n        label=get_invocation_id(),\n        context=context,\n    )\n\n\ndef track_model_run(options):\n    context = [SelfDescribingJson(RUN_MODEL_SPEC, options)]\n    assert active_user is not None, \"Cannot track model runs when active user is None\"\n\n    track(\n        active_user, category=\"dbt\", action=\"run_model\", label=get_invocation_id(), context=context\n    )\n\n\ndef track_rpc_request(options):\n    context = [SelfDescribingJson(RPC_REQUEST_SPEC, options)]\n    assert active_user is not None, \"Cannot track rpc requests when active user is None\"\n\n    track(\n        active_user,\n        category=\"dbt\",\n        action=\"rpc_request\",\n        label=get_invocation_id(),\n        context=context,\n    )\n\n\ndef get_base_invocation_context():\n    assert (\n        active_user is not None\n    ), \"initialize active user before calling get_base_invocation_context\"\n    return {\n        \"project_id\": None,\n        \"user_id\": active_user.id,\n        \"invocation_id\": active_user.invocation_id,\n        \"command\": None,\n        \"options\": None,\n        \"version\": str(dbt_version.installed),\n        \"run_type\": \"regular\",\n        \"adapter_type\": None,\n        \"adapter_unique_id\": None,\n    }\n\n\ndef track_package_install(command_name: str, project_hashed_name: Optional[str], options):\n    assert active_user is not None, \"Cannot track package installs when active user is None\"\n\n    invocation_data = get_base_invocation_context()\n\n    invocation_data.update({\"project_id\": project_hashed_name, \"command\": command_name})\n\n    context = [\n        SelfDescribingJson(INVOCATION_SPEC, invocation_data),\n        SelfDescribingJson(PACKAGE_INSTALL_SPEC, options),\n    ]\n\n    track(\n        active_user,\n        category=\"dbt\",\n        action=\"package\",\n        label=get_invocation_id(),\n        property_=\"install\",\n        context=context,\n    )\n\n\ndef track_deprecation_warn(options):\n\n    assert active_user is not None, \"Cannot track deprecation warnings when active user is None\"\n\n    context = [SelfDescribingJson(DEPRECATION_WARN_SPEC, options)]\n\n    track(\n        active_user,\n        category=\"dbt\",\n        action=\"deprecation\",\n        label=get_invocation_id(),\n        property_=\"warn\",\n        context=context,\n    )\n\n\ndef track_behavior_change_warn(msg: EventMsg) -> None:\n    if msg.info.name != \"BehaviorChangeEvent\" or active_user is None:\n        return\n\n    context = [SelfDescribingJson(BEHAVIOR_CHANGE_WARN_SPEC, msg_to_dict(msg))]\n    track(\n        active_user,\n        category=\"dbt\",\n        action=msg.info.name,\n        label=get_invocation_id(),\n        context=context,\n    )\n\n\ndef track_invocation_end(invocation_context, result_type=None):\n    data = {\"progress\": \"end\", \"result_type\": result_type, \"result\": None}\n    data.update(invocation_context)\n    context = [\n        SelfDescribingJson(INVOCATION_SPEC, data),\n        get_platform_context(),\n        get_dbt_env_context(),\n    ]\n\n    assert active_user is not None, \"Cannot track invocation end when active user is None\"\n\n    track(active_user, category=\"dbt\", action=\"invocation\", label=\"end\", context=context)\n\n\ndef track_invalid_invocation(args=None, result_type=None):\n    assert active_user is not None, \"Cannot track invalid invocations when active user is None\"\n    invocation_context = get_base_invocation_context()\n    invocation_context.update({\"command\": args.which})\n    data = {\"progress\": \"invalid\", \"result_type\": result_type, \"result\": None}\n    data.update(invocation_context)\n    context = [\n        SelfDescribingJson(INVOCATION_SPEC, data),\n        get_platform_context(),\n        get_dbt_env_context(),\n    ]\n    track(active_user, category=\"dbt\", action=\"invocation\", label=\"invalid\", context=context)\n\n\ndef track_experimental_parser_sample(options):\n    context = [SelfDescribingJson(EXPERIMENTAL_PARSER, options)]\n    assert (\n        active_user is not None\n    ), \"Cannot track experimental parser info when active user is None\"\n\n    track(\n        active_user,\n        category=\"dbt\",\n        action=\"experimental_parser\",\n        label=get_invocation_id(),\n        context=context,\n    )\n\n\ndef track_partial_parser(options):\n    context = [SelfDescribingJson(PARTIAL_PARSER, options)]\n    assert active_user is not None, \"Cannot track partial parser info when active user is None\"\n\n    track(\n        active_user,\n        category=\"dbt\",\n        action=\"partial_parser\",\n        label=get_invocation_id(),\n        context=context,\n    )\n\n\ndef track_plugin_get_nodes(options):\n    context = [SelfDescribingJson(PLUGIN_GET_NODES, options)]\n    assert active_user is not None, \"Cannot track plugin node info when active user is None\"\n\n    track(\n        active_user,\n        category=\"dbt\",\n        action=\"plugin_get_nodes\",\n        label=get_invocation_id(),\n        context=context,\n    )\n\n\ndef track_runnable_timing(options):\n    context = [SelfDescribingJson(RUNNABLE_TIMING, options)]\n    assert active_user is not None, \"Cannot track runnable info when active user is None\"\n    track(\n        active_user,\n        category=\"dbt\",\n        action=\"runnable_timing\",\n        label=get_invocation_id(),\n        context=context,\n    )\n\n\ndef track_artifact_upload(options):\n    context = [SelfDescribingJson(ARTIFACT_UPLOAD, options)]\n    assert active_user is not None, \"Cannot track artifact upload when active user is None\"\n\n    track(\n        active_user,\n        category=\"dbt\",\n        action=\"artifact_upload\",\n        label=get_invocation_id(),\n        context=context,\n    )\n\n\ndef flush():\n    fire_event(FlushEvents())\n    try:\n        tracker.flush()\n    except Exception:\n        fire_event(FlushEventsFailure())\n\n\ndef disable_tracking():\n    global active_user\n    if active_user is not None:\n        active_user.disable_tracking()\n    else:\n        active_user = User(None)\n\n\ndef do_not_track():\n    global active_user\n    active_user = User(None)\n\n\ndef initialize_from_flags(send_anonymous_usage_stats, profiles_dir):\n    global active_user\n    if send_anonymous_usage_stats:\n        active_user = User(profiles_dir)\n        try:\n            active_user.initialize()\n        except Exception:\n            fire_event(TrackingInitializeFailure(exc_info=traceback.format_exc()))\n            active_user = User(None)\n    else:\n        active_user = User(None)\n\n\n@contextmanager\ndef track_run(run_command=None):\n    invocation_context = get_base_invocation_context()\n    invocation_context[\"command\"] = run_command\n\n    track_invocation_start(invocation_context)\n    try:\n        yield\n        track_invocation_end(invocation_context, result_type=\"ok\")\n    except (NotImplementedError, FailedToConnectError) as e:\n        fire_event(MainEncounteredError(exc=str(e)))\n        track_invocation_end(invocation_context, result_type=\"error\")\n    except Exception:\n        track_invocation_end(invocation_context, result_type=\"error\")\n        raise\n    finally:\n        flush()\n"
  },
  {
    "path": "core/dbt/utils/__init__.py",
    "content": "# re-export utils\nfrom .utils import *  # noqa: F403\nfrom .utils import _coerce_decimal  # noqa: F401 somewhere in the codebase we use this\n"
  },
  {
    "path": "core/dbt/utils/artifact_upload.py",
    "content": "import time\nimport uuid\nimport zipfile\n\nimport requests\n\nimport dbt.tracking\nfrom dbt._pydantic_shim import BaseSettings  # type: ignore\nfrom dbt.config.runtime import UnsetProfile, load_project\nfrom dbt.constants import MANIFEST_FILE_NAME, RUN_RESULTS_FILE_NAME\nfrom dbt.events.types import ArtifactUploadSkipped, ArtifactUploadSuccess\nfrom dbt.exceptions import DbtProjectError\nfrom dbt_common.events.functions import fire_event\nfrom dbt_common.exceptions import DbtBaseException as DbtException\n\nMAX_RETRIES = 3\n\nEXECUTION_ARTIFACTS = [MANIFEST_FILE_NAME, RUN_RESULTS_FILE_NAME]\n\nPRODUCED_ARTIFACTS_PATHS: set[str] = set()\n\n\n# artifact paths calling this will be uploaded to dbt Cloud\ndef add_artifact_produced(artifact_path: str):\n    PRODUCED_ARTIFACTS_PATHS.add(artifact_path)\n\n\nclass ArtifactUploadConfig(BaseSettings):\n    tenant_hostname: str\n    DBT_CLOUD_TOKEN: str\n    DBT_CLOUD_ACCOUNT_ID: str\n    DBT_CLOUD_ENVIRONMENT_ID: str\n\n    def get_ingest_url(self):\n        return f\"https://{self.tenant_hostname}/api/private/accounts/{self.DBT_CLOUD_ACCOUNT_ID}/environments/{self.DBT_CLOUD_ENVIRONMENT_ID}/ingests/\"\n\n    def get_complete_url(self, ingest_id):\n        return f\"{self.get_ingest_url()}{ingest_id}/\"\n\n    def get_headers(self, invocation_id=None):\n        if invocation_id is None:\n            invocation_id = str(uuid.uuid4())\n        return {\n            \"Accept\": \"application/json\",\n            \"X-Invocation-Id\": invocation_id,\n            \"Authorization\": f\"Token {self.DBT_CLOUD_TOKEN}\",\n        }\n\n\ndef _retry_with_backoff(operation_name, func, max_retries=MAX_RETRIES, retry_codes=None):\n    \"\"\"Execute a function with exponential backoff retry logic.\n\n    Args:\n        operation_name: Name of the operation for error messages\n        func: Function to execute that returns (success, result)\n        max_retries: Maximum number of retry attempts\n\n    Returns:\n        The result from the function if successful\n\n    Raises:\n        DbtException: If all retry attempts fail\n    \"\"\"\n    if retry_codes is None:\n        retry_codes = [500, 502, 503, 504]\n    retry_delay = 1\n    for attempt in range(max_retries + 1):\n        try:\n            success, result = func()\n            if success:\n                return result\n\n            if result.status_code not in retry_codes:\n                raise DbtException(f\"Error {operation_name}: {result}\")\n            if attempt == max_retries:  # Last attempt\n                raise DbtException(f\"Error {operation_name}: {result}\")\n        except requests.RequestException as e:\n            if attempt == max_retries:  # Last attempt\n                raise DbtException(f\"Error {operation_name}: {str(e)}\")\n\n        time.sleep(retry_delay)\n        retry_delay *= 2  # exponential backoff\n\n\ndef upload_artifacts(project_dir, target_path, command):\n    # Check if there are artifacts to upload for this command\n    if not PRODUCED_ARTIFACTS_PATHS:\n        fire_event(ArtifactUploadSkipped(msg=\"No artifacts to upload for current command\"))\n        return\n\n    # read configurations\n    try:\n        project = load_project(\n            project_dir, version_check=False, profile=UnsetProfile(), cli_vars=None\n        )\n        if not project.dbt_cloud or \"tenant_hostname\" not in project.dbt_cloud:\n            raise DbtProjectError(\"dbt_cloud.tenant_hostname not found in dbt_project.yml\")\n        tenant_hostname = project.dbt_cloud[\"tenant_hostname\"]\n        if not tenant_hostname:\n            raise DbtProjectError(\"dbt_cloud.tenant_hostname is empty in dbt_project.yml\")\n    except Exception as e:\n        raise DbtProjectError(\n            f\"Error reading dbt_cloud.tenant_hostname from dbt_project.yml: {str(e)}\"\n        )\n\n    config = ArtifactUploadConfig(tenant_hostname=tenant_hostname)\n\n    if not target_path:\n        target_path = \"target\"\n\n    # Create zip file with artifacts\n    zip_file_name = \"target.zip\"\n    with zipfile.ZipFile(zip_file_name, \"w\") as z:\n        for artifact_path in PRODUCED_ARTIFACTS_PATHS:\n            z.write(artifact_path, artifact_path.split(\"/\")[-1])\n\n    # Step 1: Create ingest request with retry\n    def create_ingest():\n        response = requests.post(url=config.get_ingest_url(), headers=config.get_headers())\n        return response.status_code == 200, response\n\n    response = _retry_with_backoff(\"creating ingest request\", create_ingest)\n    response_data = response.json()\n    ingest_id = response_data[\"data\"][\"id\"]\n    upload_url = response_data[\"data\"][\"upload_url\"]\n\n    # Step 2: Upload the zip file to the provided URL with retry\n    with open(zip_file_name, \"rb\") as f:\n        file_data = f.read()\n\n        def upload_file():\n            upload_response = requests.put(url=upload_url, data=file_data)\n            return upload_response.status_code in (200, 204), upload_response\n\n        _retry_with_backoff(\"uploading artifacts\", upload_file)\n\n    # Step 3: Mark the ingest as successful with retry\n    def complete_ingest():\n        complete_response = requests.patch(\n            url=config.get_complete_url(ingest_id),\n            headers=config.get_headers(),\n            json={\"upload_status\": \"SUCCESS\"},\n        )\n        return complete_response.status_code == 204, complete_response\n\n    _retry_with_backoff(\"completing ingest\", complete_ingest)\n\n    fire_event(ArtifactUploadSuccess(msg=f\"command {command} completed successfully\"))\n    if dbt.tracking.active_user is not None:\n        dbt.tracking.track_artifact_upload({\"command\": command})\n    PRODUCED_ARTIFACTS_PATHS.clear()\n"
  },
  {
    "path": "core/dbt/utils/utils.py",
    "content": "import collections\nimport decimal\nimport functools\nimport itertools\nimport json\nimport os\nimport sys\nfrom datetime import date, datetime, time, timezone\nfrom enum import Enum\nfrom pathlib import PosixPath, WindowsPath\nfrom typing import (\n    AbstractSet,\n    Any,\n    Dict,\n    Iterable,\n    Iterator,\n    List,\n    Mapping,\n    Optional,\n    Sequence,\n    Set,\n    Tuple,\n    Type,\n)\n\nimport jinja2\n\nfrom dbt import flags\nfrom dbt.exceptions import DuplicateAliasError\nfrom dbt_common.exceptions import RecursionError\nfrom dbt_common.helper_types import WarnErrorOptionsV2\nfrom dbt_common.utils import md5\n\nDECIMALS: Tuple[Type[Any], ...]\ntry:\n    import cdecimal  # typing: ignore\nexcept ImportError:\n    DECIMALS = (decimal.Decimal,)\nelse:\n    DECIMALS = (decimal.Decimal, cdecimal.Decimal)\n\n\nclass ExitCodes(int, Enum):\n    Success = 0\n    ModelError = 1\n    UnhandledError = 2\n\n\ndef coalesce(*args):\n    for arg in args:\n        if arg is not None:\n            return arg\n    return None\n\n\ndef get_profile_from_project(project):\n    target_name = project.get(\"target\", {})\n    profile = project.get(\"outputs\", {}).get(target_name, {})\n    return profile\n\n\ndef get_model_name_or_none(model):\n    if model is None:\n        name = \"<None>\"\n\n    elif isinstance(model, str):\n        name = model\n    elif isinstance(model, dict):\n        name = model.get(\"alias\", model.get(\"name\"))\n    elif hasattr(model, \"alias\"):\n        name = model.alias\n    elif hasattr(model, \"name\"):\n        name = model.name\n    else:\n        name = str(model)\n    return name\n\n\ndef split_path(path):\n    return path.split(os.sep)\n\n\ndef get_pseudo_test_path(node_name, source_path):\n    \"schema tests all come from schema.yml files. fake a source sql file\"\n    source_path_parts = split_path(source_path)\n    source_path_parts.pop()  # ignore filename\n    suffix = [\"{}.sql\".format(node_name)]\n    pseudo_path_parts = source_path_parts + suffix\n    return os.path.join(*pseudo_path_parts)\n\n\ndef get_pseudo_hook_path(hook_name):\n    path_parts = [\"hooks\", \"{}.sql\".format(hook_name)]\n    return os.path.join(*path_parts)\n\n\ndef get_hash(model):\n    return md5(model.unique_id)\n\n\ndef get_hashed_contents(model):\n    return md5(model.raw_code)\n\n\ndef flatten_nodes(dep_list):\n    return list(itertools.chain.from_iterable(dep_list))\n\n\nclass memoized:\n    \"\"\"Decorator. Caches a function's return value each time it is called. If\n    called later with the same arguments, the cached value is returned (not\n    reevaluated).\n\n    Taken from https://wiki.python.org/moin/PythonDecoratorLibrary#Memoize\"\"\"\n\n    def __init__(self, func) -> None:\n        self.func = func\n        self.cache: Dict[Any, Any] = {}\n\n    def __call__(self, *args):\n        if not isinstance(args, collections.abc.Hashable):\n            # uncacheable. a list, for instance.\n            # better to not cache than blow up.\n            return self.func(*args)\n        if args in self.cache:\n            return self.cache[args]\n        value = self.func(*args)\n        self.cache[args] = value\n        return value\n\n    def __repr__(self):\n        \"\"\"Return the function's docstring.\"\"\"\n        return self.func.__doc__\n\n    def __get__(self, obj, objtype):\n        \"\"\"Support instance methods.\"\"\"\n        return functools.partial(self.__call__, obj)\n\n\ndef add_ephemeral_model_prefix(s: str) -> str:\n    return \"__dbt__cte__{}\".format(s)\n\n\ndef timestring() -> str:\n    \"\"\"Get the current datetime as an RFC 3339-compliant string\"\"\"\n    # isoformat doesn't include the mandatory trailing 'Z' for UTC.\n    return datetime.now(timezone.utc).replace(tzinfo=None).isoformat() + \"Z\"\n\n\ndef humanize_execution_time(execution_time: int) -> str:\n    minutes, seconds = divmod(execution_time, 60)\n    hours, minutes = divmod(minutes, 60)\n\n    return f\" in {int(hours)} hours {int(minutes)} minutes and {seconds:0.2f} seconds\"\n\n\nclass JSONEncoder(json.JSONEncoder):\n    \"\"\"A 'custom' json encoder that does normal json encoder things, but also\n    handles `Decimal`s and `Undefined`s. Decimals can lose precision because\n    they get converted to floats. Undefined's are serialized to an empty string\n    \"\"\"\n\n    def default(self, obj):\n        if isinstance(obj, DECIMALS):\n            return float(obj)\n        elif isinstance(obj, (datetime, date, time)):\n            return obj.isoformat()\n        elif isinstance(obj, jinja2.Undefined):\n            return \"\"\n        elif isinstance(obj, Exception):\n            return repr(obj)\n        elif hasattr(obj, \"to_dict\"):\n            # if we have a to_dict we should try to serialize the result of\n            # that!\n            return obj.to_dict(omit_none=True)\n        else:\n            return super().default(obj)\n\n\nclass Translator:\n    def __init__(self, aliases: Mapping[str, str], recursive: bool = False) -> None:\n        self.aliases = aliases\n        self.recursive = recursive\n\n    def translate_mapping(self, kwargs: Mapping[str, Any]) -> Dict[str, Any]:\n        result: Dict[str, Any] = {}\n\n        for key, value in kwargs.items():\n            canonical_key = self.aliases.get(key, key)\n            if canonical_key in result:\n                raise DuplicateAliasError(kwargs, self.aliases, canonical_key)\n            result[canonical_key] = self.translate_value(value)\n        return result\n\n    def translate_sequence(self, value: Sequence[Any]) -> List[Any]:\n        return [self.translate_value(v) for v in value]\n\n    def translate_value(self, value: Any) -> Any:\n        if self.recursive:\n            if isinstance(value, Mapping):\n                return self.translate_mapping(value)\n            elif isinstance(value, (list, tuple)):\n                return self.translate_sequence(value)\n        return value\n\n    def translate(self, value: Mapping[str, Any]) -> Dict[str, Any]:\n        try:\n            return self.translate_mapping(value)\n        except RuntimeError as exc:\n            if \"maximum recursion depth exceeded\" in str(exc):\n                raise RecursionError(\"Cycle detected in a value passed to translate!\")\n            raise\n\n\ndef translate_aliases(\n    kwargs: Dict[str, Any],\n    aliases: Dict[str, str],\n    recurse: bool = False,\n) -> Dict[str, Any]:\n    \"\"\"Given a dict of keyword arguments and a dict mapping aliases to their\n    canonical values, canonicalize the keys in the kwargs dict.\n\n    If recurse is True, perform this operation recursively.\n\n    :returns: A dict containing all the values in kwargs referenced by their\n        canonical key.\n    :raises: `AliasError`, if a canonical key is defined more than once.\n    \"\"\"\n    translator = Translator(aliases, recurse)\n    return translator.translate(kwargs)\n\n\n# Note that this only affects hologram json validation.\n# It has no effect on mashumaro serialization.\n# Q: Can this be removed?\ndef restrict_to(*restrictions):\n    \"\"\"Create the metadata for a restricted dataclass field\"\"\"\n    return {\"restrict\": list(restrictions)}\n\n\ndef coerce_dict_str(value: Any) -> Optional[Dict[str, Any]]:\n    \"\"\"For annoying mypy reasons, this helper makes dealing with nested dicts\n    easier. You get either `None` if it's not a Dict[str, Any], or the\n    Dict[str, Any] you expected (to pass it to dbtClassMixin.from_dict(...)).\n    \"\"\"\n    if isinstance(value, dict) and all(isinstance(k, str) for k in value):\n        return value\n    else:\n        return None\n\n\ndef _coerce_decimal(value):\n    if isinstance(value, DECIMALS):\n        return float(value)\n    return value\n\n\ndef fqn_search(root: Dict[str, Any], fqn: List[str]) -> Iterator[Dict[str, Any]]:\n    \"\"\"Iterate into a nested dictionary, looking for keys in the fqn as levels.\n    Yield the level config.\n    \"\"\"\n    yield root\n\n    for level in fqn:\n        level_config = root.get(level, None)\n        if not isinstance(level_config, dict):\n            break\n        # This used to do a 'deepcopy',\n        # but it didn't seem to be necessary\n        yield level_config\n        root = level_config\n\n\nStringMap = Mapping[str, Any]\nStringMapList = List[StringMap]\nStringMapIter = Iterable[StringMap]\n\n\nclass MultiDict(Mapping[str, Any]):\n    \"\"\"Implement the mapping protocol using a list of mappings. The most\n    recently added mapping \"wins\".\n    \"\"\"\n\n    def __init__(self, sources: Optional[StringMapList] = None) -> None:\n        super().__init__()\n        self.sources: StringMapList\n\n        if sources is None:\n            self.sources = []\n        else:\n            self.sources = sources\n\n    def add_from(self, sources: StringMapIter):\n        self.sources.extend(sources)\n\n    def add(self, source: StringMap):\n        self.sources.append(source)\n\n    def _keyset(self) -> AbstractSet[str]:\n        # return the set of keys\n        keys: Set[str] = set()\n        for entry in self._itersource():\n            keys.update(entry)\n        return keys\n\n    def _itersource(self) -> StringMapIter:\n        return reversed(self.sources)\n\n    def __iter__(self) -> Iterator[str]:\n        # we need to avoid duplicate keys\n        return iter(self._keyset())\n\n    def __len__(self):\n        return len(self._keyset())\n\n    def __getitem__(self, name: str) -> Any:\n        for entry in self._itersource():\n            if name in entry:\n                return entry[name]\n        raise KeyError(name)\n\n    def __contains__(self, name) -> bool:\n        return any((name in entry for entry in self._itersource()))\n\n\n# This is used to serialize the args in the run_results and in the logs.\n# We do this separately because there are a few fields that don't serialize,\n# i.e. PosixPath, WindowsPath, and types. It also includes args from both\n# cli args and flags, which is more complete than just the cli args.\n# If new args are added that are false by default (particularly in the\n# global options) they should be added to the 'default_false_keys' list.\ndef args_to_dict(args):\n    var_args = vars(args).copy()\n    # update the args with the flags, which could also come from environment\n    # variables or project_flags\n    flag_dict = flags.get_flag_dict()\n    var_args.update(flag_dict)\n    dict_args = {}\n    # remove args keys that clutter up the dictionary\n    for key in var_args:\n        if key.lower() in var_args and key == key.upper():\n            # skip all capped keys being introduced by Flags in dbt.cli.flags\n            continue\n        if key in [\"cls\", \"mp_context\"]:\n            continue\n        if var_args[key] is None:\n            continue\n        # TODO: add more default_false_keys\n        default_false_keys = (\n            \"debug\",\n            \"full_refresh\",\n            \"fail_fast\",\n            \"warn_error\",\n            \"single_threaded\",\n            \"log_cache_events\",\n            \"store_failures\",\n            \"use_experimental_parser\",\n        )\n        default_empty_yaml_dict_keys = (\"vars\", \"warn_error_options\")\n        if key in default_false_keys and var_args[key] is False:\n            continue\n        if key in default_empty_yaml_dict_keys and var_args[key] == \"{}\":\n            continue\n        # this was required for a test case\n        if isinstance(var_args[key], PosixPath) or isinstance(var_args[key], WindowsPath):\n            var_args[key] = str(var_args[key])\n        if isinstance(var_args[key], WarnErrorOptionsV2):\n            var_args[key] = var_args[key].to_dict()\n\n        dict_args[key] = var_args[key]\n    return dict_args\n\n\n# Taken from https://github.com/python/cpython/blob/3.11/Lib/distutils/util.py\n# This is a copy of the function from distutils.util, which was removed in Python 3.12.\ndef strtobool(val: str) -> bool:\n    \"\"\"Convert a string representation of truth to True or False.\n\n    True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values\n    are 'n', 'no', 'f', 'false', 'off', and '0'.  Raises ValueError if\n    'val' is anything else.\n    \"\"\"\n    val = val.lower()\n    if val in (\"y\", \"yes\", \"t\", \"true\", \"on\", \"1\"):\n        return True\n    elif val in (\"n\", \"no\", \"f\", \"false\", \"off\", \"0\"):\n        return False\n    else:\n        raise ValueError(\"invalid truth value %r\" % (val,))\n\n\ndef try_get_max_rss_kb() -> Optional[int]:\n    \"\"\"Attempts to get the high water mark for this process's memory use via\n    the most reliable and accurate mechanism available through the host OS.\n    Currently only implemented for Linux.\"\"\"\n    if sys.platform == \"linux\" and os.path.isfile(\"/proc/self/status\"):\n        try:\n            # On Linux, the most reliable documented mechanism for getting the RSS\n            # high-water-mark comes from the line confusingly labeled VmHWM in the\n            # /proc/self/status virtual file.\n            with open(\"/proc/self/status\") as f:\n                for line in f:\n                    if line.startswith(\"VmHWM:\"):\n                        return int(str.split(line)[1])\n        except Exception:\n            pass\n\n    return None\n"
  },
  {
    "path": "core/dbt/version.py",
    "content": "import glob\nimport importlib\nimport importlib.util\nimport json\nimport os\nfrom importlib import metadata as importlib_metadata\nfrom typing import Iterator, List, Optional, Tuple\n\nimport requests\n\nimport dbt_common.semver as semver\nfrom dbt.__version__ import version as __version_string\nfrom dbt_common.ui import green, yellow\n\nPYPI_VERSION_URL = \"https://pypi.org/pypi/dbt-core/json\"\n\n\ndef get_version_information() -> str:\n    installed = get_installed_version()\n    latest = get_latest_version()\n\n    core_msg_lines, core_info_msg = _get_core_msg_lines(installed, latest)\n    core_msg = _format_core_msg(core_msg_lines)\n    plugin_version_msg = _get_plugins_msg()\n\n    msg_lines = [core_msg]\n\n    if core_info_msg != \"\":\n        msg_lines.append(core_info_msg)\n\n    msg_lines.append(plugin_version_msg)\n    msg_lines.append(\"\")\n\n    return \"\\n\\n\".join(msg_lines)\n\n\ndef get_installed_version() -> semver.VersionSpecifier:\n    return semver.VersionSpecifier.from_version_string(__version__)\n\n\ndef get_latest_version(\n    version_url: str = PYPI_VERSION_URL,\n) -> Optional[semver.VersionSpecifier]:\n    try:\n        resp = requests.get(version_url, timeout=1)\n        data = resp.json()\n        version_string = data[\"info\"][\"version\"]\n    except (json.JSONDecodeError, KeyError, requests.RequestException):\n        return None\n\n    return semver.VersionSpecifier.from_version_string(version_string)\n\n\ndef _get_core_msg_lines(\n    installed: semver.VersionSpecifier,\n    latest: Optional[semver.VersionSpecifier],\n) -> Tuple[List[List[str]], str]:\n    installed_s = installed.to_version_string(skip_matcher=True)\n    installed_line = [\"installed\", installed_s, \"\"]\n    update_info = \"\"\n\n    if latest is None:\n        update_info = (\n            \"  The latest version of dbt-core could not be determined!\\n\"\n            \"  Make sure that the following URL is accessible:\\n\"\n            f\"  {PYPI_VERSION_URL}\"\n        )\n        return [installed_line], update_info\n\n    latest_s = latest.to_version_string(skip_matcher=True)\n    latest_line = [\"latest\", latest_s, green(\"Up to date!\")]\n\n    if installed > latest:\n        latest_line[2] = yellow(\"Ahead of latest version!\")\n    elif installed < latest:\n        latest_line[2] = yellow(\"Update available!\")\n        update_info = (\n            \"  Your version of dbt-core is out of date!\\n\"\n            \"  You can find instructions for upgrading here:\\n\"\n            \"  https://docs.getdbt.com/docs/installation\"\n        )\n\n    return [\n        installed_line,\n        latest_line,\n    ], update_info\n\n\ndef _format_core_msg(lines: List[List[str]]) -> str:\n    msg = \"Core:\\n\"\n    msg_lines = []\n\n    for name, version, update_msg in _pad_lines(lines, seperator=\":\"):\n        line_msg = f\"  - {name} {version}\"\n        if update_msg != \"\":\n            line_msg += f\" - {update_msg}\"\n        msg_lines.append(line_msg)\n\n    return msg + \"\\n\".join(msg_lines)\n\n\ndef _get_plugins_msg() -> str:\n    msg_lines = [\"Plugins:\"]\n\n    plugins = []\n    display_update_msg = False\n    for name, version_s in _get_dbt_plugins_info():\n        compatability_msg, needs_update = _get_plugin_msg_info(name, version_s, installed)\n        if needs_update:\n            display_update_msg = True\n        plugins.append([name, version_s, compatability_msg])\n\n    for plugin in _pad_lines(plugins, seperator=\":\"):\n        msg_lines.append(_format_single_plugin(plugin, \"\"))\n\n    if display_update_msg:\n        update_msg = (\n            \"  At least one plugin is out of date with dbt-core.\\n\"\n            \"  You can find instructions for upgrading here:\\n\"\n            \"  https://docs.getdbt.com/docs/installation\"\n        )\n        msg_lines += [\"\", update_msg]\n\n    return \"\\n\".join(msg_lines)\n\n\ndef _get_plugin_msg_info(\n    name: str, version_s: str, core: semver.VersionSpecifier\n) -> Tuple[str, bool]:\n    plugin = semver.VersionSpecifier.from_version_string(version_s)\n    latest_plugin = get_latest_version(version_url=get_package_pypi_url(name))\n\n    needs_update = False\n\n    if not latest_plugin:\n        compatibility_msg = yellow(\"Could not determine latest version\")\n        return (compatibility_msg, needs_update)\n\n    if plugin < latest_plugin:\n        compatibility_msg = yellow(\"Update available!\")\n        needs_update = True\n    elif plugin > latest_plugin:\n        compatibility_msg = yellow(\"Ahead of latest version!\")\n    else:\n        compatibility_msg = green(\"Up to date!\")\n\n    return (compatibility_msg, needs_update)\n\n\ndef _format_single_plugin(plugin: List[str], update_msg: str) -> str:\n    name, version_s, compatability_msg = plugin\n    msg = f\"  - {name} {version_s} - {compatability_msg}\"\n    if update_msg != \"\":\n        msg += f\"\\n{update_msg}\\n\"\n    return msg\n\n\ndef _pad_lines(lines: List[List[str]], seperator: str = \"\") -> List[List[str]]:\n    if len(lines) == 0:\n        return []\n\n    # count the max line length for each column in the line\n    counter = [0] * len(lines[0])\n    for line in lines:\n        for i, item in enumerate(line):\n            counter[i] = max(counter[i], len(item))\n\n    result: List[List[str]] = []\n    for i, line in enumerate(lines):\n        # add another list to hold padded strings\n        if len(result) == i:\n            result.append([\"\"] * len(line))\n\n        # iterate over columns in the line\n        for j, item in enumerate(line):\n            # the last column does not need padding\n            if j == len(line) - 1:\n                result[i][j] = item\n                continue\n\n            # if the following column has no length\n            # the string does not need padding\n            if counter[j + 1] == 0:\n                result[i][j] = item\n                continue\n\n            # only add the seperator to the first column\n            offset = 0\n            if j == 0 and seperator != \"\":\n                item += seperator\n                offset = len(seperator)\n\n            result[i][j] = item.ljust(counter[j] + offset)\n\n    return result\n\n\ndef get_package_pypi_url(package_name: str) -> str:\n    return f\"https://pypi.org/pypi/dbt-{package_name}/json\"\n\n\ndef _get_dbt_plugins_info() -> Iterator[Tuple[str, str]]:\n    for plugin_name in _get_adapter_plugin_names():\n        if plugin_name == \"core\":\n            continue\n        try:\n            mod = importlib.import_module(f\"dbt.adapters.{plugin_name}.__version__\")\n        except ImportError:\n            # not an adapter\n            continue\n        yield plugin_name, mod.version\n\n\ndef _get_adapter_plugin_names() -> Iterator[str]:\n    spec = importlib.util.find_spec(\"dbt.adapters\")\n    # If None, then nothing provides an importable 'dbt.adapters', so we will\n    # not be reporting plugin versions today\n    if spec is None or spec.submodule_search_locations is None:\n        return\n\n    for adapters_path in spec.submodule_search_locations:\n        version_glob = os.path.join(adapters_path, \"*\", \"__version__.py\")\n        for version_path in glob.glob(version_glob):\n            # the path is like .../dbt/adapters/{plugin_name}/__version__.py\n            # except it could be \\\\ on windows!\n            plugin_root, _ = os.path.split(version_path)\n            _, plugin_name = os.path.split(plugin_root)\n            yield plugin_name\n\n\ndef _resolve_version() -> str:\n    try:\n        return importlib_metadata.version(\"dbt-core\")\n    except importlib_metadata.PackageNotFoundError:\n        # When running from source (not installed), use version from __version__.py\n        return __version_string\n\n\n__version__ = _resolve_version()\ninstalled = get_installed_version()\n"
  },
  {
    "path": "core/hatch.toml",
    "content": "[version]\npath = \"dbt/__version__.py\"\n\n[build.targets.wheel]\npackages = [\"dbt\"]\nonly-packages = true\nexclude = [\n    \"**/*.md\",\n]\nartifacts = [\n    \"dbt/include/**/*.py\",\n    \"dbt/include/**/*.sql\",\n    \"dbt/include/**/*.yml\",\n    \"dbt/include/**/*.html\",\n    \"dbt/include/**/*.md\",\n    \"dbt/include/**/.gitkeep\",\n    \"dbt/include/**/.gitignore\",\n    \"dbt/task/docs/**/*.html\",\n    \"dbt/jsonschemas/**/*.json\",\n    \"dbt/py.typed\",\n    # Directories without __init__.py (namespace packages)\n    \"dbt/artifacts/resources/v1/**/*.py\",\n    \"dbt/artifacts/utils/**/*.py\",\n    \"dbt/event_time/**/*.py\",\n    \"dbt/docs/source/**/*.py\",\n    \"dbt/tests/util.py\",\n]\n\n[build.targets.sdist]\ninclude = [\n    \"/dbt\",\n    \"/README.md\",\n]\n\n[build.targets.sdist.force-include]\n\"dbt/task/docs/index.html\" = \"dbt/task/docs/index.html\"\n\n[envs.default]\n# Python 3.10-3.11 required locally due to flake8==4.0.1 compatibility\n# CI uses [envs.ci] which doesn't set python, allowing matrix testing\npython = \"3.11\"\ndependencies = [\n    # Git dependencies for development against main branches\n    \"dbt-adapters @ git+https://github.com/dbt-labs/dbt-adapters.git@main#subdirectory=dbt-adapters\",\n    \"dbt-tests-adapter @ git+https://github.com/dbt-labs/dbt-adapters.git@main#subdirectory=dbt-tests-adapter\",\n    \"dbt-common @ git+https://github.com/dbt-labs/dbt-common.git@main\",\n    \"dbt-postgres @ git+https://github.com/dbt-labs/dbt-adapters.git@main#subdirectory=dbt-postgres\",\n    # Code quality\n    \"pre-commit~=3.7.0\",\n    \"black>=24.3,<25.0\",\n    \"flake8==4.0.1\",  # requires python <3.12\n    \"mypy==1.4.1\",  # update requires code fixes\n    \"isort==5.13.2\",\n    # Testing\n    \"pytest>=7.0,<8.0\",\n    \"pytest-xdist~=3.6\",\n    \"pytest-csv~=3.0\",\n    \"pytest-cov\",\n    \"pytest-dotenv\",\n    \"pytest-ignore-test-results\",\n    \"pytest-mock\",\n    \"pytest-split\",\n    \"pytest-logbook~=1.2\",\n    \"logbook<1.9\",\n    \"flaky\",\n    \"freezegun>=1.5.1\",\n    \"hypothesis\",\n    \"mocker\",\n    # Debugging\n    \"ipdb\",\n    \"ddtrace==2.21.3\",\n    # Documentation\n    \"docutils\",\n    \"sphinx\",\n    # Type stubs\n    \"types-docutils\",\n    \"types-PyYAML\",\n    \"types-Jinja2\",\n    \"types-jsonschema\",\n    \"types-mock\",\n    \"types-protobuf>=5.0,<6.0\",\n    \"types-python-dateutil\",\n    \"types-pytz\",\n    \"types-requests\",\n    \"types-setuptools\",\n    # Other\n    \"pip-tools\",\n    \"protobuf>=6.0,<7.0\",\n]\n\npre-install-commands = [\n    \"pip install -e .\",\n]\n\n[envs.default.scripts]\n# Setup commands\nsetup = [\n    \"pre-commit install\",\n]\n\ndev-req = [\n    \"pip install -e .\",\n]\n\n# Code quality commands\ncode-quality = \"pre-commit run --all-files\"\nlint = [\n    \"pre-commit run flake8-check --hook-stage manual --all-files\",\n    \"pre-commit run mypy-check --hook-stage manual --all-files\",\n]\nflake8 = \"pre-commit run flake8-check --hook-stage manual --all-files\"\nmypy = \"pre-commit run mypy-check --hook-stage manual --all-files\"\nblack = \"pre-commit run black-check --hook-stage manual --all-files\"\n\n# Testing commands\nunit-tests = \"python -m pytest {args} ../tests/unit\"\nintegration-tests = \"python -m pytest -nauto {args} ../tests/functional\"\nintegration-tests-fail-fast = \"python -m pytest -x -nauto {args} ../tests/functional\"\ntest = [\n    \"python -m pytest ../tests/unit\",\n    \"pre-commit run black-check --hook-stage manual --all-files\",\n    \"pre-commit run flake8-check --hook-stage manual --all-files\",\n    \"pre-commit run mypy-check --hook-stage manual --all-files\",\n]\n\n# Database setup\nsetup-db = [\n    \"docker compose up -d database\",\n    \"bash ../scripts/setup_db.sh\",\n]\n\n# Utility commands\nclean = [\n    \"rm -f .coverage\",\n    \"rm -f .coverage.*\",\n    \"rm -rf .eggs/\",\n    \"rm -rf build/\",\n    \"rm -rf dbt.egg-info/\",\n    \"rm -f dbt_project.yml\",\n    \"rm -rf dist/\",\n    \"find . -type f -name '*.pyc' -delete\",\n    \"find . -type d -name __pycache__ -exec rm -rf {} +\",\n]\njson-schema = \"python ../scripts/collect-artifact-schema.py --path ../schemas\"\n\n[envs.build]\npython = \"3.11\"\ndetached = true\ndependencies = [\n    \"wheel\",\n    \"twine\",\n    \"check-wheel-contents\",\n]\n\n[envs.build.scripts]\ncheck-all = [\n    # Run check-wheel-contents first, before any installation overwrites dependencies\n    \"check-wheel-contents ./dist/*.whl --ignore W007,W008\",\n    \"check-wheel\",\n    \"check-sdist\",\n]\ncheck-wheel = [\n    \"twine check ./dist/*\",\n    \"find ./dist/dbt_core-*.whl -maxdepth 1 -type f | xargs python -m pip install --force-reinstall --find-links=./dist/\",\n    \"pip freeze | grep dbt-core\",\n    \"dbt --version\",\n]\ncheck-sdist = [\n    \"find ./dist/dbt_core-*.gz -maxdepth 1 -type f | xargs python -m pip install --force-reinstall --find-links=./dist/\",\n    \"pip freeze | grep dbt-core\",\n    \"dbt --version\",\n]\n\n# CI environment - isolated environment with test dependencies\n[envs.ci]\ndependencies = [\n    # Git dependencies for development against main branches\n    \"dbt-adapters @ git+https://github.com/dbt-labs/dbt-adapters.git@main#subdirectory=dbt-adapters\",\n    \"dbt-tests-adapter @ git+https://github.com/dbt-labs/dbt-adapters.git@main#subdirectory=dbt-tests-adapter\",\n    \"dbt-common @ git+https://github.com/dbt-labs/dbt-common.git@main\",\n    \"dbt-postgres @ git+https://github.com/dbt-labs/dbt-adapters.git@main#subdirectory=dbt-postgres\",\n    # Testing\n    \"pre-commit~=3.7.0\",\n    \"pytest>=7.0,<8.0\",\n    \"pytest-cov\",\n    \"pytest-xdist~=3.6\",\n    \"pytest-csv~=3.0\",\n    \"pytest-dotenv\",\n    \"pytest-ignore-test-results\",\n    \"pytest-mock\",\n    \"pytest-split\",\n    \"ddtrace==2.21.3\",\n    \"flaky\",\n    \"freezegun>=1.5.1\",\n    \"hypothesis\",\n]\n\npre-install-commands = [\n    \"pip install -e .\",\n]\n\n[envs.ci.env-vars]\nDBT_TEST_USER_1 = \"dbt_test_user_1\"\nDBT_TEST_USER_2 = \"dbt_test_user_2\"\nDBT_TEST_USER_3 = \"dbt_test_user_3\"\n# Use new ddtrace pytest plugin to avoid deprecation warnings (old plugin removed in 3.0.0)\nDD_PYTEST_USE_NEW_PLUGIN_BETA = \"true\"\n\n\n\n[envs.ci.scripts]\nunit-tests = \"python -m pytest --cov=dbt --cov-report=xml {args} ../tests/unit\"\ncode-quality = \"pre-commit run --all-files\"\n# pytest-split algorithm: we use 'least_duration' instead of the default 'duration_based_chunks'\n# because duration_based_chunks maintains alphabetical order and can create very uneven test\n# counts per group (e.g., 294 tests in group 1 vs 90 in others). Even with equal total duration,\n# more tests means more per-test overhead (fixture setup/teardown, DB connections, temp files)\n# which causes timeouts. least_duration distributes tests evenly across groups by count while\n# still balancing duration, avoiding the overhead problem.\nintegration-tests = \"python -m pytest --cov=dbt --cov-report=xml -nauto --durations-path .test_durations --splitting-algorithm least_duration {args} ../tests/functional\"\n# Used by update-test-durations.yml to generate duration data (runs in parallel split groups)\nintegration-tests-generate-durations = \"python -m pytest -nauto --durations-path .test_durations --splitting-algorithm least_duration --store-durations {args} ../tests/functional\"\n\n# Note: Python version matrix is handled by GitHub Actions CI, not hatch.\n# This avoids running tests 4x per job. The CI sets up the Python version\n# and hatch uses whatever Python is active.\n"
  },
  {
    "path": "core/pyproject.toml",
    "content": "\n[project]\nname = \"dbt-core\"\ndynamic = [\"version\"]\ndescription = \"With dbt, data analysts and engineers can build analytics the way engineers build applications.\"\nreadme = \"README.md\"\nrequires-python = \">=3.10\"\nlicense = \"Apache-2.0\"\nlicense-files = { globs = [\"LICENSE\"] }\nkeywords = []\nauthors = [\n    { name = \"dbt Labs\", email = \"info@dbtlabs.com\" },\n]\nmaintainers = [\n    { name = \"dbt Labs\", email = \"info@dbtlabs.com\" },\n]\nclassifiers = [\n    \"Development Status :: 5 - Production/Stable\",\n    \"Operating System :: Microsoft :: Windows\",\n    \"Operating System :: MacOS :: MacOS X\",\n    \"Operating System :: POSIX :: Linux\",\n    \"Programming Language :: Python\",\n    \"Programming Language :: Python :: 3.10\",\n    \"Programming Language :: Python :: 3.11\",\n    \"Programming Language :: Python :: 3.12\",\n    \"Programming Language :: Python :: 3.13\",\n    \"Programming Language :: Python :: Implementation :: CPython\",\n    \"Programming Language :: Python :: Implementation :: PyPy\",\n]\ndependencies = [\n    # ----\n    # dbt-core uses these packages deeply, throughout the codebase, and there have been breaking changes in past patch releases (even though these are major-version-one).\n    # Pin to the patch or minor version, and bump in each new minor version of dbt-core.\n    \"agate>=1.7.0,<1.10\",\n    \"Jinja2>=3.1.3,<4\",\n    \"mashumaro[msgpack]>=3.9,<3.15\",\n    # ----\n    # dbt-core uses these packages in standard ways. Pin to the major version, and check compatibility\n    # with major versions in each new minor version of dbt-core.\n    \"click>=8.3.0,<9.0\",\n    \"jsonschema>=4.19.1,<5.0\",\n    \"networkx>=2.3,<4.0\",\n    \"protobuf>=6.0,<7.0\",\n    \"requests<3.0.0\",  # should match dbt-common\n    \"snowplow-tracker>=1.0.2,<2.0\",\n    # ----\n    # These packages are major-version-0. Keep upper bounds on upcoming minor versions (which could have breaking changes)\n    # and check compatibility / bump in each new minor version of dbt-core.\n    \"pathspec>=0.9,<0.13\",\n    \"sqlparse>=0.5.5,<0.6.0\",\n    # ----\n    # These are major-version-0 packages also maintained by dbt-labs.\n    # Accept patches but avoid automatically updating past a set minor version range.\n    \"dbt-extractor>=0.5.0,<=0.6\",\n    \"dbt-semantic-interfaces>=0.10.2,<0.11\",\n    # Minor versions for these are expected to be backwards-compatible\n    \"dbt-common>=1.37.3,<2.0\",\n    \"dbt-adapters>=1.22.8,<2.0\",\n    \"dbt-protos>=1.0.419,<2.0\",\n    \"pydantic<3\",\n    # ----\n    # Expect compatibility with all new versions of these packages, so lower bounds only.\n    \"packaging>20.9\",\n    \"pytz>=2015.7\",\n    \"pyyaml>=6.0\",\n    \"daff>=1.3.46\",\n    \"typing-extensions>=4.4\",\n]\n\n[project.urls]\nHomepage = \"https://github.com/dbt-labs/dbt-core\"\nRepository = \"https://github.com/dbt-labs/dbt-core.git\"\nIssues = \"https://github.com/dbt-labs/dbt-core/issues\"\nChangelog = \"https://github.com/dbt-labs/dbt-core/blob/main/CHANGELOG.md\"\n\n[project.scripts]\ndbt = \"dbt.cli.main:cli\"\n\n[tool.hatch.version]\npath = \"dbt/__version__.py\"\n\n\n[build-system]\nrequires = [\"hatchling\"]\nbuild-backend = \"hatchling.build\"\n"
  },
  {
    "path": "docker/Dockerfile",
    "content": "ARG py_version=3.11.2\n\nFROM python:$py_version-slim-bullseye AS base\n\nRUN apt-get update \\\n  # Install version-pinned packages for reproducible builds\n  && apt-get install -y --no-install-recommends \\\n    build-essential=12.9 \\\n    ca-certificates=20210119 \\\n    libpq-dev=13.23-0+deb11u1 \\\n    make=4.3-4.1 \\\n    openssh-client=1:8.4p1-5+deb11u3 \\\n    software-properties-common=0.96.20.2-2.1 \\\n  # Prevent dist-upgrade from changing pinned package versions\n  && apt-mark hold \\\n    build-essential \\\n    ca-certificates \\\n    libpq-dev \\\n    make \\\n    openssh-client \\\n    software-properties-common \\\n  # Apply security updates to non-pinned base image packages\n  && apt-get dist-upgrade -y \\\n  # Install temporary dependencies for building git from source (removed later)\n  && apt-get install -y --no-install-recommends \\\n    wget \\\n    libcurl4-gnutls-dev \\\n    libexpat1-dev \\\n    libssl-dev \\\n    zlib1g-dev \\\n  # Build and install git from source to get 2.50.1 since debian only ships with 2.47 for now\n  && wget https://github.com/git/git/archive/refs/tags/v2.50.1.tar.gz \\\n  && tar -xf v2.50.1.tar.gz \\\n  && cd git-2.50.1 \\\n  && make prefix=/usr/local NO_TCLTK=1 NO_GETTEXT=1 all \\\n  && make prefix=/usr/local NO_TCLTK=1 NO_GETTEXT=1 install \\\n  && cd .. \\\n  && rm -rf git-2.50.1 v2.50.1.tar.gz \\\n  # Remove build dependencies to keep image slim\n  && apt-get remove -y \\\n    libcurl4-gnutls-dev \\\n    libexpat1-dev \\\n    libssl-dev \\\n    wget \\\n    zlib1g-dev \\\n  && apt-get autoremove -y \\\n  && apt-get clean \\\n  && rm -rf \\\n    /var/lib/apt/lists/* \\\n    /tmp/* \\\n    /var/tmp/*\n\nENV PYTHONIOENCODING=utf-8\nENV LANG=C.UTF-8\n\nRUN python -m pip install --upgrade \"pip==24.0\" \"setuptools==69.2.0\" \"wheel==0.43.0\" --no-cache-dir\n\n\nFROM base AS dbt-core\n\nARG commit_ref=main\n\nHEALTHCHECK CMD dbt --version || exit 1\n\nWORKDIR /usr/app/dbt/\nENTRYPOINT [\"dbt\"]\n\nRUN python -m pip install --no-cache-dir \"dbt-core @ git+https://github.com/dbt-labs/dbt-core@${commit_ref}#subdirectory=core\"\n\n\nFROM base AS dbt-postgres\n\nARG commit_ref=main\n\nHEALTHCHECK CMD dbt --version || exit 1\n\nWORKDIR /usr/app/dbt/\nENTRYPOINT [\"dbt\"]\n\nRUN python -m pip install --no-cache-dir \"dbt-postgres @ git+https://github.com/dbt-labs/dbt-core@${commit_ref}#subdirectory=plugins/postgres\"\n\n\nFROM dbt-core AS dbt-third-party\n\nARG dbt_third_party\n\nRUN if [ \"$dbt_third_party\" ]; then \\\n        python -m pip install --no-cache-dir \"${dbt_third_party}\"; \\\n    else \\\n        echo \"No third party adapter provided\"; \\\n    fi \\\n"
  },
  {
    "path": "docker/README.md",
    "content": "# Docker for dbt\nThis docker file is suitable for building dbt Docker images locally or using with CI/CD to automate populating a container registry.\n\n\n## Building an image:\nThis Dockerfile can create images for the following targets, each named after the database they support:\n* `dbt-core` _(no db-adapter support)_\n* `dbt-third-party` _(requires additional build-arg)_\n\nFor platform-specific images, please refer to that platform's repository (eg. [dbt-postgres](https://github.com/dbt-labs/dbt-adapters/blob/main/dbt-postgres/docker/README.md))\n\nIn order to build a new image, run the following docker command.\n```\ndocker build --tag <your_image_name> --target <target_name> <path/to/dockerfile>\n```\n---\n> **Note:**  Docker must be configured to use [BuildKit](https://docs.docker.com/develop/develop-images/build_enhancements/) in order for images to build properly!\n\n---\n\nBy default the images will be populated with `dbt-core` on `main`.\nIf you need to use a different version you can specify it by git ref (tag, branch, sha) using the `--build-arg` flag:\n```\ndocker build --tag <your_image_name> \\\n  --target <target_name> \\\n  --build-arg commit_ref=<git_ref> \\\n  <path/to/dockerfile>\n```\n\nIf you wish to build an image with a third-party adapter you can use the `dbt-third-party` target.\nThis target requires you provide a path to the adapter that can be processed by `pip` by using the `dbt_third_party` build arg:\n```\ndocker build --tag <your_image_name> \\\n  --target dbt-third-party \\\n  --build-arg dbt_third_party=<pip_parsable_install_string> \\\n  <path/to/dockerfile>\n```\nThis can also be combined with the `commit_ref` build arg to specify a version of `dbt-core`.\n\n### Examples:\nTo build an image named \"my-third-party-dbt\" that uses the latest release of [Materialize third party adapter](https://github.com/MaterializeInc/materialize/tree/main/misc/dbt-materialize) and the latest dev version of `dbt-core`:\n```\ncd dbt-core/docker\ndocker build --tag my-third-party-dbt \\\n  --target dbt-third-party \\\n  --build-arg dbt_third_party=dbt-materialize \\\n  .\n```\n\n\n## Running an image in a container:\nThe `ENTRYPOINT` for this Dockerfile is the command `dbt` so you can bind-mount your project to `/usr/app` and use dbt as normal:\n```\ndocker run \\\n  --network=host \\\n  --mount type=bind,source=path/to/project,target=/usr/app \\\n  --mount type=bind,source=path/to/profiles.yml,target=/root/.dbt/profiles.yml \\\n  my-dbt \\\n  ls\n```\n---\n**Notes:**\n* Bind-mount sources _must_ be an absolute path\n* You may need to make adjustments to the docker networking setting depending on the specifics of your data warehouse/database host.\n\n---\n"
  },
  {
    "path": "docker/test.sh",
    "content": "# - VERY rudimentary test script to run latest + specific branch image builds and test them all by running `--version`\n# TODO: create a real test suite\n\nclear \\\n&& echo \"\\n\\n\"\\\n\"###################################\\n\"\\\n\"##### Testing dbt-core latest #####\\n\"\\\n\"###################################\\n\"\\\n&& docker build --tag dbt-core \\\n  --target dbt-core \\\n  docker \\\n&& docker run dbt-core --version \\\n\\\n&& echo \"\\n\\n\"\\\n\"####################################\\n\"\\\n\"##### Testing dbt-core-1.0.0b1 #####\\n\"\\\n\"####################################\\n\"\\\n&& docker build --tag dbt-core-1.0.0b1 \\\n  --target dbt-core \\\n  --build-arg dbt_core_ref=dbt-core@v1.0.0b1 \\\n  docker \\\n&& docker run dbt-core-1.0.0b1 --version \\\n\\\n&& echo \"\\n\\n\"\\\n\"#######################################\\n\"\\\n\"##### Testing dbt-postgres latest #####\\n\"\\\n\"#######################################\\n\"\\\n&& docker build --tag dbt-postgres \\\n  --target dbt-postgres \\\n  docker \\\n&& docker run dbt-postgres --version \\\n\\\n&& echo \"\\n\\n\"\\\n\"########################################\\n\"\\\n\"##### Testing dbt-postgres-1.0.0b1 #####\\n\"\\\n\"########################################\\n\"\\\n&& docker build --tag dbt-postgres-1.0.0b1 \\\n  --target dbt-postgres \\\n  --build-arg dbt_postgres_ref=dbt-core@v1.0.0b1 \\\n  docker \\\n&& docker run dbt-postgres-1.0.0b1 --version \\\n\\\n&& echo \"\\n\\n\"\\\n\"#######################################\\n\"\\\n\"##### Testing dbt-redshift latest #####\\n\"\\\n\"#######################################\\n\"\\\n&& docker build --tag dbt-redshift \\\n  --target dbt-redshift \\\n  docker \\\n&& docker run dbt-redshift --version \\\n\\\n&& echo \"\\n\\n\"\\\n\"########################################\\n\"\\\n\"##### Testing dbt-redshift-1.0.0b1 #####\\n\"\\\n\"########################################\\n\"\\\n&& docker build --tag dbt-redshift-1.0.0b1 \\\n  --target dbt-redshift \\\n  --build-arg dbt_redshift_ref=dbt-redshift@v1.0.0b1 \\\n  docker \\\n&& docker run dbt-redshift-1.0.0b1 --version \\\n\\\n&& echo \"\\n\\n\"\\\n\"#######################################\\n\"\\\n\"##### Testing dbt-bigquery latest #####\\n\"\\\n\"#######################################\\n\"\\\n&& docker build --tag dbt-bigquery \\\n  --target dbt-bigquery \\\n  docker \\\n&& docker run dbt-bigquery --version \\\n\\\n&& echo \"\\n\\n\"\\\n\"########################################\\n\"\\\n\"##### Testing dbt-bigquery-1.0.0b1 #####\\n\"\\\n\"########################################\\n\"\\\n&& docker build --tag dbt-bigquery-1.0.0b1 \\\n  --target dbt-bigquery \\\n  --build-arg dbt_bigquery_ref=dbt-bigquery@v1.0.0b1 \\\n  docker \\\n&& docker run dbt-bigquery-1.0.0b1 --version \\\n\\\n&& echo \"\\n\\n\"\\\n\"########################################\\n\"\\\n\"##### Testing dbt-snowflake latest #####\\n\"\\\n\"########################################\\n\"\\\n&& docker build --tag dbt-snowflake \\\n  --target dbt-snowflake \\\n  docker \\\n&& docker run dbt-snowflake --version \\\n\\\n&& echo \"\\n\\n\"\\\n\"#########################################\\n\"\\\n\"##### Testing dbt-snowflake-1.0.0b1 #####\\n\"\\\n\"#########################################\\n\"\\\n&& docker build --tag dbt-snowflake-1.0.0b1 \\\n  --target dbt-snowflake\\\n  --build-arg dbt_snowflake_ref=dbt-snowflake@v1.0.0b1 \\\n  docker \\\n&& docker run dbt-snowflake-1.0.0b1 --version \\\n\\\n&& echo \"\\n\\n\"\\\n\"####################################\\n\"\\\n\"##### Testing dbt-spark latest #####\\n\"\\\n\"####################################\\n\"\\\n&& docker build --tag dbt-spark \\\n  --target dbt-spark \\\n  docker \\\n&& docker run dbt-spark --version \\\n\\\n&& echo \"\\n\\n\"\\\n\"#####################################\\n\"\\\n\"##### Testing dbt-spark-1.0.0rc2 ####\\n\"\\\n\"#####################################\\n\"\\\n&& docker build --tag dbt-spark-1.0.0rc2 \\\n  --target dbt-spark \\\n  --build-arg dbt_spark_ref=dbt-spark@v1.0.0rc2 \\\n  docker \\\n&& docker run dbt-spark-1.0.0rc2 --version \\\n\\\n&& echo \"\\n\\n\"\\\n\"###########################\\n\"\\\n\"##### Testing dbt-all #####\\n\"\\\n\"###########################\\n\"\\\n&& docker build --tag dbt-all \\\n  --target dbt-all \\\n  docker \\\n&& docker run dbt-all --version \\\n\\\n&& echo \"\\n\\n\"\\\n\"##########################################\\n\"\\\n\"##### Testing third party db adapter #####\\n\"\\\n\"##########################################\\n\"\\\n&& docker build --tag dbt-materialize \\\n  --target dbt-third-party \\\n  --build-arg dbt_third_party=\"dbt-materialize\" \\\n  docker \\\n&& docker run dbt-materialize --version\n"
  },
  {
    "path": "docker-compose.yml",
    "content": "##\n#  This compose file is used for local development and adapter testing only.\n#  See `/docker` for a generic and production-ready docker file\n##\n\nversion: \"3.5\"\nservices:\n  database:\n    image: postgres\n    shm_size: 1gb\n    environment:\n      POSTGRES_USER: \"root\"\n      POSTGRES_PASSWORD: \"password\"\n      POSTGRES_DB: \"dbt\"\n    ports:\n      - \"5432:5432\"\n\n  test:\n    build:\n      context: .\n      dockerfile: Dockerfile.test\n      args:\n        # Run `make .env` to set $USER_ID and $GROUP_ID\n        USER_ID: ${USER_ID:-}\n        GROUP_ID: ${GROUP_ID:-}\n    command: \"bash -c 'cd core && hatch run ci:unit-tests'\"\n    environment:\n      POSTGRES_TEST_HOST: \"database\"\n    volumes:\n      - .:/usr/app\n    working_dir: /usr/app\n    depends_on:\n      - database\n"
  },
  {
    "path": "docs/arch/1_Overview.md",
    "content": ""
  },
  {
    "path": "docs/arch/2_CLI.md",
    "content": "# CLI Architecture\n\n## Overview\n\nThe CLI layer serves as the primary entry point for all dbt commands. It handles command-line parsing, configuration resolution, and orchestration of the execution lifecycle. The implementation is built on the [Click](https://click.palletsprojects.com/) framework, with custom extensions for dbt-specific needs like multi-source configuration and decorator-based dependency injection.\n\ndbt can be invoked in two ways: via the command line or programmatically. Command-line invocation flows through the `cli` click group defined in `main.py`. For programmatic use, the `dbtRunner` class provides a Python API that wraps click invocation and returns structured `dbtRunnerResult` objects containing success status, results, and any exceptions.\n\n### Command Structure (`main.py`)\n\nCommands are defined as click-decorated functions under the root `cli` group. Each command follows a consistent pattern: it applies global flags via `@global_flags` (e.g., `--target`, `--debug`, `--fail-fast`, etc), command-specific options from the `params` module, and `@requires` decorators that build up execution context. The command body then instantiates the appropriate `Task` class for the command and calls `task.run()`. Nested command groups like `docs` and `source` contain subcommands (e.g., `docs generate`, `source freshness`).\n\n### Parameters (`params.py`)\n\nAll CLI options are defined in `params.py` as click option decorators. Each option specifies its flags, environment variable mapping, help text, type, and default value. Custom click types in `option_types.py` handle complex inputs like YAML strings (`--vars`, `--args`) and warn-error configurations. The `MultiOption` class in `options.py` allows options like `--select` to accept multiple space-separated values.\n\n### Flags and Configuration (`flags.py`)\n\nThe `Flags` dataclass is the primary configuration handler for running dbt. It consolidates configuration from multiple sources in priority order: CLI options take precedence over environment variables, which take precedence over project flags from `dbt_project.yml`, which take precedence over defaults. The `__init__` method walks the click context hierarchy to collect all parameter values, handling deprecated env vars and mutually exclusive options along the way.\n\n### `@requires` Decorators (`requires.py`)\n\nThe `requires` module provides decorators that progressively build up the execution context stored in Click's `ctx.obj`. The `preflight` decorator handles initialization: creating `Flags`, setting up logging, and initializing tracking. Resource decorators—`profile`, `project`, `runtime_config`, `manifest`, and `catalogs`—each load their respective configuration or artifact and add it to context. The `postflight` decorator wraps command execution with exception handling and fires completion events.\n\n## Execution Flow\n\nWhen a command is invoked, execution flows through the decorator chain: `preflight` initializes flags and logging, then resource decorators (`profile` → `project` → `runtime_config` → `manifest`) progressively load configuration and add it to `ctx.obj`. The command body receives this fully-populated context, instantiates a `Task` with the flags, config, and manifest, then runs it. Finally, `postflight` handles any exceptions and emits completion events.\n\n### Exception Handling\n\nIn the `postflight` decorator, the click command is invoked (i.e. `func(*args, **kwargs)`) and wrapped in a `try/except` block to handle any exceptions thrown. Any exceptions thrown from `postflight` are wrapped by custom exceptions from the `dbt.cli.exceptions` module (i.e. `ResultExit`, `ExceptionExit`) to instruct click to complete execution with a particular exit code.\n\nSome `dbt-core` handled exceptions have an attribute named `results` which contains results from running nodes (e.g. `FailFastError`). These are wrapped in the `ResultExit` exception to represent runs that have failed in a way that `dbt-core` expects. If the invocation of the command does not throw any exceptions but does not succeed, `postflight` will still raise the `ResultExit` exception to make use of the exit code. These exceptions produce an exit code of `1`.\n\nExceptions wrapped with `ExceptionExit` may be thrown by `dbt-core` intentionally (i.e. an exception that inherits from `dbt.exceptions.Exception`) or unintentionally (i.e. exceptions thrown by the python runtime). In either case these are considered errors that `dbt-core` did not expect and are treated as genuine exceptions. These exceptions produce an exit code of `2`.\n\nIf no exceptions are thrown from invoking the command and the command succeeds, `postflight` will not raise any exceptions. When no exceptions are raised an exit code of `0` is produced.\n\n### `dbtRunner`\n\n`dbtRunner` provides a programmatic interface for our click CLI and wraps the invocation of the click commands to handle any exceptions thrown. It is a feature available for users of dbt Core, but in some instances we also use it internally for testing.\n\n`dbtRunner.invoke` should ideally only ever return an instantiated `dbtRunnerResult` which contains the following fields:\n- `success`: A boolean representing whether the command invocation was successful[\n- `result`: The optional result of the command invoked. This attribute can have many types, please see [the definition of `dbtRunnerResult` for more information](https://github.com/dbt-labs/dbt-core/blob/7634345985a86b113f51b74b9b776e346b59bdbf/core/dbt/cli/main.py#L23-L37)\n- `exception`: If an exception was thrown during command invocation it will be saved here, otherwise it will be `None`. Please note that the exceptions held in this attribute are not the exceptions thrown by `postflight` but instead the exceptions that `ResultExit` and `ExceptionExit` wrap\n\nProgrammatic exception handling might look like the following:\n```python\nfrom dbt.cli.main import dbtRunner, dbtRunnerResult\n\n# initialize\ndbt = dbtRunner()\n\n# create CLI args as a list of strings\ncli_args = [\"run\", \"--select\", \"tag:my_tag\"]\n\n# run the command\nres: dbtRunnerResult = dbt.invoke(cli_args)\n\n# inspect the results\nfor r in res.result:\n    print(f\"{r.node.name}: {r.status}\")\n```\n\nReference: https://docs.getdbt.com/reference/programmatic-invocations\n\n## Adding a New Command\n\nTo add a new command: (1) define the command function in `main.py` with appropriate decorators, (2) add an entry to the `Command` enum in `types.py`, and (3) add the command to the `CMD_DICT` in `flags.py`'s `command_args` function. Every command needs at minimum the `@cli.command()` decorator, `@requires.postflight`, and `@requires.preflight`.\n\n```python\n@cli.command(\"my-new-command\")\n@requires.postflight\n@requires.preflight\ndef my_new_command(ctx, **kwargs):\n    ...\n```\n"
  },
  {
    "path": "docs/arch/3.1_Partial_Parsing.md",
    "content": "# Partial Parsing\n\n## Overview\n\nPartial parsing improves parse performance by reusing the previous manifest and only re-parsing files that have changed. Instead of reading and processing every file on each invocation, dbt compares file checksums against the saved manifest and selectively updates only what's necessary.\n\nThe saved manifest is stored in `target/partial_parse.msgpack`. On subsequent runs, if the state check passes and files can be diffed, dbt performs an incremental update rather than a full re-parse.\n\n## State Check\n\nBefore using a saved manifest, `ManifestLoader.is_partial_parsable()` validates that the environment hasn't changed in ways that would invalidate the cached parse results:\n\n- **Version match** — The saved manifest's dbt version must match the current version\n- **Vars hash** — CLI `--vars`, profile name, and target name are hashed and compared\n- **Profile hash** — Connection credentials info is hashed (changes could affect parsing)\n- **Project env vars** — Environment variables used in `dbt_project.yml` are tracked\n- **Project hashes** — Each project's `dbt_project.yml` content is hashed\n\nIf any check fails, a full re-parse is triggered and the reason is logged.\n\n## File Diff Detection\n\nThe `PartialParsing` class compares the saved manifest's files against newly-read files:\n\n```\nprior run files  ∩  current run files  →  check checksums  →  changed / unchanged\nprior run files  -  current run files  →  deleted\ncurrent run files    -  prior run files  →  added\n```\n\nSchema files (YAML) are tracked separately because they require element-level diffing: a change to one model's config in a YAML file shouldn't require re-parsing unrelated models in the same file.\n\n### When Partial Parsing Is Bypassed\n\nPartial parsing is skipped or abandoned in these cases:\n\n- `--no-partial-parse` flag is set\n- `partial_parse.msgpack` doesn't exist or can't be loaded\n- dbt version mismatch\n- Vars, profile, or project config changed\n- An error occurs during partial parse processing (falls back to full re-parse)\n- Special override macros were changed\n\nWhen bypassed, a full re-parse occurs and a new `partial_parse.msgpack` is written for the next run.\n\n\n## Processing Changes\n\n`PartialParsing.get_parsing_files()` processes the file diff and returns a dictionary of files that need parsing:\n\n### Added Files\n- Add the file to `saved_manifest.files`\n- Schedule for parsing\n\n### Deleted Files\n- Remove associated nodes from the manifest\n- Schedule dependent nodes (children in the DAG) for re-parsing\n\n### Changed Files\n- Remove old nodes from the manifest\n- Copy the new file content to saved files\n- Schedule for parsing\n- If the node had a schema patch, re-apply it\n\n### Changed Schema Files\nFor YAML files, `change_schema_file()` performs element-level diffing:\n- Compare saved vs. new YAML dictionaries key by key (models, sources, etc.)\n- For each key, identify added/deleted/changed elements by name\n- Only re-process affected elements, preserving unaffected nodes\n\n## Special Macro Handling\n\nCertain macros have global effects that make incremental updates unsafe. Changes to these \"special override macros\" trigger a full re-parse:\n\n- `ref`\n- `source`\n- `config`\n- `generate_schema_name`\n- `generate_database_name`\n- `generate_alias_name`\n\nIf a macro file containing any of these is changed or deleted, dbt abandons partial parsing and does a full re-parse.\n\n## The `PartialParsing` Class\n\nLocated in `partial.py`, this class encapsulates the partial parsing logic:\n\n**Constructor inputs:**\n- `saved_manifest` — The previously-saved manifest\n- `current run files` — Files read from the current project\n\n**Key methods:**\n- `skip_parsing()` — Returns `True` if no files changed (nothing to do)\n- `build_file_diff()` — Compares saved vs. new files, populates `file_diff` dict\n- `get_parsing_files()` — Processes the diff and returns files to parse\n- `delete_from_saved()` / `update_in_saved()` — Handle individual file changes\n- `change_schema_file()` — Handle YAML file changes with element-level granularity\n\n**Key attributes:**\n- `file_diff` — Dict with keys: `added`, `deleted`, `changed`, `unchanged`, `changed_schema_files`, `deleted_schema_files`\n- `project_parser_files` — Output dict mapping `project → parser → [file_ids]`\n"
  },
  {
    "path": "docs/arch/3.2_Deferral.md",
    "content": "# Deferral\n\nDeferral allows dbt to resolve `ref()` calls to objects that exist in a different environment (typically production) when the referenced model isn't being built in the current run. This is essential for CI workflows where you want to build and test only modified models without rebuilding the entire DAG.\n\n## Overview\n\nWhen you run `dbt run --select my_model --defer --state prod-artifacts/`, dbt will:\n\n1. Build `my_model` in your target schema\n2. For any `ref()` to an unselected model, resolve to the production location instead of the target schema\n\nThis enables \"slim CI\" workflows where only changed models are built, while still being able to reference their unchanged upstream dependencies in production.\n\n## Key Flags\n\n| Flag | Description |\n|------|-------------|\n| `--defer` | Enable deferral. Resolve unselected refs to the state manifest. |\n| `--state PATH` | Path to directory containing production `manifest.json` |\n| `--defer-state PATH` | Override state path for deferral only (separate from `--state` used for `state:modified`) |\n| `--favor-state` | Always prefer deferred relations for unselected nodes, even if they exist locally |\n\n## How Deferral is Set Up\n\nDeferral is configured during the execution phase, specifically in `GraphRunnableTask.before_run()`:\n\n### 1. Load Previous State\n\nWhen `--state` or `--defer-state` is provided, dbt creates a `PreviousState` object that loads the production `manifest.json` from the specified path. This manifest is deserialized and version-checked to ensure compatibility with the current dbt version.\n\n### 2. Merge Defer Relations\n\nBefore execution begins, `GraphRunnableTask.before_run()` calls `defer_to_manifest()`. This method retrieves the deferred manifest (loaded from the state path) and merges it into the current manifest.\n\n### 3. Attaching Defer Relations to Nodes\n\nThe merge process iterates through every node in the production manifest. For each node that also exists in the current manifest and is a refable resource type (not ephemeral), dbt creates a `DeferRelation` object containing the production location metadata: database, schema, alias, and fully-qualified relation name. This `DeferRelation` is then attached to the corresponding node in the current manifest.\n\nAfter this merge, each eligible node carries information about where it exists in production, which can be used later during ref resolution if that node is not selected for execution.\n\n## The `DeferRelation` Object\n\n`DeferRelation` (`core/dbt/artifacts/resources/v1/components.py`) is a lightweight object that captures the production location of a node:\n\n- `database`: Production database name\n- `schema`: Production schema name\n- `alias`: Production table/view name\n- `relation_name`: Fully-qualified relation name\n- `compiled_code`: The production compiled SQL (for reference)\n- `meta`, `tags`, `config`: Metadata from production\n\n## How Refs are Resolved with Deferral\n\nSee [Node Compilation — Deferred Ref Resolution](4.4_Node_Compilation.md#deferred-ref-resolution) for how `ref()` calls use the `defer_relation` during compilation.\n\n## `--favor-state` Behavior\n\nBy default, deferral only applies when the referenced relation doesn't exist in the target environment (checked via adapter cache lookup). With `--favor-state`:\n\n- Unselected nodes **always** resolve to their `defer_relation`\n- Even if the local relation exists, production is preferred\n- Useful when you want strict isolation from local state\n\n## Use Cases\n\n### Slim CI\n\n```bash\ndbt run --select state:modified+ --defer --state prod-run-artifacts/\n```\n\nOnly build modified models and their descendants, referencing production for everything else.\n\n### Development with Production Data\n\n```bash\ndbt run --select my_new_model --defer --state prod-run-artifacts/ --favor-state\n```\n\nDevelop a new model that references production tables, without rebuilding upstream models locally.\n\n### Clone with Deferral\n\n```bash\ndbt clone --select my_model --defer --state prod-run-artifacts/\n```\n\nClone specific models from production to a development schema.\n"
  },
  {
    "path": "docs/arch/3_Parsing.md",
    "content": "# Parsing\n\n## Overview\n\nParsing reads all files in the project and constructs an internal representation called the **Manifest**. The manifest contains all project resources models, tests, seeds, snapshots, sources, macros, docs, etc, and their relationships. Parsing captures dependencies (`ref()`, `source()`) and configuration, but does not compile SQL or execute anything against the database—those happen later during execution.\n\nThe manifest is written to `target/manifest.json` for external tooling and for stateful dbt behavior such as `state:modified` selection and deferral. It is also serialized to msgpack to `target/partial_parse.msgpack` for reuse on subsequent runs in partial parsing. Note that the manifest produced by parsing is not complete: fields like `compiled_code` are populated later during compilation, and graph validation (e.g., cycle detection) happens after parsing.\n\n## Entry Point\n\nThe main entry point is `ManifestLoader.get_full_manifest()`, called from the `@requires.manifest` decorator. This method:\n\n1. Loads project dependencies\n2. Creates a `ManifestLoader` instance\n3. Calls `loader.load()` to perform the actual parsing\n4. Runs post-parse validation (`_check_manifest`—checks resource uniqueness, warns for unused configs)\n\n## Parsing Phases\n\nThe `ManifestLoader.load()` method orchestrates parsing in several phases:\n\n### 1. Read Files\nScan project directories and build `manifest.files`—a dictionary of file IDs to `SourceFile` objects containing paths, checksums, and metadata. This phase also checks for partial parsing opportunities (see [Partial Parsing](3.1_Partial_Parsing.md)).\n\n### 2. Load Macros\nMacros must be parsed first because they're needed for Jinja rendering during subsequent parsing. Additonally Generic Tests also get parsed at this time due to their similarity to macros. `MacroParser` processes `.sql` files in macro directories, and `GenericTestParser` handles generic test definitions. After loading, `build_macro_resolver()` creates the `MacroResolver` for looking up macros by name.\n\n### 3. Parse Project Files\nFor each project (root + dependencies), run the appropriate parsers based on file type:\n\n- `ModelParser` — SQL/Python models\n- `SnapshotParser` — Snapshot definitions\n- `AnalysisParser` — Analysis files\n- `SingularTestParser` — Singular test SQL files\n- `SeedParser` — CSV seed files\n- `DocumentationParser` — Markdown docs\n- `HookParser` — on-run-start/end hooks from `dbt_project.yml`\n- `FixtureParser` — Unit test fixtures\n- `FunctionParser` — Function definitions\n\n### 4. Parse Schema Files\n`SchemaParser` processes YAML files, extracting:\n- Model/seed/snapshot/analysis/function patches (descriptions, configs, columns)\n- Source definitions\n- Exposures, metrics, semantic models, saved queries\n- Generic tests attached to models/sources\n- Groups and unit tests\n\n### 5. Patch Sources\nNote: The term 'patch' refers to the schema.yml contents corresponding to a particular resource in a dbt project.\n\n`SourcePatcher.construct_sources()` converts unparsed source definitions into `SourceDefinition` nodes, applying any source patches (overrides).\n\n### 6. Process References\nResolve symbolic references captured during parsing:\n- `process_refs()` — Look up `ref()` targets and populate `depends_on.nodes`\n- `process_sources()` — Look up `source()` targets\n- `process_docs()` — Render `{{ doc() }}` blocks in descriptions\n- `process_metrics()` — Resolve metric dependencies\n\n### 7. Validation\n- Check resource uniqueness (no duplicate names/aliases)\n- Validate group and access configurations\n- Validate snapshot and microbatch configs\n\n## Key Classes\n\n### `ManifestLoader` (`manifest.py`)\n\nOrchestrates the entire parsing process. Key attributes:\n- `root_project` / `all_projects` — Project configurations\n- `manifest` — The manifest being built\n- `saved_manifest` — Previous manifest for partial parsing\n- `partial_parser` — `PartialParsing` instance if doing incremental parse\n\n### Parser Hierarchy (`base.py`)\n\n- `BaseParser` — Abstract base with `parse_file()` method and `resource_type` property\n- `Parser` — Adds `root_project` reference for cross-project parsing\n- `ConfiguredParser` — Handles config resolution, FQN generation, and relation name updates (database/schema/alias)\n- `SimpleSQLParser` — Convenience class for straightforward SQL file parsing\n\nEach parser reads `FileBlock` objects and adds parsed nodes to the manifest via `manifest.add_node()`.\n\n### `SchemaParser` (`schemas.py`)\n\nThe most complex parser: handles YAML property files with multiple sub-parsers for different top-level keys (models, sources, exposures, etc.). Produces both nodes and \"patches\" that are applied to nodes parsed from SQL files.\n\n## Parsing vs. Compilation vs. Runtime\n\nSee `docs/guides/parsing-vs-compilation-vs-runtime.md` for a detailed explanation of these distinctions.\n\n- **Parsing** — Read files, construct manifest, capture `ref()`/`source()`/`config()` calls. No database connection required.\n- **Compilation** — Render Jinja with `execute=True`, run introspective queries (requiring an adapter / warehouse connection), populate `compiled_code`. Happens at runtime, in DAG order.\n- **Runtime** — Execute materializations, run tests, apply DDL/DML to the database.\n\n## Partial Parsing\n\nTo improve performance on subsequent invocations, dbt can reuse the previous manifest and only re-parse files that have changed. This is controlled by the `--partial-parse` flag (enabled by default). See [Partial Parsing](3.1_Partial_Parsing.md)\n"
  },
  {
    "path": "docs/arch/4.1_Task_Framework.md",
    "content": "# Task Framework\n\nThe `Task` framework provides the execution layer that coordinates running dbt commands. It establishes a layered architecture where `Task`s handle command-level orchestration, `Runner`s handle per-node execution, and `Selector`s manage graph-based node selection and queuing.\n\n## Task Hierarchy\n\nTasks are organized in a class hierarchy that adds capabilities at each level. The base classes live in [`core/dbt/task/base.py`](https://github.com/dbt-labs/dbt-core/blob/main/core/dbt/task/base.py) and [`core/dbt/task/runnable.py`](https://github.com/dbt-labs/dbt-core/blob/main/core/dbt/task/runnable.py).\n\n```\nBaseTask\n ├── CleanTask\n ├── DebugTask\n ├── DepsTask\n ├── InitTask\n └── ConfiguredTask\n      ├── RetryTask\n      ├── RunOperationTask\n      ├── ServeTask\n      └── GraphRunnableTask\n           ├── CloneTask\n           ├── ListTask\n           └── CompileTask\n                ├── GenerateTask\n                ├── ShowTask\n                └── RunTask\n                     ├── BuildTask\n                     ├── FreshnessTask\n                     ├── SeedTask\n                     ├── SnapshotTask\n                     └── TestTask\n```\n\n### BaseTask\n\nThe abstract base class for all tasks. It holds `args: Flags` and defines the `run()` abstract method that each task must implement. Simple commands like `dbt clean`, `dbt debug`, `dbt deps`, and `dbt init` inherit directly from `BaseTask` since they don't require project configuration or manifest access.\n\n### ConfiguredTask\n\nExtends `BaseTask` with project awareness. Adds `config: RuntimeConfig`, `manifest: Manifest`, and a `Compiler` instance. The `compile_manifest()` method invokes graph compilation (see [Graph Compilation](4.2_Graph_Compilation.md)), producing a `Graph` object. Commands that need project context but don't execute nodes against the graph (like `dbt run-operation`) inherit from this level.\n\n### GraphRunnableTask\n\nThe main workhorse for DAG-based execution. Manages the full execution lifecycle: node selection, thread pool management, and result collection. Key methods include:\n\n- `_runtime_initialize()`: Compiles the manifest and builds the `GraphQueue` via `get_graph_queue()`\n- `get_node_selector()`: Returns a `NodeSelector` (or subclass) for resolving `--select`/`--exclude` arguments\n- `execute_nodes()`: Creates a thread pool and drives `run_queue()`\n- `run_queue()`: Pulls nodes from the queue and dispatches them to `call_runner()`\n- `call_runner()`: Invokes the Runner for a single node, handles results and error propagation\n\nThe `run()` method orchestrates the full flow: `_runtime_initialize()` → `execute_with_hooks()` → result writing.\n\n### CompileTask\n\nSpecializes `GraphRunnableTask` for compilation-focused commands. Sets `raise_on_first_error()` to `True` and uses `CompileRunner` for all nodes. The `get_node_selector()` returns a `ResourceTypeSelector` filtering to executable node types.\n\n`CompileTask` also supports inline SQL compilation via the `--inline` flag (e.g., `dbt compile --inline \"select * from {{ ref('my_model') }}\"`). This allows users to compile arbitrary SQL strings that use dbt Jinja functions like `ref()` and `source()` without needing a corresponding model file. The inline SQL is parsed into a temporary `SqlOperation` node, added to the manifest, compiled, and then removed after execution.\n\n### RunTask and BuildTask\n\n`RunTask` extends `CompileTask` for model execution, adding hook execution (`on-run-start`, `on-run-end`), schema creation, and model-specific result tracking. It uses `ModelRunner` for models and handles microbatch incremental models specially.\n\n`BuildTask` extends `RunTask` to process multiple resource types in a single invocation. It maintains a `RUNNER_MAP` dispatching each `NodeType` to the appropriate Runner, and overrides `compile_manifest()` to add test edges to the graph (see [Graph Compilation](4.2_Graph_Compilation.md)).\n\n## Runner Hierarchy\n\nRunners handle per-node execution. The base class lives in `core/dbt/task/base.py`, with specialized runners in their respective task modules.\n\n```\nBaseRunner\n ├── CloneRunner\n ├── FreshnessRunner\n ├── SavedQueryRunner\n └── CompileRunner\n      ├── ShowRunner\n      ├── TestRunner\n      ├── GenericSqlRunner\n      │    ├── SqlCompileRunner\n      │    └── SqlExecuteRunner\n      └── ModelRunner\n           ├── SeedRunner\n           └── SnapshotRunner\n```\n\n### BaseRunner\n\nAbstract base for per-node execution. Holds references to `config`, `adapter`, `node`, and a `Compiler` instance. Key methods:\n\n- `run_with_hooks()`: Entry point called by the Task. Invokes `before_execute()`, `safe_run()`, `after_execute()`\n- `safe_run()`: Wraps `compile_and_execute()` with error handling and connection management\n- `compile_and_execute()`: The core two-phase execution—compiles the node, then executes it (for non-ephemeral nodes)\n- `compile()`: Abstract method implemented by subclasses to compile the node\n- `execute()`: Abstract method implemented by subclasses to execute the compiled node\n\n### CompileRunner\n\nBasic compilation runner. The `compile()` method calls `compiler.compile_node()` (see [Node Compilation](4.4_Node_Compilation.md)). The `execute()` method simply returns a success result without running SQL and is used for `dbt compile`.\n\n### ModelRunner\n\nExecutes models by invoking materialization macros. The `execute()` method generates a runtime context, looks up the appropriate materialization macro, and invokes it via `MacroGenerator`. The materialization macro handles all adapter interactions (see [Node Materialization](4.5_Node_Materialization.md)).\n\n### TestRunner\n\nExecutes tests (data tests and unit tests). For data tests, it runs the test SQL and interprets row counts as pass/fail. For unit tests, it sets up fixtures, runs the model, and compares actual vs expected results.\n\n## Node Selection\n\nNode selection determines which nodes from the manifest will be executed. The selector framework lives in `core/dbt/graph/`.\n\n### NodeSelector\n\nThe main class for resolving selection specs against the compiled graph. Given a `SelectionSpec` (parsed from `--select`/`--exclude` arguments), it traverses the graph to find matching nodes, applies graph operators (`+`, `@`), and handles indirect selection for tests. The `get_selected()` method returns the final set of unique IDs. See [Node Selection](4.3_Node_Selection.md) for details on selection syntax and methods.\n\n### ResourceTypeSelector\n\nExtends `NodeSelector` to filter by `NodeType`. Used by most commands to restrict selection to relevant resource types (e.g., `RunTask` selects only models, `TestTask` selects only tests).\n\n### GraphQueue\n\nA thread-safe priority queue backed by the dependency graph. Nodes are scored by topological depth (lower depth = higher priority). The queue tracks in-progress nodes and releases downstream nodes only when their dependencies complete via `mark_done()`. This ensures correct execution order while maximizing parallelism.\n\n## Execution Flow\n\nThe typical execution flow for a graph-based command:\n\n1. **Task.run()**: Entry point, sets up context\n2. **_runtime_initialize()**: Calls `compile_manifest()` to build the `Graph`, then `get_graph_queue()` for node selection\n3. **execute_with_hooks()**: Gets adapter, calls `before_run()`, `execute_nodes()`, `after_run()`\n4. **execute_nodes()**: Creates `DbtThreadPool`, calls `run_queue()`\n5. **run_queue()**: Loop pulling nodes from `GraphQueue`, dispatching to thread pool via `call_runner()`\n6. **call_runner()**: Creates Runner via `get_runner()`, invokes `runner.run_with_hooks()`\n7. **Runner.run_with_hooks()** → **safe_run()** → **compile_and_execute()**: Compiles node, executes it, returns `RunResult`\n8. **_handle_result()**: Records result, marks dependent nodes as skipped if needed\n9. **GraphQueue.mark_done()**: Releases downstream nodes\n\nResults are collected in `node_results` and written to `run_results.json` at the end of execution.\n"
  },
  {
    "path": "docs/arch/4.2_Graph_Compilation.md",
    "content": "# Graph Compilation\n\n## Overview\n\nGraph compilation transforms the parsed Manifest into an executable dependency graph. This happens in `Compiler.compile()` ([`core/dbt/compilation.py`](https://github.com/dbt-labs/dbt-core/blob/main/core/dbt/compilation.py)) and produces a `Graph` object wrapping a NetworkX DiGraph.\n\n## Key Classes\n\n### Compiler\n\n- `compile()`: Main entry point. Creates a `Linker`, calls `link_graph()`, optionally adds test edges, writes `graph.gpickle`\n- `compile_node()`: Per-node compilation (covered in [Node Compilation](4.4_Node_Compilation.md))\n\n### Linker\n\nWrapper around `nx.DiGraph` that builds the dependency graph:\n\n- `link_graph()`: Iterates all manifest nodes, calls `link_node()` for each\n- `link_node()`: Adds edges based on `node.depends_on_nodes`\n- `find_cycles()`: Detects cycles in the graph, raises error if found\n- `add_test_edges()`: For `dbt build`, adds edges from tests to downstream nodes\n\n## Graph Structure\n\n- Nodes: unique_ids of all manifest resources (models, tests, seeds, sources, etc.)\n- Edges: dependency relationships from `depends_on_nodes`\n- Direction: edges point from dependency to dependent (A → B means B depends on A)\n\n## Test Edge Addition\n\nFor `dbt build`, tests should block downstream models from executing. The `add_test_edges()` method adds edges from upstream tests to downstream non-test nodes, ensuring tests run before models that depend on the tested resources.\n\nTwo implementations exist:\n- `add_test_edges_1()`: Original algorithm, comprehensive but adds many redundant edges\n- `add_test_edges_2()`: Optimized algorithm (behind `USE_FAST_TEST_EDGES` flag), adds minimal edges\n\n## Cycle Detection\n\nAfter linking, `find_cycles()` uses NetworkX to detect cycles. If found, raises a `RuntimeError` with the cycle path. This catches circular `ref()` dependencies that would cause infinite loops.\n"
  },
  {
    "path": "docs/arch/4.3_Node_Selection.md",
    "content": "# Node Selection\n\n## Overview\n\nNode selection determines which nodes from the manifest will be executed based on `--select` and `--exclude` arguments. The selection framework lives in `core/dbt/graph/`.\n\n## Selection Syntax\n\n### Basic Selectors\n\n- `model_name`: Select by name\n- `tag:value`: Select by tag\n- `path:models/staging`: Select by file path\n- `package:my_package`: Select by package\n- `config.materialized:view`: Select by config value\n- `state:modified`: Select modified nodes (requires `--state`, see below)\n\n### Graph Operators\n\n- `+model`: Select model and all ancestors\n- `model+`: Select model and all descendants  \n- `+model+`: Select model, ancestors, and descendants\n- `@model`: Select model, ancestors, descendants, and tests of ancestors\n\n### Set Operations\n\n- `model_a model_b`: Union (space-separated)\n- `model_a,model_b`: Union (comma-separated)\n- `--exclude model_c`: Exclusion\n\n## Key Classes\n\n### SelectionSpec / SelectionCriteria\n\nParsed representation of selection arguments. `parse_difference()` in [`core/dbt/graph/cli.py`](https://github.com/dbt-labs/dbt-core/blob/main/core/dbt/graph/cli.py) parses CLI arguments into a `SelectionSpec`.\n\n### SelectorMethod\n\nBase class for selector implementations. Each selector type (tag, path, config, etc.) has a corresponding method class in [`core/dbt/graph/selector_methods.py`](https://github.com/dbt-labs/dbt-core/blob/main/core/dbt/graph/selector_methods.py).\n\n### NodeSelector\n\nMain class for resolving selection specs against the graph:\n\n- `select_nodes()`: Recursively resolves selection spec, applies set operations\n- `get_nodes_from_criteria()`: Resolves a single criterion, applies graph operators\n- `expand_selection()`: Handles indirect test selection\n- `filter_selection()`: Final filtering (e.g., by resource type)\n\n### ResourceTypeSelector\n\nExtends `NodeSelector` to filter by `NodeType`. The `node_is_match()` method checks if a node's resource type is in the allowed set.\n\n## State-Based Selection\n\nThe `state:modified` selector is designed for CI/CD workflows where you want to run only the resources that have changed between two project states, allowing you to detect potential regressions without running the entire project. This requires the `--state` flag pointing to a directory containing a previous manifest (typically from production).\n\n### How Modification Detection Works\n\nThe `StateSelectorMethod` in [`core/dbt/graph/selector_methods.py`](https://github.com/dbt-labs/dbt-core/blob/main/core/dbt/graph/selector_methods.py) compares each node in the current manifest against its counterpart in the previous state's manifest. Each resource type implements a `same_contents()` method that encodes the semantic comparison logic for that resource type. This method returns `True` if the node is considered unchanged, and `False` if it should be marked as modified.\n\nThe `same_contents()` comparison typically checks:\n- `raw_code` / `raw_sql`: The source SQL or Python code\n- `config`: Materialization, schema, tags, and other configuration\n- `depends_on`: References to other nodes (`ref()`, `source()`)\n- Resource-specific fields: e.g., `columns` for sources, `test_metadata` for tests\n\n### State Selector Variants\n\n- `state:modified`: Nodes where `same_contents()` returns `False`\n- `state:new`: Nodes that exist in current manifest but not in previous state\n- `state:modified.body`: Only code changes (ignores config changes)\n- `state:modified.configs`: Only config changes\n\n## Indirect Selection\n\nTests can be selected indirectly when their parent models are selected. Modes:\n\n- **eager** (default): Select test if ANY parent is selected\n- **cautious**: Select test only if ALL parents are selected\n- **buildable**: Select test if all parents are selected or are ancestors of selected nodes\n- **empty**: Don't expand to tests\n\nThese modes are set by the user via the `--indirect-selection` flag (e.g. `--indirect-selection=cautious`).\n\n## GraphQueue Construction\n\n`NodeSelector.get_graph_queue()` creates the execution queue:\n\n1. `get_selected()`: Get final set of selected node IDs\n2. `full_graph.get_subset_graph()`: Create subgraph with only selected nodes\n3. `GraphQueue(subgraph, ...)`: Wrap in thread-safe queue with topological ordering\n"
  },
  {
    "path": "docs/arch/4.4_Node_Compilation.md",
    "content": "# Node Compilation\n\n## Overview\n\nNode compilation renders Jinja templates into executable SQL. This happens in `Compiler.compile_node()` ([`core/dbt/compilation.py`](https://github.com/dbt-labs/dbt-core/blob/main/core/dbt/compilation.py)) and is invoked by Runners during execution.\n\n### Example: Before and After Compilation\n\n**Before (raw SQL with Jinja)** — `models/marts/orders_with_payments.sql`:\n\n```sql\n{{\n  config(\n    materialized='table',\n    schema='marts'\n  )\n}}\n\nwith orders as (\n    select * from {{ ref('stg_orders') }}\n),\n\npayments as (\n    select * from {{ source('stripe', 'payments') }}\n)\n\nselect\n    orders.order_id,\n    orders.customer_id,\n    orders.order_date,\n    payments.amount\nfrom orders\nleft join payments on orders.payment_id = payments.id\n```\n\n**After (compiled SQL)** — `target/compiled/my_project/models/marts/orders_with_payments.sql`:\n\n```sql\nwith orders as (\n    select * from \"database\".\"staging\".\"stg_orders\"\n),\n\npayments as (\n    select * from \"database\".\"stripe\".\"payments\"\n)\n\nselect\n    orders.order_id,\n    orders.customer_id,\n    orders.order_date,\n    payments.amount\nfrom orders\nleft join payments on orders.payment_id = payments.id\n```\n\nThe `config()` block is processed during parsing (setting node properties like `materialized='table'`) and stripped from the compiled output. The `ref()` and `source()` calls are resolved to fully-qualified database relations based on the target environment's configuration.\n\n## Key Methods\n\n### Compiler.compile_node()\n\nMain entry point for per-node compilation:\n\n1. Calls `_compile_code()` to render Jinja → `compiled_code`\n2. Calls `_recursively_prepend_ctes()` for ephemeral model CTE injection\n3. Writes compiled SQL to `target/compiled/` directory\n\n### _compile_code()\n\nRenders the node's `raw_code` using Jinja:\n\n1. Creates node context via `_create_node_context()`\n2. Calls `jinja.render()` with the context\n3. Sets `node.compiled_code` and `node.compiled = True`\n\n### _create_node_context()\n\nBuilds the Jinja rendering context:\n\n- For regular nodes: `generate_runtime_model_context()`\n- For unit tests: `generate_runtime_unit_test_context()`\n- Adds test kwargs for generic tests\n\n## Ephemeral Model Handling\n\nEphemeral models don't create database objects—they're injected as CTEs into referencing models.\n\n### _recursively_prepend_ctes()\n\nWhen a model references an ephemeral model via `ref()`:\n\n1. The ephemeral model is added to `node.extra_ctes` during parsing\n2. During compilation, `_recursively_prepend_ctes()` compiles each ephemeral dependency\n3. Recursively processes nested ephemeral references\n4. Injects compiled SQL as CTEs at the beginning of the referencing model's SQL\n\n### CTE Injection\n\nThe `_inject_ctes_into_sql()` method prepends CTEs to the model's SQL:\n\n```sql\nWITH __dbt__cte__ephemeral_model AS (\n  -- compiled SQL from ephemeral model\n),\n-- any additional CTEs from the model itself\nSELECT * FROM __dbt__cte__ephemeral_model\n```\n\n## Deferred Ref Resolution\n\nWhen deferral is enabled (`--defer`), `ref()` calls may resolve to production relations instead of the target schema. This happens in `RuntimeRefResolver.create_relation()` ([`core/dbt/context/providers.py`](https://github.com/dbt-labs/dbt-core/blob/main/core/dbt/context/providers.py)).\n\nThe resolution logic checks three conditions:\n\n1. **Node has a `defer_relation`**: Set during `merge_from_artifact()` (see [Deferral](3.2_Deferral.md))\n2. **`--defer` flag is enabled**\n3. **One of**:\n   - `--favor-state` is set AND the node is not in the current selection\n   - OR the relation doesn't exist in the target environment (adapter cache lookup)\n\n```python\nif (\n    target_model.defer_relation\n    and self.config.args.defer\n    and (\n        (self.config.args.favor_state and target_model.unique_id not in SELECTED_RESOURCES)\n        or not get_adapter(self.config).get_relation(database, schema, identifier)\n    )\n):\n    # Use defer_relation (production) instead of target_model (local)\n    return self.Relation.create_from(self.config, target_model.defer_relation, ...)\n```\n\n### Example\n\nWith `--defer --state prod-artifacts/`:\n\n```sql\n-- Source: models/marts/report.sql\nselect * from {{ ref('dim_customers') }}\n\n-- If dim_customers is NOT selected and exists in prod:\n-- Compiles to: select * from \"prod_db\".\"prod_schema\".\"dim_customers\"\n\n-- If dim_customers IS selected (being built in this run):\n-- Compiles to: select * from \"dev_db\".\"dev_schema\".\"dim_customers\"\n```\n\n## Compilation vs Parsing\n\nKey distinction (see [Parsing vs Compilation vs Runtime](../guides/parsing-vs-compilation-vs-runtime.md)):\n\n- **Parsing**: Extract structure, resolve refs, no Jinja rendering\n- **Compilation**: Render Jinja, produce `compiled_code`, inject CTEs\n- **Runtime**: Execute against database\n\nCompilation requires adapter connection for `run_query()` in Jinja. It happens during Task execution, not during manifest loading.\n"
  },
  {
    "path": "docs/arch/4.5_Node_Materialization.md",
    "content": "# Node Materialization\n\n## Overview\n\nNode materialization is the final execution step where compiled SQL is run against the data warehouse. For models, this involves invoking materialization macros that handle the specifics of creating tables, views, or incremental updates.\n\n### Example: Table Materialization (Atomic Swap Pattern)\n\nWhen a model is configured with `materialized='table'`, the materialization macro generates SQL that follows an atomic swap pattern to avoid downtime:\n\n```sql\n-- 1. Create a temporary table with the model's SQL\nCREATE TABLE \"database\".\"schema\".\"my_model__dbt_tmp\" AS (\n  SELECT * FROM ...  -- compiled model SQL\n);\n\n-- 2. Drop the existing table (if it exists)\nDROP TABLE IF EXISTS \"database\".\"schema\".\"my_model\";\n\n-- 3. Rename the temp table to the final name\nALTER TABLE \"database\".\"schema\".\"my_model__dbt_tmp\" \nRENAME TO \"my_model\";\n```\n\nThis pattern ensures that the model is never in a partially-built state—readers see either the old version or the new version, never an incomplete table. Note that this is a general pattern and assumes DWH support for an atomic `RENAME` operation. Different strategies are implemented for different warehouses based on the capabilities they support with the goals of the materialization in mind.\n\n## ModelRunner.execute()\n\nThe main execution method for models (`core/dbt/task/run.py`):\n\n1. Generates runtime context via `generate_runtime_model_context()`\n2. Looks up materialization macro via `manifest.find_materialization_macro_by_name()`\n3. Invokes the macro via `MacroGenerator`\n4. Caches created relations via `adapter.cache_added()`\n5. Returns `RunResult`\n\n## Materialization Macro Lookup\n\nWhen looking up a materialization macro, dbt searches in a specific order (`core/dbt/contracts/graph/manifest.py`):\n\n1. **Adapter-specific, project-local**: `materialization_table_snowflake` in your project\n2. **Adapter-specific, imported package**: `materialization_table_snowflake` from a dependency\n3. **Adapter-specific, adapter package**: Built into `dbt-snowflake`\n4. **Default, project-local**: `materialization_table_default` in your project\n5. **Default, core**: `materialization_table_default` from `dbt-core`\n\nThe adapter type hierarchy is also considered. For example, Snowflake inherits from the base SQL adapter, so if no Snowflake-specific materialization exists, the default SQL one is used.\n\n## Materialization Macros\n\nMaterializations are Jinja macros that define how to create database objects. Built-in materializations live in [`core/dbt/include/global_project/macros/materializations/`](https://github.com/dbt-labs/dbt-adapters/tree/main/dbt-adapters/src/dbt/include/global_project) in the `dbt-adapters` repository.\n\n### Common Materializations\n\n- **view**: `CREATE VIEW AS SELECT ...`\n- **table**: `CREATE TABLE AS SELECT ...` (with atomic swap)\n- **incremental**: Merge/insert new rows into existing table\n- **ephemeral**: No database object (CTE injection only, handled in compilation)\n\n### Materialization Interface\n\nMacros receive a context including:\n- `model`: The node being materialized\n- `config`: Node configuration (via `config.get()`, `config.require()`)\n- `adapter`: Adapter methods for database operations\n- `statement()`: Execute SQL and capture results\n- `run_query()`: Execute SQL and return results\n\nMust return `{'relations': [relation]}` for cache management.\n\n## The `statement()` Block\n\nThe `statement()` block is the core primitive that materializations use to execute SQL. It:\n\n1. Executes the provided SQL against the database via the adapter\n2. Captures the result (rows affected, timing, etc.)\n3. Stores the result in `sql_results` for later retrieval via `load_result()`\n\nExample usage in a materialization:\n\n```jinja\n{% call statement('main') %}\n  {{ sql }}\n{% endcall %}\n\n{# Later, retrieve the result #}\n{% set result = load_result('main') %}\n```\n\nThe `'main'` statement is special: it's used by `ModelRunner` to extract the adapter response for the `RunResult`.\n\n## Adapter Interactions\n\nMaterializations use adapter methods within their jinja definitions for database operations:\n\n- `adapter.execute()`: Run SQL and return response\n- `adapter.create_schema()`: Create schema if needed\n- `adapter.drop_relation()`: Drop existing object\n- `adapter.rename_relation()`: Atomic swap for table replacement\n- `adapter.Relation.create()`: Create relation references\n- `adapter.get_columns_in_relation()`: Introspect table schema\n\n## Python Models\n\nPython models follow a different execution path than SQL models. Instead of rendering Jinja and executing SQL:\n\n1. The Python code is not Jinja-rendered (no `ref()` in Python syntax)\n2. A postfix is appended that calls the `model()` function\n3. The materialization macro calls `submit_python_job()` in the context\n4. `submit_python_job()` delegates to `adapter.submit_python_job()`\n5. The adapter submits the Python code to the warehouse's execution environment (e.g., Snowpark, Databricks notebooks)\n\nPython models are supported only on adapters that implement `submit_python_job()`.\n\n## Seeds and Snapshots\n\n### Seeds\n\nSeeds (`SeedRunner`) load CSV files into database tables:\n\n1. `compile()` is a no-op (returns the node unchanged)\n2. `execute()` invokes the seed materialization macro\n3. The macro uses `adapter.load_dataframe()` to bulk-insert CSV data\n4. Results include the agate table for optional display (`--show`)\n\n### Snapshots\n\nSnapshots (`SnapshotRunner`) implement SCD Type 2 (slowly changing dimensions):\n\n1. Uses the `snapshot` materialization macro\n2. Tracks record changes with `dbt_valid_from` and `dbt_valid_to` columns\n3. Supports `strategy='timestamp'` (track by updated_at column) or `strategy='check'` (track by column hash)\n4. On each run, invalidates changed records and inserts new versions\n\n## Test Execution\n\nTests are \"materialized\" by running their SQL and interpreting results:\n\n### Data Tests (Generic and Singular)\n\n1. `TestRunner.execute_data_test()` invokes the `test` materialization\n2. The materialization runs the test SQL\n3. Results are a single row with columns: `failures`, `should_warn`, `should_error`\n4. Row count interpretation: 0 failures = pass, >0 = fail (or warn based on config)\n\n### Unit Tests\n\n1. `TestRunner.execute_unit_test()` builds a special unit test manifest\n2. Compiles and runs the `unit` materialization\n3. Compares `actual` vs `expected` result sets\n4. Reports diff if mismatch occurs\n\n## Incremental Strategies\n\nIncremental models support multiple strategies:\n\n- **append**: Insert all new rows\n- **delete+insert**: Delete matching rows, then insert new\n- **merge**: Upsert based on unique key (requires adapter support)\n- **microbatch**: Process in time-based batches (see `MicrobatchModelRunner`)\n\nStrategy selection based on `config.incremental_strategy` and adapter capabilities.\n\n## Hook Execution\n\nRunTask executes project hooks around model execution:\n\n- `on-run-start`: Before any models run\n- `on-run-end`: After all models complete\n- Pre/post hooks on individual models via `config.pre_hook` / `config.post_hook`\n\n## Relation Cache Management\n\ndbt maintains an in-memory cache of database relations to avoid repeated introspection queries. Materializations must keep this cache in sync:\n\n- `adapter.cache_added(relation)`: Register a newly created relation\n- `adapter.cache_dropped(relation)`: Remove a dropped relation\n- `adapter.cache_renamed(from_relation, to_relation)`: Update after rename\n\nThe `_materialization_relations()` return value (`{'relations': [...]}`) is used by `ModelRunner` to automatically call `cache_added()` for each relation.\n\n## Result Handling\n\n`RunResult` captures execution outcome:\n- `status`: Success, Error, Skipped, etc.\n- `timing`: Compile and execute timing info\n- `adapter_response`: Database-specific response (rows affected, etc.)\n- `message`: Human-readable status message\n"
  },
  {
    "path": "docs/arch/4_Execution.md",
    "content": "# Execution\n\nAfter parsing produces the Manifest, dbt enters the execution phase where selected nodes are compiled and run against the data warehouse. This phase is orchestrated by the `Task` framework, which provides a layered abstraction for command execution, node selection, and per-node processing.\n\nThe execution flow begins when a command's Task (e.g., `RunTask`, `BuildTask`) calls `run()`. For graph-based commands, this triggers manifest compilation into a dependency graph—including cycle detection to catch circular `ref()` dependencies—followed by node selection based on CLI arguments (`--select`, `--exclude`), and construction of a `GraphQueue` that respects topological ordering. The Task then spawns a thread pool and processes nodes concurrently, with the queue releasing downstream nodes only after their dependencies complete.\n\nEach node is processed by a dedicated `Runner` instance, which handles the compile-then-execute lifecycle. During compilation, Jinja templates are rendered to produce `compiled_code`, with ephemeral model references resolved into CTEs. During execution, the `Runner` interacts with the adapter to run the compiled SQL or invoke materialization macros. Results are collected and used to determine whether dependent nodes should proceed or be skipped due to upstream failures.\n\nThe framework supports different execution modes: topological (default, respects dependencies) and independent (parallel execution ignoring edges, used by `dbt list`). Special handling exists for `dbt build`, which adds test edges to the graph so that tests on upstream models block downstream model execution, and coordinates unit tests to run before their associated models.\n\n## Subsections\n\n- [Task Framework](4.1_Task_Framework.md) - Task and Runner class hierarchies, execution orchestration\n- [Graph Compilation](4.2_Graph_Compilation.md) - Building the dependency graph from the manifest\n- [Node Selection](4.3_Node_Selection.md) - Selection syntax and the selector framework\n- [Node Compilation](4.4_Node_Compilation.md) - Jinja rendering and CTE injection\n- [Node Materialization](4.5_Node_Materialization.md) - Materialization macros and adapter interactions\n"
  },
  {
    "path": "docs/arch/5_Adapter.md",
    "content": "# Adapter Framework\n\nThe adapter framework provides the abstraction layer between dbt-core and data warehouses. Each adapter (e.g., `dbt-snowflake`, `dbt-postgres`, `dbt-bigquery`) implements a common interface for database operations, allowing dbt-core to remain warehouse-agnostic while adapters handle the specifics of SQL dialect, connection management, and platform capabilities.\n\n## Architecture Overview\n\nThe adapter framework consists of several key components:\n\n- **Credentials**: Warehouse connection parameters parsed from `profiles.yml`\n- **Adapter Plugin**: The adapter implementation loaded dynamically based on credential type\n- **Connection Manager**: Thread-safe connection pooling and lifecycle management\n- **Relation**: Database object abstraction (database, schema, identifier)\n- **Macro Resolver**: Resolution of adapter-specific macro implementations via `adapter.dispatch()`\n\nThe base adapter classes live in the `dbt-adapters` package, with warehouse-specific implementations in their respective packages (e.g., `dbt-snowflake`).\n\n## Initialization Flow\n\nAdapter initialization happens during the CLI decorator chain in `core/dbt/cli/requires.py`:\n\n### 1. Profile Loading (`@profile` decorator)\n\n```\nprofiles.yml → load_profile() → Profile object with Credentials\n```\n\nThe `load_profile()` function:\n1. Reads `profiles.yml` from the profiles directory\n2. Extracts the target configuration (e.g., `dev`, `prod`)\n3. Parses the `type` field to determine which adapter to use\n4. Calls `load_plugin(adapter_type)` to dynamically load the adapter package\n5. Instantiates the adapter's `Credentials` class with connection parameters\n6. Returns a `Profile` object containing the credentials\n\n### 2. Runtime Config Creation (`@runtime_config` decorator)\n\n```\nProfile + Project → RuntimeConfig\n```\n\nThe `RuntimeConfig` combines:\n- Profile (credentials, target, threads)\n- Project (dbt_project.yml settings)\n- CLI flags\n\nThis config object is passed to the adapter and provides all context needed for database operations.\n\n### 3. Adapter Registration (`@manifest` decorator)\n\n```\nRuntimeConfig → register_adapter() → get_adapter()\n```\n\nDuring manifest loading in `parse_manifest()`:\n\n1. `register_adapter(runtime_config, mp_context)` registers the adapter in a global factory\n2. `get_adapter(runtime_config)` retrieves the singleton adapter instance\n3. `adapter.set_macro_context_generator()` configures how macro contexts are created\n4. `adapter.set_macro_resolver(manifest)` provides the manifest for macro resolution\n5. `adapter.connections.set_query_header()` sets up query comment headers\n\nThe adapter is now fully initialized and ready for use.\n\n## Adapter Configuration with Manifest\n\nAfter parsing completes, the adapter receives the manifest to enable macro resolution:\n\n```python\nadapter = get_adapter(runtime_config)\nadapter.set_macro_resolver(manifest)\nadapter.set_macro_context_generator(generate_runtime_macro_context)\n```\n\nThis connection is critical because:\n- Materializations and other macros use `adapter.dispatch()` to find implementations\n- The adapter needs to resolve macro calls like `adapter.dispatch('create_table_as')`\n- Query headers include project metadata from the manifest\n\n## Connection Management\n\nThe adapter manages database connections through its `ConnectionManager`:\n\n### Connection Lifecycle\n\n```python\n# Named connection context\nwith adapter.connection_named(\"master\"):\n    adapter.execute(sql)\n    # Connection automatically released on exit\n```\n\n### Thread-Safe Pooling\n\n- Each thread gets its own connection via `get_thread_connection()`\n- Connections are named (e.g., node unique_id) for debugging and cancellation\n- `cleanup_connections()` releases all connections at task end\n\n### Connection Naming by Node\n\nDuring execution, each node runs with a connection named after its unique_id:\n\n```python\nwith self.adapter.connection_named(self.node.unique_id, self.node):\n    # compile and execute the node\n```\n\nThis enables:\n- Query cancellation by node name on `KeyboardInterrupt`\n- Connection tracking and debugging\n- Proper isolation between concurrent node executions\n\n## Critical Usage Points During Execution\n\n### Before Execution (`RunTask.before_run()`)\n\n```python\nwith adapter.connection_named(\"master\"):\n    self.create_schemas(adapter, required_schemas)\n    self.populate_adapter_cache(adapter)\n    self.safe_run_hooks(adapter, RunHookType.Start, {})\n```\n\n- Creates any missing schemas\n- Populates the relation cache for fast lookups\n- Runs `on-run-start` hooks\n\n### During Node Execution\n\nRunners interact with the adapter through the Jinja context:\n\n```python\ncontext = generate_runtime_model_context(model, self.config, manifest)\n# context['adapter'] is a DatabaseWrapper around the real adapter\n```\n\nKey adapter methods used in materializations:\n- `adapter.execute(sql)`: Run SQL, return response\n- `adapter.get_columns_in_relation(relation)`: Introspect schema\n- `adapter.create_schema(relation)`: Create schema if not exists\n- `adapter.drop_relation(relation)`: Drop table/view\n- `adapter.rename_relation(from, to)`: Atomic rename\n- `adapter.dispatch(macro_name)`: Find adapter-specific macro\n\n### Relation Cache\n\nThe adapter maintains an in-memory cache of database relations:\n\n```python\nadapter.cache_added(relation)      # Register new relation\nadapter.cache_dropped(relation)    # Remove dropped relation\nadapter.cache_renamed(from, to)    # Update after rename\n```\n\nCache population happens in `populate_adapter_cache()` before execution, querying `information_schema` or equivalent to discover existing objects.\n\n### Query Cancellation\n\nOn `KeyboardInterrupt`, the task cancels in-flight queries:\n\n```python\nadapter = get_adapter(self.config)\nif adapter.is_cancelable():\n    with adapter.connection_named(\"master\"):\n        for conn_name in adapter.cancel_open_connections():\n            # Log cancelled connections\n```\n\n### After Execution (`RunTask.after_run()`)\n\n```python\nself.safe_run_hooks(adapter, RunHookType.End, extra_context)\nadapter.cleanup_connections()\n```\n\n- Runs `on-run-end` hooks\n- Cleans up all open connections\n\n## The `adapter.dispatch()` Mechanism\n\n`adapter.dispatch()` enables polymorphic macro invocation—the same macro call resolves to different implementations based on the active adapter.\n\nResolution order:\n1. Current adapter type (e.g., `snowflake__create_table_as`)\n2. Parent adapter types in inheritance chain\n3. Default implementation (`default__create_table_as`)\n\nThis allows adapters to override specific behaviors while falling back to common implementations.\n\n## Key Adapter Methods\n\n| Method | Purpose |\n|--------|---------|\n| `execute(sql, auto_begin, fetch)` | Execute SQL statement |\n| `get_columns_in_relation(relation)` | Get column metadata |\n| `create_schema(relation)` | Create schema |\n| `drop_relation(relation)` | Drop relation |\n| `rename_relation(from, to)` | Rename relation |\n| `list_schemas(database)` | List schemas in database |\n| `list_relations_without_caching(schema)` | Query relations directly |\n| `expand_column_types(...)` | Handle type expansion for incremental |\n| `submit_python_job(model, code)` | Execute Python model (if supported) |\n"
  },
  {
    "path": "docs/arch/6.10_dbt_compile.md",
    "content": "# dbt compile\n\n## Overview\n\n`dbt compile` generates executable SQL from Jinja templates without executing anything against the database. Compiled SQL files are written to the `target/compiled/` directory.\n\n**Reference**: https://docs.getdbt.com/reference/commands/compile\n\n## Task Class: `CompileTask`\n\n`CompileTask` extends `GraphRunnableTask` and is the base class for many execution commands (`RunTask`, `TestTask`, `ShowTask`, etc.).\n\n### CompileRunner\n\n`CompileRunner` extends `BaseRunner` and handles the compilation step without execution:\n\n```python\nclass CompileRunner(BaseRunner):\n    def compile(self, manifest):\n        return self.compiler.compile_node(self.node, manifest, {})\n    \n    def execute(self, compiled_node, manifest):\n        # For pure compilation, just return success\n        return RunResult(node=compiled_node, status=RunStatus.Success, ...)\n```\n\n## Implementation Quirks\n\n### `--inline` Support\n\n`CompileTask` supports inline SQL compilation via `--inline`. After compilation, the inline node is removed from the manifest.\n\n### Compiled SQL Location\n\nCompiled files are written to `target/compiled/{project_name}/{path}`:\n\n```\ntarget/\n  compiled/\n    my_project/\n      models/\n        marts/\n          orders.sql    # Compiled SQL (refs resolved)\n      tests/\n        unique_orders_id.sql\n```\n\n### `--introspect` Flag\n\nControls whether to run introspective queries (e.g., fetching column types). It is enabled by default.\n\n```python\nif self.args.introspect:\n    # Allow adapter queries during compilation\n```\n\n### Ephemeral CTE Injection\n\nWhen `--inject-ephemeral-ctes` is enabled, ephemeral model CTEs are inlined into the compiled SQL. This is enabled by default.\n\n### Output Formats\n\nThe `--output` flag controls how compiled SQL is displayed:\n\n| Value | Description |\n|-------|-------------|\n| `text` | Plain SQL text |\n| `json` | JSON with node metadata |\n\n## Flags\n\n| Flag | Description |\n|------|-------------|\n| `--select` | Compile selected nodes |\n| `--inline` | Compile inline SQL string |\n| `--output` | Output format: `text` or `json` |\n| `--introspect` / `--no-introspect` | Enable/disable adapter queries |\n| `--inject-ephemeral-ctes` | Inline ephemeral model CTEs |\n\n## Examples\n\n```bash\n# Compile all models\ndbt compile\n\n# Compile specific model\ndbt compile --select my_model\n\n# Compile inline SQL\ndbt compile --inline \"select * from {{ ref('orders') }}\"\n\n# Output as JSON\ndbt compile --select my_model --output json\n```\n\n## Use Cases\n\n1. **Preview SQL**: See exactly what SQL will run\n2. **Debug Jinja**: Verify template rendering\n3. **IDE Integration**: Generate SQL for external tools\n4. **CI Validation**: Ensure models compile without database access\n"
  },
  {
    "path": "docs/arch/6.11_dbt_source.md",
    "content": "# dbt source\n\n## Overview\n\n`dbt source` is a command group for managing sources. Currently, it has one subcommand:\n- `dbt source freshness`: Check the freshness of source data\n\n**Reference**: https://docs.getdbt.com/reference/commands/source\n\n## Subcommand: `dbt source freshness`\n\n### Task Class: `FreshnessTask`\n\n`FreshnessTask` extends `RunTask` (via different inheritance) and queries sources to check data freshness.\n\n### FreshnessRunner\n\n`FreshnessRunner` extends `BaseRunner` and queries source tables for freshness.\n\n## Implementation Quirks\n\n### Metadata Freshness Cache\n\nFor adapters supporting metadata-based freshness (table modification time as opposed to based on the max value of a dedicated event timestamp column in the data), results are cached:\n\n```python\nclass FreshnessRunner(BaseRunner):\n    def __init__(self, ...):\n        self._metadata_freshness_cache: Dict[BaseRelation, FreshnessResult] = {}\n```\n\nThis avoids re-querying metadata for tables that share the same physical relation.\n\n### Two Freshness Strategies\n\n1. **Query-based**: `SELECT MAX(loaded_at_field) FROM source`\n2. **Metadata-based**: Use adapter's `TableLastModifiedMetadata` capability\n\n```python\nif adapter.supports(Capability.TableLastModifiedMetadata):\n    # Use metadata instead of query\n    metadata = adapter.get_relation_last_modified(relation)\n```\n\n### Output Artifact\n\nWrites `sources.json` (not `run_results.json`):\n\n### Freshness Thresholds\n\nSource freshness config defines thresholds:\n\n```yaml\nsources:\n  - name: jaffle_shop\n    freshness:\n      warn_after: {count: 12, period: hour}\n      error_after: {count: 24, period: hour}\n    loaded_at_field: _etl_loaded_at\n    tables:\n      - name: orders\n```\n\nStatus is determined by comparing the data age (time since `max_loaded_at`) against configured thresholds:\n\n- If age exceeds `error_after` → **Error**\n- If age exceeds `warn_after` → **Warn**\n- Otherwise → **Pass**\n\n## Flags\n\n| Flag | Description |\n|------|-------------|\n| `--select` | Select sources to check |\n| `--exclude` | Exclude sources |\n| `--output` | Path for `sources.json` output |\n\n## Output Format\n\n`sources.json` structure:\n\n```json\n{\n  \"metadata\": {...},\n  \"results\": [\n    {\n      \"unique_id\": \"source.my_project.jaffle_shop.orders\",\n      \"status\": \"pass\",\n      \"max_loaded_at\": \"2024-01-15T10:30:00Z\",\n      \"snapshotted_at\": \"2024-01-15T11:00:00Z\",\n      \"age\": 1800.0,\n      \"criteria\": {\n        \"warn_after\": {\"count\": 12, \"period\": \"hour\"},\n        \"error_after\": {\"count\": 24, \"period\": \"hour\"}\n      }\n    }\n  ]\n}\n```\n\n## Use Cases\n\n1. **Data Quality Monitoring**: Alert when source data is stale\n2. **CI/CD Gates**: Block deployments if sources are stale\n3. **Dashboards**: Power freshness status dashboards\n4. **Incident Detection**: Identify broken upstream pipelines\n\n## Example\n\n```bash\n# Check all sources\ndbt source freshness\n\n# Check specific sources\ndbt source freshness --select source:jaffle_shop\n\n# Output to specific path\ndbt source freshness --output freshness_results/sources.json\n```\n"
  },
  {
    "path": "docs/arch/6.12_dbt_run-operation.md",
    "content": "# dbt run-operation\n\n## Overview\n\n`dbt run-operation` executes a macro by name, allowing you to run arbitrary operations defined in your project. It's useful for administrative tasks, data migrations, or any custom logic that doesn't fit the standard model/test workflow.\n\n**Reference**: https://docs.getdbt.com/reference/commands/run-operation\n\n## Task Class: `RunOperationTask`\n\n`RunOperationTask` extends `ConfiguredTask` (not `GraphRunnableTask`) since it executes a single macro, not a graph of nodes. \n\n## Implementation Quirks\n\n### Macro Name Parsing\n\nSupports both local and package-qualified macro names as input.\n\nExamples:\n- `my_macro` → searches in project\n- `my_package.my_macro` → searches in specific package\n\n### Macro Arguments\n\nArguments are passed via `--args` as a YAML dictionary:\n\n```bash\ndbt run-operation my_macro --args '{\"my_arg\": \"value\"}'\n```\n\n### Direct Adapter Execution\n\nUnlike model execution, `run-operation` calls `adapter.execute_macro()` directly:\n\n### Synthetic HookNode\n\nCreates a `HookNode` for the result artifact (since macros aren't nodes):\n\n```python\nrun_result = RunResult(\n    node=HookNode(\n        alias=macro_name,\n        checksum=FileHash.from_contents(unique_id),\n        resource_type=NodeType.Operation,\n        fqn=fqn,\n        name=macro_name,\n        unique_id=unique_id,\n        package_name=package_name,\n        path=\"\",\n        original_file_path=\"\",\n    ),\n    ...\n)\n```\n\n### Transaction Clearing\n\nClears any existing transaction before execution:\n\n### Return Value Not Used\n\nThe macro's return value is captured but not displayed:\n\n```python\nres = adapter.execute_macro(...)\n# res is not used further\n```\n\nTo output results, the macro should use `log()` or fire events.\n\n## Flags\n\n| Flag | Description |\n|------|-------------|\n| `MACRO` | Positional argument: macro name |\n| `--args` | YAML dictionary of arguments |\n\n## Use Cases\n\n1. **Grant Management**: `dbt run-operation grant_select --args '{\"role\": \"analyst\"}'`\n2. **Data Cleanup**: `dbt run-operation drop_old_partitions`\n3. **Metadata Updates**: `dbt run-operation update_table_comments`\n4. **Custom Maintenance**: Any DBA-style operations\n\n## Example Macro\n\n```sql\n-- macros/grant_select.sql\n{% macro grant_select(role) %}\n  {% set sql %}\n    GRANT SELECT ON ALL TABLES IN SCHEMA {{ target.schema }} TO ROLE {{ role }}\n  {% endset %}\n  \n  {% do run_query(sql) %}\n  {{ log(\"Granted SELECT to \" ~ role, info=True) }}\n{% endmacro %}\n```\n\n```bash\ndbt run-operation grant_select --args '{\"role\": \"analyst\"}'\n```\n\n## Retry Behavior\n\n`run-operation` results appear in `run_results.json` and are handled specially by `dbt retry`:\n- Only retried if the previous command was `run-operation`\n- Operation nodes are filtered out when retrying other commands\n"
  },
  {
    "path": "docs/arch/6.13_dbt_init.md",
    "content": "# dbt init\n\n## Overview\n\n`dbt init` scaffolds a new dbt project or initializes a profile for an existing project. It creates the standard dbt directory structure and optionally configures database credentials.\n\n**Reference**: https://docs.getdbt.com/reference/commands/init\n\n## Task Class: `InitTask`\n\n`InitTask` extends `BaseTask` and handles interactive project/profile setup.\n\n## Implementation Quirks\n\n### Minimal Context\n\n`init` requires almost nothing—no profile, no project, no manifest:\n\n```python\n@requires.postflight\n@requires.preflight\ndef init(ctx, **kwargs):\n    with InitTask(ctx.obj[\"flags\"]) as task:\n        ...\n```\n\n### Positional Argument for Project Name\n\nFor backwards compatibility, project name can be passed as a positional argument:\n\n```python\n@click.argument(\"project_name\", required=False)\ndef init(ctx, project_name=None, **kwargs):\n    ...\n```\n\n### Starter Project Template\n\nUses a built-in starter project template is defined in `core/dbt/include/starter_project`.\n\n### Profile Creation Strategies\n\nThree methods to create a profile:\n\n1. **From adapter sample**: Uses adapter's `sample_profiles.yml`\n2. **From project template**: Uses project's profile template if provided\n3. **Interactive prompts**: Asks user for connection details\n\n### Adapter Discovery\n\nDiscovers available adapters from installed packages:\n\n```python\nadapter_names = _get_adapter_plugin_names()\n# Returns list like ['postgres', 'snowflake', 'bigquery', ...]\n```\n\n## Flags\n\n| Flag | Description |\n|------|-------------|\n| `--skip-profile-setup` | Skip interactive profile configuration |\n\n## Created Structure\n\n```\nmy_project/\n├── dbt_project.yml\n├── README.md\n├── models/\n│   └── example/\n│       ├── my_first_dbt_model.sql\n│       ├── my_second_dbt_model.sql\n│       └── schema.yml\n├── analyses/\n├── macros/\n├── seeds/\n├── snapshots/\n└── tests/\n```\n\n## Interactive Flow\n\n1. **Project Name**: Prompt for name (if not provided)\n2. **Adapter Selection**: Choose from installed adapters\n3. **Connection Details**: Adapter-specific prompts (host, database, credentials)\n4. **Profile Location**: Written to `~/.dbt/profiles.yml`\n"
  },
  {
    "path": "docs/arch/6.14_dbt_list.md",
    "content": "# dbt list\n\n## Overview\n\n`dbt list` (alias: `dbt ls`) lists resources in your dbt project matching selection criteria. It's useful for exploring the project, debugging selectors, and scripting.\n\n**Reference**: https://docs.getdbt.com/reference/commands/list\n\n## Task Class: `ListTask`\n\n`ListTask` extends `GraphRunnableTask` but doesn't execute nodes. It only performs lookups against the manifest.\n\n## Implementation Quirks\n\n### Always Returns Success\n\nUnlike execution commands, `list` always returns exit code 0:\n\n### Output Modes\n\nFour output formats via `--output`:\n\n| Mode | Example Output |\n|------|----------------|\n| `selector` | `my_model`, `source:jaffle_shop.orders` |\n| `name` | `my_model`, `orders` |\n| `json` | `{\"name\": \"my_model\", \"resource_type\": \"model\"}` |\n| `path` | `models/staging/my_model.sql` |\n\n### `--models` vs `--select`\n\nFor backwards compatibility, both flags work but are mutually exclusive. `--models` implies `--resource-type model`.\n\n### JSON Output Keys\n\nDefault keys in JSON output:\n\n```python\nALLOWED_KEYS = frozenset((\n    \"alias\", \"name\", \"package_name\", \"depends_on\", \"tags\",\n    \"config\", \"resource_type\", \"source_name\", \"original_file_path\", \"unique_id\",\n))\n```\n\nOverride with `--output-keys`:\n\n```bash\ndbt ls --output json --output-keys name config.materialized\n```\n\n### Nested Key Support\n\n`--output-keys` supports dot notation for nested values.\n\n### Hidden Alias\n\n`ls` is a hidden alias for `list`:\n\n```python\n-- core/dbt/cli/main.py\n\nls = copy(cli.commands[\"list\"])\nls.hidden = True\ncli.add_command(ls, \"ls\")\n```\n\n## Flags\n\n| Flag | Description |\n|------|-------------|\n| `--select` | Selection criteria |\n| `--exclude` | Exclude nodes |\n| `--models` | Shorthand for `--select --resource-type model` |\n| `--output` | Format: `selector`, `name`, `json`, `path` |\n| `--output-keys` | JSON keys to include |\n| `--resource-type` | Filter by type |\n\n## Examples\n\n```bash\n# List all models\ndbt ls --resource-type model\n\n# List modified models (requires --state)\ndbt ls --select state:modified --state prod-artifacts/\n\n# Get JSON with specific fields\ndbt ls --output json --output-keys name config.materialized\n\n# Get file paths for shell scripting\ndbt ls --select tag:nightly --output path | xargs wc -l\n```\n"
  },
  {
    "path": "docs/arch/6.15_dbt_retry.md",
    "content": "# dbt retry\n\n## Overview\n\n`dbt retry` re-executes failed nodes from the previous run. It reads the `run_results.json` artifact to determine which nodes failed and runs them using the same command and flags from the original invocation.\n\n**Reference**: https://docs.getdbt.com/reference/commands/retry\n\n## Task Class: `RetryTask`\n\n`RetryTask` extends `ConfiguredTask` and dynamically creates the appropriate task for the original command based on `run_results.json`.\n\n```python\nclass RetryTask(ConfiguredTask):\n    def __init__(self, args, config):\n        # Load previous run results\n        self.previous_results = load_result_state(\n            Path(config.project_root) / Path(state_path) / \"run_results.json\"\n        )\n        \n        # Determine which command was run\n        self.previous_command_name = self.previous_args.get(\"which\")\n        self.task_class = TASK_DICT.get(self.previous_command_name)\n```\n\n## Implementation Quirks\n\n### Supported Commands\n\nOnly certain commands are retryable:\n\n```python\nTASK_DICT = {\n    \"build\": BuildTask,\n    \"compile\": CompileTask,\n    \"clone\": CloneTask,\n    \"generate\": GenerateTask,\n    \"seed\": SeedTask,\n    \"snapshot\": SnapshotTask,\n    \"test\": TestTask,\n    \"run\": RunTask,\n    \"run-operation\": RunOperationTask,\n}\n```\n\n### Retryable Statuses\n\nNodes with these statuses are retried:\n\n```python\nRETRYABLE_STATUSES = {\n    NodeStatus.Error,\n    NodeStatus.Fail,\n    NodeStatus.Skipped,\n    NodeStatus.RuntimeErr,\n    NodeStatus.PartialSuccess,  # Microbatch partial failure\n}\n```\n\n### Flag Merging\n\nRetry combines previous flags with current CLI arguments:\n\nFlags are merged as follows:\n\n1. **From previous run**: Most flags are restored (e.g., `--select`, `--full-refresh`, `--defer`)\n2. **Always from current invocation**: Path-related flags (`--profiles-dir`, `--project-dir`, `--target-path`, `--log-path`) and `--warn-error`\n3. **CLI override allowed**: `--vars` and `--threads` can be overridden if explicitly passed on the command line\n\n### Dynamic Task Wrapping\n\nRetry creates a wrapper class that overrides the original Task's `get_graph_queue()`:\n\n```python\nclass TaskWrapper(self.task_class):\n    def get_graph_queue(self):\n        new_graph = self.graph.get_subset_graph(unique_ids)\n        return GraphQueue(new_graph.graph, self.manifest, unique_ids)\n```\n\n### Microbatch Batch-Level Retry\n\nFor microbatch models, retry only re-runs failed batches by passing a `batch_map` to the `RunTask`.\n\n### Operation Node Filtering\n\n`run-operation` results aren't retried if not retrying `dbt run-operation` directly.\n\n### `--warn-error` Interaction\n\nIf `--warn-error` is set for retry, warnings from previous runs become failures:\n\n```python\nif args.warn_error:\n    RETRYABLE_STATUSES.add(NodeStatus.Warn)\n```\n\n### Late Manifest Parsing\n\nUnlike most commands, retry parses the manifest inside the task after resolving flags:\n\n```python\n# Parse manifest using resolved config/flags\nmanifest = parse_manifest(retry_config, ...)\n```\n\n## Flags\n\n| Flag | Description |\n|------|-------------|\n| `--state` | Override path to previous run results |\n| `--threads` | Override thread count |\n| `--vars` | Override variables |\n| `--full-refresh` | Force full refresh for incremental models |\n\n## Use Cases\n\n1. **CI Recovery**: Re-run failed nodes after fixing issues\n2. **Transient Failures**: Retry after network/database hiccups\n3. **Partial Deployments**: Complete interrupted runs\n4. **Microbatch Resumption**: Continue from failed batch\n\n## Example Flow\n\n```bash\n# Original run fails on 3 models\ndbt run --select tag:nightly\n\n# Fix the issues, then retry just the failures\ndbt retry\n\n# Or retry with different parallelism\ndbt retry --threads 1\n```\n"
  },
  {
    "path": "docs/arch/6.16_dbt_clone.md",
    "content": "# dbt clone\n\n## Overview\n\n`dbt clone` creates zero-copy clones of database objects from a source environment (typically production) to a target environment. This enables fast environment setup without data copying, using database-native cloning features.\n\n**Reference**: https://docs.getdbt.com/reference/commands/clone\n\n## Task Class: `CloneTask`\n\n`CloneTask` extends `GraphRunnableTask` and uses database cloning instead of materialization.\n\n## Implementation Quirks\n\n### Always Requires State\n\nUnlike other commands where `--defer` and `--state` are optional, clone always requires knowing where to clone from.\n\n### Independent Execution Mode\n\nClone uses `GraphRunnableMode.Independent`, which means nodes are run without topological ordering.\n\nThis is because clones don't depend on each other—they all reference the source environment.\n\n### No Compilation\n\n`CloneRunner.compile()` is a no-op since there's no SQL to compile!\n\n### Clone Materialization Macro\n\nCloning is handled by the `clone` materialization macro.\n\nThe macro calls adapter-specific clone methods (e.g., `CREATE TABLE ... CLONE` on Snowflake).\n\n### Schema Caching\n\nClone caches both target and source (defer_relation) schemas.\n\n### Refable Node Types Only\n\nClone only works with \"refable\" nodes (models, seeds, snapshots).\n\n## Flags\n\n| Flag | Description |\n|------|-------------|\n| `--select` | Select nodes to clone |\n| `--exclude` | Exclude nodes |\n| `--state` | Path to production manifest (required) |\n| `--resource-type` | Filter by type (model, seed, snapshot) |\n| `--full-refresh` | Re-clone even if target exists |\n\n## Database Support\n\nClone support varies by adapter:\n\n| Adapter | Clone Method |\n|---------|--------------|\n| Snowflake | `CREATE TABLE ... CLONE` |\n| BigQuery | Table copy/clone |\n| Databricks | Delta Lake shallow clone |\n| Others | Falls back to `CREATE TABLE AS SELECT` |\n\n## Use Cases\n\n1. **Dev Environment Setup**: Clone production to development instantly\n2. **CI Environments**: Create isolated test environments\n3. **Blue/Green Deployment**: Clone before schema migrations\n4. **Data Sampling**: Clone structure without full data\n\n## Example\n\n```bash\n# Clone production models to development\ndbt clone --select tag:core --state prod-artifacts/\n\n# Clone with full refresh\ndbt clone --select my_model --state prod-artifacts/ --full-refresh\n```\n"
  },
  {
    "path": "docs/arch/6.17_dbt_debug.md",
    "content": "# dbt debug\n\n## Overview\n\n`dbt debug` validates the data warehouse connection by checking profile.yml configuration files, testing the database connection, and reporting dependency versions. It's the first troubleshooting command when dbt isn't working correctly.\n\n**Reference**: https://docs.getdbt.com/reference/commands/debug\n\n## Task Class: `DebugTask`\n\n`DebugTask` extends `BaseTask` and performs a series of validation checks:\n\n`DebugTask` performs the following checks in order:\n\n1. Print version info (dbt, Python, OS)\n2. Load and validate `profiles.yml`\n3. Load and validate `dbt_project.yml`\n4. Test required dependencies (e.g., git)\n5. Test database connection\n\n## Implementation Quirks\n\n### Minimal Context Requirements\n\n`dbt debug` uses minimal `@requires`. decorator as it doesn't require a loaded manifest, profile, or project to start. Only `@requires.preflight` and `@requires.postflight` are used.\n\n### Graceful Failure Handling\n\nUnlike other commands, `debug` continues checking even when individual steps fail. Each check returns a `SubtaskStatus` with success/failure status and details, allowing the full diagnostic report to be generated.\n\n### `--config-dir` Flag\n\nOpens the profiles directory in the system file manager using the OS-appropriate command.\n\n### `--connection` Flag\n\nSkips configuration validation (profiles.yml, dbt_project.yml, dependencies) and jumps straight to connection testing.\n\n### Multiple Profile Handling\n\nIf no `dbt_project.yml` exists, debug lists available profiles from `profiles.yml` and prompts the user to specify one with `--profile`.\n\n### Adapter Version Detection\n\nDebug dynamically imports adapter packages (e.g., `dbt.adapters.postgres.__version__`) to report installed versions. Returns \"unknown\" if the adapter module can't be found.\n\n## Checks Performed\n\n| Check | Description |\n|-------|-------------|\n| dbt version | Installed dbt-core version |\n| python version | Python interpreter version |\n| python path | Path to Python executable |\n| os info | Operating system details |\n| profiles.yml | Profile file exists and is valid YAML |\n| dbt_project.yml | Project file exists and is valid |\n| adapter type | Which adapter is configured |\n| adapter version | Installed adapter package version |\n| Connection | Test database connectivity |\n\n## Flags\n\n| Flag | Description |\n|------|-------------|\n| `--config-dir` | Open profiles directory in file manager |\n| `--connection` | Skip to connection test only |\n\n## Output Example\n\n```\ndbt version: 1.7.0\npython version: 3.10.12\npython path: /usr/bin/python3\nos info: Linux-5.15.0-x86_64\n\nUsing profiles dir at /home/user/.dbt\nUsing profiles.yml file at /home/user/.dbt/profiles.yml\nUsing dbt_project.yml file at /home/user/project/dbt_project.yml\n\nConfiguration:\n  profiles.yml file [OK found and valid]\n  dbt_project.yml file [OK found and valid]\n\nRequired dependencies:\n  - git [OK found]\n\nConnection:\n  adapter: postgres\n  connection_info: host=localhost port=5432 user=analyst\n  Connection test: [OK connection ok]\n```\n"
  },
  {
    "path": "docs/arch/6.18_dbt_clean.md",
    "content": "# dbt clean\n\n## Overview\n\n`dbt clean` removes directories specified in the `clean-targets` config, typically `target/` (compiled artifacts) and `dbt_packages/` (installed packages). It's useful for resetting state before a fresh build.\n\n**Reference**: https://docs.getdbt.com/reference/commands/clean\n\n## Task Class: `CleanTask`\n\n`CleanTask` extends `BaseTask` and requires minimal context—no manifest, profile, or database connection.\n## Implementation Quirks\n\n### No Profile Required\n\n`@requires.unset_profile` indicates clean doesn't need database credentials:\n\n```python\n@requires.unset_profile\n@requires.project\ndef clean(ctx, **kwargs):\n    with CleanTask(ctx.obj[\"flags\"], ctx.obj[\"project\"]) as task:\n        ...\n```\n\n### `--clean-project-files-only`\n\nControls scope of cleaning:\n- Without flag: Cleans both project-level and dbt-managed directories\n- With flag: Only cleans project-defined `clean-targets`\n\n### Default Clean Targets\n\nIf not specified in `dbt_project.yml`, defaults to:\n- `target/`\n- `dbt_packages/`\n\n## Flags\n\n| Flag | Description |\n|------|-------------|\n| `--clean-project-files-only` | Only clean project-defined targets |\n\n## Configuration\n\n```yaml\n# dbt_project.yml\nclean-targets:\n  - target\n  - dbt_packages\n  - logs\n  - compile_output  # Custom directory\n```\n\n## Safety\n\n`CleanTask` only removes directories explicitly listed in `clean-targets`. It won't remove:\n- Source files (`models/`, `seeds/`, etc.)\n- Configuration files (`dbt_project.yml`, `profiles.yml`)\n- Version control (`.git/`)\n"
  },
  {
    "path": "docs/arch/6.1_dbt_parse.md",
    "content": "# dbt parse\n\n## Overview\n\n`dbt parse` parses the project and writes the manifest without executing any nodes. It's useful for validating project structure, measuring parse performance, and generating the manifest for external tools.\n\n**Reference**: https://docs.getdbt.com/reference/commands/parse\n\n## Task Implementation\n\nUnlike most commands, `parse` has no dedicated Task class—the work happens in the `@requires.manifest` decorator:\n\n```python\n@requires.manifest(write_perf_info=True)\ndef parse(ctx, **kwargs):\n    # manifest generation and writing happens in @requires.manifest\n    return ctx.obj[\"manifest\"], True\n```\n\n## Implementation Quirks\n\n### Performance Info\n\nThe `write_perf_info=True` flag causes parsing performance data to be written:\n\n```python\n@requires.manifest(write_perf_info=True)\n```\n\nThis writes timing information for each parsing phase to help diagnose slow parses.\n\n### Return Value\n\n`parse` is unique in returning the `Manifest` object directly\n\nOther commands return execution results like `RunExecutionResult`.\n\n### Partial Parsing Integration\n\n`parse` respects partial parsing settings. A full parse happens when:\n- `--no-partial-parse` is specified\n- `partial_parse.msgpack` is missing or invalid\n- Project configuration changed\n\n### No Compilation\n\n`parse` only parses. It doesn't compile SQL, meaning:\n- Jinja is not rendered\n- `compiled_code` is not populated\n- Refs/sources are extracted but not fully resolved\n\n### Manifest Output\n\nWrites `manifest.json` to the target directory (respects `--write-json` flag, which is enabled by default).\n\n## Flags\n\n| Flag | Description |\n|------|-------------|\n| `--partial-parse` / `--no-partial-parse` | Enable/disable partial parsing |\n| `--write-json` / `--no-write-json` | Write manifest.json |\n\n## Use Cases\n\n1. **Validate Syntax**: Check YAML and SQL for errors\n2. **Measure Performance**: Diagnose slow parsing with perf info\n3. **Generate Manifest**: Create manifest for external tools (IDE plugins, CI systems)\n4. **Pre-warm Cache**: Populate partial parse cache before execution\n5. **CI Validation**: Ensure project parses without database access\n\n## Performance Metrics\n\nWith `write_perf_info=True`, the following are tracked:\n- File reading time\n- YAML parsing time\n- Per-parser timing (models, tests, sources, etc.)\n- Partial parsing hit/miss\n- Total parse duration\n"
  },
  {
    "path": "docs/arch/6.2_dbt_run.md",
    "content": "# dbt run\n\n## Overview\n\n`dbt run` compiles and executes models against the target database. It's the core command for materializing SQL and Python models as tables, views, or incremental updates.\n\n**Reference**: https://docs.getdbt.com/reference/commands/run\n\n## Task Class: `RunTask`\n\n`RunTask` extends `CompileTask` (which extends `GraphRunnableTask`) and is the base class for most execution commands. Key characteristics:\n\n- **Runner**: Uses `ModelRunner` for standard models, `MicrobatchModelRunner` for microbatch incremental models\n- **Resource Types**: Models only (`NodeType.Model`)\n- **Error Handling**: `raise_on_first_error()` returns `False`—continues processing other nodes after failures\n- **Hooks**: Executes `on-run-start` and `on-run-end` hooks via `safe_run_hooks()`\n\n### Execution Flow\n\n1. **before_run()**: Creates schemas, populates adapter cache, calls `defer_to_manifest()` if `--defer` is set\n2. **Hook execution**: Runs `on-run-start` hooks\n3. **Node execution**: For each selected model, `ModelRunner` compiles and materializes\n4. **Hook execution**: Runs `on-run-end` hooks\n\n### ModelRunner\n\n`ModelRunner` extends `CompileRunner` and handles the compile-then-execute lifecycle:\n\n```\ncompile() → execute() → after_execute()\n```\n\nIn `execute()`:\n1. Generates runtime context via `generate_runtime_model_context()`\n2. Looks up materialization macro via `manifest.find_materialization_macro_by_name()`\n3. Invokes the macro via `MacroGenerator`\n4. Caches created relations for the adapter cache\n5. Returns `RunResult`\n\n## Implementation Quirks\n\n### Tracking\n\n`RunTask` includes model run tracking via `track_model_run()` which sends anonymized telemetry including execution time, materialization type, incremental strategy, contract enforcement status, and versioning.\n\n### Empty Execution\n\nThe `--empty` flag allows running with `LIMIT 0` to test compilation and downstream effects without processing data. This is handled by models' ref/source resolution injecting empty result sets.\n\n## Microbatch Models\n\nMicrobatch is a special incremental strategy for processing time-series data in batches. When a model has `incremental_strategy='microbatch'`, dbt uses `MicrobatchModelRunner` instead of `ModelRunner`.\n\n### How Microbatch Works\n\nRather than processing all data in a single transaction, microbatch:\n\n1. Divides the time range into batches based on `batch_size` (hour, day, month, year)\n2. Executes each batch as a separate transaction\n3. Supports parallel batch execution after the first batch succeeds\n4. Tracks batch-level success/failure for retry capability\n\n### Key Classes\n\n**`MicrobatchBuilder`** (`core/dbt/materializations/incremental/microbatch.py`):\n- Constructs batch definitions from model config (`begin`, `batch_size`, `lookback`)\n- Builds start/end times for each batch\n- Creates Jinja context for batch execution\n\n**`MicrobatchModelRunner`**:\n- Orchestrates batch execution\n- Manages parallel execution via thread pool\n- Tracks `relation_exists` to know when parallel execution is safe\n\n**`BatchRunner`**:\n- Handles single batch execution\n- Called by `MicrobatchModelRunner._execute_microbatch_materialization()`\n\n### Batch Execution Flow\n\n```\nMicrobatchModelRunner.execute()\n  └── For each batch:\n        └── BatchRunner._execute_microbatch_materialization()\n              ├── Build jinja context with batch bounds\n              ├── Execute materialization macro\n              └── Return batch result\n```\n\n### CLI Flags for Microbatch\n\n| Flag | Description |\n|------|-------------|\n| `--event-time-start` | Override start time for batch range |\n| `--event-time-end` | Override end time for batch range |\n\n### Retry Behavior\n\nMicrobatch models support granular retry—only failed batches are re-executed on `dbt retry`. This is tracked via `batch_results` in `RunResult`, which stores `BatchResults` containing `successful` and `failed` batch lists.\n\nWhen retrying:\n- If some batches succeeded previously, only failed batches run\n- If no batches succeeded, the model runs in full-refresh mode (to handle schema changes)\n\n### Configuration\n\n```yaml\nmodels:\n  my_model:\n    materialized: incremental\n    incremental_strategy: microbatch\n    batch_size: day  # hour, day, month, year\n    begin: '2020-01-01'\n    lookback: 1  # number of batches to re-process for late-arriving data\n```\n"
  },
  {
    "path": "docs/arch/6.3_dbt_build.md",
    "content": "# dbt build\n\n## Overview\n\n`dbt build` runs all seeds, models, snapshots, and tests in DAG order. It's the \"do everything\" command that respects dependencies across resource types.\n\n**Reference**: https://docs.getdbt.com/reference/commands/build\n\n## Task Class: `BuildTask`\n\n`BuildTask` extends `RunTask` and adds multi-resource-type execution with test edges in the graph.\n\n### Key Differences from `RunTask`\n\n1. **Multiple Resource Types**: Handles seeds, models, snapshots, tests, unit tests, saved queries, exposures, and functions via `RUNNER_MAP`\n2. **Test Edges**: Calls `compiler.compile(manifest, add_test_edges=True)` to add edges from tests to downstream nodes\n3. **Unit Test Handling**: Runs unit tests *before* their associated model (see below)\n\n### RUNNER_MAP\n\n```python\nRUNNER_MAP = {\n    NodeType.Model: ModelRunner,\n    NodeType.Snapshot: SnapshotRunner,\n    NodeType.Seed: SeedRunner,\n    NodeType.Test: TestRunner,\n    NodeType.Unit: TestRunner,\n    NodeType.SavedQuery: SavedQueryRunner,\n    NodeType.Exposure: ExposureRunner,\n    NodeType.Function: FunctionRunner,\n}\n```\n\n## Implementation Quirks\n\n### Test Edge Injection\n\nThe `add_test_edges=True` flag adds graph edges that ensure tests run at the right time:\n- Tests run *after* all their parent nodes complete\n- If a test fails, downstream nodes are skipped\n\nThis differs from `dbt run` + `dbt test` where either models or tests are run, but not both resource types.\n\n### Unit Test Ordering\n\nUnit tests run *before* their associated model, not after. This is handled specially:\n\n1. `get_graph_queue()` builds `model_to_unit_test_map` mapping model IDs to their unit tests\n2. When a model is dequeued, `handle_model_with_unit_tests_node()` runs unit tests first\n3. If any unit test fails, the model itself is skipped, via `call_model_and_unit_tests_runner()`\n\n### Node Count Adjustment\n\nBecause unit tests aren't in the main graph queue but are run inline with their models, `BuildTask` adjusts `num_nodes` in `handle_job_queue()`:\n\n```python\nif self.run_count == 0:\n    self.num_nodes = self.num_nodes + len(self.selected_unit_tests)\n```\n\n### Failure Propagation\n\n`BuildTask.MARK_DEPENDENT_ERRORS_STATUSES` determines which statuses cause downstream skips:\n\n```python\nMARK_DEPENDENT_ERRORS_STATUSES = [\n    NodeStatus.Error,\n    NodeStatus.Fail,\n    NodeStatus.Skipped,\n    NodeStatus.PartialSuccess,  # microbatch partial failure\n]\n```\n\n### Two-Pass Node Selection\n\nTo correctly count nodes and handle unit tests, `get_graph_queue()` runs selection twice:\n1. With unit tests, in order to identify selected unit tests\n2. Without unit tests—to build the actual execution queue\n\nThe difference is stored in `self.selected_unit_tests`.\n\n## Flags\n\n| Flag | Description |\n|------|-------------|\n| `--select` | Select nodes to build |\n| `--exclude` | Exclude nodes from build |\n| `--resource-type` | Filter by resource type (model, seed, snapshot, test) |\n| `--full-refresh` | Treat incremental models as full refreshes |\n| `--store-failures` | Store test failures in the database |\n"
  },
  {
    "path": "docs/arch/6.4_dbt_seed.md",
    "content": "# dbt seed\n\n## Overview\n\n`dbt seed` loads CSV files from the `seeds/` (or configured `seeds-dir` in dbt_project.yml) directory into the data warehouse as tables. Seeds are useful for small lookup tables, test fixtures, or static reference data.\n\n**Reference**: https://docs.getdbt.com/reference/commands/seed\n\n## Task Class: `SeedTask`\n\n`SeedTask` extends `RunTask` but filters to only `NodeType.Seed` resources:\n\n```python\nclass SeedTask(RunTask):\n    def get_node_selector(self):\n        return ResourceTypeSelector(\n            resource_types=[NodeType.Seed],\n            ...\n        )\n```\n\n### SeedRunner\n\n`SeedRunner` extends `ModelRunner` but with key differences:\n\n1. **No Compilation**: `compile()` returns the node unchanged—no Jinja rendering\n2. **Agate Table Result**: Returns the loaded agate table in the result for `--show` output\n\n```python\ndef compile(self, manifest: Manifest):\n    return self.node  # No Jinja compilation for seeds\n\ndef _build_run_model_result(self, model, context):\n    result = super()._build_run_model_result(model, context)\n    result.agate_table = context[\"load_result\"](\"agate_table\").table\n    return result\n```\n\n## Implementation Quirks\n\n### CSV Loading\n\nSeed CSV files are discovered during manifest loading, but the CSV content is **not** loaded during parsing. The `SeedParser` creates a `SeedNode` with file metadata (path, name, config) but explicitly skips content loading—the `render_with_context()` method is a no-op for seeds.\n\nThe actual CSV loading happens at **runtime** via `load_agate_table()` ([`core/dbt/context/providers.py`](https://github.com/dbt-labs/dbt-core/blob/main/core/dbt/context/providers.py)), which is called from the `seed` materialization macro. The adapter then handles bulk insert to the database.\n\nThe CSV is loaded into memory as an agate table via `load_agate_table()` in the Jinja context.\n\n### Large CSV Handling\n\nSeeds over **1 MB** (`MAXIMUM_SEED_SIZE`) receive special handling for partial parsing:\n\n```python\n# core/dbt/constants.py\nMAXIMUM_SEED_SIZE = 1 * 1024 * 1024  # 1 MB\n```\n\nFor large seeds:\n- **No content hashing**: Instead of hashing file contents, dbt uses the file path as the checksum (`FileHash.path()`). This avoids reading the entire file into memory during parsing.\n- **Change detection limitations**: Since content isn't hashed, dbt cannot reliably detect changes. It uses heuristics based on file path.\n\n**Warning messages for large seeds:**\n- `SeedIncreased`: Seed grew past 1MB threshold\n- `SeedExceedsLimitSamePath`: Large seed at same path, assuming unchanged\n- `SeedExceedsLimitAndPathChanged`: Large seed moved, assuming changed\n\n### `--show` Flag\n\nThe `--show` flag displays a random sample of each loaded seed:\n\n### Error Handling\n\n`raise_on_first_error()` returns `False`, so seed loading continues even if individual seed nodes fail.\n\n## Flags\n\n| Flag | Description |\n|------|-------------|\n| `--select` | Select specific seeds to load |\n| `--show` | Display random sample of loaded data |\n"
  },
  {
    "path": "docs/arch/6.5_dbt_snapshot.md",
    "content": "# dbt snapshot\n\n## Overview\n\n`dbt snapshot` executes snapshot definitions to capture slowly-changing dimension (SCD Type 2) history. Snapshots track changes to source data over time by maintaining historical records with validity timestamps.\n\n**Reference**: https://docs.getdbt.com/reference/commands/snapshot\n\n## Task Class: `SnapshotTask`\n\n`SnapshotTask` extends `RunTask` but filters to only `NodeType.Snapshot` resources.\n\n```python\nclass SnapshotTask(RunTask):\n    def get_node_selector(self):\n        return ResourceTypeSelector(\n            resource_types=[NodeType.Snapshot],\n            ...\n        )\n```\n\n### SnapshotRunner\n\n`SnapshotRunner` extends `ModelRunner` with snapshot-specific logging:\n\n```python\nclass SnapshotRunner(ModelRunner):\n    def describe_node(self) -> str:\n        return \"snapshot {}\".format(self.get_node_representation())\n    \n    def print_result_line(self, result):\n        # Includes snapshot config in output (strategy, unique_key, etc.)\n        cfg = model.config.to_dict(omit_none=True)\n        fire_event(LogSnapshotResult(..., cfg=cfg))\n```\n\n## Implementation Quirks\n\n### Snapshot Strategy Detection\n\nSnapshots use either `timestamp` or `check` strategy, configured in the snapshot definition:\n\n- **timestamp**: Tracks changes via `updated_at` column\n- **check**: Tracks changes by comparing all `check_cols`\n\nThe strategy is resolved during parsing and stored in `SnapshotNode.config.strategy`.\n\n### Materialization Macro\n\nUnder the hood, snapshots use the `snapshot` materialization macro (not `table` or `incremental`). This macro:\n\n1. Creates the snapshot table if it doesn't exist (with SCD columns: `dbt_scd_id`, `dbt_updated_at`, `dbt_valid_from`, `dbt_valid_to`)\n2. Identifies new and changed records\n3. Invalidates changed records (sets `dbt_valid_to`)\n4. Inserts new records with current validity\n\n### No Incremental Semantics\n\nUnlike models with `incremental` materialization, snapshots don't support `--full-refresh` in the same way. The `--full-refresh` flag for snapshots rebuilds from scratch, losing historical data.\n\n## Flags\n\n| Flag | Description |\n|------|-------------|\n| `--select` | Select specific snapshots to execute |\n| `--exclude` | Exclude snapshots |\n"
  },
  {
    "path": "docs/arch/6.6_dbt_test.md",
    "content": "# dbt test\n\n## Overview\n\n`dbt test` runs data tests and unit tests defined in your project. Data tests validate assumptions about your data (e.g., uniqueness, not null), while unit tests validate model logic with fixed inputs.\n\n**Reference**: https://docs.getdbt.com/reference/commands/test\n\n## Task Class: `TestTask`\n\n`TestTask` extends `RunTask` and handles both singular tests, generic tests, and unit tests.\n\n```python\nclass TestTask(RunTask):    \n    @property\n    def resource_types(self) -> List[NodeType]:\n        # TEST_NODE_TYPES = [NodeType.Test, NodeType.Unit]\n        return [rt for rt in resource_types if rt in TEST_NODE_TYPES]\n```\n\n### TestRunner\n\n`TestRunner` extends `CompileRunner` and handles three test types:\n\n1. **Singular Tests**: Custom SQL test files in `tests/` directory\n2. **Generic Tests**: Schema tests like `unique`, `not_null` from YAML\n3. **Unit Tests**: Tests with mocked inputs defined in YAML\n\n## Implementation Quirks\n\n### Test Execution Path Split\n\n`TestRunner.execute()` branches based on test type:\n\n```python\ndef execute(self, test, manifest):\n    if isinstance(test, UnitTestDefinition):\n        unit_test_node, result = self.execute_unit_test(test, manifest)\n        return self.build_unit_test_run_result(unit_test_node, result)\n    else:\n        test_result = self.execute_data_test(test, manifest)\n        return self.build_test_run_result(test, test_result)\n```\n\n### Unit Test Manifest Loading\n\nUnit tests require a separate mini-manifest containing mocked versions of referenced models:\n\n```python\ndef execute_unit_test(self, unit_test_def, manifest):\n    # Build isolated manifest with just this unit test\n    loader = UnitTestManifestLoader(manifest, self.config, {unit_test_def.unique_id})\n    unit_test_manifest = loader.load()\n    \n    # Compile and execute with the mocked manifest\n    unit_test_node = self.compiler.compile_node(unit_test_node, unit_test_manifest, {})\n    ...\n```\n\n### Unit Test Diff Rendering\n\nUnit tests compare actual vs expected results using the `daff` library for diff visualization:\n\n```python\ndef _get_daff_diff(self, expected, actual):\n    expected_table = daff.PythonTableView(list_rows_from_table(expected, sort=True))\n    actual_table = daff.PythonTableView(list_rows_from_table(actual, sort=True))\n    diff = daff.TableDiff(alignment, flags)\n    return diff\n```\n\nThe diff is rendered with colors (`green` for actual, `red` for expected).\n\n### Test Result Status Logic\n\nData test status depends on the `severity` config (`error` or `warn`) and the failure count thresholds (`error_if`, `warn_if`):\n\n- If severity is `ERROR` and failures exceed `error_if` → **Fail**\n- If failures exceed `warn_if` → **Warn** (or **Fail** if `--warn-error` is set)\n- Otherwise → **Pass**\n\n### `--store-failures`\n\nWhen enabled, test failures are stored in the database for later analysis. The `test` materialization creates a table with failing rows.\n\n## Flags\n\n| Flag | Description |\n|------|-------------|\n| `--select` | Select tests to run |\n| `--exclude` | Exclude tests |\n| `--store-failures` | Persist test failures to the database |\n| `--resource-type` | Filter by `test` or `unit` |\n\n## Test Configuration\n\n```yaml\nmodels:\n  - name: orders\n    columns:\n      - name: order_id\n        tests:\n          - unique\n          - not_null\n      - name: status\n        tests:\n          - accepted_values:\n              values: ['placed', 'shipped', 'delivered']\n\nunit_tests:\n  - name: test_order_total\n    model: orders\n    given:\n      - input: ref('order_items')\n        rows:\n          - {order_id: 1, amount: 10}\n          - {order_id: 1, amount: 20}\n    expect:\n      rows:\n        - {order_id: 1, total: 30}\n```\n"
  },
  {
    "path": "docs/arch/6.7_dbt_show.md",
    "content": "# dbt show\n\n## Overview\n\n`dbt show` compiles and executes a model or inline query, returning a preview of the results without materializing anything to the warehouse. It's useful for quickly testing SQL or viewing model output.\n\n**Reference**: https://docs.getdbt.com/reference/commands/show\n\n## Task Classes\n\n### `ShowTask`\n\n`ShowTask` extends `CompileTask` and uses `ShowRunner` to execute queries.\n\n### `ShowTaskDirect`\n\nFor `--inline-direct`, a simpler task that bypasses manifest loading entirely is invoked, `ShowTaskDirect`\n\n## Implementation Quirks\n\n### Ephemeral Model Handling\n\n`ShowRunner` sets `run_ephemeral_models = True`, which causes ephemeral upstream models to be executed inline (as CTEs) rather than skipped:\n\n```python\nclass ShowRunner(CompileRunner):\n    def __init__(self, ...):\n        super().__init__(...)\n        self.run_ephemeral_models = True\n```\n\n### `get_show_sql` Macro\n\nThe compiled SQL is wrapped by the `get_show_sql` macro which adds `LIMIT` and handles `sql_header`.\n\n### Output Formatting\n\nResults can be output as table (default) or JSON:\n\n```python\nif self.args.output == \"json\":\n    table.to_json(path=output)\nelse:\n    table.print_table(output=output, max_rows=None)\n```\n\n### `--limit` Behavior\n\n`--limit` controls the number of rows returned. Use `-1` for unlimited (returning all available rows).\n\n### Direct Mode (`--inline-direct`)\n\nThe `--inline-direct` flag executes raw SQL without any Jinja processing or manifest loading. This is the fastest path for quick queries.\n\n## Examples\n\n```bash\n# Preview a model\ndbt show --select my_model\n\n# Preview with more rows\ndbt show --select my_model --limit 100\n\n# Execute inline query with refs\ndbt show --inline \"select * from {{ ref('orders') }} limit 10\"\n\n# Execute raw SQL directly (fastest)\ndbt show --inline-direct \"select current_timestamp()\"\n```\n"
  },
  {
    "path": "docs/arch/6.8_dbt_deps.md",
    "content": "# dbt deps\n\n## Overview\n\n`dbt deps` downloads and installs dbt packages specified in `packages.yml` or `dependencies.yml`. It manages package resolution, version locking, and installation from the dbt Hub, git repositories, or local paths.\n\n**Reference**: https://docs.getdbt.com/reference/commands/deps\n\n## Task Class: `DepsTask`\n\n`DepsTask` extends `BaseTask` (not `GraphRunnableTask`) because it doesn't require a manifest or database connection:\n\n```python\nclass DepsTask(BaseTask):\n    def __init__(self, args, project):\n        super().__init__(args=args)\n        self.project = project  # Only needs project config, not runtime config\n```\n\n## Implementation Quirks\n\n### Lock File Management\n\n`dbt deps` uses a two-file system:\n- `packages.yml`: User-specified dependencies (version ranges allowed)\n- `package-lock.yml`: Resolved, pinned versions\n\nResolution flow:\n- If `packages.yml` changed or `--upgrade` is specified: resolve version ranges and update the lock file\n- Otherwise: use pinned versions from the lock file directly\n\n### SHA1 Hash Validation\n\nThe lock file includes a SHA1 hash of the serialized `packages.yml` contents. On each run, dbt computes the current hash and compares it to the stored hash. If they don't match, packages are re-resolved.\n\n### `--add-package` Flag\n\nAllows adding packages from CLI without editing `packages.yml`. Version is required unless the source is `local`.\n\n### Package Sources\n\nThree sources supported:\n\n1. **Hub** (`package:`): Downloads from packages.getdbt.com\n2. **Git** (`git:`): Clones from git repository\n3. **Local** (`local:`): Uses local filesystem path\n\n### No Profile Required\n\n`@requires.unset_profile` decorator indicates deps doesn't need database credentials:\n\n```python\n@requires.unset_profile  # Skip profile loading\n@requires.project        # Only need project config\ndef deps(ctx, **kwargs):\n    ...\n```\n\n## Flags\n\n| Flag | Description |\n|------|-------------|\n| `--source` | Package source: `hub`, `git`, or `local` |\n| `--lock` | Update only the lock file without installing |\n| `--upgrade` | Upgrade packages to latest matching versions |\n| `--add-package` | Add a package (format: `name@version`) |\n\n## Package Resolution\n\nPackages are resolved in order of specificity:\n\n```yaml\n# packages.yml\npackages:\n  - package: dbt-labs/dbt_utils\n    version: [\">=1.0.0\", \"<2.0.0\"]  # Version range\n  - git: https://github.com/org/repo\n    revision: v1.0.0                # Git ref\n  - local: ../my-local-package      # Filesystem path\n```\n\nThe lock file pins exact versions:\n\n```yaml\n# package-lock.yml\npackages:\n  - package: dbt-labs/dbt_utils\n    version: 1.1.1\nsha1_hash: abc123...\n```\n"
  },
  {
    "path": "docs/arch/6.9_dbt_docs.md",
    "content": "# dbt docs\n\n## Overview\n\n`dbt docs` is a command group with two subcommands:\n- `dbt docs generate`: Creates documentation website artifacts\n- `dbt docs serve`: Starts a local web server to view documentation\n\n**Reference**: https://docs.getdbt.com/reference/commands/cmd-docs\n\n## Subcommand: `dbt docs generate`\n\n### Task Class: `GenerateTask`\n\n`GenerateTask` extends `CompileTask` and produces three artifacts:\n1. `manifest.json`: Full project manifest\n2. `catalog.json`: Database metadata (tables, columns, stats)\n3. Static HTML/CSS/JS for the documentation site\n\nThe task compiles the manifest, queries database metadata for the catalog (unless `--empty-catalog`), and writes both artifacts.\n\n### Catalog Generation\n\nThe catalog is populated by querying the database's information schema via `adapter.get_catalog()`. This retrieves table/column metadata for all relations in the selected schemas.\n\n### `--static` Flag\n\nWhen set, copies the static documentation site files (HTML/CSS/JS) to the target directory.\n\n### `--empty-catalog` Flag\n\nSkips catalog generation entirely, producing an empty catalog. Useful for testing or when database access is slow.\n\n### `--compile` / `--no-compile`\n\nControls whether to compile the manifest with full Jinja rendering, or use the manifest as-is from parsing.\n\n### Flags\n\n| Flag | Description |\n|------|-------------|\n| `--select` | Generate docs for selected nodes only |\n| `--static` | Copy static site files to target |\n| `--empty-catalog` | Skip catalog generation |\n| `--no-compile` | Skip SQL compilation |\n\n---\n\n## Subcommand: `dbt docs serve`\n\n### Task Class: `ServeTask`\n\n`ServeTask` extends `ConfiguredTask` and starts a local HTTP server in the target directory, then opens the browser.\n\n### No Manifest Required\n\nUnlike most commands, `docs serve` doesn't load the manifest—it just serves static files. Only `@requires.runtime_config` is needed (for the target path).\n\n### Browser Opening\n\nBy default, opens the browser automatically. Disable with `--no-browser`.\n\n### Flags\n\n| Flag | Description |\n|------|-------------|\n| `--host` | Server host (default: `127.0.0.1`) |\n| `--port` | Server port (default: `8080`) |\n| `--browser` / `--no-browser` | Open browser automatically |\n\n## Artifacts\n\n### `catalog.json`\n\nContains database metadata:\n\n```json\n{\n  \"nodes\": {\n    \"model.my_project.orders\": {\n      \"metadata\": {\n        \"type\": \"table\",\n        \"schema\": \"public\",\n        \"name\": \"orders\"\n      },\n      \"columns\": {\n        \"id\": {\"type\": \"integer\", \"index\": 1},\n        \"status\": {\"type\": \"varchar\", \"index\": 2}\n      },\n      \"stats\": {\n        \"row_count\": {\"value\": 1000, \"label\": \"Row Count\"}\n      }\n    }\n  }\n}\n```\n\n### Documentation Site\n\nThe static site reads `manifest.json` and `catalog.json` at runtime to render:\n- Model lineage DAG\n- Column-level documentation\n- Test coverage\n- Source freshness\n"
  },
  {
    "path": "docs/arch/6_Commands.md",
    "content": "# Commands\n\nThis section documents each dbt CLI command's implementation details, including task classes, runners, and implementation quirks.\n\nFor detailed product documentation, see: https://docs.getdbt.com/category/list-of-commands\n\n## Command Index\n\n| Command | Task Class | Description |\n|---------|------------|-------------|\n| [dbt parse](6.1_dbt_parse.md) | *(@requires.manifest decorator)* | Parse project and write manifest |\n| [dbt run](6.2_dbt_run.md) | `RunTask` | Execute models against the database |\n| [dbt build](6.3_dbt_build.md) | `BuildTask` | Run seeds, models, snapshots, and tests in DAG order |\n| [dbt seed](6.4_dbt_seed.md) | `SeedTask` | Load CSV files into the database |\n| [dbt snapshot](6.5_dbt_snapshot.md) | `SnapshotTask` | Execute SCD Type 2 snapshots |\n| [dbt test](6.6_dbt_test.md) | `TestTask` | Run data tests and unit tests |\n| [dbt show](6.7_dbt_show.md) | `ShowTask` | Preview query results without materializing |\n| [dbt deps](6.8_dbt_deps.md) | `DepsTask` | Install package dependencies |\n| [dbt docs](6.9_dbt_docs.md) | `GenerateTask` / `ServeTask` | Generate and serve documentation |\n| [dbt compile](6.10_dbt_compile.md) | `CompileTask` | Generate compiled SQL without executing |\n| [dbt source](6.11_dbt_source.md) | `FreshnessTask` | Check source freshness |\n| [dbt run-operation](6.12_dbt_run-operation.md) | `RunOperationTask` | Execute a macro |\n| [dbt init](6.13_dbt_init.md) | `InitTask` | Scaffold new project or profile |\n| [dbt list](6.14_dbt_list.md) | `ListTask` | List project resources |\n| [dbt retry](6.15_dbt_retry.md) | `RetryTask` | Re-execute failed nodes |\n| [dbt clone](6.16_dbt_clone.md) | `CloneTask` | Create zero-copy clones from production |\n| [dbt debug](6.17_dbt_debug.md) | `DebugTask` | Validate environment and connection |\n| [dbt clean](6.18_dbt_clean.md) | `CleanTask` | Remove target and packages directories |\n\n## Command Categories\n\n### Execution Commands\nCommands that execute work against the database:\n- `dbt run` — Models\n- `dbt build` — All resource types\n- `dbt seed` — CSV data loading\n- `dbt snapshot` — SCD snapshots\n- `dbt test` — Data/unit tests\n- `dbt clone` — Zero-copy clones\n- `dbt source freshness` — Source monitoring\n- `dbt retry` — Failure recovery\n- `dbt run-operation` — Ad-hoc macro execution\n\n### Compilation Commands\nCommands that process SQL without executing:\n- `dbt compile` — Generate compiled SQL\n- `dbt show` — Preview results\n- `dbt parse` — Build manifest only\n\n### Utility Commands\nCommands for project management:\n- `dbt deps` — Package management\n- `dbt clean` — Clear artifacts\n- `dbt init` — Project scaffolding\n- `dbt debug` — Warehouse connection validation\n- `dbt list` — Resource listing\n- `dbt docs` — Documentation generation/serving\n\n## Common Patterns\n\n### Context Requirements\n\nCommands use `@requires` decorators to build their execution context:\n\n| Decorator | Provides |\n|-----------|----------|\n| `@requires.preflight` | Logging, tracking setup |\n| `@requires.profile` | Database credentials |\n| `@requires.project` | Project configuration |\n| `@requires.runtime_config` | Merged profile + project |\n| `@requires.manifest` | Parsed manifest |\n\n### Runner Pattern\n\nExecution commands use the Runner pattern:\n1. Task creates `GraphQueue` of selected nodes\n2. Thread pool processes nodes in parallel\n3. Each node is handled by a `Runner` subclass\n4. Runner calls `compile()` → `execute()`\n\n### Result Artifacts\n\nMost commands write `run_results.json`. Exceptions:\n- `dbt source freshness` → `sources.json`\n- `dbt docs generate` → `catalog.json`\n- `dbt list` → stdout only\n"
  },
  {
    "path": "docs/arch/7_Artifacts.md",
    "content": "# Artifacts\n\n## `dbt/artifacts` Directory\nThis directory is meant to be a lightweight module that is independent (and upstream of) the rest of `dbt-core` internals.\n\nIts primary responsibility is to define simple data classes that represent the versioned artifact schemas that dbt writes as JSON files throughout execution. \n\nEventually, this module may be released as a standalone package (e.g. `dbt-artifacts`) to support stable programmatic parsing of dbt artifacts.\n\n`dbt/artifacts` is organized into artifact 'schemas' and 'resources'. Schemas represent the final serialized artifact objects, while resources represent smaller components within those schemas.\n\n### dbt/artifacts/schemas\n\nEach major version of a schema under `dbt/artifacts/schema` is defined in its corresponding `dbt/artifacts/schema/<artifact-name>/v<version>` directory. Before `dbt/artifacts` artifact schemas were always modified in-place, which is why older artifacts are those missing class definitions.\n\nCurrently, there are four artifact schemas defined in `dbt/artifact/schemas`:\n\n| Artifact name | File             | Class                            | Latest definition                 |\n|---------------|------------------|----------------------------------|-----------------------------------|\n| manifest      | manifest.json    | WritableManifest                 | dbt/artifacts/schema/manifest/v12 |\n| catalog       | catalog.json     | CatalogArtifact                  | dbt/artifacts/schema/catalog/v1   |\n| run           | run_results.json | RunResultsArtifact               | dbt/artifacts/schema/run/v5       |\n| freshness     | sources.json     | FreshnessExecutionResultArtifact | dbt/artifacts/schema/freshness/v3 |\n\n\n### dbt/artifacts/resources\n\nAll existing resources are defined under `dbt/artifacts/resources/v1`.\n\n## Making changes to dbt/artifacts\n\n### All changes\n\nAll changes to any fields will require a manual update to [dbt-jsonschema](https://github.com/dbt-labs/dbt-jsonschema) to ensure live checking continues to work.\n\n### Non-breaking changes\n\nFreely make incremental, non-breaking changes in-place to the latest major version of any artifact (minor or patch bumps). The only changes that are fully forward and backward compatible are:\n* Adding a new field with a default\n* Deleting a field with a default. This is compatible in terms of serialization and deserialization, but still may be lead to suprising behaviour:\n    * For artifact consumers relying on the fields existence (e.g. `manifest[\"deleted_field\"]` will stop working unless the access was implemented safely)\n    * Old code (e.g. in dbt-core) that relies on the value of the deleted field may have surprising behaviour given only the default value will be set when instantiated from the new schema\n\nThese types of minor, non-breaking changes are tested by [tests/unit/artifacts/test_base_resource.py::TestMinorSchemaChange](https://github.com/dbt-labs/dbt-core/blob/main/tests/unit/artifacts/test_base_resource.py).\n\n\n#### Updating [schemas.getdbt.com](https://schemas.getdbt.com)\nNon-breaking changes to artifact schemas require an update to the corresponding jsonschemas published to [schemas.getdbt.com](https://schemas.getdbt.com), which are defined in https://github.com/dbt-labs/schemas.getdbt.com. To do so: \nNote this must be done AFTER the core pull request is merged, otherwise we may end up with unresolvable conflicts and schemas that are invalid prior to base pull request merge. You may create the schemas.getdbt.com pull request prior to merging the base pull request, but do not merge until afterward.\n1. Create a PR in https://github.com/dbt-labs/schemas.getdbt.com which reflects the schema changes to the artifact. The schema can be updated in-place for non-breaking changes. Example PR: https://github.com/dbt-labs/schemas.getdbt.com/pull/39\n2. Merge the https://github.com/dbt-labs/schemas.getdbt.com PR\n\nNote: Although `jsonschema` validation using the schemas in [schemas.getdbt.com](https://schemas.getdbt.com) is not encouraged or formally supported, `jsonschema` validation should still continue to work once the schemas are updated because they are forward-compatible and can therefore be used to validate previous minor versions of the schema.\n\n### Breaking changes\nA breaking change is anything that:\n* Deletes a required field\n* Changes the name or type of an existing field\n* Removes the default value of an existing field\n\nThese should be avoided however possible. When necessary, multiple breaking changes should be bundled together, to aim for minimal disruption across the ecosystem of tools that leverage dbt metadata. \n\nWhen it comes time to make breaking changes, a new versioned artifact should be created as follows: \n 1. Create a new version directory and file that defines the new artifact schema under `dbt/artifacts/schemas/<artifact>/v<next-artifact-version>/<artifact>.py`\n 2. If any resources are having breaking changes introduced, create a new resource class that defines the new resource schema under `dbt/artifacts/resources/v<next-resource-version>/<resource>.py`\n 3. Implement upgrade paths on the new versioned artifact class so it can be constructed given a dictionary representation of any previous version of the same artifact\n     * TODO: link example once available\n4. Implement downgrade paths on all previous versions of the artifact class so they can still be constructed given a dictionary representation of the new artifact schema\n    * TODO: link example once available\n5. Update the 'latest' aliases to point to the new version of the artifact and/or resource:\n    * Artifact: `dbt/artifacts/schemas/<artifact>/__init__.py `\n    * Resource: `dbt/artifacts/resources/__init__.py `\n\nDownstream consumers (e.g. `dbt-core`) importing from the latest alias are susceptible to breaking changes. Ideally, any incompatibilities should be caught my static type checking in those systems. However, it is always possible for consumers to pin imports to previous versions via `dbt.artifacts.schemas.<artifact>.v<prev-version>`.\n"
  },
  {
    "path": "docs/arch/8_Versioning_Branching_Strategy.md",
    "content": "# Release Versioning / Branching Strategy\n\n## Context\nWith `dbt` ever evolving and progressing, we continue to ship and release versions on a regular basis. As we release `dbt`, versioning and branching become key to identifying what is different for users and conveying the expectations of those changes. We currently push all our commits to `main` which is the latest version of our code. We don't always want to release the latest version of our code though. We want to be able to isolate commits to go into particular releases based on urgency (e.g. bug fixes) and stability (e.g. new features). \n\nWe already have an established versioning strategy when it comes to major/minor/patch releases. The following is our approach as to what to expect from each release version:\n\n* Major version: This signifies that breaking changes which require user action are included in this release.\n* Minor version: This signifies that new features are included in this release.\n* Patch version: This signifies that bug and security fixes are included in this release.\n\nWe need a versioning strategy that allows us to to convey to users the confidence and stability of code they are installing. We want a versioning strategy that allows users to try out new changes, and experiment with them to get early feedback. We want to make sure users can also get a preview of new features we are working on, so they can incorporate these changes into their work as soon as possible. \n\nWe need a branching strategy to support the goals of the versioning strategy. We do not want to have to stop development on `main` as we await a release, nor do we want every change in `main` published in every release. Using branches, we can decide which changes go into which release.\n\n## Common Terminology\n* Release version: refers to the numeric value of the release (eg. `1.0.1`, `0.21.0`) There are major, minor, and patch release versions that map to standard [semantic versioning practices](https://semver.org/#semantic-versioning-200).\n* Release phase: refers to the stability of the release (eg. beta, rc, final). \n\n## Requirements\nThe following are requirements that must be met for releasing dbt:\n\n1. We must have major, minor, and patch releases.\n1. We must have release phases that have the goal of garnering early feedback from the Community.\n1. We must have release phases that aim to identify bugs and test for stability.\n1. We must have release phases that are stable and of production quality.\n1. We must have the ability to isolate changes from different versions and phases to release.\n1. A version of `dbt-core` is considered released when it is available on GitHub Releases, PyPi, GitHub Container Registry, and Homebrew. This also applies to the individual `dbt` adapters. Otherwise, a version is considered partially released if only on a subset of those platforms.\n\n## Branching Strategies Considered\nThe 2 branching strategies we are considering using going forward are:\n\t1. A new branch for each and every release\n\t1. A new branch for each minor version which we release minor and patch versions from (current strategy)\n\n### New branch for every release\n#### Pros: \n* Easy mapping between a release and a branch. Great for troubleshooting issues.\n* Less confusing and more straightforward for running a release on a branch. No question of what version is being released.\n#### Cons:\n* Breaks current adapters CI which needs to point to the exact `dbt-core` branch that it needs to test with. The branches would need to be updated in all adapter repos for each final and prerelease branch every time we have a new release branch for `dbt-core`. \n* Confusing for backporting. We will need to keep creating new labels and making sure we remove the old labels because we don't want to accidently backport to the wrong branch.\n\n### Minor release branches (current strategy)\n#### Pros:\n* Adapter CI testing will continue to work with this strategy and makes it less complicated overall. Adapters and `dbt-core` need to be on the same minor version but can be on different patch versions. The current CI workflows verify that the changes slated for a new `1.1` patch are compatible across all repos by checking out the `1.1.latest` branch of each repo. The 1:1 mapping of adapter branches to `dbt-core` branches makes this easy.\n* Easy backporting. There is no need to figure out the exact branch that you need to backport to and accidently backporting to an older, stale branch.\n#### Cons:\n* Branches contain more than 1 release which is confusing. Without a 1:1 mapping between branch and release, you must rely on tags instead to know where in the branch the release was cut.\n* Releasing from the same branch multiple times can lead to confusion as to which version we are releasing. A branch named for the specific version could be extracted and used to run the bumpversion script instead of relying on human input at release time.\n\n## Decisions\n\n### Version phases\n<details>\n<summary> Header Explanations: </summary>\n\n- phases: defined in [Common Terminology](#common-terminology)\n- Released?: do we plan to release this phase to GitHub, PyPi, etc.\n- Branches: the branches where these release phases are present (e.g. betas should only exist on the `main` branch)\n- Applicable Release Versions: the release versions where the release phase is applicable (i.e. we will only have alphas for major and minor versions, we will not have alphas for patch versions)\n- Expectations: the stability of the code changes in the release\n</details>\n\n| Phase | Released? | Branches | Applicable Release Versions | Expectations |\n| ---- | --------- | -------- | ---------------- | ------------ |\n| Alpha | No | `main` | Major / Minor | Experimental |\n| Beta | Yes | `main` | Major / Minor | Experimental |\n| RC | Yes | Release branch | Major / Minor / Patch | Pre-production |\n| Final | Yes | Release branch | Major / Minor / Patch | Production |\n\n### Branching Strategy\nBased off of the release version and expectations, the version phase's branching strategy can be determined. \n * Alpha and Beta versions are experimental, and therefore exist only on the `main` branch, where all our changes reside\n * Alpha versions are never released. They signify that development is underway, though the changes they contain have not been released in any form\n * A Release Candidate (RC) version denotes a more stable state. A release branch will be created for RC releases to limit the changes a release contains\n * Final versions are stable and tested. Only verified changes will go into these releases, which are inherited from the corresponding RC version\n * A release branch will exist for each unique major or minor version, to be named accordingly: `<major>.<minor>.latest` (e.g. `1.0.latest`)\n    * This is keeping with our current stratgey that we use today.\n    * The reasoning for this decision is largely based off of not wanting to break the current adapters CI workflows and needing to redesign these as well. With patch versions of adapters and `dbt-core` needing to be compatible, testing off of a single minor version branch is much simpler. \n    * Making this current decision does not back us into a corner if we would like to revisit this again in the future. The release workflows created will be able to run on a branch that is version specific or not which makes this flexible as we test out our new processes.\n    \n\n ![Branching Strategy](images/ReleasingBranchStrategy.png)\n\n### Changes for Specific Release Versions\nThere will be times that we will want to target changes to go into specific release versions. Below outlines 2 different scenarios in which this can occur and how we will approach them.\n\n1. If a release branch already exists: This is the most common scenario where we want to add a change to an upcoming release and the release branch has already been cut. In this instance, developers will commit their changes to `main` first. Those changes (or some form of them) will then be applied to the release branch in question so that they can be included in the specific release version. \n\\* Disclaimer: the how and when to apply changes to a release branch will be covered in another upcoming ADR.\n\n1. If a release branch is not yet cut: This is the scenario where we start to develop a feature for a future version before we have cut a release branch for the upcoming version (eg. we want to work on a feature for `1.2.0` but we haven't cut the release branch for `1.1.0` yet). \n    1. Is this dead code? If so, then commiting the changes to `main` is acceptable. There must be 0 risk of users hitting this so if unsure, please use the alternative option.\n    1. Use a feature branch until the release branch is cut. Then when it makes sense, merge the feature branch into `main` and continue development.\n\n   ** Sometimes feature flags are used by teams to also achieve this goal. In our case, feature flags aren't controlled by the team and instead dependent of a user to toggle them on/off. Core uses feature flags instead for offering experimental functionality for users to try and test out. This is different from hiding features from going into certain releases.\n\n## Status\nCompleted\n\n## Consequences\nThis doesn't drastically change our current versioning or branching strategies, but documents our existing flows.\n\nThe only real change here is the addition of an Alpha release, the intent of which is to make developing across multiple repos easier. `dbt-core` and adapters should depend on minor versions. If we don't have a way to keep the `main` branches in sync with one another, integration tests will start to fail. It is also confusing when the `main` branch is marked as an RC or Final version when we never release from `main`. This change provides visibility around which versions live where.\n\n## Outside Scope\nThe following are topics that are outside the scope of this document and will be addressed in their own ADR:\n* Hotfixes and their branching strategies\n* How and why we bump release versions right before a release.\n* How and when do we backport changes to release branches\n"
  },
  {
    "path": "docs/guides/behavior-change-flags.md",
    "content": "# Playbook: Behavior Change Flags\n\nUser documentation: https://docs.getdbt.com/reference/global-configs/legacy-behaviors\n\n## Rules for introducing a new flag\n\n1. **Naming.** All behavior change flags should be named so that their default value changes from **False → True**. This makes it significantly easier for us to document them and talk about them consistently, and it's more intuitive for end users.\n    * (a) If the flag is prohibiting something that we previously allowed, use the verb \"require.\" Examples:\n        * `require_resource_names_without_spaces`\n        * `require_explicit_package_overrides_for_builtin_materializations`\n    * (b) All flags should be of boolean type, and False by default when introduced: `bool = False`.\n2. **Documentation.** Start with the docs. What is the change? Who might be affected? What action will users need to take to mitigate this change? At this point, the dates for flag Introduction + Maturity are \"TBD.\"\n3. **Deprecation warnings**. As a general rule, **all** behavior changes should be accompanied by a deprecation warning.\n    * (a) Always use our standard deprecations module: [https://github.com/dbt-labs/dbt-core/blob/main/core/dbt/deprecations.py](https://github.com/dbt-labs/dbt-core/blob/main/core/dbt/deprecations.py)\n    * (b) This serves two purposes: Signalling the change to the user, and collecting telemetry so we can understand blast radius among users with telemtry enabled.\n    * (c) These warning messages should link back to documentation: [https://docs.getdbt.com/reference/global-configs/legacy-behaviors](https://docs.getdbt.com/reference/global-configs/legacy-behaviors#deprecate_package_materialization_builtin_override)\n    * (d) Even for additive behaviors that are not \"breaking changes,\" there is still an opportunity to signal these changes for users, and to gather an estimate of the impact. E.g. `source_freshness_run_project_hooks` should still include a proactive message any time someone runs the `source freshness` command in a project that has `on-run-*` hooks defined.\n    * (e) The call site for these deprecation warnings should be as close as possible to the place where we’re evaluating conditional logic based on the project flag. Essentially, any time we check the flag value and it returns `False`, we should raise a deprecation warning while preserving the legacy behavior. (In the future, we might be able to streamline more of this boilerplate code.)\n    * (f) If users want to silence these deprecation warnings, they can do so via [`warn_error_options.silence`](https://docs.getdbt.com/reference/global-configs/warnings). Explicitly setting the flag to `False` in `dbt_project.yml` is not sufficient to silence the warning.\n4. **Exceptions.** If the behavior change is to raise an exception that prohibits behavior which was previously permitted (e.g. spaces in model names), the exception message should also link to the docs on legacy behaviors.\n5. **Backports.** Whenever possible, we should backport both the deprecation warning and the flag to the previous version of dbt Core.\n6. **Open a GitHub issue** in the dbt-core repository that is the implementation ticket for switching the default from `false` to `true`. Add the `behavior_change_flag` issue label, and add it to the GitHub milestone for the next minor version. (This is true in most cases, see below for exceptional considerations.) During planning, we will bundle up the \"introduced\" behavior changes into an epic/tasklist that schedules their maturation.\n\n## After introduction\n\n1. **Maturing flag(s) by switching value from `False` → `True` in dbt-core `main`.**\n    * (a) This should land in **the next minor (`1.X.0`) release of dbt-core**.\n    * (b) If the behavior change is mitigating a security vulnerability, and the next minor release is still planned for several months away, we still backport the fix + flag (off by default) to supported OSS versions, and we strongly advise all users to opt into the flag sooner.\n2. **Removing support for legacy behaviors.**\n    * (a) As a general rule, we will not entirely remove support for any legacy behaviors until dbt v2.0. At the same time, we are not committing to supporting them forever (à la Rust editions). We need to strike the right balance between _too fast_ and _never_.\n    * (b) On a case-by-case basis, if there is a strong compelling reason to remove a legacy behavior and we see minimal in-the-wild usage (<1% of relevant projects), we can remove it entirely. This needs to be communicated well in advance — at least 2 minor versions after introduction in dbt Core.\n    * (d) These are project configurations, not temporary feature flags. They add complexity to our codebase; that complexity compounds the more we have, and the longer we have them. Such is the price of maintaining mature v1.* software.\n"
  },
  {
    "path": "docs/guides/parsing-vs-compilation-vs-runtime.md",
    "content": "# Parsing vs. Compilation vs. Runtime\n\n## Context: Why this doc?\n\nThere’s a lot of confusion about what dbt does at parse time vs. compile time / runtime. Even that separation is a relative simplification: parsing includes multiple steps, and while there are some distinctions between \"compiling\" and \"running\" a model, the two are **very** closely related.\n\nIt's come up many times before, and we expect it will keep coming up! A decent number of bug reports in `dbt-core` are actually rooted in a misunderstanding of when configs are resolved, especially when folks are using pre/post hooks, or configs that alter materialization behavior (`partitions`, `merge_exclude_columns`, etc).\n\nSo, here goes.\n\n## What is \"parsing\"?\n\n**In a sentence:** dbt reads all the files in your project, and constructs an internal representation of the project (\"manifest\").\n\nTo keep it really simple, let’s say this happens in two steps: \"Parsing\" and \"Resolving.\"\n\n### Parsing\n\nAs a user, you write models as SQL (or Python!) + YAML. For sake of simplicity, we'll mostly consider SQL models (\"Jinja-SQL\") with additional notes for Python models (\"dbt-py\") as-needed.\n\ndbt wants to understand and define each SQL model as an object in an internal data structure. It also wants to know its dependencies and configuration (= its place in the DAG). dbt reads your code **for that one model,** and attempts to construct that object, raising a **validation** error if it can’t.\n\n<details>\n<summary>(Toggle for many more details.)</summary>\n\n- (Because your SQL and YAML live in separate files, this is actually two steps. But for things like `sources`, `exposures`, `metrics`, `tests`, it’s a single pass.)\n- dbt needs to capture and store two vital pieces of information: **dependencies** and **configuration**.\n    - We need to know the shape of the DAG. This includes which models are disabled. It also includes dependency relationships between models.\n    - Plus, certain configurations have implications for **node selection**, which supports selecting models using the `tag:` and `config:` methods.\n- Parsing also resolves the configuration for that model, based on configs set in `dbt_project.yml`, and macros like `generate_schema_name`. (These are \"special\" macros, whose results are saved at parse time!)\n- The way dbt parses models depends on the language that model is written in.\n    - dbt-py models are statically analyzed using the Python AST.\n    - Simple Jinja-SQL models (using just `ref()`, `source()`, &/or `config()` with literal inputs) are also [statically analyzed](https://docs.getdbt.com/reference/parsing#static-parser), using [a thing we built](https://github.com/dbt-labs/dbt-extractor). This is **very** fast (~0.3 ms).\n    - More complex Jinja-SQL models are parsed by actually rendering the Jinja, and \"capturing\" any instances of `ref()`, `source()`, &/or `config()`. This is kinda slow, but it’s more capable than our static parser. Those macros can receive `set` variables, or call other macros in turn, and we can still capture the right results because **we’re actually using real Jinja to render it.**\n        - We capture any other macros called in `depends_on.macros`. This enables us to do clever things later on, such as select models downstream of changed macros (`state:modified.macros`).\n        - **However:** If `ref()` is nested inside a conditional block that is false at parse time (e.g. `{% if execute %}`), we will miss capturing that macro call then. If the same conditional block resolves to true at runtime, we’re screwed! So [we have a runtime check](https://github.com/dbt-labs/dbt-core/blob/16f529e1d4e067bdbb6a659a622bead442f24b4e/core/dbt/context/providers.py#L495-L500) to validate that any `ref()` we see again at compile/runtime, is one we also previously captured at parse time. If we find a new `ref()` we weren’t expecting, there’s a risk that we’re running the DAG out of order!\n\n</details>\n\n### Resolving\n\nAfter we’ve parsed all the objects in a project, we need to resolve the links between them. This is when we look up all the `ref()`, `source()`, `metric()`, and `doc()` calls that we captured during parsing.\n\nThis is the first step of (almost) every dbt command! When it's done, we have the **Manifest**.\n\n<details>\n<summary>(Toggle for many more details.)</summary>\n\n- If we find another node matching the lookup, we add it to the first node’s `depends_on.nodes`.\n- If we don’t find an enabled node matching the lookup, we raise an error.\n    - (This is sometimes a failure mode for partial parsing, where we missed re-parsing a particular changed file/node, and it appears as though the node is missing when it clearly isn’t.)\n- Corollary: During the initial parse (previous step), we’re not actually ready to look up `ref()`, `source()`, etc. But during that first Jinja render, we still want them to return a `Relation` object, to avoid type errors if users are writing custom code that expects to operate on a `Relation`. (Otherwise, we’d see all sorts of errors like \"NoneType has no attribute \"identifier.\") So, during parsing, we just have `ref()` and `source()` return a placeholder `Relation` pointing to the model currently being parsed. This can lead to some odd behavior, such as in [this recent issue](https://github.com/dbt-labs/dbt-core/issues/6382).\n\n</details>\n\n## What is \"execution\"?\n\n**In a sentence:** Now that dbt knows about all the stuff in your project, it can perform operations on top of it.\n\nThings it can do:\n\n- tell you about all the models that match certain criteria (`list`)\n- compile + run a set of models, in DAG order\n- interactively compile / preview some Jinja-SQL, that includes calls to macros or ref’s models defined in your project\n\nDepending on what’s involved, these operations may or may not require a live database connection. While executing, dbt produces metadata, which it returns as **log events** and **artifacts**.\n\nPut another way, dbt’s execution has required inputs, expected outputs, and the possibility for side effects:\n\n- **Inputs** (provided by user): project files, credentials, configuration → Manifest + runtime configuration\n- **Outputs** (returned to user): logs & artifacts\n- **Side effects** (not seen directly by user): changes in database state, depending on the operation being performed\n\n### Compiling a model\n\nWe use the word \"compiling\" in a way that’s confusing for most software engineers (and many other people). Most of what’s described above, parsing + validating + constructing a Manifest (internal representation), falls more squarely in the traditional role of a language compiler. By contrast, when we talk about \"compiling SQL,\" we’re really talking about something that happens at **runtime**.\n\nDevils in the details; toggle away.\n\n<details>\n<summary>The mechanism of \"compilation\" varies by model language.</summary>\n\n- **Jinja-SQL** wants to compile down to \"vanilla\" SQL, appropriate for this database, where any calls to `ref('something')` have been replaced with `database.schema.something`.\n- dbt doesn’t directly modify or rewrite user-provided **dbt-py** code at all. Instead, \"compilation\" looks like code generation: appending more methods that allow calls to `dbt.ref()`, `dbt.source()`, and `dbt.config.get()` to return the correct results at runtime.\n\n</details>\n\n<details>\n<summary>If your model’s code uses a dynamic query to template code, this requires a database connection.</summary>\n\n- At this point, [`execute`](https://docs.getdbt.com/reference/dbt-jinja-functions/execute) is set to `True`.\n- e.g. `dbt_utils.get_column_values`, `dbt_utils.star`\n- Jinja-SQL supports this sort of dynamic templating. dbt-py does not; there are other imperative ways to do this, using DataFrame methods / the Python interpreter at runtime.\n\n</details>\n\n<details>\n<summary>Compilation is also when ephemeral model CTEs are interpolated into the models that `ref` them.</summary>\n\n- The code for this is *gnarly*. That’s all I’m going to say about it for now.\n\n</details>\n\n<details>\n<summary>When compiling happens for a given node varies by command.</summary>\n\n- For example, if one model’s templated SQL depends on an introspective query that expects another model to have already been materialized, this can lead to errors.\n- In `dbt run`, models are operated on in DAG order, where operating on one model means compiling it and then running its materialization. This way, if a downstream model’s compiled SQL will depend on an introspective query against the materialized results of an upstream model, we wait to compile it until the upstream model has completely finishing running.\n\n</details>\n\n</br>\n\nThe outcome of compiling a model is updating its Manifest entry in two important ways:\n- `compiled` is set to `True`\n- `compiled_code` is populated with (what else) the compiled code for this model\n\n### Running / materializing a model\n\nA model’s `compiled_code` is passed into the materialization macro, and the materialization macro is executed. That materialization macro will also call user-provided pre- and post-hooks, and other built-in macros that return the appropriate DDL + DML statements (`create`, `alter`, `merge`, etc.)\n\n(For legacy reasons, `compiled_code` is also available as a context variable named [`sql`](https://github.com/dbt-labs/dbt-core/blob/16f529e1d4e067bdbb6a659a622bead442f24b4e/core/dbt/context/providers.py#L1314-L1323). You'll see it referenced as `sql` in some materializations. Going forward, `model['compiled_code']` is a better way to access this.)\n\n## Why does it matter?\n\nKeeping these pieces of logic separate is one of the most important & opinionated abstractions offered by dbt.\n\n- **The separation of \"control plane\" logic** (configurations & shape of the DAG) **from \"data plane\" logic** (how data should be manipulated & transformed remotely).\n    - You must declare all dependencies & configurations ahead of time, rather than imperatively redefining them at runtime. You cannot dynamically redefine the DAG on the basis of a query result.\n    - This is limiting for some advanced use cases, but it prevents you from solving hard problems in exactly the wrong ways.\n- **The separation of modeling code** (\"logical\" transformation written in SQL, or DataFrame manipulations) **from materialization code** (\"physical\" state changes via DDL/DML)**.**\n    - Every model is \"just\" a `select` statement (for Jinja-SQL models), or a Python DataFrame (for dbt-py models). It can be developed, previewed, and tested as such, *without* mutating database state. Those mutations are defined declaratively, with reusable boilerplate (\"view\" vs. \"table\" vs. \"incremental\"), rather than imperatively each time.\n\n\n## Appendix\n\n<details>\n<summary>Click to toggle notes on parsing</summary>\n\n### Notes on parsing\n\n- **dbt has not yet connected to a database.** Every step performed thus far has required only project files, configuration, and `dbt-core`. You can perform parsing without an Internet connection.\n- There is a command called `parse`, which does **just** \"parsing\" + \"resolving,\" as a way to measure parsing performance in large projects. That command is the fastest way to write `manifest.json` (since v1.5).\n- In large projects, the parsing step can also be quite slow: reading lots of files, doing lots of dataclass validation, creating lots of links between lots of nodes. (See below for details on two potential optimizations.)\n\n### Two potential optimizations\n\n1. [**\"Partial parsing.\"**](https://docs.getdbt.com/reference/parsing#partial-parsing) dbt saves the mostly-done Manifest from last time, in a file called `target/partial_parse.msgpack`. dbt **just** reads the files that have changed (based on file system metadata), and makes partial updates to that mostly-done Manifest. Of course, if a user has updated configuration that could be relevant globally (e.g. `dbt_project.yml`, `--vars`), we have to opt for a full re-parse — better safe (slow & correct) than sorry (fast & incorrect).\n2. [**\"Reusing manifests.\"**](https://docs.getdbt.com/reference/programmatic-invocations#reusing-objects) Note that this is taking \"full control,\" and there are failure modes (example: [dbt-core#7945](https://github.com/dbt-labs/dbt-core/issues/7945)).\n\n</details>\n"
  },
  {
    "path": "docs/roadmap/2022-05-dbt-a-core-story.md",
    "content": "# Let's talk about dbt\n\nAny writer, any artist, who finds themselves doing work that invites [thoughtful, clear, forward-looking](https://thecreativeindependent.com/people/doreen-st-felix-on-entering-the-world-of-criticism) criticism should be counted lucky. As a person who builds dbt Core for a living, I feel lucky to have [Pedram](https://pedram.substack.com/p/we-need-to-talk-about-dbt). He's a person who understands exactly what dbt is, and who cares deeply about its future.\n\nIt's possible that we're not building the right things. It's certain that we're not doing a good enough job of communicating what we're building. How can we expect to know the former without doing the latter? In the end, [transparency always wins](https://www.getdbt.com/dbt-labs/values/#:~:text=Transparency%20always%20wins.).\n\n### What is this doc?\n\nThis is my story of dbt Core in 2022: everything we're trying to build, and why.\n\nThis Markdown table is your `tl;dr`. The rest is commentary.\n\n| Version | When | Stuff | Confidence* |\n|-----|----------|----------------------------------------------------------------------------------|------------|\n| 1.1 ✅ | April | Testing framework for dbt-core + adapters. Tools and processes for sustainable OSS maintenance tools. | 100% |\n| 1.2 | July | Refactoring core materializations (especially incremental). Built-in support for grants. \"Cross-db\" macros in dbt-core + plugins. Python-language models (beta). | 95% |\n| 1.3 | October | Python-language models. Built-in support for UDFs. Exposures / external nodes. | 80% |\n| 1.4 | Jan 2023 | Mechanisms for cross-project lineage (namespacing). Performance tune-up. Start incorporating SQL grammar (linting & lineage). | 50% |\n\n`updated_at: 2022-04-12`\n\n**\\*Confidence?** I mean the certainty of which things we build for which release. dbt Core is relied on by many. The most important things stay the same, but some of the details vary. When looking 6+ months into the future, I expect us to do ~half of the things I've listed above and below, and shuffle ~half of them out in favor of the things that you will be telling us we need to build.\n\n### Why this doc?\n\nA product philosophy of dbt, taking inspiration [from Perl](https://www.amazon.com/gp/feature.html?ie=UTF8&docId=7137#:~:text=%22Easy%20things%20should%20be%20easy%2C%20and%20hard%20things%20should%20be%20possible.%22): **\"Make the easy things easy, and the hard things possible.\"**\n\nThe analyst in you probably has some questions:\n- Which things? The entire analytics engineering workflow?\n- What ought to be easy? What deserves to be hard?\n- Who's making them, and when?\n\nI haven't been doing a good enough job of answering those questions, in a single easy-to-bookmark place. I don't do my long-form writing in a personal blog, I do it [in a GitHub repo](https://github.com/dbt-labs/dbt-core/issues?q=is%3Aissue+is%3Aopen+commenter%3Ajtcohen6+), and trawling through issues is a leisure activity enjoyed by precious few.\n\ndbt Core is a product, sort of; a CLI tool, for many; a software project, for sure; an open source project, definitively; but above all it's a guide, a set of opinionated practices about how you should do this work of data transformation, testing, documentation. We believe these are many (not all) of the essential components of the thing we call analytics engineering, which maybe you just call getting your job done. If you're reading this, even if you don't pay to use dbt, you've more than likely invested in it a meaningful quantity of your time, care, and attention—not to mention, your business logic. It matters a lot to me that you know how we're thinking about dbt's ongoing development. (That also means that the story I can tell in this document is necessarily incomplete: I can tell you what dbt Core can do for you, but just as important is [what you and other skilled practitioners can do with dbt Core](https://docs.getdbt.com/blog).)\n\nThat is to say, _mea culpa_. The best time to have written this document was a few months ago; the second best time, I hope, is right now.\n\n### Where are we now?\n\ndbt is a workflow tool. It was originally built by a team of full-time analytics consultants (us). We built it because there were jobs to be done, literally, and dbt made us unreasonably effective at doing them. As a fresh-faced Data Analyst, with a seat in the engine room (the only room there was), I was able to deliver high-quality work to clients ahead of schedule, [and go home early](https://www.getdbt.com/dbt-labs/values/#:~:text=We%20work%20hard%20and%20go%20home.) (or to the beach).\n\nThe people who built dbt had the same names, faces, and hand gestures as the people who used it every day. That was our blessing and our curse. Each time we found a new idiosyncrasy in analytical databases, we coded it into dbt. Late-bound views on Redshift? Always. Quoted identifiers on Snowflake? Never. These turned into magic incantations, whose full meaning could only be revealed, slowly, through immersion in our shared ritual practice. To the uninitiated, the curly-braced characters of the incremental materialization may more resemble cuneiform than Python.\n\nAs an end user, `dbt-core` felt like a magical experience, even as it grew to be an indecipherable mess of a codebase. Logging was random. Metadata was at once invaluable and totally undocumented. Our automated testing and release processes were \"prayers up\" undertakings. This makes sense for where our priorities were. It also meant that, at the start of 2021, two things were true:\n1. `dbt parse` was really, really freaking slow for any project with more than 500 models in it.\n2. dbt Core was major-version-zero software, a fundamentally unstable substratum, used in production by thousands of people.\n\nThose were our two top priorities in 2021. Speed up dbt-core parsing, especially in development. Work up to v1.0, and release it. We made steady progress on both of those, not without some public pains along the way. There were moments when I, like Phoebe, wondered if we'd make it through December. We did. [Read all about it, featuring a dorky picture of me, and my genuine gratitude to all the colleagues and community members who made it happen](https://www.getdbt.com/blog/dbt-core-v1-is-here/).\n\nThose were two big accomplishments. (We also grew the team of people working full-time on dbt Core from three to eight.) That doesn't mean we're done developing Core, though—not even close. I reprised the exercise. At the start of 2022, three things were true:\n1. **There are easy things we need to make easy, and one hard thing we need to make possible.** Users of dbt are still totally constrained to what they can write in SQL (or Jinja-SQL). At the same time, there's still too many things that, while doable, require lots of insider knowledge, custom code, or magic incantations. dbt Core needs some **new constructs,** a mix of totally-new and just-plain-easier things.\n2. **dbt-core is still missing the right modular interfaces for long-term development.** This is a codebase that grew organically over time. Its layout today is _much_ more sensible than it was a year ago, but we're not all the way there. The tight couplings, of tasks with configs with CLI initialization, tax our ability to build next-level capabilities with confidence, including all the stuff in (1). Not just that: it prevents community members and technology partners from building truly next-level integrations. dbt Core needs some **new interfaces.**\n3. **And yet: dbt Core is major-version-one software.** There are commitments to backwards compatibility and ease of upgrade that we take incredibly seriously. This is a necessary constraint that's always top-of-mind for us when building the new (1) and refactoring the old (2).\n\nI believe those three concerns are and remain relevant for every user of dbt. There are going to be specific things we build along the way that might be less relevant for you as an individual—support for other databases, if you happily use Redshift/Snowflake/BigQuery; support for large projects, if you're at a happy medium; better programmatic interfaces, if you need only to invoke dbt from the CLI—but they all weave together into the larger story we're telling this year.\n\nThere's inevitably some \"inside dbt-ball\" in this document. It can't just be a list of user-facing features we're shipping, or I wouldn't be doing the story justice. We're here to take big swings, the kinds of things I get excited about demo'ing at Staging and Coalesce—but we're also here to maintain critical infrastructure, to grow a roster of talented position players who can put in a solid nine innings day after day. So this will also discuss some behind-the-scenes work we're doing, and the people who rely on it.\n\nIt's true that many of the people now building dbt aren't themselves users of it—they're talented software engineers who know the things we need to do to scale large, performant, maintainable codebases. It's my job, and the job of my long-time colleagues, to ensure that dbt continues to feel dbtonic along the way.\n\n# Program for the 2022 season\n\nWelcome to the official program for \"dbt: A Core Story,\" the devised theatre piece where everyone has a part to play. First, a few housekeeping items.\n\nWe'll be releasing a new minor version of dbt Core every 3 months: April, July, August, January (2023). We put out our new [adapter](https://docs.getdbt.com/docs/available-adapters) versions at the same time. Adapters maintained by other people might be available for upgrade a few weeks later. For each new minor version, we put up a [\"migration guide\"](https://docs.getdbt.com/docs/guides/migration-guide) in the docs.\n\nEverything we work on is public on GitHub. I attach issues to [milestones](https://github.com/dbt-labs/dbt-core/milestones) for upcoming releases. We're using [discussions](https://github.com/dbt-labs/dbt-core/discussions) now for bigger-picture conversations—stuff we're thinking about, even if we can't write the code for it right away. If the dbt Community Slack feels overwhelming, discussions still feel, for now, like a slower-paced forum for dreaming up ideas, talking through caveats and rough edges. I really welcome your voices there.\n\nAs for this document: Each quarter, I'll swing back and update it, with the edits preserved in git. If you see something you don't like, you'll know whom to `blame`.\n\n## Act I: Sharpening our tools (January–April)\n\n### Scene 1: Rewrite the way we test dbt-core and adapters\n\nThis probably isn't news to you: dbt-Jinja code is pretty hard to test. I'm not talking about tests for data quality, but tests of \"application code,\" in the sense of making sure that the incremental materialization is doing the right thing in the right circumstances. We've been feeling the pain here, too—it's really hurt our ability to onboard new engineers to the team, and ship features quickly and confidently. It's also hurt our ability to help the people who, whether for their job or with the generosity of their free time, maintain the adapter plugins that let dbt talk to dozens of databases. As core maintainers, we owed them a lot more than we could give them.\n\nSo, we wrote a new testing framework, based in `pytest`, that's much easier to extend and debug. Who benefits? Concretely, these automated tests offer us a way to stamp our approval on adapter plugins developed and maintained outside dbt Labs, while ensuring a consistent baseline experience, whichever adapter you use. I think everyone who wants healthy competition between database vendors, and to know that you can have the same magical experience of using dbt across them. Ask your neighborhood adapter maintainer if the new testing framework is working well for them.\n\nIs the new `pytest`-based framework actually the dbt feature called \"unit testing\" in disguise? Funny you asked—no, but I do think it's a step on the way there. It's possible to use this functional testing framework to quickly spin up \"projects,\" with fixture inputs and outputs, that check the behavior of a macro. We can test that macro for consistency across many databases. (Check this out in that most complex project of them all, [`dbt_utils`](https://github.com/dbt-labs/dbt-utils/pull/588).) The dream is indeed to expose a dbt-code-only version of this workflow, along the lines of what people have been cooking up in https://github.com/dbt-labs/dbt-core/discussions/4455.\n\n(We also intentionally built this in a way that avoids locking us into Jinja-y code forever. Jinja is a tool, just like Python. It gets us a lot right now. There will come a time when it's no longer the right fit, and we'll need to be ready to move away from it.)\n\n### Scene 2: Sustainable maintainership\n\nSince December, we've added three new folks to the team. There's 10 of us now! You may have seen some newer names, if you're used to hanging around our GitHub: @leahwicz @gshank @nathaniel-may @iknox-fa @emmyoop @McKnight-42 @VersusFacit @ChenyuLInx @stu-k\n\nThat growth was in parallel to the growth of `dbt-core` active users, and the growth of issues in the `dbt-core` repo. We get 2 or 3 new open source issues every calendar day. When it was just me responding, I would take a week of vacation, and come back to a stack of a dozen or more.\n\nAt the same time, I was learning a **ton** about dbt—what it is today, what it should be—by reading and responding to all your issues. That's invaluable stuff for the people building dbt, and it's stuff that was all living in my head only.\n\nSo, for both reasons, I've been sharing the load with the engineering team building dbt Core. This requires more time, and process, but it also requires a level of rigor and organization that I didn't have when it was just me. Bugs don't get lost in the shuffle, and get resolved more quickly.\n\nIs this groundbreaking stuff? No, but it is major-version-one stuff. Is every one of these issues game-changing? No, but they matter a lot to the person who opens them—and I believe it matters a lot to you, a person who has invested meaningfully in standardizing on dbt Core. You should want to know that that core dbt functionality is well maintained, to know that when you run into a bug or have an idea there will be a human on the other end to receive and respond to it. To that end, I want to share a new doc we put together over the past few months: [Expectations for OSS Contributors](https://docs.getdbt.com/docs/contributing/oss-expectations).\n\nIt took some doing, but we now live in a world where:\n- every issue gets a timely response\n- every community PR gets code review (with easier code checks! and conflict-free changlog entries!)\n- they're not all (or even mostly) from Drew or me\n\nI care about making contribution accessible, and making dbt a thing we can keep building together. I care a lot about what you have to say and think about feel about dbt. I still read every new issue, even if it's not me who responds. Maybe I'll stop, someday. But for now I read them all.\n\n### Scene 3: v1.1 (Gloria Casarez)\n\nAt the end of April, [we released v1.1](https://github.com/dbt-labs/dbt-core/releases/tag/v1.1.0), named for Gloria Casarez, the activist and advocate for the rights of LGBTQ+ people in Philadelphia. This release had [some good stuff in it](https://docs.getdbt.com/docs/guides/migration-guide/upgrading-to-v1.1), including a few boundary-pushing community contributions—but I'll be the first to admit that it was a lighter release than others in recent memory. The biggest work was sharpening our tools, and sharpening the team. We'd rather do this work upfront, so we can build and ship the bigger stuff, with alacrity and assurance.\n\n## Act II: Ergonomic interfaces (May–July)\n\nThis is where we are now. There are three big focus areas for the Core team in these three months. Two of them are user-facing, and one of them is software-facing. This is work we've just kicked off, and if you choose to look closely, you can see the full flurry of issues and PRs flying around.\n\n### Scene 1: \"Adapter ergonomics\"\n\nFor the full story, and to leave your thoughts, check out the discussion: https://github.com/dbt-labs/dbt-core/discussions/5091. Meanwhile, I'll give the quick & dirty version.\n\n**First, grants.** These have been, [in Tristan's words](https://roundup.getdbt.com/p/the-response-you-deserve), \"super-budget literally forever.\" Database permissions matter; they're an easy thing, and yet dbt makes them hard. I've lost track of the number of issues (but linked to many of them in https://github.com/dbt-labs/dbt-core/issues/5090) where users have run into bad experiences with `pre-hook` and `post-hook`, which are [rendered a little bit differently](https://docs.getdbt.com/docs/building-a-dbt-project/dont-nest-your-curlies), in ways that can be very useful and very confusing. Honestly, we want to move hooks into the category of \"advanced functionality\"—use only if you must!—but we can't do that while `grants` remain hooked on hooks.\n\nThere's another reason to do this work now: BigQuery added support for DCL statements [last summer](https://cloud.google.com/bigquery/docs/release-notes#June_28_2021). Databricks has built a [brand-new unity catalog](https://databricks.com/product/unity-catalog). Many warehouses are adding more-complex permissions—dynamic data masking, role-based access policies on rows and columns. If dbt can be a forcing function for baseline consistency among data warehouse vendors—make the easy stuff easy—it provides a foundation, and clears human brain space, for the trickier case-dependent capabilities.\n\n**Second, materializations:** specifically, the 'incremental' materialization, and the sorta-real thing that is \"incremental strategy\" on a handful of adapters. These are powerful, complex, misunderstood. We need more sensible code, more sensible docs. Lots of people (adapters, users) want to customize or contribute to materialization logic. It's really tricky to write today, in ways that go beyond the standard (fair) complaints about macros. Our functional testing framework helps here, by giving us the ability to define the superset of behaviors in `dbt-core`, and to let each adapter or user opt into and fine-tune the ones they wish to support.\n\n**Third, `dbt-utils`**, which is getting unsustainably big. As part of [the work of splitting it up](https://github.com/dbt-labs/dbt-utils/discussions/487), we decided that its lowest-level building blocks—the \"cross-db\" macros so useful to authors of other packages—really belong in `dbt-core` and plugins. This is an opportunity for us to continue expanding the \"dbt-SQL\" language, such as it exists today, for the benefit of the package maintainers who contribute so much to our ecosystem.\n\n**The v1.2 release** will include all of the above, with a beta prerelease in June, and a final releaes to arrive in mid-July. What else? v1.2 will also to include [support for ratio metrics](https://github.com/dbt-labs/dbt-core/issues/4884), to power dbt's rapidly iterating semantic layer. Last and never least, it will include the dozen or so capabilities for which community members have taken the initiative to contribute. (Fun fact: thanks to our new `changie`-powered changelog, you can always catch a glimpse of [upcoming changes](https://github.com/dbt-labs/dbt-core/tree/main/.changes/unreleased), merged but not yet released.)\n\n### Scene 2: Modular programmatic interfaces\n\nIf you've hung around the `dbt-core` GitHub repo lately, you may have seen that we've started tagging a lot of issues with `tech_debt`, as well as with `Team:Language`, `Team:Execution`, `Team:Adapters`.\n\nNot long ago, we had one team (one person), one codebase, one tightly coupled application that did all of the things, from beginning to end, without clear stopping points in the middle. Now, I'm truly lucky to work with a team of talented software engineers, as we try to make the experience of developing and interfacing with `dbt-core` as no-bs as it is to use. We believe the highest-leverage way to do this is by splitting up the team into specialties, and the codebase into modular interfaces.\n\nFor too long now, the [docs for dbt's \"Python API\"](https://docs.getdbt.com/docs/running-a-dbt-project/dbt-api) have cautioned:\n\n> It _is_ possible to import and invoke dbt as a Python module. This API is still not contracted or documented, and it is liable to change in future versions of `dbt-core` without warning. Please use caution when upgrading across versions of dbt if you choose to run dbt in this manner!\n\nThere are two big parts of this initiative that I'm hoping to tackle in July, after we've readied v1.2 for prerelease testing:\n1. Decouple the CLI from the `dbt-core` \"library.\" Support actual programmatic interfaces into initialization and tasks. Unbundle the massive blobs of config that get passed around during initialization today.\n2. **Structured logging**, as the future of (real time) dbt metadata. In v1.0, we replaced all our \"legacy\" logging with a real event system and structured interface. We need to extend that system to handle errors/exceptions, too—a pain to debug when dbt spits back no or little information—and we need to add much more logging than we have today. There's so much more valuable information that dbt collects _while_ it runs, which we want to expose for you and everyone else. (Think: model table statistics _during_ `dbt run`, not just after `docs generate`.) Eventually, we see these logs eclipsing `manifest.json`—which doesn't go away, exactly, but is no longer the one (giant) file that answers every question about a dbt project.\n\nThese things don't pay dividends as quickly as user-facing functionality, but we believe they more than pay for themselves in the long run. Here are the three ways I can think of:\n1. Better interfaces makes us faster at onboarding new engineers to the Core team, and building new features in dbt Core.\n2. External contributors (you!) can contribute code to `dbt-core` more easily: to find the right module, the right interfaces to extend, and fewer pitfalls that sap enthusiasm while doing it.\n3. It's easier to build other tools on top of dbt Core. That includes dbt Cloud—which, candidly, has been hamstrung in its ability to develop differentiated experiences by the lack of reliable interfaces in Core. But it also includes way-cool tools, such as [`sqlfluff`](https://github.com/sqlfluff/sqlfluff) and [`fal`](https://github.com/fal-ai/fal), that already hook into `dbt-core`'s officially undocumented Python interface. Let's make that the practice, not the anti-pattern.\n\n### Scene 3: Python-language dbt models\n\n(!!)\n\nSorry to bury the lede for this one. This is shaping up to be the groundbreaking new entrant in the Core roadmap in 2022. If do our job well, we'll have made a hard thing possible; if we do it very well, we might just manage to make it feel easy.\n\nOver the past few weeks, I've been drafting thoughts for a forthcoming discussion, and Core engineers have been playing around with a little bit of experimental code. We're hoping to have something that's beta-ready by July. I'll have more to say about this next week, including my personal take on le grand débat of SQL ~versus~ and Python.\n\nFor now, here's a taste:\n\n```python\ndef model(dbt):\n\n    # look familiar?\n    dbt.config(\n        materialized='table',\n    )\n\n    # this knows about the DAG\n    upstream_model = dbt.ref(\"upstream_model\")\n    upstream_source = dbt.source(\"upstream\", \"source\")\n\n    # dataframe-style transformations\n    sample = upstream_model.where(col(\"city\")==\"Philly\")\n    ...\n\n    # this too\n    import numpy as np\n    ...\n    \n    # your final 'select' statement\n    df = ...\n\n    # return a dataset, just like SQL — dbt takes care of the rest\n    return df\n```\n\nOnce the beta is available, we'll want to hear everyone's thoughts. Our plan is to incorporate your thoughts, ideas, and feedback, as well as some complementary features we have in mind, as we build toward...\n\n## Act III: Unified Lineage (August–October)\n\nv1.3 takes us to Coalesce, where I might just manage to meet (some of) you in person for the very first time.\n\nThe theme of this release will be **unifying lineage.** We're pulling some new pieces of transformation logic into dbt's execution model, and offering more ways to push the rich metadata from your project out into the world.\n\nThings like:\n- Python-language dbt models, ready for production\n- Native support for UDFs (https://github.com/dbt-labs/dbt-core/issues/136: an oldie, a goodie, and newly relevant!)\n- Improvements to exposures, and external nodes, and maybe those are actually the same thing? (https://github.com/dbt-labs/dbt-core/discussions/5073)\n\nWhat else? 'Tis not so sweet now as it was before? I think there will be lots to discuss, some to debate, things to try out, a few to throw away, and maybe just maybe we'll find ourselves with an expanded standard, a thing we're proud to still call dbt Core.\n\nThoughts? For my part, I think **unit testing** model code becomes an even more pressing question when:\n- dbt models can be written in Python, a language that _wants_ to be unit-tested even more than SQL\n- dbt nodes (models?) can return _functions_, with testable inputs and outputs\n- dbt can be interacting with external services that live outside the database\n\nI rest well knowing we'll be better equipped to solve that problem, using all that we learn about Python-language models, and the components of the `pytest` framework that we put together in the first few months of the year.\n\nOf course, all of that will be in addition to the ongoing work that we're doing around metrics and the semantic layer, first previewed at last year's Coalesce. It's not my place to spoil any of the surprises there.\n\n## Act IV: Reflect and reinvest (November–January)\n\nv1.3 takes us through Coalesce, which is always a bit of an event horizon for the Product team at dbt Labs. Looking further than six months away, I'm only ~50% certain about which initiatives we'll be tackling into the new year. For now, I can share the ones that feel most important to me:\n\n**Better mechanisms for cross-project lineage** (https://github.com/dbt-labs/dbt-core/discussions/5244), to support large projects that should really be multiple projects. That would include support for namespaced models, at least in different packages. This is an initiative I care about a lot, and I'm trying to push up earlier if possible.\n\n**Building a SQL grammar**, or build compelling features on top of another open source one. Catch syntax errors at parse time, lint code, auto-format. Also, detect column-level lineage. This gets complicated, because of how some dbt models are templated dynamically, but I trust that we'll be able to find reasonable compromises when people are doing more-complex things to template model SQL.\n\n**Revisiting performance.** It will have been 2 years since we first began performance work in earnest, in November 2020. Then, we had the goal of speeding up dbt startup by 100x. Now, we should see where the bottlenecks are—I sense they're around database caching and cataloging. Then, we chose to write some low-lying parts of dbt-core in Rust, instead of Python. Now, with more clearly defined interfaces, it might make sense to rewrite some parts again.\n\n## Epilogue: What's missing?\n\nIt's not all accounted for above. There are many important things we won't be able to build. I can name a few; I'm sure you have more than these, and I want to hear them.\n\n**Meaningfully rebuilding, rewriting, or reinvesting in the `dbt-docs` site.** We're going to keep this up & running, and we'll review community PRs—but we haven't built a team of Angular (!) engineers. The fact that `dbt-core` ships with an auto-generated documentation site is essential; the next-level version of this thing needs to be built on a more powerful engine than a static site reading JSON files.\n\n**DRYer configuration.** YAML reuse. Macros in `.yml` files. Vars of vars, and docs blocks on docs blocks. Why not solve it sooner? I think column-level lineage has a part to play here; anything we build before then risks emphasizing the wrong details. But I appreciate the real frustrations around config duplication and code generation in the meantime. dbt can be verbose, not unlike yours truly.\n\n**Native plugins for VS Code, PyCharm, Vim, ...**—I know. I want these things _very_ badly. I think the role of the Core team, first and foremost, is to solidify and harden the programmatic interfaces that I mentioned above. There's no sense building a thing on a rocky (let alone undocumented) foundation. This is also the best way for us to expand our reach: by enabling our colleagues, yes, and also partners, and also every member of the community with a hack day, to build better and cooler stuff, and build it with confidence. It's the kindness of strangers, and then some—it's open source.\n\n**What about `<issue that's been open since ...>`?** Tell me which one, and I'll give it another read. I'm `@jerco` in dbt Community Slack.\n"
  },
  {
    "path": "docs/roadmap/2022-08-back-for-more.md",
    "content": "# dbt Core: Back for more (August 2022)\n\nMe again! As promised, three months later. Since I wrote to you in May, a few things have happened:\n\n- We released a new final version of dbt Core (v1.2)\n- We put out a beta of the next version (v1.3)\n- Two new colleagues on the Product team, Cody and Florian, joined me in imagining the future of dbt Core\n\nThis update is going to be a touch shorter, as we have many fewer surprises to share. That's a good thing. We've been talking more in public about what we're building: on [the blog](https://www.getdbt.com/blog/), on [the other (cooler) blog](https://docs.getdbt.com/blog), at [Staging](https://www.getdbt.com/blog/staging-highlights-the-latest-from-dbt-labs/), and in [GitHub discussions](https://github.com/dbt-labs/dbt-core/discussions). And, while the meta conceit was good once (\"welcome to my mind, it's an improvised play in four acts, how's that for stream[-of-consciousness] transformation\"), I don't want to risk overdoing it.\n\nHere's what you came for:\n\n| Version | When          | Namesake<sup>a</sup>      | Stuff | Confidence<sup>b</sup>  |\n| ------- | ------------- | -------------- | ----- | ------------ |\n| 1.1 ✅   | April        | Gloria Casarez | Testing framework for dbt-core + adapters. Tools and processes for sustainable OSS maintenance. | 100% |\n| 1.2 ✅   | July         | Henry George   | Built-in support for grants. Migrate cross-db macros into dbt-core / adapters. Improvements to metrics. | 100% |\n| 1.3 🌀   | October      |                | Python models in dbt. More improvements to metrics. (Other things, too—but those are the main events.) | 95% |\n| 1.4 ⚒️    | Jan 2023     |                | Behind-the-scenes improvements to technical interfaces. A real, documented Python API/library, with an improved CLI to wrap it. Further investments in structured logging. | 80% |\n| 1.5+ 💡  | Next year<sup>c</sup> |                | Multi-project deployments: split up the monolith. The same DAG, more active: external orchestration. Python in dbt: next steps. Start imagining dbt Core v2. | 50% |\n\n`updated_at: 2022-08-31`\n\n<sup>a</sup>Always a [phamous Philadelphian](https://en.wikipedia.org/wiki/List_of_people_from_Philadelphia), true to our roots. If you have ideas or recommendations for future version namesakes, my DMs are open :)\n\n<sup>b</sup>dbt Core is, increasingly, a standard-bearer and direction-setter. We need to tell you about the things we're thinking about, long in advance of actually building them, because it has real impacts for the plans of data teams and the roadmaps of other tools in the ecosystem. We also know that we don't know now everything we will know a year from now. As new things come up, as you tell us which ones are important to you, we reserve the right to pivot. So we'll keep sharing our future plans, on an ongoing basis, wrapped in a confidence interval.\n\n<sup>c</sup>We're sticking with one minor version release per quarter, for the foreseeable. I haven't split those out here because, 6+ months into the future, we care more about the _what_ and the _why_ than the _when_. As we get closer, we'll be able to detail the more-specific functionality that might land in specific releases. Note too that these ideas, though we're already devoting meaningful time and effort to thinking through them, are not definite commitments.\n\n# Introducing…\n\nTwo new Product Managers dedicated to thinking about dbt Core full time!\n\nCody, Florian, could you say a few words of introduction? What brought you to dbt Labs? What are some things you're excited about doing here?\n\n> Cody: Hello! My name is Cody, or [@lostmygithubaccount](https://github.com/lostmygithubaccount). The first programming language I learned was Python, my background is in electrical engineering and data science, and my previous experience as a product manager centered around operationalizing machine learning systems (MLOps). I'm excited about empowering you to build intelligent systems, the role dbt Labs has to play in converging the data & AI stacks while breaking down organizational silos, and to work on open-source software with an awesome community supporting! \n\n> Florian: Bonjour friends! You can find me around here under [@fleid](https://github.com/fleid). I started a long time ago as a SQL developer, writing monstrous queries to feed complex reports on top of operational databases. Version control was adding a version number in the filename of each report. No logic was shared across reports. Performance was horrendous. Overall data quality was… abysmal. Since then, by engaging in various communities I was able to learn a couple of neat tricks, like modern software engineering practices and dimensional modeling. So now I'm delighted to be able to contribute back to a community that supports a tool and a workflow that make these pitfalls obsolete. I only wish dbt existed all of these years ago! As for the future, I'm ramping up to help on the adapters, starting with a big backlog of issues and PRs that needs attention and love. I hope we can get to a better place, more reactive and ideally proactive, by end of the year. Please reach out if you've feelings or opinions to share about that space!\n\n(Jeremy again.) It's been a lot of fun to bring both of you into the fold over the past few months. The music does slow down when we add new chairs—there are processes that have become muscle memory for me, and turning those into collective endeavors takes time—but it's a thing worth doing. I can already say that our conversations have given me a huge boost of energy and excitement, in terms of what we can build together. We're grappling with some big questions—the biggest question being, what is dbt, *really?*—that I realize I've been taking for granted. I hadn't appreciated the risk that my old instinctive answers had calcified into constrained visions, or a GitHub issue comment from 2019 into binding precedent. Now that dbt Core is safely stable, it's the right time to ask those questions again. To start developing answers, always from the same principled viewpoint; to refine and critique them together; and to follow the logic where it leads.\n\n# Commentary\n\nHopefully, you're already well aware of, and happily making use of, the capabilities that shipped in dbt Core v1.1 and v1.2 earlier this year. If you're not, the [upgrade guides](https://docs.getdbt.com/guides/migration/versions) are a good place to get up to speed.\n\n## v1.3 (October): Coalesce\n\nI got to see a very small number of you a few months ago at a London dbt meetup, where I presented May's edition of roadmap. I'm looking forward—we're all (!) looking forward—to seeing and talking with many more of you in October for [Coalesce](https://coalesce.getdbt.com/). For those who are able and comfortable to make the trip to New Orleans, London, or Sydney—and for all the many more who are planning on a \"classic Coalesce\" experience, from the comfort of your laptop—we're very excited to have you.\n\nThe big thing coming in dbt Core v1.3 is support for Python models. You already knew that. All the details are in [the beta docs](https://docs.getdbt.com/docs/building-a-dbt-project/building-models/python-models), so give 'em a read now if you haven't yet.\n\nThere are a couple of FAQs (Frequently Associated Qualms) that I want to address, here and now, in case you're thinking one of them:\n\n**Will I need to know Python to start using dbt?** Not at all. At the same time, if you don't know it, and want to learn, that's great! The open source Python-for-data ecosystem is powerful, and often also overwhelming. We'll be creating resources to help light the way, plus highlighting guides, walkthroughs, and recommendations made by members of the community.\n\n**Is now the time to start experimenting with advanced statistical processing, predictive analytics, …?** Maybe! Or maybe not. Developing a solid, foundational set of data models should always come first. Deeply understand your data. Use it to power reliable analytical reporting. Whether you're ready to take the next step now or later, dbt is here to make it possible.\n\n**Does adding Python fundamentally change the nature of dbt Core?** Honestly, yes and no.\n\n- **No:** For all the SQL you're already writing and running successfully, we think you should keep it that way. SQL remains the most expedient and accessible way to write most forms of data transformation. We are *not* going to stop investing in dbt's support for SQL—and in Jinja as its templating engine, for the foreseeable future. (dbt-core v1.3 also includes a long-awaited upgrade to Jinja3, which should help folks installing alongside other Jinja-powered tools.)\n- **Yes:** Adding support for Python has clarified our thinking on multilingual dbt. It's helped us realize that the real value of dbt is not in Jinja-templated SQL. (Anyone can build that in a weekend; many have.) It's the framework, the environment-aware workflow, the DAG, the integrated testing and documentation—more things than I can name here. That's more language-agnostic than you might expect. At the same time, each language brings its strengths; there will be things you can do in Python that you cannot do in Jinja-SQL, and vice versa.\n\nNote that, while Python is the main event, it's not the only new thing coming in v1.3. Every release includes a bunch of exciting community contributions, and this one's got [something long awaited](https://docs.getdbt.com/reference/resource-configs/docs#custom-node-colors?version=1.3). We're also making improvements to metrics to support the launch of the **dbt Semantic Layer**. That's been a *huge* initiative, long in the works, and a long time coming. It's not my place to offer spoilers. I recommend you check out [Drew's blog](https://www.getdbt.com/blog/dbt-semantic-layer/), if you haven't already, and [join us for the show](https://coalesce.getdbt.com/).\n\n## v1.4 (January): For us, for you, for Core\n\nAfter Coalesce, we'll be taking stock of all that we built this year, and all we're looking to build next year. We are dedicating the months of November through January to dbt Core's technical foundations. (Plus: taking some well-deserved vacation over the holidays.)\n\nThis work is comprised of two big initiatives:\n\n1. **API + CLI:** Improving and documenting dbt-core's internal Python APIs. Creating a new and better-constructed CLI to wrap around it. To be clear, this CLI will support all the same commands, flags, and arguments as it does today.\n2. **Event + logging interface.** Supporting type-safe, language-agnostic ways to ingest structured logs produced by dbt-core. This will enable other tools (ours and yours) to provide reliable observability around dbt runs, as well as more-digestible and realer-time metadata. Over a longer term, providing more information in log events where it's missing today.\n\nThis is work that largely happens behind the scenes. If we do it well, the average dbt user should not notice any immediate differences. So why are we doing it?\n\n**If you use dbt Core's CLI,** this will make it easier to manage the growing number and complexity of command line options. To make sure all the right flags and options are supported on all the right commands; to add and update help text; and to automatically coordinate updated documentation that's been, to date, hand crafted by resident artisans.\n\n**If you build tools that wrap around dbt-core,** the appeal of a stable and documented API to its internals should be obvious. This is a long initiative, and we won't get to all of it right away, but the right idea is there. (And apologies, in advance, for the undocumented internal methods we'll be breaking in the process.)\n\n**If you use dbt Cloud,** Core's ability to provide stable and sensible interfaces is a big part of what enables differentiated capabilities in dbt Cloud in the future. It's not the coolest stuff in its own right, but a necessary precondition for that cool stuff to exist.\n\n**If you use dbt at all,** you should care about this work, insofar as it will make it easier for us to build more features faster next year. We want more people to join us in building dbt Core, and a welcoming codebase to greet them.\n\n## v1.5+ (Next year)\n\nIf you've been following our GitHub discussions, or the Analytics Engineering roundup, none of these topics should come as too much of a surprise. They're neither definite commitments, nor the full set of things we expect to do next year. There's a lot of linear improvement to existing functionality that's always on our minds, and in our issues. But I want to start with the pair of ideas that we've been talking about nonstop, for which we're already dreaming up some code:\n\n1. **Multi-project deployments.** `ref` a final model from someone else's project, wherever they've put it, without the need to run it first. Split up monolithic projects of 5000 models into 10 projects of 500, grouped by team and domain. This is more than just \"namespacing\": to really solve for this, we also need to solve for versioning and contracts, and support a variety of deployment mechanisms. The discussion for this has been in [#5244](https://github.com/dbt-labs/dbt-core/discussions/5244); I'll have more to share over the next few months.\n\n2. **External orchestration.** The same dbt DAG, playing a more active role. We've been developing this idea internally, and have arrived at a few strong opinions. This would not be a new node type, but an upgrade to the ones we already have: sources, models, and exposures. Sources that can trigger their own ingest. Exposures that can trigger downstream data consumers (syncs, sinks, etc). Models that can define and run transformations in dedicated execution environments, reading from and writing back to centralized data storage. For each of those external integrations, a simple request where possible, and a dedicated plugin where justified. If you're someone who followed along the original \"external nodes\" discussion ([#5073](https://github.com/dbt-labs/dbt-core/discussions/5073))—especially if you've got a tool you'd be excited to integrate into dbt's DAG—let's talk.\n\n---\n\nWe also intend to keep pushing on existing capabilities in dbt Core. Again, a non-exhaustive list:\n\n**Python models, only just beginning.** What's the right DataFrame API to standardize on? Should dbt have a role in managing packages, model training, artifacts? Eventually, a full \"MLOps\" workflow? v1.3 in October will be our first foray, not the final story. Cody just opened some GitHub discussions, starting with [#5742](https://github.com/dbt-labs/dbt-core/discussions/5742). See what we're thinking, and weigh in.\n\n**Adapters, adapters, adapters.** We want to make it easier to build, test, and validate support for dbt on a new database, query engine, or runtime environment. We want to support more than one adapter for use in a single dbt-core invocation. We want to keep honing the performance of caching, cataloging, and incremental processing at scale, across data platforms. We want to offer more adapters in dbt Cloud.\n\n**Imagining dbt Core v2.** Last December, when announcing the v1.0 release, I predicted (wildly guessed) that dbt v2.0 would take 2-4 years to reach us (2023-2025). Then I put some things on a slide, asking everyone to imagine:\n- *dbt-SQL: The same capabilities. No Jinja.*<sup>1</sup>\n- *The docs are always ready.*<sup>2</sup>\n- *One dbt run across many databases and query engines.*<sup>3</sup>\n- *Define your own tasks for the dbt DAG.*<sup>4</sup>\n\nMost of that still feels about right. I don't see us ending next year with a v2.0 final release, but I do see us having a clear picture of what v2 will look like. In a sense, we've already started the work to get there, by combing our way through the rougher edges of v1.\n\nI'm excited for the next few months. I hope you are too.\n\n---\n\n<sup>1</sup>Now, I wonder if the answer is: Jinja-SQL and Python are just two of many supported languages for dbt Core. Some languages will make it dead-easy to unit test, to transpile across different databases, to infer column-level lineage. Others make it possible to run introspective queries that dynamically template transformation logic. It's an exciting future to consider. The challenge is to be clear and opinionated about what each one brings to the table, and when each one shines.\n\n<sup>2</sup>Real-time metadata; see above.\n\n<sup>3</sup>External orchestration; see above.\n\n<sup>4</sup>This one, I'm not so sure! The task before us is the same as it ever was: build the DAG, as fast as possible, just what's needed, when it's needed. Still, I keep  more advanced use cases that want to programmatically create, manipulate, and invoking the dbt DAG—and they may well be more plausible in a future where dbt-core has a documented, contracted set of internal APIs. That would be advanced-level stuff, guardrails not included. You probably don't need (or want) it, and if you do, you know it.\n"
  },
  {
    "path": "docs/roadmap/2023-02-back-to-basics.md",
    "content": "# dbt: Back to basics (February 2023)\n\nWe're back, and there's a lot to say—so much that if we're not mindful, we risk writing a(nother) novella. We're going to try for concision this time; it's a year of focus. Of course, a lot more has already been written, so we'll also link to those issues & discussions, where we encourage you to weigh in with thoughts.\n\nSince last August, we've released two new versions of dbt Core:\n- v1.3 unleashed Python models onto the world. This is very new functionality, and we are still gathering feedback on where to go next. Read & comment on [the big ideas](https://github.com/dbt-labs/dbt-core/discussions/categories/ideas?discussions_q=label%3Apython_models+category%3AIdeas).\n- v1.4 reworked some internals, paid down some tech debt, and paved the way for better APIs going forward.\n\n| Version | When | Namesake | Stuff |\n| ------- | ------------- | -------------- | ----- |\n| 1.3 ✅ | Oct 2022 | Edgar Allen Poe | Python models in dbt. More improvements to metrics. |\n| 1.4 ✅ | Jan 2023 | Alain LeRoy Locke | Behind-the-scenes improvements to technical interfaces, especially structured logging. |\n\nThis year, we're returning to our fundamentals. This means fewer big surprises—fewer new answers to the question, \"What is dbt?\"—and more of the things that dbt needs—the dbt that you know, the dbt that you & your teams have come to rely on for getting your job done.\n\nThere are four big themes we want to tackle, reflected in the questions below. We will aim to provide compelling answers, sometimes with new functionality, sometimes with polish on top of existing capabilities. These aren't the only questions that interest us, but they are the ones we're prioritizing this year.\n\n1. **Our APIs.** How can we enable the thousands of people who want to use dbt today, ? Can we enable community members to build more powerful extensions of dbt's framework, by exposing more & more of its functionality as a stable Python library? Can we provide an experience as delightful as dbt-core's CLI, via a reliable `dbt-server`, and RESTful APIs in dbt Cloud?\n2. **Your models, as APIs.** Can dbt as a framework scale to complex deployments, across multiple teams, entering their third or fourth year of project maturity? Can it scale to some of the largest organizations who have adopted it as a standard pattern? What can we learn from the scaling challenges that software teams have encountered and surmounted over the last decade?\n3. **Streaming.** How must dbt's essential building blocks—models, tests, sources, materializations—change (or not) to finally leverage data platforms' capabilities around streaming transformation?\n4. **Semantic Layer.** How can we combine the existing power of dbt metrics, defined as an extension of your dbt DAG, with the depth of MetricFlow (!) as a framework for defining richer metrics and generating optimized queries?\n\nIn a sentence: **The same dbt, for more people.** More community members who might build plugins and extensions, without having to read `dbt-core` source code and hack together undocumented internal methods. More embedded analysts who can confidently contribute the right change to the right model in the right project, without having to first navigate through thousands of preexisting models with unclear ownership. More use cases that can be solved in \"the dbt way,\" for batch as well as streaming. More downstream queriers who can benefit from asking questions on top of a dbt Semantic Layer.\n\nWe're sticking with one minor version release every three months. There won't be a version dedicated to _just_ API improvements, multi-project deployments, streaming, or semantic layer. Rather, we expect to make incremental progress as we go along. With that, here's our near-sighted lay of the land:\n\n| Version | When          | Stuff          | Confidence |\n| ------- | ------------- | -------------- | ---------- |\n| 1.5 ⚒️ | April | An initial Python API for programmatic invocations, and a cleaner CLI to match. The beginning of multi-project deployments (\"Models as APIs\"), and of support for streaming (materialized views). | 95% |\n| 1.6 🌀 | July | Next steps for multi-project deployments (cross-project `ref`, project-level namespacing, patterns for development & deployment). Continue the story around stream processing (materialized tests, managed sources). Integrating dbt metrics and MetricFlow. | 75% |\n| 1.7 | October | More on the same themes. The details will be based on velocity, feedback, and emergent discoveries. | 50% |\n| 1.8+ 💡 | 2024 | dbt-core as a library. A sketch of dbt v2. | 25% |\n\n\n`updated_at: 2023-02-28`\n\nAs always, to keep track of what's happening between these roadmap updates:\n- [Milestones](https://github.com/dbt-labs/dbt-core/milestones)\n- [GitHub discussions](https://github.com/dbt-labs/dbt-core/discussions)\n- [Company blog](https://blog.getdbt.com/) & [dev blog](https://docs.getdbt.com/blog)\n\nDon't forget to ~~like and subscribe~~ [upgrade](https://docs.getdbt.com/guides/migration/versions)!\n\n# Commentary\n\nLet's keep it brief!\n\n## A Python API for dbt-core\n\ndbt Core v1.5 will include:\n- A new CLI, based on `click`, with improved help text & documentation\n- Support for programmatic invocations, via a Python API, at parity with CLI functionality\n\nIs this it? I don't think so. We have a longer-term vision of dbt-core as a mature software library, with clear interfaces and plugin points.\n\nWe aren't going to get all the way there by April. We will have a subset of capabilities that will enable a number of cool things for many. I believe we will be able to get there, over the next year, with carefully scoped initiatives tied to clear outcomes. We've been developing & sharing our visions as a team, and we'll have more to share over the coming months.\n\n_Read more: [\"dbt-core as a library: first steps\"](https://github.com/dbt-labs/dbt-core/issues/6356)_\n\n## Multi-project deployments (v1.5+)\n\nHere are three guiding principles:\n1. Each team owns its data, and how that data is shared with other teams.\n2. Organizations can maintain central governance, coordinating rules across teams.\n3. All models are in one DAG.\n\nThese are not necessarily the doctrine of \"dbt mesh,\" but we are using them to describe the end state we're hoping to achieve, the core capabilities we need to unlock it, and the user flows (person-to-person, team-to-team, person-to-dbt) we want to facilitate along the way.\n\nEach person interacts with the subset(s) of the DAG relevant to them. Developing and deploying dbt should feel the same.\n\nThe first step here is giving teams maintaining dbt projects the tools to start serving models as \"APIs.\" The coup de grâce is being able to `ref` another team's stable, public, contracted model as the starting point for your own.\n\n_Read more: [\"Multi-project deployments\"](https://github.com/dbt-labs/dbt-core/discussions/6725) & linked discussions_\n\n## Support for streaming\n\nBack in 2020, one of Jeremy's very first projects, as newly designated Associate Product Manager, was investigating the implementation of Materialized Views across our most popular data platforms. The findings: while the dream of MVs was a happy one, every real MV was unhappy in its own way, motivated by different use cases and beset by subtle limitations.\n\nA few years later, the major data platform vendors are taking another swing at first-class support for streaming transformation. We're also lucky to have Florian, who talked & thought streaming databases for a living. Our vision is a dbt DAG that can combine batch & streaming, without distorting the core framework that's gotten dbt where it is.\n\n_Read more: [\"Let's add Materialized View as a materialization, finally\"](https://github.com/dbt-labs/dbt-core/issues/6911)_\n\n## dbt Semantic Layer\n\nWe've officially welcomed many new colleagues from Transform. We're going to be spending time over the next several weeks talking about how to integrate dbt Core's existing metrics spec with MetricFlow's.\n\nWe expect to be writing much more about this in public. Until then, you can read our previous thinking. The specifics are liable to change, but the foundational concept still holds: [\"dbt should know more semantic information\"](https://github.com/dbt-labs/dbt-core/discussions/6644)\n\n## What's **not** here?\n\nIn 2023, we need to be focused & disciplined. There's a lot we wish we could be making progress on, but we can only guarantee that progress in a precious few areas, by devoting our attention & energy to them.\n\nEach of the topics below has appeared in the lower-confidence portions of previous roadmaps, and they continue to interest us greatly. We have all been guilty of saying, \"Let's just take a day—just one day!—and try to hack together a working demo.\" You might even see some proof-of-concept code appear, here or there. We won't turn down opportunities to take small steps, to make incremental forward progress. But none of these is something we expect us to be launching at Coalesce in October.\n\n- **External orchestration.** Can dbt trigger external APIs to ingest `sources`, and sync `exposures`? To run `models` that require tools outside the data platform? I'd like the answer here to be \"yes,\" but it isn't a priority for this year.\n- **Next steps for Python models.** It's worth restating: This is very new functionality, and we're still very early. We have some ideas of what could be compelling and ergonomic, and there are some small usability improvements we'll try to make over the year—but we need to learn more about how you all are using, and want to be using, Python models, before we once again tackle these as a top priority.\n- **More modeling languages**, or \"Bring Your Own SQL transpiler / Python framework / ???\". This is one of the more boundary-pushing ideas we've had, for continuing to expand dbt's reach as a framework for (language-agnostic!) data transformation. It's not one of the foundational reinvestments that we must make sooner rather than later. We've also [discussed this pattern](https://github.com/dbt-labs/dbt-core/discussions/4458#discussioncomment-4176217) as one potential path toward unlocking **column-level lineage,** which—while always present in our hearts & among our [most popular discussions](https://github.com/dbt-labs/dbt-core/discussions?discussions_q=sort%3Atop+)—also doesn't appear on this year's list of top priorities.\n- **Unit testing.** ~Let's just take a day—just one day!—and try to hack together a working demo.~ (We might, though.)\n\n## What we'll keep doing\n\nThis covers the big rocks. The pebbles and the sand, we already have our ~~mouths~~ hands full. Most of the time, it's even fun.\n\nWe'll keep releasing patches with fixes for bugs and any regressions that crop up in new versions of dbt-core.\n\nWe'll keep a swimlane open for developer ergonomics. Not fundamental changes to the dbt framework, but quality-of-life improvements for those who use it every day. We've created [a new label to track these \"paper cuts\"](https://github.com/dbt-labs/dbt-core/issues?q=is%3Aissue+is%3Aopen+label%3Apaper_cut+sort%3Areactions-%2B1-desc)—often among the most upvoted issues!—and we're very interested in supporting community members who want to help us refine & contribute these improvements.\n\nWe'll keep reading & responding to your issues, bug reports, feature requests, ideas. We can't respond to every comment everywhere, but we read them all. You come to dbt, and so we build it & keep building it—with ambition & with vision, with discipline & with focus.\n\nYours truly - Jeremy, Florian, Doug, & the entire Core team\n"
  },
  {
    "path": "docs/roadmap/2023-11-dbt-tng.md",
    "content": "# dbt: The Next Generation (November 2023)\n\nTo everyone we saw at [Coalesce](https://coalesce.getdbt.com/) last month: thank you for joining us! We got up on stage and shared the next chapters from this year’s featured stories: about [collaborating across multiple teams and projects at scale](https://www.youtube.com/watch?v=NIseH-Gd-U4); about [relaunching the dbt Semantic Layer](https://www.youtube.com/watch?v=2Qo5_CIsSH4); about [more flexibility in development](https://www.youtube.com/watch?v=UfraDWKsSvU); and about [more mature CI/CD](https://www.youtube.com/watch?v=3sp6tmYykVc). To anyone who missed us live, [catch us on the replays](https://www.youtube.com/@dbt-labs)!\n\nThese are stories that span both dbt Core and dbt Cloud. Our aim is to push forward the open source standard for analytics engineering, and also the platform that makes it possible for more teams to adopt & deploy dbt at scale.\n\nIn [his keynote presentation](https://youtu.be/lNZLcsHAdco?si=FdtTOOIokvm1pT8D&t=637), Tristan talked about these two priorities for dbt Labs. We remain committed to dbt Core, as a standard for the industry, and an open source project under an Apache 2 license. We are also committed to creating a business around dbt Cloud that is sustainable over the long term, to enable us to continue to invest in driving dbt forward.\n\nThose two goals are inseparable. To make them both happen, we need to strike an important balance. What has it looked like over the last six months, and what will it look like for the six months ahead?\n\n_[JC](https://github.com/jtcohen6) & [GG](https://github.com/graciegoheen)*_\n\n> *Also, hi! I’m Grace Goheen, or [@graciegoheen](https://github.com/graciegoheen). Long time dbt user, new to the dbt Core product team. I joined the Professional Services team at dbt Labs back in 2021, where I’ve since had the opportunity to work hands-on in dozens of dbt projects - leading legacy migrations, consulting on architecture, optimizing project performance, and more. I lived through the joy (lineage! testing! documentation!) and pain (spaghetti DAGs! model bottlenecks! debugging code!) of being an analytics engineer, and realized I wanted to be a part of shaping the tool at the center of it all. So here I am, the newest Product Manager of dbt Core! I am so grateful to be building this industry-defining tool with all of you.\n> \n\n# The last six months: scale\n\n| Version | When | Namesake | Stuff |\n| --- | --- | --- | --- |\n| [v1.5](https://docs.getdbt.com/guides/migration/versions/upgrading-to-v1.5) | April | [Dawn Staley](https://github.com/dbt-labs/dbt-core/releases/tag/v1.5.0#:~:text=Dawn%20Staley%20(b.%201970)) | Revamped CLI. Programmatic invocations. Model governance features (contracts, access, groups, versions). |\n| [v1.6](https://docs.getdbt.com/guides/migration/versions/upgrading-to-v1.6) | July | [Quiara Alegría Hudes](https://github.com/dbt-labs/dbt-core/releases/tag/v1.6.0#:~:text=Quiara%20Alegr%C3%ADa%20Hudes%20(b.%201977)) | New Semantic Layer spec. More on model governance (deprecations). Saving time and $$ with retry + clone. Initial rollout of materialized views. |\n| [v1.7](https://docs.getdbt.com/guides/migration/versions/upgrading-to-v1.7) | November | <a href=\"https://github.com/dbt-labs/dbt-core/releases/tag/v1.7.0#:~:text=%238692)-,Questlove%20(b.%201971),-Thanks%20to%20%40dave\">Questlove</a> | More flexible access to \"applied state\" in docs generate and source freshness. Improvements to model governance & semantic layer features (driven by user feedback). |\n\nWe added a **lot** of stuff this year! Over the past three dbt Core minor versions, we’ve managed to knock out a litany of the most popular issues and discussions gathered over the past several years:\n\n- [CLI preview](https://github.com/dbt-labs/dbt-core/discussions/5418) (1.5)\n- [Invoking dbt as a Python module](https://github.com/dbt-labs/dbt-core/issues/2013) (1.5)\n- [Materialized views](https://github.com/dbt-labs/dbt-core/issues/1162) (1.6)\n- [Namespacing for dbt resources](https://github.com/dbt-labs/dbt-core/issues/1269) (1.6), in support of [multi-project collaboration](https://github.com/dbt-labs/dbt-core/discussions/6725)\n- [`docs generate --select` for slimmer catalog queries](https://github.com/dbt-labs/dbt-core/issues/6014) (1.7)\n- And… we’re finally taking aim at [unit testing for dbt-SQL models](https://github.com/dbt-labs/dbt-core/discussions/8275) (!), coming in 1.8, which you should read more about in the section below.\n\nThank you for providing your upvotes, comments, and feedback. One of the best things about building dbt Core in the open is that we are all pushing forward the analytics engineering standard together. We’re able to prioritize these features and paper cuts because of your participation. \n\nWe’ve got lots more to build - there are some highly upvoted issues and discussions that remain, and gaps in the analytics engineering workflow that we want to close. But before we keep building, we must ensure our foundation is a **stable** one.\n\n# The next six months: stability (& unit testing!)\n\n| Version | When | Stuff | Confidence |\n| --- | --- | --- | --- |\n| 1.8 | Spring 2024 | Stable interfaces for adapters & artifacts. Built-in support for unit testing dbt models. | 80% |\n\nSince the v1.0 release of dbt Core (almost two years ago), we’ve released a minor version of dbt Core every three months. The January release (post-Coalesce, post-holidays) tends to be an understated affair: tech debt, bug fixes, support for Python 3-dot-new.\n\nWe’ve been measuring the rate of adoption for new versions, and we’ve seen that it takes more than 3 months for the wider user base to really adopt them. The plurality of dbt projects in the world are using a dbt Core version released between 6 and 12 months ago. We think this speaks to two things: It’s harder to upgrade than it should be.; and we can afford to take more time baking new releases.\n\nBetween now and next April (2024), we plan to instead prepare **one** minor release that prioritizes **all-around interface stability**. We want to make it easier for _everyone_ to upgrade with confidence, regardless of their adapter or other integrated tooling. There is a _lot_ of value locked up in the features we’ve already released in 2023, and we want to lower the barrier for *tens of thousands* of existing projects who are still on older versions. That work is important, it takes time, and it has long-lasting implications.\n\n### Adapters & artifacts\n\nWith the v1.0 release, [we committed](https://www.getdbt.com/blog/getting-ready-for-v1-0) to minimizing breaking changes to project code, so that end users would be able to upgrade more easily. We haven’t perfected this, including earlier this year when we did a full relaunch of the metrics spec for the Semantic Layer. We are committed to getting better here.\n\nEven in v1.0, though, we intentionally carved out two less-stable interfaces, which would continue to evolve in minor releases: **adapter plugins** and **metadata artifacts**. At the time, these interfaces were newer and rapidly changing. Almost every minor version upgrade, from v1.0 through v1.7, has required some fast-follow compatibility changes for adapters and for tools that parse dbt manifests.\n\nThis has been particularly difficult for adapter maintainers. As of this writing, while [the majority of third-party adapters support v1.4](https://github.com/dbt-labs/dbt-core/discussions/6624#discussioncomment-5663823) (released in January), [just over a third support v1.5](https://github.com/dbt-labs/dbt-core/discussions/7213#discussioncomment-5663790) (April), and [only a handful support v1.6](https://github.com/dbt-labs/dbt-core/discussions/7958#discussioncomment-6310276) (July). It isn’t fair of us to keep releasing in a way that *requires* this reactive compatibility work every 3 months. Instead, we will be defining a stable interface for adapters, in a separate codebase and versioned separately from dbt Core. Starting in v1.8, it will be forward-compatible for future versions. If you want to use `dbt-core` v1.X with `dbt-duckdb` v1.Y, you will be able to.\n\nFor most people, we don’t want you to have to think about versions _at all_: just use latest & greatest dbt Core. For customers and users of dbt Cloud, this is the experience we want to provide: delivering dbt Core and dbt Cloud together, as one integrated and continuously delivered SaaS application — an experience where you don’t need to think about versions or upgrading, and where you get access to Cloud-enhanced & Cloud-only features as a matter of course.\n\n**An aside:** This was the first year in which we delivered [some functionality like that](https://github.com/dbt-labs/dbt-core/discussions/6725): built it in such a way that it _feels like Core_ while being actually powered by (and exclusive to) dbt Cloud. This has long been our pattern: Core defines the spec, and Cloud the scalable implementation, especially for Enterprise-geared functionality. \n\nI (Jeremy) wish I had communicated this delineation more clearly, and from the start. We are going to continue telling unified stories, across mature capabilities in Core and newer ones in Cloud, and we want all of you — open source community members, Cloud customers, longtime data practitioners and more-recent arrivals — to know that you are along for this journey with us.\n\n### Summary: continuous & stable delivery\n\nOver the next 6-12 months, we will be spending less time on totally new constructs in dbt Core, and more time on the fundamentals that are already there: stabilizing, maintaining, iterating, improving.\n\ndbt Cloud customers will see enhancements and under-the-hood improvements delivered continuously, as we move towards this model of increased stability. Features that fit inside dbt Core’s traditional scope will also land in a subsequent minor version of dbt Core.\n\nThis is an important part of our evolving story: a compelling commercial offering that makes it possible for us to keep developing, maintaining, and distributing dbt Core as Apache 2 software.\n\n## Onwards\n\ndbt Core is as it has always been: an open source standard. It’s a framework, a coherent set of ideas, and a fully functional standalone tool that anyone can take for a spin — adopt, extend, integrate, imitate — without ever needing to ask us for permission. Adapters will keep moving at the pace of innovation for their respective data warehouse. dbt Docs remains a great \"single-player\" experience for getting hooked on data documentation. (The aesthetic isn’t dated, it’s *[retro](https://github.com/lightdash/dbt-docs-95).*) dbt Core remains the industry-defining way to author analytical models and ensure their quality in production.\n\nBut wait!\n\nAs many of you have voiced, there’s been no good way to ensure your SQL logic is correct without running expensive queries against your full production data. dbt does not have native unit testing functionality… yet. This gap in the standard is one we have been eager to work on, and we’re planning to land it in the next minor release of dbt Core.\n\n### What is unit testing in dbt?\n\nFor many years, dbt has supported \"data\" tests — testing your *data outputs* (dbt models, snapshots, seeds, etc.) based on that environment’s actual *inputs* (dbt sources in your warehouse), and ensure the resulting datasets match your defined expectations.\n\nSoon, we’re introducing \"unit\" tests — testing your modeling *logic,* using a small set of static inputs, to validate that your code is working as expected, faster and cheaper.\n\n### What’s the plan?\n\nThank you to everyone who has already provided feedback and thoughts on our [unit testing discussion](https://github.com/dbt-labs/dbt-core/discussions/8275) — or, we should say our _new_ unit testing discussion, since Michelle opened the [original one](https://github.com/dbt-labs/dbt-core/discussions/4455) back in 2020, before she joined dbt Labs :)\n\nWe truly appreciate the amount of insights and energy y’all have already poured into helping us make sure we build the right thing.\n\nWe are actively working on this feature and expect it to be ready for you all in our `1.8` release next year! If you have thoughts or opinions, please keep commenting in the discussion. We’re also planning a community feedback session for unit testing once we’ve released an initial beta of `1.8`, so keep an eye out.\n\n### Bugs, regressions, paper cuts, ...\n\nWe will continue to respond to your issues and review your PRs. We will continue to resolve regressions and high-priority bugs, fast as we’re able, and include those fixes in regular patch releases.\n\nAlong with fixing bugs and regressions, we’d also like to keep tackling some of the highly requested \"paper cuts”. Thank you to all those who have expressed their interest by upvoting and commenting.\n\nWe’re unlikely to tackle all of these things in v1.8 — they’re lower-priority than the interface stability work, which we must do — they are all legitimate opportunities to solidify the existing, well-established Core functionality:\n\n- [Allow data tests to be documented](https://github.com/dbt-labs/dbt-core/issues/2578)\n- [Snapshot paper cuts](https://github.com/dbt-labs/dbt-core/discussions/7018)\n- [Making external tables native to dbt-core](https://github.com/dbt-labs/dbt-core/discussions/8617)\n- [Defining vars, folder-level configs outside `dbt_project.yml`](https://github.com/dbt-labs/dbt-core/issues/2955)\n- [Supporting additional formats for seeds](https://github.com/dbt-labs/dbt-core/issues/2365) (JSON)\n\nLet us know which ones speak to you — in that list, not in that list, the ideas in your head — on GitHub, on Slack, or wherever you may find us.\n"
  },
  {
    "path": "docs/roadmap/2024-12-play-on.md",
    "content": "# dbt: Play On (December 2024)\n\nOh hi there :)\n\nWe’ve had the opportunity to talk a lot about our investments in open source over the past few months:\n\n- [I [Grace] renewed my vows with the dbt Community in a Vegas wedding ceremony officiated by Elvis](https://youtu.be/DC9sbZBYzpI?si=uK9Aie6Jl-FIHggm) (aka [@jtcohen6](https://github.com/jtcohen6)).\n- [We spoke about dbt Labs’ continued commitment to Open Source in the Coalesce Keynote](https://youtu.be/I72yUtrmhbY?si=Iu6s9WXdHnFtyCvi).\n- [We wrote about the importance of extensibility for how we build features in dbt Core.](https://www.getdbt.com/blog/dbt-core-v1-9-is-ga#:~:text=Extensibility%20is%20what%20powers%20the%20community)\n\nAll of these points and themes remain incredibly relevant to our team and are fueling our vision as we prepare for the new year:\n\n- we're committed to defending dbt Core as the open source standard for data transformation, which will remain licensed under Apache 2.0\n- the dbt framework will continue to be shaped by a collaborative effort between you (the community) and us (the maintainers)\n- when we add something new to the standard, we are committing to the long term, which means we are intentional about *how* and *when* we expand its breadth - in the meantime, lean into dbt's extensibility (and show us how you're doing it!)\n\nNow that we’ve gotten into our new rhythm…\n\nNow that last year’s focus on stability has earned us the right to ship awesome new additions to the dbt framework…\n\nNow that we’re actually seeing a *much* higher % of projects running the latest & greatest dbt…\n\n…the next 6-12 months will feel similar to the last. dbt will keep getting better at doing what it does - being a mission-critical piece of your data stack, and a delightful part of your work. To that end, stability always comes first. And, we will be shipping some exciting new features to dbt Core. \n\n# Oh What A Year It’s Been!\n\nThis year, we released two new minor versions of dbt Core.\n\n| **Version** | **When** | **Namesake** | **Stuff** |\n| --- | --- | --- | --- |\n| [v1.8](https://docs.getdbt.com/docs/dbt-versions/core-upgrade/upgrading-to-v1.8) | May | [Julian Abele](https://github.com/dbt-labs/dbt-core/releases/tag/v1.8.0) | Unit testing. Decoupling of dbt-core and adapters. Flags for managing changes to legacy behaviors. |\n| [v1.9](https://docs.getdbt.com/docs/dbt-versions/core-upgrade/upgrading-to-v1.9) | December | [Dr. Susan La Flesche Picotte](https://github.com/dbt-labs/dbt-core/releases/tag/v1.9.0) | Microbatch incremental strategy. New configurations and spec for snapshots. Standardizing support for Iceberg. |\n\nIn the [last roadmap post](https://github.com/dbt-labs/dbt-core/blob/main/docs/roadmap/2023-11-dbt-tng.md), we committed to prioritizing all-around interface stability. This included decoupling dbt-core and adapters, introducing [behavior change flags](https://docs.getdbt.com/reference/global-configs/behavior-changes) to give you time to adjust to ~~breaking~~ changes, and improving the stability of metadata artifacts. You can read more about those efforts [here](https://docs.getdbt.com/blog/latest-dbt-stability).\n\nStability means you can upgrade with confidence. \n\nStability means less disruptions for our adapters and integrations in the dbt ecosystem.\n\nStability means we’ve earned the right to **ship some big new features**.\n\nThis past year, we were able to ship some long-awaited additions and enhancements to the dbt Core framework:\n\n- [**Unit tests**](https://github.com/dbt-labs/dbt-core/discussions/8275) allow you to validate your SQL modeling logic on a small set of static inputs before you materialize your full model in production.\n- [**Snapshots**](https://github.com/dbt-labs/dbt-core/discussions/7018) got the glow up they deserved - with new configurations and spec to make capturing your data changes easier to configure, run, and customize.\n- [**Microbatch**](https://github.com/dbt-labs/dbt-core/discussions/10672) incremental models enable you to optimize your largest datasets, by transforming your timeseries data in discrete periods with their own SQL queries, rather than all at once.\n- [**Iceberg**](https://docs.getdbt.com/blog/icebeg-is-an-implementation-detail) table format (an open standard for storing data and accessing metadata) is standardized across adapters, enabling you to store your data in a way that promises interoperability with multiple compute engines.\n\nWe also were able to close out some highly-upvoted “paper cuts”:\n\n- `--empty` flag limits the `ref`s and `source`s to zero rows, which you can use for schema-only dry runs that validate your model SQL and run unit tests\n- dbt now issues a single (batch) query when calculating source freshness through metadata, instead of executing a query per source\n- improvements to `state:modified` help reduce the risk of false positives due to environment-aware logic\n- you can now document your data tests with `description`s\n\nA lot of these features are things that you (the community) have been discussing and experimenting with for years. To everyone who opened an issue, commented on a discussion, joined us for a feedback session, developed a package, or contributed to our code base… however you made your voice heard this year, **thank you** for continuing to care, for continuing to lean in, for continuing to help shape dbt. \n\n# New Year’s Resolutions\n\nTo start off the new year, we’re focusing on three major areas of development to the dbt framework:\n\n- **typed macros** - configure Python type annotations for better macro validation\n- **catalogs** - first-class support for materializing dbt models into external catalogs, providing a warehouse-agnostic interface for managing data in object storage\n- **sample mode** - limit your data to smaller, time-based samples for faster development and CI testing\n\n## Typed Macros\n\nIn the simplest terms, [macros](https://docs.getdbt.com/docs/build/jinja-macros#macros) are are pieces of code, written in Jinja, that can be reused throughout your project – they are similar to \"functions\" in other programming languages. \n\nIn practice, you can reference a macro in a model’s SQL (or config block, or hook) to:\n\n- make your SQL code more DRY by abstracting snippets of SQL into reusable “functions”\n- use the results of one query to generate a set of logic\n- change the way your project builds based on the current environment\n\nOr, if you really need to, run arbitrary SQL in your warehouse via `dbt run-operation`.\n\nMacros can depend on inputs, vars, `env_vars`, or even other macros — *and* there are “special” macros for defining custom generic tests and materializations.\n\nThis immense flexibility is one of the great benefits of macros — you can use them to solve **a lot** of different problems.\n\nHowever, on the flip side, this flexibility — where macros can be whatever you want them to be — makes it challenging to validate that your macros are doing what you expect. \n\nWithout a way to define expected types for the inputs and outputs of macros, our adapter maintainers struggle to validate that a built-in macro override will produce the correct output. Furthermore, *any* analytics engineer writing a macro in dbt should be able to validate the expected behavior. \n\nOne of the things we aim to work on in the coming months is an interface for **typed macros.** \n\nImagine being able to codify the expected types* for the inputs and outputs for your macros:\n\n```sql\n{% macro cents_to_dollars(column_name: str, scale: int = 2 -> str) %}\n\t({{ column_name }} / 100)::numeric(16, {{ scale }})\n{% endmacro %}\n```\n\n**Note: These are a subset of Python types (internal to dbt), not the data types within the data warehouse.*\n\nThen, we could issue warnings at parse time when usage of a macro violates these types. By adding the ability to configure type expectations, user-created macros become more predicable, and [built-in macros become easier to override](https://github.com/dbt-labs/dbt-core/issues/9164). \n\nShould this type checking be on by default, or something you opt into? Should we also support dbt-specific types, such as `Relation`? Head over to the [github discussion](https://github.com/dbt-labs/dbt-core/discussions/11158) to participate in the conversation!\n\n## Catalogs\n\nIn `v1.9`, we shipped a set of standard configs to materialize dbt models in Iceberg table format:\n\n```sql\n{{\n  config(\n    materialized = \"table\",\n    table_format = \"iceberg\",\n    external_volume = \"s3_iceberg_snow\"\n  )\n}}\n\n...\n```\n\nSupporting the Iceberg table format was our first step towards empowering users to adopt Iceberg as a standard storage format for their critical datasets.\n\nIn the coming months, we want to add first-class support for “catalogs” in dbt. “Catalogs,” including Glue or Iceberg REST, operate at a level of abstraction above specific Iceberg tables — and they can provide a warehouse-agnostic interface for managing a large number of datasets in object storage. \n\nImagine a new top-level `catalogs.yml` that tells dbt about the catalog integrations you want to write to:\n\n```yaml\ncatalogs:\n  - catalog_name: my_first_catalog\n    write_integrations:  \n      - integration_name: prod_glue_write_integration\n        external_volume: my_prod_external_volume\n        table_format: iceberg\n        catalog_type: glue\t    \n```\n\nThen, in your model’s configuration, simply specify the `catalog` field:\n\n```sql\n{{\n  config(\n    catalog = \"my_first_catalog\"\n  )\n}}\n\n...\n```\n\nThese new configurations will enable dbt to template the correct DDL statements for the platform (`CREATE GLUE ICEBERG TABLE` vs. `CREATE ICEBERG TABLE`, etc.). Now, when you run the above model, it will be materialized as an Iceberg table in s3 registered in the AWS Glue catalog. \n\nWe believe the approach of writing datasets to a platform-agnostic storage layer, and registering those datasets with a similarly agnostic *catalog service,* will become important to the technical foundations of the dbt workflow — the [Analytics Development Lifecycle (ADLC)](https://www.getdbt.com/resources/guides/the-analytics-development-lifecycle) — moving forward. Support for materializing Iceberg tables in external catalogs is another step down this path.\n\nTo read more about catalogs and participate in shaping this feature, head over to the [discussion on GitHub](https://github.com/dbt-labs/dbt-core/discussions/11171)!\n\n## Sample Mode\n\nWe began our [“event_time” journey](https://github.com/dbt-labs/dbt-core/discussions/10672) with microbatch incremental models. Next up is [sample mode](https://github.com/dbt-labs/dbt-core/discussions/10672#:~:text=%F0%9F%8C%80%5BNext%5D%20%E2%80%9CSample%E2%80%9D%20mode%20for%20dev%20%26%20CI%20runs) - we want to support a pattern for speeding up development and CI testing by filtering your dataset to a *time-limited sample.* \n\nImagine your model contains a `ref` statements like so:\n\n```sql\nselect * from {{ ref('fct_orders') }}\n```\n\nDuring standard runs, this compiles to:\n\n```sql\nselect * from my_db.my_schema.fct_orders\n```\n\nBut during a *sample* run, dbt could automatically filter down large tables to the last X days of data using the same `event_time` column used for microbatch. The exact syntax here is TBD, but imagine you run something like `dbt run --sample 3`, which then compiles your code to:\n\n```sql\nselect * from my_db.my_schema.fct_orders\n-- the event_time column in fct_orders is 'order_at'\nwhere order_at > dateadd(-3, day, current_date)\n```\n\nNo more [overriding the `source` or `ref` macro](https://discourse.getdbt.com/t/limiting-dev-runs-with-a-dynamic-date-range/508) to hack together this functionality.\n\nBuilt-in support for “sample mode” — filtering to a consistent time-based “slice” across all models — means faster development and faster testing because you’re running on *less* data. This could be configured for a specific dbt invocation, a CI environment, or as a set-it-and-forget-it default for everyone who’s developing on your team’s project.\n\n[#11200 Sample Mode (for faster Development and CI 🚀)](https://github.com/dbt-labs/dbt-core/discussions/11200) is the place to think in public with us.\n\n## and who could forget, paper cuts!\n\nThose are the big things we plan to tackle in the coming months. As always, we want to tackle some smaller `paper_cut`s as well. Your upvotes and comments help us prioritize these, so please make some noise if there’s something you care a whole lot about. Some that are top of mind for me already:\n\n- **DRY-er YML**, including:\n    - [Defining vars configs outside dbt_project.yml](https://github.com/dbt-labs/dbt-core/issues/2955)\n    - [Add ability to import/include YAML from other files](https://github.com/dbt-labs/dbt-core/issues/9695)\n- **Enhancements to model versions and contracts**, including:\n    - [Automatically create view/clone of latest version](https://github.com/dbt-labs/dbt-core/issues/7442)\n    - [Support constraints independently from enforcing a full model contract](https://github.com/dbt-labs/dbt-core/issues/10195)\n- and [warnings when configs are misspelled](https://github.com/dbt-labs/dbt-core/issues/8942) :)\n\n# [**Call me**, **beep me** if you wanna reach me](https://www.youtube.com/watch?v=GIgLqN_rAXU)\n\nIf one of *your* New Year’s resolutions is to be more involved in the dbt community, here are some of the many ways you can contribute:\n\n- open, upvote, and comment on GitHub [issues](https://docs.getdbt.com/community/resources/oss-expectations#issues)\n- start a [discussion](https://docs.getdbt.com/community/resources/oss-expectations#discussions) or discourse post when you’ve got a Big Idea\n- engage in conversations in the [dbt Community Slack](https://www.getdbt.com/community/join-the-community)\n- [contribute code](https://docs.getdbt.com/community/resources/oss-expectations#pull-requests) back to one of our open source repos, for one of our issues tagged `help_wanted` or `good_first_issue`, and our engineering team will work with you to get it over the finish line\n- join us on zoom for feedback sessions (which we’ll post about in slack and in the relevant GitHub discussion)\n- share your creative solutions in a blog post, at a dbt meetup, or by talking at Coalesce\n\nYour feedback and thoughts are incredibly valuable to us, so make yourself heard this year. We’re excited to build some awesome new features together. \n\n[Your loving wife](https://youtu.be/DC9sbZBYzpI?si=xCGWoQDK-w13Fz6U&t=1594), Grace\n"
  },
  {
    "path": "docs/roadmap/2025-05-new-engine-same-language.md",
    "content": "# dbt: New Engine, Same Language (May 2025)\n\nHello! Today was one of our biggest launches in dbt Labs history. We announced a bunch of new experiences for the dbt platform, which you can read about in [the roundup](https://www.getdbt.com/blog/dbt-launch-showcase-2025-recap).\n\nAnd we finally got to announce one big thing that we’ve been working on with [the team that joined us from SDF](https://www.getdbt.com/blog/dbt-labs-acquires-sdf-labs) — the **dbt Fusion engine**, written in Rust and optimized for speed and scale.\n\nSince [last December](https://github.com/dbt-labs/dbt-core/blob/main/docs/roadmap/2024-12-play-on.md), the Core team at dbt Labs has been busy developing new features for the [dbt Core v1.10 release](https://docs.getdbt.com/docs/dbt-versions/core-upgrade/upgrading-to-v1.10) (`rc1` available now!) …\n\n| **Version** | **When** | **Namesake** | **Stuff** |\n| --- | --- | --- | --- |\n| v1.10 | May (beta) | Florence Earle Coates | `--sample` mode. Catalogs. Macro argument validation. Calculate source freshness via a custom `loaded_at_query`. Deprecation warnings using new and improved jsonschemas. |\n\n… and **we’ve been building a [whole new dbt engine](https://github.com/dbt-labs/dbt-fusion) from the ground up**.\n\nFirst thing’s first:\n\n- We’re committed to maintaining dbt Core **indefinitely**, under the Apache 2.0 license.\n- Fusion will be available under ELv2. That means you can use Fusion internally in your own business, for free and without restriction, forever. A bunch of its components (dbt-jinja, adapters, grammars, specs) will also be available under Apache 2.0.\n- You can read all the fine print in the [Licensing FAQs](https://www.getdbt.com/licenses-faq).\n\nLet’s talk about what’s changing, and what’s staying the same.\n\n## What’s the difference between dbt Core and the new dbt Fusion engine?\n\nThe new dbt Fusion **engine** is brand-new code. It’s built for speed and SQL comprehension, meaning it already has some underlying capabilities that dbt Core doesn’t.\n\nThe **language** is the same: it’s dbt. It’s the language you’ve learned to do your job, and learned to love because it’s how you get your job done.\n\n```\n    .--------------.\n   / dbt language   \\\n  |    .--------.    |\n  |   /          \\   |\n  |  | dbt engine |  |  \n  |   \\          /   |\n  |    '--------'    |\n   \\                /\n    '--------------'\n\ncaption: the dbt framework\n```\n\nWe’ve written about this difference between “language” and the “engine” in the FAQs (linked above), and we’re going to give some more specific examples below. The really important message is this one:\n\nTogether, the **language** and the **engine** create **the dbt framework.**\n\n### What is the dbt language?\n\nThe “language” of dbt includes anything you can write in your dbt project. Some of us like to call this the “authoring layer” — what we mean is, *the code you can put in your project.* Every data test configuration, every unit test property, the `+` before configs in `dbt_project.yml`, everything you can put between `{% macro %}` and `{% endmacro %}` ([just one, though](https://github.com/dbt-labs/dbt-core/issues/11393)). The language also includes important abstractions, like the idea that one `.sql` file in the `models/` directory == one dbt model == one data warehouse object ([or none](https://docs.getdbt.com/docs/build/materializations#ephemeral)).\n\nThis language is really important. You’ve invested years into learning it, and you’ve used it to define your organization’s critical business logic. That’s why we’re committed to supporting, improving, and expanding the language across both dbt Core and Fusion.\n\nRecently, that has included important work to *tighten up* the language with stricter validation of your project code, as discussed in [dbt-core#11493](https://github.com/dbt-labs/dbt-core/discussions/11493). We want dbt to give more-helpful feedback when you misspell a config or write bad code in your project — a longtime paper-cut we are thrilled to at last be solving (see: [#2606,](https://github.com/dbt-labs/dbt-core/issues/2606) [#4280, #5605](https://github.com/dbt-labs/dbt-core/issues/5605), [#8942](https://github.com/dbt-labs/dbt-core/issues/8942)). dbt Core v1.10 is firing deprecation warnings, and Fusion will raise errors — and both engines are using the *same strongly-typed schemas* do it. Those schemas are live in the [dbt-jsonschema](https://github.com/dbt-labs/dbt-jsonschema/tree/main/schemas/latest_fusion) repo (under an Apache 2.0 license), and they’ll keep getting better as we work through prerelease feedback for dbt Core v1.10 and Fusion.\n\nWe also want to keep adding language features across both Core and Fusion. Because Fusion is newer technology and has additional capabilities, such as built-in SQL comprehension, some language features will be better or exclusively available on Fusion. Think: an _enhancement_ to `--sample` and `--empty` modes where the engine intelligently add filters and limits, [without the associated issues of subqueries](https://github.com/dbt-labs/dbt-adapters/issues/199).\n\n### What is the dbt engine?\n\nThe “engine” of dbt is the foundational technology for turning **the code in your dbt project into data platform reality*.* The engine:\n\n- takes your project code, validates it (against the dbt language spec), and turns it into a DAG\n- connects to remote data warehouse using **adapters**\n- executes that DAG in order — creating, updating, or queries data in the warehouse — based on the commands/flags/arguments you pass in\n- produces logs and metadata from that DAG execution\n\nThese things may differ across the dbt Core and Fusion engines. To ease the upgrade path, Fusion supports most of the same CLI commands/flags/arguments as dbt Core, and Fusion adapters support the same authentication methods as Core adapters. But we’re not planning for exact conformance on logs, metadata, and every single runtime behavior. \n\nTwo examples from [the upgrade guide](https://docs.getdbt.com/docs/dbt-versions/core-upgrade/upgrading-to-fusion):\n\n- Fusion can run unit tests first before building *any* models, because it can infer column schemas from SQL understanding.\n- There’s no `--partial-parse` flag for Fusion, because its project parsing is *just that much faster. (And it will manage the cache itself)*\n\nIf there are things you think are great about the dbt Core engine, and you want Fusion to meet the same need — let us know! We’ve got some tips at the end about how to engage with the next few months of Fusion development.\n\n## What’s next for dbt-the-language?\n\nWe’ve been building the new dbt Fusion engine since January, and we’ve still got plenty more to go. Our biggest focus area for the next few months is stabilizing and enhancing Fusion to support more of dbt's existing features, and more existing dbt projects. ([Joel and Jeremy wrote about Fusion’s path to GA](https://docs.getdbt.com/blog/dbt-fusion-engine-path-to-ga).)\n\nAt the same time, we know there’s appetite for new capabilities in the dbt language — including some ideas we’ve been talking about for a long time.\n\nImportantly, our goal isn’t just parity with dbt as it exists today. We intend to keep expanding the language, across both the Core and Fusion engines. In many cases, we will be able to deliver an even-better experience in Fusion, thanks to its speed and SQL awareness.\n\nThe exact specs here are TBD, but here are some features we’ve been thinking about adding:\n\n- **Out-of-the-box support for UDFs**\n- **Sources from external catalogs**\n- **Model freshness checks**\n- **…along with Bugs, Polish Work, and Paper Cuts**\n\nTo be clear, we’re not committing to building precisely these things on any specific timeline — our top priority is parity for the new engine, to support existing users and customers in upgrading to Fusion — but we’re including these ideas as an illustration of what the same-framework, multi-engine future could look like. We’d love your thoughts on these ideas — what would be most interesting/useful to you?\n\n### **Out-of-the-box support for UDFs**\n\nThe idea to manage user-defined functions (UDFs) with dbt is almost [as old as dbt](https://github.com/dbt-labs/dbt-core/issues/136) — and it’s one that has [come up](https://github.com/dbt-labs/dbt-core/discussions/5099) [every few](https://github.com/dbt-labs/dbt-core/discussions/5741) [years since](https://github.com/dbt-labs/dbt-core/discussions/10395).\n\nUDFs enable users to define and register custom functions within the warehouse. Like dbt macros, they enable DRY reuse of code; unlike macros, UDFs can be defined in languages other than SQL (Python, Java, Scala, …) and they can be used by queries outside of dbt.\n\nThere are two direct benefits to dbt-managed UDFs:\n\n1. dbt will manage (create, update, rename) UDFs as part of DAG execution. If you want to update a UDF *and* a model that calls it, you can test the changes together in a development environment; propose those changes in a single pull request that goes through CI; and deploy them together into your production environment. dbt will ensure that the UDF is created before attempting to build the model that references it. And we could even imagine supporting *unit tests* on UDFs — which are functions, after all!\n2. Fusion’s SQL comprehension is dialect-aware, but it is not yet *UDF-aware.* Today, if you call UDFs within a dbt model, you need to turn off Fusion’s static analysis for that model’s SQL. By supporting UDFs in the dbt framework, Fusion can also support them in its static analysis. We’re taking inspiration from Fusion’s antecedent, SDF, which supported UDFs for exactly this reason: https://docs.sdf.com/guide/advanced/udf\n\nImagine if the dbt framework knew about user-defined functions. The Core engine could manage the creation of UDFs as data warehouse objects. The Fusion engine could take it one step further, by *also* validating your UDFs’ SQL and statically analyzing the SQL of dbt models that call those UDFs. \n\n### **Sources from external catalogs**\n\nBack in December, we discussed ([dbt-core#11171](https://github.com/dbt-labs/dbt-core/discussions/11171)) our plans for integrating catalogs: Glue, Iceberg, Snowflake Managed, Unity, …\n\nOur goal was to centralize the configuration for materializing Iceberg tables, try to abstract over the minute differences between catalog providers (where possible), and teach dbt about a new top-level construct (`catalogs`).\n\nYou can check out [the docs on Iceberg catalogs](https://docs.getdbt.com/docs/mesh/iceberg/about-catalogs), new in dbt Core v1.10.\n\nThe first supported use case for external catalogs is around materializing dbt models *as Iceberg tables* by *writing them to catalogs* — but we know that another popular use case is reading from source tables that have been ingested to Iceberg catalogs, a.k.a. bringing the functionality of [read-external-iceberg from the dbt-labs-experimental-features](https://github.com/dbt-labs/dbt-labs-experimental-features/tree/main/read-external-iceberg) repository [into the dbt framework](https://github.com/dbt-labs/dbt-core/discussions/11265):\n\n```sql\nselect * from {{ source('my_catalog', 'my_iceberg_table') }}\n```\n\nYou can already hack this with the [experimental code](https://github.com/dbt-labs/dbt-labs-experimental-features/tree/main/read-external-iceberg) today — but we see an opportunity to build it into dbt out-of-the-box, and to standardize the configurations for everyone interacting with Iceberg tables, for both use cases (sources and models) in their dbt projects.\n\n### **Model freshness checks**\n\ndbt Core has supported `source freshness` checks since the [v0.13 release in 2019](https://github.com/dbt-labs/dbt-core/releases/tag/v0.13.0) (!). The idea, then and now, is: for tables that are updated by processes outside of dbt, the least dbt can do is ask, “How fresh is in the data in this table?”\n\nBy contrast, it should be simple for dbt to know the freshness in the models *that dbt is building*… right?\n\nIn practice, this can be trickier than you’d think! Multiple dbt invocations, split across different jobs/tasks/DAGs/schedules/orchestrators/projects/…, can result in confusion about when a model actually last built. Users have closed the gap with generic tests in popular packages, such as [dbt_utils.recency](https://github.com/dbt-labs/dbt-utils?tab=readme-ov-file#recency-source) and [dbt_expectations.expect_row_values_to_have_recent_data](https://github.com/metaplane/dbt-expectations?tab=readme-ov-file#expect_row_values_to_have_recent_data) — but the idea that [*dbt should know about model freshness*](https://github.com/dbt-labs/dbt-core/discussions/5103) is one we’ve tossed around a few times.\n\nThis is a case where we think we might be able to introduce a new language concept that powers a capability in both engines, and unlock something additional in Fusion. Imagine:\n\n- The dbt language introduces `freshness` as an optional config for models.\n- dbt Core, which is stateless, could execute `freshness` checks on models — using a configured column, or metadata from the data warehouse. Fusion could support this check, too.\n- And: When the dbt Fusion engine is connected to the dbt platform, [it can run with *state awareness*](https://docs.getdbt.com/docs/deploy/state-aware-about). Fusion checks the freshness of upstream data inputs, and users can configure `freshness.build_after` — to reduce overbuilding models when there’s no new data, or when users want to save costs by placing an upper limit on build frequency.\n\n```yaml\nmodels:\n  - name: stg_orders\n    config:\n      freshness:\n        # Fusion-powered state-aware orchestration: build this model after 4 hours, as long as it has new data\n        build_after: {count: 4, period: hour}\n        \n        # Future: check that model has successfully updated within expected SLA, warn/error owner otherwise\n        warn_after: {count: 24, period: hour}\n        error_after: {count: 48, period: hour}\n```\n\n### **Bugs, Polish Work, and Paper Cuts**\n\nAnd then, there’s everything else.\n\nWhile our team has been focused on the v1.10 release of dbt Core, and building the new dbt Fusion engine, we’ve had less capacity to triage every new issue and externally contributed PR. Thank you for your patience over the past five months — and thank you to the community members who gave us the feedback that we need to ensure maintenance even while working on the exciting new stuff.\n\nOver the coming months, alongside our work ensuring Fusion framework parity, we will be tracking our backlog of:\n\n- externally-contributed PRs\n- [polishing on microbatch](https://github.com/dbt-labs/dbt-core/issues/11292)\n- polishing on jsonschemas (the long-tail of adapter-specific configs)\n- `paper_cut`s\n\n## How can you, a community member, contribute?\n\nMostly, in all the same ways as before: [https://docs.getdbt.com/community/resources/contributor-expectations](https://docs.getdbt.com/community/resources/contributor-expectations)\n\nIn the next few weeks, we’d really like your help — trying out the new engine, mettle-testing the new jsonschemas against your project code, and opening up bug issues when you run into problems — as we get Fusion (and the stricter dbt language spec) ready for prime-time. \n\nYou can contribute your ideas by opening GitHub discussions or feature requests. While we’re focused on getting dbt Fusion to GA, we're going to keep the `dbt-fusion` repo focused on engine bugs and framework parity, so we’ll keep net-new feature requests in the `dbt-core` repo for the foreseeable future. Be on the lookout for GitHub discussions about new framework features, once we’re ready to start building.\n\nYou can contribute your code by opening pull requests against *any* of our repos — whether you’ve written Rust before, or you’re looking for an excuse to get started :)\n\n## Let’s get to work\n\nMaintaining a common framework across two codebases, written in entirely different languages, will be challenging. We’ve got some ideas for how to make this easier:\n\n- Core and Fusion are already sharing a set of strongly-typed jsonschemas defining the spec of acceptable project code inputs\n- Core adapters and Fusion adapters could share the same “packages” of macros and materializations\n- *… and more to come …*\n\nNo lie — it’s going to be tricky, any way we slice it. We’re going to keep figuring it out over the coming months, and we ask for your patience while we do.\n\nAfter all, [our commitment](https://www.youtube.com/watch?v=DC9sbZBYzpI) is to you, the community, not to any one codebase. We’re excited to welcome in some new codebases, and some new contributors, to this thing we’re all building together.\n\n(╭☞ ͡° ͜ʖ ͡°)╭☞\n\n**J**erco\n**E**lias\n**G**race\n"
  },
  {
    "path": "docs/roadmap/2025-12-magic-to-do.md",
    "content": "# dbt: Magic to Do (December 2025)\n\ndbt Core will turn in 10 in March 🥳. That’s almost a decade of `select`-ing, data-testing, and docs-generating.\n\nICYMI - [we threw a birthday bash for the dbt Community at Coalesce this year](https://www.youtube.com/watch?v=aMUAQjqTKtc), and we used the occasion to reflect on all the ways dbt has grown up:\n\nThere are now 2 engines: dbt Core (which will remain Apache 2.0 forever) and dbt Fusion (which uses a [mix of licenses](https://www.getdbt.com/blog/new-code-new-license-understanding-the-new-license-for-the-dbt-fusion-engine))...\n\n...And lots more Open Source code: [MetricFlow](https://www.getdbt.com/blog/open-source-metricflow-governed-metrics) (now Apache 2.0!), [Fusion adapters](https://github.com/dbt-labs/dbt-fusion), [dbt-jinja](https://github.com/dbt-labs/dbt-fusion/tree/main/crates/dbt-jinja), [jsonschemas](https://github.com/dbt-labs/dbt-jsonschema/tree/main/schemas/latest_fusion), and [dbt-autofix](https://github.com/dbt-labs/dbt-autofix).\n\nThe language is codified: `dbt-jinja` for the Jinja you can use in dbt, `jsonschemas` for yaml...\n\n...And will continue to grow, [with new features across Core and Fusion](https://www.youtube.com/watch?v=6lI9d-gPKW8).\n\nAs always, there is more ~~work~~ magic to do.\n\n# 2025 Wrapped\n\nIn 2025, we had: \n\n- **>90k** weekly active projects\n- **>10k** comments across over **>5k** issues from over **>1k** people across our open source and source available repos\n- **4** new product-led discussions:\n    - [Sample Mode (for faster Development and CI 🚀)](https://github.com/dbt-labs/dbt-core/discussions/11200)\n    - [Out-of-the-box support for UDFs](https://github.com/dbt-labs/dbt-core/discussions/11851)\n    - [UX Feedback on Logging and stdout](https://github.com/dbt-labs/dbt-fusion/discussions/584)\n    - [Source schemas should be first-class, versioned artifacts](https://github.com/dbt-labs/dbt-fusion/discussions/1042)\n- **10** [Community Awards](https://www.youtube.com/watch?v=I-DgySJ0Syg)\n- **1** [demo on roller skates](https://youtu.be/aMUAQjqTKtc?si=9ZCmz30wZ118HeHI&t=1116)\n\n    <img width=\"512\" height=\"341.5\" alt=\"picture of demo on roller skates\" src=\"https://github.com/user-attachments/assets/c3857e83-eca7-4b9d-a144-4638b05af564\" />\n    \n- **2** minor dbt Core releases\n    \n    \n    | **Version** | **When** | **Namesake** | **Stuff** |\n    | --- | --- | --- | --- |\n    | [v1.10](https://docs.getdbt.com/docs/dbt-versions/core-upgrade/upgrading-to-v1.10) | June | [Florence Earle Coates](https://github.com/dbt-labs/dbt-core/releases/tag/v1.10.0) | `--sample` mode. Catalogs. Macro argument validation. Calculate source freshness via a custom `loaded_at_query`. YAML `anchors:`. |\n    | [v1.11](https://docs.getdbt.com/docs/dbt-versions/core-upgrade/upgrading-to-v1.11) | December | [Juan R. Torruella](https://github.com/dbt-labs/dbt-core/releases/tag/v1.11.0) | User-defined functions. `cluster_by` for dynamic tables. Deprecation warnings using new and improved jsonschemas, enabled by default.  |\n- and **1** dbt community <3\n\n### New language features\n\nThis past year we added three big new language features to the dbt framework:\n\n- **[sample mode](https://docs.getdbt.com/docs/build/sample-flag)** renders filtered `ref`s and `source`s using time-based sampling, allowing developers to validate outputs without building entire historical datasets.\n- **[catalogs](https://docs.getdbt.com/docs/mesh/iceberg/about-catalogs)** abstraction for materializing dbt models as Iceberg tables, with a consistent set of configs (more on this below).\n- **[user-defined functions](https://docs.getdbt.com/docs/build/udfs)** as a new dbt resource type - allowing you to define custom functions in your project, call them in models, and register them in your warehouse as part of building your DAG.\n\nAll of these are supported now across BOTH engines - dbt Core and dbt Fusion.\n\nThe language is also now **codified** - **[new and improved jsonschemas](https://github.com/dbt-labs/dbt-jsonschema/tree/main/schemas/latest_fusion)** power warnings in Core (and errors in Fusion) to help you proactively identify and update deprecated configurations (such as misspelled config keys, old properties, or incorrect data types). \n\nThis stricter spec creates clearer separation between the built-in configurations of the dbt language (or flags/options of the dbt engine) and your custom code (nested under `meta`), reducing the risk of collisions as we continue to add new capabilities and configurations to the dbt framework in the future.\n\nBecause we plan to keep building dbt for a long time to come, and for that we need…\n\n### Stability\n\n[Two years ago](https://github.com/dbt-labs/dbt-core/blob/main/docs/roadmap/2023-11-dbt-tng.md), we saw that lots of projects were still running older versions of dbt Core, even as we pushed ahead with newer ones. Our top priority was making it easier to upgrade. To that end, we’ve made significant investments in interface stability, and updated the release cadence to 1 new minor version every 6 months.\n\nAll of that work has paid off: **Today, the majority of active dbt Core projects run on the latest minor version.** On December 1, >50% of projects were running on dbt Core `v1.10`, which we released in June. We just released `v1.11` this week, and we expect that the majority of projects will upgrade in the next 6 months.\n\nThis means that when we fix bugs in patch releases, or release exciting language features in new minor versions — such as UDFs in `v1.11` — more users can get *immediate* access to those fixes and features than ever before. It also means that more users can benefit from strongly-typed schemas for dbt’s properties and configurations. **And if those users want to try out the new Fusion engine while it’s in preview, they can.**\n\nIn order for the Fusion engine to work on your project, your dbt code will need to be compatible with the very latest language spec — which means resolving any deprecation warnings that you would have started seeing in dbt Core `v1.10` and `v1.11`. We have a tool that can help: [**`dbt-autofix`**](https://github.com/dbt-labs/dbt-autofix) scans your dbt project for deprecations, and automatically updates your code to align with the latest spec. \n\nWe closed out this year with \"De*bug*-cember\" - a month-long bug bash where we squashed 35 long-standing issues across parsing, execution, logging, error messages, and more in the lead up to the final `v1.11` release. (To see the full list, head over to #dbt-core-development in the community Slack.)\n\n<img width=\"604\" height=\"292\" alt=\"screenshot of slack post\" src=\"https://github.com/user-attachments/assets/e2ed08a4-7eef-4adc-a540-47a45d8e5e5a\" />\n\n# What’s in the Queue for 2026?\n\nOver the next six months, we’re adding a bunch of new team members (say hi to new faces as they pop up in slack and github). With their help, we’re eager to tackle the backlog of bugs and \"paper cuts\". You can upvote and comment on issues to help us prioritize!\n\nAs for bigger features…\n\nIn our roadmap post from May, we proposed three possibilities for \"[What’s next for dbt-the-language?](https://github.com/dbt-labs/dbt-core/blob/main/docs/roadmap/2025-05-new-engine-same-language.md#whats-next-for-dbt-the-language)\": \n\n1. Out-of-the-box support for UDFs\n2. Sources from external catalogs\n3. Model freshness checks\n\nWe tackled #1 in the `v1.11` release. \n\nWe intend to work on #3 next (github discussion coming soon).\n\nAs for #2… [Jeremy says \"it’s complicated\"](https://www.youtube.com/watch?v=bRJJkeJkUsE&t=1s):\n\n> We are always building dbt within the context of the larger data ecosystem. In summer 2024, Databricks and Snowflake acclaimed Iceberg as the most promising standard for interoperable data storage. Following the flurry of new Iceberg catalogs, we [proposed a spec](https://github.com/dbt-labs/dbt-core/discussions/11171), implemented in dbt Core `v1.10`, to configure those `catalogs` as a place to materialize dbt models.\n> \n> Over the past year, the major data warehouses have added support for writing tables to *external* Iceberg catalogs — and even for *synchronizing* metadata from those catalogs (e.g. with a Snowflake [catalog-linked database](https://docs.snowflake.com/en/user-guide/tables-iceberg-catalog-linked-database)) so that you can treat their contents like any other table. This makes it substantially easier to treat Iceberg as [just another implementation detail](https://docs.getdbt.com/blog/icebeg-is-an-implementation-detail), and as the interchange layer for [cross-platform workflows](https://www.getdbt.com/blog/introducing-cross-platform-dbt-mesh).\n> \n> It also means that other features of dbt \"just work.\" Earlier this year, we added an [experimental feature](https://github.com/dbt-labs/dbt-labs-experimental-features/tree/main/read-external-iceberg) for registering and refreshing Iceberg tables (à la `dbt-external-sources`), and in our May roadmap we proposed \"sources from external catalogs\" as a potential new feature of the dbt language. But if the underlying data warehouse can synchronize tables with an external Iceberg catalog automatically, then `sources` pointing to tables in an external Iceberg catalog already work, without any changes to the dbt language. That’s not the full end of the story — Iceberg requires a lot of setup (could dbt help here?) and careful optimization (might it be faster/cheaper to batch-calculate `freshness` by integrating with an Iceberg REST catalog directly, rather than querying the data warehouse?) — it warrants more time and testing. The plan is to keep evolving dbt along with the Iceberg ecosystem in 2026.\n\nLast-but-not-least, we will continue to invest in improving the stability of dbt Core. There’s much more we can improve about:\n\n- the interfaces shared between Core and Fusion\n- the integration between dbt Core and MetricFlow, [now that the latter is Apache 2.0 too](https://www.getdbt.com/blog/open-source-metricflow-governed-metrics)\n- the ease of contributing to our open source and source-available codebases\n\n# [Join us, leave your fields to flower](https://www.youtube.com/watch?v=AqbYa-NXFOg)\n\nLooking for ways to get involved in the dbt community? \n\n- give or get help in the [community slack](https://www.getdbt.com/community/join-the-community)\n- open up bug reports, feature requests, or discussions in our repos: [dbt-core](https://github.com/dbt-labs/dbt-core), [dbt-adapters](https://github.com/dbt-labs/dbt-adapters) (our new Core adapters monorepo), and [dbt-fusion](https://github.com/dbt-labs/dbt-fusion) are great places to start\n- join zoom feedback sessions to help shape new features coming to dbt\n- follow along with Fusion progress by [reading our diaries](https://github.com/dbt-labs/dbt-fusion/discussions/categories/announcements) and [subscribing to our linkedin newsletter](https://www.linkedin.com/newsletters/fusion-diaries-7366935294090084360/)\n- find community in-person at our [dbt meetups](https://www.meetup.com/pro/dbt/) and [roadshows](https://www.getdbt.com/events), all around the world\n\nSee you in the new year,\n\nyour neighborhood theater kids (Jerco & Grace)\n\n<img width=\"512\" height=\"341.5\" alt=\"picture of jerco and grace running away\" src=\"https://github.com/user-attachments/assets/425221e9-aac0-4e5a-a115-0f8dba4cd2e7\" />\n"
  },
  {
    "path": "hatch.toml",
    "content": "# Root-level hatch.toml - warns users to run from core/ directory\n# The actual hatch configuration is in core/hatch.toml\n\n[envs.default]\nskip-install = true\ndependencies = []\n\n[envs.default.scripts]\nsetup = \"echo '⚠️  Error: hatch must be run from the core/ directory, not the repo root.\\n\\nRun:\\n  cd core && hatch run setup' && exit 1\"\ndev-req = \"echo '⚠️  Error: hatch must be run from the core/ directory, not the repo root.\\n\\nRun:\\n  cd core && hatch run dev-req' && exit 1\"\ncode-quality = \"echo '⚠️  Error: hatch must be run from the core/ directory, not the repo root.\\n\\nRun:\\n  cd core && hatch run code-quality' && exit 1\"\nlint = \"echo '⚠️  Error: hatch must be run from the core/ directory, not the repo root.\\n\\nRun:\\n  cd core && hatch run lint' && exit 1\"\nflake8 = \"echo '⚠️  Error: hatch must be run from the core/ directory, not the repo root.\\n\\nRun:\\n  cd core && hatch run flake8' && exit 1\"\nmypy = \"echo '⚠️  Error: hatch must be run from the core/ directory, not the repo root.\\n\\nRun:\\n  cd core && hatch run mypy' && exit 1\"\nblack = \"echo '⚠️  Error: hatch must be run from the core/ directory, not the repo root.\\n\\nRun:\\n  cd core && hatch run black' && exit 1\"\nunit-tests = \"echo '⚠️  Error: hatch must be run from the core/ directory, not the repo root.\\n\\nRun:\\n  cd core && hatch run unit-tests' && exit 1\"\nintegration-tests = \"echo '⚠️  Error: hatch must be run from the core/ directory, not the repo root.\\n\\nRun:\\n  cd core && hatch run integration-tests' && exit 1\"\nintegration-tests-fail-fast = \"echo '⚠️  Error: hatch must be run from the core/ directory, not the repo root.\\n\\nRun:\\n  cd core && hatch run integration-tests-fail-fast' && exit 1\"\ntest = \"echo '⚠️  Error: hatch must be run from the core/ directory, not the repo root.\\n\\nRun:\\n  cd core && hatch run test' && exit 1\"\nsetup-db = \"echo '⚠️  Error: hatch must be run from the core/ directory, not the repo root.\\n\\nRun:\\n  cd core && hatch run setup-db' && exit 1\"\nclean = \"echo '⚠️  Error: hatch must be run from the core/ directory, not the repo root.\\n\\nRun:\\n  cd core && hatch run clean' && exit 1\"\njson-schema = \"echo '⚠️  Error: hatch must be run from the core/ directory, not the repo root.\\n\\nRun:\\n  cd core && hatch run json-schema' && exit 1\"\n\n[envs.build]\nskip-install = true\ndependencies = []\n\n[envs.build.scripts]\ncheck-all = \"echo '⚠️  Error: hatch must be run from the core/ directory, not the repo root.\\n\\nRun:\\n  cd core && hatch run build:check-all' && exit 1\"\ncheck-wheel = \"echo '⚠️  Error: hatch must be run from the core/ directory, not the repo root.\\n\\nRun:\\n  cd core && hatch run build:check-wheel' && exit 1\"\ncheck-sdist = \"echo '⚠️  Error: hatch must be run from the core/ directory, not the repo root.\\n\\nRun:\\n  cd core && hatch run build:check-sdist' && exit 1\"\n\n[envs.ci]\nskip-install = true\ndependencies = []\n\n[envs.ci.scripts]\nunit-tests = \"echo '⚠️  Error: hatch must be run from the core/ directory, not the repo root.\\n\\nRun:\\n  cd core && hatch run ci:unit-tests' && exit 1\"\ncode-quality = \"echo '⚠️  Error: hatch must be run from the core/ directory, not the repo root.\\n\\nRun:\\n  cd core && hatch run ci:code-quality' && exit 1\"\nintegration-tests = \"echo '⚠️  Error: hatch must be run from the core/ directory, not the repo root.\\n\\nRun:\\n  cd core && hatch run ci:integration-tests' && exit 1\"\n"
  },
  {
    "path": "pyproject.toml",
    "content": "# Root-level pyproject.toml for tool configurations\n# Packaging configuration is in core/pyproject.toml\n# This file exists so tools like mypy and black can find their config when run from root\n\n[tool.mypy]\n# TODO: widen range of files as we fix issues\nfiles = 'core/dbt'\nmypy_path = \"third-party-stubs/\"\nnamespace_packages = true\n\n[tool.black]\nline-length = 99\ntarget-version = ['py38']\n\n# flake8 config is in .flake8 (flake8 4.0.1 has limited pyproject.toml support).  Add here when we add support for flake8 >=5\n\n[tool.isort]\nprofile = \"black\"\nextend_skip_glob = [\n    \".github/*\",\n    \"third-party-stubs/*\",\n    \"scripts/*\",\n]\nknown_first_party = [\n    \"dbt\",\n    \"dbt_adapters\",\n    \"dbt_common\",\n    \"dbt_extractor\",\n    \"dbt_semantic_interfaces\",\n]\n"
  },
  {
    "path": "pytest.ini",
    "content": "[pytest]\nfilterwarnings =\n    ignore:.*'soft_unicode' has been renamed to 'soft_str'*:DeprecationWarning\n    ignore:unclosed file .*:ResourceWarning\nenv_files =\n    test.env\ntestpaths =\n    tests/functional\n    tests/unit\npythonpath = core\n"
  },
  {
    "path": "requirements.txt",
    "content": "./core\n"
  },
  {
    "path": "schemas/dbt/catalog/v1.json",
    "content": "{\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"type\": \"object\",\n  \"title\": \"CatalogArtifact\",\n  \"properties\": {\n    \"metadata\": {\n      \"type\": \"object\",\n      \"title\": \"CatalogMetadata\",\n      \"properties\": {\n        \"dbt_schema_version\": {\n          \"type\": \"string\"\n        },\n        \"dbt_version\": {\n          \"type\": \"string\",\n          \"default\": \"1.12.0a1\"\n        },\n        \"generated_at\": {\n          \"type\": \"string\"\n        },\n        \"invocation_id\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"invocation_started_at\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"env\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          },\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"nodes\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"type\": \"object\",\n        \"title\": \"CatalogTable\",\n        \"properties\": {\n          \"metadata\": {\n            \"type\": \"object\",\n            \"title\": \"TableMetadata\",\n            \"properties\": {\n              \"type\": {\n                \"type\": \"string\"\n              },\n              \"schema\": {\n                \"type\": \"string\"\n              },\n              \"name\": {\n                \"type\": \"string\"\n              },\n              \"database\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"comment\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"owner\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              }\n            },\n            \"additionalProperties\": false,\n            \"required\": [\n              \"type\",\n              \"schema\",\n              \"name\"\n            ]\n          },\n          \"columns\": {\n            \"type\": \"object\",\n            \"additionalProperties\": {\n              \"type\": \"object\",\n              \"title\": \"ColumnMetadata\",\n              \"properties\": {\n                \"type\": {\n                  \"type\": \"string\"\n                },\n                \"index\": {\n                  \"type\": \"integer\"\n                },\n                \"name\": {\n                  \"type\": \"string\"\n                },\n                \"comment\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"string\"\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                }\n              },\n              \"additionalProperties\": false,\n              \"required\": [\n                \"type\",\n                \"index\",\n                \"name\"\n              ]\n            },\n            \"propertyNames\": {\n              \"type\": \"string\"\n            }\n          },\n          \"stats\": {\n            \"type\": \"object\",\n            \"additionalProperties\": {\n              \"type\": \"object\",\n              \"title\": \"StatsItem\",\n              \"properties\": {\n                \"id\": {\n                  \"type\": \"string\"\n                },\n                \"label\": {\n                  \"type\": \"string\"\n                },\n                \"value\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"boolean\"\n                    },\n                    {\n                      \"type\": \"string\"\n                    },\n                    {\n                      \"type\": \"number\"\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ]\n                },\n                \"include\": {\n                  \"type\": \"boolean\"\n                },\n                \"description\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"string\"\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                }\n              },\n              \"additionalProperties\": false,\n              \"required\": [\n                \"id\",\n                \"label\",\n                \"value\",\n                \"include\"\n              ]\n            },\n            \"propertyNames\": {\n              \"type\": \"string\"\n            }\n          },\n          \"unique_id\": {\n            \"anyOf\": [\n              {\n                \"type\": \"string\"\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          }\n        },\n        \"additionalProperties\": false,\n        \"required\": [\n          \"metadata\",\n          \"columns\",\n          \"stats\"\n        ]\n      },\n      \"propertyNames\": {\n        \"type\": \"string\"\n      }\n    },\n    \"sources\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"type\": \"object\",\n        \"title\": \"CatalogTable\",\n        \"properties\": {\n          \"metadata\": {\n            \"type\": \"object\",\n            \"title\": \"TableMetadata\",\n            \"properties\": {\n              \"type\": {\n                \"type\": \"string\"\n              },\n              \"schema\": {\n                \"type\": \"string\"\n              },\n              \"name\": {\n                \"type\": \"string\"\n              },\n              \"database\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"comment\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"owner\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              }\n            },\n            \"additionalProperties\": false,\n            \"required\": [\n              \"type\",\n              \"schema\",\n              \"name\"\n            ]\n          },\n          \"columns\": {\n            \"type\": \"object\",\n            \"additionalProperties\": {\n              \"type\": \"object\",\n              \"title\": \"ColumnMetadata\",\n              \"properties\": {\n                \"type\": {\n                  \"type\": \"string\"\n                },\n                \"index\": {\n                  \"type\": \"integer\"\n                },\n                \"name\": {\n                  \"type\": \"string\"\n                },\n                \"comment\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"string\"\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                }\n              },\n              \"additionalProperties\": false,\n              \"required\": [\n                \"type\",\n                \"index\",\n                \"name\"\n              ]\n            },\n            \"propertyNames\": {\n              \"type\": \"string\"\n            }\n          },\n          \"stats\": {\n            \"type\": \"object\",\n            \"additionalProperties\": {\n              \"type\": \"object\",\n              \"title\": \"StatsItem\",\n              \"properties\": {\n                \"id\": {\n                  \"type\": \"string\"\n                },\n                \"label\": {\n                  \"type\": \"string\"\n                },\n                \"value\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"boolean\"\n                    },\n                    {\n                      \"type\": \"string\"\n                    },\n                    {\n                      \"type\": \"number\"\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ]\n                },\n                \"include\": {\n                  \"type\": \"boolean\"\n                },\n                \"description\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"string\"\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                }\n              },\n              \"additionalProperties\": false,\n              \"required\": [\n                \"id\",\n                \"label\",\n                \"value\",\n                \"include\"\n              ]\n            },\n            \"propertyNames\": {\n              \"type\": \"string\"\n            }\n          },\n          \"unique_id\": {\n            \"anyOf\": [\n              {\n                \"type\": \"string\"\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          }\n        },\n        \"additionalProperties\": false,\n        \"required\": [\n          \"metadata\",\n          \"columns\",\n          \"stats\"\n        ]\n      },\n      \"propertyNames\": {\n        \"type\": \"string\"\n      }\n    },\n    \"errors\": {\n      \"anyOf\": [\n        {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        {\n          \"type\": \"null\"\n        }\n      ],\n      \"default\": null\n    },\n    \"_compile_results\": {\n      \"anyOf\": [\n        {},\n        {\n          \"type\": \"null\"\n        }\n      ],\n      \"default\": null\n    }\n  },\n  \"additionalProperties\": false,\n  \"required\": [\n    \"metadata\",\n    \"nodes\",\n    \"sources\"\n  ],\n  \"$id\": \"https://schemas.getdbt.com/dbt/catalog/v1.json\"\n}\n"
  },
  {
    "path": "schemas/dbt/manifest/v10.json",
    "content": "{\n  \"type\": \"object\",\n  \"required\": [\n    \"metadata\",\n    \"nodes\",\n    \"sources\",\n    \"macros\",\n    \"docs\",\n    \"exposures\",\n    \"metrics\",\n    \"groups\",\n    \"selectors\",\n    \"semantic_models\"\n  ],\n  \"properties\": {\n    \"metadata\": {\n      \"$ref\": \"#/definitions/ManifestMetadata\",\n      \"description\": \"Metadata about the manifest\"\n    },\n    \"nodes\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"oneOf\": [\n          {\n            \"$ref\": \"#/definitions/AnalysisNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/SingularTestNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/HookNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/ModelNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/RPCNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/SqlNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/GenericTestNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/SnapshotNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/SeedNode\"\n          }\n        ]\n      },\n      \"description\": \"The nodes defined in the dbt project and its dependencies\"\n    },\n    \"sources\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/SourceDefinition\"\n      },\n      \"description\": \"The sources defined in the dbt project and its dependencies\"\n    },\n    \"macros\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/Macro\"\n      },\n      \"description\": \"The macros defined in the dbt project and its dependencies\"\n    },\n    \"docs\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/Documentation\"\n      },\n      \"description\": \"The docs defined in the dbt project and its dependencies\"\n    },\n    \"exposures\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/Exposure\"\n      },\n      \"description\": \"The exposures defined in the dbt project and its dependencies\"\n    },\n    \"metrics\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/Metric\"\n      },\n      \"description\": \"The metrics defined in the dbt project and its dependencies\"\n    },\n    \"groups\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/Group\"\n      },\n      \"description\": \"The groups defined in the dbt project\"\n    },\n    \"selectors\": {\n      \"type\": \"object\",\n      \"description\": \"The selectors defined in selectors.yml\"\n    },\n    \"disabled\": {\n      \"oneOf\": [\n        {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"oneOf\": [\n                {\n                  \"$ref\": \"#/definitions/AnalysisNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/SingularTestNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/HookNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/ModelNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/RPCNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/SqlNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/GenericTestNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/SnapshotNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/SeedNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/SourceDefinition\"\n                },\n                {\n                  \"$ref\": \"#/definitions/Exposure\"\n                },\n                {\n                  \"$ref\": \"#/definitions/Metric\"\n                },\n                {\n                  \"$ref\": \"#/definitions/SemanticModel\"\n                }\n              ]\n            }\n          }\n        },\n        {\n          \"type\": \"null\"\n        }\n      ],\n      \"description\": \"A mapping of the disabled nodes in the target\"\n    },\n    \"parent_map\": {\n      \"oneOf\": [\n        {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          }\n        },\n        {\n          \"type\": \"null\"\n        }\n      ],\n      \"description\": \"A mapping from\\u00a0child nodes to their dependencies\"\n    },\n    \"child_map\": {\n      \"oneOf\": [\n        {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          }\n        },\n        {\n          \"type\": \"null\"\n        }\n      ],\n      \"description\": \"A mapping from parent nodes to their dependents\"\n    },\n    \"group_map\": {\n      \"oneOf\": [\n        {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          }\n        },\n        {\n          \"type\": \"null\"\n        }\n      ],\n      \"description\": \"A mapping from group names to their nodes\"\n    },\n    \"semantic_models\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/SemanticModel\"\n      },\n      \"description\": \"The semantic models defined in the dbt project\"\n    }\n  },\n  \"additionalProperties\": false,\n  \"description\": \"WritableManifest(metadata: dbt.contracts.graph.manifest.ManifestMetadata, nodes: Mapping[str, Union[dbt.contracts.graph.nodes.AnalysisNode, dbt.contracts.graph.nodes.SingularTestNode, dbt.contracts.graph.nodes.HookNode, dbt.contracts.graph.nodes.ModelNode, dbt.contracts.graph.nodes.RPCNode, dbt.contracts.graph.nodes.SqlNode, dbt.contracts.graph.nodes.GenericTestNode, dbt.contracts.graph.nodes.SnapshotNode, dbt.contracts.graph.nodes.SeedNode]], sources: Mapping[str, dbt.contracts.graph.nodes.SourceDefinition], macros: Mapping[str, dbt.contracts.graph.nodes.Macro], docs: Mapping[str, dbt.contracts.graph.nodes.Documentation], exposures: Mapping[str, dbt.contracts.graph.nodes.Exposure], metrics: Mapping[str, dbt.contracts.graph.nodes.Metric], groups: Mapping[str, dbt.contracts.graph.nodes.Group], selectors: Mapping[str, Any], disabled: Union[Mapping[str, List[Union[dbt.contracts.graph.nodes.AnalysisNode, dbt.contracts.graph.nodes.SingularTestNode, dbt.contracts.graph.nodes.HookNode, dbt.contracts.graph.nodes.ModelNode, dbt.contracts.graph.nodes.RPCNode, dbt.contracts.graph.nodes.SqlNode, dbt.contracts.graph.nodes.GenericTestNode, dbt.contracts.graph.nodes.SnapshotNode, dbt.contracts.graph.nodes.SeedNode, dbt.contracts.graph.nodes.SourceDefinition, dbt.contracts.graph.nodes.Exposure, dbt.contracts.graph.nodes.Metric, dbt.contracts.graph.nodes.SemanticModel]]], NoneType], parent_map: Union[Dict[str, List[str]], NoneType], child_map: Union[Dict[str, List[str]], NoneType], group_map: Union[Dict[str, List[str]], NoneType], semantic_models: Mapping[str, dbt.contracts.graph.nodes.SemanticModel])\",\n  \"definitions\": {\n    \"ManifestMetadata\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"dbt_schema_version\": {\n          \"type\": \"string\",\n          \"default\": \"https://schemas.getdbt.com/dbt/manifest/v10.json\"\n        },\n        \"dbt_version\": {\n          \"type\": \"string\",\n          \"default\": \"1.6.5\"\n        },\n        \"generated_at\": {\n          \"type\": \"string\",\n          \"format\": \"date-time\",\n          \"default\": \"2023-10-05T00:33:14.410024Z\"\n        },\n        \"invocation_id\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": \"603e2fae-9c7d-4d17-8530-7d28c9875263\"\n        },\n        \"env\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          },\n          \"default\": {}\n        },\n        \"project_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"description\": \"Name of the root project\"\n        },\n        \"project_id\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"description\": \"A unique identifier for the project, hashed from the project name\"\n        },\n        \"user_id\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\",\n              \"pattern\": \"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"description\": \"A unique identifier for the user\"\n        },\n        \"send_anonymous_usage_stats\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"description\": \"Whether dbt is configured to send anonymous usage statistics\"\n        },\n        \"adapter_type\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"description\": \"The type name of the adapter\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Metadata for the manifest.\"\n    },\n    \"AnalysisNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"schema\",\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"analysis\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"group\": null,\n            \"materialized\": \"view\",\n            \"incremental_strategy\": null,\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"on_configuration_change\": \"apply\",\n            \"grants\": {},\n            \"packages\": [],\n            \"docs\": {\n              \"show\": true,\n              \"node_color\": null\n            },\n            \"contract\": {\n              \"enforced\": false\n            },\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"group\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1696465994.411958\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"raw_code\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"language\": {\n          \"type\": \"string\",\n          \"default\": \"sql\"\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/RefArgs\"\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"compiled_code\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"contract\": {\n          \"$ref\": \"#/definitions/Contract\",\n          \"default\": {\n            \"enforced\": false,\n            \"checksum\": null\n          }\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"AnalysisNode(database: Union[str, NoneType], schema: str, name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, fqn: List[str], alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.nodes.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, group: Union[str, NoneType] = None, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, relation_name: Union[str, NoneType] = None, raw_code: str = '', language: str = 'sql', refs: List[dbt.contracts.graph.nodes.RefArgs] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.nodes.DependsOn = <factory>, compiled_path: Union[str, NoneType] = None, compiled: bool = False, compiled_code: Union[str, NoneType] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.nodes.InjectedCTE] = <factory>, _pre_injected_sql: Union[str, NoneType] = None, contract: dbt.contracts.graph.nodes.Contract = <factory>)\"\n    },\n    \"FileHash\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"type\": \"string\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"FileHash(name: str, checksum: str)\"\n    },\n    \"NodeConfig\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"alias\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tags\": {\n          \"oneOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"string\"\n            }\n          ],\n          \"default\": []\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"group\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"materialized\": {\n          \"type\": \"string\",\n          \"default\": \"view\"\n        },\n        \"incremental_strategy\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"persist_docs\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"post-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Hook\"\n          },\n          \"default\": []\n        },\n        \"pre-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Hook\"\n          },\n          \"default\": []\n        },\n        \"quoting\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"column_types\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"full_refresh\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"unique_key\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"on_schema_change\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": \"ignore\"\n        },\n        \"on_configuration_change\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"apply\",\n            \"continue\",\n            \"fail\"\n          ],\n          \"default\": \"apply\"\n        },\n        \"grants\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"packages\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"contract\": {\n          \"$ref\": \"#/definitions/ContractConfig\",\n          \"default\": {\n            \"enforced\": false\n          }\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"NodeConfig(_extra: Dict[str, Any] = <factory>, enabled: bool = True, alias: Union[str, NoneType] = None, schema: Union[str, NoneType] = None, database: Union[str, NoneType] = None, tags: Union[List[str], str] = <factory>, meta: Dict[str, Any] = <factory>, group: Union[str, NoneType] = None, materialized: str = 'view', incremental_strategy: Union[str, NoneType] = None, persist_docs: Dict[str, Any] = <factory>, post_hook: List[dbt.contracts.graph.model_config.Hook] = <factory>, pre_hook: List[dbt.contracts.graph.model_config.Hook] = <factory>, quoting: Dict[str, Any] = <factory>, column_types: Dict[str, Any] = <factory>, full_refresh: Union[bool, NoneType] = None, unique_key: Union[str, List[str], NoneType] = None, on_schema_change: Union[str, NoneType] = 'ignore', on_configuration_change: dbt.contracts.graph.model_config.OnConfigurationChangeOption = <factory>, grants: Dict[str, Any] = <factory>, packages: List[str] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, contract: dbt.contracts.graph.model_config.ContractConfig = <factory>)\"\n    },\n    \"Hook\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"sql\"\n      ],\n      \"properties\": {\n        \"sql\": {\n          \"type\": \"string\"\n        },\n        \"transaction\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"index\": {\n          \"oneOf\": [\n            {\n              \"type\": \"integer\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Hook(sql: str, transaction: bool = True, index: Union[int, NoneType] = None)\"\n    },\n    \"Docs\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"show\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"node_color\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Docs(show: bool = True, node_color: Union[str, NoneType] = None)\"\n    },\n    \"ContractConfig\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"enforced\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ContractConfig(enforced: bool = False)\"\n    },\n    \"ColumnInfo\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"data_type\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"constraints\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/ColumnLevelConstraint\"\n          },\n          \"default\": []\n        },\n        \"quote\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"Used in all ManifestNodes and SourceDefinition\"\n    },\n    \"ColumnLevelConstraint\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"type\"\n      ],\n      \"properties\": {\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"check\",\n            \"not_null\",\n            \"unique\",\n            \"primary_key\",\n            \"foreign_key\",\n            \"custom\"\n          ]\n        },\n        \"name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"expression\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"warn_unenforced\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"warn_unsupported\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ColumnLevelConstraint(type: dbt.contracts.graph.nodes.ConstraintType, name: Union[str, NoneType] = None, expression: Union[str, NoneType] = None, warn_unenforced: bool = True, warn_unsupported: bool = True)\"\n    },\n    \"RefArgs\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"package\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"version\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"number\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"RefArgs(name: str, package: Union[str, NoneType] = None, version: Union[str, float, NoneType] = None)\"\n    },\n    \"DependsOn\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"macros\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"nodes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"DependsOn(macros: List[str] = <factory>, nodes: List[str] = <factory>)\"\n    },\n    \"InjectedCTE\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"id\",\n        \"sql\"\n      ],\n      \"properties\": {\n        \"id\": {\n          \"type\": \"string\"\n        },\n        \"sql\": {\n          \"type\": \"string\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Used in CompiledNodes as part of ephemeral model processing\"\n    },\n    \"Contract\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"enforced\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"checksum\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Contract(enforced: bool = False, checksum: Union[str, NoneType] = None)\"\n    },\n    \"SingularTestNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"schema\",\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"test\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/TestConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": \"dbt_test__audit\",\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"group\": null,\n            \"materialized\": \"test\",\n            \"severity\": \"ERROR\",\n            \"store_failures\": null,\n            \"where\": null,\n            \"limit\": null,\n            \"fail_calc\": \"count(*)\",\n            \"warn_if\": \"!= 0\",\n            \"error_if\": \"!= 0\"\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"group\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1696465994.413604\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"raw_code\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"language\": {\n          \"type\": \"string\",\n          \"default\": \"sql\"\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/RefArgs\"\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"compiled_code\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"contract\": {\n          \"$ref\": \"#/definitions/Contract\",\n          \"default\": {\n            \"enforced\": false,\n            \"checksum\": null\n          }\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"SingularTestNode(database: Union[str, NoneType], schema: str, name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, fqn: List[str], alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.TestConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.nodes.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, group: Union[str, NoneType] = None, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, relation_name: Union[str, NoneType] = None, raw_code: str = '', language: str = 'sql', refs: List[dbt.contracts.graph.nodes.RefArgs] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.nodes.DependsOn = <factory>, compiled_path: Union[str, NoneType] = None, compiled: bool = False, compiled_code: Union[str, NoneType] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.nodes.InjectedCTE] = <factory>, _pre_injected_sql: Union[str, NoneType] = None, contract: dbt.contracts.graph.nodes.Contract = <factory>)\"\n    },\n    \"TestConfig\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"alias\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": \"dbt_test__audit\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tags\": {\n          \"oneOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"string\"\n            }\n          ],\n          \"default\": []\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"group\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"materialized\": {\n          \"type\": \"string\",\n          \"default\": \"test\"\n        },\n        \"severity\": {\n          \"type\": \"string\",\n          \"pattern\": \"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$\",\n          \"default\": \"ERROR\"\n        },\n        \"store_failures\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"where\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"limit\": {\n          \"oneOf\": [\n            {\n              \"type\": \"integer\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"fail_calc\": {\n          \"type\": \"string\",\n          \"default\": \"count(*)\"\n        },\n        \"warn_if\": {\n          \"type\": \"string\",\n          \"default\": \"!= 0\"\n        },\n        \"error_if\": {\n          \"type\": \"string\",\n          \"default\": \"!= 0\"\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"TestConfig(_extra: Dict[str, Any] = <factory>, enabled: bool = True, alias: Union[str, NoneType] = None, schema: Union[str, NoneType] = 'dbt_test__audit', database: Union[str, NoneType] = None, tags: Union[List[str], str] = <factory>, meta: Dict[str, Any] = <factory>, group: Union[str, NoneType] = None, materialized: str = 'test', severity: dbt.contracts.graph.model_config.Severity = 'ERROR', store_failures: Union[bool, NoneType] = None, where: Union[str, NoneType] = None, limit: Union[int, NoneType] = None, fail_calc: str = 'count(*)', warn_if: str = '!= 0', error_if: str = '!= 0')\"\n    },\n    \"HookNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"schema\",\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"operation\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"group\": null,\n            \"materialized\": \"view\",\n            \"incremental_strategy\": null,\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"on_configuration_change\": \"apply\",\n            \"grants\": {},\n            \"packages\": [],\n            \"docs\": {\n              \"show\": true,\n              \"node_color\": null\n            },\n            \"contract\": {\n              \"enforced\": false\n            },\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"group\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1696465994.414359\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"raw_code\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"language\": {\n          \"type\": \"string\",\n          \"default\": \"sql\"\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/RefArgs\"\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"compiled_code\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"contract\": {\n          \"$ref\": \"#/definitions/Contract\",\n          \"default\": {\n            \"enforced\": false,\n            \"checksum\": null\n          }\n        },\n        \"index\": {\n          \"oneOf\": [\n            {\n              \"type\": \"integer\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"HookNode(database: Union[str, NoneType], schema: str, name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, fqn: List[str], alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.nodes.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, group: Union[str, NoneType] = None, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, relation_name: Union[str, NoneType] = None, raw_code: str = '', language: str = 'sql', refs: List[dbt.contracts.graph.nodes.RefArgs] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.nodes.DependsOn = <factory>, compiled_path: Union[str, NoneType] = None, compiled: bool = False, compiled_code: Union[str, NoneType] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.nodes.InjectedCTE] = <factory>, _pre_injected_sql: Union[str, NoneType] = None, contract: dbt.contracts.graph.nodes.Contract = <factory>, index: Union[int, NoneType] = None)\"\n    },\n    \"ModelNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"schema\",\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"model\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"group\": null,\n            \"materialized\": \"view\",\n            \"incremental_strategy\": null,\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"on_configuration_change\": \"apply\",\n            \"grants\": {},\n            \"packages\": [],\n            \"docs\": {\n              \"show\": true,\n              \"node_color\": null\n            },\n            \"contract\": {\n              \"enforced\": false\n            },\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"group\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1696465994.4150689\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"raw_code\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"language\": {\n          \"type\": \"string\",\n          \"default\": \"sql\"\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/RefArgs\"\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"compiled_code\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"contract\": {\n          \"$ref\": \"#/definitions/Contract\",\n          \"default\": {\n            \"enforced\": false,\n            \"checksum\": null\n          }\n        },\n        \"access\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"private\",\n            \"protected\",\n            \"public\"\n          ],\n          \"default\": \"protected\"\n        },\n        \"constraints\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/ModelLevelConstraint\"\n          },\n          \"default\": []\n        },\n        \"version\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"number\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"latest_version\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"number\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deprecation_date\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\",\n              \"format\": \"date-time\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"defer_relation\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/DeferRelation\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ModelNode(database: Union[str, NoneType], schema: str, name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, fqn: List[str], alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.nodes.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, group: Union[str, NoneType] = None, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, relation_name: Union[str, NoneType] = None, raw_code: str = '', language: str = 'sql', refs: List[dbt.contracts.graph.nodes.RefArgs] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.nodes.DependsOn = <factory>, compiled_path: Union[str, NoneType] = None, compiled: bool = False, compiled_code: Union[str, NoneType] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.nodes.InjectedCTE] = <factory>, _pre_injected_sql: Union[str, NoneType] = None, contract: dbt.contracts.graph.nodes.Contract = <factory>, access: dbt.node_types.AccessType = <AccessType.Protected: 'protected'>, constraints: List[dbt.contracts.graph.nodes.ModelLevelConstraint] = <factory>, version: Union[str, float, NoneType] = None, latest_version: Union[str, float, NoneType] = None, deprecation_date: Union[datetime.datetime, NoneType] = None, defer_relation: Union[dbt.contracts.graph.nodes.DeferRelation, NoneType] = None)\"\n    },\n    \"ModelLevelConstraint\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"type\"\n      ],\n      \"properties\": {\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"check\",\n            \"not_null\",\n            \"unique\",\n            \"primary_key\",\n            \"foreign_key\",\n            \"custom\"\n          ]\n        },\n        \"name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"expression\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"warn_unenforced\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"warn_unsupported\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"columns\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ModelLevelConstraint(type: dbt.contracts.graph.nodes.ConstraintType, name: Union[str, NoneType] = None, expression: Union[str, NoneType] = None, warn_unenforced: bool = True, warn_unsupported: bool = True, columns: List[str] = <factory>)\"\n    },\n    \"DeferRelation\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"schema\",\n        \"alias\"\n      ],\n      \"properties\": {\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"DeferRelation(database: Union[str, NoneType], schema: str, alias: str, relation_name: Union[str, NoneType])\"\n    },\n    \"RPCNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"schema\",\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"rpc\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"group\": null,\n            \"materialized\": \"view\",\n            \"incremental_strategy\": null,\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"on_configuration_change\": \"apply\",\n            \"grants\": {},\n            \"packages\": [],\n            \"docs\": {\n              \"show\": true,\n              \"node_color\": null\n            },\n            \"contract\": {\n              \"enforced\": false\n            },\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"group\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1696465994.416128\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"raw_code\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"language\": {\n          \"type\": \"string\",\n          \"default\": \"sql\"\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/RefArgs\"\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"compiled_code\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"contract\": {\n          \"$ref\": \"#/definitions/Contract\",\n          \"default\": {\n            \"enforced\": false,\n            \"checksum\": null\n          }\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"RPCNode(database: Union[str, NoneType], schema: str, name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, fqn: List[str], alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.nodes.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, group: Union[str, NoneType] = None, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, relation_name: Union[str, NoneType] = None, raw_code: str = '', language: str = 'sql', refs: List[dbt.contracts.graph.nodes.RefArgs] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.nodes.DependsOn = <factory>, compiled_path: Union[str, NoneType] = None, compiled: bool = False, compiled_code: Union[str, NoneType] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.nodes.InjectedCTE] = <factory>, _pre_injected_sql: Union[str, NoneType] = None, contract: dbt.contracts.graph.nodes.Contract = <factory>)\"\n    },\n    \"SqlNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"schema\",\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"sql_operation\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"group\": null,\n            \"materialized\": \"view\",\n            \"incremental_strategy\": null,\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"on_configuration_change\": \"apply\",\n            \"grants\": {},\n            \"packages\": [],\n            \"docs\": {\n              \"show\": true,\n              \"node_color\": null\n            },\n            \"contract\": {\n              \"enforced\": false\n            },\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"group\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1696465994.41679\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"raw_code\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"language\": {\n          \"type\": \"string\",\n          \"default\": \"sql\"\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/RefArgs\"\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"compiled_code\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"contract\": {\n          \"$ref\": \"#/definitions/Contract\",\n          \"default\": {\n            \"enforced\": false,\n            \"checksum\": null\n          }\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"SqlNode(database: Union[str, NoneType], schema: str, name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, fqn: List[str], alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.nodes.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, group: Union[str, NoneType] = None, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, relation_name: Union[str, NoneType] = None, raw_code: str = '', language: str = 'sql', refs: List[dbt.contracts.graph.nodes.RefArgs] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.nodes.DependsOn = <factory>, compiled_path: Union[str, NoneType] = None, compiled: bool = False, compiled_code: Union[str, NoneType] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.nodes.InjectedCTE] = <factory>, _pre_injected_sql: Union[str, NoneType] = None, contract: dbt.contracts.graph.nodes.Contract = <factory>)\"\n    },\n    \"GenericTestNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"test_metadata\",\n        \"schema\",\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"test_metadata\": {\n          \"$ref\": \"#/definitions/TestMetadata\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"test\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/TestConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": \"dbt_test__audit\",\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"group\": null,\n            \"materialized\": \"test\",\n            \"severity\": \"ERROR\",\n            \"store_failures\": null,\n            \"where\": null,\n            \"limit\": null,\n            \"fail_calc\": \"count(*)\",\n            \"warn_if\": \"!= 0\",\n            \"error_if\": \"!= 0\"\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"group\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1696465994.4175282\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"raw_code\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"language\": {\n          \"type\": \"string\",\n          \"default\": \"sql\"\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/RefArgs\"\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"compiled_code\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"contract\": {\n          \"$ref\": \"#/definitions/Contract\",\n          \"default\": {\n            \"enforced\": false,\n            \"checksum\": null\n          }\n        },\n        \"column_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"file_key_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"attached_node\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"GenericTestNode(test_metadata: dbt.contracts.graph.nodes.TestMetadata, database: Union[str, NoneType], schema: str, name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, fqn: List[str], alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.TestConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.nodes.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, group: Union[str, NoneType] = None, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, relation_name: Union[str, NoneType] = None, raw_code: str = '', language: str = 'sql', refs: List[dbt.contracts.graph.nodes.RefArgs] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.nodes.DependsOn = <factory>, compiled_path: Union[str, NoneType] = None, compiled: bool = False, compiled_code: Union[str, NoneType] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.nodes.InjectedCTE] = <factory>, _pre_injected_sql: Union[str, NoneType] = None, contract: dbt.contracts.graph.nodes.Contract = <factory>, column_name: Union[str, NoneType] = None, file_key_name: Union[str, NoneType] = None, attached_node: Union[str, NoneType] = None)\"\n    },\n    \"TestMetadata\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"kwargs\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"namespace\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"TestMetadata(name: str, kwargs: Dict[str, Any] = <factory>, namespace: Union[str, NoneType] = None)\"\n    },\n    \"SnapshotNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"schema\",\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"alias\",\n        \"checksum\",\n        \"config\"\n      ],\n      \"properties\": {\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"snapshot\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/SnapshotConfig\"\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"group\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1696465994.418854\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"raw_code\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"language\": {\n          \"type\": \"string\",\n          \"default\": \"sql\"\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/RefArgs\"\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"compiled_code\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"contract\": {\n          \"$ref\": \"#/definitions/Contract\",\n          \"default\": {\n            \"enforced\": false,\n            \"checksum\": null\n          }\n        },\n        \"defer_relation\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/DeferRelation\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"SnapshotNode(database: Union[str, NoneType], schema: str, name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, fqn: List[str], alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.SnapshotConfig, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.nodes.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, group: Union[str, NoneType] = None, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, relation_name: Union[str, NoneType] = None, raw_code: str = '', language: str = 'sql', refs: List[dbt.contracts.graph.nodes.RefArgs] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.nodes.DependsOn = <factory>, compiled_path: Union[str, NoneType] = None, compiled: bool = False, compiled_code: Union[str, NoneType] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.nodes.InjectedCTE] = <factory>, _pre_injected_sql: Union[str, NoneType] = None, contract: dbt.contracts.graph.nodes.Contract = <factory>, defer_relation: Union[dbt.contracts.graph.nodes.DeferRelation, NoneType] = None)\"\n    },\n    \"SnapshotConfig\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"alias\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tags\": {\n          \"oneOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"string\"\n            }\n          ],\n          \"default\": []\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"group\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"materialized\": {\n          \"type\": \"string\",\n          \"default\": \"snapshot\"\n        },\n        \"incremental_strategy\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"persist_docs\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"post-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Hook\"\n          },\n          \"default\": []\n        },\n        \"pre-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Hook\"\n          },\n          \"default\": []\n        },\n        \"quoting\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"column_types\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"full_refresh\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"unique_key\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"on_schema_change\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": \"ignore\"\n        },\n        \"on_configuration_change\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"apply\",\n            \"continue\",\n            \"fail\"\n          ],\n          \"default\": \"apply\"\n        },\n        \"grants\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"packages\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"contract\": {\n          \"$ref\": \"#/definitions/ContractConfig\",\n          \"default\": {\n            \"enforced\": false\n          }\n        },\n        \"strategy\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"target_schema\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"target_database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"updated_at\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"check_cols\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"SnapshotConfig(_extra: Dict[str, Any] = <factory>, enabled: bool = True, alias: Union[str, NoneType] = None, schema: Union[str, NoneType] = None, database: Union[str, NoneType] = None, tags: Union[List[str], str] = <factory>, meta: Dict[str, Any] = <factory>, group: Union[str, NoneType] = None, materialized: str = 'snapshot', incremental_strategy: Union[str, NoneType] = None, persist_docs: Dict[str, Any] = <factory>, post_hook: List[dbt.contracts.graph.model_config.Hook] = <factory>, pre_hook: List[dbt.contracts.graph.model_config.Hook] = <factory>, quoting: Dict[str, Any] = <factory>, column_types: Dict[str, Any] = <factory>, full_refresh: Union[bool, NoneType] = None, unique_key: Union[str, NoneType] = None, on_schema_change: Union[str, NoneType] = 'ignore', on_configuration_change: dbt.contracts.graph.model_config.OnConfigurationChangeOption = <factory>, grants: Dict[str, Any] = <factory>, packages: List[str] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, contract: dbt.contracts.graph.model_config.ContractConfig = <factory>, strategy: Union[str, NoneType] = None, target_schema: Union[str, NoneType] = None, target_database: Union[str, NoneType] = None, updated_at: Union[str, NoneType] = None, check_cols: Union[str, List[str], NoneType] = None)\"\n    },\n    \"SeedNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"schema\",\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"seed\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/SeedConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"group\": null,\n            \"materialized\": \"seed\",\n            \"incremental_strategy\": null,\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"on_configuration_change\": \"apply\",\n            \"grants\": {},\n            \"packages\": [],\n            \"docs\": {\n              \"show\": true,\n              \"node_color\": null\n            },\n            \"contract\": {\n              \"enforced\": false\n            },\n            \"quote_columns\": null,\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"group\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1696465994.420199\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"raw_code\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"root_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/MacroDependsOn\",\n          \"default\": {\n            \"macros\": []\n          }\n        },\n        \"defer_relation\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/DeferRelation\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"SeedNode(database: Union[str, NoneType], schema: str, name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, fqn: List[str], alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.SeedConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.nodes.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, group: Union[str, NoneType] = None, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, relation_name: Union[str, NoneType] = None, raw_code: str = '', root_path: Union[str, NoneType] = None, depends_on: dbt.contracts.graph.nodes.MacroDependsOn = <factory>, defer_relation: Union[dbt.contracts.graph.nodes.DeferRelation, NoneType] = None)\"\n    },\n    \"SeedConfig\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"alias\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tags\": {\n          \"oneOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"string\"\n            }\n          ],\n          \"default\": []\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"group\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"materialized\": {\n          \"type\": \"string\",\n          \"default\": \"seed\"\n        },\n        \"incremental_strategy\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"persist_docs\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"post-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Hook\"\n          },\n          \"default\": []\n        },\n        \"pre-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Hook\"\n          },\n          \"default\": []\n        },\n        \"quoting\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"column_types\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"full_refresh\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"unique_key\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"on_schema_change\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": \"ignore\"\n        },\n        \"on_configuration_change\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"apply\",\n            \"continue\",\n            \"fail\"\n          ],\n          \"default\": \"apply\"\n        },\n        \"grants\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"packages\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"contract\": {\n          \"$ref\": \"#/definitions/ContractConfig\",\n          \"default\": {\n            \"enforced\": false\n          }\n        },\n        \"quote_columns\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"SeedConfig(_extra: Dict[str, Any] = <factory>, enabled: bool = True, alias: Union[str, NoneType] = None, schema: Union[str, NoneType] = None, database: Union[str, NoneType] = None, tags: Union[List[str], str] = <factory>, meta: Dict[str, Any] = <factory>, group: Union[str, NoneType] = None, materialized: str = 'seed', incremental_strategy: Union[str, NoneType] = None, persist_docs: Dict[str, Any] = <factory>, post_hook: List[dbt.contracts.graph.model_config.Hook] = <factory>, pre_hook: List[dbt.contracts.graph.model_config.Hook] = <factory>, quoting: Dict[str, Any] = <factory>, column_types: Dict[str, Any] = <factory>, full_refresh: Union[bool, NoneType] = None, unique_key: Union[str, List[str], NoneType] = None, on_schema_change: Union[str, NoneType] = 'ignore', on_configuration_change: dbt.contracts.graph.model_config.OnConfigurationChangeOption = <factory>, grants: Dict[str, Any] = <factory>, packages: List[str] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, contract: dbt.contracts.graph.model_config.ContractConfig = <factory>, quote_columns: Union[bool, NoneType] = None)\"\n    },\n    \"MacroDependsOn\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"macros\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Used only in the Macro class\"\n    },\n    \"SourceDefinition\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"schema\",\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"source_name\",\n        \"source_description\",\n        \"loader\",\n        \"identifier\"\n      ],\n      \"properties\": {\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"source\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"source_name\": {\n          \"type\": \"string\"\n        },\n        \"source_description\": {\n          \"type\": \"string\"\n        },\n        \"loader\": {\n          \"type\": \"string\"\n        },\n        \"identifier\": {\n          \"type\": \"string\"\n        },\n        \"quoting\": {\n          \"$ref\": \"#/definitions/Quoting\",\n          \"default\": {\n            \"database\": null,\n            \"schema\": null,\n            \"identifier\": null,\n            \"column\": null\n          }\n        },\n        \"loaded_at_field\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"freshness\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/FreshnessThreshold\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"external\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/ExternalTable\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"source_meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/SourceConfig\",\n          \"default\": {\n            \"enabled\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1696465994.421661\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"SourceDefinition(database: Union[str, NoneType], schema: str, name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, fqn: List[str], source_name: str, source_description: str, loader: str, identifier: str, _event_status: Dict[str, Any] = <factory>, quoting: dbt.contracts.graph.unparsed.Quoting = <factory>, loaded_at_field: Union[str, NoneType] = None, freshness: Union[dbt.contracts.graph.unparsed.FreshnessThreshold, NoneType] = None, external: Union[dbt.contracts.graph.unparsed.ExternalTable, NoneType] = None, description: str = '', columns: Dict[str, dbt.contracts.graph.nodes.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, source_meta: Dict[str, Any] = <factory>, tags: List[str] = <factory>, config: dbt.contracts.graph.model_config.SourceConfig = <factory>, patch_path: Union[str, NoneType] = None, unrendered_config: Dict[str, Any] = <factory>, relation_name: Union[str, NoneType] = None, created_at: float = <factory>)\"\n    },\n    \"Quoting\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"identifier\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"column\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Quoting(database: Union[bool, NoneType] = None, schema: Union[bool, NoneType] = None, identifier: Union[bool, NoneType] = None, column: Union[bool, NoneType] = None)\"\n    },\n    \"FreshnessThreshold\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"warn_after\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/Time\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": {\n            \"count\": null,\n            \"period\": null\n          }\n        },\n        \"error_after\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/Time\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": {\n            \"count\": null,\n            \"period\": null\n          }\n        },\n        \"filter\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"FreshnessThreshold(warn_after: Union[dbt.contracts.graph.unparsed.Time, NoneType] = <factory>, error_after: Union[dbt.contracts.graph.unparsed.Time, NoneType] = <factory>, filter: Union[str, NoneType] = None)\"\n    },\n    \"Time\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"count\": {\n          \"oneOf\": [\n            {\n              \"type\": \"integer\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"period\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\",\n              \"enum\": [\n                \"minute\",\n                \"hour\",\n                \"day\"\n              ]\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Time(count: Union[int, NoneType] = None, period: Union[dbt.contracts.graph.unparsed.TimePeriod, NoneType] = None)\"\n    },\n    \"ExternalTable\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"location\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"file_format\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"row_format\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tbl_properties\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"partitions\": {\n          \"oneOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"$ref\": \"#/definitions/ExternalPartition\"\n              }\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"ExternalTable(_extra: Dict[str, Any] = <factory>, location: Union[str, NoneType] = None, file_format: Union[str, NoneType] = None, row_format: Union[str, NoneType] = None, tbl_properties: Union[str, NoneType] = None, partitions: Union[List[str], List[dbt.contracts.graph.unparsed.ExternalPartition], NoneType] = None)\"\n    },\n    \"ExternalPartition\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"data_type\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"ExternalPartition(_extra: Dict[str, Any] = <factory>, name: str = '', description: str = '', data_type: str = '', meta: Dict[str, Any] = <factory>)\"\n    },\n    \"SourceConfig\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"SourceConfig(_extra: Dict[str, Any] = <factory>, enabled: bool = True)\"\n    },\n    \"Macro\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"macro_sql\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"macro\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"macro_sql\": {\n          \"type\": \"string\"\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/MacroDependsOn\",\n          \"default\": {\n            \"macros\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"arguments\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/MacroArgument\"\n          },\n          \"default\": []\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1696465994.421958\n        },\n        \"supported_languages\": {\n          \"oneOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\",\n                \"enum\": [\n                  \"python\",\n                  \"sql\"\n                ]\n              }\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Macro(name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, macro_sql: str, depends_on: dbt.contracts.graph.nodes.MacroDependsOn = <factory>, description: str = '', meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, arguments: List[dbt.contracts.graph.unparsed.MacroArgument] = <factory>, created_at: float = <factory>, supported_languages: Union[List[dbt.node_types.ModelLanguage], NoneType] = None)\"\n    },\n    \"MacroArgument\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"type\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"MacroArgument(name: str, type: Union[str, NoneType] = None, description: str = '')\"\n    },\n    \"Documentation\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"block_contents\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"doc\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"block_contents\": {\n          \"type\": \"string\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Documentation(name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, block_contents: str)\"\n    },\n    \"Exposure\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"type\",\n        \"owner\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"exposure\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"dashboard\",\n            \"notebook\",\n            \"analysis\",\n            \"ml\",\n            \"application\"\n          ]\n        },\n        \"owner\": {\n          \"$ref\": \"#/definitions/Owner\"\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"label\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"maturity\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\",\n              \"enum\": [\n                \"low\",\n                \"medium\",\n                \"high\"\n              ]\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/ExposureConfig\",\n          \"default\": {\n            \"enabled\": true\n          }\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"url\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/RefArgs\"\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1696465994.422623\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Exposure(name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, fqn: List[str], type: dbt.contracts.graph.unparsed.ExposureType, owner: dbt.contracts.graph.unparsed.Owner, description: str = '', label: Union[str, NoneType] = None, maturity: Union[dbt.contracts.graph.unparsed.MaturityType, NoneType] = None, meta: Dict[str, Any] = <factory>, tags: List[str] = <factory>, config: dbt.contracts.graph.model_config.ExposureConfig = <factory>, unrendered_config: Dict[str, Any] = <factory>, url: Union[str, NoneType] = None, depends_on: dbt.contracts.graph.nodes.DependsOn = <factory>, refs: List[dbt.contracts.graph.nodes.RefArgs] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, created_at: float = <factory>)\"\n    },\n    \"Owner\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"email\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"Owner(_extra: Dict[str, Any] = <factory>, email: Union[str, NoneType] = None, name: Union[str, NoneType] = None)\"\n    },\n    \"ExposureConfig\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"ExposureConfig(_extra: Dict[str, Any] = <factory>, enabled: bool = True)\"\n    },\n    \"Metric\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"description\",\n        \"label\",\n        \"type\",\n        \"type_params\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"metric\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"label\": {\n          \"type\": \"string\"\n        },\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"simple\",\n            \"ratio\",\n            \"cumulative\",\n            \"derived\"\n          ]\n        },\n        \"type_params\": {\n          \"$ref\": \"#/definitions/MetricTypeParams\"\n        },\n        \"filter\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/WhereFilter\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"metadata\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/SourceFileMetadata\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/MetricConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"group\": null\n          }\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/RefArgs\"\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1696465994.4238322\n        },\n        \"group\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Metric(name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, fqn: List[str], description: str, label: str, type: dbt_semantic_interfaces.type_enums.metric_type.MetricType, type_params: dbt.contracts.graph.nodes.MetricTypeParams, filter: Union[dbt.contracts.graph.nodes.WhereFilter, NoneType] = None, metadata: Union[dbt.contracts.graph.semantic_models.SourceFileMetadata, NoneType] = None, meta: Dict[str, Any] = <factory>, tags: List[str] = <factory>, config: dbt.contracts.graph.model_config.MetricConfig = <factory>, unrendered_config: Dict[str, Any] = <factory>, sources: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.nodes.DependsOn = <factory>, refs: List[dbt.contracts.graph.nodes.RefArgs] = <factory>, metrics: List[List[str]] = <factory>, created_at: float = <factory>, group: Union[str, NoneType] = None)\"\n    },\n    \"MetricTypeParams\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"measure\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/MetricInputMeasure\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"input_measures\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/MetricInputMeasure\"\n          },\n          \"default\": []\n        },\n        \"numerator\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/MetricInput\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"denominator\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/MetricInput\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"expr\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"window\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/MetricTimeWindow\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"grain_to_date\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\",\n              \"enum\": [\n                \"day\",\n                \"week\",\n                \"month\",\n                \"quarter\",\n                \"year\"\n              ]\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"metrics\": {\n          \"oneOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"$ref\": \"#/definitions/MetricInput\"\n              }\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"MetricTypeParams(measure: Union[dbt.contracts.graph.nodes.MetricInputMeasure, NoneType] = None, input_measures: List[dbt.contracts.graph.nodes.MetricInputMeasure] = <factory>, numerator: Union[dbt.contracts.graph.nodes.MetricInput, NoneType] = None, denominator: Union[dbt.contracts.graph.nodes.MetricInput, NoneType] = None, expr: Union[str, NoneType] = None, window: Union[dbt.contracts.graph.nodes.MetricTimeWindow, NoneType] = None, grain_to_date: Union[dbt_semantic_interfaces.type_enums.time_granularity.TimeGranularity, NoneType] = None, metrics: Union[List[dbt.contracts.graph.nodes.MetricInput], NoneType] = None)\"\n    },\n    \"MetricInputMeasure\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"filter\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/WhereFilter\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"alias\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"join_to_timespine\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"fill_nulls_with\": {\n          \"oneOf\": [\n            {\n              \"type\": \"integer\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"MetricInputMeasure(name: str, filter: Union[dbt.contracts.graph.nodes.WhereFilter, NoneType] = None, alias: Union[str, NoneType] = None, join_to_timespine: bool = False, fill_nulls_with: Union[int, NoneType] = None)\"\n    },\n    \"WhereFilter\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"where_sql_template\"\n      ],\n      \"properties\": {\n        \"where_sql_template\": {\n          \"type\": \"string\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"WhereFilter(where_sql_template: str)\"\n    },\n    \"MetricInput\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"filter\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/WhereFilter\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"alias\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"offset_window\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/MetricTimeWindow\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"offset_to_grain\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\",\n              \"enum\": [\n                \"day\",\n                \"week\",\n                \"month\",\n                \"quarter\",\n                \"year\"\n              ]\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"MetricInput(name: str, filter: Union[dbt.contracts.graph.nodes.WhereFilter, NoneType] = None, alias: Union[str, NoneType] = None, offset_window: Union[dbt.contracts.graph.nodes.MetricTimeWindow, NoneType] = None, offset_to_grain: Union[dbt_semantic_interfaces.type_enums.time_granularity.TimeGranularity, NoneType] = None)\"\n    },\n    \"MetricTimeWindow\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"count\",\n        \"granularity\"\n      ],\n      \"properties\": {\n        \"count\": {\n          \"type\": \"integer\"\n        },\n        \"granularity\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"day\",\n            \"week\",\n            \"month\",\n            \"quarter\",\n            \"year\"\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"MetricTimeWindow(count: int, granularity: dbt_semantic_interfaces.type_enums.time_granularity.TimeGranularity)\"\n    },\n    \"SourceFileMetadata\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"repo_file_path\",\n        \"file_slice\"\n      ],\n      \"properties\": {\n        \"repo_file_path\": {\n          \"type\": \"string\"\n        },\n        \"file_slice\": {\n          \"$ref\": \"#/definitions/FileSlice\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Provides file context about what something was created from.\\n\\n    Implementation of the dbt-semantic-interfaces `Metadata` protocol\\n    \"\n    },\n    \"FileSlice\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"filename\",\n        \"content\",\n        \"start_line_number\",\n        \"end_line_number\"\n      ],\n      \"properties\": {\n        \"filename\": {\n          \"type\": \"string\"\n        },\n        \"content\": {\n          \"type\": \"string\"\n        },\n        \"start_line_number\": {\n          \"type\": \"integer\"\n        },\n        \"end_line_number\": {\n          \"type\": \"integer\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Provides file slice level context about what something was created from.\\n\\n    Implementation of the dbt-semantic-interfaces `FileSlice` protocol\\n    \"\n    },\n    \"MetricConfig\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"group\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"MetricConfig(_extra: Dict[str, Any] = <factory>, enabled: bool = True, group: Union[str, NoneType] = None)\"\n    },\n    \"Group\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"owner\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"group\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"owner\": {\n          \"$ref\": \"#/definitions/Owner\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Group(name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, owner: dbt.contracts.graph.unparsed.Owner)\"\n    },\n    \"SemanticModel\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"model\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"model\",\n            \"analysis\",\n            \"test\",\n            \"snapshot\",\n            \"operation\",\n            \"seed\",\n            \"rpc\",\n            \"sql_operation\",\n            \"doc\",\n            \"source\",\n            \"macro\",\n            \"exposure\",\n            \"metric\",\n            \"group\",\n            \"semantic_model\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"model\": {\n          \"type\": \"string\"\n        },\n        \"node_relation\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/NodeRelation\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"description\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"label\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"defaults\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/Defaults\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"entities\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Entity\"\n          },\n          \"default\": []\n        },\n        \"measures\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Measure\"\n          },\n          \"default\": []\n        },\n        \"dimensions\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Dimension\"\n          },\n          \"default\": []\n        },\n        \"metadata\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/SourceFileMetadata\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/RefArgs\"\n          },\n          \"default\": []\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1696465994.425479\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/SemanticModelConfig\",\n          \"default\": {\n            \"enabled\": true\n          }\n        },\n        \"primary_entity\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"SemanticModel(name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, fqn: List[str], model: str, node_relation: Union[dbt.contracts.graph.nodes.NodeRelation, NoneType], description: Union[str, NoneType] = None, label: Union[str, NoneType] = None, defaults: Union[dbt.contracts.graph.semantic_models.Defaults, NoneType] = None, entities: Sequence[dbt.contracts.graph.semantic_models.Entity] = <factory>, measures: Sequence[dbt.contracts.graph.semantic_models.Measure] = <factory>, dimensions: Sequence[dbt.contracts.graph.semantic_models.Dimension] = <factory>, metadata: Union[dbt.contracts.graph.semantic_models.SourceFileMetadata, NoneType] = None, depends_on: dbt.contracts.graph.nodes.DependsOn = <factory>, refs: List[dbt.contracts.graph.nodes.RefArgs] = <factory>, created_at: float = <factory>, config: dbt.contracts.graph.model_config.SemanticModelConfig = <factory>, primary_entity: Union[str, NoneType] = None)\"\n    },\n    \"NodeRelation\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"alias\",\n        \"schema_name\"\n      ],\n      \"properties\": {\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"schema_name\": {\n          \"type\": \"string\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"NodeRelation(alias: str, schema_name: str, database: Union[str, NoneType] = None, relation_name: Union[str, NoneType] = None)\"\n    },\n    \"Defaults\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"agg_time_dimension\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Defaults(agg_time_dimension: Union[str, NoneType] = None)\"\n    },\n    \"Entity\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\",\n        \"type\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"foreign\",\n            \"natural\",\n            \"primary\",\n            \"unique\"\n          ]\n        },\n        \"description\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"label\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"role\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"expr\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Entity(name: str, type: dbt_semantic_interfaces.type_enums.entity_type.EntityType, description: Union[str, NoneType] = None, label: Union[str, NoneType] = None, role: Union[str, NoneType] = None, expr: Union[str, NoneType] = None)\"\n    },\n    \"Measure\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\",\n        \"agg\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"agg\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"sum\",\n            \"min\",\n            \"max\",\n            \"count_distinct\",\n            \"sum_boolean\",\n            \"average\",\n            \"percentile\",\n            \"median\",\n            \"count\"\n          ]\n        },\n        \"description\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"label\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"create_metric\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"expr\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"agg_params\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/MeasureAggregationParameters\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"non_additive_dimension\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/NonAdditiveDimension\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"agg_time_dimension\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Measure(name: str, agg: dbt_semantic_interfaces.type_enums.aggregation_type.AggregationType, description: Union[str, NoneType] = None, label: Union[str, NoneType] = None, create_metric: bool = False, expr: Union[str, NoneType] = None, agg_params: Union[dbt.contracts.graph.semantic_models.MeasureAggregationParameters, NoneType] = None, non_additive_dimension: Union[dbt.contracts.graph.semantic_models.NonAdditiveDimension, NoneType] = None, agg_time_dimension: Union[str, NoneType] = None)\"\n    },\n    \"MeasureAggregationParameters\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"percentile\": {\n          \"oneOf\": [\n            {\n              \"type\": \"number\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"use_discrete_percentile\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"use_approximate_percentile\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"MeasureAggregationParameters(percentile: Union[float, NoneType] = None, use_discrete_percentile: bool = False, use_approximate_percentile: bool = False)\"\n    },\n    \"NonAdditiveDimension\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\",\n        \"window_choice\",\n        \"window_groupings\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"window_choice\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"sum\",\n            \"min\",\n            \"max\",\n            \"count_distinct\",\n            \"sum_boolean\",\n            \"average\",\n            \"percentile\",\n            \"median\",\n            \"count\"\n          ]\n        },\n        \"window_groupings\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"NonAdditiveDimension(name: str, window_choice: dbt_semantic_interfaces.type_enums.aggregation_type.AggregationType, window_groupings: List[str])\"\n    },\n    \"Dimension\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\",\n        \"type\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"categorical\",\n            \"time\"\n          ]\n        },\n        \"description\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"label\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"is_partition\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"type_params\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/DimensionTypeParams\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"expr\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"metadata\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/SourceFileMetadata\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Dimension(name: str, type: dbt_semantic_interfaces.type_enums.dimension_type.DimensionType, description: Union[str, NoneType] = None, label: Union[str, NoneType] = None, is_partition: bool = False, type_params: Union[dbt.contracts.graph.semantic_models.DimensionTypeParams, NoneType] = None, expr: Union[str, NoneType] = None, metadata: Union[dbt.contracts.graph.semantic_models.SourceFileMetadata, NoneType] = None)\"\n    },\n    \"DimensionTypeParams\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"time_granularity\"\n      ],\n      \"properties\": {\n        \"time_granularity\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"day\",\n            \"week\",\n            \"month\",\n            \"quarter\",\n            \"year\"\n          ]\n        },\n        \"validity_params\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/DimensionValidityParams\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"DimensionTypeParams(time_granularity: dbt_semantic_interfaces.type_enums.time_granularity.TimeGranularity, validity_params: Union[dbt.contracts.graph.semantic_models.DimensionValidityParams, NoneType] = None)\"\n    },\n    \"DimensionValidityParams\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"is_start\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"is_end\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"DimensionValidityParams(is_start: bool = False, is_end: bool = False)\"\n    },\n    \"SemanticModelConfig\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"SemanticModelConfig(_extra: Dict[str, Any] = <factory>, enabled: bool = True)\"\n    }\n  },\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n  \"$id\": \"https://schemas.getdbt.com/dbt/manifest/v10.json\"\n}"
  },
  {
    "path": "schemas/dbt/manifest/v11.json",
    "content": "{\n  \"$ref\": \"#/$defs/WritableManifest\",\n  \"$defs\": {\n    \"ManifestMetadata\": {\n      \"type\": \"object\",\n      \"title\": \"ManifestMetadata\",\n      \"properties\": {\n        \"dbt_schema_version\": {\n          \"type\": \"string\"\n        },\n        \"dbt_version\": {\n          \"type\": \"string\",\n          \"default\": \"1.8.0a1\"\n        },\n        \"generated_at\": {\n          \"type\": \"string\"\n        },\n        \"invocation_id\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"env\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          },\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"project_name\": {\n          \"description\": \"Name of the root project\",\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"project_id\": {\n          \"description\": \"A unique identifier for the project, hashed from the project name\",\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"user_id\": {\n          \"description\": \"A unique identifier for the user\",\n          \"anyOf\": [\n            {\n              \"type\": \"string\",\n              \"format\": \"uuid\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"send_anonymous_usage_stats\": {\n          \"description\": \"Whether dbt is configured to send anonymous usage statistics\",\n          \"anyOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"adapter_type\": {\n          \"description\": \"The type name of the adapter\",\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"FileHash\": {\n      \"type\": \"object\",\n      \"title\": \"FileHash\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"type\": \"string\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"name\",\n        \"checksum\"\n      ]\n    },\n    \"Hook\": {\n      \"type\": \"object\",\n      \"title\": \"Hook\",\n      \"properties\": {\n        \"sql\": {\n          \"type\": \"string\"\n        },\n        \"transaction\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"index\": {\n          \"anyOf\": [\n            {\n              \"type\": \"integer\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"sql\"\n      ]\n    },\n    \"Docs\": {\n      \"type\": \"object\",\n      \"title\": \"Docs\",\n      \"properties\": {\n        \"show\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"node_color\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"ContractConfig\": {\n      \"type\": \"object\",\n      \"title\": \"ContractConfig\",\n      \"properties\": {\n        \"enforced\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"alias_types\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"NodeConfig\": {\n      \"type\": \"object\",\n      \"title\": \"NodeConfig\",\n      \"properties\": {\n        \"_extra\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"alias\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"schema\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"database\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"tags\": {\n          \"anyOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"string\"\n            }\n          ]\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"group\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"materialized\": {\n          \"type\": \"string\",\n          \"default\": \"view\"\n        },\n        \"incremental_strategy\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"persist_docs\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"post-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/Hook\"\n          }\n        },\n        \"pre-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/Hook\"\n          }\n        },\n        \"quoting\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"column_types\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"full_refresh\": {\n          \"anyOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"unique_key\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"on_schema_change\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": \"ignore\"\n        },\n        \"on_configuration_change\": {\n          \"enum\": [\n            \"apply\",\n            \"continue\",\n            \"fail\"\n          ]\n        },\n        \"grants\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"packages\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"docs\": {\n          \"$ref\": \"#/$defs/Docs\"\n        },\n        \"contract\": {\n          \"$ref\": \"#/$defs/ContractConfig\"\n        }\n      },\n      \"additionalProperties\": true\n    },\n    \"ColumnLevelConstraint\": {\n      \"type\": \"object\",\n      \"title\": \"ColumnLevelConstraint\",\n      \"properties\": {\n        \"type\": {\n          \"enum\": [\n            \"check\",\n            \"not_null\",\n            \"unique\",\n            \"primary_key\",\n            \"foreign_key\",\n            \"custom\"\n          ]\n        },\n        \"name\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"expression\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"warn_unenforced\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"warn_unsupported\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"type\"\n      ]\n    },\n    \"ColumnInfo\": {\n      \"type\": \"object\",\n      \"title\": \"ColumnInfo\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"data_type\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"constraints\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/ColumnLevelConstraint\"\n          }\n        },\n        \"quote\": {\n          \"anyOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"_extra\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        }\n      },\n      \"additionalProperties\": true,\n      \"required\": [\n        \"name\"\n      ]\n    },\n    \"RefArgs\": {\n      \"type\": \"object\",\n      \"title\": \"RefArgs\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"package\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"version\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"number\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"name\"\n      ]\n    },\n    \"DependsOn\": {\n      \"type\": \"object\",\n      \"title\": \"DependsOn\",\n      \"properties\": {\n        \"macros\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"nodes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"InjectedCTE\": {\n      \"type\": \"object\",\n      \"title\": \"InjectedCTE\",\n      \"properties\": {\n        \"id\": {\n          \"type\": \"string\"\n        },\n        \"sql\": {\n          \"type\": \"string\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"id\",\n        \"sql\"\n      ]\n    },\n    \"Contract\": {\n      \"type\": \"object\",\n      \"title\": \"Contract\",\n      \"properties\": {\n        \"enforced\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"alias_types\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"checksum\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"AnalysisNode\": {\n      \"type\": \"object\",\n      \"title\": \"AnalysisNode\",\n      \"properties\": {\n        \"database\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"const\": \"analysis\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/$defs/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/$defs/NodeConfig\"\n        },\n        \"_event_status\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/ColumnInfo\"\n          },\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"group\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"docs\": {\n          \"$ref\": \"#/$defs/Docs\"\n        },\n        \"patch_path\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"build_path\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"created_at\": {\n          \"type\": \"number\"\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"relation_name\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"raw_code\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"language\": {\n          \"type\": \"string\",\n          \"default\": \"sql\"\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/RefArgs\"\n          }\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          }\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          }\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/$defs/DependsOn\"\n        },\n        \"compiled_path\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"compiled\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"compiled_code\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/InjectedCTE\"\n          }\n        },\n        \"_pre_injected_sql\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"contract\": {\n          \"$ref\": \"#/$defs/Contract\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"database\",\n        \"schema\",\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"alias\",\n        \"checksum\"\n      ]\n    },\n    \"TestConfig\": {\n      \"type\": \"object\",\n      \"title\": \"TestConfig\",\n      \"properties\": {\n        \"_extra\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"alias\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"schema\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": \"dbt_test__audit\"\n        },\n        \"database\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"tags\": {\n          \"anyOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"string\"\n            }\n          ]\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"group\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"materialized\": {\n          \"type\": \"string\",\n          \"default\": \"test\"\n        },\n        \"severity\": {\n          \"type\": \"string\",\n          \"default\": \"ERROR\",\n          \"pattern\": \"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$\"\n        },\n        \"store_failures\": {\n          \"anyOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"store_failures_as\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"where\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"limit\": {\n          \"anyOf\": [\n            {\n              \"type\": \"integer\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"fail_calc\": {\n          \"type\": \"string\",\n          \"default\": \"count(*)\"\n        },\n        \"warn_if\": {\n          \"type\": \"string\",\n          \"default\": \"!= 0\"\n        },\n        \"error_if\": {\n          \"type\": \"string\",\n          \"default\": \"!= 0\"\n        }\n      },\n      \"additionalProperties\": true\n    },\n    \"SingularTestNode\": {\n      \"type\": \"object\",\n      \"title\": \"SingularTestNode\",\n      \"properties\": {\n        \"database\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"const\": \"test\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/$defs/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/$defs/TestConfig\"\n        },\n        \"_event_status\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/ColumnInfo\"\n          },\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"group\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"docs\": {\n          \"$ref\": \"#/$defs/Docs\"\n        },\n        \"patch_path\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"build_path\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"created_at\": {\n          \"type\": \"number\"\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"relation_name\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"raw_code\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"language\": {\n          \"type\": \"string\",\n          \"default\": \"sql\"\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/RefArgs\"\n          }\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          }\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          }\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/$defs/DependsOn\"\n        },\n        \"compiled_path\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"compiled\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"compiled_code\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/InjectedCTE\"\n          }\n        },\n        \"_pre_injected_sql\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"contract\": {\n          \"$ref\": \"#/$defs/Contract\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"database\",\n        \"schema\",\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"alias\",\n        \"checksum\"\n      ]\n    },\n    \"HookNode\": {\n      \"type\": \"object\",\n      \"title\": \"HookNode\",\n      \"properties\": {\n        \"database\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"const\": \"operation\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/$defs/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/$defs/NodeConfig\"\n        },\n        \"_event_status\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/ColumnInfo\"\n          },\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"group\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"docs\": {\n          \"$ref\": \"#/$defs/Docs\"\n        },\n        \"patch_path\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"build_path\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"created_at\": {\n          \"type\": \"number\"\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"relation_name\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"raw_code\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"language\": {\n          \"type\": \"string\",\n          \"default\": \"sql\"\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/RefArgs\"\n          }\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          }\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          }\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/$defs/DependsOn\"\n        },\n        \"compiled_path\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"compiled\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"compiled_code\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/InjectedCTE\"\n          }\n        },\n        \"_pre_injected_sql\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"contract\": {\n          \"$ref\": \"#/$defs/Contract\"\n        },\n        \"index\": {\n          \"anyOf\": [\n            {\n              \"type\": \"integer\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"database\",\n        \"schema\",\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"alias\",\n        \"checksum\"\n      ]\n    },\n    \"ModelConfig\": {\n      \"type\": \"object\",\n      \"title\": \"ModelConfig\",\n      \"properties\": {\n        \"_extra\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"alias\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"schema\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"database\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"tags\": {\n          \"anyOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"string\"\n            }\n          ]\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"group\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"materialized\": {\n          \"type\": \"string\",\n          \"default\": \"view\"\n        },\n        \"incremental_strategy\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"persist_docs\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"post-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/Hook\"\n          }\n        },\n        \"pre-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/Hook\"\n          }\n        },\n        \"quoting\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"column_types\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"full_refresh\": {\n          \"anyOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"unique_key\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"on_schema_change\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": \"ignore\"\n        },\n        \"on_configuration_change\": {\n          \"enum\": [\n            \"apply\",\n            \"continue\",\n            \"fail\"\n          ]\n        },\n        \"grants\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"packages\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"docs\": {\n          \"$ref\": \"#/$defs/Docs\"\n        },\n        \"contract\": {\n          \"$ref\": \"#/$defs/ContractConfig\"\n        },\n        \"access\": {\n          \"enum\": [\n            \"private\",\n            \"protected\",\n            \"public\"\n          ],\n          \"default\": \"protected\"\n        }\n      },\n      \"additionalProperties\": true\n    },\n    \"ModelLevelConstraint\": {\n      \"type\": \"object\",\n      \"title\": \"ModelLevelConstraint\",\n      \"properties\": {\n        \"type\": {\n          \"enum\": [\n            \"check\",\n            \"not_null\",\n            \"unique\",\n            \"primary_key\",\n            \"foreign_key\",\n            \"custom\"\n          ]\n        },\n        \"name\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"expression\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"warn_unenforced\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"warn_unsupported\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"columns\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"type\"\n      ]\n    },\n    \"DeferRelation\": {\n      \"type\": \"object\",\n      \"title\": \"DeferRelation\",\n      \"properties\": {\n        \"database\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"relation_name\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"database\",\n        \"schema\",\n        \"alias\",\n        \"relation_name\"\n      ]\n    },\n    \"ModelNode\": {\n      \"type\": \"object\",\n      \"title\": \"ModelNode\",\n      \"properties\": {\n        \"database\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"const\": \"model\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/$defs/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/$defs/ModelConfig\"\n        },\n        \"_event_status\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/ColumnInfo\"\n          },\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"group\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"docs\": {\n          \"$ref\": \"#/$defs/Docs\"\n        },\n        \"patch_path\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"build_path\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"created_at\": {\n          \"type\": \"number\"\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"relation_name\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"raw_code\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"language\": {\n          \"type\": \"string\",\n          \"default\": \"sql\"\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/RefArgs\"\n          }\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          }\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          }\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/$defs/DependsOn\"\n        },\n        \"compiled_path\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"compiled\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"compiled_code\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/InjectedCTE\"\n          }\n        },\n        \"_pre_injected_sql\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"contract\": {\n          \"$ref\": \"#/$defs/Contract\"\n        },\n        \"access\": {\n          \"enum\": [\n            \"private\",\n            \"protected\",\n            \"public\"\n          ],\n          \"default\": \"protected\"\n        },\n        \"constraints\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/ModelLevelConstraint\"\n          }\n        },\n        \"version\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"number\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"latest_version\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"number\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"deprecation_date\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"defer_relation\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/$defs/DeferRelation\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"database\",\n        \"schema\",\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"alias\",\n        \"checksum\"\n      ]\n    },\n    \"RPCNode\": {\n      \"type\": \"object\",\n      \"title\": \"RPCNode\",\n      \"properties\": {\n        \"database\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"const\": \"rpc\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/$defs/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/$defs/NodeConfig\"\n        },\n        \"_event_status\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/ColumnInfo\"\n          },\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"group\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"docs\": {\n          \"$ref\": \"#/$defs/Docs\"\n        },\n        \"patch_path\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"build_path\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"created_at\": {\n          \"type\": \"number\"\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"relation_name\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"raw_code\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"language\": {\n          \"type\": \"string\",\n          \"default\": \"sql\"\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/RefArgs\"\n          }\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          }\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          }\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/$defs/DependsOn\"\n        },\n        \"compiled_path\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"compiled\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"compiled_code\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/InjectedCTE\"\n          }\n        },\n        \"_pre_injected_sql\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"contract\": {\n          \"$ref\": \"#/$defs/Contract\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"database\",\n        \"schema\",\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"alias\",\n        \"checksum\"\n      ]\n    },\n    \"SqlNode\": {\n      \"type\": \"object\",\n      \"title\": \"SqlNode\",\n      \"properties\": {\n        \"database\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"const\": \"sql_operation\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/$defs/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/$defs/NodeConfig\"\n        },\n        \"_event_status\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/ColumnInfo\"\n          },\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"group\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"docs\": {\n          \"$ref\": \"#/$defs/Docs\"\n        },\n        \"patch_path\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"build_path\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"created_at\": {\n          \"type\": \"number\"\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"relation_name\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"raw_code\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"language\": {\n          \"type\": \"string\",\n          \"default\": \"sql\"\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/RefArgs\"\n          }\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          }\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          }\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/$defs/DependsOn\"\n        },\n        \"compiled_path\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"compiled\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"compiled_code\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/InjectedCTE\"\n          }\n        },\n        \"_pre_injected_sql\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"contract\": {\n          \"$ref\": \"#/$defs/Contract\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"database\",\n        \"schema\",\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"alias\",\n        \"checksum\"\n      ]\n    },\n    \"TestMetadata\": {\n      \"type\": \"object\",\n      \"title\": \"TestMetadata\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"kwargs\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"namespace\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"name\"\n      ]\n    },\n    \"GenericTestNode\": {\n      \"type\": \"object\",\n      \"title\": \"GenericTestNode\",\n      \"properties\": {\n        \"test_metadata\": {\n          \"$ref\": \"#/$defs/TestMetadata\"\n        },\n        \"database\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"const\": \"test\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/$defs/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/$defs/TestConfig\"\n        },\n        \"_event_status\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/ColumnInfo\"\n          },\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"group\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"docs\": {\n          \"$ref\": \"#/$defs/Docs\"\n        },\n        \"patch_path\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"build_path\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"created_at\": {\n          \"type\": \"number\"\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"relation_name\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"raw_code\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"language\": {\n          \"type\": \"string\",\n          \"default\": \"sql\"\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/RefArgs\"\n          }\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          }\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          }\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/$defs/DependsOn\"\n        },\n        \"compiled_path\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"compiled\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"compiled_code\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/InjectedCTE\"\n          }\n        },\n        \"_pre_injected_sql\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"contract\": {\n          \"$ref\": \"#/$defs/Contract\"\n        },\n        \"column_name\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"file_key_name\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"attached_node\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"test_metadata\",\n        \"database\",\n        \"schema\",\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"alias\",\n        \"checksum\"\n      ]\n    },\n    \"SnapshotConfig\": {\n      \"type\": \"object\",\n      \"title\": \"SnapshotConfig\",\n      \"properties\": {\n        \"_extra\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"alias\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"schema\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"database\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"tags\": {\n          \"anyOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"string\"\n            }\n          ]\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"group\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"materialized\": {\n          \"type\": \"string\",\n          \"default\": \"snapshot\"\n        },\n        \"incremental_strategy\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"persist_docs\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"post-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/Hook\"\n          }\n        },\n        \"pre-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/Hook\"\n          }\n        },\n        \"quoting\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"column_types\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"full_refresh\": {\n          \"anyOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"unique_key\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"on_schema_change\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": \"ignore\"\n        },\n        \"on_configuration_change\": {\n          \"enum\": [\n            \"apply\",\n            \"continue\",\n            \"fail\"\n          ]\n        },\n        \"grants\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"packages\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"docs\": {\n          \"$ref\": \"#/$defs/Docs\"\n        },\n        \"contract\": {\n          \"$ref\": \"#/$defs/ContractConfig\"\n        },\n        \"strategy\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"target_schema\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"target_database\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"updated_at\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"check_cols\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        }\n      },\n      \"additionalProperties\": true\n    },\n    \"SnapshotNode\": {\n      \"type\": \"object\",\n      \"title\": \"SnapshotNode\",\n      \"properties\": {\n        \"database\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"const\": \"snapshot\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/$defs/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/$defs/SnapshotConfig\"\n        },\n        \"_event_status\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/ColumnInfo\"\n          },\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"group\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"docs\": {\n          \"$ref\": \"#/$defs/Docs\"\n        },\n        \"patch_path\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"build_path\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"created_at\": {\n          \"type\": \"number\"\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"relation_name\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"raw_code\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"language\": {\n          \"type\": \"string\",\n          \"default\": \"sql\"\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/RefArgs\"\n          }\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          }\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          }\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/$defs/DependsOn\"\n        },\n        \"compiled_path\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"compiled\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"compiled_code\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/InjectedCTE\"\n          }\n        },\n        \"_pre_injected_sql\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"contract\": {\n          \"$ref\": \"#/$defs/Contract\"\n        },\n        \"defer_relation\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/$defs/DeferRelation\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"database\",\n        \"schema\",\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"alias\",\n        \"checksum\",\n        \"config\"\n      ]\n    },\n    \"UnitTestNodeConfig\": {\n      \"type\": \"object\",\n      \"title\": \"UnitTestNodeConfig\",\n      \"properties\": {\n        \"_extra\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"alias\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"schema\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"database\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"tags\": {\n          \"anyOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"string\"\n            }\n          ]\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"group\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"materialized\": {\n          \"type\": \"string\",\n          \"default\": \"view\"\n        },\n        \"incremental_strategy\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"persist_docs\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"post-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/Hook\"\n          }\n        },\n        \"pre-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/Hook\"\n          }\n        },\n        \"quoting\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"column_types\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"full_refresh\": {\n          \"anyOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"unique_key\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"on_schema_change\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": \"ignore\"\n        },\n        \"on_configuration_change\": {\n          \"enum\": [\n            \"apply\",\n            \"continue\",\n            \"fail\"\n          ]\n        },\n        \"grants\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"packages\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"docs\": {\n          \"$ref\": \"#/$defs/Docs\"\n        },\n        \"contract\": {\n          \"$ref\": \"#/$defs/ContractConfig\"\n        },\n        \"expected_rows\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"object\",\n            \"propertyNames\": {\n              \"type\": \"string\"\n            }\n          }\n        }\n      },\n      \"additionalProperties\": true\n    },\n    \"UnitTestOverrides\": {\n      \"type\": \"object\",\n      \"title\": \"UnitTestOverrides\",\n      \"properties\": {\n        \"macros\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"vars\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"env_vars\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"UnitTestNode\": {\n      \"type\": \"object\",\n      \"title\": \"UnitTestNode\",\n      \"properties\": {\n        \"database\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"const\": \"unit_test\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/$defs/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/$defs/UnitTestNodeConfig\"\n        },\n        \"_event_status\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/ColumnInfo\"\n          },\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"group\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"docs\": {\n          \"$ref\": \"#/$defs/Docs\"\n        },\n        \"patch_path\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"build_path\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"created_at\": {\n          \"type\": \"number\"\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"relation_name\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"raw_code\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"language\": {\n          \"type\": \"string\",\n          \"default\": \"sql\"\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/RefArgs\"\n          }\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          }\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          }\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/$defs/DependsOn\"\n        },\n        \"compiled_path\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"compiled\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"compiled_code\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/InjectedCTE\"\n          }\n        },\n        \"_pre_injected_sql\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"contract\": {\n          \"$ref\": \"#/$defs/Contract\"\n        },\n        \"tested_node_unique_id\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"this_input_node_unique_id\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"overrides\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/$defs/UnitTestOverrides\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"database\",\n        \"schema\",\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"alias\",\n        \"checksum\"\n      ]\n    },\n    \"SeedConfig\": {\n      \"type\": \"object\",\n      \"title\": \"SeedConfig\",\n      \"properties\": {\n        \"_extra\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"alias\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"schema\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"database\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"tags\": {\n          \"anyOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"string\"\n            }\n          ]\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"group\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"materialized\": {\n          \"type\": \"string\",\n          \"default\": \"seed\"\n        },\n        \"incremental_strategy\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"persist_docs\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"post-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/Hook\"\n          }\n        },\n        \"pre-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/Hook\"\n          }\n        },\n        \"quoting\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"column_types\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"full_refresh\": {\n          \"anyOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"unique_key\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"on_schema_change\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": \"ignore\"\n        },\n        \"on_configuration_change\": {\n          \"enum\": [\n            \"apply\",\n            \"continue\",\n            \"fail\"\n          ]\n        },\n        \"grants\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"packages\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"docs\": {\n          \"$ref\": \"#/$defs/Docs\"\n        },\n        \"contract\": {\n          \"$ref\": \"#/$defs/ContractConfig\"\n        },\n        \"delimiter\": {\n          \"type\": \"string\",\n          \"default\": \",\"\n        },\n        \"quote_columns\": {\n          \"anyOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        }\n      },\n      \"additionalProperties\": true\n    },\n    \"MacroDependsOn\": {\n      \"type\": \"object\",\n      \"title\": \"MacroDependsOn\",\n      \"properties\": {\n        \"macros\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"SeedNode\": {\n      \"type\": \"object\",\n      \"title\": \"SeedNode\",\n      \"properties\": {\n        \"database\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"const\": \"seed\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/$defs/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/$defs/SeedConfig\"\n        },\n        \"_event_status\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/ColumnInfo\"\n          },\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"group\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"docs\": {\n          \"$ref\": \"#/$defs/Docs\"\n        },\n        \"patch_path\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"build_path\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"created_at\": {\n          \"type\": \"number\"\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"relation_name\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"raw_code\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"root_path\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/$defs/MacroDependsOn\"\n        },\n        \"defer_relation\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/$defs/DeferRelation\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"database\",\n        \"schema\",\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"alias\",\n        \"checksum\"\n      ]\n    },\n    \"Quoting\": {\n      \"type\": \"object\",\n      \"title\": \"Quoting\",\n      \"properties\": {\n        \"database\": {\n          \"anyOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"schema\": {\n          \"anyOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"identifier\": {\n          \"anyOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"column\": {\n          \"anyOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"Time\": {\n      \"type\": \"object\",\n      \"title\": \"Time\",\n      \"properties\": {\n        \"count\": {\n          \"anyOf\": [\n            {\n              \"type\": \"integer\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"period\": {\n          \"anyOf\": [\n            {\n              \"enum\": [\n                \"minute\",\n                \"hour\",\n                \"day\"\n              ]\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"FreshnessThreshold\": {\n      \"type\": \"object\",\n      \"title\": \"FreshnessThreshold\",\n      \"properties\": {\n        \"warn_after\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/$defs/Time\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"error_after\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/$defs/Time\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"filter\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"ExternalPartition\": {\n      \"type\": \"object\",\n      \"title\": \"ExternalPartition\",\n      \"properties\": {\n        \"_extra\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"name\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"data_type\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        }\n      },\n      \"additionalProperties\": true\n    },\n    \"ExternalTable\": {\n      \"type\": \"object\",\n      \"title\": \"ExternalTable\",\n      \"properties\": {\n        \"_extra\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"location\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"file_format\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"row_format\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"tbl_properties\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"partitions\": {\n          \"anyOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"$ref\": \"#/$defs/ExternalPartition\"\n              }\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        }\n      },\n      \"additionalProperties\": true\n    },\n    \"SourceConfig\": {\n      \"type\": \"object\",\n      \"title\": \"SourceConfig\",\n      \"properties\": {\n        \"_extra\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        }\n      },\n      \"additionalProperties\": true\n    },\n    \"SourceDefinition\": {\n      \"type\": \"object\",\n      \"title\": \"SourceDefinition\",\n      \"properties\": {\n        \"database\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"const\": \"source\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"source_name\": {\n          \"type\": \"string\"\n        },\n        \"source_description\": {\n          \"type\": \"string\"\n        },\n        \"loader\": {\n          \"type\": \"string\"\n        },\n        \"identifier\": {\n          \"type\": \"string\"\n        },\n        \"_event_status\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"quoting\": {\n          \"$ref\": \"#/$defs/Quoting\"\n        },\n        \"loaded_at_field\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"freshness\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/$defs/FreshnessThreshold\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"external\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/$defs/ExternalTable\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/ColumnInfo\"\n          },\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"source_meta\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"config\": {\n          \"$ref\": \"#/$defs/SourceConfig\"\n        },\n        \"patch_path\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"relation_name\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"created_at\": {\n          \"type\": \"number\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"database\",\n        \"schema\",\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"source_name\",\n        \"source_description\",\n        \"loader\",\n        \"identifier\"\n      ]\n    },\n    \"MacroArgument\": {\n      \"type\": \"object\",\n      \"title\": \"MacroArgument\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"type\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"name\"\n      ]\n    },\n    \"Macro\": {\n      \"type\": \"object\",\n      \"title\": \"Macro\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"const\": \"macro\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"macro_sql\": {\n          \"type\": \"string\"\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/$defs/MacroDependsOn\"\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"docs\": {\n          \"$ref\": \"#/$defs/Docs\"\n        },\n        \"patch_path\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"arguments\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/MacroArgument\"\n          }\n        },\n        \"created_at\": {\n          \"type\": \"number\"\n        },\n        \"supported_languages\": {\n          \"anyOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"enum\": [\n                  \"python\",\n                  \"sql\"\n                ]\n              }\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"macro_sql\"\n      ]\n    },\n    \"Documentation\": {\n      \"type\": \"object\",\n      \"title\": \"Documentation\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"const\": \"doc\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"block_contents\": {\n          \"type\": \"string\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"block_contents\"\n      ]\n    },\n    \"Owner\": {\n      \"type\": \"object\",\n      \"title\": \"Owner\",\n      \"properties\": {\n        \"_extra\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"email\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"name\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        }\n      },\n      \"additionalProperties\": true\n    },\n    \"ExposureConfig\": {\n      \"type\": \"object\",\n      \"title\": \"ExposureConfig\",\n      \"properties\": {\n        \"_extra\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        }\n      },\n      \"additionalProperties\": true\n    },\n    \"Exposure\": {\n      \"type\": \"object\",\n      \"title\": \"Exposure\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"const\": \"exposure\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"type\": {\n          \"enum\": [\n            \"dashboard\",\n            \"notebook\",\n            \"analysis\",\n            \"ml\",\n            \"application\"\n          ]\n        },\n        \"owner\": {\n          \"$ref\": \"#/$defs/Owner\"\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"label\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"maturity\": {\n          \"anyOf\": [\n            {\n              \"enum\": [\n                \"low\",\n                \"medium\",\n                \"high\"\n              ]\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"config\": {\n          \"$ref\": \"#/$defs/ExposureConfig\"\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"url\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/$defs/DependsOn\"\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/RefArgs\"\n          }\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          }\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          }\n        },\n        \"created_at\": {\n          \"type\": \"number\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"type\",\n        \"owner\"\n      ]\n    },\n    \"WhereFilter\": {\n      \"type\": \"object\",\n      \"title\": \"WhereFilter\",\n      \"properties\": {\n        \"where_sql_template\": {\n          \"type\": \"string\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"where_sql_template\"\n      ]\n    },\n    \"WhereFilterIntersection\": {\n      \"type\": \"object\",\n      \"title\": \"WhereFilterIntersection\",\n      \"properties\": {\n        \"where_filters\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/WhereFilter\"\n          }\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"where_filters\"\n      ]\n    },\n    \"MetricInputMeasure\": {\n      \"type\": \"object\",\n      \"title\": \"MetricInputMeasure\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"filter\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/$defs/WhereFilterIntersection\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"alias\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"join_to_timespine\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"fill_nulls_with\": {\n          \"anyOf\": [\n            {\n              \"type\": \"integer\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"name\"\n      ]\n    },\n    \"MetricTimeWindow\": {\n      \"type\": \"object\",\n      \"title\": \"MetricTimeWindow\",\n      \"properties\": {\n        \"count\": {\n          \"type\": \"integer\"\n        },\n        \"granularity\": {\n          \"enum\": [\n            \"day\",\n            \"week\",\n            \"month\",\n            \"quarter\",\n            \"year\"\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"count\",\n        \"granularity\"\n      ]\n    },\n    \"MetricInput\": {\n      \"type\": \"object\",\n      \"title\": \"MetricInput\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"filter\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/$defs/WhereFilterIntersection\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"alias\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"offset_window\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/$defs/MetricTimeWindow\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"offset_to_grain\": {\n          \"anyOf\": [\n            {\n              \"enum\": [\n                \"day\",\n                \"week\",\n                \"month\",\n                \"quarter\",\n                \"year\"\n              ]\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"name\"\n      ]\n    },\n    \"MetricTypeParams\": {\n      \"type\": \"object\",\n      \"title\": \"MetricTypeParams\",\n      \"properties\": {\n        \"measure\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/$defs/MetricInputMeasure\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"input_measures\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/MetricInputMeasure\"\n          }\n        },\n        \"numerator\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/$defs/MetricInput\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"denominator\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/$defs/MetricInput\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"expr\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"window\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/$defs/MetricTimeWindow\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"grain_to_date\": {\n          \"anyOf\": [\n            {\n              \"enum\": [\n                \"day\",\n                \"week\",\n                \"month\",\n                \"quarter\",\n                \"year\"\n              ]\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"metrics\": {\n          \"anyOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"$ref\": \"#/$defs/MetricInput\"\n              }\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"FileSlice\": {\n      \"type\": \"object\",\n      \"title\": \"FileSlice\",\n      \"properties\": {\n        \"filename\": {\n          \"type\": \"string\"\n        },\n        \"content\": {\n          \"type\": \"string\"\n        },\n        \"start_line_number\": {\n          \"type\": \"integer\"\n        },\n        \"end_line_number\": {\n          \"type\": \"integer\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"filename\",\n        \"content\",\n        \"start_line_number\",\n        \"end_line_number\"\n      ]\n    },\n    \"SourceFileMetadata\": {\n      \"type\": \"object\",\n      \"title\": \"SourceFileMetadata\",\n      \"properties\": {\n        \"repo_file_path\": {\n          \"type\": \"string\"\n        },\n        \"file_slice\": {\n          \"$ref\": \"#/$defs/FileSlice\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"repo_file_path\",\n        \"file_slice\"\n      ]\n    },\n    \"MetricConfig\": {\n      \"type\": \"object\",\n      \"title\": \"MetricConfig\",\n      \"properties\": {\n        \"_extra\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"group\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        }\n      },\n      \"additionalProperties\": true\n    },\n    \"Metric\": {\n      \"type\": \"object\",\n      \"title\": \"Metric\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"const\": \"metric\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"label\": {\n          \"type\": \"string\"\n        },\n        \"type\": {\n          \"enum\": [\n            \"simple\",\n            \"ratio\",\n            \"cumulative\",\n            \"derived\"\n          ]\n        },\n        \"type_params\": {\n          \"$ref\": \"#/$defs/MetricTypeParams\"\n        },\n        \"filter\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/$defs/WhereFilterIntersection\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"metadata\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/$defs/SourceFileMetadata\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"config\": {\n          \"$ref\": \"#/$defs/MetricConfig\"\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          }\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/$defs/DependsOn\"\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/RefArgs\"\n          }\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          }\n        },\n        \"created_at\": {\n          \"type\": \"number\"\n        },\n        \"group\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"description\",\n        \"label\",\n        \"type\",\n        \"type_params\"\n      ]\n    },\n    \"Group\": {\n      \"type\": \"object\",\n      \"title\": \"Group\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"const\": \"group\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"owner\": {\n          \"$ref\": \"#/$defs/Owner\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"owner\"\n      ]\n    },\n    \"QueryParams\": {\n      \"type\": \"object\",\n      \"title\": \"QueryParams\",\n      \"properties\": {\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"group_by\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"where\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/$defs/WhereFilterIntersection\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"metrics\",\n        \"group_by\",\n        \"where\"\n      ]\n    },\n    \"ExportConfig\": {\n      \"type\": \"object\",\n      \"title\": \"ExportConfig\",\n      \"properties\": {\n        \"export_as\": {\n          \"enum\": [\n            \"table\",\n            \"view\"\n          ]\n        },\n        \"schema_name\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"alias\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"export_as\"\n      ]\n    },\n    \"Export\": {\n      \"type\": \"object\",\n      \"title\": \"Export\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"config\": {\n          \"$ref\": \"#/$defs/ExportConfig\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"name\",\n        \"config\"\n      ]\n    },\n    \"SavedQueryConfig\": {\n      \"type\": \"object\",\n      \"title\": \"SavedQueryConfig\",\n      \"properties\": {\n        \"_extra\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"group\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"export_as\": {\n          \"anyOf\": [\n            {\n              \"enum\": [\n                \"table\",\n                \"view\"\n              ]\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"schema\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        }\n      },\n      \"additionalProperties\": true\n    },\n    \"SavedQuery\": {\n      \"type\": \"object\",\n      \"title\": \"SavedQuery\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"enum\": [\n            \"model\",\n            \"analysis\",\n            \"test\",\n            \"snapshot\",\n            \"operation\",\n            \"seed\",\n            \"rpc\",\n            \"sql_operation\",\n            \"doc\",\n            \"source\",\n            \"macro\",\n            \"exposure\",\n            \"metric\",\n            \"group\",\n            \"saved_query\",\n            \"semantic_model\",\n            \"unit_test\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"query_params\": {\n          \"$ref\": \"#/$defs/QueryParams\"\n        },\n        \"exports\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/Export\"\n          }\n        },\n        \"_event_status\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"description\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"label\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"metadata\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/$defs/SourceFileMetadata\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"config\": {\n          \"$ref\": \"#/$defs/SavedQueryConfig\"\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"group\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/$defs/DependsOn\"\n        },\n        \"created_at\": {\n          \"type\": \"number\"\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/RefArgs\"\n          }\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"query_params\",\n        \"exports\"\n      ]\n    },\n    \"NodeRelation\": {\n      \"type\": \"object\",\n      \"title\": \"NodeRelation\",\n      \"properties\": {\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"schema_name\": {\n          \"type\": \"string\"\n        },\n        \"database\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"relation_name\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"alias\",\n        \"schema_name\"\n      ]\n    },\n    \"Defaults\": {\n      \"type\": \"object\",\n      \"title\": \"Defaults\",\n      \"properties\": {\n        \"agg_time_dimension\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"Entity\": {\n      \"type\": \"object\",\n      \"title\": \"Entity\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"type\": {\n          \"enum\": [\n            \"foreign\",\n            \"natural\",\n            \"primary\",\n            \"unique\"\n          ]\n        },\n        \"description\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"label\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"role\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"expr\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"name\",\n        \"type\"\n      ]\n    },\n    \"MeasureAggregationParameters\": {\n      \"type\": \"object\",\n      \"title\": \"MeasureAggregationParameters\",\n      \"properties\": {\n        \"percentile\": {\n          \"anyOf\": [\n            {\n              \"type\": \"number\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"use_discrete_percentile\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"use_approximate_percentile\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"NonAdditiveDimension\": {\n      \"type\": \"object\",\n      \"title\": \"NonAdditiveDimension\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"window_choice\": {\n          \"enum\": [\n            \"sum\",\n            \"min\",\n            \"max\",\n            \"count_distinct\",\n            \"sum_boolean\",\n            \"average\",\n            \"percentile\",\n            \"median\",\n            \"count\"\n          ]\n        },\n        \"window_groupings\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"name\",\n        \"window_choice\",\n        \"window_groupings\"\n      ]\n    },\n    \"Measure\": {\n      \"type\": \"object\",\n      \"title\": \"Measure\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"agg\": {\n          \"enum\": [\n            \"sum\",\n            \"min\",\n            \"max\",\n            \"count_distinct\",\n            \"sum_boolean\",\n            \"average\",\n            \"percentile\",\n            \"median\",\n            \"count\"\n          ]\n        },\n        \"description\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"label\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"create_metric\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"expr\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"agg_params\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/$defs/MeasureAggregationParameters\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"non_additive_dimension\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/$defs/NonAdditiveDimension\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"agg_time_dimension\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"name\",\n        \"agg\"\n      ]\n    },\n    \"DimensionValidityParams\": {\n      \"type\": \"object\",\n      \"title\": \"DimensionValidityParams\",\n      \"properties\": {\n        \"is_start\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"is_end\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"DimensionTypeParams\": {\n      \"type\": \"object\",\n      \"title\": \"DimensionTypeParams\",\n      \"properties\": {\n        \"time_granularity\": {\n          \"enum\": [\n            \"day\",\n            \"week\",\n            \"month\",\n            \"quarter\",\n            \"year\"\n          ]\n        },\n        \"validity_params\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/$defs/DimensionValidityParams\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"time_granularity\"\n      ]\n    },\n    \"Dimension\": {\n      \"type\": \"object\",\n      \"title\": \"Dimension\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"type\": {\n          \"enum\": [\n            \"categorical\",\n            \"time\"\n          ]\n        },\n        \"description\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"label\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"is_partition\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"type_params\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/$defs/DimensionTypeParams\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"expr\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"metadata\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/$defs/SourceFileMetadata\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"name\",\n        \"type\"\n      ]\n    },\n    \"SemanticModelConfig\": {\n      \"type\": \"object\",\n      \"title\": \"SemanticModelConfig\",\n      \"properties\": {\n        \"_extra\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"group\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        }\n      },\n      \"additionalProperties\": true\n    },\n    \"SemanticModel\": {\n      \"type\": \"object\",\n      \"title\": \"SemanticModel\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"enum\": [\n            \"model\",\n            \"analysis\",\n            \"test\",\n            \"snapshot\",\n            \"operation\",\n            \"seed\",\n            \"rpc\",\n            \"sql_operation\",\n            \"doc\",\n            \"source\",\n            \"macro\",\n            \"exposure\",\n            \"metric\",\n            \"group\",\n            \"saved_query\",\n            \"semantic_model\",\n            \"unit_test\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"model\": {\n          \"type\": \"string\"\n        },\n        \"node_relation\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/$defs/NodeRelation\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"description\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"label\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"defaults\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/$defs/Defaults\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"entities\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/Entity\"\n          }\n        },\n        \"measures\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/Measure\"\n          }\n        },\n        \"dimensions\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/Dimension\"\n          }\n        },\n        \"metadata\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/$defs/SourceFileMetadata\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/$defs/DependsOn\"\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/RefArgs\"\n          }\n        },\n        \"created_at\": {\n          \"type\": \"number\"\n        },\n        \"config\": {\n          \"$ref\": \"#/$defs/SemanticModelConfig\"\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"primary_entity\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"group\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"model\",\n        \"node_relation\"\n      ]\n    },\n    \"UnitTestInputFixture\": {\n      \"type\": \"object\",\n      \"title\": \"UnitTestInputFixture\",\n      \"properties\": {\n        \"input\": {\n          \"type\": \"string\"\n        },\n        \"rows\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              }\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"format\": {\n          \"enum\": [\n            \"csv\",\n            \"dict\"\n          ],\n          \"default\": \"dict\"\n        },\n        \"fixture\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"input\"\n      ]\n    },\n    \"UnitTestOutputFixture\": {\n      \"type\": \"object\",\n      \"title\": \"UnitTestOutputFixture\",\n      \"properties\": {\n        \"rows\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              }\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"format\": {\n          \"enum\": [\n            \"csv\",\n            \"dict\"\n          ],\n          \"default\": \"dict\"\n        },\n        \"fixture\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"UnitTestConfig\": {\n      \"type\": \"object\",\n      \"title\": \"UnitTestConfig\",\n      \"properties\": {\n        \"_extra\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"tags\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            }\n          ]\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        }\n      },\n      \"additionalProperties\": true\n    },\n    \"UnitTestDefinition\": {\n      \"type\": \"object\",\n      \"title\": \"UnitTestDefinition\",\n      \"properties\": {\n        \"model\": {\n          \"type\": \"string\"\n        },\n        \"given\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/UnitTestInputFixture\"\n          }\n        },\n        \"expect\": {\n          \"$ref\": \"#/$defs/UnitTestOutputFixture\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"enum\": [\n            \"model\",\n            \"analysis\",\n            \"test\",\n            \"snapshot\",\n            \"operation\",\n            \"seed\",\n            \"rpc\",\n            \"sql_operation\",\n            \"doc\",\n            \"source\",\n            \"macro\",\n            \"exposure\",\n            \"metric\",\n            \"group\",\n            \"saved_query\",\n            \"semantic_model\",\n            \"unit_test\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"_event_status\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"overrides\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/$defs/UnitTestOverrides\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/$defs/DependsOn\"\n        },\n        \"config\": {\n          \"$ref\": \"#/$defs/UnitTestConfig\"\n        },\n        \"checksum\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"schema\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"model\",\n        \"given\",\n        \"expect\",\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\"\n      ]\n    },\n    \"WritableManifest\": {\n      \"type\": \"object\",\n      \"title\": \"WritableManifest\",\n      \"properties\": {\n        \"metadata\": {\n          \"description\": \"Metadata about the manifest\",\n          \"$ref\": \"#/$defs/ManifestMetadata\"\n        },\n        \"nodes\": {\n          \"type\": \"object\",\n          \"description\": \"The nodes defined in the dbt project and its dependencies\",\n          \"additionalProperties\": {\n            \"anyOf\": [\n              {\n                \"$ref\": \"#/$defs/AnalysisNode\"\n              },\n              {\n                \"$ref\": \"#/$defs/SingularTestNode\"\n              },\n              {\n                \"$ref\": \"#/$defs/HookNode\"\n              },\n              {\n                \"$ref\": \"#/$defs/ModelNode\"\n              },\n              {\n                \"$ref\": \"#/$defs/RPCNode\"\n              },\n              {\n                \"$ref\": \"#/$defs/SqlNode\"\n              },\n              {\n                \"$ref\": \"#/$defs/GenericTestNode\"\n              },\n              {\n                \"$ref\": \"#/$defs/SnapshotNode\"\n              },\n              {\n                \"$ref\": \"#/$defs/UnitTestNode\"\n              },\n              {\n                \"$ref\": \"#/$defs/SeedNode\"\n              }\n            ]\n          },\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"sources\": {\n          \"type\": \"object\",\n          \"description\": \"The sources defined in the dbt project and its dependencies\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/SourceDefinition\"\n          },\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"macros\": {\n          \"type\": \"object\",\n          \"description\": \"The macros defined in the dbt project and its dependencies\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/Macro\"\n          },\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"docs\": {\n          \"type\": \"object\",\n          \"description\": \"The docs defined in the dbt project and its dependencies\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/Documentation\"\n          },\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"exposures\": {\n          \"type\": \"object\",\n          \"description\": \"The exposures defined in the dbt project and its dependencies\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/Exposure\"\n          },\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"metrics\": {\n          \"type\": \"object\",\n          \"description\": \"The metrics defined in the dbt project and its dependencies\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/Metric\"\n          },\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"groups\": {\n          \"type\": \"object\",\n          \"description\": \"The groups defined in the dbt project\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/Group\"\n          },\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"selectors\": {\n          \"type\": \"object\",\n          \"description\": \"The selectors defined in selectors.yml\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"disabled\": {\n          \"description\": \"A mapping of the disabled nodes in the target\",\n          \"anyOf\": [\n            {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"anyOf\": [\n                    {\n                      \"$ref\": \"#/$defs/AnalysisNode\"\n                    },\n                    {\n                      \"$ref\": \"#/$defs/SingularTestNode\"\n                    },\n                    {\n                      \"$ref\": \"#/$defs/HookNode\"\n                    },\n                    {\n                      \"$ref\": \"#/$defs/ModelNode\"\n                    },\n                    {\n                      \"$ref\": \"#/$defs/RPCNode\"\n                    },\n                    {\n                      \"$ref\": \"#/$defs/SqlNode\"\n                    },\n                    {\n                      \"$ref\": \"#/$defs/GenericTestNode\"\n                    },\n                    {\n                      \"$ref\": \"#/$defs/SnapshotNode\"\n                    },\n                    {\n                      \"$ref\": \"#/$defs/UnitTestNode\"\n                    },\n                    {\n                      \"$ref\": \"#/$defs/SeedNode\"\n                    },\n                    {\n                      \"$ref\": \"#/$defs/SourceDefinition\"\n                    },\n                    {\n                      \"$ref\": \"#/$defs/Exposure\"\n                    },\n                    {\n                      \"$ref\": \"#/$defs/Metric\"\n                    },\n                    {\n                      \"$ref\": \"#/$defs/SavedQuery\"\n                    },\n                    {\n                      \"$ref\": \"#/$defs/SemanticModel\"\n                    },\n                    {\n                      \"$ref\": \"#/$defs/UnitTestDefinition\"\n                    }\n                  ]\n                }\n              },\n              \"propertyNames\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"parent_map\": {\n          \"description\": \"A mapping from\\u00a0child nodes to their dependencies\",\n          \"anyOf\": [\n            {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"propertyNames\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"child_map\": {\n          \"description\": \"A mapping from parent nodes to their dependents\",\n          \"anyOf\": [\n            {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"propertyNames\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"group_map\": {\n          \"description\": \"A mapping from group names to their nodes\",\n          \"anyOf\": [\n            {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"propertyNames\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"saved_queries\": {\n          \"type\": \"object\",\n          \"description\": \"The saved queries defined in the dbt project\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/SavedQuery\"\n          },\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"semantic_models\": {\n          \"type\": \"object\",\n          \"description\": \"The semantic models defined in the dbt project\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/SemanticModel\"\n          },\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unit_tests\": {\n          \"type\": \"object\",\n          \"description\": \"The unit tests defined in the project\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/UnitTestDefinition\"\n          },\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"metadata\",\n        \"nodes\",\n        \"sources\",\n        \"macros\",\n        \"docs\",\n        \"exposures\",\n        \"metrics\",\n        \"groups\",\n        \"selectors\",\n        \"disabled\",\n        \"parent_map\",\n        \"child_map\",\n        \"group_map\",\n        \"saved_queries\",\n        \"semantic_models\",\n        \"unit_tests\"\n      ]\n    }\n  },\n  \"$id\": \"https://schemas.getdbt.com/dbt/manifest/v11.json\"\n}"
  },
  {
    "path": "schemas/dbt/manifest/v12.json",
    "content": "{\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"type\": \"object\",\n  \"title\": \"WritableManifest\",\n  \"properties\": {\n    \"metadata\": {\n      \"type\": \"object\",\n      \"title\": \"ManifestMetadata\",\n      \"description\": \"Metadata about the manifest\",\n      \"properties\": {\n        \"dbt_schema_version\": {\n          \"type\": \"string\"\n        },\n        \"dbt_version\": {\n          \"type\": \"string\",\n          \"default\": \"1.12.0a1\"\n        },\n        \"generated_at\": {\n          \"type\": \"string\"\n        },\n        \"invocation_id\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"invocation_started_at\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"env\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          },\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"project_name\": {\n          \"description\": \"Name of the root project\",\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"project_id\": {\n          \"description\": \"A unique identifier for the project, hashed from the project name\",\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"user_id\": {\n          \"description\": \"A unique identifier for the user\",\n          \"anyOf\": [\n            {\n              \"type\": \"string\",\n              \"format\": \"uuid\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"send_anonymous_usage_stats\": {\n          \"description\": \"Whether dbt is configured to send anonymous usage statistics\",\n          \"anyOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"adapter_type\": {\n          \"description\": \"The type name of the adapter\",\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"quoting\": {\n          \"description\": \"The quoting configuration for the project\",\n          \"anyOf\": [\n            {\n              \"type\": \"object\",\n              \"title\": \"Quoting\",\n              \"properties\": {\n                \"database\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"boolean\"\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                },\n                \"schema\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"boolean\"\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                },\n                \"identifier\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"boolean\"\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                },\n                \"column\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"boolean\"\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                }\n              },\n              \"additionalProperties\": false\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"run_started_at\": {\n          \"description\": \"The timestamp when the run started\",\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"nodes\": {\n      \"type\": \"object\",\n      \"description\": \"The nodes defined in the dbt project and its dependencies\",\n      \"additionalProperties\": {\n        \"anyOf\": [\n          {\n            \"type\": \"object\",\n            \"title\": \"Seed\",\n            \"properties\": {\n              \"database\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ]\n              },\n              \"schema\": {\n                \"type\": \"string\"\n              },\n              \"name\": {\n                \"type\": \"string\"\n              },\n              \"resource_type\": {\n                \"const\": \"seed\"\n              },\n              \"package_name\": {\n                \"type\": \"string\"\n              },\n              \"path\": {\n                \"type\": \"string\"\n              },\n              \"original_file_path\": {\n                \"type\": \"string\"\n              },\n              \"unique_id\": {\n                \"type\": \"string\"\n              },\n              \"fqn\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"alias\": {\n                \"type\": \"string\"\n              },\n              \"checksum\": {\n                \"type\": \"object\",\n                \"title\": \"FileHash\",\n                \"properties\": {\n                  \"name\": {\n                    \"type\": \"string\"\n                  },\n                  \"checksum\": {\n                    \"type\": \"string\"\n                  }\n                },\n                \"additionalProperties\": false,\n                \"required\": [\n                  \"name\",\n                  \"checksum\"\n                ]\n              },\n              \"config\": {\n                \"type\": \"object\",\n                \"title\": \"SeedConfig\",\n                \"properties\": {\n                  \"_extra\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"enabled\": {\n                    \"type\": \"boolean\",\n                    \"default\": true\n                  },\n                  \"alias\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"schema\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"database\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"tags\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      },\n                      {\n                        \"type\": \"string\"\n                      }\n                    ]\n                  },\n                  \"meta\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"group\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"materialized\": {\n                    \"type\": \"string\",\n                    \"default\": \"seed\"\n                  },\n                  \"incremental_strategy\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"batch_size\": {\n                    \"default\": null\n                  },\n                  \"lookback\": {\n                    \"default\": 1\n                  },\n                  \"begin\": {\n                    \"default\": null\n                  },\n                  \"persist_docs\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"post-hook\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"title\": \"Hook\",\n                      \"properties\": {\n                        \"sql\": {\n                          \"type\": \"string\"\n                        },\n                        \"transaction\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"index\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"integer\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": false,\n                      \"required\": [\n                        \"sql\"\n                      ]\n                    }\n                  },\n                  \"pre-hook\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"title\": \"Hook\",\n                      \"properties\": {\n                        \"sql\": {\n                          \"type\": \"string\"\n                        },\n                        \"transaction\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"index\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"integer\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": false,\n                      \"required\": [\n                        \"sql\"\n                      ]\n                    }\n                  },\n                  \"quoting\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"column_types\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"full_refresh\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"boolean\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"unique_key\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"on_schema_change\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": \"ignore\"\n                  },\n                  \"on_configuration_change\": {\n                    \"enum\": [\n                      \"apply\",\n                      \"continue\",\n                      \"fail\"\n                    ]\n                  },\n                  \"grants\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"packages\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"docs\": {\n                    \"type\": \"object\",\n                    \"title\": \"Docs\",\n                    \"properties\": {\n                      \"show\": {\n                        \"type\": \"boolean\",\n                        \"default\": true\n                      },\n                      \"node_color\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"string\"\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ],\n                        \"default\": null\n                      }\n                    },\n                    \"additionalProperties\": false\n                  },\n                  \"contract\": {\n                    \"type\": \"object\",\n                    \"title\": \"ContractConfig\",\n                    \"properties\": {\n                      \"enforced\": {\n                        \"type\": \"boolean\",\n                        \"default\": false\n                      },\n                      \"alias_types\": {\n                        \"type\": \"boolean\",\n                        \"default\": true\n                      }\n                    },\n                    \"additionalProperties\": false\n                  },\n                  \"event_time\": {\n                    \"default\": null\n                  },\n                  \"concurrent_batches\": {\n                    \"default\": null\n                  },\n                  \"delimiter\": {\n                    \"type\": \"string\",\n                    \"default\": \",\"\n                  },\n                  \"quote_columns\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"boolean\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  }\n                },\n                \"additionalProperties\": true\n              },\n              \"tags\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"description\": {\n                \"type\": \"string\",\n                \"default\": \"\"\n              },\n              \"columns\": {\n                \"type\": \"object\",\n                \"additionalProperties\": {\n                  \"type\": \"object\",\n                  \"title\": \"ColumnInfo\",\n                  \"properties\": {\n                    \"name\": {\n                      \"type\": \"string\"\n                    },\n                    \"description\": {\n                      \"type\": \"string\",\n                      \"default\": \"\"\n                    },\n                    \"meta\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"data_type\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"constraints\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"object\",\n                        \"title\": \"ColumnLevelConstraint\",\n                        \"properties\": {\n                          \"type\": {\n                            \"enum\": [\n                              \"check\",\n                              \"not_null\",\n                              \"unique\",\n                              \"primary_key\",\n                              \"foreign_key\",\n                              \"custom\"\n                            ]\n                          },\n                          \"name\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"expression\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"warn_unenforced\": {\n                            \"type\": \"boolean\",\n                            \"default\": true\n                          },\n                          \"warn_unsupported\": {\n                            \"type\": \"boolean\",\n                            \"default\": true\n                          },\n                          \"to\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"to_columns\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"string\"\n                            }\n                          }\n                        },\n                        \"additionalProperties\": false,\n                        \"required\": [\n                          \"type\"\n                        ]\n                      }\n                    },\n                    \"quote\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"boolean\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"config\": {\n                      \"type\": \"object\",\n                      \"title\": \"ColumnConfig\",\n                      \"properties\": {\n                        \"_extra\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"meta\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"tags\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      },\n                      \"additionalProperties\": true\n                    },\n                    \"tags\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"_extra\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"granularity\": {\n                      \"anyOf\": [\n                        {\n                          \"enum\": [\n                            \"nanosecond\",\n                            \"microsecond\",\n                            \"millisecond\",\n                            \"second\",\n                            \"minute\",\n                            \"hour\",\n                            \"day\",\n                            \"week\",\n                            \"month\",\n                            \"quarter\",\n                            \"year\"\n                          ]\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"dimension\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"object\",\n                          \"title\": \"ColumnDimension\",\n                          \"properties\": {\n                            \"name\": {\n                              \"type\": \"string\"\n                            },\n                            \"type\": {\n                              \"enum\": [\n                                \"categorical\",\n                                \"time\"\n                              ]\n                            },\n                            \"description\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"label\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"is_partition\": {\n                              \"type\": \"boolean\",\n                              \"default\": false\n                            },\n                            \"config\": {\n                              \"type\": \"object\",\n                              \"propertyNames\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            \"validity_params\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"object\",\n                                  \"title\": \"ColumnDimensionValidityParams\",\n                                  \"properties\": {\n                                    \"is_start\": {\n                                      \"type\": \"boolean\",\n                                      \"default\": false\n                                    },\n                                    \"is_end\": {\n                                      \"type\": \"boolean\",\n                                      \"default\": false\n                                    }\n                                  },\n                                  \"additionalProperties\": false\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            }\n                          },\n                          \"additionalProperties\": false,\n                          \"required\": [\n                            \"name\",\n                            \"type\"\n                          ]\n                        },\n                        {\n                          \"enum\": [\n                            \"categorical\",\n                            \"time\"\n                          ]\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"entity\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"object\",\n                          \"title\": \"ColumnEntity\",\n                          \"properties\": {\n                            \"name\": {\n                              \"type\": \"string\"\n                            },\n                            \"type\": {\n                              \"enum\": [\n                                \"foreign\",\n                                \"natural\",\n                                \"primary\",\n                                \"unique\"\n                              ]\n                            },\n                            \"description\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"label\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"config\": {\n                              \"type\": \"object\",\n                              \"propertyNames\": {\n                                \"type\": \"string\"\n                              }\n                            }\n                          },\n                          \"additionalProperties\": false,\n                          \"required\": [\n                            \"name\",\n                            \"type\"\n                          ]\n                        },\n                        {\n                          \"enum\": [\n                            \"foreign\",\n                            \"natural\",\n                            \"primary\",\n                            \"unique\"\n                          ]\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"doc_blocks\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    }\n                  },\n                  \"additionalProperties\": true,\n                  \"required\": [\n                    \"name\"\n                  ]\n                },\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"meta\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"group\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"docs\": {\n                \"type\": \"object\",\n                \"title\": \"Docs\",\n                \"properties\": {\n                  \"show\": {\n                    \"type\": \"boolean\",\n                    \"default\": true\n                  },\n                  \"node_color\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  }\n                },\n                \"additionalProperties\": false\n              },\n              \"patch_path\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"build_path\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"unrendered_config\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"created_at\": {\n                \"type\": \"number\"\n              },\n              \"config_call_dict\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"unrendered_config_call_dict\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"relation_name\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"raw_code\": {\n                \"type\": \"string\",\n                \"default\": \"\"\n              },\n              \"doc_blocks\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"root_path\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"depends_on\": {\n                \"type\": \"object\",\n                \"title\": \"MacroDependsOn\",\n                \"properties\": {\n                  \"macros\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  }\n                },\n                \"additionalProperties\": false\n              },\n              \"defer_relation\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"object\",\n                    \"title\": \"DeferRelation\",\n                    \"properties\": {\n                      \"database\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"string\"\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ]\n                      },\n                      \"schema\": {\n                        \"type\": \"string\"\n                      },\n                      \"alias\": {\n                        \"type\": \"string\"\n                      },\n                      \"relation_name\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"string\"\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ]\n                      },\n                      \"resource_type\": {\n                        \"enum\": [\n                          \"model\",\n                          \"analysis\",\n                          \"test\",\n                          \"snapshot\",\n                          \"operation\",\n                          \"seed\",\n                          \"rpc\",\n                          \"sql_operation\",\n                          \"doc\",\n                          \"source\",\n                          \"macro\",\n                          \"exposure\",\n                          \"metric\",\n                          \"group\",\n                          \"saved_query\",\n                          \"semantic_model\",\n                          \"unit_test\",\n                          \"fixture\",\n                          \"function\"\n                        ]\n                      },\n                      \"name\": {\n                        \"type\": \"string\"\n                      },\n                      \"description\": {\n                        \"type\": \"string\"\n                      },\n                      \"compiled_code\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"string\"\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ]\n                      },\n                      \"meta\": {\n                        \"type\": \"object\",\n                        \"propertyNames\": {\n                          \"type\": \"string\"\n                        }\n                      },\n                      \"tags\": {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      },\n                      \"config\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"object\",\n                            \"title\": \"NodeConfig\",\n                            \"properties\": {\n                              \"_extra\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"enabled\": {\n                                \"type\": \"boolean\",\n                                \"default\": true\n                              },\n                              \"alias\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"string\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"schema\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"string\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"database\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"string\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"tags\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"array\",\n                                    \"items\": {\n                                      \"type\": \"string\"\n                                    }\n                                  },\n                                  {\n                                    \"type\": \"string\"\n                                  }\n                                ]\n                              },\n                              \"meta\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"group\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"string\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"materialized\": {\n                                \"type\": \"string\",\n                                \"default\": \"view\"\n                              },\n                              \"incremental_strategy\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"string\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"batch_size\": {\n                                \"default\": null\n                              },\n                              \"lookback\": {\n                                \"default\": 1\n                              },\n                              \"begin\": {\n                                \"default\": null\n                              },\n                              \"persist_docs\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"post-hook\": {\n                                \"type\": \"array\",\n                                \"items\": {\n                                  \"type\": \"object\",\n                                  \"title\": \"Hook\",\n                                  \"properties\": {\n                                    \"sql\": {\n                                      \"type\": \"string\"\n                                    },\n                                    \"transaction\": {\n                                      \"type\": \"boolean\",\n                                      \"default\": true\n                                    },\n                                    \"index\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"integer\"\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    }\n                                  },\n                                  \"additionalProperties\": false,\n                                  \"required\": [\n                                    \"sql\"\n                                  ]\n                                }\n                              },\n                              \"pre-hook\": {\n                                \"type\": \"array\",\n                                \"items\": {\n                                  \"type\": \"object\",\n                                  \"title\": \"Hook\",\n                                  \"properties\": {\n                                    \"sql\": {\n                                      \"type\": \"string\"\n                                    },\n                                    \"transaction\": {\n                                      \"type\": \"boolean\",\n                                      \"default\": true\n                                    },\n                                    \"index\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"integer\"\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    }\n                                  },\n                                  \"additionalProperties\": false,\n                                  \"required\": [\n                                    \"sql\"\n                                  ]\n                                }\n                              },\n                              \"quoting\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"column_types\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"full_refresh\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"boolean\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"unique_key\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"string\"\n                                  },\n                                  {\n                                    \"type\": \"array\",\n                                    \"items\": {\n                                      \"type\": \"string\"\n                                    }\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"on_schema_change\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"string\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": \"ignore\"\n                              },\n                              \"on_configuration_change\": {\n                                \"enum\": [\n                                  \"apply\",\n                                  \"continue\",\n                                  \"fail\"\n                                ]\n                              },\n                              \"grants\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"packages\": {\n                                \"type\": \"array\",\n                                \"items\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"docs\": {\n                                \"type\": \"object\",\n                                \"title\": \"Docs\",\n                                \"properties\": {\n                                  \"show\": {\n                                    \"type\": \"boolean\",\n                                    \"default\": true\n                                  },\n                                  \"node_color\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  }\n                                },\n                                \"additionalProperties\": false\n                              },\n                              \"contract\": {\n                                \"type\": \"object\",\n                                \"title\": \"ContractConfig\",\n                                \"properties\": {\n                                  \"enforced\": {\n                                    \"type\": \"boolean\",\n                                    \"default\": false\n                                  },\n                                  \"alias_types\": {\n                                    \"type\": \"boolean\",\n                                    \"default\": true\n                                  }\n                                },\n                                \"additionalProperties\": false\n                              },\n                              \"event_time\": {\n                                \"default\": null\n                              },\n                              \"concurrent_batches\": {\n                                \"default\": null\n                              }\n                            },\n                            \"additionalProperties\": true\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ]\n                      }\n                    },\n                    \"additionalProperties\": false,\n                    \"required\": [\n                      \"database\",\n                      \"schema\",\n                      \"alias\",\n                      \"relation_name\",\n                      \"resource_type\",\n                      \"name\",\n                      \"description\",\n                      \"compiled_code\",\n                      \"meta\",\n                      \"tags\",\n                      \"config\"\n                    ]\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              }\n            },\n            \"additionalProperties\": false,\n            \"required\": [\n              \"database\",\n              \"schema\",\n              \"name\",\n              \"resource_type\",\n              \"package_name\",\n              \"path\",\n              \"original_file_path\",\n              \"unique_id\",\n              \"fqn\",\n              \"alias\",\n              \"checksum\"\n            ]\n          },\n          {\n            \"type\": \"object\",\n            \"title\": \"Analysis\",\n            \"properties\": {\n              \"database\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ]\n              },\n              \"schema\": {\n                \"type\": \"string\"\n              },\n              \"name\": {\n                \"type\": \"string\"\n              },\n              \"resource_type\": {\n                \"const\": \"analysis\"\n              },\n              \"package_name\": {\n                \"type\": \"string\"\n              },\n              \"path\": {\n                \"type\": \"string\"\n              },\n              \"original_file_path\": {\n                \"type\": \"string\"\n              },\n              \"unique_id\": {\n                \"type\": \"string\"\n              },\n              \"fqn\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"alias\": {\n                \"type\": \"string\"\n              },\n              \"checksum\": {\n                \"type\": \"object\",\n                \"title\": \"FileHash\",\n                \"properties\": {\n                  \"name\": {\n                    \"type\": \"string\"\n                  },\n                  \"checksum\": {\n                    \"type\": \"string\"\n                  }\n                },\n                \"additionalProperties\": false,\n                \"required\": [\n                  \"name\",\n                  \"checksum\"\n                ]\n              },\n              \"config\": {\n                \"type\": \"object\",\n                \"title\": \"NodeConfig\",\n                \"properties\": {\n                  \"_extra\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"enabled\": {\n                    \"type\": \"boolean\",\n                    \"default\": true\n                  },\n                  \"alias\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"schema\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"database\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"tags\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      },\n                      {\n                        \"type\": \"string\"\n                      }\n                    ]\n                  },\n                  \"meta\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"group\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"materialized\": {\n                    \"type\": \"string\",\n                    \"default\": \"view\"\n                  },\n                  \"incremental_strategy\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"batch_size\": {\n                    \"default\": null\n                  },\n                  \"lookback\": {\n                    \"default\": 1\n                  },\n                  \"begin\": {\n                    \"default\": null\n                  },\n                  \"persist_docs\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"post-hook\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"title\": \"Hook\",\n                      \"properties\": {\n                        \"sql\": {\n                          \"type\": \"string\"\n                        },\n                        \"transaction\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"index\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"integer\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": false,\n                      \"required\": [\n                        \"sql\"\n                      ]\n                    }\n                  },\n                  \"pre-hook\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"title\": \"Hook\",\n                      \"properties\": {\n                        \"sql\": {\n                          \"type\": \"string\"\n                        },\n                        \"transaction\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"index\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"integer\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": false,\n                      \"required\": [\n                        \"sql\"\n                      ]\n                    }\n                  },\n                  \"quoting\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"column_types\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"full_refresh\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"boolean\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"unique_key\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"on_schema_change\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": \"ignore\"\n                  },\n                  \"on_configuration_change\": {\n                    \"enum\": [\n                      \"apply\",\n                      \"continue\",\n                      \"fail\"\n                    ]\n                  },\n                  \"grants\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"packages\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"docs\": {\n                    \"type\": \"object\",\n                    \"title\": \"Docs\",\n                    \"properties\": {\n                      \"show\": {\n                        \"type\": \"boolean\",\n                        \"default\": true\n                      },\n                      \"node_color\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"string\"\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ],\n                        \"default\": null\n                      }\n                    },\n                    \"additionalProperties\": false\n                  },\n                  \"contract\": {\n                    \"type\": \"object\",\n                    \"title\": \"ContractConfig\",\n                    \"properties\": {\n                      \"enforced\": {\n                        \"type\": \"boolean\",\n                        \"default\": false\n                      },\n                      \"alias_types\": {\n                        \"type\": \"boolean\",\n                        \"default\": true\n                      }\n                    },\n                    \"additionalProperties\": false\n                  },\n                  \"event_time\": {\n                    \"default\": null\n                  },\n                  \"concurrent_batches\": {\n                    \"default\": null\n                  }\n                },\n                \"additionalProperties\": true\n              },\n              \"tags\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"description\": {\n                \"type\": \"string\",\n                \"default\": \"\"\n              },\n              \"columns\": {\n                \"type\": \"object\",\n                \"additionalProperties\": {\n                  \"type\": \"object\",\n                  \"title\": \"ColumnInfo\",\n                  \"properties\": {\n                    \"name\": {\n                      \"type\": \"string\"\n                    },\n                    \"description\": {\n                      \"type\": \"string\",\n                      \"default\": \"\"\n                    },\n                    \"meta\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"data_type\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"constraints\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"object\",\n                        \"title\": \"ColumnLevelConstraint\",\n                        \"properties\": {\n                          \"type\": {\n                            \"enum\": [\n                              \"check\",\n                              \"not_null\",\n                              \"unique\",\n                              \"primary_key\",\n                              \"foreign_key\",\n                              \"custom\"\n                            ]\n                          },\n                          \"name\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"expression\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"warn_unenforced\": {\n                            \"type\": \"boolean\",\n                            \"default\": true\n                          },\n                          \"warn_unsupported\": {\n                            \"type\": \"boolean\",\n                            \"default\": true\n                          },\n                          \"to\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"to_columns\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"string\"\n                            }\n                          }\n                        },\n                        \"additionalProperties\": false,\n                        \"required\": [\n                          \"type\"\n                        ]\n                      }\n                    },\n                    \"quote\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"boolean\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"config\": {\n                      \"type\": \"object\",\n                      \"title\": \"ColumnConfig\",\n                      \"properties\": {\n                        \"_extra\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"meta\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"tags\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      },\n                      \"additionalProperties\": true\n                    },\n                    \"tags\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"_extra\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"granularity\": {\n                      \"anyOf\": [\n                        {\n                          \"enum\": [\n                            \"nanosecond\",\n                            \"microsecond\",\n                            \"millisecond\",\n                            \"second\",\n                            \"minute\",\n                            \"hour\",\n                            \"day\",\n                            \"week\",\n                            \"month\",\n                            \"quarter\",\n                            \"year\"\n                          ]\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"dimension\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"object\",\n                          \"title\": \"ColumnDimension\",\n                          \"properties\": {\n                            \"name\": {\n                              \"type\": \"string\"\n                            },\n                            \"type\": {\n                              \"enum\": [\n                                \"categorical\",\n                                \"time\"\n                              ]\n                            },\n                            \"description\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"label\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"is_partition\": {\n                              \"type\": \"boolean\",\n                              \"default\": false\n                            },\n                            \"config\": {\n                              \"type\": \"object\",\n                              \"propertyNames\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            \"validity_params\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"object\",\n                                  \"title\": \"ColumnDimensionValidityParams\",\n                                  \"properties\": {\n                                    \"is_start\": {\n                                      \"type\": \"boolean\",\n                                      \"default\": false\n                                    },\n                                    \"is_end\": {\n                                      \"type\": \"boolean\",\n                                      \"default\": false\n                                    }\n                                  },\n                                  \"additionalProperties\": false\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            }\n                          },\n                          \"additionalProperties\": false,\n                          \"required\": [\n                            \"name\",\n                            \"type\"\n                          ]\n                        },\n                        {\n                          \"enum\": [\n                            \"categorical\",\n                            \"time\"\n                          ]\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"entity\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"object\",\n                          \"title\": \"ColumnEntity\",\n                          \"properties\": {\n                            \"name\": {\n                              \"type\": \"string\"\n                            },\n                            \"type\": {\n                              \"enum\": [\n                                \"foreign\",\n                                \"natural\",\n                                \"primary\",\n                                \"unique\"\n                              ]\n                            },\n                            \"description\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"label\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"config\": {\n                              \"type\": \"object\",\n                              \"propertyNames\": {\n                                \"type\": \"string\"\n                              }\n                            }\n                          },\n                          \"additionalProperties\": false,\n                          \"required\": [\n                            \"name\",\n                            \"type\"\n                          ]\n                        },\n                        {\n                          \"enum\": [\n                            \"foreign\",\n                            \"natural\",\n                            \"primary\",\n                            \"unique\"\n                          ]\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"doc_blocks\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    }\n                  },\n                  \"additionalProperties\": true,\n                  \"required\": [\n                    \"name\"\n                  ]\n                },\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"meta\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"group\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"docs\": {\n                \"type\": \"object\",\n                \"title\": \"Docs\",\n                \"properties\": {\n                  \"show\": {\n                    \"type\": \"boolean\",\n                    \"default\": true\n                  },\n                  \"node_color\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  }\n                },\n                \"additionalProperties\": false\n              },\n              \"patch_path\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"build_path\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"unrendered_config\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"created_at\": {\n                \"type\": \"number\"\n              },\n              \"config_call_dict\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"unrendered_config_call_dict\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"relation_name\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"raw_code\": {\n                \"type\": \"string\",\n                \"default\": \"\"\n              },\n              \"doc_blocks\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"language\": {\n                \"type\": \"string\",\n                \"default\": \"sql\"\n              },\n              \"refs\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"object\",\n                  \"title\": \"RefArgs\",\n                  \"properties\": {\n                    \"name\": {\n                      \"type\": \"string\"\n                    },\n                    \"package\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"version\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"number\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    }\n                  },\n                  \"additionalProperties\": false,\n                  \"required\": [\n                    \"name\"\n                  ]\n                }\n              },\n              \"sources\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"string\"\n                  }\n                }\n              },\n              \"metrics\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"string\"\n                  }\n                }\n              },\n              \"functions\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"string\"\n                  }\n                }\n              },\n              \"depends_on\": {\n                \"type\": \"object\",\n                \"title\": \"DependsOn\",\n                \"properties\": {\n                  \"macros\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"nodes\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  }\n                },\n                \"additionalProperties\": false\n              },\n              \"compiled_path\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"compiled\": {\n                \"type\": \"boolean\",\n                \"default\": false\n              },\n              \"compiled_code\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"extra_ctes_injected\": {\n                \"type\": \"boolean\",\n                \"default\": false\n              },\n              \"extra_ctes\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"object\",\n                  \"title\": \"InjectedCTE\",\n                  \"properties\": {\n                    \"id\": {\n                      \"type\": \"string\"\n                    },\n                    \"sql\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"additionalProperties\": false,\n                  \"required\": [\n                    \"id\",\n                    \"sql\"\n                  ]\n                }\n              },\n              \"_pre_injected_sql\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"contract\": {\n                \"type\": \"object\",\n                \"title\": \"Contract\",\n                \"properties\": {\n                  \"enforced\": {\n                    \"type\": \"boolean\",\n                    \"default\": false\n                  },\n                  \"alias_types\": {\n                    \"type\": \"boolean\",\n                    \"default\": true\n                  },\n                  \"checksum\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  }\n                },\n                \"additionalProperties\": false\n              }\n            },\n            \"additionalProperties\": false,\n            \"required\": [\n              \"database\",\n              \"schema\",\n              \"name\",\n              \"resource_type\",\n              \"package_name\",\n              \"path\",\n              \"original_file_path\",\n              \"unique_id\",\n              \"fqn\",\n              \"alias\",\n              \"checksum\"\n            ]\n          },\n          {\n            \"type\": \"object\",\n            \"title\": \"SingularTest\",\n            \"properties\": {\n              \"database\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ]\n              },\n              \"schema\": {\n                \"type\": \"string\"\n              },\n              \"name\": {\n                \"type\": \"string\"\n              },\n              \"resource_type\": {\n                \"const\": \"test\"\n              },\n              \"package_name\": {\n                \"type\": \"string\"\n              },\n              \"path\": {\n                \"type\": \"string\"\n              },\n              \"original_file_path\": {\n                \"type\": \"string\"\n              },\n              \"unique_id\": {\n                \"type\": \"string\"\n              },\n              \"fqn\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"alias\": {\n                \"type\": \"string\"\n              },\n              \"checksum\": {\n                \"type\": \"object\",\n                \"title\": \"FileHash\",\n                \"properties\": {\n                  \"name\": {\n                    \"type\": \"string\"\n                  },\n                  \"checksum\": {\n                    \"type\": \"string\"\n                  }\n                },\n                \"additionalProperties\": false,\n                \"required\": [\n                  \"name\",\n                  \"checksum\"\n                ]\n              },\n              \"config\": {\n                \"type\": \"object\",\n                \"title\": \"TestConfig\",\n                \"properties\": {\n                  \"_extra\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"enabled\": {\n                    \"type\": \"boolean\",\n                    \"default\": true\n                  },\n                  \"alias\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"schema\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": \"dbt_test__audit\"\n                  },\n                  \"database\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"tags\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      },\n                      {\n                        \"type\": \"string\"\n                      }\n                    ]\n                  },\n                  \"meta\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"group\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"materialized\": {\n                    \"type\": \"string\",\n                    \"default\": \"test\"\n                  },\n                  \"severity\": {\n                    \"type\": \"string\",\n                    \"default\": \"ERROR\",\n                    \"pattern\": \"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$\"\n                  },\n                  \"store_failures\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"boolean\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"store_failures_as\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"sql_header\": {\n                    \"default\": null\n                  },\n                  \"where\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"limit\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"integer\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"fail_calc\": {\n                    \"type\": \"string\",\n                    \"default\": \"count(*)\"\n                  },\n                  \"warn_if\": {\n                    \"type\": \"string\",\n                    \"default\": \"!= 0\"\n                  },\n                  \"error_if\": {\n                    \"type\": \"string\",\n                    \"default\": \"!= 0\"\n                  }\n                },\n                \"additionalProperties\": true\n              },\n              \"tags\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"description\": {\n                \"type\": \"string\",\n                \"default\": \"\"\n              },\n              \"columns\": {\n                \"type\": \"object\",\n                \"additionalProperties\": {\n                  \"type\": \"object\",\n                  \"title\": \"ColumnInfo\",\n                  \"properties\": {\n                    \"name\": {\n                      \"type\": \"string\"\n                    },\n                    \"description\": {\n                      \"type\": \"string\",\n                      \"default\": \"\"\n                    },\n                    \"meta\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"data_type\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"constraints\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"object\",\n                        \"title\": \"ColumnLevelConstraint\",\n                        \"properties\": {\n                          \"type\": {\n                            \"enum\": [\n                              \"check\",\n                              \"not_null\",\n                              \"unique\",\n                              \"primary_key\",\n                              \"foreign_key\",\n                              \"custom\"\n                            ]\n                          },\n                          \"name\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"expression\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"warn_unenforced\": {\n                            \"type\": \"boolean\",\n                            \"default\": true\n                          },\n                          \"warn_unsupported\": {\n                            \"type\": \"boolean\",\n                            \"default\": true\n                          },\n                          \"to\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"to_columns\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"string\"\n                            }\n                          }\n                        },\n                        \"additionalProperties\": false,\n                        \"required\": [\n                          \"type\"\n                        ]\n                      }\n                    },\n                    \"quote\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"boolean\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"config\": {\n                      \"type\": \"object\",\n                      \"title\": \"ColumnConfig\",\n                      \"properties\": {\n                        \"_extra\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"meta\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"tags\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      },\n                      \"additionalProperties\": true\n                    },\n                    \"tags\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"_extra\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"granularity\": {\n                      \"anyOf\": [\n                        {\n                          \"enum\": [\n                            \"nanosecond\",\n                            \"microsecond\",\n                            \"millisecond\",\n                            \"second\",\n                            \"minute\",\n                            \"hour\",\n                            \"day\",\n                            \"week\",\n                            \"month\",\n                            \"quarter\",\n                            \"year\"\n                          ]\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"dimension\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"object\",\n                          \"title\": \"ColumnDimension\",\n                          \"properties\": {\n                            \"name\": {\n                              \"type\": \"string\"\n                            },\n                            \"type\": {\n                              \"enum\": [\n                                \"categorical\",\n                                \"time\"\n                              ]\n                            },\n                            \"description\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"label\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"is_partition\": {\n                              \"type\": \"boolean\",\n                              \"default\": false\n                            },\n                            \"config\": {\n                              \"type\": \"object\",\n                              \"propertyNames\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            \"validity_params\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"object\",\n                                  \"title\": \"ColumnDimensionValidityParams\",\n                                  \"properties\": {\n                                    \"is_start\": {\n                                      \"type\": \"boolean\",\n                                      \"default\": false\n                                    },\n                                    \"is_end\": {\n                                      \"type\": \"boolean\",\n                                      \"default\": false\n                                    }\n                                  },\n                                  \"additionalProperties\": false\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            }\n                          },\n                          \"additionalProperties\": false,\n                          \"required\": [\n                            \"name\",\n                            \"type\"\n                          ]\n                        },\n                        {\n                          \"enum\": [\n                            \"categorical\",\n                            \"time\"\n                          ]\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"entity\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"object\",\n                          \"title\": \"ColumnEntity\",\n                          \"properties\": {\n                            \"name\": {\n                              \"type\": \"string\"\n                            },\n                            \"type\": {\n                              \"enum\": [\n                                \"foreign\",\n                                \"natural\",\n                                \"primary\",\n                                \"unique\"\n                              ]\n                            },\n                            \"description\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"label\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"config\": {\n                              \"type\": \"object\",\n                              \"propertyNames\": {\n                                \"type\": \"string\"\n                              }\n                            }\n                          },\n                          \"additionalProperties\": false,\n                          \"required\": [\n                            \"name\",\n                            \"type\"\n                          ]\n                        },\n                        {\n                          \"enum\": [\n                            \"foreign\",\n                            \"natural\",\n                            \"primary\",\n                            \"unique\"\n                          ]\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"doc_blocks\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    }\n                  },\n                  \"additionalProperties\": true,\n                  \"required\": [\n                    \"name\"\n                  ]\n                },\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"meta\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"group\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"docs\": {\n                \"type\": \"object\",\n                \"title\": \"Docs\",\n                \"properties\": {\n                  \"show\": {\n                    \"type\": \"boolean\",\n                    \"default\": true\n                  },\n                  \"node_color\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  }\n                },\n                \"additionalProperties\": false\n              },\n              \"patch_path\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"build_path\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"unrendered_config\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"created_at\": {\n                \"type\": \"number\"\n              },\n              \"config_call_dict\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"unrendered_config_call_dict\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"relation_name\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"raw_code\": {\n                \"type\": \"string\",\n                \"default\": \"\"\n              },\n              \"doc_blocks\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"language\": {\n                \"type\": \"string\",\n                \"default\": \"sql\"\n              },\n              \"refs\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"object\",\n                  \"title\": \"RefArgs\",\n                  \"properties\": {\n                    \"name\": {\n                      \"type\": \"string\"\n                    },\n                    \"package\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"version\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"number\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    }\n                  },\n                  \"additionalProperties\": false,\n                  \"required\": [\n                    \"name\"\n                  ]\n                }\n              },\n              \"sources\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"string\"\n                  }\n                }\n              },\n              \"metrics\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"string\"\n                  }\n                }\n              },\n              \"functions\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"string\"\n                  }\n                }\n              },\n              \"depends_on\": {\n                \"type\": \"object\",\n                \"title\": \"DependsOn\",\n                \"properties\": {\n                  \"macros\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"nodes\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  }\n                },\n                \"additionalProperties\": false\n              },\n              \"compiled_path\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"compiled\": {\n                \"type\": \"boolean\",\n                \"default\": false\n              },\n              \"compiled_code\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"extra_ctes_injected\": {\n                \"type\": \"boolean\",\n                \"default\": false\n              },\n              \"extra_ctes\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"object\",\n                  \"title\": \"InjectedCTE\",\n                  \"properties\": {\n                    \"id\": {\n                      \"type\": \"string\"\n                    },\n                    \"sql\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"additionalProperties\": false,\n                  \"required\": [\n                    \"id\",\n                    \"sql\"\n                  ]\n                }\n              },\n              \"_pre_injected_sql\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"contract\": {\n                \"type\": \"object\",\n                \"title\": \"Contract\",\n                \"properties\": {\n                  \"enforced\": {\n                    \"type\": \"boolean\",\n                    \"default\": false\n                  },\n                  \"alias_types\": {\n                    \"type\": \"boolean\",\n                    \"default\": true\n                  },\n                  \"checksum\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  }\n                },\n                \"additionalProperties\": false\n              }\n            },\n            \"additionalProperties\": false,\n            \"required\": [\n              \"database\",\n              \"schema\",\n              \"name\",\n              \"resource_type\",\n              \"package_name\",\n              \"path\",\n              \"original_file_path\",\n              \"unique_id\",\n              \"fqn\",\n              \"alias\",\n              \"checksum\"\n            ]\n          },\n          {\n            \"type\": \"object\",\n            \"title\": \"HookNode\",\n            \"properties\": {\n              \"database\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ]\n              },\n              \"schema\": {\n                \"type\": \"string\"\n              },\n              \"name\": {\n                \"type\": \"string\"\n              },\n              \"resource_type\": {\n                \"const\": \"operation\"\n              },\n              \"package_name\": {\n                \"type\": \"string\"\n              },\n              \"path\": {\n                \"type\": \"string\"\n              },\n              \"original_file_path\": {\n                \"type\": \"string\"\n              },\n              \"unique_id\": {\n                \"type\": \"string\"\n              },\n              \"fqn\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"alias\": {\n                \"type\": \"string\"\n              },\n              \"checksum\": {\n                \"type\": \"object\",\n                \"title\": \"FileHash\",\n                \"properties\": {\n                  \"name\": {\n                    \"type\": \"string\"\n                  },\n                  \"checksum\": {\n                    \"type\": \"string\"\n                  }\n                },\n                \"additionalProperties\": false,\n                \"required\": [\n                  \"name\",\n                  \"checksum\"\n                ]\n              },\n              \"config\": {\n                \"type\": \"object\",\n                \"title\": \"NodeConfig\",\n                \"properties\": {\n                  \"_extra\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"enabled\": {\n                    \"type\": \"boolean\",\n                    \"default\": true\n                  },\n                  \"alias\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"schema\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"database\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"tags\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      },\n                      {\n                        \"type\": \"string\"\n                      }\n                    ]\n                  },\n                  \"meta\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"group\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"materialized\": {\n                    \"type\": \"string\",\n                    \"default\": \"view\"\n                  },\n                  \"incremental_strategy\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"batch_size\": {\n                    \"default\": null\n                  },\n                  \"lookback\": {\n                    \"default\": 1\n                  },\n                  \"begin\": {\n                    \"default\": null\n                  },\n                  \"persist_docs\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"post-hook\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"title\": \"Hook\",\n                      \"properties\": {\n                        \"sql\": {\n                          \"type\": \"string\"\n                        },\n                        \"transaction\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"index\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"integer\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": false,\n                      \"required\": [\n                        \"sql\"\n                      ]\n                    }\n                  },\n                  \"pre-hook\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"title\": \"Hook\",\n                      \"properties\": {\n                        \"sql\": {\n                          \"type\": \"string\"\n                        },\n                        \"transaction\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"index\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"integer\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": false,\n                      \"required\": [\n                        \"sql\"\n                      ]\n                    }\n                  },\n                  \"quoting\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"column_types\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"full_refresh\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"boolean\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"unique_key\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"on_schema_change\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": \"ignore\"\n                  },\n                  \"on_configuration_change\": {\n                    \"enum\": [\n                      \"apply\",\n                      \"continue\",\n                      \"fail\"\n                    ]\n                  },\n                  \"grants\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"packages\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"docs\": {\n                    \"type\": \"object\",\n                    \"title\": \"Docs\",\n                    \"properties\": {\n                      \"show\": {\n                        \"type\": \"boolean\",\n                        \"default\": true\n                      },\n                      \"node_color\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"string\"\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ],\n                        \"default\": null\n                      }\n                    },\n                    \"additionalProperties\": false\n                  },\n                  \"contract\": {\n                    \"type\": \"object\",\n                    \"title\": \"ContractConfig\",\n                    \"properties\": {\n                      \"enforced\": {\n                        \"type\": \"boolean\",\n                        \"default\": false\n                      },\n                      \"alias_types\": {\n                        \"type\": \"boolean\",\n                        \"default\": true\n                      }\n                    },\n                    \"additionalProperties\": false\n                  },\n                  \"event_time\": {\n                    \"default\": null\n                  },\n                  \"concurrent_batches\": {\n                    \"default\": null\n                  }\n                },\n                \"additionalProperties\": true\n              },\n              \"tags\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"description\": {\n                \"type\": \"string\",\n                \"default\": \"\"\n              },\n              \"columns\": {\n                \"type\": \"object\",\n                \"additionalProperties\": {\n                  \"type\": \"object\",\n                  \"title\": \"ColumnInfo\",\n                  \"properties\": {\n                    \"name\": {\n                      \"type\": \"string\"\n                    },\n                    \"description\": {\n                      \"type\": \"string\",\n                      \"default\": \"\"\n                    },\n                    \"meta\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"data_type\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"constraints\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"object\",\n                        \"title\": \"ColumnLevelConstraint\",\n                        \"properties\": {\n                          \"type\": {\n                            \"enum\": [\n                              \"check\",\n                              \"not_null\",\n                              \"unique\",\n                              \"primary_key\",\n                              \"foreign_key\",\n                              \"custom\"\n                            ]\n                          },\n                          \"name\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"expression\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"warn_unenforced\": {\n                            \"type\": \"boolean\",\n                            \"default\": true\n                          },\n                          \"warn_unsupported\": {\n                            \"type\": \"boolean\",\n                            \"default\": true\n                          },\n                          \"to\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"to_columns\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"string\"\n                            }\n                          }\n                        },\n                        \"additionalProperties\": false,\n                        \"required\": [\n                          \"type\"\n                        ]\n                      }\n                    },\n                    \"quote\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"boolean\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"config\": {\n                      \"type\": \"object\",\n                      \"title\": \"ColumnConfig\",\n                      \"properties\": {\n                        \"_extra\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"meta\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"tags\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      },\n                      \"additionalProperties\": true\n                    },\n                    \"tags\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"_extra\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"granularity\": {\n                      \"anyOf\": [\n                        {\n                          \"enum\": [\n                            \"nanosecond\",\n                            \"microsecond\",\n                            \"millisecond\",\n                            \"second\",\n                            \"minute\",\n                            \"hour\",\n                            \"day\",\n                            \"week\",\n                            \"month\",\n                            \"quarter\",\n                            \"year\"\n                          ]\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"dimension\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"object\",\n                          \"title\": \"ColumnDimension\",\n                          \"properties\": {\n                            \"name\": {\n                              \"type\": \"string\"\n                            },\n                            \"type\": {\n                              \"enum\": [\n                                \"categorical\",\n                                \"time\"\n                              ]\n                            },\n                            \"description\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"label\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"is_partition\": {\n                              \"type\": \"boolean\",\n                              \"default\": false\n                            },\n                            \"config\": {\n                              \"type\": \"object\",\n                              \"propertyNames\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            \"validity_params\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"object\",\n                                  \"title\": \"ColumnDimensionValidityParams\",\n                                  \"properties\": {\n                                    \"is_start\": {\n                                      \"type\": \"boolean\",\n                                      \"default\": false\n                                    },\n                                    \"is_end\": {\n                                      \"type\": \"boolean\",\n                                      \"default\": false\n                                    }\n                                  },\n                                  \"additionalProperties\": false\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            }\n                          },\n                          \"additionalProperties\": false,\n                          \"required\": [\n                            \"name\",\n                            \"type\"\n                          ]\n                        },\n                        {\n                          \"enum\": [\n                            \"categorical\",\n                            \"time\"\n                          ]\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"entity\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"object\",\n                          \"title\": \"ColumnEntity\",\n                          \"properties\": {\n                            \"name\": {\n                              \"type\": \"string\"\n                            },\n                            \"type\": {\n                              \"enum\": [\n                                \"foreign\",\n                                \"natural\",\n                                \"primary\",\n                                \"unique\"\n                              ]\n                            },\n                            \"description\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"label\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"config\": {\n                              \"type\": \"object\",\n                              \"propertyNames\": {\n                                \"type\": \"string\"\n                              }\n                            }\n                          },\n                          \"additionalProperties\": false,\n                          \"required\": [\n                            \"name\",\n                            \"type\"\n                          ]\n                        },\n                        {\n                          \"enum\": [\n                            \"foreign\",\n                            \"natural\",\n                            \"primary\",\n                            \"unique\"\n                          ]\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"doc_blocks\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    }\n                  },\n                  \"additionalProperties\": true,\n                  \"required\": [\n                    \"name\"\n                  ]\n                },\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"meta\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"group\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"docs\": {\n                \"type\": \"object\",\n                \"title\": \"Docs\",\n                \"properties\": {\n                  \"show\": {\n                    \"type\": \"boolean\",\n                    \"default\": true\n                  },\n                  \"node_color\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  }\n                },\n                \"additionalProperties\": false\n              },\n              \"patch_path\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"build_path\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"unrendered_config\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"created_at\": {\n                \"type\": \"number\"\n              },\n              \"config_call_dict\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"unrendered_config_call_dict\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"relation_name\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"raw_code\": {\n                \"type\": \"string\",\n                \"default\": \"\"\n              },\n              \"doc_blocks\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"language\": {\n                \"type\": \"string\",\n                \"default\": \"sql\"\n              },\n              \"refs\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"object\",\n                  \"title\": \"RefArgs\",\n                  \"properties\": {\n                    \"name\": {\n                      \"type\": \"string\"\n                    },\n                    \"package\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"version\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"number\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    }\n                  },\n                  \"additionalProperties\": false,\n                  \"required\": [\n                    \"name\"\n                  ]\n                }\n              },\n              \"sources\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"string\"\n                  }\n                }\n              },\n              \"metrics\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"string\"\n                  }\n                }\n              },\n              \"functions\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"string\"\n                  }\n                }\n              },\n              \"depends_on\": {\n                \"type\": \"object\",\n                \"title\": \"DependsOn\",\n                \"properties\": {\n                  \"macros\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"nodes\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  }\n                },\n                \"additionalProperties\": false\n              },\n              \"compiled_path\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"compiled\": {\n                \"type\": \"boolean\",\n                \"default\": false\n              },\n              \"compiled_code\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"extra_ctes_injected\": {\n                \"type\": \"boolean\",\n                \"default\": false\n              },\n              \"extra_ctes\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"object\",\n                  \"title\": \"InjectedCTE\",\n                  \"properties\": {\n                    \"id\": {\n                      \"type\": \"string\"\n                    },\n                    \"sql\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"additionalProperties\": false,\n                  \"required\": [\n                    \"id\",\n                    \"sql\"\n                  ]\n                }\n              },\n              \"_pre_injected_sql\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"contract\": {\n                \"type\": \"object\",\n                \"title\": \"Contract\",\n                \"properties\": {\n                  \"enforced\": {\n                    \"type\": \"boolean\",\n                    \"default\": false\n                  },\n                  \"alias_types\": {\n                    \"type\": \"boolean\",\n                    \"default\": true\n                  },\n                  \"checksum\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  }\n                },\n                \"additionalProperties\": false\n              },\n              \"index\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"integer\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              }\n            },\n            \"additionalProperties\": false,\n            \"required\": [\n              \"database\",\n              \"schema\",\n              \"name\",\n              \"resource_type\",\n              \"package_name\",\n              \"path\",\n              \"original_file_path\",\n              \"unique_id\",\n              \"fqn\",\n              \"alias\",\n              \"checksum\"\n            ]\n          },\n          {\n            \"type\": \"object\",\n            \"title\": \"Model\",\n            \"properties\": {\n              \"database\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ]\n              },\n              \"schema\": {\n                \"type\": \"string\"\n              },\n              \"name\": {\n                \"type\": \"string\"\n              },\n              \"resource_type\": {\n                \"const\": \"model\"\n              },\n              \"package_name\": {\n                \"type\": \"string\"\n              },\n              \"path\": {\n                \"type\": \"string\"\n              },\n              \"original_file_path\": {\n                \"type\": \"string\"\n              },\n              \"unique_id\": {\n                \"type\": \"string\"\n              },\n              \"fqn\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"alias\": {\n                \"type\": \"string\"\n              },\n              \"checksum\": {\n                \"type\": \"object\",\n                \"title\": \"FileHash\",\n                \"properties\": {\n                  \"name\": {\n                    \"type\": \"string\"\n                  },\n                  \"checksum\": {\n                    \"type\": \"string\"\n                  }\n                },\n                \"additionalProperties\": false,\n                \"required\": [\n                  \"name\",\n                  \"checksum\"\n                ]\n              },\n              \"config\": {\n                \"type\": \"object\",\n                \"title\": \"ModelConfig\",\n                \"properties\": {\n                  \"_extra\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"enabled\": {\n                    \"type\": \"boolean\",\n                    \"default\": true\n                  },\n                  \"alias\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"schema\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"database\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"tags\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      },\n                      {\n                        \"type\": \"string\"\n                      }\n                    ]\n                  },\n                  \"meta\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"group\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"materialized\": {\n                    \"type\": \"string\",\n                    \"default\": \"view\"\n                  },\n                  \"incremental_strategy\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"batch_size\": {\n                    \"default\": null\n                  },\n                  \"lookback\": {\n                    \"default\": 1\n                  },\n                  \"begin\": {\n                    \"default\": null\n                  },\n                  \"persist_docs\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"post-hook\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"title\": \"Hook\",\n                      \"properties\": {\n                        \"sql\": {\n                          \"type\": \"string\"\n                        },\n                        \"transaction\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"index\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"integer\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": false,\n                      \"required\": [\n                        \"sql\"\n                      ]\n                    }\n                  },\n                  \"pre-hook\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"title\": \"Hook\",\n                      \"properties\": {\n                        \"sql\": {\n                          \"type\": \"string\"\n                        },\n                        \"transaction\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"index\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"integer\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": false,\n                      \"required\": [\n                        \"sql\"\n                      ]\n                    }\n                  },\n                  \"quoting\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"column_types\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"full_refresh\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"boolean\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"unique_key\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"on_schema_change\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": \"ignore\"\n                  },\n                  \"on_configuration_change\": {\n                    \"enum\": [\n                      \"apply\",\n                      \"continue\",\n                      \"fail\"\n                    ]\n                  },\n                  \"grants\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"packages\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"docs\": {\n                    \"type\": \"object\",\n                    \"title\": \"Docs\",\n                    \"properties\": {\n                      \"show\": {\n                        \"type\": \"boolean\",\n                        \"default\": true\n                      },\n                      \"node_color\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"string\"\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ],\n                        \"default\": null\n                      }\n                    },\n                    \"additionalProperties\": false\n                  },\n                  \"contract\": {\n                    \"type\": \"object\",\n                    \"title\": \"ContractConfig\",\n                    \"properties\": {\n                      \"enforced\": {\n                        \"type\": \"boolean\",\n                        \"default\": false\n                      },\n                      \"alias_types\": {\n                        \"type\": \"boolean\",\n                        \"default\": true\n                      }\n                    },\n                    \"additionalProperties\": false\n                  },\n                  \"event_time\": {\n                    \"default\": null\n                  },\n                  \"concurrent_batches\": {\n                    \"default\": null\n                  },\n                  \"access\": {\n                    \"enum\": [\n                      \"private\",\n                      \"protected\",\n                      \"public\"\n                    ],\n                    \"default\": \"protected\"\n                  },\n                  \"freshness\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"object\",\n                        \"title\": \"ModelFreshness\",\n                        \"properties\": {\n                          \"build_after\": {\n                            \"type\": \"object\",\n                            \"title\": \"ModelBuildAfter\",\n                            \"properties\": {\n                              \"count\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"integer\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"period\": {\n                                \"anyOf\": [\n                                  {\n                                    \"enum\": [\n                                      \"minute\",\n                                      \"hour\",\n                                      \"day\"\n                                    ]\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"updates_on\": {\n                                \"enum\": [\n                                  \"all\",\n                                  \"any\"\n                                ],\n                                \"default\": \"any\"\n                              }\n                            },\n                            \"additionalProperties\": true\n                          }\n                        },\n                        \"additionalProperties\": true,\n                        \"required\": [\n                          \"build_after\"\n                        ]\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  }\n                },\n                \"additionalProperties\": true\n              },\n              \"tags\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"description\": {\n                \"type\": \"string\",\n                \"default\": \"\"\n              },\n              \"columns\": {\n                \"type\": \"object\",\n                \"additionalProperties\": {\n                  \"type\": \"object\",\n                  \"title\": \"ColumnInfo\",\n                  \"properties\": {\n                    \"name\": {\n                      \"type\": \"string\"\n                    },\n                    \"description\": {\n                      \"type\": \"string\",\n                      \"default\": \"\"\n                    },\n                    \"meta\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"data_type\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"constraints\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"object\",\n                        \"title\": \"ColumnLevelConstraint\",\n                        \"properties\": {\n                          \"type\": {\n                            \"enum\": [\n                              \"check\",\n                              \"not_null\",\n                              \"unique\",\n                              \"primary_key\",\n                              \"foreign_key\",\n                              \"custom\"\n                            ]\n                          },\n                          \"name\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"expression\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"warn_unenforced\": {\n                            \"type\": \"boolean\",\n                            \"default\": true\n                          },\n                          \"warn_unsupported\": {\n                            \"type\": \"boolean\",\n                            \"default\": true\n                          },\n                          \"to\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"to_columns\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"string\"\n                            }\n                          }\n                        },\n                        \"additionalProperties\": false,\n                        \"required\": [\n                          \"type\"\n                        ]\n                      }\n                    },\n                    \"quote\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"boolean\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"config\": {\n                      \"type\": \"object\",\n                      \"title\": \"ColumnConfig\",\n                      \"properties\": {\n                        \"_extra\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"meta\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"tags\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      },\n                      \"additionalProperties\": true\n                    },\n                    \"tags\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"_extra\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"granularity\": {\n                      \"anyOf\": [\n                        {\n                          \"enum\": [\n                            \"nanosecond\",\n                            \"microsecond\",\n                            \"millisecond\",\n                            \"second\",\n                            \"minute\",\n                            \"hour\",\n                            \"day\",\n                            \"week\",\n                            \"month\",\n                            \"quarter\",\n                            \"year\"\n                          ]\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"dimension\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"object\",\n                          \"title\": \"ColumnDimension\",\n                          \"properties\": {\n                            \"name\": {\n                              \"type\": \"string\"\n                            },\n                            \"type\": {\n                              \"enum\": [\n                                \"categorical\",\n                                \"time\"\n                              ]\n                            },\n                            \"description\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"label\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"is_partition\": {\n                              \"type\": \"boolean\",\n                              \"default\": false\n                            },\n                            \"config\": {\n                              \"type\": \"object\",\n                              \"propertyNames\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            \"validity_params\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"object\",\n                                  \"title\": \"ColumnDimensionValidityParams\",\n                                  \"properties\": {\n                                    \"is_start\": {\n                                      \"type\": \"boolean\",\n                                      \"default\": false\n                                    },\n                                    \"is_end\": {\n                                      \"type\": \"boolean\",\n                                      \"default\": false\n                                    }\n                                  },\n                                  \"additionalProperties\": false\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            }\n                          },\n                          \"additionalProperties\": false,\n                          \"required\": [\n                            \"name\",\n                            \"type\"\n                          ]\n                        },\n                        {\n                          \"enum\": [\n                            \"categorical\",\n                            \"time\"\n                          ]\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"entity\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"object\",\n                          \"title\": \"ColumnEntity\",\n                          \"properties\": {\n                            \"name\": {\n                              \"type\": \"string\"\n                            },\n                            \"type\": {\n                              \"enum\": [\n                                \"foreign\",\n                                \"natural\",\n                                \"primary\",\n                                \"unique\"\n                              ]\n                            },\n                            \"description\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"label\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"config\": {\n                              \"type\": \"object\",\n                              \"propertyNames\": {\n                                \"type\": \"string\"\n                              }\n                            }\n                          },\n                          \"additionalProperties\": false,\n                          \"required\": [\n                            \"name\",\n                            \"type\"\n                          ]\n                        },\n                        {\n                          \"enum\": [\n                            \"foreign\",\n                            \"natural\",\n                            \"primary\",\n                            \"unique\"\n                          ]\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"doc_blocks\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    }\n                  },\n                  \"additionalProperties\": true,\n                  \"required\": [\n                    \"name\"\n                  ]\n                },\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"meta\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"group\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"docs\": {\n                \"type\": \"object\",\n                \"title\": \"Docs\",\n                \"properties\": {\n                  \"show\": {\n                    \"type\": \"boolean\",\n                    \"default\": true\n                  },\n                  \"node_color\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  }\n                },\n                \"additionalProperties\": false\n              },\n              \"patch_path\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"build_path\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"unrendered_config\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"created_at\": {\n                \"type\": \"number\"\n              },\n              \"config_call_dict\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"unrendered_config_call_dict\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"relation_name\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"raw_code\": {\n                \"type\": \"string\",\n                \"default\": \"\"\n              },\n              \"doc_blocks\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"language\": {\n                \"type\": \"string\",\n                \"default\": \"sql\"\n              },\n              \"refs\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"object\",\n                  \"title\": \"RefArgs\",\n                  \"properties\": {\n                    \"name\": {\n                      \"type\": \"string\"\n                    },\n                    \"package\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"version\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"number\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    }\n                  },\n                  \"additionalProperties\": false,\n                  \"required\": [\n                    \"name\"\n                  ]\n                }\n              },\n              \"sources\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"string\"\n                  }\n                }\n              },\n              \"metrics\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"string\"\n                  }\n                }\n              },\n              \"functions\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"string\"\n                  }\n                }\n              },\n              \"depends_on\": {\n                \"type\": \"object\",\n                \"title\": \"DependsOn\",\n                \"properties\": {\n                  \"macros\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"nodes\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  }\n                },\n                \"additionalProperties\": false\n              },\n              \"compiled_path\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"compiled\": {\n                \"type\": \"boolean\",\n                \"default\": false\n              },\n              \"compiled_code\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"extra_ctes_injected\": {\n                \"type\": \"boolean\",\n                \"default\": false\n              },\n              \"extra_ctes\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"object\",\n                  \"title\": \"InjectedCTE\",\n                  \"properties\": {\n                    \"id\": {\n                      \"type\": \"string\"\n                    },\n                    \"sql\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"additionalProperties\": false,\n                  \"required\": [\n                    \"id\",\n                    \"sql\"\n                  ]\n                }\n              },\n              \"_pre_injected_sql\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"contract\": {\n                \"type\": \"object\",\n                \"title\": \"Contract\",\n                \"properties\": {\n                  \"enforced\": {\n                    \"type\": \"boolean\",\n                    \"default\": false\n                  },\n                  \"alias_types\": {\n                    \"type\": \"boolean\",\n                    \"default\": true\n                  },\n                  \"checksum\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  }\n                },\n                \"additionalProperties\": false\n              },\n              \"access\": {\n                \"enum\": [\n                  \"private\",\n                  \"protected\",\n                  \"public\"\n                ],\n                \"default\": \"protected\"\n              },\n              \"constraints\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"object\",\n                  \"title\": \"ModelLevelConstraint\",\n                  \"properties\": {\n                    \"type\": {\n                      \"enum\": [\n                        \"check\",\n                        \"not_null\",\n                        \"unique\",\n                        \"primary_key\",\n                        \"foreign_key\",\n                        \"custom\"\n                      ]\n                    },\n                    \"name\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"expression\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"warn_unenforced\": {\n                      \"type\": \"boolean\",\n                      \"default\": true\n                    },\n                    \"warn_unsupported\": {\n                      \"type\": \"boolean\",\n                      \"default\": true\n                    },\n                    \"to\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"to_columns\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"columns\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    }\n                  },\n                  \"additionalProperties\": false,\n                  \"required\": [\n                    \"type\"\n                  ]\n                }\n              },\n              \"version\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"number\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"latest_version\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"number\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"deprecation_date\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"defer_relation\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"object\",\n                    \"title\": \"DeferRelation\",\n                    \"properties\": {\n                      \"database\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"string\"\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ]\n                      },\n                      \"schema\": {\n                        \"type\": \"string\"\n                      },\n                      \"alias\": {\n                        \"type\": \"string\"\n                      },\n                      \"relation_name\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"string\"\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ]\n                      },\n                      \"resource_type\": {\n                        \"enum\": [\n                          \"model\",\n                          \"analysis\",\n                          \"test\",\n                          \"snapshot\",\n                          \"operation\",\n                          \"seed\",\n                          \"rpc\",\n                          \"sql_operation\",\n                          \"doc\",\n                          \"source\",\n                          \"macro\",\n                          \"exposure\",\n                          \"metric\",\n                          \"group\",\n                          \"saved_query\",\n                          \"semantic_model\",\n                          \"unit_test\",\n                          \"fixture\",\n                          \"function\"\n                        ]\n                      },\n                      \"name\": {\n                        \"type\": \"string\"\n                      },\n                      \"description\": {\n                        \"type\": \"string\"\n                      },\n                      \"compiled_code\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"string\"\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ]\n                      },\n                      \"meta\": {\n                        \"type\": \"object\",\n                        \"propertyNames\": {\n                          \"type\": \"string\"\n                        }\n                      },\n                      \"tags\": {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      },\n                      \"config\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"object\",\n                            \"title\": \"NodeConfig\",\n                            \"properties\": {\n                              \"_extra\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"enabled\": {\n                                \"type\": \"boolean\",\n                                \"default\": true\n                              },\n                              \"alias\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"string\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"schema\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"string\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"database\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"string\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"tags\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"array\",\n                                    \"items\": {\n                                      \"type\": \"string\"\n                                    }\n                                  },\n                                  {\n                                    \"type\": \"string\"\n                                  }\n                                ]\n                              },\n                              \"meta\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"group\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"string\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"materialized\": {\n                                \"type\": \"string\",\n                                \"default\": \"view\"\n                              },\n                              \"incremental_strategy\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"string\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"batch_size\": {\n                                \"default\": null\n                              },\n                              \"lookback\": {\n                                \"default\": 1\n                              },\n                              \"begin\": {\n                                \"default\": null\n                              },\n                              \"persist_docs\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"post-hook\": {\n                                \"type\": \"array\",\n                                \"items\": {\n                                  \"type\": \"object\",\n                                  \"title\": \"Hook\",\n                                  \"properties\": {\n                                    \"sql\": {\n                                      \"type\": \"string\"\n                                    },\n                                    \"transaction\": {\n                                      \"type\": \"boolean\",\n                                      \"default\": true\n                                    },\n                                    \"index\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"integer\"\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    }\n                                  },\n                                  \"additionalProperties\": false,\n                                  \"required\": [\n                                    \"sql\"\n                                  ]\n                                }\n                              },\n                              \"pre-hook\": {\n                                \"type\": \"array\",\n                                \"items\": {\n                                  \"type\": \"object\",\n                                  \"title\": \"Hook\",\n                                  \"properties\": {\n                                    \"sql\": {\n                                      \"type\": \"string\"\n                                    },\n                                    \"transaction\": {\n                                      \"type\": \"boolean\",\n                                      \"default\": true\n                                    },\n                                    \"index\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"integer\"\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    }\n                                  },\n                                  \"additionalProperties\": false,\n                                  \"required\": [\n                                    \"sql\"\n                                  ]\n                                }\n                              },\n                              \"quoting\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"column_types\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"full_refresh\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"boolean\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"unique_key\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"string\"\n                                  },\n                                  {\n                                    \"type\": \"array\",\n                                    \"items\": {\n                                      \"type\": \"string\"\n                                    }\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"on_schema_change\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"string\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": \"ignore\"\n                              },\n                              \"on_configuration_change\": {\n                                \"enum\": [\n                                  \"apply\",\n                                  \"continue\",\n                                  \"fail\"\n                                ]\n                              },\n                              \"grants\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"packages\": {\n                                \"type\": \"array\",\n                                \"items\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"docs\": {\n                                \"type\": \"object\",\n                                \"title\": \"Docs\",\n                                \"properties\": {\n                                  \"show\": {\n                                    \"type\": \"boolean\",\n                                    \"default\": true\n                                  },\n                                  \"node_color\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  }\n                                },\n                                \"additionalProperties\": false\n                              },\n                              \"contract\": {\n                                \"type\": \"object\",\n                                \"title\": \"ContractConfig\",\n                                \"properties\": {\n                                  \"enforced\": {\n                                    \"type\": \"boolean\",\n                                    \"default\": false\n                                  },\n                                  \"alias_types\": {\n                                    \"type\": \"boolean\",\n                                    \"default\": true\n                                  }\n                                },\n                                \"additionalProperties\": false\n                              },\n                              \"event_time\": {\n                                \"default\": null\n                              },\n                              \"concurrent_batches\": {\n                                \"default\": null\n                              }\n                            },\n                            \"additionalProperties\": true\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ]\n                      }\n                    },\n                    \"additionalProperties\": false,\n                    \"required\": [\n                      \"database\",\n                      \"schema\",\n                      \"alias\",\n                      \"relation_name\",\n                      \"resource_type\",\n                      \"name\",\n                      \"description\",\n                      \"compiled_code\",\n                      \"meta\",\n                      \"tags\",\n                      \"config\"\n                    ]\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"primary_key\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"time_spine\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"object\",\n                    \"title\": \"TimeSpine\",\n                    \"properties\": {\n                      \"standard_granularity_column\": {\n                        \"type\": \"string\"\n                      },\n                      \"custom_granularities\": {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"object\",\n                          \"title\": \"CustomGranularity\",\n                          \"properties\": {\n                            \"name\": {\n                              \"type\": \"string\"\n                            },\n                            \"column_name\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            }\n                          },\n                          \"additionalProperties\": false,\n                          \"required\": [\n                            \"name\"\n                          ]\n                        }\n                      }\n                    },\n                    \"additionalProperties\": false,\n                    \"required\": [\n                      \"standard_granularity_column\"\n                    ]\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              }\n            },\n            \"additionalProperties\": false,\n            \"required\": [\n              \"database\",\n              \"schema\",\n              \"name\",\n              \"resource_type\",\n              \"package_name\",\n              \"path\",\n              \"original_file_path\",\n              \"unique_id\",\n              \"fqn\",\n              \"alias\",\n              \"checksum\"\n            ]\n          },\n          {\n            \"type\": \"object\",\n            \"title\": \"SqlOperation\",\n            \"properties\": {\n              \"database\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ]\n              },\n              \"schema\": {\n                \"type\": \"string\"\n              },\n              \"name\": {\n                \"type\": \"string\"\n              },\n              \"resource_type\": {\n                \"const\": \"sql_operation\"\n              },\n              \"package_name\": {\n                \"type\": \"string\"\n              },\n              \"path\": {\n                \"type\": \"string\"\n              },\n              \"original_file_path\": {\n                \"type\": \"string\"\n              },\n              \"unique_id\": {\n                \"type\": \"string\"\n              },\n              \"fqn\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"alias\": {\n                \"type\": \"string\"\n              },\n              \"checksum\": {\n                \"type\": \"object\",\n                \"title\": \"FileHash\",\n                \"properties\": {\n                  \"name\": {\n                    \"type\": \"string\"\n                  },\n                  \"checksum\": {\n                    \"type\": \"string\"\n                  }\n                },\n                \"additionalProperties\": false,\n                \"required\": [\n                  \"name\",\n                  \"checksum\"\n                ]\n              },\n              \"config\": {\n                \"type\": \"object\",\n                \"title\": \"NodeConfig\",\n                \"properties\": {\n                  \"_extra\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"enabled\": {\n                    \"type\": \"boolean\",\n                    \"default\": true\n                  },\n                  \"alias\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"schema\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"database\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"tags\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      },\n                      {\n                        \"type\": \"string\"\n                      }\n                    ]\n                  },\n                  \"meta\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"group\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"materialized\": {\n                    \"type\": \"string\",\n                    \"default\": \"view\"\n                  },\n                  \"incremental_strategy\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"batch_size\": {\n                    \"default\": null\n                  },\n                  \"lookback\": {\n                    \"default\": 1\n                  },\n                  \"begin\": {\n                    \"default\": null\n                  },\n                  \"persist_docs\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"post-hook\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"title\": \"Hook\",\n                      \"properties\": {\n                        \"sql\": {\n                          \"type\": \"string\"\n                        },\n                        \"transaction\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"index\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"integer\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": false,\n                      \"required\": [\n                        \"sql\"\n                      ]\n                    }\n                  },\n                  \"pre-hook\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"title\": \"Hook\",\n                      \"properties\": {\n                        \"sql\": {\n                          \"type\": \"string\"\n                        },\n                        \"transaction\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"index\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"integer\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": false,\n                      \"required\": [\n                        \"sql\"\n                      ]\n                    }\n                  },\n                  \"quoting\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"column_types\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"full_refresh\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"boolean\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"unique_key\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"on_schema_change\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": \"ignore\"\n                  },\n                  \"on_configuration_change\": {\n                    \"enum\": [\n                      \"apply\",\n                      \"continue\",\n                      \"fail\"\n                    ]\n                  },\n                  \"grants\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"packages\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"docs\": {\n                    \"type\": \"object\",\n                    \"title\": \"Docs\",\n                    \"properties\": {\n                      \"show\": {\n                        \"type\": \"boolean\",\n                        \"default\": true\n                      },\n                      \"node_color\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"string\"\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ],\n                        \"default\": null\n                      }\n                    },\n                    \"additionalProperties\": false\n                  },\n                  \"contract\": {\n                    \"type\": \"object\",\n                    \"title\": \"ContractConfig\",\n                    \"properties\": {\n                      \"enforced\": {\n                        \"type\": \"boolean\",\n                        \"default\": false\n                      },\n                      \"alias_types\": {\n                        \"type\": \"boolean\",\n                        \"default\": true\n                      }\n                    },\n                    \"additionalProperties\": false\n                  },\n                  \"event_time\": {\n                    \"default\": null\n                  },\n                  \"concurrent_batches\": {\n                    \"default\": null\n                  }\n                },\n                \"additionalProperties\": true\n              },\n              \"tags\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"description\": {\n                \"type\": \"string\",\n                \"default\": \"\"\n              },\n              \"columns\": {\n                \"type\": \"object\",\n                \"additionalProperties\": {\n                  \"type\": \"object\",\n                  \"title\": \"ColumnInfo\",\n                  \"properties\": {\n                    \"name\": {\n                      \"type\": \"string\"\n                    },\n                    \"description\": {\n                      \"type\": \"string\",\n                      \"default\": \"\"\n                    },\n                    \"meta\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"data_type\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"constraints\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"object\",\n                        \"title\": \"ColumnLevelConstraint\",\n                        \"properties\": {\n                          \"type\": {\n                            \"enum\": [\n                              \"check\",\n                              \"not_null\",\n                              \"unique\",\n                              \"primary_key\",\n                              \"foreign_key\",\n                              \"custom\"\n                            ]\n                          },\n                          \"name\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"expression\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"warn_unenforced\": {\n                            \"type\": \"boolean\",\n                            \"default\": true\n                          },\n                          \"warn_unsupported\": {\n                            \"type\": \"boolean\",\n                            \"default\": true\n                          },\n                          \"to\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"to_columns\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"string\"\n                            }\n                          }\n                        },\n                        \"additionalProperties\": false,\n                        \"required\": [\n                          \"type\"\n                        ]\n                      }\n                    },\n                    \"quote\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"boolean\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"config\": {\n                      \"type\": \"object\",\n                      \"title\": \"ColumnConfig\",\n                      \"properties\": {\n                        \"_extra\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"meta\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"tags\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      },\n                      \"additionalProperties\": true\n                    },\n                    \"tags\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"_extra\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"granularity\": {\n                      \"anyOf\": [\n                        {\n                          \"enum\": [\n                            \"nanosecond\",\n                            \"microsecond\",\n                            \"millisecond\",\n                            \"second\",\n                            \"minute\",\n                            \"hour\",\n                            \"day\",\n                            \"week\",\n                            \"month\",\n                            \"quarter\",\n                            \"year\"\n                          ]\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"dimension\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"object\",\n                          \"title\": \"ColumnDimension\",\n                          \"properties\": {\n                            \"name\": {\n                              \"type\": \"string\"\n                            },\n                            \"type\": {\n                              \"enum\": [\n                                \"categorical\",\n                                \"time\"\n                              ]\n                            },\n                            \"description\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"label\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"is_partition\": {\n                              \"type\": \"boolean\",\n                              \"default\": false\n                            },\n                            \"config\": {\n                              \"type\": \"object\",\n                              \"propertyNames\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            \"validity_params\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"object\",\n                                  \"title\": \"ColumnDimensionValidityParams\",\n                                  \"properties\": {\n                                    \"is_start\": {\n                                      \"type\": \"boolean\",\n                                      \"default\": false\n                                    },\n                                    \"is_end\": {\n                                      \"type\": \"boolean\",\n                                      \"default\": false\n                                    }\n                                  },\n                                  \"additionalProperties\": false\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            }\n                          },\n                          \"additionalProperties\": false,\n                          \"required\": [\n                            \"name\",\n                            \"type\"\n                          ]\n                        },\n                        {\n                          \"enum\": [\n                            \"categorical\",\n                            \"time\"\n                          ]\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"entity\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"object\",\n                          \"title\": \"ColumnEntity\",\n                          \"properties\": {\n                            \"name\": {\n                              \"type\": \"string\"\n                            },\n                            \"type\": {\n                              \"enum\": [\n                                \"foreign\",\n                                \"natural\",\n                                \"primary\",\n                                \"unique\"\n                              ]\n                            },\n                            \"description\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"label\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"config\": {\n                              \"type\": \"object\",\n                              \"propertyNames\": {\n                                \"type\": \"string\"\n                              }\n                            }\n                          },\n                          \"additionalProperties\": false,\n                          \"required\": [\n                            \"name\",\n                            \"type\"\n                          ]\n                        },\n                        {\n                          \"enum\": [\n                            \"foreign\",\n                            \"natural\",\n                            \"primary\",\n                            \"unique\"\n                          ]\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"doc_blocks\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    }\n                  },\n                  \"additionalProperties\": true,\n                  \"required\": [\n                    \"name\"\n                  ]\n                },\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"meta\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"group\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"docs\": {\n                \"type\": \"object\",\n                \"title\": \"Docs\",\n                \"properties\": {\n                  \"show\": {\n                    \"type\": \"boolean\",\n                    \"default\": true\n                  },\n                  \"node_color\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  }\n                },\n                \"additionalProperties\": false\n              },\n              \"patch_path\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"build_path\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"unrendered_config\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"created_at\": {\n                \"type\": \"number\"\n              },\n              \"config_call_dict\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"unrendered_config_call_dict\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"relation_name\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"raw_code\": {\n                \"type\": \"string\",\n                \"default\": \"\"\n              },\n              \"doc_blocks\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"language\": {\n                \"type\": \"string\",\n                \"default\": \"sql\"\n              },\n              \"refs\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"object\",\n                  \"title\": \"RefArgs\",\n                  \"properties\": {\n                    \"name\": {\n                      \"type\": \"string\"\n                    },\n                    \"package\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"version\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"number\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    }\n                  },\n                  \"additionalProperties\": false,\n                  \"required\": [\n                    \"name\"\n                  ]\n                }\n              },\n              \"sources\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"string\"\n                  }\n                }\n              },\n              \"metrics\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"string\"\n                  }\n                }\n              },\n              \"functions\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"string\"\n                  }\n                }\n              },\n              \"depends_on\": {\n                \"type\": \"object\",\n                \"title\": \"DependsOn\",\n                \"properties\": {\n                  \"macros\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"nodes\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  }\n                },\n                \"additionalProperties\": false\n              },\n              \"compiled_path\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"compiled\": {\n                \"type\": \"boolean\",\n                \"default\": false\n              },\n              \"compiled_code\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"extra_ctes_injected\": {\n                \"type\": \"boolean\",\n                \"default\": false\n              },\n              \"extra_ctes\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"object\",\n                  \"title\": \"InjectedCTE\",\n                  \"properties\": {\n                    \"id\": {\n                      \"type\": \"string\"\n                    },\n                    \"sql\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"additionalProperties\": false,\n                  \"required\": [\n                    \"id\",\n                    \"sql\"\n                  ]\n                }\n              },\n              \"_pre_injected_sql\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"contract\": {\n                \"type\": \"object\",\n                \"title\": \"Contract\",\n                \"properties\": {\n                  \"enforced\": {\n                    \"type\": \"boolean\",\n                    \"default\": false\n                  },\n                  \"alias_types\": {\n                    \"type\": \"boolean\",\n                    \"default\": true\n                  },\n                  \"checksum\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  }\n                },\n                \"additionalProperties\": false\n              }\n            },\n            \"additionalProperties\": false,\n            \"required\": [\n              \"database\",\n              \"schema\",\n              \"name\",\n              \"resource_type\",\n              \"package_name\",\n              \"path\",\n              \"original_file_path\",\n              \"unique_id\",\n              \"fqn\",\n              \"alias\",\n              \"checksum\"\n            ]\n          },\n          {\n            \"type\": \"object\",\n            \"title\": \"GenericTest\",\n            \"properties\": {\n              \"database\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ]\n              },\n              \"schema\": {\n                \"type\": \"string\"\n              },\n              \"name\": {\n                \"type\": \"string\"\n              },\n              \"resource_type\": {\n                \"const\": \"test\"\n              },\n              \"package_name\": {\n                \"type\": \"string\"\n              },\n              \"path\": {\n                \"type\": \"string\"\n              },\n              \"original_file_path\": {\n                \"type\": \"string\"\n              },\n              \"unique_id\": {\n                \"type\": \"string\"\n              },\n              \"fqn\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"alias\": {\n                \"type\": \"string\"\n              },\n              \"checksum\": {\n                \"type\": \"object\",\n                \"title\": \"FileHash\",\n                \"properties\": {\n                  \"name\": {\n                    \"type\": \"string\"\n                  },\n                  \"checksum\": {\n                    \"type\": \"string\"\n                  }\n                },\n                \"additionalProperties\": false,\n                \"required\": [\n                  \"name\",\n                  \"checksum\"\n                ]\n              },\n              \"config\": {\n                \"type\": \"object\",\n                \"title\": \"TestConfig\",\n                \"properties\": {\n                  \"_extra\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"enabled\": {\n                    \"type\": \"boolean\",\n                    \"default\": true\n                  },\n                  \"alias\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"schema\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": \"dbt_test__audit\"\n                  },\n                  \"database\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"tags\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      },\n                      {\n                        \"type\": \"string\"\n                      }\n                    ]\n                  },\n                  \"meta\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"group\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"materialized\": {\n                    \"type\": \"string\",\n                    \"default\": \"test\"\n                  },\n                  \"severity\": {\n                    \"type\": \"string\",\n                    \"default\": \"ERROR\",\n                    \"pattern\": \"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$\"\n                  },\n                  \"store_failures\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"boolean\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"store_failures_as\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"sql_header\": {\n                    \"default\": null\n                  },\n                  \"where\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"limit\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"integer\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"fail_calc\": {\n                    \"type\": \"string\",\n                    \"default\": \"count(*)\"\n                  },\n                  \"warn_if\": {\n                    \"type\": \"string\",\n                    \"default\": \"!= 0\"\n                  },\n                  \"error_if\": {\n                    \"type\": \"string\",\n                    \"default\": \"!= 0\"\n                  }\n                },\n                \"additionalProperties\": true\n              },\n              \"tags\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"description\": {\n                \"type\": \"string\",\n                \"default\": \"\"\n              },\n              \"columns\": {\n                \"type\": \"object\",\n                \"additionalProperties\": {\n                  \"type\": \"object\",\n                  \"title\": \"ColumnInfo\",\n                  \"properties\": {\n                    \"name\": {\n                      \"type\": \"string\"\n                    },\n                    \"description\": {\n                      \"type\": \"string\",\n                      \"default\": \"\"\n                    },\n                    \"meta\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"data_type\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"constraints\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"object\",\n                        \"title\": \"ColumnLevelConstraint\",\n                        \"properties\": {\n                          \"type\": {\n                            \"enum\": [\n                              \"check\",\n                              \"not_null\",\n                              \"unique\",\n                              \"primary_key\",\n                              \"foreign_key\",\n                              \"custom\"\n                            ]\n                          },\n                          \"name\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"expression\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"warn_unenforced\": {\n                            \"type\": \"boolean\",\n                            \"default\": true\n                          },\n                          \"warn_unsupported\": {\n                            \"type\": \"boolean\",\n                            \"default\": true\n                          },\n                          \"to\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"to_columns\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"string\"\n                            }\n                          }\n                        },\n                        \"additionalProperties\": false,\n                        \"required\": [\n                          \"type\"\n                        ]\n                      }\n                    },\n                    \"quote\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"boolean\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"config\": {\n                      \"type\": \"object\",\n                      \"title\": \"ColumnConfig\",\n                      \"properties\": {\n                        \"_extra\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"meta\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"tags\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      },\n                      \"additionalProperties\": true\n                    },\n                    \"tags\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"_extra\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"granularity\": {\n                      \"anyOf\": [\n                        {\n                          \"enum\": [\n                            \"nanosecond\",\n                            \"microsecond\",\n                            \"millisecond\",\n                            \"second\",\n                            \"minute\",\n                            \"hour\",\n                            \"day\",\n                            \"week\",\n                            \"month\",\n                            \"quarter\",\n                            \"year\"\n                          ]\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"dimension\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"object\",\n                          \"title\": \"ColumnDimension\",\n                          \"properties\": {\n                            \"name\": {\n                              \"type\": \"string\"\n                            },\n                            \"type\": {\n                              \"enum\": [\n                                \"categorical\",\n                                \"time\"\n                              ]\n                            },\n                            \"description\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"label\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"is_partition\": {\n                              \"type\": \"boolean\",\n                              \"default\": false\n                            },\n                            \"config\": {\n                              \"type\": \"object\",\n                              \"propertyNames\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            \"validity_params\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"object\",\n                                  \"title\": \"ColumnDimensionValidityParams\",\n                                  \"properties\": {\n                                    \"is_start\": {\n                                      \"type\": \"boolean\",\n                                      \"default\": false\n                                    },\n                                    \"is_end\": {\n                                      \"type\": \"boolean\",\n                                      \"default\": false\n                                    }\n                                  },\n                                  \"additionalProperties\": false\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            }\n                          },\n                          \"additionalProperties\": false,\n                          \"required\": [\n                            \"name\",\n                            \"type\"\n                          ]\n                        },\n                        {\n                          \"enum\": [\n                            \"categorical\",\n                            \"time\"\n                          ]\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"entity\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"object\",\n                          \"title\": \"ColumnEntity\",\n                          \"properties\": {\n                            \"name\": {\n                              \"type\": \"string\"\n                            },\n                            \"type\": {\n                              \"enum\": [\n                                \"foreign\",\n                                \"natural\",\n                                \"primary\",\n                                \"unique\"\n                              ]\n                            },\n                            \"description\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"label\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"config\": {\n                              \"type\": \"object\",\n                              \"propertyNames\": {\n                                \"type\": \"string\"\n                              }\n                            }\n                          },\n                          \"additionalProperties\": false,\n                          \"required\": [\n                            \"name\",\n                            \"type\"\n                          ]\n                        },\n                        {\n                          \"enum\": [\n                            \"foreign\",\n                            \"natural\",\n                            \"primary\",\n                            \"unique\"\n                          ]\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"doc_blocks\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    }\n                  },\n                  \"additionalProperties\": true,\n                  \"required\": [\n                    \"name\"\n                  ]\n                },\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"meta\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"group\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"docs\": {\n                \"type\": \"object\",\n                \"title\": \"Docs\",\n                \"properties\": {\n                  \"show\": {\n                    \"type\": \"boolean\",\n                    \"default\": true\n                  },\n                  \"node_color\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  }\n                },\n                \"additionalProperties\": false\n              },\n              \"patch_path\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"build_path\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"unrendered_config\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"created_at\": {\n                \"type\": \"number\"\n              },\n              \"config_call_dict\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"unrendered_config_call_dict\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"relation_name\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"raw_code\": {\n                \"type\": \"string\",\n                \"default\": \"\"\n              },\n              \"doc_blocks\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"language\": {\n                \"type\": \"string\",\n                \"default\": \"sql\"\n              },\n              \"refs\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"object\",\n                  \"title\": \"RefArgs\",\n                  \"properties\": {\n                    \"name\": {\n                      \"type\": \"string\"\n                    },\n                    \"package\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"version\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"number\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    }\n                  },\n                  \"additionalProperties\": false,\n                  \"required\": [\n                    \"name\"\n                  ]\n                }\n              },\n              \"sources\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"string\"\n                  }\n                }\n              },\n              \"metrics\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"string\"\n                  }\n                }\n              },\n              \"functions\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"string\"\n                  }\n                }\n              },\n              \"depends_on\": {\n                \"type\": \"object\",\n                \"title\": \"DependsOn\",\n                \"properties\": {\n                  \"macros\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"nodes\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  }\n                },\n                \"additionalProperties\": false\n              },\n              \"compiled_path\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"compiled\": {\n                \"type\": \"boolean\",\n                \"default\": false\n              },\n              \"compiled_code\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"extra_ctes_injected\": {\n                \"type\": \"boolean\",\n                \"default\": false\n              },\n              \"extra_ctes\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"object\",\n                  \"title\": \"InjectedCTE\",\n                  \"properties\": {\n                    \"id\": {\n                      \"type\": \"string\"\n                    },\n                    \"sql\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"additionalProperties\": false,\n                  \"required\": [\n                    \"id\",\n                    \"sql\"\n                  ]\n                }\n              },\n              \"_pre_injected_sql\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"contract\": {\n                \"type\": \"object\",\n                \"title\": \"Contract\",\n                \"properties\": {\n                  \"enforced\": {\n                    \"type\": \"boolean\",\n                    \"default\": false\n                  },\n                  \"alias_types\": {\n                    \"type\": \"boolean\",\n                    \"default\": true\n                  },\n                  \"checksum\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  }\n                },\n                \"additionalProperties\": false\n              },\n              \"column_name\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"file_key_name\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"attached_node\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"test_metadata\": {\n                \"type\": \"object\",\n                \"title\": \"TestMetadata\",\n                \"properties\": {\n                  \"name\": {\n                    \"type\": \"string\",\n                    \"default\": \"test\"\n                  },\n                  \"kwargs\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"namespace\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  }\n                },\n                \"additionalProperties\": false\n              }\n            },\n            \"additionalProperties\": false,\n            \"required\": [\n              \"database\",\n              \"schema\",\n              \"name\",\n              \"resource_type\",\n              \"package_name\",\n              \"path\",\n              \"original_file_path\",\n              \"unique_id\",\n              \"fqn\",\n              \"alias\",\n              \"checksum\"\n            ]\n          },\n          {\n            \"type\": \"object\",\n            \"title\": \"Snapshot\",\n            \"properties\": {\n              \"database\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ]\n              },\n              \"schema\": {\n                \"type\": \"string\"\n              },\n              \"name\": {\n                \"type\": \"string\"\n              },\n              \"resource_type\": {\n                \"const\": \"snapshot\"\n              },\n              \"package_name\": {\n                \"type\": \"string\"\n              },\n              \"path\": {\n                \"type\": \"string\"\n              },\n              \"original_file_path\": {\n                \"type\": \"string\"\n              },\n              \"unique_id\": {\n                \"type\": \"string\"\n              },\n              \"fqn\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"alias\": {\n                \"type\": \"string\"\n              },\n              \"checksum\": {\n                \"type\": \"object\",\n                \"title\": \"FileHash\",\n                \"properties\": {\n                  \"name\": {\n                    \"type\": \"string\"\n                  },\n                  \"checksum\": {\n                    \"type\": \"string\"\n                  }\n                },\n                \"additionalProperties\": false,\n                \"required\": [\n                  \"name\",\n                  \"checksum\"\n                ]\n              },\n              \"config\": {\n                \"type\": \"object\",\n                \"title\": \"SnapshotConfig\",\n                \"properties\": {\n                  \"_extra\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"enabled\": {\n                    \"type\": \"boolean\",\n                    \"default\": true\n                  },\n                  \"alias\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"schema\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"database\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"tags\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      },\n                      {\n                        \"type\": \"string\"\n                      }\n                    ]\n                  },\n                  \"meta\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"group\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"materialized\": {\n                    \"type\": \"string\",\n                    \"default\": \"snapshot\"\n                  },\n                  \"incremental_strategy\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"batch_size\": {\n                    \"default\": null\n                  },\n                  \"lookback\": {\n                    \"default\": 1\n                  },\n                  \"begin\": {\n                    \"default\": null\n                  },\n                  \"persist_docs\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"post-hook\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"title\": \"Hook\",\n                      \"properties\": {\n                        \"sql\": {\n                          \"type\": \"string\"\n                        },\n                        \"transaction\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"index\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"integer\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": false,\n                      \"required\": [\n                        \"sql\"\n                      ]\n                    }\n                  },\n                  \"pre-hook\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"title\": \"Hook\",\n                      \"properties\": {\n                        \"sql\": {\n                          \"type\": \"string\"\n                        },\n                        \"transaction\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"index\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"integer\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": false,\n                      \"required\": [\n                        \"sql\"\n                      ]\n                    }\n                  },\n                  \"quoting\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"column_types\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"full_refresh\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"boolean\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"unique_key\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"on_schema_change\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": \"ignore\"\n                  },\n                  \"on_configuration_change\": {\n                    \"enum\": [\n                      \"apply\",\n                      \"continue\",\n                      \"fail\"\n                    ]\n                  },\n                  \"grants\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"packages\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"docs\": {\n                    \"type\": \"object\",\n                    \"title\": \"Docs\",\n                    \"properties\": {\n                      \"show\": {\n                        \"type\": \"boolean\",\n                        \"default\": true\n                      },\n                      \"node_color\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"string\"\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ],\n                        \"default\": null\n                      }\n                    },\n                    \"additionalProperties\": false\n                  },\n                  \"contract\": {\n                    \"type\": \"object\",\n                    \"title\": \"ContractConfig\",\n                    \"properties\": {\n                      \"enforced\": {\n                        \"type\": \"boolean\",\n                        \"default\": false\n                      },\n                      \"alias_types\": {\n                        \"type\": \"boolean\",\n                        \"default\": true\n                      }\n                    },\n                    \"additionalProperties\": false\n                  },\n                  \"event_time\": {\n                    \"default\": null\n                  },\n                  \"concurrent_batches\": {\n                    \"default\": null\n                  },\n                  \"strategy\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"target_schema\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"target_database\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"updated_at\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"check_cols\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"snapshot_meta_column_names\": {\n                    \"type\": \"object\",\n                    \"title\": \"SnapshotMetaColumnNames\",\n                    \"properties\": {\n                      \"dbt_valid_to\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"string\"\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ],\n                        \"default\": null\n                      },\n                      \"dbt_valid_from\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"string\"\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ],\n                        \"default\": null\n                      },\n                      \"dbt_scd_id\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"string\"\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ],\n                        \"default\": null\n                      },\n                      \"dbt_updated_at\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"string\"\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ],\n                        \"default\": null\n                      },\n                      \"dbt_is_deleted\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"string\"\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ],\n                        \"default\": null\n                      }\n                    },\n                    \"additionalProperties\": false\n                  },\n                  \"dbt_valid_to_current\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  }\n                },\n                \"additionalProperties\": true\n              },\n              \"tags\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"description\": {\n                \"type\": \"string\",\n                \"default\": \"\"\n              },\n              \"columns\": {\n                \"type\": \"object\",\n                \"additionalProperties\": {\n                  \"type\": \"object\",\n                  \"title\": \"ColumnInfo\",\n                  \"properties\": {\n                    \"name\": {\n                      \"type\": \"string\"\n                    },\n                    \"description\": {\n                      \"type\": \"string\",\n                      \"default\": \"\"\n                    },\n                    \"meta\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"data_type\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"constraints\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"object\",\n                        \"title\": \"ColumnLevelConstraint\",\n                        \"properties\": {\n                          \"type\": {\n                            \"enum\": [\n                              \"check\",\n                              \"not_null\",\n                              \"unique\",\n                              \"primary_key\",\n                              \"foreign_key\",\n                              \"custom\"\n                            ]\n                          },\n                          \"name\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"expression\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"warn_unenforced\": {\n                            \"type\": \"boolean\",\n                            \"default\": true\n                          },\n                          \"warn_unsupported\": {\n                            \"type\": \"boolean\",\n                            \"default\": true\n                          },\n                          \"to\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"to_columns\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"string\"\n                            }\n                          }\n                        },\n                        \"additionalProperties\": false,\n                        \"required\": [\n                          \"type\"\n                        ]\n                      }\n                    },\n                    \"quote\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"boolean\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"config\": {\n                      \"type\": \"object\",\n                      \"title\": \"ColumnConfig\",\n                      \"properties\": {\n                        \"_extra\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"meta\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"tags\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      },\n                      \"additionalProperties\": true\n                    },\n                    \"tags\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"_extra\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"granularity\": {\n                      \"anyOf\": [\n                        {\n                          \"enum\": [\n                            \"nanosecond\",\n                            \"microsecond\",\n                            \"millisecond\",\n                            \"second\",\n                            \"minute\",\n                            \"hour\",\n                            \"day\",\n                            \"week\",\n                            \"month\",\n                            \"quarter\",\n                            \"year\"\n                          ]\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"dimension\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"object\",\n                          \"title\": \"ColumnDimension\",\n                          \"properties\": {\n                            \"name\": {\n                              \"type\": \"string\"\n                            },\n                            \"type\": {\n                              \"enum\": [\n                                \"categorical\",\n                                \"time\"\n                              ]\n                            },\n                            \"description\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"label\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"is_partition\": {\n                              \"type\": \"boolean\",\n                              \"default\": false\n                            },\n                            \"config\": {\n                              \"type\": \"object\",\n                              \"propertyNames\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            \"validity_params\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"object\",\n                                  \"title\": \"ColumnDimensionValidityParams\",\n                                  \"properties\": {\n                                    \"is_start\": {\n                                      \"type\": \"boolean\",\n                                      \"default\": false\n                                    },\n                                    \"is_end\": {\n                                      \"type\": \"boolean\",\n                                      \"default\": false\n                                    }\n                                  },\n                                  \"additionalProperties\": false\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            }\n                          },\n                          \"additionalProperties\": false,\n                          \"required\": [\n                            \"name\",\n                            \"type\"\n                          ]\n                        },\n                        {\n                          \"enum\": [\n                            \"categorical\",\n                            \"time\"\n                          ]\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"entity\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"object\",\n                          \"title\": \"ColumnEntity\",\n                          \"properties\": {\n                            \"name\": {\n                              \"type\": \"string\"\n                            },\n                            \"type\": {\n                              \"enum\": [\n                                \"foreign\",\n                                \"natural\",\n                                \"primary\",\n                                \"unique\"\n                              ]\n                            },\n                            \"description\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"label\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"config\": {\n                              \"type\": \"object\",\n                              \"propertyNames\": {\n                                \"type\": \"string\"\n                              }\n                            }\n                          },\n                          \"additionalProperties\": false,\n                          \"required\": [\n                            \"name\",\n                            \"type\"\n                          ]\n                        },\n                        {\n                          \"enum\": [\n                            \"foreign\",\n                            \"natural\",\n                            \"primary\",\n                            \"unique\"\n                          ]\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"doc_blocks\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    }\n                  },\n                  \"additionalProperties\": true,\n                  \"required\": [\n                    \"name\"\n                  ]\n                },\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"meta\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"group\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"docs\": {\n                \"type\": \"object\",\n                \"title\": \"Docs\",\n                \"properties\": {\n                  \"show\": {\n                    \"type\": \"boolean\",\n                    \"default\": true\n                  },\n                  \"node_color\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  }\n                },\n                \"additionalProperties\": false\n              },\n              \"patch_path\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"build_path\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"unrendered_config\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"created_at\": {\n                \"type\": \"number\"\n              },\n              \"config_call_dict\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"unrendered_config_call_dict\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"relation_name\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"raw_code\": {\n                \"type\": \"string\",\n                \"default\": \"\"\n              },\n              \"doc_blocks\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"language\": {\n                \"type\": \"string\",\n                \"default\": \"sql\"\n              },\n              \"refs\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"object\",\n                  \"title\": \"RefArgs\",\n                  \"properties\": {\n                    \"name\": {\n                      \"type\": \"string\"\n                    },\n                    \"package\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"version\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"number\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    }\n                  },\n                  \"additionalProperties\": false,\n                  \"required\": [\n                    \"name\"\n                  ]\n                }\n              },\n              \"sources\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"string\"\n                  }\n                }\n              },\n              \"metrics\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"string\"\n                  }\n                }\n              },\n              \"functions\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"string\"\n                  }\n                }\n              },\n              \"depends_on\": {\n                \"type\": \"object\",\n                \"title\": \"DependsOn\",\n                \"properties\": {\n                  \"macros\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"nodes\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  }\n                },\n                \"additionalProperties\": false\n              },\n              \"compiled_path\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"compiled\": {\n                \"type\": \"boolean\",\n                \"default\": false\n              },\n              \"compiled_code\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"extra_ctes_injected\": {\n                \"type\": \"boolean\",\n                \"default\": false\n              },\n              \"extra_ctes\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"object\",\n                  \"title\": \"InjectedCTE\",\n                  \"properties\": {\n                    \"id\": {\n                      \"type\": \"string\"\n                    },\n                    \"sql\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"additionalProperties\": false,\n                  \"required\": [\n                    \"id\",\n                    \"sql\"\n                  ]\n                }\n              },\n              \"_pre_injected_sql\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"contract\": {\n                \"type\": \"object\",\n                \"title\": \"Contract\",\n                \"properties\": {\n                  \"enforced\": {\n                    \"type\": \"boolean\",\n                    \"default\": false\n                  },\n                  \"alias_types\": {\n                    \"type\": \"boolean\",\n                    \"default\": true\n                  },\n                  \"checksum\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  }\n                },\n                \"additionalProperties\": false\n              },\n              \"defer_relation\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"object\",\n                    \"title\": \"DeferRelation\",\n                    \"properties\": {\n                      \"database\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"string\"\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ]\n                      },\n                      \"schema\": {\n                        \"type\": \"string\"\n                      },\n                      \"alias\": {\n                        \"type\": \"string\"\n                      },\n                      \"relation_name\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"string\"\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ]\n                      },\n                      \"resource_type\": {\n                        \"enum\": [\n                          \"model\",\n                          \"analysis\",\n                          \"test\",\n                          \"snapshot\",\n                          \"operation\",\n                          \"seed\",\n                          \"rpc\",\n                          \"sql_operation\",\n                          \"doc\",\n                          \"source\",\n                          \"macro\",\n                          \"exposure\",\n                          \"metric\",\n                          \"group\",\n                          \"saved_query\",\n                          \"semantic_model\",\n                          \"unit_test\",\n                          \"fixture\",\n                          \"function\"\n                        ]\n                      },\n                      \"name\": {\n                        \"type\": \"string\"\n                      },\n                      \"description\": {\n                        \"type\": \"string\"\n                      },\n                      \"compiled_code\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"string\"\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ]\n                      },\n                      \"meta\": {\n                        \"type\": \"object\",\n                        \"propertyNames\": {\n                          \"type\": \"string\"\n                        }\n                      },\n                      \"tags\": {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      },\n                      \"config\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"object\",\n                            \"title\": \"NodeConfig\",\n                            \"properties\": {\n                              \"_extra\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"enabled\": {\n                                \"type\": \"boolean\",\n                                \"default\": true\n                              },\n                              \"alias\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"string\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"schema\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"string\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"database\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"string\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"tags\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"array\",\n                                    \"items\": {\n                                      \"type\": \"string\"\n                                    }\n                                  },\n                                  {\n                                    \"type\": \"string\"\n                                  }\n                                ]\n                              },\n                              \"meta\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"group\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"string\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"materialized\": {\n                                \"type\": \"string\",\n                                \"default\": \"view\"\n                              },\n                              \"incremental_strategy\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"string\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"batch_size\": {\n                                \"default\": null\n                              },\n                              \"lookback\": {\n                                \"default\": 1\n                              },\n                              \"begin\": {\n                                \"default\": null\n                              },\n                              \"persist_docs\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"post-hook\": {\n                                \"type\": \"array\",\n                                \"items\": {\n                                  \"type\": \"object\",\n                                  \"title\": \"Hook\",\n                                  \"properties\": {\n                                    \"sql\": {\n                                      \"type\": \"string\"\n                                    },\n                                    \"transaction\": {\n                                      \"type\": \"boolean\",\n                                      \"default\": true\n                                    },\n                                    \"index\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"integer\"\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    }\n                                  },\n                                  \"additionalProperties\": false,\n                                  \"required\": [\n                                    \"sql\"\n                                  ]\n                                }\n                              },\n                              \"pre-hook\": {\n                                \"type\": \"array\",\n                                \"items\": {\n                                  \"type\": \"object\",\n                                  \"title\": \"Hook\",\n                                  \"properties\": {\n                                    \"sql\": {\n                                      \"type\": \"string\"\n                                    },\n                                    \"transaction\": {\n                                      \"type\": \"boolean\",\n                                      \"default\": true\n                                    },\n                                    \"index\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"integer\"\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    }\n                                  },\n                                  \"additionalProperties\": false,\n                                  \"required\": [\n                                    \"sql\"\n                                  ]\n                                }\n                              },\n                              \"quoting\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"column_types\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"full_refresh\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"boolean\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"unique_key\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"string\"\n                                  },\n                                  {\n                                    \"type\": \"array\",\n                                    \"items\": {\n                                      \"type\": \"string\"\n                                    }\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"on_schema_change\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"string\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": \"ignore\"\n                              },\n                              \"on_configuration_change\": {\n                                \"enum\": [\n                                  \"apply\",\n                                  \"continue\",\n                                  \"fail\"\n                                ]\n                              },\n                              \"grants\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"packages\": {\n                                \"type\": \"array\",\n                                \"items\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"docs\": {\n                                \"type\": \"object\",\n                                \"title\": \"Docs\",\n                                \"properties\": {\n                                  \"show\": {\n                                    \"type\": \"boolean\",\n                                    \"default\": true\n                                  },\n                                  \"node_color\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  }\n                                },\n                                \"additionalProperties\": false\n                              },\n                              \"contract\": {\n                                \"type\": \"object\",\n                                \"title\": \"ContractConfig\",\n                                \"properties\": {\n                                  \"enforced\": {\n                                    \"type\": \"boolean\",\n                                    \"default\": false\n                                  },\n                                  \"alias_types\": {\n                                    \"type\": \"boolean\",\n                                    \"default\": true\n                                  }\n                                },\n                                \"additionalProperties\": false\n                              },\n                              \"event_time\": {\n                                \"default\": null\n                              },\n                              \"concurrent_batches\": {\n                                \"default\": null\n                              }\n                            },\n                            \"additionalProperties\": true\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ]\n                      }\n                    },\n                    \"additionalProperties\": false,\n                    \"required\": [\n                      \"database\",\n                      \"schema\",\n                      \"alias\",\n                      \"relation_name\",\n                      \"resource_type\",\n                      \"name\",\n                      \"description\",\n                      \"compiled_code\",\n                      \"meta\",\n                      \"tags\",\n                      \"config\"\n                    ]\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              }\n            },\n            \"additionalProperties\": false,\n            \"required\": [\n              \"database\",\n              \"schema\",\n              \"name\",\n              \"resource_type\",\n              \"package_name\",\n              \"path\",\n              \"original_file_path\",\n              \"unique_id\",\n              \"fqn\",\n              \"alias\",\n              \"checksum\",\n              \"config\"\n            ]\n          },\n          {\n            \"type\": \"object\",\n            \"title\": \"Function\",\n            \"properties\": {\n              \"returns\": {\n                \"type\": \"object\",\n                \"title\": \"FunctionReturns\",\n                \"properties\": {\n                  \"data_type\": {\n                    \"type\": \"string\"\n                  },\n                  \"description\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  }\n                },\n                \"additionalProperties\": false,\n                \"required\": [\n                  \"data_type\"\n                ]\n              },\n              \"database\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ]\n              },\n              \"schema\": {\n                \"type\": \"string\"\n              },\n              \"name\": {\n                \"type\": \"string\"\n              },\n              \"resource_type\": {\n                \"const\": \"function\"\n              },\n              \"package_name\": {\n                \"type\": \"string\"\n              },\n              \"path\": {\n                \"type\": \"string\"\n              },\n              \"original_file_path\": {\n                \"type\": \"string\"\n              },\n              \"unique_id\": {\n                \"type\": \"string\"\n              },\n              \"fqn\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"alias\": {\n                \"type\": \"string\"\n              },\n              \"checksum\": {\n                \"type\": \"object\",\n                \"title\": \"FileHash\",\n                \"properties\": {\n                  \"name\": {\n                    \"type\": \"string\"\n                  },\n                  \"checksum\": {\n                    \"type\": \"string\"\n                  }\n                },\n                \"additionalProperties\": false,\n                \"required\": [\n                  \"name\",\n                  \"checksum\"\n                ]\n              },\n              \"config\": {\n                \"type\": \"object\",\n                \"title\": \"FunctionConfig\",\n                \"properties\": {\n                  \"_extra\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"enabled\": {\n                    \"type\": \"boolean\",\n                    \"default\": true\n                  },\n                  \"alias\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"schema\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"database\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"tags\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      },\n                      {\n                        \"type\": \"string\"\n                      }\n                    ]\n                  },\n                  \"meta\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"group\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"materialized\": {\n                    \"type\": \"string\",\n                    \"default\": \"function\"\n                  },\n                  \"incremental_strategy\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"batch_size\": {\n                    \"default\": null\n                  },\n                  \"lookback\": {\n                    \"default\": 1\n                  },\n                  \"begin\": {\n                    \"default\": null\n                  },\n                  \"persist_docs\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"post-hook\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"title\": \"Hook\",\n                      \"properties\": {\n                        \"sql\": {\n                          \"type\": \"string\"\n                        },\n                        \"transaction\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"index\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"integer\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": false,\n                      \"required\": [\n                        \"sql\"\n                      ]\n                    }\n                  },\n                  \"pre-hook\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"title\": \"Hook\",\n                      \"properties\": {\n                        \"sql\": {\n                          \"type\": \"string\"\n                        },\n                        \"transaction\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"index\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"integer\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": false,\n                      \"required\": [\n                        \"sql\"\n                      ]\n                    }\n                  },\n                  \"quoting\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"column_types\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"full_refresh\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"boolean\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"unique_key\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"on_schema_change\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": \"ignore\"\n                  },\n                  \"on_configuration_change\": {\n                    \"enum\": [\n                      \"apply\",\n                      \"continue\",\n                      \"fail\"\n                    ]\n                  },\n                  \"grants\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"packages\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"docs\": {\n                    \"type\": \"object\",\n                    \"title\": \"Docs\",\n                    \"properties\": {\n                      \"show\": {\n                        \"type\": \"boolean\",\n                        \"default\": true\n                      },\n                      \"node_color\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"string\"\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ],\n                        \"default\": null\n                      }\n                    },\n                    \"additionalProperties\": false\n                  },\n                  \"contract\": {\n                    \"type\": \"object\",\n                    \"title\": \"ContractConfig\",\n                    \"properties\": {\n                      \"enforced\": {\n                        \"type\": \"boolean\",\n                        \"default\": false\n                      },\n                      \"alias_types\": {\n                        \"type\": \"boolean\",\n                        \"default\": true\n                      }\n                    },\n                    \"additionalProperties\": false\n                  },\n                  \"event_time\": {\n                    \"default\": null\n                  },\n                  \"concurrent_batches\": {\n                    \"default\": null\n                  },\n                  \"type\": {\n                    \"enum\": [\n                      \"scalar\",\n                      \"aggregate\",\n                      \"table\"\n                    ],\n                    \"default\": \"scalar\"\n                  },\n                  \"volatility\": {\n                    \"anyOf\": [\n                      {\n                        \"enum\": [\n                          \"deterministic\",\n                          \"stable\",\n                          \"non-deterministic\"\n                        ]\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"runtime_version\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"entry_point\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  }\n                },\n                \"additionalProperties\": true\n              },\n              \"tags\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"description\": {\n                \"type\": \"string\",\n                \"default\": \"\"\n              },\n              \"columns\": {\n                \"type\": \"object\",\n                \"additionalProperties\": {\n                  \"type\": \"object\",\n                  \"title\": \"ColumnInfo\",\n                  \"properties\": {\n                    \"name\": {\n                      \"type\": \"string\"\n                    },\n                    \"description\": {\n                      \"type\": \"string\",\n                      \"default\": \"\"\n                    },\n                    \"meta\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"data_type\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"constraints\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"object\",\n                        \"title\": \"ColumnLevelConstraint\",\n                        \"properties\": {\n                          \"type\": {\n                            \"enum\": [\n                              \"check\",\n                              \"not_null\",\n                              \"unique\",\n                              \"primary_key\",\n                              \"foreign_key\",\n                              \"custom\"\n                            ]\n                          },\n                          \"name\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"expression\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"warn_unenforced\": {\n                            \"type\": \"boolean\",\n                            \"default\": true\n                          },\n                          \"warn_unsupported\": {\n                            \"type\": \"boolean\",\n                            \"default\": true\n                          },\n                          \"to\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"to_columns\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"string\"\n                            }\n                          }\n                        },\n                        \"additionalProperties\": false,\n                        \"required\": [\n                          \"type\"\n                        ]\n                      }\n                    },\n                    \"quote\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"boolean\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"config\": {\n                      \"type\": \"object\",\n                      \"title\": \"ColumnConfig\",\n                      \"properties\": {\n                        \"_extra\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"meta\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"tags\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      },\n                      \"additionalProperties\": true\n                    },\n                    \"tags\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"_extra\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"granularity\": {\n                      \"anyOf\": [\n                        {\n                          \"enum\": [\n                            \"nanosecond\",\n                            \"microsecond\",\n                            \"millisecond\",\n                            \"second\",\n                            \"minute\",\n                            \"hour\",\n                            \"day\",\n                            \"week\",\n                            \"month\",\n                            \"quarter\",\n                            \"year\"\n                          ]\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"dimension\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"object\",\n                          \"title\": \"ColumnDimension\",\n                          \"properties\": {\n                            \"name\": {\n                              \"type\": \"string\"\n                            },\n                            \"type\": {\n                              \"enum\": [\n                                \"categorical\",\n                                \"time\"\n                              ]\n                            },\n                            \"description\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"label\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"is_partition\": {\n                              \"type\": \"boolean\",\n                              \"default\": false\n                            },\n                            \"config\": {\n                              \"type\": \"object\",\n                              \"propertyNames\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            \"validity_params\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"object\",\n                                  \"title\": \"ColumnDimensionValidityParams\",\n                                  \"properties\": {\n                                    \"is_start\": {\n                                      \"type\": \"boolean\",\n                                      \"default\": false\n                                    },\n                                    \"is_end\": {\n                                      \"type\": \"boolean\",\n                                      \"default\": false\n                                    }\n                                  },\n                                  \"additionalProperties\": false\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            }\n                          },\n                          \"additionalProperties\": false,\n                          \"required\": [\n                            \"name\",\n                            \"type\"\n                          ]\n                        },\n                        {\n                          \"enum\": [\n                            \"categorical\",\n                            \"time\"\n                          ]\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"entity\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"object\",\n                          \"title\": \"ColumnEntity\",\n                          \"properties\": {\n                            \"name\": {\n                              \"type\": \"string\"\n                            },\n                            \"type\": {\n                              \"enum\": [\n                                \"foreign\",\n                                \"natural\",\n                                \"primary\",\n                                \"unique\"\n                              ]\n                            },\n                            \"description\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"label\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"config\": {\n                              \"type\": \"object\",\n                              \"propertyNames\": {\n                                \"type\": \"string\"\n                              }\n                            }\n                          },\n                          \"additionalProperties\": false,\n                          \"required\": [\n                            \"name\",\n                            \"type\"\n                          ]\n                        },\n                        {\n                          \"enum\": [\n                            \"foreign\",\n                            \"natural\",\n                            \"primary\",\n                            \"unique\"\n                          ]\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"doc_blocks\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    }\n                  },\n                  \"additionalProperties\": true,\n                  \"required\": [\n                    \"name\"\n                  ]\n                },\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"meta\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"group\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"docs\": {\n                \"type\": \"object\",\n                \"title\": \"Docs\",\n                \"properties\": {\n                  \"show\": {\n                    \"type\": \"boolean\",\n                    \"default\": true\n                  },\n                  \"node_color\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  }\n                },\n                \"additionalProperties\": false\n              },\n              \"patch_path\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"build_path\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"unrendered_config\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"created_at\": {\n                \"type\": \"number\"\n              },\n              \"config_call_dict\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"unrendered_config_call_dict\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"relation_name\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"raw_code\": {\n                \"type\": \"string\",\n                \"default\": \"\"\n              },\n              \"doc_blocks\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"language\": {\n                \"type\": \"string\",\n                \"default\": \"sql\"\n              },\n              \"refs\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"object\",\n                  \"title\": \"RefArgs\",\n                  \"properties\": {\n                    \"name\": {\n                      \"type\": \"string\"\n                    },\n                    \"package\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"version\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"number\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    }\n                  },\n                  \"additionalProperties\": false,\n                  \"required\": [\n                    \"name\"\n                  ]\n                }\n              },\n              \"sources\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"string\"\n                  }\n                }\n              },\n              \"metrics\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"string\"\n                  }\n                }\n              },\n              \"functions\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"string\"\n                  }\n                }\n              },\n              \"depends_on\": {\n                \"type\": \"object\",\n                \"title\": \"DependsOn\",\n                \"properties\": {\n                  \"macros\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"nodes\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  }\n                },\n                \"additionalProperties\": false\n              },\n              \"compiled_path\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"compiled\": {\n                \"type\": \"boolean\",\n                \"default\": false\n              },\n              \"compiled_code\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"extra_ctes_injected\": {\n                \"type\": \"boolean\",\n                \"default\": false\n              },\n              \"extra_ctes\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"object\",\n                  \"title\": \"InjectedCTE\",\n                  \"properties\": {\n                    \"id\": {\n                      \"type\": \"string\"\n                    },\n                    \"sql\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"additionalProperties\": false,\n                  \"required\": [\n                    \"id\",\n                    \"sql\"\n                  ]\n                }\n              },\n              \"_pre_injected_sql\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"contract\": {\n                \"type\": \"object\",\n                \"title\": \"Contract\",\n                \"properties\": {\n                  \"enforced\": {\n                    \"type\": \"boolean\",\n                    \"default\": false\n                  },\n                  \"alias_types\": {\n                    \"type\": \"boolean\",\n                    \"default\": true\n                  },\n                  \"checksum\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  }\n                },\n                \"additionalProperties\": false\n              },\n              \"arguments\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"object\",\n                  \"title\": \"FunctionArgument\",\n                  \"properties\": {\n                    \"name\": {\n                      \"type\": \"string\"\n                    },\n                    \"data_type\": {\n                      \"type\": \"string\"\n                    },\n                    \"description\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"default_value\": {\n                      \"anyOf\": [\n                        {},\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    }\n                  },\n                  \"additionalProperties\": false,\n                  \"required\": [\n                    \"name\",\n                    \"data_type\"\n                  ]\n                }\n              },\n              \"defer_function\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"object\",\n                    \"title\": \"DeferFunction\",\n                    \"properties\": {\n                      \"database\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"string\"\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ]\n                      },\n                      \"schema\": {\n                        \"type\": \"string\"\n                      },\n                      \"alias\": {\n                        \"type\": \"string\"\n                      },\n                      \"resource_type\": {\n                        \"enum\": [\n                          \"model\",\n                          \"analysis\",\n                          \"test\",\n                          \"snapshot\",\n                          \"operation\",\n                          \"seed\",\n                          \"rpc\",\n                          \"sql_operation\",\n                          \"doc\",\n                          \"source\",\n                          \"macro\",\n                          \"exposure\",\n                          \"metric\",\n                          \"group\",\n                          \"saved_query\",\n                          \"semantic_model\",\n                          \"unit_test\",\n                          \"fixture\",\n                          \"function\"\n                        ]\n                      },\n                      \"name\": {\n                        \"type\": \"string\"\n                      },\n                      \"description\": {\n                        \"type\": \"string\"\n                      },\n                      \"compiled_code\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"string\"\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ]\n                      },\n                      \"meta\": {\n                        \"type\": \"object\",\n                        \"propertyNames\": {\n                          \"type\": \"string\"\n                        }\n                      },\n                      \"tags\": {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      },\n                      \"config\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"object\",\n                            \"title\": \"FunctionConfig\",\n                            \"properties\": {\n                              \"_extra\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"enabled\": {\n                                \"type\": \"boolean\",\n                                \"default\": true\n                              },\n                              \"alias\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"string\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"schema\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"string\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"database\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"string\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"tags\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"array\",\n                                    \"items\": {\n                                      \"type\": \"string\"\n                                    }\n                                  },\n                                  {\n                                    \"type\": \"string\"\n                                  }\n                                ]\n                              },\n                              \"meta\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"group\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"string\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"materialized\": {\n                                \"type\": \"string\",\n                                \"default\": \"function\"\n                              },\n                              \"incremental_strategy\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"string\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"batch_size\": {\n                                \"default\": null\n                              },\n                              \"lookback\": {\n                                \"default\": 1\n                              },\n                              \"begin\": {\n                                \"default\": null\n                              },\n                              \"persist_docs\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"post-hook\": {\n                                \"type\": \"array\",\n                                \"items\": {\n                                  \"type\": \"object\",\n                                  \"title\": \"Hook\",\n                                  \"properties\": {\n                                    \"sql\": {\n                                      \"type\": \"string\"\n                                    },\n                                    \"transaction\": {\n                                      \"type\": \"boolean\",\n                                      \"default\": true\n                                    },\n                                    \"index\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"integer\"\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    }\n                                  },\n                                  \"additionalProperties\": false,\n                                  \"required\": [\n                                    \"sql\"\n                                  ]\n                                }\n                              },\n                              \"pre-hook\": {\n                                \"type\": \"array\",\n                                \"items\": {\n                                  \"type\": \"object\",\n                                  \"title\": \"Hook\",\n                                  \"properties\": {\n                                    \"sql\": {\n                                      \"type\": \"string\"\n                                    },\n                                    \"transaction\": {\n                                      \"type\": \"boolean\",\n                                      \"default\": true\n                                    },\n                                    \"index\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"integer\"\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    }\n                                  },\n                                  \"additionalProperties\": false,\n                                  \"required\": [\n                                    \"sql\"\n                                  ]\n                                }\n                              },\n                              \"quoting\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"column_types\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"full_refresh\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"boolean\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"unique_key\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"string\"\n                                  },\n                                  {\n                                    \"type\": \"array\",\n                                    \"items\": {\n                                      \"type\": \"string\"\n                                    }\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"on_schema_change\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"string\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": \"ignore\"\n                              },\n                              \"on_configuration_change\": {\n                                \"enum\": [\n                                  \"apply\",\n                                  \"continue\",\n                                  \"fail\"\n                                ]\n                              },\n                              \"grants\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"packages\": {\n                                \"type\": \"array\",\n                                \"items\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"docs\": {\n                                \"type\": \"object\",\n                                \"title\": \"Docs\",\n                                \"properties\": {\n                                  \"show\": {\n                                    \"type\": \"boolean\",\n                                    \"default\": true\n                                  },\n                                  \"node_color\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  }\n                                },\n                                \"additionalProperties\": false\n                              },\n                              \"contract\": {\n                                \"type\": \"object\",\n                                \"title\": \"ContractConfig\",\n                                \"properties\": {\n                                  \"enforced\": {\n                                    \"type\": \"boolean\",\n                                    \"default\": false\n                                  },\n                                  \"alias_types\": {\n                                    \"type\": \"boolean\",\n                                    \"default\": true\n                                  }\n                                },\n                                \"additionalProperties\": false\n                              },\n                              \"event_time\": {\n                                \"default\": null\n                              },\n                              \"concurrent_batches\": {\n                                \"default\": null\n                              },\n                              \"type\": {\n                                \"enum\": [\n                                  \"scalar\",\n                                  \"aggregate\",\n                                  \"table\"\n                                ],\n                                \"default\": \"scalar\"\n                              },\n                              \"volatility\": {\n                                \"anyOf\": [\n                                  {\n                                    \"enum\": [\n                                      \"deterministic\",\n                                      \"stable\",\n                                      \"non-deterministic\"\n                                    ]\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"runtime_version\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"string\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"entry_point\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"string\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              }\n                            },\n                            \"additionalProperties\": true\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ]\n                      },\n                      \"arguments\": {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"object\",\n                          \"title\": \"FunctionArgument\",\n                          \"properties\": {\n                            \"name\": {\n                              \"type\": \"string\"\n                            },\n                            \"data_type\": {\n                              \"type\": \"string\"\n                            },\n                            \"description\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"default_value\": {\n                              \"anyOf\": [\n                                {},\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            }\n                          },\n                          \"additionalProperties\": false,\n                          \"required\": [\n                            \"name\",\n                            \"data_type\"\n                          ]\n                        }\n                      },\n                      \"returns\": {\n                        \"type\": \"object\",\n                        \"title\": \"FunctionReturns\",\n                        \"properties\": {\n                          \"data_type\": {\n                            \"type\": \"string\"\n                          },\n                          \"description\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          }\n                        },\n                        \"additionalProperties\": false,\n                        \"required\": [\n                          \"data_type\"\n                        ]\n                      }\n                    },\n                    \"additionalProperties\": false,\n                    \"required\": [\n                      \"database\",\n                      \"schema\",\n                      \"alias\",\n                      \"resource_type\",\n                      \"name\",\n                      \"description\",\n                      \"compiled_code\",\n                      \"meta\",\n                      \"tags\",\n                      \"config\",\n                      \"arguments\",\n                      \"returns\"\n                    ]\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              }\n            },\n            \"additionalProperties\": false,\n            \"required\": [\n              \"returns\",\n              \"database\",\n              \"schema\",\n              \"name\",\n              \"resource_type\",\n              \"package_name\",\n              \"path\",\n              \"original_file_path\",\n              \"unique_id\",\n              \"fqn\",\n              \"alias\",\n              \"checksum\",\n              \"config\"\n            ]\n          }\n        ]\n      },\n      \"propertyNames\": {\n        \"type\": \"string\"\n      }\n    },\n    \"sources\": {\n      \"type\": \"object\",\n      \"description\": \"The sources defined in the dbt project and its dependencies\",\n      \"additionalProperties\": {\n        \"type\": \"object\",\n        \"title\": \"SourceDefinition\",\n        \"properties\": {\n          \"database\": {\n            \"anyOf\": [\n              {\n                \"type\": \"string\"\n              },\n              {\n                \"type\": \"null\"\n              }\n            ]\n          },\n          \"schema\": {\n            \"type\": \"string\"\n          },\n          \"name\": {\n            \"type\": \"string\"\n          },\n          \"resource_type\": {\n            \"const\": \"source\"\n          },\n          \"package_name\": {\n            \"type\": \"string\"\n          },\n          \"path\": {\n            \"type\": \"string\"\n          },\n          \"original_file_path\": {\n            \"type\": \"string\"\n          },\n          \"unique_id\": {\n            \"type\": \"string\"\n          },\n          \"fqn\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"source_name\": {\n            \"type\": \"string\"\n          },\n          \"source_description\": {\n            \"type\": \"string\"\n          },\n          \"loader\": {\n            \"type\": \"string\"\n          },\n          \"identifier\": {\n            \"type\": \"string\"\n          },\n          \"quoting\": {\n            \"type\": \"object\",\n            \"title\": \"Quoting\",\n            \"properties\": {\n              \"database\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"boolean\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"schema\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"boolean\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"identifier\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"boolean\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"column\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"boolean\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              }\n            },\n            \"additionalProperties\": false\n          },\n          \"loaded_at_field\": {\n            \"anyOf\": [\n              {\n                \"type\": \"string\"\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          },\n          \"loaded_at_query\": {\n            \"anyOf\": [\n              {\n                \"type\": \"string\"\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          },\n          \"freshness\": {\n            \"anyOf\": [\n              {\n                \"type\": \"object\",\n                \"title\": \"FreshnessThreshold\",\n                \"properties\": {\n                  \"warn_after\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"object\",\n                        \"title\": \"Time\",\n                        \"properties\": {\n                          \"count\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"integer\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"period\": {\n                            \"anyOf\": [\n                              {\n                                \"enum\": [\n                                  \"minute\",\n                                  \"hour\",\n                                  \"day\"\n                                ]\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          }\n                        },\n                        \"additionalProperties\": false\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ]\n                  },\n                  \"error_after\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"object\",\n                        \"title\": \"Time\",\n                        \"properties\": {\n                          \"count\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"integer\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"period\": {\n                            \"anyOf\": [\n                              {\n                                \"enum\": [\n                                  \"minute\",\n                                  \"hour\",\n                                  \"day\"\n                                ]\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          }\n                        },\n                        \"additionalProperties\": false\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ]\n                  },\n                  \"filter\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  }\n                },\n                \"additionalProperties\": false\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          },\n          \"external\": {\n            \"anyOf\": [\n              {\n                \"type\": \"object\",\n                \"title\": \"ExternalTable\",\n                \"properties\": {\n                  \"_extra\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"location\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"file_format\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"row_format\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"tbl_properties\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"partitions\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      },\n                      {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"object\",\n                          \"title\": \"ExternalPartition\",\n                          \"properties\": {\n                            \"_extra\": {\n                              \"type\": \"object\",\n                              \"propertyNames\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            \"name\": {\n                              \"type\": \"string\",\n                              \"default\": \"\"\n                            },\n                            \"description\": {\n                              \"type\": \"string\",\n                              \"default\": \"\"\n                            },\n                            \"data_type\": {\n                              \"type\": \"string\",\n                              \"default\": \"\"\n                            },\n                            \"meta\": {\n                              \"type\": \"object\",\n                              \"propertyNames\": {\n                                \"type\": \"string\"\n                              }\n                            }\n                          },\n                          \"additionalProperties\": true\n                        }\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  }\n                },\n                \"additionalProperties\": true\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          },\n          \"description\": {\n            \"type\": \"string\",\n            \"default\": \"\"\n          },\n          \"columns\": {\n            \"type\": \"object\",\n            \"additionalProperties\": {\n              \"type\": \"object\",\n              \"title\": \"ColumnInfo\",\n              \"properties\": {\n                \"name\": {\n                  \"type\": \"string\"\n                },\n                \"description\": {\n                  \"type\": \"string\",\n                  \"default\": \"\"\n                },\n                \"meta\": {\n                  \"type\": \"object\",\n                  \"propertyNames\": {\n                    \"type\": \"string\"\n                  }\n                },\n                \"data_type\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"string\"\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                },\n                \"constraints\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"object\",\n                    \"title\": \"ColumnLevelConstraint\",\n                    \"properties\": {\n                      \"type\": {\n                        \"enum\": [\n                          \"check\",\n                          \"not_null\",\n                          \"unique\",\n                          \"primary_key\",\n                          \"foreign_key\",\n                          \"custom\"\n                        ]\n                      },\n                      \"name\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"string\"\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ],\n                        \"default\": null\n                      },\n                      \"expression\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"string\"\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ],\n                        \"default\": null\n                      },\n                      \"warn_unenforced\": {\n                        \"type\": \"boolean\",\n                        \"default\": true\n                      },\n                      \"warn_unsupported\": {\n                        \"type\": \"boolean\",\n                        \"default\": true\n                      },\n                      \"to\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"string\"\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ],\n                        \"default\": null\n                      },\n                      \"to_columns\": {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      }\n                    },\n                    \"additionalProperties\": false,\n                    \"required\": [\n                      \"type\"\n                    ]\n                  }\n                },\n                \"quote\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"boolean\"\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                },\n                \"config\": {\n                  \"type\": \"object\",\n                  \"title\": \"ColumnConfig\",\n                  \"properties\": {\n                    \"_extra\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"meta\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"tags\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    }\n                  },\n                  \"additionalProperties\": true\n                },\n                \"tags\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"string\"\n                  }\n                },\n                \"_extra\": {\n                  \"type\": \"object\",\n                  \"propertyNames\": {\n                    \"type\": \"string\"\n                  }\n                },\n                \"granularity\": {\n                  \"anyOf\": [\n                    {\n                      \"enum\": [\n                        \"nanosecond\",\n                        \"microsecond\",\n                        \"millisecond\",\n                        \"second\",\n                        \"minute\",\n                        \"hour\",\n                        \"day\",\n                        \"week\",\n                        \"month\",\n                        \"quarter\",\n                        \"year\"\n                      ]\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                },\n                \"dimension\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"object\",\n                      \"title\": \"ColumnDimension\",\n                      \"properties\": {\n                        \"name\": {\n                          \"type\": \"string\"\n                        },\n                        \"type\": {\n                          \"enum\": [\n                            \"categorical\",\n                            \"time\"\n                          ]\n                        },\n                        \"description\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"label\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"is_partition\": {\n                          \"type\": \"boolean\",\n                          \"default\": false\n                        },\n                        \"config\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"validity_params\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"object\",\n                              \"title\": \"ColumnDimensionValidityParams\",\n                              \"properties\": {\n                                \"is_start\": {\n                                  \"type\": \"boolean\",\n                                  \"default\": false\n                                },\n                                \"is_end\": {\n                                  \"type\": \"boolean\",\n                                  \"default\": false\n                                }\n                              },\n                              \"additionalProperties\": false\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": false,\n                      \"required\": [\n                        \"name\",\n                        \"type\"\n                      ]\n                    },\n                    {\n                      \"enum\": [\n                        \"categorical\",\n                        \"time\"\n                      ]\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                },\n                \"entity\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"object\",\n                      \"title\": \"ColumnEntity\",\n                      \"properties\": {\n                        \"name\": {\n                          \"type\": \"string\"\n                        },\n                        \"type\": {\n                          \"enum\": [\n                            \"foreign\",\n                            \"natural\",\n                            \"primary\",\n                            \"unique\"\n                          ]\n                        },\n                        \"description\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"label\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"config\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      },\n                      \"additionalProperties\": false,\n                      \"required\": [\n                        \"name\",\n                        \"type\"\n                      ]\n                    },\n                    {\n                      \"enum\": [\n                        \"foreign\",\n                        \"natural\",\n                        \"primary\",\n                        \"unique\"\n                      ]\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                },\n                \"doc_blocks\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"string\"\n                  }\n                }\n              },\n              \"additionalProperties\": true,\n              \"required\": [\n                \"name\"\n              ]\n            },\n            \"propertyNames\": {\n              \"type\": \"string\"\n            }\n          },\n          \"meta\": {\n            \"type\": \"object\",\n            \"propertyNames\": {\n              \"type\": \"string\"\n            }\n          },\n          \"source_meta\": {\n            \"type\": \"object\",\n            \"propertyNames\": {\n              \"type\": \"string\"\n            }\n          },\n          \"tags\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"config\": {\n            \"type\": \"object\",\n            \"title\": \"SourceConfig\",\n            \"properties\": {\n              \"_extra\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"enabled\": {\n                \"type\": \"boolean\",\n                \"default\": true\n              },\n              \"event_time\": {\n                \"default\": null\n              },\n              \"freshness\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"object\",\n                    \"title\": \"FreshnessThreshold\",\n                    \"properties\": {\n                      \"warn_after\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"object\",\n                            \"title\": \"Time\",\n                            \"properties\": {\n                              \"count\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"integer\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"period\": {\n                                \"anyOf\": [\n                                  {\n                                    \"enum\": [\n                                      \"minute\",\n                                      \"hour\",\n                                      \"day\"\n                                    ]\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              }\n                            },\n                            \"additionalProperties\": false\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ]\n                      },\n                      \"error_after\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"object\",\n                            \"title\": \"Time\",\n                            \"properties\": {\n                              \"count\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"integer\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"period\": {\n                                \"anyOf\": [\n                                  {\n                                    \"enum\": [\n                                      \"minute\",\n                                      \"hour\",\n                                      \"day\"\n                                    ]\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              }\n                            },\n                            \"additionalProperties\": false\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ]\n                      },\n                      \"filter\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"string\"\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ],\n                        \"default\": null\n                      }\n                    },\n                    \"additionalProperties\": false\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ]\n              },\n              \"loaded_at_field\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"loaded_at_query\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"meta\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"tags\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              }\n            },\n            \"additionalProperties\": true\n          },\n          \"patch_path\": {\n            \"anyOf\": [\n              {\n                \"type\": \"string\"\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          },\n          \"unrendered_config\": {\n            \"type\": \"object\",\n            \"propertyNames\": {\n              \"type\": \"string\"\n            }\n          },\n          \"relation_name\": {\n            \"anyOf\": [\n              {\n                \"type\": \"string\"\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          },\n          \"created_at\": {\n            \"type\": \"number\"\n          },\n          \"unrendered_database\": {\n            \"anyOf\": [\n              {\n                \"type\": \"string\"\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          },\n          \"unrendered_schema\": {\n            \"anyOf\": [\n              {\n                \"type\": \"string\"\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          },\n          \"doc_blocks\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          }\n        },\n        \"additionalProperties\": false,\n        \"required\": [\n          \"database\",\n          \"schema\",\n          \"name\",\n          \"resource_type\",\n          \"package_name\",\n          \"path\",\n          \"original_file_path\",\n          \"unique_id\",\n          \"fqn\",\n          \"source_name\",\n          \"source_description\",\n          \"loader\",\n          \"identifier\"\n        ]\n      },\n      \"propertyNames\": {\n        \"type\": \"string\"\n      }\n    },\n    \"macros\": {\n      \"type\": \"object\",\n      \"description\": \"The macros defined in the dbt project and its dependencies\",\n      \"additionalProperties\": {\n        \"type\": \"object\",\n        \"title\": \"Macro\",\n        \"properties\": {\n          \"name\": {\n            \"type\": \"string\"\n          },\n          \"resource_type\": {\n            \"const\": \"macro\"\n          },\n          \"package_name\": {\n            \"type\": \"string\"\n          },\n          \"path\": {\n            \"type\": \"string\"\n          },\n          \"original_file_path\": {\n            \"type\": \"string\"\n          },\n          \"unique_id\": {\n            \"type\": \"string\"\n          },\n          \"macro_sql\": {\n            \"type\": \"string\"\n          },\n          \"depends_on\": {\n            \"type\": \"object\",\n            \"title\": \"MacroDependsOn\",\n            \"properties\": {\n              \"macros\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              }\n            },\n            \"additionalProperties\": false\n          },\n          \"description\": {\n            \"type\": \"string\",\n            \"default\": \"\"\n          },\n          \"meta\": {\n            \"type\": \"object\",\n            \"propertyNames\": {\n              \"type\": \"string\"\n            }\n          },\n          \"docs\": {\n            \"type\": \"object\",\n            \"title\": \"Docs\",\n            \"properties\": {\n              \"show\": {\n                \"type\": \"boolean\",\n                \"default\": true\n              },\n              \"node_color\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              }\n            },\n            \"additionalProperties\": false\n          },\n          \"config\": {\n            \"type\": \"object\",\n            \"title\": \"MacroConfig\",\n            \"properties\": {\n              \"_extra\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"meta\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"docs\": {\n                \"type\": \"object\",\n                \"title\": \"Docs\",\n                \"properties\": {\n                  \"show\": {\n                    \"type\": \"boolean\",\n                    \"default\": true\n                  },\n                  \"node_color\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  }\n                },\n                \"additionalProperties\": false\n              }\n            },\n            \"additionalProperties\": true\n          },\n          \"patch_path\": {\n            \"anyOf\": [\n              {\n                \"type\": \"string\"\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          },\n          \"arguments\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"object\",\n              \"title\": \"MacroArgument\",\n              \"properties\": {\n                \"name\": {\n                  \"type\": \"string\"\n                },\n                \"type\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"string\"\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                },\n                \"description\": {\n                  \"type\": \"string\",\n                  \"default\": \"\"\n                }\n              },\n              \"additionalProperties\": false,\n              \"required\": [\n                \"name\"\n              ]\n            }\n          },\n          \"created_at\": {\n            \"type\": \"number\"\n          },\n          \"supported_languages\": {\n            \"anyOf\": [\n              {\n                \"type\": \"array\",\n                \"items\": {\n                  \"enum\": [\n                    \"python\",\n                    \"sql\"\n                  ]\n                }\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          }\n        },\n        \"additionalProperties\": false,\n        \"required\": [\n          \"name\",\n          \"resource_type\",\n          \"package_name\",\n          \"path\",\n          \"original_file_path\",\n          \"unique_id\",\n          \"macro_sql\"\n        ]\n      },\n      \"propertyNames\": {\n        \"type\": \"string\"\n      }\n    },\n    \"docs\": {\n      \"type\": \"object\",\n      \"description\": \"The docs defined in the dbt project and its dependencies\",\n      \"additionalProperties\": {\n        \"type\": \"object\",\n        \"title\": \"Documentation\",\n        \"properties\": {\n          \"name\": {\n            \"type\": \"string\"\n          },\n          \"resource_type\": {\n            \"const\": \"doc\"\n          },\n          \"package_name\": {\n            \"type\": \"string\"\n          },\n          \"path\": {\n            \"type\": \"string\"\n          },\n          \"original_file_path\": {\n            \"type\": \"string\"\n          },\n          \"unique_id\": {\n            \"type\": \"string\"\n          },\n          \"block_contents\": {\n            \"type\": \"string\"\n          }\n        },\n        \"additionalProperties\": false,\n        \"required\": [\n          \"name\",\n          \"resource_type\",\n          \"package_name\",\n          \"path\",\n          \"original_file_path\",\n          \"unique_id\",\n          \"block_contents\"\n        ]\n      },\n      \"propertyNames\": {\n        \"type\": \"string\"\n      }\n    },\n    \"exposures\": {\n      \"type\": \"object\",\n      \"description\": \"The exposures defined in the dbt project and its dependencies\",\n      \"additionalProperties\": {\n        \"type\": \"object\",\n        \"title\": \"Exposure\",\n        \"properties\": {\n          \"name\": {\n            \"type\": \"string\"\n          },\n          \"resource_type\": {\n            \"const\": \"exposure\"\n          },\n          \"package_name\": {\n            \"type\": \"string\"\n          },\n          \"path\": {\n            \"type\": \"string\"\n          },\n          \"original_file_path\": {\n            \"type\": \"string\"\n          },\n          \"unique_id\": {\n            \"type\": \"string\"\n          },\n          \"fqn\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"type\": {\n            \"enum\": [\n              \"dashboard\",\n              \"notebook\",\n              \"analysis\",\n              \"ml\",\n              \"application\"\n            ]\n          },\n          \"owner\": {\n            \"type\": \"object\",\n            \"title\": \"Owner\",\n            \"properties\": {\n              \"_extra\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"email\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"name\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              }\n            },\n            \"additionalProperties\": true\n          },\n          \"description\": {\n            \"type\": \"string\",\n            \"default\": \"\"\n          },\n          \"label\": {\n            \"anyOf\": [\n              {\n                \"type\": \"string\"\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          },\n          \"maturity\": {\n            \"anyOf\": [\n              {\n                \"enum\": [\n                  \"low\",\n                  \"medium\",\n                  \"high\"\n                ]\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          },\n          \"meta\": {\n            \"type\": \"object\",\n            \"propertyNames\": {\n              \"type\": \"string\"\n            }\n          },\n          \"tags\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"config\": {\n            \"type\": \"object\",\n            \"title\": \"ExposureConfig\",\n            \"properties\": {\n              \"_extra\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"enabled\": {\n                \"type\": \"boolean\",\n                \"default\": true\n              },\n              \"tags\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"meta\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              }\n            },\n            \"additionalProperties\": true\n          },\n          \"unrendered_config\": {\n            \"type\": \"object\",\n            \"propertyNames\": {\n              \"type\": \"string\"\n            }\n          },\n          \"url\": {\n            \"anyOf\": [\n              {\n                \"type\": \"string\"\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          },\n          \"depends_on\": {\n            \"type\": \"object\",\n            \"title\": \"DependsOn\",\n            \"properties\": {\n              \"macros\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"nodes\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              }\n            },\n            \"additionalProperties\": false\n          },\n          \"refs\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"object\",\n              \"title\": \"RefArgs\",\n              \"properties\": {\n                \"name\": {\n                  \"type\": \"string\"\n                },\n                \"package\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"string\"\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                },\n                \"version\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"string\"\n                    },\n                    {\n                      \"type\": \"number\"\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                }\n              },\n              \"additionalProperties\": false,\n              \"required\": [\n                \"name\"\n              ]\n            }\n          },\n          \"sources\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            }\n          },\n          \"metrics\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            }\n          },\n          \"created_at\": {\n            \"type\": \"number\"\n          }\n        },\n        \"additionalProperties\": false,\n        \"required\": [\n          \"name\",\n          \"resource_type\",\n          \"package_name\",\n          \"path\",\n          \"original_file_path\",\n          \"unique_id\",\n          \"fqn\",\n          \"type\",\n          \"owner\"\n        ]\n      },\n      \"propertyNames\": {\n        \"type\": \"string\"\n      }\n    },\n    \"metrics\": {\n      \"type\": \"object\",\n      \"description\": \"The metrics defined in the dbt project and its dependencies\",\n      \"additionalProperties\": {\n        \"type\": \"object\",\n        \"title\": \"Metric\",\n        \"properties\": {\n          \"name\": {\n            \"type\": \"string\"\n          },\n          \"resource_type\": {\n            \"const\": \"metric\"\n          },\n          \"package_name\": {\n            \"type\": \"string\"\n          },\n          \"path\": {\n            \"type\": \"string\"\n          },\n          \"original_file_path\": {\n            \"type\": \"string\"\n          },\n          \"unique_id\": {\n            \"type\": \"string\"\n          },\n          \"fqn\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"description\": {\n            \"type\": \"string\"\n          },\n          \"label\": {\n            \"type\": \"string\"\n          },\n          \"type\": {\n            \"enum\": [\n              \"simple\",\n              \"ratio\",\n              \"cumulative\",\n              \"derived\",\n              \"conversion\"\n            ]\n          },\n          \"type_params\": {\n            \"type\": \"object\",\n            \"title\": \"MetricTypeParams\",\n            \"properties\": {\n              \"measure\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"object\",\n                    \"title\": \"MetricInputMeasure\",\n                    \"properties\": {\n                      \"name\": {\n                        \"type\": \"string\"\n                      },\n                      \"filter\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"object\",\n                            \"title\": \"WhereFilterIntersection\",\n                            \"properties\": {\n                              \"where_filters\": {\n                                \"type\": \"array\",\n                                \"items\": {\n                                  \"type\": \"object\",\n                                  \"title\": \"WhereFilter\",\n                                  \"properties\": {\n                                    \"where_sql_template\": {\n                                      \"type\": \"string\"\n                                    }\n                                  },\n                                  \"additionalProperties\": false,\n                                  \"required\": [\n                                    \"where_sql_template\"\n                                  ]\n                                }\n                              }\n                            },\n                            \"additionalProperties\": false,\n                            \"required\": [\n                              \"where_filters\"\n                            ]\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ],\n                        \"default\": null\n                      },\n                      \"alias\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"string\"\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ],\n                        \"default\": null\n                      },\n                      \"join_to_timespine\": {\n                        \"type\": \"boolean\",\n                        \"default\": false\n                      },\n                      \"fill_nulls_with\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"integer\"\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ],\n                        \"default\": null\n                      }\n                    },\n                    \"additionalProperties\": false,\n                    \"required\": [\n                      \"name\"\n                    ]\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"input_measures\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"object\",\n                  \"title\": \"MetricInputMeasure\",\n                  \"properties\": {\n                    \"name\": {\n                      \"type\": \"string\"\n                    },\n                    \"filter\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"object\",\n                          \"title\": \"WhereFilterIntersection\",\n                          \"properties\": {\n                            \"where_filters\": {\n                              \"type\": \"array\",\n                              \"items\": {\n                                \"type\": \"object\",\n                                \"title\": \"WhereFilter\",\n                                \"properties\": {\n                                  \"where_sql_template\": {\n                                    \"type\": \"string\"\n                                  }\n                                },\n                                \"additionalProperties\": false,\n                                \"required\": [\n                                  \"where_sql_template\"\n                                ]\n                              }\n                            }\n                          },\n                          \"additionalProperties\": false,\n                          \"required\": [\n                            \"where_filters\"\n                          ]\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"alias\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"join_to_timespine\": {\n                      \"type\": \"boolean\",\n                      \"default\": false\n                    },\n                    \"fill_nulls_with\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"integer\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    }\n                  },\n                  \"additionalProperties\": false,\n                  \"required\": [\n                    \"name\"\n                  ]\n                }\n              },\n              \"numerator\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"object\",\n                    \"title\": \"MetricInput\",\n                    \"properties\": {\n                      \"name\": {\n                        \"type\": \"string\"\n                      },\n                      \"filter\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"object\",\n                            \"title\": \"WhereFilterIntersection\",\n                            \"properties\": {\n                              \"where_filters\": {\n                                \"type\": \"array\",\n                                \"items\": {\n                                  \"type\": \"object\",\n                                  \"title\": \"WhereFilter\",\n                                  \"properties\": {\n                                    \"where_sql_template\": {\n                                      \"type\": \"string\"\n                                    }\n                                  },\n                                  \"additionalProperties\": false,\n                                  \"required\": [\n                                    \"where_sql_template\"\n                                  ]\n                                }\n                              }\n                            },\n                            \"additionalProperties\": false,\n                            \"required\": [\n                              \"where_filters\"\n                            ]\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ],\n                        \"default\": null\n                      },\n                      \"alias\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"string\"\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ],\n                        \"default\": null\n                      },\n                      \"offset_window\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"object\",\n                            \"title\": \"MetricTimeWindow\",\n                            \"properties\": {\n                              \"count\": {\n                                \"type\": \"integer\"\n                              },\n                              \"granularity\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            \"additionalProperties\": false,\n                            \"required\": [\n                              \"count\",\n                              \"granularity\"\n                            ]\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ],\n                        \"default\": null\n                      },\n                      \"offset_to_grain\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"string\"\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ],\n                        \"default\": null\n                      }\n                    },\n                    \"additionalProperties\": false,\n                    \"required\": [\n                      \"name\"\n                    ]\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"denominator\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"object\",\n                    \"title\": \"MetricInput\",\n                    \"properties\": {\n                      \"name\": {\n                        \"type\": \"string\"\n                      },\n                      \"filter\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"object\",\n                            \"title\": \"WhereFilterIntersection\",\n                            \"properties\": {\n                              \"where_filters\": {\n                                \"type\": \"array\",\n                                \"items\": {\n                                  \"type\": \"object\",\n                                  \"title\": \"WhereFilter\",\n                                  \"properties\": {\n                                    \"where_sql_template\": {\n                                      \"type\": \"string\"\n                                    }\n                                  },\n                                  \"additionalProperties\": false,\n                                  \"required\": [\n                                    \"where_sql_template\"\n                                  ]\n                                }\n                              }\n                            },\n                            \"additionalProperties\": false,\n                            \"required\": [\n                              \"where_filters\"\n                            ]\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ],\n                        \"default\": null\n                      },\n                      \"alias\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"string\"\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ],\n                        \"default\": null\n                      },\n                      \"offset_window\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"object\",\n                            \"title\": \"MetricTimeWindow\",\n                            \"properties\": {\n                              \"count\": {\n                                \"type\": \"integer\"\n                              },\n                              \"granularity\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            \"additionalProperties\": false,\n                            \"required\": [\n                              \"count\",\n                              \"granularity\"\n                            ]\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ],\n                        \"default\": null\n                      },\n                      \"offset_to_grain\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"string\"\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ],\n                        \"default\": null\n                      }\n                    },\n                    \"additionalProperties\": false,\n                    \"required\": [\n                      \"name\"\n                    ]\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"expr\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"window\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"object\",\n                    \"title\": \"MetricTimeWindow\",\n                    \"properties\": {\n                      \"count\": {\n                        \"type\": \"integer\"\n                      },\n                      \"granularity\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"additionalProperties\": false,\n                    \"required\": [\n                      \"count\",\n                      \"granularity\"\n                    ]\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"grain_to_date\": {\n                \"anyOf\": [\n                  {\n                    \"enum\": [\n                      \"nanosecond\",\n                      \"microsecond\",\n                      \"millisecond\",\n                      \"second\",\n                      \"minute\",\n                      \"hour\",\n                      \"day\",\n                      \"week\",\n                      \"month\",\n                      \"quarter\",\n                      \"year\"\n                    ]\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"metrics\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"title\": \"MetricInput\",\n                      \"properties\": {\n                        \"name\": {\n                          \"type\": \"string\"\n                        },\n                        \"filter\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"object\",\n                              \"title\": \"WhereFilterIntersection\",\n                              \"properties\": {\n                                \"where_filters\": {\n                                  \"type\": \"array\",\n                                  \"items\": {\n                                    \"type\": \"object\",\n                                    \"title\": \"WhereFilter\",\n                                    \"properties\": {\n                                      \"where_sql_template\": {\n                                        \"type\": \"string\"\n                                      }\n                                    },\n                                    \"additionalProperties\": false,\n                                    \"required\": [\n                                      \"where_sql_template\"\n                                    ]\n                                  }\n                                }\n                              },\n                              \"additionalProperties\": false,\n                              \"required\": [\n                                \"where_filters\"\n                              ]\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"alias\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"offset_window\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"object\",\n                              \"title\": \"MetricTimeWindow\",\n                              \"properties\": {\n                                \"count\": {\n                                  \"type\": \"integer\"\n                                },\n                                \"granularity\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"additionalProperties\": false,\n                              \"required\": [\n                                \"count\",\n                                \"granularity\"\n                              ]\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"offset_to_grain\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": false,\n                      \"required\": [\n                        \"name\"\n                      ]\n                    }\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"conversion_type_params\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"object\",\n                    \"title\": \"ConversionTypeParams\",\n                    \"properties\": {\n                      \"entity\": {\n                        \"type\": \"string\"\n                      },\n                      \"base_measure\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"object\",\n                            \"title\": \"MetricInputMeasure\",\n                            \"properties\": {\n                              \"name\": {\n                                \"type\": \"string\"\n                              },\n                              \"filter\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"object\",\n                                    \"title\": \"WhereFilterIntersection\",\n                                    \"properties\": {\n                                      \"where_filters\": {\n                                        \"type\": \"array\",\n                                        \"items\": {\n                                          \"type\": \"object\",\n                                          \"title\": \"WhereFilter\",\n                                          \"properties\": {\n                                            \"where_sql_template\": {\n                                              \"type\": \"string\"\n                                            }\n                                          },\n                                          \"additionalProperties\": false,\n                                          \"required\": [\n                                            \"where_sql_template\"\n                                          ]\n                                        }\n                                      }\n                                    },\n                                    \"additionalProperties\": false,\n                                    \"required\": [\n                                      \"where_filters\"\n                                    ]\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"alias\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"string\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"join_to_timespine\": {\n                                \"type\": \"boolean\",\n                                \"default\": false\n                              },\n                              \"fill_nulls_with\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"integer\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              }\n                            },\n                            \"additionalProperties\": false,\n                            \"required\": [\n                              \"name\"\n                            ]\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ],\n                        \"default\": null\n                      },\n                      \"conversion_measure\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"object\",\n                            \"title\": \"MetricInputMeasure\",\n                            \"properties\": {\n                              \"name\": {\n                                \"type\": \"string\"\n                              },\n                              \"filter\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"object\",\n                                    \"title\": \"WhereFilterIntersection\",\n                                    \"properties\": {\n                                      \"where_filters\": {\n                                        \"type\": \"array\",\n                                        \"items\": {\n                                          \"type\": \"object\",\n                                          \"title\": \"WhereFilter\",\n                                          \"properties\": {\n                                            \"where_sql_template\": {\n                                              \"type\": \"string\"\n                                            }\n                                          },\n                                          \"additionalProperties\": false,\n                                          \"required\": [\n                                            \"where_sql_template\"\n                                          ]\n                                        }\n                                      }\n                                    },\n                                    \"additionalProperties\": false,\n                                    \"required\": [\n                                      \"where_filters\"\n                                    ]\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"alias\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"string\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"join_to_timespine\": {\n                                \"type\": \"boolean\",\n                                \"default\": false\n                              },\n                              \"fill_nulls_with\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"integer\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              }\n                            },\n                            \"additionalProperties\": false,\n                            \"required\": [\n                              \"name\"\n                            ]\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ],\n                        \"default\": null\n                      },\n                      \"base_metric\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"object\",\n                            \"title\": \"MetricInput\",\n                            \"properties\": {\n                              \"name\": {\n                                \"type\": \"string\"\n                              },\n                              \"filter\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"object\",\n                                    \"title\": \"WhereFilterIntersection\",\n                                    \"properties\": {\n                                      \"where_filters\": {\n                                        \"type\": \"array\",\n                                        \"items\": {\n                                          \"type\": \"object\",\n                                          \"title\": \"WhereFilter\",\n                                          \"properties\": {\n                                            \"where_sql_template\": {\n                                              \"type\": \"string\"\n                                            }\n                                          },\n                                          \"additionalProperties\": false,\n                                          \"required\": [\n                                            \"where_sql_template\"\n                                          ]\n                                        }\n                                      }\n                                    },\n                                    \"additionalProperties\": false,\n                                    \"required\": [\n                                      \"where_filters\"\n                                    ]\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"alias\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"string\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"offset_window\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"object\",\n                                    \"title\": \"MetricTimeWindow\",\n                                    \"properties\": {\n                                      \"count\": {\n                                        \"type\": \"integer\"\n                                      },\n                                      \"granularity\": {\n                                        \"type\": \"string\"\n                                      }\n                                    },\n                                    \"additionalProperties\": false,\n                                    \"required\": [\n                                      \"count\",\n                                      \"granularity\"\n                                    ]\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"offset_to_grain\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"string\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              }\n                            },\n                            \"additionalProperties\": false,\n                            \"required\": [\n                              \"name\"\n                            ]\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ],\n                        \"default\": null\n                      },\n                      \"conversion_metric\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"object\",\n                            \"title\": \"MetricInput\",\n                            \"properties\": {\n                              \"name\": {\n                                \"type\": \"string\"\n                              },\n                              \"filter\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"object\",\n                                    \"title\": \"WhereFilterIntersection\",\n                                    \"properties\": {\n                                      \"where_filters\": {\n                                        \"type\": \"array\",\n                                        \"items\": {\n                                          \"type\": \"object\",\n                                          \"title\": \"WhereFilter\",\n                                          \"properties\": {\n                                            \"where_sql_template\": {\n                                              \"type\": \"string\"\n                                            }\n                                          },\n                                          \"additionalProperties\": false,\n                                          \"required\": [\n                                            \"where_sql_template\"\n                                          ]\n                                        }\n                                      }\n                                    },\n                                    \"additionalProperties\": false,\n                                    \"required\": [\n                                      \"where_filters\"\n                                    ]\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"alias\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"string\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"offset_window\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"object\",\n                                    \"title\": \"MetricTimeWindow\",\n                                    \"properties\": {\n                                      \"count\": {\n                                        \"type\": \"integer\"\n                                      },\n                                      \"granularity\": {\n                                        \"type\": \"string\"\n                                      }\n                                    },\n                                    \"additionalProperties\": false,\n                                    \"required\": [\n                                      \"count\",\n                                      \"granularity\"\n                                    ]\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"offset_to_grain\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"string\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              }\n                            },\n                            \"additionalProperties\": false,\n                            \"required\": [\n                              \"name\"\n                            ]\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ],\n                        \"default\": null\n                      },\n                      \"calculation\": {\n                        \"enum\": [\n                          \"conversions\",\n                          \"conversion_rate\"\n                        ],\n                        \"default\": \"conversion_rate\"\n                      },\n                      \"window\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"object\",\n                            \"title\": \"MetricTimeWindow\",\n                            \"properties\": {\n                              \"count\": {\n                                \"type\": \"integer\"\n                              },\n                              \"granularity\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            \"additionalProperties\": false,\n                            \"required\": [\n                              \"count\",\n                              \"granularity\"\n                            ]\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ],\n                        \"default\": null\n                      },\n                      \"constant_properties\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"object\",\n                              \"title\": \"ConstantPropertyInput\",\n                              \"properties\": {\n                                \"base_property\": {\n                                  \"type\": \"string\"\n                                },\n                                \"conversion_property\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"additionalProperties\": false,\n                              \"required\": [\n                                \"base_property\",\n                                \"conversion_property\"\n                              ]\n                            }\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ],\n                        \"default\": null\n                      }\n                    },\n                    \"additionalProperties\": false,\n                    \"required\": [\n                      \"entity\"\n                    ]\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"cumulative_type_params\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"object\",\n                    \"title\": \"CumulativeTypeParams\",\n                    \"properties\": {\n                      \"window\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"object\",\n                            \"title\": \"MetricTimeWindow\",\n                            \"properties\": {\n                              \"count\": {\n                                \"type\": \"integer\"\n                              },\n                              \"granularity\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            \"additionalProperties\": false,\n                            \"required\": [\n                              \"count\",\n                              \"granularity\"\n                            ]\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ],\n                        \"default\": null\n                      },\n                      \"grain_to_date\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"string\"\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ],\n                        \"default\": null\n                      },\n                      \"period_agg\": {\n                        \"enum\": [\n                          \"first\",\n                          \"last\",\n                          \"average\"\n                        ],\n                        \"default\": \"first\"\n                      },\n                      \"metric\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"object\",\n                            \"title\": \"MetricInput\",\n                            \"properties\": {\n                              \"name\": {\n                                \"type\": \"string\"\n                              },\n                              \"filter\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"object\",\n                                    \"title\": \"WhereFilterIntersection\",\n                                    \"properties\": {\n                                      \"where_filters\": {\n                                        \"type\": \"array\",\n                                        \"items\": {\n                                          \"type\": \"object\",\n                                          \"title\": \"WhereFilter\",\n                                          \"properties\": {\n                                            \"where_sql_template\": {\n                                              \"type\": \"string\"\n                                            }\n                                          },\n                                          \"additionalProperties\": false,\n                                          \"required\": [\n                                            \"where_sql_template\"\n                                          ]\n                                        }\n                                      }\n                                    },\n                                    \"additionalProperties\": false,\n                                    \"required\": [\n                                      \"where_filters\"\n                                    ]\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"alias\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"string\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"offset_window\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"object\",\n                                    \"title\": \"MetricTimeWindow\",\n                                    \"properties\": {\n                                      \"count\": {\n                                        \"type\": \"integer\"\n                                      },\n                                      \"granularity\": {\n                                        \"type\": \"string\"\n                                      }\n                                    },\n                                    \"additionalProperties\": false,\n                                    \"required\": [\n                                      \"count\",\n                                      \"granularity\"\n                                    ]\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"offset_to_grain\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"string\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              }\n                            },\n                            \"additionalProperties\": false,\n                            \"required\": [\n                              \"name\"\n                            ]\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ],\n                        \"default\": null\n                      }\n                    },\n                    \"additionalProperties\": false\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"metric_aggregation_params\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"object\",\n                    \"title\": \"MetricAggregationParams\",\n                    \"properties\": {\n                      \"semantic_model\": {\n                        \"type\": \"string\"\n                      },\n                      \"agg\": {\n                        \"enum\": [\n                          \"sum\",\n                          \"min\",\n                          \"max\",\n                          \"count_distinct\",\n                          \"sum_boolean\",\n                          \"average\",\n                          \"percentile\",\n                          \"median\",\n                          \"count\"\n                        ]\n                      },\n                      \"agg_params\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"object\",\n                            \"title\": \"MeasureAggregationParameters\",\n                            \"properties\": {\n                              \"percentile\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"number\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"use_discrete_percentile\": {\n                                \"type\": \"boolean\",\n                                \"default\": false\n                              },\n                              \"use_approximate_percentile\": {\n                                \"type\": \"boolean\",\n                                \"default\": false\n                              }\n                            },\n                            \"additionalProperties\": false\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ],\n                        \"default\": null\n                      },\n                      \"agg_time_dimension\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"string\"\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ],\n                        \"default\": null\n                      },\n                      \"non_additive_dimension\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"object\",\n                            \"title\": \"NonAdditiveDimension\",\n                            \"properties\": {\n                              \"name\": {\n                                \"type\": \"string\"\n                              },\n                              \"window_choice\": {\n                                \"enum\": [\n                                  \"sum\",\n                                  \"min\",\n                                  \"max\",\n                                  \"count_distinct\",\n                                  \"sum_boolean\",\n                                  \"average\",\n                                  \"percentile\",\n                                  \"median\",\n                                  \"count\"\n                                ]\n                              },\n                              \"window_groupings\": {\n                                \"type\": \"array\",\n                                \"items\": {\n                                  \"type\": \"string\"\n                                }\n                              }\n                            },\n                            \"additionalProperties\": false,\n                            \"required\": [\n                              \"name\",\n                              \"window_choice\",\n                              \"window_groupings\"\n                            ]\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ],\n                        \"default\": null\n                      }\n                    },\n                    \"additionalProperties\": false,\n                    \"required\": [\n                      \"semantic_model\",\n                      \"agg\"\n                    ]\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"fill_nulls_with\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"integer\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"join_to_timespine\": {\n                \"type\": \"boolean\",\n                \"default\": false\n              },\n              \"is_private\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"boolean\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              }\n            },\n            \"additionalProperties\": false\n          },\n          \"filter\": {\n            \"anyOf\": [\n              {\n                \"type\": \"object\",\n                \"title\": \"WhereFilterIntersection\",\n                \"properties\": {\n                  \"where_filters\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"title\": \"WhereFilter\",\n                      \"properties\": {\n                        \"where_sql_template\": {\n                          \"type\": \"string\"\n                        }\n                      },\n                      \"additionalProperties\": false,\n                      \"required\": [\n                        \"where_sql_template\"\n                      ]\n                    }\n                  }\n                },\n                \"additionalProperties\": false,\n                \"required\": [\n                  \"where_filters\"\n                ]\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          },\n          \"metadata\": {\n            \"anyOf\": [\n              {\n                \"type\": \"object\",\n                \"title\": \"SourceFileMetadata\",\n                \"properties\": {\n                  \"repo_file_path\": {\n                    \"type\": \"string\"\n                  },\n                  \"file_slice\": {\n                    \"type\": \"object\",\n                    \"title\": \"FileSlice\",\n                    \"properties\": {\n                      \"filename\": {\n                        \"type\": \"string\"\n                      },\n                      \"content\": {\n                        \"type\": \"string\"\n                      },\n                      \"start_line_number\": {\n                        \"type\": \"integer\"\n                      },\n                      \"end_line_number\": {\n                        \"type\": \"integer\"\n                      }\n                    },\n                    \"additionalProperties\": false,\n                    \"required\": [\n                      \"filename\",\n                      \"content\",\n                      \"start_line_number\",\n                      \"end_line_number\"\n                    ]\n                  }\n                },\n                \"additionalProperties\": false,\n                \"required\": [\n                  \"repo_file_path\",\n                  \"file_slice\"\n                ]\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          },\n          \"time_granularity\": {\n            \"anyOf\": [\n              {\n                \"type\": \"string\"\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          },\n          \"config\": {\n            \"type\": \"object\",\n            \"title\": \"MetricConfig\",\n            \"properties\": {\n              \"_extra\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"enabled\": {\n                \"type\": \"boolean\",\n                \"default\": true\n              },\n              \"group\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"meta\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              }\n            },\n            \"additionalProperties\": true\n          },\n          \"unrendered_config\": {\n            \"type\": \"object\",\n            \"propertyNames\": {\n              \"type\": \"string\"\n            }\n          },\n          \"sources\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            }\n          },\n          \"depends_on\": {\n            \"type\": \"object\",\n            \"title\": \"DependsOn\",\n            \"properties\": {\n              \"macros\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"nodes\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              }\n            },\n            \"additionalProperties\": false\n          },\n          \"refs\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"object\",\n              \"title\": \"RefArgs\",\n              \"properties\": {\n                \"name\": {\n                  \"type\": \"string\"\n                },\n                \"package\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"string\"\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                },\n                \"version\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"string\"\n                    },\n                    {\n                      \"type\": \"number\"\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                }\n              },\n              \"additionalProperties\": false,\n              \"required\": [\n                \"name\"\n              ]\n            }\n          },\n          \"metrics\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            }\n          },\n          \"created_at\": {\n            \"type\": \"number\"\n          },\n          \"group\": {\n            \"anyOf\": [\n              {\n                \"type\": \"string\"\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          },\n          \"meta\": {\n            \"type\": \"object\",\n            \"propertyNames\": {\n              \"type\": \"string\"\n            }\n          },\n          \"tags\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          }\n        },\n        \"additionalProperties\": false,\n        \"required\": [\n          \"name\",\n          \"resource_type\",\n          \"package_name\",\n          \"path\",\n          \"original_file_path\",\n          \"unique_id\",\n          \"fqn\",\n          \"description\",\n          \"label\",\n          \"type\",\n          \"type_params\"\n        ]\n      },\n      \"propertyNames\": {\n        \"type\": \"string\"\n      }\n    },\n    \"groups\": {\n      \"type\": \"object\",\n      \"description\": \"The groups defined in the dbt project\",\n      \"additionalProperties\": {\n        \"type\": \"object\",\n        \"title\": \"Group\",\n        \"properties\": {\n          \"name\": {\n            \"type\": \"string\"\n          },\n          \"resource_type\": {\n            \"const\": \"group\"\n          },\n          \"package_name\": {\n            \"type\": \"string\"\n          },\n          \"path\": {\n            \"type\": \"string\"\n          },\n          \"original_file_path\": {\n            \"type\": \"string\"\n          },\n          \"unique_id\": {\n            \"type\": \"string\"\n          },\n          \"owner\": {\n            \"type\": \"object\",\n            \"title\": \"Owner\",\n            \"properties\": {\n              \"_extra\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"email\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"name\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              }\n            },\n            \"additionalProperties\": true\n          },\n          \"description\": {\n            \"anyOf\": [\n              {\n                \"type\": \"string\"\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          },\n          \"config\": {\n            \"type\": \"object\",\n            \"title\": \"GroupConfig\",\n            \"properties\": {\n              \"_extra\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"meta\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              }\n            },\n            \"additionalProperties\": true\n          }\n        },\n        \"additionalProperties\": false,\n        \"required\": [\n          \"name\",\n          \"resource_type\",\n          \"package_name\",\n          \"path\",\n          \"original_file_path\",\n          \"unique_id\",\n          \"owner\"\n        ]\n      },\n      \"propertyNames\": {\n        \"type\": \"string\"\n      }\n    },\n    \"selectors\": {\n      \"type\": \"object\",\n      \"description\": \"The selectors defined in selectors.yml\",\n      \"propertyNames\": {\n        \"type\": \"string\"\n      }\n    },\n    \"disabled\": {\n      \"description\": \"A mapping of the disabled nodes in the target\",\n      \"anyOf\": [\n        {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"anyOf\": [\n                {\n                  \"type\": \"object\",\n                  \"title\": \"Seed\",\n                  \"properties\": {\n                    \"database\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ]\n                    },\n                    \"schema\": {\n                      \"type\": \"string\"\n                    },\n                    \"name\": {\n                      \"type\": \"string\"\n                    },\n                    \"resource_type\": {\n                      \"const\": \"seed\"\n                    },\n                    \"package_name\": {\n                      \"type\": \"string\"\n                    },\n                    \"path\": {\n                      \"type\": \"string\"\n                    },\n                    \"original_file_path\": {\n                      \"type\": \"string\"\n                    },\n                    \"unique_id\": {\n                      \"type\": \"string\"\n                    },\n                    \"fqn\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"alias\": {\n                      \"type\": \"string\"\n                    },\n                    \"checksum\": {\n                      \"type\": \"object\",\n                      \"title\": \"FileHash\",\n                      \"properties\": {\n                        \"name\": {\n                          \"type\": \"string\"\n                        },\n                        \"checksum\": {\n                          \"type\": \"string\"\n                        }\n                      },\n                      \"additionalProperties\": false,\n                      \"required\": [\n                        \"name\",\n                        \"checksum\"\n                      ]\n                    },\n                    \"config\": {\n                      \"type\": \"object\",\n                      \"title\": \"SeedConfig\",\n                      \"properties\": {\n                        \"_extra\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"enabled\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"alias\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"schema\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"database\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"tags\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"array\",\n                              \"items\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            {\n                              \"type\": \"string\"\n                            }\n                          ]\n                        },\n                        \"meta\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"group\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"materialized\": {\n                          \"type\": \"string\",\n                          \"default\": \"seed\"\n                        },\n                        \"incremental_strategy\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"batch_size\": {\n                          \"default\": null\n                        },\n                        \"lookback\": {\n                          \"default\": 1\n                        },\n                        \"begin\": {\n                          \"default\": null\n                        },\n                        \"persist_docs\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"post-hook\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"object\",\n                            \"title\": \"Hook\",\n                            \"properties\": {\n                              \"sql\": {\n                                \"type\": \"string\"\n                              },\n                              \"transaction\": {\n                                \"type\": \"boolean\",\n                                \"default\": true\n                              },\n                              \"index\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"integer\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              }\n                            },\n                            \"additionalProperties\": false,\n                            \"required\": [\n                              \"sql\"\n                            ]\n                          }\n                        },\n                        \"pre-hook\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"object\",\n                            \"title\": \"Hook\",\n                            \"properties\": {\n                              \"sql\": {\n                                \"type\": \"string\"\n                              },\n                              \"transaction\": {\n                                \"type\": \"boolean\",\n                                \"default\": true\n                              },\n                              \"index\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"integer\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              }\n                            },\n                            \"additionalProperties\": false,\n                            \"required\": [\n                              \"sql\"\n                            ]\n                          }\n                        },\n                        \"quoting\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"column_types\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"full_refresh\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"boolean\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"unique_key\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"array\",\n                              \"items\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"on_schema_change\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": \"ignore\"\n                        },\n                        \"on_configuration_change\": {\n                          \"enum\": [\n                            \"apply\",\n                            \"continue\",\n                            \"fail\"\n                          ]\n                        },\n                        \"grants\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"packages\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"docs\": {\n                          \"type\": \"object\",\n                          \"title\": \"Docs\",\n                          \"properties\": {\n                            \"show\": {\n                              \"type\": \"boolean\",\n                              \"default\": true\n                            },\n                            \"node_color\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            }\n                          },\n                          \"additionalProperties\": false\n                        },\n                        \"contract\": {\n                          \"type\": \"object\",\n                          \"title\": \"ContractConfig\",\n                          \"properties\": {\n                            \"enforced\": {\n                              \"type\": \"boolean\",\n                              \"default\": false\n                            },\n                            \"alias_types\": {\n                              \"type\": \"boolean\",\n                              \"default\": true\n                            }\n                          },\n                          \"additionalProperties\": false\n                        },\n                        \"event_time\": {\n                          \"default\": null\n                        },\n                        \"concurrent_batches\": {\n                          \"default\": null\n                        },\n                        \"delimiter\": {\n                          \"type\": \"string\",\n                          \"default\": \",\"\n                        },\n                        \"quote_columns\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"boolean\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": true\n                    },\n                    \"tags\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"description\": {\n                      \"type\": \"string\",\n                      \"default\": \"\"\n                    },\n                    \"columns\": {\n                      \"type\": \"object\",\n                      \"additionalProperties\": {\n                        \"type\": \"object\",\n                        \"title\": \"ColumnInfo\",\n                        \"properties\": {\n                          \"name\": {\n                            \"type\": \"string\"\n                          },\n                          \"description\": {\n                            \"type\": \"string\",\n                            \"default\": \"\"\n                          },\n                          \"meta\": {\n                            \"type\": \"object\",\n                            \"propertyNames\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"data_type\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"constraints\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"object\",\n                              \"title\": \"ColumnLevelConstraint\",\n                              \"properties\": {\n                                \"type\": {\n                                  \"enum\": [\n                                    \"check\",\n                                    \"not_null\",\n                                    \"unique\",\n                                    \"primary_key\",\n                                    \"foreign_key\",\n                                    \"custom\"\n                                  ]\n                                },\n                                \"name\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"string\"\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"expression\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"string\"\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"warn_unenforced\": {\n                                  \"type\": \"boolean\",\n                                  \"default\": true\n                                },\n                                \"warn_unsupported\": {\n                                  \"type\": \"boolean\",\n                                  \"default\": true\n                                },\n                                \"to\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"string\"\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"to_columns\": {\n                                  \"type\": \"array\",\n                                  \"items\": {\n                                    \"type\": \"string\"\n                                  }\n                                }\n                              },\n                              \"additionalProperties\": false,\n                              \"required\": [\n                                \"type\"\n                              ]\n                            }\n                          },\n                          \"quote\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"boolean\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"config\": {\n                            \"type\": \"object\",\n                            \"title\": \"ColumnConfig\",\n                            \"properties\": {\n                              \"_extra\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"meta\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"tags\": {\n                                \"type\": \"array\",\n                                \"items\": {\n                                  \"type\": \"string\"\n                                }\n                              }\n                            },\n                            \"additionalProperties\": true\n                          },\n                          \"tags\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"_extra\": {\n                            \"type\": \"object\",\n                            \"propertyNames\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"granularity\": {\n                            \"anyOf\": [\n                              {\n                                \"enum\": [\n                                  \"nanosecond\",\n                                  \"microsecond\",\n                                  \"millisecond\",\n                                  \"second\",\n                                  \"minute\",\n                                  \"hour\",\n                                  \"day\",\n                                  \"week\",\n                                  \"month\",\n                                  \"quarter\",\n                                  \"year\"\n                                ]\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"dimension\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"object\",\n                                \"title\": \"ColumnDimension\",\n                                \"properties\": {\n                                  \"name\": {\n                                    \"type\": \"string\"\n                                  },\n                                  \"type\": {\n                                    \"enum\": [\n                                      \"categorical\",\n                                      \"time\"\n                                    ]\n                                  },\n                                  \"description\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"label\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"is_partition\": {\n                                    \"type\": \"boolean\",\n                                    \"default\": false\n                                  },\n                                  \"config\": {\n                                    \"type\": \"object\",\n                                    \"propertyNames\": {\n                                      \"type\": \"string\"\n                                    }\n                                  },\n                                  \"validity_params\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"object\",\n                                        \"title\": \"ColumnDimensionValidityParams\",\n                                        \"properties\": {\n                                          \"is_start\": {\n                                            \"type\": \"boolean\",\n                                            \"default\": false\n                                          },\n                                          \"is_end\": {\n                                            \"type\": \"boolean\",\n                                            \"default\": false\n                                          }\n                                        },\n                                        \"additionalProperties\": false\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  }\n                                },\n                                \"additionalProperties\": false,\n                                \"required\": [\n                                  \"name\",\n                                  \"type\"\n                                ]\n                              },\n                              {\n                                \"enum\": [\n                                  \"categorical\",\n                                  \"time\"\n                                ]\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"entity\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"object\",\n                                \"title\": \"ColumnEntity\",\n                                \"properties\": {\n                                  \"name\": {\n                                    \"type\": \"string\"\n                                  },\n                                  \"type\": {\n                                    \"enum\": [\n                                      \"foreign\",\n                                      \"natural\",\n                                      \"primary\",\n                                      \"unique\"\n                                    ]\n                                  },\n                                  \"description\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"label\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"config\": {\n                                    \"type\": \"object\",\n                                    \"propertyNames\": {\n                                      \"type\": \"string\"\n                                    }\n                                  }\n                                },\n                                \"additionalProperties\": false,\n                                \"required\": [\n                                  \"name\",\n                                  \"type\"\n                                ]\n                              },\n                              {\n                                \"enum\": [\n                                  \"foreign\",\n                                  \"natural\",\n                                  \"primary\",\n                                  \"unique\"\n                                ]\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"doc_blocks\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"string\"\n                            }\n                          }\n                        },\n                        \"additionalProperties\": true,\n                        \"required\": [\n                          \"name\"\n                        ]\n                      },\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"meta\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"group\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"docs\": {\n                      \"type\": \"object\",\n                      \"title\": \"Docs\",\n                      \"properties\": {\n                        \"show\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"node_color\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": false\n                    },\n                    \"patch_path\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"build_path\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"unrendered_config\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"created_at\": {\n                      \"type\": \"number\"\n                    },\n                    \"config_call_dict\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"unrendered_config_call_dict\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"relation_name\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"raw_code\": {\n                      \"type\": \"string\",\n                      \"default\": \"\"\n                    },\n                    \"doc_blocks\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"root_path\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"depends_on\": {\n                      \"type\": \"object\",\n                      \"title\": \"MacroDependsOn\",\n                      \"properties\": {\n                        \"macros\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      },\n                      \"additionalProperties\": false\n                    },\n                    \"defer_relation\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"object\",\n                          \"title\": \"DeferRelation\",\n                          \"properties\": {\n                            \"database\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ]\n                            },\n                            \"schema\": {\n                              \"type\": \"string\"\n                            },\n                            \"alias\": {\n                              \"type\": \"string\"\n                            },\n                            \"relation_name\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ]\n                            },\n                            \"resource_type\": {\n                              \"enum\": [\n                                \"model\",\n                                \"analysis\",\n                                \"test\",\n                                \"snapshot\",\n                                \"operation\",\n                                \"seed\",\n                                \"rpc\",\n                                \"sql_operation\",\n                                \"doc\",\n                                \"source\",\n                                \"macro\",\n                                \"exposure\",\n                                \"metric\",\n                                \"group\",\n                                \"saved_query\",\n                                \"semantic_model\",\n                                \"unit_test\",\n                                \"fixture\",\n                                \"function\"\n                              ]\n                            },\n                            \"name\": {\n                              \"type\": \"string\"\n                            },\n                            \"description\": {\n                              \"type\": \"string\"\n                            },\n                            \"compiled_code\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ]\n                            },\n                            \"meta\": {\n                              \"type\": \"object\",\n                              \"propertyNames\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            \"tags\": {\n                              \"type\": \"array\",\n                              \"items\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            \"config\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"object\",\n                                  \"title\": \"NodeConfig\",\n                                  \"properties\": {\n                                    \"_extra\": {\n                                      \"type\": \"object\",\n                                      \"propertyNames\": {\n                                        \"type\": \"string\"\n                                      }\n                                    },\n                                    \"enabled\": {\n                                      \"type\": \"boolean\",\n                                      \"default\": true\n                                    },\n                                    \"alias\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"string\"\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    },\n                                    \"schema\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"string\"\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    },\n                                    \"database\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"string\"\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    },\n                                    \"tags\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"array\",\n                                          \"items\": {\n                                            \"type\": \"string\"\n                                          }\n                                        },\n                                        {\n                                          \"type\": \"string\"\n                                        }\n                                      ]\n                                    },\n                                    \"meta\": {\n                                      \"type\": \"object\",\n                                      \"propertyNames\": {\n                                        \"type\": \"string\"\n                                      }\n                                    },\n                                    \"group\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"string\"\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    },\n                                    \"materialized\": {\n                                      \"type\": \"string\",\n                                      \"default\": \"view\"\n                                    },\n                                    \"incremental_strategy\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"string\"\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    },\n                                    \"batch_size\": {\n                                      \"default\": null\n                                    },\n                                    \"lookback\": {\n                                      \"default\": 1\n                                    },\n                                    \"begin\": {\n                                      \"default\": null\n                                    },\n                                    \"persist_docs\": {\n                                      \"type\": \"object\",\n                                      \"propertyNames\": {\n                                        \"type\": \"string\"\n                                      }\n                                    },\n                                    \"post-hook\": {\n                                      \"type\": \"array\",\n                                      \"items\": {\n                                        \"type\": \"object\",\n                                        \"title\": \"Hook\",\n                                        \"properties\": {\n                                          \"sql\": {\n                                            \"type\": \"string\"\n                                          },\n                                          \"transaction\": {\n                                            \"type\": \"boolean\",\n                                            \"default\": true\n                                          },\n                                          \"index\": {\n                                            \"anyOf\": [\n                                              {\n                                                \"type\": \"integer\"\n                                              },\n                                              {\n                                                \"type\": \"null\"\n                                              }\n                                            ],\n                                            \"default\": null\n                                          }\n                                        },\n                                        \"additionalProperties\": false,\n                                        \"required\": [\n                                          \"sql\"\n                                        ]\n                                      }\n                                    },\n                                    \"pre-hook\": {\n                                      \"type\": \"array\",\n                                      \"items\": {\n                                        \"type\": \"object\",\n                                        \"title\": \"Hook\",\n                                        \"properties\": {\n                                          \"sql\": {\n                                            \"type\": \"string\"\n                                          },\n                                          \"transaction\": {\n                                            \"type\": \"boolean\",\n                                            \"default\": true\n                                          },\n                                          \"index\": {\n                                            \"anyOf\": [\n                                              {\n                                                \"type\": \"integer\"\n                                              },\n                                              {\n                                                \"type\": \"null\"\n                                              }\n                                            ],\n                                            \"default\": null\n                                          }\n                                        },\n                                        \"additionalProperties\": false,\n                                        \"required\": [\n                                          \"sql\"\n                                        ]\n                                      }\n                                    },\n                                    \"quoting\": {\n                                      \"type\": \"object\",\n                                      \"propertyNames\": {\n                                        \"type\": \"string\"\n                                      }\n                                    },\n                                    \"column_types\": {\n                                      \"type\": \"object\",\n                                      \"propertyNames\": {\n                                        \"type\": \"string\"\n                                      }\n                                    },\n                                    \"full_refresh\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"boolean\"\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    },\n                                    \"unique_key\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"string\"\n                                        },\n                                        {\n                                          \"type\": \"array\",\n                                          \"items\": {\n                                            \"type\": \"string\"\n                                          }\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    },\n                                    \"on_schema_change\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"string\"\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": \"ignore\"\n                                    },\n                                    \"on_configuration_change\": {\n                                      \"enum\": [\n                                        \"apply\",\n                                        \"continue\",\n                                        \"fail\"\n                                      ]\n                                    },\n                                    \"grants\": {\n                                      \"type\": \"object\",\n                                      \"propertyNames\": {\n                                        \"type\": \"string\"\n                                      }\n                                    },\n                                    \"packages\": {\n                                      \"type\": \"array\",\n                                      \"items\": {\n                                        \"type\": \"string\"\n                                      }\n                                    },\n                                    \"docs\": {\n                                      \"type\": \"object\",\n                                      \"title\": \"Docs\",\n                                      \"properties\": {\n                                        \"show\": {\n                                          \"type\": \"boolean\",\n                                          \"default\": true\n                                        },\n                                        \"node_color\": {\n                                          \"anyOf\": [\n                                            {\n                                              \"type\": \"string\"\n                                            },\n                                            {\n                                              \"type\": \"null\"\n                                            }\n                                          ],\n                                          \"default\": null\n                                        }\n                                      },\n                                      \"additionalProperties\": false\n                                    },\n                                    \"contract\": {\n                                      \"type\": \"object\",\n                                      \"title\": \"ContractConfig\",\n                                      \"properties\": {\n                                        \"enforced\": {\n                                          \"type\": \"boolean\",\n                                          \"default\": false\n                                        },\n                                        \"alias_types\": {\n                                          \"type\": \"boolean\",\n                                          \"default\": true\n                                        }\n                                      },\n                                      \"additionalProperties\": false\n                                    },\n                                    \"event_time\": {\n                                      \"default\": null\n                                    },\n                                    \"concurrent_batches\": {\n                                      \"default\": null\n                                    }\n                                  },\n                                  \"additionalProperties\": true\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ]\n                            }\n                          },\n                          \"additionalProperties\": false,\n                          \"required\": [\n                            \"database\",\n                            \"schema\",\n                            \"alias\",\n                            \"relation_name\",\n                            \"resource_type\",\n                            \"name\",\n                            \"description\",\n                            \"compiled_code\",\n                            \"meta\",\n                            \"tags\",\n                            \"config\"\n                          ]\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    }\n                  },\n                  \"additionalProperties\": false,\n                  \"required\": [\n                    \"database\",\n                    \"schema\",\n                    \"name\",\n                    \"resource_type\",\n                    \"package_name\",\n                    \"path\",\n                    \"original_file_path\",\n                    \"unique_id\",\n                    \"fqn\",\n                    \"alias\",\n                    \"checksum\"\n                  ]\n                },\n                {\n                  \"type\": \"object\",\n                  \"title\": \"Analysis\",\n                  \"properties\": {\n                    \"database\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ]\n                    },\n                    \"schema\": {\n                      \"type\": \"string\"\n                    },\n                    \"name\": {\n                      \"type\": \"string\"\n                    },\n                    \"resource_type\": {\n                      \"const\": \"analysis\"\n                    },\n                    \"package_name\": {\n                      \"type\": \"string\"\n                    },\n                    \"path\": {\n                      \"type\": \"string\"\n                    },\n                    \"original_file_path\": {\n                      \"type\": \"string\"\n                    },\n                    \"unique_id\": {\n                      \"type\": \"string\"\n                    },\n                    \"fqn\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"alias\": {\n                      \"type\": \"string\"\n                    },\n                    \"checksum\": {\n                      \"type\": \"object\",\n                      \"title\": \"FileHash\",\n                      \"properties\": {\n                        \"name\": {\n                          \"type\": \"string\"\n                        },\n                        \"checksum\": {\n                          \"type\": \"string\"\n                        }\n                      },\n                      \"additionalProperties\": false,\n                      \"required\": [\n                        \"name\",\n                        \"checksum\"\n                      ]\n                    },\n                    \"config\": {\n                      \"type\": \"object\",\n                      \"title\": \"NodeConfig\",\n                      \"properties\": {\n                        \"_extra\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"enabled\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"alias\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"schema\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"database\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"tags\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"array\",\n                              \"items\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            {\n                              \"type\": \"string\"\n                            }\n                          ]\n                        },\n                        \"meta\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"group\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"materialized\": {\n                          \"type\": \"string\",\n                          \"default\": \"view\"\n                        },\n                        \"incremental_strategy\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"batch_size\": {\n                          \"default\": null\n                        },\n                        \"lookback\": {\n                          \"default\": 1\n                        },\n                        \"begin\": {\n                          \"default\": null\n                        },\n                        \"persist_docs\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"post-hook\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"object\",\n                            \"title\": \"Hook\",\n                            \"properties\": {\n                              \"sql\": {\n                                \"type\": \"string\"\n                              },\n                              \"transaction\": {\n                                \"type\": \"boolean\",\n                                \"default\": true\n                              },\n                              \"index\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"integer\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              }\n                            },\n                            \"additionalProperties\": false,\n                            \"required\": [\n                              \"sql\"\n                            ]\n                          }\n                        },\n                        \"pre-hook\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"object\",\n                            \"title\": \"Hook\",\n                            \"properties\": {\n                              \"sql\": {\n                                \"type\": \"string\"\n                              },\n                              \"transaction\": {\n                                \"type\": \"boolean\",\n                                \"default\": true\n                              },\n                              \"index\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"integer\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              }\n                            },\n                            \"additionalProperties\": false,\n                            \"required\": [\n                              \"sql\"\n                            ]\n                          }\n                        },\n                        \"quoting\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"column_types\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"full_refresh\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"boolean\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"unique_key\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"array\",\n                              \"items\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"on_schema_change\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": \"ignore\"\n                        },\n                        \"on_configuration_change\": {\n                          \"enum\": [\n                            \"apply\",\n                            \"continue\",\n                            \"fail\"\n                          ]\n                        },\n                        \"grants\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"packages\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"docs\": {\n                          \"type\": \"object\",\n                          \"title\": \"Docs\",\n                          \"properties\": {\n                            \"show\": {\n                              \"type\": \"boolean\",\n                              \"default\": true\n                            },\n                            \"node_color\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            }\n                          },\n                          \"additionalProperties\": false\n                        },\n                        \"contract\": {\n                          \"type\": \"object\",\n                          \"title\": \"ContractConfig\",\n                          \"properties\": {\n                            \"enforced\": {\n                              \"type\": \"boolean\",\n                              \"default\": false\n                            },\n                            \"alias_types\": {\n                              \"type\": \"boolean\",\n                              \"default\": true\n                            }\n                          },\n                          \"additionalProperties\": false\n                        },\n                        \"event_time\": {\n                          \"default\": null\n                        },\n                        \"concurrent_batches\": {\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": true\n                    },\n                    \"tags\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"description\": {\n                      \"type\": \"string\",\n                      \"default\": \"\"\n                    },\n                    \"columns\": {\n                      \"type\": \"object\",\n                      \"additionalProperties\": {\n                        \"type\": \"object\",\n                        \"title\": \"ColumnInfo\",\n                        \"properties\": {\n                          \"name\": {\n                            \"type\": \"string\"\n                          },\n                          \"description\": {\n                            \"type\": \"string\",\n                            \"default\": \"\"\n                          },\n                          \"meta\": {\n                            \"type\": \"object\",\n                            \"propertyNames\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"data_type\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"constraints\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"object\",\n                              \"title\": \"ColumnLevelConstraint\",\n                              \"properties\": {\n                                \"type\": {\n                                  \"enum\": [\n                                    \"check\",\n                                    \"not_null\",\n                                    \"unique\",\n                                    \"primary_key\",\n                                    \"foreign_key\",\n                                    \"custom\"\n                                  ]\n                                },\n                                \"name\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"string\"\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"expression\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"string\"\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"warn_unenforced\": {\n                                  \"type\": \"boolean\",\n                                  \"default\": true\n                                },\n                                \"warn_unsupported\": {\n                                  \"type\": \"boolean\",\n                                  \"default\": true\n                                },\n                                \"to\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"string\"\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"to_columns\": {\n                                  \"type\": \"array\",\n                                  \"items\": {\n                                    \"type\": \"string\"\n                                  }\n                                }\n                              },\n                              \"additionalProperties\": false,\n                              \"required\": [\n                                \"type\"\n                              ]\n                            }\n                          },\n                          \"quote\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"boolean\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"config\": {\n                            \"type\": \"object\",\n                            \"title\": \"ColumnConfig\",\n                            \"properties\": {\n                              \"_extra\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"meta\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"tags\": {\n                                \"type\": \"array\",\n                                \"items\": {\n                                  \"type\": \"string\"\n                                }\n                              }\n                            },\n                            \"additionalProperties\": true\n                          },\n                          \"tags\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"_extra\": {\n                            \"type\": \"object\",\n                            \"propertyNames\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"granularity\": {\n                            \"anyOf\": [\n                              {\n                                \"enum\": [\n                                  \"nanosecond\",\n                                  \"microsecond\",\n                                  \"millisecond\",\n                                  \"second\",\n                                  \"minute\",\n                                  \"hour\",\n                                  \"day\",\n                                  \"week\",\n                                  \"month\",\n                                  \"quarter\",\n                                  \"year\"\n                                ]\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"dimension\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"object\",\n                                \"title\": \"ColumnDimension\",\n                                \"properties\": {\n                                  \"name\": {\n                                    \"type\": \"string\"\n                                  },\n                                  \"type\": {\n                                    \"enum\": [\n                                      \"categorical\",\n                                      \"time\"\n                                    ]\n                                  },\n                                  \"description\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"label\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"is_partition\": {\n                                    \"type\": \"boolean\",\n                                    \"default\": false\n                                  },\n                                  \"config\": {\n                                    \"type\": \"object\",\n                                    \"propertyNames\": {\n                                      \"type\": \"string\"\n                                    }\n                                  },\n                                  \"validity_params\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"object\",\n                                        \"title\": \"ColumnDimensionValidityParams\",\n                                        \"properties\": {\n                                          \"is_start\": {\n                                            \"type\": \"boolean\",\n                                            \"default\": false\n                                          },\n                                          \"is_end\": {\n                                            \"type\": \"boolean\",\n                                            \"default\": false\n                                          }\n                                        },\n                                        \"additionalProperties\": false\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  }\n                                },\n                                \"additionalProperties\": false,\n                                \"required\": [\n                                  \"name\",\n                                  \"type\"\n                                ]\n                              },\n                              {\n                                \"enum\": [\n                                  \"categorical\",\n                                  \"time\"\n                                ]\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"entity\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"object\",\n                                \"title\": \"ColumnEntity\",\n                                \"properties\": {\n                                  \"name\": {\n                                    \"type\": \"string\"\n                                  },\n                                  \"type\": {\n                                    \"enum\": [\n                                      \"foreign\",\n                                      \"natural\",\n                                      \"primary\",\n                                      \"unique\"\n                                    ]\n                                  },\n                                  \"description\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"label\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"config\": {\n                                    \"type\": \"object\",\n                                    \"propertyNames\": {\n                                      \"type\": \"string\"\n                                    }\n                                  }\n                                },\n                                \"additionalProperties\": false,\n                                \"required\": [\n                                  \"name\",\n                                  \"type\"\n                                ]\n                              },\n                              {\n                                \"enum\": [\n                                  \"foreign\",\n                                  \"natural\",\n                                  \"primary\",\n                                  \"unique\"\n                                ]\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"doc_blocks\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"string\"\n                            }\n                          }\n                        },\n                        \"additionalProperties\": true,\n                        \"required\": [\n                          \"name\"\n                        ]\n                      },\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"meta\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"group\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"docs\": {\n                      \"type\": \"object\",\n                      \"title\": \"Docs\",\n                      \"properties\": {\n                        \"show\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"node_color\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": false\n                    },\n                    \"patch_path\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"build_path\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"unrendered_config\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"created_at\": {\n                      \"type\": \"number\"\n                    },\n                    \"config_call_dict\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"unrendered_config_call_dict\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"relation_name\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"raw_code\": {\n                      \"type\": \"string\",\n                      \"default\": \"\"\n                    },\n                    \"doc_blocks\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"language\": {\n                      \"type\": \"string\",\n                      \"default\": \"sql\"\n                    },\n                    \"refs\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"object\",\n                        \"title\": \"RefArgs\",\n                        \"properties\": {\n                          \"name\": {\n                            \"type\": \"string\"\n                          },\n                          \"package\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"version\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"number\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          }\n                        },\n                        \"additionalProperties\": false,\n                        \"required\": [\n                          \"name\"\n                        ]\n                      }\n                    },\n                    \"sources\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      }\n                    },\n                    \"metrics\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      }\n                    },\n                    \"functions\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      }\n                    },\n                    \"depends_on\": {\n                      \"type\": \"object\",\n                      \"title\": \"DependsOn\",\n                      \"properties\": {\n                        \"macros\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"nodes\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      },\n                      \"additionalProperties\": false\n                    },\n                    \"compiled_path\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"compiled\": {\n                      \"type\": \"boolean\",\n                      \"default\": false\n                    },\n                    \"compiled_code\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"extra_ctes_injected\": {\n                      \"type\": \"boolean\",\n                      \"default\": false\n                    },\n                    \"extra_ctes\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"object\",\n                        \"title\": \"InjectedCTE\",\n                        \"properties\": {\n                          \"id\": {\n                            \"type\": \"string\"\n                          },\n                          \"sql\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"additionalProperties\": false,\n                        \"required\": [\n                          \"id\",\n                          \"sql\"\n                        ]\n                      }\n                    },\n                    \"_pre_injected_sql\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"contract\": {\n                      \"type\": \"object\",\n                      \"title\": \"Contract\",\n                      \"properties\": {\n                        \"enforced\": {\n                          \"type\": \"boolean\",\n                          \"default\": false\n                        },\n                        \"alias_types\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"checksum\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": false\n                    }\n                  },\n                  \"additionalProperties\": false,\n                  \"required\": [\n                    \"database\",\n                    \"schema\",\n                    \"name\",\n                    \"resource_type\",\n                    \"package_name\",\n                    \"path\",\n                    \"original_file_path\",\n                    \"unique_id\",\n                    \"fqn\",\n                    \"alias\",\n                    \"checksum\"\n                  ]\n                },\n                {\n                  \"type\": \"object\",\n                  \"title\": \"SingularTest\",\n                  \"properties\": {\n                    \"database\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ]\n                    },\n                    \"schema\": {\n                      \"type\": \"string\"\n                    },\n                    \"name\": {\n                      \"type\": \"string\"\n                    },\n                    \"resource_type\": {\n                      \"const\": \"test\"\n                    },\n                    \"package_name\": {\n                      \"type\": \"string\"\n                    },\n                    \"path\": {\n                      \"type\": \"string\"\n                    },\n                    \"original_file_path\": {\n                      \"type\": \"string\"\n                    },\n                    \"unique_id\": {\n                      \"type\": \"string\"\n                    },\n                    \"fqn\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"alias\": {\n                      \"type\": \"string\"\n                    },\n                    \"checksum\": {\n                      \"type\": \"object\",\n                      \"title\": \"FileHash\",\n                      \"properties\": {\n                        \"name\": {\n                          \"type\": \"string\"\n                        },\n                        \"checksum\": {\n                          \"type\": \"string\"\n                        }\n                      },\n                      \"additionalProperties\": false,\n                      \"required\": [\n                        \"name\",\n                        \"checksum\"\n                      ]\n                    },\n                    \"config\": {\n                      \"type\": \"object\",\n                      \"title\": \"TestConfig\",\n                      \"properties\": {\n                        \"_extra\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"enabled\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"alias\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"schema\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": \"dbt_test__audit\"\n                        },\n                        \"database\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"tags\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"array\",\n                              \"items\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            {\n                              \"type\": \"string\"\n                            }\n                          ]\n                        },\n                        \"meta\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"group\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"materialized\": {\n                          \"type\": \"string\",\n                          \"default\": \"test\"\n                        },\n                        \"severity\": {\n                          \"type\": \"string\",\n                          \"default\": \"ERROR\",\n                          \"pattern\": \"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$\"\n                        },\n                        \"store_failures\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"boolean\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"store_failures_as\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"sql_header\": {\n                          \"default\": null\n                        },\n                        \"where\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"limit\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"integer\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"fail_calc\": {\n                          \"type\": \"string\",\n                          \"default\": \"count(*)\"\n                        },\n                        \"warn_if\": {\n                          \"type\": \"string\",\n                          \"default\": \"!= 0\"\n                        },\n                        \"error_if\": {\n                          \"type\": \"string\",\n                          \"default\": \"!= 0\"\n                        }\n                      },\n                      \"additionalProperties\": true\n                    },\n                    \"tags\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"description\": {\n                      \"type\": \"string\",\n                      \"default\": \"\"\n                    },\n                    \"columns\": {\n                      \"type\": \"object\",\n                      \"additionalProperties\": {\n                        \"type\": \"object\",\n                        \"title\": \"ColumnInfo\",\n                        \"properties\": {\n                          \"name\": {\n                            \"type\": \"string\"\n                          },\n                          \"description\": {\n                            \"type\": \"string\",\n                            \"default\": \"\"\n                          },\n                          \"meta\": {\n                            \"type\": \"object\",\n                            \"propertyNames\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"data_type\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"constraints\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"object\",\n                              \"title\": \"ColumnLevelConstraint\",\n                              \"properties\": {\n                                \"type\": {\n                                  \"enum\": [\n                                    \"check\",\n                                    \"not_null\",\n                                    \"unique\",\n                                    \"primary_key\",\n                                    \"foreign_key\",\n                                    \"custom\"\n                                  ]\n                                },\n                                \"name\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"string\"\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"expression\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"string\"\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"warn_unenforced\": {\n                                  \"type\": \"boolean\",\n                                  \"default\": true\n                                },\n                                \"warn_unsupported\": {\n                                  \"type\": \"boolean\",\n                                  \"default\": true\n                                },\n                                \"to\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"string\"\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"to_columns\": {\n                                  \"type\": \"array\",\n                                  \"items\": {\n                                    \"type\": \"string\"\n                                  }\n                                }\n                              },\n                              \"additionalProperties\": false,\n                              \"required\": [\n                                \"type\"\n                              ]\n                            }\n                          },\n                          \"quote\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"boolean\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"config\": {\n                            \"type\": \"object\",\n                            \"title\": \"ColumnConfig\",\n                            \"properties\": {\n                              \"_extra\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"meta\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"tags\": {\n                                \"type\": \"array\",\n                                \"items\": {\n                                  \"type\": \"string\"\n                                }\n                              }\n                            },\n                            \"additionalProperties\": true\n                          },\n                          \"tags\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"_extra\": {\n                            \"type\": \"object\",\n                            \"propertyNames\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"granularity\": {\n                            \"anyOf\": [\n                              {\n                                \"enum\": [\n                                  \"nanosecond\",\n                                  \"microsecond\",\n                                  \"millisecond\",\n                                  \"second\",\n                                  \"minute\",\n                                  \"hour\",\n                                  \"day\",\n                                  \"week\",\n                                  \"month\",\n                                  \"quarter\",\n                                  \"year\"\n                                ]\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"dimension\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"object\",\n                                \"title\": \"ColumnDimension\",\n                                \"properties\": {\n                                  \"name\": {\n                                    \"type\": \"string\"\n                                  },\n                                  \"type\": {\n                                    \"enum\": [\n                                      \"categorical\",\n                                      \"time\"\n                                    ]\n                                  },\n                                  \"description\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"label\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"is_partition\": {\n                                    \"type\": \"boolean\",\n                                    \"default\": false\n                                  },\n                                  \"config\": {\n                                    \"type\": \"object\",\n                                    \"propertyNames\": {\n                                      \"type\": \"string\"\n                                    }\n                                  },\n                                  \"validity_params\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"object\",\n                                        \"title\": \"ColumnDimensionValidityParams\",\n                                        \"properties\": {\n                                          \"is_start\": {\n                                            \"type\": \"boolean\",\n                                            \"default\": false\n                                          },\n                                          \"is_end\": {\n                                            \"type\": \"boolean\",\n                                            \"default\": false\n                                          }\n                                        },\n                                        \"additionalProperties\": false\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  }\n                                },\n                                \"additionalProperties\": false,\n                                \"required\": [\n                                  \"name\",\n                                  \"type\"\n                                ]\n                              },\n                              {\n                                \"enum\": [\n                                  \"categorical\",\n                                  \"time\"\n                                ]\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"entity\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"object\",\n                                \"title\": \"ColumnEntity\",\n                                \"properties\": {\n                                  \"name\": {\n                                    \"type\": \"string\"\n                                  },\n                                  \"type\": {\n                                    \"enum\": [\n                                      \"foreign\",\n                                      \"natural\",\n                                      \"primary\",\n                                      \"unique\"\n                                    ]\n                                  },\n                                  \"description\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"label\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"config\": {\n                                    \"type\": \"object\",\n                                    \"propertyNames\": {\n                                      \"type\": \"string\"\n                                    }\n                                  }\n                                },\n                                \"additionalProperties\": false,\n                                \"required\": [\n                                  \"name\",\n                                  \"type\"\n                                ]\n                              },\n                              {\n                                \"enum\": [\n                                  \"foreign\",\n                                  \"natural\",\n                                  \"primary\",\n                                  \"unique\"\n                                ]\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"doc_blocks\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"string\"\n                            }\n                          }\n                        },\n                        \"additionalProperties\": true,\n                        \"required\": [\n                          \"name\"\n                        ]\n                      },\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"meta\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"group\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"docs\": {\n                      \"type\": \"object\",\n                      \"title\": \"Docs\",\n                      \"properties\": {\n                        \"show\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"node_color\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": false\n                    },\n                    \"patch_path\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"build_path\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"unrendered_config\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"created_at\": {\n                      \"type\": \"number\"\n                    },\n                    \"config_call_dict\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"unrendered_config_call_dict\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"relation_name\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"raw_code\": {\n                      \"type\": \"string\",\n                      \"default\": \"\"\n                    },\n                    \"doc_blocks\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"language\": {\n                      \"type\": \"string\",\n                      \"default\": \"sql\"\n                    },\n                    \"refs\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"object\",\n                        \"title\": \"RefArgs\",\n                        \"properties\": {\n                          \"name\": {\n                            \"type\": \"string\"\n                          },\n                          \"package\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"version\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"number\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          }\n                        },\n                        \"additionalProperties\": false,\n                        \"required\": [\n                          \"name\"\n                        ]\n                      }\n                    },\n                    \"sources\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      }\n                    },\n                    \"metrics\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      }\n                    },\n                    \"functions\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      }\n                    },\n                    \"depends_on\": {\n                      \"type\": \"object\",\n                      \"title\": \"DependsOn\",\n                      \"properties\": {\n                        \"macros\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"nodes\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      },\n                      \"additionalProperties\": false\n                    },\n                    \"compiled_path\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"compiled\": {\n                      \"type\": \"boolean\",\n                      \"default\": false\n                    },\n                    \"compiled_code\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"extra_ctes_injected\": {\n                      \"type\": \"boolean\",\n                      \"default\": false\n                    },\n                    \"extra_ctes\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"object\",\n                        \"title\": \"InjectedCTE\",\n                        \"properties\": {\n                          \"id\": {\n                            \"type\": \"string\"\n                          },\n                          \"sql\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"additionalProperties\": false,\n                        \"required\": [\n                          \"id\",\n                          \"sql\"\n                        ]\n                      }\n                    },\n                    \"_pre_injected_sql\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"contract\": {\n                      \"type\": \"object\",\n                      \"title\": \"Contract\",\n                      \"properties\": {\n                        \"enforced\": {\n                          \"type\": \"boolean\",\n                          \"default\": false\n                        },\n                        \"alias_types\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"checksum\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": false\n                    }\n                  },\n                  \"additionalProperties\": false,\n                  \"required\": [\n                    \"database\",\n                    \"schema\",\n                    \"name\",\n                    \"resource_type\",\n                    \"package_name\",\n                    \"path\",\n                    \"original_file_path\",\n                    \"unique_id\",\n                    \"fqn\",\n                    \"alias\",\n                    \"checksum\"\n                  ]\n                },\n                {\n                  \"type\": \"object\",\n                  \"title\": \"HookNode\",\n                  \"properties\": {\n                    \"database\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ]\n                    },\n                    \"schema\": {\n                      \"type\": \"string\"\n                    },\n                    \"name\": {\n                      \"type\": \"string\"\n                    },\n                    \"resource_type\": {\n                      \"const\": \"operation\"\n                    },\n                    \"package_name\": {\n                      \"type\": \"string\"\n                    },\n                    \"path\": {\n                      \"type\": \"string\"\n                    },\n                    \"original_file_path\": {\n                      \"type\": \"string\"\n                    },\n                    \"unique_id\": {\n                      \"type\": \"string\"\n                    },\n                    \"fqn\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"alias\": {\n                      \"type\": \"string\"\n                    },\n                    \"checksum\": {\n                      \"type\": \"object\",\n                      \"title\": \"FileHash\",\n                      \"properties\": {\n                        \"name\": {\n                          \"type\": \"string\"\n                        },\n                        \"checksum\": {\n                          \"type\": \"string\"\n                        }\n                      },\n                      \"additionalProperties\": false,\n                      \"required\": [\n                        \"name\",\n                        \"checksum\"\n                      ]\n                    },\n                    \"config\": {\n                      \"type\": \"object\",\n                      \"title\": \"NodeConfig\",\n                      \"properties\": {\n                        \"_extra\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"enabled\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"alias\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"schema\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"database\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"tags\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"array\",\n                              \"items\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            {\n                              \"type\": \"string\"\n                            }\n                          ]\n                        },\n                        \"meta\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"group\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"materialized\": {\n                          \"type\": \"string\",\n                          \"default\": \"view\"\n                        },\n                        \"incremental_strategy\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"batch_size\": {\n                          \"default\": null\n                        },\n                        \"lookback\": {\n                          \"default\": 1\n                        },\n                        \"begin\": {\n                          \"default\": null\n                        },\n                        \"persist_docs\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"post-hook\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"object\",\n                            \"title\": \"Hook\",\n                            \"properties\": {\n                              \"sql\": {\n                                \"type\": \"string\"\n                              },\n                              \"transaction\": {\n                                \"type\": \"boolean\",\n                                \"default\": true\n                              },\n                              \"index\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"integer\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              }\n                            },\n                            \"additionalProperties\": false,\n                            \"required\": [\n                              \"sql\"\n                            ]\n                          }\n                        },\n                        \"pre-hook\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"object\",\n                            \"title\": \"Hook\",\n                            \"properties\": {\n                              \"sql\": {\n                                \"type\": \"string\"\n                              },\n                              \"transaction\": {\n                                \"type\": \"boolean\",\n                                \"default\": true\n                              },\n                              \"index\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"integer\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              }\n                            },\n                            \"additionalProperties\": false,\n                            \"required\": [\n                              \"sql\"\n                            ]\n                          }\n                        },\n                        \"quoting\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"column_types\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"full_refresh\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"boolean\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"unique_key\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"array\",\n                              \"items\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"on_schema_change\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": \"ignore\"\n                        },\n                        \"on_configuration_change\": {\n                          \"enum\": [\n                            \"apply\",\n                            \"continue\",\n                            \"fail\"\n                          ]\n                        },\n                        \"grants\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"packages\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"docs\": {\n                          \"type\": \"object\",\n                          \"title\": \"Docs\",\n                          \"properties\": {\n                            \"show\": {\n                              \"type\": \"boolean\",\n                              \"default\": true\n                            },\n                            \"node_color\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            }\n                          },\n                          \"additionalProperties\": false\n                        },\n                        \"contract\": {\n                          \"type\": \"object\",\n                          \"title\": \"ContractConfig\",\n                          \"properties\": {\n                            \"enforced\": {\n                              \"type\": \"boolean\",\n                              \"default\": false\n                            },\n                            \"alias_types\": {\n                              \"type\": \"boolean\",\n                              \"default\": true\n                            }\n                          },\n                          \"additionalProperties\": false\n                        },\n                        \"event_time\": {\n                          \"default\": null\n                        },\n                        \"concurrent_batches\": {\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": true\n                    },\n                    \"tags\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"description\": {\n                      \"type\": \"string\",\n                      \"default\": \"\"\n                    },\n                    \"columns\": {\n                      \"type\": \"object\",\n                      \"additionalProperties\": {\n                        \"type\": \"object\",\n                        \"title\": \"ColumnInfo\",\n                        \"properties\": {\n                          \"name\": {\n                            \"type\": \"string\"\n                          },\n                          \"description\": {\n                            \"type\": \"string\",\n                            \"default\": \"\"\n                          },\n                          \"meta\": {\n                            \"type\": \"object\",\n                            \"propertyNames\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"data_type\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"constraints\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"object\",\n                              \"title\": \"ColumnLevelConstraint\",\n                              \"properties\": {\n                                \"type\": {\n                                  \"enum\": [\n                                    \"check\",\n                                    \"not_null\",\n                                    \"unique\",\n                                    \"primary_key\",\n                                    \"foreign_key\",\n                                    \"custom\"\n                                  ]\n                                },\n                                \"name\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"string\"\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"expression\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"string\"\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"warn_unenforced\": {\n                                  \"type\": \"boolean\",\n                                  \"default\": true\n                                },\n                                \"warn_unsupported\": {\n                                  \"type\": \"boolean\",\n                                  \"default\": true\n                                },\n                                \"to\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"string\"\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"to_columns\": {\n                                  \"type\": \"array\",\n                                  \"items\": {\n                                    \"type\": \"string\"\n                                  }\n                                }\n                              },\n                              \"additionalProperties\": false,\n                              \"required\": [\n                                \"type\"\n                              ]\n                            }\n                          },\n                          \"quote\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"boolean\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"config\": {\n                            \"type\": \"object\",\n                            \"title\": \"ColumnConfig\",\n                            \"properties\": {\n                              \"_extra\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"meta\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"tags\": {\n                                \"type\": \"array\",\n                                \"items\": {\n                                  \"type\": \"string\"\n                                }\n                              }\n                            },\n                            \"additionalProperties\": true\n                          },\n                          \"tags\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"_extra\": {\n                            \"type\": \"object\",\n                            \"propertyNames\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"granularity\": {\n                            \"anyOf\": [\n                              {\n                                \"enum\": [\n                                  \"nanosecond\",\n                                  \"microsecond\",\n                                  \"millisecond\",\n                                  \"second\",\n                                  \"minute\",\n                                  \"hour\",\n                                  \"day\",\n                                  \"week\",\n                                  \"month\",\n                                  \"quarter\",\n                                  \"year\"\n                                ]\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"dimension\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"object\",\n                                \"title\": \"ColumnDimension\",\n                                \"properties\": {\n                                  \"name\": {\n                                    \"type\": \"string\"\n                                  },\n                                  \"type\": {\n                                    \"enum\": [\n                                      \"categorical\",\n                                      \"time\"\n                                    ]\n                                  },\n                                  \"description\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"label\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"is_partition\": {\n                                    \"type\": \"boolean\",\n                                    \"default\": false\n                                  },\n                                  \"config\": {\n                                    \"type\": \"object\",\n                                    \"propertyNames\": {\n                                      \"type\": \"string\"\n                                    }\n                                  },\n                                  \"validity_params\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"object\",\n                                        \"title\": \"ColumnDimensionValidityParams\",\n                                        \"properties\": {\n                                          \"is_start\": {\n                                            \"type\": \"boolean\",\n                                            \"default\": false\n                                          },\n                                          \"is_end\": {\n                                            \"type\": \"boolean\",\n                                            \"default\": false\n                                          }\n                                        },\n                                        \"additionalProperties\": false\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  }\n                                },\n                                \"additionalProperties\": false,\n                                \"required\": [\n                                  \"name\",\n                                  \"type\"\n                                ]\n                              },\n                              {\n                                \"enum\": [\n                                  \"categorical\",\n                                  \"time\"\n                                ]\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"entity\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"object\",\n                                \"title\": \"ColumnEntity\",\n                                \"properties\": {\n                                  \"name\": {\n                                    \"type\": \"string\"\n                                  },\n                                  \"type\": {\n                                    \"enum\": [\n                                      \"foreign\",\n                                      \"natural\",\n                                      \"primary\",\n                                      \"unique\"\n                                    ]\n                                  },\n                                  \"description\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"label\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"config\": {\n                                    \"type\": \"object\",\n                                    \"propertyNames\": {\n                                      \"type\": \"string\"\n                                    }\n                                  }\n                                },\n                                \"additionalProperties\": false,\n                                \"required\": [\n                                  \"name\",\n                                  \"type\"\n                                ]\n                              },\n                              {\n                                \"enum\": [\n                                  \"foreign\",\n                                  \"natural\",\n                                  \"primary\",\n                                  \"unique\"\n                                ]\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"doc_blocks\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"string\"\n                            }\n                          }\n                        },\n                        \"additionalProperties\": true,\n                        \"required\": [\n                          \"name\"\n                        ]\n                      },\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"meta\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"group\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"docs\": {\n                      \"type\": \"object\",\n                      \"title\": \"Docs\",\n                      \"properties\": {\n                        \"show\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"node_color\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": false\n                    },\n                    \"patch_path\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"build_path\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"unrendered_config\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"created_at\": {\n                      \"type\": \"number\"\n                    },\n                    \"config_call_dict\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"unrendered_config_call_dict\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"relation_name\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"raw_code\": {\n                      \"type\": \"string\",\n                      \"default\": \"\"\n                    },\n                    \"doc_blocks\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"language\": {\n                      \"type\": \"string\",\n                      \"default\": \"sql\"\n                    },\n                    \"refs\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"object\",\n                        \"title\": \"RefArgs\",\n                        \"properties\": {\n                          \"name\": {\n                            \"type\": \"string\"\n                          },\n                          \"package\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"version\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"number\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          }\n                        },\n                        \"additionalProperties\": false,\n                        \"required\": [\n                          \"name\"\n                        ]\n                      }\n                    },\n                    \"sources\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      }\n                    },\n                    \"metrics\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      }\n                    },\n                    \"functions\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      }\n                    },\n                    \"depends_on\": {\n                      \"type\": \"object\",\n                      \"title\": \"DependsOn\",\n                      \"properties\": {\n                        \"macros\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"nodes\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      },\n                      \"additionalProperties\": false\n                    },\n                    \"compiled_path\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"compiled\": {\n                      \"type\": \"boolean\",\n                      \"default\": false\n                    },\n                    \"compiled_code\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"extra_ctes_injected\": {\n                      \"type\": \"boolean\",\n                      \"default\": false\n                    },\n                    \"extra_ctes\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"object\",\n                        \"title\": \"InjectedCTE\",\n                        \"properties\": {\n                          \"id\": {\n                            \"type\": \"string\"\n                          },\n                          \"sql\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"additionalProperties\": false,\n                        \"required\": [\n                          \"id\",\n                          \"sql\"\n                        ]\n                      }\n                    },\n                    \"_pre_injected_sql\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"contract\": {\n                      \"type\": \"object\",\n                      \"title\": \"Contract\",\n                      \"properties\": {\n                        \"enforced\": {\n                          \"type\": \"boolean\",\n                          \"default\": false\n                        },\n                        \"alias_types\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"checksum\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": false\n                    },\n                    \"index\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"integer\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    }\n                  },\n                  \"additionalProperties\": false,\n                  \"required\": [\n                    \"database\",\n                    \"schema\",\n                    \"name\",\n                    \"resource_type\",\n                    \"package_name\",\n                    \"path\",\n                    \"original_file_path\",\n                    \"unique_id\",\n                    \"fqn\",\n                    \"alias\",\n                    \"checksum\"\n                  ]\n                },\n                {\n                  \"type\": \"object\",\n                  \"title\": \"Model\",\n                  \"properties\": {\n                    \"database\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ]\n                    },\n                    \"schema\": {\n                      \"type\": \"string\"\n                    },\n                    \"name\": {\n                      \"type\": \"string\"\n                    },\n                    \"resource_type\": {\n                      \"const\": \"model\"\n                    },\n                    \"package_name\": {\n                      \"type\": \"string\"\n                    },\n                    \"path\": {\n                      \"type\": \"string\"\n                    },\n                    \"original_file_path\": {\n                      \"type\": \"string\"\n                    },\n                    \"unique_id\": {\n                      \"type\": \"string\"\n                    },\n                    \"fqn\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"alias\": {\n                      \"type\": \"string\"\n                    },\n                    \"checksum\": {\n                      \"type\": \"object\",\n                      \"title\": \"FileHash\",\n                      \"properties\": {\n                        \"name\": {\n                          \"type\": \"string\"\n                        },\n                        \"checksum\": {\n                          \"type\": \"string\"\n                        }\n                      },\n                      \"additionalProperties\": false,\n                      \"required\": [\n                        \"name\",\n                        \"checksum\"\n                      ]\n                    },\n                    \"config\": {\n                      \"type\": \"object\",\n                      \"title\": \"ModelConfig\",\n                      \"properties\": {\n                        \"_extra\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"enabled\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"alias\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"schema\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"database\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"tags\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"array\",\n                              \"items\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            {\n                              \"type\": \"string\"\n                            }\n                          ]\n                        },\n                        \"meta\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"group\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"materialized\": {\n                          \"type\": \"string\",\n                          \"default\": \"view\"\n                        },\n                        \"incremental_strategy\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"batch_size\": {\n                          \"default\": null\n                        },\n                        \"lookback\": {\n                          \"default\": 1\n                        },\n                        \"begin\": {\n                          \"default\": null\n                        },\n                        \"persist_docs\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"post-hook\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"object\",\n                            \"title\": \"Hook\",\n                            \"properties\": {\n                              \"sql\": {\n                                \"type\": \"string\"\n                              },\n                              \"transaction\": {\n                                \"type\": \"boolean\",\n                                \"default\": true\n                              },\n                              \"index\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"integer\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              }\n                            },\n                            \"additionalProperties\": false,\n                            \"required\": [\n                              \"sql\"\n                            ]\n                          }\n                        },\n                        \"pre-hook\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"object\",\n                            \"title\": \"Hook\",\n                            \"properties\": {\n                              \"sql\": {\n                                \"type\": \"string\"\n                              },\n                              \"transaction\": {\n                                \"type\": \"boolean\",\n                                \"default\": true\n                              },\n                              \"index\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"integer\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              }\n                            },\n                            \"additionalProperties\": false,\n                            \"required\": [\n                              \"sql\"\n                            ]\n                          }\n                        },\n                        \"quoting\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"column_types\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"full_refresh\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"boolean\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"unique_key\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"array\",\n                              \"items\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"on_schema_change\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": \"ignore\"\n                        },\n                        \"on_configuration_change\": {\n                          \"enum\": [\n                            \"apply\",\n                            \"continue\",\n                            \"fail\"\n                          ]\n                        },\n                        \"grants\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"packages\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"docs\": {\n                          \"type\": \"object\",\n                          \"title\": \"Docs\",\n                          \"properties\": {\n                            \"show\": {\n                              \"type\": \"boolean\",\n                              \"default\": true\n                            },\n                            \"node_color\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            }\n                          },\n                          \"additionalProperties\": false\n                        },\n                        \"contract\": {\n                          \"type\": \"object\",\n                          \"title\": \"ContractConfig\",\n                          \"properties\": {\n                            \"enforced\": {\n                              \"type\": \"boolean\",\n                              \"default\": false\n                            },\n                            \"alias_types\": {\n                              \"type\": \"boolean\",\n                              \"default\": true\n                            }\n                          },\n                          \"additionalProperties\": false\n                        },\n                        \"event_time\": {\n                          \"default\": null\n                        },\n                        \"concurrent_batches\": {\n                          \"default\": null\n                        },\n                        \"access\": {\n                          \"enum\": [\n                            \"private\",\n                            \"protected\",\n                            \"public\"\n                          ],\n                          \"default\": \"protected\"\n                        },\n                        \"freshness\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"object\",\n                              \"title\": \"ModelFreshness\",\n                              \"properties\": {\n                                \"build_after\": {\n                                  \"type\": \"object\",\n                                  \"title\": \"ModelBuildAfter\",\n                                  \"properties\": {\n                                    \"count\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"integer\"\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    },\n                                    \"period\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"enum\": [\n                                            \"minute\",\n                                            \"hour\",\n                                            \"day\"\n                                          ]\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    },\n                                    \"updates_on\": {\n                                      \"enum\": [\n                                        \"all\",\n                                        \"any\"\n                                      ],\n                                      \"default\": \"any\"\n                                    }\n                                  },\n                                  \"additionalProperties\": true\n                                }\n                              },\n                              \"additionalProperties\": true,\n                              \"required\": [\n                                \"build_after\"\n                              ]\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": true\n                    },\n                    \"tags\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"description\": {\n                      \"type\": \"string\",\n                      \"default\": \"\"\n                    },\n                    \"columns\": {\n                      \"type\": \"object\",\n                      \"additionalProperties\": {\n                        \"type\": \"object\",\n                        \"title\": \"ColumnInfo\",\n                        \"properties\": {\n                          \"name\": {\n                            \"type\": \"string\"\n                          },\n                          \"description\": {\n                            \"type\": \"string\",\n                            \"default\": \"\"\n                          },\n                          \"meta\": {\n                            \"type\": \"object\",\n                            \"propertyNames\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"data_type\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"constraints\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"object\",\n                              \"title\": \"ColumnLevelConstraint\",\n                              \"properties\": {\n                                \"type\": {\n                                  \"enum\": [\n                                    \"check\",\n                                    \"not_null\",\n                                    \"unique\",\n                                    \"primary_key\",\n                                    \"foreign_key\",\n                                    \"custom\"\n                                  ]\n                                },\n                                \"name\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"string\"\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"expression\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"string\"\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"warn_unenforced\": {\n                                  \"type\": \"boolean\",\n                                  \"default\": true\n                                },\n                                \"warn_unsupported\": {\n                                  \"type\": \"boolean\",\n                                  \"default\": true\n                                },\n                                \"to\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"string\"\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"to_columns\": {\n                                  \"type\": \"array\",\n                                  \"items\": {\n                                    \"type\": \"string\"\n                                  }\n                                }\n                              },\n                              \"additionalProperties\": false,\n                              \"required\": [\n                                \"type\"\n                              ]\n                            }\n                          },\n                          \"quote\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"boolean\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"config\": {\n                            \"type\": \"object\",\n                            \"title\": \"ColumnConfig\",\n                            \"properties\": {\n                              \"_extra\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"meta\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"tags\": {\n                                \"type\": \"array\",\n                                \"items\": {\n                                  \"type\": \"string\"\n                                }\n                              }\n                            },\n                            \"additionalProperties\": true\n                          },\n                          \"tags\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"_extra\": {\n                            \"type\": \"object\",\n                            \"propertyNames\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"granularity\": {\n                            \"anyOf\": [\n                              {\n                                \"enum\": [\n                                  \"nanosecond\",\n                                  \"microsecond\",\n                                  \"millisecond\",\n                                  \"second\",\n                                  \"minute\",\n                                  \"hour\",\n                                  \"day\",\n                                  \"week\",\n                                  \"month\",\n                                  \"quarter\",\n                                  \"year\"\n                                ]\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"dimension\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"object\",\n                                \"title\": \"ColumnDimension\",\n                                \"properties\": {\n                                  \"name\": {\n                                    \"type\": \"string\"\n                                  },\n                                  \"type\": {\n                                    \"enum\": [\n                                      \"categorical\",\n                                      \"time\"\n                                    ]\n                                  },\n                                  \"description\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"label\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"is_partition\": {\n                                    \"type\": \"boolean\",\n                                    \"default\": false\n                                  },\n                                  \"config\": {\n                                    \"type\": \"object\",\n                                    \"propertyNames\": {\n                                      \"type\": \"string\"\n                                    }\n                                  },\n                                  \"validity_params\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"object\",\n                                        \"title\": \"ColumnDimensionValidityParams\",\n                                        \"properties\": {\n                                          \"is_start\": {\n                                            \"type\": \"boolean\",\n                                            \"default\": false\n                                          },\n                                          \"is_end\": {\n                                            \"type\": \"boolean\",\n                                            \"default\": false\n                                          }\n                                        },\n                                        \"additionalProperties\": false\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  }\n                                },\n                                \"additionalProperties\": false,\n                                \"required\": [\n                                  \"name\",\n                                  \"type\"\n                                ]\n                              },\n                              {\n                                \"enum\": [\n                                  \"categorical\",\n                                  \"time\"\n                                ]\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"entity\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"object\",\n                                \"title\": \"ColumnEntity\",\n                                \"properties\": {\n                                  \"name\": {\n                                    \"type\": \"string\"\n                                  },\n                                  \"type\": {\n                                    \"enum\": [\n                                      \"foreign\",\n                                      \"natural\",\n                                      \"primary\",\n                                      \"unique\"\n                                    ]\n                                  },\n                                  \"description\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"label\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"config\": {\n                                    \"type\": \"object\",\n                                    \"propertyNames\": {\n                                      \"type\": \"string\"\n                                    }\n                                  }\n                                },\n                                \"additionalProperties\": false,\n                                \"required\": [\n                                  \"name\",\n                                  \"type\"\n                                ]\n                              },\n                              {\n                                \"enum\": [\n                                  \"foreign\",\n                                  \"natural\",\n                                  \"primary\",\n                                  \"unique\"\n                                ]\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"doc_blocks\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"string\"\n                            }\n                          }\n                        },\n                        \"additionalProperties\": true,\n                        \"required\": [\n                          \"name\"\n                        ]\n                      },\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"meta\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"group\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"docs\": {\n                      \"type\": \"object\",\n                      \"title\": \"Docs\",\n                      \"properties\": {\n                        \"show\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"node_color\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": false\n                    },\n                    \"patch_path\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"build_path\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"unrendered_config\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"created_at\": {\n                      \"type\": \"number\"\n                    },\n                    \"config_call_dict\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"unrendered_config_call_dict\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"relation_name\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"raw_code\": {\n                      \"type\": \"string\",\n                      \"default\": \"\"\n                    },\n                    \"doc_blocks\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"language\": {\n                      \"type\": \"string\",\n                      \"default\": \"sql\"\n                    },\n                    \"refs\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"object\",\n                        \"title\": \"RefArgs\",\n                        \"properties\": {\n                          \"name\": {\n                            \"type\": \"string\"\n                          },\n                          \"package\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"version\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"number\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          }\n                        },\n                        \"additionalProperties\": false,\n                        \"required\": [\n                          \"name\"\n                        ]\n                      }\n                    },\n                    \"sources\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      }\n                    },\n                    \"metrics\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      }\n                    },\n                    \"functions\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      }\n                    },\n                    \"depends_on\": {\n                      \"type\": \"object\",\n                      \"title\": \"DependsOn\",\n                      \"properties\": {\n                        \"macros\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"nodes\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      },\n                      \"additionalProperties\": false\n                    },\n                    \"compiled_path\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"compiled\": {\n                      \"type\": \"boolean\",\n                      \"default\": false\n                    },\n                    \"compiled_code\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"extra_ctes_injected\": {\n                      \"type\": \"boolean\",\n                      \"default\": false\n                    },\n                    \"extra_ctes\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"object\",\n                        \"title\": \"InjectedCTE\",\n                        \"properties\": {\n                          \"id\": {\n                            \"type\": \"string\"\n                          },\n                          \"sql\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"additionalProperties\": false,\n                        \"required\": [\n                          \"id\",\n                          \"sql\"\n                        ]\n                      }\n                    },\n                    \"_pre_injected_sql\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"contract\": {\n                      \"type\": \"object\",\n                      \"title\": \"Contract\",\n                      \"properties\": {\n                        \"enforced\": {\n                          \"type\": \"boolean\",\n                          \"default\": false\n                        },\n                        \"alias_types\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"checksum\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": false\n                    },\n                    \"access\": {\n                      \"enum\": [\n                        \"private\",\n                        \"protected\",\n                        \"public\"\n                      ],\n                      \"default\": \"protected\"\n                    },\n                    \"constraints\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"object\",\n                        \"title\": \"ModelLevelConstraint\",\n                        \"properties\": {\n                          \"type\": {\n                            \"enum\": [\n                              \"check\",\n                              \"not_null\",\n                              \"unique\",\n                              \"primary_key\",\n                              \"foreign_key\",\n                              \"custom\"\n                            ]\n                          },\n                          \"name\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"expression\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"warn_unenforced\": {\n                            \"type\": \"boolean\",\n                            \"default\": true\n                          },\n                          \"warn_unsupported\": {\n                            \"type\": \"boolean\",\n                            \"default\": true\n                          },\n                          \"to\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"to_columns\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"columns\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"string\"\n                            }\n                          }\n                        },\n                        \"additionalProperties\": false,\n                        \"required\": [\n                          \"type\"\n                        ]\n                      }\n                    },\n                    \"version\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"number\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"latest_version\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"number\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"deprecation_date\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"defer_relation\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"object\",\n                          \"title\": \"DeferRelation\",\n                          \"properties\": {\n                            \"database\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ]\n                            },\n                            \"schema\": {\n                              \"type\": \"string\"\n                            },\n                            \"alias\": {\n                              \"type\": \"string\"\n                            },\n                            \"relation_name\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ]\n                            },\n                            \"resource_type\": {\n                              \"enum\": [\n                                \"model\",\n                                \"analysis\",\n                                \"test\",\n                                \"snapshot\",\n                                \"operation\",\n                                \"seed\",\n                                \"rpc\",\n                                \"sql_operation\",\n                                \"doc\",\n                                \"source\",\n                                \"macro\",\n                                \"exposure\",\n                                \"metric\",\n                                \"group\",\n                                \"saved_query\",\n                                \"semantic_model\",\n                                \"unit_test\",\n                                \"fixture\",\n                                \"function\"\n                              ]\n                            },\n                            \"name\": {\n                              \"type\": \"string\"\n                            },\n                            \"description\": {\n                              \"type\": \"string\"\n                            },\n                            \"compiled_code\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ]\n                            },\n                            \"meta\": {\n                              \"type\": \"object\",\n                              \"propertyNames\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            \"tags\": {\n                              \"type\": \"array\",\n                              \"items\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            \"config\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"object\",\n                                  \"title\": \"NodeConfig\",\n                                  \"properties\": {\n                                    \"_extra\": {\n                                      \"type\": \"object\",\n                                      \"propertyNames\": {\n                                        \"type\": \"string\"\n                                      }\n                                    },\n                                    \"enabled\": {\n                                      \"type\": \"boolean\",\n                                      \"default\": true\n                                    },\n                                    \"alias\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"string\"\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    },\n                                    \"schema\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"string\"\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    },\n                                    \"database\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"string\"\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    },\n                                    \"tags\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"array\",\n                                          \"items\": {\n                                            \"type\": \"string\"\n                                          }\n                                        },\n                                        {\n                                          \"type\": \"string\"\n                                        }\n                                      ]\n                                    },\n                                    \"meta\": {\n                                      \"type\": \"object\",\n                                      \"propertyNames\": {\n                                        \"type\": \"string\"\n                                      }\n                                    },\n                                    \"group\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"string\"\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    },\n                                    \"materialized\": {\n                                      \"type\": \"string\",\n                                      \"default\": \"view\"\n                                    },\n                                    \"incremental_strategy\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"string\"\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    },\n                                    \"batch_size\": {\n                                      \"default\": null\n                                    },\n                                    \"lookback\": {\n                                      \"default\": 1\n                                    },\n                                    \"begin\": {\n                                      \"default\": null\n                                    },\n                                    \"persist_docs\": {\n                                      \"type\": \"object\",\n                                      \"propertyNames\": {\n                                        \"type\": \"string\"\n                                      }\n                                    },\n                                    \"post-hook\": {\n                                      \"type\": \"array\",\n                                      \"items\": {\n                                        \"type\": \"object\",\n                                        \"title\": \"Hook\",\n                                        \"properties\": {\n                                          \"sql\": {\n                                            \"type\": \"string\"\n                                          },\n                                          \"transaction\": {\n                                            \"type\": \"boolean\",\n                                            \"default\": true\n                                          },\n                                          \"index\": {\n                                            \"anyOf\": [\n                                              {\n                                                \"type\": \"integer\"\n                                              },\n                                              {\n                                                \"type\": \"null\"\n                                              }\n                                            ],\n                                            \"default\": null\n                                          }\n                                        },\n                                        \"additionalProperties\": false,\n                                        \"required\": [\n                                          \"sql\"\n                                        ]\n                                      }\n                                    },\n                                    \"pre-hook\": {\n                                      \"type\": \"array\",\n                                      \"items\": {\n                                        \"type\": \"object\",\n                                        \"title\": \"Hook\",\n                                        \"properties\": {\n                                          \"sql\": {\n                                            \"type\": \"string\"\n                                          },\n                                          \"transaction\": {\n                                            \"type\": \"boolean\",\n                                            \"default\": true\n                                          },\n                                          \"index\": {\n                                            \"anyOf\": [\n                                              {\n                                                \"type\": \"integer\"\n                                              },\n                                              {\n                                                \"type\": \"null\"\n                                              }\n                                            ],\n                                            \"default\": null\n                                          }\n                                        },\n                                        \"additionalProperties\": false,\n                                        \"required\": [\n                                          \"sql\"\n                                        ]\n                                      }\n                                    },\n                                    \"quoting\": {\n                                      \"type\": \"object\",\n                                      \"propertyNames\": {\n                                        \"type\": \"string\"\n                                      }\n                                    },\n                                    \"column_types\": {\n                                      \"type\": \"object\",\n                                      \"propertyNames\": {\n                                        \"type\": \"string\"\n                                      }\n                                    },\n                                    \"full_refresh\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"boolean\"\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    },\n                                    \"unique_key\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"string\"\n                                        },\n                                        {\n                                          \"type\": \"array\",\n                                          \"items\": {\n                                            \"type\": \"string\"\n                                          }\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    },\n                                    \"on_schema_change\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"string\"\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": \"ignore\"\n                                    },\n                                    \"on_configuration_change\": {\n                                      \"enum\": [\n                                        \"apply\",\n                                        \"continue\",\n                                        \"fail\"\n                                      ]\n                                    },\n                                    \"grants\": {\n                                      \"type\": \"object\",\n                                      \"propertyNames\": {\n                                        \"type\": \"string\"\n                                      }\n                                    },\n                                    \"packages\": {\n                                      \"type\": \"array\",\n                                      \"items\": {\n                                        \"type\": \"string\"\n                                      }\n                                    },\n                                    \"docs\": {\n                                      \"type\": \"object\",\n                                      \"title\": \"Docs\",\n                                      \"properties\": {\n                                        \"show\": {\n                                          \"type\": \"boolean\",\n                                          \"default\": true\n                                        },\n                                        \"node_color\": {\n                                          \"anyOf\": [\n                                            {\n                                              \"type\": \"string\"\n                                            },\n                                            {\n                                              \"type\": \"null\"\n                                            }\n                                          ],\n                                          \"default\": null\n                                        }\n                                      },\n                                      \"additionalProperties\": false\n                                    },\n                                    \"contract\": {\n                                      \"type\": \"object\",\n                                      \"title\": \"ContractConfig\",\n                                      \"properties\": {\n                                        \"enforced\": {\n                                          \"type\": \"boolean\",\n                                          \"default\": false\n                                        },\n                                        \"alias_types\": {\n                                          \"type\": \"boolean\",\n                                          \"default\": true\n                                        }\n                                      },\n                                      \"additionalProperties\": false\n                                    },\n                                    \"event_time\": {\n                                      \"default\": null\n                                    },\n                                    \"concurrent_batches\": {\n                                      \"default\": null\n                                    }\n                                  },\n                                  \"additionalProperties\": true\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ]\n                            }\n                          },\n                          \"additionalProperties\": false,\n                          \"required\": [\n                            \"database\",\n                            \"schema\",\n                            \"alias\",\n                            \"relation_name\",\n                            \"resource_type\",\n                            \"name\",\n                            \"description\",\n                            \"compiled_code\",\n                            \"meta\",\n                            \"tags\",\n                            \"config\"\n                          ]\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"primary_key\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"time_spine\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"object\",\n                          \"title\": \"TimeSpine\",\n                          \"properties\": {\n                            \"standard_granularity_column\": {\n                              \"type\": \"string\"\n                            },\n                            \"custom_granularities\": {\n                              \"type\": \"array\",\n                              \"items\": {\n                                \"type\": \"object\",\n                                \"title\": \"CustomGranularity\",\n                                \"properties\": {\n                                  \"name\": {\n                                    \"type\": \"string\"\n                                  },\n                                  \"column_name\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  }\n                                },\n                                \"additionalProperties\": false,\n                                \"required\": [\n                                  \"name\"\n                                ]\n                              }\n                            }\n                          },\n                          \"additionalProperties\": false,\n                          \"required\": [\n                            \"standard_granularity_column\"\n                          ]\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    }\n                  },\n                  \"additionalProperties\": false,\n                  \"required\": [\n                    \"database\",\n                    \"schema\",\n                    \"name\",\n                    \"resource_type\",\n                    \"package_name\",\n                    \"path\",\n                    \"original_file_path\",\n                    \"unique_id\",\n                    \"fqn\",\n                    \"alias\",\n                    \"checksum\"\n                  ]\n                },\n                {\n                  \"type\": \"object\",\n                  \"title\": \"SqlOperation\",\n                  \"properties\": {\n                    \"database\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ]\n                    },\n                    \"schema\": {\n                      \"type\": \"string\"\n                    },\n                    \"name\": {\n                      \"type\": \"string\"\n                    },\n                    \"resource_type\": {\n                      \"const\": \"sql_operation\"\n                    },\n                    \"package_name\": {\n                      \"type\": \"string\"\n                    },\n                    \"path\": {\n                      \"type\": \"string\"\n                    },\n                    \"original_file_path\": {\n                      \"type\": \"string\"\n                    },\n                    \"unique_id\": {\n                      \"type\": \"string\"\n                    },\n                    \"fqn\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"alias\": {\n                      \"type\": \"string\"\n                    },\n                    \"checksum\": {\n                      \"type\": \"object\",\n                      \"title\": \"FileHash\",\n                      \"properties\": {\n                        \"name\": {\n                          \"type\": \"string\"\n                        },\n                        \"checksum\": {\n                          \"type\": \"string\"\n                        }\n                      },\n                      \"additionalProperties\": false,\n                      \"required\": [\n                        \"name\",\n                        \"checksum\"\n                      ]\n                    },\n                    \"config\": {\n                      \"type\": \"object\",\n                      \"title\": \"NodeConfig\",\n                      \"properties\": {\n                        \"_extra\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"enabled\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"alias\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"schema\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"database\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"tags\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"array\",\n                              \"items\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            {\n                              \"type\": \"string\"\n                            }\n                          ]\n                        },\n                        \"meta\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"group\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"materialized\": {\n                          \"type\": \"string\",\n                          \"default\": \"view\"\n                        },\n                        \"incremental_strategy\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"batch_size\": {\n                          \"default\": null\n                        },\n                        \"lookback\": {\n                          \"default\": 1\n                        },\n                        \"begin\": {\n                          \"default\": null\n                        },\n                        \"persist_docs\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"post-hook\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"object\",\n                            \"title\": \"Hook\",\n                            \"properties\": {\n                              \"sql\": {\n                                \"type\": \"string\"\n                              },\n                              \"transaction\": {\n                                \"type\": \"boolean\",\n                                \"default\": true\n                              },\n                              \"index\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"integer\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              }\n                            },\n                            \"additionalProperties\": false,\n                            \"required\": [\n                              \"sql\"\n                            ]\n                          }\n                        },\n                        \"pre-hook\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"object\",\n                            \"title\": \"Hook\",\n                            \"properties\": {\n                              \"sql\": {\n                                \"type\": \"string\"\n                              },\n                              \"transaction\": {\n                                \"type\": \"boolean\",\n                                \"default\": true\n                              },\n                              \"index\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"integer\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              }\n                            },\n                            \"additionalProperties\": false,\n                            \"required\": [\n                              \"sql\"\n                            ]\n                          }\n                        },\n                        \"quoting\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"column_types\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"full_refresh\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"boolean\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"unique_key\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"array\",\n                              \"items\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"on_schema_change\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": \"ignore\"\n                        },\n                        \"on_configuration_change\": {\n                          \"enum\": [\n                            \"apply\",\n                            \"continue\",\n                            \"fail\"\n                          ]\n                        },\n                        \"grants\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"packages\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"docs\": {\n                          \"type\": \"object\",\n                          \"title\": \"Docs\",\n                          \"properties\": {\n                            \"show\": {\n                              \"type\": \"boolean\",\n                              \"default\": true\n                            },\n                            \"node_color\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            }\n                          },\n                          \"additionalProperties\": false\n                        },\n                        \"contract\": {\n                          \"type\": \"object\",\n                          \"title\": \"ContractConfig\",\n                          \"properties\": {\n                            \"enforced\": {\n                              \"type\": \"boolean\",\n                              \"default\": false\n                            },\n                            \"alias_types\": {\n                              \"type\": \"boolean\",\n                              \"default\": true\n                            }\n                          },\n                          \"additionalProperties\": false\n                        },\n                        \"event_time\": {\n                          \"default\": null\n                        },\n                        \"concurrent_batches\": {\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": true\n                    },\n                    \"tags\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"description\": {\n                      \"type\": \"string\",\n                      \"default\": \"\"\n                    },\n                    \"columns\": {\n                      \"type\": \"object\",\n                      \"additionalProperties\": {\n                        \"type\": \"object\",\n                        \"title\": \"ColumnInfo\",\n                        \"properties\": {\n                          \"name\": {\n                            \"type\": \"string\"\n                          },\n                          \"description\": {\n                            \"type\": \"string\",\n                            \"default\": \"\"\n                          },\n                          \"meta\": {\n                            \"type\": \"object\",\n                            \"propertyNames\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"data_type\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"constraints\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"object\",\n                              \"title\": \"ColumnLevelConstraint\",\n                              \"properties\": {\n                                \"type\": {\n                                  \"enum\": [\n                                    \"check\",\n                                    \"not_null\",\n                                    \"unique\",\n                                    \"primary_key\",\n                                    \"foreign_key\",\n                                    \"custom\"\n                                  ]\n                                },\n                                \"name\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"string\"\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"expression\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"string\"\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"warn_unenforced\": {\n                                  \"type\": \"boolean\",\n                                  \"default\": true\n                                },\n                                \"warn_unsupported\": {\n                                  \"type\": \"boolean\",\n                                  \"default\": true\n                                },\n                                \"to\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"string\"\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"to_columns\": {\n                                  \"type\": \"array\",\n                                  \"items\": {\n                                    \"type\": \"string\"\n                                  }\n                                }\n                              },\n                              \"additionalProperties\": false,\n                              \"required\": [\n                                \"type\"\n                              ]\n                            }\n                          },\n                          \"quote\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"boolean\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"config\": {\n                            \"type\": \"object\",\n                            \"title\": \"ColumnConfig\",\n                            \"properties\": {\n                              \"_extra\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"meta\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"tags\": {\n                                \"type\": \"array\",\n                                \"items\": {\n                                  \"type\": \"string\"\n                                }\n                              }\n                            },\n                            \"additionalProperties\": true\n                          },\n                          \"tags\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"_extra\": {\n                            \"type\": \"object\",\n                            \"propertyNames\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"granularity\": {\n                            \"anyOf\": [\n                              {\n                                \"enum\": [\n                                  \"nanosecond\",\n                                  \"microsecond\",\n                                  \"millisecond\",\n                                  \"second\",\n                                  \"minute\",\n                                  \"hour\",\n                                  \"day\",\n                                  \"week\",\n                                  \"month\",\n                                  \"quarter\",\n                                  \"year\"\n                                ]\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"dimension\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"object\",\n                                \"title\": \"ColumnDimension\",\n                                \"properties\": {\n                                  \"name\": {\n                                    \"type\": \"string\"\n                                  },\n                                  \"type\": {\n                                    \"enum\": [\n                                      \"categorical\",\n                                      \"time\"\n                                    ]\n                                  },\n                                  \"description\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"label\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"is_partition\": {\n                                    \"type\": \"boolean\",\n                                    \"default\": false\n                                  },\n                                  \"config\": {\n                                    \"type\": \"object\",\n                                    \"propertyNames\": {\n                                      \"type\": \"string\"\n                                    }\n                                  },\n                                  \"validity_params\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"object\",\n                                        \"title\": \"ColumnDimensionValidityParams\",\n                                        \"properties\": {\n                                          \"is_start\": {\n                                            \"type\": \"boolean\",\n                                            \"default\": false\n                                          },\n                                          \"is_end\": {\n                                            \"type\": \"boolean\",\n                                            \"default\": false\n                                          }\n                                        },\n                                        \"additionalProperties\": false\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  }\n                                },\n                                \"additionalProperties\": false,\n                                \"required\": [\n                                  \"name\",\n                                  \"type\"\n                                ]\n                              },\n                              {\n                                \"enum\": [\n                                  \"categorical\",\n                                  \"time\"\n                                ]\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"entity\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"object\",\n                                \"title\": \"ColumnEntity\",\n                                \"properties\": {\n                                  \"name\": {\n                                    \"type\": \"string\"\n                                  },\n                                  \"type\": {\n                                    \"enum\": [\n                                      \"foreign\",\n                                      \"natural\",\n                                      \"primary\",\n                                      \"unique\"\n                                    ]\n                                  },\n                                  \"description\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"label\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"config\": {\n                                    \"type\": \"object\",\n                                    \"propertyNames\": {\n                                      \"type\": \"string\"\n                                    }\n                                  }\n                                },\n                                \"additionalProperties\": false,\n                                \"required\": [\n                                  \"name\",\n                                  \"type\"\n                                ]\n                              },\n                              {\n                                \"enum\": [\n                                  \"foreign\",\n                                  \"natural\",\n                                  \"primary\",\n                                  \"unique\"\n                                ]\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"doc_blocks\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"string\"\n                            }\n                          }\n                        },\n                        \"additionalProperties\": true,\n                        \"required\": [\n                          \"name\"\n                        ]\n                      },\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"meta\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"group\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"docs\": {\n                      \"type\": \"object\",\n                      \"title\": \"Docs\",\n                      \"properties\": {\n                        \"show\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"node_color\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": false\n                    },\n                    \"patch_path\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"build_path\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"unrendered_config\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"created_at\": {\n                      \"type\": \"number\"\n                    },\n                    \"config_call_dict\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"unrendered_config_call_dict\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"relation_name\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"raw_code\": {\n                      \"type\": \"string\",\n                      \"default\": \"\"\n                    },\n                    \"doc_blocks\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"language\": {\n                      \"type\": \"string\",\n                      \"default\": \"sql\"\n                    },\n                    \"refs\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"object\",\n                        \"title\": \"RefArgs\",\n                        \"properties\": {\n                          \"name\": {\n                            \"type\": \"string\"\n                          },\n                          \"package\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"version\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"number\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          }\n                        },\n                        \"additionalProperties\": false,\n                        \"required\": [\n                          \"name\"\n                        ]\n                      }\n                    },\n                    \"sources\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      }\n                    },\n                    \"metrics\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      }\n                    },\n                    \"functions\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      }\n                    },\n                    \"depends_on\": {\n                      \"type\": \"object\",\n                      \"title\": \"DependsOn\",\n                      \"properties\": {\n                        \"macros\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"nodes\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      },\n                      \"additionalProperties\": false\n                    },\n                    \"compiled_path\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"compiled\": {\n                      \"type\": \"boolean\",\n                      \"default\": false\n                    },\n                    \"compiled_code\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"extra_ctes_injected\": {\n                      \"type\": \"boolean\",\n                      \"default\": false\n                    },\n                    \"extra_ctes\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"object\",\n                        \"title\": \"InjectedCTE\",\n                        \"properties\": {\n                          \"id\": {\n                            \"type\": \"string\"\n                          },\n                          \"sql\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"additionalProperties\": false,\n                        \"required\": [\n                          \"id\",\n                          \"sql\"\n                        ]\n                      }\n                    },\n                    \"_pre_injected_sql\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"contract\": {\n                      \"type\": \"object\",\n                      \"title\": \"Contract\",\n                      \"properties\": {\n                        \"enforced\": {\n                          \"type\": \"boolean\",\n                          \"default\": false\n                        },\n                        \"alias_types\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"checksum\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": false\n                    }\n                  },\n                  \"additionalProperties\": false,\n                  \"required\": [\n                    \"database\",\n                    \"schema\",\n                    \"name\",\n                    \"resource_type\",\n                    \"package_name\",\n                    \"path\",\n                    \"original_file_path\",\n                    \"unique_id\",\n                    \"fqn\",\n                    \"alias\",\n                    \"checksum\"\n                  ]\n                },\n                {\n                  \"type\": \"object\",\n                  \"title\": \"GenericTest\",\n                  \"properties\": {\n                    \"database\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ]\n                    },\n                    \"schema\": {\n                      \"type\": \"string\"\n                    },\n                    \"name\": {\n                      \"type\": \"string\"\n                    },\n                    \"resource_type\": {\n                      \"const\": \"test\"\n                    },\n                    \"package_name\": {\n                      \"type\": \"string\"\n                    },\n                    \"path\": {\n                      \"type\": \"string\"\n                    },\n                    \"original_file_path\": {\n                      \"type\": \"string\"\n                    },\n                    \"unique_id\": {\n                      \"type\": \"string\"\n                    },\n                    \"fqn\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"alias\": {\n                      \"type\": \"string\"\n                    },\n                    \"checksum\": {\n                      \"type\": \"object\",\n                      \"title\": \"FileHash\",\n                      \"properties\": {\n                        \"name\": {\n                          \"type\": \"string\"\n                        },\n                        \"checksum\": {\n                          \"type\": \"string\"\n                        }\n                      },\n                      \"additionalProperties\": false,\n                      \"required\": [\n                        \"name\",\n                        \"checksum\"\n                      ]\n                    },\n                    \"config\": {\n                      \"type\": \"object\",\n                      \"title\": \"TestConfig\",\n                      \"properties\": {\n                        \"_extra\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"enabled\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"alias\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"schema\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": \"dbt_test__audit\"\n                        },\n                        \"database\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"tags\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"array\",\n                              \"items\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            {\n                              \"type\": \"string\"\n                            }\n                          ]\n                        },\n                        \"meta\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"group\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"materialized\": {\n                          \"type\": \"string\",\n                          \"default\": \"test\"\n                        },\n                        \"severity\": {\n                          \"type\": \"string\",\n                          \"default\": \"ERROR\",\n                          \"pattern\": \"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$\"\n                        },\n                        \"store_failures\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"boolean\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"store_failures_as\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"sql_header\": {\n                          \"default\": null\n                        },\n                        \"where\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"limit\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"integer\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"fail_calc\": {\n                          \"type\": \"string\",\n                          \"default\": \"count(*)\"\n                        },\n                        \"warn_if\": {\n                          \"type\": \"string\",\n                          \"default\": \"!= 0\"\n                        },\n                        \"error_if\": {\n                          \"type\": \"string\",\n                          \"default\": \"!= 0\"\n                        }\n                      },\n                      \"additionalProperties\": true\n                    },\n                    \"tags\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"description\": {\n                      \"type\": \"string\",\n                      \"default\": \"\"\n                    },\n                    \"columns\": {\n                      \"type\": \"object\",\n                      \"additionalProperties\": {\n                        \"type\": \"object\",\n                        \"title\": \"ColumnInfo\",\n                        \"properties\": {\n                          \"name\": {\n                            \"type\": \"string\"\n                          },\n                          \"description\": {\n                            \"type\": \"string\",\n                            \"default\": \"\"\n                          },\n                          \"meta\": {\n                            \"type\": \"object\",\n                            \"propertyNames\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"data_type\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"constraints\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"object\",\n                              \"title\": \"ColumnLevelConstraint\",\n                              \"properties\": {\n                                \"type\": {\n                                  \"enum\": [\n                                    \"check\",\n                                    \"not_null\",\n                                    \"unique\",\n                                    \"primary_key\",\n                                    \"foreign_key\",\n                                    \"custom\"\n                                  ]\n                                },\n                                \"name\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"string\"\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"expression\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"string\"\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"warn_unenforced\": {\n                                  \"type\": \"boolean\",\n                                  \"default\": true\n                                },\n                                \"warn_unsupported\": {\n                                  \"type\": \"boolean\",\n                                  \"default\": true\n                                },\n                                \"to\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"string\"\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"to_columns\": {\n                                  \"type\": \"array\",\n                                  \"items\": {\n                                    \"type\": \"string\"\n                                  }\n                                }\n                              },\n                              \"additionalProperties\": false,\n                              \"required\": [\n                                \"type\"\n                              ]\n                            }\n                          },\n                          \"quote\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"boolean\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"config\": {\n                            \"type\": \"object\",\n                            \"title\": \"ColumnConfig\",\n                            \"properties\": {\n                              \"_extra\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"meta\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"tags\": {\n                                \"type\": \"array\",\n                                \"items\": {\n                                  \"type\": \"string\"\n                                }\n                              }\n                            },\n                            \"additionalProperties\": true\n                          },\n                          \"tags\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"_extra\": {\n                            \"type\": \"object\",\n                            \"propertyNames\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"granularity\": {\n                            \"anyOf\": [\n                              {\n                                \"enum\": [\n                                  \"nanosecond\",\n                                  \"microsecond\",\n                                  \"millisecond\",\n                                  \"second\",\n                                  \"minute\",\n                                  \"hour\",\n                                  \"day\",\n                                  \"week\",\n                                  \"month\",\n                                  \"quarter\",\n                                  \"year\"\n                                ]\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"dimension\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"object\",\n                                \"title\": \"ColumnDimension\",\n                                \"properties\": {\n                                  \"name\": {\n                                    \"type\": \"string\"\n                                  },\n                                  \"type\": {\n                                    \"enum\": [\n                                      \"categorical\",\n                                      \"time\"\n                                    ]\n                                  },\n                                  \"description\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"label\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"is_partition\": {\n                                    \"type\": \"boolean\",\n                                    \"default\": false\n                                  },\n                                  \"config\": {\n                                    \"type\": \"object\",\n                                    \"propertyNames\": {\n                                      \"type\": \"string\"\n                                    }\n                                  },\n                                  \"validity_params\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"object\",\n                                        \"title\": \"ColumnDimensionValidityParams\",\n                                        \"properties\": {\n                                          \"is_start\": {\n                                            \"type\": \"boolean\",\n                                            \"default\": false\n                                          },\n                                          \"is_end\": {\n                                            \"type\": \"boolean\",\n                                            \"default\": false\n                                          }\n                                        },\n                                        \"additionalProperties\": false\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  }\n                                },\n                                \"additionalProperties\": false,\n                                \"required\": [\n                                  \"name\",\n                                  \"type\"\n                                ]\n                              },\n                              {\n                                \"enum\": [\n                                  \"categorical\",\n                                  \"time\"\n                                ]\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"entity\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"object\",\n                                \"title\": \"ColumnEntity\",\n                                \"properties\": {\n                                  \"name\": {\n                                    \"type\": \"string\"\n                                  },\n                                  \"type\": {\n                                    \"enum\": [\n                                      \"foreign\",\n                                      \"natural\",\n                                      \"primary\",\n                                      \"unique\"\n                                    ]\n                                  },\n                                  \"description\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"label\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"config\": {\n                                    \"type\": \"object\",\n                                    \"propertyNames\": {\n                                      \"type\": \"string\"\n                                    }\n                                  }\n                                },\n                                \"additionalProperties\": false,\n                                \"required\": [\n                                  \"name\",\n                                  \"type\"\n                                ]\n                              },\n                              {\n                                \"enum\": [\n                                  \"foreign\",\n                                  \"natural\",\n                                  \"primary\",\n                                  \"unique\"\n                                ]\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"doc_blocks\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"string\"\n                            }\n                          }\n                        },\n                        \"additionalProperties\": true,\n                        \"required\": [\n                          \"name\"\n                        ]\n                      },\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"meta\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"group\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"docs\": {\n                      \"type\": \"object\",\n                      \"title\": \"Docs\",\n                      \"properties\": {\n                        \"show\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"node_color\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": false\n                    },\n                    \"patch_path\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"build_path\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"unrendered_config\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"created_at\": {\n                      \"type\": \"number\"\n                    },\n                    \"config_call_dict\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"unrendered_config_call_dict\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"relation_name\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"raw_code\": {\n                      \"type\": \"string\",\n                      \"default\": \"\"\n                    },\n                    \"doc_blocks\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"language\": {\n                      \"type\": \"string\",\n                      \"default\": \"sql\"\n                    },\n                    \"refs\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"object\",\n                        \"title\": \"RefArgs\",\n                        \"properties\": {\n                          \"name\": {\n                            \"type\": \"string\"\n                          },\n                          \"package\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"version\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"number\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          }\n                        },\n                        \"additionalProperties\": false,\n                        \"required\": [\n                          \"name\"\n                        ]\n                      }\n                    },\n                    \"sources\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      }\n                    },\n                    \"metrics\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      }\n                    },\n                    \"functions\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      }\n                    },\n                    \"depends_on\": {\n                      \"type\": \"object\",\n                      \"title\": \"DependsOn\",\n                      \"properties\": {\n                        \"macros\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"nodes\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      },\n                      \"additionalProperties\": false\n                    },\n                    \"compiled_path\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"compiled\": {\n                      \"type\": \"boolean\",\n                      \"default\": false\n                    },\n                    \"compiled_code\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"extra_ctes_injected\": {\n                      \"type\": \"boolean\",\n                      \"default\": false\n                    },\n                    \"extra_ctes\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"object\",\n                        \"title\": \"InjectedCTE\",\n                        \"properties\": {\n                          \"id\": {\n                            \"type\": \"string\"\n                          },\n                          \"sql\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"additionalProperties\": false,\n                        \"required\": [\n                          \"id\",\n                          \"sql\"\n                        ]\n                      }\n                    },\n                    \"_pre_injected_sql\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"contract\": {\n                      \"type\": \"object\",\n                      \"title\": \"Contract\",\n                      \"properties\": {\n                        \"enforced\": {\n                          \"type\": \"boolean\",\n                          \"default\": false\n                        },\n                        \"alias_types\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"checksum\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": false\n                    },\n                    \"column_name\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"file_key_name\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"attached_node\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"test_metadata\": {\n                      \"type\": \"object\",\n                      \"title\": \"TestMetadata\",\n                      \"properties\": {\n                        \"name\": {\n                          \"type\": \"string\",\n                          \"default\": \"test\"\n                        },\n                        \"kwargs\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"namespace\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": false\n                    }\n                  },\n                  \"additionalProperties\": false,\n                  \"required\": [\n                    \"database\",\n                    \"schema\",\n                    \"name\",\n                    \"resource_type\",\n                    \"package_name\",\n                    \"path\",\n                    \"original_file_path\",\n                    \"unique_id\",\n                    \"fqn\",\n                    \"alias\",\n                    \"checksum\"\n                  ]\n                },\n                {\n                  \"type\": \"object\",\n                  \"title\": \"Snapshot\",\n                  \"properties\": {\n                    \"database\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ]\n                    },\n                    \"schema\": {\n                      \"type\": \"string\"\n                    },\n                    \"name\": {\n                      \"type\": \"string\"\n                    },\n                    \"resource_type\": {\n                      \"const\": \"snapshot\"\n                    },\n                    \"package_name\": {\n                      \"type\": \"string\"\n                    },\n                    \"path\": {\n                      \"type\": \"string\"\n                    },\n                    \"original_file_path\": {\n                      \"type\": \"string\"\n                    },\n                    \"unique_id\": {\n                      \"type\": \"string\"\n                    },\n                    \"fqn\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"alias\": {\n                      \"type\": \"string\"\n                    },\n                    \"checksum\": {\n                      \"type\": \"object\",\n                      \"title\": \"FileHash\",\n                      \"properties\": {\n                        \"name\": {\n                          \"type\": \"string\"\n                        },\n                        \"checksum\": {\n                          \"type\": \"string\"\n                        }\n                      },\n                      \"additionalProperties\": false,\n                      \"required\": [\n                        \"name\",\n                        \"checksum\"\n                      ]\n                    },\n                    \"config\": {\n                      \"type\": \"object\",\n                      \"title\": \"SnapshotConfig\",\n                      \"properties\": {\n                        \"_extra\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"enabled\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"alias\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"schema\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"database\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"tags\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"array\",\n                              \"items\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            {\n                              \"type\": \"string\"\n                            }\n                          ]\n                        },\n                        \"meta\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"group\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"materialized\": {\n                          \"type\": \"string\",\n                          \"default\": \"snapshot\"\n                        },\n                        \"incremental_strategy\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"batch_size\": {\n                          \"default\": null\n                        },\n                        \"lookback\": {\n                          \"default\": 1\n                        },\n                        \"begin\": {\n                          \"default\": null\n                        },\n                        \"persist_docs\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"post-hook\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"object\",\n                            \"title\": \"Hook\",\n                            \"properties\": {\n                              \"sql\": {\n                                \"type\": \"string\"\n                              },\n                              \"transaction\": {\n                                \"type\": \"boolean\",\n                                \"default\": true\n                              },\n                              \"index\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"integer\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              }\n                            },\n                            \"additionalProperties\": false,\n                            \"required\": [\n                              \"sql\"\n                            ]\n                          }\n                        },\n                        \"pre-hook\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"object\",\n                            \"title\": \"Hook\",\n                            \"properties\": {\n                              \"sql\": {\n                                \"type\": \"string\"\n                              },\n                              \"transaction\": {\n                                \"type\": \"boolean\",\n                                \"default\": true\n                              },\n                              \"index\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"integer\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              }\n                            },\n                            \"additionalProperties\": false,\n                            \"required\": [\n                              \"sql\"\n                            ]\n                          }\n                        },\n                        \"quoting\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"column_types\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"full_refresh\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"boolean\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"unique_key\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"array\",\n                              \"items\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"on_schema_change\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": \"ignore\"\n                        },\n                        \"on_configuration_change\": {\n                          \"enum\": [\n                            \"apply\",\n                            \"continue\",\n                            \"fail\"\n                          ]\n                        },\n                        \"grants\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"packages\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"docs\": {\n                          \"type\": \"object\",\n                          \"title\": \"Docs\",\n                          \"properties\": {\n                            \"show\": {\n                              \"type\": \"boolean\",\n                              \"default\": true\n                            },\n                            \"node_color\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            }\n                          },\n                          \"additionalProperties\": false\n                        },\n                        \"contract\": {\n                          \"type\": \"object\",\n                          \"title\": \"ContractConfig\",\n                          \"properties\": {\n                            \"enforced\": {\n                              \"type\": \"boolean\",\n                              \"default\": false\n                            },\n                            \"alias_types\": {\n                              \"type\": \"boolean\",\n                              \"default\": true\n                            }\n                          },\n                          \"additionalProperties\": false\n                        },\n                        \"event_time\": {\n                          \"default\": null\n                        },\n                        \"concurrent_batches\": {\n                          \"default\": null\n                        },\n                        \"strategy\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"target_schema\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"target_database\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"updated_at\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"check_cols\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"array\",\n                              \"items\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"snapshot_meta_column_names\": {\n                          \"type\": \"object\",\n                          \"title\": \"SnapshotMetaColumnNames\",\n                          \"properties\": {\n                            \"dbt_valid_to\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"dbt_valid_from\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"dbt_scd_id\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"dbt_updated_at\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"dbt_is_deleted\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            }\n                          },\n                          \"additionalProperties\": false\n                        },\n                        \"dbt_valid_to_current\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": true\n                    },\n                    \"tags\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"description\": {\n                      \"type\": \"string\",\n                      \"default\": \"\"\n                    },\n                    \"columns\": {\n                      \"type\": \"object\",\n                      \"additionalProperties\": {\n                        \"type\": \"object\",\n                        \"title\": \"ColumnInfo\",\n                        \"properties\": {\n                          \"name\": {\n                            \"type\": \"string\"\n                          },\n                          \"description\": {\n                            \"type\": \"string\",\n                            \"default\": \"\"\n                          },\n                          \"meta\": {\n                            \"type\": \"object\",\n                            \"propertyNames\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"data_type\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"constraints\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"object\",\n                              \"title\": \"ColumnLevelConstraint\",\n                              \"properties\": {\n                                \"type\": {\n                                  \"enum\": [\n                                    \"check\",\n                                    \"not_null\",\n                                    \"unique\",\n                                    \"primary_key\",\n                                    \"foreign_key\",\n                                    \"custom\"\n                                  ]\n                                },\n                                \"name\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"string\"\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"expression\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"string\"\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"warn_unenforced\": {\n                                  \"type\": \"boolean\",\n                                  \"default\": true\n                                },\n                                \"warn_unsupported\": {\n                                  \"type\": \"boolean\",\n                                  \"default\": true\n                                },\n                                \"to\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"string\"\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"to_columns\": {\n                                  \"type\": \"array\",\n                                  \"items\": {\n                                    \"type\": \"string\"\n                                  }\n                                }\n                              },\n                              \"additionalProperties\": false,\n                              \"required\": [\n                                \"type\"\n                              ]\n                            }\n                          },\n                          \"quote\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"boolean\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"config\": {\n                            \"type\": \"object\",\n                            \"title\": \"ColumnConfig\",\n                            \"properties\": {\n                              \"_extra\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"meta\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"tags\": {\n                                \"type\": \"array\",\n                                \"items\": {\n                                  \"type\": \"string\"\n                                }\n                              }\n                            },\n                            \"additionalProperties\": true\n                          },\n                          \"tags\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"_extra\": {\n                            \"type\": \"object\",\n                            \"propertyNames\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"granularity\": {\n                            \"anyOf\": [\n                              {\n                                \"enum\": [\n                                  \"nanosecond\",\n                                  \"microsecond\",\n                                  \"millisecond\",\n                                  \"second\",\n                                  \"minute\",\n                                  \"hour\",\n                                  \"day\",\n                                  \"week\",\n                                  \"month\",\n                                  \"quarter\",\n                                  \"year\"\n                                ]\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"dimension\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"object\",\n                                \"title\": \"ColumnDimension\",\n                                \"properties\": {\n                                  \"name\": {\n                                    \"type\": \"string\"\n                                  },\n                                  \"type\": {\n                                    \"enum\": [\n                                      \"categorical\",\n                                      \"time\"\n                                    ]\n                                  },\n                                  \"description\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"label\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"is_partition\": {\n                                    \"type\": \"boolean\",\n                                    \"default\": false\n                                  },\n                                  \"config\": {\n                                    \"type\": \"object\",\n                                    \"propertyNames\": {\n                                      \"type\": \"string\"\n                                    }\n                                  },\n                                  \"validity_params\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"object\",\n                                        \"title\": \"ColumnDimensionValidityParams\",\n                                        \"properties\": {\n                                          \"is_start\": {\n                                            \"type\": \"boolean\",\n                                            \"default\": false\n                                          },\n                                          \"is_end\": {\n                                            \"type\": \"boolean\",\n                                            \"default\": false\n                                          }\n                                        },\n                                        \"additionalProperties\": false\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  }\n                                },\n                                \"additionalProperties\": false,\n                                \"required\": [\n                                  \"name\",\n                                  \"type\"\n                                ]\n                              },\n                              {\n                                \"enum\": [\n                                  \"categorical\",\n                                  \"time\"\n                                ]\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"entity\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"object\",\n                                \"title\": \"ColumnEntity\",\n                                \"properties\": {\n                                  \"name\": {\n                                    \"type\": \"string\"\n                                  },\n                                  \"type\": {\n                                    \"enum\": [\n                                      \"foreign\",\n                                      \"natural\",\n                                      \"primary\",\n                                      \"unique\"\n                                    ]\n                                  },\n                                  \"description\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"label\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"config\": {\n                                    \"type\": \"object\",\n                                    \"propertyNames\": {\n                                      \"type\": \"string\"\n                                    }\n                                  }\n                                },\n                                \"additionalProperties\": false,\n                                \"required\": [\n                                  \"name\",\n                                  \"type\"\n                                ]\n                              },\n                              {\n                                \"enum\": [\n                                  \"foreign\",\n                                  \"natural\",\n                                  \"primary\",\n                                  \"unique\"\n                                ]\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"doc_blocks\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"string\"\n                            }\n                          }\n                        },\n                        \"additionalProperties\": true,\n                        \"required\": [\n                          \"name\"\n                        ]\n                      },\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"meta\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"group\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"docs\": {\n                      \"type\": \"object\",\n                      \"title\": \"Docs\",\n                      \"properties\": {\n                        \"show\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"node_color\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": false\n                    },\n                    \"patch_path\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"build_path\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"unrendered_config\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"created_at\": {\n                      \"type\": \"number\"\n                    },\n                    \"config_call_dict\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"unrendered_config_call_dict\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"relation_name\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"raw_code\": {\n                      \"type\": \"string\",\n                      \"default\": \"\"\n                    },\n                    \"doc_blocks\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"language\": {\n                      \"type\": \"string\",\n                      \"default\": \"sql\"\n                    },\n                    \"refs\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"object\",\n                        \"title\": \"RefArgs\",\n                        \"properties\": {\n                          \"name\": {\n                            \"type\": \"string\"\n                          },\n                          \"package\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"version\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"number\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          }\n                        },\n                        \"additionalProperties\": false,\n                        \"required\": [\n                          \"name\"\n                        ]\n                      }\n                    },\n                    \"sources\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      }\n                    },\n                    \"metrics\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      }\n                    },\n                    \"functions\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      }\n                    },\n                    \"depends_on\": {\n                      \"type\": \"object\",\n                      \"title\": \"DependsOn\",\n                      \"properties\": {\n                        \"macros\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"nodes\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      },\n                      \"additionalProperties\": false\n                    },\n                    \"compiled_path\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"compiled\": {\n                      \"type\": \"boolean\",\n                      \"default\": false\n                    },\n                    \"compiled_code\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"extra_ctes_injected\": {\n                      \"type\": \"boolean\",\n                      \"default\": false\n                    },\n                    \"extra_ctes\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"object\",\n                        \"title\": \"InjectedCTE\",\n                        \"properties\": {\n                          \"id\": {\n                            \"type\": \"string\"\n                          },\n                          \"sql\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"additionalProperties\": false,\n                        \"required\": [\n                          \"id\",\n                          \"sql\"\n                        ]\n                      }\n                    },\n                    \"_pre_injected_sql\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"contract\": {\n                      \"type\": \"object\",\n                      \"title\": \"Contract\",\n                      \"properties\": {\n                        \"enforced\": {\n                          \"type\": \"boolean\",\n                          \"default\": false\n                        },\n                        \"alias_types\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"checksum\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": false\n                    },\n                    \"defer_relation\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"object\",\n                          \"title\": \"DeferRelation\",\n                          \"properties\": {\n                            \"database\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ]\n                            },\n                            \"schema\": {\n                              \"type\": \"string\"\n                            },\n                            \"alias\": {\n                              \"type\": \"string\"\n                            },\n                            \"relation_name\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ]\n                            },\n                            \"resource_type\": {\n                              \"enum\": [\n                                \"model\",\n                                \"analysis\",\n                                \"test\",\n                                \"snapshot\",\n                                \"operation\",\n                                \"seed\",\n                                \"rpc\",\n                                \"sql_operation\",\n                                \"doc\",\n                                \"source\",\n                                \"macro\",\n                                \"exposure\",\n                                \"metric\",\n                                \"group\",\n                                \"saved_query\",\n                                \"semantic_model\",\n                                \"unit_test\",\n                                \"fixture\",\n                                \"function\"\n                              ]\n                            },\n                            \"name\": {\n                              \"type\": \"string\"\n                            },\n                            \"description\": {\n                              \"type\": \"string\"\n                            },\n                            \"compiled_code\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ]\n                            },\n                            \"meta\": {\n                              \"type\": \"object\",\n                              \"propertyNames\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            \"tags\": {\n                              \"type\": \"array\",\n                              \"items\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            \"config\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"object\",\n                                  \"title\": \"NodeConfig\",\n                                  \"properties\": {\n                                    \"_extra\": {\n                                      \"type\": \"object\",\n                                      \"propertyNames\": {\n                                        \"type\": \"string\"\n                                      }\n                                    },\n                                    \"enabled\": {\n                                      \"type\": \"boolean\",\n                                      \"default\": true\n                                    },\n                                    \"alias\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"string\"\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    },\n                                    \"schema\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"string\"\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    },\n                                    \"database\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"string\"\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    },\n                                    \"tags\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"array\",\n                                          \"items\": {\n                                            \"type\": \"string\"\n                                          }\n                                        },\n                                        {\n                                          \"type\": \"string\"\n                                        }\n                                      ]\n                                    },\n                                    \"meta\": {\n                                      \"type\": \"object\",\n                                      \"propertyNames\": {\n                                        \"type\": \"string\"\n                                      }\n                                    },\n                                    \"group\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"string\"\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    },\n                                    \"materialized\": {\n                                      \"type\": \"string\",\n                                      \"default\": \"view\"\n                                    },\n                                    \"incremental_strategy\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"string\"\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    },\n                                    \"batch_size\": {\n                                      \"default\": null\n                                    },\n                                    \"lookback\": {\n                                      \"default\": 1\n                                    },\n                                    \"begin\": {\n                                      \"default\": null\n                                    },\n                                    \"persist_docs\": {\n                                      \"type\": \"object\",\n                                      \"propertyNames\": {\n                                        \"type\": \"string\"\n                                      }\n                                    },\n                                    \"post-hook\": {\n                                      \"type\": \"array\",\n                                      \"items\": {\n                                        \"type\": \"object\",\n                                        \"title\": \"Hook\",\n                                        \"properties\": {\n                                          \"sql\": {\n                                            \"type\": \"string\"\n                                          },\n                                          \"transaction\": {\n                                            \"type\": \"boolean\",\n                                            \"default\": true\n                                          },\n                                          \"index\": {\n                                            \"anyOf\": [\n                                              {\n                                                \"type\": \"integer\"\n                                              },\n                                              {\n                                                \"type\": \"null\"\n                                              }\n                                            ],\n                                            \"default\": null\n                                          }\n                                        },\n                                        \"additionalProperties\": false,\n                                        \"required\": [\n                                          \"sql\"\n                                        ]\n                                      }\n                                    },\n                                    \"pre-hook\": {\n                                      \"type\": \"array\",\n                                      \"items\": {\n                                        \"type\": \"object\",\n                                        \"title\": \"Hook\",\n                                        \"properties\": {\n                                          \"sql\": {\n                                            \"type\": \"string\"\n                                          },\n                                          \"transaction\": {\n                                            \"type\": \"boolean\",\n                                            \"default\": true\n                                          },\n                                          \"index\": {\n                                            \"anyOf\": [\n                                              {\n                                                \"type\": \"integer\"\n                                              },\n                                              {\n                                                \"type\": \"null\"\n                                              }\n                                            ],\n                                            \"default\": null\n                                          }\n                                        },\n                                        \"additionalProperties\": false,\n                                        \"required\": [\n                                          \"sql\"\n                                        ]\n                                      }\n                                    },\n                                    \"quoting\": {\n                                      \"type\": \"object\",\n                                      \"propertyNames\": {\n                                        \"type\": \"string\"\n                                      }\n                                    },\n                                    \"column_types\": {\n                                      \"type\": \"object\",\n                                      \"propertyNames\": {\n                                        \"type\": \"string\"\n                                      }\n                                    },\n                                    \"full_refresh\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"boolean\"\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    },\n                                    \"unique_key\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"string\"\n                                        },\n                                        {\n                                          \"type\": \"array\",\n                                          \"items\": {\n                                            \"type\": \"string\"\n                                          }\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    },\n                                    \"on_schema_change\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"string\"\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": \"ignore\"\n                                    },\n                                    \"on_configuration_change\": {\n                                      \"enum\": [\n                                        \"apply\",\n                                        \"continue\",\n                                        \"fail\"\n                                      ]\n                                    },\n                                    \"grants\": {\n                                      \"type\": \"object\",\n                                      \"propertyNames\": {\n                                        \"type\": \"string\"\n                                      }\n                                    },\n                                    \"packages\": {\n                                      \"type\": \"array\",\n                                      \"items\": {\n                                        \"type\": \"string\"\n                                      }\n                                    },\n                                    \"docs\": {\n                                      \"type\": \"object\",\n                                      \"title\": \"Docs\",\n                                      \"properties\": {\n                                        \"show\": {\n                                          \"type\": \"boolean\",\n                                          \"default\": true\n                                        },\n                                        \"node_color\": {\n                                          \"anyOf\": [\n                                            {\n                                              \"type\": \"string\"\n                                            },\n                                            {\n                                              \"type\": \"null\"\n                                            }\n                                          ],\n                                          \"default\": null\n                                        }\n                                      },\n                                      \"additionalProperties\": false\n                                    },\n                                    \"contract\": {\n                                      \"type\": \"object\",\n                                      \"title\": \"ContractConfig\",\n                                      \"properties\": {\n                                        \"enforced\": {\n                                          \"type\": \"boolean\",\n                                          \"default\": false\n                                        },\n                                        \"alias_types\": {\n                                          \"type\": \"boolean\",\n                                          \"default\": true\n                                        }\n                                      },\n                                      \"additionalProperties\": false\n                                    },\n                                    \"event_time\": {\n                                      \"default\": null\n                                    },\n                                    \"concurrent_batches\": {\n                                      \"default\": null\n                                    }\n                                  },\n                                  \"additionalProperties\": true\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ]\n                            }\n                          },\n                          \"additionalProperties\": false,\n                          \"required\": [\n                            \"database\",\n                            \"schema\",\n                            \"alias\",\n                            \"relation_name\",\n                            \"resource_type\",\n                            \"name\",\n                            \"description\",\n                            \"compiled_code\",\n                            \"meta\",\n                            \"tags\",\n                            \"config\"\n                          ]\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    }\n                  },\n                  \"additionalProperties\": false,\n                  \"required\": [\n                    \"database\",\n                    \"schema\",\n                    \"name\",\n                    \"resource_type\",\n                    \"package_name\",\n                    \"path\",\n                    \"original_file_path\",\n                    \"unique_id\",\n                    \"fqn\",\n                    \"alias\",\n                    \"checksum\",\n                    \"config\"\n                  ]\n                },\n                {\n                  \"type\": \"object\",\n                  \"title\": \"Function\",\n                  \"properties\": {\n                    \"returns\": {\n                      \"type\": \"object\",\n                      \"title\": \"FunctionReturns\",\n                      \"properties\": {\n                        \"data_type\": {\n                          \"type\": \"string\"\n                        },\n                        \"description\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": false,\n                      \"required\": [\n                        \"data_type\"\n                      ]\n                    },\n                    \"database\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ]\n                    },\n                    \"schema\": {\n                      \"type\": \"string\"\n                    },\n                    \"name\": {\n                      \"type\": \"string\"\n                    },\n                    \"resource_type\": {\n                      \"const\": \"function\"\n                    },\n                    \"package_name\": {\n                      \"type\": \"string\"\n                    },\n                    \"path\": {\n                      \"type\": \"string\"\n                    },\n                    \"original_file_path\": {\n                      \"type\": \"string\"\n                    },\n                    \"unique_id\": {\n                      \"type\": \"string\"\n                    },\n                    \"fqn\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"alias\": {\n                      \"type\": \"string\"\n                    },\n                    \"checksum\": {\n                      \"type\": \"object\",\n                      \"title\": \"FileHash\",\n                      \"properties\": {\n                        \"name\": {\n                          \"type\": \"string\"\n                        },\n                        \"checksum\": {\n                          \"type\": \"string\"\n                        }\n                      },\n                      \"additionalProperties\": false,\n                      \"required\": [\n                        \"name\",\n                        \"checksum\"\n                      ]\n                    },\n                    \"config\": {\n                      \"type\": \"object\",\n                      \"title\": \"FunctionConfig\",\n                      \"properties\": {\n                        \"_extra\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"enabled\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"alias\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"schema\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"database\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"tags\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"array\",\n                              \"items\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            {\n                              \"type\": \"string\"\n                            }\n                          ]\n                        },\n                        \"meta\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"group\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"materialized\": {\n                          \"type\": \"string\",\n                          \"default\": \"function\"\n                        },\n                        \"incremental_strategy\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"batch_size\": {\n                          \"default\": null\n                        },\n                        \"lookback\": {\n                          \"default\": 1\n                        },\n                        \"begin\": {\n                          \"default\": null\n                        },\n                        \"persist_docs\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"post-hook\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"object\",\n                            \"title\": \"Hook\",\n                            \"properties\": {\n                              \"sql\": {\n                                \"type\": \"string\"\n                              },\n                              \"transaction\": {\n                                \"type\": \"boolean\",\n                                \"default\": true\n                              },\n                              \"index\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"integer\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              }\n                            },\n                            \"additionalProperties\": false,\n                            \"required\": [\n                              \"sql\"\n                            ]\n                          }\n                        },\n                        \"pre-hook\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"object\",\n                            \"title\": \"Hook\",\n                            \"properties\": {\n                              \"sql\": {\n                                \"type\": \"string\"\n                              },\n                              \"transaction\": {\n                                \"type\": \"boolean\",\n                                \"default\": true\n                              },\n                              \"index\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"integer\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              }\n                            },\n                            \"additionalProperties\": false,\n                            \"required\": [\n                              \"sql\"\n                            ]\n                          }\n                        },\n                        \"quoting\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"column_types\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"full_refresh\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"boolean\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"unique_key\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"array\",\n                              \"items\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"on_schema_change\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": \"ignore\"\n                        },\n                        \"on_configuration_change\": {\n                          \"enum\": [\n                            \"apply\",\n                            \"continue\",\n                            \"fail\"\n                          ]\n                        },\n                        \"grants\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"packages\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"docs\": {\n                          \"type\": \"object\",\n                          \"title\": \"Docs\",\n                          \"properties\": {\n                            \"show\": {\n                              \"type\": \"boolean\",\n                              \"default\": true\n                            },\n                            \"node_color\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            }\n                          },\n                          \"additionalProperties\": false\n                        },\n                        \"contract\": {\n                          \"type\": \"object\",\n                          \"title\": \"ContractConfig\",\n                          \"properties\": {\n                            \"enforced\": {\n                              \"type\": \"boolean\",\n                              \"default\": false\n                            },\n                            \"alias_types\": {\n                              \"type\": \"boolean\",\n                              \"default\": true\n                            }\n                          },\n                          \"additionalProperties\": false\n                        },\n                        \"event_time\": {\n                          \"default\": null\n                        },\n                        \"concurrent_batches\": {\n                          \"default\": null\n                        },\n                        \"type\": {\n                          \"enum\": [\n                            \"scalar\",\n                            \"aggregate\",\n                            \"table\"\n                          ],\n                          \"default\": \"scalar\"\n                        },\n                        \"volatility\": {\n                          \"anyOf\": [\n                            {\n                              \"enum\": [\n                                \"deterministic\",\n                                \"stable\",\n                                \"non-deterministic\"\n                              ]\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"runtime_version\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"entry_point\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": true\n                    },\n                    \"tags\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"description\": {\n                      \"type\": \"string\",\n                      \"default\": \"\"\n                    },\n                    \"columns\": {\n                      \"type\": \"object\",\n                      \"additionalProperties\": {\n                        \"type\": \"object\",\n                        \"title\": \"ColumnInfo\",\n                        \"properties\": {\n                          \"name\": {\n                            \"type\": \"string\"\n                          },\n                          \"description\": {\n                            \"type\": \"string\",\n                            \"default\": \"\"\n                          },\n                          \"meta\": {\n                            \"type\": \"object\",\n                            \"propertyNames\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"data_type\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"constraints\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"object\",\n                              \"title\": \"ColumnLevelConstraint\",\n                              \"properties\": {\n                                \"type\": {\n                                  \"enum\": [\n                                    \"check\",\n                                    \"not_null\",\n                                    \"unique\",\n                                    \"primary_key\",\n                                    \"foreign_key\",\n                                    \"custom\"\n                                  ]\n                                },\n                                \"name\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"string\"\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"expression\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"string\"\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"warn_unenforced\": {\n                                  \"type\": \"boolean\",\n                                  \"default\": true\n                                },\n                                \"warn_unsupported\": {\n                                  \"type\": \"boolean\",\n                                  \"default\": true\n                                },\n                                \"to\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"string\"\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"to_columns\": {\n                                  \"type\": \"array\",\n                                  \"items\": {\n                                    \"type\": \"string\"\n                                  }\n                                }\n                              },\n                              \"additionalProperties\": false,\n                              \"required\": [\n                                \"type\"\n                              ]\n                            }\n                          },\n                          \"quote\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"boolean\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"config\": {\n                            \"type\": \"object\",\n                            \"title\": \"ColumnConfig\",\n                            \"properties\": {\n                              \"_extra\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"meta\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"tags\": {\n                                \"type\": \"array\",\n                                \"items\": {\n                                  \"type\": \"string\"\n                                }\n                              }\n                            },\n                            \"additionalProperties\": true\n                          },\n                          \"tags\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"_extra\": {\n                            \"type\": \"object\",\n                            \"propertyNames\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"granularity\": {\n                            \"anyOf\": [\n                              {\n                                \"enum\": [\n                                  \"nanosecond\",\n                                  \"microsecond\",\n                                  \"millisecond\",\n                                  \"second\",\n                                  \"minute\",\n                                  \"hour\",\n                                  \"day\",\n                                  \"week\",\n                                  \"month\",\n                                  \"quarter\",\n                                  \"year\"\n                                ]\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"dimension\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"object\",\n                                \"title\": \"ColumnDimension\",\n                                \"properties\": {\n                                  \"name\": {\n                                    \"type\": \"string\"\n                                  },\n                                  \"type\": {\n                                    \"enum\": [\n                                      \"categorical\",\n                                      \"time\"\n                                    ]\n                                  },\n                                  \"description\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"label\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"is_partition\": {\n                                    \"type\": \"boolean\",\n                                    \"default\": false\n                                  },\n                                  \"config\": {\n                                    \"type\": \"object\",\n                                    \"propertyNames\": {\n                                      \"type\": \"string\"\n                                    }\n                                  },\n                                  \"validity_params\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"object\",\n                                        \"title\": \"ColumnDimensionValidityParams\",\n                                        \"properties\": {\n                                          \"is_start\": {\n                                            \"type\": \"boolean\",\n                                            \"default\": false\n                                          },\n                                          \"is_end\": {\n                                            \"type\": \"boolean\",\n                                            \"default\": false\n                                          }\n                                        },\n                                        \"additionalProperties\": false\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  }\n                                },\n                                \"additionalProperties\": false,\n                                \"required\": [\n                                  \"name\",\n                                  \"type\"\n                                ]\n                              },\n                              {\n                                \"enum\": [\n                                  \"categorical\",\n                                  \"time\"\n                                ]\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"entity\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"object\",\n                                \"title\": \"ColumnEntity\",\n                                \"properties\": {\n                                  \"name\": {\n                                    \"type\": \"string\"\n                                  },\n                                  \"type\": {\n                                    \"enum\": [\n                                      \"foreign\",\n                                      \"natural\",\n                                      \"primary\",\n                                      \"unique\"\n                                    ]\n                                  },\n                                  \"description\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"label\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"config\": {\n                                    \"type\": \"object\",\n                                    \"propertyNames\": {\n                                      \"type\": \"string\"\n                                    }\n                                  }\n                                },\n                                \"additionalProperties\": false,\n                                \"required\": [\n                                  \"name\",\n                                  \"type\"\n                                ]\n                              },\n                              {\n                                \"enum\": [\n                                  \"foreign\",\n                                  \"natural\",\n                                  \"primary\",\n                                  \"unique\"\n                                ]\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"doc_blocks\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"string\"\n                            }\n                          }\n                        },\n                        \"additionalProperties\": true,\n                        \"required\": [\n                          \"name\"\n                        ]\n                      },\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"meta\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"group\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"docs\": {\n                      \"type\": \"object\",\n                      \"title\": \"Docs\",\n                      \"properties\": {\n                        \"show\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"node_color\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": false\n                    },\n                    \"patch_path\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"build_path\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"unrendered_config\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"created_at\": {\n                      \"type\": \"number\"\n                    },\n                    \"config_call_dict\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"unrendered_config_call_dict\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"relation_name\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"raw_code\": {\n                      \"type\": \"string\",\n                      \"default\": \"\"\n                    },\n                    \"doc_blocks\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"language\": {\n                      \"type\": \"string\",\n                      \"default\": \"sql\"\n                    },\n                    \"refs\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"object\",\n                        \"title\": \"RefArgs\",\n                        \"properties\": {\n                          \"name\": {\n                            \"type\": \"string\"\n                          },\n                          \"package\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"version\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"number\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          }\n                        },\n                        \"additionalProperties\": false,\n                        \"required\": [\n                          \"name\"\n                        ]\n                      }\n                    },\n                    \"sources\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      }\n                    },\n                    \"metrics\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      }\n                    },\n                    \"functions\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      }\n                    },\n                    \"depends_on\": {\n                      \"type\": \"object\",\n                      \"title\": \"DependsOn\",\n                      \"properties\": {\n                        \"macros\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"nodes\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      },\n                      \"additionalProperties\": false\n                    },\n                    \"compiled_path\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"compiled\": {\n                      \"type\": \"boolean\",\n                      \"default\": false\n                    },\n                    \"compiled_code\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"extra_ctes_injected\": {\n                      \"type\": \"boolean\",\n                      \"default\": false\n                    },\n                    \"extra_ctes\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"object\",\n                        \"title\": \"InjectedCTE\",\n                        \"properties\": {\n                          \"id\": {\n                            \"type\": \"string\"\n                          },\n                          \"sql\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"additionalProperties\": false,\n                        \"required\": [\n                          \"id\",\n                          \"sql\"\n                        ]\n                      }\n                    },\n                    \"_pre_injected_sql\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"contract\": {\n                      \"type\": \"object\",\n                      \"title\": \"Contract\",\n                      \"properties\": {\n                        \"enforced\": {\n                          \"type\": \"boolean\",\n                          \"default\": false\n                        },\n                        \"alias_types\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"checksum\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": false\n                    },\n                    \"arguments\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"object\",\n                        \"title\": \"FunctionArgument\",\n                        \"properties\": {\n                          \"name\": {\n                            \"type\": \"string\"\n                          },\n                          \"data_type\": {\n                            \"type\": \"string\"\n                          },\n                          \"description\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"default_value\": {\n                            \"anyOf\": [\n                              {},\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          }\n                        },\n                        \"additionalProperties\": false,\n                        \"required\": [\n                          \"name\",\n                          \"data_type\"\n                        ]\n                      }\n                    },\n                    \"defer_function\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"object\",\n                          \"title\": \"DeferFunction\",\n                          \"properties\": {\n                            \"database\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ]\n                            },\n                            \"schema\": {\n                              \"type\": \"string\"\n                            },\n                            \"alias\": {\n                              \"type\": \"string\"\n                            },\n                            \"resource_type\": {\n                              \"enum\": [\n                                \"model\",\n                                \"analysis\",\n                                \"test\",\n                                \"snapshot\",\n                                \"operation\",\n                                \"seed\",\n                                \"rpc\",\n                                \"sql_operation\",\n                                \"doc\",\n                                \"source\",\n                                \"macro\",\n                                \"exposure\",\n                                \"metric\",\n                                \"group\",\n                                \"saved_query\",\n                                \"semantic_model\",\n                                \"unit_test\",\n                                \"fixture\",\n                                \"function\"\n                              ]\n                            },\n                            \"name\": {\n                              \"type\": \"string\"\n                            },\n                            \"description\": {\n                              \"type\": \"string\"\n                            },\n                            \"compiled_code\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ]\n                            },\n                            \"meta\": {\n                              \"type\": \"object\",\n                              \"propertyNames\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            \"tags\": {\n                              \"type\": \"array\",\n                              \"items\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            \"config\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"object\",\n                                  \"title\": \"FunctionConfig\",\n                                  \"properties\": {\n                                    \"_extra\": {\n                                      \"type\": \"object\",\n                                      \"propertyNames\": {\n                                        \"type\": \"string\"\n                                      }\n                                    },\n                                    \"enabled\": {\n                                      \"type\": \"boolean\",\n                                      \"default\": true\n                                    },\n                                    \"alias\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"string\"\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    },\n                                    \"schema\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"string\"\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    },\n                                    \"database\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"string\"\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    },\n                                    \"tags\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"array\",\n                                          \"items\": {\n                                            \"type\": \"string\"\n                                          }\n                                        },\n                                        {\n                                          \"type\": \"string\"\n                                        }\n                                      ]\n                                    },\n                                    \"meta\": {\n                                      \"type\": \"object\",\n                                      \"propertyNames\": {\n                                        \"type\": \"string\"\n                                      }\n                                    },\n                                    \"group\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"string\"\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    },\n                                    \"materialized\": {\n                                      \"type\": \"string\",\n                                      \"default\": \"function\"\n                                    },\n                                    \"incremental_strategy\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"string\"\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    },\n                                    \"batch_size\": {\n                                      \"default\": null\n                                    },\n                                    \"lookback\": {\n                                      \"default\": 1\n                                    },\n                                    \"begin\": {\n                                      \"default\": null\n                                    },\n                                    \"persist_docs\": {\n                                      \"type\": \"object\",\n                                      \"propertyNames\": {\n                                        \"type\": \"string\"\n                                      }\n                                    },\n                                    \"post-hook\": {\n                                      \"type\": \"array\",\n                                      \"items\": {\n                                        \"type\": \"object\",\n                                        \"title\": \"Hook\",\n                                        \"properties\": {\n                                          \"sql\": {\n                                            \"type\": \"string\"\n                                          },\n                                          \"transaction\": {\n                                            \"type\": \"boolean\",\n                                            \"default\": true\n                                          },\n                                          \"index\": {\n                                            \"anyOf\": [\n                                              {\n                                                \"type\": \"integer\"\n                                              },\n                                              {\n                                                \"type\": \"null\"\n                                              }\n                                            ],\n                                            \"default\": null\n                                          }\n                                        },\n                                        \"additionalProperties\": false,\n                                        \"required\": [\n                                          \"sql\"\n                                        ]\n                                      }\n                                    },\n                                    \"pre-hook\": {\n                                      \"type\": \"array\",\n                                      \"items\": {\n                                        \"type\": \"object\",\n                                        \"title\": \"Hook\",\n                                        \"properties\": {\n                                          \"sql\": {\n                                            \"type\": \"string\"\n                                          },\n                                          \"transaction\": {\n                                            \"type\": \"boolean\",\n                                            \"default\": true\n                                          },\n                                          \"index\": {\n                                            \"anyOf\": [\n                                              {\n                                                \"type\": \"integer\"\n                                              },\n                                              {\n                                                \"type\": \"null\"\n                                              }\n                                            ],\n                                            \"default\": null\n                                          }\n                                        },\n                                        \"additionalProperties\": false,\n                                        \"required\": [\n                                          \"sql\"\n                                        ]\n                                      }\n                                    },\n                                    \"quoting\": {\n                                      \"type\": \"object\",\n                                      \"propertyNames\": {\n                                        \"type\": \"string\"\n                                      }\n                                    },\n                                    \"column_types\": {\n                                      \"type\": \"object\",\n                                      \"propertyNames\": {\n                                        \"type\": \"string\"\n                                      }\n                                    },\n                                    \"full_refresh\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"boolean\"\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    },\n                                    \"unique_key\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"string\"\n                                        },\n                                        {\n                                          \"type\": \"array\",\n                                          \"items\": {\n                                            \"type\": \"string\"\n                                          }\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    },\n                                    \"on_schema_change\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"string\"\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": \"ignore\"\n                                    },\n                                    \"on_configuration_change\": {\n                                      \"enum\": [\n                                        \"apply\",\n                                        \"continue\",\n                                        \"fail\"\n                                      ]\n                                    },\n                                    \"grants\": {\n                                      \"type\": \"object\",\n                                      \"propertyNames\": {\n                                        \"type\": \"string\"\n                                      }\n                                    },\n                                    \"packages\": {\n                                      \"type\": \"array\",\n                                      \"items\": {\n                                        \"type\": \"string\"\n                                      }\n                                    },\n                                    \"docs\": {\n                                      \"type\": \"object\",\n                                      \"title\": \"Docs\",\n                                      \"properties\": {\n                                        \"show\": {\n                                          \"type\": \"boolean\",\n                                          \"default\": true\n                                        },\n                                        \"node_color\": {\n                                          \"anyOf\": [\n                                            {\n                                              \"type\": \"string\"\n                                            },\n                                            {\n                                              \"type\": \"null\"\n                                            }\n                                          ],\n                                          \"default\": null\n                                        }\n                                      },\n                                      \"additionalProperties\": false\n                                    },\n                                    \"contract\": {\n                                      \"type\": \"object\",\n                                      \"title\": \"ContractConfig\",\n                                      \"properties\": {\n                                        \"enforced\": {\n                                          \"type\": \"boolean\",\n                                          \"default\": false\n                                        },\n                                        \"alias_types\": {\n                                          \"type\": \"boolean\",\n                                          \"default\": true\n                                        }\n                                      },\n                                      \"additionalProperties\": false\n                                    },\n                                    \"event_time\": {\n                                      \"default\": null\n                                    },\n                                    \"concurrent_batches\": {\n                                      \"default\": null\n                                    },\n                                    \"type\": {\n                                      \"enum\": [\n                                        \"scalar\",\n                                        \"aggregate\",\n                                        \"table\"\n                                      ],\n                                      \"default\": \"scalar\"\n                                    },\n                                    \"volatility\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"enum\": [\n                                            \"deterministic\",\n                                            \"stable\",\n                                            \"non-deterministic\"\n                                          ]\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    },\n                                    \"runtime_version\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"string\"\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    },\n                                    \"entry_point\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"string\"\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    }\n                                  },\n                                  \"additionalProperties\": true\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ]\n                            },\n                            \"arguments\": {\n                              \"type\": \"array\",\n                              \"items\": {\n                                \"type\": \"object\",\n                                \"title\": \"FunctionArgument\",\n                                \"properties\": {\n                                  \"name\": {\n                                    \"type\": \"string\"\n                                  },\n                                  \"data_type\": {\n                                    \"type\": \"string\"\n                                  },\n                                  \"description\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"default_value\": {\n                                    \"anyOf\": [\n                                      {},\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  }\n                                },\n                                \"additionalProperties\": false,\n                                \"required\": [\n                                  \"name\",\n                                  \"data_type\"\n                                ]\n                              }\n                            },\n                            \"returns\": {\n                              \"type\": \"object\",\n                              \"title\": \"FunctionReturns\",\n                              \"properties\": {\n                                \"data_type\": {\n                                  \"type\": \"string\"\n                                },\n                                \"description\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"string\"\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                }\n                              },\n                              \"additionalProperties\": false,\n                              \"required\": [\n                                \"data_type\"\n                              ]\n                            }\n                          },\n                          \"additionalProperties\": false,\n                          \"required\": [\n                            \"database\",\n                            \"schema\",\n                            \"alias\",\n                            \"resource_type\",\n                            \"name\",\n                            \"description\",\n                            \"compiled_code\",\n                            \"meta\",\n                            \"tags\",\n                            \"config\",\n                            \"arguments\",\n                            \"returns\"\n                          ]\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    }\n                  },\n                  \"additionalProperties\": false,\n                  \"required\": [\n                    \"returns\",\n                    \"database\",\n                    \"schema\",\n                    \"name\",\n                    \"resource_type\",\n                    \"package_name\",\n                    \"path\",\n                    \"original_file_path\",\n                    \"unique_id\",\n                    \"fqn\",\n                    \"alias\",\n                    \"checksum\",\n                    \"config\"\n                  ]\n                },\n                {\n                  \"type\": \"object\",\n                  \"title\": \"SourceDefinition\",\n                  \"properties\": {\n                    \"database\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ]\n                    },\n                    \"schema\": {\n                      \"type\": \"string\"\n                    },\n                    \"name\": {\n                      \"type\": \"string\"\n                    },\n                    \"resource_type\": {\n                      \"const\": \"source\"\n                    },\n                    \"package_name\": {\n                      \"type\": \"string\"\n                    },\n                    \"path\": {\n                      \"type\": \"string\"\n                    },\n                    \"original_file_path\": {\n                      \"type\": \"string\"\n                    },\n                    \"unique_id\": {\n                      \"type\": \"string\"\n                    },\n                    \"fqn\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"source_name\": {\n                      \"type\": \"string\"\n                    },\n                    \"source_description\": {\n                      \"type\": \"string\"\n                    },\n                    \"loader\": {\n                      \"type\": \"string\"\n                    },\n                    \"identifier\": {\n                      \"type\": \"string\"\n                    },\n                    \"quoting\": {\n                      \"type\": \"object\",\n                      \"title\": \"Quoting\",\n                      \"properties\": {\n                        \"database\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"boolean\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"schema\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"boolean\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"identifier\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"boolean\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"column\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"boolean\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": false\n                    },\n                    \"loaded_at_field\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"loaded_at_query\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"freshness\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"object\",\n                          \"title\": \"FreshnessThreshold\",\n                          \"properties\": {\n                            \"warn_after\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"object\",\n                                  \"title\": \"Time\",\n                                  \"properties\": {\n                                    \"count\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"integer\"\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    },\n                                    \"period\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"enum\": [\n                                            \"minute\",\n                                            \"hour\",\n                                            \"day\"\n                                          ]\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    }\n                                  },\n                                  \"additionalProperties\": false\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ]\n                            },\n                            \"error_after\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"object\",\n                                  \"title\": \"Time\",\n                                  \"properties\": {\n                                    \"count\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"type\": \"integer\"\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    },\n                                    \"period\": {\n                                      \"anyOf\": [\n                                        {\n                                          \"enum\": [\n                                            \"minute\",\n                                            \"hour\",\n                                            \"day\"\n                                          ]\n                                        },\n                                        {\n                                          \"type\": \"null\"\n                                        }\n                                      ],\n                                      \"default\": null\n                                    }\n                                  },\n                                  \"additionalProperties\": false\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ]\n                            },\n                            \"filter\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            }\n                          },\n                          \"additionalProperties\": false\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"external\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"object\",\n                          \"title\": \"ExternalTable\",\n                          \"properties\": {\n                            \"_extra\": {\n                              \"type\": \"object\",\n                              \"propertyNames\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            \"location\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"file_format\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"row_format\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"tbl_properties\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"partitions\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"array\",\n                                  \"items\": {\n                                    \"type\": \"string\"\n                                  }\n                                },\n                                {\n                                  \"type\": \"array\",\n                                  \"items\": {\n                                    \"type\": \"object\",\n                                    \"title\": \"ExternalPartition\",\n                                    \"properties\": {\n                                      \"_extra\": {\n                                        \"type\": \"object\",\n                                        \"propertyNames\": {\n                                          \"type\": \"string\"\n                                        }\n                                      },\n                                      \"name\": {\n                                        \"type\": \"string\",\n                                        \"default\": \"\"\n                                      },\n                                      \"description\": {\n                                        \"type\": \"string\",\n                                        \"default\": \"\"\n                                      },\n                                      \"data_type\": {\n                                        \"type\": \"string\",\n                                        \"default\": \"\"\n                                      },\n                                      \"meta\": {\n                                        \"type\": \"object\",\n                                        \"propertyNames\": {\n                                          \"type\": \"string\"\n                                        }\n                                      }\n                                    },\n                                    \"additionalProperties\": true\n                                  }\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            }\n                          },\n                          \"additionalProperties\": true\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"description\": {\n                      \"type\": \"string\",\n                      \"default\": \"\"\n                    },\n                    \"columns\": {\n                      \"type\": \"object\",\n                      \"additionalProperties\": {\n                        \"type\": \"object\",\n                        \"title\": \"ColumnInfo\",\n                        \"properties\": {\n                          \"name\": {\n                            \"type\": \"string\"\n                          },\n                          \"description\": {\n                            \"type\": \"string\",\n                            \"default\": \"\"\n                          },\n                          \"meta\": {\n                            \"type\": \"object\",\n                            \"propertyNames\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"data_type\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"constraints\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"object\",\n                              \"title\": \"ColumnLevelConstraint\",\n                              \"properties\": {\n                                \"type\": {\n                                  \"enum\": [\n                                    \"check\",\n                                    \"not_null\",\n                                    \"unique\",\n                                    \"primary_key\",\n                                    \"foreign_key\",\n                                    \"custom\"\n                                  ]\n                                },\n                                \"name\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"string\"\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"expression\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"string\"\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"warn_unenforced\": {\n                                  \"type\": \"boolean\",\n                                  \"default\": true\n                                },\n                                \"warn_unsupported\": {\n                                  \"type\": \"boolean\",\n                                  \"default\": true\n                                },\n                                \"to\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"string\"\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"to_columns\": {\n                                  \"type\": \"array\",\n                                  \"items\": {\n                                    \"type\": \"string\"\n                                  }\n                                }\n                              },\n                              \"additionalProperties\": false,\n                              \"required\": [\n                                \"type\"\n                              ]\n                            }\n                          },\n                          \"quote\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"boolean\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"config\": {\n                            \"type\": \"object\",\n                            \"title\": \"ColumnConfig\",\n                            \"properties\": {\n                              \"_extra\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"meta\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"tags\": {\n                                \"type\": \"array\",\n                                \"items\": {\n                                  \"type\": \"string\"\n                                }\n                              }\n                            },\n                            \"additionalProperties\": true\n                          },\n                          \"tags\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"_extra\": {\n                            \"type\": \"object\",\n                            \"propertyNames\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"granularity\": {\n                            \"anyOf\": [\n                              {\n                                \"enum\": [\n                                  \"nanosecond\",\n                                  \"microsecond\",\n                                  \"millisecond\",\n                                  \"second\",\n                                  \"minute\",\n                                  \"hour\",\n                                  \"day\",\n                                  \"week\",\n                                  \"month\",\n                                  \"quarter\",\n                                  \"year\"\n                                ]\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"dimension\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"object\",\n                                \"title\": \"ColumnDimension\",\n                                \"properties\": {\n                                  \"name\": {\n                                    \"type\": \"string\"\n                                  },\n                                  \"type\": {\n                                    \"enum\": [\n                                      \"categorical\",\n                                      \"time\"\n                                    ]\n                                  },\n                                  \"description\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"label\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"is_partition\": {\n                                    \"type\": \"boolean\",\n                                    \"default\": false\n                                  },\n                                  \"config\": {\n                                    \"type\": \"object\",\n                                    \"propertyNames\": {\n                                      \"type\": \"string\"\n                                    }\n                                  },\n                                  \"validity_params\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"object\",\n                                        \"title\": \"ColumnDimensionValidityParams\",\n                                        \"properties\": {\n                                          \"is_start\": {\n                                            \"type\": \"boolean\",\n                                            \"default\": false\n                                          },\n                                          \"is_end\": {\n                                            \"type\": \"boolean\",\n                                            \"default\": false\n                                          }\n                                        },\n                                        \"additionalProperties\": false\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  }\n                                },\n                                \"additionalProperties\": false,\n                                \"required\": [\n                                  \"name\",\n                                  \"type\"\n                                ]\n                              },\n                              {\n                                \"enum\": [\n                                  \"categorical\",\n                                  \"time\"\n                                ]\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"entity\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"object\",\n                                \"title\": \"ColumnEntity\",\n                                \"properties\": {\n                                  \"name\": {\n                                    \"type\": \"string\"\n                                  },\n                                  \"type\": {\n                                    \"enum\": [\n                                      \"foreign\",\n                                      \"natural\",\n                                      \"primary\",\n                                      \"unique\"\n                                    ]\n                                  },\n                                  \"description\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"label\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"config\": {\n                                    \"type\": \"object\",\n                                    \"propertyNames\": {\n                                      \"type\": \"string\"\n                                    }\n                                  }\n                                },\n                                \"additionalProperties\": false,\n                                \"required\": [\n                                  \"name\",\n                                  \"type\"\n                                ]\n                              },\n                              {\n                                \"enum\": [\n                                  \"foreign\",\n                                  \"natural\",\n                                  \"primary\",\n                                  \"unique\"\n                                ]\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"doc_blocks\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"string\"\n                            }\n                          }\n                        },\n                        \"additionalProperties\": true,\n                        \"required\": [\n                          \"name\"\n                        ]\n                      },\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"meta\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"source_meta\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"tags\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"config\": {\n                      \"type\": \"object\",\n                      \"title\": \"SourceConfig\",\n                      \"properties\": {\n                        \"_extra\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"enabled\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"event_time\": {\n                          \"default\": null\n                        },\n                        \"freshness\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"object\",\n                              \"title\": \"FreshnessThreshold\",\n                              \"properties\": {\n                                \"warn_after\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"object\",\n                                      \"title\": \"Time\",\n                                      \"properties\": {\n                                        \"count\": {\n                                          \"anyOf\": [\n                                            {\n                                              \"type\": \"integer\"\n                                            },\n                                            {\n                                              \"type\": \"null\"\n                                            }\n                                          ],\n                                          \"default\": null\n                                        },\n                                        \"period\": {\n                                          \"anyOf\": [\n                                            {\n                                              \"enum\": [\n                                                \"minute\",\n                                                \"hour\",\n                                                \"day\"\n                                              ]\n                                            },\n                                            {\n                                              \"type\": \"null\"\n                                            }\n                                          ],\n                                          \"default\": null\n                                        }\n                                      },\n                                      \"additionalProperties\": false\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ]\n                                },\n                                \"error_after\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"object\",\n                                      \"title\": \"Time\",\n                                      \"properties\": {\n                                        \"count\": {\n                                          \"anyOf\": [\n                                            {\n                                              \"type\": \"integer\"\n                                            },\n                                            {\n                                              \"type\": \"null\"\n                                            }\n                                          ],\n                                          \"default\": null\n                                        },\n                                        \"period\": {\n                                          \"anyOf\": [\n                                            {\n                                              \"enum\": [\n                                                \"minute\",\n                                                \"hour\",\n                                                \"day\"\n                                              ]\n                                            },\n                                            {\n                                              \"type\": \"null\"\n                                            }\n                                          ],\n                                          \"default\": null\n                                        }\n                                      },\n                                      \"additionalProperties\": false\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ]\n                                },\n                                \"filter\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"string\"\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                }\n                              },\n                              \"additionalProperties\": false\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ]\n                        },\n                        \"loaded_at_field\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"loaded_at_query\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"meta\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"tags\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      },\n                      \"additionalProperties\": true\n                    },\n                    \"patch_path\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"unrendered_config\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"relation_name\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"created_at\": {\n                      \"type\": \"number\"\n                    },\n                    \"unrendered_database\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"unrendered_schema\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"doc_blocks\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    }\n                  },\n                  \"additionalProperties\": false,\n                  \"required\": [\n                    \"database\",\n                    \"schema\",\n                    \"name\",\n                    \"resource_type\",\n                    \"package_name\",\n                    \"path\",\n                    \"original_file_path\",\n                    \"unique_id\",\n                    \"fqn\",\n                    \"source_name\",\n                    \"source_description\",\n                    \"loader\",\n                    \"identifier\"\n                  ]\n                },\n                {\n                  \"type\": \"object\",\n                  \"title\": \"Exposure\",\n                  \"properties\": {\n                    \"name\": {\n                      \"type\": \"string\"\n                    },\n                    \"resource_type\": {\n                      \"const\": \"exposure\"\n                    },\n                    \"package_name\": {\n                      \"type\": \"string\"\n                    },\n                    \"path\": {\n                      \"type\": \"string\"\n                    },\n                    \"original_file_path\": {\n                      \"type\": \"string\"\n                    },\n                    \"unique_id\": {\n                      \"type\": \"string\"\n                    },\n                    \"fqn\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"type\": {\n                      \"enum\": [\n                        \"dashboard\",\n                        \"notebook\",\n                        \"analysis\",\n                        \"ml\",\n                        \"application\"\n                      ]\n                    },\n                    \"owner\": {\n                      \"type\": \"object\",\n                      \"title\": \"Owner\",\n                      \"properties\": {\n                        \"_extra\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"email\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"array\",\n                              \"items\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"name\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": true\n                    },\n                    \"description\": {\n                      \"type\": \"string\",\n                      \"default\": \"\"\n                    },\n                    \"label\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"maturity\": {\n                      \"anyOf\": [\n                        {\n                          \"enum\": [\n                            \"low\",\n                            \"medium\",\n                            \"high\"\n                          ]\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"meta\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"tags\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"config\": {\n                      \"type\": \"object\",\n                      \"title\": \"ExposureConfig\",\n                      \"properties\": {\n                        \"_extra\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"enabled\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"tags\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"meta\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      },\n                      \"additionalProperties\": true\n                    },\n                    \"unrendered_config\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"url\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"depends_on\": {\n                      \"type\": \"object\",\n                      \"title\": \"DependsOn\",\n                      \"properties\": {\n                        \"macros\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"nodes\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      },\n                      \"additionalProperties\": false\n                    },\n                    \"refs\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"object\",\n                        \"title\": \"RefArgs\",\n                        \"properties\": {\n                          \"name\": {\n                            \"type\": \"string\"\n                          },\n                          \"package\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"version\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"number\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          }\n                        },\n                        \"additionalProperties\": false,\n                        \"required\": [\n                          \"name\"\n                        ]\n                      }\n                    },\n                    \"sources\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      }\n                    },\n                    \"metrics\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      }\n                    },\n                    \"created_at\": {\n                      \"type\": \"number\"\n                    }\n                  },\n                  \"additionalProperties\": false,\n                  \"required\": [\n                    \"name\",\n                    \"resource_type\",\n                    \"package_name\",\n                    \"path\",\n                    \"original_file_path\",\n                    \"unique_id\",\n                    \"fqn\",\n                    \"type\",\n                    \"owner\"\n                  ]\n                },\n                {\n                  \"type\": \"object\",\n                  \"title\": \"Metric\",\n                  \"properties\": {\n                    \"name\": {\n                      \"type\": \"string\"\n                    },\n                    \"resource_type\": {\n                      \"const\": \"metric\"\n                    },\n                    \"package_name\": {\n                      \"type\": \"string\"\n                    },\n                    \"path\": {\n                      \"type\": \"string\"\n                    },\n                    \"original_file_path\": {\n                      \"type\": \"string\"\n                    },\n                    \"unique_id\": {\n                      \"type\": \"string\"\n                    },\n                    \"fqn\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"description\": {\n                      \"type\": \"string\"\n                    },\n                    \"label\": {\n                      \"type\": \"string\"\n                    },\n                    \"type\": {\n                      \"enum\": [\n                        \"simple\",\n                        \"ratio\",\n                        \"cumulative\",\n                        \"derived\",\n                        \"conversion\"\n                      ]\n                    },\n                    \"type_params\": {\n                      \"type\": \"object\",\n                      \"title\": \"MetricTypeParams\",\n                      \"properties\": {\n                        \"measure\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"object\",\n                              \"title\": \"MetricInputMeasure\",\n                              \"properties\": {\n                                \"name\": {\n                                  \"type\": \"string\"\n                                },\n                                \"filter\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"object\",\n                                      \"title\": \"WhereFilterIntersection\",\n                                      \"properties\": {\n                                        \"where_filters\": {\n                                          \"type\": \"array\",\n                                          \"items\": {\n                                            \"type\": \"object\",\n                                            \"title\": \"WhereFilter\",\n                                            \"properties\": {\n                                              \"where_sql_template\": {\n                                                \"type\": \"string\"\n                                              }\n                                            },\n                                            \"additionalProperties\": false,\n                                            \"required\": [\n                                              \"where_sql_template\"\n                                            ]\n                                          }\n                                        }\n                                      },\n                                      \"additionalProperties\": false,\n                                      \"required\": [\n                                        \"where_filters\"\n                                      ]\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"alias\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"string\"\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"join_to_timespine\": {\n                                  \"type\": \"boolean\",\n                                  \"default\": false\n                                },\n                                \"fill_nulls_with\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"integer\"\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                }\n                              },\n                              \"additionalProperties\": false,\n                              \"required\": [\n                                \"name\"\n                              ]\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"input_measures\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"object\",\n                            \"title\": \"MetricInputMeasure\",\n                            \"properties\": {\n                              \"name\": {\n                                \"type\": \"string\"\n                              },\n                              \"filter\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"object\",\n                                    \"title\": \"WhereFilterIntersection\",\n                                    \"properties\": {\n                                      \"where_filters\": {\n                                        \"type\": \"array\",\n                                        \"items\": {\n                                          \"type\": \"object\",\n                                          \"title\": \"WhereFilter\",\n                                          \"properties\": {\n                                            \"where_sql_template\": {\n                                              \"type\": \"string\"\n                                            }\n                                          },\n                                          \"additionalProperties\": false,\n                                          \"required\": [\n                                            \"where_sql_template\"\n                                          ]\n                                        }\n                                      }\n                                    },\n                                    \"additionalProperties\": false,\n                                    \"required\": [\n                                      \"where_filters\"\n                                    ]\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"alias\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"string\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"join_to_timespine\": {\n                                \"type\": \"boolean\",\n                                \"default\": false\n                              },\n                              \"fill_nulls_with\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"integer\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              }\n                            },\n                            \"additionalProperties\": false,\n                            \"required\": [\n                              \"name\"\n                            ]\n                          }\n                        },\n                        \"numerator\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"object\",\n                              \"title\": \"MetricInput\",\n                              \"properties\": {\n                                \"name\": {\n                                  \"type\": \"string\"\n                                },\n                                \"filter\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"object\",\n                                      \"title\": \"WhereFilterIntersection\",\n                                      \"properties\": {\n                                        \"where_filters\": {\n                                          \"type\": \"array\",\n                                          \"items\": {\n                                            \"type\": \"object\",\n                                            \"title\": \"WhereFilter\",\n                                            \"properties\": {\n                                              \"where_sql_template\": {\n                                                \"type\": \"string\"\n                                              }\n                                            },\n                                            \"additionalProperties\": false,\n                                            \"required\": [\n                                              \"where_sql_template\"\n                                            ]\n                                          }\n                                        }\n                                      },\n                                      \"additionalProperties\": false,\n                                      \"required\": [\n                                        \"where_filters\"\n                                      ]\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"alias\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"string\"\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"offset_window\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"object\",\n                                      \"title\": \"MetricTimeWindow\",\n                                      \"properties\": {\n                                        \"count\": {\n                                          \"type\": \"integer\"\n                                        },\n                                        \"granularity\": {\n                                          \"type\": \"string\"\n                                        }\n                                      },\n                                      \"additionalProperties\": false,\n                                      \"required\": [\n                                        \"count\",\n                                        \"granularity\"\n                                      ]\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"offset_to_grain\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"string\"\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                }\n                              },\n                              \"additionalProperties\": false,\n                              \"required\": [\n                                \"name\"\n                              ]\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"denominator\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"object\",\n                              \"title\": \"MetricInput\",\n                              \"properties\": {\n                                \"name\": {\n                                  \"type\": \"string\"\n                                },\n                                \"filter\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"object\",\n                                      \"title\": \"WhereFilterIntersection\",\n                                      \"properties\": {\n                                        \"where_filters\": {\n                                          \"type\": \"array\",\n                                          \"items\": {\n                                            \"type\": \"object\",\n                                            \"title\": \"WhereFilter\",\n                                            \"properties\": {\n                                              \"where_sql_template\": {\n                                                \"type\": \"string\"\n                                              }\n                                            },\n                                            \"additionalProperties\": false,\n                                            \"required\": [\n                                              \"where_sql_template\"\n                                            ]\n                                          }\n                                        }\n                                      },\n                                      \"additionalProperties\": false,\n                                      \"required\": [\n                                        \"where_filters\"\n                                      ]\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"alias\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"string\"\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"offset_window\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"object\",\n                                      \"title\": \"MetricTimeWindow\",\n                                      \"properties\": {\n                                        \"count\": {\n                                          \"type\": \"integer\"\n                                        },\n                                        \"granularity\": {\n                                          \"type\": \"string\"\n                                        }\n                                      },\n                                      \"additionalProperties\": false,\n                                      \"required\": [\n                                        \"count\",\n                                        \"granularity\"\n                                      ]\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"offset_to_grain\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"string\"\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                }\n                              },\n                              \"additionalProperties\": false,\n                              \"required\": [\n                                \"name\"\n                              ]\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"expr\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"window\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"object\",\n                              \"title\": \"MetricTimeWindow\",\n                              \"properties\": {\n                                \"count\": {\n                                  \"type\": \"integer\"\n                                },\n                                \"granularity\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              \"additionalProperties\": false,\n                              \"required\": [\n                                \"count\",\n                                \"granularity\"\n                              ]\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"grain_to_date\": {\n                          \"anyOf\": [\n                            {\n                              \"enum\": [\n                                \"nanosecond\",\n                                \"microsecond\",\n                                \"millisecond\",\n                                \"second\",\n                                \"minute\",\n                                \"hour\",\n                                \"day\",\n                                \"week\",\n                                \"month\",\n                                \"quarter\",\n                                \"year\"\n                              ]\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"metrics\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"array\",\n                              \"items\": {\n                                \"type\": \"object\",\n                                \"title\": \"MetricInput\",\n                                \"properties\": {\n                                  \"name\": {\n                                    \"type\": \"string\"\n                                  },\n                                  \"filter\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"object\",\n                                        \"title\": \"WhereFilterIntersection\",\n                                        \"properties\": {\n                                          \"where_filters\": {\n                                            \"type\": \"array\",\n                                            \"items\": {\n                                              \"type\": \"object\",\n                                              \"title\": \"WhereFilter\",\n                                              \"properties\": {\n                                                \"where_sql_template\": {\n                                                  \"type\": \"string\"\n                                                }\n                                              },\n                                              \"additionalProperties\": false,\n                                              \"required\": [\n                                                \"where_sql_template\"\n                                              ]\n                                            }\n                                          }\n                                        },\n                                        \"additionalProperties\": false,\n                                        \"required\": [\n                                          \"where_filters\"\n                                        ]\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"alias\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"offset_window\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"object\",\n                                        \"title\": \"MetricTimeWindow\",\n                                        \"properties\": {\n                                          \"count\": {\n                                            \"type\": \"integer\"\n                                          },\n                                          \"granularity\": {\n                                            \"type\": \"string\"\n                                          }\n                                        },\n                                        \"additionalProperties\": false,\n                                        \"required\": [\n                                          \"count\",\n                                          \"granularity\"\n                                        ]\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"offset_to_grain\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  }\n                                },\n                                \"additionalProperties\": false,\n                                \"required\": [\n                                  \"name\"\n                                ]\n                              }\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"conversion_type_params\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"object\",\n                              \"title\": \"ConversionTypeParams\",\n                              \"properties\": {\n                                \"entity\": {\n                                  \"type\": \"string\"\n                                },\n                                \"base_measure\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"object\",\n                                      \"title\": \"MetricInputMeasure\",\n                                      \"properties\": {\n                                        \"name\": {\n                                          \"type\": \"string\"\n                                        },\n                                        \"filter\": {\n                                          \"anyOf\": [\n                                            {\n                                              \"type\": \"object\",\n                                              \"title\": \"WhereFilterIntersection\",\n                                              \"properties\": {\n                                                \"where_filters\": {\n                                                  \"type\": \"array\",\n                                                  \"items\": {\n                                                    \"type\": \"object\",\n                                                    \"title\": \"WhereFilter\",\n                                                    \"properties\": {\n                                                      \"where_sql_template\": {\n                                                        \"type\": \"string\"\n                                                      }\n                                                    },\n                                                    \"additionalProperties\": false,\n                                                    \"required\": [\n                                                      \"where_sql_template\"\n                                                    ]\n                                                  }\n                                                }\n                                              },\n                                              \"additionalProperties\": false,\n                                              \"required\": [\n                                                \"where_filters\"\n                                              ]\n                                            },\n                                            {\n                                              \"type\": \"null\"\n                                            }\n                                          ],\n                                          \"default\": null\n                                        },\n                                        \"alias\": {\n                                          \"anyOf\": [\n                                            {\n                                              \"type\": \"string\"\n                                            },\n                                            {\n                                              \"type\": \"null\"\n                                            }\n                                          ],\n                                          \"default\": null\n                                        },\n                                        \"join_to_timespine\": {\n                                          \"type\": \"boolean\",\n                                          \"default\": false\n                                        },\n                                        \"fill_nulls_with\": {\n                                          \"anyOf\": [\n                                            {\n                                              \"type\": \"integer\"\n                                            },\n                                            {\n                                              \"type\": \"null\"\n                                            }\n                                          ],\n                                          \"default\": null\n                                        }\n                                      },\n                                      \"additionalProperties\": false,\n                                      \"required\": [\n                                        \"name\"\n                                      ]\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"conversion_measure\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"object\",\n                                      \"title\": \"MetricInputMeasure\",\n                                      \"properties\": {\n                                        \"name\": {\n                                          \"type\": \"string\"\n                                        },\n                                        \"filter\": {\n                                          \"anyOf\": [\n                                            {\n                                              \"type\": \"object\",\n                                              \"title\": \"WhereFilterIntersection\",\n                                              \"properties\": {\n                                                \"where_filters\": {\n                                                  \"type\": \"array\",\n                                                  \"items\": {\n                                                    \"type\": \"object\",\n                                                    \"title\": \"WhereFilter\",\n                                                    \"properties\": {\n                                                      \"where_sql_template\": {\n                                                        \"type\": \"string\"\n                                                      }\n                                                    },\n                                                    \"additionalProperties\": false,\n                                                    \"required\": [\n                                                      \"where_sql_template\"\n                                                    ]\n                                                  }\n                                                }\n                                              },\n                                              \"additionalProperties\": false,\n                                              \"required\": [\n                                                \"where_filters\"\n                                              ]\n                                            },\n                                            {\n                                              \"type\": \"null\"\n                                            }\n                                          ],\n                                          \"default\": null\n                                        },\n                                        \"alias\": {\n                                          \"anyOf\": [\n                                            {\n                                              \"type\": \"string\"\n                                            },\n                                            {\n                                              \"type\": \"null\"\n                                            }\n                                          ],\n                                          \"default\": null\n                                        },\n                                        \"join_to_timespine\": {\n                                          \"type\": \"boolean\",\n                                          \"default\": false\n                                        },\n                                        \"fill_nulls_with\": {\n                                          \"anyOf\": [\n                                            {\n                                              \"type\": \"integer\"\n                                            },\n                                            {\n                                              \"type\": \"null\"\n                                            }\n                                          ],\n                                          \"default\": null\n                                        }\n                                      },\n                                      \"additionalProperties\": false,\n                                      \"required\": [\n                                        \"name\"\n                                      ]\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"base_metric\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"object\",\n                                      \"title\": \"MetricInput\",\n                                      \"properties\": {\n                                        \"name\": {\n                                          \"type\": \"string\"\n                                        },\n                                        \"filter\": {\n                                          \"anyOf\": [\n                                            {\n                                              \"type\": \"object\",\n                                              \"title\": \"WhereFilterIntersection\",\n                                              \"properties\": {\n                                                \"where_filters\": {\n                                                  \"type\": \"array\",\n                                                  \"items\": {\n                                                    \"type\": \"object\",\n                                                    \"title\": \"WhereFilter\",\n                                                    \"properties\": {\n                                                      \"where_sql_template\": {\n                                                        \"type\": \"string\"\n                                                      }\n                                                    },\n                                                    \"additionalProperties\": false,\n                                                    \"required\": [\n                                                      \"where_sql_template\"\n                                                    ]\n                                                  }\n                                                }\n                                              },\n                                              \"additionalProperties\": false,\n                                              \"required\": [\n                                                \"where_filters\"\n                                              ]\n                                            },\n                                            {\n                                              \"type\": \"null\"\n                                            }\n                                          ],\n                                          \"default\": null\n                                        },\n                                        \"alias\": {\n                                          \"anyOf\": [\n                                            {\n                                              \"type\": \"string\"\n                                            },\n                                            {\n                                              \"type\": \"null\"\n                                            }\n                                          ],\n                                          \"default\": null\n                                        },\n                                        \"offset_window\": {\n                                          \"anyOf\": [\n                                            {\n                                              \"type\": \"object\",\n                                              \"title\": \"MetricTimeWindow\",\n                                              \"properties\": {\n                                                \"count\": {\n                                                  \"type\": \"integer\"\n                                                },\n                                                \"granularity\": {\n                                                  \"type\": \"string\"\n                                                }\n                                              },\n                                              \"additionalProperties\": false,\n                                              \"required\": [\n                                                \"count\",\n                                                \"granularity\"\n                                              ]\n                                            },\n                                            {\n                                              \"type\": \"null\"\n                                            }\n                                          ],\n                                          \"default\": null\n                                        },\n                                        \"offset_to_grain\": {\n                                          \"anyOf\": [\n                                            {\n                                              \"type\": \"string\"\n                                            },\n                                            {\n                                              \"type\": \"null\"\n                                            }\n                                          ],\n                                          \"default\": null\n                                        }\n                                      },\n                                      \"additionalProperties\": false,\n                                      \"required\": [\n                                        \"name\"\n                                      ]\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"conversion_metric\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"object\",\n                                      \"title\": \"MetricInput\",\n                                      \"properties\": {\n                                        \"name\": {\n                                          \"type\": \"string\"\n                                        },\n                                        \"filter\": {\n                                          \"anyOf\": [\n                                            {\n                                              \"type\": \"object\",\n                                              \"title\": \"WhereFilterIntersection\",\n                                              \"properties\": {\n                                                \"where_filters\": {\n                                                  \"type\": \"array\",\n                                                  \"items\": {\n                                                    \"type\": \"object\",\n                                                    \"title\": \"WhereFilter\",\n                                                    \"properties\": {\n                                                      \"where_sql_template\": {\n                                                        \"type\": \"string\"\n                                                      }\n                                                    },\n                                                    \"additionalProperties\": false,\n                                                    \"required\": [\n                                                      \"where_sql_template\"\n                                                    ]\n                                                  }\n                                                }\n                                              },\n                                              \"additionalProperties\": false,\n                                              \"required\": [\n                                                \"where_filters\"\n                                              ]\n                                            },\n                                            {\n                                              \"type\": \"null\"\n                                            }\n                                          ],\n                                          \"default\": null\n                                        },\n                                        \"alias\": {\n                                          \"anyOf\": [\n                                            {\n                                              \"type\": \"string\"\n                                            },\n                                            {\n                                              \"type\": \"null\"\n                                            }\n                                          ],\n                                          \"default\": null\n                                        },\n                                        \"offset_window\": {\n                                          \"anyOf\": [\n                                            {\n                                              \"type\": \"object\",\n                                              \"title\": \"MetricTimeWindow\",\n                                              \"properties\": {\n                                                \"count\": {\n                                                  \"type\": \"integer\"\n                                                },\n                                                \"granularity\": {\n                                                  \"type\": \"string\"\n                                                }\n                                              },\n                                              \"additionalProperties\": false,\n                                              \"required\": [\n                                                \"count\",\n                                                \"granularity\"\n                                              ]\n                                            },\n                                            {\n                                              \"type\": \"null\"\n                                            }\n                                          ],\n                                          \"default\": null\n                                        },\n                                        \"offset_to_grain\": {\n                                          \"anyOf\": [\n                                            {\n                                              \"type\": \"string\"\n                                            },\n                                            {\n                                              \"type\": \"null\"\n                                            }\n                                          ],\n                                          \"default\": null\n                                        }\n                                      },\n                                      \"additionalProperties\": false,\n                                      \"required\": [\n                                        \"name\"\n                                      ]\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"calculation\": {\n                                  \"enum\": [\n                                    \"conversions\",\n                                    \"conversion_rate\"\n                                  ],\n                                  \"default\": \"conversion_rate\"\n                                },\n                                \"window\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"object\",\n                                      \"title\": \"MetricTimeWindow\",\n                                      \"properties\": {\n                                        \"count\": {\n                                          \"type\": \"integer\"\n                                        },\n                                        \"granularity\": {\n                                          \"type\": \"string\"\n                                        }\n                                      },\n                                      \"additionalProperties\": false,\n                                      \"required\": [\n                                        \"count\",\n                                        \"granularity\"\n                                      ]\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"constant_properties\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"array\",\n                                      \"items\": {\n                                        \"type\": \"object\",\n                                        \"title\": \"ConstantPropertyInput\",\n                                        \"properties\": {\n                                          \"base_property\": {\n                                            \"type\": \"string\"\n                                          },\n                                          \"conversion_property\": {\n                                            \"type\": \"string\"\n                                          }\n                                        },\n                                        \"additionalProperties\": false,\n                                        \"required\": [\n                                          \"base_property\",\n                                          \"conversion_property\"\n                                        ]\n                                      }\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                }\n                              },\n                              \"additionalProperties\": false,\n                              \"required\": [\n                                \"entity\"\n                              ]\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"cumulative_type_params\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"object\",\n                              \"title\": \"CumulativeTypeParams\",\n                              \"properties\": {\n                                \"window\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"object\",\n                                      \"title\": \"MetricTimeWindow\",\n                                      \"properties\": {\n                                        \"count\": {\n                                          \"type\": \"integer\"\n                                        },\n                                        \"granularity\": {\n                                          \"type\": \"string\"\n                                        }\n                                      },\n                                      \"additionalProperties\": false,\n                                      \"required\": [\n                                        \"count\",\n                                        \"granularity\"\n                                      ]\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"grain_to_date\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"string\"\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"period_agg\": {\n                                  \"enum\": [\n                                    \"first\",\n                                    \"last\",\n                                    \"average\"\n                                  ],\n                                  \"default\": \"first\"\n                                },\n                                \"metric\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"object\",\n                                      \"title\": \"MetricInput\",\n                                      \"properties\": {\n                                        \"name\": {\n                                          \"type\": \"string\"\n                                        },\n                                        \"filter\": {\n                                          \"anyOf\": [\n                                            {\n                                              \"type\": \"object\",\n                                              \"title\": \"WhereFilterIntersection\",\n                                              \"properties\": {\n                                                \"where_filters\": {\n                                                  \"type\": \"array\",\n                                                  \"items\": {\n                                                    \"type\": \"object\",\n                                                    \"title\": \"WhereFilter\",\n                                                    \"properties\": {\n                                                      \"where_sql_template\": {\n                                                        \"type\": \"string\"\n                                                      }\n                                                    },\n                                                    \"additionalProperties\": false,\n                                                    \"required\": [\n                                                      \"where_sql_template\"\n                                                    ]\n                                                  }\n                                                }\n                                              },\n                                              \"additionalProperties\": false,\n                                              \"required\": [\n                                                \"where_filters\"\n                                              ]\n                                            },\n                                            {\n                                              \"type\": \"null\"\n                                            }\n                                          ],\n                                          \"default\": null\n                                        },\n                                        \"alias\": {\n                                          \"anyOf\": [\n                                            {\n                                              \"type\": \"string\"\n                                            },\n                                            {\n                                              \"type\": \"null\"\n                                            }\n                                          ],\n                                          \"default\": null\n                                        },\n                                        \"offset_window\": {\n                                          \"anyOf\": [\n                                            {\n                                              \"type\": \"object\",\n                                              \"title\": \"MetricTimeWindow\",\n                                              \"properties\": {\n                                                \"count\": {\n                                                  \"type\": \"integer\"\n                                                },\n                                                \"granularity\": {\n                                                  \"type\": \"string\"\n                                                }\n                                              },\n                                              \"additionalProperties\": false,\n                                              \"required\": [\n                                                \"count\",\n                                                \"granularity\"\n                                              ]\n                                            },\n                                            {\n                                              \"type\": \"null\"\n                                            }\n                                          ],\n                                          \"default\": null\n                                        },\n                                        \"offset_to_grain\": {\n                                          \"anyOf\": [\n                                            {\n                                              \"type\": \"string\"\n                                            },\n                                            {\n                                              \"type\": \"null\"\n                                            }\n                                          ],\n                                          \"default\": null\n                                        }\n                                      },\n                                      \"additionalProperties\": false,\n                                      \"required\": [\n                                        \"name\"\n                                      ]\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                }\n                              },\n                              \"additionalProperties\": false\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"metric_aggregation_params\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"object\",\n                              \"title\": \"MetricAggregationParams\",\n                              \"properties\": {\n                                \"semantic_model\": {\n                                  \"type\": \"string\"\n                                },\n                                \"agg\": {\n                                  \"enum\": [\n                                    \"sum\",\n                                    \"min\",\n                                    \"max\",\n                                    \"count_distinct\",\n                                    \"sum_boolean\",\n                                    \"average\",\n                                    \"percentile\",\n                                    \"median\",\n                                    \"count\"\n                                  ]\n                                },\n                                \"agg_params\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"object\",\n                                      \"title\": \"MeasureAggregationParameters\",\n                                      \"properties\": {\n                                        \"percentile\": {\n                                          \"anyOf\": [\n                                            {\n                                              \"type\": \"number\"\n                                            },\n                                            {\n                                              \"type\": \"null\"\n                                            }\n                                          ],\n                                          \"default\": null\n                                        },\n                                        \"use_discrete_percentile\": {\n                                          \"type\": \"boolean\",\n                                          \"default\": false\n                                        },\n                                        \"use_approximate_percentile\": {\n                                          \"type\": \"boolean\",\n                                          \"default\": false\n                                        }\n                                      },\n                                      \"additionalProperties\": false\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"agg_time_dimension\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"string\"\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                },\n                                \"non_additive_dimension\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"object\",\n                                      \"title\": \"NonAdditiveDimension\",\n                                      \"properties\": {\n                                        \"name\": {\n                                          \"type\": \"string\"\n                                        },\n                                        \"window_choice\": {\n                                          \"enum\": [\n                                            \"sum\",\n                                            \"min\",\n                                            \"max\",\n                                            \"count_distinct\",\n                                            \"sum_boolean\",\n                                            \"average\",\n                                            \"percentile\",\n                                            \"median\",\n                                            \"count\"\n                                          ]\n                                        },\n                                        \"window_groupings\": {\n                                          \"type\": \"array\",\n                                          \"items\": {\n                                            \"type\": \"string\"\n                                          }\n                                        }\n                                      },\n                                      \"additionalProperties\": false,\n                                      \"required\": [\n                                        \"name\",\n                                        \"window_choice\",\n                                        \"window_groupings\"\n                                      ]\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                }\n                              },\n                              \"additionalProperties\": false,\n                              \"required\": [\n                                \"semantic_model\",\n                                \"agg\"\n                              ]\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"fill_nulls_with\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"integer\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"join_to_timespine\": {\n                          \"type\": \"boolean\",\n                          \"default\": false\n                        },\n                        \"is_private\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"boolean\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": false\n                    },\n                    \"filter\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"object\",\n                          \"title\": \"WhereFilterIntersection\",\n                          \"properties\": {\n                            \"where_filters\": {\n                              \"type\": \"array\",\n                              \"items\": {\n                                \"type\": \"object\",\n                                \"title\": \"WhereFilter\",\n                                \"properties\": {\n                                  \"where_sql_template\": {\n                                    \"type\": \"string\"\n                                  }\n                                },\n                                \"additionalProperties\": false,\n                                \"required\": [\n                                  \"where_sql_template\"\n                                ]\n                              }\n                            }\n                          },\n                          \"additionalProperties\": false,\n                          \"required\": [\n                            \"where_filters\"\n                          ]\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"metadata\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"object\",\n                          \"title\": \"SourceFileMetadata\",\n                          \"properties\": {\n                            \"repo_file_path\": {\n                              \"type\": \"string\"\n                            },\n                            \"file_slice\": {\n                              \"type\": \"object\",\n                              \"title\": \"FileSlice\",\n                              \"properties\": {\n                                \"filename\": {\n                                  \"type\": \"string\"\n                                },\n                                \"content\": {\n                                  \"type\": \"string\"\n                                },\n                                \"start_line_number\": {\n                                  \"type\": \"integer\"\n                                },\n                                \"end_line_number\": {\n                                  \"type\": \"integer\"\n                                }\n                              },\n                              \"additionalProperties\": false,\n                              \"required\": [\n                                \"filename\",\n                                \"content\",\n                                \"start_line_number\",\n                                \"end_line_number\"\n                              ]\n                            }\n                          },\n                          \"additionalProperties\": false,\n                          \"required\": [\n                            \"repo_file_path\",\n                            \"file_slice\"\n                          ]\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"time_granularity\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"config\": {\n                      \"type\": \"object\",\n                      \"title\": \"MetricConfig\",\n                      \"properties\": {\n                        \"_extra\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"enabled\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"group\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"meta\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      },\n                      \"additionalProperties\": true\n                    },\n                    \"unrendered_config\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"sources\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      }\n                    },\n                    \"depends_on\": {\n                      \"type\": \"object\",\n                      \"title\": \"DependsOn\",\n                      \"properties\": {\n                        \"macros\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"nodes\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      },\n                      \"additionalProperties\": false\n                    },\n                    \"refs\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"object\",\n                        \"title\": \"RefArgs\",\n                        \"properties\": {\n                          \"name\": {\n                            \"type\": \"string\"\n                          },\n                          \"package\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"version\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"number\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          }\n                        },\n                        \"additionalProperties\": false,\n                        \"required\": [\n                          \"name\"\n                        ]\n                      }\n                    },\n                    \"metrics\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      }\n                    },\n                    \"created_at\": {\n                      \"type\": \"number\"\n                    },\n                    \"group\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"meta\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"tags\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    }\n                  },\n                  \"additionalProperties\": false,\n                  \"required\": [\n                    \"name\",\n                    \"resource_type\",\n                    \"package_name\",\n                    \"path\",\n                    \"original_file_path\",\n                    \"unique_id\",\n                    \"fqn\",\n                    \"description\",\n                    \"label\",\n                    \"type\",\n                    \"type_params\"\n                  ]\n                },\n                {\n                  \"type\": \"object\",\n                  \"title\": \"SavedQuery\",\n                  \"properties\": {\n                    \"name\": {\n                      \"type\": \"string\"\n                    },\n                    \"resource_type\": {\n                      \"const\": \"saved_query\"\n                    },\n                    \"package_name\": {\n                      \"type\": \"string\"\n                    },\n                    \"path\": {\n                      \"type\": \"string\"\n                    },\n                    \"original_file_path\": {\n                      \"type\": \"string\"\n                    },\n                    \"unique_id\": {\n                      \"type\": \"string\"\n                    },\n                    \"fqn\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"query_params\": {\n                      \"type\": \"object\",\n                      \"title\": \"QueryParams\",\n                      \"properties\": {\n                        \"metrics\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"group_by\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"where\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"object\",\n                              \"title\": \"WhereFilterIntersection\",\n                              \"properties\": {\n                                \"where_filters\": {\n                                  \"type\": \"array\",\n                                  \"items\": {\n                                    \"type\": \"object\",\n                                    \"title\": \"WhereFilter\",\n                                    \"properties\": {\n                                      \"where_sql_template\": {\n                                        \"type\": \"string\"\n                                      }\n                                    },\n                                    \"additionalProperties\": false,\n                                    \"required\": [\n                                      \"where_sql_template\"\n                                    ]\n                                  }\n                                }\n                              },\n                              \"additionalProperties\": false,\n                              \"required\": [\n                                \"where_filters\"\n                              ]\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ]\n                        },\n                        \"order_by\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"limit\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"integer\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": false,\n                      \"required\": [\n                        \"metrics\",\n                        \"group_by\",\n                        \"where\"\n                      ]\n                    },\n                    \"exports\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"object\",\n                        \"title\": \"Export\",\n                        \"properties\": {\n                          \"name\": {\n                            \"type\": \"string\"\n                          },\n                          \"config\": {\n                            \"type\": \"object\",\n                            \"title\": \"ExportConfig\",\n                            \"properties\": {\n                              \"export_as\": {\n                                \"enum\": [\n                                  \"table\",\n                                  \"view\"\n                                ]\n                              },\n                              \"schema_name\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"string\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"alias\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"string\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              },\n                              \"database\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"string\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              }\n                            },\n                            \"additionalProperties\": false,\n                            \"required\": [\n                              \"export_as\"\n                            ]\n                          },\n                          \"unrendered_config\": {\n                            \"type\": \"object\",\n                            \"additionalProperties\": {\n                              \"type\": \"string\"\n                            },\n                            \"propertyNames\": {\n                              \"type\": \"string\"\n                            }\n                          }\n                        },\n                        \"additionalProperties\": false,\n                        \"required\": [\n                          \"name\",\n                          \"config\"\n                        ]\n                      }\n                    },\n                    \"description\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"label\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"metadata\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"object\",\n                          \"title\": \"SourceFileMetadata\",\n                          \"properties\": {\n                            \"repo_file_path\": {\n                              \"type\": \"string\"\n                            },\n                            \"file_slice\": {\n                              \"type\": \"object\",\n                              \"title\": \"FileSlice\",\n                              \"properties\": {\n                                \"filename\": {\n                                  \"type\": \"string\"\n                                },\n                                \"content\": {\n                                  \"type\": \"string\"\n                                },\n                                \"start_line_number\": {\n                                  \"type\": \"integer\"\n                                },\n                                \"end_line_number\": {\n                                  \"type\": \"integer\"\n                                }\n                              },\n                              \"additionalProperties\": false,\n                              \"required\": [\n                                \"filename\",\n                                \"content\",\n                                \"start_line_number\",\n                                \"end_line_number\"\n                              ]\n                            }\n                          },\n                          \"additionalProperties\": false,\n                          \"required\": [\n                            \"repo_file_path\",\n                            \"file_slice\"\n                          ]\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"config\": {\n                      \"type\": \"object\",\n                      \"title\": \"SavedQueryConfig\",\n                      \"properties\": {\n                        \"_extra\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"enabled\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"group\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"meta\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"export_as\": {\n                          \"anyOf\": [\n                            {\n                              \"enum\": [\n                                \"table\",\n                                \"view\"\n                              ]\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"schema\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"cache\": {\n                          \"type\": \"object\",\n                          \"title\": \"SavedQueryCache\",\n                          \"properties\": {\n                            \"enabled\": {\n                              \"type\": \"boolean\",\n                              \"default\": false\n                            }\n                          },\n                          \"additionalProperties\": false\n                        }\n                      },\n                      \"additionalProperties\": true\n                    },\n                    \"unrendered_config\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"group\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"depends_on\": {\n                      \"type\": \"object\",\n                      \"title\": \"DependsOn\",\n                      \"properties\": {\n                        \"macros\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"nodes\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      },\n                      \"additionalProperties\": false\n                    },\n                    \"created_at\": {\n                      \"type\": \"number\"\n                    },\n                    \"refs\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"object\",\n                        \"title\": \"RefArgs\",\n                        \"properties\": {\n                          \"name\": {\n                            \"type\": \"string\"\n                          },\n                          \"package\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"version\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"number\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          }\n                        },\n                        \"additionalProperties\": false,\n                        \"required\": [\n                          \"name\"\n                        ]\n                      }\n                    },\n                    \"tags\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        {\n                          \"type\": \"string\"\n                        }\n                      ]\n                    }\n                  },\n                  \"additionalProperties\": false,\n                  \"required\": [\n                    \"name\",\n                    \"resource_type\",\n                    \"package_name\",\n                    \"path\",\n                    \"original_file_path\",\n                    \"unique_id\",\n                    \"fqn\",\n                    \"query_params\",\n                    \"exports\"\n                  ]\n                },\n                {\n                  \"type\": \"object\",\n                  \"title\": \"SemanticModel\",\n                  \"properties\": {\n                    \"name\": {\n                      \"type\": \"string\"\n                    },\n                    \"resource_type\": {\n                      \"enum\": [\n                        \"model\",\n                        \"analysis\",\n                        \"test\",\n                        \"snapshot\",\n                        \"operation\",\n                        \"seed\",\n                        \"rpc\",\n                        \"sql_operation\",\n                        \"doc\",\n                        \"source\",\n                        \"macro\",\n                        \"exposure\",\n                        \"metric\",\n                        \"group\",\n                        \"saved_query\",\n                        \"semantic_model\",\n                        \"unit_test\",\n                        \"fixture\",\n                        \"function\"\n                      ]\n                    },\n                    \"package_name\": {\n                      \"type\": \"string\"\n                    },\n                    \"path\": {\n                      \"type\": \"string\"\n                    },\n                    \"original_file_path\": {\n                      \"type\": \"string\"\n                    },\n                    \"unique_id\": {\n                      \"type\": \"string\"\n                    },\n                    \"fqn\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"model\": {\n                      \"type\": \"string\"\n                    },\n                    \"node_relation\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"object\",\n                          \"title\": \"NodeRelation\",\n                          \"properties\": {\n                            \"alias\": {\n                              \"type\": \"string\"\n                            },\n                            \"schema_name\": {\n                              \"type\": \"string\"\n                            },\n                            \"database\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"relation_name\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": \"\"\n                            }\n                          },\n                          \"additionalProperties\": false,\n                          \"required\": [\n                            \"alias\",\n                            \"schema_name\"\n                          ]\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ]\n                    },\n                    \"description\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"label\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"defaults\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"object\",\n                          \"title\": \"Defaults\",\n                          \"properties\": {\n                            \"agg_time_dimension\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"string\"\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            }\n                          },\n                          \"additionalProperties\": false\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"entities\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"object\",\n                        \"title\": \"Entity\",\n                        \"properties\": {\n                          \"name\": {\n                            \"type\": \"string\"\n                          },\n                          \"type\": {\n                            \"enum\": [\n                              \"foreign\",\n                              \"natural\",\n                              \"primary\",\n                              \"unique\"\n                            ]\n                          },\n                          \"description\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"label\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"role\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"expr\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"config\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"object\",\n                                \"title\": \"SemanticLayerElementConfig\",\n                                \"properties\": {\n                                  \"meta\": {\n                                    \"type\": \"object\",\n                                    \"propertyNames\": {\n                                      \"type\": \"string\"\n                                    }\n                                  }\n                                },\n                                \"additionalProperties\": false\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          }\n                        },\n                        \"additionalProperties\": false,\n                        \"required\": [\n                          \"name\",\n                          \"type\"\n                        ]\n                      }\n                    },\n                    \"measures\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"object\",\n                        \"title\": \"Measure\",\n                        \"properties\": {\n                          \"name\": {\n                            \"type\": \"string\"\n                          },\n                          \"agg\": {\n                            \"enum\": [\n                              \"sum\",\n                              \"min\",\n                              \"max\",\n                              \"count_distinct\",\n                              \"sum_boolean\",\n                              \"average\",\n                              \"percentile\",\n                              \"median\",\n                              \"count\"\n                            ]\n                          },\n                          \"description\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"label\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"create_metric\": {\n                            \"type\": \"boolean\",\n                            \"default\": false\n                          },\n                          \"expr\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"agg_params\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"object\",\n                                \"title\": \"MeasureAggregationParameters\",\n                                \"properties\": {\n                                  \"percentile\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"number\"\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  },\n                                  \"use_discrete_percentile\": {\n                                    \"type\": \"boolean\",\n                                    \"default\": false\n                                  },\n                                  \"use_approximate_percentile\": {\n                                    \"type\": \"boolean\",\n                                    \"default\": false\n                                  }\n                                },\n                                \"additionalProperties\": false\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"non_additive_dimension\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"object\",\n                                \"title\": \"NonAdditiveDimension\",\n                                \"properties\": {\n                                  \"name\": {\n                                    \"type\": \"string\"\n                                  },\n                                  \"window_choice\": {\n                                    \"enum\": [\n                                      \"sum\",\n                                      \"min\",\n                                      \"max\",\n                                      \"count_distinct\",\n                                      \"sum_boolean\",\n                                      \"average\",\n                                      \"percentile\",\n                                      \"median\",\n                                      \"count\"\n                                    ]\n                                  },\n                                  \"window_groupings\": {\n                                    \"type\": \"array\",\n                                    \"items\": {\n                                      \"type\": \"string\"\n                                    }\n                                  }\n                                },\n                                \"additionalProperties\": false,\n                                \"required\": [\n                                  \"name\",\n                                  \"window_choice\",\n                                  \"window_groupings\"\n                                ]\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"agg_time_dimension\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"config\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"object\",\n                                \"title\": \"SemanticLayerElementConfig\",\n                                \"properties\": {\n                                  \"meta\": {\n                                    \"type\": \"object\",\n                                    \"propertyNames\": {\n                                      \"type\": \"string\"\n                                    }\n                                  }\n                                },\n                                \"additionalProperties\": false\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          }\n                        },\n                        \"additionalProperties\": false,\n                        \"required\": [\n                          \"name\",\n                          \"agg\"\n                        ]\n                      }\n                    },\n                    \"dimensions\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"object\",\n                        \"title\": \"Dimension\",\n                        \"properties\": {\n                          \"name\": {\n                            \"type\": \"string\"\n                          },\n                          \"type\": {\n                            \"enum\": [\n                              \"categorical\",\n                              \"time\"\n                            ]\n                          },\n                          \"description\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"label\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"is_partition\": {\n                            \"type\": \"boolean\",\n                            \"default\": false\n                          },\n                          \"type_params\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"object\",\n                                \"title\": \"DimensionTypeParams\",\n                                \"properties\": {\n                                  \"time_granularity\": {\n                                    \"enum\": [\n                                      \"nanosecond\",\n                                      \"microsecond\",\n                                      \"millisecond\",\n                                      \"second\",\n                                      \"minute\",\n                                      \"hour\",\n                                      \"day\",\n                                      \"week\",\n                                      \"month\",\n                                      \"quarter\",\n                                      \"year\"\n                                    ]\n                                  },\n                                  \"validity_params\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"object\",\n                                        \"title\": \"DimensionValidityParams\",\n                                        \"properties\": {\n                                          \"is_start\": {\n                                            \"type\": \"boolean\",\n                                            \"default\": false\n                                          },\n                                          \"is_end\": {\n                                            \"type\": \"boolean\",\n                                            \"default\": false\n                                          }\n                                        },\n                                        \"additionalProperties\": false\n                                      },\n                                      {\n                                        \"type\": \"null\"\n                                      }\n                                    ],\n                                    \"default\": null\n                                  }\n                                },\n                                \"additionalProperties\": false,\n                                \"required\": [\n                                  \"time_granularity\"\n                                ]\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"expr\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"metadata\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"object\",\n                                \"title\": \"SourceFileMetadata\",\n                                \"properties\": {\n                                  \"repo_file_path\": {\n                                    \"type\": \"string\"\n                                  },\n                                  \"file_slice\": {\n                                    \"type\": \"object\",\n                                    \"title\": \"FileSlice\",\n                                    \"properties\": {\n                                      \"filename\": {\n                                        \"type\": \"string\"\n                                      },\n                                      \"content\": {\n                                        \"type\": \"string\"\n                                      },\n                                      \"start_line_number\": {\n                                        \"type\": \"integer\"\n                                      },\n                                      \"end_line_number\": {\n                                        \"type\": \"integer\"\n                                      }\n                                    },\n                                    \"additionalProperties\": false,\n                                    \"required\": [\n                                      \"filename\",\n                                      \"content\",\n                                      \"start_line_number\",\n                                      \"end_line_number\"\n                                    ]\n                                  }\n                                },\n                                \"additionalProperties\": false,\n                                \"required\": [\n                                  \"repo_file_path\",\n                                  \"file_slice\"\n                                ]\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"config\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"object\",\n                                \"title\": \"SemanticLayerElementConfig\",\n                                \"properties\": {\n                                  \"meta\": {\n                                    \"type\": \"object\",\n                                    \"propertyNames\": {\n                                      \"type\": \"string\"\n                                    }\n                                  }\n                                },\n                                \"additionalProperties\": false\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          }\n                        },\n                        \"additionalProperties\": false,\n                        \"required\": [\n                          \"name\",\n                          \"type\"\n                        ]\n                      }\n                    },\n                    \"metadata\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"object\",\n                          \"title\": \"SourceFileMetadata\",\n                          \"properties\": {\n                            \"repo_file_path\": {\n                              \"type\": \"string\"\n                            },\n                            \"file_slice\": {\n                              \"type\": \"object\",\n                              \"title\": \"FileSlice\",\n                              \"properties\": {\n                                \"filename\": {\n                                  \"type\": \"string\"\n                                },\n                                \"content\": {\n                                  \"type\": \"string\"\n                                },\n                                \"start_line_number\": {\n                                  \"type\": \"integer\"\n                                },\n                                \"end_line_number\": {\n                                  \"type\": \"integer\"\n                                }\n                              },\n                              \"additionalProperties\": false,\n                              \"required\": [\n                                \"filename\",\n                                \"content\",\n                                \"start_line_number\",\n                                \"end_line_number\"\n                              ]\n                            }\n                          },\n                          \"additionalProperties\": false,\n                          \"required\": [\n                            \"repo_file_path\",\n                            \"file_slice\"\n                          ]\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"depends_on\": {\n                      \"type\": \"object\",\n                      \"title\": \"DependsOn\",\n                      \"properties\": {\n                        \"macros\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"nodes\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      },\n                      \"additionalProperties\": false\n                    },\n                    \"refs\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"object\",\n                        \"title\": \"RefArgs\",\n                        \"properties\": {\n                          \"name\": {\n                            \"type\": \"string\"\n                          },\n                          \"package\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"version\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"number\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          }\n                        },\n                        \"additionalProperties\": false,\n                        \"required\": [\n                          \"name\"\n                        ]\n                      }\n                    },\n                    \"created_at\": {\n                      \"type\": \"number\"\n                    },\n                    \"config\": {\n                      \"type\": \"object\",\n                      \"title\": \"SemanticModelConfig\",\n                      \"properties\": {\n                        \"_extra\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"enabled\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        },\n                        \"group\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"meta\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      },\n                      \"additionalProperties\": true\n                    },\n                    \"unrendered_config\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"primary_entity\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"group\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    }\n                  },\n                  \"additionalProperties\": false,\n                  \"required\": [\n                    \"name\",\n                    \"resource_type\",\n                    \"package_name\",\n                    \"path\",\n                    \"original_file_path\",\n                    \"unique_id\",\n                    \"fqn\",\n                    \"model\",\n                    \"node_relation\"\n                  ]\n                },\n                {\n                  \"type\": \"object\",\n                  \"title\": \"UnitTestDefinition\",\n                  \"properties\": {\n                    \"model\": {\n                      \"type\": \"string\"\n                    },\n                    \"given\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"object\",\n                        \"title\": \"UnitTestInputFixture\",\n                        \"properties\": {\n                          \"input\": {\n                            \"type\": \"string\"\n                          },\n                          \"rows\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"array\",\n                                \"items\": {\n                                  \"type\": \"object\",\n                                  \"propertyNames\": {\n                                    \"type\": \"string\"\n                                  }\n                                }\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"format\": {\n                            \"enum\": [\n                              \"csv\",\n                              \"dict\",\n                              \"sql\"\n                            ],\n                            \"default\": \"dict\"\n                          },\n                          \"fixture\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          }\n                        },\n                        \"additionalProperties\": false,\n                        \"required\": [\n                          \"input\"\n                        ]\n                      }\n                    },\n                    \"expect\": {\n                      \"type\": \"object\",\n                      \"title\": \"UnitTestOutputFixture\",\n                      \"properties\": {\n                        \"rows\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"array\",\n                              \"items\": {\n                                \"type\": \"object\",\n                                \"propertyNames\": {\n                                  \"type\": \"string\"\n                                }\n                              }\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"format\": {\n                          \"enum\": [\n                            \"csv\",\n                            \"dict\",\n                            \"sql\"\n                          ],\n                          \"default\": \"dict\"\n                        },\n                        \"fixture\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": false\n                    },\n                    \"name\": {\n                      \"type\": \"string\"\n                    },\n                    \"resource_type\": {\n                      \"enum\": [\n                        \"model\",\n                        \"analysis\",\n                        \"test\",\n                        \"snapshot\",\n                        \"operation\",\n                        \"seed\",\n                        \"rpc\",\n                        \"sql_operation\",\n                        \"doc\",\n                        \"source\",\n                        \"macro\",\n                        \"exposure\",\n                        \"metric\",\n                        \"group\",\n                        \"saved_query\",\n                        \"semantic_model\",\n                        \"unit_test\",\n                        \"fixture\",\n                        \"function\"\n                      ]\n                    },\n                    \"package_name\": {\n                      \"type\": \"string\"\n                    },\n                    \"path\": {\n                      \"type\": \"string\"\n                    },\n                    \"original_file_path\": {\n                      \"type\": \"string\"\n                    },\n                    \"unique_id\": {\n                      \"type\": \"string\"\n                    },\n                    \"fqn\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"description\": {\n                      \"type\": \"string\",\n                      \"default\": \"\"\n                    },\n                    \"overrides\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"object\",\n                          \"title\": \"UnitTestOverrides\",\n                          \"properties\": {\n                            \"macros\": {\n                              \"type\": \"object\",\n                              \"propertyNames\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            \"vars\": {\n                              \"type\": \"object\",\n                              \"propertyNames\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            \"env_vars\": {\n                              \"type\": \"object\",\n                              \"propertyNames\": {\n                                \"type\": \"string\"\n                              }\n                            }\n                          },\n                          \"additionalProperties\": false\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"depends_on\": {\n                      \"type\": \"object\",\n                      \"title\": \"DependsOn\",\n                      \"properties\": {\n                        \"macros\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"nodes\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      },\n                      \"additionalProperties\": false\n                    },\n                    \"config\": {\n                      \"type\": \"object\",\n                      \"title\": \"UnitTestConfig\",\n                      \"properties\": {\n                        \"_extra\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"tags\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"array\",\n                              \"items\": {\n                                \"type\": \"string\"\n                              }\n                            }\n                          ]\n                        },\n                        \"meta\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"enabled\": {\n                          \"type\": \"boolean\",\n                          \"default\": true\n                        }\n                      },\n                      \"additionalProperties\": true\n                    },\n                    \"checksum\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"schema\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"created_at\": {\n                      \"type\": \"number\"\n                    },\n                    \"versions\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"object\",\n                          \"title\": \"UnitTestNodeVersions\",\n                          \"properties\": {\n                            \"include\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"array\",\n                                  \"items\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"number\"\n                                      }\n                                    ]\n                                  }\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            },\n                            \"exclude\": {\n                              \"anyOf\": [\n                                {\n                                  \"type\": \"array\",\n                                  \"items\": {\n                                    \"anyOf\": [\n                                      {\n                                        \"type\": \"string\"\n                                      },\n                                      {\n                                        \"type\": \"number\"\n                                      }\n                                    ]\n                                  }\n                                },\n                                {\n                                  \"type\": \"null\"\n                                }\n                              ],\n                              \"default\": null\n                            }\n                          },\n                          \"additionalProperties\": false\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"version\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"number\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    }\n                  },\n                  \"additionalProperties\": false,\n                  \"required\": [\n                    \"model\",\n                    \"given\",\n                    \"expect\",\n                    \"name\",\n                    \"resource_type\",\n                    \"package_name\",\n                    \"path\",\n                    \"original_file_path\",\n                    \"unique_id\",\n                    \"fqn\"\n                  ]\n                }\n              ]\n            }\n          },\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"parent_map\": {\n      \"description\": \"A mapping from\\u00a0child nodes to their dependencies\",\n      \"anyOf\": [\n        {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"child_map\": {\n      \"description\": \"A mapping from parent nodes to their dependents\",\n      \"anyOf\": [\n        {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"group_map\": {\n      \"description\": \"A mapping from group names to their nodes\",\n      \"anyOf\": [\n        {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        {\n          \"type\": \"null\"\n        }\n      ]\n    },\n    \"saved_queries\": {\n      \"type\": \"object\",\n      \"description\": \"The saved queries defined in the dbt project\",\n      \"additionalProperties\": {\n        \"type\": \"object\",\n        \"title\": \"SavedQuery\",\n        \"properties\": {\n          \"name\": {\n            \"type\": \"string\"\n          },\n          \"resource_type\": {\n            \"const\": \"saved_query\"\n          },\n          \"package_name\": {\n            \"type\": \"string\"\n          },\n          \"path\": {\n            \"type\": \"string\"\n          },\n          \"original_file_path\": {\n            \"type\": \"string\"\n          },\n          \"unique_id\": {\n            \"type\": \"string\"\n          },\n          \"fqn\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"query_params\": {\n            \"type\": \"object\",\n            \"title\": \"QueryParams\",\n            \"properties\": {\n              \"metrics\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"group_by\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"where\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"object\",\n                    \"title\": \"WhereFilterIntersection\",\n                    \"properties\": {\n                      \"where_filters\": {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"object\",\n                          \"title\": \"WhereFilter\",\n                          \"properties\": {\n                            \"where_sql_template\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"additionalProperties\": false,\n                          \"required\": [\n                            \"where_sql_template\"\n                          ]\n                        }\n                      }\n                    },\n                    \"additionalProperties\": false,\n                    \"required\": [\n                      \"where_filters\"\n                    ]\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ]\n              },\n              \"order_by\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"limit\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"integer\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              }\n            },\n            \"additionalProperties\": false,\n            \"required\": [\n              \"metrics\",\n              \"group_by\",\n              \"where\"\n            ]\n          },\n          \"exports\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"object\",\n              \"title\": \"Export\",\n              \"properties\": {\n                \"name\": {\n                  \"type\": \"string\"\n                },\n                \"config\": {\n                  \"type\": \"object\",\n                  \"title\": \"ExportConfig\",\n                  \"properties\": {\n                    \"export_as\": {\n                      \"enum\": [\n                        \"table\",\n                        \"view\"\n                      ]\n                    },\n                    \"schema_name\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"alias\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"database\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    }\n                  },\n                  \"additionalProperties\": false,\n                  \"required\": [\n                    \"export_as\"\n                  ]\n                },\n                \"unrendered_config\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"string\"\n                  },\n                  \"propertyNames\": {\n                    \"type\": \"string\"\n                  }\n                }\n              },\n              \"additionalProperties\": false,\n              \"required\": [\n                \"name\",\n                \"config\"\n              ]\n            }\n          },\n          \"description\": {\n            \"anyOf\": [\n              {\n                \"type\": \"string\"\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          },\n          \"label\": {\n            \"anyOf\": [\n              {\n                \"type\": \"string\"\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          },\n          \"metadata\": {\n            \"anyOf\": [\n              {\n                \"type\": \"object\",\n                \"title\": \"SourceFileMetadata\",\n                \"properties\": {\n                  \"repo_file_path\": {\n                    \"type\": \"string\"\n                  },\n                  \"file_slice\": {\n                    \"type\": \"object\",\n                    \"title\": \"FileSlice\",\n                    \"properties\": {\n                      \"filename\": {\n                        \"type\": \"string\"\n                      },\n                      \"content\": {\n                        \"type\": \"string\"\n                      },\n                      \"start_line_number\": {\n                        \"type\": \"integer\"\n                      },\n                      \"end_line_number\": {\n                        \"type\": \"integer\"\n                      }\n                    },\n                    \"additionalProperties\": false,\n                    \"required\": [\n                      \"filename\",\n                      \"content\",\n                      \"start_line_number\",\n                      \"end_line_number\"\n                    ]\n                  }\n                },\n                \"additionalProperties\": false,\n                \"required\": [\n                  \"repo_file_path\",\n                  \"file_slice\"\n                ]\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          },\n          \"config\": {\n            \"type\": \"object\",\n            \"title\": \"SavedQueryConfig\",\n            \"properties\": {\n              \"_extra\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"enabled\": {\n                \"type\": \"boolean\",\n                \"default\": true\n              },\n              \"group\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"meta\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"export_as\": {\n                \"anyOf\": [\n                  {\n                    \"enum\": [\n                      \"table\",\n                      \"view\"\n                    ]\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"schema\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"cache\": {\n                \"type\": \"object\",\n                \"title\": \"SavedQueryCache\",\n                \"properties\": {\n                  \"enabled\": {\n                    \"type\": \"boolean\",\n                    \"default\": false\n                  }\n                },\n                \"additionalProperties\": false\n              }\n            },\n            \"additionalProperties\": true\n          },\n          \"unrendered_config\": {\n            \"type\": \"object\",\n            \"propertyNames\": {\n              \"type\": \"string\"\n            }\n          },\n          \"group\": {\n            \"anyOf\": [\n              {\n                \"type\": \"string\"\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          },\n          \"depends_on\": {\n            \"type\": \"object\",\n            \"title\": \"DependsOn\",\n            \"properties\": {\n              \"macros\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"nodes\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              }\n            },\n            \"additionalProperties\": false\n          },\n          \"created_at\": {\n            \"type\": \"number\"\n          },\n          \"refs\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"object\",\n              \"title\": \"RefArgs\",\n              \"properties\": {\n                \"name\": {\n                  \"type\": \"string\"\n                },\n                \"package\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"string\"\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                },\n                \"version\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"string\"\n                    },\n                    {\n                      \"type\": \"number\"\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                }\n              },\n              \"additionalProperties\": false,\n              \"required\": [\n                \"name\"\n              ]\n            }\n          },\n          \"tags\": {\n            \"anyOf\": [\n              {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              },\n              {\n                \"type\": \"string\"\n              }\n            ]\n          }\n        },\n        \"additionalProperties\": false,\n        \"required\": [\n          \"name\",\n          \"resource_type\",\n          \"package_name\",\n          \"path\",\n          \"original_file_path\",\n          \"unique_id\",\n          \"fqn\",\n          \"query_params\",\n          \"exports\"\n        ]\n      },\n      \"propertyNames\": {\n        \"type\": \"string\"\n      }\n    },\n    \"semantic_models\": {\n      \"type\": \"object\",\n      \"description\": \"The semantic models defined in the dbt project\",\n      \"additionalProperties\": {\n        \"type\": \"object\",\n        \"title\": \"SemanticModel\",\n        \"properties\": {\n          \"name\": {\n            \"type\": \"string\"\n          },\n          \"resource_type\": {\n            \"enum\": [\n              \"model\",\n              \"analysis\",\n              \"test\",\n              \"snapshot\",\n              \"operation\",\n              \"seed\",\n              \"rpc\",\n              \"sql_operation\",\n              \"doc\",\n              \"source\",\n              \"macro\",\n              \"exposure\",\n              \"metric\",\n              \"group\",\n              \"saved_query\",\n              \"semantic_model\",\n              \"unit_test\",\n              \"fixture\",\n              \"function\"\n            ]\n          },\n          \"package_name\": {\n            \"type\": \"string\"\n          },\n          \"path\": {\n            \"type\": \"string\"\n          },\n          \"original_file_path\": {\n            \"type\": \"string\"\n          },\n          \"unique_id\": {\n            \"type\": \"string\"\n          },\n          \"fqn\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"model\": {\n            \"type\": \"string\"\n          },\n          \"node_relation\": {\n            \"anyOf\": [\n              {\n                \"type\": \"object\",\n                \"title\": \"NodeRelation\",\n                \"properties\": {\n                  \"alias\": {\n                    \"type\": \"string\"\n                  },\n                  \"schema_name\": {\n                    \"type\": \"string\"\n                  },\n                  \"database\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"relation_name\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": \"\"\n                  }\n                },\n                \"additionalProperties\": false,\n                \"required\": [\n                  \"alias\",\n                  \"schema_name\"\n                ]\n              },\n              {\n                \"type\": \"null\"\n              }\n            ]\n          },\n          \"description\": {\n            \"anyOf\": [\n              {\n                \"type\": \"string\"\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          },\n          \"label\": {\n            \"anyOf\": [\n              {\n                \"type\": \"string\"\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          },\n          \"defaults\": {\n            \"anyOf\": [\n              {\n                \"type\": \"object\",\n                \"title\": \"Defaults\",\n                \"properties\": {\n                  \"agg_time_dimension\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  }\n                },\n                \"additionalProperties\": false\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          },\n          \"entities\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"object\",\n              \"title\": \"Entity\",\n              \"properties\": {\n                \"name\": {\n                  \"type\": \"string\"\n                },\n                \"type\": {\n                  \"enum\": [\n                    \"foreign\",\n                    \"natural\",\n                    \"primary\",\n                    \"unique\"\n                  ]\n                },\n                \"description\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"string\"\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                },\n                \"label\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"string\"\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                },\n                \"role\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"string\"\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                },\n                \"expr\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"string\"\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                },\n                \"config\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"object\",\n                      \"title\": \"SemanticLayerElementConfig\",\n                      \"properties\": {\n                        \"meta\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      },\n                      \"additionalProperties\": false\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                }\n              },\n              \"additionalProperties\": false,\n              \"required\": [\n                \"name\",\n                \"type\"\n              ]\n            }\n          },\n          \"measures\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"object\",\n              \"title\": \"Measure\",\n              \"properties\": {\n                \"name\": {\n                  \"type\": \"string\"\n                },\n                \"agg\": {\n                  \"enum\": [\n                    \"sum\",\n                    \"min\",\n                    \"max\",\n                    \"count_distinct\",\n                    \"sum_boolean\",\n                    \"average\",\n                    \"percentile\",\n                    \"median\",\n                    \"count\"\n                  ]\n                },\n                \"description\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"string\"\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                },\n                \"label\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"string\"\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                },\n                \"create_metric\": {\n                  \"type\": \"boolean\",\n                  \"default\": false\n                },\n                \"expr\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"string\"\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                },\n                \"agg_params\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"object\",\n                      \"title\": \"MeasureAggregationParameters\",\n                      \"properties\": {\n                        \"percentile\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"number\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"use_discrete_percentile\": {\n                          \"type\": \"boolean\",\n                          \"default\": false\n                        },\n                        \"use_approximate_percentile\": {\n                          \"type\": \"boolean\",\n                          \"default\": false\n                        }\n                      },\n                      \"additionalProperties\": false\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                },\n                \"non_additive_dimension\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"object\",\n                      \"title\": \"NonAdditiveDimension\",\n                      \"properties\": {\n                        \"name\": {\n                          \"type\": \"string\"\n                        },\n                        \"window_choice\": {\n                          \"enum\": [\n                            \"sum\",\n                            \"min\",\n                            \"max\",\n                            \"count_distinct\",\n                            \"sum_boolean\",\n                            \"average\",\n                            \"percentile\",\n                            \"median\",\n                            \"count\"\n                          ]\n                        },\n                        \"window_groupings\": {\n                          \"type\": \"array\",\n                          \"items\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      },\n                      \"additionalProperties\": false,\n                      \"required\": [\n                        \"name\",\n                        \"window_choice\",\n                        \"window_groupings\"\n                      ]\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                },\n                \"agg_time_dimension\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"string\"\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                },\n                \"config\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"object\",\n                      \"title\": \"SemanticLayerElementConfig\",\n                      \"properties\": {\n                        \"meta\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      },\n                      \"additionalProperties\": false\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                }\n              },\n              \"additionalProperties\": false,\n              \"required\": [\n                \"name\",\n                \"agg\"\n              ]\n            }\n          },\n          \"dimensions\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"object\",\n              \"title\": \"Dimension\",\n              \"properties\": {\n                \"name\": {\n                  \"type\": \"string\"\n                },\n                \"type\": {\n                  \"enum\": [\n                    \"categorical\",\n                    \"time\"\n                  ]\n                },\n                \"description\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"string\"\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                },\n                \"label\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"string\"\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                },\n                \"is_partition\": {\n                  \"type\": \"boolean\",\n                  \"default\": false\n                },\n                \"type_params\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"object\",\n                      \"title\": \"DimensionTypeParams\",\n                      \"properties\": {\n                        \"time_granularity\": {\n                          \"enum\": [\n                            \"nanosecond\",\n                            \"microsecond\",\n                            \"millisecond\",\n                            \"second\",\n                            \"minute\",\n                            \"hour\",\n                            \"day\",\n                            \"week\",\n                            \"month\",\n                            \"quarter\",\n                            \"year\"\n                          ]\n                        },\n                        \"validity_params\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"object\",\n                              \"title\": \"DimensionValidityParams\",\n                              \"properties\": {\n                                \"is_start\": {\n                                  \"type\": \"boolean\",\n                                  \"default\": false\n                                },\n                                \"is_end\": {\n                                  \"type\": \"boolean\",\n                                  \"default\": false\n                                }\n                              },\n                              \"additionalProperties\": false\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": false,\n                      \"required\": [\n                        \"time_granularity\"\n                      ]\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                },\n                \"expr\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"string\"\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                },\n                \"metadata\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"object\",\n                      \"title\": \"SourceFileMetadata\",\n                      \"properties\": {\n                        \"repo_file_path\": {\n                          \"type\": \"string\"\n                        },\n                        \"file_slice\": {\n                          \"type\": \"object\",\n                          \"title\": \"FileSlice\",\n                          \"properties\": {\n                            \"filename\": {\n                              \"type\": \"string\"\n                            },\n                            \"content\": {\n                              \"type\": \"string\"\n                            },\n                            \"start_line_number\": {\n                              \"type\": \"integer\"\n                            },\n                            \"end_line_number\": {\n                              \"type\": \"integer\"\n                            }\n                          },\n                          \"additionalProperties\": false,\n                          \"required\": [\n                            \"filename\",\n                            \"content\",\n                            \"start_line_number\",\n                            \"end_line_number\"\n                          ]\n                        }\n                      },\n                      \"additionalProperties\": false,\n                      \"required\": [\n                        \"repo_file_path\",\n                        \"file_slice\"\n                      ]\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                },\n                \"config\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"object\",\n                      \"title\": \"SemanticLayerElementConfig\",\n                      \"properties\": {\n                        \"meta\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      },\n                      \"additionalProperties\": false\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                }\n              },\n              \"additionalProperties\": false,\n              \"required\": [\n                \"name\",\n                \"type\"\n              ]\n            }\n          },\n          \"metadata\": {\n            \"anyOf\": [\n              {\n                \"type\": \"object\",\n                \"title\": \"SourceFileMetadata\",\n                \"properties\": {\n                  \"repo_file_path\": {\n                    \"type\": \"string\"\n                  },\n                  \"file_slice\": {\n                    \"type\": \"object\",\n                    \"title\": \"FileSlice\",\n                    \"properties\": {\n                      \"filename\": {\n                        \"type\": \"string\"\n                      },\n                      \"content\": {\n                        \"type\": \"string\"\n                      },\n                      \"start_line_number\": {\n                        \"type\": \"integer\"\n                      },\n                      \"end_line_number\": {\n                        \"type\": \"integer\"\n                      }\n                    },\n                    \"additionalProperties\": false,\n                    \"required\": [\n                      \"filename\",\n                      \"content\",\n                      \"start_line_number\",\n                      \"end_line_number\"\n                    ]\n                  }\n                },\n                \"additionalProperties\": false,\n                \"required\": [\n                  \"repo_file_path\",\n                  \"file_slice\"\n                ]\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          },\n          \"depends_on\": {\n            \"type\": \"object\",\n            \"title\": \"DependsOn\",\n            \"properties\": {\n              \"macros\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"nodes\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              }\n            },\n            \"additionalProperties\": false\n          },\n          \"refs\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"object\",\n              \"title\": \"RefArgs\",\n              \"properties\": {\n                \"name\": {\n                  \"type\": \"string\"\n                },\n                \"package\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"string\"\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                },\n                \"version\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"string\"\n                    },\n                    {\n                      \"type\": \"number\"\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                }\n              },\n              \"additionalProperties\": false,\n              \"required\": [\n                \"name\"\n              ]\n            }\n          },\n          \"created_at\": {\n            \"type\": \"number\"\n          },\n          \"config\": {\n            \"type\": \"object\",\n            \"title\": \"SemanticModelConfig\",\n            \"properties\": {\n              \"_extra\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"enabled\": {\n                \"type\": \"boolean\",\n                \"default\": true\n              },\n              \"group\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"meta\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              }\n            },\n            \"additionalProperties\": true\n          },\n          \"unrendered_config\": {\n            \"type\": \"object\",\n            \"propertyNames\": {\n              \"type\": \"string\"\n            }\n          },\n          \"primary_entity\": {\n            \"anyOf\": [\n              {\n                \"type\": \"string\"\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          },\n          \"group\": {\n            \"anyOf\": [\n              {\n                \"type\": \"string\"\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          }\n        },\n        \"additionalProperties\": false,\n        \"required\": [\n          \"name\",\n          \"resource_type\",\n          \"package_name\",\n          \"path\",\n          \"original_file_path\",\n          \"unique_id\",\n          \"fqn\",\n          \"model\",\n          \"node_relation\"\n        ]\n      },\n      \"propertyNames\": {\n        \"type\": \"string\"\n      }\n    },\n    \"unit_tests\": {\n      \"type\": \"object\",\n      \"description\": \"The unit tests defined in the project\",\n      \"additionalProperties\": {\n        \"type\": \"object\",\n        \"title\": \"UnitTestDefinition\",\n        \"properties\": {\n          \"model\": {\n            \"type\": \"string\"\n          },\n          \"given\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"object\",\n              \"title\": \"UnitTestInputFixture\",\n              \"properties\": {\n                \"input\": {\n                  \"type\": \"string\"\n                },\n                \"rows\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"string\"\n                    },\n                    {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"object\",\n                        \"propertyNames\": {\n                          \"type\": \"string\"\n                        }\n                      }\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                },\n                \"format\": {\n                  \"enum\": [\n                    \"csv\",\n                    \"dict\",\n                    \"sql\"\n                  ],\n                  \"default\": \"dict\"\n                },\n                \"fixture\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"string\"\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                }\n              },\n              \"additionalProperties\": false,\n              \"required\": [\n                \"input\"\n              ]\n            }\n          },\n          \"expect\": {\n            \"type\": \"object\",\n            \"title\": \"UnitTestOutputFixture\",\n            \"properties\": {\n              \"rows\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    }\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"format\": {\n                \"enum\": [\n                  \"csv\",\n                  \"dict\",\n                  \"sql\"\n                ],\n                \"default\": \"dict\"\n              },\n              \"fixture\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              }\n            },\n            \"additionalProperties\": false\n          },\n          \"name\": {\n            \"type\": \"string\"\n          },\n          \"resource_type\": {\n            \"enum\": [\n              \"model\",\n              \"analysis\",\n              \"test\",\n              \"snapshot\",\n              \"operation\",\n              \"seed\",\n              \"rpc\",\n              \"sql_operation\",\n              \"doc\",\n              \"source\",\n              \"macro\",\n              \"exposure\",\n              \"metric\",\n              \"group\",\n              \"saved_query\",\n              \"semantic_model\",\n              \"unit_test\",\n              \"fixture\",\n              \"function\"\n            ]\n          },\n          \"package_name\": {\n            \"type\": \"string\"\n          },\n          \"path\": {\n            \"type\": \"string\"\n          },\n          \"original_file_path\": {\n            \"type\": \"string\"\n          },\n          \"unique_id\": {\n            \"type\": \"string\"\n          },\n          \"fqn\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"description\": {\n            \"type\": \"string\",\n            \"default\": \"\"\n          },\n          \"overrides\": {\n            \"anyOf\": [\n              {\n                \"type\": \"object\",\n                \"title\": \"UnitTestOverrides\",\n                \"properties\": {\n                  \"macros\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"vars\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"env_vars\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  }\n                },\n                \"additionalProperties\": false\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          },\n          \"depends_on\": {\n            \"type\": \"object\",\n            \"title\": \"DependsOn\",\n            \"properties\": {\n              \"macros\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"nodes\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              }\n            },\n            \"additionalProperties\": false\n          },\n          \"config\": {\n            \"type\": \"object\",\n            \"title\": \"UnitTestConfig\",\n            \"properties\": {\n              \"_extra\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"tags\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  }\n                ]\n              },\n              \"meta\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"enabled\": {\n                \"type\": \"boolean\",\n                \"default\": true\n              }\n            },\n            \"additionalProperties\": true\n          },\n          \"checksum\": {\n            \"anyOf\": [\n              {\n                \"type\": \"string\"\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          },\n          \"schema\": {\n            \"anyOf\": [\n              {\n                \"type\": \"string\"\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          },\n          \"created_at\": {\n            \"type\": \"number\"\n          },\n          \"versions\": {\n            \"anyOf\": [\n              {\n                \"type\": \"object\",\n                \"title\": \"UnitTestNodeVersions\",\n                \"properties\": {\n                  \"include\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"number\"\n                            }\n                          ]\n                        }\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  },\n                  \"exclude\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"number\"\n                            }\n                          ]\n                        }\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  }\n                },\n                \"additionalProperties\": false\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          },\n          \"version\": {\n            \"anyOf\": [\n              {\n                \"type\": \"string\"\n              },\n              {\n                \"type\": \"number\"\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          }\n        },\n        \"additionalProperties\": false,\n        \"required\": [\n          \"model\",\n          \"given\",\n          \"expect\",\n          \"name\",\n          \"resource_type\",\n          \"package_name\",\n          \"path\",\n          \"original_file_path\",\n          \"unique_id\",\n          \"fqn\"\n        ]\n      },\n      \"propertyNames\": {\n        \"type\": \"string\"\n      }\n    },\n    \"functions\": {\n      \"type\": \"object\",\n      \"description\": \"The functions defined in the dbt project\",\n      \"additionalProperties\": {\n        \"type\": \"object\",\n        \"title\": \"Function\",\n        \"properties\": {\n          \"returns\": {\n            \"type\": \"object\",\n            \"title\": \"FunctionReturns\",\n            \"properties\": {\n              \"data_type\": {\n                \"type\": \"string\"\n              },\n              \"description\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              }\n            },\n            \"additionalProperties\": false,\n            \"required\": [\n              \"data_type\"\n            ]\n          },\n          \"database\": {\n            \"anyOf\": [\n              {\n                \"type\": \"string\"\n              },\n              {\n                \"type\": \"null\"\n              }\n            ]\n          },\n          \"schema\": {\n            \"type\": \"string\"\n          },\n          \"name\": {\n            \"type\": \"string\"\n          },\n          \"resource_type\": {\n            \"const\": \"function\"\n          },\n          \"package_name\": {\n            \"type\": \"string\"\n          },\n          \"path\": {\n            \"type\": \"string\"\n          },\n          \"original_file_path\": {\n            \"type\": \"string\"\n          },\n          \"unique_id\": {\n            \"type\": \"string\"\n          },\n          \"fqn\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"alias\": {\n            \"type\": \"string\"\n          },\n          \"checksum\": {\n            \"type\": \"object\",\n            \"title\": \"FileHash\",\n            \"properties\": {\n              \"name\": {\n                \"type\": \"string\"\n              },\n              \"checksum\": {\n                \"type\": \"string\"\n              }\n            },\n            \"additionalProperties\": false,\n            \"required\": [\n              \"name\",\n              \"checksum\"\n            ]\n          },\n          \"config\": {\n            \"type\": \"object\",\n            \"title\": \"FunctionConfig\",\n            \"properties\": {\n              \"_extra\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"enabled\": {\n                \"type\": \"boolean\",\n                \"default\": true\n              },\n              \"alias\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"schema\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"database\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"tags\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  {\n                    \"type\": \"string\"\n                  }\n                ]\n              },\n              \"meta\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"group\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"materialized\": {\n                \"type\": \"string\",\n                \"default\": \"function\"\n              },\n              \"incremental_strategy\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"batch_size\": {\n                \"default\": null\n              },\n              \"lookback\": {\n                \"default\": 1\n              },\n              \"begin\": {\n                \"default\": null\n              },\n              \"persist_docs\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"post-hook\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"object\",\n                  \"title\": \"Hook\",\n                  \"properties\": {\n                    \"sql\": {\n                      \"type\": \"string\"\n                    },\n                    \"transaction\": {\n                      \"type\": \"boolean\",\n                      \"default\": true\n                    },\n                    \"index\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"integer\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    }\n                  },\n                  \"additionalProperties\": false,\n                  \"required\": [\n                    \"sql\"\n                  ]\n                }\n              },\n              \"pre-hook\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"object\",\n                  \"title\": \"Hook\",\n                  \"properties\": {\n                    \"sql\": {\n                      \"type\": \"string\"\n                    },\n                    \"transaction\": {\n                      \"type\": \"boolean\",\n                      \"default\": true\n                    },\n                    \"index\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"integer\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    }\n                  },\n                  \"additionalProperties\": false,\n                  \"required\": [\n                    \"sql\"\n                  ]\n                }\n              },\n              \"quoting\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"column_types\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"full_refresh\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"boolean\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"unique_key\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"on_schema_change\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": \"ignore\"\n              },\n              \"on_configuration_change\": {\n                \"enum\": [\n                  \"apply\",\n                  \"continue\",\n                  \"fail\"\n                ]\n              },\n              \"grants\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"packages\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"docs\": {\n                \"type\": \"object\",\n                \"title\": \"Docs\",\n                \"properties\": {\n                  \"show\": {\n                    \"type\": \"boolean\",\n                    \"default\": true\n                  },\n                  \"node_color\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  }\n                },\n                \"additionalProperties\": false\n              },\n              \"contract\": {\n                \"type\": \"object\",\n                \"title\": \"ContractConfig\",\n                \"properties\": {\n                  \"enforced\": {\n                    \"type\": \"boolean\",\n                    \"default\": false\n                  },\n                  \"alias_types\": {\n                    \"type\": \"boolean\",\n                    \"default\": true\n                  }\n                },\n                \"additionalProperties\": false\n              },\n              \"event_time\": {\n                \"default\": null\n              },\n              \"concurrent_batches\": {\n                \"default\": null\n              },\n              \"type\": {\n                \"enum\": [\n                  \"scalar\",\n                  \"aggregate\",\n                  \"table\"\n                ],\n                \"default\": \"scalar\"\n              },\n              \"volatility\": {\n                \"anyOf\": [\n                  {\n                    \"enum\": [\n                      \"deterministic\",\n                      \"stable\",\n                      \"non-deterministic\"\n                    ]\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"runtime_version\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              },\n              \"entry_point\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              }\n            },\n            \"additionalProperties\": true\n          },\n          \"tags\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"description\": {\n            \"type\": \"string\",\n            \"default\": \"\"\n          },\n          \"columns\": {\n            \"type\": \"object\",\n            \"additionalProperties\": {\n              \"type\": \"object\",\n              \"title\": \"ColumnInfo\",\n              \"properties\": {\n                \"name\": {\n                  \"type\": \"string\"\n                },\n                \"description\": {\n                  \"type\": \"string\",\n                  \"default\": \"\"\n                },\n                \"meta\": {\n                  \"type\": \"object\",\n                  \"propertyNames\": {\n                    \"type\": \"string\"\n                  }\n                },\n                \"data_type\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"string\"\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                },\n                \"constraints\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"object\",\n                    \"title\": \"ColumnLevelConstraint\",\n                    \"properties\": {\n                      \"type\": {\n                        \"enum\": [\n                          \"check\",\n                          \"not_null\",\n                          \"unique\",\n                          \"primary_key\",\n                          \"foreign_key\",\n                          \"custom\"\n                        ]\n                      },\n                      \"name\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"string\"\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ],\n                        \"default\": null\n                      },\n                      \"expression\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"string\"\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ],\n                        \"default\": null\n                      },\n                      \"warn_unenforced\": {\n                        \"type\": \"boolean\",\n                        \"default\": true\n                      },\n                      \"warn_unsupported\": {\n                        \"type\": \"boolean\",\n                        \"default\": true\n                      },\n                      \"to\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"string\"\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ],\n                        \"default\": null\n                      },\n                      \"to_columns\": {\n                        \"type\": \"array\",\n                        \"items\": {\n                          \"type\": \"string\"\n                        }\n                      }\n                    },\n                    \"additionalProperties\": false,\n                    \"required\": [\n                      \"type\"\n                    ]\n                  }\n                },\n                \"quote\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"boolean\"\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                },\n                \"config\": {\n                  \"type\": \"object\",\n                  \"title\": \"ColumnConfig\",\n                  \"properties\": {\n                    \"_extra\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"meta\": {\n                      \"type\": \"object\",\n                      \"propertyNames\": {\n                        \"type\": \"string\"\n                      }\n                    },\n                    \"tags\": {\n                      \"type\": \"array\",\n                      \"items\": {\n                        \"type\": \"string\"\n                      }\n                    }\n                  },\n                  \"additionalProperties\": true\n                },\n                \"tags\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"string\"\n                  }\n                },\n                \"_extra\": {\n                  \"type\": \"object\",\n                  \"propertyNames\": {\n                    \"type\": \"string\"\n                  }\n                },\n                \"granularity\": {\n                  \"anyOf\": [\n                    {\n                      \"enum\": [\n                        \"nanosecond\",\n                        \"microsecond\",\n                        \"millisecond\",\n                        \"second\",\n                        \"minute\",\n                        \"hour\",\n                        \"day\",\n                        \"week\",\n                        \"month\",\n                        \"quarter\",\n                        \"year\"\n                      ]\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                },\n                \"dimension\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"object\",\n                      \"title\": \"ColumnDimension\",\n                      \"properties\": {\n                        \"name\": {\n                          \"type\": \"string\"\n                        },\n                        \"type\": {\n                          \"enum\": [\n                            \"categorical\",\n                            \"time\"\n                          ]\n                        },\n                        \"description\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"label\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"is_partition\": {\n                          \"type\": \"boolean\",\n                          \"default\": false\n                        },\n                        \"config\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        },\n                        \"validity_params\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"object\",\n                              \"title\": \"ColumnDimensionValidityParams\",\n                              \"properties\": {\n                                \"is_start\": {\n                                  \"type\": \"boolean\",\n                                  \"default\": false\n                                },\n                                \"is_end\": {\n                                  \"type\": \"boolean\",\n                                  \"default\": false\n                                }\n                              },\n                              \"additionalProperties\": false\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": false,\n                      \"required\": [\n                        \"name\",\n                        \"type\"\n                      ]\n                    },\n                    {\n                      \"enum\": [\n                        \"categorical\",\n                        \"time\"\n                      ]\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                },\n                \"entity\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"object\",\n                      \"title\": \"ColumnEntity\",\n                      \"properties\": {\n                        \"name\": {\n                          \"type\": \"string\"\n                        },\n                        \"type\": {\n                          \"enum\": [\n                            \"foreign\",\n                            \"natural\",\n                            \"primary\",\n                            \"unique\"\n                          ]\n                        },\n                        \"description\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"label\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"config\": {\n                          \"type\": \"object\",\n                          \"propertyNames\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      },\n                      \"additionalProperties\": false,\n                      \"required\": [\n                        \"name\",\n                        \"type\"\n                      ]\n                    },\n                    {\n                      \"enum\": [\n                        \"foreign\",\n                        \"natural\",\n                        \"primary\",\n                        \"unique\"\n                      ]\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                },\n                \"doc_blocks\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"string\"\n                  }\n                }\n              },\n              \"additionalProperties\": true,\n              \"required\": [\n                \"name\"\n              ]\n            },\n            \"propertyNames\": {\n              \"type\": \"string\"\n            }\n          },\n          \"meta\": {\n            \"type\": \"object\",\n            \"propertyNames\": {\n              \"type\": \"string\"\n            }\n          },\n          \"group\": {\n            \"anyOf\": [\n              {\n                \"type\": \"string\"\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          },\n          \"docs\": {\n            \"type\": \"object\",\n            \"title\": \"Docs\",\n            \"properties\": {\n              \"show\": {\n                \"type\": \"boolean\",\n                \"default\": true\n              },\n              \"node_color\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              }\n            },\n            \"additionalProperties\": false\n          },\n          \"patch_path\": {\n            \"anyOf\": [\n              {\n                \"type\": \"string\"\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          },\n          \"build_path\": {\n            \"anyOf\": [\n              {\n                \"type\": \"string\"\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          },\n          \"unrendered_config\": {\n            \"type\": \"object\",\n            \"propertyNames\": {\n              \"type\": \"string\"\n            }\n          },\n          \"created_at\": {\n            \"type\": \"number\"\n          },\n          \"config_call_dict\": {\n            \"type\": \"object\",\n            \"propertyNames\": {\n              \"type\": \"string\"\n            }\n          },\n          \"unrendered_config_call_dict\": {\n            \"type\": \"object\",\n            \"propertyNames\": {\n              \"type\": \"string\"\n            }\n          },\n          \"relation_name\": {\n            \"anyOf\": [\n              {\n                \"type\": \"string\"\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          },\n          \"raw_code\": {\n            \"type\": \"string\",\n            \"default\": \"\"\n          },\n          \"doc_blocks\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"language\": {\n            \"type\": \"string\",\n            \"default\": \"sql\"\n          },\n          \"refs\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"object\",\n              \"title\": \"RefArgs\",\n              \"properties\": {\n                \"name\": {\n                  \"type\": \"string\"\n                },\n                \"package\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"string\"\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                },\n                \"version\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"string\"\n                    },\n                    {\n                      \"type\": \"number\"\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                }\n              },\n              \"additionalProperties\": false,\n              \"required\": [\n                \"name\"\n              ]\n            }\n          },\n          \"sources\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            }\n          },\n          \"metrics\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            }\n          },\n          \"functions\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            }\n          },\n          \"depends_on\": {\n            \"type\": \"object\",\n            \"title\": \"DependsOn\",\n            \"properties\": {\n              \"macros\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"nodes\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"string\"\n                }\n              }\n            },\n            \"additionalProperties\": false\n          },\n          \"compiled_path\": {\n            \"anyOf\": [\n              {\n                \"type\": \"string\"\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          },\n          \"compiled\": {\n            \"type\": \"boolean\",\n            \"default\": false\n          },\n          \"compiled_code\": {\n            \"anyOf\": [\n              {\n                \"type\": \"string\"\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          },\n          \"extra_ctes_injected\": {\n            \"type\": \"boolean\",\n            \"default\": false\n          },\n          \"extra_ctes\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"object\",\n              \"title\": \"InjectedCTE\",\n              \"properties\": {\n                \"id\": {\n                  \"type\": \"string\"\n                },\n                \"sql\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"additionalProperties\": false,\n              \"required\": [\n                \"id\",\n                \"sql\"\n              ]\n            }\n          },\n          \"_pre_injected_sql\": {\n            \"anyOf\": [\n              {\n                \"type\": \"string\"\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          },\n          \"contract\": {\n            \"type\": \"object\",\n            \"title\": \"Contract\",\n            \"properties\": {\n              \"enforced\": {\n                \"type\": \"boolean\",\n                \"default\": false\n              },\n              \"alias_types\": {\n                \"type\": \"boolean\",\n                \"default\": true\n              },\n              \"checksum\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ],\n                \"default\": null\n              }\n            },\n            \"additionalProperties\": false\n          },\n          \"arguments\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"object\",\n              \"title\": \"FunctionArgument\",\n              \"properties\": {\n                \"name\": {\n                  \"type\": \"string\"\n                },\n                \"data_type\": {\n                  \"type\": \"string\"\n                },\n                \"description\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"string\"\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                },\n                \"default_value\": {\n                  \"anyOf\": [\n                    {},\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                }\n              },\n              \"additionalProperties\": false,\n              \"required\": [\n                \"name\",\n                \"data_type\"\n              ]\n            }\n          },\n          \"defer_function\": {\n            \"anyOf\": [\n              {\n                \"type\": \"object\",\n                \"title\": \"DeferFunction\",\n                \"properties\": {\n                  \"database\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ]\n                  },\n                  \"schema\": {\n                    \"type\": \"string\"\n                  },\n                  \"alias\": {\n                    \"type\": \"string\"\n                  },\n                  \"resource_type\": {\n                    \"enum\": [\n                      \"model\",\n                      \"analysis\",\n                      \"test\",\n                      \"snapshot\",\n                      \"operation\",\n                      \"seed\",\n                      \"rpc\",\n                      \"sql_operation\",\n                      \"doc\",\n                      \"source\",\n                      \"macro\",\n                      \"exposure\",\n                      \"metric\",\n                      \"group\",\n                      \"saved_query\",\n                      \"semantic_model\",\n                      \"unit_test\",\n                      \"fixture\",\n                      \"function\"\n                    ]\n                  },\n                  \"name\": {\n                    \"type\": \"string\"\n                  },\n                  \"description\": {\n                    \"type\": \"string\"\n                  },\n                  \"compiled_code\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ]\n                  },\n                  \"meta\": {\n                    \"type\": \"object\",\n                    \"propertyNames\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"tags\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"config\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"object\",\n                        \"title\": \"FunctionConfig\",\n                        \"properties\": {\n                          \"_extra\": {\n                            \"type\": \"object\",\n                            \"propertyNames\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"enabled\": {\n                            \"type\": \"boolean\",\n                            \"default\": true\n                          },\n                          \"alias\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"schema\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"database\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"tags\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"array\",\n                                \"items\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              {\n                                \"type\": \"string\"\n                              }\n                            ]\n                          },\n                          \"meta\": {\n                            \"type\": \"object\",\n                            \"propertyNames\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"group\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"materialized\": {\n                            \"type\": \"string\",\n                            \"default\": \"function\"\n                          },\n                          \"incremental_strategy\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"batch_size\": {\n                            \"default\": null\n                          },\n                          \"lookback\": {\n                            \"default\": 1\n                          },\n                          \"begin\": {\n                            \"default\": null\n                          },\n                          \"persist_docs\": {\n                            \"type\": \"object\",\n                            \"propertyNames\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"post-hook\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"object\",\n                              \"title\": \"Hook\",\n                              \"properties\": {\n                                \"sql\": {\n                                  \"type\": \"string\"\n                                },\n                                \"transaction\": {\n                                  \"type\": \"boolean\",\n                                  \"default\": true\n                                },\n                                \"index\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"integer\"\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                }\n                              },\n                              \"additionalProperties\": false,\n                              \"required\": [\n                                \"sql\"\n                              ]\n                            }\n                          },\n                          \"pre-hook\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"object\",\n                              \"title\": \"Hook\",\n                              \"properties\": {\n                                \"sql\": {\n                                  \"type\": \"string\"\n                                },\n                                \"transaction\": {\n                                  \"type\": \"boolean\",\n                                  \"default\": true\n                                },\n                                \"index\": {\n                                  \"anyOf\": [\n                                    {\n                                      \"type\": \"integer\"\n                                    },\n                                    {\n                                      \"type\": \"null\"\n                                    }\n                                  ],\n                                  \"default\": null\n                                }\n                              },\n                              \"additionalProperties\": false,\n                              \"required\": [\n                                \"sql\"\n                              ]\n                            }\n                          },\n                          \"quoting\": {\n                            \"type\": \"object\",\n                            \"propertyNames\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"column_types\": {\n                            \"type\": \"object\",\n                            \"propertyNames\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"full_refresh\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"boolean\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"unique_key\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"array\",\n                                \"items\": {\n                                  \"type\": \"string\"\n                                }\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"on_schema_change\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": \"ignore\"\n                          },\n                          \"on_configuration_change\": {\n                            \"enum\": [\n                              \"apply\",\n                              \"continue\",\n                              \"fail\"\n                            ]\n                          },\n                          \"grants\": {\n                            \"type\": \"object\",\n                            \"propertyNames\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"packages\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"docs\": {\n                            \"type\": \"object\",\n                            \"title\": \"Docs\",\n                            \"properties\": {\n                              \"show\": {\n                                \"type\": \"boolean\",\n                                \"default\": true\n                              },\n                              \"node_color\": {\n                                \"anyOf\": [\n                                  {\n                                    \"type\": \"string\"\n                                  },\n                                  {\n                                    \"type\": \"null\"\n                                  }\n                                ],\n                                \"default\": null\n                              }\n                            },\n                            \"additionalProperties\": false\n                          },\n                          \"contract\": {\n                            \"type\": \"object\",\n                            \"title\": \"ContractConfig\",\n                            \"properties\": {\n                              \"enforced\": {\n                                \"type\": \"boolean\",\n                                \"default\": false\n                              },\n                              \"alias_types\": {\n                                \"type\": \"boolean\",\n                                \"default\": true\n                              }\n                            },\n                            \"additionalProperties\": false\n                          },\n                          \"event_time\": {\n                            \"default\": null\n                          },\n                          \"concurrent_batches\": {\n                            \"default\": null\n                          },\n                          \"type\": {\n                            \"enum\": [\n                              \"scalar\",\n                              \"aggregate\",\n                              \"table\"\n                            ],\n                            \"default\": \"scalar\"\n                          },\n                          \"volatility\": {\n                            \"anyOf\": [\n                              {\n                                \"enum\": [\n                                  \"deterministic\",\n                                  \"stable\",\n                                  \"non-deterministic\"\n                                ]\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"runtime_version\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"entry_point\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"string\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          }\n                        },\n                        \"additionalProperties\": true\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ]\n                  },\n                  \"arguments\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"title\": \"FunctionArgument\",\n                      \"properties\": {\n                        \"name\": {\n                          \"type\": \"string\"\n                        },\n                        \"data_type\": {\n                          \"type\": \"string\"\n                        },\n                        \"description\": {\n                          \"anyOf\": [\n                            {\n                              \"type\": \"string\"\n                            },\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        },\n                        \"default_value\": {\n                          \"anyOf\": [\n                            {},\n                            {\n                              \"type\": \"null\"\n                            }\n                          ],\n                          \"default\": null\n                        }\n                      },\n                      \"additionalProperties\": false,\n                      \"required\": [\n                        \"name\",\n                        \"data_type\"\n                      ]\n                    }\n                  },\n                  \"returns\": {\n                    \"type\": \"object\",\n                    \"title\": \"FunctionReturns\",\n                    \"properties\": {\n                      \"data_type\": {\n                        \"type\": \"string\"\n                      },\n                      \"description\": {\n                        \"anyOf\": [\n                          {\n                            \"type\": \"string\"\n                          },\n                          {\n                            \"type\": \"null\"\n                          }\n                        ],\n                        \"default\": null\n                      }\n                    },\n                    \"additionalProperties\": false,\n                    \"required\": [\n                      \"data_type\"\n                    ]\n                  }\n                },\n                \"additionalProperties\": false,\n                \"required\": [\n                  \"database\",\n                  \"schema\",\n                  \"alias\",\n                  \"resource_type\",\n                  \"name\",\n                  \"description\",\n                  \"compiled_code\",\n                  \"meta\",\n                  \"tags\",\n                  \"config\",\n                  \"arguments\",\n                  \"returns\"\n                ]\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          }\n        },\n        \"additionalProperties\": false,\n        \"required\": [\n          \"returns\",\n          \"database\",\n          \"schema\",\n          \"name\",\n          \"resource_type\",\n          \"package_name\",\n          \"path\",\n          \"original_file_path\",\n          \"unique_id\",\n          \"fqn\",\n          \"alias\",\n          \"checksum\",\n          \"config\"\n        ]\n      },\n      \"propertyNames\": {\n        \"type\": \"string\"\n      }\n    }\n  },\n  \"additionalProperties\": false,\n  \"required\": [\n    \"metadata\",\n    \"nodes\",\n    \"sources\",\n    \"macros\",\n    \"docs\",\n    \"exposures\",\n    \"metrics\",\n    \"groups\",\n    \"selectors\",\n    \"disabled\",\n    \"parent_map\",\n    \"child_map\",\n    \"group_map\",\n    \"saved_queries\",\n    \"semantic_models\",\n    \"unit_tests\"\n  ],\n  \"$id\": \"https://schemas.getdbt.com/dbt/manifest/v12.json\"\n}"
  },
  {
    "path": "schemas/dbt/manifest/v5.json",
    "content": "{\n  \"type\": \"object\",\n  \"required\": [\n    \"metadata\",\n    \"nodes\",\n    \"sources\",\n    \"macros\",\n    \"docs\",\n    \"exposures\",\n    \"metrics\",\n    \"selectors\"\n  ],\n  \"properties\": {\n    \"metadata\": {\n      \"$ref\": \"#/definitions/ManifestMetadata\",\n      \"description\": \"Metadata about the manifest\"\n    },\n    \"nodes\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"oneOf\": [\n          {\n            \"$ref\": \"#/definitions/CompiledAnalysisNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/CompiledSingularTestNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/CompiledModelNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/CompiledHookNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/CompiledRPCNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/CompiledSqlNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/CompiledGenericTestNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/CompiledSeedNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/CompiledSnapshotNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/ParsedAnalysisNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/ParsedSingularTestNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/ParsedHookNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/ParsedModelNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/ParsedRPCNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/ParsedSqlNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/ParsedGenericTestNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/ParsedSeedNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/ParsedSnapshotNode\"\n          }\n        ]\n      },\n      \"description\": \"The nodes defined in the dbt project and its dependencies\"\n    },\n    \"sources\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/ParsedSourceDefinition\"\n      },\n      \"description\": \"The sources defined in the dbt project and its dependencies\"\n    },\n    \"macros\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/ParsedMacro\"\n      },\n      \"description\": \"The macros defined in the dbt project and its dependencies\"\n    },\n    \"docs\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/ParsedDocumentation\"\n      },\n      \"description\": \"The docs defined in the dbt project and its dependencies\"\n    },\n    \"exposures\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/ParsedExposure\"\n      },\n      \"description\": \"The exposures defined in the dbt project and its dependencies\"\n    },\n    \"metrics\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/ParsedMetric\"\n      },\n      \"description\": \"The metrics defined in the dbt project and its dependencies\"\n    },\n    \"selectors\": {\n      \"type\": \"object\",\n      \"description\": \"The selectors defined in selectors.yml\"\n    },\n    \"disabled\": {\n      \"oneOf\": [\n        {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"oneOf\": [\n                {\n                  \"$ref\": \"#/definitions/CompiledAnalysisNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/CompiledSingularTestNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/CompiledModelNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/CompiledHookNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/CompiledRPCNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/CompiledSqlNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/CompiledGenericTestNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/CompiledSeedNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/CompiledSnapshotNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/ParsedAnalysisNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/ParsedSingularTestNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/ParsedHookNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/ParsedModelNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/ParsedRPCNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/ParsedSqlNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/ParsedGenericTestNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/ParsedSeedNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/ParsedSnapshotNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/ParsedSourceDefinition\"\n                }\n              ]\n            }\n          }\n        },\n        {\n          \"type\": \"null\"\n        }\n      ],\n      \"description\": \"A mapping of the disabled nodes in the target\"\n    },\n    \"parent_map\": {\n      \"oneOf\": [\n        {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          }\n        },\n        {\n          \"type\": \"null\"\n        }\n      ],\n      \"description\": \"A mapping from\\u00a0child nodes to their dependencies\"\n    },\n    \"child_map\": {\n      \"oneOf\": [\n        {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          }\n        },\n        {\n          \"type\": \"null\"\n        }\n      ],\n      \"description\": \"A mapping from parent nodes to their dependents\"\n    }\n  },\n  \"additionalProperties\": false,\n  \"description\": \"WritableManifest(metadata: dbt.contracts.graph.manifest.ManifestMetadata, nodes: Mapping[str, Union[dbt.contracts.graph.compiled.CompiledAnalysisNode, dbt.contracts.graph.compiled.CompiledSingularTestNode, dbt.contracts.graph.compiled.CompiledModelNode, dbt.contracts.graph.compiled.CompiledHookNode, dbt.contracts.graph.compiled.CompiledRPCNode, dbt.contracts.graph.compiled.CompiledSqlNode, dbt.contracts.graph.compiled.CompiledGenericTestNode, dbt.contracts.graph.compiled.CompiledSeedNode, dbt.contracts.graph.compiled.CompiledSnapshotNode, dbt.contracts.graph.parsed.ParsedAnalysisNode, dbt.contracts.graph.parsed.ParsedSingularTestNode, dbt.contracts.graph.parsed.ParsedHookNode, dbt.contracts.graph.parsed.ParsedModelNode, dbt.contracts.graph.parsed.ParsedRPCNode, dbt.contracts.graph.parsed.ParsedSqlNode, dbt.contracts.graph.parsed.ParsedGenericTestNode, dbt.contracts.graph.parsed.ParsedSeedNode, dbt.contracts.graph.parsed.ParsedSnapshotNode]], sources: Mapping[str, dbt.contracts.graph.parsed.ParsedSourceDefinition], macros: Mapping[str, dbt.contracts.graph.parsed.ParsedMacro], docs: Mapping[str, dbt.contracts.graph.parsed.ParsedDocumentation], exposures: Mapping[str, dbt.contracts.graph.parsed.ParsedExposure], metrics: Mapping[str, dbt.contracts.graph.parsed.ParsedMetric], selectors: Mapping[str, Any], disabled: Union[Mapping[str, List[Union[dbt.contracts.graph.compiled.CompiledAnalysisNode, dbt.contracts.graph.compiled.CompiledSingularTestNode, dbt.contracts.graph.compiled.CompiledModelNode, dbt.contracts.graph.compiled.CompiledHookNode, dbt.contracts.graph.compiled.CompiledRPCNode, dbt.contracts.graph.compiled.CompiledSqlNode, dbt.contracts.graph.compiled.CompiledGenericTestNode, dbt.contracts.graph.compiled.CompiledSeedNode, dbt.contracts.graph.compiled.CompiledSnapshotNode, dbt.contracts.graph.parsed.ParsedAnalysisNode, dbt.contracts.graph.parsed.ParsedSingularTestNode, dbt.contracts.graph.parsed.ParsedHookNode, dbt.contracts.graph.parsed.ParsedModelNode, dbt.contracts.graph.parsed.ParsedRPCNode, dbt.contracts.graph.parsed.ParsedSqlNode, dbt.contracts.graph.parsed.ParsedGenericTestNode, dbt.contracts.graph.parsed.ParsedSeedNode, dbt.contracts.graph.parsed.ParsedSnapshotNode, dbt.contracts.graph.parsed.ParsedSourceDefinition]]], NoneType], parent_map: Union[Dict[str, List[str]], NoneType], child_map: Union[Dict[str, List[str]], NoneType])\",\n  \"definitions\": {\n    \"ManifestMetadata\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"dbt_schema_version\": {\n          \"type\": \"string\",\n          \"default\": \"https://schemas.getdbt.com/dbt/manifest/v5.json\"\n        },\n        \"dbt_version\": {\n          \"type\": \"string\",\n          \"default\": \"1.2.0a1\"\n        },\n        \"generated_at\": {\n          \"type\": \"string\",\n          \"format\": \"date-time\",\n          \"default\": \"2022-04-15T20:38:22.703053Z\"\n        },\n        \"invocation_id\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": \"34abf75e-59d3-442f-920c-fa3843d98014\"\n        },\n        \"env\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          },\n          \"default\": {}\n        },\n        \"project_id\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"description\": \"A unique identifier for the project\"\n        },\n        \"user_id\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\",\n              \"pattern\": \"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"description\": \"A unique identifier for the user\"\n        },\n        \"send_anonymous_usage_stats\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"description\": \"Whether dbt is configured to send anonymous usage statistics\"\n        },\n        \"adapter_type\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"description\": \"The type name of the adapter\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Metadata for the manifest.\"\n    },\n    \"CompiledAnalysisNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"raw_sql\",\n        \"compiled\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"raw_sql\": {\n          \"type\": \"string\"\n        },\n        \"compiled\": {\n          \"type\": \"boolean\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"analysis\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"view\",\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1650055102.707036\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"compiled_sql\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"CompiledAnalysisNode(raw_sql: str, compiled: bool, database: Union[str, NoneType], schema: str, fqn: List[str], unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, compiled_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, compiled_sql: Union[str, NoneType] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.compiled.InjectedCTE] = <factory>, relation_name: Union[str, NoneType] = None, _pre_injected_sql: Union[str, NoneType] = None)\"\n    },\n    \"FileHash\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"type\": \"string\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"FileHash(name: str, checksum: str)\"\n    },\n    \"NodeConfig\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"alias\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tags\": {\n          \"oneOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"string\"\n            }\n          ],\n          \"default\": []\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"materialized\": {\n          \"type\": \"string\",\n          \"default\": \"view\"\n        },\n        \"persist_docs\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"post-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Hook\"\n          },\n          \"default\": []\n        },\n        \"pre-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Hook\"\n          },\n          \"default\": []\n        },\n        \"quoting\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"column_types\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"full_refresh\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"unique_key\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"on_schema_change\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": \"ignore\"\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"NodeConfig(_extra: Dict[str, Any] = <factory>, enabled: bool = True, alias: Union[str, NoneType] = None, schema: Union[str, NoneType] = None, database: Union[str, NoneType] = None, tags: Union[List[str], str] = <factory>, meta: Dict[str, Any] = <factory>, materialized: str = 'view', persist_docs: Dict[str, Any] = <factory>, post_hook: List[dbt.contracts.graph.model_config.Hook] = <factory>, pre_hook: List[dbt.contracts.graph.model_config.Hook] = <factory>, quoting: Dict[str, Any] = <factory>, column_types: Dict[str, Any] = <factory>, full_refresh: Union[bool, NoneType] = None, unique_key: Union[str, List[str], NoneType] = None, on_schema_change: Union[str, NoneType] = 'ignore')\"\n    },\n    \"Hook\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"sql\"\n      ],\n      \"properties\": {\n        \"sql\": {\n          \"type\": \"string\"\n        },\n        \"transaction\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"index\": {\n          \"oneOf\": [\n            {\n              \"type\": \"integer\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Hook(sql: str, transaction: bool = True, index: Union[int, NoneType] = None)\"\n    },\n    \"DependsOn\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"macros\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"nodes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"DependsOn(macros: List[str] = <factory>, nodes: List[str] = <factory>)\"\n    },\n    \"ColumnInfo\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"data_type\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"quote\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"ColumnInfo(name: str, description: str = '', meta: Dict[str, Any] = <factory>, data_type: Union[str, NoneType] = None, quote: Union[bool, NoneType] = None, tags: List[str] = <factory>, _extra: Dict[str, Any] = <factory>)\"\n    },\n    \"Docs\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"show\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Docs(show: bool = True)\"\n    },\n    \"InjectedCTE\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"id\",\n        \"sql\"\n      ],\n      \"properties\": {\n        \"id\": {\n          \"type\": \"string\"\n        },\n        \"sql\": {\n          \"type\": \"string\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"InjectedCTE(id: str, sql: str)\"\n    },\n    \"CompiledSingularTestNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"raw_sql\",\n        \"compiled\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"raw_sql\": {\n          \"type\": \"string\"\n        },\n        \"compiled\": {\n          \"type\": \"boolean\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"test\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/TestConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": \"dbt_test__audit\",\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"test\",\n            \"severity\": \"ERROR\",\n            \"store_failures\": null,\n            \"where\": null,\n            \"limit\": null,\n            \"fail_calc\": \"count(*)\",\n            \"warn_if\": \"!= 0\",\n            \"error_if\": \"!= 0\"\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1650055102.7093382\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"compiled_sql\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"CompiledSingularTestNode(raw_sql: str, compiled: bool, database: Union[str, NoneType], schema: str, fqn: List[str], unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.TestConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, compiled_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, compiled_sql: Union[str, NoneType] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.compiled.InjectedCTE] = <factory>, relation_name: Union[str, NoneType] = None, _pre_injected_sql: Union[str, NoneType] = None)\"\n    },\n    \"TestConfig\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"alias\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": \"dbt_test__audit\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tags\": {\n          \"oneOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"string\"\n            }\n          ],\n          \"default\": []\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"materialized\": {\n          \"type\": \"string\",\n          \"default\": \"test\"\n        },\n        \"severity\": {\n          \"type\": \"string\",\n          \"pattern\": \"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$\",\n          \"default\": \"ERROR\"\n        },\n        \"store_failures\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"where\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"limit\": {\n          \"oneOf\": [\n            {\n              \"type\": \"integer\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"fail_calc\": {\n          \"type\": \"string\",\n          \"default\": \"count(*)\"\n        },\n        \"warn_if\": {\n          \"type\": \"string\",\n          \"default\": \"!= 0\"\n        },\n        \"error_if\": {\n          \"type\": \"string\",\n          \"default\": \"!= 0\"\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"TestConfig(_extra: Dict[str, Any] = <factory>, enabled: bool = True, alias: Union[str, NoneType] = None, schema: Union[str, NoneType] = 'dbt_test__audit', database: Union[str, NoneType] = None, tags: Union[List[str], str] = <factory>, meta: Dict[str, Any] = <factory>, materialized: str = 'test', severity: dbt.contracts.graph.model_config.Severity = 'ERROR', store_failures: Union[bool, NoneType] = None, where: Union[str, NoneType] = None, limit: Union[int, NoneType] = None, fail_calc: str = 'count(*)', warn_if: str = '!= 0', error_if: str = '!= 0')\"\n    },\n    \"CompiledModelNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"raw_sql\",\n        \"compiled\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"raw_sql\": {\n          \"type\": \"string\"\n        },\n        \"compiled\": {\n          \"type\": \"boolean\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"model\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"view\",\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1650055102.710903\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"compiled_sql\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"CompiledModelNode(raw_sql: str, compiled: bool, database: Union[str, NoneType], schema: str, fqn: List[str], unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, compiled_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, compiled_sql: Union[str, NoneType] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.compiled.InjectedCTE] = <factory>, relation_name: Union[str, NoneType] = None, _pre_injected_sql: Union[str, NoneType] = None)\"\n    },\n    \"CompiledHookNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"raw_sql\",\n        \"compiled\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"raw_sql\": {\n          \"type\": \"string\"\n        },\n        \"compiled\": {\n          \"type\": \"boolean\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"operation\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"view\",\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1650055102.712516\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"compiled_sql\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"index\": {\n          \"oneOf\": [\n            {\n              \"type\": \"integer\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"CompiledHookNode(raw_sql: str, compiled: bool, database: Union[str, NoneType], schema: str, fqn: List[str], unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, compiled_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, compiled_sql: Union[str, NoneType] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.compiled.InjectedCTE] = <factory>, relation_name: Union[str, NoneType] = None, _pre_injected_sql: Union[str, NoneType] = None, index: Union[int, NoneType] = None)\"\n    },\n    \"CompiledRPCNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"raw_sql\",\n        \"compiled\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"raw_sql\": {\n          \"type\": \"string\"\n        },\n        \"compiled\": {\n          \"type\": \"boolean\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"rpc\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"view\",\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1650055102.714043\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"compiled_sql\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"CompiledRPCNode(raw_sql: str, compiled: bool, database: Union[str, NoneType], schema: str, fqn: List[str], unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, compiled_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, compiled_sql: Union[str, NoneType] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.compiled.InjectedCTE] = <factory>, relation_name: Union[str, NoneType] = None, _pre_injected_sql: Union[str, NoneType] = None)\"\n    },\n    \"CompiledSqlNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"raw_sql\",\n        \"compiled\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"raw_sql\": {\n          \"type\": \"string\"\n        },\n        \"compiled\": {\n          \"type\": \"boolean\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"sql\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"view\",\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1650055102.715457\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"compiled_sql\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"CompiledSqlNode(raw_sql: str, compiled: bool, database: Union[str, NoneType], schema: str, fqn: List[str], unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, compiled_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, compiled_sql: Union[str, NoneType] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.compiled.InjectedCTE] = <factory>, relation_name: Union[str, NoneType] = None, _pre_injected_sql: Union[str, NoneType] = None)\"\n    },\n    \"CompiledGenericTestNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"raw_sql\",\n        \"test_metadata\",\n        \"compiled\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"raw_sql\": {\n          \"type\": \"string\"\n        },\n        \"test_metadata\": {\n          \"$ref\": \"#/definitions/TestMetadata\"\n        },\n        \"compiled\": {\n          \"type\": \"boolean\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"test\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/TestConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": \"dbt_test__audit\",\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"test\",\n            \"severity\": \"ERROR\",\n            \"store_failures\": null,\n            \"where\": null,\n            \"limit\": null,\n            \"fail_calc\": \"count(*)\",\n            \"warn_if\": \"!= 0\",\n            \"error_if\": \"!= 0\"\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1650055102.717103\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"compiled_sql\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"column_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"file_key_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"CompiledGenericTestNode(raw_sql: str, test_metadata: dbt.contracts.graph.parsed.TestMetadata, compiled: bool, database: Union[str, NoneType], schema: str, fqn: List[str], unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.TestConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, compiled_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, compiled_sql: Union[str, NoneType] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.compiled.InjectedCTE] = <factory>, relation_name: Union[str, NoneType] = None, _pre_injected_sql: Union[str, NoneType] = None, column_name: Union[str, NoneType] = None, file_key_name: Union[str, NoneType] = None)\"\n    },\n    \"TestMetadata\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"kwargs\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"namespace\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"TestMetadata(name: str, kwargs: Dict[str, Any] = <factory>, namespace: Union[str, NoneType] = None)\"\n    },\n    \"CompiledSeedNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"raw_sql\",\n        \"compiled\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"raw_sql\": {\n          \"type\": \"string\"\n        },\n        \"compiled\": {\n          \"type\": \"boolean\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"seed\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/SeedConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"seed\",\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"quote_columns\": null,\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1650055102.719672\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"compiled_sql\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"CompiledSeedNode(raw_sql: str, compiled: bool, database: Union[str, NoneType], schema: str, fqn: List[str], unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.SeedConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, compiled_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, compiled_sql: Union[str, NoneType] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.compiled.InjectedCTE] = <factory>, relation_name: Union[str, NoneType] = None, _pre_injected_sql: Union[str, NoneType] = None)\"\n    },\n    \"SeedConfig\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"alias\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tags\": {\n          \"oneOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"string\"\n            }\n          ],\n          \"default\": []\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"materialized\": {\n          \"type\": \"string\",\n          \"default\": \"seed\"\n        },\n        \"persist_docs\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"post-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Hook\"\n          },\n          \"default\": []\n        },\n        \"pre-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Hook\"\n          },\n          \"default\": []\n        },\n        \"quoting\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"column_types\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"full_refresh\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"unique_key\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"on_schema_change\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": \"ignore\"\n        },\n        \"quote_columns\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"SeedConfig(_extra: Dict[str, Any] = <factory>, enabled: bool = True, alias: Union[str, NoneType] = None, schema: Union[str, NoneType] = None, database: Union[str, NoneType] = None, tags: Union[List[str], str] = <factory>, meta: Dict[str, Any] = <factory>, materialized: str = 'seed', persist_docs: Dict[str, Any] = <factory>, post_hook: List[dbt.contracts.graph.model_config.Hook] = <factory>, pre_hook: List[dbt.contracts.graph.model_config.Hook] = <factory>, quoting: Dict[str, Any] = <factory>, column_types: Dict[str, Any] = <factory>, full_refresh: Union[bool, NoneType] = None, unique_key: Union[str, List[str], NoneType] = None, on_schema_change: Union[str, NoneType] = 'ignore', quote_columns: Union[bool, NoneType] = None)\"\n    },\n    \"CompiledSnapshotNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"raw_sql\",\n        \"compiled\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"raw_sql\": {\n          \"type\": \"string\"\n        },\n        \"compiled\": {\n          \"type\": \"boolean\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"snapshot\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"view\",\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1650055102.72113\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"compiled_sql\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"CompiledSnapshotNode(raw_sql: str, compiled: bool, database: Union[str, NoneType], schema: str, fqn: List[str], unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, compiled_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, compiled_sql: Union[str, NoneType] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.compiled.InjectedCTE] = <factory>, relation_name: Union[str, NoneType] = None, _pre_injected_sql: Union[str, NoneType] = None)\"\n    },\n    \"ParsedAnalysisNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"raw_sql\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"raw_sql\": {\n          \"type\": \"string\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"analysis\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"view\",\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1650055102.7224698\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ParsedAnalysisNode(raw_sql: str, database: Union[str, NoneType], schema: str, fqn: List[str], unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, compiled_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>)\"\n    },\n    \"ParsedSingularTestNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"raw_sql\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"raw_sql\": {\n          \"type\": \"string\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"test\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/TestConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": \"dbt_test__audit\",\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"test\",\n            \"severity\": \"ERROR\",\n            \"store_failures\": null,\n            \"where\": null,\n            \"limit\": null,\n            \"fail_calc\": \"count(*)\",\n            \"warn_if\": \"!= 0\",\n            \"error_if\": \"!= 0\"\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1650055102.723626\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ParsedSingularTestNode(raw_sql: str, database: Union[str, NoneType], schema: str, fqn: List[str], unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.TestConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, compiled_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>)\"\n    },\n    \"ParsedHookNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"raw_sql\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"raw_sql\": {\n          \"type\": \"string\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"operation\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"view\",\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1650055102.724789\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"index\": {\n          \"oneOf\": [\n            {\n              \"type\": \"integer\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ParsedHookNode(raw_sql: str, database: Union[str, NoneType], schema: str, fqn: List[str], unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, compiled_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, index: Union[int, NoneType] = None)\"\n    },\n    \"ParsedModelNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"raw_sql\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"raw_sql\": {\n          \"type\": \"string\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"model\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"view\",\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1650055102.725993\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ParsedModelNode(raw_sql: str, database: Union[str, NoneType], schema: str, fqn: List[str], unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, compiled_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>)\"\n    },\n    \"ParsedRPCNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"raw_sql\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"raw_sql\": {\n          \"type\": \"string\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"rpc\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"view\",\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1650055102.727343\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ParsedRPCNode(raw_sql: str, database: Union[str, NoneType], schema: str, fqn: List[str], unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, compiled_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>)\"\n    },\n    \"ParsedSqlNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"raw_sql\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"raw_sql\": {\n          \"type\": \"string\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"sql\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"view\",\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1650055102.728572\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ParsedSqlNode(raw_sql: str, database: Union[str, NoneType], schema: str, fqn: List[str], unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, compiled_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>)\"\n    },\n    \"ParsedGenericTestNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"raw_sql\",\n        \"test_metadata\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"raw_sql\": {\n          \"type\": \"string\"\n        },\n        \"test_metadata\": {\n          \"$ref\": \"#/definitions/TestMetadata\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"test\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/TestConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": \"dbt_test__audit\",\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"test\",\n            \"severity\": \"ERROR\",\n            \"store_failures\": null,\n            \"where\": null,\n            \"limit\": null,\n            \"fail_calc\": \"count(*)\",\n            \"warn_if\": \"!= 0\",\n            \"error_if\": \"!= 0\"\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1650055102.729745\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"column_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"file_key_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ParsedGenericTestNode(raw_sql: str, test_metadata: dbt.contracts.graph.parsed.TestMetadata, database: Union[str, NoneType], schema: str, fqn: List[str], unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.TestConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, compiled_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, column_name: Union[str, NoneType] = None, file_key_name: Union[str, NoneType] = None)\"\n    },\n    \"ParsedSeedNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"raw_sql\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"raw_sql\": {\n          \"type\": \"string\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"seed\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/SeedConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"seed\",\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"quote_columns\": null,\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1650055102.731012\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ParsedSeedNode(raw_sql: str, database: Union[str, NoneType], schema: str, fqn: List[str], unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.SeedConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, compiled_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>)\"\n    },\n    \"ParsedSnapshotNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"raw_sql\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\",\n        \"config\"\n      ],\n      \"properties\": {\n        \"raw_sql\": {\n          \"type\": \"string\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"snapshot\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/SnapshotConfig\"\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1650055102.733336\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ParsedSnapshotNode(raw_sql: str, database: Union[str, NoneType], schema: str, fqn: List[str], unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.SnapshotConfig, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, compiled_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>)\"\n    },\n    \"SnapshotConfig\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"alias\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tags\": {\n          \"oneOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"string\"\n            }\n          ],\n          \"default\": []\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"materialized\": {\n          \"type\": \"string\",\n          \"default\": \"snapshot\"\n        },\n        \"persist_docs\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"post-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Hook\"\n          },\n          \"default\": []\n        },\n        \"pre-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Hook\"\n          },\n          \"default\": []\n        },\n        \"quoting\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"column_types\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"full_refresh\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"unique_key\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"on_schema_change\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": \"ignore\"\n        },\n        \"strategy\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"target_schema\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"target_database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"updated_at\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"check_cols\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"SnapshotConfig(_extra: Dict[str, Any] = <factory>, enabled: bool = True, alias: Union[str, NoneType] = None, schema: Union[str, NoneType] = None, database: Union[str, NoneType] = None, tags: Union[List[str], str] = <factory>, meta: Dict[str, Any] = <factory>, materialized: str = 'snapshot', persist_docs: Dict[str, Any] = <factory>, post_hook: List[dbt.contracts.graph.model_config.Hook] = <factory>, pre_hook: List[dbt.contracts.graph.model_config.Hook] = <factory>, quoting: Dict[str, Any] = <factory>, column_types: Dict[str, Any] = <factory>, full_refresh: Union[bool, NoneType] = None, unique_key: Union[str, NoneType] = None, on_schema_change: Union[str, NoneType] = 'ignore', strategy: Union[str, NoneType] = None, target_schema: Union[str, NoneType] = None, target_database: Union[str, NoneType] = None, updated_at: Union[str, NoneType] = None, check_cols: Union[str, List[str], NoneType] = None)\"\n    },\n    \"ParsedSourceDefinition\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"fqn\",\n        \"schema\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"source_name\",\n        \"source_description\",\n        \"loader\",\n        \"identifier\",\n        \"resource_type\"\n      ],\n      \"properties\": {\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"source_name\": {\n          \"type\": \"string\"\n        },\n        \"source_description\": {\n          \"type\": \"string\"\n        },\n        \"loader\": {\n          \"type\": \"string\"\n        },\n        \"identifier\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"source\"\n          ]\n        },\n        \"quoting\": {\n          \"$ref\": \"#/definitions/Quoting\",\n          \"default\": {\n            \"database\": null,\n            \"schema\": null,\n            \"identifier\": null,\n            \"column\": null\n          }\n        },\n        \"loaded_at_field\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"freshness\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/FreshnessThreshold\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"external\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/ExternalTable\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"source_meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/SourceConfig\",\n          \"default\": {\n            \"enabled\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1650055102.735436\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ParsedSourceDefinition(fqn: List[str], database: Union[str, NoneType], schema: str, unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, source_name: str, source_description: str, loader: str, identifier: str, resource_type: dbt.node_types.NodeType, _event_status: Dict[str, Any] = <factory>, quoting: dbt.contracts.graph.unparsed.Quoting = <factory>, loaded_at_field: Union[str, NoneType] = None, freshness: Union[dbt.contracts.graph.unparsed.FreshnessThreshold, NoneType] = None, external: Union[dbt.contracts.graph.unparsed.ExternalTable, NoneType] = None, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, source_meta: Dict[str, Any] = <factory>, tags: List[str] = <factory>, config: dbt.contracts.graph.model_config.SourceConfig = <factory>, patch_path: Union[pathlib.Path, NoneType] = None, unrendered_config: Dict[str, Any] = <factory>, relation_name: Union[str, NoneType] = None, created_at: float = <factory>)\"\n    },\n    \"Quoting\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"identifier\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"column\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Quoting(database: Union[bool, NoneType] = None, schema: Union[bool, NoneType] = None, identifier: Union[bool, NoneType] = None, column: Union[bool, NoneType] = None)\"\n    },\n    \"FreshnessThreshold\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"warn_after\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/Time\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": {\n            \"count\": null,\n            \"period\": null\n          }\n        },\n        \"error_after\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/Time\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": {\n            \"count\": null,\n            \"period\": null\n          }\n        },\n        \"filter\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"FreshnessThreshold(warn_after: Union[dbt.contracts.graph.unparsed.Time, NoneType] = <factory>, error_after: Union[dbt.contracts.graph.unparsed.Time, NoneType] = <factory>, filter: Union[str, NoneType] = None)\"\n    },\n    \"FreshnessMetadata\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"dbt_schema_version\": {\n          \"type\": \"string\",\n          \"default\": \"https://schemas.getdbt.com/dbt/sources/v3.json\"\n        },\n        \"dbt_version\": {\n          \"type\": \"string\",\n          \"default\": \"1.2.0a1\"\n        },\n        \"generated_at\": {\n          \"type\": \"string\",\n          \"format\": \"date-time\",\n          \"default\": \"2022-04-15T20:38:22.697740Z\"\n        },\n        \"invocation_id\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": \"34abf75e-59d3-442f-920c-fa3843d98014\"\n        },\n        \"env\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          },\n          \"default\": {}\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"FreshnessMetadata(dbt_schema_version: str = <factory>, dbt_version: str = '1.2.0a1', generated_at: datetime.datetime = <factory>, invocation_id: Union[str, NoneType] = <factory>, env: Dict[str, str] = <factory>)\"\n    },\n    \"SourceFreshnessRuntimeError\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"unique_id\",\n        \"status\"\n      ],\n      \"properties\": {\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"error\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"integer\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"status\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"runtime error\"\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"SourceFreshnessRuntimeError(unique_id: str, error: Union[str, int, NoneType], status: dbt.contracts.results.FreshnessErrorEnum)\"\n    },\n    \"SourceFreshnessOutput\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"unique_id\",\n        \"max_loaded_at\",\n        \"snapshotted_at\",\n        \"max_loaded_at_time_ago_in_s\",\n        \"status\",\n        \"criteria\",\n        \"adapter_response\",\n        \"timing\",\n        \"thread_id\",\n        \"execution_time\"\n      ],\n      \"properties\": {\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"max_loaded_at\": {\n          \"type\": \"string\",\n          \"format\": \"date-time\"\n        },\n        \"snapshotted_at\": {\n          \"type\": \"string\",\n          \"format\": \"date-time\"\n        },\n        \"max_loaded_at_time_ago_in_s\": {\n          \"type\": \"number\"\n        },\n        \"status\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"pass\",\n            \"warn\",\n            \"error\",\n            \"runtime error\"\n          ]\n        },\n        \"criteria\": {\n          \"$ref\": \"#/definitions/FreshnessThreshold\"\n        },\n        \"adapter_response\": {\n          \"type\": \"object\"\n        },\n        \"timing\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/TimingInfo\"\n          }\n        },\n        \"thread_id\": {\n          \"type\": \"string\"\n        },\n        \"execution_time\": {\n          \"type\": \"number\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"SourceFreshnessOutput(unique_id: str, max_loaded_at: datetime.datetime, snapshotted_at: datetime.datetime, max_loaded_at_time_ago_in_s: float, status: dbt.contracts.results.FreshnessStatus, criteria: dbt.contracts.graph.unparsed.FreshnessThreshold, adapter_response: Dict[str, Any], timing: List[dbt.contracts.results.TimingInfo], thread_id: str, execution_time: float)\"\n    },\n    \"Time\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"count\": {\n          \"oneOf\": [\n            {\n              \"type\": \"integer\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"period\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\",\n              \"enum\": [\n                \"minute\",\n                \"hour\",\n                \"day\"\n              ]\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Time(count: Union[int, NoneType] = None, period: Union[dbt.contracts.graph.unparsed.TimePeriod, NoneType] = None)\"\n    },\n    \"TimingInfo\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"started_at\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\",\n              \"format\": \"date-time\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"completed_at\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\",\n              \"format\": \"date-time\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"TimingInfo(name: str, started_at: Union[datetime.datetime, NoneType] = None, completed_at: Union[datetime.datetime, NoneType] = None)\"\n    },\n    \"ExternalTable\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"location\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"file_format\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"row_format\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tbl_properties\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"partitions\": {\n          \"oneOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"$ref\": \"#/definitions/ExternalPartition\"\n              }\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"ExternalTable(_extra: Dict[str, Any] = <factory>, location: Union[str, NoneType] = None, file_format: Union[str, NoneType] = None, row_format: Union[str, NoneType] = None, tbl_properties: Union[str, NoneType] = None, partitions: Union[List[dbt.contracts.graph.unparsed.ExternalPartition], NoneType] = None)\"\n    },\n    \"ExternalPartition\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"data_type\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"ExternalPartition(_extra: Dict[str, Any] = <factory>, name: str = '', description: str = '', data_type: str = '', meta: Dict[str, Any] = <factory>)\"\n    },\n    \"SourceConfig\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"SourceConfig(_extra: Dict[str, Any] = <factory>, enabled: bool = True)\"\n    },\n    \"ParsedMacro\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"macro_sql\",\n        \"resource_type\"\n      ],\n      \"properties\": {\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"macro_sql\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"macro\"\n          ]\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/MacroDependsOn\",\n          \"default\": {\n            \"macros\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"arguments\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/MacroArgument\"\n          },\n          \"default\": []\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1650055102.736266\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ParsedMacro(unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, macro_sql: str, resource_type: dbt.node_types.NodeType, tags: List[str] = <factory>, depends_on: dbt.contracts.graph.parsed.MacroDependsOn = <factory>, description: str = '', meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, arguments: List[dbt.contracts.graph.unparsed.MacroArgument] = <factory>, created_at: float = <factory>)\"\n    },\n    \"MacroDependsOn\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"macros\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"MacroDependsOn(macros: List[str] = <factory>)\"\n    },\n    \"MacroArgument\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"type\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"MacroArgument(name: str, type: Union[str, NoneType] = None, description: str = '')\"\n    },\n    \"ParsedDocumentation\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"block_contents\"\n      ],\n      \"properties\": {\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"block_contents\": {\n          \"type\": \"string\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ParsedDocumentation(unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, block_contents: str)\"\n    },\n    \"ParsedExposure\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"fqn\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"type\",\n        \"owner\"\n      ],\n      \"properties\": {\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"dashboard\",\n            \"notebook\",\n            \"analysis\",\n            \"ml\",\n            \"application\"\n          ]\n        },\n        \"owner\": {\n          \"$ref\": \"#/definitions/ExposureOwner\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"model\",\n            \"analysis\",\n            \"test\",\n            \"snapshot\",\n            \"operation\",\n            \"seed\",\n            \"rpc\",\n            \"sql\",\n            \"docs\",\n            \"source\",\n            \"macro\",\n            \"exposure\",\n            \"metric\"\n          ],\n          \"default\": \"exposure\"\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"maturity\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\",\n              \"enum\": [\n                \"low\",\n                \"medium\",\n                \"high\"\n              ]\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"url\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1650055102.7375019\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ParsedExposure(fqn: List[str], unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, type: dbt.contracts.graph.unparsed.ExposureType, owner: dbt.contracts.graph.unparsed.ExposureOwner, resource_type: dbt.node_types.NodeType = <NodeType.Exposure: 'exposure'>, description: str = '', maturity: Union[dbt.contracts.graph.unparsed.MaturityType, NoneType] = None, meta: Dict[str, Any] = <factory>, tags: List[str] = <factory>, url: Union[str, NoneType] = None, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, created_at: float = <factory>)\"\n    },\n    \"ExposureOwner\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"email\"\n      ],\n      \"properties\": {\n        \"email\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ExposureOwner(email: str, name: Union[str, NoneType] = None)\"\n    },\n    \"ParsedMetric\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"fqn\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"model\",\n        \"name\",\n        \"description\",\n        \"label\",\n        \"type\",\n        \"filters\",\n        \"time_grains\",\n        \"dimensions\"\n      ],\n      \"properties\": {\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"model\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"label\": {\n          \"type\": \"string\"\n        },\n        \"type\": {\n          \"type\": \"string\"\n        },\n        \"sql\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"timestamp\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"filters\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/MetricFilter\"\n          }\n        },\n        \"time_grains\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"dimensions\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"model\",\n            \"analysis\",\n            \"test\",\n            \"snapshot\",\n            \"operation\",\n            \"seed\",\n            \"rpc\",\n            \"sql\",\n            \"docs\",\n            \"source\",\n            \"macro\",\n            \"exposure\",\n            \"metric\"\n          ],\n          \"default\": \"metric\"\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1650055102.738508\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ParsedMetric(fqn: List[str], unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, model: str, name: str, description: str, label: str, type: str, sql: Union[str, NoneType], timestamp: Union[str, NoneType], filters: List[dbt.contracts.graph.unparsed.MetricFilter], time_grains: List[str], dimensions: List[str], resource_type: dbt.node_types.NodeType = <NodeType.Metric: 'metric'>, meta: Dict[str, Any] = <factory>, tags: List[str] = <factory>, sources: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, refs: List[List[str]] = <factory>, created_at: float = <factory>)\"\n    },\n    \"MetricFilter\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"field\",\n        \"operator\",\n        \"value\"\n      ],\n      \"properties\": {\n        \"field\": {\n          \"type\": \"string\"\n        },\n        \"operator\": {\n          \"type\": \"string\"\n        },\n        \"value\": {\n          \"type\": \"string\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"MetricFilter(field: str, operator: str, value: str)\"\n    }\n  },\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n  \"$id\": \"https://schemas.getdbt.com/dbt/manifest/v5.json\"\n}"
  },
  {
    "path": "schemas/dbt/manifest/v6.json",
    "content": "{\n  \"type\": \"object\",\n  \"required\": [\n    \"metadata\",\n    \"nodes\",\n    \"sources\",\n    \"macros\",\n    \"docs\",\n    \"exposures\",\n    \"metrics\",\n    \"selectors\"\n  ],\n  \"properties\": {\n    \"metadata\": {\n      \"$ref\": \"#/definitions/ManifestMetadata\",\n      \"description\": \"Metadata about the manifest\"\n    },\n    \"nodes\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"oneOf\": [\n          {\n            \"$ref\": \"#/definitions/CompiledAnalysisNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/CompiledSingularTestNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/CompiledModelNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/CompiledHookNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/CompiledRPCNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/CompiledSqlNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/CompiledGenericTestNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/CompiledSeedNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/CompiledSnapshotNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/ParsedAnalysisNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/ParsedSingularTestNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/ParsedHookNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/ParsedModelNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/ParsedRPCNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/ParsedSqlNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/ParsedGenericTestNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/ParsedSeedNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/ParsedSnapshotNode\"\n          }\n        ]\n      },\n      \"description\": \"The nodes defined in the dbt project and its dependencies\"\n    },\n    \"sources\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/ParsedSourceDefinition\"\n      },\n      \"description\": \"The sources defined in the dbt project and its dependencies\"\n    },\n    \"macros\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/ParsedMacro\"\n      },\n      \"description\": \"The macros defined in the dbt project and its dependencies\"\n    },\n    \"docs\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/ParsedDocumentation\"\n      },\n      \"description\": \"The docs defined in the dbt project and its dependencies\"\n    },\n    \"exposures\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/ParsedExposure\"\n      },\n      \"description\": \"The exposures defined in the dbt project and its dependencies\"\n    },\n    \"metrics\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/ParsedMetric\"\n      },\n      \"description\": \"The metrics defined in the dbt project and its dependencies\"\n    },\n    \"selectors\": {\n      \"type\": \"object\",\n      \"description\": \"The selectors defined in selectors.yml\"\n    },\n    \"disabled\": {\n      \"oneOf\": [\n        {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"oneOf\": [\n                {\n                  \"$ref\": \"#/definitions/CompiledAnalysisNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/CompiledSingularTestNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/CompiledModelNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/CompiledHookNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/CompiledRPCNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/CompiledSqlNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/CompiledGenericTestNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/CompiledSeedNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/CompiledSnapshotNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/ParsedAnalysisNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/ParsedSingularTestNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/ParsedHookNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/ParsedModelNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/ParsedRPCNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/ParsedSqlNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/ParsedGenericTestNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/ParsedSeedNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/ParsedSnapshotNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/ParsedSourceDefinition\"\n                }\n              ]\n            }\n          }\n        },\n        {\n          \"type\": \"null\"\n        }\n      ],\n      \"description\": \"A mapping of the disabled nodes in the target\"\n    },\n    \"parent_map\": {\n      \"oneOf\": [\n        {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          }\n        },\n        {\n          \"type\": \"null\"\n        }\n      ],\n      \"description\": \"A mapping from\\u00a0child nodes to their dependencies\"\n    },\n    \"child_map\": {\n      \"oneOf\": [\n        {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          }\n        },\n        {\n          \"type\": \"null\"\n        }\n      ],\n      \"description\": \"A mapping from parent nodes to their dependents\"\n    }\n  },\n  \"additionalProperties\": false,\n  \"description\": \"WritableManifest(metadata: dbt.contracts.graph.manifest.ManifestMetadata, nodes: Mapping[str, Union[dbt.contracts.graph.compiled.CompiledAnalysisNode, dbt.contracts.graph.compiled.CompiledSingularTestNode, dbt.contracts.graph.compiled.CompiledModelNode, dbt.contracts.graph.compiled.CompiledHookNode, dbt.contracts.graph.compiled.CompiledRPCNode, dbt.contracts.graph.compiled.CompiledSqlNode, dbt.contracts.graph.compiled.CompiledGenericTestNode, dbt.contracts.graph.compiled.CompiledSeedNode, dbt.contracts.graph.compiled.CompiledSnapshotNode, dbt.contracts.graph.parsed.ParsedAnalysisNode, dbt.contracts.graph.parsed.ParsedSingularTestNode, dbt.contracts.graph.parsed.ParsedHookNode, dbt.contracts.graph.parsed.ParsedModelNode, dbt.contracts.graph.parsed.ParsedRPCNode, dbt.contracts.graph.parsed.ParsedSqlNode, dbt.contracts.graph.parsed.ParsedGenericTestNode, dbt.contracts.graph.parsed.ParsedSeedNode, dbt.contracts.graph.parsed.ParsedSnapshotNode]], sources: Mapping[str, dbt.contracts.graph.parsed.ParsedSourceDefinition], macros: Mapping[str, dbt.contracts.graph.parsed.ParsedMacro], docs: Mapping[str, dbt.contracts.graph.parsed.ParsedDocumentation], exposures: Mapping[str, dbt.contracts.graph.parsed.ParsedExposure], metrics: Mapping[str, dbt.contracts.graph.parsed.ParsedMetric], selectors: Mapping[str, Any], disabled: Optional[Mapping[str, List[Union[dbt.contracts.graph.compiled.CompiledAnalysisNode, dbt.contracts.graph.compiled.CompiledSingularTestNode, dbt.contracts.graph.compiled.CompiledModelNode, dbt.contracts.graph.compiled.CompiledHookNode, dbt.contracts.graph.compiled.CompiledRPCNode, dbt.contracts.graph.compiled.CompiledSqlNode, dbt.contracts.graph.compiled.CompiledGenericTestNode, dbt.contracts.graph.compiled.CompiledSeedNode, dbt.contracts.graph.compiled.CompiledSnapshotNode, dbt.contracts.graph.parsed.ParsedAnalysisNode, dbt.contracts.graph.parsed.ParsedSingularTestNode, dbt.contracts.graph.parsed.ParsedHookNode, dbt.contracts.graph.parsed.ParsedModelNode, dbt.contracts.graph.parsed.ParsedRPCNode, dbt.contracts.graph.parsed.ParsedSqlNode, dbt.contracts.graph.parsed.ParsedGenericTestNode, dbt.contracts.graph.parsed.ParsedSeedNode, dbt.contracts.graph.parsed.ParsedSnapshotNode, dbt.contracts.graph.parsed.ParsedSourceDefinition]]]], parent_map: Optional[Dict[str, List[str]]], child_map: Optional[Dict[str, List[str]]])\",\n  \"definitions\": {\n    \"ManifestMetadata\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"dbt_schema_version\": {\n          \"type\": \"string\",\n          \"default\": \"https://schemas.getdbt.com/dbt/manifest/v6.json\"\n        },\n        \"dbt_version\": {\n          \"type\": \"string\",\n          \"default\": \"1.2.0a1\"\n        },\n        \"generated_at\": {\n          \"type\": \"string\",\n          \"format\": \"date-time\",\n          \"default\": \"2022-07-05T17:06:02.022011Z\"\n        },\n        \"invocation_id\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": \"6cec400a-e8a4-4480-8ceb-d35589d12bab\"\n        },\n        \"env\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          },\n          \"default\": {}\n        },\n        \"project_id\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"description\": \"A unique identifier for the project\"\n        },\n        \"user_id\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\",\n              \"pattern\": \"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"description\": \"A unique identifier for the user\"\n        },\n        \"send_anonymous_usage_stats\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"description\": \"Whether dbt is configured to send anonymous usage statistics\"\n        },\n        \"adapter_type\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"description\": \"The type name of the adapter\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Metadata for the manifest.\"\n    },\n    \"CompiledAnalysisNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"raw_sql\",\n        \"compiled\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"raw_sql\": {\n          \"type\": \"string\"\n        },\n        \"compiled\": {\n          \"type\": \"boolean\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"analysis\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"view\",\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"grants\": {},\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1657040762.0262258\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"compiled_sql\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"CompiledAnalysisNode(raw_sql: str, compiled: bool, database: Optional[str], schema: str, fqn: List[str], unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Optional[str] = None, compiled_path: Optional[str] = None, build_path: Optional[str] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, compiled_sql: Optional[str] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.compiled.InjectedCTE] = <factory>, relation_name: Optional[str] = None, _pre_injected_sql: Optional[str] = None)\"\n    },\n    \"FileHash\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"type\": \"string\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"FileHash(name: str, checksum: str)\"\n    },\n    \"NodeConfig\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"alias\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tags\": {\n          \"oneOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"string\"\n            }\n          ],\n          \"default\": []\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"materialized\": {\n          \"type\": \"string\",\n          \"default\": \"view\"\n        },\n        \"persist_docs\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"post-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Hook\"\n          },\n          \"default\": []\n        },\n        \"pre-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Hook\"\n          },\n          \"default\": []\n        },\n        \"quoting\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"column_types\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"full_refresh\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"unique_key\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"on_schema_change\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": \"ignore\"\n        },\n        \"grants\": {\n          \"type\": \"object\",\n          \"default\": {}\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"NodeConfig(_extra: Dict[str, Any] = <factory>, enabled: bool = True, alias: Optional[str] = None, schema: Optional[str] = None, database: Optional[str] = None, tags: Union[List[str], str] = <factory>, meta: Dict[str, Any] = <factory>, materialized: str = 'view', persist_docs: Dict[str, Any] = <factory>, post_hook: List[dbt.contracts.graph.model_config.Hook] = <factory>, pre_hook: List[dbt.contracts.graph.model_config.Hook] = <factory>, quoting: Dict[str, Any] = <factory>, column_types: Dict[str, Any] = <factory>, full_refresh: Optional[bool] = None, unique_key: Union[str, List[str], NoneType] = None, on_schema_change: Optional[str] = 'ignore', grants: Dict[str, Any] = <factory>)\"\n    },\n    \"Hook\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"sql\"\n      ],\n      \"properties\": {\n        \"sql\": {\n          \"type\": \"string\"\n        },\n        \"transaction\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"index\": {\n          \"oneOf\": [\n            {\n              \"type\": \"integer\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Hook(sql: str, transaction: bool = True, index: Optional[int] = None)\"\n    },\n    \"DependsOn\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"macros\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"nodes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"DependsOn(macros: List[str] = <factory>, nodes: List[str] = <factory>)\"\n    },\n    \"ColumnInfo\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"data_type\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"quote\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"ColumnInfo(name: str, description: str = '', meta: Dict[str, Any] = <factory>, data_type: Optional[str] = None, quote: Optional[bool] = None, tags: List[str] = <factory>, _extra: Dict[str, Any] = <factory>)\"\n    },\n    \"Docs\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"show\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Docs(show: bool = True)\"\n    },\n    \"InjectedCTE\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"id\",\n        \"sql\"\n      ],\n      \"properties\": {\n        \"id\": {\n          \"type\": \"string\"\n        },\n        \"sql\": {\n          \"type\": \"string\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"InjectedCTE(id: str, sql: str)\"\n    },\n    \"CompiledSingularTestNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"raw_sql\",\n        \"compiled\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"raw_sql\": {\n          \"type\": \"string\"\n        },\n        \"compiled\": {\n          \"type\": \"boolean\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"test\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/TestConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": \"dbt_test__audit\",\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"test\",\n            \"severity\": \"ERROR\",\n            \"store_failures\": null,\n            \"where\": null,\n            \"limit\": null,\n            \"fail_calc\": \"count(*)\",\n            \"warn_if\": \"!= 0\",\n            \"error_if\": \"!= 0\"\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1657040762.028276\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"compiled_sql\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"CompiledSingularTestNode(raw_sql: str, compiled: bool, database: Optional[str], schema: str, fqn: List[str], unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.TestConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Optional[str] = None, compiled_path: Optional[str] = None, build_path: Optional[str] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, compiled_sql: Optional[str] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.compiled.InjectedCTE] = <factory>, relation_name: Optional[str] = None, _pre_injected_sql: Optional[str] = None)\"\n    },\n    \"TestConfig\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"alias\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": \"dbt_test__audit\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tags\": {\n          \"oneOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"string\"\n            }\n          ],\n          \"default\": []\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"materialized\": {\n          \"type\": \"string\",\n          \"default\": \"test\"\n        },\n        \"severity\": {\n          \"type\": \"string\",\n          \"pattern\": \"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$\",\n          \"default\": \"ERROR\"\n        },\n        \"store_failures\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"where\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"limit\": {\n          \"oneOf\": [\n            {\n              \"type\": \"integer\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"fail_calc\": {\n          \"type\": \"string\",\n          \"default\": \"count(*)\"\n        },\n        \"warn_if\": {\n          \"type\": \"string\",\n          \"default\": \"!= 0\"\n        },\n        \"error_if\": {\n          \"type\": \"string\",\n          \"default\": \"!= 0\"\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"TestConfig(_extra: Dict[str, Any] = <factory>, enabled: bool = True, alias: Optional[str] = None, schema: Optional[str] = 'dbt_test__audit', database: Optional[str] = None, tags: Union[List[str], str] = <factory>, meta: Dict[str, Any] = <factory>, materialized: str = 'test', severity: dbt.contracts.graph.model_config.Severity = 'ERROR', store_failures: Optional[bool] = None, where: Optional[str] = None, limit: Optional[int] = None, fail_calc: str = 'count(*)', warn_if: str = '!= 0', error_if: str = '!= 0')\"\n    },\n    \"CompiledModelNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"raw_sql\",\n        \"compiled\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"raw_sql\": {\n          \"type\": \"string\"\n        },\n        \"compiled\": {\n          \"type\": \"boolean\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"model\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"view\",\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"grants\": {},\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1657040762.0294158\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"compiled_sql\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"CompiledModelNode(raw_sql: str, compiled: bool, database: Optional[str], schema: str, fqn: List[str], unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Optional[str] = None, compiled_path: Optional[str] = None, build_path: Optional[str] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, compiled_sql: Optional[str] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.compiled.InjectedCTE] = <factory>, relation_name: Optional[str] = None, _pre_injected_sql: Optional[str] = None)\"\n    },\n    \"CompiledHookNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"raw_sql\",\n        \"compiled\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"raw_sql\": {\n          \"type\": \"string\"\n        },\n        \"compiled\": {\n          \"type\": \"boolean\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"operation\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"view\",\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"grants\": {},\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1657040762.030488\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"compiled_sql\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"index\": {\n          \"oneOf\": [\n            {\n              \"type\": \"integer\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"CompiledHookNode(raw_sql: str, compiled: bool, database: Optional[str], schema: str, fqn: List[str], unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Optional[str] = None, compiled_path: Optional[str] = None, build_path: Optional[str] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, compiled_sql: Optional[str] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.compiled.InjectedCTE] = <factory>, relation_name: Optional[str] = None, _pre_injected_sql: Optional[str] = None, index: Optional[int] = None)\"\n    },\n    \"CompiledRPCNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"raw_sql\",\n        \"compiled\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"raw_sql\": {\n          \"type\": \"string\"\n        },\n        \"compiled\": {\n          \"type\": \"boolean\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"rpc\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"view\",\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"grants\": {},\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1657040762.031699\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"compiled_sql\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"CompiledRPCNode(raw_sql: str, compiled: bool, database: Optional[str], schema: str, fqn: List[str], unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Optional[str] = None, compiled_path: Optional[str] = None, build_path: Optional[str] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, compiled_sql: Optional[str] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.compiled.InjectedCTE] = <factory>, relation_name: Optional[str] = None, _pre_injected_sql: Optional[str] = None)\"\n    },\n    \"CompiledSqlNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"raw_sql\",\n        \"compiled\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"raw_sql\": {\n          \"type\": \"string\"\n        },\n        \"compiled\": {\n          \"type\": \"boolean\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"sql\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"view\",\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"grants\": {},\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1657040762.032803\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"compiled_sql\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"CompiledSqlNode(raw_sql: str, compiled: bool, database: Optional[str], schema: str, fqn: List[str], unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Optional[str] = None, compiled_path: Optional[str] = None, build_path: Optional[str] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, compiled_sql: Optional[str] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.compiled.InjectedCTE] = <factory>, relation_name: Optional[str] = None, _pre_injected_sql: Optional[str] = None)\"\n    },\n    \"CompiledGenericTestNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"raw_sql\",\n        \"test_metadata\",\n        \"compiled\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"raw_sql\": {\n          \"type\": \"string\"\n        },\n        \"test_metadata\": {\n          \"$ref\": \"#/definitions/TestMetadata\"\n        },\n        \"compiled\": {\n          \"type\": \"boolean\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"test\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/TestConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": \"dbt_test__audit\",\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"test\",\n            \"severity\": \"ERROR\",\n            \"store_failures\": null,\n            \"where\": null,\n            \"limit\": null,\n            \"fail_calc\": \"count(*)\",\n            \"warn_if\": \"!= 0\",\n            \"error_if\": \"!= 0\"\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1657040762.0341172\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"compiled_sql\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"column_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"file_key_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"CompiledGenericTestNode(raw_sql: str, test_metadata: dbt.contracts.graph.parsed.TestMetadata, compiled: bool, database: Optional[str], schema: str, fqn: List[str], unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.TestConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Optional[str] = None, compiled_path: Optional[str] = None, build_path: Optional[str] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, compiled_sql: Optional[str] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.compiled.InjectedCTE] = <factory>, relation_name: Optional[str] = None, _pre_injected_sql: Optional[str] = None, column_name: Optional[str] = None, file_key_name: Optional[str] = None)\"\n    },\n    \"TestMetadata\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"kwargs\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"namespace\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"TestMetadata(name: str, kwargs: Dict[str, Any] = <factory>, namespace: Optional[str] = None)\"\n    },\n    \"CompiledSeedNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"raw_sql\",\n        \"compiled\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"raw_sql\": {\n          \"type\": \"string\"\n        },\n        \"compiled\": {\n          \"type\": \"boolean\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"seed\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/SeedConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"seed\",\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"grants\": {},\n            \"quote_columns\": null,\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1657040762.035997\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"compiled_sql\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"CompiledSeedNode(raw_sql: str, compiled: bool, database: Optional[str], schema: str, fqn: List[str], unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.SeedConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Optional[str] = None, compiled_path: Optional[str] = None, build_path: Optional[str] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, compiled_sql: Optional[str] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.compiled.InjectedCTE] = <factory>, relation_name: Optional[str] = None, _pre_injected_sql: Optional[str] = None)\"\n    },\n    \"SeedConfig\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"alias\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tags\": {\n          \"oneOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"string\"\n            }\n          ],\n          \"default\": []\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"materialized\": {\n          \"type\": \"string\",\n          \"default\": \"seed\"\n        },\n        \"persist_docs\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"post-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Hook\"\n          },\n          \"default\": []\n        },\n        \"pre-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Hook\"\n          },\n          \"default\": []\n        },\n        \"quoting\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"column_types\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"full_refresh\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"unique_key\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"on_schema_change\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": \"ignore\"\n        },\n        \"grants\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"quote_columns\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"SeedConfig(_extra: Dict[str, Any] = <factory>, enabled: bool = True, alias: Optional[str] = None, schema: Optional[str] = None, database: Optional[str] = None, tags: Union[List[str], str] = <factory>, meta: Dict[str, Any] = <factory>, materialized: str = 'seed', persist_docs: Dict[str, Any] = <factory>, post_hook: List[dbt.contracts.graph.model_config.Hook] = <factory>, pre_hook: List[dbt.contracts.graph.model_config.Hook] = <factory>, quoting: Dict[str, Any] = <factory>, column_types: Dict[str, Any] = <factory>, full_refresh: Optional[bool] = None, unique_key: Union[str, List[str], NoneType] = None, on_schema_change: Optional[str] = 'ignore', grants: Dict[str, Any] = <factory>, quote_columns: Optional[bool] = None)\"\n    },\n    \"CompiledSnapshotNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"raw_sql\",\n        \"compiled\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"raw_sql\": {\n          \"type\": \"string\"\n        },\n        \"compiled\": {\n          \"type\": \"boolean\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"snapshot\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"view\",\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"grants\": {},\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1657040762.037313\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"compiled_sql\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"CompiledSnapshotNode(raw_sql: str, compiled: bool, database: Optional[str], schema: str, fqn: List[str], unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Optional[str] = None, compiled_path: Optional[str] = None, build_path: Optional[str] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, compiled_sql: Optional[str] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.compiled.InjectedCTE] = <factory>, relation_name: Optional[str] = None, _pre_injected_sql: Optional[str] = None)\"\n    },\n    \"ParsedAnalysisNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"raw_sql\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"raw_sql\": {\n          \"type\": \"string\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"analysis\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"view\",\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"grants\": {},\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1657040762.038346\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ParsedAnalysisNode(raw_sql: str, database: Optional[str], schema: str, fqn: List[str], unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Optional[str] = None, compiled_path: Optional[str] = None, build_path: Optional[str] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>)\"\n    },\n    \"ParsedSingularTestNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"raw_sql\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"raw_sql\": {\n          \"type\": \"string\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"test\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/TestConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": \"dbt_test__audit\",\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"test\",\n            \"severity\": \"ERROR\",\n            \"store_failures\": null,\n            \"where\": null,\n            \"limit\": null,\n            \"fail_calc\": \"count(*)\",\n            \"warn_if\": \"!= 0\",\n            \"error_if\": \"!= 0\"\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1657040762.039365\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ParsedSingularTestNode(raw_sql: str, database: Optional[str], schema: str, fqn: List[str], unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.TestConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Optional[str] = None, compiled_path: Optional[str] = None, build_path: Optional[str] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>)\"\n    },\n    \"ParsedHookNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"raw_sql\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"raw_sql\": {\n          \"type\": \"string\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"operation\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"view\",\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"grants\": {},\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1657040762.0402749\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"index\": {\n          \"oneOf\": [\n            {\n              \"type\": \"integer\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ParsedHookNode(raw_sql: str, database: Optional[str], schema: str, fqn: List[str], unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Optional[str] = None, compiled_path: Optional[str] = None, build_path: Optional[str] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, index: Optional[int] = None)\"\n    },\n    \"ParsedModelNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"raw_sql\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"raw_sql\": {\n          \"type\": \"string\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"model\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"view\",\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"grants\": {},\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1657040762.041198\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ParsedModelNode(raw_sql: str, database: Optional[str], schema: str, fqn: List[str], unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Optional[str] = None, compiled_path: Optional[str] = None, build_path: Optional[str] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>)\"\n    },\n    \"ParsedRPCNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"raw_sql\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"raw_sql\": {\n          \"type\": \"string\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"rpc\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"view\",\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"grants\": {},\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1657040762.0420969\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ParsedRPCNode(raw_sql: str, database: Optional[str], schema: str, fqn: List[str], unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Optional[str] = None, compiled_path: Optional[str] = None, build_path: Optional[str] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>)\"\n    },\n    \"ParsedSqlNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"raw_sql\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"raw_sql\": {\n          \"type\": \"string\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"sql\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"view\",\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"grants\": {},\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1657040762.0429912\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ParsedSqlNode(raw_sql: str, database: Optional[str], schema: str, fqn: List[str], unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Optional[str] = None, compiled_path: Optional[str] = None, build_path: Optional[str] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>)\"\n    },\n    \"ParsedGenericTestNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"raw_sql\",\n        \"test_metadata\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"raw_sql\": {\n          \"type\": \"string\"\n        },\n        \"test_metadata\": {\n          \"$ref\": \"#/definitions/TestMetadata\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"test\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/TestConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": \"dbt_test__audit\",\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"test\",\n            \"severity\": \"ERROR\",\n            \"store_failures\": null,\n            \"where\": null,\n            \"limit\": null,\n            \"fail_calc\": \"count(*)\",\n            \"warn_if\": \"!= 0\",\n            \"error_if\": \"!= 0\"\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1657040762.043911\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"column_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"file_key_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ParsedGenericTestNode(raw_sql: str, test_metadata: dbt.contracts.graph.parsed.TestMetadata, database: Optional[str], schema: str, fqn: List[str], unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.TestConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Optional[str] = None, compiled_path: Optional[str] = None, build_path: Optional[str] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, column_name: Optional[str] = None, file_key_name: Optional[str] = None)\"\n    },\n    \"ParsedSeedNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"raw_sql\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"raw_sql\": {\n          \"type\": \"string\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"seed\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/SeedConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"seed\",\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"grants\": {},\n            \"quote_columns\": null,\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1657040762.044916\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ParsedSeedNode(raw_sql: str, database: Optional[str], schema: str, fqn: List[str], unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.SeedConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Optional[str] = None, compiled_path: Optional[str] = None, build_path: Optional[str] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>)\"\n    },\n    \"ParsedSnapshotNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"raw_sql\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\",\n        \"config\"\n      ],\n      \"properties\": {\n        \"raw_sql\": {\n          \"type\": \"string\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"snapshot\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/SnapshotConfig\"\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1657040762.04684\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ParsedSnapshotNode(raw_sql: str, database: Optional[str], schema: str, fqn: List[str], unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.SnapshotConfig, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Optional[str] = None, compiled_path: Optional[str] = None, build_path: Optional[str] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>)\"\n    },\n    \"SnapshotConfig\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"alias\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tags\": {\n          \"oneOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"string\"\n            }\n          ],\n          \"default\": []\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"materialized\": {\n          \"type\": \"string\",\n          \"default\": \"snapshot\"\n        },\n        \"persist_docs\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"post-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Hook\"\n          },\n          \"default\": []\n        },\n        \"pre-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Hook\"\n          },\n          \"default\": []\n        },\n        \"quoting\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"column_types\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"full_refresh\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"unique_key\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"on_schema_change\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": \"ignore\"\n        },\n        \"grants\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"strategy\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"target_schema\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"target_database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"updated_at\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"check_cols\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"SnapshotConfig(_extra: Dict[str, Any] = <factory>, enabled: bool = True, alias: Optional[str] = None, schema: Optional[str] = None, database: Optional[str] = None, tags: Union[List[str], str] = <factory>, meta: Dict[str, Any] = <factory>, materialized: str = 'snapshot', persist_docs: Dict[str, Any] = <factory>, post_hook: List[dbt.contracts.graph.model_config.Hook] = <factory>, pre_hook: List[dbt.contracts.graph.model_config.Hook] = <factory>, quoting: Dict[str, Any] = <factory>, column_types: Dict[str, Any] = <factory>, full_refresh: Optional[bool] = None, unique_key: Optional[str] = None, on_schema_change: Optional[str] = 'ignore', grants: Dict[str, Any] = <factory>, strategy: Optional[str] = None, target_schema: Optional[str] = None, target_database: Optional[str] = None, updated_at: Optional[str] = None, check_cols: Union[str, List[str], NoneType] = None)\"\n    },\n    \"ParsedSourceDefinition\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"fqn\",\n        \"schema\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"source_name\",\n        \"source_description\",\n        \"loader\",\n        \"identifier\",\n        \"resource_type\"\n      ],\n      \"properties\": {\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"source_name\": {\n          \"type\": \"string\"\n        },\n        \"source_description\": {\n          \"type\": \"string\"\n        },\n        \"loader\": {\n          \"type\": \"string\"\n        },\n        \"identifier\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"source\"\n          ]\n        },\n        \"quoting\": {\n          \"$ref\": \"#/definitions/Quoting\",\n          \"default\": {\n            \"database\": null,\n            \"schema\": null,\n            \"identifier\": null,\n            \"column\": null\n          }\n        },\n        \"loaded_at_field\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"freshness\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/FreshnessThreshold\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"external\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/ExternalTable\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"source_meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/SourceConfig\",\n          \"default\": {\n            \"enabled\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1657040762.048556\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ParsedSourceDefinition(fqn: List[str], database: Optional[str], schema: str, unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, source_name: str, source_description: str, loader: str, identifier: str, resource_type: dbt.node_types.NodeType, _event_status: Dict[str, Any] = <factory>, quoting: dbt.contracts.graph.unparsed.Quoting = <factory>, loaded_at_field: Optional[str] = None, freshness: Optional[dbt.contracts.graph.unparsed.FreshnessThreshold] = None, external: Optional[dbt.contracts.graph.unparsed.ExternalTable] = None, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, source_meta: Dict[str, Any] = <factory>, tags: List[str] = <factory>, config: dbt.contracts.graph.model_config.SourceConfig = <factory>, patch_path: Optional[pathlib.Path] = None, unrendered_config: Dict[str, Any] = <factory>, relation_name: Optional[str] = None, created_at: float = <factory>)\"\n    },\n    \"Quoting\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"identifier\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"column\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Quoting(database: Optional[bool] = None, schema: Optional[bool] = None, identifier: Optional[bool] = None, column: Optional[bool] = None)\"\n    },\n    \"FreshnessThreshold\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"warn_after\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/Time\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": {\n            \"count\": null,\n            \"period\": null\n          }\n        },\n        \"error_after\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/Time\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": {\n            \"count\": null,\n            \"period\": null\n          }\n        },\n        \"filter\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"FreshnessThreshold(warn_after: Optional[dbt.contracts.graph.unparsed.Time] = <factory>, error_after: Optional[dbt.contracts.graph.unparsed.Time] = <factory>, filter: Optional[str] = None)\"\n    },\n    \"FreshnessMetadata\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"dbt_schema_version\": {\n          \"type\": \"string\",\n          \"default\": \"https://schemas.getdbt.com/dbt/sources/v3.json\"\n        },\n        \"dbt_version\": {\n          \"type\": \"string\",\n          \"default\": \"1.2.0a1\"\n        },\n        \"generated_at\": {\n          \"type\": \"string\",\n          \"format\": \"date-time\",\n          \"default\": \"2022-07-05T17:06:02.017833Z\"\n        },\n        \"invocation_id\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": \"6cec400a-e8a4-4480-8ceb-d35589d12bab\"\n        },\n        \"env\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          },\n          \"default\": {}\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"FreshnessMetadata(dbt_schema_version: str = <factory>, dbt_version: str = '1.2.0a1', generated_at: datetime.datetime = <factory>, invocation_id: Optional[str] = <factory>, env: Dict[str, str] = <factory>)\"\n    },\n    \"SourceFreshnessRuntimeError\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"unique_id\",\n        \"status\"\n      ],\n      \"properties\": {\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"error\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"integer\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"status\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"runtime error\"\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"SourceFreshnessRuntimeError(unique_id: str, error: Union[str, int, NoneType], status: dbt.contracts.results.FreshnessErrorEnum)\"\n    },\n    \"SourceFreshnessOutput\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"unique_id\",\n        \"max_loaded_at\",\n        \"snapshotted_at\",\n        \"max_loaded_at_time_ago_in_s\",\n        \"status\",\n        \"criteria\",\n        \"adapter_response\",\n        \"timing\",\n        \"thread_id\",\n        \"execution_time\"\n      ],\n      \"properties\": {\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"max_loaded_at\": {\n          \"type\": \"string\",\n          \"format\": \"date-time\"\n        },\n        \"snapshotted_at\": {\n          \"type\": \"string\",\n          \"format\": \"date-time\"\n        },\n        \"max_loaded_at_time_ago_in_s\": {\n          \"type\": \"number\"\n        },\n        \"status\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"pass\",\n            \"warn\",\n            \"error\",\n            \"runtime error\"\n          ]\n        },\n        \"criteria\": {\n          \"$ref\": \"#/definitions/FreshnessThreshold\"\n        },\n        \"adapter_response\": {\n          \"type\": \"object\"\n        },\n        \"timing\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/TimingInfo\"\n          }\n        },\n        \"thread_id\": {\n          \"type\": \"string\"\n        },\n        \"execution_time\": {\n          \"type\": \"number\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"SourceFreshnessOutput(unique_id: str, max_loaded_at: datetime.datetime, snapshotted_at: datetime.datetime, max_loaded_at_time_ago_in_s: float, status: dbt.contracts.results.FreshnessStatus, criteria: dbt.contracts.graph.unparsed.FreshnessThreshold, adapter_response: Dict[str, Any], timing: List[dbt.contracts.results.TimingInfo], thread_id: str, execution_time: float)\"\n    },\n    \"Time\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"count\": {\n          \"oneOf\": [\n            {\n              \"type\": \"integer\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"period\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\",\n              \"enum\": [\n                \"minute\",\n                \"hour\",\n                \"day\"\n              ]\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Time(count: Optional[int] = None, period: Optional[dbt.contracts.graph.unparsed.TimePeriod] = None)\"\n    },\n    \"TimingInfo\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"started_at\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\",\n              \"format\": \"date-time\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"completed_at\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\",\n              \"format\": \"date-time\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"TimingInfo(name: str, started_at: Optional[datetime.datetime] = None, completed_at: Optional[datetime.datetime] = None)\"\n    },\n    \"ExternalTable\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"location\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"file_format\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"row_format\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tbl_properties\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"partitions\": {\n          \"oneOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"$ref\": \"#/definitions/ExternalPartition\"\n              }\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"ExternalTable(_extra: Dict[str, Any] = <factory>, location: Optional[str] = None, file_format: Optional[str] = None, row_format: Optional[str] = None, tbl_properties: Optional[str] = None, partitions: Optional[List[dbt.contracts.graph.unparsed.ExternalPartition]] = None)\"\n    },\n    \"ExternalPartition\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"data_type\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"ExternalPartition(_extra: Dict[str, Any] = <factory>, name: str = '', description: str = '', data_type: str = '', meta: Dict[str, Any] = <factory>)\"\n    },\n    \"SourceConfig\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"SourceConfig(_extra: Dict[str, Any] = <factory>, enabled: bool = True)\"\n    },\n    \"ParsedMacro\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"macro_sql\",\n        \"resource_type\"\n      ],\n      \"properties\": {\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"macro_sql\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"macro\"\n          ]\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/MacroDependsOn\",\n          \"default\": {\n            \"macros\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"arguments\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/MacroArgument\"\n          },\n          \"default\": []\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1657040762.049289\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ParsedMacro(unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, macro_sql: str, resource_type: dbt.node_types.NodeType, tags: List[str] = <factory>, depends_on: dbt.contracts.graph.parsed.MacroDependsOn = <factory>, description: str = '', meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Optional[str] = None, arguments: List[dbt.contracts.graph.unparsed.MacroArgument] = <factory>, created_at: float = <factory>)\"\n    },\n    \"MacroDependsOn\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"macros\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"MacroDependsOn(macros: List[str] = <factory>)\"\n    },\n    \"MacroArgument\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"type\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"MacroArgument(name: str, type: Optional[str] = None, description: str = '')\"\n    },\n    \"ParsedDocumentation\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"block_contents\"\n      ],\n      \"properties\": {\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"block_contents\": {\n          \"type\": \"string\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ParsedDocumentation(unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, block_contents: str)\"\n    },\n    \"ParsedExposure\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"fqn\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"type\",\n        \"owner\"\n      ],\n      \"properties\": {\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"dashboard\",\n            \"notebook\",\n            \"analysis\",\n            \"ml\",\n            \"application\"\n          ]\n        },\n        \"owner\": {\n          \"$ref\": \"#/definitions/ExposureOwner\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"model\",\n            \"analysis\",\n            \"test\",\n            \"snapshot\",\n            \"operation\",\n            \"seed\",\n            \"rpc\",\n            \"sql\",\n            \"docs\",\n            \"source\",\n            \"macro\",\n            \"exposure\",\n            \"metric\"\n          ],\n          \"default\": \"exposure\"\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"maturity\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\",\n              \"enum\": [\n                \"low\",\n                \"medium\",\n                \"high\"\n              ]\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"url\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1657040762.050287\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ParsedExposure(fqn: List[str], unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, type: dbt.contracts.graph.unparsed.ExposureType, owner: dbt.contracts.graph.unparsed.ExposureOwner, resource_type: dbt.node_types.NodeType = <NodeType.Exposure: 'exposure'>, description: str = '', maturity: Optional[dbt.contracts.graph.unparsed.MaturityType] = None, meta: Dict[str, Any] = <factory>, tags: List[str] = <factory>, url: Optional[str] = None, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, created_at: float = <factory>)\"\n    },\n    \"ExposureOwner\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"email\"\n      ],\n      \"properties\": {\n        \"email\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ExposureOwner(email: str, name: Optional[str] = None)\"\n    },\n    \"ParsedMetric\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"fqn\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"description\",\n        \"label\",\n        \"type\",\n        \"sql\",\n        \"filters\",\n        \"time_grains\",\n        \"dimensions\"\n      ],\n      \"properties\": {\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"label\": {\n          \"type\": \"string\"\n        },\n        \"type\": {\n          \"type\": \"string\"\n        },\n        \"sql\": {\n          \"type\": \"string\"\n        },\n        \"timestamp\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"filters\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/MetricFilter\"\n          }\n        },\n        \"time_grains\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"dimensions\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"model\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"model_unique_id\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"model\",\n            \"analysis\",\n            \"test\",\n            \"snapshot\",\n            \"operation\",\n            \"seed\",\n            \"rpc\",\n            \"sql\",\n            \"docs\",\n            \"source\",\n            \"macro\",\n            \"exposure\",\n            \"metric\"\n          ],\n          \"default\": \"metric\"\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1657040762.051152\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ParsedMetric(fqn: List[str], unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, description: str, label: str, type: str, sql: str, timestamp: Optional[str], filters: List[dbt.contracts.graph.unparsed.MetricFilter], time_grains: List[str], dimensions: List[str], model: Optional[str] = None, model_unique_id: Optional[str] = None, resource_type: dbt.node_types.NodeType = <NodeType.Metric: 'metric'>, meta: Dict[str, Any] = <factory>, tags: List[str] = <factory>, sources: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, refs: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, created_at: float = <factory>)\"\n    },\n    \"MetricFilter\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"field\",\n        \"operator\",\n        \"value\"\n      ],\n      \"properties\": {\n        \"field\": {\n          \"type\": \"string\"\n        },\n        \"operator\": {\n          \"type\": \"string\"\n        },\n        \"value\": {\n          \"type\": \"string\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"MetricFilter(field: str, operator: str, value: str)\"\n    }\n  },\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n  \"$id\": \"https://schemas.getdbt.com/dbt/manifest/v6.json\"\n}"
  },
  {
    "path": "schemas/dbt/manifest/v7.json",
    "content": "{\n  \"type\": \"object\",\n  \"required\": [\n    \"metadata\",\n    \"nodes\",\n    \"sources\",\n    \"macros\",\n    \"docs\",\n    \"exposures\",\n    \"metrics\",\n    \"selectors\"\n  ],\n  \"properties\": {\n    \"metadata\": {\n      \"$ref\": \"#/definitions/ManifestMetadata\",\n      \"description\": \"Metadata about the manifest\"\n    },\n    \"nodes\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"oneOf\": [\n          {\n            \"$ref\": \"#/definitions/CompiledAnalysisNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/CompiledSingularTestNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/CompiledModelNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/CompiledHookNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/CompiledRPCNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/CompiledSqlNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/CompiledGenericTestNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/CompiledSeedNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/CompiledSnapshotNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/ParsedAnalysisNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/ParsedSingularTestNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/ParsedHookNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/ParsedModelNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/ParsedRPCNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/ParsedSqlNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/ParsedGenericTestNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/ParsedSeedNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/ParsedSnapshotNode\"\n          }\n        ]\n      },\n      \"description\": \"The nodes defined in the dbt project and its dependencies\"\n    },\n    \"sources\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/ParsedSourceDefinition\"\n      },\n      \"description\": \"The sources defined in the dbt project and its dependencies\"\n    },\n    \"macros\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/ParsedMacro\"\n      },\n      \"description\": \"The macros defined in the dbt project and its dependencies\"\n    },\n    \"docs\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/ParsedDocumentation\"\n      },\n      \"description\": \"The docs defined in the dbt project and its dependencies\"\n    },\n    \"exposures\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/ParsedExposure\"\n      },\n      \"description\": \"The exposures defined in the dbt project and its dependencies\"\n    },\n    \"metrics\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/ParsedMetric\"\n      },\n      \"description\": \"The metrics defined in the dbt project and its dependencies\"\n    },\n    \"selectors\": {\n      \"type\": \"object\",\n      \"description\": \"The selectors defined in selectors.yml\"\n    },\n    \"disabled\": {\n      \"oneOf\": [\n        {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"oneOf\": [\n                {\n                  \"$ref\": \"#/definitions/CompiledAnalysisNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/CompiledSingularTestNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/CompiledModelNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/CompiledHookNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/CompiledRPCNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/CompiledSqlNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/CompiledGenericTestNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/CompiledSeedNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/CompiledSnapshotNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/ParsedAnalysisNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/ParsedSingularTestNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/ParsedHookNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/ParsedModelNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/ParsedRPCNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/ParsedSqlNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/ParsedGenericTestNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/ParsedSeedNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/ParsedSnapshotNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/ParsedSourceDefinition\"\n                }\n              ]\n            }\n          }\n        },\n        {\n          \"type\": \"null\"\n        }\n      ],\n      \"description\": \"A mapping of the disabled nodes in the target\"\n    },\n    \"parent_map\": {\n      \"oneOf\": [\n        {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          }\n        },\n        {\n          \"type\": \"null\"\n        }\n      ],\n      \"description\": \"A mapping from\\u00a0child nodes to their dependencies\"\n    },\n    \"child_map\": {\n      \"oneOf\": [\n        {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          }\n        },\n        {\n          \"type\": \"null\"\n        }\n      ],\n      \"description\": \"A mapping from parent nodes to their dependents\"\n    }\n  },\n  \"additionalProperties\": false,\n  \"description\": \"WritableManifest(metadata: dbt.contracts.graph.manifest.ManifestMetadata, nodes: Mapping[str, Union[dbt.contracts.graph.compiled.CompiledAnalysisNode, dbt.contracts.graph.compiled.CompiledSingularTestNode, dbt.contracts.graph.compiled.CompiledModelNode, dbt.contracts.graph.compiled.CompiledHookNode, dbt.contracts.graph.compiled.CompiledRPCNode, dbt.contracts.graph.compiled.CompiledSqlNode, dbt.contracts.graph.compiled.CompiledGenericTestNode, dbt.contracts.graph.compiled.CompiledSeedNode, dbt.contracts.graph.compiled.CompiledSnapshotNode, dbt.contracts.graph.parsed.ParsedAnalysisNode, dbt.contracts.graph.parsed.ParsedSingularTestNode, dbt.contracts.graph.parsed.ParsedHookNode, dbt.contracts.graph.parsed.ParsedModelNode, dbt.contracts.graph.parsed.ParsedRPCNode, dbt.contracts.graph.parsed.ParsedSqlNode, dbt.contracts.graph.parsed.ParsedGenericTestNode, dbt.contracts.graph.parsed.ParsedSeedNode, dbt.contracts.graph.parsed.ParsedSnapshotNode]], sources: Mapping[str, dbt.contracts.graph.parsed.ParsedSourceDefinition], macros: Mapping[str, dbt.contracts.graph.parsed.ParsedMacro], docs: Mapping[str, dbt.contracts.graph.parsed.ParsedDocumentation], exposures: Mapping[str, dbt.contracts.graph.parsed.ParsedExposure], metrics: Mapping[str, dbt.contracts.graph.parsed.ParsedMetric], selectors: Mapping[str, Any], disabled: Union[Mapping[str, List[Union[dbt.contracts.graph.compiled.CompiledAnalysisNode, dbt.contracts.graph.compiled.CompiledSingularTestNode, dbt.contracts.graph.compiled.CompiledModelNode, dbt.contracts.graph.compiled.CompiledHookNode, dbt.contracts.graph.compiled.CompiledRPCNode, dbt.contracts.graph.compiled.CompiledSqlNode, dbt.contracts.graph.compiled.CompiledGenericTestNode, dbt.contracts.graph.compiled.CompiledSeedNode, dbt.contracts.graph.compiled.CompiledSnapshotNode, dbt.contracts.graph.parsed.ParsedAnalysisNode, dbt.contracts.graph.parsed.ParsedSingularTestNode, dbt.contracts.graph.parsed.ParsedHookNode, dbt.contracts.graph.parsed.ParsedModelNode, dbt.contracts.graph.parsed.ParsedRPCNode, dbt.contracts.graph.parsed.ParsedSqlNode, dbt.contracts.graph.parsed.ParsedGenericTestNode, dbt.contracts.graph.parsed.ParsedSeedNode, dbt.contracts.graph.parsed.ParsedSnapshotNode, dbt.contracts.graph.parsed.ParsedSourceDefinition]]], NoneType], parent_map: Union[Dict[str, List[str]], NoneType], child_map: Union[Dict[str, List[str]], NoneType])\",\n  \"definitions\": {\n    \"ManifestMetadata\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"dbt_schema_version\": {\n          \"type\": \"string\",\n          \"default\": \"https://schemas.getdbt.com/dbt/manifest/v7.json\"\n        },\n        \"dbt_version\": {\n          \"type\": \"string\",\n          \"default\": \"1.3.0b2\"\n        },\n        \"generated_at\": {\n          \"type\": \"string\",\n          \"format\": \"date-time\",\n          \"default\": \"2022-09-14T20:35:15.346636Z\"\n        },\n        \"invocation_id\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": \"c59a8269-533c-4b78-a709-5094045afd4d\"\n        },\n        \"env\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          },\n          \"default\": {}\n        },\n        \"project_id\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"description\": \"A unique identifier for the project\"\n        },\n        \"user_id\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\",\n              \"pattern\": \"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"description\": \"A unique identifier for the user\"\n        },\n        \"send_anonymous_usage_stats\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"description\": \"Whether dbt is configured to send anonymous usage statistics\"\n        },\n        \"adapter_type\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"description\": \"The type name of the adapter\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Metadata for the manifest.\"\n    },\n    \"CompiledAnalysisNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"compiled\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"raw_code\",\n        \"language\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"compiled\": {\n          \"type\": \"boolean\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"raw_code\": {\n          \"type\": \"string\"\n        },\n        \"language\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"analysis\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"view\",\n            \"incremental_strategy\": null,\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"grants\": {},\n            \"packages\": [],\n            \"docs\": {\n              \"show\": true,\n              \"node_color\": null\n            },\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1663187715.3517282\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"compiled_code\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"CompiledAnalysisNode(compiled: bool, database: Union[str, NoneType], schema: str, fqn: List[str], unique_id: str, raw_code: str, language: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, compiled_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, compiled_code: Union[str, NoneType] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.compiled.InjectedCTE] = <factory>, relation_name: Union[str, NoneType] = None, _pre_injected_sql: Union[str, NoneType] = None)\"\n    },\n    \"FileHash\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"type\": \"string\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"FileHash(name: str, checksum: str)\"\n    },\n    \"NodeConfig\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"alias\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tags\": {\n          \"oneOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"string\"\n            }\n          ],\n          \"default\": []\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"materialized\": {\n          \"type\": \"string\",\n          \"default\": \"view\"\n        },\n        \"incremental_strategy\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"persist_docs\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"post-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Hook\"\n          },\n          \"default\": []\n        },\n        \"pre-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Hook\"\n          },\n          \"default\": []\n        },\n        \"quoting\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"column_types\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"full_refresh\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"unique_key\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"on_schema_change\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": \"ignore\"\n        },\n        \"grants\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"packages\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"NodeConfig(_extra: Dict[str, Any] = <factory>, enabled: bool = True, alias: Union[str, NoneType] = None, schema: Union[str, NoneType] = None, database: Union[str, NoneType] = None, tags: Union[List[str], str] = <factory>, meta: Dict[str, Any] = <factory>, materialized: str = 'view', incremental_strategy: Union[str, NoneType] = None, persist_docs: Dict[str, Any] = <factory>, post_hook: List[dbt.contracts.graph.model_config.Hook] = <factory>, pre_hook: List[dbt.contracts.graph.model_config.Hook] = <factory>, quoting: Dict[str, Any] = <factory>, column_types: Dict[str, Any] = <factory>, full_refresh: Union[bool, NoneType] = None, unique_key: Union[str, List[str], NoneType] = None, on_schema_change: Union[str, NoneType] = 'ignore', grants: Dict[str, Any] = <factory>, packages: List[str] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>)\"\n    },\n    \"Hook\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"sql\"\n      ],\n      \"properties\": {\n        \"sql\": {\n          \"type\": \"string\"\n        },\n        \"transaction\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"index\": {\n          \"oneOf\": [\n            {\n              \"type\": \"integer\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Hook(sql: str, transaction: bool = True, index: Union[int, NoneType] = None)\"\n    },\n    \"Docs\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"show\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"node_color\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Docs(show: bool = True, node_color: Union[str, NoneType] = None)\"\n    },\n    \"DependsOn\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"macros\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"nodes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"DependsOn(macros: List[str] = <factory>, nodes: List[str] = <factory>)\"\n    },\n    \"ColumnInfo\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"data_type\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"quote\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"ColumnInfo(name: str, description: str = '', meta: Dict[str, Any] = <factory>, data_type: Union[str, NoneType] = None, quote: Union[bool, NoneType] = None, tags: List[str] = <factory>, _extra: Dict[str, Any] = <factory>)\"\n    },\n    \"InjectedCTE\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"id\",\n        \"sql\"\n      ],\n      \"properties\": {\n        \"id\": {\n          \"type\": \"string\"\n        },\n        \"sql\": {\n          \"type\": \"string\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"InjectedCTE(id: str, sql: str)\"\n    },\n    \"CompiledSingularTestNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"compiled\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"raw_code\",\n        \"language\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"compiled\": {\n          \"type\": \"boolean\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"raw_code\": {\n          \"type\": \"string\"\n        },\n        \"language\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"test\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/TestConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": \"dbt_test__audit\",\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"test\",\n            \"severity\": \"ERROR\",\n            \"store_failures\": null,\n            \"where\": null,\n            \"limit\": null,\n            \"fail_calc\": \"count(*)\",\n            \"warn_if\": \"!= 0\",\n            \"error_if\": \"!= 0\"\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1663187715.35441\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"compiled_code\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"CompiledSingularTestNode(compiled: bool, database: Union[str, NoneType], schema: str, fqn: List[str], unique_id: str, raw_code: str, language: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.TestConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, compiled_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, compiled_code: Union[str, NoneType] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.compiled.InjectedCTE] = <factory>, relation_name: Union[str, NoneType] = None, _pre_injected_sql: Union[str, NoneType] = None)\"\n    },\n    \"TestConfig\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"alias\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": \"dbt_test__audit\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tags\": {\n          \"oneOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"string\"\n            }\n          ],\n          \"default\": []\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"materialized\": {\n          \"type\": \"string\",\n          \"default\": \"test\"\n        },\n        \"severity\": {\n          \"type\": \"string\",\n          \"pattern\": \"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$\",\n          \"default\": \"ERROR\"\n        },\n        \"store_failures\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"where\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"limit\": {\n          \"oneOf\": [\n            {\n              \"type\": \"integer\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"fail_calc\": {\n          \"type\": \"string\",\n          \"default\": \"count(*)\"\n        },\n        \"warn_if\": {\n          \"type\": \"string\",\n          \"default\": \"!= 0\"\n        },\n        \"error_if\": {\n          \"type\": \"string\",\n          \"default\": \"!= 0\"\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"TestConfig(_extra: Dict[str, Any] = <factory>, enabled: bool = True, alias: Union[str, NoneType] = None, schema: Union[str, NoneType] = 'dbt_test__audit', database: Union[str, NoneType] = None, tags: Union[List[str], str] = <factory>, meta: Dict[str, Any] = <factory>, materialized: str = 'test', severity: dbt.contracts.graph.model_config.Severity = 'ERROR', store_failures: Union[bool, NoneType] = None, where: Union[str, NoneType] = None, limit: Union[int, NoneType] = None, fail_calc: str = 'count(*)', warn_if: str = '!= 0', error_if: str = '!= 0')\"\n    },\n    \"CompiledModelNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"compiled\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"raw_code\",\n        \"language\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"compiled\": {\n          \"type\": \"boolean\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"raw_code\": {\n          \"type\": \"string\"\n        },\n        \"language\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"model\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"view\",\n            \"incremental_strategy\": null,\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"grants\": {},\n            \"packages\": [],\n            \"docs\": {\n              \"show\": true,\n              \"node_color\": null\n            },\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1663187715.356541\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"compiled_code\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"CompiledModelNode(compiled: bool, database: Union[str, NoneType], schema: str, fqn: List[str], unique_id: str, raw_code: str, language: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, compiled_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, compiled_code: Union[str, NoneType] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.compiled.InjectedCTE] = <factory>, relation_name: Union[str, NoneType] = None, _pre_injected_sql: Union[str, NoneType] = None)\"\n    },\n    \"CompiledHookNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"compiled\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"raw_code\",\n        \"language\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"compiled\": {\n          \"type\": \"boolean\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"raw_code\": {\n          \"type\": \"string\"\n        },\n        \"language\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"operation\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"view\",\n            \"incremental_strategy\": null,\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"grants\": {},\n            \"packages\": [],\n            \"docs\": {\n              \"show\": true,\n              \"node_color\": null\n            },\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1663187715.3582149\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"compiled_code\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"index\": {\n          \"oneOf\": [\n            {\n              \"type\": \"integer\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"CompiledHookNode(compiled: bool, database: Union[str, NoneType], schema: str, fqn: List[str], unique_id: str, raw_code: str, language: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, compiled_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, compiled_code: Union[str, NoneType] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.compiled.InjectedCTE] = <factory>, relation_name: Union[str, NoneType] = None, _pre_injected_sql: Union[str, NoneType] = None, index: Union[int, NoneType] = None)\"\n    },\n    \"CompiledRPCNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"compiled\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"raw_code\",\n        \"language\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"compiled\": {\n          \"type\": \"boolean\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"raw_code\": {\n          \"type\": \"string\"\n        },\n        \"language\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"rpc\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"view\",\n            \"incremental_strategy\": null,\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"grants\": {},\n            \"packages\": [],\n            \"docs\": {\n              \"show\": true,\n              \"node_color\": null\n            },\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1663187715.359935\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"compiled_code\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"CompiledRPCNode(compiled: bool, database: Union[str, NoneType], schema: str, fqn: List[str], unique_id: str, raw_code: str, language: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, compiled_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, compiled_code: Union[str, NoneType] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.compiled.InjectedCTE] = <factory>, relation_name: Union[str, NoneType] = None, _pre_injected_sql: Union[str, NoneType] = None)\"\n    },\n    \"CompiledSqlNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"compiled\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"raw_code\",\n        \"language\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"compiled\": {\n          \"type\": \"boolean\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"raw_code\": {\n          \"type\": \"string\"\n        },\n        \"language\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"sql operation\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"view\",\n            \"incremental_strategy\": null,\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"grants\": {},\n            \"packages\": [],\n            \"docs\": {\n              \"show\": true,\n              \"node_color\": null\n            },\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1663187715.361423\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"compiled_code\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"CompiledSqlNode(compiled: bool, database: Union[str, NoneType], schema: str, fqn: List[str], unique_id: str, raw_code: str, language: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, compiled_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, compiled_code: Union[str, NoneType] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.compiled.InjectedCTE] = <factory>, relation_name: Union[str, NoneType] = None, _pre_injected_sql: Union[str, NoneType] = None)\"\n    },\n    \"CompiledGenericTestNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"test_metadata\",\n        \"compiled\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"raw_code\",\n        \"language\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"test_metadata\": {\n          \"$ref\": \"#/definitions/TestMetadata\"\n        },\n        \"compiled\": {\n          \"type\": \"boolean\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"raw_code\": {\n          \"type\": \"string\"\n        },\n        \"language\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"test\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/TestConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": \"dbt_test__audit\",\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"test\",\n            \"severity\": \"ERROR\",\n            \"store_failures\": null,\n            \"where\": null,\n            \"limit\": null,\n            \"fail_calc\": \"count(*)\",\n            \"warn_if\": \"!= 0\",\n            \"error_if\": \"!= 0\"\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1663187715.363411\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"compiled_code\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"column_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"file_key_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"CompiledGenericTestNode(test_metadata: dbt.contracts.graph.parsed.TestMetadata, compiled: bool, database: Union[str, NoneType], schema: str, fqn: List[str], unique_id: str, raw_code: str, language: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.TestConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, compiled_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, compiled_code: Union[str, NoneType] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.compiled.InjectedCTE] = <factory>, relation_name: Union[str, NoneType] = None, _pre_injected_sql: Union[str, NoneType] = None, column_name: Union[str, NoneType] = None, file_key_name: Union[str, NoneType] = None)\"\n    },\n    \"TestMetadata\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"kwargs\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"namespace\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"TestMetadata(name: str, kwargs: Dict[str, Any] = <factory>, namespace: Union[str, NoneType] = None)\"\n    },\n    \"CompiledSeedNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"compiled\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"raw_code\",\n        \"language\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"compiled\": {\n          \"type\": \"boolean\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"raw_code\": {\n          \"type\": \"string\"\n        },\n        \"language\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"seed\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/SeedConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"seed\",\n            \"incremental_strategy\": null,\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"grants\": {},\n            \"packages\": [],\n            \"docs\": {\n              \"show\": true,\n              \"node_color\": null\n            },\n            \"quote_columns\": null,\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1663187715.366584\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"compiled_code\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"CompiledSeedNode(compiled: bool, database: Union[str, NoneType], schema: str, fqn: List[str], unique_id: str, raw_code: str, language: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.SeedConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, compiled_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, compiled_code: Union[str, NoneType] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.compiled.InjectedCTE] = <factory>, relation_name: Union[str, NoneType] = None, _pre_injected_sql: Union[str, NoneType] = None)\"\n    },\n    \"SeedConfig\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"alias\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tags\": {\n          \"oneOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"string\"\n            }\n          ],\n          \"default\": []\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"materialized\": {\n          \"type\": \"string\",\n          \"default\": \"seed\"\n        },\n        \"incremental_strategy\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"persist_docs\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"post-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Hook\"\n          },\n          \"default\": []\n        },\n        \"pre-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Hook\"\n          },\n          \"default\": []\n        },\n        \"quoting\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"column_types\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"full_refresh\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"unique_key\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"on_schema_change\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": \"ignore\"\n        },\n        \"grants\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"packages\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"quote_columns\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"SeedConfig(_extra: Dict[str, Any] = <factory>, enabled: bool = True, alias: Union[str, NoneType] = None, schema: Union[str, NoneType] = None, database: Union[str, NoneType] = None, tags: Union[List[str], str] = <factory>, meta: Dict[str, Any] = <factory>, materialized: str = 'seed', incremental_strategy: Union[str, NoneType] = None, persist_docs: Dict[str, Any] = <factory>, post_hook: List[dbt.contracts.graph.model_config.Hook] = <factory>, pre_hook: List[dbt.contracts.graph.model_config.Hook] = <factory>, quoting: Dict[str, Any] = <factory>, column_types: Dict[str, Any] = <factory>, full_refresh: Union[bool, NoneType] = None, unique_key: Union[str, List[str], NoneType] = None, on_schema_change: Union[str, NoneType] = 'ignore', grants: Dict[str, Any] = <factory>, packages: List[str] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, quote_columns: Union[bool, NoneType] = None)\"\n    },\n    \"CompiledSnapshotNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"compiled\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"raw_code\",\n        \"language\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"compiled\": {\n          \"type\": \"boolean\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"raw_code\": {\n          \"type\": \"string\"\n        },\n        \"language\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"snapshot\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"view\",\n            \"incremental_strategy\": null,\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"grants\": {},\n            \"packages\": [],\n            \"docs\": {\n              \"show\": true,\n              \"node_color\": null\n            },\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1663187715.3682182\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"compiled_code\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"CompiledSnapshotNode(compiled: bool, database: Union[str, NoneType], schema: str, fqn: List[str], unique_id: str, raw_code: str, language: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, compiled_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, compiled_code: Union[str, NoneType] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.compiled.InjectedCTE] = <factory>, relation_name: Union[str, NoneType] = None, _pre_injected_sql: Union[str, NoneType] = None)\"\n    },\n    \"ParsedAnalysisNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"raw_code\",\n        \"language\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"raw_code\": {\n          \"type\": \"string\"\n        },\n        \"language\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"analysis\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"view\",\n            \"incremental_strategy\": null,\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"grants\": {},\n            \"packages\": [],\n            \"docs\": {\n              \"show\": true,\n              \"node_color\": null\n            },\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1663187715.369675\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ParsedAnalysisNode(database: Union[str, NoneType], schema: str, fqn: List[str], unique_id: str, raw_code: str, language: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, compiled_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>)\"\n    },\n    \"ParsedSingularTestNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"raw_code\",\n        \"language\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"raw_code\": {\n          \"type\": \"string\"\n        },\n        \"language\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"test\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/TestConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": \"dbt_test__audit\",\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"test\",\n            \"severity\": \"ERROR\",\n            \"store_failures\": null,\n            \"where\": null,\n            \"limit\": null,\n            \"fail_calc\": \"count(*)\",\n            \"warn_if\": \"!= 0\",\n            \"error_if\": \"!= 0\"\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1663187715.370925\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ParsedSingularTestNode(database: Union[str, NoneType], schema: str, fqn: List[str], unique_id: str, raw_code: str, language: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.TestConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, compiled_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>)\"\n    },\n    \"ParsedHookNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"raw_code\",\n        \"language\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"raw_code\": {\n          \"type\": \"string\"\n        },\n        \"language\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"operation\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"view\",\n            \"incremental_strategy\": null,\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"grants\": {},\n            \"packages\": [],\n            \"docs\": {\n              \"show\": true,\n              \"node_color\": null\n            },\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1663187715.372257\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"index\": {\n          \"oneOf\": [\n            {\n              \"type\": \"integer\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ParsedHookNode(database: Union[str, NoneType], schema: str, fqn: List[str], unique_id: str, raw_code: str, language: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, compiled_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, index: Union[int, NoneType] = None)\"\n    },\n    \"ParsedModelNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"raw_code\",\n        \"language\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"raw_code\": {\n          \"type\": \"string\"\n        },\n        \"language\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"model\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"view\",\n            \"incremental_strategy\": null,\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"grants\": {},\n            \"packages\": [],\n            \"docs\": {\n              \"show\": true,\n              \"node_color\": null\n            },\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1663187715.373705\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ParsedModelNode(database: Union[str, NoneType], schema: str, fqn: List[str], unique_id: str, raw_code: str, language: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, compiled_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>)\"\n    },\n    \"ParsedRPCNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"raw_code\",\n        \"language\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"raw_code\": {\n          \"type\": \"string\"\n        },\n        \"language\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"rpc\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"view\",\n            \"incremental_strategy\": null,\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"grants\": {},\n            \"packages\": [],\n            \"docs\": {\n              \"show\": true,\n              \"node_color\": null\n            },\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1663187715.375131\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ParsedRPCNode(database: Union[str, NoneType], schema: str, fqn: List[str], unique_id: str, raw_code: str, language: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, compiled_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>)\"\n    },\n    \"ParsedSqlNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"raw_code\",\n        \"language\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"raw_code\": {\n          \"type\": \"string\"\n        },\n        \"language\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"sql operation\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"view\",\n            \"incremental_strategy\": null,\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"grants\": {},\n            \"packages\": [],\n            \"docs\": {\n              \"show\": true,\n              \"node_color\": null\n            },\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1663187715.376405\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ParsedSqlNode(database: Union[str, NoneType], schema: str, fqn: List[str], unique_id: str, raw_code: str, language: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, compiled_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>)\"\n    },\n    \"ParsedGenericTestNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"test_metadata\",\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"raw_code\",\n        \"language\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"test_metadata\": {\n          \"$ref\": \"#/definitions/TestMetadata\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"raw_code\": {\n          \"type\": \"string\"\n        },\n        \"language\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"test\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/TestConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": \"dbt_test__audit\",\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"test\",\n            \"severity\": \"ERROR\",\n            \"store_failures\": null,\n            \"where\": null,\n            \"limit\": null,\n            \"fail_calc\": \"count(*)\",\n            \"warn_if\": \"!= 0\",\n            \"error_if\": \"!= 0\"\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1663187715.3784761\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"column_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"file_key_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ParsedGenericTestNode(test_metadata: dbt.contracts.graph.parsed.TestMetadata, database: Union[str, NoneType], schema: str, fqn: List[str], unique_id: str, raw_code: str, language: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.TestConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, compiled_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, column_name: Union[str, NoneType] = None, file_key_name: Union[str, NoneType] = None)\"\n    },\n    \"ParsedSeedNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"raw_code\",\n        \"language\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"raw_code\": {\n          \"type\": \"string\"\n        },\n        \"language\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"seed\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/SeedConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"seed\",\n            \"incremental_strategy\": null,\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"grants\": {},\n            \"packages\": [],\n            \"docs\": {\n              \"show\": true,\n              \"node_color\": null\n            },\n            \"quote_columns\": null,\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1663187715.380325\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ParsedSeedNode(database: Union[str, NoneType], schema: str, fqn: List[str], unique_id: str, raw_code: str, language: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.SeedConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, compiled_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>)\"\n    },\n    \"ParsedSnapshotNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"schema\",\n        \"fqn\",\n        \"unique_id\",\n        \"raw_code\",\n        \"language\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"resource_type\",\n        \"alias\",\n        \"checksum\",\n        \"config\"\n      ],\n      \"properties\": {\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"raw_code\": {\n          \"type\": \"string\"\n        },\n        \"language\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"snapshot\"\n          ]\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/SnapshotConfig\"\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1663187715.3832462\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ParsedSnapshotNode(database: Union[str, NoneType], schema: str, fqn: List[str], unique_id: str, raw_code: str, language: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, resource_type: dbt.node_types.NodeType, alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.SnapshotConfig, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, compiled_path: Union[str, NoneType] = None, build_path: Union[str, NoneType] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>)\"\n    },\n    \"SnapshotConfig\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"alias\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tags\": {\n          \"oneOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"string\"\n            }\n          ],\n          \"default\": []\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"materialized\": {\n          \"type\": \"string\",\n          \"default\": \"snapshot\"\n        },\n        \"incremental_strategy\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"persist_docs\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"post-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Hook\"\n          },\n          \"default\": []\n        },\n        \"pre-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Hook\"\n          },\n          \"default\": []\n        },\n        \"quoting\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"column_types\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"full_refresh\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"unique_key\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"on_schema_change\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": \"ignore\"\n        },\n        \"grants\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"packages\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"strategy\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"target_schema\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"target_database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"updated_at\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"check_cols\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"SnapshotConfig(_extra: Dict[str, Any] = <factory>, enabled: bool = True, alias: Union[str, NoneType] = None, schema: Union[str, NoneType] = None, database: Union[str, NoneType] = None, tags: Union[List[str], str] = <factory>, meta: Dict[str, Any] = <factory>, materialized: str = 'snapshot', incremental_strategy: Union[str, NoneType] = None, persist_docs: Dict[str, Any] = <factory>, post_hook: List[dbt.contracts.graph.model_config.Hook] = <factory>, pre_hook: List[dbt.contracts.graph.model_config.Hook] = <factory>, quoting: Dict[str, Any] = <factory>, column_types: Dict[str, Any] = <factory>, full_refresh: Union[bool, NoneType] = None, unique_key: Union[str, NoneType] = None, on_schema_change: Union[str, NoneType] = 'ignore', grants: Dict[str, Any] = <factory>, packages: List[str] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, strategy: Union[str, NoneType] = None, target_schema: Union[str, NoneType] = None, target_database: Union[str, NoneType] = None, updated_at: Union[str, NoneType] = None, check_cols: Union[str, List[str], NoneType] = None)\"\n    },\n    \"ParsedSourceDefinition\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"fqn\",\n        \"schema\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"source_name\",\n        \"source_description\",\n        \"loader\",\n        \"identifier\",\n        \"resource_type\"\n      ],\n      \"properties\": {\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"source_name\": {\n          \"type\": \"string\"\n        },\n        \"source_description\": {\n          \"type\": \"string\"\n        },\n        \"loader\": {\n          \"type\": \"string\"\n        },\n        \"identifier\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"source\"\n          ]\n        },\n        \"quoting\": {\n          \"$ref\": \"#/definitions/Quoting\",\n          \"default\": {\n            \"database\": null,\n            \"schema\": null,\n            \"identifier\": null,\n            \"column\": null\n          }\n        },\n        \"loaded_at_field\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"freshness\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/FreshnessThreshold\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"external\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/ExternalTable\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"source_meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/SourceConfig\",\n          \"default\": {\n            \"enabled\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1663187715.3854342\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ParsedSourceDefinition(fqn: List[str], database: Union[str, NoneType], schema: str, unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, source_name: str, source_description: str, loader: str, identifier: str, resource_type: dbt.node_types.NodeType, _event_status: Dict[str, Any] = <factory>, quoting: dbt.contracts.graph.unparsed.Quoting = <factory>, loaded_at_field: Union[str, NoneType] = None, freshness: Union[dbt.contracts.graph.unparsed.FreshnessThreshold, NoneType] = None, external: Union[dbt.contracts.graph.unparsed.ExternalTable, NoneType] = None, description: str = '', columns: Dict[str, dbt.contracts.graph.parsed.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, source_meta: Dict[str, Any] = <factory>, tags: List[str] = <factory>, config: dbt.contracts.graph.model_config.SourceConfig = <factory>, patch_path: Union[pathlib.Path, NoneType] = None, unrendered_config: Dict[str, Any] = <factory>, relation_name: Union[str, NoneType] = None, created_at: float = <factory>)\"\n    },\n    \"Quoting\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"identifier\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"column\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Quoting(database: Union[bool, NoneType] = None, schema: Union[bool, NoneType] = None, identifier: Union[bool, NoneType] = None, column: Union[bool, NoneType] = None)\"\n    },\n    \"FreshnessThreshold\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"warn_after\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/Time\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": {\n            \"count\": null,\n            \"period\": null\n          }\n        },\n        \"error_after\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/Time\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": {\n            \"count\": null,\n            \"period\": null\n          }\n        },\n        \"filter\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"FreshnessThreshold(warn_after: Union[dbt.contracts.graph.unparsed.Time, NoneType] = <factory>, error_after: Union[dbt.contracts.graph.unparsed.Time, NoneType] = <factory>, filter: Union[str, NoneType] = None)\"\n    },\n    \"FreshnessMetadata\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"dbt_schema_version\": {\n          \"type\": \"string\",\n          \"default\": \"https://schemas.getdbt.com/dbt/sources/v3.json\"\n        },\n        \"dbt_version\": {\n          \"type\": \"string\",\n          \"default\": \"1.3.0b2\"\n        },\n        \"generated_at\": {\n          \"type\": \"string\",\n          \"format\": \"date-time\",\n          \"default\": \"2022-09-14T20:35:15.341700Z\"\n        },\n        \"invocation_id\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": \"c59a8269-533c-4b78-a709-5094045afd4d\"\n        },\n        \"env\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          },\n          \"default\": {}\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"FreshnessMetadata(dbt_schema_version: str = <factory>, dbt_version: str = '1.3.0b2', generated_at: datetime.datetime = <factory>, invocation_id: Union[str, NoneType] = <factory>, env: Dict[str, str] = <factory>)\"\n    },\n    \"SourceFreshnessRuntimeError\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"unique_id\",\n        \"status\"\n      ],\n      \"properties\": {\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"error\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"integer\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"status\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"runtime error\"\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"SourceFreshnessRuntimeError(unique_id: str, error: Union[str, int, NoneType], status: dbt.contracts.results.FreshnessErrorEnum)\"\n    },\n    \"SourceFreshnessOutput\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"unique_id\",\n        \"max_loaded_at\",\n        \"snapshotted_at\",\n        \"max_loaded_at_time_ago_in_s\",\n        \"status\",\n        \"criteria\",\n        \"adapter_response\",\n        \"timing\",\n        \"thread_id\",\n        \"execution_time\"\n      ],\n      \"properties\": {\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"max_loaded_at\": {\n          \"type\": \"string\",\n          \"format\": \"date-time\"\n        },\n        \"snapshotted_at\": {\n          \"type\": \"string\",\n          \"format\": \"date-time\"\n        },\n        \"max_loaded_at_time_ago_in_s\": {\n          \"type\": \"number\"\n        },\n        \"status\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"pass\",\n            \"warn\",\n            \"error\",\n            \"runtime error\"\n          ]\n        },\n        \"criteria\": {\n          \"$ref\": \"#/definitions/FreshnessThreshold\"\n        },\n        \"adapter_response\": {\n          \"type\": \"object\"\n        },\n        \"timing\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/TimingInfo\"\n          }\n        },\n        \"thread_id\": {\n          \"type\": \"string\"\n        },\n        \"execution_time\": {\n          \"type\": \"number\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"SourceFreshnessOutput(unique_id: str, max_loaded_at: datetime.datetime, snapshotted_at: datetime.datetime, max_loaded_at_time_ago_in_s: float, status: dbt.contracts.results.FreshnessStatus, criteria: dbt.contracts.graph.unparsed.FreshnessThreshold, adapter_response: Dict[str, Any], timing: List[dbt.contracts.results.TimingInfo], thread_id: str, execution_time: float)\"\n    },\n    \"Time\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"count\": {\n          \"oneOf\": [\n            {\n              \"type\": \"integer\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"period\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\",\n              \"enum\": [\n                \"minute\",\n                \"hour\",\n                \"day\"\n              ]\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Time(count: Union[int, NoneType] = None, period: Union[dbt.contracts.graph.unparsed.TimePeriod, NoneType] = None)\"\n    },\n    \"TimingInfo\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"started_at\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\",\n              \"format\": \"date-time\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"completed_at\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\",\n              \"format\": \"date-time\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"TimingInfo(name: str, started_at: Union[datetime.datetime, NoneType] = None, completed_at: Union[datetime.datetime, NoneType] = None)\"\n    },\n    \"ExternalTable\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"location\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"file_format\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"row_format\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tbl_properties\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"partitions\": {\n          \"oneOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"$ref\": \"#/definitions/ExternalPartition\"\n              }\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"ExternalTable(_extra: Dict[str, Any] = <factory>, location: Union[str, NoneType] = None, file_format: Union[str, NoneType] = None, row_format: Union[str, NoneType] = None, tbl_properties: Union[str, NoneType] = None, partitions: Union[List[dbt.contracts.graph.unparsed.ExternalPartition], NoneType] = None)\"\n    },\n    \"ExternalPartition\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"data_type\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"ExternalPartition(_extra: Dict[str, Any] = <factory>, name: str = '', description: str = '', data_type: str = '', meta: Dict[str, Any] = <factory>)\"\n    },\n    \"SourceConfig\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"SourceConfig(_extra: Dict[str, Any] = <factory>, enabled: bool = True)\"\n    },\n    \"ParsedMacro\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"macro_sql\",\n        \"resource_type\"\n      ],\n      \"properties\": {\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"macro_sql\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"macro\"\n          ]\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/MacroDependsOn\",\n          \"default\": {\n            \"macros\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"arguments\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/MacroArgument\"\n          },\n          \"default\": []\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1663187715.386226\n        },\n        \"supported_languages\": {\n          \"oneOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\",\n                \"enum\": [\n                  \"python\",\n                  \"sql\"\n                ]\n              }\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ParsedMacro(unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, macro_sql: str, resource_type: dbt.node_types.NodeType, tags: List[str] = <factory>, depends_on: dbt.contracts.graph.parsed.MacroDependsOn = <factory>, description: str = '', meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Union[str, NoneType] = None, arguments: List[dbt.contracts.graph.unparsed.MacroArgument] = <factory>, created_at: float = <factory>, supported_languages: Union[List[dbt.node_types.ModelLanguage], NoneType] = None)\"\n    },\n    \"MacroDependsOn\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"macros\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"MacroDependsOn(macros: List[str] = <factory>)\"\n    },\n    \"MacroArgument\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"type\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"MacroArgument(name: str, type: Union[str, NoneType] = None, description: str = '')\"\n    },\n    \"ParsedDocumentation\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"block_contents\"\n      ],\n      \"properties\": {\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"block_contents\": {\n          \"type\": \"string\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ParsedDocumentation(unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, block_contents: str)\"\n    },\n    \"ParsedExposure\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"fqn\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"type\",\n        \"owner\"\n      ],\n      \"properties\": {\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"dashboard\",\n            \"notebook\",\n            \"analysis\",\n            \"ml\",\n            \"application\"\n          ]\n        },\n        \"owner\": {\n          \"$ref\": \"#/definitions/ExposureOwner\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"model\",\n            \"analysis\",\n            \"test\",\n            \"snapshot\",\n            \"operation\",\n            \"seed\",\n            \"rpc\",\n            \"sql operation\",\n            \"docs block\",\n            \"source\",\n            \"macro\",\n            \"exposure\",\n            \"metric\"\n          ],\n          \"default\": \"exposure\"\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"label\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"maturity\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\",\n              \"enum\": [\n                \"low\",\n                \"medium\",\n                \"high\"\n              ]\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/ExposureConfig\",\n          \"default\": {\n            \"enabled\": true\n          }\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"url\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1663187715.3878772\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ParsedExposure(fqn: List[str], unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, type: dbt.contracts.graph.unparsed.ExposureType, owner: dbt.contracts.graph.unparsed.ExposureOwner, resource_type: dbt.node_types.NodeType = <NodeType.Exposure: 'exposure'>, description: str = '', label: Union[str, NoneType] = None, maturity: Union[dbt.contracts.graph.unparsed.MaturityType, NoneType] = None, meta: Dict[str, Any] = <factory>, tags: List[str] = <factory>, config: dbt.contracts.graph.model_config.ExposureConfig = <factory>, unrendered_config: Dict[str, Any] = <factory>, url: Union[str, NoneType] = None, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, created_at: float = <factory>)\"\n    },\n    \"ExposureOwner\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"email\"\n      ],\n      \"properties\": {\n        \"email\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ExposureOwner(email: str, name: Union[str, NoneType] = None)\"\n    },\n    \"ExposureConfig\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"ExposureConfig(_extra: Dict[str, Any] = <factory>, enabled: bool = True)\"\n    },\n    \"ParsedMetric\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"fqn\",\n        \"unique_id\",\n        \"package_name\",\n        \"root_path\",\n        \"path\",\n        \"original_file_path\",\n        \"name\",\n        \"description\",\n        \"label\",\n        \"calculation_method\",\n        \"expression\",\n        \"filters\",\n        \"time_grains\",\n        \"dimensions\"\n      ],\n      \"properties\": {\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"root_path\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"label\": {\n          \"type\": \"string\"\n        },\n        \"calculation_method\": {\n          \"type\": \"string\"\n        },\n        \"expression\": {\n          \"type\": \"string\"\n        },\n        \"timestamp\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"filters\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/MetricFilter\"\n          }\n        },\n        \"time_grains\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"dimensions\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"window\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/MetricTime\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"model\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"model_unique_id\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"model\",\n            \"analysis\",\n            \"test\",\n            \"snapshot\",\n            \"operation\",\n            \"seed\",\n            \"rpc\",\n            \"sql operation\",\n            \"docs block\",\n            \"source\",\n            \"macro\",\n            \"exposure\",\n            \"metric\"\n          ],\n          \"default\": \"metric\"\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/MetricConfig\",\n          \"default\": {\n            \"enabled\": true\n          }\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1663187715.38939\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ParsedMetric(fqn: List[str], unique_id: str, package_name: str, root_path: str, path: str, original_file_path: str, name: str, description: str, label: str, calculation_method: str, expression: str, timestamp: Union[str, NoneType], filters: List[dbt.contracts.graph.unparsed.MetricFilter], time_grains: List[str], dimensions: List[str], window: Union[dbt.contracts.graph.unparsed.MetricTime, NoneType], model: Union[str, NoneType] = None, model_unique_id: Union[str, NoneType] = None, resource_type: dbt.node_types.NodeType = <NodeType.Metric: 'metric'>, meta: Dict[str, Any] = <factory>, tags: List[str] = <factory>, config: dbt.contracts.graph.model_config.MetricConfig = <factory>, unrendered_config: Dict[str, Any] = <factory>, sources: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.parsed.DependsOn = <factory>, refs: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, created_at: float = <factory>)\"\n    },\n    \"MetricFilter\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"field\",\n        \"operator\",\n        \"value\"\n      ],\n      \"properties\": {\n        \"field\": {\n          \"type\": \"string\"\n        },\n        \"operator\": {\n          \"type\": \"string\"\n        },\n        \"value\": {\n          \"type\": \"string\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"MetricFilter(field: str, operator: str, value: str)\"\n    },\n    \"MetricTime\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"count\": {\n          \"oneOf\": [\n            {\n              \"type\": \"integer\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"period\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\",\n              \"enum\": [\n                \"day\",\n                \"week\",\n                \"month\",\n                \"year\"\n              ]\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"MetricTime(count: Union[int, NoneType] = None, period: Union[dbt.contracts.graph.unparsed.MetricTimePeriod, NoneType] = None)\"\n    },\n    \"MetricConfig\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"MetricConfig(_extra: Dict[str, Any] = <factory>, enabled: bool = True)\"\n    }\n  },\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n  \"$id\": \"https://schemas.getdbt.com/dbt/manifest/v7.json\"\n}"
  },
  {
    "path": "schemas/dbt/manifest/v8.json",
    "content": "{\n  \"type\": \"object\",\n  \"required\": [\n    \"metadata\",\n    \"nodes\",\n    \"sources\",\n    \"macros\",\n    \"docs\",\n    \"exposures\",\n    \"metrics\",\n    \"selectors\"\n  ],\n  \"properties\": {\n    \"metadata\": {\n      \"$ref\": \"#/definitions/ManifestMetadata\",\n      \"description\": \"Metadata about the manifest\"\n    },\n    \"nodes\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"oneOf\": [\n          {\n            \"$ref\": \"#/definitions/AnalysisNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/SingularTestNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/HookNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/ModelNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/RPCNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/SqlNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/GenericTestNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/SnapshotNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/SeedNode\"\n          }\n        ]\n      },\n      \"description\": \"The nodes defined in the dbt project and its dependencies\"\n    },\n    \"sources\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/SourceDefinition\"\n      },\n      \"description\": \"The sources defined in the dbt project and its dependencies\"\n    },\n    \"macros\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/Macro\"\n      },\n      \"description\": \"The macros defined in the dbt project and its dependencies\"\n    },\n    \"docs\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/Documentation\"\n      },\n      \"description\": \"The docs defined in the dbt project and its dependencies\"\n    },\n    \"exposures\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/Exposure\"\n      },\n      \"description\": \"The exposures defined in the dbt project and its dependencies\"\n    },\n    \"metrics\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/Metric\"\n      },\n      \"description\": \"The metrics defined in the dbt project and its dependencies\"\n    },\n    \"selectors\": {\n      \"type\": \"object\",\n      \"description\": \"The selectors defined in selectors.yml\"\n    },\n    \"disabled\": {\n      \"oneOf\": [\n        {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"oneOf\": [\n                {\n                  \"$ref\": \"#/definitions/AnalysisNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/SingularTestNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/HookNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/ModelNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/RPCNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/SqlNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/GenericTestNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/SnapshotNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/SeedNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/SourceDefinition\"\n                }\n              ]\n            }\n          }\n        },\n        {\n          \"type\": \"null\"\n        }\n      ],\n      \"description\": \"A mapping of the disabled nodes in the target\"\n    },\n    \"parent_map\": {\n      \"oneOf\": [\n        {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          }\n        },\n        {\n          \"type\": \"null\"\n        }\n      ],\n      \"description\": \"A mapping from\\u00a0child nodes to their dependencies\"\n    },\n    \"child_map\": {\n      \"oneOf\": [\n        {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          }\n        },\n        {\n          \"type\": \"null\"\n        }\n      ],\n      \"description\": \"A mapping from parent nodes to their dependents\"\n    }\n  },\n  \"additionalProperties\": false,\n  \"description\": \"WritableManifest(metadata: dbt.contracts.graph.manifest.ManifestMetadata, nodes: Mapping[str, Union[dbt.contracts.graph.nodes.AnalysisNode, dbt.contracts.graph.nodes.SingularTestNode, dbt.contracts.graph.nodes.HookNode, dbt.contracts.graph.nodes.ModelNode, dbt.contracts.graph.nodes.RPCNode, dbt.contracts.graph.nodes.SqlNode, dbt.contracts.graph.nodes.GenericTestNode, dbt.contracts.graph.nodes.SnapshotNode, dbt.contracts.graph.nodes.SeedNode]], sources: Mapping[str, dbt.contracts.graph.nodes.SourceDefinition], macros: Mapping[str, dbt.contracts.graph.nodes.Macro], docs: Mapping[str, dbt.contracts.graph.nodes.Documentation], exposures: Mapping[str, dbt.contracts.graph.nodes.Exposure], metrics: Mapping[str, dbt.contracts.graph.nodes.Metric], selectors: Mapping[str, Any], disabled: Optional[Mapping[str, List[Union[dbt.contracts.graph.nodes.AnalysisNode, dbt.contracts.graph.nodes.SingularTestNode, dbt.contracts.graph.nodes.HookNode, dbt.contracts.graph.nodes.ModelNode, dbt.contracts.graph.nodes.RPCNode, dbt.contracts.graph.nodes.SqlNode, dbt.contracts.graph.nodes.GenericTestNode, dbt.contracts.graph.nodes.SnapshotNode, dbt.contracts.graph.nodes.SeedNode, dbt.contracts.graph.nodes.SourceDefinition]]]], parent_map: Optional[Dict[str, List[str]]], child_map: Optional[Dict[str, List[str]]])\",\n  \"definitions\": {\n    \"ManifestMetadata\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"dbt_schema_version\": {\n          \"type\": \"string\",\n          \"default\": \"https://schemas.getdbt.com/dbt/manifest/v8.json\"\n        },\n        \"dbt_version\": {\n          \"type\": \"string\",\n          \"default\": \"1.4.1\"\n        },\n        \"generated_at\": {\n          \"type\": \"string\",\n          \"format\": \"date-time\",\n          \"default\": \"2023-02-09T10:04:47.350768Z\"\n        },\n        \"invocation_id\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": \"f795bc66-f417-4007-af6e-f2e513d33790\"\n        },\n        \"env\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          },\n          \"default\": {}\n        },\n        \"project_id\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"description\": \"A unique identifier for the project\"\n        },\n        \"user_id\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\",\n              \"pattern\": \"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"description\": \"A unique identifier for the user\"\n        },\n        \"send_anonymous_usage_stats\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"description\": \"Whether dbt is configured to send anonymous usage statistics\"\n        },\n        \"adapter_type\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"description\": \"The type name of the adapter\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Metadata for the manifest.\"\n    },\n    \"AnalysisNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"schema\",\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"analysis\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"view\",\n            \"incremental_strategy\": null,\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"grants\": {},\n            \"packages\": [],\n            \"docs\": {\n              \"show\": true,\n              \"node_color\": null\n            },\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1675937087.353436\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"raw_code\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"language\": {\n          \"type\": \"string\",\n          \"default\": \"sql\"\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"compiled_code\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"AnalysisNode(database: Optional[str], schema: str, name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, fqn: List[str], alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.nodes.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Optional[str] = None, build_path: Optional[str] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, relation_name: Optional[str] = None, raw_code: str = '', language: str = 'sql', refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.nodes.DependsOn = <factory>, compiled_path: Optional[str] = None, compiled: bool = False, compiled_code: Optional[str] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.nodes.InjectedCTE] = <factory>, _pre_injected_sql: Optional[str] = None)\"\n    },\n    \"FileHash\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"type\": \"string\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"FileHash(name: str, checksum: str)\"\n    },\n    \"NodeConfig\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"alias\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tags\": {\n          \"oneOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"string\"\n            }\n          ],\n          \"default\": []\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"materialized\": {\n          \"type\": \"string\",\n          \"default\": \"view\"\n        },\n        \"incremental_strategy\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"persist_docs\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"post-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Hook\"\n          },\n          \"default\": []\n        },\n        \"pre-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Hook\"\n          },\n          \"default\": []\n        },\n        \"quoting\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"column_types\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"full_refresh\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"unique_key\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"on_schema_change\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": \"ignore\"\n        },\n        \"grants\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"packages\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"NodeConfig(_extra: Dict[str, Any] = <factory>, enabled: bool = True, alias: Optional[str] = None, schema: Optional[str] = None, database: Optional[str] = None, tags: Union[List[str], str] = <factory>, meta: Dict[str, Any] = <factory>, materialized: str = 'view', incremental_strategy: Optional[str] = None, persist_docs: Dict[str, Any] = <factory>, post_hook: List[dbt.contracts.graph.model_config.Hook] = <factory>, pre_hook: List[dbt.contracts.graph.model_config.Hook] = <factory>, quoting: Dict[str, Any] = <factory>, column_types: Dict[str, Any] = <factory>, full_refresh: Optional[bool] = None, unique_key: Union[str, List[str], NoneType] = None, on_schema_change: Optional[str] = 'ignore', grants: Dict[str, Any] = <factory>, packages: List[str] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>)\"\n    },\n    \"Hook\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"sql\"\n      ],\n      \"properties\": {\n        \"sql\": {\n          \"type\": \"string\"\n        },\n        \"transaction\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"index\": {\n          \"oneOf\": [\n            {\n              \"type\": \"integer\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Hook(sql: str, transaction: bool = True, index: Optional[int] = None)\"\n    },\n    \"Docs\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"show\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"node_color\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Docs(show: bool = True, node_color: Optional[str] = None)\"\n    },\n    \"ColumnInfo\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"data_type\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"quote\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"Used in all ManifestNodes and SourceDefinition\"\n    },\n    \"DependsOn\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"macros\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"nodes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"DependsOn(macros: List[str] = <factory>, nodes: List[str] = <factory>)\"\n    },\n    \"InjectedCTE\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"id\",\n        \"sql\"\n      ],\n      \"properties\": {\n        \"id\": {\n          \"type\": \"string\"\n        },\n        \"sql\": {\n          \"type\": \"string\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Used in CompiledNodes as part of ephemeral model processing\"\n    },\n    \"SingularTestNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"schema\",\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"test\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/TestConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": \"dbt_test__audit\",\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"test\",\n            \"severity\": \"ERROR\",\n            \"store_failures\": null,\n            \"where\": null,\n            \"limit\": null,\n            \"fail_calc\": \"count(*)\",\n            \"warn_if\": \"!= 0\",\n            \"error_if\": \"!= 0\"\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1675937087.355371\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"raw_code\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"language\": {\n          \"type\": \"string\",\n          \"default\": \"sql\"\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"compiled_code\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"SingularTestNode(database: Optional[str], schema: str, name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, fqn: List[str], alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.TestConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.nodes.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Optional[str] = None, build_path: Optional[str] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, relation_name: Optional[str] = None, raw_code: str = '', language: str = 'sql', refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.nodes.DependsOn = <factory>, compiled_path: Optional[str] = None, compiled: bool = False, compiled_code: Optional[str] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.nodes.InjectedCTE] = <factory>, _pre_injected_sql: Optional[str] = None)\"\n    },\n    \"TestConfig\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"alias\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": \"dbt_test__audit\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tags\": {\n          \"oneOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"string\"\n            }\n          ],\n          \"default\": []\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"materialized\": {\n          \"type\": \"string\",\n          \"default\": \"test\"\n        },\n        \"severity\": {\n          \"type\": \"string\",\n          \"pattern\": \"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$\",\n          \"default\": \"ERROR\"\n        },\n        \"store_failures\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"where\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"limit\": {\n          \"oneOf\": [\n            {\n              \"type\": \"integer\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"fail_calc\": {\n          \"type\": \"string\",\n          \"default\": \"count(*)\"\n        },\n        \"warn_if\": {\n          \"type\": \"string\",\n          \"default\": \"!= 0\"\n        },\n        \"error_if\": {\n          \"type\": \"string\",\n          \"default\": \"!= 0\"\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"TestConfig(_extra: Dict[str, Any] = <factory>, enabled: bool = True, alias: Optional[str] = None, schema: Optional[str] = 'dbt_test__audit', database: Optional[str] = None, tags: Union[List[str], str] = <factory>, meta: Dict[str, Any] = <factory>, materialized: str = 'test', severity: dbt.contracts.graph.model_config.Severity = 'ERROR', store_failures: Optional[bool] = None, where: Optional[str] = None, limit: Optional[int] = None, fail_calc: str = 'count(*)', warn_if: str = '!= 0', error_if: str = '!= 0')\"\n    },\n    \"HookNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"schema\",\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"operation\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"view\",\n            \"incremental_strategy\": null,\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"grants\": {},\n            \"packages\": [],\n            \"docs\": {\n              \"show\": true,\n              \"node_color\": null\n            },\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1675937087.356482\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"raw_code\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"language\": {\n          \"type\": \"string\",\n          \"default\": \"sql\"\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"compiled_code\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"index\": {\n          \"oneOf\": [\n            {\n              \"type\": \"integer\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"HookNode(database: Optional[str], schema: str, name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, fqn: List[str], alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.nodes.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Optional[str] = None, build_path: Optional[str] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, relation_name: Optional[str] = None, raw_code: str = '', language: str = 'sql', refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.nodes.DependsOn = <factory>, compiled_path: Optional[str] = None, compiled: bool = False, compiled_code: Optional[str] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.nodes.InjectedCTE] = <factory>, _pre_injected_sql: Optional[str] = None, index: Optional[int] = None)\"\n    },\n    \"ModelNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"schema\",\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"model\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"view\",\n            \"incremental_strategy\": null,\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"grants\": {},\n            \"packages\": [],\n            \"docs\": {\n              \"show\": true,\n              \"node_color\": null\n            },\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1675937087.357701\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"raw_code\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"language\": {\n          \"type\": \"string\",\n          \"default\": \"sql\"\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"compiled_code\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ModelNode(database: Optional[str], schema: str, name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, fqn: List[str], alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.nodes.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Optional[str] = None, build_path: Optional[str] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, relation_name: Optional[str] = None, raw_code: str = '', language: str = 'sql', refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.nodes.DependsOn = <factory>, compiled_path: Optional[str] = None, compiled: bool = False, compiled_code: Optional[str] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.nodes.InjectedCTE] = <factory>, _pre_injected_sql: Optional[str] = None)\"\n    },\n    \"RPCNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"schema\",\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"rpc\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"view\",\n            \"incremental_strategy\": null,\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"grants\": {},\n            \"packages\": [],\n            \"docs\": {\n              \"show\": true,\n              \"node_color\": null\n            },\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1675937087.358761\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"raw_code\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"language\": {\n          \"type\": \"string\",\n          \"default\": \"sql\"\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"compiled_code\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"RPCNode(database: Optional[str], schema: str, name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, fqn: List[str], alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.nodes.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Optional[str] = None, build_path: Optional[str] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, relation_name: Optional[str] = None, raw_code: str = '', language: str = 'sql', refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.nodes.DependsOn = <factory>, compiled_path: Optional[str] = None, compiled: bool = False, compiled_code: Optional[str] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.nodes.InjectedCTE] = <factory>, _pre_injected_sql: Optional[str] = None)\"\n    },\n    \"SqlNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"schema\",\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"sql operation\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"view\",\n            \"incremental_strategy\": null,\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"grants\": {},\n            \"packages\": [],\n            \"docs\": {\n              \"show\": true,\n              \"node_color\": null\n            },\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1675937087.359803\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"raw_code\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"language\": {\n          \"type\": \"string\",\n          \"default\": \"sql\"\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"compiled_code\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"SqlNode(database: Optional[str], schema: str, name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, fqn: List[str], alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.nodes.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Optional[str] = None, build_path: Optional[str] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, relation_name: Optional[str] = None, raw_code: str = '', language: str = 'sql', refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.nodes.DependsOn = <factory>, compiled_path: Optional[str] = None, compiled: bool = False, compiled_code: Optional[str] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.nodes.InjectedCTE] = <factory>, _pre_injected_sql: Optional[str] = None)\"\n    },\n    \"GenericTestNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"test_metadata\",\n        \"schema\",\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"test_metadata\": {\n          \"$ref\": \"#/definitions/TestMetadata\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"test\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/TestConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": \"dbt_test__audit\",\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"test\",\n            \"severity\": \"ERROR\",\n            \"store_failures\": null,\n            \"where\": null,\n            \"limit\": null,\n            \"fail_calc\": \"count(*)\",\n            \"warn_if\": \"!= 0\",\n            \"error_if\": \"!= 0\"\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1675937087.361009\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"raw_code\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"language\": {\n          \"type\": \"string\",\n          \"default\": \"sql\"\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"compiled_code\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"column_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"file_key_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"GenericTestNode(test_metadata: dbt.contracts.graph.nodes.TestMetadata, database: Optional[str], schema: str, name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, fqn: List[str], alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.TestConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.nodes.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Optional[str] = None, build_path: Optional[str] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, relation_name: Optional[str] = None, raw_code: str = '', language: str = 'sql', refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.nodes.DependsOn = <factory>, compiled_path: Optional[str] = None, compiled: bool = False, compiled_code: Optional[str] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.nodes.InjectedCTE] = <factory>, _pre_injected_sql: Optional[str] = None, column_name: Optional[str] = None, file_key_name: Optional[str] = None)\"\n    },\n    \"TestMetadata\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"kwargs\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"namespace\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"TestMetadata(name: str, kwargs: Dict[str, Any] = <factory>, namespace: Optional[str] = None)\"\n    },\n    \"SnapshotNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"schema\",\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"alias\",\n        \"checksum\",\n        \"config\"\n      ],\n      \"properties\": {\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"snapshot\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/SnapshotConfig\"\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1675937087.364386\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"raw_code\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"language\": {\n          \"type\": \"string\",\n          \"default\": \"sql\"\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"compiled_code\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"SnapshotNode(database: Optional[str], schema: str, name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, fqn: List[str], alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.SnapshotConfig, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.nodes.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Optional[str] = None, build_path: Optional[str] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, relation_name: Optional[str] = None, raw_code: str = '', language: str = 'sql', refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.nodes.DependsOn = <factory>, compiled_path: Optional[str] = None, compiled: bool = False, compiled_code: Optional[str] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.nodes.InjectedCTE] = <factory>, _pre_injected_sql: Optional[str] = None)\"\n    },\n    \"SnapshotConfig\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"alias\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tags\": {\n          \"oneOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"string\"\n            }\n          ],\n          \"default\": []\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"materialized\": {\n          \"type\": \"string\",\n          \"default\": \"snapshot\"\n        },\n        \"incremental_strategy\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"persist_docs\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"post-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Hook\"\n          },\n          \"default\": []\n        },\n        \"pre-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Hook\"\n          },\n          \"default\": []\n        },\n        \"quoting\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"column_types\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"full_refresh\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"unique_key\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"on_schema_change\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": \"ignore\"\n        },\n        \"grants\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"packages\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"strategy\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"target_schema\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"target_database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"updated_at\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"check_cols\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"SnapshotConfig(_extra: Dict[str, Any] = <factory>, enabled: bool = True, alias: Optional[str] = None, schema: Optional[str] = None, database: Optional[str] = None, tags: Union[List[str], str] = <factory>, meta: Dict[str, Any] = <factory>, materialized: str = 'snapshot', incremental_strategy: Optional[str] = None, persist_docs: Dict[str, Any] = <factory>, post_hook: List[dbt.contracts.graph.model_config.Hook] = <factory>, pre_hook: List[dbt.contracts.graph.model_config.Hook] = <factory>, quoting: Dict[str, Any] = <factory>, column_types: Dict[str, Any] = <factory>, full_refresh: Optional[bool] = None, unique_key: Optional[str] = None, on_schema_change: Optional[str] = 'ignore', grants: Dict[str, Any] = <factory>, packages: List[str] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, strategy: Optional[str] = None, target_schema: Optional[str] = None, target_database: Optional[str] = None, updated_at: Optional[str] = None, check_cols: Union[str, List[str], NoneType] = None)\"\n    },\n    \"SeedNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"schema\",\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"seed\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/SeedConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"materialized\": \"seed\",\n            \"incremental_strategy\": null,\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"grants\": {},\n            \"packages\": [],\n            \"docs\": {\n              \"show\": true,\n              \"node_color\": null\n            },\n            \"quote_columns\": null,\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1675937087.366245\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"raw_code\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"root_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/MacroDependsOn\",\n          \"default\": {\n            \"macros\": []\n          }\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"SeedNode(database: Optional[str], schema: str, name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, fqn: List[str], alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.SeedConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.nodes.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Optional[str] = None, build_path: Optional[str] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, relation_name: Optional[str] = None, raw_code: str = '', root_path: Optional[str] = None, depends_on: dbt.contracts.graph.nodes.MacroDependsOn = <factory>)\"\n    },\n    \"SeedConfig\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"alias\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tags\": {\n          \"oneOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"string\"\n            }\n          ],\n          \"default\": []\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"materialized\": {\n          \"type\": \"string\",\n          \"default\": \"seed\"\n        },\n        \"incremental_strategy\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"persist_docs\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"post-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Hook\"\n          },\n          \"default\": []\n        },\n        \"pre-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Hook\"\n          },\n          \"default\": []\n        },\n        \"quoting\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"column_types\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"full_refresh\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"unique_key\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"on_schema_change\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": \"ignore\"\n        },\n        \"grants\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"packages\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"quote_columns\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"SeedConfig(_extra: Dict[str, Any] = <factory>, enabled: bool = True, alias: Optional[str] = None, schema: Optional[str] = None, database: Optional[str] = None, tags: Union[List[str], str] = <factory>, meta: Dict[str, Any] = <factory>, materialized: str = 'seed', incremental_strategy: Optional[str] = None, persist_docs: Dict[str, Any] = <factory>, post_hook: List[dbt.contracts.graph.model_config.Hook] = <factory>, pre_hook: List[dbt.contracts.graph.model_config.Hook] = <factory>, quoting: Dict[str, Any] = <factory>, column_types: Dict[str, Any] = <factory>, full_refresh: Optional[bool] = None, unique_key: Union[str, List[str], NoneType] = None, on_schema_change: Optional[str] = 'ignore', grants: Dict[str, Any] = <factory>, packages: List[str] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, quote_columns: Optional[bool] = None)\"\n    },\n    \"MacroDependsOn\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"macros\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Used only in the Macro class\"\n    },\n    \"SourceDefinition\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"schema\",\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"source_name\",\n        \"source_description\",\n        \"loader\",\n        \"identifier\"\n      ],\n      \"properties\": {\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"source\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"source_name\": {\n          \"type\": \"string\"\n        },\n        \"source_description\": {\n          \"type\": \"string\"\n        },\n        \"loader\": {\n          \"type\": \"string\"\n        },\n        \"identifier\": {\n          \"type\": \"string\"\n        },\n        \"quoting\": {\n          \"$ref\": \"#/definitions/Quoting\",\n          \"default\": {\n            \"database\": null,\n            \"schema\": null,\n            \"identifier\": null,\n            \"column\": null\n          }\n        },\n        \"loaded_at_field\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"freshness\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/FreshnessThreshold\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"external\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/ExternalTable\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"source_meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/SourceConfig\",\n          \"default\": {\n            \"enabled\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1675937087.368067\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"SourceDefinition(database: Optional[str], schema: str, name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, fqn: List[str], source_name: str, source_description: str, loader: str, identifier: str, _event_status: Dict[str, Any] = <factory>, quoting: dbt.contracts.graph.unparsed.Quoting = <factory>, loaded_at_field: Optional[str] = None, freshness: Optional[dbt.contracts.graph.unparsed.FreshnessThreshold] = None, external: Optional[dbt.contracts.graph.unparsed.ExternalTable] = None, description: str = '', columns: Dict[str, dbt.contracts.graph.nodes.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, source_meta: Dict[str, Any] = <factory>, tags: List[str] = <factory>, config: dbt.contracts.graph.model_config.SourceConfig = <factory>, patch_path: Optional[str] = None, unrendered_config: Dict[str, Any] = <factory>, relation_name: Optional[str] = None, created_at: float = <factory>)\"\n    },\n    \"Quoting\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"identifier\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"column\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Quoting(database: Optional[bool] = None, schema: Optional[bool] = None, identifier: Optional[bool] = None, column: Optional[bool] = None)\"\n    },\n    \"FreshnessThreshold\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"warn_after\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/Time\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": {\n            \"count\": null,\n            \"period\": null\n          }\n        },\n        \"error_after\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/Time\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": {\n            \"count\": null,\n            \"period\": null\n          }\n        },\n        \"filter\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"FreshnessThreshold(warn_after: Optional[dbt.contracts.graph.unparsed.Time] = <factory>, error_after: Optional[dbt.contracts.graph.unparsed.Time] = <factory>, filter: Optional[str] = None)\"\n    },\n    \"FreshnessMetadata\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"dbt_schema_version\": {\n          \"type\": \"string\",\n          \"default\": \"https://schemas.getdbt.com/dbt/sources/v3.json\"\n        },\n        \"dbt_version\": {\n          \"type\": \"string\",\n          \"default\": \"1.4.1\"\n        },\n        \"generated_at\": {\n          \"type\": \"string\",\n          \"format\": \"date-time\",\n          \"default\": \"2023-02-09T10:04:47.347023Z\"\n        },\n        \"invocation_id\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": \"f795bc66-f417-4007-af6e-f2e513d33790\"\n        },\n        \"env\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          },\n          \"default\": {}\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"FreshnessMetadata(dbt_schema_version: str = <factory>, dbt_version: str = '1.4.1', generated_at: datetime.datetime = <factory>, invocation_id: Optional[str] = <factory>, env: Dict[str, str] = <factory>)\"\n    },\n    \"SourceFreshnessRuntimeError\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"unique_id\",\n        \"status\"\n      ],\n      \"properties\": {\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"error\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"integer\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"status\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"runtime error\"\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"SourceFreshnessRuntimeError(unique_id: str, error: Union[str, int, NoneType], status: dbt.contracts.results.FreshnessErrorEnum)\"\n    },\n    \"SourceFreshnessOutput\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"unique_id\",\n        \"max_loaded_at\",\n        \"snapshotted_at\",\n        \"max_loaded_at_time_ago_in_s\",\n        \"status\",\n        \"criteria\",\n        \"adapter_response\",\n        \"timing\",\n        \"thread_id\",\n        \"execution_time\"\n      ],\n      \"properties\": {\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"max_loaded_at\": {\n          \"type\": \"string\",\n          \"format\": \"date-time\"\n        },\n        \"snapshotted_at\": {\n          \"type\": \"string\",\n          \"format\": \"date-time\"\n        },\n        \"max_loaded_at_time_ago_in_s\": {\n          \"type\": \"number\"\n        },\n        \"status\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"pass\",\n            \"warn\",\n            \"error\",\n            \"runtime error\"\n          ]\n        },\n        \"criteria\": {\n          \"$ref\": \"#/definitions/FreshnessThreshold\"\n        },\n        \"adapter_response\": {\n          \"type\": \"object\"\n        },\n        \"timing\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/TimingInfo\"\n          }\n        },\n        \"thread_id\": {\n          \"type\": \"string\"\n        },\n        \"execution_time\": {\n          \"type\": \"number\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"SourceFreshnessOutput(unique_id: str, max_loaded_at: datetime.datetime, snapshotted_at: datetime.datetime, max_loaded_at_time_ago_in_s: float, status: dbt.contracts.results.FreshnessStatus, criteria: dbt.contracts.graph.unparsed.FreshnessThreshold, adapter_response: Dict[str, Any], timing: List[dbt.contracts.results.TimingInfo], thread_id: str, execution_time: float)\"\n    },\n    \"Time\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"count\": {\n          \"oneOf\": [\n            {\n              \"type\": \"integer\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"period\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\",\n              \"enum\": [\n                \"minute\",\n                \"hour\",\n                \"day\"\n              ]\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Time(count: Optional[int] = None, period: Optional[dbt.contracts.graph.unparsed.TimePeriod] = None)\"\n    },\n    \"TimingInfo\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"started_at\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\",\n              \"format\": \"date-time\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"completed_at\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\",\n              \"format\": \"date-time\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"TimingInfo(name: str, started_at: Optional[datetime.datetime] = None, completed_at: Optional[datetime.datetime] = None)\"\n    },\n    \"ExternalTable\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"location\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"file_format\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"row_format\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tbl_properties\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"partitions\": {\n          \"oneOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"$ref\": \"#/definitions/ExternalPartition\"\n              }\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"ExternalTable(_extra: Dict[str, Any] = <factory>, location: Optional[str] = None, file_format: Optional[str] = None, row_format: Optional[str] = None, tbl_properties: Optional[str] = None, partitions: Union[List[str], List[dbt.contracts.graph.unparsed.ExternalPartition], NoneType] = None)\"\n    },\n    \"ExternalPartition\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"data_type\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"ExternalPartition(_extra: Dict[str, Any] = <factory>, name: str = '', description: str = '', data_type: str = '', meta: Dict[str, Any] = <factory>)\"\n    },\n    \"SourceConfig\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"SourceConfig(_extra: Dict[str, Any] = <factory>, enabled: bool = True)\"\n    },\n    \"Macro\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"macro_sql\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"macro\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"macro_sql\": {\n          \"type\": \"string\"\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/MacroDependsOn\",\n          \"default\": {\n            \"macros\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"arguments\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/MacroArgument\"\n          },\n          \"default\": []\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1675937087.368656\n        },\n        \"supported_languages\": {\n          \"oneOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\",\n                \"enum\": [\n                  \"python\",\n                  \"sql\"\n                ]\n              }\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Macro(name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, macro_sql: str, depends_on: dbt.contracts.graph.nodes.MacroDependsOn = <factory>, description: str = '', meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Optional[str] = None, arguments: List[dbt.contracts.graph.unparsed.MacroArgument] = <factory>, created_at: float = <factory>, supported_languages: Optional[List[dbt.node_types.ModelLanguage]] = None)\"\n    },\n    \"MacroArgument\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"type\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"MacroArgument(name: str, type: Optional[str] = None, description: str = '')\"\n    },\n    \"Documentation\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"block_contents\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"doc\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"block_contents\": {\n          \"type\": \"string\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Documentation(name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, block_contents: str)\"\n    },\n    \"Exposure\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"type\",\n        \"owner\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"exposure\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"dashboard\",\n            \"notebook\",\n            \"analysis\",\n            \"ml\",\n            \"application\"\n          ]\n        },\n        \"owner\": {\n          \"$ref\": \"#/definitions/ExposureOwner\"\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"label\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"maturity\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\",\n              \"enum\": [\n                \"low\",\n                \"medium\",\n                \"high\"\n              ]\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/ExposureConfig\",\n          \"default\": {\n            \"enabled\": true\n          }\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"url\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1675937087.369866\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Exposure(name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, fqn: List[str], type: dbt.contracts.graph.unparsed.ExposureType, owner: dbt.contracts.graph.unparsed.ExposureOwner, description: str = '', label: Optional[str] = None, maturity: Optional[dbt.contracts.graph.unparsed.MaturityType] = None, meta: Dict[str, Any] = <factory>, tags: List[str] = <factory>, config: dbt.contracts.graph.model_config.ExposureConfig = <factory>, unrendered_config: Dict[str, Any] = <factory>, url: Optional[str] = None, depends_on: dbt.contracts.graph.nodes.DependsOn = <factory>, refs: List[List[str]] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, created_at: float = <factory>)\"\n    },\n    \"ExposureOwner\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"email\"\n      ],\n      \"properties\": {\n        \"email\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ExposureOwner(email: str, name: Optional[str] = None)\"\n    },\n    \"ExposureConfig\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"ExposureConfig(_extra: Dict[str, Any] = <factory>, enabled: bool = True)\"\n    },\n    \"Metric\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"description\",\n        \"label\",\n        \"calculation_method\",\n        \"expression\",\n        \"filters\",\n        \"time_grains\",\n        \"dimensions\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"metric\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"label\": {\n          \"type\": \"string\"\n        },\n        \"calculation_method\": {\n          \"type\": \"string\"\n        },\n        \"expression\": {\n          \"type\": \"string\"\n        },\n        \"filters\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/MetricFilter\"\n          }\n        },\n        \"time_grains\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"dimensions\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"timestamp\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"window\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/MetricTime\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"model\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"model_unique_id\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/MetricConfig\",\n          \"default\": {\n            \"enabled\": true\n          }\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1675937087.371092\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Metric(name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, fqn: List[str], description: str, label: str, calculation_method: str, expression: str, filters: List[dbt.contracts.graph.unparsed.MetricFilter], time_grains: List[str], dimensions: List[str], timestamp: Optional[str] = None, window: Optional[dbt.contracts.graph.unparsed.MetricTime] = None, model: Optional[str] = None, model_unique_id: Optional[str] = None, meta: Dict[str, Any] = <factory>, tags: List[str] = <factory>, config: dbt.contracts.graph.model_config.MetricConfig = <factory>, unrendered_config: Dict[str, Any] = <factory>, sources: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.nodes.DependsOn = <factory>, refs: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, created_at: float = <factory>)\"\n    },\n    \"MetricFilter\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"field\",\n        \"operator\",\n        \"value\"\n      ],\n      \"properties\": {\n        \"field\": {\n          \"type\": \"string\"\n        },\n        \"operator\": {\n          \"type\": \"string\"\n        },\n        \"value\": {\n          \"type\": \"string\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"MetricFilter(field: str, operator: str, value: str)\"\n    },\n    \"MetricTime\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"count\": {\n          \"oneOf\": [\n            {\n              \"type\": \"integer\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"period\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\",\n              \"enum\": [\n                \"day\",\n                \"week\",\n                \"month\",\n                \"year\"\n              ]\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"MetricTime(count: Optional[int] = None, period: Optional[dbt.contracts.graph.unparsed.MetricTimePeriod] = None)\"\n    },\n    \"MetricConfig\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"MetricConfig(_extra: Dict[str, Any] = <factory>, enabled: bool = True)\"\n    }\n  },\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n  \"$id\": \"https://schemas.getdbt.com/dbt/manifest/v8.json\"\n}"
  },
  {
    "path": "schemas/dbt/manifest/v9.json",
    "content": "{\n  \"type\": \"object\",\n  \"required\": [\n    \"metadata\",\n    \"nodes\",\n    \"sources\",\n    \"macros\",\n    \"docs\",\n    \"exposures\",\n    \"metrics\",\n    \"groups\",\n    \"selectors\"\n  ],\n  \"properties\": {\n    \"metadata\": {\n      \"$ref\": \"#/definitions/ManifestMetadata\",\n      \"description\": \"Metadata about the manifest\"\n    },\n    \"nodes\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"oneOf\": [\n          {\n            \"$ref\": \"#/definitions/AnalysisNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/SingularTestNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/HookNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/ModelNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/RPCNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/SqlNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/GenericTestNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/SnapshotNode\"\n          },\n          {\n            \"$ref\": \"#/definitions/SeedNode\"\n          }\n        ]\n      },\n      \"description\": \"The nodes defined in the dbt project and its dependencies\"\n    },\n    \"sources\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/SourceDefinition\"\n      },\n      \"description\": \"The sources defined in the dbt project and its dependencies\"\n    },\n    \"macros\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/Macro\"\n      },\n      \"description\": \"The macros defined in the dbt project and its dependencies\"\n    },\n    \"docs\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/Documentation\"\n      },\n      \"description\": \"The docs defined in the dbt project and its dependencies\"\n    },\n    \"exposures\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/Exposure\"\n      },\n      \"description\": \"The exposures defined in the dbt project and its dependencies\"\n    },\n    \"metrics\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/Metric\"\n      },\n      \"description\": \"The metrics defined in the dbt project and its dependencies\"\n    },\n    \"groups\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/Group\"\n      },\n      \"description\": \"The groups defined in the dbt project\"\n    },\n    \"selectors\": {\n      \"type\": \"object\",\n      \"description\": \"The selectors defined in selectors.yml\"\n    },\n    \"disabled\": {\n      \"oneOf\": [\n        {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"oneOf\": [\n                {\n                  \"$ref\": \"#/definitions/AnalysisNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/SingularTestNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/HookNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/ModelNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/RPCNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/SqlNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/GenericTestNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/SnapshotNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/SeedNode\"\n                },\n                {\n                  \"$ref\": \"#/definitions/SourceDefinition\"\n                },\n                {\n                  \"$ref\": \"#/definitions/Exposure\"\n                },\n                {\n                  \"$ref\": \"#/definitions/Metric\"\n                }\n              ]\n            }\n          }\n        },\n        {\n          \"type\": \"null\"\n        }\n      ],\n      \"description\": \"A mapping of the disabled nodes in the target\"\n    },\n    \"parent_map\": {\n      \"oneOf\": [\n        {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          }\n        },\n        {\n          \"type\": \"null\"\n        }\n      ],\n      \"description\": \"A mapping from\\u00a0child nodes to their dependencies\"\n    },\n    \"child_map\": {\n      \"oneOf\": [\n        {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          }\n        },\n        {\n          \"type\": \"null\"\n        }\n      ],\n      \"description\": \"A mapping from parent nodes to their dependents\"\n    },\n    \"group_map\": {\n      \"oneOf\": [\n        {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          }\n        },\n        {\n          \"type\": \"null\"\n        }\n      ],\n      \"description\": \"A mapping from group names to their nodes\"\n    }\n  },\n  \"additionalProperties\": false,\n  \"description\": \"WritableManifest(metadata: dbt.contracts.graph.manifest.ManifestMetadata, nodes: Mapping[str, Union[dbt.contracts.graph.nodes.AnalysisNode, dbt.contracts.graph.nodes.SingularTestNode, dbt.contracts.graph.nodes.HookNode, dbt.contracts.graph.nodes.ModelNode, dbt.contracts.graph.nodes.RPCNode, dbt.contracts.graph.nodes.SqlNode, dbt.contracts.graph.nodes.GenericTestNode, dbt.contracts.graph.nodes.SnapshotNode, dbt.contracts.graph.nodes.SeedNode]], sources: Mapping[str, dbt.contracts.graph.nodes.SourceDefinition], macros: Mapping[str, dbt.contracts.graph.nodes.Macro], docs: Mapping[str, dbt.contracts.graph.nodes.Documentation], exposures: Mapping[str, dbt.contracts.graph.nodes.Exposure], metrics: Mapping[str, dbt.contracts.graph.nodes.Metric], groups: Mapping[str, dbt.contracts.graph.nodes.Group], selectors: Mapping[str, Any], disabled: Optional[Mapping[str, List[Union[dbt.contracts.graph.nodes.AnalysisNode, dbt.contracts.graph.nodes.SingularTestNode, dbt.contracts.graph.nodes.HookNode, dbt.contracts.graph.nodes.ModelNode, dbt.contracts.graph.nodes.RPCNode, dbt.contracts.graph.nodes.SqlNode, dbt.contracts.graph.nodes.GenericTestNode, dbt.contracts.graph.nodes.SnapshotNode, dbt.contracts.graph.nodes.SeedNode, dbt.contracts.graph.nodes.SourceDefinition, dbt.contracts.graph.nodes.Exposure, dbt.contracts.graph.nodes.Metric]]]], parent_map: Optional[Dict[str, List[str]]], child_map: Optional[Dict[str, List[str]]], group_map: Optional[Dict[str, List[str]]])\",\n  \"definitions\": {\n    \"ManifestMetadata\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"dbt_schema_version\": {\n          \"type\": \"string\",\n          \"default\": \"https://schemas.getdbt.com/dbt/manifest/v9.json\"\n        },\n        \"dbt_version\": {\n          \"type\": \"string\",\n          \"default\": \"1.5.0b5\"\n        },\n        \"generated_at\": {\n          \"type\": \"string\",\n          \"format\": \"date-time\",\n          \"default\": \"2023-04-12T03:35:01.188035Z\"\n        },\n        \"invocation_id\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": \"8aa1596d-f52f-40bc-ad4b-f5e48fc7e6c2\"\n        },\n        \"env\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          },\n          \"default\": {}\n        },\n        \"project_id\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"description\": \"A unique identifier for the project\"\n        },\n        \"user_id\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\",\n              \"pattern\": \"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"description\": \"A unique identifier for the user\"\n        },\n        \"send_anonymous_usage_stats\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"description\": \"Whether dbt is configured to send anonymous usage statistics\"\n        },\n        \"adapter_type\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"description\": \"The type name of the adapter\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Metadata for the manifest.\"\n    },\n    \"AnalysisNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"schema\",\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"analysis\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"group\": null,\n            \"materialized\": \"view\",\n            \"incremental_strategy\": null,\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"grants\": {},\n            \"packages\": [],\n            \"docs\": {\n              \"show\": true,\n              \"node_color\": null\n            },\n            \"contract\": {\n              \"enforced\": false\n            },\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"group\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1681270501.189703\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"raw_code\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"language\": {\n          \"type\": \"string\",\n          \"default\": \"sql\"\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/RefArgs\"\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"compiled_code\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"contract\": {\n          \"$ref\": \"#/definitions/Contract\",\n          \"default\": {\n            \"enforced\": false,\n            \"checksum\": null\n          }\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"AnalysisNode(database: Optional[str], schema: str, name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, fqn: List[str], alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.nodes.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, group: Optional[str] = None, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Optional[str] = None, build_path: Optional[str] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, relation_name: Optional[str] = None, raw_code: str = '', language: str = 'sql', refs: List[dbt.contracts.graph.nodes.RefArgs] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.nodes.DependsOn = <factory>, compiled_path: Optional[str] = None, compiled: bool = False, compiled_code: Optional[str] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.nodes.InjectedCTE] = <factory>, _pre_injected_sql: Optional[str] = None, contract: dbt.contracts.graph.nodes.Contract = <factory>)\"\n    },\n    \"FileHash\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"type\": \"string\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"FileHash(name: str, checksum: str)\"\n    },\n    \"NodeConfig\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"alias\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tags\": {\n          \"oneOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"string\"\n            }\n          ],\n          \"default\": []\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"group\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"materialized\": {\n          \"type\": \"string\",\n          \"default\": \"view\"\n        },\n        \"incremental_strategy\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"persist_docs\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"post-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Hook\"\n          },\n          \"default\": []\n        },\n        \"pre-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Hook\"\n          },\n          \"default\": []\n        },\n        \"quoting\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"column_types\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"full_refresh\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"unique_key\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"on_schema_change\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": \"ignore\"\n        },\n        \"grants\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"packages\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"contract\": {\n          \"$ref\": \"#/definitions/ContractConfig\",\n          \"default\": {\n            \"enforced\": false\n          }\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"NodeConfig(_extra: Dict[str, Any] = <factory>, enabled: bool = True, alias: Optional[str] = None, schema: Optional[str] = None, database: Optional[str] = None, tags: Union[List[str], str] = <factory>, meta: Dict[str, Any] = <factory>, group: Optional[str] = None, materialized: str = 'view', incremental_strategy: Optional[str] = None, persist_docs: Dict[str, Any] = <factory>, post_hook: List[dbt.contracts.graph.model_config.Hook] = <factory>, pre_hook: List[dbt.contracts.graph.model_config.Hook] = <factory>, quoting: Dict[str, Any] = <factory>, column_types: Dict[str, Any] = <factory>, full_refresh: Optional[bool] = None, unique_key: Union[str, List[str], NoneType] = None, on_schema_change: Optional[str] = 'ignore', grants: Dict[str, Any] = <factory>, packages: List[str] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, contract: dbt.contracts.graph.model_config.ContractConfig = <factory>)\"\n    },\n    \"Hook\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"sql\"\n      ],\n      \"properties\": {\n        \"sql\": {\n          \"type\": \"string\"\n        },\n        \"transaction\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"index\": {\n          \"oneOf\": [\n            {\n              \"type\": \"integer\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Hook(sql: str, transaction: bool = True, index: Optional[int] = None)\"\n    },\n    \"Docs\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"show\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"node_color\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Docs(show: bool = True, node_color: Optional[str] = None)\"\n    },\n    \"ContractConfig\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"enforced\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ContractConfig(enforced: bool = False)\"\n    },\n    \"ColumnInfo\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"data_type\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"constraints\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/ColumnLevelConstraint\"\n          },\n          \"default\": []\n        },\n        \"quote\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"Used in all ManifestNodes and SourceDefinition\"\n    },\n    \"ColumnLevelConstraint\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"type\"\n      ],\n      \"properties\": {\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"check\",\n            \"not_null\",\n            \"unique\",\n            \"primary_key\",\n            \"foreign_key\",\n            \"custom\"\n          ]\n        },\n        \"name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"expression\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"warn_unenforced\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"warn_unsupported\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ColumnLevelConstraint(type: dbt.contracts.graph.nodes.ConstraintType, name: Optional[str] = None, expression: Optional[str] = None, warn_unenforced: bool = True, warn_unsupported: bool = True)\"\n    },\n    \"RefArgs\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"package\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"version\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"number\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"RefArgs(name: str, package: Optional[str] = None, version: Union[str, float, NoneType] = None)\"\n    },\n    \"DependsOn\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"macros\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"nodes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"DependsOn(macros: List[str] = <factory>, nodes: List[str] = <factory>)\"\n    },\n    \"InjectedCTE\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"id\",\n        \"sql\"\n      ],\n      \"properties\": {\n        \"id\": {\n          \"type\": \"string\"\n        },\n        \"sql\": {\n          \"type\": \"string\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Used in CompiledNodes as part of ephemeral model processing\"\n    },\n    \"Contract\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"enforced\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"checksum\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Contract(enforced: bool = False, checksum: Optional[str] = None)\"\n    },\n    \"SingularTestNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"schema\",\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"test\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/TestConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": \"dbt_test__audit\",\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"group\": null,\n            \"materialized\": \"test\",\n            \"severity\": \"ERROR\",\n            \"store_failures\": null,\n            \"where\": null,\n            \"limit\": null,\n            \"fail_calc\": \"count(*)\",\n            \"warn_if\": \"!= 0\",\n            \"error_if\": \"!= 0\"\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"group\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1681270501.19095\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"raw_code\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"language\": {\n          \"type\": \"string\",\n          \"default\": \"sql\"\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/RefArgs\"\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"compiled_code\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"contract\": {\n          \"$ref\": \"#/definitions/Contract\",\n          \"default\": {\n            \"enforced\": false,\n            \"checksum\": null\n          }\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"SingularTestNode(database: Optional[str], schema: str, name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, fqn: List[str], alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.TestConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.nodes.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, group: Optional[str] = None, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Optional[str] = None, build_path: Optional[str] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, relation_name: Optional[str] = None, raw_code: str = '', language: str = 'sql', refs: List[dbt.contracts.graph.nodes.RefArgs] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.nodes.DependsOn = <factory>, compiled_path: Optional[str] = None, compiled: bool = False, compiled_code: Optional[str] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.nodes.InjectedCTE] = <factory>, _pre_injected_sql: Optional[str] = None, contract: dbt.contracts.graph.nodes.Contract = <factory>)\"\n    },\n    \"TestConfig\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"alias\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": \"dbt_test__audit\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tags\": {\n          \"oneOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"string\"\n            }\n          ],\n          \"default\": []\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"group\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"materialized\": {\n          \"type\": \"string\",\n          \"default\": \"test\"\n        },\n        \"severity\": {\n          \"type\": \"string\",\n          \"pattern\": \"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$\",\n          \"default\": \"ERROR\"\n        },\n        \"store_failures\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"where\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"limit\": {\n          \"oneOf\": [\n            {\n              \"type\": \"integer\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"fail_calc\": {\n          \"type\": \"string\",\n          \"default\": \"count(*)\"\n        },\n        \"warn_if\": {\n          \"type\": \"string\",\n          \"default\": \"!= 0\"\n        },\n        \"error_if\": {\n          \"type\": \"string\",\n          \"default\": \"!= 0\"\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"TestConfig(_extra: Dict[str, Any] = <factory>, enabled: bool = True, alias: Optional[str] = None, schema: Optional[str] = 'dbt_test__audit', database: Optional[str] = None, tags: Union[List[str], str] = <factory>, meta: Dict[str, Any] = <factory>, group: Optional[str] = None, materialized: str = 'test', severity: dbt.contracts.graph.model_config.Severity = 'ERROR', store_failures: Optional[bool] = None, where: Optional[str] = None, limit: Optional[int] = None, fail_calc: str = 'count(*)', warn_if: str = '!= 0', error_if: str = '!= 0')\"\n    },\n    \"HookNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"schema\",\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"operation\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"group\": null,\n            \"materialized\": \"view\",\n            \"incremental_strategy\": null,\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"grants\": {},\n            \"packages\": [],\n            \"docs\": {\n              \"show\": true,\n              \"node_color\": null\n            },\n            \"contract\": {\n              \"enforced\": false\n            },\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"group\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1681270501.191555\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"raw_code\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"language\": {\n          \"type\": \"string\",\n          \"default\": \"sql\"\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/RefArgs\"\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"compiled_code\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"contract\": {\n          \"$ref\": \"#/definitions/Contract\",\n          \"default\": {\n            \"enforced\": false,\n            \"checksum\": null\n          }\n        },\n        \"index\": {\n          \"oneOf\": [\n            {\n              \"type\": \"integer\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"HookNode(database: Optional[str], schema: str, name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, fqn: List[str], alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.nodes.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, group: Optional[str] = None, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Optional[str] = None, build_path: Optional[str] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, relation_name: Optional[str] = None, raw_code: str = '', language: str = 'sql', refs: List[dbt.contracts.graph.nodes.RefArgs] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.nodes.DependsOn = <factory>, compiled_path: Optional[str] = None, compiled: bool = False, compiled_code: Optional[str] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.nodes.InjectedCTE] = <factory>, _pre_injected_sql: Optional[str] = None, contract: dbt.contracts.graph.nodes.Contract = <factory>, index: Optional[int] = None)\"\n    },\n    \"ModelNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"schema\",\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"model\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"group\": null,\n            \"materialized\": \"view\",\n            \"incremental_strategy\": null,\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"grants\": {},\n            \"packages\": [],\n            \"docs\": {\n              \"show\": true,\n              \"node_color\": null\n            },\n            \"contract\": {\n              \"enforced\": false\n            },\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"group\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1681270501.192162\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"raw_code\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"language\": {\n          \"type\": \"string\",\n          \"default\": \"sql\"\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/RefArgs\"\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"compiled_code\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"contract\": {\n          \"$ref\": \"#/definitions/Contract\",\n          \"default\": {\n            \"enforced\": false,\n            \"checksum\": null\n          }\n        },\n        \"access\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"protected\",\n            \"private\",\n            \"public\"\n          ],\n          \"default\": \"protected\"\n        },\n        \"constraints\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/ModelLevelConstraint\"\n          },\n          \"default\": []\n        },\n        \"version\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"number\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"latest_version\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"number\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ModelNode(database: Optional[str], schema: str, name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, fqn: List[str], alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.nodes.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, group: Optional[str] = None, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Optional[str] = None, build_path: Optional[str] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, relation_name: Optional[str] = None, raw_code: str = '', language: str = 'sql', refs: List[dbt.contracts.graph.nodes.RefArgs] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.nodes.DependsOn = <factory>, compiled_path: Optional[str] = None, compiled: bool = False, compiled_code: Optional[str] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.nodes.InjectedCTE] = <factory>, _pre_injected_sql: Optional[str] = None, contract: dbt.contracts.graph.nodes.Contract = <factory>, access: dbt.node_types.AccessType = <AccessType.Protected: 'protected'>, constraints: List[dbt.contracts.graph.nodes.ModelLevelConstraint] = <factory>, version: Union[str, float, NoneType] = None, latest_version: Union[str, float, NoneType] = None)\"\n    },\n    \"ModelLevelConstraint\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"type\"\n      ],\n      \"properties\": {\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"check\",\n            \"not_null\",\n            \"unique\",\n            \"primary_key\",\n            \"foreign_key\",\n            \"custom\"\n          ]\n        },\n        \"name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"expression\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"warn_unenforced\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"warn_unsupported\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"columns\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"ModelLevelConstraint(type: dbt.contracts.graph.nodes.ConstraintType, name: Optional[str] = None, expression: Optional[str] = None, warn_unenforced: bool = True, warn_unsupported: bool = True, columns: List[str] = <factory>)\"\n    },\n    \"RPCNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"schema\",\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"rpc\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"group\": null,\n            \"materialized\": \"view\",\n            \"incremental_strategy\": null,\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"grants\": {},\n            \"packages\": [],\n            \"docs\": {\n              \"show\": true,\n              \"node_color\": null\n            },\n            \"contract\": {\n              \"enforced\": false\n            },\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"group\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1681270501.192949\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"raw_code\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"language\": {\n          \"type\": \"string\",\n          \"default\": \"sql\"\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/RefArgs\"\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"compiled_code\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"contract\": {\n          \"$ref\": \"#/definitions/Contract\",\n          \"default\": {\n            \"enforced\": false,\n            \"checksum\": null\n          }\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"RPCNode(database: Optional[str], schema: str, name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, fqn: List[str], alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.nodes.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, group: Optional[str] = None, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Optional[str] = None, build_path: Optional[str] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, relation_name: Optional[str] = None, raw_code: str = '', language: str = 'sql', refs: List[dbt.contracts.graph.nodes.RefArgs] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.nodes.DependsOn = <factory>, compiled_path: Optional[str] = None, compiled: bool = False, compiled_code: Optional[str] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.nodes.InjectedCTE] = <factory>, _pre_injected_sql: Optional[str] = None, contract: dbt.contracts.graph.nodes.Contract = <factory>)\"\n    },\n    \"SqlNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"schema\",\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"sql operation\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/NodeConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"group\": null,\n            \"materialized\": \"view\",\n            \"incremental_strategy\": null,\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"grants\": {},\n            \"packages\": [],\n            \"docs\": {\n              \"show\": true,\n              \"node_color\": null\n            },\n            \"contract\": {\n              \"enforced\": false\n            },\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"group\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1681270501.1935291\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"raw_code\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"language\": {\n          \"type\": \"string\",\n          \"default\": \"sql\"\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/RefArgs\"\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"compiled_code\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"contract\": {\n          \"$ref\": \"#/definitions/Contract\",\n          \"default\": {\n            \"enforced\": false,\n            \"checksum\": null\n          }\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"SqlNode(database: Optional[str], schema: str, name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, fqn: List[str], alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.NodeConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.nodes.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, group: Optional[str] = None, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Optional[str] = None, build_path: Optional[str] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, relation_name: Optional[str] = None, raw_code: str = '', language: str = 'sql', refs: List[dbt.contracts.graph.nodes.RefArgs] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.nodes.DependsOn = <factory>, compiled_path: Optional[str] = None, compiled: bool = False, compiled_code: Optional[str] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.nodes.InjectedCTE] = <factory>, _pre_injected_sql: Optional[str] = None, contract: dbt.contracts.graph.nodes.Contract = <factory>)\"\n    },\n    \"GenericTestNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"test_metadata\",\n        \"schema\",\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"test_metadata\": {\n          \"$ref\": \"#/definitions/TestMetadata\"\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"test\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/TestConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": \"dbt_test__audit\",\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"group\": null,\n            \"materialized\": \"test\",\n            \"severity\": \"ERROR\",\n            \"store_failures\": null,\n            \"where\": null,\n            \"limit\": null,\n            \"fail_calc\": \"count(*)\",\n            \"warn_if\": \"!= 0\",\n            \"error_if\": \"!= 0\"\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"group\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1681270501.19419\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"raw_code\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"language\": {\n          \"type\": \"string\",\n          \"default\": \"sql\"\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/RefArgs\"\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"compiled_code\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"contract\": {\n          \"$ref\": \"#/definitions/Contract\",\n          \"default\": {\n            \"enforced\": false,\n            \"checksum\": null\n          }\n        },\n        \"column_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"file_key_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"attached_node\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"GenericTestNode(test_metadata: dbt.contracts.graph.nodes.TestMetadata, database: Optional[str], schema: str, name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, fqn: List[str], alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.TestConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.nodes.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, group: Optional[str] = None, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Optional[str] = None, build_path: Optional[str] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, relation_name: Optional[str] = None, raw_code: str = '', language: str = 'sql', refs: List[dbt.contracts.graph.nodes.RefArgs] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.nodes.DependsOn = <factory>, compiled_path: Optional[str] = None, compiled: bool = False, compiled_code: Optional[str] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.nodes.InjectedCTE] = <factory>, _pre_injected_sql: Optional[str] = None, contract: dbt.contracts.graph.nodes.Contract = <factory>, column_name: Optional[str] = None, file_key_name: Optional[str] = None, attached_node: Optional[str] = None)\"\n    },\n    \"TestMetadata\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"kwargs\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"namespace\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"TestMetadata(name: str, kwargs: Dict[str, Any] = <factory>, namespace: Optional[str] = None)\"\n    },\n    \"SnapshotNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"schema\",\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"alias\",\n        \"checksum\",\n        \"config\"\n      ],\n      \"properties\": {\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"snapshot\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/SnapshotConfig\"\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"group\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1681270501.1952698\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"raw_code\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"language\": {\n          \"type\": \"string\",\n          \"default\": \"sql\"\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/RefArgs\"\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"compiled_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"compiled_code\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"extra_ctes_injected\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"extra_ctes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InjectedCTE\"\n          },\n          \"default\": []\n        },\n        \"contract\": {\n          \"$ref\": \"#/definitions/Contract\",\n          \"default\": {\n            \"enforced\": false,\n            \"checksum\": null\n          }\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"SnapshotNode(database: Optional[str], schema: str, name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, fqn: List[str], alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.SnapshotConfig, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.nodes.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, group: Optional[str] = None, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Optional[str] = None, build_path: Optional[str] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, relation_name: Optional[str] = None, raw_code: str = '', language: str = 'sql', refs: List[dbt.contracts.graph.nodes.RefArgs] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.nodes.DependsOn = <factory>, compiled_path: Optional[str] = None, compiled: bool = False, compiled_code: Optional[str] = None, extra_ctes_injected: bool = False, extra_ctes: List[dbt.contracts.graph.nodes.InjectedCTE] = <factory>, _pre_injected_sql: Optional[str] = None, contract: dbt.contracts.graph.nodes.Contract = <factory>)\"\n    },\n    \"SnapshotConfig\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"alias\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tags\": {\n          \"oneOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"string\"\n            }\n          ],\n          \"default\": []\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"group\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"materialized\": {\n          \"type\": \"string\",\n          \"default\": \"snapshot\"\n        },\n        \"incremental_strategy\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"persist_docs\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"post-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Hook\"\n          },\n          \"default\": []\n        },\n        \"pre-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Hook\"\n          },\n          \"default\": []\n        },\n        \"quoting\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"column_types\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"full_refresh\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"unique_key\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"on_schema_change\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": \"ignore\"\n        },\n        \"grants\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"packages\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"contract\": {\n          \"$ref\": \"#/definitions/ContractConfig\",\n          \"default\": {\n            \"enforced\": false\n          }\n        },\n        \"strategy\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"target_schema\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"target_database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"updated_at\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"check_cols\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"SnapshotConfig(_extra: Dict[str, Any] = <factory>, enabled: bool = True, alias: Optional[str] = None, schema: Optional[str] = None, database: Optional[str] = None, tags: Union[List[str], str] = <factory>, meta: Dict[str, Any] = <factory>, group: Optional[str] = None, materialized: str = 'snapshot', incremental_strategy: Optional[str] = None, persist_docs: Dict[str, Any] = <factory>, post_hook: List[dbt.contracts.graph.model_config.Hook] = <factory>, pre_hook: List[dbt.contracts.graph.model_config.Hook] = <factory>, quoting: Dict[str, Any] = <factory>, column_types: Dict[str, Any] = <factory>, full_refresh: Optional[bool] = None, unique_key: Optional[str] = None, on_schema_change: Optional[str] = 'ignore', grants: Dict[str, Any] = <factory>, packages: List[str] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, contract: dbt.contracts.graph.model_config.ContractConfig = <factory>, strategy: Optional[str] = None, target_schema: Optional[str] = None, target_database: Optional[str] = None, updated_at: Optional[str] = None, check_cols: Union[str, List[str], NoneType] = None)\"\n    },\n    \"SeedNode\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"schema\",\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"alias\",\n        \"checksum\"\n      ],\n      \"properties\": {\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"seed\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"alias\": {\n          \"type\": \"string\"\n        },\n        \"checksum\": {\n          \"$ref\": \"#/definitions/FileHash\"\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/SeedConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"alias\": null,\n            \"schema\": null,\n            \"database\": null,\n            \"tags\": [],\n            \"meta\": {},\n            \"group\": null,\n            \"materialized\": \"seed\",\n            \"incremental_strategy\": null,\n            \"persist_docs\": {},\n            \"quoting\": {},\n            \"column_types\": {},\n            \"full_refresh\": null,\n            \"unique_key\": null,\n            \"on_schema_change\": \"ignore\",\n            \"grants\": {},\n            \"packages\": [],\n            \"docs\": {\n              \"show\": true,\n              \"node_color\": null\n            },\n            \"contract\": {\n              \"enforced\": false\n            },\n            \"quote_columns\": null,\n            \"post-hook\": [],\n            \"pre-hook\": []\n          }\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"group\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"build_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"deferred\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1681270501.1968079\n        },\n        \"config_call_dict\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"raw_code\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"root_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/MacroDependsOn\",\n          \"default\": {\n            \"macros\": []\n          }\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"SeedNode(database: Optional[str], schema: str, name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, fqn: List[str], alias: str, checksum: dbt.contracts.files.FileHash, config: dbt.contracts.graph.model_config.SeedConfig = <factory>, _event_status: Dict[str, Any] = <factory>, tags: List[str] = <factory>, description: str = '', columns: Dict[str, dbt.contracts.graph.nodes.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, group: Optional[str] = None, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Optional[str] = None, build_path: Optional[str] = None, deferred: bool = False, unrendered_config: Dict[str, Any] = <factory>, created_at: float = <factory>, config_call_dict: Dict[str, Any] = <factory>, relation_name: Optional[str] = None, raw_code: str = '', root_path: Optional[str] = None, depends_on: dbt.contracts.graph.nodes.MacroDependsOn = <factory>)\"\n    },\n    \"SeedConfig\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"alias\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tags\": {\n          \"oneOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"string\"\n            }\n          ],\n          \"default\": []\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"group\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"materialized\": {\n          \"type\": \"string\",\n          \"default\": \"seed\"\n        },\n        \"incremental_strategy\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"persist_docs\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"post-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Hook\"\n          },\n          \"default\": []\n        },\n        \"pre-hook\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Hook\"\n          },\n          \"default\": []\n        },\n        \"quoting\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"column_types\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"full_refresh\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"unique_key\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"on_schema_change\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": \"ignore\"\n        },\n        \"grants\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"packages\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"contract\": {\n          \"$ref\": \"#/definitions/ContractConfig\",\n          \"default\": {\n            \"enforced\": false\n          }\n        },\n        \"quote_columns\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"SeedConfig(_extra: Dict[str, Any] = <factory>, enabled: bool = True, alias: Optional[str] = None, schema: Optional[str] = None, database: Optional[str] = None, tags: Union[List[str], str] = <factory>, meta: Dict[str, Any] = <factory>, group: Optional[str] = None, materialized: str = 'seed', incremental_strategy: Optional[str] = None, persist_docs: Dict[str, Any] = <factory>, post_hook: List[dbt.contracts.graph.model_config.Hook] = <factory>, pre_hook: List[dbt.contracts.graph.model_config.Hook] = <factory>, quoting: Dict[str, Any] = <factory>, column_types: Dict[str, Any] = <factory>, full_refresh: Optional[bool] = None, unique_key: Union[str, List[str], NoneType] = None, on_schema_change: Optional[str] = 'ignore', grants: Dict[str, Any] = <factory>, packages: List[str] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, contract: dbt.contracts.graph.model_config.ContractConfig = <factory>, quote_columns: Optional[bool] = None)\"\n    },\n    \"MacroDependsOn\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"macros\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Used only in the Macro class\"\n    },\n    \"SourceDefinition\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"schema\",\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"source_name\",\n        \"source_description\",\n        \"loader\",\n        \"identifier\"\n      ],\n      \"properties\": {\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"source\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"source_name\": {\n          \"type\": \"string\"\n        },\n        \"source_description\": {\n          \"type\": \"string\"\n        },\n        \"loader\": {\n          \"type\": \"string\"\n        },\n        \"identifier\": {\n          \"type\": \"string\"\n        },\n        \"quoting\": {\n          \"$ref\": \"#/definitions/Quoting\",\n          \"default\": {\n            \"database\": null,\n            \"schema\": null,\n            \"identifier\": null,\n            \"column\": null\n          }\n        },\n        \"loaded_at_field\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"freshness\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/FreshnessThreshold\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"external\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/ExternalTable\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"columns\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ColumnInfo\"\n          },\n          \"default\": {}\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"source_meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/SourceConfig\",\n          \"default\": {\n            \"enabled\": true\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"relation_name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1681270501.197819\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"SourceDefinition(database: Optional[str], schema: str, name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, fqn: List[str], source_name: str, source_description: str, loader: str, identifier: str, _event_status: Dict[str, Any] = <factory>, quoting: dbt.contracts.graph.unparsed.Quoting = <factory>, loaded_at_field: Optional[str] = None, freshness: Optional[dbt.contracts.graph.unparsed.FreshnessThreshold] = None, external: Optional[dbt.contracts.graph.unparsed.ExternalTable] = None, description: str = '', columns: Dict[str, dbt.contracts.graph.nodes.ColumnInfo] = <factory>, meta: Dict[str, Any] = <factory>, source_meta: Dict[str, Any] = <factory>, tags: List[str] = <factory>, config: dbt.contracts.graph.model_config.SourceConfig = <factory>, patch_path: Optional[str] = None, unrendered_config: Dict[str, Any] = <factory>, relation_name: Optional[str] = None, created_at: float = <factory>)\"\n    },\n    \"Quoting\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"database\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"schema\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"identifier\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"column\": {\n          \"oneOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Quoting(database: Optional[bool] = None, schema: Optional[bool] = None, identifier: Optional[bool] = None, column: Optional[bool] = None)\"\n    },\n    \"FreshnessThreshold\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"warn_after\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/Time\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": {\n            \"count\": null,\n            \"period\": null\n          }\n        },\n        \"error_after\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/Time\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": {\n            \"count\": null,\n            \"period\": null\n          }\n        },\n        \"filter\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"FreshnessThreshold(warn_after: Optional[dbt.contracts.graph.unparsed.Time] = <factory>, error_after: Optional[dbt.contracts.graph.unparsed.Time] = <factory>, filter: Optional[str] = None)\"\n    },\n    \"FreshnessMetadata\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"dbt_schema_version\": {\n          \"type\": \"string\",\n          \"default\": \"https://schemas.getdbt.com/dbt/sources/v3.json\"\n        },\n        \"dbt_version\": {\n          \"type\": \"string\",\n          \"default\": \"1.5.0b5\"\n        },\n        \"generated_at\": {\n          \"type\": \"string\",\n          \"format\": \"date-time\",\n          \"default\": \"2023-04-12T03:35:01.185979Z\"\n        },\n        \"invocation_id\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": \"8aa1596d-f52f-40bc-ad4b-f5e48fc7e6c2\"\n        },\n        \"env\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          },\n          \"default\": {}\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"FreshnessMetadata(dbt_schema_version: str = <factory>, dbt_version: str = '1.5.0b5', generated_at: datetime.datetime = <factory>, invocation_id: Optional[str] = <factory>, env: Dict[str, str] = <factory>)\"\n    },\n    \"SourceFreshnessRuntimeError\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"unique_id\",\n        \"status\"\n      ],\n      \"properties\": {\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"error\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"integer\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"status\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"runtime error\"\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"SourceFreshnessRuntimeError(unique_id: str, error: Union[str, int, NoneType], status: dbt.contracts.results.FreshnessErrorEnum)\"\n    },\n    \"SourceFreshnessOutput\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"unique_id\",\n        \"max_loaded_at\",\n        \"snapshotted_at\",\n        \"max_loaded_at_time_ago_in_s\",\n        \"status\",\n        \"criteria\",\n        \"adapter_response\",\n        \"timing\",\n        \"thread_id\",\n        \"execution_time\"\n      ],\n      \"properties\": {\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"max_loaded_at\": {\n          \"type\": \"string\",\n          \"format\": \"date-time\"\n        },\n        \"snapshotted_at\": {\n          \"type\": \"string\",\n          \"format\": \"date-time\"\n        },\n        \"max_loaded_at_time_ago_in_s\": {\n          \"type\": \"number\"\n        },\n        \"status\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"pass\",\n            \"warn\",\n            \"error\",\n            \"runtime error\"\n          ]\n        },\n        \"criteria\": {\n          \"$ref\": \"#/definitions/FreshnessThreshold\"\n        },\n        \"adapter_response\": {\n          \"type\": \"object\"\n        },\n        \"timing\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/TimingInfo\"\n          }\n        },\n        \"thread_id\": {\n          \"type\": \"string\"\n        },\n        \"execution_time\": {\n          \"type\": \"number\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"SourceFreshnessOutput(unique_id: str, max_loaded_at: datetime.datetime, snapshotted_at: datetime.datetime, max_loaded_at_time_ago_in_s: float, status: dbt.contracts.results.FreshnessStatus, criteria: dbt.contracts.graph.unparsed.FreshnessThreshold, adapter_response: Dict[str, Any], timing: List[dbt.contracts.results.TimingInfo], thread_id: str, execution_time: float)\"\n    },\n    \"Time\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"count\": {\n          \"oneOf\": [\n            {\n              \"type\": \"integer\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"period\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\",\n              \"enum\": [\n                \"minute\",\n                \"hour\",\n                \"day\"\n              ]\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Time(count: Optional[int] = None, period: Optional[dbt.contracts.graph.unparsed.TimePeriod] = None)\"\n    },\n    \"TimingInfo\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"started_at\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\",\n              \"format\": \"date-time\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"completed_at\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\",\n              \"format\": \"date-time\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"TimingInfo(name: str, started_at: Optional[datetime.datetime] = None, completed_at: Optional[datetime.datetime] = None)\"\n    },\n    \"ExternalTable\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"location\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"file_format\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"row_format\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"tbl_properties\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"partitions\": {\n          \"oneOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"$ref\": \"#/definitions/ExternalPartition\"\n              }\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"ExternalTable(_extra: Dict[str, Any] = <factory>, location: Optional[str] = None, file_format: Optional[str] = None, row_format: Optional[str] = None, tbl_properties: Optional[str] = None, partitions: Union[List[str], List[dbt.contracts.graph.unparsed.ExternalPartition], NoneType] = None)\"\n    },\n    \"ExternalPartition\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"data_type\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"ExternalPartition(_extra: Dict[str, Any] = <factory>, name: str = '', description: str = '', data_type: str = '', meta: Dict[str, Any] = <factory>)\"\n    },\n    \"SourceConfig\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"SourceConfig(_extra: Dict[str, Any] = <factory>, enabled: bool = True)\"\n    },\n    \"Macro\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"macro_sql\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"macro\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"macro_sql\": {\n          \"type\": \"string\"\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/MacroDependsOn\",\n          \"default\": {\n            \"macros\": []\n          }\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"docs\": {\n          \"$ref\": \"#/definitions/Docs\",\n          \"default\": {\n            \"show\": true,\n            \"node_color\": null\n          }\n        },\n        \"patch_path\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"arguments\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/MacroArgument\"\n          },\n          \"default\": []\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1681270501.198105\n        },\n        \"supported_languages\": {\n          \"oneOf\": [\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\",\n                \"enum\": [\n                  \"python\",\n                  \"sql\"\n                ]\n              }\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Macro(name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, macro_sql: str, depends_on: dbt.contracts.graph.nodes.MacroDependsOn = <factory>, description: str = '', meta: Dict[str, Any] = <factory>, docs: dbt.contracts.graph.unparsed.Docs = <factory>, patch_path: Optional[str] = None, arguments: List[dbt.contracts.graph.unparsed.MacroArgument] = <factory>, created_at: float = <factory>, supported_languages: Optional[List[dbt.node_types.ModelLanguage]] = None)\"\n    },\n    \"MacroArgument\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"type\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"MacroArgument(name: str, type: Optional[str] = None, description: str = '')\"\n    },\n    \"Documentation\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"block_contents\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"doc\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"block_contents\": {\n          \"type\": \"string\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Documentation(name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, block_contents: str)\"\n    },\n    \"Exposure\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"type\",\n        \"owner\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"exposure\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"dashboard\",\n            \"notebook\",\n            \"analysis\",\n            \"ml\",\n            \"application\"\n          ]\n        },\n        \"owner\": {\n          \"$ref\": \"#/definitions/Owner\"\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"default\": \"\"\n        },\n        \"label\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"maturity\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\",\n              \"enum\": [\n                \"low\",\n                \"medium\",\n                \"high\"\n              ]\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/ExposureConfig\",\n          \"default\": {\n            \"enabled\": true\n          }\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"url\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/RefArgs\"\n          },\n          \"default\": []\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1681270501.198782\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Exposure(name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, fqn: List[str], type: dbt.contracts.graph.unparsed.ExposureType, owner: dbt.contracts.graph.unparsed.Owner, description: str = '', label: Optional[str] = None, maturity: Optional[dbt.contracts.graph.unparsed.MaturityType] = None, meta: Dict[str, Any] = <factory>, tags: List[str] = <factory>, config: dbt.contracts.graph.model_config.ExposureConfig = <factory>, unrendered_config: Dict[str, Any] = <factory>, url: Optional[str] = None, depends_on: dbt.contracts.graph.nodes.DependsOn = <factory>, refs: List[dbt.contracts.graph.nodes.RefArgs] = <factory>, sources: List[List[str]] = <factory>, metrics: List[List[str]] = <factory>, created_at: float = <factory>)\"\n    },\n    \"Owner\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"email\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"name\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"Owner(_extra: Dict[str, Any] = <factory>, email: Optional[str] = None, name: Optional[str] = None)\"\n    },\n    \"ExposureConfig\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"ExposureConfig(_extra: Dict[str, Any] = <factory>, enabled: bool = True)\"\n    },\n    \"Metric\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"fqn\",\n        \"description\",\n        \"label\",\n        \"calculation_method\",\n        \"expression\",\n        \"filters\",\n        \"time_grains\",\n        \"dimensions\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"metric\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"fqn\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"label\": {\n          \"type\": \"string\"\n        },\n        \"calculation_method\": {\n          \"type\": \"string\"\n        },\n        \"expression\": {\n          \"type\": \"string\"\n        },\n        \"filters\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/MetricFilter\"\n          }\n        },\n        \"time_grains\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"dimensions\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"timestamp\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"window\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/MetricTime\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"model\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"model_unique_id\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"meta\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"default\": []\n        },\n        \"config\": {\n          \"$ref\": \"#/definitions/MetricConfig\",\n          \"default\": {\n            \"enabled\": true,\n            \"group\": null\n          }\n        },\n        \"unrendered_config\": {\n          \"type\": \"object\",\n          \"default\": {}\n        },\n        \"sources\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"depends_on\": {\n          \"$ref\": \"#/definitions/DependsOn\",\n          \"default\": {\n            \"macros\": [],\n            \"nodes\": []\n          }\n        },\n        \"refs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/RefArgs\"\n          },\n          \"default\": []\n        },\n        \"metrics\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"default\": []\n        },\n        \"created_at\": {\n          \"type\": \"number\",\n          \"default\": 1681270501.199492\n        },\n        \"group\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Metric(name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, fqn: List[str], description: str, label: str, calculation_method: str, expression: str, filters: List[dbt.contracts.graph.unparsed.MetricFilter], time_grains: List[str], dimensions: List[str], timestamp: Optional[str] = None, window: Optional[dbt.contracts.graph.unparsed.MetricTime] = None, model: Optional[str] = None, model_unique_id: Optional[str] = None, meta: Dict[str, Any] = <factory>, tags: List[str] = <factory>, config: dbt.contracts.graph.model_config.MetricConfig = <factory>, unrendered_config: Dict[str, Any] = <factory>, sources: List[List[str]] = <factory>, depends_on: dbt.contracts.graph.nodes.DependsOn = <factory>, refs: List[dbt.contracts.graph.nodes.RefArgs] = <factory>, metrics: List[List[str]] = <factory>, created_at: float = <factory>, group: Optional[str] = None)\"\n    },\n    \"MetricFilter\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"field\",\n        \"operator\",\n        \"value\"\n      ],\n      \"properties\": {\n        \"field\": {\n          \"type\": \"string\"\n        },\n        \"operator\": {\n          \"type\": \"string\"\n        },\n        \"value\": {\n          \"type\": \"string\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"MetricFilter(field: str, operator: str, value: str)\"\n    },\n    \"MetricTime\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"count\": {\n          \"oneOf\": [\n            {\n              \"type\": \"integer\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"period\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\",\n              \"enum\": [\n                \"day\",\n                \"week\",\n                \"month\",\n                \"year\"\n              ]\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"MetricTime(count: Optional[int] = None, period: Optional[dbt.contracts.graph.unparsed.MetricTimePeriod] = None)\"\n    },\n    \"MetricConfig\": {\n      \"type\": \"object\",\n      \"required\": [],\n      \"properties\": {\n        \"enabled\": {\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"group\": {\n          \"oneOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": true,\n      \"description\": \"MetricConfig(_extra: Dict[str, Any] = <factory>, enabled: bool = True, group: Optional[str] = None)\"\n    },\n    \"Group\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\",\n        \"resource_type\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"unique_id\",\n        \"owner\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"resource_type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"group\"\n          ]\n        },\n        \"package_name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"original_file_path\": {\n          \"type\": \"string\"\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"owner\": {\n          \"$ref\": \"#/definitions/Owner\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"description\": \"Group(name: str, resource_type: dbt.node_types.NodeType, package_name: str, path: str, original_file_path: str, unique_id: str, owner: dbt.contracts.graph.unparsed.Owner)\"\n    }\n  },\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n  \"$id\": \"https://schemas.getdbt.com/dbt/manifest/v9.json\"\n}"
  },
  {
    "path": "schemas/dbt/run-results/v4.json",
    "content": "{\n  \"$ref\": \"#/$defs/RunResultsArtifact\",\n  \"$defs\": {\n    \"BaseArtifactMetadata\": {\n      \"type\": \"object\",\n      \"title\": \"BaseArtifactMetadata\",\n      \"properties\": {\n        \"dbt_schema_version\": {\n          \"type\": \"string\"\n        },\n        \"dbt_version\": {\n          \"type\": \"string\",\n          \"default\": \"1.7.0b1\"\n        },\n        \"generated_at\": {\n          \"type\": \"string\"\n        },\n        \"invocation_id\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"env\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          },\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"dbt_schema_version\"\n      ]\n    },\n    \"TimingInfo\": {\n      \"type\": \"object\",\n      \"title\": \"TimingInfo\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"started_at\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\",\n              \"format\": \"date-time\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"completed_at\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\",\n              \"format\": \"date-time\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"name\"\n      ]\n    },\n    \"RunResultOutput\": {\n      \"type\": \"object\",\n      \"title\": \"RunResultOutput\",\n      \"properties\": {\n        \"status\": {\n          \"anyOf\": [\n            {\n              \"enum\": [\n                \"success\",\n                \"error\",\n                \"skipped\"\n              ]\n            },\n            {\n              \"enum\": [\n                \"pass\",\n                \"error\",\n                \"fail\",\n                \"warn\",\n                \"skipped\"\n              ]\n            },\n            {\n              \"enum\": [\n                \"pass\",\n                \"warn\",\n                \"error\",\n                \"runtime error\"\n              ]\n            }\n          ]\n        },\n        \"timing\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/TimingInfo\"\n          }\n        },\n        \"thread_id\": {\n          \"type\": \"string\"\n        },\n        \"execution_time\": {\n          \"type\": \"number\"\n        },\n        \"adapter_response\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"message\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"failures\": {\n          \"anyOf\": [\n            {\n              \"type\": \"integer\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"status\",\n        \"timing\",\n        \"thread_id\",\n        \"execution_time\",\n        \"adapter_response\",\n        \"message\",\n        \"failures\",\n        \"unique_id\"\n      ]\n    },\n    \"RunResultsArtifact\": {\n      \"type\": \"object\",\n      \"title\": \"RunResultsArtifact\",\n      \"properties\": {\n        \"metadata\": {\n          \"$ref\": \"#/$defs/BaseArtifactMetadata\"\n        },\n        \"results\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/RunResultOutput\"\n          }\n        },\n        \"elapsed_time\": {\n          \"type\": \"number\"\n        },\n        \"args\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"metadata\",\n        \"results\",\n        \"elapsed_time\"\n      ]\n    }\n  },\n  \"$id\": \"https://schemas.getdbt.com/dbt/run-results/v4.json\"\n}\n"
  },
  {
    "path": "schemas/dbt/run-results/v5.json",
    "content": "{\n  \"$ref\": \"#/$defs/RunResultsArtifact\",\n  \"$defs\": {\n    \"BaseArtifactMetadata\": {\n      \"type\": \"object\",\n      \"title\": \"BaseArtifactMetadata\",\n      \"properties\": {\n        \"dbt_schema_version\": {\n          \"type\": \"string\"\n        },\n        \"dbt_version\": {\n          \"type\": \"string\",\n          \"default\": \"1.7.0b1\"\n        },\n        \"generated_at\": {\n          \"type\": \"string\"\n        },\n        \"invocation_id\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"env\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          },\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"dbt_schema_version\"\n      ]\n    },\n    \"TimingInfo\": {\n      \"type\": \"object\",\n      \"title\": \"TimingInfo\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"started_at\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        },\n        \"completed_at\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ],\n          \"default\": null\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"name\"\n      ]\n    },\n    \"RunResultOutput\": {\n      \"type\": \"object\",\n      \"title\": \"RunResultOutput\",\n      \"properties\": {\n        \"status\": {\n          \"anyOf\": [\n            {\n              \"enum\": [\n                \"success\",\n                \"error\",\n                \"skipped\"\n              ]\n            },\n            {\n              \"enum\": [\n                \"pass\",\n                \"error\",\n                \"fail\",\n                \"warn\",\n                \"skipped\"\n              ]\n            },\n            {\n              \"enum\": [\n                \"pass\",\n                \"warn\",\n                \"error\",\n                \"runtime error\"\n              ]\n            }\n          ]\n        },\n        \"timing\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/TimingInfo\"\n          }\n        },\n        \"thread_id\": {\n          \"type\": \"string\"\n        },\n        \"execution_time\": {\n          \"type\": \"number\"\n        },\n        \"adapter_response\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        },\n        \"message\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"failures\": {\n          \"anyOf\": [\n            {\n              \"type\": \"integer\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"unique_id\": {\n          \"type\": \"string\"\n        },\n        \"compiled\": {\n          \"anyOf\": [\n            {\n              \"type\": \"boolean\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"compiled_code\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"relation_name\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"status\",\n        \"timing\",\n        \"thread_id\",\n        \"execution_time\",\n        \"adapter_response\",\n        \"message\",\n        \"failures\",\n        \"unique_id\",\n        \"compiled\",\n        \"compiled_code\",\n        \"relation_name\"\n      ]\n    },\n    \"RunResultsArtifact\": {\n      \"type\": \"object\",\n      \"title\": \"RunResultsArtifact\",\n      \"properties\": {\n        \"metadata\": {\n          \"$ref\": \"#/$defs/BaseArtifactMetadata\"\n        },\n        \"results\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/RunResultOutput\"\n          }\n        },\n        \"elapsed_time\": {\n          \"type\": \"number\"\n        },\n        \"args\": {\n          \"type\": \"object\",\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"metadata\",\n        \"results\",\n        \"elapsed_time\"\n      ]\n    }\n  },\n  \"$id\": \"https://schemas.getdbt.com/dbt/run-results/v5.json\"\n}\n"
  },
  {
    "path": "schemas/dbt/run-results/v6.json",
    "content": "{\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"type\": \"object\",\n  \"title\": \"RunResultsArtifact\",\n  \"properties\": {\n    \"metadata\": {\n      \"type\": \"object\",\n      \"title\": \"BaseArtifactMetadata\",\n      \"properties\": {\n        \"dbt_schema_version\": {\n          \"type\": \"string\"\n        },\n        \"dbt_version\": {\n          \"type\": \"string\",\n          \"default\": \"1.12.0a1\"\n        },\n        \"generated_at\": {\n          \"type\": \"string\"\n        },\n        \"invocation_id\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"invocation_started_at\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"env\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          },\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"dbt_schema_version\"\n      ]\n    },\n    \"results\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"type\": \"object\",\n        \"title\": \"RunResultOutput\",\n        \"properties\": {\n          \"status\": {\n            \"anyOf\": [\n              {\n                \"enum\": [\n                  \"success\",\n                  \"error\",\n                  \"skipped\",\n                  \"partial success\",\n                  \"no-op\"\n                ]\n              },\n              {\n                \"enum\": [\n                  \"pass\",\n                  \"error\",\n                  \"fail\",\n                  \"warn\",\n                  \"skipped\"\n                ]\n              },\n              {\n                \"enum\": [\n                  \"pass\",\n                  \"warn\",\n                  \"error\",\n                  \"runtime error\"\n                ]\n              }\n            ]\n          },\n          \"timing\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"object\",\n              \"title\": \"TimingInfo\",\n              \"properties\": {\n                \"name\": {\n                  \"type\": \"string\"\n                },\n                \"started_at\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"string\"\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                },\n                \"completed_at\": {\n                  \"anyOf\": [\n                    {\n                      \"type\": \"string\"\n                    },\n                    {\n                      \"type\": \"null\"\n                    }\n                  ],\n                  \"default\": null\n                }\n              },\n              \"additionalProperties\": false,\n              \"required\": [\n                \"name\"\n              ]\n            }\n          },\n          \"thread_id\": {\n            \"type\": \"string\"\n          },\n          \"execution_time\": {\n            \"type\": \"number\"\n          },\n          \"adapter_response\": {\n            \"type\": \"object\",\n            \"propertyNames\": {\n              \"type\": \"string\"\n            }\n          },\n          \"message\": {\n            \"anyOf\": [\n              {\n                \"type\": \"string\"\n              },\n              {\n                \"type\": \"null\"\n              }\n            ]\n          },\n          \"failures\": {\n            \"anyOf\": [\n              {\n                \"type\": \"integer\"\n              },\n              {\n                \"type\": \"null\"\n              }\n            ]\n          },\n          \"unique_id\": {\n            \"type\": \"string\"\n          },\n          \"compiled\": {\n            \"anyOf\": [\n              {\n                \"type\": \"boolean\"\n              },\n              {\n                \"type\": \"null\"\n              }\n            ]\n          },\n          \"compiled_code\": {\n            \"anyOf\": [\n              {\n                \"type\": \"string\"\n              },\n              {\n                \"type\": \"null\"\n              }\n            ]\n          },\n          \"relation_name\": {\n            \"anyOf\": [\n              {\n                \"type\": \"string\"\n              },\n              {\n                \"type\": \"null\"\n              }\n            ]\n          },\n          \"batch_results\": {\n            \"anyOf\": [\n              {\n                \"type\": \"object\",\n                \"title\": \"BatchResults\",\n                \"properties\": {\n                  \"successful\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"array\",\n                      \"prefixItems\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"string\"\n                        }\n                      ],\n                      \"maxItems\": 2,\n                      \"minItems\": 2\n                    }\n                  },\n                  \"failed\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"array\",\n                      \"prefixItems\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"string\"\n                        }\n                      ],\n                      \"maxItems\": 2,\n                      \"minItems\": 2\n                    }\n                  }\n                },\n                \"additionalProperties\": false\n              },\n              {\n                \"type\": \"null\"\n              }\n            ],\n            \"default\": null\n          }\n        },\n        \"additionalProperties\": false,\n        \"required\": [\n          \"status\",\n          \"timing\",\n          \"thread_id\",\n          \"execution_time\",\n          \"adapter_response\",\n          \"message\",\n          \"failures\",\n          \"unique_id\",\n          \"compiled\",\n          \"compiled_code\",\n          \"relation_name\"\n        ]\n      }\n    },\n    \"elapsed_time\": {\n      \"type\": \"number\"\n    },\n    \"args\": {\n      \"type\": \"object\",\n      \"propertyNames\": {\n        \"type\": \"string\"\n      }\n    }\n  },\n  \"additionalProperties\": false,\n  \"required\": [\n    \"metadata\",\n    \"results\",\n    \"elapsed_time\"\n  ],\n  \"$id\": \"https://schemas.getdbt.com/dbt/run-results/v6.json\"\n}\n"
  },
  {
    "path": "schemas/dbt/sources/v3.json",
    "content": "{\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"type\": \"object\",\n  \"title\": \"FreshnessExecutionResultArtifact\",\n  \"properties\": {\n    \"metadata\": {\n      \"type\": \"object\",\n      \"title\": \"FreshnessMetadata\",\n      \"properties\": {\n        \"dbt_schema_version\": {\n          \"type\": \"string\"\n        },\n        \"dbt_version\": {\n          \"type\": \"string\",\n          \"default\": \"1.12.0a1\"\n        },\n        \"generated_at\": {\n          \"type\": \"string\"\n        },\n        \"invocation_id\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"invocation_started_at\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"type\": \"null\"\n            }\n          ]\n        },\n        \"env\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          },\n          \"propertyNames\": {\n            \"type\": \"string\"\n          }\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"results\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"anyOf\": [\n          {\n            \"type\": \"object\",\n            \"title\": \"SourceFreshnessRuntimeError\",\n            \"properties\": {\n              \"unique_id\": {\n                \"type\": \"string\"\n              },\n              \"error\": {\n                \"anyOf\": [\n                  {\n                    \"type\": \"string\"\n                  },\n                  {\n                    \"type\": \"integer\"\n                  },\n                  {\n                    \"type\": \"null\"\n                  }\n                ]\n              },\n              \"status\": {\n                \"enum\": [\n                  \"runtime error\"\n                ]\n              }\n            },\n            \"additionalProperties\": false,\n            \"required\": [\n              \"unique_id\",\n              \"error\",\n              \"status\"\n            ]\n          },\n          {\n            \"type\": \"object\",\n            \"title\": \"SourceFreshnessOutput\",\n            \"properties\": {\n              \"unique_id\": {\n                \"type\": \"string\"\n              },\n              \"max_loaded_at\": {\n                \"type\": \"string\"\n              },\n              \"snapshotted_at\": {\n                \"type\": \"string\"\n              },\n              \"max_loaded_at_time_ago_in_s\": {\n                \"type\": \"number\"\n              },\n              \"status\": {\n                \"enum\": [\n                  \"pass\",\n                  \"warn\",\n                  \"error\",\n                  \"runtime error\"\n                ]\n              },\n              \"criteria\": {\n                \"type\": \"object\",\n                \"title\": \"FreshnessThreshold\",\n                \"properties\": {\n                  \"warn_after\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"object\",\n                        \"title\": \"Time\",\n                        \"properties\": {\n                          \"count\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"integer\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"period\": {\n                            \"anyOf\": [\n                              {\n                                \"enum\": [\n                                  \"minute\",\n                                  \"hour\",\n                                  \"day\"\n                                ]\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          }\n                        },\n                        \"additionalProperties\": false\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ]\n                  },\n                  \"error_after\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"object\",\n                        \"title\": \"Time\",\n                        \"properties\": {\n                          \"count\": {\n                            \"anyOf\": [\n                              {\n                                \"type\": \"integer\"\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          },\n                          \"period\": {\n                            \"anyOf\": [\n                              {\n                                \"enum\": [\n                                  \"minute\",\n                                  \"hour\",\n                                  \"day\"\n                                ]\n                              },\n                              {\n                                \"type\": \"null\"\n                              }\n                            ],\n                            \"default\": null\n                          }\n                        },\n                        \"additionalProperties\": false\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ]\n                  },\n                  \"filter\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\"\n                      },\n                      {\n                        \"type\": \"null\"\n                      }\n                    ],\n                    \"default\": null\n                  }\n                },\n                \"additionalProperties\": false\n              },\n              \"adapter_response\": {\n                \"type\": \"object\",\n                \"propertyNames\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"timing\": {\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"object\",\n                  \"title\": \"TimingInfo\",\n                  \"properties\": {\n                    \"name\": {\n                      \"type\": \"string\"\n                    },\n                    \"started_at\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    },\n                    \"completed_at\": {\n                      \"anyOf\": [\n                        {\n                          \"type\": \"string\"\n                        },\n                        {\n                          \"type\": \"null\"\n                        }\n                      ],\n                      \"default\": null\n                    }\n                  },\n                  \"additionalProperties\": false,\n                  \"required\": [\n                    \"name\"\n                  ]\n                }\n              },\n              \"thread_id\": {\n                \"type\": \"string\"\n              },\n              \"execution_time\": {\n                \"type\": \"number\"\n              }\n            },\n            \"additionalProperties\": false,\n            \"required\": [\n              \"unique_id\",\n              \"max_loaded_at\",\n              \"snapshotted_at\",\n              \"max_loaded_at_time_ago_in_s\",\n              \"status\",\n              \"criteria\",\n              \"adapter_response\",\n              \"timing\",\n              \"thread_id\",\n              \"execution_time\"\n            ]\n          }\n        ]\n      }\n    },\n    \"elapsed_time\": {\n      \"type\": \"number\"\n    }\n  },\n  \"additionalProperties\": false,\n  \"required\": [\n    \"metadata\",\n    \"results\",\n    \"elapsed_time\"\n  ],\n  \"$id\": \"https://schemas.getdbt.com/dbt/sources/v3.json\"\n}\n"
  },
  {
    "path": "scripts/check_libyaml.py",
    "content": "#!/usr/bin/env python\ntry:\n    from yaml import CDumper as Dumper\n    from yaml import CLoader as Loader  # noqa: F401\n    from yaml import CSafeLoader as SafeLoader\nexcept ImportError:\n    from yaml import Dumper, Loader, SafeLoader  # noqa: F401\n\nif Loader.__name__ == \"CLoader\":\n    print(\"libyaml is working\")\nelif Loader.__name__ == \"Loader\":\n    print(\"libyaml is not working\")\n    print(\"Check the python executable and pyyaml for libyaml support\")\n"
  },
  {
    "path": "scripts/collect-artifact-schema.py",
    "content": "#!/usr/bin/env python\nimport json\nfrom argparse import ArgumentParser\nfrom dataclasses import dataclass\nfrom pathlib import Path\nfrom typing import Any, Dict, Type\n\nfrom dbt.artifacts.schemas.base import VersionedSchema\nfrom dbt.artifacts.schemas.catalog import CatalogArtifact\nfrom dbt.artifacts.schemas.freshness import FreshnessExecutionResultArtifact\nfrom dbt.artifacts.schemas.run import RunResultsArtifact\nfrom dbt.contracts.graph.manifest import WritableManifest\nfrom dbt_common.clients.system import write_file\n\n\n@dataclass\nclass ArtifactInfo:\n    path: str\n    name: str\n    json_schema: Dict[str, Any]\n\n    @classmethod\n    def from_artifact_cls(\n        cls,\n        artifact_cls: Type[VersionedSchema],\n    ) -> \"ArtifactInfo\":\n        return cls(\n            path=artifact_cls.dbt_schema_version.path,\n            name=artifact_cls.dbt_schema_version.name,\n            json_schema=artifact_cls.json_schema(),\n        )\n\n    def write_schema(self, dest_dir: Path):\n        write_file(str(dest_dir / self.path), json.dumps(self.json_schema, indent=2))\n\n\n@dataclass\nclass Arguments:\n    artifact: str\n    path: Path\n\n    @classmethod\n    def parse(cls) -> \"Arguments\":\n        parser = ArgumentParser(prog=\"Collect and write dbt arfifact schema\")\n        parser.add_argument(\n            \"--path\",\n            type=Path,\n            help=\"The dir to write artifact schema\",\n        )\n\n        parser.add_argument(\n            \"--artifact\",\n            type=str,\n            choices=[\"manifest\", \"sources\", \"run-results\", \"catalog\"],\n            help=\"The name of the artifact to update\",\n        )\n\n        parsed = parser.parse_args()\n        return cls(artifact=parsed.artifact, path=parsed.path)\n\n\ndef collect_artifact_schema(args: Arguments):\n    artifacts = [\n        FreshnessExecutionResultArtifact,\n        RunResultsArtifact,\n        CatalogArtifact,\n        # WritableManifest introduces new definitions in hologram which are likely\n        # getting persisted across invocations of json_schema and making their\n        # way to other written artifacts - so write it last as a short-term fix.\n        # https://github.com/dbt-labs/dbt-core/issues/7604\n        WritableManifest,\n    ]\n    filtered_artifacts = filter(\n        lambda a: a.dbt_schema_version.name == args.artifact or args.artifact is None, artifacts\n    )\n    artifact_infos = []\n    for artifact_cls in filtered_artifacts:\n        artifact_infos.append(ArtifactInfo.from_artifact_cls(artifact_cls))\n\n    if args and args.path is not None:\n        for artifact_info in artifact_infos:\n            dest_dir = args.path.resolve()\n            artifact_info.write_schema(dest_dir)\n    else:\n        artifacts_dict = {\n            artifact_info.name: artifact_info.json_schema for artifact_info in artifact_infos\n        }\n        print(json.dumps(artifacts_dict))\n\n\ndef main():\n    parsed = Arguments.parse()\n    collect_artifact_schema(parsed)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "scripts/collect-dbt-contexts.py",
    "content": "#!/usr/bin/env python\n\nimport inspect\nimport json\nfrom dataclasses import dataclass\nfrom typing import Any, Dict, Iterable, List, Optional, Union\n\nfrom dbt.context.base import BaseContext\nfrom dbt.context.providers import MacroContext, ModelContext\nfrom dbt.context.target import TargetContext\nfrom dbt_common.dataclass_schema import dbtClassMixin\n\nCONTEXTS_MAP = {\n    \"base\": BaseContext,\n    \"target\": TargetContext,\n    \"model\": ModelContext,\n    \"macro\": MacroContext,\n}\n\n\n@dataclass\nclass ContextValue(dbtClassMixin):\n    name: str\n    value: str  # a type description\n    doc: Optional[str]\n\n\n@dataclass\nclass MethodArgument(dbtClassMixin):\n    name: str\n    value: str  # a type description\n\n\n@dataclass\nclass ContextMethod(dbtClassMixin):\n    name: str\n    args: List[MethodArgument]\n    result: str  # a type description\n    doc: Optional[str]\n\n\n@dataclass\nclass Unknown(dbtClassMixin):\n    name: str\n    value: str\n    doc: Optional[str]\n\n\nContextMember = Union[ContextValue, ContextMethod, Unknown]\n\n\ndef _get_args(func: inspect.Signature) -> Iterable[MethodArgument]:\n    found_first = False\n    for argname, arg in func.parameters.items():\n        if found_first is False and argname in {\"self\", \"cls\"}:\n            continue\n        if found_first is False:\n            found_first = True\n\n        yield MethodArgument(\n            name=argname,\n            value=inspect.formatannotation(arg.annotation),\n        )\n\n\ndef collect(cls):\n    values = []\n    for name, v in cls._context_members_.items():\n        attrname = cls._context_attrs_[name]\n        attrdef = getattr(cls, attrname)\n        doc = getattr(attrdef, \"__doc__\")\n        if inspect.isfunction(attrdef):\n            sig = inspect.signature(attrdef)\n            result = inspect.formatannotation(sig.return_annotation)\n            sig_good_part = ContextMethod(\n                name=name,\n                args=list(_get_args(sig)),\n                result=result,\n                doc=doc,\n            )\n        elif isinstance(attrdef, property):\n            sig = inspect.signature(attrdef.fget)\n            sig_txt = inspect.formatannotation(sig.return_annotation)\n            sig_good_part = ContextValue(name=name, value=sig_txt, doc=doc)\n        else:\n            sig_good_part = Unknown(name=name, value=repr(attrdef), doc=doc)\n        values.append(sig_good_part)\n\n    return values\n\n\n@dataclass\nclass ContextCatalog(dbtClassMixin):\n    base: List[ContextMember]\n    target: List[ContextMember]\n    model: List[ContextMember]\n    macro: List[ContextMember]\n    schema: Dict[str, Any]\n\n\ndef main():\n    catalog = ContextCatalog(\n        base=collect(BaseContext),\n        target=collect(TargetContext),\n        model=collect(ModelContext),\n        macro=collect(MacroContext),\n        schema=ContextCatalog.json_schema(),\n    )\n    print(json.dumps(catalog.to_dict()))\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "scripts/env-setup.sh",
    "content": "#!/bin/bash\n# Set environment variables required for integration tests\n# This is used in the release workflow to set the environment variables for the integration tests\necho \"DBT_INVOCATION_ENV=github-actions\" >> $GITHUB_ENV\necho \"DBT_TEST_USER_1=dbt_test_user_1\" >> $GITHUB_ENV\necho \"DBT_TEST_USER_2=dbt_test_user_2\" >> $GITHUB_ENV\necho \"DBT_TEST_USER_3=dbt_test_user_3\" >> $GITHUB_ENV\n"
  },
  {
    "path": "scripts/migrate-adapters.py",
    "content": "import argparse\nimport ast\nfrom collections import namedtuple\nfrom pathlib import Path\n\nImport = namedtuple(\"Import\", [\"module\", \"name\", \"alias\"])\n\n\ndef get_imports(path):\n    with open(path) as fh:\n        root = ast.parse(fh.read(), path)\n\n    for node in ast.iter_child_nodes(root):\n        if isinstance(node, ast.Import):\n            module = []\n        elif isinstance(node, ast.ImportFrom):\n            module = node.module.split(\".\")\n        else:\n            continue\n\n        for n in node.names:\n            yield Import(module, n.name.split(\".\"), n.asname)\n\n\nparser = argparse.ArgumentParser(\"migrate_adapters\")\nparser.add_argument(\"path\", help=\"The path to run the migration tool over.\", type=str)\nargs = parser.parse_args()\n\npath = Path(args.path)\npathlist = path.rglob(\"*.py\")\n\ntotal_dbt_imports = 0\ninvalid_dbt_imports = 0\npath_to_invalid_imports = {}\nfor path in pathlist:\n    path_to_invalid_imports[path] = []\n    for imported_module in get_imports(str(path)):\n        if imported_module.module and imported_module.module[0] == \"dbt\":\n            total_dbt_imports += 1\n            if imported_module.module[1] not in (\"common\", \"adapters\"):\n                invalid_dbt_imports += 1\n                path_to_invalid_imports[path].append(\n                    f\"{'.'.join(imported_module.module)}::{imported_module.name[0]}\"\n                )\n\nmigrated_imports = total_dbt_imports - invalid_dbt_imports\nmigrated_imports_progress = round((migrated_imports / total_dbt_imports) * 100, 2)\n\nfor path, invalid_imports in path_to_invalid_imports.items():\n    if invalid_imports:\n        print()\n        print(f\"\\033[92m{path}:\\033[0m\")\n        for invalid_import in invalid_imports:\n            print(f\"  - {invalid_import}\")\n\nprint()\nprint(\n    f\"migration progress: {migrated_imports_progress}% of dbt imports are valid (from adapters or common)\"\n)\nprint(f\"remaining core imports: {invalid_dbt_imports}\")\n"
  },
  {
    "path": "scripts/pre-commit-hooks/no_versioned_artifact_resource_imports.py",
    "content": "import os\nimport re\nimport sys\n\nfrom dbt_common.ui import red\n\n\ndef normalize(path: str) -> str:\n    \"\"\"On windows, neither is enough on its own:\n    >>> normcase('C:\\\\documents/ALL CAPS/subdir\\\\..')\n    'c:\\\\documents\\\\all caps\\\\subdir\\\\..'\n    >>> normpath('C:\\\\documents/ALL CAPS/subdir\\\\..')\n    'C:\\\\documents\\\\ALL CAPS'\n    >>> normpath(normcase('C:\\\\documents/ALL CAPS/subdir\\\\..'))\n    'c:\\\\documents\\\\all caps'\n    \"\"\"\n    return os.path.normcase(os.path.normpath(path))\n\n\ndef has_bad_artifact_resource_imports(filepath: str) -> bool:\n    \"\"\"\n    Checks for improper artifact resource imports outside of the artifacts module.\n\n    Returns:\n        True if a file imports from a versioned artifacts module\n        False otherwise\n    \"\"\"\n\n    if not filepath.endswith(\".py\"):\n        # skip non-python files\n        return False\n    elif normalize(\"core/dbt/artifacts\") in filepath:\n        # skip files in the artifacts module\n        return False\n\n    with open(filepath, \"r\") as f:\n        lines = f.readlines()\n\n    has_bad_imports = False\n    for line_number, line in enumerate(lines):\n        line_without_whitespace = line.strip()  # get rid of leading and trailing whitespace\n\n        # we only care about import/from statements\n        if line_without_whitespace.startswith(\"from \") or line_without_whitespace.startswith(\n            \"import \"\n        ):\n            import_path = line_without_whitespace.split(\" \")[1]\n            if re.match(r\"^dbt\\.artifacts\\.resources\\.v\\d+\", import_path):\n                has_bad_imports = True\n                print(\n                    f\"{filepath}:{line_number}: [{red('ERROR')}] `{import_path}` is an import from a versioned resource. Instead import `from dbt.artifacts.resource` directly.\"\n                )\n\n    return has_bad_imports\n\n\ndef main():\n    all_passed = True\n    for filepath in sys.argv[1:]:\n        if has_bad_artifact_resource_imports(filepath):\n            all_passed = False\n\n    return 0 if all_passed else 1\n\n\nif __name__ == \"__main__\":\n    sys.exit(main())\n"
  },
  {
    "path": "scripts/setup_db.sh",
    "content": "#!/bin/bash\nset -x\n\nif [ \"${SKIP_HOMEBREW:-false}\" = \"false\" ]; then\n    brew install postgresql@16\n    brew link postgresql@16 --force\n    export PATH=\"/opt/homebrew/opt/postgresql@16/bin:$PATH\"\n\n    # Start PostgreSQL using the full command instead of brew services\n    pg_ctl -D /opt/homebrew/var/postgresql@16 start\n\n    echo \"Check PostgreSQL service is running\"\n    i=10\n    COMMAND='pg_isready'\n    while [ $i -gt -1 ]; do\n        if [ $i == 0 ]; then\n            echo \"PostgreSQL service not ready, all attempts exhausted\"\n            exit 1\n        fi\n        echo \"Check PostgreSQL service status\"\n        eval $COMMAND && break\n        echo \"PostgreSQL service not ready, wait 10 more sec, attempts left: $i\"\n        sleep 10\n        ((i--))\n    done\n\n    createuser -s postgres\n\n    env | grep '^PG'\nfi\n\n# If you want to run this script for your own postgresql (run with\n# docker-compose) it will look like this:\n# PGHOST=127.0.0.1 PGUSER=root PGPASSWORD=password PGDATABASE=postgres \\\nPGUSER=\"${PGUSER:-postgres}\"\nexport PGUSER\nPGPORT=\"${PGPORT:-5432}\"\nexport PGPORT\nPGHOST=\"${PGHOST:-localhost}\"\nexport PGHOST\nPGDATABASE=\"${PGDATABASE:-postgres}\"\nexport PGDATABASE\n: \"${PGPASSWORD:=password}\"\nexport PGPASSWORD\n\n# Normalize localhost to IPv4 to avoid IPv6 (::1) surprises\nif [ \"${PGHOST}\" = \"localhost\" ]; then\n    PGHOST=\"127.0.0.1\"\n    export PGHOST\nfi\n\n\nfor i in {1..10}; do\n\tif pg_isready -h \"${PGHOST}\" -p \"${PGPORT}\" -U \"${PGUSER}\" ; then\n\t\tbreak\n\tfi\n\n    echo \"Waiting for postgres to be ready...\"\n    sleep 2;\ndone;\n\ncreatedb dbt\npsql -c \"SELECT version();\"\npsql -c \"CREATE ROLE root WITH PASSWORD 'password';\"\npsql -c \"ALTER ROLE root WITH LOGIN;\"\npsql -c \"GRANT CREATE, CONNECT ON DATABASE dbt TO root WITH GRANT OPTION;\"\n\npsql -c \"CREATE ROLE noaccess WITH PASSWORD 'password' NOSUPERUSER;\"\npsql -c \"ALTER ROLE noaccess WITH LOGIN;\"\npsql -c \"GRANT CONNECT ON DATABASE dbt TO noaccess;\"\npsql -c \"CREATE ROLE dbt_test_user_1;\"\npsql -c \"CREATE ROLE dbt_test_user_2;\"\npsql -c \"CREATE ROLE dbt_test_user_3;\"\n\npsql -c 'CREATE DATABASE \"dbtMixedCase\";'\npsql -c 'GRANT CREATE, CONNECT ON DATABASE \"dbtMixedCase\" TO root WITH GRANT OPTION;'\n\nset +x\n"
  },
  {
    "path": "scripts/update_dev_packages.sh",
    "content": "#!/bin/bash -e\nset -e\n\n# this is used in dbt-common for CI\n\nrepo=$1\nref=$2\ntarget_req_file=\"core/hatch.toml\"\n\nreq_sed_pattern=\"s|${repo}.git@main|${repo}.git@${ref}|g\"\nif [[ \"$OSTYPE\" == darwin* ]]; then\n  # mac ships with a different version of sed that requires a delimiter arg\n  sed -i \"\" \"$req_sed_pattern\" \"$target_req_file\"\nelse\n  sed -i \"$req_sed_pattern\" \"$target_req_file\"\nfi\n"
  },
  {
    "path": "tests/__init__.py",
    "content": "# tests directory\n"
  },
  {
    "path": "tests/conftest.py",
    "content": "# Import the fuctional fixtures as a plugin\n# Note: fixtures with session scope need to be local\n\npytest_plugins = [\"dbt.tests.fixtures.project\"]\n"
  },
  {
    "path": "tests/data/__init__.py",
    "content": "# tests/data directory\n"
  },
  {
    "path": "tests/fixtures/__init__.py",
    "content": "# fixtures directory\n"
  },
  {
    "path": "tests/fixtures/dbt_integration_project.py",
    "content": "import pytest\n\ndbt_integration_project__my_macros_sql = \"\"\"\n\n\n{% macro do_something(foo, bar) %}\n\n    select\n        '{{ foo }}'::text as foo,\n        '{{ bar }}'::text as bar\n\n{% endmacro %}\n\n\"\"\"\n\n\ndbt_integration_project__incremental_sql = \"\"\"\n\n-- TODO : add dist/sort keys\n{{\n    config(\n        materialized = 'incremental',\n        unique_key   = 'id',\n    )\n}}\n\n\nselect * from {{ this.schema }}.seed\n\n{% if is_incremental() %}\n    where updated_at > (select max(updated_at) from {{ this }})\n{% endif %}\n\"\"\"\n\n\ndbt_integration_project__schema_yml = \"\"\"\nversion: 2\nmodels:\n- name: table_model\n  columns:\n  - name: id\n    data_tests:\n    - unique\n\"\"\"\n\n\ndbt_integration_project__table_model_sql = \"\"\"\n\n-- TODO : add dist/sort keys\n{{\n    config(\n        materialized = 'table',\n    )\n}}\n\nselect * from {{ this.schema }}.seed\n\"\"\"\n\ndbt_integration_project__view_model_sql = \"\"\"\n{{\n    config(\n        materialized = 'view',\n    )\n}}\n\nselect * from {{ this.schema }}.seed\n\"\"\"\n\n\ndbt_integration_project__dbt_project_yml = \"\"\"\nname: dbt_integration_project\nversion: '1.0'\nconfig-version: 2\n\nmodel-paths: [\"models\"]    # paths to models\nanalysis-paths: [\"analyses\"] # path with analysis files which are compiled, but not run\ntarget-path: \"target\"      # path for compiled code\nclean-targets: [\"target\"]  # directories removed by the clean task\ntest-paths: [\"tests\"]       # where to store test results\nseed-paths: [\"seeds\"]       # load CSVs from this directory with `dbt seed`\nmacro-paths: [\"macros\"]    # where to find macros\n\nprofile: user\n\nmodels:\n    dbt_integration_project:\n\"\"\"\n\n\n@pytest.fixture(scope=\"class\")\ndef dbt_integration_project():\n    return {\n        \"dbt_project.yml\": dbt_integration_project__dbt_project_yml,\n        \"macros\": {\"my_macros.sql\": dbt_integration_project__my_macros_sql},\n        \"models\": {\n            \"incremental.sql\": dbt_integration_project__incremental_sql,\n            \"schema.yml\": dbt_integration_project__schema_yml,\n            \"table_model.sql\": dbt_integration_project__table_model_sql,\n            \"view_model.sql\": dbt_integration_project__view_model_sql,\n        },\n    }\n"
  },
  {
    "path": "tests/fixtures/jaffle_shop.py",
    "content": "import os\n\nimport pytest\n\nfrom dbt.tests.util import read_file\n\n# models/customers.sql\ncustomers_sql = \"\"\"\nwith customers as (\n\n    select * from {{ ref('stg_customers') }}\n\n),\n\norders as (\n\n    select * from {{ ref('stg_orders') }}\n\n),\n\npayments as (\n\n    select * from {{ ref('stg_payments') }}\n\n),\n\ncustomer_orders as (\n\n        select\n        customer_id,\n\n        min(order_date) as first_order,\n        max(order_date) as most_recent_order,\n        count(order_id) as number_of_orders\n    from orders\n\n    group by customer_id\n\n),\n\ncustomer_payments as (\n\n    select\n        orders.customer_id,\n        sum(amount) as total_amount\n\n    from payments\n\n    left join orders on\n         payments.order_id = orders.order_id\n\n    group by orders.customer_id\n\n),\n\nfinal as (\n\n    select\n        customers.customer_id,\n        customers.first_name,\n        customers.last_name,\n        customer_orders.first_order,\n        customer_orders.most_recent_order,\n        customer_orders.number_of_orders,\n        customer_payments.total_amount as customer_lifetime_value\n\n    from customers\n\n    left join customer_orders\n        on customers.customer_id = customer_orders.customer_id\n\n    left join customer_payments\n        on  customers.customer_id = customer_payments.customer_id\n\n)\n\nselect * from final\n\"\"\"\n\n# models/docs.md\ndocs_md = \"\"\"\n{% docs orders_status %}\n\nOrders can be one of the following statuses:\n\n| status         | description                                                                                                            |\n|----------------|------------------------------------------------------------------------------------------------------------------------|\n| placed         | The order has been placed but has not yet left the warehouse                                                           |\n| shipped        | The order has ben shipped to the customer and is currently in transit                                                  |\n| completed      | The order has been received by the customer                                                                            |\n| return_pending | The customer has indicated that they would like to return the order, but it has not yet been received at the warehouse |\n| returned       | The order has been returned by the customer and received at the warehouse                                              |\n\n\n{% enddocs %}\n\"\"\"\n\n# models/orders.sql\norders_sql = \"\"\"\n{% set payment_methods = ['credit_card', 'coupon', 'bank_transfer', 'gift_card'] %}\n\nwith orders as (\n\n    select * from {{ ref('stg_orders') }}\n\n),\n\npayments as (\n\n    select * from {{ ref('stg_payments') }}\n\n),\n\norder_payments as (\n\n    select\n        order_id,\n\n        {% for payment_method in payment_methods -%}\n        sum(case when payment_method = '{{ payment_method }}' then amount else 0 end) as {{ payment_method }}_amount,\n        {% endfor -%}\n\n        sum(amount) as total_amount\n\n    from payments\n\n    group by order_id\n\n),\n\nfinal as (\n\n    select\n        orders.order_id,\n        orders.customer_id,\n        orders.order_date,\n        orders.status,\n\n        {% for payment_method in payment_methods -%}\n\n        order_payments.{{ payment_method }}_amount,\n\n        {% endfor -%}\n\n        order_payments.total_amount as amount\n\n    from orders\n\n\n    left join order_payments\n        on orders.order_id = order_payments.order_id\n\n)\n\nselect * from final\n\"\"\"\n\n# models/overview.md\noverview_md = \"\"\"\n{% docs __overview__ %}\n\n## Data Documentation for Jaffle Shop\n\n`jaffle_shop` is a fictional ecommerce store.\n\nThis [dbt](https://www.getdbt.com/) project is for testing out code.\n\nThe source code can be found [here](https://github.com/clrcrl/jaffle_shop).\n\n{% enddocs %}\n\"\"\"\n\n# models/schema.yml\nschema_yml = \"\"\"\nversion: 2\n\nmodels:\n  - name: customers\n    description: This table has basic information about a customer, as well as some derived facts based on a customer's orders\n\n    columns:\n      - name: customer_id\n        description: This is a unique identifier for a customer\n        data_tests:\n          - unique\n          - not_null\n\n      - name: first_name\n        description: Customer's first name. PII.\n\n      - name: last_name\n        description: Customer's last name. PII.\n\n      - name: first_order\n        description: Date (UTC) of a customer's first order\n\n      - name: most_recent_order\n        description: Date (UTC) of a customer's most recent order\n\n      - name: number_of_orders\n        description: Count of the number of orders a customer has placed\n\n      - name: total_order_amount\n        description: Total value (AUD) of a customer's orders\n\n  - name: orders\n    description: This table has basic information about orders, as well as some derived facts based on payments\n\n    columns:\n      - name: order_id\n        data_tests:\n          - unique\n          - not_null\n        description: This is a unique identifier for an order\n\n      - name: customer_id\n        description: Foreign key to the customers table\n        data_tests:\n          - not_null\n          - relationships:\n              to: ref('customers')\n              field: customer_id\n\n      - name: order_date\n        description: Date (UTC) that the order was placed\n\n      - name: status\n        description: '{{ doc(\"orders_status\") }}'\n        data_tests:\n          - accepted_values:\n              values: ['placed', 'shipped', 'completed', 'return_pending', 'returned']\n\n      - name: amount\n        description: Total amount (AUD) of the order\n        data_tests:\n          - not_null\n\n      - name: credit_card_amount\n        description: Amount of the order (AUD) paid for by credit card\n        data_tests:\n          - not_null\n\n      - name: coupon_amount\n        description: Amount of the order (AUD) paid for by coupon\n        data_tests:\n          - not_null\n\n      - name: bank_transfer_amount\n        description: Amount of the order (AUD) paid for by bank transfer\n        data_tests:\n          - not_null\n\n      - name: gift_card_amount\n        description: Amount of the order (AUD) paid for by gift card\n        data_tests:\n          - not_null\n\"\"\"\n\n# models/staging/schema.yml\nstaging_schema_yml = \"\"\"\nversion: 2\n\nmodels:\n  - name: stg_customers\n    columns:\n      - name: customer_id\n        data_tests:\n          - unique\n          - not_null\n\n  - name: stg_orders\n    columns:\n      - name: order_id\n        data_tests:\n          - unique\n          - not_null\n      - name: status\n        data_tests:\n          - accepted_values:\n              values: ['placed', 'shipped', 'completed', 'return_pending', 'returned']\n\n  - name: stg_payments\n    columns:\n      - name: payment_id\n        data_tests:\n          - unique\n          - not_null\n      - name: payment_method\n        data_tests:\n          - accepted_values:\n              values: ['credit_card', 'coupon', 'bank_transfer', 'gift_card']\n\"\"\"\n\n# models/staging/stg_customers.sql\nstaging_stg_customers_sql = \"\"\"\nwith source as (\n\n    {#-\n    Normally we would select from the table here, but we are using seeds to load\n    our data in this project\n    #}\n    select * from {{ ref('raw_customers') }}\n\n),\n\nrenamed as (\n\n    select\n        id as customer_id,\n        first_name,\n        last_name\n\n    from source\n\n)\n\nselect * from renamed\n\"\"\"\n\n# models/staging/stg_orders.sql\nstaging_stg_orders_sql = \"\"\"\nwith source as (\n\n    {#-\n    Normally we would select from the table here, but we are using seeds to load\n    our data in this project\n    #}\n    select * from {{ ref('raw_orders') }}\n\n),\n\nrenamed as (\n\n    select\n        id as order_id,\n        user_id as customer_id,\n        order_date,\n        status\n\n    from source\n\n)\n\nselect * from renamed\n\"\"\"\n\n# models/staging/stg_payments.sql\nstaging_stg_payments_sql = \"\"\"\nwith source as (\n\n    {#-\n    Normally we would select from the table here, but we are using seeds to load\n    our data in this project\n    #}\n    select * from {{ ref('raw_payments') }}\n\n),\n\nrenamed as (\n\n    select\n        id as payment_id,\n        order_id,\n        payment_method,\n\n        -- `amount` is currently stored in cents, so we convert it to dollars\n        amount / 100 as amount\n\n    from source\n\n)\n\nselect * from renamed\n\"\"\"\n\n\nclass JaffleShopProject:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"customers.sql\": customers_sql,\n            \"docs.md\": docs_md,\n            \"orders.sql\": orders_sql,\n            \"ignored_model1.sql\": \"select 1 as id\",\n            \"ignored_model2.sql\": \"select 1 as id\",\n            \"overview.md\": overview_md,\n            \"schema.yml\": schema_yml,\n            \"ignore_folder\": {\n                \"model1.sql\": \"select 1 as id\",\n                \"model2.sql\": \"select 1 as id\",\n            },\n            \"staging\": {\n                \"schema.yml\": staging_schema_yml,\n                \"stg_customers.sql\": staging_stg_customers_sql,\n                \"stg_orders.sql\": staging_stg_orders_sql,\n                \"stg_payments.sql\": staging_stg_payments_sql,\n            },\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        # Read seed file and return\n        seeds = {}\n        dir_path = os.path.dirname(os.path.realpath(__file__))\n        for file_name in (\"raw_customers.csv\", \"raw_orders.csv\", \"raw_payments.csv\"):\n            contents = read_file(dir_path, \"jaffle_shop_data\", file_name)\n            seeds[file_name] = contents\n        return seeds\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"name\": \"jaffle_shop\",\n            \"models\": {\n                \"jaffle_shop\": {\n                    \"materialized\": \"table\",\n                    \"staging\": {\n                        \"materialized\": \"view\",\n                    },\n                }\n            },\n        }\n"
  },
  {
    "path": "tests/fixtures/jaffle_shop_data/.gitkeep",
    "content": ""
  },
  {
    "path": "tests/fixtures/jaffle_shop_data/raw_customers.csv",
    "content": "id,first_name,last_name\n1,Michael,P.\n2,Shawn,M.\n3,Kathleen,P.\n4,Jimmy,C.\n5,Katherine,R.\n6,Sarah,R.\n7,Martin,M.\n8,Frank,R.\n9,Jennifer,F.\n10,Henry,W.\n11,Fred,S.\n12,Amy,D.\n13,Kathleen,M.\n14,Steve,F.\n15,Teresa,H.\n16,Amanda,H.\n17,Kimberly,R.\n18,Johnny,K.\n19,Virginia,F.\n20,Anna,A.\n21,Willie,H.\n22,Sean,H.\n23,Mildred,A.\n24,David,G.\n25,Victor,H.\n26,Aaron,R.\n27,Benjamin,B.\n28,Lisa,W.\n29,Benjamin,K.\n30,Christina,W.\n31,Jane,G.\n32,Thomas,O.\n33,Katherine,M.\n34,Jennifer,S.\n35,Sara,T.\n36,Harold,O.\n37,Shirley,J.\n38,Dennis,J.\n39,Louise,W.\n40,Maria,A.\n41,Gloria,C.\n42,Diana,S.\n43,Kelly,N.\n44,Jane,R.\n45,Scott,B.\n46,Norma,C.\n47,Marie,P.\n48,Lillian,C.\n49,Judy,N.\n50,Billy,L.\n51,Howard,R.\n52,Laura,F.\n53,Anne,B.\n54,Rose,M.\n55,Nicholas,R.\n56,Joshua,K.\n57,Paul,W.\n58,Kathryn,K.\n59,Adam,A.\n60,Norma,W.\n61,Timothy,R.\n62,Elizabeth,P.\n63,Edward,G.\n64,David,C.\n65,Brenda,W.\n66,Adam,W.\n67,Michael,H.\n68,Jesse,E.\n69,Janet,P.\n70,Helen,F.\n71,Gerald,C.\n72,Kathryn,O.\n73,Alan,B.\n74,Harry,A.\n75,Andrea,H.\n76,Barbara,W.\n77,Anne,W.\n78,Harry,H.\n79,Jack,R.\n80,Phillip,H.\n81,Shirley,H.\n82,Arthur,D.\n83,Virginia,R.\n84,Christina,R.\n85,Theresa,M.\n86,Jason,C.\n87,Phillip,B.\n88,Adam,T.\n89,Margaret,J.\n90,Paul,P.\n91,Todd,W.\n92,Willie,O.\n93,Frances,R.\n94,Gregory,H.\n95,Lisa,P.\n96,Jacqueline,A.\n97,Shirley,D.\n98,Nicole,M.\n99,Mary,G.\n100,Jean,M.\n"
  },
  {
    "path": "tests/fixtures/jaffle_shop_data/raw_orders.csv",
    "content": "id,user_id,order_date,status\r\n1,1,2018-01-01,returned\r\n2,3,2018-01-02,completed\r\n3,94,2018-01-04,completed\r\n4,50,2018-01-05,completed\r\n5,64,2018-01-05,completed\r\n6,54,2018-01-07,completed\r\n7,88,2018-01-09,completed\r\n8,2,2018-01-11,returned\r\n9,53,2018-01-12,completed\r\n10,7,2018-01-14,completed\r\n11,99,2018-01-14,completed\r\n12,59,2018-01-15,completed\r\n13,84,2018-01-17,completed\r\n14,40,2018-01-17,returned\r\n15,25,2018-01-17,completed\r\n16,39,2018-01-18,completed\r\n17,71,2018-01-18,completed\r\n18,64,2018-01-20,returned\r\n19,54,2018-01-22,completed\r\n20,20,2018-01-23,completed\r\n21,71,2018-01-23,completed\r\n22,86,2018-01-24,completed\r\n23,22,2018-01-26,return_pending\r\n24,3,2018-01-27,completed\r\n25,51,2018-01-28,completed\r\n26,32,2018-01-28,completed\r\n27,94,2018-01-29,completed\r\n28,8,2018-01-29,completed\r\n29,57,2018-01-31,completed\r\n30,69,2018-02-02,completed\r\n31,16,2018-02-02,completed\r\n32,28,2018-02-04,completed\r\n33,42,2018-02-04,completed\r\n34,38,2018-02-06,completed\r\n35,80,2018-02-08,completed\r\n36,85,2018-02-10,completed\r\n37,1,2018-02-10,completed\r\n38,51,2018-02-10,completed\r\n39,26,2018-02-11,completed\r\n40,33,2018-02-13,completed\r\n41,99,2018-02-14,completed\r\n42,92,2018-02-16,completed\r\n43,31,2018-02-17,completed\r\n44,66,2018-02-17,completed\r\n45,22,2018-02-17,completed\r\n46,6,2018-02-19,completed\r\n47,50,2018-02-20,completed\r\n48,27,2018-02-21,completed\r\n49,35,2018-02-21,completed\r\n50,51,2018-02-23,completed\r\n51,71,2018-02-24,completed\r\n52,54,2018-02-25,return_pending\r\n53,34,2018-02-26,completed\r\n54,54,2018-02-26,completed\r\n55,18,2018-02-27,completed\r\n56,79,2018-02-28,completed\r\n57,93,2018-03-01,completed\r\n58,22,2018-03-01,completed\r\n59,30,2018-03-02,completed\r\n60,12,2018-03-03,completed\r\n61,63,2018-03-03,completed\r\n62,57,2018-03-05,completed\r\n63,70,2018-03-06,completed\r\n64,13,2018-03-07,completed\r\n65,26,2018-03-08,completed\r\n66,36,2018-03-10,completed\r\n67,79,2018-03-11,completed\r\n68,53,2018-03-11,completed\r\n69,3,2018-03-11,completed\r\n70,8,2018-03-12,completed\r\n71,42,2018-03-12,shipped\r\n72,30,2018-03-14,shipped\r\n73,19,2018-03-16,completed\r\n74,9,2018-03-17,shipped\r\n75,69,2018-03-18,completed\r\n76,25,2018-03-20,completed\r\n77,35,2018-03-21,shipped\r\n78,90,2018-03-23,shipped\r\n79,52,2018-03-23,shipped\r\n80,11,2018-03-23,shipped\r\n81,76,2018-03-23,shipped\r\n82,46,2018-03-24,shipped\r\n83,54,2018-03-24,shipped\r\n84,70,2018-03-26,placed\r\n85,47,2018-03-26,shipped\r\n86,68,2018-03-26,placed\r\n87,46,2018-03-27,placed\r\n88,91,2018-03-27,shipped\r\n89,21,2018-03-28,placed\r\n90,66,2018-03-30,shipped\r\n91,47,2018-03-31,placed\r\n92,84,2018-04-02,placed\r\n93,66,2018-04-03,placed\r\n94,63,2018-04-03,placed\r\n95,27,2018-04-04,placed\r\n96,90,2018-04-06,placed\r\n97,89,2018-04-07,placed\r\n98,41,2018-04-07,placed\r\n99,85,2018-04-09,placed\r\n"
  },
  {
    "path": "tests/fixtures/jaffle_shop_data/raw_payments.csv",
    "content": "id,order_id,payment_method,amount\n1,1,credit_card,1000\n2,2,credit_card,2000\n3,3,coupon,100\n4,4,coupon,2500\n5,5,bank_transfer,1700\n6,6,credit_card,600\n7,7,credit_card,1600\n8,8,credit_card,2300\n9,9,gift_card,2300\n10,9,bank_transfer,0\n11,10,bank_transfer,2600\n12,11,credit_card,2700\n13,12,credit_card,100\n14,13,credit_card,500\n15,13,bank_transfer,1400\n16,14,bank_transfer,300\n17,15,coupon,2200\n18,16,credit_card,1000\n19,17,bank_transfer,200\n20,18,credit_card,500\n21,18,credit_card,800\n22,19,gift_card,600\n23,20,bank_transfer,1500\n24,21,credit_card,1200\n25,22,bank_transfer,800\n26,23,gift_card,2300\n27,24,coupon,2600\n28,25,bank_transfer,2000\n29,25,credit_card,2200\n30,25,coupon,1600\n31,26,credit_card,3000\n32,27,credit_card,2300\n33,28,bank_transfer,1900\n34,29,bank_transfer,1200\n35,30,credit_card,1300\n36,31,credit_card,1200\n37,32,credit_card,300\n38,33,credit_card,2200\n39,34,bank_transfer,1500\n40,35,credit_card,2900\n41,36,bank_transfer,900\n42,37,credit_card,2300\n43,38,credit_card,1500\n44,39,bank_transfer,800\n45,40,credit_card,1400\n46,41,credit_card,1700\n47,42,coupon,1700\n48,43,gift_card,1800\n49,44,gift_card,1100\n50,45,bank_transfer,500\n51,46,bank_transfer,800\n52,47,credit_card,2200\n53,48,bank_transfer,300\n54,49,credit_card,600\n55,49,credit_card,900\n56,50,credit_card,2600\n57,51,credit_card,2900\n58,51,credit_card,100\n59,52,bank_transfer,1500\n60,53,credit_card,300\n61,54,credit_card,1800\n62,54,bank_transfer,1100\n63,55,credit_card,2900\n64,56,credit_card,400\n65,57,bank_transfer,200\n66,58,coupon,1800\n67,58,gift_card,600\n68,59,gift_card,2800\n69,60,credit_card,400\n70,61,bank_transfer,1600\n71,62,gift_card,1400\n72,63,credit_card,2900\n73,64,bank_transfer,2600\n74,65,credit_card,0\n75,66,credit_card,2800\n76,67,bank_transfer,400\n77,67,credit_card,1900\n78,68,credit_card,1600\n79,69,credit_card,1900\n80,70,credit_card,2600\n81,71,credit_card,500\n82,72,credit_card,2900\n83,73,bank_transfer,300\n84,74,credit_card,3000\n85,75,credit_card,1900\n86,76,coupon,200\n87,77,credit_card,0\n88,77,bank_transfer,1900\n89,78,bank_transfer,2600\n90,79,credit_card,1800\n91,79,credit_card,900\n92,80,gift_card,300\n93,81,coupon,200\n94,82,credit_card,800\n95,83,credit_card,100\n96,84,bank_transfer,2500\n97,85,bank_transfer,1700\n98,86,coupon,2300\n99,87,gift_card,3000\n100,87,credit_card,2600\n101,88,credit_card,2900\n102,89,bank_transfer,2200\n103,90,bank_transfer,200\n104,91,credit_card,1900\n105,92,bank_transfer,1500\n106,92,coupon,200\n107,93,gift_card,2600\n108,94,coupon,700\n109,95,coupon,2400\n110,96,gift_card,1700\n111,97,bank_transfer,1400\n112,98,bank_transfer,1000\n113,99,credit_card,2400\n"
  },
  {
    "path": "tests/functional/README.md",
    "content": "# This is where we are putting the pytest conversions of test/integration\n\n#  Goals of moving tests to pytest\n * Readability\n * Modularity\n * Easier to create and debug\n * Ability to create a project for external debugging\n\n# TODO\n * Create the ability to export a project\n * Explore using:\n   *  https://github.com/pytest-docker-compose/pytest-docker-compose or\n   *  https://github.com/avast/pytest-docker for automatically managing a postgres instance running in a docker container\n * Track test coverage (https://pytest-cov.readthedocs.io/en/latest)\n"
  },
  {
    "path": "tests/functional/__init__.py",
    "content": "# Functional tests focus on the business requirements of an application. They\n# only verify the output of an action and do not check the intermediate states\n# of the system when performing that action.\n"
  },
  {
    "path": "tests/functional/access/test_access.py",
    "content": "import pytest\n\nfrom dbt.exceptions import DbtReferenceError, InvalidAccessTypeError\nfrom dbt.node_types import AccessType\nfrom dbt.tests.fixtures.project import write_project_files\nfrom dbt.tests.util import get_manifest, rm_file, run_dbt, write_file\nfrom tests.fixtures.dbt_integration_project import dbt_integration_project  # noqa: F401\n\nmy_model_sql = \"select 1 as fun\"\n\nanother_model_sql = \"select 1234 as notfun\"\n\nyet_another_model_sql = \"select 999 as weird\"\n\nschema_yml = \"\"\"\nmodels:\n  - name: my_model\n    description: \"my model\"\n    access: public\n  - name: another_model\n    description: \"yet another model\"\n\"\"\"\n\nephemeral_schema_yml = \"\"\"\nmodels:\n  - name: my_model\n    description: \"my model\"\n    access: public\n    config:\n      materialized: ephemeral\n  - name: another_model\n    description: \"yet another model\"\n\"\"\"\n\nv2_schema_yml = \"\"\"\nmodels:\n  - name: my_model\n    description: \"my model\"\n    access: public\n  - name: another_model\n    description: \"another model\"\n  - name: yet_another_model\n    description: \"yet another model\"\n    access: unsupported\n\"\"\"\n\nref_my_model_sql = \"\"\"\n   select fun from {{ ref('my_model') }}\n\"\"\"\n\ngroups_yml = \"\"\"\ngroups:\n  - name: analytics\n    owner:\n      name: analytics_owner\n  - name: marts\n    owner:\n      name: marts_owner\n\"\"\"\n\n\nv3_schema_yml = \"\"\"\nmodels:\n  - name: my_model\n    description: \"my model\"\n    access: private\n    group: analytics\n  - name: another_model\n    description: \"yet another model\"\n  - name: ref_my_model\n    description: \"a model that refs my_model\"\n    group: analytics\n\"\"\"\n\nv4_schema_yml = \"\"\"\nmodels:\n  - name: my_model\n    description: \"my model\"\n    access: private\n    group: analytics\n  - name: another_model\n    description: \"yet another model\"\n  - name: ref_my_model\n    description: \"a model that refs my_model\"\n    group: marts\n\"\"\"\n\nsimple_exposure_yml = \"\"\"\nexposures:\n  - name: simple_exposure\n    label: simple exposure label\n    type: dashboard\n    depends_on:\n      - ref('my_model')\n    owner:\n      email: something@example.com\n\"\"\"\n\nv5_schema_yml = \"\"\"\nmodels:\n  - name: my_model\n    description: \"my model\"\n    access: private\n    group: analytics\n  - name: another_model\n    description: \"yet another model\"\n  - name: ref_my_model\n    description: \"a model that refs my_model\"\n    group: analytics\n  - name: people_model\n    description: \"some people\"\n    access: public\n    group: analytics\n\"\"\"\n\nv6_schema_yml = \"\"\"\nmodels:\n  - name: my_model\n    description: \"my model\"\n    config:\n      access: private\n      group: analytics\n  - name: another_model\n    description: \"yet another model\"\n  - name: ref_my_model\n    description: \"a model that refs my_model\"\n    config:\n      group: analytics\n  - name: people_model\n    description: \"some people\"\n    config:\n      access: public\n      group: analytics\n\"\"\"\n\npeople_model_sql = \"\"\"\nselect 1 as id, 'Drew' as first_name, 'Banin' as last_name, 'yellow' as favorite_color, true as loves_dbt, 5 as tenure, current_timestamp as created_at\nunion all\nselect 1 as id, 'Jeremy' as first_name, 'Cohen' as last_name, 'indigo' as favorite_color, true as loves_dbt, 4 as tenure, current_timestamp as created_at\nunion all\nselect 1 as id, 'Callum' as first_name, 'McCann' as last_name, 'emerald' as favorite_color, true as loves_dbt, 0 as tenure, current_timestamp as created_at\n\"\"\"\n\npeople_semantic_model_yml = \"\"\"\nsemantic_models:\n  - name: semantic_people\n    model: ref('people_model')\n    dimensions:\n      - name: favorite_color\n        type: categorical\n      - name: created_at\n        type: TIME\n        type_params:\n          time_granularity: day\n    measures:\n      - name: years_tenure\n        agg: SUM\n        expr: tenure\n      - name: people\n        agg: count\n        expr: id\n    entities:\n      - name: id\n        type: primary\n    defaults:\n      agg_time_dimension: created_at\n\"\"\"\n\npeople_metric_yml = \"\"\"\nmetrics:\n\n  - name: number_of_people\n    label: \"Number of people\"\n    description: Total count of people\n    type: simple\n    type_params:\n      measure: \"people\"\n    meta:\n        my_meta: 'testing'\n    config:\n      group: analytics\n\"\"\"\n\nv2_people_metric_yml = \"\"\"\nmetrics:\n\n  - name: number_of_people\n    label: \"Number of people\"\n    description: Total count of people\n    type: simple\n    type_params:\n      measure: \"people\"\n    meta:\n        my_meta: 'testing'\n    config:\n      group: marts\n\"\"\"\n\n\ndbt_integration_project__dbt_project_yml_restrited_access = \"\"\"\nname: dbt_integration_project\nversion: '1.0'\nconfig-version: 2\n\nmodel-paths: [\"models\"]    # paths to models\nanalysis-paths: [\"analyses\"] # path with analysis files which are compiled, but not run\ntarget-path: \"target\"      # path for compiled code\nclean-targets: [\"target\"]  # directories removed by the clean task\ntest-paths: [\"tests\"]       # where to store test results\nseed-paths: [\"seeds\"]       # load CSVs from this directory with `dbt seed`\nmacro-paths: [\"macros\"]    # where to find macros\n\nprofile: user\n\nmodels:\n    dbt_integration_project:\n\nrestrict-access: True\n\"\"\"\n\n\ndbt_integration_project__schema_yml_protected_model = \"\"\"\nversion: 2\nmodels:\n- name: table_model\n  access: protected\n\"\"\"\n\ndbt_integration_project__schema_yml_private_model = \"\"\"\nversion: 2\nmodels:\n- name: table_model\n  access: private\n  group: package\n\"\"\"\n\nref_package_model_sql = \"\"\"\n   select * from {{ ref('dbt_integration_project', 'table_model') }}\n\"\"\"\n\nschema_yml_ref_package_model = \"\"\"\nversion: 2\nmodels:\n- name: ref_package_model\n  group: package\n\"\"\"\n\nmetricflow_time_spine_sql = \"\"\"\nSELECT to_date('02/20/2023', 'mm/dd/yyyy') as date_day\n\"\"\"\n\n\nclass TestAccess:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": my_model_sql,\n            \"another_model.sql\": yet_another_model_sql,\n            \"schema.yml\": schema_yml,\n        }\n\n    def test_access_attribute(self, project):\n        manifest = run_dbt([\"parse\"])\n        assert len(manifest.nodes) == 2\n\n        my_model_id = \"model.test.my_model\"\n        another_model_id = \"model.test.another_model\"\n        assert my_model_id in manifest.nodes\n        assert another_model_id in manifest.nodes\n\n        assert manifest.nodes[my_model_id].access == AccessType.Public\n        assert manifest.nodes[another_model_id].access == AccessType.Protected\n\n        # write a file with invalid materialization for public access value\n        write_file(ephemeral_schema_yml, project.project_root, \"models\", \"schema.yml\")\n        with pytest.raises(InvalidAccessTypeError):\n            run_dbt([\"parse\"])\n\n        # write a file with an invalid access value\n        write_file(yet_another_model_sql, project.project_root, \"models\", \"yet_another_model.sql\")\n        write_file(v2_schema_yml, project.project_root, \"models\", \"schema.yml\")\n\n        with pytest.raises(InvalidAccessTypeError):\n            run_dbt([\"parse\"])\n\n        write_file(v2_schema_yml, project.project_root, \"models\", \"schema.yml\")\n        with pytest.raises(InvalidAccessTypeError):\n            run_dbt([\"parse\"])\n\n        # Remove invalid access files and write out model that refs my_model\n        rm_file(project.project_root, \"models\", \"yet_another_model.sql\")\n        write_file(schema_yml, project.project_root, \"models\", \"schema.yml\")\n        write_file(ref_my_model_sql, project.project_root, \"models\", \"ref_my_model.sql\")\n        manifest = run_dbt([\"parse\"])\n        assert len(manifest.nodes) == 3\n\n        # make my_model private, set same group on my_model and ref_my_model\n        write_file(groups_yml, project.project_root, \"models\", \"groups.yml\")\n        write_file(v3_schema_yml, project.project_root, \"models\", \"schema.yml\")\n        manifest = run_dbt([\"parse\"])\n        assert len(manifest.nodes) == 3\n        manifest = get_manifest(project.project_root)\n        ref_my_model_id = \"model.test.ref_my_model\"\n        assert manifest.nodes[my_model_id].group == \"analytics\"\n        assert manifest.nodes[ref_my_model_id].group == \"analytics\"\n\n        # Change group on ref_my_model and it should raise\n        write_file(v4_schema_yml, project.project_root, \"models\", \"schema.yml\")\n        with pytest.raises(DbtReferenceError):\n            run_dbt([\"parse\"])\n\n        # put back group on ref_my_model, add exposure with ref to private model\n        write_file(v3_schema_yml, project.project_root, \"models\", \"schema.yml\")\n        # verify it works again\n        manifest = run_dbt([\"parse\"])\n        assert len(manifest.nodes) == 3\n        # Write out exposure refing private my_model\n        write_file(simple_exposure_yml, project.project_root, \"models\", \"simple_exposure.yml\")\n        # Fails with reference error\n        with pytest.raises(DbtReferenceError):\n            run_dbt([\"parse\"])\n\n        # Remove exposure and add people model and metric file\n        write_file(v5_schema_yml, project.project_root, \"models\", \"schema.yml\")\n        rm_file(project.project_root, \"models\", \"simple_exposure.yml\")\n        write_file(people_model_sql, \"models\", \"people_model.sql\")\n        write_file(people_semantic_model_yml, \"models\", \"people_semantic_model.yml\")\n        write_file(people_metric_yml, \"models\", \"people_metric.yml\")\n        write_file(metricflow_time_spine_sql, \"models\", \"metricflow_time_spine.sql\")\n        # Should succeed\n        manifest = run_dbt([\"parse\"])\n        assert len(manifest.nodes) == 5\n        metric_id = \"metric.test.number_of_people\"\n        assert manifest.metrics[metric_id].group == \"analytics\"\n\n        # Use access and group in config\n        write_file(v5_schema_yml, project.project_root, \"models\", \"schema.yml\")\n        manifest = run_dbt([\"parse\"])\n        assert len(manifest.nodes) == 5\n        assert manifest.nodes[\"model.test.my_model\"].access == AccessType.Private\n        assert manifest.nodes[\"model.test.my_model\"].group == \"analytics\"\n        assert manifest.nodes[\"model.test.ref_my_model\"].access == AccessType.Protected\n        assert manifest.nodes[\"model.test.ref_my_model\"].group == \"analytics\"\n        assert manifest.nodes[\"model.test.people_model\"].access == AccessType.Public\n        assert manifest.nodes[\"model.test.people_model\"].group == \"analytics\"\n        assert manifest.nodes[\"model.test.another_model\"].access == AccessType.Protected\n        assert manifest.nodes[\"model.test.another_model\"].group is None\n\n\nclass TestUnrestrictedPackageAccess:\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project_root, dbt_integration_project):  # noqa: F811\n        write_project_files(project_root, \"dbt_integration_project\", dbt_integration_project)\n\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\"packages\": [{\"local\": \"dbt_integration_project\"}]}\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"ref_protected_package_model.sql\": ref_package_model_sql}\n\n    def test_unrestricted_protected_ref(self, project):\n        write_file(\n            dbt_integration_project__schema_yml_protected_model,\n            project.project_root,\n            \"dbt_integration_project\",\n            \"models\",\n            \"schema.yml\",\n        )\n        run_dbt([\"deps\"])\n\n        # Runs without issue because restrict-access defaults to False\n        manifest = run_dbt([\"parse\"])\n        assert len(manifest.nodes) == 4\n        root_project_model = manifest.nodes[\"model.test.ref_protected_package_model\"]\n        assert root_project_model.depends_on_nodes == [\"model.dbt_integration_project.table_model\"]\n\n\nclass TestRestrictedPackageAccess:\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project_root, dbt_integration_project):  # noqa: F811\n        write_project_files(project_root, \"dbt_integration_project\", dbt_integration_project)\n        # Set table_model.access to protected\n        write_file(\n            dbt_integration_project__schema_yml_protected_model,\n            project_root,\n            \"dbt_integration_project\",\n            \"models\",\n            \"schema.yml\",\n        )\n        # Set dbt_integration_project.restrict-access to True\n        write_file(\n            dbt_integration_project__dbt_project_yml_restrited_access,\n            project_root,\n            \"dbt_integration_project\",\n            \"dbt_project.yml\",\n        )\n\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\"packages\": [{\"local\": \"dbt_integration_project\"}]}\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"ref_package_model.sql\": ref_package_model_sql,\n            \"schema.yml\": schema_yml_ref_package_model,\n        }\n\n    def test_restricted_protected_ref(self, project):\n        run_dbt([\"deps\"])\n        with pytest.raises(DbtReferenceError):\n            run_dbt([\"parse\"])\n\n    def test_restricted_private_ref(self, project):\n        run_dbt([\"deps\"])\n\n        # Set table_model.access to private\n        write_file(\n            dbt_integration_project__schema_yml_private_model,\n            project.project_root,\n            \"dbt_integration_project\",\n            \"models\",\n            \"schema.yml\",\n        )\n\n        with pytest.raises(DbtReferenceError):\n            run_dbt([\"parse\"])\n\n\ndbt_project_yml = \"\"\"\nmodels:\n  test:\n    subdir_one:\n      +group: analytics\n      +access: private\n    subdir_two:\n      +group: marts\n      +access: public\n\"\"\"\n\n\nclass TestAccessDbtProjectConfig:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_one.sql\": my_model_sql,\n            \"subdir_one\": {\n                \"model_two.sql\": my_model_sql,\n            },\n            \"subdir_two\": {\n                \"model_three.sql\": my_model_sql,\n            },\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return dbt_project_yml\n\n    def test_dbt_project_access_config(self, project):\n        write_file(groups_yml, project.project_root, \"models\", \"groups.yml\")\n        manifest = run_dbt([\"parse\"])\n        model_one = manifest.nodes[\"model.test.model_one\"]\n        model_two = manifest.nodes[\"model.test.model_two\"]\n        model_three = manifest.nodes[\"model.test.model_three\"]\n        assert model_one.group is None\n        assert model_one.access == AccessType.Protected\n        assert model_two.group == \"analytics\"\n        assert model_two.access == AccessType.Private\n        assert model_three.group == \"marts\"\n        assert model_three.access == AccessType.Public\n\n\nmodels_yml = \"\"\"\nmodels:\n  - name: accounts\n    description: >\n      All accounts with whom we have done business. This is a very sensitive asset.\n    access: private\n    group: sales\n\n    columns:\n      - name: name\n        description: Name of the account.\n        tests:\n          - not_null\n          - unique\n\ngroups:\n  - name: sales\n    owner:\n      name: sales_owner\n\"\"\"\n\naccounts_sql = \"\"\"\nselect 'Jane' as name\n\"\"\"\n\n\nclass TestGenericTestRestrictAccess:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"models.yml\": models_yml,\n            \"accounts.sql\": accounts_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"restrict-access\": True,\n        }\n\n    def test_generic_tests(self, project):\n        run_dbt([\"run\"])\n        run_dbt([\"test\"])\n"
  },
  {
    "path": "tests/functional/analysis/test_analyses.py",
    "content": "import os\n\nimport pytest\n\nfrom dbt.tests.util import get_manifest, run_dbt\n\nmy_model_sql = \"\"\"\nselect 1 as id\n\"\"\"\n\nraw_stuff_sql = \"\"\"\n{% raw %}\n{% invalid jinja stuff %}\n{% endraw %}\n\"\"\"\n\nschema_yml = \"\"\"\nversion: 2\n\nanalyses:\n  - name: my_analysis\n    description: \"This is my analysis\"\n\"\"\"\n\nmy_analysis_sql = \"\"\"\nselect * from {{ ref('my_model') }}\n\"\"\"\n\n\nclass TestAnalyses:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"my_model.sql\": my_model_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def analyses(self):\n        return {\n            \"raw_stuff.sql\": raw_stuff_sql,\n            \"schema.yml\": schema_yml,\n            \"my_analysis.sql\": my_analysis_sql,\n        }\n\n    def assert_contents_equal(self, path, expected):\n        with open(path) as fp:\n            assert fp.read().strip() == expected\n\n    def test_postgres_analyses(self, project):\n        compiled_analysis_path = os.path.normpath(\"target/compiled/test/analyses\")\n        path_1 = os.path.join(compiled_analysis_path, \"my_analysis.sql\")\n        path_2 = os.path.join(compiled_analysis_path, \"raw_stuff.sql\")\n\n        run_dbt([\"clean\"])\n        assert not (os.path.exists(compiled_analysis_path))\n\n        results = run_dbt([\"compile\"])\n        assert len(results) == 3\n\n        manifest = get_manifest(project.project_root)\n        analysis_id = \"analysis.test.my_analysis\"\n        assert analysis_id in manifest.nodes\n\n        node = manifest.nodes[analysis_id]\n        assert node.description == \"This is my analysis\"\n\n        assert os.path.exists(path_1)\n        assert os.path.exists(path_2)\n\n        expected_sql = 'select * from \"{}\".\"{}\".\"my_model\"'.format(\n            project.database, project.test_schema\n        )\n        self.assert_contents_equal(path_1, expected_sql)\n        self.assert_contents_equal(path_2, \"{% invalid jinja stuff %}\")\n"
  },
  {
    "path": "tests/functional/artifacts/data/results/v4/run_results.json",
    "content": "{\"metadata\": {\"dbt_schema_version\": \"https://schemas.getdbt.com/dbt/run-results/v4.json\", \"dbt_version\": \"1.6.7\", \"generated_at\": \"2023-11-06T20:40:37.557735Z\", \"invocation_id\": \"42f85a60-4f7b-4cc1-a197-62687104fecc\", \"env\": {}}, \"results\": [{\"status\": \"success\", \"timing\": [{\"name\": \"compile\", \"started_at\": \"2023-11-06T20:40:37.486980Z\", \"completed_at\": \"2023-11-06T20:40:37.488837Z\"}, {\"name\": \"execute\", \"started_at\": \"2023-11-06T20:40:37.490290Z\", \"completed_at\": \"2023-11-06T20:40:37.539787Z\"}], \"thread_id\": \"Thread-9 (worker)\", \"execution_time\": 0.0566411018371582, \"adapter_response\": {\"_message\": \"CREATE VIEW\", \"code\": \"CREATE VIEW\", \"rows_affected\": -1}, \"message\": \"CREATE VIEW\", \"failures\": null, \"unique_id\": \"model.test.my_model\"}, {\"status\": \"success\", \"timing\": [{\"name\": \"compile\", \"started_at\": \"2023-11-06T20:40:37.485334Z\", \"completed_at\": \"2023-11-06T20:40:37.489266Z\"}, {\"name\": \"execute\", \"started_at\": \"2023-11-06T20:40:37.494545Z\", \"completed_at\": \"2023-11-06T20:40:37.542811Z\"}], \"thread_id\": \"Thread-8 (worker)\", \"execution_time\": 0.060118675231933594, \"adapter_response\": {\"_message\": \"CREATE VIEW\", \"code\": \"CREATE VIEW\", \"rows_affected\": -1}, \"message\": \"CREATE VIEW\", \"failures\": null, \"unique_id\": \"model.test.metricflow_time_spine\"}], \"elapsed_time\": 0.18144583702087402, \"args\": {\"defer\": false, \"indirect_selection\": \"eager\", \"select\": [], \"log_level_file\": \"debug\", \"use_colors\": true, \"cache_selected_only\": false, \"strict_mode\": false, \"use_colors_file\": true, \"partial_parse_file_diff\": true, \"static_parser\": true, \"write_json\": true, \"warn_error_options\": {\"include\": [], \"exclude\": []}, \"print\": true, \"log_level\": \"info\", \"profiles_dir\": \"/private/var/folders/7h/hj5_fw9j291c58hwfdvy5xbm0000gp/T/pytest-of-jerco/pytest-16/profile0\", \"log_path\": \"/Users/jerco/dev/product/dbt-core/logs/test16993032361853467608\", \"partial_parse\": true, \"quiet\": false, \"log_format_file\": \"debug\", \"version_check\": true, \"send_anonymous_usage_stats\": false, \"project_dir\": \"/private/var/folders/7h/hj5_fw9j291c58hwfdvy5xbm0000gp/T/pytest-of-jerco/pytest-16/project0\", \"log_format\": \"default\", \"enable_legacy_logger\": false, \"exclude\": [], \"populate_cache\": true, \"log_file_max_bytes\": 10485760, \"macro_debugging\": false, \"printer_width\": 80, \"invocation_command\": \"dbt tests/functional/artifacts/test_previous_version_state.py::TestPreviousVersionState\", \"which\": \"run\", \"favor_state\": false, \"introspect\": true, \"vars\": {}}}\n"
  },
  {
    "path": "tests/functional/artifacts/data/results/v5/run_results.json",
    "content": "{\"metadata\": {\"dbt_schema_version\": \"https://schemas.getdbt.com/dbt/run-results/v5.json\", \"dbt_version\": \"1.8.0a1\", \"generated_at\": \"2023-11-06T20:43:08.231028Z\", \"invocation_id\": \"a9238a29-6764-47f0-ba7d-f7d61ae5e6c0\", \"env\": {}}, \"results\": [{\"status\": \"success\", \"timing\": [{\"name\": \"compile\", \"started_at\": \"2023-11-06T20:43:08.146847Z\", \"completed_at\": \"2023-11-06T20:43:08.149862Z\"}, {\"name\": \"execute\", \"started_at\": \"2023-11-06T20:43:08.151676Z\", \"completed_at\": \"2023-11-06T20:43:08.206208Z\"}], \"thread_id\": \"Thread-9 (worker)\", \"execution_time\": 0.06433510780334473, \"adapter_response\": {\"_message\": \"CREATE VIEW\", \"code\": \"CREATE VIEW\", \"rows_affected\": -1}, \"message\": \"CREATE VIEW\", \"failures\": null, \"unique_id\": \"model.test.my_model\", \"compiled\": true, \"compiled_code\": \"select 1 as id\", \"relation_name\": \"\\\"dbt\\\".\\\"test16993033859513627134_test_previous_version_state\\\".\\\"my_model\\\"\"}, {\"status\": \"success\", \"timing\": [{\"name\": \"compile\", \"started_at\": \"2023-11-06T20:43:08.144982Z\", \"completed_at\": \"2023-11-06T20:43:08.150320Z\"}, {\"name\": \"execute\", \"started_at\": \"2023-11-06T20:43:08.155222Z\", \"completed_at\": \"2023-11-06T20:43:08.209881Z\"}], \"thread_id\": \"Thread-8 (worker)\", \"execution_time\": 0.06822013854980469, \"adapter_response\": {\"_message\": \"CREATE VIEW\", \"code\": \"CREATE VIEW\", \"rows_affected\": -1}, \"message\": \"CREATE VIEW\", \"failures\": null, \"unique_id\": \"model.test.metricflow_time_spine\", \"compiled\": true, \"compiled_code\": \"SELECT to_date('02/20/2023', 'mm/dd/yyyy') as date_day\", \"relation_name\": \"\\\"dbt\\\".\\\"test16993033859513627134_test_previous_version_state\\\".\\\"metricflow_time_spine\\\"\"}], \"elapsed_time\": 0.18284392356872559, \"args\": {\"send_anonymous_usage_stats\": false, \"profiles_dir\": \"/private/var/folders/7h/hj5_fw9j291c58hwfdvy5xbm0000gp/T/pytest-of-jerco/pytest-19/profile0\", \"static_parser\": true, \"partial_parse_file_diff\": true, \"printer_width\": 80, \"log_level_file\": \"debug\", \"project_dir\": \"/private/var/folders/7h/hj5_fw9j291c58hwfdvy5xbm0000gp/T/pytest-of-jerco/pytest-19/project0\", \"log_format\": \"default\", \"strict_mode\": false, \"macro_debugging\": false, \"indirect_selection\": \"eager\", \"version_check\": true, \"use_colors_file\": true, \"select\": [], \"log_file_max_bytes\": 10485760, \"warn_error_options\": {\"include\": [], \"exclude\": []}, \"log_format_file\": \"debug\", \"invocation_command\": \"dbt tests/functional/artifacts/test_previous_version_state.py::TestPreviousVersionState\", \"write_json\": true, \"log_level\": \"info\", \"cache_selected_only\": false, \"quiet\": false, \"favor_state\": false, \"enable_legacy_logger\": false, \"log_path\": \"/Users/jerco/dev/product/dbt-core/logs/test16993033859513627134\", \"which\": \"run\", \"partial_parse\": true, \"introspect\": true, \"show_resource_report\": false, \"exclude\": [], \"populate_cache\": true, \"vars\": {}, \"use_colors\": true, \"defer\": false, \"print\": true}}\n"
  },
  {
    "path": "tests/functional/artifacts/data/results/v6/run_results.json",
    "content": "{\"metadata\": {\"dbt_schema_version\": \"https://schemas.getdbt.com/dbt/run-results/v6.json\", \"dbt_version\": \"1.9.0a1\", \"generated_at\": \"2024-09-24T15:24:36.246406Z\", \"invocation_id\": \"ca07d2ca-054f-4ea1-be63-4acccfe4a6a7\", \"env\": {}}, \"results\": [{\"status\": \"success\", \"timing\": [{\"name\": \"compile\", \"started_at\": \"2024-09-24T15:24:36.181448Z\", \"completed_at\": \"2024-09-24T15:24:36.183192Z\"}, {\"name\": \"execute\", \"started_at\": \"2024-09-24T15:24:36.185536Z\", \"completed_at\": \"2024-09-24T15:24:36.231442Z\"}], \"thread_id\": \"Thread-9 (worker)\", \"execution_time\": 0.0535128116607666, \"adapter_response\": {\"_message\": \"CREATE VIEW\", \"code\": \"CREATE VIEW\", \"rows_affected\": -1}, \"message\": \"CREATE VIEW\", \"failures\": null, \"unique_id\": \"model.test.my_model\", \"compiled\": true, \"compiled_code\": \"select 1 as id\", \"relation_name\": \"\\\"dbt\\\".\\\"test17271914717676665882_test_previous_version_state\\\".\\\"my_model\\\"\", \"batch_results\": null}, {\"status\": \"success\", \"timing\": [{\"name\": \"compile\", \"started_at\": \"2024-09-24T15:24:36.179261Z\", \"completed_at\": \"2024-09-24T15:24:36.182955Z\"}, {\"name\": \"execute\", \"started_at\": \"2024-09-24T15:24:36.183455Z\", \"completed_at\": \"2024-09-24T15:24:36.232800Z\"}], \"thread_id\": \"Thread-8 (worker)\", \"execution_time\": 0.055058956146240234, \"adapter_response\": {\"_message\": \"CREATE VIEW\", \"code\": \"CREATE VIEW\", \"rows_affected\": -1}, \"message\": \"CREATE VIEW\", \"failures\": null, \"unique_id\": \"model.test.metricflow_time_spine\", \"compiled\": true, \"compiled_code\": \"SELECT to_date('02/20/2023', 'mm/dd/yyyy') as date_day\", \"relation_name\": \"\\\"dbt\\\".\\\"test17271914717676665882_test_previous_version_state\\\".\\\"metricflow_time_spine\\\"\", \"batch_results\": null}], \"elapsed_time\": 0.6437027454376221, \"args\": {\"profiles_dir\": \"/private/var/folders/79/5290gpvn3lx5jdryk4844rm80000gn/T/pytest-of-quigleymalcolm/pytest-139/profile0\", \"invocation_command\": \"dbt tests/functional/artifacts/test_previous_version_state.py\", \"strict_mode\": false, \"partial_parse_file_diff\": true, \"favor_state\": false, \"select\": [], \"log_level_file\": \"debug\", \"log_format_file\": \"debug\", \"which\": \"run\", \"introspect\": true, \"cache_selected_only\": false, \"log_level\": \"info\", \"defer\": false, \"static_parser\": true, \"macro_debugging\": false, \"write_json\": true, \"partial_parse\": true, \"version_check\": true, \"exclude\": [], \"use_colors_file\": true, \"indirect_selection\": \"eager\", \"project_dir\": \"/private/var/folders/79/5290gpvn3lx5jdryk4844rm80000gn/T/pytest-of-quigleymalcolm/pytest-139/project0\", \"require_resource_names_without_spaces\": false, \"warn_error_options\": {\"include\": [], \"exclude\": []}, \"log_path\": \"/Users/quigleymalcolm/Developer/dbt-labs/dbt-core/logs/test17271914717676665882\", \"printer_width\": 80, \"use_colors\": true, \"require_explicit_package_overrides_for_builtin_materializations\": true, \"show_resource_report\": false, \"quiet\": false, \"log_format\": \"default\", \"populate_cache\": true, \"send_anonymous_usage_stats\": false, \"source_freshness_run_project_hooks\": false, \"log_file_max_bytes\": 10485760, \"print\": true, \"vars\": {}, \"empty\": false}}\n"
  },
  {
    "path": "tests/functional/artifacts/data/state/v1/manifest.json",
    "content": "{\n    \"metadata\": {\n        \"dbt_schema_version\": \"https://schemas.getdbt.com/dbt/manifest/v1.json\",\n        \"dbt_version\": \"0.19.2\",\n        \"generated_at\": \"2022-06-08T05:12:57.550908Z\",\n        \"invocation_id\": \"57566e21-fbd4-4848-87ca-d05ddbd9012e\",\n        \"env\": {},\n        \"project_id\": \"098f6bcd4621d373cade4e832627b4f6\",\n        \"user_id\": null,\n        \"send_anonymous_usage_stats\": false,\n        \"adapter_type\": \"postgres\"\n    },\n    \"nodes\": {\n        \"model.test.my_model\": {\n            \"raw_sql\": \"select 1 as id\",\n            \"resource_type\": \"model\",\n            \"depends_on\": {\n                \"macros\": [],\n                \"nodes\": []\n            },\n            \"config\": {\n                \"enabled\": true,\n                \"materialized\": \"view\",\n                \"persist_docs\": {},\n                \"vars\": {},\n                \"quoting\": {},\n                \"column_types\": {},\n                \"alias\": null,\n                \"schema\": null,\n                \"database\": null,\n                \"tags\": [],\n                \"full_refresh\": null,\n                \"post-hook\": [],\n                \"pre-hook\": []\n            },\n            \"database\": \"jerco\",\n            \"schema\": \"dbt_jcohen\",\n            \"fqn\": [\n                \"test\",\n                \"my_model\"\n            ],\n            \"unique_id\": \"model.test.my_model\",\n            \"package_name\": \"test\",\n            \"root_path\": \"/Users/jerco/dev/scratch/testy\",\n            \"path\": \"my_model.sql\",\n            \"original_file_path\": \"models/my_model.sql\",\n            \"name\": \"my_model\",\n            \"alias\": \"my_model\",\n            \"checksum\": {\n                \"name\": \"sha256\",\n                \"checksum\": \"479636cb85ce8d3b0f8db5ff13cf338b61254ad98d905630eac61f963e719e9d\"\n            },\n            \"tags\": [],\n            \"refs\": [],\n            \"sources\": [],\n            \"description\": \"\",\n            \"columns\": {},\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"build_path\": null,\n            \"deferred\": false,\n            \"unrendered_config\": {}\n        }\n    },\n    \"sources\": {},\n    \"macros\": {\n        \"macro.test.drop_relation\": {\n            \"unique_id\": \"macro.test.drop_relation\",\n            \"package_name\": \"test\",\n            \"root_path\": \"/Users/jerco/dev/scratch/testy\",\n            \"path\": \"macros/whatever.sql\",\n            \"original_file_path\": \"macros/whatever.sql\",\n            \"name\": \"drop_relation\",\n            \"macro_sql\": \"{% macro drop_relation(relation) -%}\\n  {{ return(dbt_labs_materialized_views.drop_relation(relation)) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.test.drop_relation\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.test.postgres__list_relations_without_caching\": {\n            \"unique_id\": \"macro.test.postgres__list_relations_without_caching\",\n            \"package_name\": \"test\",\n            \"root_path\": \"/Users/jerco/dev/scratch/testy\",\n            \"path\": \"macros/whatever.sql\",\n            \"original_file_path\": \"macros/whatever.sql\",\n            \"name\": \"postgres__list_relations_without_caching\",\n            \"macro_sql\": \"{% macro postgres__list_relations_without_caching(schema_relation) %}\\n  {{ return(dbt_labs_materialized_views.postgres__list_relations_without_caching(schema_relation)) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.test.postgres__list_relations_without_caching\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.test.postgres_get_relations\": {\n            \"unique_id\": \"macro.test.postgres_get_relations\",\n            \"package_name\": \"test\",\n            \"root_path\": \"/Users/jerco/dev/scratch/testy\",\n            \"path\": \"macros/whatever.sql\",\n            \"original_file_path\": \"macros/whatever.sql\",\n            \"name\": \"postgres_get_relations\",\n            \"macro_sql\": \"{% macro postgres_get_relations() %}\\n  {{ return(dbt_labs_materialized_views.postgres_get_relations()) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.test.postgres_get_relations\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.test.redshift__list_relations_without_caching\": {\n            \"unique_id\": \"macro.test.redshift__list_relations_without_caching\",\n            \"package_name\": \"test\",\n            \"root_path\": \"/Users/jerco/dev/scratch/testy\",\n            \"path\": \"macros/whatever.sql\",\n            \"original_file_path\": \"macros/whatever.sql\",\n            \"name\": \"redshift__list_relations_without_caching\",\n            \"macro_sql\": \"{% macro redshift__list_relations_without_caching(schema_relation) %}\\n  {{ return(dbt_labs_materialized_views.redshift__list_relations_without_caching(schema_relation)) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.test.redshift__list_relations_without_caching\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.test.load_relation\": {\n            \"unique_id\": \"macro.test.load_relation\",\n            \"package_name\": \"test\",\n            \"root_path\": \"/Users/jerco/dev/scratch/testy\",\n            \"path\": \"macros/whatever.sql\",\n            \"original_file_path\": \"macros/whatever.sql\",\n            \"name\": \"load_relation\",\n            \"macro_sql\": \"{% macro load_relation(relation) %}\\n  {{ return(dbt_labs_materialized_views.redshift_load_relation_or_mv(relation)) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt_postgres.postgres__get_catalog\": {\n            \"unique_id\": \"macro.dbt_postgres.postgres__get_catalog\",\n            \"package_name\": \"dbt_postgres\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\",\n            \"path\": \"macros/catalog.sql\",\n            \"original_file_path\": \"macros/catalog.sql\",\n            \"name\": \"postgres__get_catalog\",\n            \"macro_sql\": \"{% macro postgres__get_catalog(information_schema, schemas) -%}\\n\\n  {%- call statement('catalog', fetch_result=True) -%}\\n    {#\\n      If the user has multiple databases set and the first one is wrong, this will fail.\\n      But we won't fail in the case where there are multiple quoting-difference-only dbs, which is better.\\n    #}\\n    {% set database = information_schema.database %}\\n    {{ adapter.verify_database(database) }}\\n\\n    select\\n        '{{ database }}' as table_database,\\n        sch.nspname as table_schema,\\n        tbl.relname as table_name,\\n        case tbl.relkind\\n            when 'v' then 'VIEW'\\n            else 'BASE TABLE'\\n        end as table_type,\\n        tbl_desc.description as table_comment,\\n        col.attname as column_name,\\n        col.attnum as column_index,\\n        pg_catalog.format_type(col.atttypid, col.atttypmod) as column_type,\\n        col_desc.description as column_comment,\\n        pg_get_userbyid(tbl.relowner) as table_owner\\n\\n    from pg_catalog.pg_namespace sch\\n    join pg_catalog.pg_class tbl on tbl.relnamespace = sch.oid\\n    join pg_catalog.pg_attribute col on col.attrelid = tbl.oid\\n    left outer join pg_catalog.pg_description tbl_desc on (tbl_desc.objoid = tbl.oid and tbl_desc.objsubid = 0)\\n    left outer join pg_catalog.pg_description col_desc on (col_desc.objoid = tbl.oid and col_desc.objsubid = col.attnum)\\n\\n    where (\\n        {%- for schema in schemas -%}\\n          upper(sch.nspname) = upper('{{ schema }}'){%- if not loop.last %} or {% endif -%}\\n        {%- endfor -%}\\n      )\\n      and not pg_is_other_temp_schema(sch.oid) -- not a temporary schema belonging to another session\\n      and tbl.relpersistence = 'p' -- [p]ermanent table. Other values are [u]nlogged table, [t]emporary table\\n      and tbl.relkind in ('r', 'v', 'f', 'p') -- o[r]dinary table, [v]iew, [f]oreign table, [p]artitioned table. Other values are [i]ndex, [S]equence, [c]omposite type, [t]OAST table, [m]aterialized view\\n      and col.attnum > 0 -- negative numbers are used for system columns such as oid\\n      and not col.attisdropped -- column as not been dropped\\n\\n    order by\\n        sch.nspname,\\n        tbl.relname,\\n        col.attnum\\n\\n  {%- endcall -%}\\n\\n  {{ return(load_result('catalog').table) }}\\n\\n{%- endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.statement\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt_postgres.postgres_get_relations\": {\n            \"unique_id\": \"macro.dbt_postgres.postgres_get_relations\",\n            \"package_name\": \"dbt_postgres\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\",\n            \"path\": \"macros/relations.sql\",\n            \"original_file_path\": \"macros/relations.sql\",\n            \"name\": \"postgres_get_relations\",\n            \"macro_sql\": \"{% macro postgres_get_relations () -%}\\n\\n  {#\\n      -- in pg_depend, objid is the dependent, refobjid is the referenced object\\n      --  > a pg_depend entry indicates that the referenced object cannot be\\n      --  > dropped without also dropping the dependent object.\\n  #}\\n\\n  {%- call statement('relations', fetch_result=True) -%}\\n    with relation as (\\n        select\\n            pg_rewrite.ev_class as class,\\n            pg_rewrite.oid as id\\n        from pg_rewrite\\n    ),\\n    class as (\\n        select\\n            oid as id,\\n            relname as name,\\n            relnamespace as schema,\\n            relkind as kind\\n        from pg_class\\n    ),\\n    dependency as (\\n        select\\n            pg_depend.objid as id,\\n            pg_depend.refobjid as ref\\n        from pg_depend\\n    ),\\n    schema as (\\n        select\\n            pg_namespace.oid as id,\\n            pg_namespace.nspname as name\\n        from pg_namespace\\n        where nspname != 'information_schema' and nspname not like 'pg\\\\_%'\\n    ),\\n    referenced as (\\n        select\\n            relation.id AS id,\\n            referenced_class.name ,\\n            referenced_class.schema ,\\n            referenced_class.kind\\n        from relation\\n        join class as referenced_class on relation.class=referenced_class.id\\n        where referenced_class.kind in ('r', 'v')\\n    ),\\n    relationships as (\\n        select\\n            referenced.name as referenced_name,\\n            referenced.schema as referenced_schema_id,\\n            dependent_class.name as dependent_name,\\n            dependent_class.schema as dependent_schema_id,\\n            referenced.kind as kind\\n        from referenced\\n        join dependency on referenced.id=dependency.id\\n        join class as dependent_class on dependency.ref=dependent_class.id\\n        where\\n            (referenced.name != dependent_class.name or\\n             referenced.schema != dependent_class.schema)\\n    )\\n\\n    select\\n        referenced_schema.name as referenced_schema,\\n        relationships.referenced_name as referenced_name,\\n        dependent_schema.name as dependent_schema,\\n        relationships.dependent_name as dependent_name\\n    from relationships\\n    join schema as dependent_schema on relationships.dependent_schema_id=dependent_schema.id\\n    join schema as referenced_schema on relationships.referenced_schema_id=referenced_schema.id\\n    group by referenced_schema, referenced_name, dependent_schema, dependent_name\\n    order by referenced_schema, referenced_name, dependent_schema, dependent_name;\\n\\n  {%- endcall -%}\\n\\n  {{ return(load_result('relations').table) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.statement\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt_postgres.postgres__create_table_as\": {\n            \"unique_id\": \"macro.dbt_postgres.postgres__create_table_as\",\n            \"package_name\": \"dbt_postgres\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\",\n            \"path\": \"macros/adapters.sql\",\n            \"original_file_path\": \"macros/adapters.sql\",\n            \"name\": \"postgres__create_table_as\",\n            \"macro_sql\": \"{% macro postgres__create_table_as(temporary, relation, sql) -%}\\n  {%- set unlogged = config.get('unlogged', default=false) -%}\\n  {%- set sql_header = config.get('sql_header', none) -%}\\n\\n  {{ sql_header if sql_header is not none }}\\n\\n  create {% if temporary -%}\\n    temporary\\n  {%- elif unlogged -%}\\n    unlogged\\n  {%- endif %} table {{ relation }}\\n  as (\\n    {{ sql }}\\n  );\\n{%- endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt_postgres.postgres__create_schema\": {\n            \"unique_id\": \"macro.dbt_postgres.postgres__create_schema\",\n            \"package_name\": \"dbt_postgres\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\",\n            \"path\": \"macros/adapters.sql\",\n            \"original_file_path\": \"macros/adapters.sql\",\n            \"name\": \"postgres__create_schema\",\n            \"macro_sql\": \"{% macro postgres__create_schema(relation) -%}\\n  {% if relation.database -%}\\n    {{ adapter.verify_database(relation.database) }}\\n  {%- endif -%}\\n  {%- call statement('create_schema') -%}\\n    create schema if not exists {{ relation.without_identifier().include(database=False) }}\\n  {%- endcall -%}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.statement\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt_postgres.postgres__drop_schema\": {\n            \"unique_id\": \"macro.dbt_postgres.postgres__drop_schema\",\n            \"package_name\": \"dbt_postgres\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\",\n            \"path\": \"macros/adapters.sql\",\n            \"original_file_path\": \"macros/adapters.sql\",\n            \"name\": \"postgres__drop_schema\",\n            \"macro_sql\": \"{% macro postgres__drop_schema(relation) -%}\\n  {% if relation.database -%}\\n    {{ adapter.verify_database(relation.database) }}\\n  {%- endif -%}\\n  {%- call statement('drop_schema') -%}\\n    drop schema if exists {{ relation.without_identifier().include(database=False) }} cascade\\n  {%- endcall -%}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.statement\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt_postgres.postgres__get_columns_in_relation\": {\n            \"unique_id\": \"macro.dbt_postgres.postgres__get_columns_in_relation\",\n            \"package_name\": \"dbt_postgres\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\",\n            \"path\": \"macros/adapters.sql\",\n            \"original_file_path\": \"macros/adapters.sql\",\n            \"name\": \"postgres__get_columns_in_relation\",\n            \"macro_sql\": \"{% macro postgres__get_columns_in_relation(relation) -%}\\n  {% call statement('get_columns_in_relation', fetch_result=True) %}\\n      select\\n          column_name,\\n          data_type,\\n          character_maximum_length,\\n          numeric_precision,\\n          numeric_scale\\n\\n      from {{ relation.information_schema('columns') }}\\n      where table_name = '{{ relation.identifier }}'\\n        {% if relation.schema %}\\n        and table_schema = '{{ relation.schema }}'\\n        {% endif %}\\n      order by ordinal_position\\n\\n  {% endcall %}\\n  {% set table = load_result('get_columns_in_relation').table %}\\n  {{ return(sql_convert_columns_in_relation(table)) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.statement\",\n                    \"macro.dbt.sql_convert_columns_in_relation\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt_postgres.postgres__list_relations_without_caching\": {\n            \"unique_id\": \"macro.dbt_postgres.postgres__list_relations_without_caching\",\n            \"package_name\": \"dbt_postgres\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\",\n            \"path\": \"macros/adapters.sql\",\n            \"original_file_path\": \"macros/adapters.sql\",\n            \"name\": \"postgres__list_relations_without_caching\",\n            \"macro_sql\": \"{% macro postgres__list_relations_without_caching(schema_relation) %}\\n  {% call statement('list_relations_without_caching', fetch_result=True) -%}\\n    select\\n      '{{ schema_relation.database }}' as database,\\n      tablename as name,\\n      schemaname as schema,\\n      'table' as type\\n    from pg_tables\\n    where schemaname ilike '{{ schema_relation.schema }}'\\n    union all\\n    select\\n      '{{ schema_relation.database }}' as database,\\n      viewname as name,\\n      schemaname as schema,\\n      'view' as type\\n    from pg_views\\n    where schemaname ilike '{{ schema_relation.schema }}'\\n  {% endcall %}\\n  {{ return(load_result('list_relations_without_caching').table) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.statement\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt_postgres.postgres__information_schema_name\": {\n            \"unique_id\": \"macro.dbt_postgres.postgres__information_schema_name\",\n            \"package_name\": \"dbt_postgres\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\",\n            \"path\": \"macros/adapters.sql\",\n            \"original_file_path\": \"macros/adapters.sql\",\n            \"name\": \"postgres__information_schema_name\",\n            \"macro_sql\": \"{% macro postgres__information_schema_name(database) -%}\\n  {% if database_name -%}\\n    {{ adapter.verify_database(database_name) }}\\n  {%- endif -%}\\n  information_schema\\n{%- endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt_postgres.postgres__list_schemas\": {\n            \"unique_id\": \"macro.dbt_postgres.postgres__list_schemas\",\n            \"package_name\": \"dbt_postgres\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\",\n            \"path\": \"macros/adapters.sql\",\n            \"original_file_path\": \"macros/adapters.sql\",\n            \"name\": \"postgres__list_schemas\",\n            \"macro_sql\": \"{% macro postgres__list_schemas(database) %}\\n  {% if database -%}\\n    {{ adapter.verify_database(database) }}\\n  {%- endif -%}\\n  {% call statement('list_schemas', fetch_result=True, auto_begin=False) %}\\n    select distinct nspname from pg_namespace\\n  {% endcall %}\\n  {{ return(load_result('list_schemas').table) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.statement\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt_postgres.postgres__check_schema_exists\": {\n            \"unique_id\": \"macro.dbt_postgres.postgres__check_schema_exists\",\n            \"package_name\": \"dbt_postgres\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\",\n            \"path\": \"macros/adapters.sql\",\n            \"original_file_path\": \"macros/adapters.sql\",\n            \"name\": \"postgres__check_schema_exists\",\n            \"macro_sql\": \"{% macro postgres__check_schema_exists(information_schema, schema) -%}\\n  {% if information_schema.database -%}\\n    {{ adapter.verify_database(information_schema.database) }}\\n  {%- endif -%}\\n  {% call statement('check_schema_exists', fetch_result=True, auto_begin=False) %}\\n    select count(*) from pg_namespace where nspname = '{{ schema }}'\\n  {% endcall %}\\n  {{ return(load_result('check_schema_exists').table) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.statement\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt_postgres.postgres__current_timestamp\": {\n            \"unique_id\": \"macro.dbt_postgres.postgres__current_timestamp\",\n            \"package_name\": \"dbt_postgres\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\",\n            \"path\": \"macros/adapters.sql\",\n            \"original_file_path\": \"macros/adapters.sql\",\n            \"name\": \"postgres__current_timestamp\",\n            \"macro_sql\": \"{% macro postgres__current_timestamp() -%}\\n  now()\\n{%- endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt_postgres.postgres__snapshot_string_as_time\": {\n            \"unique_id\": \"macro.dbt_postgres.postgres__snapshot_string_as_time\",\n            \"package_name\": \"dbt_postgres\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\",\n            \"path\": \"macros/adapters.sql\",\n            \"original_file_path\": \"macros/adapters.sql\",\n            \"name\": \"postgres__snapshot_string_as_time\",\n            \"macro_sql\": \"{% macro postgres__snapshot_string_as_time(timestamp) -%}\\n    {%- set result = \\\"'\\\" ~ timestamp ~ \\\"'::timestamp without time zone\\\" -%}\\n    {{ return(result) }}\\n{%- endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt_postgres.postgres__snapshot_get_time\": {\n            \"unique_id\": \"macro.dbt_postgres.postgres__snapshot_get_time\",\n            \"package_name\": \"dbt_postgres\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\",\n            \"path\": \"macros/adapters.sql\",\n            \"original_file_path\": \"macros/adapters.sql\",\n            \"name\": \"postgres__snapshot_get_time\",\n            \"macro_sql\": \"{% macro postgres__snapshot_get_time() -%}\\n  {{ current_timestamp() }}::timestamp without time zone\\n{%- endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.current_timestamp\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt_postgres.postgres__make_temp_relation\": {\n            \"unique_id\": \"macro.dbt_postgres.postgres__make_temp_relation\",\n            \"package_name\": \"dbt_postgres\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\",\n            \"path\": \"macros/adapters.sql\",\n            \"original_file_path\": \"macros/adapters.sql\",\n            \"name\": \"postgres__make_temp_relation\",\n            \"macro_sql\": \"{% macro postgres__make_temp_relation(base_relation, suffix) %}\\n    {% set dt = modules.datetime.datetime.now() %}\\n    {% set dtstring = dt.strftime(\\\"%H%M%S%f\\\") %}\\n    {% set suffix_length = suffix|length + dtstring|length %}\\n    {% set relation_max_name_length = 63 %}\\n    {% if suffix_length > relation_max_name_length %}\\n        {% do exceptions.raise_compiler_error('Temp relation suffix is too long (' ~ suffix|length ~ ' characters). Maximum length is ' ~ (relation_max_name_length - dtstring|length) ~ ' characters.') %}\\n    {% endif %}\\n    {% set tmp_identifier = base_relation.identifier[:relation_max_name_length - suffix_length] ~ suffix ~ dtstring %}\\n    {% do return(base_relation.incorporate(\\n                                  path={\\n                                    \\\"identifier\\\": tmp_identifier,\\n                                    \\\"schema\\\": none,\\n                                    \\\"database\\\": none\\n                                  })) -%}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt_postgres.postgres_escape_comment\": {\n            \"unique_id\": \"macro.dbt_postgres.postgres_escape_comment\",\n            \"package_name\": \"dbt_postgres\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\",\n            \"path\": \"macros/adapters.sql\",\n            \"original_file_path\": \"macros/adapters.sql\",\n            \"name\": \"postgres_escape_comment\",\n            \"macro_sql\": \"{% macro postgres_escape_comment(comment) -%}\\n  {% if comment is not string %}\\n    {% do exceptions.raise_compiler_error('cannot escape a non-string: ' ~ comment) %}\\n  {% endif %}\\n  {%- set magic = '$dbt_comment_literal_block$' -%}\\n  {%- if magic in comment -%}\\n    {%- do exceptions.raise_compiler_error('The string ' ~ magic ~ ' is not allowed in comments.') -%}\\n  {%- endif -%}\\n  {{ magic }}{{ comment }}{{ magic }}\\n{%- endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt_postgres.postgres__alter_relation_comment\": {\n            \"unique_id\": \"macro.dbt_postgres.postgres__alter_relation_comment\",\n            \"package_name\": \"dbt_postgres\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\",\n            \"path\": \"macros/adapters.sql\",\n            \"original_file_path\": \"macros/adapters.sql\",\n            \"name\": \"postgres__alter_relation_comment\",\n            \"macro_sql\": \"{% macro postgres__alter_relation_comment(relation, comment) %}\\n  {% set escaped_comment = postgres_escape_comment(comment) %}\\n  comment on {{ relation.type }} {{ relation }} is {{ escaped_comment }};\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt_postgres.postgres_escape_comment\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt_postgres.postgres__alter_column_comment\": {\n            \"unique_id\": \"macro.dbt_postgres.postgres__alter_column_comment\",\n            \"package_name\": \"dbt_postgres\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\",\n            \"path\": \"macros/adapters.sql\",\n            \"original_file_path\": \"macros/adapters.sql\",\n            \"name\": \"postgres__alter_column_comment\",\n            \"macro_sql\": \"{% macro postgres__alter_column_comment(relation, column_dict) %}\\n  {% for column_name in column_dict %}\\n    {% set comment = column_dict[column_name]['description'] %}\\n    {% set escaped_comment = postgres_escape_comment(comment) %}\\n    comment on column {{ relation }}.{{ adapter.quote(column_name) if column_dict[column_name]['quote'] else column_name }} is {{ escaped_comment }};\\n  {% endfor %}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt_postgres.postgres_escape_comment\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt_postgres.postgres__snapshot_merge_sql\": {\n            \"unique_id\": \"macro.dbt_postgres.postgres__snapshot_merge_sql\",\n            \"package_name\": \"dbt_postgres\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\",\n            \"path\": \"macros/materializations/snapshot_merge.sql\",\n            \"original_file_path\": \"macros/materializations/snapshot_merge.sql\",\n            \"name\": \"postgres__snapshot_merge_sql\",\n            \"macro_sql\": \"{% macro postgres__snapshot_merge_sql(target, source, insert_cols) -%}\\n    {%- set insert_cols_csv = insert_cols | join(', ') -%}\\n\\n    update {{ target }}\\n    set dbt_valid_to = DBT_INTERNAL_SOURCE.dbt_valid_to\\n    from {{ source }} as DBT_INTERNAL_SOURCE\\n    where DBT_INTERNAL_SOURCE.dbt_scd_id::text = {{ target }}.dbt_scd_id::text\\n      and DBT_INTERNAL_SOURCE.dbt_change_type::text in ('update'::text, 'delete'::text)\\n      and {{ target }}.dbt_valid_to is null;\\n\\n    insert into {{ target }} ({{ insert_cols_csv }})\\n    select {% for column in insert_cols -%}\\n        DBT_INTERNAL_SOURCE.{{ column }} {%- if not loop.last %}, {%- endif %}\\n    {%- endfor %}\\n    from {{ source }} as DBT_INTERNAL_SOURCE\\n    where DBT_INTERNAL_SOURCE.dbt_change_type::text = 'insert'::text;\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.statement\": {\n            \"unique_id\": \"macro.dbt.statement\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/core.sql\",\n            \"original_file_path\": \"macros/core.sql\",\n            \"name\": \"statement\",\n            \"macro_sql\": \"{% macro statement(name=None, fetch_result=False, auto_begin=True) -%}\\n  {%- if execute: -%}\\n    {%- set sql = caller() -%}\\n\\n    {%- if name == 'main' -%}\\n      {{ log('Writing runtime SQL for node \\\"{}\\\"'.format(model['unique_id'])) }}\\n      {{ write(sql) }}\\n    {%- endif -%}\\n\\n    {%- set res, table = adapter.execute(sql, auto_begin=auto_begin, fetch=fetch_result) -%}\\n    {%- if name is not none -%}\\n      {{ store_result(name, response=res, agate_table=table) }}\\n    {%- endif -%}\\n\\n  {%- endif -%}\\n{%- endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.noop_statement\": {\n            \"unique_id\": \"macro.dbt.noop_statement\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/core.sql\",\n            \"original_file_path\": \"macros/core.sql\",\n            \"name\": \"noop_statement\",\n            \"macro_sql\": \"{% macro noop_statement(name=None, message=None, code=None, rows_affected=None, res=None) -%}\\n  {%- set sql = caller() -%}\\n\\n  {%- if name == 'main' -%}\\n    {{ log('Writing runtime SQL for node \\\"{}\\\"'.format(model['unique_id'])) }}\\n    {{ write(sql) }}\\n  {%- endif -%}\\n\\n  {%- if name is not none -%}\\n    {{ store_raw_result(name, message=message, code=code, rows_affected=rows_affected, agate_table=res) }}\\n  {%- endif -%}\\n\\n{%- endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.run_hooks\": {\n            \"unique_id\": \"macro.dbt.run_hooks\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/helpers.sql\",\n            \"original_file_path\": \"macros/materializations/helpers.sql\",\n            \"name\": \"run_hooks\",\n            \"macro_sql\": \"{% macro run_hooks(hooks, inside_transaction=True) %}\\n  {% for hook in hooks | selectattr('transaction', 'equalto', inside_transaction)  %}\\n    {% if not inside_transaction and loop.first %}\\n      {% call statement(auto_begin=inside_transaction) %}\\n        commit;\\n      {% endcall %}\\n    {% endif %}\\n    {% set rendered = render(hook.get('sql')) | trim %}\\n    {% if (rendered | length) > 0 %}\\n      {% call statement(auto_begin=inside_transaction) %}\\n        {{ rendered }}\\n      {% endcall %}\\n    {% endif %}\\n  {% endfor %}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.statement\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.column_list\": {\n            \"unique_id\": \"macro.dbt.column_list\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/helpers.sql\",\n            \"original_file_path\": \"macros/materializations/helpers.sql\",\n            \"name\": \"column_list\",\n            \"macro_sql\": \"{% macro column_list(columns) %}\\n  {%- for col in columns %}\\n    {{ col.name }} {% if not loop.last %},{% endif %}\\n  {% endfor -%}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.column_list_for_create_table\": {\n            \"unique_id\": \"macro.dbt.column_list_for_create_table\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/helpers.sql\",\n            \"original_file_path\": \"macros/materializations/helpers.sql\",\n            \"name\": \"column_list_for_create_table\",\n            \"macro_sql\": \"{% macro column_list_for_create_table(columns) %}\\n  {%- for col in columns %}\\n    {{ col.name }} {{ col.data_type }} {%- if not loop.last %},{% endif %}\\n  {% endfor -%}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.make_hook_config\": {\n            \"unique_id\": \"macro.dbt.make_hook_config\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/helpers.sql\",\n            \"original_file_path\": \"macros/materializations/helpers.sql\",\n            \"name\": \"make_hook_config\",\n            \"macro_sql\": \"{% macro make_hook_config(sql, inside_transaction) %}\\n    {{ tojson({\\\"sql\\\": sql, \\\"transaction\\\": inside_transaction}) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.before_begin\": {\n            \"unique_id\": \"macro.dbt.before_begin\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/helpers.sql\",\n            \"original_file_path\": \"macros/materializations/helpers.sql\",\n            \"name\": \"before_begin\",\n            \"macro_sql\": \"{% macro before_begin(sql) %}\\n    {{ make_hook_config(sql, inside_transaction=False) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.make_hook_config\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.in_transaction\": {\n            \"unique_id\": \"macro.dbt.in_transaction\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/helpers.sql\",\n            \"original_file_path\": \"macros/materializations/helpers.sql\",\n            \"name\": \"in_transaction\",\n            \"macro_sql\": \"{% macro in_transaction(sql) %}\\n    {{ make_hook_config(sql, inside_transaction=True) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.make_hook_config\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.after_commit\": {\n            \"unique_id\": \"macro.dbt.after_commit\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/helpers.sql\",\n            \"original_file_path\": \"macros/materializations/helpers.sql\",\n            \"name\": \"after_commit\",\n            \"macro_sql\": \"{% macro after_commit(sql) %}\\n    {{ make_hook_config(sql, inside_transaction=False) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.make_hook_config\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.drop_relation_if_exists\": {\n            \"unique_id\": \"macro.dbt.drop_relation_if_exists\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/helpers.sql\",\n            \"original_file_path\": \"macros/materializations/helpers.sql\",\n            \"name\": \"drop_relation_if_exists\",\n            \"macro_sql\": \"{% macro drop_relation_if_exists(relation) %}\\n  {% if relation is not none %}\\n    {{ adapter.drop_relation(relation) }}\\n  {% endif %}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.load_relation\": {\n            \"unique_id\": \"macro.dbt.load_relation\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/helpers.sql\",\n            \"original_file_path\": \"macros/materializations/helpers.sql\",\n            \"name\": \"load_relation\",\n            \"macro_sql\": \"{% macro load_relation(relation) %}\\n  {% do return(adapter.get_relation(\\n    database=relation.database,\\n    schema=relation.schema,\\n    identifier=relation.identifier\\n  )) -%}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.should_full_refresh\": {\n            \"unique_id\": \"macro.dbt.should_full_refresh\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/helpers.sql\",\n            \"original_file_path\": \"macros/materializations/helpers.sql\",\n            \"name\": \"should_full_refresh\",\n            \"macro_sql\": \"{% macro should_full_refresh() %}\\n  {% set config_full_refresh = config.get('full_refresh') %}\\n  {% if config_full_refresh is none %}\\n    {% set config_full_refresh = flags.FULL_REFRESH %}\\n  {% endif %}\\n  {% do return(config_full_refresh) %}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.snapshot_merge_sql\": {\n            \"unique_id\": \"macro.dbt.snapshot_merge_sql\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/snapshot/snapshot_merge.sql\",\n            \"original_file_path\": \"macros/materializations/snapshot/snapshot_merge.sql\",\n            \"name\": \"snapshot_merge_sql\",\n            \"macro_sql\": \"{% macro snapshot_merge_sql(target, source, insert_cols) -%}\\n  {{ adapter.dispatch('snapshot_merge_sql')(target, source, insert_cols) }}\\n{%- endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt_postgres.postgres__snapshot_merge_sql\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.default__snapshot_merge_sql\": {\n            \"unique_id\": \"macro.dbt.default__snapshot_merge_sql\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/snapshot/snapshot_merge.sql\",\n            \"original_file_path\": \"macros/materializations/snapshot/snapshot_merge.sql\",\n            \"name\": \"default__snapshot_merge_sql\",\n            \"macro_sql\": \"{% macro default__snapshot_merge_sql(target, source, insert_cols) -%}\\n    {%- set insert_cols_csv = insert_cols | join(', ') -%}\\n\\n    merge into {{ target }} as DBT_INTERNAL_DEST\\n    using {{ source }} as DBT_INTERNAL_SOURCE\\n    on DBT_INTERNAL_SOURCE.dbt_scd_id = DBT_INTERNAL_DEST.dbt_scd_id\\n\\n    when matched\\n     and DBT_INTERNAL_DEST.dbt_valid_to is null\\n     and DBT_INTERNAL_SOURCE.dbt_change_type in ('update', 'delete')\\n        then update\\n        set dbt_valid_to = DBT_INTERNAL_SOURCE.dbt_valid_to\\n\\n    when not matched\\n     and DBT_INTERNAL_SOURCE.dbt_change_type = 'insert'\\n        then insert ({{ insert_cols_csv }})\\n        values ({{ insert_cols_csv }})\\n    ;\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.strategy_dispatch\": {\n            \"unique_id\": \"macro.dbt.strategy_dispatch\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/snapshot/strategies.sql\",\n            \"original_file_path\": \"macros/materializations/snapshot/strategies.sql\",\n            \"name\": \"strategy_dispatch\",\n            \"macro_sql\": \"{% macro strategy_dispatch(name) -%}\\n{% set original_name = name %}\\n  {% if '.' in name %}\\n    {% set package_name, name = name.split(\\\".\\\", 1) %}\\n  {% else %}\\n    {% set package_name = none %}\\n  {% endif %}\\n\\n  {% if package_name is none %}\\n    {% set package_context = context %}\\n  {% elif package_name in context %}\\n    {% set package_context = context[package_name] %}\\n  {% else %}\\n    {% set error_msg %}\\n        Could not find package '{{package_name}}', called with '{{original_name}}'\\n    {% endset %}\\n    {{ exceptions.raise_compiler_error(error_msg | trim) }}\\n  {% endif %}\\n\\n  {%- set search_name = 'snapshot_' ~ name ~ '_strategy' -%}\\n\\n  {% if search_name not in package_context %}\\n    {% set error_msg %}\\n        The specified strategy macro '{{name}}' was not found in package '{{ package_name }}'\\n    {% endset %}\\n    {{ exceptions.raise_compiler_error(error_msg | trim) }}\\n  {% endif %}\\n  {{ return(package_context[search_name]) }}\\n{%- endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.snapshot_hash_arguments\": {\n            \"unique_id\": \"macro.dbt.snapshot_hash_arguments\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/snapshot/strategies.sql\",\n            \"original_file_path\": \"macros/materializations/snapshot/strategies.sql\",\n            \"name\": \"snapshot_hash_arguments\",\n            \"macro_sql\": \"{% macro snapshot_hash_arguments(args) -%}\\n  {{ adapter.dispatch('snapshot_hash_arguments')(args) }}\\n{%- endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.default__snapshot_hash_arguments\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.default__snapshot_hash_arguments\": {\n            \"unique_id\": \"macro.dbt.default__snapshot_hash_arguments\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/snapshot/strategies.sql\",\n            \"original_file_path\": \"macros/materializations/snapshot/strategies.sql\",\n            \"name\": \"default__snapshot_hash_arguments\",\n            \"macro_sql\": \"{% macro default__snapshot_hash_arguments(args) -%}\\n    md5({%- for arg in args -%}\\n        coalesce(cast({{ arg }} as varchar ), '')\\n        {% if not loop.last %} || '|' || {% endif %}\\n    {%- endfor -%})\\n{%- endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.snapshot_get_time\": {\n            \"unique_id\": \"macro.dbt.snapshot_get_time\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/snapshot/strategies.sql\",\n            \"original_file_path\": \"macros/materializations/snapshot/strategies.sql\",\n            \"name\": \"snapshot_get_time\",\n            \"macro_sql\": \"{% macro snapshot_get_time() -%}\\n  {{ adapter.dispatch('snapshot_get_time')() }}\\n{%- endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt_postgres.postgres__snapshot_get_time\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.default__snapshot_get_time\": {\n            \"unique_id\": \"macro.dbt.default__snapshot_get_time\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/snapshot/strategies.sql\",\n            \"original_file_path\": \"macros/materializations/snapshot/strategies.sql\",\n            \"name\": \"default__snapshot_get_time\",\n            \"macro_sql\": \"{% macro default__snapshot_get_time() -%}\\n  {{ current_timestamp() }}\\n{%- endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.current_timestamp\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.snapshot_timestamp_strategy\": {\n            \"unique_id\": \"macro.dbt.snapshot_timestamp_strategy\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/snapshot/strategies.sql\",\n            \"original_file_path\": \"macros/materializations/snapshot/strategies.sql\",\n            \"name\": \"snapshot_timestamp_strategy\",\n            \"macro_sql\": \"{% macro snapshot_timestamp_strategy(node, snapshotted_rel, current_rel, config, target_exists) %}\\n    {% set primary_key = config['unique_key'] %}\\n    {% set updated_at = config['updated_at'] %}\\n    {% set invalidate_hard_deletes = config.get('invalidate_hard_deletes', false) %}\\n\\n    {#/*\\n        The snapshot relation might not have an {{ updated_at }} value if the\\n        snapshot strategy is changed from `check` to `timestamp`. We\\n        should use a dbt-created column for the comparison in the snapshot\\n        table instead of assuming that the user-supplied {{ updated_at }}\\n        will be present in the historical data.\\n\\n        See https://github.com/fishtown-analytics/dbt/issues/2350\\n    */ #}\\n    {% set row_changed_expr -%}\\n        ({{ snapshotted_rel }}.dbt_valid_from < {{ current_rel }}.{{ updated_at }})\\n    {%- endset %}\\n\\n    {% set scd_id_expr = snapshot_hash_arguments([primary_key, updated_at]) %}\\n\\n    {% do return({\\n        \\\"unique_key\\\": primary_key,\\n        \\\"updated_at\\\": updated_at,\\n        \\\"row_changed\\\": row_changed_expr,\\n        \\\"scd_id\\\": scd_id_expr,\\n        \\\"invalidate_hard_deletes\\\": invalidate_hard_deletes\\n    }) %}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.snapshot_hash_arguments\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.snapshot_string_as_time\": {\n            \"unique_id\": \"macro.dbt.snapshot_string_as_time\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/snapshot/strategies.sql\",\n            \"original_file_path\": \"macros/materializations/snapshot/strategies.sql\",\n            \"name\": \"snapshot_string_as_time\",\n            \"macro_sql\": \"{% macro snapshot_string_as_time(timestamp) -%}\\n    {{ adapter.dispatch('snapshot_string_as_time')(timestamp) }}\\n{%- endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt_postgres.postgres__snapshot_string_as_time\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.default__snapshot_string_as_time\": {\n            \"unique_id\": \"macro.dbt.default__snapshot_string_as_time\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/snapshot/strategies.sql\",\n            \"original_file_path\": \"macros/materializations/snapshot/strategies.sql\",\n            \"name\": \"default__snapshot_string_as_time\",\n            \"macro_sql\": \"{% macro default__snapshot_string_as_time(timestamp) %}\\n    {% do exceptions.raise_not_implemented(\\n        'snapshot_string_as_time macro not implemented for adapter '+adapter.type()\\n    ) %}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.snapshot_check_all_get_existing_columns\": {\n            \"unique_id\": \"macro.dbt.snapshot_check_all_get_existing_columns\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/snapshot/strategies.sql\",\n            \"original_file_path\": \"macros/materializations/snapshot/strategies.sql\",\n            \"name\": \"snapshot_check_all_get_existing_columns\",\n            \"macro_sql\": \"{% macro snapshot_check_all_get_existing_columns(node, target_exists) -%}\\n    {%- set query_columns = get_columns_in_query(node['compiled_sql']) -%}\\n    {%- if not target_exists -%}\\n        {# no table yet -> return whatever the query does #}\\n        {{ return([false, query_columns]) }}\\n    {%- endif -%}\\n    {# handle any schema changes #}\\n    {%- set target_table = node.get('alias', node.get('name')) -%}\\n    {%- set target_relation = adapter.get_relation(database=node.database, schema=node.schema, identifier=target_table) -%}\\n    {%- set existing_cols = get_columns_in_query('select * from ' ~ target_relation) -%}\\n    {%- set ns = namespace() -%} {# handle for-loop scoping with a namespace #}\\n    {%- set ns.column_added = false -%}\\n\\n    {%- set intersection = [] -%}\\n    {%- for col in query_columns -%}\\n        {%- if col in existing_cols -%}\\n            {%- do intersection.append(col) -%}\\n        {%- else -%}\\n            {% set ns.column_added = true %}\\n        {%- endif -%}\\n    {%- endfor -%}\\n    {{ return([ns.column_added, intersection]) }}\\n{%- endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.get_columns_in_query\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.snapshot_check_strategy\": {\n            \"unique_id\": \"macro.dbt.snapshot_check_strategy\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/snapshot/strategies.sql\",\n            \"original_file_path\": \"macros/materializations/snapshot/strategies.sql\",\n            \"name\": \"snapshot_check_strategy\",\n            \"macro_sql\": \"{% macro snapshot_check_strategy(node, snapshotted_rel, current_rel, config, target_exists) %}\\n    {% set check_cols_config = config['check_cols'] %}\\n    {% set primary_key = config['unique_key'] %}\\n    {% set invalidate_hard_deletes = config.get('invalidate_hard_deletes', false) %}\\n    \\n    {% set select_current_time -%}\\n        select {{ snapshot_get_time() }} as snapshot_start\\n    {%- endset %}\\n\\n    {#-- don't access the column by name, to avoid dealing with casing issues on snowflake #}\\n    {%- set now = run_query(select_current_time)[0][0] -%}\\n    {% if now is none or now is undefined -%}\\n        {%- do exceptions.raise_compiler_error('Could not get a snapshot start time from the database') -%}\\n    {%- endif %}\\n    {% set updated_at = snapshot_string_as_time(now) %}\\n\\n    {% set column_added = false %}\\n\\n    {% if check_cols_config == 'all' %}\\n        {% set column_added, check_cols = snapshot_check_all_get_existing_columns(node, target_exists) %}\\n    {% elif check_cols_config is iterable and (check_cols_config | length) > 0 %}\\n        {% set check_cols = check_cols_config %}\\n    {% else %}\\n        {% do exceptions.raise_compiler_error(\\\"Invalid value for 'check_cols': \\\" ~ check_cols_config) %}\\n    {% endif %}\\n\\n    {%- set row_changed_expr -%}\\n    (\\n    {%- if column_added -%}\\n        TRUE\\n    {%- else -%}\\n    {%- for col in check_cols -%}\\n        {{ snapshotted_rel }}.{{ col }} != {{ current_rel }}.{{ col }}\\n        or\\n        (\\n            (({{ snapshotted_rel }}.{{ col }} is null) and not ({{ current_rel }}.{{ col }} is null))\\n            or\\n            ((not {{ snapshotted_rel }}.{{ col }} is null) and ({{ current_rel }}.{{ col }} is null))\\n        )\\n        {%- if not loop.last %} or {% endif -%}\\n    {%- endfor -%}\\n    {%- endif -%}\\n    )\\n    {%- endset %}\\n\\n    {% set scd_id_expr = snapshot_hash_arguments([primary_key, updated_at]) %}\\n\\n    {% do return({\\n        \\\"unique_key\\\": primary_key,\\n        \\\"updated_at\\\": updated_at,\\n        \\\"row_changed\\\": row_changed_expr,\\n        \\\"scd_id\\\": scd_id_expr,\\n        \\\"invalidate_hard_deletes\\\": invalidate_hard_deletes\\n    }) %}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.snapshot_get_time\",\n                    \"macro.dbt.run_query\",\n                    \"macro.dbt.snapshot_string_as_time\",\n                    \"macro.dbt.snapshot_check_all_get_existing_columns\",\n                    \"macro.dbt.snapshot_hash_arguments\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.create_columns\": {\n            \"unique_id\": \"macro.dbt.create_columns\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/snapshot/snapshot.sql\",\n            \"original_file_path\": \"macros/materializations/snapshot/snapshot.sql\",\n            \"name\": \"create_columns\",\n            \"macro_sql\": \"{% macro create_columns(relation, columns) %}\\n  {{ adapter.dispatch('create_columns')(relation, columns) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.default__create_columns\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.default__create_columns\": {\n            \"unique_id\": \"macro.dbt.default__create_columns\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/snapshot/snapshot.sql\",\n            \"original_file_path\": \"macros/materializations/snapshot/snapshot.sql\",\n            \"name\": \"default__create_columns\",\n            \"macro_sql\": \"{% macro default__create_columns(relation, columns) %}\\n  {% for column in columns %}\\n    {% call statement() %}\\n      alter table {{ relation }} add column \\\"{{ column.name }}\\\" {{ column.data_type }};\\n    {% endcall %}\\n  {% endfor %}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.statement\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.post_snapshot\": {\n            \"unique_id\": \"macro.dbt.post_snapshot\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/snapshot/snapshot.sql\",\n            \"original_file_path\": \"macros/materializations/snapshot/snapshot.sql\",\n            \"name\": \"post_snapshot\",\n            \"macro_sql\": \"{% macro post_snapshot(staging_relation) %}\\n  {{ adapter.dispatch('post_snapshot')(staging_relation) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.default__post_snapshot\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.default__post_snapshot\": {\n            \"unique_id\": \"macro.dbt.default__post_snapshot\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/snapshot/snapshot.sql\",\n            \"original_file_path\": \"macros/materializations/snapshot/snapshot.sql\",\n            \"name\": \"default__post_snapshot\",\n            \"macro_sql\": \"{% macro default__post_snapshot(staging_relation) %}\\n    {# no-op #}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.snapshot_staging_table\": {\n            \"unique_id\": \"macro.dbt.snapshot_staging_table\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/snapshot/snapshot.sql\",\n            \"original_file_path\": \"macros/materializations/snapshot/snapshot.sql\",\n            \"name\": \"snapshot_staging_table\",\n            \"macro_sql\": \"{% macro snapshot_staging_table(strategy, source_sql, target_relation) -%}\\n\\n    with snapshot_query as (\\n\\n        {{ source_sql }}\\n\\n    ),\\n\\n    snapshotted_data as (\\n\\n        select *,\\n            {{ strategy.unique_key }} as dbt_unique_key\\n\\n        from {{ target_relation }}\\n        where dbt_valid_to is null\\n\\n    ),\\n\\n    insertions_source_data as (\\n\\n        select\\n            *,\\n            {{ strategy.unique_key }} as dbt_unique_key,\\n            {{ strategy.updated_at }} as dbt_updated_at,\\n            {{ strategy.updated_at }} as dbt_valid_from,\\n            nullif({{ strategy.updated_at }}, {{ strategy.updated_at }}) as dbt_valid_to,\\n            {{ strategy.scd_id }} as dbt_scd_id\\n\\n        from snapshot_query\\n    ),\\n\\n    updates_source_data as (\\n\\n        select\\n            *,\\n            {{ strategy.unique_key }} as dbt_unique_key,\\n            {{ strategy.updated_at }} as dbt_updated_at,\\n            {{ strategy.updated_at }} as dbt_valid_from,\\n            {{ strategy.updated_at }} as dbt_valid_to\\n\\n        from snapshot_query\\n    ),\\n\\n    {%- if strategy.invalidate_hard_deletes %}\\n\\n    deletes_source_data as (\\n\\n        select \\n            *,\\n            {{ strategy.unique_key }} as dbt_unique_key\\n        from snapshot_query\\n    ),\\n    {% endif %}\\n\\n    insertions as (\\n\\n        select\\n            'insert' as dbt_change_type,\\n            source_data.*\\n\\n        from insertions_source_data as source_data\\n        left outer join snapshotted_data on snapshotted_data.dbt_unique_key = source_data.dbt_unique_key\\n        where snapshotted_data.dbt_unique_key is null\\n           or (\\n                snapshotted_data.dbt_unique_key is not null\\n            and (\\n                {{ strategy.row_changed }}\\n            )\\n        )\\n\\n    ),\\n\\n    updates as (\\n\\n        select\\n            'update' as dbt_change_type,\\n            source_data.*,\\n            snapshotted_data.dbt_scd_id\\n\\n        from updates_source_data as source_data\\n        join snapshotted_data on snapshotted_data.dbt_unique_key = source_data.dbt_unique_key\\n        where (\\n            {{ strategy.row_changed }}\\n        )\\n    )\\n\\n    {%- if strategy.invalidate_hard_deletes -%}\\n    ,\\n\\n    deletes as (\\n    \\n        select\\n            'delete' as dbt_change_type,\\n            source_data.*,\\n            {{ snapshot_get_time() }} as dbt_valid_from,\\n            {{ snapshot_get_time() }} as dbt_updated_at,\\n            {{ snapshot_get_time() }} as dbt_valid_to,\\n            snapshotted_data.dbt_scd_id\\n    \\n        from snapshotted_data\\n        left join deletes_source_data as source_data on snapshotted_data.dbt_unique_key = source_data.dbt_unique_key\\n        where source_data.dbt_unique_key is null\\n    )\\n    {%- endif %}\\n\\n    select * from insertions\\n    union all\\n    select * from updates\\n    {%- if strategy.invalidate_hard_deletes %}\\n    union all\\n    select * from deletes\\n    {%- endif %}\\n\\n{%- endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.snapshot_get_time\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.build_snapshot_table\": {\n            \"unique_id\": \"macro.dbt.build_snapshot_table\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/snapshot/snapshot.sql\",\n            \"original_file_path\": \"macros/materializations/snapshot/snapshot.sql\",\n            \"name\": \"build_snapshot_table\",\n            \"macro_sql\": \"{% macro build_snapshot_table(strategy, sql) %}\\n\\n    select *,\\n        {{ strategy.scd_id }} as dbt_scd_id,\\n        {{ strategy.updated_at }} as dbt_updated_at,\\n        {{ strategy.updated_at }} as dbt_valid_from,\\n        nullif({{ strategy.updated_at }}, {{ strategy.updated_at }}) as dbt_valid_to\\n    from (\\n        {{ sql }}\\n    ) sbq\\n\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.get_or_create_relation\": {\n            \"unique_id\": \"macro.dbt.get_or_create_relation\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/snapshot/snapshot.sql\",\n            \"original_file_path\": \"macros/materializations/snapshot/snapshot.sql\",\n            \"name\": \"get_or_create_relation\",\n            \"macro_sql\": \"{% macro get_or_create_relation(database, schema, identifier, type) %}\\n  {%- set target_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) %}\\n\\n  {% if target_relation %}\\n    {% do return([true, target_relation]) %}\\n  {% endif %}\\n\\n  {%- set new_relation = api.Relation.create(\\n      database=database,\\n      schema=schema,\\n      identifier=identifier,\\n      type=type\\n  ) -%}\\n  {% do return([false, new_relation]) %}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.build_snapshot_staging_table\": {\n            \"unique_id\": \"macro.dbt.build_snapshot_staging_table\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/snapshot/snapshot.sql\",\n            \"original_file_path\": \"macros/materializations/snapshot/snapshot.sql\",\n            \"name\": \"build_snapshot_staging_table\",\n            \"macro_sql\": \"{% macro build_snapshot_staging_table(strategy, sql, target_relation) %}\\n    {% set tmp_relation = make_temp_relation(target_relation) %}\\n\\n    {% set select = snapshot_staging_table(strategy, sql, target_relation) %}\\n\\n    {% call statement('build_snapshot_staging_relation') %}\\n        {{ create_table_as(True, tmp_relation, select) }}\\n    {% endcall %}\\n\\n    {% do return(tmp_relation) %}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.make_temp_relation\",\n                    \"macro.dbt.snapshot_staging_table\",\n                    \"macro.dbt.statement\",\n                    \"macro.dbt.create_table_as\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.materialization_snapshot_default\": {\n            \"unique_id\": \"macro.dbt.materialization_snapshot_default\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/snapshot/snapshot.sql\",\n            \"original_file_path\": \"macros/materializations/snapshot/snapshot.sql\",\n            \"name\": \"materialization_snapshot_default\",\n            \"macro_sql\": \"{% materialization snapshot, default %}\\n  {%- set config = model['config'] -%}\\n\\n  {%- set target_table = model.get('alias', model.get('name')) -%}\\n\\n  {%- set strategy_name = config.get('strategy') -%}\\n  {%- set unique_key = config.get('unique_key') %}\\n\\n  {% if not adapter.check_schema_exists(model.database, model.schema) %}\\n    {% do create_schema(model.database, model.schema) %}\\n  {% endif %}\\n\\n  {% set target_relation_exists, target_relation = get_or_create_relation(\\n          database=model.database,\\n          schema=model.schema,\\n          identifier=target_table,\\n          type='table') -%}\\n\\n  {%- if not target_relation.is_table -%}\\n    {% do exceptions.relation_wrong_type(target_relation, 'table') %}\\n  {%- endif -%}\\n\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  {% set strategy_macro = strategy_dispatch(strategy_name) %}\\n  {% set strategy = strategy_macro(model, \\\"snapshotted_data\\\", \\\"source_data\\\", config, target_relation_exists) %}\\n\\n  {% if not target_relation_exists %}\\n\\n      {% set build_sql = build_snapshot_table(strategy, model['compiled_sql']) %}\\n      {% set final_sql = create_table_as(False, target_relation, build_sql) %}\\n\\n  {% else %}\\n\\n      {{ adapter.valid_snapshot_target(target_relation) }}\\n\\n      {% set staging_table = build_snapshot_staging_table(strategy, sql, target_relation) %}\\n\\n      -- this may no-op if the database does not require column expansion\\n      {% do adapter.expand_target_column_types(from_relation=staging_table,\\n                                               to_relation=target_relation) %}\\n\\n      {% set missing_columns = adapter.get_missing_columns(staging_table, target_relation)\\n                                   | rejectattr('name', 'equalto', 'dbt_change_type')\\n                                   | rejectattr('name', 'equalto', 'DBT_CHANGE_TYPE')\\n                                   | rejectattr('name', 'equalto', 'dbt_unique_key')\\n                                   | rejectattr('name', 'equalto', 'DBT_UNIQUE_KEY')\\n                                   | list %}\\n\\n      {% do create_columns(target_relation, missing_columns) %}\\n\\n      {% set source_columns = adapter.get_columns_in_relation(staging_table)\\n                                   | rejectattr('name', 'equalto', 'dbt_change_type')\\n                                   | rejectattr('name', 'equalto', 'DBT_CHANGE_TYPE')\\n                                   | rejectattr('name', 'equalto', 'dbt_unique_key')\\n                                   | rejectattr('name', 'equalto', 'DBT_UNIQUE_KEY')\\n                                   | list %}\\n\\n      {% set quoted_source_columns = [] %}\\n      {% for column in source_columns %}\\n        {% do quoted_source_columns.append(adapter.quote(column.name)) %}\\n      {% endfor %}\\n\\n      {% set final_sql = snapshot_merge_sql(\\n            target = target_relation,\\n            source = staging_table,\\n            insert_cols = quoted_source_columns\\n         )\\n      %}\\n\\n  {% endif %}\\n\\n  {% call statement('main') %}\\n      {{ final_sql }}\\n  {% endcall %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  {{ adapter.commit() }}\\n\\n  {% if staging_table is defined %}\\n      {% do post_snapshot(staging_table) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{% endmaterialization %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.create_schema\",\n                    \"macro.dbt.get_or_create_relation\",\n                    \"macro.dbt.run_hooks\",\n                    \"macro.dbt.strategy_dispatch\",\n                    \"macro.dbt.build_snapshot_table\",\n                    \"macro.dbt.create_table_as\",\n                    \"macro.dbt.build_snapshot_staging_table\",\n                    \"macro.dbt.create_columns\",\n                    \"macro.dbt.snapshot_merge_sql\",\n                    \"macro.dbt.statement\",\n                    \"macro.dbt.persist_docs\",\n                    \"macro.dbt.post_snapshot\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.create_csv_table\": {\n            \"unique_id\": \"macro.dbt.create_csv_table\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/seed/seed.sql\",\n            \"original_file_path\": \"macros/materializations/seed/seed.sql\",\n            \"name\": \"create_csv_table\",\n            \"macro_sql\": \"{% macro create_csv_table(model, agate_table) -%}\\n  {{ adapter.dispatch('create_csv_table')(model, agate_table) }}\\n{%- endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.default__create_csv_table\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.reset_csv_table\": {\n            \"unique_id\": \"macro.dbt.reset_csv_table\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/seed/seed.sql\",\n            \"original_file_path\": \"macros/materializations/seed/seed.sql\",\n            \"name\": \"reset_csv_table\",\n            \"macro_sql\": \"{% macro reset_csv_table(model, full_refresh, old_relation, agate_table) -%}\\n  {{ adapter.dispatch('reset_csv_table')(model, full_refresh, old_relation, agate_table) }}\\n{%- endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.default__reset_csv_table\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.load_csv_rows\": {\n            \"unique_id\": \"macro.dbt.load_csv_rows\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/seed/seed.sql\",\n            \"original_file_path\": \"macros/materializations/seed/seed.sql\",\n            \"name\": \"load_csv_rows\",\n            \"macro_sql\": \"{% macro load_csv_rows(model, agate_table) -%}\\n  {{ adapter.dispatch('load_csv_rows')(model, agate_table) }}\\n{%- endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.default__load_csv_rows\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.default__create_csv_table\": {\n            \"unique_id\": \"macro.dbt.default__create_csv_table\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/seed/seed.sql\",\n            \"original_file_path\": \"macros/materializations/seed/seed.sql\",\n            \"name\": \"default__create_csv_table\",\n            \"macro_sql\": \"{% macro default__create_csv_table(model, agate_table) %}\\n  {%- set column_override = model['config'].get('column_types', {}) -%}\\n  {%- set quote_seed_column = model['config'].get('quote_columns', None) -%}\\n\\n  {% set sql %}\\n    create table {{ this.render() }} (\\n        {%- for col_name in agate_table.column_names -%}\\n            {%- set inferred_type = adapter.convert_type(agate_table, loop.index0) -%}\\n            {%- set type = column_override.get(col_name, inferred_type) -%}\\n            {%- set column_name = (col_name | string) -%}\\n            {{ adapter.quote_seed_column(column_name, quote_seed_column) }} {{ type }} {%- if not loop.last -%}, {%- endif -%}\\n        {%- endfor -%}\\n    )\\n  {% endset %}\\n\\n  {% call statement('_') -%}\\n    {{ sql }}\\n  {%- endcall %}\\n\\n  {{ return(sql) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.statement\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.default__reset_csv_table\": {\n            \"unique_id\": \"macro.dbt.default__reset_csv_table\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/seed/seed.sql\",\n            \"original_file_path\": \"macros/materializations/seed/seed.sql\",\n            \"name\": \"default__reset_csv_table\",\n            \"macro_sql\": \"{% macro default__reset_csv_table(model, full_refresh, old_relation, agate_table) %}\\n    {% set sql = \\\"\\\" %}\\n    {% if full_refresh %}\\n        {{ adapter.drop_relation(old_relation) }}\\n        {% set sql = create_csv_table(model, agate_table) %}\\n    {% else %}\\n        {{ adapter.truncate_relation(old_relation) }}\\n        {% set sql = \\\"truncate table \\\" ~ old_relation %}\\n    {% endif %}\\n\\n    {{ return(sql) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.create_csv_table\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.get_seed_column_quoted_csv\": {\n            \"unique_id\": \"macro.dbt.get_seed_column_quoted_csv\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/seed/seed.sql\",\n            \"original_file_path\": \"macros/materializations/seed/seed.sql\",\n            \"name\": \"get_seed_column_quoted_csv\",\n            \"macro_sql\": \"{% macro get_seed_column_quoted_csv(model, column_names) %}\\n  {%- set quote_seed_column = model['config'].get('quote_columns', None) -%}\\n    {% set quoted = [] %}\\n    {% for col in column_names -%}\\n        {%- do quoted.append(adapter.quote_seed_column(col, quote_seed_column)) -%}\\n    {%- endfor %}\\n\\n    {%- set dest_cols_csv = quoted | join(', ') -%}\\n    {{ return(dest_cols_csv) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.basic_load_csv_rows\": {\n            \"unique_id\": \"macro.dbt.basic_load_csv_rows\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/seed/seed.sql\",\n            \"original_file_path\": \"macros/materializations/seed/seed.sql\",\n            \"name\": \"basic_load_csv_rows\",\n            \"macro_sql\": \"{% macro basic_load_csv_rows(model, batch_size, agate_table) %}\\n    {% set cols_sql = get_seed_column_quoted_csv(model, agate_table.column_names) %}\\n    {% set bindings = [] %}\\n\\n    {% set statements = [] %}\\n\\n    {% for chunk in agate_table.rows | batch(batch_size) %}\\n        {% set bindings = [] %}\\n\\n        {% for row in chunk %}\\n            {% do bindings.extend(row) %}\\n        {% endfor %}\\n\\n        {% set sql %}\\n            insert into {{ this.render() }} ({{ cols_sql }}) values\\n            {% for row in chunk -%}\\n                ({%- for column in agate_table.column_names -%}\\n                    %s\\n                    {%- if not loop.last%},{%- endif %}\\n                {%- endfor -%})\\n                {%- if not loop.last%},{%- endif %}\\n            {%- endfor %}\\n        {% endset %}\\n\\n        {% do adapter.add_query(sql, bindings=bindings, abridge_sql_log=True) %}\\n\\n        {% if loop.index0 == 0 %}\\n            {% do statements.append(sql) %}\\n        {% endif %}\\n    {% endfor %}\\n\\n    {# Return SQL so we can render it out into the compiled files #}\\n    {{ return(statements[0]) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.get_seed_column_quoted_csv\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.default__load_csv_rows\": {\n            \"unique_id\": \"macro.dbt.default__load_csv_rows\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/seed/seed.sql\",\n            \"original_file_path\": \"macros/materializations/seed/seed.sql\",\n            \"name\": \"default__load_csv_rows\",\n            \"macro_sql\": \"{% macro default__load_csv_rows(model, agate_table) %}\\n  {{ return(basic_load_csv_rows(model, 10000, agate_table) )}}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.basic_load_csv_rows\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.materialization_seed_default\": {\n            \"unique_id\": \"macro.dbt.materialization_seed_default\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/seed/seed.sql\",\n            \"original_file_path\": \"macros/materializations/seed/seed.sql\",\n            \"name\": \"materialization_seed_default\",\n            \"macro_sql\": \"{% materialization seed, default %}\\n\\n  {%- set identifier = model['alias'] -%}\\n  {%- set full_refresh_mode = (should_full_refresh()) -%}\\n\\n  {%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%}\\n\\n  {%- set exists_as_table = (old_relation is not none and old_relation.is_table) -%}\\n  {%- set exists_as_view = (old_relation is not none and old_relation.is_view) -%}\\n\\n  {%- set agate_table = load_agate_table() -%}\\n  {%- do store_result('agate_table', response='OK', agate_table=agate_table) -%}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  -- build model\\n  {% set create_table_sql = \\\"\\\" %}\\n  {% if exists_as_view %}\\n    {{ exceptions.raise_compiler_error(\\\"Cannot seed to '{}', it is a view\\\".format(old_relation)) }}\\n  {% elif exists_as_table %}\\n    {% set create_table_sql = reset_csv_table(model, full_refresh_mode, old_relation, agate_table) %}\\n  {% else %}\\n    {% set create_table_sql = create_csv_table(model, agate_table) %}\\n  {% endif %}\\n\\n  {% set code = 'CREATE' if full_refresh_mode else 'INSERT' %}\\n  {% set rows_affected = (agate_table.rows | length) %}\\n  {% set sql = load_csv_rows(model, agate_table) %}\\n\\n  {% call noop_statement('main', code ~ ' ' ~ rows_affected, code, rows_affected) %}\\n    {{ create_table_sql }};\\n    -- dbt seed --\\n    {{ sql }}\\n  {% endcall %}\\n\\n  {% set target_relation = this.incorporate(type='table') %}\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  -- `COMMIT` happens here\\n  {{ adapter.commit() }}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{% endmaterialization %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.should_full_refresh\",\n                    \"macro.dbt.run_hooks\",\n                    \"macro.dbt.reset_csv_table\",\n                    \"macro.dbt.create_csv_table\",\n                    \"macro.dbt.load_csv_rows\",\n                    \"macro.dbt.noop_statement\",\n                    \"macro.dbt.persist_docs\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.incremental_upsert\": {\n            \"unique_id\": \"macro.dbt.incremental_upsert\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/incremental/helpers.sql\",\n            \"original_file_path\": \"macros/materializations/incremental/helpers.sql\",\n            \"name\": \"incremental_upsert\",\n            \"macro_sql\": \"{% macro incremental_upsert(tmp_relation, target_relation, unique_key=none, statement_name=\\\"main\\\") %}\\n    {%- set dest_columns = adapter.get_columns_in_relation(target_relation) -%}\\n    {%- set dest_cols_csv = dest_columns | map(attribute='quoted') | join(', ') -%}\\n\\n    {%- if unique_key is not none -%}\\n    delete\\n    from {{ target_relation }}\\n    where ({{ unique_key }}) in (\\n        select ({{ unique_key }})\\n        from {{ tmp_relation }}\\n    );\\n    {%- endif %}\\n\\n    insert into {{ target_relation }} ({{ dest_cols_csv }})\\n    (\\n       select {{ dest_cols_csv }}\\n       from {{ tmp_relation }}\\n    );\\n{%- endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.materialization_incremental_default\": {\n            \"unique_id\": \"macro.dbt.materialization_incremental_default\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/incremental/incremental.sql\",\n            \"original_file_path\": \"macros/materializations/incremental/incremental.sql\",\n            \"name\": \"materialization_incremental_default\",\n            \"macro_sql\": \"{% materialization incremental, default -%}\\n\\n  {% set unique_key = config.get('unique_key') %}\\n\\n  {% set target_relation = this.incorporate(type='table') %}\\n  {% set existing_relation = load_relation(this) %}\\n  {% set tmp_relation = make_temp_relation(this) %}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  {% set to_drop = [] %}\\n  {% if existing_relation is none %}\\n      {% set build_sql = create_table_as(False, target_relation, sql) %}\\n  {% elif existing_relation.is_view or should_full_refresh() %}\\n      {#-- Make sure the backup doesn't exist so we don't encounter issues with the rename below #}\\n      {% set backup_identifier = existing_relation.identifier ~ \\\"__dbt_backup\\\" %}\\n      {% set backup_relation = existing_relation.incorporate(path={\\\"identifier\\\": backup_identifier}) %}\\n      {% do adapter.drop_relation(backup_relation) %}\\n\\n      {% do adapter.rename_relation(target_relation, backup_relation) %}\\n      {% set build_sql = create_table_as(False, target_relation, sql) %}\\n      {% do to_drop.append(backup_relation) %}\\n  {% else %}\\n      {% set tmp_relation = make_temp_relation(target_relation) %}\\n      {% do run_query(create_table_as(True, tmp_relation, sql)) %}\\n      {% do adapter.expand_target_column_types(\\n             from_relation=tmp_relation,\\n             to_relation=target_relation) %}\\n      {% set build_sql = incremental_upsert(tmp_relation, target_relation, unique_key=unique_key) %}\\n  {% endif %}\\n\\n  {% call statement(\\\"main\\\") %}\\n      {{ build_sql }}\\n  {% endcall %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  -- `COMMIT` happens here\\n  {% do adapter.commit() %}\\n\\n  {% for rel in to_drop %}\\n      {% do adapter.drop_relation(rel) %}\\n  {% endfor %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{%- endmaterialization %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.test.load_relation\",\n                    \"macro.dbt.make_temp_relation\",\n                    \"macro.dbt.run_hooks\",\n                    \"macro.dbt.create_table_as\",\n                    \"macro.dbt.should_full_refresh\",\n                    \"macro.dbt.run_query\",\n                    \"macro.dbt.incremental_upsert\",\n                    \"macro.dbt.statement\",\n                    \"macro.dbt.persist_docs\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.get_merge_sql\": {\n            \"unique_id\": \"macro.dbt.get_merge_sql\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/common/merge.sql\",\n            \"original_file_path\": \"macros/materializations/common/merge.sql\",\n            \"name\": \"get_merge_sql\",\n            \"macro_sql\": \"{% macro get_merge_sql(target, source, unique_key, dest_columns, predicates=none) -%}\\n  {{ adapter.dispatch('get_merge_sql')(target, source, unique_key, dest_columns, predicates) }}\\n{%- endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.default__get_merge_sql\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.get_delete_insert_merge_sql\": {\n            \"unique_id\": \"macro.dbt.get_delete_insert_merge_sql\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/common/merge.sql\",\n            \"original_file_path\": \"macros/materializations/common/merge.sql\",\n            \"name\": \"get_delete_insert_merge_sql\",\n            \"macro_sql\": \"{% macro get_delete_insert_merge_sql(target, source, unique_key, dest_columns) -%}\\n  {{ adapter.dispatch('get_delete_insert_merge_sql')(target, source, unique_key, dest_columns) }}\\n{%- endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.default__get_delete_insert_merge_sql\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.get_insert_overwrite_merge_sql\": {\n            \"unique_id\": \"macro.dbt.get_insert_overwrite_merge_sql\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/common/merge.sql\",\n            \"original_file_path\": \"macros/materializations/common/merge.sql\",\n            \"name\": \"get_insert_overwrite_merge_sql\",\n            \"macro_sql\": \"{% macro get_insert_overwrite_merge_sql(target, source, dest_columns, predicates, include_sql_header=false) -%}\\n  {{ adapter.dispatch('get_insert_overwrite_merge_sql')(target, source, dest_columns, predicates, include_sql_header) }}\\n{%- endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.default__get_insert_overwrite_merge_sql\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.default__get_merge_sql\": {\n            \"unique_id\": \"macro.dbt.default__get_merge_sql\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/common/merge.sql\",\n            \"original_file_path\": \"macros/materializations/common/merge.sql\",\n            \"name\": \"default__get_merge_sql\",\n            \"macro_sql\": \"{% macro default__get_merge_sql(target, source, unique_key, dest_columns, predicates) -%}\\n    {%- set predicates = [] if predicates is none else [] + predicates -%}\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n    {%- set sql_header = config.get('sql_header', none) -%}\\n\\n    {% if unique_key %}\\n        {% set unique_key_match %}\\n            DBT_INTERNAL_SOURCE.{{ unique_key }} = DBT_INTERNAL_DEST.{{ unique_key }}\\n        {% endset %}\\n        {% do predicates.append(unique_key_match) %}\\n    {% else %}\\n        {% do predicates.append('FALSE') %}\\n    {% endif %}\\n\\n    {{ sql_header if sql_header is not none }}\\n\\n    merge into {{ target }} as DBT_INTERNAL_DEST\\n        using {{ source }} as DBT_INTERNAL_SOURCE\\n        on {{ predicates | join(' and ') }}\\n\\n    {% if unique_key %}\\n    when matched then update set\\n        {% for column in dest_columns -%}\\n            {{ adapter.quote(column.name) }} = DBT_INTERNAL_SOURCE.{{ adapter.quote(column.name) }}\\n            {%- if not loop.last %}, {%- endif %}\\n        {%- endfor %}\\n    {% endif %}\\n\\n    when not matched then insert\\n        ({{ dest_cols_csv }})\\n    values\\n        ({{ dest_cols_csv }})\\n\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.get_quoted_csv\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.get_quoted_csv\": {\n            \"unique_id\": \"macro.dbt.get_quoted_csv\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/common/merge.sql\",\n            \"original_file_path\": \"macros/materializations/common/merge.sql\",\n            \"name\": \"get_quoted_csv\",\n            \"macro_sql\": \"{% macro get_quoted_csv(column_names) %}\\n    {% set quoted = [] %}\\n    {% for col in column_names -%}\\n        {%- do quoted.append(adapter.quote(col)) -%}\\n    {%- endfor %}\\n\\n    {%- set dest_cols_csv = quoted | join(', ') -%}\\n    {{ return(dest_cols_csv) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.common_get_delete_insert_merge_sql\": {\n            \"unique_id\": \"macro.dbt.common_get_delete_insert_merge_sql\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/common/merge.sql\",\n            \"original_file_path\": \"macros/materializations/common/merge.sql\",\n            \"name\": \"common_get_delete_insert_merge_sql\",\n            \"macro_sql\": \"{% macro common_get_delete_insert_merge_sql(target, source, unique_key, dest_columns) -%}\\n\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n\\n    {% if unique_key is not none %}\\n    delete from {{ target }}\\n    where ({{ unique_key }}) in (\\n        select ({{ unique_key }})\\n        from {{ source }}\\n    );\\n    {% endif %}\\n\\n    insert into {{ target }} ({{ dest_cols_csv }})\\n    (\\n        select {{ dest_cols_csv }}\\n        from {{ source }}\\n    );\\n\\n{%- endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.get_quoted_csv\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.default__get_delete_insert_merge_sql\": {\n            \"unique_id\": \"macro.dbt.default__get_delete_insert_merge_sql\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/common/merge.sql\",\n            \"original_file_path\": \"macros/materializations/common/merge.sql\",\n            \"name\": \"default__get_delete_insert_merge_sql\",\n            \"macro_sql\": \"{% macro default__get_delete_insert_merge_sql(target, source, unique_key, dest_columns) -%}\\n    {{ common_get_delete_insert_merge_sql(target, source, unique_key, dest_columns) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.common_get_delete_insert_merge_sql\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.default__get_insert_overwrite_merge_sql\": {\n            \"unique_id\": \"macro.dbt.default__get_insert_overwrite_merge_sql\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/common/merge.sql\",\n            \"original_file_path\": \"macros/materializations/common/merge.sql\",\n            \"name\": \"default__get_insert_overwrite_merge_sql\",\n            \"macro_sql\": \"{% macro default__get_insert_overwrite_merge_sql(target, source, dest_columns, predicates, include_sql_header) -%}\\n    {%- set predicates = [] if predicates is none else [] + predicates -%}\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n    {%- set sql_header = config.get('sql_header', none) -%}\\n\\n    {{ sql_header if sql_header is not none and include_sql_header }}\\n\\n    merge into {{ target }} as DBT_INTERNAL_DEST\\n        using {{ source }} as DBT_INTERNAL_SOURCE\\n        on FALSE\\n\\n    when not matched by source\\n        {% if predicates %} and {{ predicates | join(' and ') }} {% endif %}\\n        then delete\\n\\n    when not matched then insert\\n        ({{ dest_cols_csv }})\\n    values\\n        ({{ dest_cols_csv }})\\n\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.get_quoted_csv\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.materialization_table_default\": {\n            \"unique_id\": \"macro.dbt.materialization_table_default\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/table/table.sql\",\n            \"original_file_path\": \"macros/materializations/table/table.sql\",\n            \"name\": \"materialization_table_default\",\n            \"macro_sql\": \"{% materialization table, default %}\\n  {%- set identifier = model['alias'] -%}\\n  {%- set tmp_identifier = model['name'] + '__dbt_tmp' -%}\\n  {%- set backup_identifier = model['name'] + '__dbt_backup' -%}\\n\\n  {%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%}\\n  {%- set target_relation = api.Relation.create(identifier=identifier,\\n                                                schema=schema,\\n                                                database=database,\\n                                                type='table') -%}\\n  {%- set intermediate_relation = api.Relation.create(identifier=tmp_identifier,\\n                                                      schema=schema,\\n                                                      database=database,\\n                                                      type='table') -%}\\n\\n  /*\\n      See ../view/view.sql for more information about this relation.\\n  */\\n  {%- set backup_relation_type = 'table' if old_relation is none else old_relation.type -%}\\n  {%- set backup_relation = api.Relation.create(identifier=backup_identifier,\\n                                                schema=schema,\\n                                                database=database,\\n                                                type=backup_relation_type) -%}\\n\\n  {%- set exists_as_table = (old_relation is not none and old_relation.is_table) -%}\\n  {%- set exists_as_view = (old_relation is not none and old_relation.is_view) -%}\\n\\n\\n  -- drop the temp relations if they exists for some reason\\n  {{ adapter.drop_relation(intermediate_relation) }}\\n  {{ adapter.drop_relation(backup_relation) }}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  -- build model\\n  {% call statement('main') -%}\\n    {{ create_table_as(False, intermediate_relation, sql) }}\\n  {%- endcall %}\\n\\n  -- cleanup\\n  {% if old_relation is not none %}\\n      {{ adapter.rename_relation(target_relation, backup_relation) }}\\n  {% endif %}\\n\\n  {{ adapter.rename_relation(intermediate_relation, target_relation) }}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  -- `COMMIT` happens here\\n  {{ adapter.commit() }}\\n\\n  -- finally, drop the existing/backup relation after the commit\\n  {{ drop_relation_if_exists(backup_relation) }}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n{% endmaterialization %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.run_hooks\",\n                    \"macro.dbt.statement\",\n                    \"macro.dbt.create_table_as\",\n                    \"macro.dbt.persist_docs\",\n                    \"macro.dbt.drop_relation_if_exists\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.materialization_view_default\": {\n            \"unique_id\": \"macro.dbt.materialization_view_default\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/view/view.sql\",\n            \"original_file_path\": \"macros/materializations/view/view.sql\",\n            \"name\": \"materialization_view_default\",\n            \"macro_sql\": \"{%- materialization view, default -%}\\n\\n  {%- set identifier = model['alias'] -%}\\n  {%- set tmp_identifier = model['name'] + '__dbt_tmp' -%}\\n  {%- set backup_identifier = model['name'] + '__dbt_backup' -%}\\n\\n  {%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%}\\n  {%- set target_relation = api.Relation.create(identifier=identifier, schema=schema, database=database,\\n                                                type='view') -%}\\n  {%- set intermediate_relation = api.Relation.create(identifier=tmp_identifier,\\n                                                      schema=schema, database=database, type='view') -%}\\n\\n  /*\\n     This relation (probably) doesn't exist yet. If it does exist, it's a leftover from\\n     a previous run, and we're going to try to drop it immediately. At the end of this\\n     materialization, we're going to rename the \\\"old_relation\\\" to this identifier,\\n     and then we're going to drop it. In order to make sure we run the correct one of:\\n       - drop view ...\\n       - drop table ...\\n\\n     We need to set the type of this relation to be the type of the old_relation, if it exists,\\n     or else \\\"view\\\" as a sane default if it does not. Note that if the old_relation does not\\n     exist, then there is nothing to move out of the way and subsequentally drop. In that case,\\n     this relation will be effectively unused.\\n  */\\n  {%- set backup_relation_type = 'view' if old_relation is none else old_relation.type -%}\\n  {%- set backup_relation = api.Relation.create(identifier=backup_identifier,\\n                                                schema=schema, database=database,\\n                                                type=backup_relation_type) -%}\\n\\n  {%- set exists_as_view = (old_relation is not none and old_relation.is_view) -%}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- drop the temp relations if they exists for some reason\\n  {{ adapter.drop_relation(intermediate_relation) }}\\n  {{ adapter.drop_relation(backup_relation) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  -- build model\\n  {% call statement('main') -%}\\n    {{ create_view_as(intermediate_relation, sql) }}\\n  {%- endcall %}\\n\\n  -- cleanup\\n  -- move the existing view out of the way\\n  {% if old_relation is not none %}\\n    {{ adapter.rename_relation(target_relation, backup_relation) }}\\n  {% endif %}\\n  {{ adapter.rename_relation(intermediate_relation, target_relation) }}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  {{ adapter.commit() }}\\n\\n  {{ drop_relation_if_exists(backup_relation) }}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{%- endmaterialization -%}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.run_hooks\",\n                    \"macro.dbt.statement\",\n                    \"macro.dbt.create_view_as\",\n                    \"macro.dbt.persist_docs\",\n                    \"macro.dbt.drop_relation_if_exists\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.handle_existing_table\": {\n            \"unique_id\": \"macro.dbt.handle_existing_table\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/view/create_or_replace_view.sql\",\n            \"original_file_path\": \"macros/materializations/view/create_or_replace_view.sql\",\n            \"name\": \"handle_existing_table\",\n            \"macro_sql\": \"{% macro handle_existing_table(full_refresh, old_relation) %}\\n    {{ adapter.dispatch(\\\"handle_existing_table\\\", packages=['dbt'])(full_refresh, old_relation) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.default__handle_existing_table\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.default__handle_existing_table\": {\n            \"unique_id\": \"macro.dbt.default__handle_existing_table\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/view/create_or_replace_view.sql\",\n            \"original_file_path\": \"macros/materializations/view/create_or_replace_view.sql\",\n            \"name\": \"default__handle_existing_table\",\n            \"macro_sql\": \"{% macro default__handle_existing_table(full_refresh, old_relation) %}\\n    {{ adapter.drop_relation(old_relation) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.create_or_replace_view\": {\n            \"unique_id\": \"macro.dbt.create_or_replace_view\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/materializations/view/create_or_replace_view.sql\",\n            \"original_file_path\": \"macros/materializations/view/create_or_replace_view.sql\",\n            \"name\": \"create_or_replace_view\",\n            \"macro_sql\": \"{% macro create_or_replace_view(run_outside_transaction_hooks=True) %}\\n  {%- set identifier = model['alias'] -%}\\n\\n  {%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%}\\n\\n  {%- set exists_as_view = (old_relation is not none and old_relation.is_view) -%}\\n\\n  {%- set target_relation = api.Relation.create(\\n      identifier=identifier, schema=schema, database=database,\\n      type='view') -%}\\n\\n  {% if run_outside_transaction_hooks %}\\n      -- no transactions on BigQuery\\n      {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n  {% endif %}\\n\\n  -- `BEGIN` happens here on Snowflake\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  -- If there's a table with the same name and we weren't told to full refresh,\\n  -- that's an error. If we were told to full refresh, drop it. This behavior differs\\n  -- for Snowflake and BigQuery, so multiple dispatch is used.\\n  {%- if old_relation is not none and old_relation.is_table -%}\\n    {{ handle_existing_table(should_full_refresh(), old_relation) }}\\n  {%- endif -%}\\n\\n  -- build model\\n  {% call statement('main') -%}\\n    {{ create_view_as(target_relation, sql) }}\\n  {%- endcall %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  {{ adapter.commit() }}\\n\\n  {% if run_outside_transaction_hooks %}\\n      -- No transactions on BigQuery\\n      {{ run_hooks(post_hooks, inside_transaction=False) }}\\n  {% endif %}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.run_hooks\",\n                    \"macro.dbt.handle_existing_table\",\n                    \"macro.dbt.should_full_refresh\",\n                    \"macro.dbt.statement\",\n                    \"macro.dbt.create_view_as\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.generate_alias_name\": {\n            \"unique_id\": \"macro.dbt.generate_alias_name\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/etc/get_custom_alias.sql\",\n            \"original_file_path\": \"macros/etc/get_custom_alias.sql\",\n            \"name\": \"generate_alias_name\",\n            \"macro_sql\": \"{% macro generate_alias_name(custom_alias_name=none, node=none) -%}\\n\\n    {%- if custom_alias_name is none -%}\\n\\n        {{ node.name }}\\n\\n    {%- else -%}\\n\\n        {{ custom_alias_name | trim }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.run_query\": {\n            \"unique_id\": \"macro.dbt.run_query\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/etc/query.sql\",\n            \"original_file_path\": \"macros/etc/query.sql\",\n            \"name\": \"run_query\",\n            \"macro_sql\": \"{% macro run_query(sql) %}\\n  {% call statement(\\\"run_query_statement\\\", fetch_result=true, auto_begin=false) %}\\n    {{ sql }}\\n  {% endcall %}\\n\\n  {% do return(load_result(\\\"run_query_statement\\\").table) %}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.statement\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.is_incremental\": {\n            \"unique_id\": \"macro.dbt.is_incremental\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/etc/is_incremental.sql\",\n            \"original_file_path\": \"macros/etc/is_incremental.sql\",\n            \"name\": \"is_incremental\",\n            \"macro_sql\": \"{% macro is_incremental() %}\\n    {#-- do not run introspective queries in parsing #}\\n    {% if not execute %}\\n        {{ return(False) }}\\n    {% else %}\\n        {% set relation = adapter.get_relation(this.database, this.schema, this.table) %}\\n        {{ return(relation is not none\\n                  and relation.type == 'table'\\n                  and model.config.materialized == 'incremental'\\n                  and not should_full_refresh()) }}\\n    {% endif %}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.should_full_refresh\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.convert_datetime\": {\n            \"unique_id\": \"macro.dbt.convert_datetime\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/etc/datetime.sql\",\n            \"original_file_path\": \"macros/etc/datetime.sql\",\n            \"name\": \"convert_datetime\",\n            \"macro_sql\": \"{% macro convert_datetime(date_str, date_fmt) %}\\n\\n  {% set error_msg -%}\\n      The provided partition date '{{ date_str }}' does not match the expected format '{{ date_fmt }}'\\n  {%- endset %}\\n\\n  {% set res = try_or_compiler_error(error_msg, modules.datetime.datetime.strptime, date_str.strip(), date_fmt) %}\\n  {{ return(res) }}\\n\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.dates_in_range\": {\n            \"unique_id\": \"macro.dbt.dates_in_range\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/etc/datetime.sql\",\n            \"original_file_path\": \"macros/etc/datetime.sql\",\n            \"name\": \"dates_in_range\",\n            \"macro_sql\": \"{% macro dates_in_range(start_date_str, end_date_str=none, in_fmt=\\\"%Y%m%d\\\", out_fmt=\\\"%Y%m%d\\\") %}\\n    {% set end_date_str = start_date_str if end_date_str is none else end_date_str %}\\n\\n    {% set start_date = convert_datetime(start_date_str, in_fmt) %}\\n    {% set end_date = convert_datetime(end_date_str, in_fmt) %}\\n\\n    {% set day_count = (end_date - start_date).days %}\\n    {% if day_count < 0 %}\\n        {% set msg -%}\\n            Partition start date is after the end date ({{ start_date }}, {{ end_date }})\\n        {%- endset %}\\n\\n        {{ exceptions.raise_compiler_error(msg, model) }}\\n    {% endif %}\\n\\n    {% set date_list = [] %}\\n    {% for i in range(0, day_count + 1) %}\\n        {% set the_date = (modules.datetime.timedelta(days=i) + start_date) %}\\n        {% if not out_fmt %}\\n            {% set _ = date_list.append(the_date) %}\\n        {% else %}\\n            {% set _ = date_list.append(the_date.strftime(out_fmt)) %}\\n        {% endif %}\\n    {% endfor %}\\n\\n    {{ return(date_list) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.convert_datetime\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.partition_range\": {\n            \"unique_id\": \"macro.dbt.partition_range\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/etc/datetime.sql\",\n            \"original_file_path\": \"macros/etc/datetime.sql\",\n            \"name\": \"partition_range\",\n            \"macro_sql\": \"{% macro partition_range(raw_partition_date, date_fmt='%Y%m%d') %}\\n    {% set partition_range = (raw_partition_date | string).split(\\\",\\\") %}\\n\\n    {% if (partition_range | length) == 1 %}\\n      {% set start_date = partition_range[0] %}\\n      {% set end_date = none %}\\n    {% elif (partition_range | length) == 2 %}\\n      {% set start_date = partition_range[0] %}\\n      {% set end_date = partition_range[1] %}\\n    {% else %}\\n      {{ exceptions.raise_compiler_error(\\\"Invalid partition time. Expected format: {Start Date}[,{End Date}]. Got: \\\" ~ raw_partition_date) }}\\n    {% endif %}\\n\\n    {{ return(dates_in_range(start_date, end_date, in_fmt=date_fmt)) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.dates_in_range\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.py_current_timestring\": {\n            \"unique_id\": \"macro.dbt.py_current_timestring\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/etc/datetime.sql\",\n            \"original_file_path\": \"macros/etc/datetime.sql\",\n            \"name\": \"py_current_timestring\",\n            \"macro_sql\": \"{% macro py_current_timestring() %}\\n    {% set dt = modules.datetime.datetime.now() %}\\n    {% do return(dt.strftime(\\\"%Y%m%d%H%M%S%f\\\")) %}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.generate_schema_name\": {\n            \"unique_id\": \"macro.dbt.generate_schema_name\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/etc/get_custom_schema.sql\",\n            \"original_file_path\": \"macros/etc/get_custom_schema.sql\",\n            \"name\": \"generate_schema_name\",\n            \"macro_sql\": \"{% macro generate_schema_name(custom_schema_name, node) -%}\\n\\n    {%- set default_schema = target.schema -%}\\n    {%- if custom_schema_name is none -%}\\n\\n        {{ default_schema }}\\n\\n    {%- else -%}\\n\\n        {{ default_schema }}_{{ custom_schema_name | trim }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.generate_schema_name_for_env\": {\n            \"unique_id\": \"macro.dbt.generate_schema_name_for_env\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/etc/get_custom_schema.sql\",\n            \"original_file_path\": \"macros/etc/get_custom_schema.sql\",\n            \"name\": \"generate_schema_name_for_env\",\n            \"macro_sql\": \"{% macro generate_schema_name_for_env(custom_schema_name, node) -%}\\n\\n    {%- set default_schema = target.schema -%}\\n    {%- if target.name == 'prod' and custom_schema_name is not none -%}\\n\\n        {{ custom_schema_name | trim }}\\n\\n    {%- else -%}\\n\\n        {{ default_schema }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.generate_database_name\": {\n            \"unique_id\": \"macro.dbt.generate_database_name\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/etc/get_custom_database.sql\",\n            \"original_file_path\": \"macros/etc/get_custom_database.sql\",\n            \"name\": \"generate_database_name\",\n            \"macro_sql\": \"{% macro generate_database_name(custom_database_name=none, node=none) -%}\\n    {% do return(adapter.dispatch('generate_database_name')(custom_database_name, node)) %}\\n{%- endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.default__generate_database_name\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.default__generate_database_name\": {\n            \"unique_id\": \"macro.dbt.default__generate_database_name\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/etc/get_custom_database.sql\",\n            \"original_file_path\": \"macros/etc/get_custom_database.sql\",\n            \"name\": \"default__generate_database_name\",\n            \"macro_sql\": \"{% macro default__generate_database_name(custom_database_name=none, node=none) -%}\\n    {%- set default_database = target.database -%}\\n    {%- if custom_database_name is none -%}\\n\\n        {{ default_database }}\\n\\n    {%- else -%}\\n\\n        {{ custom_database_name }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.get_columns_in_query\": {\n            \"unique_id\": \"macro.dbt.get_columns_in_query\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"get_columns_in_query\",\n            \"macro_sql\": \"{% macro get_columns_in_query(select_sql) -%}\\n  {{ return(adapter.dispatch('get_columns_in_query')(select_sql)) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.default__get_columns_in_query\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.default__get_columns_in_query\": {\n            \"unique_id\": \"macro.dbt.default__get_columns_in_query\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"default__get_columns_in_query\",\n            \"macro_sql\": \"{% macro default__get_columns_in_query(select_sql) %}\\n    {% call statement('get_columns_in_query', fetch_result=True, auto_begin=False) -%}\\n        select * from (\\n            {{ select_sql }}\\n        ) as __dbt_sbq\\n        where false\\n        limit 0\\n    {% endcall %}\\n\\n    {{ return(load_result('get_columns_in_query').table.columns | map(attribute='name') | list) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.statement\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.create_schema\": {\n            \"unique_id\": \"macro.dbt.create_schema\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"create_schema\",\n            \"macro_sql\": \"{% macro create_schema(relation) -%}\\n  {{ adapter.dispatch('create_schema')(relation) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt_postgres.postgres__create_schema\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.default__create_schema\": {\n            \"unique_id\": \"macro.dbt.default__create_schema\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"default__create_schema\",\n            \"macro_sql\": \"{% macro default__create_schema(relation) -%}\\n  {%- call statement('create_schema') -%}\\n    create schema if not exists {{ relation.without_identifier() }}\\n  {% endcall %}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.statement\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.drop_schema\": {\n            \"unique_id\": \"macro.dbt.drop_schema\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"drop_schema\",\n            \"macro_sql\": \"{% macro drop_schema(relation) -%}\\n  {{ adapter.dispatch('drop_schema')(relation) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt_postgres.postgres__drop_schema\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.default__drop_schema\": {\n            \"unique_id\": \"macro.dbt.default__drop_schema\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"default__drop_schema\",\n            \"macro_sql\": \"{% macro default__drop_schema(relation) -%}\\n  {%- call statement('drop_schema') -%}\\n    drop schema if exists {{ relation.without_identifier() }} cascade\\n  {% endcall %}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.statement\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.create_table_as\": {\n            \"unique_id\": \"macro.dbt.create_table_as\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"create_table_as\",\n            \"macro_sql\": \"{% macro create_table_as(temporary, relation, sql) -%}\\n  {{ adapter.dispatch('create_table_as')(temporary, relation, sql) }}\\n{%- endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt_postgres.postgres__create_table_as\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.default__create_table_as\": {\n            \"unique_id\": \"macro.dbt.default__create_table_as\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"default__create_table_as\",\n            \"macro_sql\": \"{% macro default__create_table_as(temporary, relation, sql) -%}\\n  {%- set sql_header = config.get('sql_header', none) -%}\\n\\n  {{ sql_header if sql_header is not none }}\\n\\n  create {% if temporary: -%}temporary{%- endif %} table\\n    {{ relation.include(database=(not temporary), schema=(not temporary)) }}\\n  as (\\n    {{ sql }}\\n  );\\n\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.create_view_as\": {\n            \"unique_id\": \"macro.dbt.create_view_as\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"create_view_as\",\n            \"macro_sql\": \"{% macro create_view_as(relation, sql) -%}\\n  {{ adapter.dispatch('create_view_as')(relation, sql) }}\\n{%- endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.default__create_view_as\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.default__create_view_as\": {\n            \"unique_id\": \"macro.dbt.default__create_view_as\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"default__create_view_as\",\n            \"macro_sql\": \"{% macro default__create_view_as(relation, sql) -%}\\n  {%- set sql_header = config.get('sql_header', none) -%}\\n\\n  {{ sql_header if sql_header is not none }}\\n  create view {{ relation }} as (\\n    {{ sql }}\\n  );\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.get_catalog\": {\n            \"unique_id\": \"macro.dbt.get_catalog\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"get_catalog\",\n            \"macro_sql\": \"{% macro get_catalog(information_schema, schemas) -%}\\n  {{ return(adapter.dispatch('get_catalog')(information_schema, schemas)) }}\\n{%- endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt_postgres.postgres__get_catalog\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.default__get_catalog\": {\n            \"unique_id\": \"macro.dbt.default__get_catalog\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"default__get_catalog\",\n            \"macro_sql\": \"{% macro default__get_catalog(information_schema, schemas) -%}\\n\\n  {% set typename = adapter.type() %}\\n  {% set msg -%}\\n    get_catalog not implemented for {{ typename }}\\n  {%- endset %}\\n\\n  {{ exceptions.raise_compiler_error(msg) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.get_columns_in_relation\": {\n            \"unique_id\": \"macro.dbt.get_columns_in_relation\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"get_columns_in_relation\",\n            \"macro_sql\": \"{% macro get_columns_in_relation(relation) -%}\\n  {{ return(adapter.dispatch('get_columns_in_relation')(relation)) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt_postgres.postgres__get_columns_in_relation\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.sql_convert_columns_in_relation\": {\n            \"unique_id\": \"macro.dbt.sql_convert_columns_in_relation\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"sql_convert_columns_in_relation\",\n            \"macro_sql\": \"{% macro sql_convert_columns_in_relation(table) -%}\\n  {% set columns = [] %}\\n  {% for row in table %}\\n    {% do columns.append(api.Column(*row)) %}\\n  {% endfor %}\\n  {{ return(columns) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.default__get_columns_in_relation\": {\n            \"unique_id\": \"macro.dbt.default__get_columns_in_relation\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"default__get_columns_in_relation\",\n            \"macro_sql\": \"{% macro default__get_columns_in_relation(relation) -%}\\n  {{ exceptions.raise_not_implemented(\\n    'get_columns_in_relation macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.alter_column_type\": {\n            \"unique_id\": \"macro.dbt.alter_column_type\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"alter_column_type\",\n            \"macro_sql\": \"{% macro alter_column_type(relation, column_name, new_column_type) -%}\\n  {{ return(adapter.dispatch('alter_column_type')(relation, column_name, new_column_type)) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.default__alter_column_type\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.alter_column_comment\": {\n            \"unique_id\": \"macro.dbt.alter_column_comment\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"alter_column_comment\",\n            \"macro_sql\": \"{% macro alter_column_comment(relation, column_dict) -%}\\n  {{ return(adapter.dispatch('alter_column_comment')(relation, column_dict)) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt_postgres.postgres__alter_column_comment\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.default__alter_column_comment\": {\n            \"unique_id\": \"macro.dbt.default__alter_column_comment\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"default__alter_column_comment\",\n            \"macro_sql\": \"{% macro default__alter_column_comment(relation, column_dict) -%}\\n  {{ exceptions.raise_not_implemented(\\n    'alter_column_comment macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.alter_relation_comment\": {\n            \"unique_id\": \"macro.dbt.alter_relation_comment\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"alter_relation_comment\",\n            \"macro_sql\": \"{% macro alter_relation_comment(relation, relation_comment) -%}\\n  {{ return(adapter.dispatch('alter_relation_comment')(relation, relation_comment)) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt_postgres.postgres__alter_relation_comment\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.default__alter_relation_comment\": {\n            \"unique_id\": \"macro.dbt.default__alter_relation_comment\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"default__alter_relation_comment\",\n            \"macro_sql\": \"{% macro default__alter_relation_comment(relation, relation_comment) -%}\\n  {{ exceptions.raise_not_implemented(\\n    'alter_relation_comment macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.persist_docs\": {\n            \"unique_id\": \"macro.dbt.persist_docs\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"persist_docs\",\n            \"macro_sql\": \"{% macro persist_docs(relation, model, for_relation=true, for_columns=true) -%}\\n  {{ return(adapter.dispatch('persist_docs')(relation, model, for_relation, for_columns)) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.default__persist_docs\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.default__persist_docs\": {\n            \"unique_id\": \"macro.dbt.default__persist_docs\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"default__persist_docs\",\n            \"macro_sql\": \"{% macro default__persist_docs(relation, model, for_relation, for_columns) -%}\\n  {% if for_relation and config.persist_relation_docs() and model.description %}\\n    {% do run_query(alter_relation_comment(relation, model.description)) %}\\n  {% endif %}\\n\\n  {% if for_columns and config.persist_column_docs() and model.columns %}\\n    {% do run_query(alter_column_comment(relation, model.columns)) %}\\n  {% endif %}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.run_query\",\n                    \"macro.dbt.alter_relation_comment\",\n                    \"macro.dbt.alter_column_comment\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.default__alter_column_type\": {\n            \"unique_id\": \"macro.dbt.default__alter_column_type\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"default__alter_column_type\",\n            \"macro_sql\": \"{% macro default__alter_column_type(relation, column_name, new_column_type) -%}\\n  {#\\n    1. Create a new column (w/ temp name and correct type)\\n    2. Copy data over to it\\n    3. Drop the existing column (cascade!)\\n    4. Rename the new column to existing column\\n  #}\\n  {%- set tmp_column = column_name + \\\"__dbt_alter\\\" -%}\\n\\n  {% call statement('alter_column_type') %}\\n    alter table {{ relation }} add column {{ adapter.quote(tmp_column) }} {{ new_column_type }};\\n    update {{ relation }} set {{ adapter.quote(tmp_column) }} = {{ adapter.quote(column_name) }};\\n    alter table {{ relation }} drop column {{ adapter.quote(column_name) }} cascade;\\n    alter table {{ relation }} rename column {{ adapter.quote(tmp_column) }} to {{ adapter.quote(column_name) }}\\n  {% endcall %}\\n\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.statement\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.drop_relation\": {\n            \"unique_id\": \"macro.dbt.drop_relation\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"drop_relation\",\n            \"macro_sql\": \"{% macro drop_relation(relation) -%}\\n  {{ return(adapter.dispatch('drop_relation')(relation)) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.default__drop_relation\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.default__drop_relation\": {\n            \"unique_id\": \"macro.dbt.default__drop_relation\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"default__drop_relation\",\n            \"macro_sql\": \"{% macro default__drop_relation(relation) -%}\\n  {% call statement('drop_relation', auto_begin=False) -%}\\n    drop {{ relation.type }} if exists {{ relation }} cascade\\n  {%- endcall %}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.statement\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.truncate_relation\": {\n            \"unique_id\": \"macro.dbt.truncate_relation\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"truncate_relation\",\n            \"macro_sql\": \"{% macro truncate_relation(relation) -%}\\n  {{ return(adapter.dispatch('truncate_relation')(relation)) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.default__truncate_relation\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.default__truncate_relation\": {\n            \"unique_id\": \"macro.dbt.default__truncate_relation\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"default__truncate_relation\",\n            \"macro_sql\": \"{% macro default__truncate_relation(relation) -%}\\n  {% call statement('truncate_relation') -%}\\n    truncate table {{ relation }}\\n  {%- endcall %}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.statement\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.rename_relation\": {\n            \"unique_id\": \"macro.dbt.rename_relation\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"rename_relation\",\n            \"macro_sql\": \"{% macro rename_relation(from_relation, to_relation) -%}\\n  {{ return(adapter.dispatch('rename_relation')(from_relation, to_relation)) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.default__rename_relation\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.default__rename_relation\": {\n            \"unique_id\": \"macro.dbt.default__rename_relation\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"default__rename_relation\",\n            \"macro_sql\": \"{% macro default__rename_relation(from_relation, to_relation) -%}\\n  {% set target_name = adapter.quote_as_configured(to_relation.identifier, 'identifier') %}\\n  {% call statement('rename_relation') -%}\\n    alter table {{ from_relation }} rename to {{ target_name }}\\n  {%- endcall %}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.statement\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.information_schema_name\": {\n            \"unique_id\": \"macro.dbt.information_schema_name\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"information_schema_name\",\n            \"macro_sql\": \"{% macro information_schema_name(database) %}\\n  {{ return(adapter.dispatch('information_schema_name')(database)) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt_postgres.postgres__information_schema_name\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.default__information_schema_name\": {\n            \"unique_id\": \"macro.dbt.default__information_schema_name\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"default__information_schema_name\",\n            \"macro_sql\": \"{% macro default__information_schema_name(database) -%}\\n  {%- if database -%}\\n    {{ database }}.INFORMATION_SCHEMA\\n  {%- else -%}\\n    INFORMATION_SCHEMA\\n  {%- endif -%}\\n{%- endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.list_schemas\": {\n            \"unique_id\": \"macro.dbt.list_schemas\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"list_schemas\",\n            \"macro_sql\": \"{% macro list_schemas(database) -%}\\n  {{ return(adapter.dispatch('list_schemas')(database)) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt_postgres.postgres__list_schemas\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.default__list_schemas\": {\n            \"unique_id\": \"macro.dbt.default__list_schemas\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"default__list_schemas\",\n            \"macro_sql\": \"{% macro default__list_schemas(database) -%}\\n  {% set sql %}\\n    select distinct schema_name\\n    from {{ information_schema_name(database) }}.SCHEMATA\\n    where catalog_name ilike '{{ database }}'\\n  {% endset %}\\n  {{ return(run_query(sql)) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.information_schema_name\",\n                    \"macro.dbt.run_query\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.check_schema_exists\": {\n            \"unique_id\": \"macro.dbt.check_schema_exists\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"check_schema_exists\",\n            \"macro_sql\": \"{% macro check_schema_exists(information_schema, schema) -%}\\n  {{ return(adapter.dispatch('check_schema_exists')(information_schema, schema)) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt_postgres.postgres__check_schema_exists\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.default__check_schema_exists\": {\n            \"unique_id\": \"macro.dbt.default__check_schema_exists\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"default__check_schema_exists\",\n            \"macro_sql\": \"{% macro default__check_schema_exists(information_schema, schema) -%}\\n  {% set sql -%}\\n        select count(*)\\n        from {{ information_schema.replace(information_schema_view='SCHEMATA') }}\\n        where catalog_name='{{ information_schema.database }}'\\n          and schema_name='{{ schema }}'\\n  {%- endset %}\\n  {{ return(run_query(sql)) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.run_query\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.list_relations_without_caching\": {\n            \"unique_id\": \"macro.dbt.list_relations_without_caching\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"list_relations_without_caching\",\n            \"macro_sql\": \"{% macro list_relations_without_caching(schema_relation) %}\\n  {{ return(adapter.dispatch('list_relations_without_caching')(schema_relation)) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.test.postgres__list_relations_without_caching\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.default__list_relations_without_caching\": {\n            \"unique_id\": \"macro.dbt.default__list_relations_without_caching\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"default__list_relations_without_caching\",\n            \"macro_sql\": \"{% macro default__list_relations_without_caching(schema_relation) %}\\n  {{ exceptions.raise_not_implemented(\\n    'list_relations_without_caching macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.current_timestamp\": {\n            \"unique_id\": \"macro.dbt.current_timestamp\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"current_timestamp\",\n            \"macro_sql\": \"{% macro current_timestamp() -%}\\n  {{ adapter.dispatch('current_timestamp')() }}\\n{%- endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt_postgres.postgres__current_timestamp\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.default__current_timestamp\": {\n            \"unique_id\": \"macro.dbt.default__current_timestamp\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"default__current_timestamp\",\n            \"macro_sql\": \"{% macro default__current_timestamp() -%}\\n  {{ exceptions.raise_not_implemented(\\n    'current_timestamp macro not implemented for adapter '+adapter.type()) }}\\n{%- endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.collect_freshness\": {\n            \"unique_id\": \"macro.dbt.collect_freshness\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"collect_freshness\",\n            \"macro_sql\": \"{% macro collect_freshness(source, loaded_at_field, filter) %}\\n  {{ return(adapter.dispatch('collect_freshness')(source, loaded_at_field, filter))}}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.default__collect_freshness\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.default__collect_freshness\": {\n            \"unique_id\": \"macro.dbt.default__collect_freshness\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"default__collect_freshness\",\n            \"macro_sql\": \"{% macro default__collect_freshness(source, loaded_at_field, filter) %}\\n  {% call statement('collect_freshness', fetch_result=True, auto_begin=False) -%}\\n    select\\n      max({{ loaded_at_field }}) as max_loaded_at,\\n      {{ current_timestamp() }} as snapshotted_at\\n    from {{ source }}\\n    {% if filter %}\\n    where {{ filter }}\\n    {% endif %}\\n  {% endcall %}\\n  {{ return(load_result('collect_freshness').table) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.statement\",\n                    \"macro.dbt.current_timestamp\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.make_temp_relation\": {\n            \"unique_id\": \"macro.dbt.make_temp_relation\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"make_temp_relation\",\n            \"macro_sql\": \"{% macro make_temp_relation(base_relation, suffix='__dbt_tmp') %}\\n  {{ return(adapter.dispatch('make_temp_relation')(base_relation, suffix))}}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt_postgres.postgres__make_temp_relation\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.default__make_temp_relation\": {\n            \"unique_id\": \"macro.dbt.default__make_temp_relation\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"default__make_temp_relation\",\n            \"macro_sql\": \"{% macro default__make_temp_relation(base_relation, suffix) %}\\n    {% set tmp_identifier = base_relation.identifier ~ suffix %}\\n    {% set tmp_relation = base_relation.incorporate(\\n                                path={\\\"identifier\\\": tmp_identifier}) -%}\\n\\n    {% do return(tmp_relation) %}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.set_sql_header\": {\n            \"unique_id\": \"macro.dbt.set_sql_header\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/adapters/common.sql\",\n            \"original_file_path\": \"macros/adapters/common.sql\",\n            \"name\": \"set_sql_header\",\n            \"macro_sql\": \"{% macro set_sql_header(config) -%}\\n  {{ config.set('sql_header', caller()) }}\\n{%- endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.default__test_relationships\": {\n            \"unique_id\": \"macro.dbt.default__test_relationships\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/schema_tests/relationships.sql\",\n            \"original_file_path\": \"macros/schema_tests/relationships.sql\",\n            \"name\": \"default__test_relationships\",\n            \"macro_sql\": \"{% macro default__test_relationships(model, to, field) %}\\n\\n{% set column_name = kwargs.get('column_name', kwargs.get('from')) %}\\n\\n\\nselect count(*) as validation_errors\\nfrom (\\n    select {{ column_name }} as id from {{ model }}\\n) as child\\nleft join (\\n    select {{ field }} as id from {{ to }}\\n) as parent on parent.id = child.id\\nwhere child.id is not null\\n  and parent.id is null\\n\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.test_relationships\": {\n            \"unique_id\": \"macro.dbt.test_relationships\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/schema_tests/relationships.sql\",\n            \"original_file_path\": \"macros/schema_tests/relationships.sql\",\n            \"name\": \"test_relationships\",\n            \"macro_sql\": \"{% macro test_relationships(model, to, field) %}\\n    {% set macro = adapter.dispatch('test_relationships') %}\\n    {{ macro(model, to, field, **kwargs) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.default__test_relationships\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.default__test_not_null\": {\n            \"unique_id\": \"macro.dbt.default__test_not_null\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/schema_tests/not_null.sql\",\n            \"original_file_path\": \"macros/schema_tests/not_null.sql\",\n            \"name\": \"default__test_not_null\",\n            \"macro_sql\": \"{% macro default__test_not_null(model) %}\\n\\n{% set column_name = kwargs.get('column_name', kwargs.get('arg')) %}\\n\\nselect count(*) as validation_errors\\nfrom {{ model }}\\nwhere {{ column_name }} is null\\n\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.test_not_null\": {\n            \"unique_id\": \"macro.dbt.test_not_null\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/schema_tests/not_null.sql\",\n            \"original_file_path\": \"macros/schema_tests/not_null.sql\",\n            \"name\": \"test_not_null\",\n            \"macro_sql\": \"{% macro test_not_null(model) %}\\n    {% set macro = adapter.dispatch('test_not_null') %}\\n    {{ macro(model, **kwargs) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.default__test_not_null\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.default__test_unique\": {\n            \"unique_id\": \"macro.dbt.default__test_unique\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/schema_tests/unique.sql\",\n            \"original_file_path\": \"macros/schema_tests/unique.sql\",\n            \"name\": \"default__test_unique\",\n            \"macro_sql\": \"{% macro default__test_unique(model) %}\\n\\n{% set column_name = kwargs.get('column_name', kwargs.get('arg')) %}\\n\\nselect count(*) as validation_errors\\nfrom (\\n\\n    select\\n        {{ column_name }}\\n\\n    from {{ model }}\\n    where {{ column_name }} is not null\\n    group by {{ column_name }}\\n    having count(*) > 1\\n\\n) validation_errors\\n\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.test_unique\": {\n            \"unique_id\": \"macro.dbt.test_unique\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/schema_tests/unique.sql\",\n            \"original_file_path\": \"macros/schema_tests/unique.sql\",\n            \"name\": \"test_unique\",\n            \"macro_sql\": \"{% macro test_unique(model) %}\\n    {% set macro = adapter.dispatch('test_unique') %}\\n    {{ macro(model, **kwargs) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.default__test_unique\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.default__test_accepted_values\": {\n            \"unique_id\": \"macro.dbt.default__test_accepted_values\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/schema_tests/accepted_values.sql\",\n            \"original_file_path\": \"macros/schema_tests/accepted_values.sql\",\n            \"name\": \"default__test_accepted_values\",\n            \"macro_sql\": \"{% macro default__test_accepted_values(model, values) %}\\n\\n{% set column_name = kwargs.get('column_name', kwargs.get('field')) %}\\n{% set quote_values = kwargs.get('quote', True) %}\\n\\nwith all_values as (\\n\\n    select distinct\\n        {{ column_name }} as value_field\\n\\n    from {{ model }}\\n\\n),\\n\\nvalidation_errors as (\\n\\n    select\\n        value_field\\n\\n    from all_values\\n    where value_field not in (\\n        {% for value in values -%}\\n            {% if quote_values -%}\\n            '{{ value }}'\\n            {%- else -%}\\n            {{ value }}\\n            {%- endif -%}\\n            {%- if not loop.last -%},{%- endif %}\\n        {%- endfor %}\\n    )\\n)\\n\\nselect count(*) as validation_errors\\nfrom validation_errors\\n\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": []\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        },\n        \"macro.dbt.test_accepted_values\": {\n            \"unique_id\": \"macro.dbt.test_accepted_values\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"macros/schema_tests/accepted_values.sql\",\n            \"original_file_path\": \"macros/schema_tests/accepted_values.sql\",\n            \"name\": \"test_accepted_values\",\n            \"macro_sql\": \"{% macro test_accepted_values(model, values) %}\\n    {% set macro = adapter.dispatch('test_accepted_values') %}\\n    {{ macro(model, values, **kwargs) }}\\n{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"tags\": [],\n            \"depends_on\": {\n                \"macros\": [\n                    \"macro.dbt.default__test_accepted_values\"\n                ]\n            },\n            \"description\": \"\",\n            \"meta\": {},\n            \"docs\": {\n                \"show\": true\n            },\n            \"patch_path\": null,\n            \"arguments\": []\n        }\n    },\n    \"docs\": {\n        \"dbt.__overview__\": {\n            \"unique_id\": \"dbt.__overview__\",\n            \"package_name\": \"dbt\",\n            \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\",\n            \"path\": \"overview.md\",\n            \"original_file_path\": \"docs/overview.md\",\n            \"name\": \"__overview__\",\n            \"block_contents\": \"### Welcome!\\n\\nWelcome to the auto-generated documentation for your dbt project!\\n\\n### Navigation\\n\\nYou can use the `Project` and `Database` navigation tabs on the left side of the window to explore the models\\nin your project.\\n\\n#### Project Tab\\nThe `Project` tab mirrors the directory structure of your dbt project. In this tab, you can see all of the\\nmodels defined in your dbt project, as well as models imported from dbt packages.\\n\\n#### Database Tab\\nThe `Database` tab also exposes your models, but in a format that looks more like a database explorer. This view\\nshows relations (tables and views) grouped into database schemas. Note that ephemeral models are _not_ shown\\nin this interface, as they do not exist in the database.\\n\\n### Graph Exploration\\nYou can click the blue icon on the bottom-right corner of the page to view the lineage graph of your models.\\n\\nOn model pages, you'll see the immediate parents and children of the model you're exploring. By clicking the `Expand`\\nbutton at the top-right of this lineage pane, you'll be able to see all of the models that are used to build,\\nor are built from, the model you're exploring.\\n\\nOnce expanded, you'll be able to use the `--models` and `--exclude` model selection syntax to filter the\\nmodels in the graph. For more information on model selection, check out the [dbt docs](https://docs.getdbt.com/docs/model-selection-syntax).\\n\\nNote that you can also right-click on models to interactively filter and explore the graph.\\n\\n---\\n\\n### More information\\n\\n- [What is dbt](https://docs.getdbt.com/docs/overview)?\\n- Read the [dbt viewpoint](https://docs.getdbt.com/docs/viewpoint)\\n- [Installation](https://docs.getdbt.com/docs/installation)\\n- Join the [chat](https://community.getdbt.com/) on Slack for live questions and support.\"\n        }\n    },\n    \"exposures\": {},\n    \"selectors\": {},\n    \"disabled\": [],\n    \"parent_map\": {\n        \"model.test.my_model\": []\n    },\n    \"child_map\": {\n        \"model.test.my_model\": []\n    }\n}\n"
  },
  {
    "path": "tests/functional/artifacts/data/state/v10/manifest.json",
    "content": "{\"metadata\": {\"dbt_schema_version\": \"https://schemas.getdbt.com/dbt/manifest/v10.json\", \"dbt_version\": \"1.6.6\", \"generated_at\": \"2023-10-11T20:49:37.080431Z\", \"invocation_id\": \"e2f630c5-769a-47a2-89ce-294a00e14e1a\", \"env\": {}, \"project_name\": \"test\", \"project_id\": \"098f6bcd4621d373cade4e832627b4f6\", \"user_id\": null, \"send_anonymous_usage_stats\": false, \"adapter_type\": \"postgres\"}, \"nodes\": {\"model.test.my_model\": {\"database\": \"dbt\", \"schema\": \"test16970573770617803847_test_previous_version_state\", \"name\": \"my_model\", \"resource_type\": \"model\", \"package_name\": \"test\", \"path\": \"my_model.sql\", \"original_file_path\": \"models/my_model.sql\", \"unique_id\": \"model.test.my_model\", \"fqn\": [\"test\", \"my_model\"], \"alias\": \"my_model\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"3ea0f972fa1b56aa2dc2f56ee784b6a5796312f9a813d59ae70fd8855f10d16d\"}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"view\", \"incremental_strategy\": null, \"persist_docs\": {}, \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": null, \"on_schema_change\": \"ignore\", \"on_configuration_change\": \"apply\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"contract\": {\"enforced\": false}, \"post-hook\": [], \"pre-hook\": []}, \"tags\": [], \"description\": \"Example model\", \"columns\": {\"id\": {\"name\": \"id\", \"description\": \"\", \"meta\": {}, \"data_type\": null, \"constraints\": [], \"quote\": null, \"tags\": []}}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": \"test://models/schema.yml\", \"build_path\": null, \"deferred\": false, \"unrendered_config\": {}, \"created_at\": 1697057377.543413, \"relation_name\": \"\\\"dbt\\\".\\\"test16970573770617803847_test_previous_version_state\\\".\\\"my_model\\\"\", \"raw_code\": \"select 1 as id\", \"language\": \"sql\", \"refs\": [], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [], \"nodes\": []}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"checksum\": null}, \"access\": \"protected\", \"constraints\": [], \"version\": null, \"latest_version\": null, \"deprecation_date\": null}, \"model.test.metricflow_time_spine\": {\"database\": \"dbt\", \"schema\": \"test16970573770617803847_test_previous_version_state\", \"name\": \"metricflow_time_spine\", \"resource_type\": \"model\", \"package_name\": \"test\", \"path\": \"metricflow_time_spine.sql\", \"original_file_path\": \"models/metricflow_time_spine.sql\", \"unique_id\": \"model.test.metricflow_time_spine\", \"fqn\": [\"test\", \"metricflow_time_spine\"], \"alias\": \"metricflow_time_spine\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"954d9b349821edb5558a373119a7d91eeac9e620aaa96cd112c0d14bab729fdb\"}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"view\", \"incremental_strategy\": null, \"persist_docs\": {}, \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": null, \"on_schema_change\": \"ignore\", \"on_configuration_change\": \"apply\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"contract\": {\"enforced\": false}, \"post-hook\": [], \"pre-hook\": []}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {}, \"created_at\": 1697057377.456355, \"relation_name\": \"\\\"dbt\\\".\\\"test16970573770617803847_test_previous_version_state\\\".\\\"metricflow_time_spine\\\"\", \"raw_code\": \"SELECT to_date('02/20/2023', 'mm/dd/yyyy') as date_day\", \"language\": \"sql\", \"refs\": [], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [], \"nodes\": []}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"checksum\": null}, \"access\": \"protected\", \"constraints\": [], \"version\": null, \"latest_version\": null, \"deprecation_date\": null}, \"snapshot.test.snapshot_seed\": {\"database\": \"dbt\", \"schema\": \"test16970573770617803847_test_previous_version_state\", \"name\": \"snapshot_seed\", \"resource_type\": \"snapshot\", \"package_name\": \"test\", \"path\": \"snapshot_seed.sql\", \"original_file_path\": \"snapshots/snapshot_seed.sql\", \"unique_id\": \"snapshot.test.snapshot_seed\", \"fqn\": [\"test\", \"snapshot_seed\", \"snapshot_seed\"], \"alias\": \"snapshot_seed\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"5fc998f39655f8fe52443a919e749b6e23883ef90202b040412baac13c6bfe18\"}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"snapshot\", \"incremental_strategy\": null, \"persist_docs\": {}, \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": \"id\", \"on_schema_change\": \"ignore\", \"on_configuration_change\": \"apply\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"contract\": {\"enforced\": false}, \"strategy\": \"check\", \"target_schema\": \"test16970573770617803847_test_previous_version_state\", \"target_database\": null, \"updated_at\": null, \"check_cols\": \"all\", \"post-hook\": [], \"pre-hook\": []}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {\"unique_key\": \"id\", \"strategy\": \"check\", \"check_cols\": \"all\", \"target_schema\": \"test16970573770617803847_test_previous_version_state\"}, \"created_at\": 1697057377.471309, \"relation_name\": \"\\\"dbt\\\".\\\"test16970573770617803847_test_previous_version_state\\\".\\\"snapshot_seed\\\"\", \"raw_code\": \"\\n{{\\n    config(\\n      unique_key='id',\\n      strategy='check',\\n      check_cols='all',\\n      target_schema=schema,\\n    )\\n}}\\nselect * from {{ ref('my_seed') }}\\n\", \"language\": \"sql\", \"refs\": [{\"name\": \"my_seed\", \"package\": null, \"version\": null}], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [], \"nodes\": [\"seed.test.my_seed\"]}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"checksum\": null}}, \"analysis.test.a\": {\"database\": \"dbt\", \"schema\": \"test16970573770617803847_test_previous_version_state\", \"name\": \"a\", \"resource_type\": \"analysis\", \"package_name\": \"test\", \"path\": \"analysis/a.sql\", \"original_file_path\": \"analyses/a.sql\", \"unique_id\": \"analysis.test.a\", \"fqn\": [\"test\", \"analysis\", \"a\"], \"alias\": \"a\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"a389c282f569f0bbdc2a8a4f174dea746c28582fdaf2048d31d9226af9feab23\"}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"view\", \"incremental_strategy\": null, \"persist_docs\": {}, \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": null, \"on_schema_change\": \"ignore\", \"on_configuration_change\": \"apply\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"contract\": {\"enforced\": false}, \"post-hook\": [], \"pre-hook\": []}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {}, \"created_at\": 1697057377.492032, \"relation_name\": null, \"raw_code\": \"select 4 as id\", \"language\": \"sql\", \"refs\": [], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [], \"nodes\": []}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"checksum\": null}}, \"test.test.just_my\": {\"database\": \"dbt\", \"schema\": \"test16970573770617803847_test_previous_version_state_dbt_test__audit\", \"name\": \"just_my\", \"resource_type\": \"test\", \"package_name\": \"test\", \"path\": \"just_my.sql\", \"original_file_path\": \"tests/just_my.sql\", \"unique_id\": \"test.test.just_my\", \"fqn\": [\"test\", \"just_my\"], \"alias\": \"just_my\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"744889a2e2d9ce380619265e1217d7ccf6e6ca896c048d42ebe0f9cfb74d7156\"}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": \"dbt_test__audit\", \"database\": null, \"tags\": [\"data_test_tag\"], \"meta\": {}, \"group\": null, \"materialized\": \"test\", \"severity\": \"ERROR\", \"store_failures\": null, \"where\": null, \"limit\": null, \"fail_calc\": \"count(*)\", \"warn_if\": \"!= 0\", \"error_if\": \"!= 0\"}, \"tags\": [\"data_test_tag\"], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {\"tags\": [\"data_test_tag\"]}, \"created_at\": 1697057377.508335, \"relation_name\": null, \"raw_code\": \"{{ config(tags = ['data_test_tag']) }}\\n\\nselect * from {{ ref('my_model') }}\\nwhere false\", \"language\": \"sql\", \"refs\": [{\"name\": \"my_model\", \"package\": null, \"version\": null}], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [], \"nodes\": [\"model.test.my_model\"]}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"checksum\": null}}, \"seed.test.my_seed\": {\"database\": \"dbt\", \"schema\": \"test16970573770617803847_test_previous_version_state\", \"name\": \"my_seed\", \"resource_type\": \"seed\", \"package_name\": \"test\", \"path\": \"my_seed.csv\", \"original_file_path\": \"seeds/my_seed.csv\", \"unique_id\": \"seed.test.my_seed\", \"fqn\": [\"test\", \"my_seed\"], \"alias\": \"my_seed\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"f7ede83f36165ac6b7a047aa2c3f212dff385bfa9f35f395108cd06fc8e96943\"}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"seed\", \"incremental_strategy\": null, \"persist_docs\": {}, \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": null, \"on_schema_change\": \"ignore\", \"on_configuration_change\": \"apply\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"contract\": {\"enforced\": false}, \"quote_columns\": null, \"post-hook\": [], \"pre-hook\": []}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {}, \"created_at\": 1697057377.525708, \"relation_name\": \"\\\"dbt\\\".\\\"test16970573770617803847_test_previous_version_state\\\".\\\"my_seed\\\"\", \"raw_code\": \"\", \"root_path\": \"/private/var/folders/79/5290gpvn3lx5jdryk4844rm80000gn/T/pytest-of-quigleymalcolm/pytest-271/project0\", \"depends_on\": {\"macros\": []}}, \"test.test.not_null_my_model_id.43e0e9183a\": {\"test_metadata\": {\"name\": \"not_null\", \"kwargs\": {\"column_name\": \"id\", \"model\": \"{{ get_where_subquery(ref('my_model')) }}\"}, \"namespace\": null}, \"database\": \"dbt\", \"schema\": \"test16970573770617803847_test_previous_version_state_dbt_test__audit\", \"name\": \"not_null_my_model_id\", \"resource_type\": \"test\", \"package_name\": \"test\", \"path\": \"not_null_my_model_id.sql\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"test.test.not_null_my_model_id.43e0e9183a\", \"fqn\": [\"test\", \"not_null_my_model_id\"], \"alias\": \"not_null_my_model_id\", \"checksum\": {\"name\": \"none\", \"checksum\": \"\"}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": \"dbt_test__audit\", \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"test\", \"severity\": \"ERROR\", \"store_failures\": null, \"where\": null, \"limit\": null, \"fail_calc\": \"count(*)\", \"warn_if\": \"!= 0\", \"error_if\": \"!= 0\"}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {}, \"created_at\": 1697057377.552852, \"relation_name\": null, \"raw_code\": \"{{ test_not_null(**_dbt_generic_test_kwargs) }}\", \"language\": \"sql\", \"refs\": [{\"name\": \"my_model\", \"package\": null, \"version\": null}], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [\"macro.dbt.test_not_null\"], \"nodes\": [\"model.test.my_model\"]}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"checksum\": null}, \"column_name\": \"id\", \"file_key_name\": \"models.my_model\", \"attached_node\": \"model.test.my_model\"}, \"test.test.check_nothing_my_model_.d5a5e66110\": {\"test_metadata\": {\"name\": \"check_nothing\", \"kwargs\": {\"model\": \"{{ get_where_subquery(ref('my_model')) }}\"}, \"namespace\": null}, \"database\": \"dbt\", \"schema\": \"test16970573770617803847_test_previous_version_state_dbt_test__audit\", \"name\": \"check_nothing_my_model_\", \"resource_type\": \"test\", \"package_name\": \"test\", \"path\": \"check_nothing_my_model_.sql\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"test.test.check_nothing_my_model_.d5a5e66110\", \"fqn\": [\"test\", \"check_nothing_my_model_\"], \"alias\": \"check_nothing_my_model_\", \"checksum\": {\"name\": \"none\", \"checksum\": \"\"}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": \"dbt_test__audit\", \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"test\", \"severity\": \"ERROR\", \"store_failures\": null, \"where\": null, \"limit\": null, \"fail_calc\": \"count(*)\", \"warn_if\": \"!= 0\", \"error_if\": \"!= 0\"}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {}, \"created_at\": 1697057377.553834, \"relation_name\": null, \"raw_code\": \"{{ test_check_nothing(**_dbt_generic_test_kwargs) }}\", \"language\": \"sql\", \"refs\": [{\"name\": \"my_model\", \"package\": null, \"version\": null}], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [\"macro.test.test_check_nothing\", \"macro.dbt.get_where_subquery\"], \"nodes\": [\"model.test.my_model\"]}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"checksum\": null}, \"column_name\": null, \"file_key_name\": \"models.my_model\", \"attached_node\": \"model.test.my_model\"}}, \"sources\": {\"source.test.my_source.my_table\": {\"database\": \"dbt\", \"schema\": \"my_source\", \"name\": \"my_table\", \"resource_type\": \"source\", \"package_name\": \"test\", \"path\": \"models/schema.yml\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"source.test.my_source.my_table\", \"fqn\": [\"test\", \"my_source\", \"my_table\"], \"source_name\": \"my_source\", \"source_description\": \"My source\", \"loader\": \"a_loader\", \"identifier\": \"my_seed\", \"quoting\": {\"database\": null, \"schema\": null, \"identifier\": null, \"column\": null}, \"loaded_at_field\": null, \"freshness\": {\"warn_after\": {\"count\": null, \"period\": null}, \"error_after\": {\"count\": null, \"period\": null}, \"filter\": null}, \"external\": null, \"description\": \"My table\", \"columns\": {}, \"meta\": {}, \"source_meta\": {}, \"tags\": [], \"config\": {\"enabled\": true}, \"patch_path\": null, \"unrendered_config\": {}, \"relation_name\": \"\\\"dbt\\\".\\\"my_source\\\".\\\"my_seed\\\"\", \"created_at\": 1697057377.594166}}, \"macros\": {\"macro.test.test_check_nothing\": {\"name\": \"test_check_nothing\", \"resource_type\": \"macro\", \"package_name\": \"test\", \"path\": \"macros/dummy_test.sql\", \"original_file_path\": \"macros/dummy_test.sql\", \"unique_id\": \"macro.test.test_check_nothing\", \"macro_sql\": \"{% test check_nothing(model) %}\\n-- a silly test to make sure that table-level tests show up in the manifest\\n-- without a column_name field\\n\\nselect 0\\n\\n{% endtest %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.099874, \"supported_languages\": null}, \"macro.test.test_disabled_check_nothing\": {\"name\": \"test_disabled_check_nothing\", \"resource_type\": \"macro\", \"package_name\": \"test\", \"path\": \"macros/disabled_dummy_test.sql\", \"original_file_path\": \"macros/disabled_dummy_test.sql\", \"unique_id\": \"macro.test.test_disabled_check_nothing\", \"macro_sql\": \"{% test disabled_check_nothing(model) %}\\n-- a silly test to make sure that table-level tests show up in the manifest\\n-- without a column_name field\\n\\n{{ config(enabled=False) }}\\nselect 0\\n\\n{% endtest %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.1000938, \"supported_languages\": null}, \"macro.test.do_nothing\": {\"name\": \"do_nothing\", \"resource_type\": \"macro\", \"package_name\": \"test\", \"path\": \"macros/do_nothing.sql\", \"original_file_path\": \"macros/do_nothing.sql\", \"unique_id\": \"macro.test.do_nothing\", \"macro_sql\": \"{% macro do_nothing(foo2, bar2) %}\\n    select\\n        '{{ foo2 }}' as foo2,\\n        '{{ bar2 }}' as bar2\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.1002848, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__current_timestamp\": {\"name\": \"postgres__current_timestamp\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/timestamps.sql\", \"original_file_path\": \"macros/timestamps.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__current_timestamp\", \"macro_sql\": \"{% macro postgres__current_timestamp() -%}\\n    now()\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.1005828, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__snapshot_string_as_time\": {\"name\": \"postgres__snapshot_string_as_time\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/timestamps.sql\", \"original_file_path\": \"macros/timestamps.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__snapshot_string_as_time\", \"macro_sql\": \"{% macro postgres__snapshot_string_as_time(timestamp) -%}\\n    {%- set result = \\\"'\\\" ~ timestamp ~ \\\"'::timestamp without time zone\\\" -%}\\n    {{ return(result) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.10079, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__snapshot_get_time\": {\"name\": \"postgres__snapshot_get_time\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/timestamps.sql\", \"original_file_path\": \"macros/timestamps.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__snapshot_get_time\", \"macro_sql\": \"{% macro postgres__snapshot_get_time() -%}\\n  {{ current_timestamp() }}::timestamp without time zone\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.1009028, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__current_timestamp_backcompat\": {\"name\": \"postgres__current_timestamp_backcompat\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/timestamps.sql\", \"original_file_path\": \"macros/timestamps.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__current_timestamp_backcompat\", \"macro_sql\": \"{% macro postgres__current_timestamp_backcompat() %}\\n    current_timestamp::{{ type_timestamp() }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.type_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.101016, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__current_timestamp_in_utc_backcompat\": {\"name\": \"postgres__current_timestamp_in_utc_backcompat\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/timestamps.sql\", \"original_file_path\": \"macros/timestamps.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__current_timestamp_in_utc_backcompat\", \"macro_sql\": \"{% macro postgres__current_timestamp_in_utc_backcompat() %}\\n    (current_timestamp at time zone 'utc')::{{ type_timestamp() }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.type_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.101125, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_catalog\": {\"name\": \"postgres__get_catalog\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/catalog.sql\", \"original_file_path\": \"macros/catalog.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_catalog\", \"macro_sql\": \"{% macro postgres__get_catalog(information_schema, schemas) -%}\\n\\n  {%- call statement('catalog', fetch_result=True) -%}\\n    {#\\n      If the user has multiple databases set and the first one is wrong, this will fail.\\n      But we won't fail in the case where there are multiple quoting-difference-only dbs, which is better.\\n    #}\\n    {% set database = information_schema.database %}\\n    {{ adapter.verify_database(database) }}\\n\\n    select\\n        '{{ database }}' as table_database,\\n        sch.nspname as table_schema,\\n        tbl.relname as table_name,\\n        case tbl.relkind\\n            when 'v' then 'VIEW'\\n            else 'BASE TABLE'\\n        end as table_type,\\n        tbl_desc.description as table_comment,\\n        col.attname as column_name,\\n        col.attnum as column_index,\\n        pg_catalog.format_type(col.atttypid, col.atttypmod) as column_type,\\n        col_desc.description as column_comment,\\n        pg_get_userbyid(tbl.relowner) as table_owner\\n\\n    from pg_catalog.pg_namespace sch\\n    join pg_catalog.pg_class tbl on tbl.relnamespace = sch.oid\\n    join pg_catalog.pg_attribute col on col.attrelid = tbl.oid\\n    left outer join pg_catalog.pg_description tbl_desc on (tbl_desc.objoid = tbl.oid and tbl_desc.objsubid = 0)\\n    left outer join pg_catalog.pg_description col_desc on (col_desc.objoid = tbl.oid and col_desc.objsubid = col.attnum)\\n\\n    where (\\n        {%- for schema in schemas -%}\\n          upper(sch.nspname) = upper('{{ schema }}'){%- if not loop.last %} or {% endif -%}\\n        {%- endfor -%}\\n      )\\n      and not pg_is_other_temp_schema(sch.oid) -- not a temporary schema belonging to another session\\n      and tbl.relpersistence in ('p', 'u') -- [p]ermanent table or [u]nlogged table. Exclude [t]emporary tables\\n      and tbl.relkind in ('r', 'v', 'f', 'p') -- o[r]dinary table, [v]iew, [f]oreign table, [p]artitioned table. Other values are [i]ndex, [S]equence, [c]omposite type, [t]OAST table, [m]aterialized view\\n      and col.attnum > 0 -- negative numbers are used for system columns such as oid\\n      and not col.attisdropped -- column as not been dropped\\n\\n    order by\\n        sch.nspname,\\n        tbl.relname,\\n        col.attnum\\n\\n  {%- endcall -%}\\n\\n  {{ return(load_result('catalog').table) }}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.1022131, \"supported_languages\": null}, \"macro.dbt_postgres.postgres_get_relations\": {\"name\": \"postgres_get_relations\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/relations.sql\", \"original_file_path\": \"macros/relations.sql\", \"unique_id\": \"macro.dbt_postgres.postgres_get_relations\", \"macro_sql\": \"{% macro postgres_get_relations () -%}\\n\\n  {#\\n      -- in pg_depend, objid is the dependent, refobjid is the referenced object\\n      --  > a pg_depend entry indicates that the referenced object cannot be\\n      --  > dropped without also dropping the dependent object.\\n  #}\\n\\n  {%- call statement('relations', fetch_result=True) -%}\\n    with relation as (\\n        select\\n            pg_rewrite.ev_class as class,\\n            pg_rewrite.oid as id\\n        from pg_rewrite\\n    ),\\n    class as (\\n        select\\n            oid as id,\\n            relname as name,\\n            relnamespace as schema,\\n            relkind as kind\\n        from pg_class\\n    ),\\n    dependency as (\\n        select distinct\\n            pg_depend.objid as id,\\n            pg_depend.refobjid as ref\\n        from pg_depend\\n    ),\\n    schema as (\\n        select\\n            pg_namespace.oid as id,\\n            pg_namespace.nspname as name\\n        from pg_namespace\\n        where nspname != 'information_schema' and nspname not like 'pg\\\\_%'\\n    ),\\n    referenced as (\\n        select\\n            relation.id AS id,\\n            referenced_class.name ,\\n            referenced_class.schema ,\\n            referenced_class.kind\\n        from relation\\n        join class as referenced_class on relation.class=referenced_class.id\\n        where referenced_class.kind in ('r', 'v', 'm')\\n    ),\\n    relationships as (\\n        select\\n            referenced.name as referenced_name,\\n            referenced.schema as referenced_schema_id,\\n            dependent_class.name as dependent_name,\\n            dependent_class.schema as dependent_schema_id,\\n            referenced.kind as kind\\n        from referenced\\n        join dependency on referenced.id=dependency.id\\n        join class as dependent_class on dependency.ref=dependent_class.id\\n        where\\n            (referenced.name != dependent_class.name or\\n             referenced.schema != dependent_class.schema)\\n    )\\n\\n    select\\n        referenced_schema.name as referenced_schema,\\n        relationships.referenced_name as referenced_name,\\n        dependent_schema.name as dependent_schema,\\n        relationships.dependent_name as dependent_name\\n    from relationships\\n    join schema as dependent_schema on relationships.dependent_schema_id=dependent_schema.id\\n    join schema as referenced_schema on relationships.referenced_schema_id=referenced_schema.id\\n    group by referenced_schema, referenced_name, dependent_schema, dependent_name\\n    order by referenced_schema, referenced_name, dependent_schema, dependent_name;\\n\\n  {%- endcall -%}\\n\\n  {{ return(load_result('relations').table) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.1028638, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__create_table_as\": {\"name\": \"postgres__create_table_as\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__create_table_as\", \"macro_sql\": \"{% macro postgres__create_table_as(temporary, relation, sql) -%}\\n  {%- set unlogged = config.get('unlogged', default=false) -%}\\n  {%- set sql_header = config.get('sql_header', none) -%}\\n\\n  {{ sql_header if sql_header is not none }}\\n\\n  create {% if temporary -%}\\n    temporary\\n  {%- elif unlogged -%}\\n    unlogged\\n  {%- endif %} table {{ relation }}\\n  {% set contract_config = config.get('contract') %}\\n  {% if contract_config.enforced and (not temporary) %}\\n    {{ get_assert_columns_equivalent(sql) }}\\n    {{ get_table_columns_and_constraints() }} ;\\n    insert into {{ relation }} (\\n      {{ adapter.dispatch('get_column_names', 'dbt')() }}\\n    )\\n    {%- set sql = get_select_subquery(sql) %}\\n  {% else %}\\n    as\\n  {% endif %}\\n  (\\n    {{ sql }}\\n  );\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_assert_columns_equivalent\", \"macro.dbt.get_table_columns_and_constraints\", \"macro.dbt.default__get_column_names\", \"macro.dbt.get_select_subquery\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.1119502, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_create_index_sql\": {\"name\": \"postgres__get_create_index_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_create_index_sql\", \"macro_sql\": \"{% macro postgres__get_create_index_sql(relation, index_dict) -%}\\n  {%- set index_config = adapter.parse_index(index_dict) -%}\\n  {%- set comma_separated_columns = \\\", \\\".join(index_config.columns) -%}\\n  {%- set index_name = index_config.render(relation) -%}\\n\\n  create {% if index_config.unique -%}\\n    unique\\n  {%- endif %} index if not exists\\n  \\\"{{ index_name }}\\\"\\n  on {{ relation }} {% if index_config.type -%}\\n    using {{ index_config.type }}\\n  {%- endif %}\\n  ({{ comma_separated_columns }});\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.112461, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__create_schema\": {\"name\": \"postgres__create_schema\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__create_schema\", \"macro_sql\": \"{% macro postgres__create_schema(relation) -%}\\n  {% if relation.database -%}\\n    {{ adapter.verify_database(relation.database) }}\\n  {%- endif -%}\\n  {%- call statement('create_schema') -%}\\n    create schema if not exists {{ relation.without_identifier().include(database=False) }}\\n  {%- endcall -%}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.112787, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__drop_schema\": {\"name\": \"postgres__drop_schema\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__drop_schema\", \"macro_sql\": \"{% macro postgres__drop_schema(relation) -%}\\n  {% if relation.database -%}\\n    {{ adapter.verify_database(relation.database) }}\\n  {%- endif -%}\\n  {%- call statement('drop_schema') -%}\\n    drop schema if exists {{ relation.without_identifier().include(database=False) }} cascade\\n  {%- endcall -%}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.113112, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_columns_in_relation\": {\"name\": \"postgres__get_columns_in_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_columns_in_relation\", \"macro_sql\": \"{% macro postgres__get_columns_in_relation(relation) -%}\\n  {% call statement('get_columns_in_relation', fetch_result=True) %}\\n      select\\n          column_name,\\n          data_type,\\n          character_maximum_length,\\n          numeric_precision,\\n          numeric_scale\\n\\n      from {{ relation.information_schema('columns') }}\\n      where table_name = '{{ relation.identifier }}'\\n        {% if relation.schema %}\\n        and table_schema = '{{ relation.schema }}'\\n        {% endif %}\\n      order by ordinal_position\\n\\n  {% endcall %}\\n  {% set table = load_result('get_columns_in_relation').table %}\\n  {{ return(sql_convert_columns_in_relation(table)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\", \"macro.dbt.sql_convert_columns_in_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.113596, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__list_relations_without_caching\": {\"name\": \"postgres__list_relations_without_caching\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__list_relations_without_caching\", \"macro_sql\": \"{% macro postgres__list_relations_without_caching(schema_relation) %}\\n  {% call statement('list_relations_without_caching', fetch_result=True) -%}\\n    select\\n      '{{ schema_relation.database }}' as database,\\n      tablename as name,\\n      schemaname as schema,\\n      'table' as type\\n    from pg_tables\\n    where schemaname ilike '{{ schema_relation.schema }}'\\n    union all\\n    select\\n      '{{ schema_relation.database }}' as database,\\n      viewname as name,\\n      schemaname as schema,\\n      'view' as type\\n    from pg_views\\n    where schemaname ilike '{{ schema_relation.schema }}'\\n    union all\\n    select\\n      '{{ schema_relation.database }}' as database,\\n      matviewname as name,\\n      schemaname as schema,\\n      'materialized_view' as type\\n    from pg_matviews\\n    where schemaname ilike '{{ schema_relation.schema }}'\\n  {% endcall %}\\n  {{ return(load_result('list_relations_without_caching').table) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.114043, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__information_schema_name\": {\"name\": \"postgres__information_schema_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__information_schema_name\", \"macro_sql\": \"{% macro postgres__information_schema_name(database) -%}\\n  {% if database_name -%}\\n    {{ adapter.verify_database(database_name) }}\\n  {%- endif -%}\\n  information_schema\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.114221, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__list_schemas\": {\"name\": \"postgres__list_schemas\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__list_schemas\", \"macro_sql\": \"{% macro postgres__list_schemas(database) %}\\n  {% if database -%}\\n    {{ adapter.verify_database(database) }}\\n  {%- endif -%}\\n  {% call statement('list_schemas', fetch_result=True, auto_begin=False) %}\\n    select distinct nspname from pg_namespace\\n  {% endcall %}\\n  {{ return(load_result('list_schemas').table) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.1145759, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__check_schema_exists\": {\"name\": \"postgres__check_schema_exists\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__check_schema_exists\", \"macro_sql\": \"{% macro postgres__check_schema_exists(information_schema, schema) -%}\\n  {% if information_schema.database -%}\\n    {{ adapter.verify_database(information_schema.database) }}\\n  {%- endif -%}\\n  {% call statement('check_schema_exists', fetch_result=True, auto_begin=False) %}\\n    select count(*) from pg_namespace where nspname = '{{ schema }}'\\n  {% endcall %}\\n  {{ return(load_result('check_schema_exists').table) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.1149912, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__make_relation_with_suffix\": {\"name\": \"postgres__make_relation_with_suffix\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__make_relation_with_suffix\", \"macro_sql\": \"{% macro postgres__make_relation_with_suffix(base_relation, suffix, dstring) %}\\n    {% if dstring %}\\n      {% set dt = modules.datetime.datetime.now() %}\\n      {% set dtstring = dt.strftime(\\\"%H%M%S%f\\\") %}\\n      {% set suffix = suffix ~ dtstring %}\\n    {% endif %}\\n    {% set suffix_length = suffix|length %}\\n    {% set relation_max_name_length = base_relation.relation_max_name_length() %}\\n    {% if suffix_length > relation_max_name_length %}\\n        {% do exceptions.raise_compiler_error('Relation suffix is too long (' ~ suffix_length ~ ' characters). Maximum length is ' ~ relation_max_name_length ~ ' characters.') %}\\n    {% endif %}\\n    {% set identifier = base_relation.identifier[:relation_max_name_length - suffix_length] ~ suffix %}\\n\\n    {{ return(base_relation.incorporate(path={\\\"identifier\\\": identifier })) }}\\n\\n  {% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.1158679, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__make_intermediate_relation\": {\"name\": \"postgres__make_intermediate_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__make_intermediate_relation\", \"macro_sql\": \"{% macro postgres__make_intermediate_relation(base_relation, suffix) %}\\n    {{ return(postgres__make_relation_with_suffix(base_relation, suffix, dstring=False)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_relation_with_suffix\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.1160781, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__make_temp_relation\": {\"name\": \"postgres__make_temp_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__make_temp_relation\", \"macro_sql\": \"{% macro postgres__make_temp_relation(base_relation, suffix) %}\\n    {% set temp_relation = postgres__make_relation_with_suffix(base_relation, suffix, dstring=True) %}\\n    {{ return(temp_relation.incorporate(path={\\\"schema\\\": none,\\n                                              \\\"database\\\": none})) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_relation_with_suffix\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.116409, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__make_backup_relation\": {\"name\": \"postgres__make_backup_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__make_backup_relation\", \"macro_sql\": \"{% macro postgres__make_backup_relation(base_relation, backup_relation_type, suffix) %}\\n    {% set backup_relation = postgres__make_relation_with_suffix(base_relation, suffix, dstring=False) %}\\n    {{ return(backup_relation.incorporate(type=backup_relation_type)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_relation_with_suffix\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.116695, \"supported_languages\": null}, \"macro.dbt_postgres.postgres_escape_comment\": {\"name\": \"postgres_escape_comment\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres_escape_comment\", \"macro_sql\": \"{% macro postgres_escape_comment(comment) -%}\\n  {% if comment is not string %}\\n    {% do exceptions.raise_compiler_error('cannot escape a non-string: ' ~ comment) %}\\n  {% endif %}\\n  {%- set magic = '$dbt_comment_literal_block$' -%}\\n  {%- if magic in comment -%}\\n    {%- do exceptions.raise_compiler_error('The string ' ~ magic ~ ' is not allowed in comments.') -%}\\n  {%- endif -%}\\n  {{ magic }}{{ comment }}{{ magic }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.117132, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__alter_relation_comment\": {\"name\": \"postgres__alter_relation_comment\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__alter_relation_comment\", \"macro_sql\": \"{% macro postgres__alter_relation_comment(relation, comment) %}\\n  {% set escaped_comment = postgres_escape_comment(comment) %}\\n  comment on {{ relation.type }} {{ relation }} is {{ escaped_comment }};\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres_escape_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.117368, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__alter_column_comment\": {\"name\": \"postgres__alter_column_comment\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__alter_column_comment\", \"macro_sql\": \"{% macro postgres__alter_column_comment(relation, column_dict) %}\\n  {% set existing_columns = adapter.get_columns_in_relation(relation) | map(attribute=\\\"name\\\") | list %}\\n  {% for column_name in column_dict if (column_name in existing_columns) %}\\n    {% set comment = column_dict[column_name]['description'] %}\\n    {% set escaped_comment = postgres_escape_comment(comment) %}\\n    comment on column {{ relation }}.{{ adapter.quote(column_name) if column_dict[column_name]['quote'] else column_name }} is {{ escaped_comment }};\\n  {% endfor %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres_escape_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.117985, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_show_grant_sql\": {\"name\": \"postgres__get_show_grant_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_show_grant_sql\", \"macro_sql\": \"\\n\\n{%- macro postgres__get_show_grant_sql(relation) -%}\\n  select grantee, privilege_type\\n  from {{ relation.information_schema('role_table_grants') }}\\n      where grantor = current_role\\n        and grantee != current_role\\n        and table_schema = '{{ relation.schema }}'\\n        and table_name = '{{ relation.identifier }}'\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.118195, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__copy_grants\": {\"name\": \"postgres__copy_grants\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__copy_grants\", \"macro_sql\": \"{% macro postgres__copy_grants() %}\\n    {{ return(False) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.118315, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_show_indexes_sql\": {\"name\": \"postgres__get_show_indexes_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_show_indexes_sql\", \"macro_sql\": \"{% macro postgres__get_show_indexes_sql(relation) %}\\n    select\\n        i.relname                                   as name,\\n        m.amname                                    as method,\\n        ix.indisunique                              as \\\"unique\\\",\\n        array_to_string(array_agg(a.attname), ',')  as column_names\\n    from pg_index ix\\n    join pg_class i\\n        on i.oid = ix.indexrelid\\n    join pg_am m\\n        on m.oid=i.relam\\n    join pg_class t\\n        on t.oid = ix.indrelid\\n    join pg_namespace n\\n        on n.oid = t.relnamespace\\n    join pg_attribute a\\n        on a.attrelid = t.oid\\n        and a.attnum = ANY(ix.indkey)\\n    where t.relname = '{{ relation.identifier }}'\\n      and n.nspname = '{{ relation.schema }}'\\n      and t.relkind in ('r', 'm')\\n    group by 1, 2, 3\\n    order by 1, 2, 3\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.118505, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_drop_index_sql\": {\"name\": \"postgres__get_drop_index_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_drop_index_sql\", \"macro_sql\": \"\\n\\n\\n{%- macro postgres__get_drop_index_sql(relation, index_name) -%}\\n    drop index if exists \\\"{{ relation.schema }}\\\".\\\"{{ index_name }}\\\"\\n{%- endmacro -%}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.118647, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_alter_materialized_view_as_sql\": {\"name\": \"postgres__get_alter_materialized_view_as_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/materializations/materialized_view.sql\", \"original_file_path\": \"macros/materializations/materialized_view.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_alter_materialized_view_as_sql\", \"macro_sql\": \"{% macro postgres__get_alter_materialized_view_as_sql(\\n    relation,\\n    configuration_changes,\\n    sql,\\n    existing_relation,\\n    backup_relation,\\n    intermediate_relation\\n) %}\\n\\n    -- apply a full refresh immediately if needed\\n    {% if configuration_changes.requires_full_refresh %}\\n\\n        {{ get_replace_materialized_view_as_sql(relation, sql, existing_relation, backup_relation, intermediate_relation) }}\\n\\n    -- otherwise apply individual changes as needed\\n    {% else %}\\n\\n        {{ postgres__update_indexes_on_materialized_view(relation, configuration_changes.indexes) }}\\n\\n    {%- endif -%}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_replace_materialized_view_as_sql\", \"macro.dbt_postgres.postgres__update_indexes_on_materialized_view\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.120726, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_create_materialized_view_as_sql\": {\"name\": \"postgres__get_create_materialized_view_as_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/materializations/materialized_view.sql\", \"original_file_path\": \"macros/materializations/materialized_view.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_create_materialized_view_as_sql\", \"macro_sql\": \"{% macro postgres__get_create_materialized_view_as_sql(relation, sql) %}\\n    create materialized view if not exists {{ relation }} as {{ sql }};\\n\\n    {% for _index_dict in config.get('indexes', []) -%}\\n        {{- get_create_index_sql(relation, _index_dict) -}}\\n    {%- endfor -%}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_create_index_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.121023, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_replace_materialized_view_as_sql\": {\"name\": \"postgres__get_replace_materialized_view_as_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/materializations/materialized_view.sql\", \"original_file_path\": \"macros/materializations/materialized_view.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_replace_materialized_view_as_sql\", \"macro_sql\": \"{% macro postgres__get_replace_materialized_view_as_sql(relation, sql, existing_relation, backup_relation, intermediate_relation) %}\\n    {{- get_create_materialized_view_as_sql(intermediate_relation, sql) -}}\\n\\n    {% if existing_relation is not none %}\\n        alter materialized view {{ existing_relation }} rename to {{ backup_relation.include(database=False, schema=False) }};\\n    {% endif %}\\n\\n    alter materialized view {{ intermediate_relation }} rename to {{ relation.include(database=False, schema=False) }};\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_create_materialized_view_as_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.121473, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_materialized_view_configuration_changes\": {\"name\": \"postgres__get_materialized_view_configuration_changes\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/materializations/materialized_view.sql\", \"original_file_path\": \"macros/materializations/materialized_view.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_materialized_view_configuration_changes\", \"macro_sql\": \"{% macro postgres__get_materialized_view_configuration_changes(existing_relation, new_config) %}\\n    {% set _existing_materialized_view = postgres__describe_materialized_view(existing_relation) %}\\n    {% set _configuration_changes = existing_relation.get_materialized_view_config_change_collection(_existing_materialized_view, new_config) %}\\n    {% do return(_configuration_changes) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__describe_materialized_view\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.121773, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__refresh_materialized_view\": {\"name\": \"postgres__refresh_materialized_view\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/materializations/materialized_view.sql\", \"original_file_path\": \"macros/materializations/materialized_view.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__refresh_materialized_view\", \"macro_sql\": \"{% macro postgres__refresh_materialized_view(relation) %}\\n    refresh materialized view {{ relation }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.1218822, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__update_indexes_on_materialized_view\": {\"name\": \"postgres__update_indexes_on_materialized_view\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/materializations/materialized_view.sql\", \"original_file_path\": \"macros/materializations/materialized_view.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__update_indexes_on_materialized_view\", \"macro_sql\": \"\\n\\n\\n{%- macro postgres__update_indexes_on_materialized_view(relation, index_changes) -%}\\n    {{- log(\\\"Applying UPDATE INDEXES to: \\\" ~ relation) -}}\\n\\n    {%- for _index_change in index_changes -%}\\n        {%- set _index = _index_change.context -%}\\n\\n        {%- if _index_change.action == \\\"drop\\\" -%}\\n\\n            {{ postgres__get_drop_index_sql(relation, _index.name) }};\\n\\n        {%- elif _index_change.action == \\\"create\\\" -%}\\n\\n            {{ postgres__get_create_index_sql(relation, _index.as_node_config) }}\\n\\n        {%- endif -%}\\n\\n    {%- endfor -%}\\n\\n{%- endmacro -%}\\n\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_drop_index_sql\", \"macro.dbt_postgres.postgres__get_create_index_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.122449, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__describe_materialized_view\": {\"name\": \"postgres__describe_materialized_view\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/materializations/materialized_view.sql\", \"original_file_path\": \"macros/materializations/materialized_view.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__describe_materialized_view\", \"macro_sql\": \"{% macro postgres__describe_materialized_view(relation) %}\\n    -- for now just get the indexes, we don't need the name or the query yet\\n    {% set _indexes = run_query(get_show_indexes_sql(relation)) %}\\n    {% do return({'indexes': _indexes}) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.run_query\", \"macro.dbt.get_show_indexes_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.122707, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_incremental_default_sql\": {\"name\": \"postgres__get_incremental_default_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/materializations/incremental_strategies.sql\", \"original_file_path\": \"macros/materializations/incremental_strategies.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_incremental_default_sql\", \"macro_sql\": \"{% macro postgres__get_incremental_default_sql(arg_dict) %}\\n\\n  {% if arg_dict[\\\"unique_key\\\"] %}\\n    {% do return(get_incremental_delete_insert_sql(arg_dict)) %}\\n  {% else %}\\n    {% do return(get_incremental_append_sql(arg_dict)) %}\\n  {% endif %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_incremental_delete_insert_sql\", \"macro.dbt.get_incremental_append_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.123094, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__snapshot_merge_sql\": {\"name\": \"postgres__snapshot_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/materializations/snapshot_merge.sql\", \"original_file_path\": \"macros/materializations/snapshot_merge.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__snapshot_merge_sql\", \"macro_sql\": \"{% macro postgres__snapshot_merge_sql(target, source, insert_cols) -%}\\n    {%- set insert_cols_csv = insert_cols | join(', ') -%}\\n\\n    update {{ target }}\\n    set dbt_valid_to = DBT_INTERNAL_SOURCE.dbt_valid_to\\n    from {{ source }} as DBT_INTERNAL_SOURCE\\n    where DBT_INTERNAL_SOURCE.dbt_scd_id::text = {{ target }}.dbt_scd_id::text\\n      and DBT_INTERNAL_SOURCE.dbt_change_type::text in ('update'::text, 'delete'::text)\\n      and {{ target }}.dbt_valid_to is null;\\n\\n    insert into {{ target }} ({{ insert_cols_csv }})\\n    select {% for column in insert_cols -%}\\n        DBT_INTERNAL_SOURCE.{{ column }} {%- if not loop.last %}, {%- endif %}\\n    {%- endfor %}\\n    from {{ source }} as DBT_INTERNAL_SOURCE\\n    where DBT_INTERNAL_SOURCE.dbt_change_type::text = 'insert'::text;\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.123816, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__dateadd\": {\"name\": \"postgres__dateadd\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/utils/dateadd.sql\", \"original_file_path\": \"macros/utils/dateadd.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__dateadd\", \"macro_sql\": \"{% macro postgres__dateadd(datepart, interval, from_date_or_timestamp) %}\\n\\n    {{ from_date_or_timestamp }} + ((interval '1 {{ datepart }}') * ({{ interval }}))\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.124038, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__listagg\": {\"name\": \"postgres__listagg\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/utils/listagg.sql\", \"original_file_path\": \"macros/utils/listagg.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__listagg\", \"macro_sql\": \"{% macro postgres__listagg(measure, delimiter_text, order_by_clause, limit_num) -%}\\n\\n    {% if limit_num -%}\\n    array_to_string(\\n        (array_agg(\\n            {{ measure }}\\n            {% if order_by_clause -%}\\n            {{ order_by_clause }}\\n            {%- endif %}\\n        ))[1:{{ limit_num }}],\\n        {{ delimiter_text }}\\n        )\\n    {%- else %}\\n    string_agg(\\n        {{ measure }},\\n        {{ delimiter_text }}\\n        {% if order_by_clause -%}\\n        {{ order_by_clause }}\\n        {%- endif %}\\n        )\\n    {%- endif %}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.124678, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__datediff\": {\"name\": \"postgres__datediff\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/utils/datediff.sql\", \"original_file_path\": \"macros/utils/datediff.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__datediff\", \"macro_sql\": \"{% macro postgres__datediff(first_date, second_date, datepart) -%}\\n\\n    {% if datepart == 'year' %}\\n        (date_part('year', ({{second_date}})::date) - date_part('year', ({{first_date}})::date))\\n    {% elif datepart == 'quarter' %}\\n        ({{ datediff(first_date, second_date, 'year') }} * 4 + date_part('quarter', ({{second_date}})::date) - date_part('quarter', ({{first_date}})::date))\\n    {% elif datepart == 'month' %}\\n        ({{ datediff(first_date, second_date, 'year') }} * 12 + date_part('month', ({{second_date}})::date) - date_part('month', ({{first_date}})::date))\\n    {% elif datepart == 'day' %}\\n        (({{second_date}})::date - ({{first_date}})::date)\\n    {% elif datepart == 'week' %}\\n        ({{ datediff(first_date, second_date, 'day') }} / 7 + case\\n            when date_part('dow', ({{first_date}})::timestamp) <= date_part('dow', ({{second_date}})::timestamp) then\\n                case when {{first_date}} <= {{second_date}} then 0 else -1 end\\n            else\\n                case when {{first_date}} <= {{second_date}} then 1 else 0 end\\n        end)\\n    {% elif datepart == 'hour' %}\\n        ({{ datediff(first_date, second_date, 'day') }} * 24 + date_part('hour', ({{second_date}})::timestamp) - date_part('hour', ({{first_date}})::timestamp))\\n    {% elif datepart == 'minute' %}\\n        ({{ datediff(first_date, second_date, 'hour') }} * 60 + date_part('minute', ({{second_date}})::timestamp) - date_part('minute', ({{first_date}})::timestamp))\\n    {% elif datepart == 'second' %}\\n        ({{ datediff(first_date, second_date, 'minute') }} * 60 + floor(date_part('second', ({{second_date}})::timestamp)) - floor(date_part('second', ({{first_date}})::timestamp)))\\n    {% elif datepart == 'millisecond' %}\\n        ({{ datediff(first_date, second_date, 'minute') }} * 60000 + floor(date_part('millisecond', ({{second_date}})::timestamp)) - floor(date_part('millisecond', ({{first_date}})::timestamp)))\\n    {% elif datepart == 'microsecond' %}\\n        ({{ datediff(first_date, second_date, 'minute') }} * 60000000 + floor(date_part('microsecond', ({{second_date}})::timestamp)) - floor(date_part('microsecond', ({{first_date}})::timestamp)))\\n    {% else %}\\n        {{ exceptions.raise_compiler_error(\\\"Unsupported datepart for macro datediff in postgres: {!r}\\\".format(datepart)) }}\\n    {% endif %}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.datediff\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.127991, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__any_value\": {\"name\": \"postgres__any_value\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/utils/any_value.sql\", \"original_file_path\": \"macros/utils/any_value.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__any_value\", \"macro_sql\": \"{% macro postgres__any_value(expression) -%}\\n\\n    min({{ expression }})\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.128149, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__last_day\": {\"name\": \"postgres__last_day\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/utils/last_day.sql\", \"original_file_path\": \"macros/utils/last_day.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__last_day\", \"macro_sql\": \"{% macro postgres__last_day(date, datepart) -%}\\n\\n    {%- if datepart == 'quarter' -%}\\n    -- postgres dateadd does not support quarter interval.\\n    cast(\\n        {{dbt.dateadd('day', '-1',\\n        dbt.dateadd('month', '3', dbt.date_trunc(datepart, date))\\n        )}}\\n        as date)\\n    {%- else -%}\\n    {{dbt.default_last_day(date, datepart)}}\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.dateadd\", \"macro.dbt.date_trunc\", \"macro.dbt.default_last_day\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.1286578, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__split_part\": {\"name\": \"postgres__split_part\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/utils/split_part.sql\", \"original_file_path\": \"macros/utils/split_part.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__split_part\", \"macro_sql\": \"{% macro postgres__split_part(string_text, delimiter_text, part_number) %}\\n\\n  {% if part_number >= 0 %}\\n    {{ dbt.default__split_part(string_text, delimiter_text, part_number) }}\\n  {% else %}\\n    {{ dbt._split_part_negative(string_text, delimiter_text, part_number) }}\\n  {% endif %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__split_part\", \"macro.dbt._split_part_negative\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.129076, \"supported_languages\": null}, \"macro.dbt.run_hooks\": {\"name\": \"run_hooks\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"unique_id\": \"macro.dbt.run_hooks\", \"macro_sql\": \"{% macro run_hooks(hooks, inside_transaction=True) %}\\n  {% for hook in hooks | selectattr('transaction', 'equalto', inside_transaction)  %}\\n    {% if not inside_transaction and loop.first %}\\n      {% call statement(auto_begin=inside_transaction) %}\\n        commit;\\n      {% endcall %}\\n    {% endif %}\\n    {% set rendered = render(hook.get('sql')) | trim %}\\n    {% if (rendered | length) > 0 %}\\n      {% call statement(auto_begin=inside_transaction) %}\\n        {{ rendered }}\\n      {% endcall %}\\n    {% endif %}\\n  {% endfor %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.130199, \"supported_languages\": null}, \"macro.dbt.make_hook_config\": {\"name\": \"make_hook_config\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"unique_id\": \"macro.dbt.make_hook_config\", \"macro_sql\": \"{% macro make_hook_config(sql, inside_transaction) %}\\n    {{ tojson({\\\"sql\\\": sql, \\\"transaction\\\": inside_transaction}) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.130403, \"supported_languages\": null}, \"macro.dbt.before_begin\": {\"name\": \"before_begin\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"unique_id\": \"macro.dbt.before_begin\", \"macro_sql\": \"{% macro before_begin(sql) %}\\n    {{ make_hook_config(sql, inside_transaction=False) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.make_hook_config\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.130552, \"supported_languages\": null}, \"macro.dbt.in_transaction\": {\"name\": \"in_transaction\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"unique_id\": \"macro.dbt.in_transaction\", \"macro_sql\": \"{% macro in_transaction(sql) %}\\n    {{ make_hook_config(sql, inside_transaction=True) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.make_hook_config\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.1307, \"supported_languages\": null}, \"macro.dbt.after_commit\": {\"name\": \"after_commit\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"unique_id\": \"macro.dbt.after_commit\", \"macro_sql\": \"{% macro after_commit(sql) %}\\n    {{ make_hook_config(sql, inside_transaction=False) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.make_hook_config\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.1308448, \"supported_languages\": null}, \"macro.dbt.set_sql_header\": {\"name\": \"set_sql_header\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/configs.sql\", \"original_file_path\": \"macros/materializations/configs.sql\", \"unique_id\": \"macro.dbt.set_sql_header\", \"macro_sql\": \"{% macro set_sql_header(config) -%}\\n  {{ config.set('sql_header', caller()) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.131226, \"supported_languages\": null}, \"macro.dbt.should_full_refresh\": {\"name\": \"should_full_refresh\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/configs.sql\", \"original_file_path\": \"macros/materializations/configs.sql\", \"unique_id\": \"macro.dbt.should_full_refresh\", \"macro_sql\": \"{% macro should_full_refresh() %}\\n  {% set config_full_refresh = config.get('full_refresh') %}\\n  {% if config_full_refresh is none %}\\n    {% set config_full_refresh = flags.FULL_REFRESH %}\\n  {% endif %}\\n  {% do return(config_full_refresh) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.131537, \"supported_languages\": null}, \"macro.dbt.should_store_failures\": {\"name\": \"should_store_failures\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/configs.sql\", \"original_file_path\": \"macros/materializations/configs.sql\", \"unique_id\": \"macro.dbt.should_store_failures\", \"macro_sql\": \"{% macro should_store_failures() %}\\n  {% set config_store_failures = config.get('store_failures') %}\\n  {% if config_store_failures is none %}\\n    {% set config_store_failures = flags.STORE_FAILURES %}\\n  {% endif %}\\n  {% do return(config_store_failures) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.1318662, \"supported_languages\": null}, \"macro.dbt.snapshot_merge_sql\": {\"name\": \"snapshot_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/snapshot_merge.sql\", \"original_file_path\": \"macros/materializations/snapshots/snapshot_merge.sql\", \"unique_id\": \"macro.dbt.snapshot_merge_sql\", \"macro_sql\": \"{% macro snapshot_merge_sql(target, source, insert_cols) -%}\\n  {{ adapter.dispatch('snapshot_merge_sql', 'dbt')(target, source, insert_cols) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__snapshot_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.13231, \"supported_languages\": null}, \"macro.dbt.default__snapshot_merge_sql\": {\"name\": \"default__snapshot_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/snapshot_merge.sql\", \"original_file_path\": \"macros/materializations/snapshots/snapshot_merge.sql\", \"unique_id\": \"macro.dbt.default__snapshot_merge_sql\", \"macro_sql\": \"{% macro default__snapshot_merge_sql(target, source, insert_cols) -%}\\n    {%- set insert_cols_csv = insert_cols | join(', ') -%}\\n\\n    merge into {{ target }} as DBT_INTERNAL_DEST\\n    using {{ source }} as DBT_INTERNAL_SOURCE\\n    on DBT_INTERNAL_SOURCE.dbt_scd_id = DBT_INTERNAL_DEST.dbt_scd_id\\n\\n    when matched\\n     and DBT_INTERNAL_DEST.dbt_valid_to is null\\n     and DBT_INTERNAL_SOURCE.dbt_change_type in ('update', 'delete')\\n        then update\\n        set dbt_valid_to = DBT_INTERNAL_SOURCE.dbt_valid_to\\n\\n    when not matched\\n     and DBT_INTERNAL_SOURCE.dbt_change_type = 'insert'\\n        then insert ({{ insert_cols_csv }})\\n        values ({{ insert_cols_csv }})\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.132591, \"supported_languages\": null}, \"macro.dbt.strategy_dispatch\": {\"name\": \"strategy_dispatch\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"unique_id\": \"macro.dbt.strategy_dispatch\", \"macro_sql\": \"{% macro strategy_dispatch(name) -%}\\n{% set original_name = name %}\\n  {% if '.' in name %}\\n    {% set package_name, name = name.split(\\\".\\\", 1) %}\\n  {% else %}\\n    {% set package_name = none %}\\n  {% endif %}\\n\\n  {% if package_name is none %}\\n    {% set package_context = context %}\\n  {% elif package_name in context %}\\n    {% set package_context = context[package_name] %}\\n  {% else %}\\n    {% set error_msg %}\\n        Could not find package '{{package_name}}', called with '{{original_name}}'\\n    {% endset %}\\n    {{ exceptions.raise_compiler_error(error_msg | trim) }}\\n  {% endif %}\\n\\n  {%- set search_name = 'snapshot_' ~ name ~ '_strategy' -%}\\n\\n  {% if search_name not in package_context %}\\n    {% set error_msg %}\\n        The specified strategy macro '{{name}}' was not found in package '{{ package_name }}'\\n    {% endset %}\\n    {{ exceptions.raise_compiler_error(error_msg | trim) }}\\n  {% endif %}\\n  {{ return(package_context[search_name]) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.136333, \"supported_languages\": null}, \"macro.dbt.snapshot_hash_arguments\": {\"name\": \"snapshot_hash_arguments\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"unique_id\": \"macro.dbt.snapshot_hash_arguments\", \"macro_sql\": \"{% macro snapshot_hash_arguments(args) -%}\\n  {{ adapter.dispatch('snapshot_hash_arguments', 'dbt')(args) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__snapshot_hash_arguments\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.13651, \"supported_languages\": null}, \"macro.dbt.default__snapshot_hash_arguments\": {\"name\": \"default__snapshot_hash_arguments\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"unique_id\": \"macro.dbt.default__snapshot_hash_arguments\", \"macro_sql\": \"{% macro default__snapshot_hash_arguments(args) -%}\\n    md5({%- for arg in args -%}\\n        coalesce(cast({{ arg }} as varchar ), '')\\n        {% if not loop.last %} || '|' || {% endif %}\\n    {%- endfor -%})\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.1367402, \"supported_languages\": null}, \"macro.dbt.snapshot_timestamp_strategy\": {\"name\": \"snapshot_timestamp_strategy\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"unique_id\": \"macro.dbt.snapshot_timestamp_strategy\", \"macro_sql\": \"{% macro snapshot_timestamp_strategy(node, snapshotted_rel, current_rel, config, target_exists) %}\\n    {% set primary_key = config['unique_key'] %}\\n    {% set updated_at = config['updated_at'] %}\\n    {% set invalidate_hard_deletes = config.get('invalidate_hard_deletes', false) %}\\n\\n    {#/*\\n        The snapshot relation might not have an {{ updated_at }} value if the\\n        snapshot strategy is changed from `check` to `timestamp`. We\\n        should use a dbt-created column for the comparison in the snapshot\\n        table instead of assuming that the user-supplied {{ updated_at }}\\n        will be present in the historical data.\\n\\n        See https://github.com/dbt-labs/dbt-core/issues/2350\\n    */ #}\\n    {% set row_changed_expr -%}\\n        ({{ snapshotted_rel }}.dbt_valid_from < {{ current_rel }}.{{ updated_at }})\\n    {%- endset %}\\n\\n    {% set scd_id_expr = snapshot_hash_arguments([primary_key, updated_at]) %}\\n\\n    {% do return({\\n        \\\"unique_key\\\": primary_key,\\n        \\\"updated_at\\\": updated_at,\\n        \\\"row_changed\\\": row_changed_expr,\\n        \\\"scd_id\\\": scd_id_expr,\\n        \\\"invalidate_hard_deletes\\\": invalidate_hard_deletes\\n    }) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.snapshot_hash_arguments\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.1374788, \"supported_languages\": null}, \"macro.dbt.snapshot_string_as_time\": {\"name\": \"snapshot_string_as_time\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"unique_id\": \"macro.dbt.snapshot_string_as_time\", \"macro_sql\": \"{% macro snapshot_string_as_time(timestamp) -%}\\n    {{ adapter.dispatch('snapshot_string_as_time', 'dbt')(timestamp) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__snapshot_string_as_time\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.13765, \"supported_languages\": null}, \"macro.dbt.default__snapshot_string_as_time\": {\"name\": \"default__snapshot_string_as_time\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"unique_id\": \"macro.dbt.default__snapshot_string_as_time\", \"macro_sql\": \"{% macro default__snapshot_string_as_time(timestamp) %}\\n    {% do exceptions.raise_not_implemented(\\n        'snapshot_string_as_time macro not implemented for adapter '+adapter.type()\\n    ) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.137829, \"supported_languages\": null}, \"macro.dbt.snapshot_check_all_get_existing_columns\": {\"name\": \"snapshot_check_all_get_existing_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"unique_id\": \"macro.dbt.snapshot_check_all_get_existing_columns\", \"macro_sql\": \"{% macro snapshot_check_all_get_existing_columns(node, target_exists, check_cols_config) -%}\\n    {%- if not target_exists -%}\\n        {#-- no table yet -> return whatever the query does --#}\\n        {{ return((false, query_columns)) }}\\n    {%- endif -%}\\n\\n    {#-- handle any schema changes --#}\\n    {%- set target_relation = adapter.get_relation(database=node.database, schema=node.schema, identifier=node.alias) -%}\\n\\n    {% if check_cols_config == 'all' %}\\n        {%- set query_columns = get_columns_in_query(node['compiled_code']) -%}\\n\\n    {% elif check_cols_config is iterable and (check_cols_config | length) > 0 %}\\n        {#-- query for proper casing/quoting, to support comparison below --#}\\n        {%- set select_check_cols_from_target -%}\\n            {#-- N.B. The whitespace below is necessary to avoid edge case issue with comments --#}\\n            {#-- See: https://github.com/dbt-labs/dbt-core/issues/6781 --#}\\n            select {{ check_cols_config | join(', ') }} from (\\n                {{ node['compiled_code'] }}\\n            ) subq\\n        {%- endset -%}\\n        {% set query_columns = get_columns_in_query(select_check_cols_from_target) %}\\n\\n    {% else %}\\n        {% do exceptions.raise_compiler_error(\\\"Invalid value for 'check_cols': \\\" ~ check_cols_config) %}\\n    {% endif %}\\n\\n    {%- set existing_cols = adapter.get_columns_in_relation(target_relation) | map(attribute = 'name') | list -%}\\n    {%- set ns = namespace() -%} {#-- handle for-loop scoping with a namespace --#}\\n    {%- set ns.column_added = false -%}\\n\\n    {%- set intersection = [] -%}\\n    {%- for col in query_columns -%}\\n        {%- if col in existing_cols -%}\\n            {%- do intersection.append(adapter.quote(col)) -%}\\n        {%- else -%}\\n            {% set ns.column_added = true %}\\n        {%- endif -%}\\n    {%- endfor -%}\\n    {{ return((ns.column_added, intersection)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_columns_in_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.1392791, \"supported_languages\": null}, \"macro.dbt.snapshot_check_strategy\": {\"name\": \"snapshot_check_strategy\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"unique_id\": \"macro.dbt.snapshot_check_strategy\", \"macro_sql\": \"{% macro snapshot_check_strategy(node, snapshotted_rel, current_rel, config, target_exists) %}\\n    {% set check_cols_config = config['check_cols'] %}\\n    {% set primary_key = config['unique_key'] %}\\n    {% set invalidate_hard_deletes = config.get('invalidate_hard_deletes', false) %}\\n    {% set updated_at = config.get('updated_at', snapshot_get_time()) %}\\n\\n    {% set column_added = false %}\\n\\n    {% set column_added, check_cols = snapshot_check_all_get_existing_columns(node, target_exists, check_cols_config) %}\\n\\n    {%- set row_changed_expr -%}\\n    (\\n    {%- if column_added -%}\\n        {{ get_true_sql() }}\\n    {%- else -%}\\n    {%- for col in check_cols -%}\\n        {{ snapshotted_rel }}.{{ col }} != {{ current_rel }}.{{ col }}\\n        or\\n        (\\n            (({{ snapshotted_rel }}.{{ col }} is null) and not ({{ current_rel }}.{{ col }} is null))\\n            or\\n            ((not {{ snapshotted_rel }}.{{ col }} is null) and ({{ current_rel }}.{{ col }} is null))\\n        )\\n        {%- if not loop.last %} or {% endif -%}\\n    {%- endfor -%}\\n    {%- endif -%}\\n    )\\n    {%- endset %}\\n\\n    {% set scd_id_expr = snapshot_hash_arguments([primary_key, updated_at]) %}\\n\\n    {% do return({\\n        \\\"unique_key\\\": primary_key,\\n        \\\"updated_at\\\": updated_at,\\n        \\\"row_changed\\\": row_changed_expr,\\n        \\\"scd_id\\\": scd_id_expr,\\n        \\\"invalidate_hard_deletes\\\": invalidate_hard_deletes\\n    }) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.snapshot_get_time\", \"macro.dbt.snapshot_check_all_get_existing_columns\", \"macro.dbt.get_true_sql\", \"macro.dbt.snapshot_hash_arguments\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.140613, \"supported_languages\": null}, \"macro.dbt.create_columns\": {\"name\": \"create_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.create_columns\", \"macro_sql\": \"{% macro create_columns(relation, columns) %}\\n  {{ adapter.dispatch('create_columns', 'dbt')(relation, columns) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__create_columns\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.144871, \"supported_languages\": null}, \"macro.dbt.default__create_columns\": {\"name\": \"default__create_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.default__create_columns\", \"macro_sql\": \"{% macro default__create_columns(relation, columns) %}\\n  {% for column in columns %}\\n    {% call statement() %}\\n      alter table {{ relation }} add column \\\"{{ column.name }}\\\" {{ column.data_type }};\\n    {% endcall %}\\n  {% endfor %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.14516, \"supported_languages\": null}, \"macro.dbt.post_snapshot\": {\"name\": \"post_snapshot\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.post_snapshot\", \"macro_sql\": \"{% macro post_snapshot(staging_relation) %}\\n  {{ adapter.dispatch('post_snapshot', 'dbt')(staging_relation) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__post_snapshot\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.145334, \"supported_languages\": null}, \"macro.dbt.default__post_snapshot\": {\"name\": \"default__post_snapshot\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.default__post_snapshot\", \"macro_sql\": \"{% macro default__post_snapshot(staging_relation) %}\\n    {# no-op #}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.1454248, \"supported_languages\": null}, \"macro.dbt.get_true_sql\": {\"name\": \"get_true_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.get_true_sql\", \"macro_sql\": \"{% macro get_true_sql() %}\\n  {{ adapter.dispatch('get_true_sql', 'dbt')() }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_true_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.1455739, \"supported_languages\": null}, \"macro.dbt.default__get_true_sql\": {\"name\": \"default__get_true_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.default__get_true_sql\", \"macro_sql\": \"{% macro default__get_true_sql() %}\\n    {{ return('TRUE') }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.145694, \"supported_languages\": null}, \"macro.dbt.snapshot_staging_table\": {\"name\": \"snapshot_staging_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.snapshot_staging_table\", \"macro_sql\": \"{% macro snapshot_staging_table(strategy, source_sql, target_relation) -%}\\n  {{ adapter.dispatch('snapshot_staging_table', 'dbt')(strategy, source_sql, target_relation) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__snapshot_staging_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.145904, \"supported_languages\": null}, \"macro.dbt.default__snapshot_staging_table\": {\"name\": \"default__snapshot_staging_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.default__snapshot_staging_table\", \"macro_sql\": \"{% macro default__snapshot_staging_table(strategy, source_sql, target_relation) -%}\\n\\n    with snapshot_query as (\\n\\n        {{ source_sql }}\\n\\n    ),\\n\\n    snapshotted_data as (\\n\\n        select *,\\n            {{ strategy.unique_key }} as dbt_unique_key\\n\\n        from {{ target_relation }}\\n        where dbt_valid_to is null\\n\\n    ),\\n\\n    insertions_source_data as (\\n\\n        select\\n            *,\\n            {{ strategy.unique_key }} as dbt_unique_key,\\n            {{ strategy.updated_at }} as dbt_updated_at,\\n            {{ strategy.updated_at }} as dbt_valid_from,\\n            nullif({{ strategy.updated_at }}, {{ strategy.updated_at }}) as dbt_valid_to,\\n            {{ strategy.scd_id }} as dbt_scd_id\\n\\n        from snapshot_query\\n    ),\\n\\n    updates_source_data as (\\n\\n        select\\n            *,\\n            {{ strategy.unique_key }} as dbt_unique_key,\\n            {{ strategy.updated_at }} as dbt_updated_at,\\n            {{ strategy.updated_at }} as dbt_valid_from,\\n            {{ strategy.updated_at }} as dbt_valid_to\\n\\n        from snapshot_query\\n    ),\\n\\n    {%- if strategy.invalidate_hard_deletes %}\\n\\n    deletes_source_data as (\\n\\n        select\\n            *,\\n            {{ strategy.unique_key }} as dbt_unique_key\\n        from snapshot_query\\n    ),\\n    {% endif %}\\n\\n    insertions as (\\n\\n        select\\n            'insert' as dbt_change_type,\\n            source_data.*\\n\\n        from insertions_source_data as source_data\\n        left outer join snapshotted_data on snapshotted_data.dbt_unique_key = source_data.dbt_unique_key\\n        where snapshotted_data.dbt_unique_key is null\\n           or (\\n                snapshotted_data.dbt_unique_key is not null\\n            and (\\n                {{ strategy.row_changed }}\\n            )\\n        )\\n\\n    ),\\n\\n    updates as (\\n\\n        select\\n            'update' as dbt_change_type,\\n            source_data.*,\\n            snapshotted_data.dbt_scd_id\\n\\n        from updates_source_data as source_data\\n        join snapshotted_data on snapshotted_data.dbt_unique_key = source_data.dbt_unique_key\\n        where (\\n            {{ strategy.row_changed }}\\n        )\\n    )\\n\\n    {%- if strategy.invalidate_hard_deletes -%}\\n    ,\\n\\n    deletes as (\\n\\n        select\\n            'delete' as dbt_change_type,\\n            source_data.*,\\n            {{ snapshot_get_time() }} as dbt_valid_from,\\n            {{ snapshot_get_time() }} as dbt_updated_at,\\n            {{ snapshot_get_time() }} as dbt_valid_to,\\n            snapshotted_data.dbt_scd_id\\n\\n        from snapshotted_data\\n        left join deletes_source_data as source_data on snapshotted_data.dbt_unique_key = source_data.dbt_unique_key\\n        where source_data.dbt_unique_key is null\\n    )\\n    {%- endif %}\\n\\n    select * from insertions\\n    union all\\n    select * from updates\\n    {%- if strategy.invalidate_hard_deletes %}\\n    union all\\n    select * from deletes\\n    {%- endif %}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.snapshot_get_time\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.146819, \"supported_languages\": null}, \"macro.dbt.build_snapshot_table\": {\"name\": \"build_snapshot_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.build_snapshot_table\", \"macro_sql\": \"{% macro build_snapshot_table(strategy, sql) -%}\\n  {{ adapter.dispatch('build_snapshot_table', 'dbt')(strategy, sql) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__build_snapshot_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.1470149, \"supported_languages\": null}, \"macro.dbt.default__build_snapshot_table\": {\"name\": \"default__build_snapshot_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.default__build_snapshot_table\", \"macro_sql\": \"{% macro default__build_snapshot_table(strategy, sql) %}\\n\\n    select *,\\n        {{ strategy.scd_id }} as dbt_scd_id,\\n        {{ strategy.updated_at }} as dbt_updated_at,\\n        {{ strategy.updated_at }} as dbt_valid_from,\\n        nullif({{ strategy.updated_at }}, {{ strategy.updated_at }}) as dbt_valid_to\\n    from (\\n        {{ sql }}\\n    ) sbq\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.147279, \"supported_languages\": null}, \"macro.dbt.build_snapshot_staging_table\": {\"name\": \"build_snapshot_staging_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.build_snapshot_staging_table\", \"macro_sql\": \"{% macro build_snapshot_staging_table(strategy, sql, target_relation) %}\\n    {% set temp_relation = make_temp_relation(target_relation) %}\\n\\n    {% set select = snapshot_staging_table(strategy, sql, target_relation) %}\\n\\n    {% call statement('build_snapshot_staging_relation') %}\\n        {{ create_table_as(True, temp_relation, select) }}\\n    {% endcall %}\\n\\n    {% do return(temp_relation) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.make_temp_relation\", \"macro.dbt.snapshot_staging_table\", \"macro.dbt.statement\", \"macro.dbt.create_table_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.147718, \"supported_languages\": null}, \"macro.dbt.materialization_snapshot_default\": {\"name\": \"materialization_snapshot_default\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/snapshot.sql\", \"original_file_path\": \"macros/materializations/snapshots/snapshot.sql\", \"unique_id\": \"macro.dbt.materialization_snapshot_default\", \"macro_sql\": \"{% materialization snapshot, default %}\\n  {%- set config = model['config'] -%}\\n\\n  {%- set target_table = model.get('alias', model.get('name')) -%}\\n\\n  {%- set strategy_name = config.get('strategy') -%}\\n  {%- set unique_key = config.get('unique_key') %}\\n  -- grab current tables grants config for comparision later on\\n  {%- set grant_config = config.get('grants') -%}\\n\\n  {% set target_relation_exists, target_relation = get_or_create_relation(\\n          database=model.database,\\n          schema=model.schema,\\n          identifier=target_table,\\n          type='table') -%}\\n\\n  {%- if not target_relation.is_table -%}\\n    {% do exceptions.relation_wrong_type(target_relation, 'table') %}\\n  {%- endif -%}\\n\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  {% set strategy_macro = strategy_dispatch(strategy_name) %}\\n  {% set strategy = strategy_macro(model, \\\"snapshotted_data\\\", \\\"source_data\\\", config, target_relation_exists) %}\\n\\n  {% if not target_relation_exists %}\\n\\n      {% set build_sql = build_snapshot_table(strategy, model['compiled_code']) %}\\n      {% set final_sql = create_table_as(False, target_relation, build_sql) %}\\n\\n  {% else %}\\n\\n      {{ adapter.valid_snapshot_target(target_relation) }}\\n\\n      {% set staging_table = build_snapshot_staging_table(strategy, sql, target_relation) %}\\n\\n      -- this may no-op if the database does not require column expansion\\n      {% do adapter.expand_target_column_types(from_relation=staging_table,\\n                                               to_relation=target_relation) %}\\n\\n      {% set missing_columns = adapter.get_missing_columns(staging_table, target_relation)\\n                                   | rejectattr('name', 'equalto', 'dbt_change_type')\\n                                   | rejectattr('name', 'equalto', 'DBT_CHANGE_TYPE')\\n                                   | rejectattr('name', 'equalto', 'dbt_unique_key')\\n                                   | rejectattr('name', 'equalto', 'DBT_UNIQUE_KEY')\\n                                   | list %}\\n\\n      {% do create_columns(target_relation, missing_columns) %}\\n\\n      {% set source_columns = adapter.get_columns_in_relation(staging_table)\\n                                   | rejectattr('name', 'equalto', 'dbt_change_type')\\n                                   | rejectattr('name', 'equalto', 'DBT_CHANGE_TYPE')\\n                                   | rejectattr('name', 'equalto', 'dbt_unique_key')\\n                                   | rejectattr('name', 'equalto', 'DBT_UNIQUE_KEY')\\n                                   | list %}\\n\\n      {% set quoted_source_columns = [] %}\\n      {% for column in source_columns %}\\n        {% do quoted_source_columns.append(adapter.quote(column.name)) %}\\n      {% endfor %}\\n\\n      {% set final_sql = snapshot_merge_sql(\\n            target = target_relation,\\n            source = staging_table,\\n            insert_cols = quoted_source_columns\\n         )\\n      %}\\n\\n  {% endif %}\\n\\n  {% call statement('main') %}\\n      {{ final_sql }}\\n  {% endcall %}\\n\\n  {% set should_revoke = should_revoke(target_relation_exists, full_refresh_mode=False) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {% if not target_relation_exists %}\\n    {% do create_indexes(target_relation) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  {{ adapter.commit() }}\\n\\n  {% if staging_table is defined %}\\n      {% do post_snapshot(staging_table) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{% endmaterialization %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_or_create_relation\", \"macro.dbt.run_hooks\", \"macro.dbt.strategy_dispatch\", \"macro.dbt.build_snapshot_table\", \"macro.dbt.create_table_as\", \"macro.dbt.build_snapshot_staging_table\", \"macro.dbt.create_columns\", \"macro.dbt.snapshot_merge_sql\", \"macro.dbt.statement\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\", \"macro.dbt.persist_docs\", \"macro.dbt.create_indexes\", \"macro.dbt.post_snapshot\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.154073, \"supported_languages\": [\"sql\"]}, \"macro.dbt.materialization_test_default\": {\"name\": \"materialization_test_default\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/tests/test.sql\", \"original_file_path\": \"macros/materializations/tests/test.sql\", \"unique_id\": \"macro.dbt.materialization_test_default\", \"macro_sql\": \"{%- materialization test, default -%}\\n\\n  {% set relations = [] %}\\n\\n  {% if should_store_failures() %}\\n\\n    {% set identifier = model['alias'] %}\\n    {% set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) %}\\n    {% set target_relation = api.Relation.create(\\n        identifier=identifier, schema=schema, database=database, type='table') -%} %}\\n\\n    {% if old_relation %}\\n        {% do adapter.drop_relation(old_relation) %}\\n    {% endif %}\\n\\n    {% call statement(auto_begin=True) %}\\n        {{ create_table_as(False, target_relation, sql) }}\\n    {% endcall %}\\n\\n    {% do relations.append(target_relation) %}\\n\\n    {% set main_sql %}\\n        select *\\n        from {{ target_relation }}\\n    {% endset %}\\n\\n    {{ adapter.commit() }}\\n\\n  {% else %}\\n\\n      {% set main_sql = sql %}\\n\\n  {% endif %}\\n\\n  {% set limit = config.get('limit') %}\\n  {% set fail_calc = config.get('fail_calc') %}\\n  {% set warn_if = config.get('warn_if') %}\\n  {% set error_if = config.get('error_if') %}\\n\\n  {% call statement('main', fetch_result=True) -%}\\n\\n    {{ get_test_sql(main_sql, fail_calc, warn_if, error_if, limit)}}\\n\\n  {%- endcall %}\\n\\n  {{ return({'relations': relations}) }}\\n\\n{%- endmaterialization -%}\", \"depends_on\": {\"macros\": [\"macro.dbt.should_store_failures\", \"macro.dbt.statement\", \"macro.dbt.create_table_as\", \"macro.dbt.get_test_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.156199, \"supported_languages\": [\"sql\"]}, \"macro.dbt.get_test_sql\": {\"name\": \"get_test_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/tests/helpers.sql\", \"original_file_path\": \"macros/materializations/tests/helpers.sql\", \"unique_id\": \"macro.dbt.get_test_sql\", \"macro_sql\": \"{% macro get_test_sql(main_sql, fail_calc, warn_if, error_if, limit) -%}\\n  {{ adapter.dispatch('get_test_sql', 'dbt')(main_sql, fail_calc, warn_if, error_if, limit) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_test_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.156668, \"supported_languages\": null}, \"macro.dbt.default__get_test_sql\": {\"name\": \"default__get_test_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/tests/helpers.sql\", \"original_file_path\": \"macros/materializations/tests/helpers.sql\", \"unique_id\": \"macro.dbt.default__get_test_sql\", \"macro_sql\": \"{% macro default__get_test_sql(main_sql, fail_calc, warn_if, error_if, limit) -%}\\n    select\\n      {{ fail_calc }} as failures,\\n      {{ fail_calc }} {{ warn_if }} as should_warn,\\n      {{ fail_calc }} {{ error_if }} as should_error\\n    from (\\n      {{ main_sql }}\\n      {{ \\\"limit \\\" ~ limit if limit != none }}\\n    ) dbt_internal_test\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.156987, \"supported_languages\": null}, \"macro.dbt.get_where_subquery\": {\"name\": \"get_where_subquery\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/tests/where_subquery.sql\", \"original_file_path\": \"macros/materializations/tests/where_subquery.sql\", \"unique_id\": \"macro.dbt.get_where_subquery\", \"macro_sql\": \"{% macro get_where_subquery(relation) -%}\\n    {% do return(adapter.dispatch('get_where_subquery', 'dbt')(relation)) %}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_where_subquery\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.157378, \"supported_languages\": null}, \"macro.dbt.default__get_where_subquery\": {\"name\": \"default__get_where_subquery\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/tests/where_subquery.sql\", \"original_file_path\": \"macros/materializations/tests/where_subquery.sql\", \"unique_id\": \"macro.dbt.default__get_where_subquery\", \"macro_sql\": \"{% macro default__get_where_subquery(relation) -%}\\n    {% set where = config.get('where', '') %}\\n    {% if where %}\\n        {%- set filtered -%}\\n            (select * from {{ relation }} where {{ where }}) dbt_subquery\\n        {%- endset -%}\\n        {% do return(filtered) %}\\n    {%- else -%}\\n        {% do return(relation) %}\\n    {%- endif -%}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.157763, \"supported_languages\": null}, \"macro.dbt.get_quoted_csv\": {\"name\": \"get_quoted_csv\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"unique_id\": \"macro.dbt.get_quoted_csv\", \"macro_sql\": \"{% macro get_quoted_csv(column_names) %}\\n\\n    {% set quoted = [] %}\\n    {% for col in column_names -%}\\n        {%- do quoted.append(adapter.quote(col)) -%}\\n    {%- endfor %}\\n\\n    {%- set dest_cols_csv = quoted | join(', ') -%}\\n    {{ return(dest_cols_csv) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.159425, \"supported_languages\": null}, \"macro.dbt.diff_columns\": {\"name\": \"diff_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"unique_id\": \"macro.dbt.diff_columns\", \"macro_sql\": \"{% macro diff_columns(source_columns, target_columns) %}\\n\\n  {% set result = [] %}\\n  {% set source_names = source_columns | map(attribute = 'column') | list %}\\n  {% set target_names = target_columns | map(attribute = 'column') | list %}\\n\\n   {# --check whether the name attribute exists in the target - this does not perform a data type check #}\\n   {% for sc in source_columns %}\\n     {% if sc.name not in target_names %}\\n        {{ result.append(sc) }}\\n     {% endif %}\\n   {% endfor %}\\n\\n  {{ return(result) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.1599932, \"supported_languages\": null}, \"macro.dbt.diff_column_data_types\": {\"name\": \"diff_column_data_types\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"unique_id\": \"macro.dbt.diff_column_data_types\", \"macro_sql\": \"{% macro diff_column_data_types(source_columns, target_columns) %}\\n\\n  {% set result = [] %}\\n  {% for sc in source_columns %}\\n    {% set tc = target_columns | selectattr(\\\"name\\\", \\\"equalto\\\", sc.name) | list | first %}\\n    {% if tc %}\\n      {% if sc.data_type != tc.data_type and not sc.can_expand_to(other_column=tc) %}\\n        {{ result.append( { 'column_name': tc.name, 'new_type': sc.data_type } ) }}\\n      {% endif %}\\n    {% endif %}\\n  {% endfor %}\\n\\n  {{ return(result) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.160686, \"supported_languages\": null}, \"macro.dbt.get_merge_update_columns\": {\"name\": \"get_merge_update_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"unique_id\": \"macro.dbt.get_merge_update_columns\", \"macro_sql\": \"{% macro get_merge_update_columns(merge_update_columns, merge_exclude_columns, dest_columns) %}\\n  {{ return(adapter.dispatch('get_merge_update_columns', 'dbt')(merge_update_columns, merge_exclude_columns, dest_columns)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_merge_update_columns\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.1609302, \"supported_languages\": null}, \"macro.dbt.default__get_merge_update_columns\": {\"name\": \"default__get_merge_update_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"unique_id\": \"macro.dbt.default__get_merge_update_columns\", \"macro_sql\": \"{% macro default__get_merge_update_columns(merge_update_columns, merge_exclude_columns, dest_columns) %}\\n  {%- set default_cols = dest_columns | map(attribute=\\\"quoted\\\") | list -%}\\n\\n  {%- if merge_update_columns and merge_exclude_columns -%}\\n    {{ exceptions.raise_compiler_error(\\n        'Model cannot specify merge_update_columns and merge_exclude_columns. Please update model to use only one config'\\n    )}}\\n  {%- elif merge_update_columns -%}\\n    {%- set update_columns = merge_update_columns -%}\\n  {%- elif merge_exclude_columns -%}\\n    {%- set update_columns = [] -%}\\n    {%- for column in dest_columns -%}\\n      {% if column.column | lower not in merge_exclude_columns | map(\\\"lower\\\") | list %}\\n        {%- do update_columns.append(column.quoted) -%}\\n      {% endif %}\\n    {%- endfor -%}\\n  {%- else -%}\\n    {%- set update_columns = default_cols -%}\\n  {%- endif -%}\\n\\n  {{ return(update_columns) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.1617038, \"supported_languages\": null}, \"macro.dbt.get_merge_sql\": {\"name\": \"get_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"unique_id\": \"macro.dbt.get_merge_sql\", \"macro_sql\": \"{% macro get_merge_sql(target, source, unique_key, dest_columns, incremental_predicates=none) -%}\\n   -- back compat for old kwarg name\\n  {% set incremental_predicates = kwargs.get('predicates', incremental_predicates) %}\\n  {{ adapter.dispatch('get_merge_sql', 'dbt')(target, source, unique_key, dest_columns, incremental_predicates) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.168492, \"supported_languages\": null}, \"macro.dbt.default__get_merge_sql\": {\"name\": \"default__get_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"unique_id\": \"macro.dbt.default__get_merge_sql\", \"macro_sql\": \"{% macro default__get_merge_sql(target, source, unique_key, dest_columns, incremental_predicates=none) -%}\\n    {%- set predicates = [] if incremental_predicates is none else [] + incremental_predicates -%}\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n    {%- set merge_update_columns = config.get('merge_update_columns') -%}\\n    {%- set merge_exclude_columns = config.get('merge_exclude_columns') -%}\\n    {%- set update_columns = get_merge_update_columns(merge_update_columns, merge_exclude_columns, dest_columns) -%}\\n    {%- set sql_header = config.get('sql_header', none) -%}\\n\\n    {% if unique_key %}\\n        {% if unique_key is sequence and unique_key is not mapping and unique_key is not string %}\\n            {% for key in unique_key %}\\n                {% set this_key_match %}\\n                    DBT_INTERNAL_SOURCE.{{ key }} = DBT_INTERNAL_DEST.{{ key }}\\n                {% endset %}\\n                {% do predicates.append(this_key_match) %}\\n            {% endfor %}\\n        {% else %}\\n            {% set unique_key_match %}\\n                DBT_INTERNAL_SOURCE.{{ unique_key }} = DBT_INTERNAL_DEST.{{ unique_key }}\\n            {% endset %}\\n            {% do predicates.append(unique_key_match) %}\\n        {% endif %}\\n    {% else %}\\n        {% do predicates.append('FALSE') %}\\n    {% endif %}\\n\\n    {{ sql_header if sql_header is not none }}\\n\\n    merge into {{ target }} as DBT_INTERNAL_DEST\\n        using {{ source }} as DBT_INTERNAL_SOURCE\\n        on {{\\\"(\\\" ~ predicates | join(\\\") and (\\\") ~ \\\")\\\"}}\\n\\n    {% if unique_key %}\\n    when matched then update set\\n        {% for column_name in update_columns -%}\\n            {{ column_name }} = DBT_INTERNAL_SOURCE.{{ column_name }}\\n            {%- if not loop.last %}, {%- endif %}\\n        {%- endfor %}\\n    {% endif %}\\n\\n    when not matched then insert\\n        ({{ dest_cols_csv }})\\n    values\\n        ({{ dest_cols_csv }})\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_quoted_csv\", \"macro.dbt.get_merge_update_columns\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.170215, \"supported_languages\": null}, \"macro.dbt.get_delete_insert_merge_sql\": {\"name\": \"get_delete_insert_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"unique_id\": \"macro.dbt.get_delete_insert_merge_sql\", \"macro_sql\": \"{% macro get_delete_insert_merge_sql(target, source, unique_key, dest_columns, incremental_predicates) -%}\\n  {{ adapter.dispatch('get_delete_insert_merge_sql', 'dbt')(target, source, unique_key, dest_columns, incremental_predicates) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_delete_insert_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.170489, \"supported_languages\": null}, \"macro.dbt.default__get_delete_insert_merge_sql\": {\"name\": \"default__get_delete_insert_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"unique_id\": \"macro.dbt.default__get_delete_insert_merge_sql\", \"macro_sql\": \"{% macro default__get_delete_insert_merge_sql(target, source, unique_key, dest_columns, incremental_predicates) -%}\\n\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n\\n    {% if unique_key %}\\n        {% if unique_key is sequence and unique_key is not string %}\\n            delete from {{target }}\\n            using {{ source }}\\n            where (\\n                {% for key in unique_key %}\\n                    {{ source }}.{{ key }} = {{ target }}.{{ key }}\\n                    {{ \\\"and \\\" if not loop.last}}\\n                {% endfor %}\\n                {% if incremental_predicates %}\\n                    {% for predicate in incremental_predicates %}\\n                        and {{ predicate }}\\n                    {% endfor %}\\n                {% endif %}\\n            );\\n        {% else %}\\n            delete from {{ target }}\\n            where (\\n                {{ unique_key }}) in (\\n                select ({{ unique_key }})\\n                from {{ source }}\\n            )\\n            {%- if incremental_predicates %}\\n                {% for predicate in incremental_predicates %}\\n                    and {{ predicate }}\\n                {% endfor %}\\n            {%- endif -%};\\n\\n        {% endif %}\\n    {% endif %}\\n\\n    insert into {{ target }} ({{ dest_cols_csv }})\\n    (\\n        select {{ dest_cols_csv }}\\n        from {{ source }}\\n    )\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_quoted_csv\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.171521, \"supported_languages\": null}, \"macro.dbt.get_insert_overwrite_merge_sql\": {\"name\": \"get_insert_overwrite_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"unique_id\": \"macro.dbt.get_insert_overwrite_merge_sql\", \"macro_sql\": \"{% macro get_insert_overwrite_merge_sql(target, source, dest_columns, predicates, include_sql_header=false) -%}\\n  {{ adapter.dispatch('get_insert_overwrite_merge_sql', 'dbt')(target, source, dest_columns, predicates, include_sql_header) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_insert_overwrite_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.171801, \"supported_languages\": null}, \"macro.dbt.default__get_insert_overwrite_merge_sql\": {\"name\": \"default__get_insert_overwrite_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"unique_id\": \"macro.dbt.default__get_insert_overwrite_merge_sql\", \"macro_sql\": \"{% macro default__get_insert_overwrite_merge_sql(target, source, dest_columns, predicates, include_sql_header) -%}\\n    {#-- The only time include_sql_header is True: --#}\\n    {#-- BigQuery + insert_overwrite strategy + \\\"static\\\" partitions config --#}\\n    {#-- We should consider including the sql header at the materialization level instead --#}\\n\\n    {%- set predicates = [] if predicates is none else [] + predicates -%}\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n    {%- set sql_header = config.get('sql_header', none) -%}\\n\\n    {{ sql_header if sql_header is not none and include_sql_header }}\\n\\n    merge into {{ target }} as DBT_INTERNAL_DEST\\n        using {{ source }} as DBT_INTERNAL_SOURCE\\n        on FALSE\\n\\n    when not matched by source\\n        {% if predicates %} and {{ predicates | join(' and ') }} {% endif %}\\n        then delete\\n\\n    when not matched then insert\\n        ({{ dest_cols_csv }})\\n    values\\n        ({{ dest_cols_csv }})\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_quoted_csv\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.172469, \"supported_languages\": null}, \"macro.dbt.is_incremental\": {\"name\": \"is_incremental\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/is_incremental.sql\", \"original_file_path\": \"macros/materializations/models/incremental/is_incremental.sql\", \"unique_id\": \"macro.dbt.is_incremental\", \"macro_sql\": \"{% macro is_incremental() %}\\n    {#-- do not run introspective queries in parsing #}\\n    {% if not execute %}\\n        {{ return(False) }}\\n    {% else %}\\n        {% set relation = adapter.get_relation(this.database, this.schema, this.table) %}\\n        {{ return(relation is not none\\n                  and relation.type == 'table'\\n                  and model.config.materialized == 'incremental'\\n                  and not should_full_refresh()) }}\\n    {% endif %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.should_full_refresh\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.173121, \"supported_languages\": null}, \"macro.dbt.get_incremental_append_sql\": {\"name\": \"get_incremental_append_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.get_incremental_append_sql\", \"macro_sql\": \"{% macro get_incremental_append_sql(arg_dict) %}\\n\\n  {{ return(adapter.dispatch('get_incremental_append_sql', 'dbt')(arg_dict)) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_incremental_append_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.17403, \"supported_languages\": null}, \"macro.dbt.default__get_incremental_append_sql\": {\"name\": \"default__get_incremental_append_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.default__get_incremental_append_sql\", \"macro_sql\": \"{% macro default__get_incremental_append_sql(arg_dict) %}\\n\\n  {% do return(get_insert_into_sql(arg_dict[\\\"target_relation\\\"], arg_dict[\\\"temp_relation\\\"], arg_dict[\\\"dest_columns\\\"])) %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_insert_into_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.174277, \"supported_languages\": null}, \"macro.dbt.get_incremental_delete_insert_sql\": {\"name\": \"get_incremental_delete_insert_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.get_incremental_delete_insert_sql\", \"macro_sql\": \"{% macro get_incremental_delete_insert_sql(arg_dict) %}\\n\\n  {{ return(adapter.dispatch('get_incremental_delete_insert_sql', 'dbt')(arg_dict)) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_incremental_delete_insert_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.174471, \"supported_languages\": null}, \"macro.dbt.default__get_incremental_delete_insert_sql\": {\"name\": \"default__get_incremental_delete_insert_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.default__get_incremental_delete_insert_sql\", \"macro_sql\": \"{% macro default__get_incremental_delete_insert_sql(arg_dict) %}\\n\\n  {% do return(get_delete_insert_merge_sql(arg_dict[\\\"target_relation\\\"], arg_dict[\\\"temp_relation\\\"], arg_dict[\\\"unique_key\\\"], arg_dict[\\\"dest_columns\\\"], arg_dict[\\\"incremental_predicates\\\"])) %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_delete_insert_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.174779, \"supported_languages\": null}, \"macro.dbt.get_incremental_merge_sql\": {\"name\": \"get_incremental_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.get_incremental_merge_sql\", \"macro_sql\": \"{% macro get_incremental_merge_sql(arg_dict) %}\\n\\n  {{ return(adapter.dispatch('get_incremental_merge_sql', 'dbt')(arg_dict)) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_incremental_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.174974, \"supported_languages\": null}, \"macro.dbt.default__get_incremental_merge_sql\": {\"name\": \"default__get_incremental_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.default__get_incremental_merge_sql\", \"macro_sql\": \"{% macro default__get_incremental_merge_sql(arg_dict) %}\\n\\n  {% do return(get_merge_sql(arg_dict[\\\"target_relation\\\"], arg_dict[\\\"temp_relation\\\"], arg_dict[\\\"unique_key\\\"], arg_dict[\\\"dest_columns\\\"], arg_dict[\\\"incremental_predicates\\\"])) %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.17528, \"supported_languages\": null}, \"macro.dbt.get_incremental_insert_overwrite_sql\": {\"name\": \"get_incremental_insert_overwrite_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.get_incremental_insert_overwrite_sql\", \"macro_sql\": \"{% macro get_incremental_insert_overwrite_sql(arg_dict) %}\\n\\n  {{ return(adapter.dispatch('get_incremental_insert_overwrite_sql', 'dbt')(arg_dict)) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_incremental_insert_overwrite_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.175472, \"supported_languages\": null}, \"macro.dbt.default__get_incremental_insert_overwrite_sql\": {\"name\": \"default__get_incremental_insert_overwrite_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.default__get_incremental_insert_overwrite_sql\", \"macro_sql\": \"{% macro default__get_incremental_insert_overwrite_sql(arg_dict) %}\\n\\n  {% do return(get_insert_overwrite_merge_sql(arg_dict[\\\"target_relation\\\"], arg_dict[\\\"temp_relation\\\"], arg_dict[\\\"dest_columns\\\"], arg_dict[\\\"incremental_predicates\\\"])) %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_insert_overwrite_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.175742, \"supported_languages\": null}, \"macro.dbt.get_incremental_default_sql\": {\"name\": \"get_incremental_default_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.get_incremental_default_sql\", \"macro_sql\": \"{% macro get_incremental_default_sql(arg_dict) %}\\n\\n  {{ return(adapter.dispatch('get_incremental_default_sql', 'dbt')(arg_dict)) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_incremental_default_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.175937, \"supported_languages\": null}, \"macro.dbt.default__get_incremental_default_sql\": {\"name\": \"default__get_incremental_default_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.default__get_incremental_default_sql\", \"macro_sql\": \"{% macro default__get_incremental_default_sql(arg_dict) %}\\n\\n  {% do return(get_incremental_append_sql(arg_dict)) %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_incremental_append_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.176092, \"supported_languages\": null}, \"macro.dbt.get_insert_into_sql\": {\"name\": \"get_insert_into_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.get_insert_into_sql\", \"macro_sql\": \"{% macro get_insert_into_sql(target_relation, temp_relation, dest_columns) %}\\n\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n\\n    insert into {{ target_relation }} ({{ dest_cols_csv }})\\n    (\\n        select {{ dest_cols_csv }}\\n        from {{ temp_relation }}\\n    )\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_quoted_csv\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.176376, \"supported_languages\": null}, \"macro.dbt.materialization_incremental_default\": {\"name\": \"materialization_incremental_default\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/incremental.sql\", \"original_file_path\": \"macros/materializations/models/incremental/incremental.sql\", \"unique_id\": \"macro.dbt.materialization_incremental_default\", \"macro_sql\": \"{% materialization incremental, default -%}\\n\\n  -- relations\\n  {%- set existing_relation = load_cached_relation(this) -%}\\n  {%- set target_relation = this.incorporate(type='table') -%}\\n  {%- set temp_relation = make_temp_relation(target_relation)-%}\\n  {%- set intermediate_relation = make_intermediate_relation(target_relation)-%}\\n  {%- set backup_relation_type = 'table' if existing_relation is none else existing_relation.type -%}\\n  {%- set backup_relation = make_backup_relation(target_relation, backup_relation_type) -%}\\n\\n  -- configs\\n  {%- set unique_key = config.get('unique_key') -%}\\n  {%- set full_refresh_mode = (should_full_refresh()  or existing_relation.is_view) -%}\\n  {%- set on_schema_change = incremental_validate_on_schema_change(config.get('on_schema_change'), default='ignore') -%}\\n\\n  -- the temp_ and backup_ relations should not already exist in the database; get_relation\\n  -- will return None in that case. Otherwise, we get a relation that we can drop\\n  -- later, before we try to use this name for the current operation. This has to happen before\\n  -- BEGIN, in a separate transaction\\n  {%- set preexisting_intermediate_relation = load_cached_relation(intermediate_relation)-%}\\n  {%- set preexisting_backup_relation = load_cached_relation(backup_relation) -%}\\n   -- grab current tables grants config for comparision later on\\n  {% set grant_config = config.get('grants') %}\\n  {{ drop_relation_if_exists(preexisting_intermediate_relation) }}\\n  {{ drop_relation_if_exists(preexisting_backup_relation) }}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  {% set to_drop = [] %}\\n\\n  {% if existing_relation is none %}\\n      {% set build_sql = get_create_table_as_sql(False, target_relation, sql) %}\\n  {% elif full_refresh_mode %}\\n      {% set build_sql = get_create_table_as_sql(False, intermediate_relation, sql) %}\\n      {% set need_swap = true %}\\n  {% else %}\\n    {% do run_query(get_create_table_as_sql(True, temp_relation, sql)) %}\\n    {% do adapter.expand_target_column_types(\\n             from_relation=temp_relation,\\n             to_relation=target_relation) %}\\n    {#-- Process schema changes. Returns dict of changes if successful. Use source columns for upserting/merging --#}\\n    {% set dest_columns = process_schema_changes(on_schema_change, temp_relation, existing_relation) %}\\n    {% if not dest_columns %}\\n      {% set dest_columns = adapter.get_columns_in_relation(existing_relation) %}\\n    {% endif %}\\n\\n    {#-- Get the incremental_strategy, the macro to use for the strategy, and build the sql --#}\\n    {% set incremental_strategy = config.get('incremental_strategy') or 'default' %}\\n    {% set incremental_predicates = config.get('predicates', none) or config.get('incremental_predicates', none) %}\\n    {% set strategy_sql_macro_func = adapter.get_incremental_strategy_macro(context, incremental_strategy) %}\\n    {% set strategy_arg_dict = ({'target_relation': target_relation, 'temp_relation': temp_relation, 'unique_key': unique_key, 'dest_columns': dest_columns, 'incremental_predicates': incremental_predicates }) %}\\n    {% set build_sql = strategy_sql_macro_func(strategy_arg_dict) %}\\n\\n  {% endif %}\\n\\n  {% call statement(\\\"main\\\") %}\\n      {{ build_sql }}\\n  {% endcall %}\\n\\n  {% if need_swap %}\\n      {% do adapter.rename_relation(target_relation, backup_relation) %}\\n      {% do adapter.rename_relation(intermediate_relation, target_relation) %}\\n      {% do to_drop.append(backup_relation) %}\\n  {% endif %}\\n\\n  {% set should_revoke = should_revoke(existing_relation, full_refresh_mode) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {% if existing_relation is none or existing_relation.is_view or should_full_refresh() %}\\n    {% do create_indexes(target_relation) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  -- `COMMIT` happens here\\n  {% do adapter.commit() %}\\n\\n  {% for rel in to_drop %}\\n      {% do adapter.drop_relation(rel) %}\\n  {% endfor %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{%- endmaterialization %}\", \"depends_on\": {\"macros\": [\"macro.dbt.load_cached_relation\", \"macro.dbt.make_temp_relation\", \"macro.dbt.make_intermediate_relation\", \"macro.dbt.make_backup_relation\", \"macro.dbt.should_full_refresh\", \"macro.dbt.incremental_validate_on_schema_change\", \"macro.dbt.drop_relation_if_exists\", \"macro.dbt.run_hooks\", \"macro.dbt.get_create_table_as_sql\", \"macro.dbt.run_query\", \"macro.dbt.process_schema_changes\", \"macro.dbt.statement\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\", \"macro.dbt.persist_docs\", \"macro.dbt.create_indexes\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.1815941, \"supported_languages\": [\"sql\"]}, \"macro.dbt.incremental_validate_on_schema_change\": {\"name\": \"incremental_validate_on_schema_change\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"original_file_path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"unique_id\": \"macro.dbt.incremental_validate_on_schema_change\", \"macro_sql\": \"{% macro incremental_validate_on_schema_change(on_schema_change, default='ignore') %}\\n\\n   {% if on_schema_change not in ['sync_all_columns', 'append_new_columns', 'fail', 'ignore'] %}\\n\\n     {% set log_message = 'Invalid value for on_schema_change (%s) specified. Setting default value of %s.' % (on_schema_change, default) %}\\n     {% do log(log_message) %}\\n\\n     {{ return(default) }}\\n\\n   {% else %}\\n\\n     {{ return(on_schema_change) }}\\n\\n   {% endif %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.1874628, \"supported_languages\": null}, \"macro.dbt.check_for_schema_changes\": {\"name\": \"check_for_schema_changes\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"original_file_path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"unique_id\": \"macro.dbt.check_for_schema_changes\", \"macro_sql\": \"{% macro check_for_schema_changes(source_relation, target_relation) %}\\n\\n  {% set schema_changed = False %}\\n\\n  {%- set source_columns = adapter.get_columns_in_relation(source_relation) -%}\\n  {%- set target_columns = adapter.get_columns_in_relation(target_relation) -%}\\n  {%- set source_not_in_target = diff_columns(source_columns, target_columns) -%}\\n  {%- set target_not_in_source = diff_columns(target_columns, source_columns) -%}\\n\\n  {% set new_target_types = diff_column_data_types(source_columns, target_columns) %}\\n\\n  {% if source_not_in_target != [] %}\\n    {% set schema_changed = True %}\\n  {% elif target_not_in_source != [] or new_target_types != [] %}\\n    {% set schema_changed = True %}\\n  {% elif new_target_types != [] %}\\n    {% set schema_changed = True %}\\n  {% endif %}\\n\\n  {% set changes_dict = {\\n    'schema_changed': schema_changed,\\n    'source_not_in_target': source_not_in_target,\\n    'target_not_in_source': target_not_in_source,\\n    'source_columns': source_columns,\\n    'target_columns': target_columns,\\n    'new_target_types': new_target_types\\n  } %}\\n\\n  {% set msg %}\\n    In {{ target_relation }}:\\n        Schema changed: {{ schema_changed }}\\n        Source columns not in target: {{ source_not_in_target }}\\n        Target columns not in source: {{ target_not_in_source }}\\n        New column types: {{ new_target_types }}\\n  {% endset %}\\n\\n  {% do log(msg) %}\\n\\n  {{ return(changes_dict) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.diff_columns\", \"macro.dbt.diff_column_data_types\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.188724, \"supported_languages\": null}, \"macro.dbt.sync_column_schemas\": {\"name\": \"sync_column_schemas\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"original_file_path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"unique_id\": \"macro.dbt.sync_column_schemas\", \"macro_sql\": \"{% macro sync_column_schemas(on_schema_change, target_relation, schema_changes_dict) %}\\n\\n  {%- set add_to_target_arr = schema_changes_dict['source_not_in_target'] -%}\\n\\n  {%- if on_schema_change == 'append_new_columns'-%}\\n     {%- if add_to_target_arr | length > 0 -%}\\n       {%- do alter_relation_add_remove_columns(target_relation, add_to_target_arr, none) -%}\\n     {%- endif -%}\\n\\n  {% elif on_schema_change == 'sync_all_columns' %}\\n     {%- set remove_from_target_arr = schema_changes_dict['target_not_in_source'] -%}\\n     {%- set new_target_types = schema_changes_dict['new_target_types'] -%}\\n\\n     {% if add_to_target_arr | length > 0 or remove_from_target_arr | length > 0 %}\\n       {%- do alter_relation_add_remove_columns(target_relation, add_to_target_arr, remove_from_target_arr) -%}\\n     {% endif %}\\n\\n     {% if new_target_types != [] %}\\n       {% for ntt in new_target_types %}\\n         {% set column_name = ntt['column_name'] %}\\n         {% set new_type = ntt['new_type'] %}\\n         {% do alter_column_type(target_relation, column_name, new_type) %}\\n       {% endfor %}\\n     {% endif %}\\n\\n  {% endif %}\\n\\n  {% set schema_change_message %}\\n    In {{ target_relation }}:\\n        Schema change approach: {{ on_schema_change }}\\n        Columns added: {{ add_to_target_arr }}\\n        Columns removed: {{ remove_from_target_arr }}\\n        Data types changed: {{ new_target_types }}\\n  {% endset %}\\n\\n  {% do log(schema_change_message) %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.alter_relation_add_remove_columns\", \"macro.dbt.alter_column_type\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.189962, \"supported_languages\": null}, \"macro.dbt.process_schema_changes\": {\"name\": \"process_schema_changes\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"original_file_path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"unique_id\": \"macro.dbt.process_schema_changes\", \"macro_sql\": \"{% macro process_schema_changes(on_schema_change, source_relation, target_relation) %}\\n\\n    {% if on_schema_change == 'ignore' %}\\n\\n     {{ return({}) }}\\n\\n    {% else %}\\n\\n      {% set schema_changes_dict = check_for_schema_changes(source_relation, target_relation) %}\\n\\n      {% if schema_changes_dict['schema_changed'] %}\\n\\n        {% if on_schema_change == 'fail' %}\\n\\n          {% set fail_msg %}\\n              The source and target schemas on this incremental model are out of sync!\\n              They can be reconciled in several ways:\\n                - set the `on_schema_change` config to either append_new_columns or sync_all_columns, depending on your situation.\\n                - Re-run the incremental model with `full_refresh: True` to update the target schema.\\n                - update the schema manually and re-run the process.\\n\\n              Additional troubleshooting context:\\n                 Source columns not in target: {{ schema_changes_dict['source_not_in_target'] }}\\n                 Target columns not in source: {{ schema_changes_dict['target_not_in_source'] }}\\n                 New column types: {{ schema_changes_dict['new_target_types'] }}\\n          {% endset %}\\n\\n          {% do exceptions.raise_compiler_error(fail_msg) %}\\n\\n        {# -- unless we ignore, run the sync operation per the config #}\\n        {% else %}\\n\\n          {% do sync_column_schemas(on_schema_change, target_relation, schema_changes_dict) %}\\n\\n        {% endif %}\\n\\n      {% endif %}\\n\\n      {{ return(schema_changes_dict['source_columns']) }}\\n\\n    {% endif %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.check_for_schema_changes\", \"macro.dbt.sync_column_schemas\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.1908412, \"supported_languages\": null}, \"macro.dbt.materialization_materialized_view_default\": {\"name\": \"materialization_materialized_view_default\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/materialized_view/materialized_view.sql\", \"original_file_path\": \"macros/materializations/models/materialized_view/materialized_view.sql\", \"unique_id\": \"macro.dbt.materialization_materialized_view_default\", \"macro_sql\": \"{% materialization materialized_view, default %}\\n    {% set existing_relation = load_cached_relation(this) %}\\n    {% set target_relation = this.incorporate(type=this.MaterializedView) %}\\n    {% set intermediate_relation = make_intermediate_relation(target_relation) %}\\n    {% set backup_relation_type = target_relation.MaterializedView if existing_relation is none else existing_relation.type %}\\n    {% set backup_relation = make_backup_relation(target_relation, backup_relation_type) %}\\n\\n    {{ materialized_view_setup(backup_relation, intermediate_relation, pre_hooks) }}\\n\\n        {% set build_sql = materialized_view_get_build_sql(existing_relation, target_relation, backup_relation, intermediate_relation) %}\\n\\n        {% if build_sql == '' %}\\n            {{ materialized_view_execute_no_op(target_relation) }}\\n        {% else %}\\n            {{ materialized_view_execute_build_sql(build_sql, existing_relation, target_relation, post_hooks) }}\\n        {% endif %}\\n\\n    {{ materialized_view_teardown(backup_relation, intermediate_relation, post_hooks) }}\\n\\n    {{ return({'relations': [target_relation]}) }}\\n\\n{% endmaterialization %}\", \"depends_on\": {\"macros\": [\"macro.dbt.load_cached_relation\", \"macro.dbt.make_intermediate_relation\", \"macro.dbt.make_backup_relation\", \"macro.dbt.materialized_view_setup\", \"macro.dbt.materialized_view_get_build_sql\", \"macro.dbt.materialized_view_execute_no_op\", \"macro.dbt.materialized_view_execute_build_sql\", \"macro.dbt.materialized_view_teardown\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.196028, \"supported_languages\": [\"sql\"]}, \"macro.dbt.materialized_view_setup\": {\"name\": \"materialized_view_setup\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/materialized_view/materialized_view.sql\", \"original_file_path\": \"macros/materializations/models/materialized_view/materialized_view.sql\", \"unique_id\": \"macro.dbt.materialized_view_setup\", \"macro_sql\": \"{% macro materialized_view_setup(backup_relation, intermediate_relation, pre_hooks) %}\\n\\n    -- backup_relation and intermediate_relation should not already exist in the database\\n    -- it's possible these exist because of a previous run that exited unexpectedly\\n    {% set preexisting_backup_relation = load_cached_relation(backup_relation) %}\\n    {% set preexisting_intermediate_relation = load_cached_relation(intermediate_relation) %}\\n\\n    -- drop the temp relations if they exist already in the database\\n    {{ drop_relation_if_exists(preexisting_backup_relation) }}\\n    {{ drop_relation_if_exists(preexisting_intermediate_relation) }}\\n\\n    {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.load_cached_relation\", \"macro.dbt.drop_relation_if_exists\", \"macro.dbt.run_hooks\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.1964319, \"supported_languages\": null}, \"macro.dbt.materialized_view_teardown\": {\"name\": \"materialized_view_teardown\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/materialized_view/materialized_view.sql\", \"original_file_path\": \"macros/materializations/models/materialized_view/materialized_view.sql\", \"unique_id\": \"macro.dbt.materialized_view_teardown\", \"macro_sql\": \"{% macro materialized_view_teardown(backup_relation, intermediate_relation, post_hooks) %}\\n\\n    -- drop the temp relations if they exist to leave the database clean for the next run\\n    {{ drop_relation_if_exists(backup_relation) }}\\n    {{ drop_relation_if_exists(intermediate_relation) }}\\n\\n    {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.drop_relation_if_exists\", \"macro.dbt.run_hooks\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.196692, \"supported_languages\": null}, \"macro.dbt.materialized_view_get_build_sql\": {\"name\": \"materialized_view_get_build_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/materialized_view/materialized_view.sql\", \"original_file_path\": \"macros/materializations/models/materialized_view/materialized_view.sql\", \"unique_id\": \"macro.dbt.materialized_view_get_build_sql\", \"macro_sql\": \"{% macro materialized_view_get_build_sql(existing_relation, target_relation, backup_relation, intermediate_relation) %}\\n\\n    {% set full_refresh_mode = should_full_refresh() %}\\n\\n    -- determine the scenario we're in: create, full_refresh, alter, refresh data\\n    {% if existing_relation is none %}\\n        {% set build_sql = get_create_materialized_view_as_sql(target_relation, sql) %}\\n    {% elif full_refresh_mode or not existing_relation.is_materialized_view %}\\n        {% set build_sql = get_replace_materialized_view_as_sql(target_relation, sql, existing_relation, backup_relation, intermediate_relation) %}\\n    {% else %}\\n\\n        -- get config options\\n        {% set on_configuration_change = config.get('on_configuration_change') %}\\n        {% set configuration_changes = get_materialized_view_configuration_changes(existing_relation, config) %}\\n\\n        {% if configuration_changes is none %}\\n            {% set build_sql = refresh_materialized_view(target_relation) %}\\n\\n        {% elif on_configuration_change == 'apply' %}\\n            {% set build_sql = get_alter_materialized_view_as_sql(target_relation, configuration_changes, sql, existing_relation, backup_relation, intermediate_relation) %}\\n        {% elif on_configuration_change == 'continue' %}\\n            {% set build_sql = '' %}\\n            {{ exceptions.warn(\\\"Configuration changes were identified and `on_configuration_change` was set to `continue` for `\\\" ~ target_relation ~ \\\"`\\\") }}\\n        {% elif on_configuration_change == 'fail' %}\\n            {{ exceptions.raise_fail_fast_error(\\\"Configuration changes were identified and `on_configuration_change` was set to `fail` for `\\\" ~ target_relation ~ \\\"`\\\") }}\\n\\n        {% else %}\\n            -- this only happens if the user provides a value other than `apply`, 'skip', 'fail'\\n            {{ exceptions.raise_compiler_error(\\\"Unexpected configuration scenario\\\") }}\\n\\n        {% endif %}\\n\\n    {% endif %}\\n\\n    {% do return(build_sql) %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.should_full_refresh\", \"macro.dbt.get_create_materialized_view_as_sql\", \"macro.dbt.get_replace_materialized_view_as_sql\", \"macro.dbt.get_materialized_view_configuration_changes\", \"macro.dbt.refresh_materialized_view\", \"macro.dbt.get_alter_materialized_view_as_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.1980631, \"supported_languages\": null}, \"macro.dbt.materialized_view_execute_no_op\": {\"name\": \"materialized_view_execute_no_op\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/materialized_view/materialized_view.sql\", \"original_file_path\": \"macros/materializations/models/materialized_view/materialized_view.sql\", \"unique_id\": \"macro.dbt.materialized_view_execute_no_op\", \"macro_sql\": \"{% macro materialized_view_execute_no_op(target_relation) %}\\n    {% do store_raw_result(\\n        name=\\\"main\\\",\\n        message=\\\"skip \\\" ~ target_relation,\\n        code=\\\"skip\\\",\\n        rows_affected=\\\"-1\\\"\\n    ) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.198303, \"supported_languages\": null}, \"macro.dbt.materialized_view_execute_build_sql\": {\"name\": \"materialized_view_execute_build_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/materialized_view/materialized_view.sql\", \"original_file_path\": \"macros/materializations/models/materialized_view/materialized_view.sql\", \"unique_id\": \"macro.dbt.materialized_view_execute_build_sql\", \"macro_sql\": \"{% macro materialized_view_execute_build_sql(build_sql, existing_relation, target_relation, post_hooks) %}\\n\\n    -- `BEGIN` happens here:\\n    {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n    {% set grant_config = config.get('grants') %}\\n\\n    {% call statement(name=\\\"main\\\") %}\\n        {{ build_sql }}\\n    {% endcall %}\\n\\n    {% set should_revoke = should_revoke(existing_relation, full_refresh_mode=True) %}\\n    {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n    {% do persist_docs(target_relation, model) %}\\n\\n    {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n    {{ adapter.commit() }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.run_hooks\", \"macro.dbt.statement\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\", \"macro.dbt.persist_docs\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.198978, \"supported_languages\": null}, \"macro.dbt.get_materialized_view_configuration_changes\": {\"name\": \"get_materialized_view_configuration_changes\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/materialized_view/get_materialized_view_configuration_changes.sql\", \"original_file_path\": \"macros/materializations/models/materialized_view/get_materialized_view_configuration_changes.sql\", \"unique_id\": \"macro.dbt.get_materialized_view_configuration_changes\", \"macro_sql\": \"{% macro get_materialized_view_configuration_changes(existing_relation, new_config) %}\\n    /* {#\\n    It's recommended that configuration changes be formatted as follows:\\n    {\\\"<change_category>\\\": [{\\\"action\\\": \\\"<name>\\\", \\\"context\\\": ...}]}\\n\\n    For example:\\n    {\\n        \\\"indexes\\\": [\\n            {\\\"action\\\": \\\"drop\\\", \\\"context\\\": \\\"index_abc\\\"},\\n            {\\\"action\\\": \\\"create\\\", \\\"context\\\": {\\\"columns\\\": [\\\"column_1\\\", \\\"column_2\\\"], \\\"type\\\": \\\"hash\\\", \\\"unique\\\": True}},\\n        ],\\n    }\\n\\n    Either way, `get_materialized_view_configuration_changes` needs to align with `get_alter_materialized_view_as_sql`.\\n    #} */\\n    {{- log('Determining configuration changes on: ' ~ existing_relation) -}}\\n    {%- do return(adapter.dispatch('get_materialized_view_configuration_changes', 'dbt')(existing_relation, new_config)) -%}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_materialized_view_configuration_changes\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.19941, \"supported_languages\": null}, \"macro.dbt.default__get_materialized_view_configuration_changes\": {\"name\": \"default__get_materialized_view_configuration_changes\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/materialized_view/get_materialized_view_configuration_changes.sql\", \"original_file_path\": \"macros/materializations/models/materialized_view/get_materialized_view_configuration_changes.sql\", \"unique_id\": \"macro.dbt.default__get_materialized_view_configuration_changes\", \"macro_sql\": \"{% macro default__get_materialized_view_configuration_changes(existing_relation, new_config) %}\\n    {{ exceptions.raise_compiler_error(\\\"Materialized views have not been implemented for this adapter.\\\") }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.19956, \"supported_languages\": null}, \"macro.dbt.get_alter_materialized_view_as_sql\": {\"name\": \"get_alter_materialized_view_as_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/materialized_view/alter_materialized_view.sql\", \"original_file_path\": \"macros/materializations/models/materialized_view/alter_materialized_view.sql\", \"unique_id\": \"macro.dbt.get_alter_materialized_view_as_sql\", \"macro_sql\": \"{% macro get_alter_materialized_view_as_sql(\\n    relation,\\n    configuration_changes,\\n    sql,\\n    existing_relation,\\n    backup_relation,\\n    intermediate_relation\\n) %}\\n    {{- log('Applying ALTER to: ' ~ relation) -}}\\n    {{- adapter.dispatch('get_alter_materialized_view_as_sql', 'dbt')(\\n        relation,\\n        configuration_changes,\\n        sql,\\n        existing_relation,\\n        backup_relation,\\n        intermediate_relation\\n    ) -}}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_alter_materialized_view_as_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.200053, \"supported_languages\": null}, \"macro.dbt.default__get_alter_materialized_view_as_sql\": {\"name\": \"default__get_alter_materialized_view_as_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/materialized_view/alter_materialized_view.sql\", \"original_file_path\": \"macros/materializations/models/materialized_view/alter_materialized_view.sql\", \"unique_id\": \"macro.dbt.default__get_alter_materialized_view_as_sql\", \"macro_sql\": \"{% macro default__get_alter_materialized_view_as_sql(\\n    relation,\\n    configuration_changes,\\n    sql,\\n    existing_relation,\\n    backup_relation,\\n    intermediate_relation\\n) %}\\n    {{ exceptions.raise_compiler_error(\\\"Materialized views have not been implemented for this adapter.\\\") }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.200245, \"supported_languages\": null}, \"macro.dbt.refresh_materialized_view\": {\"name\": \"refresh_materialized_view\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/materialized_view/refresh_materialized_view.sql\", \"original_file_path\": \"macros/materializations/models/materialized_view/refresh_materialized_view.sql\", \"unique_id\": \"macro.dbt.refresh_materialized_view\", \"macro_sql\": \"{% macro refresh_materialized_view(relation) %}\\n    {{- log('Applying REFRESH to: ' ~ relation) -}}\\n    {{- adapter.dispatch('refresh_materialized_view', 'dbt')(relation) -}}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__refresh_materialized_view\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2005591, \"supported_languages\": null}, \"macro.dbt.default__refresh_materialized_view\": {\"name\": \"default__refresh_materialized_view\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/materialized_view/refresh_materialized_view.sql\", \"original_file_path\": \"macros/materializations/models/materialized_view/refresh_materialized_view.sql\", \"unique_id\": \"macro.dbt.default__refresh_materialized_view\", \"macro_sql\": \"{% macro default__refresh_materialized_view(relation) %}\\n    {{ exceptions.raise_compiler_error(\\\"Materialized views have not been implemented for this adapter.\\\") }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2006972, \"supported_languages\": null}, \"macro.dbt.get_replace_materialized_view_as_sql\": {\"name\": \"get_replace_materialized_view_as_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/materialized_view/replace_materialized_view.sql\", \"original_file_path\": \"macros/materializations/models/materialized_view/replace_materialized_view.sql\", \"unique_id\": \"macro.dbt.get_replace_materialized_view_as_sql\", \"macro_sql\": \"{% macro get_replace_materialized_view_as_sql(relation, sql, existing_relation, backup_relation, intermediate_relation) %}\\n    {{- log('Applying REPLACE to: ' ~ relation) -}}\\n    {{- adapter.dispatch('get_replace_materialized_view_as_sql', 'dbt')(relation, sql, existing_relation, backup_relation, intermediate_relation) -}}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_replace_materialized_view_as_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2011251, \"supported_languages\": null}, \"macro.dbt.default__get_replace_materialized_view_as_sql\": {\"name\": \"default__get_replace_materialized_view_as_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/materialized_view/replace_materialized_view.sql\", \"original_file_path\": \"macros/materializations/models/materialized_view/replace_materialized_view.sql\", \"unique_id\": \"macro.dbt.default__get_replace_materialized_view_as_sql\", \"macro_sql\": \"{% macro default__get_replace_materialized_view_as_sql(relation, sql, existing_relation, backup_relation, intermediate_relation) %}\\n    {{ exceptions.raise_compiler_error(\\\"Materialized views have not been implemented for this adapter.\\\") }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2013052, \"supported_languages\": null}, \"macro.dbt.get_create_materialized_view_as_sql\": {\"name\": \"get_create_materialized_view_as_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/materialized_view/create_materialized_view.sql\", \"original_file_path\": \"macros/materializations/models/materialized_view/create_materialized_view.sql\", \"unique_id\": \"macro.dbt.get_create_materialized_view_as_sql\", \"macro_sql\": \"{% macro get_create_materialized_view_as_sql(relation, sql) -%}\\n    {{- log('Applying CREATE to: ' ~ relation) -}}\\n    {{- adapter.dispatch('get_create_materialized_view_as_sql', 'dbt')(relation, sql) -}}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_create_materialized_view_as_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.201658, \"supported_languages\": null}, \"macro.dbt.default__get_create_materialized_view_as_sql\": {\"name\": \"default__get_create_materialized_view_as_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/materialized_view/create_materialized_view.sql\", \"original_file_path\": \"macros/materializations/models/materialized_view/create_materialized_view.sql\", \"unique_id\": \"macro.dbt.default__get_create_materialized_view_as_sql\", \"macro_sql\": \"{% macro default__get_create_materialized_view_as_sql(relation, sql) -%}\\n    {{ exceptions.raise_compiler_error(\\\"Materialized views have not been implemented for this adapter.\\\") }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.201805, \"supported_languages\": null}, \"macro.dbt.can_clone_table\": {\"name\": \"can_clone_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/clone/can_clone_table.sql\", \"original_file_path\": \"macros/materializations/models/clone/can_clone_table.sql\", \"unique_id\": \"macro.dbt.can_clone_table\", \"macro_sql\": \"{% macro can_clone_table() %}\\n    {{ return(adapter.dispatch('can_clone_table', 'dbt')()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__can_clone_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.202045, \"supported_languages\": null}, \"macro.dbt.default__can_clone_table\": {\"name\": \"default__can_clone_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/clone/can_clone_table.sql\", \"original_file_path\": \"macros/materializations/models/clone/can_clone_table.sql\", \"unique_id\": \"macro.dbt.default__can_clone_table\", \"macro_sql\": \"{% macro default__can_clone_table() %}\\n    {{ return(False) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.202231, \"supported_languages\": null}, \"macro.dbt.create_or_replace_clone\": {\"name\": \"create_or_replace_clone\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/clone/create_or_replace_clone.sql\", \"original_file_path\": \"macros/materializations/models/clone/create_or_replace_clone.sql\", \"unique_id\": \"macro.dbt.create_or_replace_clone\", \"macro_sql\": \"{% macro create_or_replace_clone(this_relation, defer_relation) %}\\n    {{ return(adapter.dispatch('create_or_replace_clone', 'dbt')(this_relation, defer_relation)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__create_or_replace_clone\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.202538, \"supported_languages\": null}, \"macro.dbt.default__create_or_replace_clone\": {\"name\": \"default__create_or_replace_clone\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/clone/create_or_replace_clone.sql\", \"original_file_path\": \"macros/materializations/models/clone/create_or_replace_clone.sql\", \"unique_id\": \"macro.dbt.default__create_or_replace_clone\", \"macro_sql\": \"{% macro default__create_or_replace_clone(this_relation, defer_relation) %}\\n    create or replace table {{ this_relation }} clone {{ defer_relation }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.202677, \"supported_languages\": null}, \"macro.dbt.materialization_clone_default\": {\"name\": \"materialization_clone_default\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/clone/clone.sql\", \"original_file_path\": \"macros/materializations/models/clone/clone.sql\", \"unique_id\": \"macro.dbt.materialization_clone_default\", \"macro_sql\": \"{%- materialization clone, default -%}\\n\\n  {%- set relations = {'relations': []} -%}\\n\\n  {%- if not defer_relation -%}\\n      -- nothing to do\\n      {{ log(\\\"No relation found in state manifest for \\\" ~ model.unique_id, info=True) }}\\n      {{ return(relations) }}\\n  {%- endif -%}\\n\\n  {%- set existing_relation = load_cached_relation(this) -%}\\n\\n  {%- if existing_relation and not flags.FULL_REFRESH -%}\\n      -- noop!\\n      {{ log(\\\"Relation \\\" ~ existing_relation ~ \\\" already exists\\\", info=True) }}\\n      {{ return(relations) }}\\n  {%- endif -%}\\n\\n  {%- set other_existing_relation = load_cached_relation(defer_relation) -%}\\n\\n  -- If this is a database that can do zero-copy cloning of tables, and the other relation is a table, then this will be a table\\n  -- Otherwise, this will be a view\\n\\n  {% set can_clone_table = can_clone_table() %}\\n\\n  {%- if other_existing_relation and other_existing_relation.type == 'table' and can_clone_table -%}\\n\\n      {%- set target_relation = this.incorporate(type='table') -%}\\n      {% if existing_relation is not none and not existing_relation.is_table %}\\n        {{ log(\\\"Dropping relation \\\" ~ existing_relation ~ \\\" because it is of type \\\" ~ existing_relation.type) }}\\n        {{ drop_relation_if_exists(existing_relation) }}\\n      {% endif %}\\n\\n      -- as a general rule, data platforms that can clone tables can also do atomic 'create or replace'\\n      {% call statement('main') %}\\n          {{ create_or_replace_clone(target_relation, defer_relation) }}\\n      {% endcall %}\\n\\n      {% set should_revoke = should_revoke(existing_relation, full_refresh_mode=True) %}\\n      {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n      {% do persist_docs(target_relation, model) %}\\n\\n      {{ return({'relations': [target_relation]}) }}\\n\\n  {%- else -%}\\n\\n      {%- set target_relation = this.incorporate(type='view') -%}\\n\\n      -- reuse the view materialization\\n      -- TODO: support actual dispatch for materialization macros\\n      -- Tracking ticket: https://github.com/dbt-labs/dbt-core/issues/7799\\n      {% set search_name = \\\"materialization_view_\\\" ~ adapter.type() %}\\n      {% if not search_name in context %}\\n          {% set search_name = \\\"materialization_view_default\\\" %}\\n      {% endif %}\\n      {% set materialization_macro = context[search_name] %}\\n      {% set relations = materialization_macro() %}\\n      {{ return(relations) }}\\n\\n  {%- endif -%}\\n\\n{%- endmaterialization -%}\", \"depends_on\": {\"macros\": [\"macro.dbt.load_cached_relation\", \"macro.dbt.can_clone_table\", \"macro.dbt.drop_relation_if_exists\", \"macro.dbt.statement\", \"macro.dbt.create_or_replace_clone\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\", \"macro.dbt.persist_docs\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2059531, \"supported_languages\": [\"sql\"]}, \"macro.dbt.get_table_columns_and_constraints\": {\"name\": \"get_table_columns_and_constraints\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/table/columns_spec_ddl.sql\", \"original_file_path\": \"macros/materializations/models/table/columns_spec_ddl.sql\", \"unique_id\": \"macro.dbt.get_table_columns_and_constraints\", \"macro_sql\": \"{%- macro get_table_columns_and_constraints() -%}\\n  {{ adapter.dispatch('get_table_columns_and_constraints', 'dbt')() }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_table_columns_and_constraints\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2070122, \"supported_languages\": null}, \"macro.dbt.default__get_table_columns_and_constraints\": {\"name\": \"default__get_table_columns_and_constraints\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/table/columns_spec_ddl.sql\", \"original_file_path\": \"macros/materializations/models/table/columns_spec_ddl.sql\", \"unique_id\": \"macro.dbt.default__get_table_columns_and_constraints\", \"macro_sql\": \"{% macro default__get_table_columns_and_constraints() -%}\\n  {{ return(table_columns_and_constraints()) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.table_columns_and_constraints\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2071402, \"supported_languages\": null}, \"macro.dbt.table_columns_and_constraints\": {\"name\": \"table_columns_and_constraints\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/table/columns_spec_ddl.sql\", \"original_file_path\": \"macros/materializations/models/table/columns_spec_ddl.sql\", \"unique_id\": \"macro.dbt.table_columns_and_constraints\", \"macro_sql\": \"{% macro table_columns_and_constraints() %}\\n  {# loop through user_provided_columns to create DDL with data types and constraints #}\\n    {%- set raw_column_constraints = adapter.render_raw_columns_constraints(raw_columns=model['columns']) -%}\\n    {%- set raw_model_constraints = adapter.render_raw_model_constraints(raw_constraints=model['constraints']) -%}\\n    (\\n    {% for c in raw_column_constraints -%}\\n      {{ c }}{{ \\\",\\\" if not loop.last or raw_model_constraints }}\\n    {% endfor %}\\n    {% for c in raw_model_constraints -%}\\n        {{ c }}{{ \\\",\\\" if not loop.last }}\\n    {% endfor -%}\\n    )\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.207693, \"supported_languages\": null}, \"macro.dbt.get_assert_columns_equivalent\": {\"name\": \"get_assert_columns_equivalent\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/table/columns_spec_ddl.sql\", \"original_file_path\": \"macros/materializations/models/table/columns_spec_ddl.sql\", \"unique_id\": \"macro.dbt.get_assert_columns_equivalent\", \"macro_sql\": \"\\n\\n{%- macro get_assert_columns_equivalent(sql) -%}\\n  {{ adapter.dispatch('get_assert_columns_equivalent', 'dbt')(sql) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_assert_columns_equivalent\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2078662, \"supported_languages\": null}, \"macro.dbt.default__get_assert_columns_equivalent\": {\"name\": \"default__get_assert_columns_equivalent\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/table/columns_spec_ddl.sql\", \"original_file_path\": \"macros/materializations/models/table/columns_spec_ddl.sql\", \"unique_id\": \"macro.dbt.default__get_assert_columns_equivalent\", \"macro_sql\": \"{% macro default__get_assert_columns_equivalent(sql) -%}\\n  {{ return(assert_columns_equivalent(sql)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.assert_columns_equivalent\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2080052, \"supported_languages\": null}, \"macro.dbt.assert_columns_equivalent\": {\"name\": \"assert_columns_equivalent\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/table/columns_spec_ddl.sql\", \"original_file_path\": \"macros/materializations/models/table/columns_spec_ddl.sql\", \"unique_id\": \"macro.dbt.assert_columns_equivalent\", \"macro_sql\": \"{% macro assert_columns_equivalent(sql) %}\\n\\n  {#-- First ensure the user has defined 'columns' in yaml specification --#}\\n  {%- set user_defined_columns = model['columns'] -%}\\n  {%- if not user_defined_columns -%}\\n      {{ exceptions.raise_contract_error([], []) }}\\n  {%- endif -%}\\n\\n  {#-- Obtain the column schema provided by sql file. #}\\n  {%- set sql_file_provided_columns = get_column_schema_from_query(sql, config.get('sql_header', none)) -%}\\n  {#--Obtain the column schema provided by the schema file by generating an 'empty schema' query from the model's columns. #}\\n  {%- set schema_file_provided_columns = get_column_schema_from_query(get_empty_schema_sql(user_defined_columns)) -%}\\n\\n  {#-- create dictionaries with name and formatted data type and strings for exception #}\\n  {%- set sql_columns = format_columns(sql_file_provided_columns) -%}\\n  {%- set yaml_columns = format_columns(schema_file_provided_columns)  -%}\\n\\n  {%- if sql_columns|length != yaml_columns|length -%}\\n    {%- do exceptions.raise_contract_error(yaml_columns, sql_columns) -%}\\n  {%- endif -%}\\n\\n  {%- for sql_col in sql_columns -%}\\n    {%- set yaml_col = [] -%}\\n    {%- for this_col in yaml_columns -%}\\n      {%- if this_col['name'] == sql_col['name'] -%}\\n        {%- do yaml_col.append(this_col) -%}\\n        {%- break -%}\\n      {%- endif -%}\\n    {%- endfor -%}\\n    {%- if not yaml_col -%}\\n      {#-- Column with name not found in yaml #}\\n      {%- do exceptions.raise_contract_error(yaml_columns, sql_columns) -%}\\n    {%- endif -%}\\n    {%- if sql_col['formatted'] != yaml_col[0]['formatted'] -%}\\n      {#-- Column data types don't match #}\\n      {%- do exceptions.raise_contract_error(yaml_columns, sql_columns) -%}\\n    {%- endif -%}\\n  {%- endfor -%}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_column_schema_from_query\", \"macro.dbt.get_empty_schema_sql\", \"macro.dbt.format_columns\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.209325, \"supported_languages\": null}, \"macro.dbt.format_columns\": {\"name\": \"format_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/table/columns_spec_ddl.sql\", \"original_file_path\": \"macros/materializations/models/table/columns_spec_ddl.sql\", \"unique_id\": \"macro.dbt.format_columns\", \"macro_sql\": \"{% macro format_columns(columns) %}\\n  {% set formatted_columns = [] %}\\n  {% for column in columns %}\\n    {%- set formatted_column = adapter.dispatch('format_column', 'dbt')(column) -%}\\n    {%- do formatted_columns.append(formatted_column) -%}\\n  {% endfor %}\\n  {{ return(formatted_columns) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__format_column\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.209718, \"supported_languages\": null}, \"macro.dbt.default__format_column\": {\"name\": \"default__format_column\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/table/columns_spec_ddl.sql\", \"original_file_path\": \"macros/materializations/models/table/columns_spec_ddl.sql\", \"unique_id\": \"macro.dbt.default__format_column\", \"macro_sql\": \"{% macro default__format_column(column) -%}\\n  {% set data_type = column.dtype %}\\n  {% set formatted = column.column.lower() ~ \\\" \\\" ~ data_type %}\\n  {{ return({'name': column.name, 'data_type': data_type, 'formatted': formatted}) }}\\n{%- endmacro -%}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.210073, \"supported_languages\": null}, \"macro.dbt.materialization_table_default\": {\"name\": \"materialization_table_default\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/table/table.sql\", \"original_file_path\": \"macros/materializations/models/table/table.sql\", \"unique_id\": \"macro.dbt.materialization_table_default\", \"macro_sql\": \"{% materialization table, default %}\\n\\n  {%- set existing_relation = load_cached_relation(this) -%}\\n  {%- set target_relation = this.incorporate(type='table') %}\\n  {%- set intermediate_relation =  make_intermediate_relation(target_relation) -%}\\n  -- the intermediate_relation should not already exist in the database; get_relation\\n  -- will return None in that case. Otherwise, we get a relation that we can drop\\n  -- later, before we try to use this name for the current operation\\n  {%- set preexisting_intermediate_relation = load_cached_relation(intermediate_relation) -%}\\n  /*\\n      See ../view/view.sql for more information about this relation.\\n  */\\n  {%- set backup_relation_type = 'table' if existing_relation is none else existing_relation.type -%}\\n  {%- set backup_relation = make_backup_relation(target_relation, backup_relation_type) -%}\\n  -- as above, the backup_relation should not already exist\\n  {%- set preexisting_backup_relation = load_cached_relation(backup_relation) -%}\\n  -- grab current tables grants config for comparision later on\\n  {% set grant_config = config.get('grants') %}\\n\\n  -- drop the temp relations if they exist already in the database\\n  {{ drop_relation_if_exists(preexisting_intermediate_relation) }}\\n  {{ drop_relation_if_exists(preexisting_backup_relation) }}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  -- build model\\n  {% call statement('main') -%}\\n    {{ get_create_table_as_sql(False, intermediate_relation, sql) }}\\n  {%- endcall %}\\n\\n  -- cleanup\\n  {% if existing_relation is not none %}\\n     /* Do the equivalent of rename_if_exists. 'existing_relation' could have been dropped\\n        since the variable was first set. */\\n    {% set existing_relation = load_cached_relation(existing_relation) %}\\n    {% if existing_relation is not none %}\\n        {{ adapter.rename_relation(existing_relation, backup_relation) }}\\n    {% endif %}\\n  {% endif %}\\n\\n  {{ adapter.rename_relation(intermediate_relation, target_relation) }}\\n\\n  {% do create_indexes(target_relation) %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  {% set should_revoke = should_revoke(existing_relation, full_refresh_mode=True) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  -- `COMMIT` happens here\\n  {{ adapter.commit() }}\\n\\n  -- finally, drop the existing/backup relation after the commit\\n  {{ drop_relation_if_exists(backup_relation) }}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n{% endmaterialization %}\", \"depends_on\": {\"macros\": [\"macro.dbt.load_cached_relation\", \"macro.dbt.make_intermediate_relation\", \"macro.dbt.make_backup_relation\", \"macro.dbt.drop_relation_if_exists\", \"macro.dbt.run_hooks\", \"macro.dbt.statement\", \"macro.dbt.get_create_table_as_sql\", \"macro.dbt.create_indexes\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\", \"macro.dbt.persist_docs\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2131069, \"supported_languages\": [\"sql\"]}, \"macro.dbt.get_create_table_as_sql\": {\"name\": \"get_create_table_as_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/table/create_table_as.sql\", \"original_file_path\": \"macros/materializations/models/table/create_table_as.sql\", \"unique_id\": \"macro.dbt.get_create_table_as_sql\", \"macro_sql\": \"{% macro get_create_table_as_sql(temporary, relation, sql) -%}\\n  {{ adapter.dispatch('get_create_table_as_sql', 'dbt')(temporary, relation, sql) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_create_table_as_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.214011, \"supported_languages\": null}, \"macro.dbt.default__get_create_table_as_sql\": {\"name\": \"default__get_create_table_as_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/table/create_table_as.sql\", \"original_file_path\": \"macros/materializations/models/table/create_table_as.sql\", \"unique_id\": \"macro.dbt.default__get_create_table_as_sql\", \"macro_sql\": \"{% macro default__get_create_table_as_sql(temporary, relation, sql) -%}\\n  {{ return(create_table_as(temporary, relation, sql)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.create_table_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2142022, \"supported_languages\": null}, \"macro.dbt.create_table_as\": {\"name\": \"create_table_as\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/table/create_table_as.sql\", \"original_file_path\": \"macros/materializations/models/table/create_table_as.sql\", \"unique_id\": \"macro.dbt.create_table_as\", \"macro_sql\": \"{% macro create_table_as(temporary, relation, compiled_code, language='sql') -%}\\n  {# backward compatibility for create_table_as that does not support language #}\\n  {% if language == \\\"sql\\\" %}\\n    {{ adapter.dispatch('create_table_as', 'dbt')(temporary, relation, compiled_code)}}\\n  {% else %}\\n    {{ adapter.dispatch('create_table_as', 'dbt')(temporary, relation, compiled_code, language) }}\\n  {% endif %}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__create_table_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.214653, \"supported_languages\": null}, \"macro.dbt.default__create_table_as\": {\"name\": \"default__create_table_as\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/table/create_table_as.sql\", \"original_file_path\": \"macros/materializations/models/table/create_table_as.sql\", \"unique_id\": \"macro.dbt.default__create_table_as\", \"macro_sql\": \"{% macro default__create_table_as(temporary, relation, sql) -%}\\n  {%- set sql_header = config.get('sql_header', none) -%}\\n\\n  {{ sql_header if sql_header is not none }}\\n\\n  create {% if temporary: -%}temporary{%- endif %} table\\n    {{ relation.include(database=(not temporary), schema=(not temporary)) }}\\n  {% set contract_config = config.get('contract') %}\\n  {% if contract_config.enforced and (not temporary) %}\\n    {{ get_assert_columns_equivalent(sql) }}\\n    {{ get_table_columns_and_constraints() }}\\n    {%- set sql = get_select_subquery(sql) %}\\n  {% endif %}\\n  as (\\n    {{ sql }}\\n  );\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_assert_columns_equivalent\", \"macro.dbt.get_table_columns_and_constraints\", \"macro.dbt.get_select_subquery\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2153769, \"supported_languages\": null}, \"macro.dbt.default__get_column_names\": {\"name\": \"default__get_column_names\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/table/create_table_as.sql\", \"original_file_path\": \"macros/materializations/models/table/create_table_as.sql\", \"unique_id\": \"macro.dbt.default__get_column_names\", \"macro_sql\": \"{% macro default__get_column_names() %}\\n  {#- loop through user_provided_columns to get column names -#}\\n    {%- set user_provided_columns = model['columns'] -%}\\n    {%- for i in user_provided_columns %}\\n      {%- set col = user_provided_columns[i] -%}\\n      {%- set col_name = adapter.quote(col['name']) if col.get('quote') else col['name'] -%}\\n      {{ col_name }}{{ \\\", \\\" if not loop.last }}\\n    {%- endfor -%}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2158551, \"supported_languages\": null}, \"macro.dbt.get_select_subquery\": {\"name\": \"get_select_subquery\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/table/create_table_as.sql\", \"original_file_path\": \"macros/materializations/models/table/create_table_as.sql\", \"unique_id\": \"macro.dbt.get_select_subquery\", \"macro_sql\": \"{% macro get_select_subquery(sql) %}\\n  {{ return(adapter.dispatch('get_select_subquery', 'dbt')(sql)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_select_subquery\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2160509, \"supported_languages\": null}, \"macro.dbt.default__get_select_subquery\": {\"name\": \"default__get_select_subquery\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/table/create_table_as.sql\", \"original_file_path\": \"macros/materializations/models/table/create_table_as.sql\", \"unique_id\": \"macro.dbt.default__get_select_subquery\", \"macro_sql\": \"{% macro default__get_select_subquery(sql) %}\\n    select {{ adapter.dispatch('get_column_names', 'dbt')() }}\\n    from (\\n        {{ sql }}\\n    ) as model_subq\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_column_names\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.216245, \"supported_languages\": null}, \"macro.dbt.materialization_view_default\": {\"name\": \"materialization_view_default\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/view/view.sql\", \"original_file_path\": \"macros/materializations/models/view/view.sql\", \"unique_id\": \"macro.dbt.materialization_view_default\", \"macro_sql\": \"{%- materialization view, default -%}\\n\\n  {%- set existing_relation = load_cached_relation(this) -%}\\n  {%- set target_relation = this.incorporate(type='view') -%}\\n  {%- set intermediate_relation =  make_intermediate_relation(target_relation) -%}\\n\\n  -- the intermediate_relation should not already exist in the database; get_relation\\n  -- will return None in that case. Otherwise, we get a relation that we can drop\\n  -- later, before we try to use this name for the current operation\\n  {%- set preexisting_intermediate_relation = load_cached_relation(intermediate_relation) -%}\\n  /*\\n     This relation (probably) doesn't exist yet. If it does exist, it's a leftover from\\n     a previous run, and we're going to try to drop it immediately. At the end of this\\n     materialization, we're going to rename the \\\"existing_relation\\\" to this identifier,\\n     and then we're going to drop it. In order to make sure we run the correct one of:\\n       - drop view ...\\n       - drop table ...\\n\\n     We need to set the type of this relation to be the type of the existing_relation, if it exists,\\n     or else \\\"view\\\" as a sane default if it does not. Note that if the existing_relation does not\\n     exist, then there is nothing to move out of the way and subsequentally drop. In that case,\\n     this relation will be effectively unused.\\n  */\\n  {%- set backup_relation_type = 'view' if existing_relation is none else existing_relation.type -%}\\n  {%- set backup_relation = make_backup_relation(target_relation, backup_relation_type) -%}\\n  -- as above, the backup_relation should not already exist\\n  {%- set preexisting_backup_relation = load_cached_relation(backup_relation) -%}\\n  -- grab current tables grants config for comparision later on\\n  {% set grant_config = config.get('grants') %}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- drop the temp relations if they exist already in the database\\n  {{ drop_relation_if_exists(preexisting_intermediate_relation) }}\\n  {{ drop_relation_if_exists(preexisting_backup_relation) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  -- build model\\n  {% call statement('main') -%}\\n    {{ get_create_view_as_sql(intermediate_relation, sql) }}\\n  {%- endcall %}\\n\\n  -- cleanup\\n  -- move the existing view out of the way\\n  {% if existing_relation is not none %}\\n     /* Do the equivalent of rename_if_exists. 'existing_relation' could have been dropped\\n        since the variable was first set. */\\n    {% set existing_relation = load_cached_relation(existing_relation) %}\\n    {% if existing_relation is not none %}\\n        {{ adapter.rename_relation(existing_relation, backup_relation) }}\\n    {% endif %}\\n  {% endif %}\\n  {{ adapter.rename_relation(intermediate_relation, target_relation) }}\\n\\n  {% set should_revoke = should_revoke(existing_relation, full_refresh_mode=True) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  {{ adapter.commit() }}\\n\\n  {{ drop_relation_if_exists(backup_relation) }}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{%- endmaterialization -%}\", \"depends_on\": {\"macros\": [\"macro.dbt.load_cached_relation\", \"macro.dbt.make_intermediate_relation\", \"macro.dbt.make_backup_relation\", \"macro.dbt.run_hooks\", \"macro.dbt.drop_relation_if_exists\", \"macro.dbt.statement\", \"macro.dbt.get_create_view_as_sql\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\", \"macro.dbt.persist_docs\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.219257, \"supported_languages\": [\"sql\"]}, \"macro.dbt.handle_existing_table\": {\"name\": \"handle_existing_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/view/helpers.sql\", \"original_file_path\": \"macros/materializations/models/view/helpers.sql\", \"unique_id\": \"macro.dbt.handle_existing_table\", \"macro_sql\": \"{% macro handle_existing_table(full_refresh, old_relation) %}\\n    {{ adapter.dispatch('handle_existing_table', 'dbt')(full_refresh, old_relation) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__handle_existing_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.219564, \"supported_languages\": null}, \"macro.dbt.default__handle_existing_table\": {\"name\": \"default__handle_existing_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/view/helpers.sql\", \"original_file_path\": \"macros/materializations/models/view/helpers.sql\", \"unique_id\": \"macro.dbt.default__handle_existing_table\", \"macro_sql\": \"{% macro default__handle_existing_table(full_refresh, old_relation) %}\\n    {{ log(\\\"Dropping relation \\\" ~ old_relation ~ \\\" because it is of type \\\" ~ old_relation.type) }}\\n    {{ adapter.drop_relation(old_relation) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.219792, \"supported_languages\": null}, \"macro.dbt.create_or_replace_view\": {\"name\": \"create_or_replace_view\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/view/create_or_replace_view.sql\", \"original_file_path\": \"macros/materializations/models/view/create_or_replace_view.sql\", \"unique_id\": \"macro.dbt.create_or_replace_view\", \"macro_sql\": \"{% macro create_or_replace_view() %}\\n  {%- set identifier = model['alias'] -%}\\n\\n  {%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%}\\n  {%- set exists_as_view = (old_relation is not none and old_relation.is_view) -%}\\n\\n  {%- set target_relation = api.Relation.create(\\n      identifier=identifier, schema=schema, database=database,\\n      type='view') -%}\\n  {% set grant_config = config.get('grants') %}\\n\\n  {{ run_hooks(pre_hooks) }}\\n\\n  -- If there's a table with the same name and we weren't told to full refresh,\\n  -- that's an error. If we were told to full refresh, drop it. This behavior differs\\n  -- for Snowflake and BigQuery, so multiple dispatch is used.\\n  {%- if old_relation is not none and old_relation.is_table -%}\\n    {{ handle_existing_table(should_full_refresh(), old_relation) }}\\n  {%- endif -%}\\n\\n  -- build model\\n  {% call statement('main') -%}\\n    {{ get_create_view_as_sql(target_relation, sql) }}\\n  {%- endcall %}\\n\\n  {% set should_revoke = should_revoke(exists_as_view, full_refresh_mode=True) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {{ run_hooks(post_hooks) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.run_hooks\", \"macro.dbt.handle_existing_table\", \"macro.dbt.should_full_refresh\", \"macro.dbt.statement\", \"macro.dbt.get_create_view_as_sql\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2213418, \"supported_languages\": null}, \"macro.dbt.get_create_view_as_sql\": {\"name\": \"get_create_view_as_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/view/create_view_as.sql\", \"original_file_path\": \"macros/materializations/models/view/create_view_as.sql\", \"unique_id\": \"macro.dbt.get_create_view_as_sql\", \"macro_sql\": \"{% macro get_create_view_as_sql(relation, sql) -%}\\n  {{ adapter.dispatch('get_create_view_as_sql', 'dbt')(relation, sql) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_create_view_as_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.221772, \"supported_languages\": null}, \"macro.dbt.default__get_create_view_as_sql\": {\"name\": \"default__get_create_view_as_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/view/create_view_as.sql\", \"original_file_path\": \"macros/materializations/models/view/create_view_as.sql\", \"unique_id\": \"macro.dbt.default__get_create_view_as_sql\", \"macro_sql\": \"{% macro default__get_create_view_as_sql(relation, sql) -%}\\n  {{ return(create_view_as(relation, sql)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.create_view_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2219388, \"supported_languages\": null}, \"macro.dbt.create_view_as\": {\"name\": \"create_view_as\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/view/create_view_as.sql\", \"original_file_path\": \"macros/materializations/models/view/create_view_as.sql\", \"unique_id\": \"macro.dbt.create_view_as\", \"macro_sql\": \"{% macro create_view_as(relation, sql) -%}\\n  {{ adapter.dispatch('create_view_as', 'dbt')(relation, sql) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__create_view_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.222131, \"supported_languages\": null}, \"macro.dbt.default__create_view_as\": {\"name\": \"default__create_view_as\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/view/create_view_as.sql\", \"original_file_path\": \"macros/materializations/models/view/create_view_as.sql\", \"unique_id\": \"macro.dbt.default__create_view_as\", \"macro_sql\": \"{% macro default__create_view_as(relation, sql) -%}\\n  {%- set sql_header = config.get('sql_header', none) -%}\\n\\n  {{ sql_header if sql_header is not none }}\\n  create view {{ relation }}\\n    {% set contract_config = config.get('contract') %}\\n    {% if contract_config.enforced %}\\n      {{ get_assert_columns_equivalent(sql) }}\\n    {%- endif %}\\n  as (\\n    {{ sql }}\\n  );\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_assert_columns_equivalent\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.222568, \"supported_languages\": null}, \"macro.dbt.materialization_seed_default\": {\"name\": \"materialization_seed_default\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/seed.sql\", \"original_file_path\": \"macros/materializations/seeds/seed.sql\", \"unique_id\": \"macro.dbt.materialization_seed_default\", \"macro_sql\": \"{% materialization seed, default %}\\n\\n  {%- set identifier = model['alias'] -%}\\n  {%- set full_refresh_mode = (should_full_refresh()) -%}\\n\\n  {%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%}\\n\\n  {%- set exists_as_table = (old_relation is not none and old_relation.is_table) -%}\\n  {%- set exists_as_view = (old_relation is not none and old_relation.is_view) -%}\\n\\n  {%- set grant_config = config.get('grants') -%}\\n  {%- set agate_table = load_agate_table() -%}\\n  -- grab current tables grants config for comparison later on\\n\\n  {%- do store_result('agate_table', response='OK', agate_table=agate_table) -%}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  -- build model\\n  {% set create_table_sql = \\\"\\\" %}\\n  {% if exists_as_view %}\\n    {{ exceptions.raise_compiler_error(\\\"Cannot seed to '{}', it is a view\\\".format(old_relation)) }}\\n  {% elif exists_as_table %}\\n    {% set create_table_sql = reset_csv_table(model, full_refresh_mode, old_relation, agate_table) %}\\n  {% else %}\\n    {% set create_table_sql = create_csv_table(model, agate_table) %}\\n  {% endif %}\\n\\n  {% set code = 'CREATE' if full_refresh_mode else 'INSERT' %}\\n  {% set rows_affected = (agate_table.rows | length) %}\\n  {% set sql = load_csv_rows(model, agate_table) %}\\n\\n  {% call noop_statement('main', code ~ ' ' ~ rows_affected, code, rows_affected) %}\\n    {{ get_csv_sql(create_table_sql, sql) }};\\n  {% endcall %}\\n\\n  {% set target_relation = this.incorporate(type='table') %}\\n\\n  {% set should_revoke = should_revoke(old_relation, full_refresh_mode) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {% if full_refresh_mode or not exists_as_table %}\\n    {% do create_indexes(target_relation) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  -- `COMMIT` happens here\\n  {{ adapter.commit() }}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{% endmaterialization %}\", \"depends_on\": {\"macros\": [\"macro.dbt.should_full_refresh\", \"macro.dbt.run_hooks\", \"macro.dbt.reset_csv_table\", \"macro.dbt.create_csv_table\", \"macro.dbt.load_csv_rows\", \"macro.dbt.noop_statement\", \"macro.dbt.get_csv_sql\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\", \"macro.dbt.persist_docs\", \"macro.dbt.create_indexes\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.225961, \"supported_languages\": [\"sql\"]}, \"macro.dbt.create_csv_table\": {\"name\": \"create_csv_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.create_csv_table\", \"macro_sql\": \"{% macro create_csv_table(model, agate_table) -%}\\n  {{ adapter.dispatch('create_csv_table', 'dbt')(model, agate_table) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__create_csv_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.231348, \"supported_languages\": null}, \"macro.dbt.default__create_csv_table\": {\"name\": \"default__create_csv_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.default__create_csv_table\", \"macro_sql\": \"{% macro default__create_csv_table(model, agate_table) %}\\n  {%- set column_override = model['config'].get('column_types', {}) -%}\\n  {%- set quote_seed_column = model['config'].get('quote_columns', None) -%}\\n\\n  {% set sql %}\\n    create table {{ this.render() }} (\\n        {%- for col_name in agate_table.column_names -%}\\n            {%- set inferred_type = adapter.convert_type(agate_table, loop.index0) -%}\\n            {%- set type = column_override.get(col_name, inferred_type) -%}\\n            {%- set column_name = (col_name | string) -%}\\n            {{ adapter.quote_seed_column(column_name, quote_seed_column) }} {{ type }} {%- if not loop.last -%}, {%- endif -%}\\n        {%- endfor -%}\\n    )\\n  {% endset %}\\n\\n  {% call statement('_') -%}\\n    {{ sql }}\\n  {%- endcall %}\\n\\n  {{ return(sql) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.232269, \"supported_languages\": null}, \"macro.dbt.reset_csv_table\": {\"name\": \"reset_csv_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.reset_csv_table\", \"macro_sql\": \"{% macro reset_csv_table(model, full_refresh, old_relation, agate_table) -%}\\n  {{ adapter.dispatch('reset_csv_table', 'dbt')(model, full_refresh, old_relation, agate_table) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__reset_csv_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.232512, \"supported_languages\": null}, \"macro.dbt.default__reset_csv_table\": {\"name\": \"default__reset_csv_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.default__reset_csv_table\", \"macro_sql\": \"{% macro default__reset_csv_table(model, full_refresh, old_relation, agate_table) %}\\n    {% set sql = \\\"\\\" %}\\n    {% if full_refresh %}\\n        {{ adapter.drop_relation(old_relation) }}\\n        {% set sql = create_csv_table(model, agate_table) %}\\n    {% else %}\\n        {{ adapter.truncate_relation(old_relation) }}\\n        {% set sql = \\\"truncate table \\\" ~ old_relation %}\\n    {% endif %}\\n\\n    {{ return(sql) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.create_csv_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.233001, \"supported_languages\": null}, \"macro.dbt.get_csv_sql\": {\"name\": \"get_csv_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.get_csv_sql\", \"macro_sql\": \"{% macro get_csv_sql(create_or_truncate_sql, insert_sql) %}\\n    {{ adapter.dispatch('get_csv_sql', 'dbt')(create_or_truncate_sql, insert_sql) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_csv_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2331991, \"supported_languages\": null}, \"macro.dbt.default__get_csv_sql\": {\"name\": \"default__get_csv_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.default__get_csv_sql\", \"macro_sql\": \"{% macro default__get_csv_sql(create_or_truncate_sql, insert_sql) %}\\n    {{ create_or_truncate_sql }};\\n    -- dbt seed --\\n    {{ insert_sql }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.233336, \"supported_languages\": null}, \"macro.dbt.get_binding_char\": {\"name\": \"get_binding_char\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.get_binding_char\", \"macro_sql\": \"{% macro get_binding_char() -%}\\n  {{ adapter.dispatch('get_binding_char', 'dbt')() }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_binding_char\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.233479, \"supported_languages\": null}, \"macro.dbt.default__get_binding_char\": {\"name\": \"default__get_binding_char\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.default__get_binding_char\", \"macro_sql\": \"{% macro default__get_binding_char() %}\\n  {{ return('%s') }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.233599, \"supported_languages\": null}, \"macro.dbt.get_batch_size\": {\"name\": \"get_batch_size\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.get_batch_size\", \"macro_sql\": \"{% macro get_batch_size() -%}\\n  {{ return(adapter.dispatch('get_batch_size', 'dbt')()) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_batch_size\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.233762, \"supported_languages\": null}, \"macro.dbt.default__get_batch_size\": {\"name\": \"default__get_batch_size\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.default__get_batch_size\", \"macro_sql\": \"{% macro default__get_batch_size() %}\\n  {{ return(10000) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.233883, \"supported_languages\": null}, \"macro.dbt.get_seed_column_quoted_csv\": {\"name\": \"get_seed_column_quoted_csv\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.get_seed_column_quoted_csv\", \"macro_sql\": \"{% macro get_seed_column_quoted_csv(model, column_names) %}\\n  {%- set quote_seed_column = model['config'].get('quote_columns', None) -%}\\n    {% set quoted = [] %}\\n    {% for col in column_names -%}\\n        {%- do quoted.append(adapter.quote_seed_column(col, quote_seed_column)) -%}\\n    {%- endfor %}\\n\\n    {%- set dest_cols_csv = quoted | join(', ') -%}\\n    {{ return(dest_cols_csv) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2343712, \"supported_languages\": null}, \"macro.dbt.load_csv_rows\": {\"name\": \"load_csv_rows\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.load_csv_rows\", \"macro_sql\": \"{% macro load_csv_rows(model, agate_table) -%}\\n  {{ adapter.dispatch('load_csv_rows', 'dbt')(model, agate_table) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__load_csv_rows\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2345622, \"supported_languages\": null}, \"macro.dbt.default__load_csv_rows\": {\"name\": \"default__load_csv_rows\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.default__load_csv_rows\", \"macro_sql\": \"{% macro default__load_csv_rows(model, agate_table) %}\\n\\n  {% set batch_size = get_batch_size() %}\\n\\n  {% set cols_sql = get_seed_column_quoted_csv(model, agate_table.column_names) %}\\n  {% set bindings = [] %}\\n\\n  {% set statements = [] %}\\n\\n  {% for chunk in agate_table.rows | batch(batch_size) %}\\n      {% set bindings = [] %}\\n\\n      {% for row in chunk %}\\n          {% do bindings.extend(row) %}\\n      {% endfor %}\\n\\n      {% set sql %}\\n          insert into {{ this.render() }} ({{ cols_sql }}) values\\n          {% for row in chunk -%}\\n              ({%- for column in agate_table.column_names -%}\\n                  {{ get_binding_char() }}\\n                  {%- if not loop.last%},{%- endif %}\\n              {%- endfor -%})\\n              {%- if not loop.last%},{%- endif %}\\n          {%- endfor %}\\n      {% endset %}\\n\\n      {% do adapter.add_query(sql, bindings=bindings, abridge_sql_log=True) %}\\n\\n      {% if loop.index0 == 0 %}\\n          {% do statements.append(sql) %}\\n      {% endif %}\\n  {% endfor %}\\n\\n  {# Return SQL so we can render it out into the compiled files #}\\n  {{ return(statements[0]) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_batch_size\", \"macro.dbt.get_seed_column_quoted_csv\", \"macro.dbt.get_binding_char\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.236012, \"supported_languages\": null}, \"macro.dbt.generate_alias_name\": {\"name\": \"generate_alias_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/get_custom_name/get_custom_alias.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_alias.sql\", \"unique_id\": \"macro.dbt.generate_alias_name\", \"macro_sql\": \"{% macro generate_alias_name(custom_alias_name=none, node=none) -%}\\n    {% do return(adapter.dispatch('generate_alias_name', 'dbt')(custom_alias_name, node)) %}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__generate_alias_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2364511, \"supported_languages\": null}, \"macro.dbt.default__generate_alias_name\": {\"name\": \"default__generate_alias_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/get_custom_name/get_custom_alias.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_alias.sql\", \"unique_id\": \"macro.dbt.default__generate_alias_name\", \"macro_sql\": \"{% macro default__generate_alias_name(custom_alias_name=none, node=none) -%}\\n\\n    {%- if custom_alias_name -%}\\n\\n        {{ custom_alias_name | trim }}\\n\\n    {%- elif node.version -%}\\n\\n        {{ return(node.name ~ \\\"_v\\\" ~ (node.version | replace(\\\".\\\", \\\"_\\\"))) }}\\n\\n    {%- else -%}\\n\\n        {{ node.name }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.236854, \"supported_languages\": null}, \"macro.dbt.generate_schema_name\": {\"name\": \"generate_schema_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/get_custom_name/get_custom_schema.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_schema.sql\", \"unique_id\": \"macro.dbt.generate_schema_name\", \"macro_sql\": \"{% macro generate_schema_name(custom_schema_name=none, node=none) -%}\\n    {{ return(adapter.dispatch('generate_schema_name', 'dbt')(custom_schema_name, node)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__generate_schema_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.237386, \"supported_languages\": null}, \"macro.dbt.default__generate_schema_name\": {\"name\": \"default__generate_schema_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/get_custom_name/get_custom_schema.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_schema.sql\", \"unique_id\": \"macro.dbt.default__generate_schema_name\", \"macro_sql\": \"{% macro default__generate_schema_name(custom_schema_name, node) -%}\\n\\n    {%- set default_schema = target.schema -%}\\n    {%- if custom_schema_name is none -%}\\n\\n        {{ default_schema }}\\n\\n    {%- else -%}\\n\\n        {{ default_schema }}_{{ custom_schema_name | trim }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.237652, \"supported_languages\": null}, \"macro.dbt.generate_schema_name_for_env\": {\"name\": \"generate_schema_name_for_env\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/get_custom_name/get_custom_schema.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_schema.sql\", \"unique_id\": \"macro.dbt.generate_schema_name_for_env\", \"macro_sql\": \"{% macro generate_schema_name_for_env(custom_schema_name, node) -%}\\n\\n    {%- set default_schema = target.schema -%}\\n    {%- if target.name == 'prod' and custom_schema_name is not none -%}\\n\\n        {{ custom_schema_name | trim }}\\n\\n    {%- else -%}\\n\\n        {{ default_schema }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.237949, \"supported_languages\": null}, \"macro.dbt.generate_database_name\": {\"name\": \"generate_database_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/get_custom_name/get_custom_database.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_database.sql\", \"unique_id\": \"macro.dbt.generate_database_name\", \"macro_sql\": \"{% macro generate_database_name(custom_database_name=none, node=none) -%}\\n    {% do return(adapter.dispatch('generate_database_name', 'dbt')(custom_database_name, node)) %}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__generate_database_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.238351, \"supported_languages\": null}, \"macro.dbt.default__generate_database_name\": {\"name\": \"default__generate_database_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/get_custom_name/get_custom_database.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_database.sql\", \"unique_id\": \"macro.dbt.default__generate_database_name\", \"macro_sql\": \"{% macro default__generate_database_name(custom_database_name=none, node=none) -%}\\n    {%- set default_database = target.database -%}\\n    {%- if custom_database_name is none -%}\\n\\n        {{ default_database }}\\n\\n    {%- else -%}\\n\\n        {{ custom_database_name }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.238611, \"supported_languages\": null}, \"macro.dbt.default__test_relationships\": {\"name\": \"default__test_relationships\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/generic_test_sql/relationships.sql\", \"original_file_path\": \"macros/generic_test_sql/relationships.sql\", \"unique_id\": \"macro.dbt.default__test_relationships\", \"macro_sql\": \"{% macro default__test_relationships(model, column_name, to, field) %}\\n\\nwith child as (\\n    select {{ column_name }} as from_field\\n    from {{ model }}\\n    where {{ column_name }} is not null\\n),\\n\\nparent as (\\n    select {{ field }} as to_field\\n    from {{ to }}\\n)\\n\\nselect\\n    from_field\\n\\nfrom child\\nleft join parent\\n    on child.from_field = parent.to_field\\n\\nwhere parent.to_field is null\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.238965, \"supported_languages\": null}, \"macro.dbt.default__test_not_null\": {\"name\": \"default__test_not_null\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/generic_test_sql/not_null.sql\", \"original_file_path\": \"macros/generic_test_sql/not_null.sql\", \"unique_id\": \"macro.dbt.default__test_not_null\", \"macro_sql\": \"{% macro default__test_not_null(model, column_name) %}\\n\\n{% set column_list = '*' if should_store_failures() else column_name %}\\n\\nselect {{ column_list }}\\nfrom {{ model }}\\nwhere {{ column_name }} is null\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.should_store_failures\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2392662, \"supported_languages\": null}, \"macro.dbt.default__test_unique\": {\"name\": \"default__test_unique\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/generic_test_sql/unique.sql\", \"original_file_path\": \"macros/generic_test_sql/unique.sql\", \"unique_id\": \"macro.dbt.default__test_unique\", \"macro_sql\": \"{% macro default__test_unique(model, column_name) %}\\n\\nselect\\n    {{ column_name }} as unique_field,\\n    count(*) as n_records\\n\\nfrom {{ model }}\\nwhere {{ column_name }} is not null\\ngroup by {{ column_name }}\\nhaving count(*) > 1\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.239514, \"supported_languages\": null}, \"macro.dbt.default__test_accepted_values\": {\"name\": \"default__test_accepted_values\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/generic_test_sql/accepted_values.sql\", \"original_file_path\": \"macros/generic_test_sql/accepted_values.sql\", \"unique_id\": \"macro.dbt.default__test_accepted_values\", \"macro_sql\": \"{% macro default__test_accepted_values(model, column_name, values, quote=True) %}\\n\\nwith all_values as (\\n\\n    select\\n        {{ column_name }} as value_field,\\n        count(*) as n_records\\n\\n    from {{ model }}\\n    group by {{ column_name }}\\n\\n)\\n\\nselect *\\nfrom all_values\\nwhere value_field not in (\\n    {% for value in values -%}\\n        {% if quote -%}\\n        '{{ value }}'\\n        {%- else -%}\\n        {{ value }}\\n        {%- endif -%}\\n        {%- if not loop.last -%},{%- endif %}\\n    {%- endfor %}\\n)\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2400918, \"supported_languages\": null}, \"macro.dbt.statement\": {\"name\": \"statement\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/etc/statement.sql\", \"original_file_path\": \"macros/etc/statement.sql\", \"unique_id\": \"macro.dbt.statement\", \"macro_sql\": \"\\n{%- macro statement(name=None, fetch_result=False, auto_begin=True, language='sql') -%}\\n  {%- if execute: -%}\\n    {%- set compiled_code = caller() -%}\\n\\n    {%- if name == 'main' -%}\\n      {{ log('Writing runtime {} for node \\\"{}\\\"'.format(language, model['unique_id'])) }}\\n      {{ write(compiled_code) }}\\n    {%- endif -%}\\n    {%- if language == 'sql'-%}\\n      {%- set res, table = adapter.execute(compiled_code, auto_begin=auto_begin, fetch=fetch_result) -%}\\n    {%- elif language == 'python' -%}\\n      {%- set res = submit_python_job(model, compiled_code) -%}\\n      {#-- TODO: What should table be for python models? --#}\\n      {%- set table = None -%}\\n    {%- else -%}\\n      {% do exceptions.raise_compiler_error(\\\"statement macro didn't get supported language\\\") %}\\n    {%- endif -%}\\n\\n    {%- if name is not none -%}\\n      {{ store_result(name, response=res, agate_table=table) }}\\n    {%- endif -%}\\n\\n  {%- endif -%}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.241607, \"supported_languages\": null}, \"macro.dbt.noop_statement\": {\"name\": \"noop_statement\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/etc/statement.sql\", \"original_file_path\": \"macros/etc/statement.sql\", \"unique_id\": \"macro.dbt.noop_statement\", \"macro_sql\": \"{% macro noop_statement(name=None, message=None, code=None, rows_affected=None, res=None) -%}\\n  {%- set sql = caller() -%}\\n\\n  {%- if name == 'main' -%}\\n    {{ log('Writing runtime SQL for node \\\"{}\\\"'.format(model['unique_id'])) }}\\n    {{ write(sql) }}\\n  {%- endif -%}\\n\\n  {%- if name is not none -%}\\n    {{ store_raw_result(name, message=message, code=code, rows_affected=rows_affected, agate_table=res) }}\\n  {%- endif -%}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.242203, \"supported_languages\": null}, \"macro.dbt.run_query\": {\"name\": \"run_query\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/etc/statement.sql\", \"original_file_path\": \"macros/etc/statement.sql\", \"unique_id\": \"macro.dbt.run_query\", \"macro_sql\": \"{% macro run_query(sql) %}\\n  {% call statement(\\\"run_query_statement\\\", fetch_result=true, auto_begin=false) %}\\n    {{ sql }}\\n  {% endcall %}\\n\\n  {% do return(load_result(\\\"run_query_statement\\\").table) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2425091, \"supported_languages\": null}, \"macro.dbt.convert_datetime\": {\"name\": \"convert_datetime\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"unique_id\": \"macro.dbt.convert_datetime\", \"macro_sql\": \"{% macro convert_datetime(date_str, date_fmt) %}\\n\\n  {% set error_msg -%}\\n      The provided partition date '{{ date_str }}' does not match the expected format '{{ date_fmt }}'\\n  {%- endset %}\\n\\n  {% set res = try_or_compiler_error(error_msg, modules.datetime.datetime.strptime, date_str.strip(), date_fmt) %}\\n  {{ return(res) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2444658, \"supported_languages\": null}, \"macro.dbt.dates_in_range\": {\"name\": \"dates_in_range\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"unique_id\": \"macro.dbt.dates_in_range\", \"macro_sql\": \"{% macro dates_in_range(start_date_str, end_date_str=none, in_fmt=\\\"%Y%m%d\\\", out_fmt=\\\"%Y%m%d\\\") %}\\n    {% set end_date_str = start_date_str if end_date_str is none else end_date_str %}\\n\\n    {% set start_date = convert_datetime(start_date_str, in_fmt) %}\\n    {% set end_date = convert_datetime(end_date_str, in_fmt) %}\\n\\n    {% set day_count = (end_date - start_date).days %}\\n    {% if day_count < 0 %}\\n        {% set msg -%}\\n            Partiton start date is after the end date ({{ start_date }}, {{ end_date }})\\n        {%- endset %}\\n\\n        {{ exceptions.raise_compiler_error(msg, model) }}\\n    {% endif %}\\n\\n    {% set date_list = [] %}\\n    {% for i in range(0, day_count + 1) %}\\n        {% set the_date = (modules.datetime.timedelta(days=i) + start_date) %}\\n        {% if not out_fmt %}\\n            {% set _ = date_list.append(the_date) %}\\n        {% else %}\\n            {% set _ = date_list.append(the_date.strftime(out_fmt)) %}\\n        {% endif %}\\n    {% endfor %}\\n\\n    {{ return(date_list) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.convert_datetime\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.245748, \"supported_languages\": null}, \"macro.dbt.partition_range\": {\"name\": \"partition_range\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"unique_id\": \"macro.dbt.partition_range\", \"macro_sql\": \"{% macro partition_range(raw_partition_date, date_fmt='%Y%m%d') %}\\n    {% set partition_range = (raw_partition_date | string).split(\\\",\\\") %}\\n\\n    {% if (partition_range | length) == 1 %}\\n      {% set start_date = partition_range[0] %}\\n      {% set end_date = none %}\\n    {% elif (partition_range | length) == 2 %}\\n      {% set start_date = partition_range[0] %}\\n      {% set end_date = partition_range[1] %}\\n    {% else %}\\n      {{ exceptions.raise_compiler_error(\\\"Invalid partition time. Expected format: {Start Date}[,{End Date}]. Got: \\\" ~ raw_partition_date) }}\\n    {% endif %}\\n\\n    {{ return(dates_in_range(start_date, end_date, in_fmt=date_fmt)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.dates_in_range\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.246516, \"supported_languages\": null}, \"macro.dbt.py_current_timestring\": {\"name\": \"py_current_timestring\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"unique_id\": \"macro.dbt.py_current_timestring\", \"macro_sql\": \"{% macro py_current_timestring() %}\\n    {% set dt = modules.datetime.datetime.now() %}\\n    {% do return(dt.strftime(\\\"%Y%m%d%H%M%S%f\\\")) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2467651, \"supported_languages\": null}, \"macro.dbt.except\": {\"name\": \"except\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/except.sql\", \"original_file_path\": \"macros/utils/except.sql\", \"unique_id\": \"macro.dbt.except\", \"macro_sql\": \"{% macro except() %}\\n  {{ return(adapter.dispatch('except', 'dbt')()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__except\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2469969, \"supported_languages\": null}, \"macro.dbt.default__except\": {\"name\": \"default__except\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/except.sql\", \"original_file_path\": \"macros/utils/except.sql\", \"unique_id\": \"macro.dbt.default__except\", \"macro_sql\": \"{% macro default__except() %}\\n\\n    except\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.247075, \"supported_languages\": null}, \"macro.dbt.replace\": {\"name\": \"replace\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/replace.sql\", \"original_file_path\": \"macros/utils/replace.sql\", \"unique_id\": \"macro.dbt.replace\", \"macro_sql\": \"{% macro replace(field, old_chars, new_chars) -%}\\n    {{ return(adapter.dispatch('replace', 'dbt') (field, old_chars, new_chars)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__replace\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2474089, \"supported_languages\": null}, \"macro.dbt.default__replace\": {\"name\": \"default__replace\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/replace.sql\", \"original_file_path\": \"macros/utils/replace.sql\", \"unique_id\": \"macro.dbt.default__replace\", \"macro_sql\": \"{% macro default__replace(field, old_chars, new_chars) %}\\n\\n    replace(\\n        {{ field }},\\n        {{ old_chars }},\\n        {{ new_chars }}\\n    )\\n\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2475772, \"supported_languages\": null}, \"macro.dbt.concat\": {\"name\": \"concat\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/concat.sql\", \"original_file_path\": \"macros/utils/concat.sql\", \"unique_id\": \"macro.dbt.concat\", \"macro_sql\": \"{% macro concat(fields) -%}\\n  {{ return(adapter.dispatch('concat', 'dbt')(fields)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__concat\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.247827, \"supported_languages\": null}, \"macro.dbt.default__concat\": {\"name\": \"default__concat\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/concat.sql\", \"original_file_path\": \"macros/utils/concat.sql\", \"unique_id\": \"macro.dbt.default__concat\", \"macro_sql\": \"{% macro default__concat(fields) -%}\\n    {{ fields|join(' || ') }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.247957, \"supported_languages\": null}, \"macro.dbt.length\": {\"name\": \"length\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/length.sql\", \"original_file_path\": \"macros/utils/length.sql\", \"unique_id\": \"macro.dbt.length\", \"macro_sql\": \"{% macro length(expression) -%}\\n    {{ return(adapter.dispatch('length', 'dbt') (expression)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__length\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.248211, \"supported_languages\": null}, \"macro.dbt.default__length\": {\"name\": \"default__length\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/length.sql\", \"original_file_path\": \"macros/utils/length.sql\", \"unique_id\": \"macro.dbt.default__length\", \"macro_sql\": \"{% macro default__length(expression) %}\\n\\n    length(\\n        {{ expression }}\\n    )\\n\\n{%- endmacro -%}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.248318, \"supported_languages\": null}, \"macro.dbt.dateadd\": {\"name\": \"dateadd\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/dateadd.sql\", \"original_file_path\": \"macros/utils/dateadd.sql\", \"unique_id\": \"macro.dbt.dateadd\", \"macro_sql\": \"{% macro dateadd(datepart, interval, from_date_or_timestamp) %}\\n  {{ return(adapter.dispatch('dateadd', 'dbt')(datepart, interval, from_date_or_timestamp)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__dateadd\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2486641, \"supported_languages\": null}, \"macro.dbt.default__dateadd\": {\"name\": \"default__dateadd\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/dateadd.sql\", \"original_file_path\": \"macros/utils/dateadd.sql\", \"unique_id\": \"macro.dbt.default__dateadd\", \"macro_sql\": \"{% macro default__dateadd(datepart, interval, from_date_or_timestamp) %}\\n\\n    dateadd(\\n        {{ datepart }},\\n        {{ interval }},\\n        {{ from_date_or_timestamp }}\\n        )\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.248833, \"supported_languages\": null}, \"macro.dbt.intersect\": {\"name\": \"intersect\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/intersect.sql\", \"original_file_path\": \"macros/utils/intersect.sql\", \"unique_id\": \"macro.dbt.intersect\", \"macro_sql\": \"{% macro intersect() %}\\n  {{ return(adapter.dispatch('intersect', 'dbt')()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__intersect\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2490602, \"supported_languages\": null}, \"macro.dbt.default__intersect\": {\"name\": \"default__intersect\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/intersect.sql\", \"original_file_path\": \"macros/utils/intersect.sql\", \"unique_id\": \"macro.dbt.default__intersect\", \"macro_sql\": \"{% macro default__intersect() %}\\n\\n    intersect\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2491379, \"supported_languages\": null}, \"macro.dbt.escape_single_quotes\": {\"name\": \"escape_single_quotes\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/escape_single_quotes.sql\", \"original_file_path\": \"macros/utils/escape_single_quotes.sql\", \"unique_id\": \"macro.dbt.escape_single_quotes\", \"macro_sql\": \"{% macro escape_single_quotes(expression) %}\\n      {{ return(adapter.dispatch('escape_single_quotes', 'dbt') (expression)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__escape_single_quotes\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.249404, \"supported_languages\": null}, \"macro.dbt.default__escape_single_quotes\": {\"name\": \"default__escape_single_quotes\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/escape_single_quotes.sql\", \"original_file_path\": \"macros/utils/escape_single_quotes.sql\", \"unique_id\": \"macro.dbt.default__escape_single_quotes\", \"macro_sql\": \"{% macro default__escape_single_quotes(expression) -%}\\n{{ expression | replace(\\\"'\\\",\\\"''\\\") }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2495492, \"supported_languages\": null}, \"macro.dbt.right\": {\"name\": \"right\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/right.sql\", \"original_file_path\": \"macros/utils/right.sql\", \"unique_id\": \"macro.dbt.right\", \"macro_sql\": \"{% macro right(string_text, length_expression) -%}\\n    {{ return(adapter.dispatch('right', 'dbt') (string_text, length_expression)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__right\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.249847, \"supported_languages\": null}, \"macro.dbt.default__right\": {\"name\": \"default__right\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/right.sql\", \"original_file_path\": \"macros/utils/right.sql\", \"unique_id\": \"macro.dbt.default__right\", \"macro_sql\": \"{% macro default__right(string_text, length_expression) %}\\n\\n    right(\\n        {{ string_text }},\\n        {{ length_expression }}\\n    )\\n\\n{%- endmacro -%}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.249984, \"supported_languages\": null}, \"macro.dbt.listagg\": {\"name\": \"listagg\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/listagg.sql\", \"original_file_path\": \"macros/utils/listagg.sql\", \"unique_id\": \"macro.dbt.listagg\", \"macro_sql\": \"{% macro listagg(measure, delimiter_text=\\\"','\\\", order_by_clause=none, limit_num=none) -%}\\n    {{ return(adapter.dispatch('listagg', 'dbt') (measure, delimiter_text, order_by_clause, limit_num)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__listagg\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2506409, \"supported_languages\": null}, \"macro.dbt.default__listagg\": {\"name\": \"default__listagg\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/listagg.sql\", \"original_file_path\": \"macros/utils/listagg.sql\", \"unique_id\": \"macro.dbt.default__listagg\", \"macro_sql\": \"{% macro default__listagg(measure, delimiter_text, order_by_clause, limit_num) -%}\\n\\n    {% if limit_num -%}\\n    array_to_string(\\n        array_slice(\\n            array_agg(\\n                {{ measure }}\\n            ){% if order_by_clause -%}\\n            within group ({{ order_by_clause }})\\n            {%- endif %}\\n            ,0\\n            ,{{ limit_num }}\\n        ),\\n        {{ delimiter_text }}\\n        )\\n    {%- else %}\\n    listagg(\\n        {{ measure }},\\n        {{ delimiter_text }}\\n        )\\n        {% if order_by_clause -%}\\n        within group ({{ order_by_clause }})\\n        {%- endif %}\\n    {%- endif %}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.251061, \"supported_languages\": null}, \"macro.dbt.datediff\": {\"name\": \"datediff\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/datediff.sql\", \"original_file_path\": \"macros/utils/datediff.sql\", \"unique_id\": \"macro.dbt.datediff\", \"macro_sql\": \"{% macro datediff(first_date, second_date, datepart) %}\\n  {{ return(adapter.dispatch('datediff', 'dbt')(first_date, second_date, datepart)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__datediff\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.251404, \"supported_languages\": null}, \"macro.dbt.default__datediff\": {\"name\": \"default__datediff\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/datediff.sql\", \"original_file_path\": \"macros/utils/datediff.sql\", \"unique_id\": \"macro.dbt.default__datediff\", \"macro_sql\": \"{% macro default__datediff(first_date, second_date, datepart) -%}\\n\\n    datediff(\\n        {{ datepart }},\\n        {{ first_date }},\\n        {{ second_date }}\\n        )\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.251571, \"supported_languages\": null}, \"macro.dbt.safe_cast\": {\"name\": \"safe_cast\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/safe_cast.sql\", \"original_file_path\": \"macros/utils/safe_cast.sql\", \"unique_id\": \"macro.dbt.safe_cast\", \"macro_sql\": \"{% macro safe_cast(field, type) %}\\n  {{ return(adapter.dispatch('safe_cast', 'dbt') (field, type)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__safe_cast\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.25186, \"supported_languages\": null}, \"macro.dbt.default__safe_cast\": {\"name\": \"default__safe_cast\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/safe_cast.sql\", \"original_file_path\": \"macros/utils/safe_cast.sql\", \"unique_id\": \"macro.dbt.default__safe_cast\", \"macro_sql\": \"{% macro default__safe_cast(field, type) %}\\n    {# most databases don't support this function yet\\n    so we just need to use cast #}\\n    cast({{field}} as {{type}})\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.252075, \"supported_languages\": null}, \"macro.dbt.hash\": {\"name\": \"hash\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/hash.sql\", \"original_file_path\": \"macros/utils/hash.sql\", \"unique_id\": \"macro.dbt.hash\", \"macro_sql\": \"{% macro hash(field) -%}\\n  {{ return(adapter.dispatch('hash', 'dbt') (field)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__hash\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.252336, \"supported_languages\": null}, \"macro.dbt.default__hash\": {\"name\": \"default__hash\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/hash.sql\", \"original_file_path\": \"macros/utils/hash.sql\", \"unique_id\": \"macro.dbt.default__hash\", \"macro_sql\": \"{% macro default__hash(field) -%}\\n    md5(cast({{ field }} as {{ api.Column.translate_type('string') }}))\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.252498, \"supported_languages\": null}, \"macro.dbt.cast_bool_to_text\": {\"name\": \"cast_bool_to_text\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/cast_bool_to_text.sql\", \"original_file_path\": \"macros/utils/cast_bool_to_text.sql\", \"unique_id\": \"macro.dbt.cast_bool_to_text\", \"macro_sql\": \"{% macro cast_bool_to_text(field) %}\\n  {{ adapter.dispatch('cast_bool_to_text', 'dbt') (field) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__cast_bool_to_text\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2527459, \"supported_languages\": null}, \"macro.dbt.default__cast_bool_to_text\": {\"name\": \"default__cast_bool_to_text\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/cast_bool_to_text.sql\", \"original_file_path\": \"macros/utils/cast_bool_to_text.sql\", \"unique_id\": \"macro.dbt.default__cast_bool_to_text\", \"macro_sql\": \"{% macro default__cast_bool_to_text(field) %}\\n    cast({{ field }} as {{ api.Column.translate_type('string') }})\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.252909, \"supported_languages\": null}, \"macro.dbt.any_value\": {\"name\": \"any_value\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/any_value.sql\", \"original_file_path\": \"macros/utils/any_value.sql\", \"unique_id\": \"macro.dbt.any_value\", \"macro_sql\": \"{% macro any_value(expression) -%}\\n    {{ return(adapter.dispatch('any_value', 'dbt') (expression)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__any_value\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.25316, \"supported_languages\": null}, \"macro.dbt.default__any_value\": {\"name\": \"default__any_value\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/any_value.sql\", \"original_file_path\": \"macros/utils/any_value.sql\", \"unique_id\": \"macro.dbt.default__any_value\", \"macro_sql\": \"{% macro default__any_value(expression) -%}\\n\\n    any_value({{ expression }})\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.253269, \"supported_languages\": null}, \"macro.dbt.position\": {\"name\": \"position\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/position.sql\", \"original_file_path\": \"macros/utils/position.sql\", \"unique_id\": \"macro.dbt.position\", \"macro_sql\": \"{% macro position(substring_text, string_text) -%}\\n    {{ return(adapter.dispatch('position', 'dbt') (substring_text, string_text)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__position\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2535648, \"supported_languages\": null}, \"macro.dbt.default__position\": {\"name\": \"default__position\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/position.sql\", \"original_file_path\": \"macros/utils/position.sql\", \"unique_id\": \"macro.dbt.default__position\", \"macro_sql\": \"{% macro default__position(substring_text, string_text) %}\\n\\n    position(\\n        {{ substring_text }} in {{ string_text }}\\n    )\\n\\n{%- endmacro -%}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2537038, \"supported_languages\": null}, \"macro.dbt.string_literal\": {\"name\": \"string_literal\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/literal.sql\", \"original_file_path\": \"macros/utils/literal.sql\", \"unique_id\": \"macro.dbt.string_literal\", \"macro_sql\": \"{%- macro string_literal(value) -%}\\n  {{ return(adapter.dispatch('string_literal', 'dbt') (value)) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__string_literal\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.253951, \"supported_languages\": null}, \"macro.dbt.default__string_literal\": {\"name\": \"default__string_literal\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/literal.sql\", \"original_file_path\": \"macros/utils/literal.sql\", \"unique_id\": \"macro.dbt.default__string_literal\", \"macro_sql\": \"{% macro default__string_literal(value) -%}\\n    '{{ value }}'\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.254057, \"supported_languages\": null}, \"macro.dbt.type_string\": {\"name\": \"type_string\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.type_string\", \"macro_sql\": \"\\n\\n{%- macro type_string() -%}\\n  {{ return(adapter.dispatch('type_string', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__type_string\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.254996, \"supported_languages\": null}, \"macro.dbt.default__type_string\": {\"name\": \"default__type_string\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.default__type_string\", \"macro_sql\": \"{% macro default__type_string() %}\\n    {{ return(api.Column.translate_type(\\\"string\\\")) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2551548, \"supported_languages\": null}, \"macro.dbt.type_timestamp\": {\"name\": \"type_timestamp\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.type_timestamp\", \"macro_sql\": \"\\n\\n{%- macro type_timestamp() -%}\\n  {{ return(adapter.dispatch('type_timestamp', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__type_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2553222, \"supported_languages\": null}, \"macro.dbt.default__type_timestamp\": {\"name\": \"default__type_timestamp\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.default__type_timestamp\", \"macro_sql\": \"{% macro default__type_timestamp() %}\\n    {{ return(api.Column.translate_type(\\\"timestamp\\\")) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.255476, \"supported_languages\": null}, \"macro.dbt.type_float\": {\"name\": \"type_float\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.type_float\", \"macro_sql\": \"\\n\\n{%- macro type_float() -%}\\n  {{ return(adapter.dispatch('type_float', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__type_float\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.255645, \"supported_languages\": null}, \"macro.dbt.default__type_float\": {\"name\": \"default__type_float\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.default__type_float\", \"macro_sql\": \"{% macro default__type_float() %}\\n    {{ return(api.Column.translate_type(\\\"float\\\")) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2558029, \"supported_languages\": null}, \"macro.dbt.type_numeric\": {\"name\": \"type_numeric\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.type_numeric\", \"macro_sql\": \"\\n\\n{%- macro type_numeric() -%}\\n  {{ return(adapter.dispatch('type_numeric', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__type_numeric\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.255967, \"supported_languages\": null}, \"macro.dbt.default__type_numeric\": {\"name\": \"default__type_numeric\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.default__type_numeric\", \"macro_sql\": \"{% macro default__type_numeric() %}\\n    {{ return(api.Column.numeric_type(\\\"numeric\\\", 28, 6)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.256154, \"supported_languages\": null}, \"macro.dbt.type_bigint\": {\"name\": \"type_bigint\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.type_bigint\", \"macro_sql\": \"\\n\\n{%- macro type_bigint() -%}\\n  {{ return(adapter.dispatch('type_bigint', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__type_bigint\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.256317, \"supported_languages\": null}, \"macro.dbt.default__type_bigint\": {\"name\": \"default__type_bigint\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.default__type_bigint\", \"macro_sql\": \"{% macro default__type_bigint() %}\\n    {{ return(api.Column.translate_type(\\\"bigint\\\")) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.256474, \"supported_languages\": null}, \"macro.dbt.type_int\": {\"name\": \"type_int\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.type_int\", \"macro_sql\": \"\\n\\n{%- macro type_int() -%}\\n  {{ return(adapter.dispatch('type_int', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__type_int\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.256723, \"supported_languages\": null}, \"macro.dbt.default__type_int\": {\"name\": \"default__type_int\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.default__type_int\", \"macro_sql\": \"{%- macro default__type_int() -%}\\n  {{ return(api.Column.translate_type(\\\"integer\\\")) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2568839, \"supported_languages\": null}, \"macro.dbt.type_boolean\": {\"name\": \"type_boolean\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.type_boolean\", \"macro_sql\": \"\\n\\n{%- macro type_boolean() -%}\\n  {{ return(adapter.dispatch('type_boolean', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__type_boolean\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.257049, \"supported_languages\": null}, \"macro.dbt.default__type_boolean\": {\"name\": \"default__type_boolean\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.default__type_boolean\", \"macro_sql\": \"{%- macro default__type_boolean() -%}\\n  {{ return(api.Column.translate_type(\\\"boolean\\\")) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2572002, \"supported_languages\": null}, \"macro.dbt.array_concat\": {\"name\": \"array_concat\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/array_concat.sql\", \"original_file_path\": \"macros/utils/array_concat.sql\", \"unique_id\": \"macro.dbt.array_concat\", \"macro_sql\": \"{% macro array_concat(array_1, array_2) -%}\\n  {{ return(adapter.dispatch('array_concat', 'dbt')(array_1, array_2)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__array_concat\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2574809, \"supported_languages\": null}, \"macro.dbt.default__array_concat\": {\"name\": \"default__array_concat\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/array_concat.sql\", \"original_file_path\": \"macros/utils/array_concat.sql\", \"unique_id\": \"macro.dbt.default__array_concat\", \"macro_sql\": \"{% macro default__array_concat(array_1, array_2) -%}\\n    array_cat({{ array_1 }}, {{ array_2 }})\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.257617, \"supported_languages\": null}, \"macro.dbt.bool_or\": {\"name\": \"bool_or\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/bool_or.sql\", \"original_file_path\": \"macros/utils/bool_or.sql\", \"unique_id\": \"macro.dbt.bool_or\", \"macro_sql\": \"{% macro bool_or(expression) -%}\\n    {{ return(adapter.dispatch('bool_or', 'dbt') (expression)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__bool_or\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2578712, \"supported_languages\": null}, \"macro.dbt.default__bool_or\": {\"name\": \"default__bool_or\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/bool_or.sql\", \"original_file_path\": \"macros/utils/bool_or.sql\", \"unique_id\": \"macro.dbt.default__bool_or\", \"macro_sql\": \"{% macro default__bool_or(expression) -%}\\n\\n    bool_or({{ expression }})\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.257977, \"supported_languages\": null}, \"macro.dbt.last_day\": {\"name\": \"last_day\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/last_day.sql\", \"original_file_path\": \"macros/utils/last_day.sql\", \"unique_id\": \"macro.dbt.last_day\", \"macro_sql\": \"{% macro last_day(date, datepart) %}\\n  {{ return(adapter.dispatch('last_day', 'dbt') (date, datepart)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__last_day\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.258348, \"supported_languages\": null}, \"macro.dbt.default_last_day\": {\"name\": \"default_last_day\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/last_day.sql\", \"original_file_path\": \"macros/utils/last_day.sql\", \"unique_id\": \"macro.dbt.default_last_day\", \"macro_sql\": \"\\n\\n{%- macro default_last_day(date, datepart) -%}\\n    cast(\\n        {{dbt.dateadd('day', '-1',\\n        dbt.dateadd(datepart, '1', dbt.date_trunc(datepart, date))\\n        )}}\\n        as date)\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.dateadd\", \"macro.dbt.date_trunc\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.258624, \"supported_languages\": null}, \"macro.dbt.default__last_day\": {\"name\": \"default__last_day\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/last_day.sql\", \"original_file_path\": \"macros/utils/last_day.sql\", \"unique_id\": \"macro.dbt.default__last_day\", \"macro_sql\": \"{% macro default__last_day(date, datepart) -%}\\n    {{dbt.default_last_day(date, datepart)}}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default_last_day\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.258776, \"supported_languages\": null}, \"macro.dbt.split_part\": {\"name\": \"split_part\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/split_part.sql\", \"original_file_path\": \"macros/utils/split_part.sql\", \"unique_id\": \"macro.dbt.split_part\", \"macro_sql\": \"{% macro split_part(string_text, delimiter_text, part_number) %}\\n  {{ return(adapter.dispatch('split_part', 'dbt') (string_text, delimiter_text, part_number)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__split_part\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.259321, \"supported_languages\": null}, \"macro.dbt.default__split_part\": {\"name\": \"default__split_part\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/split_part.sql\", \"original_file_path\": \"macros/utils/split_part.sql\", \"unique_id\": \"macro.dbt.default__split_part\", \"macro_sql\": \"{% macro default__split_part(string_text, delimiter_text, part_number) %}\\n\\n    split_part(\\n        {{ string_text }},\\n        {{ delimiter_text }},\\n        {{ part_number }}\\n        )\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.259488, \"supported_languages\": null}, \"macro.dbt._split_part_negative\": {\"name\": \"_split_part_negative\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/split_part.sql\", \"original_file_path\": \"macros/utils/split_part.sql\", \"unique_id\": \"macro.dbt._split_part_negative\", \"macro_sql\": \"{% macro _split_part_negative(string_text, delimiter_text, part_number) %}\\n\\n    split_part(\\n        {{ string_text }},\\n        {{ delimiter_text }},\\n          length({{ string_text }})\\n          - length(\\n              replace({{ string_text }},  {{ delimiter_text }}, '')\\n          ) + 2 + {{ part_number }}\\n        )\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.259715, \"supported_languages\": null}, \"macro.dbt.date_trunc\": {\"name\": \"date_trunc\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/date_trunc.sql\", \"original_file_path\": \"macros/utils/date_trunc.sql\", \"unique_id\": \"macro.dbt.date_trunc\", \"macro_sql\": \"{% macro date_trunc(datepart, date) -%}\\n  {{ return(adapter.dispatch('date_trunc', 'dbt') (datepart, date)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__date_trunc\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.259997, \"supported_languages\": null}, \"macro.dbt.default__date_trunc\": {\"name\": \"default__date_trunc\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/date_trunc.sql\", \"original_file_path\": \"macros/utils/date_trunc.sql\", \"unique_id\": \"macro.dbt.default__date_trunc\", \"macro_sql\": \"{% macro default__date_trunc(datepart, date) -%}\\n    date_trunc('{{datepart}}', {{date}})\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.260129, \"supported_languages\": null}, \"macro.dbt.array_construct\": {\"name\": \"array_construct\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/array_construct.sql\", \"original_file_path\": \"macros/utils/array_construct.sql\", \"unique_id\": \"macro.dbt.array_construct\", \"macro_sql\": \"{% macro array_construct(inputs=[], data_type=api.Column.translate_type('integer')) -%}\\n  {{ return(adapter.dispatch('array_construct', 'dbt')(inputs, data_type)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__array_construct\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.26051, \"supported_languages\": null}, \"macro.dbt.default__array_construct\": {\"name\": \"default__array_construct\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/array_construct.sql\", \"original_file_path\": \"macros/utils/array_construct.sql\", \"unique_id\": \"macro.dbt.default__array_construct\", \"macro_sql\": \"{% macro default__array_construct(inputs, data_type) -%}\\n    {% if inputs|length > 0 %}\\n    array[ {{ inputs|join(' , ') }} ]\\n    {% else %}\\n    array[]::{{data_type}}[]\\n    {% endif %}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.260766, \"supported_languages\": null}, \"macro.dbt.array_append\": {\"name\": \"array_append\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/array_append.sql\", \"original_file_path\": \"macros/utils/array_append.sql\", \"unique_id\": \"macro.dbt.array_append\", \"macro_sql\": \"{% macro array_append(array, new_element) -%}\\n  {{ return(adapter.dispatch('array_append', 'dbt')(array, new_element)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__array_append\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2610502, \"supported_languages\": null}, \"macro.dbt.default__array_append\": {\"name\": \"default__array_append\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/array_append.sql\", \"original_file_path\": \"macros/utils/array_append.sql\", \"unique_id\": \"macro.dbt.default__array_append\", \"macro_sql\": \"{% macro default__array_append(array, new_element) -%}\\n    array_append({{ array }}, {{ new_element }})\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.261183, \"supported_languages\": null}, \"macro.dbt.create_schema\": {\"name\": \"create_schema\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/schema.sql\", \"original_file_path\": \"macros/adapters/schema.sql\", \"unique_id\": \"macro.dbt.create_schema\", \"macro_sql\": \"{% macro create_schema(relation) -%}\\n  {{ adapter.dispatch('create_schema', 'dbt')(relation) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__create_schema\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.261564, \"supported_languages\": null}, \"macro.dbt.default__create_schema\": {\"name\": \"default__create_schema\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/schema.sql\", \"original_file_path\": \"macros/adapters/schema.sql\", \"unique_id\": \"macro.dbt.default__create_schema\", \"macro_sql\": \"{% macro default__create_schema(relation) -%}\\n  {%- call statement('create_schema') -%}\\n    create schema if not exists {{ relation.without_identifier() }}\\n  {% endcall %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.261753, \"supported_languages\": null}, \"macro.dbt.drop_schema\": {\"name\": \"drop_schema\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/schema.sql\", \"original_file_path\": \"macros/adapters/schema.sql\", \"unique_id\": \"macro.dbt.drop_schema\", \"macro_sql\": \"{% macro drop_schema(relation) -%}\\n  {{ adapter.dispatch('drop_schema', 'dbt')(relation) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__drop_schema\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.261918, \"supported_languages\": null}, \"macro.dbt.default__drop_schema\": {\"name\": \"default__drop_schema\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/schema.sql\", \"original_file_path\": \"macros/adapters/schema.sql\", \"unique_id\": \"macro.dbt.default__drop_schema\", \"macro_sql\": \"{% macro default__drop_schema(relation) -%}\\n  {%- call statement('drop_schema') -%}\\n    drop schema if exists {{ relation.without_identifier() }} cascade\\n  {% endcall %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.262178, \"supported_languages\": null}, \"macro.dbt.current_timestamp\": {\"name\": \"current_timestamp\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"unique_id\": \"macro.dbt.current_timestamp\", \"macro_sql\": \"{%- macro current_timestamp() -%}\\n    {{ adapter.dispatch('current_timestamp', 'dbt')() }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2626739, \"supported_languages\": null}, \"macro.dbt.default__current_timestamp\": {\"name\": \"default__current_timestamp\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"unique_id\": \"macro.dbt.default__current_timestamp\", \"macro_sql\": \"{% macro default__current_timestamp() -%}\\n  {{ exceptions.raise_not_implemented(\\n    'current_timestamp macro not implemented for adapter ' + adapter.type()) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.262827, \"supported_languages\": null}, \"macro.dbt.snapshot_get_time\": {\"name\": \"snapshot_get_time\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"unique_id\": \"macro.dbt.snapshot_get_time\", \"macro_sql\": \"\\n\\n{%- macro snapshot_get_time() -%}\\n    {{ adapter.dispatch('snapshot_get_time', 'dbt')() }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__snapshot_get_time\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.262975, \"supported_languages\": null}, \"macro.dbt.default__snapshot_get_time\": {\"name\": \"default__snapshot_get_time\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"unique_id\": \"macro.dbt.default__snapshot_get_time\", \"macro_sql\": \"{% macro default__snapshot_get_time() %}\\n    {{ current_timestamp() }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.263083, \"supported_languages\": null}, \"macro.dbt.current_timestamp_backcompat\": {\"name\": \"current_timestamp_backcompat\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"unique_id\": \"macro.dbt.current_timestamp_backcompat\", \"macro_sql\": \"{% macro current_timestamp_backcompat() %}\\n    {{ return(adapter.dispatch('current_timestamp_backcompat', 'dbt')()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__current_timestamp_backcompat\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.263253, \"supported_languages\": null}, \"macro.dbt.default__current_timestamp_backcompat\": {\"name\": \"default__current_timestamp_backcompat\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"unique_id\": \"macro.dbt.default__current_timestamp_backcompat\", \"macro_sql\": \"{% macro default__current_timestamp_backcompat() %}\\n    current_timestamp::timestamp\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.26333, \"supported_languages\": null}, \"macro.dbt.current_timestamp_in_utc_backcompat\": {\"name\": \"current_timestamp_in_utc_backcompat\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"unique_id\": \"macro.dbt.current_timestamp_in_utc_backcompat\", \"macro_sql\": \"{% macro current_timestamp_in_utc_backcompat() %}\\n    {{ return(adapter.dispatch('current_timestamp_in_utc_backcompat', 'dbt')()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__current_timestamp_in_utc_backcompat\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2635038, \"supported_languages\": null}, \"macro.dbt.default__current_timestamp_in_utc_backcompat\": {\"name\": \"default__current_timestamp_in_utc_backcompat\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"unique_id\": \"macro.dbt.default__current_timestamp_in_utc_backcompat\", \"macro_sql\": \"{% macro default__current_timestamp_in_utc_backcompat() %}\\n    {{ return(adapter.dispatch('current_timestamp_backcompat', 'dbt')()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.current_timestamp_backcompat\", \"macro.dbt_postgres.postgres__current_timestamp_backcompat\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.263676, \"supported_languages\": null}, \"macro.dbt.get_create_index_sql\": {\"name\": \"get_create_index_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"unique_id\": \"macro.dbt.get_create_index_sql\", \"macro_sql\": \"{% macro get_create_index_sql(relation, index_dict) -%}\\n  {{ return(adapter.dispatch('get_create_index_sql', 'dbt')(relation, index_dict)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_create_index_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.264548, \"supported_languages\": null}, \"macro.dbt.default__get_create_index_sql\": {\"name\": \"default__get_create_index_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"unique_id\": \"macro.dbt.default__get_create_index_sql\", \"macro_sql\": \"{% macro default__get_create_index_sql(relation, index_dict) -%}\\n  {% do return(None) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.264692, \"supported_languages\": null}, \"macro.dbt.create_indexes\": {\"name\": \"create_indexes\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"unique_id\": \"macro.dbt.create_indexes\", \"macro_sql\": \"{% macro create_indexes(relation) -%}\\n  {{ adapter.dispatch('create_indexes', 'dbt')(relation) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__create_indexes\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.264854, \"supported_languages\": null}, \"macro.dbt.default__create_indexes\": {\"name\": \"default__create_indexes\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"unique_id\": \"macro.dbt.default__create_indexes\", \"macro_sql\": \"{% macro default__create_indexes(relation) -%}\\n  {%- set _indexes = config.get('indexes', default=[]) -%}\\n\\n  {% for _index_dict in _indexes %}\\n    {% set create_index_sql = get_create_index_sql(relation, _index_dict) %}\\n    {% if create_index_sql %}\\n      {% do run_query(create_index_sql) %}\\n    {% endif %}\\n  {% endfor %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_create_index_sql\", \"macro.dbt.run_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.265263, \"supported_languages\": null}, \"macro.dbt.get_drop_index_sql\": {\"name\": \"get_drop_index_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"unique_id\": \"macro.dbt.get_drop_index_sql\", \"macro_sql\": \"{% macro get_drop_index_sql(relation, index_name) -%}\\n    {{ adapter.dispatch('get_drop_index_sql', 'dbt')(relation, index_name) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_drop_index_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.265459, \"supported_languages\": null}, \"macro.dbt.default__get_drop_index_sql\": {\"name\": \"default__get_drop_index_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"unique_id\": \"macro.dbt.default__get_drop_index_sql\", \"macro_sql\": \"{% macro default__get_drop_index_sql(relation, index_name) -%}\\n    {{ exceptions.raise_compiler_error(\\\"`get_drop_index_sql has not been implemented for this adapter.\\\") }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.265602, \"supported_languages\": null}, \"macro.dbt.get_show_indexes_sql\": {\"name\": \"get_show_indexes_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"unique_id\": \"macro.dbt.get_show_indexes_sql\", \"macro_sql\": \"{% macro get_show_indexes_sql(relation) -%}\\n    {{ adapter.dispatch('get_show_indexes_sql', 'dbt')(relation) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_show_indexes_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.265763, \"supported_languages\": null}, \"macro.dbt.default__get_show_indexes_sql\": {\"name\": \"default__get_show_indexes_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"unique_id\": \"macro.dbt.default__get_show_indexes_sql\", \"macro_sql\": \"{% macro default__get_show_indexes_sql(relation) -%}\\n    {{ exceptions.raise_compiler_error(\\\"`get_show_indexes_sql has not been implemented for this adapter.\\\") }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.265894, \"supported_languages\": null}, \"macro.dbt.make_intermediate_relation\": {\"name\": \"make_intermediate_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.make_intermediate_relation\", \"macro_sql\": \"{% macro make_intermediate_relation(base_relation, suffix='__dbt_tmp') %}\\n  {{ return(adapter.dispatch('make_intermediate_relation', 'dbt')(base_relation, suffix)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_intermediate_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.268777, \"supported_languages\": null}, \"macro.dbt.default__make_intermediate_relation\": {\"name\": \"default__make_intermediate_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.default__make_intermediate_relation\", \"macro_sql\": \"{% macro default__make_intermediate_relation(base_relation, suffix) %}\\n    {{ return(default__make_temp_relation(base_relation, suffix)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__make_temp_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.268948, \"supported_languages\": null}, \"macro.dbt.make_temp_relation\": {\"name\": \"make_temp_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.make_temp_relation\", \"macro_sql\": \"{% macro make_temp_relation(base_relation, suffix='__dbt_tmp') %}\\n  {{ return(adapter.dispatch('make_temp_relation', 'dbt')(base_relation, suffix)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_temp_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.269174, \"supported_languages\": null}, \"macro.dbt.default__make_temp_relation\": {\"name\": \"default__make_temp_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.default__make_temp_relation\", \"macro_sql\": \"{% macro default__make_temp_relation(base_relation, suffix) %}\\n    {%- set temp_identifier = base_relation.identifier ~ suffix -%}\\n    {%- set temp_relation = base_relation.incorporate(\\n                                path={\\\"identifier\\\": temp_identifier}) -%}\\n\\n    {{ return(temp_relation) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.269548, \"supported_languages\": null}, \"macro.dbt.make_backup_relation\": {\"name\": \"make_backup_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.make_backup_relation\", \"macro_sql\": \"{% macro make_backup_relation(base_relation, backup_relation_type, suffix='__dbt_backup') %}\\n    {{ return(adapter.dispatch('make_backup_relation', 'dbt')(base_relation, backup_relation_type, suffix)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_backup_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.269803, \"supported_languages\": null}, \"macro.dbt.default__make_backup_relation\": {\"name\": \"default__make_backup_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.default__make_backup_relation\", \"macro_sql\": \"{% macro default__make_backup_relation(base_relation, backup_relation_type, suffix) %}\\n    {%- set backup_identifier = base_relation.identifier ~ suffix -%}\\n    {%- set backup_relation = base_relation.incorporate(\\n                                  path={\\\"identifier\\\": backup_identifier},\\n                                  type=backup_relation_type\\n    ) -%}\\n    {{ return(backup_relation) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.270133, \"supported_languages\": null}, \"macro.dbt.truncate_relation\": {\"name\": \"truncate_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.truncate_relation\", \"macro_sql\": \"{% macro truncate_relation(relation) -%}\\n  {{ return(adapter.dispatch('truncate_relation', 'dbt')(relation)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__truncate_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.270325, \"supported_languages\": null}, \"macro.dbt.default__truncate_relation\": {\"name\": \"default__truncate_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.default__truncate_relation\", \"macro_sql\": \"{% macro default__truncate_relation(relation) -%}\\n  {% call statement('truncate_relation') -%}\\n    truncate table {{ relation }}\\n  {%- endcall %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2704918, \"supported_languages\": null}, \"macro.dbt.rename_relation\": {\"name\": \"rename_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.rename_relation\", \"macro_sql\": \"{% macro rename_relation(from_relation, to_relation) -%}\\n  {{ return(adapter.dispatch('rename_relation', 'dbt')(from_relation, to_relation)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__rename_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.270706, \"supported_languages\": null}, \"macro.dbt.default__rename_relation\": {\"name\": \"default__rename_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.default__rename_relation\", \"macro_sql\": \"{% macro default__rename_relation(from_relation, to_relation) -%}\\n  {% set target_name = adapter.quote_as_configured(to_relation.identifier, 'identifier') %}\\n  {% call statement('rename_relation') -%}\\n    alter table {{ from_relation }} rename to {{ target_name }}\\n  {%- endcall %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.270998, \"supported_languages\": null}, \"macro.dbt.get_or_create_relation\": {\"name\": \"get_or_create_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.get_or_create_relation\", \"macro_sql\": \"{% macro get_or_create_relation(database, schema, identifier, type) -%}\\n  {{ return(adapter.dispatch('get_or_create_relation', 'dbt')(database, schema, identifier, type)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_or_create_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.271255, \"supported_languages\": null}, \"macro.dbt.default__get_or_create_relation\": {\"name\": \"default__get_or_create_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.default__get_or_create_relation\", \"macro_sql\": \"{% macro default__get_or_create_relation(database, schema, identifier, type) %}\\n  {%- set target_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) %}\\n\\n  {% if target_relation %}\\n    {% do return([true, target_relation]) %}\\n  {% endif %}\\n\\n  {%- set new_relation = api.Relation.create(\\n      database=database,\\n      schema=schema,\\n      identifier=identifier,\\n      type=type\\n  ) -%}\\n  {% do return([false, new_relation]) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.271829, \"supported_languages\": null}, \"macro.dbt.load_cached_relation\": {\"name\": \"load_cached_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.load_cached_relation\", \"macro_sql\": \"{% macro load_cached_relation(relation) %}\\n  {% do return(adapter.get_relation(\\n    database=relation.database,\\n    schema=relation.schema,\\n    identifier=relation.identifier\\n  )) -%}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.27207, \"supported_languages\": null}, \"macro.dbt.load_relation\": {\"name\": \"load_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.load_relation\", \"macro_sql\": \"{% macro load_relation(relation) %}\\n    {{ return(load_cached_relation(relation)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.load_cached_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.27222, \"supported_languages\": null}, \"macro.dbt.drop_relation_if_exists\": {\"name\": \"drop_relation_if_exists\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.drop_relation_if_exists\", \"macro_sql\": \"{% macro drop_relation_if_exists(relation) %}\\n  {% if relation is not none %}\\n    {{ adapter.drop_relation(relation) }}\\n  {% endif %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.272419, \"supported_languages\": null}, \"macro.dbt.collect_freshness\": {\"name\": \"collect_freshness\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/freshness.sql\", \"original_file_path\": \"macros/adapters/freshness.sql\", \"unique_id\": \"macro.dbt.collect_freshness\", \"macro_sql\": \"{% macro collect_freshness(source, loaded_at_field, filter) %}\\n  {{ return(adapter.dispatch('collect_freshness', 'dbt')(source, loaded_at_field, filter))}}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__collect_freshness\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.272854, \"supported_languages\": null}, \"macro.dbt.default__collect_freshness\": {\"name\": \"default__collect_freshness\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/freshness.sql\", \"original_file_path\": \"macros/adapters/freshness.sql\", \"unique_id\": \"macro.dbt.default__collect_freshness\", \"macro_sql\": \"{% macro default__collect_freshness(source, loaded_at_field, filter) %}\\n  {% call statement('collect_freshness', fetch_result=True, auto_begin=False) -%}\\n    select\\n      max({{ loaded_at_field }}) as max_loaded_at,\\n      {{ current_timestamp() }} as snapshotted_at\\n    from {{ source }}\\n    {% if filter %}\\n    where {{ filter }}\\n    {% endif %}\\n  {% endcall %}\\n  {{ return(load_result('collect_freshness')) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\", \"macro.dbt.current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.273275, \"supported_languages\": null}, \"macro.dbt.validate_sql\": {\"name\": \"validate_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/validate_sql.sql\", \"original_file_path\": \"macros/adapters/validate_sql.sql\", \"unique_id\": \"macro.dbt.validate_sql\", \"macro_sql\": \"{% macro validate_sql(sql) -%}\\n  {{ return(adapter.dispatch('validate_sql', 'dbt')(sql)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__validate_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2735639, \"supported_languages\": null}, \"macro.dbt.default__validate_sql\": {\"name\": \"default__validate_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/validate_sql.sql\", \"original_file_path\": \"macros/adapters/validate_sql.sql\", \"unique_id\": \"macro.dbt.default__validate_sql\", \"macro_sql\": \"{% macro default__validate_sql(sql) -%}\\n  {% call statement('validate_sql') -%}\\n    explain {{ sql }}\\n  {% endcall %}\\n  {{ return(load_result('validate_sql')) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.273793, \"supported_languages\": null}, \"macro.dbt.copy_grants\": {\"name\": \"copy_grants\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.copy_grants\", \"macro_sql\": \"{% macro copy_grants() %}\\n    {{ return(adapter.dispatch('copy_grants', 'dbt')()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__copy_grants\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.275553, \"supported_languages\": null}, \"macro.dbt.default__copy_grants\": {\"name\": \"default__copy_grants\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.default__copy_grants\", \"macro_sql\": \"{% macro default__copy_grants() %}\\n    {{ return(True) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2756748, \"supported_languages\": null}, \"macro.dbt.support_multiple_grantees_per_dcl_statement\": {\"name\": \"support_multiple_grantees_per_dcl_statement\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.support_multiple_grantees_per_dcl_statement\", \"macro_sql\": \"{% macro support_multiple_grantees_per_dcl_statement() %}\\n    {{ return(adapter.dispatch('support_multiple_grantees_per_dcl_statement', 'dbt')()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__support_multiple_grantees_per_dcl_statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2758532, \"supported_languages\": null}, \"macro.dbt.default__support_multiple_grantees_per_dcl_statement\": {\"name\": \"default__support_multiple_grantees_per_dcl_statement\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.default__support_multiple_grantees_per_dcl_statement\", \"macro_sql\": \"\\n\\n{%- macro default__support_multiple_grantees_per_dcl_statement() -%}\\n    {{ return(True) }}\\n{%- endmacro -%}\\n\\n\\n\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.275969, \"supported_languages\": null}, \"macro.dbt.should_revoke\": {\"name\": \"should_revoke\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.should_revoke\", \"macro_sql\": \"{% macro should_revoke(existing_relation, full_refresh_mode=True) %}\\n\\n    {% if not existing_relation %}\\n        {#-- The table doesn't already exist, so no grants to copy over --#}\\n        {{ return(False) }}\\n    {% elif full_refresh_mode %}\\n        {#-- The object is being REPLACED -- whether grants are copied over depends on the value of user config --#}\\n        {{ return(copy_grants()) }}\\n    {% else %}\\n        {#-- The table is being merged/upserted/inserted -- grants will be carried over --#}\\n        {{ return(True) }}\\n    {% endif %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.copy_grants\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.276321, \"supported_languages\": null}, \"macro.dbt.get_show_grant_sql\": {\"name\": \"get_show_grant_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.get_show_grant_sql\", \"macro_sql\": \"{% macro get_show_grant_sql(relation) %}\\n    {{ return(adapter.dispatch(\\\"get_show_grant_sql\\\", \\\"dbt\\\")(relation)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_show_grant_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.276514, \"supported_languages\": null}, \"macro.dbt.default__get_show_grant_sql\": {\"name\": \"default__get_show_grant_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.default__get_show_grant_sql\", \"macro_sql\": \"{% macro default__get_show_grant_sql(relation) %}\\n    show grants on {{ relation }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2766201, \"supported_languages\": null}, \"macro.dbt.get_grant_sql\": {\"name\": \"get_grant_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.get_grant_sql\", \"macro_sql\": \"{% macro get_grant_sql(relation, privilege, grantees) %}\\n    {{ return(adapter.dispatch('get_grant_sql', 'dbt')(relation, privilege, grantees)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_grant_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.276926, \"supported_languages\": null}, \"macro.dbt.default__get_grant_sql\": {\"name\": \"default__get_grant_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.default__get_grant_sql\", \"macro_sql\": \"\\n\\n{%- macro default__get_grant_sql(relation, privilege, grantees) -%}\\n    grant {{ privilege }} on {{ relation }} to {{ grantees | join(', ') }}\\n{%- endmacro -%}\\n\\n\\n\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.277123, \"supported_languages\": null}, \"macro.dbt.get_revoke_sql\": {\"name\": \"get_revoke_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.get_revoke_sql\", \"macro_sql\": \"{% macro get_revoke_sql(relation, privilege, grantees) %}\\n    {{ return(adapter.dispatch('get_revoke_sql', 'dbt')(relation, privilege, grantees)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_revoke_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.277358, \"supported_languages\": null}, \"macro.dbt.default__get_revoke_sql\": {\"name\": \"default__get_revoke_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.default__get_revoke_sql\", \"macro_sql\": \"\\n\\n{%- macro default__get_revoke_sql(relation, privilege, grantees) -%}\\n    revoke {{ privilege }} on {{ relation }} from {{ grantees | join(', ') }}\\n{%- endmacro -%}\\n\\n\\n\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2775512, \"supported_languages\": null}, \"macro.dbt.get_dcl_statement_list\": {\"name\": \"get_dcl_statement_list\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.get_dcl_statement_list\", \"macro_sql\": \"{% macro get_dcl_statement_list(relation, grant_config, get_dcl_macro) %}\\n    {{ return(adapter.dispatch('get_dcl_statement_list', 'dbt')(relation, grant_config, get_dcl_macro)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_dcl_statement_list\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.277785, \"supported_languages\": null}, \"macro.dbt.default__get_dcl_statement_list\": {\"name\": \"default__get_dcl_statement_list\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.default__get_dcl_statement_list\", \"macro_sql\": \"\\n\\n{%- macro default__get_dcl_statement_list(relation, grant_config, get_dcl_macro) -%}\\n    {#\\n      -- Unpack grant_config into specific privileges and the set of users who need them granted/revoked.\\n      -- Depending on whether this database supports multiple grantees per statement, pass in the list of\\n      -- all grantees per privilege, or (if not) template one statement per privilege-grantee pair.\\n      -- `get_dcl_macro` will be either `get_grant_sql` or `get_revoke_sql`\\n    #}\\n    {%- set dcl_statements = [] -%}\\n    {%- for privilege, grantees in grant_config.items() %}\\n        {%- if support_multiple_grantees_per_dcl_statement() and grantees -%}\\n          {%- set dcl = get_dcl_macro(relation, privilege, grantees) -%}\\n          {%- do dcl_statements.append(dcl) -%}\\n        {%- else -%}\\n          {%- for grantee in grantees -%}\\n              {% set dcl = get_dcl_macro(relation, privilege, [grantee]) %}\\n              {%- do dcl_statements.append(dcl) -%}\\n          {% endfor -%}\\n        {%- endif -%}\\n    {%- endfor -%}\\n    {{ return(dcl_statements) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.support_multiple_grantees_per_dcl_statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.278485, \"supported_languages\": null}, \"macro.dbt.call_dcl_statements\": {\"name\": \"call_dcl_statements\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.call_dcl_statements\", \"macro_sql\": \"{% macro call_dcl_statements(dcl_statement_list) %}\\n    {{ return(adapter.dispatch(\\\"call_dcl_statements\\\", \\\"dbt\\\")(dcl_statement_list)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__call_dcl_statements\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.278682, \"supported_languages\": null}, \"macro.dbt.default__call_dcl_statements\": {\"name\": \"default__call_dcl_statements\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.default__call_dcl_statements\", \"macro_sql\": \"{% macro default__call_dcl_statements(dcl_statement_list) %}\\n    {#\\n      -- By default, supply all grant + revoke statements in a single semicolon-separated block,\\n      -- so that they're all processed together.\\n\\n      -- Some databases do not support this. Those adapters will need to override this macro\\n      -- to run each statement individually.\\n    #}\\n    {% call statement('grants') %}\\n        {% for dcl_statement in dcl_statement_list %}\\n            {{ dcl_statement }};\\n        {% endfor %}\\n    {% endcall %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2789361, \"supported_languages\": null}, \"macro.dbt.apply_grants\": {\"name\": \"apply_grants\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.apply_grants\", \"macro_sql\": \"{% macro apply_grants(relation, grant_config, should_revoke) %}\\n    {{ return(adapter.dispatch(\\\"apply_grants\\\", \\\"dbt\\\")(relation, grant_config, should_revoke)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__apply_grants\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2791739, \"supported_languages\": null}, \"macro.dbt.default__apply_grants\": {\"name\": \"default__apply_grants\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.default__apply_grants\", \"macro_sql\": \"{% macro default__apply_grants(relation, grant_config, should_revoke=True) %}\\n    {#-- If grant_config is {} or None, this is a no-op --#}\\n    {% if grant_config %}\\n        {% if should_revoke %}\\n            {#-- We think previous grants may have carried over --#}\\n            {#-- Show current grants and calculate diffs --#}\\n            {% set current_grants_table = run_query(get_show_grant_sql(relation)) %}\\n            {% set current_grants_dict = adapter.standardize_grants_dict(current_grants_table) %}\\n            {% set needs_granting = diff_of_two_dicts(grant_config, current_grants_dict) %}\\n            {% set needs_revoking = diff_of_two_dicts(current_grants_dict, grant_config) %}\\n            {% if not (needs_granting or needs_revoking) %}\\n                {{ log('On ' ~ relation ~': All grants are in place, no revocation or granting needed.')}}\\n            {% endif %}\\n        {% else %}\\n            {#-- We don't think there's any chance of previous grants having carried over. --#}\\n            {#-- Jump straight to granting what the user has configured. --#}\\n            {% set needs_revoking = {} %}\\n            {% set needs_granting = grant_config %}\\n        {% endif %}\\n        {% if needs_granting or needs_revoking %}\\n            {% set revoke_statement_list = get_dcl_statement_list(relation, needs_revoking, get_revoke_sql) %}\\n            {% set grant_statement_list = get_dcl_statement_list(relation, needs_granting, get_grant_sql) %}\\n            {% set dcl_statement_list = revoke_statement_list + grant_statement_list %}\\n            {% if dcl_statement_list %}\\n                {{ call_dcl_statements(dcl_statement_list) }}\\n            {% endif %}\\n        {% endif %}\\n    {% endif %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.run_query\", \"macro.dbt.get_show_grant_sql\", \"macro.dbt.get_dcl_statement_list\", \"macro.dbt.call_dcl_statements\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2803478, \"supported_languages\": null}, \"macro.dbt.get_show_sql\": {\"name\": \"get_show_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/show.sql\", \"original_file_path\": \"macros/adapters/show.sql\", \"unique_id\": \"macro.dbt.get_show_sql\", \"macro_sql\": \"{% macro get_show_sql(compiled_code, sql_header, limit) -%}\\n  {%- if sql_header -%}\\n  {{ sql_header }}\\n  {%- endif -%}\\n  {%- if limit is not none -%}\\n  {{ get_limit_subquery_sql(compiled_code, limit) }}\\n  {%- else -%}\\n  {{ compiled_code }}\\n  {%- endif -%}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_limit_subquery_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2808928, \"supported_languages\": null}, \"macro.dbt.get_limit_subquery_sql\": {\"name\": \"get_limit_subquery_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/show.sql\", \"original_file_path\": \"macros/adapters/show.sql\", \"unique_id\": \"macro.dbt.get_limit_subquery_sql\", \"macro_sql\": \"{% macro get_limit_subquery_sql(sql, limit) %}\\n  {{ adapter.dispatch('get_limit_subquery_sql', 'dbt')(sql, limit) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_limit_subquery_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.281089, \"supported_languages\": null}, \"macro.dbt.default__get_limit_subquery_sql\": {\"name\": \"default__get_limit_subquery_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/show.sql\", \"original_file_path\": \"macros/adapters/show.sql\", \"unique_id\": \"macro.dbt.default__get_limit_subquery_sql\", \"macro_sql\": \"{% macro default__get_limit_subquery_sql(sql, limit) %}\\n    select *\\n    from (\\n        {{ sql }}\\n    ) as model_limit_subq\\n    limit {{ limit }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.281228, \"supported_languages\": null}, \"macro.dbt.alter_column_comment\": {\"name\": \"alter_column_comment\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"unique_id\": \"macro.dbt.alter_column_comment\", \"macro_sql\": \"{% macro alter_column_comment(relation, column_dict) -%}\\n  {{ return(adapter.dispatch('alter_column_comment', 'dbt')(relation, column_dict)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__alter_column_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.281921, \"supported_languages\": null}, \"macro.dbt.default__alter_column_comment\": {\"name\": \"default__alter_column_comment\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"unique_id\": \"macro.dbt.default__alter_column_comment\", \"macro_sql\": \"{% macro default__alter_column_comment(relation, column_dict) -%}\\n  {{ exceptions.raise_not_implemented(\\n    'alter_column_comment macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2820952, \"supported_languages\": null}, \"macro.dbt.alter_relation_comment\": {\"name\": \"alter_relation_comment\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"unique_id\": \"macro.dbt.alter_relation_comment\", \"macro_sql\": \"{% macro alter_relation_comment(relation, relation_comment) -%}\\n  {{ return(adapter.dispatch('alter_relation_comment', 'dbt')(relation, relation_comment)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__alter_relation_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.282303, \"supported_languages\": null}, \"macro.dbt.default__alter_relation_comment\": {\"name\": \"default__alter_relation_comment\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"unique_id\": \"macro.dbt.default__alter_relation_comment\", \"macro_sql\": \"{% macro default__alter_relation_comment(relation, relation_comment) -%}\\n  {{ exceptions.raise_not_implemented(\\n    'alter_relation_comment macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.282475, \"supported_languages\": null}, \"macro.dbt.persist_docs\": {\"name\": \"persist_docs\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"unique_id\": \"macro.dbt.persist_docs\", \"macro_sql\": \"{% macro persist_docs(relation, model, for_relation=true, for_columns=true) -%}\\n  {{ return(adapter.dispatch('persist_docs', 'dbt')(relation, model, for_relation, for_columns)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__persist_docs\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.282752, \"supported_languages\": null}, \"macro.dbt.default__persist_docs\": {\"name\": \"default__persist_docs\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"unique_id\": \"macro.dbt.default__persist_docs\", \"macro_sql\": \"{% macro default__persist_docs(relation, model, for_relation, for_columns) -%}\\n  {% if for_relation and config.persist_relation_docs() and model.description %}\\n    {% do run_query(alter_relation_comment(relation, model.description)) %}\\n  {% endif %}\\n\\n  {% if for_columns and config.persist_column_docs() and model.columns %}\\n    {% do run_query(alter_column_comment(relation, model.columns)) %}\\n  {% endif %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.run_query\", \"macro.dbt.alter_relation_comment\", \"macro.dbt.alter_column_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.283254, \"supported_languages\": null}, \"macro.dbt.get_catalog\": {\"name\": \"get_catalog\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.get_catalog\", \"macro_sql\": \"{% macro get_catalog(information_schema, schemas) -%}\\n  {{ return(adapter.dispatch('get_catalog', 'dbt')(information_schema, schemas)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_catalog\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2848241, \"supported_languages\": null}, \"macro.dbt.default__get_catalog\": {\"name\": \"default__get_catalog\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.default__get_catalog\", \"macro_sql\": \"{% macro default__get_catalog(information_schema, schemas) -%}\\n\\n  {% set typename = adapter.type() %}\\n  {% set msg -%}\\n    get_catalog not implemented for {{ typename }}\\n  {%- endset %}\\n\\n  {{ exceptions.raise_compiler_error(msg) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.285086, \"supported_languages\": null}, \"macro.dbt.information_schema_name\": {\"name\": \"information_schema_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.information_schema_name\", \"macro_sql\": \"{% macro information_schema_name(database) %}\\n  {{ return(adapter.dispatch('information_schema_name', 'dbt')(database)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__information_schema_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2852778, \"supported_languages\": null}, \"macro.dbt.default__information_schema_name\": {\"name\": \"default__information_schema_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.default__information_schema_name\", \"macro_sql\": \"{% macro default__information_schema_name(database) -%}\\n  {%- if database -%}\\n    {{ database }}.INFORMATION_SCHEMA\\n  {%- else -%}\\n    INFORMATION_SCHEMA\\n  {%- endif -%}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.285444, \"supported_languages\": null}, \"macro.dbt.list_schemas\": {\"name\": \"list_schemas\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.list_schemas\", \"macro_sql\": \"{% macro list_schemas(database) -%}\\n  {{ return(adapter.dispatch('list_schemas', 'dbt')(database)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__list_schemas\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.285694, \"supported_languages\": null}, \"macro.dbt.default__list_schemas\": {\"name\": \"default__list_schemas\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.default__list_schemas\", \"macro_sql\": \"{% macro default__list_schemas(database) -%}\\n  {% set sql %}\\n    select distinct schema_name\\n    from {{ information_schema_name(database) }}.SCHEMATA\\n    where catalog_name ilike '{{ database }}'\\n  {% endset %}\\n  {{ return(run_query(sql)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.information_schema_name\", \"macro.dbt.run_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.28595, \"supported_languages\": null}, \"macro.dbt.check_schema_exists\": {\"name\": \"check_schema_exists\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.check_schema_exists\", \"macro_sql\": \"{% macro check_schema_exists(information_schema, schema) -%}\\n  {{ return(adapter.dispatch('check_schema_exists', 'dbt')(information_schema, schema)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__check_schema_exists\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2861598, \"supported_languages\": null}, \"macro.dbt.default__check_schema_exists\": {\"name\": \"default__check_schema_exists\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.default__check_schema_exists\", \"macro_sql\": \"{% macro default__check_schema_exists(information_schema, schema) -%}\\n  {% set sql -%}\\n        select count(*)\\n        from {{ information_schema.replace(information_schema_view='SCHEMATA') }}\\n        where catalog_name='{{ information_schema.database }}'\\n          and schema_name='{{ schema }}'\\n  {%- endset %}\\n  {{ return(run_query(sql)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.replace\", \"macro.dbt.run_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2864761, \"supported_languages\": null}, \"macro.dbt.list_relations_without_caching\": {\"name\": \"list_relations_without_caching\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.list_relations_without_caching\", \"macro_sql\": \"{% macro list_relations_without_caching(schema_relation) %}\\n  {{ return(adapter.dispatch('list_relations_without_caching', 'dbt')(schema_relation)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__list_relations_without_caching\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.286675, \"supported_languages\": null}, \"macro.dbt.default__list_relations_without_caching\": {\"name\": \"default__list_relations_without_caching\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.default__list_relations_without_caching\", \"macro_sql\": \"{% macro default__list_relations_without_caching(schema_relation) %}\\n  {{ exceptions.raise_not_implemented(\\n    'list_relations_without_caching macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2868428, \"supported_languages\": null}, \"macro.dbt.drop_relation\": {\"name\": \"drop_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/drop_relation.sql\", \"original_file_path\": \"macros/adapters/drop_relation.sql\", \"unique_id\": \"macro.dbt.drop_relation\", \"macro_sql\": \"{% macro drop_relation(relation) -%}\\n    {{ return(adapter.dispatch('drop_relation', 'dbt')(relation)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__drop_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2877948, \"supported_languages\": null}, \"macro.dbt.default__drop_relation\": {\"name\": \"default__drop_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/drop_relation.sql\", \"original_file_path\": \"macros/adapters/drop_relation.sql\", \"unique_id\": \"macro.dbt.default__drop_relation\", \"macro_sql\": \"{% macro default__drop_relation(relation) -%}\\n    {% call statement('drop_relation', auto_begin=False) -%}\\n        {%- if relation.is_table -%}\\n            {{- drop_table(relation) -}}\\n        {%- elif relation.is_view -%}\\n            {{- drop_view(relation) -}}\\n        {%- elif relation.is_materialized_view -%}\\n            {{- drop_materialized_view(relation) -}}\\n        {%- else -%}\\n            drop {{ relation.type }} if exists {{ relation }} cascade\\n        {%- endif -%}\\n    {%- endcall %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\", \"macro.dbt.drop_table\", \"macro.dbt.drop_view\", \"macro.dbt.drop_materialized_view\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.28826, \"supported_languages\": null}, \"macro.dbt.drop_table\": {\"name\": \"drop_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/drop_relation.sql\", \"original_file_path\": \"macros/adapters/drop_relation.sql\", \"unique_id\": \"macro.dbt.drop_table\", \"macro_sql\": \"{% macro drop_table(relation) -%}\\n  {{ return(adapter.dispatch('drop_table', 'dbt')(relation)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__drop_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.288448, \"supported_languages\": null}, \"macro.dbt.default__drop_table\": {\"name\": \"default__drop_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/drop_relation.sql\", \"original_file_path\": \"macros/adapters/drop_relation.sql\", \"unique_id\": \"macro.dbt.default__drop_table\", \"macro_sql\": \"{% macro default__drop_table(relation) -%}\\n    drop table if exists {{ relation }} cascade\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.288556, \"supported_languages\": null}, \"macro.dbt.drop_view\": {\"name\": \"drop_view\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/drop_relation.sql\", \"original_file_path\": \"macros/adapters/drop_relation.sql\", \"unique_id\": \"macro.dbt.drop_view\", \"macro_sql\": \"{% macro drop_view(relation) -%}\\n  {{ return(adapter.dispatch('drop_view', 'dbt')(relation)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__drop_view\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.288737, \"supported_languages\": null}, \"macro.dbt.default__drop_view\": {\"name\": \"default__drop_view\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/drop_relation.sql\", \"original_file_path\": \"macros/adapters/drop_relation.sql\", \"unique_id\": \"macro.dbt.default__drop_view\", \"macro_sql\": \"{% macro default__drop_view(relation) -%}\\n    drop view if exists {{ relation }} cascade\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.288845, \"supported_languages\": null}, \"macro.dbt.drop_materialized_view\": {\"name\": \"drop_materialized_view\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/drop_relation.sql\", \"original_file_path\": \"macros/adapters/drop_relation.sql\", \"unique_id\": \"macro.dbt.drop_materialized_view\", \"macro_sql\": \"{% macro drop_materialized_view(relation) -%}\\n  {{ return(adapter.dispatch('drop_materialized_view', 'dbt')(relation)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__drop_materialized_view\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.289025, \"supported_languages\": null}, \"macro.dbt.default__drop_materialized_view\": {\"name\": \"default__drop_materialized_view\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/drop_relation.sql\", \"original_file_path\": \"macros/adapters/drop_relation.sql\", \"unique_id\": \"macro.dbt.default__drop_materialized_view\", \"macro_sql\": \"{% macro default__drop_materialized_view(relation) -%}\\n    drop materialized view if exists {{ relation }} cascade\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.289133, \"supported_languages\": null}, \"macro.dbt.get_columns_in_relation\": {\"name\": \"get_columns_in_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.get_columns_in_relation\", \"macro_sql\": \"{% macro get_columns_in_relation(relation) -%}\\n  {{ return(adapter.dispatch('get_columns_in_relation', 'dbt')(relation)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_columns_in_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.291446, \"supported_languages\": null}, \"macro.dbt.default__get_columns_in_relation\": {\"name\": \"default__get_columns_in_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.default__get_columns_in_relation\", \"macro_sql\": \"{% macro default__get_columns_in_relation(relation) -%}\\n  {{ exceptions.raise_not_implemented(\\n    'get_columns_in_relation macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2916129, \"supported_languages\": null}, \"macro.dbt.sql_convert_columns_in_relation\": {\"name\": \"sql_convert_columns_in_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.sql_convert_columns_in_relation\", \"macro_sql\": \"{% macro sql_convert_columns_in_relation(table) -%}\\n  {% set columns = [] %}\\n  {% for row in table %}\\n    {% do columns.append(api.Column(*row)) %}\\n  {% endfor %}\\n  {{ return(columns) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2919302, \"supported_languages\": null}, \"macro.dbt.get_empty_subquery_sql\": {\"name\": \"get_empty_subquery_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.get_empty_subquery_sql\", \"macro_sql\": \"{% macro get_empty_subquery_sql(select_sql, select_sql_header=none) -%}\\n  {{ return(adapter.dispatch('get_empty_subquery_sql', 'dbt')(select_sql, select_sql_header)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_empty_subquery_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2921631, \"supported_languages\": null}, \"macro.dbt.default__get_empty_subquery_sql\": {\"name\": \"default__get_empty_subquery_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.default__get_empty_subquery_sql\", \"macro_sql\": \"{% macro default__get_empty_subquery_sql(select_sql, select_sql_header=none) %}\\n    {%- if select_sql_header is not none -%}\\n    {{ select_sql_header }}\\n    {%- endif -%}\\n    select * from (\\n        {{ select_sql }}\\n    ) as __dbt_sbq\\n    where false\\n    limit 0\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.292375, \"supported_languages\": null}, \"macro.dbt.get_empty_schema_sql\": {\"name\": \"get_empty_schema_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.get_empty_schema_sql\", \"macro_sql\": \"{% macro get_empty_schema_sql(columns) -%}\\n  {{ return(adapter.dispatch('get_empty_schema_sql', 'dbt')(columns)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_empty_schema_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.292562, \"supported_languages\": null}, \"macro.dbt.default__get_empty_schema_sql\": {\"name\": \"default__get_empty_schema_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.default__get_empty_schema_sql\", \"macro_sql\": \"{% macro default__get_empty_schema_sql(columns) %}\\n    {%- set col_err = [] -%}\\n    select\\n    {% for i in columns %}\\n      {%- set col = columns[i] -%}\\n      {%- if col['data_type'] is not defined -%}\\n        {{ col_err.append(col['name']) }}\\n      {%- endif -%}\\n      {% set col_name = adapter.quote(col['name']) if col.get('quote') else col['name'] %}\\n      cast(null as {{ col['data_type'] }}) as {{ col_name }}{{ \\\", \\\" if not loop.last }}\\n    {%- endfor -%}\\n    {%- if (col_err | length) > 0 -%}\\n      {{ exceptions.column_type_missing(column_names=col_err) }}\\n    {%- endif -%}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.293418, \"supported_languages\": null}, \"macro.dbt.get_column_schema_from_query\": {\"name\": \"get_column_schema_from_query\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.get_column_schema_from_query\", \"macro_sql\": \"{% macro get_column_schema_from_query(select_sql, select_sql_header=none) -%}\\n    {% set columns = [] %}\\n    {# -- Using an 'empty subquery' here to get the same schema as the given select_sql statement, without necessitating a data scan.#}\\n    {% set sql = get_empty_subquery_sql(select_sql, select_sql_header) %}\\n    {% set column_schema = adapter.get_column_schema_from_query(sql) %}\\n    {{ return(column_schema) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_empty_subquery_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2937758, \"supported_languages\": null}, \"macro.dbt.get_columns_in_query\": {\"name\": \"get_columns_in_query\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.get_columns_in_query\", \"macro_sql\": \"{% macro get_columns_in_query(select_sql) -%}\\n  {{ return(adapter.dispatch('get_columns_in_query', 'dbt')(select_sql)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_columns_in_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2939641, \"supported_languages\": null}, \"macro.dbt.default__get_columns_in_query\": {\"name\": \"default__get_columns_in_query\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.default__get_columns_in_query\", \"macro_sql\": \"{% macro default__get_columns_in_query(select_sql) %}\\n    {% call statement('get_columns_in_query', fetch_result=True, auto_begin=False) -%}\\n        {{ get_empty_subquery_sql(select_sql) }}\\n    {% endcall %}\\n    {{ return(load_result('get_columns_in_query').table.columns | map(attribute='name') | list) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\", \"macro.dbt.get_empty_subquery_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.294328, \"supported_languages\": null}, \"macro.dbt.alter_column_type\": {\"name\": \"alter_column_type\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.alter_column_type\", \"macro_sql\": \"{% macro alter_column_type(relation, column_name, new_column_type) -%}\\n  {{ return(adapter.dispatch('alter_column_type', 'dbt')(relation, column_name, new_column_type)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__alter_column_type\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2945652, \"supported_languages\": null}, \"macro.dbt.default__alter_column_type\": {\"name\": \"default__alter_column_type\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.default__alter_column_type\", \"macro_sql\": \"{% macro default__alter_column_type(relation, column_name, new_column_type) -%}\\n  {#\\n    1. Create a new column (w/ temp name and correct type)\\n    2. Copy data over to it\\n    3. Drop the existing column (cascade!)\\n    4. Rename the new column to existing column\\n  #}\\n  {%- set tmp_column = column_name + \\\"__dbt_alter\\\" -%}\\n\\n  {% call statement('alter_column_type') %}\\n    alter table {{ relation }} add column {{ adapter.quote(tmp_column) }} {{ new_column_type }};\\n    update {{ relation }} set {{ adapter.quote(tmp_column) }} = {{ adapter.quote(column_name) }};\\n    alter table {{ relation }} drop column {{ adapter.quote(column_name) }} cascade;\\n    alter table {{ relation }} rename column {{ adapter.quote(tmp_column) }} to {{ adapter.quote(column_name) }}\\n  {% endcall %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.295179, \"supported_languages\": null}, \"macro.dbt.alter_relation_add_remove_columns\": {\"name\": \"alter_relation_add_remove_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.alter_relation_add_remove_columns\", \"macro_sql\": \"{% macro alter_relation_add_remove_columns(relation, add_columns = none, remove_columns = none) -%}\\n  {{ return(adapter.dispatch('alter_relation_add_remove_columns', 'dbt')(relation, add_columns, remove_columns)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__alter_relation_add_remove_columns\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.295451, \"supported_languages\": null}, \"macro.dbt.default__alter_relation_add_remove_columns\": {\"name\": \"default__alter_relation_add_remove_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.default__alter_relation_add_remove_columns\", \"macro_sql\": \"{% macro default__alter_relation_add_remove_columns(relation, add_columns, remove_columns) %}\\n\\n  {% if add_columns is none %}\\n    {% set add_columns = [] %}\\n  {% endif %}\\n  {% if remove_columns is none %}\\n    {% set remove_columns = [] %}\\n  {% endif %}\\n\\n  {% set sql -%}\\n\\n     alter {{ relation.type }} {{ relation }}\\n\\n            {% for column in add_columns %}\\n               add column {{ column.name }} {{ column.data_type }}{{ ',' if not loop.last }}\\n            {% endfor %}{{ ',' if add_columns and remove_columns }}\\n\\n            {% for column in remove_columns %}\\n                drop column {{ column.name }}{{ ',' if not loop.last }}\\n            {% endfor %}\\n\\n  {%- endset -%}\\n\\n  {% do run_query(sql) %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.run_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.296254, \"supported_languages\": null}, \"macro.dbt.resolve_model_name\": {\"name\": \"resolve_model_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/python_model/python.sql\", \"original_file_path\": \"macros/python_model/python.sql\", \"unique_id\": \"macro.dbt.resolve_model_name\", \"macro_sql\": \"{% macro resolve_model_name(input_model_name) %}\\n    {{ return(adapter.dispatch('resolve_model_name', 'dbt')(input_model_name)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__resolve_model_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.29796, \"supported_languages\": null}, \"macro.dbt.default__resolve_model_name\": {\"name\": \"default__resolve_model_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/python_model/python.sql\", \"original_file_path\": \"macros/python_model/python.sql\", \"unique_id\": \"macro.dbt.default__resolve_model_name\", \"macro_sql\": \"\\n\\n{%- macro default__resolve_model_name(input_model_name) -%}\\n    {{  input_model_name | string | replace('\\\"', '\\\\\\\"') }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.2981188, \"supported_languages\": null}, \"macro.dbt.build_ref_function\": {\"name\": \"build_ref_function\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/python_model/python.sql\", \"original_file_path\": \"macros/python_model/python.sql\", \"unique_id\": \"macro.dbt.build_ref_function\", \"macro_sql\": \"{% macro build_ref_function(model) %}\\n\\n    {%- set ref_dict = {} -%}\\n    {%- for _ref in model.refs -%}\\n        {% set _ref_args = [_ref.get('package'), _ref['name']] if _ref.get('package') else [_ref['name'],] %}\\n        {%- set resolved = ref(*_ref_args, v=_ref.get('version')) -%}\\n        {%- if _ref.get('version') -%}\\n            {% do _ref_args.extend([\\\"v\\\" ~ _ref['version']]) %}\\n        {%- endif -%}\\n       {%- do ref_dict.update({_ref_args | join('.'): resolve_model_name(resolved)}) -%}\\n    {%- endfor -%}\\n\\ndef ref(*args, **kwargs):\\n    refs = {{ ref_dict | tojson }}\\n    key = '.'.join(args)\\n    version = kwargs.get(\\\"v\\\") or kwargs.get(\\\"version\\\")\\n    if version:\\n        key += f\\\".v{version}\\\"\\n    dbt_load_df_function = kwargs.get(\\\"dbt_load_df_function\\\")\\n    return dbt_load_df_function(refs[key])\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.resolve_model_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.298965, \"supported_languages\": null}, \"macro.dbt.build_source_function\": {\"name\": \"build_source_function\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/python_model/python.sql\", \"original_file_path\": \"macros/python_model/python.sql\", \"unique_id\": \"macro.dbt.build_source_function\", \"macro_sql\": \"{% macro build_source_function(model) %}\\n\\n    {%- set source_dict = {} -%}\\n    {%- for _source in model.sources -%}\\n        {%- set resolved = source(*_source) -%}\\n        {%- do source_dict.update({_source | join('.'): resolve_model_name(resolved)}) -%}\\n    {%- endfor -%}\\n\\ndef source(*args, dbt_load_df_function):\\n    sources = {{ source_dict | tojson }}\\n    key = '.'.join(args)\\n    return dbt_load_df_function(sources[key])\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.resolve_model_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.299389, \"supported_languages\": null}, \"macro.dbt.build_config_dict\": {\"name\": \"build_config_dict\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/python_model/python.sql\", \"original_file_path\": \"macros/python_model/python.sql\", \"unique_id\": \"macro.dbt.build_config_dict\", \"macro_sql\": \"{% macro build_config_dict(model) %}\\n    {%- set config_dict = {} -%}\\n    {% set config_dbt_used = zip(model.config.config_keys_used, model.config.config_keys_defaults) | list %}\\n    {%- for key, default in config_dbt_used -%}\\n        {# weird type testing with enum, would be much easier to write this logic in Python! #}\\n        {%- if key == \\\"language\\\" -%}\\n          {%- set value = \\\"python\\\" -%}\\n        {%- endif -%}\\n        {%- set value = model.config.get(key, default) -%}\\n        {%- do config_dict.update({key: value}) -%}\\n    {%- endfor -%}\\nconfig_dict = {{ config_dict }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.299982, \"supported_languages\": null}, \"macro.dbt.py_script_postfix\": {\"name\": \"py_script_postfix\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/python_model/python.sql\", \"original_file_path\": \"macros/python_model/python.sql\", \"unique_id\": \"macro.dbt.py_script_postfix\", \"macro_sql\": \"{% macro py_script_postfix(model) %}\\n# This part is user provided model code\\n# you will need to copy the next section to run the code\\n# COMMAND ----------\\n# this part is dbt logic for get ref work, do not modify\\n\\n{{ build_ref_function(model ) }}\\n{{ build_source_function(model ) }}\\n{{ build_config_dict(model) }}\\n\\nclass config:\\n    def __init__(self, *args, **kwargs):\\n        pass\\n\\n    @staticmethod\\n    def get(key, default=None):\\n        return config_dict.get(key, default)\\n\\nclass this:\\n    \\\"\\\"\\\"dbt.this() or dbt.this.identifier\\\"\\\"\\\"\\n    database = \\\"{{ this.database }}\\\"\\n    schema = \\\"{{ this.schema }}\\\"\\n    identifier = \\\"{{ this.identifier }}\\\"\\n    {% set this_relation_name = resolve_model_name(this) %}\\n    def __repr__(self):\\n        return '{{ this_relation_name  }}'\\n\\n\\nclass dbtObj:\\n    def __init__(self, load_df_function) -> None:\\n        self.source = lambda *args: source(*args, dbt_load_df_function=load_df_function)\\n        self.ref = lambda *args, **kwargs: ref(*args, **kwargs, dbt_load_df_function=load_df_function)\\n        self.config = config\\n        self.this = this()\\n        self.is_incremental = {{ is_incremental() }}\\n\\n# COMMAND ----------\\n{{py_script_comment()}}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.build_ref_function\", \"macro.dbt.build_source_function\", \"macro.dbt.build_config_dict\", \"macro.dbt.resolve_model_name\", \"macro.dbt.is_incremental\", \"macro.dbt.py_script_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.30047, \"supported_languages\": null}, \"macro.dbt.py_script_comment\": {\"name\": \"py_script_comment\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/python_model/python.sql\", \"original_file_path\": \"macros/python_model/python.sql\", \"unique_id\": \"macro.dbt.py_script_comment\", \"macro_sql\": \"{%macro py_script_comment()%}\\n{%endmacro%}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.3005419, \"supported_languages\": null}, \"macro.dbt.test_unique\": {\"name\": \"test_unique\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"tests/generic/builtin.sql\", \"original_file_path\": \"tests/generic/builtin.sql\", \"unique_id\": \"macro.dbt.test_unique\", \"macro_sql\": \"{% test unique(model, column_name) %}\\n    {% set macro = adapter.dispatch('test_unique', 'dbt') %}\\n    {{ macro(model, column_name) }}\\n{% endtest %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__test_unique\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.3010602, \"supported_languages\": null}, \"macro.dbt.test_not_null\": {\"name\": \"test_not_null\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"tests/generic/builtin.sql\", \"original_file_path\": \"tests/generic/builtin.sql\", \"unique_id\": \"macro.dbt.test_not_null\", \"macro_sql\": \"{% test not_null(model, column_name) %}\\n    {% set macro = adapter.dispatch('test_not_null', 'dbt') %}\\n    {{ macro(model, column_name) }}\\n{% endtest %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__test_not_null\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.3013, \"supported_languages\": null}, \"macro.dbt.test_accepted_values\": {\"name\": \"test_accepted_values\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"tests/generic/builtin.sql\", \"original_file_path\": \"tests/generic/builtin.sql\", \"unique_id\": \"macro.dbt.test_accepted_values\", \"macro_sql\": \"{% test accepted_values(model, column_name, values, quote=True) %}\\n    {% set macro = adapter.dispatch('test_accepted_values', 'dbt') %}\\n    {{ macro(model, column_name, values, quote) }}\\n{% endtest %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__test_accepted_values\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.301594, \"supported_languages\": null}, \"macro.dbt.test_relationships\": {\"name\": \"test_relationships\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"tests/generic/builtin.sql\", \"original_file_path\": \"tests/generic/builtin.sql\", \"unique_id\": \"macro.dbt.test_relationships\", \"macro_sql\": \"{% test relationships(model, column_name, to, field) %}\\n    {% set macro = adapter.dispatch('test_relationships', 'dbt') %}\\n    {{ macro(model, column_name, to, field) }}\\n{% endtest %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__test_relationships\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1697057377.301873, \"supported_languages\": null}}, \"docs\": {\"doc.test.somedoc\": {\"name\": \"somedoc\", \"resource_type\": \"doc\", \"package_name\": \"test\", \"path\": \"somedoc.md\", \"original_file_path\": \"models/somedoc.md\", \"unique_id\": \"doc.test.somedoc\", \"block_contents\": \"Testing, testing\"}, \"doc.dbt.__overview__\": {\"name\": \"__overview__\", \"resource_type\": \"doc\", \"package_name\": \"dbt\", \"path\": \"overview.md\", \"original_file_path\": \"docs/overview.md\", \"unique_id\": \"doc.dbt.__overview__\", \"block_contents\": \"### Welcome!\\n\\nWelcome to the auto-generated documentation for your dbt project!\\n\\n### Navigation\\n\\nYou can use the `Project` and `Database` navigation tabs on the left side of the window to explore the models\\nin your project.\\n\\n#### Project Tab\\nThe `Project` tab mirrors the directory structure of your dbt project. In this tab, you can see all of the\\nmodels defined in your dbt project, as well as models imported from dbt packages.\\n\\n#### Database Tab\\nThe `Database` tab also exposes your models, but in a format that looks more like a database explorer. This view\\nshows relations (tables and views) grouped into database schemas. Note that ephemeral models are _not_ shown\\nin this interface, as they do not exist in the database.\\n\\n### Graph Exploration\\nYou can click the blue icon on the bottom-right corner of the page to view the lineage graph of your models.\\n\\nOn model pages, you'll see the immediate parents and children of the model you're exploring. By clicking the `Expand`\\nbutton at the top-right of this lineage pane, you'll be able to see all of the models that are used to build,\\nor are built from, the model you're exploring.\\n\\nOnce expanded, you'll be able to use the `--select` and `--exclude` model selection syntax to filter the\\nmodels in the graph. For more information on model selection, check out the [dbt docs](https://docs.getdbt.com/docs/model-selection-syntax).\\n\\nNote that you can also right-click on models to interactively filter and explore the graph.\\n\\n---\\n\\n### More information\\n\\n- [What is dbt](https://docs.getdbt.com/docs/introduction)?\\n- Read the [dbt viewpoint](https://docs.getdbt.com/docs/viewpoint)\\n- [Installation](https://docs.getdbt.com/docs/installation)\\n- Join the [dbt Community](https://www.getdbt.com/community/) for questions and discussion\"}}, \"exposures\": {\"exposure.test.simple_exposure\": {\"name\": \"simple_exposure\", \"resource_type\": \"exposure\", \"package_name\": \"test\", \"path\": \"schema.yml\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"exposure.test.simple_exposure\", \"fqn\": [\"test\", \"simple_exposure\"], \"type\": \"dashboard\", \"owner\": {\"email\": \"something@example.com\", \"name\": null}, \"description\": \"\", \"label\": null, \"maturity\": null, \"meta\": {}, \"tags\": [], \"config\": {\"enabled\": true}, \"unrendered_config\": {}, \"url\": null, \"depends_on\": {\"macros\": [], \"nodes\": [\"source.test.my_source.my_table\", \"model.test.my_model\"]}, \"refs\": [{\"name\": \"my_model\", \"package\": null, \"version\": null}], \"sources\": [[\"my_source\", \"my_table\"]], \"metrics\": [], \"created_at\": 1697057377.578206}}, \"metrics\": {\"metric.test.blue_customers_post_2010\": {\"name\": \"blue_customers_post_2010\", \"resource_type\": \"metric\", \"package_name\": \"test\", \"path\": \"schema.yml\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"metric.test.blue_customers_post_2010\", \"fqn\": [\"test\", \"blue_customers_post_2010\"], \"description\": \"\", \"label\": \"Blue Customers since 2010\", \"type\": \"simple\", \"type_params\": {\"measure\": {\"name\": \"customers\", \"filter\": {\"where_sql_template\": \"{{ Dimension('id__favorite_color') }} = 'blue'\"}, \"alias\": null, \"join_to_timespine\": false, \"fill_nulls_with\": null}, \"input_measures\": [{\"name\": \"customers\", \"filter\": {\"where_sql_template\": \"{{ Dimension('id__favorite_color') }} = 'blue'\"}, \"alias\": null, \"join_to_timespine\": false, \"fill_nulls_with\": null}], \"numerator\": null, \"denominator\": null, \"expr\": null, \"window\": null, \"grain_to_date\": null, \"metrics\": []}, \"filter\": {\"where_sql_template\": \"{{ TimeDimension('id__created_at', 'day') }} > '2010-01-01'\"}, \"metadata\": null, \"meta\": {}, \"tags\": [], \"config\": {\"enabled\": true, \"group\": null}, \"unrendered_config\": {}, \"sources\": [], \"depends_on\": {\"macros\": [], \"nodes\": [\"semantic_model.test.semantic_people\"]}, \"refs\": [], \"metrics\": [], \"created_at\": 1697057377.583621, \"group\": null}, \"metric.test.customers\": {\"name\": \"customers\", \"resource_type\": \"metric\", \"package_name\": \"test\", \"path\": \"schema.yml\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"metric.test.customers\", \"fqn\": [\"test\", \"customers\"], \"description\": \"\", \"label\": \"Customers Metric\", \"type\": \"simple\", \"type_params\": {\"measure\": {\"name\": \"customers\", \"filter\": null, \"alias\": null, \"join_to_timespine\": false, \"fill_nulls_with\": null}, \"input_measures\": [{\"name\": \"customers\", \"filter\": null, \"alias\": null, \"join_to_timespine\": false, \"fill_nulls_with\": null}], \"numerator\": null, \"denominator\": null, \"expr\": null, \"window\": null, \"grain_to_date\": null, \"metrics\": []}, \"filter\": null, \"metadata\": null, \"meta\": {}, \"tags\": [], \"config\": {\"enabled\": true, \"group\": null}, \"unrendered_config\": {}, \"sources\": [], \"depends_on\": {\"macros\": [], \"nodes\": [\"semantic_model.test.semantic_people\"]}, \"refs\": [], \"metrics\": [], \"created_at\": 1697057377.5840042, \"group\": null}, \"metric.test.ratio_of_blue_customers_to_red_customers\": {\"name\": \"ratio_of_blue_customers_to_red_customers\", \"resource_type\": \"metric\", \"package_name\": \"test\", \"path\": \"schema.yml\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"metric.test.ratio_of_blue_customers_to_red_customers\", \"fqn\": [\"test\", \"ratio_of_blue_customers_to_red_customers\"], \"description\": \"\", \"label\": \"Very Important Customer Color Ratio\", \"type\": \"ratio\", \"type_params\": {\"measure\": null, \"input_measures\": [{\"name\": \"customers\", \"filter\": null, \"alias\": null, \"join_to_timespine\": false, \"fill_nulls_with\": null}, {\"name\": \"customers\", \"filter\": null, \"alias\": null, \"join_to_timespine\": false, \"fill_nulls_with\": null}], \"numerator\": {\"name\": \"customers\", \"filter\": {\"where_sql_template\": \"{{ Dimension('id__favorite_color')}} = 'blue'\"}, \"alias\": null, \"offset_window\": null, \"offset_to_grain\": null}, \"denominator\": {\"name\": \"customers\", \"filter\": {\"where_sql_template\": \"{{ Dimension('id__favorite_color')}} = 'red'\"}, \"alias\": null, \"offset_window\": null, \"offset_to_grain\": null}, \"expr\": null, \"window\": null, \"grain_to_date\": null, \"metrics\": []}, \"filter\": null, \"metadata\": null, \"meta\": {}, \"tags\": [], \"config\": {\"enabled\": true, \"group\": null}, \"unrendered_config\": {}, \"sources\": [], \"depends_on\": {\"macros\": [], \"nodes\": [\"metric.test.customers\"]}, \"refs\": [], \"metrics\": [], \"created_at\": 1697057377.585288, \"group\": null}, \"metric.test.doubled_blue_customers\": {\"name\": \"doubled_blue_customers\", \"resource_type\": \"metric\", \"package_name\": \"test\", \"path\": \"schema.yml\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"metric.test.doubled_blue_customers\", \"fqn\": [\"test\", \"doubled_blue_customers\"], \"description\": \"\", \"label\": \"Inflated blue customer numbers\", \"type\": \"derived\", \"type_params\": {\"measure\": null, \"input_measures\": [{\"name\": \"customers\", \"filter\": null, \"alias\": null, \"join_to_timespine\": false, \"fill_nulls_with\": null}], \"numerator\": null, \"denominator\": null, \"expr\": \"customers * 2\", \"window\": null, \"grain_to_date\": null, \"metrics\": [{\"name\": \"customers\", \"filter\": {\"where_sql_template\": \"{{ Dimension('id__favorite_color')}} = 'blue'\"}, \"alias\": null, \"offset_window\": null, \"offset_to_grain\": null}]}, \"filter\": null, \"metadata\": null, \"meta\": {}, \"tags\": [], \"config\": {\"enabled\": true, \"group\": null}, \"unrendered_config\": {}, \"sources\": [], \"depends_on\": {\"macros\": [], \"nodes\": [\"metric.test.customers\"]}, \"refs\": [], \"metrics\": [], \"created_at\": 1697057377.5861351, \"group\": null}}, \"groups\": {}, \"selectors\": {}, \"disabled\": {\"model.test.disabled_model\": [{\"database\": \"dbt\", \"schema\": \"test16970573770617803847_test_previous_version_state\", \"name\": \"disabled_model\", \"resource_type\": \"model\", \"package_name\": \"test\", \"path\": \"disabled_model.sql\", \"original_file_path\": \"models/disabled_model.sql\", \"unique_id\": \"model.test.disabled_model\", \"fqn\": [\"test\", \"disabled_model\"], \"alias\": \"disabled_model\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"597106d23ce34e3cd2430588e5c1cf474ebdd138fc47e09b925a4ab258a27acc\"}, \"config\": {\"enabled\": false, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"view\", \"incremental_strategy\": null, \"persist_docs\": {}, \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": null, \"on_schema_change\": \"ignore\", \"on_configuration_change\": \"apply\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"contract\": {\"enforced\": false}, \"post-hook\": [], \"pre-hook\": []}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {\"enabled\": false}, \"created_at\": 1697057377.4547698, \"config_call_dict\": {\"enabled\": false}, \"relation_name\": \"\\\"dbt\\\".\\\"test16970573770617803847_test_previous_version_state\\\".\\\"disabled_model\\\"\", \"raw_code\": \"{{ config(enabled=False) }}\\nselect 2 as id\", \"language\": \"sql\", \"refs\": [], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [], \"nodes\": []}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"checksum\": null}, \"access\": \"protected\", \"constraints\": [], \"version\": null, \"latest_version\": null, \"deprecation_date\": null, \"defer_relation\": null}], \"snapshot.test.disabled_snapshot_seed\": [{\"database\": \"dbt\", \"schema\": \"test16970573770617803847_test_previous_version_state\", \"name\": \"disabled_snapshot_seed\", \"resource_type\": \"snapshot\", \"package_name\": \"test\", \"path\": \"disabled_snapshot_seed.sql\", \"original_file_path\": \"snapshots/disabled_snapshot_seed.sql\", \"unique_id\": \"snapshot.test.disabled_snapshot_seed\", \"fqn\": [\"test\", \"disabled_snapshot_seed\", \"disabled_snapshot_seed\"], \"alias\": \"disabled_snapshot_seed\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"fe76c9dd437341c9e82a0f2a8baf3148f961b768eaa0a4410cd27d3c071bd617\"}, \"config\": {\"enabled\": false, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"snapshot\", \"incremental_strategy\": null, \"persist_docs\": {}, \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": \"id\", \"on_schema_change\": \"ignore\", \"on_configuration_change\": \"apply\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"contract\": {\"enforced\": false}, \"strategy\": \"check\", \"target_schema\": \"test16970573770617803847_test_previous_version_state\", \"target_database\": null, \"updated_at\": null, \"check_cols\": \"all\", \"post-hook\": [], \"pre-hook\": []}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {\"unique_key\": \"id\", \"strategy\": \"check\", \"check_cols\": \"all\", \"target_schema\": \"test16970573770617803847_test_previous_version_state\", \"enabled\": false}, \"created_at\": 1697057377.4774349, \"config_call_dict\": {\"unique_key\": \"id\", \"strategy\": \"check\", \"check_cols\": \"all\", \"target_schema\": \"test16970573770617803847_test_previous_version_state\", \"enabled\": false}, \"relation_name\": \"\\\"dbt\\\".\\\"test16970573770617803847_test_previous_version_state\\\".\\\"disabled_snapshot_seed\\\"\", \"raw_code\": \"\\n{{\\n    config(\\n      unique_key='id',\\n      strategy='check',\\n      check_cols='all',\\n      target_schema=schema,\\n      enabled=False,\\n    )\\n}}\\nselect * from {{ ref('my_seed') }}\\n\", \"language\": \"sql\", \"refs\": [{\"name\": \"my_seed\", \"package\": null, \"version\": null}], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [], \"nodes\": []}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"checksum\": null}, \"defer_relation\": null}], \"analysis.test.disabled_al\": [{\"database\": \"dbt\", \"schema\": \"test16970573770617803847_test_previous_version_state\", \"name\": \"disabled_al\", \"resource_type\": \"analysis\", \"package_name\": \"test\", \"path\": \"analysis/disabled_al.sql\", \"original_file_path\": \"analyses/disabled_al.sql\", \"unique_id\": \"analysis.test.disabled_al\", \"fqn\": [\"test\", \"analysis\", \"disabled_al\"], \"alias\": \"disabled_al\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"32d36ad6cff0786eb562440ba60ef6c9b9a7f4c282dfb7a52eaf19d36370f0e1\"}, \"config\": {\"enabled\": false, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"view\", \"incremental_strategy\": null, \"persist_docs\": {}, \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": null, \"on_schema_change\": \"ignore\", \"on_configuration_change\": \"apply\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"contract\": {\"enforced\": false}, \"post-hook\": [], \"pre-hook\": []}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {\"enabled\": false}, \"created_at\": 1697057377.489575, \"config_call_dict\": {\"enabled\": false}, \"relation_name\": null, \"raw_code\": \"{{ config(enabled=False) }}\\nselect 9 as id\", \"language\": \"sql\", \"refs\": [], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [], \"nodes\": []}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"checksum\": null}}], \"test.test.disabled_just_my\": [{\"database\": \"dbt\", \"schema\": \"test16970573770617803847_test_previous_version_state_dbt_test__audit\", \"name\": \"disabled_just_my\", \"resource_type\": \"test\", \"package_name\": \"test\", \"path\": \"disabled_just_my.sql\", \"original_file_path\": \"tests/disabled_just_my.sql\", \"unique_id\": \"test.test.disabled_just_my\", \"fqn\": [\"test\", \"disabled_just_my\"], \"alias\": \"disabled_just_my\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"4f2268fd89a3b4ef899264ada6d7aa33603671cbc5d5acead7dc2eadf1add985\"}, \"config\": {\"enabled\": false, \"alias\": null, \"schema\": \"dbt_test__audit\", \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"test\", \"severity\": \"ERROR\", \"store_failures\": null, \"where\": null, \"limit\": null, \"fail_calc\": \"count(*)\", \"warn_if\": \"!= 0\", \"error_if\": \"!= 0\"}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {\"enabled\": false}, \"created_at\": 1697057377.5060952, \"config_call_dict\": {\"enabled\": false}, \"relation_name\": null, \"raw_code\": \"{{ config(enabled=False) }}\\n\\nselect * from {{ ref('my_model') }}\\nwhere false\", \"language\": \"sql\", \"refs\": [{\"name\": \"my_model\", \"package\": null, \"version\": null}], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [], \"nodes\": []}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"checksum\": null}}], \"test.test.disabled_check_nothing_my_model_.f2c6a72d37\": [{\"test_metadata\": {\"name\": \"disabled_check_nothing\", \"kwargs\": {\"model\": \"{{ get_where_subquery(ref('my_model')) }}\"}, \"namespace\": null}, \"database\": \"dbt\", \"schema\": \"test16970573770617803847_test_previous_version_state_dbt_test__audit\", \"name\": \"disabled_check_nothing_my_model_\", \"resource_type\": \"test\", \"package_name\": \"test\", \"path\": \"disabled_check_nothing_my_model_.sql\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"test.test.disabled_check_nothing_my_model_.f2c6a72d37\", \"fqn\": [\"test\", \"disabled_check_nothing_my_model_\"], \"alias\": \"disabled_check_nothing_my_model_\", \"checksum\": {\"name\": \"none\", \"checksum\": \"\"}, \"config\": {\"enabled\": false, \"alias\": null, \"schema\": \"dbt_test__audit\", \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"test\", \"severity\": \"ERROR\", \"store_failures\": null, \"where\": null, \"limit\": null, \"fail_calc\": \"count(*)\", \"warn_if\": \"!= 0\", \"error_if\": \"!= 0\"}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {\"enabled\": false}, \"created_at\": 1697057377.558094, \"config_call_dict\": {\"enabled\": false}, \"relation_name\": null, \"raw_code\": \"{{ test_disabled_check_nothing(**_dbt_generic_test_kwargs) }}\", \"language\": \"sql\", \"refs\": [{\"name\": \"my_model\", \"package\": null, \"version\": null}], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [\"macro.test.test_disabled_check_nothing\", \"macro.dbt.get_where_subquery\"], \"nodes\": []}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"checksum\": null}, \"column_name\": null, \"file_key_name\": \"models.my_model\", \"attached_node\": \"model.test.my_model\"}], \"exposure.test.disabled_exposure\": [{\"name\": \"disabled_exposure\", \"resource_type\": \"exposure\", \"package_name\": \"test\", \"path\": \"schema.yml\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"exposure.test.disabled_exposure\", \"fqn\": [\"test\", \"disabled_exposure\"], \"type\": \"dashboard\", \"owner\": {\"email\": \"something@example.com\", \"name\": null}, \"description\": \"\", \"label\": null, \"maturity\": null, \"meta\": {}, \"tags\": [], \"config\": {\"enabled\": false}, \"unrendered_config\": {\"enabled\": false}, \"url\": null, \"depends_on\": {\"macros\": [], \"nodes\": []}, \"refs\": [{\"name\": \"my_model\", \"package\": null, \"version\": null}], \"sources\": [], \"metrics\": [], \"created_at\": 1697057377.5790222}], \"metric.test.disabled_metric\": [{\"name\": \"disabled_metric\", \"resource_type\": \"metric\", \"package_name\": \"test\", \"path\": \"schema.yml\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"metric.test.disabled_metric\", \"fqn\": [\"test\", \"disabled_metric\"], \"description\": \"\", \"label\": \"Count records\", \"type\": \"simple\", \"type_params\": {\"measure\": {\"name\": \"customers\", \"filter\": null, \"alias\": null, \"join_to_timespine\": false, \"fill_nulls_with\": null}, \"input_measures\": [], \"numerator\": null, \"denominator\": null, \"expr\": null, \"window\": null, \"grain_to_date\": null, \"metrics\": []}, \"filter\": {\"where_sql_template\": \"{{ Dimension('id__favorite_color') }} = 'blue'\"}, \"metadata\": null, \"meta\": {}, \"tags\": [], \"config\": {\"enabled\": false, \"group\": null}, \"unrendered_config\": {\"enabled\": false}, \"sources\": [], \"depends_on\": {\"macros\": [], \"nodes\": []}, \"refs\": [], \"metrics\": [], \"created_at\": 1697057377.584552, \"group\": null}], \"seed.test.disabled_seed\": [{\"database\": \"dbt\", \"schema\": \"test16970573770617803847_test_previous_version_state\", \"name\": \"disabled_seed\", \"resource_type\": \"seed\", \"package_name\": \"test\", \"path\": \"disabled_seed.csv\", \"original_file_path\": \"seeds/disabled_seed.csv\", \"unique_id\": \"seed.test.disabled_seed\", \"fqn\": [\"test\", \"disabled_seed\"], \"alias\": \"disabled_seed\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"31fddd8ec40c6aba6a3a8e7d83fedea2fd0a56c47b64ea3df1847ec1b018e2d1\"}, \"config\": {\"enabled\": false, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"seed\", \"incremental_strategy\": null, \"persist_docs\": {}, \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": null, \"on_schema_change\": \"ignore\", \"on_configuration_change\": \"apply\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"contract\": {\"enforced\": false}, \"quote_columns\": null, \"post-hook\": [], \"pre-hook\": []}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": \"test://models/schema.yml\", \"build_path\": null, \"deferred\": false, \"unrendered_config\": {\"enabled\": false}, \"created_at\": 1697057377.5646772, \"config_call_dict\": {}, \"relation_name\": \"\\\"dbt\\\".\\\"test16970573770617803847_test_previous_version_state\\\".\\\"disabled_seed\\\"\", \"raw_code\": \"\", \"root_path\": \"/private/var/folders/79/5290gpvn3lx5jdryk4844rm80000gn/T/pytest-of-quigleymalcolm/pytest-271/project0\", \"depends_on\": {\"macros\": []}, \"defer_relation\": null}], \"source.test.my_source.disabled_table\": [{\"database\": \"dbt\", \"schema\": \"my_source\", \"name\": \"disabled_table\", \"resource_type\": \"source\", \"package_name\": \"test\", \"path\": \"models/schema.yml\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"source.test.my_source.disabled_table\", \"fqn\": [\"test\", \"my_source\", \"disabled_table\"], \"source_name\": \"my_source\", \"source_description\": \"My source\", \"loader\": \"a_loader\", \"identifier\": \"disabled_table\", \"quoting\": {\"database\": null, \"schema\": null, \"identifier\": null, \"column\": null}, \"loaded_at_field\": null, \"freshness\": {\"warn_after\": {\"count\": null, \"period\": null}, \"error_after\": {\"count\": null, \"period\": null}, \"filter\": null}, \"external\": null, \"description\": \"Disabled table\", \"columns\": {}, \"meta\": {}, \"source_meta\": {}, \"tags\": [], \"config\": {\"enabled\": false}, \"patch_path\": null, \"unrendered_config\": {\"enabled\": false}, \"relation_name\": \"\\\"dbt\\\".\\\"my_source\\\".\\\"disabled_table\\\"\", \"created_at\": 1697057377.5942788}]}, \"parent_map\": {\"model.test.my_model\": [], \"model.test.metricflow_time_spine\": [], \"snapshot.test.snapshot_seed\": [\"seed.test.my_seed\"], \"analysis.test.a\": [], \"test.test.just_my\": [\"model.test.my_model\"], \"seed.test.my_seed\": [], \"test.test.not_null_my_model_id.43e0e9183a\": [\"model.test.my_model\"], \"test.test.check_nothing_my_model_.d5a5e66110\": [\"model.test.my_model\"], \"source.test.my_source.my_table\": [], \"exposure.test.simple_exposure\": [\"model.test.my_model\", \"source.test.my_source.my_table\"], \"metric.test.blue_customers_post_2010\": [\"semantic_model.test.semantic_people\"], \"metric.test.customers\": [\"semantic_model.test.semantic_people\"], \"metric.test.ratio_of_blue_customers_to_red_customers\": [\"metric.test.customers\"], \"metric.test.doubled_blue_customers\": [\"metric.test.customers\"], \"semantic_model.test.semantic_people\": [\"model.test.my_model\"]}, \"child_map\": {\"model.test.my_model\": [\"exposure.test.simple_exposure\", \"semantic_model.test.semantic_people\", \"test.test.check_nothing_my_model_.d5a5e66110\", \"test.test.just_my\", \"test.test.not_null_my_model_id.43e0e9183a\"], \"model.test.metricflow_time_spine\": [], \"snapshot.test.snapshot_seed\": [], \"analysis.test.a\": [], \"test.test.just_my\": [], \"seed.test.my_seed\": [\"snapshot.test.snapshot_seed\"], \"test.test.not_null_my_model_id.43e0e9183a\": [], \"test.test.check_nothing_my_model_.d5a5e66110\": [], \"source.test.my_source.my_table\": [\"exposure.test.simple_exposure\"], \"exposure.test.simple_exposure\": [], \"metric.test.blue_customers_post_2010\": [], \"metric.test.customers\": [\"metric.test.doubled_blue_customers\", \"metric.test.ratio_of_blue_customers_to_red_customers\"], \"metric.test.ratio_of_blue_customers_to_red_customers\": [], \"metric.test.doubled_blue_customers\": [], \"semantic_model.test.semantic_people\": [\"metric.test.blue_customers_post_2010\", \"metric.test.customers\"]}, \"group_map\": {}, \"semantic_models\": {\"semantic_model.test.semantic_people\": {\"name\": \"semantic_people\", \"resource_type\": \"semantic_model\", \"package_name\": \"test\", \"path\": \"schema.yml\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"semantic_model.test.semantic_people\", \"fqn\": [\"test\", \"semantic_people\"], \"model\": \"ref('my_model')\", \"node_relation\": {\"alias\": \"my_model\", \"schema_name\": \"test16970573770617803847_test_previous_version_state\", \"database\": \"dbt\", \"relation_name\": \"\\\"dbt\\\".\\\"test16970573770617803847_test_previous_version_state\\\".\\\"my_model\\\"\"}, \"description\": null, \"label\": null, \"defaults\": {\"agg_time_dimension\": \"created_at\"}, \"entities\": [{\"name\": \"id\", \"type\": \"primary\", \"description\": null, \"label\": null, \"role\": null, \"expr\": null}], \"measures\": [{\"name\": \"years_tenure\", \"agg\": \"sum\", \"description\": null, \"label\": null, \"create_metric\": false, \"expr\": \"tenure\", \"agg_params\": null, \"non_additive_dimension\": null, \"agg_time_dimension\": null}, {\"name\": \"people\", \"agg\": \"count\", \"description\": null, \"label\": null, \"create_metric\": false, \"expr\": \"id\", \"agg_params\": null, \"non_additive_dimension\": null, \"agg_time_dimension\": null}, {\"name\": \"customers\", \"agg\": \"count\", \"description\": null, \"label\": null, \"create_metric\": false, \"expr\": \"id\", \"agg_params\": null, \"non_additive_dimension\": null, \"agg_time_dimension\": null}], \"dimensions\": [{\"name\": \"favorite_color\", \"type\": \"categorical\", \"description\": null, \"label\": null, \"is_partition\": false, \"type_params\": null, \"expr\": null, \"metadata\": null}, {\"name\": \"created_at\", \"type\": \"time\", \"description\": null, \"label\": null, \"is_partition\": false, \"type_params\": {\"time_granularity\": \"day\", \"validity_params\": null}, \"expr\": null, \"metadata\": null}], \"metadata\": null, \"depends_on\": {\"macros\": [], \"nodes\": [\"model.test.my_model\"]}, \"refs\": [{\"name\": \"my_model\", \"package\": null, \"version\": null}], \"created_at\": 1697057377.5929039, \"config\": {\"enabled\": true}, \"primary_entity\": null}}}\n"
  },
  {
    "path": "tests/functional/artifacts/data/state/v11/manifest.json",
    "content": "{\"metadata\": {\"dbt_schema_version\": \"https://schemas.getdbt.com/dbt/manifest/v11.json\", \"dbt_version\": \"1.7.6\", \"generated_at\": \"2024-01-30T11:27:16.415331Z\", \"invocation_id\": \"05b2865a-32e1-4aae-bf19-bace9c34ecf6\", \"env\": {}, \"project_name\": \"test\", \"project_id\": \"098f6bcd4621d373cade4e832627b4f6\", \"user_id\": null, \"send_anonymous_usage_stats\": false, \"adapter_type\": \"postgres\"}, \"nodes\": {\"model.test.my_model\": {\"database\": \"dbt\", \"schema\": \"test17066140326720908695_test_previous_version_state\", \"name\": \"my_model\", \"resource_type\": \"model\", \"package_name\": \"test\", \"path\": \"my_model.sql\", \"original_file_path\": \"models/my_model.sql\", \"unique_id\": \"model.test.my_model\", \"fqn\": [\"test\", \"my_model\"], \"alias\": \"my_model\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"3ea0f972fa1b56aa2dc2f56ee784b6a5796312f9a813d59ae70fd8855f10d16d\"}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"view\", \"incremental_strategy\": null, \"persist_docs\": {}, \"post-hook\": [], \"pre-hook\": [], \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": null, \"on_schema_change\": \"ignore\", \"on_configuration_change\": \"apply\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"contract\": {\"enforced\": false, \"alias_types\": true}, \"access\": \"protected\"}, \"tags\": [], \"description\": \"Example model\", \"columns\": {\"id\": {\"name\": \"id\", \"description\": \"\", \"meta\": {}, \"data_type\": null, \"constraints\": [], \"quote\": null, \"tags\": []}}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": \"test://models/schema.yml\", \"build_path\": null, \"deferred\": false, \"unrendered_config\": {}, \"created_at\": 1706614035.6203048, \"relation_name\": \"\\\"dbt\\\".\\\"test17066140326720908695_test_previous_version_state\\\".\\\"my_model\\\"\", \"raw_code\": \"select 1 as id\", \"language\": \"sql\", \"refs\": [], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [], \"nodes\": []}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"alias_types\": true, \"checksum\": null}, \"access\": \"protected\", \"constraints\": [], \"version\": null, \"latest_version\": null, \"deprecation_date\": null}, \"model.test.metricflow_time_spine\": {\"database\": \"dbt\", \"schema\": \"test17066140326720908695_test_previous_version_state\", \"name\": \"metricflow_time_spine\", \"resource_type\": \"model\", \"package_name\": \"test\", \"path\": \"metricflow_time_spine.sql\", \"original_file_path\": \"models/metricflow_time_spine.sql\", \"unique_id\": \"model.test.metricflow_time_spine\", \"fqn\": [\"test\", \"metricflow_time_spine\"], \"alias\": \"metricflow_time_spine\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"954d9b349821edb5558a373119a7d91eeac9e620aaa96cd112c0d14bab729fdb\"}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"view\", \"incremental_strategy\": null, \"persist_docs\": {}, \"post-hook\": [], \"pre-hook\": [], \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": null, \"on_schema_change\": \"ignore\", \"on_configuration_change\": \"apply\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"contract\": {\"enforced\": false, \"alias_types\": true}, \"access\": \"protected\"}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {}, \"created_at\": 1706614035.2472441, \"relation_name\": \"\\\"dbt\\\".\\\"test17066140326720908695_test_previous_version_state\\\".\\\"metricflow_time_spine\\\"\", \"raw_code\": \"SELECT to_date('02/20/2023', 'mm/dd/yyyy') as date_day\", \"language\": \"sql\", \"refs\": [], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [], \"nodes\": []}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"alias_types\": true, \"checksum\": null}, \"access\": \"protected\", \"constraints\": [], \"version\": null, \"latest_version\": null, \"deprecation_date\": null}, \"snapshot.test.snapshot_seed\": {\"database\": \"dbt\", \"schema\": \"test17066140326720908695_test_previous_version_state\", \"name\": \"snapshot_seed\", \"resource_type\": \"snapshot\", \"package_name\": \"test\", \"path\": \"snapshot_seed.sql\", \"original_file_path\": \"snapshots/snapshot_seed.sql\", \"unique_id\": \"snapshot.test.snapshot_seed\", \"fqn\": [\"test\", \"snapshot_seed\", \"snapshot_seed\"], \"alias\": \"snapshot_seed\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"5fc998f39655f8fe52443a919e749b6e23883ef90202b040412baac13c6bfe18\"}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"snapshot\", \"incremental_strategy\": null, \"persist_docs\": {}, \"post-hook\": [], \"pre-hook\": [], \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": \"id\", \"on_schema_change\": \"ignore\", \"on_configuration_change\": \"apply\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"contract\": {\"enforced\": false, \"alias_types\": true}, \"strategy\": \"check\", \"target_schema\": \"test17066140326720908695_test_previous_version_state\", \"target_database\": null, \"updated_at\": null, \"check_cols\": \"all\"}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {\"unique_key\": \"id\", \"strategy\": \"check\", \"check_cols\": \"all\", \"target_schema\": \"test17066140326720908695_test_previous_version_state\"}, \"created_at\": 1706614035.331658, \"relation_name\": \"\\\"dbt\\\".\\\"test17066140326720908695_test_previous_version_state\\\".\\\"snapshot_seed\\\"\", \"raw_code\": \"\\n{{\\n    config(\\n      unique_key='id',\\n      strategy='check',\\n      check_cols='all',\\n      target_schema=schema,\\n    )\\n}}\\nselect * from {{ ref('my_seed') }}\\n\", \"language\": \"sql\", \"refs\": [{\"name\": \"my_seed\", \"package\": null, \"version\": null}], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [], \"nodes\": [\"seed.test.my_seed\"]}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"alias_types\": true, \"checksum\": null}}, \"analysis.test.a\": {\"database\": \"dbt\", \"schema\": \"test17066140326720908695_test_previous_version_state\", \"name\": \"a\", \"resource_type\": \"analysis\", \"package_name\": \"test\", \"path\": \"analysis/a.sql\", \"original_file_path\": \"analyses/a.sql\", \"unique_id\": \"analysis.test.a\", \"fqn\": [\"test\", \"analysis\", \"a\"], \"alias\": \"a\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"a389c282f569f0bbdc2a8a4f174dea746c28582fdaf2048d31d9226af9feab23\"}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"view\", \"incremental_strategy\": null, \"persist_docs\": {}, \"post-hook\": [], \"pre-hook\": [], \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": null, \"on_schema_change\": \"ignore\", \"on_configuration_change\": \"apply\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"contract\": {\"enforced\": false, \"alias_types\": true}}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {}, \"created_at\": 1706614035.426197, \"relation_name\": null, \"raw_code\": \"select 4 as id\", \"language\": \"sql\", \"refs\": [], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [], \"nodes\": []}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"alias_types\": true, \"checksum\": null}}, \"test.test.just_my\": {\"database\": \"dbt\", \"schema\": \"test17066140326720908695_test_previous_version_state_dbt_test__audit\", \"name\": \"just_my\", \"resource_type\": \"test\", \"package_name\": \"test\", \"path\": \"just_my.sql\", \"original_file_path\": \"tests/just_my.sql\", \"unique_id\": \"test.test.just_my\", \"fqn\": [\"test\", \"just_my\"], \"alias\": \"just_my\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"744889a2e2d9ce380619265e1217d7ccf6e6ca896c048d42ebe0f9cfb74d7156\"}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": \"dbt_test__audit\", \"database\": null, \"tags\": [\"data_test_tag\"], \"meta\": {}, \"group\": null, \"materialized\": \"test\", \"severity\": \"ERROR\", \"store_failures\": null, \"store_failures_as\": null, \"where\": null, \"limit\": null, \"fail_calc\": \"count(*)\", \"warn_if\": \"!= 0\", \"error_if\": \"!= 0\"}, \"tags\": [\"data_test_tag\"], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {\"tags\": [\"data_test_tag\"]}, \"created_at\": 1706614035.493541, \"relation_name\": null, \"raw_code\": \"{{ config(tags = ['data_test_tag']) }}\\n\\nselect * from {{ ref('my_model') }}\\nwhere false\", \"language\": \"sql\", \"refs\": [{\"name\": \"my_model\", \"package\": null, \"version\": null}], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [], \"nodes\": [\"model.test.my_model\"]}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"alias_types\": true, \"checksum\": null}}, \"seed.test.my_seed\": {\"database\": \"dbt\", \"schema\": \"test17066140326720908695_test_previous_version_state\", \"name\": \"my_seed\", \"resource_type\": \"seed\", \"package_name\": \"test\", \"path\": \"my_seed.csv\", \"original_file_path\": \"seeds/my_seed.csv\", \"unique_id\": \"seed.test.my_seed\", \"fqn\": [\"test\", \"my_seed\"], \"alias\": \"my_seed\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"f7ede83f36165ac6b7a047aa2c3f212dff385bfa9f35f395108cd06fc8e96943\"}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"seed\", \"incremental_strategy\": null, \"persist_docs\": {}, \"post-hook\": [], \"pre-hook\": [], \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": null, \"on_schema_change\": \"ignore\", \"on_configuration_change\": \"apply\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"contract\": {\"enforced\": false, \"alias_types\": true}, \"delimiter\": \",\", \"quote_columns\": null}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {}, \"created_at\": 1706614035.5665338, \"relation_name\": \"\\\"dbt\\\".\\\"test17066140326720908695_test_previous_version_state\\\".\\\"my_seed\\\"\", \"raw_code\": \"\", \"root_path\": \"/private/var/folders/7h/hj5_fw9j291c58hwfdvy5xbm0000gp/T/pytest-of-jerco/pytest-10/project0\", \"depends_on\": {\"macros\": []}}, \"test.test.not_null_my_model_id.43e0e9183a\": {\"test_metadata\": {\"name\": \"not_null\", \"kwargs\": {\"column_name\": \"id\", \"model\": \"{{ get_where_subquery(ref('my_model')) }}\"}, \"namespace\": null}, \"database\": \"dbt\", \"schema\": \"test17066140326720908695_test_previous_version_state_dbt_test__audit\", \"name\": \"not_null_my_model_id\", \"resource_type\": \"test\", \"package_name\": \"test\", \"path\": \"not_null_my_model_id.sql\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"test.test.not_null_my_model_id.43e0e9183a\", \"fqn\": [\"test\", \"not_null_my_model_id\"], \"alias\": \"not_null_my_model_id\", \"checksum\": {\"name\": \"none\", \"checksum\": \"\"}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": \"dbt_test__audit\", \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"test\", \"severity\": \"ERROR\", \"store_failures\": null, \"store_failures_as\": null, \"where\": null, \"limit\": null, \"fail_calc\": \"count(*)\", \"warn_if\": \"!= 0\", \"error_if\": \"!= 0\"}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {}, \"created_at\": 1706614035.668334, \"relation_name\": null, \"raw_code\": \"{{ test_not_null(**_dbt_generic_test_kwargs) }}\", \"language\": \"sql\", \"refs\": [{\"name\": \"my_model\", \"package\": null, \"version\": null}], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [\"macro.dbt.test_not_null\"], \"nodes\": [\"model.test.my_model\"]}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"alias_types\": true, \"checksum\": null}, \"column_name\": \"id\", \"file_key_name\": \"models.my_model\", \"attached_node\": \"model.test.my_model\"}, \"test.test.check_nothing_my_model_.d5a5e66110\": {\"test_metadata\": {\"name\": \"check_nothing\", \"kwargs\": {\"model\": \"{{ get_where_subquery(ref('my_model')) }}\"}, \"namespace\": null}, \"database\": \"dbt\", \"schema\": \"test17066140326720908695_test_previous_version_state_dbt_test__audit\", \"name\": \"check_nothing_my_model_\", \"resource_type\": \"test\", \"package_name\": \"test\", \"path\": \"check_nothing_my_model_.sql\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"test.test.check_nothing_my_model_.d5a5e66110\", \"fqn\": [\"test\", \"check_nothing_my_model_\"], \"alias\": \"check_nothing_my_model_\", \"checksum\": {\"name\": \"none\", \"checksum\": \"\"}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": \"dbt_test__audit\", \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"test\", \"severity\": \"ERROR\", \"store_failures\": null, \"store_failures_as\": null, \"where\": null, \"limit\": null, \"fail_calc\": \"count(*)\", \"warn_if\": \"!= 0\", \"error_if\": \"!= 0\"}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {}, \"created_at\": 1706614035.6698759, \"relation_name\": null, \"raw_code\": \"{{ test_check_nothing(**_dbt_generic_test_kwargs) }}\", \"language\": \"sql\", \"refs\": [{\"name\": \"my_model\", \"package\": null, \"version\": null}], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [\"macro.test.test_check_nothing\", \"macro.dbt.get_where_subquery\"], \"nodes\": [\"model.test.my_model\"]}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"alias_types\": true, \"checksum\": null}, \"column_name\": null, \"file_key_name\": \"models.my_model\", \"attached_node\": \"model.test.my_model\"}}, \"sources\": {\"source.test.my_source.my_table\": {\"database\": \"dbt\", \"schema\": \"my_source\", \"name\": \"my_table\", \"resource_type\": \"source\", \"package_name\": \"test\", \"path\": \"models/schema.yml\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"source.test.my_source.my_table\", \"fqn\": [\"test\", \"my_source\", \"my_table\"], \"source_name\": \"my_source\", \"source_description\": \"My source\", \"loader\": \"a_loader\", \"identifier\": \"my_seed\", \"quoting\": {\"database\": null, \"schema\": null, \"identifier\": null, \"column\": null}, \"loaded_at_field\": null, \"freshness\": {\"warn_after\": {\"count\": null, \"period\": null}, \"error_after\": {\"count\": null, \"period\": null}, \"filter\": null}, \"external\": null, \"description\": \"My table\", \"columns\": {}, \"meta\": {}, \"source_meta\": {}, \"tags\": [], \"config\": {\"enabled\": true}, \"patch_path\": null, \"unrendered_config\": {}, \"relation_name\": \"\\\"dbt\\\".\\\"my_source\\\".\\\"my_seed\\\"\", \"created_at\": 1706614035.938528}}, \"macros\": {\"macro.test.test_check_nothing\": {\"name\": \"test_check_nothing\", \"resource_type\": \"macro\", \"package_name\": \"test\", \"path\": \"macros/dummy_test.sql\", \"original_file_path\": \"macros/dummy_test.sql\", \"unique_id\": \"macro.test.test_check_nothing\", \"macro_sql\": \"{% test check_nothing(model) %}\\n-- a silly test to make sure that table-level tests show up in the manifest\\n-- without a column_name field\\n\\nselect 0\\n\\n{% endtest %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.49347, \"supported_languages\": null}, \"macro.test.test_disabled_check_nothing\": {\"name\": \"test_disabled_check_nothing\", \"resource_type\": \"macro\", \"package_name\": \"test\", \"path\": \"macros/disabled_dummy_test.sql\", \"original_file_path\": \"macros/disabled_dummy_test.sql\", \"unique_id\": \"macro.test.test_disabled_check_nothing\", \"macro_sql\": \"{% test disabled_check_nothing(model) %}\\n-- a silly test to make sure that table-level tests show up in the manifest\\n-- without a column_name field\\n\\n{{ config(enabled=False) }}\\nselect 0\\n\\n{% endtest %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.493846, \"supported_languages\": null}, \"macro.test.do_nothing\": {\"name\": \"do_nothing\", \"resource_type\": \"macro\", \"package_name\": \"test\", \"path\": \"macros/do_nothing.sql\", \"original_file_path\": \"macros/do_nothing.sql\", \"unique_id\": \"macro.test.do_nothing\", \"macro_sql\": \"{% macro do_nothing(foo2, bar2) %}\\n    select\\n        '{{ foo2 }}' as foo2,\\n        '{{ bar2 }}' as bar2\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.494155, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__current_timestamp\": {\"name\": \"postgres__current_timestamp\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/timestamps.sql\", \"original_file_path\": \"macros/timestamps.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__current_timestamp\", \"macro_sql\": \"{% macro postgres__current_timestamp() -%}\\n    now()\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.4946299, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__snapshot_string_as_time\": {\"name\": \"postgres__snapshot_string_as_time\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/timestamps.sql\", \"original_file_path\": \"macros/timestamps.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__snapshot_string_as_time\", \"macro_sql\": \"{% macro postgres__snapshot_string_as_time(timestamp) -%}\\n    {%- set result = \\\"'\\\" ~ timestamp ~ \\\"'::timestamp without time zone\\\" -%}\\n    {{ return(result) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.494959, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__snapshot_get_time\": {\"name\": \"postgres__snapshot_get_time\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/timestamps.sql\", \"original_file_path\": \"macros/timestamps.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__snapshot_get_time\", \"macro_sql\": \"{% macro postgres__snapshot_get_time() -%}\\n  {{ current_timestamp() }}::timestamp without time zone\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.495212, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__current_timestamp_backcompat\": {\"name\": \"postgres__current_timestamp_backcompat\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/timestamps.sql\", \"original_file_path\": \"macros/timestamps.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__current_timestamp_backcompat\", \"macro_sql\": \"{% macro postgres__current_timestamp_backcompat() %}\\n    current_timestamp::{{ type_timestamp() }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.type_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.4953868, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__current_timestamp_in_utc_backcompat\": {\"name\": \"postgres__current_timestamp_in_utc_backcompat\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/timestamps.sql\", \"original_file_path\": \"macros/timestamps.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__current_timestamp_in_utc_backcompat\", \"macro_sql\": \"{% macro postgres__current_timestamp_in_utc_backcompat() %}\\n    (current_timestamp at time zone 'utc')::{{ type_timestamp() }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.type_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.495561, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_catalog_relations\": {\"name\": \"postgres__get_catalog_relations\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/catalog.sql\", \"original_file_path\": \"macros/catalog.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_catalog_relations\", \"macro_sql\": \"{% macro postgres__get_catalog_relations(information_schema, relations) -%}\\n  {%- call statement('catalog', fetch_result=True) -%}\\n\\n    {#\\n      If the user has multiple databases set and the first one is wrong, this will fail.\\n      But we won't fail in the case where there are multiple quoting-difference-only dbs, which is better.\\n    #}\\n    {% set database = information_schema.database %}\\n    {{ adapter.verify_database(database) }}\\n\\n    select\\n        '{{ database }}' as table_database,\\n        sch.nspname as table_schema,\\n        tbl.relname as table_name,\\n        case tbl.relkind\\n            when 'v' then 'VIEW'\\n            when 'm' then 'MATERIALIZED VIEW'\\n            else 'BASE TABLE'\\n        end as table_type,\\n        tbl_desc.description as table_comment,\\n        col.attname as column_name,\\n        col.attnum as column_index,\\n        pg_catalog.format_type(col.atttypid, col.atttypmod) as column_type,\\n        col_desc.description as column_comment,\\n        pg_get_userbyid(tbl.relowner) as table_owner\\n\\n    from pg_catalog.pg_namespace sch\\n    join pg_catalog.pg_class tbl on tbl.relnamespace = sch.oid\\n    join pg_catalog.pg_attribute col on col.attrelid = tbl.oid\\n    left outer join pg_catalog.pg_description tbl_desc on (tbl_desc.objoid = tbl.oid and tbl_desc.objsubid = 0)\\n    left outer join pg_catalog.pg_description col_desc on (col_desc.objoid = tbl.oid and col_desc.objsubid = col.attnum)\\n    where (\\n      {%- for relation in relations -%}\\n        {%- if relation.identifier -%}\\n          (upper(sch.nspname) = upper('{{ relation.schema }}') and\\n           upper(tbl.relname) = upper('{{ relation.identifier }}'))\\n        {%- else-%}\\n          upper(sch.nspname) = upper('{{ relation.schema }}')\\n        {%- endif -%}\\n        {%- if not loop.last %} or {% endif -%}\\n      {%- endfor -%}\\n    )\\n      and not pg_is_other_temp_schema(sch.oid) -- not a temporary schema belonging to another session\\n      and tbl.relpersistence in ('p', 'u') -- [p]ermanent table or [u]nlogged table. Exclude [t]emporary tables\\n      and tbl.relkind in ('r', 'v', 'f', 'p', 'm') -- o[r]dinary table, [v]iew, [f]oreign table, [p]artitioned table, [m]aterialized view. Other values are [i]ndex, [S]equence, [c]omposite type, [t]OAST table\\n      and col.attnum > 0 -- negative numbers are used for system columns such as oid\\n      and not col.attisdropped -- column as not been dropped\\n\\n    order by\\n        sch.nspname,\\n        tbl.relname,\\n        col.attnum\\n\\n  {%- endcall -%}\\n\\n  {{ return(load_result('catalog').table) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.498032, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_catalog\": {\"name\": \"postgres__get_catalog\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/catalog.sql\", \"original_file_path\": \"macros/catalog.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_catalog\", \"macro_sql\": \"{% macro postgres__get_catalog(information_schema, schemas) -%}\\n  {%- set relations = [] -%}\\n  {%- for schema in schemas -%}\\n    {%- set dummy = relations.append({'schema': schema}) -%}\\n  {%- endfor -%}\\n  {{ return(postgres__get_catalog_relations(information_schema, relations)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_catalog_relations\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.498621, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_relations\": {\"name\": \"postgres__get_relations\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/relations.sql\", \"original_file_path\": \"macros/relations.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_relations\", \"macro_sql\": \"{% macro postgres__get_relations() -%}\\n\\n  {#\\n      -- in pg_depend, objid is the dependent, refobjid is the referenced object\\n      --  > a pg_depend entry indicates that the referenced object cannot be\\n      --  > dropped without also dropping the dependent object.\\n  #}\\n\\n  {%- call statement('relations', fetch_result=True) -%}\\n    with relation as (\\n        select\\n            pg_rewrite.ev_class as class,\\n            pg_rewrite.oid as id\\n        from pg_rewrite\\n    ),\\n    class as (\\n        select\\n            oid as id,\\n            relname as name,\\n            relnamespace as schema,\\n            relkind as kind\\n        from pg_class\\n    ),\\n    dependency as (\\n        select distinct\\n            pg_depend.objid as id,\\n            pg_depend.refobjid as ref\\n        from pg_depend\\n    ),\\n    schema as (\\n        select\\n            pg_namespace.oid as id,\\n            pg_namespace.nspname as name\\n        from pg_namespace\\n        where nspname != 'information_schema' and nspname not like 'pg\\\\_%'\\n    ),\\n    referenced as (\\n        select\\n            relation.id AS id,\\n            referenced_class.name ,\\n            referenced_class.schema ,\\n            referenced_class.kind\\n        from relation\\n        join class as referenced_class on relation.class=referenced_class.id\\n        where referenced_class.kind in ('r', 'v', 'm')\\n    ),\\n    relationships as (\\n        select\\n            referenced.name as referenced_name,\\n            referenced.schema as referenced_schema_id,\\n            dependent_class.name as dependent_name,\\n            dependent_class.schema as dependent_schema_id,\\n            referenced.kind as kind\\n        from referenced\\n        join dependency on referenced.id=dependency.id\\n        join class as dependent_class on dependency.ref=dependent_class.id\\n        where\\n            (referenced.name != dependent_class.name or\\n             referenced.schema != dependent_class.schema)\\n    )\\n\\n    select\\n        referenced_schema.name as referenced_schema,\\n        relationships.referenced_name as referenced_name,\\n        dependent_schema.name as dependent_schema,\\n        relationships.dependent_name as dependent_name\\n    from relationships\\n    join schema as dependent_schema on relationships.dependent_schema_id=dependent_schema.id\\n    join schema as referenced_schema on relationships.referenced_schema_id=referenced_schema.id\\n    group by referenced_schema, referenced_name, dependent_schema, dependent_name\\n    order by referenced_schema, referenced_name, dependent_schema, dependent_name;\\n\\n  {%- endcall -%}\\n\\n  {{ return(load_result('relations').table) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.4997098, \"supported_languages\": null}, \"macro.dbt_postgres.postgres_get_relations\": {\"name\": \"postgres_get_relations\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/relations.sql\", \"original_file_path\": \"macros/relations.sql\", \"unique_id\": \"macro.dbt_postgres.postgres_get_relations\", \"macro_sql\": \"{% macro postgres_get_relations() %}\\n  {{ return(postgres__get_relations()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_relations\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.499924, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__create_table_as\": {\"name\": \"postgres__create_table_as\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__create_table_as\", \"macro_sql\": \"{% macro postgres__create_table_as(temporary, relation, sql) -%}\\n  {%- set unlogged = config.get('unlogged', default=false) -%}\\n  {%- set sql_header = config.get('sql_header', none) -%}\\n\\n  {{ sql_header if sql_header is not none }}\\n\\n  create {% if temporary -%}\\n    temporary\\n  {%- elif unlogged -%}\\n    unlogged\\n  {%- endif %} table {{ relation }}\\n  {% set contract_config = config.get('contract') %}\\n  {% if contract_config.enforced %}\\n    {{ get_assert_columns_equivalent(sql) }}\\n  {% endif -%}\\n  {% if contract_config.enforced and (not temporary) -%}\\n      {{ get_table_columns_and_constraints() }} ;\\n    insert into {{ relation }} (\\n      {{ adapter.dispatch('get_column_names', 'dbt')() }}\\n    )\\n    {%- set sql = get_select_subquery(sql) %}\\n  {% else %}\\n    as\\n  {% endif %}\\n  (\\n    {{ sql }}\\n  );\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_assert_columns_equivalent\", \"macro.dbt.get_table_columns_and_constraints\", \"macro.dbt.default__get_column_names\", \"macro.dbt.get_select_subquery\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.5139258, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_create_index_sql\": {\"name\": \"postgres__get_create_index_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_create_index_sql\", \"macro_sql\": \"{% macro postgres__get_create_index_sql(relation, index_dict) -%}\\n  {%- set index_config = adapter.parse_index(index_dict) -%}\\n  {%- set comma_separated_columns = \\\", \\\".join(index_config.columns) -%}\\n  {%- set index_name = index_config.render(relation) -%}\\n\\n  create {% if index_config.unique -%}\\n    unique\\n  {%- endif %} index if not exists\\n  \\\"{{ index_name }}\\\"\\n  on {{ relation }} {% if index_config.type -%}\\n    using {{ index_config.type }}\\n  {%- endif %}\\n  ({{ comma_separated_columns }});\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.514729, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__create_schema\": {\"name\": \"postgres__create_schema\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__create_schema\", \"macro_sql\": \"{% macro postgres__create_schema(relation) -%}\\n  {% if relation.database -%}\\n    {{ adapter.verify_database(relation.database) }}\\n  {%- endif -%}\\n  {%- call statement('create_schema') -%}\\n    create schema if not exists {{ relation.without_identifier().include(database=False) }}\\n  {%- endcall -%}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.515243, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__drop_schema\": {\"name\": \"postgres__drop_schema\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__drop_schema\", \"macro_sql\": \"{% macro postgres__drop_schema(relation) -%}\\n  {% if relation.database -%}\\n    {{ adapter.verify_database(relation.database) }}\\n  {%- endif -%}\\n  {%- call statement('drop_schema') -%}\\n    drop schema if exists {{ relation.without_identifier().include(database=False) }} cascade\\n  {%- endcall -%}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.5157518, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_columns_in_relation\": {\"name\": \"postgres__get_columns_in_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_columns_in_relation\", \"macro_sql\": \"{% macro postgres__get_columns_in_relation(relation) -%}\\n  {% call statement('get_columns_in_relation', fetch_result=True) %}\\n      select\\n          column_name,\\n          data_type,\\n          character_maximum_length,\\n          numeric_precision,\\n          numeric_scale\\n\\n      from {{ relation.information_schema('columns') }}\\n      where table_name = '{{ relation.identifier }}'\\n        {% if relation.schema %}\\n        and table_schema = '{{ relation.schema }}'\\n        {% endif %}\\n      order by ordinal_position\\n\\n  {% endcall %}\\n  {% set table = load_result('get_columns_in_relation').table %}\\n  {{ return(sql_convert_columns_in_relation(table)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\", \"macro.dbt.sql_convert_columns_in_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.5165281, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__list_relations_without_caching\": {\"name\": \"postgres__list_relations_without_caching\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__list_relations_without_caching\", \"macro_sql\": \"{% macro postgres__list_relations_without_caching(schema_relation) %}\\n  {% call statement('list_relations_without_caching', fetch_result=True) -%}\\n    select\\n      '{{ schema_relation.database }}' as database,\\n      tablename as name,\\n      schemaname as schema,\\n      'table' as type\\n    from pg_tables\\n    where schemaname ilike '{{ schema_relation.schema }}'\\n    union all\\n    select\\n      '{{ schema_relation.database }}' as database,\\n      viewname as name,\\n      schemaname as schema,\\n      'view' as type\\n    from pg_views\\n    where schemaname ilike '{{ schema_relation.schema }}'\\n    union all\\n    select\\n      '{{ schema_relation.database }}' as database,\\n      matviewname as name,\\n      schemaname as schema,\\n      'materialized_view' as type\\n    from pg_matviews\\n    where schemaname ilike '{{ schema_relation.schema }}'\\n  {% endcall %}\\n  {{ return(load_result('list_relations_without_caching').table) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.5172532, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__information_schema_name\": {\"name\": \"postgres__information_schema_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__information_schema_name\", \"macro_sql\": \"{% macro postgres__information_schema_name(database) -%}\\n  {% if database_name -%}\\n    {{ adapter.verify_database(database_name) }}\\n  {%- endif -%}\\n  information_schema\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.5175521, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__list_schemas\": {\"name\": \"postgres__list_schemas\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__list_schemas\", \"macro_sql\": \"{% macro postgres__list_schemas(database) %}\\n  {% if database -%}\\n    {{ adapter.verify_database(database) }}\\n  {%- endif -%}\\n  {% call statement('list_schemas', fetch_result=True, auto_begin=False) %}\\n    select distinct nspname from pg_namespace\\n  {% endcall %}\\n  {{ return(load_result('list_schemas').table) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.518124, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__check_schema_exists\": {\"name\": \"postgres__check_schema_exists\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__check_schema_exists\", \"macro_sql\": \"{% macro postgres__check_schema_exists(information_schema, schema) -%}\\n  {% if information_schema.database -%}\\n    {{ adapter.verify_database(information_schema.database) }}\\n  {%- endif -%}\\n  {% call statement('check_schema_exists', fetch_result=True, auto_begin=False) %}\\n    select count(*) from pg_namespace where nspname = '{{ schema }}'\\n  {% endcall %}\\n  {{ return(load_result('check_schema_exists').table) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.518896, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__make_relation_with_suffix\": {\"name\": \"postgres__make_relation_with_suffix\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__make_relation_with_suffix\", \"macro_sql\": \"{% macro postgres__make_relation_with_suffix(base_relation, suffix, dstring) %}\\n    {% if dstring %}\\n      {% set dt = modules.datetime.datetime.now() %}\\n      {% set dtstring = dt.strftime(\\\"%H%M%S%f\\\") %}\\n      {% set suffix = suffix ~ dtstring %}\\n    {% endif %}\\n    {% set suffix_length = suffix|length %}\\n    {% set relation_max_name_length = base_relation.relation_max_name_length() %}\\n    {% if suffix_length > relation_max_name_length %}\\n        {% do exceptions.raise_compiler_error('Relation suffix is too long (' ~ suffix_length ~ ' characters). Maximum length is ' ~ relation_max_name_length ~ ' characters.') %}\\n    {% endif %}\\n    {% set identifier = base_relation.identifier[:relation_max_name_length - suffix_length] ~ suffix %}\\n\\n    {{ return(base_relation.incorporate(path={\\\"identifier\\\": identifier })) }}\\n\\n  {% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.520294, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__make_intermediate_relation\": {\"name\": \"postgres__make_intermediate_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__make_intermediate_relation\", \"macro_sql\": \"{% macro postgres__make_intermediate_relation(base_relation, suffix) %}\\n    {{ return(postgres__make_relation_with_suffix(base_relation, suffix, dstring=False)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_relation_with_suffix\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.520627, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__make_temp_relation\": {\"name\": \"postgres__make_temp_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__make_temp_relation\", \"macro_sql\": \"{% macro postgres__make_temp_relation(base_relation, suffix) %}\\n    {% set temp_relation = postgres__make_relation_with_suffix(base_relation, suffix, dstring=True) %}\\n    {{ return(temp_relation.incorporate(path={\\\"schema\\\": none,\\n                                              \\\"database\\\": none})) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_relation_with_suffix\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.521166, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__make_backup_relation\": {\"name\": \"postgres__make_backup_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__make_backup_relation\", \"macro_sql\": \"{% macro postgres__make_backup_relation(base_relation, backup_relation_type, suffix) %}\\n    {% set backup_relation = postgres__make_relation_with_suffix(base_relation, suffix, dstring=False) %}\\n    {{ return(backup_relation.incorporate(type=backup_relation_type)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_relation_with_suffix\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.521612, \"supported_languages\": null}, \"macro.dbt_postgres.postgres_escape_comment\": {\"name\": \"postgres_escape_comment\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres_escape_comment\", \"macro_sql\": \"{% macro postgres_escape_comment(comment) -%}\\n  {% if comment is not string %}\\n    {% do exceptions.raise_compiler_error('cannot escape a non-string: ' ~ comment) %}\\n  {% endif %}\\n  {%- set magic = '$dbt_comment_literal_block$' -%}\\n  {%- if magic in comment -%}\\n    {%- do exceptions.raise_compiler_error('The string ' ~ magic ~ ' is not allowed in comments.') -%}\\n  {%- endif -%}\\n  {{ magic }}{{ comment }}{{ magic }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.5223072, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__alter_relation_comment\": {\"name\": \"postgres__alter_relation_comment\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__alter_relation_comment\", \"macro_sql\": \"{% macro postgres__alter_relation_comment(relation, comment) %}\\n  {% set escaped_comment = postgres_escape_comment(comment) %}\\n  comment on {{ relation.type }} {{ relation }} is {{ escaped_comment }};\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres_escape_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.522679, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__alter_column_comment\": {\"name\": \"postgres__alter_column_comment\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__alter_column_comment\", \"macro_sql\": \"{% macro postgres__alter_column_comment(relation, column_dict) %}\\n  {% set existing_columns = adapter.get_columns_in_relation(relation) | map(attribute=\\\"name\\\") | list %}\\n  {% for column_name in column_dict if (column_name in existing_columns) %}\\n    {% set comment = column_dict[column_name]['description'] %}\\n    {% set escaped_comment = postgres_escape_comment(comment) %}\\n    comment on column {{ relation }}.{{ adapter.quote(column_name) if column_dict[column_name]['quote'] else column_name }} is {{ escaped_comment }};\\n  {% endfor %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres_escape_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.52365, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_show_grant_sql\": {\"name\": \"postgres__get_show_grant_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_show_grant_sql\", \"macro_sql\": \"\\n\\n{%- macro postgres__get_show_grant_sql(relation) -%}\\n  select grantee, privilege_type\\n  from {{ relation.information_schema('role_table_grants') }}\\n      where grantor = current_role\\n        and grantee != current_role\\n        and table_schema = '{{ relation.schema }}'\\n        and table_name = '{{ relation.identifier }}'\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.523999, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__copy_grants\": {\"name\": \"postgres__copy_grants\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__copy_grants\", \"macro_sql\": \"{% macro postgres__copy_grants() %}\\n    {{ return(False) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.524189, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_show_indexes_sql\": {\"name\": \"postgres__get_show_indexes_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_show_indexes_sql\", \"macro_sql\": \"{% macro postgres__get_show_indexes_sql(relation) %}\\n    select\\n        i.relname                                   as name,\\n        m.amname                                    as method,\\n        ix.indisunique                              as \\\"unique\\\",\\n        array_to_string(array_agg(a.attname), ',')  as column_names\\n    from pg_index ix\\n    join pg_class i\\n        on i.oid = ix.indexrelid\\n    join pg_am m\\n        on m.oid=i.relam\\n    join pg_class t\\n        on t.oid = ix.indrelid\\n    join pg_namespace n\\n        on n.oid = t.relnamespace\\n    join pg_attribute a\\n        on a.attrelid = t.oid\\n        and a.attnum = ANY(ix.indkey)\\n    where t.relname = '{{ relation.identifier }}'\\n      and n.nspname = '{{ relation.schema }}'\\n      and t.relkind in ('r', 'm')\\n    group by 1, 2, 3\\n    order by 1, 2, 3\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.524483, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_drop_index_sql\": {\"name\": \"postgres__get_drop_index_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_drop_index_sql\", \"macro_sql\": \"\\n\\n\\n{%- macro postgres__get_drop_index_sql(relation, index_name) -%}\\n    drop index if exists \\\"{{ relation.schema }}\\\".\\\"{{ index_name }}\\\"\\n{%- endmacro -%}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.524713, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_incremental_default_sql\": {\"name\": \"postgres__get_incremental_default_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/materializations/incremental_strategies.sql\", \"original_file_path\": \"macros/materializations/incremental_strategies.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_incremental_default_sql\", \"macro_sql\": \"{% macro postgres__get_incremental_default_sql(arg_dict) %}\\n\\n  {% if arg_dict[\\\"unique_key\\\"] %}\\n    {% do return(get_incremental_delete_insert_sql(arg_dict)) %}\\n  {% else %}\\n    {% do return(get_incremental_append_sql(arg_dict)) %}\\n  {% endif %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_incremental_delete_insert_sql\", \"macro.dbt.get_incremental_append_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.525357, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__snapshot_merge_sql\": {\"name\": \"postgres__snapshot_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/materializations/snapshot_merge.sql\", \"original_file_path\": \"macros/materializations/snapshot_merge.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__snapshot_merge_sql\", \"macro_sql\": \"{% macro postgres__snapshot_merge_sql(target, source, insert_cols) -%}\\n    {%- set insert_cols_csv = insert_cols | join(', ') -%}\\n\\n    update {{ target }}\\n    set dbt_valid_to = DBT_INTERNAL_SOURCE.dbt_valid_to\\n    from {{ source }} as DBT_INTERNAL_SOURCE\\n    where DBT_INTERNAL_SOURCE.dbt_scd_id::text = {{ target }}.dbt_scd_id::text\\n      and DBT_INTERNAL_SOURCE.dbt_change_type::text in ('update'::text, 'delete'::text)\\n      and {{ target }}.dbt_valid_to is null;\\n\\n    insert into {{ target }} ({{ insert_cols_csv }})\\n    select {% for column in insert_cols -%}\\n        DBT_INTERNAL_SOURCE.{{ column }} {%- if not loop.last %}, {%- endif %}\\n    {%- endfor %}\\n    from {{ source }} as DBT_INTERNAL_SOURCE\\n    where DBT_INTERNAL_SOURCE.dbt_change_type::text = 'insert'::text;\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.526551, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__drop_materialized_view\": {\"name\": \"postgres__drop_materialized_view\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/relations/materialized_view/drop.sql\", \"original_file_path\": \"macros/relations/materialized_view/drop.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__drop_materialized_view\", \"macro_sql\": \"{% macro postgres__drop_materialized_view(relation) -%}\\n    drop materialized view if exists {{ relation }} cascade\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.5267892, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__describe_materialized_view\": {\"name\": \"postgres__describe_materialized_view\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/relations/materialized_view/describe.sql\", \"original_file_path\": \"macros/relations/materialized_view/describe.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__describe_materialized_view\", \"macro_sql\": \"{% macro postgres__describe_materialized_view(relation) %}\\n    -- for now just get the indexes, we don't need the name or the query yet\\n    {% set _indexes = run_query(get_show_indexes_sql(relation)) %}\\n    {% do return({'indexes': _indexes}) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.run_query\", \"macro.dbt.get_show_indexes_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.527286, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__refresh_materialized_view\": {\"name\": \"postgres__refresh_materialized_view\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/relations/materialized_view/refresh.sql\", \"original_file_path\": \"macros/relations/materialized_view/refresh.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__refresh_materialized_view\", \"macro_sql\": \"{% macro postgres__refresh_materialized_view(relation) %}\\n    refresh materialized view {{ relation }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.527518, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_rename_materialized_view_sql\": {\"name\": \"postgres__get_rename_materialized_view_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/relations/materialized_view/rename.sql\", \"original_file_path\": \"macros/relations/materialized_view/rename.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_rename_materialized_view_sql\", \"macro_sql\": \"{% macro postgres__get_rename_materialized_view_sql(relation, new_name) %}\\n    alter materialized view {{ relation }} rename to {{ new_name }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.527804, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_alter_materialized_view_as_sql\": {\"name\": \"postgres__get_alter_materialized_view_as_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/relations/materialized_view/alter.sql\", \"original_file_path\": \"macros/relations/materialized_view/alter.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_alter_materialized_view_as_sql\", \"macro_sql\": \"{% macro postgres__get_alter_materialized_view_as_sql(\\n    relation,\\n    configuration_changes,\\n    sql,\\n    existing_relation,\\n    backup_relation,\\n    intermediate_relation\\n) %}\\n\\n    -- apply a full refresh immediately if needed\\n    {% if configuration_changes.requires_full_refresh %}\\n\\n        {{ get_replace_sql(existing_relation, relation, sql) }}\\n\\n    -- otherwise apply individual changes as needed\\n    {% else %}\\n\\n        {{ postgres__update_indexes_on_materialized_view(relation, configuration_changes.indexes) }}\\n\\n    {%- endif -%}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_replace_sql\", \"macro.dbt_postgres.postgres__update_indexes_on_materialized_view\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.529207, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__update_indexes_on_materialized_view\": {\"name\": \"postgres__update_indexes_on_materialized_view\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/relations/materialized_view/alter.sql\", \"original_file_path\": \"macros/relations/materialized_view/alter.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__update_indexes_on_materialized_view\", \"macro_sql\": \"\\n\\n\\n{%- macro postgres__update_indexes_on_materialized_view(relation, index_changes) -%}\\n    {{- log(\\\"Applying UPDATE INDEXES to: \\\" ~ relation) -}}\\n\\n    {%- for _index_change in index_changes -%}\\n        {%- set _index = _index_change.context -%}\\n\\n        {%- if _index_change.action == \\\"drop\\\" -%}\\n\\n            {{ postgres__get_drop_index_sql(relation, _index.name) }};\\n\\n        {%- elif _index_change.action == \\\"create\\\" -%}\\n\\n            {{ postgres__get_create_index_sql(relation, _index.as_node_config) }}\\n\\n        {%- endif -%}\\n\\n    {%- endfor -%}\\n\\n{%- endmacro -%}\\n\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_drop_index_sql\", \"macro.dbt_postgres.postgres__get_create_index_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.530157, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_materialized_view_configuration_changes\": {\"name\": \"postgres__get_materialized_view_configuration_changes\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/relations/materialized_view/alter.sql\", \"original_file_path\": \"macros/relations/materialized_view/alter.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_materialized_view_configuration_changes\", \"macro_sql\": \"{% macro postgres__get_materialized_view_configuration_changes(existing_relation, new_config) %}\\n    {% set _existing_materialized_view = postgres__describe_materialized_view(existing_relation) %}\\n    {% set _configuration_changes = existing_relation.get_materialized_view_config_change_collection(_existing_materialized_view, new_config) %}\\n    {% do return(_configuration_changes) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__describe_materialized_view\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.530636, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_create_materialized_view_as_sql\": {\"name\": \"postgres__get_create_materialized_view_as_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/relations/materialized_view/create.sql\", \"original_file_path\": \"macros/relations/materialized_view/create.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_create_materialized_view_as_sql\", \"macro_sql\": \"{% macro postgres__get_create_materialized_view_as_sql(relation, sql) %}\\n    create materialized view if not exists {{ relation }} as {{ sql }};\\n\\n    {% for _index_dict in config.get('indexes', []) -%}\\n        {{- get_create_index_sql(relation, _index_dict) -}}\\n    {%- endfor -%}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_create_index_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.5312471, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__drop_table\": {\"name\": \"postgres__drop_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/relations/table/drop.sql\", \"original_file_path\": \"macros/relations/table/drop.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__drop_table\", \"macro_sql\": \"{% macro postgres__drop_table(relation) -%}\\n    drop table if exists {{ relation }} cascade\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.5314791, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_replace_table_sql\": {\"name\": \"postgres__get_replace_table_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/relations/table/replace.sql\", \"original_file_path\": \"macros/relations/table/replace.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_replace_table_sql\", \"macro_sql\": \"{% macro postgres__get_replace_table_sql(relation, sql) -%}\\n\\n    {%- set sql_header = config.get('sql_header', none) -%}\\n    {{ sql_header if sql_header is not none }}\\n\\n    create or replace table {{ relation }}\\n        {% set contract_config = config.get('contract') %}\\n        {% if contract_config.enforced %}\\n            {{ get_assert_columns_equivalent(sql) }}\\n            {{ get_table_columns_and_constraints() }}\\n            {%- set sql = get_select_subquery(sql) %}\\n        {% endif %}\\n    as (\\n        {{ sql }}\\n    );\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_assert_columns_equivalent\", \"macro.dbt.get_table_columns_and_constraints\", \"macro.dbt.get_select_subquery\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.532609, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_rename_table_sql\": {\"name\": \"postgres__get_rename_table_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/relations/table/rename.sql\", \"original_file_path\": \"macros/relations/table/rename.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_rename_table_sql\", \"macro_sql\": \"{% macro postgres__get_rename_table_sql(relation, new_name) %}\\n    alter table {{ relation }} rename to {{ new_name }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.5328991, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__drop_view\": {\"name\": \"postgres__drop_view\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/relations/view/drop.sql\", \"original_file_path\": \"macros/relations/view/drop.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__drop_view\", \"macro_sql\": \"{% macro postgres__drop_view(relation) -%}\\n    drop view if exists {{ relation }} cascade\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.5331168, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_replace_view_sql\": {\"name\": \"postgres__get_replace_view_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/relations/view/replace.sql\", \"original_file_path\": \"macros/relations/view/replace.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_replace_view_sql\", \"macro_sql\": \"{% macro postgres__get_replace_view_sql(relation, sql) -%}\\n\\n    {%- set sql_header = config.get('sql_header', none) -%}\\n    {{ sql_header if sql_header is not none }}\\n\\n    create or replace view {{ relation }}\\n        {% set contract_config = config.get('contract') %}\\n        {% if contract_config.enforced %}\\n            {{ get_assert_columns_equivalent(sql) }}\\n        {%- endif %}\\n    as (\\n        {{ sql }}\\n    );\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_assert_columns_equivalent\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.5340202, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_rename_view_sql\": {\"name\": \"postgres__get_rename_view_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/relations/view/rename.sql\", \"original_file_path\": \"macros/relations/view/rename.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_rename_view_sql\", \"macro_sql\": \"{% macro postgres__get_rename_view_sql(relation, new_name) %}\\n    alter view {{ relation }} rename to {{ new_name }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.534313, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__dateadd\": {\"name\": \"postgres__dateadd\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/utils/dateadd.sql\", \"original_file_path\": \"macros/utils/dateadd.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__dateadd\", \"macro_sql\": \"{% macro postgres__dateadd(datepart, interval, from_date_or_timestamp) %}\\n\\n    {{ from_date_or_timestamp }} + ((interval '1 {{ datepart }}') * ({{ interval }}))\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.534663, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__listagg\": {\"name\": \"postgres__listagg\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/utils/listagg.sql\", \"original_file_path\": \"macros/utils/listagg.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__listagg\", \"macro_sql\": \"{% macro postgres__listagg(measure, delimiter_text, order_by_clause, limit_num) -%}\\n\\n    {% if limit_num -%}\\n    array_to_string(\\n        (array_agg(\\n            {{ measure }}\\n            {% if order_by_clause -%}\\n            {{ order_by_clause }}\\n            {%- endif %}\\n        ))[1:{{ limit_num }}],\\n        {{ delimiter_text }}\\n        )\\n    {%- else %}\\n    string_agg(\\n        {{ measure }},\\n        {{ delimiter_text }}\\n        {% if order_by_clause -%}\\n        {{ order_by_clause }}\\n        {%- endif %}\\n        )\\n    {%- endif %}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.5356429, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__datediff\": {\"name\": \"postgres__datediff\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/utils/datediff.sql\", \"original_file_path\": \"macros/utils/datediff.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__datediff\", \"macro_sql\": \"{% macro postgres__datediff(first_date, second_date, datepart) -%}\\n\\n    {% if datepart == 'year' %}\\n        (date_part('year', ({{second_date}})::date) - date_part('year', ({{first_date}})::date))\\n    {% elif datepart == 'quarter' %}\\n        ({{ datediff(first_date, second_date, 'year') }} * 4 + date_part('quarter', ({{second_date}})::date) - date_part('quarter', ({{first_date}})::date))\\n    {% elif datepart == 'month' %}\\n        ({{ datediff(first_date, second_date, 'year') }} * 12 + date_part('month', ({{second_date}})::date) - date_part('month', ({{first_date}})::date))\\n    {% elif datepart == 'day' %}\\n        (({{second_date}})::date - ({{first_date}})::date)\\n    {% elif datepart == 'week' %}\\n        ({{ datediff(first_date, second_date, 'day') }} / 7 + case\\n            when date_part('dow', ({{first_date}})::timestamp) <= date_part('dow', ({{second_date}})::timestamp) then\\n                case when {{first_date}} <= {{second_date}} then 0 else -1 end\\n            else\\n                case when {{first_date}} <= {{second_date}} then 1 else 0 end\\n        end)\\n    {% elif datepart == 'hour' %}\\n        ({{ datediff(first_date, second_date, 'day') }} * 24 + date_part('hour', ({{second_date}})::timestamp) - date_part('hour', ({{first_date}})::timestamp))\\n    {% elif datepart == 'minute' %}\\n        ({{ datediff(first_date, second_date, 'hour') }} * 60 + date_part('minute', ({{second_date}})::timestamp) - date_part('minute', ({{first_date}})::timestamp))\\n    {% elif datepart == 'second' %}\\n        ({{ datediff(first_date, second_date, 'minute') }} * 60 + floor(date_part('second', ({{second_date}})::timestamp)) - floor(date_part('second', ({{first_date}})::timestamp)))\\n    {% elif datepart == 'millisecond' %}\\n        ({{ datediff(first_date, second_date, 'minute') }} * 60000 + floor(date_part('millisecond', ({{second_date}})::timestamp)) - floor(date_part('millisecond', ({{first_date}})::timestamp)))\\n    {% elif datepart == 'microsecond' %}\\n        ({{ datediff(first_date, second_date, 'minute') }} * 60000000 + floor(date_part('microsecond', ({{second_date}})::timestamp)) - floor(date_part('microsecond', ({{first_date}})::timestamp)))\\n    {% else %}\\n        {{ exceptions.raise_compiler_error(\\\"Unsupported datepart for macro datediff in postgres: {!r}\\\".format(datepart)) }}\\n    {% endif %}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.datediff\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.5409238, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__any_value\": {\"name\": \"postgres__any_value\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/utils/any_value.sql\", \"original_file_path\": \"macros/utils/any_value.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__any_value\", \"macro_sql\": \"{% macro postgres__any_value(expression) -%}\\n\\n    min({{ expression }})\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.541182, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__last_day\": {\"name\": \"postgres__last_day\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/utils/last_day.sql\", \"original_file_path\": \"macros/utils/last_day.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__last_day\", \"macro_sql\": \"{% macro postgres__last_day(date, datepart) -%}\\n\\n    {%- if datepart == 'quarter' -%}\\n    -- postgres dateadd does not support quarter interval.\\n    cast(\\n        {{dbt.dateadd('day', '-1',\\n        dbt.dateadd('month', '3', dbt.date_trunc(datepart, date))\\n        )}}\\n        as date)\\n    {%- else -%}\\n    {{dbt.default_last_day(date, datepart)}}\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.dateadd\", \"macro.dbt.date_trunc\", \"macro.dbt.default_last_day\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.541986, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__split_part\": {\"name\": \"postgres__split_part\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/utils/split_part.sql\", \"original_file_path\": \"macros/utils/split_part.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__split_part\", \"macro_sql\": \"{% macro postgres__split_part(string_text, delimiter_text, part_number) %}\\n\\n  {% if part_number >= 0 %}\\n    {{ dbt.default__split_part(string_text, delimiter_text, part_number) }}\\n  {% else %}\\n    {{ dbt._split_part_negative(string_text, delimiter_text, part_number) }}\\n  {% endif %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__split_part\", \"macro.dbt._split_part_negative\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.542672, \"supported_languages\": null}, \"macro.dbt.run_hooks\": {\"name\": \"run_hooks\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"unique_id\": \"macro.dbt.run_hooks\", \"macro_sql\": \"{% macro run_hooks(hooks, inside_transaction=True) %}\\n  {% for hook in hooks | selectattr('transaction', 'equalto', inside_transaction)  %}\\n    {% if not inside_transaction and loop.first %}\\n      {% call statement(auto_begin=inside_transaction) %}\\n        commit;\\n      {% endcall %}\\n    {% endif %}\\n    {% set rendered = render(hook.get('sql')) | trim %}\\n    {% if (rendered | length) > 0 %}\\n      {% call statement(auto_begin=inside_transaction) %}\\n        {{ rendered }}\\n      {% endcall %}\\n    {% endif %}\\n  {% endfor %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.544426, \"supported_languages\": null}, \"macro.dbt.make_hook_config\": {\"name\": \"make_hook_config\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"unique_id\": \"macro.dbt.make_hook_config\", \"macro_sql\": \"{% macro make_hook_config(sql, inside_transaction) %}\\n    {{ tojson({\\\"sql\\\": sql, \\\"transaction\\\": inside_transaction}) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.5447628, \"supported_languages\": null}, \"macro.dbt.before_begin\": {\"name\": \"before_begin\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"unique_id\": \"macro.dbt.before_begin\", \"macro_sql\": \"{% macro before_begin(sql) %}\\n    {{ make_hook_config(sql, inside_transaction=False) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.make_hook_config\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.545001, \"supported_languages\": null}, \"macro.dbt.in_transaction\": {\"name\": \"in_transaction\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"unique_id\": \"macro.dbt.in_transaction\", \"macro_sql\": \"{% macro in_transaction(sql) %}\\n    {{ make_hook_config(sql, inside_transaction=True) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.make_hook_config\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.545242, \"supported_languages\": null}, \"macro.dbt.after_commit\": {\"name\": \"after_commit\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"unique_id\": \"macro.dbt.after_commit\", \"macro_sql\": \"{% macro after_commit(sql) %}\\n    {{ make_hook_config(sql, inside_transaction=False) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.make_hook_config\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.545506, \"supported_languages\": null}, \"macro.dbt.set_sql_header\": {\"name\": \"set_sql_header\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/configs.sql\", \"original_file_path\": \"macros/materializations/configs.sql\", \"unique_id\": \"macro.dbt.set_sql_header\", \"macro_sql\": \"{% macro set_sql_header(config) -%}\\n  {{ config.set('sql_header', caller()) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.5461252, \"supported_languages\": null}, \"macro.dbt.should_full_refresh\": {\"name\": \"should_full_refresh\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/configs.sql\", \"original_file_path\": \"macros/materializations/configs.sql\", \"unique_id\": \"macro.dbt.should_full_refresh\", \"macro_sql\": \"{% macro should_full_refresh() %}\\n  {% set config_full_refresh = config.get('full_refresh') %}\\n  {% if config_full_refresh is none %}\\n    {% set config_full_refresh = flags.FULL_REFRESH %}\\n  {% endif %}\\n  {% do return(config_full_refresh) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.5466251, \"supported_languages\": null}, \"macro.dbt.should_store_failures\": {\"name\": \"should_store_failures\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/configs.sql\", \"original_file_path\": \"macros/materializations/configs.sql\", \"unique_id\": \"macro.dbt.should_store_failures\", \"macro_sql\": \"{% macro should_store_failures() %}\\n  {% set config_store_failures = config.get('store_failures') %}\\n  {% if config_store_failures is none %}\\n    {% set config_store_failures = flags.STORE_FAILURES %}\\n  {% endif %}\\n  {% do return(config_store_failures) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.547284, \"supported_languages\": null}, \"macro.dbt.snapshot_merge_sql\": {\"name\": \"snapshot_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/snapshot_merge.sql\", \"original_file_path\": \"macros/materializations/snapshots/snapshot_merge.sql\", \"unique_id\": \"macro.dbt.snapshot_merge_sql\", \"macro_sql\": \"{% macro snapshot_merge_sql(target, source, insert_cols) -%}\\n  {{ adapter.dispatch('snapshot_merge_sql', 'dbt')(target, source, insert_cols) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__snapshot_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.548049, \"supported_languages\": null}, \"macro.dbt.default__snapshot_merge_sql\": {\"name\": \"default__snapshot_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/snapshot_merge.sql\", \"original_file_path\": \"macros/materializations/snapshots/snapshot_merge.sql\", \"unique_id\": \"macro.dbt.default__snapshot_merge_sql\", \"macro_sql\": \"{% macro default__snapshot_merge_sql(target, source, insert_cols) -%}\\n    {%- set insert_cols_csv = insert_cols | join(', ') -%}\\n\\n    merge into {{ target }} as DBT_INTERNAL_DEST\\n    using {{ source }} as DBT_INTERNAL_SOURCE\\n    on DBT_INTERNAL_SOURCE.dbt_scd_id = DBT_INTERNAL_DEST.dbt_scd_id\\n\\n    when matched\\n     and DBT_INTERNAL_DEST.dbt_valid_to is null\\n     and DBT_INTERNAL_SOURCE.dbt_change_type in ('update', 'delete')\\n        then update\\n        set dbt_valid_to = DBT_INTERNAL_SOURCE.dbt_valid_to\\n\\n    when not matched\\n     and DBT_INTERNAL_SOURCE.dbt_change_type = 'insert'\\n        then insert ({{ insert_cols_csv }})\\n        values ({{ insert_cols_csv }})\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.548515, \"supported_languages\": null}, \"macro.dbt.strategy_dispatch\": {\"name\": \"strategy_dispatch\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"unique_id\": \"macro.dbt.strategy_dispatch\", \"macro_sql\": \"{% macro strategy_dispatch(name) -%}\\n{% set original_name = name %}\\n  {% if '.' in name %}\\n    {% set package_name, name = name.split(\\\".\\\", 1) %}\\n  {% else %}\\n    {% set package_name = none %}\\n  {% endif %}\\n\\n  {% if package_name is none %}\\n    {% set package_context = context %}\\n  {% elif package_name in context %}\\n    {% set package_context = context[package_name] %}\\n  {% else %}\\n    {% set error_msg %}\\n        Could not find package '{{package_name}}', called with '{{original_name}}'\\n    {% endset %}\\n    {{ exceptions.raise_compiler_error(error_msg | trim) }}\\n  {% endif %}\\n\\n  {%- set search_name = 'snapshot_' ~ name ~ '_strategy' -%}\\n\\n  {% if search_name not in package_context %}\\n    {% set error_msg %}\\n        The specified strategy macro '{{name}}' was not found in package '{{ package_name }}'\\n    {% endset %}\\n    {{ exceptions.raise_compiler_error(error_msg | trim) }}\\n  {% endif %}\\n  {{ return(package_context[search_name]) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.5546088, \"supported_languages\": null}, \"macro.dbt.snapshot_hash_arguments\": {\"name\": \"snapshot_hash_arguments\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"unique_id\": \"macro.dbt.snapshot_hash_arguments\", \"macro_sql\": \"{% macro snapshot_hash_arguments(args) -%}\\n  {{ adapter.dispatch('snapshot_hash_arguments', 'dbt')(args) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__snapshot_hash_arguments\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.554924, \"supported_languages\": null}, \"macro.dbt.default__snapshot_hash_arguments\": {\"name\": \"default__snapshot_hash_arguments\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"unique_id\": \"macro.dbt.default__snapshot_hash_arguments\", \"macro_sql\": \"{% macro default__snapshot_hash_arguments(args) -%}\\n    md5({%- for arg in args -%}\\n        coalesce(cast({{ arg }} as varchar ), '')\\n        {% if not loop.last %} || '|' || {% endif %}\\n    {%- endfor -%})\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.55531, \"supported_languages\": null}, \"macro.dbt.snapshot_timestamp_strategy\": {\"name\": \"snapshot_timestamp_strategy\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"unique_id\": \"macro.dbt.snapshot_timestamp_strategy\", \"macro_sql\": \"{% macro snapshot_timestamp_strategy(node, snapshotted_rel, current_rel, config, target_exists) %}\\n    {% set primary_key = config['unique_key'] %}\\n    {% set updated_at = config['updated_at'] %}\\n    {% set invalidate_hard_deletes = config.get('invalidate_hard_deletes', false) %}\\n\\n    {#/*\\n        The snapshot relation might not have an {{ updated_at }} value if the\\n        snapshot strategy is changed from `check` to `timestamp`. We\\n        should use a dbt-created column for the comparison in the snapshot\\n        table instead of assuming that the user-supplied {{ updated_at }}\\n        will be present in the historical data.\\n\\n        See https://github.com/dbt-labs/dbt-core/issues/2350\\n    */ #}\\n    {% set row_changed_expr -%}\\n        ({{ snapshotted_rel }}.dbt_valid_from < {{ current_rel }}.{{ updated_at }})\\n    {%- endset %}\\n\\n    {% set scd_id_expr = snapshot_hash_arguments([primary_key, updated_at]) %}\\n\\n    {% do return({\\n        \\\"unique_key\\\": primary_key,\\n        \\\"updated_at\\\": updated_at,\\n        \\\"row_changed\\\": row_changed_expr,\\n        \\\"scd_id\\\": scd_id_expr,\\n        \\\"invalidate_hard_deletes\\\": invalidate_hard_deletes\\n    }) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.snapshot_hash_arguments\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.556515, \"supported_languages\": null}, \"macro.dbt.snapshot_string_as_time\": {\"name\": \"snapshot_string_as_time\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"unique_id\": \"macro.dbt.snapshot_string_as_time\", \"macro_sql\": \"{% macro snapshot_string_as_time(timestamp) -%}\\n    {{ adapter.dispatch('snapshot_string_as_time', 'dbt')(timestamp) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__snapshot_string_as_time\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.5568, \"supported_languages\": null}, \"macro.dbt.default__snapshot_string_as_time\": {\"name\": \"default__snapshot_string_as_time\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"unique_id\": \"macro.dbt.default__snapshot_string_as_time\", \"macro_sql\": \"{% macro default__snapshot_string_as_time(timestamp) %}\\n    {% do exceptions.raise_not_implemented(\\n        'snapshot_string_as_time macro not implemented for adapter '+adapter.type()\\n    ) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.557099, \"supported_languages\": null}, \"macro.dbt.snapshot_check_all_get_existing_columns\": {\"name\": \"snapshot_check_all_get_existing_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"unique_id\": \"macro.dbt.snapshot_check_all_get_existing_columns\", \"macro_sql\": \"{% macro snapshot_check_all_get_existing_columns(node, target_exists, check_cols_config) -%}\\n    {%- if not target_exists -%}\\n        {#-- no table yet -> return whatever the query does --#}\\n        {{ return((false, query_columns)) }}\\n    {%- endif -%}\\n\\n    {#-- handle any schema changes --#}\\n    {%- set target_relation = adapter.get_relation(database=node.database, schema=node.schema, identifier=node.alias) -%}\\n\\n    {% if check_cols_config == 'all' %}\\n        {%- set query_columns = get_columns_in_query(node['compiled_code']) -%}\\n\\n    {% elif check_cols_config is iterable and (check_cols_config | length) > 0 %}\\n        {#-- query for proper casing/quoting, to support comparison below --#}\\n        {%- set select_check_cols_from_target -%}\\n            {#-- N.B. The whitespace below is necessary to avoid edge case issue with comments --#}\\n            {#-- See: https://github.com/dbt-labs/dbt-core/issues/6781 --#}\\n            select {{ check_cols_config | join(', ') }} from (\\n                {{ node['compiled_code'] }}\\n            ) subq\\n        {%- endset -%}\\n        {% set query_columns = get_columns_in_query(select_check_cols_from_target) %}\\n\\n    {% else %}\\n        {% do exceptions.raise_compiler_error(\\\"Invalid value for 'check_cols': \\\" ~ check_cols_config) %}\\n    {% endif %}\\n\\n    {%- set existing_cols = adapter.get_columns_in_relation(target_relation) | map(attribute = 'name') | list -%}\\n    {%- set ns = namespace() -%} {#-- handle for-loop scoping with a namespace --#}\\n    {%- set ns.column_added = false -%}\\n\\n    {%- set intersection = [] -%}\\n    {%- for col in query_columns -%}\\n        {%- if col in existing_cols -%}\\n            {%- do intersection.append(adapter.quote(col)) -%}\\n        {%- else -%}\\n            {% set ns.column_added = true %}\\n        {%- endif -%}\\n    {%- endfor -%}\\n    {{ return((ns.column_added, intersection)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_columns_in_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.559448, \"supported_languages\": null}, \"macro.dbt.snapshot_check_strategy\": {\"name\": \"snapshot_check_strategy\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"unique_id\": \"macro.dbt.snapshot_check_strategy\", \"macro_sql\": \"{% macro snapshot_check_strategy(node, snapshotted_rel, current_rel, config, target_exists) %}\\n    {% set check_cols_config = config['check_cols'] %}\\n    {% set primary_key = config['unique_key'] %}\\n    {% set invalidate_hard_deletes = config.get('invalidate_hard_deletes', false) %}\\n    {% set updated_at = config.get('updated_at', snapshot_get_time()) %}\\n\\n    {% set column_added = false %}\\n\\n    {% set column_added, check_cols = snapshot_check_all_get_existing_columns(node, target_exists, check_cols_config) %}\\n\\n    {%- set row_changed_expr -%}\\n    (\\n    {%- if column_added -%}\\n        {{ get_true_sql() }}\\n    {%- else -%}\\n    {%- for col in check_cols -%}\\n        {{ snapshotted_rel }}.{{ col }} != {{ current_rel }}.{{ col }}\\n        or\\n        (\\n            (({{ snapshotted_rel }}.{{ col }} is null) and not ({{ current_rel }}.{{ col }} is null))\\n            or\\n            ((not {{ snapshotted_rel }}.{{ col }} is null) and ({{ current_rel }}.{{ col }} is null))\\n        )\\n        {%- if not loop.last %} or {% endif -%}\\n    {%- endfor -%}\\n    {%- endif -%}\\n    )\\n    {%- endset %}\\n\\n    {% set scd_id_expr = snapshot_hash_arguments([primary_key, updated_at]) %}\\n\\n    {% do return({\\n        \\\"unique_key\\\": primary_key,\\n        \\\"updated_at\\\": updated_at,\\n        \\\"row_changed\\\": row_changed_expr,\\n        \\\"scd_id\\\": scd_id_expr,\\n        \\\"invalidate_hard_deletes\\\": invalidate_hard_deletes\\n    }) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.snapshot_get_time\", \"macro.dbt.snapshot_check_all_get_existing_columns\", \"macro.dbt.get_true_sql\", \"macro.dbt.snapshot_hash_arguments\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.561697, \"supported_languages\": null}, \"macro.dbt.create_columns\": {\"name\": \"create_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.create_columns\", \"macro_sql\": \"{% macro create_columns(relation, columns) %}\\n  {{ adapter.dispatch('create_columns', 'dbt')(relation, columns) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__create_columns\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.567965, \"supported_languages\": null}, \"macro.dbt.default__create_columns\": {\"name\": \"default__create_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.default__create_columns\", \"macro_sql\": \"{% macro default__create_columns(relation, columns) %}\\n  {% for column in columns %}\\n    {% call statement() %}\\n      alter table {{ relation }} add column \\\"{{ column.name }}\\\" {{ column.data_type }};\\n    {% endcall %}\\n  {% endfor %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.568439, \"supported_languages\": null}, \"macro.dbt.post_snapshot\": {\"name\": \"post_snapshot\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.post_snapshot\", \"macro_sql\": \"{% macro post_snapshot(staging_relation) %}\\n  {{ adapter.dispatch('post_snapshot', 'dbt')(staging_relation) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__post_snapshot\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.568725, \"supported_languages\": null}, \"macro.dbt.default__post_snapshot\": {\"name\": \"default__post_snapshot\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.default__post_snapshot\", \"macro_sql\": \"{% macro default__post_snapshot(staging_relation) %}\\n    {# no-op #}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.568873, \"supported_languages\": null}, \"macro.dbt.get_true_sql\": {\"name\": \"get_true_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.get_true_sql\", \"macro_sql\": \"{% macro get_true_sql() %}\\n  {{ adapter.dispatch('get_true_sql', 'dbt')() }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_true_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.569119, \"supported_languages\": null}, \"macro.dbt.default__get_true_sql\": {\"name\": \"default__get_true_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.default__get_true_sql\", \"macro_sql\": \"{% macro default__get_true_sql() %}\\n    {{ return('TRUE') }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.569309, \"supported_languages\": null}, \"macro.dbt.snapshot_staging_table\": {\"name\": \"snapshot_staging_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.snapshot_staging_table\", \"macro_sql\": \"{% macro snapshot_staging_table(strategy, source_sql, target_relation) -%}\\n  {{ adapter.dispatch('snapshot_staging_table', 'dbt')(strategy, source_sql, target_relation) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__snapshot_staging_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.569651, \"supported_languages\": null}, \"macro.dbt.default__snapshot_staging_table\": {\"name\": \"default__snapshot_staging_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.default__snapshot_staging_table\", \"macro_sql\": \"{% macro default__snapshot_staging_table(strategy, source_sql, target_relation) -%}\\n\\n    with snapshot_query as (\\n\\n        {{ source_sql }}\\n\\n    ),\\n\\n    snapshotted_data as (\\n\\n        select *,\\n            {{ strategy.unique_key }} as dbt_unique_key\\n\\n        from {{ target_relation }}\\n        where dbt_valid_to is null\\n\\n    ),\\n\\n    insertions_source_data as (\\n\\n        select\\n            *,\\n            {{ strategy.unique_key }} as dbt_unique_key,\\n            {{ strategy.updated_at }} as dbt_updated_at,\\n            {{ strategy.updated_at }} as dbt_valid_from,\\n            nullif({{ strategy.updated_at }}, {{ strategy.updated_at }}) as dbt_valid_to,\\n            {{ strategy.scd_id }} as dbt_scd_id\\n\\n        from snapshot_query\\n    ),\\n\\n    updates_source_data as (\\n\\n        select\\n            *,\\n            {{ strategy.unique_key }} as dbt_unique_key,\\n            {{ strategy.updated_at }} as dbt_updated_at,\\n            {{ strategy.updated_at }} as dbt_valid_from,\\n            {{ strategy.updated_at }} as dbt_valid_to\\n\\n        from snapshot_query\\n    ),\\n\\n    {%- if strategy.invalidate_hard_deletes %}\\n\\n    deletes_source_data as (\\n\\n        select\\n            *,\\n            {{ strategy.unique_key }} as dbt_unique_key\\n        from snapshot_query\\n    ),\\n    {% endif %}\\n\\n    insertions as (\\n\\n        select\\n            'insert' as dbt_change_type,\\n            source_data.*\\n\\n        from insertions_source_data as source_data\\n        left outer join snapshotted_data on snapshotted_data.dbt_unique_key = source_data.dbt_unique_key\\n        where snapshotted_data.dbt_unique_key is null\\n           or (\\n                snapshotted_data.dbt_unique_key is not null\\n            and (\\n                {{ strategy.row_changed }}\\n            )\\n        )\\n\\n    ),\\n\\n    updates as (\\n\\n        select\\n            'update' as dbt_change_type,\\n            source_data.*,\\n            snapshotted_data.dbt_scd_id\\n\\n        from updates_source_data as source_data\\n        join snapshotted_data on snapshotted_data.dbt_unique_key = source_data.dbt_unique_key\\n        where (\\n            {{ strategy.row_changed }}\\n        )\\n    )\\n\\n    {%- if strategy.invalidate_hard_deletes -%}\\n    ,\\n\\n    deletes as (\\n\\n        select\\n            'delete' as dbt_change_type,\\n            source_data.*,\\n            {{ snapshot_get_time() }} as dbt_valid_from,\\n            {{ snapshot_get_time() }} as dbt_updated_at,\\n            {{ snapshot_get_time() }} as dbt_valid_to,\\n            snapshotted_data.dbt_scd_id\\n\\n        from snapshotted_data\\n        left join deletes_source_data as source_data on snapshotted_data.dbt_unique_key = source_data.dbt_unique_key\\n        where source_data.dbt_unique_key is null\\n    )\\n    {%- endif %}\\n\\n    select * from insertions\\n    union all\\n    select * from updates\\n    {%- if strategy.invalidate_hard_deletes %}\\n    union all\\n    select * from deletes\\n    {%- endif %}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.snapshot_get_time\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.571101, \"supported_languages\": null}, \"macro.dbt.build_snapshot_table\": {\"name\": \"build_snapshot_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.build_snapshot_table\", \"macro_sql\": \"{% macro build_snapshot_table(strategy, sql) -%}\\n  {{ adapter.dispatch('build_snapshot_table', 'dbt')(strategy, sql) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__build_snapshot_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.571421, \"supported_languages\": null}, \"macro.dbt.default__build_snapshot_table\": {\"name\": \"default__build_snapshot_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.default__build_snapshot_table\", \"macro_sql\": \"{% macro default__build_snapshot_table(strategy, sql) %}\\n\\n    select *,\\n        {{ strategy.scd_id }} as dbt_scd_id,\\n        {{ strategy.updated_at }} as dbt_updated_at,\\n        {{ strategy.updated_at }} as dbt_valid_from,\\n        nullif({{ strategy.updated_at }}, {{ strategy.updated_at }}) as dbt_valid_to\\n    from (\\n        {{ sql }}\\n    ) sbq\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.571839, \"supported_languages\": null}, \"macro.dbt.build_snapshot_staging_table\": {\"name\": \"build_snapshot_staging_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.build_snapshot_staging_table\", \"macro_sql\": \"{% macro build_snapshot_staging_table(strategy, sql, target_relation) %}\\n    {% set temp_relation = make_temp_relation(target_relation) %}\\n\\n    {% set select = snapshot_staging_table(strategy, sql, target_relation) %}\\n\\n    {% call statement('build_snapshot_staging_relation') %}\\n        {{ create_table_as(True, temp_relation, select) }}\\n    {% endcall %}\\n\\n    {% do return(temp_relation) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.make_temp_relation\", \"macro.dbt.snapshot_staging_table\", \"macro.dbt.statement\", \"macro.dbt.create_table_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.5725482, \"supported_languages\": null}, \"macro.dbt.materialization_snapshot_default\": {\"name\": \"materialization_snapshot_default\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/snapshot.sql\", \"original_file_path\": \"macros/materializations/snapshots/snapshot.sql\", \"unique_id\": \"macro.dbt.materialization_snapshot_default\", \"macro_sql\": \"{% materialization snapshot, default %}\\n  {%- set config = model['config'] -%}\\n\\n  {%- set target_table = model.get('alias', model.get('name')) -%}\\n\\n  {%- set strategy_name = config.get('strategy') -%}\\n  {%- set unique_key = config.get('unique_key') %}\\n  -- grab current tables grants config for comparision later on\\n  {%- set grant_config = config.get('grants') -%}\\n\\n  {% set target_relation_exists, target_relation = get_or_create_relation(\\n          database=model.database,\\n          schema=model.schema,\\n          identifier=target_table,\\n          type='table') -%}\\n\\n  {%- if not target_relation.is_table -%}\\n    {% do exceptions.relation_wrong_type(target_relation, 'table') %}\\n  {%- endif -%}\\n\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  {% set strategy_macro = strategy_dispatch(strategy_name) %}\\n  {% set strategy = strategy_macro(model, \\\"snapshotted_data\\\", \\\"source_data\\\", config, target_relation_exists) %}\\n\\n  {% if not target_relation_exists %}\\n\\n      {% set build_sql = build_snapshot_table(strategy, model['compiled_code']) %}\\n      {% set final_sql = create_table_as(False, target_relation, build_sql) %}\\n\\n  {% else %}\\n\\n      {{ adapter.valid_snapshot_target(target_relation) }}\\n\\n      {% set staging_table = build_snapshot_staging_table(strategy, sql, target_relation) %}\\n\\n      -- this may no-op if the database does not require column expansion\\n      {% do adapter.expand_target_column_types(from_relation=staging_table,\\n                                               to_relation=target_relation) %}\\n\\n      {% set missing_columns = adapter.get_missing_columns(staging_table, target_relation)\\n                                   | rejectattr('name', 'equalto', 'dbt_change_type')\\n                                   | rejectattr('name', 'equalto', 'DBT_CHANGE_TYPE')\\n                                   | rejectattr('name', 'equalto', 'dbt_unique_key')\\n                                   | rejectattr('name', 'equalto', 'DBT_UNIQUE_KEY')\\n                                   | list %}\\n\\n      {% do create_columns(target_relation, missing_columns) %}\\n\\n      {% set source_columns = adapter.get_columns_in_relation(staging_table)\\n                                   | rejectattr('name', 'equalto', 'dbt_change_type')\\n                                   | rejectattr('name', 'equalto', 'DBT_CHANGE_TYPE')\\n                                   | rejectattr('name', 'equalto', 'dbt_unique_key')\\n                                   | rejectattr('name', 'equalto', 'DBT_UNIQUE_KEY')\\n                                   | list %}\\n\\n      {% set quoted_source_columns = [] %}\\n      {% for column in source_columns %}\\n        {% do quoted_source_columns.append(adapter.quote(column.name)) %}\\n      {% endfor %}\\n\\n      {% set final_sql = snapshot_merge_sql(\\n            target = target_relation,\\n            source = staging_table,\\n            insert_cols = quoted_source_columns\\n         )\\n      %}\\n\\n  {% endif %}\\n\\n  {% call statement('main') %}\\n      {{ final_sql }}\\n  {% endcall %}\\n\\n  {% set should_revoke = should_revoke(target_relation_exists, full_refresh_mode=False) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {% if not target_relation_exists %}\\n    {% do create_indexes(target_relation) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  {{ adapter.commit() }}\\n\\n  {% if staging_table is defined %}\\n      {% do post_snapshot(staging_table) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{% endmaterialization %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_or_create_relation\", \"macro.dbt.run_hooks\", \"macro.dbt.strategy_dispatch\", \"macro.dbt.build_snapshot_table\", \"macro.dbt.create_table_as\", \"macro.dbt.build_snapshot_staging_table\", \"macro.dbt.create_columns\", \"macro.dbt.snapshot_merge_sql\", \"macro.dbt.statement\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\", \"macro.dbt.persist_docs\", \"macro.dbt.create_indexes\", \"macro.dbt.post_snapshot\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.582187, \"supported_languages\": [\"sql\"]}, \"macro.dbt.materialization_test_default\": {\"name\": \"materialization_test_default\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/tests/test.sql\", \"original_file_path\": \"macros/materializations/tests/test.sql\", \"unique_id\": \"macro.dbt.materialization_test_default\", \"macro_sql\": \"{%- materialization test, default -%}\\n\\n  {% set relations = [] %}\\n\\n  {% if should_store_failures() %}\\n\\n    {% set identifier = model['alias'] %}\\n    {% set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) %}\\n\\n    {% set store_failures_as = config.get('store_failures_as') %}\\n    -- if `--store-failures` is invoked via command line and `store_failures_as` is not set,\\n    -- config.get('store_failures_as', 'table') returns None, not 'table'\\n    {% if store_failures_as == none %}{% set store_failures_as = 'table' %}{% endif %}\\n    {% if store_failures_as not in ['table', 'view'] %}\\n        {{ exceptions.raise_compiler_error(\\n            \\\"'\\\" ~ store_failures_as ~ \\\"' is not a valid value for `store_failures_as`. \\\"\\n            \\\"Accepted values are: ['ephemeral', 'table', 'view']\\\"\\n        ) }}\\n    {% endif %}\\n\\n    {% set target_relation = api.Relation.create(\\n        identifier=identifier, schema=schema, database=database, type=store_failures_as) -%} %}\\n\\n    {% if old_relation %}\\n        {% do adapter.drop_relation(old_relation) %}\\n    {% endif %}\\n\\n    {% call statement(auto_begin=True) %}\\n        {{ get_create_sql(target_relation, sql) }}\\n    {% endcall %}\\n\\n    {% do relations.append(target_relation) %}\\n\\n    {% set main_sql %}\\n        select *\\n        from {{ target_relation }}\\n    {% endset %}\\n\\n    {{ adapter.commit() }}\\n\\n  {% else %}\\n\\n      {% set main_sql = sql %}\\n\\n  {% endif %}\\n\\n  {% set limit = config.get('limit') %}\\n  {% set fail_calc = config.get('fail_calc') %}\\n  {% set warn_if = config.get('warn_if') %}\\n  {% set error_if = config.get('error_if') %}\\n\\n  {% call statement('main', fetch_result=True) -%}\\n\\n    {{ get_test_sql(main_sql, fail_calc, warn_if, error_if, limit)}}\\n\\n  {%- endcall %}\\n\\n  {{ return({'relations': relations}) }}\\n\\n{%- endmaterialization -%}\", \"depends_on\": {\"macros\": [\"macro.dbt.should_store_failures\", \"macro.dbt.statement\", \"macro.dbt.get_create_sql\", \"macro.dbt.get_test_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.586581, \"supported_languages\": [\"sql\"]}, \"macro.dbt.get_test_sql\": {\"name\": \"get_test_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/tests/helpers.sql\", \"original_file_path\": \"macros/materializations/tests/helpers.sql\", \"unique_id\": \"macro.dbt.get_test_sql\", \"macro_sql\": \"{% macro get_test_sql(main_sql, fail_calc, warn_if, error_if, limit) -%}\\n  {{ adapter.dispatch('get_test_sql', 'dbt')(main_sql, fail_calc, warn_if, error_if, limit) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_test_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.587331, \"supported_languages\": null}, \"macro.dbt.default__get_test_sql\": {\"name\": \"default__get_test_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/tests/helpers.sql\", \"original_file_path\": \"macros/materializations/tests/helpers.sql\", \"unique_id\": \"macro.dbt.default__get_test_sql\", \"macro_sql\": \"{% macro default__get_test_sql(main_sql, fail_calc, warn_if, error_if, limit) -%}\\n    select\\n      {{ fail_calc }} as failures,\\n      {{ fail_calc }} {{ warn_if }} as should_warn,\\n      {{ fail_calc }} {{ error_if }} as should_error\\n    from (\\n      {{ main_sql }}\\n      {{ \\\"limit \\\" ~ limit if limit != none }}\\n    ) dbt_internal_test\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.587847, \"supported_languages\": null}, \"macro.dbt.get_where_subquery\": {\"name\": \"get_where_subquery\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/tests/where_subquery.sql\", \"original_file_path\": \"macros/materializations/tests/where_subquery.sql\", \"unique_id\": \"macro.dbt.get_where_subquery\", \"macro_sql\": \"{% macro get_where_subquery(relation) -%}\\n    {% do return(adapter.dispatch('get_where_subquery', 'dbt')(relation)) %}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_where_subquery\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.5884538, \"supported_languages\": null}, \"macro.dbt.default__get_where_subquery\": {\"name\": \"default__get_where_subquery\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/tests/where_subquery.sql\", \"original_file_path\": \"macros/materializations/tests/where_subquery.sql\", \"unique_id\": \"macro.dbt.default__get_where_subquery\", \"macro_sql\": \"{% macro default__get_where_subquery(relation) -%}\\n    {% set where = config.get('where', '') %}\\n    {% if where %}\\n        {%- set filtered -%}\\n            (select * from {{ relation }} where {{ where }}) dbt_subquery\\n        {%- endset -%}\\n        {% do return(filtered) %}\\n    {%- else -%}\\n        {% do return(relation) %}\\n    {%- endif -%}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.589078, \"supported_languages\": null}, \"macro.dbt.materialization_materialized_view_default\": {\"name\": \"materialization_materialized_view_default\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/materialized_view.sql\", \"original_file_path\": \"macros/materializations/models/materialized_view.sql\", \"unique_id\": \"macro.dbt.materialization_materialized_view_default\", \"macro_sql\": \"{% materialization materialized_view, default %}\\n    {% set existing_relation = load_cached_relation(this) %}\\n    {% set target_relation = this.incorporate(type=this.MaterializedView) %}\\n    {% set intermediate_relation = make_intermediate_relation(target_relation) %}\\n    {% set backup_relation_type = target_relation.MaterializedView if existing_relation is none else existing_relation.type %}\\n    {% set backup_relation = make_backup_relation(target_relation, backup_relation_type) %}\\n\\n    {{ materialized_view_setup(backup_relation, intermediate_relation, pre_hooks) }}\\n\\n        {% set build_sql = materialized_view_get_build_sql(existing_relation, target_relation, backup_relation, intermediate_relation) %}\\n\\n        {% if build_sql == '' %}\\n            {{ materialized_view_execute_no_op(target_relation) }}\\n        {% else %}\\n            {{ materialized_view_execute_build_sql(build_sql, existing_relation, target_relation, post_hooks) }}\\n        {% endif %}\\n\\n    {{ materialized_view_teardown(backup_relation, intermediate_relation, post_hooks) }}\\n\\n    {{ return({'relations': [target_relation]}) }}\\n\\n{% endmaterialization %}\", \"depends_on\": {\"macros\": [\"macro.dbt.load_cached_relation\", \"macro.dbt.make_intermediate_relation\", \"macro.dbt.make_backup_relation\", \"macro.dbt.materialized_view_setup\", \"macro.dbt.materialized_view_get_build_sql\", \"macro.dbt.materialized_view_execute_no_op\", \"macro.dbt.materialized_view_execute_build_sql\", \"macro.dbt.materialized_view_teardown\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.5966778, \"supported_languages\": [\"sql\"]}, \"macro.dbt.materialized_view_setup\": {\"name\": \"materialized_view_setup\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/materialized_view.sql\", \"original_file_path\": \"macros/materializations/models/materialized_view.sql\", \"unique_id\": \"macro.dbt.materialized_view_setup\", \"macro_sql\": \"{% macro materialized_view_setup(backup_relation, intermediate_relation, pre_hooks) %}\\n\\n    -- backup_relation and intermediate_relation should not already exist in the database\\n    -- it's possible these exist because of a previous run that exited unexpectedly\\n    {% set preexisting_backup_relation = load_cached_relation(backup_relation) %}\\n    {% set preexisting_intermediate_relation = load_cached_relation(intermediate_relation) %}\\n\\n    -- drop the temp relations if they exist already in the database\\n    {{ drop_relation_if_exists(preexisting_backup_relation) }}\\n    {{ drop_relation_if_exists(preexisting_intermediate_relation) }}\\n\\n    {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.load_cached_relation\", \"macro.dbt.drop_relation_if_exists\", \"macro.dbt.run_hooks\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.5973198, \"supported_languages\": null}, \"macro.dbt.materialized_view_teardown\": {\"name\": \"materialized_view_teardown\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/materialized_view.sql\", \"original_file_path\": \"macros/materializations/models/materialized_view.sql\", \"unique_id\": \"macro.dbt.materialized_view_teardown\", \"macro_sql\": \"{% macro materialized_view_teardown(backup_relation, intermediate_relation, post_hooks) %}\\n\\n    -- drop the temp relations if they exist to leave the database clean for the next run\\n    {{ drop_relation_if_exists(backup_relation) }}\\n    {{ drop_relation_if_exists(intermediate_relation) }}\\n\\n    {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.drop_relation_if_exists\", \"macro.dbt.run_hooks\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.597737, \"supported_languages\": null}, \"macro.dbt.materialized_view_get_build_sql\": {\"name\": \"materialized_view_get_build_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/materialized_view.sql\", \"original_file_path\": \"macros/materializations/models/materialized_view.sql\", \"unique_id\": \"macro.dbt.materialized_view_get_build_sql\", \"macro_sql\": \"{% macro materialized_view_get_build_sql(existing_relation, target_relation, backup_relation, intermediate_relation) %}\\n\\n    {% set full_refresh_mode = should_full_refresh() %}\\n\\n    -- determine the scenario we're in: create, full_refresh, alter, refresh data\\n    {% if existing_relation is none %}\\n        {% set build_sql = get_create_materialized_view_as_sql(target_relation, sql) %}\\n    {% elif full_refresh_mode or not existing_relation.is_materialized_view %}\\n        {% set build_sql = get_replace_sql(existing_relation, target_relation, sql) %}\\n    {% else %}\\n\\n        -- get config options\\n        {% set on_configuration_change = config.get('on_configuration_change') %}\\n        {% set configuration_changes = get_materialized_view_configuration_changes(existing_relation, config) %}\\n\\n        {% if configuration_changes is none %}\\n            {% set build_sql = refresh_materialized_view(target_relation) %}\\n\\n        {% elif on_configuration_change == 'apply' %}\\n            {% set build_sql = get_alter_materialized_view_as_sql(target_relation, configuration_changes, sql, existing_relation, backup_relation, intermediate_relation) %}\\n        {% elif on_configuration_change == 'continue' %}\\n            {% set build_sql = '' %}\\n            {{ exceptions.warn(\\\"Configuration changes were identified and `on_configuration_change` was set to `continue` for `\\\" ~ target_relation ~ \\\"`\\\") }}\\n        {% elif on_configuration_change == 'fail' %}\\n            {{ exceptions.raise_fail_fast_error(\\\"Configuration changes were identified and `on_configuration_change` was set to `fail` for `\\\" ~ target_relation ~ \\\"`\\\") }}\\n\\n        {% else %}\\n            -- this only happens if the user provides a value other than `apply`, 'skip', 'fail'\\n            {{ exceptions.raise_compiler_error(\\\"Unexpected configuration scenario\\\") }}\\n\\n        {% endif %}\\n\\n    {% endif %}\\n\\n    {% do return(build_sql) %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.should_full_refresh\", \"macro.dbt.get_create_materialized_view_as_sql\", \"macro.dbt.get_replace_sql\", \"macro.dbt.get_materialized_view_configuration_changes\", \"macro.dbt.refresh_materialized_view\", \"macro.dbt.get_alter_materialized_view_as_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.599859, \"supported_languages\": null}, \"macro.dbt.materialized_view_execute_no_op\": {\"name\": \"materialized_view_execute_no_op\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/materialized_view.sql\", \"original_file_path\": \"macros/materializations/models/materialized_view.sql\", \"unique_id\": \"macro.dbt.materialized_view_execute_no_op\", \"macro_sql\": \"{% macro materialized_view_execute_no_op(target_relation) %}\\n    {% do store_raw_result(\\n        name=\\\"main\\\",\\n        message=\\\"skip \\\" ~ target_relation,\\n        code=\\\"skip\\\",\\n        rows_affected=\\\"-1\\\"\\n    ) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.600245, \"supported_languages\": null}, \"macro.dbt.materialized_view_execute_build_sql\": {\"name\": \"materialized_view_execute_build_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/materialized_view.sql\", \"original_file_path\": \"macros/materializations/models/materialized_view.sql\", \"unique_id\": \"macro.dbt.materialized_view_execute_build_sql\", \"macro_sql\": \"{% macro materialized_view_execute_build_sql(build_sql, existing_relation, target_relation, post_hooks) %}\\n\\n    -- `BEGIN` happens here:\\n    {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n    {% set grant_config = config.get('grants') %}\\n\\n    {% call statement(name=\\\"main\\\") %}\\n        {{ build_sql }}\\n    {% endcall %}\\n\\n    {% set should_revoke = should_revoke(existing_relation, full_refresh_mode=True) %}\\n    {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n    {% do persist_docs(target_relation, model) %}\\n\\n    {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n    {{ adapter.commit() }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.run_hooks\", \"macro.dbt.statement\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\", \"macro.dbt.persist_docs\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.601315, \"supported_languages\": null}, \"macro.dbt.materialization_view_default\": {\"name\": \"materialization_view_default\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/view.sql\", \"original_file_path\": \"macros/materializations/models/view.sql\", \"unique_id\": \"macro.dbt.materialization_view_default\", \"macro_sql\": \"{%- materialization view, default -%}\\n\\n  {%- set existing_relation = load_cached_relation(this) -%}\\n  {%- set target_relation = this.incorporate(type='view') -%}\\n  {%- set intermediate_relation =  make_intermediate_relation(target_relation) -%}\\n\\n  -- the intermediate_relation should not already exist in the database; get_relation\\n  -- will return None in that case. Otherwise, we get a relation that we can drop\\n  -- later, before we try to use this name for the current operation\\n  {%- set preexisting_intermediate_relation = load_cached_relation(intermediate_relation) -%}\\n  /*\\n     This relation (probably) doesn't exist yet. If it does exist, it's a leftover from\\n     a previous run, and we're going to try to drop it immediately. At the end of this\\n     materialization, we're going to rename the \\\"existing_relation\\\" to this identifier,\\n     and then we're going to drop it. In order to make sure we run the correct one of:\\n       - drop view ...\\n       - drop table ...\\n\\n     We need to set the type of this relation to be the type of the existing_relation, if it exists,\\n     or else \\\"view\\\" as a sane default if it does not. Note that if the existing_relation does not\\n     exist, then there is nothing to move out of the way and subsequentally drop. In that case,\\n     this relation will be effectively unused.\\n  */\\n  {%- set backup_relation_type = 'view' if existing_relation is none else existing_relation.type -%}\\n  {%- set backup_relation = make_backup_relation(target_relation, backup_relation_type) -%}\\n  -- as above, the backup_relation should not already exist\\n  {%- set preexisting_backup_relation = load_cached_relation(backup_relation) -%}\\n  -- grab current tables grants config for comparision later on\\n  {% set grant_config = config.get('grants') %}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- drop the temp relations if they exist already in the database\\n  {{ drop_relation_if_exists(preexisting_intermediate_relation) }}\\n  {{ drop_relation_if_exists(preexisting_backup_relation) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  -- build model\\n  {% call statement('main') -%}\\n    {{ get_create_view_as_sql(intermediate_relation, sql) }}\\n  {%- endcall %}\\n\\n  -- cleanup\\n  -- move the existing view out of the way\\n  {% if existing_relation is not none %}\\n     /* Do the equivalent of rename_if_exists. 'existing_relation' could have been dropped\\n        since the variable was first set. */\\n    {% set existing_relation = load_cached_relation(existing_relation) %}\\n    {% if existing_relation is not none %}\\n        {{ adapter.rename_relation(existing_relation, backup_relation) }}\\n    {% endif %}\\n  {% endif %}\\n  {{ adapter.rename_relation(intermediate_relation, target_relation) }}\\n\\n  {% set should_revoke = should_revoke(existing_relation, full_refresh_mode=True) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  {{ adapter.commit() }}\\n\\n  {{ drop_relation_if_exists(backup_relation) }}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{%- endmaterialization -%}\", \"depends_on\": {\"macros\": [\"macro.dbt.load_cached_relation\", \"macro.dbt.make_intermediate_relation\", \"macro.dbt.make_backup_relation\", \"macro.dbt.run_hooks\", \"macro.dbt.drop_relation_if_exists\", \"macro.dbt.statement\", \"macro.dbt.get_create_view_as_sql\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\", \"macro.dbt.persist_docs\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.6060789, \"supported_languages\": [\"sql\"]}, \"macro.dbt.materialization_table_default\": {\"name\": \"materialization_table_default\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/table.sql\", \"original_file_path\": \"macros/materializations/models/table.sql\", \"unique_id\": \"macro.dbt.materialization_table_default\", \"macro_sql\": \"{% materialization table, default %}\\n\\n  {%- set existing_relation = load_cached_relation(this) -%}\\n  {%- set target_relation = this.incorporate(type='table') %}\\n  {%- set intermediate_relation =  make_intermediate_relation(target_relation) -%}\\n  -- the intermediate_relation should not already exist in the database; get_relation\\n  -- will return None in that case. Otherwise, we get a relation that we can drop\\n  -- later, before we try to use this name for the current operation\\n  {%- set preexisting_intermediate_relation = load_cached_relation(intermediate_relation) -%}\\n  /*\\n      See ../view/view.sql for more information about this relation.\\n  */\\n  {%- set backup_relation_type = 'table' if existing_relation is none else existing_relation.type -%}\\n  {%- set backup_relation = make_backup_relation(target_relation, backup_relation_type) -%}\\n  -- as above, the backup_relation should not already exist\\n  {%- set preexisting_backup_relation = load_cached_relation(backup_relation) -%}\\n  -- grab current tables grants config for comparision later on\\n  {% set grant_config = config.get('grants') %}\\n\\n  -- drop the temp relations if they exist already in the database\\n  {{ drop_relation_if_exists(preexisting_intermediate_relation) }}\\n  {{ drop_relation_if_exists(preexisting_backup_relation) }}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  -- build model\\n  {% call statement('main') -%}\\n    {{ get_create_table_as_sql(False, intermediate_relation, sql) }}\\n  {%- endcall %}\\n\\n  -- cleanup\\n  {% if existing_relation is not none %}\\n     /* Do the equivalent of rename_if_exists. 'existing_relation' could have been dropped\\n        since the variable was first set. */\\n    {% set existing_relation = load_cached_relation(existing_relation) %}\\n    {% if existing_relation is not none %}\\n        {{ adapter.rename_relation(existing_relation, backup_relation) }}\\n    {% endif %}\\n  {% endif %}\\n\\n  {{ adapter.rename_relation(intermediate_relation, target_relation) }}\\n\\n  {% do create_indexes(target_relation) %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  {% set should_revoke = should_revoke(existing_relation, full_refresh_mode=True) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  -- `COMMIT` happens here\\n  {{ adapter.commit() }}\\n\\n  -- finally, drop the existing/backup relation after the commit\\n  {{ drop_relation_if_exists(backup_relation) }}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n{% endmaterialization %}\", \"depends_on\": {\"macros\": [\"macro.dbt.load_cached_relation\", \"macro.dbt.make_intermediate_relation\", \"macro.dbt.make_backup_relation\", \"macro.dbt.drop_relation_if_exists\", \"macro.dbt.run_hooks\", \"macro.dbt.statement\", \"macro.dbt.get_create_table_as_sql\", \"macro.dbt.create_indexes\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\", \"macro.dbt.persist_docs\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.610741, \"supported_languages\": [\"sql\"]}, \"macro.dbt.get_quoted_csv\": {\"name\": \"get_quoted_csv\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"unique_id\": \"macro.dbt.get_quoted_csv\", \"macro_sql\": \"{% macro get_quoted_csv(column_names) %}\\n\\n    {% set quoted = [] %}\\n    {% for col in column_names -%}\\n        {%- do quoted.append(adapter.quote(col)) -%}\\n    {%- endfor %}\\n\\n    {%- set dest_cols_csv = quoted | join(', ') -%}\\n    {{ return(dest_cols_csv) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.613347, \"supported_languages\": null}, \"macro.dbt.diff_columns\": {\"name\": \"diff_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"unique_id\": \"macro.dbt.diff_columns\", \"macro_sql\": \"{% macro diff_columns(source_columns, target_columns) %}\\n\\n  {% set result = [] %}\\n  {% set source_names = source_columns | map(attribute = 'column') | list %}\\n  {% set target_names = target_columns | map(attribute = 'column') | list %}\\n\\n   {# --check whether the name attribute exists in the target - this does not perform a data type check #}\\n   {% for sc in source_columns %}\\n     {% if sc.name not in target_names %}\\n        {{ result.append(sc) }}\\n     {% endif %}\\n   {% endfor %}\\n\\n  {{ return(result) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.6142552, \"supported_languages\": null}, \"macro.dbt.diff_column_data_types\": {\"name\": \"diff_column_data_types\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"unique_id\": \"macro.dbt.diff_column_data_types\", \"macro_sql\": \"{% macro diff_column_data_types(source_columns, target_columns) %}\\n\\n  {% set result = [] %}\\n  {% for sc in source_columns %}\\n    {% set tc = target_columns | selectattr(\\\"name\\\", \\\"equalto\\\", sc.name) | list | first %}\\n    {% if tc %}\\n      {% if sc.data_type != tc.data_type and not sc.can_expand_to(other_column=tc) %}\\n        {{ result.append( { 'column_name': tc.name, 'new_type': sc.data_type } ) }}\\n      {% endif %}\\n    {% endif %}\\n  {% endfor %}\\n\\n  {{ return(result) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.615365, \"supported_languages\": null}, \"macro.dbt.get_merge_update_columns\": {\"name\": \"get_merge_update_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"unique_id\": \"macro.dbt.get_merge_update_columns\", \"macro_sql\": \"{% macro get_merge_update_columns(merge_update_columns, merge_exclude_columns, dest_columns) %}\\n  {{ return(adapter.dispatch('get_merge_update_columns', 'dbt')(merge_update_columns, merge_exclude_columns, dest_columns)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_merge_update_columns\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.615764, \"supported_languages\": null}, \"macro.dbt.default__get_merge_update_columns\": {\"name\": \"default__get_merge_update_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"unique_id\": \"macro.dbt.default__get_merge_update_columns\", \"macro_sql\": \"{% macro default__get_merge_update_columns(merge_update_columns, merge_exclude_columns, dest_columns) %}\\n  {%- set default_cols = dest_columns | map(attribute=\\\"quoted\\\") | list -%}\\n\\n  {%- if merge_update_columns and merge_exclude_columns -%}\\n    {{ exceptions.raise_compiler_error(\\n        'Model cannot specify merge_update_columns and merge_exclude_columns. Please update model to use only one config'\\n    )}}\\n  {%- elif merge_update_columns -%}\\n    {%- set update_columns = merge_update_columns -%}\\n  {%- elif merge_exclude_columns -%}\\n    {%- set update_columns = [] -%}\\n    {%- for column in dest_columns -%}\\n      {% if column.column | lower not in merge_exclude_columns | map(\\\"lower\\\") | list %}\\n        {%- do update_columns.append(column.quoted) -%}\\n      {% endif %}\\n    {%- endfor -%}\\n  {%- else -%}\\n    {%- set update_columns = default_cols -%}\\n  {%- endif -%}\\n\\n  {{ return(update_columns) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.6169448, \"supported_languages\": null}, \"macro.dbt.get_merge_sql\": {\"name\": \"get_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"unique_id\": \"macro.dbt.get_merge_sql\", \"macro_sql\": \"{% macro get_merge_sql(target, source, unique_key, dest_columns, incremental_predicates=none) -%}\\n   -- back compat for old kwarg name\\n  {% set incremental_predicates = kwargs.get('predicates', incremental_predicates) %}\\n  {{ adapter.dispatch('get_merge_sql', 'dbt')(target, source, unique_key, dest_columns, incremental_predicates) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.6264052, \"supported_languages\": null}, \"macro.dbt.default__get_merge_sql\": {\"name\": \"default__get_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"unique_id\": \"macro.dbt.default__get_merge_sql\", \"macro_sql\": \"{% macro default__get_merge_sql(target, source, unique_key, dest_columns, incremental_predicates=none) -%}\\n    {%- set predicates = [] if incremental_predicates is none else [] + incremental_predicates -%}\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n    {%- set merge_update_columns = config.get('merge_update_columns') -%}\\n    {%- set merge_exclude_columns = config.get('merge_exclude_columns') -%}\\n    {%- set update_columns = get_merge_update_columns(merge_update_columns, merge_exclude_columns, dest_columns) -%}\\n    {%- set sql_header = config.get('sql_header', none) -%}\\n\\n    {% if unique_key %}\\n        {% if unique_key is sequence and unique_key is not mapping and unique_key is not string %}\\n            {% for key in unique_key %}\\n                {% set this_key_match %}\\n                    DBT_INTERNAL_SOURCE.{{ key }} = DBT_INTERNAL_DEST.{{ key }}\\n                {% endset %}\\n                {% do predicates.append(this_key_match) %}\\n            {% endfor %}\\n        {% else %}\\n            {% set unique_key_match %}\\n                DBT_INTERNAL_SOURCE.{{ unique_key }} = DBT_INTERNAL_DEST.{{ unique_key }}\\n            {% endset %}\\n            {% do predicates.append(unique_key_match) %}\\n        {% endif %}\\n    {% else %}\\n        {% do predicates.append('FALSE') %}\\n    {% endif %}\\n\\n    {{ sql_header if sql_header is not none }}\\n\\n    merge into {{ target }} as DBT_INTERNAL_DEST\\n        using {{ source }} as DBT_INTERNAL_SOURCE\\n        on {{\\\"(\\\" ~ predicates | join(\\\") and (\\\") ~ \\\")\\\"}}\\n\\n    {% if unique_key %}\\n    when matched then update set\\n        {% for column_name in update_columns -%}\\n            {{ column_name }} = DBT_INTERNAL_SOURCE.{{ column_name }}\\n            {%- if not loop.last %}, {%- endif %}\\n        {%- endfor %}\\n    {% endif %}\\n\\n    when not matched then insert\\n        ({{ dest_cols_csv }})\\n    values\\n        ({{ dest_cols_csv }})\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_quoted_csv\", \"macro.dbt.get_merge_update_columns\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.6290119, \"supported_languages\": null}, \"macro.dbt.get_delete_insert_merge_sql\": {\"name\": \"get_delete_insert_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"unique_id\": \"macro.dbt.get_delete_insert_merge_sql\", \"macro_sql\": \"{% macro get_delete_insert_merge_sql(target, source, unique_key, dest_columns, incremental_predicates) -%}\\n  {{ adapter.dispatch('get_delete_insert_merge_sql', 'dbt')(target, source, unique_key, dest_columns, incremental_predicates) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_delete_insert_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.6294458, \"supported_languages\": null}, \"macro.dbt.default__get_delete_insert_merge_sql\": {\"name\": \"default__get_delete_insert_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"unique_id\": \"macro.dbt.default__get_delete_insert_merge_sql\", \"macro_sql\": \"{% macro default__get_delete_insert_merge_sql(target, source, unique_key, dest_columns, incremental_predicates) -%}\\n\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n\\n    {% if unique_key %}\\n        {% if unique_key is sequence and unique_key is not string %}\\n            delete from {{target }}\\n            using {{ source }}\\n            where (\\n                {% for key in unique_key %}\\n                    {{ source }}.{{ key }} = {{ target }}.{{ key }}\\n                    {{ \\\"and \\\" if not loop.last}}\\n                {% endfor %}\\n                {% if incremental_predicates %}\\n                    {% for predicate in incremental_predicates %}\\n                        and {{ predicate }}\\n                    {% endfor %}\\n                {% endif %}\\n            );\\n        {% else %}\\n            delete from {{ target }}\\n            where (\\n                {{ unique_key }}) in (\\n                select ({{ unique_key }})\\n                from {{ source }}\\n            )\\n            {%- if incremental_predicates %}\\n                {% for predicate in incremental_predicates %}\\n                    and {{ predicate }}\\n                {% endfor %}\\n            {%- endif -%};\\n\\n        {% endif %}\\n    {% endif %}\\n\\n    insert into {{ target }} ({{ dest_cols_csv }})\\n    (\\n        select {{ dest_cols_csv }}\\n        from {{ source }}\\n    )\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_quoted_csv\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.63107, \"supported_languages\": null}, \"macro.dbt.get_insert_overwrite_merge_sql\": {\"name\": \"get_insert_overwrite_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"unique_id\": \"macro.dbt.get_insert_overwrite_merge_sql\", \"macro_sql\": \"{% macro get_insert_overwrite_merge_sql(target, source, dest_columns, predicates, include_sql_header=false) -%}\\n  {{ adapter.dispatch('get_insert_overwrite_merge_sql', 'dbt')(target, source, dest_columns, predicates, include_sql_header) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_insert_overwrite_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.631517, \"supported_languages\": null}, \"macro.dbt.default__get_insert_overwrite_merge_sql\": {\"name\": \"default__get_insert_overwrite_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"unique_id\": \"macro.dbt.default__get_insert_overwrite_merge_sql\", \"macro_sql\": \"{% macro default__get_insert_overwrite_merge_sql(target, source, dest_columns, predicates, include_sql_header) -%}\\n    {#-- The only time include_sql_header is True: --#}\\n    {#-- BigQuery + insert_overwrite strategy + \\\"static\\\" partitions config --#}\\n    {#-- We should consider including the sql header at the materialization level instead --#}\\n\\n    {%- set predicates = [] if predicates is none else [] + predicates -%}\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n    {%- set sql_header = config.get('sql_header', none) -%}\\n\\n    {{ sql_header if sql_header is not none and include_sql_header }}\\n\\n    merge into {{ target }} as DBT_INTERNAL_DEST\\n        using {{ source }} as DBT_INTERNAL_SOURCE\\n        on FALSE\\n\\n    when not matched by source\\n        {% if predicates %} and {{ predicates | join(' and ') }} {% endif %}\\n        then delete\\n\\n    when not matched then insert\\n        ({{ dest_cols_csv }})\\n    values\\n        ({{ dest_cols_csv }})\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_quoted_csv\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.632575, \"supported_languages\": null}, \"macro.dbt.is_incremental\": {\"name\": \"is_incremental\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/is_incremental.sql\", \"original_file_path\": \"macros/materializations/models/incremental/is_incremental.sql\", \"unique_id\": \"macro.dbt.is_incremental\", \"macro_sql\": \"{% macro is_incremental() %}\\n    {#-- do not run introspective queries in parsing #}\\n    {% if not execute %}\\n        {{ return(False) }}\\n    {% else %}\\n        {% set relation = adapter.get_relation(this.database, this.schema, this.table) %}\\n        {{ return(relation is not none\\n                  and relation.type == 'table'\\n                  and model.config.materialized == 'incremental'\\n                  and not should_full_refresh()) }}\\n    {% endif %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.should_full_refresh\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.633599, \"supported_languages\": null}, \"macro.dbt.get_incremental_append_sql\": {\"name\": \"get_incremental_append_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.get_incremental_append_sql\", \"macro_sql\": \"{% macro get_incremental_append_sql(arg_dict) %}\\n\\n  {{ return(adapter.dispatch('get_incremental_append_sql', 'dbt')(arg_dict)) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_incremental_append_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.635051, \"supported_languages\": null}, \"macro.dbt.default__get_incremental_append_sql\": {\"name\": \"default__get_incremental_append_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.default__get_incremental_append_sql\", \"macro_sql\": \"{% macro default__get_incremental_append_sql(arg_dict) %}\\n\\n  {% do return(get_insert_into_sql(arg_dict[\\\"target_relation\\\"], arg_dict[\\\"temp_relation\\\"], arg_dict[\\\"dest_columns\\\"])) %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_insert_into_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.635458, \"supported_languages\": null}, \"macro.dbt.get_incremental_delete_insert_sql\": {\"name\": \"get_incremental_delete_insert_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.get_incremental_delete_insert_sql\", \"macro_sql\": \"{% macro get_incremental_delete_insert_sql(arg_dict) %}\\n\\n  {{ return(adapter.dispatch('get_incremental_delete_insert_sql', 'dbt')(arg_dict)) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_incremental_delete_insert_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.63577, \"supported_languages\": null}, \"macro.dbt.default__get_incremental_delete_insert_sql\": {\"name\": \"default__get_incremental_delete_insert_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.default__get_incremental_delete_insert_sql\", \"macro_sql\": \"{% macro default__get_incremental_delete_insert_sql(arg_dict) %}\\n\\n  {% do return(get_delete_insert_merge_sql(arg_dict[\\\"target_relation\\\"], arg_dict[\\\"temp_relation\\\"], arg_dict[\\\"unique_key\\\"], arg_dict[\\\"dest_columns\\\"], arg_dict[\\\"incremental_predicates\\\"])) %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_delete_insert_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.6362581, \"supported_languages\": null}, \"macro.dbt.get_incremental_merge_sql\": {\"name\": \"get_incremental_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.get_incremental_merge_sql\", \"macro_sql\": \"{% macro get_incremental_merge_sql(arg_dict) %}\\n\\n  {{ return(adapter.dispatch('get_incremental_merge_sql', 'dbt')(arg_dict)) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_incremental_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.636678, \"supported_languages\": null}, \"macro.dbt.default__get_incremental_merge_sql\": {\"name\": \"default__get_incremental_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.default__get_incremental_merge_sql\", \"macro_sql\": \"{% macro default__get_incremental_merge_sql(arg_dict) %}\\n\\n  {% do return(get_merge_sql(arg_dict[\\\"target_relation\\\"], arg_dict[\\\"temp_relation\\\"], arg_dict[\\\"unique_key\\\"], arg_dict[\\\"dest_columns\\\"], arg_dict[\\\"incremental_predicates\\\"])) %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.637161, \"supported_languages\": null}, \"macro.dbt.get_incremental_insert_overwrite_sql\": {\"name\": \"get_incremental_insert_overwrite_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.get_incremental_insert_overwrite_sql\", \"macro_sql\": \"{% macro get_incremental_insert_overwrite_sql(arg_dict) %}\\n\\n  {{ return(adapter.dispatch('get_incremental_insert_overwrite_sql', 'dbt')(arg_dict)) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_incremental_insert_overwrite_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.637471, \"supported_languages\": null}, \"macro.dbt.default__get_incremental_insert_overwrite_sql\": {\"name\": \"default__get_incremental_insert_overwrite_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.default__get_incremental_insert_overwrite_sql\", \"macro_sql\": \"{% macro default__get_incremental_insert_overwrite_sql(arg_dict) %}\\n\\n  {% do return(get_insert_overwrite_merge_sql(arg_dict[\\\"target_relation\\\"], arg_dict[\\\"temp_relation\\\"], arg_dict[\\\"dest_columns\\\"], arg_dict[\\\"incremental_predicates\\\"])) %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_insert_overwrite_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.6379, \"supported_languages\": null}, \"macro.dbt.get_incremental_default_sql\": {\"name\": \"get_incremental_default_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.get_incremental_default_sql\", \"macro_sql\": \"{% macro get_incremental_default_sql(arg_dict) %}\\n\\n  {{ return(adapter.dispatch('get_incremental_default_sql', 'dbt')(arg_dict)) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_incremental_default_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.6382148, \"supported_languages\": null}, \"macro.dbt.default__get_incremental_default_sql\": {\"name\": \"default__get_incremental_default_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.default__get_incremental_default_sql\", \"macro_sql\": \"{% macro default__get_incremental_default_sql(arg_dict) %}\\n\\n  {% do return(get_incremental_append_sql(arg_dict)) %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_incremental_append_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.63846, \"supported_languages\": null}, \"macro.dbt.get_insert_into_sql\": {\"name\": \"get_insert_into_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.get_insert_into_sql\", \"macro_sql\": \"{% macro get_insert_into_sql(target_relation, temp_relation, dest_columns) %}\\n\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n\\n    insert into {{ target_relation }} ({{ dest_cols_csv }})\\n    (\\n        select {{ dest_cols_csv }}\\n        from {{ temp_relation }}\\n    )\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_quoted_csv\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.6389172, \"supported_languages\": null}, \"macro.dbt.materialization_incremental_default\": {\"name\": \"materialization_incremental_default\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/incremental.sql\", \"original_file_path\": \"macros/materializations/models/incremental/incremental.sql\", \"unique_id\": \"macro.dbt.materialization_incremental_default\", \"macro_sql\": \"{% materialization incremental, default -%}\\n\\n  -- relations\\n  {%- set existing_relation = load_cached_relation(this) -%}\\n  {%- set target_relation = this.incorporate(type='table') -%}\\n  {%- set temp_relation = make_temp_relation(target_relation)-%}\\n  {%- set intermediate_relation = make_intermediate_relation(target_relation)-%}\\n  {%- set backup_relation_type = 'table' if existing_relation is none else existing_relation.type -%}\\n  {%- set backup_relation = make_backup_relation(target_relation, backup_relation_type) -%}\\n\\n  -- configs\\n  {%- set unique_key = config.get('unique_key') -%}\\n  {%- set full_refresh_mode = (should_full_refresh()  or existing_relation.is_view) -%}\\n  {%- set on_schema_change = incremental_validate_on_schema_change(config.get('on_schema_change'), default='ignore') -%}\\n\\n  -- the temp_ and backup_ relations should not already exist in the database; get_relation\\n  -- will return None in that case. Otherwise, we get a relation that we can drop\\n  -- later, before we try to use this name for the current operation. This has to happen before\\n  -- BEGIN, in a separate transaction\\n  {%- set preexisting_intermediate_relation = load_cached_relation(intermediate_relation)-%}\\n  {%- set preexisting_backup_relation = load_cached_relation(backup_relation) -%}\\n   -- grab current tables grants config for comparision later on\\n  {% set grant_config = config.get('grants') %}\\n  {{ drop_relation_if_exists(preexisting_intermediate_relation) }}\\n  {{ drop_relation_if_exists(preexisting_backup_relation) }}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  {% set to_drop = [] %}\\n\\n  {% if existing_relation is none %}\\n      {% set build_sql = get_create_table_as_sql(False, target_relation, sql) %}\\n  {% elif full_refresh_mode %}\\n      {% set build_sql = get_create_table_as_sql(False, intermediate_relation, sql) %}\\n      {% set need_swap = true %}\\n  {% else %}\\n    {% do run_query(get_create_table_as_sql(True, temp_relation, sql)) %}\\n    {% do adapter.expand_target_column_types(\\n             from_relation=temp_relation,\\n             to_relation=target_relation) %}\\n    {#-- Process schema changes. Returns dict of changes if successful. Use source columns for upserting/merging --#}\\n    {% set dest_columns = process_schema_changes(on_schema_change, temp_relation, existing_relation) %}\\n    {% if not dest_columns %}\\n      {% set dest_columns = adapter.get_columns_in_relation(existing_relation) %}\\n    {% endif %}\\n\\n    {#-- Get the incremental_strategy, the macro to use for the strategy, and build the sql --#}\\n    {% set incremental_strategy = config.get('incremental_strategy') or 'default' %}\\n    {% set incremental_predicates = config.get('predicates', none) or config.get('incremental_predicates', none) %}\\n    {% set strategy_sql_macro_func = adapter.get_incremental_strategy_macro(context, incremental_strategy) %}\\n    {% set strategy_arg_dict = ({'target_relation': target_relation, 'temp_relation': temp_relation, 'unique_key': unique_key, 'dest_columns': dest_columns, 'incremental_predicates': incremental_predicates }) %}\\n    {% set build_sql = strategy_sql_macro_func(strategy_arg_dict) %}\\n\\n  {% endif %}\\n\\n  {% call statement(\\\"main\\\") %}\\n      {{ build_sql }}\\n  {% endcall %}\\n\\n  {% if need_swap %}\\n      {% do adapter.rename_relation(target_relation, backup_relation) %}\\n      {% do adapter.rename_relation(intermediate_relation, target_relation) %}\\n      {% do to_drop.append(backup_relation) %}\\n  {% endif %}\\n\\n  {% set should_revoke = should_revoke(existing_relation, full_refresh_mode) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {% if existing_relation is none or existing_relation.is_view or should_full_refresh() %}\\n    {% do create_indexes(target_relation) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  -- `COMMIT` happens here\\n  {% do adapter.commit() %}\\n\\n  {% for rel in to_drop %}\\n      {% do adapter.drop_relation(rel) %}\\n  {% endfor %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{%- endmaterialization %}\", \"depends_on\": {\"macros\": [\"macro.dbt.load_cached_relation\", \"macro.dbt.make_temp_relation\", \"macro.dbt.make_intermediate_relation\", \"macro.dbt.make_backup_relation\", \"macro.dbt.should_full_refresh\", \"macro.dbt.incremental_validate_on_schema_change\", \"macro.dbt.drop_relation_if_exists\", \"macro.dbt.run_hooks\", \"macro.dbt.get_create_table_as_sql\", \"macro.dbt.run_query\", \"macro.dbt.process_schema_changes\", \"macro.dbt.statement\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\", \"macro.dbt.persist_docs\", \"macro.dbt.create_indexes\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.647358, \"supported_languages\": [\"sql\"]}, \"macro.dbt.incremental_validate_on_schema_change\": {\"name\": \"incremental_validate_on_schema_change\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"original_file_path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"unique_id\": \"macro.dbt.incremental_validate_on_schema_change\", \"macro_sql\": \"{% macro incremental_validate_on_schema_change(on_schema_change, default='ignore') %}\\n\\n   {% if on_schema_change not in ['sync_all_columns', 'append_new_columns', 'fail', 'ignore'] %}\\n\\n     {% set log_message = 'Invalid value for on_schema_change (%s) specified. Setting default value of %s.' % (on_schema_change, default) %}\\n     {% do log(log_message) %}\\n\\n     {{ return(default) }}\\n\\n   {% else %}\\n\\n     {{ return(on_schema_change) }}\\n\\n   {% endif %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.655884, \"supported_languages\": null}, \"macro.dbt.check_for_schema_changes\": {\"name\": \"check_for_schema_changes\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"original_file_path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"unique_id\": \"macro.dbt.check_for_schema_changes\", \"macro_sql\": \"{% macro check_for_schema_changes(source_relation, target_relation) %}\\n\\n  {% set schema_changed = False %}\\n\\n  {%- set source_columns = adapter.get_columns_in_relation(source_relation) -%}\\n  {%- set target_columns = adapter.get_columns_in_relation(target_relation) -%}\\n  {%- set source_not_in_target = diff_columns(source_columns, target_columns) -%}\\n  {%- set target_not_in_source = diff_columns(target_columns, source_columns) -%}\\n\\n  {% set new_target_types = diff_column_data_types(source_columns, target_columns) %}\\n\\n  {% if source_not_in_target != [] %}\\n    {% set schema_changed = True %}\\n  {% elif target_not_in_source != [] or new_target_types != [] %}\\n    {% set schema_changed = True %}\\n  {% elif new_target_types != [] %}\\n    {% set schema_changed = True %}\\n  {% endif %}\\n\\n  {% set changes_dict = {\\n    'schema_changed': schema_changed,\\n    'source_not_in_target': source_not_in_target,\\n    'target_not_in_source': target_not_in_source,\\n    'source_columns': source_columns,\\n    'target_columns': target_columns,\\n    'new_target_types': new_target_types\\n  } %}\\n\\n  {% set msg %}\\n    In {{ target_relation }}:\\n        Schema changed: {{ schema_changed }}\\n        Source columns not in target: {{ source_not_in_target }}\\n        Target columns not in source: {{ target_not_in_source }}\\n        New column types: {{ new_target_types }}\\n  {% endset %}\\n\\n  {% do log(msg) %}\\n\\n  {{ return(changes_dict) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.diff_columns\", \"macro.dbt.diff_column_data_types\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.657853, \"supported_languages\": null}, \"macro.dbt.sync_column_schemas\": {\"name\": \"sync_column_schemas\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"original_file_path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"unique_id\": \"macro.dbt.sync_column_schemas\", \"macro_sql\": \"{% macro sync_column_schemas(on_schema_change, target_relation, schema_changes_dict) %}\\n\\n  {%- set add_to_target_arr = schema_changes_dict['source_not_in_target'] -%}\\n\\n  {%- if on_schema_change == 'append_new_columns'-%}\\n     {%- if add_to_target_arr | length > 0 -%}\\n       {%- do alter_relation_add_remove_columns(target_relation, add_to_target_arr, none) -%}\\n     {%- endif -%}\\n\\n  {% elif on_schema_change == 'sync_all_columns' %}\\n     {%- set remove_from_target_arr = schema_changes_dict['target_not_in_source'] -%}\\n     {%- set new_target_types = schema_changes_dict['new_target_types'] -%}\\n\\n     {% if add_to_target_arr | length > 0 or remove_from_target_arr | length > 0 %}\\n       {%- do alter_relation_add_remove_columns(target_relation, add_to_target_arr, remove_from_target_arr) -%}\\n     {% endif %}\\n\\n     {% if new_target_types != [] %}\\n       {% for ntt in new_target_types %}\\n         {% set column_name = ntt['column_name'] %}\\n         {% set new_type = ntt['new_type'] %}\\n         {% do alter_column_type(target_relation, column_name, new_type) %}\\n       {% endfor %}\\n     {% endif %}\\n\\n  {% endif %}\\n\\n  {% set schema_change_message %}\\n    In {{ target_relation }}:\\n        Schema change approach: {{ on_schema_change }}\\n        Columns added: {{ add_to_target_arr }}\\n        Columns removed: {{ remove_from_target_arr }}\\n        Data types changed: {{ new_target_types }}\\n  {% endset %}\\n\\n  {% do log(schema_change_message) %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.alter_relation_add_remove_columns\", \"macro.dbt.alter_column_type\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.659792, \"supported_languages\": null}, \"macro.dbt.process_schema_changes\": {\"name\": \"process_schema_changes\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"original_file_path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"unique_id\": \"macro.dbt.process_schema_changes\", \"macro_sql\": \"{% macro process_schema_changes(on_schema_change, source_relation, target_relation) %}\\n\\n    {% if on_schema_change == 'ignore' %}\\n\\n     {{ return({}) }}\\n\\n    {% else %}\\n\\n      {% set schema_changes_dict = check_for_schema_changes(source_relation, target_relation) %}\\n\\n      {% if schema_changes_dict['schema_changed'] %}\\n\\n        {% if on_schema_change == 'fail' %}\\n\\n          {% set fail_msg %}\\n              The source and target schemas on this incremental model are out of sync!\\n              They can be reconciled in several ways:\\n                - set the `on_schema_change` config to either append_new_columns or sync_all_columns, depending on your situation.\\n                - Re-run the incremental model with `full_refresh: True` to update the target schema.\\n                - update the schema manually and re-run the process.\\n\\n              Additional troubleshooting context:\\n                 Source columns not in target: {{ schema_changes_dict['source_not_in_target'] }}\\n                 Target columns not in source: {{ schema_changes_dict['target_not_in_source'] }}\\n                 New column types: {{ schema_changes_dict['new_target_types'] }}\\n          {% endset %}\\n\\n          {% do exceptions.raise_compiler_error(fail_msg) %}\\n\\n        {# -- unless we ignore, run the sync operation per the config #}\\n        {% else %}\\n\\n          {% do sync_column_schemas(on_schema_change, target_relation, schema_changes_dict) %}\\n\\n        {% endif %}\\n\\n      {% endif %}\\n\\n      {{ return(schema_changes_dict['source_columns']) }}\\n\\n    {% endif %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.check_for_schema_changes\", \"macro.dbt.sync_column_schemas\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.6611788, \"supported_languages\": null}, \"macro.dbt.can_clone_table\": {\"name\": \"can_clone_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/clone/can_clone_table.sql\", \"original_file_path\": \"macros/materializations/models/clone/can_clone_table.sql\", \"unique_id\": \"macro.dbt.can_clone_table\", \"macro_sql\": \"{% macro can_clone_table() %}\\n    {{ return(adapter.dispatch('can_clone_table', 'dbt')()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__can_clone_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.661578, \"supported_languages\": null}, \"macro.dbt.default__can_clone_table\": {\"name\": \"default__can_clone_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/clone/can_clone_table.sql\", \"original_file_path\": \"macros/materializations/models/clone/can_clone_table.sql\", \"unique_id\": \"macro.dbt.default__can_clone_table\", \"macro_sql\": \"{% macro default__can_clone_table() %}\\n    {{ return(False) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.6617699, \"supported_languages\": null}, \"macro.dbt.create_or_replace_clone\": {\"name\": \"create_or_replace_clone\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/clone/create_or_replace_clone.sql\", \"original_file_path\": \"macros/materializations/models/clone/create_or_replace_clone.sql\", \"unique_id\": \"macro.dbt.create_or_replace_clone\", \"macro_sql\": \"{% macro create_or_replace_clone(this_relation, defer_relation) %}\\n    {{ return(adapter.dispatch('create_or_replace_clone', 'dbt')(this_relation, defer_relation)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__create_or_replace_clone\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.662251, \"supported_languages\": null}, \"macro.dbt.default__create_or_replace_clone\": {\"name\": \"default__create_or_replace_clone\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/clone/create_or_replace_clone.sql\", \"original_file_path\": \"macros/materializations/models/clone/create_or_replace_clone.sql\", \"unique_id\": \"macro.dbt.default__create_or_replace_clone\", \"macro_sql\": \"{% macro default__create_or_replace_clone(this_relation, defer_relation) %}\\n    create or replace table {{ this_relation }} clone {{ defer_relation }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.662475, \"supported_languages\": null}, \"macro.dbt.materialization_clone_default\": {\"name\": \"materialization_clone_default\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/clone/clone.sql\", \"original_file_path\": \"macros/materializations/models/clone/clone.sql\", \"unique_id\": \"macro.dbt.materialization_clone_default\", \"macro_sql\": \"{%- materialization clone, default -%}\\n\\n  {%- set relations = {'relations': []} -%}\\n\\n  {%- if not defer_relation -%}\\n      -- nothing to do\\n      {{ log(\\\"No relation found in state manifest for \\\" ~ model.unique_id, info=True) }}\\n      {{ return(relations) }}\\n  {%- endif -%}\\n\\n  {%- set existing_relation = load_cached_relation(this) -%}\\n\\n  {%- if existing_relation and not flags.FULL_REFRESH -%}\\n      -- noop!\\n      {{ log(\\\"Relation \\\" ~ existing_relation ~ \\\" already exists\\\", info=True) }}\\n      {{ return(relations) }}\\n  {%- endif -%}\\n\\n  {%- set other_existing_relation = load_cached_relation(defer_relation) -%}\\n\\n  -- If this is a database that can do zero-copy cloning of tables, and the other relation is a table, then this will be a table\\n  -- Otherwise, this will be a view\\n\\n  {% set can_clone_table = can_clone_table() %}\\n\\n  {%- if other_existing_relation and other_existing_relation.type == 'table' and can_clone_table -%}\\n\\n      {%- set target_relation = this.incorporate(type='table') -%}\\n      {% if existing_relation is not none and not existing_relation.is_table %}\\n        {{ log(\\\"Dropping relation \\\" ~ existing_relation ~ \\\" because it is of type \\\" ~ existing_relation.type) }}\\n        {{ drop_relation_if_exists(existing_relation) }}\\n      {% endif %}\\n\\n      -- as a general rule, data platforms that can clone tables can also do atomic 'create or replace'\\n      {% call statement('main') %}\\n          {% if target_relation and defer_relation and target_relation == defer_relation %}\\n              {{ log(\\\"Target relation and defer relation are the same, skipping clone for relation: \\\" ~ target_relation) }}\\n          {% else %}\\n              {{ create_or_replace_clone(target_relation, defer_relation) }}\\n          {% endif %}\\n\\n      {% endcall %}\\n\\n      {% set should_revoke = should_revoke(existing_relation, full_refresh_mode=True) %}\\n      {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n      {% do persist_docs(target_relation, model) %}\\n\\n      {{ return({'relations': [target_relation]}) }}\\n\\n  {%- else -%}\\n\\n      {%- set target_relation = this.incorporate(type='view') -%}\\n\\n      -- reuse the view materialization\\n      -- TODO: support actual dispatch for materialization macros\\n      -- Tracking ticket: https://github.com/dbt-labs/dbt-core/issues/7799\\n      {% set search_name = \\\"materialization_view_\\\" ~ adapter.type() %}\\n      {% if not search_name in context %}\\n          {% set search_name = \\\"materialization_view_default\\\" %}\\n      {% endif %}\\n      {% set materialization_macro = context[search_name] %}\\n      {% set relations = materialization_macro() %}\\n      {{ return(relations) }}\\n\\n  {%- endif -%}\\n\\n{%- endmaterialization -%}\", \"depends_on\": {\"macros\": [\"macro.dbt.load_cached_relation\", \"macro.dbt.can_clone_table\", \"macro.dbt.drop_relation_if_exists\", \"macro.dbt.statement\", \"macro.dbt.create_or_replace_clone\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\", \"macro.dbt.persist_docs\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.668271, \"supported_languages\": [\"sql\"]}, \"macro.dbt.materialization_seed_default\": {\"name\": \"materialization_seed_default\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/seed.sql\", \"original_file_path\": \"macros/materializations/seeds/seed.sql\", \"unique_id\": \"macro.dbt.materialization_seed_default\", \"macro_sql\": \"{% materialization seed, default %}\\n\\n  {%- set identifier = model['alias'] -%}\\n  {%- set full_refresh_mode = (should_full_refresh()) -%}\\n\\n  {%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%}\\n\\n  {%- set exists_as_table = (old_relation is not none and old_relation.is_table) -%}\\n  {%- set exists_as_view = (old_relation is not none and old_relation.is_view) -%}\\n\\n  {%- set grant_config = config.get('grants') -%}\\n  {%- set agate_table = load_agate_table() -%}\\n  -- grab current tables grants config for comparison later on\\n\\n  {%- do store_result('agate_table', response='OK', agate_table=agate_table) -%}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  -- build model\\n  {% set create_table_sql = \\\"\\\" %}\\n  {% if exists_as_view %}\\n    {{ exceptions.raise_compiler_error(\\\"Cannot seed to '{}', it is a view\\\".format(old_relation)) }}\\n  {% elif exists_as_table %}\\n    {% set create_table_sql = reset_csv_table(model, full_refresh_mode, old_relation, agate_table) %}\\n  {% else %}\\n    {% set create_table_sql = create_csv_table(model, agate_table) %}\\n  {% endif %}\\n\\n  {% set code = 'CREATE' if full_refresh_mode else 'INSERT' %}\\n  {% set rows_affected = (agate_table.rows | length) %}\\n  {% set sql = load_csv_rows(model, agate_table) %}\\n\\n  {% call noop_statement('main', code ~ ' ' ~ rows_affected, code, rows_affected) %}\\n    {{ get_csv_sql(create_table_sql, sql) }};\\n  {% endcall %}\\n\\n  {% set target_relation = this.incorporate(type='table') %}\\n\\n  {% set should_revoke = should_revoke(old_relation, full_refresh_mode) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {% if full_refresh_mode or not exists_as_table %}\\n    {% do create_indexes(target_relation) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  -- `COMMIT` happens here\\n  {{ adapter.commit() }}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{% endmaterialization %}\", \"depends_on\": {\"macros\": [\"macro.dbt.should_full_refresh\", \"macro.dbt.run_hooks\", \"macro.dbt.reset_csv_table\", \"macro.dbt.create_csv_table\", \"macro.dbt.load_csv_rows\", \"macro.dbt.noop_statement\", \"macro.dbt.get_csv_sql\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\", \"macro.dbt.persist_docs\", \"macro.dbt.create_indexes\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.673449, \"supported_languages\": [\"sql\"]}, \"macro.dbt.create_csv_table\": {\"name\": \"create_csv_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.create_csv_table\", \"macro_sql\": \"{% macro create_csv_table(model, agate_table) -%}\\n  {{ adapter.dispatch('create_csv_table', 'dbt')(model, agate_table) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__create_csv_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.681057, \"supported_languages\": null}, \"macro.dbt.default__create_csv_table\": {\"name\": \"default__create_csv_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.default__create_csv_table\", \"macro_sql\": \"{% macro default__create_csv_table(model, agate_table) %}\\n  {%- set column_override = model['config'].get('column_types', {}) -%}\\n  {%- set quote_seed_column = model['config'].get('quote_columns', None) -%}\\n\\n  {% set sql %}\\n    create table {{ this.render() }} (\\n        {%- for col_name in agate_table.column_names -%}\\n            {%- set inferred_type = adapter.convert_type(agate_table, loop.index0) -%}\\n            {%- set type = column_override.get(col_name, inferred_type) -%}\\n            {%- set column_name = (col_name | string) -%}\\n            {{ adapter.quote_seed_column(column_name, quote_seed_column) }} {{ type }} {%- if not loop.last -%}, {%- endif -%}\\n        {%- endfor -%}\\n    )\\n  {% endset %}\\n\\n  {% call statement('_') -%}\\n    {{ sql }}\\n  {%- endcall %}\\n\\n  {{ return(sql) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.682514, \"supported_languages\": null}, \"macro.dbt.reset_csv_table\": {\"name\": \"reset_csv_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.reset_csv_table\", \"macro_sql\": \"{% macro reset_csv_table(model, full_refresh, old_relation, agate_table) -%}\\n  {{ adapter.dispatch('reset_csv_table', 'dbt')(model, full_refresh, old_relation, agate_table) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__reset_csv_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.6828969, \"supported_languages\": null}, \"macro.dbt.default__reset_csv_table\": {\"name\": \"default__reset_csv_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.default__reset_csv_table\", \"macro_sql\": \"{% macro default__reset_csv_table(model, full_refresh, old_relation, agate_table) %}\\n    {% set sql = \\\"\\\" %}\\n    {% if full_refresh %}\\n        {{ adapter.drop_relation(old_relation) }}\\n        {% set sql = create_csv_table(model, agate_table) %}\\n    {% else %}\\n        {{ adapter.truncate_relation(old_relation) }}\\n        {% set sql = \\\"truncate table \\\" ~ old_relation %}\\n    {% endif %}\\n\\n    {{ return(sql) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.create_csv_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.6836748, \"supported_languages\": null}, \"macro.dbt.get_csv_sql\": {\"name\": \"get_csv_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.get_csv_sql\", \"macro_sql\": \"{% macro get_csv_sql(create_or_truncate_sql, insert_sql) %}\\n    {{ adapter.dispatch('get_csv_sql', 'dbt')(create_or_truncate_sql, insert_sql) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_csv_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.6839921, \"supported_languages\": null}, \"macro.dbt.default__get_csv_sql\": {\"name\": \"default__get_csv_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.default__get_csv_sql\", \"macro_sql\": \"{% macro default__get_csv_sql(create_or_truncate_sql, insert_sql) %}\\n    {{ create_or_truncate_sql }};\\n    -- dbt seed --\\n    {{ insert_sql }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.684214, \"supported_languages\": null}, \"macro.dbt.get_binding_char\": {\"name\": \"get_binding_char\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.get_binding_char\", \"macro_sql\": \"{% macro get_binding_char() -%}\\n  {{ adapter.dispatch('get_binding_char', 'dbt')() }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_binding_char\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.684445, \"supported_languages\": null}, \"macro.dbt.default__get_binding_char\": {\"name\": \"default__get_binding_char\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.default__get_binding_char\", \"macro_sql\": \"{% macro default__get_binding_char() %}\\n  {{ return('%s') }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.684631, \"supported_languages\": null}, \"macro.dbt.get_batch_size\": {\"name\": \"get_batch_size\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.get_batch_size\", \"macro_sql\": \"{% macro get_batch_size() -%}\\n  {{ return(adapter.dispatch('get_batch_size', 'dbt')()) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_batch_size\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.684887, \"supported_languages\": null}, \"macro.dbt.default__get_batch_size\": {\"name\": \"default__get_batch_size\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.default__get_batch_size\", \"macro_sql\": \"{% macro default__get_batch_size() %}\\n  {{ return(10000) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.68508, \"supported_languages\": null}, \"macro.dbt.get_seed_column_quoted_csv\": {\"name\": \"get_seed_column_quoted_csv\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.get_seed_column_quoted_csv\", \"macro_sql\": \"{% macro get_seed_column_quoted_csv(model, column_names) %}\\n  {%- set quote_seed_column = model['config'].get('quote_columns', None) -%}\\n    {% set quoted = [] %}\\n    {% for col in column_names -%}\\n        {%- do quoted.append(adapter.quote_seed_column(col, quote_seed_column)) -%}\\n    {%- endfor %}\\n\\n    {%- set dest_cols_csv = quoted | join(', ') -%}\\n    {{ return(dest_cols_csv) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.6858501, \"supported_languages\": null}, \"macro.dbt.load_csv_rows\": {\"name\": \"load_csv_rows\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.load_csv_rows\", \"macro_sql\": \"{% macro load_csv_rows(model, agate_table) -%}\\n  {{ adapter.dispatch('load_csv_rows', 'dbt')(model, agate_table) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__load_csv_rows\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.686155, \"supported_languages\": null}, \"macro.dbt.default__load_csv_rows\": {\"name\": \"default__load_csv_rows\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.default__load_csv_rows\", \"macro_sql\": \"{% macro default__load_csv_rows(model, agate_table) %}\\n\\n  {% set batch_size = get_batch_size() %}\\n\\n  {% set cols_sql = get_seed_column_quoted_csv(model, agate_table.column_names) %}\\n  {% set bindings = [] %}\\n\\n  {% set statements = [] %}\\n\\n  {% for chunk in agate_table.rows | batch(batch_size) %}\\n      {% set bindings = [] %}\\n\\n      {% for row in chunk %}\\n          {% do bindings.extend(row) %}\\n      {% endfor %}\\n\\n      {% set sql %}\\n          insert into {{ this.render() }} ({{ cols_sql }}) values\\n          {% for row in chunk -%}\\n              ({%- for column in agate_table.column_names -%}\\n                  {{ get_binding_char() }}\\n                  {%- if not loop.last%},{%- endif %}\\n              {%- endfor -%})\\n              {%- if not loop.last%},{%- endif %}\\n          {%- endfor %}\\n      {% endset %}\\n\\n      {% do adapter.add_query(sql, bindings=bindings, abridge_sql_log=True) %}\\n\\n      {% if loop.index0 == 0 %}\\n          {% do statements.append(sql) %}\\n      {% endif %}\\n  {% endfor %}\\n\\n  {# Return SQL so we can render it out into the compiled files #}\\n  {{ return(statements[0]) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_batch_size\", \"macro.dbt.get_seed_column_quoted_csv\", \"macro.dbt.get_binding_char\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.688233, \"supported_languages\": null}, \"macro.dbt.generate_alias_name\": {\"name\": \"generate_alias_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/get_custom_name/get_custom_alias.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_alias.sql\", \"unique_id\": \"macro.dbt.generate_alias_name\", \"macro_sql\": \"{% macro generate_alias_name(custom_alias_name=none, node=none) -%}\\n    {% do return(adapter.dispatch('generate_alias_name', 'dbt')(custom_alias_name, node)) %}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__generate_alias_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.68893, \"supported_languages\": null}, \"macro.dbt.default__generate_alias_name\": {\"name\": \"default__generate_alias_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/get_custom_name/get_custom_alias.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_alias.sql\", \"unique_id\": \"macro.dbt.default__generate_alias_name\", \"macro_sql\": \"{% macro default__generate_alias_name(custom_alias_name=none, node=none) -%}\\n\\n    {%- if custom_alias_name -%}\\n\\n        {{ custom_alias_name | trim }}\\n\\n    {%- elif node.version -%}\\n\\n        {{ return(node.name ~ \\\"_v\\\" ~ (node.version | replace(\\\".\\\", \\\"_\\\"))) }}\\n\\n    {%- else -%}\\n\\n        {{ node.name }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.6895602, \"supported_languages\": null}, \"macro.dbt.generate_schema_name\": {\"name\": \"generate_schema_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/get_custom_name/get_custom_schema.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_schema.sql\", \"unique_id\": \"macro.dbt.generate_schema_name\", \"macro_sql\": \"{% macro generate_schema_name(custom_schema_name=none, node=none) -%}\\n    {{ return(adapter.dispatch('generate_schema_name', 'dbt')(custom_schema_name, node)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__generate_schema_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.69043, \"supported_languages\": null}, \"macro.dbt.default__generate_schema_name\": {\"name\": \"default__generate_schema_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/get_custom_name/get_custom_schema.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_schema.sql\", \"unique_id\": \"macro.dbt.default__generate_schema_name\", \"macro_sql\": \"{% macro default__generate_schema_name(custom_schema_name, node) -%}\\n\\n    {%- set default_schema = target.schema -%}\\n    {%- if custom_schema_name is none -%}\\n\\n        {{ default_schema }}\\n\\n    {%- else -%}\\n\\n        {{ default_schema }}_{{ custom_schema_name | trim }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.690857, \"supported_languages\": null}, \"macro.dbt.generate_schema_name_for_env\": {\"name\": \"generate_schema_name_for_env\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/get_custom_name/get_custom_schema.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_schema.sql\", \"unique_id\": \"macro.dbt.generate_schema_name_for_env\", \"macro_sql\": \"{% macro generate_schema_name_for_env(custom_schema_name, node) -%}\\n\\n    {%- set default_schema = target.schema -%}\\n    {%- if target.name == 'prod' and custom_schema_name is not none -%}\\n\\n        {{ custom_schema_name | trim }}\\n\\n    {%- else -%}\\n\\n        {{ default_schema }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.6913202, \"supported_languages\": null}, \"macro.dbt.generate_database_name\": {\"name\": \"generate_database_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/get_custom_name/get_custom_database.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_database.sql\", \"unique_id\": \"macro.dbt.generate_database_name\", \"macro_sql\": \"{% macro generate_database_name(custom_database_name=none, node=none) -%}\\n    {% do return(adapter.dispatch('generate_database_name', 'dbt')(custom_database_name, node)) %}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__generate_database_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.691966, \"supported_languages\": null}, \"macro.dbt.default__generate_database_name\": {\"name\": \"default__generate_database_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/get_custom_name/get_custom_database.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_database.sql\", \"unique_id\": \"macro.dbt.default__generate_database_name\", \"macro_sql\": \"{% macro default__generate_database_name(custom_database_name=none, node=none) -%}\\n    {%- set default_database = target.database -%}\\n    {%- if custom_database_name is none -%}\\n\\n        {{ default_database }}\\n\\n    {%- else -%}\\n\\n        {{ custom_database_name }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.692378, \"supported_languages\": null}, \"macro.dbt.get_drop_sql\": {\"name\": \"get_drop_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/drop.sql\", \"original_file_path\": \"macros/relations/drop.sql\", \"unique_id\": \"macro.dbt.get_drop_sql\", \"macro_sql\": \"{%- macro get_drop_sql(relation) -%}\\n    {{- log('Applying DROP to: ' ~ relation) -}}\\n    {{- adapter.dispatch('get_drop_sql', 'dbt')(relation) -}}\\n{%- endmacro -%}\\n\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_drop_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.693515, \"supported_languages\": null}, \"macro.dbt.default__get_drop_sql\": {\"name\": \"default__get_drop_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/drop.sql\", \"original_file_path\": \"macros/relations/drop.sql\", \"unique_id\": \"macro.dbt.default__get_drop_sql\", \"macro_sql\": \"{%- macro default__get_drop_sql(relation) -%}\\n\\n    {%- if relation.is_view -%}\\n        {{ drop_view(relation) }}\\n\\n    {%- elif relation.is_table -%}\\n        {{ drop_table(relation) }}\\n\\n    {%- elif relation.is_materialized_view -%}\\n        {{ drop_materialized_view(relation) }}\\n\\n    {%- else -%}\\n        drop {{ relation.type }} if exists {{ relation }} cascade\\n\\n    {%- endif -%}\\n\\n{%- endmacro -%}\\n\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.drop_view\", \"macro.dbt.drop_table\", \"macro.dbt.drop_materialized_view\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.694123, \"supported_languages\": null}, \"macro.dbt.drop_relation\": {\"name\": \"drop_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/drop.sql\", \"original_file_path\": \"macros/relations/drop.sql\", \"unique_id\": \"macro.dbt.drop_relation\", \"macro_sql\": \"{% macro drop_relation(relation) -%}\\n    {{ return(adapter.dispatch('drop_relation', 'dbt')(relation)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__drop_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.694428, \"supported_languages\": null}, \"macro.dbt.default__drop_relation\": {\"name\": \"default__drop_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/drop.sql\", \"original_file_path\": \"macros/relations/drop.sql\", \"unique_id\": \"macro.dbt.default__drop_relation\", \"macro_sql\": \"{% macro default__drop_relation(relation) -%}\\n    {% call statement('drop_relation', auto_begin=False) -%}\\n        {{ get_drop_sql(relation) }}\\n    {%- endcall %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\", \"macro.dbt.get_drop_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.694753, \"supported_languages\": null}, \"macro.dbt.drop_relation_if_exists\": {\"name\": \"drop_relation_if_exists\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/drop.sql\", \"original_file_path\": \"macros/relations/drop.sql\", \"unique_id\": \"macro.dbt.drop_relation_if_exists\", \"macro_sql\": \"{% macro drop_relation_if_exists(relation) %}\\n  {% if relation is not none %}\\n    {{ adapter.drop_relation(relation) }}\\n  {% endif %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.695075, \"supported_languages\": null}, \"macro.dbt.get_replace_sql\": {\"name\": \"get_replace_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/replace.sql\", \"original_file_path\": \"macros/relations/replace.sql\", \"unique_id\": \"macro.dbt.get_replace_sql\", \"macro_sql\": \"{% macro get_replace_sql(existing_relation, target_relation, sql) %}\\n    {{- log('Applying REPLACE to: ' ~ existing_relation) -}}\\n    {{- adapter.dispatch('get_replace_sql', 'dbt')(existing_relation, target_relation, sql) -}}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_replace_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.6964202, \"supported_languages\": null}, \"macro.dbt.default__get_replace_sql\": {\"name\": \"default__get_replace_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/replace.sql\", \"original_file_path\": \"macros/relations/replace.sql\", \"unique_id\": \"macro.dbt.default__get_replace_sql\", \"macro_sql\": \"{% macro default__get_replace_sql(existing_relation, target_relation, sql) %}\\n\\n    {# /* use a create or replace statement if possible */ #}\\n\\n    {% set is_replaceable = existing_relation.type == target_relation_type and existing_relation.can_be_replaced %}\\n\\n    {% if is_replaceable and existing_relation.is_view %}\\n        {{ get_replace_view_sql(target_relation, sql) }}\\n\\n    {% elif is_replaceable and existing_relation.is_table %}\\n        {{ get_replace_table_sql(target_relation, sql) }}\\n\\n    {% elif is_replaceable and existing_relation.is_materialized_view %}\\n        {{ get_replace_materialized_view_sql(target_relation, sql) }}\\n\\n    {# /* a create or replace statement is not possible, so try to stage and/or backup to be safe */ #}\\n\\n    {# /* create target_relation as an intermediate relation, then swap it out with the existing one using a backup */ #}\\n    {%- elif target_relation.can_be_renamed and existing_relation.can_be_renamed -%}\\n        {{ get_create_intermediate_sql(target_relation, sql) }};\\n        {{ get_create_backup_sql(existing_relation) }};\\n        {{ get_rename_intermediate_sql(target_relation) }};\\n        {{ get_drop_backup_sql(existing_relation) }}\\n\\n    {# /* create target_relation as an intermediate relation, then swap it out with the existing one without using a backup */ #}\\n    {%- elif target_relation.can_be_renamed -%}\\n        {{ get_create_intermediate_sql(target_relation, sql) }};\\n        {{ get_drop_sql(existing_relation) }};\\n        {{ get_rename_intermediate_sql(target_relation) }}\\n\\n    {# /* create target_relation in place by first backing up the existing relation */ #}\\n    {%- elif existing_relation.can_be_renamed -%}\\n        {{ get_create_backup_sql(existing_relation) }};\\n        {{ get_create_sql(target_relation, sql) }};\\n        {{ get_drop_backup_sql(existing_relation) }}\\n\\n    {# /* no renaming is allowed, so just drop and create */ #}\\n    {%- else -%}\\n        {{ get_drop_sql(existing_relation) }};\\n        {{ get_create_sql(target_relation, sql) }}\\n\\n    {%- endif -%}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_replace_view_sql\", \"macro.dbt.get_replace_table_sql\", \"macro.dbt.get_replace_materialized_view_sql\", \"macro.dbt.get_create_intermediate_sql\", \"macro.dbt.get_create_backup_sql\", \"macro.dbt.get_rename_intermediate_sql\", \"macro.dbt.get_drop_backup_sql\", \"macro.dbt.get_drop_sql\", \"macro.dbt.get_create_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.698515, \"supported_languages\": null}, \"macro.dbt.get_create_intermediate_sql\": {\"name\": \"get_create_intermediate_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/create_intermediate.sql\", \"original_file_path\": \"macros/relations/create_intermediate.sql\", \"unique_id\": \"macro.dbt.get_create_intermediate_sql\", \"macro_sql\": \"{%- macro get_create_intermediate_sql(relation, sql) -%}\\n    {{- log('Applying CREATE INTERMEDIATE to: ' ~ relation) -}}\\n    {{- adapter.dispatch('get_create_intermediate_sql', 'dbt')(relation, sql) -}}\\n{%- endmacro -%}\\n\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_create_intermediate_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.699143, \"supported_languages\": null}, \"macro.dbt.default__get_create_intermediate_sql\": {\"name\": \"default__get_create_intermediate_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/create_intermediate.sql\", \"original_file_path\": \"macros/relations/create_intermediate.sql\", \"unique_id\": \"macro.dbt.default__get_create_intermediate_sql\", \"macro_sql\": \"{%- macro default__get_create_intermediate_sql(relation, sql) -%}\\n\\n    -- get the standard intermediate name\\n    {% set intermediate_relation = make_intermediate_relation(relation) %}\\n\\n    -- drop any pre-existing intermediate\\n    {{ get_drop_sql(intermediate_relation) }};\\n\\n    {{ get_create_sql(intermediate_relation, sql) }}\\n\\n{%- endmacro -%}\", \"depends_on\": {\"macros\": [\"macro.dbt.make_intermediate_relation\", \"macro.dbt.get_drop_sql\", \"macro.dbt.get_create_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.699562, \"supported_languages\": null}, \"macro.dbt.get_drop_backup_sql\": {\"name\": \"get_drop_backup_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/drop_backup.sql\", \"original_file_path\": \"macros/relations/drop_backup.sql\", \"unique_id\": \"macro.dbt.get_drop_backup_sql\", \"macro_sql\": \"{%- macro get_drop_backup_sql(relation) -%}\\n    {{- log('Applying DROP BACKUP to: ' ~ relation) -}}\\n    {{- adapter.dispatch('get_drop_backup_sql', 'dbt')(relation) -}}\\n{%- endmacro -%}\\n\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_drop_backup_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.700088, \"supported_languages\": null}, \"macro.dbt.default__get_drop_backup_sql\": {\"name\": \"default__get_drop_backup_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/drop_backup.sql\", \"original_file_path\": \"macros/relations/drop_backup.sql\", \"unique_id\": \"macro.dbt.default__get_drop_backup_sql\", \"macro_sql\": \"{%- macro default__get_drop_backup_sql(relation) -%}\\n\\n    -- get the standard backup name\\n    {% set backup_relation = make_backup_relation(relation, relation.type) %}\\n\\n    {{ get_drop_sql(backup_relation) }}\\n\\n{%- endmacro -%}\", \"depends_on\": {\"macros\": [\"macro.dbt.make_backup_relation\", \"macro.dbt.get_drop_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7004328, \"supported_languages\": null}, \"macro.dbt.get_rename_sql\": {\"name\": \"get_rename_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/rename.sql\", \"original_file_path\": \"macros/relations/rename.sql\", \"unique_id\": \"macro.dbt.get_rename_sql\", \"macro_sql\": \"{%- macro get_rename_sql(relation, new_name) -%}\\n    {{- log('Applying RENAME to: ' ~ relation) -}}\\n    {{- adapter.dispatch('get_rename_sql', 'dbt')(relation, new_name) -}}\\n{%- endmacro -%}\\n\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_rename_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.701566, \"supported_languages\": null}, \"macro.dbt.default__get_rename_sql\": {\"name\": \"default__get_rename_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/rename.sql\", \"original_file_path\": \"macros/relations/rename.sql\", \"unique_id\": \"macro.dbt.default__get_rename_sql\", \"macro_sql\": \"{%- macro default__get_rename_sql(relation, new_name) -%}\\n\\n    {%- if relation.is_view -%}\\n        {{ get_rename_view_sql(relation, new_name) }}\\n\\n    {%- elif relation.is_table -%}\\n        {{ get_rename_table_sql(relation, new_name) }}\\n\\n    {%- elif relation.is_materialized_view -%}\\n        {{ get_rename_materialized_view_sql(relation, new_name) }}\\n\\n    {%- else -%}\\n        {{- exceptions.raise_compiler_error(\\\"`get_rename_sql` has not been implemented for: \\\" ~ relation.type ) -}}\\n\\n    {%- endif -%}\\n\\n{%- endmacro -%}\\n\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.get_rename_view_sql\", \"macro.dbt.get_rename_table_sql\", \"macro.dbt.get_rename_materialized_view_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.702281, \"supported_languages\": null}, \"macro.dbt.rename_relation\": {\"name\": \"rename_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/rename.sql\", \"original_file_path\": \"macros/relations/rename.sql\", \"unique_id\": \"macro.dbt.rename_relation\", \"macro_sql\": \"{% macro rename_relation(from_relation, to_relation) -%}\\n  {{ return(adapter.dispatch('rename_relation', 'dbt')(from_relation, to_relation)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__rename_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.702626, \"supported_languages\": null}, \"macro.dbt.default__rename_relation\": {\"name\": \"default__rename_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/rename.sql\", \"original_file_path\": \"macros/relations/rename.sql\", \"unique_id\": \"macro.dbt.default__rename_relation\", \"macro_sql\": \"{% macro default__rename_relation(from_relation, to_relation) -%}\\n  {% set target_name = adapter.quote_as_configured(to_relation.identifier, 'identifier') %}\\n  {% call statement('rename_relation') -%}\\n    alter table {{ from_relation }} rename to {{ target_name }}\\n  {%- endcall %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.703085, \"supported_languages\": null}, \"macro.dbt.get_create_backup_sql\": {\"name\": \"get_create_backup_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/create_backup.sql\", \"original_file_path\": \"macros/relations/create_backup.sql\", \"unique_id\": \"macro.dbt.get_create_backup_sql\", \"macro_sql\": \"{%- macro get_create_backup_sql(relation) -%}\\n    {{- log('Applying CREATE BACKUP to: ' ~ relation) -}}\\n    {{- adapter.dispatch('get_create_backup_sql', 'dbt')(relation) -}}\\n{%- endmacro -%}\\n\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_create_backup_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.703655, \"supported_languages\": null}, \"macro.dbt.default__get_create_backup_sql\": {\"name\": \"default__get_create_backup_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/create_backup.sql\", \"original_file_path\": \"macros/relations/create_backup.sql\", \"unique_id\": \"macro.dbt.default__get_create_backup_sql\", \"macro_sql\": \"{%- macro default__get_create_backup_sql(relation) -%}\\n\\n    -- get the standard backup name\\n    {% set backup_relation = make_backup_relation(relation, relation.type) %}\\n\\n    -- drop any pre-existing backup\\n    {{ get_drop_sql(backup_relation) }};\\n\\n    {{ get_rename_sql(relation, backup_relation.identifier) }}\\n\\n{%- endmacro -%}\", \"depends_on\": {\"macros\": [\"macro.dbt.make_backup_relation\", \"macro.dbt.get_drop_sql\", \"macro.dbt.get_rename_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.704103, \"supported_languages\": null}, \"macro.dbt.get_create_sql\": {\"name\": \"get_create_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/create.sql\", \"original_file_path\": \"macros/relations/create.sql\", \"unique_id\": \"macro.dbt.get_create_sql\", \"macro_sql\": \"{%- macro get_create_sql(relation, sql) -%}\\n    {{- log('Applying CREATE to: ' ~ relation) -}}\\n    {{- adapter.dispatch('get_create_sql', 'dbt')(relation, sql) -}}\\n{%- endmacro -%}\\n\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_create_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.704864, \"supported_languages\": null}, \"macro.dbt.default__get_create_sql\": {\"name\": \"default__get_create_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/create.sql\", \"original_file_path\": \"macros/relations/create.sql\", \"unique_id\": \"macro.dbt.default__get_create_sql\", \"macro_sql\": \"{%- macro default__get_create_sql(relation, sql) -%}\\n\\n    {%- if relation.is_view -%}\\n        {{ get_create_view_as_sql(relation, sql) }}\\n\\n    {%- elif relation.is_table -%}\\n        {{ get_create_table_as_sql(False, relation, sql) }}\\n\\n    {%- elif relation.is_materialized_view -%}\\n        {{ get_create_materialized_view_as_sql(relation, sql) }}\\n\\n    {%- else -%}\\n        {{- exceptions.raise_compiler_error(\\\"`get_create_sql` has not been implemented for: \\\" ~ relation.type ) -}}\\n\\n    {%- endif -%}\\n\\n{%- endmacro -%}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_create_view_as_sql\", \"macro.dbt.get_create_table_as_sql\", \"macro.dbt.get_create_materialized_view_as_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7055922, \"supported_languages\": null}, \"macro.dbt.get_rename_intermediate_sql\": {\"name\": \"get_rename_intermediate_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/rename_intermediate.sql\", \"original_file_path\": \"macros/relations/rename_intermediate.sql\", \"unique_id\": \"macro.dbt.get_rename_intermediate_sql\", \"macro_sql\": \"{%- macro get_rename_intermediate_sql(relation) -%}\\n    {{- log('Applying RENAME INTERMEDIATE to: ' ~ relation) -}}\\n    {{- adapter.dispatch('get_rename_intermediate_sql', 'dbt')(relation) -}}\\n{%- endmacro -%}\\n\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_rename_intermediate_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.706131, \"supported_languages\": null}, \"macro.dbt.default__get_rename_intermediate_sql\": {\"name\": \"default__get_rename_intermediate_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/rename_intermediate.sql\", \"original_file_path\": \"macros/relations/rename_intermediate.sql\", \"unique_id\": \"macro.dbt.default__get_rename_intermediate_sql\", \"macro_sql\": \"{%- macro default__get_rename_intermediate_sql(relation) -%}\\n\\n    -- get the standard intermediate name\\n    {% set intermediate_relation = make_intermediate_relation(relation) %}\\n\\n    {{ get_rename_sql(intermediate_relation, relation.identifier) }}\\n\\n{%- endmacro -%}\", \"depends_on\": {\"macros\": [\"macro.dbt.make_intermediate_relation\", \"macro.dbt.get_rename_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.706486, \"supported_languages\": null}, \"macro.dbt.drop_materialized_view\": {\"name\": \"drop_materialized_view\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/materialized_view/drop.sql\", \"original_file_path\": \"macros/relations/materialized_view/drop.sql\", \"unique_id\": \"macro.dbt.drop_materialized_view\", \"macro_sql\": \"{% macro drop_materialized_view(relation) -%}\\n    {{ return(adapter.dispatch('drop_materialized_view', 'dbt')(relation)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__drop_materialized_view\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.706933, \"supported_languages\": null}, \"macro.dbt.default__drop_materialized_view\": {\"name\": \"default__drop_materialized_view\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/materialized_view/drop.sql\", \"original_file_path\": \"macros/relations/materialized_view/drop.sql\", \"unique_id\": \"macro.dbt.default__drop_materialized_view\", \"macro_sql\": \"{% macro default__drop_materialized_view(relation) -%}\\n    drop materialized view if exists {{ relation }} cascade\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.707106, \"supported_languages\": null}, \"macro.dbt.get_replace_materialized_view_sql\": {\"name\": \"get_replace_materialized_view_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/materialized_view/replace.sql\", \"original_file_path\": \"macros/relations/materialized_view/replace.sql\", \"unique_id\": \"macro.dbt.get_replace_materialized_view_sql\", \"macro_sql\": \"{% macro get_replace_materialized_view_sql(relation, sql) %}\\n    {{- adapter.dispatch('get_replace_materialized_view_sql', 'dbt')(relation, sql) -}}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_replace_materialized_view_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.707551, \"supported_languages\": null}, \"macro.dbt.default__get_replace_materialized_view_sql\": {\"name\": \"default__get_replace_materialized_view_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/materialized_view/replace.sql\", \"original_file_path\": \"macros/relations/materialized_view/replace.sql\", \"unique_id\": \"macro.dbt.default__get_replace_materialized_view_sql\", \"macro_sql\": \"{% macro default__get_replace_materialized_view_sql(relation, sql) %}\\n    {{ exceptions.raise_compiler_error(\\n        \\\"`get_replace_materialized_view_sql` has not been implemented for this adapter.\\\"\\n    ) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.707791, \"supported_languages\": null}, \"macro.dbt.refresh_materialized_view\": {\"name\": \"refresh_materialized_view\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/materialized_view/refresh.sql\", \"original_file_path\": \"macros/relations/materialized_view/refresh.sql\", \"unique_id\": \"macro.dbt.refresh_materialized_view\", \"macro_sql\": \"{% macro refresh_materialized_view(relation) %}\\n    {{- log('Applying REFRESH to: ' ~ relation) -}}\\n    {{- adapter.dispatch('refresh_materialized_view', 'dbt')(relation) -}}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__refresh_materialized_view\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.708298, \"supported_languages\": null}, \"macro.dbt.default__refresh_materialized_view\": {\"name\": \"default__refresh_materialized_view\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/materialized_view/refresh.sql\", \"original_file_path\": \"macros/relations/materialized_view/refresh.sql\", \"unique_id\": \"macro.dbt.default__refresh_materialized_view\", \"macro_sql\": \"{% macro default__refresh_materialized_view(relation) %}\\n    {{ exceptions.raise_compiler_error(\\\"`refresh_materialized_view` has not been implemented for this adapter.\\\") }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.708629, \"supported_languages\": null}, \"macro.dbt.get_rename_materialized_view_sql\": {\"name\": \"get_rename_materialized_view_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/materialized_view/rename.sql\", \"original_file_path\": \"macros/relations/materialized_view/rename.sql\", \"unique_id\": \"macro.dbt.get_rename_materialized_view_sql\", \"macro_sql\": \"{% macro get_rename_materialized_view_sql(relation, new_name) %}\\n    {{- adapter.dispatch('get_rename_materialized_view_sql', 'dbt')(relation, new_name) -}}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_rename_materialized_view_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.709074, \"supported_languages\": null}, \"macro.dbt.default__get_rename_materialized_view_sql\": {\"name\": \"default__get_rename_materialized_view_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/materialized_view/rename.sql\", \"original_file_path\": \"macros/relations/materialized_view/rename.sql\", \"unique_id\": \"macro.dbt.default__get_rename_materialized_view_sql\", \"macro_sql\": \"{% macro default__get_rename_materialized_view_sql(relation, new_name) %}\\n    {{ exceptions.raise_compiler_error(\\n        \\\"`get_rename_materialized_view_sql` has not been implemented for this adapter.\\\"\\n    ) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7093172, \"supported_languages\": null}, \"macro.dbt.get_alter_materialized_view_as_sql\": {\"name\": \"get_alter_materialized_view_as_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/materialized_view/alter.sql\", \"original_file_path\": \"macros/relations/materialized_view/alter.sql\", \"unique_id\": \"macro.dbt.get_alter_materialized_view_as_sql\", \"macro_sql\": \"{% macro get_alter_materialized_view_as_sql(\\n    relation,\\n    configuration_changes,\\n    sql,\\n    existing_relation,\\n    backup_relation,\\n    intermediate_relation\\n) %}\\n    {{- log('Applying ALTER to: ' ~ relation) -}}\\n    {{- adapter.dispatch('get_alter_materialized_view_as_sql', 'dbt')(\\n        relation,\\n        configuration_changes,\\n        sql,\\n        existing_relation,\\n        backup_relation,\\n        intermediate_relation\\n    ) -}}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_alter_materialized_view_as_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.710311, \"supported_languages\": null}, \"macro.dbt.default__get_alter_materialized_view_as_sql\": {\"name\": \"default__get_alter_materialized_view_as_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/materialized_view/alter.sql\", \"original_file_path\": \"macros/relations/materialized_view/alter.sql\", \"unique_id\": \"macro.dbt.default__get_alter_materialized_view_as_sql\", \"macro_sql\": \"{% macro default__get_alter_materialized_view_as_sql(\\n    relation,\\n    configuration_changes,\\n    sql,\\n    existing_relation,\\n    backup_relation,\\n    intermediate_relation\\n) %}\\n    {{ exceptions.raise_compiler_error(\\\"Materialized views have not been implemented for this adapter.\\\") }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7106209, \"supported_languages\": null}, \"macro.dbt.get_materialized_view_configuration_changes\": {\"name\": \"get_materialized_view_configuration_changes\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/materialized_view/alter.sql\", \"original_file_path\": \"macros/relations/materialized_view/alter.sql\", \"unique_id\": \"macro.dbt.get_materialized_view_configuration_changes\", \"macro_sql\": \"{% macro get_materialized_view_configuration_changes(existing_relation, new_config) %}\\n    /* {#\\n    It's recommended that configuration changes be formatted as follows:\\n    {\\\"<change_category>\\\": [{\\\"action\\\": \\\"<name>\\\", \\\"context\\\": ...}]}\\n\\n    For example:\\n    {\\n        \\\"indexes\\\": [\\n            {\\\"action\\\": \\\"drop\\\", \\\"context\\\": \\\"index_abc\\\"},\\n            {\\\"action\\\": \\\"create\\\", \\\"context\\\": {\\\"columns\\\": [\\\"column_1\\\", \\\"column_2\\\"], \\\"type\\\": \\\"hash\\\", \\\"unique\\\": True}},\\n        ],\\n    }\\n\\n    Either way, `get_materialized_view_configuration_changes` needs to align with `get_alter_materialized_view_as_sql`.\\n    #} */\\n    {{- log('Determining configuration changes on: ' ~ existing_relation) -}}\\n    {%- do return(adapter.dispatch('get_materialized_view_configuration_changes', 'dbt')(existing_relation, new_config)) -%}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_materialized_view_configuration_changes\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.711103, \"supported_languages\": null}, \"macro.dbt.default__get_materialized_view_configuration_changes\": {\"name\": \"default__get_materialized_view_configuration_changes\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/materialized_view/alter.sql\", \"original_file_path\": \"macros/relations/materialized_view/alter.sql\", \"unique_id\": \"macro.dbt.default__get_materialized_view_configuration_changes\", \"macro_sql\": \"{% macro default__get_materialized_view_configuration_changes(existing_relation, new_config) %}\\n    {{ exceptions.raise_compiler_error(\\\"Materialized views have not been implemented for this adapter.\\\") }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7113469, \"supported_languages\": null}, \"macro.dbt.get_create_materialized_view_as_sql\": {\"name\": \"get_create_materialized_view_as_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/materialized_view/create.sql\", \"original_file_path\": \"macros/relations/materialized_view/create.sql\", \"unique_id\": \"macro.dbt.get_create_materialized_view_as_sql\", \"macro_sql\": \"{% macro get_create_materialized_view_as_sql(relation, sql) -%}\\n    {{- adapter.dispatch('get_create_materialized_view_as_sql', 'dbt')(relation, sql) -}}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_create_materialized_view_as_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7117891, \"supported_languages\": null}, \"macro.dbt.default__get_create_materialized_view_as_sql\": {\"name\": \"default__get_create_materialized_view_as_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/materialized_view/create.sql\", \"original_file_path\": \"macros/relations/materialized_view/create.sql\", \"unique_id\": \"macro.dbt.default__get_create_materialized_view_as_sql\", \"macro_sql\": \"{% macro default__get_create_materialized_view_as_sql(relation, sql) -%}\\n    {{ exceptions.raise_compiler_error(\\n        \\\"`get_create_materialized_view_as_sql` has not been implemented for this adapter.\\\"\\n    ) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.712033, \"supported_languages\": null}, \"macro.dbt.get_table_columns_and_constraints\": {\"name\": \"get_table_columns_and_constraints\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/column/columns_spec_ddl.sql\", \"original_file_path\": \"macros/relations/column/columns_spec_ddl.sql\", \"unique_id\": \"macro.dbt.get_table_columns_and_constraints\", \"macro_sql\": \"{%- macro get_table_columns_and_constraints() -%}\\n  {{ adapter.dispatch('get_table_columns_and_constraints', 'dbt')() }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_table_columns_and_constraints\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.713679, \"supported_languages\": null}, \"macro.dbt.default__get_table_columns_and_constraints\": {\"name\": \"default__get_table_columns_and_constraints\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/column/columns_spec_ddl.sql\", \"original_file_path\": \"macros/relations/column/columns_spec_ddl.sql\", \"unique_id\": \"macro.dbt.default__get_table_columns_and_constraints\", \"macro_sql\": \"{% macro default__get_table_columns_and_constraints() -%}\\n  {{ return(table_columns_and_constraints()) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.table_columns_and_constraints\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.713873, \"supported_languages\": null}, \"macro.dbt.table_columns_and_constraints\": {\"name\": \"table_columns_and_constraints\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/column/columns_spec_ddl.sql\", \"original_file_path\": \"macros/relations/column/columns_spec_ddl.sql\", \"unique_id\": \"macro.dbt.table_columns_and_constraints\", \"macro_sql\": \"{% macro table_columns_and_constraints() %}\\n  {# loop through user_provided_columns to create DDL with data types and constraints #}\\n    {%- set raw_column_constraints = adapter.render_raw_columns_constraints(raw_columns=model['columns']) -%}\\n    {%- set raw_model_constraints = adapter.render_raw_model_constraints(raw_constraints=model['constraints']) -%}\\n    (\\n    {% for c in raw_column_constraints -%}\\n      {{ c }}{{ \\\",\\\" if not loop.last or raw_model_constraints }}\\n    {% endfor %}\\n    {% for c in raw_model_constraints -%}\\n        {{ c }}{{ \\\",\\\" if not loop.last }}\\n    {% endfor -%}\\n    )\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7147489, \"supported_languages\": null}, \"macro.dbt.get_assert_columns_equivalent\": {\"name\": \"get_assert_columns_equivalent\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/column/columns_spec_ddl.sql\", \"original_file_path\": \"macros/relations/column/columns_spec_ddl.sql\", \"unique_id\": \"macro.dbt.get_assert_columns_equivalent\", \"macro_sql\": \"\\n\\n{%- macro get_assert_columns_equivalent(sql) -%}\\n  {{ adapter.dispatch('get_assert_columns_equivalent', 'dbt')(sql) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_assert_columns_equivalent\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.715026, \"supported_languages\": null}, \"macro.dbt.default__get_assert_columns_equivalent\": {\"name\": \"default__get_assert_columns_equivalent\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/column/columns_spec_ddl.sql\", \"original_file_path\": \"macros/relations/column/columns_spec_ddl.sql\", \"unique_id\": \"macro.dbt.default__get_assert_columns_equivalent\", \"macro_sql\": \"{% macro default__get_assert_columns_equivalent(sql) -%}\\n  {{ return(assert_columns_equivalent(sql)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.assert_columns_equivalent\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7152472, \"supported_languages\": null}, \"macro.dbt.assert_columns_equivalent\": {\"name\": \"assert_columns_equivalent\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/column/columns_spec_ddl.sql\", \"original_file_path\": \"macros/relations/column/columns_spec_ddl.sql\", \"unique_id\": \"macro.dbt.assert_columns_equivalent\", \"macro_sql\": \"{% macro assert_columns_equivalent(sql) %}\\n\\n  {#-- First ensure the user has defined 'columns' in yaml specification --#}\\n  {%- set user_defined_columns = model['columns'] -%}\\n  {%- if not user_defined_columns -%}\\n      {{ exceptions.raise_contract_error([], []) }}\\n  {%- endif -%}\\n\\n  {#-- Obtain the column schema provided by sql file. #}\\n  {%- set sql_file_provided_columns = get_column_schema_from_query(sql, config.get('sql_header', none)) -%}\\n  {#--Obtain the column schema provided by the schema file by generating an 'empty schema' query from the model's columns. #}\\n  {%- set schema_file_provided_columns = get_column_schema_from_query(get_empty_schema_sql(user_defined_columns)) -%}\\n\\n  {#-- create dictionaries with name and formatted data type and strings for exception #}\\n  {%- set sql_columns = format_columns(sql_file_provided_columns) -%}\\n  {%- set yaml_columns = format_columns(schema_file_provided_columns)  -%}\\n\\n  {%- if sql_columns|length != yaml_columns|length -%}\\n    {%- do exceptions.raise_contract_error(yaml_columns, sql_columns) -%}\\n  {%- endif -%}\\n\\n  {%- for sql_col in sql_columns -%}\\n    {%- set yaml_col = [] -%}\\n    {%- for this_col in yaml_columns -%}\\n      {%- if this_col['name'] == sql_col['name'] -%}\\n        {%- do yaml_col.append(this_col) -%}\\n        {%- break -%}\\n      {%- endif -%}\\n    {%- endfor -%}\\n    {%- if not yaml_col -%}\\n      {#-- Column with name not found in yaml #}\\n      {%- do exceptions.raise_contract_error(yaml_columns, sql_columns) -%}\\n    {%- endif -%}\\n    {%- if sql_col['formatted'] != yaml_col[0]['formatted'] -%}\\n      {#-- Column data types don't match #}\\n      {%- do exceptions.raise_contract_error(yaml_columns, sql_columns) -%}\\n    {%- endif -%}\\n  {%- endfor -%}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_column_schema_from_query\", \"macro.dbt.get_empty_schema_sql\", \"macro.dbt.format_columns\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.717453, \"supported_languages\": null}, \"macro.dbt.format_columns\": {\"name\": \"format_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/column/columns_spec_ddl.sql\", \"original_file_path\": \"macros/relations/column/columns_spec_ddl.sql\", \"unique_id\": \"macro.dbt.format_columns\", \"macro_sql\": \"{% macro format_columns(columns) %}\\n  {% set formatted_columns = [] %}\\n  {% for column in columns %}\\n    {%- set formatted_column = adapter.dispatch('format_column', 'dbt')(column) -%}\\n    {%- do formatted_columns.append(formatted_column) -%}\\n  {% endfor %}\\n  {{ return(formatted_columns) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__format_column\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.718085, \"supported_languages\": null}, \"macro.dbt.default__format_column\": {\"name\": \"default__format_column\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/column/columns_spec_ddl.sql\", \"original_file_path\": \"macros/relations/column/columns_spec_ddl.sql\", \"unique_id\": \"macro.dbt.default__format_column\", \"macro_sql\": \"{% macro default__format_column(column) -%}\\n  {% set data_type = column.dtype %}\\n  {% set formatted = column.column.lower() ~ \\\" \\\" ~ data_type %}\\n  {{ return({'name': column.name, 'data_type': data_type, 'formatted': formatted}) }}\\n{%- endmacro -%}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.718652, \"supported_languages\": null}, \"macro.dbt.drop_table\": {\"name\": \"drop_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/table/drop.sql\", \"original_file_path\": \"macros/relations/table/drop.sql\", \"unique_id\": \"macro.dbt.drop_table\", \"macro_sql\": \"{% macro drop_table(relation) -%}\\n    {{ return(adapter.dispatch('drop_table', 'dbt')(relation)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__drop_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.719095, \"supported_languages\": null}, \"macro.dbt.default__drop_table\": {\"name\": \"default__drop_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/table/drop.sql\", \"original_file_path\": \"macros/relations/table/drop.sql\", \"unique_id\": \"macro.dbt.default__drop_table\", \"macro_sql\": \"{% macro default__drop_table(relation) -%}\\n    drop table if exists {{ relation }} cascade\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.719268, \"supported_languages\": null}, \"macro.dbt.get_replace_table_sql\": {\"name\": \"get_replace_table_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/table/replace.sql\", \"original_file_path\": \"macros/relations/table/replace.sql\", \"unique_id\": \"macro.dbt.get_replace_table_sql\", \"macro_sql\": \"{% macro get_replace_table_sql(relation, sql) %}\\n    {{- adapter.dispatch('get_replace_table_sql', 'dbt')(relation, sql) -}}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_replace_table_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.719711, \"supported_languages\": null}, \"macro.dbt.default__get_replace_table_sql\": {\"name\": \"default__get_replace_table_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/table/replace.sql\", \"original_file_path\": \"macros/relations/table/replace.sql\", \"unique_id\": \"macro.dbt.default__get_replace_table_sql\", \"macro_sql\": \"{% macro default__get_replace_table_sql(relation, sql) %}\\n    {{ exceptions.raise_compiler_error(\\n        \\\"`get_replace_table_sql` has not been implemented for this adapter.\\\"\\n    ) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.719948, \"supported_languages\": null}, \"macro.dbt.get_rename_table_sql\": {\"name\": \"get_rename_table_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/table/rename.sql\", \"original_file_path\": \"macros/relations/table/rename.sql\", \"unique_id\": \"macro.dbt.get_rename_table_sql\", \"macro_sql\": \"{% macro get_rename_table_sql(relation, new_name) %}\\n    {{- adapter.dispatch('get_rename_table_sql', 'dbt')(relation, new_name) -}}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_rename_table_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7203882, \"supported_languages\": null}, \"macro.dbt.default__get_rename_table_sql\": {\"name\": \"default__get_rename_table_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/table/rename.sql\", \"original_file_path\": \"macros/relations/table/rename.sql\", \"unique_id\": \"macro.dbt.default__get_rename_table_sql\", \"macro_sql\": \"{% macro default__get_rename_table_sql(relation, new_name) %}\\n    {{ exceptions.raise_compiler_error(\\n        \\\"`get_rename_table_sql` has not been implemented for this adapter.\\\"\\n    ) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7206268, \"supported_languages\": null}, \"macro.dbt.get_create_table_as_sql\": {\"name\": \"get_create_table_as_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/table/create.sql\", \"original_file_path\": \"macros/relations/table/create.sql\", \"unique_id\": \"macro.dbt.get_create_table_as_sql\", \"macro_sql\": \"{% macro get_create_table_as_sql(temporary, relation, sql) -%}\\n  {{ adapter.dispatch('get_create_table_as_sql', 'dbt')(temporary, relation, sql) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_create_table_as_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.722004, \"supported_languages\": null}, \"macro.dbt.default__get_create_table_as_sql\": {\"name\": \"default__get_create_table_as_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/table/create.sql\", \"original_file_path\": \"macros/relations/table/create.sql\", \"unique_id\": \"macro.dbt.default__get_create_table_as_sql\", \"macro_sql\": \"{% macro default__get_create_table_as_sql(temporary, relation, sql) -%}\\n  {{ return(create_table_as(temporary, relation, sql)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.create_table_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.722313, \"supported_languages\": null}, \"macro.dbt.create_table_as\": {\"name\": \"create_table_as\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/table/create.sql\", \"original_file_path\": \"macros/relations/table/create.sql\", \"unique_id\": \"macro.dbt.create_table_as\", \"macro_sql\": \"{% macro create_table_as(temporary, relation, compiled_code, language='sql') -%}\\n  {# backward compatibility for create_table_as that does not support language #}\\n  {% if language == \\\"sql\\\" %}\\n    {{ adapter.dispatch('create_table_as', 'dbt')(temporary, relation, compiled_code)}}\\n  {% else %}\\n    {{ adapter.dispatch('create_table_as', 'dbt')(temporary, relation, compiled_code, language) }}\\n  {% endif %}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__create_table_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.723018, \"supported_languages\": null}, \"macro.dbt.default__create_table_as\": {\"name\": \"default__create_table_as\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/table/create.sql\", \"original_file_path\": \"macros/relations/table/create.sql\", \"unique_id\": \"macro.dbt.default__create_table_as\", \"macro_sql\": \"{% macro default__create_table_as(temporary, relation, sql) -%}\\n  {%- set sql_header = config.get('sql_header', none) -%}\\n\\n  {{ sql_header if sql_header is not none }}\\n\\n  create {% if temporary: -%}temporary{%- endif %} table\\n    {{ relation.include(database=(not temporary), schema=(not temporary)) }}\\n  {% set contract_config = config.get('contract') %}\\n  {% if contract_config.enforced and (not temporary) %}\\n    {{ get_assert_columns_equivalent(sql) }}\\n    {{ get_table_columns_and_constraints() }}\\n    {%- set sql = get_select_subquery(sql) %}\\n  {% endif %}\\n  as (\\n    {{ sql }}\\n  );\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_assert_columns_equivalent\", \"macro.dbt.get_table_columns_and_constraints\", \"macro.dbt.get_select_subquery\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.724143, \"supported_languages\": null}, \"macro.dbt.default__get_column_names\": {\"name\": \"default__get_column_names\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/table/create.sql\", \"original_file_path\": \"macros/relations/table/create.sql\", \"unique_id\": \"macro.dbt.default__get_column_names\", \"macro_sql\": \"{% macro default__get_column_names() %}\\n  {#- loop through user_provided_columns to get column names -#}\\n    {%- set user_provided_columns = model['columns'] -%}\\n    {%- for i in user_provided_columns %}\\n      {%- set col = user_provided_columns[i] -%}\\n      {%- set col_name = adapter.quote(col['name']) if col.get('quote') else col['name'] -%}\\n      {{ col_name }}{{ \\\", \\\" if not loop.last }}\\n    {%- endfor -%}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.724905, \"supported_languages\": null}, \"macro.dbt.get_select_subquery\": {\"name\": \"get_select_subquery\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/table/create.sql\", \"original_file_path\": \"macros/relations/table/create.sql\", \"unique_id\": \"macro.dbt.get_select_subquery\", \"macro_sql\": \"{% macro get_select_subquery(sql) %}\\n  {{ return(adapter.dispatch('get_select_subquery', 'dbt')(sql)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_select_subquery\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.725209, \"supported_languages\": null}, \"macro.dbt.default__get_select_subquery\": {\"name\": \"default__get_select_subquery\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/table/create.sql\", \"original_file_path\": \"macros/relations/table/create.sql\", \"unique_id\": \"macro.dbt.default__get_select_subquery\", \"macro_sql\": \"{% macro default__get_select_subquery(sql) %}\\n    select {{ adapter.dispatch('get_column_names', 'dbt')() }}\\n    from (\\n        {{ sql }}\\n    ) as model_subq\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_column_names\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7255082, \"supported_languages\": null}, \"macro.dbt.drop_view\": {\"name\": \"drop_view\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/view/drop.sql\", \"original_file_path\": \"macros/relations/view/drop.sql\", \"unique_id\": \"macro.dbt.drop_view\", \"macro_sql\": \"{% macro drop_view(relation) -%}\\n    {{ return(adapter.dispatch('drop_view', 'dbt')(relation)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__drop_view\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.72594, \"supported_languages\": null}, \"macro.dbt.default__drop_view\": {\"name\": \"default__drop_view\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/view/drop.sql\", \"original_file_path\": \"macros/relations/view/drop.sql\", \"unique_id\": \"macro.dbt.default__drop_view\", \"macro_sql\": \"{% macro default__drop_view(relation) -%}\\n    drop view if exists {{ relation }} cascade\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.726114, \"supported_languages\": null}, \"macro.dbt.get_replace_view_sql\": {\"name\": \"get_replace_view_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/view/replace.sql\", \"original_file_path\": \"macros/relations/view/replace.sql\", \"unique_id\": \"macro.dbt.get_replace_view_sql\", \"macro_sql\": \"{% macro get_replace_view_sql(relation, sql) %}\\n    {{- adapter.dispatch('get_replace_view_sql', 'dbt')(relation, sql) -}}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_replace_view_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.72751, \"supported_languages\": null}, \"macro.dbt.default__get_replace_view_sql\": {\"name\": \"default__get_replace_view_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/view/replace.sql\", \"original_file_path\": \"macros/relations/view/replace.sql\", \"unique_id\": \"macro.dbt.default__get_replace_view_sql\", \"macro_sql\": \"{% macro default__get_replace_view_sql(relation, sql) %}\\n    {{ exceptions.raise_compiler_error(\\n        \\\"`get_replace_view_sql` has not been implemented for this adapter.\\\"\\n    ) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7277539, \"supported_languages\": null}, \"macro.dbt.create_or_replace_view\": {\"name\": \"create_or_replace_view\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/view/replace.sql\", \"original_file_path\": \"macros/relations/view/replace.sql\", \"unique_id\": \"macro.dbt.create_or_replace_view\", \"macro_sql\": \"{% macro create_or_replace_view() %}\\n  {%- set identifier = model['alias'] -%}\\n\\n  {%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%}\\n  {%- set exists_as_view = (old_relation is not none and old_relation.is_view) -%}\\n\\n  {%- set target_relation = api.Relation.create(\\n      identifier=identifier, schema=schema, database=database,\\n      type='view') -%}\\n  {% set grant_config = config.get('grants') %}\\n\\n  {{ run_hooks(pre_hooks) }}\\n\\n  -- If there's a table with the same name and we weren't told to full refresh,\\n  -- that's an error. If we were told to full refresh, drop it. This behavior differs\\n  -- for Snowflake and BigQuery, so multiple dispatch is used.\\n  {%- if old_relation is not none and old_relation.is_table -%}\\n    {{ handle_existing_table(should_full_refresh(), old_relation) }}\\n  {%- endif -%}\\n\\n  -- build model\\n  {% call statement('main') -%}\\n    {{ get_create_view_as_sql(target_relation, sql) }}\\n  {%- endcall %}\\n\\n  {% set should_revoke = should_revoke(exists_as_view, full_refresh_mode=True) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {{ run_hooks(post_hooks) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.run_hooks\", \"macro.dbt.handle_existing_table\", \"macro.dbt.should_full_refresh\", \"macro.dbt.statement\", \"macro.dbt.get_create_view_as_sql\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.729735, \"supported_languages\": null}, \"macro.dbt.handle_existing_table\": {\"name\": \"handle_existing_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/view/replace.sql\", \"original_file_path\": \"macros/relations/view/replace.sql\", \"unique_id\": \"macro.dbt.handle_existing_table\", \"macro_sql\": \"{% macro handle_existing_table(full_refresh, old_relation) %}\\n    {{ adapter.dispatch('handle_existing_table', 'dbt')(full_refresh, old_relation) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__handle_existing_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.730062, \"supported_languages\": null}, \"macro.dbt.default__handle_existing_table\": {\"name\": \"default__handle_existing_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/view/replace.sql\", \"original_file_path\": \"macros/relations/view/replace.sql\", \"unique_id\": \"macro.dbt.default__handle_existing_table\", \"macro_sql\": \"{% macro default__handle_existing_table(full_refresh, old_relation) %}\\n    {{ log(\\\"Dropping relation \\\" ~ old_relation ~ \\\" because it is of type \\\" ~ old_relation.type) }}\\n    {{ adapter.drop_relation(old_relation) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7304268, \"supported_languages\": null}, \"macro.dbt.get_rename_view_sql\": {\"name\": \"get_rename_view_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/view/rename.sql\", \"original_file_path\": \"macros/relations/view/rename.sql\", \"unique_id\": \"macro.dbt.get_rename_view_sql\", \"macro_sql\": \"{% macro get_rename_view_sql(relation, new_name) %}\\n    {{- adapter.dispatch('get_rename_view_sql', 'dbt')(relation, new_name) -}}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_rename_view_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.730877, \"supported_languages\": null}, \"macro.dbt.default__get_rename_view_sql\": {\"name\": \"default__get_rename_view_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/view/rename.sql\", \"original_file_path\": \"macros/relations/view/rename.sql\", \"unique_id\": \"macro.dbt.default__get_rename_view_sql\", \"macro_sql\": \"{% macro default__get_rename_view_sql(relation, new_name) %}\\n    {{ exceptions.raise_compiler_error(\\n        \\\"`get_rename_view_sql` has not been implemented for this adapter.\\\"\\n    ) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7311208, \"supported_languages\": null}, \"macro.dbt.get_create_view_as_sql\": {\"name\": \"get_create_view_as_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/view/create.sql\", \"original_file_path\": \"macros/relations/view/create.sql\", \"unique_id\": \"macro.dbt.get_create_view_as_sql\", \"macro_sql\": \"{% macro get_create_view_as_sql(relation, sql) -%}\\n  {{ adapter.dispatch('get_create_view_as_sql', 'dbt')(relation, sql) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_create_view_as_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7317948, \"supported_languages\": null}, \"macro.dbt.default__get_create_view_as_sql\": {\"name\": \"default__get_create_view_as_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/view/create.sql\", \"original_file_path\": \"macros/relations/view/create.sql\", \"unique_id\": \"macro.dbt.default__get_create_view_as_sql\", \"macro_sql\": \"{% macro default__get_create_view_as_sql(relation, sql) -%}\\n  {{ return(create_view_as(relation, sql)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.create_view_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.732067, \"supported_languages\": null}, \"macro.dbt.create_view_as\": {\"name\": \"create_view_as\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/view/create.sql\", \"original_file_path\": \"macros/relations/view/create.sql\", \"unique_id\": \"macro.dbt.create_view_as\", \"macro_sql\": \"{% macro create_view_as(relation, sql) -%}\\n  {{ adapter.dispatch('create_view_as', 'dbt')(relation, sql) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__create_view_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7323651, \"supported_languages\": null}, \"macro.dbt.default__create_view_as\": {\"name\": \"default__create_view_as\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/view/create.sql\", \"original_file_path\": \"macros/relations/view/create.sql\", \"unique_id\": \"macro.dbt.default__create_view_as\", \"macro_sql\": \"{% macro default__create_view_as(relation, sql) -%}\\n  {%- set sql_header = config.get('sql_header', none) -%}\\n\\n  {{ sql_header if sql_header is not none }}\\n  create view {{ relation }}\\n    {% set contract_config = config.get('contract') %}\\n    {% if contract_config.enforced %}\\n      {{ get_assert_columns_equivalent(sql) }}\\n    {%- endif %}\\n  as (\\n    {{ sql }}\\n  );\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_assert_columns_equivalent\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7330492, \"supported_languages\": null}, \"macro.dbt.default__test_relationships\": {\"name\": \"default__test_relationships\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/generic_test_sql/relationships.sql\", \"original_file_path\": \"macros/generic_test_sql/relationships.sql\", \"unique_id\": \"macro.dbt.default__test_relationships\", \"macro_sql\": \"{% macro default__test_relationships(model, column_name, to, field) %}\\n\\nwith child as (\\n    select {{ column_name }} as from_field\\n    from {{ model }}\\n    where {{ column_name }} is not null\\n),\\n\\nparent as (\\n    select {{ field }} as to_field\\n    from {{ to }}\\n)\\n\\nselect\\n    from_field\\n\\nfrom child\\nleft join parent\\n    on child.from_field = parent.to_field\\n\\nwhere parent.to_field is null\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7336361, \"supported_languages\": null}, \"macro.dbt.default__test_not_null\": {\"name\": \"default__test_not_null\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/generic_test_sql/not_null.sql\", \"original_file_path\": \"macros/generic_test_sql/not_null.sql\", \"unique_id\": \"macro.dbt.default__test_not_null\", \"macro_sql\": \"{% macro default__test_not_null(model, column_name) %}\\n\\n{% set column_list = '*' if should_store_failures() else column_name %}\\n\\nselect {{ column_list }}\\nfrom {{ model }}\\nwhere {{ column_name }} is null\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.should_store_failures\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.734132, \"supported_languages\": null}, \"macro.dbt.default__test_unique\": {\"name\": \"default__test_unique\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/generic_test_sql/unique.sql\", \"original_file_path\": \"macros/generic_test_sql/unique.sql\", \"unique_id\": \"macro.dbt.default__test_unique\", \"macro_sql\": \"{% macro default__test_unique(model, column_name) %}\\n\\nselect\\n    {{ column_name }} as unique_field,\\n    count(*) as n_records\\n\\nfrom {{ model }}\\nwhere {{ column_name }} is not null\\ngroup by {{ column_name }}\\nhaving count(*) > 1\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7345579, \"supported_languages\": null}, \"macro.dbt.default__test_accepted_values\": {\"name\": \"default__test_accepted_values\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/generic_test_sql/accepted_values.sql\", \"original_file_path\": \"macros/generic_test_sql/accepted_values.sql\", \"unique_id\": \"macro.dbt.default__test_accepted_values\", \"macro_sql\": \"{% macro default__test_accepted_values(model, column_name, values, quote=True) %}\\n\\nwith all_values as (\\n\\n    select\\n        {{ column_name }} as value_field,\\n        count(*) as n_records\\n\\n    from {{ model }}\\n    group by {{ column_name }}\\n\\n)\\n\\nselect *\\nfrom all_values\\nwhere value_field not in (\\n    {% for value in values -%}\\n        {% if quote -%}\\n        '{{ value }}'\\n        {%- else -%}\\n        {{ value }}\\n        {%- endif -%}\\n        {%- if not loop.last -%},{%- endif %}\\n    {%- endfor %}\\n)\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.735542, \"supported_languages\": null}, \"macro.dbt.statement\": {\"name\": \"statement\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/etc/statement.sql\", \"original_file_path\": \"macros/etc/statement.sql\", \"unique_id\": \"macro.dbt.statement\", \"macro_sql\": \"\\n{%- macro statement(name=None, fetch_result=False, auto_begin=True, language='sql') -%}\\n  {%- if execute: -%}\\n    {%- set compiled_code = caller() -%}\\n\\n    {%- if name == 'main' -%}\\n      {{ log('Writing runtime {} for node \\\"{}\\\"'.format(language, model['unique_id'])) }}\\n      {{ write(compiled_code) }}\\n    {%- endif -%}\\n    {%- if language == 'sql'-%}\\n      {%- set res, table = adapter.execute(compiled_code, auto_begin=auto_begin, fetch=fetch_result) -%}\\n    {%- elif language == 'python' -%}\\n      {%- set res = submit_python_job(model, compiled_code) -%}\\n      {#-- TODO: What should table be for python models? --#}\\n      {%- set table = None -%}\\n    {%- else -%}\\n      {% do exceptions.raise_compiler_error(\\\"statement macro didn't get supported language\\\") %}\\n    {%- endif -%}\\n\\n    {%- if name is not none -%}\\n      {{ store_result(name, response=res, agate_table=table) }}\\n    {%- endif -%}\\n\\n  {%- endif -%}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7379699, \"supported_languages\": null}, \"macro.dbt.noop_statement\": {\"name\": \"noop_statement\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/etc/statement.sql\", \"original_file_path\": \"macros/etc/statement.sql\", \"unique_id\": \"macro.dbt.noop_statement\", \"macro_sql\": \"{% macro noop_statement(name=None, message=None, code=None, rows_affected=None, res=None) -%}\\n  {%- set sql = caller() -%}\\n\\n  {%- if name == 'main' -%}\\n    {{ log('Writing runtime SQL for node \\\"{}\\\"'.format(model['unique_id'])) }}\\n    {{ write(sql) }}\\n  {%- endif -%}\\n\\n  {%- if name is not none -%}\\n    {{ store_raw_result(name, message=message, code=code, rows_affected=rows_affected, agate_table=res) }}\\n  {%- endif -%}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7389178, \"supported_languages\": null}, \"macro.dbt.run_query\": {\"name\": \"run_query\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/etc/statement.sql\", \"original_file_path\": \"macros/etc/statement.sql\", \"unique_id\": \"macro.dbt.run_query\", \"macro_sql\": \"{% macro run_query(sql) %}\\n  {% call statement(\\\"run_query_statement\\\", fetch_result=true, auto_begin=false) %}\\n    {{ sql }}\\n  {% endcall %}\\n\\n  {% do return(load_result(\\\"run_query_statement\\\").table) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.739396, \"supported_languages\": null}, \"macro.dbt.convert_datetime\": {\"name\": \"convert_datetime\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"unique_id\": \"macro.dbt.convert_datetime\", \"macro_sql\": \"{% macro convert_datetime(date_str, date_fmt) %}\\n\\n  {% set error_msg -%}\\n      The provided partition date '{{ date_str }}' does not match the expected format '{{ date_fmt }}'\\n  {%- endset %}\\n\\n  {% set res = try_or_compiler_error(error_msg, modules.datetime.datetime.strptime, date_str.strip(), date_fmt) %}\\n  {{ return(res) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7423072, \"supported_languages\": null}, \"macro.dbt.dates_in_range\": {\"name\": \"dates_in_range\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"unique_id\": \"macro.dbt.dates_in_range\", \"macro_sql\": \"{% macro dates_in_range(start_date_str, end_date_str=none, in_fmt=\\\"%Y%m%d\\\", out_fmt=\\\"%Y%m%d\\\") %}\\n    {% set end_date_str = start_date_str if end_date_str is none else end_date_str %}\\n\\n    {% set start_date = convert_datetime(start_date_str, in_fmt) %}\\n    {% set end_date = convert_datetime(end_date_str, in_fmt) %}\\n\\n    {% set day_count = (end_date - start_date).days %}\\n    {% if day_count < 0 %}\\n        {% set msg -%}\\n            Partition start date is after the end date ({{ start_date }}, {{ end_date }})\\n        {%- endset %}\\n\\n        {{ exceptions.raise_compiler_error(msg, model) }}\\n    {% endif %}\\n\\n    {% set date_list = [] %}\\n    {% for i in range(0, day_count + 1) %}\\n        {% set the_date = (modules.datetime.timedelta(days=i) + start_date) %}\\n        {% if not out_fmt %}\\n            {% set _ = date_list.append(the_date) %}\\n        {% else %}\\n            {% set _ = date_list.append(the_date.strftime(out_fmt)) %}\\n        {% endif %}\\n    {% endfor %}\\n\\n    {{ return(date_list) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.convert_datetime\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7443829, \"supported_languages\": null}, \"macro.dbt.partition_range\": {\"name\": \"partition_range\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"unique_id\": \"macro.dbt.partition_range\", \"macro_sql\": \"{% macro partition_range(raw_partition_date, date_fmt='%Y%m%d') %}\\n    {% set partition_range = (raw_partition_date | string).split(\\\",\\\") %}\\n\\n    {% if (partition_range | length) == 1 %}\\n      {% set start_date = partition_range[0] %}\\n      {% set end_date = none %}\\n    {% elif (partition_range | length) == 2 %}\\n      {% set start_date = partition_range[0] %}\\n      {% set end_date = partition_range[1] %}\\n    {% else %}\\n      {{ exceptions.raise_compiler_error(\\\"Invalid partition time. Expected format: {Start Date}[,{End Date}]. Got: \\\" ~ raw_partition_date) }}\\n    {% endif %}\\n\\n    {{ return(dates_in_range(start_date, end_date, in_fmt=date_fmt)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.dates_in_range\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.745625, \"supported_languages\": null}, \"macro.dbt.py_current_timestring\": {\"name\": \"py_current_timestring\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"unique_id\": \"macro.dbt.py_current_timestring\", \"macro_sql\": \"{% macro py_current_timestring() %}\\n    {% set dt = modules.datetime.datetime.now() %}\\n    {% do return(dt.strftime(\\\"%Y%m%d%H%M%S%f\\\")) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.746016, \"supported_languages\": null}, \"macro.dbt.except\": {\"name\": \"except\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/except.sql\", \"original_file_path\": \"macros/utils/except.sql\", \"unique_id\": \"macro.dbt.except\", \"macro_sql\": \"{% macro except() %}\\n  {{ return(adapter.dispatch('except', 'dbt')()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__except\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7463942, \"supported_languages\": null}, \"macro.dbt.default__except\": {\"name\": \"default__except\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/except.sql\", \"original_file_path\": \"macros/utils/except.sql\", \"unique_id\": \"macro.dbt.default__except\", \"macro_sql\": \"{% macro default__except() %}\\n\\n    except\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7465222, \"supported_languages\": null}, \"macro.dbt.get_intervals_between\": {\"name\": \"get_intervals_between\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/date_spine.sql\", \"original_file_path\": \"macros/utils/date_spine.sql\", \"unique_id\": \"macro.dbt.get_intervals_between\", \"macro_sql\": \"{% macro get_intervals_between(start_date, end_date, datepart) -%}\\n    {{ return(adapter.dispatch('get_intervals_between', 'dbt')(start_date, end_date, datepart)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_intervals_between\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7477372, \"supported_languages\": null}, \"macro.dbt.default__get_intervals_between\": {\"name\": \"default__get_intervals_between\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/date_spine.sql\", \"original_file_path\": \"macros/utils/date_spine.sql\", \"unique_id\": \"macro.dbt.default__get_intervals_between\", \"macro_sql\": \"{% macro default__get_intervals_between(start_date, end_date, datepart) -%}\\n    {%- call statement('get_intervals_between', fetch_result=True) %}\\n\\n        select {{ dbt.datediff(start_date, end_date, datepart) }}\\n\\n    {%- endcall -%}\\n\\n    {%- set value_list = load_result('get_intervals_between') -%}\\n\\n    {%- if value_list and value_list['data'] -%}\\n        {%- set values = value_list['data'] | map(attribute=0) | list %}\\n        {{ return(values[0]) }}\\n    {%- else -%}\\n        {{ return(1) }}\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\", \"macro.dbt.datediff\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.748717, \"supported_languages\": null}, \"macro.dbt.date_spine\": {\"name\": \"date_spine\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/date_spine.sql\", \"original_file_path\": \"macros/utils/date_spine.sql\", \"unique_id\": \"macro.dbt.date_spine\", \"macro_sql\": \"{% macro date_spine(datepart, start_date, end_date) %}\\n    {{ return(adapter.dispatch('date_spine', 'dbt')(datepart, start_date, end_date)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__date_spine\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.749108, \"supported_languages\": null}, \"macro.dbt.default__date_spine\": {\"name\": \"default__date_spine\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/date_spine.sql\", \"original_file_path\": \"macros/utils/date_spine.sql\", \"unique_id\": \"macro.dbt.default__date_spine\", \"macro_sql\": \"{% macro default__date_spine(datepart, start_date, end_date) %}\\n\\n\\n    {# call as follows:\\n\\n    date_spine(\\n        \\\"day\\\",\\n        \\\"to_date('01/01/2016', 'mm/dd/yyyy')\\\",\\n        \\\"dbt.dateadd(week, 1, current_date)\\\"\\n    ) #}\\n\\n\\n    with rawdata as (\\n\\n        {{dbt.generate_series(\\n            dbt.get_intervals_between(start_date, end_date, datepart)\\n        )}}\\n\\n    ),\\n\\n    all_periods as (\\n\\n        select (\\n            {{\\n                dbt.dateadd(\\n                    datepart,\\n                    \\\"row_number() over (order by 1) - 1\\\",\\n                    start_date\\n                )\\n            }}\\n        ) as date_{{datepart}}\\n        from rawdata\\n\\n    ),\\n\\n    filtered as (\\n\\n        select *\\n        from all_periods\\n        where date_{{datepart}} <= {{ end_date }}\\n\\n    )\\n\\n    select * from filtered\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.generate_series\", \"macro.dbt.get_intervals_between\", \"macro.dbt.dateadd\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.749716, \"supported_languages\": null}, \"macro.dbt.replace\": {\"name\": \"replace\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/replace.sql\", \"original_file_path\": \"macros/utils/replace.sql\", \"unique_id\": \"macro.dbt.replace\", \"macro_sql\": \"{% macro replace(field, old_chars, new_chars) -%}\\n    {{ return(adapter.dispatch('replace', 'dbt') (field, old_chars, new_chars)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__replace\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.750282, \"supported_languages\": null}, \"macro.dbt.default__replace\": {\"name\": \"default__replace\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/replace.sql\", \"original_file_path\": \"macros/utils/replace.sql\", \"unique_id\": \"macro.dbt.default__replace\", \"macro_sql\": \"{% macro default__replace(field, old_chars, new_chars) %}\\n\\n    replace(\\n        {{ field }},\\n        {{ old_chars }},\\n        {{ new_chars }}\\n    )\\n\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.750558, \"supported_languages\": null}, \"macro.dbt.concat\": {\"name\": \"concat\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/concat.sql\", \"original_file_path\": \"macros/utils/concat.sql\", \"unique_id\": \"macro.dbt.concat\", \"macro_sql\": \"{% macro concat(fields) -%}\\n  {{ return(adapter.dispatch('concat', 'dbt')(fields)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__concat\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.75096, \"supported_languages\": null}, \"macro.dbt.default__concat\": {\"name\": \"default__concat\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/concat.sql\", \"original_file_path\": \"macros/utils/concat.sql\", \"unique_id\": \"macro.dbt.default__concat\", \"macro_sql\": \"{% macro default__concat(fields) -%}\\n    {{ fields|join(' || ') }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7511628, \"supported_languages\": null}, \"macro.dbt.get_powers_of_two\": {\"name\": \"get_powers_of_two\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/generate_series.sql\", \"original_file_path\": \"macros/utils/generate_series.sql\", \"unique_id\": \"macro.dbt.get_powers_of_two\", \"macro_sql\": \"{% macro get_powers_of_two(upper_bound) %}\\n    {{ return(adapter.dispatch('get_powers_of_two', 'dbt')(upper_bound)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_powers_of_two\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7524989, \"supported_languages\": null}, \"macro.dbt.default__get_powers_of_two\": {\"name\": \"default__get_powers_of_two\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/generate_series.sql\", \"original_file_path\": \"macros/utils/generate_series.sql\", \"unique_id\": \"macro.dbt.default__get_powers_of_two\", \"macro_sql\": \"{% macro default__get_powers_of_two(upper_bound) %}\\n\\n    {% if upper_bound <= 0 %}\\n    {{ exceptions.raise_compiler_error(\\\"upper bound must be positive\\\") }}\\n    {% endif %}\\n\\n    {% for _ in range(1, 100) %}\\n       {% if upper_bound <= 2 ** loop.index %}{{ return(loop.index) }}{% endif %}\\n    {% endfor %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.753182, \"supported_languages\": null}, \"macro.dbt.generate_series\": {\"name\": \"generate_series\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/generate_series.sql\", \"original_file_path\": \"macros/utils/generate_series.sql\", \"unique_id\": \"macro.dbt.generate_series\", \"macro_sql\": \"{% macro generate_series(upper_bound) %}\\n    {{ return(adapter.dispatch('generate_series', 'dbt')(upper_bound)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__generate_series\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7535, \"supported_languages\": null}, \"macro.dbt.default__generate_series\": {\"name\": \"default__generate_series\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/generate_series.sql\", \"original_file_path\": \"macros/utils/generate_series.sql\", \"unique_id\": \"macro.dbt.default__generate_series\", \"macro_sql\": \"{% macro default__generate_series(upper_bound) %}\\n\\n    {% set n = dbt.get_powers_of_two(upper_bound) %}\\n\\n    with p as (\\n        select 0 as generated_number union all select 1\\n    ), unioned as (\\n\\n    select\\n\\n    {% for i in range(n) %}\\n    p{{i}}.generated_number * power(2, {{i}})\\n    {% if not loop.last %} + {% endif %}\\n    {% endfor %}\\n    + 1\\n    as generated_number\\n\\n    from\\n\\n    {% for i in range(n) %}\\n    p as p{{i}}\\n    {% if not loop.last %} cross join {% endif %}\\n    {% endfor %}\\n\\n    )\\n\\n    select *\\n    from unioned\\n    where generated_number <= {{upper_bound}}\\n    order by generated_number\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_powers_of_two\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.754335, \"supported_languages\": null}, \"macro.dbt.length\": {\"name\": \"length\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/length.sql\", \"original_file_path\": \"macros/utils/length.sql\", \"unique_id\": \"macro.dbt.length\", \"macro_sql\": \"{% macro length(expression) -%}\\n    {{ return(adapter.dispatch('length', 'dbt') (expression)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__length\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7547672, \"supported_languages\": null}, \"macro.dbt.default__length\": {\"name\": \"default__length\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/length.sql\", \"original_file_path\": \"macros/utils/length.sql\", \"unique_id\": \"macro.dbt.default__length\", \"macro_sql\": \"{% macro default__length(expression) %}\\n\\n    length(\\n        {{ expression }}\\n    )\\n\\n{%- endmacro -%}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7549481, \"supported_languages\": null}, \"macro.dbt.dateadd\": {\"name\": \"dateadd\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/dateadd.sql\", \"original_file_path\": \"macros/utils/dateadd.sql\", \"unique_id\": \"macro.dbt.dateadd\", \"macro_sql\": \"{% macro dateadd(datepart, interval, from_date_or_timestamp) %}\\n  {{ return(adapter.dispatch('dateadd', 'dbt')(datepart, interval, from_date_or_timestamp)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__dateadd\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7555032, \"supported_languages\": null}, \"macro.dbt.default__dateadd\": {\"name\": \"default__dateadd\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/dateadd.sql\", \"original_file_path\": \"macros/utils/dateadd.sql\", \"unique_id\": \"macro.dbt.default__dateadd\", \"macro_sql\": \"{% macro default__dateadd(datepart, interval, from_date_or_timestamp) %}\\n\\n    dateadd(\\n        {{ datepart }},\\n        {{ interval }},\\n        {{ from_date_or_timestamp }}\\n        )\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7557771, \"supported_languages\": null}, \"macro.dbt.intersect\": {\"name\": \"intersect\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/intersect.sql\", \"original_file_path\": \"macros/utils/intersect.sql\", \"unique_id\": \"macro.dbt.intersect\", \"macro_sql\": \"{% macro intersect() %}\\n  {{ return(adapter.dispatch('intersect', 'dbt')()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__intersect\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.75615, \"supported_languages\": null}, \"macro.dbt.default__intersect\": {\"name\": \"default__intersect\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/intersect.sql\", \"original_file_path\": \"macros/utils/intersect.sql\", \"unique_id\": \"macro.dbt.default__intersect\", \"macro_sql\": \"{% macro default__intersect() %}\\n\\n    intersect\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7564, \"supported_languages\": null}, \"macro.dbt.escape_single_quotes\": {\"name\": \"escape_single_quotes\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/escape_single_quotes.sql\", \"original_file_path\": \"macros/utils/escape_single_quotes.sql\", \"unique_id\": \"macro.dbt.escape_single_quotes\", \"macro_sql\": \"{% macro escape_single_quotes(expression) %}\\n      {{ return(adapter.dispatch('escape_single_quotes', 'dbt') (expression)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__escape_single_quotes\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.756841, \"supported_languages\": null}, \"macro.dbt.default__escape_single_quotes\": {\"name\": \"default__escape_single_quotes\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/escape_single_quotes.sql\", \"original_file_path\": \"macros/utils/escape_single_quotes.sql\", \"unique_id\": \"macro.dbt.default__escape_single_quotes\", \"macro_sql\": \"{% macro default__escape_single_quotes(expression) -%}\\n{{ expression | replace(\\\"'\\\",\\\"''\\\") }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7570739, \"supported_languages\": null}, \"macro.dbt.right\": {\"name\": \"right\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/right.sql\", \"original_file_path\": \"macros/utils/right.sql\", \"unique_id\": \"macro.dbt.right\", \"macro_sql\": \"{% macro right(string_text, length_expression) -%}\\n    {{ return(adapter.dispatch('right', 'dbt') (string_text, length_expression)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__right\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.75756, \"supported_languages\": null}, \"macro.dbt.default__right\": {\"name\": \"default__right\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/right.sql\", \"original_file_path\": \"macros/utils/right.sql\", \"unique_id\": \"macro.dbt.default__right\", \"macro_sql\": \"{% macro default__right(string_text, length_expression) %}\\n\\n    right(\\n        {{ string_text }},\\n        {{ length_expression }}\\n    )\\n\\n{%- endmacro -%}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.757789, \"supported_languages\": null}, \"macro.dbt.listagg\": {\"name\": \"listagg\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/listagg.sql\", \"original_file_path\": \"macros/utils/listagg.sql\", \"unique_id\": \"macro.dbt.listagg\", \"macro_sql\": \"{% macro listagg(measure, delimiter_text=\\\"','\\\", order_by_clause=none, limit_num=none) -%}\\n    {{ return(adapter.dispatch('listagg', 'dbt') (measure, delimiter_text, order_by_clause, limit_num)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__listagg\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.758796, \"supported_languages\": null}, \"macro.dbt.default__listagg\": {\"name\": \"default__listagg\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/listagg.sql\", \"original_file_path\": \"macros/utils/listagg.sql\", \"unique_id\": \"macro.dbt.default__listagg\", \"macro_sql\": \"{% macro default__listagg(measure, delimiter_text, order_by_clause, limit_num) -%}\\n\\n    {% if limit_num -%}\\n    array_to_string(\\n        array_slice(\\n            array_agg(\\n                {{ measure }}\\n            ){% if order_by_clause -%}\\n            within group ({{ order_by_clause }})\\n            {%- endif %}\\n            ,0\\n            ,{{ limit_num }}\\n        ),\\n        {{ delimiter_text }}\\n        )\\n    {%- else %}\\n    listagg(\\n        {{ measure }},\\n        {{ delimiter_text }}\\n        )\\n        {% if order_by_clause -%}\\n        within group ({{ order_by_clause }})\\n        {%- endif %}\\n    {%- endif %}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7594528, \"supported_languages\": null}, \"macro.dbt.datediff\": {\"name\": \"datediff\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/datediff.sql\", \"original_file_path\": \"macros/utils/datediff.sql\", \"unique_id\": \"macro.dbt.datediff\", \"macro_sql\": \"{% macro datediff(first_date, second_date, datepart) %}\\n  {{ return(adapter.dispatch('datediff', 'dbt')(first_date, second_date, datepart)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__datediff\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.759997, \"supported_languages\": null}, \"macro.dbt.default__datediff\": {\"name\": \"default__datediff\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/datediff.sql\", \"original_file_path\": \"macros/utils/datediff.sql\", \"unique_id\": \"macro.dbt.default__datediff\", \"macro_sql\": \"{% macro default__datediff(first_date, second_date, datepart) -%}\\n\\n    datediff(\\n        {{ datepart }},\\n        {{ first_date }},\\n        {{ second_date }}\\n        )\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7602718, \"supported_languages\": null}, \"macro.dbt.safe_cast\": {\"name\": \"safe_cast\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/safe_cast.sql\", \"original_file_path\": \"macros/utils/safe_cast.sql\", \"unique_id\": \"macro.dbt.safe_cast\", \"macro_sql\": \"{% macro safe_cast(field, type) %}\\n  {{ return(adapter.dispatch('safe_cast', 'dbt') (field, type)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__safe_cast\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.760739, \"supported_languages\": null}, \"macro.dbt.default__safe_cast\": {\"name\": \"default__safe_cast\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/safe_cast.sql\", \"original_file_path\": \"macros/utils/safe_cast.sql\", \"unique_id\": \"macro.dbt.default__safe_cast\", \"macro_sql\": \"{% macro default__safe_cast(field, type) %}\\n    {# most databases don't support this function yet\\n    so we just need to use cast #}\\n    cast({{field}} as {{type}})\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.760973, \"supported_languages\": null}, \"macro.dbt.hash\": {\"name\": \"hash\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/hash.sql\", \"original_file_path\": \"macros/utils/hash.sql\", \"unique_id\": \"macro.dbt.hash\", \"macro_sql\": \"{% macro hash(field) -%}\\n  {{ return(adapter.dispatch('hash', 'dbt') (field)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__hash\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.76143, \"supported_languages\": null}, \"macro.dbt.default__hash\": {\"name\": \"default__hash\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/hash.sql\", \"original_file_path\": \"macros/utils/hash.sql\", \"unique_id\": \"macro.dbt.default__hash\", \"macro_sql\": \"{% macro default__hash(field) -%}\\n    md5(cast({{ field }} as {{ api.Column.translate_type('string') }}))\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.761698, \"supported_languages\": null}, \"macro.dbt.cast_bool_to_text\": {\"name\": \"cast_bool_to_text\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/cast_bool_to_text.sql\", \"original_file_path\": \"macros/utils/cast_bool_to_text.sql\", \"unique_id\": \"macro.dbt.cast_bool_to_text\", \"macro_sql\": \"{% macro cast_bool_to_text(field) %}\\n  {{ adapter.dispatch('cast_bool_to_text', 'dbt') (field) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__cast_bool_to_text\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.762109, \"supported_languages\": null}, \"macro.dbt.default__cast_bool_to_text\": {\"name\": \"default__cast_bool_to_text\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/cast_bool_to_text.sql\", \"original_file_path\": \"macros/utils/cast_bool_to_text.sql\", \"unique_id\": \"macro.dbt.default__cast_bool_to_text\", \"macro_sql\": \"{% macro default__cast_bool_to_text(field) %}\\n    cast({{ field }} as {{ api.Column.translate_type('string') }})\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.762371, \"supported_languages\": null}, \"macro.dbt.any_value\": {\"name\": \"any_value\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/any_value.sql\", \"original_file_path\": \"macros/utils/any_value.sql\", \"unique_id\": \"macro.dbt.any_value\", \"macro_sql\": \"{% macro any_value(expression) -%}\\n    {{ return(adapter.dispatch('any_value', 'dbt') (expression)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__any_value\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.762775, \"supported_languages\": null}, \"macro.dbt.default__any_value\": {\"name\": \"default__any_value\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/any_value.sql\", \"original_file_path\": \"macros/utils/any_value.sql\", \"unique_id\": \"macro.dbt.default__any_value\", \"macro_sql\": \"{% macro default__any_value(expression) -%}\\n\\n    any_value({{ expression }})\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7629561, \"supported_languages\": null}, \"macro.dbt.position\": {\"name\": \"position\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/position.sql\", \"original_file_path\": \"macros/utils/position.sql\", \"unique_id\": \"macro.dbt.position\", \"macro_sql\": \"{% macro position(substring_text, string_text) -%}\\n    {{ return(adapter.dispatch('position', 'dbt') (substring_text, string_text)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__position\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7634618, \"supported_languages\": null}, \"macro.dbt.default__position\": {\"name\": \"default__position\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/position.sql\", \"original_file_path\": \"macros/utils/position.sql\", \"unique_id\": \"macro.dbt.default__position\", \"macro_sql\": \"{% macro default__position(substring_text, string_text) %}\\n\\n    position(\\n        {{ substring_text }} in {{ string_text }}\\n    )\\n\\n{%- endmacro -%}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.763691, \"supported_languages\": null}, \"macro.dbt.string_literal\": {\"name\": \"string_literal\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/literal.sql\", \"original_file_path\": \"macros/utils/literal.sql\", \"unique_id\": \"macro.dbt.string_literal\", \"macro_sql\": \"{%- macro string_literal(value) -%}\\n  {{ return(adapter.dispatch('string_literal', 'dbt') (value)) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__string_literal\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.764083, \"supported_languages\": null}, \"macro.dbt.default__string_literal\": {\"name\": \"default__string_literal\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/literal.sql\", \"original_file_path\": \"macros/utils/literal.sql\", \"unique_id\": \"macro.dbt.default__string_literal\", \"macro_sql\": \"{% macro default__string_literal(value) -%}\\n    '{{ value }}'\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.764363, \"supported_languages\": null}, \"macro.dbt.type_string\": {\"name\": \"type_string\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.type_string\", \"macro_sql\": \"\\n\\n{%- macro type_string() -%}\\n  {{ return(adapter.dispatch('type_string', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__type_string\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.765888, \"supported_languages\": null}, \"macro.dbt.default__type_string\": {\"name\": \"default__type_string\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.default__type_string\", \"macro_sql\": \"{% macro default__type_string() %}\\n    {{ return(api.Column.translate_type(\\\"string\\\")) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.766141, \"supported_languages\": null}, \"macro.dbt.type_timestamp\": {\"name\": \"type_timestamp\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.type_timestamp\", \"macro_sql\": \"\\n\\n{%- macro type_timestamp() -%}\\n  {{ return(adapter.dispatch('type_timestamp', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__type_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.766407, \"supported_languages\": null}, \"macro.dbt.default__type_timestamp\": {\"name\": \"default__type_timestamp\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.default__type_timestamp\", \"macro_sql\": \"{% macro default__type_timestamp() %}\\n    {{ return(api.Column.translate_type(\\\"timestamp\\\")) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7666519, \"supported_languages\": null}, \"macro.dbt.type_float\": {\"name\": \"type_float\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.type_float\", \"macro_sql\": \"\\n\\n{%- macro type_float() -%}\\n  {{ return(adapter.dispatch('type_float', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__type_float\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7669199, \"supported_languages\": null}, \"macro.dbt.default__type_float\": {\"name\": \"default__type_float\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.default__type_float\", \"macro_sql\": \"{% macro default__type_float() %}\\n    {{ return(api.Column.translate_type(\\\"float\\\")) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.767169, \"supported_languages\": null}, \"macro.dbt.type_numeric\": {\"name\": \"type_numeric\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.type_numeric\", \"macro_sql\": \"\\n\\n{%- macro type_numeric() -%}\\n  {{ return(adapter.dispatch('type_numeric', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__type_numeric\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.767443, \"supported_languages\": null}, \"macro.dbt.default__type_numeric\": {\"name\": \"default__type_numeric\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.default__type_numeric\", \"macro_sql\": \"{% macro default__type_numeric() %}\\n    {{ return(api.Column.numeric_type(\\\"numeric\\\", 28, 6)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7677372, \"supported_languages\": null}, \"macro.dbt.type_bigint\": {\"name\": \"type_bigint\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.type_bigint\", \"macro_sql\": \"\\n\\n{%- macro type_bigint() -%}\\n  {{ return(adapter.dispatch('type_bigint', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__type_bigint\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7680051, \"supported_languages\": null}, \"macro.dbt.default__type_bigint\": {\"name\": \"default__type_bigint\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.default__type_bigint\", \"macro_sql\": \"{% macro default__type_bigint() %}\\n    {{ return(api.Column.translate_type(\\\"bigint\\\")) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.768262, \"supported_languages\": null}, \"macro.dbt.type_int\": {\"name\": \"type_int\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.type_int\", \"macro_sql\": \"\\n\\n{%- macro type_int() -%}\\n  {{ return(adapter.dispatch('type_int', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__type_int\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.768537, \"supported_languages\": null}, \"macro.dbt.default__type_int\": {\"name\": \"default__type_int\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.default__type_int\", \"macro_sql\": \"{%- macro default__type_int() -%}\\n  {{ return(api.Column.translate_type(\\\"integer\\\")) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.768776, \"supported_languages\": null}, \"macro.dbt.type_boolean\": {\"name\": \"type_boolean\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.type_boolean\", \"macro_sql\": \"\\n\\n{%- macro type_boolean() -%}\\n  {{ return(adapter.dispatch('type_boolean', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__type_boolean\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.769038, \"supported_languages\": null}, \"macro.dbt.default__type_boolean\": {\"name\": \"default__type_boolean\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.default__type_boolean\", \"macro_sql\": \"{%- macro default__type_boolean() -%}\\n  {{ return(api.Column.translate_type(\\\"boolean\\\")) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.769278, \"supported_languages\": null}, \"macro.dbt.array_concat\": {\"name\": \"array_concat\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/array_concat.sql\", \"original_file_path\": \"macros/utils/array_concat.sql\", \"unique_id\": \"macro.dbt.array_concat\", \"macro_sql\": \"{% macro array_concat(array_1, array_2) -%}\\n  {{ return(adapter.dispatch('array_concat', 'dbt')(array_1, array_2)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__array_concat\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.769752, \"supported_languages\": null}, \"macro.dbt.default__array_concat\": {\"name\": \"default__array_concat\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/array_concat.sql\", \"original_file_path\": \"macros/utils/array_concat.sql\", \"unique_id\": \"macro.dbt.default__array_concat\", \"macro_sql\": \"{% macro default__array_concat(array_1, array_2) -%}\\n    array_cat({{ array_1 }}, {{ array_2 }})\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.769978, \"supported_languages\": null}, \"macro.dbt.bool_or\": {\"name\": \"bool_or\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/bool_or.sql\", \"original_file_path\": \"macros/utils/bool_or.sql\", \"unique_id\": \"macro.dbt.bool_or\", \"macro_sql\": \"{% macro bool_or(expression) -%}\\n    {{ return(adapter.dispatch('bool_or', 'dbt') (expression)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__bool_or\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.770388, \"supported_languages\": null}, \"macro.dbt.default__bool_or\": {\"name\": \"default__bool_or\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/bool_or.sql\", \"original_file_path\": \"macros/utils/bool_or.sql\", \"unique_id\": \"macro.dbt.default__bool_or\", \"macro_sql\": \"{% macro default__bool_or(expression) -%}\\n\\n    bool_or({{ expression }})\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.770564, \"supported_languages\": null}, \"macro.dbt.last_day\": {\"name\": \"last_day\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/last_day.sql\", \"original_file_path\": \"macros/utils/last_day.sql\", \"unique_id\": \"macro.dbt.last_day\", \"macro_sql\": \"{% macro last_day(date, datepart) %}\\n  {{ return(adapter.dispatch('last_day', 'dbt') (date, datepart)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__last_day\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.771231, \"supported_languages\": null}, \"macro.dbt.default_last_day\": {\"name\": \"default_last_day\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/last_day.sql\", \"original_file_path\": \"macros/utils/last_day.sql\", \"unique_id\": \"macro.dbt.default_last_day\", \"macro_sql\": \"\\n\\n{%- macro default_last_day(date, datepart) -%}\\n    cast(\\n        {{dbt.dateadd('day', '-1',\\n        dbt.dateadd(datepart, '1', dbt.date_trunc(datepart, date))\\n        )}}\\n        as date)\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.dateadd\", \"macro.dbt.date_trunc\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.771678, \"supported_languages\": null}, \"macro.dbt.default__last_day\": {\"name\": \"default__last_day\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/last_day.sql\", \"original_file_path\": \"macros/utils/last_day.sql\", \"unique_id\": \"macro.dbt.default__last_day\", \"macro_sql\": \"{% macro default__last_day(date, datepart) -%}\\n    {{dbt.default_last_day(date, datepart)}}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default_last_day\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.771925, \"supported_languages\": null}, \"macro.dbt.split_part\": {\"name\": \"split_part\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/split_part.sql\", \"original_file_path\": \"macros/utils/split_part.sql\", \"unique_id\": \"macro.dbt.split_part\", \"macro_sql\": \"{% macro split_part(string_text, delimiter_text, part_number) %}\\n  {{ return(adapter.dispatch('split_part', 'dbt') (string_text, delimiter_text, part_number)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__split_part\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.772767, \"supported_languages\": null}, \"macro.dbt.default__split_part\": {\"name\": \"default__split_part\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/split_part.sql\", \"original_file_path\": \"macros/utils/split_part.sql\", \"unique_id\": \"macro.dbt.default__split_part\", \"macro_sql\": \"{% macro default__split_part(string_text, delimiter_text, part_number) %}\\n\\n    split_part(\\n        {{ string_text }},\\n        {{ delimiter_text }},\\n        {{ part_number }}\\n        )\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.773036, \"supported_languages\": null}, \"macro.dbt._split_part_negative\": {\"name\": \"_split_part_negative\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/split_part.sql\", \"original_file_path\": \"macros/utils/split_part.sql\", \"unique_id\": \"macro.dbt._split_part_negative\", \"macro_sql\": \"{% macro _split_part_negative(string_text, delimiter_text, part_number) %}\\n\\n    split_part(\\n        {{ string_text }},\\n        {{ delimiter_text }},\\n          length({{ string_text }})\\n          - length(\\n              replace({{ string_text }},  {{ delimiter_text }}, '')\\n          ) + 2 + {{ part_number }}\\n        )\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7733939, \"supported_languages\": null}, \"macro.dbt.date_trunc\": {\"name\": \"date_trunc\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/date_trunc.sql\", \"original_file_path\": \"macros/utils/date_trunc.sql\", \"unique_id\": \"macro.dbt.date_trunc\", \"macro_sql\": \"{% macro date_trunc(datepart, date) -%}\\n  {{ return(adapter.dispatch('date_trunc', 'dbt') (datepart, date)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__date_trunc\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.773841, \"supported_languages\": null}, \"macro.dbt.default__date_trunc\": {\"name\": \"default__date_trunc\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/date_trunc.sql\", \"original_file_path\": \"macros/utils/date_trunc.sql\", \"unique_id\": \"macro.dbt.default__date_trunc\", \"macro_sql\": \"{% macro default__date_trunc(datepart, date) -%}\\n    date_trunc('{{datepart}}', {{date}})\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.774057, \"supported_languages\": null}, \"macro.dbt.array_construct\": {\"name\": \"array_construct\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/array_construct.sql\", \"original_file_path\": \"macros/utils/array_construct.sql\", \"unique_id\": \"macro.dbt.array_construct\", \"macro_sql\": \"{% macro array_construct(inputs=[], data_type=api.Column.translate_type('integer')) -%}\\n  {{ return(adapter.dispatch('array_construct', 'dbt')(inputs, data_type)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__array_construct\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7746718, \"supported_languages\": null}, \"macro.dbt.default__array_construct\": {\"name\": \"default__array_construct\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/array_construct.sql\", \"original_file_path\": \"macros/utils/array_construct.sql\", \"unique_id\": \"macro.dbt.default__array_construct\", \"macro_sql\": \"{% macro default__array_construct(inputs, data_type) -%}\\n    {% if inputs|length > 0 %}\\n    array[ {{ inputs|join(' , ') }} ]\\n    {% else %}\\n    array[]::{{data_type}}[]\\n    {% endif %}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.77508, \"supported_languages\": null}, \"macro.dbt.array_append\": {\"name\": \"array_append\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/array_append.sql\", \"original_file_path\": \"macros/utils/array_append.sql\", \"unique_id\": \"macro.dbt.array_append\", \"macro_sql\": \"{% macro array_append(array, new_element) -%}\\n  {{ return(adapter.dispatch('array_append', 'dbt')(array, new_element)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__array_append\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.775543, \"supported_languages\": null}, \"macro.dbt.default__array_append\": {\"name\": \"default__array_append\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/array_append.sql\", \"original_file_path\": \"macros/utils/array_append.sql\", \"unique_id\": \"macro.dbt.default__array_append\", \"macro_sql\": \"{% macro default__array_append(array, new_element) -%}\\n    array_append({{ array }}, {{ new_element }})\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.775769, \"supported_languages\": null}, \"macro.dbt.create_schema\": {\"name\": \"create_schema\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/schema.sql\", \"original_file_path\": \"macros/adapters/schema.sql\", \"unique_id\": \"macro.dbt.create_schema\", \"macro_sql\": \"{% macro create_schema(relation) -%}\\n  {{ adapter.dispatch('create_schema', 'dbt')(relation) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__create_schema\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.776381, \"supported_languages\": null}, \"macro.dbt.default__create_schema\": {\"name\": \"default__create_schema\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/schema.sql\", \"original_file_path\": \"macros/adapters/schema.sql\", \"unique_id\": \"macro.dbt.default__create_schema\", \"macro_sql\": \"{% macro default__create_schema(relation) -%}\\n  {%- call statement('create_schema') -%}\\n    create schema if not exists {{ relation.without_identifier() }}\\n  {% endcall %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.776683, \"supported_languages\": null}, \"macro.dbt.drop_schema\": {\"name\": \"drop_schema\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/schema.sql\", \"original_file_path\": \"macros/adapters/schema.sql\", \"unique_id\": \"macro.dbt.drop_schema\", \"macro_sql\": \"{% macro drop_schema(relation) -%}\\n  {{ adapter.dispatch('drop_schema', 'dbt')(relation) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__drop_schema\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.776957, \"supported_languages\": null}, \"macro.dbt.default__drop_schema\": {\"name\": \"default__drop_schema\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/schema.sql\", \"original_file_path\": \"macros/adapters/schema.sql\", \"unique_id\": \"macro.dbt.default__drop_schema\", \"macro_sql\": \"{% macro default__drop_schema(relation) -%}\\n  {%- call statement('drop_schema') -%}\\n    drop schema if exists {{ relation.without_identifier() }} cascade\\n  {% endcall %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.777257, \"supported_languages\": null}, \"macro.dbt.current_timestamp\": {\"name\": \"current_timestamp\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"unique_id\": \"macro.dbt.current_timestamp\", \"macro_sql\": \"{%- macro current_timestamp() -%}\\n    {{ adapter.dispatch('current_timestamp', 'dbt')() }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.778059, \"supported_languages\": null}, \"macro.dbt.default__current_timestamp\": {\"name\": \"default__current_timestamp\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"unique_id\": \"macro.dbt.default__current_timestamp\", \"macro_sql\": \"{% macro default__current_timestamp() -%}\\n  {{ exceptions.raise_not_implemented(\\n    'current_timestamp macro not implemented for adapter ' + adapter.type()) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.778315, \"supported_languages\": null}, \"macro.dbt.snapshot_get_time\": {\"name\": \"snapshot_get_time\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"unique_id\": \"macro.dbt.snapshot_get_time\", \"macro_sql\": \"\\n\\n{%- macro snapshot_get_time() -%}\\n    {{ adapter.dispatch('snapshot_get_time', 'dbt')() }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__snapshot_get_time\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.778553, \"supported_languages\": null}, \"macro.dbt.default__snapshot_get_time\": {\"name\": \"default__snapshot_get_time\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"unique_id\": \"macro.dbt.default__snapshot_get_time\", \"macro_sql\": \"{% macro default__snapshot_get_time() %}\\n    {{ current_timestamp() }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7787268, \"supported_languages\": null}, \"macro.dbt.current_timestamp_backcompat\": {\"name\": \"current_timestamp_backcompat\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"unique_id\": \"macro.dbt.current_timestamp_backcompat\", \"macro_sql\": \"{% macro current_timestamp_backcompat() %}\\n    {{ return(adapter.dispatch('current_timestamp_backcompat', 'dbt')()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__current_timestamp_backcompat\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7791228, \"supported_languages\": null}, \"macro.dbt.default__current_timestamp_backcompat\": {\"name\": \"default__current_timestamp_backcompat\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"unique_id\": \"macro.dbt.default__current_timestamp_backcompat\", \"macro_sql\": \"{% macro default__current_timestamp_backcompat() %}\\n    current_timestamp::timestamp\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.779256, \"supported_languages\": null}, \"macro.dbt.current_timestamp_in_utc_backcompat\": {\"name\": \"current_timestamp_in_utc_backcompat\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"unique_id\": \"macro.dbt.current_timestamp_in_utc_backcompat\", \"macro_sql\": \"{% macro current_timestamp_in_utc_backcompat() %}\\n    {{ return(adapter.dispatch('current_timestamp_in_utc_backcompat', 'dbt')()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__current_timestamp_in_utc_backcompat\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.779534, \"supported_languages\": null}, \"macro.dbt.default__current_timestamp_in_utc_backcompat\": {\"name\": \"default__current_timestamp_in_utc_backcompat\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"unique_id\": \"macro.dbt.default__current_timestamp_in_utc_backcompat\", \"macro_sql\": \"{% macro default__current_timestamp_in_utc_backcompat() %}\\n    {{ return(adapter.dispatch('current_timestamp_backcompat', 'dbt')()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.current_timestamp_backcompat\", \"macro.dbt_postgres.postgres__current_timestamp_backcompat\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.779809, \"supported_languages\": null}, \"macro.dbt.get_create_index_sql\": {\"name\": \"get_create_index_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"unique_id\": \"macro.dbt.get_create_index_sql\", \"macro_sql\": \"{% macro get_create_index_sql(relation, index_dict) -%}\\n  {{ return(adapter.dispatch('get_create_index_sql', 'dbt')(relation, index_dict)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_create_index_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.781184, \"supported_languages\": null}, \"macro.dbt.default__get_create_index_sql\": {\"name\": \"default__get_create_index_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"unique_id\": \"macro.dbt.default__get_create_index_sql\", \"macro_sql\": \"{% macro default__get_create_index_sql(relation, index_dict) -%}\\n  {% do return(None) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7814138, \"supported_languages\": null}, \"macro.dbt.create_indexes\": {\"name\": \"create_indexes\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"unique_id\": \"macro.dbt.create_indexes\", \"macro_sql\": \"{% macro create_indexes(relation) -%}\\n  {{ adapter.dispatch('create_indexes', 'dbt')(relation) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__create_indexes\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.781677, \"supported_languages\": null}, \"macro.dbt.default__create_indexes\": {\"name\": \"default__create_indexes\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"unique_id\": \"macro.dbt.default__create_indexes\", \"macro_sql\": \"{% macro default__create_indexes(relation) -%}\\n  {%- set _indexes = config.get('indexes', default=[]) -%}\\n\\n  {% for _index_dict in _indexes %}\\n    {% set create_index_sql = get_create_index_sql(relation, _index_dict) %}\\n    {% if create_index_sql %}\\n      {% do run_query(create_index_sql) %}\\n    {% endif %}\\n  {% endfor %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_create_index_sql\", \"macro.dbt.run_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.782335, \"supported_languages\": null}, \"macro.dbt.get_drop_index_sql\": {\"name\": \"get_drop_index_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"unique_id\": \"macro.dbt.get_drop_index_sql\", \"macro_sql\": \"{% macro get_drop_index_sql(relation, index_name) -%}\\n    {{ adapter.dispatch('get_drop_index_sql', 'dbt')(relation, index_name) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_drop_index_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.782665, \"supported_languages\": null}, \"macro.dbt.default__get_drop_index_sql\": {\"name\": \"default__get_drop_index_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"unique_id\": \"macro.dbt.default__get_drop_index_sql\", \"macro_sql\": \"{% macro default__get_drop_index_sql(relation, index_name) -%}\\n    {{ exceptions.raise_compiler_error(\\\"`get_drop_index_sql has not been implemented for this adapter.\\\") }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.782913, \"supported_languages\": null}, \"macro.dbt.get_show_indexes_sql\": {\"name\": \"get_show_indexes_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"unique_id\": \"macro.dbt.get_show_indexes_sql\", \"macro_sql\": \"{% macro get_show_indexes_sql(relation) -%}\\n    {{ adapter.dispatch('get_show_indexes_sql', 'dbt')(relation) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_show_indexes_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.783176, \"supported_languages\": null}, \"macro.dbt.default__get_show_indexes_sql\": {\"name\": \"default__get_show_indexes_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"unique_id\": \"macro.dbt.default__get_show_indexes_sql\", \"macro_sql\": \"{% macro default__get_show_indexes_sql(relation) -%}\\n    {{ exceptions.raise_compiler_error(\\\"`get_show_indexes_sql has not been implemented for this adapter.\\\") }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.783384, \"supported_languages\": null}, \"macro.dbt.make_intermediate_relation\": {\"name\": \"make_intermediate_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.make_intermediate_relation\", \"macro_sql\": \"{% macro make_intermediate_relation(base_relation, suffix='__dbt_tmp') %}\\n  {{ return(adapter.dispatch('make_intermediate_relation', 'dbt')(base_relation, suffix)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_intermediate_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7865632, \"supported_languages\": null}, \"macro.dbt.default__make_intermediate_relation\": {\"name\": \"default__make_intermediate_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.default__make_intermediate_relation\", \"macro_sql\": \"{% macro default__make_intermediate_relation(base_relation, suffix) %}\\n    {{ return(default__make_temp_relation(base_relation, suffix)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__make_temp_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7868469, \"supported_languages\": null}, \"macro.dbt.make_temp_relation\": {\"name\": \"make_temp_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.make_temp_relation\", \"macro_sql\": \"{% macro make_temp_relation(base_relation, suffix='__dbt_tmp') %}\\n  {{ return(adapter.dispatch('make_temp_relation', 'dbt')(base_relation, suffix)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_temp_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7872078, \"supported_languages\": null}, \"macro.dbt.default__make_temp_relation\": {\"name\": \"default__make_temp_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.default__make_temp_relation\", \"macro_sql\": \"{% macro default__make_temp_relation(base_relation, suffix) %}\\n    {%- set temp_identifier = base_relation.identifier ~ suffix -%}\\n    {%- set temp_relation = base_relation.incorporate(\\n                                path={\\\"identifier\\\": temp_identifier}) -%}\\n\\n    {{ return(temp_relation) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7876961, \"supported_languages\": null}, \"macro.dbt.make_backup_relation\": {\"name\": \"make_backup_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.make_backup_relation\", \"macro_sql\": \"{% macro make_backup_relation(base_relation, backup_relation_type, suffix='__dbt_backup') %}\\n    {{ return(adapter.dispatch('make_backup_relation', 'dbt')(base_relation, backup_relation_type, suffix)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_backup_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.788102, \"supported_languages\": null}, \"macro.dbt.default__make_backup_relation\": {\"name\": \"default__make_backup_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.default__make_backup_relation\", \"macro_sql\": \"{% macro default__make_backup_relation(base_relation, backup_relation_type, suffix) %}\\n    {%- set backup_identifier = base_relation.identifier ~ suffix -%}\\n    {%- set backup_relation = base_relation.incorporate(\\n                                  path={\\\"identifier\\\": backup_identifier},\\n                                  type=backup_relation_type\\n    ) -%}\\n    {{ return(backup_relation) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.788644, \"supported_languages\": null}, \"macro.dbt.truncate_relation\": {\"name\": \"truncate_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.truncate_relation\", \"macro_sql\": \"{% macro truncate_relation(relation) -%}\\n  {{ return(adapter.dispatch('truncate_relation', 'dbt')(relation)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__truncate_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.788949, \"supported_languages\": null}, \"macro.dbt.default__truncate_relation\": {\"name\": \"default__truncate_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.default__truncate_relation\", \"macro_sql\": \"{% macro default__truncate_relation(relation) -%}\\n  {% call statement('truncate_relation') -%}\\n    truncate table {{ relation }}\\n  {%- endcall %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.789593, \"supported_languages\": null}, \"macro.dbt.get_or_create_relation\": {\"name\": \"get_or_create_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.get_or_create_relation\", \"macro_sql\": \"{% macro get_or_create_relation(database, schema, identifier, type) -%}\\n  {{ return(adapter.dispatch('get_or_create_relation', 'dbt')(database, schema, identifier, type)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_or_create_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.790008, \"supported_languages\": null}, \"macro.dbt.default__get_or_create_relation\": {\"name\": \"default__get_or_create_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.default__get_or_create_relation\", \"macro_sql\": \"{% macro default__get_or_create_relation(database, schema, identifier, type) %}\\n  {%- set target_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) %}\\n\\n  {% if target_relation %}\\n    {% do return([true, target_relation]) %}\\n  {% endif %}\\n\\n  {%- set new_relation = api.Relation.create(\\n      database=database,\\n      schema=schema,\\n      identifier=identifier,\\n      type=type\\n  ) -%}\\n  {% do return([false, new_relation]) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7909272, \"supported_languages\": null}, \"macro.dbt.load_cached_relation\": {\"name\": \"load_cached_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.load_cached_relation\", \"macro_sql\": \"{% macro load_cached_relation(relation) %}\\n  {% do return(adapter.get_relation(\\n    database=relation.database,\\n    schema=relation.schema,\\n    identifier=relation.identifier\\n  )) -%}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.791318, \"supported_languages\": null}, \"macro.dbt.load_relation\": {\"name\": \"load_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.load_relation\", \"macro_sql\": \"{% macro load_relation(relation) %}\\n    {{ return(load_cached_relation(relation)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.load_cached_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.791553, \"supported_languages\": null}, \"macro.dbt.collect_freshness\": {\"name\": \"collect_freshness\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/freshness.sql\", \"original_file_path\": \"macros/adapters/freshness.sql\", \"unique_id\": \"macro.dbt.collect_freshness\", \"macro_sql\": \"{% macro collect_freshness(source, loaded_at_field, filter) %}\\n  {{ return(adapter.dispatch('collect_freshness', 'dbt')(source, loaded_at_field, filter))}}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__collect_freshness\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7922392, \"supported_languages\": null}, \"macro.dbt.default__collect_freshness\": {\"name\": \"default__collect_freshness\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/freshness.sql\", \"original_file_path\": \"macros/adapters/freshness.sql\", \"unique_id\": \"macro.dbt.default__collect_freshness\", \"macro_sql\": \"{% macro default__collect_freshness(source, loaded_at_field, filter) %}\\n  {% call statement('collect_freshness', fetch_result=True, auto_begin=False) -%}\\n    select\\n      max({{ loaded_at_field }}) as max_loaded_at,\\n      {{ current_timestamp() }} as snapshotted_at\\n    from {{ source }}\\n    {% if filter %}\\n    where {{ filter }}\\n    {% endif %}\\n  {% endcall %}\\n  {{ return(load_result('collect_freshness')) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\", \"macro.dbt.current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7929611, \"supported_languages\": null}, \"macro.dbt.validate_sql\": {\"name\": \"validate_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/validate_sql.sql\", \"original_file_path\": \"macros/adapters/validate_sql.sql\", \"unique_id\": \"macro.dbt.validate_sql\", \"macro_sql\": \"{% macro validate_sql(sql) -%}\\n  {{ return(adapter.dispatch('validate_sql', 'dbt')(sql)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__validate_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.793429, \"supported_languages\": null}, \"macro.dbt.default__validate_sql\": {\"name\": \"default__validate_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/validate_sql.sql\", \"original_file_path\": \"macros/adapters/validate_sql.sql\", \"unique_id\": \"macro.dbt.default__validate_sql\", \"macro_sql\": \"{% macro default__validate_sql(sql) -%}\\n  {% call statement('validate_sql') -%}\\n    explain {{ sql }}\\n  {% endcall %}\\n  {{ return(load_result('validate_sql')) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.793799, \"supported_languages\": null}, \"macro.dbt.copy_grants\": {\"name\": \"copy_grants\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.copy_grants\", \"macro_sql\": \"{% macro copy_grants() %}\\n    {{ return(adapter.dispatch('copy_grants', 'dbt')()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__copy_grants\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.796642, \"supported_languages\": null}, \"macro.dbt.default__copy_grants\": {\"name\": \"default__copy_grants\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.default__copy_grants\", \"macro_sql\": \"{% macro default__copy_grants() %}\\n    {{ return(True) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7968378, \"supported_languages\": null}, \"macro.dbt.support_multiple_grantees_per_dcl_statement\": {\"name\": \"support_multiple_grantees_per_dcl_statement\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.support_multiple_grantees_per_dcl_statement\", \"macro_sql\": \"{% macro support_multiple_grantees_per_dcl_statement() %}\\n    {{ return(adapter.dispatch('support_multiple_grantees_per_dcl_statement', 'dbt')()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__support_multiple_grantees_per_dcl_statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.797121, \"supported_languages\": null}, \"macro.dbt.default__support_multiple_grantees_per_dcl_statement\": {\"name\": \"default__support_multiple_grantees_per_dcl_statement\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.default__support_multiple_grantees_per_dcl_statement\", \"macro_sql\": \"\\n\\n{%- macro default__support_multiple_grantees_per_dcl_statement() -%}\\n    {{ return(True) }}\\n{%- endmacro -%}\\n\\n\\n\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.797313, \"supported_languages\": null}, \"macro.dbt.should_revoke\": {\"name\": \"should_revoke\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.should_revoke\", \"macro_sql\": \"{% macro should_revoke(existing_relation, full_refresh_mode=True) %}\\n\\n    {% if not existing_relation %}\\n        {#-- The table doesn't already exist, so no grants to copy over --#}\\n        {{ return(False) }}\\n    {% elif full_refresh_mode %}\\n        {#-- The object is being REPLACED -- whether grants are copied over depends on the value of user config --#}\\n        {{ return(copy_grants()) }}\\n    {% else %}\\n        {#-- The table is being merged/upserted/inserted -- grants will be carried over --#}\\n        {{ return(True) }}\\n    {% endif %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.copy_grants\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.797886, \"supported_languages\": null}, \"macro.dbt.get_show_grant_sql\": {\"name\": \"get_show_grant_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.get_show_grant_sql\", \"macro_sql\": \"{% macro get_show_grant_sql(relation) %}\\n    {{ return(adapter.dispatch(\\\"get_show_grant_sql\\\", \\\"dbt\\\")(relation)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_show_grant_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7982059, \"supported_languages\": null}, \"macro.dbt.default__get_show_grant_sql\": {\"name\": \"default__get_show_grant_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.default__get_show_grant_sql\", \"macro_sql\": \"{% macro default__get_show_grant_sql(relation) %}\\n    show grants on {{ relation }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.798379, \"supported_languages\": null}, \"macro.dbt.get_grant_sql\": {\"name\": \"get_grant_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.get_grant_sql\", \"macro_sql\": \"{% macro get_grant_sql(relation, privilege, grantees) %}\\n    {{ return(adapter.dispatch('get_grant_sql', 'dbt')(relation, privilege, grantees)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_grant_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7987661, \"supported_languages\": null}, \"macro.dbt.default__get_grant_sql\": {\"name\": \"default__get_grant_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.default__get_grant_sql\", \"macro_sql\": \"\\n\\n{%- macro default__get_grant_sql(relation, privilege, grantees) -%}\\n    grant {{ privilege }} on {{ relation }} to {{ grantees | join(', ') }}\\n{%- endmacro -%}\\n\\n\\n\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.799092, \"supported_languages\": null}, \"macro.dbt.get_revoke_sql\": {\"name\": \"get_revoke_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.get_revoke_sql\", \"macro_sql\": \"{% macro get_revoke_sql(relation, privilege, grantees) %}\\n    {{ return(adapter.dispatch('get_revoke_sql', 'dbt')(relation, privilege, grantees)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_revoke_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.799478, \"supported_languages\": null}, \"macro.dbt.default__get_revoke_sql\": {\"name\": \"default__get_revoke_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.default__get_revoke_sql\", \"macro_sql\": \"\\n\\n{%- macro default__get_revoke_sql(relation, privilege, grantees) -%}\\n    revoke {{ privilege }} on {{ relation }} from {{ grantees | join(', ') }}\\n{%- endmacro -%}\\n\\n\\n\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.7999208, \"supported_languages\": null}, \"macro.dbt.get_dcl_statement_list\": {\"name\": \"get_dcl_statement_list\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.get_dcl_statement_list\", \"macro_sql\": \"{% macro get_dcl_statement_list(relation, grant_config, get_dcl_macro) %}\\n    {{ return(adapter.dispatch('get_dcl_statement_list', 'dbt')(relation, grant_config, get_dcl_macro)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_dcl_statement_list\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.8003159, \"supported_languages\": null}, \"macro.dbt.default__get_dcl_statement_list\": {\"name\": \"default__get_dcl_statement_list\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.default__get_dcl_statement_list\", \"macro_sql\": \"\\n\\n{%- macro default__get_dcl_statement_list(relation, grant_config, get_dcl_macro) -%}\\n    {#\\n      -- Unpack grant_config into specific privileges and the set of users who need them granted/revoked.\\n      -- Depending on whether this database supports multiple grantees per statement, pass in the list of\\n      -- all grantees per privilege, or (if not) template one statement per privilege-grantee pair.\\n      -- `get_dcl_macro` will be either `get_grant_sql` or `get_revoke_sql`\\n    #}\\n    {%- set dcl_statements = [] -%}\\n    {%- for privilege, grantees in grant_config.items() %}\\n        {%- if support_multiple_grantees_per_dcl_statement() and grantees -%}\\n          {%- set dcl = get_dcl_macro(relation, privilege, grantees) -%}\\n          {%- do dcl_statements.append(dcl) -%}\\n        {%- else -%}\\n          {%- for grantee in grantees -%}\\n              {% set dcl = get_dcl_macro(relation, privilege, [grantee]) %}\\n              {%- do dcl_statements.append(dcl) -%}\\n          {% endfor -%}\\n        {%- endif -%}\\n    {%- endfor -%}\\n    {{ return(dcl_statements) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.support_multiple_grantees_per_dcl_statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.80143, \"supported_languages\": null}, \"macro.dbt.call_dcl_statements\": {\"name\": \"call_dcl_statements\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.call_dcl_statements\", \"macro_sql\": \"{% macro call_dcl_statements(dcl_statement_list) %}\\n    {{ return(adapter.dispatch(\\\"call_dcl_statements\\\", \\\"dbt\\\")(dcl_statement_list)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__call_dcl_statements\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.801748, \"supported_languages\": null}, \"macro.dbt.default__call_dcl_statements\": {\"name\": \"default__call_dcl_statements\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.default__call_dcl_statements\", \"macro_sql\": \"{% macro default__call_dcl_statements(dcl_statement_list) %}\\n    {#\\n      -- By default, supply all grant + revoke statements in a single semicolon-separated block,\\n      -- so that they're all processed together.\\n\\n      -- Some databases do not support this. Those adapters will need to override this macro\\n      -- to run each statement individually.\\n    #}\\n    {% call statement('grants') %}\\n        {% for dcl_statement in dcl_statement_list %}\\n            {{ dcl_statement }};\\n        {% endfor %}\\n    {% endcall %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.802148, \"supported_languages\": null}, \"macro.dbt.apply_grants\": {\"name\": \"apply_grants\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.apply_grants\", \"macro_sql\": \"{% macro apply_grants(relation, grant_config, should_revoke) %}\\n    {{ return(adapter.dispatch(\\\"apply_grants\\\", \\\"dbt\\\")(relation, grant_config, should_revoke)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__apply_grants\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.802525, \"supported_languages\": null}, \"macro.dbt.default__apply_grants\": {\"name\": \"default__apply_grants\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.default__apply_grants\", \"macro_sql\": \"{% macro default__apply_grants(relation, grant_config, should_revoke=True) %}\\n    {#-- If grant_config is {} or None, this is a no-op --#}\\n    {% if grant_config %}\\n        {% if should_revoke %}\\n            {#-- We think previous grants may have carried over --#}\\n            {#-- Show current grants and calculate diffs --#}\\n            {% set current_grants_table = run_query(get_show_grant_sql(relation)) %}\\n            {% set current_grants_dict = adapter.standardize_grants_dict(current_grants_table) %}\\n            {% set needs_granting = diff_of_two_dicts(grant_config, current_grants_dict) %}\\n            {% set needs_revoking = diff_of_two_dicts(current_grants_dict, grant_config) %}\\n            {% if not (needs_granting or needs_revoking) %}\\n                {{ log('On ' ~ relation ~': All grants are in place, no revocation or granting needed.')}}\\n            {% endif %}\\n        {% else %}\\n            {#-- We don't think there's any chance of previous grants having carried over. --#}\\n            {#-- Jump straight to granting what the user has configured. --#}\\n            {% set needs_revoking = {} %}\\n            {% set needs_granting = grant_config %}\\n        {% endif %}\\n        {% if needs_granting or needs_revoking %}\\n            {% set revoke_statement_list = get_dcl_statement_list(relation, needs_revoking, get_revoke_sql) %}\\n            {% set grant_statement_list = get_dcl_statement_list(relation, needs_granting, get_grant_sql) %}\\n            {% set dcl_statement_list = revoke_statement_list + grant_statement_list %}\\n            {% if dcl_statement_list %}\\n                {{ call_dcl_statements(dcl_statement_list) }}\\n            {% endif %}\\n        {% endif %}\\n    {% endif %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.run_query\", \"macro.dbt.get_show_grant_sql\", \"macro.dbt.get_dcl_statement_list\", \"macro.dbt.call_dcl_statements\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.804396, \"supported_languages\": null}, \"macro.dbt.get_show_sql\": {\"name\": \"get_show_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/show.sql\", \"original_file_path\": \"macros/adapters/show.sql\", \"unique_id\": \"macro.dbt.get_show_sql\", \"macro_sql\": \"{% macro get_show_sql(compiled_code, sql_header, limit) -%}\\n  {%- if sql_header -%}\\n  {{ sql_header }}\\n  {%- endif -%}\\n  {%- if limit is not none -%}\\n  {{ get_limit_subquery_sql(compiled_code, limit) }}\\n  {%- else -%}\\n  {{ compiled_code }}\\n  {%- endif -%}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_limit_subquery_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.805258, \"supported_languages\": null}, \"macro.dbt.get_limit_subquery_sql\": {\"name\": \"get_limit_subquery_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/show.sql\", \"original_file_path\": \"macros/adapters/show.sql\", \"unique_id\": \"macro.dbt.get_limit_subquery_sql\", \"macro_sql\": \"{% macro get_limit_subquery_sql(sql, limit) %}\\n  {{ adapter.dispatch('get_limit_subquery_sql', 'dbt')(sql, limit) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_limit_subquery_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.805578, \"supported_languages\": null}, \"macro.dbt.default__get_limit_subquery_sql\": {\"name\": \"default__get_limit_subquery_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/show.sql\", \"original_file_path\": \"macros/adapters/show.sql\", \"unique_id\": \"macro.dbt.default__get_limit_subquery_sql\", \"macro_sql\": \"{% macro default__get_limit_subquery_sql(sql, limit) %}\\n    select *\\n    from (\\n        {{ sql }}\\n    ) as model_limit_subq\\n    limit {{ limit }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.805804, \"supported_languages\": null}, \"macro.dbt.alter_column_comment\": {\"name\": \"alter_column_comment\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"unique_id\": \"macro.dbt.alter_column_comment\", \"macro_sql\": \"{% macro alter_column_comment(relation, column_dict) -%}\\n  {{ return(adapter.dispatch('alter_column_comment', 'dbt')(relation, column_dict)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__alter_column_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.80692, \"supported_languages\": null}, \"macro.dbt.default__alter_column_comment\": {\"name\": \"default__alter_column_comment\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"unique_id\": \"macro.dbt.default__alter_column_comment\", \"macro_sql\": \"{% macro default__alter_column_comment(relation, column_dict) -%}\\n  {{ exceptions.raise_not_implemented(\\n    'alter_column_comment macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.8072052, \"supported_languages\": null}, \"macro.dbt.alter_relation_comment\": {\"name\": \"alter_relation_comment\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"unique_id\": \"macro.dbt.alter_relation_comment\", \"macro_sql\": \"{% macro alter_relation_comment(relation, relation_comment) -%}\\n  {{ return(adapter.dispatch('alter_relation_comment', 'dbt')(relation, relation_comment)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__alter_relation_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.80755, \"supported_languages\": null}, \"macro.dbt.default__alter_relation_comment\": {\"name\": \"default__alter_relation_comment\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"unique_id\": \"macro.dbt.default__alter_relation_comment\", \"macro_sql\": \"{% macro default__alter_relation_comment(relation, relation_comment) -%}\\n  {{ exceptions.raise_not_implemented(\\n    'alter_relation_comment macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.807842, \"supported_languages\": null}, \"macro.dbt.persist_docs\": {\"name\": \"persist_docs\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"unique_id\": \"macro.dbt.persist_docs\", \"macro_sql\": \"{% macro persist_docs(relation, model, for_relation=true, for_columns=true) -%}\\n  {{ return(adapter.dispatch('persist_docs', 'dbt')(relation, model, for_relation, for_columns)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__persist_docs\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.8083148, \"supported_languages\": null}, \"macro.dbt.default__persist_docs\": {\"name\": \"default__persist_docs\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"unique_id\": \"macro.dbt.default__persist_docs\", \"macro_sql\": \"{% macro default__persist_docs(relation, model, for_relation, for_columns) -%}\\n  {% if for_relation and config.persist_relation_docs() and model.description %}\\n    {% do run_query(alter_relation_comment(relation, model.description)) %}\\n  {% endif %}\\n\\n  {% if for_columns and config.persist_column_docs() and model.columns %}\\n    {% do run_query(alter_column_comment(relation, model.columns)) %}\\n  {% endif %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.run_query\", \"macro.dbt.alter_relation_comment\", \"macro.dbt.alter_column_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.80914, \"supported_languages\": null}, \"macro.dbt.get_catalog_relations\": {\"name\": \"get_catalog_relations\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.get_catalog_relations\", \"macro_sql\": \"{% macro get_catalog_relations(information_schema, relations) -%}\\n  {{ return(adapter.dispatch('get_catalog_relations', 'dbt')(information_schema, relations)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_catalog_relations\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.813777, \"supported_languages\": null}, \"macro.dbt.default__get_catalog_relations\": {\"name\": \"default__get_catalog_relations\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.default__get_catalog_relations\", \"macro_sql\": \"{% macro default__get_catalog_relations(information_schema, relations) -%}\\n  {% set typename = adapter.type() %}\\n  {% set msg -%}\\n    get_catalog_relations not implemented for {{ typename }}\\n  {%- endset %}\\n\\n  {{ exceptions.raise_compiler_error(msg) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.814204, \"supported_languages\": null}, \"macro.dbt.get_catalog\": {\"name\": \"get_catalog\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.get_catalog\", \"macro_sql\": \"{% macro get_catalog(information_schema, schemas) -%}\\n  {{ return(adapter.dispatch('get_catalog', 'dbt')(information_schema, schemas)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_catalog\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.814544, \"supported_languages\": null}, \"macro.dbt.default__get_catalog\": {\"name\": \"default__get_catalog\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.default__get_catalog\", \"macro_sql\": \"{% macro default__get_catalog(information_schema, schemas) -%}\\n\\n  {% set typename = adapter.type() %}\\n  {% set msg -%}\\n    get_catalog not implemented for {{ typename }}\\n  {%- endset %}\\n\\n  {{ exceptions.raise_compiler_error(msg) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.815083, \"supported_languages\": null}, \"macro.dbt.information_schema_name\": {\"name\": \"information_schema_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.information_schema_name\", \"macro_sql\": \"{% macro information_schema_name(database) %}\\n  {{ return(adapter.dispatch('information_schema_name', 'dbt')(database)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__information_schema_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.815398, \"supported_languages\": null}, \"macro.dbt.default__information_schema_name\": {\"name\": \"default__information_schema_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.default__information_schema_name\", \"macro_sql\": \"{% macro default__information_schema_name(database) -%}\\n  {%- if database -%}\\n    {{ database }}.INFORMATION_SCHEMA\\n  {%- else -%}\\n    INFORMATION_SCHEMA\\n  {%- endif -%}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.8156521, \"supported_languages\": null}, \"macro.dbt.list_schemas\": {\"name\": \"list_schemas\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.list_schemas\", \"macro_sql\": \"{% macro list_schemas(database) -%}\\n  {{ return(adapter.dispatch('list_schemas', 'dbt')(database)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__list_schemas\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.8159559, \"supported_languages\": null}, \"macro.dbt.default__list_schemas\": {\"name\": \"default__list_schemas\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.default__list_schemas\", \"macro_sql\": \"{% macro default__list_schemas(database) -%}\\n  {% set sql %}\\n    select distinct schema_name\\n    from {{ information_schema_name(database) }}.SCHEMATA\\n    where catalog_name ilike '{{ database }}'\\n  {% endset %}\\n  {{ return(run_query(sql)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.information_schema_name\", \"macro.dbt.run_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.816355, \"supported_languages\": null}, \"macro.dbt.check_schema_exists\": {\"name\": \"check_schema_exists\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.check_schema_exists\", \"macro_sql\": \"{% macro check_schema_exists(information_schema, schema) -%}\\n  {{ return(adapter.dispatch('check_schema_exists', 'dbt')(information_schema, schema)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__check_schema_exists\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.816694, \"supported_languages\": null}, \"macro.dbt.default__check_schema_exists\": {\"name\": \"default__check_schema_exists\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.default__check_schema_exists\", \"macro_sql\": \"{% macro default__check_schema_exists(information_schema, schema) -%}\\n  {% set sql -%}\\n        select count(*)\\n        from {{ information_schema.replace(information_schema_view='SCHEMATA') }}\\n        where catalog_name='{{ information_schema.database }}'\\n          and schema_name='{{ schema }}'\\n  {%- endset %}\\n  {{ return(run_query(sql)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.replace\", \"macro.dbt.run_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.817198, \"supported_languages\": null}, \"macro.dbt.list_relations_without_caching\": {\"name\": \"list_relations_without_caching\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.list_relations_without_caching\", \"macro_sql\": \"{% macro list_relations_without_caching(schema_relation) %}\\n  {{ return(adapter.dispatch('list_relations_without_caching', 'dbt')(schema_relation)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__list_relations_without_caching\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.817512, \"supported_languages\": null}, \"macro.dbt.default__list_relations_without_caching\": {\"name\": \"default__list_relations_without_caching\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.default__list_relations_without_caching\", \"macro_sql\": \"{% macro default__list_relations_without_caching(schema_relation) %}\\n  {{ exceptions.raise_not_implemented(\\n    'list_relations_without_caching macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.8177779, \"supported_languages\": null}, \"macro.dbt.get_relations\": {\"name\": \"get_relations\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.get_relations\", \"macro_sql\": \"{% macro get_relations() %}\\n  {{ return(adapter.dispatch('get_relations', 'dbt')()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_relations\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.818053, \"supported_languages\": null}, \"macro.dbt.default__get_relations\": {\"name\": \"default__get_relations\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.default__get_relations\", \"macro_sql\": \"{% macro default__get_relations() %}\\n  {{ exceptions.raise_not_implemented(\\n    'get_relations macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.818312, \"supported_languages\": null}, \"macro.dbt.get_relation_last_modified\": {\"name\": \"get_relation_last_modified\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.get_relation_last_modified\", \"macro_sql\": \"{% macro get_relation_last_modified(information_schema, relations) %}\\n  {{ return(adapter.dispatch('get_relation_last_modified', 'dbt')(information_schema, relations)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_relation_last_modified\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.818652, \"supported_languages\": null}, \"macro.dbt.default__get_relation_last_modified\": {\"name\": \"default__get_relation_last_modified\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.default__get_relation_last_modified\", \"macro_sql\": \"{% macro default__get_relation_last_modified(information_schema, relations) %}\\n  {{ exceptions.raise_not_implemented(\\n    'get_relation_last_modified macro not implemented for adapter ' + adapter.type()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.818933, \"supported_languages\": null}, \"macro.dbt.get_columns_in_relation\": {\"name\": \"get_columns_in_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.get_columns_in_relation\", \"macro_sql\": \"{% macro get_columns_in_relation(relation) -%}\\n  {{ return(adapter.dispatch('get_columns_in_relation', 'dbt')(relation)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_columns_in_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.822517, \"supported_languages\": null}, \"macro.dbt.default__get_columns_in_relation\": {\"name\": \"default__get_columns_in_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.default__get_columns_in_relation\", \"macro_sql\": \"{% macro default__get_columns_in_relation(relation) -%}\\n  {{ exceptions.raise_not_implemented(\\n    'get_columns_in_relation macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.822782, \"supported_languages\": null}, \"macro.dbt.sql_convert_columns_in_relation\": {\"name\": \"sql_convert_columns_in_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.sql_convert_columns_in_relation\", \"macro_sql\": \"{% macro sql_convert_columns_in_relation(table) -%}\\n  {% set columns = [] %}\\n  {% for row in table %}\\n    {% do columns.append(api.Column(*row)) %}\\n  {% endfor %}\\n  {{ return(columns) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.82329, \"supported_languages\": null}, \"macro.dbt.get_empty_subquery_sql\": {\"name\": \"get_empty_subquery_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.get_empty_subquery_sql\", \"macro_sql\": \"{% macro get_empty_subquery_sql(select_sql, select_sql_header=none) -%}\\n  {{ return(adapter.dispatch('get_empty_subquery_sql', 'dbt')(select_sql, select_sql_header)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_empty_subquery_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.823643, \"supported_languages\": null}, \"macro.dbt.default__get_empty_subquery_sql\": {\"name\": \"default__get_empty_subquery_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.default__get_empty_subquery_sql\", \"macro_sql\": \"{% macro default__get_empty_subquery_sql(select_sql, select_sql_header=none) %}\\n    {%- if select_sql_header is not none -%}\\n    {{ select_sql_header }}\\n    {%- endif -%}\\n    select * from (\\n        {{ select_sql }}\\n    ) as __dbt_sbq\\n    where false\\n    limit 0\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.823992, \"supported_languages\": null}, \"macro.dbt.get_empty_schema_sql\": {\"name\": \"get_empty_schema_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.get_empty_schema_sql\", \"macro_sql\": \"{% macro get_empty_schema_sql(columns) -%}\\n  {{ return(adapter.dispatch('get_empty_schema_sql', 'dbt')(columns)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_empty_schema_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.824285, \"supported_languages\": null}, \"macro.dbt.default__get_empty_schema_sql\": {\"name\": \"default__get_empty_schema_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.default__get_empty_schema_sql\", \"macro_sql\": \"{% macro default__get_empty_schema_sql(columns) %}\\n    {%- set col_err = [] -%}\\n    {%- set col_naked_numeric = [] -%}\\n    select\\n    {% for i in columns %}\\n      {%- set col = columns[i] -%}\\n      {%- if col['data_type'] is not defined -%}\\n        {%- do col_err.append(col['name']) -%}\\n      {#-- If this column's type is just 'numeric' then it is missing precision/scale, raise a warning --#}\\n      {%- elif col['data_type'].strip().lower() in ('numeric', 'decimal', 'number') -%}\\n        {%- do col_naked_numeric.append(col['name']) -%}\\n      {%- endif -%}\\n      {% set col_name = adapter.quote(col['name']) if col.get('quote') else col['name'] %}\\n      cast(null as {{ col['data_type'] }}) as {{ col_name }}{{ \\\", \\\" if not loop.last }}\\n    {%- endfor -%}\\n    {%- if (col_err | length) > 0 -%}\\n      {{ exceptions.column_type_missing(column_names=col_err) }}\\n    {%- elif (col_naked_numeric | length) > 0 -%}\\n      {{ exceptions.warn(\\\"Detected columns with numeric type and unspecified precision/scale, this can lead to unintended rounding: \\\" ~ col_naked_numeric ~ \\\"`\\\") }}\\n    {%- endif -%}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.8263, \"supported_languages\": null}, \"macro.dbt.get_column_schema_from_query\": {\"name\": \"get_column_schema_from_query\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.get_column_schema_from_query\", \"macro_sql\": \"{% macro get_column_schema_from_query(select_sql, select_sql_header=none) -%}\\n    {% set columns = [] %}\\n    {# -- Using an 'empty subquery' here to get the same schema as the given select_sql statement, without necessitating a data scan.#}\\n    {% set sql = get_empty_subquery_sql(select_sql, select_sql_header) %}\\n    {% set column_schema = adapter.get_column_schema_from_query(sql) %}\\n    {{ return(column_schema) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_empty_subquery_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.826881, \"supported_languages\": null}, \"macro.dbt.get_columns_in_query\": {\"name\": \"get_columns_in_query\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.get_columns_in_query\", \"macro_sql\": \"{% macro get_columns_in_query(select_sql) -%}\\n  {{ return(adapter.dispatch('get_columns_in_query', 'dbt')(select_sql)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_columns_in_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.8271859, \"supported_languages\": null}, \"macro.dbt.default__get_columns_in_query\": {\"name\": \"default__get_columns_in_query\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.default__get_columns_in_query\", \"macro_sql\": \"{% macro default__get_columns_in_query(select_sql) %}\\n    {% call statement('get_columns_in_query', fetch_result=True, auto_begin=False) -%}\\n        {{ get_empty_subquery_sql(select_sql) }}\\n    {% endcall %}\\n    {{ return(load_result('get_columns_in_query').table.columns | map(attribute='name') | list) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\", \"macro.dbt.get_empty_subquery_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.827768, \"supported_languages\": null}, \"macro.dbt.alter_column_type\": {\"name\": \"alter_column_type\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.alter_column_type\", \"macro_sql\": \"{% macro alter_column_type(relation, column_name, new_column_type) -%}\\n  {{ return(adapter.dispatch('alter_column_type', 'dbt')(relation, column_name, new_column_type)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__alter_column_type\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.8281548, \"supported_languages\": null}, \"macro.dbt.default__alter_column_type\": {\"name\": \"default__alter_column_type\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.default__alter_column_type\", \"macro_sql\": \"{% macro default__alter_column_type(relation, column_name, new_column_type) -%}\\n  {#\\n    1. Create a new column (w/ temp name and correct type)\\n    2. Copy data over to it\\n    3. Drop the existing column (cascade!)\\n    4. Rename the new column to existing column\\n  #}\\n  {%- set tmp_column = column_name + \\\"__dbt_alter\\\" -%}\\n\\n  {% call statement('alter_column_type') %}\\n    alter table {{ relation }} add column {{ adapter.quote(tmp_column) }} {{ new_column_type }};\\n    update {{ relation }} set {{ adapter.quote(tmp_column) }} = {{ adapter.quote(column_name) }};\\n    alter table {{ relation }} drop column {{ adapter.quote(column_name) }} cascade;\\n    alter table {{ relation }} rename column {{ adapter.quote(tmp_column) }} to {{ adapter.quote(column_name) }}\\n  {% endcall %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.829144, \"supported_languages\": null}, \"macro.dbt.alter_relation_add_remove_columns\": {\"name\": \"alter_relation_add_remove_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.alter_relation_add_remove_columns\", \"macro_sql\": \"{% macro alter_relation_add_remove_columns(relation, add_columns = none, remove_columns = none) -%}\\n  {{ return(adapter.dispatch('alter_relation_add_remove_columns', 'dbt')(relation, add_columns, remove_columns)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__alter_relation_add_remove_columns\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.8295648, \"supported_languages\": null}, \"macro.dbt.default__alter_relation_add_remove_columns\": {\"name\": \"default__alter_relation_add_remove_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.default__alter_relation_add_remove_columns\", \"macro_sql\": \"{% macro default__alter_relation_add_remove_columns(relation, add_columns, remove_columns) %}\\n\\n  {% if add_columns is none %}\\n    {% set add_columns = [] %}\\n  {% endif %}\\n  {% if remove_columns is none %}\\n    {% set remove_columns = [] %}\\n  {% endif %}\\n\\n  {% set sql -%}\\n\\n     alter {{ relation.type }} {{ relation }}\\n\\n            {% for column in add_columns %}\\n               add column {{ column.name }} {{ column.data_type }}{{ ',' if not loop.last }}\\n            {% endfor %}{{ ',' if add_columns and remove_columns }}\\n\\n            {% for column in remove_columns %}\\n                drop column {{ column.name }}{{ ',' if not loop.last }}\\n            {% endfor %}\\n\\n  {%- endset -%}\\n\\n  {% do run_query(sql) %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.run_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.8308558, \"supported_languages\": null}, \"macro.dbt.resolve_model_name\": {\"name\": \"resolve_model_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/python_model/python.sql\", \"original_file_path\": \"macros/python_model/python.sql\", \"unique_id\": \"macro.dbt.resolve_model_name\", \"macro_sql\": \"{% macro resolve_model_name(input_model_name) %}\\n    {{ return(adapter.dispatch('resolve_model_name', 'dbt')(input_model_name)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__resolve_model_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.833535, \"supported_languages\": null}, \"macro.dbt.default__resolve_model_name\": {\"name\": \"default__resolve_model_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/python_model/python.sql\", \"original_file_path\": \"macros/python_model/python.sql\", \"unique_id\": \"macro.dbt.default__resolve_model_name\", \"macro_sql\": \"\\n\\n{%- macro default__resolve_model_name(input_model_name) -%}\\n    {{  input_model_name | string | replace('\\\"', '\\\\\\\"') }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.833805, \"supported_languages\": null}, \"macro.dbt.build_ref_function\": {\"name\": \"build_ref_function\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/python_model/python.sql\", \"original_file_path\": \"macros/python_model/python.sql\", \"unique_id\": \"macro.dbt.build_ref_function\", \"macro_sql\": \"{% macro build_ref_function(model) %}\\n\\n    {%- set ref_dict = {} -%}\\n    {%- for _ref in model.refs -%}\\n        {% set _ref_args = [_ref.get('package'), _ref['name']] if _ref.get('package') else [_ref['name'],] %}\\n        {%- set resolved = ref(*_ref_args, v=_ref.get('version')) -%}\\n        {%- if _ref.get('version') -%}\\n            {% do _ref_args.extend([\\\"v\\\" ~ _ref['version']]) %}\\n        {%- endif -%}\\n       {%- do ref_dict.update({_ref_args | join('.'): resolve_model_name(resolved)}) -%}\\n    {%- endfor -%}\\n\\ndef ref(*args, **kwargs):\\n    refs = {{ ref_dict | tojson }}\\n    key = '.'.join(args)\\n    version = kwargs.get(\\\"v\\\") or kwargs.get(\\\"version\\\")\\n    if version:\\n        key += f\\\".v{version}\\\"\\n    dbt_load_df_function = kwargs.get(\\\"dbt_load_df_function\\\")\\n    return dbt_load_df_function(refs[key])\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.resolve_model_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.835222, \"supported_languages\": null}, \"macro.dbt.build_source_function\": {\"name\": \"build_source_function\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/python_model/python.sql\", \"original_file_path\": \"macros/python_model/python.sql\", \"unique_id\": \"macro.dbt.build_source_function\", \"macro_sql\": \"{% macro build_source_function(model) %}\\n\\n    {%- set source_dict = {} -%}\\n    {%- for _source in model.sources -%}\\n        {%- set resolved = source(*_source) -%}\\n        {%- do source_dict.update({_source | join('.'): resolve_model_name(resolved)}) -%}\\n    {%- endfor -%}\\n\\ndef source(*args, dbt_load_df_function):\\n    sources = {{ source_dict | tojson }}\\n    key = '.'.join(args)\\n    return dbt_load_df_function(sources[key])\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.resolve_model_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.835905, \"supported_languages\": null}, \"macro.dbt.build_config_dict\": {\"name\": \"build_config_dict\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/python_model/python.sql\", \"original_file_path\": \"macros/python_model/python.sql\", \"unique_id\": \"macro.dbt.build_config_dict\", \"macro_sql\": \"{% macro build_config_dict(model) %}\\n    {%- set config_dict = {} -%}\\n    {% set config_dbt_used = zip(model.config.config_keys_used, model.config.config_keys_defaults) | list %}\\n    {%- for key, default in config_dbt_used -%}\\n        {# weird type testing with enum, would be much easier to write this logic in Python! #}\\n        {%- if key == \\\"language\\\" -%}\\n          {%- set value = \\\"python\\\" -%}\\n        {%- endif -%}\\n        {%- set value = model.config.get(key, default) -%}\\n        {%- do config_dict.update({key: value}) -%}\\n    {%- endfor -%}\\nconfig_dict = {{ config_dict }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.836863, \"supported_languages\": null}, \"macro.dbt.py_script_postfix\": {\"name\": \"py_script_postfix\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/python_model/python.sql\", \"original_file_path\": \"macros/python_model/python.sql\", \"unique_id\": \"macro.dbt.py_script_postfix\", \"macro_sql\": \"{% macro py_script_postfix(model) %}\\n# This part is user provided model code\\n# you will need to copy the next section to run the code\\n# COMMAND ----------\\n# this part is dbt logic for get ref work, do not modify\\n\\n{{ build_ref_function(model ) }}\\n{{ build_source_function(model ) }}\\n{{ build_config_dict(model) }}\\n\\nclass config:\\n    def __init__(self, *args, **kwargs):\\n        pass\\n\\n    @staticmethod\\n    def get(key, default=None):\\n        return config_dict.get(key, default)\\n\\nclass this:\\n    \\\"\\\"\\\"dbt.this() or dbt.this.identifier\\\"\\\"\\\"\\n    database = \\\"{{ this.database }}\\\"\\n    schema = \\\"{{ this.schema }}\\\"\\n    identifier = \\\"{{ this.identifier }}\\\"\\n    {% set this_relation_name = resolve_model_name(this) %}\\n    def __repr__(self):\\n        return '{{ this_relation_name  }}'\\n\\n\\nclass dbtObj:\\n    def __init__(self, load_df_function) -> None:\\n        self.source = lambda *args: source(*args, dbt_load_df_function=load_df_function)\\n        self.ref = lambda *args, **kwargs: ref(*args, **kwargs, dbt_load_df_function=load_df_function)\\n        self.config = config\\n        self.this = this()\\n        self.is_incremental = {{ is_incremental() }}\\n\\n# COMMAND ----------\\n{{py_script_comment()}}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.build_ref_function\", \"macro.dbt.build_source_function\", \"macro.dbt.build_config_dict\", \"macro.dbt.resolve_model_name\", \"macro.dbt.is_incremental\", \"macro.dbt.py_script_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.8376498, \"supported_languages\": null}, \"macro.dbt.py_script_comment\": {\"name\": \"py_script_comment\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/python_model/python.sql\", \"original_file_path\": \"macros/python_model/python.sql\", \"unique_id\": \"macro.dbt.py_script_comment\", \"macro_sql\": \"{%macro py_script_comment()%}\\n{%endmacro%}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.837773, \"supported_languages\": null}, \"macro.dbt.test_unique\": {\"name\": \"test_unique\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"tests/generic/builtin.sql\", \"original_file_path\": \"tests/generic/builtin.sql\", \"unique_id\": \"macro.dbt.test_unique\", \"macro_sql\": \"{% test unique(model, column_name) %}\\n    {% set macro = adapter.dispatch('test_unique', 'dbt') %}\\n    {{ macro(model, column_name) }}\\n{% endtest %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__test_unique\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.838603, \"supported_languages\": null}, \"macro.dbt.test_not_null\": {\"name\": \"test_not_null\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"tests/generic/builtin.sql\", \"original_file_path\": \"tests/generic/builtin.sql\", \"unique_id\": \"macro.dbt.test_not_null\", \"macro_sql\": \"{% test not_null(model, column_name) %}\\n    {% set macro = adapter.dispatch('test_not_null', 'dbt') %}\\n    {{ macro(model, column_name) }}\\n{% endtest %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__test_not_null\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.8389928, \"supported_languages\": null}, \"macro.dbt.test_accepted_values\": {\"name\": \"test_accepted_values\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"tests/generic/builtin.sql\", \"original_file_path\": \"tests/generic/builtin.sql\", \"unique_id\": \"macro.dbt.test_accepted_values\", \"macro_sql\": \"{% test accepted_values(model, column_name, values, quote=True) %}\\n    {% set macro = adapter.dispatch('test_accepted_values', 'dbt') %}\\n    {{ macro(model, column_name, values, quote) }}\\n{% endtest %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__test_accepted_values\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.839478, \"supported_languages\": null}, \"macro.dbt.test_relationships\": {\"name\": \"test_relationships\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"tests/generic/builtin.sql\", \"original_file_path\": \"tests/generic/builtin.sql\", \"unique_id\": \"macro.dbt.test_relationships\", \"macro_sql\": \"{% test relationships(model, column_name, to, field) %}\\n    {% set macro = adapter.dispatch('test_relationships', 'dbt') %}\\n    {{ macro(model, column_name, to, field) }}\\n{% endtest %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__test_relationships\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1706614034.839941, \"supported_languages\": null}}, \"docs\": {\"doc.test.somedoc\": {\"name\": \"somedoc\", \"resource_type\": \"doc\", \"package_name\": \"test\", \"path\": \"somedoc.md\", \"original_file_path\": \"models/somedoc.md\", \"unique_id\": \"doc.test.somedoc\", \"block_contents\": \"Testing, testing\"}, \"doc.dbt.__overview__\": {\"name\": \"__overview__\", \"resource_type\": \"doc\", \"package_name\": \"dbt\", \"path\": \"overview.md\", \"original_file_path\": \"docs/overview.md\", \"unique_id\": \"doc.dbt.__overview__\", \"block_contents\": \"### Welcome!\\n\\nWelcome to the auto-generated documentation for your dbt project!\\n\\n### Navigation\\n\\nYou can use the `Project` and `Database` navigation tabs on the left side of the window to explore the models\\nin your project.\\n\\n#### Project Tab\\nThe `Project` tab mirrors the directory structure of your dbt project. In this tab, you can see all of the\\nmodels defined in your dbt project, as well as models imported from dbt packages.\\n\\n#### Database Tab\\nThe `Database` tab also exposes your models, but in a format that looks more like a database explorer. This view\\nshows relations (tables and views) grouped into database schemas. Note that ephemeral models are _not_ shown\\nin this interface, as they do not exist in the database.\\n\\n### Graph Exploration\\nYou can click the blue icon on the bottom-right corner of the page to view the lineage graph of your models.\\n\\nOn model pages, you'll see the immediate parents and children of the model you're exploring. By clicking the `Expand`\\nbutton at the top-right of this lineage pane, you'll be able to see all of the models that are used to build,\\nor are built from, the model you're exploring.\\n\\nOnce expanded, you'll be able to use the `--select` and `--exclude` model selection syntax to filter the\\nmodels in the graph. For more information on model selection, check out the [dbt docs](https://docs.getdbt.com/docs/model-selection-syntax).\\n\\nNote that you can also right-click on models to interactively filter and explore the graph.\\n\\n---\\n\\n### More information\\n\\n- [What is dbt](https://docs.getdbt.com/docs/introduction)?\\n- Read the [dbt viewpoint](https://docs.getdbt.com/docs/viewpoint)\\n- [Installation](https://docs.getdbt.com/docs/installation)\\n- Join the [dbt Community](https://www.getdbt.com/community/) for questions and discussion\"}}, \"exposures\": {\"exposure.test.simple_exposure\": {\"name\": \"simple_exposure\", \"resource_type\": \"exposure\", \"package_name\": \"test\", \"path\": \"schema.yml\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"exposure.test.simple_exposure\", \"fqn\": [\"test\", \"simple_exposure\"], \"type\": \"dashboard\", \"owner\": {\"email\": \"something@example.com\", \"name\": null}, \"description\": \"\", \"label\": null, \"maturity\": null, \"meta\": {}, \"tags\": [], \"config\": {\"enabled\": true}, \"unrendered_config\": {}, \"url\": null, \"depends_on\": {\"macros\": [], \"nodes\": [\"source.test.my_source.my_table\", \"model.test.my_model\"]}, \"refs\": [{\"name\": \"my_model\", \"package\": null, \"version\": null}], \"sources\": [[\"my_source\", \"my_table\"]], \"metrics\": [], \"created_at\": 1706614035.762317}}, \"metrics\": {\"metric.test.blue_customers_post_2010\": {\"name\": \"blue_customers_post_2010\", \"resource_type\": \"metric\", \"package_name\": \"test\", \"path\": \"schema.yml\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"metric.test.blue_customers_post_2010\", \"fqn\": [\"test\", \"blue_customers_post_2010\"], \"description\": \"\", \"label\": \"Blue Customers since 2010\", \"type\": \"simple\", \"type_params\": {\"measure\": {\"name\": \"customers\", \"filter\": {\"where_filters\": [{\"where_sql_template\": \"{{ Dimension('id__favorite_color') }} = 'blue'\"}]}, \"alias\": null, \"join_to_timespine\": false, \"fill_nulls_with\": null}, \"input_measures\": [{\"name\": \"customers\", \"filter\": {\"where_filters\": [{\"where_sql_template\": \"{{ Dimension('id__favorite_color') }} = 'blue'\"}]}, \"alias\": null, \"join_to_timespine\": false, \"fill_nulls_with\": null}], \"numerator\": null, \"denominator\": null, \"expr\": null, \"window\": null, \"grain_to_date\": null, \"metrics\": [], \"conversion_type_params\": null}, \"filter\": {\"where_filters\": [{\"where_sql_template\": \"{{ TimeDimension('id__created_at', 'day') }} > '2010-01-01'\"}]}, \"metadata\": null, \"meta\": {}, \"tags\": [], \"config\": {\"enabled\": true, \"group\": null}, \"unrendered_config\": {}, \"sources\": [], \"depends_on\": {\"macros\": [], \"nodes\": [\"semantic_model.test.semantic_people\"]}, \"refs\": [], \"metrics\": [], \"created_at\": 1706614035.8904068, \"group\": null}, \"metric.test.customers\": {\"name\": \"customers\", \"resource_type\": \"metric\", \"package_name\": \"test\", \"path\": \"schema.yml\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"metric.test.customers\", \"fqn\": [\"test\", \"customers\"], \"description\": \"\", \"label\": \"Customers Metric\", \"type\": \"simple\", \"type_params\": {\"measure\": {\"name\": \"customers\", \"filter\": null, \"alias\": null, \"join_to_timespine\": false, \"fill_nulls_with\": null}, \"input_measures\": [{\"name\": \"customers\", \"filter\": null, \"alias\": null, \"join_to_timespine\": false, \"fill_nulls_with\": null}], \"numerator\": null, \"denominator\": null, \"expr\": null, \"window\": null, \"grain_to_date\": null, \"metrics\": [], \"conversion_type_params\": null}, \"filter\": null, \"metadata\": null, \"meta\": {}, \"tags\": [], \"config\": {\"enabled\": true, \"group\": null}, \"unrendered_config\": {}, \"sources\": [], \"depends_on\": {\"macros\": [], \"nodes\": [\"semantic_model.test.semantic_people\"]}, \"refs\": [], \"metrics\": [], \"created_at\": 1706614035.891094, \"group\": null}, \"metric.test.ratio_of_blue_customers_to_red_customers\": {\"name\": \"ratio_of_blue_customers_to_red_customers\", \"resource_type\": \"metric\", \"package_name\": \"test\", \"path\": \"schema.yml\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"metric.test.ratio_of_blue_customers_to_red_customers\", \"fqn\": [\"test\", \"ratio_of_blue_customers_to_red_customers\"], \"description\": \"\", \"label\": \"Very Important Customer Color Ratio\", \"type\": \"ratio\", \"type_params\": {\"measure\": null, \"input_measures\": [{\"name\": \"customers\", \"filter\": null, \"alias\": null, \"join_to_timespine\": false, \"fill_nulls_with\": null}, {\"name\": \"customers\", \"filter\": null, \"alias\": null, \"join_to_timespine\": false, \"fill_nulls_with\": null}], \"numerator\": {\"name\": \"customers\", \"filter\": {\"where_filters\": [{\"where_sql_template\": \"{{ Dimension('id__favorite_color')}} = 'blue'\"}]}, \"alias\": null, \"offset_window\": null, \"offset_to_grain\": null}, \"denominator\": {\"name\": \"customers\", \"filter\": {\"where_filters\": [{\"where_sql_template\": \"{{ Dimension('id__favorite_color')}} = 'red'\"}]}, \"alias\": null, \"offset_window\": null, \"offset_to_grain\": null}, \"expr\": null, \"window\": null, \"grain_to_date\": null, \"metrics\": [], \"conversion_type_params\": null}, \"filter\": null, \"metadata\": null, \"meta\": {}, \"tags\": [], \"config\": {\"enabled\": true, \"group\": null}, \"unrendered_config\": {}, \"sources\": [], \"depends_on\": {\"macros\": [], \"nodes\": [\"metric.test.customers\"]}, \"refs\": [], \"metrics\": [], \"created_at\": 1706614035.892986, \"group\": null}, \"metric.test.doubled_blue_customers\": {\"name\": \"doubled_blue_customers\", \"resource_type\": \"metric\", \"package_name\": \"test\", \"path\": \"schema.yml\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"metric.test.doubled_blue_customers\", \"fqn\": [\"test\", \"doubled_blue_customers\"], \"description\": \"\", \"label\": \"Inflated blue customer numbers\", \"type\": \"derived\", \"type_params\": {\"measure\": null, \"input_measures\": [{\"name\": \"customers\", \"filter\": null, \"alias\": null, \"join_to_timespine\": false, \"fill_nulls_with\": null}], \"numerator\": null, \"denominator\": null, \"expr\": \"customers * 2\", \"window\": null, \"grain_to_date\": null, \"metrics\": [{\"name\": \"customers\", \"filter\": {\"where_filters\": [{\"where_sql_template\": \"{{ Dimension('id__favorite_color')}} = 'blue'\"}]}, \"alias\": null, \"offset_window\": null, \"offset_to_grain\": null}], \"conversion_type_params\": null}, \"filter\": null, \"metadata\": null, \"meta\": {}, \"tags\": [], \"config\": {\"enabled\": true, \"group\": null}, \"unrendered_config\": {}, \"sources\": [], \"depends_on\": {\"macros\": [], \"nodes\": [\"metric.test.customers\"]}, \"refs\": [], \"metrics\": [], \"created_at\": 1706614035.894361, \"group\": null}}, \"groups\": {}, \"selectors\": {}, \"disabled\": {\"model.test.disabled_model\": [{\"database\": \"dbt\", \"schema\": \"test17066140326720908695_test_previous_version_state\", \"name\": \"disabled_model\", \"resource_type\": \"model\", \"package_name\": \"test\", \"path\": \"disabled_model.sql\", \"original_file_path\": \"models/disabled_model.sql\", \"unique_id\": \"model.test.disabled_model\", \"fqn\": [\"test\", \"disabled_model\"], \"alias\": \"disabled_model\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"597106d23ce34e3cd2430588e5c1cf474ebdd138fc47e09b925a4ab258a27acc\"}, \"config\": {\"enabled\": false, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"view\", \"incremental_strategy\": null, \"persist_docs\": {}, \"post-hook\": [], \"pre-hook\": [], \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": null, \"on_schema_change\": \"ignore\", \"on_configuration_change\": \"apply\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"contract\": {\"enforced\": false, \"alias_types\": true}, \"access\": \"protected\"}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {\"enabled\": false}, \"created_at\": 1706614035.24477, \"config_call_dict\": {\"enabled\": false}, \"relation_name\": \"\\\"dbt\\\".\\\"test17066140326720908695_test_previous_version_state\\\".\\\"disabled_model\\\"\", \"raw_code\": \"{{ config(enabled=False) }}\\nselect 2 as id\", \"language\": \"sql\", \"refs\": [], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [], \"nodes\": []}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"alias_types\": true, \"checksum\": null}, \"access\": \"protected\", \"constraints\": [], \"version\": null, \"latest_version\": null, \"deprecation_date\": null, \"defer_relation\": null}], \"snapshot.test.disabled_snapshot_seed\": [{\"database\": \"dbt\", \"schema\": \"test17066140326720908695_test_previous_version_state\", \"name\": \"disabled_snapshot_seed\", \"resource_type\": \"snapshot\", \"package_name\": \"test\", \"path\": \"disabled_snapshot_seed.sql\", \"original_file_path\": \"snapshots/disabled_snapshot_seed.sql\", \"unique_id\": \"snapshot.test.disabled_snapshot_seed\", \"fqn\": [\"test\", \"disabled_snapshot_seed\", \"disabled_snapshot_seed\"], \"alias\": \"disabled_snapshot_seed\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"fe76c9dd437341c9e82a0f2a8baf3148f961b768eaa0a4410cd27d3c071bd617\"}, \"config\": {\"enabled\": false, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"snapshot\", \"incremental_strategy\": null, \"persist_docs\": {}, \"post-hook\": [], \"pre-hook\": [], \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": \"id\", \"on_schema_change\": \"ignore\", \"on_configuration_change\": \"apply\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"contract\": {\"enforced\": false, \"alias_types\": true}, \"strategy\": \"check\", \"target_schema\": \"test17066140326720908695_test_previous_version_state\", \"target_database\": null, \"updated_at\": null, \"check_cols\": \"all\"}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {\"unique_key\": \"id\", \"strategy\": \"check\", \"check_cols\": \"all\", \"target_schema\": \"test17066140326720908695_test_previous_version_state\", \"enabled\": false}, \"created_at\": 1706614035.3636532, \"config_call_dict\": {\"unique_key\": \"id\", \"strategy\": \"check\", \"check_cols\": \"all\", \"target_schema\": \"test17066140326720908695_test_previous_version_state\", \"enabled\": false}, \"relation_name\": \"\\\"dbt\\\".\\\"test17066140326720908695_test_previous_version_state\\\".\\\"disabled_snapshot_seed\\\"\", \"raw_code\": \"\\n{{\\n    config(\\n      unique_key='id',\\n      strategy='check',\\n      check_cols='all',\\n      target_schema=schema,\\n      enabled=False,\\n    )\\n}}\\nselect * from {{ ref('my_seed') }}\\n\", \"language\": \"sql\", \"refs\": [{\"name\": \"my_seed\", \"package\": null, \"version\": null}], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [], \"nodes\": []}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"alias_types\": true, \"checksum\": null}, \"defer_relation\": null}], \"analysis.test.disabled_al\": [{\"database\": \"dbt\", \"schema\": \"test17066140326720908695_test_previous_version_state\", \"name\": \"disabled_al\", \"resource_type\": \"analysis\", \"package_name\": \"test\", \"path\": \"analysis/disabled_al.sql\", \"original_file_path\": \"analyses/disabled_al.sql\", \"unique_id\": \"analysis.test.disabled_al\", \"fqn\": [\"test\", \"analysis\", \"disabled_al\"], \"alias\": \"disabled_al\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"32d36ad6cff0786eb562440ba60ef6c9b9a7f4c282dfb7a52eaf19d36370f0e1\"}, \"config\": {\"enabled\": false, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"view\", \"incremental_strategy\": null, \"persist_docs\": {}, \"post-hook\": [], \"pre-hook\": [], \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": null, \"on_schema_change\": \"ignore\", \"on_configuration_change\": \"apply\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"contract\": {\"enforced\": false, \"alias_types\": true}}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {\"enabled\": false}, \"created_at\": 1706614035.422348, \"config_call_dict\": {\"enabled\": false}, \"relation_name\": null, \"raw_code\": \"{{ config(enabled=False) }}\\nselect 9 as id\", \"language\": \"sql\", \"refs\": [], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [], \"nodes\": []}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"alias_types\": true, \"checksum\": null}}], \"test.test.disabled_just_my\": [{\"database\": \"dbt\", \"schema\": \"test17066140326720908695_test_previous_version_state_dbt_test__audit\", \"name\": \"disabled_just_my\", \"resource_type\": \"test\", \"package_name\": \"test\", \"path\": \"disabled_just_my.sql\", \"original_file_path\": \"tests/disabled_just_my.sql\", \"unique_id\": \"test.test.disabled_just_my\", \"fqn\": [\"test\", \"disabled_just_my\"], \"alias\": \"disabled_just_my\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"4f2268fd89a3b4ef899264ada6d7aa33603671cbc5d5acead7dc2eadf1add985\"}, \"config\": {\"enabled\": false, \"alias\": null, \"schema\": \"dbt_test__audit\", \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"test\", \"severity\": \"ERROR\", \"store_failures\": null, \"store_failures_as\": null, \"where\": null, \"limit\": null, \"fail_calc\": \"count(*)\", \"warn_if\": \"!= 0\", \"error_if\": \"!= 0\"}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {\"enabled\": false}, \"created_at\": 1706614035.489865, \"config_call_dict\": {\"enabled\": false}, \"relation_name\": null, \"raw_code\": \"{{ config(enabled=False) }}\\n\\nselect * from {{ ref('my_model') }}\\nwhere false\", \"language\": \"sql\", \"refs\": [{\"name\": \"my_model\", \"package\": null, \"version\": null}], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [], \"nodes\": []}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"alias_types\": true, \"checksum\": null}}], \"test.test.disabled_check_nothing_my_model_.f2c6a72d37\": [{\"test_metadata\": {\"name\": \"disabled_check_nothing\", \"kwargs\": {\"model\": \"{{ get_where_subquery(ref('my_model')) }}\"}, \"namespace\": null}, \"database\": \"dbt\", \"schema\": \"test17066140326720908695_test_previous_version_state_dbt_test__audit\", \"name\": \"disabled_check_nothing_my_model_\", \"resource_type\": \"test\", \"package_name\": \"test\", \"path\": \"disabled_check_nothing_my_model_.sql\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"test.test.disabled_check_nothing_my_model_.f2c6a72d37\", \"fqn\": [\"test\", \"disabled_check_nothing_my_model_\"], \"alias\": \"disabled_check_nothing_my_model_\", \"checksum\": {\"name\": \"none\", \"checksum\": \"\"}, \"config\": {\"enabled\": false, \"alias\": null, \"schema\": \"dbt_test__audit\", \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"test\", \"severity\": \"ERROR\", \"store_failures\": null, \"store_failures_as\": null, \"where\": null, \"limit\": null, \"fail_calc\": \"count(*)\", \"warn_if\": \"!= 0\", \"error_if\": \"!= 0\"}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {\"enabled\": false}, \"created_at\": 1706614035.6771069, \"config_call_dict\": {\"enabled\": false}, \"relation_name\": null, \"raw_code\": \"{{ test_disabled_check_nothing(**_dbt_generic_test_kwargs) }}\", \"language\": \"sql\", \"refs\": [{\"name\": \"my_model\", \"package\": null, \"version\": null}], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [\"macro.test.test_disabled_check_nothing\", \"macro.dbt.get_where_subquery\"], \"nodes\": []}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"alias_types\": true, \"checksum\": null}, \"column_name\": null, \"file_key_name\": \"models.my_model\", \"attached_node\": \"model.test.my_model\"}], \"exposure.test.disabled_exposure\": [{\"name\": \"disabled_exposure\", \"resource_type\": \"exposure\", \"package_name\": \"test\", \"path\": \"schema.yml\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"exposure.test.disabled_exposure\", \"fqn\": [\"test\", \"disabled_exposure\"], \"type\": \"dashboard\", \"owner\": {\"email\": \"something@example.com\", \"name\": null}, \"description\": \"\", \"label\": null, \"maturity\": null, \"meta\": {}, \"tags\": [], \"config\": {\"enabled\": false}, \"unrendered_config\": {\"enabled\": false}, \"url\": null, \"depends_on\": {\"macros\": [], \"nodes\": []}, \"refs\": [{\"name\": \"my_model\", \"package\": null, \"version\": null}], \"sources\": [], \"metrics\": [], \"created_at\": 1706614035.763594}], \"metric.test.disabled_metric\": [{\"name\": \"disabled_metric\", \"resource_type\": \"metric\", \"package_name\": \"test\", \"path\": \"schema.yml\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"metric.test.disabled_metric\", \"fqn\": [\"test\", \"disabled_metric\"], \"description\": \"\", \"label\": \"Count records\", \"type\": \"simple\", \"type_params\": {\"measure\": {\"name\": \"customers\", \"filter\": null, \"alias\": null, \"join_to_timespine\": false, \"fill_nulls_with\": null}, \"input_measures\": [], \"numerator\": null, \"denominator\": null, \"expr\": null, \"window\": null, \"grain_to_date\": null, \"metrics\": [], \"conversion_type_params\": null}, \"filter\": {\"where_filters\": [{\"where_sql_template\": \"{{ Dimension('id__favorite_color') }} = 'blue'\"}]}, \"metadata\": null, \"meta\": {}, \"tags\": [], \"config\": {\"enabled\": false, \"group\": null}, \"unrendered_config\": {\"enabled\": false}, \"sources\": [], \"depends_on\": {\"macros\": [], \"nodes\": []}, \"refs\": [], \"metrics\": [], \"created_at\": 1706614035.891953, \"group\": null}], \"seed.test.disabled_seed\": [{\"database\": \"dbt\", \"schema\": \"test17066140326720908695_test_previous_version_state\", \"name\": \"disabled_seed\", \"resource_type\": \"seed\", \"package_name\": \"test\", \"path\": \"disabled_seed.csv\", \"original_file_path\": \"seeds/disabled_seed.csv\", \"unique_id\": \"seed.test.disabled_seed\", \"fqn\": [\"test\", \"disabled_seed\"], \"alias\": \"disabled_seed\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"31fddd8ec40c6aba6a3a8e7d83fedea2fd0a56c47b64ea3df1847ec1b018e2d1\"}, \"config\": {\"enabled\": false, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"seed\", \"incremental_strategy\": null, \"persist_docs\": {}, \"post-hook\": [], \"pre-hook\": [], \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": null, \"on_schema_change\": \"ignore\", \"on_configuration_change\": \"apply\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"contract\": {\"enforced\": false, \"alias_types\": true}, \"delimiter\": \",\", \"quote_columns\": null}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": \"test://models/schema.yml\", \"build_path\": null, \"deferred\": false, \"unrendered_config\": {\"enabled\": false}, \"created_at\": 1706614035.695063, \"config_call_dict\": {}, \"relation_name\": \"\\\"dbt\\\".\\\"test17066140326720908695_test_previous_version_state\\\".\\\"disabled_seed\\\"\", \"raw_code\": \"\", \"root_path\": \"/private/var/folders/7h/hj5_fw9j291c58hwfdvy5xbm0000gp/T/pytest-of-jerco/pytest-10/project0\", \"depends_on\": {\"macros\": []}, \"defer_relation\": null}], \"source.test.my_source.disabled_table\": [{\"database\": \"dbt\", \"schema\": \"my_source\", \"name\": \"disabled_table\", \"resource_type\": \"source\", \"package_name\": \"test\", \"path\": \"models/schema.yml\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"source.test.my_source.disabled_table\", \"fqn\": [\"test\", \"my_source\", \"disabled_table\"], \"source_name\": \"my_source\", \"source_description\": \"My source\", \"loader\": \"a_loader\", \"identifier\": \"disabled_table\", \"quoting\": {\"database\": null, \"schema\": null, \"identifier\": null, \"column\": null}, \"loaded_at_field\": null, \"freshness\": {\"warn_after\": {\"count\": null, \"period\": null}, \"error_after\": {\"count\": null, \"period\": null}, \"filter\": null}, \"external\": null, \"description\": \"Disabled table\", \"columns\": {}, \"meta\": {}, \"source_meta\": {}, \"tags\": [], \"config\": {\"enabled\": false}, \"patch_path\": null, \"unrendered_config\": {\"enabled\": false}, \"relation_name\": \"\\\"dbt\\\".\\\"my_source\\\".\\\"disabled_table\\\"\", \"created_at\": 1706614035.93874}]}, \"parent_map\": {\"model.test.my_model\": [], \"model.test.metricflow_time_spine\": [], \"snapshot.test.snapshot_seed\": [\"seed.test.my_seed\"], \"analysis.test.a\": [], \"test.test.just_my\": [\"model.test.my_model\"], \"seed.test.my_seed\": [], \"test.test.not_null_my_model_id.43e0e9183a\": [\"model.test.my_model\"], \"test.test.check_nothing_my_model_.d5a5e66110\": [\"model.test.my_model\"], \"source.test.my_source.my_table\": [], \"exposure.test.simple_exposure\": [\"model.test.my_model\", \"source.test.my_source.my_table\"], \"metric.test.blue_customers_post_2010\": [\"semantic_model.test.semantic_people\"], \"metric.test.customers\": [\"semantic_model.test.semantic_people\"], \"metric.test.ratio_of_blue_customers_to_red_customers\": [\"metric.test.customers\"], \"metric.test.doubled_blue_customers\": [\"metric.test.customers\"], \"semantic_model.test.semantic_people\": [\"model.test.my_model\"]}, \"child_map\": {\"model.test.my_model\": [\"exposure.test.simple_exposure\", \"semantic_model.test.semantic_people\", \"test.test.check_nothing_my_model_.d5a5e66110\", \"test.test.just_my\", \"test.test.not_null_my_model_id.43e0e9183a\"], \"model.test.metricflow_time_spine\": [], \"snapshot.test.snapshot_seed\": [], \"analysis.test.a\": [], \"test.test.just_my\": [], \"seed.test.my_seed\": [\"snapshot.test.snapshot_seed\"], \"test.test.not_null_my_model_id.43e0e9183a\": [], \"test.test.check_nothing_my_model_.d5a5e66110\": [], \"source.test.my_source.my_table\": [\"exposure.test.simple_exposure\"], \"exposure.test.simple_exposure\": [], \"metric.test.blue_customers_post_2010\": [], \"metric.test.customers\": [\"metric.test.doubled_blue_customers\", \"metric.test.ratio_of_blue_customers_to_red_customers\"], \"metric.test.ratio_of_blue_customers_to_red_customers\": [], \"metric.test.doubled_blue_customers\": [], \"semantic_model.test.semantic_people\": [\"metric.test.blue_customers_post_2010\", \"metric.test.customers\"]}, \"group_map\": {}, \"saved_queries\": {}, \"semantic_models\": {\"semantic_model.test.semantic_people\": {\"name\": \"semantic_people\", \"resource_type\": \"semantic_model\", \"package_name\": \"test\", \"path\": \"schema.yml\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"semantic_model.test.semantic_people\", \"fqn\": [\"test\", \"semantic_people\"], \"model\": \"ref('my_model')\", \"node_relation\": {\"alias\": \"my_model\", \"schema_name\": \"test17066140326720908695_test_previous_version_state\", \"database\": \"dbt\", \"relation_name\": \"\\\"dbt\\\".\\\"test17066140326720908695_test_previous_version_state\\\".\\\"my_model\\\"\"}, \"description\": null, \"label\": null, \"defaults\": {\"agg_time_dimension\": \"created_at\"}, \"entities\": [{\"name\": \"id\", \"type\": \"primary\", \"description\": null, \"label\": null, \"role\": null, \"expr\": null}], \"measures\": [{\"name\": \"years_tenure\", \"agg\": \"sum\", \"description\": null, \"label\": null, \"create_metric\": false, \"expr\": \"tenure\", \"agg_params\": null, \"non_additive_dimension\": null, \"agg_time_dimension\": null}, {\"name\": \"people\", \"agg\": \"count\", \"description\": null, \"label\": null, \"create_metric\": false, \"expr\": \"id\", \"agg_params\": null, \"non_additive_dimension\": null, \"agg_time_dimension\": null}, {\"name\": \"customers\", \"agg\": \"count\", \"description\": null, \"label\": null, \"create_metric\": false, \"expr\": \"id\", \"agg_params\": null, \"non_additive_dimension\": null, \"agg_time_dimension\": null}], \"dimensions\": [{\"name\": \"favorite_color\", \"type\": \"categorical\", \"description\": null, \"label\": null, \"is_partition\": false, \"type_params\": null, \"expr\": null, \"metadata\": null}, {\"name\": \"created_at\", \"type\": \"time\", \"description\": null, \"label\": null, \"is_partition\": false, \"type_params\": {\"time_granularity\": \"day\", \"validity_params\": null}, \"expr\": null, \"metadata\": null}], \"metadata\": null, \"depends_on\": {\"macros\": [], \"nodes\": [\"model.test.my_model\"]}, \"refs\": [{\"name\": \"my_model\", \"package\": null, \"version\": null}], \"created_at\": 1706614035.935194, \"config\": {\"enabled\": true, \"group\": null, \"meta\": {}}, \"unrendered_config\": {}, \"primary_entity\": null, \"group\": null}}}\n"
  },
  {
    "path": "tests/functional/artifacts/data/state/v12/manifest.json",
    "content": "{\"metadata\": {\"dbt_schema_version\": \"https://schemas.getdbt.com/dbt/manifest/v12.json\", \"dbt_version\": \"1.11.0a1\", \"generated_at\": \"2025-10-02T16:48:38.578317Z\", \"invocation_id\": \"44bddff0-d7eb-4be7-8e0c-f4e1709ae7fe\", \"invocation_started_at\": \"2025-10-02T16:48:35.875974+00:00\", \"env\": {}, \"project_name\": \"test\", \"project_id\": \"098f6bcd4621d373cade4e832627b4f6\", \"user_id\": null, \"send_anonymous_usage_stats\": false, \"adapter_type\": \"postgres\", \"quoting\": {\"database\": true, \"schema\": true, \"identifier\": true, \"column\": null}, \"run_started_at\": \"2025-10-02T16:48:35.876320+00:00\"}, \"nodes\": {\"model.test.my_model\": {\"database\": \"dbt\", \"schema\": \"test17594237163467600387_test_previous_version_state\", \"name\": \"my_model\", \"resource_type\": \"model\", \"package_name\": \"test\", \"path\": \"my_model.sql\", \"original_file_path\": \"models/my_model.sql\", \"unique_id\": \"model.test.my_model\", \"fqn\": [\"test\", \"my_model\"], \"alias\": \"my_model\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"3ea0f972fa1b56aa2dc2f56ee784b6a5796312f9a813d59ae70fd8855f10d16d\"}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"view\", \"incremental_strategy\": null, \"batch_size\": null, \"lookback\": 1, \"begin\": null, \"persist_docs\": {}, \"post-hook\": [], \"pre-hook\": [], \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": null, \"on_schema_change\": \"ignore\", \"on_configuration_change\": \"apply\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"contract\": {\"enforced\": false, \"alias_types\": true}, \"event_time\": null, \"concurrent_batches\": null, \"access\": \"protected\", \"freshness\": null}, \"tags\": [], \"description\": \"Example model\", \"columns\": {\"id\": {\"name\": \"id\", \"description\": \"\", \"meta\": {}, \"data_type\": null, \"constraints\": [], \"quote\": null, \"config\": {\"meta\": {}, \"tags\": []}, \"tags\": [], \"granularity\": null, \"doc_blocks\": []}}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": \"test://models/schema.yml\", \"build_path\": null, \"unrendered_config\": {}, \"created_at\": 1759423716.418234, \"relation_name\": \"\\\"dbt\\\".\\\"test17594237163467600387_test_previous_version_state\\\".\\\"my_model\\\"\", \"raw_code\": \"select 1 as id\", \"doc_blocks\": [], \"language\": \"sql\", \"refs\": [], \"sources\": [], \"metrics\": [], \"functions\": [], \"depends_on\": {\"macros\": [], \"nodes\": []}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"alias_types\": true, \"checksum\": null}, \"access\": \"protected\", \"constraints\": [], \"version\": null, \"latest_version\": null, \"deprecation_date\": null, \"primary_key\": [], \"time_spine\": null}, \"model.test.metricflow_time_spine\": {\"database\": \"dbt\", \"schema\": \"test17594237163467600387_test_previous_version_state\", \"name\": \"metricflow_time_spine\", \"resource_type\": \"model\", \"package_name\": \"test\", \"path\": \"metricflow_time_spine.sql\", \"original_file_path\": \"models/metricflow_time_spine.sql\", \"unique_id\": \"model.test.metricflow_time_spine\", \"fqn\": [\"test\", \"metricflow_time_spine\"], \"alias\": \"metricflow_time_spine\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"954d9b349821edb5558a373119a7d91eeac9e620aaa96cd112c0d14bab729fdb\"}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"view\", \"incremental_strategy\": null, \"batch_size\": null, \"lookback\": 1, \"begin\": null, \"persist_docs\": {}, \"post-hook\": [], \"pre-hook\": [], \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": null, \"on_schema_change\": \"ignore\", \"on_configuration_change\": \"apply\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"contract\": {\"enforced\": false, \"alias_types\": true}, \"event_time\": null, \"concurrent_batches\": null, \"access\": \"protected\", \"freshness\": null}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"unrendered_config\": {}, \"created_at\": 1759423716.101295, \"relation_name\": \"\\\"dbt\\\".\\\"test17594237163467600387_test_previous_version_state\\\".\\\"metricflow_time_spine\\\"\", \"raw_code\": \"SELECT to_date('02/20/2023', 'mm/dd/yyyy') as date_day\", \"doc_blocks\": [], \"language\": \"sql\", \"refs\": [], \"sources\": [], \"metrics\": [], \"functions\": [], \"depends_on\": {\"macros\": [], \"nodes\": []}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"alias_types\": true, \"checksum\": null}, \"access\": \"protected\", \"constraints\": [], \"version\": null, \"latest_version\": null, \"deprecation_date\": null, \"primary_key\": [], \"time_spine\": null}, \"snapshot.test.snapshot_seed\": {\"database\": \"dbt\", \"schema\": \"test17594237163467600387_test_previous_version_state\", \"name\": \"snapshot_seed\", \"resource_type\": \"snapshot\", \"package_name\": \"test\", \"path\": \"snapshot_seed.sql\", \"original_file_path\": \"snapshots/snapshot_seed.sql\", \"unique_id\": \"snapshot.test.snapshot_seed\", \"fqn\": [\"test\", \"snapshot_seed\", \"snapshot_seed\"], \"alias\": \"snapshot_seed\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"5fc998f39655f8fe52443a919e749b6e23883ef90202b040412baac13c6bfe18\"}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"snapshot\", \"incremental_strategy\": null, \"batch_size\": null, \"lookback\": 1, \"begin\": null, \"persist_docs\": {}, \"post-hook\": [], \"pre-hook\": [], \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": \"id\", \"on_schema_change\": \"ignore\", \"on_configuration_change\": \"apply\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"contract\": {\"enforced\": false, \"alias_types\": true}, \"event_time\": null, \"concurrent_batches\": null, \"strategy\": \"check\", \"target_schema\": \"test17594237163467600387_test_previous_version_state\", \"target_database\": null, \"updated_at\": null, \"check_cols\": \"all\", \"snapshot_meta_column_names\": {\"dbt_valid_to\": null, \"dbt_valid_from\": null, \"dbt_scd_id\": null, \"dbt_updated_at\": null, \"dbt_is_deleted\": null}, \"dbt_valid_to_current\": null}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"unrendered_config\": {\"unique_key\": \"id\", \"strategy\": \"check\", \"check_cols\": \"all\", \"target_schema\": \"test17594237163467600387_test_previous_version_state\"}, \"created_at\": 1759423716.114626, \"relation_name\": \"\\\"dbt\\\".\\\"test17594237163467600387_test_previous_version_state\\\".\\\"snapshot_seed\\\"\", \"raw_code\": \"\\n{{\\n    config(\\n      unique_key='id',\\n      strategy='check',\\n      check_cols='all',\\n      target_schema=schema,\\n    )\\n}}\\nselect * from {{ ref('my_seed') }}\\n\", \"doc_blocks\": [], \"language\": \"sql\", \"refs\": [{\"name\": \"my_seed\", \"package\": null, \"version\": null}], \"sources\": [], \"metrics\": [], \"functions\": [], \"depends_on\": {\"macros\": [], \"nodes\": [\"seed.test.my_seed\"]}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"alias_types\": true, \"checksum\": null}}, \"analysis.test.a\": {\"database\": \"dbt\", \"schema\": \"test17594237163467600387_test_previous_version_state\", \"name\": \"a\", \"resource_type\": \"analysis\", \"package_name\": \"test\", \"path\": \"analysis/a.sql\", \"original_file_path\": \"analyses/a.sql\", \"unique_id\": \"analysis.test.a\", \"fqn\": [\"test\", \"analysis\", \"a\"], \"alias\": \"a\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"a389c282f569f0bbdc2a8a4f174dea746c28582fdaf2048d31d9226af9feab23\"}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"view\", \"incremental_strategy\": null, \"batch_size\": null, \"lookback\": 1, \"begin\": null, \"persist_docs\": {}, \"post-hook\": [], \"pre-hook\": [], \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": null, \"on_schema_change\": \"ignore\", \"on_configuration_change\": \"apply\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"contract\": {\"enforced\": false, \"alias_types\": true}, \"event_time\": null, \"concurrent_batches\": null}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"unrendered_config\": {}, \"created_at\": 1759423716.1562681, \"relation_name\": null, \"raw_code\": \"select 4 as id\", \"doc_blocks\": [], \"language\": \"sql\", \"refs\": [], \"sources\": [], \"metrics\": [], \"functions\": [], \"depends_on\": {\"macros\": [], \"nodes\": []}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"alias_types\": true, \"checksum\": null}}, \"test.test.just_my\": {\"database\": \"dbt\", \"schema\": \"test17594237163467600387_test_previous_version_state_dbt_test__audit\", \"name\": \"just_my\", \"resource_type\": \"test\", \"package_name\": \"test\", \"path\": \"just_my.sql\", \"original_file_path\": \"tests/just_my.sql\", \"unique_id\": \"test.test.just_my\", \"fqn\": [\"test\", \"just_my\"], \"alias\": \"just_my\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"744889a2e2d9ce380619265e1217d7ccf6e6ca896c048d42ebe0f9cfb74d7156\"}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": \"dbt_test__audit\", \"database\": null, \"tags\": [\"data_test_tag\"], \"meta\": {}, \"group\": null, \"materialized\": \"test\", \"severity\": \"ERROR\", \"store_failures\": null, \"store_failures_as\": null, \"where\": null, \"limit\": null, \"fail_calc\": \"count(*)\", \"warn_if\": \"!= 0\", \"error_if\": \"!= 0\"}, \"tags\": [\"data_test_tag\"], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"unrendered_config\": {\"tags\": [\"data_test_tag\"]}, \"created_at\": 1759423716.287831, \"relation_name\": null, \"raw_code\": \"{{ config(tags = ['data_test_tag']) }}\\n\\nselect * from {{ ref('my_model') }}\\nwhere false\", \"doc_blocks\": [], \"language\": \"sql\", \"refs\": [{\"name\": \"my_model\", \"package\": null, \"version\": null}], \"sources\": [], \"metrics\": [], \"functions\": [], \"depends_on\": {\"macros\": [], \"nodes\": [\"model.test.my_model\"]}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"alias_types\": true, \"checksum\": null}}, \"seed.test.my_seed\": {\"database\": \"dbt\", \"schema\": \"test17594237163467600387_test_previous_version_state\", \"name\": \"my_seed\", \"resource_type\": \"seed\", \"package_name\": \"test\", \"path\": \"my_seed.csv\", \"original_file_path\": \"seeds/my_seed.csv\", \"unique_id\": \"seed.test.my_seed\", \"fqn\": [\"test\", \"my_seed\"], \"alias\": \"my_seed\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"f7ede83f36165ac6b7a047aa2c3f212dff385bfa9f35f395108cd06fc8e96943\"}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"seed\", \"incremental_strategy\": null, \"batch_size\": null, \"lookback\": 1, \"begin\": null, \"persist_docs\": {}, \"post-hook\": [], \"pre-hook\": [], \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": null, \"on_schema_change\": \"ignore\", \"on_configuration_change\": \"apply\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"contract\": {\"enforced\": false, \"alias_types\": true}, \"event_time\": null, \"concurrent_batches\": null, \"delimiter\": \",\", \"quote_columns\": null}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"unrendered_config\": {}, \"created_at\": 1759423716.320315, \"relation_name\": \"\\\"dbt\\\".\\\"test17594237163467600387_test_previous_version_state\\\".\\\"my_seed\\\"\", \"raw_code\": \"\", \"doc_blocks\": [], \"root_path\": \"/private/var/folders/79/5290gpvn3lx5jdryk4844rm80000gn/T/pytest-of-quigleymalcolm/pytest-154/popen-gw6/project18\", \"depends_on\": {\"macros\": []}}, \"test.test.not_null_my_model_id.43e0e9183a\": {\"database\": \"dbt\", \"schema\": \"test17594237163467600387_test_previous_version_state_dbt_test__audit\", \"name\": \"not_null_my_model_id\", \"resource_type\": \"test\", \"package_name\": \"test\", \"path\": \"not_null_my_model_id.sql\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"test.test.not_null_my_model_id.43e0e9183a\", \"fqn\": [\"test\", \"not_null_my_model_id\"], \"alias\": \"not_null_my_model_id\", \"checksum\": {\"name\": \"none\", \"checksum\": \"\"}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": \"dbt_test__audit\", \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"test\", \"severity\": \"ERROR\", \"store_failures\": null, \"store_failures_as\": null, \"where\": null, \"limit\": null, \"fail_calc\": \"count(*)\", \"warn_if\": \"!= 0\", \"error_if\": \"!= 0\"}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"unrendered_config\": {}, \"created_at\": 1759423716.41968, \"relation_name\": null, \"raw_code\": \"{{ test_not_null(**_dbt_generic_test_kwargs) }}\", \"doc_blocks\": [], \"language\": \"sql\", \"refs\": [{\"name\": \"my_model\", \"package\": null, \"version\": null}], \"sources\": [], \"metrics\": [], \"functions\": [], \"depends_on\": {\"macros\": [\"macro.dbt.test_not_null\"], \"nodes\": [\"model.test.my_model\"]}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"alias_types\": true, \"checksum\": null}, \"column_name\": \"id\", \"file_key_name\": \"models.my_model\", \"attached_node\": \"model.test.my_model\", \"test_metadata\": {\"name\": \"not_null\", \"kwargs\": {\"column_name\": \"id\", \"model\": \"{{ get_where_subquery(ref('my_model')) }}\"}, \"namespace\": null}}, \"test.test.check_nothing_my_model_.d5a5e66110\": {\"database\": \"dbt\", \"schema\": \"test17594237163467600387_test_previous_version_state_dbt_test__audit\", \"name\": \"check_nothing_my_model_\", \"resource_type\": \"test\", \"package_name\": \"test\", \"path\": \"check_nothing_my_model_.sql\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"test.test.check_nothing_my_model_.d5a5e66110\", \"fqn\": [\"test\", \"check_nothing_my_model_\"], \"alias\": \"check_nothing_my_model_\", \"checksum\": {\"name\": \"none\", \"checksum\": \"\"}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": \"dbt_test__audit\", \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"test\", \"severity\": \"ERROR\", \"store_failures\": null, \"store_failures_as\": null, \"where\": null, \"limit\": null, \"fail_calc\": \"count(*)\", \"warn_if\": \"!= 0\", \"error_if\": \"!= 0\"}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"unrendered_config\": {}, \"created_at\": 1759423716.421907, \"relation_name\": null, \"raw_code\": \"{{ test_check_nothing(**_dbt_generic_test_kwargs) }}\", \"doc_blocks\": [], \"language\": \"sql\", \"refs\": [{\"name\": \"my_model\", \"package\": null, \"version\": null}], \"sources\": [], \"metrics\": [], \"functions\": [], \"depends_on\": {\"macros\": [\"macro.test.test_check_nothing\", \"macro.dbt.get_where_subquery\"], \"nodes\": [\"model.test.my_model\"]}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"alias_types\": true, \"checksum\": null}, \"column_name\": null, \"file_key_name\": \"models.my_model\", \"attached_node\": \"model.test.my_model\", \"test_metadata\": {\"name\": \"check_nothing\", \"kwargs\": {\"model\": \"{{ get_where_subquery(ref('my_model')) }}\"}, \"namespace\": null}}}, \"sources\": {\"source.test.my_source.my_table\": {\"database\": \"dbt\", \"schema\": \"my_source\", \"name\": \"my_table\", \"resource_type\": \"source\", \"package_name\": \"test\", \"path\": \"models/schema.yml\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"source.test.my_source.my_table\", \"fqn\": [\"test\", \"my_source\", \"my_table\"], \"source_name\": \"my_source\", \"source_description\": \"My source\", \"loader\": \"a_loader\", \"identifier\": \"my_seed\", \"quoting\": {\"database\": null, \"schema\": null, \"identifier\": null, \"column\": null}, \"loaded_at_field\": null, \"loaded_at_query\": null, \"freshness\": {\"warn_after\": {\"count\": null, \"period\": null}, \"error_after\": {\"count\": null, \"period\": null}, \"filter\": null}, \"external\": null, \"description\": \"My table\", \"columns\": {}, \"meta\": {}, \"source_meta\": {}, \"tags\": [], \"config\": {\"enabled\": true, \"event_time\": null, \"freshness\": {\"warn_after\": {\"count\": null, \"period\": null}, \"error_after\": {\"count\": null, \"period\": null}, \"filter\": null}, \"loaded_at_field\": null, \"loaded_at_query\": null, \"meta\": {}, \"tags\": []}, \"patch_path\": null, \"unrendered_config\": {\"loaded_at_field\": null, \"loaded_at_query\": null, \"meta\": {}, \"tags\": []}, \"relation_name\": \"\\\"dbt\\\".\\\"my_source\\\".\\\"my_seed\\\"\", \"created_at\": 1759423716.976106, \"unrendered_database\": null, \"unrendered_schema\": null, \"doc_blocks\": []}}, \"macros\": {\"macro.test.test_check_nothing\": {\"name\": \"test_check_nothing\", \"resource_type\": \"macro\", \"package_name\": \"test\", \"path\": \"macros/dummy_test.sql\", \"original_file_path\": \"macros/dummy_test.sql\", \"unique_id\": \"macro.test.test_check_nothing\", \"macro_sql\": \"{% test check_nothing(model) %}\\n-- a silly test to make sure that table-level tests show up in the manifest\\n-- without a column_name field\\n\\nselect 0\\n\\n{% endtest %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.008358, \"supported_languages\": null}, \"macro.test.test_disabled_check_nothing\": {\"name\": \"test_disabled_check_nothing\", \"resource_type\": \"macro\", \"package_name\": \"test\", \"path\": \"macros/disabled_dummy_test.sql\", \"original_file_path\": \"macros/disabled_dummy_test.sql\", \"unique_id\": \"macro.test.test_disabled_check_nothing\", \"macro_sql\": \"{% test disabled_check_nothing(model) %}\\n-- a silly test to make sure that table-level tests show up in the manifest\\n-- without a column_name field\\n\\n{{ config(enabled=False) }}\\nselect 0\\n\\n{% endtest %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0087419, \"supported_languages\": null}, \"macro.test.do_nothing\": {\"name\": \"do_nothing\", \"resource_type\": \"macro\", \"package_name\": \"test\", \"path\": \"macros/do_nothing.sql\", \"original_file_path\": \"macros/do_nothing.sql\", \"unique_id\": \"macro.test.do_nothing\", \"macro_sql\": \"{% macro do_nothing(foo2, bar2) %}\\n    select\\n        '{{ foo2 }}' as foo2,\\n        '{{ bar2 }}' as bar2\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.009166, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__current_timestamp\": {\"name\": \"postgres__current_timestamp\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/timestamps.sql\", \"original_file_path\": \"macros/timestamps.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__current_timestamp\", \"macro_sql\": \"{% macro postgres__current_timestamp() -%}\\n    now()\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0092008, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__snapshot_string_as_time\": {\"name\": \"postgres__snapshot_string_as_time\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/timestamps.sql\", \"original_file_path\": \"macros/timestamps.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__snapshot_string_as_time\", \"macro_sql\": \"{% macro postgres__snapshot_string_as_time(timestamp) -%}\\n    {%- set result = \\\"'\\\" ~ timestamp ~ \\\"'::timestamp without time zone\\\" -%}\\n    {{ return(result) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.009213, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__snapshot_get_time\": {\"name\": \"postgres__snapshot_get_time\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/timestamps.sql\", \"original_file_path\": \"macros/timestamps.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__snapshot_get_time\", \"macro_sql\": \"{% macro postgres__snapshot_get_time() -%}\\n  {{ current_timestamp() }}::timestamp without time zone\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.009224, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__current_timestamp_backcompat\": {\"name\": \"postgres__current_timestamp_backcompat\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/timestamps.sql\", \"original_file_path\": \"macros/timestamps.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__current_timestamp_backcompat\", \"macro_sql\": \"{% macro postgres__current_timestamp_backcompat() %}\\n    current_timestamp::{{ type_timestamp() }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.type_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.009235, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__current_timestamp_in_utc_backcompat\": {\"name\": \"postgres__current_timestamp_in_utc_backcompat\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/timestamps.sql\", \"original_file_path\": \"macros/timestamps.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__current_timestamp_in_utc_backcompat\", \"macro_sql\": \"{% macro postgres__current_timestamp_in_utc_backcompat() %}\\n    (current_timestamp at time zone 'utc')::{{ type_timestamp() }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.type_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0092459, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_catalog_relations\": {\"name\": \"postgres__get_catalog_relations\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/catalog.sql\", \"original_file_path\": \"macros/catalog.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_catalog_relations\", \"macro_sql\": \"{% macro postgres__get_catalog_relations(information_schema, relations) -%}\\n  {%- call statement('catalog', fetch_result=True) -%}\\n\\n    {#\\n      If the user has multiple databases set and the first one is wrong, this will fail.\\n      But we won't fail in the case where there are multiple quoting-difference-only dbs, which is better.\\n    #}\\n    {% set database = information_schema.database %}\\n    {{ adapter.verify_database(database) }}\\n\\n    select\\n        '{{ database }}' as table_database,\\n        sch.nspname as table_schema,\\n        tbl.relname as table_name,\\n        case tbl.relkind\\n            when 'v' then 'VIEW'\\n            when 'm' then 'MATERIALIZED VIEW'\\n            else 'BASE TABLE'\\n        end as table_type,\\n        tbl_desc.description as table_comment,\\n        col.attname as column_name,\\n        col.attnum as column_index,\\n        pg_catalog.format_type(col.atttypid, col.atttypmod) as column_type,\\n        col_desc.description as column_comment,\\n        pg_get_userbyid(tbl.relowner) as table_owner\\n\\n    from pg_catalog.pg_namespace sch\\n    join pg_catalog.pg_class tbl on tbl.relnamespace = sch.oid\\n    join pg_catalog.pg_attribute col on col.attrelid = tbl.oid\\n    left outer join pg_catalog.pg_description tbl_desc on (tbl_desc.objoid = tbl.oid and tbl_desc.objsubid = 0)\\n    left outer join pg_catalog.pg_description col_desc on (col_desc.objoid = tbl.oid and col_desc.objsubid = col.attnum)\\n    where (\\n      {%- for relation in relations -%}\\n        {%- if relation.identifier -%}\\n          (upper(sch.nspname) = upper('{{ relation.schema }}') and\\n           upper(tbl.relname) = upper('{{ relation.identifier }}'))\\n        {%- else-%}\\n          upper(sch.nspname) = upper('{{ relation.schema }}')\\n        {%- endif -%}\\n        {%- if not loop.last %} or {% endif -%}\\n      {%- endfor -%}\\n    )\\n      and not pg_is_other_temp_schema(sch.oid) -- not a temporary schema belonging to another session\\n      and tbl.relpersistence in ('p', 'u') -- [p]ermanent table or [u]nlogged table. Exclude [t]emporary tables\\n      and tbl.relkind in ('r', 'v', 'f', 'p', 'm') -- o[r]dinary table, [v]iew, [f]oreign table, [p]artitioned table, [m]aterialized view. Other values are [i]ndex, [S]equence, [c]omposite type, [t]OAST table\\n      and col.attnum > 0 -- negative numbers are used for system columns such as oid\\n      and not col.attisdropped -- column as not been dropped\\n\\n    order by\\n        sch.nspname,\\n        tbl.relname,\\n        col.attnum\\n\\n  {%- endcall -%}\\n\\n  {{ return(load_result('catalog').table) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.009269, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_catalog\": {\"name\": \"postgres__get_catalog\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/catalog.sql\", \"original_file_path\": \"macros/catalog.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_catalog\", \"macro_sql\": \"{% macro postgres__get_catalog(information_schema, schemas) -%}\\n  {%- set relations = [] -%}\\n  {%- for schema in schemas -%}\\n    {%- set dummy = relations.append({'schema': schema}) -%}\\n  {%- endfor -%}\\n  {{ return(postgres__get_catalog_relations(information_schema, relations)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_catalog_relations\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.009279, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_relations\": {\"name\": \"postgres__get_relations\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/relations.sql\", \"original_file_path\": \"macros/relations.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_relations\", \"macro_sql\": \"{% macro postgres__get_relations() -%}\\n\\n  {#\\n      -- in pg_depend, objid is the dependent, refobjid is the referenced object\\n      --  > a pg_depend entry indicates that the referenced object cannot be\\n      --  > dropped without also dropping the dependent object.\\n  #}\\n\\n  {%- call statement('relations', fetch_result=True) -%}\\n    select distinct\\n        dependent_namespace.nspname as dependent_schema,\\n        dependent_class.relname as dependent_name,\\n        referenced_namespace.nspname as referenced_schema,\\n        referenced_class.relname as referenced_name\\n\\n    -- Query for views: views are entries in pg_class with an entry in pg_rewrite, but we avoid\\n    -- a seq scan on pg_rewrite by leveraging the fact there is an \\\"internal\\\" row in pg_depend for\\n    -- the view...\\n    from pg_class as dependent_class\\n    join pg_namespace as dependent_namespace on dependent_namespace.oid = dependent_class.relnamespace\\n    join pg_depend as dependent_depend on dependent_depend.refobjid = dependent_class.oid\\n        and dependent_depend.classid = 'pg_rewrite'::regclass\\n        and dependent_depend.refclassid = 'pg_class'::regclass\\n        and dependent_depend.deptype = 'i'\\n\\n    -- ... and via pg_depend (that has a row per column, hence the need for \\\"distinct\\\" above, and\\n    -- making sure to exclude the internal row to avoid a view appearing to depend on itself)...\\n    join pg_depend as joining_depend on joining_depend.objid = dependent_depend.objid\\n        and joining_depend.classid = 'pg_rewrite'::regclass\\n        and joining_depend.refclassid = 'pg_class'::regclass\\n        and joining_depend.refobjid != dependent_depend.refobjid\\n\\n    -- ... we can find the tables they query from in pg_class, but excluding system tables. Note we\\n    -- don't need need to exclude _dependent_ system tables, because they only query from other\\n    -- system tables, and so are automatically excluded by excluding _referenced_ system tables\\n    join pg_class as referenced_class on referenced_class.oid = joining_depend.refobjid\\n    join pg_namespace as referenced_namespace on referenced_namespace.oid = referenced_class.relnamespace\\n        and referenced_namespace.nspname != 'information_schema'\\n        and referenced_namespace.nspname not like 'pg\\\\_%'\\n\\n    order by\\n        dependent_schema, dependent_name, referenced_schema, referenced_name;\\n\\n  {%- endcall -%}\\n\\n  {{ return(load_result('relations').table) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.009302, \"supported_languages\": null}, \"macro.dbt_postgres.postgres_get_relations\": {\"name\": \"postgres_get_relations\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/relations.sql\", \"original_file_path\": \"macros/relations.sql\", \"unique_id\": \"macro.dbt_postgres.postgres_get_relations\", \"macro_sql\": \"{% macro postgres_get_relations() %}\\n  {{ return(postgres__get_relations()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_relations\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.009314, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__create_table_as\": {\"name\": \"postgres__create_table_as\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__create_table_as\", \"macro_sql\": \"{% macro postgres__create_table_as(temporary, relation, sql) -%}\\n  {%- set unlogged = config.get('unlogged', default=false) -%}\\n  {%- set sql_header = config.get('sql_header', none) -%}\\n\\n  {{ sql_header if sql_header is not none }}\\n\\n  create {% if temporary -%}\\n    temporary\\n  {%- elif unlogged -%}\\n    unlogged\\n  {%- endif %} table {{ relation }}\\n  {% set contract_config = config.get('contract') %}\\n  {% if contract_config.enforced %}\\n    {{ get_assert_columns_equivalent(sql) }}\\n  {% endif -%}\\n  {% if contract_config.enforced and (not temporary) -%}\\n      {{ get_table_columns_and_constraints() }} ;\\n    insert into {{ relation }} (\\n      {{ adapter.dispatch('get_column_names', 'dbt')() }}\\n    )\\n    {%- set sql = get_select_subquery(sql) %}\\n  {% else %}\\n    as\\n  {% endif %}\\n  (\\n    {{ sql }}\\n  );\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_assert_columns_equivalent\", \"macro.dbt.get_table_columns_and_constraints\", \"macro.dbt.default__get_column_names\", \"macro.dbt.get_select_subquery\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.009342, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_create_index_sql\": {\"name\": \"postgres__get_create_index_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_create_index_sql\", \"macro_sql\": \"{% macro postgres__get_create_index_sql(relation, index_dict) -%}\\n  {%- set index_config = adapter.parse_index(index_dict) -%}\\n  {%- set comma_separated_columns = \\\", \\\".join(index_config.columns) -%}\\n  {%- set index_name = index_config.render(relation) -%}\\n\\n  create {% if index_config.unique -%}\\n    unique\\n  {%- endif %} index if not exists\\n  \\\"{{ index_name }}\\\"\\n  on {{ relation }} {% if index_config.type -%}\\n    using {{ index_config.type }}\\n  {%- endif %}\\n  ({{ comma_separated_columns }})\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.009353, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__create_schema\": {\"name\": \"postgres__create_schema\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__create_schema\", \"macro_sql\": \"{% macro postgres__create_schema(relation) -%}\\n  {% if relation.database -%}\\n    {{ adapter.verify_database(relation.database) }}\\n  {%- endif -%}\\n  {%- call statement('create_schema') -%}\\n    create schema if not exists {{ relation.without_identifier().include(database=False) }}\\n  {%- endcall -%}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.009364, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__drop_schema\": {\"name\": \"postgres__drop_schema\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__drop_schema\", \"macro_sql\": \"{% macro postgres__drop_schema(relation) -%}\\n  {% if relation.database -%}\\n    {{ adapter.verify_database(relation.database) }}\\n  {%- endif -%}\\n  {%- call statement('drop_schema') -%}\\n    drop schema if exists {{ relation.without_identifier().include(database=False) }} cascade\\n  {%- endcall -%}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.009374, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_columns_in_relation\": {\"name\": \"postgres__get_columns_in_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_columns_in_relation\", \"macro_sql\": \"{% macro postgres__get_columns_in_relation(relation) -%}\\n  {% call statement('get_columns_in_relation', fetch_result=True) %}\\n      select\\n          column_name,\\n          data_type,\\n          character_maximum_length,\\n          numeric_precision,\\n          numeric_scale\\n\\n      from {{ relation.information_schema('columns') }}\\n      where table_name = '{{ relation.identifier }}'\\n        {% if relation.schema %}\\n        and table_schema = '{{ relation.schema }}'\\n        {% endif %}\\n      order by ordinal_position\\n\\n  {% endcall %}\\n  {% set table = load_result('get_columns_in_relation').table %}\\n  {{ return(sql_convert_columns_in_relation(table)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\", \"macro.dbt.sql_convert_columns_in_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.009384, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__list_relations_without_caching\": {\"name\": \"postgres__list_relations_without_caching\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__list_relations_without_caching\", \"macro_sql\": \"{% macro postgres__list_relations_without_caching(schema_relation) %}\\n  {% call statement('list_relations_without_caching', fetch_result=True) -%}\\n    select\\n      '{{ schema_relation.database }}' as database,\\n      tablename as name,\\n      schemaname as schema,\\n      'table' as type\\n    from pg_tables\\n    where schemaname ilike '{{ schema_relation.schema }}'\\n    union all\\n    select\\n      '{{ schema_relation.database }}' as database,\\n      viewname as name,\\n      schemaname as schema,\\n      'view' as type\\n    from pg_views\\n    where schemaname ilike '{{ schema_relation.schema }}'\\n    union all\\n    select\\n      '{{ schema_relation.database }}' as database,\\n      matviewname as name,\\n      schemaname as schema,\\n      'materialized_view' as type\\n    from pg_matviews\\n    where schemaname ilike '{{ schema_relation.schema }}'\\n  {% endcall %}\\n  {{ return(load_result('list_relations_without_caching').table) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.009394, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__information_schema_name\": {\"name\": \"postgres__information_schema_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__information_schema_name\", \"macro_sql\": \"{% macro postgres__information_schema_name(database) -%}\\n  {% if database_name -%}\\n    {{ adapter.verify_database(database_name) }}\\n  {%- endif -%}\\n  information_schema\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.009404, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__list_schemas\": {\"name\": \"postgres__list_schemas\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__list_schemas\", \"macro_sql\": \"{% macro postgres__list_schemas(database) %}\\n  {% if database -%}\\n    {{ adapter.verify_database(database) }}\\n  {%- endif -%}\\n  {% call statement('list_schemas', fetch_result=True, auto_begin=False) %}\\n    select distinct nspname from pg_namespace\\n  {% endcall %}\\n  {{ return(load_result('list_schemas').table) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.009414, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__check_schema_exists\": {\"name\": \"postgres__check_schema_exists\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__check_schema_exists\", \"macro_sql\": \"{% macro postgres__check_schema_exists(information_schema, schema) -%}\\n  {% if information_schema.database -%}\\n    {{ adapter.verify_database(information_schema.database) }}\\n  {%- endif -%}\\n  {% call statement('check_schema_exists', fetch_result=True, auto_begin=False) %}\\n    select count(*) from pg_namespace where nspname = '{{ schema }}'\\n  {% endcall %}\\n  {{ return(load_result('check_schema_exists').table) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.009425, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__make_relation_with_suffix\": {\"name\": \"postgres__make_relation_with_suffix\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__make_relation_with_suffix\", \"macro_sql\": \"{% macro postgres__make_relation_with_suffix(base_relation, suffix, dstring) %}\\n    {% if dstring %}\\n      {% set dt = modules.datetime.datetime.now() %}\\n      {% set dtstring = dt.strftime(\\\"%H%M%S%f\\\") %}\\n      {% set suffix = suffix ~ dtstring %}\\n    {% endif %}\\n    {% set suffix_length = suffix|length %}\\n    {% set relation_max_name_length = base_relation.relation_max_name_length() %}\\n    {% if suffix_length > relation_max_name_length %}\\n        {% do exceptions.raise_compiler_error('Relation suffix is too long (' ~ suffix_length ~ ' characters). Maximum length is ' ~ relation_max_name_length ~ ' characters.') %}\\n    {% endif %}\\n    {% set identifier = base_relation.identifier[:relation_max_name_length - suffix_length] ~ suffix %}\\n\\n    {{ return(base_relation.incorporate(path={\\\"identifier\\\": identifier })) }}\\n\\n  {% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.009435, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__make_intermediate_relation\": {\"name\": \"postgres__make_intermediate_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__make_intermediate_relation\", \"macro_sql\": \"{% macro postgres__make_intermediate_relation(base_relation, suffix) %}\\n    {{ return(postgres__make_relation_with_suffix(base_relation, suffix, dstring=False)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_relation_with_suffix\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0094469, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__make_temp_relation\": {\"name\": \"postgres__make_temp_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__make_temp_relation\", \"macro_sql\": \"{% macro postgres__make_temp_relation(base_relation, suffix) %}\\n    {% set temp_relation = postgres__make_relation_with_suffix(base_relation, suffix, dstring=True) %}\\n    {{ return(temp_relation.incorporate(path={\\\"schema\\\": none,\\n                                              \\\"database\\\": none})) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_relation_with_suffix\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0094569, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__make_backup_relation\": {\"name\": \"postgres__make_backup_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__make_backup_relation\", \"macro_sql\": \"{% macro postgres__make_backup_relation(base_relation, backup_relation_type, suffix) %}\\n    {% set backup_relation = postgres__make_relation_with_suffix(base_relation, suffix, dstring=False) %}\\n    {{ return(backup_relation.incorporate(type=backup_relation_type)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_relation_with_suffix\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.009467, \"supported_languages\": null}, \"macro.dbt_postgres.postgres_escape_comment\": {\"name\": \"postgres_escape_comment\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres_escape_comment\", \"macro_sql\": \"{% macro postgres_escape_comment(comment) -%}\\n  {% if comment is not string %}\\n    {% do exceptions.raise_compiler_error('cannot escape a non-string: ' ~ comment) %}\\n  {% endif %}\\n  {%- set magic = '$dbt_comment_literal_block$' -%}\\n  {%- if magic in comment -%}\\n    {%- do exceptions.raise_compiler_error('The string ' ~ magic ~ ' is not allowed in comments.') -%}\\n  {%- endif -%}\\n  {{ magic }}{{ comment }}{{ magic }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0094779, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__alter_relation_comment\": {\"name\": \"postgres__alter_relation_comment\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__alter_relation_comment\", \"macro_sql\": \"{% macro postgres__alter_relation_comment(relation, comment) %}\\n  {% set escaped_comment = postgres_escape_comment(comment) %}\\n  {% if relation.type == 'materialized_view' -%}\\n    {% set relation_type = \\\"materialized view\\\" %}\\n  {%- else -%}\\n    {%- set relation_type = relation.type -%}\\n  {%- endif -%}\\n  comment on {{ relation_type }} {{ relation }} is {{ escaped_comment }};\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres_escape_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0094879, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__alter_column_comment\": {\"name\": \"postgres__alter_column_comment\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__alter_column_comment\", \"macro_sql\": \"{% macro postgres__alter_column_comment(relation, column_dict) %}\\n  {% set existing_columns = adapter.get_columns_in_relation(relation) | map(attribute=\\\"name\\\") | list %}\\n  {% for column_name in column_dict if (column_name in existing_columns) %}\\n    {% set comment = column_dict[column_name]['description'] %}\\n    {% set escaped_comment = postgres_escape_comment(comment) %}\\n    comment on column {{ relation }}.{{ adapter.quote(column_name) if column_dict[column_name]['quote'] else column_name }} is {{ escaped_comment }};\\n  {% endfor %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres_escape_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0094981, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_show_grant_sql\": {\"name\": \"postgres__get_show_grant_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_show_grant_sql\", \"macro_sql\": \"\\n\\n{%- macro postgres__get_show_grant_sql(relation) -%}\\n  select grantee, privilege_type\\n  from {{ relation.information_schema('role_table_grants') }}\\n      where grantor = current_role\\n        and grantee != current_role\\n        and table_schema = '{{ relation.schema }}'\\n        and table_name = '{{ relation.identifier }}'\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.009509, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__copy_grants\": {\"name\": \"postgres__copy_grants\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__copy_grants\", \"macro_sql\": \"{% macro postgres__copy_grants() %}\\n    {{ return(False) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.009519, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_show_indexes_sql\": {\"name\": \"postgres__get_show_indexes_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_show_indexes_sql\", \"macro_sql\": \"{% macro postgres__get_show_indexes_sql(relation) %}\\n    select\\n        i.relname                                   as name,\\n        m.amname                                    as method,\\n        ix.indisunique                              as \\\"unique\\\",\\n        array_to_string(array_agg(a.attname), ',')  as column_names\\n    from pg_index ix\\n    join pg_class i\\n        on i.oid = ix.indexrelid\\n    join pg_am m\\n        on m.oid=i.relam\\n    join pg_class t\\n        on t.oid = ix.indrelid\\n    join pg_namespace n\\n        on n.oid = t.relnamespace\\n    join pg_attribute a\\n        on a.attrelid = t.oid\\n        and a.attnum = ANY(ix.indkey)\\n    where t.relname = '{{ relation.identifier }}'\\n      and n.nspname = '{{ relation.schema }}'\\n      and t.relkind in ('r', 'm')\\n    group by 1, 2, 3\\n    order by 1, 2, 3\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.009529, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_drop_index_sql\": {\"name\": \"postgres__get_drop_index_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_drop_index_sql\", \"macro_sql\": \"\\n\\n\\n{%- macro postgres__get_drop_index_sql(relation, index_name) -%}\\n    drop index if exists \\\"{{ relation.schema }}\\\".\\\"{{ index_name }}\\\"\\n{%- endmacro -%}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0095391, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_incremental_default_sql\": {\"name\": \"postgres__get_incremental_default_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/materializations/incremental_strategies.sql\", \"original_file_path\": \"macros/materializations/incremental_strategies.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_incremental_default_sql\", \"macro_sql\": \"{% macro postgres__get_incremental_default_sql(arg_dict) %}\\n\\n  {% if arg_dict[\\\"unique_key\\\"] %}\\n    {% do return(get_incremental_delete_insert_sql(arg_dict)) %}\\n  {% else %}\\n    {% do return(get_incremental_append_sql(arg_dict)) %}\\n  {% endif %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_incremental_delete_insert_sql\", \"macro.dbt.get_incremental_append_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0095592, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_incremental_microbatch_sql\": {\"name\": \"postgres__get_incremental_microbatch_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/materializations/incremental_strategies.sql\", \"original_file_path\": \"macros/materializations/incremental_strategies.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_incremental_microbatch_sql\", \"macro_sql\": \"{% macro postgres__get_incremental_microbatch_sql(arg_dict) %}\\n\\n  {% if arg_dict[\\\"unique_key\\\"] %}\\n    {% do return(adapter.dispatch('get_incremental_merge_sql', 'dbt')(arg_dict)) %}\\n  {% else %}\\n    {{ exceptions.raise_compiler_error(\\\"dbt-postgres 'microbatch' requires a `unique_key` config\\\") }}\\n  {% endif %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_incremental_merge_sql\", \"macro.dbt.default__get_incremental_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0095701, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__snapshot_merge_sql\": {\"name\": \"postgres__snapshot_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/materializations/snapshot_merge.sql\", \"original_file_path\": \"macros/materializations/snapshot_merge.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__snapshot_merge_sql\", \"macro_sql\": \"{% macro postgres__snapshot_merge_sql(target, source, insert_cols) -%}\\n    {%- set insert_cols_csv = insert_cols | join(', ') -%}\\n\\n    {%- set columns = config.get(\\\"snapshot_table_column_names\\\") or get_snapshot_table_column_names() -%}\\n\\n    update {{ target }}\\n    set {{ columns.dbt_valid_to }} = DBT_INTERNAL_SOURCE.{{ columns.dbt_valid_to }}\\n    from {{ source }} as DBT_INTERNAL_SOURCE\\n    where DBT_INTERNAL_SOURCE.{{ columns.dbt_scd_id }}::text = {{ target }}.{{ columns.dbt_scd_id }}::text\\n      and DBT_INTERNAL_SOURCE.dbt_change_type::text in ('update'::text, 'delete'::text)\\n      {% if config.get(\\\"dbt_valid_to_current\\\") %}\\n        and ({{ target }}.{{ columns.dbt_valid_to }} = {{ config.get('dbt_valid_to_current') }} or {{ target }}.{{ columns.dbt_valid_to }} is null);\\n      {% else %}\\n        and {{ target }}.{{ columns.dbt_valid_to }} is null;\\n      {% endif %}\\n\\n\\n    insert into {{ target }} ({{ insert_cols_csv }})\\n    select {% for column in insert_cols -%}\\n        DBT_INTERNAL_SOURCE.{{ column }} {%- if not loop.last %}, {%- endif %}\\n    {%- endfor %}\\n    from {{ source }} as DBT_INTERNAL_SOURCE\\n    where DBT_INTERNAL_SOURCE.dbt_change_type::text = 'insert'::text;\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_snapshot_table_column_names\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.00959, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__drop_materialized_view\": {\"name\": \"postgres__drop_materialized_view\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/relations/materialized_view/drop.sql\", \"original_file_path\": \"macros/relations/materialized_view/drop.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__drop_materialized_view\", \"macro_sql\": \"{% macro postgres__drop_materialized_view(relation) -%}\\n    drop materialized view if exists {{ relation }} cascade\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.009609, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__describe_materialized_view\": {\"name\": \"postgres__describe_materialized_view\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/relations/materialized_view/describe.sql\", \"original_file_path\": \"macros/relations/materialized_view/describe.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__describe_materialized_view\", \"macro_sql\": \"{% macro postgres__describe_materialized_view(relation) %}\\n    -- for now just get the indexes, we don't need the name or the query yet\\n    {% set _indexes = run_query(get_show_indexes_sql(relation)) %}\\n    {% do return({'indexes': _indexes}) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.run_query\", \"macro.dbt.get_show_indexes_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.009629, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__refresh_materialized_view\": {\"name\": \"postgres__refresh_materialized_view\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/relations/materialized_view/refresh.sql\", \"original_file_path\": \"macros/relations/materialized_view/refresh.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__refresh_materialized_view\", \"macro_sql\": \"{% macro postgres__refresh_materialized_view(relation) %}\\n    refresh materialized view {{ relation }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0096471, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_rename_materialized_view_sql\": {\"name\": \"postgres__get_rename_materialized_view_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/relations/materialized_view/rename.sql\", \"original_file_path\": \"macros/relations/materialized_view/rename.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_rename_materialized_view_sql\", \"macro_sql\": \"{% macro postgres__get_rename_materialized_view_sql(relation, new_name) %}\\n    alter materialized view {{ relation }} rename to {{ new_name }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.009665, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_alter_materialized_view_as_sql\": {\"name\": \"postgres__get_alter_materialized_view_as_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/relations/materialized_view/alter.sql\", \"original_file_path\": \"macros/relations/materialized_view/alter.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_alter_materialized_view_as_sql\", \"macro_sql\": \"{% macro postgres__get_alter_materialized_view_as_sql(\\n    relation,\\n    configuration_changes,\\n    sql,\\n    existing_relation,\\n    backup_relation,\\n    intermediate_relation\\n) %}\\n\\n    -- apply a full refresh immediately if needed\\n    {% if configuration_changes.requires_full_refresh %}\\n\\n        {{ get_replace_sql(existing_relation, relation, sql) }}\\n\\n    -- otherwise apply individual changes as needed\\n    {% else %}\\n\\n        {{ postgres__update_indexes_on_materialized_view(relation, configuration_changes.indexes) }}\\n\\n    {%- endif -%}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_replace_sql\", \"macro.dbt_postgres.postgres__update_indexes_on_materialized_view\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.009685, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__update_indexes_on_materialized_view\": {\"name\": \"postgres__update_indexes_on_materialized_view\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/relations/materialized_view/alter.sql\", \"original_file_path\": \"macros/relations/materialized_view/alter.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__update_indexes_on_materialized_view\", \"macro_sql\": \"\\n\\n\\n{%- macro postgres__update_indexes_on_materialized_view(relation, index_changes) -%}\\n    {{- log(\\\"Applying UPDATE INDEXES to: \\\" ~ relation) -}}\\n\\n    {%- for _index_change in index_changes -%}\\n        {%- set _index = _index_change.context -%}\\n\\n        {%- if _index_change.action == \\\"drop\\\" -%}\\n\\n            {{ postgres__get_drop_index_sql(relation, _index.name) }}\\n\\n        {%- elif _index_change.action == \\\"create\\\" -%}\\n\\n            {{ postgres__get_create_index_sql(relation, _index.as_node_config) }}\\n\\n        {%- endif -%}\\n\\t{{ ';' if not loop.last else \\\"\\\" }}\\n\\n    {%- endfor -%}\\n\\n{%- endmacro -%}\\n\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_drop_index_sql\", \"macro.dbt_postgres.postgres__get_create_index_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.009695, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_materialized_view_configuration_changes\": {\"name\": \"postgres__get_materialized_view_configuration_changes\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/relations/materialized_view/alter.sql\", \"original_file_path\": \"macros/relations/materialized_view/alter.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_materialized_view_configuration_changes\", \"macro_sql\": \"{% macro postgres__get_materialized_view_configuration_changes(existing_relation, new_config) %}\\n    {% set _existing_materialized_view = postgres__describe_materialized_view(existing_relation) %}\\n    {% set _configuration_changes = existing_relation.get_materialized_view_config_change_collection(_existing_materialized_view, new_config.model) %}\\n    {% do return(_configuration_changes) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__describe_materialized_view\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.009711, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_create_materialized_view_as_sql\": {\"name\": \"postgres__get_create_materialized_view_as_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/relations/materialized_view/create.sql\", \"original_file_path\": \"macros/relations/materialized_view/create.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_create_materialized_view_as_sql\", \"macro_sql\": \"{% macro postgres__get_create_materialized_view_as_sql(relation, sql) %}\\n    create materialized view if not exists {{ relation }} as {{ sql }};\\n\\n    {% for _index_dict in config.get('indexes', []) -%}\\n        {{- get_create_index_sql(relation, _index_dict) -}}{{ ';' if not loop.last else \\\"\\\" }}\\n    {%- endfor -%}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_create_index_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.009731, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__drop_table\": {\"name\": \"postgres__drop_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/relations/table/drop.sql\", \"original_file_path\": \"macros/relations/table/drop.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__drop_table\", \"macro_sql\": \"{% macro postgres__drop_table(relation) -%}\\n    drop table if exists {{ relation }} cascade\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.009758, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_replace_table_sql\": {\"name\": \"postgres__get_replace_table_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/relations/table/replace.sql\", \"original_file_path\": \"macros/relations/table/replace.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_replace_table_sql\", \"macro_sql\": \"{% macro postgres__get_replace_table_sql(relation, sql) -%}\\n\\n    {%- set sql_header = config.get('sql_header', none) -%}\\n    {{ sql_header if sql_header is not none }}\\n\\n    create or replace table {{ relation }}\\n        {% set contract_config = config.get('contract') %}\\n        {% if contract_config.enforced %}\\n            {{ get_assert_columns_equivalent(sql) }}\\n            {{ get_table_columns_and_constraints() }}\\n            {%- set sql = get_select_subquery(sql) %}\\n        {% endif %}\\n    as (\\n        {{ sql }}\\n    );\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_assert_columns_equivalent\", \"macro.dbt.get_table_columns_and_constraints\", \"macro.dbt.get_select_subquery\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.009779, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_rename_table_sql\": {\"name\": \"postgres__get_rename_table_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/relations/table/rename.sql\", \"original_file_path\": \"macros/relations/table/rename.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_rename_table_sql\", \"macro_sql\": \"{% macro postgres__get_rename_table_sql(relation, new_name) %}\\n    alter table {{ relation }} rename to {{ new_name }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0097978, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__drop_view\": {\"name\": \"postgres__drop_view\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/relations/view/drop.sql\", \"original_file_path\": \"macros/relations/view/drop.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__drop_view\", \"macro_sql\": \"{% macro postgres__drop_view(relation) -%}\\n    drop view if exists {{ relation }} cascade\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.009823, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_replace_view_sql\": {\"name\": \"postgres__get_replace_view_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/relations/view/replace.sql\", \"original_file_path\": \"macros/relations/view/replace.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_replace_view_sql\", \"macro_sql\": \"{% macro postgres__get_replace_view_sql(relation, sql) -%}\\n\\n    {%- set sql_header = config.get('sql_header', none) -%}\\n    {{ sql_header if sql_header is not none }}\\n\\n    create or replace view {{ relation }}\\n        {% set contract_config = config.get('contract') %}\\n        {% if contract_config.enforced %}\\n            {{ get_assert_columns_equivalent(sql) }}\\n        {%- endif %}\\n    as (\\n        {{ sql }}\\n    );\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_assert_columns_equivalent\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.009842, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_rename_view_sql\": {\"name\": \"postgres__get_rename_view_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/relations/view/rename.sql\", \"original_file_path\": \"macros/relations/view/rename.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_rename_view_sql\", \"macro_sql\": \"{% macro postgres__get_rename_view_sql(relation, new_name) %}\\n    alter view {{ relation }} rename to {{ new_name }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.00986, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__dateadd\": {\"name\": \"postgres__dateadd\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/utils/dateadd.sql\", \"original_file_path\": \"macros/utils/dateadd.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__dateadd\", \"macro_sql\": \"{% macro postgres__dateadd(datepart, interval, from_date_or_timestamp) %}\\n\\n    {{ from_date_or_timestamp }} + ((interval '1 {{ datepart }}') * ({{ interval }}))\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.009887, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__listagg\": {\"name\": \"postgres__listagg\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/utils/listagg.sql\", \"original_file_path\": \"macros/utils/listagg.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__listagg\", \"macro_sql\": \"{% macro postgres__listagg(measure, delimiter_text, order_by_clause, limit_num) -%}\\n\\n    {% if limit_num -%}\\n    array_to_string(\\n        (array_agg(\\n            {{ measure }}\\n            {% if order_by_clause -%}\\n            {{ order_by_clause }}\\n            {%- endif %}\\n        ))[1:{{ limit_num }}],\\n        {{ delimiter_text }}\\n        )\\n    {%- else %}\\n    string_agg(\\n        {{ measure }},\\n        {{ delimiter_text }}\\n        {% if order_by_clause -%}\\n        {{ order_by_clause }}\\n        {%- endif %}\\n        )\\n    {%- endif %}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0099058, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__datediff\": {\"name\": \"postgres__datediff\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/utils/datediff.sql\", \"original_file_path\": \"macros/utils/datediff.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__datediff\", \"macro_sql\": \"{% macro postgres__datediff(first_date, second_date, datepart) -%}\\n\\n    {% if datepart == 'year' %}\\n        (date_part('year', ({{second_date}})::date) - date_part('year', ({{first_date}})::date))\\n    {% elif datepart == 'quarter' %}\\n        ({{ datediff(first_date, second_date, 'year') }} * 4 + date_part('quarter', ({{second_date}})::date) - date_part('quarter', ({{first_date}})::date))\\n    {% elif datepart == 'month' %}\\n        ({{ datediff(first_date, second_date, 'year') }} * 12 + date_part('month', ({{second_date}})::date) - date_part('month', ({{first_date}})::date))\\n    {% elif datepart == 'day' %}\\n        (({{second_date}})::date - ({{first_date}})::date)\\n    {% elif datepart == 'week' %}\\n        ({{ datediff(first_date, second_date, 'day') }} / 7 + case\\n            when date_part('dow', ({{first_date}})::timestamp) <= date_part('dow', ({{second_date}})::timestamp) then\\n                case when {{first_date}} <= {{second_date}} then 0 else -1 end\\n            else\\n                case when {{first_date}} <= {{second_date}} then 1 else 0 end\\n        end)\\n    {% elif datepart == 'hour' %}\\n        ({{ datediff(first_date, second_date, 'day') }} * 24 + date_part('hour', ({{second_date}})::timestamp) - date_part('hour', ({{first_date}})::timestamp))\\n    {% elif datepart == 'minute' %}\\n        ({{ datediff(first_date, second_date, 'hour') }} * 60 + date_part('minute', ({{second_date}})::timestamp) - date_part('minute', ({{first_date}})::timestamp))\\n    {% elif datepart == 'second' %}\\n        ({{ datediff(first_date, second_date, 'minute') }} * 60 + floor(date_part('second', ({{second_date}})::timestamp)) - floor(date_part('second', ({{first_date}})::timestamp)))\\n    {% elif datepart == 'millisecond' %}\\n        ({{ datediff(first_date, second_date, 'minute') }} * 60000 + floor(date_part('millisecond', ({{second_date}})::timestamp)) - floor(date_part('millisecond', ({{first_date}})::timestamp)))\\n    {% elif datepart == 'microsecond' %}\\n        ({{ datediff(first_date, second_date, 'minute') }} * 60000000 + floor(date_part('microsecond', ({{second_date}})::timestamp)) - floor(date_part('microsecond', ({{first_date}})::timestamp)))\\n    {% else %}\\n        {{ exceptions.raise_compiler_error(\\\"Unsupported datepart for macro datediff in postgres: {!r}\\\".format(datepart)) }}\\n    {% endif %}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.datediff\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0099258, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__any_value\": {\"name\": \"postgres__any_value\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/utils/any_value.sql\", \"original_file_path\": \"macros/utils/any_value.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__any_value\", \"macro_sql\": \"{% macro postgres__any_value(expression) -%}\\n\\n    min({{ expression }})\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.009944, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__last_day\": {\"name\": \"postgres__last_day\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/utils/last_day.sql\", \"original_file_path\": \"macros/utils/last_day.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__last_day\", \"macro_sql\": \"{% macro postgres__last_day(date, datepart) -%}\\n\\n    {%- if datepart == 'quarter' -%}\\n    -- postgres dateadd does not support quarter interval.\\n    cast(\\n        {{dbt.dateadd('day', '-1',\\n        dbt.dateadd('month', '3', dbt.date_trunc(datepart, date))\\n        )}}\\n        as date)\\n    {%- else -%}\\n    {{dbt.default_last_day(date, datepart)}}\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.dateadd\", \"macro.dbt.date_trunc\", \"macro.dbt.default_last_day\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.009963, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__split_part\": {\"name\": \"postgres__split_part\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/utils/split_part.sql\", \"original_file_path\": \"macros/utils/split_part.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__split_part\", \"macro_sql\": \"{% macro postgres__split_part(string_text, delimiter_text, part_number) %}\\n\\n  {% if part_number >= 0 %}\\n    {{ dbt.default__split_part(string_text, delimiter_text, part_number) }}\\n  {% else %}\\n    {{ dbt._split_part_negative(string_text, delimiter_text, part_number) }}\\n  {% endif %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__split_part\", \"macro.dbt._split_part_negative\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.009981, \"supported_languages\": null}, \"macro.dbt.run_hooks\": {\"name\": \"run_hooks\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"unique_id\": \"macro.dbt.run_hooks\", \"macro_sql\": \"{% macro run_hooks(hooks, inside_transaction=True) %}\\n  {% for hook in hooks | selectattr('transaction', 'equalto', inside_transaction)  %}\\n    {% if not inside_transaction and loop.first %}\\n      {% call statement(auto_begin=inside_transaction) %}\\n        commit;\\n      {% endcall %}\\n    {% endif %}\\n    {% set rendered = render(hook.get('sql')) | trim %}\\n    {% if (rendered | length) > 0 %}\\n      {% call statement(auto_begin=inside_transaction) %}\\n        {{ rendered }}\\n      {% endcall %}\\n    {% endif %}\\n  {% endfor %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.010005, \"supported_languages\": null}, \"macro.dbt.make_hook_config\": {\"name\": \"make_hook_config\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"unique_id\": \"macro.dbt.make_hook_config\", \"macro_sql\": \"{% macro make_hook_config(sql, inside_transaction) %}\\n    {{ tojson({\\\"sql\\\": sql, \\\"transaction\\\": inside_transaction}) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.010015, \"supported_languages\": null}, \"macro.dbt.before_begin\": {\"name\": \"before_begin\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"unique_id\": \"macro.dbt.before_begin\", \"macro_sql\": \"{% macro before_begin(sql) %}\\n    {{ make_hook_config(sql, inside_transaction=False) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.make_hook_config\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.010025, \"supported_languages\": null}, \"macro.dbt.in_transaction\": {\"name\": \"in_transaction\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"unique_id\": \"macro.dbt.in_transaction\", \"macro_sql\": \"{% macro in_transaction(sql) %}\\n    {{ make_hook_config(sql, inside_transaction=True) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.make_hook_config\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.010036, \"supported_languages\": null}, \"macro.dbt.after_commit\": {\"name\": \"after_commit\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"unique_id\": \"macro.dbt.after_commit\", \"macro_sql\": \"{% macro after_commit(sql) %}\\n    {{ make_hook_config(sql, inside_transaction=False) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.make_hook_config\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.010046, \"supported_languages\": null}, \"macro.dbt.set_sql_header\": {\"name\": \"set_sql_header\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/configs.sql\", \"original_file_path\": \"macros/materializations/configs.sql\", \"unique_id\": \"macro.dbt.set_sql_header\", \"macro_sql\": \"{% macro set_sql_header(config) -%}\\n  {{ config.set('sql_header', caller()) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0100648, \"supported_languages\": null}, \"macro.dbt.should_full_refresh\": {\"name\": \"should_full_refresh\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/configs.sql\", \"original_file_path\": \"macros/materializations/configs.sql\", \"unique_id\": \"macro.dbt.should_full_refresh\", \"macro_sql\": \"{% macro should_full_refresh() %}\\n  {% set config_full_refresh = config.get('full_refresh') %}\\n  {% if config_full_refresh is none %}\\n    {% set config_full_refresh = flags.FULL_REFRESH %}\\n  {% endif %}\\n  {% do return(config_full_refresh) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0100758, \"supported_languages\": null}, \"macro.dbt.should_store_failures\": {\"name\": \"should_store_failures\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/configs.sql\", \"original_file_path\": \"macros/materializations/configs.sql\", \"unique_id\": \"macro.dbt.should_store_failures\", \"macro_sql\": \"{% macro should_store_failures() %}\\n  {% set config_store_failures = config.get('store_failures') %}\\n  {% if config_store_failures is none %}\\n    {% set config_store_failures = flags.STORE_FAILURES %}\\n  {% endif %}\\n  {% do return(config_store_failures) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.010085, \"supported_languages\": null}, \"macro.dbt.snapshot_merge_sql\": {\"name\": \"snapshot_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/snapshot_merge.sql\", \"original_file_path\": \"macros/materializations/snapshots/snapshot_merge.sql\", \"unique_id\": \"macro.dbt.snapshot_merge_sql\", \"macro_sql\": \"{% macro snapshot_merge_sql(target, source, insert_cols) -%}\\n  {{ adapter.dispatch('snapshot_merge_sql', 'dbt')(target, source, insert_cols) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__snapshot_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0101051, \"supported_languages\": null}, \"macro.dbt.default__snapshot_merge_sql\": {\"name\": \"default__snapshot_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/snapshot_merge.sql\", \"original_file_path\": \"macros/materializations/snapshots/snapshot_merge.sql\", \"unique_id\": \"macro.dbt.default__snapshot_merge_sql\", \"macro_sql\": \"{% macro default__snapshot_merge_sql(target, source, insert_cols) -%}\\n    {%- set insert_cols_csv = insert_cols | join(', ') -%}\\n\\n    {%- set columns = config.get(\\\"snapshot_table_column_names\\\") or get_snapshot_table_column_names() -%}\\n\\n    merge into {{ target.render() }} as DBT_INTERNAL_DEST\\n    using {{ source }} as DBT_INTERNAL_SOURCE\\n    on DBT_INTERNAL_SOURCE.{{ columns.dbt_scd_id }} = DBT_INTERNAL_DEST.{{ columns.dbt_scd_id }}\\n\\n    when matched\\n     {% if config.get(\\\"dbt_valid_to_current\\\") %}\\n\\t{% set source_unique_key = (\\\"DBT_INTERNAL_DEST.\\\" ~ columns.dbt_valid_to) | trim %}\\n\\t{% set target_unique_key = config.get('dbt_valid_to_current') | trim %}\\n\\tand ({{ equals(source_unique_key, target_unique_key) }} or {{ source_unique_key }} is null)\\n\\n     {% else %}\\n       and DBT_INTERNAL_DEST.{{ columns.dbt_valid_to }} is null\\n     {% endif %}\\n     and DBT_INTERNAL_SOURCE.dbt_change_type in ('update', 'delete')\\n        then update\\n        set {{ columns.dbt_valid_to }} = DBT_INTERNAL_SOURCE.{{ columns.dbt_valid_to }}\\n\\n    when not matched\\n     and DBT_INTERNAL_SOURCE.dbt_change_type = 'insert'\\n        then insert ({{ insert_cols_csv }})\\n        values ({{ insert_cols_csv }})\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_snapshot_table_column_names\", \"macro.dbt.equals\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0101151, \"supported_languages\": null}, \"macro.dbt.strategy_dispatch\": {\"name\": \"strategy_dispatch\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"unique_id\": \"macro.dbt.strategy_dispatch\", \"macro_sql\": \"{% macro strategy_dispatch(name) -%}\\n{% set original_name = name %}\\n  {% if '.' in name %}\\n    {% set package_name, name = name.split(\\\".\\\", 1) %}\\n  {% else %}\\n    {% set package_name = none %}\\n  {% endif %}\\n\\n  {% if package_name is none %}\\n    {% set package_context = context %}\\n  {% elif package_name in context %}\\n    {% set package_context = context[package_name] %}\\n  {% else %}\\n    {% set error_msg %}\\n        Could not find package '{{package_name}}', called with '{{original_name}}'\\n    {% endset %}\\n    {{ exceptions.raise_compiler_error(error_msg | trim) }}\\n  {% endif %}\\n\\n  {%- set search_name = 'snapshot_' ~ name ~ '_strategy' -%}\\n\\n  {% if search_name not in package_context %}\\n    {% set error_msg %}\\n        The specified strategy macro '{{name}}' was not found in package '{{ package_name }}'\\n    {% endset %}\\n    {{ exceptions.raise_compiler_error(error_msg | trim) }}\\n  {% endif %}\\n  {{ return(package_context[search_name]) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.010141, \"supported_languages\": null}, \"macro.dbt.snapshot_hash_arguments\": {\"name\": \"snapshot_hash_arguments\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"unique_id\": \"macro.dbt.snapshot_hash_arguments\", \"macro_sql\": \"{% macro snapshot_hash_arguments(args) -%}\\n  {{ adapter.dispatch('snapshot_hash_arguments', 'dbt')(args) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__snapshot_hash_arguments\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.010151, \"supported_languages\": null}, \"macro.dbt.default__snapshot_hash_arguments\": {\"name\": \"default__snapshot_hash_arguments\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"unique_id\": \"macro.dbt.default__snapshot_hash_arguments\", \"macro_sql\": \"{% macro default__snapshot_hash_arguments(args) -%}\\n    md5({%- for arg in args -%}\\n        coalesce(cast({{ arg }} as varchar ), '')\\n        {% if not loop.last %} || '|' || {% endif %}\\n    {%- endfor -%})\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.010161, \"supported_languages\": null}, \"macro.dbt.snapshot_timestamp_strategy\": {\"name\": \"snapshot_timestamp_strategy\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"unique_id\": \"macro.dbt.snapshot_timestamp_strategy\", \"macro_sql\": \"{% macro snapshot_timestamp_strategy(node, snapshotted_rel, current_rel, model_config, target_exists) %}\\n    {# The model_config parameter is no longer used, but is passed in anyway for compatibility. #}\\n    {% set primary_key = config.get('unique_key') %}\\n    {% set updated_at = config.get('updated_at') %}\\n    {% set hard_deletes = adapter.get_hard_deletes_behavior(config) %}\\n    {% set invalidate_hard_deletes = hard_deletes == 'invalidate' %}\\n    {% set columns = config.get(\\\"snapshot_table_column_names\\\") or get_snapshot_table_column_names() %}\\n\\n    {#/*\\n        The snapshot relation might not have an {{ updated_at }} value if the\\n        snapshot strategy is changed from `check` to `timestamp`. We\\n        should use a dbt-created column for the comparison in the snapshot\\n        table instead of assuming that the user-supplied {{ updated_at }}\\n        will be present in the historical data.\\n\\n        See https://github.com/dbt-labs/dbt-core/issues/2350\\n    */ #}\\n    {% set row_changed_expr -%}\\n        ({{ snapshotted_rel }}.{{ columns.dbt_valid_from }} < {{ current_rel }}.{{ updated_at }})\\n    {%- endset %}\\n\\n    {% set scd_args = api.Relation.scd_args(primary_key, updated_at) %}\\n    {% set scd_id_expr = snapshot_hash_arguments(scd_args) %}\\n\\n    {% do return({\\n        \\\"unique_key\\\": primary_key,\\n        \\\"updated_at\\\": updated_at,\\n        \\\"row_changed\\\": row_changed_expr,\\n        \\\"scd_id\\\": scd_id_expr,\\n        \\\"invalidate_hard_deletes\\\": invalidate_hard_deletes,\\n        \\\"hard_deletes\\\": hard_deletes\\n    }) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_snapshot_table_column_names\", \"macro.dbt.snapshot_hash_arguments\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.010171, \"supported_languages\": null}, \"macro.dbt.snapshot_string_as_time\": {\"name\": \"snapshot_string_as_time\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"unique_id\": \"macro.dbt.snapshot_string_as_time\", \"macro_sql\": \"{% macro snapshot_string_as_time(timestamp) -%}\\n    {{ adapter.dispatch('snapshot_string_as_time', 'dbt')(timestamp) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__snapshot_string_as_time\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0101812, \"supported_languages\": null}, \"macro.dbt.default__snapshot_string_as_time\": {\"name\": \"default__snapshot_string_as_time\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"unique_id\": \"macro.dbt.default__snapshot_string_as_time\", \"macro_sql\": \"{% macro default__snapshot_string_as_time(timestamp) %}\\n    {% do exceptions.raise_not_implemented(\\n        'snapshot_string_as_time macro not implemented for adapter '+adapter.type()\\n    ) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.01019, \"supported_languages\": null}, \"macro.dbt.snapshot_check_all_get_existing_columns\": {\"name\": \"snapshot_check_all_get_existing_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"unique_id\": \"macro.dbt.snapshot_check_all_get_existing_columns\", \"macro_sql\": \"{% macro snapshot_check_all_get_existing_columns(node, target_exists, check_cols_config) -%}\\n    {%- if not target_exists -%}\\n        {#-- no table yet -> return whatever the query does --#}\\n        {{ return((false, query_columns)) }}\\n    {%- endif -%}\\n\\n    {#-- handle any schema changes --#}\\n    {%- set target_relation = adapter.get_relation(database=node.database, schema=node.schema, identifier=node.alias) -%}\\n\\n    {% if check_cols_config == 'all' %}\\n        {%- set query_columns = get_columns_in_query(node['compiled_code']) -%}\\n\\n    {% elif check_cols_config is iterable and (check_cols_config | length) > 0 %}\\n        {#-- query for proper casing/quoting, to support comparison below --#}\\n        {%- set select_check_cols_from_target -%}\\n            {#-- N.B. The whitespace below is necessary to avoid edge case issue with comments --#}\\n            {#-- See: https://github.com/dbt-labs/dbt-core/issues/6781 --#}\\n            select {{ check_cols_config | join(', ') }} from (\\n                {{ node['compiled_code'] }}\\n            ) subq\\n        {%- endset -%}\\n        {% set query_columns = get_columns_in_query(select_check_cols_from_target) %}\\n\\n    {% else %}\\n        {% do exceptions.raise_compiler_error(\\\"Invalid value for 'check_cols': \\\" ~ check_cols_config) %}\\n    {% endif %}\\n\\n    {%- set existing_cols = adapter.get_columns_in_relation(target_relation) | map(attribute = 'name') | list -%}\\n    {%- set ns = namespace() -%} {#-- handle for-loop scoping with a namespace --#}\\n    {%- set ns.column_added = false -%}\\n\\n    {%- set intersection = [] -%}\\n    {%- for col in query_columns -%}\\n        {%- if col in existing_cols -%}\\n            {%- do intersection.append(adapter.quote(col)) -%}\\n        {%- else -%}\\n            {% set ns.column_added = true %}\\n        {%- endif -%}\\n    {%- endfor -%}\\n    {{ return((ns.column_added, intersection)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_columns_in_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.010201, \"supported_languages\": null}, \"macro.dbt.snapshot_check_strategy\": {\"name\": \"snapshot_check_strategy\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"unique_id\": \"macro.dbt.snapshot_check_strategy\", \"macro_sql\": \"{% macro snapshot_check_strategy(node, snapshotted_rel, current_rel, model_config, target_exists) %}\\n    {# The model_config parameter is no longer used, but is passed in anyway for compatibility. #}\\n    {% set check_cols_config = config.get('check_cols') %}\\n    {% set primary_key = config.get('unique_key') %}\\n    {% set hard_deletes = adapter.get_hard_deletes_behavior(config) %}\\n    {% set invalidate_hard_deletes = hard_deletes == 'invalidate' %}\\n    {% set updated_at = config.get('updated_at') or snapshot_get_time() %}\\n\\n    {% set column_added = false %}\\n\\n    {% set column_added, check_cols = snapshot_check_all_get_existing_columns(node, target_exists, check_cols_config) %}\\n\\n    {%- set row_changed_expr -%}\\n    (\\n    {%- if column_added -%}\\n        {{ get_true_sql() }}\\n    {%- else -%}\\n    {%- for col in check_cols -%}\\n        {{ snapshotted_rel }}.{{ col }} != {{ current_rel }}.{{ col }}\\n        or\\n        (\\n            (({{ snapshotted_rel }}.{{ col }} is null) and not ({{ current_rel }}.{{ col }} is null))\\n            or\\n            ((not {{ snapshotted_rel }}.{{ col }} is null) and ({{ current_rel }}.{{ col }} is null))\\n        )\\n        {%- if not loop.last %} or {% endif -%}\\n    {%- endfor -%}\\n    {%- endif -%}\\n    )\\n    {%- endset %}\\n\\n    {% set scd_args = api.Relation.scd_args(primary_key, updated_at) %}\\n    {% set scd_id_expr = snapshot_hash_arguments(scd_args) %}\\n\\n    {% do return({\\n        \\\"unique_key\\\": primary_key,\\n        \\\"updated_at\\\": updated_at,\\n        \\\"row_changed\\\": row_changed_expr,\\n        \\\"scd_id\\\": scd_id_expr,\\n        \\\"invalidate_hard_deletes\\\": invalidate_hard_deletes,\\n        \\\"hard_deletes\\\": hard_deletes\\n    }) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.snapshot_get_time\", \"macro.dbt.snapshot_check_all_get_existing_columns\", \"macro.dbt.get_true_sql\", \"macro.dbt.snapshot_hash_arguments\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.010211, \"supported_languages\": null}, \"macro.dbt.create_columns\": {\"name\": \"create_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.create_columns\", \"macro_sql\": \"{% macro create_columns(relation, columns) %}\\n  {{ adapter.dispatch('create_columns', 'dbt')(relation, columns) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__create_columns\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.01024, \"supported_languages\": null}, \"macro.dbt.default__create_columns\": {\"name\": \"default__create_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.default__create_columns\", \"macro_sql\": \"{% macro default__create_columns(relation, columns) %}\\n  {% for column in columns %}\\n    {% call statement() %}\\n      alter table {{ relation.render() }} add column {{ adapter.quote(column.name) }} {{ column.data_type }};\\n    {% endcall %}\\n  {% endfor %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.01025, \"supported_languages\": null}, \"macro.dbt.post_snapshot\": {\"name\": \"post_snapshot\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.post_snapshot\", \"macro_sql\": \"{% macro post_snapshot(staging_relation) %}\\n  {{ adapter.dispatch('post_snapshot', 'dbt')(staging_relation) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__post_snapshot\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.010286, \"supported_languages\": null}, \"macro.dbt.default__post_snapshot\": {\"name\": \"default__post_snapshot\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.default__post_snapshot\", \"macro_sql\": \"{% macro default__post_snapshot(staging_relation) %}\\n    {# no-op #}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.010296, \"supported_languages\": null}, \"macro.dbt.get_true_sql\": {\"name\": \"get_true_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.get_true_sql\", \"macro_sql\": \"{% macro get_true_sql() %}\\n  {{ adapter.dispatch('get_true_sql', 'dbt')() }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_true_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0103061, \"supported_languages\": null}, \"macro.dbt.default__get_true_sql\": {\"name\": \"default__get_true_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.default__get_true_sql\", \"macro_sql\": \"{% macro default__get_true_sql() %}\\n    {{ return('TRUE') }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0103161, \"supported_languages\": null}, \"macro.dbt.snapshot_staging_table\": {\"name\": \"snapshot_staging_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.snapshot_staging_table\", \"macro_sql\": \"{% macro snapshot_staging_table(strategy, source_sql, target_relation) -%}\\n  {{ adapter.dispatch('snapshot_staging_table', 'dbt')(strategy, source_sql, target_relation) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__snapshot_staging_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.010325, \"supported_languages\": null}, \"macro.dbt.get_snapshot_table_column_names\": {\"name\": \"get_snapshot_table_column_names\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.get_snapshot_table_column_names\", \"macro_sql\": \"{% macro get_snapshot_table_column_names() %}\\n    {{ return({'dbt_valid_to': 'dbt_valid_to', 'dbt_valid_from': 'dbt_valid_from', 'dbt_scd_id': 'dbt_scd_id', 'dbt_updated_at': 'dbt_updated_at', 'dbt_is_deleted': 'dbt_is_deleted'}) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.010335, \"supported_languages\": null}, \"macro.dbt.default__snapshot_staging_table\": {\"name\": \"default__snapshot_staging_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.default__snapshot_staging_table\", \"macro_sql\": \"{% macro default__snapshot_staging_table(strategy, source_sql, target_relation) -%}\\n    {% set columns = config.get('snapshot_table_column_names') or get_snapshot_table_column_names() %}\\n    {% if strategy.hard_deletes == 'new_record' %}\\n        {% set new_scd_id = snapshot_hash_arguments([columns.dbt_scd_id, snapshot_get_time()]) %}\\n    {% endif %}\\n    with snapshot_query as (\\n\\n        {{ source_sql }}\\n\\n    ),\\n\\n    snapshotted_data as (\\n\\n        select *, {{ unique_key_fields(strategy.unique_key) }}\\n        from {{ target_relation }}\\n        where\\n            {% if config.get('dbt_valid_to_current') %}\\n\\t\\t{% set source_unique_key = columns.dbt_valid_to | trim %}\\n\\t\\t{% set target_unique_key = config.get('dbt_valid_to_current') | trim %}\\n\\n\\t\\t{# The exact equals semantics between NULL values depends on the current behavior flag set. Also, update records if the source field is null #}\\n                ( {{ equals(source_unique_key, target_unique_key) }} or {{ source_unique_key }} is null )\\n            {% else %}\\n                {{ columns.dbt_valid_to }} is null\\n            {% endif %}\\n\\n    ),\\n\\n    insertions_source_data as (\\n\\n        select *, {{ unique_key_fields(strategy.unique_key) }},\\n            {{ strategy.updated_at }} as {{ columns.dbt_updated_at }},\\n            {{ strategy.updated_at }} as {{ columns.dbt_valid_from }},\\n            {{ get_dbt_valid_to_current(strategy, columns) }},\\n            {{ strategy.scd_id }} as {{ columns.dbt_scd_id }}\\n\\n        from snapshot_query\\n    ),\\n\\n    updates_source_data as (\\n\\n        select *, {{ unique_key_fields(strategy.unique_key) }},\\n            {{ strategy.updated_at }} as {{ columns.dbt_updated_at }},\\n            {{ strategy.updated_at }} as {{ columns.dbt_valid_from }},\\n            {{ strategy.updated_at }} as {{ columns.dbt_valid_to }}\\n\\n        from snapshot_query\\n    ),\\n\\n    {%- if strategy.hard_deletes == 'invalidate' or strategy.hard_deletes == 'new_record' %}\\n\\n    deletes_source_data as (\\n\\n        select *, {{ unique_key_fields(strategy.unique_key) }}\\n        from snapshot_query\\n    ),\\n    {% endif %}\\n\\n    insertions as (\\n\\n        select\\n            'insert' as dbt_change_type,\\n            source_data.*\\n          {%- if strategy.hard_deletes == 'new_record' -%}\\n            ,'False' as {{ columns.dbt_is_deleted }}\\n          {%- endif %}\\n\\n        from insertions_source_data as source_data\\n        left outer join snapshotted_data\\n            on {{ unique_key_join_on(strategy.unique_key, \\\"snapshotted_data\\\", \\\"source_data\\\") }}\\n            where {{ unique_key_is_null(strategy.unique_key, \\\"snapshotted_data\\\") }}\\n            or ({{ unique_key_is_not_null(strategy.unique_key, \\\"snapshotted_data\\\") }} and (\\n               {{ strategy.row_changed }} {%- if strategy.hard_deletes == 'new_record' -%} or snapshotted_data.{{ columns.dbt_is_deleted }} = 'True' {% endif %}\\n            )\\n\\n        )\\n\\n    ),\\n\\n    updates as (\\n\\n        select\\n            'update' as dbt_change_type,\\n            source_data.*,\\n            snapshotted_data.{{ columns.dbt_scd_id }}\\n          {%- if strategy.hard_deletes == 'new_record' -%}\\n            , snapshotted_data.{{ columns.dbt_is_deleted }}\\n          {%- endif %}\\n\\n        from updates_source_data as source_data\\n        join snapshotted_data\\n            on {{ unique_key_join_on(strategy.unique_key, \\\"snapshotted_data\\\", \\\"source_data\\\") }}\\n        where (\\n            {{ strategy.row_changed }}  {%- if strategy.hard_deletes == 'new_record' -%} or snapshotted_data.{{ columns.dbt_is_deleted }} = 'True' {% endif %}\\n        )\\n    )\\n\\n    {%- if strategy.hard_deletes == 'invalidate' or strategy.hard_deletes == 'new_record' %}\\n    ,\\n    deletes as (\\n\\n        select\\n            'delete' as dbt_change_type,\\n            source_data.*,\\n            {{ snapshot_get_time() }} as {{ columns.dbt_valid_from }},\\n            {{ snapshot_get_time() }} as {{ columns.dbt_updated_at }},\\n            {{ snapshot_get_time() }} as {{ columns.dbt_valid_to }},\\n            snapshotted_data.{{ columns.dbt_scd_id }}\\n          {%- if strategy.hard_deletes == 'new_record' -%}\\n            , snapshotted_data.{{ columns.dbt_is_deleted }}\\n          {%- endif %}\\n        from snapshotted_data\\n        left join deletes_source_data as source_data\\n            on {{ unique_key_join_on(strategy.unique_key, \\\"snapshotted_data\\\", \\\"source_data\\\") }}\\n            where {{ unique_key_is_null(strategy.unique_key, \\\"source_data\\\") }}\\n\\n            {%- if strategy.hard_deletes == 'new_record' %}\\n            and not (\\n                --avoid updating the record's valid_to if the latest entry is marked as deleted\\n                snapshotted_data.{{ columns.dbt_is_deleted }} = 'True'\\n                and\\n                {% if config.get('dbt_valid_to_current') -%}\\n                    snapshotted_data.{{ columns.dbt_valid_to }} = {{ config.get('dbt_valid_to_current') }}\\n                {%- else -%}\\n                    snapshotted_data.{{ columns.dbt_valid_to }} is null\\n                {%- endif %}\\n            )\\n            {%- endif %}\\n    )\\n    {%- endif %}\\n\\n    {%- if strategy.hard_deletes == 'new_record' %}\\n        {% set snapshotted_cols = get_list_of_column_names(get_columns_in_relation(target_relation)) %}\\n        {% set source_sql_cols = get_column_schema_from_query(source_sql) %}\\n    ,\\n    deletion_records as (\\n\\n        select\\n            'insert' as dbt_change_type,\\n            {#/*\\n                If a column has been added to the source it won't yet exist in the\\n                snapshotted table so we insert a null value as a placeholder for the column.\\n             */#}\\n            {%- for col in source_sql_cols -%}\\n            {%- if col.name in snapshotted_cols -%}\\n            snapshotted_data.{{ adapter.quote(col.column) }},\\n            {%- else -%}\\n            NULL as {{ adapter.quote(col.column) }},\\n            {%- endif -%}\\n            {% endfor -%}\\n            {%- if strategy.unique_key | is_list -%}\\n                {%- for key in strategy.unique_key -%}\\n            snapshotted_data.{{ key }} as dbt_unique_key_{{ loop.index }},\\n                {% endfor -%}\\n            {%- else -%}\\n            snapshotted_data.dbt_unique_key as dbt_unique_key,\\n            {% endif -%}\\n            {{ snapshot_get_time() }} as {{ columns.dbt_valid_from }},\\n            {{ snapshot_get_time() }} as {{ columns.dbt_updated_at }},\\n            snapshotted_data.{{ columns.dbt_valid_to }} as {{ columns.dbt_valid_to }},\\n            {{ new_scd_id }} as {{ columns.dbt_scd_id }},\\n            'True' as {{ columns.dbt_is_deleted }}\\n        from snapshotted_data\\n        left join deletes_source_data as source_data\\n            on {{ unique_key_join_on(strategy.unique_key, \\\"snapshotted_data\\\", \\\"source_data\\\") }}\\n        where {{ unique_key_is_null(strategy.unique_key, \\\"source_data\\\") }}\\n        and not (\\n            --avoid inserting a new record if the latest one is marked as deleted\\n            snapshotted_data.{{ columns.dbt_is_deleted }} = 'True'\\n            and\\n            {% if config.get('dbt_valid_to_current') -%}\\n                snapshotted_data.{{ columns.dbt_valid_to }} = {{ config.get('dbt_valid_to_current') }}\\n            {%- else -%}\\n                snapshotted_data.{{ columns.dbt_valid_to }} is null\\n            {%- endif %}\\n            )\\n\\n    )\\n    {%- endif %}\\n\\n    select * from insertions\\n    union all\\n    select * from updates\\n    {%- if strategy.hard_deletes == 'invalidate' or strategy.hard_deletes == 'new_record' %}\\n    union all\\n    select * from deletes\\n    {%- endif %}\\n    {%- if strategy.hard_deletes == 'new_record' %}\\n    union all\\n    select * from deletion_records\\n    {%- endif %}\\n\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_snapshot_table_column_names\", \"macro.dbt.snapshot_hash_arguments\", \"macro.dbt.snapshot_get_time\", \"macro.dbt.unique_key_fields\", \"macro.dbt.equals\", \"macro.dbt.get_dbt_valid_to_current\", \"macro.dbt.unique_key_join_on\", \"macro.dbt.unique_key_is_null\", \"macro.dbt.unique_key_is_not_null\", \"macro.dbt.get_list_of_column_names\", \"macro.dbt.get_columns_in_relation\", \"macro.dbt.get_column_schema_from_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.010345, \"supported_languages\": null}, \"macro.dbt.build_snapshot_table\": {\"name\": \"build_snapshot_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.build_snapshot_table\", \"macro_sql\": \"{% macro build_snapshot_table(strategy, sql) -%}\\n  {{ adapter.dispatch('build_snapshot_table', 'dbt')(strategy, sql) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__build_snapshot_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.010355, \"supported_languages\": null}, \"macro.dbt.default__build_snapshot_table\": {\"name\": \"default__build_snapshot_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.default__build_snapshot_table\", \"macro_sql\": \"{% macro default__build_snapshot_table(strategy, sql) %}\\n    {% set columns = config.get('snapshot_table_column_names') or get_snapshot_table_column_names() %}\\n\\n    select *,\\n        {{ strategy.scd_id }} as {{ columns.dbt_scd_id }},\\n        {{ strategy.updated_at }} as {{ columns.dbt_updated_at }},\\n        {{ strategy.updated_at }} as {{ columns.dbt_valid_from }},\\n        {{ get_dbt_valid_to_current(strategy, columns) }}\\n      {%- if strategy.hard_deletes == 'new_record' -%}\\n        , 'False' as {{ columns.dbt_is_deleted }}\\n      {% endif -%}\\n    from (\\n        {{ sql }}\\n    ) sbq\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_snapshot_table_column_names\", \"macro.dbt.get_dbt_valid_to_current\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.010365, \"supported_languages\": null}, \"macro.dbt.build_snapshot_staging_table\": {\"name\": \"build_snapshot_staging_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.build_snapshot_staging_table\", \"macro_sql\": \"{% macro build_snapshot_staging_table(strategy, sql, target_relation) %}\\n    {% set temp_relation = make_temp_relation(target_relation) %}\\n\\n    {% set select = snapshot_staging_table(strategy, sql, target_relation) %}\\n\\n    {% call statement('build_snapshot_staging_relation') %}\\n        {{ create_table_as(True, temp_relation, select) }}\\n    {% endcall %}\\n\\n    {% do return(temp_relation) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.make_temp_relation\", \"macro.dbt.snapshot_staging_table\", \"macro.dbt.statement\", \"macro.dbt.create_table_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.010375, \"supported_languages\": null}, \"macro.dbt.get_updated_at_column_data_type\": {\"name\": \"get_updated_at_column_data_type\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.get_updated_at_column_data_type\", \"macro_sql\": \"{% macro get_updated_at_column_data_type(snapshot_sql) %}\\n    {% set snapshot_sql_column_schema = get_column_schema_from_query(snapshot_sql) %}\\n    {% set dbt_updated_at_data_type = null %}\\n    {% set ns = namespace() -%} {#-- handle for-loop scoping with a namespace --#}\\n    {% set ns.dbt_updated_at_data_type = null -%}\\n    {% for column in snapshot_sql_column_schema %}\\n    {%   if ((column.column == 'dbt_updated_at') or (column.column == 'DBT_UPDATED_AT')) %}\\n    {%     set ns.dbt_updated_at_data_type = column.dtype %}\\n    {%   endif %}\\n    {% endfor %}\\n    {{ return(ns.dbt_updated_at_data_type or none)  }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_column_schema_from_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0103838, \"supported_languages\": null}, \"macro.dbt.check_time_data_types\": {\"name\": \"check_time_data_types\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.check_time_data_types\", \"macro_sql\": \"{% macro check_time_data_types(sql) %}\\n  {% set dbt_updated_at_data_type = get_updated_at_column_data_type(sql) %}\\n  {% set snapshot_get_time_data_type = get_snapshot_get_time_data_type() %}\\n  {% if snapshot_get_time_data_type is not none and dbt_updated_at_data_type is not none and snapshot_get_time_data_type != dbt_updated_at_data_type %}\\n  {%   if exceptions.warn_snapshot_timestamp_data_types %}\\n  {{     exceptions.warn_snapshot_timestamp_data_types(snapshot_get_time_data_type, dbt_updated_at_data_type) }}\\n  {%   endif %}\\n  {% endif %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_updated_at_column_data_type\", \"macro.dbt.get_snapshot_get_time_data_type\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.010397, \"supported_languages\": null}, \"macro.dbt.get_dbt_valid_to_current\": {\"name\": \"get_dbt_valid_to_current\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.get_dbt_valid_to_current\", \"macro_sql\": \"{% macro get_dbt_valid_to_current(strategy, columns) %}\\n  {% set dbt_valid_to_current = config.get('dbt_valid_to_current') or \\\"null\\\" %}\\n  coalesce(nullif({{ strategy.updated_at }}, {{ strategy.updated_at }}), {{dbt_valid_to_current}})\\n  as {{ columns.dbt_valid_to }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0104058, \"supported_languages\": null}, \"macro.dbt.unique_key_fields\": {\"name\": \"unique_key_fields\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.unique_key_fields\", \"macro_sql\": \"{% macro unique_key_fields(unique_key) %}\\n    {% if unique_key | is_list %}\\n        {% for key in unique_key %}\\n            {{ key }} as dbt_unique_key_{{ loop.index }}\\n            {%- if not loop.last %} , {%- endif %}\\n        {% endfor %}\\n    {% else %}\\n        {{ unique_key }} as dbt_unique_key\\n    {% endif %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.010416, \"supported_languages\": null}, \"macro.dbt.unique_key_join_on\": {\"name\": \"unique_key_join_on\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.unique_key_join_on\", \"macro_sql\": \"{% macro unique_key_join_on(unique_key, identifier, from_identifier) %}\\n    {% if unique_key | is_list %}\\n        {% for key in unique_key %}\\n\\t    {% set source_unique_key = (identifier ~ \\\".dbt_unique_key_\\\" ~ loop.index) | trim %}\\n\\t    {% set target_unique_key = (from_identifier ~ \\\".dbt_unique_key_\\\" ~ loop.index) | trim %}\\n\\t    {{ equals(source_unique_key, target_unique_key) }}\\n            {%- if not loop.last %} and {%- endif %}\\n        {% endfor %}\\n    {% else %}\\n        {{ identifier }}.dbt_unique_key = {{ from_identifier }}.dbt_unique_key\\n    {% endif %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.equals\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.010426, \"supported_languages\": null}, \"macro.dbt.unique_key_is_null\": {\"name\": \"unique_key_is_null\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.unique_key_is_null\", \"macro_sql\": \"{% macro unique_key_is_null(unique_key, identifier) %}\\n    {% if unique_key | is_list %}\\n        {{ identifier }}.dbt_unique_key_1 is null\\n    {% else %}\\n        {{ identifier }}.dbt_unique_key is null\\n    {% endif %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.010435, \"supported_languages\": null}, \"macro.dbt.unique_key_is_not_null\": {\"name\": \"unique_key_is_not_null\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.unique_key_is_not_null\", \"macro_sql\": \"{% macro unique_key_is_not_null(unique_key, identifier) %}\\n    {% if unique_key | is_list %}\\n        {{ identifier }}.dbt_unique_key_1 is not null\\n    {% else %}\\n        {{ identifier }}.dbt_unique_key is not null\\n    {% endif %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.010445, \"supported_languages\": null}, \"macro.dbt.materialization_snapshot_default\": {\"name\": \"materialization_snapshot_default\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/snapshot.sql\", \"original_file_path\": \"macros/materializations/snapshots/snapshot.sql\", \"unique_id\": \"macro.dbt.materialization_snapshot_default\", \"macro_sql\": \"{% materialization snapshot, default %}\\n\\n  {%- set target_table = model.get('alias', model.get('name')) -%}\\n\\n  {%- set strategy_name = config.get('strategy') -%}\\n  {%- set unique_key = config.get('unique_key') %}\\n  -- grab current tables grants config for comparision later on\\n  {%- set grant_config = config.get('grants') -%}\\n\\n  {% set target_relation_exists, target_relation = get_or_create_relation(\\n          database=model.database,\\n          schema=model.schema,\\n          identifier=target_table,\\n          type='table') -%}\\n\\n  {%- if not target_relation.is_table -%}\\n    {% do exceptions.relation_wrong_type(target_relation, 'table') %}\\n  {%- endif -%}\\n\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  {% set strategy_macro = strategy_dispatch(strategy_name) %}\\n  {# The model['config'] parameter below is no longer used, but passing anyway for compatibility #}\\n  {# It was a dictionary of config, instead of the config object from the context #}\\n  {% set strategy = strategy_macro(model, \\\"snapshotted_data\\\", \\\"source_data\\\", model['config'], target_relation_exists) %}\\n\\n  {% if not target_relation_exists %}\\n\\n      {% set build_sql = build_snapshot_table(strategy, model['compiled_code']) %}\\n      {% set build_or_select_sql = build_sql %}\\n      {% set final_sql = create_table_as(False, target_relation, build_sql) %}\\n\\n  {% else %}\\n\\n      {% set columns = config.get(\\\"snapshot_table_column_names\\\") or get_snapshot_table_column_names() %}\\n\\n      {{ adapter.assert_valid_snapshot_target_given_strategy(target_relation, columns, strategy) }}\\n\\n      {% set build_or_select_sql = snapshot_staging_table(strategy, sql, target_relation) %}\\n      {% set staging_table = build_snapshot_staging_table(strategy, sql, target_relation) %}\\n\\n      -- this may no-op if the database does not require column expansion\\n      {% do adapter.expand_target_column_types(from_relation=staging_table,\\n                                               to_relation=target_relation) %}\\n\\n      {% set remove_columns = ['dbt_change_type', 'DBT_CHANGE_TYPE', 'dbt_unique_key', 'DBT_UNIQUE_KEY'] %}\\n      {% if unique_key | is_list %}\\n          {% for key in strategy.unique_key %}\\n              {{ remove_columns.append('dbt_unique_key_' + loop.index|string) }}\\n              {{ remove_columns.append('DBT_UNIQUE_KEY_' + loop.index|string) }}\\n          {% endfor %}\\n      {% endif %}\\n\\n      {% set missing_columns = adapter.get_missing_columns(staging_table, target_relation)\\n                                   | rejectattr('name', 'in', remove_columns)\\n                                   | list %}\\n\\n      {% do create_columns(target_relation, missing_columns) %}\\n\\n      {% set source_columns = adapter.get_columns_in_relation(staging_table)\\n                                   | rejectattr('name', 'in', remove_columns)\\n                                   | list %}\\n\\n      {% set quoted_source_columns = [] %}\\n      {% for column in source_columns %}\\n        {% do quoted_source_columns.append(adapter.quote(column.name)) %}\\n      {% endfor %}\\n\\n      {% set final_sql = snapshot_merge_sql(\\n            target = target_relation,\\n            source = staging_table,\\n            insert_cols = quoted_source_columns\\n         )\\n      %}\\n\\n  {% endif %}\\n\\n\\n  {{ check_time_data_types(build_or_select_sql) }}\\n\\n  {% call statement('main') %}\\n      {{ final_sql }}\\n  {% endcall %}\\n\\n  {% set should_revoke = should_revoke(target_relation_exists, full_refresh_mode=False) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {% if not target_relation_exists %}\\n    {% do create_indexes(target_relation) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  {{ adapter.commit() }}\\n\\n  {% if staging_table is defined %}\\n      {% do post_snapshot(staging_table) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{% endmaterialization %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_or_create_relation\", \"macro.dbt.run_hooks\", \"macro.dbt.strategy_dispatch\", \"macro.dbt.build_snapshot_table\", \"macro.dbt.create_table_as\", \"macro.dbt.get_snapshot_table_column_names\", \"macro.dbt.snapshot_staging_table\", \"macro.dbt.build_snapshot_staging_table\", \"macro.dbt.create_columns\", \"macro.dbt.snapshot_merge_sql\", \"macro.dbt.check_time_data_types\", \"macro.dbt.statement\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\", \"macro.dbt.persist_docs\", \"macro.dbt.create_indexes\", \"macro.dbt.post_snapshot\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.010466, \"supported_languages\": [\"sql\"]}, \"macro.dbt.materialization_test_default\": {\"name\": \"materialization_test_default\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/tests/test.sql\", \"original_file_path\": \"macros/materializations/tests/test.sql\", \"unique_id\": \"macro.dbt.materialization_test_default\", \"macro_sql\": \"{%- materialization test, default -%}\\n\\n  {% set relations = [] %}\\n  {% set limit = config.get('limit') %}\\n\\n  {% set sql_with_limit %}\\n    {{ get_limit_subquery_sql(sql, limit) }}\\n  {% endset %}\\n\\n  {% if should_store_failures() %}\\n\\n    {% set identifier = model['alias'] %}\\n    {% set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) %}\\n\\n    {% set store_failures_as = config.get('store_failures_as') %}\\n    -- if `--store-failures` is invoked via command line and `store_failures_as` is not set,\\n    -- config.get('store_failures_as', 'table') returns None, not 'table'\\n    {% if store_failures_as == none %}{% set store_failures_as = 'table' %}{% endif %}\\n    {% if store_failures_as not in ['table', 'view'] %}\\n        {{ exceptions.raise_compiler_error(\\n            \\\"'\\\" ~ store_failures_as ~ \\\"' is not a valid value for `store_failures_as`. \\\"\\n            \\\"Accepted values are: ['ephemeral', 'table', 'view']\\\"\\n        ) }}\\n    {% endif %}\\n\\n    {% set target_relation = api.Relation.create(\\n        identifier=identifier, schema=schema, database=database, type=store_failures_as) -%} %}\\n\\n    {% if old_relation %}\\n        {% do adapter.drop_relation(old_relation) %}\\n    {% endif %}\\n\\n    {% call statement(auto_begin=True) %}\\n        {{ get_create_sql(target_relation, sql_with_limit) }}\\n    {% endcall %}\\n\\n    {% do relations.append(target_relation) %}\\n\\n    {# Since the test failures have already been saved to the database, reuse that result rather than querying again #}\\n    {% set main_sql %}\\n        select *\\n        from {{ target_relation }}\\n    {% endset %}\\n\\n    {{ adapter.commit() }}\\n\\n  {% else %}\\n\\n      {% set main_sql = sql_with_limit %}\\n\\n  {% endif %}\\n\\n  {% set fail_calc = config.get('fail_calc') %}\\n  {% set warn_if = config.get('warn_if') %}\\n  {% set error_if = config.get('error_if') %}\\n\\n  {% call statement('main', fetch_result=True) -%}\\n\\n    {# The limit has already been included above, and we do not want to duplicate it again. We also want to be safe for macro overrides treating `limit` as a required parameter. #}\\n    {{ get_test_sql(main_sql, fail_calc, warn_if, error_if, limit=none)}}\\n\\n  {%- endcall %}\\n\\n  {{ return({'relations': relations}) }}\\n\\n{%- endmaterialization -%}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_limit_subquery_sql\", \"macro.dbt.should_store_failures\", \"macro.dbt.statement\", \"macro.dbt.get_create_sql\", \"macro.dbt.get_test_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0105011, \"supported_languages\": [\"sql\"]}, \"macro.dbt.get_test_sql\": {\"name\": \"get_test_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/tests/helpers.sql\", \"original_file_path\": \"macros/materializations/tests/helpers.sql\", \"unique_id\": \"macro.dbt.get_test_sql\", \"macro_sql\": \"{% macro get_test_sql(main_sql, fail_calc, warn_if, error_if, limit) -%}\\n  {{ adapter.dispatch('get_test_sql', 'dbt')(main_sql, fail_calc, warn_if, error_if, limit) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_test_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.010528, \"supported_languages\": null}, \"macro.dbt.default__get_test_sql\": {\"name\": \"default__get_test_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/tests/helpers.sql\", \"original_file_path\": \"macros/materializations/tests/helpers.sql\", \"unique_id\": \"macro.dbt.default__get_test_sql\", \"macro_sql\": \"{% macro default__get_test_sql(main_sql, fail_calc, warn_if, error_if, limit) -%}\\n    select\\n      {{ fail_calc }} as failures,\\n      {{ fail_calc }} {{ warn_if }} as should_warn,\\n      {{ fail_calc }} {{ error_if }} as should_error\\n    from (\\n      {{ main_sql }}\\n      {{ \\\"limit \\\" ~ limit if limit != none }}\\n    ) dbt_internal_test\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.010539, \"supported_languages\": null}, \"macro.dbt.get_unit_test_sql\": {\"name\": \"get_unit_test_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/tests/helpers.sql\", \"original_file_path\": \"macros/materializations/tests/helpers.sql\", \"unique_id\": \"macro.dbt.get_unit_test_sql\", \"macro_sql\": \"{% macro get_unit_test_sql(main_sql, expected_fixture_sql, expected_column_names) -%}\\n  {{ adapter.dispatch('get_unit_test_sql', 'dbt')(main_sql, expected_fixture_sql, expected_column_names) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_unit_test_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.010549, \"supported_languages\": null}, \"macro.dbt.default__get_unit_test_sql\": {\"name\": \"default__get_unit_test_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/tests/helpers.sql\", \"original_file_path\": \"macros/materializations/tests/helpers.sql\", \"unique_id\": \"macro.dbt.default__get_unit_test_sql\", \"macro_sql\": \"{% macro default__get_unit_test_sql(main_sql, expected_fixture_sql, expected_column_names) -%}\\n-- Build actual result given inputs\\nwith dbt_internal_unit_test_actual as (\\n  select\\n    {% for expected_column_name in expected_column_names %}{{expected_column_name}}{% if not loop.last -%},{% endif %}{%- endfor -%}, {{ dbt.string_literal(\\\"actual\\\") }} as {{ adapter.quote(\\\"actual_or_expected\\\") }}\\n  from (\\n    {{ main_sql }}\\n  ) _dbt_internal_unit_test_actual\\n),\\n-- Build expected result\\ndbt_internal_unit_test_expected as (\\n  select\\n    {% for expected_column_name in expected_column_names %}{{expected_column_name}}{% if not loop.last -%}, {% endif %}{%- endfor -%}, {{ dbt.string_literal(\\\"expected\\\") }} as {{ adapter.quote(\\\"actual_or_expected\\\") }}\\n  from (\\n    {{ expected_fixture_sql }}\\n  ) _dbt_internal_unit_test_expected\\n)\\n-- Union actual and expected results\\nselect * from dbt_internal_unit_test_actual\\nunion all\\nselect * from dbt_internal_unit_test_expected\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.string_literal\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.010559, \"supported_languages\": null}, \"macro.dbt.get_where_subquery\": {\"name\": \"get_where_subquery\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/tests/where_subquery.sql\", \"original_file_path\": \"macros/materializations/tests/where_subquery.sql\", \"unique_id\": \"macro.dbt.get_where_subquery\", \"macro_sql\": \"{% macro get_where_subquery(relation) -%}\\n    {% do return(adapter.dispatch('get_where_subquery', 'dbt')(relation)) %}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_where_subquery\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.010578, \"supported_languages\": null}, \"macro.dbt.default__get_where_subquery\": {\"name\": \"default__get_where_subquery\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/tests/where_subquery.sql\", \"original_file_path\": \"macros/materializations/tests/where_subquery.sql\", \"unique_id\": \"macro.dbt.default__get_where_subquery\", \"macro_sql\": \"{% macro default__get_where_subquery(relation) -%}\\n    {% set where = config.get('where', '') %}\\n    {% if where %}\\n        {%- set filtered -%}\\n            (select * from {{ relation }} where {{ where }}) dbt_subquery\\n        {%- endset -%}\\n        {% do return(filtered) %}\\n    {%- else -%}\\n        {% do return(relation) %}\\n    {%- endif -%}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.010588, \"supported_languages\": null}, \"macro.dbt.materialization_unit_default\": {\"name\": \"materialization_unit_default\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/tests/unit.sql\", \"original_file_path\": \"macros/materializations/tests/unit.sql\", \"unique_id\": \"macro.dbt.materialization_unit_default\", \"macro_sql\": \"{%- materialization unit, default -%}\\n\\n  {% set relations = [] %}\\n\\n  {% set expected_rows = config.get('expected_rows') %}\\n  {% set expected_sql = config.get('expected_sql') %}\\n  {% set tested_expected_column_names = expected_rows[0].keys() if (expected_rows | length ) > 0 else get_columns_in_query(sql) %}\\n\\n  {%- set target_relation = this.incorporate(type='table') -%}\\n  {%- set temp_relation = make_temp_relation(target_relation)-%}\\n  {% do run_query(get_create_table_as_sql(True, temp_relation, get_empty_subquery_sql(sql))) %}\\n  {%- set columns_in_relation = adapter.get_columns_in_relation(temp_relation) -%}\\n  {%- set column_name_to_data_types = {} -%}\\n  {%- set column_name_to_quoted = {} -%}\\n  {%- for column in columns_in_relation -%}\\n  {%-   do column_name_to_data_types.update({column.name|lower: column.data_type}) -%}\\n  {%-   do column_name_to_quoted.update({column.name|lower: column.quoted}) -%}\\n  {%- endfor -%}\\n\\n  {%- set expected_column_names_quoted = [] -%}\\n  {%- for column_name in tested_expected_column_names -%}\\n  {%-   do expected_column_names_quoted.append(column_name_to_quoted[column_name|lower]) -%}\\n  {%- endfor -%}\\n\\n  {% if not expected_sql %}\\n  {%   set expected_sql = get_expected_sql(expected_rows, column_name_to_data_types, column_name_to_quoted) %}\\n  {% endif %}\\n  {% set unit_test_sql = get_unit_test_sql(sql, expected_sql, expected_column_names_quoted) %}\\n\\n  {% call statement('main', fetch_result=True) -%}\\n\\n    {{ unit_test_sql }}\\n\\n  {%- endcall %}\\n\\n  {% do adapter.drop_relation(temp_relation) %}\\n\\n  {{ return({'relations': relations}) }}\\n\\n{%- endmaterialization -%}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_columns_in_query\", \"macro.dbt.make_temp_relation\", \"macro.dbt.run_query\", \"macro.dbt.get_create_table_as_sql\", \"macro.dbt.get_empty_subquery_sql\", \"macro.dbt.get_expected_sql\", \"macro.dbt.get_unit_test_sql\", \"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.010607, \"supported_languages\": [\"sql\"]}, \"macro.dbt.materialization_materialized_view_default\": {\"name\": \"materialization_materialized_view_default\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/materialized_view.sql\", \"original_file_path\": \"macros/materializations/models/materialized_view.sql\", \"unique_id\": \"macro.dbt.materialization_materialized_view_default\", \"macro_sql\": \"{% materialization materialized_view, default %}\\n    {% set existing_relation = load_cached_relation(this) %}\\n    {% set target_relation = this.incorporate(type=this.MaterializedView) %}\\n    {% set intermediate_relation = make_intermediate_relation(target_relation) %}\\n    {% set backup_relation_type = target_relation.MaterializedView if existing_relation is none else existing_relation.type %}\\n    {% set backup_relation = make_backup_relation(target_relation, backup_relation_type) %}\\n\\n    {{ materialized_view_setup(backup_relation, intermediate_relation, pre_hooks) }}\\n\\n        {% set build_sql = materialized_view_get_build_sql(existing_relation, target_relation, backup_relation, intermediate_relation) %}\\n\\n        {% if build_sql == '' %}\\n            {{ materialized_view_execute_no_op(target_relation) }}\\n        {% else %}\\n            {{ materialized_view_execute_build_sql(build_sql, existing_relation, target_relation, post_hooks) }}\\n        {% endif %}\\n\\n    {{ materialized_view_teardown(backup_relation, intermediate_relation, post_hooks) }}\\n\\n    {{ return({'relations': [target_relation]}) }}\\n\\n{% endmaterialization %}\", \"depends_on\": {\"macros\": [\"macro.dbt.load_cached_relation\", \"macro.dbt.make_intermediate_relation\", \"macro.dbt.make_backup_relation\", \"macro.dbt.materialized_view_setup\", \"macro.dbt.materialized_view_get_build_sql\", \"macro.dbt.materialized_view_execute_no_op\", \"macro.dbt.materialized_view_execute_build_sql\", \"macro.dbt.materialized_view_teardown\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.010638, \"supported_languages\": [\"sql\"]}, \"macro.dbt.materialized_view_setup\": {\"name\": \"materialized_view_setup\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/materialized_view.sql\", \"original_file_path\": \"macros/materializations/models/materialized_view.sql\", \"unique_id\": \"macro.dbt.materialized_view_setup\", \"macro_sql\": \"{% macro materialized_view_setup(backup_relation, intermediate_relation, pre_hooks) %}\\n\\n    -- backup_relation and intermediate_relation should not already exist in the database\\n    -- it's possible these exist because of a previous run that exited unexpectedly\\n    {% set preexisting_backup_relation = load_cached_relation(backup_relation) %}\\n    {% set preexisting_intermediate_relation = load_cached_relation(intermediate_relation) %}\\n\\n    -- drop the temp relations if they exist already in the database\\n    {{ drop_relation_if_exists(preexisting_backup_relation) }}\\n    {{ drop_relation_if_exists(preexisting_intermediate_relation) }}\\n\\n    {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.load_cached_relation\", \"macro.dbt.drop_relation_if_exists\", \"macro.dbt.run_hooks\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.010655, \"supported_languages\": null}, \"macro.dbt.materialized_view_teardown\": {\"name\": \"materialized_view_teardown\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/materialized_view.sql\", \"original_file_path\": \"macros/materializations/models/materialized_view.sql\", \"unique_id\": \"macro.dbt.materialized_view_teardown\", \"macro_sql\": \"{% macro materialized_view_teardown(backup_relation, intermediate_relation, post_hooks) %}\\n\\n    -- drop the temp relations if they exist to leave the database clean for the next run\\n    {{ drop_relation_if_exists(backup_relation) }}\\n    {{ drop_relation_if_exists(intermediate_relation) }}\\n\\n    {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.drop_relation_if_exists\", \"macro.dbt.run_hooks\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.010665, \"supported_languages\": null}, \"macro.dbt.materialized_view_get_build_sql\": {\"name\": \"materialized_view_get_build_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/materialized_view.sql\", \"original_file_path\": \"macros/materializations/models/materialized_view.sql\", \"unique_id\": \"macro.dbt.materialized_view_get_build_sql\", \"macro_sql\": \"{% macro materialized_view_get_build_sql(existing_relation, target_relation, backup_relation, intermediate_relation) %}\\n\\n    {% set full_refresh_mode = should_full_refresh() %}\\n\\n    -- determine the scenario we're in: create, full_refresh, alter, refresh data\\n    {% if existing_relation is none %}\\n        {% set build_sql = get_create_materialized_view_as_sql(target_relation, sql) %}\\n    {% elif full_refresh_mode or not existing_relation.is_materialized_view %}\\n        {% set build_sql = get_replace_sql(existing_relation, target_relation, sql) %}\\n    {% else %}\\n\\n        -- get config options\\n        {% set on_configuration_change = config.get('on_configuration_change') %}\\n        {% set configuration_changes = get_materialized_view_configuration_changes(existing_relation, config) %}\\n\\n        {% if configuration_changes is none %}\\n            {% set build_sql = refresh_materialized_view(target_relation) %}\\n\\n        {% elif on_configuration_change == 'apply' %}\\n            {% set build_sql = get_alter_materialized_view_as_sql(target_relation, configuration_changes, sql, existing_relation, backup_relation, intermediate_relation) %}\\n        {% elif on_configuration_change == 'continue' %}\\n            {% set build_sql = '' %}\\n            {{ exceptions.warn(\\\"Configuration changes were identified and `on_configuration_change` was set to `continue` for `\\\" ~ target_relation.render() ~ \\\"`\\\") }}\\n        {% elif on_configuration_change == 'fail' %}\\n            {{ exceptions.raise_fail_fast_error(\\\"Configuration changes were identified and `on_configuration_change` was set to `fail` for `\\\" ~ target_relation.render() ~ \\\"`\\\") }}\\n\\n        {% else %}\\n            -- this only happens if the user provides a value other than `apply`, 'skip', 'fail'\\n            {{ exceptions.raise_compiler_error(\\\"Unexpected configuration scenario\\\") }}\\n\\n        {% endif %}\\n\\n    {% endif %}\\n\\n    {% do return(build_sql) %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.should_full_refresh\", \"macro.dbt.get_create_materialized_view_as_sql\", \"macro.dbt.get_replace_sql\", \"macro.dbt.get_materialized_view_configuration_changes\", \"macro.dbt.refresh_materialized_view\", \"macro.dbt.get_alter_materialized_view_as_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.010675, \"supported_languages\": null}, \"macro.dbt.materialized_view_execute_no_op\": {\"name\": \"materialized_view_execute_no_op\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/materialized_view.sql\", \"original_file_path\": \"macros/materializations/models/materialized_view.sql\", \"unique_id\": \"macro.dbt.materialized_view_execute_no_op\", \"macro_sql\": \"{% macro materialized_view_execute_no_op(target_relation) %}\\n    {% do store_raw_result(\\n        name=\\\"main\\\",\\n        message=\\\"skip \\\" ~ target_relation,\\n        code=\\\"skip\\\",\\n        rows_affected=\\\"-1\\\"\\n    ) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.010688, \"supported_languages\": null}, \"macro.dbt.materialized_view_execute_build_sql\": {\"name\": \"materialized_view_execute_build_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/materialized_view.sql\", \"original_file_path\": \"macros/materializations/models/materialized_view.sql\", \"unique_id\": \"macro.dbt.materialized_view_execute_build_sql\", \"macro_sql\": \"{% macro materialized_view_execute_build_sql(build_sql, existing_relation, target_relation, post_hooks) %}\\n\\n    -- `BEGIN` happens here:\\n    {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n    {% set grant_config = config.get('grants') %}\\n\\n    {% call statement(name=\\\"main\\\") %}\\n        {{ build_sql }}\\n    {% endcall %}\\n\\n    {% set should_revoke = should_revoke(existing_relation, full_refresh_mode=True) %}\\n    {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n    {% do persist_docs(target_relation, model) %}\\n\\n    {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n    {{ adapter.commit() }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.run_hooks\", \"macro.dbt.statement\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\", \"macro.dbt.persist_docs\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.010698, \"supported_languages\": null}, \"macro.dbt.materialization_view_default\": {\"name\": \"materialization_view_default\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/view.sql\", \"original_file_path\": \"macros/materializations/models/view.sql\", \"unique_id\": \"macro.dbt.materialization_view_default\", \"macro_sql\": \"{%- materialization view, default -%}\\n\\n  {%- set existing_relation = load_cached_relation(this) -%}\\n  {%- set target_relation = this.incorporate(type='view') -%}\\n  {%- set intermediate_relation =  make_intermediate_relation(target_relation) -%}\\n\\n  -- the intermediate_relation should not already exist in the database; get_relation\\n  -- will return None in that case. Otherwise, we get a relation that we can drop\\n  -- later, before we try to use this name for the current operation\\n  {%- set preexisting_intermediate_relation = load_cached_relation(intermediate_relation) -%}\\n  /*\\n     This relation (probably) doesn't exist yet. If it does exist, it's a leftover from\\n     a previous run, and we're going to try to drop it immediately. At the end of this\\n     materialization, we're going to rename the \\\"existing_relation\\\" to this identifier,\\n     and then we're going to drop it. In order to make sure we run the correct one of:\\n       - drop view ...\\n       - drop table ...\\n\\n     We need to set the type of this relation to be the type of the existing_relation, if it exists,\\n     or else \\\"view\\\" as a sane default if it does not. Note that if the existing_relation does not\\n     exist, then there is nothing to move out of the way and subsequentally drop. In that case,\\n     this relation will be effectively unused.\\n  */\\n  {%- set backup_relation_type = 'view' if existing_relation is none else existing_relation.type -%}\\n  {%- set backup_relation = make_backup_relation(target_relation, backup_relation_type) -%}\\n  -- as above, the backup_relation should not already exist\\n  {%- set preexisting_backup_relation = load_cached_relation(backup_relation) -%}\\n  -- grab current tables grants config for comparision later on\\n  {% set grant_config = config.get('grants') %}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- drop the temp relations if they exist already in the database\\n  {{ drop_relation_if_exists(preexisting_intermediate_relation) }}\\n  {{ drop_relation_if_exists(preexisting_backup_relation) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  -- build model\\n  {% call statement('main') -%}\\n    {{ get_create_view_as_sql(intermediate_relation, sql) }}\\n  {%- endcall %}\\n\\n  -- cleanup\\n  -- move the existing view out of the way\\n  {% if existing_relation is not none %}\\n     /* Do the equivalent of rename_if_exists. 'existing_relation' could have been dropped\\n        since the variable was first set. */\\n    {% set existing_relation = load_cached_relation(existing_relation) %}\\n    {% if existing_relation is not none %}\\n        {{ adapter.rename_relation(existing_relation, backup_relation) }}\\n    {% endif %}\\n  {% endif %}\\n  {{ adapter.rename_relation(intermediate_relation, target_relation) }}\\n\\n  {% set should_revoke = should_revoke(existing_relation, full_refresh_mode=True) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  {{ adapter.commit() }}\\n\\n  {{ drop_relation_if_exists(backup_relation) }}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{%- endmaterialization -%}\", \"depends_on\": {\"macros\": [\"macro.dbt.load_cached_relation\", \"macro.dbt.make_intermediate_relation\", \"macro.dbt.make_backup_relation\", \"macro.dbt.run_hooks\", \"macro.dbt.drop_relation_if_exists\", \"macro.dbt.statement\", \"macro.dbt.get_create_view_as_sql\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\", \"macro.dbt.persist_docs\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0107179, \"supported_languages\": [\"sql\"]}, \"macro.dbt.materialization_table_default\": {\"name\": \"materialization_table_default\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/table.sql\", \"original_file_path\": \"macros/materializations/models/table.sql\", \"unique_id\": \"macro.dbt.materialization_table_default\", \"macro_sql\": \"{% materialization table, default %}\\n\\n  {%- set existing_relation = load_cached_relation(this) -%}\\n  {%- set target_relation = this.incorporate(type='table') %}\\n  {%- set intermediate_relation =  make_intermediate_relation(target_relation) -%}\\n  -- the intermediate_relation should not already exist in the database; get_relation\\n  -- will return None in that case. Otherwise, we get a relation that we can drop\\n  -- later, before we try to use this name for the current operation\\n  {%- set preexisting_intermediate_relation = load_cached_relation(intermediate_relation) -%}\\n  /*\\n      See ../view/view.sql for more information about this relation.\\n  */\\n  {%- set backup_relation_type = 'table' if existing_relation is none else existing_relation.type -%}\\n  {%- set backup_relation = make_backup_relation(target_relation, backup_relation_type) -%}\\n  -- as above, the backup_relation should not already exist\\n  {%- set preexisting_backup_relation = load_cached_relation(backup_relation) -%}\\n  -- grab current tables grants config for comparision later on\\n  {% set grant_config = config.get('grants') %}\\n\\n  -- drop the temp relations if they exist already in the database\\n  {{ drop_relation_if_exists(preexisting_intermediate_relation) }}\\n  {{ drop_relation_if_exists(preexisting_backup_relation) }}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  -- build model\\n  {% call statement('main') -%}\\n    {{ get_create_table_as_sql(False, intermediate_relation, sql) }}\\n  {%- endcall %}\\n\\n  {% do create_indexes(intermediate_relation) %}\\n\\n  -- cleanup\\n  {% if existing_relation is not none %}\\n     /* Do the equivalent of rename_if_exists. 'existing_relation' could have been dropped\\n        since the variable was first set. */\\n    {% set existing_relation = load_cached_relation(existing_relation) %}\\n    {% if existing_relation is not none %}\\n        {{ adapter.rename_relation(existing_relation, backup_relation) }}\\n    {% endif %}\\n  {% endif %}\\n\\n  {{ adapter.rename_relation(intermediate_relation, target_relation) }}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  {% set should_revoke = should_revoke(existing_relation, full_refresh_mode=True) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  -- `COMMIT` happens here\\n  {{ adapter.commit() }}\\n\\n  -- finally, drop the existing/backup relation after the commit\\n  {{ drop_relation_if_exists(backup_relation) }}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n{% endmaterialization %}\", \"depends_on\": {\"macros\": [\"macro.dbt.load_cached_relation\", \"macro.dbt.make_intermediate_relation\", \"macro.dbt.make_backup_relation\", \"macro.dbt.drop_relation_if_exists\", \"macro.dbt.run_hooks\", \"macro.dbt.statement\", \"macro.dbt.get_create_table_as_sql\", \"macro.dbt.create_indexes\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\", \"macro.dbt.persist_docs\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.010744, \"supported_languages\": [\"sql\"]}, \"macro.dbt.get_quoted_csv\": {\"name\": \"get_quoted_csv\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"unique_id\": \"macro.dbt.get_quoted_csv\", \"macro_sql\": \"{% macro get_quoted_csv(column_names) %}\\n\\n    {% set quoted = [] %}\\n    {% for col in column_names -%}\\n        {%- do quoted.append(adapter.quote(col)) -%}\\n    {%- endfor %}\\n\\n    {%- set dest_cols_csv = quoted | join(', ') -%}\\n    {{ return(dest_cols_csv) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.010772, \"supported_languages\": null}, \"macro.dbt.diff_columns\": {\"name\": \"diff_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"unique_id\": \"macro.dbt.diff_columns\", \"macro_sql\": \"{% macro diff_columns(source_columns, target_columns) %}\\n\\n  {% set result = [] %}\\n  {% set source_names = source_columns | map(attribute = 'column') | list %}\\n  {% set target_names = target_columns | map(attribute = 'column') | list %}\\n\\n   {# --check whether the name attribute exists in the target - this does not perform a data type check #}\\n   {% for sc in source_columns %}\\n     {% if sc.name not in target_names %}\\n        {{ result.append(sc) }}\\n     {% endif %}\\n   {% endfor %}\\n\\n  {{ return(result) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0107882, \"supported_languages\": null}, \"macro.dbt.diff_column_data_types\": {\"name\": \"diff_column_data_types\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"unique_id\": \"macro.dbt.diff_column_data_types\", \"macro_sql\": \"{% macro diff_column_data_types(source_columns, target_columns) %}\\n\\n  {% set result = [] %}\\n  {% for sc in source_columns %}\\n    {% set tc = target_columns | selectattr(\\\"name\\\", \\\"equalto\\\", sc.name) | list | first %}\\n    {% if tc %}\\n      {% if sc.data_type != tc.data_type and not sc.can_expand_to(other_column=tc) %}\\n        {{ result.append( { 'column_name': tc.name, 'new_type': sc.data_type } ) }}\\n      {% endif %}\\n    {% endif %}\\n  {% endfor %}\\n\\n  {{ return(result) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0107992, \"supported_languages\": null}, \"macro.dbt.get_merge_update_columns\": {\"name\": \"get_merge_update_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"unique_id\": \"macro.dbt.get_merge_update_columns\", \"macro_sql\": \"{% macro get_merge_update_columns(merge_update_columns, merge_exclude_columns, dest_columns) %}\\n  {{ return(adapter.dispatch('get_merge_update_columns', 'dbt')(merge_update_columns, merge_exclude_columns, dest_columns)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_merge_update_columns\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0108259, \"supported_languages\": null}, \"macro.dbt.default__get_merge_update_columns\": {\"name\": \"default__get_merge_update_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"unique_id\": \"macro.dbt.default__get_merge_update_columns\", \"macro_sql\": \"{% macro default__get_merge_update_columns(merge_update_columns, merge_exclude_columns, dest_columns) %}\\n  {%- set default_cols = dest_columns | map(attribute=\\\"quoted\\\") | list -%}\\n\\n  {%- if merge_update_columns and merge_exclude_columns -%}\\n    {{ exceptions.raise_compiler_error(\\n        'Model cannot specify merge_update_columns and merge_exclude_columns. Please update model to use only one config'\\n    )}}\\n  {%- elif merge_update_columns -%}\\n    {%- set update_columns = merge_update_columns -%}\\n  {%- elif merge_exclude_columns -%}\\n    {%- set update_columns = [] -%}\\n    {%- for column in dest_columns -%}\\n      {% if column.column | lower not in merge_exclude_columns | map(\\\"lower\\\") | list %}\\n        {%- do update_columns.append(column.quoted) -%}\\n      {% endif %}\\n    {%- endfor -%}\\n  {%- else -%}\\n    {%- set update_columns = default_cols -%}\\n  {%- endif -%}\\n\\n  {{ return(update_columns) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.010836, \"supported_languages\": null}, \"macro.dbt.get_merge_sql\": {\"name\": \"get_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"unique_id\": \"macro.dbt.get_merge_sql\", \"macro_sql\": \"{% macro get_merge_sql(target, source, unique_key, dest_columns, incremental_predicates=none) -%}\\n   -- back compat for old kwarg name\\n  {% set incremental_predicates = kwargs.get('predicates', incremental_predicates) %}\\n  {{ adapter.dispatch('get_merge_sql', 'dbt')(target, source, unique_key, dest_columns, incremental_predicates) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.010859, \"supported_languages\": null}, \"macro.dbt.default__get_merge_sql\": {\"name\": \"default__get_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"unique_id\": \"macro.dbt.default__get_merge_sql\", \"macro_sql\": \"{% macro default__get_merge_sql(target, source, unique_key, dest_columns, incremental_predicates=none) -%}\\n    {%- set predicates = [] if incremental_predicates is none else [] + incremental_predicates -%}\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n    {%- set merge_update_columns = config.get('merge_update_columns') -%}\\n    {%- set merge_exclude_columns = config.get('merge_exclude_columns') -%}\\n    {%- set update_columns = get_merge_update_columns(merge_update_columns, merge_exclude_columns, dest_columns) -%}\\n    {%- set sql_header = config.get('sql_header', none) -%}\\n\\n    {% if unique_key %}\\n        {% if unique_key is sequence and unique_key is not mapping and unique_key is not string %}\\n            {% for key in unique_key %}\\n                {% set this_key_match %}\\n                    DBT_INTERNAL_SOURCE.{{ key }} = DBT_INTERNAL_DEST.{{ key }}\\n                {% endset %}\\n                {% do predicates.append(this_key_match) %}\\n            {% endfor %}\\n        {% else %}\\n            {% set source_unique_key = (\\\"DBT_INTERNAL_SOURCE.\\\" ~ unique_key) | trim %}\\n\\t    {% set target_unique_key = (\\\"DBT_INTERNAL_DEST.\\\" ~ unique_key) | trim %}\\n\\t    {% set unique_key_match = equals(source_unique_key, target_unique_key) | trim %}\\n            {% do predicates.append(unique_key_match) %}\\n        {% endif %}\\n    {% else %}\\n        {% do predicates.append('FALSE') %}\\n    {% endif %}\\n\\n    {{ sql_header if sql_header is not none }}\\n\\n    merge into {{ target }} as DBT_INTERNAL_DEST\\n        using {{ source }} as DBT_INTERNAL_SOURCE\\n        on {{\\\"(\\\" ~ predicates | join(\\\") and (\\\") ~ \\\")\\\"}}\\n\\n    {% if unique_key %}\\n    when matched then update set\\n        {% for column_name in update_columns -%}\\n            {{ column_name }} = DBT_INTERNAL_SOURCE.{{ column_name }}\\n            {%- if not loop.last %}, {%- endif %}\\n        {%- endfor %}\\n    {% endif %}\\n\\n    when not matched then insert\\n        ({{ dest_cols_csv }})\\n    values\\n        ({{ dest_cols_csv }})\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_quoted_csv\", \"macro.dbt.get_merge_update_columns\", \"macro.dbt.equals\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0121658, \"supported_languages\": null}, \"macro.dbt.get_delete_insert_merge_sql\": {\"name\": \"get_delete_insert_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"unique_id\": \"macro.dbt.get_delete_insert_merge_sql\", \"macro_sql\": \"{% macro get_delete_insert_merge_sql(target, source, unique_key, dest_columns, incremental_predicates) -%}\\n  {{ adapter.dispatch('get_delete_insert_merge_sql', 'dbt')(target, source, unique_key, dest_columns, incremental_predicates) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_delete_insert_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.012267, \"supported_languages\": null}, \"macro.dbt.default__get_delete_insert_merge_sql\": {\"name\": \"default__get_delete_insert_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"unique_id\": \"macro.dbt.default__get_delete_insert_merge_sql\", \"macro_sql\": \"{% macro default__get_delete_insert_merge_sql(target, source, unique_key, dest_columns, incremental_predicates) -%}\\n\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n\\n    {% if unique_key %}\\n        {% if unique_key is string %}\\n        {% set unique_key = [unique_key] %}\\n        {% endif %}\\n\\n        {%- set unique_key_str = unique_key|join(', ') -%}\\n\\n        delete from {{ target }} as DBT_INTERNAL_DEST\\n        where ({{ unique_key_str }}) in (\\n            select distinct {{ unique_key_str }}\\n            from {{ source }} as DBT_INTERNAL_SOURCE\\n        )\\n        {%- if incremental_predicates %}\\n            {% for predicate in incremental_predicates %}\\n                and {{ predicate }}\\n            {% endfor %}\\n        {%- endif -%};\\n\\n    {% endif %}\\n\\n    insert into {{ target }} ({{ dest_cols_csv }})\\n    (\\n        select {{ dest_cols_csv }}\\n        from {{ source }}\\n    )\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_quoted_csv\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.012331, \"supported_languages\": null}, \"macro.dbt.get_insert_overwrite_merge_sql\": {\"name\": \"get_insert_overwrite_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"unique_id\": \"macro.dbt.get_insert_overwrite_merge_sql\", \"macro_sql\": \"{% macro get_insert_overwrite_merge_sql(target, source, dest_columns, predicates, include_sql_header=false) -%}\\n  {{ adapter.dispatch('get_insert_overwrite_merge_sql', 'dbt')(target, source, dest_columns, predicates, include_sql_header) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_insert_overwrite_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.012369, \"supported_languages\": null}, \"macro.dbt.default__get_insert_overwrite_merge_sql\": {\"name\": \"default__get_insert_overwrite_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"unique_id\": \"macro.dbt.default__get_insert_overwrite_merge_sql\", \"macro_sql\": \"{% macro default__get_insert_overwrite_merge_sql(target, source, dest_columns, predicates, include_sql_header) -%}\\n    {#-- The only time include_sql_header is True: --#}\\n    {#-- BigQuery + insert_overwrite strategy + \\\"static\\\" partitions config --#}\\n    {#-- We should consider including the sql header at the materialization level instead --#}\\n\\n    {%- set predicates = [] if predicates is none else [] + predicates -%}\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n    {%- set sql_header = config.get('sql_header', none) -%}\\n\\n    {{ sql_header if sql_header is not none and include_sql_header }}\\n\\n    merge into {{ target }} as DBT_INTERNAL_DEST\\n        using {{ source }} as DBT_INTERNAL_SOURCE\\n        on FALSE\\n\\n    when not matched by source\\n        {% if predicates %} and {{ predicates | join(' and ') }} {% endif %}\\n        then delete\\n\\n    when not matched then insert\\n        ({{ dest_cols_csv }})\\n    values\\n        ({{ dest_cols_csv }})\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_quoted_csv\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.012474, \"supported_languages\": null}, \"macro.dbt.is_incremental\": {\"name\": \"is_incremental\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/is_incremental.sql\", \"original_file_path\": \"macros/materializations/models/incremental/is_incremental.sql\", \"unique_id\": \"macro.dbt.is_incremental\", \"macro_sql\": \"{% macro is_incremental() %}\\n    {#-- do not run introspective queries in parsing #}\\n    {% if not execute %}\\n        {{ return(False) }}\\n    {% else %}\\n        {% set relation = adapter.get_relation(this.database, this.schema, this.table) %}\\n        {{ return(relation is not none\\n                  and relation.type == 'table'\\n                  and model.config.materialized == 'incremental'\\n                  and not should_full_refresh()) }}\\n    {% endif %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.should_full_refresh\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.012625, \"supported_languages\": null}, \"macro.dbt.get_incremental_append_sql\": {\"name\": \"get_incremental_append_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.get_incremental_append_sql\", \"macro_sql\": \"{% macro get_incremental_append_sql(arg_dict) %}\\n\\n  {{ return(adapter.dispatch('get_incremental_append_sql', 'dbt')(arg_dict)) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_incremental_append_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.012676, \"supported_languages\": null}, \"macro.dbt.default__get_incremental_append_sql\": {\"name\": \"default__get_incremental_append_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.default__get_incremental_append_sql\", \"macro_sql\": \"{% macro default__get_incremental_append_sql(arg_dict) %}\\n\\n  {% do return(get_insert_into_sql(arg_dict[\\\"target_relation\\\"], arg_dict[\\\"temp_relation\\\"], arg_dict[\\\"dest_columns\\\"])) %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_insert_into_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0126889, \"supported_languages\": null}, \"macro.dbt.get_incremental_delete_insert_sql\": {\"name\": \"get_incremental_delete_insert_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.get_incremental_delete_insert_sql\", \"macro_sql\": \"{% macro get_incremental_delete_insert_sql(arg_dict) %}\\n\\n  {{ return(adapter.dispatch('get_incremental_delete_insert_sql', 'dbt')(arg_dict)) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_incremental_delete_insert_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0126998, \"supported_languages\": null}, \"macro.dbt.default__get_incremental_delete_insert_sql\": {\"name\": \"default__get_incremental_delete_insert_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.default__get_incremental_delete_insert_sql\", \"macro_sql\": \"{% macro default__get_incremental_delete_insert_sql(arg_dict) %}\\n\\n  {% do return(get_delete_insert_merge_sql(arg_dict[\\\"target_relation\\\"], arg_dict[\\\"temp_relation\\\"], arg_dict[\\\"unique_key\\\"], arg_dict[\\\"dest_columns\\\"], arg_dict[\\\"incremental_predicates\\\"])) %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_delete_insert_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0127108, \"supported_languages\": null}, \"macro.dbt.get_incremental_merge_sql\": {\"name\": \"get_incremental_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.get_incremental_merge_sql\", \"macro_sql\": \"{% macro get_incremental_merge_sql(arg_dict) %}\\n\\n  {{ return(adapter.dispatch('get_incremental_merge_sql', 'dbt')(arg_dict)) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_incremental_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.012722, \"supported_languages\": null}, \"macro.dbt.default__get_incremental_merge_sql\": {\"name\": \"default__get_incremental_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.default__get_incremental_merge_sql\", \"macro_sql\": \"{% macro default__get_incremental_merge_sql(arg_dict) %}\\n\\n  {% do return(get_merge_sql(arg_dict[\\\"target_relation\\\"], arg_dict[\\\"temp_relation\\\"], arg_dict[\\\"unique_key\\\"], arg_dict[\\\"dest_columns\\\"], arg_dict[\\\"incremental_predicates\\\"])) %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0127318, \"supported_languages\": null}, \"macro.dbt.get_incremental_insert_overwrite_sql\": {\"name\": \"get_incremental_insert_overwrite_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.get_incremental_insert_overwrite_sql\", \"macro_sql\": \"{% macro get_incremental_insert_overwrite_sql(arg_dict) %}\\n\\n  {{ return(adapter.dispatch('get_incremental_insert_overwrite_sql', 'dbt')(arg_dict)) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_incremental_insert_overwrite_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0127418, \"supported_languages\": null}, \"macro.dbt.default__get_incremental_insert_overwrite_sql\": {\"name\": \"default__get_incremental_insert_overwrite_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.default__get_incremental_insert_overwrite_sql\", \"macro_sql\": \"{% macro default__get_incremental_insert_overwrite_sql(arg_dict) %}\\n\\n  {% do return(get_insert_overwrite_merge_sql(arg_dict[\\\"target_relation\\\"], arg_dict[\\\"temp_relation\\\"], arg_dict[\\\"dest_columns\\\"], arg_dict[\\\"incremental_predicates\\\"])) %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_insert_overwrite_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.012753, \"supported_languages\": null}, \"macro.dbt.get_incremental_default_sql\": {\"name\": \"get_incremental_default_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.get_incremental_default_sql\", \"macro_sql\": \"{% macro get_incremental_default_sql(arg_dict) %}\\n\\n  {{ return(adapter.dispatch('get_incremental_default_sql', 'dbt')(arg_dict)) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_incremental_default_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0127628, \"supported_languages\": null}, \"macro.dbt.default__get_incremental_default_sql\": {\"name\": \"default__get_incremental_default_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.default__get_incremental_default_sql\", \"macro_sql\": \"{% macro default__get_incremental_default_sql(arg_dict) %}\\n\\n  {% do return(get_incremental_append_sql(arg_dict)) %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_incremental_append_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.012773, \"supported_languages\": null}, \"macro.dbt.get_incremental_microbatch_sql\": {\"name\": \"get_incremental_microbatch_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.get_incremental_microbatch_sql\", \"macro_sql\": \"{% macro get_incremental_microbatch_sql(arg_dict) %}\\n\\n  {{ return(adapter.dispatch('get_incremental_microbatch_sql', 'dbt')(arg_dict)) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_incremental_microbatch_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0127969, \"supported_languages\": null}, \"macro.dbt.default__get_incremental_microbatch_sql\": {\"name\": \"default__get_incremental_microbatch_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.default__get_incremental_microbatch_sql\", \"macro_sql\": \"{% macro default__get_incremental_microbatch_sql(arg_dict) %}\\n\\n  {{ exceptions.raise_not_implemented('microbatch materialization strategy not implemented for adapter ' + adapter.type()) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.012822, \"supported_languages\": null}, \"macro.dbt.get_insert_into_sql\": {\"name\": \"get_insert_into_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.get_insert_into_sql\", \"macro_sql\": \"{% macro get_insert_into_sql(target_relation, temp_relation, dest_columns) %}\\n\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n\\n    insert into {{ target_relation }} ({{ dest_cols_csv }})\\n    (\\n        select {{ dest_cols_csv }}\\n        from {{ temp_relation }}\\n    )\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_quoted_csv\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.012835, \"supported_languages\": null}, \"macro.dbt.materialization_incremental_default\": {\"name\": \"materialization_incremental_default\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/incremental.sql\", \"original_file_path\": \"macros/materializations/models/incremental/incremental.sql\", \"unique_id\": \"macro.dbt.materialization_incremental_default\", \"macro_sql\": \"{% materialization incremental, default -%}\\n\\n  -- relations\\n  {%- set existing_relation = load_cached_relation(this) -%}\\n  {%- set target_relation = this.incorporate(type='table') -%}\\n  {%- set temp_relation = make_temp_relation(target_relation)-%}\\n  {%- set intermediate_relation = make_intermediate_relation(target_relation)-%}\\n  {%- set backup_relation_type = 'table' if existing_relation is none else existing_relation.type -%}\\n  {%- set backup_relation = make_backup_relation(target_relation, backup_relation_type) -%}\\n\\n  -- configs\\n  {%- set unique_key = config.get('unique_key') -%}\\n  {%- set full_refresh_mode = (should_full_refresh()  or existing_relation.is_view) -%}\\n  {%- set on_schema_change = incremental_validate_on_schema_change(config.get('on_schema_change'), default='ignore') -%}\\n\\n  -- the temp_ and backup_ relations should not already exist in the database; get_relation\\n  -- will return None in that case. Otherwise, we get a relation that we can drop\\n  -- later, before we try to use this name for the current operation. This has to happen before\\n  -- BEGIN, in a separate transaction\\n  {%- set preexisting_intermediate_relation = load_cached_relation(intermediate_relation)-%}\\n  {%- set preexisting_backup_relation = load_cached_relation(backup_relation) -%}\\n   -- grab current tables grants config for comparision later on\\n  {% set grant_config = config.get('grants') %}\\n  {{ drop_relation_if_exists(preexisting_intermediate_relation) }}\\n  {{ drop_relation_if_exists(preexisting_backup_relation) }}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  {% set to_drop = [] %}\\n\\n  {% set incremental_strategy = config.get('incremental_strategy') or 'default' %}\\n  {% set strategy_sql_macro_func = adapter.get_incremental_strategy_macro(context, incremental_strategy) %}\\n\\n  {% if existing_relation is none %}\\n      {% set build_sql = get_create_table_as_sql(False, target_relation, sql) %}\\n      {% set relation_for_indexes = target_relation %}\\n  {% elif full_refresh_mode %}\\n      {% set build_sql = get_create_table_as_sql(False, intermediate_relation, sql) %}\\n      {% set relation_for_indexes = intermediate_relation %}\\n      {% set need_swap = true %}\\n  {% else %}\\n    {% do run_query(get_create_table_as_sql(True, temp_relation, sql)) %}\\n    {% set relation_for_indexes = temp_relation %}\\n    {% set contract_config = config.get('contract') %}\\n    {% if not contract_config or not contract_config.enforced %}\\n      {% do adapter.expand_target_column_types(\\n               from_relation=temp_relation,\\n               to_relation=target_relation) %}\\n    {% endif %}\\n    {#-- Process schema changes. Returns dict of changes if successful. Use source columns for upserting/merging --#}\\n    {% set dest_columns = process_schema_changes(on_schema_change, temp_relation, existing_relation) %}\\n    {% if not dest_columns %}\\n      {% set dest_columns = adapter.get_columns_in_relation(existing_relation) %}\\n    {% endif %}\\n\\n    {#-- Get the incremental_strategy, the macro to use for the strategy, and build the sql --#}\\n    {% set incremental_predicates = config.get('predicates', none) or config.get('incremental_predicates', none) %}\\n    {% set strategy_arg_dict = ({'target_relation': target_relation, 'temp_relation': temp_relation, 'unique_key': unique_key, 'dest_columns': dest_columns, 'incremental_predicates': incremental_predicates }) %}\\n    {% set build_sql = strategy_sql_macro_func(strategy_arg_dict) %}\\n\\n  {% endif %}\\n\\n  {% call statement(\\\"main\\\") %}\\n      {{ build_sql }}\\n  {% endcall %}\\n\\n  {% if existing_relation is none or existing_relation.is_view or should_full_refresh() %}\\n    {% do create_indexes(relation_for_indexes) %}\\n  {% endif %}\\n\\n  {% if need_swap %}\\n      {% do adapter.rename_relation(target_relation, backup_relation) %}\\n      {% do adapter.rename_relation(intermediate_relation, target_relation) %}\\n      {% do to_drop.append(backup_relation) %}\\n  {% endif %}\\n\\n  {% set should_revoke = should_revoke(existing_relation, full_refresh_mode) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  -- `COMMIT` happens here\\n  {% do adapter.commit() %}\\n\\n  {% for rel in to_drop %}\\n      {% do adapter.drop_relation(rel) %}\\n  {% endfor %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{%- endmaterialization %}\", \"depends_on\": {\"macros\": [\"macro.dbt.load_cached_relation\", \"macro.dbt.make_temp_relation\", \"macro.dbt.make_intermediate_relation\", \"macro.dbt.make_backup_relation\", \"macro.dbt.should_full_refresh\", \"macro.dbt.incremental_validate_on_schema_change\", \"macro.dbt.drop_relation_if_exists\", \"macro.dbt.run_hooks\", \"macro.dbt.get_create_table_as_sql\", \"macro.dbt.run_query\", \"macro.dbt.process_schema_changes\", \"macro.dbt.statement\", \"macro.dbt.create_indexes\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\", \"macro.dbt.persist_docs\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.012867, \"supported_languages\": [\"sql\"]}, \"macro.dbt.incremental_validate_on_schema_change\": {\"name\": \"incremental_validate_on_schema_change\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"original_file_path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"unique_id\": \"macro.dbt.incremental_validate_on_schema_change\", \"macro_sql\": \"{% macro incremental_validate_on_schema_change(on_schema_change, default='ignore') %}\\n\\n   {% if on_schema_change not in ['sync_all_columns', 'append_new_columns', 'fail', 'ignore'] %}\\n\\n     {% set log_message = 'Invalid value for on_schema_change (%s) specified. Setting default value of %s.' % (on_schema_change, default) %}\\n     {% do log(log_message) %}\\n\\n     {{ return(default) }}\\n\\n   {% else %}\\n\\n     {{ return(on_schema_change) }}\\n\\n   {% endif %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.012906, \"supported_languages\": null}, \"macro.dbt.check_for_schema_changes\": {\"name\": \"check_for_schema_changes\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"original_file_path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"unique_id\": \"macro.dbt.check_for_schema_changes\", \"macro_sql\": \"{% macro check_for_schema_changes(source_relation, target_relation) %}\\n\\n  {% set schema_changed = False %}\\n\\n  {%- set source_columns = adapter.get_columns_in_relation(source_relation) -%}\\n  {%- set target_columns = adapter.get_columns_in_relation(target_relation) -%}\\n  {%- set source_not_in_target = diff_columns(source_columns, target_columns) -%}\\n  {%- set target_not_in_source = diff_columns(target_columns, source_columns) -%}\\n\\n  {% set new_target_types = diff_column_data_types(source_columns, target_columns) %}\\n\\n  {% if source_not_in_target != [] %}\\n    {% set schema_changed = True %}\\n  {% elif target_not_in_source != [] or new_target_types != [] %}\\n    {% set schema_changed = True %}\\n  {% elif new_target_types != [] %}\\n    {% set schema_changed = True %}\\n  {% endif %}\\n\\n  {% set changes_dict = {\\n    'schema_changed': schema_changed,\\n    'source_not_in_target': source_not_in_target,\\n    'target_not_in_source': target_not_in_source,\\n    'source_columns': source_columns,\\n    'target_columns': target_columns,\\n    'new_target_types': new_target_types\\n  } %}\\n\\n  {% set msg %}\\n    In {{ target_relation }}:\\n        Schema changed: {{ schema_changed }}\\n        Source columns not in target: {{ source_not_in_target }}\\n        Target columns not in source: {{ target_not_in_source }}\\n        New column types: {{ new_target_types }}\\n  {% endset %}\\n\\n  {% do log(msg) %}\\n\\n  {{ return(changes_dict) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.diff_columns\", \"macro.dbt.diff_column_data_types\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.012925, \"supported_languages\": null}, \"macro.dbt.sync_column_schemas\": {\"name\": \"sync_column_schemas\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"original_file_path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"unique_id\": \"macro.dbt.sync_column_schemas\", \"macro_sql\": \"{% macro sync_column_schemas(on_schema_change, target_relation, schema_changes_dict) %}\\n\\n  {%- set add_to_target_arr = schema_changes_dict['source_not_in_target'] -%}\\n\\n  {%- if on_schema_change == 'append_new_columns'-%}\\n     {%- if add_to_target_arr | length > 0 -%}\\n       {%- do alter_relation_add_remove_columns(target_relation, add_to_target_arr, none) -%}\\n     {%- endif -%}\\n\\n  {% elif on_schema_change == 'sync_all_columns' %}\\n     {%- set remove_from_target_arr = schema_changes_dict['target_not_in_source'] -%}\\n     {%- set new_target_types = schema_changes_dict['new_target_types'] -%}\\n\\n     {% if add_to_target_arr | length > 0 or remove_from_target_arr | length > 0 %}\\n       {%- do alter_relation_add_remove_columns(target_relation, add_to_target_arr, remove_from_target_arr) -%}\\n     {% endif %}\\n\\n     {% if new_target_types != [] %}\\n       {% for ntt in new_target_types %}\\n         {% set column_name = ntt['column_name'] %}\\n         {% set new_type = ntt['new_type'] %}\\n         {% do alter_column_type(target_relation, column_name, new_type) %}\\n       {% endfor %}\\n     {% endif %}\\n\\n  {% endif %}\\n\\n  {% set schema_change_message %}\\n    In {{ target_relation }}:\\n        Schema change approach: {{ on_schema_change }}\\n        Columns added: {{ add_to_target_arr }}\\n        Columns removed: {{ remove_from_target_arr }}\\n        Data types changed: {{ new_target_types }}\\n  {% endset %}\\n\\n  {% do log(schema_change_message) %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.alter_relation_add_remove_columns\", \"macro.dbt.alter_column_type\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0129359, \"supported_languages\": null}, \"macro.dbt.process_schema_changes\": {\"name\": \"process_schema_changes\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"original_file_path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"unique_id\": \"macro.dbt.process_schema_changes\", \"macro_sql\": \"{% macro process_schema_changes(on_schema_change, source_relation, target_relation) %}\\n\\n    {% if on_schema_change == 'ignore' %}\\n\\n     {{ return({}) }}\\n\\n    {% else %}\\n\\n      {% set schema_changes_dict = check_for_schema_changes(source_relation, target_relation) %}\\n\\n      {% if schema_changes_dict['schema_changed'] %}\\n\\n        {% if on_schema_change == 'fail' %}\\n\\n          {% set fail_msg %}\\n              The source and target schemas on this incremental model are out of sync!\\n              They can be reconciled in several ways:\\n                - set the `on_schema_change` config to either append_new_columns or sync_all_columns, depending on your situation.\\n                - Re-run the incremental model with `full_refresh: True` to update the target schema.\\n                - update the schema manually and re-run the process.\\n\\n              Additional troubleshooting context:\\n                 Source columns not in target: {{ schema_changes_dict['source_not_in_target'] }}\\n                 Target columns not in source: {{ schema_changes_dict['target_not_in_source'] }}\\n                 New column types: {{ schema_changes_dict['new_target_types'] }}\\n          {% endset %}\\n\\n          {% do exceptions.raise_compiler_error(fail_msg) %}\\n\\n        {# -- unless we ignore, run the sync operation per the config #}\\n        {% else %}\\n\\n          {% do sync_column_schemas(on_schema_change, target_relation, schema_changes_dict) %}\\n\\n        {% endif %}\\n\\n      {% endif %}\\n\\n      {{ return(schema_changes_dict['source_columns']) }}\\n\\n    {% endif %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.check_for_schema_changes\", \"macro.dbt.sync_column_schemas\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.012948, \"supported_languages\": null}, \"macro.dbt.can_clone_table\": {\"name\": \"can_clone_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/clone/can_clone_table.sql\", \"original_file_path\": \"macros/materializations/models/clone/can_clone_table.sql\", \"unique_id\": \"macro.dbt.can_clone_table\", \"macro_sql\": \"{% macro can_clone_table() %}\\n    {{ return(adapter.dispatch('can_clone_table', 'dbt')()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__can_clone_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.012969, \"supported_languages\": null}, \"macro.dbt.default__can_clone_table\": {\"name\": \"default__can_clone_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/clone/can_clone_table.sql\", \"original_file_path\": \"macros/materializations/models/clone/can_clone_table.sql\", \"unique_id\": \"macro.dbt.default__can_clone_table\", \"macro_sql\": \"{% macro default__can_clone_table() %}\\n    {{ return(False) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.01298, \"supported_languages\": null}, \"macro.dbt.create_or_replace_clone\": {\"name\": \"create_or_replace_clone\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/clone/create_or_replace_clone.sql\", \"original_file_path\": \"macros/materializations/models/clone/create_or_replace_clone.sql\", \"unique_id\": \"macro.dbt.create_or_replace_clone\", \"macro_sql\": \"{% macro create_or_replace_clone(this_relation, defer_relation) %}\\n    {{ return(adapter.dispatch('create_or_replace_clone', 'dbt')(this_relation, defer_relation)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__create_or_replace_clone\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.013037, \"supported_languages\": null}, \"macro.dbt.default__create_or_replace_clone\": {\"name\": \"default__create_or_replace_clone\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/clone/create_or_replace_clone.sql\", \"original_file_path\": \"macros/materializations/models/clone/create_or_replace_clone.sql\", \"unique_id\": \"macro.dbt.default__create_or_replace_clone\", \"macro_sql\": \"{% macro default__create_or_replace_clone(this_relation, defer_relation) %}\\n    create or replace table {{ this_relation.render() }} clone {{ defer_relation.render() }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0130482, \"supported_languages\": null}, \"macro.dbt.materialization_clone_default\": {\"name\": \"materialization_clone_default\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/clone/clone.sql\", \"original_file_path\": \"macros/materializations/models/clone/clone.sql\", \"unique_id\": \"macro.dbt.materialization_clone_default\", \"macro_sql\": \"{%- materialization clone, default -%}\\n\\n  {%- set relations = {'relations': []} -%}\\n\\n  {%- if not defer_relation -%}\\n      -- nothing to do\\n      {{ log(\\\"No relation found in state manifest for \\\" ~ model.unique_id, info=True) }}\\n      {{ return(relations) }}\\n  {%- endif -%}\\n\\n  {%- set existing_relation = load_cached_relation(this) -%}\\n\\n  {%- if existing_relation and not flags.FULL_REFRESH -%}\\n      -- noop!\\n      {{ log(\\\"Relation \\\" ~ existing_relation ~ \\\" already exists\\\", info=True) }}\\n      {{ return(relations) }}\\n  {%- endif -%}\\n\\n  {%- set other_existing_relation = load_cached_relation(defer_relation) -%}\\n\\n  -- If this is a database that can do zero-copy cloning of tables, and the other relation is a table, then this will be a table\\n  -- Otherwise, this will be a view\\n\\n  {% set can_clone_table = can_clone_table() %}\\n\\n  {%- if other_existing_relation and other_existing_relation.type == 'table' and can_clone_table -%}\\n\\n      {%- set target_relation = this.incorporate(type='table') -%}\\n      {% if existing_relation is not none and not existing_relation.is_table %}\\n        {{ log(\\\"Dropping relation \\\" ~ existing_relation.render() ~ \\\" because it is of type \\\" ~ existing_relation.type) }}\\n        {{ drop_relation_if_exists(existing_relation) }}\\n      {% endif %}\\n\\n      -- as a general rule, data platforms that can clone tables can also do atomic 'create or replace'\\n      {% if target_relation.database == defer_relation.database and\\n            target_relation.schema == defer_relation.schema and\\n            target_relation.identifier == defer_relation.identifier %}\\n        {{ log(\\\"Target relation and defer relation are the same, skipping clone for relation: \\\" ~ target_relation.render()) }}\\n      {% else %}\\n        {% call statement('main') %}\\n            {{ create_or_replace_clone(target_relation, defer_relation) }}\\n        {% endcall %}\\n      {% endif %}\\n      {% set should_revoke = should_revoke(existing_relation, full_refresh_mode=True) %}\\n      {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n      {% do persist_docs(target_relation, model) %}\\n\\n      {{ return({'relations': [target_relation]}) }}\\n\\n  {%- else -%}\\n\\n      {%- set target_relation = this.incorporate(type='view') -%}\\n\\n      -- reuse the view materialization\\n      -- TODO: support actual dispatch for materialization macros\\n      -- Tracking ticket: https://github.com/dbt-labs/dbt-core/issues/7799\\n      {% set search_name = \\\"materialization_view_\\\" ~ adapter.type() %}\\n      {% if not search_name in context %}\\n          {% set search_name = \\\"materialization_view_default\\\" %}\\n      {% endif %}\\n      {% set materialization_macro = context[search_name] %}\\n      {% set relations = materialization_macro() %}\\n      {{ return(relations) }}\\n\\n  {%- endif -%}\\n\\n{%- endmaterialization -%}\", \"depends_on\": {\"macros\": [\"macro.dbt.load_cached_relation\", \"macro.dbt.can_clone_table\", \"macro.dbt.drop_relation_if_exists\", \"macro.dbt.statement\", \"macro.dbt.create_or_replace_clone\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\", \"macro.dbt.persist_docs\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.013071, \"supported_languages\": [\"sql\"]}, \"macro.dbt.materialization_seed_default\": {\"name\": \"materialization_seed_default\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/seed.sql\", \"original_file_path\": \"macros/materializations/seeds/seed.sql\", \"unique_id\": \"macro.dbt.materialization_seed_default\", \"macro_sql\": \"{% materialization seed, default %}\\n\\n  {%- set identifier = model['alias'] -%}\\n  {%- set full_refresh_mode = (should_full_refresh()) -%}\\n\\n  {%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%}\\n\\n  {%- set exists_as_table = (old_relation is not none and old_relation.is_table) -%}\\n  {%- set exists_as_view = (old_relation is not none and old_relation.is_view) -%}\\n\\n  {%- set grant_config = config.get('grants') -%}\\n  {%- set agate_table = load_agate_table() -%}\\n  -- grab current tables grants config for comparison later on\\n\\n  {%- do store_result('agate_table', response='OK', agate_table=agate_table) -%}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  -- build model\\n  {% set create_table_sql = \\\"\\\" %}\\n  {% if exists_as_view %}\\n    {{ exceptions.raise_compiler_error(\\\"Cannot seed to '{}', it is a view\\\".format(old_relation.render())) }}\\n  {% elif exists_as_table %}\\n    {% set create_table_sql = reset_csv_table(model, full_refresh_mode, old_relation, agate_table) %}\\n  {% else %}\\n    {% set create_table_sql = create_csv_table(model, agate_table) %}\\n  {% endif %}\\n\\n  {% set code = 'CREATE' if full_refresh_mode else 'INSERT' %}\\n  {% set rows_affected = (agate_table.rows | length) %}\\n  {% set sql = load_csv_rows(model, agate_table) %}\\n\\n  {% call noop_statement('main', code ~ ' ' ~ rows_affected, code, rows_affected) %}\\n    {{ get_csv_sql(create_table_sql, sql) }};\\n  {% endcall %}\\n\\n  {% set target_relation = this.incorporate(type='table') %}\\n\\n  {% set should_revoke = should_revoke(old_relation, full_refresh_mode) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {% if full_refresh_mode or not exists_as_table %}\\n    {% do create_indexes(target_relation) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  -- `COMMIT` happens here\\n  {{ adapter.commit() }}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{% endmaterialization %}\", \"depends_on\": {\"macros\": [\"macro.dbt.should_full_refresh\", \"macro.dbt.run_hooks\", \"macro.dbt.reset_csv_table\", \"macro.dbt.create_csv_table\", \"macro.dbt.load_csv_rows\", \"macro.dbt.noop_statement\", \"macro.dbt.get_csv_sql\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\", \"macro.dbt.persist_docs\", \"macro.dbt.create_indexes\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.013102, \"supported_languages\": [\"sql\"]}, \"macro.dbt.create_csv_table\": {\"name\": \"create_csv_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.create_csv_table\", \"macro_sql\": \"{% macro create_csv_table(model, agate_table) -%}\\n  {{ adapter.dispatch('create_csv_table', 'dbt')(model, agate_table) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__create_csv_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0131352, \"supported_languages\": null}, \"macro.dbt.default__create_csv_table\": {\"name\": \"default__create_csv_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.default__create_csv_table\", \"macro_sql\": \"{% macro default__create_csv_table(model, agate_table) %}\\n  {%- set column_override = model['config'].get('column_types', {}) -%}\\n  {%- set quote_seed_column = model['config'].get('quote_columns', None) -%}\\n\\n  {% set sql %}\\n    create table {{ this.render() }} (\\n        {%- for col_name in agate_table.column_names -%}\\n            {%- set inferred_type = adapter.convert_type(agate_table, loop.index0) -%}\\n            {%- set type = column_override.get(col_name, inferred_type) -%}\\n            {%- set column_name = (col_name | string) -%}\\n            {{ adapter.quote_seed_column(column_name, quote_seed_column) }} {{ type }} {%- if not loop.last -%}, {%- endif -%}\\n        {%- endfor -%}\\n    )\\n  {% endset %}\\n\\n  {% call statement('_') -%}\\n    {{ sql }}\\n  {%- endcall %}\\n\\n  {{ return(sql) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0131462, \"supported_languages\": null}, \"macro.dbt.reset_csv_table\": {\"name\": \"reset_csv_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.reset_csv_table\", \"macro_sql\": \"{% macro reset_csv_table(model, full_refresh, old_relation, agate_table) -%}\\n  {{ adapter.dispatch('reset_csv_table', 'dbt')(model, full_refresh, old_relation, agate_table) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__reset_csv_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.01316, \"supported_languages\": null}, \"macro.dbt.default__reset_csv_table\": {\"name\": \"default__reset_csv_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.default__reset_csv_table\", \"macro_sql\": \"{% macro default__reset_csv_table(model, full_refresh, old_relation, agate_table) %}\\n    {% set sql = \\\"\\\" %}\\n    {% if full_refresh %}\\n        {{ adapter.drop_relation(old_relation) }}\\n        {% set sql = create_csv_table(model, agate_table) %}\\n    {% else %}\\n        {{ adapter.truncate_relation(old_relation) }}\\n        {% set sql = \\\"truncate table \\\" ~ old_relation.render() %}\\n    {% endif %}\\n\\n    {{ return(sql) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.create_csv_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.013171, \"supported_languages\": null}, \"macro.dbt.get_csv_sql\": {\"name\": \"get_csv_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.get_csv_sql\", \"macro_sql\": \"{% macro get_csv_sql(create_or_truncate_sql, insert_sql) %}\\n    {{ adapter.dispatch('get_csv_sql', 'dbt')(create_or_truncate_sql, insert_sql) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_csv_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.013224, \"supported_languages\": null}, \"macro.dbt.default__get_csv_sql\": {\"name\": \"default__get_csv_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.default__get_csv_sql\", \"macro_sql\": \"{% macro default__get_csv_sql(create_or_truncate_sql, insert_sql) %}\\n    {{ create_or_truncate_sql }};\\n    -- dbt seed --\\n    {{ insert_sql }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.013238, \"supported_languages\": null}, \"macro.dbt.get_binding_char\": {\"name\": \"get_binding_char\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.get_binding_char\", \"macro_sql\": \"{% macro get_binding_char() -%}\\n  {{ adapter.dispatch('get_binding_char', 'dbt')() }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_binding_char\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.013248, \"supported_languages\": null}, \"macro.dbt.default__get_binding_char\": {\"name\": \"default__get_binding_char\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.default__get_binding_char\", \"macro_sql\": \"{% macro default__get_binding_char() %}\\n  {{ return('%s') }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.013259, \"supported_languages\": null}, \"macro.dbt.get_batch_size\": {\"name\": \"get_batch_size\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.get_batch_size\", \"macro_sql\": \"{% macro get_batch_size() -%}\\n  {{ return(adapter.dispatch('get_batch_size', 'dbt')()) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_batch_size\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.01327, \"supported_languages\": null}, \"macro.dbt.default__get_batch_size\": {\"name\": \"default__get_batch_size\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.default__get_batch_size\", \"macro_sql\": \"{% macro default__get_batch_size() %}\\n  {{ return(10000) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.01328, \"supported_languages\": null}, \"macro.dbt.get_seed_column_quoted_csv\": {\"name\": \"get_seed_column_quoted_csv\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.get_seed_column_quoted_csv\", \"macro_sql\": \"{% macro get_seed_column_quoted_csv(model, column_names) %}\\n  {%- set quote_seed_column = model['config'].get('quote_columns', None) -%}\\n    {% set quoted = [] %}\\n    {% for col in column_names -%}\\n        {%- do quoted.append(adapter.quote_seed_column(col, quote_seed_column)) -%}\\n    {%- endfor %}\\n\\n    {%- set dest_cols_csv = quoted | join(', ') -%}\\n    {{ return(dest_cols_csv) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.01329, \"supported_languages\": null}, \"macro.dbt.load_csv_rows\": {\"name\": \"load_csv_rows\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.load_csv_rows\", \"macro_sql\": \"{% macro load_csv_rows(model, agate_table) -%}\\n  {{ adapter.dispatch('load_csv_rows', 'dbt')(model, agate_table) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__load_csv_rows\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.013301, \"supported_languages\": null}, \"macro.dbt.default__load_csv_rows\": {\"name\": \"default__load_csv_rows\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.default__load_csv_rows\", \"macro_sql\": \"{% macro default__load_csv_rows(model, agate_table) %}\\n\\n  {% set batch_size = get_batch_size() %}\\n\\n  {% set cols_sql = get_seed_column_quoted_csv(model, agate_table.column_names) %}\\n  {% set bindings = [] %}\\n\\n  {% set statements = [] %}\\n\\n  {% for chunk in agate_table.rows | batch(batch_size) %}\\n      {% set bindings = [] %}\\n\\n      {% for row in chunk %}\\n          {% do bindings.extend(row) %}\\n      {% endfor %}\\n\\n      {% set sql %}\\n          insert into {{ this.render() }} ({{ cols_sql }}) values\\n          {% for row in chunk -%}\\n              ({%- for column in agate_table.column_names -%}\\n                  {{ get_binding_char() }}\\n                  {%- if not loop.last%},{%- endif %}\\n              {%- endfor -%})\\n              {%- if not loop.last%},{%- endif %}\\n          {%- endfor %}\\n      {% endset %}\\n\\n      {% do adapter.add_query(sql, bindings=bindings, abridge_sql_log=True) %}\\n\\n      {% if loop.index0 == 0 %}\\n          {% do statements.append(sql) %}\\n      {% endif %}\\n  {% endfor %}\\n\\n  {# Return SQL so we can render it out into the compiled files #}\\n  {{ return(statements[0]) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_batch_size\", \"macro.dbt.get_seed_column_quoted_csv\", \"macro.dbt.get_binding_char\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.013311, \"supported_languages\": null}, \"macro.dbt.scalar_function_sql\": {\"name\": \"scalar_function_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/functions/scalar.sql\", \"original_file_path\": \"macros/materializations/functions/scalar.sql\", \"unique_id\": \"macro.dbt.scalar_function_sql\", \"macro_sql\": \"{% macro scalar_function_sql(target_relation) %}\\n    {{ return(adapter.dispatch('scalar_function_sql', 'dbt')(target_relation)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__scalar_function_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.013334, \"supported_languages\": null}, \"macro.dbt.default__scalar_function_sql\": {\"name\": \"default__scalar_function_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/functions/scalar.sql\", \"original_file_path\": \"macros/materializations/functions/scalar.sql\", \"unique_id\": \"macro.dbt.default__scalar_function_sql\", \"macro_sql\": \"{% macro default__scalar_function_sql(target_relation) %}\\n    {{ scalar_function_create_replace_signature_sql(target_relation) }}\\n    {{ scalar_function_body_sql() }};\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.scalar_function_create_replace_signature_sql\", \"macro.dbt.scalar_function_body_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0133471, \"supported_languages\": null}, \"macro.dbt.scalar_function_create_replace_signature_sql\": {\"name\": \"scalar_function_create_replace_signature_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/functions/scalar.sql\", \"original_file_path\": \"macros/materializations/functions/scalar.sql\", \"unique_id\": \"macro.dbt.scalar_function_create_replace_signature_sql\", \"macro_sql\": \"{% macro scalar_function_create_replace_signature_sql(target_relation) %}\\n    {{ return(adapter.dispatch('scalar_function_create_replace_signature_sql', 'dbt')(target_relation)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__scalar_function_create_replace_signature_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.013358, \"supported_languages\": null}, \"macro.dbt.default__scalar_function_create_replace_signature_sql\": {\"name\": \"default__scalar_function_create_replace_signature_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/functions/scalar.sql\", \"original_file_path\": \"macros/materializations/functions/scalar.sql\", \"unique_id\": \"macro.dbt.default__scalar_function_create_replace_signature_sql\", \"macro_sql\": \"{% macro default__scalar_function_create_replace_signature_sql(target_relation) %}\\n    CREATE OR REPLACE FUNCTION {{ target_relation.render() }} ({{ formatted_scalar_function_args_sql()}}) RETURNS {{ model.return_type.type }} AS\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.formatted_scalar_function_args_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0133681, \"supported_languages\": null}, \"macro.dbt.formatted_scalar_function_args_sql\": {\"name\": \"formatted_scalar_function_args_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/functions/scalar.sql\", \"original_file_path\": \"macros/materializations/functions/scalar.sql\", \"unique_id\": \"macro.dbt.formatted_scalar_function_args_sql\", \"macro_sql\": \"{% macro formatted_scalar_function_args_sql() %}\\n    {{ return(adapter.dispatch('formatted_scalar_function_args_sql', 'dbt')()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__formatted_scalar_function_args_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0133839, \"supported_languages\": null}, \"macro.dbt.default__formatted_scalar_function_args_sql\": {\"name\": \"default__formatted_scalar_function_args_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/functions/scalar.sql\", \"original_file_path\": \"macros/materializations/functions/scalar.sql\", \"unique_id\": \"macro.dbt.default__formatted_scalar_function_args_sql\", \"macro_sql\": \"{% macro default__formatted_scalar_function_args_sql() %}\\n    {% set args = [] %}\\n    {% for arg in model.arguments -%}\\n        {%- do args.append(arg.name ~ ' ' ~ arg.type) -%}\\n    {%- endfor %}\\n    {{ args | join(', ') }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0133948, \"supported_languages\": null}, \"macro.dbt.scalar_function_body_sql\": {\"name\": \"scalar_function_body_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/functions/scalar.sql\", \"original_file_path\": \"macros/materializations/functions/scalar.sql\", \"unique_id\": \"macro.dbt.scalar_function_body_sql\", \"macro_sql\": \"{% macro scalar_function_body_sql() %}\\n    {{ return(adapter.dispatch('scalar_function_body_sql', 'dbt')()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__scalar_function_body_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0134048, \"supported_languages\": null}, \"macro.dbt.default__scalar_function_body_sql\": {\"name\": \"default__scalar_function_body_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/functions/scalar.sql\", \"original_file_path\": \"macros/materializations/functions/scalar.sql\", \"unique_id\": \"macro.dbt.default__scalar_function_body_sql\", \"macro_sql\": \"{% macro default__scalar_function_body_sql() %}\\n    $$\\n       {{ model.compiled_code }}\\n    $$ LANGUAGE SQL\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.013416, \"supported_languages\": null}, \"macro.dbt.function_execute_build_sql\": {\"name\": \"function_execute_build_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/functions/helpers.sql\", \"original_file_path\": \"macros/materializations/functions/helpers.sql\", \"unique_id\": \"macro.dbt.function_execute_build_sql\", \"macro_sql\": \"{% macro function_execute_build_sql(build_sql, existing_relation, target_relation) %}\\n    {{ return(adapter.dispatch('function_execute_build_sql', 'dbt')(build_sql, existing_relation, target_relation)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__function_execute_build_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.013437, \"supported_languages\": null}, \"macro.dbt.default__function_execute_build_sql\": {\"name\": \"default__function_execute_build_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/functions/helpers.sql\", \"original_file_path\": \"macros/materializations/functions/helpers.sql\", \"unique_id\": \"macro.dbt.default__function_execute_build_sql\", \"macro_sql\": \"{% macro default__function_execute_build_sql(build_sql, existing_relation, target_relation) %}\\n\\n    {% set grant_config = config.get('grants') %}\\n\\n    {% call statement(name=\\\"main\\\") %}\\n        {{ build_sql }}\\n    {% endcall %}\\n\\n    {% set should_revoke = should_revoke(existing_relation, full_refresh_mode=True) %}\\n    {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n    {% do persist_docs(target_relation, model) %}\\n\\n    {{ adapter.commit() }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\", \"macro.dbt.persist_docs\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0134468, \"supported_languages\": null}, \"macro.dbt.get_function_macro\": {\"name\": \"get_function_macro\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/functions/helpers.sql\", \"original_file_path\": \"macros/materializations/functions/helpers.sql\", \"unique_id\": \"macro.dbt.get_function_macro\", \"macro_sql\": \"{% macro get_function_macro(function_type, function_language) %}\\n    {{ return(adapter.dispatch('get_function_macro', 'dbt')(function_type, function_language)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_function_macro\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.013458, \"supported_languages\": null}, \"macro.dbt.default__get_function_macro\": {\"name\": \"default__get_function_macro\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/functions/helpers.sql\", \"original_file_path\": \"macros/materializations/functions/helpers.sql\", \"unique_id\": \"macro.dbt.default__get_function_macro\", \"macro_sql\": \"{% macro default__get_function_macro(function_type, function_language) %}\\n    {% set macro_name = function_type ~ \\\"_function_\\\" ~ function_language %}\\n    {% if not macro_name in context %}\\n        {{ exceptions.raise_not_implemented(function_language ~ ' ' ~ function_type ~ ' function not implemented for adapter ' ~adapter.type()) }}\\n    {% endif %}\\n    {% set macro = context[macro_name] %}\\n    {{ return(macro) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0134678, \"supported_languages\": null}, \"macro.dbt.materialization_function_default\": {\"name\": \"materialization_function_default\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/functions/function.sql\", \"original_file_path\": \"macros/materializations/functions/function.sql\", \"unique_id\": \"macro.dbt.materialization_function_default\", \"macro_sql\": \"{% materialization function, default %}\\n    {% set existing_relation = load_cached_relation(this) %}\\n    {% set target_relation = this.incorporate(type=this.Function) %}\\n\\n    {{ run_hooks(pre_hooks) }}\\n\\n    {% set function_type_macro = get_function_macro('scalar', 'sql') %}\\n    {% set build_sql = function_type_macro(target_relation) %}\\n\\n    {{ function_execute_build_sql(build_sql, existing_relation, target_relation) }}\\n\\n    {{ run_hooks(post_hooks) }}\\n\\n    {{ return({'relations': [target_relation]}) }}\\n\\n{% endmaterialization %}\", \"depends_on\": {\"macros\": [\"macro.dbt.load_cached_relation\", \"macro.dbt.run_hooks\", \"macro.dbt.get_function_macro\", \"macro.dbt.function_execute_build_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.01349, \"supported_languages\": [\"sql\"]}, \"macro.dbt.generate_alias_name\": {\"name\": \"generate_alias_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/get_custom_name/get_custom_alias.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_alias.sql\", \"unique_id\": \"macro.dbt.generate_alias_name\", \"macro_sql\": \"{% macro generate_alias_name(custom_alias_name=none, node=none) -%}\\n    {% do return(adapter.dispatch('generate_alias_name', 'dbt')(custom_alias_name, node)) %}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__generate_alias_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.013665, \"supported_languages\": null}, \"macro.dbt.default__generate_alias_name\": {\"name\": \"default__generate_alias_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/get_custom_name/get_custom_alias.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_alias.sql\", \"unique_id\": \"macro.dbt.default__generate_alias_name\", \"macro_sql\": \"{% macro default__generate_alias_name(custom_alias_name=none, node=none) -%}\\n\\n    {%- if custom_alias_name -%}\\n\\n        {{ custom_alias_name | trim }}\\n\\n    {%- elif node.version -%}\\n\\n        {{ return(node.name ~ \\\"_v\\\" ~ (node.version | replace(\\\".\\\", \\\"_\\\"))) }}\\n\\n    {%- else -%}\\n\\n        {{ node.name }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0136828, \"supported_languages\": null}, \"macro.dbt.generate_schema_name\": {\"name\": \"generate_schema_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/get_custom_name/get_custom_schema.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_schema.sql\", \"unique_id\": \"macro.dbt.generate_schema_name\", \"macro_sql\": \"{% macro generate_schema_name(custom_schema_name=none, node=none) -%}\\n    {{ return(adapter.dispatch('generate_schema_name', 'dbt')(custom_schema_name, node)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__generate_schema_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.013712, \"supported_languages\": null}, \"macro.dbt.default__generate_schema_name\": {\"name\": \"default__generate_schema_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/get_custom_name/get_custom_schema.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_schema.sql\", \"unique_id\": \"macro.dbt.default__generate_schema_name\", \"macro_sql\": \"{% macro default__generate_schema_name(custom_schema_name, node) -%}\\n\\n    {%- set default_schema = target.schema -%}\\n    {%- if custom_schema_name is none -%}\\n\\n        {{ default_schema }}\\n\\n    {%- else -%}\\n\\n        {{ default_schema }}_{{ custom_schema_name | trim }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0137239, \"supported_languages\": null}, \"macro.dbt.generate_schema_name_for_env\": {\"name\": \"generate_schema_name_for_env\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/get_custom_name/get_custom_schema.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_schema.sql\", \"unique_id\": \"macro.dbt.generate_schema_name_for_env\", \"macro_sql\": \"{% macro generate_schema_name_for_env(custom_schema_name, node) -%}\\n\\n    {%- set default_schema = target.schema -%}\\n    {%- if target.name == 'prod' and custom_schema_name is not none -%}\\n\\n        {{ custom_schema_name | trim }}\\n\\n    {%- else -%}\\n\\n        {{ default_schema }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0137348, \"supported_languages\": null}, \"macro.dbt.generate_database_name\": {\"name\": \"generate_database_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/get_custom_name/get_custom_database.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_database.sql\", \"unique_id\": \"macro.dbt.generate_database_name\", \"macro_sql\": \"{% macro generate_database_name(custom_database_name=none, node=none) -%}\\n    {% do return(adapter.dispatch('generate_database_name', 'dbt')(custom_database_name, node)) %}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__generate_database_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0137558, \"supported_languages\": null}, \"macro.dbt.default__generate_database_name\": {\"name\": \"default__generate_database_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/get_custom_name/get_custom_database.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_database.sql\", \"unique_id\": \"macro.dbt.default__generate_database_name\", \"macro_sql\": \"{% macro default__generate_database_name(custom_database_name=none, node=none) -%}\\n    {%- set default_database = target.database -%}\\n    {%- if custom_database_name is none -%}\\n\\n        {{ default_database }}\\n\\n    {%- else -%}\\n\\n        {{ custom_database_name }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.013767, \"supported_languages\": null}, \"macro.dbt.get_drop_sql\": {\"name\": \"get_drop_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/drop.sql\", \"original_file_path\": \"macros/relations/drop.sql\", \"unique_id\": \"macro.dbt.get_drop_sql\", \"macro_sql\": \"{%- macro get_drop_sql(relation) -%}\\n    {{- log('Applying DROP to: ' ~ relation) -}}\\n    {{- adapter.dispatch('get_drop_sql', 'dbt')(relation) -}}\\n{%- endmacro -%}\\n\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_drop_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.013788, \"supported_languages\": null}, \"macro.dbt.default__get_drop_sql\": {\"name\": \"default__get_drop_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/drop.sql\", \"original_file_path\": \"macros/relations/drop.sql\", \"unique_id\": \"macro.dbt.default__get_drop_sql\", \"macro_sql\": \"{%- macro default__get_drop_sql(relation) -%}\\n\\n    {%- if relation.is_view -%}\\n        {{ drop_view(relation) }}\\n\\n    {%- elif relation.is_table -%}\\n        {{ drop_table(relation) }}\\n\\n    {%- elif relation.is_materialized_view -%}\\n        {{ drop_materialized_view(relation) }}\\n\\n    {%- else -%}\\n        drop {{ relation.type }} if exists {{ relation.render() }} cascade\\n\\n    {%- endif -%}\\n\\n{%- endmacro -%}\\n\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.drop_view\", \"macro.dbt.drop_table\", \"macro.dbt.drop_materialized_view\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.013799, \"supported_languages\": null}, \"macro.dbt.drop_relation\": {\"name\": \"drop_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/drop.sql\", \"original_file_path\": \"macros/relations/drop.sql\", \"unique_id\": \"macro.dbt.drop_relation\", \"macro_sql\": \"{% macro drop_relation(relation) -%}\\n    {{ return(adapter.dispatch('drop_relation', 'dbt')(relation)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__drop_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.01381, \"supported_languages\": null}, \"macro.dbt.default__drop_relation\": {\"name\": \"default__drop_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/drop.sql\", \"original_file_path\": \"macros/relations/drop.sql\", \"unique_id\": \"macro.dbt.default__drop_relation\", \"macro_sql\": \"{% macro default__drop_relation(relation) -%}\\n    {% call statement('drop_relation', auto_begin=False) -%}\\n        {{ get_drop_sql(relation) }}\\n    {%- endcall %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\", \"macro.dbt.get_drop_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.01382, \"supported_languages\": null}, \"macro.dbt.drop_relation_if_exists\": {\"name\": \"drop_relation_if_exists\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/drop.sql\", \"original_file_path\": \"macros/relations/drop.sql\", \"unique_id\": \"macro.dbt.drop_relation_if_exists\", \"macro_sql\": \"{% macro drop_relation_if_exists(relation) %}\\n  {% if relation is not none %}\\n    {{ adapter.drop_relation(relation) }}\\n  {% endif %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.013831, \"supported_languages\": null}, \"macro.dbt.get_replace_sql\": {\"name\": \"get_replace_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/replace.sql\", \"original_file_path\": \"macros/relations/replace.sql\", \"unique_id\": \"macro.dbt.get_replace_sql\", \"macro_sql\": \"{% macro get_replace_sql(existing_relation, target_relation, sql) %}\\n    {{- log('Applying REPLACE to: ' ~ existing_relation) -}}\\n    {{- adapter.dispatch('get_replace_sql', 'dbt')(existing_relation, target_relation, sql) -}}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_replace_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.013851, \"supported_languages\": null}, \"macro.dbt.default__get_replace_sql\": {\"name\": \"default__get_replace_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/replace.sql\", \"original_file_path\": \"macros/relations/replace.sql\", \"unique_id\": \"macro.dbt.default__get_replace_sql\", \"macro_sql\": \"{% macro default__get_replace_sql(existing_relation, target_relation, sql) %}\\n\\n    {# /* use a create or replace statement if possible */ #}\\n\\n    {% set is_replaceable = existing_relation.type == target_relation.type and existing_relation.can_be_replaced %}\\n\\n    {% if is_replaceable and existing_relation.is_view %}\\n        {{ get_replace_view_sql(target_relation, sql) }}\\n\\n    {% elif is_replaceable and existing_relation.is_table %}\\n        {{ get_replace_table_sql(target_relation, sql) }}\\n\\n    {% elif is_replaceable and existing_relation.is_materialized_view %}\\n        {{ get_replace_materialized_view_sql(target_relation, sql) }}\\n\\n    {# /* a create or replace statement is not possible, so try to stage and/or backup to be safe */ #}\\n\\n    {# /* create target_relation as an intermediate relation, then swap it out with the existing one using a backup */ #}\\n    {%- elif target_relation.can_be_renamed and existing_relation.can_be_renamed -%}\\n        {{ get_create_intermediate_sql(target_relation, sql) }};\\n        {{ get_create_backup_sql(existing_relation) }};\\n        {{ get_rename_intermediate_sql(target_relation) }};\\n        {{ get_drop_backup_sql(existing_relation) }}\\n\\n    {# /* create target_relation as an intermediate relation, then swap it out with the existing one without using a backup */ #}\\n    {%- elif target_relation.can_be_renamed -%}\\n        {{ get_create_intermediate_sql(target_relation, sql) }};\\n        {{ get_drop_sql(existing_relation) }};\\n        {{ get_rename_intermediate_sql(target_relation) }}\\n\\n    {# /* create target_relation in place by first backing up the existing relation */ #}\\n    {%- elif existing_relation.can_be_renamed -%}\\n        {{ get_create_backup_sql(existing_relation) }};\\n        {{ get_create_sql(target_relation, sql) }};\\n        {{ get_drop_backup_sql(existing_relation) }}\\n\\n    {# /* no renaming is allowed, so just drop and create */ #}\\n    {%- else -%}\\n        {{ get_drop_sql(existing_relation) }};\\n        {{ get_create_sql(target_relation, sql) }}\\n\\n    {%- endif -%}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_replace_view_sql\", \"macro.dbt.get_replace_table_sql\", \"macro.dbt.get_replace_materialized_view_sql\", \"macro.dbt.get_create_intermediate_sql\", \"macro.dbt.get_create_backup_sql\", \"macro.dbt.get_rename_intermediate_sql\", \"macro.dbt.get_drop_backup_sql\", \"macro.dbt.get_drop_sql\", \"macro.dbt.get_create_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.013862, \"supported_languages\": null}, \"macro.dbt.get_create_intermediate_sql\": {\"name\": \"get_create_intermediate_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/create_intermediate.sql\", \"original_file_path\": \"macros/relations/create_intermediate.sql\", \"unique_id\": \"macro.dbt.get_create_intermediate_sql\", \"macro_sql\": \"{%- macro get_create_intermediate_sql(relation, sql) -%}\\n    {{- log('Applying CREATE INTERMEDIATE to: ' ~ relation) -}}\\n    {{- adapter.dispatch('get_create_intermediate_sql', 'dbt')(relation, sql) -}}\\n{%- endmacro -%}\\n\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_create_intermediate_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0138822, \"supported_languages\": null}, \"macro.dbt.default__get_create_intermediate_sql\": {\"name\": \"default__get_create_intermediate_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/create_intermediate.sql\", \"original_file_path\": \"macros/relations/create_intermediate.sql\", \"unique_id\": \"macro.dbt.default__get_create_intermediate_sql\", \"macro_sql\": \"{%- macro default__get_create_intermediate_sql(relation, sql) -%}\\n\\n    -- get the standard intermediate name\\n    {% set intermediate_relation = make_intermediate_relation(relation) %}\\n\\n    -- drop any pre-existing intermediate\\n    {{ get_drop_sql(intermediate_relation) }};\\n\\n    {{ get_create_sql(intermediate_relation, sql) }}\\n\\n{%- endmacro -%}\", \"depends_on\": {\"macros\": [\"macro.dbt.make_intermediate_relation\", \"macro.dbt.get_drop_sql\", \"macro.dbt.get_create_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0138922, \"supported_languages\": null}, \"macro.dbt.drop_schema_named\": {\"name\": \"drop_schema_named\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/schema.sql\", \"original_file_path\": \"macros/relations/schema.sql\", \"unique_id\": \"macro.dbt.drop_schema_named\", \"macro_sql\": \"{% macro drop_schema_named(schema_name) %}\\n    {{ return(adapter.dispatch('drop_schema_named', 'dbt') (schema_name)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__drop_schema_named\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.013912, \"supported_languages\": null}, \"macro.dbt.default__drop_schema_named\": {\"name\": \"default__drop_schema_named\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/schema.sql\", \"original_file_path\": \"macros/relations/schema.sql\", \"unique_id\": \"macro.dbt.default__drop_schema_named\", \"macro_sql\": \"{% macro default__drop_schema_named(schema_name) %}\\n  {% set schema_relation = api.Relation.create(schema=schema_name) %}\\n  {{ adapter.drop_schema(schema_relation) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.013922, \"supported_languages\": null}, \"macro.dbt.get_drop_backup_sql\": {\"name\": \"get_drop_backup_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/drop_backup.sql\", \"original_file_path\": \"macros/relations/drop_backup.sql\", \"unique_id\": \"macro.dbt.get_drop_backup_sql\", \"macro_sql\": \"{%- macro get_drop_backup_sql(relation) -%}\\n    {{- log('Applying DROP BACKUP to: ' ~ relation) -}}\\n    {{- adapter.dispatch('get_drop_backup_sql', 'dbt')(relation) -}}\\n{%- endmacro -%}\\n\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_drop_backup_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.013942, \"supported_languages\": null}, \"macro.dbt.default__get_drop_backup_sql\": {\"name\": \"default__get_drop_backup_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/drop_backup.sql\", \"original_file_path\": \"macros/relations/drop_backup.sql\", \"unique_id\": \"macro.dbt.default__get_drop_backup_sql\", \"macro_sql\": \"{%- macro default__get_drop_backup_sql(relation) -%}\\n\\n    -- get the standard backup name\\n    {% set backup_relation = make_backup_relation(relation, relation.type) %}\\n\\n    {{ get_drop_sql(backup_relation) }}\\n\\n{%- endmacro -%}\", \"depends_on\": {\"macros\": [\"macro.dbt.make_backup_relation\", \"macro.dbt.get_drop_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.013952, \"supported_languages\": null}, \"macro.dbt.get_rename_sql\": {\"name\": \"get_rename_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/rename.sql\", \"original_file_path\": \"macros/relations/rename.sql\", \"unique_id\": \"macro.dbt.get_rename_sql\", \"macro_sql\": \"{%- macro get_rename_sql(relation, new_name) -%}\\n    {{- log('Applying RENAME to: ' ~ relation) -}}\\n    {{- adapter.dispatch('get_rename_sql', 'dbt')(relation, new_name) -}}\\n{%- endmacro -%}\\n\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_rename_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.013972, \"supported_languages\": null}, \"macro.dbt.default__get_rename_sql\": {\"name\": \"default__get_rename_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/rename.sql\", \"original_file_path\": \"macros/relations/rename.sql\", \"unique_id\": \"macro.dbt.default__get_rename_sql\", \"macro_sql\": \"{%- macro default__get_rename_sql(relation, new_name) -%}\\n\\n    {%- if relation.is_view -%}\\n        {{ get_rename_view_sql(relation, new_name) }}\\n\\n    {%- elif relation.is_table -%}\\n        {{ get_rename_table_sql(relation, new_name) }}\\n\\n    {%- elif relation.is_materialized_view -%}\\n        {{ get_rename_materialized_view_sql(relation, new_name) }}\\n\\n    {%- else -%}\\n        {{- exceptions.raise_compiler_error(\\\"`get_rename_sql` has not been implemented for: \\\" ~ relation.type ) -}}\\n\\n    {%- endif -%}\\n\\n{%- endmacro -%}\\n\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.get_rename_view_sql\", \"macro.dbt.get_rename_table_sql\", \"macro.dbt.get_rename_materialized_view_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.013983, \"supported_languages\": null}, \"macro.dbt.rename_relation\": {\"name\": \"rename_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/rename.sql\", \"original_file_path\": \"macros/relations/rename.sql\", \"unique_id\": \"macro.dbt.rename_relation\", \"macro_sql\": \"{% macro rename_relation(from_relation, to_relation) -%}\\n  {{ return(adapter.dispatch('rename_relation', 'dbt')(from_relation, to_relation)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__rename_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.013993, \"supported_languages\": null}, \"macro.dbt.default__rename_relation\": {\"name\": \"default__rename_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/rename.sql\", \"original_file_path\": \"macros/relations/rename.sql\", \"unique_id\": \"macro.dbt.default__rename_relation\", \"macro_sql\": \"{% macro default__rename_relation(from_relation, to_relation) -%}\\n  {% set target_name = adapter.quote_as_configured(to_relation.identifier, 'identifier') %}\\n  {% call statement('rename_relation') -%}\\n    alter table {{ from_relation.render() }} rename to {{ target_name }}\\n  {%- endcall %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.014003, \"supported_languages\": null}, \"macro.dbt.get_create_backup_sql\": {\"name\": \"get_create_backup_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/create_backup.sql\", \"original_file_path\": \"macros/relations/create_backup.sql\", \"unique_id\": \"macro.dbt.get_create_backup_sql\", \"macro_sql\": \"{%- macro get_create_backup_sql(relation) -%}\\n    {{- log('Applying CREATE BACKUP to: ' ~ relation) -}}\\n    {{- adapter.dispatch('get_create_backup_sql', 'dbt')(relation) -}}\\n{%- endmacro -%}\\n\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_create_backup_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0140219, \"supported_languages\": null}, \"macro.dbt.default__get_create_backup_sql\": {\"name\": \"default__get_create_backup_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/create_backup.sql\", \"original_file_path\": \"macros/relations/create_backup.sql\", \"unique_id\": \"macro.dbt.default__get_create_backup_sql\", \"macro_sql\": \"{%- macro default__get_create_backup_sql(relation) -%}\\n\\n    -- get the standard backup name\\n    {% set backup_relation = make_backup_relation(relation, relation.type) %}\\n\\n    -- drop any pre-existing backup\\n    {{ get_drop_sql(backup_relation) }};\\n\\n    {{ get_rename_sql(relation, backup_relation.identifier) }}\\n\\n{%- endmacro -%}\", \"depends_on\": {\"macros\": [\"macro.dbt.make_backup_relation\", \"macro.dbt.get_drop_sql\", \"macro.dbt.get_rename_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0140328, \"supported_languages\": null}, \"macro.dbt.get_create_sql\": {\"name\": \"get_create_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/create.sql\", \"original_file_path\": \"macros/relations/create.sql\", \"unique_id\": \"macro.dbt.get_create_sql\", \"macro_sql\": \"{%- macro get_create_sql(relation, sql) -%}\\n    {{- log('Applying CREATE to: ' ~ relation) -}}\\n    {{- adapter.dispatch('get_create_sql', 'dbt')(relation, sql) -}}\\n{%- endmacro -%}\\n\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_create_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0140522, \"supported_languages\": null}, \"macro.dbt.default__get_create_sql\": {\"name\": \"default__get_create_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/create.sql\", \"original_file_path\": \"macros/relations/create.sql\", \"unique_id\": \"macro.dbt.default__get_create_sql\", \"macro_sql\": \"{%- macro default__get_create_sql(relation, sql) -%}\\n\\n    {%- if relation.is_view -%}\\n        {{ get_create_view_as_sql(relation, sql) }}\\n\\n    {%- elif relation.is_table -%}\\n        {{ get_create_table_as_sql(False, relation, sql) }}\\n\\n    {%- elif relation.is_materialized_view -%}\\n        {{ get_create_materialized_view_as_sql(relation, sql) }}\\n\\n    {%- else -%}\\n        {{- exceptions.raise_compiler_error(\\\"`get_create_sql` has not been implemented for: \\\" ~ relation.type ) -}}\\n\\n    {%- endif -%}\\n\\n{%- endmacro -%}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_create_view_as_sql\", \"macro.dbt.get_create_table_as_sql\", \"macro.dbt.get_create_materialized_view_as_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0140631, \"supported_languages\": null}, \"macro.dbt.get_rename_intermediate_sql\": {\"name\": \"get_rename_intermediate_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/rename_intermediate.sql\", \"original_file_path\": \"macros/relations/rename_intermediate.sql\", \"unique_id\": \"macro.dbt.get_rename_intermediate_sql\", \"macro_sql\": \"{%- macro get_rename_intermediate_sql(relation) -%}\\n    {{- log('Applying RENAME INTERMEDIATE to: ' ~ relation) -}}\\n    {{- adapter.dispatch('get_rename_intermediate_sql', 'dbt')(relation) -}}\\n{%- endmacro -%}\\n\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_rename_intermediate_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0140831, \"supported_languages\": null}, \"macro.dbt.default__get_rename_intermediate_sql\": {\"name\": \"default__get_rename_intermediate_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/rename_intermediate.sql\", \"original_file_path\": \"macros/relations/rename_intermediate.sql\", \"unique_id\": \"macro.dbt.default__get_rename_intermediate_sql\", \"macro_sql\": \"{%- macro default__get_rename_intermediate_sql(relation) -%}\\n\\n    -- get the standard intermediate name\\n    {% set intermediate_relation = make_intermediate_relation(relation) %}\\n\\n    {{ get_rename_sql(intermediate_relation, relation.identifier) }}\\n\\n{%- endmacro -%}\", \"depends_on\": {\"macros\": [\"macro.dbt.make_intermediate_relation\", \"macro.dbt.get_rename_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0140932, \"supported_languages\": null}, \"macro.dbt.drop_materialized_view\": {\"name\": \"drop_materialized_view\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/materialized_view/drop.sql\", \"original_file_path\": \"macros/relations/materialized_view/drop.sql\", \"unique_id\": \"macro.dbt.drop_materialized_view\", \"macro_sql\": \"{% macro drop_materialized_view(relation) -%}\\n    {{- adapter.dispatch('drop_materialized_view', 'dbt')(relation) -}}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__drop_materialized_view\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.014113, \"supported_languages\": null}, \"macro.dbt.default__drop_materialized_view\": {\"name\": \"default__drop_materialized_view\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/materialized_view/drop.sql\", \"original_file_path\": \"macros/relations/materialized_view/drop.sql\", \"unique_id\": \"macro.dbt.default__drop_materialized_view\", \"macro_sql\": \"{% macro default__drop_materialized_view(relation) -%}\\n    drop materialized view if exists {{ relation.render() }} cascade\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.014123, \"supported_languages\": null}, \"macro.dbt.get_replace_materialized_view_sql\": {\"name\": \"get_replace_materialized_view_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/materialized_view/replace.sql\", \"original_file_path\": \"macros/relations/materialized_view/replace.sql\", \"unique_id\": \"macro.dbt.get_replace_materialized_view_sql\", \"macro_sql\": \"{% macro get_replace_materialized_view_sql(relation, sql) %}\\n    {{- adapter.dispatch('get_replace_materialized_view_sql', 'dbt')(relation, sql) -}}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_replace_materialized_view_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.014143, \"supported_languages\": null}, \"macro.dbt.default__get_replace_materialized_view_sql\": {\"name\": \"default__get_replace_materialized_view_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/materialized_view/replace.sql\", \"original_file_path\": \"macros/relations/materialized_view/replace.sql\", \"unique_id\": \"macro.dbt.default__get_replace_materialized_view_sql\", \"macro_sql\": \"{% macro default__get_replace_materialized_view_sql(relation, sql) %}\\n    {{ exceptions.raise_compiler_error(\\n        \\\"`get_replace_materialized_view_sql` has not been implemented for this adapter.\\\"\\n    ) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.014154, \"supported_languages\": null}, \"macro.dbt.refresh_materialized_view\": {\"name\": \"refresh_materialized_view\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/materialized_view/refresh.sql\", \"original_file_path\": \"macros/relations/materialized_view/refresh.sql\", \"unique_id\": \"macro.dbt.refresh_materialized_view\", \"macro_sql\": \"{% macro refresh_materialized_view(relation) %}\\n    {{- log('Applying REFRESH to: ' ~ relation) -}}\\n    {{- adapter.dispatch('refresh_materialized_view', 'dbt')(relation) -}}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__refresh_materialized_view\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.014177, \"supported_languages\": null}, \"macro.dbt.default__refresh_materialized_view\": {\"name\": \"default__refresh_materialized_view\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/materialized_view/refresh.sql\", \"original_file_path\": \"macros/relations/materialized_view/refresh.sql\", \"unique_id\": \"macro.dbt.default__refresh_materialized_view\", \"macro_sql\": \"{% macro default__refresh_materialized_view(relation) %}\\n    {{ exceptions.raise_compiler_error(\\\"`refresh_materialized_view` has not been implemented for this adapter.\\\") }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.014192, \"supported_languages\": null}, \"macro.dbt.get_rename_materialized_view_sql\": {\"name\": \"get_rename_materialized_view_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/materialized_view/rename.sql\", \"original_file_path\": \"macros/relations/materialized_view/rename.sql\", \"unique_id\": \"macro.dbt.get_rename_materialized_view_sql\", \"macro_sql\": \"{% macro get_rename_materialized_view_sql(relation, new_name) %}\\n    {{- adapter.dispatch('get_rename_materialized_view_sql', 'dbt')(relation, new_name) -}}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_rename_materialized_view_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0142121, \"supported_languages\": null}, \"macro.dbt.default__get_rename_materialized_view_sql\": {\"name\": \"default__get_rename_materialized_view_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/materialized_view/rename.sql\", \"original_file_path\": \"macros/relations/materialized_view/rename.sql\", \"unique_id\": \"macro.dbt.default__get_rename_materialized_view_sql\", \"macro_sql\": \"{% macro default__get_rename_materialized_view_sql(relation, new_name) %}\\n    {{ exceptions.raise_compiler_error(\\n        \\\"`get_rename_materialized_view_sql` has not been implemented for this adapter.\\\"\\n    ) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.014223, \"supported_languages\": null}, \"macro.dbt.get_alter_materialized_view_as_sql\": {\"name\": \"get_alter_materialized_view_as_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/materialized_view/alter.sql\", \"original_file_path\": \"macros/relations/materialized_view/alter.sql\", \"unique_id\": \"macro.dbt.get_alter_materialized_view_as_sql\", \"macro_sql\": \"{% macro get_alter_materialized_view_as_sql(\\n    relation,\\n    configuration_changes,\\n    sql,\\n    existing_relation,\\n    backup_relation,\\n    intermediate_relation\\n) %}\\n    {{- log('Applying ALTER to: ' ~ relation) -}}\\n    {{- adapter.dispatch('get_alter_materialized_view_as_sql', 'dbt')(\\n        relation,\\n        configuration_changes,\\n        sql,\\n        existing_relation,\\n        backup_relation,\\n        intermediate_relation\\n    ) -}}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_alter_materialized_view_as_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0142431, \"supported_languages\": null}, \"macro.dbt.default__get_alter_materialized_view_as_sql\": {\"name\": \"default__get_alter_materialized_view_as_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/materialized_view/alter.sql\", \"original_file_path\": \"macros/relations/materialized_view/alter.sql\", \"unique_id\": \"macro.dbt.default__get_alter_materialized_view_as_sql\", \"macro_sql\": \"{% macro default__get_alter_materialized_view_as_sql(\\n    relation,\\n    configuration_changes,\\n    sql,\\n    existing_relation,\\n    backup_relation,\\n    intermediate_relation\\n) %}\\n    {{ exceptions.raise_compiler_error(\\\"Materialized views have not been implemented for this adapter.\\\") }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0152268, \"supported_languages\": null}, \"macro.dbt.get_materialized_view_configuration_changes\": {\"name\": \"get_materialized_view_configuration_changes\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/materialized_view/alter.sql\", \"original_file_path\": \"macros/relations/materialized_view/alter.sql\", \"unique_id\": \"macro.dbt.get_materialized_view_configuration_changes\", \"macro_sql\": \"{% macro get_materialized_view_configuration_changes(existing_relation, new_config) %}\\n    /* {#\\n    It's recommended that configuration changes be formatted as follows:\\n    {\\\"<change_category>\\\": [{\\\"action\\\": \\\"<name>\\\", \\\"context\\\": ...}]}\\n\\n    For example:\\n    {\\n        \\\"indexes\\\": [\\n            {\\\"action\\\": \\\"drop\\\", \\\"context\\\": \\\"index_abc\\\"},\\n            {\\\"action\\\": \\\"create\\\", \\\"context\\\": {\\\"columns\\\": [\\\"column_1\\\", \\\"column_2\\\"], \\\"type\\\": \\\"hash\\\", \\\"unique\\\": True}},\\n        ],\\n    }\\n\\n    Either way, `get_materialized_view_configuration_changes` needs to align with `get_alter_materialized_view_as_sql`.\\n    #} */\\n    {{- log('Determining configuration changes on: ' ~ existing_relation) -}}\\n    {%- do return(adapter.dispatch('get_materialized_view_configuration_changes', 'dbt')(existing_relation, new_config)) -%}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_materialized_view_configuration_changes\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.015249, \"supported_languages\": null}, \"macro.dbt.default__get_materialized_view_configuration_changes\": {\"name\": \"default__get_materialized_view_configuration_changes\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/materialized_view/alter.sql\", \"original_file_path\": \"macros/relations/materialized_view/alter.sql\", \"unique_id\": \"macro.dbt.default__get_materialized_view_configuration_changes\", \"macro_sql\": \"{% macro default__get_materialized_view_configuration_changes(existing_relation, new_config) %}\\n    {{ exceptions.raise_compiler_error(\\\"Materialized views have not been implemented for this adapter.\\\") }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.015261, \"supported_languages\": null}, \"macro.dbt.get_create_materialized_view_as_sql\": {\"name\": \"get_create_materialized_view_as_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/materialized_view/create.sql\", \"original_file_path\": \"macros/relations/materialized_view/create.sql\", \"unique_id\": \"macro.dbt.get_create_materialized_view_as_sql\", \"macro_sql\": \"{% macro get_create_materialized_view_as_sql(relation, sql) -%}\\n    {{- adapter.dispatch('get_create_materialized_view_as_sql', 'dbt')(relation, sql) -}}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_create_materialized_view_as_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.015289, \"supported_languages\": null}, \"macro.dbt.default__get_create_materialized_view_as_sql\": {\"name\": \"default__get_create_materialized_view_as_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/materialized_view/create.sql\", \"original_file_path\": \"macros/relations/materialized_view/create.sql\", \"unique_id\": \"macro.dbt.default__get_create_materialized_view_as_sql\", \"macro_sql\": \"{% macro default__get_create_materialized_view_as_sql(relation, sql) -%}\\n    {{ exceptions.raise_compiler_error(\\n        \\\"`get_create_materialized_view_as_sql` has not been implemented for this adapter.\\\"\\n    ) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0153, \"supported_languages\": null}, \"macro.dbt.get_table_columns_and_constraints\": {\"name\": \"get_table_columns_and_constraints\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/column/columns_spec_ddl.sql\", \"original_file_path\": \"macros/relations/column/columns_spec_ddl.sql\", \"unique_id\": \"macro.dbt.get_table_columns_and_constraints\", \"macro_sql\": \"{%- macro get_table_columns_and_constraints() -%}\\n  {{ adapter.dispatch('get_table_columns_and_constraints', 'dbt')() }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_table_columns_and_constraints\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.015323, \"supported_languages\": null}, \"macro.dbt.default__get_table_columns_and_constraints\": {\"name\": \"default__get_table_columns_and_constraints\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/column/columns_spec_ddl.sql\", \"original_file_path\": \"macros/relations/column/columns_spec_ddl.sql\", \"unique_id\": \"macro.dbt.default__get_table_columns_and_constraints\", \"macro_sql\": \"{% macro default__get_table_columns_and_constraints() -%}\\n  {{ return(table_columns_and_constraints()) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.table_columns_and_constraints\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0153332, \"supported_languages\": null}, \"macro.dbt.table_columns_and_constraints\": {\"name\": \"table_columns_and_constraints\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/column/columns_spec_ddl.sql\", \"original_file_path\": \"macros/relations/column/columns_spec_ddl.sql\", \"unique_id\": \"macro.dbt.table_columns_and_constraints\", \"macro_sql\": \"{% macro table_columns_and_constraints() %}\\n  {# loop through user_provided_columns to create DDL with data types and constraints #}\\n    {%- set raw_column_constraints = adapter.render_raw_columns_constraints(raw_columns=model['columns']) -%}\\n    {%- set raw_model_constraints = adapter.render_raw_model_constraints(raw_constraints=model['constraints']) -%}\\n    (\\n    {% for c in raw_column_constraints -%}\\n      {{ c }}{{ \\\",\\\" if not loop.last or raw_model_constraints }}\\n    {% endfor %}\\n    {% for c in raw_model_constraints -%}\\n        {{ c }}{{ \\\",\\\" if not loop.last }}\\n    {% endfor -%}\\n    )\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0153432, \"supported_languages\": null}, \"macro.dbt.get_assert_columns_equivalent\": {\"name\": \"get_assert_columns_equivalent\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/column/columns_spec_ddl.sql\", \"original_file_path\": \"macros/relations/column/columns_spec_ddl.sql\", \"unique_id\": \"macro.dbt.get_assert_columns_equivalent\", \"macro_sql\": \"\\n\\n{%- macro get_assert_columns_equivalent(sql) -%}\\n  {{ adapter.dispatch('get_assert_columns_equivalent', 'dbt')(sql) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_assert_columns_equivalent\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0153532, \"supported_languages\": null}, \"macro.dbt.default__get_assert_columns_equivalent\": {\"name\": \"default__get_assert_columns_equivalent\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/column/columns_spec_ddl.sql\", \"original_file_path\": \"macros/relations/column/columns_spec_ddl.sql\", \"unique_id\": \"macro.dbt.default__get_assert_columns_equivalent\", \"macro_sql\": \"{% macro default__get_assert_columns_equivalent(sql) -%}\\n  {{ return(assert_columns_equivalent(sql)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.assert_columns_equivalent\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.015363, \"supported_languages\": null}, \"macro.dbt.assert_columns_equivalent\": {\"name\": \"assert_columns_equivalent\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/column/columns_spec_ddl.sql\", \"original_file_path\": \"macros/relations/column/columns_spec_ddl.sql\", \"unique_id\": \"macro.dbt.assert_columns_equivalent\", \"macro_sql\": \"{% macro assert_columns_equivalent(sql) %}\\n\\n  {#-- First ensure the user has defined 'columns' in yaml specification --#}\\n  {%- set user_defined_columns = model['columns'] -%}\\n  {%- if not user_defined_columns -%}\\n      {{ exceptions.raise_contract_error([], []) }}\\n  {%- endif -%}\\n\\n  {#-- Obtain the column schema provided by sql file. #}\\n  {%- set sql_file_provided_columns = get_column_schema_from_query(sql, config.get('sql_header', none)) -%}\\n  {#--Obtain the column schema provided by the schema file by generating an 'empty schema' query from the model's columns. #}\\n  {%- set schema_file_provided_columns = get_column_schema_from_query(get_empty_schema_sql(user_defined_columns)) -%}\\n\\n  {#-- create dictionaries with name and formatted data type and strings for exception #}\\n  {%- set sql_columns = format_columns(sql_file_provided_columns) -%}\\n  {%- set yaml_columns = format_columns(schema_file_provided_columns)  -%}\\n\\n  {%- if sql_columns|length != yaml_columns|length -%}\\n    {%- do exceptions.raise_contract_error(yaml_columns, sql_columns) -%}\\n  {%- endif -%}\\n\\n  {%- for sql_col in sql_columns -%}\\n    {%- set yaml_col = [] -%}\\n    {%- for this_col in yaml_columns -%}\\n      {%- if this_col['name'] == sql_col['name'] -%}\\n        {%- do yaml_col.append(this_col) -%}\\n        {%- break -%}\\n      {%- endif -%}\\n    {%- endfor -%}\\n    {%- if not yaml_col -%}\\n      {#-- Column with name not found in yaml #}\\n      {%- do exceptions.raise_contract_error(yaml_columns, sql_columns) -%}\\n    {%- endif -%}\\n    {%- if sql_col['formatted'] != yaml_col[0]['formatted'] -%}\\n      {#-- Column data types don't match #}\\n      {%- do exceptions.raise_contract_error(yaml_columns, sql_columns) -%}\\n    {%- endif -%}\\n  {%- endfor -%}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_column_schema_from_query\", \"macro.dbt.get_empty_schema_sql\", \"macro.dbt.format_columns\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0153742, \"supported_languages\": null}, \"macro.dbt.format_columns\": {\"name\": \"format_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/column/columns_spec_ddl.sql\", \"original_file_path\": \"macros/relations/column/columns_spec_ddl.sql\", \"unique_id\": \"macro.dbt.format_columns\", \"macro_sql\": \"{% macro format_columns(columns) %}\\n  {% set formatted_columns = [] %}\\n  {% for column in columns %}\\n    {%- set formatted_column = adapter.dispatch('format_column', 'dbt')(column) -%}\\n    {%- do formatted_columns.append(formatted_column) -%}\\n  {% endfor %}\\n  {{ return(formatted_columns) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__format_column\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.015383, \"supported_languages\": null}, \"macro.dbt.default__format_column\": {\"name\": \"default__format_column\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/column/columns_spec_ddl.sql\", \"original_file_path\": \"macros/relations/column/columns_spec_ddl.sql\", \"unique_id\": \"macro.dbt.default__format_column\", \"macro_sql\": \"{% macro default__format_column(column) -%}\\n  {% set data_type = column.dtype %}\\n  {% set formatted = column.column.lower() ~ \\\" \\\" ~ data_type %}\\n  {{ return({'name': column.name, 'data_type': data_type, 'formatted': formatted}) }}\\n{%- endmacro -%}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.015393, \"supported_languages\": null}, \"macro.dbt.drop_table\": {\"name\": \"drop_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/table/drop.sql\", \"original_file_path\": \"macros/relations/table/drop.sql\", \"unique_id\": \"macro.dbt.drop_table\", \"macro_sql\": \"{% macro drop_table(relation) -%}\\n    {{- adapter.dispatch('drop_table', 'dbt')(relation) -}}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__drop_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.015413, \"supported_languages\": null}, \"macro.dbt.default__drop_table\": {\"name\": \"default__drop_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/table/drop.sql\", \"original_file_path\": \"macros/relations/table/drop.sql\", \"unique_id\": \"macro.dbt.default__drop_table\", \"macro_sql\": \"{% macro default__drop_table(relation) -%}\\n    drop table if exists {{ relation.render() }} cascade\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.015423, \"supported_languages\": null}, \"macro.dbt.get_replace_table_sql\": {\"name\": \"get_replace_table_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/table/replace.sql\", \"original_file_path\": \"macros/relations/table/replace.sql\", \"unique_id\": \"macro.dbt.get_replace_table_sql\", \"macro_sql\": \"{% macro get_replace_table_sql(relation, sql) %}\\n    {{- adapter.dispatch('get_replace_table_sql', 'dbt')(relation, sql) -}}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_replace_table_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.015442, \"supported_languages\": null}, \"macro.dbt.default__get_replace_table_sql\": {\"name\": \"default__get_replace_table_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/table/replace.sql\", \"original_file_path\": \"macros/relations/table/replace.sql\", \"unique_id\": \"macro.dbt.default__get_replace_table_sql\", \"macro_sql\": \"{% macro default__get_replace_table_sql(relation, sql) %}\\n    {{ exceptions.raise_compiler_error(\\n        \\\"`get_replace_table_sql` has not been implemented for this adapter.\\\"\\n    ) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.015454, \"supported_languages\": null}, \"macro.dbt.get_rename_table_sql\": {\"name\": \"get_rename_table_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/table/rename.sql\", \"original_file_path\": \"macros/relations/table/rename.sql\", \"unique_id\": \"macro.dbt.get_rename_table_sql\", \"macro_sql\": \"{% macro get_rename_table_sql(relation, new_name) %}\\n    {{- adapter.dispatch('get_rename_table_sql', 'dbt')(relation, new_name) -}}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_rename_table_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.015473, \"supported_languages\": null}, \"macro.dbt.default__get_rename_table_sql\": {\"name\": \"default__get_rename_table_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/table/rename.sql\", \"original_file_path\": \"macros/relations/table/rename.sql\", \"unique_id\": \"macro.dbt.default__get_rename_table_sql\", \"macro_sql\": \"{% macro default__get_rename_table_sql(relation, new_name) %}\\n    {{ exceptions.raise_compiler_error(\\n        \\\"`get_rename_table_sql` has not been implemented for this adapter.\\\"\\n    ) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.015483, \"supported_languages\": null}, \"macro.dbt.get_create_table_as_sql\": {\"name\": \"get_create_table_as_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/table/create.sql\", \"original_file_path\": \"macros/relations/table/create.sql\", \"unique_id\": \"macro.dbt.get_create_table_as_sql\", \"macro_sql\": \"{% macro get_create_table_as_sql(temporary, relation, sql) -%}\\n  {{ adapter.dispatch('get_create_table_as_sql', 'dbt')(temporary, relation, sql) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_create_table_as_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.015504, \"supported_languages\": null}, \"macro.dbt.default__get_create_table_as_sql\": {\"name\": \"default__get_create_table_as_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/table/create.sql\", \"original_file_path\": \"macros/relations/table/create.sql\", \"unique_id\": \"macro.dbt.default__get_create_table_as_sql\", \"macro_sql\": \"{% macro default__get_create_table_as_sql(temporary, relation, sql) -%}\\n  {{ return(create_table_as(temporary, relation, sql)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.create_table_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.015539, \"supported_languages\": null}, \"macro.dbt.create_table_as\": {\"name\": \"create_table_as\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/table/create.sql\", \"original_file_path\": \"macros/relations/table/create.sql\", \"unique_id\": \"macro.dbt.create_table_as\", \"macro_sql\": \"{% macro create_table_as(temporary, relation, compiled_code, language='sql') -%}\\n  {# backward compatibility for create_table_as that does not support language #}\\n  {% if language == \\\"sql\\\" %}\\n    {{ adapter.dispatch('create_table_as', 'dbt')(temporary, relation, compiled_code)}}\\n  {% else %}\\n    {{ adapter.dispatch('create_table_as', 'dbt')(temporary, relation, compiled_code, language) }}\\n  {% endif %}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__create_table_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.015549, \"supported_languages\": null}, \"macro.dbt.default__create_table_as\": {\"name\": \"default__create_table_as\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/table/create.sql\", \"original_file_path\": \"macros/relations/table/create.sql\", \"unique_id\": \"macro.dbt.default__create_table_as\", \"macro_sql\": \"{% macro default__create_table_as(temporary, relation, sql) -%}\\n  {%- set sql_header = config.get('sql_header', none) -%}\\n\\n  {{ sql_header if sql_header is not none }}\\n\\n  create {% if temporary: -%}temporary{%- endif %} table\\n    {{ relation.include(database=(not temporary), schema=(not temporary)) }}\\n  {% set contract_config = config.get('contract') %}\\n  {% if contract_config.enforced and (not temporary) %}\\n    {{ get_assert_columns_equivalent(sql) }}\\n    {{ get_table_columns_and_constraints() }}\\n    {%- set sql = get_select_subquery(sql) %}\\n  {% endif %}\\n  as (\\n    {{ sql }}\\n  );\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_assert_columns_equivalent\", \"macro.dbt.get_table_columns_and_constraints\", \"macro.dbt.get_select_subquery\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.015559, \"supported_languages\": null}, \"macro.dbt.default__get_column_names\": {\"name\": \"default__get_column_names\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/table/create.sql\", \"original_file_path\": \"macros/relations/table/create.sql\", \"unique_id\": \"macro.dbt.default__get_column_names\", \"macro_sql\": \"{% macro default__get_column_names() %}\\n  {#- loop through user_provided_columns to get column names -#}\\n    {%- set user_provided_columns = model['columns'] -%}\\n    {%- for i in user_provided_columns %}\\n      {%- set col = user_provided_columns[i] -%}\\n      {%- set col_name = adapter.quote(col['name']) if col.get('quote') else col['name'] -%}\\n      {{ col_name }}{{ \\\", \\\" if not loop.last }}\\n    {%- endfor -%}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.015569, \"supported_languages\": null}, \"macro.dbt.get_select_subquery\": {\"name\": \"get_select_subquery\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/table/create.sql\", \"original_file_path\": \"macros/relations/table/create.sql\", \"unique_id\": \"macro.dbt.get_select_subquery\", \"macro_sql\": \"{% macro get_select_subquery(sql) %}\\n  {{ return(adapter.dispatch('get_select_subquery', 'dbt')(sql)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_select_subquery\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.015578, \"supported_languages\": null}, \"macro.dbt.default__get_select_subquery\": {\"name\": \"default__get_select_subquery\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/table/create.sql\", \"original_file_path\": \"macros/relations/table/create.sql\", \"unique_id\": \"macro.dbt.default__get_select_subquery\", \"macro_sql\": \"{% macro default__get_select_subquery(sql) %}\\n    select {{ adapter.dispatch('get_column_names', 'dbt')() }}\\n    from (\\n        {{ sql }}\\n    ) as model_subq\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_column_names\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0155892, \"supported_languages\": null}, \"macro.dbt.drop_view\": {\"name\": \"drop_view\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/view/drop.sql\", \"original_file_path\": \"macros/relations/view/drop.sql\", \"unique_id\": \"macro.dbt.drop_view\", \"macro_sql\": \"{% macro drop_view(relation) -%}\\n    {{- adapter.dispatch('drop_view', 'dbt')(relation) -}}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__drop_view\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.015608, \"supported_languages\": null}, \"macro.dbt.default__drop_view\": {\"name\": \"default__drop_view\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/view/drop.sql\", \"original_file_path\": \"macros/relations/view/drop.sql\", \"unique_id\": \"macro.dbt.default__drop_view\", \"macro_sql\": \"{% macro default__drop_view(relation) -%}\\n    drop view if exists {{ relation.render() }} cascade\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.015618, \"supported_languages\": null}, \"macro.dbt.get_replace_view_sql\": {\"name\": \"get_replace_view_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/view/replace.sql\", \"original_file_path\": \"macros/relations/view/replace.sql\", \"unique_id\": \"macro.dbt.get_replace_view_sql\", \"macro_sql\": \"{% macro get_replace_view_sql(relation, sql) %}\\n    {{- adapter.dispatch('get_replace_view_sql', 'dbt')(relation, sql) -}}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_replace_view_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.015639, \"supported_languages\": null}, \"macro.dbt.default__get_replace_view_sql\": {\"name\": \"default__get_replace_view_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/view/replace.sql\", \"original_file_path\": \"macros/relations/view/replace.sql\", \"unique_id\": \"macro.dbt.default__get_replace_view_sql\", \"macro_sql\": \"{% macro default__get_replace_view_sql(relation, sql) %}\\n    {{ exceptions.raise_compiler_error(\\n        \\\"`get_replace_view_sql` has not been implemented for this adapter.\\\"\\n    ) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0156958, \"supported_languages\": null}, \"macro.dbt.create_or_replace_view\": {\"name\": \"create_or_replace_view\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/view/replace.sql\", \"original_file_path\": \"macros/relations/view/replace.sql\", \"unique_id\": \"macro.dbt.create_or_replace_view\", \"macro_sql\": \"{% macro create_or_replace_view() %}\\n  {%- set identifier = model['alias'] -%}\\n\\n  {%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%}\\n  {%- set exists_as_view = (old_relation is not none and old_relation.is_view) -%}\\n\\n  {%- set target_relation = api.Relation.create(\\n      identifier=identifier, schema=schema, database=database,\\n      type='view') -%}\\n  {% set grant_config = config.get('grants') %}\\n\\n  {{ run_hooks(pre_hooks) }}\\n\\n  -- If there's a table with the same name and we weren't told to full refresh,\\n  -- that's an error. If we were told to full refresh, drop it. This behavior differs\\n  -- for Snowflake and BigQuery, so multiple dispatch is used.\\n  {%- if old_relation is not none and old_relation.is_table -%}\\n    {{ handle_existing_table(should_full_refresh(), old_relation) }}\\n  {%- endif -%}\\n\\n  -- build model\\n  {% call statement('main') -%}\\n    {{ get_create_view_as_sql(target_relation, sql) }}\\n  {%- endcall %}\\n\\n  {% set should_revoke = should_revoke(exists_as_view, full_refresh_mode=True) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {{ run_hooks(post_hooks) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.run_hooks\", \"macro.dbt.handle_existing_table\", \"macro.dbt.should_full_refresh\", \"macro.dbt.statement\", \"macro.dbt.get_create_view_as_sql\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.015811, \"supported_languages\": null}, \"macro.dbt.handle_existing_table\": {\"name\": \"handle_existing_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/view/replace.sql\", \"original_file_path\": \"macros/relations/view/replace.sql\", \"unique_id\": \"macro.dbt.handle_existing_table\", \"macro_sql\": \"{% macro handle_existing_table(full_refresh, old_relation) %}\\n    {{ adapter.dispatch('handle_existing_table', 'dbt')(full_refresh, old_relation) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__handle_existing_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.015876, \"supported_languages\": null}, \"macro.dbt.default__handle_existing_table\": {\"name\": \"default__handle_existing_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/view/replace.sql\", \"original_file_path\": \"macros/relations/view/replace.sql\", \"unique_id\": \"macro.dbt.default__handle_existing_table\", \"macro_sql\": \"{% macro default__handle_existing_table(full_refresh, old_relation) %}\\n    {{ log(\\\"Dropping relation \\\" ~ old_relation.render() ~ \\\" because it is of type \\\" ~ old_relation.type) }}\\n    {{ adapter.drop_relation(old_relation) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.015913, \"supported_languages\": null}, \"macro.dbt.get_rename_view_sql\": {\"name\": \"get_rename_view_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/view/rename.sql\", \"original_file_path\": \"macros/relations/view/rename.sql\", \"unique_id\": \"macro.dbt.get_rename_view_sql\", \"macro_sql\": \"{% macro get_rename_view_sql(relation, new_name) %}\\n    {{- adapter.dispatch('get_rename_view_sql', 'dbt')(relation, new_name) -}}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_rename_view_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.016115, \"supported_languages\": null}, \"macro.dbt.default__get_rename_view_sql\": {\"name\": \"default__get_rename_view_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/view/rename.sql\", \"original_file_path\": \"macros/relations/view/rename.sql\", \"unique_id\": \"macro.dbt.default__get_rename_view_sql\", \"macro_sql\": \"{% macro default__get_rename_view_sql(relation, new_name) %}\\n    {{ exceptions.raise_compiler_error(\\n        \\\"`get_rename_view_sql` has not been implemented for this adapter.\\\"\\n    ) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.016132, \"supported_languages\": null}, \"macro.dbt.get_create_view_as_sql\": {\"name\": \"get_create_view_as_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/view/create.sql\", \"original_file_path\": \"macros/relations/view/create.sql\", \"unique_id\": \"macro.dbt.get_create_view_as_sql\", \"macro_sql\": \"{% macro get_create_view_as_sql(relation, sql) -%}\\n  {{ adapter.dispatch('get_create_view_as_sql', 'dbt')(relation, sql) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_create_view_as_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0161622, \"supported_languages\": null}, \"macro.dbt.default__get_create_view_as_sql\": {\"name\": \"default__get_create_view_as_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/view/create.sql\", \"original_file_path\": \"macros/relations/view/create.sql\", \"unique_id\": \"macro.dbt.default__get_create_view_as_sql\", \"macro_sql\": \"{% macro default__get_create_view_as_sql(relation, sql) -%}\\n  {{ return(create_view_as(relation, sql)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.create_view_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.016174, \"supported_languages\": null}, \"macro.dbt.create_view_as\": {\"name\": \"create_view_as\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/view/create.sql\", \"original_file_path\": \"macros/relations/view/create.sql\", \"unique_id\": \"macro.dbt.create_view_as\", \"macro_sql\": \"{% macro create_view_as(relation, sql) -%}\\n  {{ adapter.dispatch('create_view_as', 'dbt')(relation, sql) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__create_view_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.016185, \"supported_languages\": null}, \"macro.dbt.default__create_view_as\": {\"name\": \"default__create_view_as\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/relations/view/create.sql\", \"original_file_path\": \"macros/relations/view/create.sql\", \"unique_id\": \"macro.dbt.default__create_view_as\", \"macro_sql\": \"{% macro default__create_view_as(relation, sql) -%}\\n  {%- set sql_header = config.get('sql_header', none) -%}\\n\\n  {{ sql_header if sql_header is not none }}\\n  create view {{ relation.render() }}\\n    {% set contract_config = config.get('contract') %}\\n    {% if contract_config.enforced %}\\n      {{ get_assert_columns_equivalent(sql) }}\\n    {%- endif %}\\n  as (\\n    {{ sql }}\\n  );\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_assert_columns_equivalent\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.016196, \"supported_languages\": null}, \"macro.dbt.default__test_relationships\": {\"name\": \"default__test_relationships\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/generic_test_sql/relationships.sql\", \"original_file_path\": \"macros/generic_test_sql/relationships.sql\", \"unique_id\": \"macro.dbt.default__test_relationships\", \"macro_sql\": \"{% macro default__test_relationships(model, column_name, to, field) %}\\n\\nwith child as (\\n    select {{ column_name }} as from_field\\n    from {{ model }}\\n    where {{ column_name }} is not null\\n),\\n\\nparent as (\\n    select {{ field }} as to_field\\n    from {{ to }}\\n)\\n\\nselect\\n    from_field\\n\\nfrom child\\nleft join parent\\n    on child.from_field = parent.to_field\\n\\nwhere parent.to_field is null\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.016305, \"supported_languages\": null}, \"macro.dbt.default__test_not_null\": {\"name\": \"default__test_not_null\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/generic_test_sql/not_null.sql\", \"original_file_path\": \"macros/generic_test_sql/not_null.sql\", \"unique_id\": \"macro.dbt.default__test_not_null\", \"macro_sql\": \"{% macro default__test_not_null(model, column_name) %}\\n\\n{% set column_list = '*' if should_store_failures() else column_name %}\\n\\nselect {{ column_list }}\\nfrom {{ model }}\\nwhere {{ column_name }} is null\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.should_store_failures\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.016336, \"supported_languages\": null}, \"macro.dbt.default__test_unique\": {\"name\": \"default__test_unique\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/generic_test_sql/unique.sql\", \"original_file_path\": \"macros/generic_test_sql/unique.sql\", \"unique_id\": \"macro.dbt.default__test_unique\", \"macro_sql\": \"{% macro default__test_unique(model, column_name) %}\\n\\nselect\\n    {{ column_name }} as unique_field,\\n    count(*) as n_records\\n\\nfrom {{ model }}\\nwhere {{ column_name }} is not null\\ngroup by {{ column_name }}\\nhaving count(*) > 1\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0163572, \"supported_languages\": null}, \"macro.dbt.default__test_accepted_values\": {\"name\": \"default__test_accepted_values\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/generic_test_sql/accepted_values.sql\", \"original_file_path\": \"macros/generic_test_sql/accepted_values.sql\", \"unique_id\": \"macro.dbt.default__test_accepted_values\", \"macro_sql\": \"{% macro default__test_accepted_values(model, column_name, values, quote=True) %}\\n\\nwith all_values as (\\n\\n    select\\n        {{ column_name }} as value_field,\\n        count(*) as n_records\\n\\n    from {{ model }}\\n    group by {{ column_name }}\\n\\n)\\n\\nselect *\\nfrom all_values\\nwhere value_field not in (\\n    {% for value in values -%}\\n        {% if quote -%}\\n        '{{ value }}'\\n        {%- else -%}\\n        {{ value }}\\n        {%- endif -%}\\n        {%- if not loop.last -%},{%- endif %}\\n    {%- endfor %}\\n)\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.016377, \"supported_languages\": null}, \"macro.dbt.statement\": {\"name\": \"statement\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/etc/statement.sql\", \"original_file_path\": \"macros/etc/statement.sql\", \"unique_id\": \"macro.dbt.statement\", \"macro_sql\": \"\\n{%- macro statement(name=None, fetch_result=False, auto_begin=True, language='sql') -%}\\n  {%- if execute: -%}\\n    {%- set compiled_code = caller() -%}\\n\\n    {%- if name == 'main' -%}\\n      {{ log('Writing runtime {} for node \\\"{}\\\"'.format(language, model['unique_id'])) }}\\n      {{ write(compiled_code) }}\\n    {%- endif -%}\\n    {%- if language == 'sql'-%}\\n      {%- set res, table = adapter.execute(compiled_code, auto_begin=auto_begin, fetch=fetch_result) -%}\\n    {%- elif language == 'python' -%}\\n      {%- set res = submit_python_job(model, compiled_code) -%}\\n      {#-- TODO: What should table be for python models? --#}\\n      {%- set table = None -%}\\n    {%- else -%}\\n      {% do exceptions.raise_compiler_error(\\\"statement macro didn't get supported language\\\") %}\\n    {%- endif -%}\\n\\n    {%- if name is not none -%}\\n      {{ store_result(name, response=res, agate_table=table) }}\\n    {%- endif -%}\\n\\n  {%- endif -%}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0163991, \"supported_languages\": null}, \"macro.dbt.noop_statement\": {\"name\": \"noop_statement\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/etc/statement.sql\", \"original_file_path\": \"macros/etc/statement.sql\", \"unique_id\": \"macro.dbt.noop_statement\", \"macro_sql\": \"{% macro noop_statement(name=None, message=None, code=None, rows_affected=None, res=None) -%}\\n  {%- set sql = caller() -%}\\n\\n  {%- if name == 'main' -%}\\n    {{ log('Writing runtime SQL for node \\\"{}\\\"'.format(model['unique_id'])) }}\\n    {{ write(sql) }}\\n  {%- endif -%}\\n\\n  {%- if name is not none -%}\\n    {{ store_raw_result(name, message=message, code=code, rows_affected=rows_affected, agate_table=res) }}\\n  {%- endif -%}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0164108, \"supported_languages\": null}, \"macro.dbt.run_query\": {\"name\": \"run_query\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/etc/statement.sql\", \"original_file_path\": \"macros/etc/statement.sql\", \"unique_id\": \"macro.dbt.run_query\", \"macro_sql\": \"{% macro run_query(sql) %}\\n  {% call statement(\\\"run_query_statement\\\", fetch_result=true, auto_begin=false) %}\\n    {{ sql }}\\n  {% endcall %}\\n\\n  {% do return(load_result(\\\"run_query_statement\\\").table) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.016421, \"supported_languages\": null}, \"macro.dbt.convert_datetime\": {\"name\": \"convert_datetime\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"unique_id\": \"macro.dbt.convert_datetime\", \"macro_sql\": \"{% macro convert_datetime(date_str, date_fmt) %}\\n\\n  {% set error_msg -%}\\n      The provided partition date '{{ date_str }}' does not match the expected format '{{ date_fmt }}'\\n  {%- endset %}\\n\\n  {% set res = try_or_compiler_error(error_msg, modules.datetime.datetime.strptime, date_str.strip(), date_fmt) %}\\n  {{ return(res) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.016442, \"supported_languages\": null}, \"macro.dbt.dates_in_range\": {\"name\": \"dates_in_range\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"unique_id\": \"macro.dbt.dates_in_range\", \"macro_sql\": \"{% macro dates_in_range(start_date_str, end_date_str=none, in_fmt=\\\"%Y%m%d\\\", out_fmt=\\\"%Y%m%d\\\") %}\\n    {% set end_date_str = start_date_str if end_date_str is none else end_date_str %}\\n\\n    {% set start_date = convert_datetime(start_date_str, in_fmt) %}\\n    {% set end_date = convert_datetime(end_date_str, in_fmt) %}\\n\\n    {% set day_count = (end_date - start_date).days %}\\n    {% if day_count < 0 %}\\n        {% set msg -%}\\n            Partition start date is after the end date ({{ start_date }}, {{ end_date }})\\n        {%- endset %}\\n\\n        {{ exceptions.raise_compiler_error(msg, model) }}\\n    {% endif %}\\n\\n    {% set date_list = [] %}\\n    {% for i in range(0, day_count + 1) %}\\n        {% set the_date = (modules.datetime.timedelta(days=i) + start_date) %}\\n        {% if not out_fmt %}\\n            {% set _ = date_list.append(the_date) %}\\n        {% else %}\\n            {% set _ = date_list.append(the_date.strftime(out_fmt)) %}\\n        {% endif %}\\n    {% endfor %}\\n\\n    {{ return(date_list) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.convert_datetime\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.016452, \"supported_languages\": null}, \"macro.dbt.partition_range\": {\"name\": \"partition_range\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"unique_id\": \"macro.dbt.partition_range\", \"macro_sql\": \"{% macro partition_range(raw_partition_date, date_fmt='%Y%m%d') %}\\n    {% set partition_range = (raw_partition_date | string).split(\\\",\\\") %}\\n\\n    {% if (partition_range | length) == 1 %}\\n      {% set start_date = partition_range[0] %}\\n      {% set end_date = none %}\\n    {% elif (partition_range | length) == 2 %}\\n      {% set start_date = partition_range[0] %}\\n      {% set end_date = partition_range[1] %}\\n    {% else %}\\n      {{ exceptions.raise_compiler_error(\\\"Invalid partition time. Expected format: {Start Date}[,{End Date}]. Got: \\\" ~ raw_partition_date) }}\\n    {% endif %}\\n\\n    {{ return(dates_in_range(start_date, end_date, in_fmt=date_fmt)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.dates_in_range\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.016462, \"supported_languages\": null}, \"macro.dbt.py_current_timestring\": {\"name\": \"py_current_timestring\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"unique_id\": \"macro.dbt.py_current_timestring\", \"macro_sql\": \"{% macro py_current_timestring() %}\\n    {% set dt = modules.datetime.datetime.now() %}\\n    {% do return(dt.strftime(\\\"%Y%m%d%H%M%S%f\\\")) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.016473, \"supported_languages\": null}, \"macro.dbt.except\": {\"name\": \"except\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/except.sql\", \"original_file_path\": \"macros/utils/except.sql\", \"unique_id\": \"macro.dbt.except\", \"macro_sql\": \"{% macro except() %}\\n  {{ return(adapter.dispatch('except', 'dbt')()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__except\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.016493, \"supported_languages\": null}, \"macro.dbt.default__except\": {\"name\": \"default__except\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/except.sql\", \"original_file_path\": \"macros/utils/except.sql\", \"unique_id\": \"macro.dbt.default__except\", \"macro_sql\": \"{% macro default__except() %}\\n\\n    except\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.016503, \"supported_languages\": null}, \"macro.dbt.get_intervals_between\": {\"name\": \"get_intervals_between\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/date_spine.sql\", \"original_file_path\": \"macros/utils/date_spine.sql\", \"unique_id\": \"macro.dbt.get_intervals_between\", \"macro_sql\": \"{% macro get_intervals_between(start_date, end_date, datepart) -%}\\n    {{ return(adapter.dispatch('get_intervals_between', 'dbt')(start_date, end_date, datepart)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_intervals_between\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.016522, \"supported_languages\": null}, \"macro.dbt.default__get_intervals_between\": {\"name\": \"default__get_intervals_between\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/date_spine.sql\", \"original_file_path\": \"macros/utils/date_spine.sql\", \"unique_id\": \"macro.dbt.default__get_intervals_between\", \"macro_sql\": \"{% macro default__get_intervals_between(start_date, end_date, datepart) -%}\\n    {%- call statement('get_intervals_between', fetch_result=True) %}\\n\\n        select {{ dbt.datediff(start_date, end_date, datepart) }}\\n\\n    {%- endcall -%}\\n\\n    {%- set value_list = load_result('get_intervals_between') -%}\\n\\n    {%- if value_list and value_list['data'] -%}\\n        {%- set values = value_list['data'] | map(attribute=0) | list %}\\n        {{ return(values[0]) }}\\n    {%- else -%}\\n        {{ return(1) }}\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\", \"macro.dbt.datediff\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.016533, \"supported_languages\": null}, \"macro.dbt.date_spine\": {\"name\": \"date_spine\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/date_spine.sql\", \"original_file_path\": \"macros/utils/date_spine.sql\", \"unique_id\": \"macro.dbt.date_spine\", \"macro_sql\": \"{% macro date_spine(datepart, start_date, end_date) %}\\n    {{ return(adapter.dispatch('date_spine', 'dbt')(datepart, start_date, end_date)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__date_spine\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.016543, \"supported_languages\": null}, \"macro.dbt.default__date_spine\": {\"name\": \"default__date_spine\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/date_spine.sql\", \"original_file_path\": \"macros/utils/date_spine.sql\", \"unique_id\": \"macro.dbt.default__date_spine\", \"macro_sql\": \"{% macro default__date_spine(datepart, start_date, end_date) %}\\n\\n\\n    {# call as follows:\\n\\n    date_spine(\\n        \\\"day\\\",\\n        \\\"to_date('01/01/2016', 'mm/dd/yyyy')\\\",\\n        \\\"dbt.dateadd(week, 1, current_date)\\\"\\n    ) #}\\n\\n\\n    with rawdata as (\\n\\n        {{dbt.generate_series(\\n            dbt.get_intervals_between(start_date, end_date, datepart)\\n        )}}\\n\\n    ),\\n\\n    all_periods as (\\n\\n        select (\\n            {{\\n                dbt.dateadd(\\n                    datepart,\\n                    \\\"row_number() over (order by 1) - 1\\\",\\n                    start_date\\n                )\\n            }}\\n        ) as date_{{datepart}}\\n        from rawdata\\n\\n    ),\\n\\n    filtered as (\\n\\n        select *\\n        from all_periods\\n        where date_{{datepart}} <= {{ end_date }}\\n\\n    )\\n\\n    select * from filtered\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.generate_series\", \"macro.dbt.get_intervals_between\", \"macro.dbt.dateadd\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.016553, \"supported_languages\": null}, \"macro.dbt.date\": {\"name\": \"date\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/date.sql\", \"original_file_path\": \"macros/utils/date.sql\", \"unique_id\": \"macro.dbt.date\", \"macro_sql\": \"{% macro date(year, month, day) %}\\n  {{ return(adapter.dispatch('date', 'dbt') (year, month, day)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__date\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.016574, \"supported_languages\": null}, \"macro.dbt.default__date\": {\"name\": \"default__date\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/date.sql\", \"original_file_path\": \"macros/utils/date.sql\", \"unique_id\": \"macro.dbt.default__date\", \"macro_sql\": \"{% macro default__date(year, month, day) -%}\\n    {%- set dt = modules.datetime.date(year, month, day) -%}\\n    {%- set iso_8601_formatted_date = dt.strftime('%Y-%m-%d') -%}\\n    to_date('{{ iso_8601_formatted_date }}', 'YYYY-MM-DD')\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0165849, \"supported_languages\": null}, \"macro.dbt.replace\": {\"name\": \"replace\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/replace.sql\", \"original_file_path\": \"macros/utils/replace.sql\", \"unique_id\": \"macro.dbt.replace\", \"macro_sql\": \"{% macro replace(field, old_chars, new_chars) -%}\\n    {{ return(adapter.dispatch('replace', 'dbt') (field, old_chars, new_chars)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__replace\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.016604, \"supported_languages\": null}, \"macro.dbt.default__replace\": {\"name\": \"default__replace\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/replace.sql\", \"original_file_path\": \"macros/utils/replace.sql\", \"unique_id\": \"macro.dbt.default__replace\", \"macro_sql\": \"{% macro default__replace(field, old_chars, new_chars) %}\\n\\n    replace(\\n        {{ field }},\\n        {{ old_chars }},\\n        {{ new_chars }}\\n    )\\n\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.016615, \"supported_languages\": null}, \"macro.dbt.concat\": {\"name\": \"concat\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/concat.sql\", \"original_file_path\": \"macros/utils/concat.sql\", \"unique_id\": \"macro.dbt.concat\", \"macro_sql\": \"{% macro concat(fields) -%}\\n  {{ return(adapter.dispatch('concat', 'dbt')(fields)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__concat\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0166342, \"supported_languages\": null}, \"macro.dbt.default__concat\": {\"name\": \"default__concat\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/concat.sql\", \"original_file_path\": \"macros/utils/concat.sql\", \"unique_id\": \"macro.dbt.default__concat\", \"macro_sql\": \"{% macro default__concat(fields) -%}\\n    {{ fields|join(' || ') }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.016644, \"supported_languages\": null}, \"macro.dbt.get_powers_of_two\": {\"name\": \"get_powers_of_two\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/generate_series.sql\", \"original_file_path\": \"macros/utils/generate_series.sql\", \"unique_id\": \"macro.dbt.get_powers_of_two\", \"macro_sql\": \"{% macro get_powers_of_two(upper_bound) %}\\n    {{ return(adapter.dispatch('get_powers_of_two', 'dbt')(upper_bound)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_powers_of_two\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.016665, \"supported_languages\": null}, \"macro.dbt.default__get_powers_of_two\": {\"name\": \"default__get_powers_of_two\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/generate_series.sql\", \"original_file_path\": \"macros/utils/generate_series.sql\", \"unique_id\": \"macro.dbt.default__get_powers_of_two\", \"macro_sql\": \"{% macro default__get_powers_of_two(upper_bound) %}\\n\\n    {% if upper_bound <= 0 %}\\n    {{ exceptions.raise_compiler_error(\\\"upper bound must be positive\\\") }}\\n    {% endif %}\\n\\n    {% for _ in range(1, 100) %}\\n       {% if upper_bound <= 2 ** loop.index %}{{ return(loop.index) }}{% endif %}\\n    {% endfor %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.016675, \"supported_languages\": null}, \"macro.dbt.generate_series\": {\"name\": \"generate_series\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/generate_series.sql\", \"original_file_path\": \"macros/utils/generate_series.sql\", \"unique_id\": \"macro.dbt.generate_series\", \"macro_sql\": \"{% macro generate_series(upper_bound) %}\\n    {{ return(adapter.dispatch('generate_series', 'dbt')(upper_bound)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__generate_series\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.016685, \"supported_languages\": null}, \"macro.dbt.default__generate_series\": {\"name\": \"default__generate_series\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/generate_series.sql\", \"original_file_path\": \"macros/utils/generate_series.sql\", \"unique_id\": \"macro.dbt.default__generate_series\", \"macro_sql\": \"{% macro default__generate_series(upper_bound) %}\\n\\n    {% set n = dbt.get_powers_of_two(upper_bound) %}\\n\\n    with p as (\\n        select 0 as generated_number union all select 1\\n    ), unioned as (\\n\\n    select\\n\\n    {% for i in range(n) %}\\n    p{{i}}.generated_number * power(2, {{i}})\\n    {% if not loop.last %} + {% endif %}\\n    {% endfor %}\\n    + 1\\n    as generated_number\\n\\n    from\\n\\n    {% for i in range(n) %}\\n    p as p{{i}}\\n    {% if not loop.last %} cross join {% endif %}\\n    {% endfor %}\\n\\n    )\\n\\n    select *\\n    from unioned\\n    where generated_number <= {{upper_bound}}\\n    order by generated_number\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_powers_of_two\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.016695, \"supported_languages\": null}, \"macro.dbt.length\": {\"name\": \"length\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/length.sql\", \"original_file_path\": \"macros/utils/length.sql\", \"unique_id\": \"macro.dbt.length\", \"macro_sql\": \"{% macro length(expression) -%}\\n    {{ return(adapter.dispatch('length', 'dbt') (expression)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__length\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.016714, \"supported_languages\": null}, \"macro.dbt.default__length\": {\"name\": \"default__length\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/length.sql\", \"original_file_path\": \"macros/utils/length.sql\", \"unique_id\": \"macro.dbt.default__length\", \"macro_sql\": \"{% macro default__length(expression) %}\\n\\n    length(\\n        {{ expression }}\\n    )\\n\\n{%- endmacro -%}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.016725, \"supported_languages\": null}, \"macro.dbt.dateadd\": {\"name\": \"dateadd\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/dateadd.sql\", \"original_file_path\": \"macros/utils/dateadd.sql\", \"unique_id\": \"macro.dbt.dateadd\", \"macro_sql\": \"{% macro dateadd(datepart, interval, from_date_or_timestamp) %}\\n  {{ return(adapter.dispatch('dateadd', 'dbt')(datepart, interval, from_date_or_timestamp)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__dateadd\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.016744, \"supported_languages\": null}, \"macro.dbt.default__dateadd\": {\"name\": \"default__dateadd\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/dateadd.sql\", \"original_file_path\": \"macros/utils/dateadd.sql\", \"unique_id\": \"macro.dbt.default__dateadd\", \"macro_sql\": \"{% macro default__dateadd(datepart, interval, from_date_or_timestamp) %}\\n\\n    dateadd(\\n        {{ datepart }},\\n        {{ interval }},\\n        {{ from_date_or_timestamp }}\\n        )\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.016754, \"supported_languages\": null}, \"macro.dbt.intersect\": {\"name\": \"intersect\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/intersect.sql\", \"original_file_path\": \"macros/utils/intersect.sql\", \"unique_id\": \"macro.dbt.intersect\", \"macro_sql\": \"{% macro intersect() %}\\n  {{ return(adapter.dispatch('intersect', 'dbt')()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__intersect\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0167758, \"supported_languages\": null}, \"macro.dbt.default__intersect\": {\"name\": \"default__intersect\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/intersect.sql\", \"original_file_path\": \"macros/utils/intersect.sql\", \"unique_id\": \"macro.dbt.default__intersect\", \"macro_sql\": \"{% macro default__intersect() %}\\n\\n    intersect\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.016788, \"supported_languages\": null}, \"macro.dbt.escape_single_quotes\": {\"name\": \"escape_single_quotes\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/escape_single_quotes.sql\", \"original_file_path\": \"macros/utils/escape_single_quotes.sql\", \"unique_id\": \"macro.dbt.escape_single_quotes\", \"macro_sql\": \"{% macro escape_single_quotes(expression) %}\\n      {{ return(adapter.dispatch('escape_single_quotes', 'dbt') (expression)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__escape_single_quotes\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0169332, \"supported_languages\": null}, \"macro.dbt.default__escape_single_quotes\": {\"name\": \"default__escape_single_quotes\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/escape_single_quotes.sql\", \"original_file_path\": \"macros/utils/escape_single_quotes.sql\", \"unique_id\": \"macro.dbt.default__escape_single_quotes\", \"macro_sql\": \"{% macro default__escape_single_quotes(expression) -%}\\n{{ expression | replace(\\\"'\\\",\\\"''\\\") }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0169458, \"supported_languages\": null}, \"macro.dbt.right\": {\"name\": \"right\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/right.sql\", \"original_file_path\": \"macros/utils/right.sql\", \"unique_id\": \"macro.dbt.right\", \"macro_sql\": \"{% macro right(string_text, length_expression) -%}\\n    {{ return(adapter.dispatch('right', 'dbt') (string_text, length_expression)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__right\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.016968, \"supported_languages\": null}, \"macro.dbt.default__right\": {\"name\": \"default__right\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/right.sql\", \"original_file_path\": \"macros/utils/right.sql\", \"unique_id\": \"macro.dbt.default__right\", \"macro_sql\": \"{% macro default__right(string_text, length_expression) %}\\n\\n    right(\\n        {{ string_text }},\\n        {{ length_expression }}\\n    )\\n\\n{%- endmacro -%}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.016979, \"supported_languages\": null}, \"macro.dbt.listagg\": {\"name\": \"listagg\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/listagg.sql\", \"original_file_path\": \"macros/utils/listagg.sql\", \"unique_id\": \"macro.dbt.listagg\", \"macro_sql\": \"{% macro listagg(measure, delimiter_text=\\\"','\\\", order_by_clause=none, limit_num=none) -%}\\n    {{ return(adapter.dispatch('listagg', 'dbt') (measure, delimiter_text, order_by_clause, limit_num)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__listagg\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.017, \"supported_languages\": null}, \"macro.dbt.default__listagg\": {\"name\": \"default__listagg\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/listagg.sql\", \"original_file_path\": \"macros/utils/listagg.sql\", \"unique_id\": \"macro.dbt.default__listagg\", \"macro_sql\": \"{% macro default__listagg(measure, delimiter_text, order_by_clause, limit_num) -%}\\n\\n    {% if limit_num -%}\\n    array_to_string(\\n        array_slice(\\n            array_agg(\\n                {{ measure }}\\n            ){% if order_by_clause -%}\\n            within group ({{ order_by_clause }})\\n            {%- endif %}\\n            ,0\\n            ,{{ limit_num }}\\n        ),\\n        {{ delimiter_text }}\\n        )\\n    {%- else %}\\n    listagg(\\n        {{ measure }},\\n        {{ delimiter_text }}\\n        )\\n        {% if order_by_clause -%}\\n        within group ({{ order_by_clause }})\\n        {%- endif %}\\n    {%- endif %}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.01701, \"supported_languages\": null}, \"macro.dbt.datediff\": {\"name\": \"datediff\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/datediff.sql\", \"original_file_path\": \"macros/utils/datediff.sql\", \"unique_id\": \"macro.dbt.datediff\", \"macro_sql\": \"{% macro datediff(first_date, second_date, datepart) %}\\n  {{ return(adapter.dispatch('datediff', 'dbt')(first_date, second_date, datepart)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__datediff\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.01703, \"supported_languages\": null}, \"macro.dbt.default__datediff\": {\"name\": \"default__datediff\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/datediff.sql\", \"original_file_path\": \"macros/utils/datediff.sql\", \"unique_id\": \"macro.dbt.default__datediff\", \"macro_sql\": \"{% macro default__datediff(first_date, second_date, datepart) -%}\\n\\n    datediff(\\n        {{ datepart }},\\n        {{ first_date }},\\n        {{ second_date }}\\n        )\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.017548, \"supported_languages\": null}, \"macro.dbt.safe_cast\": {\"name\": \"safe_cast\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/safe_cast.sql\", \"original_file_path\": \"macros/utils/safe_cast.sql\", \"unique_id\": \"macro.dbt.safe_cast\", \"macro_sql\": \"{% macro safe_cast(field, type) %}\\n  {{ return(adapter.dispatch('safe_cast', 'dbt') (field, type)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__safe_cast\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.017575, \"supported_languages\": null}, \"macro.dbt.default__safe_cast\": {\"name\": \"default__safe_cast\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/safe_cast.sql\", \"original_file_path\": \"macros/utils/safe_cast.sql\", \"unique_id\": \"macro.dbt.default__safe_cast\", \"macro_sql\": \"{% macro default__safe_cast(field, type) %}\\n    {# most databases don't support this function yet\\n    so we just need to use cast #}\\n    cast({{field}} as {{type}})\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.017586, \"supported_languages\": null}, \"macro.dbt.equals\": {\"name\": \"equals\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/equals.sql\", \"original_file_path\": \"macros/utils/equals.sql\", \"unique_id\": \"macro.dbt.equals\", \"macro_sql\": \"{% macro equals(expr1, expr2) %}\\n    {{ return(adapter.dispatch('equals', 'dbt') (expr1, expr2)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__equals\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.017608, \"supported_languages\": null}, \"macro.dbt.default__equals\": {\"name\": \"default__equals\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/equals.sql\", \"original_file_path\": \"macros/utils/equals.sql\", \"unique_id\": \"macro.dbt.default__equals\", \"macro_sql\": \"{% macro default__equals(expr1, expr2) -%}\\n{%- if adapter.behavior.enable_truthy_nulls_equals_macro.no_warn %}\\n    case when (({{ expr1 }} = {{ expr2 }}) or ({{ expr1 }} is null and {{ expr2 }} is null))\\n        then 0\\n        else 1\\n    end = 0\\n{%- else -%}\\n    ({{ expr1 }} = {{ expr2 }})\\n{%- endif %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.017618, \"supported_languages\": null}, \"macro.dbt.hash\": {\"name\": \"hash\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/hash.sql\", \"original_file_path\": \"macros/utils/hash.sql\", \"unique_id\": \"macro.dbt.hash\", \"macro_sql\": \"{% macro hash(field) -%}\\n  {{ return(adapter.dispatch('hash', 'dbt') (field)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__hash\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.017652, \"supported_languages\": null}, \"macro.dbt.default__hash\": {\"name\": \"default__hash\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/hash.sql\", \"original_file_path\": \"macros/utils/hash.sql\", \"unique_id\": \"macro.dbt.default__hash\", \"macro_sql\": \"{% macro default__hash(field) -%}\\n    md5(cast({{ field }} as {{ api.Column.translate_type('string') }}))\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.017663, \"supported_languages\": null}, \"macro.dbt.cast_bool_to_text\": {\"name\": \"cast_bool_to_text\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/cast_bool_to_text.sql\", \"original_file_path\": \"macros/utils/cast_bool_to_text.sql\", \"unique_id\": \"macro.dbt.cast_bool_to_text\", \"macro_sql\": \"{% macro cast_bool_to_text(field) %}\\n  {{ adapter.dispatch('cast_bool_to_text', 'dbt') (field) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__cast_bool_to_text\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0176818, \"supported_languages\": null}, \"macro.dbt.default__cast_bool_to_text\": {\"name\": \"default__cast_bool_to_text\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/cast_bool_to_text.sql\", \"original_file_path\": \"macros/utils/cast_bool_to_text.sql\", \"unique_id\": \"macro.dbt.default__cast_bool_to_text\", \"macro_sql\": \"{% macro default__cast_bool_to_text(field) %}\\n    cast({{ field }} as {{ api.Column.translate_type('string') }})\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0177002, \"supported_languages\": null}, \"macro.dbt.cast\": {\"name\": \"cast\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/cast.sql\", \"original_file_path\": \"macros/utils/cast.sql\", \"unique_id\": \"macro.dbt.cast\", \"macro_sql\": \"{% macro cast(field, type) %}\\n  {{ return(adapter.dispatch('cast', 'dbt') (field, type)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__cast\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.017718, \"supported_languages\": null}, \"macro.dbt.default__cast\": {\"name\": \"default__cast\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/cast.sql\", \"original_file_path\": \"macros/utils/cast.sql\", \"unique_id\": \"macro.dbt.default__cast\", \"macro_sql\": \"{% macro default__cast(field, type) %}\\n    cast({{field}} as {{type}})\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.017728, \"supported_languages\": null}, \"macro.dbt.any_value\": {\"name\": \"any_value\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/any_value.sql\", \"original_file_path\": \"macros/utils/any_value.sql\", \"unique_id\": \"macro.dbt.any_value\", \"macro_sql\": \"{% macro any_value(expression) -%}\\n    {{ return(adapter.dispatch('any_value', 'dbt') (expression)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__any_value\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0177479, \"supported_languages\": null}, \"macro.dbt.default__any_value\": {\"name\": \"default__any_value\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/any_value.sql\", \"original_file_path\": \"macros/utils/any_value.sql\", \"unique_id\": \"macro.dbt.default__any_value\", \"macro_sql\": \"{% macro default__any_value(expression) -%}\\n\\n    any_value({{ expression }})\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.017758, \"supported_languages\": null}, \"macro.dbt.position\": {\"name\": \"position\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/position.sql\", \"original_file_path\": \"macros/utils/position.sql\", \"unique_id\": \"macro.dbt.position\", \"macro_sql\": \"{% macro position(substring_text, string_text) -%}\\n    {{ return(adapter.dispatch('position', 'dbt') (substring_text, string_text)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__position\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.017777, \"supported_languages\": null}, \"macro.dbt.default__position\": {\"name\": \"default__position\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/position.sql\", \"original_file_path\": \"macros/utils/position.sql\", \"unique_id\": \"macro.dbt.default__position\", \"macro_sql\": \"{% macro default__position(substring_text, string_text) %}\\n\\n    position(\\n        {{ substring_text }} in {{ string_text }}\\n    )\\n\\n{%- endmacro -%}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.017787, \"supported_languages\": null}, \"macro.dbt.string_literal\": {\"name\": \"string_literal\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/literal.sql\", \"original_file_path\": \"macros/utils/literal.sql\", \"unique_id\": \"macro.dbt.string_literal\", \"macro_sql\": \"{%- macro string_literal(value) -%}\\n  {{ return(adapter.dispatch('string_literal', 'dbt') (value)) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__string_literal\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.017806, \"supported_languages\": null}, \"macro.dbt.default__string_literal\": {\"name\": \"default__string_literal\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/literal.sql\", \"original_file_path\": \"macros/utils/literal.sql\", \"unique_id\": \"macro.dbt.default__string_literal\", \"macro_sql\": \"{% macro default__string_literal(value) -%}\\n    '{{ value }}'\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.017816, \"supported_languages\": null}, \"macro.dbt.type_string\": {\"name\": \"type_string\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.type_string\", \"macro_sql\": \"\\n\\n{%- macro type_string() -%}\\n  {{ return(adapter.dispatch('type_string', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__type_string\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.017843, \"supported_languages\": null}, \"macro.dbt.default__type_string\": {\"name\": \"default__type_string\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.default__type_string\", \"macro_sql\": \"{% macro default__type_string() %}\\n    {{ return(api.Column.translate_type(\\\"string\\\")) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.017853, \"supported_languages\": null}, \"macro.dbt.type_timestamp\": {\"name\": \"type_timestamp\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.type_timestamp\", \"macro_sql\": \"\\n\\n{%- macro type_timestamp() -%}\\n  {{ return(adapter.dispatch('type_timestamp', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__type_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0178628, \"supported_languages\": null}, \"macro.dbt.default__type_timestamp\": {\"name\": \"default__type_timestamp\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.default__type_timestamp\", \"macro_sql\": \"{% macro default__type_timestamp() %}\\n    {{ return(api.Column.translate_type(\\\"timestamp\\\")) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0178728, \"supported_languages\": null}, \"macro.dbt.type_float\": {\"name\": \"type_float\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.type_float\", \"macro_sql\": \"\\n\\n{%- macro type_float() -%}\\n  {{ return(adapter.dispatch('type_float', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__type_float\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0178828, \"supported_languages\": null}, \"macro.dbt.default__type_float\": {\"name\": \"default__type_float\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.default__type_float\", \"macro_sql\": \"{% macro default__type_float() %}\\n    {{ return(api.Column.translate_type(\\\"float\\\")) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.017893, \"supported_languages\": null}, \"macro.dbt.type_numeric\": {\"name\": \"type_numeric\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.type_numeric\", \"macro_sql\": \"\\n\\n{%- macro type_numeric() -%}\\n  {{ return(adapter.dispatch('type_numeric', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__type_numeric\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.017905, \"supported_languages\": null}, \"macro.dbt.default__type_numeric\": {\"name\": \"default__type_numeric\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.default__type_numeric\", \"macro_sql\": \"{% macro default__type_numeric() %}\\n    {{ return(api.Column.numeric_type(\\\"numeric\\\", 28, 6)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.017916, \"supported_languages\": null}, \"macro.dbt.type_bigint\": {\"name\": \"type_bigint\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.type_bigint\", \"macro_sql\": \"\\n\\n{%- macro type_bigint() -%}\\n  {{ return(adapter.dispatch('type_bigint', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__type_bigint\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.017929, \"supported_languages\": null}, \"macro.dbt.default__type_bigint\": {\"name\": \"default__type_bigint\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.default__type_bigint\", \"macro_sql\": \"{% macro default__type_bigint() %}\\n    {{ return(api.Column.translate_type(\\\"bigint\\\")) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0179389, \"supported_languages\": null}, \"macro.dbt.type_int\": {\"name\": \"type_int\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.type_int\", \"macro_sql\": \"\\n\\n{%- macro type_int() -%}\\n  {{ return(adapter.dispatch('type_int', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__type_int\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.017977, \"supported_languages\": null}, \"macro.dbt.default__type_int\": {\"name\": \"default__type_int\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.default__type_int\", \"macro_sql\": \"{%- macro default__type_int() -%}\\n  {{ return(api.Column.translate_type(\\\"integer\\\")) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018013, \"supported_languages\": null}, \"macro.dbt.type_boolean\": {\"name\": \"type_boolean\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.type_boolean\", \"macro_sql\": \"\\n\\n{%- macro type_boolean() -%}\\n  {{ return(adapter.dispatch('type_boolean', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__type_boolean\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0180259, \"supported_languages\": null}, \"macro.dbt.default__type_boolean\": {\"name\": \"default__type_boolean\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.default__type_boolean\", \"macro_sql\": \"{%- macro default__type_boolean() -%}\\n  {{ return(api.Column.translate_type(\\\"boolean\\\")) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018037, \"supported_languages\": null}, \"macro.dbt.array_concat\": {\"name\": \"array_concat\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/array_concat.sql\", \"original_file_path\": \"macros/utils/array_concat.sql\", \"unique_id\": \"macro.dbt.array_concat\", \"macro_sql\": \"{% macro array_concat(array_1, array_2) -%}\\n  {{ return(adapter.dispatch('array_concat', 'dbt')(array_1, array_2)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__array_concat\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018074, \"supported_languages\": null}, \"macro.dbt.default__array_concat\": {\"name\": \"default__array_concat\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/array_concat.sql\", \"original_file_path\": \"macros/utils/array_concat.sql\", \"unique_id\": \"macro.dbt.default__array_concat\", \"macro_sql\": \"{% macro default__array_concat(array_1, array_2) -%}\\n    array_cat({{ array_1 }}, {{ array_2 }})\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018085, \"supported_languages\": null}, \"macro.dbt.bool_or\": {\"name\": \"bool_or\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/bool_or.sql\", \"original_file_path\": \"macros/utils/bool_or.sql\", \"unique_id\": \"macro.dbt.bool_or\", \"macro_sql\": \"{% macro bool_or(expression) -%}\\n    {{ return(adapter.dispatch('bool_or', 'dbt') (expression)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__bool_or\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0181062, \"supported_languages\": null}, \"macro.dbt.default__bool_or\": {\"name\": \"default__bool_or\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/bool_or.sql\", \"original_file_path\": \"macros/utils/bool_or.sql\", \"unique_id\": \"macro.dbt.default__bool_or\", \"macro_sql\": \"{% macro default__bool_or(expression) -%}\\n\\n    bool_or({{ expression }})\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018116, \"supported_languages\": null}, \"macro.dbt.last_day\": {\"name\": \"last_day\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/last_day.sql\", \"original_file_path\": \"macros/utils/last_day.sql\", \"unique_id\": \"macro.dbt.last_day\", \"macro_sql\": \"{% macro last_day(date, datepart) %}\\n  {{ return(adapter.dispatch('last_day', 'dbt') (date, datepart)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__last_day\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018135, \"supported_languages\": null}, \"macro.dbt.default_last_day\": {\"name\": \"default_last_day\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/last_day.sql\", \"original_file_path\": \"macros/utils/last_day.sql\", \"unique_id\": \"macro.dbt.default_last_day\", \"macro_sql\": \"\\n\\n{%- macro default_last_day(date, datepart) -%}\\n    cast(\\n        {{dbt.dateadd('day', '-1',\\n        dbt.dateadd(datepart, '1', dbt.date_trunc(datepart, date))\\n        )}}\\n        as date)\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.dateadd\", \"macro.dbt.date_trunc\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018145, \"supported_languages\": null}, \"macro.dbt.default__last_day\": {\"name\": \"default__last_day\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/last_day.sql\", \"original_file_path\": \"macros/utils/last_day.sql\", \"unique_id\": \"macro.dbt.default__last_day\", \"macro_sql\": \"{% macro default__last_day(date, datepart) -%}\\n    {{dbt.default_last_day(date, datepart)}}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default_last_day\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018155, \"supported_languages\": null}, \"macro.dbt.split_part\": {\"name\": \"split_part\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/split_part.sql\", \"original_file_path\": \"macros/utils/split_part.sql\", \"unique_id\": \"macro.dbt.split_part\", \"macro_sql\": \"{% macro split_part(string_text, delimiter_text, part_number) %}\\n  {{ return(adapter.dispatch('split_part', 'dbt') (string_text, delimiter_text, part_number)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__split_part\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018175, \"supported_languages\": null}, \"macro.dbt.default__split_part\": {\"name\": \"default__split_part\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/split_part.sql\", \"original_file_path\": \"macros/utils/split_part.sql\", \"unique_id\": \"macro.dbt.default__split_part\", \"macro_sql\": \"{% macro default__split_part(string_text, delimiter_text, part_number) %}\\n\\n    split_part(\\n        {{ string_text }},\\n        {{ delimiter_text }},\\n        {{ part_number }}\\n        )\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018193, \"supported_languages\": null}, \"macro.dbt._split_part_negative\": {\"name\": \"_split_part_negative\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/split_part.sql\", \"original_file_path\": \"macros/utils/split_part.sql\", \"unique_id\": \"macro.dbt._split_part_negative\", \"macro_sql\": \"{% macro _split_part_negative(string_text, delimiter_text, part_number) %}\\n\\n    split_part(\\n        {{ string_text }},\\n        {{ delimiter_text }},\\n          length({{ string_text }})\\n          - length(\\n              replace({{ string_text }},  {{ delimiter_text }}, '')\\n          ) + 2 + {{ part_number }}\\n        )\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0182028, \"supported_languages\": null}, \"macro.dbt.date_trunc\": {\"name\": \"date_trunc\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/date_trunc.sql\", \"original_file_path\": \"macros/utils/date_trunc.sql\", \"unique_id\": \"macro.dbt.date_trunc\", \"macro_sql\": \"{% macro date_trunc(datepart, date) -%}\\n  {{ return(adapter.dispatch('date_trunc', 'dbt') (datepart, date)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__date_trunc\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018223, \"supported_languages\": null}, \"macro.dbt.default__date_trunc\": {\"name\": \"default__date_trunc\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/date_trunc.sql\", \"original_file_path\": \"macros/utils/date_trunc.sql\", \"unique_id\": \"macro.dbt.default__date_trunc\", \"macro_sql\": \"{% macro default__date_trunc(datepart, date) -%}\\n    date_trunc('{{datepart}}', {{date}})\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018233, \"supported_languages\": null}, \"macro.dbt.array_construct\": {\"name\": \"array_construct\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/array_construct.sql\", \"original_file_path\": \"macros/utils/array_construct.sql\", \"unique_id\": \"macro.dbt.array_construct\", \"macro_sql\": \"{% macro array_construct(inputs=[], data_type=api.Column.translate_type('integer')) -%}\\n  {{ return(adapter.dispatch('array_construct', 'dbt')(inputs, data_type)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__array_construct\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0182521, \"supported_languages\": null}, \"macro.dbt.default__array_construct\": {\"name\": \"default__array_construct\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/array_construct.sql\", \"original_file_path\": \"macros/utils/array_construct.sql\", \"unique_id\": \"macro.dbt.default__array_construct\", \"macro_sql\": \"{% macro default__array_construct(inputs, data_type) -%}\\n    {% if inputs|length > 0 %}\\n    array[ {{ inputs|join(' , ') }} ]\\n    {% else %}\\n    array[]::{{data_type}}[]\\n    {% endif %}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018263, \"supported_languages\": null}, \"macro.dbt.array_append\": {\"name\": \"array_append\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/array_append.sql\", \"original_file_path\": \"macros/utils/array_append.sql\", \"unique_id\": \"macro.dbt.array_append\", \"macro_sql\": \"{% macro array_append(array, new_element) -%}\\n  {{ return(adapter.dispatch('array_append', 'dbt')(array, new_element)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__array_append\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018283, \"supported_languages\": null}, \"macro.dbt.default__array_append\": {\"name\": \"default__array_append\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/array_append.sql\", \"original_file_path\": \"macros/utils/array_append.sql\", \"unique_id\": \"macro.dbt.default__array_append\", \"macro_sql\": \"{% macro default__array_append(array, new_element) -%}\\n    array_append({{ array }}, {{ new_element }})\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018293, \"supported_languages\": null}, \"macro.dbt.create_schema\": {\"name\": \"create_schema\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/schema.sql\", \"original_file_path\": \"macros/adapters/schema.sql\", \"unique_id\": \"macro.dbt.create_schema\", \"macro_sql\": \"{% macro create_schema(relation) -%}\\n  {{ adapter.dispatch('create_schema', 'dbt')(relation) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__create_schema\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018314, \"supported_languages\": null}, \"macro.dbt.default__create_schema\": {\"name\": \"default__create_schema\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/schema.sql\", \"original_file_path\": \"macros/adapters/schema.sql\", \"unique_id\": \"macro.dbt.default__create_schema\", \"macro_sql\": \"{% macro default__create_schema(relation) -%}\\n  {%- call statement('create_schema') -%}\\n    create schema if not exists {{ relation.without_identifier() }}\\n  {% endcall %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018324, \"supported_languages\": null}, \"macro.dbt.drop_schema\": {\"name\": \"drop_schema\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/schema.sql\", \"original_file_path\": \"macros/adapters/schema.sql\", \"unique_id\": \"macro.dbt.drop_schema\", \"macro_sql\": \"{% macro drop_schema(relation) -%}\\n  {{ adapter.dispatch('drop_schema', 'dbt')(relation) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__drop_schema\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018334, \"supported_languages\": null}, \"macro.dbt.default__drop_schema\": {\"name\": \"default__drop_schema\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/schema.sql\", \"original_file_path\": \"macros/adapters/schema.sql\", \"unique_id\": \"macro.dbt.default__drop_schema\", \"macro_sql\": \"{% macro default__drop_schema(relation) -%}\\n  {%- call statement('drop_schema') -%}\\n    drop schema if exists {{ relation.without_identifier() }} cascade\\n  {% endcall %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018343, \"supported_languages\": null}, \"macro.dbt.current_timestamp\": {\"name\": \"current_timestamp\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"unique_id\": \"macro.dbt.current_timestamp\", \"macro_sql\": \"{%- macro current_timestamp() -%}\\n    {{ adapter.dispatch('current_timestamp', 'dbt')() }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018365, \"supported_languages\": null}, \"macro.dbt.default__current_timestamp\": {\"name\": \"default__current_timestamp\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"unique_id\": \"macro.dbt.default__current_timestamp\", \"macro_sql\": \"{% macro default__current_timestamp() -%}\\n  {{ exceptions.raise_not_implemented(\\n    'current_timestamp macro not implemented for adapter ' + adapter.type()) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0183759, \"supported_languages\": null}, \"macro.dbt.snapshot_get_time\": {\"name\": \"snapshot_get_time\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"unique_id\": \"macro.dbt.snapshot_get_time\", \"macro_sql\": \"\\n\\n{%- macro snapshot_get_time() -%}\\n    {{ adapter.dispatch('snapshot_get_time', 'dbt')() }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__snapshot_get_time\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018404, \"supported_languages\": null}, \"macro.dbt.default__snapshot_get_time\": {\"name\": \"default__snapshot_get_time\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"unique_id\": \"macro.dbt.default__snapshot_get_time\", \"macro_sql\": \"{% macro default__snapshot_get_time() %}\\n    {{ current_timestamp() }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018414, \"supported_languages\": null}, \"macro.dbt.get_snapshot_get_time_data_type\": {\"name\": \"get_snapshot_get_time_data_type\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"unique_id\": \"macro.dbt.get_snapshot_get_time_data_type\", \"macro_sql\": \"{% macro get_snapshot_get_time_data_type() %}\\n    {% set snapshot_time = adapter.dispatch('snapshot_get_time', 'dbt')() %}\\n    {% set time_data_type_sql = 'select ' ~ snapshot_time ~ ' as dbt_snapshot_time' %}\\n    {% set snapshot_time_column_schema = get_column_schema_from_query(time_data_type_sql) %}\\n    {% set time_data_type = snapshot_time_column_schema[0].dtype %}\\n    {{ return(time_data_type or none) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.snapshot_get_time\", \"macro.dbt_postgres.postgres__snapshot_get_time\", \"macro.dbt.get_column_schema_from_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018424, \"supported_languages\": null}, \"macro.dbt.current_timestamp_backcompat\": {\"name\": \"current_timestamp_backcompat\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"unique_id\": \"macro.dbt.current_timestamp_backcompat\", \"macro_sql\": \"{% macro current_timestamp_backcompat() %}\\n    {{ return(adapter.dispatch('current_timestamp_backcompat', 'dbt')()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__current_timestamp_backcompat\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018434, \"supported_languages\": null}, \"macro.dbt.default__current_timestamp_backcompat\": {\"name\": \"default__current_timestamp_backcompat\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"unique_id\": \"macro.dbt.default__current_timestamp_backcompat\", \"macro_sql\": \"{% macro default__current_timestamp_backcompat() %}\\n    current_timestamp::timestamp\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018444, \"supported_languages\": null}, \"macro.dbt.current_timestamp_in_utc_backcompat\": {\"name\": \"current_timestamp_in_utc_backcompat\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"unique_id\": \"macro.dbt.current_timestamp_in_utc_backcompat\", \"macro_sql\": \"{% macro current_timestamp_in_utc_backcompat() %}\\n    {{ return(adapter.dispatch('current_timestamp_in_utc_backcompat', 'dbt')()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__current_timestamp_in_utc_backcompat\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018453, \"supported_languages\": null}, \"macro.dbt.default__current_timestamp_in_utc_backcompat\": {\"name\": \"default__current_timestamp_in_utc_backcompat\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"unique_id\": \"macro.dbt.default__current_timestamp_in_utc_backcompat\", \"macro_sql\": \"{% macro default__current_timestamp_in_utc_backcompat() %}\\n    {{ return(adapter.dispatch('current_timestamp_backcompat', 'dbt')()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.current_timestamp_backcompat\", \"macro.dbt_postgres.postgres__current_timestamp_backcompat\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018463, \"supported_languages\": null}, \"macro.dbt.get_create_index_sql\": {\"name\": \"get_create_index_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"unique_id\": \"macro.dbt.get_create_index_sql\", \"macro_sql\": \"{% macro get_create_index_sql(relation, index_dict) -%}\\n  {{ return(adapter.dispatch('get_create_index_sql', 'dbt')(relation, index_dict)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_create_index_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018485, \"supported_languages\": null}, \"macro.dbt.default__get_create_index_sql\": {\"name\": \"default__get_create_index_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"unique_id\": \"macro.dbt.default__get_create_index_sql\", \"macro_sql\": \"{% macro default__get_create_index_sql(relation, index_dict) -%}\\n  {% do return(None) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018496, \"supported_languages\": null}, \"macro.dbt.create_indexes\": {\"name\": \"create_indexes\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"unique_id\": \"macro.dbt.create_indexes\", \"macro_sql\": \"{% macro create_indexes(relation) -%}\\n  {{ adapter.dispatch('create_indexes', 'dbt')(relation) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__create_indexes\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.01851, \"supported_languages\": null}, \"macro.dbt.default__create_indexes\": {\"name\": \"default__create_indexes\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"unique_id\": \"macro.dbt.default__create_indexes\", \"macro_sql\": \"{% macro default__create_indexes(relation) -%}\\n  {%- set _indexes = config.get('indexes', default=[]) -%}\\n\\n  {% for _index_dict in _indexes %}\\n    {% set create_index_sql = get_create_index_sql(relation, _index_dict) %}\\n    {% if create_index_sql %}\\n      {% do run_query(create_index_sql) %}\\n    {% endif %}\\n  {% endfor %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_create_index_sql\", \"macro.dbt.run_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.01852, \"supported_languages\": null}, \"macro.dbt.get_drop_index_sql\": {\"name\": \"get_drop_index_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"unique_id\": \"macro.dbt.get_drop_index_sql\", \"macro_sql\": \"{% macro get_drop_index_sql(relation, index_name) -%}\\n    {{ adapter.dispatch('get_drop_index_sql', 'dbt')(relation, index_name) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_drop_index_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018529, \"supported_languages\": null}, \"macro.dbt.default__get_drop_index_sql\": {\"name\": \"default__get_drop_index_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"unique_id\": \"macro.dbt.default__get_drop_index_sql\", \"macro_sql\": \"{% macro default__get_drop_index_sql(relation, index_name) -%}\\n    {{ exceptions.raise_compiler_error(\\\"`get_drop_index_sql has not been implemented for this adapter.\\\") }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018539, \"supported_languages\": null}, \"macro.dbt.get_show_indexes_sql\": {\"name\": \"get_show_indexes_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"unique_id\": \"macro.dbt.get_show_indexes_sql\", \"macro_sql\": \"{% macro get_show_indexes_sql(relation) -%}\\n    {{ adapter.dispatch('get_show_indexes_sql', 'dbt')(relation) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_show_indexes_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018549, \"supported_languages\": null}, \"macro.dbt.default__get_show_indexes_sql\": {\"name\": \"default__get_show_indexes_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"unique_id\": \"macro.dbt.default__get_show_indexes_sql\", \"macro_sql\": \"{% macro default__get_show_indexes_sql(relation) -%}\\n    {{ exceptions.raise_compiler_error(\\\"`get_show_indexes_sql has not been implemented for this adapter.\\\") }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018559, \"supported_languages\": null}, \"macro.dbt.make_intermediate_relation\": {\"name\": \"make_intermediate_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.make_intermediate_relation\", \"macro_sql\": \"{% macro make_intermediate_relation(base_relation, suffix='__dbt_tmp') %}\\n  {{ return(adapter.dispatch('make_intermediate_relation', 'dbt')(base_relation, suffix)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_intermediate_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018581, \"supported_languages\": null}, \"macro.dbt.default__make_intermediate_relation\": {\"name\": \"default__make_intermediate_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.default__make_intermediate_relation\", \"macro_sql\": \"{% macro default__make_intermediate_relation(base_relation, suffix) %}\\n    {{ return(default__make_temp_relation(base_relation, suffix)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__make_temp_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018591, \"supported_languages\": null}, \"macro.dbt.make_temp_relation\": {\"name\": \"make_temp_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.make_temp_relation\", \"macro_sql\": \"{% macro make_temp_relation(base_relation, suffix='__dbt_tmp') %}\\n  {#-- This ensures microbatch batches get unique temp relations to avoid clobbering --#}\\n  {% if suffix == '__dbt_tmp' and model.batch %}\\n    {% set suffix = suffix ~ '_' ~ model.batch.id %}\\n  {% endif %}\\n\\n  {{ return(adapter.dispatch('make_temp_relation', 'dbt')(base_relation, suffix)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_temp_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0186298, \"supported_languages\": null}, \"macro.dbt.default__make_temp_relation\": {\"name\": \"default__make_temp_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.default__make_temp_relation\", \"macro_sql\": \"{% macro default__make_temp_relation(base_relation, suffix) %}\\n    {%- set temp_identifier = base_relation.identifier ~ suffix -%}\\n    {%- set temp_relation = base_relation.incorporate(\\n                                path={\\\"identifier\\\": temp_identifier}) -%}\\n\\n    {{ return(temp_relation) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018641, \"supported_languages\": null}, \"macro.dbt.make_backup_relation\": {\"name\": \"make_backup_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.make_backup_relation\", \"macro_sql\": \"{% macro make_backup_relation(base_relation, backup_relation_type, suffix='__dbt_backup') %}\\n    {{ return(adapter.dispatch('make_backup_relation', 'dbt')(base_relation, backup_relation_type, suffix)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_backup_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018652, \"supported_languages\": null}, \"macro.dbt.default__make_backup_relation\": {\"name\": \"default__make_backup_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.default__make_backup_relation\", \"macro_sql\": \"{% macro default__make_backup_relation(base_relation, backup_relation_type, suffix) %}\\n    {%- set backup_identifier = base_relation.identifier ~ suffix -%}\\n    {%- set backup_relation = base_relation.incorporate(\\n                                  path={\\\"identifier\\\": backup_identifier},\\n                                  type=backup_relation_type\\n    ) -%}\\n    {{ return(backup_relation) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018662, \"supported_languages\": null}, \"macro.dbt.truncate_relation\": {\"name\": \"truncate_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.truncate_relation\", \"macro_sql\": \"{% macro truncate_relation(relation) -%}\\n  {{ return(adapter.dispatch('truncate_relation', 'dbt')(relation)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__truncate_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018671, \"supported_languages\": null}, \"macro.dbt.default__truncate_relation\": {\"name\": \"default__truncate_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.default__truncate_relation\", \"macro_sql\": \"{% macro default__truncate_relation(relation) -%}\\n  {% call statement('truncate_relation') -%}\\n    truncate table {{ relation.render() }}\\n  {%- endcall %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018682, \"supported_languages\": null}, \"macro.dbt.get_or_create_relation\": {\"name\": \"get_or_create_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.get_or_create_relation\", \"macro_sql\": \"{% macro get_or_create_relation(database, schema, identifier, type) -%}\\n  {{ return(adapter.dispatch('get_or_create_relation', 'dbt')(database, schema, identifier, type)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_or_create_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018691, \"supported_languages\": null}, \"macro.dbt.default__get_or_create_relation\": {\"name\": \"default__get_or_create_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.default__get_or_create_relation\", \"macro_sql\": \"{% macro default__get_or_create_relation(database, schema, identifier, type) %}\\n  {%- set target_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) %}\\n\\n  {% if target_relation %}\\n    {% do return([true, target_relation]) %}\\n  {% endif %}\\n\\n  {%- set new_relation = api.Relation.create(\\n      database=database,\\n      schema=schema,\\n      identifier=identifier,\\n      type=type\\n  ) -%}\\n  {% do return([false, new_relation]) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0187001, \"supported_languages\": null}, \"macro.dbt.load_cached_relation\": {\"name\": \"load_cached_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.load_cached_relation\", \"macro_sql\": \"{% macro load_cached_relation(relation) %}\\n  {% do return(adapter.get_relation(\\n    database=relation.database,\\n    schema=relation.schema,\\n    identifier=relation.identifier\\n  )) -%}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.01871, \"supported_languages\": null}, \"macro.dbt.load_relation\": {\"name\": \"load_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.load_relation\", \"macro_sql\": \"{% macro load_relation(relation) %}\\n    {{ return(load_cached_relation(relation)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.load_cached_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.01872, \"supported_languages\": null}, \"macro.dbt.collect_freshness\": {\"name\": \"collect_freshness\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/freshness.sql\", \"original_file_path\": \"macros/adapters/freshness.sql\", \"unique_id\": \"macro.dbt.collect_freshness\", \"macro_sql\": \"{% macro collect_freshness(source, loaded_at_field, filter) %}\\n  {{ return(adapter.dispatch('collect_freshness', 'dbt')(source, loaded_at_field, filter))}}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__collect_freshness\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018741, \"supported_languages\": null}, \"macro.dbt.default__collect_freshness\": {\"name\": \"default__collect_freshness\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/freshness.sql\", \"original_file_path\": \"macros/adapters/freshness.sql\", \"unique_id\": \"macro.dbt.default__collect_freshness\", \"macro_sql\": \"{% macro default__collect_freshness(source, loaded_at_field, filter) %}\\n  {% call statement('collect_freshness', fetch_result=True, auto_begin=False) -%}\\n    select\\n      max({{ loaded_at_field }}) as max_loaded_at,\\n      {{ current_timestamp() }} as snapshotted_at\\n    from {{ source }}\\n    {% if filter %}\\n    where {{ filter }}\\n    {% endif %}\\n  {% endcall %}\\n  {{ return(load_result('collect_freshness')) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\", \"macro.dbt.current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.01875, \"supported_languages\": null}, \"macro.dbt.collect_freshness_custom_sql\": {\"name\": \"collect_freshness_custom_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/freshness.sql\", \"original_file_path\": \"macros/adapters/freshness.sql\", \"unique_id\": \"macro.dbt.collect_freshness_custom_sql\", \"macro_sql\": \"{% macro collect_freshness_custom_sql(source, loaded_at_query) %}\\n  {{ return(adapter.dispatch('collect_freshness_custom_sql', 'dbt')(source, loaded_at_query))}}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__collect_freshness_custom_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.01876, \"supported_languages\": null}, \"macro.dbt.default__collect_freshness_custom_sql\": {\"name\": \"default__collect_freshness_custom_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/freshness.sql\", \"original_file_path\": \"macros/adapters/freshness.sql\", \"unique_id\": \"macro.dbt.default__collect_freshness_custom_sql\", \"macro_sql\": \"{% macro default__collect_freshness_custom_sql(source, loaded_at_query) %}\\n  {% call statement('collect_freshness_custom_sql', fetch_result=True, auto_begin=False) -%}\\n  with source_query as (\\n    {{ loaded_at_query }}\\n  )\\n  select\\n    (select * from source_query) as max_loaded_at,\\n    {{ current_timestamp() }} as snapshotted_at\\n  {% endcall %}\\n  {{ return(load_result('collect_freshness_custom_sql')) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\", \"macro.dbt.current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.01877, \"supported_languages\": null}, \"macro.dbt.validate_sql\": {\"name\": \"validate_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/validate_sql.sql\", \"original_file_path\": \"macros/adapters/validate_sql.sql\", \"unique_id\": \"macro.dbt.validate_sql\", \"macro_sql\": \"{% macro validate_sql(sql) -%}\\n  {{ return(adapter.dispatch('validate_sql', 'dbt')(sql)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__validate_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018788, \"supported_languages\": null}, \"macro.dbt.default__validate_sql\": {\"name\": \"default__validate_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/validate_sql.sql\", \"original_file_path\": \"macros/adapters/validate_sql.sql\", \"unique_id\": \"macro.dbt.default__validate_sql\", \"macro_sql\": \"{% macro default__validate_sql(sql) -%}\\n  {% call statement('validate_sql') -%}\\n    explain {{ sql }}\\n  {% endcall %}\\n  {{ return(load_result('validate_sql')) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0187972, \"supported_languages\": null}, \"macro.dbt.copy_grants\": {\"name\": \"copy_grants\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.copy_grants\", \"macro_sql\": \"{% macro copy_grants() %}\\n    {{ return(adapter.dispatch('copy_grants', 'dbt')()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__copy_grants\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018823, \"supported_languages\": null}, \"macro.dbt.default__copy_grants\": {\"name\": \"default__copy_grants\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.default__copy_grants\", \"macro_sql\": \"{% macro default__copy_grants() %}\\n    {{ return(True) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018833, \"supported_languages\": null}, \"macro.dbt.support_multiple_grantees_per_dcl_statement\": {\"name\": \"support_multiple_grantees_per_dcl_statement\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.support_multiple_grantees_per_dcl_statement\", \"macro_sql\": \"{% macro support_multiple_grantees_per_dcl_statement() %}\\n    {{ return(adapter.dispatch('support_multiple_grantees_per_dcl_statement', 'dbt')()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__support_multiple_grantees_per_dcl_statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018843, \"supported_languages\": null}, \"macro.dbt.default__support_multiple_grantees_per_dcl_statement\": {\"name\": \"default__support_multiple_grantees_per_dcl_statement\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.default__support_multiple_grantees_per_dcl_statement\", \"macro_sql\": \"\\n\\n{%- macro default__support_multiple_grantees_per_dcl_statement() -%}\\n    {{ return(True) }}\\n{%- endmacro -%}\\n\\n\\n\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018852, \"supported_languages\": null}, \"macro.dbt.should_revoke\": {\"name\": \"should_revoke\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.should_revoke\", \"macro_sql\": \"{% macro should_revoke(existing_relation, full_refresh_mode=True) %}\\n\\n    {% if not existing_relation %}\\n        {#-- The table doesn't already exist, so no grants to copy over --#}\\n        {{ return(False) }}\\n    {% elif full_refresh_mode %}\\n        {#-- The object is being REPLACED -- whether grants are copied over depends on the value of user config --#}\\n        {{ return(copy_grants()) }}\\n    {% else %}\\n        {#-- The table is being merged/upserted/inserted -- grants will be carried over --#}\\n        {{ return(True) }}\\n    {% endif %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.copy_grants\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018862, \"supported_languages\": null}, \"macro.dbt.get_show_grant_sql\": {\"name\": \"get_show_grant_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.get_show_grant_sql\", \"macro_sql\": \"{% macro get_show_grant_sql(relation) %}\\n    {{ return(adapter.dispatch(\\\"get_show_grant_sql\\\", \\\"dbt\\\")(relation)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_show_grant_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018871, \"supported_languages\": null}, \"macro.dbt.default__get_show_grant_sql\": {\"name\": \"default__get_show_grant_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.default__get_show_grant_sql\", \"macro_sql\": \"{% macro default__get_show_grant_sql(relation) %}\\n    show grants on {{ relation.render() }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018881, \"supported_languages\": null}, \"macro.dbt.get_grant_sql\": {\"name\": \"get_grant_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.get_grant_sql\", \"macro_sql\": \"{% macro get_grant_sql(relation, privilege, grantees) %}\\n    {{ return(adapter.dispatch('get_grant_sql', 'dbt')(relation, privilege, grantees)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_grant_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018891, \"supported_languages\": null}, \"macro.dbt.default__get_grant_sql\": {\"name\": \"default__get_grant_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.default__get_grant_sql\", \"macro_sql\": \"\\n\\n{%- macro default__get_grant_sql(relation, privilege, grantees) -%}\\n    grant {{ privilege }} on {{ relation.render() }} to {{ grantees | join(', ') }}\\n{%- endmacro -%}\\n\\n\\n\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018901, \"supported_languages\": null}, \"macro.dbt.get_revoke_sql\": {\"name\": \"get_revoke_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.get_revoke_sql\", \"macro_sql\": \"{% macro get_revoke_sql(relation, privilege, grantees) %}\\n    {{ return(adapter.dispatch('get_revoke_sql', 'dbt')(relation, privilege, grantees)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_revoke_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018911, \"supported_languages\": null}, \"macro.dbt.default__get_revoke_sql\": {\"name\": \"default__get_revoke_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.default__get_revoke_sql\", \"macro_sql\": \"\\n\\n{%- macro default__get_revoke_sql(relation, privilege, grantees) -%}\\n    revoke {{ privilege }} on {{ relation.render() }} from {{ grantees | join(', ') }}\\n{%- endmacro -%}\\n\\n\\n\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.01892, \"supported_languages\": null}, \"macro.dbt.get_dcl_statement_list\": {\"name\": \"get_dcl_statement_list\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.get_dcl_statement_list\", \"macro_sql\": \"{% macro get_dcl_statement_list(relation, grant_config, get_dcl_macro) %}\\n    {{ return(adapter.dispatch('get_dcl_statement_list', 'dbt')(relation, grant_config, get_dcl_macro)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_dcl_statement_list\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.01893, \"supported_languages\": null}, \"macro.dbt.default__get_dcl_statement_list\": {\"name\": \"default__get_dcl_statement_list\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.default__get_dcl_statement_list\", \"macro_sql\": \"\\n\\n{%- macro default__get_dcl_statement_list(relation, grant_config, get_dcl_macro) -%}\\n    {#\\n      -- Unpack grant_config into specific privileges and the set of users who need them granted/revoked.\\n      -- Depending on whether this database supports multiple grantees per statement, pass in the list of\\n      -- all grantees per privilege, or (if not) template one statement per privilege-grantee pair.\\n      -- `get_dcl_macro` will be either `get_grant_sql` or `get_revoke_sql`\\n    #}\\n    {%- set dcl_statements = [] -%}\\n    {%- for privilege, grantees in grant_config.items() %}\\n        {%- if support_multiple_grantees_per_dcl_statement() and grantees -%}\\n          {%- set dcl = get_dcl_macro(relation, privilege, grantees) -%}\\n          {%- do dcl_statements.append(dcl) -%}\\n        {%- else -%}\\n          {%- for grantee in grantees -%}\\n              {% set dcl = get_dcl_macro(relation, privilege, [grantee]) %}\\n              {%- do dcl_statements.append(dcl) -%}\\n          {% endfor -%}\\n        {%- endif -%}\\n    {%- endfor -%}\\n    {{ return(dcl_statements) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.support_multiple_grantees_per_dcl_statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0189471, \"supported_languages\": null}, \"macro.dbt.call_dcl_statements\": {\"name\": \"call_dcl_statements\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.call_dcl_statements\", \"macro_sql\": \"{% macro call_dcl_statements(dcl_statement_list) %}\\n    {{ return(adapter.dispatch(\\\"call_dcl_statements\\\", \\\"dbt\\\")(dcl_statement_list)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__call_dcl_statements\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018959, \"supported_languages\": null}, \"macro.dbt.default__call_dcl_statements\": {\"name\": \"default__call_dcl_statements\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.default__call_dcl_statements\", \"macro_sql\": \"{% macro default__call_dcl_statements(dcl_statement_list) %}\\n    {#\\n      -- By default, supply all grant + revoke statements in a single semicolon-separated block,\\n      -- so that they're all processed together.\\n\\n      -- Some databases do not support this. Those adapters will need to override this macro\\n      -- to run each statement individually.\\n    #}\\n    {% call statement('grants') %}\\n        {% for dcl_statement in dcl_statement_list %}\\n            {{ dcl_statement }};\\n        {% endfor %}\\n    {% endcall %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.018969, \"supported_languages\": null}, \"macro.dbt.apply_grants\": {\"name\": \"apply_grants\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.apply_grants\", \"macro_sql\": \"{% macro apply_grants(relation, grant_config, should_revoke) %}\\n    {{ return(adapter.dispatch(\\\"apply_grants\\\", \\\"dbt\\\")(relation, grant_config, should_revoke)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__apply_grants\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.01898, \"supported_languages\": null}, \"macro.dbt.default__apply_grants\": {\"name\": \"default__apply_grants\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.default__apply_grants\", \"macro_sql\": \"{% macro default__apply_grants(relation, grant_config, should_revoke=True) %}\\n    {#-- If grant_config is {} or None, this is a no-op --#}\\n    {% if grant_config %}\\n        {% if should_revoke %}\\n            {#-- We think previous grants may have carried over --#}\\n            {#-- Show current grants and calculate diffs --#}\\n            {% set current_grants_table = run_query(get_show_grant_sql(relation)) %}\\n            {% set current_grants_dict = adapter.standardize_grants_dict(current_grants_table) %}\\n            {% set needs_granting = diff_of_two_dicts(grant_config, current_grants_dict) %}\\n            {% set needs_revoking = diff_of_two_dicts(current_grants_dict, grant_config) %}\\n            {% if not (needs_granting or needs_revoking) %}\\n                {{ log('On ' ~ relation.render() ~': All grants are in place, no revocation or granting needed.')}}\\n            {% endif %}\\n        {% else %}\\n            {#-- We don't think there's any chance of previous grants having carried over. --#}\\n            {#-- Jump straight to granting what the user has configured. --#}\\n            {% set needs_revoking = {} %}\\n            {% set needs_granting = grant_config %}\\n        {% endif %}\\n        {% if needs_granting or needs_revoking %}\\n            {% set revoke_statement_list = get_dcl_statement_list(relation, needs_revoking, get_revoke_sql) %}\\n            {% set grant_statement_list = get_dcl_statement_list(relation, needs_granting, get_grant_sql) %}\\n            {% set dcl_statement_list = revoke_statement_list + grant_statement_list %}\\n            {% if dcl_statement_list %}\\n                {{ call_dcl_statements(dcl_statement_list) }}\\n            {% endif %}\\n        {% endif %}\\n    {% endif %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.run_query\", \"macro.dbt.get_show_grant_sql\", \"macro.dbt.get_dcl_statement_list\", \"macro.dbt.call_dcl_statements\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.01899, \"supported_languages\": null}, \"macro.dbt.get_show_sql\": {\"name\": \"get_show_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/show.sql\", \"original_file_path\": \"macros/adapters/show.sql\", \"unique_id\": \"macro.dbt.get_show_sql\", \"macro_sql\": \"{% macro get_show_sql(compiled_code, sql_header, limit) -%}\\n  {%- if sql_header is not none -%}\\n  {{ sql_header }}\\n  {%- endif %}\\n  {{ get_limit_subquery_sql(compiled_code, limit) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_limit_subquery_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.019017, \"supported_languages\": null}, \"macro.dbt.get_limit_subquery_sql\": {\"name\": \"get_limit_subquery_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/show.sql\", \"original_file_path\": \"macros/adapters/show.sql\", \"unique_id\": \"macro.dbt.get_limit_subquery_sql\", \"macro_sql\": \"\\n{%- macro get_limit_subquery_sql(sql, limit) -%}\\n  {{ adapter.dispatch('get_limit_sql', 'dbt')(sql, limit) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_limit_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.019028, \"supported_languages\": null}, \"macro.dbt.default__get_limit_sql\": {\"name\": \"default__get_limit_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/show.sql\", \"original_file_path\": \"macros/adapters/show.sql\", \"unique_id\": \"macro.dbt.default__get_limit_sql\", \"macro_sql\": \"{% macro default__get_limit_sql(sql, limit) %}\\n  {{ sql }}\\n  {% if limit is not none %}\\n  limit {{ limit }}\\n  {%- endif -%}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.019038, \"supported_languages\": null}, \"macro.dbt.alter_column_comment\": {\"name\": \"alter_column_comment\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"unique_id\": \"macro.dbt.alter_column_comment\", \"macro_sql\": \"{% macro alter_column_comment(relation, column_dict) -%}\\n  {{ return(adapter.dispatch('alter_column_comment', 'dbt')(relation, column_dict)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__alter_column_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.019069, \"supported_languages\": null}, \"macro.dbt.default__alter_column_comment\": {\"name\": \"default__alter_column_comment\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"unique_id\": \"macro.dbt.default__alter_column_comment\", \"macro_sql\": \"{% macro default__alter_column_comment(relation, column_dict) -%}\\n  {{ exceptions.raise_not_implemented(\\n    'alter_column_comment macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.01908, \"supported_languages\": null}, \"macro.dbt.alter_relation_comment\": {\"name\": \"alter_relation_comment\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"unique_id\": \"macro.dbt.alter_relation_comment\", \"macro_sql\": \"{% macro alter_relation_comment(relation, relation_comment) -%}\\n  {{ return(adapter.dispatch('alter_relation_comment', 'dbt')(relation, relation_comment)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__alter_relation_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.019098, \"supported_languages\": null}, \"macro.dbt.default__alter_relation_comment\": {\"name\": \"default__alter_relation_comment\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"unique_id\": \"macro.dbt.default__alter_relation_comment\", \"macro_sql\": \"{% macro default__alter_relation_comment(relation, relation_comment) -%}\\n  {{ exceptions.raise_not_implemented(\\n    'alter_relation_comment macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.019109, \"supported_languages\": null}, \"macro.dbt.persist_docs\": {\"name\": \"persist_docs\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"unique_id\": \"macro.dbt.persist_docs\", \"macro_sql\": \"{% macro persist_docs(relation, model, for_relation=true, for_columns=true) -%}\\n  {{ return(adapter.dispatch('persist_docs', 'dbt')(relation, model, for_relation, for_columns)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__persist_docs\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.019119, \"supported_languages\": null}, \"macro.dbt.default__persist_docs\": {\"name\": \"default__persist_docs\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"unique_id\": \"macro.dbt.default__persist_docs\", \"macro_sql\": \"{% macro default__persist_docs(relation, model, for_relation, for_columns) -%}\\n  {% if for_relation and config.persist_relation_docs() and model.description %}\\n    {% do run_query(alter_relation_comment(relation, model.description)) %}\\n  {% endif %}\\n\\n  {% if for_columns and config.persist_column_docs() and model.columns %}\\n    {% do run_query(alter_column_comment(relation, model.columns)) %}\\n  {% endif %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.run_query\", \"macro.dbt.alter_relation_comment\", \"macro.dbt.alter_column_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.019129, \"supported_languages\": null}, \"macro.dbt.get_catalog_relations\": {\"name\": \"get_catalog_relations\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.get_catalog_relations\", \"macro_sql\": \"{% macro get_catalog_relations(information_schema, relations) -%}\\n  {{ return(adapter.dispatch('get_catalog_relations', 'dbt')(information_schema, relations)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_catalog_relations\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0191538, \"supported_languages\": null}, \"macro.dbt.default__get_catalog_relations\": {\"name\": \"default__get_catalog_relations\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.default__get_catalog_relations\", \"macro_sql\": \"{% macro default__get_catalog_relations(information_schema, relations) -%}\\n  {% set typename = adapter.type() %}\\n  {% set msg -%}\\n    get_catalog_relations not implemented for {{ typename }}\\n  {%- endset %}\\n\\n  {{ exceptions.raise_compiler_error(msg) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0191638, \"supported_languages\": null}, \"macro.dbt.get_catalog\": {\"name\": \"get_catalog\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.get_catalog\", \"macro_sql\": \"{% macro get_catalog(information_schema, schemas) -%}\\n  {{ return(adapter.dispatch('get_catalog', 'dbt')(information_schema, schemas)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_catalog\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0191739, \"supported_languages\": null}, \"macro.dbt.default__get_catalog\": {\"name\": \"default__get_catalog\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.default__get_catalog\", \"macro_sql\": \"{% macro default__get_catalog(information_schema, schemas) -%}\\n\\n  {% set typename = adapter.type() %}\\n  {% set msg -%}\\n    get_catalog not implemented for {{ typename }}\\n  {%- endset %}\\n\\n  {{ exceptions.raise_compiler_error(msg) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.019184, \"supported_languages\": null}, \"macro.dbt.information_schema_name\": {\"name\": \"information_schema_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.information_schema_name\", \"macro_sql\": \"{% macro information_schema_name(database) %}\\n  {{ return(adapter.dispatch('information_schema_name', 'dbt')(database)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__information_schema_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0191948, \"supported_languages\": null}, \"macro.dbt.default__information_schema_name\": {\"name\": \"default__information_schema_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.default__information_schema_name\", \"macro_sql\": \"{% macro default__information_schema_name(database) -%}\\n  {%- if database -%}\\n    {{ database }}.INFORMATION_SCHEMA\\n  {%- else -%}\\n    INFORMATION_SCHEMA\\n  {%- endif -%}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.019205, \"supported_languages\": null}, \"macro.dbt.list_schemas\": {\"name\": \"list_schemas\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.list_schemas\", \"macro_sql\": \"{% macro list_schemas(database) -%}\\n  {{ return(adapter.dispatch('list_schemas', 'dbt')(database)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__list_schemas\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0192142, \"supported_languages\": null}, \"macro.dbt.default__list_schemas\": {\"name\": \"default__list_schemas\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.default__list_schemas\", \"macro_sql\": \"{% macro default__list_schemas(database) -%}\\n  {% set sql %}\\n    select distinct schema_name\\n    from {{ information_schema_name(database) }}.SCHEMATA\\n    where catalog_name ilike '{{ database }}'\\n  {% endset %}\\n  {{ return(run_query(sql)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.information_schema_name\", \"macro.dbt.run_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0192242, \"supported_languages\": null}, \"macro.dbt.check_schema_exists\": {\"name\": \"check_schema_exists\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.check_schema_exists\", \"macro_sql\": \"{% macro check_schema_exists(information_schema, schema) -%}\\n  {{ return(adapter.dispatch('check_schema_exists', 'dbt')(information_schema, schema)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__check_schema_exists\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.019234, \"supported_languages\": null}, \"macro.dbt.default__check_schema_exists\": {\"name\": \"default__check_schema_exists\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.default__check_schema_exists\", \"macro_sql\": \"{% macro default__check_schema_exists(information_schema, schema) -%}\\n  {% set sql -%}\\n        select count(*)\\n        from {{ information_schema.replace(information_schema_view='SCHEMATA') }}\\n        where catalog_name='{{ information_schema.database }}'\\n          and schema_name='{{ schema }}'\\n  {%- endset %}\\n  {{ return(run_query(sql)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.replace\", \"macro.dbt.run_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.019244, \"supported_languages\": null}, \"macro.dbt.list_relations_without_caching\": {\"name\": \"list_relations_without_caching\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.list_relations_without_caching\", \"macro_sql\": \"{% macro list_relations_without_caching(schema_relation) %}\\n  {{ return(adapter.dispatch('list_relations_without_caching', 'dbt')(schema_relation)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__list_relations_without_caching\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.019254, \"supported_languages\": null}, \"macro.dbt.default__list_relations_without_caching\": {\"name\": \"default__list_relations_without_caching\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.default__list_relations_without_caching\", \"macro_sql\": \"{% macro default__list_relations_without_caching(schema_relation) %}\\n  {{ exceptions.raise_not_implemented(\\n    'list_relations_without_caching macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.019263, \"supported_languages\": null}, \"macro.dbt.get_catalog_for_single_relation\": {\"name\": \"get_catalog_for_single_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.get_catalog_for_single_relation\", \"macro_sql\": \"{% macro get_catalog_for_single_relation(relation) %}\\n  {{ return(adapter.dispatch('get_catalog_for_single_relation', 'dbt')(relation)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_catalog_for_single_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.019273, \"supported_languages\": null}, \"macro.dbt.default__get_catalog_for_single_relation\": {\"name\": \"default__get_catalog_for_single_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.default__get_catalog_for_single_relation\", \"macro_sql\": \"{% macro default__get_catalog_for_single_relation(relation) %}\\n  {{ exceptions.raise_not_implemented(\\n    'get_catalog_for_single_relation macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.019283, \"supported_languages\": null}, \"macro.dbt.get_relations\": {\"name\": \"get_relations\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.get_relations\", \"macro_sql\": \"{% macro get_relations() %}\\n  {{ return(adapter.dispatch('get_relations', 'dbt')()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_relations\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0192919, \"supported_languages\": null}, \"macro.dbt.default__get_relations\": {\"name\": \"default__get_relations\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.default__get_relations\", \"macro_sql\": \"{% macro default__get_relations() %}\\n  {{ exceptions.raise_not_implemented(\\n    'get_relations macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.019302, \"supported_languages\": null}, \"macro.dbt.get_relation_last_modified\": {\"name\": \"get_relation_last_modified\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.get_relation_last_modified\", \"macro_sql\": \"{% macro get_relation_last_modified(information_schema, relations) %}\\n  {{ return(adapter.dispatch('get_relation_last_modified', 'dbt')(information_schema, relations)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_relation_last_modified\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0193121, \"supported_languages\": null}, \"macro.dbt.default__get_relation_last_modified\": {\"name\": \"default__get_relation_last_modified\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.default__get_relation_last_modified\", \"macro_sql\": \"{% macro default__get_relation_last_modified(information_schema, relations) %}\\n  {{ exceptions.raise_not_implemented(\\n    'get_relation_last_modified macro not implemented for adapter ' + adapter.type()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0193212, \"supported_languages\": null}, \"macro.dbt.get_columns_in_relation\": {\"name\": \"get_columns_in_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.get_columns_in_relation\", \"macro_sql\": \"{% macro get_columns_in_relation(relation) -%}\\n  {{ return(adapter.dispatch('get_columns_in_relation', 'dbt')(relation)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_columns_in_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.019346, \"supported_languages\": null}, \"macro.dbt.default__get_columns_in_relation\": {\"name\": \"default__get_columns_in_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.default__get_columns_in_relation\", \"macro_sql\": \"{% macro default__get_columns_in_relation(relation) -%}\\n  {{ exceptions.raise_not_implemented(\\n    'get_columns_in_relation macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.019357, \"supported_languages\": null}, \"macro.dbt.sql_convert_columns_in_relation\": {\"name\": \"sql_convert_columns_in_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.sql_convert_columns_in_relation\", \"macro_sql\": \"{% macro sql_convert_columns_in_relation(table) -%}\\n  {% set columns = [] %}\\n  {% for row in table %}\\n    {% do columns.append(api.Column(*row)) %}\\n  {% endfor %}\\n  {{ return(columns) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0193658, \"supported_languages\": null}, \"macro.dbt.get_list_of_column_names\": {\"name\": \"get_list_of_column_names\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.get_list_of_column_names\", \"macro_sql\": \"\\n\\n{%- macro get_list_of_column_names(columns) -%}\\n  {% set col_names = [] %}\\n  {% for col in columns %}\\n    {% do col_names.append(col.name) %}\\n  {% endfor %}\\n  {{ return(col_names) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.019376, \"supported_languages\": null}, \"macro.dbt.get_empty_subquery_sql\": {\"name\": \"get_empty_subquery_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.get_empty_subquery_sql\", \"macro_sql\": \"{% macro get_empty_subquery_sql(select_sql, select_sql_header=none) -%}\\n  {{ return(adapter.dispatch('get_empty_subquery_sql', 'dbt')(select_sql, select_sql_header)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_empty_subquery_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0193868, \"supported_languages\": null}, \"macro.dbt.default__get_empty_subquery_sql\": {\"name\": \"default__get_empty_subquery_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.default__get_empty_subquery_sql\", \"macro_sql\": \"{% macro default__get_empty_subquery_sql(select_sql, select_sql_header=none) %}\\n    {%- if select_sql_header is not none -%}\\n    {{ select_sql_header }}\\n    {%- endif -%}\\n    select * from (\\n        {{ select_sql }}\\n    ) as __dbt_sbq\\n    where false\\n    limit 0\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.019396, \"supported_languages\": null}, \"macro.dbt.get_empty_schema_sql\": {\"name\": \"get_empty_schema_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.get_empty_schema_sql\", \"macro_sql\": \"{% macro get_empty_schema_sql(columns) -%}\\n  {{ return(adapter.dispatch('get_empty_schema_sql', 'dbt')(columns)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_empty_schema_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.019406, \"supported_languages\": null}, \"macro.dbt.default__get_empty_schema_sql\": {\"name\": \"default__get_empty_schema_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.default__get_empty_schema_sql\", \"macro_sql\": \"{% macro default__get_empty_schema_sql(columns) %}\\n    {%- set col_err = [] -%}\\n    {%- set col_naked_numeric = [] -%}\\n    select\\n    {% for i in columns %}\\n      {%- set col = columns[i] -%}\\n      {%- if col['data_type'] is not defined -%}\\n        {%- do col_err.append(col['name']) -%}\\n      {#-- If this column's type is just 'numeric' then it is missing precision/scale, raise a warning --#}\\n      {%- elif col['data_type'].strip().lower() in ('numeric', 'decimal', 'number') -%}\\n        {%- do col_naked_numeric.append(col['name']) -%}\\n      {%- endif -%}\\n      {% set col_name = adapter.quote(col['name']) if col.get('quote') else col['name'] %}\\n      {{ cast('null', col['data_type']) }} as {{ col_name }}{{ \\\", \\\" if not loop.last }}\\n    {%- endfor -%}\\n    {%- if (col_err | length) > 0 -%}\\n      {{ exceptions.column_type_missing(column_names=col_err) }}\\n    {%- elif (col_naked_numeric | length) > 0 -%}\\n      {{ exceptions.warn(\\\"Detected columns with numeric type and unspecified precision/scale, this can lead to unintended rounding: \\\" ~ col_naked_numeric ~ \\\"`\\\") }}\\n    {%- endif -%}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.cast\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0194151, \"supported_languages\": null}, \"macro.dbt.get_column_schema_from_query\": {\"name\": \"get_column_schema_from_query\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.get_column_schema_from_query\", \"macro_sql\": \"{% macro get_column_schema_from_query(select_sql, select_sql_header=none) -%}\\n    {% set columns = [] %}\\n    {# -- Using an 'empty subquery' here to get the same schema as the given select_sql statement, without necessitating a data scan.#}\\n    {% set sql = get_empty_subquery_sql(select_sql, select_sql_header) %}\\n    {% set column_schema = adapter.get_column_schema_from_query(sql) %}\\n    {{ return(column_schema) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_empty_subquery_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.019425, \"supported_languages\": null}, \"macro.dbt.get_columns_in_query\": {\"name\": \"get_columns_in_query\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.get_columns_in_query\", \"macro_sql\": \"{% macro get_columns_in_query(select_sql) -%}\\n  {{ return(adapter.dispatch('get_columns_in_query', 'dbt')(select_sql)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_columns_in_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.019435, \"supported_languages\": null}, \"macro.dbt.default__get_columns_in_query\": {\"name\": \"default__get_columns_in_query\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.default__get_columns_in_query\", \"macro_sql\": \"{% macro default__get_columns_in_query(select_sql) %}\\n    {% call statement('get_columns_in_query', fetch_result=True, auto_begin=False) -%}\\n        {{ get_empty_subquery_sql(select_sql) }}\\n    {% endcall %}\\n    {{ return(load_result('get_columns_in_query').table.columns | map(attribute='name') | list) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\", \"macro.dbt.get_empty_subquery_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.019465, \"supported_languages\": null}, \"macro.dbt.alter_column_type\": {\"name\": \"alter_column_type\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.alter_column_type\", \"macro_sql\": \"{% macro alter_column_type(relation, column_name, new_column_type) -%}\\n  {{ return(adapter.dispatch('alter_column_type', 'dbt')(relation, column_name, new_column_type)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__alter_column_type\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.019476, \"supported_languages\": null}, \"macro.dbt.default__alter_column_type\": {\"name\": \"default__alter_column_type\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.default__alter_column_type\", \"macro_sql\": \"{% macro default__alter_column_type(relation, column_name, new_column_type) -%}\\n  {#\\n    1. Create a new column (w/ temp name and correct type)\\n    2. Copy data over to it\\n    3. Drop the existing column (cascade!)\\n    4. Rename the new column to existing column\\n  #}\\n  {%- set tmp_column = column_name + \\\"__dbt_alter\\\" -%}\\n\\n  {% call statement('alter_column_type') %}\\n    alter table {{ relation.render() }} add column {{ adapter.quote(tmp_column) }} {{ new_column_type }};\\n    update {{ relation.render() }} set {{ adapter.quote(tmp_column) }} = {{ adapter.quote(column_name) }};\\n    alter table {{ relation.render() }} drop column {{ adapter.quote(column_name) }} cascade;\\n    alter table {{ relation.render() }} rename column {{ adapter.quote(tmp_column) }} to {{ adapter.quote(column_name) }}\\n  {% endcall %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.019485, \"supported_languages\": null}, \"macro.dbt.alter_relation_add_remove_columns\": {\"name\": \"alter_relation_add_remove_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.alter_relation_add_remove_columns\", \"macro_sql\": \"{% macro alter_relation_add_remove_columns(relation, add_columns = none, remove_columns = none) -%}\\n  {{ return(adapter.dispatch('alter_relation_add_remove_columns', 'dbt')(relation, add_columns, remove_columns)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__alter_relation_add_remove_columns\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.019495, \"supported_languages\": null}, \"macro.dbt.default__alter_relation_add_remove_columns\": {\"name\": \"default__alter_relation_add_remove_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.default__alter_relation_add_remove_columns\", \"macro_sql\": \"{% macro default__alter_relation_add_remove_columns(relation, add_columns, remove_columns) %}\\n\\n  {% if add_columns is none %}\\n    {% set add_columns = [] %}\\n  {% endif %}\\n  {% if remove_columns is none %}\\n    {% set remove_columns = [] %}\\n  {% endif %}\\n\\n  {% set sql -%}\\n\\n     alter {{ relation.type }} {{ relation.render() }}\\n\\n            {% for column in add_columns %}\\n               add column {{ column.quoted }} {{ column.data_type }}{{ ',' if not loop.last }}\\n            {% endfor %}{{ ',' if add_columns and remove_columns }}\\n\\n            {% for column in remove_columns %}\\n                drop column {{ column.quoted }}{{ ',' if not loop.last }}\\n            {% endfor %}\\n\\n  {%- endset -%}\\n\\n  {% do run_query(sql) %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.run_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0195048, \"supported_languages\": null}, \"macro.dbt.get_fixture_sql\": {\"name\": \"get_fixture_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/unit_test_sql/get_fixture_sql.sql\", \"original_file_path\": \"macros/unit_test_sql/get_fixture_sql.sql\", \"unique_id\": \"macro.dbt.get_fixture_sql\", \"macro_sql\": \"{% macro get_fixture_sql(rows, column_name_to_data_types) %}\\n-- Fixture for {{ model.name }}\\n{% set default_row = {} %}\\n\\n{%- if not column_name_to_data_types -%}\\n{#-- Use defer_relation IFF it is available in the manifest and 'this' is missing from the database --#}\\n{%-   set this_or_defer_relation = defer_relation if (defer_relation and not load_relation(this)) else this -%}\\n{%-   set columns_in_relation = adapter.get_columns_in_relation(this_or_defer_relation) -%}\\n\\n{%-   set column_name_to_data_types = {} -%}\\n{%-   set column_name_to_quoted = {} -%}\\n{%-   for column in columns_in_relation -%}\\n\\n{#-- This needs to be a case-insensitive comparison --#}\\n{%-     do column_name_to_data_types.update({column.name|lower: column.data_type}) -%}\\n{%-     do column_name_to_quoted.update({column.name|lower: column.quoted}) -%}\\n{%-   endfor -%}\\n{%- endif -%}\\n\\n{%- if not column_name_to_data_types -%}\\n    {{ exceptions.raise_compiler_error(\\\"Not able to get columns for unit test '\\\" ~ model.name ~ \\\"' from relation \\\" ~ this ~ \\\" because the relation doesn't exist\\\") }}\\n{%- endif -%}\\n\\n{%- for column_name, column_type in column_name_to_data_types.items() -%}\\n    {%- do default_row.update({column_name: (safe_cast(\\\"null\\\", column_type) | trim )}) -%}\\n{%- endfor -%}\\n\\n{{ validate_fixture_rows(rows, row_number) }}\\n\\n{%- for row in rows -%}\\n{%-   set formatted_row = format_row(row, column_name_to_data_types) -%}\\n{%-   set default_row_copy = default_row.copy() -%}\\n{%-   do default_row_copy.update(formatted_row) -%}\\nselect\\n{%-   for column_name, column_value in default_row_copy.items() %} {{ column_value }} as {{ column_name_to_quoted[column_name] }}{% if not loop.last -%}, {%- endif %}\\n{%-   endfor %}\\n{%-   if not loop.last %}\\nunion all\\n{%    endif %}\\n{%- endfor -%}\\n\\n{%- if (rows | length) == 0 -%}\\n    select\\n    {%- for column_name, column_value in default_row.items() %} {{ column_value }} as {{ column_name_to_quoted[column_name] }}{% if not loop.last -%},{%- endif %}\\n    {%- endfor %}\\n    limit 0\\n{%- endif -%}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.load_relation\", \"macro.dbt.safe_cast\", \"macro.dbt.validate_fixture_rows\", \"macro.dbt.format_row\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.019527, \"supported_languages\": null}, \"macro.dbt.get_expected_sql\": {\"name\": \"get_expected_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/unit_test_sql/get_fixture_sql.sql\", \"original_file_path\": \"macros/unit_test_sql/get_fixture_sql.sql\", \"unique_id\": \"macro.dbt.get_expected_sql\", \"macro_sql\": \"{% macro get_expected_sql(rows, column_name_to_data_types, column_name_to_quoted) %}\\n\\n{%- if (rows | length) == 0 -%}\\n    select * from dbt_internal_unit_test_actual\\n    limit 0\\n{%- else -%}\\n{%- for row in rows -%}\\n{%- set formatted_row = format_row(row, column_name_to_data_types) -%}\\nselect\\n{%- for column_name, column_value in formatted_row.items() %} {{ column_value }} as {{ column_name_to_quoted[column_name] }}{% if not loop.last -%}, {%- endif %}\\n{%- endfor %}\\n{%- if not loop.last %}\\nunion all\\n{% endif %}\\n{%- endfor -%}\\n{%- endif -%}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.format_row\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.019538, \"supported_languages\": null}, \"macro.dbt.format_row\": {\"name\": \"format_row\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/unit_test_sql/get_fixture_sql.sql\", \"original_file_path\": \"macros/unit_test_sql/get_fixture_sql.sql\", \"unique_id\": \"macro.dbt.format_row\", \"macro_sql\": \"\\n\\n{%- macro format_row(row, column_name_to_data_types) -%}\\n    {#-- generate case-insensitive formatted row --#}\\n    {% set formatted_row = {} %}\\n    {%- for column_name, column_value in row.items() -%}\\n        {% set column_name = column_name|lower %}\\n\\n        {%- if column_name not in column_name_to_data_types %}\\n            {#-- if user-provided row contains column name that relation does not contain, raise an error --#}\\n            {% set fixture_name = \\\"expected output\\\" if model.resource_type == 'unit_test' else (\\\"'\\\" ~ model.name ~ \\\"'\\\") %}\\n            {{ exceptions.raise_compiler_error(\\n                \\\"Invalid column name: '\\\" ~ column_name ~ \\\"' in unit test fixture for \\\" ~ fixture_name ~ \\\".\\\"\\n                \\\"\\\\nAccepted columns for \\\" ~ fixture_name ~ \\\" are: \\\" ~ (column_name_to_data_types.keys()|list)\\n            ) }}\\n        {%- endif -%}\\n\\n        {%- set column_type = column_name_to_data_types[column_name] %}\\n\\n        {#-- sanitize column_value: wrap yaml strings in quotes, apply cast --#}\\n        {%- set column_value_clean = column_value -%}\\n        {%- if column_value is string -%}\\n            {%- set column_value_clean = dbt.string_literal(dbt.escape_single_quotes(column_value)) -%}\\n        {%- elif column_value is none -%}\\n            {%- set column_value_clean = 'null' -%}\\n        {%- endif -%}\\n\\n        {%- set row_update = {column_name: safe_cast(column_value_clean, column_type) } -%}\\n        {%- do formatted_row.update(row_update) -%}\\n    {%- endfor -%}\\n    {{ return(formatted_row) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.string_literal\", \"macro.dbt.escape_single_quotes\", \"macro.dbt.safe_cast\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.019548, \"supported_languages\": null}, \"macro.dbt.validate_fixture_rows\": {\"name\": \"validate_fixture_rows\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/unit_test_sql/get_fixture_sql.sql\", \"original_file_path\": \"macros/unit_test_sql/get_fixture_sql.sql\", \"unique_id\": \"macro.dbt.validate_fixture_rows\", \"macro_sql\": \"{%- macro validate_fixture_rows(rows, row_number) -%}\\n  {{ return(adapter.dispatch('validate_fixture_rows', 'dbt')(rows, row_number)) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__validate_fixture_rows\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.019558, \"supported_languages\": null}, \"macro.dbt.default__validate_fixture_rows\": {\"name\": \"default__validate_fixture_rows\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/unit_test_sql/get_fixture_sql.sql\", \"original_file_path\": \"macros/unit_test_sql/get_fixture_sql.sql\", \"unique_id\": \"macro.dbt.default__validate_fixture_rows\", \"macro_sql\": \"{%- macro default__validate_fixture_rows(rows, row_number) -%}\\n  {# This is an abstract method for adapter overrides as needed #}\\n{%- endmacro -%}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0195682, \"supported_languages\": null}, \"macro.dbt.resolve_model_name\": {\"name\": \"resolve_model_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/python_model/python.sql\", \"original_file_path\": \"macros/python_model/python.sql\", \"unique_id\": \"macro.dbt.resolve_model_name\", \"macro_sql\": \"{% macro resolve_model_name(input_model_name) %}\\n    {{ return(adapter.dispatch('resolve_model_name', 'dbt')(input_model_name)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__resolve_model_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.01959, \"supported_languages\": null}, \"macro.dbt.default__resolve_model_name\": {\"name\": \"default__resolve_model_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/python_model/python.sql\", \"original_file_path\": \"macros/python_model/python.sql\", \"unique_id\": \"macro.dbt.default__resolve_model_name\", \"macro_sql\": \"\\n\\n{%- macro default__resolve_model_name(input_model_name) -%}\\n    {{  input_model_name | string | replace('\\\"', '\\\\\\\"') }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0196, \"supported_languages\": null}, \"macro.dbt.build_ref_function\": {\"name\": \"build_ref_function\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/python_model/python.sql\", \"original_file_path\": \"macros/python_model/python.sql\", \"unique_id\": \"macro.dbt.build_ref_function\", \"macro_sql\": \"{% macro build_ref_function(model) %}\\n\\n    {%- set ref_dict = {} -%}\\n    {%- for _ref in model.refs -%}\\n        {% set _ref_args = [_ref.get('package'), _ref['name']] if _ref.get('package') else [_ref['name'],] %}\\n        {%- set resolved = ref(*_ref_args, v=_ref.get('version')) -%}\\n\\n        {#\\n            We want to get the string of the returned relation by calling .render() in order to skip sample/empty\\n            mode rendering logic. However, people override the default ref macro, and often return a string instead\\n            of a relation (like the ref macro does by default). Thus, to make sure we dont blow things up, we have\\n            to ensure the resolved relation has a .render() method.\\n        #}\\n        {%- if resolved.render is defined and resolved.render is callable -%}\\n            {%- set resolved = resolved.render() -%}\\n        {%- endif -%}\\n\\n        {%- if _ref.get('version') -%}\\n            {% do _ref_args.extend([\\\"v\\\" ~ _ref['version']]) %}\\n        {%- endif -%}\\n       {%- do ref_dict.update({_ref_args | join('.'): resolve_model_name(resolved)}) -%}\\n    {%- endfor -%}\\n\\ndef ref(*args, **kwargs):\\n    refs = {{ ref_dict | tojson }}\\n    key = '.'.join(args)\\n    version = kwargs.get(\\\"v\\\") or kwargs.get(\\\"version\\\")\\n    if version:\\n        key += f\\\".v{version}\\\"\\n    dbt_load_df_function = kwargs.get(\\\"dbt_load_df_function\\\")\\n    return dbt_load_df_function(refs[key])\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.resolve_model_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.019609, \"supported_languages\": null}, \"macro.dbt.build_source_function\": {\"name\": \"build_source_function\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/python_model/python.sql\", \"original_file_path\": \"macros/python_model/python.sql\", \"unique_id\": \"macro.dbt.build_source_function\", \"macro_sql\": \"{% macro build_source_function(model) %}\\n\\n    {%- set source_dict = {} -%}\\n    {%- for _source in model.sources -%}\\n        {%- set resolved = source(*_source) -%}\\n        {%- do source_dict.update({_source | join('.'): resolve_model_name(resolved)}) -%}\\n    {%- endfor -%}\\n\\ndef source(*args, dbt_load_df_function):\\n    sources = {{ source_dict | tojson }}\\n    key = '.'.join(args)\\n    return dbt_load_df_function(sources[key])\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.resolve_model_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.019619, \"supported_languages\": null}, \"macro.dbt.build_config_dict\": {\"name\": \"build_config_dict\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/python_model/python.sql\", \"original_file_path\": \"macros/python_model/python.sql\", \"unique_id\": \"macro.dbt.build_config_dict\", \"macro_sql\": \"{% macro build_config_dict(model) %}\\n    {%- set config_dict = {} -%}\\n    {% set config_dbt_used = zip(model.config.config_keys_used, model.config.config_keys_defaults) | list %}\\n    {%- for key, default in config_dbt_used -%}\\n        {# weird type testing with enum, would be much easier to write this logic in Python! #}\\n        {%- if key == \\\"language\\\" -%}\\n          {%- set value = \\\"python\\\" -%}\\n        {%- endif -%}\\n        {%- set value = model.config.get(key, default) -%}\\n        {%- do config_dict.update({key: value}) -%}\\n    {%- endfor -%}\\nconfig_dict = {{ config_dict }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.019629, \"supported_languages\": null}, \"macro.dbt.py_script_postfix\": {\"name\": \"py_script_postfix\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/python_model/python.sql\", \"original_file_path\": \"macros/python_model/python.sql\", \"unique_id\": \"macro.dbt.py_script_postfix\", \"macro_sql\": \"{% macro py_script_postfix(model) %}\\n# This part is user provided model code\\n# you will need to copy the next section to run the code\\n# COMMAND ----------\\n# this part is dbt logic for get ref work, do not modify\\n\\n{{ build_ref_function(model ) }}\\n{{ build_source_function(model ) }}\\n{{ build_config_dict(model) }}\\n\\nclass config:\\n    def __init__(self, *args, **kwargs):\\n        pass\\n\\n    @staticmethod\\n    def get(key, default=None):\\n        return config_dict.get(key, default)\\n\\nclass this:\\n    \\\"\\\"\\\"dbt.this() or dbt.this.identifier\\\"\\\"\\\"\\n    database = \\\"{{ this.database }}\\\"\\n    schema = \\\"{{ this.schema }}\\\"\\n    identifier = \\\"{{ this.identifier }}\\\"\\n    {% set this_relation_name = resolve_model_name(this) %}\\n    def __repr__(self):\\n        return '{{ this_relation_name  }}'\\n\\n\\nclass dbtObj:\\n    def __init__(self, load_df_function) -> None:\\n        self.source = lambda *args: source(*args, dbt_load_df_function=load_df_function)\\n        self.ref = lambda *args, **kwargs: ref(*args, **kwargs, dbt_load_df_function=load_df_function)\\n        self.config = config\\n        self.this = this()\\n        self.is_incremental = {{ is_incremental() }}\\n\\n# COMMAND ----------\\n{{py_script_comment()}}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.build_ref_function\", \"macro.dbt.build_source_function\", \"macro.dbt.build_config_dict\", \"macro.dbt.resolve_model_name\", \"macro.dbt.is_incremental\", \"macro.dbt.py_script_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.019638, \"supported_languages\": null}, \"macro.dbt.py_script_comment\": {\"name\": \"py_script_comment\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/python_model/python.sql\", \"original_file_path\": \"macros/python_model/python.sql\", \"unique_id\": \"macro.dbt.py_script_comment\", \"macro_sql\": \"{%macro py_script_comment()%}\\n{%endmacro%}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.019648, \"supported_languages\": null}, \"macro.dbt.test_unique\": {\"name\": \"test_unique\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"tests/generic/builtin.sql\", \"original_file_path\": \"tests/generic/builtin.sql\", \"unique_id\": \"macro.dbt.test_unique\", \"macro_sql\": \"{% test unique(model, column_name) %}\\n    {% set macro = adapter.dispatch('test_unique', 'dbt') %}\\n    {{ macro(model, column_name) }}\\n{% endtest %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__test_unique\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0197601, \"supported_languages\": null}, \"macro.dbt.test_not_null\": {\"name\": \"test_not_null\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"tests/generic/builtin.sql\", \"original_file_path\": \"tests/generic/builtin.sql\", \"unique_id\": \"macro.dbt.test_not_null\", \"macro_sql\": \"{% test not_null(model, column_name) %}\\n    {% set macro = adapter.dispatch('test_not_null', 'dbt') %}\\n    {{ macro(model, column_name) }}\\n{% endtest %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__test_not_null\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.019809, \"supported_languages\": null}, \"macro.dbt.test_accepted_values\": {\"name\": \"test_accepted_values\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"tests/generic/builtin.sql\", \"original_file_path\": \"tests/generic/builtin.sql\", \"unique_id\": \"macro.dbt.test_accepted_values\", \"macro_sql\": \"{% test accepted_values(model, column_name, values, quote=True) %}\\n    {% set macro = adapter.dispatch('test_accepted_values', 'dbt') %}\\n    {{ macro(model, column_name, values, quote) }}\\n{% endtest %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__test_accepted_values\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.019872, \"supported_languages\": null}, \"macro.dbt.test_relationships\": {\"name\": \"test_relationships\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"tests/generic/builtin.sql\", \"original_file_path\": \"tests/generic/builtin.sql\", \"unique_id\": \"macro.dbt.test_relationships\", \"macro_sql\": \"{% test relationships(model, column_name, to, field) %}\\n    {% set macro = adapter.dispatch('test_relationships', 'dbt') %}\\n    {{ macro(model, column_name, to, field) }}\\n{% endtest %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__test_relationships\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1759423716.0199392, \"supported_languages\": null}}, \"docs\": {\"doc.test.somedoc\": {\"name\": \"somedoc\", \"resource_type\": \"doc\", \"package_name\": \"test\", \"path\": \"somedoc.md\", \"original_file_path\": \"models/somedoc.md\", \"unique_id\": \"doc.test.somedoc\", \"block_contents\": \"Testing, testing\"}, \"doc.dbt.__overview__\": {\"name\": \"__overview__\", \"resource_type\": \"doc\", \"package_name\": \"dbt\", \"path\": \"overview.md\", \"original_file_path\": \"docs/overview.md\", \"unique_id\": \"doc.dbt.__overview__\", \"block_contents\": \"### Welcome!\\n\\nWelcome to the auto-generated documentation for your dbt project!\\n\\n### Navigation\\n\\nYou can use the `Project` and `Database` navigation tabs on the left side of the window to explore the models\\nin your project.\\n\\n#### Project Tab\\nThe `Project` tab mirrors the directory structure of your dbt project. In this tab, you can see all of the\\nmodels defined in your dbt project, as well as models imported from dbt packages.\\n\\n#### Database Tab\\nThe `Database` tab also exposes your models, but in a format that looks more like a database explorer. This view\\nshows relations (tables and views) grouped into database schemas. Note that ephemeral models are _not_ shown\\nin this interface, as they do not exist in the database.\\n\\n### Graph Exploration\\nYou can click the blue icon on the bottom-right corner of the page to view the lineage graph of your models.\\n\\nOn model pages, you'll see the immediate parents and children of the model you're exploring. By clicking the `Expand`\\nbutton at the top-right of this lineage pane, you'll be able to see all of the models that are used to build,\\nor are built from, the model you're exploring.\\n\\nOnce expanded, you'll be able to use the `--select` and `--exclude` model selection syntax to filter the\\nmodels in the graph. For more information on model selection, check out the [dbt docs](https://docs.getdbt.com/docs/model-selection-syntax).\\n\\nNote that you can also right-click on models to interactively filter and explore the graph.\\n\\n---\\n\\n### More information\\n\\n- [What is dbt](https://docs.getdbt.com/docs/introduction)?\\n- Read the [dbt viewpoint](https://docs.getdbt.com/docs/viewpoint)\\n- [Installation](https://docs.getdbt.com/docs/installation)\\n- Join the [dbt Community](https://www.getdbt.com/community/) for questions and discussion\"}}, \"exposures\": {\"exposure.test.simple_exposure\": {\"name\": \"simple_exposure\", \"resource_type\": \"exposure\", \"package_name\": \"test\", \"path\": \"schema.yml\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"exposure.test.simple_exposure\", \"fqn\": [\"test\", \"simple_exposure\"], \"type\": \"dashboard\", \"owner\": {\"email\": \"something@example.com\", \"name\": null}, \"description\": \"\", \"label\": null, \"maturity\": null, \"meta\": {}, \"tags\": [], \"config\": {\"enabled\": true, \"tags\": [], \"meta\": {}}, \"unrendered_config\": {}, \"url\": null, \"depends_on\": {\"macros\": [], \"nodes\": [\"source.test.my_source.my_table\", \"model.test.my_model\"]}, \"refs\": [{\"name\": \"my_model\", \"package\": null, \"version\": null}], \"sources\": [[\"my_source\", \"my_table\"]], \"metrics\": [], \"created_at\": 1759423716.4544902}}, \"metrics\": {\"metric.test.blue_customers_post_2010\": {\"name\": \"blue_customers_post_2010\", \"resource_type\": \"metric\", \"package_name\": \"test\", \"path\": \"schema.yml\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"metric.test.blue_customers_post_2010\", \"fqn\": [\"test\", \"blue_customers_post_2010\"], \"description\": \"\", \"label\": \"Blue Customers since 2010\", \"type\": \"simple\", \"type_params\": {\"measure\": {\"name\": \"customers\", \"filter\": {\"where_filters\": [{\"where_sql_template\": \"{{ Dimension('id__favorite_color') }} = 'blue'\"}]}, \"alias\": null, \"join_to_timespine\": false, \"fill_nulls_with\": null}, \"input_measures\": [{\"name\": \"customers\", \"filter\": {\"where_filters\": [{\"where_sql_template\": \"{{ Dimension('id__favorite_color') }} = 'blue'\"}]}, \"alias\": null, \"join_to_timespine\": false, \"fill_nulls_with\": null}], \"numerator\": null, \"denominator\": null, \"expr\": null, \"window\": null, \"grain_to_date\": null, \"metrics\": [], \"conversion_type_params\": null, \"cumulative_type_params\": null, \"metric_aggregation_params\": null}, \"filter\": {\"where_filters\": [{\"where_sql_template\": \"{{ TimeDimension('id__created_at', 'day') }} > '2010-01-01'\"}]}, \"metadata\": null, \"time_granularity\": null, \"meta\": {}, \"tags\": [], \"config\": {\"enabled\": true, \"group\": null, \"meta\": {}}, \"unrendered_config\": {}, \"sources\": [], \"depends_on\": {\"macros\": [], \"nodes\": [\"semantic_model.test.semantic_people\"]}, \"refs\": [], \"metrics\": [], \"created_at\": 1759423716.7306838, \"group\": null}, \"metric.test.customers\": {\"name\": \"customers\", \"resource_type\": \"metric\", \"package_name\": \"test\", \"path\": \"schema.yml\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"metric.test.customers\", \"fqn\": [\"test\", \"customers\"], \"description\": \"\", \"label\": \"Customers Metric\", \"type\": \"simple\", \"type_params\": {\"measure\": {\"name\": \"customers\", \"filter\": null, \"alias\": null, \"join_to_timespine\": false, \"fill_nulls_with\": null}, \"input_measures\": [{\"name\": \"customers\", \"filter\": null, \"alias\": null, \"join_to_timespine\": false, \"fill_nulls_with\": null}], \"numerator\": null, \"denominator\": null, \"expr\": null, \"window\": null, \"grain_to_date\": null, \"metrics\": [], \"conversion_type_params\": null, \"cumulative_type_params\": null, \"metric_aggregation_params\": null}, \"filter\": null, \"metadata\": null, \"time_granularity\": null, \"meta\": {}, \"tags\": [], \"config\": {\"enabled\": true, \"group\": null, \"meta\": {}}, \"unrendered_config\": {}, \"sources\": [], \"depends_on\": {\"macros\": [], \"nodes\": [\"semantic_model.test.semantic_people\"]}, \"refs\": [], \"metrics\": [], \"created_at\": 1759423716.734397, \"group\": null}, \"metric.test.ratio_of_blue_customers_to_red_customers\": {\"name\": \"ratio_of_blue_customers_to_red_customers\", \"resource_type\": \"metric\", \"package_name\": \"test\", \"path\": \"schema.yml\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"metric.test.ratio_of_blue_customers_to_red_customers\", \"fqn\": [\"test\", \"ratio_of_blue_customers_to_red_customers\"], \"description\": \"\", \"label\": \"Very Important Customer Color Ratio\", \"type\": \"ratio\", \"type_params\": {\"measure\": null, \"input_measures\": [{\"name\": \"customers\", \"filter\": null, \"alias\": null, \"join_to_timespine\": false, \"fill_nulls_with\": null}], \"numerator\": {\"name\": \"customers\", \"filter\": {\"where_filters\": [{\"where_sql_template\": \"{{ Dimension('id__favorite_color')}} = 'blue'\"}]}, \"alias\": null, \"offset_window\": null, \"offset_to_grain\": null}, \"denominator\": {\"name\": \"customers\", \"filter\": {\"where_filters\": [{\"where_sql_template\": \"{{ Dimension('id__favorite_color')}} = 'red'\"}]}, \"alias\": null, \"offset_window\": null, \"offset_to_grain\": null}, \"expr\": null, \"window\": null, \"grain_to_date\": null, \"metrics\": [], \"conversion_type_params\": null, \"cumulative_type_params\": null, \"metric_aggregation_params\": null}, \"filter\": null, \"metadata\": null, \"time_granularity\": null, \"meta\": {}, \"tags\": [], \"config\": {\"enabled\": true, \"group\": null, \"meta\": {}}, \"unrendered_config\": {}, \"sources\": [], \"depends_on\": {\"macros\": [], \"nodes\": [\"metric.test.customers\"]}, \"refs\": [], \"metrics\": [], \"created_at\": 1759423716.748488, \"group\": null}, \"metric.test.doubled_blue_customers\": {\"name\": \"doubled_blue_customers\", \"resource_type\": \"metric\", \"package_name\": \"test\", \"path\": \"schema.yml\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"metric.test.doubled_blue_customers\", \"fqn\": [\"test\", \"doubled_blue_customers\"], \"description\": \"\", \"label\": \"Inflated blue customer numbers\", \"type\": \"derived\", \"type_params\": {\"measure\": null, \"input_measures\": [{\"name\": \"customers\", \"filter\": null, \"alias\": null, \"join_to_timespine\": false, \"fill_nulls_with\": null}], \"numerator\": null, \"denominator\": null, \"expr\": \"customers * 2\", \"window\": null, \"grain_to_date\": null, \"metrics\": [{\"name\": \"customers\", \"filter\": {\"where_filters\": [{\"where_sql_template\": \"{{ Dimension('id__favorite_color')}} = 'blue'\"}]}, \"alias\": null, \"offset_window\": null, \"offset_to_grain\": null}], \"conversion_type_params\": null, \"cumulative_type_params\": null, \"metric_aggregation_params\": null}, \"filter\": null, \"metadata\": null, \"time_granularity\": null, \"meta\": {}, \"tags\": [], \"config\": {\"enabled\": true, \"group\": null, \"meta\": {}}, \"unrendered_config\": {}, \"sources\": [], \"depends_on\": {\"macros\": [], \"nodes\": [\"metric.test.customers\"]}, \"refs\": [], \"metrics\": [], \"created_at\": 1759423716.753501, \"group\": null}}, \"groups\": {}, \"selectors\": {}, \"disabled\": {\"model.test.disabled_model\": [{\"database\": \"dbt\", \"schema\": \"test17594237163467600387_test_previous_version_state\", \"name\": \"disabled_model\", \"resource_type\": \"model\", \"package_name\": \"test\", \"path\": \"disabled_model.sql\", \"original_file_path\": \"models/disabled_model.sql\", \"unique_id\": \"model.test.disabled_model\", \"fqn\": [\"test\", \"disabled_model\"], \"alias\": \"disabled_model\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"597106d23ce34e3cd2430588e5c1cf474ebdd138fc47e09b925a4ab258a27acc\"}, \"config\": {\"enabled\": false, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"view\", \"incremental_strategy\": null, \"batch_size\": null, \"lookback\": 1, \"begin\": null, \"persist_docs\": {}, \"post-hook\": [], \"pre-hook\": [], \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": null, \"on_schema_change\": \"ignore\", \"on_configuration_change\": \"apply\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"contract\": {\"enforced\": false, \"alias_types\": true}, \"event_time\": null, \"concurrent_batches\": null, \"access\": \"protected\", \"freshness\": null}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"unrendered_config\": {\"enabled\": false}, \"created_at\": 1759423716.096579, \"relation_name\": \"\\\"dbt\\\".\\\"test17594237163467600387_test_previous_version_state\\\".\\\"disabled_model\\\"\", \"raw_code\": \"{{ config(enabled=False) }}\\nselect 2 as id\", \"doc_blocks\": [], \"language\": \"sql\", \"refs\": [], \"sources\": [], \"metrics\": [], \"functions\": [], \"depends_on\": {\"macros\": [], \"nodes\": []}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"alias_types\": true, \"checksum\": null}, \"access\": \"protected\", \"constraints\": [], \"version\": null, \"latest_version\": null, \"deprecation_date\": null, \"primary_key\": [], \"time_spine\": null}], \"snapshot.test.disabled_snapshot_seed\": [{\"database\": \"dbt\", \"schema\": \"test17594237163467600387_test_previous_version_state\", \"name\": \"disabled_snapshot_seed\", \"resource_type\": \"snapshot\", \"package_name\": \"test\", \"path\": \"disabled_snapshot_seed.sql\", \"original_file_path\": \"snapshots/disabled_snapshot_seed.sql\", \"unique_id\": \"snapshot.test.disabled_snapshot_seed\", \"fqn\": [\"test\", \"disabled_snapshot_seed\", \"disabled_snapshot_seed\"], \"alias\": \"disabled_snapshot_seed\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"fe76c9dd437341c9e82a0f2a8baf3148f961b768eaa0a4410cd27d3c071bd617\"}, \"config\": {\"enabled\": false, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"snapshot\", \"incremental_strategy\": null, \"batch_size\": null, \"lookback\": 1, \"begin\": null, \"persist_docs\": {}, \"post-hook\": [], \"pre-hook\": [], \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": \"id\", \"on_schema_change\": \"ignore\", \"on_configuration_change\": \"apply\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"contract\": {\"enforced\": false, \"alias_types\": true}, \"event_time\": null, \"concurrent_batches\": null, \"strategy\": \"check\", \"target_schema\": \"test17594237163467600387_test_previous_version_state\", \"target_database\": null, \"updated_at\": null, \"check_cols\": \"all\", \"snapshot_meta_column_names\": {\"dbt_valid_to\": null, \"dbt_valid_from\": null, \"dbt_scd_id\": null, \"dbt_updated_at\": null, \"dbt_is_deleted\": null}, \"dbt_valid_to_current\": null}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"unrendered_config\": {\"unique_key\": \"id\", \"strategy\": \"check\", \"check_cols\": \"all\", \"target_schema\": \"test17594237163467600387_test_previous_version_state\", \"enabled\": false}, \"created_at\": 1759423716.123988, \"relation_name\": \"\\\"dbt\\\".\\\"test17594237163467600387_test_previous_version_state\\\".\\\"disabled_snapshot_seed\\\"\", \"raw_code\": \"\\n{{\\n    config(\\n      unique_key='id',\\n      strategy='check',\\n      check_cols='all',\\n      target_schema=schema,\\n      enabled=False,\\n    )\\n}}\\nselect * from {{ ref('my_seed') }}\\n\", \"doc_blocks\": [], \"language\": \"sql\", \"refs\": [{\"name\": \"my_seed\", \"package\": null, \"version\": null}], \"sources\": [], \"metrics\": [], \"functions\": [], \"depends_on\": {\"macros\": [], \"nodes\": []}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"alias_types\": true, \"checksum\": null}}], \"analysis.test.disabled_al\": [{\"database\": \"dbt\", \"schema\": \"test17594237163467600387_test_previous_version_state\", \"name\": \"disabled_al\", \"resource_type\": \"analysis\", \"package_name\": \"test\", \"path\": \"analysis/disabled_al.sql\", \"original_file_path\": \"analyses/disabled_al.sql\", \"unique_id\": \"analysis.test.disabled_al\", \"fqn\": [\"test\", \"analysis\", \"disabled_al\"], \"alias\": \"disabled_al\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"32d36ad6cff0786eb562440ba60ef6c9b9a7f4c282dfb7a52eaf19d36370f0e1\"}, \"config\": {\"enabled\": false, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"view\", \"incremental_strategy\": null, \"batch_size\": null, \"lookback\": 1, \"begin\": null, \"persist_docs\": {}, \"post-hook\": [], \"pre-hook\": [], \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": null, \"on_schema_change\": \"ignore\", \"on_configuration_change\": \"apply\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"contract\": {\"enforced\": false, \"alias_types\": true}, \"event_time\": null, \"concurrent_batches\": null}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"unrendered_config\": {\"enabled\": false}, \"created_at\": 1759423716.143224, \"relation_name\": null, \"raw_code\": \"{{ config(enabled=False) }}\\nselect 9 as id\", \"doc_blocks\": [], \"language\": \"sql\", \"refs\": [], \"sources\": [], \"metrics\": [], \"functions\": [], \"depends_on\": {\"macros\": [], \"nodes\": []}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"alias_types\": true, \"checksum\": null}}], \"test.test.disabled_just_my\": [{\"database\": \"dbt\", \"schema\": \"test17594237163467600387_test_previous_version_state_dbt_test__audit\", \"name\": \"disabled_just_my\", \"resource_type\": \"test\", \"package_name\": \"test\", \"path\": \"disabled_just_my.sql\", \"original_file_path\": \"tests/disabled_just_my.sql\", \"unique_id\": \"test.test.disabled_just_my\", \"fqn\": [\"test\", \"disabled_just_my\"], \"alias\": \"disabled_just_my\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"4f2268fd89a3b4ef899264ada6d7aa33603671cbc5d5acead7dc2eadf1add985\"}, \"config\": {\"enabled\": false, \"alias\": null, \"schema\": \"dbt_test__audit\", \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"test\", \"severity\": \"ERROR\", \"store_failures\": null, \"store_failures_as\": null, \"where\": null, \"limit\": null, \"fail_calc\": \"count(*)\", \"warn_if\": \"!= 0\", \"error_if\": \"!= 0\"}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"unrendered_config\": {\"enabled\": false}, \"created_at\": 1759423716.270129, \"relation_name\": null, \"raw_code\": \"{{ config(enabled=False) }}\\n\\nselect * from {{ ref('my_model') }}\\nwhere false\", \"doc_blocks\": [], \"language\": \"sql\", \"refs\": [{\"name\": \"my_model\", \"package\": null, \"version\": null}], \"sources\": [], \"metrics\": [], \"functions\": [], \"depends_on\": {\"macros\": [], \"nodes\": []}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"alias_types\": true, \"checksum\": null}}], \"test.test.disabled_check_nothing_my_model_.f2c6a72d37\": [{\"database\": \"dbt\", \"schema\": \"test17594237163467600387_test_previous_version_state_dbt_test__audit\", \"name\": \"disabled_check_nothing_my_model_\", \"resource_type\": \"test\", \"package_name\": \"test\", \"path\": \"disabled_check_nothing_my_model_.sql\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"test.test.disabled_check_nothing_my_model_.f2c6a72d37\", \"fqn\": [\"test\", \"disabled_check_nothing_my_model_\"], \"alias\": \"disabled_check_nothing_my_model_\", \"checksum\": {\"name\": \"none\", \"checksum\": \"\"}, \"config\": {\"enabled\": false, \"alias\": null, \"schema\": \"dbt_test__audit\", \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"test\", \"severity\": \"ERROR\", \"store_failures\": null, \"store_failures_as\": null, \"where\": null, \"limit\": null, \"fail_calc\": \"count(*)\", \"warn_if\": \"!= 0\", \"error_if\": \"!= 0\"}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"unrendered_config\": {\"enabled\": false}, \"created_at\": 1759423716.4264681, \"relation_name\": null, \"raw_code\": \"{{ test_disabled_check_nothing(**_dbt_generic_test_kwargs) }}\", \"doc_blocks\": [], \"language\": \"sql\", \"refs\": [{\"name\": \"my_model\", \"package\": null, \"version\": null}], \"sources\": [], \"metrics\": [], \"functions\": [], \"depends_on\": {\"macros\": [\"macro.test.test_disabled_check_nothing\", \"macro.dbt.get_where_subquery\"], \"nodes\": []}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"alias_types\": true, \"checksum\": null}, \"column_name\": null, \"file_key_name\": \"models.my_model\", \"attached_node\": \"model.test.my_model\", \"test_metadata\": {\"name\": \"disabled_check_nothing\", \"kwargs\": {\"model\": \"{{ get_where_subquery(ref('my_model')) }}\"}, \"namespace\": null}}], \"exposure.test.disabled_exposure\": [{\"name\": \"disabled_exposure\", \"resource_type\": \"exposure\", \"package_name\": \"test\", \"path\": \"schema.yml\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"exposure.test.disabled_exposure\", \"fqn\": [\"test\", \"disabled_exposure\"], \"type\": \"dashboard\", \"owner\": {\"email\": \"something@example.com\", \"name\": null}, \"description\": \"\", \"label\": null, \"maturity\": null, \"meta\": {}, \"tags\": [], \"config\": {\"enabled\": false, \"tags\": [], \"meta\": {}}, \"unrendered_config\": {\"enabled\": false}, \"url\": null, \"depends_on\": {\"macros\": [], \"nodes\": []}, \"refs\": [{\"name\": \"my_model\", \"package\": null, \"version\": null}], \"sources\": [], \"metrics\": [], \"created_at\": 1759423716.459041}], \"metric.test.disabled_metric\": [{\"name\": \"disabled_metric\", \"resource_type\": \"metric\", \"package_name\": \"test\", \"path\": \"schema.yml\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"metric.test.disabled_metric\", \"fqn\": [\"test\", \"disabled_metric\"], \"description\": \"\", \"label\": \"Count records\", \"type\": \"simple\", \"type_params\": {\"measure\": {\"name\": \"customers\", \"filter\": null, \"alias\": null, \"join_to_timespine\": false, \"fill_nulls_with\": null}, \"input_measures\": [], \"numerator\": null, \"denominator\": null, \"expr\": null, \"window\": null, \"grain_to_date\": null, \"metrics\": [], \"conversion_type_params\": null, \"cumulative_type_params\": null, \"metric_aggregation_params\": null}, \"filter\": {\"where_filters\": [{\"where_sql_template\": \"{{ Dimension('id__favorite_color') }} = 'blue'\"}]}, \"metadata\": null, \"time_granularity\": null, \"meta\": {}, \"tags\": [], \"config\": {\"enabled\": false, \"group\": null, \"meta\": {}}, \"unrendered_config\": {\"enabled\": false}, \"sources\": [], \"depends_on\": {\"macros\": [], \"nodes\": []}, \"refs\": [], \"metrics\": [], \"created_at\": 1759423716.738817, \"group\": null}], \"seed.test.disabled_seed\": [{\"database\": \"dbt\", \"schema\": \"test17594237163467600387_test_previous_version_state\", \"name\": \"disabled_seed\", \"resource_type\": \"seed\", \"package_name\": \"test\", \"path\": \"disabled_seed.csv\", \"original_file_path\": \"seeds/disabled_seed.csv\", \"unique_id\": \"seed.test.disabled_seed\", \"fqn\": [\"test\", \"disabled_seed\"], \"alias\": \"disabled_seed\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"31fddd8ec40c6aba6a3a8e7d83fedea2fd0a56c47b64ea3df1847ec1b018e2d1\"}, \"config\": {\"enabled\": false, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"seed\", \"incremental_strategy\": null, \"batch_size\": null, \"lookback\": 1, \"begin\": null, \"persist_docs\": {}, \"post-hook\": [], \"pre-hook\": [], \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": null, \"on_schema_change\": \"ignore\", \"on_configuration_change\": \"apply\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"contract\": {\"enforced\": false, \"alias_types\": true}, \"event_time\": null, \"concurrent_batches\": null, \"delimiter\": \",\", \"quote_columns\": null}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": \"test://models/schema.yml\", \"build_path\": null, \"unrendered_config\": {\"enabled\": false}, \"created_at\": 1759423716.450551, \"relation_name\": \"\\\"dbt\\\".\\\"test17594237163467600387_test_previous_version_state\\\".\\\"disabled_seed\\\"\", \"raw_code\": \"\", \"doc_blocks\": [], \"root_path\": \"/private/var/folders/79/5290gpvn3lx5jdryk4844rm80000gn/T/pytest-of-quigleymalcolm/pytest-154/popen-gw6/project18\", \"depends_on\": {\"macros\": []}}], \"source.test.my_source.disabled_table\": [{\"database\": \"dbt\", \"schema\": \"my_source\", \"name\": \"disabled_table\", \"resource_type\": \"source\", \"package_name\": \"test\", \"path\": \"models/schema.yml\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"source.test.my_source.disabled_table\", \"fqn\": [\"test\", \"my_source\", \"disabled_table\"], \"source_name\": \"my_source\", \"source_description\": \"My source\", \"loader\": \"a_loader\", \"identifier\": \"disabled_table\", \"quoting\": {\"database\": null, \"schema\": null, \"identifier\": null, \"column\": null}, \"loaded_at_field\": null, \"loaded_at_query\": null, \"freshness\": {\"warn_after\": {\"count\": null, \"period\": null}, \"error_after\": {\"count\": null, \"period\": null}, \"filter\": null}, \"external\": null, \"description\": \"Disabled table\", \"columns\": {}, \"meta\": {}, \"source_meta\": {}, \"tags\": [], \"config\": {\"enabled\": false, \"event_time\": null, \"freshness\": {\"warn_after\": {\"count\": null, \"period\": null}, \"error_after\": {\"count\": null, \"period\": null}, \"filter\": null}, \"loaded_at_field\": null, \"loaded_at_query\": null, \"meta\": {}, \"tags\": []}, \"patch_path\": null, \"unrendered_config\": {\"enabled\": false, \"loaded_at_field\": null, \"loaded_at_query\": null, \"meta\": {}, \"tags\": []}, \"relation_name\": \"\\\"dbt\\\".\\\"my_source\\\".\\\"disabled_table\\\"\", \"created_at\": 1759423716.977084, \"unrendered_database\": null, \"unrendered_schema\": null, \"doc_blocks\": []}]}, \"parent_map\": {\"model.test.my_model\": [], \"model.test.metricflow_time_spine\": [], \"snapshot.test.snapshot_seed\": [\"seed.test.my_seed\"], \"analysis.test.a\": [], \"test.test.just_my\": [\"model.test.my_model\"], \"seed.test.my_seed\": [], \"test.test.not_null_my_model_id.43e0e9183a\": [\"model.test.my_model\"], \"test.test.check_nothing_my_model_.d5a5e66110\": [\"model.test.my_model\"], \"source.test.my_source.my_table\": [], \"exposure.test.simple_exposure\": [\"model.test.my_model\", \"source.test.my_source.my_table\"], \"metric.test.blue_customers_post_2010\": [\"semantic_model.test.semantic_people\"], \"metric.test.customers\": [\"semantic_model.test.semantic_people\"], \"metric.test.ratio_of_blue_customers_to_red_customers\": [\"metric.test.customers\"], \"metric.test.doubled_blue_customers\": [\"metric.test.customers\"], \"semantic_model.test.semantic_people\": [\"model.test.my_model\"]}, \"child_map\": {\"model.test.my_model\": [\"exposure.test.simple_exposure\", \"semantic_model.test.semantic_people\", \"test.test.check_nothing_my_model_.d5a5e66110\", \"test.test.just_my\", \"test.test.not_null_my_model_id.43e0e9183a\"], \"model.test.metricflow_time_spine\": [], \"snapshot.test.snapshot_seed\": [], \"analysis.test.a\": [], \"test.test.just_my\": [], \"seed.test.my_seed\": [\"snapshot.test.snapshot_seed\"], \"test.test.not_null_my_model_id.43e0e9183a\": [], \"test.test.check_nothing_my_model_.d5a5e66110\": [], \"source.test.my_source.my_table\": [\"exposure.test.simple_exposure\"], \"exposure.test.simple_exposure\": [], \"metric.test.blue_customers_post_2010\": [], \"metric.test.customers\": [\"metric.test.doubled_blue_customers\", \"metric.test.ratio_of_blue_customers_to_red_customers\"], \"metric.test.ratio_of_blue_customers_to_red_customers\": [], \"metric.test.doubled_blue_customers\": [], \"semantic_model.test.semantic_people\": [\"metric.test.blue_customers_post_2010\", \"metric.test.customers\"]}, \"group_map\": {}, \"saved_queries\": {}, \"semantic_models\": {\"semantic_model.test.semantic_people\": {\"name\": \"semantic_people\", \"resource_type\": \"semantic_model\", \"package_name\": \"test\", \"path\": \"schema.yml\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"semantic_model.test.semantic_people\", \"fqn\": [\"test\", \"semantic_people\"], \"model\": \"ref('my_model')\", \"node_relation\": {\"alias\": \"my_model\", \"schema_name\": \"test17594237163467600387_test_previous_version_state\", \"database\": \"dbt\", \"relation_name\": \"\\\"dbt\\\".\\\"test17594237163467600387_test_previous_version_state\\\".\\\"my_model\\\"\"}, \"description\": null, \"label\": null, \"defaults\": {\"agg_time_dimension\": \"created_at\"}, \"entities\": [{\"name\": \"id\", \"type\": \"primary\", \"description\": null, \"label\": null, \"role\": null, \"expr\": null, \"config\": {\"meta\": {}}}], \"measures\": [{\"name\": \"years_tenure\", \"agg\": \"sum\", \"description\": null, \"label\": null, \"create_metric\": false, \"expr\": \"tenure\", \"agg_params\": null, \"non_additive_dimension\": null, \"agg_time_dimension\": null, \"config\": {\"meta\": {}}}, {\"name\": \"people\", \"agg\": \"count\", \"description\": null, \"label\": null, \"create_metric\": false, \"expr\": \"id\", \"agg_params\": null, \"non_additive_dimension\": null, \"agg_time_dimension\": null, \"config\": {\"meta\": {}}}, {\"name\": \"customers\", \"agg\": \"count\", \"description\": null, \"label\": null, \"create_metric\": false, \"expr\": \"id\", \"agg_params\": null, \"non_additive_dimension\": null, \"agg_time_dimension\": null, \"config\": {\"meta\": {}}}], \"dimensions\": [{\"name\": \"favorite_color\", \"type\": \"categorical\", \"description\": null, \"label\": null, \"is_partition\": false, \"type_params\": null, \"expr\": null, \"metadata\": null, \"config\": {\"meta\": {}}}, {\"name\": \"created_at\", \"type\": \"time\", \"description\": null, \"label\": null, \"is_partition\": false, \"type_params\": {\"time_granularity\": \"day\", \"validity_params\": null}, \"expr\": null, \"metadata\": null, \"config\": {\"meta\": {}}}], \"metadata\": null, \"depends_on\": {\"macros\": [], \"nodes\": [\"model.test.my_model\"]}, \"refs\": [{\"name\": \"my_model\", \"package\": null, \"version\": null}], \"created_at\": 1759423716.958543, \"config\": {\"enabled\": true, \"group\": null, \"meta\": {}}, \"unrendered_config\": {}, \"primary_entity\": null, \"group\": null}}, \"unit_tests\": {}, \"functions\": {}}\n"
  },
  {
    "path": "tests/functional/artifacts/data/state/v2/manifest.json",
    "content": "{\"metadata\": {\"dbt_schema_version\": \"https://schemas.getdbt.com/dbt/manifest/v2.json\", \"dbt_version\": \"0.20.2\", \"generated_at\": \"2022-06-08T05:12:43.870174Z\", \"invocation_id\": \"b9b21a26-1804-47f9-866b-620501fe5540\", \"env\": {}, \"project_id\": \"098f6bcd4621d373cade4e832627b4f6\", \"user_id\": null, \"send_anonymous_usage_stats\": false, \"adapter_type\": \"postgres\"}, \"nodes\": {\"model.test.my_model\": {\"raw_sql\": \"select 1 as id\", \"resource_type\": \"model\", \"depends_on\": {\"macros\": [], \"nodes\": []}, \"config\": {\"enabled\": true, \"materialized\": \"view\", \"persist_docs\": {}, \"vars\": {}, \"quoting\": {}, \"column_types\": {}, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"full_refresh\": null, \"post-hook\": [], \"pre-hook\": []}, \"database\": \"jerco\", \"schema\": \"dbt_jcohen\", \"fqn\": [\"test\", \"my_model\"], \"unique_id\": \"model.test.my_model\", \"package_name\": \"test\", \"root_path\": \"/Users/jerco/dev/scratch/testy\", \"path\": \"my_model.sql\", \"original_file_path\": \"models/my_model.sql\", \"name\": \"my_model\", \"alias\": \"my_model\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"479636cb85ce8d3b0f8db5ff13cf338b61254ad98d905630eac61f963e719e9d\"}, \"tags\": [], \"refs\": [], \"sources\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"compiled_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {}, \"created_at\": 1654665164}}, \"sources\": {}, \"macros\": {\"macro.test.drop_relation\": {\"unique_id\": \"macro.test.drop_relation\", \"package_name\": \"test\", \"root_path\": \"/Users/jerco/dev/scratch/testy\", \"path\": \"macros/whatever.sql\", \"original_file_path\": \"macros/whatever.sql\", \"name\": \"drop_relation\", \"macro_sql\": \"{% macro drop_relation(relation) -%}\\n  {{ return(dbt_labs_materialized_views.drop_relation(relation)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.test.drop_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.test.postgres__list_relations_without_caching\": {\"unique_id\": \"macro.test.postgres__list_relations_without_caching\", \"package_name\": \"test\", \"root_path\": \"/Users/jerco/dev/scratch/testy\", \"path\": \"macros/whatever.sql\", \"original_file_path\": \"macros/whatever.sql\", \"name\": \"postgres__list_relations_without_caching\", \"macro_sql\": \"{% macro postgres__list_relations_without_caching(schema_relation) %}\\n  {{ return(dbt_labs_materialized_views.postgres__list_relations_without_caching(schema_relation)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.test.postgres__list_relations_without_caching\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.test.postgres_get_relations\": {\"unique_id\": \"macro.test.postgres_get_relations\", \"package_name\": \"test\", \"root_path\": \"/Users/jerco/dev/scratch/testy\", \"path\": \"macros/whatever.sql\", \"original_file_path\": \"macros/whatever.sql\", \"name\": \"postgres_get_relations\", \"macro_sql\": \"{% macro postgres_get_relations() %}\\n  {{ return(dbt_labs_materialized_views.postgres_get_relations()) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.test.postgres_get_relations\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.test.redshift__list_relations_without_caching\": {\"unique_id\": \"macro.test.redshift__list_relations_without_caching\", \"package_name\": \"test\", \"root_path\": \"/Users/jerco/dev/scratch/testy\", \"path\": \"macros/whatever.sql\", \"original_file_path\": \"macros/whatever.sql\", \"name\": \"redshift__list_relations_without_caching\", \"macro_sql\": \"{% macro redshift__list_relations_without_caching(schema_relation) %}\\n  {{ return(dbt_labs_materialized_views.redshift__list_relations_without_caching(schema_relation)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.test.redshift__list_relations_without_caching\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.test.load_relation\": {\"unique_id\": \"macro.test.load_relation\", \"package_name\": \"test\", \"root_path\": \"/Users/jerco/dev/scratch/testy\", \"path\": \"macros/whatever.sql\", \"original_file_path\": \"macros/whatever.sql\", \"name\": \"load_relation\", \"macro_sql\": \"{% macro load_relation(relation) %}\\n  {{ return(dbt_labs_materialized_views.redshift_load_relation_or_mv(relation)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt_postgres.postgres__get_catalog\": {\"unique_id\": \"macro.dbt_postgres.postgres__get_catalog\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/catalog.sql\", \"original_file_path\": \"macros/catalog.sql\", \"name\": \"postgres__get_catalog\", \"macro_sql\": \"{% macro postgres__get_catalog(information_schema, schemas) -%}\\n\\n  {%- call statement('catalog', fetch_result=True) -%}\\n    {#\\n      If the user has multiple databases set and the first one is wrong, this will fail.\\n      But we won't fail in the case where there are multiple quoting-difference-only dbs, which is better.\\n    #}\\n    {% set database = information_schema.database %}\\n    {{ adapter.verify_database(database) }}\\n\\n    select\\n        '{{ database }}' as table_database,\\n        sch.nspname as table_schema,\\n        tbl.relname as table_name,\\n        case tbl.relkind\\n            when 'v' then 'VIEW'\\n            else 'BASE TABLE'\\n        end as table_type,\\n        tbl_desc.description as table_comment,\\n        col.attname as column_name,\\n        col.attnum as column_index,\\n        pg_catalog.format_type(col.atttypid, col.atttypmod) as column_type,\\n        col_desc.description as column_comment,\\n        pg_get_userbyid(tbl.relowner) as table_owner\\n\\n    from pg_catalog.pg_namespace sch\\n    join pg_catalog.pg_class tbl on tbl.relnamespace = sch.oid\\n    join pg_catalog.pg_attribute col on col.attrelid = tbl.oid\\n    left outer join pg_catalog.pg_description tbl_desc on (tbl_desc.objoid = tbl.oid and tbl_desc.objsubid = 0)\\n    left outer join pg_catalog.pg_description col_desc on (col_desc.objoid = tbl.oid and col_desc.objsubid = col.attnum)\\n\\n    where (\\n        {%- for schema in schemas -%}\\n          upper(sch.nspname) = upper('{{ schema }}'){%- if not loop.last %} or {% endif -%}\\n        {%- endfor -%}\\n      )\\n      and not pg_is_other_temp_schema(sch.oid) -- not a temporary schema belonging to another session\\n      and tbl.relpersistence = 'p' -- [p]ermanent table. Other values are [u]nlogged table, [t]emporary table\\n      and tbl.relkind in ('r', 'v', 'f', 'p') -- o[r]dinary table, [v]iew, [f]oreign table, [p]artitioned table. Other values are [i]ndex, [S]equence, [c]omposite type, [t]OAST table, [m]aterialized view\\n      and col.attnum > 0 -- negative numbers are used for system columns such as oid\\n      and not col.attisdropped -- column as not been dropped\\n\\n    order by\\n        sch.nspname,\\n        tbl.relname,\\n        col.attnum\\n\\n  {%- endcall -%}\\n\\n  {{ return(load_result('catalog').table) }}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt_postgres.postgres_get_relations\": {\"unique_id\": \"macro.dbt_postgres.postgres_get_relations\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/relations.sql\", \"original_file_path\": \"macros/relations.sql\", \"name\": \"postgres_get_relations\", \"macro_sql\": \"{% macro postgres_get_relations () -%}\\n\\n  {#\\n      -- in pg_depend, objid is the dependent, refobjid is the referenced object\\n      --  > a pg_depend entry indicates that the referenced object cannot be\\n      --  > dropped without also dropping the dependent object.\\n  #}\\n\\n  {%- call statement('relations', fetch_result=True) -%}\\n    with relation as (\\n        select\\n            pg_rewrite.ev_class as class,\\n            pg_rewrite.oid as id\\n        from pg_rewrite\\n    ),\\n    class as (\\n        select\\n            oid as id,\\n            relname as name,\\n            relnamespace as schema,\\n            relkind as kind\\n        from pg_class\\n    ),\\n    dependency as (\\n        select\\n            pg_depend.objid as id,\\n            pg_depend.refobjid as ref\\n        from pg_depend\\n    ),\\n    schema as (\\n        select\\n            pg_namespace.oid as id,\\n            pg_namespace.nspname as name\\n        from pg_namespace\\n        where nspname != 'information_schema' and nspname not like 'pg\\\\_%'\\n    ),\\n    referenced as (\\n        select\\n            relation.id AS id,\\n            referenced_class.name ,\\n            referenced_class.schema ,\\n            referenced_class.kind\\n        from relation\\n        join class as referenced_class on relation.class=referenced_class.id\\n        where referenced_class.kind in ('r', 'v')\\n    ),\\n    relationships as (\\n        select\\n            referenced.name as referenced_name,\\n            referenced.schema as referenced_schema_id,\\n            dependent_class.name as dependent_name,\\n            dependent_class.schema as dependent_schema_id,\\n            referenced.kind as kind\\n        from referenced\\n        join dependency on referenced.id=dependency.id\\n        join class as dependent_class on dependency.ref=dependent_class.id\\n        where\\n            (referenced.name != dependent_class.name or\\n             referenced.schema != dependent_class.schema)\\n    )\\n\\n    select\\n        referenced_schema.name as referenced_schema,\\n        relationships.referenced_name as referenced_name,\\n        dependent_schema.name as dependent_schema,\\n        relationships.dependent_name as dependent_name\\n    from relationships\\n    join schema as dependent_schema on relationships.dependent_schema_id=dependent_schema.id\\n    join schema as referenced_schema on relationships.referenced_schema_id=referenced_schema.id\\n    group by referenced_schema, referenced_name, dependent_schema, dependent_name\\n    order by referenced_schema, referenced_name, dependent_schema, dependent_name;\\n\\n  {%- endcall -%}\\n\\n  {{ return(load_result('relations').table) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt_postgres.postgres__create_table_as\": {\"unique_id\": \"macro.dbt_postgres.postgres__create_table_as\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__create_table_as\", \"macro_sql\": \"{% macro postgres__create_table_as(temporary, relation, sql) -%}\\n  {%- set unlogged = config.get('unlogged', default=false) -%}\\n  {%- set sql_header = config.get('sql_header', none) -%}\\n\\n  {{ sql_header if sql_header is not none }}\\n\\n  create {% if temporary -%}\\n    temporary\\n  {%- elif unlogged -%}\\n    unlogged\\n  {%- endif %} table {{ relation }}\\n  as (\\n    {{ sql }}\\n  );\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt_postgres.postgres__get_create_index_sql\": {\"unique_id\": \"macro.dbt_postgres.postgres__get_create_index_sql\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__get_create_index_sql\", \"macro_sql\": \"{% macro postgres__get_create_index_sql(relation, index_dict) -%}\\n  {%- set index_config = adapter.parse_index(index_dict) -%}\\n  {%- set comma_separated_columns = \\\", \\\".join(index_config.columns) -%}\\n  {%- set index_name = index_config.render(relation) -%}\\n\\n  create {% if index_config.unique -%}\\n    unique\\n  {%- endif %} index if not exists\\n  \\\"{{ index_name }}\\\"\\n  on {{ relation }} {% if index_config.type -%}\\n    using {{ index_config.type }}\\n  {%- endif %}\\n  ({{ comma_separated_columns }});\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt_postgres.postgres__create_schema\": {\"unique_id\": \"macro.dbt_postgres.postgres__create_schema\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__create_schema\", \"macro_sql\": \"{% macro postgres__create_schema(relation) -%}\\n  {% if relation.database -%}\\n    {{ adapter.verify_database(relation.database) }}\\n  {%- endif -%}\\n  {%- call statement('create_schema') -%}\\n    create schema if not exists {{ relation.without_identifier().include(database=False) }}\\n  {%- endcall -%}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt_postgres.postgres__drop_schema\": {\"unique_id\": \"macro.dbt_postgres.postgres__drop_schema\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__drop_schema\", \"macro_sql\": \"{% macro postgres__drop_schema(relation) -%}\\n  {% if relation.database -%}\\n    {{ adapter.verify_database(relation.database) }}\\n  {%- endif -%}\\n  {%- call statement('drop_schema') -%}\\n    drop schema if exists {{ relation.without_identifier().include(database=False) }} cascade\\n  {%- endcall -%}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt_postgres.postgres__get_columns_in_relation\": {\"unique_id\": \"macro.dbt_postgres.postgres__get_columns_in_relation\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__get_columns_in_relation\", \"macro_sql\": \"{% macro postgres__get_columns_in_relation(relation) -%}\\n  {% call statement('get_columns_in_relation', fetch_result=True) %}\\n      select\\n          column_name,\\n          data_type,\\n          character_maximum_length,\\n          numeric_precision,\\n          numeric_scale\\n\\n      from {{ relation.information_schema('columns') }}\\n      where table_name = '{{ relation.identifier }}'\\n        {% if relation.schema %}\\n        and table_schema = '{{ relation.schema }}'\\n        {% endif %}\\n      order by ordinal_position\\n\\n  {% endcall %}\\n  {% set table = load_result('get_columns_in_relation').table %}\\n  {{ return(sql_convert_columns_in_relation(table)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\", \"macro.dbt.sql_convert_columns_in_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt_postgres.postgres__list_relations_without_caching\": {\"unique_id\": \"macro.dbt_postgres.postgres__list_relations_without_caching\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__list_relations_without_caching\", \"macro_sql\": \"{% macro postgres__list_relations_without_caching(schema_relation) %}\\n  {% call statement('list_relations_without_caching', fetch_result=True) -%}\\n    select\\n      '{{ schema_relation.database }}' as database,\\n      tablename as name,\\n      schemaname as schema,\\n      'table' as type\\n    from pg_tables\\n    where schemaname ilike '{{ schema_relation.schema }}'\\n    union all\\n    select\\n      '{{ schema_relation.database }}' as database,\\n      viewname as name,\\n      schemaname as schema,\\n      'view' as type\\n    from pg_views\\n    where schemaname ilike '{{ schema_relation.schema }}'\\n  {% endcall %}\\n  {{ return(load_result('list_relations_without_caching').table) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt_postgres.postgres__information_schema_name\": {\"unique_id\": \"macro.dbt_postgres.postgres__information_schema_name\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__information_schema_name\", \"macro_sql\": \"{% macro postgres__information_schema_name(database) -%}\\n  {% if database_name -%}\\n    {{ adapter.verify_database(database_name) }}\\n  {%- endif -%}\\n  information_schema\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt_postgres.postgres__list_schemas\": {\"unique_id\": \"macro.dbt_postgres.postgres__list_schemas\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__list_schemas\", \"macro_sql\": \"{% macro postgres__list_schemas(database) %}\\n  {% if database -%}\\n    {{ adapter.verify_database(database) }}\\n  {%- endif -%}\\n  {% call statement('list_schemas', fetch_result=True, auto_begin=False) %}\\n    select distinct nspname from pg_namespace\\n  {% endcall %}\\n  {{ return(load_result('list_schemas').table) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt_postgres.postgres__check_schema_exists\": {\"unique_id\": \"macro.dbt_postgres.postgres__check_schema_exists\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__check_schema_exists\", \"macro_sql\": \"{% macro postgres__check_schema_exists(information_schema, schema) -%}\\n  {% if information_schema.database -%}\\n    {{ adapter.verify_database(information_schema.database) }}\\n  {%- endif -%}\\n  {% call statement('check_schema_exists', fetch_result=True, auto_begin=False) %}\\n    select count(*) from pg_namespace where nspname = '{{ schema }}'\\n  {% endcall %}\\n  {{ return(load_result('check_schema_exists').table) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt_postgres.postgres__current_timestamp\": {\"unique_id\": \"macro.dbt_postgres.postgres__current_timestamp\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__current_timestamp\", \"macro_sql\": \"{% macro postgres__current_timestamp() -%}\\n  now()\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt_postgres.postgres__snapshot_string_as_time\": {\"unique_id\": \"macro.dbt_postgres.postgres__snapshot_string_as_time\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__snapshot_string_as_time\", \"macro_sql\": \"{% macro postgres__snapshot_string_as_time(timestamp) -%}\\n    {%- set result = \\\"'\\\" ~ timestamp ~ \\\"'::timestamp without time zone\\\" -%}\\n    {{ return(result) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt_postgres.postgres__snapshot_get_time\": {\"unique_id\": \"macro.dbt_postgres.postgres__snapshot_get_time\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__snapshot_get_time\", \"macro_sql\": \"{% macro postgres__snapshot_get_time() -%}\\n  {{ current_timestamp() }}::timestamp without time zone\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt_postgres.postgres__make_temp_relation\": {\"unique_id\": \"macro.dbt_postgres.postgres__make_temp_relation\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__make_temp_relation\", \"macro_sql\": \"{% macro postgres__make_temp_relation(base_relation, suffix) %}\\n    {% set dt = modules.datetime.datetime.now() %}\\n    {% set dtstring = dt.strftime(\\\"%H%M%S%f\\\") %}\\n    {% set suffix_length = suffix|length + dtstring|length %}\\n    {% set relation_max_name_length = 63 %}\\n    {% if suffix_length > relation_max_name_length %}\\n        {% do exceptions.raise_compiler_error('Temp relation suffix is too long (' ~ suffix|length ~ ' characters). Maximum length is ' ~ (relation_max_name_length - dtstring|length) ~ ' characters.') %}\\n    {% endif %}\\n    {% set tmp_identifier = base_relation.identifier[:relation_max_name_length - suffix_length] ~ suffix ~ dtstring %}\\n    {% do return(base_relation.incorporate(\\n                                  path={\\n                                    \\\"identifier\\\": tmp_identifier,\\n                                    \\\"schema\\\": none,\\n                                    \\\"database\\\": none\\n                                  })) -%}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt_postgres.postgres_escape_comment\": {\"unique_id\": \"macro.dbt_postgres.postgres_escape_comment\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres_escape_comment\", \"macro_sql\": \"{% macro postgres_escape_comment(comment) -%}\\n  {% if comment is not string %}\\n    {% do exceptions.raise_compiler_error('cannot escape a non-string: ' ~ comment) %}\\n  {% endif %}\\n  {%- set magic = '$dbt_comment_literal_block$' -%}\\n  {%- if magic in comment -%}\\n    {%- do exceptions.raise_compiler_error('The string ' ~ magic ~ ' is not allowed in comments.') -%}\\n  {%- endif -%}\\n  {{ magic }}{{ comment }}{{ magic }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt_postgres.postgres__alter_relation_comment\": {\"unique_id\": \"macro.dbt_postgres.postgres__alter_relation_comment\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__alter_relation_comment\", \"macro_sql\": \"{% macro postgres__alter_relation_comment(relation, comment) %}\\n  {% set escaped_comment = postgres_escape_comment(comment) %}\\n  comment on {{ relation.type }} {{ relation }} is {{ escaped_comment }};\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres_escape_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt_postgres.postgres__alter_column_comment\": {\"unique_id\": \"macro.dbt_postgres.postgres__alter_column_comment\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__alter_column_comment\", \"macro_sql\": \"{% macro postgres__alter_column_comment(relation, column_dict) %}\\n  {% for column_name in column_dict %}\\n    {% set comment = column_dict[column_name]['description'] %}\\n    {% set escaped_comment = postgres_escape_comment(comment) %}\\n    comment on column {{ relation }}.{{ adapter.quote(column_name) if column_dict[column_name]['quote'] else column_name }} is {{ escaped_comment }};\\n  {% endfor %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres_escape_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt_postgres.postgres__snapshot_merge_sql\": {\"unique_id\": \"macro.dbt_postgres.postgres__snapshot_merge_sql\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/materializations/snapshot_merge.sql\", \"original_file_path\": \"macros/materializations/snapshot_merge.sql\", \"name\": \"postgres__snapshot_merge_sql\", \"macro_sql\": \"{% macro postgres__snapshot_merge_sql(target, source, insert_cols) -%}\\n    {%- set insert_cols_csv = insert_cols | join(', ') -%}\\n\\n    update {{ target }}\\n    set dbt_valid_to = DBT_INTERNAL_SOURCE.dbt_valid_to\\n    from {{ source }} as DBT_INTERNAL_SOURCE\\n    where DBT_INTERNAL_SOURCE.dbt_scd_id::text = {{ target }}.dbt_scd_id::text\\n      and DBT_INTERNAL_SOURCE.dbt_change_type::text in ('update'::text, 'delete'::text)\\n      and {{ target }}.dbt_valid_to is null;\\n\\n    insert into {{ target }} ({{ insert_cols_csv }})\\n    select {% for column in insert_cols -%}\\n        DBT_INTERNAL_SOURCE.{{ column }} {%- if not loop.last %}, {%- endif %}\\n    {%- endfor %}\\n    from {{ source }} as DBT_INTERNAL_SOURCE\\n    where DBT_INTERNAL_SOURCE.dbt_change_type::text = 'insert'::text;\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.statement\": {\"unique_id\": \"macro.dbt.statement\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/core.sql\", \"original_file_path\": \"macros/core.sql\", \"name\": \"statement\", \"macro_sql\": \"{% macro statement(name=None, fetch_result=False, auto_begin=True) -%}\\n  {%- if execute: -%}\\n    {%- set sql = caller() -%}\\n\\n    {%- if name == 'main' -%}\\n      {{ log('Writing runtime SQL for node \\\"{}\\\"'.format(model['unique_id'])) }}\\n      {{ write(sql) }}\\n    {%- endif -%}\\n\\n    {%- set res, table = adapter.execute(sql, auto_begin=auto_begin, fetch=fetch_result) -%}\\n    {%- if name is not none -%}\\n      {{ store_result(name, response=res, agate_table=table) }}\\n    {%- endif -%}\\n\\n  {%- endif -%}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.noop_statement\": {\"unique_id\": \"macro.dbt.noop_statement\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/core.sql\", \"original_file_path\": \"macros/core.sql\", \"name\": \"noop_statement\", \"macro_sql\": \"{% macro noop_statement(name=None, message=None, code=None, rows_affected=None, res=None) -%}\\n  {%- set sql = caller() -%}\\n\\n  {%- if name == 'main' -%}\\n    {{ log('Writing runtime SQL for node \\\"{}\\\"'.format(model['unique_id'])) }}\\n    {{ write(sql) }}\\n  {%- endif -%}\\n\\n  {%- if name is not none -%}\\n    {{ store_raw_result(name, message=message, code=code, rows_affected=rows_affected, agate_table=res) }}\\n  {%- endif -%}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.get_test_sql\": {\"unique_id\": \"macro.dbt.get_test_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/test.sql\", \"original_file_path\": \"macros/materializations/test.sql\", \"name\": \"get_test_sql\", \"macro_sql\": \"{% macro get_test_sql(main_sql, fail_calc, warn_if, error_if, limit) -%}\\n  {{ adapter.dispatch('get_test_sql')(main_sql, fail_calc, warn_if, error_if, limit) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_test_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.default__get_test_sql\": {\"unique_id\": \"macro.dbt.default__get_test_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/test.sql\", \"original_file_path\": \"macros/materializations/test.sql\", \"name\": \"default__get_test_sql\", \"macro_sql\": \"{% macro default__get_test_sql(main_sql, fail_calc, warn_if, error_if, limit) -%}\\n    select\\n      {{ fail_calc }} as failures,\\n      {{ fail_calc }} {{ warn_if }} as should_warn,\\n      {{ fail_calc }} {{ error_if }} as should_error\\n    from (\\n      {{ main_sql }}\\n      {{ \\\"limit \\\" ~ limit if limit != none }}\\n    ) dbt_internal_test\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.materialization_test_default\": {\"unique_id\": \"macro.dbt.materialization_test_default\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/test.sql\", \"original_file_path\": \"macros/materializations/test.sql\", \"name\": \"materialization_test_default\", \"macro_sql\": \"\\n\\n{%- materialization test, default -%}\\n\\n  {% set relations = [] %}\\n\\n  {% if should_store_failures() %}\\n\\n    {% set identifier = model['alias'] %}\\n    {% set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) %}\\n    {% set target_relation = api.Relation.create(\\n        identifier=identifier, schema=schema, database=database, type='table') -%} %}\\n    \\n    {% if old_relation %}\\n        {% do adapter.drop_relation(old_relation) %}\\n    {% endif %}\\n    \\n    {% call statement(auto_begin=True) %}\\n        {{ create_table_as(False, target_relation, sql) }}\\n    {% endcall %}\\n    \\n    {% do relations.append(target_relation) %}\\n  \\n    {% set main_sql %}\\n        select *\\n        from {{ target_relation }}\\n    {% endset %}\\n    \\n    {{ adapter.commit() }}\\n  \\n  {% else %}\\n\\n      {% set main_sql = sql %}\\n  \\n  {% endif %}\\n\\n  {% set limit = config.get('limit') %}\\n  {% set fail_calc = config.get('fail_calc') %}\\n  {% set warn_if = config.get('warn_if') %}\\n  {% set error_if = config.get('error_if') %}\\n\\n  {% call statement('main', fetch_result=True) -%}\\n\\n    {{ get_test_sql(main_sql, fail_calc, warn_if, error_if, limit)}}\\n\\n  {%- endcall %}\\n  \\n  {{ return({'relations': relations}) }}\\n\\n{%- endmaterialization -%}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.should_store_failures\", \"macro.dbt.statement\", \"macro.dbt.create_table_as\", \"macro.dbt.get_test_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.run_hooks\": {\"unique_id\": \"macro.dbt.run_hooks\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/helpers.sql\", \"original_file_path\": \"macros/materializations/helpers.sql\", \"name\": \"run_hooks\", \"macro_sql\": \"{% macro run_hooks(hooks, inside_transaction=True) %}\\n  {% for hook in hooks | selectattr('transaction', 'equalto', inside_transaction)  %}\\n    {% if not inside_transaction and loop.first %}\\n      {% call statement(auto_begin=inside_transaction) %}\\n        commit;\\n      {% endcall %}\\n    {% endif %}\\n    {% set rendered = render(hook.get('sql')) | trim %}\\n    {% if (rendered | length) > 0 %}\\n      {% call statement(auto_begin=inside_transaction) %}\\n        {{ rendered }}\\n      {% endcall %}\\n    {% endif %}\\n  {% endfor %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.column_list\": {\"unique_id\": \"macro.dbt.column_list\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/helpers.sql\", \"original_file_path\": \"macros/materializations/helpers.sql\", \"name\": \"column_list\", \"macro_sql\": \"{% macro column_list(columns) %}\\n  {%- for col in columns %}\\n    {{ col.name }} {% if not loop.last %},{% endif %}\\n  {% endfor -%}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.column_list_for_create_table\": {\"unique_id\": \"macro.dbt.column_list_for_create_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/helpers.sql\", \"original_file_path\": \"macros/materializations/helpers.sql\", \"name\": \"column_list_for_create_table\", \"macro_sql\": \"{% macro column_list_for_create_table(columns) %}\\n  {%- for col in columns %}\\n    {{ col.name }} {{ col.data_type }} {%- if not loop.last %},{% endif %}\\n  {% endfor -%}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.make_hook_config\": {\"unique_id\": \"macro.dbt.make_hook_config\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/helpers.sql\", \"original_file_path\": \"macros/materializations/helpers.sql\", \"name\": \"make_hook_config\", \"macro_sql\": \"{% macro make_hook_config(sql, inside_transaction) %}\\n    {{ tojson({\\\"sql\\\": sql, \\\"transaction\\\": inside_transaction}) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.before_begin\": {\"unique_id\": \"macro.dbt.before_begin\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/helpers.sql\", \"original_file_path\": \"macros/materializations/helpers.sql\", \"name\": \"before_begin\", \"macro_sql\": \"{% macro before_begin(sql) %}\\n    {{ make_hook_config(sql, inside_transaction=False) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.make_hook_config\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.in_transaction\": {\"unique_id\": \"macro.dbt.in_transaction\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/helpers.sql\", \"original_file_path\": \"macros/materializations/helpers.sql\", \"name\": \"in_transaction\", \"macro_sql\": \"{% macro in_transaction(sql) %}\\n    {{ make_hook_config(sql, inside_transaction=True) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.make_hook_config\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.after_commit\": {\"unique_id\": \"macro.dbt.after_commit\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/helpers.sql\", \"original_file_path\": \"macros/materializations/helpers.sql\", \"name\": \"after_commit\", \"macro_sql\": \"{% macro after_commit(sql) %}\\n    {{ make_hook_config(sql, inside_transaction=False) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.make_hook_config\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.drop_relation_if_exists\": {\"unique_id\": \"macro.dbt.drop_relation_if_exists\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/helpers.sql\", \"original_file_path\": \"macros/materializations/helpers.sql\", \"name\": \"drop_relation_if_exists\", \"macro_sql\": \"{% macro drop_relation_if_exists(relation) %}\\n  {% if relation is not none %}\\n    {{ adapter.drop_relation(relation) }}\\n  {% endif %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.load_relation\": {\"unique_id\": \"macro.dbt.load_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/helpers.sql\", \"original_file_path\": \"macros/materializations/helpers.sql\", \"name\": \"load_relation\", \"macro_sql\": \"{% macro load_relation(relation) %}\\n  {% do return(adapter.get_relation(\\n    database=relation.database,\\n    schema=relation.schema,\\n    identifier=relation.identifier\\n  )) -%}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.should_full_refresh\": {\"unique_id\": \"macro.dbt.should_full_refresh\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/helpers.sql\", \"original_file_path\": \"macros/materializations/helpers.sql\", \"name\": \"should_full_refresh\", \"macro_sql\": \"{% macro should_full_refresh() %}\\n  {% set config_full_refresh = config.get('full_refresh') %}\\n  {% if config_full_refresh is none %}\\n    {% set config_full_refresh = flags.FULL_REFRESH %}\\n  {% endif %}\\n  {% do return(config_full_refresh) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.should_store_failures\": {\"unique_id\": \"macro.dbt.should_store_failures\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/helpers.sql\", \"original_file_path\": \"macros/materializations/helpers.sql\", \"name\": \"should_store_failures\", \"macro_sql\": \"{% macro should_store_failures() %}\\n  {% set config_store_failures = config.get('store_failures') %}\\n  {% if config_store_failures is none %}\\n    {% set config_store_failures = flags.STORE_FAILURES %}\\n  {% endif %}\\n  {% do return(config_store_failures) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.snapshot_merge_sql\": {\"unique_id\": \"macro.dbt.snapshot_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshot/snapshot_merge.sql\", \"original_file_path\": \"macros/materializations/snapshot/snapshot_merge.sql\", \"name\": \"snapshot_merge_sql\", \"macro_sql\": \"{% macro snapshot_merge_sql(target, source, insert_cols) -%}\\n  {{ adapter.dispatch('snapshot_merge_sql')(target, source, insert_cols) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__snapshot_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.default__snapshot_merge_sql\": {\"unique_id\": \"macro.dbt.default__snapshot_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshot/snapshot_merge.sql\", \"original_file_path\": \"macros/materializations/snapshot/snapshot_merge.sql\", \"name\": \"default__snapshot_merge_sql\", \"macro_sql\": \"{% macro default__snapshot_merge_sql(target, source, insert_cols) -%}\\n    {%- set insert_cols_csv = insert_cols | join(', ') -%}\\n\\n    merge into {{ target }} as DBT_INTERNAL_DEST\\n    using {{ source }} as DBT_INTERNAL_SOURCE\\n    on DBT_INTERNAL_SOURCE.dbt_scd_id = DBT_INTERNAL_DEST.dbt_scd_id\\n\\n    when matched\\n     and DBT_INTERNAL_DEST.dbt_valid_to is null\\n     and DBT_INTERNAL_SOURCE.dbt_change_type in ('update', 'delete')\\n        then update\\n        set dbt_valid_to = DBT_INTERNAL_SOURCE.dbt_valid_to\\n\\n    when not matched\\n     and DBT_INTERNAL_SOURCE.dbt_change_type = 'insert'\\n        then insert ({{ insert_cols_csv }})\\n        values ({{ insert_cols_csv }})\\n    ;\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.strategy_dispatch\": {\"unique_id\": \"macro.dbt.strategy_dispatch\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshot/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshot/strategies.sql\", \"name\": \"strategy_dispatch\", \"macro_sql\": \"{% macro strategy_dispatch(name) -%}\\n{% set original_name = name %}\\n  {% if '.' in name %}\\n    {% set package_name, name = name.split(\\\".\\\", 1) %}\\n  {% else %}\\n    {% set package_name = none %}\\n  {% endif %}\\n\\n  {% if package_name is none %}\\n    {% set package_context = context %}\\n  {% elif package_name in context %}\\n    {% set package_context = context[package_name] %}\\n  {% else %}\\n    {% set error_msg %}\\n        Could not find package '{{package_name}}', called with '{{original_name}}'\\n    {% endset %}\\n    {{ exceptions.raise_compiler_error(error_msg | trim) }}\\n  {% endif %}\\n\\n  {%- set search_name = 'snapshot_' ~ name ~ '_strategy' -%}\\n\\n  {% if search_name not in package_context %}\\n    {% set error_msg %}\\n        The specified strategy macro '{{name}}' was not found in package '{{ package_name }}'\\n    {% endset %}\\n    {{ exceptions.raise_compiler_error(error_msg | trim) }}\\n  {% endif %}\\n  {{ return(package_context[search_name]) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.snapshot_hash_arguments\": {\"unique_id\": \"macro.dbt.snapshot_hash_arguments\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshot/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshot/strategies.sql\", \"name\": \"snapshot_hash_arguments\", \"macro_sql\": \"{% macro snapshot_hash_arguments(args) -%}\\n  {{ adapter.dispatch('snapshot_hash_arguments')(args) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__snapshot_hash_arguments\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.default__snapshot_hash_arguments\": {\"unique_id\": \"macro.dbt.default__snapshot_hash_arguments\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshot/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshot/strategies.sql\", \"name\": \"default__snapshot_hash_arguments\", \"macro_sql\": \"{% macro default__snapshot_hash_arguments(args) -%}\\n    md5({%- for arg in args -%}\\n        coalesce(cast({{ arg }} as varchar ), '')\\n        {% if not loop.last %} || '|' || {% endif %}\\n    {%- endfor -%})\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.snapshot_get_time\": {\"unique_id\": \"macro.dbt.snapshot_get_time\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshot/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshot/strategies.sql\", \"name\": \"snapshot_get_time\", \"macro_sql\": \"{% macro snapshot_get_time() -%}\\n  {{ adapter.dispatch('snapshot_get_time')() }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__snapshot_get_time\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.default__snapshot_get_time\": {\"unique_id\": \"macro.dbt.default__snapshot_get_time\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshot/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshot/strategies.sql\", \"name\": \"default__snapshot_get_time\", \"macro_sql\": \"{% macro default__snapshot_get_time() -%}\\n  {{ current_timestamp() }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.snapshot_timestamp_strategy\": {\"unique_id\": \"macro.dbt.snapshot_timestamp_strategy\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshot/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshot/strategies.sql\", \"name\": \"snapshot_timestamp_strategy\", \"macro_sql\": \"{% macro snapshot_timestamp_strategy(node, snapshotted_rel, current_rel, config, target_exists) %}\\n    {% set primary_key = config['unique_key'] %}\\n    {% set updated_at = config['updated_at'] %}\\n    {% set invalidate_hard_deletes = config.get('invalidate_hard_deletes', false) %}\\n\\n    {#/*\\n        The snapshot relation might not have an {{ updated_at }} value if the\\n        snapshot strategy is changed from `check` to `timestamp`. We\\n        should use a dbt-created column for the comparison in the snapshot\\n        table instead of assuming that the user-supplied {{ updated_at }}\\n        will be present in the historical data.\\n\\n        See https://github.com/fishtown-analytics/dbt/issues/2350\\n    */ #}\\n    {% set row_changed_expr -%}\\n        ({{ snapshotted_rel }}.dbt_valid_from < {{ current_rel }}.{{ updated_at }})\\n    {%- endset %}\\n\\n    {% set scd_id_expr = snapshot_hash_arguments([primary_key, updated_at]) %}\\n\\n    {% do return({\\n        \\\"unique_key\\\": primary_key,\\n        \\\"updated_at\\\": updated_at,\\n        \\\"row_changed\\\": row_changed_expr,\\n        \\\"scd_id\\\": scd_id_expr,\\n        \\\"invalidate_hard_deletes\\\": invalidate_hard_deletes\\n    }) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.snapshot_hash_arguments\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.snapshot_string_as_time\": {\"unique_id\": \"macro.dbt.snapshot_string_as_time\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshot/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshot/strategies.sql\", \"name\": \"snapshot_string_as_time\", \"macro_sql\": \"{% macro snapshot_string_as_time(timestamp) -%}\\n    {{ adapter.dispatch('snapshot_string_as_time')(timestamp) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__snapshot_string_as_time\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.default__snapshot_string_as_time\": {\"unique_id\": \"macro.dbt.default__snapshot_string_as_time\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshot/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshot/strategies.sql\", \"name\": \"default__snapshot_string_as_time\", \"macro_sql\": \"{% macro default__snapshot_string_as_time(timestamp) %}\\n    {% do exceptions.raise_not_implemented(\\n        'snapshot_string_as_time macro not implemented for adapter '+adapter.type()\\n    ) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.snapshot_check_all_get_existing_columns\": {\"unique_id\": \"macro.dbt.snapshot_check_all_get_existing_columns\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshot/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshot/strategies.sql\", \"name\": \"snapshot_check_all_get_existing_columns\", \"macro_sql\": \"{% macro snapshot_check_all_get_existing_columns(node, target_exists) -%}\\n    {%- set query_columns = get_columns_in_query(node['compiled_sql']) -%}\\n    {%- if not target_exists -%}\\n        {# no table yet -> return whatever the query does #}\\n        {{ return([false, query_columns]) }}\\n    {%- endif -%}\\n    {# handle any schema changes #}\\n    {%- set target_table = node.get('alias', node.get('name')) -%}\\n    {%- set target_relation = adapter.get_relation(database=node.database, schema=node.schema, identifier=target_table) -%}\\n    {%- set existing_cols = get_columns_in_query('select * from ' ~ target_relation) -%}\\n    {%- set ns = namespace() -%} {# handle for-loop scoping with a namespace #}\\n    {%- set ns.column_added = false -%}\\n\\n    {%- set intersection = [] -%}\\n    {%- for col in query_columns -%}\\n        {%- if col in existing_cols -%}\\n            {%- do intersection.append(col) -%}\\n        {%- else -%}\\n            {% set ns.column_added = true %}\\n        {%- endif -%}\\n    {%- endfor -%}\\n    {{ return([ns.column_added, intersection]) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_columns_in_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.snapshot_check_strategy\": {\"unique_id\": \"macro.dbt.snapshot_check_strategy\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshot/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshot/strategies.sql\", \"name\": \"snapshot_check_strategy\", \"macro_sql\": \"{% macro snapshot_check_strategy(node, snapshotted_rel, current_rel, config, target_exists) %}\\n    {% set check_cols_config = config['check_cols'] %}\\n    {% set primary_key = config['unique_key'] %}\\n    {% set invalidate_hard_deletes = config.get('invalidate_hard_deletes', false) %}\\n    \\n    {% set select_current_time -%}\\n        select {{ snapshot_get_time() }} as snapshot_start\\n    {%- endset %}\\n\\n    {#-- don't access the column by name, to avoid dealing with casing issues on snowflake #}\\n    {%- set now = run_query(select_current_time)[0][0] -%}\\n    {% if now is none or now is undefined -%}\\n        {%- do exceptions.raise_compiler_error('Could not get a snapshot start time from the database') -%}\\n    {%- endif %}\\n    {% set updated_at = config.get('updated_at', snapshot_string_as_time(now)) %}\\n\\n    {% set column_added = false %}\\n\\n    {% if check_cols_config == 'all' %}\\n        {% set column_added, check_cols = snapshot_check_all_get_existing_columns(node, target_exists) %}\\n    {% elif check_cols_config is iterable and (check_cols_config | length) > 0 %}\\n        {% set check_cols = check_cols_config %}\\n    {% else %}\\n        {% do exceptions.raise_compiler_error(\\\"Invalid value for 'check_cols': \\\" ~ check_cols_config) %}\\n    {% endif %}\\n\\n    {%- set row_changed_expr -%}\\n    (\\n    {%- if column_added -%}\\n        TRUE\\n    {%- else -%}\\n    {%- for col in check_cols -%}\\n        {{ snapshotted_rel }}.{{ col }} != {{ current_rel }}.{{ col }}\\n        or\\n        (\\n            (({{ snapshotted_rel }}.{{ col }} is null) and not ({{ current_rel }}.{{ col }} is null))\\n            or\\n            ((not {{ snapshotted_rel }}.{{ col }} is null) and ({{ current_rel }}.{{ col }} is null))\\n        )\\n        {%- if not loop.last %} or {% endif -%}\\n    {%- endfor -%}\\n    {%- endif -%}\\n    )\\n    {%- endset %}\\n\\n    {% set scd_id_expr = snapshot_hash_arguments([primary_key, updated_at]) %}\\n\\n    {% do return({\\n        \\\"unique_key\\\": primary_key,\\n        \\\"updated_at\\\": updated_at,\\n        \\\"row_changed\\\": row_changed_expr,\\n        \\\"scd_id\\\": scd_id_expr,\\n        \\\"invalidate_hard_deletes\\\": invalidate_hard_deletes\\n    }) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.snapshot_get_time\", \"macro.dbt.run_query\", \"macro.dbt.snapshot_string_as_time\", \"macro.dbt.snapshot_check_all_get_existing_columns\", \"macro.dbt.snapshot_hash_arguments\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.create_columns\": {\"unique_id\": \"macro.dbt.create_columns\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshot/snapshot.sql\", \"original_file_path\": \"macros/materializations/snapshot/snapshot.sql\", \"name\": \"create_columns\", \"macro_sql\": \"{% macro create_columns(relation, columns) %}\\n  {{ adapter.dispatch('create_columns')(relation, columns) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__create_columns\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.default__create_columns\": {\"unique_id\": \"macro.dbt.default__create_columns\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshot/snapshot.sql\", \"original_file_path\": \"macros/materializations/snapshot/snapshot.sql\", \"name\": \"default__create_columns\", \"macro_sql\": \"{% macro default__create_columns(relation, columns) %}\\n  {% for column in columns %}\\n    {% call statement() %}\\n      alter table {{ relation }} add column \\\"{{ column.name }}\\\" {{ column.data_type }};\\n    {% endcall %}\\n  {% endfor %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.post_snapshot\": {\"unique_id\": \"macro.dbt.post_snapshot\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshot/snapshot.sql\", \"original_file_path\": \"macros/materializations/snapshot/snapshot.sql\", \"name\": \"post_snapshot\", \"macro_sql\": \"{% macro post_snapshot(staging_relation) %}\\n  {{ adapter.dispatch('post_snapshot')(staging_relation) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__post_snapshot\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.default__post_snapshot\": {\"unique_id\": \"macro.dbt.default__post_snapshot\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshot/snapshot.sql\", \"original_file_path\": \"macros/materializations/snapshot/snapshot.sql\", \"name\": \"default__post_snapshot\", \"macro_sql\": \"{% macro default__post_snapshot(staging_relation) %}\\n    {# no-op #}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.snapshot_staging_table\": {\"unique_id\": \"macro.dbt.snapshot_staging_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshot/snapshot.sql\", \"original_file_path\": \"macros/materializations/snapshot/snapshot.sql\", \"name\": \"snapshot_staging_table\", \"macro_sql\": \"{% macro snapshot_staging_table(strategy, source_sql, target_relation) -%}\\n\\n    with snapshot_query as (\\n\\n        {{ source_sql }}\\n\\n    ),\\n\\n    snapshotted_data as (\\n\\n        select *,\\n            {{ strategy.unique_key }} as dbt_unique_key\\n\\n        from {{ target_relation }}\\n        where dbt_valid_to is null\\n\\n    ),\\n\\n    insertions_source_data as (\\n\\n        select\\n            *,\\n            {{ strategy.unique_key }} as dbt_unique_key,\\n            {{ strategy.updated_at }} as dbt_updated_at,\\n            {{ strategy.updated_at }} as dbt_valid_from,\\n            nullif({{ strategy.updated_at }}, {{ strategy.updated_at }}) as dbt_valid_to,\\n            {{ strategy.scd_id }} as dbt_scd_id\\n\\n        from snapshot_query\\n    ),\\n\\n    updates_source_data as (\\n\\n        select\\n            *,\\n            {{ strategy.unique_key }} as dbt_unique_key,\\n            {{ strategy.updated_at }} as dbt_updated_at,\\n            {{ strategy.updated_at }} as dbt_valid_from,\\n            {{ strategy.updated_at }} as dbt_valid_to\\n\\n        from snapshot_query\\n    ),\\n\\n    {%- if strategy.invalidate_hard_deletes %}\\n\\n    deletes_source_data as (\\n\\n        select \\n            *,\\n            {{ strategy.unique_key }} as dbt_unique_key\\n        from snapshot_query\\n    ),\\n    {% endif %}\\n\\n    insertions as (\\n\\n        select\\n            'insert' as dbt_change_type,\\n            source_data.*\\n\\n        from insertions_source_data as source_data\\n        left outer join snapshotted_data on snapshotted_data.dbt_unique_key = source_data.dbt_unique_key\\n        where snapshotted_data.dbt_unique_key is null\\n           or (\\n                snapshotted_data.dbt_unique_key is not null\\n            and (\\n                {{ strategy.row_changed }}\\n            )\\n        )\\n\\n    ),\\n\\n    updates as (\\n\\n        select\\n            'update' as dbt_change_type,\\n            source_data.*,\\n            snapshotted_data.dbt_scd_id\\n\\n        from updates_source_data as source_data\\n        join snapshotted_data on snapshotted_data.dbt_unique_key = source_data.dbt_unique_key\\n        where (\\n            {{ strategy.row_changed }}\\n        )\\n    )\\n\\n    {%- if strategy.invalidate_hard_deletes -%}\\n    ,\\n\\n    deletes as (\\n    \\n        select\\n            'delete' as dbt_change_type,\\n            source_data.*,\\n            {{ snapshot_get_time() }} as dbt_valid_from,\\n            {{ snapshot_get_time() }} as dbt_updated_at,\\n            {{ snapshot_get_time() }} as dbt_valid_to,\\n            snapshotted_data.dbt_scd_id\\n    \\n        from snapshotted_data\\n        left join deletes_source_data as source_data on snapshotted_data.dbt_unique_key = source_data.dbt_unique_key\\n        where source_data.dbt_unique_key is null\\n    )\\n    {%- endif %}\\n\\n    select * from insertions\\n    union all\\n    select * from updates\\n    {%- if strategy.invalidate_hard_deletes %}\\n    union all\\n    select * from deletes\\n    {%- endif %}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.snapshot_get_time\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.build_snapshot_table\": {\"unique_id\": \"macro.dbt.build_snapshot_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshot/snapshot.sql\", \"original_file_path\": \"macros/materializations/snapshot/snapshot.sql\", \"name\": \"build_snapshot_table\", \"macro_sql\": \"{% macro build_snapshot_table(strategy, sql) %}\\n\\n    select *,\\n        {{ strategy.scd_id }} as dbt_scd_id,\\n        {{ strategy.updated_at }} as dbt_updated_at,\\n        {{ strategy.updated_at }} as dbt_valid_from,\\n        nullif({{ strategy.updated_at }}, {{ strategy.updated_at }}) as dbt_valid_to\\n    from (\\n        {{ sql }}\\n    ) sbq\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.get_or_create_relation\": {\"unique_id\": \"macro.dbt.get_or_create_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshot/snapshot.sql\", \"original_file_path\": \"macros/materializations/snapshot/snapshot.sql\", \"name\": \"get_or_create_relation\", \"macro_sql\": \"{% macro get_or_create_relation(database, schema, identifier, type) %}\\n  {%- set target_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) %}\\n\\n  {% if target_relation %}\\n    {% do return([true, target_relation]) %}\\n  {% endif %}\\n\\n  {%- set new_relation = api.Relation.create(\\n      database=database,\\n      schema=schema,\\n      identifier=identifier,\\n      type=type\\n  ) -%}\\n  {% do return([false, new_relation]) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.build_snapshot_staging_table\": {\"unique_id\": \"macro.dbt.build_snapshot_staging_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshot/snapshot.sql\", \"original_file_path\": \"macros/materializations/snapshot/snapshot.sql\", \"name\": \"build_snapshot_staging_table\", \"macro_sql\": \"{% macro build_snapshot_staging_table(strategy, sql, target_relation) %}\\n    {% set tmp_relation = make_temp_relation(target_relation) %}\\n\\n    {% set select = snapshot_staging_table(strategy, sql, target_relation) %}\\n\\n    {% call statement('build_snapshot_staging_relation') %}\\n        {{ create_table_as(True, tmp_relation, select) }}\\n    {% endcall %}\\n\\n    {% do return(tmp_relation) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.make_temp_relation\", \"macro.dbt.snapshot_staging_table\", \"macro.dbt.statement\", \"macro.dbt.create_table_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.materialization_snapshot_default\": {\"unique_id\": \"macro.dbt.materialization_snapshot_default\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshot/snapshot.sql\", \"original_file_path\": \"macros/materializations/snapshot/snapshot.sql\", \"name\": \"materialization_snapshot_default\", \"macro_sql\": \"{% materialization snapshot, default %}\\n  {%- set config = model['config'] -%}\\n\\n  {%- set target_table = model.get('alias', model.get('name')) -%}\\n\\n  {%- set strategy_name = config.get('strategy') -%}\\n  {%- set unique_key = config.get('unique_key') %}\\n\\n  {% if not adapter.check_schema_exists(model.database, model.schema) %}\\n    {% do create_schema(model.database, model.schema) %}\\n  {% endif %}\\n\\n  {% set target_relation_exists, target_relation = get_or_create_relation(\\n          database=model.database,\\n          schema=model.schema,\\n          identifier=target_table,\\n          type='table') -%}\\n\\n  {%- if not target_relation.is_table -%}\\n    {% do exceptions.relation_wrong_type(target_relation, 'table') %}\\n  {%- endif -%}\\n\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  {% set strategy_macro = strategy_dispatch(strategy_name) %}\\n  {% set strategy = strategy_macro(model, \\\"snapshotted_data\\\", \\\"source_data\\\", config, target_relation_exists) %}\\n\\n  {% if not target_relation_exists %}\\n\\n      {% set build_sql = build_snapshot_table(strategy, model['compiled_sql']) %}\\n      {% set final_sql = create_table_as(False, target_relation, build_sql) %}\\n\\n  {% else %}\\n\\n      {{ adapter.valid_snapshot_target(target_relation) }}\\n\\n      {% set staging_table = build_snapshot_staging_table(strategy, sql, target_relation) %}\\n\\n      -- this may no-op if the database does not require column expansion\\n      {% do adapter.expand_target_column_types(from_relation=staging_table,\\n                                               to_relation=target_relation) %}\\n\\n      {% set missing_columns = adapter.get_missing_columns(staging_table, target_relation)\\n                                   | rejectattr('name', 'equalto', 'dbt_change_type')\\n                                   | rejectattr('name', 'equalto', 'DBT_CHANGE_TYPE')\\n                                   | rejectattr('name', 'equalto', 'dbt_unique_key')\\n                                   | rejectattr('name', 'equalto', 'DBT_UNIQUE_KEY')\\n                                   | list %}\\n\\n      {% do create_columns(target_relation, missing_columns) %}\\n\\n      {% set source_columns = adapter.get_columns_in_relation(staging_table)\\n                                   | rejectattr('name', 'equalto', 'dbt_change_type')\\n                                   | rejectattr('name', 'equalto', 'DBT_CHANGE_TYPE')\\n                                   | rejectattr('name', 'equalto', 'dbt_unique_key')\\n                                   | rejectattr('name', 'equalto', 'DBT_UNIQUE_KEY')\\n                                   | list %}\\n\\n      {% set quoted_source_columns = [] %}\\n      {% for column in source_columns %}\\n        {% do quoted_source_columns.append(adapter.quote(column.name)) %}\\n      {% endfor %}\\n\\n      {% set final_sql = snapshot_merge_sql(\\n            target = target_relation,\\n            source = staging_table,\\n            insert_cols = quoted_source_columns\\n         )\\n      %}\\n\\n  {% endif %}\\n\\n  {% call statement('main') %}\\n      {{ final_sql }}\\n  {% endcall %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {% if not target_relation_exists %}\\n    {% do create_indexes(target_relation) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  {{ adapter.commit() }}\\n\\n  {% if staging_table is defined %}\\n      {% do post_snapshot(staging_table) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{% endmaterialization %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.create_schema\", \"macro.dbt.get_or_create_relation\", \"macro.dbt.run_hooks\", \"macro.dbt.strategy_dispatch\", \"macro.dbt.build_snapshot_table\", \"macro.dbt.create_table_as\", \"macro.dbt.build_snapshot_staging_table\", \"macro.dbt.create_columns\", \"macro.dbt.snapshot_merge_sql\", \"macro.dbt.statement\", \"macro.dbt.persist_docs\", \"macro.dbt.create_indexes\", \"macro.dbt.post_snapshot\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.create_csv_table\": {\"unique_id\": \"macro.dbt.create_csv_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/seed/seed.sql\", \"original_file_path\": \"macros/materializations/seed/seed.sql\", \"name\": \"create_csv_table\", \"macro_sql\": \"{% macro create_csv_table(model, agate_table) -%}\\n  {{ adapter.dispatch('create_csv_table')(model, agate_table) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__create_csv_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.reset_csv_table\": {\"unique_id\": \"macro.dbt.reset_csv_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/seed/seed.sql\", \"original_file_path\": \"macros/materializations/seed/seed.sql\", \"name\": \"reset_csv_table\", \"macro_sql\": \"{% macro reset_csv_table(model, full_refresh, old_relation, agate_table) -%}\\n  {{ adapter.dispatch('reset_csv_table')(model, full_refresh, old_relation, agate_table) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__reset_csv_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.load_csv_rows\": {\"unique_id\": \"macro.dbt.load_csv_rows\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/seed/seed.sql\", \"original_file_path\": \"macros/materializations/seed/seed.sql\", \"name\": \"load_csv_rows\", \"macro_sql\": \"{% macro load_csv_rows(model, agate_table) -%}\\n  {{ adapter.dispatch('load_csv_rows')(model, agate_table) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__load_csv_rows\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.default__create_csv_table\": {\"unique_id\": \"macro.dbt.default__create_csv_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/seed/seed.sql\", \"original_file_path\": \"macros/materializations/seed/seed.sql\", \"name\": \"default__create_csv_table\", \"macro_sql\": \"{% macro default__create_csv_table(model, agate_table) %}\\n  {%- set column_override = model['config'].get('column_types', {}) -%}\\n  {%- set quote_seed_column = model['config'].get('quote_columns', None) -%}\\n\\n  {% set sql %}\\n    create table {{ this.render() }} (\\n        {%- for col_name in agate_table.column_names -%}\\n            {%- set inferred_type = adapter.convert_type(agate_table, loop.index0) -%}\\n            {%- set type = column_override.get(col_name, inferred_type) -%}\\n            {%- set column_name = (col_name | string) -%}\\n            {{ adapter.quote_seed_column(column_name, quote_seed_column) }} {{ type }} {%- if not loop.last -%}, {%- endif -%}\\n        {%- endfor -%}\\n    )\\n  {% endset %}\\n\\n  {% call statement('_') -%}\\n    {{ sql }}\\n  {%- endcall %}\\n\\n  {{ return(sql) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.default__reset_csv_table\": {\"unique_id\": \"macro.dbt.default__reset_csv_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/seed/seed.sql\", \"original_file_path\": \"macros/materializations/seed/seed.sql\", \"name\": \"default__reset_csv_table\", \"macro_sql\": \"{% macro default__reset_csv_table(model, full_refresh, old_relation, agate_table) %}\\n    {% set sql = \\\"\\\" %}\\n    {% if full_refresh %}\\n        {{ adapter.drop_relation(old_relation) }}\\n        {% set sql = create_csv_table(model, agate_table) %}\\n    {% else %}\\n        {{ adapter.truncate_relation(old_relation) }}\\n        {% set sql = \\\"truncate table \\\" ~ old_relation %}\\n    {% endif %}\\n\\n    {{ return(sql) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.create_csv_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.get_seed_column_quoted_csv\": {\"unique_id\": \"macro.dbt.get_seed_column_quoted_csv\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/seed/seed.sql\", \"original_file_path\": \"macros/materializations/seed/seed.sql\", \"name\": \"get_seed_column_quoted_csv\", \"macro_sql\": \"{% macro get_seed_column_quoted_csv(model, column_names) %}\\n  {%- set quote_seed_column = model['config'].get('quote_columns', None) -%}\\n    {% set quoted = [] %}\\n    {% for col in column_names -%}\\n        {%- do quoted.append(adapter.quote_seed_column(col, quote_seed_column)) -%}\\n    {%- endfor %}\\n\\n    {%- set dest_cols_csv = quoted | join(', ') -%}\\n    {{ return(dest_cols_csv) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665163}, \"macro.dbt.basic_load_csv_rows\": {\"unique_id\": \"macro.dbt.basic_load_csv_rows\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/seed/seed.sql\", \"original_file_path\": \"macros/materializations/seed/seed.sql\", \"name\": \"basic_load_csv_rows\", \"macro_sql\": \"{% macro basic_load_csv_rows(model, batch_size, agate_table) %}\\n    {% set cols_sql = get_seed_column_quoted_csv(model, agate_table.column_names) %}\\n    {% set bindings = [] %}\\n\\n    {% set statements = [] %}\\n\\n    {% for chunk in agate_table.rows | batch(batch_size) %}\\n        {% set bindings = [] %}\\n\\n        {% for row in chunk %}\\n            {% do bindings.extend(row) %}\\n        {% endfor %}\\n\\n        {% set sql %}\\n            insert into {{ this.render() }} ({{ cols_sql }}) values\\n            {% for row in chunk -%}\\n                ({%- for column in agate_table.column_names -%}\\n                    %s\\n                    {%- if not loop.last%},{%- endif %}\\n                {%- endfor -%})\\n                {%- if not loop.last%},{%- endif %}\\n            {%- endfor %}\\n        {% endset %}\\n\\n        {% do adapter.add_query(sql, bindings=bindings, abridge_sql_log=True) %}\\n\\n        {% if loop.index0 == 0 %}\\n            {% do statements.append(sql) %}\\n        {% endif %}\\n    {% endfor %}\\n\\n    {# Return SQL so we can render it out into the compiled files #}\\n    {{ return(statements[0]) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_seed_column_quoted_csv\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.default__load_csv_rows\": {\"unique_id\": \"macro.dbt.default__load_csv_rows\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/seed/seed.sql\", \"original_file_path\": \"macros/materializations/seed/seed.sql\", \"name\": \"default__load_csv_rows\", \"macro_sql\": \"{% macro default__load_csv_rows(model, agate_table) %}\\n  {{ return(basic_load_csv_rows(model, 10000, agate_table) )}}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.basic_load_csv_rows\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.materialization_seed_default\": {\"unique_id\": \"macro.dbt.materialization_seed_default\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/seed/seed.sql\", \"original_file_path\": \"macros/materializations/seed/seed.sql\", \"name\": \"materialization_seed_default\", \"macro_sql\": \"{% materialization seed, default %}\\n\\n  {%- set identifier = model['alias'] -%}\\n  {%- set full_refresh_mode = (should_full_refresh()) -%}\\n\\n  {%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%}\\n\\n  {%- set exists_as_table = (old_relation is not none and old_relation.is_table) -%}\\n  {%- set exists_as_view = (old_relation is not none and old_relation.is_view) -%}\\n\\n  {%- set agate_table = load_agate_table() -%}\\n  {%- do store_result('agate_table', response='OK', agate_table=agate_table) -%}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  -- build model\\n  {% set create_table_sql = \\\"\\\" %}\\n  {% if exists_as_view %}\\n    {{ exceptions.raise_compiler_error(\\\"Cannot seed to '{}', it is a view\\\".format(old_relation)) }}\\n  {% elif exists_as_table %}\\n    {% set create_table_sql = reset_csv_table(model, full_refresh_mode, old_relation, agate_table) %}\\n  {% else %}\\n    {% set create_table_sql = create_csv_table(model, agate_table) %}\\n  {% endif %}\\n\\n  {% set code = 'CREATE' if full_refresh_mode else 'INSERT' %}\\n  {% set rows_affected = (agate_table.rows | length) %}\\n  {% set sql = load_csv_rows(model, agate_table) %}\\n\\n  {% call noop_statement('main', code ~ ' ' ~ rows_affected, code, rows_affected) %}\\n    {{ create_table_sql }};\\n    -- dbt seed --\\n    {{ sql }}\\n  {% endcall %}\\n\\n  {% set target_relation = this.incorporate(type='table') %}\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {% if full_refresh_mode or not exists_as_table %}\\n    {% do create_indexes(target_relation) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  -- `COMMIT` happens here\\n  {{ adapter.commit() }}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{% endmaterialization %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.should_full_refresh\", \"macro.dbt.run_hooks\", \"macro.dbt.reset_csv_table\", \"macro.dbt.create_csv_table\", \"macro.dbt.load_csv_rows\", \"macro.dbt.noop_statement\", \"macro.dbt.persist_docs\", \"macro.dbt.create_indexes\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.incremental_upsert\": {\"unique_id\": \"macro.dbt.incremental_upsert\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/incremental/helpers.sql\", \"original_file_path\": \"macros/materializations/incremental/helpers.sql\", \"name\": \"incremental_upsert\", \"macro_sql\": \"{% macro incremental_upsert(tmp_relation, target_relation, unique_key=none, statement_name=\\\"main\\\") %}\\n    {%- set dest_columns = adapter.get_columns_in_relation(target_relation) -%}\\n    {%- set dest_cols_csv = dest_columns | map(attribute='quoted') | join(', ') -%}\\n\\n    {%- if unique_key is not none -%}\\n    delete\\n    from {{ target_relation }}\\n    where ({{ unique_key }}) in (\\n        select ({{ unique_key }})\\n        from {{ tmp_relation }}\\n    );\\n    {%- endif %}\\n\\n    insert into {{ target_relation }} ({{ dest_cols_csv }})\\n    (\\n       select {{ dest_cols_csv }}\\n       from {{ tmp_relation }}\\n    );\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.materialization_incremental_default\": {\"unique_id\": \"macro.dbt.materialization_incremental_default\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/incremental/incremental.sql\", \"original_file_path\": \"macros/materializations/incremental/incremental.sql\", \"name\": \"materialization_incremental_default\", \"macro_sql\": \"{% materialization incremental, default -%}\\n\\n  {% set unique_key = config.get('unique_key') %}\\n\\n  {% set target_relation = this.incorporate(type='table') %}\\n  {% set existing_relation = load_relation(this) %}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  {% set to_drop = [] %}\\n  {% if existing_relation is none %}\\n      {% set build_sql = create_table_as(False, target_relation, sql) %}\\n  {% elif existing_relation.is_view or should_full_refresh() %}\\n      {#-- Make sure the backup doesn't exist so we don't encounter issues with the rename below #}\\n      {% set tmp_identifier = model['name'] + '__dbt_tmp' %}\\n      {% set backup_identifier = model['name'] + \\\"__dbt_backup\\\" %}\\n\\n      {% set intermediate_relation = existing_relation.incorporate(path={\\\"identifier\\\": tmp_identifier}) %}\\n      {% set backup_relation = existing_relation.incorporate(path={\\\"identifier\\\": backup_identifier}) %}\\n\\n      {% do adapter.drop_relation(intermediate_relation) %}\\n      {% do adapter.drop_relation(backup_relation) %}\\n\\n      {% set build_sql = create_table_as(False, intermediate_relation, sql) %}\\n      {% set need_swap = true %}\\n      {% do to_drop.append(backup_relation) %}\\n  {% else %}\\n      {% set tmp_relation = make_temp_relation(target_relation) %}\\n      {% do run_query(create_table_as(True, tmp_relation, sql)) %}\\n      {% do adapter.expand_target_column_types(\\n             from_relation=tmp_relation,\\n             to_relation=target_relation) %}\\n      {% set build_sql = incremental_upsert(tmp_relation, target_relation, unique_key=unique_key) %}\\n  {% endif %}\\n\\n  {% call statement(\\\"main\\\") %}\\n      {{ build_sql }}\\n  {% endcall %}\\n\\n  {% if need_swap %} \\n      {% do adapter.rename_relation(target_relation, backup_relation) %} \\n      {% do adapter.rename_relation(intermediate_relation, target_relation) %} \\n  {% endif %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {% if existing_relation is none or existing_relation.is_view or should_full_refresh() %}\\n    {% do create_indexes(target_relation) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  -- `COMMIT` happens here\\n  {% do adapter.commit() %}\\n\\n  {% for rel in to_drop %}\\n      {% do adapter.drop_relation(rel) %}\\n  {% endfor %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{%- endmaterialization %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.test.load_relation\", \"macro.dbt.run_hooks\", \"macro.dbt.create_table_as\", \"macro.dbt.should_full_refresh\", \"macro.dbt.make_temp_relation\", \"macro.dbt.run_query\", \"macro.dbt.incremental_upsert\", \"macro.dbt.statement\", \"macro.dbt.persist_docs\", \"macro.dbt.create_indexes\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.get_merge_sql\": {\"unique_id\": \"macro.dbt.get_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/common/merge.sql\", \"original_file_path\": \"macros/materializations/common/merge.sql\", \"name\": \"get_merge_sql\", \"macro_sql\": \"{% macro get_merge_sql(target, source, unique_key, dest_columns, predicates=none) -%}\\n  {{ adapter.dispatch('get_merge_sql')(target, source, unique_key, dest_columns, predicates) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.get_delete_insert_merge_sql\": {\"unique_id\": \"macro.dbt.get_delete_insert_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/common/merge.sql\", \"original_file_path\": \"macros/materializations/common/merge.sql\", \"name\": \"get_delete_insert_merge_sql\", \"macro_sql\": \"{% macro get_delete_insert_merge_sql(target, source, unique_key, dest_columns) -%}\\n  {{ adapter.dispatch('get_delete_insert_merge_sql')(target, source, unique_key, dest_columns) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_delete_insert_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.get_insert_overwrite_merge_sql\": {\"unique_id\": \"macro.dbt.get_insert_overwrite_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/common/merge.sql\", \"original_file_path\": \"macros/materializations/common/merge.sql\", \"name\": \"get_insert_overwrite_merge_sql\", \"macro_sql\": \"{% macro get_insert_overwrite_merge_sql(target, source, dest_columns, predicates, include_sql_header=false) -%}\\n  {{ adapter.dispatch('get_insert_overwrite_merge_sql')(target, source, dest_columns, predicates, include_sql_header) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_insert_overwrite_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.default__get_merge_sql\": {\"unique_id\": \"macro.dbt.default__get_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/common/merge.sql\", \"original_file_path\": \"macros/materializations/common/merge.sql\", \"name\": \"default__get_merge_sql\", \"macro_sql\": \"{% macro default__get_merge_sql(target, source, unique_key, dest_columns, predicates) -%}\\n    {%- set predicates = [] if predicates is none else [] + predicates -%}\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n    {%- set update_columns = config.get('merge_update_columns', default = dest_columns | map(attribute=\\\"quoted\\\") | list) -%}\\n    {%- set sql_header = config.get('sql_header', none) -%}\\n\\n    {% if unique_key %}\\n        {% set unique_key_match %}\\n            DBT_INTERNAL_SOURCE.{{ unique_key }} = DBT_INTERNAL_DEST.{{ unique_key }}\\n        {% endset %}\\n        {% do predicates.append(unique_key_match) %}\\n    {% else %}\\n        {% do predicates.append('FALSE') %}\\n    {% endif %}\\n\\n    {{ sql_header if sql_header is not none }}\\n\\n    merge into {{ target }} as DBT_INTERNAL_DEST\\n        using {{ source }} as DBT_INTERNAL_SOURCE\\n        on {{ predicates | join(' and ') }}\\n\\n    {% if unique_key %}\\n    when matched then update set\\n        {% for column_name in update_columns -%}\\n            {{ column_name }} = DBT_INTERNAL_SOURCE.{{ column_name }}\\n            {%- if not loop.last %}, {%- endif %}\\n        {%- endfor %}\\n    {% endif %}\\n\\n    when not matched then insert\\n        ({{ dest_cols_csv }})\\n    values\\n        ({{ dest_cols_csv }})\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_quoted_csv\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.get_quoted_csv\": {\"unique_id\": \"macro.dbt.get_quoted_csv\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/common/merge.sql\", \"original_file_path\": \"macros/materializations/common/merge.sql\", \"name\": \"get_quoted_csv\", \"macro_sql\": \"{% macro get_quoted_csv(column_names) %}\\n    {% set quoted = [] %}\\n    {% for col in column_names -%}\\n        {%- do quoted.append(adapter.quote(col)) -%}\\n    {%- endfor %}\\n\\n    {%- set dest_cols_csv = quoted | join(', ') -%}\\n    {{ return(dest_cols_csv) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.common_get_delete_insert_merge_sql\": {\"unique_id\": \"macro.dbt.common_get_delete_insert_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/common/merge.sql\", \"original_file_path\": \"macros/materializations/common/merge.sql\", \"name\": \"common_get_delete_insert_merge_sql\", \"macro_sql\": \"{% macro common_get_delete_insert_merge_sql(target, source, unique_key, dest_columns) -%}\\n\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n\\n    {% if unique_key is not none %}\\n    delete from {{ target }}\\n    where ({{ unique_key }}) in (\\n        select ({{ unique_key }})\\n        from {{ source }}\\n    );\\n    {% endif %}\\n\\n    insert into {{ target }} ({{ dest_cols_csv }})\\n    (\\n        select {{ dest_cols_csv }}\\n        from {{ source }}\\n    );\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_quoted_csv\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.default__get_delete_insert_merge_sql\": {\"unique_id\": \"macro.dbt.default__get_delete_insert_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/common/merge.sql\", \"original_file_path\": \"macros/materializations/common/merge.sql\", \"name\": \"default__get_delete_insert_merge_sql\", \"macro_sql\": \"{% macro default__get_delete_insert_merge_sql(target, source, unique_key, dest_columns) -%}\\n    {{ common_get_delete_insert_merge_sql(target, source, unique_key, dest_columns) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.common_get_delete_insert_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.default__get_insert_overwrite_merge_sql\": {\"unique_id\": \"macro.dbt.default__get_insert_overwrite_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/common/merge.sql\", \"original_file_path\": \"macros/materializations/common/merge.sql\", \"name\": \"default__get_insert_overwrite_merge_sql\", \"macro_sql\": \"{% macro default__get_insert_overwrite_merge_sql(target, source, dest_columns, predicates, include_sql_header) -%}\\n    {%- set predicates = [] if predicates is none else [] + predicates -%}\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n    {%- set sql_header = config.get('sql_header', none) -%}\\n\\n    {{ sql_header if sql_header is not none and include_sql_header }}\\n\\n    merge into {{ target }} as DBT_INTERNAL_DEST\\n        using {{ source }} as DBT_INTERNAL_SOURCE\\n        on FALSE\\n\\n    when not matched by source\\n        {% if predicates %} and {{ predicates | join(' and ') }} {% endif %}\\n        then delete\\n\\n    when not matched then insert\\n        ({{ dest_cols_csv }})\\n    values\\n        ({{ dest_cols_csv }})\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_quoted_csv\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.materialization_table_default\": {\"unique_id\": \"macro.dbt.materialization_table_default\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/table/table.sql\", \"original_file_path\": \"macros/materializations/table/table.sql\", \"name\": \"materialization_table_default\", \"macro_sql\": \"{% materialization table, default %}\\n  {%- set identifier = model['alias'] -%}\\n  {%- set tmp_identifier = model['name'] + '__dbt_tmp' -%}\\n  {%- set backup_identifier = model['name'] + '__dbt_backup' -%}\\n\\n  {%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%}\\n  {%- set target_relation = api.Relation.create(identifier=identifier,\\n                                                schema=schema,\\n                                                database=database,\\n                                                type='table') -%}\\n  {%- set intermediate_relation = api.Relation.create(identifier=tmp_identifier,\\n                                                      schema=schema,\\n                                                      database=database,\\n                                                      type='table') -%}\\n\\n  /*\\n      See ../view/view.sql for more information about this relation.\\n  */\\n  {%- set backup_relation_type = 'table' if old_relation is none else old_relation.type -%}\\n  {%- set backup_relation = api.Relation.create(identifier=backup_identifier,\\n                                                schema=schema,\\n                                                database=database,\\n                                                type=backup_relation_type) -%}\\n\\n  {%- set exists_as_table = (old_relation is not none and old_relation.is_table) -%}\\n  {%- set exists_as_view = (old_relation is not none and old_relation.is_view) -%}\\n\\n\\n  -- drop the temp relations if they exists for some reason\\n  {{ adapter.drop_relation(intermediate_relation) }}\\n  {{ adapter.drop_relation(backup_relation) }}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  -- build model\\n  {% call statement('main') -%}\\n    {{ create_table_as(False, intermediate_relation, sql) }}\\n  {%- endcall %}\\n\\n  -- cleanup\\n  {% if old_relation is not none %}\\n      {{ adapter.rename_relation(target_relation, backup_relation) }}\\n  {% endif %}\\n\\n  {{ adapter.rename_relation(intermediate_relation, target_relation) }}\\n\\n  {% do create_indexes(target_relation) %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  -- `COMMIT` happens here\\n  {{ adapter.commit() }}\\n\\n  -- finally, drop the existing/backup relation after the commit\\n  {{ drop_relation_if_exists(backup_relation) }}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n{% endmaterialization %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.run_hooks\", \"macro.dbt.statement\", \"macro.dbt.create_table_as\", \"macro.dbt.create_indexes\", \"macro.dbt.persist_docs\", \"macro.dbt.drop_relation_if_exists\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.materialization_view_default\": {\"unique_id\": \"macro.dbt.materialization_view_default\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/view/view.sql\", \"original_file_path\": \"macros/materializations/view/view.sql\", \"name\": \"materialization_view_default\", \"macro_sql\": \"{%- materialization view, default -%}\\n\\n  {%- set identifier = model['alias'] -%}\\n  {%- set tmp_identifier = model['name'] + '__dbt_tmp' -%}\\n  {%- set backup_identifier = model['name'] + '__dbt_backup' -%}\\n\\n  {%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%}\\n  {%- set target_relation = api.Relation.create(identifier=identifier, schema=schema, database=database,\\n                                                type='view') -%}\\n  {%- set intermediate_relation = api.Relation.create(identifier=tmp_identifier,\\n                                                      schema=schema, database=database, type='view') -%}\\n\\n  /*\\n     This relation (probably) doesn't exist yet. If it does exist, it's a leftover from\\n     a previous run, and we're going to try to drop it immediately. At the end of this\\n     materialization, we're going to rename the \\\"old_relation\\\" to this identifier,\\n     and then we're going to drop it. In order to make sure we run the correct one of:\\n       - drop view ...\\n       - drop table ...\\n\\n     We need to set the type of this relation to be the type of the old_relation, if it exists,\\n     or else \\\"view\\\" as a sane default if it does not. Note that if the old_relation does not\\n     exist, then there is nothing to move out of the way and subsequentally drop. In that case,\\n     this relation will be effectively unused.\\n  */\\n  {%- set backup_relation_type = 'view' if old_relation is none else old_relation.type -%}\\n  {%- set backup_relation = api.Relation.create(identifier=backup_identifier,\\n                                                schema=schema, database=database,\\n                                                type=backup_relation_type) -%}\\n\\n  {%- set exists_as_view = (old_relation is not none and old_relation.is_view) -%}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- drop the temp relations if they exists for some reason\\n  {{ adapter.drop_relation(intermediate_relation) }}\\n  {{ adapter.drop_relation(backup_relation) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  -- build model\\n  {% call statement('main') -%}\\n    {{ create_view_as(intermediate_relation, sql) }}\\n  {%- endcall %}\\n\\n  -- cleanup\\n  -- move the existing view out of the way\\n  {% if old_relation is not none %}\\n    {{ adapter.rename_relation(target_relation, backup_relation) }}\\n  {% endif %}\\n  {{ adapter.rename_relation(intermediate_relation, target_relation) }}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  {{ adapter.commit() }}\\n\\n  {{ drop_relation_if_exists(backup_relation) }}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{%- endmaterialization -%}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.run_hooks\", \"macro.dbt.statement\", \"macro.dbt.create_view_as\", \"macro.dbt.persist_docs\", \"macro.dbt.drop_relation_if_exists\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.handle_existing_table\": {\"unique_id\": \"macro.dbt.handle_existing_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/view/create_or_replace_view.sql\", \"original_file_path\": \"macros/materializations/view/create_or_replace_view.sql\", \"name\": \"handle_existing_table\", \"macro_sql\": \"{% macro handle_existing_table(full_refresh, old_relation) %}\\n    {{ adapter.dispatch('handle_existing_table', macro_namespace = 'dbt')(full_refresh, old_relation) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__handle_existing_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.default__handle_existing_table\": {\"unique_id\": \"macro.dbt.default__handle_existing_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/view/create_or_replace_view.sql\", \"original_file_path\": \"macros/materializations/view/create_or_replace_view.sql\", \"name\": \"default__handle_existing_table\", \"macro_sql\": \"{% macro default__handle_existing_table(full_refresh, old_relation) %}\\n    {{ adapter.drop_relation(old_relation) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.create_or_replace_view\": {\"unique_id\": \"macro.dbt.create_or_replace_view\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/view/create_or_replace_view.sql\", \"original_file_path\": \"macros/materializations/view/create_or_replace_view.sql\", \"name\": \"create_or_replace_view\", \"macro_sql\": \"{% macro create_or_replace_view(run_outside_transaction_hooks=True) %}\\n  {%- set identifier = model['alias'] -%}\\n\\n  {%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%}\\n\\n  {%- set exists_as_view = (old_relation is not none and old_relation.is_view) -%}\\n\\n  {%- set target_relation = api.Relation.create(\\n      identifier=identifier, schema=schema, database=database,\\n      type='view') -%}\\n\\n  {% if run_outside_transaction_hooks %}\\n      -- no transactions on BigQuery\\n      {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n  {% endif %}\\n\\n  -- `BEGIN` happens here on Snowflake\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  -- If there's a table with the same name and we weren't told to full refresh,\\n  -- that's an error. If we were told to full refresh, drop it. This behavior differs\\n  -- for Snowflake and BigQuery, so multiple dispatch is used.\\n  {%- if old_relation is not none and old_relation.is_table -%}\\n    {{ handle_existing_table(should_full_refresh(), old_relation) }}\\n  {%- endif -%}\\n\\n  -- build model\\n  {% call statement('main') -%}\\n    {{ create_view_as(target_relation, sql) }}\\n  {%- endcall %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  {{ adapter.commit() }}\\n\\n  {% if run_outside_transaction_hooks %}\\n      -- No transactions on BigQuery\\n      {{ run_hooks(post_hooks, inside_transaction=False) }}\\n  {% endif %}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.run_hooks\", \"macro.dbt.handle_existing_table\", \"macro.dbt.should_full_refresh\", \"macro.dbt.statement\", \"macro.dbt.create_view_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.generate_alias_name\": {\"unique_id\": \"macro.dbt.generate_alias_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/etc/get_custom_alias.sql\", \"original_file_path\": \"macros/etc/get_custom_alias.sql\", \"name\": \"generate_alias_name\", \"macro_sql\": \"{% macro generate_alias_name(custom_alias_name=none, node=none) -%}\\n\\n    {%- if custom_alias_name is none -%}\\n\\n        {{ node.name }}\\n\\n    {%- else -%}\\n\\n        {{ custom_alias_name | trim }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.run_query\": {\"unique_id\": \"macro.dbt.run_query\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/etc/query.sql\", \"original_file_path\": \"macros/etc/query.sql\", \"name\": \"run_query\", \"macro_sql\": \"{% macro run_query(sql) %}\\n  {% call statement(\\\"run_query_statement\\\", fetch_result=true, auto_begin=false) %}\\n    {{ sql }}\\n  {% endcall %}\\n\\n  {% do return(load_result(\\\"run_query_statement\\\").table) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.is_incremental\": {\"unique_id\": \"macro.dbt.is_incremental\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/etc/is_incremental.sql\", \"original_file_path\": \"macros/etc/is_incremental.sql\", \"name\": \"is_incremental\", \"macro_sql\": \"{% macro is_incremental() %}\\n    {#-- do not run introspective queries in parsing #}\\n    {% if not execute %}\\n        {{ return(False) }}\\n    {% else %}\\n        {% set relation = adapter.get_relation(this.database, this.schema, this.table) %}\\n        {{ return(relation is not none\\n                  and relation.type == 'table'\\n                  and model.config.materialized == 'incremental'\\n                  and not should_full_refresh()) }}\\n    {% endif %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.should_full_refresh\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.convert_datetime\": {\"unique_id\": \"macro.dbt.convert_datetime\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"name\": \"convert_datetime\", \"macro_sql\": \"{% macro convert_datetime(date_str, date_fmt) %}\\n\\n  {% set error_msg -%}\\n      The provided partition date '{{ date_str }}' does not match the expected format '{{ date_fmt }}'\\n  {%- endset %}\\n\\n  {% set res = try_or_compiler_error(error_msg, modules.datetime.datetime.strptime, date_str.strip(), date_fmt) %}\\n  {{ return(res) }}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.dates_in_range\": {\"unique_id\": \"macro.dbt.dates_in_range\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"name\": \"dates_in_range\", \"macro_sql\": \"{% macro dates_in_range(start_date_str, end_date_str=none, in_fmt=\\\"%Y%m%d\\\", out_fmt=\\\"%Y%m%d\\\") %}\\n    {% set end_date_str = start_date_str if end_date_str is none else end_date_str %}\\n\\n    {% set start_date = convert_datetime(start_date_str, in_fmt) %}\\n    {% set end_date = convert_datetime(end_date_str, in_fmt) %}\\n\\n    {% set day_count = (end_date - start_date).days %}\\n    {% if day_count < 0 %}\\n        {% set msg -%}\\n            Partition start date is after the end date ({{ start_date }}, {{ end_date }})\\n        {%- endset %}\\n\\n        {{ exceptions.raise_compiler_error(msg, model) }}\\n    {% endif %}\\n\\n    {% set date_list = [] %}\\n    {% for i in range(0, day_count + 1) %}\\n        {% set the_date = (modules.datetime.timedelta(days=i) + start_date) %}\\n        {% if not out_fmt %}\\n            {% set _ = date_list.append(the_date) %}\\n        {% else %}\\n            {% set _ = date_list.append(the_date.strftime(out_fmt)) %}\\n        {% endif %}\\n    {% endfor %}\\n\\n    {{ return(date_list) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.convert_datetime\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.partition_range\": {\"unique_id\": \"macro.dbt.partition_range\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"name\": \"partition_range\", \"macro_sql\": \"{% macro partition_range(raw_partition_date, date_fmt='%Y%m%d') %}\\n    {% set partition_range = (raw_partition_date | string).split(\\\",\\\") %}\\n\\n    {% if (partition_range | length) == 1 %}\\n      {% set start_date = partition_range[0] %}\\n      {% set end_date = none %}\\n    {% elif (partition_range | length) == 2 %}\\n      {% set start_date = partition_range[0] %}\\n      {% set end_date = partition_range[1] %}\\n    {% else %}\\n      {{ exceptions.raise_compiler_error(\\\"Invalid partition time. Expected format: {Start Date}[,{End Date}]. Got: \\\" ~ raw_partition_date) }}\\n    {% endif %}\\n\\n    {{ return(dates_in_range(start_date, end_date, in_fmt=date_fmt)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.dates_in_range\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.py_current_timestring\": {\"unique_id\": \"macro.dbt.py_current_timestring\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"name\": \"py_current_timestring\", \"macro_sql\": \"{% macro py_current_timestring() %}\\n    {% set dt = modules.datetime.datetime.now() %}\\n    {% do return(dt.strftime(\\\"%Y%m%d%H%M%S%f\\\")) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.generate_schema_name\": {\"unique_id\": \"macro.dbt.generate_schema_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/etc/get_custom_schema.sql\", \"original_file_path\": \"macros/etc/get_custom_schema.sql\", \"name\": \"generate_schema_name\", \"macro_sql\": \"{% macro generate_schema_name(custom_schema_name, node) -%}\\n\\n    {%- set default_schema = target.schema -%}\\n    {%- if custom_schema_name is none -%}\\n\\n        {{ default_schema }}\\n\\n    {%- else -%}\\n\\n        {{ default_schema }}_{{ custom_schema_name | trim }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.generate_schema_name_for_env\": {\"unique_id\": \"macro.dbt.generate_schema_name_for_env\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/etc/get_custom_schema.sql\", \"original_file_path\": \"macros/etc/get_custom_schema.sql\", \"name\": \"generate_schema_name_for_env\", \"macro_sql\": \"{% macro generate_schema_name_for_env(custom_schema_name, node) -%}\\n\\n    {%- set default_schema = target.schema -%}\\n    {%- if target.name == 'prod' and custom_schema_name is not none -%}\\n\\n        {{ custom_schema_name | trim }}\\n\\n    {%- else -%}\\n\\n        {{ default_schema }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.generate_database_name\": {\"unique_id\": \"macro.dbt.generate_database_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/etc/get_custom_database.sql\", \"original_file_path\": \"macros/etc/get_custom_database.sql\", \"name\": \"generate_database_name\", \"macro_sql\": \"{% macro generate_database_name(custom_database_name=none, node=none) -%}\\n    {% do return(adapter.dispatch('generate_database_name')(custom_database_name, node)) %}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__generate_database_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.default__generate_database_name\": {\"unique_id\": \"macro.dbt.default__generate_database_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/etc/get_custom_database.sql\", \"original_file_path\": \"macros/etc/get_custom_database.sql\", \"name\": \"default__generate_database_name\", \"macro_sql\": \"{% macro default__generate_database_name(custom_database_name=none, node=none) -%}\\n    {%- set default_database = target.database -%}\\n    {%- if custom_database_name is none -%}\\n\\n        {{ default_database }}\\n\\n    {%- else -%}\\n\\n        {{ custom_database_name }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.get_columns_in_query\": {\"unique_id\": \"macro.dbt.get_columns_in_query\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"get_columns_in_query\", \"macro_sql\": \"{% macro get_columns_in_query(select_sql) -%}\\n  {{ return(adapter.dispatch('get_columns_in_query')(select_sql)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_columns_in_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.default__get_columns_in_query\": {\"unique_id\": \"macro.dbt.default__get_columns_in_query\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__get_columns_in_query\", \"macro_sql\": \"{% macro default__get_columns_in_query(select_sql) %}\\n    {% call statement('get_columns_in_query', fetch_result=True, auto_begin=False) -%}\\n        select * from (\\n            {{ select_sql }}\\n        ) as __dbt_sbq\\n        where false\\n        limit 0\\n    {% endcall %}\\n\\n    {{ return(load_result('get_columns_in_query').table.columns | map(attribute='name') | list) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.create_schema\": {\"unique_id\": \"macro.dbt.create_schema\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"create_schema\", \"macro_sql\": \"{% macro create_schema(relation) -%}\\n  {{ adapter.dispatch('create_schema')(relation) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__create_schema\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.default__create_schema\": {\"unique_id\": \"macro.dbt.default__create_schema\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__create_schema\", \"macro_sql\": \"{% macro default__create_schema(relation) -%}\\n  {%- call statement('create_schema') -%}\\n    create schema if not exists {{ relation.without_identifier() }}\\n  {% endcall %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.drop_schema\": {\"unique_id\": \"macro.dbt.drop_schema\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"drop_schema\", \"macro_sql\": \"{% macro drop_schema(relation) -%}\\n  {{ adapter.dispatch('drop_schema')(relation) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__drop_schema\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.default__drop_schema\": {\"unique_id\": \"macro.dbt.default__drop_schema\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__drop_schema\", \"macro_sql\": \"{% macro default__drop_schema(relation) -%}\\n  {%- call statement('drop_schema') -%}\\n    drop schema if exists {{ relation.without_identifier() }} cascade\\n  {% endcall %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.create_table_as\": {\"unique_id\": \"macro.dbt.create_table_as\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"create_table_as\", \"macro_sql\": \"{% macro create_table_as(temporary, relation, sql) -%}\\n  {{ adapter.dispatch('create_table_as')(temporary, relation, sql) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__create_table_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.default__create_table_as\": {\"unique_id\": \"macro.dbt.default__create_table_as\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__create_table_as\", \"macro_sql\": \"{% macro default__create_table_as(temporary, relation, sql) -%}\\n  {%- set sql_header = config.get('sql_header', none) -%}\\n\\n  {{ sql_header if sql_header is not none }}\\n\\n  create {% if temporary: -%}temporary{%- endif %} table\\n    {{ relation.include(database=(not temporary), schema=(not temporary)) }}\\n  as (\\n    {{ sql }}\\n  );\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.get_create_index_sql\": {\"unique_id\": \"macro.dbt.get_create_index_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"get_create_index_sql\", \"macro_sql\": \"{% macro get_create_index_sql(relation, index_dict) -%}\\n  {{ return(adapter.dispatch('get_create_index_sql')(relation, index_dict)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_create_index_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.default__get_create_index_sql\": {\"unique_id\": \"macro.dbt.default__get_create_index_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__get_create_index_sql\", \"macro_sql\": \"{% macro default__get_create_index_sql(relation, index_dict) -%}\\n  {% do return(None) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.create_indexes\": {\"unique_id\": \"macro.dbt.create_indexes\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"create_indexes\", \"macro_sql\": \"{% macro create_indexes(relation) -%}\\n  {{ adapter.dispatch('create_indexes')(relation) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__create_indexes\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.default__create_indexes\": {\"unique_id\": \"macro.dbt.default__create_indexes\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__create_indexes\", \"macro_sql\": \"{% macro default__create_indexes(relation) -%}\\n  {%- set _indexes = config.get('indexes', default=[]) -%}\\n\\n  {% for _index_dict in _indexes %}\\n    {% set create_index_sql = get_create_index_sql(relation, _index_dict) %}\\n    {% if create_index_sql %}\\n      {% do run_query(create_index_sql) %}\\n    {% endif %}\\n  {% endfor %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_create_index_sql\", \"macro.dbt.run_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.create_view_as\": {\"unique_id\": \"macro.dbt.create_view_as\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"create_view_as\", \"macro_sql\": \"{% macro create_view_as(relation, sql) -%}\\n  {{ adapter.dispatch('create_view_as')(relation, sql) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__create_view_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.default__create_view_as\": {\"unique_id\": \"macro.dbt.default__create_view_as\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__create_view_as\", \"macro_sql\": \"{% macro default__create_view_as(relation, sql) -%}\\n  {%- set sql_header = config.get('sql_header', none) -%}\\n\\n  {{ sql_header if sql_header is not none }}\\n  create view {{ relation }} as (\\n    {{ sql }}\\n  );\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.get_catalog\": {\"unique_id\": \"macro.dbt.get_catalog\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"get_catalog\", \"macro_sql\": \"{% macro get_catalog(information_schema, schemas) -%}\\n  {{ return(adapter.dispatch('get_catalog')(information_schema, schemas)) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_catalog\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.default__get_catalog\": {\"unique_id\": \"macro.dbt.default__get_catalog\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__get_catalog\", \"macro_sql\": \"{% macro default__get_catalog(information_schema, schemas) -%}\\n\\n  {% set typename = adapter.type() %}\\n  {% set msg -%}\\n    get_catalog not implemented for {{ typename }}\\n  {%- endset %}\\n\\n  {{ exceptions.raise_compiler_error(msg) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.get_columns_in_relation\": {\"unique_id\": \"macro.dbt.get_columns_in_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"get_columns_in_relation\", \"macro_sql\": \"{% macro get_columns_in_relation(relation) -%}\\n  {{ return(adapter.dispatch('get_columns_in_relation')(relation)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_columns_in_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.sql_convert_columns_in_relation\": {\"unique_id\": \"macro.dbt.sql_convert_columns_in_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"sql_convert_columns_in_relation\", \"macro_sql\": \"{% macro sql_convert_columns_in_relation(table) -%}\\n  {% set columns = [] %}\\n  {% for row in table %}\\n    {% do columns.append(api.Column(*row)) %}\\n  {% endfor %}\\n  {{ return(columns) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.default__get_columns_in_relation\": {\"unique_id\": \"macro.dbt.default__get_columns_in_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__get_columns_in_relation\", \"macro_sql\": \"{% macro default__get_columns_in_relation(relation) -%}\\n  {{ exceptions.raise_not_implemented(\\n    'get_columns_in_relation macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.alter_column_type\": {\"unique_id\": \"macro.dbt.alter_column_type\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"alter_column_type\", \"macro_sql\": \"{% macro alter_column_type(relation, column_name, new_column_type) -%}\\n  {{ return(adapter.dispatch('alter_column_type')(relation, column_name, new_column_type)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__alter_column_type\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.alter_column_comment\": {\"unique_id\": \"macro.dbt.alter_column_comment\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"alter_column_comment\", \"macro_sql\": \"{% macro alter_column_comment(relation, column_dict) -%}\\n  {{ return(adapter.dispatch('alter_column_comment')(relation, column_dict)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__alter_column_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.default__alter_column_comment\": {\"unique_id\": \"macro.dbt.default__alter_column_comment\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__alter_column_comment\", \"macro_sql\": \"{% macro default__alter_column_comment(relation, column_dict) -%}\\n  {{ exceptions.raise_not_implemented(\\n    'alter_column_comment macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.alter_relation_comment\": {\"unique_id\": \"macro.dbt.alter_relation_comment\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"alter_relation_comment\", \"macro_sql\": \"{% macro alter_relation_comment(relation, relation_comment) -%}\\n  {{ return(adapter.dispatch('alter_relation_comment')(relation, relation_comment)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__alter_relation_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.default__alter_relation_comment\": {\"unique_id\": \"macro.dbt.default__alter_relation_comment\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__alter_relation_comment\", \"macro_sql\": \"{% macro default__alter_relation_comment(relation, relation_comment) -%}\\n  {{ exceptions.raise_not_implemented(\\n    'alter_relation_comment macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.persist_docs\": {\"unique_id\": \"macro.dbt.persist_docs\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"persist_docs\", \"macro_sql\": \"{% macro persist_docs(relation, model, for_relation=true, for_columns=true) -%}\\n  {{ return(adapter.dispatch('persist_docs')(relation, model, for_relation, for_columns)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__persist_docs\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.default__persist_docs\": {\"unique_id\": \"macro.dbt.default__persist_docs\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__persist_docs\", \"macro_sql\": \"{% macro default__persist_docs(relation, model, for_relation, for_columns) -%}\\n  {% if for_relation and config.persist_relation_docs() and model.description %}\\n    {% do run_query(alter_relation_comment(relation, model.description)) %}\\n  {% endif %}\\n\\n  {% if for_columns and config.persist_column_docs() and model.columns %}\\n    {% do run_query(alter_column_comment(relation, model.columns)) %}\\n  {% endif %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.run_query\", \"macro.dbt.alter_relation_comment\", \"macro.dbt.alter_column_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.default__alter_column_type\": {\"unique_id\": \"macro.dbt.default__alter_column_type\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__alter_column_type\", \"macro_sql\": \"{% macro default__alter_column_type(relation, column_name, new_column_type) -%}\\n  {#\\n    1. Create a new column (w/ temp name and correct type)\\n    2. Copy data over to it\\n    3. Drop the existing column (cascade!)\\n    4. Rename the new column to existing column\\n  #}\\n  {%- set tmp_column = column_name + \\\"__dbt_alter\\\" -%}\\n\\n  {% call statement('alter_column_type') %}\\n    alter table {{ relation }} add column {{ adapter.quote(tmp_column) }} {{ new_column_type }};\\n    update {{ relation }} set {{ adapter.quote(tmp_column) }} = {{ adapter.quote(column_name) }};\\n    alter table {{ relation }} drop column {{ adapter.quote(column_name) }} cascade;\\n    alter table {{ relation }} rename column {{ adapter.quote(tmp_column) }} to {{ adapter.quote(column_name) }}\\n  {% endcall %}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.drop_relation\": {\"unique_id\": \"macro.dbt.drop_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"drop_relation\", \"macro_sql\": \"{% macro drop_relation(relation) -%}\\n  {{ return(adapter.dispatch('drop_relation')(relation)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__drop_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.default__drop_relation\": {\"unique_id\": \"macro.dbt.default__drop_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__drop_relation\", \"macro_sql\": \"{% macro default__drop_relation(relation) -%}\\n  {% call statement('drop_relation', auto_begin=False) -%}\\n    drop {{ relation.type }} if exists {{ relation }} cascade\\n  {%- endcall %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.truncate_relation\": {\"unique_id\": \"macro.dbt.truncate_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"truncate_relation\", \"macro_sql\": \"{% macro truncate_relation(relation) -%}\\n  {{ return(adapter.dispatch('truncate_relation')(relation)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__truncate_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.default__truncate_relation\": {\"unique_id\": \"macro.dbt.default__truncate_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__truncate_relation\", \"macro_sql\": \"{% macro default__truncate_relation(relation) -%}\\n  {% call statement('truncate_relation') -%}\\n    truncate table {{ relation }}\\n  {%- endcall %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.rename_relation\": {\"unique_id\": \"macro.dbt.rename_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"rename_relation\", \"macro_sql\": \"{% macro rename_relation(from_relation, to_relation) -%}\\n  {{ return(adapter.dispatch('rename_relation')(from_relation, to_relation)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__rename_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.default__rename_relation\": {\"unique_id\": \"macro.dbt.default__rename_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__rename_relation\", \"macro_sql\": \"{% macro default__rename_relation(from_relation, to_relation) -%}\\n  {% set target_name = adapter.quote_as_configured(to_relation.identifier, 'identifier') %}\\n  {% call statement('rename_relation') -%}\\n    alter table {{ from_relation }} rename to {{ target_name }}\\n  {%- endcall %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.information_schema_name\": {\"unique_id\": \"macro.dbt.information_schema_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"information_schema_name\", \"macro_sql\": \"{% macro information_schema_name(database) %}\\n  {{ return(adapter.dispatch('information_schema_name')(database)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__information_schema_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.default__information_schema_name\": {\"unique_id\": \"macro.dbt.default__information_schema_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__information_schema_name\", \"macro_sql\": \"{% macro default__information_schema_name(database) -%}\\n  {%- if database -%}\\n    {{ database }}.INFORMATION_SCHEMA\\n  {%- else -%}\\n    INFORMATION_SCHEMA\\n  {%- endif -%}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.list_schemas\": {\"unique_id\": \"macro.dbt.list_schemas\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"list_schemas\", \"macro_sql\": \"{% macro list_schemas(database) -%}\\n  {{ return(adapter.dispatch('list_schemas')(database)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__list_schemas\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.default__list_schemas\": {\"unique_id\": \"macro.dbt.default__list_schemas\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__list_schemas\", \"macro_sql\": \"{% macro default__list_schemas(database) -%}\\n  {% set sql %}\\n    select distinct schema_name\\n    from {{ information_schema_name(database) }}.SCHEMATA\\n    where catalog_name ilike '{{ database }}'\\n  {% endset %}\\n  {{ return(run_query(sql)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.information_schema_name\", \"macro.dbt.run_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.check_schema_exists\": {\"unique_id\": \"macro.dbt.check_schema_exists\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"check_schema_exists\", \"macro_sql\": \"{% macro check_schema_exists(information_schema, schema) -%}\\n  {{ return(adapter.dispatch('check_schema_exists')(information_schema, schema)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__check_schema_exists\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.default__check_schema_exists\": {\"unique_id\": \"macro.dbt.default__check_schema_exists\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__check_schema_exists\", \"macro_sql\": \"{% macro default__check_schema_exists(information_schema, schema) -%}\\n  {% set sql -%}\\n        select count(*)\\n        from {{ information_schema.replace(information_schema_view='SCHEMATA') }}\\n        where catalog_name='{{ information_schema.database }}'\\n          and schema_name='{{ schema }}'\\n  {%- endset %}\\n  {{ return(run_query(sql)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.run_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.list_relations_without_caching\": {\"unique_id\": \"macro.dbt.list_relations_without_caching\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"list_relations_without_caching\", \"macro_sql\": \"{% macro list_relations_without_caching(schema_relation) %}\\n  {{ return(adapter.dispatch('list_relations_without_caching')(schema_relation)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.test.postgres__list_relations_without_caching\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.default__list_relations_without_caching\": {\"unique_id\": \"macro.dbt.default__list_relations_without_caching\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__list_relations_without_caching\", \"macro_sql\": \"{% macro default__list_relations_without_caching(schema_relation) %}\\n  {{ exceptions.raise_not_implemented(\\n    'list_relations_without_caching macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.current_timestamp\": {\"unique_id\": \"macro.dbt.current_timestamp\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"current_timestamp\", \"macro_sql\": \"{% macro current_timestamp() -%}\\n  {{ adapter.dispatch('current_timestamp')() }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.default__current_timestamp\": {\"unique_id\": \"macro.dbt.default__current_timestamp\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__current_timestamp\", \"macro_sql\": \"{% macro default__current_timestamp() -%}\\n  {{ exceptions.raise_not_implemented(\\n    'current_timestamp macro not implemented for adapter '+adapter.type()) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.collect_freshness\": {\"unique_id\": \"macro.dbt.collect_freshness\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"collect_freshness\", \"macro_sql\": \"{% macro collect_freshness(source, loaded_at_field, filter) %}\\n  {{ return(adapter.dispatch('collect_freshness')(source, loaded_at_field, filter))}}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__collect_freshness\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.default__collect_freshness\": {\"unique_id\": \"macro.dbt.default__collect_freshness\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__collect_freshness\", \"macro_sql\": \"{% macro default__collect_freshness(source, loaded_at_field, filter) %}\\n  {% call statement('collect_freshness', fetch_result=True, auto_begin=False) -%}\\n    select\\n      max({{ loaded_at_field }}) as max_loaded_at,\\n      {{ current_timestamp() }} as snapshotted_at\\n    from {{ source }}\\n    {% if filter %}\\n    where {{ filter }}\\n    {% endif %}\\n  {% endcall %}\\n  {{ return(load_result('collect_freshness').table) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\", \"macro.dbt.current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.make_temp_relation\": {\"unique_id\": \"macro.dbt.make_temp_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"make_temp_relation\", \"macro_sql\": \"{% macro make_temp_relation(base_relation, suffix='__dbt_tmp') %}\\n  {{ return(adapter.dispatch('make_temp_relation')(base_relation, suffix))}}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_temp_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.default__make_temp_relation\": {\"unique_id\": \"macro.dbt.default__make_temp_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__make_temp_relation\", \"macro_sql\": \"{% macro default__make_temp_relation(base_relation, suffix) %}\\n    {% set tmp_identifier = base_relation.identifier ~ suffix %}\\n    {% set tmp_relation = base_relation.incorporate(\\n                                path={\\\"identifier\\\": tmp_identifier}) -%}\\n\\n    {% do return(tmp_relation) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.set_sql_header\": {\"unique_id\": \"macro.dbt.set_sql_header\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"set_sql_header\", \"macro_sql\": \"{% macro set_sql_header(config) -%}\\n  {{ config.set('sql_header', caller()) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.default__test_relationships\": {\"unique_id\": \"macro.dbt.default__test_relationships\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/schema_tests/relationships.sql\", \"original_file_path\": \"macros/schema_tests/relationships.sql\", \"name\": \"default__test_relationships\", \"macro_sql\": \"{% macro default__test_relationships(model, column_name, to, field) %}\\n\\nwith child as (\\n    select {{ column_name }} as from_field\\n    from {{ model }}\\n    where {{ column_name }} is not null\\n),\\n\\nparent as (\\n    select {{ field }} as to_field\\n    from {{ to }}\\n)\\n\\nselect\\n    from_field\\n\\nfrom child\\nleft join parent\\n    on child.from_field = parent.to_field\\n\\nwhere parent.to_field is null\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.test_relationships\": {\"unique_id\": \"macro.dbt.test_relationships\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/schema_tests/relationships.sql\", \"original_file_path\": \"macros/schema_tests/relationships.sql\", \"name\": \"test_relationships\", \"macro_sql\": \"{% test relationships(model, column_name, to, field) %}\\n    {% set macro = adapter.dispatch('test_relationships') %}\\n    {{ macro(model, column_name, to, field) }}\\n{% endtest %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__test_relationships\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.default__test_not_null\": {\"unique_id\": \"macro.dbt.default__test_not_null\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/schema_tests/not_null.sql\", \"original_file_path\": \"macros/schema_tests/not_null.sql\", \"name\": \"default__test_not_null\", \"macro_sql\": \"{% macro default__test_not_null(model, column_name) %}\\n\\nselect *\\nfrom {{ model }}\\nwhere {{ column_name }} is null\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.test_not_null\": {\"unique_id\": \"macro.dbt.test_not_null\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/schema_tests/not_null.sql\", \"original_file_path\": \"macros/schema_tests/not_null.sql\", \"name\": \"test_not_null\", \"macro_sql\": \"{% test not_null(model, column_name) %}\\n    {% set macro = adapter.dispatch('test_not_null') %}\\n    {{ macro(model, column_name) }}\\n{% endtest %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__test_not_null\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.default__test_unique\": {\"unique_id\": \"macro.dbt.default__test_unique\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/schema_tests/unique.sql\", \"original_file_path\": \"macros/schema_tests/unique.sql\", \"name\": \"default__test_unique\", \"macro_sql\": \"{% macro default__test_unique(model, column_name) %}\\n\\nselect\\n    {{ column_name }} as unique_field,\\n    count(*) as n_records\\n\\nfrom {{ model }}\\nwhere {{ column_name }} is not null\\ngroup by {{ column_name }}\\nhaving count(*) > 1\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.test_unique\": {\"unique_id\": \"macro.dbt.test_unique\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/schema_tests/unique.sql\", \"original_file_path\": \"macros/schema_tests/unique.sql\", \"name\": \"test_unique\", \"macro_sql\": \"{% test unique(model, column_name) %}\\n    {% set macro = adapter.dispatch('test_unique') %}\\n    {{ macro(model, column_name) }}\\n{% endtest %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__test_unique\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.default__test_accepted_values\": {\"unique_id\": \"macro.dbt.default__test_accepted_values\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/schema_tests/accepted_values.sql\", \"original_file_path\": \"macros/schema_tests/accepted_values.sql\", \"name\": \"default__test_accepted_values\", \"macro_sql\": \"{% macro default__test_accepted_values(model, column_name, values, quote=True) %}\\n\\nwith all_values as (\\n\\n    select\\n        {{ column_name }} as value_field,\\n        count(*) as n_records\\n\\n    from {{ model }}\\n    group by 1\\n\\n)\\n\\nselect *\\nfrom all_values\\nwhere value_field not in (\\n    {% for value in values -%}\\n        {% if quote -%}\\n        '{{ value }}'\\n        {%- else -%}\\n        {{ value }}\\n        {%- endif -%}\\n        {%- if not loop.last -%},{%- endif %}\\n    {%- endfor %}\\n)\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}, \"macro.dbt.test_accepted_values\": {\"unique_id\": \"macro.dbt.test_accepted_values\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/schema_tests/accepted_values.sql\", \"original_file_path\": \"macros/schema_tests/accepted_values.sql\", \"name\": \"test_accepted_values\", \"macro_sql\": \"{% test accepted_values(model, column_name, values, quote=True) %}\\n    {% set macro = adapter.dispatch('test_accepted_values') %}\\n    {{ macro(model, column_name, values, quote) }}\\n{% endtest %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__test_accepted_values\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665164}}, \"docs\": {\"dbt.__overview__\": {\"unique_id\": \"dbt.__overview__\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"overview.md\", \"original_file_path\": \"docs/overview.md\", \"name\": \"__overview__\", \"block_contents\": \"### Welcome!\\n\\nWelcome to the auto-generated documentation for your dbt project!\\n\\n### Navigation\\n\\nYou can use the `Project` and `Database` navigation tabs on the left side of the window to explore the models\\nin your project.\\n\\n#### Project Tab\\nThe `Project` tab mirrors the directory structure of your dbt project. In this tab, you can see all of the\\nmodels defined in your dbt project, as well as models imported from dbt packages.\\n\\n#### Database Tab\\nThe `Database` tab also exposes your models, but in a format that looks more like a database explorer. This view\\nshows relations (tables and views) grouped into database schemas. Note that ephemeral models are _not_ shown\\nin this interface, as they do not exist in the database.\\n\\n### Graph Exploration\\nYou can click the blue icon on the bottom-right corner of the page to view the lineage graph of your models.\\n\\nOn model pages, you'll see the immediate parents and children of the model you're exploring. By clicking the `Expand`\\nbutton at the top-right of this lineage pane, you'll be able to see all of the models that are used to build,\\nor are built from, the model you're exploring.\\n\\nOnce expanded, you'll be able to use the `--models` and `--exclude` model selection syntax to filter the\\nmodels in the graph. For more information on model selection, check out the [dbt docs](https://docs.getdbt.com/docs/model-selection-syntax).\\n\\nNote that you can also right-click on models to interactively filter and explore the graph.\\n\\n---\\n\\n### More information\\n\\n- [What is dbt](https://docs.getdbt.com/docs/overview)?\\n- Read the [dbt viewpoint](https://docs.getdbt.com/docs/viewpoint)\\n- [Installation](https://docs.getdbt.com/docs/installation)\\n- Join the [chat](https://community.getdbt.com/) on Slack for live questions and support.\"}}, \"exposures\": {}, \"selectors\": {}, \"disabled\": [], \"parent_map\": {\"model.test.my_model\": []}, \"child_map\": {\"model.test.my_model\": []}}\n"
  },
  {
    "path": "tests/functional/artifacts/data/state/v3/manifest.json",
    "content": "{\"metadata\": {\"dbt_schema_version\": \"https://schemas.getdbt.com/dbt/manifest/v3.json\", \"dbt_version\": \"0.21.1\", \"generated_at\": \"2022-06-08T05:12:26.978818Z\", \"invocation_id\": \"a2594229-14b7-46fe-864f-37cabb5f5f65\", \"env\": {}, \"project_id\": \"098f6bcd4621d373cade4e832627b4f6\", \"user_id\": null, \"send_anonymous_usage_stats\": false, \"adapter_type\": \"postgres\"}, \"nodes\": {\"model.test.my_model\": {\"raw_sql\": \"select 1 as id\", \"resource_type\": \"model\", \"depends_on\": {\"macros\": [], \"nodes\": []}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"materialized\": \"view\", \"persist_docs\": {}, \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"on_schema_change\": \"ignore\", \"post-hook\": [], \"pre-hook\": []}, \"database\": \"jerco\", \"schema\": \"dbt_jcohen\", \"fqn\": [\"test\", \"my_model\"], \"unique_id\": \"model.test.my_model\", \"package_name\": \"test\", \"root_path\": \"/Users/jerco/dev/scratch/testy\", \"path\": \"my_model.sql\", \"original_file_path\": \"models/my_model.sql\", \"name\": \"my_model\", \"alias\": \"my_model\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"479636cb85ce8d3b0f8db5ff13cf338b61254ad98d905630eac61f963e719e9d\"}, \"tags\": [], \"refs\": [], \"sources\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"compiled_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {}, \"created_at\": 1654665147}}, \"sources\": {}, \"macros\": {\"macro.test.drop_relation\": {\"unique_id\": \"macro.test.drop_relation\", \"package_name\": \"test\", \"root_path\": \"/Users/jerco/dev/scratch/testy\", \"path\": \"macros/whatever.sql\", \"original_file_path\": \"macros/whatever.sql\", \"name\": \"drop_relation\", \"macro_sql\": \"{% macro drop_relation(relation) -%}\\n  {{ return(dbt_labs_materialized_views.drop_relation(relation)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.test.drop_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665146}, \"macro.test.postgres__list_relations_without_caching\": {\"unique_id\": \"macro.test.postgres__list_relations_without_caching\", \"package_name\": \"test\", \"root_path\": \"/Users/jerco/dev/scratch/testy\", \"path\": \"macros/whatever.sql\", \"original_file_path\": \"macros/whatever.sql\", \"name\": \"postgres__list_relations_without_caching\", \"macro_sql\": \"{% macro postgres__list_relations_without_caching(schema_relation) %}\\n  {{ return(dbt_labs_materialized_views.postgres__list_relations_without_caching(schema_relation)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.test.postgres__list_relations_without_caching\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665146}, \"macro.test.postgres_get_relations\": {\"unique_id\": \"macro.test.postgres_get_relations\", \"package_name\": \"test\", \"root_path\": \"/Users/jerco/dev/scratch/testy\", \"path\": \"macros/whatever.sql\", \"original_file_path\": \"macros/whatever.sql\", \"name\": \"postgres_get_relations\", \"macro_sql\": \"{% macro postgres_get_relations() %}\\n  {{ return(dbt_labs_materialized_views.postgres_get_relations()) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.test.postgres_get_relations\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665146}, \"macro.test.redshift__list_relations_without_caching\": {\"unique_id\": \"macro.test.redshift__list_relations_without_caching\", \"package_name\": \"test\", \"root_path\": \"/Users/jerco/dev/scratch/testy\", \"path\": \"macros/whatever.sql\", \"original_file_path\": \"macros/whatever.sql\", \"name\": \"redshift__list_relations_without_caching\", \"macro_sql\": \"{% macro redshift__list_relations_without_caching(schema_relation) %}\\n  {{ return(dbt_labs_materialized_views.redshift__list_relations_without_caching(schema_relation)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.test.redshift__list_relations_without_caching\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665146}, \"macro.test.load_relation\": {\"unique_id\": \"macro.test.load_relation\", \"package_name\": \"test\", \"root_path\": \"/Users/jerco/dev/scratch/testy\", \"path\": \"macros/whatever.sql\", \"original_file_path\": \"macros/whatever.sql\", \"name\": \"load_relation\", \"macro_sql\": \"{% macro load_relation(relation) %}\\n  {{ return(dbt_labs_materialized_views.redshift_load_relation_or_mv(relation)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665146}, \"macro.dbt_postgres.postgres__get_catalog\": {\"unique_id\": \"macro.dbt_postgres.postgres__get_catalog\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/catalog.sql\", \"original_file_path\": \"macros/catalog.sql\", \"name\": \"postgres__get_catalog\", \"macro_sql\": \"{% macro postgres__get_catalog(information_schema, schemas) -%}\\n\\n  {%- call statement('catalog', fetch_result=True) -%}\\n    {#\\n      If the user has multiple databases set and the first one is wrong, this will fail.\\n      But we won't fail in the case where there are multiple quoting-difference-only dbs, which is better.\\n    #}\\n    {% set database = information_schema.database %}\\n    {{ adapter.verify_database(database) }}\\n\\n    select\\n        '{{ database }}' as table_database,\\n        sch.nspname as table_schema,\\n        tbl.relname as table_name,\\n        case tbl.relkind\\n            when 'v' then 'VIEW'\\n            else 'BASE TABLE'\\n        end as table_type,\\n        tbl_desc.description as table_comment,\\n        col.attname as column_name,\\n        col.attnum as column_index,\\n        pg_catalog.format_type(col.atttypid, col.atttypmod) as column_type,\\n        col_desc.description as column_comment,\\n        pg_get_userbyid(tbl.relowner) as table_owner\\n\\n    from pg_catalog.pg_namespace sch\\n    join pg_catalog.pg_class tbl on tbl.relnamespace = sch.oid\\n    join pg_catalog.pg_attribute col on col.attrelid = tbl.oid\\n    left outer join pg_catalog.pg_description tbl_desc on (tbl_desc.objoid = tbl.oid and tbl_desc.objsubid = 0)\\n    left outer join pg_catalog.pg_description col_desc on (col_desc.objoid = tbl.oid and col_desc.objsubid = col.attnum)\\n\\n    where (\\n        {%- for schema in schemas -%}\\n          upper(sch.nspname) = upper('{{ schema }}'){%- if not loop.last %} or {% endif -%}\\n        {%- endfor -%}\\n      )\\n      and not pg_is_other_temp_schema(sch.oid) -- not a temporary schema belonging to another session\\n      and tbl.relpersistence = 'p' -- [p]ermanent table. Other values are [u]nlogged table, [t]emporary table\\n      and tbl.relkind in ('r', 'v', 'f', 'p') -- o[r]dinary table, [v]iew, [f]oreign table, [p]artitioned table. Other values are [i]ndex, [S]equence, [c]omposite type, [t]OAST table, [m]aterialized view\\n      and col.attnum > 0 -- negative numbers are used for system columns such as oid\\n      and not col.attisdropped -- column as not been dropped\\n\\n    order by\\n        sch.nspname,\\n        tbl.relname,\\n        col.attnum\\n\\n  {%- endcall -%}\\n\\n  {{ return(load_result('catalog').table) }}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665146}, \"macro.dbt_postgres.postgres_get_relations\": {\"unique_id\": \"macro.dbt_postgres.postgres_get_relations\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/relations.sql\", \"original_file_path\": \"macros/relations.sql\", \"name\": \"postgres_get_relations\", \"macro_sql\": \"{% macro postgres_get_relations () -%}\\n\\n  {#\\n      -- in pg_depend, objid is the dependent, refobjid is the referenced object\\n      --  > a pg_depend entry indicates that the referenced object cannot be\\n      --  > dropped without also dropping the dependent object.\\n  #}\\n\\n  {%- call statement('relations', fetch_result=True) -%}\\n    with relation as (\\n        select\\n            pg_rewrite.ev_class as class,\\n            pg_rewrite.oid as id\\n        from pg_rewrite\\n    ),\\n    class as (\\n        select\\n            oid as id,\\n            relname as name,\\n            relnamespace as schema,\\n            relkind as kind\\n        from pg_class\\n    ),\\n    dependency as (\\n        select\\n            pg_depend.objid as id,\\n            pg_depend.refobjid as ref\\n        from pg_depend\\n    ),\\n    schema as (\\n        select\\n            pg_namespace.oid as id,\\n            pg_namespace.nspname as name\\n        from pg_namespace\\n        where nspname != 'information_schema' and nspname not like 'pg\\\\_%'\\n    ),\\n    referenced as (\\n        select\\n            relation.id AS id,\\n            referenced_class.name ,\\n            referenced_class.schema ,\\n            referenced_class.kind\\n        from relation\\n        join class as referenced_class on relation.class=referenced_class.id\\n        where referenced_class.kind in ('r', 'v')\\n    ),\\n    relationships as (\\n        select\\n            referenced.name as referenced_name,\\n            referenced.schema as referenced_schema_id,\\n            dependent_class.name as dependent_name,\\n            dependent_class.schema as dependent_schema_id,\\n            referenced.kind as kind\\n        from referenced\\n        join dependency on referenced.id=dependency.id\\n        join class as dependent_class on dependency.ref=dependent_class.id\\n        where\\n            (referenced.name != dependent_class.name or\\n             referenced.schema != dependent_class.schema)\\n    )\\n\\n    select\\n        referenced_schema.name as referenced_schema,\\n        relationships.referenced_name as referenced_name,\\n        dependent_schema.name as dependent_schema,\\n        relationships.dependent_name as dependent_name\\n    from relationships\\n    join schema as dependent_schema on relationships.dependent_schema_id=dependent_schema.id\\n    join schema as referenced_schema on relationships.referenced_schema_id=referenced_schema.id\\n    group by referenced_schema, referenced_name, dependent_schema, dependent_name\\n    order by referenced_schema, referenced_name, dependent_schema, dependent_name;\\n\\n  {%- endcall -%}\\n\\n  {{ return(load_result('relations').table) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665146}, \"macro.dbt_postgres.postgres__create_table_as\": {\"unique_id\": \"macro.dbt_postgres.postgres__create_table_as\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__create_table_as\", \"macro_sql\": \"{% macro postgres__create_table_as(temporary, relation, sql) -%}\\n  {%- set unlogged = config.get('unlogged', default=false) -%}\\n  {%- set sql_header = config.get('sql_header', none) -%}\\n\\n  {{ sql_header if sql_header is not none }}\\n\\n  create {% if temporary -%}\\n    temporary\\n  {%- elif unlogged -%}\\n    unlogged\\n  {%- endif %} table {{ relation }}\\n  as (\\n    {{ sql }}\\n  );\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt_postgres.postgres__get_create_index_sql\": {\"unique_id\": \"macro.dbt_postgres.postgres__get_create_index_sql\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__get_create_index_sql\", \"macro_sql\": \"{% macro postgres__get_create_index_sql(relation, index_dict) -%}\\n  {%- set index_config = adapter.parse_index(index_dict) -%}\\n  {%- set comma_separated_columns = \\\", \\\".join(index_config.columns) -%}\\n  {%- set index_name = index_config.render(relation) -%}\\n\\n  create {% if index_config.unique -%}\\n    unique\\n  {%- endif %} index if not exists\\n  \\\"{{ index_name }}\\\"\\n  on {{ relation }} {% if index_config.type -%}\\n    using {{ index_config.type }}\\n  {%- endif %}\\n  ({{ comma_separated_columns }});\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt_postgres.postgres__create_schema\": {\"unique_id\": \"macro.dbt_postgres.postgres__create_schema\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__create_schema\", \"macro_sql\": \"{% macro postgres__create_schema(relation) -%}\\n  {% if relation.database -%}\\n    {{ adapter.verify_database(relation.database) }}\\n  {%- endif -%}\\n  {%- call statement('create_schema') -%}\\n    create schema if not exists {{ relation.without_identifier().include(database=False) }}\\n  {%- endcall -%}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt_postgres.postgres__drop_schema\": {\"unique_id\": \"macro.dbt_postgres.postgres__drop_schema\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__drop_schema\", \"macro_sql\": \"{% macro postgres__drop_schema(relation) -%}\\n  {% if relation.database -%}\\n    {{ adapter.verify_database(relation.database) }}\\n  {%- endif -%}\\n  {%- call statement('drop_schema') -%}\\n    drop schema if exists {{ relation.without_identifier().include(database=False) }} cascade\\n  {%- endcall -%}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt_postgres.postgres__get_columns_in_relation\": {\"unique_id\": \"macro.dbt_postgres.postgres__get_columns_in_relation\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__get_columns_in_relation\", \"macro_sql\": \"{% macro postgres__get_columns_in_relation(relation) -%}\\n  {% call statement('get_columns_in_relation', fetch_result=True) %}\\n      select\\n          column_name,\\n          data_type,\\n          character_maximum_length,\\n          numeric_precision,\\n          numeric_scale\\n\\n      from {{ relation.information_schema('columns') }}\\n      where table_name = '{{ relation.identifier }}'\\n        {% if relation.schema %}\\n        and table_schema = '{{ relation.schema }}'\\n        {% endif %}\\n      order by ordinal_position\\n\\n  {% endcall %}\\n  {% set table = load_result('get_columns_in_relation').table %}\\n  {{ return(sql_convert_columns_in_relation(table)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\", \"macro.dbt.sql_convert_columns_in_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt_postgres.postgres__list_relations_without_caching\": {\"unique_id\": \"macro.dbt_postgres.postgres__list_relations_without_caching\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__list_relations_without_caching\", \"macro_sql\": \"{% macro postgres__list_relations_without_caching(schema_relation) %}\\n  {% call statement('list_relations_without_caching', fetch_result=True) -%}\\n    select\\n      '{{ schema_relation.database }}' as database,\\n      tablename as name,\\n      schemaname as schema,\\n      'table' as type\\n    from pg_tables\\n    where schemaname ilike '{{ schema_relation.schema }}'\\n    union all\\n    select\\n      '{{ schema_relation.database }}' as database,\\n      viewname as name,\\n      schemaname as schema,\\n      'view' as type\\n    from pg_views\\n    where schemaname ilike '{{ schema_relation.schema }}'\\n  {% endcall %}\\n  {{ return(load_result('list_relations_without_caching').table) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt_postgres.postgres__information_schema_name\": {\"unique_id\": \"macro.dbt_postgres.postgres__information_schema_name\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__information_schema_name\", \"macro_sql\": \"{% macro postgres__information_schema_name(database) -%}\\n  {% if database_name -%}\\n    {{ adapter.verify_database(database_name) }}\\n  {%- endif -%}\\n  information_schema\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt_postgres.postgres__list_schemas\": {\"unique_id\": \"macro.dbt_postgres.postgres__list_schemas\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__list_schemas\", \"macro_sql\": \"{% macro postgres__list_schemas(database) %}\\n  {% if database -%}\\n    {{ adapter.verify_database(database) }}\\n  {%- endif -%}\\n  {% call statement('list_schemas', fetch_result=True, auto_begin=False) %}\\n    select distinct nspname from pg_namespace\\n  {% endcall %}\\n  {{ return(load_result('list_schemas').table) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt_postgres.postgres__check_schema_exists\": {\"unique_id\": \"macro.dbt_postgres.postgres__check_schema_exists\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__check_schema_exists\", \"macro_sql\": \"{% macro postgres__check_schema_exists(information_schema, schema) -%}\\n  {% if information_schema.database -%}\\n    {{ adapter.verify_database(information_schema.database) }}\\n  {%- endif -%}\\n  {% call statement('check_schema_exists', fetch_result=True, auto_begin=False) %}\\n    select count(*) from pg_namespace where nspname = '{{ schema }}'\\n  {% endcall %}\\n  {{ return(load_result('check_schema_exists').table) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt_postgres.postgres__current_timestamp\": {\"unique_id\": \"macro.dbt_postgres.postgres__current_timestamp\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__current_timestamp\", \"macro_sql\": \"{% macro postgres__current_timestamp() -%}\\n  now()\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt_postgres.postgres__snapshot_string_as_time\": {\"unique_id\": \"macro.dbt_postgres.postgres__snapshot_string_as_time\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__snapshot_string_as_time\", \"macro_sql\": \"{% macro postgres__snapshot_string_as_time(timestamp) -%}\\n    {%- set result = \\\"'\\\" ~ timestamp ~ \\\"'::timestamp without time zone\\\" -%}\\n    {{ return(result) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt_postgres.postgres__snapshot_get_time\": {\"unique_id\": \"macro.dbt_postgres.postgres__snapshot_get_time\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__snapshot_get_time\", \"macro_sql\": \"{% macro postgres__snapshot_get_time() -%}\\n  {{ current_timestamp() }}::timestamp without time zone\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt_postgres.postgres__make_temp_relation\": {\"unique_id\": \"macro.dbt_postgres.postgres__make_temp_relation\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__make_temp_relation\", \"macro_sql\": \"{% macro postgres__make_temp_relation(base_relation, suffix) %}\\n    {% set dt = modules.datetime.datetime.now() %}\\n    {% set dtstring = dt.strftime(\\\"%H%M%S%f\\\") %}\\n    {% set suffix_length = suffix|length + dtstring|length %}\\n    {% set relation_max_name_length = 63 %}\\n    {% if suffix_length > relation_max_name_length %}\\n        {% do exceptions.raise_compiler_error('Temp relation suffix is too long (' ~ suffix|length ~ ' characters). Maximum length is ' ~ (relation_max_name_length - dtstring|length) ~ ' characters.') %}\\n    {% endif %}\\n    {% set tmp_identifier = base_relation.identifier[:relation_max_name_length - suffix_length] ~ suffix ~ dtstring %}\\n    {% do return(base_relation.incorporate(\\n                                  path={\\n                                    \\\"identifier\\\": tmp_identifier,\\n                                    \\\"schema\\\": none,\\n                                    \\\"database\\\": none\\n                                  })) -%}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt_postgres.postgres_escape_comment\": {\"unique_id\": \"macro.dbt_postgres.postgres_escape_comment\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres_escape_comment\", \"macro_sql\": \"{% macro postgres_escape_comment(comment) -%}\\n  {% if comment is not string %}\\n    {% do exceptions.raise_compiler_error('cannot escape a non-string: ' ~ comment) %}\\n  {% endif %}\\n  {%- set magic = '$dbt_comment_literal_block$' -%}\\n  {%- if magic in comment -%}\\n    {%- do exceptions.raise_compiler_error('The string ' ~ magic ~ ' is not allowed in comments.') -%}\\n  {%- endif -%}\\n  {{ magic }}{{ comment }}{{ magic }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt_postgres.postgres__alter_relation_comment\": {\"unique_id\": \"macro.dbt_postgres.postgres__alter_relation_comment\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__alter_relation_comment\", \"macro_sql\": \"{% macro postgres__alter_relation_comment(relation, comment) %}\\n  {% set escaped_comment = postgres_escape_comment(comment) %}\\n  comment on {{ relation.type }} {{ relation }} is {{ escaped_comment }};\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres_escape_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt_postgres.postgres__alter_column_comment\": {\"unique_id\": \"macro.dbt_postgres.postgres__alter_column_comment\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__alter_column_comment\", \"macro_sql\": \"{% macro postgres__alter_column_comment(relation, column_dict) %}\\n  {% for column_name in column_dict %}\\n    {% set comment = column_dict[column_name]['description'] %}\\n    {% set escaped_comment = postgres_escape_comment(comment) %}\\n    comment on column {{ relation }}.{{ adapter.quote(column_name) if column_dict[column_name]['quote'] else column_name }} is {{ escaped_comment }};\\n  {% endfor %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres_escape_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt_postgres.postgres__snapshot_merge_sql\": {\"unique_id\": \"macro.dbt_postgres.postgres__snapshot_merge_sql\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/materializations/snapshot_merge.sql\", \"original_file_path\": \"macros/materializations/snapshot_merge.sql\", \"name\": \"postgres__snapshot_merge_sql\", \"macro_sql\": \"{% macro postgres__snapshot_merge_sql(target, source, insert_cols) -%}\\n    {%- set insert_cols_csv = insert_cols | join(', ') -%}\\n\\n    update {{ target }}\\n    set dbt_valid_to = DBT_INTERNAL_SOURCE.dbt_valid_to\\n    from {{ source }} as DBT_INTERNAL_SOURCE\\n    where DBT_INTERNAL_SOURCE.dbt_scd_id::text = {{ target }}.dbt_scd_id::text\\n      and DBT_INTERNAL_SOURCE.dbt_change_type::text in ('update'::text, 'delete'::text)\\n      and {{ target }}.dbt_valid_to is null;\\n\\n    insert into {{ target }} ({{ insert_cols_csv }})\\n    select {% for column in insert_cols -%}\\n        DBT_INTERNAL_SOURCE.{{ column }} {%- if not loop.last %}, {%- endif %}\\n    {%- endfor %}\\n    from {{ source }} as DBT_INTERNAL_SOURCE\\n    where DBT_INTERNAL_SOURCE.dbt_change_type::text = 'insert'::text;\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.statement\": {\"unique_id\": \"macro.dbt.statement\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/core.sql\", \"original_file_path\": \"macros/core.sql\", \"name\": \"statement\", \"macro_sql\": \"{% macro statement(name=None, fetch_result=False, auto_begin=True) -%}\\n  {%- if execute: -%}\\n    {%- set sql = caller() -%}\\n\\n    {%- if name == 'main' -%}\\n      {{ log('Writing runtime SQL for node \\\"{}\\\"'.format(model['unique_id'])) }}\\n      {{ write(sql) }}\\n    {%- endif -%}\\n\\n    {%- set res, table = adapter.execute(sql, auto_begin=auto_begin, fetch=fetch_result) -%}\\n    {%- if name is not none -%}\\n      {{ store_result(name, response=res, agate_table=table) }}\\n    {%- endif -%}\\n\\n  {%- endif -%}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.noop_statement\": {\"unique_id\": \"macro.dbt.noop_statement\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/core.sql\", \"original_file_path\": \"macros/core.sql\", \"name\": \"noop_statement\", \"macro_sql\": \"{% macro noop_statement(name=None, message=None, code=None, rows_affected=None, res=None) -%}\\n  {%- set sql = caller() -%}\\n\\n  {%- if name == 'main' -%}\\n    {{ log('Writing runtime SQL for node \\\"{}\\\"'.format(model['unique_id'])) }}\\n    {{ write(sql) }}\\n  {%- endif -%}\\n\\n  {%- if name is not none -%}\\n    {{ store_raw_result(name, message=message, code=code, rows_affected=rows_affected, agate_table=res) }}\\n  {%- endif -%}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.get_test_sql\": {\"unique_id\": \"macro.dbt.get_test_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/test.sql\", \"original_file_path\": \"macros/materializations/test.sql\", \"name\": \"get_test_sql\", \"macro_sql\": \"{% macro get_test_sql(main_sql, fail_calc, warn_if, error_if, limit) -%}\\n  {{ adapter.dispatch('get_test_sql', 'dbt')(main_sql, fail_calc, warn_if, error_if, limit) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_test_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__get_test_sql\": {\"unique_id\": \"macro.dbt.default__get_test_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/test.sql\", \"original_file_path\": \"macros/materializations/test.sql\", \"name\": \"default__get_test_sql\", \"macro_sql\": \"{% macro default__get_test_sql(main_sql, fail_calc, warn_if, error_if, limit) -%}\\n    select\\n      {{ fail_calc }} as failures,\\n      {{ fail_calc }} {{ warn_if }} as should_warn,\\n      {{ fail_calc }} {{ error_if }} as should_error\\n    from (\\n      {{ main_sql }}\\n      {{ \\\"limit \\\" ~ limit if limit != none }}\\n    ) dbt_internal_test\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.materialization_test_default\": {\"unique_id\": \"macro.dbt.materialization_test_default\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/test.sql\", \"original_file_path\": \"macros/materializations/test.sql\", \"name\": \"materialization_test_default\", \"macro_sql\": \"\\n\\n{%- materialization test, default -%}\\n\\n  {% set relations = [] %}\\n\\n  {% if should_store_failures() %}\\n\\n    {% set identifier = model['alias'] %}\\n    {% set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) %}\\n    {% set target_relation = api.Relation.create(\\n        identifier=identifier, schema=schema, database=database, type='table') -%} %}\\n    \\n    {% if old_relation %}\\n        {% do adapter.drop_relation(old_relation) %}\\n    {% endif %}\\n    \\n    {% call statement(auto_begin=True) %}\\n        {{ create_table_as(False, target_relation, sql) }}\\n    {% endcall %}\\n    \\n    {% do relations.append(target_relation) %}\\n  \\n    {% set main_sql %}\\n        select *\\n        from {{ target_relation }}\\n    {% endset %}\\n    \\n    {{ adapter.commit() }}\\n  \\n  {% else %}\\n\\n      {% set main_sql = sql %}\\n  \\n  {% endif %}\\n\\n  {% set limit = config.get('limit') %}\\n  {% set fail_calc = config.get('fail_calc') %}\\n  {% set warn_if = config.get('warn_if') %}\\n  {% set error_if = config.get('error_if') %}\\n\\n  {% call statement('main', fetch_result=True) -%}\\n\\n    {{ get_test_sql(main_sql, fail_calc, warn_if, error_if, limit)}}\\n\\n  {%- endcall %}\\n  \\n  {{ return({'relations': relations}) }}\\n\\n{%- endmaterialization -%}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.should_store_failures\", \"macro.dbt.statement\", \"macro.dbt.create_table_as\", \"macro.dbt.get_test_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.run_hooks\": {\"unique_id\": \"macro.dbt.run_hooks\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/helpers.sql\", \"original_file_path\": \"macros/materializations/helpers.sql\", \"name\": \"run_hooks\", \"macro_sql\": \"{% macro run_hooks(hooks, inside_transaction=True) %}\\n  {% for hook in hooks | selectattr('transaction', 'equalto', inside_transaction)  %}\\n    {% if not inside_transaction and loop.first %}\\n      {% call statement(auto_begin=inside_transaction) %}\\n        commit;\\n      {% endcall %}\\n    {% endif %}\\n    {% set rendered = render(hook.get('sql')) | trim %}\\n    {% if (rendered | length) > 0 %}\\n      {% call statement(auto_begin=inside_transaction) %}\\n        {{ rendered }}\\n      {% endcall %}\\n    {% endif %}\\n  {% endfor %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.column_list\": {\"unique_id\": \"macro.dbt.column_list\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/helpers.sql\", \"original_file_path\": \"macros/materializations/helpers.sql\", \"name\": \"column_list\", \"macro_sql\": \"{% macro column_list(columns) %}\\n  {%- for col in columns %}\\n    {{ col.name }} {% if not loop.last %},{% endif %}\\n  {% endfor -%}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.column_list_for_create_table\": {\"unique_id\": \"macro.dbt.column_list_for_create_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/helpers.sql\", \"original_file_path\": \"macros/materializations/helpers.sql\", \"name\": \"column_list_for_create_table\", \"macro_sql\": \"{% macro column_list_for_create_table(columns) %}\\n  {%- for col in columns %}\\n    {{ col.name }} {{ col.data_type }} {%- if not loop.last %},{% endif %}\\n  {% endfor -%}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.make_hook_config\": {\"unique_id\": \"macro.dbt.make_hook_config\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/helpers.sql\", \"original_file_path\": \"macros/materializations/helpers.sql\", \"name\": \"make_hook_config\", \"macro_sql\": \"{% macro make_hook_config(sql, inside_transaction) %}\\n    {{ tojson({\\\"sql\\\": sql, \\\"transaction\\\": inside_transaction}) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.before_begin\": {\"unique_id\": \"macro.dbt.before_begin\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/helpers.sql\", \"original_file_path\": \"macros/materializations/helpers.sql\", \"name\": \"before_begin\", \"macro_sql\": \"{% macro before_begin(sql) %}\\n    {{ make_hook_config(sql, inside_transaction=False) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.make_hook_config\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.in_transaction\": {\"unique_id\": \"macro.dbt.in_transaction\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/helpers.sql\", \"original_file_path\": \"macros/materializations/helpers.sql\", \"name\": \"in_transaction\", \"macro_sql\": \"{% macro in_transaction(sql) %}\\n    {{ make_hook_config(sql, inside_transaction=True) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.make_hook_config\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.after_commit\": {\"unique_id\": \"macro.dbt.after_commit\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/helpers.sql\", \"original_file_path\": \"macros/materializations/helpers.sql\", \"name\": \"after_commit\", \"macro_sql\": \"{% macro after_commit(sql) %}\\n    {{ make_hook_config(sql, inside_transaction=False) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.make_hook_config\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.drop_relation_if_exists\": {\"unique_id\": \"macro.dbt.drop_relation_if_exists\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/helpers.sql\", \"original_file_path\": \"macros/materializations/helpers.sql\", \"name\": \"drop_relation_if_exists\", \"macro_sql\": \"{% macro drop_relation_if_exists(relation) %}\\n  {% if relation is not none %}\\n    {{ adapter.drop_relation(relation) }}\\n  {% endif %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.load_relation\": {\"unique_id\": \"macro.dbt.load_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/helpers.sql\", \"original_file_path\": \"macros/materializations/helpers.sql\", \"name\": \"load_relation\", \"macro_sql\": \"{% macro load_relation(relation) %}\\n  {% do return(adapter.get_relation(\\n    database=relation.database,\\n    schema=relation.schema,\\n    identifier=relation.identifier\\n  )) -%}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.should_full_refresh\": {\"unique_id\": \"macro.dbt.should_full_refresh\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/helpers.sql\", \"original_file_path\": \"macros/materializations/helpers.sql\", \"name\": \"should_full_refresh\", \"macro_sql\": \"{% macro should_full_refresh() %}\\n  {% set config_full_refresh = config.get('full_refresh') %}\\n  {% if config_full_refresh is none %}\\n    {% set config_full_refresh = flags.FULL_REFRESH %}\\n  {% endif %}\\n  {% do return(config_full_refresh) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.should_store_failures\": {\"unique_id\": \"macro.dbt.should_store_failures\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/helpers.sql\", \"original_file_path\": \"macros/materializations/helpers.sql\", \"name\": \"should_store_failures\", \"macro_sql\": \"{% macro should_store_failures() %}\\n  {% set config_store_failures = config.get('store_failures') %}\\n  {% if config_store_failures is none %}\\n    {% set config_store_failures = flags.STORE_FAILURES %}\\n  {% endif %}\\n  {% do return(config_store_failures) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.snapshot_merge_sql\": {\"unique_id\": \"macro.dbt.snapshot_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshot/snapshot_merge.sql\", \"original_file_path\": \"macros/materializations/snapshot/snapshot_merge.sql\", \"name\": \"snapshot_merge_sql\", \"macro_sql\": \"{% macro snapshot_merge_sql(target, source, insert_cols) -%}\\n  {{ adapter.dispatch('snapshot_merge_sql', 'dbt')(target, source, insert_cols) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__snapshot_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__snapshot_merge_sql\": {\"unique_id\": \"macro.dbt.default__snapshot_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshot/snapshot_merge.sql\", \"original_file_path\": \"macros/materializations/snapshot/snapshot_merge.sql\", \"name\": \"default__snapshot_merge_sql\", \"macro_sql\": \"{% macro default__snapshot_merge_sql(target, source, insert_cols) -%}\\n    {%- set insert_cols_csv = insert_cols | join(', ') -%}\\n\\n    merge into {{ target }} as DBT_INTERNAL_DEST\\n    using {{ source }} as DBT_INTERNAL_SOURCE\\n    on DBT_INTERNAL_SOURCE.dbt_scd_id = DBT_INTERNAL_DEST.dbt_scd_id\\n\\n    when matched\\n     and DBT_INTERNAL_DEST.dbt_valid_to is null\\n     and DBT_INTERNAL_SOURCE.dbt_change_type in ('update', 'delete')\\n        then update\\n        set dbt_valid_to = DBT_INTERNAL_SOURCE.dbt_valid_to\\n\\n    when not matched\\n     and DBT_INTERNAL_SOURCE.dbt_change_type = 'insert'\\n        then insert ({{ insert_cols_csv }})\\n        values ({{ insert_cols_csv }})\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.strategy_dispatch\": {\"unique_id\": \"macro.dbt.strategy_dispatch\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshot/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshot/strategies.sql\", \"name\": \"strategy_dispatch\", \"macro_sql\": \"{% macro strategy_dispatch(name) -%}\\n{% set original_name = name %}\\n  {% if '.' in name %}\\n    {% set package_name, name = name.split(\\\".\\\", 1) %}\\n  {% else %}\\n    {% set package_name = none %}\\n  {% endif %}\\n\\n  {% if package_name is none %}\\n    {% set package_context = context %}\\n  {% elif package_name in context %}\\n    {% set package_context = context[package_name] %}\\n  {% else %}\\n    {% set error_msg %}\\n        Could not find package '{{package_name}}', called with '{{original_name}}'\\n    {% endset %}\\n    {{ exceptions.raise_compiler_error(error_msg | trim) }}\\n  {% endif %}\\n\\n  {%- set search_name = 'snapshot_' ~ name ~ '_strategy' -%}\\n\\n  {% if search_name not in package_context %}\\n    {% set error_msg %}\\n        The specified strategy macro '{{name}}' was not found in package '{{ package_name }}'\\n    {% endset %}\\n    {{ exceptions.raise_compiler_error(error_msg | trim) }}\\n  {% endif %}\\n  {{ return(package_context[search_name]) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.snapshot_hash_arguments\": {\"unique_id\": \"macro.dbt.snapshot_hash_arguments\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshot/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshot/strategies.sql\", \"name\": \"snapshot_hash_arguments\", \"macro_sql\": \"{% macro snapshot_hash_arguments(args) -%}\\n  {{ adapter.dispatch('snapshot_hash_arguments', 'dbt')(args) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__snapshot_hash_arguments\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__snapshot_hash_arguments\": {\"unique_id\": \"macro.dbt.default__snapshot_hash_arguments\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshot/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshot/strategies.sql\", \"name\": \"default__snapshot_hash_arguments\", \"macro_sql\": \"{% macro default__snapshot_hash_arguments(args) -%}\\n    md5({%- for arg in args -%}\\n        coalesce(cast({{ arg }} as varchar ), '')\\n        {% if not loop.last %} || '|' || {% endif %}\\n    {%- endfor -%})\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.snapshot_get_time\": {\"unique_id\": \"macro.dbt.snapshot_get_time\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshot/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshot/strategies.sql\", \"name\": \"snapshot_get_time\", \"macro_sql\": \"{% macro snapshot_get_time() -%}\\n  {{ adapter.dispatch('snapshot_get_time', 'dbt')() }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__snapshot_get_time\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__snapshot_get_time\": {\"unique_id\": \"macro.dbt.default__snapshot_get_time\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshot/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshot/strategies.sql\", \"name\": \"default__snapshot_get_time\", \"macro_sql\": \"{% macro default__snapshot_get_time() -%}\\n  {{ current_timestamp() }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.snapshot_timestamp_strategy\": {\"unique_id\": \"macro.dbt.snapshot_timestamp_strategy\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshot/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshot/strategies.sql\", \"name\": \"snapshot_timestamp_strategy\", \"macro_sql\": \"{% macro snapshot_timestamp_strategy(node, snapshotted_rel, current_rel, config, target_exists) %}\\n    {% set primary_key = config['unique_key'] %}\\n    {% set updated_at = config['updated_at'] %}\\n    {% set invalidate_hard_deletes = config.get('invalidate_hard_deletes', false) %}\\n\\n    {#/*\\n        The snapshot relation might not have an {{ updated_at }} value if the\\n        snapshot strategy is changed from `check` to `timestamp`. We\\n        should use a dbt-created column for the comparison in the snapshot\\n        table instead of assuming that the user-supplied {{ updated_at }}\\n        will be present in the historical data.\\n\\n        See https://github.com/dbt-labs/dbt/issues/2350\\n    */ #}\\n    {% set row_changed_expr -%}\\n        ({{ snapshotted_rel }}.dbt_valid_from < {{ current_rel }}.{{ updated_at }})\\n    {%- endset %}\\n\\n    {% set scd_id_expr = snapshot_hash_arguments([primary_key, updated_at]) %}\\n\\n    {% do return({\\n        \\\"unique_key\\\": primary_key,\\n        \\\"updated_at\\\": updated_at,\\n        \\\"row_changed\\\": row_changed_expr,\\n        \\\"scd_id\\\": scd_id_expr,\\n        \\\"invalidate_hard_deletes\\\": invalidate_hard_deletes\\n    }) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.snapshot_hash_arguments\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.snapshot_string_as_time\": {\"unique_id\": \"macro.dbt.snapshot_string_as_time\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshot/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshot/strategies.sql\", \"name\": \"snapshot_string_as_time\", \"macro_sql\": \"{% macro snapshot_string_as_time(timestamp) -%}\\n    {{ adapter.dispatch('snapshot_string_as_time', 'dbt')(timestamp) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__snapshot_string_as_time\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__snapshot_string_as_time\": {\"unique_id\": \"macro.dbt.default__snapshot_string_as_time\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshot/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshot/strategies.sql\", \"name\": \"default__snapshot_string_as_time\", \"macro_sql\": \"{% macro default__snapshot_string_as_time(timestamp) %}\\n    {% do exceptions.raise_not_implemented(\\n        'snapshot_string_as_time macro not implemented for adapter '+adapter.type()\\n    ) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.snapshot_check_all_get_existing_columns\": {\"unique_id\": \"macro.dbt.snapshot_check_all_get_existing_columns\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshot/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshot/strategies.sql\", \"name\": \"snapshot_check_all_get_existing_columns\", \"macro_sql\": \"{% macro snapshot_check_all_get_existing_columns(node, target_exists) -%}\\n    {%- set query_columns = get_columns_in_query(node['compiled_sql']) -%}\\n    {%- if not target_exists -%}\\n        {# no table yet -> return whatever the query does #}\\n        {{ return([false, query_columns]) }}\\n    {%- endif -%}\\n    {# handle any schema changes #}\\n    {%- set target_table = node.get('alias', node.get('name')) -%}\\n    {%- set target_relation = adapter.get_relation(database=node.database, schema=node.schema, identifier=target_table) -%}\\n    {%- set existing_cols = get_columns_in_query('select * from ' ~ target_relation) -%}\\n    {%- set ns = namespace() -%} {# handle for-loop scoping with a namespace #}\\n    {%- set ns.column_added = false -%}\\n\\n    {%- set intersection = [] -%}\\n    {%- for col in query_columns -%}\\n        {%- if col in existing_cols -%}\\n            {%- do intersection.append(col) -%}\\n        {%- else -%}\\n            {% set ns.column_added = true %}\\n        {%- endif -%}\\n    {%- endfor -%}\\n    {{ return([ns.column_added, intersection]) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_columns_in_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.snapshot_check_strategy\": {\"unique_id\": \"macro.dbt.snapshot_check_strategy\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshot/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshot/strategies.sql\", \"name\": \"snapshot_check_strategy\", \"macro_sql\": \"{% macro snapshot_check_strategy(node, snapshotted_rel, current_rel, config, target_exists) %}\\n    {% set check_cols_config = config['check_cols'] %}\\n    {% set primary_key = config['unique_key'] %}\\n    {% set invalidate_hard_deletes = config.get('invalidate_hard_deletes', false) %}\\n    \\n    {% set select_current_time -%}\\n        select {{ snapshot_get_time() }} as snapshot_start\\n    {%- endset %}\\n\\n    {#-- don't access the column by name, to avoid dealing with casing issues on snowflake #}\\n    {%- set now = run_query(select_current_time)[0][0] -%}\\n    {% if now is none or now is undefined -%}\\n        {%- do exceptions.raise_compiler_error('Could not get a snapshot start time from the database') -%}\\n    {%- endif %}\\n    {% set updated_at = config.get('updated_at', snapshot_string_as_time(now)) %}\\n\\n    {% set column_added = false %}\\n\\n    {% if check_cols_config == 'all' %}\\n        {% set column_added, check_cols = snapshot_check_all_get_existing_columns(node, target_exists) %}\\n    {% elif check_cols_config is iterable and (check_cols_config | length) > 0 %}\\n        {% set check_cols = check_cols_config %}\\n    {% else %}\\n        {% do exceptions.raise_compiler_error(\\\"Invalid value for 'check_cols': \\\" ~ check_cols_config) %}\\n    {% endif %}\\n\\n    {%- set row_changed_expr -%}\\n    (\\n    {%- if column_added -%}\\n        TRUE\\n    {%- else -%}\\n    {%- for col in check_cols -%}\\n        {{ snapshotted_rel }}.{{ col }} != {{ current_rel }}.{{ col }}\\n        or\\n        (\\n            (({{ snapshotted_rel }}.{{ col }} is null) and not ({{ current_rel }}.{{ col }} is null))\\n            or\\n            ((not {{ snapshotted_rel }}.{{ col }} is null) and ({{ current_rel }}.{{ col }} is null))\\n        )\\n        {%- if not loop.last %} or {% endif -%}\\n    {%- endfor -%}\\n    {%- endif -%}\\n    )\\n    {%- endset %}\\n\\n    {% set scd_id_expr = snapshot_hash_arguments([primary_key, updated_at]) %}\\n\\n    {% do return({\\n        \\\"unique_key\\\": primary_key,\\n        \\\"updated_at\\\": updated_at,\\n        \\\"row_changed\\\": row_changed_expr,\\n        \\\"scd_id\\\": scd_id_expr,\\n        \\\"invalidate_hard_deletes\\\": invalidate_hard_deletes\\n    }) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.snapshot_get_time\", \"macro.dbt.run_query\", \"macro.dbt.snapshot_string_as_time\", \"macro.dbt.snapshot_check_all_get_existing_columns\", \"macro.dbt.snapshot_hash_arguments\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.create_columns\": {\"unique_id\": \"macro.dbt.create_columns\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshot/snapshot.sql\", \"original_file_path\": \"macros/materializations/snapshot/snapshot.sql\", \"name\": \"create_columns\", \"macro_sql\": \"{% macro create_columns(relation, columns) %}\\n  {{ adapter.dispatch('create_columns', 'dbt')(relation, columns) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__create_columns\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__create_columns\": {\"unique_id\": \"macro.dbt.default__create_columns\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshot/snapshot.sql\", \"original_file_path\": \"macros/materializations/snapshot/snapshot.sql\", \"name\": \"default__create_columns\", \"macro_sql\": \"{% macro default__create_columns(relation, columns) %}\\n  {% for column in columns %}\\n    {% call statement() %}\\n      alter table {{ relation }} add column \\\"{{ column.name }}\\\" {{ column.data_type }};\\n    {% endcall %}\\n  {% endfor %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.post_snapshot\": {\"unique_id\": \"macro.dbt.post_snapshot\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshot/snapshot.sql\", \"original_file_path\": \"macros/materializations/snapshot/snapshot.sql\", \"name\": \"post_snapshot\", \"macro_sql\": \"{% macro post_snapshot(staging_relation) %}\\n  {{ adapter.dispatch('post_snapshot', 'dbt')(staging_relation) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__post_snapshot\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__post_snapshot\": {\"unique_id\": \"macro.dbt.default__post_snapshot\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshot/snapshot.sql\", \"original_file_path\": \"macros/materializations/snapshot/snapshot.sql\", \"name\": \"default__post_snapshot\", \"macro_sql\": \"{% macro default__post_snapshot(staging_relation) %}\\n    {# no-op #}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.snapshot_staging_table\": {\"unique_id\": \"macro.dbt.snapshot_staging_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshot/snapshot.sql\", \"original_file_path\": \"macros/materializations/snapshot/snapshot.sql\", \"name\": \"snapshot_staging_table\", \"macro_sql\": \"{% macro snapshot_staging_table(strategy, source_sql, target_relation) -%}\\n\\n    with snapshot_query as (\\n\\n        {{ source_sql }}\\n\\n    ),\\n\\n    snapshotted_data as (\\n\\n        select *,\\n            {{ strategy.unique_key }} as dbt_unique_key\\n\\n        from {{ target_relation }}\\n        where dbt_valid_to is null\\n\\n    ),\\n\\n    insertions_source_data as (\\n\\n        select\\n            *,\\n            {{ strategy.unique_key }} as dbt_unique_key,\\n            {{ strategy.updated_at }} as dbt_updated_at,\\n            {{ strategy.updated_at }} as dbt_valid_from,\\n            nullif({{ strategy.updated_at }}, {{ strategy.updated_at }}) as dbt_valid_to,\\n            {{ strategy.scd_id }} as dbt_scd_id\\n\\n        from snapshot_query\\n    ),\\n\\n    updates_source_data as (\\n\\n        select\\n            *,\\n            {{ strategy.unique_key }} as dbt_unique_key,\\n            {{ strategy.updated_at }} as dbt_updated_at,\\n            {{ strategy.updated_at }} as dbt_valid_from,\\n            {{ strategy.updated_at }} as dbt_valid_to\\n\\n        from snapshot_query\\n    ),\\n\\n    {%- if strategy.invalidate_hard_deletes %}\\n\\n    deletes_source_data as (\\n\\n        select \\n            *,\\n            {{ strategy.unique_key }} as dbt_unique_key\\n        from snapshot_query\\n    ),\\n    {% endif %}\\n\\n    insertions as (\\n\\n        select\\n            'insert' as dbt_change_type,\\n            source_data.*\\n\\n        from insertions_source_data as source_data\\n        left outer join snapshotted_data on snapshotted_data.dbt_unique_key = source_data.dbt_unique_key\\n        where snapshotted_data.dbt_unique_key is null\\n           or (\\n                snapshotted_data.dbt_unique_key is not null\\n            and (\\n                {{ strategy.row_changed }}\\n            )\\n        )\\n\\n    ),\\n\\n    updates as (\\n\\n        select\\n            'update' as dbt_change_type,\\n            source_data.*,\\n            snapshotted_data.dbt_scd_id\\n\\n        from updates_source_data as source_data\\n        join snapshotted_data on snapshotted_data.dbt_unique_key = source_data.dbt_unique_key\\n        where (\\n            {{ strategy.row_changed }}\\n        )\\n    )\\n\\n    {%- if strategy.invalidate_hard_deletes -%}\\n    ,\\n\\n    deletes as (\\n    \\n        select\\n            'delete' as dbt_change_type,\\n            source_data.*,\\n            {{ snapshot_get_time() }} as dbt_valid_from,\\n            {{ snapshot_get_time() }} as dbt_updated_at,\\n            {{ snapshot_get_time() }} as dbt_valid_to,\\n            snapshotted_data.dbt_scd_id\\n    \\n        from snapshotted_data\\n        left join deletes_source_data as source_data on snapshotted_data.dbt_unique_key = source_data.dbt_unique_key\\n        where source_data.dbt_unique_key is null\\n    )\\n    {%- endif %}\\n\\n    select * from insertions\\n    union all\\n    select * from updates\\n    {%- if strategy.invalidate_hard_deletes %}\\n    union all\\n    select * from deletes\\n    {%- endif %}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.snapshot_get_time\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.build_snapshot_table\": {\"unique_id\": \"macro.dbt.build_snapshot_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshot/snapshot.sql\", \"original_file_path\": \"macros/materializations/snapshot/snapshot.sql\", \"name\": \"build_snapshot_table\", \"macro_sql\": \"{% macro build_snapshot_table(strategy, sql) %}\\n\\n    select *,\\n        {{ strategy.scd_id }} as dbt_scd_id,\\n        {{ strategy.updated_at }} as dbt_updated_at,\\n        {{ strategy.updated_at }} as dbt_valid_from,\\n        nullif({{ strategy.updated_at }}, {{ strategy.updated_at }}) as dbt_valid_to\\n    from (\\n        {{ sql }}\\n    ) sbq\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.get_or_create_relation\": {\"unique_id\": \"macro.dbt.get_or_create_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshot/snapshot.sql\", \"original_file_path\": \"macros/materializations/snapshot/snapshot.sql\", \"name\": \"get_or_create_relation\", \"macro_sql\": \"{% macro get_or_create_relation(database, schema, identifier, type) %}\\n  {%- set target_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) %}\\n\\n  {% if target_relation %}\\n    {% do return([true, target_relation]) %}\\n  {% endif %}\\n\\n  {%- set new_relation = api.Relation.create(\\n      database=database,\\n      schema=schema,\\n      identifier=identifier,\\n      type=type\\n  ) -%}\\n  {% do return([false, new_relation]) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.build_snapshot_staging_table\": {\"unique_id\": \"macro.dbt.build_snapshot_staging_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshot/snapshot.sql\", \"original_file_path\": \"macros/materializations/snapshot/snapshot.sql\", \"name\": \"build_snapshot_staging_table\", \"macro_sql\": \"{% macro build_snapshot_staging_table(strategy, sql, target_relation) %}\\n    {% set tmp_relation = make_temp_relation(target_relation) %}\\n\\n    {% set select = snapshot_staging_table(strategy, sql, target_relation) %}\\n\\n    {% call statement('build_snapshot_staging_relation') %}\\n        {{ create_table_as(True, tmp_relation, select) }}\\n    {% endcall %}\\n\\n    {% do return(tmp_relation) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.make_temp_relation\", \"macro.dbt.snapshot_staging_table\", \"macro.dbt.statement\", \"macro.dbt.create_table_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.materialization_snapshot_default\": {\"unique_id\": \"macro.dbt.materialization_snapshot_default\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshot/snapshot.sql\", \"original_file_path\": \"macros/materializations/snapshot/snapshot.sql\", \"name\": \"materialization_snapshot_default\", \"macro_sql\": \"{% materialization snapshot, default %}\\n  {%- set config = model['config'] -%}\\n\\n  {%- set target_table = model.get('alias', model.get('name')) -%}\\n\\n  {%- set strategy_name = config.get('strategy') -%}\\n  {%- set unique_key = config.get('unique_key') %}\\n\\n  {% if not adapter.check_schema_exists(model.database, model.schema) %}\\n    {% do create_schema(model.database, model.schema) %}\\n  {% endif %}\\n\\n  {% set target_relation_exists, target_relation = get_or_create_relation(\\n          database=model.database,\\n          schema=model.schema,\\n          identifier=target_table,\\n          type='table') -%}\\n\\n  {%- if not target_relation.is_table -%}\\n    {% do exceptions.relation_wrong_type(target_relation, 'table') %}\\n  {%- endif -%}\\n\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  {% set strategy_macro = strategy_dispatch(strategy_name) %}\\n  {% set strategy = strategy_macro(model, \\\"snapshotted_data\\\", \\\"source_data\\\", config, target_relation_exists) %}\\n\\n  {% if not target_relation_exists %}\\n\\n      {% set build_sql = build_snapshot_table(strategy, model['compiled_sql']) %}\\n      {% set final_sql = create_table_as(False, target_relation, build_sql) %}\\n\\n  {% else %}\\n\\n      {{ adapter.valid_snapshot_target(target_relation) }}\\n\\n      {% set staging_table = build_snapshot_staging_table(strategy, sql, target_relation) %}\\n\\n      -- this may no-op if the database does not require column expansion\\n      {% do adapter.expand_target_column_types(from_relation=staging_table,\\n                                               to_relation=target_relation) %}\\n\\n      {% set missing_columns = adapter.get_missing_columns(staging_table, target_relation)\\n                                   | rejectattr('name', 'equalto', 'dbt_change_type')\\n                                   | rejectattr('name', 'equalto', 'DBT_CHANGE_TYPE')\\n                                   | rejectattr('name', 'equalto', 'dbt_unique_key')\\n                                   | rejectattr('name', 'equalto', 'DBT_UNIQUE_KEY')\\n                                   | list %}\\n\\n      {% do create_columns(target_relation, missing_columns) %}\\n\\n      {% set source_columns = adapter.get_columns_in_relation(staging_table)\\n                                   | rejectattr('name', 'equalto', 'dbt_change_type')\\n                                   | rejectattr('name', 'equalto', 'DBT_CHANGE_TYPE')\\n                                   | rejectattr('name', 'equalto', 'dbt_unique_key')\\n                                   | rejectattr('name', 'equalto', 'DBT_UNIQUE_KEY')\\n                                   | list %}\\n\\n      {% set quoted_source_columns = [] %}\\n      {% for column in source_columns %}\\n        {% do quoted_source_columns.append(adapter.quote(column.name)) %}\\n      {% endfor %}\\n\\n      {% set final_sql = snapshot_merge_sql(\\n            target = target_relation,\\n            source = staging_table,\\n            insert_cols = quoted_source_columns\\n         )\\n      %}\\n\\n  {% endif %}\\n\\n  {% call statement('main') %}\\n      {{ final_sql }}\\n  {% endcall %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {% if not target_relation_exists %}\\n    {% do create_indexes(target_relation) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  {{ adapter.commit() }}\\n\\n  {% if staging_table is defined %}\\n      {% do post_snapshot(staging_table) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{% endmaterialization %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.create_schema\", \"macro.dbt.get_or_create_relation\", \"macro.dbt.run_hooks\", \"macro.dbt.strategy_dispatch\", \"macro.dbt.build_snapshot_table\", \"macro.dbt.create_table_as\", \"macro.dbt.build_snapshot_staging_table\", \"macro.dbt.create_columns\", \"macro.dbt.snapshot_merge_sql\", \"macro.dbt.statement\", \"macro.dbt.persist_docs\", \"macro.dbt.create_indexes\", \"macro.dbt.post_snapshot\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.create_csv_table\": {\"unique_id\": \"macro.dbt.create_csv_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/seed/seed.sql\", \"original_file_path\": \"macros/materializations/seed/seed.sql\", \"name\": \"create_csv_table\", \"macro_sql\": \"{% macro create_csv_table(model, agate_table) -%}\\n  {{ adapter.dispatch('create_csv_table', 'dbt')(model, agate_table) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__create_csv_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__create_csv_table\": {\"unique_id\": \"macro.dbt.default__create_csv_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/seed/seed.sql\", \"original_file_path\": \"macros/materializations/seed/seed.sql\", \"name\": \"default__create_csv_table\", \"macro_sql\": \"{% macro default__create_csv_table(model, agate_table) %}\\n  {%- set column_override = model['config'].get('column_types', {}) -%}\\n  {%- set quote_seed_column = model['config'].get('quote_columns', None) -%}\\n\\n  {% set sql %}\\n    create table {{ this.render() }} (\\n        {%- for col_name in agate_table.column_names -%}\\n            {%- set inferred_type = adapter.convert_type(agate_table, loop.index0) -%}\\n            {%- set type = column_override.get(col_name, inferred_type) -%}\\n            {%- set column_name = (col_name | string) -%}\\n            {{ adapter.quote_seed_column(column_name, quote_seed_column) }} {{ type }} {%- if not loop.last -%}, {%- endif -%}\\n        {%- endfor -%}\\n    )\\n  {% endset %}\\n\\n  {% call statement('_') -%}\\n    {{ sql }}\\n  {%- endcall %}\\n\\n  {{ return(sql) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.reset_csv_table\": {\"unique_id\": \"macro.dbt.reset_csv_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/seed/seed.sql\", \"original_file_path\": \"macros/materializations/seed/seed.sql\", \"name\": \"reset_csv_table\", \"macro_sql\": \"{% macro reset_csv_table(model, full_refresh, old_relation, agate_table) -%}\\n  {{ adapter.dispatch('reset_csv_table', 'dbt')(model, full_refresh, old_relation, agate_table) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__reset_csv_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__reset_csv_table\": {\"unique_id\": \"macro.dbt.default__reset_csv_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/seed/seed.sql\", \"original_file_path\": \"macros/materializations/seed/seed.sql\", \"name\": \"default__reset_csv_table\", \"macro_sql\": \"{% macro default__reset_csv_table(model, full_refresh, old_relation, agate_table) %}\\n    {% set sql = \\\"\\\" %}\\n    {% if full_refresh %}\\n        {{ adapter.drop_relation(old_relation) }}\\n        {% set sql = create_csv_table(model, agate_table) %}\\n    {% else %}\\n        {{ adapter.truncate_relation(old_relation) }}\\n        {% set sql = \\\"truncate table \\\" ~ old_relation %}\\n    {% endif %}\\n\\n    {{ return(sql) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.create_csv_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.get_binding_char\": {\"unique_id\": \"macro.dbt.get_binding_char\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/seed/seed.sql\", \"original_file_path\": \"macros/materializations/seed/seed.sql\", \"name\": \"get_binding_char\", \"macro_sql\": \"{% macro get_binding_char() -%}\\n  {{ adapter.dispatch('get_binding_char', 'dbt')() }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_binding_char\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__get_binding_char\": {\"unique_id\": \"macro.dbt.default__get_binding_char\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/seed/seed.sql\", \"original_file_path\": \"macros/materializations/seed/seed.sql\", \"name\": \"default__get_binding_char\", \"macro_sql\": \"{% macro default__get_binding_char() %}\\n  {{ return('%s') }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.get_batch_size\": {\"unique_id\": \"macro.dbt.get_batch_size\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/seed/seed.sql\", \"original_file_path\": \"macros/materializations/seed/seed.sql\", \"name\": \"get_batch_size\", \"macro_sql\": \"{% macro get_batch_size() -%}\\n  {{ return(adapter.dispatch('get_batch_size', 'dbt')()) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_batch_size\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__get_batch_size\": {\"unique_id\": \"macro.dbt.default__get_batch_size\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/seed/seed.sql\", \"original_file_path\": \"macros/materializations/seed/seed.sql\", \"name\": \"default__get_batch_size\", \"macro_sql\": \"{% macro default__get_batch_size() %}\\n  {{ return(10000) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.get_seed_column_quoted_csv\": {\"unique_id\": \"macro.dbt.get_seed_column_quoted_csv\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/seed/seed.sql\", \"original_file_path\": \"macros/materializations/seed/seed.sql\", \"name\": \"get_seed_column_quoted_csv\", \"macro_sql\": \"{% macro get_seed_column_quoted_csv(model, column_names) %}\\n  {%- set quote_seed_column = model['config'].get('quote_columns', None) -%}\\n    {% set quoted = [] %}\\n    {% for col in column_names -%}\\n        {%- do quoted.append(adapter.quote_seed_column(col, quote_seed_column)) -%}\\n    {%- endfor %}\\n\\n    {%- set dest_cols_csv = quoted | join(', ') -%}\\n    {{ return(dest_cols_csv) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.load_csv_rows\": {\"unique_id\": \"macro.dbt.load_csv_rows\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/seed/seed.sql\", \"original_file_path\": \"macros/materializations/seed/seed.sql\", \"name\": \"load_csv_rows\", \"macro_sql\": \"{% macro load_csv_rows(model, agate_table) -%}\\n  {{ adapter.dispatch('load_csv_rows', 'dbt')(model, agate_table) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__load_csv_rows\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__load_csv_rows\": {\"unique_id\": \"macro.dbt.default__load_csv_rows\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/seed/seed.sql\", \"original_file_path\": \"macros/materializations/seed/seed.sql\", \"name\": \"default__load_csv_rows\", \"macro_sql\": \"{% macro default__load_csv_rows(model, agate_table) %}\\n\\n  {% set batch_size = get_batch_size() %}\\n\\n  {% set cols_sql = get_seed_column_quoted_csv(model, agate_table.column_names) %}\\n  {% set bindings = [] %}\\n\\n  {% set statements = [] %}\\n\\n  {% for chunk in agate_table.rows | batch(batch_size) %}\\n      {% set bindings = [] %}\\n\\n      {% for row in chunk %}\\n          {% do bindings.extend(row) %}\\n      {% endfor %}\\n\\n      {% set sql %}\\n          insert into {{ this.render() }} ({{ cols_sql }}) values\\n          {% for row in chunk -%}\\n              ({%- for column in agate_table.column_names -%}\\n                  {{ get_binding_char() }}\\n                  {%- if not loop.last%},{%- endif %}\\n              {%- endfor -%})\\n              {%- if not loop.last%},{%- endif %}\\n          {%- endfor %}\\n      {% endset %}\\n\\n      {% do adapter.add_query(sql, bindings=bindings, abridge_sql_log=True) %}\\n\\n      {% if loop.index0 == 0 %}\\n          {% do statements.append(sql) %}\\n      {% endif %}\\n  {% endfor %}\\n\\n  {# Return SQL so we can render it out into the compiled files #}\\n  {{ return(statements[0]) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_batch_size\", \"macro.dbt.get_seed_column_quoted_csv\", \"macro.dbt.get_binding_char\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.materialization_seed_default\": {\"unique_id\": \"macro.dbt.materialization_seed_default\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/seed/seed.sql\", \"original_file_path\": \"macros/materializations/seed/seed.sql\", \"name\": \"materialization_seed_default\", \"macro_sql\": \"{% materialization seed, default %}\\n\\n  {%- set identifier = model['alias'] -%}\\n  {%- set full_refresh_mode = (should_full_refresh()) -%}\\n\\n  {%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%}\\n\\n  {%- set exists_as_table = (old_relation is not none and old_relation.is_table) -%}\\n  {%- set exists_as_view = (old_relation is not none and old_relation.is_view) -%}\\n\\n  {%- set agate_table = load_agate_table() -%}\\n  {%- do store_result('agate_table', response='OK', agate_table=agate_table) -%}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  -- build model\\n  {% set create_table_sql = \\\"\\\" %}\\n  {% if exists_as_view %}\\n    {{ exceptions.raise_compiler_error(\\\"Cannot seed to '{}', it is a view\\\".format(old_relation)) }}\\n  {% elif exists_as_table %}\\n    {% set create_table_sql = reset_csv_table(model, full_refresh_mode, old_relation, agate_table) %}\\n  {% else %}\\n    {% set create_table_sql = create_csv_table(model, agate_table) %}\\n  {% endif %}\\n\\n  {% set code = 'CREATE' if full_refresh_mode else 'INSERT' %}\\n  {% set rows_affected = (agate_table.rows | length) %}\\n  {% set sql = load_csv_rows(model, agate_table) %}\\n\\n  {% call noop_statement('main', code ~ ' ' ~ rows_affected, code, rows_affected) %}\\n    {{ create_table_sql }};\\n    -- dbt seed --\\n    {{ sql }}\\n  {% endcall %}\\n\\n  {% set target_relation = this.incorporate(type='table') %}\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {% if full_refresh_mode or not exists_as_table %}\\n    {% do create_indexes(target_relation) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  -- `COMMIT` happens here\\n  {{ adapter.commit() }}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{% endmaterialization %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.should_full_refresh\", \"macro.dbt.run_hooks\", \"macro.dbt.reset_csv_table\", \"macro.dbt.create_csv_table\", \"macro.dbt.load_csv_rows\", \"macro.dbt.noop_statement\", \"macro.dbt.persist_docs\", \"macro.dbt.create_indexes\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.incremental_upsert\": {\"unique_id\": \"macro.dbt.incremental_upsert\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/incremental/helpers.sql\", \"original_file_path\": \"macros/materializations/incremental/helpers.sql\", \"name\": \"incremental_upsert\", \"macro_sql\": \"{% macro incremental_upsert(tmp_relation, target_relation, unique_key=none, statement_name=\\\"main\\\") %}\\n    \\n    {%- set dest_columns = adapter.get_columns_in_relation(target_relation) -%}\\n    {%- set dest_cols_csv = dest_columns | map(attribute='quoted') | join(', ') -%}\\n\\n    {%- if unique_key is not none -%}\\n    delete\\n    from {{ target_relation }}\\n    where ({{ unique_key }}) in (\\n        select ({{ unique_key }})\\n        from {{ tmp_relation }}\\n    );\\n    {%- endif %}\\n\\n    insert into {{ target_relation }} ({{ dest_cols_csv }})\\n    (\\n       select {{ dest_cols_csv }}\\n       from {{ tmp_relation }}\\n    );\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.materialization_incremental_default\": {\"unique_id\": \"macro.dbt.materialization_incremental_default\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/incremental/incremental.sql\", \"original_file_path\": \"macros/materializations/incremental/incremental.sql\", \"name\": \"materialization_incremental_default\", \"macro_sql\": \"{% materialization incremental, default -%}\\n\\n  {% set unique_key = config.get('unique_key') %}\\n\\n  {% set target_relation = this.incorporate(type='table') %}\\n  {% set existing_relation = load_relation(this) %}\\n  {% set tmp_relation = make_temp_relation(target_relation) %}\\n  {%- set full_refresh_mode = (should_full_refresh()) -%}\\n\\n  {% set on_schema_change = incremental_validate_on_schema_change(config.get('on_schema_change'), default='ignore') %}\\n\\n  {% set tmp_identifier = model['name'] + '__dbt_tmp' %}\\n  {% set backup_identifier = model['name'] + \\\"__dbt_backup\\\" %}\\n\\n  -- the intermediate_ and backup_ relations should not already exist in the database; get_relation\\n  -- will return None in that case. Otherwise, we get a relation that we can drop\\n  -- later, before we try to use this name for the current operation. This has to happen before\\n  -- BEGIN, in a separate transaction\\n  {% set preexisting_intermediate_relation = adapter.get_relation(identifier=tmp_identifier, \\n                                                                  schema=schema,\\n                                                                  database=database) %}                                               \\n  {% set preexisting_backup_relation = adapter.get_relation(identifier=backup_identifier,\\n                                                            schema=schema,\\n                                                            database=database) %}\\n  {{ drop_relation_if_exists(preexisting_intermediate_relation) }}\\n  {{ drop_relation_if_exists(preexisting_backup_relation) }}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  {% set to_drop = [] %}\\n\\n  {# -- first check whether we want to full refresh for source view or config reasons #}\\n  {% set trigger_full_refresh = (full_refresh_mode or existing_relation.is_view) %}\\n\\n  {% if existing_relation is none %}\\n      {% set build_sql = create_table_as(False, target_relation, sql) %}\\n{% elif trigger_full_refresh %}\\n      {#-- Make sure the backup doesn't exist so we don't encounter issues with the rename below #}\\n      {% set tmp_identifier = model['name'] + '__dbt_tmp' %}\\n      {% set backup_identifier = model['name'] + '__dbt_backup' %}\\n      {% set intermediate_relation = existing_relation.incorporate(path={\\\"identifier\\\": tmp_identifier}) %}\\n      {% set backup_relation = existing_relation.incorporate(path={\\\"identifier\\\": backup_identifier}) %}\\n\\n      {% set build_sql = create_table_as(False, intermediate_relation, sql) %}\\n      {% set need_swap = true %}\\n      {% do to_drop.append(backup_relation) %}\\n  {% else %}\\n    {% do run_query(create_table_as(True, tmp_relation, sql)) %}\\n    {% do adapter.expand_target_column_types(\\n             from_relation=tmp_relation,\\n             to_relation=target_relation) %}\\n    {% do process_schema_changes(on_schema_change, tmp_relation, existing_relation) %}\\n    {% set build_sql = incremental_upsert(tmp_relation, target_relation, unique_key=unique_key) %}\\n  \\n  {% endif %}\\n\\n  {% call statement(\\\"main\\\") %}\\n      {{ build_sql }}\\n  {% endcall %}\\n\\n  {% if need_swap %} \\n      {% do adapter.rename_relation(target_relation, backup_relation) %} \\n      {% do adapter.rename_relation(intermediate_relation, target_relation) %} \\n  {% endif %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {% if existing_relation is none or existing_relation.is_view or should_full_refresh() %}\\n    {% do create_indexes(target_relation) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  -- `COMMIT` happens here\\n  {% do adapter.commit() %}\\n\\n  {% for rel in to_drop %}\\n      {% do adapter.drop_relation(rel) %}\\n  {% endfor %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{%- endmaterialization %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.test.load_relation\", \"macro.dbt.make_temp_relation\", \"macro.dbt.should_full_refresh\", \"macro.dbt.incremental_validate_on_schema_change\", \"macro.dbt.drop_relation_if_exists\", \"macro.dbt.run_hooks\", \"macro.dbt.create_table_as\", \"macro.dbt.run_query\", \"macro.dbt.process_schema_changes\", \"macro.dbt.incremental_upsert\", \"macro.dbt.statement\", \"macro.dbt.persist_docs\", \"macro.dbt.create_indexes\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.incremental_validate_on_schema_change\": {\"unique_id\": \"macro.dbt.incremental_validate_on_schema_change\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/incremental/on_schema_change.sql\", \"original_file_path\": \"macros/materializations/incremental/on_schema_change.sql\", \"name\": \"incremental_validate_on_schema_change\", \"macro_sql\": \"{% macro incremental_validate_on_schema_change(on_schema_change, default='ignore') %}\\n   \\n   {% if on_schema_change not in ['sync_all_columns', 'append_new_columns', 'fail', 'ignore'] %}\\n     \\n     {% set log_message = 'Invalid value for on_schema_change (%s) specified. Setting default value of %s.' % (on_schema_change, default) %}\\n     {% do log(log_message) %}\\n     \\n     {{ return(default) }}\\n\\n   {% else %}\\n\\n     {{ return(on_schema_change) }}\\n   \\n   {% endif %}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.diff_columns\": {\"unique_id\": \"macro.dbt.diff_columns\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/incremental/on_schema_change.sql\", \"original_file_path\": \"macros/materializations/incremental/on_schema_change.sql\", \"name\": \"diff_columns\", \"macro_sql\": \"{% macro diff_columns(source_columns, target_columns) %}\\n\\n  {% set result = [] %}\\n  {% set source_names = source_columns | map(attribute = 'column') | list %}\\n  {% set target_names = target_columns | map(attribute = 'column') | list %}\\n   \\n   {# --check whether the name attribute exists in the target - this does not perform a data type check #}\\n   {% for sc in source_columns %}\\n     {% if sc.name not in target_names %}\\n        {{ result.append(sc) }}\\n     {% endif %}\\n   {% endfor %}\\n  \\n  {{ return(result) }}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.diff_column_data_types\": {\"unique_id\": \"macro.dbt.diff_column_data_types\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/incremental/on_schema_change.sql\", \"original_file_path\": \"macros/materializations/incremental/on_schema_change.sql\", \"name\": \"diff_column_data_types\", \"macro_sql\": \"{% macro diff_column_data_types(source_columns, target_columns) %}\\n  \\n  {% set result = [] %}\\n  {% for sc in source_columns %}\\n    {% set tc = target_columns | selectattr(\\\"name\\\", \\\"equalto\\\", sc.name) | list | first %}\\n    {% if tc %}\\n      {% if sc.data_type != tc.data_type %}\\n        {{ result.append( { 'column_name': tc.name, 'new_type': sc.data_type } ) }} \\n      {% endif %}\\n    {% endif %}\\n  {% endfor %}\\n\\n  {{ return(result) }}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.check_for_schema_changes\": {\"unique_id\": \"macro.dbt.check_for_schema_changes\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/incremental/on_schema_change.sql\", \"original_file_path\": \"macros/materializations/incremental/on_schema_change.sql\", \"name\": \"check_for_schema_changes\", \"macro_sql\": \"{% macro check_for_schema_changes(source_relation, target_relation) %}\\n  \\n  {% set schema_changed = False %}\\n  \\n  {%- set source_columns = adapter.get_columns_in_relation(source_relation) -%}\\n  {%- set target_columns = adapter.get_columns_in_relation(target_relation) -%}\\n  {%- set source_not_in_target = diff_columns(source_columns, target_columns) -%}\\n  {%- set target_not_in_source = diff_columns(target_columns, source_columns) -%}\\n  \\n  {% set new_target_types = diff_column_data_types(source_columns, target_columns) %}\\n\\n  {% if source_not_in_target != [] %}\\n    {% set schema_changed = True %}\\n  {% elif target_not_in_source != [] or new_target_types != [] %}\\n    {% set schema_changed = True %}\\n  {% elif new_target_types != [] %}\\n    {% set schema_changed = True %}\\n  {% endif %}\\n  \\n  {% set changes_dict = {\\n    'schema_changed': schema_changed,\\n    'source_not_in_target': source_not_in_target,\\n    'target_not_in_source': target_not_in_source,\\n    'new_target_types': new_target_types\\n  } %}\\n\\n  {% set msg %}\\n    In {{ target_relation }}:\\n        Schema changed: {{ schema_changed }}\\n        Source columns not in target: {{ source_not_in_target }}\\n        Target columns not in source: {{ target_not_in_source }}\\n        New column types: {{ new_target_types }}\\n  {% endset %}\\n  \\n  {% do log(msg) %}\\n\\n  {{ return(changes_dict) }}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.diff_columns\", \"macro.dbt.diff_column_data_types\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.sync_column_schemas\": {\"unique_id\": \"macro.dbt.sync_column_schemas\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/incremental/on_schema_change.sql\", \"original_file_path\": \"macros/materializations/incremental/on_schema_change.sql\", \"name\": \"sync_column_schemas\", \"macro_sql\": \"{% macro sync_column_schemas(on_schema_change, target_relation, schema_changes_dict) %}\\n  \\n  {%- set add_to_target_arr = schema_changes_dict['source_not_in_target'] -%}\\n\\n  {%- if on_schema_change == 'append_new_columns'-%}\\n     {%- if add_to_target_arr | length > 0 -%}\\n       {%- do alter_relation_add_remove_columns(target_relation, add_to_target_arr, none) -%}\\n     {%- endif -%}\\n  \\n  {% elif on_schema_change == 'sync_all_columns' %}\\n     {%- set remove_from_target_arr = schema_changes_dict['target_not_in_source'] -%}\\n     {%- set new_target_types = schema_changes_dict['new_target_types'] -%}\\n  \\n     {% if add_to_target_arr | length > 0 or remove_from_target_arr | length > 0 %} \\n       {%- do alter_relation_add_remove_columns(target_relation, add_to_target_arr, remove_from_target_arr) -%}\\n     {% endif %}\\n\\n     {% if new_target_types != [] %}\\n       {% for ntt in new_target_types %}\\n         {% set column_name = ntt['column_name'] %}\\n         {% set new_type = ntt['new_type'] %}\\n         {% do alter_column_type(target_relation, column_name, new_type) %}\\n       {% endfor %}\\n     {% endif %}\\n  \\n  {% endif %}\\n\\n  {% set schema_change_message %}\\n    In {{ target_relation }}:\\n        Schema change approach: {{ on_schema_change }}\\n        Columns added: {{ add_to_target_arr }}\\n        Columns removed: {{ remove_from_target_arr }}\\n        Data types changed: {{ new_target_types }}\\n  {% endset %}\\n  \\n  {% do log(schema_change_message) %}\\n  \\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.alter_relation_add_remove_columns\", \"macro.dbt.alter_column_type\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.process_schema_changes\": {\"unique_id\": \"macro.dbt.process_schema_changes\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/incremental/on_schema_change.sql\", \"original_file_path\": \"macros/materializations/incremental/on_schema_change.sql\", \"name\": \"process_schema_changes\", \"macro_sql\": \"{% macro process_schema_changes(on_schema_change, source_relation, target_relation) %}\\n    \\n    {% if on_schema_change != 'ignore' %}\\n    \\n      {% set schema_changes_dict = check_for_schema_changes(source_relation, target_relation) %}\\n      \\n      {% if schema_changes_dict['schema_changed'] %}\\n    \\n        {% if on_schema_change == 'fail' %}\\n        \\n          {% set fail_msg %}\\n              The source and target schemas on this incremental model are out of sync!\\n              They can be reconciled in several ways: \\n                - set the `on_schema_change` config to either append_new_columns or sync_all_columns, depending on your situation.\\n                - Re-run the incremental model with `full_refresh: True` to update the target schema.\\n                - update the schema manually and re-run the process.\\n          {% endset %}\\n          \\n          {% do exceptions.raise_compiler_error(fail_msg) %}\\n        \\n        {# -- unless we ignore, run the sync operation per the config #}\\n        {% else %}\\n          \\n          {% do sync_column_schemas(on_schema_change, target_relation, schema_changes_dict) %}\\n        \\n        {% endif %}\\n      \\n      {% endif %}\\n    \\n    {% endif %}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.check_for_schema_changes\", \"macro.dbt.sync_column_schemas\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.get_merge_sql\": {\"unique_id\": \"macro.dbt.get_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/common/merge.sql\", \"original_file_path\": \"macros/materializations/common/merge.sql\", \"name\": \"get_merge_sql\", \"macro_sql\": \"{% macro get_merge_sql(target, source, unique_key, dest_columns, predicates=none) -%}\\n  {{ adapter.dispatch('get_merge_sql', 'dbt')(target, source, unique_key, dest_columns, predicates) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.get_delete_insert_merge_sql\": {\"unique_id\": \"macro.dbt.get_delete_insert_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/common/merge.sql\", \"original_file_path\": \"macros/materializations/common/merge.sql\", \"name\": \"get_delete_insert_merge_sql\", \"macro_sql\": \"{% macro get_delete_insert_merge_sql(target, source, unique_key, dest_columns) -%}\\n  {{ adapter.dispatch('get_delete_insert_merge_sql', 'dbt')(target, source, unique_key, dest_columns) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_delete_insert_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.get_insert_overwrite_merge_sql\": {\"unique_id\": \"macro.dbt.get_insert_overwrite_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/common/merge.sql\", \"original_file_path\": \"macros/materializations/common/merge.sql\", \"name\": \"get_insert_overwrite_merge_sql\", \"macro_sql\": \"{% macro get_insert_overwrite_merge_sql(target, source, dest_columns, predicates, include_sql_header=false) -%}\\n  {{ adapter.dispatch('get_insert_overwrite_merge_sql', 'dbt')(target, source, dest_columns, predicates, include_sql_header) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_insert_overwrite_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__get_merge_sql\": {\"unique_id\": \"macro.dbt.default__get_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/common/merge.sql\", \"original_file_path\": \"macros/materializations/common/merge.sql\", \"name\": \"default__get_merge_sql\", \"macro_sql\": \"{% macro default__get_merge_sql(target, source, unique_key, dest_columns, predicates) -%}\\n    {%- set predicates = [] if predicates is none else [] + predicates -%}\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n    {%- set update_columns = config.get('merge_update_columns', default = dest_columns | map(attribute=\\\"quoted\\\") | list) -%}\\n    {%- set sql_header = config.get('sql_header', none) -%}\\n\\n    {% if unique_key %}\\n        {% set unique_key_match %}\\n            DBT_INTERNAL_SOURCE.{{ unique_key }} = DBT_INTERNAL_DEST.{{ unique_key }}\\n        {% endset %}\\n        {% do predicates.append(unique_key_match) %}\\n    {% else %}\\n        {% do predicates.append('FALSE') %}\\n    {% endif %}\\n\\n    {{ sql_header if sql_header is not none }}\\n\\n    merge into {{ target }} as DBT_INTERNAL_DEST\\n        using {{ source }} as DBT_INTERNAL_SOURCE\\n        on {{ predicates | join(' and ') }}\\n\\n    {% if unique_key %}\\n    when matched then update set\\n        {% for column_name in update_columns -%}\\n            {{ column_name }} = DBT_INTERNAL_SOURCE.{{ column_name }}\\n            {%- if not loop.last %}, {%- endif %}\\n        {%- endfor %}\\n    {% endif %}\\n\\n    when not matched then insert\\n        ({{ dest_cols_csv }})\\n    values\\n        ({{ dest_cols_csv }})\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_quoted_csv\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.get_quoted_csv\": {\"unique_id\": \"macro.dbt.get_quoted_csv\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/common/merge.sql\", \"original_file_path\": \"macros/materializations/common/merge.sql\", \"name\": \"get_quoted_csv\", \"macro_sql\": \"{% macro get_quoted_csv(column_names) %}\\n    {% set quoted = [] %}\\n    {% for col in column_names -%}\\n        {%- do quoted.append(adapter.quote(col)) -%}\\n    {%- endfor %}\\n\\n    {%- set dest_cols_csv = quoted | join(', ') -%}\\n    {{ return(dest_cols_csv) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.common_get_delete_insert_merge_sql\": {\"unique_id\": \"macro.dbt.common_get_delete_insert_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/common/merge.sql\", \"original_file_path\": \"macros/materializations/common/merge.sql\", \"name\": \"common_get_delete_insert_merge_sql\", \"macro_sql\": \"{% macro common_get_delete_insert_merge_sql(target, source, unique_key, dest_columns) -%}\\n\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n\\n    {% if unique_key is not none %}\\n    delete from {{ target }}\\n    where ({{ unique_key }}) in (\\n        select ({{ unique_key }})\\n        from {{ source }}\\n    );\\n    {% endif %}\\n\\n    insert into {{ target }} ({{ dest_cols_csv }})\\n    (\\n        select {{ dest_cols_csv }}\\n        from {{ source }}\\n    )\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_quoted_csv\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__get_delete_insert_merge_sql\": {\"unique_id\": \"macro.dbt.default__get_delete_insert_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/common/merge.sql\", \"original_file_path\": \"macros/materializations/common/merge.sql\", \"name\": \"default__get_delete_insert_merge_sql\", \"macro_sql\": \"{% macro default__get_delete_insert_merge_sql(target, source, unique_key, dest_columns) -%}\\n    {{ common_get_delete_insert_merge_sql(target, source, unique_key, dest_columns) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.common_get_delete_insert_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__get_insert_overwrite_merge_sql\": {\"unique_id\": \"macro.dbt.default__get_insert_overwrite_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/common/merge.sql\", \"original_file_path\": \"macros/materializations/common/merge.sql\", \"name\": \"default__get_insert_overwrite_merge_sql\", \"macro_sql\": \"{% macro default__get_insert_overwrite_merge_sql(target, source, dest_columns, predicates, include_sql_header) -%}\\n    {%- set predicates = [] if predicates is none else [] + predicates -%}\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n    {%- set sql_header = config.get('sql_header', none) -%}\\n\\n    {{ sql_header if sql_header is not none and include_sql_header }}\\n\\n    merge into {{ target }} as DBT_INTERNAL_DEST\\n        using {{ source }} as DBT_INTERNAL_SOURCE\\n        on FALSE\\n\\n    when not matched by source\\n        {% if predicates %} and {{ predicates | join(' and ') }} {% endif %}\\n        then delete\\n\\n    when not matched then insert\\n        ({{ dest_cols_csv }})\\n    values\\n        ({{ dest_cols_csv }})\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_quoted_csv\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.materialization_table_default\": {\"unique_id\": \"macro.dbt.materialization_table_default\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/table/table.sql\", \"original_file_path\": \"macros/materializations/table/table.sql\", \"name\": \"materialization_table_default\", \"macro_sql\": \"{% materialization table, default %}\\n  {%- set identifier = model['alias'] -%}\\n  {%- set tmp_identifier = model['name'] + '__dbt_tmp' -%}\\n  {%- set backup_identifier = model['name'] + '__dbt_backup' -%}\\n\\n  {%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%}\\n  {%- set target_relation = api.Relation.create(identifier=identifier,\\n                                                schema=schema,\\n                                                database=database,\\n                                                type='table') -%}\\n  {%- set intermediate_relation = api.Relation.create(identifier=tmp_identifier,\\n                                                      schema=schema,\\n                                                      database=database,\\n                                                      type='table') -%}\\n  -- the intermediate_relation should not already exist in the database; get_relation\\n  -- will return None in that case. Otherwise, we get a relation that we can drop\\n  -- later, before we try to use this name for the current operation\\n  {%- set preexisting_intermediate_relation = adapter.get_relation(identifier=tmp_identifier, \\n                                                                   schema=schema,\\n                                                                   database=database) -%}\\n  /*\\n      See ../view/view.sql for more information about this relation.\\n  */\\n  {%- set backup_relation_type = 'table' if old_relation is none else old_relation.type -%}\\n  {%- set backup_relation = api.Relation.create(identifier=backup_identifier,\\n                                                schema=schema,\\n                                                database=database,\\n                                                type=backup_relation_type) -%}\\n  -- as above, the backup_relation should not already exist\\n  {%- set preexisting_backup_relation = adapter.get_relation(identifier=backup_identifier,\\n                                                             schema=schema,\\n                                                             database=database) -%}\\n\\n\\n  -- drop the temp relations if they exist already in the database\\n  {{ drop_relation_if_exists(preexisting_intermediate_relation) }}\\n  {{ drop_relation_if_exists(preexisting_backup_relation) }}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  -- build model\\n  {% call statement('main') -%}\\n    {{ create_table_as(False, intermediate_relation, sql) }}\\n  {%- endcall %}\\n\\n  -- cleanup\\n  {% if old_relation is not none %}\\n      {{ adapter.rename_relation(old_relation, backup_relation) }}\\n  {% endif %}\\n\\n  {{ adapter.rename_relation(intermediate_relation, target_relation) }}\\n\\n  {% do create_indexes(target_relation) %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  -- `COMMIT` happens here\\n  {{ adapter.commit() }}\\n\\n  -- finally, drop the existing/backup relation after the commit\\n  {{ drop_relation_if_exists(backup_relation) }}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n{% endmaterialization %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.drop_relation_if_exists\", \"macro.dbt.run_hooks\", \"macro.dbt.statement\", \"macro.dbt.create_table_as\", \"macro.dbt.create_indexes\", \"macro.dbt.persist_docs\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.materialization_view_default\": {\"unique_id\": \"macro.dbt.materialization_view_default\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/view/view.sql\", \"original_file_path\": \"macros/materializations/view/view.sql\", \"name\": \"materialization_view_default\", \"macro_sql\": \"{%- materialization view, default -%}\\n\\n  {%- set identifier = model['alias'] -%}\\n  {%- set tmp_identifier = model['name'] + '__dbt_tmp' -%}\\n  {%- set backup_identifier = model['name'] + '__dbt_backup' -%}\\n\\n  {%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%}\\n  {%- set target_relation = api.Relation.create(identifier=identifier, schema=schema, database=database,\\n                                                type='view') -%}\\n  {%- set intermediate_relation = api.Relation.create(identifier=tmp_identifier,\\n                                                      schema=schema, database=database, type='view') -%}\\n  -- the intermediate_relation should not already exist in the database; get_relation\\n  -- will return None in that case. Otherwise, we get a relation that we can drop\\n  -- later, before we try to use this name for the current operation\\n  {%- set preexisting_intermediate_relation = adapter.get_relation(identifier=tmp_identifier, \\n                                                                   schema=schema,\\n                                                                   database=database) -%}\\n  /*\\n     This relation (probably) doesn't exist yet. If it does exist, it's a leftover from\\n     a previous run, and we're going to try to drop it immediately. At the end of this\\n     materialization, we're going to rename the \\\"old_relation\\\" to this identifier,\\n     and then we're going to drop it. In order to make sure we run the correct one of:\\n       - drop view ...\\n       - drop table ...\\n\\n     We need to set the type of this relation to be the type of the old_relation, if it exists,\\n     or else \\\"view\\\" as a sane default if it does not. Note that if the old_relation does not\\n     exist, then there is nothing to move out of the way and subsequentally drop. In that case,\\n     this relation will be effectively unused.\\n  */\\n  {%- set backup_relation_type = 'view' if old_relation is none else old_relation.type -%}\\n  {%- set backup_relation = api.Relation.create(identifier=backup_identifier,\\n                                                schema=schema, database=database,\\n                                                type=backup_relation_type) -%}\\n  -- as above, the backup_relation should not already exist\\n  {%- set preexisting_backup_relation = adapter.get_relation(identifier=backup_identifier,\\n                                                             schema=schema,\\n                                                             database=database) -%}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- drop the temp relations if they exist already in the database\\n  {{ drop_relation_if_exists(preexisting_intermediate_relation) }}\\n  {{ drop_relation_if_exists(preexisting_backup_relation) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  -- build model\\n  {% call statement('main') -%}\\n    {{ create_view_as(intermediate_relation, sql) }}\\n  {%- endcall %}\\n\\n  -- cleanup\\n  -- move the existing view out of the way\\n  {% if old_relation is not none %}\\n    {{ adapter.rename_relation(old_relation, backup_relation) }}\\n  {% endif %}\\n  {{ adapter.rename_relation(intermediate_relation, target_relation) }}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  {{ adapter.commit() }}\\n\\n  {{ drop_relation_if_exists(backup_relation) }}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{%- endmaterialization -%}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.run_hooks\", \"macro.dbt.drop_relation_if_exists\", \"macro.dbt.statement\", \"macro.dbt.create_view_as\", \"macro.dbt.persist_docs\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.handle_existing_table\": {\"unique_id\": \"macro.dbt.handle_existing_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/view/create_or_replace_view.sql\", \"original_file_path\": \"macros/materializations/view/create_or_replace_view.sql\", \"name\": \"handle_existing_table\", \"macro_sql\": \"{% macro handle_existing_table(full_refresh, old_relation) %}\\n    {{ adapter.dispatch('handle_existing_table', 'dbt')(full_refresh, old_relation) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__handle_existing_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__handle_existing_table\": {\"unique_id\": \"macro.dbt.default__handle_existing_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/view/create_or_replace_view.sql\", \"original_file_path\": \"macros/materializations/view/create_or_replace_view.sql\", \"name\": \"default__handle_existing_table\", \"macro_sql\": \"{% macro default__handle_existing_table(full_refresh, old_relation) %}\\n    {{ log(\\\"Dropping relation \\\" ~ old_relation ~ \\\" because it is of type \\\" ~ old_relation.type) }}\\n    {{ adapter.drop_relation(old_relation) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.create_or_replace_view\": {\"unique_id\": \"macro.dbt.create_or_replace_view\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/materializations/view/create_or_replace_view.sql\", \"original_file_path\": \"macros/materializations/view/create_or_replace_view.sql\", \"name\": \"create_or_replace_view\", \"macro_sql\": \"{% macro create_or_replace_view() %}\\n  {%- set identifier = model['alias'] -%}\\n\\n  {%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%}\\n\\n  {%- set exists_as_view = (old_relation is not none and old_relation.is_view) -%}\\n\\n  {%- set target_relation = api.Relation.create(\\n      identifier=identifier, schema=schema, database=database,\\n      type='view') -%}\\n\\n  {{ run_hooks(pre_hooks) }}\\n\\n  -- If there's a table with the same name and we weren't told to full refresh,\\n  -- that's an error. If we were told to full refresh, drop it. This behavior differs\\n  -- for Snowflake and BigQuery, so multiple dispatch is used.\\n  {%- if old_relation is not none and old_relation.is_table -%}\\n    {{ handle_existing_table(should_full_refresh(), old_relation) }}\\n  {%- endif -%}\\n\\n  -- build model\\n  {% call statement('main') -%}\\n    {{ create_view_as(target_relation, sql) }}\\n  {%- endcall %}\\n\\n  {{ run_hooks(post_hooks) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.run_hooks\", \"macro.dbt.handle_existing_table\", \"macro.dbt.should_full_refresh\", \"macro.dbt.statement\", \"macro.dbt.create_view_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.generate_alias_name\": {\"unique_id\": \"macro.dbt.generate_alias_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/etc/get_custom_alias.sql\", \"original_file_path\": \"macros/etc/get_custom_alias.sql\", \"name\": \"generate_alias_name\", \"macro_sql\": \"{% macro generate_alias_name(custom_alias_name=none, node=none) -%}\\n    {% do return(adapter.dispatch('generate_alias_name', 'dbt')(custom_alias_name, node)) %}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__generate_alias_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__generate_alias_name\": {\"unique_id\": \"macro.dbt.default__generate_alias_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/etc/get_custom_alias.sql\", \"original_file_path\": \"macros/etc/get_custom_alias.sql\", \"name\": \"default__generate_alias_name\", \"macro_sql\": \"{% macro default__generate_alias_name(custom_alias_name=none, node=none) -%}\\n\\n    {%- if custom_alias_name is none -%}\\n\\n        {{ node.name }}\\n\\n    {%- else -%}\\n\\n        {{ custom_alias_name | trim }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.run_query\": {\"unique_id\": \"macro.dbt.run_query\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/etc/query.sql\", \"original_file_path\": \"macros/etc/query.sql\", \"name\": \"run_query\", \"macro_sql\": \"{% macro run_query(sql) %}\\n  {% call statement(\\\"run_query_statement\\\", fetch_result=true, auto_begin=false) %}\\n    {{ sql }}\\n  {% endcall %}\\n\\n  {% do return(load_result(\\\"run_query_statement\\\").table) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.is_incremental\": {\"unique_id\": \"macro.dbt.is_incremental\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/etc/is_incremental.sql\", \"original_file_path\": \"macros/etc/is_incremental.sql\", \"name\": \"is_incremental\", \"macro_sql\": \"{% macro is_incremental() %}\\n    {#-- do not run introspective queries in parsing #}\\n    {% if not execute %}\\n        {{ return(False) }}\\n    {% else %}\\n        {% set relation = adapter.get_relation(this.database, this.schema, this.table) %}\\n        {{ return(relation is not none\\n                  and relation.type == 'table'\\n                  and model.config.materialized == 'incremental'\\n                  and not should_full_refresh()) }}\\n    {% endif %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.should_full_refresh\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.convert_datetime\": {\"unique_id\": \"macro.dbt.convert_datetime\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"name\": \"convert_datetime\", \"macro_sql\": \"{% macro convert_datetime(date_str, date_fmt) %}\\n\\n  {% set error_msg -%}\\n      The provided partition date '{{ date_str }}' does not match the expected format '{{ date_fmt }}'\\n  {%- endset %}\\n\\n  {% set res = try_or_compiler_error(error_msg, modules.datetime.datetime.strptime, date_str.strip(), date_fmt) %}\\n  {{ return(res) }}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.dates_in_range\": {\"unique_id\": \"macro.dbt.dates_in_range\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"name\": \"dates_in_range\", \"macro_sql\": \"{% macro dates_in_range(start_date_str, end_date_str=none, in_fmt=\\\"%Y%m%d\\\", out_fmt=\\\"%Y%m%d\\\") %}\\n    {% set end_date_str = start_date_str if end_date_str is none else end_date_str %}\\n\\n    {% set start_date = convert_datetime(start_date_str, in_fmt) %}\\n    {% set end_date = convert_datetime(end_date_str, in_fmt) %}\\n\\n    {% set day_count = (end_date - start_date).days %}\\n    {% if day_count < 0 %}\\n        {% set msg -%}\\n            Partition start date is after the end date ({{ start_date }}, {{ end_date }})\\n        {%- endset %}\\n\\n        {{ exceptions.raise_compiler_error(msg, model) }}\\n    {% endif %}\\n\\n    {% set date_list = [] %}\\n    {% for i in range(0, day_count + 1) %}\\n        {% set the_date = (modules.datetime.timedelta(days=i) + start_date) %}\\n        {% if not out_fmt %}\\n            {% set _ = date_list.append(the_date) %}\\n        {% else %}\\n            {% set _ = date_list.append(the_date.strftime(out_fmt)) %}\\n        {% endif %}\\n    {% endfor %}\\n\\n    {{ return(date_list) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.convert_datetime\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.partition_range\": {\"unique_id\": \"macro.dbt.partition_range\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"name\": \"partition_range\", \"macro_sql\": \"{% macro partition_range(raw_partition_date, date_fmt='%Y%m%d') %}\\n    {% set partition_range = (raw_partition_date | string).split(\\\",\\\") %}\\n\\n    {% if (partition_range | length) == 1 %}\\n      {% set start_date = partition_range[0] %}\\n      {% set end_date = none %}\\n    {% elif (partition_range | length) == 2 %}\\n      {% set start_date = partition_range[0] %}\\n      {% set end_date = partition_range[1] %}\\n    {% else %}\\n      {{ exceptions.raise_compiler_error(\\\"Invalid partition time. Expected format: {Start Date}[,{End Date}]. Got: \\\" ~ raw_partition_date) }}\\n    {% endif %}\\n\\n    {{ return(dates_in_range(start_date, end_date, in_fmt=date_fmt)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.dates_in_range\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.py_current_timestring\": {\"unique_id\": \"macro.dbt.py_current_timestring\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"name\": \"py_current_timestring\", \"macro_sql\": \"{% macro py_current_timestring() %}\\n    {% set dt = modules.datetime.datetime.now() %}\\n    {% do return(dt.strftime(\\\"%Y%m%d%H%M%S%f\\\")) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.get_where_subquery\": {\"unique_id\": \"macro.dbt.get_where_subquery\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/etc/where_subquery.sql\", \"original_file_path\": \"macros/etc/where_subquery.sql\", \"name\": \"get_where_subquery\", \"macro_sql\": \"{% macro get_where_subquery(relation) -%}\\n    {% do return(adapter.dispatch('get_where_subquery', 'dbt')(relation)) %}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_where_subquery\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__get_where_subquery\": {\"unique_id\": \"macro.dbt.default__get_where_subquery\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/etc/where_subquery.sql\", \"original_file_path\": \"macros/etc/where_subquery.sql\", \"name\": \"default__get_where_subquery\", \"macro_sql\": \"{% macro default__get_where_subquery(relation) -%}\\n    {% set where = config.get('where', '') %}\\n    {% if where %}\\n        {%- set filtered -%}\\n            (select * from {{ relation }} where {{ where }}) dbt_subquery\\n        {%- endset -%}\\n        {% do return(filtered) %}\\n    {%- else -%}\\n        {% do return(relation) %}\\n    {%- endif -%}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.generate_schema_name\": {\"unique_id\": \"macro.dbt.generate_schema_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/etc/get_custom_schema.sql\", \"original_file_path\": \"macros/etc/get_custom_schema.sql\", \"name\": \"generate_schema_name\", \"macro_sql\": \"{% macro generate_schema_name(custom_schema_name, node) -%}\\n    {{ return(adapter.dispatch('generate_schema_name', 'dbt')(custom_schema_name, node)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__generate_schema_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__generate_schema_name\": {\"unique_id\": \"macro.dbt.default__generate_schema_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/etc/get_custom_schema.sql\", \"original_file_path\": \"macros/etc/get_custom_schema.sql\", \"name\": \"default__generate_schema_name\", \"macro_sql\": \"{% macro default__generate_schema_name(custom_schema_name, node) -%}\\n\\n    {%- set default_schema = target.schema -%}\\n    {%- if custom_schema_name is none -%}\\n\\n        {{ default_schema }}\\n\\n    {%- else -%}\\n\\n        {{ default_schema }}_{{ custom_schema_name | trim }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.generate_schema_name_for_env\": {\"unique_id\": \"macro.dbt.generate_schema_name_for_env\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/etc/get_custom_schema.sql\", \"original_file_path\": \"macros/etc/get_custom_schema.sql\", \"name\": \"generate_schema_name_for_env\", \"macro_sql\": \"{% macro generate_schema_name_for_env(custom_schema_name, node) -%}\\n\\n    {%- set default_schema = target.schema -%}\\n    {%- if target.name == 'prod' and custom_schema_name is not none -%}\\n\\n        {{ custom_schema_name | trim }}\\n\\n    {%- else -%}\\n\\n        {{ default_schema }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.generate_database_name\": {\"unique_id\": \"macro.dbt.generate_database_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/etc/get_custom_database.sql\", \"original_file_path\": \"macros/etc/get_custom_database.sql\", \"name\": \"generate_database_name\", \"macro_sql\": \"{% macro generate_database_name(custom_database_name=none, node=none) -%}\\n    {% do return(adapter.dispatch('generate_database_name', 'dbt')(custom_database_name, node)) %}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__generate_database_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__generate_database_name\": {\"unique_id\": \"macro.dbt.default__generate_database_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/etc/get_custom_database.sql\", \"original_file_path\": \"macros/etc/get_custom_database.sql\", \"name\": \"default__generate_database_name\", \"macro_sql\": \"{% macro default__generate_database_name(custom_database_name=none, node=none) -%}\\n    {%- set default_database = target.database -%}\\n    {%- if custom_database_name is none -%}\\n\\n        {{ default_database }}\\n\\n    {%- else -%}\\n\\n        {{ custom_database_name }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.get_columns_in_query\": {\"unique_id\": \"macro.dbt.get_columns_in_query\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"get_columns_in_query\", \"macro_sql\": \"{% macro get_columns_in_query(select_sql) -%}\\n  {{ return(adapter.dispatch('get_columns_in_query', 'dbt')(select_sql)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_columns_in_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__get_columns_in_query\": {\"unique_id\": \"macro.dbt.default__get_columns_in_query\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__get_columns_in_query\", \"macro_sql\": \"{% macro default__get_columns_in_query(select_sql) %}\\n    {% call statement('get_columns_in_query', fetch_result=True, auto_begin=False) -%}\\n        select * from (\\n            {{ select_sql }}\\n        ) as __dbt_sbq\\n        where false\\n        limit 0\\n    {% endcall %}\\n\\n    {{ return(load_result('get_columns_in_query').table.columns | map(attribute='name') | list) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.create_schema\": {\"unique_id\": \"macro.dbt.create_schema\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"create_schema\", \"macro_sql\": \"{% macro create_schema(relation) -%}\\n  {{ adapter.dispatch('create_schema', 'dbt')(relation) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__create_schema\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__create_schema\": {\"unique_id\": \"macro.dbt.default__create_schema\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__create_schema\", \"macro_sql\": \"{% macro default__create_schema(relation) -%}\\n  {%- call statement('create_schema') -%}\\n    create schema if not exists {{ relation.without_identifier() }}\\n  {% endcall %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.drop_schema\": {\"unique_id\": \"macro.dbt.drop_schema\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"drop_schema\", \"macro_sql\": \"{% macro drop_schema(relation) -%}\\n  {{ adapter.dispatch('drop_schema', 'dbt')(relation) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__drop_schema\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__drop_schema\": {\"unique_id\": \"macro.dbt.default__drop_schema\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__drop_schema\", \"macro_sql\": \"{% macro default__drop_schema(relation) -%}\\n  {%- call statement('drop_schema') -%}\\n    drop schema if exists {{ relation.without_identifier() }} cascade\\n  {% endcall %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.create_table_as\": {\"unique_id\": \"macro.dbt.create_table_as\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"create_table_as\", \"macro_sql\": \"{% macro create_table_as(temporary, relation, sql) -%}\\n  {{ adapter.dispatch('create_table_as', 'dbt')(temporary, relation, sql) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__create_table_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__create_table_as\": {\"unique_id\": \"macro.dbt.default__create_table_as\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__create_table_as\", \"macro_sql\": \"{% macro default__create_table_as(temporary, relation, sql) -%}\\n  {%- set sql_header = config.get('sql_header', none) -%}\\n\\n  {{ sql_header if sql_header is not none }}\\n\\n  create {% if temporary: -%}temporary{%- endif %} table\\n    {{ relation.include(database=(not temporary), schema=(not temporary)) }}\\n  as (\\n    {{ sql }}\\n  );\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.get_create_index_sql\": {\"unique_id\": \"macro.dbt.get_create_index_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"get_create_index_sql\", \"macro_sql\": \"{% macro get_create_index_sql(relation, index_dict) -%}\\n  {{ return(adapter.dispatch('get_create_index_sql', 'dbt')(relation, index_dict)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_create_index_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__get_create_index_sql\": {\"unique_id\": \"macro.dbt.default__get_create_index_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__get_create_index_sql\", \"macro_sql\": \"{% macro default__get_create_index_sql(relation, index_dict) -%}\\n  {% do return(None) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.create_indexes\": {\"unique_id\": \"macro.dbt.create_indexes\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"create_indexes\", \"macro_sql\": \"{% macro create_indexes(relation) -%}\\n  {{ adapter.dispatch('create_indexes', 'dbt')(relation) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__create_indexes\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__create_indexes\": {\"unique_id\": \"macro.dbt.default__create_indexes\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__create_indexes\", \"macro_sql\": \"{% macro default__create_indexes(relation) -%}\\n  {%- set _indexes = config.get('indexes', default=[]) -%}\\n\\n  {% for _index_dict in _indexes %}\\n    {% set create_index_sql = get_create_index_sql(relation, _index_dict) %}\\n    {% if create_index_sql %}\\n      {% do run_query(create_index_sql) %}\\n    {% endif %}\\n  {% endfor %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_create_index_sql\", \"macro.dbt.run_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.create_view_as\": {\"unique_id\": \"macro.dbt.create_view_as\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"create_view_as\", \"macro_sql\": \"{% macro create_view_as(relation, sql) -%}\\n  {{ adapter.dispatch('create_view_as', 'dbt')(relation, sql) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__create_view_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__create_view_as\": {\"unique_id\": \"macro.dbt.default__create_view_as\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__create_view_as\", \"macro_sql\": \"{% macro default__create_view_as(relation, sql) -%}\\n  {%- set sql_header = config.get('sql_header', none) -%}\\n\\n  {{ sql_header if sql_header is not none }}\\n  create view {{ relation }} as (\\n    {{ sql }}\\n  );\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.get_catalog\": {\"unique_id\": \"macro.dbt.get_catalog\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"get_catalog\", \"macro_sql\": \"{% macro get_catalog(information_schema, schemas) -%}\\n  {{ return(adapter.dispatch('get_catalog', 'dbt')(information_schema, schemas)) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_catalog\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__get_catalog\": {\"unique_id\": \"macro.dbt.default__get_catalog\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__get_catalog\", \"macro_sql\": \"{% macro default__get_catalog(information_schema, schemas) -%}\\n\\n  {% set typename = adapter.type() %}\\n  {% set msg -%}\\n    get_catalog not implemented for {{ typename }}\\n  {%- endset %}\\n\\n  {{ exceptions.raise_compiler_error(msg) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.get_columns_in_relation\": {\"unique_id\": \"macro.dbt.get_columns_in_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"get_columns_in_relation\", \"macro_sql\": \"{% macro get_columns_in_relation(relation) -%}\\n  {{ return(adapter.dispatch('get_columns_in_relation', 'dbt')(relation)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_columns_in_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.sql_convert_columns_in_relation\": {\"unique_id\": \"macro.dbt.sql_convert_columns_in_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"sql_convert_columns_in_relation\", \"macro_sql\": \"{% macro sql_convert_columns_in_relation(table) -%}\\n  {% set columns = [] %}\\n  {% for row in table %}\\n    {% do columns.append(api.Column(*row)) %}\\n  {% endfor %}\\n  {{ return(columns) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__get_columns_in_relation\": {\"unique_id\": \"macro.dbt.default__get_columns_in_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__get_columns_in_relation\", \"macro_sql\": \"{% macro default__get_columns_in_relation(relation) -%}\\n  {{ exceptions.raise_not_implemented(\\n    'get_columns_in_relation macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.alter_column_type\": {\"unique_id\": \"macro.dbt.alter_column_type\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"alter_column_type\", \"macro_sql\": \"{% macro alter_column_type(relation, column_name, new_column_type) -%}\\n  {{ return(adapter.dispatch('alter_column_type', 'dbt')(relation, column_name, new_column_type)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__alter_column_type\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.alter_column_comment\": {\"unique_id\": \"macro.dbt.alter_column_comment\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"alter_column_comment\", \"macro_sql\": \"{% macro alter_column_comment(relation, column_dict) -%}\\n  {{ return(adapter.dispatch('alter_column_comment', 'dbt')(relation, column_dict)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__alter_column_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__alter_column_comment\": {\"unique_id\": \"macro.dbt.default__alter_column_comment\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__alter_column_comment\", \"macro_sql\": \"{% macro default__alter_column_comment(relation, column_dict) -%}\\n  {{ exceptions.raise_not_implemented(\\n    'alter_column_comment macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.alter_relation_comment\": {\"unique_id\": \"macro.dbt.alter_relation_comment\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"alter_relation_comment\", \"macro_sql\": \"{% macro alter_relation_comment(relation, relation_comment) -%}\\n  {{ return(adapter.dispatch('alter_relation_comment', 'dbt')(relation, relation_comment)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__alter_relation_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__alter_relation_comment\": {\"unique_id\": \"macro.dbt.default__alter_relation_comment\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__alter_relation_comment\", \"macro_sql\": \"{% macro default__alter_relation_comment(relation, relation_comment) -%}\\n  {{ exceptions.raise_not_implemented(\\n    'alter_relation_comment macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.persist_docs\": {\"unique_id\": \"macro.dbt.persist_docs\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"persist_docs\", \"macro_sql\": \"{% macro persist_docs(relation, model, for_relation=true, for_columns=true) -%}\\n  {{ return(adapter.dispatch('persist_docs', 'dbt')(relation, model, for_relation, for_columns)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__persist_docs\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__persist_docs\": {\"unique_id\": \"macro.dbt.default__persist_docs\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__persist_docs\", \"macro_sql\": \"{% macro default__persist_docs(relation, model, for_relation, for_columns) -%}\\n  {% if for_relation and config.persist_relation_docs() and model.description %}\\n    {% do run_query(alter_relation_comment(relation, model.description)) %}\\n  {% endif %}\\n\\n  {% if for_columns and config.persist_column_docs() and model.columns %}\\n    {% do run_query(alter_column_comment(relation, model.columns)) %}\\n  {% endif %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.run_query\", \"macro.dbt.alter_relation_comment\", \"macro.dbt.alter_column_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__alter_column_type\": {\"unique_id\": \"macro.dbt.default__alter_column_type\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__alter_column_type\", \"macro_sql\": \"{% macro default__alter_column_type(relation, column_name, new_column_type) -%}\\n  {#\\n    1. Create a new column (w/ temp name and correct type)\\n    2. Copy data over to it\\n    3. Drop the existing column (cascade!)\\n    4. Rename the new column to existing column\\n  #}\\n  {%- set tmp_column = column_name + \\\"__dbt_alter\\\" -%}\\n\\n  {% call statement('alter_column_type') %}\\n    alter table {{ relation }} add column {{ adapter.quote(tmp_column) }} {{ new_column_type }};\\n    update {{ relation }} set {{ adapter.quote(tmp_column) }} = {{ adapter.quote(column_name) }};\\n    alter table {{ relation }} drop column {{ adapter.quote(column_name) }} cascade;\\n    alter table {{ relation }} rename column {{ adapter.quote(tmp_column) }} to {{ adapter.quote(column_name) }}\\n  {% endcall %}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.drop_relation\": {\"unique_id\": \"macro.dbt.drop_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"drop_relation\", \"macro_sql\": \"{% macro drop_relation(relation) -%}\\n  {{ return(adapter.dispatch('drop_relation', 'dbt')(relation)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__drop_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__drop_relation\": {\"unique_id\": \"macro.dbt.default__drop_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__drop_relation\", \"macro_sql\": \"{% macro default__drop_relation(relation) -%}\\n  {% call statement('drop_relation', auto_begin=False) -%}\\n    drop {{ relation.type }} if exists {{ relation }} cascade\\n  {%- endcall %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.truncate_relation\": {\"unique_id\": \"macro.dbt.truncate_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"truncate_relation\", \"macro_sql\": \"{% macro truncate_relation(relation) -%}\\n  {{ return(adapter.dispatch('truncate_relation', 'dbt')(relation)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__truncate_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__truncate_relation\": {\"unique_id\": \"macro.dbt.default__truncate_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__truncate_relation\", \"macro_sql\": \"{% macro default__truncate_relation(relation) -%}\\n  {% call statement('truncate_relation') -%}\\n    truncate table {{ relation }}\\n  {%- endcall %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.rename_relation\": {\"unique_id\": \"macro.dbt.rename_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"rename_relation\", \"macro_sql\": \"{% macro rename_relation(from_relation, to_relation) -%}\\n  {{ return(adapter.dispatch('rename_relation', 'dbt')(from_relation, to_relation)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__rename_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__rename_relation\": {\"unique_id\": \"macro.dbt.default__rename_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__rename_relation\", \"macro_sql\": \"{% macro default__rename_relation(from_relation, to_relation) -%}\\n  {% set target_name = adapter.quote_as_configured(to_relation.identifier, 'identifier') %}\\n  {% call statement('rename_relation') -%}\\n    alter table {{ from_relation }} rename to {{ target_name }}\\n  {%- endcall %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.information_schema_name\": {\"unique_id\": \"macro.dbt.information_schema_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"information_schema_name\", \"macro_sql\": \"{% macro information_schema_name(database) %}\\n  {{ return(adapter.dispatch('information_schema_name', 'dbt')(database)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__information_schema_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__information_schema_name\": {\"unique_id\": \"macro.dbt.default__information_schema_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__information_schema_name\", \"macro_sql\": \"{% macro default__information_schema_name(database) -%}\\n  {%- if database -%}\\n    {{ database }}.INFORMATION_SCHEMA\\n  {%- else -%}\\n    INFORMATION_SCHEMA\\n  {%- endif -%}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.list_schemas\": {\"unique_id\": \"macro.dbt.list_schemas\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"list_schemas\", \"macro_sql\": \"{% macro list_schemas(database) -%}\\n  {{ return(adapter.dispatch('list_schemas', 'dbt')(database)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__list_schemas\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__list_schemas\": {\"unique_id\": \"macro.dbt.default__list_schemas\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__list_schemas\", \"macro_sql\": \"{% macro default__list_schemas(database) -%}\\n  {% set sql %}\\n    select distinct schema_name\\n    from {{ information_schema_name(database) }}.SCHEMATA\\n    where catalog_name ilike '{{ database }}'\\n  {% endset %}\\n  {{ return(run_query(sql)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.information_schema_name\", \"macro.dbt.run_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.check_schema_exists\": {\"unique_id\": \"macro.dbt.check_schema_exists\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"check_schema_exists\", \"macro_sql\": \"{% macro check_schema_exists(information_schema, schema) -%}\\n  {{ return(adapter.dispatch('check_schema_exists', 'dbt')(information_schema, schema)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__check_schema_exists\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__check_schema_exists\": {\"unique_id\": \"macro.dbt.default__check_schema_exists\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__check_schema_exists\", \"macro_sql\": \"{% macro default__check_schema_exists(information_schema, schema) -%}\\n  {% set sql -%}\\n        select count(*)\\n        from {{ information_schema.replace(information_schema_view='SCHEMATA') }}\\n        where catalog_name='{{ information_schema.database }}'\\n          and schema_name='{{ schema }}'\\n  {%- endset %}\\n  {{ return(run_query(sql)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.run_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.list_relations_without_caching\": {\"unique_id\": \"macro.dbt.list_relations_without_caching\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"list_relations_without_caching\", \"macro_sql\": \"{% macro list_relations_without_caching(schema_relation) %}\\n  {{ return(adapter.dispatch('list_relations_without_caching', 'dbt')(schema_relation)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.test.postgres__list_relations_without_caching\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__list_relations_without_caching\": {\"unique_id\": \"macro.dbt.default__list_relations_without_caching\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__list_relations_without_caching\", \"macro_sql\": \"{% macro default__list_relations_without_caching(schema_relation) %}\\n  {{ exceptions.raise_not_implemented(\\n    'list_relations_without_caching macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.current_timestamp\": {\"unique_id\": \"macro.dbt.current_timestamp\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"current_timestamp\", \"macro_sql\": \"{% macro current_timestamp() -%}\\n  {{ adapter.dispatch('current_timestamp', 'dbt')() }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__current_timestamp\": {\"unique_id\": \"macro.dbt.default__current_timestamp\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__current_timestamp\", \"macro_sql\": \"{% macro default__current_timestamp() -%}\\n  {{ exceptions.raise_not_implemented(\\n    'current_timestamp macro not implemented for adapter '+adapter.type()) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.collect_freshness\": {\"unique_id\": \"macro.dbt.collect_freshness\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"collect_freshness\", \"macro_sql\": \"{% macro collect_freshness(source, loaded_at_field, filter) %}\\n  {{ return(adapter.dispatch('collect_freshness', 'dbt')(source, loaded_at_field, filter))}}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__collect_freshness\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__collect_freshness\": {\"unique_id\": \"macro.dbt.default__collect_freshness\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__collect_freshness\", \"macro_sql\": \"{% macro default__collect_freshness(source, loaded_at_field, filter) %}\\n  {% call statement('collect_freshness', fetch_result=True, auto_begin=False) -%}\\n    select\\n      max({{ loaded_at_field }}) as max_loaded_at,\\n      {{ current_timestamp() }} as snapshotted_at\\n    from {{ source }}\\n    {% if filter %}\\n    where {{ filter }}\\n    {% endif %}\\n  {% endcall %}\\n  {{ return(load_result('collect_freshness').table) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\", \"macro.dbt.current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.make_temp_relation\": {\"unique_id\": \"macro.dbt.make_temp_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"make_temp_relation\", \"macro_sql\": \"{% macro make_temp_relation(base_relation, suffix='__dbt_tmp') %}\\n  {{ return(adapter.dispatch('make_temp_relation', 'dbt')(base_relation, suffix))}}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_temp_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__make_temp_relation\": {\"unique_id\": \"macro.dbt.default__make_temp_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__make_temp_relation\", \"macro_sql\": \"{% macro default__make_temp_relation(base_relation, suffix) %}\\n    {% set tmp_identifier = base_relation.identifier ~ suffix %}\\n    {% set tmp_relation = base_relation.incorporate(\\n                                path={\\\"identifier\\\": tmp_identifier}) -%}\\n\\n    {% do return(tmp_relation) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.set_sql_header\": {\"unique_id\": \"macro.dbt.set_sql_header\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"set_sql_header\", \"macro_sql\": \"{% macro set_sql_header(config) -%}\\n  {{ config.set('sql_header', caller()) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.alter_relation_add_remove_columns\": {\"unique_id\": \"macro.dbt.alter_relation_add_remove_columns\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"alter_relation_add_remove_columns\", \"macro_sql\": \"{% macro alter_relation_add_remove_columns(relation, add_columns = none, remove_columns = none) -%}\\n  {{ return(adapter.dispatch('alter_relation_add_remove_columns', 'dbt')(relation, add_columns, remove_columns)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__alter_relation_add_remove_columns\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__alter_relation_add_remove_columns\": {\"unique_id\": \"macro.dbt.default__alter_relation_add_remove_columns\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/adapters/common.sql\", \"original_file_path\": \"macros/adapters/common.sql\", \"name\": \"default__alter_relation_add_remove_columns\", \"macro_sql\": \"{% macro default__alter_relation_add_remove_columns(relation, add_columns, remove_columns) %}\\n  \\n  {% if add_columns is none %}\\n    {% set add_columns = [] %}\\n  {% endif %}\\n  {% if remove_columns is none %}\\n    {% set remove_columns = [] %}\\n  {% endif %}\\n  \\n  {% set sql -%}\\n     \\n     alter {{ relation.type }} {{ relation }}\\n       \\n            {% for column in add_columns %}\\n               add column {{ column.name }} {{ column.data_type }}{{ ',' if not loop.last }}\\n            {% endfor %}{{ ',' if add_columns and remove_columns }}\\n            \\n            {% for column in remove_columns %}\\n                drop column {{ column.name }}{{ ',' if not loop.last }}\\n            {% endfor %}\\n  \\n  {%- endset -%}\\n\\n  {% do run_query(sql) %}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.run_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__test_relationships\": {\"unique_id\": \"macro.dbt.default__test_relationships\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/schema_tests/relationships.sql\", \"original_file_path\": \"macros/schema_tests/relationships.sql\", \"name\": \"default__test_relationships\", \"macro_sql\": \"{% macro default__test_relationships(model, column_name, to, field) %}\\n\\nwith child as (\\n    select {{ column_name }} as from_field\\n    from {{ model }}\\n    where {{ column_name }} is not null\\n),\\n\\nparent as (\\n    select {{ field }} as to_field\\n    from {{ to }}\\n)\\n\\nselect\\n    from_field\\n\\nfrom child\\nleft join parent\\n    on child.from_field = parent.to_field\\n\\nwhere parent.to_field is null\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.test_relationships\": {\"unique_id\": \"macro.dbt.test_relationships\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/schema_tests/relationships.sql\", \"original_file_path\": \"macros/schema_tests/relationships.sql\", \"name\": \"test_relationships\", \"macro_sql\": \"{% test relationships(model, column_name, to, field) %}\\n    {% set macro = adapter.dispatch('test_relationships', 'dbt') %}\\n    {{ macro(model, column_name, to, field) }}\\n{% endtest %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__test_relationships\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__test_not_null\": {\"unique_id\": \"macro.dbt.default__test_not_null\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/schema_tests/not_null.sql\", \"original_file_path\": \"macros/schema_tests/not_null.sql\", \"name\": \"default__test_not_null\", \"macro_sql\": \"{% macro default__test_not_null(model, column_name) %}\\n\\nselect *\\nfrom {{ model }}\\nwhere {{ column_name }} is null\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.test_not_null\": {\"unique_id\": \"macro.dbt.test_not_null\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/schema_tests/not_null.sql\", \"original_file_path\": \"macros/schema_tests/not_null.sql\", \"name\": \"test_not_null\", \"macro_sql\": \"{% test not_null(model, column_name) %}\\n    {% set macro = adapter.dispatch('test_not_null', 'dbt') %}\\n    {{ macro(model, column_name) }}\\n{% endtest %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__test_not_null\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__test_unique\": {\"unique_id\": \"macro.dbt.default__test_unique\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/schema_tests/unique.sql\", \"original_file_path\": \"macros/schema_tests/unique.sql\", \"name\": \"default__test_unique\", \"macro_sql\": \"{% macro default__test_unique(model, column_name) %}\\n\\nselect\\n    {{ column_name }} as unique_field,\\n    count(*) as n_records\\n\\nfrom {{ model }}\\nwhere {{ column_name }} is not null\\ngroup by {{ column_name }}\\nhaving count(*) > 1\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.test_unique\": {\"unique_id\": \"macro.dbt.test_unique\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/schema_tests/unique.sql\", \"original_file_path\": \"macros/schema_tests/unique.sql\", \"name\": \"test_unique\", \"macro_sql\": \"{% test unique(model, column_name) %}\\n    {% set macro = adapter.dispatch('test_unique', 'dbt') %}\\n    {{ macro(model, column_name) }}\\n{% endtest %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__test_unique\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.default__test_accepted_values\": {\"unique_id\": \"macro.dbt.default__test_accepted_values\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/schema_tests/accepted_values.sql\", \"original_file_path\": \"macros/schema_tests/accepted_values.sql\", \"name\": \"default__test_accepted_values\", \"macro_sql\": \"{% macro default__test_accepted_values(model, column_name, values, quote=True) %}\\n\\nwith all_values as (\\n\\n    select\\n        {{ column_name }} as value_field,\\n        count(*) as n_records\\n\\n    from {{ model }}\\n    group by {{ column_name }}\\n\\n)\\n\\nselect *\\nfrom all_values\\nwhere value_field not in (\\n    {% for value in values -%}\\n        {% if quote -%}\\n        '{{ value }}'\\n        {%- else -%}\\n        {{ value }}\\n        {%- endif -%}\\n        {%- if not loop.last -%},{%- endif %}\\n    {%- endfor %}\\n)\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}, \"macro.dbt.test_accepted_values\": {\"unique_id\": \"macro.dbt.test_accepted_values\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"macros/schema_tests/accepted_values.sql\", \"original_file_path\": \"macros/schema_tests/accepted_values.sql\", \"name\": \"test_accepted_values\", \"macro_sql\": \"{% test accepted_values(model, column_name, values, quote=True) %}\\n    {% set macro = adapter.dispatch('test_accepted_values', 'dbt') %}\\n    {{ macro(model, column_name, values, quote) }}\\n{% endtest %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__test_accepted_values\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1654665147}}, \"docs\": {\"dbt.__overview__\": {\"unique_id\": \"dbt.__overview__\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/product/dbt-core/core/dbt/include/global_project\", \"path\": \"overview.md\", \"original_file_path\": \"docs/overview.md\", \"name\": \"__overview__\", \"block_contents\": \"### Welcome!\\n\\nWelcome to the auto-generated documentation for your dbt project!\\n\\n### Navigation\\n\\nYou can use the `Project` and `Database` navigation tabs on the left side of the window to explore the models\\nin your project.\\n\\n#### Project Tab\\nThe `Project` tab mirrors the directory structure of your dbt project. In this tab, you can see all of the\\nmodels defined in your dbt project, as well as models imported from dbt packages.\\n\\n#### Database Tab\\nThe `Database` tab also exposes your models, but in a format that looks more like a database explorer. This view\\nshows relations (tables and views) grouped into database schemas. Note that ephemeral models are _not_ shown\\nin this interface, as they do not exist in the database.\\n\\n### Graph Exploration\\nYou can click the blue icon on the bottom-right corner of the page to view the lineage graph of your models.\\n\\nOn model pages, you'll see the immediate parents and children of the model you're exploring. By clicking the `Expand`\\nbutton at the top-right of this lineage pane, you'll be able to see all of the models that are used to build,\\nor are built from, the model you're exploring.\\n\\nOnce expanded, you'll be able to use the `--models` and `--exclude` model selection syntax to filter the\\nmodels in the graph. For more information on model selection, check out the [dbt docs](https://docs.getdbt.com/docs/model-selection-syntax).\\n\\nNote that you can also right-click on models to interactively filter and explore the graph.\\n\\n---\\n\\n### More information\\n\\n- [What is dbt](https://docs.getdbt.com/docs/overview)?\\n- Read the [dbt viewpoint](https://docs.getdbt.com/docs/viewpoint)\\n- [Installation](https://docs.getdbt.com/docs/installation)\\n- Join the [chat](https://community.getdbt.com/) on Slack for live questions and support.\"}}, \"exposures\": {}, \"selectors\": {}, \"disabled\": [], \"parent_map\": {\"model.test.my_model\": []}, \"child_map\": {\"model.test.my_model\": []}}\n"
  },
  {
    "path": "tests/functional/artifacts/data/state/v4/manifest.json",
    "content": "{\"metadata\": {\"dbt_schema_version\": \"https://schemas.getdbt.com/dbt/manifest/v4.json\", \"dbt_version\": \"1.0.8\", \"generated_at\": \"2022-09-13T08:43:20.641750Z\", \"invocation_id\": \"5da6faab-41cb-4180-ab19-8375c0e1f1a5\", \"env\": {}, \"project_id\": \"098f6bcd4621d373cade4e832627b4f6\", \"user_id\": null, \"send_anonymous_usage_stats\": false, \"adapter_type\": \"postgres\"}, \"nodes\": {\"model.test.my_model\": {\"raw_sql\": \"select 1 as id\", \"resource_type\": \"model\", \"depends_on\": {\"macros\": [], \"nodes\": []}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"materialized\": \"view\", \"persist_docs\": {}, \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"on_schema_change\": \"ignore\", \"post-hook\": [], \"pre-hook\": []}, \"database\": \"jerco\", \"schema\": \"dbt_jcohen\", \"fqn\": [\"test\", \"my_model\"], \"unique_id\": \"model.test.my_model\", \"package_name\": \"test\", \"root_path\": \"/Users/jerco/dev/scratch/testy\", \"path\": \"my_model.sql\", \"original_file_path\": \"models/my_model.sql\", \"name\": \"my_model\", \"alias\": \"my_model\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"479636cb85ce8d3b0f8db5ff13cf338b61254ad98d905630eac61f963e719e9d\"}, \"tags\": [], \"refs\": [], \"sources\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"compiled_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {}, \"created_at\": 1663058601.2387}}, \"sources\": {}, \"macros\": {\"macro.dbt_postgres.postgres__get_catalog\": {\"unique_id\": \"macro.dbt_postgres.postgres__get_catalog\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/catalog.sql\", \"original_file_path\": \"macros/catalog.sql\", \"name\": \"postgres__get_catalog\", \"macro_sql\": \"{% macro postgres__get_catalog(information_schema, schemas) -%}\\n\\n  {%- call statement('catalog', fetch_result=True) -%}\\n    {#\\n      If the user has multiple databases set and the first one is wrong, this will fail.\\n      But we won't fail in the case where there are multiple quoting-difference-only dbs, which is better.\\n    #}\\n    {% set database = information_schema.database %}\\n    {{ adapter.verify_database(database) }}\\n\\n    select\\n        '{{ database }}' as table_database,\\n        sch.nspname as table_schema,\\n        tbl.relname as table_name,\\n        case tbl.relkind\\n            when 'v' then 'VIEW'\\n            else 'BASE TABLE'\\n        end as table_type,\\n        tbl_desc.description as table_comment,\\n        col.attname as column_name,\\n        col.attnum as column_index,\\n        pg_catalog.format_type(col.atttypid, col.atttypmod) as column_type,\\n        col_desc.description as column_comment,\\n        pg_get_userbyid(tbl.relowner) as table_owner\\n\\n    from pg_catalog.pg_namespace sch\\n    join pg_catalog.pg_class tbl on tbl.relnamespace = sch.oid\\n    join pg_catalog.pg_attribute col on col.attrelid = tbl.oid\\n    left outer join pg_catalog.pg_description tbl_desc on (tbl_desc.objoid = tbl.oid and tbl_desc.objsubid = 0)\\n    left outer join pg_catalog.pg_description col_desc on (col_desc.objoid = tbl.oid and col_desc.objsubid = col.attnum)\\n\\n    where (\\n        {%- for schema in schemas -%}\\n          upper(sch.nspname) = upper('{{ schema }}'){%- if not loop.last %} or {% endif -%}\\n        {%- endfor -%}\\n      )\\n      and not pg_is_other_temp_schema(sch.oid) -- not a temporary schema belonging to another session\\n      and tbl.relpersistence in ('p', 'u') -- [p]ermanent table or [u]nlogged table. Exclude [t]emporary tables\\n      and tbl.relkind in ('r', 'v', 'f', 'p') -- o[r]dinary table, [v]iew, [f]oreign table, [p]artitioned table. Other values are [i]ndex, [S]equence, [c]omposite type, [t]OAST table, [m]aterialized view\\n      and col.attnum > 0 -- negative numbers are used for system columns such as oid\\n      and not col.attisdropped -- column as not been dropped\\n\\n    order by\\n        sch.nspname,\\n        tbl.relname,\\n        col.attnum\\n\\n  {%- endcall -%}\\n\\n  {{ return(load_result('catalog').table) }}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.6944451}, \"macro.dbt_postgres.postgres_get_relations\": {\"unique_id\": \"macro.dbt_postgres.postgres_get_relations\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/relations.sql\", \"original_file_path\": \"macros/relations.sql\", \"name\": \"postgres_get_relations\", \"macro_sql\": \"{% macro postgres_get_relations () -%}\\n\\n  {#\\n      -- in pg_depend, objid is the dependent, refobjid is the referenced object\\n      --  > a pg_depend entry indicates that the referenced object cannot be\\n      --  > dropped without also dropping the dependent object.\\n  #}\\n\\n  {%- call statement('relations', fetch_result=True) -%}\\n    with relation as (\\n        select\\n            pg_rewrite.ev_class as class,\\n            pg_rewrite.oid as id\\n        from pg_rewrite\\n    ),\\n    class as (\\n        select\\n            oid as id,\\n            relname as name,\\n            relnamespace as schema,\\n            relkind as kind\\n        from pg_class\\n    ),\\n    dependency as (\\n        select\\n            pg_depend.objid as id,\\n            pg_depend.refobjid as ref\\n        from pg_depend\\n    ),\\n    schema as (\\n        select\\n            pg_namespace.oid as id,\\n            pg_namespace.nspname as name\\n        from pg_namespace\\n        where nspname != 'information_schema' and nspname not like 'pg\\\\_%'\\n    ),\\n    referenced as (\\n        select\\n            relation.id AS id,\\n            referenced_class.name ,\\n            referenced_class.schema ,\\n            referenced_class.kind\\n        from relation\\n        join class as referenced_class on relation.class=referenced_class.id\\n        where referenced_class.kind in ('r', 'v')\\n    ),\\n    relationships as (\\n        select\\n            referenced.name as referenced_name,\\n            referenced.schema as referenced_schema_id,\\n            dependent_class.name as dependent_name,\\n            dependent_class.schema as dependent_schema_id,\\n            referenced.kind as kind\\n        from referenced\\n        join dependency on referenced.id=dependency.id\\n        join class as dependent_class on dependency.ref=dependent_class.id\\n        where\\n            (referenced.name != dependent_class.name or\\n             referenced.schema != dependent_class.schema)\\n    )\\n\\n    select\\n        referenced_schema.name as referenced_schema,\\n        relationships.referenced_name as referenced_name,\\n        dependent_schema.name as dependent_schema,\\n        relationships.dependent_name as dependent_name\\n    from relationships\\n    join schema as dependent_schema on relationships.dependent_schema_id=dependent_schema.id\\n    join schema as referenced_schema on relationships.referenced_schema_id=referenced_schema.id\\n    group by referenced_schema, referenced_name, dependent_schema, dependent_name\\n    order by referenced_schema, referenced_name, dependent_schema, dependent_name;\\n\\n  {%- endcall -%}\\n\\n  {{ return(load_result('relations').table) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.696331}, \"macro.dbt_postgres.postgres__create_table_as\": {\"unique_id\": \"macro.dbt_postgres.postgres__create_table_as\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__create_table_as\", \"macro_sql\": \"{% macro postgres__create_table_as(temporary, relation, sql) -%}\\n  {%- set unlogged = config.get('unlogged', default=false) -%}\\n  {%- set sql_header = config.get('sql_header', none) -%}\\n\\n  {{ sql_header if sql_header is not none }}\\n\\n  create {% if temporary -%}\\n    temporary\\n  {%- elif unlogged -%}\\n    unlogged\\n  {%- endif %} table {{ relation }}\\n  as (\\n    {{ sql }}\\n  );\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.712787}, \"macro.dbt_postgres.postgres__get_create_index_sql\": {\"unique_id\": \"macro.dbt_postgres.postgres__get_create_index_sql\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__get_create_index_sql\", \"macro_sql\": \"{% macro postgres__get_create_index_sql(relation, index_dict) -%}\\n  {%- set index_config = adapter.parse_index(index_dict) -%}\\n  {%- set comma_separated_columns = \\\", \\\".join(index_config.columns) -%}\\n  {%- set index_name = index_config.render(relation) -%}\\n\\n  create {% if index_config.unique -%}\\n    unique\\n  {%- endif %} index if not exists\\n  \\\"{{ index_name }}\\\"\\n  on {{ relation }} {% if index_config.type -%}\\n    using {{ index_config.type }}\\n  {%- endif %}\\n  ({{ comma_separated_columns }});\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.714135}, \"macro.dbt_postgres.postgres__create_schema\": {\"unique_id\": \"macro.dbt_postgres.postgres__create_schema\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__create_schema\", \"macro_sql\": \"{% macro postgres__create_schema(relation) -%}\\n  {% if relation.database -%}\\n    {{ adapter.verify_database(relation.database) }}\\n  {%- endif -%}\\n  {%- call statement('create_schema') -%}\\n    create schema if not exists {{ relation.without_identifier().include(database=False) }}\\n  {%- endcall -%}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.714985}, \"macro.dbt_postgres.postgres__drop_schema\": {\"unique_id\": \"macro.dbt_postgres.postgres__drop_schema\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__drop_schema\", \"macro_sql\": \"{% macro postgres__drop_schema(relation) -%}\\n  {% if relation.database -%}\\n    {{ adapter.verify_database(relation.database) }}\\n  {%- endif -%}\\n  {%- call statement('drop_schema') -%}\\n    drop schema if exists {{ relation.without_identifier().include(database=False) }} cascade\\n  {%- endcall -%}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.7158241}, \"macro.dbt_postgres.postgres__get_columns_in_relation\": {\"unique_id\": \"macro.dbt_postgres.postgres__get_columns_in_relation\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__get_columns_in_relation\", \"macro_sql\": \"{% macro postgres__get_columns_in_relation(relation) -%}\\n  {% call statement('get_columns_in_relation', fetch_result=True) %}\\n      select\\n          column_name,\\n          data_type,\\n          character_maximum_length,\\n          numeric_precision,\\n          numeric_scale\\n\\n      from {{ relation.information_schema('columns') }}\\n      where table_name = '{{ relation.identifier }}'\\n        {% if relation.schema %}\\n        and table_schema = '{{ relation.schema }}'\\n        {% endif %}\\n      order by ordinal_position\\n\\n  {% endcall %}\\n  {% set table = load_result('get_columns_in_relation').table %}\\n  {{ return(sql_convert_columns_in_relation(table)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\", \"macro.dbt.sql_convert_columns_in_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.717091}, \"macro.dbt_postgres.postgres__list_relations_without_caching\": {\"unique_id\": \"macro.dbt_postgres.postgres__list_relations_without_caching\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__list_relations_without_caching\", \"macro_sql\": \"{% macro postgres__list_relations_without_caching(schema_relation) %}\\n  {% call statement('list_relations_without_caching', fetch_result=True) -%}\\n    select\\n      '{{ schema_relation.database }}' as database,\\n      tablename as name,\\n      schemaname as schema,\\n      'table' as type\\n    from pg_tables\\n    where schemaname ilike '{{ schema_relation.schema }}'\\n    union all\\n    select\\n      '{{ schema_relation.database }}' as database,\\n      viewname as name,\\n      schemaname as schema,\\n      'view' as type\\n    from pg_views\\n    where schemaname ilike '{{ schema_relation.schema }}'\\n  {% endcall %}\\n  {{ return(load_result('list_relations_without_caching').table) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.718103}, \"macro.dbt_postgres.postgres__information_schema_name\": {\"unique_id\": \"macro.dbt_postgres.postgres__information_schema_name\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__information_schema_name\", \"macro_sql\": \"{% macro postgres__information_schema_name(database) -%}\\n  {% if database_name -%}\\n    {{ adapter.verify_database(database_name) }}\\n  {%- endif -%}\\n  information_schema\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.7185578}, \"macro.dbt_postgres.postgres__list_schemas\": {\"unique_id\": \"macro.dbt_postgres.postgres__list_schemas\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__list_schemas\", \"macro_sql\": \"{% macro postgres__list_schemas(database) %}\\n  {% if database -%}\\n    {{ adapter.verify_database(database) }}\\n  {%- endif -%}\\n  {% call statement('list_schemas', fetch_result=True, auto_begin=False) %}\\n    select distinct nspname from pg_namespace\\n  {% endcall %}\\n  {{ return(load_result('list_schemas').table) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.7194948}, \"macro.dbt_postgres.postgres__check_schema_exists\": {\"unique_id\": \"macro.dbt_postgres.postgres__check_schema_exists\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__check_schema_exists\", \"macro_sql\": \"{% macro postgres__check_schema_exists(information_schema, schema) -%}\\n  {% if information_schema.database -%}\\n    {{ adapter.verify_database(information_schema.database) }}\\n  {%- endif -%}\\n  {% call statement('check_schema_exists', fetch_result=True, auto_begin=False) %}\\n    select count(*) from pg_namespace where nspname = '{{ schema }}'\\n  {% endcall %}\\n  {{ return(load_result('check_schema_exists').table) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.720533}, \"macro.dbt_postgres.postgres__current_timestamp\": {\"unique_id\": \"macro.dbt_postgres.postgres__current_timestamp\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__current_timestamp\", \"macro_sql\": \"{% macro postgres__current_timestamp() -%}\\n  now()\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.720746}, \"macro.dbt_postgres.postgres__snapshot_string_as_time\": {\"unique_id\": \"macro.dbt_postgres.postgres__snapshot_string_as_time\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__snapshot_string_as_time\", \"macro_sql\": \"{% macro postgres__snapshot_string_as_time(timestamp) -%}\\n    {%- set result = \\\"'\\\" ~ timestamp ~ \\\"'::timestamp without time zone\\\" -%}\\n    {{ return(result) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.72122}, \"macro.dbt_postgres.postgres__snapshot_get_time\": {\"unique_id\": \"macro.dbt_postgres.postgres__snapshot_get_time\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__snapshot_get_time\", \"macro_sql\": \"{% macro postgres__snapshot_get_time() -%}\\n  {{ current_timestamp() }}::timestamp without time zone\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.721492}, \"macro.dbt_postgres.postgres__make_temp_relation\": {\"unique_id\": \"macro.dbt_postgres.postgres__make_temp_relation\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__make_temp_relation\", \"macro_sql\": \"{% macro postgres__make_temp_relation(base_relation, suffix) %}\\n    {% set dt = modules.datetime.datetime.now() %}\\n    {% set dtstring = dt.strftime(\\\"%H%M%S%f\\\") %}\\n    {% set suffix_length = suffix|length + dtstring|length %}\\n    {% set relation_max_name_length = 63 %}\\n    {% if suffix_length > relation_max_name_length %}\\n        {% do exceptions.raise_compiler_error('Temp relation suffix is too long (' ~ suffix|length ~ ' characters). Maximum length is ' ~ (relation_max_name_length - dtstring|length) ~ ' characters.') %}\\n    {% endif %}\\n    {% set tmp_identifier = base_relation.identifier[:relation_max_name_length - suffix_length] ~ suffix ~ dtstring %}\\n    {% do return(base_relation.incorporate(\\n                                  path={\\n                                    \\\"identifier\\\": tmp_identifier,\\n                                    \\\"schema\\\": none,\\n                                    \\\"database\\\": none\\n                                  })) -%}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.7240572}, \"macro.dbt_postgres.postgres_escape_comment\": {\"unique_id\": \"macro.dbt_postgres.postgres_escape_comment\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres_escape_comment\", \"macro_sql\": \"{% macro postgres_escape_comment(comment) -%}\\n  {% if comment is not string %}\\n    {% do exceptions.raise_compiler_error('cannot escape a non-string: ' ~ comment) %}\\n  {% endif %}\\n  {%- set magic = '$dbt_comment_literal_block$' -%}\\n  {%- if magic in comment -%}\\n    {%- do exceptions.raise_compiler_error('The string ' ~ magic ~ ' is not allowed in comments.') -%}\\n  {%- endif -%}\\n  {{ magic }}{{ comment }}{{ magic }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.7252119}, \"macro.dbt_postgres.postgres__alter_relation_comment\": {\"unique_id\": \"macro.dbt_postgres.postgres__alter_relation_comment\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__alter_relation_comment\", \"macro_sql\": \"{% macro postgres__alter_relation_comment(relation, comment) %}\\n  {% set escaped_comment = postgres_escape_comment(comment) %}\\n  comment on {{ relation.type }} {{ relation }} is {{ escaped_comment }};\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres_escape_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.7258098}, \"macro.dbt_postgres.postgres__alter_column_comment\": {\"unique_id\": \"macro.dbt_postgres.postgres__alter_column_comment\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__alter_column_comment\", \"macro_sql\": \"{% macro postgres__alter_column_comment(relation, column_dict) %}\\n  {% set existing_columns = adapter.get_columns_in_relation(relation) | map(attribute=\\\"name\\\") | list %}\\n  {% for column_name in column_dict if (column_name in existing_columns) %}\\n    {% set comment = column_dict[column_name]['description'] %}\\n    {% set escaped_comment = postgres_escape_comment(comment) %}\\n    comment on column {{ relation }}.{{ adapter.quote(column_name) if column_dict[column_name]['quote'] else column_name }} is {{ escaped_comment }};\\n  {% endfor %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres_escape_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.727401}, \"macro.dbt_postgres.postgres__snapshot_merge_sql\": {\"unique_id\": \"macro.dbt_postgres.postgres__snapshot_merge_sql\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/materializations/snapshot_merge.sql\", \"original_file_path\": \"macros/materializations/snapshot_merge.sql\", \"name\": \"postgres__snapshot_merge_sql\", \"macro_sql\": \"{% macro postgres__snapshot_merge_sql(target, source, insert_cols) -%}\\n    {%- set insert_cols_csv = insert_cols | join(', ') -%}\\n\\n    update {{ target }}\\n    set dbt_valid_to = DBT_INTERNAL_SOURCE.dbt_valid_to\\n    from {{ source }} as DBT_INTERNAL_SOURCE\\n    where DBT_INTERNAL_SOURCE.dbt_scd_id::text = {{ target }}.dbt_scd_id::text\\n      and DBT_INTERNAL_SOURCE.dbt_change_type::text in ('update'::text, 'delete'::text)\\n      and {{ target }}.dbt_valid_to is null;\\n\\n    insert into {{ target }} ({{ insert_cols_csv }})\\n    select {% for column in insert_cols -%}\\n        DBT_INTERNAL_SOURCE.{{ column }} {%- if not loop.last %}, {%- endif %}\\n    {%- endfor %}\\n    from {{ source }} as DBT_INTERNAL_SOURCE\\n    where DBT_INTERNAL_SOURCE.dbt_change_type::text = 'insert'::text;\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.729517}, \"macro.dbt.run_hooks\": {\"unique_id\": \"macro.dbt.run_hooks\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"name\": \"run_hooks\", \"macro_sql\": \"{% macro run_hooks(hooks, inside_transaction=True) %}\\n  {% for hook in hooks | selectattr('transaction', 'equalto', inside_transaction)  %}\\n    {% if not inside_transaction and loop.first %}\\n      {% call statement(auto_begin=inside_transaction) %}\\n        commit;\\n      {% endcall %}\\n    {% endif %}\\n    {% set rendered = render(hook.get('sql')) | trim %}\\n    {% if (rendered | length) > 0 %}\\n      {% call statement(auto_begin=inside_transaction) %}\\n        {{ rendered }}\\n      {% endcall %}\\n    {% endif %}\\n  {% endfor %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.732625}, \"macro.dbt.make_hook_config\": {\"unique_id\": \"macro.dbt.make_hook_config\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"name\": \"make_hook_config\", \"macro_sql\": \"{% macro make_hook_config(sql, inside_transaction) %}\\n    {{ tojson({\\\"sql\\\": sql, \\\"transaction\\\": inside_transaction}) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.7331321}, \"macro.dbt.before_begin\": {\"unique_id\": \"macro.dbt.before_begin\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"name\": \"before_begin\", \"macro_sql\": \"{% macro before_begin(sql) %}\\n    {{ make_hook_config(sql, inside_transaction=False) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.make_hook_config\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.7335098}, \"macro.dbt.in_transaction\": {\"unique_id\": \"macro.dbt.in_transaction\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"name\": \"in_transaction\", \"macro_sql\": \"{% macro in_transaction(sql) %}\\n    {{ make_hook_config(sql, inside_transaction=True) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.make_hook_config\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.733889}, \"macro.dbt.after_commit\": {\"unique_id\": \"macro.dbt.after_commit\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"name\": \"after_commit\", \"macro_sql\": \"{% macro after_commit(sql) %}\\n    {{ make_hook_config(sql, inside_transaction=False) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.make_hook_config\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.7342541}, \"macro.dbt.set_sql_header\": {\"unique_id\": \"macro.dbt.set_sql_header\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/configs.sql\", \"original_file_path\": \"macros/materializations/configs.sql\", \"name\": \"set_sql_header\", \"macro_sql\": \"{% macro set_sql_header(config) -%}\\n  {{ config.set('sql_header', caller()) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.735413}, \"macro.dbt.should_full_refresh\": {\"unique_id\": \"macro.dbt.should_full_refresh\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/configs.sql\", \"original_file_path\": \"macros/materializations/configs.sql\", \"name\": \"should_full_refresh\", \"macro_sql\": \"{% macro should_full_refresh() %}\\n  {% set config_full_refresh = config.get('full_refresh') %}\\n  {% if config_full_refresh is none %}\\n    {% set config_full_refresh = flags.FULL_REFRESH %}\\n  {% endif %}\\n  {% do return(config_full_refresh) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.736206}, \"macro.dbt.should_store_failures\": {\"unique_id\": \"macro.dbt.should_store_failures\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/configs.sql\", \"original_file_path\": \"macros/materializations/configs.sql\", \"name\": \"should_store_failures\", \"macro_sql\": \"{% macro should_store_failures() %}\\n  {% set config_store_failures = config.get('store_failures') %}\\n  {% if config_store_failures is none %}\\n    {% set config_store_failures = flags.STORE_FAILURES %}\\n  {% endif %}\\n  {% do return(config_store_failures) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.737014}, \"macro.dbt.snapshot_merge_sql\": {\"unique_id\": \"macro.dbt.snapshot_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/snapshot_merge.sql\", \"original_file_path\": \"macros/materializations/snapshots/snapshot_merge.sql\", \"name\": \"snapshot_merge_sql\", \"macro_sql\": \"{% macro snapshot_merge_sql(target, source, insert_cols) -%}\\n  {{ adapter.dispatch('snapshot_merge_sql', 'dbt')(target, source, insert_cols) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__snapshot_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.738338}, \"macro.dbt.default__snapshot_merge_sql\": {\"unique_id\": \"macro.dbt.default__snapshot_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/snapshot_merge.sql\", \"original_file_path\": \"macros/materializations/snapshots/snapshot_merge.sql\", \"name\": \"default__snapshot_merge_sql\", \"macro_sql\": \"{% macro default__snapshot_merge_sql(target, source, insert_cols) -%}\\n    {%- set insert_cols_csv = insert_cols | join(', ') -%}\\n\\n    merge into {{ target }} as DBT_INTERNAL_DEST\\n    using {{ source }} as DBT_INTERNAL_SOURCE\\n    on DBT_INTERNAL_SOURCE.dbt_scd_id = DBT_INTERNAL_DEST.dbt_scd_id\\n\\n    when matched\\n     and DBT_INTERNAL_DEST.dbt_valid_to is null\\n     and DBT_INTERNAL_SOURCE.dbt_change_type in ('update', 'delete')\\n        then update\\n        set dbt_valid_to = DBT_INTERNAL_SOURCE.dbt_valid_to\\n\\n    when not matched\\n     and DBT_INTERNAL_SOURCE.dbt_change_type = 'insert'\\n        then insert ({{ insert_cols_csv }})\\n        values ({{ insert_cols_csv }})\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.7390552}, \"macro.dbt.strategy_dispatch\": {\"unique_id\": \"macro.dbt.strategy_dispatch\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"name\": \"strategy_dispatch\", \"macro_sql\": \"{% macro strategy_dispatch(name) -%}\\n{% set original_name = name %}\\n  {% if '.' in name %}\\n    {% set package_name, name = name.split(\\\".\\\", 1) %}\\n  {% else %}\\n    {% set package_name = none %}\\n  {% endif %}\\n\\n  {% if package_name is none %}\\n    {% set package_context = context %}\\n  {% elif package_name in context %}\\n    {% set package_context = context[package_name] %}\\n  {% else %}\\n    {% set error_msg %}\\n        Could not find package '{{package_name}}', called with '{{original_name}}'\\n    {% endset %}\\n    {{ exceptions.raise_compiler_error(error_msg | trim) }}\\n  {% endif %}\\n\\n  {%- set search_name = 'snapshot_' ~ name ~ '_strategy' -%}\\n\\n  {% if search_name not in package_context %}\\n    {% set error_msg %}\\n        The specified strategy macro '{{name}}' was not found in package '{{ package_name }}'\\n    {% endset %}\\n    {{ exceptions.raise_compiler_error(error_msg | trim) }}\\n  {% endif %}\\n  {{ return(package_context[search_name]) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.7487428}, \"macro.dbt.snapshot_hash_arguments\": {\"unique_id\": \"macro.dbt.snapshot_hash_arguments\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"name\": \"snapshot_hash_arguments\", \"macro_sql\": \"{% macro snapshot_hash_arguments(args) -%}\\n  {{ adapter.dispatch('snapshot_hash_arguments', 'dbt')(args) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__snapshot_hash_arguments\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.7491798}, \"macro.dbt.default__snapshot_hash_arguments\": {\"unique_id\": \"macro.dbt.default__snapshot_hash_arguments\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"name\": \"default__snapshot_hash_arguments\", \"macro_sql\": \"{% macro default__snapshot_hash_arguments(args) -%}\\n    md5({%- for arg in args -%}\\n        coalesce(cast({{ arg }} as varchar ), '')\\n        {% if not loop.last %} || '|' || {% endif %}\\n    {%- endfor -%})\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.74975}, \"macro.dbt.snapshot_get_time\": {\"unique_id\": \"macro.dbt.snapshot_get_time\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"name\": \"snapshot_get_time\", \"macro_sql\": \"{% macro snapshot_get_time() -%}\\n  {{ adapter.dispatch('snapshot_get_time', 'dbt')() }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__snapshot_get_time\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.7501109}, \"macro.dbt.default__snapshot_get_time\": {\"unique_id\": \"macro.dbt.default__snapshot_get_time\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"name\": \"default__snapshot_get_time\", \"macro_sql\": \"{% macro default__snapshot_get_time() -%}\\n  {{ current_timestamp() }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.7503612}, \"macro.dbt.snapshot_timestamp_strategy\": {\"unique_id\": \"macro.dbt.snapshot_timestamp_strategy\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"name\": \"snapshot_timestamp_strategy\", \"macro_sql\": \"{% macro snapshot_timestamp_strategy(node, snapshotted_rel, current_rel, config, target_exists) %}\\n    {% set primary_key = config['unique_key'] %}\\n    {% set updated_at = config['updated_at'] %}\\n    {% set invalidate_hard_deletes = config.get('invalidate_hard_deletes', false) %}\\n\\n    {#/*\\n        The snapshot relation might not have an {{ updated_at }} value if the\\n        snapshot strategy is changed from `check` to `timestamp`. We\\n        should use a dbt-created column for the comparison in the snapshot\\n        table instead of assuming that the user-supplied {{ updated_at }}\\n        will be present in the historical data.\\n\\n        See https://github.com/dbt-labs/dbt-core/issues/2350\\n    */ #}\\n    {% set row_changed_expr -%}\\n        ({{ snapshotted_rel }}.dbt_valid_from < {{ current_rel }}.{{ updated_at }})\\n    {%- endset %}\\n\\n    {% set scd_id_expr = snapshot_hash_arguments([primary_key, updated_at]) %}\\n\\n    {% do return({\\n        \\\"unique_key\\\": primary_key,\\n        \\\"updated_at\\\": updated_at,\\n        \\\"row_changed\\\": row_changed_expr,\\n        \\\"scd_id\\\": scd_id_expr,\\n        \\\"invalidate_hard_deletes\\\": invalidate_hard_deletes\\n    }) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.snapshot_hash_arguments\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.7524228}, \"macro.dbt.snapshot_string_as_time\": {\"unique_id\": \"macro.dbt.snapshot_string_as_time\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"name\": \"snapshot_string_as_time\", \"macro_sql\": \"{% macro snapshot_string_as_time(timestamp) -%}\\n    {{ adapter.dispatch('snapshot_string_as_time', 'dbt')(timestamp) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__snapshot_string_as_time\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.752844}, \"macro.dbt.default__snapshot_string_as_time\": {\"unique_id\": \"macro.dbt.default__snapshot_string_as_time\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"name\": \"default__snapshot_string_as_time\", \"macro_sql\": \"{% macro default__snapshot_string_as_time(timestamp) %}\\n    {% do exceptions.raise_not_implemented(\\n        'snapshot_string_as_time macro not implemented for adapter '+adapter.type()\\n    ) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.753275}, \"macro.dbt.snapshot_check_all_get_existing_columns\": {\"unique_id\": \"macro.dbt.snapshot_check_all_get_existing_columns\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"name\": \"snapshot_check_all_get_existing_columns\", \"macro_sql\": \"{% macro snapshot_check_all_get_existing_columns(node, target_exists) -%}\\n    {%- set query_columns = get_columns_in_query(node['compiled_sql']) -%}\\n    {%- if not target_exists -%}\\n        {# no table yet -> return whatever the query does #}\\n        {{ return([false, query_columns]) }}\\n    {%- endif -%}\\n    {# handle any schema changes #}\\n    {%- set target_table = node.get('alias', node.get('name')) -%}\\n    {%- set target_relation = adapter.get_relation(database=node.database, schema=node.schema, identifier=target_table) -%}\\n    {%- set existing_cols = get_columns_in_query('select * from ' ~ target_relation) -%}\\n    {%- set ns = namespace() -%} {# handle for-loop scoping with a namespace #}\\n    {%- set ns.column_added = false -%}\\n\\n    {%- set intersection = [] -%}\\n    {%- for col in query_columns -%}\\n        {%- if col in existing_cols -%}\\n            {%- do intersection.append(col) -%}\\n        {%- else -%}\\n            {% set ns.column_added = true %}\\n        {%- endif -%}\\n    {%- endfor -%}\\n    {{ return([ns.column_added, intersection]) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_columns_in_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.755879}, \"macro.dbt.snapshot_check_strategy\": {\"unique_id\": \"macro.dbt.snapshot_check_strategy\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"name\": \"snapshot_check_strategy\", \"macro_sql\": \"{% macro snapshot_check_strategy(node, snapshotted_rel, current_rel, config, target_exists) %}\\n    {% set check_cols_config = config['check_cols'] %}\\n    {% set primary_key = config['unique_key'] %}\\n    {% set invalidate_hard_deletes = config.get('invalidate_hard_deletes', false) %}\\n    \\n    {% set select_current_time -%}\\n        select {{ snapshot_get_time() }} as snapshot_start\\n    {%- endset %}\\n\\n    {#-- don't access the column by name, to avoid dealing with casing issues on snowflake #}\\n    {%- set now = run_query(select_current_time)[0][0] -%}\\n    {% if now is none or now is undefined -%}\\n        {%- do exceptions.raise_compiler_error('Could not get a snapshot start time from the database') -%}\\n    {%- endif %}\\n    {% set updated_at = config.get('updated_at', snapshot_string_as_time(now)) %}\\n\\n    {% set column_added = false %}\\n\\n    {% if check_cols_config == 'all' %}\\n        {% set column_added, check_cols = snapshot_check_all_get_existing_columns(node, target_exists) %}\\n    {% elif check_cols_config is iterable and (check_cols_config | length) > 0 %}\\n        {% set check_cols = check_cols_config %}\\n    {% else %}\\n        {% do exceptions.raise_compiler_error(\\\"Invalid value for 'check_cols': \\\" ~ check_cols_config) %}\\n    {% endif %}\\n\\n    {%- set row_changed_expr -%}\\n    (\\n    {%- if column_added -%}\\n        TRUE\\n    {%- else -%}\\n    {%- for col in check_cols -%}\\n        {{ snapshotted_rel }}.{{ col }} != {{ current_rel }}.{{ col }}\\n        or\\n        (\\n            (({{ snapshotted_rel }}.{{ col }} is null) and not ({{ current_rel }}.{{ col }} is null))\\n            or\\n            ((not {{ snapshotted_rel }}.{{ col }} is null) and ({{ current_rel }}.{{ col }} is null))\\n        )\\n        {%- if not loop.last %} or {% endif -%}\\n    {%- endfor -%}\\n    {%- endif -%}\\n    )\\n    {%- endset %}\\n\\n    {% set scd_id_expr = snapshot_hash_arguments([primary_key, updated_at]) %}\\n\\n    {% do return({\\n        \\\"unique_key\\\": primary_key,\\n        \\\"updated_at\\\": updated_at,\\n        \\\"row_changed\\\": row_changed_expr,\\n        \\\"scd_id\\\": scd_id_expr,\\n        \\\"invalidate_hard_deletes\\\": invalidate_hard_deletes\\n    }) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.snapshot_get_time\", \"macro.dbt.run_query\", \"macro.dbt.snapshot_string_as_time\", \"macro.dbt.snapshot_check_all_get_existing_columns\", \"macro.dbt.snapshot_hash_arguments\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.760828}, \"macro.dbt.create_columns\": {\"unique_id\": \"macro.dbt.create_columns\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"name\": \"create_columns\", \"macro_sql\": \"{% macro create_columns(relation, columns) %}\\n  {{ adapter.dispatch('create_columns', 'dbt')(relation, columns) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__create_columns\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.7705312}, \"macro.dbt.default__create_columns\": {\"unique_id\": \"macro.dbt.default__create_columns\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"name\": \"default__create_columns\", \"macro_sql\": \"{% macro default__create_columns(relation, columns) %}\\n  {% for column in columns %}\\n    {% call statement() %}\\n      alter table {{ relation }} add column \\\"{{ column.name }}\\\" {{ column.data_type }};\\n    {% endcall %}\\n  {% endfor %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.7712681}, \"macro.dbt.post_snapshot\": {\"unique_id\": \"macro.dbt.post_snapshot\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"name\": \"post_snapshot\", \"macro_sql\": \"{% macro post_snapshot(staging_relation) %}\\n  {{ adapter.dispatch('post_snapshot', 'dbt')(staging_relation) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__post_snapshot\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.771702}, \"macro.dbt.default__post_snapshot\": {\"unique_id\": \"macro.dbt.default__post_snapshot\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"name\": \"default__post_snapshot\", \"macro_sql\": \"{% macro default__post_snapshot(staging_relation) %}\\n    {# no-op #}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.77192}, \"macro.dbt.snapshot_staging_table\": {\"unique_id\": \"macro.dbt.snapshot_staging_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"name\": \"snapshot_staging_table\", \"macro_sql\": \"{% macro snapshot_staging_table(strategy, source_sql, target_relation) -%}\\n  {{ adapter.dispatch('snapshot_staging_table', 'dbt')(strategy, source_sql, target_relation) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__snapshot_staging_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.772458}, \"macro.dbt.default__snapshot_staging_table\": {\"unique_id\": \"macro.dbt.default__snapshot_staging_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"name\": \"default__snapshot_staging_table\", \"macro_sql\": \"{% macro default__snapshot_staging_table(strategy, source_sql, target_relation) -%}\\n\\n    with snapshot_query as (\\n\\n        {{ source_sql }}\\n\\n    ),\\n\\n    snapshotted_data as (\\n\\n        select *,\\n            {{ strategy.unique_key }} as dbt_unique_key\\n\\n        from {{ target_relation }}\\n        where dbt_valid_to is null\\n\\n    ),\\n\\n    insertions_source_data as (\\n\\n        select\\n            *,\\n            {{ strategy.unique_key }} as dbt_unique_key,\\n            {{ strategy.updated_at }} as dbt_updated_at,\\n            {{ strategy.updated_at }} as dbt_valid_from,\\n            nullif({{ strategy.updated_at }}, {{ strategy.updated_at }}) as dbt_valid_to,\\n            {{ strategy.scd_id }} as dbt_scd_id\\n\\n        from snapshot_query\\n    ),\\n\\n    updates_source_data as (\\n\\n        select\\n            *,\\n            {{ strategy.unique_key }} as dbt_unique_key,\\n            {{ strategy.updated_at }} as dbt_updated_at,\\n            {{ strategy.updated_at }} as dbt_valid_from,\\n            {{ strategy.updated_at }} as dbt_valid_to\\n\\n        from snapshot_query\\n    ),\\n\\n    {%- if strategy.invalidate_hard_deletes %}\\n\\n    deletes_source_data as (\\n\\n        select \\n            *,\\n            {{ strategy.unique_key }} as dbt_unique_key\\n        from snapshot_query\\n    ),\\n    {% endif %}\\n\\n    insertions as (\\n\\n        select\\n            'insert' as dbt_change_type,\\n            source_data.*\\n\\n        from insertions_source_data as source_data\\n        left outer join snapshotted_data on snapshotted_data.dbt_unique_key = source_data.dbt_unique_key\\n        where snapshotted_data.dbt_unique_key is null\\n           or (\\n                snapshotted_data.dbt_unique_key is not null\\n            and (\\n                {{ strategy.row_changed }}\\n            )\\n        )\\n\\n    ),\\n\\n    updates as (\\n\\n        select\\n            'update' as dbt_change_type,\\n            source_data.*,\\n            snapshotted_data.dbt_scd_id\\n\\n        from updates_source_data as source_data\\n        join snapshotted_data on snapshotted_data.dbt_unique_key = source_data.dbt_unique_key\\n        where (\\n            {{ strategy.row_changed }}\\n        )\\n    )\\n\\n    {%- if strategy.invalidate_hard_deletes -%}\\n    ,\\n\\n    deletes as (\\n    \\n        select\\n            'delete' as dbt_change_type,\\n            source_data.*,\\n            {{ snapshot_get_time() }} as dbt_valid_from,\\n            {{ snapshot_get_time() }} as dbt_updated_at,\\n            {{ snapshot_get_time() }} as dbt_valid_to,\\n            snapshotted_data.dbt_scd_id\\n    \\n        from snapshotted_data\\n        left join deletes_source_data as source_data on snapshotted_data.dbt_unique_key = source_data.dbt_unique_key\\n        where source_data.dbt_unique_key is null\\n    )\\n    {%- endif %}\\n\\n    select * from insertions\\n    union all\\n    select * from updates\\n    {%- if strategy.invalidate_hard_deletes %}\\n    union all\\n    select * from deletes\\n    {%- endif %}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.snapshot_get_time\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.7748082}, \"macro.dbt.build_snapshot_table\": {\"unique_id\": \"macro.dbt.build_snapshot_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"name\": \"build_snapshot_table\", \"macro_sql\": \"{% macro build_snapshot_table(strategy, sql) -%}\\n  {{ adapter.dispatch('build_snapshot_table', 'dbt')(strategy, sql) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__build_snapshot_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.775297}, \"macro.dbt.default__build_snapshot_table\": {\"unique_id\": \"macro.dbt.default__build_snapshot_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"name\": \"default__build_snapshot_table\", \"macro_sql\": \"{% macro default__build_snapshot_table(strategy, sql) %}\\n\\n    select *,\\n        {{ strategy.scd_id }} as dbt_scd_id,\\n        {{ strategy.updated_at }} as dbt_updated_at,\\n        {{ strategy.updated_at }} as dbt_valid_from,\\n        nullif({{ strategy.updated_at }}, {{ strategy.updated_at }}) as dbt_valid_to\\n    from (\\n        {{ sql }}\\n    ) sbq\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.775959}, \"macro.dbt.build_snapshot_staging_table\": {\"unique_id\": \"macro.dbt.build_snapshot_staging_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"name\": \"build_snapshot_staging_table\", \"macro_sql\": \"{% macro build_snapshot_staging_table(strategy, sql, target_relation) %}\\n    {% set tmp_relation = make_temp_relation(target_relation) %}\\n\\n    {% set select = snapshot_staging_table(strategy, sql, target_relation) %}\\n\\n    {% call statement('build_snapshot_staging_relation') %}\\n        {{ create_table_as(True, tmp_relation, select) }}\\n    {% endcall %}\\n\\n    {% do return(tmp_relation) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.make_temp_relation\", \"macro.dbt.snapshot_staging_table\", \"macro.dbt.statement\", \"macro.dbt.create_table_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.777101}, \"macro.dbt.materialization_snapshot_default\": {\"unique_id\": \"macro.dbt.materialization_snapshot_default\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/snapshot.sql\", \"original_file_path\": \"macros/materializations/snapshots/snapshot.sql\", \"name\": \"materialization_snapshot_default\", \"macro_sql\": \"{% materialization snapshot, default %}\\n  {%- set config = model['config'] -%}\\n\\n  {%- set target_table = model.get('alias', model.get('name')) -%}\\n\\n  {%- set strategy_name = config.get('strategy') -%}\\n  {%- set unique_key = config.get('unique_key') %}\\n\\n  {% if not adapter.check_schema_exists(model.database, model.schema) %}\\n    {% do create_schema(model.database, model.schema) %}\\n  {% endif %}\\n\\n  {% set target_relation_exists, target_relation = get_or_create_relation(\\n          database=model.database,\\n          schema=model.schema,\\n          identifier=target_table,\\n          type='table') -%}\\n\\n  {%- if not target_relation.is_table -%}\\n    {% do exceptions.relation_wrong_type(target_relation, 'table') %}\\n  {%- endif -%}\\n\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  {% set strategy_macro = strategy_dispatch(strategy_name) %}\\n  {% set strategy = strategy_macro(model, \\\"snapshotted_data\\\", \\\"source_data\\\", config, target_relation_exists) %}\\n\\n  {% if not target_relation_exists %}\\n\\n      {% set build_sql = build_snapshot_table(strategy, model['compiled_sql']) %}\\n      {% set final_sql = create_table_as(False, target_relation, build_sql) %}\\n\\n  {% else %}\\n\\n      {{ adapter.valid_snapshot_target(target_relation) }}\\n\\n      {% set staging_table = build_snapshot_staging_table(strategy, sql, target_relation) %}\\n\\n      -- this may no-op if the database does not require column expansion\\n      {% do adapter.expand_target_column_types(from_relation=staging_table,\\n                                               to_relation=target_relation) %}\\n\\n      {% set missing_columns = adapter.get_missing_columns(staging_table, target_relation)\\n                                   | rejectattr('name', 'equalto', 'dbt_change_type')\\n                                   | rejectattr('name', 'equalto', 'DBT_CHANGE_TYPE')\\n                                   | rejectattr('name', 'equalto', 'dbt_unique_key')\\n                                   | rejectattr('name', 'equalto', 'DBT_UNIQUE_KEY')\\n                                   | list %}\\n\\n      {% do create_columns(target_relation, missing_columns) %}\\n\\n      {% set source_columns = adapter.get_columns_in_relation(staging_table)\\n                                   | rejectattr('name', 'equalto', 'dbt_change_type')\\n                                   | rejectattr('name', 'equalto', 'DBT_CHANGE_TYPE')\\n                                   | rejectattr('name', 'equalto', 'dbt_unique_key')\\n                                   | rejectattr('name', 'equalto', 'DBT_UNIQUE_KEY')\\n                                   | list %}\\n\\n      {% set quoted_source_columns = [] %}\\n      {% for column in source_columns %}\\n        {% do quoted_source_columns.append(adapter.quote(column.name)) %}\\n      {% endfor %}\\n\\n      {% set final_sql = snapshot_merge_sql(\\n            target = target_relation,\\n            source = staging_table,\\n            insert_cols = quoted_source_columns\\n         )\\n      %}\\n\\n  {% endif %}\\n\\n  {% call statement('main') %}\\n      {{ final_sql }}\\n  {% endcall %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {% if not target_relation_exists %}\\n    {% do create_indexes(target_relation) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  {{ adapter.commit() }}\\n\\n  {% if staging_table is defined %}\\n      {% do post_snapshot(staging_table) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{% endmaterialization %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.create_schema\", \"macro.dbt.get_or_create_relation\", \"macro.dbt.run_hooks\", \"macro.dbt.strategy_dispatch\", \"macro.dbt.build_snapshot_table\", \"macro.dbt.create_table_as\", \"macro.dbt.build_snapshot_staging_table\", \"macro.dbt.create_columns\", \"macro.dbt.snapshot_merge_sql\", \"macro.dbt.statement\", \"macro.dbt.persist_docs\", \"macro.dbt.create_indexes\", \"macro.dbt.post_snapshot\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.7941692}, \"macro.dbt.materialization_test_default\": {\"unique_id\": \"macro.dbt.materialization_test_default\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/tests/test.sql\", \"original_file_path\": \"macros/materializations/tests/test.sql\", \"name\": \"materialization_test_default\", \"macro_sql\": \"{%- materialization test, default -%}\\n\\n  {% set relations = [] %}\\n\\n  {% if should_store_failures() %}\\n\\n    {% set identifier = model['alias'] %}\\n    {% set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) %}\\n    {% set target_relation = api.Relation.create(\\n        identifier=identifier, schema=schema, database=database, type='table') -%} %}\\n    \\n    {% if old_relation %}\\n        {% do adapter.drop_relation(old_relation) %}\\n    {% endif %}\\n    \\n    {% call statement(auto_begin=True) %}\\n        {{ create_table_as(False, target_relation, sql) }}\\n    {% endcall %}\\n    \\n    {% do relations.append(target_relation) %}\\n  \\n    {% set main_sql %}\\n        select *\\n        from {{ target_relation }}\\n    {% endset %}\\n    \\n    {{ adapter.commit() }}\\n  \\n  {% else %}\\n\\n      {% set main_sql = sql %}\\n  \\n  {% endif %}\\n\\n  {% set limit = config.get('limit') %}\\n  {% set fail_calc = config.get('fail_calc') %}\\n  {% set warn_if = config.get('warn_if') %}\\n  {% set error_if = config.get('error_if') %}\\n\\n  {% call statement('main', fetch_result=True) -%}\\n\\n    {{ get_test_sql(main_sql, fail_calc, warn_if, error_if, limit)}}\\n\\n  {%- endcall %}\\n  \\n  {{ return({'relations': relations}) }}\\n\\n{%- endmaterialization -%}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.should_store_failures\", \"macro.dbt.statement\", \"macro.dbt.create_table_as\", \"macro.dbt.get_test_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.7998898}, \"macro.dbt.get_test_sql\": {\"unique_id\": \"macro.dbt.get_test_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/tests/helpers.sql\", \"original_file_path\": \"macros/materializations/tests/helpers.sql\", \"name\": \"get_test_sql\", \"macro_sql\": \"{% macro get_test_sql(main_sql, fail_calc, warn_if, error_if, limit) -%}\\n  {{ adapter.dispatch('get_test_sql', 'dbt')(main_sql, fail_calc, warn_if, error_if, limit) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_test_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.801226}, \"macro.dbt.default__get_test_sql\": {\"unique_id\": \"macro.dbt.default__get_test_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/tests/helpers.sql\", \"original_file_path\": \"macros/materializations/tests/helpers.sql\", \"name\": \"default__get_test_sql\", \"macro_sql\": \"{% macro default__get_test_sql(main_sql, fail_calc, warn_if, error_if, limit) -%}\\n    select\\n      {{ fail_calc }} as failures,\\n      {{ fail_calc }} {{ warn_if }} as should_warn,\\n      {{ fail_calc }} {{ error_if }} as should_error\\n    from (\\n      {{ main_sql }}\\n      {{ \\\"limit \\\" ~ limit if limit != none }}\\n    ) dbt_internal_test\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.8020391}, \"macro.dbt.get_where_subquery\": {\"unique_id\": \"macro.dbt.get_where_subquery\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/tests/where_subquery.sql\", \"original_file_path\": \"macros/materializations/tests/where_subquery.sql\", \"name\": \"get_where_subquery\", \"macro_sql\": \"{% macro get_where_subquery(relation) -%}\\n    {% do return(adapter.dispatch('get_where_subquery', 'dbt')(relation)) %}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_where_subquery\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.803186}, \"macro.dbt.default__get_where_subquery\": {\"unique_id\": \"macro.dbt.default__get_where_subquery\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/tests/where_subquery.sql\", \"original_file_path\": \"macros/materializations/tests/where_subquery.sql\", \"name\": \"default__get_where_subquery\", \"macro_sql\": \"{% macro default__get_where_subquery(relation) -%}\\n    {% set where = config.get('where', '') %}\\n    {% if where %}\\n        {%- set filtered -%}\\n            (select * from {{ relation }} where {{ where }}) dbt_subquery\\n        {%- endset -%}\\n        {% do return(filtered) %}\\n    {%- else -%}\\n        {% do return(relation) %}\\n    {%- endif -%}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.804178}, \"macro.dbt.get_quoted_csv\": {\"unique_id\": \"macro.dbt.get_quoted_csv\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"name\": \"get_quoted_csv\", \"macro_sql\": \"{% macro get_quoted_csv(column_names) %}\\n    \\n    {% set quoted = [] %}\\n    {% for col in column_names -%}\\n        {%- do quoted.append(adapter.quote(col)) -%}\\n    {%- endfor %}\\n\\n    {%- set dest_cols_csv = quoted | join(', ') -%}\\n    {{ return(dest_cols_csv) }}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.806505}, \"macro.dbt.diff_columns\": {\"unique_id\": \"macro.dbt.diff_columns\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"name\": \"diff_columns\", \"macro_sql\": \"{% macro diff_columns(source_columns, target_columns) %}\\n\\n  {% set result = [] %}\\n  {% set source_names = source_columns | map(attribute = 'column') | list %}\\n  {% set target_names = target_columns | map(attribute = 'column') | list %}\\n   \\n   {# --check whether the name attribute exists in the target - this does not perform a data type check #}\\n   {% for sc in source_columns %}\\n     {% if sc.name not in target_names %}\\n        {{ result.append(sc) }}\\n     {% endif %}\\n   {% endfor %}\\n  \\n  {{ return(result) }}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.8079581}, \"macro.dbt.diff_column_data_types\": {\"unique_id\": \"macro.dbt.diff_column_data_types\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"name\": \"diff_column_data_types\", \"macro_sql\": \"{% macro diff_column_data_types(source_columns, target_columns) %}\\n  \\n  {% set result = [] %}\\n  {% for sc in source_columns %}\\n    {% set tc = target_columns | selectattr(\\\"name\\\", \\\"equalto\\\", sc.name) | list | first %}\\n    {% if tc %}\\n      {% if sc.data_type != tc.data_type %}\\n        {{ result.append( { 'column_name': tc.name, 'new_type': sc.data_type } ) }} \\n      {% endif %}\\n    {% endif %}\\n  {% endfor %}\\n\\n  {{ return(result) }}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.809567}, \"macro.dbt.get_merge_sql\": {\"unique_id\": \"macro.dbt.get_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"name\": \"get_merge_sql\", \"macro_sql\": \"{% macro get_merge_sql(target, source, unique_key, dest_columns, predicates=none) -%}\\n  {{ adapter.dispatch('get_merge_sql', 'dbt')(target, source, unique_key, dest_columns, predicates) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.8179982}, \"macro.dbt.default__get_merge_sql\": {\"unique_id\": \"macro.dbt.default__get_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"name\": \"default__get_merge_sql\", \"macro_sql\": \"{% macro default__get_merge_sql(target, source, unique_key, dest_columns, predicates) -%}\\n    {%- set predicates = [] if predicates is none else [] + predicates -%}\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n    {%- set update_columns = config.get('merge_update_columns', default = dest_columns | map(attribute=\\\"quoted\\\") | list) -%}\\n    {%- set sql_header = config.get('sql_header', none) -%}\\n\\n    {% if unique_key %}\\n        {% set unique_key_match %}\\n            DBT_INTERNAL_SOURCE.{{ unique_key }} = DBT_INTERNAL_DEST.{{ unique_key }}\\n        {% endset %}\\n        {% do predicates.append(unique_key_match) %}\\n    {% else %}\\n        {% do predicates.append('FALSE') %}\\n    {% endif %}\\n\\n    {{ sql_header if sql_header is not none }}\\n\\n    merge into {{ target }} as DBT_INTERNAL_DEST\\n        using {{ source }} as DBT_INTERNAL_SOURCE\\n        on {{ predicates | join(' and ') }}\\n\\n    {% if unique_key %}\\n    when matched then update set\\n        {% for column_name in update_columns -%}\\n            {{ column_name }} = DBT_INTERNAL_SOURCE.{{ column_name }}\\n            {%- if not loop.last %}, {%- endif %}\\n        {%- endfor %}\\n    {% endif %}\\n\\n    when not matched then insert\\n        ({{ dest_cols_csv }})\\n    values\\n        ({{ dest_cols_csv }})\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_quoted_csv\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.8210711}, \"macro.dbt.get_delete_insert_merge_sql\": {\"unique_id\": \"macro.dbt.get_delete_insert_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"name\": \"get_delete_insert_merge_sql\", \"macro_sql\": \"{% macro get_delete_insert_merge_sql(target, source, unique_key, dest_columns) -%}\\n  {{ adapter.dispatch('get_delete_insert_merge_sql', 'dbt')(target, source, unique_key, dest_columns) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_delete_insert_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.821682}, \"macro.dbt.default__get_delete_insert_merge_sql\": {\"unique_id\": \"macro.dbt.default__get_delete_insert_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"name\": \"default__get_delete_insert_merge_sql\", \"macro_sql\": \"{% macro default__get_delete_insert_merge_sql(target, source, unique_key, dest_columns) -%}\\n\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n\\n    {% if unique_key is not none %}\\n    delete from {{ target }}\\n    where ({{ unique_key }}) in (\\n        select ({{ unique_key }})\\n        from {{ source }}\\n    );\\n    {% endif %}\\n\\n    insert into {{ target }} ({{ dest_cols_csv }})\\n    (\\n        select {{ dest_cols_csv }}\\n        from {{ source }}\\n    )\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_quoted_csv\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.8228061}, \"macro.dbt.get_insert_overwrite_merge_sql\": {\"unique_id\": \"macro.dbt.get_insert_overwrite_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"name\": \"get_insert_overwrite_merge_sql\", \"macro_sql\": \"{% macro get_insert_overwrite_merge_sql(target, source, dest_columns, predicates, include_sql_header=false) -%}\\n  {{ adapter.dispatch('get_insert_overwrite_merge_sql', 'dbt')(target, source, dest_columns, predicates, include_sql_header) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_insert_overwrite_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.823494}, \"macro.dbt.default__get_insert_overwrite_merge_sql\": {\"unique_id\": \"macro.dbt.default__get_insert_overwrite_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"name\": \"default__get_insert_overwrite_merge_sql\", \"macro_sql\": \"{% macro default__get_insert_overwrite_merge_sql(target, source, dest_columns, predicates, include_sql_header) -%}\\n    {%- set predicates = [] if predicates is none else [] + predicates -%}\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n    {%- set sql_header = config.get('sql_header', none) -%}\\n\\n    {{ sql_header if sql_header is not none and include_sql_header }}\\n\\n    merge into {{ target }} as DBT_INTERNAL_DEST\\n        using {{ source }} as DBT_INTERNAL_SOURCE\\n        on FALSE\\n\\n    when not matched by source\\n        {% if predicates %} and {{ predicates | join(' and ') }} {% endif %}\\n        then delete\\n\\n    when not matched then insert\\n        ({{ dest_cols_csv }})\\n    values\\n        ({{ dest_cols_csv }})\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_quoted_csv\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.825151}, \"macro.dbt.is_incremental\": {\"unique_id\": \"macro.dbt.is_incremental\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/is_incremental.sql\", \"original_file_path\": \"macros/materializations/models/incremental/is_incremental.sql\", \"name\": \"is_incremental\", \"macro_sql\": \"{% macro is_incremental() %}\\n    {#-- do not run introspective queries in parsing #}\\n    {% if not execute %}\\n        {{ return(False) }}\\n    {% else %}\\n        {% set relation = adapter.get_relation(this.database, this.schema, this.table) %}\\n        {{ return(relation is not none\\n                  and relation.type == 'table'\\n                  and model.config.materialized == 'incremental'\\n                  and not should_full_refresh()) }}\\n    {% endif %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.should_full_refresh\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.8269792}, \"macro.dbt.materialization_incremental_default\": {\"unique_id\": \"macro.dbt.materialization_incremental_default\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/incremental.sql\", \"original_file_path\": \"macros/materializations/models/incremental/incremental.sql\", \"name\": \"materialization_incremental_default\", \"macro_sql\": \"{% materialization incremental, default -%}\\n\\n  {% set unique_key = config.get('unique_key') %}\\n\\n  {% set target_relation = this.incorporate(type='table') %}\\n  {% set existing_relation = load_relation(this) %}\\n  {% set tmp_relation = make_temp_relation(target_relation) %}\\n  {%- set full_refresh_mode = (should_full_refresh()) -%}\\n\\n  {% set on_schema_change = incremental_validate_on_schema_change(config.get('on_schema_change'), default='ignore') %}\\n\\n  {% set tmp_identifier = model['name'] + '__dbt_tmp' %}\\n  {% set backup_identifier = model['name'] + \\\"__dbt_backup\\\" %}\\n\\n  -- the intermediate_ and backup_ relations should not already exist in the database; get_relation\\n  -- will return None in that case. Otherwise, we get a relation that we can drop\\n  -- later, before we try to use this name for the current operation. This has to happen before\\n  -- BEGIN, in a separate transaction\\n  {% set preexisting_intermediate_relation = adapter.get_relation(identifier=tmp_identifier, \\n                                                                  schema=schema,\\n                                                                  database=database) %}                                               \\n  {% set preexisting_backup_relation = adapter.get_relation(identifier=backup_identifier,\\n                                                            schema=schema,\\n                                                            database=database) %}\\n  {{ drop_relation_if_exists(preexisting_intermediate_relation) }}\\n  {{ drop_relation_if_exists(preexisting_backup_relation) }}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  {% set to_drop = [] %}\\n\\n  {# -- first check whether we want to full refresh for source view or config reasons #}\\n  {% set trigger_full_refresh = (full_refresh_mode or existing_relation.is_view) %}\\n\\n  {% if existing_relation is none %}\\n      {% set build_sql = create_table_as(False, target_relation, sql) %}\\n{% elif trigger_full_refresh %}\\n      {#-- Make sure the backup doesn't exist so we don't encounter issues with the rename below #}\\n      {% set tmp_identifier = model['name'] + '__dbt_tmp' %}\\n      {% set backup_identifier = model['name'] + '__dbt_backup' %}\\n      {% set intermediate_relation = existing_relation.incorporate(path={\\\"identifier\\\": tmp_identifier}) %}\\n      {% set backup_relation = existing_relation.incorporate(path={\\\"identifier\\\": backup_identifier}) %}\\n\\n      {% set build_sql = create_table_as(False, intermediate_relation, sql) %}\\n      {% set need_swap = true %}\\n      {% do to_drop.append(backup_relation) %}\\n  {% else %}\\n    {% do run_query(create_table_as(True, tmp_relation, sql)) %}\\n    {% do adapter.expand_target_column_types(\\n             from_relation=tmp_relation,\\n             to_relation=target_relation) %}\\n    {#-- Process schema changes. Returns dict of changes if successful. Use source columns for upserting/merging --#}\\n    {% set dest_columns = process_schema_changes(on_schema_change, tmp_relation, existing_relation) %}\\n    {% if not dest_columns %}\\n      {% set dest_columns = adapter.get_columns_in_relation(existing_relation) %}\\n    {% endif %}\\n    {% set build_sql = get_delete_insert_merge_sql(target_relation, tmp_relation, unique_key, dest_columns) %}\\n  \\n  {% endif %}\\n\\n  {% call statement(\\\"main\\\") %}\\n      {{ build_sql }}\\n  {% endcall %}\\n\\n  {% if need_swap %} \\n      {% do adapter.rename_relation(target_relation, backup_relation) %} \\n      {% do adapter.rename_relation(intermediate_relation, target_relation) %} \\n  {% endif %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {% if existing_relation is none or existing_relation.is_view or should_full_refresh() %}\\n    {% do create_indexes(target_relation) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  -- `COMMIT` happens here\\n  {% do adapter.commit() %}\\n\\n  {% for rel in to_drop %}\\n      {% do adapter.drop_relation(rel) %}\\n  {% endfor %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{%- endmaterialization %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.load_relation\", \"macro.dbt.make_temp_relation\", \"macro.dbt.should_full_refresh\", \"macro.dbt.incremental_validate_on_schema_change\", \"macro.dbt.drop_relation_if_exists\", \"macro.dbt.run_hooks\", \"macro.dbt.create_table_as\", \"macro.dbt.run_query\", \"macro.dbt.process_schema_changes\", \"macro.dbt.get_delete_insert_merge_sql\", \"macro.dbt.statement\", \"macro.dbt.persist_docs\", \"macro.dbt.create_indexes\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.840609}, \"macro.dbt.incremental_validate_on_schema_change\": {\"unique_id\": \"macro.dbt.incremental_validate_on_schema_change\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"original_file_path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"name\": \"incremental_validate_on_schema_change\", \"macro_sql\": \"{% macro incremental_validate_on_schema_change(on_schema_change, default='ignore') %}\\n   \\n   {% if on_schema_change not in ['sync_all_columns', 'append_new_columns', 'fail', 'ignore'] %}\\n     \\n     {% set log_message = 'Invalid value for on_schema_change (%s) specified. Setting default value of %s.' % (on_schema_change, default) %}\\n     {% do log(log_message) %}\\n     \\n     {{ return(default) }}\\n\\n   {% else %}\\n\\n     {{ return(on_schema_change) }}\\n   \\n   {% endif %}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.8552}, \"macro.dbt.check_for_schema_changes\": {\"unique_id\": \"macro.dbt.check_for_schema_changes\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"original_file_path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"name\": \"check_for_schema_changes\", \"macro_sql\": \"{% macro check_for_schema_changes(source_relation, target_relation) %}\\n  \\n  {% set schema_changed = False %}\\n  \\n  {%- set source_columns = adapter.get_columns_in_relation(source_relation) -%}\\n  {%- set target_columns = adapter.get_columns_in_relation(target_relation) -%}\\n  {%- set source_not_in_target = diff_columns(source_columns, target_columns) -%}\\n  {%- set target_not_in_source = diff_columns(target_columns, source_columns) -%}\\n\\n  {% set new_target_types = diff_column_data_types(source_columns, target_columns) %}\\n\\n  {% if source_not_in_target != [] %}\\n    {% set schema_changed = True %}\\n  {% elif target_not_in_source != [] or new_target_types != [] %}\\n    {% set schema_changed = True %}\\n  {% elif new_target_types != [] %}\\n    {% set schema_changed = True %}\\n  {% endif %}\\n  \\n  {% set changes_dict = {\\n    'schema_changed': schema_changed,\\n    'source_not_in_target': source_not_in_target,\\n    'target_not_in_source': target_not_in_source,\\n    'source_columns': source_columns,\\n    'target_columns': target_columns,\\n    'new_target_types': new_target_types\\n  } %}\\n\\n  {% set msg %}\\n    In {{ target_relation }}:\\n        Schema changed: {{ schema_changed }}\\n        Source columns not in target: {{ source_not_in_target }}\\n        Target columns not in source: {{ target_not_in_source }}\\n        New column types: {{ new_target_types }}\\n  {% endset %}\\n  \\n  {% do log(msg) %}\\n\\n  {{ return(changes_dict) }}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.diff_columns\", \"macro.dbt.diff_column_data_types\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.858468}, \"macro.dbt.sync_column_schemas\": {\"unique_id\": \"macro.dbt.sync_column_schemas\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"original_file_path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"name\": \"sync_column_schemas\", \"macro_sql\": \"{% macro sync_column_schemas(on_schema_change, target_relation, schema_changes_dict) %}\\n  \\n  {%- set add_to_target_arr = schema_changes_dict['source_not_in_target'] -%}\\n\\n  {%- if on_schema_change == 'append_new_columns'-%}\\n     {%- if add_to_target_arr | length > 0 -%}\\n       {%- do alter_relation_add_remove_columns(target_relation, add_to_target_arr, none) -%}\\n     {%- endif -%}\\n  \\n  {% elif on_schema_change == 'sync_all_columns' %}\\n     {%- set remove_from_target_arr = schema_changes_dict['target_not_in_source'] -%}\\n     {%- set new_target_types = schema_changes_dict['new_target_types'] -%}\\n  \\n     {% if add_to_target_arr | length > 0 or remove_from_target_arr | length > 0 %} \\n       {%- do alter_relation_add_remove_columns(target_relation, add_to_target_arr, remove_from_target_arr) -%}\\n     {% endif %}\\n\\n     {% if new_target_types != [] %}\\n       {% for ntt in new_target_types %}\\n         {% set column_name = ntt['column_name'] %}\\n         {% set new_type = ntt['new_type'] %}\\n         {% do alter_column_type(target_relation, column_name, new_type) %}\\n       {% endfor %}\\n     {% endif %}\\n  \\n  {% endif %}\\n\\n  {% set schema_change_message %}\\n    In {{ target_relation }}:\\n        Schema change approach: {{ on_schema_change }}\\n        Columns added: {{ add_to_target_arr }}\\n        Columns removed: {{ remove_from_target_arr }}\\n        Data types changed: {{ new_target_types }}\\n  {% endset %}\\n  \\n  {% do log(schema_change_message) %}\\n  \\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.alter_relation_add_remove_columns\", \"macro.dbt.alter_column_type\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.8616462}, \"macro.dbt.process_schema_changes\": {\"unique_id\": \"macro.dbt.process_schema_changes\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"original_file_path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"name\": \"process_schema_changes\", \"macro_sql\": \"{% macro process_schema_changes(on_schema_change, source_relation, target_relation) %}\\n    \\n    {% if on_schema_change == 'ignore' %}\\n\\n     {{ return({}) }}\\n\\n    {% else %}\\n    \\n      {% set schema_changes_dict = check_for_schema_changes(source_relation, target_relation) %}\\n      \\n      {% if schema_changes_dict['schema_changed'] %}\\n    \\n        {% if on_schema_change == 'fail' %}\\n        \\n          {% set fail_msg %}\\n              The source and target schemas on this incremental model are out of sync!\\n              They can be reconciled in several ways: \\n                - set the `on_schema_change` config to either append_new_columns or sync_all_columns, depending on your situation.\\n                - Re-run the incremental model with `full_refresh: True` to update the target schema.\\n                - update the schema manually and re-run the process.\\n          {% endset %}\\n          \\n          {% do exceptions.raise_compiler_error(fail_msg) %}\\n        \\n        {# -- unless we ignore, run the sync operation per the config #}\\n        {% else %}\\n          \\n          {% do sync_column_schemas(on_schema_change, target_relation, schema_changes_dict) %}\\n        \\n        {% endif %}\\n      \\n      {% endif %}\\n\\n      {{ return(schema_changes_dict['source_columns']) }}\\n    \\n    {% endif %}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.check_for_schema_changes\", \"macro.dbt.sync_column_schemas\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.8635662}, \"macro.dbt.materialization_table_default\": {\"unique_id\": \"macro.dbt.materialization_table_default\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/table/table.sql\", \"original_file_path\": \"macros/materializations/models/table/table.sql\", \"name\": \"materialization_table_default\", \"macro_sql\": \"{% materialization table, default %}\\n  {%- set identifier = model['alias'] -%}\\n  {%- set tmp_identifier = model['name'] + '__dbt_tmp' -%}\\n  {%- set backup_identifier = model['name'] + '__dbt_backup' -%}\\n\\n  {%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%}\\n  {%- set target_relation = api.Relation.create(identifier=identifier,\\n                                                schema=schema,\\n                                                database=database,\\n                                                type='table') -%}\\n  {%- set intermediate_relation = api.Relation.create(identifier=tmp_identifier,\\n                                                      schema=schema,\\n                                                      database=database,\\n                                                      type='table') -%}\\n  -- the intermediate_relation should not already exist in the database; get_relation\\n  -- will return None in that case. Otherwise, we get a relation that we can drop\\n  -- later, before we try to use this name for the current operation\\n  {%- set preexisting_intermediate_relation = adapter.get_relation(identifier=tmp_identifier, \\n                                                                   schema=schema,\\n                                                                   database=database) -%}\\n  /*\\n      See ../view/view.sql for more information about this relation.\\n  */\\n  {%- set backup_relation_type = 'table' if old_relation is none else old_relation.type -%}\\n  {%- set backup_relation = api.Relation.create(identifier=backup_identifier,\\n                                                schema=schema,\\n                                                database=database,\\n                                                type=backup_relation_type) -%}\\n  -- as above, the backup_relation should not already exist\\n  {%- set preexisting_backup_relation = adapter.get_relation(identifier=backup_identifier,\\n                                                             schema=schema,\\n                                                             database=database) -%}\\n\\n\\n  -- drop the temp relations if they exist already in the database\\n  {{ drop_relation_if_exists(preexisting_intermediate_relation) }}\\n  {{ drop_relation_if_exists(preexisting_backup_relation) }}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  -- build model\\n  {% call statement('main') -%}\\n    {{ get_create_table_as_sql(False, intermediate_relation, sql) }}\\n  {%- endcall %}\\n\\n  -- cleanup\\n  {% if old_relation is not none %}\\n      {{ adapter.rename_relation(old_relation, backup_relation) }}\\n  {% endif %}\\n\\n  {{ adapter.rename_relation(intermediate_relation, target_relation) }}\\n\\n  {% do create_indexes(target_relation) %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  -- `COMMIT` happens here\\n  {{ adapter.commit() }}\\n\\n  -- finally, drop the existing/backup relation after the commit\\n  {{ drop_relation_if_exists(backup_relation) }}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n{% endmaterialization %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.drop_relation_if_exists\", \"macro.dbt.run_hooks\", \"macro.dbt.statement\", \"macro.dbt.get_create_table_as_sql\", \"macro.dbt.create_indexes\", \"macro.dbt.persist_docs\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.874618}, \"macro.dbt.get_create_table_as_sql\": {\"unique_id\": \"macro.dbt.get_create_table_as_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/table/create_table_as.sql\", \"original_file_path\": \"macros/materializations/models/table/create_table_as.sql\", \"name\": \"get_create_table_as_sql\", \"macro_sql\": \"{% macro get_create_table_as_sql(temporary, relation, sql) -%}\\n  {{ adapter.dispatch('get_create_table_as_sql', 'dbt')(temporary, relation, sql) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_create_table_as_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.8760588}, \"macro.dbt.default__get_create_table_as_sql\": {\"unique_id\": \"macro.dbt.default__get_create_table_as_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/table/create_table_as.sql\", \"original_file_path\": \"macros/materializations/models/table/create_table_as.sql\", \"name\": \"default__get_create_table_as_sql\", \"macro_sql\": \"{% macro default__get_create_table_as_sql(temporary, relation, sql) -%}\\n  {{ return(create_table_as(temporary, relation, sql)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.create_table_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.876541}, \"macro.dbt.create_table_as\": {\"unique_id\": \"macro.dbt.create_table_as\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/table/create_table_as.sql\", \"original_file_path\": \"macros/materializations/models/table/create_table_as.sql\", \"name\": \"create_table_as\", \"macro_sql\": \"{% macro create_table_as(temporary, relation, sql) -%}\\n  {{ adapter.dispatch('create_table_as', 'dbt')(temporary, relation, sql) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__create_table_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.877064}, \"macro.dbt.default__create_table_as\": {\"unique_id\": \"macro.dbt.default__create_table_as\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/table/create_table_as.sql\", \"original_file_path\": \"macros/materializations/models/table/create_table_as.sql\", \"name\": \"default__create_table_as\", \"macro_sql\": \"{% macro default__create_table_as(temporary, relation, sql) -%}\\n  {%- set sql_header = config.get('sql_header', none) -%}\\n  \\n  {{ sql_header if sql_header is not none }}\\n  \\n  create {% if temporary: -%}temporary{%- endif %} table\\n    {{ relation.include(database=(not temporary), schema=(not temporary)) }}\\n  as (\\n    {{ sql }}\\n  );\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.878151}, \"macro.dbt.materialization_view_default\": {\"unique_id\": \"macro.dbt.materialization_view_default\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/view/view.sql\", \"original_file_path\": \"macros/materializations/models/view/view.sql\", \"name\": \"materialization_view_default\", \"macro_sql\": \"{%- materialization view, default -%}\\n\\n  {%- set identifier = model['alias'] -%}\\n  {%- set tmp_identifier = model['name'] + '__dbt_tmp' -%}\\n  {%- set backup_identifier = model['name'] + '__dbt_backup' -%}\\n\\n  {%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%}\\n  {%- set target_relation = api.Relation.create(identifier=identifier, schema=schema, database=database,\\n                                                type='view') -%}\\n  {%- set intermediate_relation = api.Relation.create(identifier=tmp_identifier,\\n                                                      schema=schema, database=database, type='view') -%}\\n  -- the intermediate_relation should not already exist in the database; get_relation\\n  -- will return None in that case. Otherwise, we get a relation that we can drop\\n  -- later, before we try to use this name for the current operation\\n  {%- set preexisting_intermediate_relation = adapter.get_relation(identifier=tmp_identifier, \\n                                                                   schema=schema,\\n                                                                   database=database) -%}\\n  /*\\n     This relation (probably) doesn't exist yet. If it does exist, it's a leftover from\\n     a previous run, and we're going to try to drop it immediately. At the end of this\\n     materialization, we're going to rename the \\\"old_relation\\\" to this identifier,\\n     and then we're going to drop it. In order to make sure we run the correct one of:\\n       - drop view ...\\n       - drop table ...\\n\\n     We need to set the type of this relation to be the type of the old_relation, if it exists,\\n     or else \\\"view\\\" as a sane default if it does not. Note that if the old_relation does not\\n     exist, then there is nothing to move out of the way and subsequentally drop. In that case,\\n     this relation will be effectively unused.\\n  */\\n  {%- set backup_relation_type = 'view' if old_relation is none else old_relation.type -%}\\n  {%- set backup_relation = api.Relation.create(identifier=backup_identifier,\\n                                                schema=schema, database=database,\\n                                                type=backup_relation_type) -%}\\n  -- as above, the backup_relation should not already exist\\n  {%- set preexisting_backup_relation = adapter.get_relation(identifier=backup_identifier,\\n                                                             schema=schema,\\n                                                             database=database) -%}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- drop the temp relations if they exist already in the database\\n  {{ drop_relation_if_exists(preexisting_intermediate_relation) }}\\n  {{ drop_relation_if_exists(preexisting_backup_relation) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  -- build model\\n  {% call statement('main') -%}\\n    {{ create_view_as(intermediate_relation, sql) }}\\n  {%- endcall %}\\n\\n  -- cleanup\\n  -- move the existing view out of the way\\n  {% if old_relation is not none %}\\n    {{ adapter.rename_relation(old_relation, backup_relation) }}\\n  {% endif %}\\n  {{ adapter.rename_relation(intermediate_relation, target_relation) }}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  {{ adapter.commit() }}\\n\\n  {{ drop_relation_if_exists(backup_relation) }}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{%- endmaterialization -%}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.run_hooks\", \"macro.dbt.drop_relation_if_exists\", \"macro.dbt.statement\", \"macro.dbt.create_view_as\", \"macro.dbt.persist_docs\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.888351}, \"macro.dbt.handle_existing_table\": {\"unique_id\": \"macro.dbt.handle_existing_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/view/helpers.sql\", \"original_file_path\": \"macros/materializations/models/view/helpers.sql\", \"name\": \"handle_existing_table\", \"macro_sql\": \"{% macro handle_existing_table(full_refresh, old_relation) %}\\n    {{ adapter.dispatch('handle_existing_table', 'dbt')(full_refresh, old_relation) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__handle_existing_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.889299}, \"macro.dbt.default__handle_existing_table\": {\"unique_id\": \"macro.dbt.default__handle_existing_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/view/helpers.sql\", \"original_file_path\": \"macros/materializations/models/view/helpers.sql\", \"name\": \"default__handle_existing_table\", \"macro_sql\": \"{% macro default__handle_existing_table(full_refresh, old_relation) %}\\n    {{ log(\\\"Dropping relation \\\" ~ old_relation ~ \\\" because it is of type \\\" ~ old_relation.type) }}\\n    {{ adapter.drop_relation(old_relation) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.889876}, \"macro.dbt.create_or_replace_view\": {\"unique_id\": \"macro.dbt.create_or_replace_view\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/view/create_or_replace_view.sql\", \"original_file_path\": \"macros/materializations/models/view/create_or_replace_view.sql\", \"name\": \"create_or_replace_view\", \"macro_sql\": \"{% macro create_or_replace_view() %}\\n  {%- set identifier = model['alias'] -%}\\n\\n  {%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%}\\n\\n  {%- set exists_as_view = (old_relation is not none and old_relation.is_view) -%}\\n\\n  {%- set target_relation = api.Relation.create(\\n      identifier=identifier, schema=schema, database=database,\\n      type='view') -%}\\n\\n  {{ run_hooks(pre_hooks) }}\\n\\n  -- If there's a table with the same name and we weren't told to full refresh,\\n  -- that's an error. If we were told to full refresh, drop it. This behavior differs\\n  -- for Snowflake and BigQuery, so multiple dispatch is used.\\n  {%- if old_relation is not none and old_relation.is_table -%}\\n    {{ handle_existing_table(should_full_refresh(), old_relation) }}\\n  {%- endif -%}\\n\\n  -- build model\\n  {% call statement('main') -%}\\n    {{ get_create_view_as_sql(target_relation, sql) }}\\n  {%- endcall %}\\n\\n  {{ run_hooks(post_hooks) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.run_hooks\", \"macro.dbt.handle_existing_table\", \"macro.dbt.should_full_refresh\", \"macro.dbt.statement\", \"macro.dbt.get_create_view_as_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.895395}, \"macro.dbt.get_create_view_as_sql\": {\"unique_id\": \"macro.dbt.get_create_view_as_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/view/create_view_as.sql\", \"original_file_path\": \"macros/materializations/models/view/create_view_as.sql\", \"name\": \"get_create_view_as_sql\", \"macro_sql\": \"{% macro get_create_view_as_sql(relation, sql) -%}\\n  {{ adapter.dispatch('get_create_view_as_sql', 'dbt')(relation, sql) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_create_view_as_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.8964942}, \"macro.dbt.default__get_create_view_as_sql\": {\"unique_id\": \"macro.dbt.default__get_create_view_as_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/view/create_view_as.sql\", \"original_file_path\": \"macros/materializations/models/view/create_view_as.sql\", \"name\": \"default__get_create_view_as_sql\", \"macro_sql\": \"{% macro default__get_create_view_as_sql(relation, sql) -%}\\n  {{ return(create_view_as(relation, sql)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.create_view_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.8969111}, \"macro.dbt.create_view_as\": {\"unique_id\": \"macro.dbt.create_view_as\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/view/create_view_as.sql\", \"original_file_path\": \"macros/materializations/models/view/create_view_as.sql\", \"name\": \"create_view_as\", \"macro_sql\": \"{% macro create_view_as(relation, sql) -%}\\n  {{ adapter.dispatch('create_view_as', 'dbt')(relation, sql) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__create_view_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.897373}, \"macro.dbt.default__create_view_as\": {\"unique_id\": \"macro.dbt.default__create_view_as\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/view/create_view_as.sql\", \"original_file_path\": \"macros/materializations/models/view/create_view_as.sql\", \"name\": \"default__create_view_as\", \"macro_sql\": \"{% macro default__create_view_as(relation, sql) -%}\\n  {%- set sql_header = config.get('sql_header', none) -%}\\n\\n  {{ sql_header if sql_header is not none }}\\n  create view {{ relation }} as (\\n    {{ sql }}\\n  );\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.898056}, \"macro.dbt.materialization_seed_default\": {\"unique_id\": \"macro.dbt.materialization_seed_default\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/seed.sql\", \"original_file_path\": \"macros/materializations/seeds/seed.sql\", \"name\": \"materialization_seed_default\", \"macro_sql\": \"{% materialization seed, default %}\\n\\n  {%- set identifier = model['alias'] -%}\\n  {%- set full_refresh_mode = (should_full_refresh()) -%}\\n\\n  {%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%}\\n\\n  {%- set exists_as_table = (old_relation is not none and old_relation.is_table) -%}\\n  {%- set exists_as_view = (old_relation is not none and old_relation.is_view) -%}\\n\\n  {%- set agate_table = load_agate_table() -%}\\n  {%- do store_result('agate_table', response='OK', agate_table=agate_table) -%}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  -- build model\\n  {% set create_table_sql = \\\"\\\" %}\\n  {% if exists_as_view %}\\n    {{ exceptions.raise_compiler_error(\\\"Cannot seed to '{}', it is a view\\\".format(old_relation)) }}\\n  {% elif exists_as_table %}\\n    {% set create_table_sql = reset_csv_table(model, full_refresh_mode, old_relation, agate_table) %}\\n  {% else %}\\n    {% set create_table_sql = create_csv_table(model, agate_table) %}\\n  {% endif %}\\n\\n  {% set code = 'CREATE' if full_refresh_mode else 'INSERT' %}\\n  {% set rows_affected = (agate_table.rows | length) %}\\n  {% set sql = load_csv_rows(model, agate_table) %}\\n\\n  {% call noop_statement('main', code ~ ' ' ~ rows_affected, code, rows_affected) %}\\n    {{ create_table_sql }};\\n    -- dbt seed --\\n    {{ sql }}\\n  {% endcall %}\\n\\n  {% set target_relation = this.incorporate(type='table') %}\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {% if full_refresh_mode or not exists_as_table %}\\n    {% do create_indexes(target_relation) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  -- `COMMIT` happens here\\n  {{ adapter.commit() }}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{% endmaterialization %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.should_full_refresh\", \"macro.dbt.run_hooks\", \"macro.dbt.reset_csv_table\", \"macro.dbt.create_csv_table\", \"macro.dbt.load_csv_rows\", \"macro.dbt.noop_statement\", \"macro.dbt.persist_docs\", \"macro.dbt.create_indexes\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.905844}, \"macro.dbt.create_csv_table\": {\"unique_id\": \"macro.dbt.create_csv_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"create_csv_table\", \"macro_sql\": \"{% macro create_csv_table(model, agate_table) -%}\\n  {{ adapter.dispatch('create_csv_table', 'dbt')(model, agate_table) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__create_csv_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.9181492}, \"macro.dbt.default__create_csv_table\": {\"unique_id\": \"macro.dbt.default__create_csv_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"default__create_csv_table\", \"macro_sql\": \"{% macro default__create_csv_table(model, agate_table) %}\\n  {%- set column_override = model['config'].get('column_types', {}) -%}\\n  {%- set quote_seed_column = model['config'].get('quote_columns', None) -%}\\n\\n  {% set sql %}\\n    create table {{ this.render() }} (\\n        {%- for col_name in agate_table.column_names -%}\\n            {%- set inferred_type = adapter.convert_type(agate_table, loop.index0) -%}\\n            {%- set type = column_override.get(col_name, inferred_type) -%}\\n            {%- set column_name = (col_name | string) -%}\\n            {{ adapter.quote_seed_column(column_name, quote_seed_column) }} {{ type }} {%- if not loop.last -%}, {%- endif -%}\\n        {%- endfor -%}\\n    )\\n  {% endset %}\\n\\n  {% call statement('_') -%}\\n    {{ sql }}\\n  {%- endcall %}\\n\\n  {{ return(sql) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.920773}, \"macro.dbt.reset_csv_table\": {\"unique_id\": \"macro.dbt.reset_csv_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"reset_csv_table\", \"macro_sql\": \"{% macro reset_csv_table(model, full_refresh, old_relation, agate_table) -%}\\n  {{ adapter.dispatch('reset_csv_table', 'dbt')(model, full_refresh, old_relation, agate_table) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__reset_csv_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.921389}, \"macro.dbt.default__reset_csv_table\": {\"unique_id\": \"macro.dbt.default__reset_csv_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"default__reset_csv_table\", \"macro_sql\": \"{% macro default__reset_csv_table(model, full_refresh, old_relation, agate_table) %}\\n    {% set sql = \\\"\\\" %}\\n    {% if full_refresh %}\\n        {{ adapter.drop_relation(old_relation) }}\\n        {% set sql = create_csv_table(model, agate_table) %}\\n    {% else %}\\n        {{ adapter.truncate_relation(old_relation) }}\\n        {% set sql = \\\"truncate table \\\" ~ old_relation %}\\n    {% endif %}\\n\\n    {{ return(sql) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.create_csv_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.922673}, \"macro.dbt.get_binding_char\": {\"unique_id\": \"macro.dbt.get_binding_char\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"get_binding_char\", \"macro_sql\": \"{% macro get_binding_char() -%}\\n  {{ adapter.dispatch('get_binding_char', 'dbt')() }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_binding_char\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.9230442}, \"macro.dbt.default__get_binding_char\": {\"unique_id\": \"macro.dbt.default__get_binding_char\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"default__get_binding_char\", \"macro_sql\": \"{% macro default__get_binding_char() %}\\n  {{ return('%s') }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.923341}, \"macro.dbt.get_batch_size\": {\"unique_id\": \"macro.dbt.get_batch_size\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"get_batch_size\", \"macro_sql\": \"{% macro get_batch_size() -%}\\n  {{ return(adapter.dispatch('get_batch_size', 'dbt')()) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_batch_size\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.923764}, \"macro.dbt.default__get_batch_size\": {\"unique_id\": \"macro.dbt.default__get_batch_size\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"default__get_batch_size\", \"macro_sql\": \"{% macro default__get_batch_size() %}\\n  {{ return(10000) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.924055}, \"macro.dbt.get_seed_column_quoted_csv\": {\"unique_id\": \"macro.dbt.get_seed_column_quoted_csv\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"get_seed_column_quoted_csv\", \"macro_sql\": \"{% macro get_seed_column_quoted_csv(model, column_names) %}\\n  {%- set quote_seed_column = model['config'].get('quote_columns', None) -%}\\n    {% set quoted = [] %}\\n    {% for col in column_names -%}\\n        {%- do quoted.append(adapter.quote_seed_column(col, quote_seed_column)) -%}\\n    {%- endfor %}\\n\\n    {%- set dest_cols_csv = quoted | join(', ') -%}\\n    {{ return(dest_cols_csv) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.925326}, \"macro.dbt.load_csv_rows\": {\"unique_id\": \"macro.dbt.load_csv_rows\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"load_csv_rows\", \"macro_sql\": \"{% macro load_csv_rows(model, agate_table) -%}\\n  {{ adapter.dispatch('load_csv_rows', 'dbt')(model, agate_table) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__load_csv_rows\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.9259362}, \"macro.dbt.default__load_csv_rows\": {\"unique_id\": \"macro.dbt.default__load_csv_rows\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"default__load_csv_rows\", \"macro_sql\": \"{% macro default__load_csv_rows(model, agate_table) %}\\n\\n  {% set batch_size = get_batch_size() %}\\n\\n  {% set cols_sql = get_seed_column_quoted_csv(model, agate_table.column_names) %}\\n  {% set bindings = [] %}\\n\\n  {% set statements = [] %}\\n\\n  {% for chunk in agate_table.rows | batch(batch_size) %}\\n      {% set bindings = [] %}\\n\\n      {% for row in chunk %}\\n          {% do bindings.extend(row) %}\\n      {% endfor %}\\n\\n      {% set sql %}\\n          insert into {{ this.render() }} ({{ cols_sql }}) values\\n          {% for row in chunk -%}\\n              ({%- for column in agate_table.column_names -%}\\n                  {{ get_binding_char() }}\\n                  {%- if not loop.last%},{%- endif %}\\n              {%- endfor -%})\\n              {%- if not loop.last%},{%- endif %}\\n          {%- endfor %}\\n      {% endset %}\\n\\n      {% do adapter.add_query(sql, bindings=bindings, abridge_sql_log=True) %}\\n\\n      {% if loop.index0 == 0 %}\\n          {% do statements.append(sql) %}\\n      {% endif %}\\n  {% endfor %}\\n\\n  {# Return SQL so we can render it out into the compiled files #}\\n  {{ return(statements[0]) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_batch_size\", \"macro.dbt.get_seed_column_quoted_csv\", \"macro.dbt.get_binding_char\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.9291992}, \"macro.dbt.generate_alias_name\": {\"unique_id\": \"macro.dbt.generate_alias_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/get_custom_name/get_custom_alias.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_alias.sql\", \"name\": \"generate_alias_name\", \"macro_sql\": \"{% macro generate_alias_name(custom_alias_name=none, node=none) -%}\\n    {% do return(adapter.dispatch('generate_alias_name', 'dbt')(custom_alias_name, node)) %}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__generate_alias_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.9304068}, \"macro.dbt.default__generate_alias_name\": {\"unique_id\": \"macro.dbt.default__generate_alias_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/get_custom_name/get_custom_alias.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_alias.sql\", \"name\": \"default__generate_alias_name\", \"macro_sql\": \"{% macro default__generate_alias_name(custom_alias_name=none, node=none) -%}\\n\\n    {%- if custom_alias_name is none -%}\\n\\n        {{ node.name }}\\n\\n    {%- else -%}\\n\\n        {{ custom_alias_name | trim }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.930997}, \"macro.dbt.generate_schema_name\": {\"unique_id\": \"macro.dbt.generate_schema_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/get_custom_name/get_custom_schema.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_schema.sql\", \"name\": \"generate_schema_name\", \"macro_sql\": \"{% macro generate_schema_name(custom_schema_name=none, node=none) -%}\\n    {{ return(adapter.dispatch('generate_schema_name', 'dbt')(custom_schema_name, node)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__generate_schema_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.93258}, \"macro.dbt.default__generate_schema_name\": {\"unique_id\": \"macro.dbt.default__generate_schema_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/get_custom_name/get_custom_schema.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_schema.sql\", \"name\": \"default__generate_schema_name\", \"macro_sql\": \"{% macro default__generate_schema_name(custom_schema_name, node) -%}\\n\\n    {%- set default_schema = target.schema -%}\\n    {%- if custom_schema_name is none -%}\\n\\n        {{ default_schema }}\\n\\n    {%- else -%}\\n\\n        {{ default_schema }}_{{ custom_schema_name | trim }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.933256}, \"macro.dbt.generate_schema_name_for_env\": {\"unique_id\": \"macro.dbt.generate_schema_name_for_env\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/get_custom_name/get_custom_schema.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_schema.sql\", \"name\": \"generate_schema_name_for_env\", \"macro_sql\": \"{% macro generate_schema_name_for_env(custom_schema_name, node) -%}\\n\\n    {%- set default_schema = target.schema -%}\\n    {%- if target.name == 'prod' and custom_schema_name is not none -%}\\n\\n        {{ custom_schema_name | trim }}\\n\\n    {%- else -%}\\n\\n        {{ default_schema }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.933998}, \"macro.dbt.generate_database_name\": {\"unique_id\": \"macro.dbt.generate_database_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/get_custom_name/get_custom_database.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_database.sql\", \"name\": \"generate_database_name\", \"macro_sql\": \"{% macro generate_database_name(custom_database_name=none, node=none) -%}\\n    {% do return(adapter.dispatch('generate_database_name', 'dbt')(custom_database_name, node)) %}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__generate_database_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.93523}, \"macro.dbt.default__generate_database_name\": {\"unique_id\": \"macro.dbt.default__generate_database_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/get_custom_name/get_custom_database.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_database.sql\", \"name\": \"default__generate_database_name\", \"macro_sql\": \"{% macro default__generate_database_name(custom_database_name=none, node=none) -%}\\n    {%- set default_database = target.database -%}\\n    {%- if custom_database_name is none -%}\\n\\n        {{ default_database }}\\n\\n    {%- else -%}\\n\\n        {{ custom_database_name }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.93588}, \"macro.dbt.default__test_relationships\": {\"unique_id\": \"macro.dbt.default__test_relationships\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/generic_test_sql/relationships.sql\", \"original_file_path\": \"macros/generic_test_sql/relationships.sql\", \"name\": \"default__test_relationships\", \"macro_sql\": \"{% macro default__test_relationships(model, column_name, to, field) %}\\n\\nwith child as (\\n    select {{ column_name }} as from_field\\n    from {{ model }}\\n    where {{ column_name }} is not null\\n),\\n\\nparent as (\\n    select {{ field }} as to_field\\n    from {{ to }}\\n)\\n\\nselect\\n    from_field\\n\\nfrom child\\nleft join parent\\n    on child.from_field = parent.to_field\\n\\nwhere parent.to_field is null\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.9369469}, \"macro.dbt.default__test_not_null\": {\"unique_id\": \"macro.dbt.default__test_not_null\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/generic_test_sql/not_null.sql\", \"original_file_path\": \"macros/generic_test_sql/not_null.sql\", \"name\": \"default__test_not_null\", \"macro_sql\": \"{% macro default__test_not_null(model, column_name) %}\\n\\nselect *\\nfrom {{ model }}\\nwhere {{ column_name }} is null\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.9375691}, \"macro.dbt.default__test_unique\": {\"unique_id\": \"macro.dbt.default__test_unique\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/generic_test_sql/unique.sql\", \"original_file_path\": \"macros/generic_test_sql/unique.sql\", \"name\": \"default__test_unique\", \"macro_sql\": \"{% macro default__test_unique(model, column_name) %}\\n\\nselect\\n    {{ column_name }} as unique_field,\\n    count(*) as n_records\\n\\nfrom {{ model }}\\nwhere {{ column_name }} is not null\\ngroup by {{ column_name }}\\nhaving count(*) > 1\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.9383721}, \"macro.dbt.default__test_accepted_values\": {\"unique_id\": \"macro.dbt.default__test_accepted_values\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/generic_test_sql/accepted_values.sql\", \"original_file_path\": \"macros/generic_test_sql/accepted_values.sql\", \"name\": \"default__test_accepted_values\", \"macro_sql\": \"{% macro default__test_accepted_values(model, column_name, values, quote=True) %}\\n\\nwith all_values as (\\n\\n    select\\n        {{ column_name }} as value_field,\\n        count(*) as n_records\\n\\n    from {{ model }}\\n    group by {{ column_name }}\\n\\n)\\n\\nselect *\\nfrom all_values\\nwhere value_field not in (\\n    {% for value in values -%}\\n        {% if quote -%}\\n        '{{ value }}'\\n        {%- else -%}\\n        {{ value }}\\n        {%- endif -%}\\n        {%- if not loop.last -%},{%- endif %}\\n    {%- endfor %}\\n)\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.940022}, \"macro.dbt.statement\": {\"unique_id\": \"macro.dbt.statement\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/etc/statement.sql\", \"original_file_path\": \"macros/etc/statement.sql\", \"name\": \"statement\", \"macro_sql\": \"{% macro statement(name=None, fetch_result=False, auto_begin=True) -%}\\n  {%- if execute: -%}\\n    {%- set sql = caller() -%}\\n\\n    {%- if name == 'main' -%}\\n      {{ log('Writing runtime SQL for node \\\"{}\\\"'.format(model['unique_id'])) }}\\n      {{ write(sql) }}\\n    {%- endif -%}\\n\\n    {%- set res, table = adapter.execute(sql, auto_begin=auto_begin, fetch=fetch_result) -%}\\n    {%- if name is not none -%}\\n      {{ store_result(name, response=res, agate_table=table) }}\\n    {%- endif -%}\\n\\n  {%- endif -%}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.943184}, \"macro.dbt.noop_statement\": {\"unique_id\": \"macro.dbt.noop_statement\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/etc/statement.sql\", \"original_file_path\": \"macros/etc/statement.sql\", \"name\": \"noop_statement\", \"macro_sql\": \"{% macro noop_statement(name=None, message=None, code=None, rows_affected=None, res=None) -%}\\n  {%- set sql = caller() -%}\\n\\n  {%- if name == 'main' -%}\\n    {{ log('Writing runtime SQL for node \\\"{}\\\"'.format(model['unique_id'])) }}\\n    {{ write(sql) }}\\n  {%- endif -%}\\n\\n  {%- if name is not none -%}\\n    {{ store_raw_result(name, message=message, code=code, rows_affected=rows_affected, agate_table=res) }}\\n  {%- endif -%}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.944719}, \"macro.dbt.run_query\": {\"unique_id\": \"macro.dbt.run_query\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/etc/statement.sql\", \"original_file_path\": \"macros/etc/statement.sql\", \"name\": \"run_query\", \"macro_sql\": \"{% macro run_query(sql) %}\\n  {% call statement(\\\"run_query_statement\\\", fetch_result=true, auto_begin=false) %}\\n    {{ sql }}\\n  {% endcall %}\\n\\n  {% do return(load_result(\\\"run_query_statement\\\").table) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.94549}, \"macro.dbt.convert_datetime\": {\"unique_id\": \"macro.dbt.convert_datetime\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"name\": \"convert_datetime\", \"macro_sql\": \"{% macro convert_datetime(date_str, date_fmt) %}\\n\\n  {% set error_msg -%}\\n      The provided partition date '{{ date_str }}' does not match the expected format '{{ date_fmt }}'\\n  {%- endset %}\\n\\n  {% set res = try_or_compiler_error(error_msg, modules.datetime.datetime.strptime, date_str.strip(), date_fmt) %}\\n  {{ return(res) }}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.950737}, \"macro.dbt.dates_in_range\": {\"unique_id\": \"macro.dbt.dates_in_range\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"name\": \"dates_in_range\", \"macro_sql\": \"{% macro dates_in_range(start_date_str, end_date_str=none, in_fmt=\\\"%Y%m%d\\\", out_fmt=\\\"%Y%m%d\\\") %}\\n    {% set end_date_str = start_date_str if end_date_str is none else end_date_str %}\\n\\n    {% set start_date = convert_datetime(start_date_str, in_fmt) %}\\n    {% set end_date = convert_datetime(end_date_str, in_fmt) %}\\n\\n    {% set day_count = (end_date - start_date).days %}\\n    {% if day_count < 0 %}\\n        {% set msg -%}\\n            Partition start date is after the end date ({{ start_date }}, {{ end_date }})\\n        {%- endset %}\\n\\n        {{ exceptions.raise_compiler_error(msg, model) }}\\n    {% endif %}\\n\\n    {% set date_list = [] %}\\n    {% for i in range(0, day_count + 1) %}\\n        {% set the_date = (modules.datetime.timedelta(days=i) + start_date) %}\\n        {% if not out_fmt %}\\n            {% set _ = date_list.append(the_date) %}\\n        {% else %}\\n            {% set _ = date_list.append(the_date.strftime(out_fmt)) %}\\n        {% endif %}\\n    {% endfor %}\\n\\n    {{ return(date_list) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.convert_datetime\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.954061}, \"macro.dbt.partition_range\": {\"unique_id\": \"macro.dbt.partition_range\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"name\": \"partition_range\", \"macro_sql\": \"{% macro partition_range(raw_partition_date, date_fmt='%Y%m%d') %}\\n    {% set partition_range = (raw_partition_date | string).split(\\\",\\\") %}\\n\\n    {% if (partition_range | length) == 1 %}\\n      {% set start_date = partition_range[0] %}\\n      {% set end_date = none %}\\n    {% elif (partition_range | length) == 2 %}\\n      {% set start_date = partition_range[0] %}\\n      {% set end_date = partition_range[1] %}\\n    {% else %}\\n      {{ exceptions.raise_compiler_error(\\\"Invalid partition time. Expected format: {Start Date}[,{End Date}]. Got: \\\" ~ raw_partition_date) }}\\n    {% endif %}\\n\\n    {{ return(dates_in_range(start_date, end_date, in_fmt=date_fmt)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.dates_in_range\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.956046}, \"macro.dbt.py_current_timestring\": {\"unique_id\": \"macro.dbt.py_current_timestring\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"name\": \"py_current_timestring\", \"macro_sql\": \"{% macro py_current_timestring() %}\\n    {% set dt = modules.datetime.datetime.now() %}\\n    {% do return(dt.strftime(\\\"%Y%m%d%H%M%S%f\\\")) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.956654}, \"macro.dbt.create_schema\": {\"unique_id\": \"macro.dbt.create_schema\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/schema.sql\", \"original_file_path\": \"macros/adapters/schema.sql\", \"name\": \"create_schema\", \"macro_sql\": \"{% macro create_schema(relation) -%}\\n  {{ adapter.dispatch('create_schema', 'dbt')(relation) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__create_schema\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.9578362}, \"macro.dbt.default__create_schema\": {\"unique_id\": \"macro.dbt.default__create_schema\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/schema.sql\", \"original_file_path\": \"macros/adapters/schema.sql\", \"name\": \"default__create_schema\", \"macro_sql\": \"{% macro default__create_schema(relation) -%}\\n  {%- call statement('create_schema') -%}\\n    create schema if not exists {{ relation.without_identifier() }}\\n  {% endcall %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.9583108}, \"macro.dbt.drop_schema\": {\"unique_id\": \"macro.dbt.drop_schema\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/schema.sql\", \"original_file_path\": \"macros/adapters/schema.sql\", \"name\": \"drop_schema\", \"macro_sql\": \"{% macro drop_schema(relation) -%}\\n  {{ adapter.dispatch('drop_schema', 'dbt')(relation) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__drop_schema\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.9587321}, \"macro.dbt.default__drop_schema\": {\"unique_id\": \"macro.dbt.default__drop_schema\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/schema.sql\", \"original_file_path\": \"macros/adapters/schema.sql\", \"name\": \"default__drop_schema\", \"macro_sql\": \"{% macro default__drop_schema(relation) -%}\\n  {%- call statement('drop_schema') -%}\\n    drop schema if exists {{ relation.without_identifier() }} cascade\\n  {% endcall %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.9592059}, \"macro.dbt.get_create_index_sql\": {\"unique_id\": \"macro.dbt.get_create_index_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"name\": \"get_create_index_sql\", \"macro_sql\": \"{% macro get_create_index_sql(relation, index_dict) -%}\\n  {{ return(adapter.dispatch('get_create_index_sql', 'dbt')(relation, index_dict)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_create_index_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.9605691}, \"macro.dbt.default__get_create_index_sql\": {\"unique_id\": \"macro.dbt.default__get_create_index_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"name\": \"default__get_create_index_sql\", \"macro_sql\": \"{% macro default__get_create_index_sql(relation, index_dict) -%}\\n  {% do return(None) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.9609149}, \"macro.dbt.create_indexes\": {\"unique_id\": \"macro.dbt.create_indexes\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"name\": \"create_indexes\", \"macro_sql\": \"{% macro create_indexes(relation) -%}\\n  {{ adapter.dispatch('create_indexes', 'dbt')(relation) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__create_indexes\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.9613152}, \"macro.dbt.default__create_indexes\": {\"unique_id\": \"macro.dbt.default__create_indexes\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"name\": \"default__create_indexes\", \"macro_sql\": \"{% macro default__create_indexes(relation) -%}\\n  {%- set _indexes = config.get('indexes', default=[]) -%}\\n\\n  {% for _index_dict in _indexes %}\\n    {% set create_index_sql = get_create_index_sql(relation, _index_dict) %}\\n    {% if create_index_sql %}\\n      {% do run_query(create_index_sql) %}\\n    {% endif %}\\n  {% endfor %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_create_index_sql\", \"macro.dbt.run_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.962351}, \"macro.dbt.make_temp_relation\": {\"unique_id\": \"macro.dbt.make_temp_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"make_temp_relation\", \"macro_sql\": \"{% macro make_temp_relation(base_relation, suffix='__dbt_tmp') %}\\n  {{ return(adapter.dispatch('make_temp_relation', 'dbt')(base_relation, suffix))}}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_temp_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.9670699}, \"macro.dbt.default__make_temp_relation\": {\"unique_id\": \"macro.dbt.default__make_temp_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"default__make_temp_relation\", \"macro_sql\": \"{% macro default__make_temp_relation(base_relation, suffix) %}\\n    {% set tmp_identifier = base_relation.identifier ~ suffix %}\\n    {% set tmp_relation = base_relation.incorporate(\\n                                path={\\\"identifier\\\": tmp_identifier}) -%}\\n\\n    {% do return(tmp_relation) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.967857}, \"macro.dbt.drop_relation\": {\"unique_id\": \"macro.dbt.drop_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"drop_relation\", \"macro_sql\": \"{% macro drop_relation(relation) -%}\\n  {{ return(adapter.dispatch('drop_relation', 'dbt')(relation)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__drop_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.9683268}, \"macro.dbt.default__drop_relation\": {\"unique_id\": \"macro.dbt.default__drop_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"default__drop_relation\", \"macro_sql\": \"{% macro default__drop_relation(relation) -%}\\n  {% call statement('drop_relation', auto_begin=False) -%}\\n    drop {{ relation.type }} if exists {{ relation }} cascade\\n  {%- endcall %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.968875}, \"macro.dbt.truncate_relation\": {\"unique_id\": \"macro.dbt.truncate_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"truncate_relation\", \"macro_sql\": \"{% macro truncate_relation(relation) -%}\\n  {{ return(adapter.dispatch('truncate_relation', 'dbt')(relation)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__truncate_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.969353}, \"macro.dbt.default__truncate_relation\": {\"unique_id\": \"macro.dbt.default__truncate_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"default__truncate_relation\", \"macro_sql\": \"{% macro default__truncate_relation(relation) -%}\\n  {% call statement('truncate_relation') -%}\\n    truncate table {{ relation }}\\n  {%- endcall %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.9697769}, \"macro.dbt.rename_relation\": {\"unique_id\": \"macro.dbt.rename_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"rename_relation\", \"macro_sql\": \"{% macro rename_relation(from_relation, to_relation) -%}\\n  {{ return(adapter.dispatch('rename_relation', 'dbt')(from_relation, to_relation)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__rename_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.9703019}, \"macro.dbt.default__rename_relation\": {\"unique_id\": \"macro.dbt.default__rename_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"default__rename_relation\", \"macro_sql\": \"{% macro default__rename_relation(from_relation, to_relation) -%}\\n  {% set target_name = adapter.quote_as_configured(to_relation.identifier, 'identifier') %}\\n  {% call statement('rename_relation') -%}\\n    alter table {{ from_relation }} rename to {{ target_name }}\\n  {%- endcall %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.971044}, \"macro.dbt.get_or_create_relation\": {\"unique_id\": \"macro.dbt.get_or_create_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"get_or_create_relation\", \"macro_sql\": \"{% macro get_or_create_relation(database, schema, identifier, type) -%}\\n  {{ return(adapter.dispatch('get_or_create_relation', 'dbt')(database, schema, identifier, type)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_or_create_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.9716868}, \"macro.dbt.default__get_or_create_relation\": {\"unique_id\": \"macro.dbt.default__get_or_create_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"default__get_or_create_relation\", \"macro_sql\": \"{% macro default__get_or_create_relation(database, schema, identifier, type) %}\\n  {%- set target_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) %}\\n\\n  {% if target_relation %}\\n    {% do return([true, target_relation]) %}\\n  {% endif %}\\n\\n  {%- set new_relation = api.Relation.create(\\n      database=database,\\n      schema=schema,\\n      identifier=identifier,\\n      type=type\\n  ) -%}\\n  {% do return([false, new_relation]) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.973294}, \"macro.dbt.load_relation\": {\"unique_id\": \"macro.dbt.load_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"load_relation\", \"macro_sql\": \"{% macro load_relation(relation) %}\\n  {% do return(adapter.get_relation(\\n    database=relation.database,\\n    schema=relation.schema,\\n    identifier=relation.identifier\\n  )) -%}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.973898}, \"macro.dbt.drop_relation_if_exists\": {\"unique_id\": \"macro.dbt.drop_relation_if_exists\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"drop_relation_if_exists\", \"macro_sql\": \"{% macro drop_relation_if_exists(relation) %}\\n  {% if relation is not none %}\\n    {{ adapter.drop_relation(relation) }}\\n  {% endif %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.974398}, \"macro.dbt.current_timestamp\": {\"unique_id\": \"macro.dbt.current_timestamp\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/freshness.sql\", \"original_file_path\": \"macros/adapters/freshness.sql\", \"name\": \"current_timestamp\", \"macro_sql\": \"{% macro current_timestamp() -%}\\n  {{ adapter.dispatch('current_timestamp', 'dbt')() }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.9758022}, \"macro.dbt.default__current_timestamp\": {\"unique_id\": \"macro.dbt.default__current_timestamp\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/freshness.sql\", \"original_file_path\": \"macros/adapters/freshness.sql\", \"name\": \"default__current_timestamp\", \"macro_sql\": \"{% macro default__current_timestamp() -%}\\n  {{ exceptions.raise_not_implemented(\\n    'current_timestamp macro not implemented for adapter '+adapter.type()) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.9761899}, \"macro.dbt.collect_freshness\": {\"unique_id\": \"macro.dbt.collect_freshness\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/freshness.sql\", \"original_file_path\": \"macros/adapters/freshness.sql\", \"name\": \"collect_freshness\", \"macro_sql\": \"{% macro collect_freshness(source, loaded_at_field, filter) %}\\n  {{ return(adapter.dispatch('collect_freshness', 'dbt')(source, loaded_at_field, filter))}}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__collect_freshness\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.9767869}, \"macro.dbt.default__collect_freshness\": {\"unique_id\": \"macro.dbt.default__collect_freshness\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/freshness.sql\", \"original_file_path\": \"macros/adapters/freshness.sql\", \"name\": \"default__collect_freshness\", \"macro_sql\": \"{% macro default__collect_freshness(source, loaded_at_field, filter) %}\\n  {% call statement('collect_freshness', fetch_result=True, auto_begin=False) -%}\\n    select\\n      max({{ loaded_at_field }}) as max_loaded_at,\\n      {{ current_timestamp() }} as snapshotted_at\\n    from {{ source }}\\n    {% if filter %}\\n    where {{ filter }}\\n    {% endif %}\\n  {% endcall %}\\n  {{ return(load_result('collect_freshness').table) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\", \"macro.dbt.current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.977885}, \"macro.dbt.alter_column_comment\": {\"unique_id\": \"macro.dbt.alter_column_comment\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"name\": \"alter_column_comment\", \"macro_sql\": \"{% macro alter_column_comment(relation, column_dict) -%}\\n  {{ return(adapter.dispatch('alter_column_comment', 'dbt')(relation, column_dict)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__alter_column_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.979867}, \"macro.dbt.default__alter_column_comment\": {\"unique_id\": \"macro.dbt.default__alter_column_comment\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"name\": \"default__alter_column_comment\", \"macro_sql\": \"{% macro default__alter_column_comment(relation, column_dict) -%}\\n  {{ exceptions.raise_not_implemented(\\n    'alter_column_comment macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.98031}, \"macro.dbt.alter_relation_comment\": {\"unique_id\": \"macro.dbt.alter_relation_comment\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"name\": \"alter_relation_comment\", \"macro_sql\": \"{% macro alter_relation_comment(relation, relation_comment) -%}\\n  {{ return(adapter.dispatch('alter_relation_comment', 'dbt')(relation, relation_comment)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__alter_relation_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.980829}, \"macro.dbt.default__alter_relation_comment\": {\"unique_id\": \"macro.dbt.default__alter_relation_comment\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"name\": \"default__alter_relation_comment\", \"macro_sql\": \"{% macro default__alter_relation_comment(relation, relation_comment) -%}\\n  {{ exceptions.raise_not_implemented(\\n    'alter_relation_comment macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.9812522}, \"macro.dbt.persist_docs\": {\"unique_id\": \"macro.dbt.persist_docs\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"name\": \"persist_docs\", \"macro_sql\": \"{% macro persist_docs(relation, model, for_relation=true, for_columns=true) -%}\\n  {{ return(adapter.dispatch('persist_docs', 'dbt')(relation, model, for_relation, for_columns)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__persist_docs\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.981956}, \"macro.dbt.default__persist_docs\": {\"unique_id\": \"macro.dbt.default__persist_docs\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"name\": \"default__persist_docs\", \"macro_sql\": \"{% macro default__persist_docs(relation, model, for_relation, for_columns) -%}\\n  {% if for_relation and config.persist_relation_docs() and model.description %}\\n    {% do run_query(alter_relation_comment(relation, model.description)) %}\\n  {% endif %}\\n\\n  {% if for_columns and config.persist_column_docs() and model.columns %}\\n    {% do run_query(alter_column_comment(relation, model.columns)) %}\\n  {% endif %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.run_query\", \"macro.dbt.alter_relation_comment\", \"macro.dbt.alter_column_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.9832299}, \"macro.dbt.get_catalog\": {\"unique_id\": \"macro.dbt.get_catalog\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"name\": \"get_catalog\", \"macro_sql\": \"{% macro get_catalog(information_schema, schemas) -%}\\n  {{ return(adapter.dispatch('get_catalog', 'dbt')(information_schema, schemas)) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_catalog\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.9874718}, \"macro.dbt.default__get_catalog\": {\"unique_id\": \"macro.dbt.default__get_catalog\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"name\": \"default__get_catalog\", \"macro_sql\": \"{% macro default__get_catalog(information_schema, schemas) -%}\\n\\n  {% set typename = adapter.type() %}\\n  {% set msg -%}\\n    get_catalog not implemented for {{ typename }}\\n  {%- endset %}\\n\\n  {{ exceptions.raise_compiler_error(msg) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.9881449}, \"macro.dbt.information_schema_name\": {\"unique_id\": \"macro.dbt.information_schema_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"name\": \"information_schema_name\", \"macro_sql\": \"{% macro information_schema_name(database) %}\\n  {{ return(adapter.dispatch('information_schema_name', 'dbt')(database)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__information_schema_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.98862}, \"macro.dbt.default__information_schema_name\": {\"unique_id\": \"macro.dbt.default__information_schema_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"name\": \"default__information_schema_name\", \"macro_sql\": \"{% macro default__information_schema_name(database) -%}\\n  {%- if database -%}\\n    {{ database }}.INFORMATION_SCHEMA\\n  {%- else -%}\\n    INFORMATION_SCHEMA\\n  {%- endif -%}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.989036}, \"macro.dbt.list_schemas\": {\"unique_id\": \"macro.dbt.list_schemas\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"name\": \"list_schemas\", \"macro_sql\": \"{% macro list_schemas(database) -%}\\n  {{ return(adapter.dispatch('list_schemas', 'dbt')(database)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__list_schemas\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.989502}, \"macro.dbt.default__list_schemas\": {\"unique_id\": \"macro.dbt.default__list_schemas\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"name\": \"default__list_schemas\", \"macro_sql\": \"{% macro default__list_schemas(database) -%}\\n  {% set sql %}\\n    select distinct schema_name\\n    from {{ information_schema_name(database) }}.SCHEMATA\\n    where catalog_name ilike '{{ database }}'\\n  {% endset %}\\n  {{ return(run_query(sql)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.information_schema_name\", \"macro.dbt.run_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.990141}, \"macro.dbt.check_schema_exists\": {\"unique_id\": \"macro.dbt.check_schema_exists\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"name\": \"check_schema_exists\", \"macro_sql\": \"{% macro check_schema_exists(information_schema, schema) -%}\\n  {{ return(adapter.dispatch('check_schema_exists', 'dbt')(information_schema, schema)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__check_schema_exists\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.9906712}, \"macro.dbt.default__check_schema_exists\": {\"unique_id\": \"macro.dbt.default__check_schema_exists\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"name\": \"default__check_schema_exists\", \"macro_sql\": \"{% macro default__check_schema_exists(information_schema, schema) -%}\\n  {% set sql -%}\\n        select count(*)\\n        from {{ information_schema.replace(information_schema_view='SCHEMATA') }}\\n        where catalog_name='{{ information_schema.database }}'\\n          and schema_name='{{ schema }}'\\n  {%- endset %}\\n  {{ return(run_query(sql)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.run_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.991599}, \"macro.dbt.list_relations_without_caching\": {\"unique_id\": \"macro.dbt.list_relations_without_caching\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"name\": \"list_relations_without_caching\", \"macro_sql\": \"{% macro list_relations_without_caching(schema_relation) %}\\n  {{ return(adapter.dispatch('list_relations_without_caching', 'dbt')(schema_relation)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__list_relations_without_caching\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.992081}, \"macro.dbt.default__list_relations_without_caching\": {\"unique_id\": \"macro.dbt.default__list_relations_without_caching\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"name\": \"default__list_relations_without_caching\", \"macro_sql\": \"{% macro default__list_relations_without_caching(schema_relation) %}\\n  {{ exceptions.raise_not_implemented(\\n    'list_relations_without_caching macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.9924932}, \"macro.dbt.get_columns_in_relation\": {\"unique_id\": \"macro.dbt.get_columns_in_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"name\": \"get_columns_in_relation\", \"macro_sql\": \"{% macro get_columns_in_relation(relation) -%}\\n  {{ return(adapter.dispatch('get_columns_in_relation', 'dbt')(relation)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_columns_in_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.9975512}, \"macro.dbt.default__get_columns_in_relation\": {\"unique_id\": \"macro.dbt.default__get_columns_in_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"name\": \"default__get_columns_in_relation\", \"macro_sql\": \"{% macro default__get_columns_in_relation(relation) -%}\\n  {{ exceptions.raise_not_implemented(\\n    'get_columns_in_relation macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.997951}, \"macro.dbt.sql_convert_columns_in_relation\": {\"unique_id\": \"macro.dbt.sql_convert_columns_in_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"name\": \"sql_convert_columns_in_relation\", \"macro_sql\": \"{% macro sql_convert_columns_in_relation(table) -%}\\n  {% set columns = [] %}\\n  {% for row in table %}\\n    {% do columns.append(api.Column(*row)) %}\\n  {% endfor %}\\n  {{ return(columns) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.9987469}, \"macro.dbt.get_columns_in_query\": {\"unique_id\": \"macro.dbt.get_columns_in_query\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"name\": \"get_columns_in_query\", \"macro_sql\": \"{% macro get_columns_in_query(select_sql) -%}\\n  {{ return(adapter.dispatch('get_columns_in_query', 'dbt')(select_sql)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_columns_in_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058600.9992452}, \"macro.dbt.default__get_columns_in_query\": {\"unique_id\": \"macro.dbt.default__get_columns_in_query\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"name\": \"default__get_columns_in_query\", \"macro_sql\": \"{% macro default__get_columns_in_query(select_sql) %}\\n    {% call statement('get_columns_in_query', fetch_result=True, auto_begin=False) -%}\\n        select * from (\\n            {{ select_sql }}\\n        ) as __dbt_sbq\\n        where false\\n        limit 0\\n    {% endcall %}\\n\\n    {{ return(load_result('get_columns_in_query').table.columns | map(attribute='name') | list) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058601.000154}, \"macro.dbt.alter_column_type\": {\"unique_id\": \"macro.dbt.alter_column_type\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"name\": \"alter_column_type\", \"macro_sql\": \"{% macro alter_column_type(relation, column_name, new_column_type) -%}\\n  {{ return(adapter.dispatch('alter_column_type', 'dbt')(relation, column_name, new_column_type)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__alter_column_type\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058601.0007622}, \"macro.dbt.default__alter_column_type\": {\"unique_id\": \"macro.dbt.default__alter_column_type\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"name\": \"default__alter_column_type\", \"macro_sql\": \"{% macro default__alter_column_type(relation, column_name, new_column_type) -%}\\n  {#\\n    1. Create a new column (w/ temp name and correct type)\\n    2. Copy data over to it\\n    3. Drop the existing column (cascade!)\\n    4. Rename the new column to existing column\\n  #}\\n  {%- set tmp_column = column_name + \\\"__dbt_alter\\\" -%}\\n\\n  {% call statement('alter_column_type') %}\\n    alter table {{ relation }} add column {{ adapter.quote(tmp_column) }} {{ new_column_type }};\\n    update {{ relation }} set {{ adapter.quote(tmp_column) }} = {{ adapter.quote(column_name) }};\\n    alter table {{ relation }} drop column {{ adapter.quote(column_name) }} cascade;\\n    alter table {{ relation }} rename column {{ adapter.quote(tmp_column) }} to {{ adapter.quote(column_name) }}\\n  {% endcall %}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058601.0023592}, \"macro.dbt.alter_relation_add_remove_columns\": {\"unique_id\": \"macro.dbt.alter_relation_add_remove_columns\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"name\": \"alter_relation_add_remove_columns\", \"macro_sql\": \"{% macro alter_relation_add_remove_columns(relation, add_columns = none, remove_columns = none) -%}\\n  {{ return(adapter.dispatch('alter_relation_add_remove_columns', 'dbt')(relation, add_columns, remove_columns)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__alter_relation_add_remove_columns\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058601.003041}, \"macro.dbt.default__alter_relation_add_remove_columns\": {\"unique_id\": \"macro.dbt.default__alter_relation_add_remove_columns\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"name\": \"default__alter_relation_add_remove_columns\", \"macro_sql\": \"{% macro default__alter_relation_add_remove_columns(relation, add_columns, remove_columns) %}\\n  \\n  {% if add_columns is none %}\\n    {% set add_columns = [] %}\\n  {% endif %}\\n  {% if remove_columns is none %}\\n    {% set remove_columns = [] %}\\n  {% endif %}\\n  \\n  {% set sql -%}\\n     \\n     alter {{ relation.type }} {{ relation }}\\n       \\n            {% for column in add_columns %}\\n               add column {{ column.name }} {{ column.data_type }}{{ ',' if not loop.last }}\\n            {% endfor %}{{ ',' if add_columns and remove_columns }}\\n            \\n            {% for column in remove_columns %}\\n                drop column {{ column.name }}{{ ',' if not loop.last }}\\n            {% endfor %}\\n  \\n  {%- endset -%}\\n\\n  {% do run_query(sql) %}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.run_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058601.005121}, \"macro.dbt.test_unique\": {\"unique_id\": \"macro.dbt.test_unique\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"tests/generic/builtin.sql\", \"original_file_path\": \"tests/generic/builtin.sql\", \"name\": \"test_unique\", \"macro_sql\": \"{% test unique(model, column_name) %}\\n    {% set macro = adapter.dispatch('test_unique', 'dbt') %}\\n    {{ macro(model, column_name) }}\\n{% endtest %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__test_unique\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058601.006654}, \"macro.dbt.test_not_null\": {\"unique_id\": \"macro.dbt.test_not_null\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"tests/generic/builtin.sql\", \"original_file_path\": \"tests/generic/builtin.sql\", \"name\": \"test_not_null\", \"macro_sql\": \"{% test not_null(model, column_name) %}\\n    {% set macro = adapter.dispatch('test_not_null', 'dbt') %}\\n    {{ macro(model, column_name) }}\\n{% endtest %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__test_not_null\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058601.007256}, \"macro.dbt.test_accepted_values\": {\"unique_id\": \"macro.dbt.test_accepted_values\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"tests/generic/builtin.sql\", \"original_file_path\": \"tests/generic/builtin.sql\", \"name\": \"test_accepted_values\", \"macro_sql\": \"{% test accepted_values(model, column_name, values, quote=True) %}\\n    {% set macro = adapter.dispatch('test_accepted_values', 'dbt') %}\\n    {{ macro(model, column_name, values, quote) }}\\n{% endtest %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__test_accepted_values\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058601.007999}, \"macro.dbt.test_relationships\": {\"unique_id\": \"macro.dbt.test_relationships\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"tests/generic/builtin.sql\", \"original_file_path\": \"tests/generic/builtin.sql\", \"name\": \"test_relationships\", \"macro_sql\": \"{% test relationships(model, column_name, to, field) %}\\n    {% set macro = adapter.dispatch('test_relationships', 'dbt') %}\\n    {{ macro(model, column_name, to, field) }}\\n{% endtest %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__test_relationships\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058601.008718}}, \"docs\": {\"dbt.__overview__\": {\"unique_id\": \"dbt.__overview__\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"overview.md\", \"original_file_path\": \"docs/overview.md\", \"name\": \"__overview__\", \"block_contents\": \"### Welcome!\\n\\nWelcome to the auto-generated documentation for your dbt project!\\n\\n### Navigation\\n\\nYou can use the `Project` and `Database` navigation tabs on the left side of the window to explore the models\\nin your project.\\n\\n#### Project Tab\\nThe `Project` tab mirrors the directory structure of your dbt project. In this tab, you can see all of the\\nmodels defined in your dbt project, as well as models imported from dbt packages.\\n\\n#### Database Tab\\nThe `Database` tab also exposes your models, but in a format that looks more like a database explorer. This view\\nshows relations (tables and views) grouped into database schemas. Note that ephemeral models are _not_ shown\\nin this interface, as they do not exist in the database.\\n\\n### Graph Exploration\\nYou can click the blue icon on the bottom-right corner of the page to view the lineage graph of your models.\\n\\nOn model pages, you'll see the immediate parents and children of the model you're exploring. By clicking the `Expand`\\nbutton at the top-right of this lineage pane, you'll be able to see all of the models that are used to build,\\nor are built from, the model you're exploring.\\n\\nOnce expanded, you'll be able to use the `--select` and `--exclude` model selection syntax to filter the\\nmodels in the graph. For more information on model selection, check out the [dbt docs](https://docs.getdbt.com/docs/model-selection-syntax).\\n\\nNote that you can also right-click on models to interactively filter and explore the graph.\\n\\n---\\n\\n### More information\\n\\n- [What is dbt](https://docs.getdbt.com/docs/introduction)?\\n- Read the [dbt viewpoint](https://docs.getdbt.com/docs/viewpoint)\\n- [Installation](https://docs.getdbt.com/docs/installation)\\n- Join the [dbt Community](https://www.getdbt.com/community/) for questions and discussion\"}}, \"exposures\": {}, \"metrics\": {\"metric.test.my_metric\": {\"fqn\": [\"test\", \"my_metric\"], \"unique_id\": \"metric.test.my_metric\", \"package_name\": \"test\", \"root_path\": \"/Users/jerco/dev/scratch/testy\", \"path\": \"metric.yml\", \"original_file_path\": \"models/metric.yml\", \"model\": \"ref('my_model')\", \"name\": \"my_metric\", \"description\": \"\", \"label\": \"Count records\", \"type\": \"count\", \"sql\": \"*\", \"timestamp\": \"updated_at\", \"filters\": [], \"time_grains\": [\"day\"], \"dimensions\": [], \"resource_type\": \"metric\", \"meta\": {}, \"tags\": [], \"sources\": [], \"depends_on\": {\"macros\": [], \"nodes\": [\"model.test.my_model\"]}, \"refs\": [[\"my_model\"]], \"created_at\": 1663058601.2723079}}, \"selectors\": {}, \"disabled\": {}, \"parent_map\": {\"model.test.my_model\": [], \"metric.test.my_metric\": [\"model.test.my_model\"]}, \"child_map\": {\"model.test.my_model\": [\"metric.test.my_metric\"], \"metric.test.my_metric\": []}}\n"
  },
  {
    "path": "tests/functional/artifacts/data/state/v5/manifest.json",
    "content": "{\"metadata\": {\"dbt_schema_version\": \"https://schemas.getdbt.com/dbt/manifest/v5.json\", \"dbt_version\": \"1.1.2\", \"generated_at\": \"2022-09-13T08:43:05.173401Z\", \"invocation_id\": \"46690f0c-35b6-44f7-95bc-3a91cbf87484\", \"env\": {}, \"project_id\": \"098f6bcd4621d373cade4e832627b4f6\", \"user_id\": null, \"send_anonymous_usage_stats\": false, \"adapter_type\": \"postgres\"}, \"nodes\": {\"model.test.my_model\": {\"raw_sql\": \"select 1 as id\", \"resource_type\": \"model\", \"depends_on\": {\"macros\": [], \"nodes\": []}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"materialized\": \"view\", \"persist_docs\": {}, \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": null, \"on_schema_change\": \"ignore\", \"post-hook\": [], \"pre-hook\": []}, \"database\": \"jerco\", \"schema\": \"dbt_jcohen\", \"fqn\": [\"test\", \"my_model\"], \"unique_id\": \"model.test.my_model\", \"package_name\": \"test\", \"root_path\": \"/Users/jerco/dev/scratch/testy\", \"path\": \"my_model.sql\", \"original_file_path\": \"models/my_model.sql\", \"name\": \"my_model\", \"alias\": \"my_model\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"479636cb85ce8d3b0f8db5ff13cf338b61254ad98d905630eac61f963e719e9d\"}, \"tags\": [], \"refs\": [], \"sources\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"compiled_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {}, \"created_at\": 1663058585.790391}}, \"sources\": {}, \"macros\": {\"macro.dbt_postgres.postgres__get_catalog\": {\"unique_id\": \"macro.dbt_postgres.postgres__get_catalog\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/catalog.sql\", \"original_file_path\": \"macros/catalog.sql\", \"name\": \"postgres__get_catalog\", \"macro_sql\": \"{% macro postgres__get_catalog(information_schema, schemas) -%}\\n\\n  {%- call statement('catalog', fetch_result=True) -%}\\n    {#\\n      If the user has multiple databases set and the first one is wrong, this will fail.\\n      But we won't fail in the case where there are multiple quoting-difference-only dbs, which is better.\\n    #}\\n    {% set database = information_schema.database %}\\n    {{ adapter.verify_database(database) }}\\n\\n    select\\n        '{{ database }}' as table_database,\\n        sch.nspname as table_schema,\\n        tbl.relname as table_name,\\n        case tbl.relkind\\n            when 'v' then 'VIEW'\\n            else 'BASE TABLE'\\n        end as table_type,\\n        tbl_desc.description as table_comment,\\n        col.attname as column_name,\\n        col.attnum as column_index,\\n        pg_catalog.format_type(col.atttypid, col.atttypmod) as column_type,\\n        col_desc.description as column_comment,\\n        pg_get_userbyid(tbl.relowner) as table_owner\\n\\n    from pg_catalog.pg_namespace sch\\n    join pg_catalog.pg_class tbl on tbl.relnamespace = sch.oid\\n    join pg_catalog.pg_attribute col on col.attrelid = tbl.oid\\n    left outer join pg_catalog.pg_description tbl_desc on (tbl_desc.objoid = tbl.oid and tbl_desc.objsubid = 0)\\n    left outer join pg_catalog.pg_description col_desc on (col_desc.objoid = tbl.oid and col_desc.objsubid = col.attnum)\\n\\n    where (\\n        {%- for schema in schemas -%}\\n          upper(sch.nspname) = upper('{{ schema }}'){%- if not loop.last %} or {% endif -%}\\n        {%- endfor -%}\\n      )\\n      and not pg_is_other_temp_schema(sch.oid) -- not a temporary schema belonging to another session\\n      and tbl.relpersistence in ('p', 'u') -- [p]ermanent table or [u]nlogged table. Exclude [t]emporary tables\\n      and tbl.relkind in ('r', 'v', 'f', 'p') -- o[r]dinary table, [v]iew, [f]oreign table, [p]artitioned table. Other values are [i]ndex, [S]equence, [c]omposite type, [t]OAST table, [m]aterialized view\\n      and col.attnum > 0 -- negative numbers are used for system columns such as oid\\n      and not col.attisdropped -- column as not been dropped\\n\\n    order by\\n        sch.nspname,\\n        tbl.relname,\\n        col.attnum\\n\\n  {%- endcall -%}\\n\\n  {{ return(load_result('catalog').table) }}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.2411761}, \"macro.dbt_postgres.postgres_get_relations\": {\"unique_id\": \"macro.dbt_postgres.postgres_get_relations\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/relations.sql\", \"original_file_path\": \"macros/relations.sql\", \"name\": \"postgres_get_relations\", \"macro_sql\": \"{% macro postgres_get_relations () -%}\\n\\n  {#\\n      -- in pg_depend, objid is the dependent, refobjid is the referenced object\\n      --  > a pg_depend entry indicates that the referenced object cannot be\\n      --  > dropped without also dropping the dependent object.\\n  #}\\n\\n  {%- call statement('relations', fetch_result=True) -%}\\n    with relation as (\\n        select\\n            pg_rewrite.ev_class as class,\\n            pg_rewrite.oid as id\\n        from pg_rewrite\\n    ),\\n    class as (\\n        select\\n            oid as id,\\n            relname as name,\\n            relnamespace as schema,\\n            relkind as kind\\n        from pg_class\\n    ),\\n    dependency as (\\n        select distinct\\n            pg_depend.objid as id,\\n            pg_depend.refobjid as ref\\n        from pg_depend\\n    ),\\n    schema as (\\n        select\\n            pg_namespace.oid as id,\\n            pg_namespace.nspname as name\\n        from pg_namespace\\n        where nspname != 'information_schema' and nspname not like 'pg\\\\_%'\\n    ),\\n    referenced as (\\n        select\\n            relation.id AS id,\\n            referenced_class.name ,\\n            referenced_class.schema ,\\n            referenced_class.kind\\n        from relation\\n        join class as referenced_class on relation.class=referenced_class.id\\n        where referenced_class.kind in ('r', 'v')\\n    ),\\n    relationships as (\\n        select\\n            referenced.name as referenced_name,\\n            referenced.schema as referenced_schema_id,\\n            dependent_class.name as dependent_name,\\n            dependent_class.schema as dependent_schema_id,\\n            referenced.kind as kind\\n        from referenced\\n        join dependency on referenced.id=dependency.id\\n        join class as dependent_class on dependency.ref=dependent_class.id\\n        where\\n            (referenced.name != dependent_class.name or\\n             referenced.schema != dependent_class.schema)\\n    )\\n\\n    select\\n        referenced_schema.name as referenced_schema,\\n        relationships.referenced_name as referenced_name,\\n        dependent_schema.name as dependent_schema,\\n        relationships.dependent_name as dependent_name\\n    from relationships\\n    join schema as dependent_schema on relationships.dependent_schema_id=dependent_schema.id\\n    join schema as referenced_schema on relationships.referenced_schema_id=referenced_schema.id\\n    group by referenced_schema, referenced_name, dependent_schema, dependent_name\\n    order by referenced_schema, referenced_name, dependent_schema, dependent_name;\\n\\n  {%- endcall -%}\\n\\n  {{ return(load_result('relations').table) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.2429922}, \"macro.dbt_postgres.postgres__create_table_as\": {\"unique_id\": \"macro.dbt_postgres.postgres__create_table_as\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__create_table_as\", \"macro_sql\": \"{% macro postgres__create_table_as(temporary, relation, sql) -%}\\n  {%- set unlogged = config.get('unlogged', default=false) -%}\\n  {%- set sql_header = config.get('sql_header', none) -%}\\n\\n  {{ sql_header if sql_header is not none }}\\n\\n  create {% if temporary -%}\\n    temporary\\n  {%- elif unlogged -%}\\n    unlogged\\n  {%- endif %} table {{ relation }}\\n  as (\\n    {{ sql }}\\n  );\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.258873}, \"macro.dbt_postgres.postgres__get_create_index_sql\": {\"unique_id\": \"macro.dbt_postgres.postgres__get_create_index_sql\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__get_create_index_sql\", \"macro_sql\": \"{% macro postgres__get_create_index_sql(relation, index_dict) -%}\\n  {%- set index_config = adapter.parse_index(index_dict) -%}\\n  {%- set comma_separated_columns = \\\", \\\".join(index_config.columns) -%}\\n  {%- set index_name = index_config.render(relation) -%}\\n\\n  create {% if index_config.unique -%}\\n    unique\\n  {%- endif %} index if not exists\\n  \\\"{{ index_name }}\\\"\\n  on {{ relation }} {% if index_config.type -%}\\n    using {{ index_config.type }}\\n  {%- endif %}\\n  ({{ comma_separated_columns }});\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.260246}, \"macro.dbt_postgres.postgres__create_schema\": {\"unique_id\": \"macro.dbt_postgres.postgres__create_schema\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__create_schema\", \"macro_sql\": \"{% macro postgres__create_schema(relation) -%}\\n  {% if relation.database -%}\\n    {{ adapter.verify_database(relation.database) }}\\n  {%- endif -%}\\n  {%- call statement('create_schema') -%}\\n    create schema if not exists {{ relation.without_identifier().include(database=False) }}\\n  {%- endcall -%}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.261101}, \"macro.dbt_postgres.postgres__drop_schema\": {\"unique_id\": \"macro.dbt_postgres.postgres__drop_schema\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__drop_schema\", \"macro_sql\": \"{% macro postgres__drop_schema(relation) -%}\\n  {% if relation.database -%}\\n    {{ adapter.verify_database(relation.database) }}\\n  {%- endif -%}\\n  {%- call statement('drop_schema') -%}\\n    drop schema if exists {{ relation.without_identifier().include(database=False) }} cascade\\n  {%- endcall -%}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.2619379}, \"macro.dbt_postgres.postgres__get_columns_in_relation\": {\"unique_id\": \"macro.dbt_postgres.postgres__get_columns_in_relation\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__get_columns_in_relation\", \"macro_sql\": \"{% macro postgres__get_columns_in_relation(relation) -%}\\n  {% call statement('get_columns_in_relation', fetch_result=True) %}\\n      select\\n          column_name,\\n          data_type,\\n          character_maximum_length,\\n          numeric_precision,\\n          numeric_scale\\n\\n      from {{ relation.information_schema('columns') }}\\n      where table_name = '{{ relation.identifier }}'\\n        {% if relation.schema %}\\n        and table_schema = '{{ relation.schema }}'\\n        {% endif %}\\n      order by ordinal_position\\n\\n  {% endcall %}\\n  {% set table = load_result('get_columns_in_relation').table %}\\n  {{ return(sql_convert_columns_in_relation(table)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\", \"macro.dbt.sql_convert_columns_in_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.263221}, \"macro.dbt_postgres.postgres__list_relations_without_caching\": {\"unique_id\": \"macro.dbt_postgres.postgres__list_relations_without_caching\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__list_relations_without_caching\", \"macro_sql\": \"{% macro postgres__list_relations_without_caching(schema_relation) %}\\n  {% call statement('list_relations_without_caching', fetch_result=True) -%}\\n    select\\n      '{{ schema_relation.database }}' as database,\\n      tablename as name,\\n      schemaname as schema,\\n      'table' as type\\n    from pg_tables\\n    where schemaname ilike '{{ schema_relation.schema }}'\\n    union all\\n    select\\n      '{{ schema_relation.database }}' as database,\\n      viewname as name,\\n      schemaname as schema,\\n      'view' as type\\n    from pg_views\\n    where schemaname ilike '{{ schema_relation.schema }}'\\n  {% endcall %}\\n  {{ return(load_result('list_relations_without_caching').table) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.264239}, \"macro.dbt_postgres.postgres__information_schema_name\": {\"unique_id\": \"macro.dbt_postgres.postgres__information_schema_name\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__information_schema_name\", \"macro_sql\": \"{% macro postgres__information_schema_name(database) -%}\\n  {% if database_name -%}\\n    {{ adapter.verify_database(database_name) }}\\n  {%- endif -%}\\n  information_schema\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.264697}, \"macro.dbt_postgres.postgres__list_schemas\": {\"unique_id\": \"macro.dbt_postgres.postgres__list_schemas\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__list_schemas\", \"macro_sql\": \"{% macro postgres__list_schemas(database) %}\\n  {% if database -%}\\n    {{ adapter.verify_database(database) }}\\n  {%- endif -%}\\n  {% call statement('list_schemas', fetch_result=True, auto_begin=False) %}\\n    select distinct nspname from pg_namespace\\n  {% endcall %}\\n  {{ return(load_result('list_schemas').table) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.265624}, \"macro.dbt_postgres.postgres__check_schema_exists\": {\"unique_id\": \"macro.dbt_postgres.postgres__check_schema_exists\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__check_schema_exists\", \"macro_sql\": \"{% macro postgres__check_schema_exists(information_schema, schema) -%}\\n  {% if information_schema.database -%}\\n    {{ adapter.verify_database(information_schema.database) }}\\n  {%- endif -%}\\n  {% call statement('check_schema_exists', fetch_result=True, auto_begin=False) %}\\n    select count(*) from pg_namespace where nspname = '{{ schema }}'\\n  {% endcall %}\\n  {{ return(load_result('check_schema_exists').table) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.2666838}, \"macro.dbt_postgres.postgres__current_timestamp\": {\"unique_id\": \"macro.dbt_postgres.postgres__current_timestamp\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__current_timestamp\", \"macro_sql\": \"{% macro postgres__current_timestamp() -%}\\n  now()\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.266898}, \"macro.dbt_postgres.postgres__snapshot_string_as_time\": {\"unique_id\": \"macro.dbt_postgres.postgres__snapshot_string_as_time\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__snapshot_string_as_time\", \"macro_sql\": \"{% macro postgres__snapshot_string_as_time(timestamp) -%}\\n    {%- set result = \\\"'\\\" ~ timestamp ~ \\\"'::timestamp without time zone\\\" -%}\\n    {{ return(result) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.2673979}, \"macro.dbt_postgres.postgres__snapshot_get_time\": {\"unique_id\": \"macro.dbt_postgres.postgres__snapshot_get_time\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__snapshot_get_time\", \"macro_sql\": \"{% macro postgres__snapshot_get_time() -%}\\n  {{ current_timestamp() }}::timestamp without time zone\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.267664}, \"macro.dbt_postgres.postgres__make_temp_relation\": {\"unique_id\": \"macro.dbt_postgres.postgres__make_temp_relation\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__make_temp_relation\", \"macro_sql\": \"{% macro postgres__make_temp_relation(base_relation, suffix) %}\\n    {% set dt = modules.datetime.datetime.now() %}\\n    {% set dtstring = dt.strftime(\\\"%H%M%S%f\\\") %}\\n    {% set suffix_length = suffix|length + dtstring|length %}\\n    {% set relation_max_name_length = 63 %}\\n    {% if suffix_length > relation_max_name_length %}\\n        {% do exceptions.raise_compiler_error('Temp relation suffix is too long (' ~ suffix|length ~ ' characters). Maximum length is ' ~ (relation_max_name_length - dtstring|length) ~ ' characters.') %}\\n    {% endif %}\\n    {% set tmp_identifier = base_relation.identifier[:relation_max_name_length - suffix_length] ~ suffix ~ dtstring %}\\n    {% do return(base_relation.incorporate(\\n                                  path={\\n                                    \\\"identifier\\\": tmp_identifier,\\n                                    \\\"schema\\\": none,\\n                                    \\\"database\\\": none\\n                                  })) -%}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.270232}, \"macro.dbt_postgres.postgres_escape_comment\": {\"unique_id\": \"macro.dbt_postgres.postgres_escape_comment\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres_escape_comment\", \"macro_sql\": \"{% macro postgres_escape_comment(comment) -%}\\n  {% if comment is not string %}\\n    {% do exceptions.raise_compiler_error('cannot escape a non-string: ' ~ comment) %}\\n  {% endif %}\\n  {%- set magic = '$dbt_comment_literal_block$' -%}\\n  {%- if magic in comment -%}\\n    {%- do exceptions.raise_compiler_error('The string ' ~ magic ~ ' is not allowed in comments.') -%}\\n  {%- endif -%}\\n  {{ magic }}{{ comment }}{{ magic }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.271394}, \"macro.dbt_postgres.postgres__alter_relation_comment\": {\"unique_id\": \"macro.dbt_postgres.postgres__alter_relation_comment\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__alter_relation_comment\", \"macro_sql\": \"{% macro postgres__alter_relation_comment(relation, comment) %}\\n  {% set escaped_comment = postgres_escape_comment(comment) %}\\n  comment on {{ relation.type }} {{ relation }} is {{ escaped_comment }};\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres_escape_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.271986}, \"macro.dbt_postgres.postgres__alter_column_comment\": {\"unique_id\": \"macro.dbt_postgres.postgres__alter_column_comment\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__alter_column_comment\", \"macro_sql\": \"{% macro postgres__alter_column_comment(relation, column_dict) %}\\n  {% set existing_columns = adapter.get_columns_in_relation(relation) | map(attribute=\\\"name\\\") | list %}\\n  {% for column_name in column_dict if (column_name in existing_columns) %}\\n    {% set comment = column_dict[column_name]['description'] %}\\n    {% set escaped_comment = postgres_escape_comment(comment) %}\\n    comment on column {{ relation }}.{{ adapter.quote(column_name) if column_dict[column_name]['quote'] else column_name }} is {{ escaped_comment }};\\n  {% endfor %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres_escape_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.273597}, \"macro.dbt_postgres.postgres__snapshot_merge_sql\": {\"unique_id\": \"macro.dbt_postgres.postgres__snapshot_merge_sql\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/materializations/snapshot_merge.sql\", \"original_file_path\": \"macros/materializations/snapshot_merge.sql\", \"name\": \"postgres__snapshot_merge_sql\", \"macro_sql\": \"{% macro postgres__snapshot_merge_sql(target, source, insert_cols) -%}\\n    {%- set insert_cols_csv = insert_cols | join(', ') -%}\\n\\n    update {{ target }}\\n    set dbt_valid_to = DBT_INTERNAL_SOURCE.dbt_valid_to\\n    from {{ source }} as DBT_INTERNAL_SOURCE\\n    where DBT_INTERNAL_SOURCE.dbt_scd_id::text = {{ target }}.dbt_scd_id::text\\n      and DBT_INTERNAL_SOURCE.dbt_change_type::text in ('update'::text, 'delete'::text)\\n      and {{ target }}.dbt_valid_to is null;\\n\\n    insert into {{ target }} ({{ insert_cols_csv }})\\n    select {% for column in insert_cols -%}\\n        DBT_INTERNAL_SOURCE.{{ column }} {%- if not loop.last %}, {%- endif %}\\n    {%- endfor %}\\n    from {{ source }} as DBT_INTERNAL_SOURCE\\n    where DBT_INTERNAL_SOURCE.dbt_change_type::text = 'insert'::text;\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.275718}, \"macro.dbt.run_hooks\": {\"unique_id\": \"macro.dbt.run_hooks\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"name\": \"run_hooks\", \"macro_sql\": \"{% macro run_hooks(hooks, inside_transaction=True) %}\\n  {% for hook in hooks | selectattr('transaction', 'equalto', inside_transaction)  %}\\n    {% if not inside_transaction and loop.first %}\\n      {% call statement(auto_begin=inside_transaction) %}\\n        commit;\\n      {% endcall %}\\n    {% endif %}\\n    {% set rendered = render(hook.get('sql')) | trim %}\\n    {% if (rendered | length) > 0 %}\\n      {% call statement(auto_begin=inside_transaction) %}\\n        {{ rendered }}\\n      {% endcall %}\\n    {% endif %}\\n  {% endfor %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.278846}, \"macro.dbt.make_hook_config\": {\"unique_id\": \"macro.dbt.make_hook_config\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"name\": \"make_hook_config\", \"macro_sql\": \"{% macro make_hook_config(sql, inside_transaction) %}\\n    {{ tojson({\\\"sql\\\": sql, \\\"transaction\\\": inside_transaction}) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.2793732}, \"macro.dbt.before_begin\": {\"unique_id\": \"macro.dbt.before_begin\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"name\": \"before_begin\", \"macro_sql\": \"{% macro before_begin(sql) %}\\n    {{ make_hook_config(sql, inside_transaction=False) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.make_hook_config\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.2797408}, \"macro.dbt.in_transaction\": {\"unique_id\": \"macro.dbt.in_transaction\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"name\": \"in_transaction\", \"macro_sql\": \"{% macro in_transaction(sql) %}\\n    {{ make_hook_config(sql, inside_transaction=True) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.make_hook_config\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.280107}, \"macro.dbt.after_commit\": {\"unique_id\": \"macro.dbt.after_commit\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"name\": \"after_commit\", \"macro_sql\": \"{% macro after_commit(sql) %}\\n    {{ make_hook_config(sql, inside_transaction=False) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.make_hook_config\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.280468}, \"macro.dbt.set_sql_header\": {\"unique_id\": \"macro.dbt.set_sql_header\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/configs.sql\", \"original_file_path\": \"macros/materializations/configs.sql\", \"name\": \"set_sql_header\", \"macro_sql\": \"{% macro set_sql_header(config) -%}\\n  {{ config.set('sql_header', caller()) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.28161}, \"macro.dbt.should_full_refresh\": {\"unique_id\": \"macro.dbt.should_full_refresh\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/configs.sql\", \"original_file_path\": \"macros/materializations/configs.sql\", \"name\": \"should_full_refresh\", \"macro_sql\": \"{% macro should_full_refresh() %}\\n  {% set config_full_refresh = config.get('full_refresh') %}\\n  {% if config_full_refresh is none %}\\n    {% set config_full_refresh = flags.FULL_REFRESH %}\\n  {% endif %}\\n  {% do return(config_full_refresh) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.28241}, \"macro.dbt.should_store_failures\": {\"unique_id\": \"macro.dbt.should_store_failures\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/configs.sql\", \"original_file_path\": \"macros/materializations/configs.sql\", \"name\": \"should_store_failures\", \"macro_sql\": \"{% macro should_store_failures() %}\\n  {% set config_store_failures = config.get('store_failures') %}\\n  {% if config_store_failures is none %}\\n    {% set config_store_failures = flags.STORE_FAILURES %}\\n  {% endif %}\\n  {% do return(config_store_failures) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.283215}, \"macro.dbt.snapshot_merge_sql\": {\"unique_id\": \"macro.dbt.snapshot_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/snapshot_merge.sql\", \"original_file_path\": \"macros/materializations/snapshots/snapshot_merge.sql\", \"name\": \"snapshot_merge_sql\", \"macro_sql\": \"{% macro snapshot_merge_sql(target, source, insert_cols) -%}\\n  {{ adapter.dispatch('snapshot_merge_sql', 'dbt')(target, source, insert_cols) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__snapshot_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.284517}, \"macro.dbt.default__snapshot_merge_sql\": {\"unique_id\": \"macro.dbt.default__snapshot_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/snapshot_merge.sql\", \"original_file_path\": \"macros/materializations/snapshots/snapshot_merge.sql\", \"name\": \"default__snapshot_merge_sql\", \"macro_sql\": \"{% macro default__snapshot_merge_sql(target, source, insert_cols) -%}\\n    {%- set insert_cols_csv = insert_cols | join(', ') -%}\\n\\n    merge into {{ target }} as DBT_INTERNAL_DEST\\n    using {{ source }} as DBT_INTERNAL_SOURCE\\n    on DBT_INTERNAL_SOURCE.dbt_scd_id = DBT_INTERNAL_DEST.dbt_scd_id\\n\\n    when matched\\n     and DBT_INTERNAL_DEST.dbt_valid_to is null\\n     and DBT_INTERNAL_SOURCE.dbt_change_type in ('update', 'delete')\\n        then update\\n        set dbt_valid_to = DBT_INTERNAL_SOURCE.dbt_valid_to\\n\\n    when not matched\\n     and DBT_INTERNAL_SOURCE.dbt_change_type = 'insert'\\n        then insert ({{ insert_cols_csv }})\\n        values ({{ insert_cols_csv }})\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.285232}, \"macro.dbt.strategy_dispatch\": {\"unique_id\": \"macro.dbt.strategy_dispatch\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"name\": \"strategy_dispatch\", \"macro_sql\": \"{% macro strategy_dispatch(name) -%}\\n{% set original_name = name %}\\n  {% if '.' in name %}\\n    {% set package_name, name = name.split(\\\".\\\", 1) %}\\n  {% else %}\\n    {% set package_name = none %}\\n  {% endif %}\\n\\n  {% if package_name is none %}\\n    {% set package_context = context %}\\n  {% elif package_name in context %}\\n    {% set package_context = context[package_name] %}\\n  {% else %}\\n    {% set error_msg %}\\n        Could not find package '{{package_name}}', called with '{{original_name}}'\\n    {% endset %}\\n    {{ exceptions.raise_compiler_error(error_msg | trim) }}\\n  {% endif %}\\n\\n  {%- set search_name = 'snapshot_' ~ name ~ '_strategy' -%}\\n\\n  {% if search_name not in package_context %}\\n    {% set error_msg %}\\n        The specified strategy macro '{{name}}' was not found in package '{{ package_name }}'\\n    {% endset %}\\n    {{ exceptions.raise_compiler_error(error_msg | trim) }}\\n  {% endif %}\\n  {{ return(package_context[search_name]) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.2955132}, \"macro.dbt.snapshot_hash_arguments\": {\"unique_id\": \"macro.dbt.snapshot_hash_arguments\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"name\": \"snapshot_hash_arguments\", \"macro_sql\": \"{% macro snapshot_hash_arguments(args) -%}\\n  {{ adapter.dispatch('snapshot_hash_arguments', 'dbt')(args) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__snapshot_hash_arguments\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.295966}, \"macro.dbt.default__snapshot_hash_arguments\": {\"unique_id\": \"macro.dbt.default__snapshot_hash_arguments\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"name\": \"default__snapshot_hash_arguments\", \"macro_sql\": \"{% macro default__snapshot_hash_arguments(args) -%}\\n    md5({%- for arg in args -%}\\n        coalesce(cast({{ arg }} as varchar ), '')\\n        {% if not loop.last %} || '|' || {% endif %}\\n    {%- endfor -%})\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.296581}, \"macro.dbt.snapshot_get_time\": {\"unique_id\": \"macro.dbt.snapshot_get_time\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"name\": \"snapshot_get_time\", \"macro_sql\": \"{% macro snapshot_get_time() -%}\\n  {{ adapter.dispatch('snapshot_get_time', 'dbt')() }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__snapshot_get_time\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.2969642}, \"macro.dbt.default__snapshot_get_time\": {\"unique_id\": \"macro.dbt.default__snapshot_get_time\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"name\": \"default__snapshot_get_time\", \"macro_sql\": \"{% macro default__snapshot_get_time() -%}\\n  {{ current_timestamp() }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.297218}, \"macro.dbt.snapshot_timestamp_strategy\": {\"unique_id\": \"macro.dbt.snapshot_timestamp_strategy\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"name\": \"snapshot_timestamp_strategy\", \"macro_sql\": \"{% macro snapshot_timestamp_strategy(node, snapshotted_rel, current_rel, config, target_exists) %}\\n    {% set primary_key = config['unique_key'] %}\\n    {% set updated_at = config['updated_at'] %}\\n    {% set invalidate_hard_deletes = config.get('invalidate_hard_deletes', false) %}\\n\\n    {#/*\\n        The snapshot relation might not have an {{ updated_at }} value if the\\n        snapshot strategy is changed from `check` to `timestamp`. We\\n        should use a dbt-created column for the comparison in the snapshot\\n        table instead of assuming that the user-supplied {{ updated_at }}\\n        will be present in the historical data.\\n\\n        See https://github.com/dbt-labs/dbt-core/issues/2350\\n    */ #}\\n    {% set row_changed_expr -%}\\n        ({{ snapshotted_rel }}.dbt_valid_from < {{ current_rel }}.{{ updated_at }})\\n    {%- endset %}\\n\\n    {% set scd_id_expr = snapshot_hash_arguments([primary_key, updated_at]) %}\\n\\n    {% do return({\\n        \\\"unique_key\\\": primary_key,\\n        \\\"updated_at\\\": updated_at,\\n        \\\"row_changed\\\": row_changed_expr,\\n        \\\"scd_id\\\": scd_id_expr,\\n        \\\"invalidate_hard_deletes\\\": invalidate_hard_deletes\\n    }) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.snapshot_hash_arguments\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.29933}, \"macro.dbt.snapshot_string_as_time\": {\"unique_id\": \"macro.dbt.snapshot_string_as_time\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"name\": \"snapshot_string_as_time\", \"macro_sql\": \"{% macro snapshot_string_as_time(timestamp) -%}\\n    {{ adapter.dispatch('snapshot_string_as_time', 'dbt')(timestamp) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__snapshot_string_as_time\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.2997508}, \"macro.dbt.default__snapshot_string_as_time\": {\"unique_id\": \"macro.dbt.default__snapshot_string_as_time\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"name\": \"default__snapshot_string_as_time\", \"macro_sql\": \"{% macro default__snapshot_string_as_time(timestamp) %}\\n    {% do exceptions.raise_not_implemented(\\n        'snapshot_string_as_time macro not implemented for adapter '+adapter.type()\\n    ) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.3001878}, \"macro.dbt.snapshot_check_all_get_existing_columns\": {\"unique_id\": \"macro.dbt.snapshot_check_all_get_existing_columns\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"name\": \"snapshot_check_all_get_existing_columns\", \"macro_sql\": \"{% macro snapshot_check_all_get_existing_columns(node, target_exists) -%}\\n    {%- set query_columns = get_columns_in_query(node['compiled_sql']) -%}\\n    {%- if not target_exists -%}\\n        {# no table yet -> return whatever the query does #}\\n        {{ return([false, query_columns]) }}\\n    {%- endif -%}\\n    {# handle any schema changes #}\\n    {%- set target_table = node.get('alias', node.get('name')) -%}\\n    {%- set target_relation = adapter.get_relation(database=node.database, schema=node.schema, identifier=target_table) -%}\\n    {%- set existing_cols = get_columns_in_query('select * from ' ~ target_relation) -%}\\n    {%- set ns = namespace() -%} {# handle for-loop scoping with a namespace #}\\n    {%- set ns.column_added = false -%}\\n\\n    {%- set intersection = [] -%}\\n    {%- for col in query_columns -%}\\n        {%- if col in existing_cols -%}\\n            {%- do intersection.append(col) -%}\\n        {%- else -%}\\n            {% set ns.column_added = true %}\\n        {%- endif -%}\\n    {%- endfor -%}\\n    {{ return([ns.column_added, intersection]) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_columns_in_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.3028228}, \"macro.dbt.snapshot_check_strategy\": {\"unique_id\": \"macro.dbt.snapshot_check_strategy\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"name\": \"snapshot_check_strategy\", \"macro_sql\": \"{% macro snapshot_check_strategy(node, snapshotted_rel, current_rel, config, target_exists) %}\\n    {% set check_cols_config = config['check_cols'] %}\\n    {% set primary_key = config['unique_key'] %}\\n    {% set invalidate_hard_deletes = config.get('invalidate_hard_deletes', false) %}\\n    {% set updated_at = config.get('updated_at', snapshot_get_time()) %}\\n\\n    {% set column_added = false %}\\n\\n    {% if check_cols_config == 'all' %}\\n        {% set column_added, check_cols = snapshot_check_all_get_existing_columns(node, target_exists) %}\\n    {% elif check_cols_config is iterable and (check_cols_config | length) > 0 %}\\n        {% set check_cols = check_cols_config %}\\n    {% else %}\\n        {% do exceptions.raise_compiler_error(\\\"Invalid value for 'check_cols': \\\" ~ check_cols_config) %}\\n    {% endif %}\\n\\n    {%- set row_changed_expr -%}\\n    (\\n    {%- if column_added -%}\\n        {{ get_true_sql() }}\\n    {%- else -%}\\n    {%- for col in check_cols -%}\\n        {{ snapshotted_rel }}.{{ col }} != {{ current_rel }}.{{ col }}\\n        or\\n        (\\n            (({{ snapshotted_rel }}.{{ col }} is null) and not ({{ current_rel }}.{{ col }} is null))\\n            or\\n            ((not {{ snapshotted_rel }}.{{ col }} is null) and ({{ current_rel }}.{{ col }} is null))\\n        )\\n        {%- if not loop.last %} or {% endif -%}\\n    {%- endfor -%}\\n    {%- endif -%}\\n    )\\n    {%- endset %}\\n\\n    {% set scd_id_expr = snapshot_hash_arguments([primary_key, updated_at]) %}\\n\\n    {% do return({\\n        \\\"unique_key\\\": primary_key,\\n        \\\"updated_at\\\": updated_at,\\n        \\\"row_changed\\\": row_changed_expr,\\n        \\\"scd_id\\\": scd_id_expr,\\n        \\\"invalidate_hard_deletes\\\": invalidate_hard_deletes\\n    }) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.snapshot_get_time\", \"macro.dbt.snapshot_check_all_get_existing_columns\", \"macro.dbt.get_true_sql\", \"macro.dbt.snapshot_hash_arguments\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.3070579}, \"macro.dbt.create_columns\": {\"unique_id\": \"macro.dbt.create_columns\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"name\": \"create_columns\", \"macro_sql\": \"{% macro create_columns(relation, columns) %}\\n  {{ adapter.dispatch('create_columns', 'dbt')(relation, columns) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__create_columns\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.3179069}, \"macro.dbt.default__create_columns\": {\"unique_id\": \"macro.dbt.default__create_columns\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"name\": \"default__create_columns\", \"macro_sql\": \"{% macro default__create_columns(relation, columns) %}\\n  {% for column in columns %}\\n    {% call statement() %}\\n      alter table {{ relation }} add column \\\"{{ column.name }}\\\" {{ column.data_type }};\\n    {% endcall %}\\n  {% endfor %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.318669}, \"macro.dbt.post_snapshot\": {\"unique_id\": \"macro.dbt.post_snapshot\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"name\": \"post_snapshot\", \"macro_sql\": \"{% macro post_snapshot(staging_relation) %}\\n  {{ adapter.dispatch('post_snapshot', 'dbt')(staging_relation) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__post_snapshot\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.3191}, \"macro.dbt.default__post_snapshot\": {\"unique_id\": \"macro.dbt.default__post_snapshot\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"name\": \"default__post_snapshot\", \"macro_sql\": \"{% macro default__post_snapshot(staging_relation) %}\\n    {# no-op #}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.3193212}, \"macro.dbt.get_true_sql\": {\"unique_id\": \"macro.dbt.get_true_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"name\": \"get_true_sql\", \"macro_sql\": \"{% macro get_true_sql() %}\\n  {{ adapter.dispatch('get_true_sql', 'dbt')() }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_true_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.319695}, \"macro.dbt.default__get_true_sql\": {\"unique_id\": \"macro.dbt.default__get_true_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"name\": \"default__get_true_sql\", \"macro_sql\": \"{% macro default__get_true_sql() %}\\n    {{ return('TRUE') }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.319982}, \"macro.dbt.snapshot_staging_table\": {\"unique_id\": \"macro.dbt.snapshot_staging_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"name\": \"snapshot_staging_table\", \"macro_sql\": \"{% macro snapshot_staging_table(strategy, source_sql, target_relation) -%}\\n  {{ adapter.dispatch('snapshot_staging_table', 'dbt')(strategy, source_sql, target_relation) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__snapshot_staging_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.320519}, \"macro.dbt.default__snapshot_staging_table\": {\"unique_id\": \"macro.dbt.default__snapshot_staging_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"name\": \"default__snapshot_staging_table\", \"macro_sql\": \"{% macro default__snapshot_staging_table(strategy, source_sql, target_relation) -%}\\n\\n    with snapshot_query as (\\n\\n        {{ source_sql }}\\n\\n    ),\\n\\n    snapshotted_data as (\\n\\n        select *,\\n            {{ strategy.unique_key }} as dbt_unique_key\\n\\n        from {{ target_relation }}\\n        where dbt_valid_to is null\\n\\n    ),\\n\\n    insertions_source_data as (\\n\\n        select\\n            *,\\n            {{ strategy.unique_key }} as dbt_unique_key,\\n            {{ strategy.updated_at }} as dbt_updated_at,\\n            {{ strategy.updated_at }} as dbt_valid_from,\\n            nullif({{ strategy.updated_at }}, {{ strategy.updated_at }}) as dbt_valid_to,\\n            {{ strategy.scd_id }} as dbt_scd_id\\n\\n        from snapshot_query\\n    ),\\n\\n    updates_source_data as (\\n\\n        select\\n            *,\\n            {{ strategy.unique_key }} as dbt_unique_key,\\n            {{ strategy.updated_at }} as dbt_updated_at,\\n            {{ strategy.updated_at }} as dbt_valid_from,\\n            {{ strategy.updated_at }} as dbt_valid_to\\n\\n        from snapshot_query\\n    ),\\n\\n    {%- if strategy.invalidate_hard_deletes %}\\n\\n    deletes_source_data as (\\n\\n        select\\n            *,\\n            {{ strategy.unique_key }} as dbt_unique_key\\n        from snapshot_query\\n    ),\\n    {% endif %}\\n\\n    insertions as (\\n\\n        select\\n            'insert' as dbt_change_type,\\n            source_data.*\\n\\n        from insertions_source_data as source_data\\n        left outer join snapshotted_data on snapshotted_data.dbt_unique_key = source_data.dbt_unique_key\\n        where snapshotted_data.dbt_unique_key is null\\n           or (\\n                snapshotted_data.dbt_unique_key is not null\\n            and (\\n                {{ strategy.row_changed }}\\n            )\\n        )\\n\\n    ),\\n\\n    updates as (\\n\\n        select\\n            'update' as dbt_change_type,\\n            source_data.*,\\n            snapshotted_data.dbt_scd_id\\n\\n        from updates_source_data as source_data\\n        join snapshotted_data on snapshotted_data.dbt_unique_key = source_data.dbt_unique_key\\n        where (\\n            {{ strategy.row_changed }}\\n        )\\n    )\\n\\n    {%- if strategy.invalidate_hard_deletes -%}\\n    ,\\n\\n    deletes as (\\n\\n        select\\n            'delete' as dbt_change_type,\\n            source_data.*,\\n            {{ snapshot_get_time() }} as dbt_valid_from,\\n            {{ snapshot_get_time() }} as dbt_updated_at,\\n            {{ snapshot_get_time() }} as dbt_valid_to,\\n            snapshotted_data.dbt_scd_id\\n\\n        from snapshotted_data\\n        left join deletes_source_data as source_data on snapshotted_data.dbt_unique_key = source_data.dbt_unique_key\\n        where source_data.dbt_unique_key is null\\n    )\\n    {%- endif %}\\n\\n    select * from insertions\\n    union all\\n    select * from updates\\n    {%- if strategy.invalidate_hard_deletes %}\\n    union all\\n    select * from deletes\\n    {%- endif %}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.snapshot_get_time\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.322867}, \"macro.dbt.build_snapshot_table\": {\"unique_id\": \"macro.dbt.build_snapshot_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"name\": \"build_snapshot_table\", \"macro_sql\": \"{% macro build_snapshot_table(strategy, sql) -%}\\n  {{ adapter.dispatch('build_snapshot_table', 'dbt')(strategy, sql) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__build_snapshot_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.323358}, \"macro.dbt.default__build_snapshot_table\": {\"unique_id\": \"macro.dbt.default__build_snapshot_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"name\": \"default__build_snapshot_table\", \"macro_sql\": \"{% macro default__build_snapshot_table(strategy, sql) %}\\n\\n    select *,\\n        {{ strategy.scd_id }} as dbt_scd_id,\\n        {{ strategy.updated_at }} as dbt_updated_at,\\n        {{ strategy.updated_at }} as dbt_valid_from,\\n        nullif({{ strategy.updated_at }}, {{ strategy.updated_at }}) as dbt_valid_to\\n    from (\\n        {{ sql }}\\n    ) sbq\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.324033}, \"macro.dbt.build_snapshot_staging_table\": {\"unique_id\": \"macro.dbt.build_snapshot_staging_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"name\": \"build_snapshot_staging_table\", \"macro_sql\": \"{% macro build_snapshot_staging_table(strategy, sql, target_relation) %}\\n    {% set tmp_relation = make_temp_relation(target_relation) %}\\n\\n    {% set select = snapshot_staging_table(strategy, sql, target_relation) %}\\n\\n    {% call statement('build_snapshot_staging_relation') %}\\n        {{ create_table_as(True, tmp_relation, select) }}\\n    {% endcall %}\\n\\n    {% do return(tmp_relation) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.make_temp_relation\", \"macro.dbt.snapshot_staging_table\", \"macro.dbt.statement\", \"macro.dbt.create_table_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.325182}, \"macro.dbt.materialization_snapshot_default\": {\"unique_id\": \"macro.dbt.materialization_snapshot_default\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/snapshot.sql\", \"original_file_path\": \"macros/materializations/snapshots/snapshot.sql\", \"name\": \"materialization_snapshot_default\", \"macro_sql\": \"{% materialization snapshot, default %}\\n  {%- set config = model['config'] -%}\\n\\n  {%- set target_table = model.get('alias', model.get('name')) -%}\\n\\n  {%- set strategy_name = config.get('strategy') -%}\\n  {%- set unique_key = config.get('unique_key') %}\\n\\n  {% set target_relation_exists, target_relation = get_or_create_relation(\\n          database=model.database,\\n          schema=model.schema,\\n          identifier=target_table,\\n          type='table') -%}\\n\\n  {%- if not target_relation.is_table -%}\\n    {% do exceptions.relation_wrong_type(target_relation, 'table') %}\\n  {%- endif -%}\\n\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  {% set strategy_macro = strategy_dispatch(strategy_name) %}\\n  {% set strategy = strategy_macro(model, \\\"snapshotted_data\\\", \\\"source_data\\\", config, target_relation_exists) %}\\n\\n  {% if not target_relation_exists %}\\n\\n      {% set build_sql = build_snapshot_table(strategy, model['compiled_sql']) %}\\n      {% set final_sql = create_table_as(False, target_relation, build_sql) %}\\n\\n  {% else %}\\n\\n      {{ adapter.valid_snapshot_target(target_relation) }}\\n\\n      {% set staging_table = build_snapshot_staging_table(strategy, sql, target_relation) %}\\n\\n      -- this may no-op if the database does not require column expansion\\n      {% do adapter.expand_target_column_types(from_relation=staging_table,\\n                                               to_relation=target_relation) %}\\n\\n      {% set missing_columns = adapter.get_missing_columns(staging_table, target_relation)\\n                                   | rejectattr('name', 'equalto', 'dbt_change_type')\\n                                   | rejectattr('name', 'equalto', 'DBT_CHANGE_TYPE')\\n                                   | rejectattr('name', 'equalto', 'dbt_unique_key')\\n                                   | rejectattr('name', 'equalto', 'DBT_UNIQUE_KEY')\\n                                   | list %}\\n\\n      {% do create_columns(target_relation, missing_columns) %}\\n\\n      {% set source_columns = adapter.get_columns_in_relation(staging_table)\\n                                   | rejectattr('name', 'equalto', 'dbt_change_type')\\n                                   | rejectattr('name', 'equalto', 'DBT_CHANGE_TYPE')\\n                                   | rejectattr('name', 'equalto', 'dbt_unique_key')\\n                                   | rejectattr('name', 'equalto', 'DBT_UNIQUE_KEY')\\n                                   | list %}\\n\\n      {% set quoted_source_columns = [] %}\\n      {% for column in source_columns %}\\n        {% do quoted_source_columns.append(adapter.quote(column.name)) %}\\n      {% endfor %}\\n\\n      {% set final_sql = snapshot_merge_sql(\\n            target = target_relation,\\n            source = staging_table,\\n            insert_cols = quoted_source_columns\\n         )\\n      %}\\n\\n  {% endif %}\\n\\n  {% call statement('main') %}\\n      {{ final_sql }}\\n  {% endcall %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {% if not target_relation_exists %}\\n    {% do create_indexes(target_relation) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  {{ adapter.commit() }}\\n\\n  {% if staging_table is defined %}\\n      {% do post_snapshot(staging_table) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{% endmaterialization %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_or_create_relation\", \"macro.dbt.run_hooks\", \"macro.dbt.strategy_dispatch\", \"macro.dbt.build_snapshot_table\", \"macro.dbt.create_table_as\", \"macro.dbt.build_snapshot_staging_table\", \"macro.dbt.create_columns\", \"macro.dbt.snapshot_merge_sql\", \"macro.dbt.statement\", \"macro.dbt.persist_docs\", \"macro.dbt.create_indexes\", \"macro.dbt.post_snapshot\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.34037}, \"macro.dbt.materialization_test_default\": {\"unique_id\": \"macro.dbt.materialization_test_default\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/tests/test.sql\", \"original_file_path\": \"macros/materializations/tests/test.sql\", \"name\": \"materialization_test_default\", \"macro_sql\": \"{%- materialization test, default -%}\\n\\n  {% set relations = [] %}\\n\\n  {% if should_store_failures() %}\\n\\n    {% set identifier = model['alias'] %}\\n    {% set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) %}\\n    {% set target_relation = api.Relation.create(\\n        identifier=identifier, schema=schema, database=database, type='table') -%} %}\\n\\n    {% if old_relation %}\\n        {% do adapter.drop_relation(old_relation) %}\\n    {% endif %}\\n\\n    {% call statement(auto_begin=True) %}\\n        {{ create_table_as(False, target_relation, sql) }}\\n    {% endcall %}\\n\\n    {% do relations.append(target_relation) %}\\n\\n    {% set main_sql %}\\n        select *\\n        from {{ target_relation }}\\n    {% endset %}\\n\\n    {{ adapter.commit() }}\\n\\n  {% else %}\\n\\n      {% set main_sql = sql %}\\n\\n  {% endif %}\\n\\n  {% set limit = config.get('limit') %}\\n  {% set fail_calc = config.get('fail_calc') %}\\n  {% set warn_if = config.get('warn_if') %}\\n  {% set error_if = config.get('error_if') %}\\n\\n  {% call statement('main', fetch_result=True) -%}\\n\\n    {{ get_test_sql(main_sql, fail_calc, warn_if, error_if, limit)}}\\n\\n  {%- endcall %}\\n\\n  {{ return({'relations': relations}) }}\\n\\n{%- endmaterialization -%}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.should_store_failures\", \"macro.dbt.statement\", \"macro.dbt.create_table_as\", \"macro.dbt.get_test_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.346029}, \"macro.dbt.get_test_sql\": {\"unique_id\": \"macro.dbt.get_test_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/tests/helpers.sql\", \"original_file_path\": \"macros/materializations/tests/helpers.sql\", \"name\": \"get_test_sql\", \"macro_sql\": \"{% macro get_test_sql(main_sql, fail_calc, warn_if, error_if, limit) -%}\\n  {{ adapter.dispatch('get_test_sql', 'dbt')(main_sql, fail_calc, warn_if, error_if, limit) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_test_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.3473558}, \"macro.dbt.default__get_test_sql\": {\"unique_id\": \"macro.dbt.default__get_test_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/tests/helpers.sql\", \"original_file_path\": \"macros/materializations/tests/helpers.sql\", \"name\": \"default__get_test_sql\", \"macro_sql\": \"{% macro default__get_test_sql(main_sql, fail_calc, warn_if, error_if, limit) -%}\\n    select\\n      {{ fail_calc }} as failures,\\n      {{ fail_calc }} {{ warn_if }} as should_warn,\\n      {{ fail_calc }} {{ error_if }} as should_error\\n    from (\\n      {{ main_sql }}\\n      {{ \\\"limit \\\" ~ limit if limit != none }}\\n    ) dbt_internal_test\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.348177}, \"macro.dbt.get_where_subquery\": {\"unique_id\": \"macro.dbt.get_where_subquery\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/tests/where_subquery.sql\", \"original_file_path\": \"macros/materializations/tests/where_subquery.sql\", \"name\": \"get_where_subquery\", \"macro_sql\": \"{% macro get_where_subquery(relation) -%}\\n    {% do return(adapter.dispatch('get_where_subquery', 'dbt')(relation)) %}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_where_subquery\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.349312}, \"macro.dbt.default__get_where_subquery\": {\"unique_id\": \"macro.dbt.default__get_where_subquery\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/tests/where_subquery.sql\", \"original_file_path\": \"macros/materializations/tests/where_subquery.sql\", \"name\": \"default__get_where_subquery\", \"macro_sql\": \"{% macro default__get_where_subquery(relation) -%}\\n    {% set where = config.get('where', '') %}\\n    {% if where %}\\n        {%- set filtered -%}\\n            (select * from {{ relation }} where {{ where }}) dbt_subquery\\n        {%- endset -%}\\n        {% do return(filtered) %}\\n    {%- else -%}\\n        {% do return(relation) %}\\n    {%- endif -%}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.350326}, \"macro.dbt.get_quoted_csv\": {\"unique_id\": \"macro.dbt.get_quoted_csv\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"name\": \"get_quoted_csv\", \"macro_sql\": \"{% macro get_quoted_csv(column_names) %}\\n\\n    {% set quoted = [] %}\\n    {% for col in column_names -%}\\n        {%- do quoted.append(adapter.quote(col)) -%}\\n    {%- endfor %}\\n\\n    {%- set dest_cols_csv = quoted | join(', ') -%}\\n    {{ return(dest_cols_csv) }}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.352607}, \"macro.dbt.diff_columns\": {\"unique_id\": \"macro.dbt.diff_columns\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"name\": \"diff_columns\", \"macro_sql\": \"{% macro diff_columns(source_columns, target_columns) %}\\n\\n  {% set result = [] %}\\n  {% set source_names = source_columns | map(attribute = 'column') | list %}\\n  {% set target_names = target_columns | map(attribute = 'column') | list %}\\n\\n   {# --check whether the name attribute exists in the target - this does not perform a data type check #}\\n   {% for sc in source_columns %}\\n     {% if sc.name not in target_names %}\\n        {{ result.append(sc) }}\\n     {% endif %}\\n   {% endfor %}\\n\\n  {{ return(result) }}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.35407}, \"macro.dbt.diff_column_data_types\": {\"unique_id\": \"macro.dbt.diff_column_data_types\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"name\": \"diff_column_data_types\", \"macro_sql\": \"{% macro diff_column_data_types(source_columns, target_columns) %}\\n\\n  {% set result = [] %}\\n  {% for sc in source_columns %}\\n    {% set tc = target_columns | selectattr(\\\"name\\\", \\\"equalto\\\", sc.name) | list | first %}\\n    {% if tc %}\\n      {% if sc.data_type != tc.data_type %}\\n        {{ result.append( { 'column_name': tc.name, 'new_type': sc.data_type } ) }}\\n      {% endif %}\\n    {% endif %}\\n  {% endfor %}\\n\\n  {{ return(result) }}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.3557}, \"macro.dbt.get_merge_sql\": {\"unique_id\": \"macro.dbt.get_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"name\": \"get_merge_sql\", \"macro_sql\": \"{% macro get_merge_sql(target, source, unique_key, dest_columns, predicates=none) -%}\\n  {{ adapter.dispatch('get_merge_sql', 'dbt')(target, source, unique_key, dest_columns, predicates) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.370045}, \"macro.dbt.default__get_merge_sql\": {\"unique_id\": \"macro.dbt.default__get_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"name\": \"default__get_merge_sql\", \"macro_sql\": \"{% macro default__get_merge_sql(target, source, unique_key, dest_columns, predicates) -%}\\n    {%- set predicates = [] if predicates is none else [] + predicates -%}\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n    {%- set update_columns = config.get('merge_update_columns', default = dest_columns | map(attribute=\\\"quoted\\\") | list) -%}\\n    {%- set sql_header = config.get('sql_header', none) -%}\\n\\n    {% if unique_key %}\\n        {% if unique_key is sequence and unique_key is not mapping and unique_key is not string %}\\n            {% for key in unique_key %}\\n                {% set this_key_match %}\\n                    DBT_INTERNAL_SOURCE.{{ key }} = DBT_INTERNAL_DEST.{{ key }}\\n                {% endset %}\\n                {% do predicates.append(this_key_match) %}\\n            {% endfor %}\\n        {% else %}\\n            {% set unique_key_match %}\\n                DBT_INTERNAL_SOURCE.{{ unique_key }} = DBT_INTERNAL_DEST.{{ unique_key }}\\n            {% endset %}\\n            {% do predicates.append(unique_key_match) %}\\n        {% endif %}\\n    {% else %}\\n        {% do predicates.append('FALSE') %}\\n    {% endif %}\\n\\n    {{ sql_header if sql_header is not none }}\\n\\n    merge into {{ target }} as DBT_INTERNAL_DEST\\n        using {{ source }} as DBT_INTERNAL_SOURCE\\n        on {{ predicates | join(' and ') }}\\n\\n    {% if unique_key %}\\n    when matched then update set\\n        {% for column_name in update_columns -%}\\n            {{ column_name }} = DBT_INTERNAL_SOURCE.{{ column_name }}\\n            {%- if not loop.last %}, {%- endif %}\\n        {%- endfor %}\\n    {% endif %}\\n\\n    when not matched then insert\\n        ({{ dest_cols_csv }})\\n    values\\n        ({{ dest_cols_csv }})\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_quoted_csv\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.374055}, \"macro.dbt.get_delete_insert_merge_sql\": {\"unique_id\": \"macro.dbt.get_delete_insert_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"name\": \"get_delete_insert_merge_sql\", \"macro_sql\": \"{% macro get_delete_insert_merge_sql(target, source, unique_key, dest_columns) -%}\\n  {{ adapter.dispatch('get_delete_insert_merge_sql', 'dbt')(target, source, unique_key, dest_columns) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_delete_insert_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.401227}, \"macro.dbt.default__get_delete_insert_merge_sql\": {\"unique_id\": \"macro.dbt.default__get_delete_insert_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"name\": \"default__get_delete_insert_merge_sql\", \"macro_sql\": \"{% macro default__get_delete_insert_merge_sql(target, source, unique_key, dest_columns) -%}\\n\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n\\n    {% if unique_key %}\\n        {% if unique_key is sequence and unique_key is not string %}\\n            delete from {{target }}\\n            using {{ source }}\\n            where (\\n                {% for key in unique_key %}\\n                    {{ source }}.{{ key }} = {{ target }}.{{ key }}\\n                    {{ \\\"and \\\" if not loop.last }}\\n                {% endfor %}\\n            );\\n        {% else %}\\n            delete from {{ target }}\\n            where (\\n                {{ unique_key }}) in (\\n                select ({{ unique_key }})\\n                from {{ source }}\\n            );\\n\\n        {% endif %}\\n        {% endif %}\\n\\n    insert into {{ target }} ({{ dest_cols_csv }})\\n    (\\n        select {{ dest_cols_csv }}\\n        from {{ source }}\\n    )\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_quoted_csv\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.4033751}, \"macro.dbt.get_insert_overwrite_merge_sql\": {\"unique_id\": \"macro.dbt.get_insert_overwrite_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"name\": \"get_insert_overwrite_merge_sql\", \"macro_sql\": \"{% macro get_insert_overwrite_merge_sql(target, source, dest_columns, predicates, include_sql_header=false) -%}\\n  {{ adapter.dispatch('get_insert_overwrite_merge_sql', 'dbt')(target, source, dest_columns, predicates, include_sql_header) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_insert_overwrite_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.4041102}, \"macro.dbt.default__get_insert_overwrite_merge_sql\": {\"unique_id\": \"macro.dbt.default__get_insert_overwrite_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"name\": \"default__get_insert_overwrite_merge_sql\", \"macro_sql\": \"{% macro default__get_insert_overwrite_merge_sql(target, source, dest_columns, predicates, include_sql_header) -%}\\n    {%- set predicates = [] if predicates is none else [] + predicates -%}\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n    {%- set sql_header = config.get('sql_header', none) -%}\\n\\n    {{ sql_header if sql_header is not none and include_sql_header }}\\n\\n    merge into {{ target }} as DBT_INTERNAL_DEST\\n        using {{ source }} as DBT_INTERNAL_SOURCE\\n        on FALSE\\n\\n    when not matched by source\\n        {% if predicates %} and {{ predicates | join(' and ') }} {% endif %}\\n        then delete\\n\\n    when not matched then insert\\n        ({{ dest_cols_csv }})\\n    values\\n        ({{ dest_cols_csv }})\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_quoted_csv\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.405853}, \"macro.dbt.is_incremental\": {\"unique_id\": \"macro.dbt.is_incremental\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/is_incremental.sql\", \"original_file_path\": \"macros/materializations/models/incremental/is_incremental.sql\", \"name\": \"is_incremental\", \"macro_sql\": \"{% macro is_incremental() %}\\n    {#-- do not run introspective queries in parsing #}\\n    {% if not execute %}\\n        {{ return(False) }}\\n    {% else %}\\n        {% set relation = adapter.get_relation(this.database, this.schema, this.table) %}\\n        {{ return(relation is not none\\n                  and relation.type == 'table'\\n                  and model.config.materialized == 'incremental'\\n                  and not should_full_refresh()) }}\\n    {% endif %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.should_full_refresh\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.4078321}, \"macro.dbt.materialization_incremental_default\": {\"unique_id\": \"macro.dbt.materialization_incremental_default\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/incremental.sql\", \"original_file_path\": \"macros/materializations/models/incremental/incremental.sql\", \"name\": \"materialization_incremental_default\", \"macro_sql\": \"{% materialization incremental, default -%}\\n\\n  {% set unique_key = config.get('unique_key') %}\\n\\n  {% set target_relation = this.incorporate(type='table') %}\\n  {% set existing_relation = load_relation(this) %}\\n  {% set tmp_relation = make_temp_relation(target_relation) %}\\n  {%- set full_refresh_mode = (should_full_refresh()) -%}\\n\\n  {% set on_schema_change = incremental_validate_on_schema_change(config.get('on_schema_change'), default='ignore') %}\\n\\n  {% set tmp_identifier = model['name'] + '__dbt_tmp' %}\\n  {% set backup_identifier = model['name'] + \\\"__dbt_backup\\\" %}\\n\\n  -- the intermediate_ and backup_ relations should not already exist in the database; get_relation\\n  -- will return None in that case. Otherwise, we get a relation that we can drop\\n  -- later, before we try to use this name for the current operation. This has to happen before\\n  -- BEGIN, in a separate transaction\\n  {% set preexisting_intermediate_relation = adapter.get_relation(identifier=tmp_identifier,\\n                                                                  schema=schema,\\n                                                                  database=database) %}\\n  {% set preexisting_backup_relation = adapter.get_relation(identifier=backup_identifier,\\n                                                            schema=schema,\\n                                                            database=database) %}\\n  {{ drop_relation_if_exists(preexisting_intermediate_relation) }}\\n  {{ drop_relation_if_exists(preexisting_backup_relation) }}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  {% set to_drop = [] %}\\n\\n  {# -- first check whether we want to full refresh for source view or config reasons #}\\n  {% set trigger_full_refresh = (full_refresh_mode or existing_relation.is_view) %}\\n\\n  {% if existing_relation is none %}\\n      {% set build_sql = create_table_as(False, target_relation, sql) %}\\n{% elif trigger_full_refresh %}\\n      {#-- Make sure the backup doesn't exist so we don't encounter issues with the rename below #}\\n      {% set tmp_identifier = model['name'] + '__dbt_tmp' %}\\n      {% set backup_identifier = model['name'] + '__dbt_backup' %}\\n      {% set intermediate_relation = existing_relation.incorporate(path={\\\"identifier\\\": tmp_identifier}) %}\\n      {% set backup_relation = existing_relation.incorporate(path={\\\"identifier\\\": backup_identifier}) %}\\n\\n      {% set build_sql = create_table_as(False, intermediate_relation, sql) %}\\n      {% set need_swap = true %}\\n      {% do to_drop.append(backup_relation) %}\\n  {% else %}\\n    {% do run_query(create_table_as(True, tmp_relation, sql)) %}\\n    {% do adapter.expand_target_column_types(\\n             from_relation=tmp_relation,\\n             to_relation=target_relation) %}\\n    {#-- Process schema changes. Returns dict of changes if successful. Use source columns for upserting/merging --#}\\n    {% set dest_columns = process_schema_changes(on_schema_change, tmp_relation, existing_relation) %}\\n    {% if not dest_columns %}\\n      {% set dest_columns = adapter.get_columns_in_relation(existing_relation) %}\\n    {% endif %}\\n    {% set build_sql = get_delete_insert_merge_sql(target_relation, tmp_relation, unique_key, dest_columns) %}\\n\\n  {% endif %}\\n\\n  {% call statement(\\\"main\\\") %}\\n      {{ build_sql }}\\n  {% endcall %}\\n\\n  {% if need_swap %}\\n      {% do adapter.rename_relation(target_relation, backup_relation) %}\\n      {% do adapter.rename_relation(intermediate_relation, target_relation) %}\\n  {% endif %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {% if existing_relation is none or existing_relation.is_view or should_full_refresh() %}\\n    {% do create_indexes(target_relation) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  -- `COMMIT` happens here\\n  {% do adapter.commit() %}\\n\\n  {% for rel in to_drop %}\\n      {% do adapter.drop_relation(rel) %}\\n  {% endfor %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{%- endmaterialization %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.load_relation\", \"macro.dbt.make_temp_relation\", \"macro.dbt.should_full_refresh\", \"macro.dbt.incremental_validate_on_schema_change\", \"macro.dbt.drop_relation_if_exists\", \"macro.dbt.run_hooks\", \"macro.dbt.create_table_as\", \"macro.dbt.run_query\", \"macro.dbt.process_schema_changes\", \"macro.dbt.get_delete_insert_merge_sql\", \"macro.dbt.statement\", \"macro.dbt.persist_docs\", \"macro.dbt.create_indexes\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.421077}, \"macro.dbt.incremental_validate_on_schema_change\": {\"unique_id\": \"macro.dbt.incremental_validate_on_schema_change\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"original_file_path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"name\": \"incremental_validate_on_schema_change\", \"macro_sql\": \"{% macro incremental_validate_on_schema_change(on_schema_change, default='ignore') %}\\n\\n   {% if on_schema_change not in ['sync_all_columns', 'append_new_columns', 'fail', 'ignore'] %}\\n\\n     {% set log_message = 'Invalid value for on_schema_change (%s) specified. Setting default value of %s.' % (on_schema_change, default) %}\\n     {% do log(log_message) %}\\n\\n     {{ return(default) }}\\n\\n   {% else %}\\n\\n     {{ return(on_schema_change) }}\\n\\n   {% endif %}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.434217}, \"macro.dbt.check_for_schema_changes\": {\"unique_id\": \"macro.dbt.check_for_schema_changes\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"original_file_path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"name\": \"check_for_schema_changes\", \"macro_sql\": \"{% macro check_for_schema_changes(source_relation, target_relation) %}\\n\\n  {% set schema_changed = False %}\\n\\n  {%- set source_columns = adapter.get_columns_in_relation(source_relation) -%}\\n  {%- set target_columns = adapter.get_columns_in_relation(target_relation) -%}\\n  {%- set source_not_in_target = diff_columns(source_columns, target_columns) -%}\\n  {%- set target_not_in_source = diff_columns(target_columns, source_columns) -%}\\n\\n  {% set new_target_types = diff_column_data_types(source_columns, target_columns) %}\\n\\n  {% if source_not_in_target != [] %}\\n    {% set schema_changed = True %}\\n  {% elif target_not_in_source != [] or new_target_types != [] %}\\n    {% set schema_changed = True %}\\n  {% elif new_target_types != [] %}\\n    {% set schema_changed = True %}\\n  {% endif %}\\n\\n  {% set changes_dict = {\\n    'schema_changed': schema_changed,\\n    'source_not_in_target': source_not_in_target,\\n    'target_not_in_source': target_not_in_source,\\n    'source_columns': source_columns,\\n    'target_columns': target_columns,\\n    'new_target_types': new_target_types\\n  } %}\\n\\n  {% set msg %}\\n    In {{ target_relation }}:\\n        Schema changed: {{ schema_changed }}\\n        Source columns not in target: {{ source_not_in_target }}\\n        Target columns not in source: {{ target_not_in_source }}\\n        New column types: {{ new_target_types }}\\n  {% endset %}\\n\\n  {% do log(msg) %}\\n\\n  {{ return(changes_dict) }}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.diff_columns\", \"macro.dbt.diff_column_data_types\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.43755}, \"macro.dbt.sync_column_schemas\": {\"unique_id\": \"macro.dbt.sync_column_schemas\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"original_file_path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"name\": \"sync_column_schemas\", \"macro_sql\": \"{% macro sync_column_schemas(on_schema_change, target_relation, schema_changes_dict) %}\\n\\n  {%- set add_to_target_arr = schema_changes_dict['source_not_in_target'] -%}\\n\\n  {%- if on_schema_change == 'append_new_columns'-%}\\n     {%- if add_to_target_arr | length > 0 -%}\\n       {%- do alter_relation_add_remove_columns(target_relation, add_to_target_arr, none) -%}\\n     {%- endif -%}\\n\\n  {% elif on_schema_change == 'sync_all_columns' %}\\n     {%- set remove_from_target_arr = schema_changes_dict['target_not_in_source'] -%}\\n     {%- set new_target_types = schema_changes_dict['new_target_types'] -%}\\n\\n     {% if add_to_target_arr | length > 0 or remove_from_target_arr | length > 0 %}\\n       {%- do alter_relation_add_remove_columns(target_relation, add_to_target_arr, remove_from_target_arr) -%}\\n     {% endif %}\\n\\n     {% if new_target_types != [] %}\\n       {% for ntt in new_target_types %}\\n         {% set column_name = ntt['column_name'] %}\\n         {% set new_type = ntt['new_type'] %}\\n         {% do alter_column_type(target_relation, column_name, new_type) %}\\n       {% endfor %}\\n     {% endif %}\\n\\n  {% endif %}\\n\\n  {% set schema_change_message %}\\n    In {{ target_relation }}:\\n        Schema change approach: {{ on_schema_change }}\\n        Columns added: {{ add_to_target_arr }}\\n        Columns removed: {{ remove_from_target_arr }}\\n        Data types changed: {{ new_target_types }}\\n  {% endset %}\\n\\n  {% do log(schema_change_message) %}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.alter_relation_add_remove_columns\", \"macro.dbt.alter_column_type\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.440778}, \"macro.dbt.process_schema_changes\": {\"unique_id\": \"macro.dbt.process_schema_changes\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"original_file_path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"name\": \"process_schema_changes\", \"macro_sql\": \"{% macro process_schema_changes(on_schema_change, source_relation, target_relation) %}\\n\\n    {% if on_schema_change == 'ignore' %}\\n\\n     {{ return({}) }}\\n\\n    {% else %}\\n\\n      {% set schema_changes_dict = check_for_schema_changes(source_relation, target_relation) %}\\n\\n      {% if schema_changes_dict['schema_changed'] %}\\n\\n        {% if on_schema_change == 'fail' %}\\n\\n          {% set fail_msg %}\\n              The source and target schemas on this incremental model are out of sync!\\n              They can be reconciled in several ways:\\n                - set the `on_schema_change` config to either append_new_columns or sync_all_columns, depending on your situation.\\n                - Re-run the incremental model with `full_refresh: True` to update the target schema.\\n                - update the schema manually and re-run the process.\\n          {% endset %}\\n\\n          {% do exceptions.raise_compiler_error(fail_msg) %}\\n\\n        {# -- unless we ignore, run the sync operation per the config #}\\n        {% else %}\\n\\n          {% do sync_column_schemas(on_schema_change, target_relation, schema_changes_dict) %}\\n\\n        {% endif %}\\n\\n      {% endif %}\\n\\n      {{ return(schema_changes_dict['source_columns']) }}\\n\\n    {% endif %}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.check_for_schema_changes\", \"macro.dbt.sync_column_schemas\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.442719}, \"macro.dbt.materialization_table_default\": {\"unique_id\": \"macro.dbt.materialization_table_default\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/table/table.sql\", \"original_file_path\": \"macros/materializations/models/table/table.sql\", \"name\": \"materialization_table_default\", \"macro_sql\": \"{% materialization table, default %}\\n  {%- set identifier = model['alias'] -%}\\n  {%- set tmp_identifier = model['name'] + '__dbt_tmp' -%}\\n  {%- set backup_identifier = model['name'] + '__dbt_backup' -%}\\n\\n  {%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%}\\n  {%- set target_relation = api.Relation.create(identifier=identifier,\\n                                                schema=schema,\\n                                                database=database,\\n                                                type='table') -%}\\n  {%- set intermediate_relation = api.Relation.create(identifier=tmp_identifier,\\n                                                      schema=schema,\\n                                                      database=database,\\n                                                      type='table') -%}\\n  -- the intermediate_relation should not already exist in the database; get_relation\\n  -- will return None in that case. Otherwise, we get a relation that we can drop\\n  -- later, before we try to use this name for the current operation\\n  {%- set preexisting_intermediate_relation = adapter.get_relation(identifier=tmp_identifier,\\n                                                                   schema=schema,\\n                                                                   database=database) -%}\\n  /*\\n      See ../view/view.sql for more information about this relation.\\n  */\\n  {%- set backup_relation_type = 'table' if old_relation is none else old_relation.type -%}\\n  {%- set backup_relation = api.Relation.create(identifier=backup_identifier,\\n                                                schema=schema,\\n                                                database=database,\\n                                                type=backup_relation_type) -%}\\n  -- as above, the backup_relation should not already exist\\n  {%- set preexisting_backup_relation = adapter.get_relation(identifier=backup_identifier,\\n                                                             schema=schema,\\n                                                             database=database) -%}\\n\\n\\n  -- drop the temp relations if they exist already in the database\\n  {{ drop_relation_if_exists(preexisting_intermediate_relation) }}\\n  {{ drop_relation_if_exists(preexisting_backup_relation) }}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  -- build model\\n  {% call statement('main') -%}\\n    {{ get_create_table_as_sql(False, intermediate_relation, sql) }}\\n  {%- endcall %}\\n\\n  -- cleanup\\n  {% if old_relation is not none %}\\n      {{ adapter.rename_relation(old_relation, backup_relation) }}\\n  {% endif %}\\n\\n  {{ adapter.rename_relation(intermediate_relation, target_relation) }}\\n\\n  {% do create_indexes(target_relation) %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  -- `COMMIT` happens here\\n  {{ adapter.commit() }}\\n\\n  -- finally, drop the existing/backup relation after the commit\\n  {{ drop_relation_if_exists(backup_relation) }}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n{% endmaterialization %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.drop_relation_if_exists\", \"macro.dbt.run_hooks\", \"macro.dbt.statement\", \"macro.dbt.get_create_table_as_sql\", \"macro.dbt.create_indexes\", \"macro.dbt.persist_docs\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.452991}, \"macro.dbt.get_create_table_as_sql\": {\"unique_id\": \"macro.dbt.get_create_table_as_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/table/create_table_as.sql\", \"original_file_path\": \"macros/materializations/models/table/create_table_as.sql\", \"name\": \"get_create_table_as_sql\", \"macro_sql\": \"{% macro get_create_table_as_sql(temporary, relation, sql) -%}\\n  {{ adapter.dispatch('get_create_table_as_sql', 'dbt')(temporary, relation, sql) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_create_table_as_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.454284}, \"macro.dbt.default__get_create_table_as_sql\": {\"unique_id\": \"macro.dbt.default__get_create_table_as_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/table/create_table_as.sql\", \"original_file_path\": \"macros/materializations/models/table/create_table_as.sql\", \"name\": \"default__get_create_table_as_sql\", \"macro_sql\": \"{% macro default__get_create_table_as_sql(temporary, relation, sql) -%}\\n  {{ return(create_table_as(temporary, relation, sql)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.create_table_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.454771}, \"macro.dbt.create_table_as\": {\"unique_id\": \"macro.dbt.create_table_as\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/table/create_table_as.sql\", \"original_file_path\": \"macros/materializations/models/table/create_table_as.sql\", \"name\": \"create_table_as\", \"macro_sql\": \"{% macro create_table_as(temporary, relation, sql) -%}\\n  {{ adapter.dispatch('create_table_as', 'dbt')(temporary, relation, sql) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__create_table_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.455303}, \"macro.dbt.default__create_table_as\": {\"unique_id\": \"macro.dbt.default__create_table_as\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/table/create_table_as.sql\", \"original_file_path\": \"macros/materializations/models/table/create_table_as.sql\", \"name\": \"default__create_table_as\", \"macro_sql\": \"{% macro default__create_table_as(temporary, relation, sql) -%}\\n  {%- set sql_header = config.get('sql_header', none) -%}\\n\\n  {{ sql_header if sql_header is not none }}\\n\\n  create {% if temporary: -%}temporary{%- endif %} table\\n    {{ relation.include(database=(not temporary), schema=(not temporary)) }}\\n  as (\\n    {{ sql }}\\n  );\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.456414}, \"macro.dbt.materialization_view_default\": {\"unique_id\": \"macro.dbt.materialization_view_default\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/view/view.sql\", \"original_file_path\": \"macros/materializations/models/view/view.sql\", \"name\": \"materialization_view_default\", \"macro_sql\": \"{%- materialization view, default -%}\\n\\n  {%- set identifier = model['alias'] -%}\\n  {%- set tmp_identifier = model['name'] + '__dbt_tmp' -%}\\n  {%- set backup_identifier = model['name'] + '__dbt_backup' -%}\\n\\n  {%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%}\\n  {%- set target_relation = api.Relation.create(identifier=identifier, schema=schema, database=database,\\n                                                type='view') -%}\\n  {%- set intermediate_relation = api.Relation.create(identifier=tmp_identifier,\\n                                                      schema=schema, database=database, type='view') -%}\\n  -- the intermediate_relation should not already exist in the database; get_relation\\n  -- will return None in that case. Otherwise, we get a relation that we can drop\\n  -- later, before we try to use this name for the current operation\\n  {%- set preexisting_intermediate_relation = adapter.get_relation(identifier=tmp_identifier,\\n                                                                   schema=schema,\\n                                                                   database=database) -%}\\n  /*\\n     This relation (probably) doesn't exist yet. If it does exist, it's a leftover from\\n     a previous run, and we're going to try to drop it immediately. At the end of this\\n     materialization, we're going to rename the \\\"old_relation\\\" to this identifier,\\n     and then we're going to drop it. In order to make sure we run the correct one of:\\n       - drop view ...\\n       - drop table ...\\n\\n     We need to set the type of this relation to be the type of the old_relation, if it exists,\\n     or else \\\"view\\\" as a sane default if it does not. Note that if the old_relation does not\\n     exist, then there is nothing to move out of the way and subsequentally drop. In that case,\\n     this relation will be effectively unused.\\n  */\\n  {%- set backup_relation_type = 'view' if old_relation is none else old_relation.type -%}\\n  {%- set backup_relation = api.Relation.create(identifier=backup_identifier,\\n                                                schema=schema, database=database,\\n                                                type=backup_relation_type) -%}\\n  -- as above, the backup_relation should not already exist\\n  {%- set preexisting_backup_relation = adapter.get_relation(identifier=backup_identifier,\\n                                                             schema=schema,\\n                                                             database=database) -%}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- drop the temp relations if they exist already in the database\\n  {{ drop_relation_if_exists(preexisting_intermediate_relation) }}\\n  {{ drop_relation_if_exists(preexisting_backup_relation) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  -- build model\\n  {% call statement('main') -%}\\n    {{ create_view_as(intermediate_relation, sql) }}\\n  {%- endcall %}\\n\\n  -- cleanup\\n  -- move the existing view out of the way\\n  {% if old_relation is not none %}\\n    {{ adapter.rename_relation(old_relation, backup_relation) }}\\n  {% endif %}\\n  {{ adapter.rename_relation(intermediate_relation, target_relation) }}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  {{ adapter.commit() }}\\n\\n  {{ drop_relation_if_exists(backup_relation) }}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{%- endmaterialization -%}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.run_hooks\", \"macro.dbt.drop_relation_if_exists\", \"macro.dbt.statement\", \"macro.dbt.create_view_as\", \"macro.dbt.persist_docs\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.4662242}, \"macro.dbt.handle_existing_table\": {\"unique_id\": \"macro.dbt.handle_existing_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/view/helpers.sql\", \"original_file_path\": \"macros/materializations/models/view/helpers.sql\", \"name\": \"handle_existing_table\", \"macro_sql\": \"{% macro handle_existing_table(full_refresh, old_relation) %}\\n    {{ adapter.dispatch('handle_existing_table', 'dbt')(full_refresh, old_relation) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__handle_existing_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.467168}, \"macro.dbt.default__handle_existing_table\": {\"unique_id\": \"macro.dbt.default__handle_existing_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/view/helpers.sql\", \"original_file_path\": \"macros/materializations/models/view/helpers.sql\", \"name\": \"default__handle_existing_table\", \"macro_sql\": \"{% macro default__handle_existing_table(full_refresh, old_relation) %}\\n    {{ log(\\\"Dropping relation \\\" ~ old_relation ~ \\\" because it is of type \\\" ~ old_relation.type) }}\\n    {{ adapter.drop_relation(old_relation) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.46778}, \"macro.dbt.create_or_replace_view\": {\"unique_id\": \"macro.dbt.create_or_replace_view\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/view/create_or_replace_view.sql\", \"original_file_path\": \"macros/materializations/models/view/create_or_replace_view.sql\", \"name\": \"create_or_replace_view\", \"macro_sql\": \"{% macro create_or_replace_view() %}\\n  {%- set identifier = model['alias'] -%}\\n\\n  {%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%}\\n\\n  {%- set exists_as_view = (old_relation is not none and old_relation.is_view) -%}\\n\\n  {%- set target_relation = api.Relation.create(\\n      identifier=identifier, schema=schema, database=database,\\n      type='view') -%}\\n\\n  {{ run_hooks(pre_hooks) }}\\n\\n  -- If there's a table with the same name and we weren't told to full refresh,\\n  -- that's an error. If we were told to full refresh, drop it. This behavior differs\\n  -- for Snowflake and BigQuery, so multiple dispatch is used.\\n  {%- if old_relation is not none and old_relation.is_table -%}\\n    {{ handle_existing_table(should_full_refresh(), old_relation) }}\\n  {%- endif -%}\\n\\n  -- build model\\n  {% call statement('main') -%}\\n    {{ get_create_view_as_sql(target_relation, sql) }}\\n  {%- endcall %}\\n\\n  {{ run_hooks(post_hooks) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.run_hooks\", \"macro.dbt.handle_existing_table\", \"macro.dbt.should_full_refresh\", \"macro.dbt.statement\", \"macro.dbt.get_create_view_as_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.4711108}, \"macro.dbt.get_create_view_as_sql\": {\"unique_id\": \"macro.dbt.get_create_view_as_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/view/create_view_as.sql\", \"original_file_path\": \"macros/materializations/models/view/create_view_as.sql\", \"name\": \"get_create_view_as_sql\", \"macro_sql\": \"{% macro get_create_view_as_sql(relation, sql) -%}\\n  {{ adapter.dispatch('get_create_view_as_sql', 'dbt')(relation, sql) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_create_view_as_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.4722078}, \"macro.dbt.default__get_create_view_as_sql\": {\"unique_id\": \"macro.dbt.default__get_create_view_as_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/view/create_view_as.sql\", \"original_file_path\": \"macros/materializations/models/view/create_view_as.sql\", \"name\": \"default__get_create_view_as_sql\", \"macro_sql\": \"{% macro default__get_create_view_as_sql(relation, sql) -%}\\n  {{ return(create_view_as(relation, sql)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.create_view_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.472634}, \"macro.dbt.create_view_as\": {\"unique_id\": \"macro.dbt.create_view_as\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/view/create_view_as.sql\", \"original_file_path\": \"macros/materializations/models/view/create_view_as.sql\", \"name\": \"create_view_as\", \"macro_sql\": \"{% macro create_view_as(relation, sql) -%}\\n  {{ adapter.dispatch('create_view_as', 'dbt')(relation, sql) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__create_view_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.473103}, \"macro.dbt.default__create_view_as\": {\"unique_id\": \"macro.dbt.default__create_view_as\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/view/create_view_as.sql\", \"original_file_path\": \"macros/materializations/models/view/create_view_as.sql\", \"name\": \"default__create_view_as\", \"macro_sql\": \"{% macro default__create_view_as(relation, sql) -%}\\n  {%- set sql_header = config.get('sql_header', none) -%}\\n\\n  {{ sql_header if sql_header is not none }}\\n  create view {{ relation }} as (\\n    {{ sql }}\\n  );\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.473792}, \"macro.dbt.materialization_seed_default\": {\"unique_id\": \"macro.dbt.materialization_seed_default\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/seed.sql\", \"original_file_path\": \"macros/materializations/seeds/seed.sql\", \"name\": \"materialization_seed_default\", \"macro_sql\": \"{% materialization seed, default %}\\n\\n  {%- set identifier = model['alias'] -%}\\n  {%- set full_refresh_mode = (should_full_refresh()) -%}\\n\\n  {%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%}\\n\\n  {%- set exists_as_table = (old_relation is not none and old_relation.is_table) -%}\\n  {%- set exists_as_view = (old_relation is not none and old_relation.is_view) -%}\\n\\n  {%- set agate_table = load_agate_table() -%}\\n  {%- do store_result('agate_table', response='OK', agate_table=agate_table) -%}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  -- build model\\n  {% set create_table_sql = \\\"\\\" %}\\n  {% if exists_as_view %}\\n    {{ exceptions.raise_compiler_error(\\\"Cannot seed to '{}', it is a view\\\".format(old_relation)) }}\\n  {% elif exists_as_table %}\\n    {% set create_table_sql = reset_csv_table(model, full_refresh_mode, old_relation, agate_table) %}\\n  {% else %}\\n    {% set create_table_sql = create_csv_table(model, agate_table) %}\\n  {% endif %}\\n\\n  {% set code = 'CREATE' if full_refresh_mode else 'INSERT' %}\\n  {% set rows_affected = (agate_table.rows | length) %}\\n  {% set sql = load_csv_rows(model, agate_table) %}\\n\\n  {% call noop_statement('main', code ~ ' ' ~ rows_affected, code, rows_affected) %}\\n    {{ create_table_sql }};\\n    -- dbt seed --\\n    {{ sql }}\\n  {% endcall %}\\n\\n  {% set target_relation = this.incorporate(type='table') %}\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {% if full_refresh_mode or not exists_as_table %}\\n    {% do create_indexes(target_relation) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  -- `COMMIT` happens here\\n  {{ adapter.commit() }}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{% endmaterialization %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.should_full_refresh\", \"macro.dbt.run_hooks\", \"macro.dbt.reset_csv_table\", \"macro.dbt.create_csv_table\", \"macro.dbt.load_csv_rows\", \"macro.dbt.noop_statement\", \"macro.dbt.persist_docs\", \"macro.dbt.create_indexes\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.4816241}, \"macro.dbt.create_csv_table\": {\"unique_id\": \"macro.dbt.create_csv_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"create_csv_table\", \"macro_sql\": \"{% macro create_csv_table(model, agate_table) -%}\\n  {{ adapter.dispatch('create_csv_table', 'dbt')(model, agate_table) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__create_csv_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.493353}, \"macro.dbt.default__create_csv_table\": {\"unique_id\": \"macro.dbt.default__create_csv_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"default__create_csv_table\", \"macro_sql\": \"{% macro default__create_csv_table(model, agate_table) %}\\n  {%- set column_override = model['config'].get('column_types', {}) -%}\\n  {%- set quote_seed_column = model['config'].get('quote_columns', None) -%}\\n\\n  {% set sql %}\\n    create table {{ this.render() }} (\\n        {%- for col_name in agate_table.column_names -%}\\n            {%- set inferred_type = adapter.convert_type(agate_table, loop.index0) -%}\\n            {%- set type = column_override.get(col_name, inferred_type) -%}\\n            {%- set column_name = (col_name | string) -%}\\n            {{ adapter.quote_seed_column(column_name, quote_seed_column) }} {{ type }} {%- if not loop.last -%}, {%- endif -%}\\n        {%- endfor -%}\\n    )\\n  {% endset %}\\n\\n  {% call statement('_') -%}\\n    {{ sql }}\\n  {%- endcall %}\\n\\n  {{ return(sql) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.495795}, \"macro.dbt.reset_csv_table\": {\"unique_id\": \"macro.dbt.reset_csv_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"reset_csv_table\", \"macro_sql\": \"{% macro reset_csv_table(model, full_refresh, old_relation, agate_table) -%}\\n  {{ adapter.dispatch('reset_csv_table', 'dbt')(model, full_refresh, old_relation, agate_table) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__reset_csv_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.4964218}, \"macro.dbt.default__reset_csv_table\": {\"unique_id\": \"macro.dbt.default__reset_csv_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"default__reset_csv_table\", \"macro_sql\": \"{% macro default__reset_csv_table(model, full_refresh, old_relation, agate_table) %}\\n    {% set sql = \\\"\\\" %}\\n    {% if full_refresh %}\\n        {{ adapter.drop_relation(old_relation) }}\\n        {% set sql = create_csv_table(model, agate_table) %}\\n    {% else %}\\n        {{ adapter.truncate_relation(old_relation) }}\\n        {% set sql = \\\"truncate table \\\" ~ old_relation %}\\n    {% endif %}\\n\\n    {{ return(sql) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.create_csv_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.497696}, \"macro.dbt.get_binding_char\": {\"unique_id\": \"macro.dbt.get_binding_char\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"get_binding_char\", \"macro_sql\": \"{% macro get_binding_char() -%}\\n  {{ adapter.dispatch('get_binding_char', 'dbt')() }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_binding_char\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.498073}, \"macro.dbt.default__get_binding_char\": {\"unique_id\": \"macro.dbt.default__get_binding_char\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"default__get_binding_char\", \"macro_sql\": \"{% macro default__get_binding_char() %}\\n  {{ return('%s') }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.498365}, \"macro.dbt.get_batch_size\": {\"unique_id\": \"macro.dbt.get_batch_size\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"get_batch_size\", \"macro_sql\": \"{% macro get_batch_size() -%}\\n  {{ return(adapter.dispatch('get_batch_size', 'dbt')()) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_batch_size\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.498788}, \"macro.dbt.default__get_batch_size\": {\"unique_id\": \"macro.dbt.default__get_batch_size\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"default__get_batch_size\", \"macro_sql\": \"{% macro default__get_batch_size() %}\\n  {{ return(10000) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.499098}, \"macro.dbt.get_seed_column_quoted_csv\": {\"unique_id\": \"macro.dbt.get_seed_column_quoted_csv\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"get_seed_column_quoted_csv\", \"macro_sql\": \"{% macro get_seed_column_quoted_csv(model, column_names) %}\\n  {%- set quote_seed_column = model['config'].get('quote_columns', None) -%}\\n    {% set quoted = [] %}\\n    {% for col in column_names -%}\\n        {%- do quoted.append(adapter.quote_seed_column(col, quote_seed_column)) -%}\\n    {%- endfor %}\\n\\n    {%- set dest_cols_csv = quoted | join(', ') -%}\\n    {{ return(dest_cols_csv) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.500374}, \"macro.dbt.load_csv_rows\": {\"unique_id\": \"macro.dbt.load_csv_rows\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"load_csv_rows\", \"macro_sql\": \"{% macro load_csv_rows(model, agate_table) -%}\\n  {{ adapter.dispatch('load_csv_rows', 'dbt')(model, agate_table) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__load_csv_rows\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.500983}, \"macro.dbt.default__load_csv_rows\": {\"unique_id\": \"macro.dbt.default__load_csv_rows\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"default__load_csv_rows\", \"macro_sql\": \"{% macro default__load_csv_rows(model, agate_table) %}\\n\\n  {% set batch_size = get_batch_size() %}\\n\\n  {% set cols_sql = get_seed_column_quoted_csv(model, agate_table.column_names) %}\\n  {% set bindings = [] %}\\n\\n  {% set statements = [] %}\\n\\n  {% for chunk in agate_table.rows | batch(batch_size) %}\\n      {% set bindings = [] %}\\n\\n      {% for row in chunk %}\\n          {% do bindings.extend(row) %}\\n      {% endfor %}\\n\\n      {% set sql %}\\n          insert into {{ this.render() }} ({{ cols_sql }}) values\\n          {% for row in chunk -%}\\n              ({%- for column in agate_table.column_names -%}\\n                  {{ get_binding_char() }}\\n                  {%- if not loop.last%},{%- endif %}\\n              {%- endfor -%})\\n              {%- if not loop.last%},{%- endif %}\\n          {%- endfor %}\\n      {% endset %}\\n\\n      {% do adapter.add_query(sql, bindings=bindings, abridge_sql_log=True) %}\\n\\n      {% if loop.index0 == 0 %}\\n          {% do statements.append(sql) %}\\n      {% endif %}\\n  {% endfor %}\\n\\n  {# Return SQL so we can render it out into the compiled files #}\\n  {{ return(statements[0]) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_batch_size\", \"macro.dbt.get_seed_column_quoted_csv\", \"macro.dbt.get_binding_char\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.5042381}, \"macro.dbt.generate_alias_name\": {\"unique_id\": \"macro.dbt.generate_alias_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/get_custom_name/get_custom_alias.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_alias.sql\", \"name\": \"generate_alias_name\", \"macro_sql\": \"{% macro generate_alias_name(custom_alias_name=none, node=none) -%}\\n    {% do return(adapter.dispatch('generate_alias_name', 'dbt')(custom_alias_name, node)) %}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__generate_alias_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.5054028}, \"macro.dbt.default__generate_alias_name\": {\"unique_id\": \"macro.dbt.default__generate_alias_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/get_custom_name/get_custom_alias.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_alias.sql\", \"name\": \"default__generate_alias_name\", \"macro_sql\": \"{% macro default__generate_alias_name(custom_alias_name=none, node=none) -%}\\n\\n    {%- if custom_alias_name is none -%}\\n\\n        {{ node.name }}\\n\\n    {%- else -%}\\n\\n        {{ custom_alias_name | trim }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.505999}, \"macro.dbt.generate_schema_name\": {\"unique_id\": \"macro.dbt.generate_schema_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/get_custom_name/get_custom_schema.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_schema.sql\", \"name\": \"generate_schema_name\", \"macro_sql\": \"{% macro generate_schema_name(custom_schema_name=none, node=none) -%}\\n    {{ return(adapter.dispatch('generate_schema_name', 'dbt')(custom_schema_name, node)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__generate_schema_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.507547}, \"macro.dbt.default__generate_schema_name\": {\"unique_id\": \"macro.dbt.default__generate_schema_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/get_custom_name/get_custom_schema.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_schema.sql\", \"name\": \"default__generate_schema_name\", \"macro_sql\": \"{% macro default__generate_schema_name(custom_schema_name, node) -%}\\n\\n    {%- set default_schema = target.schema -%}\\n    {%- if custom_schema_name is none -%}\\n\\n        {{ default_schema }}\\n\\n    {%- else -%}\\n\\n        {{ default_schema }}_{{ custom_schema_name | trim }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.508227}, \"macro.dbt.generate_schema_name_for_env\": {\"unique_id\": \"macro.dbt.generate_schema_name_for_env\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/get_custom_name/get_custom_schema.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_schema.sql\", \"name\": \"generate_schema_name_for_env\", \"macro_sql\": \"{% macro generate_schema_name_for_env(custom_schema_name, node) -%}\\n\\n    {%- set default_schema = target.schema -%}\\n    {%- if target.name == 'prod' and custom_schema_name is not none -%}\\n\\n        {{ custom_schema_name | trim }}\\n\\n    {%- else -%}\\n\\n        {{ default_schema }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.508971}, \"macro.dbt.generate_database_name\": {\"unique_id\": \"macro.dbt.generate_database_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/get_custom_name/get_custom_database.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_database.sql\", \"name\": \"generate_database_name\", \"macro_sql\": \"{% macro generate_database_name(custom_database_name=none, node=none) -%}\\n    {% do return(adapter.dispatch('generate_database_name', 'dbt')(custom_database_name, node)) %}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__generate_database_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.5101619}, \"macro.dbt.default__generate_database_name\": {\"unique_id\": \"macro.dbt.default__generate_database_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/get_custom_name/get_custom_database.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_database.sql\", \"name\": \"default__generate_database_name\", \"macro_sql\": \"{% macro default__generate_database_name(custom_database_name=none, node=none) -%}\\n    {%- set default_database = target.database -%}\\n    {%- if custom_database_name is none -%}\\n\\n        {{ default_database }}\\n\\n    {%- else -%}\\n\\n        {{ custom_database_name }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.510827}, \"macro.dbt.default__test_relationships\": {\"unique_id\": \"macro.dbt.default__test_relationships\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/generic_test_sql/relationships.sql\", \"original_file_path\": \"macros/generic_test_sql/relationships.sql\", \"name\": \"default__test_relationships\", \"macro_sql\": \"{% macro default__test_relationships(model, column_name, to, field) %}\\n\\nwith child as (\\n    select {{ column_name }} as from_field\\n    from {{ model }}\\n    where {{ column_name }} is not null\\n),\\n\\nparent as (\\n    select {{ field }} as to_field\\n    from {{ to }}\\n)\\n\\nselect\\n    from_field\\n\\nfrom child\\nleft join parent\\n    on child.from_field = parent.to_field\\n\\nwhere parent.to_field is null\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.511889}, \"macro.dbt.default__test_not_null\": {\"unique_id\": \"macro.dbt.default__test_not_null\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/generic_test_sql/not_null.sql\", \"original_file_path\": \"macros/generic_test_sql/not_null.sql\", \"name\": \"default__test_not_null\", \"macro_sql\": \"{% macro default__test_not_null(model, column_name) %}\\n\\n{% set column_list = '*' if should_store_failures() else column_name %}\\n\\nselect {{ column_list }}\\nfrom {{ model }}\\nwhere {{ column_name }} is null\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.should_store_failures\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.5128162}, \"macro.dbt.default__test_unique\": {\"unique_id\": \"macro.dbt.default__test_unique\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/generic_test_sql/unique.sql\", \"original_file_path\": \"macros/generic_test_sql/unique.sql\", \"name\": \"default__test_unique\", \"macro_sql\": \"{% macro default__test_unique(model, column_name) %}\\n\\nselect\\n    {{ column_name }} as unique_field,\\n    count(*) as n_records\\n\\nfrom {{ model }}\\nwhere {{ column_name }} is not null\\ngroup by {{ column_name }}\\nhaving count(*) > 1\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.5136151}, \"macro.dbt.default__test_accepted_values\": {\"unique_id\": \"macro.dbt.default__test_accepted_values\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/generic_test_sql/accepted_values.sql\", \"original_file_path\": \"macros/generic_test_sql/accepted_values.sql\", \"name\": \"default__test_accepted_values\", \"macro_sql\": \"{% macro default__test_accepted_values(model, column_name, values, quote=True) %}\\n\\nwith all_values as (\\n\\n    select\\n        {{ column_name }} as value_field,\\n        count(*) as n_records\\n\\n    from {{ model }}\\n    group by {{ column_name }}\\n\\n)\\n\\nselect *\\nfrom all_values\\nwhere value_field not in (\\n    {% for value in values -%}\\n        {% if quote -%}\\n        '{{ value }}'\\n        {%- else -%}\\n        {{ value }}\\n        {%- endif -%}\\n        {%- if not loop.last -%},{%- endif %}\\n    {%- endfor %}\\n)\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.515251}, \"macro.dbt.statement\": {\"unique_id\": \"macro.dbt.statement\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/etc/statement.sql\", \"original_file_path\": \"macros/etc/statement.sql\", \"name\": \"statement\", \"macro_sql\": \"{% macro statement(name=None, fetch_result=False, auto_begin=True) -%}\\n  {%- if execute: -%}\\n    {%- set sql = caller() -%}\\n\\n    {%- if name == 'main' -%}\\n      {{ log('Writing runtime SQL for node \\\"{}\\\"'.format(model['unique_id'])) }}\\n      {{ write(sql) }}\\n    {%- endif -%}\\n\\n    {%- set res, table = adapter.execute(sql, auto_begin=auto_begin, fetch=fetch_result) -%}\\n    {%- if name is not none -%}\\n      {{ store_result(name, response=res, agate_table=table) }}\\n    {%- endif -%}\\n\\n  {%- endif -%}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.518385}, \"macro.dbt.noop_statement\": {\"unique_id\": \"macro.dbt.noop_statement\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/etc/statement.sql\", \"original_file_path\": \"macros/etc/statement.sql\", \"name\": \"noop_statement\", \"macro_sql\": \"{% macro noop_statement(name=None, message=None, code=None, rows_affected=None, res=None) -%}\\n  {%- set sql = caller() -%}\\n\\n  {%- if name == 'main' -%}\\n    {{ log('Writing runtime SQL for node \\\"{}\\\"'.format(model['unique_id'])) }}\\n    {{ write(sql) }}\\n  {%- endif -%}\\n\\n  {%- if name is not none -%}\\n    {{ store_raw_result(name, message=message, code=code, rows_affected=rows_affected, agate_table=res) }}\\n  {%- endif -%}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.519926}, \"macro.dbt.run_query\": {\"unique_id\": \"macro.dbt.run_query\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/etc/statement.sql\", \"original_file_path\": \"macros/etc/statement.sql\", \"name\": \"run_query\", \"macro_sql\": \"{% macro run_query(sql) %}\\n  {% call statement(\\\"run_query_statement\\\", fetch_result=true, auto_begin=false) %}\\n    {{ sql }}\\n  {% endcall %}\\n\\n  {% do return(load_result(\\\"run_query_statement\\\").table) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.5207071}, \"macro.dbt.convert_datetime\": {\"unique_id\": \"macro.dbt.convert_datetime\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"name\": \"convert_datetime\", \"macro_sql\": \"{% macro convert_datetime(date_str, date_fmt) %}\\n\\n  {% set error_msg -%}\\n      The provided partition date '{{ date_str }}' does not match the expected format '{{ date_fmt }}'\\n  {%- endset %}\\n\\n  {% set res = try_or_compiler_error(error_msg, modules.datetime.datetime.strptime, date_str.strip(), date_fmt) %}\\n  {{ return(res) }}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.525802}, \"macro.dbt.dates_in_range\": {\"unique_id\": \"macro.dbt.dates_in_range\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"name\": \"dates_in_range\", \"macro_sql\": \"{% macro dates_in_range(start_date_str, end_date_str=none, in_fmt=\\\"%Y%m%d\\\", out_fmt=\\\"%Y%m%d\\\") %}\\n    {% set end_date_str = start_date_str if end_date_str is none else end_date_str %}\\n\\n    {% set start_date = convert_datetime(start_date_str, in_fmt) %}\\n    {% set end_date = convert_datetime(end_date_str, in_fmt) %}\\n\\n    {% set day_count = (end_date - start_date).days %}\\n    {% if day_count < 0 %}\\n        {% set msg -%}\\n            Partition start date is after the end date ({{ start_date }}, {{ end_date }})\\n        {%- endset %}\\n\\n        {{ exceptions.raise_compiler_error(msg, model) }}\\n    {% endif %}\\n\\n    {% set date_list = [] %}\\n    {% for i in range(0, day_count + 1) %}\\n        {% set the_date = (modules.datetime.timedelta(days=i) + start_date) %}\\n        {% if not out_fmt %}\\n            {% set _ = date_list.append(the_date) %}\\n        {% else %}\\n            {% set _ = date_list.append(the_date.strftime(out_fmt)) %}\\n        {% endif %}\\n    {% endfor %}\\n\\n    {{ return(date_list) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.convert_datetime\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.52915}, \"macro.dbt.partition_range\": {\"unique_id\": \"macro.dbt.partition_range\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"name\": \"partition_range\", \"macro_sql\": \"{% macro partition_range(raw_partition_date, date_fmt='%Y%m%d') %}\\n    {% set partition_range = (raw_partition_date | string).split(\\\",\\\") %}\\n\\n    {% if (partition_range | length) == 1 %}\\n      {% set start_date = partition_range[0] %}\\n      {% set end_date = none %}\\n    {% elif (partition_range | length) == 2 %}\\n      {% set start_date = partition_range[0] %}\\n      {% set end_date = partition_range[1] %}\\n    {% else %}\\n      {{ exceptions.raise_compiler_error(\\\"Invalid partition time. Expected format: {Start Date}[,{End Date}]. Got: \\\" ~ raw_partition_date) }}\\n    {% endif %}\\n\\n    {{ return(dates_in_range(start_date, end_date, in_fmt=date_fmt)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.dates_in_range\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.53116}, \"macro.dbt.py_current_timestring\": {\"unique_id\": \"macro.dbt.py_current_timestring\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"name\": \"py_current_timestring\", \"macro_sql\": \"{% macro py_current_timestring() %}\\n    {% set dt = modules.datetime.datetime.now() %}\\n    {% do return(dt.strftime(\\\"%Y%m%d%H%M%S%f\\\")) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.5317729}, \"macro.dbt.create_schema\": {\"unique_id\": \"macro.dbt.create_schema\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/schema.sql\", \"original_file_path\": \"macros/adapters/schema.sql\", \"name\": \"create_schema\", \"macro_sql\": \"{% macro create_schema(relation) -%}\\n  {{ adapter.dispatch('create_schema', 'dbt')(relation) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__create_schema\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.532931}, \"macro.dbt.default__create_schema\": {\"unique_id\": \"macro.dbt.default__create_schema\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/schema.sql\", \"original_file_path\": \"macros/adapters/schema.sql\", \"name\": \"default__create_schema\", \"macro_sql\": \"{% macro default__create_schema(relation) -%}\\n  {%- call statement('create_schema') -%}\\n    create schema if not exists {{ relation.without_identifier() }}\\n  {% endcall %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.533409}, \"macro.dbt.drop_schema\": {\"unique_id\": \"macro.dbt.drop_schema\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/schema.sql\", \"original_file_path\": \"macros/adapters/schema.sql\", \"name\": \"drop_schema\", \"macro_sql\": \"{% macro drop_schema(relation) -%}\\n  {{ adapter.dispatch('drop_schema', 'dbt')(relation) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__drop_schema\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.533822}, \"macro.dbt.default__drop_schema\": {\"unique_id\": \"macro.dbt.default__drop_schema\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/schema.sql\", \"original_file_path\": \"macros/adapters/schema.sql\", \"name\": \"default__drop_schema\", \"macro_sql\": \"{% macro default__drop_schema(relation) -%}\\n  {%- call statement('drop_schema') -%}\\n    drop schema if exists {{ relation.without_identifier() }} cascade\\n  {% endcall %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.5342898}, \"macro.dbt.get_create_index_sql\": {\"unique_id\": \"macro.dbt.get_create_index_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"name\": \"get_create_index_sql\", \"macro_sql\": \"{% macro get_create_index_sql(relation, index_dict) -%}\\n  {{ return(adapter.dispatch('get_create_index_sql', 'dbt')(relation, index_dict)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_create_index_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.5356438}, \"macro.dbt.default__get_create_index_sql\": {\"unique_id\": \"macro.dbt.default__get_create_index_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"name\": \"default__get_create_index_sql\", \"macro_sql\": \"{% macro default__get_create_index_sql(relation, index_dict) -%}\\n  {% do return(None) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.536011}, \"macro.dbt.create_indexes\": {\"unique_id\": \"macro.dbt.create_indexes\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"name\": \"create_indexes\", \"macro_sql\": \"{% macro create_indexes(relation) -%}\\n  {{ adapter.dispatch('create_indexes', 'dbt')(relation) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__create_indexes\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.536417}, \"macro.dbt.default__create_indexes\": {\"unique_id\": \"macro.dbt.default__create_indexes\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"name\": \"default__create_indexes\", \"macro_sql\": \"{% macro default__create_indexes(relation) -%}\\n  {%- set _indexes = config.get('indexes', default=[]) -%}\\n\\n  {% for _index_dict in _indexes %}\\n    {% set create_index_sql = get_create_index_sql(relation, _index_dict) %}\\n    {% if create_index_sql %}\\n      {% do run_query(create_index_sql) %}\\n    {% endif %}\\n  {% endfor %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_create_index_sql\", \"macro.dbt.run_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.5374599}, \"macro.dbt.make_temp_relation\": {\"unique_id\": \"macro.dbt.make_temp_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"make_temp_relation\", \"macro_sql\": \"{% macro make_temp_relation(base_relation, suffix='__dbt_tmp') %}\\n  {{ return(adapter.dispatch('make_temp_relation', 'dbt')(base_relation, suffix))}}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_temp_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.542093}, \"macro.dbt.default__make_temp_relation\": {\"unique_id\": \"macro.dbt.default__make_temp_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"default__make_temp_relation\", \"macro_sql\": \"{% macro default__make_temp_relation(base_relation, suffix) %}\\n    {% set tmp_identifier = base_relation.identifier ~ suffix %}\\n    {% set tmp_relation = base_relation.incorporate(\\n                                path={\\\"identifier\\\": tmp_identifier}) -%}\\n\\n    {% do return(tmp_relation) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.5428941}, \"macro.dbt.drop_relation\": {\"unique_id\": \"macro.dbt.drop_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"drop_relation\", \"macro_sql\": \"{% macro drop_relation(relation) -%}\\n  {{ return(adapter.dispatch('drop_relation', 'dbt')(relation)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__drop_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.543366}, \"macro.dbt.default__drop_relation\": {\"unique_id\": \"macro.dbt.default__drop_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"default__drop_relation\", \"macro_sql\": \"{% macro default__drop_relation(relation) -%}\\n  {% call statement('drop_relation', auto_begin=False) -%}\\n    drop {{ relation.type }} if exists {{ relation }} cascade\\n  {%- endcall %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.543921}, \"macro.dbt.truncate_relation\": {\"unique_id\": \"macro.dbt.truncate_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"truncate_relation\", \"macro_sql\": \"{% macro truncate_relation(relation) -%}\\n  {{ return(adapter.dispatch('truncate_relation', 'dbt')(relation)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__truncate_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.544389}, \"macro.dbt.default__truncate_relation\": {\"unique_id\": \"macro.dbt.default__truncate_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"default__truncate_relation\", \"macro_sql\": \"{% macro default__truncate_relation(relation) -%}\\n  {% call statement('truncate_relation') -%}\\n    truncate table {{ relation }}\\n  {%- endcall %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.544798}, \"macro.dbt.rename_relation\": {\"unique_id\": \"macro.dbt.rename_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"rename_relation\", \"macro_sql\": \"{% macro rename_relation(from_relation, to_relation) -%}\\n  {{ return(adapter.dispatch('rename_relation', 'dbt')(from_relation, to_relation)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__rename_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.5453591}, \"macro.dbt.default__rename_relation\": {\"unique_id\": \"macro.dbt.default__rename_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"default__rename_relation\", \"macro_sql\": \"{% macro default__rename_relation(from_relation, to_relation) -%}\\n  {% set target_name = adapter.quote_as_configured(to_relation.identifier, 'identifier') %}\\n  {% call statement('rename_relation') -%}\\n    alter table {{ from_relation }} rename to {{ target_name }}\\n  {%- endcall %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.546091}, \"macro.dbt.get_or_create_relation\": {\"unique_id\": \"macro.dbt.get_or_create_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"get_or_create_relation\", \"macro_sql\": \"{% macro get_or_create_relation(database, schema, identifier, type) -%}\\n  {{ return(adapter.dispatch('get_or_create_relation', 'dbt')(database, schema, identifier, type)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_or_create_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.546772}, \"macro.dbt.default__get_or_create_relation\": {\"unique_id\": \"macro.dbt.default__get_or_create_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"default__get_or_create_relation\", \"macro_sql\": \"{% macro default__get_or_create_relation(database, schema, identifier, type) %}\\n  {%- set target_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) %}\\n\\n  {% if target_relation %}\\n    {% do return([true, target_relation]) %}\\n  {% endif %}\\n\\n  {%- set new_relation = api.Relation.create(\\n      database=database,\\n      schema=schema,\\n      identifier=identifier,\\n      type=type\\n  ) -%}\\n  {% do return([false, new_relation]) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.548408}, \"macro.dbt.load_relation\": {\"unique_id\": \"macro.dbt.load_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"load_relation\", \"macro_sql\": \"{% macro load_relation(relation) %}\\n  {% do return(adapter.get_relation(\\n    database=relation.database,\\n    schema=relation.schema,\\n    identifier=relation.identifier\\n  )) -%}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.54901}, \"macro.dbt.drop_relation_if_exists\": {\"unique_id\": \"macro.dbt.drop_relation_if_exists\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"drop_relation_if_exists\", \"macro_sql\": \"{% macro drop_relation_if_exists(relation) %}\\n  {% if relation is not none %}\\n    {{ adapter.drop_relation(relation) }}\\n  {% endif %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.549522}, \"macro.dbt.current_timestamp\": {\"unique_id\": \"macro.dbt.current_timestamp\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/freshness.sql\", \"original_file_path\": \"macros/adapters/freshness.sql\", \"name\": \"current_timestamp\", \"macro_sql\": \"{% macro current_timestamp() -%}\\n  {{ adapter.dispatch('current_timestamp', 'dbt')() }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.550913}, \"macro.dbt.default__current_timestamp\": {\"unique_id\": \"macro.dbt.default__current_timestamp\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/freshness.sql\", \"original_file_path\": \"macros/adapters/freshness.sql\", \"name\": \"default__current_timestamp\", \"macro_sql\": \"{% macro default__current_timestamp() -%}\\n  {{ exceptions.raise_not_implemented(\\n    'current_timestamp macro not implemented for adapter '+adapter.type()) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.551292}, \"macro.dbt.collect_freshness\": {\"unique_id\": \"macro.dbt.collect_freshness\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/freshness.sql\", \"original_file_path\": \"macros/adapters/freshness.sql\", \"name\": \"collect_freshness\", \"macro_sql\": \"{% macro collect_freshness(source, loaded_at_field, filter) %}\\n  {{ return(adapter.dispatch('collect_freshness', 'dbt')(source, loaded_at_field, filter))}}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__collect_freshness\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.5518851}, \"macro.dbt.default__collect_freshness\": {\"unique_id\": \"macro.dbt.default__collect_freshness\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/freshness.sql\", \"original_file_path\": \"macros/adapters/freshness.sql\", \"name\": \"default__collect_freshness\", \"macro_sql\": \"{% macro default__collect_freshness(source, loaded_at_field, filter) %}\\n  {% call statement('collect_freshness', fetch_result=True, auto_begin=False) -%}\\n    select\\n      max({{ loaded_at_field }}) as max_loaded_at,\\n      {{ current_timestamp() }} as snapshotted_at\\n    from {{ source }}\\n    {% if filter %}\\n    where {{ filter }}\\n    {% endif %}\\n  {% endcall %}\\n  {{ return(load_result('collect_freshness').table) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\", \"macro.dbt.current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.552993}, \"macro.dbt.alter_column_comment\": {\"unique_id\": \"macro.dbt.alter_column_comment\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"name\": \"alter_column_comment\", \"macro_sql\": \"{% macro alter_column_comment(relation, column_dict) -%}\\n  {{ return(adapter.dispatch('alter_column_comment', 'dbt')(relation, column_dict)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__alter_column_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.554944}, \"macro.dbt.default__alter_column_comment\": {\"unique_id\": \"macro.dbt.default__alter_column_comment\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"name\": \"default__alter_column_comment\", \"macro_sql\": \"{% macro default__alter_column_comment(relation, column_dict) -%}\\n  {{ exceptions.raise_not_implemented(\\n    'alter_column_comment macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.5553741}, \"macro.dbt.alter_relation_comment\": {\"unique_id\": \"macro.dbt.alter_relation_comment\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"name\": \"alter_relation_comment\", \"macro_sql\": \"{% macro alter_relation_comment(relation, relation_comment) -%}\\n  {{ return(adapter.dispatch('alter_relation_comment', 'dbt')(relation, relation_comment)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__alter_relation_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.5559008}, \"macro.dbt.default__alter_relation_comment\": {\"unique_id\": \"macro.dbt.default__alter_relation_comment\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"name\": \"default__alter_relation_comment\", \"macro_sql\": \"{% macro default__alter_relation_comment(relation, relation_comment) -%}\\n  {{ exceptions.raise_not_implemented(\\n    'alter_relation_comment macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.556353}, \"macro.dbt.persist_docs\": {\"unique_id\": \"macro.dbt.persist_docs\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"name\": \"persist_docs\", \"macro_sql\": \"{% macro persist_docs(relation, model, for_relation=true, for_columns=true) -%}\\n  {{ return(adapter.dispatch('persist_docs', 'dbt')(relation, model, for_relation, for_columns)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__persist_docs\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.557066}, \"macro.dbt.default__persist_docs\": {\"unique_id\": \"macro.dbt.default__persist_docs\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"name\": \"default__persist_docs\", \"macro_sql\": \"{% macro default__persist_docs(relation, model, for_relation, for_columns) -%}\\n  {% if for_relation and config.persist_relation_docs() and model.description %}\\n    {% do run_query(alter_relation_comment(relation, model.description)) %}\\n  {% endif %}\\n\\n  {% if for_columns and config.persist_column_docs() and model.columns %}\\n    {% do run_query(alter_column_comment(relation, model.columns)) %}\\n  {% endif %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.run_query\", \"macro.dbt.alter_relation_comment\", \"macro.dbt.alter_column_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.55835}, \"macro.dbt.get_catalog\": {\"unique_id\": \"macro.dbt.get_catalog\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"name\": \"get_catalog\", \"macro_sql\": \"{% macro get_catalog(information_schema, schemas) -%}\\n  {{ return(adapter.dispatch('get_catalog', 'dbt')(information_schema, schemas)) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_catalog\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.5624719}, \"macro.dbt.default__get_catalog\": {\"unique_id\": \"macro.dbt.default__get_catalog\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"name\": \"default__get_catalog\", \"macro_sql\": \"{% macro default__get_catalog(information_schema, schemas) -%}\\n\\n  {% set typename = adapter.type() %}\\n  {% set msg -%}\\n    get_catalog not implemented for {{ typename }}\\n  {%- endset %}\\n\\n  {{ exceptions.raise_compiler_error(msg) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.563156}, \"macro.dbt.information_schema_name\": {\"unique_id\": \"macro.dbt.information_schema_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"name\": \"information_schema_name\", \"macro_sql\": \"{% macro information_schema_name(database) %}\\n  {{ return(adapter.dispatch('information_schema_name', 'dbt')(database)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__information_schema_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.563638}, \"macro.dbt.default__information_schema_name\": {\"unique_id\": \"macro.dbt.default__information_schema_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"name\": \"default__information_schema_name\", \"macro_sql\": \"{% macro default__information_schema_name(database) -%}\\n  {%- if database -%}\\n    {{ database }}.INFORMATION_SCHEMA\\n  {%- else -%}\\n    INFORMATION_SCHEMA\\n  {%- endif -%}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.564032}, \"macro.dbt.list_schemas\": {\"unique_id\": \"macro.dbt.list_schemas\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"name\": \"list_schemas\", \"macro_sql\": \"{% macro list_schemas(database) -%}\\n  {{ return(adapter.dispatch('list_schemas', 'dbt')(database)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__list_schemas\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.564497}, \"macro.dbt.default__list_schemas\": {\"unique_id\": \"macro.dbt.default__list_schemas\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"name\": \"default__list_schemas\", \"macro_sql\": \"{% macro default__list_schemas(database) -%}\\n  {% set sql %}\\n    select distinct schema_name\\n    from {{ information_schema_name(database) }}.SCHEMATA\\n    where catalog_name ilike '{{ database }}'\\n  {% endset %}\\n  {{ return(run_query(sql)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.information_schema_name\", \"macro.dbt.run_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.565144}, \"macro.dbt.check_schema_exists\": {\"unique_id\": \"macro.dbt.check_schema_exists\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"name\": \"check_schema_exists\", \"macro_sql\": \"{% macro check_schema_exists(information_schema, schema) -%}\\n  {{ return(adapter.dispatch('check_schema_exists', 'dbt')(information_schema, schema)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__check_schema_exists\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.565687}, \"macro.dbt.default__check_schema_exists\": {\"unique_id\": \"macro.dbt.default__check_schema_exists\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"name\": \"default__check_schema_exists\", \"macro_sql\": \"{% macro default__check_schema_exists(information_schema, schema) -%}\\n  {% set sql -%}\\n        select count(*)\\n        from {{ information_schema.replace(information_schema_view='SCHEMATA') }}\\n        where catalog_name='{{ information_schema.database }}'\\n          and schema_name='{{ schema }}'\\n  {%- endset %}\\n  {{ return(run_query(sql)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.run_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.566637}, \"macro.dbt.list_relations_without_caching\": {\"unique_id\": \"macro.dbt.list_relations_without_caching\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"name\": \"list_relations_without_caching\", \"macro_sql\": \"{% macro list_relations_without_caching(schema_relation) %}\\n  {{ return(adapter.dispatch('list_relations_without_caching', 'dbt')(schema_relation)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__list_relations_without_caching\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.5671191}, \"macro.dbt.default__list_relations_without_caching\": {\"unique_id\": \"macro.dbt.default__list_relations_without_caching\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"name\": \"default__list_relations_without_caching\", \"macro_sql\": \"{% macro default__list_relations_without_caching(schema_relation) %}\\n  {{ exceptions.raise_not_implemented(\\n    'list_relations_without_caching macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.567532}, \"macro.dbt.get_columns_in_relation\": {\"unique_id\": \"macro.dbt.get_columns_in_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"name\": \"get_columns_in_relation\", \"macro_sql\": \"{% macro get_columns_in_relation(relation) -%}\\n  {{ return(adapter.dispatch('get_columns_in_relation', 'dbt')(relation)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_columns_in_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.572185}, \"macro.dbt.default__get_columns_in_relation\": {\"unique_id\": \"macro.dbt.default__get_columns_in_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"name\": \"default__get_columns_in_relation\", \"macro_sql\": \"{% macro default__get_columns_in_relation(relation) -%}\\n  {{ exceptions.raise_not_implemented(\\n    'get_columns_in_relation macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.572603}, \"macro.dbt.sql_convert_columns_in_relation\": {\"unique_id\": \"macro.dbt.sql_convert_columns_in_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"name\": \"sql_convert_columns_in_relation\", \"macro_sql\": \"{% macro sql_convert_columns_in_relation(table) -%}\\n  {% set columns = [] %}\\n  {% for row in table %}\\n    {% do columns.append(api.Column(*row)) %}\\n  {% endfor %}\\n  {{ return(columns) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.5734131}, \"macro.dbt.get_columns_in_query\": {\"unique_id\": \"macro.dbt.get_columns_in_query\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"name\": \"get_columns_in_query\", \"macro_sql\": \"{% macro get_columns_in_query(select_sql) -%}\\n  {{ return(adapter.dispatch('get_columns_in_query', 'dbt')(select_sql)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_columns_in_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.573897}, \"macro.dbt.default__get_columns_in_query\": {\"unique_id\": \"macro.dbt.default__get_columns_in_query\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"name\": \"default__get_columns_in_query\", \"macro_sql\": \"{% macro default__get_columns_in_query(select_sql) %}\\n    {% call statement('get_columns_in_query', fetch_result=True, auto_begin=False) -%}\\n        select * from (\\n            {{ select_sql }}\\n        ) as __dbt_sbq\\n        where false\\n        limit 0\\n    {% endcall %}\\n\\n    {{ return(load_result('get_columns_in_query').table.columns | map(attribute='name') | list) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.5747972}, \"macro.dbt.alter_column_type\": {\"unique_id\": \"macro.dbt.alter_column_type\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"name\": \"alter_column_type\", \"macro_sql\": \"{% macro alter_column_type(relation, column_name, new_column_type) -%}\\n  {{ return(adapter.dispatch('alter_column_type', 'dbt')(relation, column_name, new_column_type)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__alter_column_type\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.5754082}, \"macro.dbt.default__alter_column_type\": {\"unique_id\": \"macro.dbt.default__alter_column_type\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"name\": \"default__alter_column_type\", \"macro_sql\": \"{% macro default__alter_column_type(relation, column_name, new_column_type) -%}\\n  {#\\n    1. Create a new column (w/ temp name and correct type)\\n    2. Copy data over to it\\n    3. Drop the existing column (cascade!)\\n    4. Rename the new column to existing column\\n  #}\\n  {%- set tmp_column = column_name + \\\"__dbt_alter\\\" -%}\\n\\n  {% call statement('alter_column_type') %}\\n    alter table {{ relation }} add column {{ adapter.quote(tmp_column) }} {{ new_column_type }};\\n    update {{ relation }} set {{ adapter.quote(tmp_column) }} = {{ adapter.quote(column_name) }};\\n    alter table {{ relation }} drop column {{ adapter.quote(column_name) }} cascade;\\n    alter table {{ relation }} rename column {{ adapter.quote(tmp_column) }} to {{ adapter.quote(column_name) }}\\n  {% endcall %}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.577007}, \"macro.dbt.alter_relation_add_remove_columns\": {\"unique_id\": \"macro.dbt.alter_relation_add_remove_columns\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"name\": \"alter_relation_add_remove_columns\", \"macro_sql\": \"{% macro alter_relation_add_remove_columns(relation, add_columns = none, remove_columns = none) -%}\\n  {{ return(adapter.dispatch('alter_relation_add_remove_columns', 'dbt')(relation, add_columns, remove_columns)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__alter_relation_add_remove_columns\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.577695}, \"macro.dbt.default__alter_relation_add_remove_columns\": {\"unique_id\": \"macro.dbt.default__alter_relation_add_remove_columns\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"name\": \"default__alter_relation_add_remove_columns\", \"macro_sql\": \"{% macro default__alter_relation_add_remove_columns(relation, add_columns, remove_columns) %}\\n\\n  {% if add_columns is none %}\\n    {% set add_columns = [] %}\\n  {% endif %}\\n  {% if remove_columns is none %}\\n    {% set remove_columns = [] %}\\n  {% endif %}\\n\\n  {% set sql -%}\\n\\n     alter {{ relation.type }} {{ relation }}\\n\\n            {% for column in add_columns %}\\n               add column {{ column.name }} {{ column.data_type }}{{ ',' if not loop.last }}\\n            {% endfor %}{{ ',' if add_columns and remove_columns }}\\n\\n            {% for column in remove_columns %}\\n                drop column {{ column.name }}{{ ',' if not loop.last }}\\n            {% endfor %}\\n\\n  {%- endset -%}\\n\\n  {% do run_query(sql) %}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.run_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.579798}, \"macro.dbt.test_unique\": {\"unique_id\": \"macro.dbt.test_unique\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"tests/generic/builtin.sql\", \"original_file_path\": \"tests/generic/builtin.sql\", \"name\": \"test_unique\", \"macro_sql\": \"{% test unique(model, column_name) %}\\n    {% set macro = adapter.dispatch('test_unique', 'dbt') %}\\n    {{ macro(model, column_name) }}\\n{% endtest %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__test_unique\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.581336}, \"macro.dbt.test_not_null\": {\"unique_id\": \"macro.dbt.test_not_null\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"tests/generic/builtin.sql\", \"original_file_path\": \"tests/generic/builtin.sql\", \"name\": \"test_not_null\", \"macro_sql\": \"{% test not_null(model, column_name) %}\\n    {% set macro = adapter.dispatch('test_not_null', 'dbt') %}\\n    {{ macro(model, column_name) }}\\n{% endtest %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__test_not_null\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.581941}, \"macro.dbt.test_accepted_values\": {\"unique_id\": \"macro.dbt.test_accepted_values\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"tests/generic/builtin.sql\", \"original_file_path\": \"tests/generic/builtin.sql\", \"name\": \"test_accepted_values\", \"macro_sql\": \"{% test accepted_values(model, column_name, values, quote=True) %}\\n    {% set macro = adapter.dispatch('test_accepted_values', 'dbt') %}\\n    {{ macro(model, column_name, values, quote) }}\\n{% endtest %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__test_accepted_values\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.582701}, \"macro.dbt.test_relationships\": {\"unique_id\": \"macro.dbt.test_relationships\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"tests/generic/builtin.sql\", \"original_file_path\": \"tests/generic/builtin.sql\", \"name\": \"test_relationships\", \"macro_sql\": \"{% test relationships(model, column_name, to, field) %}\\n    {% set macro = adapter.dispatch('test_relationships', 'dbt') %}\\n    {{ macro(model, column_name, to, field) }}\\n{% endtest %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__test_relationships\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058585.583425}}, \"docs\": {\"dbt.__overview__\": {\"unique_id\": \"dbt.__overview__\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"overview.md\", \"original_file_path\": \"docs/overview.md\", \"name\": \"__overview__\", \"block_contents\": \"### Welcome!\\n\\nWelcome to the auto-generated documentation for your dbt project!\\n\\n### Navigation\\n\\nYou can use the `Project` and `Database` navigation tabs on the left side of the window to explore the models\\nin your project.\\n\\n#### Project Tab\\nThe `Project` tab mirrors the directory structure of your dbt project. In this tab, you can see all of the\\nmodels defined in your dbt project, as well as models imported from dbt packages.\\n\\n#### Database Tab\\nThe `Database` tab also exposes your models, but in a format that looks more like a database explorer. This view\\nshows relations (tables and views) grouped into database schemas. Note that ephemeral models are _not_ shown\\nin this interface, as they do not exist in the database.\\n\\n### Graph Exploration\\nYou can click the blue icon on the bottom-right corner of the page to view the lineage graph of your models.\\n\\nOn model pages, you'll see the immediate parents and children of the model you're exploring. By clicking the `Expand`\\nbutton at the top-right of this lineage pane, you'll be able to see all of the models that are used to build,\\nor are built from, the model you're exploring.\\n\\nOnce expanded, you'll be able to use the `--select` and `--exclude` model selection syntax to filter the\\nmodels in the graph. For more information on model selection, check out the [dbt docs](https://docs.getdbt.com/docs/model-selection-syntax).\\n\\nNote that you can also right-click on models to interactively filter and explore the graph.\\n\\n---\\n\\n### More information\\n\\n- [What is dbt](https://docs.getdbt.com/docs/introduction)?\\n- Read the [dbt viewpoint](https://docs.getdbt.com/docs/viewpoint)\\n- [Installation](https://docs.getdbt.com/docs/installation)\\n- Join the [dbt Community](https://www.getdbt.com/community/) for questions and discussion\"}}, \"exposures\": {}, \"metrics\": {\"metric.test.my_metric\": {\"fqn\": [\"test\", \"my_metric\"], \"unique_id\": \"metric.test.my_metric\", \"package_name\": \"test\", \"root_path\": \"/Users/jerco/dev/scratch/testy\", \"path\": \"metric.yml\", \"original_file_path\": \"models/metric.yml\", \"model\": \"ref('my_model')\", \"name\": \"my_metric\", \"description\": \"\", \"label\": \"Count records\", \"type\": \"count\", \"sql\": \"*\", \"timestamp\": \"updated_at\", \"filters\": [], \"time_grains\": [\"day\"], \"dimensions\": [], \"resource_type\": \"metric\", \"meta\": {}, \"tags\": [], \"sources\": [], \"depends_on\": {\"macros\": [], \"nodes\": [\"model.test.my_model\"]}, \"refs\": [[\"my_model\"]], \"created_at\": 1663058585.822956}}, \"selectors\": {}, \"disabled\": {}, \"parent_map\": {\"model.test.my_model\": [], \"metric.test.my_metric\": [\"model.test.my_model\"]}, \"child_map\": {\"model.test.my_model\": [\"metric.test.my_metric\"], \"metric.test.my_metric\": []}}\n"
  },
  {
    "path": "tests/functional/artifacts/data/state/v6/manifest.json",
    "content": "{\"metadata\": {\"dbt_schema_version\": \"https://schemas.getdbt.com/dbt/manifest/v6.json\", \"dbt_version\": \"1.2.1\", \"generated_at\": \"2022-09-13T08:42:50.298210Z\", \"invocation_id\": \"aa834731-46c3-49aa-8ec8-956dae621b58\", \"env\": {}, \"project_id\": \"098f6bcd4621d373cade4e832627b4f6\", \"user_id\": null, \"send_anonymous_usage_stats\": false, \"adapter_type\": \"postgres\"}, \"nodes\": {\"model.test.my_model\": {\"raw_sql\": \"select 1 as id\", \"resource_type\": \"model\", \"depends_on\": {\"macros\": [], \"nodes\": []}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"materialized\": \"view\", \"persist_docs\": {}, \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": null, \"on_schema_change\": \"ignore\", \"grants\": {}, \"post-hook\": [], \"pre-hook\": []}, \"database\": \"jerco\", \"schema\": \"dbt_jcohen\", \"fqn\": [\"test\", \"my_model\"], \"unique_id\": \"model.test.my_model\", \"package_name\": \"test\", \"root_path\": \"/Users/jerco/dev/scratch/testy\", \"path\": \"my_model.sql\", \"original_file_path\": \"models/my_model.sql\", \"name\": \"my_model\", \"alias\": \"my_model\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"479636cb85ce8d3b0f8db5ff13cf338b61254ad98d905630eac61f963e719e9d\"}, \"tags\": [], \"refs\": [], \"sources\": [], \"metrics\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"compiled_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {}, \"created_at\": 1663058263.145605}}, \"sources\": {}, \"macros\": {\"macro.dbt_postgres.postgres__get_catalog\": {\"unique_id\": \"macro.dbt_postgres.postgres__get_catalog\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/catalog.sql\", \"original_file_path\": \"macros/catalog.sql\", \"name\": \"postgres__get_catalog\", \"macro_sql\": \"{% macro postgres__get_catalog(information_schema, schemas) -%}\\n\\n  {%- call statement('catalog', fetch_result=True) -%}\\n    {#\\n      If the user has multiple databases set and the first one is wrong, this will fail.\\n      But we won't fail in the case where there are multiple quoting-difference-only dbs, which is better.\\n    #}\\n    {% set database = information_schema.database %}\\n    {{ adapter.verify_database(database) }}\\n\\n    select\\n        '{{ database }}' as table_database,\\n        sch.nspname as table_schema,\\n        tbl.relname as table_name,\\n        case tbl.relkind\\n            when 'v' then 'VIEW'\\n            else 'BASE TABLE'\\n        end as table_type,\\n        tbl_desc.description as table_comment,\\n        col.attname as column_name,\\n        col.attnum as column_index,\\n        pg_catalog.format_type(col.atttypid, col.atttypmod) as column_type,\\n        col_desc.description as column_comment,\\n        pg_get_userbyid(tbl.relowner) as table_owner\\n\\n    from pg_catalog.pg_namespace sch\\n    join pg_catalog.pg_class tbl on tbl.relnamespace = sch.oid\\n    join pg_catalog.pg_attribute col on col.attrelid = tbl.oid\\n    left outer join pg_catalog.pg_description tbl_desc on (tbl_desc.objoid = tbl.oid and tbl_desc.objsubid = 0)\\n    left outer join pg_catalog.pg_description col_desc on (col_desc.objoid = tbl.oid and col_desc.objsubid = col.attnum)\\n\\n    where (\\n        {%- for schema in schemas -%}\\n          upper(sch.nspname) = upper('{{ schema }}'){%- if not loop.last %} or {% endif -%}\\n        {%- endfor -%}\\n      )\\n      and not pg_is_other_temp_schema(sch.oid) -- not a temporary schema belonging to another session\\n      and tbl.relpersistence in ('p', 'u') -- [p]ermanent table or [u]nlogged table. Exclude [t]emporary tables\\n      and tbl.relkind in ('r', 'v', 'f', 'p') -- o[r]dinary table, [v]iew, [f]oreign table, [p]artitioned table. Other values are [i]ndex, [S]equence, [c]omposite type, [t]OAST table, [m]aterialized view\\n      and col.attnum > 0 -- negative numbers are used for system columns such as oid\\n      and not col.attisdropped -- column as not been dropped\\n\\n    order by\\n        sch.nspname,\\n        tbl.relname,\\n        col.attnum\\n\\n  {%- endcall -%}\\n\\n  {{ return(load_result('catalog').table) }}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.441694}, \"macro.dbt_postgres.postgres_get_relations\": {\"unique_id\": \"macro.dbt_postgres.postgres_get_relations\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/relations.sql\", \"original_file_path\": \"macros/relations.sql\", \"name\": \"postgres_get_relations\", \"macro_sql\": \"{% macro postgres_get_relations () -%}\\n\\n  {#\\n      -- in pg_depend, objid is the dependent, refobjid is the referenced object\\n      --  > a pg_depend entry indicates that the referenced object cannot be\\n      --  > dropped without also dropping the dependent object.\\n  #}\\n\\n  {%- call statement('relations', fetch_result=True) -%}\\n    with relation as (\\n        select\\n            pg_rewrite.ev_class as class,\\n            pg_rewrite.oid as id\\n        from pg_rewrite\\n    ),\\n    class as (\\n        select\\n            oid as id,\\n            relname as name,\\n            relnamespace as schema,\\n            relkind as kind\\n        from pg_class\\n    ),\\n    dependency as (\\n        select distinct\\n            pg_depend.objid as id,\\n            pg_depend.refobjid as ref\\n        from pg_depend\\n    ),\\n    schema as (\\n        select\\n            pg_namespace.oid as id,\\n            pg_namespace.nspname as name\\n        from pg_namespace\\n        where nspname != 'information_schema' and nspname not like 'pg\\\\_%'\\n    ),\\n    referenced as (\\n        select\\n            relation.id AS id,\\n            referenced_class.name ,\\n            referenced_class.schema ,\\n            referenced_class.kind\\n        from relation\\n        join class as referenced_class on relation.class=referenced_class.id\\n        where referenced_class.kind in ('r', 'v')\\n    ),\\n    relationships as (\\n        select\\n            referenced.name as referenced_name,\\n            referenced.schema as referenced_schema_id,\\n            dependent_class.name as dependent_name,\\n            dependent_class.schema as dependent_schema_id,\\n            referenced.kind as kind\\n        from referenced\\n        join dependency on referenced.id=dependency.id\\n        join class as dependent_class on dependency.ref=dependent_class.id\\n        where\\n            (referenced.name != dependent_class.name or\\n             referenced.schema != dependent_class.schema)\\n    )\\n\\n    select\\n        referenced_schema.name as referenced_schema,\\n        relationships.referenced_name as referenced_name,\\n        dependent_schema.name as dependent_schema,\\n        relationships.dependent_name as dependent_name\\n    from relationships\\n    join schema as dependent_schema on relationships.dependent_schema_id=dependent_schema.id\\n    join schema as referenced_schema on relationships.referenced_schema_id=referenced_schema.id\\n    group by referenced_schema, referenced_name, dependent_schema, dependent_name\\n    order by referenced_schema, referenced_name, dependent_schema, dependent_name;\\n\\n  {%- endcall -%}\\n\\n  {{ return(load_result('relations').table) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.443508}, \"macro.dbt_postgres.postgres__create_table_as\": {\"unique_id\": \"macro.dbt_postgres.postgres__create_table_as\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__create_table_as\", \"macro_sql\": \"{% macro postgres__create_table_as(temporary, relation, sql) -%}\\n  {%- set unlogged = config.get('unlogged', default=false) -%}\\n  {%- set sql_header = config.get('sql_header', none) -%}\\n\\n  {{ sql_header if sql_header is not none }}\\n\\n  create {% if temporary -%}\\n    temporary\\n  {%- elif unlogged -%}\\n    unlogged\\n  {%- endif %} table {{ relation }}\\n  as (\\n    {{ sql }}\\n  );\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.4609761}, \"macro.dbt_postgres.postgres__get_create_index_sql\": {\"unique_id\": \"macro.dbt_postgres.postgres__get_create_index_sql\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__get_create_index_sql\", \"macro_sql\": \"{% macro postgres__get_create_index_sql(relation, index_dict) -%}\\n  {%- set index_config = adapter.parse_index(index_dict) -%}\\n  {%- set comma_separated_columns = \\\", \\\".join(index_config.columns) -%}\\n  {%- set index_name = index_config.render(relation) -%}\\n\\n  create {% if index_config.unique -%}\\n    unique\\n  {%- endif %} index if not exists\\n  \\\"{{ index_name }}\\\"\\n  on {{ relation }} {% if index_config.type -%}\\n    using {{ index_config.type }}\\n  {%- endif %}\\n  ({{ comma_separated_columns }});\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.462327}, \"macro.dbt_postgres.postgres__create_schema\": {\"unique_id\": \"macro.dbt_postgres.postgres__create_schema\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__create_schema\", \"macro_sql\": \"{% macro postgres__create_schema(relation) -%}\\n  {% if relation.database -%}\\n    {{ adapter.verify_database(relation.database) }}\\n  {%- endif -%}\\n  {%- call statement('create_schema') -%}\\n    create schema if not exists {{ relation.without_identifier().include(database=False) }}\\n  {%- endcall -%}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.4631748}, \"macro.dbt_postgres.postgres__drop_schema\": {\"unique_id\": \"macro.dbt_postgres.postgres__drop_schema\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__drop_schema\", \"macro_sql\": \"{% macro postgres__drop_schema(relation) -%}\\n  {% if relation.database -%}\\n    {{ adapter.verify_database(relation.database) }}\\n  {%- endif -%}\\n  {%- call statement('drop_schema') -%}\\n    drop schema if exists {{ relation.without_identifier().include(database=False) }} cascade\\n  {%- endcall -%}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.46401}, \"macro.dbt_postgres.postgres__get_columns_in_relation\": {\"unique_id\": \"macro.dbt_postgres.postgres__get_columns_in_relation\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__get_columns_in_relation\", \"macro_sql\": \"{% macro postgres__get_columns_in_relation(relation) -%}\\n  {% call statement('get_columns_in_relation', fetch_result=True) %}\\n      select\\n          column_name,\\n          data_type,\\n          character_maximum_length,\\n          numeric_precision,\\n          numeric_scale\\n\\n      from {{ relation.information_schema('columns') }}\\n      where table_name = '{{ relation.identifier }}'\\n        {% if relation.schema %}\\n        and table_schema = '{{ relation.schema }}'\\n        {% endif %}\\n      order by ordinal_position\\n\\n  {% endcall %}\\n  {% set table = load_result('get_columns_in_relation').table %}\\n  {{ return(sql_convert_columns_in_relation(table)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\", \"macro.dbt.sql_convert_columns_in_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.465282}, \"macro.dbt_postgres.postgres__list_relations_without_caching\": {\"unique_id\": \"macro.dbt_postgres.postgres__list_relations_without_caching\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__list_relations_without_caching\", \"macro_sql\": \"{% macro postgres__list_relations_without_caching(schema_relation) %}\\n  {% call statement('list_relations_without_caching', fetch_result=True) -%}\\n    select\\n      '{{ schema_relation.database }}' as database,\\n      tablename as name,\\n      schemaname as schema,\\n      'table' as type\\n    from pg_tables\\n    where schemaname ilike '{{ schema_relation.schema }}'\\n    union all\\n    select\\n      '{{ schema_relation.database }}' as database,\\n      viewname as name,\\n      schemaname as schema,\\n      'view' as type\\n    from pg_views\\n    where schemaname ilike '{{ schema_relation.schema }}'\\n  {% endcall %}\\n  {{ return(load_result('list_relations_without_caching').table) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.46641}, \"macro.dbt_postgres.postgres__information_schema_name\": {\"unique_id\": \"macro.dbt_postgres.postgres__information_schema_name\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__information_schema_name\", \"macro_sql\": \"{% macro postgres__information_schema_name(database) -%}\\n  {% if database_name -%}\\n    {{ adapter.verify_database(database_name) }}\\n  {%- endif -%}\\n  information_schema\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.4668732}, \"macro.dbt_postgres.postgres__list_schemas\": {\"unique_id\": \"macro.dbt_postgres.postgres__list_schemas\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__list_schemas\", \"macro_sql\": \"{% macro postgres__list_schemas(database) %}\\n  {% if database -%}\\n    {{ adapter.verify_database(database) }}\\n  {%- endif -%}\\n  {% call statement('list_schemas', fetch_result=True, auto_begin=False) %}\\n    select distinct nspname from pg_namespace\\n  {% endcall %}\\n  {{ return(load_result('list_schemas').table) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.4678211}, \"macro.dbt_postgres.postgres__check_schema_exists\": {\"unique_id\": \"macro.dbt_postgres.postgres__check_schema_exists\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__check_schema_exists\", \"macro_sql\": \"{% macro postgres__check_schema_exists(information_schema, schema) -%}\\n  {% if information_schema.database -%}\\n    {{ adapter.verify_database(information_schema.database) }}\\n  {%- endif -%}\\n  {% call statement('check_schema_exists', fetch_result=True, auto_begin=False) %}\\n    select count(*) from pg_namespace where nspname = '{{ schema }}'\\n  {% endcall %}\\n  {{ return(load_result('check_schema_exists').table) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.4688902}, \"macro.dbt_postgres.postgres__current_timestamp\": {\"unique_id\": \"macro.dbt_postgres.postgres__current_timestamp\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__current_timestamp\", \"macro_sql\": \"{% macro postgres__current_timestamp() -%}\\n  now()\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.46909}, \"macro.dbt_postgres.postgres__snapshot_string_as_time\": {\"unique_id\": \"macro.dbt_postgres.postgres__snapshot_string_as_time\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__snapshot_string_as_time\", \"macro_sql\": \"{% macro postgres__snapshot_string_as_time(timestamp) -%}\\n    {%- set result = \\\"'\\\" ~ timestamp ~ \\\"'::timestamp without time zone\\\" -%}\\n    {{ return(result) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.469568}, \"macro.dbt_postgres.postgres__snapshot_get_time\": {\"unique_id\": \"macro.dbt_postgres.postgres__snapshot_get_time\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__snapshot_get_time\", \"macro_sql\": \"{% macro postgres__snapshot_get_time() -%}\\n  {{ current_timestamp() }}::timestamp without time zone\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.469843}, \"macro.dbt_postgres.postgres__make_relation_with_suffix\": {\"unique_id\": \"macro.dbt_postgres.postgres__make_relation_with_suffix\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__make_relation_with_suffix\", \"macro_sql\": \"{% macro postgres__make_relation_with_suffix(base_relation, suffix, dstring) %}\\n    {% if dstring %}\\n      {% set dt = modules.datetime.datetime.now() %}\\n      {% set dtstring = dt.strftime(\\\"%H%M%S%f\\\") %}\\n      {% set suffix = suffix ~ dtstring %}\\n    {% endif %}\\n    {% set suffix_length = suffix|length %}\\n    {% set relation_max_name_length = base_relation.relation_max_name_length() %}\\n    {% if suffix_length > relation_max_name_length %}\\n        {% do exceptions.raise_compiler_error('Relation suffix is too long (' ~ suffix_length ~ ' characters). Maximum length is ' ~ relation_max_name_length ~ ' characters.') %}\\n    {% endif %}\\n    {% set identifier = base_relation.identifier[:relation_max_name_length - suffix_length] ~ suffix %}\\n\\n    {{ return(base_relation.incorporate(path={\\\"identifier\\\": identifier })) }}\\n\\n  {% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.472267}, \"macro.dbt_postgres.postgres__make_intermediate_relation\": {\"unique_id\": \"macro.dbt_postgres.postgres__make_intermediate_relation\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__make_intermediate_relation\", \"macro_sql\": \"{% macro postgres__make_intermediate_relation(base_relation, suffix) %}\\n    {{ return(postgres__make_relation_with_suffix(base_relation, suffix, dstring=False)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_relation_with_suffix\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.472806}, \"macro.dbt_postgres.postgres__make_temp_relation\": {\"unique_id\": \"macro.dbt_postgres.postgres__make_temp_relation\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__make_temp_relation\", \"macro_sql\": \"{% macro postgres__make_temp_relation(base_relation, suffix) %}\\n    {% set temp_relation = postgres__make_relation_with_suffix(base_relation, suffix, dstring=True) %}\\n    {{ return(temp_relation.incorporate(path={\\\"schema\\\": none,\\n                                              \\\"database\\\": none})) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_relation_with_suffix\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.473689}, \"macro.dbt_postgres.postgres__make_backup_relation\": {\"unique_id\": \"macro.dbt_postgres.postgres__make_backup_relation\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__make_backup_relation\", \"macro_sql\": \"{% macro postgres__make_backup_relation(base_relation, backup_relation_type, suffix) %}\\n    {% set backup_relation = postgres__make_relation_with_suffix(base_relation, suffix, dstring=False) %}\\n    {{ return(backup_relation.incorporate(type=backup_relation_type)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_relation_with_suffix\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.4744241}, \"macro.dbt_postgres.postgres_escape_comment\": {\"unique_id\": \"macro.dbt_postgres.postgres_escape_comment\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres_escape_comment\", \"macro_sql\": \"{% macro postgres_escape_comment(comment) -%}\\n  {% if comment is not string %}\\n    {% do exceptions.raise_compiler_error('cannot escape a non-string: ' ~ comment) %}\\n  {% endif %}\\n  {%- set magic = '$dbt_comment_literal_block$' -%}\\n  {%- if magic in comment -%}\\n    {%- do exceptions.raise_compiler_error('The string ' ~ magic ~ ' is not allowed in comments.') -%}\\n  {%- endif -%}\\n  {{ magic }}{{ comment }}{{ magic }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.475544}, \"macro.dbt_postgres.postgres__alter_relation_comment\": {\"unique_id\": \"macro.dbt_postgres.postgres__alter_relation_comment\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__alter_relation_comment\", \"macro_sql\": \"{% macro postgres__alter_relation_comment(relation, comment) %}\\n  {% set escaped_comment = postgres_escape_comment(comment) %}\\n  comment on {{ relation.type }} {{ relation }} is {{ escaped_comment }};\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres_escape_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.4761422}, \"macro.dbt_postgres.postgres__alter_column_comment\": {\"unique_id\": \"macro.dbt_postgres.postgres__alter_column_comment\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__alter_column_comment\", \"macro_sql\": \"{% macro postgres__alter_column_comment(relation, column_dict) %}\\n  {% set existing_columns = adapter.get_columns_in_relation(relation) | map(attribute=\\\"name\\\") | list %}\\n  {% for column_name in column_dict if (column_name in existing_columns) %}\\n    {% set comment = column_dict[column_name]['description'] %}\\n    {% set escaped_comment = postgres_escape_comment(comment) %}\\n    comment on column {{ relation }}.{{ adapter.quote(column_name) if column_dict[column_name]['quote'] else column_name }} is {{ escaped_comment }};\\n  {% endfor %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres_escape_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.477773}, \"macro.dbt_postgres.postgres__get_show_grant_sql\": {\"unique_id\": \"macro.dbt_postgres.postgres__get_show_grant_sql\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__get_show_grant_sql\", \"macro_sql\": \"\\n\\n{%- macro postgres__get_show_grant_sql(relation) -%}\\n  select grantee, privilege_type\\n  from {{ relation.information_schema('role_table_grants') }}\\n      where grantor = current_role\\n        and grantee != current_role\\n        and table_schema = '{{ relation.schema }}'\\n        and table_name = '{{ relation.identifier }}'\\n{%- endmacro -%}\\n\\n\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.478305}, \"macro.dbt_postgres.postgres__copy_grants\": {\"unique_id\": \"macro.dbt_postgres.postgres__copy_grants\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__copy_grants\", \"macro_sql\": \"{% macro postgres__copy_grants() %}\\n    {{ return(False) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.478604}, \"macro.dbt_postgres.postgres__snapshot_merge_sql\": {\"unique_id\": \"macro.dbt_postgres.postgres__snapshot_merge_sql\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/materializations/snapshot_merge.sql\", \"original_file_path\": \"macros/materializations/snapshot_merge.sql\", \"name\": \"postgres__snapshot_merge_sql\", \"macro_sql\": \"{% macro postgres__snapshot_merge_sql(target, source, insert_cols) -%}\\n    {%- set insert_cols_csv = insert_cols | join(', ') -%}\\n\\n    update {{ target }}\\n    set dbt_valid_to = DBT_INTERNAL_SOURCE.dbt_valid_to\\n    from {{ source }} as DBT_INTERNAL_SOURCE\\n    where DBT_INTERNAL_SOURCE.dbt_scd_id::text = {{ target }}.dbt_scd_id::text\\n      and DBT_INTERNAL_SOURCE.dbt_change_type::text in ('update'::text, 'delete'::text)\\n      and {{ target }}.dbt_valid_to is null;\\n\\n    insert into {{ target }} ({{ insert_cols_csv }})\\n    select {% for column in insert_cols -%}\\n        DBT_INTERNAL_SOURCE.{{ column }} {%- if not loop.last %}, {%- endif %}\\n    {%- endfor %}\\n    from {{ source }} as DBT_INTERNAL_SOURCE\\n    where DBT_INTERNAL_SOURCE.dbt_change_type::text = 'insert'::text;\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.480701}, \"macro.dbt_postgres.postgres__dateadd\": {\"unique_id\": \"macro.dbt_postgres.postgres__dateadd\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/utils/dateadd.sql\", \"original_file_path\": \"macros/utils/dateadd.sql\", \"name\": \"postgres__dateadd\", \"macro_sql\": \"{% macro postgres__dateadd(datepart, interval, from_date_or_timestamp) %}\\n\\n    {{ from_date_or_timestamp }} + ((interval '1 {{ datepart }}') * ({{ interval }}))\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.481434}, \"macro.dbt_postgres.postgres__listagg\": {\"unique_id\": \"macro.dbt_postgres.postgres__listagg\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/utils/listagg.sql\", \"original_file_path\": \"macros/utils/listagg.sql\", \"name\": \"postgres__listagg\", \"macro_sql\": \"{% macro postgres__listagg(measure, delimiter_text, order_by_clause, limit_num) -%}\\n\\n    {% if limit_num -%}\\n    array_to_string(\\n        (array_agg(\\n            {{ measure }}\\n            {% if order_by_clause -%}\\n            {{ order_by_clause }}\\n            {%- endif %}\\n        ))[1:{{ limit_num }}],\\n        {{ delimiter_text }}\\n        )\\n    {%- else %}\\n    string_agg(\\n        {{ measure }},\\n        {{ delimiter_text }}\\n        {% if order_by_clause -%}\\n        {{ order_by_clause }}\\n        {%- endif %}\\n        )\\n    {%- endif %}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.483254}, \"macro.dbt_postgres.postgres__datediff\": {\"unique_id\": \"macro.dbt_postgres.postgres__datediff\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/utils/datediff.sql\", \"original_file_path\": \"macros/utils/datediff.sql\", \"name\": \"postgres__datediff\", \"macro_sql\": \"{% macro postgres__datediff(first_date, second_date, datepart) -%}\\n\\n    {% if datepart == 'year' %}\\n        (date_part('year', ({{second_date}})::date) - date_part('year', ({{first_date}})::date))\\n    {% elif datepart == 'quarter' %}\\n        ({{ datediff(first_date, second_date, 'year') }} * 4 + date_part('quarter', ({{second_date}})::date) - date_part('quarter', ({{first_date}})::date))\\n    {% elif datepart == 'month' %}\\n        ({{ datediff(first_date, second_date, 'year') }} * 12 + date_part('month', ({{second_date}})::date) - date_part('month', ({{first_date}})::date))\\n    {% elif datepart == 'day' %}\\n        (({{second_date}})::date - ({{first_date}})::date)\\n    {% elif datepart == 'week' %}\\n        ({{ datediff(first_date, second_date, 'day') }} / 7 + case\\n            when date_part('dow', ({{first_date}})::timestamp) <= date_part('dow', ({{second_date}})::timestamp) then\\n                case when {{first_date}} <= {{second_date}} then 0 else -1 end\\n            else\\n                case when {{first_date}} <= {{second_date}} then 1 else 0 end\\n        end)\\n    {% elif datepart == 'hour' %}\\n        ({{ datediff(first_date, second_date, 'day') }} * 24 + date_part('hour', ({{second_date}})::timestamp) - date_part('hour', ({{first_date}})::timestamp))\\n    {% elif datepart == 'minute' %}\\n        ({{ datediff(first_date, second_date, 'hour') }} * 60 + date_part('minute', ({{second_date}})::timestamp) - date_part('minute', ({{first_date}})::timestamp))\\n    {% elif datepart == 'second' %}\\n        ({{ datediff(first_date, second_date, 'minute') }} * 60 + floor(date_part('second', ({{second_date}})::timestamp)) - floor(date_part('second', ({{first_date}})::timestamp)))\\n    {% elif datepart == 'millisecond' %}\\n        ({{ datediff(first_date, second_date, 'minute') }} * 60000 + floor(date_part('millisecond', ({{second_date}})::timestamp)) - floor(date_part('millisecond', ({{first_date}})::timestamp)))\\n    {% elif datepart == 'microsecond' %}\\n        ({{ datediff(first_date, second_date, 'minute') }} * 60000000 + floor(date_part('microsecond', ({{second_date}})::timestamp)) - floor(date_part('microsecond', ({{first_date}})::timestamp)))\\n    {% else %}\\n        {{ exceptions.raise_compiler_error(\\\"Unsupported datepart for macro datediff in postgres: {!r}\\\".format(datepart)) }}\\n    {% endif %}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.datediff\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.492169}, \"macro.dbt_postgres.postgres__any_value\": {\"unique_id\": \"macro.dbt_postgres.postgres__any_value\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/utils/any_value.sql\", \"original_file_path\": \"macros/utils/any_value.sql\", \"name\": \"postgres__any_value\", \"macro_sql\": \"{% macro postgres__any_value(expression) -%}\\n\\n    min({{ expression }})\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.4927092}, \"macro.dbt_postgres.postgres__last_day\": {\"unique_id\": \"macro.dbt_postgres.postgres__last_day\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/utils/last_day.sql\", \"original_file_path\": \"macros/utils/last_day.sql\", \"name\": \"postgres__last_day\", \"macro_sql\": \"{% macro postgres__last_day(date, datepart) -%}\\n\\n    {%- if datepart == 'quarter' -%}\\n    -- postgres dateadd does not support quarter interval.\\n    cast(\\n        {{dbt.dateadd('day', '-1',\\n        dbt.dateadd('month', '3', dbt.date_trunc(datepart, date))\\n        )}}\\n        as date)\\n    {%- else -%}\\n    {{dbt.default_last_day(date, datepart)}}\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.dateadd\", \"macro.dbt.date_trunc\", \"macro.dbt.default_last_day\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.494153}, \"macro.dbt_postgres.postgres__split_part\": {\"unique_id\": \"macro.dbt_postgres.postgres__split_part\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/postgres\", \"path\": \"macros/utils/split_part.sql\", \"original_file_path\": \"macros/utils/split_part.sql\", \"name\": \"postgres__split_part\", \"macro_sql\": \"{% macro postgres__split_part(string_text, delimiter_text, part_number) %}\\n\\n  {% if part_number >= 0 %}\\n    {{ dbt.default__split_part(string_text, delimiter_text, part_number) }}\\n  {% else %}\\n    {{ dbt._split_part_negative(string_text, delimiter_text, part_number) }}\\n  {% endif %}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__split_part\", \"macro.dbt._split_part_negative\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.495394}, \"macro.dbt.run_hooks\": {\"unique_id\": \"macro.dbt.run_hooks\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"name\": \"run_hooks\", \"macro_sql\": \"{% macro run_hooks(hooks, inside_transaction=True) %}\\n  {% for hook in hooks | selectattr('transaction', 'equalto', inside_transaction)  %}\\n    {% if not inside_transaction and loop.first %}\\n      {% call statement(auto_begin=inside_transaction) %}\\n        commit;\\n      {% endcall %}\\n    {% endif %}\\n    {% set rendered = render(hook.get('sql')) | trim %}\\n    {% if (rendered | length) > 0 %}\\n      {% call statement(auto_begin=inside_transaction) %}\\n        {{ rendered }}\\n      {% endcall %}\\n    {% endif %}\\n  {% endfor %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.498407}, \"macro.dbt.make_hook_config\": {\"unique_id\": \"macro.dbt.make_hook_config\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"name\": \"make_hook_config\", \"macro_sql\": \"{% macro make_hook_config(sql, inside_transaction) %}\\n    {{ tojson({\\\"sql\\\": sql, \\\"transaction\\\": inside_transaction}) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.4989262}, \"macro.dbt.before_begin\": {\"unique_id\": \"macro.dbt.before_begin\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"name\": \"before_begin\", \"macro_sql\": \"{% macro before_begin(sql) %}\\n    {{ make_hook_config(sql, inside_transaction=False) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.make_hook_config\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.499295}, \"macro.dbt.in_transaction\": {\"unique_id\": \"macro.dbt.in_transaction\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"name\": \"in_transaction\", \"macro_sql\": \"{% macro in_transaction(sql) %}\\n    {{ make_hook_config(sql, inside_transaction=True) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.make_hook_config\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.4996538}, \"macro.dbt.after_commit\": {\"unique_id\": \"macro.dbt.after_commit\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"name\": \"after_commit\", \"macro_sql\": \"{% macro after_commit(sql) %}\\n    {{ make_hook_config(sql, inside_transaction=False) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.make_hook_config\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.5000162}, \"macro.dbt.set_sql_header\": {\"unique_id\": \"macro.dbt.set_sql_header\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/configs.sql\", \"original_file_path\": \"macros/materializations/configs.sql\", \"name\": \"set_sql_header\", \"macro_sql\": \"{% macro set_sql_header(config) -%}\\n  {{ config.set('sql_header', caller()) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.5011232}, \"macro.dbt.should_full_refresh\": {\"unique_id\": \"macro.dbt.should_full_refresh\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/configs.sql\", \"original_file_path\": \"macros/materializations/configs.sql\", \"name\": \"should_full_refresh\", \"macro_sql\": \"{% macro should_full_refresh() %}\\n  {% set config_full_refresh = config.get('full_refresh') %}\\n  {% if config_full_refresh is none %}\\n    {% set config_full_refresh = flags.FULL_REFRESH %}\\n  {% endif %}\\n  {% do return(config_full_refresh) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.50192}, \"macro.dbt.should_store_failures\": {\"unique_id\": \"macro.dbt.should_store_failures\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/configs.sql\", \"original_file_path\": \"macros/materializations/configs.sql\", \"name\": \"should_store_failures\", \"macro_sql\": \"{% macro should_store_failures() %}\\n  {% set config_store_failures = config.get('store_failures') %}\\n  {% if config_store_failures is none %}\\n    {% set config_store_failures = flags.STORE_FAILURES %}\\n  {% endif %}\\n  {% do return(config_store_failures) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.502719}, \"macro.dbt.snapshot_merge_sql\": {\"unique_id\": \"macro.dbt.snapshot_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/snapshot_merge.sql\", \"original_file_path\": \"macros/materializations/snapshots/snapshot_merge.sql\", \"name\": \"snapshot_merge_sql\", \"macro_sql\": \"{% macro snapshot_merge_sql(target, source, insert_cols) -%}\\n  {{ adapter.dispatch('snapshot_merge_sql', 'dbt')(target, source, insert_cols) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__snapshot_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.50401}, \"macro.dbt.default__snapshot_merge_sql\": {\"unique_id\": \"macro.dbt.default__snapshot_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/snapshot_merge.sql\", \"original_file_path\": \"macros/materializations/snapshots/snapshot_merge.sql\", \"name\": \"default__snapshot_merge_sql\", \"macro_sql\": \"{% macro default__snapshot_merge_sql(target, source, insert_cols) -%}\\n    {%- set insert_cols_csv = insert_cols | join(', ') -%}\\n\\n    merge into {{ target }} as DBT_INTERNAL_DEST\\n    using {{ source }} as DBT_INTERNAL_SOURCE\\n    on DBT_INTERNAL_SOURCE.dbt_scd_id = DBT_INTERNAL_DEST.dbt_scd_id\\n\\n    when matched\\n     and DBT_INTERNAL_DEST.dbt_valid_to is null\\n     and DBT_INTERNAL_SOURCE.dbt_change_type in ('update', 'delete')\\n        then update\\n        set dbt_valid_to = DBT_INTERNAL_SOURCE.dbt_valid_to\\n\\n    when not matched\\n     and DBT_INTERNAL_SOURCE.dbt_change_type = 'insert'\\n        then insert ({{ insert_cols_csv }})\\n        values ({{ insert_cols_csv }})\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.504728}, \"macro.dbt.strategy_dispatch\": {\"unique_id\": \"macro.dbt.strategy_dispatch\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"name\": \"strategy_dispatch\", \"macro_sql\": \"{% macro strategy_dispatch(name) -%}\\n{% set original_name = name %}\\n  {% if '.' in name %}\\n    {% set package_name, name = name.split(\\\".\\\", 1) %}\\n  {% else %}\\n    {% set package_name = none %}\\n  {% endif %}\\n\\n  {% if package_name is none %}\\n    {% set package_context = context %}\\n  {% elif package_name in context %}\\n    {% set package_context = context[package_name] %}\\n  {% else %}\\n    {% set error_msg %}\\n        Could not find package '{{package_name}}', called with '{{original_name}}'\\n    {% endset %}\\n    {{ exceptions.raise_compiler_error(error_msg | trim) }}\\n  {% endif %}\\n\\n  {%- set search_name = 'snapshot_' ~ name ~ '_strategy' -%}\\n\\n  {% if search_name not in package_context %}\\n    {% set error_msg %}\\n        The specified strategy macro '{{name}}' was not found in package '{{ package_name }}'\\n    {% endset %}\\n    {{ exceptions.raise_compiler_error(error_msg | trim) }}\\n  {% endif %}\\n  {{ return(package_context[search_name]) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.51448}, \"macro.dbt.snapshot_hash_arguments\": {\"unique_id\": \"macro.dbt.snapshot_hash_arguments\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"name\": \"snapshot_hash_arguments\", \"macro_sql\": \"{% macro snapshot_hash_arguments(args) -%}\\n  {{ adapter.dispatch('snapshot_hash_arguments', 'dbt')(args) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__snapshot_hash_arguments\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.51492}, \"macro.dbt.default__snapshot_hash_arguments\": {\"unique_id\": \"macro.dbt.default__snapshot_hash_arguments\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"name\": \"default__snapshot_hash_arguments\", \"macro_sql\": \"{% macro default__snapshot_hash_arguments(args) -%}\\n    md5({%- for arg in args -%}\\n        coalesce(cast({{ arg }} as varchar ), '')\\n        {% if not loop.last %} || '|' || {% endif %}\\n    {%- endfor -%})\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.5155}, \"macro.dbt.snapshot_get_time\": {\"unique_id\": \"macro.dbt.snapshot_get_time\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"name\": \"snapshot_get_time\", \"macro_sql\": \"{% macro snapshot_get_time() -%}\\n  {{ adapter.dispatch('snapshot_get_time', 'dbt')() }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__snapshot_get_time\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.515872}, \"macro.dbt.default__snapshot_get_time\": {\"unique_id\": \"macro.dbt.default__snapshot_get_time\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"name\": \"default__snapshot_get_time\", \"macro_sql\": \"{% macro default__snapshot_get_time() -%}\\n  {{ current_timestamp() }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.516114}, \"macro.dbt.snapshot_timestamp_strategy\": {\"unique_id\": \"macro.dbt.snapshot_timestamp_strategy\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"name\": \"snapshot_timestamp_strategy\", \"macro_sql\": \"{% macro snapshot_timestamp_strategy(node, snapshotted_rel, current_rel, config, target_exists) %}\\n    {% set primary_key = config['unique_key'] %}\\n    {% set updated_at = config['updated_at'] %}\\n    {% set invalidate_hard_deletes = config.get('invalidate_hard_deletes', false) %}\\n\\n    {#/*\\n        The snapshot relation might not have an {{ updated_at }} value if the\\n        snapshot strategy is changed from `check` to `timestamp`. We\\n        should use a dbt-created column for the comparison in the snapshot\\n        table instead of assuming that the user-supplied {{ updated_at }}\\n        will be present in the historical data.\\n\\n        See https://github.com/dbt-labs/dbt-core/issues/2350\\n    */ #}\\n    {% set row_changed_expr -%}\\n        ({{ snapshotted_rel }}.dbt_valid_from < {{ current_rel }}.{{ updated_at }})\\n    {%- endset %}\\n\\n    {% set scd_id_expr = snapshot_hash_arguments([primary_key, updated_at]) %}\\n\\n    {% do return({\\n        \\\"unique_key\\\": primary_key,\\n        \\\"updated_at\\\": updated_at,\\n        \\\"row_changed\\\": row_changed_expr,\\n        \\\"scd_id\\\": scd_id_expr,\\n        \\\"invalidate_hard_deletes\\\": invalidate_hard_deletes\\n    }) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.snapshot_hash_arguments\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.518018}, \"macro.dbt.snapshot_string_as_time\": {\"unique_id\": \"macro.dbt.snapshot_string_as_time\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"name\": \"snapshot_string_as_time\", \"macro_sql\": \"{% macro snapshot_string_as_time(timestamp) -%}\\n    {{ adapter.dispatch('snapshot_string_as_time', 'dbt')(timestamp) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__snapshot_string_as_time\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.5184388}, \"macro.dbt.default__snapshot_string_as_time\": {\"unique_id\": \"macro.dbt.default__snapshot_string_as_time\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"name\": \"default__snapshot_string_as_time\", \"macro_sql\": \"{% macro default__snapshot_string_as_time(timestamp) %}\\n    {% do exceptions.raise_not_implemented(\\n        'snapshot_string_as_time macro not implemented for adapter '+adapter.type()\\n    ) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.5188859}, \"macro.dbt.snapshot_check_all_get_existing_columns\": {\"unique_id\": \"macro.dbt.snapshot_check_all_get_existing_columns\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"name\": \"snapshot_check_all_get_existing_columns\", \"macro_sql\": \"{% macro snapshot_check_all_get_existing_columns(node, target_exists, check_cols_config) -%}\\n    {%- if not target_exists -%}\\n        {#-- no table yet -> return whatever the query does --#}\\n        {{ return((false, query_columns)) }}\\n    {%- endif -%}\\n\\n    {#-- handle any schema changes --#}\\n    {%- set target_relation = adapter.get_relation(database=node.database, schema=node.schema, identifier=node.alias) -%}\\n\\n    {% if check_cols_config == 'all' %}\\n        {%- set query_columns = get_columns_in_query(node['compiled_sql']) -%}\\n\\n    {% elif check_cols_config is iterable and (check_cols_config | length) > 0 %}\\n        {#-- query for proper casing/quoting, to support comparison below --#}\\n        {%- set select_check_cols_from_target -%}\\n          select {{ check_cols_config | join(', ') }} from ({{ node['compiled_sql'] }}) subq\\n        {%- endset -%}\\n        {% set query_columns = get_columns_in_query(select_check_cols_from_target) %}\\n\\n    {% else %}\\n        {% do exceptions.raise_compiler_error(\\\"Invalid value for 'check_cols': \\\" ~ check_cols_config) %}\\n    {% endif %}\\n\\n    {%- set existing_cols = adapter.get_columns_in_relation(target_relation) | map(attribute = 'name') | list -%}\\n    {%- set ns = namespace() -%} {#-- handle for-loop scoping with a namespace --#}\\n    {%- set ns.column_added = false -%}\\n\\n    {%- set intersection = [] -%}\\n    {%- for col in query_columns -%}\\n        {%- if col in existing_cols -%}\\n            {%- do intersection.append(adapter.quote(col)) -%}\\n        {%- else -%}\\n            {% set ns.column_added = true %}\\n        {%- endif -%}\\n    {%- endfor -%}\\n    {{ return((ns.column_added, intersection)) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_columns_in_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.522562}, \"macro.dbt.snapshot_check_strategy\": {\"unique_id\": \"macro.dbt.snapshot_check_strategy\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"name\": \"snapshot_check_strategy\", \"macro_sql\": \"{% macro snapshot_check_strategy(node, snapshotted_rel, current_rel, config, target_exists) %}\\n    {% set check_cols_config = config['check_cols'] %}\\n    {% set primary_key = config['unique_key'] %}\\n    {% set invalidate_hard_deletes = config.get('invalidate_hard_deletes', false) %}\\n    {% set updated_at = config.get('updated_at', snapshot_get_time()) %}\\n\\n    {% set column_added = false %}\\n\\n    {% set column_added, check_cols = snapshot_check_all_get_existing_columns(node, target_exists, check_cols_config) %}\\n\\n    {%- set row_changed_expr -%}\\n    (\\n    {%- if column_added -%}\\n        {{ get_true_sql() }}\\n    {%- else -%}\\n    {%- for col in check_cols -%}\\n        {{ snapshotted_rel }}.{{ col }} != {{ current_rel }}.{{ col }}\\n        or\\n        (\\n            (({{ snapshotted_rel }}.{{ col }} is null) and not ({{ current_rel }}.{{ col }} is null))\\n            or\\n            ((not {{ snapshotted_rel }}.{{ col }} is null) and ({{ current_rel }}.{{ col }} is null))\\n        )\\n        {%- if not loop.last %} or {% endif -%}\\n    {%- endfor -%}\\n    {%- endif -%}\\n    )\\n    {%- endset %}\\n\\n    {% set scd_id_expr = snapshot_hash_arguments([primary_key, updated_at]) %}\\n\\n    {% do return({\\n        \\\"unique_key\\\": primary_key,\\n        \\\"updated_at\\\": updated_at,\\n        \\\"row_changed\\\": row_changed_expr,\\n        \\\"scd_id\\\": scd_id_expr,\\n        \\\"invalidate_hard_deletes\\\": invalidate_hard_deletes\\n    }) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.snapshot_get_time\", \"macro.dbt.snapshot_check_all_get_existing_columns\", \"macro.dbt.get_true_sql\", \"macro.dbt.snapshot_hash_arguments\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.526156}, \"macro.dbt.create_columns\": {\"unique_id\": \"macro.dbt.create_columns\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"name\": \"create_columns\", \"macro_sql\": \"{% macro create_columns(relation, columns) %}\\n  {{ adapter.dispatch('create_columns', 'dbt')(relation, columns) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__create_columns\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.53722}, \"macro.dbt.default__create_columns\": {\"unique_id\": \"macro.dbt.default__create_columns\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"name\": \"default__create_columns\", \"macro_sql\": \"{% macro default__create_columns(relation, columns) %}\\n  {% for column in columns %}\\n    {% call statement() %}\\n      alter table {{ relation }} add column \\\"{{ column.name }}\\\" {{ column.data_type }};\\n    {% endcall %}\\n  {% endfor %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.537965}, \"macro.dbt.post_snapshot\": {\"unique_id\": \"macro.dbt.post_snapshot\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"name\": \"post_snapshot\", \"macro_sql\": \"{% macro post_snapshot(staging_relation) %}\\n  {{ adapter.dispatch('post_snapshot', 'dbt')(staging_relation) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__post_snapshot\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.538402}, \"macro.dbt.default__post_snapshot\": {\"unique_id\": \"macro.dbt.default__post_snapshot\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"name\": \"default__post_snapshot\", \"macro_sql\": \"{% macro default__post_snapshot(staging_relation) %}\\n    {# no-op #}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.538624}, \"macro.dbt.get_true_sql\": {\"unique_id\": \"macro.dbt.get_true_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"name\": \"get_true_sql\", \"macro_sql\": \"{% macro get_true_sql() %}\\n  {{ adapter.dispatch('get_true_sql', 'dbt')() }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_true_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.538997}, \"macro.dbt.default__get_true_sql\": {\"unique_id\": \"macro.dbt.default__get_true_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"name\": \"default__get_true_sql\", \"macro_sql\": \"{% macro default__get_true_sql() %}\\n    {{ return('TRUE') }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.539289}, \"macro.dbt.snapshot_staging_table\": {\"unique_id\": \"macro.dbt.snapshot_staging_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"name\": \"snapshot_staging_table\", \"macro_sql\": \"{% macro snapshot_staging_table(strategy, source_sql, target_relation) -%}\\n  {{ adapter.dispatch('snapshot_staging_table', 'dbt')(strategy, source_sql, target_relation) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__snapshot_staging_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.539823}, \"macro.dbt.default__snapshot_staging_table\": {\"unique_id\": \"macro.dbt.default__snapshot_staging_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"name\": \"default__snapshot_staging_table\", \"macro_sql\": \"{% macro default__snapshot_staging_table(strategy, source_sql, target_relation) -%}\\n\\n    with snapshot_query as (\\n\\n        {{ source_sql }}\\n\\n    ),\\n\\n    snapshotted_data as (\\n\\n        select *,\\n            {{ strategy.unique_key }} as dbt_unique_key\\n\\n        from {{ target_relation }}\\n        where dbt_valid_to is null\\n\\n    ),\\n\\n    insertions_source_data as (\\n\\n        select\\n            *,\\n            {{ strategy.unique_key }} as dbt_unique_key,\\n            {{ strategy.updated_at }} as dbt_updated_at,\\n            {{ strategy.updated_at }} as dbt_valid_from,\\n            nullif({{ strategy.updated_at }}, {{ strategy.updated_at }}) as dbt_valid_to,\\n            {{ strategy.scd_id }} as dbt_scd_id\\n\\n        from snapshot_query\\n    ),\\n\\n    updates_source_data as (\\n\\n        select\\n            *,\\n            {{ strategy.unique_key }} as dbt_unique_key,\\n            {{ strategy.updated_at }} as dbt_updated_at,\\n            {{ strategy.updated_at }} as dbt_valid_from,\\n            {{ strategy.updated_at }} as dbt_valid_to\\n\\n        from snapshot_query\\n    ),\\n\\n    {%- if strategy.invalidate_hard_deletes %}\\n\\n    deletes_source_data as (\\n\\n        select\\n            *,\\n            {{ strategy.unique_key }} as dbt_unique_key\\n        from snapshot_query\\n    ),\\n    {% endif %}\\n\\n    insertions as (\\n\\n        select\\n            'insert' as dbt_change_type,\\n            source_data.*\\n\\n        from insertions_source_data as source_data\\n        left outer join snapshotted_data on snapshotted_data.dbt_unique_key = source_data.dbt_unique_key\\n        where snapshotted_data.dbt_unique_key is null\\n           or (\\n                snapshotted_data.dbt_unique_key is not null\\n            and (\\n                {{ strategy.row_changed }}\\n            )\\n        )\\n\\n    ),\\n\\n    updates as (\\n\\n        select\\n            'update' as dbt_change_type,\\n            source_data.*,\\n            snapshotted_data.dbt_scd_id\\n\\n        from updates_source_data as source_data\\n        join snapshotted_data on snapshotted_data.dbt_unique_key = source_data.dbt_unique_key\\n        where (\\n            {{ strategy.row_changed }}\\n        )\\n    )\\n\\n    {%- if strategy.invalidate_hard_deletes -%}\\n    ,\\n\\n    deletes as (\\n\\n        select\\n            'delete' as dbt_change_type,\\n            source_data.*,\\n            {{ snapshot_get_time() }} as dbt_valid_from,\\n            {{ snapshot_get_time() }} as dbt_updated_at,\\n            {{ snapshot_get_time() }} as dbt_valid_to,\\n            snapshotted_data.dbt_scd_id\\n\\n        from snapshotted_data\\n        left join deletes_source_data as source_data on snapshotted_data.dbt_unique_key = source_data.dbt_unique_key\\n        where source_data.dbt_unique_key is null\\n    )\\n    {%- endif %}\\n\\n    select * from insertions\\n    union all\\n    select * from updates\\n    {%- if strategy.invalidate_hard_deletes %}\\n    union all\\n    select * from deletes\\n    {%- endif %}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.snapshot_get_time\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.542159}, \"macro.dbt.build_snapshot_table\": {\"unique_id\": \"macro.dbt.build_snapshot_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"name\": \"build_snapshot_table\", \"macro_sql\": \"{% macro build_snapshot_table(strategy, sql) -%}\\n  {{ adapter.dispatch('build_snapshot_table', 'dbt')(strategy, sql) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__build_snapshot_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.5426402}, \"macro.dbt.default__build_snapshot_table\": {\"unique_id\": \"macro.dbt.default__build_snapshot_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"name\": \"default__build_snapshot_table\", \"macro_sql\": \"{% macro default__build_snapshot_table(strategy, sql) %}\\n\\n    select *,\\n        {{ strategy.scd_id }} as dbt_scd_id,\\n        {{ strategy.updated_at }} as dbt_updated_at,\\n        {{ strategy.updated_at }} as dbt_valid_from,\\n        nullif({{ strategy.updated_at }}, {{ strategy.updated_at }}) as dbt_valid_to\\n    from (\\n        {{ sql }}\\n    ) sbq\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.543298}, \"macro.dbt.build_snapshot_staging_table\": {\"unique_id\": \"macro.dbt.build_snapshot_staging_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"name\": \"build_snapshot_staging_table\", \"macro_sql\": \"{% macro build_snapshot_staging_table(strategy, sql, target_relation) %}\\n    {% set temp_relation = make_temp_relation(target_relation) %}\\n\\n    {% set select = snapshot_staging_table(strategy, sql, target_relation) %}\\n\\n    {% call statement('build_snapshot_staging_relation') %}\\n        {{ create_table_as(True, temp_relation, select) }}\\n    {% endcall %}\\n\\n    {% do return(temp_relation) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.make_temp_relation\", \"macro.dbt.snapshot_staging_table\", \"macro.dbt.statement\", \"macro.dbt.create_table_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.5444548}, \"macro.dbt.materialization_snapshot_default\": {\"unique_id\": \"macro.dbt.materialization_snapshot_default\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/snapshot.sql\", \"original_file_path\": \"macros/materializations/snapshots/snapshot.sql\", \"name\": \"materialization_snapshot_default\", \"macro_sql\": \"{% materialization snapshot, default %}\\n  {%- set config = model['config'] -%}\\n\\n  {%- set target_table = model.get('alias', model.get('name')) -%}\\n\\n  {%- set strategy_name = config.get('strategy') -%}\\n  {%- set unique_key = config.get('unique_key') %}\\n  -- grab current tables grants config for comparision later on\\n  {%- set grant_config = config.get('grants') -%}\\n\\n  {% set target_relation_exists, target_relation = get_or_create_relation(\\n          database=model.database,\\n          schema=model.schema,\\n          identifier=target_table,\\n          type='table') -%}\\n\\n  {%- if not target_relation.is_table -%}\\n    {% do exceptions.relation_wrong_type(target_relation, 'table') %}\\n  {%- endif -%}\\n\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  {% set strategy_macro = strategy_dispatch(strategy_name) %}\\n  {% set strategy = strategy_macro(model, \\\"snapshotted_data\\\", \\\"source_data\\\", config, target_relation_exists) %}\\n\\n  {% if not target_relation_exists %}\\n\\n      {% set build_sql = build_snapshot_table(strategy, model['compiled_sql']) %}\\n      {% set final_sql = create_table_as(False, target_relation, build_sql) %}\\n\\n  {% else %}\\n\\n      {{ adapter.valid_snapshot_target(target_relation) }}\\n\\n      {% set staging_table = build_snapshot_staging_table(strategy, sql, target_relation) %}\\n\\n      -- this may no-op if the database does not require column expansion\\n      {% do adapter.expand_target_column_types(from_relation=staging_table,\\n                                               to_relation=target_relation) %}\\n\\n      {% set missing_columns = adapter.get_missing_columns(staging_table, target_relation)\\n                                   | rejectattr('name', 'equalto', 'dbt_change_type')\\n                                   | rejectattr('name', 'equalto', 'DBT_CHANGE_TYPE')\\n                                   | rejectattr('name', 'equalto', 'dbt_unique_key')\\n                                   | rejectattr('name', 'equalto', 'DBT_UNIQUE_KEY')\\n                                   | list %}\\n\\n      {% do create_columns(target_relation, missing_columns) %}\\n\\n      {% set source_columns = adapter.get_columns_in_relation(staging_table)\\n                                   | rejectattr('name', 'equalto', 'dbt_change_type')\\n                                   | rejectattr('name', 'equalto', 'DBT_CHANGE_TYPE')\\n                                   | rejectattr('name', 'equalto', 'dbt_unique_key')\\n                                   | rejectattr('name', 'equalto', 'DBT_UNIQUE_KEY')\\n                                   | list %}\\n\\n      {% set quoted_source_columns = [] %}\\n      {% for column in source_columns %}\\n        {% do quoted_source_columns.append(adapter.quote(column.name)) %}\\n      {% endfor %}\\n\\n      {% set final_sql = snapshot_merge_sql(\\n            target = target_relation,\\n            source = staging_table,\\n            insert_cols = quoted_source_columns\\n         )\\n      %}\\n\\n  {% endif %}\\n\\n  {% call statement('main') %}\\n      {{ final_sql }}\\n  {% endcall %}\\n\\n  {% set should_revoke = should_revoke(target_relation_exists, full_refresh_mode=False) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {% if not target_relation_exists %}\\n    {% do create_indexes(target_relation) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  {{ adapter.commit() }}\\n\\n  {% if staging_table is defined %}\\n      {% do post_snapshot(staging_table) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{% endmaterialization %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_or_create_relation\", \"macro.dbt.run_hooks\", \"macro.dbt.strategy_dispatch\", \"macro.dbt.build_snapshot_table\", \"macro.dbt.create_table_as\", \"macro.dbt.build_snapshot_staging_table\", \"macro.dbt.create_columns\", \"macro.dbt.snapshot_merge_sql\", \"macro.dbt.statement\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\", \"macro.dbt.persist_docs\", \"macro.dbt.create_indexes\", \"macro.dbt.post_snapshot\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.561558}, \"macro.dbt.materialization_test_default\": {\"unique_id\": \"macro.dbt.materialization_test_default\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/tests/test.sql\", \"original_file_path\": \"macros/materializations/tests/test.sql\", \"name\": \"materialization_test_default\", \"macro_sql\": \"{%- materialization test, default -%}\\n\\n  {% set relations = [] %}\\n\\n  {% if should_store_failures() %}\\n\\n    {% set identifier = model['alias'] %}\\n    {% set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) %}\\n    {% set target_relation = api.Relation.create(\\n        identifier=identifier, schema=schema, database=database, type='table') -%} %}\\n\\n    {% if old_relation %}\\n        {% do adapter.drop_relation(old_relation) %}\\n    {% endif %}\\n\\n    {% call statement(auto_begin=True) %}\\n        {{ create_table_as(False, target_relation, sql) }}\\n    {% endcall %}\\n\\n    {% do relations.append(target_relation) %}\\n\\n    {% set main_sql %}\\n        select *\\n        from {{ target_relation }}\\n    {% endset %}\\n\\n    {{ adapter.commit() }}\\n\\n  {% else %}\\n\\n      {% set main_sql = sql %}\\n\\n  {% endif %}\\n\\n  {% set limit = config.get('limit') %}\\n  {% set fail_calc = config.get('fail_calc') %}\\n  {% set warn_if = config.get('warn_if') %}\\n  {% set error_if = config.get('error_if') %}\\n\\n  {% call statement('main', fetch_result=True) -%}\\n\\n    {{ get_test_sql(main_sql, fail_calc, warn_if, error_if, limit)}}\\n\\n  {%- endcall %}\\n\\n  {{ return({'relations': relations}) }}\\n\\n{%- endmaterialization -%}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.should_store_failures\", \"macro.dbt.statement\", \"macro.dbt.create_table_as\", \"macro.dbt.get_test_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.5671492}, \"macro.dbt.get_test_sql\": {\"unique_id\": \"macro.dbt.get_test_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/tests/helpers.sql\", \"original_file_path\": \"macros/materializations/tests/helpers.sql\", \"name\": \"get_test_sql\", \"macro_sql\": \"{% macro get_test_sql(main_sql, fail_calc, warn_if, error_if, limit) -%}\\n  {{ adapter.dispatch('get_test_sql', 'dbt')(main_sql, fail_calc, warn_if, error_if, limit) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_test_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.5684512}, \"macro.dbt.default__get_test_sql\": {\"unique_id\": \"macro.dbt.default__get_test_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/tests/helpers.sql\", \"original_file_path\": \"macros/materializations/tests/helpers.sql\", \"name\": \"default__get_test_sql\", \"macro_sql\": \"{% macro default__get_test_sql(main_sql, fail_calc, warn_if, error_if, limit) -%}\\n    select\\n      {{ fail_calc }} as failures,\\n      {{ fail_calc }} {{ warn_if }} as should_warn,\\n      {{ fail_calc }} {{ error_if }} as should_error\\n    from (\\n      {{ main_sql }}\\n      {{ \\\"limit \\\" ~ limit if limit != none }}\\n    ) dbt_internal_test\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.569262}, \"macro.dbt.get_where_subquery\": {\"unique_id\": \"macro.dbt.get_where_subquery\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/tests/where_subquery.sql\", \"original_file_path\": \"macros/materializations/tests/where_subquery.sql\", \"name\": \"get_where_subquery\", \"macro_sql\": \"{% macro get_where_subquery(relation) -%}\\n    {% do return(adapter.dispatch('get_where_subquery', 'dbt')(relation)) %}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_where_subquery\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.570368}, \"macro.dbt.default__get_where_subquery\": {\"unique_id\": \"macro.dbt.default__get_where_subquery\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/tests/where_subquery.sql\", \"original_file_path\": \"macros/materializations/tests/where_subquery.sql\", \"name\": \"default__get_where_subquery\", \"macro_sql\": \"{% macro default__get_where_subquery(relation) -%}\\n    {% set where = config.get('where', '') %}\\n    {% if where %}\\n        {%- set filtered -%}\\n            (select * from {{ relation }} where {{ where }}) dbt_subquery\\n        {%- endset -%}\\n        {% do return(filtered) %}\\n    {%- else -%}\\n        {% do return(relation) %}\\n    {%- endif -%}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.5713542}, \"macro.dbt.get_quoted_csv\": {\"unique_id\": \"macro.dbt.get_quoted_csv\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"name\": \"get_quoted_csv\", \"macro_sql\": \"{% macro get_quoted_csv(column_names) %}\\n\\n    {% set quoted = [] %}\\n    {% for col in column_names -%}\\n        {%- do quoted.append(adapter.quote(col)) -%}\\n    {%- endfor %}\\n\\n    {%- set dest_cols_csv = quoted | join(', ') -%}\\n    {{ return(dest_cols_csv) }}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.5735822}, \"macro.dbt.diff_columns\": {\"unique_id\": \"macro.dbt.diff_columns\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"name\": \"diff_columns\", \"macro_sql\": \"{% macro diff_columns(source_columns, target_columns) %}\\n\\n  {% set result = [] %}\\n  {% set source_names = source_columns | map(attribute = 'column') | list %}\\n  {% set target_names = target_columns | map(attribute = 'column') | list %}\\n\\n   {# --check whether the name attribute exists in the target - this does not perform a data type check #}\\n   {% for sc in source_columns %}\\n     {% if sc.name not in target_names %}\\n        {{ result.append(sc) }}\\n     {% endif %}\\n   {% endfor %}\\n\\n  {{ return(result) }}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.5750248}, \"macro.dbt.diff_column_data_types\": {\"unique_id\": \"macro.dbt.diff_column_data_types\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"name\": \"diff_column_data_types\", \"macro_sql\": \"{% macro diff_column_data_types(source_columns, target_columns) %}\\n\\n  {% set result = [] %}\\n  {% for sc in source_columns %}\\n    {% set tc = target_columns | selectattr(\\\"name\\\", \\\"equalto\\\", sc.name) | list | first %}\\n    {% if tc %}\\n      {% if sc.data_type != tc.data_type %}\\n        {{ result.append( { 'column_name': tc.name, 'new_type': sc.data_type } ) }}\\n      {% endif %}\\n    {% endif %}\\n  {% endfor %}\\n\\n  {{ return(result) }}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.576639}, \"macro.dbt.get_merge_sql\": {\"unique_id\": \"macro.dbt.get_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"name\": \"get_merge_sql\", \"macro_sql\": \"{% macro get_merge_sql(target, source, unique_key, dest_columns, predicates=none) -%}\\n  {{ adapter.dispatch('get_merge_sql', 'dbt')(target, source, unique_key, dest_columns, predicates) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.591182}, \"macro.dbt.default__get_merge_sql\": {\"unique_id\": \"macro.dbt.default__get_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"name\": \"default__get_merge_sql\", \"macro_sql\": \"{% macro default__get_merge_sql(target, source, unique_key, dest_columns, predicates) -%}\\n    {%- set predicates = [] if predicates is none else [] + predicates -%}\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n    {%- set update_columns = config.get('merge_update_columns', default = dest_columns | map(attribute=\\\"quoted\\\") | list) -%}\\n    {%- set sql_header = config.get('sql_header', none) -%}\\n\\n    {% if unique_key %}\\n        {% if unique_key is sequence and unique_key is not mapping and unique_key is not string %}\\n            {% for key in unique_key %}\\n                {% set this_key_match %}\\n                    DBT_INTERNAL_SOURCE.{{ key }} = DBT_INTERNAL_DEST.{{ key }}\\n                {% endset %}\\n                {% do predicates.append(this_key_match) %}\\n            {% endfor %}\\n        {% else %}\\n            {% set unique_key_match %}\\n                DBT_INTERNAL_SOURCE.{{ unique_key }} = DBT_INTERNAL_DEST.{{ unique_key }}\\n            {% endset %}\\n            {% do predicates.append(unique_key_match) %}\\n        {% endif %}\\n    {% else %}\\n        {% do predicates.append('FALSE') %}\\n    {% endif %}\\n\\n    {{ sql_header if sql_header is not none }}\\n\\n    merge into {{ target }} as DBT_INTERNAL_DEST\\n        using {{ source }} as DBT_INTERNAL_SOURCE\\n        on {{ predicates | join(' and ') }}\\n\\n    {% if unique_key %}\\n    when matched then update set\\n        {% for column_name in update_columns -%}\\n            {{ column_name }} = DBT_INTERNAL_SOURCE.{{ column_name }}\\n            {%- if not loop.last %}, {%- endif %}\\n        {%- endfor %}\\n    {% endif %}\\n\\n    when not matched then insert\\n        ({{ dest_cols_csv }})\\n    values\\n        ({{ dest_cols_csv }})\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_quoted_csv\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.595134}, \"macro.dbt.get_delete_insert_merge_sql\": {\"unique_id\": \"macro.dbt.get_delete_insert_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"name\": \"get_delete_insert_merge_sql\", \"macro_sql\": \"{% macro get_delete_insert_merge_sql(target, source, unique_key, dest_columns) -%}\\n  {{ adapter.dispatch('get_delete_insert_merge_sql', 'dbt')(target, source, unique_key, dest_columns) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_delete_insert_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.622782}, \"macro.dbt.default__get_delete_insert_merge_sql\": {\"unique_id\": \"macro.dbt.default__get_delete_insert_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"name\": \"default__get_delete_insert_merge_sql\", \"macro_sql\": \"{% macro default__get_delete_insert_merge_sql(target, source, unique_key, dest_columns) -%}\\n\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n\\n    {% if unique_key %}\\n        {% if unique_key is sequence and unique_key is not string %}\\n            delete from {{target }}\\n            using {{ source }}\\n            where (\\n                {% for key in unique_key %}\\n                    {{ source }}.{{ key }} = {{ target }}.{{ key }}\\n                    {{ \\\"and \\\" if not loop.last }}\\n                {% endfor %}\\n            );\\n        {% else %}\\n            delete from {{ target }}\\n            where (\\n                {{ unique_key }}) in (\\n                select ({{ unique_key }})\\n                from {{ source }}\\n            );\\n\\n        {% endif %}\\n        {% endif %}\\n\\n    insert into {{ target }} ({{ dest_cols_csv }})\\n    (\\n        select {{ dest_cols_csv }}\\n        from {{ source }}\\n    )\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_quoted_csv\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.624852}, \"macro.dbt.get_insert_overwrite_merge_sql\": {\"unique_id\": \"macro.dbt.get_insert_overwrite_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"name\": \"get_insert_overwrite_merge_sql\", \"macro_sql\": \"{% macro get_insert_overwrite_merge_sql(target, source, dest_columns, predicates, include_sql_header=false) -%}\\n  {{ adapter.dispatch('get_insert_overwrite_merge_sql', 'dbt')(target, source, dest_columns, predicates, include_sql_header) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_insert_overwrite_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.625576}, \"macro.dbt.default__get_insert_overwrite_merge_sql\": {\"unique_id\": \"macro.dbt.default__get_insert_overwrite_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"name\": \"default__get_insert_overwrite_merge_sql\", \"macro_sql\": \"{% macro default__get_insert_overwrite_merge_sql(target, source, dest_columns, predicates, include_sql_header) -%}\\n    {%- set predicates = [] if predicates is none else [] + predicates -%}\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n    {%- set sql_header = config.get('sql_header', none) -%}\\n\\n    {{ sql_header if sql_header is not none and include_sql_header }}\\n\\n    merge into {{ target }} as DBT_INTERNAL_DEST\\n        using {{ source }} as DBT_INTERNAL_SOURCE\\n        on FALSE\\n\\n    when not matched by source\\n        {% if predicates %} and {{ predicates | join(' and ') }} {% endif %}\\n        then delete\\n\\n    when not matched then insert\\n        ({{ dest_cols_csv }})\\n    values\\n        ({{ dest_cols_csv }})\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_quoted_csv\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.627269}, \"macro.dbt.is_incremental\": {\"unique_id\": \"macro.dbt.is_incremental\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/is_incremental.sql\", \"original_file_path\": \"macros/materializations/models/incremental/is_incremental.sql\", \"name\": \"is_incremental\", \"macro_sql\": \"{% macro is_incremental() %}\\n    {#-- do not run introspective queries in parsing #}\\n    {% if not execute %}\\n        {{ return(False) }}\\n    {% else %}\\n        {% set relation = adapter.get_relation(this.database, this.schema, this.table) %}\\n        {{ return(relation is not none\\n                  and relation.type == 'table'\\n                  and model.config.materialized == 'incremental'\\n                  and not should_full_refresh()) }}\\n    {% endif %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.should_full_refresh\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.6292028}, \"macro.dbt.materialization_incremental_default\": {\"unique_id\": \"macro.dbt.materialization_incremental_default\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/incremental.sql\", \"original_file_path\": \"macros/materializations/models/incremental/incremental.sql\", \"name\": \"materialization_incremental_default\", \"macro_sql\": \"{% materialization incremental, default -%}\\n\\n  -- relations\\n  {%- set existing_relation = load_cached_relation(this) -%}\\n  {%- set target_relation = this.incorporate(type='table') -%}\\n  {%- set temp_relation = make_temp_relation(target_relation)-%}\\n  {%- set intermediate_relation = make_intermediate_relation(target_relation)-%}\\n  {%- set backup_relation_type = 'table' if existing_relation is none else existing_relation.type -%}\\n  {%- set backup_relation = make_backup_relation(target_relation, backup_relation_type) -%}\\n\\n  -- configs\\n  {%- set unique_key = config.get('unique_key') -%}\\n  {%- set full_refresh_mode = (should_full_refresh()  or existing_relation.is_view) -%}\\n  {%- set on_schema_change = incremental_validate_on_schema_change(config.get('on_schema_change'), default='ignore') -%}\\n\\n  -- the temp_ and backup_ relations should not already exist in the database; get_relation\\n  -- will return None in that case. Otherwise, we get a relation that we can drop\\n  -- later, before we try to use this name for the current operation. This has to happen before\\n  -- BEGIN, in a separate transaction\\n  {%- set preexisting_intermediate_relation = load_cached_relation(intermediate_relation)-%}\\n  {%- set preexisting_backup_relation = load_cached_relation(backup_relation) -%}\\n   -- grab current tables grants config for comparision later on\\n  {% set grant_config = config.get('grants') %}\\n  {{ drop_relation_if_exists(preexisting_intermediate_relation) }}\\n  {{ drop_relation_if_exists(preexisting_backup_relation) }}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  {% set to_drop = [] %}\\n\\n  {% if existing_relation is none %}\\n      {% set build_sql = get_create_table_as_sql(False, target_relation, sql) %}\\n  {% elif full_refresh_mode %}\\n      {% set build_sql = get_create_table_as_sql(False, intermediate_relation, sql) %}\\n      {% set need_swap = true %}\\n  {% else %}\\n    {% do run_query(get_create_table_as_sql(True, temp_relation, sql)) %}\\n    {% do adapter.expand_target_column_types(\\n             from_relation=temp_relation,\\n             to_relation=target_relation) %}\\n    {#-- Process schema changes. Returns dict of changes if successful. Use source columns for upserting/merging --#}\\n    {% set dest_columns = process_schema_changes(on_schema_change, temp_relation, existing_relation) %}\\n    {% if not dest_columns %}\\n      {% set dest_columns = adapter.get_columns_in_relation(existing_relation) %}\\n    {% endif %}\\n    {% set build_sql = get_delete_insert_merge_sql(target_relation, temp_relation, unique_key, dest_columns) %}\\n\\n  {% endif %}\\n\\n  {% call statement(\\\"main\\\") %}\\n      {{ build_sql }}\\n  {% endcall %}\\n\\n  {% if need_swap %}\\n      {% do adapter.rename_relation(target_relation, backup_relation) %}\\n      {% do adapter.rename_relation(intermediate_relation, target_relation) %}\\n      {% do to_drop.append(backup_relation) %}\\n  {% endif %}\\n\\n  {% set should_revoke = should_revoke(existing_relation, full_refresh_mode) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {% if existing_relation is none or existing_relation.is_view or should_full_refresh() %}\\n    {% do create_indexes(target_relation) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  -- `COMMIT` happens here\\n  {% do adapter.commit() %}\\n\\n  {% for rel in to_drop %}\\n      {% do adapter.drop_relation(rel) %}\\n  {% endfor %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{%- endmaterialization %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.load_cached_relation\", \"macro.dbt.make_temp_relation\", \"macro.dbt.make_intermediate_relation\", \"macro.dbt.make_backup_relation\", \"macro.dbt.should_full_refresh\", \"macro.dbt.incremental_validate_on_schema_change\", \"macro.dbt.drop_relation_if_exists\", \"macro.dbt.run_hooks\", \"macro.dbt.get_create_table_as_sql\", \"macro.dbt.run_query\", \"macro.dbt.process_schema_changes\", \"macro.dbt.get_delete_insert_merge_sql\", \"macro.dbt.statement\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\", \"macro.dbt.persist_docs\", \"macro.dbt.create_indexes\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.6413598}, \"macro.dbt.incremental_validate_on_schema_change\": {\"unique_id\": \"macro.dbt.incremental_validate_on_schema_change\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"original_file_path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"name\": \"incremental_validate_on_schema_change\", \"macro_sql\": \"{% macro incremental_validate_on_schema_change(on_schema_change, default='ignore') %}\\n\\n   {% if on_schema_change not in ['sync_all_columns', 'append_new_columns', 'fail', 'ignore'] %}\\n\\n     {% set log_message = 'Invalid value for on_schema_change (%s) specified. Setting default value of %s.' % (on_schema_change, default) %}\\n     {% do log(log_message) %}\\n\\n     {{ return(default) }}\\n\\n   {% else %}\\n\\n     {{ return(on_schema_change) }}\\n\\n   {% endif %}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.654586}, \"macro.dbt.check_for_schema_changes\": {\"unique_id\": \"macro.dbt.check_for_schema_changes\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"original_file_path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"name\": \"check_for_schema_changes\", \"macro_sql\": \"{% macro check_for_schema_changes(source_relation, target_relation) %}\\n\\n  {% set schema_changed = False %}\\n\\n  {%- set source_columns = adapter.get_columns_in_relation(source_relation) -%}\\n  {%- set target_columns = adapter.get_columns_in_relation(target_relation) -%}\\n  {%- set source_not_in_target = diff_columns(source_columns, target_columns) -%}\\n  {%- set target_not_in_source = diff_columns(target_columns, source_columns) -%}\\n\\n  {% set new_target_types = diff_column_data_types(source_columns, target_columns) %}\\n\\n  {% if source_not_in_target != [] %}\\n    {% set schema_changed = True %}\\n  {% elif target_not_in_source != [] or new_target_types != [] %}\\n    {% set schema_changed = True %}\\n  {% elif new_target_types != [] %}\\n    {% set schema_changed = True %}\\n  {% endif %}\\n\\n  {% set changes_dict = {\\n    'schema_changed': schema_changed,\\n    'source_not_in_target': source_not_in_target,\\n    'target_not_in_source': target_not_in_source,\\n    'source_columns': source_columns,\\n    'target_columns': target_columns,\\n    'new_target_types': new_target_types\\n  } %}\\n\\n  {% set msg %}\\n    In {{ target_relation }}:\\n        Schema changed: {{ schema_changed }}\\n        Source columns not in target: {{ source_not_in_target }}\\n        Target columns not in source: {{ target_not_in_source }}\\n        New column types: {{ new_target_types }}\\n  {% endset %}\\n\\n  {% do log(msg) %}\\n\\n  {{ return(changes_dict) }}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.diff_columns\", \"macro.dbt.diff_column_data_types\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.6579268}, \"macro.dbt.sync_column_schemas\": {\"unique_id\": \"macro.dbt.sync_column_schemas\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"original_file_path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"name\": \"sync_column_schemas\", \"macro_sql\": \"{% macro sync_column_schemas(on_schema_change, target_relation, schema_changes_dict) %}\\n\\n  {%- set add_to_target_arr = schema_changes_dict['source_not_in_target'] -%}\\n\\n  {%- if on_schema_change == 'append_new_columns'-%}\\n     {%- if add_to_target_arr | length > 0 -%}\\n       {%- do alter_relation_add_remove_columns(target_relation, add_to_target_arr, none) -%}\\n     {%- endif -%}\\n\\n  {% elif on_schema_change == 'sync_all_columns' %}\\n     {%- set remove_from_target_arr = schema_changes_dict['target_not_in_source'] -%}\\n     {%- set new_target_types = schema_changes_dict['new_target_types'] -%}\\n\\n     {% if add_to_target_arr | length > 0 or remove_from_target_arr | length > 0 %}\\n       {%- do alter_relation_add_remove_columns(target_relation, add_to_target_arr, remove_from_target_arr) -%}\\n     {% endif %}\\n\\n     {% if new_target_types != [] %}\\n       {% for ntt in new_target_types %}\\n         {% set column_name = ntt['column_name'] %}\\n         {% set new_type = ntt['new_type'] %}\\n         {% do alter_column_type(target_relation, column_name, new_type) %}\\n       {% endfor %}\\n     {% endif %}\\n\\n  {% endif %}\\n\\n  {% set schema_change_message %}\\n    In {{ target_relation }}:\\n        Schema change approach: {{ on_schema_change }}\\n        Columns added: {{ add_to_target_arr }}\\n        Columns removed: {{ remove_from_target_arr }}\\n        Data types changed: {{ new_target_types }}\\n  {% endset %}\\n\\n  {% do log(schema_change_message) %}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.alter_relation_add_remove_columns\", \"macro.dbt.alter_column_type\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.6611688}, \"macro.dbt.process_schema_changes\": {\"unique_id\": \"macro.dbt.process_schema_changes\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"original_file_path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"name\": \"process_schema_changes\", \"macro_sql\": \"{% macro process_schema_changes(on_schema_change, source_relation, target_relation) %}\\n\\n    {% if on_schema_change == 'ignore' %}\\n\\n     {{ return({}) }}\\n\\n    {% else %}\\n\\n      {% set schema_changes_dict = check_for_schema_changes(source_relation, target_relation) %}\\n\\n      {% if schema_changes_dict['schema_changed'] %}\\n\\n        {% if on_schema_change == 'fail' %}\\n\\n          {% set fail_msg %}\\n              The source and target schemas on this incremental model are out of sync!\\n              They can be reconciled in several ways:\\n                - set the `on_schema_change` config to either append_new_columns or sync_all_columns, depending on your situation.\\n                - Re-run the incremental model with `full_refresh: True` to update the target schema.\\n                - update the schema manually and re-run the process.\\n          {% endset %}\\n\\n          {% do exceptions.raise_compiler_error(fail_msg) %}\\n\\n        {# -- unless we ignore, run the sync operation per the config #}\\n        {% else %}\\n\\n          {% do sync_column_schemas(on_schema_change, target_relation, schema_changes_dict) %}\\n\\n        {% endif %}\\n\\n      {% endif %}\\n\\n      {{ return(schema_changes_dict['source_columns']) }}\\n\\n    {% endif %}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.check_for_schema_changes\", \"macro.dbt.sync_column_schemas\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.663094}, \"macro.dbt.materialization_table_default\": {\"unique_id\": \"macro.dbt.materialization_table_default\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/table/table.sql\", \"original_file_path\": \"macros/materializations/models/table/table.sql\", \"name\": \"materialization_table_default\", \"macro_sql\": \"{% materialization table, default %}\\n\\n  {%- set existing_relation = load_cached_relation(this) -%}\\n  {%- set target_relation = this.incorporate(type='table') %}\\n  {%- set intermediate_relation =  make_intermediate_relation(target_relation) -%}\\n  -- the intermediate_relation should not already exist in the database; get_relation\\n  -- will return None in that case. Otherwise, we get a relation that we can drop\\n  -- later, before we try to use this name for the current operation\\n  {%- set preexisting_intermediate_relation = load_cached_relation(intermediate_relation) -%}\\n  /*\\n      See ../view/view.sql for more information about this relation.\\n  */\\n  {%- set backup_relation_type = 'table' if existing_relation is none else existing_relation.type -%}\\n  {%- set backup_relation = make_backup_relation(target_relation, backup_relation_type) -%}\\n  -- as above, the backup_relation should not already exist\\n  {%- set preexisting_backup_relation = load_cached_relation(backup_relation) -%}\\n  -- grab current tables grants config for comparision later on\\n  {% set grant_config = config.get('grants') %}\\n\\n  -- drop the temp relations if they exist already in the database\\n  {{ drop_relation_if_exists(preexisting_intermediate_relation) }}\\n  {{ drop_relation_if_exists(preexisting_backup_relation) }}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  -- build model\\n  {% call statement('main') -%}\\n    {{ get_create_table_as_sql(False, intermediate_relation, sql) }}\\n  {%- endcall %}\\n\\n  -- cleanup\\n  {% if existing_relation is not none %}\\n      {{ adapter.rename_relation(existing_relation, backup_relation) }}\\n  {% endif %}\\n\\n  {{ adapter.rename_relation(intermediate_relation, target_relation) }}\\n\\n  {% do create_indexes(target_relation) %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  {% set should_revoke = should_revoke(existing_relation, full_refresh_mode=True) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  -- `COMMIT` happens here\\n  {{ adapter.commit() }}\\n\\n  -- finally, drop the existing/backup relation after the commit\\n  {{ drop_relation_if_exists(backup_relation) }}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n{% endmaterialization %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.load_cached_relation\", \"macro.dbt.make_intermediate_relation\", \"macro.dbt.make_backup_relation\", \"macro.dbt.drop_relation_if_exists\", \"macro.dbt.run_hooks\", \"macro.dbt.statement\", \"macro.dbt.get_create_table_as_sql\", \"macro.dbt.create_indexes\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\", \"macro.dbt.persist_docs\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.670167}, \"macro.dbt.get_create_table_as_sql\": {\"unique_id\": \"macro.dbt.get_create_table_as_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/table/create_table_as.sql\", \"original_file_path\": \"macros/materializations/models/table/create_table_as.sql\", \"name\": \"get_create_table_as_sql\", \"macro_sql\": \"{% macro get_create_table_as_sql(temporary, relation, sql) -%}\\n  {{ adapter.dispatch('get_create_table_as_sql', 'dbt')(temporary, relation, sql) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_create_table_as_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.6714208}, \"macro.dbt.default__get_create_table_as_sql\": {\"unique_id\": \"macro.dbt.default__get_create_table_as_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/table/create_table_as.sql\", \"original_file_path\": \"macros/materializations/models/table/create_table_as.sql\", \"name\": \"default__get_create_table_as_sql\", \"macro_sql\": \"{% macro default__get_create_table_as_sql(temporary, relation, sql) -%}\\n  {{ return(create_table_as(temporary, relation, sql)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.create_table_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.671903}, \"macro.dbt.create_table_as\": {\"unique_id\": \"macro.dbt.create_table_as\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/table/create_table_as.sql\", \"original_file_path\": \"macros/materializations/models/table/create_table_as.sql\", \"name\": \"create_table_as\", \"macro_sql\": \"{% macro create_table_as(temporary, relation, sql) -%}\\n  {{ adapter.dispatch('create_table_as', 'dbt')(temporary, relation, sql) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__create_table_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.67243}, \"macro.dbt.default__create_table_as\": {\"unique_id\": \"macro.dbt.default__create_table_as\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/table/create_table_as.sql\", \"original_file_path\": \"macros/materializations/models/table/create_table_as.sql\", \"name\": \"default__create_table_as\", \"macro_sql\": \"{% macro default__create_table_as(temporary, relation, sql) -%}\\n  {%- set sql_header = config.get('sql_header', none) -%}\\n\\n  {{ sql_header if sql_header is not none }}\\n\\n  create {% if temporary: -%}temporary{%- endif %} table\\n    {{ relation.include(database=(not temporary), schema=(not temporary)) }}\\n  as (\\n    {{ sql }}\\n  );\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.673532}, \"macro.dbt.materialization_view_default\": {\"unique_id\": \"macro.dbt.materialization_view_default\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/view/view.sql\", \"original_file_path\": \"macros/materializations/models/view/view.sql\", \"name\": \"materialization_view_default\", \"macro_sql\": \"{%- materialization view, default -%}\\n\\n  {%- set existing_relation = load_cached_relation(this) -%}\\n  {%- set target_relation = this.incorporate(type='view') -%}\\n  {%- set intermediate_relation =  make_intermediate_relation(target_relation) -%}\\n\\n  -- the intermediate_relation should not already exist in the database; get_relation\\n  -- will return None in that case. Otherwise, we get a relation that we can drop\\n  -- later, before we try to use this name for the current operation\\n  {%- set preexisting_intermediate_relation = load_cached_relation(intermediate_relation) -%}\\n  /*\\n     This relation (probably) doesn't exist yet. If it does exist, it's a leftover from\\n     a previous run, and we're going to try to drop it immediately. At the end of this\\n     materialization, we're going to rename the \\\"existing_relation\\\" to this identifier,\\n     and then we're going to drop it. In order to make sure we run the correct one of:\\n       - drop view ...\\n       - drop table ...\\n\\n     We need to set the type of this relation to be the type of the existing_relation, if it exists,\\n     or else \\\"view\\\" as a sane default if it does not. Note that if the existing_relation does not\\n     exist, then there is nothing to move out of the way and subsequentally drop. In that case,\\n     this relation will be effectively unused.\\n  */\\n  {%- set backup_relation_type = 'view' if existing_relation is none else existing_relation.type -%}\\n  {%- set backup_relation = make_backup_relation(target_relation, backup_relation_type) -%}\\n  -- as above, the backup_relation should not already exist\\n  {%- set preexisting_backup_relation = load_cached_relation(backup_relation) -%}\\n  -- grab current tables grants config for comparision later on\\n  {% set grant_config = config.get('grants') %}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- drop the temp relations if they exist already in the database\\n  {{ drop_relation_if_exists(preexisting_intermediate_relation) }}\\n  {{ drop_relation_if_exists(preexisting_backup_relation) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  -- build model\\n  {% call statement('main') -%}\\n    {{ get_create_view_as_sql(intermediate_relation, sql) }}\\n  {%- endcall %}\\n\\n  -- cleanup\\n  -- move the existing view out of the way\\n  {% if existing_relation is not none %}\\n    {{ adapter.rename_relation(existing_relation, backup_relation) }}\\n  {% endif %}\\n  {{ adapter.rename_relation(intermediate_relation, target_relation) }}\\n\\n  {% set should_revoke = should_revoke(existing_relation, full_refresh_mode=True) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  {{ adapter.commit() }}\\n\\n  {{ drop_relation_if_exists(backup_relation) }}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{%- endmaterialization -%}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.load_cached_relation\", \"macro.dbt.make_intermediate_relation\", \"macro.dbt.make_backup_relation\", \"macro.dbt.run_hooks\", \"macro.dbt.drop_relation_if_exists\", \"macro.dbt.statement\", \"macro.dbt.get_create_view_as_sql\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\", \"macro.dbt.persist_docs\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.680615}, \"macro.dbt.handle_existing_table\": {\"unique_id\": \"macro.dbt.handle_existing_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/view/helpers.sql\", \"original_file_path\": \"macros/materializations/models/view/helpers.sql\", \"name\": \"handle_existing_table\", \"macro_sql\": \"{% macro handle_existing_table(full_refresh, old_relation) %}\\n    {{ adapter.dispatch('handle_existing_table', 'dbt')(full_refresh, old_relation) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__handle_existing_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.6815622}, \"macro.dbt.default__handle_existing_table\": {\"unique_id\": \"macro.dbt.default__handle_existing_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/view/helpers.sql\", \"original_file_path\": \"macros/materializations/models/view/helpers.sql\", \"name\": \"default__handle_existing_table\", \"macro_sql\": \"{% macro default__handle_existing_table(full_refresh, old_relation) %}\\n    {{ log(\\\"Dropping relation \\\" ~ old_relation ~ \\\" because it is of type \\\" ~ old_relation.type) }}\\n    {{ adapter.drop_relation(old_relation) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.682152}, \"macro.dbt.create_or_replace_view\": {\"unique_id\": \"macro.dbt.create_or_replace_view\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/view/create_or_replace_view.sql\", \"original_file_path\": \"macros/materializations/models/view/create_or_replace_view.sql\", \"name\": \"create_or_replace_view\", \"macro_sql\": \"{% macro create_or_replace_view() %}\\n  {%- set identifier = model['alias'] -%}\\n\\n  {%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%}\\n  {%- set exists_as_view = (old_relation is not none and old_relation.is_view) -%}\\n\\n  {%- set target_relation = api.Relation.create(\\n      identifier=identifier, schema=schema, database=database,\\n      type='view') -%}\\n  {% set grant_config = config.get('grants') %}\\n\\n  {{ run_hooks(pre_hooks) }}\\n\\n  -- If there's a table with the same name and we weren't told to full refresh,\\n  -- that's an error. If we were told to full refresh, drop it. This behavior differs\\n  -- for Snowflake and BigQuery, so multiple dispatch is used.\\n  {%- if old_relation is not none and old_relation.is_table -%}\\n    {{ handle_existing_table(should_full_refresh(), old_relation) }}\\n  {%- endif -%}\\n\\n  -- build model\\n  {% call statement('main') -%}\\n    {{ get_create_view_as_sql(target_relation, sql) }}\\n  {%- endcall %}\\n\\n  {% set should_revoke = should_revoke(exists_as_view, full_refresh_mode=True) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=True) %}\\n\\n  {{ run_hooks(post_hooks) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.run_hooks\", \"macro.dbt.handle_existing_table\", \"macro.dbt.should_full_refresh\", \"macro.dbt.statement\", \"macro.dbt.get_create_view_as_sql\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.686346}, \"macro.dbt.get_create_view_as_sql\": {\"unique_id\": \"macro.dbt.get_create_view_as_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/view/create_view_as.sql\", \"original_file_path\": \"macros/materializations/models/view/create_view_as.sql\", \"name\": \"get_create_view_as_sql\", \"macro_sql\": \"{% macro get_create_view_as_sql(relation, sql) -%}\\n  {{ adapter.dispatch('get_create_view_as_sql', 'dbt')(relation, sql) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_create_view_as_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.687447}, \"macro.dbt.default__get_create_view_as_sql\": {\"unique_id\": \"macro.dbt.default__get_create_view_as_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/view/create_view_as.sql\", \"original_file_path\": \"macros/materializations/models/view/create_view_as.sql\", \"name\": \"default__get_create_view_as_sql\", \"macro_sql\": \"{% macro default__get_create_view_as_sql(relation, sql) -%}\\n  {{ return(create_view_as(relation, sql)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.create_view_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.6878788}, \"macro.dbt.create_view_as\": {\"unique_id\": \"macro.dbt.create_view_as\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/view/create_view_as.sql\", \"original_file_path\": \"macros/materializations/models/view/create_view_as.sql\", \"name\": \"create_view_as\", \"macro_sql\": \"{% macro create_view_as(relation, sql) -%}\\n  {{ adapter.dispatch('create_view_as', 'dbt')(relation, sql) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__create_view_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.688359}, \"macro.dbt.default__create_view_as\": {\"unique_id\": \"macro.dbt.default__create_view_as\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/models/view/create_view_as.sql\", \"original_file_path\": \"macros/materializations/models/view/create_view_as.sql\", \"name\": \"default__create_view_as\", \"macro_sql\": \"{% macro default__create_view_as(relation, sql) -%}\\n  {%- set sql_header = config.get('sql_header', none) -%}\\n\\n  {{ sql_header if sql_header is not none }}\\n  create view {{ relation }} as (\\n    {{ sql }}\\n  );\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.6890602}, \"macro.dbt.materialization_seed_default\": {\"unique_id\": \"macro.dbt.materialization_seed_default\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/seed.sql\", \"original_file_path\": \"macros/materializations/seeds/seed.sql\", \"name\": \"materialization_seed_default\", \"macro_sql\": \"{% materialization seed, default %}\\n\\n  {%- set identifier = model['alias'] -%}\\n  {%- set full_refresh_mode = (should_full_refresh()) -%}\\n\\n  {%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%}\\n\\n  {%- set exists_as_table = (old_relation is not none and old_relation.is_table) -%}\\n  {%- set exists_as_view = (old_relation is not none and old_relation.is_view) -%}\\n\\n  {%- set grant_config = config.get('grants') -%}\\n  {%- set agate_table = load_agate_table() -%}\\n  -- grab current tables grants config for comparision later on\\n\\n  {%- do store_result('agate_table', response='OK', agate_table=agate_table) -%}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  -- build model\\n  {% set create_table_sql = \\\"\\\" %}\\n  {% if exists_as_view %}\\n    {{ exceptions.raise_compiler_error(\\\"Cannot seed to '{}', it is a view\\\".format(old_relation)) }}\\n  {% elif exists_as_table %}\\n    {% set create_table_sql = reset_csv_table(model, full_refresh_mode, old_relation, agate_table) %}\\n  {% else %}\\n    {% set create_table_sql = create_csv_table(model, agate_table) %}\\n  {% endif %}\\n\\n  {% set code = 'CREATE' if full_refresh_mode else 'INSERT' %}\\n  {% set rows_affected = (agate_table.rows | length) %}\\n  {% set sql = load_csv_rows(model, agate_table) %}\\n\\n  {% call noop_statement('main', code ~ ' ' ~ rows_affected, code, rows_affected) %}\\n    {{ get_csv_sql(create_table_sql, sql) }};\\n  {% endcall %}\\n\\n  {% set target_relation = this.incorporate(type='table') %}\\n\\n  {% set should_revoke = should_revoke(old_relation, full_refresh_mode) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {% if full_refresh_mode or not exists_as_table %}\\n    {% do create_indexes(target_relation) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  -- `COMMIT` happens here\\n  {{ adapter.commit() }}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{% endmaterialization %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.should_full_refresh\", \"macro.dbt.run_hooks\", \"macro.dbt.reset_csv_table\", \"macro.dbt.create_csv_table\", \"macro.dbt.load_csv_rows\", \"macro.dbt.noop_statement\", \"macro.dbt.get_csv_sql\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\", \"macro.dbt.persist_docs\", \"macro.dbt.create_indexes\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.698056}, \"macro.dbt.create_csv_table\": {\"unique_id\": \"macro.dbt.create_csv_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"create_csv_table\", \"macro_sql\": \"{% macro create_csv_table(model, agate_table) -%}\\n  {{ adapter.dispatch('create_csv_table', 'dbt')(model, agate_table) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__create_csv_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.7117178}, \"macro.dbt.default__create_csv_table\": {\"unique_id\": \"macro.dbt.default__create_csv_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"default__create_csv_table\", \"macro_sql\": \"{% macro default__create_csv_table(model, agate_table) %}\\n  {%- set column_override = model['config'].get('column_types', {}) -%}\\n  {%- set quote_seed_column = model['config'].get('quote_columns', None) -%}\\n\\n  {% set sql %}\\n    create table {{ this.render() }} (\\n        {%- for col_name in agate_table.column_names -%}\\n            {%- set inferred_type = adapter.convert_type(agate_table, loop.index0) -%}\\n            {%- set type = column_override.get(col_name, inferred_type) -%}\\n            {%- set column_name = (col_name | string) -%}\\n            {{ adapter.quote_seed_column(column_name, quote_seed_column) }} {{ type }} {%- if not loop.last -%}, {%- endif -%}\\n        {%- endfor -%}\\n    )\\n  {% endset %}\\n\\n  {% call statement('_') -%}\\n    {{ sql }}\\n  {%- endcall %}\\n\\n  {{ return(sql) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.7141619}, \"macro.dbt.reset_csv_table\": {\"unique_id\": \"macro.dbt.reset_csv_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"reset_csv_table\", \"macro_sql\": \"{% macro reset_csv_table(model, full_refresh, old_relation, agate_table) -%}\\n  {{ adapter.dispatch('reset_csv_table', 'dbt')(model, full_refresh, old_relation, agate_table) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__reset_csv_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.714784}, \"macro.dbt.default__reset_csv_table\": {\"unique_id\": \"macro.dbt.default__reset_csv_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"default__reset_csv_table\", \"macro_sql\": \"{% macro default__reset_csv_table(model, full_refresh, old_relation, agate_table) %}\\n    {% set sql = \\\"\\\" %}\\n    {% if full_refresh %}\\n        {{ adapter.drop_relation(old_relation) }}\\n        {% set sql = create_csv_table(model, agate_table) %}\\n    {% else %}\\n        {{ adapter.truncate_relation(old_relation) }}\\n        {% set sql = \\\"truncate table \\\" ~ old_relation %}\\n    {% endif %}\\n\\n    {{ return(sql) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.create_csv_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.716077}, \"macro.dbt.get_csv_sql\": {\"unique_id\": \"macro.dbt.get_csv_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"get_csv_sql\", \"macro_sql\": \"{% macro get_csv_sql(create_or_truncate_sql, insert_sql) %}\\n    {{ adapter.dispatch('get_csv_sql', 'dbt')(create_or_truncate_sql, insert_sql) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_csv_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.716581}, \"macro.dbt.default__get_csv_sql\": {\"unique_id\": \"macro.dbt.default__get_csv_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"default__get_csv_sql\", \"macro_sql\": \"{% macro default__get_csv_sql(create_or_truncate_sql, insert_sql) %}\\n    {{ create_or_truncate_sql }};\\n    -- dbt seed --\\n    {{ insert_sql }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.716925}, \"macro.dbt.get_binding_char\": {\"unique_id\": \"macro.dbt.get_binding_char\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"get_binding_char\", \"macro_sql\": \"{% macro get_binding_char() -%}\\n  {{ adapter.dispatch('get_binding_char', 'dbt')() }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_binding_char\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.717283}, \"macro.dbt.default__get_binding_char\": {\"unique_id\": \"macro.dbt.default__get_binding_char\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"default__get_binding_char\", \"macro_sql\": \"{% macro default__get_binding_char() %}\\n  {{ return('%s') }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.717576}, \"macro.dbt.get_batch_size\": {\"unique_id\": \"macro.dbt.get_batch_size\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"get_batch_size\", \"macro_sql\": \"{% macro get_batch_size() -%}\\n  {{ return(adapter.dispatch('get_batch_size', 'dbt')()) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_batch_size\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.717988}, \"macro.dbt.default__get_batch_size\": {\"unique_id\": \"macro.dbt.default__get_batch_size\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"default__get_batch_size\", \"macro_sql\": \"{% macro default__get_batch_size() %}\\n  {{ return(10000) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.718283}, \"macro.dbt.get_seed_column_quoted_csv\": {\"unique_id\": \"macro.dbt.get_seed_column_quoted_csv\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"get_seed_column_quoted_csv\", \"macro_sql\": \"{% macro get_seed_column_quoted_csv(model, column_names) %}\\n  {%- set quote_seed_column = model['config'].get('quote_columns', None) -%}\\n    {% set quoted = [] %}\\n    {% for col in column_names -%}\\n        {%- do quoted.append(adapter.quote_seed_column(col, quote_seed_column)) -%}\\n    {%- endfor %}\\n\\n    {%- set dest_cols_csv = quoted | join(', ') -%}\\n    {{ return(dest_cols_csv) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.719548}, \"macro.dbt.load_csv_rows\": {\"unique_id\": \"macro.dbt.load_csv_rows\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"load_csv_rows\", \"macro_sql\": \"{% macro load_csv_rows(model, agate_table) -%}\\n  {{ adapter.dispatch('load_csv_rows', 'dbt')(model, agate_table) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__load_csv_rows\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.720028}, \"macro.dbt.default__load_csv_rows\": {\"unique_id\": \"macro.dbt.default__load_csv_rows\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"default__load_csv_rows\", \"macro_sql\": \"{% macro default__load_csv_rows(model, agate_table) %}\\n\\n  {% set batch_size = get_batch_size() %}\\n\\n  {% set cols_sql = get_seed_column_quoted_csv(model, agate_table.column_names) %}\\n  {% set bindings = [] %}\\n\\n  {% set statements = [] %}\\n\\n  {% for chunk in agate_table.rows | batch(batch_size) %}\\n      {% set bindings = [] %}\\n\\n      {% for row in chunk %}\\n          {% do bindings.extend(row) %}\\n      {% endfor %}\\n\\n      {% set sql %}\\n          insert into {{ this.render() }} ({{ cols_sql }}) values\\n          {% for row in chunk -%}\\n              ({%- for column in agate_table.column_names -%}\\n                  {{ get_binding_char() }}\\n                  {%- if not loop.last%},{%- endif %}\\n              {%- endfor -%})\\n              {%- if not loop.last%},{%- endif %}\\n          {%- endfor %}\\n      {% endset %}\\n\\n      {% do adapter.add_query(sql, bindings=bindings, abridge_sql_log=True) %}\\n\\n      {% if loop.index0 == 0 %}\\n          {% do statements.append(sql) %}\\n      {% endif %}\\n  {% endfor %}\\n\\n  {# Return SQL so we can render it out into the compiled files #}\\n  {{ return(statements[0]) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_batch_size\", \"macro.dbt.get_seed_column_quoted_csv\", \"macro.dbt.get_binding_char\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.723425}, \"macro.dbt.generate_alias_name\": {\"unique_id\": \"macro.dbt.generate_alias_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/get_custom_name/get_custom_alias.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_alias.sql\", \"name\": \"generate_alias_name\", \"macro_sql\": \"{% macro generate_alias_name(custom_alias_name=none, node=none) -%}\\n    {% do return(adapter.dispatch('generate_alias_name', 'dbt')(custom_alias_name, node)) %}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__generate_alias_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.724572}, \"macro.dbt.default__generate_alias_name\": {\"unique_id\": \"macro.dbt.default__generate_alias_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/get_custom_name/get_custom_alias.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_alias.sql\", \"name\": \"default__generate_alias_name\", \"macro_sql\": \"{% macro default__generate_alias_name(custom_alias_name=none, node=none) -%}\\n\\n    {%- if custom_alias_name is none -%}\\n\\n        {{ node.name }}\\n\\n    {%- else -%}\\n\\n        {{ custom_alias_name | trim }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.725169}, \"macro.dbt.generate_schema_name\": {\"unique_id\": \"macro.dbt.generate_schema_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/get_custom_name/get_custom_schema.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_schema.sql\", \"name\": \"generate_schema_name\", \"macro_sql\": \"{% macro generate_schema_name(custom_schema_name=none, node=none) -%}\\n    {{ return(adapter.dispatch('generate_schema_name', 'dbt')(custom_schema_name, node)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__generate_schema_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.72671}, \"macro.dbt.default__generate_schema_name\": {\"unique_id\": \"macro.dbt.default__generate_schema_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/get_custom_name/get_custom_schema.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_schema.sql\", \"name\": \"default__generate_schema_name\", \"macro_sql\": \"{% macro default__generate_schema_name(custom_schema_name, node) -%}\\n\\n    {%- set default_schema = target.schema -%}\\n    {%- if custom_schema_name is none -%}\\n\\n        {{ default_schema }}\\n\\n    {%- else -%}\\n\\n        {{ default_schema }}_{{ custom_schema_name | trim }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.727396}, \"macro.dbt.generate_schema_name_for_env\": {\"unique_id\": \"macro.dbt.generate_schema_name_for_env\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/get_custom_name/get_custom_schema.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_schema.sql\", \"name\": \"generate_schema_name_for_env\", \"macro_sql\": \"{% macro generate_schema_name_for_env(custom_schema_name, node) -%}\\n\\n    {%- set default_schema = target.schema -%}\\n    {%- if target.name == 'prod' and custom_schema_name is not none -%}\\n\\n        {{ custom_schema_name | trim }}\\n\\n    {%- else -%}\\n\\n        {{ default_schema }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.728158}, \"macro.dbt.generate_database_name\": {\"unique_id\": \"macro.dbt.generate_database_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/get_custom_name/get_custom_database.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_database.sql\", \"name\": \"generate_database_name\", \"macro_sql\": \"{% macro generate_database_name(custom_database_name=none, node=none) -%}\\n    {% do return(adapter.dispatch('generate_database_name', 'dbt')(custom_database_name, node)) %}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__generate_database_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.729355}, \"macro.dbt.default__generate_database_name\": {\"unique_id\": \"macro.dbt.default__generate_database_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/get_custom_name/get_custom_database.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_database.sql\", \"name\": \"default__generate_database_name\", \"macro_sql\": \"{% macro default__generate_database_name(custom_database_name=none, node=none) -%}\\n    {%- set default_database = target.database -%}\\n    {%- if custom_database_name is none -%}\\n\\n        {{ default_database }}\\n\\n    {%- else -%}\\n\\n        {{ custom_database_name }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.73002}, \"macro.dbt.default__test_relationships\": {\"unique_id\": \"macro.dbt.default__test_relationships\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/generic_test_sql/relationships.sql\", \"original_file_path\": \"macros/generic_test_sql/relationships.sql\", \"name\": \"default__test_relationships\", \"macro_sql\": \"{% macro default__test_relationships(model, column_name, to, field) %}\\n\\nwith child as (\\n    select {{ column_name }} as from_field\\n    from {{ model }}\\n    where {{ column_name }} is not null\\n),\\n\\nparent as (\\n    select {{ field }} as to_field\\n    from {{ to }}\\n)\\n\\nselect\\n    from_field\\n\\nfrom child\\nleft join parent\\n    on child.from_field = parent.to_field\\n\\nwhere parent.to_field is null\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.7310588}, \"macro.dbt.default__test_not_null\": {\"unique_id\": \"macro.dbt.default__test_not_null\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/generic_test_sql/not_null.sql\", \"original_file_path\": \"macros/generic_test_sql/not_null.sql\", \"name\": \"default__test_not_null\", \"macro_sql\": \"{% macro default__test_not_null(model, column_name) %}\\n\\n{% set column_list = '*' if should_store_failures() else column_name %}\\n\\nselect {{ column_list }}\\nfrom {{ model }}\\nwhere {{ column_name }} is null\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.should_store_failures\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.731988}, \"macro.dbt.default__test_unique\": {\"unique_id\": \"macro.dbt.default__test_unique\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/generic_test_sql/unique.sql\", \"original_file_path\": \"macros/generic_test_sql/unique.sql\", \"name\": \"default__test_unique\", \"macro_sql\": \"{% macro default__test_unique(model, column_name) %}\\n\\nselect\\n    {{ column_name }} as unique_field,\\n    count(*) as n_records\\n\\nfrom {{ model }}\\nwhere {{ column_name }} is not null\\ngroup by {{ column_name }}\\nhaving count(*) > 1\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.732775}, \"macro.dbt.default__test_accepted_values\": {\"unique_id\": \"macro.dbt.default__test_accepted_values\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/generic_test_sql/accepted_values.sql\", \"original_file_path\": \"macros/generic_test_sql/accepted_values.sql\", \"name\": \"default__test_accepted_values\", \"macro_sql\": \"{% macro default__test_accepted_values(model, column_name, values, quote=True) %}\\n\\nwith all_values as (\\n\\n    select\\n        {{ column_name }} as value_field,\\n        count(*) as n_records\\n\\n    from {{ model }}\\n    group by {{ column_name }}\\n\\n)\\n\\nselect *\\nfrom all_values\\nwhere value_field not in (\\n    {% for value in values -%}\\n        {% if quote -%}\\n        '{{ value }}'\\n        {%- else -%}\\n        {{ value }}\\n        {%- endif -%}\\n        {%- if not loop.last -%},{%- endif %}\\n    {%- endfor %}\\n)\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.734423}, \"macro.dbt.statement\": {\"unique_id\": \"macro.dbt.statement\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/etc/statement.sql\", \"original_file_path\": \"macros/etc/statement.sql\", \"name\": \"statement\", \"macro_sql\": \"{% macro statement(name=None, fetch_result=False, auto_begin=True) -%}\\n  {%- if execute: -%}\\n    {%- set sql = caller() -%}\\n\\n    {%- if name == 'main' -%}\\n      {{ log('Writing runtime SQL for node \\\"{}\\\"'.format(model['unique_id'])) }}\\n      {{ write(sql) }}\\n    {%- endif -%}\\n\\n    {%- set res, table = adapter.execute(sql, auto_begin=auto_begin, fetch=fetch_result) -%}\\n    {%- if name is not none -%}\\n      {{ store_result(name, response=res, agate_table=table) }}\\n    {%- endif -%}\\n\\n  {%- endif -%}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.737539}, \"macro.dbt.noop_statement\": {\"unique_id\": \"macro.dbt.noop_statement\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/etc/statement.sql\", \"original_file_path\": \"macros/etc/statement.sql\", \"name\": \"noop_statement\", \"macro_sql\": \"{% macro noop_statement(name=None, message=None, code=None, rows_affected=None, res=None) -%}\\n  {%- set sql = caller() -%}\\n\\n  {%- if name == 'main' -%}\\n    {{ log('Writing runtime SQL for node \\\"{}\\\"'.format(model['unique_id'])) }}\\n    {{ write(sql) }}\\n  {%- endif -%}\\n\\n  {%- if name is not none -%}\\n    {{ store_raw_result(name, message=message, code=code, rows_affected=rows_affected, agate_table=res) }}\\n  {%- endif -%}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.739098}, \"macro.dbt.run_query\": {\"unique_id\": \"macro.dbt.run_query\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/etc/statement.sql\", \"original_file_path\": \"macros/etc/statement.sql\", \"name\": \"run_query\", \"macro_sql\": \"{% macro run_query(sql) %}\\n  {% call statement(\\\"run_query_statement\\\", fetch_result=true, auto_begin=false) %}\\n    {{ sql }}\\n  {% endcall %}\\n\\n  {% do return(load_result(\\\"run_query_statement\\\").table) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.739882}, \"macro.dbt.convert_datetime\": {\"unique_id\": \"macro.dbt.convert_datetime\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"name\": \"convert_datetime\", \"macro_sql\": \"{% macro convert_datetime(date_str, date_fmt) %}\\n\\n  {% set error_msg -%}\\n      The provided partition date '{{ date_str }}' does not match the expected format '{{ date_fmt }}'\\n  {%- endset %}\\n\\n  {% set res = try_or_compiler_error(error_msg, modules.datetime.datetime.strptime, date_str.strip(), date_fmt) %}\\n  {{ return(res) }}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.744986}, \"macro.dbt.dates_in_range\": {\"unique_id\": \"macro.dbt.dates_in_range\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"name\": \"dates_in_range\", \"macro_sql\": \"{% macro dates_in_range(start_date_str, end_date_str=none, in_fmt=\\\"%Y%m%d\\\", out_fmt=\\\"%Y%m%d\\\") %}\\n    {% set end_date_str = start_date_str if end_date_str is none else end_date_str %}\\n\\n    {% set start_date = convert_datetime(start_date_str, in_fmt) %}\\n    {% set end_date = convert_datetime(end_date_str, in_fmt) %}\\n\\n    {% set day_count = (end_date - start_date).days %}\\n    {% if day_count < 0 %}\\n        {% set msg -%}\\n            Partition start date is after the end date ({{ start_date }}, {{ end_date }})\\n        {%- endset %}\\n\\n        {{ exceptions.raise_compiler_error(msg, model) }}\\n    {% endif %}\\n\\n    {% set date_list = [] %}\\n    {% for i in range(0, day_count + 1) %}\\n        {% set the_date = (modules.datetime.timedelta(days=i) + start_date) %}\\n        {% if not out_fmt %}\\n            {% set _ = date_list.append(the_date) %}\\n        {% else %}\\n            {% set _ = date_list.append(the_date.strftime(out_fmt)) %}\\n        {% endif %}\\n    {% endfor %}\\n\\n    {{ return(date_list) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.convert_datetime\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.7483132}, \"macro.dbt.partition_range\": {\"unique_id\": \"macro.dbt.partition_range\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"name\": \"partition_range\", \"macro_sql\": \"{% macro partition_range(raw_partition_date, date_fmt='%Y%m%d') %}\\n    {% set partition_range = (raw_partition_date | string).split(\\\",\\\") %}\\n\\n    {% if (partition_range | length) == 1 %}\\n      {% set start_date = partition_range[0] %}\\n      {% set end_date = none %}\\n    {% elif (partition_range | length) == 2 %}\\n      {% set start_date = partition_range[0] %}\\n      {% set end_date = partition_range[1] %}\\n    {% else %}\\n      {{ exceptions.raise_compiler_error(\\\"Invalid partition time. Expected format: {Start Date}[,{End Date}]. Got: \\\" ~ raw_partition_date) }}\\n    {% endif %}\\n\\n    {{ return(dates_in_range(start_date, end_date, in_fmt=date_fmt)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.dates_in_range\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.750348}, \"macro.dbt.py_current_timestring\": {\"unique_id\": \"macro.dbt.py_current_timestring\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"name\": \"py_current_timestring\", \"macro_sql\": \"{% macro py_current_timestring() %}\\n    {% set dt = modules.datetime.datetime.now() %}\\n    {% do return(dt.strftime(\\\"%Y%m%d%H%M%S%f\\\")) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.750963}, \"macro.dbt.except\": {\"unique_id\": \"macro.dbt.except\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/except.sql\", \"original_file_path\": \"macros/utils/except.sql\", \"name\": \"except\", \"macro_sql\": \"{% macro except() %}\\n  {{ return(adapter.dispatch('except', 'dbt')()) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__except\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.7517078}, \"macro.dbt.default__except\": {\"unique_id\": \"macro.dbt.default__except\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/except.sql\", \"original_file_path\": \"macros/utils/except.sql\", \"name\": \"default__except\", \"macro_sql\": \"{% macro default__except() %}\\n\\n    except\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.751895}, \"macro.dbt.replace\": {\"unique_id\": \"macro.dbt.replace\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/replace.sql\", \"original_file_path\": \"macros/utils/replace.sql\", \"name\": \"replace\", \"macro_sql\": \"{% macro replace(field, old_chars, new_chars) -%}\\n    {{ return(adapter.dispatch('replace', 'dbt') (field, old_chars, new_chars)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__replace\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.752911}, \"macro.dbt.default__replace\": {\"unique_id\": \"macro.dbt.default__replace\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/replace.sql\", \"original_file_path\": \"macros/utils/replace.sql\", \"name\": \"default__replace\", \"macro_sql\": \"{% macro default__replace(field, old_chars, new_chars) %}\\n\\n    replace(\\n        {{ field }},\\n        {{ old_chars }},\\n        {{ new_chars }}\\n    )\\n\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.753338}, \"macro.dbt.concat\": {\"unique_id\": \"macro.dbt.concat\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/concat.sql\", \"original_file_path\": \"macros/utils/concat.sql\", \"name\": \"concat\", \"macro_sql\": \"{% macro concat(fields) -%}\\n  {{ return(adapter.dispatch('concat', 'dbt')(fields)) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__concat\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.7541351}, \"macro.dbt.default__concat\": {\"unique_id\": \"macro.dbt.default__concat\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/concat.sql\", \"original_file_path\": \"macros/utils/concat.sql\", \"name\": \"default__concat\", \"macro_sql\": \"{% macro default__concat(fields) -%}\\n    {{ fields|join(' || ') }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.754451}, \"macro.dbt.length\": {\"unique_id\": \"macro.dbt.length\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/length.sql\", \"original_file_path\": \"macros/utils/length.sql\", \"name\": \"length\", \"macro_sql\": \"{% macro length(expression) -%}\\n    {{ return(adapter.dispatch('length', 'dbt') (expression)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__length\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.75524}, \"macro.dbt.default__length\": {\"unique_id\": \"macro.dbt.default__length\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/length.sql\", \"original_file_path\": \"macros/utils/length.sql\", \"name\": \"default__length\", \"macro_sql\": \"{% macro default__length(expression) %}\\n\\n    length(\\n        {{ expression }}\\n    )\\n\\n{%- endmacro -%}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.755511}, \"macro.dbt.dateadd\": {\"unique_id\": \"macro.dbt.dateadd\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/dateadd.sql\", \"original_file_path\": \"macros/utils/dateadd.sql\", \"name\": \"dateadd\", \"macro_sql\": \"{% macro dateadd(datepart, interval, from_date_or_timestamp) %}\\n  {{ return(adapter.dispatch('dateadd', 'dbt')(datepart, interval, from_date_or_timestamp)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__dateadd\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.7565598}, \"macro.dbt.default__dateadd\": {\"unique_id\": \"macro.dbt.default__dateadd\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/dateadd.sql\", \"original_file_path\": \"macros/utils/dateadd.sql\", \"name\": \"default__dateadd\", \"macro_sql\": \"{% macro default__dateadd(datepart, interval, from_date_or_timestamp) %}\\n\\n    dateadd(\\n        {{ datepart }},\\n        {{ interval }},\\n        {{ from_date_or_timestamp }}\\n        )\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.756995}, \"macro.dbt.intersect\": {\"unique_id\": \"macro.dbt.intersect\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/intersect.sql\", \"original_file_path\": \"macros/utils/intersect.sql\", \"name\": \"intersect\", \"macro_sql\": \"{% macro intersect() %}\\n  {{ return(adapter.dispatch('intersect', 'dbt')()) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__intersect\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.7577422}, \"macro.dbt.default__intersect\": {\"unique_id\": \"macro.dbt.default__intersect\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/intersect.sql\", \"original_file_path\": \"macros/utils/intersect.sql\", \"name\": \"default__intersect\", \"macro_sql\": \"{% macro default__intersect() %}\\n\\n    intersect\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.7579389}, \"macro.dbt.escape_single_quotes\": {\"unique_id\": \"macro.dbt.escape_single_quotes\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/escape_single_quotes.sql\", \"original_file_path\": \"macros/utils/escape_single_quotes.sql\", \"name\": \"escape_single_quotes\", \"macro_sql\": \"{% macro escape_single_quotes(expression) %}\\n      {{ return(adapter.dispatch('escape_single_quotes', 'dbt') (expression)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__escape_single_quotes\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.7587788}, \"macro.dbt.default__escape_single_quotes\": {\"unique_id\": \"macro.dbt.default__escape_single_quotes\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/escape_single_quotes.sql\", \"original_file_path\": \"macros/utils/escape_single_quotes.sql\", \"name\": \"default__escape_single_quotes\", \"macro_sql\": \"{% macro default__escape_single_quotes(expression) -%}\\n{{ expression | replace(\\\"'\\\",\\\"''\\\") }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.75913}, \"macro.dbt.right\": {\"unique_id\": \"macro.dbt.right\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/right.sql\", \"original_file_path\": \"macros/utils/right.sql\", \"name\": \"right\", \"macro_sql\": \"{% macro right(string_text, length_expression) -%}\\n    {{ return(adapter.dispatch('right', 'dbt') (string_text, length_expression)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__right\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.760025}, \"macro.dbt.default__right\": {\"unique_id\": \"macro.dbt.default__right\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/right.sql\", \"original_file_path\": \"macros/utils/right.sql\", \"name\": \"default__right\", \"macro_sql\": \"{% macro default__right(string_text, length_expression) %}\\n\\n    right(\\n        {{ string_text }},\\n        {{ length_expression }}\\n    )\\n\\n{%- endmacro -%}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.760372}, \"macro.dbt.listagg\": {\"unique_id\": \"macro.dbt.listagg\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/listagg.sql\", \"original_file_path\": \"macros/utils/listagg.sql\", \"name\": \"listagg\", \"macro_sql\": \"{% macro listagg(measure, delimiter_text=\\\"','\\\", order_by_clause=none, limit_num=none) -%}\\n    {{ return(adapter.dispatch('listagg', 'dbt') (measure, delimiter_text, order_by_clause, limit_num)) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__listagg\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.762194}, \"macro.dbt.default__listagg\": {\"unique_id\": \"macro.dbt.default__listagg\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/listagg.sql\", \"original_file_path\": \"macros/utils/listagg.sql\", \"name\": \"default__listagg\", \"macro_sql\": \"{% macro default__listagg(measure, delimiter_text, order_by_clause, limit_num) -%}\\n\\n    {% if limit_num -%}\\n    array_to_string(\\n        array_slice(\\n            array_agg(\\n                {{ measure }}\\n            ){% if order_by_clause -%}\\n            within group ({{ order_by_clause }})\\n            {%- endif %}\\n            ,0\\n            ,{{ limit_num }}\\n        ),\\n        {{ delimiter_text }}\\n        )\\n    {%- else %}\\n    listagg(\\n        {{ measure }},\\n        {{ delimiter_text }}\\n        )\\n        {% if order_by_clause -%}\\n        within group ({{ order_by_clause }})\\n        {%- endif %}\\n    {%- endif %}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.7634282}, \"macro.dbt.datediff\": {\"unique_id\": \"macro.dbt.datediff\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/datediff.sql\", \"original_file_path\": \"macros/utils/datediff.sql\", \"name\": \"datediff\", \"macro_sql\": \"{% macro datediff(first_date, second_date, datepart) %}\\n  {{ return(adapter.dispatch('datediff', 'dbt')(first_date, second_date, datepart)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__datediff\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.764456}, \"macro.dbt.default__datediff\": {\"unique_id\": \"macro.dbt.default__datediff\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/datediff.sql\", \"original_file_path\": \"macros/utils/datediff.sql\", \"name\": \"default__datediff\", \"macro_sql\": \"{% macro default__datediff(first_date, second_date, datepart) -%}\\n\\n    datediff(\\n        {{ datepart }},\\n        {{ first_date }},\\n        {{ second_date }}\\n        )\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.764895}, \"macro.dbt.safe_cast\": {\"unique_id\": \"macro.dbt.safe_cast\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/safe_cast.sql\", \"original_file_path\": \"macros/utils/safe_cast.sql\", \"name\": \"safe_cast\", \"macro_sql\": \"{% macro safe_cast(field, type) %}\\n  {{ return(adapter.dispatch('safe_cast', 'dbt') (field, type)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__safe_cast\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.76579}, \"macro.dbt.default__safe_cast\": {\"unique_id\": \"macro.dbt.default__safe_cast\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/safe_cast.sql\", \"original_file_path\": \"macros/utils/safe_cast.sql\", \"name\": \"default__safe_cast\", \"macro_sql\": \"{% macro default__safe_cast(field, type) %}\\n    {# most databases don't support this function yet\\n    so we just need to use cast #}\\n    cast({{field}} as {{type}})\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.7661529}, \"macro.dbt.hash\": {\"unique_id\": \"macro.dbt.hash\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/hash.sql\", \"original_file_path\": \"macros/utils/hash.sql\", \"name\": \"hash\", \"macro_sql\": \"{% macro hash(field) -%}\\n  {{ return(adapter.dispatch('hash', 'dbt') (field)) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__hash\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.766952}, \"macro.dbt.default__hash\": {\"unique_id\": \"macro.dbt.default__hash\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/hash.sql\", \"original_file_path\": \"macros/utils/hash.sql\", \"name\": \"default__hash\", \"macro_sql\": \"{% macro default__hash(field) -%}\\n    md5(cast({{ field }} as {{ api.Column.translate_type('string') }}))\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.767371}, \"macro.dbt.cast_bool_to_text\": {\"unique_id\": \"macro.dbt.cast_bool_to_text\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/cast_bool_to_text.sql\", \"original_file_path\": \"macros/utils/cast_bool_to_text.sql\", \"name\": \"cast_bool_to_text\", \"macro_sql\": \"{% macro cast_bool_to_text(field) %}\\n  {{ adapter.dispatch('cast_bool_to_text', 'dbt') (field) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__cast_bool_to_text\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.7681432}, \"macro.dbt.default__cast_bool_to_text\": {\"unique_id\": \"macro.dbt.default__cast_bool_to_text\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/cast_bool_to_text.sql\", \"original_file_path\": \"macros/utils/cast_bool_to_text.sql\", \"name\": \"default__cast_bool_to_text\", \"macro_sql\": \"{% macro default__cast_bool_to_text(field) %}\\n    cast({{ field }} as {{ api.Column.translate_type('string') }})\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.768564}, \"macro.dbt.any_value\": {\"unique_id\": \"macro.dbt.any_value\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/any_value.sql\", \"original_file_path\": \"macros/utils/any_value.sql\", \"name\": \"any_value\", \"macro_sql\": \"{% macro any_value(expression) -%}\\n    {{ return(adapter.dispatch('any_value', 'dbt') (expression)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__any_value\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.769363}, \"macro.dbt.default__any_value\": {\"unique_id\": \"macro.dbt.default__any_value\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/any_value.sql\", \"original_file_path\": \"macros/utils/any_value.sql\", \"name\": \"default__any_value\", \"macro_sql\": \"{% macro default__any_value(expression) -%}\\n\\n    any_value({{ expression }})\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.769631}, \"macro.dbt.position\": {\"unique_id\": \"macro.dbt.position\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/position.sql\", \"original_file_path\": \"macros/utils/position.sql\", \"name\": \"position\", \"macro_sql\": \"{% macro position(substring_text, string_text) -%}\\n    {{ return(adapter.dispatch('position', 'dbt') (substring_text, string_text)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__position\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.770546}, \"macro.dbt.default__position\": {\"unique_id\": \"macro.dbt.default__position\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/position.sql\", \"original_file_path\": \"macros/utils/position.sql\", \"name\": \"default__position\", \"macro_sql\": \"{% macro default__position(substring_text, string_text) %}\\n\\n    position(\\n        {{ substring_text }} in {{ string_text }}\\n    )\\n\\n{%- endmacro -%}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.7708979}, \"macro.dbt.string_literal\": {\"unique_id\": \"macro.dbt.string_literal\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/literal.sql\", \"original_file_path\": \"macros/utils/literal.sql\", \"name\": \"string_literal\", \"macro_sql\": \"{%- macro string_literal(value) -%}\\n  {{ return(adapter.dispatch('string_literal', 'dbt') (value)) }}\\n{%- endmacro -%}\\n\\n\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__string_literal\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.77168}, \"macro.dbt.default__string_literal\": {\"unique_id\": \"macro.dbt.default__string_literal\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/literal.sql\", \"original_file_path\": \"macros/utils/literal.sql\", \"name\": \"default__string_literal\", \"macro_sql\": \"{% macro default__string_literal(value) -%}\\n    '{{ value }}'\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.771949}, \"macro.dbt.type_string\": {\"unique_id\": \"macro.dbt.type_string\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"name\": \"type_string\", \"macro_sql\": \"\\n\\n{%- macro type_string() -%}\\n  {{ return(adapter.dispatch('type_string', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__type_string\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.775103}, \"macro.dbt.default__type_string\": {\"unique_id\": \"macro.dbt.default__type_string\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"name\": \"default__type_string\", \"macro_sql\": \"{% macro default__type_string() %}\\n    {{ return(api.Column.translate_type(\\\"string\\\")) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.7755132}, \"macro.dbt.type_timestamp\": {\"unique_id\": \"macro.dbt.type_timestamp\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"name\": \"type_timestamp\", \"macro_sql\": \"\\n\\n{%- macro type_timestamp() -%}\\n  {{ return(adapter.dispatch('type_timestamp', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__type_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.7759519}, \"macro.dbt.default__type_timestamp\": {\"unique_id\": \"macro.dbt.default__type_timestamp\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"name\": \"default__type_timestamp\", \"macro_sql\": \"{% macro default__type_timestamp() %}\\n    {{ return(api.Column.translate_type(\\\"timestamp\\\")) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.776351}, \"macro.dbt.type_float\": {\"unique_id\": \"macro.dbt.type_float\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"name\": \"type_float\", \"macro_sql\": \"\\n\\n{%- macro type_float() -%}\\n  {{ return(adapter.dispatch('type_float', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__type_float\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.7769148}, \"macro.dbt.default__type_float\": {\"unique_id\": \"macro.dbt.default__type_float\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"name\": \"default__type_float\", \"macro_sql\": \"{% macro default__type_float() %}\\n    {{ return(api.Column.translate_type(\\\"float\\\")) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.777309}, \"macro.dbt.type_numeric\": {\"unique_id\": \"macro.dbt.type_numeric\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"name\": \"type_numeric\", \"macro_sql\": \"\\n\\n{%- macro type_numeric() -%}\\n  {{ return(adapter.dispatch('type_numeric', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__type_numeric\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.7777238}, \"macro.dbt.default__type_numeric\": {\"unique_id\": \"macro.dbt.default__type_numeric\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"name\": \"default__type_numeric\", \"macro_sql\": \"{% macro default__type_numeric() %}\\n    {{ return(api.Column.numeric_type(\\\"numeric\\\", 28, 6)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.778186}, \"macro.dbt.type_bigint\": {\"unique_id\": \"macro.dbt.type_bigint\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"name\": \"type_bigint\", \"macro_sql\": \"\\n\\n{%- macro type_bigint() -%}\\n  {{ return(adapter.dispatch('type_bigint', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__type_bigint\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.7786}, \"macro.dbt.default__type_bigint\": {\"unique_id\": \"macro.dbt.default__type_bigint\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"name\": \"default__type_bigint\", \"macro_sql\": \"{% macro default__type_bigint() %}\\n    {{ return(api.Column.translate_type(\\\"bigint\\\")) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.778995}, \"macro.dbt.type_int\": {\"unique_id\": \"macro.dbt.type_int\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"name\": \"type_int\", \"macro_sql\": \"\\n\\n{%- macro type_int() -%}\\n  {{ return(adapter.dispatch('type_int', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__type_int\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.7794151}, \"macro.dbt.default__type_int\": {\"unique_id\": \"macro.dbt.default__type_int\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"name\": \"default__type_int\", \"macro_sql\": \"{%- macro default__type_int() -%}\\n  {{ return(api.Column.translate_type(\\\"integer\\\")) }}\\n{%- endmacro -%}\\n\\n\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.779795}, \"macro.dbt.bool_or\": {\"unique_id\": \"macro.dbt.bool_or\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/bool_or.sql\", \"original_file_path\": \"macros/utils/bool_or.sql\", \"name\": \"bool_or\", \"macro_sql\": \"{% macro bool_or(expression) -%}\\n    {{ return(adapter.dispatch('bool_or', 'dbt') (expression)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__bool_or\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.780659}, \"macro.dbt.default__bool_or\": {\"unique_id\": \"macro.dbt.default__bool_or\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/bool_or.sql\", \"original_file_path\": \"macros/utils/bool_or.sql\", \"name\": \"default__bool_or\", \"macro_sql\": \"{% macro default__bool_or(expression) -%}\\n\\n    bool_or({{ expression }})\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.780927}, \"macro.dbt.last_day\": {\"unique_id\": \"macro.dbt.last_day\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/last_day.sql\", \"original_file_path\": \"macros/utils/last_day.sql\", \"name\": \"last_day\", \"macro_sql\": \"{% macro last_day(date, datepart) %}\\n  {{ return(adapter.dispatch('last_day', 'dbt') (date, datepart)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__last_day\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.782002}, \"macro.dbt.default_last_day\": {\"unique_id\": \"macro.dbt.default_last_day\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/last_day.sql\", \"original_file_path\": \"macros/utils/last_day.sql\", \"name\": \"default_last_day\", \"macro_sql\": \"\\n\\n{%- macro default_last_day(date, datepart) -%}\\n    cast(\\n        {{dbt.dateadd('day', '-1',\\n        dbt.dateadd(datepart, '1', dbt.date_trunc(datepart, date))\\n        )}}\\n        as date)\\n{%- endmacro -%}\\n\\n\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.dateadd\", \"macro.dbt.date_trunc\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.782704}, \"macro.dbt.default__last_day\": {\"unique_id\": \"macro.dbt.default__last_day\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/last_day.sql\", \"original_file_path\": \"macros/utils/last_day.sql\", \"name\": \"default__last_day\", \"macro_sql\": \"{% macro default__last_day(date, datepart) -%}\\n    {{dbt.default_last_day(date, datepart)}}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default_last_day\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.7830899}, \"macro.dbt.split_part\": {\"unique_id\": \"macro.dbt.split_part\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/split_part.sql\", \"original_file_path\": \"macros/utils/split_part.sql\", \"name\": \"split_part\", \"macro_sql\": \"{% macro split_part(string_text, delimiter_text, part_number) %}\\n  {{ return(adapter.dispatch('split_part', 'dbt') (string_text, delimiter_text, part_number)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__split_part\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.7846441}, \"macro.dbt.default__split_part\": {\"unique_id\": \"macro.dbt.default__split_part\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/split_part.sql\", \"original_file_path\": \"macros/utils/split_part.sql\", \"name\": \"default__split_part\", \"macro_sql\": \"{% macro default__split_part(string_text, delimiter_text, part_number) %}\\n\\n    split_part(\\n        {{ string_text }},\\n        {{ delimiter_text }},\\n        {{ part_number }}\\n        )\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.7850811}, \"macro.dbt._split_part_negative\": {\"unique_id\": \"macro.dbt._split_part_negative\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/split_part.sql\", \"original_file_path\": \"macros/utils/split_part.sql\", \"name\": \"_split_part_negative\", \"macro_sql\": \"{% macro _split_part_negative(string_text, delimiter_text, part_number) %}\\n\\n    split_part(\\n        {{ string_text }},\\n        {{ delimiter_text }},\\n          length({{ string_text }})\\n          - length(\\n              replace({{ string_text }},  {{ delimiter_text }}, '')\\n          ) + 2 {{ part_number }}\\n        )\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.785673}, \"macro.dbt.date_trunc\": {\"unique_id\": \"macro.dbt.date_trunc\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/date_trunc.sql\", \"original_file_path\": \"macros/utils/date_trunc.sql\", \"name\": \"date_trunc\", \"macro_sql\": \"{% macro date_trunc(datepart, date) -%}\\n  {{ return(adapter.dispatch('date_trunc', 'dbt') (datepart, date)) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__date_trunc\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.7865448}, \"macro.dbt.default__date_trunc\": {\"unique_id\": \"macro.dbt.default__date_trunc\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/utils/date_trunc.sql\", \"original_file_path\": \"macros/utils/date_trunc.sql\", \"name\": \"default__date_trunc\", \"macro_sql\": \"{% macro default__date_trunc(datepart, date) -%}\\n    date_trunc('{{datepart}}', {{date}})\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.786887}, \"macro.dbt.create_schema\": {\"unique_id\": \"macro.dbt.create_schema\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/schema.sql\", \"original_file_path\": \"macros/adapters/schema.sql\", \"name\": \"create_schema\", \"macro_sql\": \"{% macro create_schema(relation) -%}\\n  {{ adapter.dispatch('create_schema', 'dbt')(relation) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__create_schema\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.788033}, \"macro.dbt.default__create_schema\": {\"unique_id\": \"macro.dbt.default__create_schema\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/schema.sql\", \"original_file_path\": \"macros/adapters/schema.sql\", \"name\": \"default__create_schema\", \"macro_sql\": \"{% macro default__create_schema(relation) -%}\\n  {%- call statement('create_schema') -%}\\n    create schema if not exists {{ relation.without_identifier() }}\\n  {% endcall %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.7884989}, \"macro.dbt.drop_schema\": {\"unique_id\": \"macro.dbt.drop_schema\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/schema.sql\", \"original_file_path\": \"macros/adapters/schema.sql\", \"name\": \"drop_schema\", \"macro_sql\": \"{% macro drop_schema(relation) -%}\\n  {{ adapter.dispatch('drop_schema', 'dbt')(relation) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__drop_schema\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.788918}, \"macro.dbt.default__drop_schema\": {\"unique_id\": \"macro.dbt.default__drop_schema\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/schema.sql\", \"original_file_path\": \"macros/adapters/schema.sql\", \"name\": \"default__drop_schema\", \"macro_sql\": \"{% macro default__drop_schema(relation) -%}\\n  {%- call statement('drop_schema') -%}\\n    drop schema if exists {{ relation.without_identifier() }} cascade\\n  {% endcall %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.7895281}, \"macro.dbt.get_create_index_sql\": {\"unique_id\": \"macro.dbt.get_create_index_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"name\": \"get_create_index_sql\", \"macro_sql\": \"{% macro get_create_index_sql(relation, index_dict) -%}\\n  {{ return(adapter.dispatch('get_create_index_sql', 'dbt')(relation, index_dict)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_create_index_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.79088}, \"macro.dbt.default__get_create_index_sql\": {\"unique_id\": \"macro.dbt.default__get_create_index_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"name\": \"default__get_create_index_sql\", \"macro_sql\": \"{% macro default__get_create_index_sql(relation, index_dict) -%}\\n  {% do return(None) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.791239}, \"macro.dbt.create_indexes\": {\"unique_id\": \"macro.dbt.create_indexes\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"name\": \"create_indexes\", \"macro_sql\": \"{% macro create_indexes(relation) -%}\\n  {{ adapter.dispatch('create_indexes', 'dbt')(relation) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__create_indexes\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.791649}, \"macro.dbt.default__create_indexes\": {\"unique_id\": \"macro.dbt.default__create_indexes\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"name\": \"default__create_indexes\", \"macro_sql\": \"{% macro default__create_indexes(relation) -%}\\n  {%- set _indexes = config.get('indexes', default=[]) -%}\\n\\n  {% for _index_dict in _indexes %}\\n    {% set create_index_sql = get_create_index_sql(relation, _index_dict) %}\\n    {% if create_index_sql %}\\n      {% do run_query(create_index_sql) %}\\n    {% endif %}\\n  {% endfor %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_create_index_sql\", \"macro.dbt.run_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.792712}, \"macro.dbt.make_intermediate_relation\": {\"unique_id\": \"macro.dbt.make_intermediate_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"make_intermediate_relation\", \"macro_sql\": \"{% macro make_intermediate_relation(base_relation, suffix='__dbt_tmp') %}\\n  {{ return(adapter.dispatch('make_intermediate_relation', 'dbt')(base_relation, suffix)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_intermediate_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.80177}, \"macro.dbt.default__make_intermediate_relation\": {\"unique_id\": \"macro.dbt.default__make_intermediate_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"default__make_intermediate_relation\", \"macro_sql\": \"{% macro default__make_intermediate_relation(base_relation, suffix) %}\\n    {{ return(default__make_temp_relation(base_relation, suffix)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__make_temp_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.802206}, \"macro.dbt.make_temp_relation\": {\"unique_id\": \"macro.dbt.make_temp_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"make_temp_relation\", \"macro_sql\": \"{% macro make_temp_relation(base_relation, suffix='__dbt_tmp') %}\\n  {{ return(adapter.dispatch('make_temp_relation', 'dbt')(base_relation, suffix)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_temp_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.802784}, \"macro.dbt.default__make_temp_relation\": {\"unique_id\": \"macro.dbt.default__make_temp_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"default__make_temp_relation\", \"macro_sql\": \"{% macro default__make_temp_relation(base_relation, suffix) %}\\n    {%- set temp_identifier = base_relation.identifier ~ suffix -%}\\n    {%- set temp_relation = base_relation.incorporate(\\n                                path={\\\"identifier\\\": temp_identifier}) -%}\\n\\n    {{ return(temp_relation) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.8035462}, \"macro.dbt.make_backup_relation\": {\"unique_id\": \"macro.dbt.make_backup_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"make_backup_relation\", \"macro_sql\": \"{% macro make_backup_relation(base_relation, backup_relation_type, suffix='__dbt_backup') %}\\n    {{ return(adapter.dispatch('make_backup_relation', 'dbt')(base_relation, backup_relation_type, suffix)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_backup_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.804203}, \"macro.dbt.default__make_backup_relation\": {\"unique_id\": \"macro.dbt.default__make_backup_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"default__make_backup_relation\", \"macro_sql\": \"{% macro default__make_backup_relation(base_relation, backup_relation_type, suffix) %}\\n    {%- set backup_identifier = base_relation.identifier ~ suffix -%}\\n    {%- set backup_relation = base_relation.incorporate(\\n                                  path={\\\"identifier\\\": backup_identifier},\\n                                  type=backup_relation_type\\n    ) -%}\\n    {{ return(backup_relation) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.805045}, \"macro.dbt.drop_relation\": {\"unique_id\": \"macro.dbt.drop_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"drop_relation\", \"macro_sql\": \"{% macro drop_relation(relation) -%}\\n  {{ return(adapter.dispatch('drop_relation', 'dbt')(relation)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__drop_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.805522}, \"macro.dbt.default__drop_relation\": {\"unique_id\": \"macro.dbt.default__drop_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"default__drop_relation\", \"macro_sql\": \"{% macro default__drop_relation(relation) -%}\\n  {% call statement('drop_relation', auto_begin=False) -%}\\n    drop {{ relation.type }} if exists {{ relation }} cascade\\n  {%- endcall %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.8060842}, \"macro.dbt.truncate_relation\": {\"unique_id\": \"macro.dbt.truncate_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"truncate_relation\", \"macro_sql\": \"{% macro truncate_relation(relation) -%}\\n  {{ return(adapter.dispatch('truncate_relation', 'dbt')(relation)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__truncate_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.806554}, \"macro.dbt.default__truncate_relation\": {\"unique_id\": \"macro.dbt.default__truncate_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"default__truncate_relation\", \"macro_sql\": \"{% macro default__truncate_relation(relation) -%}\\n  {% call statement('truncate_relation') -%}\\n    truncate table {{ relation }}\\n  {%- endcall %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.806978}, \"macro.dbt.rename_relation\": {\"unique_id\": \"macro.dbt.rename_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"rename_relation\", \"macro_sql\": \"{% macro rename_relation(from_relation, to_relation) -%}\\n  {{ return(adapter.dispatch('rename_relation', 'dbt')(from_relation, to_relation)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__rename_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.8075058}, \"macro.dbt.default__rename_relation\": {\"unique_id\": \"macro.dbt.default__rename_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"default__rename_relation\", \"macro_sql\": \"{% macro default__rename_relation(from_relation, to_relation) -%}\\n  {% set target_name = adapter.quote_as_configured(to_relation.identifier, 'identifier') %}\\n  {% call statement('rename_relation') -%}\\n    alter table {{ from_relation }} rename to {{ target_name }}\\n  {%- endcall %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.808251}, \"macro.dbt.get_or_create_relation\": {\"unique_id\": \"macro.dbt.get_or_create_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"get_or_create_relation\", \"macro_sql\": \"{% macro get_or_create_relation(database, schema, identifier, type) -%}\\n  {{ return(adapter.dispatch('get_or_create_relation', 'dbt')(database, schema, identifier, type)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_or_create_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.808909}, \"macro.dbt.default__get_or_create_relation\": {\"unique_id\": \"macro.dbt.default__get_or_create_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"default__get_or_create_relation\", \"macro_sql\": \"{% macro default__get_or_create_relation(database, schema, identifier, type) %}\\n  {%- set target_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) %}\\n\\n  {% if target_relation %}\\n    {% do return([true, target_relation]) %}\\n  {% endif %}\\n\\n  {%- set new_relation = api.Relation.create(\\n      database=database,\\n      schema=schema,\\n      identifier=identifier,\\n      type=type\\n  ) -%}\\n  {% do return([false, new_relation]) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.810538}, \"macro.dbt.load_cached_relation\": {\"unique_id\": \"macro.dbt.load_cached_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"load_cached_relation\", \"macro_sql\": \"{% macro load_cached_relation(relation) %}\\n  {% do return(adapter.get_relation(\\n    database=relation.database,\\n    schema=relation.schema,\\n    identifier=relation.identifier\\n  )) -%}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.8111548}, \"macro.dbt.load_relation\": {\"unique_id\": \"macro.dbt.load_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"load_relation\", \"macro_sql\": \"{% macro load_relation(relation) %}\\n    {{ return(load_cached_relation(relation)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.load_cached_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.811518}, \"macro.dbt.drop_relation_if_exists\": {\"unique_id\": \"macro.dbt.drop_relation_if_exists\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"drop_relation_if_exists\", \"macro_sql\": \"{% macro drop_relation_if_exists(relation) %}\\n  {% if relation is not none %}\\n    {{ adapter.drop_relation(relation) }}\\n  {% endif %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.812018}, \"macro.dbt.current_timestamp\": {\"unique_id\": \"macro.dbt.current_timestamp\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/freshness.sql\", \"original_file_path\": \"macros/adapters/freshness.sql\", \"name\": \"current_timestamp\", \"macro_sql\": \"{% macro current_timestamp() -%}\\n  {{ adapter.dispatch('current_timestamp', 'dbt')() }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.813409}, \"macro.dbt.default__current_timestamp\": {\"unique_id\": \"macro.dbt.default__current_timestamp\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/freshness.sql\", \"original_file_path\": \"macros/adapters/freshness.sql\", \"name\": \"default__current_timestamp\", \"macro_sql\": \"{% macro default__current_timestamp() -%}\\n  {{ exceptions.raise_not_implemented(\\n    'current_timestamp macro not implemented for adapter '+adapter.type()) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.813792}, \"macro.dbt.collect_freshness\": {\"unique_id\": \"macro.dbt.collect_freshness\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/freshness.sql\", \"original_file_path\": \"macros/adapters/freshness.sql\", \"name\": \"collect_freshness\", \"macro_sql\": \"{% macro collect_freshness(source, loaded_at_field, filter) %}\\n  {{ return(adapter.dispatch('collect_freshness', 'dbt')(source, loaded_at_field, filter))}}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__collect_freshness\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.8143969}, \"macro.dbt.default__collect_freshness\": {\"unique_id\": \"macro.dbt.default__collect_freshness\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/freshness.sql\", \"original_file_path\": \"macros/adapters/freshness.sql\", \"name\": \"default__collect_freshness\", \"macro_sql\": \"{% macro default__collect_freshness(source, loaded_at_field, filter) %}\\n  {% call statement('collect_freshness', fetch_result=True, auto_begin=False) -%}\\n    select\\n      max({{ loaded_at_field }}) as max_loaded_at,\\n      {{ current_timestamp() }} as snapshotted_at\\n    from {{ source }}\\n    {% if filter %}\\n    where {{ filter }}\\n    {% endif %}\\n  {% endcall %}\\n  {{ return(load_result('collect_freshness').table) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\", \"macro.dbt.current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.815532}, \"macro.dbt.copy_grants\": {\"unique_id\": \"macro.dbt.copy_grants\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"name\": \"copy_grants\", \"macro_sql\": \"{% macro copy_grants() %}\\n    {{ return(adapter.dispatch('copy_grants', 'dbt')()) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__copy_grants\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.820182}, \"macro.dbt.default__copy_grants\": {\"unique_id\": \"macro.dbt.default__copy_grants\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"name\": \"default__copy_grants\", \"macro_sql\": \"{% macro default__copy_grants() %}\\n    {{ return(True) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.820483}, \"macro.dbt.support_multiple_grantees_per_dcl_statement\": {\"unique_id\": \"macro.dbt.support_multiple_grantees_per_dcl_statement\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"name\": \"support_multiple_grantees_per_dcl_statement\", \"macro_sql\": \"{% macro support_multiple_grantees_per_dcl_statement() %}\\n    {{ return(adapter.dispatch('support_multiple_grantees_per_dcl_statement', 'dbt')()) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__support_multiple_grantees_per_dcl_statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.820917}, \"macro.dbt.default__support_multiple_grantees_per_dcl_statement\": {\"unique_id\": \"macro.dbt.default__support_multiple_grantees_per_dcl_statement\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"name\": \"default__support_multiple_grantees_per_dcl_statement\", \"macro_sql\": \"\\n\\n{%- macro default__support_multiple_grantees_per_dcl_statement() -%}\\n    {{ return(True) }}\\n{%- endmacro -%}\\n\\n\\n\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.8212}, \"macro.dbt.should_revoke\": {\"unique_id\": \"macro.dbt.should_revoke\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"name\": \"should_revoke\", \"macro_sql\": \"{% macro should_revoke(existing_relation, full_refresh_mode=True) %}\\n\\n    {% if not existing_relation %}\\n        {#-- The table doesn't already exist, so no grants to copy over --#}\\n        {{ return(False) }}\\n    {% elif full_refresh_mode %}\\n        {#-- The object is being REPLACED -- whether grants are copied over depends on the value of user config --#}\\n        {{ return(copy_grants()) }}\\n    {% else %}\\n        {#-- The table is being merged/upserted/inserted -- grants will be carried over --#}\\n        {{ return(True) }}\\n    {% endif %}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.copy_grants\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.8221052}, \"macro.dbt.get_show_grant_sql\": {\"unique_id\": \"macro.dbt.get_show_grant_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"name\": \"get_show_grant_sql\", \"macro_sql\": \"{% macro get_show_grant_sql(relation) %}\\n    {{ return(adapter.dispatch(\\\"get_show_grant_sql\\\", \\\"dbt\\\")(relation)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_show_grant_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.8225951}, \"macro.dbt.default__get_show_grant_sql\": {\"unique_id\": \"macro.dbt.default__get_show_grant_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"name\": \"default__get_show_grant_sql\", \"macro_sql\": \"{% macro default__get_show_grant_sql(relation) %}\\n    show grants on {{ relation }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.822855}, \"macro.dbt.get_grant_sql\": {\"unique_id\": \"macro.dbt.get_grant_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"name\": \"get_grant_sql\", \"macro_sql\": \"{% macro get_grant_sql(relation, privilege, grantees) %}\\n    {{ return(adapter.dispatch('get_grant_sql', 'dbt')(relation, privilege, grantees)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_grant_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.823464}, \"macro.dbt.default__get_grant_sql\": {\"unique_id\": \"macro.dbt.default__get_grant_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"name\": \"default__get_grant_sql\", \"macro_sql\": \"\\n\\n{%- macro default__get_grant_sql(relation, privilege, grantees) -%}\\n    grant {{ privilege }} on {{ relation }} to {{ grantees | join(', ') }}\\n{%- endmacro -%}\\n\\n\\n\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.823967}, \"macro.dbt.get_revoke_sql\": {\"unique_id\": \"macro.dbt.get_revoke_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"name\": \"get_revoke_sql\", \"macro_sql\": \"{% macro get_revoke_sql(relation, privilege, grantees) %}\\n    {{ return(adapter.dispatch('get_revoke_sql', 'dbt')(relation, privilege, grantees)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_revoke_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.8245819}, \"macro.dbt.default__get_revoke_sql\": {\"unique_id\": \"macro.dbt.default__get_revoke_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"name\": \"default__get_revoke_sql\", \"macro_sql\": \"\\n\\n{%- macro default__get_revoke_sql(relation, privilege, grantees) -%}\\n    revoke {{ privilege }} on {{ relation }} from {{ grantees | join(', ') }}\\n{%- endmacro -%}\\n\\n\\n\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.825077}, \"macro.dbt.get_dcl_statement_list\": {\"unique_id\": \"macro.dbt.get_dcl_statement_list\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"name\": \"get_dcl_statement_list\", \"macro_sql\": \"{% macro get_dcl_statement_list(relation, grant_config, get_dcl_macro) %}\\n    {{ return(adapter.dispatch('get_dcl_statement_list', 'dbt')(relation, grant_config, get_dcl_macro)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_dcl_statement_list\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.825684}, \"macro.dbt.default__get_dcl_statement_list\": {\"unique_id\": \"macro.dbt.default__get_dcl_statement_list\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"name\": \"default__get_dcl_statement_list\", \"macro_sql\": \"\\n\\n{%- macro default__get_dcl_statement_list(relation, grant_config, get_dcl_macro) -%}\\n    {#\\n      -- Unpack grant_config into specific privileges and the set of users who need them granted/revoked.\\n      -- Depending on whether this database supports multiple grantees per statement, pass in the list of\\n      -- all grantees per privilege, or (if not) template one statement per privilege-grantee pair.\\n      -- `get_dcl_macro` will be either `get_grant_sql` or `get_revoke_sql`\\n    #}\\n    {%- set dcl_statements = [] -%}\\n    {%- for privilege, grantees in grant_config.items() %}\\n        {%- if support_multiple_grantees_per_dcl_statement() and grantees -%}\\n          {%- set dcl = get_dcl_macro(relation, privilege, grantees) -%}\\n          {%- do dcl_statements.append(dcl) -%}\\n        {%- else -%}\\n          {%- for grantee in grantees -%}\\n              {% set dcl = get_dcl_macro(relation, privilege, [grantee]) %}\\n              {%- do dcl_statements.append(dcl) -%}\\n          {% endfor -%}\\n        {%- endif -%}\\n    {%- endfor -%}\\n    {{ return(dcl_statements) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.support_multiple_grantees_per_dcl_statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.827622}, \"macro.dbt.call_dcl_statements\": {\"unique_id\": \"macro.dbt.call_dcl_statements\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"name\": \"call_dcl_statements\", \"macro_sql\": \"{% macro call_dcl_statements(dcl_statement_list) %}\\n    {{ return(adapter.dispatch(\\\"call_dcl_statements\\\", \\\"dbt\\\")(dcl_statement_list)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__call_dcl_statements\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.828118}, \"macro.dbt.default__call_dcl_statements\": {\"unique_id\": \"macro.dbt.default__call_dcl_statements\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"name\": \"default__call_dcl_statements\", \"macro_sql\": \"{% macro default__call_dcl_statements(dcl_statement_list) %}\\n    {#\\n      -- By default, supply all grant + revoke statements in a single semicolon-separated block,\\n      -- so that they're all processed together.\\n\\n      -- Some databases do not support this. Those adapters will need to override this macro\\n      -- to run each statement individually.\\n    #}\\n    {% call statement('grants') %}\\n        {% for dcl_statement in dcl_statement_list %}\\n            {{ dcl_statement }};\\n        {% endfor %}\\n    {% endcall %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.828738}, \"macro.dbt.apply_grants\": {\"unique_id\": \"macro.dbt.apply_grants\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"name\": \"apply_grants\", \"macro_sql\": \"{% macro apply_grants(relation, grant_config, should_revoke) %}\\n    {{ return(adapter.dispatch(\\\"apply_grants\\\", \\\"dbt\\\")(relation, grant_config, should_revoke)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__apply_grants\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.8293319}, \"macro.dbt.default__apply_grants\": {\"unique_id\": \"macro.dbt.default__apply_grants\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"name\": \"default__apply_grants\", \"macro_sql\": \"{% macro default__apply_grants(relation, grant_config, should_revoke=True) %}\\n    {#-- If grant_config is {} or None, this is a no-op --#}\\n    {% if grant_config %}\\n        {% if should_revoke %}\\n            {#-- We think previous grants may have carried over --#}\\n            {#-- Show current grants and calculate diffs --#}\\n            {% set current_grants_table = run_query(get_show_grant_sql(relation)) %}\\n            {% set current_grants_dict = adapter.standardize_grants_dict(current_grants_table) %}\\n            {% set needs_granting = diff_of_two_dicts(grant_config, current_grants_dict) %}\\n            {% set needs_revoking = diff_of_two_dicts(current_grants_dict, grant_config) %}\\n            {% if not (needs_granting or needs_revoking) %}\\n                {{ log('On ' ~ relation ~': All grants are in place, no revocation or granting needed.')}}\\n            {% endif %}\\n        {% else %}\\n            {#-- We don't think there's any chance of previous grants having carried over. --#}\\n            {#-- Jump straight to granting what the user has configured. --#}\\n            {% set needs_revoking = {} %}\\n            {% set needs_granting = grant_config %}\\n        {% endif %}\\n        {% if needs_granting or needs_revoking %}\\n            {% set revoke_statement_list = get_dcl_statement_list(relation, needs_revoking, get_revoke_sql) %}\\n            {% set grant_statement_list = get_dcl_statement_list(relation, needs_granting, get_grant_sql) %}\\n            {% set dcl_statement_list = revoke_statement_list + grant_statement_list %}\\n            {% if dcl_statement_list %}\\n                {{ call_dcl_statements(dcl_statement_list) }}\\n            {% endif %}\\n        {% endif %}\\n    {% endif %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.run_query\", \"macro.dbt.get_show_grant_sql\", \"macro.dbt.get_dcl_statement_list\", \"macro.dbt.call_dcl_statements\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.8324008}, \"macro.dbt.alter_column_comment\": {\"unique_id\": \"macro.dbt.alter_column_comment\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"name\": \"alter_column_comment\", \"macro_sql\": \"{% macro alter_column_comment(relation, column_dict) -%}\\n  {{ return(adapter.dispatch('alter_column_comment', 'dbt')(relation, column_dict)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__alter_column_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.834379}, \"macro.dbt.default__alter_column_comment\": {\"unique_id\": \"macro.dbt.default__alter_column_comment\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"name\": \"default__alter_column_comment\", \"macro_sql\": \"{% macro default__alter_column_comment(relation, column_dict) -%}\\n  {{ exceptions.raise_not_implemented(\\n    'alter_column_comment macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.834809}, \"macro.dbt.alter_relation_comment\": {\"unique_id\": \"macro.dbt.alter_relation_comment\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"name\": \"alter_relation_comment\", \"macro_sql\": \"{% macro alter_relation_comment(relation, relation_comment) -%}\\n  {{ return(adapter.dispatch('alter_relation_comment', 'dbt')(relation, relation_comment)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__alter_relation_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.835356}, \"macro.dbt.default__alter_relation_comment\": {\"unique_id\": \"macro.dbt.default__alter_relation_comment\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"name\": \"default__alter_relation_comment\", \"macro_sql\": \"{% macro default__alter_relation_comment(relation, relation_comment) -%}\\n  {{ exceptions.raise_not_implemented(\\n    'alter_relation_comment macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.835799}, \"macro.dbt.persist_docs\": {\"unique_id\": \"macro.dbt.persist_docs\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"name\": \"persist_docs\", \"macro_sql\": \"{% macro persist_docs(relation, model, for_relation=true, for_columns=true) -%}\\n  {{ return(adapter.dispatch('persist_docs', 'dbt')(relation, model, for_relation, for_columns)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__persist_docs\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.8365178}, \"macro.dbt.default__persist_docs\": {\"unique_id\": \"macro.dbt.default__persist_docs\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"name\": \"default__persist_docs\", \"macro_sql\": \"{% macro default__persist_docs(relation, model, for_relation, for_columns) -%}\\n  {% if for_relation and config.persist_relation_docs() and model.description %}\\n    {% do run_query(alter_relation_comment(relation, model.description)) %}\\n  {% endif %}\\n\\n  {% if for_columns and config.persist_column_docs() and model.columns %}\\n    {% do run_query(alter_column_comment(relation, model.columns)) %}\\n  {% endif %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.run_query\", \"macro.dbt.alter_relation_comment\", \"macro.dbt.alter_column_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.837826}, \"macro.dbt.get_catalog\": {\"unique_id\": \"macro.dbt.get_catalog\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"name\": \"get_catalog\", \"macro_sql\": \"{% macro get_catalog(information_schema, schemas) -%}\\n  {{ return(adapter.dispatch('get_catalog', 'dbt')(information_schema, schemas)) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_catalog\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.841973}, \"macro.dbt.default__get_catalog\": {\"unique_id\": \"macro.dbt.default__get_catalog\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"name\": \"default__get_catalog\", \"macro_sql\": \"{% macro default__get_catalog(information_schema, schemas) -%}\\n\\n  {% set typename = adapter.type() %}\\n  {% set msg -%}\\n    get_catalog not implemented for {{ typename }}\\n  {%- endset %}\\n\\n  {{ exceptions.raise_compiler_error(msg) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.842654}, \"macro.dbt.information_schema_name\": {\"unique_id\": \"macro.dbt.information_schema_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"name\": \"information_schema_name\", \"macro_sql\": \"{% macro information_schema_name(database) %}\\n  {{ return(adapter.dispatch('information_schema_name', 'dbt')(database)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__information_schema_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.843149}, \"macro.dbt.default__information_schema_name\": {\"unique_id\": \"macro.dbt.default__information_schema_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"name\": \"default__information_schema_name\", \"macro_sql\": \"{% macro default__information_schema_name(database) -%}\\n  {%- if database -%}\\n    {{ database }}.INFORMATION_SCHEMA\\n  {%- else -%}\\n    INFORMATION_SCHEMA\\n  {%- endif -%}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.8435562}, \"macro.dbt.list_schemas\": {\"unique_id\": \"macro.dbt.list_schemas\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"name\": \"list_schemas\", \"macro_sql\": \"{% macro list_schemas(database) -%}\\n  {{ return(adapter.dispatch('list_schemas', 'dbt')(database)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__list_schemas\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.8440409}, \"macro.dbt.default__list_schemas\": {\"unique_id\": \"macro.dbt.default__list_schemas\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"name\": \"default__list_schemas\", \"macro_sql\": \"{% macro default__list_schemas(database) -%}\\n  {% set sql %}\\n    select distinct schema_name\\n    from {{ information_schema_name(database) }}.SCHEMATA\\n    where catalog_name ilike '{{ database }}'\\n  {% endset %}\\n  {{ return(run_query(sql)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.information_schema_name\", \"macro.dbt.run_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.8447008}, \"macro.dbt.check_schema_exists\": {\"unique_id\": \"macro.dbt.check_schema_exists\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"name\": \"check_schema_exists\", \"macro_sql\": \"{% macro check_schema_exists(information_schema, schema) -%}\\n  {{ return(adapter.dispatch('check_schema_exists', 'dbt')(information_schema, schema)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__check_schema_exists\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.845243}, \"macro.dbt.default__check_schema_exists\": {\"unique_id\": \"macro.dbt.default__check_schema_exists\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"name\": \"default__check_schema_exists\", \"macro_sql\": \"{% macro default__check_schema_exists(information_schema, schema) -%}\\n  {% set sql -%}\\n        select count(*)\\n        from {{ information_schema.replace(information_schema_view='SCHEMATA') }}\\n        where catalog_name='{{ information_schema.database }}'\\n          and schema_name='{{ schema }}'\\n  {%- endset %}\\n  {{ return(run_query(sql)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.replace\", \"macro.dbt.run_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.846046}, \"macro.dbt.list_relations_without_caching\": {\"unique_id\": \"macro.dbt.list_relations_without_caching\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"name\": \"list_relations_without_caching\", \"macro_sql\": \"{% macro list_relations_without_caching(schema_relation) %}\\n  {{ return(adapter.dispatch('list_relations_without_caching', 'dbt')(schema_relation)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__list_relations_without_caching\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.846539}, \"macro.dbt.default__list_relations_without_caching\": {\"unique_id\": \"macro.dbt.default__list_relations_without_caching\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"name\": \"default__list_relations_without_caching\", \"macro_sql\": \"{% macro default__list_relations_without_caching(schema_relation) %}\\n  {{ exceptions.raise_not_implemented(\\n    'list_relations_without_caching macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.846957}, \"macro.dbt.get_columns_in_relation\": {\"unique_id\": \"macro.dbt.get_columns_in_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"name\": \"get_columns_in_relation\", \"macro_sql\": \"{% macro get_columns_in_relation(relation) -%}\\n  {{ return(adapter.dispatch('get_columns_in_relation', 'dbt')(relation)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_columns_in_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.851595}, \"macro.dbt.default__get_columns_in_relation\": {\"unique_id\": \"macro.dbt.default__get_columns_in_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"name\": \"default__get_columns_in_relation\", \"macro_sql\": \"{% macro default__get_columns_in_relation(relation) -%}\\n  {{ exceptions.raise_not_implemented(\\n    'get_columns_in_relation macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.852285}, \"macro.dbt.sql_convert_columns_in_relation\": {\"unique_id\": \"macro.dbt.sql_convert_columns_in_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"name\": \"sql_convert_columns_in_relation\", \"macro_sql\": \"{% macro sql_convert_columns_in_relation(table) -%}\\n  {% set columns = [] %}\\n  {% for row in table %}\\n    {% do columns.append(api.Column(*row)) %}\\n  {% endfor %}\\n  {{ return(columns) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.853091}, \"macro.dbt.get_columns_in_query\": {\"unique_id\": \"macro.dbt.get_columns_in_query\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"name\": \"get_columns_in_query\", \"macro_sql\": \"{% macro get_columns_in_query(select_sql) -%}\\n  {{ return(adapter.dispatch('get_columns_in_query', 'dbt')(select_sql)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_columns_in_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.853559}, \"macro.dbt.default__get_columns_in_query\": {\"unique_id\": \"macro.dbt.default__get_columns_in_query\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"name\": \"default__get_columns_in_query\", \"macro_sql\": \"{% macro default__get_columns_in_query(select_sql) %}\\n    {% call statement('get_columns_in_query', fetch_result=True, auto_begin=False) -%}\\n        select * from (\\n            {{ select_sql }}\\n        ) as __dbt_sbq\\n        where false\\n        limit 0\\n    {% endcall %}\\n\\n    {{ return(load_result('get_columns_in_query').table.columns | map(attribute='name') | list) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.854439}, \"macro.dbt.alter_column_type\": {\"unique_id\": \"macro.dbt.alter_column_type\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"name\": \"alter_column_type\", \"macro_sql\": \"{% macro alter_column_type(relation, column_name, new_column_type) -%}\\n  {{ return(adapter.dispatch('alter_column_type', 'dbt')(relation, column_name, new_column_type)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__alter_column_type\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.85503}, \"macro.dbt.default__alter_column_type\": {\"unique_id\": \"macro.dbt.default__alter_column_type\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"name\": \"default__alter_column_type\", \"macro_sql\": \"{% macro default__alter_column_type(relation, column_name, new_column_type) -%}\\n  {#\\n    1. Create a new column (w/ temp name and correct type)\\n    2. Copy data over to it\\n    3. Drop the existing column (cascade!)\\n    4. Rename the new column to existing column\\n  #}\\n  {%- set tmp_column = column_name + \\\"__dbt_alter\\\" -%}\\n\\n  {% call statement('alter_column_type') %}\\n    alter table {{ relation }} add column {{ adapter.quote(tmp_column) }} {{ new_column_type }};\\n    update {{ relation }} set {{ adapter.quote(tmp_column) }} = {{ adapter.quote(column_name) }};\\n    alter table {{ relation }} drop column {{ adapter.quote(column_name) }} cascade;\\n    alter table {{ relation }} rename column {{ adapter.quote(tmp_column) }} to {{ adapter.quote(column_name) }}\\n  {% endcall %}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.856618}, \"macro.dbt.alter_relation_add_remove_columns\": {\"unique_id\": \"macro.dbt.alter_relation_add_remove_columns\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"name\": \"alter_relation_add_remove_columns\", \"macro_sql\": \"{% macro alter_relation_add_remove_columns(relation, add_columns = none, remove_columns = none) -%}\\n  {{ return(adapter.dispatch('alter_relation_add_remove_columns', 'dbt')(relation, add_columns, remove_columns)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__alter_relation_add_remove_columns\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.8572822}, \"macro.dbt.default__alter_relation_add_remove_columns\": {\"unique_id\": \"macro.dbt.default__alter_relation_add_remove_columns\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"name\": \"default__alter_relation_add_remove_columns\", \"macro_sql\": \"{% macro default__alter_relation_add_remove_columns(relation, add_columns, remove_columns) %}\\n\\n  {% if add_columns is none %}\\n    {% set add_columns = [] %}\\n  {% endif %}\\n  {% if remove_columns is none %}\\n    {% set remove_columns = [] %}\\n  {% endif %}\\n\\n  {% set sql -%}\\n\\n     alter {{ relation.type }} {{ relation }}\\n\\n            {% for column in add_columns %}\\n               add column {{ column.name }} {{ column.data_type }}{{ ',' if not loop.last }}\\n            {% endfor %}{{ ',' if add_columns and remove_columns }}\\n\\n            {% for column in remove_columns %}\\n                drop column {{ column.name }}{{ ',' if not loop.last }}\\n            {% endfor %}\\n\\n  {%- endset -%}\\n\\n  {% do run_query(sql) %}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.run_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.8593512}, \"macro.dbt.test_unique\": {\"unique_id\": \"macro.dbt.test_unique\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"tests/generic/builtin.sql\", \"original_file_path\": \"tests/generic/builtin.sql\", \"name\": \"test_unique\", \"macro_sql\": \"{% test unique(model, column_name) %}\\n    {% set macro = adapter.dispatch('test_unique', 'dbt') %}\\n    {{ macro(model, column_name) }}\\n{% endtest %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__test_unique\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.87712}, \"macro.dbt.test_not_null\": {\"unique_id\": \"macro.dbt.test_not_null\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"tests/generic/builtin.sql\", \"original_file_path\": \"tests/generic/builtin.sql\", \"name\": \"test_not_null\", \"macro_sql\": \"{% test not_null(model, column_name) %}\\n    {% set macro = adapter.dispatch('test_not_null', 'dbt') %}\\n    {{ macro(model, column_name) }}\\n{% endtest %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__test_not_null\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.877723}, \"macro.dbt.test_accepted_values\": {\"unique_id\": \"macro.dbt.test_accepted_values\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"tests/generic/builtin.sql\", \"original_file_path\": \"tests/generic/builtin.sql\", \"name\": \"test_accepted_values\", \"macro_sql\": \"{% test accepted_values(model, column_name, values, quote=True) %}\\n    {% set macro = adapter.dispatch('test_accepted_values', 'dbt') %}\\n    {{ macro(model, column_name, values, quote) }}\\n{% endtest %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__test_accepted_values\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.878474}, \"macro.dbt.test_relationships\": {\"unique_id\": \"macro.dbt.test_relationships\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"tests/generic/builtin.sql\", \"original_file_path\": \"tests/generic/builtin.sql\", \"name\": \"test_relationships\", \"macro_sql\": \"{% test relationships(model, column_name, to, field) %}\\n    {% set macro = adapter.dispatch('test_relationships', 'dbt') %}\\n    {{ macro(model, column_name, to, field) }}\\n{% endtest %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__test_relationships\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1663058262.879189}}, \"docs\": {\"dbt.__overview__\": {\"unique_id\": \"dbt.__overview__\", \"package_name\": \"dbt\", \"root_path\": \"/Users/jerco/dev/scratch/testy/env/lib/python3.9/site-packages/dbt/include/global_project\", \"path\": \"overview.md\", \"original_file_path\": \"docs/overview.md\", \"name\": \"__overview__\", \"block_contents\": \"### Welcome!\\n\\nWelcome to the auto-generated documentation for your dbt project!\\n\\n### Navigation\\n\\nYou can use the `Project` and `Database` navigation tabs on the left side of the window to explore the models\\nin your project.\\n\\n#### Project Tab\\nThe `Project` tab mirrors the directory structure of your dbt project. In this tab, you can see all of the\\nmodels defined in your dbt project, as well as models imported from dbt packages.\\n\\n#### Database Tab\\nThe `Database` tab also exposes your models, but in a format that looks more like a database explorer. This view\\nshows relations (tables and views) grouped into database schemas. Note that ephemeral models are _not_ shown\\nin this interface, as they do not exist in the database.\\n\\n### Graph Exploration\\nYou can click the blue icon on the bottom-right corner of the page to view the lineage graph of your models.\\n\\nOn model pages, you'll see the immediate parents and children of the model you're exploring. By clicking the `Expand`\\nbutton at the top-right of this lineage pane, you'll be able to see all of the models that are used to build,\\nor are built from, the model you're exploring.\\n\\nOnce expanded, you'll be able to use the `--select` and `--exclude` model selection syntax to filter the\\nmodels in the graph. For more information on model selection, check out the [dbt docs](https://docs.getdbt.com/docs/model-selection-syntax).\\n\\nNote that you can also right-click on models to interactively filter and explore the graph.\\n\\n---\\n\\n### More information\\n\\n- [What is dbt](https://docs.getdbt.com/docs/introduction)?\\n- Read the [dbt viewpoint](https://docs.getdbt.com/docs/viewpoint)\\n- [Installation](https://docs.getdbt.com/docs/installation)\\n- Join the [dbt Community](https://www.getdbt.com/community/) for questions and discussion\"}}, \"exposures\": {}, \"metrics\": {\"metric.test.my_metric\": {\"fqn\": [\"test\", \"my_metric\"], \"unique_id\": \"metric.test.my_metric\", \"package_name\": \"test\", \"root_path\": \"/Users/jerco/dev/scratch/testy\", \"path\": \"metric.yml\", \"original_file_path\": \"models/metric.yml\", \"name\": \"my_metric\", \"description\": \"\", \"label\": \"Count records\", \"type\": \"count\", \"sql\": \"*\", \"timestamp\": \"updated_at\", \"filters\": [], \"time_grains\": [\"day\"], \"dimensions\": [], \"model\": \"ref('my_model')\", \"model_unique_id\": null, \"resource_type\": \"metric\", \"meta\": {}, \"tags\": [], \"sources\": [], \"depends_on\": {\"macros\": [], \"nodes\": [\"model.test.my_model\"]}, \"refs\": [[\"my_model\"]], \"metrics\": [], \"created_at\": 1663058517.2551522}}, \"selectors\": {}, \"disabled\": {}, \"parent_map\": {\"model.test.my_model\": [], \"metric.test.my_metric\": [\"model.test.my_model\"]}, \"child_map\": {\"model.test.my_model\": [\"metric.test.my_metric\"], \"metric.test.my_metric\": []}}\n"
  },
  {
    "path": "tests/functional/artifacts/data/state/v7/manifest.json",
    "content": "{\"metadata\": {\"dbt_schema_version\": \"https://schemas.getdbt.com/dbt/manifest/v7.json\", \"dbt_version\": \"1.3.2\", \"generated_at\": \"2023-02-13T21:34:36.870255Z\", \"invocation_id\": \"96c0aa43-0ccd-4420-a50c-05c0f22a0df1\", \"env\": {}, \"project_id\": \"098f6bcd4621d373cade4e832627b4f6\", \"user_id\": null, \"send_anonymous_usage_stats\": false, \"adapter_type\": \"postgres\"}, \"nodes\": {\"model.test.my_model\": {\"resource_type\": \"model\", \"depends_on\": {\"macros\": [], \"nodes\": []}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"materialized\": \"view\", \"incremental_strategy\": null, \"persist_docs\": {}, \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": null, \"on_schema_change\": \"ignore\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"post-hook\": [], \"pre-hook\": []}, \"database\": \"dbt\", \"schema\": \"test16763240740000063267_test_previous_version_state\", \"fqn\": [\"test\", \"my_model\"], \"unique_id\": \"model.test.my_model\", \"raw_code\": \"select 1 as id\", \"language\": \"sql\", \"package_name\": \"test\", \"root_path\": \"/private/var/folders/qt/vw8wqdgx4w381wh14b9y25m40000gn/T/pytest-of-gerda/pytest-126/project0\", \"path\": \"my_model.sql\", \"original_file_path\": \"models/my_model.sql\", \"name\": \"my_model\", \"alias\": \"my_model\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"2b9123e04ab8bb798f7c565afdc3ee0e56fcd66b4bfbdb435b4891c878d947c5\"}, \"tags\": [], \"refs\": [], \"sources\": [], \"metrics\": [], \"description\": \"Example model\", \"columns\": {\"id\": {\"name\": \"id\", \"description\": \"\", \"meta\": {}, \"data_type\": null, \"quote\": null, \"tags\": []}}, \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": \"test://models/schema.yml\", \"compiled_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {}, \"created_at\": 1676324075.566336}, \"snapshot.test.snapshot_seed\": {\"resource_type\": \"snapshot\", \"depends_on\": {\"macros\": [], \"nodes\": [\"seed.test.my_seed\"]}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"materialized\": \"snapshot\", \"incremental_strategy\": null, \"persist_docs\": {}, \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": \"id\", \"on_schema_change\": \"ignore\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"strategy\": \"check\", \"target_schema\": \"test16763240740000063267_test_previous_version_state\", \"target_database\": null, \"updated_at\": null, \"check_cols\": \"all\", \"post-hook\": [], \"pre-hook\": []}, \"database\": \"dbt\", \"schema\": \"test16763240740000063267_test_previous_version_state\", \"fqn\": [\"test\", \"snapshot_seed\", \"snapshot_seed\"], \"unique_id\": \"snapshot.test.snapshot_seed\", \"raw_code\": \"\\n{{\\n    config(\\n      unique_key='id',\\n      strategy='check',\\n      check_cols='all',\\n      target_schema=schema,\\n    )\\n}}\\nselect * from {{ ref('my_seed') }}\\n\", \"language\": \"sql\", \"package_name\": \"test\", \"root_path\": \"/private/var/folders/qt/vw8wqdgx4w381wh14b9y25m40000gn/T/pytest-of-gerda/pytest-126/project0\", \"path\": \"snapshot_seed.sql\", \"original_file_path\": \"snapshots/snapshot_seed.sql\", \"name\": \"snapshot_seed\", \"alias\": \"snapshot_seed\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"00c13c306831070996970605fbc4c901aa456e1ed1c028725a932e4e6a4ffb0a\"}, \"tags\": [], \"refs\": [[\"my_seed\"]], \"sources\": [], \"metrics\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"compiled_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {\"unique_key\": \"id\", \"strategy\": \"check\", \"check_cols\": \"all\", \"target_schema\": \"test16763240740000063267_test_previous_version_state\"}, \"created_at\": 1676324075.423856}, \"analysis.test.a\": {\"resource_type\": \"analysis\", \"depends_on\": {\"macros\": [], \"nodes\": []}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"materialized\": \"view\", \"incremental_strategy\": null, \"persist_docs\": {}, \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": null, \"on_schema_change\": \"ignore\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"post-hook\": [], \"pre-hook\": []}, \"database\": \"dbt\", \"schema\": \"test16763240740000063267_test_previous_version_state\", \"fqn\": [\"test\", \"analysis\", \"a\"], \"unique_id\": \"analysis.test.a\", \"raw_code\": \"select 4 as id\", \"language\": \"sql\", \"package_name\": \"test\", \"root_path\": \"/private/var/folders/qt/vw8wqdgx4w381wh14b9y25m40000gn/T/pytest-of-gerda/pytest-126/project0\", \"path\": \"analysis/a.sql\", \"original_file_path\": \"analyses/a.sql\", \"name\": \"a\", \"alias\": \"a\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"bd1ee600e4e80d03f488fee52a66e8d51b5be2b98acc20df1cf8be4670d86ae5\"}, \"tags\": [], \"refs\": [], \"sources\": [], \"metrics\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"compiled_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {}, \"created_at\": 1676324075.453177}, \"test.test.just_my\": {\"resource_type\": \"test\", \"depends_on\": {\"macros\": [], \"nodes\": [\"model.test.my_model\"]}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": \"dbt_test__audit\", \"database\": null, \"tags\": [\"data_test_tag\"], \"meta\": {}, \"materialized\": \"test\", \"severity\": \"ERROR\", \"store_failures\": null, \"where\": null, \"limit\": null, \"fail_calc\": \"count(*)\", \"warn_if\": \"!= 0\", \"error_if\": \"!= 0\"}, \"database\": \"dbt\", \"schema\": \"test16763240740000063267_test_previous_version_state_dbt_test__audit\", \"fqn\": [\"test\", \"just_my\"], \"unique_id\": \"test.test.just_my\", \"raw_code\": \"{{ config(tags = ['data_test_tag']) }}\\n\\nselect * from {{ ref('my_model') }}\\nwhere false\", \"language\": \"sql\", \"package_name\": \"test\", \"root_path\": \"/private/var/folders/qt/vw8wqdgx4w381wh14b9y25m40000gn/T/pytest-of-gerda/pytest-126/project0\", \"path\": \"just_my.sql\", \"original_file_path\": \"tests/just_my.sql\", \"name\": \"just_my\", \"alias\": \"just_my\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"f30b7a814e0e3761d1a8042aa40d658d6c33affb28cd92782b0f56559c414fd8\"}, \"tags\": [\"data_test_tag\"], \"refs\": [[\"my_model\"]], \"sources\": [], \"metrics\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"compiled_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {\"tags\": [\"data_test_tag\"]}, \"created_at\": 1676324075.520421}, \"seed.test.my_seed\": {\"resource_type\": \"seed\", \"depends_on\": {\"macros\": [], \"nodes\": []}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"materialized\": \"seed\", \"incremental_strategy\": null, \"persist_docs\": {}, \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": null, \"on_schema_change\": \"ignore\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"quote_columns\": null, \"post-hook\": [], \"pre-hook\": []}, \"database\": \"dbt\", \"schema\": \"test16763240740000063267_test_previous_version_state\", \"fqn\": [\"test\", \"my_seed\"], \"unique_id\": \"seed.test.my_seed\", \"raw_code\": \"\", \"language\": \"sql\", \"package_name\": \"test\", \"root_path\": \"/private/var/folders/qt/vw8wqdgx4w381wh14b9y25m40000gn/T/pytest-of-gerda/pytest-126/project0\", \"path\": \"my_seed.csv\", \"original_file_path\": \"seeds/my_seed.csv\", \"name\": \"my_seed\", \"alias\": \"my_seed\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"22697c9b76d73a6c7561554ddb2ce101428ea2737ba8dc500d52ebcfdcfcfc13\"}, \"tags\": [], \"refs\": [], \"sources\": [], \"metrics\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"compiled_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {}, \"created_at\": 1676324075.542836}, \"test.test.not_null_my_model_id.43e0e9183a\": {\"test_metadata\": {\"name\": \"not_null\", \"kwargs\": {\"column_name\": \"id\", \"model\": \"{{ get_where_subquery(ref('my_model')) }}\"}, \"namespace\": null}, \"resource_type\": \"test\", \"depends_on\": {\"macros\": [\"macro.dbt.test_not_null\"], \"nodes\": [\"model.test.my_model\"]}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": \"dbt_test__audit\", \"database\": null, \"tags\": [], \"meta\": {}, \"materialized\": \"test\", \"severity\": \"ERROR\", \"store_failures\": null, \"where\": null, \"limit\": null, \"fail_calc\": \"count(*)\", \"warn_if\": \"!= 0\", \"error_if\": \"!= 0\"}, \"database\": \"dbt\", \"schema\": \"test16763240740000063267_test_previous_version_state_dbt_test__audit\", \"fqn\": [\"test\", \"not_null_my_model_id\"], \"unique_id\": \"test.test.not_null_my_model_id.43e0e9183a\", \"raw_code\": \"{{ test_not_null(**_dbt_generic_test_kwargs) }}\", \"language\": \"sql\", \"package_name\": \"test\", \"root_path\": \"/private/var/folders/qt/vw8wqdgx4w381wh14b9y25m40000gn/T/pytest-of-gerda/pytest-126/project0\", \"path\": \"not_null_my_model_id.sql\", \"original_file_path\": \"models/schema.yml\", \"name\": \"not_null_my_model_id\", \"alias\": \"not_null_my_model_id\", \"checksum\": {\"name\": \"none\", \"checksum\": \"\"}, \"tags\": [], \"refs\": [[\"my_model\"]], \"sources\": [], \"metrics\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"compiled_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {}, \"created_at\": 1676324075.575407, \"column_name\": \"id\", \"file_key_name\": \"models.my_model\"}, \"test.test.check_nothing_my_model_.d5a5e66110\": {\"test_metadata\": {\"name\": \"check_nothing\", \"kwargs\": {\"model\": \"{{ get_where_subquery(ref('my_model')) }}\"}, \"namespace\": null}, \"resource_type\": \"test\", \"depends_on\": {\"macros\": [\"macro.test.test_check_nothing\", \"macro.dbt.get_where_subquery\"], \"nodes\": [\"model.test.my_model\"]}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": \"dbt_test__audit\", \"database\": null, \"tags\": [], \"meta\": {}, \"materialized\": \"test\", \"severity\": \"ERROR\", \"store_failures\": null, \"where\": null, \"limit\": null, \"fail_calc\": \"count(*)\", \"warn_if\": \"!= 0\", \"error_if\": \"!= 0\"}, \"database\": \"dbt\", \"schema\": \"test16763240740000063267_test_previous_version_state_dbt_test__audit\", \"fqn\": [\"test\", \"check_nothing_my_model_\"], \"unique_id\": \"test.test.check_nothing_my_model_.d5a5e66110\", \"raw_code\": \"{{ test_check_nothing(**_dbt_generic_test_kwargs) }}\", \"language\": \"sql\", \"package_name\": \"test\", \"root_path\": \"/private/var/folders/qt/vw8wqdgx4w381wh14b9y25m40000gn/T/pytest-of-gerda/pytest-126/project0\", \"path\": \"check_nothing_my_model_.sql\", \"original_file_path\": \"models/schema.yml\", \"name\": \"check_nothing_my_model_\", \"alias\": \"check_nothing_my_model_\", \"checksum\": {\"name\": \"none\", \"checksum\": \"\"}, \"tags\": [], \"refs\": [[\"my_model\"]], \"sources\": [], \"metrics\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"compiled_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {}, \"created_at\": 1676324075.577614, \"column_name\": null, \"file_key_name\": \"models.my_model\"}}, \"sources\": {\"source.test.my_source.my_table\": {\"fqn\": [\"test\", \"my_source\", \"my_table\"], \"database\": \"dbt\", \"schema\": \"my_source\", \"unique_id\": \"source.test.my_source.my_table\", \"package_name\": \"test\", \"root_path\": \"/private/var/folders/qt/vw8wqdgx4w381wh14b9y25m40000gn/T/pytest-of-gerda/pytest-126/project0\", \"path\": \"models/schema.yml\", \"original_file_path\": \"models/schema.yml\", \"name\": \"my_table\", \"source_name\": \"my_source\", \"source_description\": \"My source\", \"loader\": \"a_loader\", \"identifier\": \"my_seed\", \"resource_type\": \"source\", \"quoting\": {\"database\": null, \"schema\": null, \"identifier\": null, \"column\": null}, \"loaded_at_field\": null, \"freshness\": {\"warn_after\": {\"count\": null, \"period\": null}, \"error_after\": {\"count\": null, \"period\": null}, \"filter\": null}, \"external\": null, \"description\": \"My table\", \"columns\": {}, \"meta\": {}, \"source_meta\": {}, \"tags\": [], \"config\": {\"enabled\": true}, \"patch_path\": null, \"unrendered_config\": {}, \"relation_name\": \"\\\"dbt\\\".\\\"my_source\\\".\\\"my_seed\\\"\", \"created_at\": 1676324075.624893}}, \"macros\": {\"macro.test.test_check_nothing\": {\"unique_id\": \"macro.test.test_check_nothing\", \"package_name\": \"test\", \"root_path\": \"/private/var/folders/qt/vw8wqdgx4w381wh14b9y25m40000gn/T/pytest-of-gerda/pytest-126/project0\", \"path\": \"macros/dummy_test.sql\", \"original_file_path\": \"macros/dummy_test.sql\", \"name\": \"test_check_nothing\", \"macro_sql\": \"{% test check_nothing(model) %}\\n-- a silly test to make sure that table-level tests show up in the manifest\\n-- without a column_name field\\n\\nselect 0\\n\\n{% endtest %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.712246, \"supported_languages\": null}, \"macro.test.test_disabled_check_nothing\": {\"unique_id\": \"macro.test.test_disabled_check_nothing\", \"package_name\": \"test\", \"root_path\": \"/private/var/folders/qt/vw8wqdgx4w381wh14b9y25m40000gn/T/pytest-of-gerda/pytest-126/project0\", \"path\": \"macros/disabled_dummy_test.sql\", \"original_file_path\": \"macros/disabled_dummy_test.sql\", \"name\": \"test_disabled_check_nothing\", \"macro_sql\": \"{% test disabled_check_nothing(model) %}\\n-- a silly test to make sure that table-level tests show up in the manifest\\n-- without a column_name field\\n\\n{{ config(enabled=False) }}\\nselect 0\\n\\n{% endtest %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.713166, \"supported_languages\": null}, \"macro.test.do_nothing\": {\"unique_id\": \"macro.test.do_nothing\", \"package_name\": \"test\", \"root_path\": \"/private/var/folders/qt/vw8wqdgx4w381wh14b9y25m40000gn/T/pytest-of-gerda/pytest-126/project0\", \"path\": \"macros/do_nothing.sql\", \"original_file_path\": \"macros/do_nothing.sql\", \"name\": \"do_nothing\", \"macro_sql\": \"{% macro do_nothing(foo2, bar2) %}\\n    select\\n        '{{ foo2 }}' as foo2,\\n        '{{ bar2 }}' as bar2\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.7140381, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__current_timestamp\": {\"unique_id\": \"macro.dbt_postgres.postgres__current_timestamp\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/gerda/FTA/dbt/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/timestamps.sql\", \"original_file_path\": \"macros/timestamps.sql\", \"name\": \"postgres__current_timestamp\", \"macro_sql\": \"{% macro postgres__current_timestamp() -%}\\n    now()\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.714999, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__snapshot_string_as_time\": {\"unique_id\": \"macro.dbt_postgres.postgres__snapshot_string_as_time\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/gerda/FTA/dbt/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/timestamps.sql\", \"original_file_path\": \"macros/timestamps.sql\", \"name\": \"postgres__snapshot_string_as_time\", \"macro_sql\": \"{% macro postgres__snapshot_string_as_time(timestamp) -%}\\n    {%- set result = \\\"'\\\" ~ timestamp ~ \\\"'::timestamp without time zone\\\" -%}\\n    {{ return(result) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.715521, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__snapshot_get_time\": {\"unique_id\": \"macro.dbt_postgres.postgres__snapshot_get_time\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/gerda/FTA/dbt/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/timestamps.sql\", \"original_file_path\": \"macros/timestamps.sql\", \"name\": \"postgres__snapshot_get_time\", \"macro_sql\": \"{% macro postgres__snapshot_get_time() -%}\\n  {{ current_timestamp() }}::timestamp without time zone\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.7158241, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__current_timestamp_backcompat\": {\"unique_id\": \"macro.dbt_postgres.postgres__current_timestamp_backcompat\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/gerda/FTA/dbt/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/timestamps.sql\", \"original_file_path\": \"macros/timestamps.sql\", \"name\": \"postgres__current_timestamp_backcompat\", \"macro_sql\": \"{% macro postgres__current_timestamp_backcompat() %}\\n    current_timestamp::{{ type_timestamp() }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.type_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.716109, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__current_timestamp_in_utc_backcompat\": {\"unique_id\": \"macro.dbt_postgres.postgres__current_timestamp_in_utc_backcompat\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/gerda/FTA/dbt/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/timestamps.sql\", \"original_file_path\": \"macros/timestamps.sql\", \"name\": \"postgres__current_timestamp_in_utc_backcompat\", \"macro_sql\": \"{% macro postgres__current_timestamp_in_utc_backcompat() %}\\n    (current_timestamp at time zone 'utc')::{{ type_timestamp() }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.type_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.7164018, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_catalog\": {\"unique_id\": \"macro.dbt_postgres.postgres__get_catalog\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/gerda/FTA/dbt/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/catalog.sql\", \"original_file_path\": \"macros/catalog.sql\", \"name\": \"postgres__get_catalog\", \"macro_sql\": \"{% macro postgres__get_catalog(information_schema, schemas) -%}\\n\\n  {%- call statement('catalog', fetch_result=True) -%}\\n    {#\\n      If the user has multiple databases set and the first one is wrong, this will fail.\\n      But we won't fail in the case where there are multiple quoting-difference-only dbs, which is better.\\n    #}\\n    {% set database = information_schema.database %}\\n    {{ adapter.verify_database(database) }}\\n\\n    select\\n        '{{ database }}' as table_database,\\n        sch.nspname as table_schema,\\n        tbl.relname as table_name,\\n        case tbl.relkind\\n            when 'v' then 'VIEW'\\n            else 'BASE TABLE'\\n        end as table_type,\\n        tbl_desc.description as table_comment,\\n        col.attname as column_name,\\n        col.attnum as column_index,\\n        pg_catalog.format_type(col.atttypid, col.atttypmod) as column_type,\\n        col_desc.description as column_comment,\\n        pg_get_userbyid(tbl.relowner) as table_owner\\n\\n    from pg_catalog.pg_namespace sch\\n    join pg_catalog.pg_class tbl on tbl.relnamespace = sch.oid\\n    join pg_catalog.pg_attribute col on col.attrelid = tbl.oid\\n    left outer join pg_catalog.pg_description tbl_desc on (tbl_desc.objoid = tbl.oid and tbl_desc.objsubid = 0)\\n    left outer join pg_catalog.pg_description col_desc on (col_desc.objoid = tbl.oid and col_desc.objsubid = col.attnum)\\n\\n    where (\\n        {%- for schema in schemas -%}\\n          upper(sch.nspname) = upper('{{ schema }}'){%- if not loop.last %} or {% endif -%}\\n        {%- endfor -%}\\n      )\\n      and not pg_is_other_temp_schema(sch.oid) -- not a temporary schema belonging to another session\\n      and tbl.relpersistence in ('p', 'u') -- [p]ermanent table or [u]nlogged table. Exclude [t]emporary tables\\n      and tbl.relkind in ('r', 'v', 'f', 'p') -- o[r]dinary table, [v]iew, [f]oreign table, [p]artitioned table. Other values are [i]ndex, [S]equence, [c]omposite type, [t]OAST table, [m]aterialized view\\n      and col.attnum > 0 -- negative numbers are used for system columns such as oid\\n      and not col.attisdropped -- column as not been dropped\\n\\n    order by\\n        sch.nspname,\\n        tbl.relname,\\n        col.attnum\\n\\n  {%- endcall -%}\\n\\n  {{ return(load_result('catalog').table) }}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.719163, \"supported_languages\": null}, \"macro.dbt_postgres.postgres_get_relations\": {\"unique_id\": \"macro.dbt_postgres.postgres_get_relations\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/gerda/FTA/dbt/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/relations.sql\", \"original_file_path\": \"macros/relations.sql\", \"name\": \"postgres_get_relations\", \"macro_sql\": \"{% macro postgres_get_relations () -%}\\n\\n  {#\\n      -- in pg_depend, objid is the dependent, refobjid is the referenced object\\n      --  > a pg_depend entry indicates that the referenced object cannot be\\n      --  > dropped without also dropping the dependent object.\\n  #}\\n\\n  {%- call statement('relations', fetch_result=True) -%}\\n    with relation as (\\n        select\\n            pg_rewrite.ev_class as class,\\n            pg_rewrite.oid as id\\n        from pg_rewrite\\n    ),\\n    class as (\\n        select\\n            oid as id,\\n            relname as name,\\n            relnamespace as schema,\\n            relkind as kind\\n        from pg_class\\n    ),\\n    dependency as (\\n        select distinct\\n            pg_depend.objid as id,\\n            pg_depend.refobjid as ref\\n        from pg_depend\\n    ),\\n    schema as (\\n        select\\n            pg_namespace.oid as id,\\n            pg_namespace.nspname as name\\n        from pg_namespace\\n        where nspname != 'information_schema' and nspname not like 'pg\\\\_%'\\n    ),\\n    referenced as (\\n        select\\n            relation.id AS id,\\n            referenced_class.name ,\\n            referenced_class.schema ,\\n            referenced_class.kind\\n        from relation\\n        join class as referenced_class on relation.class=referenced_class.id\\n        where referenced_class.kind in ('r', 'v')\\n    ),\\n    relationships as (\\n        select\\n            referenced.name as referenced_name,\\n            referenced.schema as referenced_schema_id,\\n            dependent_class.name as dependent_name,\\n            dependent_class.schema as dependent_schema_id,\\n            referenced.kind as kind\\n        from referenced\\n        join dependency on referenced.id=dependency.id\\n        join class as dependent_class on dependency.ref=dependent_class.id\\n        where\\n            (referenced.name != dependent_class.name or\\n             referenced.schema != dependent_class.schema)\\n    )\\n\\n    select\\n        referenced_schema.name as referenced_schema,\\n        relationships.referenced_name as referenced_name,\\n        dependent_schema.name as dependent_schema,\\n        relationships.dependent_name as dependent_name\\n    from relationships\\n    join schema as dependent_schema on relationships.dependent_schema_id=dependent_schema.id\\n    join schema as referenced_schema on relationships.referenced_schema_id=referenced_schema.id\\n    group by referenced_schema, referenced_name, dependent_schema, dependent_name\\n    order by referenced_schema, referenced_name, dependent_schema, dependent_name;\\n\\n  {%- endcall -%}\\n\\n  {{ return(load_result('relations').table) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.7208161, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__create_table_as\": {\"unique_id\": \"macro.dbt_postgres.postgres__create_table_as\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/gerda/FTA/dbt/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__create_table_as\", \"macro_sql\": \"{% macro postgres__create_table_as(temporary, relation, sql) -%}\\n  {%- set unlogged = config.get('unlogged', default=false) -%}\\n  {%- set sql_header = config.get('sql_header', none) -%}\\n\\n  {{ sql_header if sql_header is not none }}\\n\\n  create {% if temporary -%}\\n    temporary\\n  {%- elif unlogged -%}\\n    unlogged\\n  {%- endif %} table {{ relation }}\\n  as (\\n    {{ sql }}\\n  );\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.733047, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_create_index_sql\": {\"unique_id\": \"macro.dbt_postgres.postgres__get_create_index_sql\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/gerda/FTA/dbt/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__get_create_index_sql\", \"macro_sql\": \"{% macro postgres__get_create_index_sql(relation, index_dict) -%}\\n  {%- set index_config = adapter.parse_index(index_dict) -%}\\n  {%- set comma_separated_columns = \\\", \\\".join(index_config.columns) -%}\\n  {%- set index_name = index_config.render(relation) -%}\\n\\n  create {% if index_config.unique -%}\\n    unique\\n  {%- endif %} index if not exists\\n  \\\"{{ index_name }}\\\"\\n  on {{ relation }} {% if index_config.type -%}\\n    using {{ index_config.type }}\\n  {%- endif %}\\n  ({{ comma_separated_columns }});\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.734891, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__create_schema\": {\"unique_id\": \"macro.dbt_postgres.postgres__create_schema\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/gerda/FTA/dbt/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__create_schema\", \"macro_sql\": \"{% macro postgres__create_schema(relation) -%}\\n  {% if relation.database -%}\\n    {{ adapter.verify_database(relation.database) }}\\n  {%- endif -%}\\n  {%- call statement('create_schema') -%}\\n    create schema if not exists {{ relation.without_identifier().include(database=False) }}\\n  {%- endcall -%}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.735866, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__drop_schema\": {\"unique_id\": \"macro.dbt_postgres.postgres__drop_schema\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/gerda/FTA/dbt/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__drop_schema\", \"macro_sql\": \"{% macro postgres__drop_schema(relation) -%}\\n  {% if relation.database -%}\\n    {{ adapter.verify_database(relation.database) }}\\n  {%- endif -%}\\n  {%- call statement('drop_schema') -%}\\n    drop schema if exists {{ relation.without_identifier().include(database=False) }} cascade\\n  {%- endcall -%}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.736712, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_columns_in_relation\": {\"unique_id\": \"macro.dbt_postgres.postgres__get_columns_in_relation\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/gerda/FTA/dbt/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__get_columns_in_relation\", \"macro_sql\": \"{% macro postgres__get_columns_in_relation(relation) -%}\\n  {% call statement('get_columns_in_relation', fetch_result=True) %}\\n      select\\n          column_name,\\n          data_type,\\n          character_maximum_length,\\n          numeric_precision,\\n          numeric_scale\\n\\n      from {{ relation.information_schema('columns') }}\\n      where table_name = '{{ relation.identifier }}'\\n        {% if relation.schema %}\\n        and table_schema = '{{ relation.schema }}'\\n        {% endif %}\\n      order by ordinal_position\\n\\n  {% endcall %}\\n  {% set table = load_result('get_columns_in_relation').table %}\\n  {{ return(sql_convert_columns_in_relation(table)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\", \"macro.dbt.sql_convert_columns_in_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.738183, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__list_relations_without_caching\": {\"unique_id\": \"macro.dbt_postgres.postgres__list_relations_without_caching\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/gerda/FTA/dbt/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__list_relations_without_caching\", \"macro_sql\": \"{% macro postgres__list_relations_without_caching(schema_relation) %}\\n  {% call statement('list_relations_without_caching', fetch_result=True) -%}\\n    select\\n      '{{ schema_relation.database }}' as database,\\n      tablename as name,\\n      schemaname as schema,\\n      'table' as type\\n    from pg_tables\\n    where schemaname ilike '{{ schema_relation.schema }}'\\n    union all\\n    select\\n      '{{ schema_relation.database }}' as database,\\n      viewname as name,\\n      schemaname as schema,\\n      'view' as type\\n    from pg_views\\n    where schemaname ilike '{{ schema_relation.schema }}'\\n  {% endcall %}\\n  {{ return(load_result('list_relations_without_caching').table) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.739969, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__information_schema_name\": {\"unique_id\": \"macro.dbt_postgres.postgres__information_schema_name\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/gerda/FTA/dbt/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__information_schema_name\", \"macro_sql\": \"{% macro postgres__information_schema_name(database) -%}\\n  {% if database_name -%}\\n    {{ adapter.verify_database(database_name) }}\\n  {%- endif -%}\\n  information_schema\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.740651, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__list_schemas\": {\"unique_id\": \"macro.dbt_postgres.postgres__list_schemas\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/gerda/FTA/dbt/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__list_schemas\", \"macro_sql\": \"{% macro postgres__list_schemas(database) %}\\n  {% if database -%}\\n    {{ adapter.verify_database(database) }}\\n  {%- endif -%}\\n  {% call statement('list_schemas', fetch_result=True, auto_begin=False) %}\\n    select distinct nspname from pg_namespace\\n  {% endcall %}\\n  {{ return(load_result('list_schemas').table) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.741567, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__check_schema_exists\": {\"unique_id\": \"macro.dbt_postgres.postgres__check_schema_exists\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/gerda/FTA/dbt/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__check_schema_exists\", \"macro_sql\": \"{% macro postgres__check_schema_exists(information_schema, schema) -%}\\n  {% if information_schema.database -%}\\n    {{ adapter.verify_database(information_schema.database) }}\\n  {%- endif -%}\\n  {% call statement('check_schema_exists', fetch_result=True, auto_begin=False) %}\\n    select count(*) from pg_namespace where nspname = '{{ schema }}'\\n  {% endcall %}\\n  {{ return(load_result('check_schema_exists').table) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.742538, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__make_relation_with_suffix\": {\"unique_id\": \"macro.dbt_postgres.postgres__make_relation_with_suffix\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/gerda/FTA/dbt/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__make_relation_with_suffix\", \"macro_sql\": \"{% macro postgres__make_relation_with_suffix(base_relation, suffix, dstring) %}\\n    {% if dstring %}\\n      {% set dt = modules.datetime.datetime.now() %}\\n      {% set dtstring = dt.strftime(\\\"%H%M%S%f\\\") %}\\n      {% set suffix = suffix ~ dtstring %}\\n    {% endif %}\\n    {% set suffix_length = suffix|length %}\\n    {% set relation_max_name_length = base_relation.relation_max_name_length() %}\\n    {% if suffix_length > relation_max_name_length %}\\n        {% do exceptions.raise_compiler_error('Relation suffix is too long (' ~ suffix_length ~ ' characters). Maximum length is ' ~ relation_max_name_length ~ ' characters.') %}\\n    {% endif %}\\n    {% set identifier = base_relation.identifier[:relation_max_name_length - suffix_length] ~ suffix %}\\n\\n    {{ return(base_relation.incorporate(path={\\\"identifier\\\": identifier })) }}\\n\\n  {% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.744768, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__make_intermediate_relation\": {\"unique_id\": \"macro.dbt_postgres.postgres__make_intermediate_relation\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/gerda/FTA/dbt/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__make_intermediate_relation\", \"macro_sql\": \"{% macro postgres__make_intermediate_relation(base_relation, suffix) %}\\n    {{ return(postgres__make_relation_with_suffix(base_relation, suffix, dstring=False)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_relation_with_suffix\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.745294, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__make_temp_relation\": {\"unique_id\": \"macro.dbt_postgres.postgres__make_temp_relation\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/gerda/FTA/dbt/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__make_temp_relation\", \"macro_sql\": \"{% macro postgres__make_temp_relation(base_relation, suffix) %}\\n    {% set temp_relation = postgres__make_relation_with_suffix(base_relation, suffix, dstring=True) %}\\n    {{ return(temp_relation.incorporate(path={\\\"schema\\\": none,\\n                                              \\\"database\\\": none})) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_relation_with_suffix\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.746094, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__make_backup_relation\": {\"unique_id\": \"macro.dbt_postgres.postgres__make_backup_relation\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/gerda/FTA/dbt/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__make_backup_relation\", \"macro_sql\": \"{% macro postgres__make_backup_relation(base_relation, backup_relation_type, suffix) %}\\n    {% set backup_relation = postgres__make_relation_with_suffix(base_relation, suffix, dstring=False) %}\\n    {{ return(backup_relation.incorporate(type=backup_relation_type)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_relation_with_suffix\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.746795, \"supported_languages\": null}, \"macro.dbt_postgres.postgres_escape_comment\": {\"unique_id\": \"macro.dbt_postgres.postgres_escape_comment\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/gerda/FTA/dbt/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres_escape_comment\", \"macro_sql\": \"{% macro postgres_escape_comment(comment) -%}\\n  {% if comment is not string %}\\n    {% do exceptions.raise_compiler_error('cannot escape a non-string: ' ~ comment) %}\\n  {% endif %}\\n  {%- set magic = '$dbt_comment_literal_block$' -%}\\n  {%- if magic in comment -%}\\n    {%- do exceptions.raise_compiler_error('The string ' ~ magic ~ ' is not allowed in comments.') -%}\\n  {%- endif -%}\\n  {{ magic }}{{ comment }}{{ magic }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.747864, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__alter_relation_comment\": {\"unique_id\": \"macro.dbt_postgres.postgres__alter_relation_comment\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/gerda/FTA/dbt/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__alter_relation_comment\", \"macro_sql\": \"{% macro postgres__alter_relation_comment(relation, comment) %}\\n  {% set escaped_comment = postgres_escape_comment(comment) %}\\n  comment on {{ relation.type }} {{ relation }} is {{ escaped_comment }};\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres_escape_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.7484329, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__alter_column_comment\": {\"unique_id\": \"macro.dbt_postgres.postgres__alter_column_comment\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/gerda/FTA/dbt/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__alter_column_comment\", \"macro_sql\": \"{% macro postgres__alter_column_comment(relation, column_dict) %}\\n  {% set existing_columns = adapter.get_columns_in_relation(relation) | map(attribute=\\\"name\\\") | list %}\\n  {% for column_name in column_dict if (column_name in existing_columns) %}\\n    {% set comment = column_dict[column_name]['description'] %}\\n    {% set escaped_comment = postgres_escape_comment(comment) %}\\n    comment on column {{ relation }}.{{ adapter.quote(column_name) if column_dict[column_name]['quote'] else column_name }} is {{ escaped_comment }};\\n  {% endfor %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres_escape_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.7500181, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_show_grant_sql\": {\"unique_id\": \"macro.dbt_postgres.postgres__get_show_grant_sql\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/gerda/FTA/dbt/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__get_show_grant_sql\", \"macro_sql\": \"\\n\\n{%- macro postgres__get_show_grant_sql(relation) -%}\\n  select grantee, privilege_type\\n  from {{ relation.information_schema('role_table_grants') }}\\n      where grantor = current_role\\n        and grantee != current_role\\n        and table_schema = '{{ relation.schema }}'\\n        and table_name = '{{ relation.identifier }}'\\n{%- endmacro -%}\\n\\n\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.750537, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__copy_grants\": {\"unique_id\": \"macro.dbt_postgres.postgres__copy_grants\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/gerda/FTA/dbt/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"name\": \"postgres__copy_grants\", \"macro_sql\": \"{% macro postgres__copy_grants() %}\\n    {{ return(False) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.750845, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_incremental_default_sql\": {\"unique_id\": \"macro.dbt_postgres.postgres__get_incremental_default_sql\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/gerda/FTA/dbt/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/materializations/incremental_strategies.sql\", \"original_file_path\": \"macros/materializations/incremental_strategies.sql\", \"name\": \"postgres__get_incremental_default_sql\", \"macro_sql\": \"{% macro postgres__get_incremental_default_sql(arg_dict) %}\\n\\n  {% if arg_dict[\\\"unique_key\\\"] %}\\n    {% do return(get_incremental_delete_insert_sql(arg_dict)) %}\\n  {% else %}\\n    {% do return(get_incremental_append_sql(arg_dict)) %}\\n  {% endif %}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_incremental_delete_insert_sql\", \"macro.dbt.get_incremental_append_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.752257, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__snapshot_merge_sql\": {\"unique_id\": \"macro.dbt_postgres.postgres__snapshot_merge_sql\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/gerda/FTA/dbt/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/materializations/snapshot_merge.sql\", \"original_file_path\": \"macros/materializations/snapshot_merge.sql\", \"name\": \"postgres__snapshot_merge_sql\", \"macro_sql\": \"{% macro postgres__snapshot_merge_sql(target, source, insert_cols) -%}\\n    {%- set insert_cols_csv = insert_cols | join(', ') -%}\\n\\n    update {{ target }}\\n    set dbt_valid_to = DBT_INTERNAL_SOURCE.dbt_valid_to\\n    from {{ source }} as DBT_INTERNAL_SOURCE\\n    where DBT_INTERNAL_SOURCE.dbt_scd_id::text = {{ target }}.dbt_scd_id::text\\n      and DBT_INTERNAL_SOURCE.dbt_change_type::text in ('update'::text, 'delete'::text)\\n      and {{ target }}.dbt_valid_to is null;\\n\\n    insert into {{ target }} ({{ insert_cols_csv }})\\n    select {% for column in insert_cols -%}\\n        DBT_INTERNAL_SOURCE.{{ column }} {%- if not loop.last %}, {%- endif %}\\n    {%- endfor %}\\n    from {{ source }} as DBT_INTERNAL_SOURCE\\n    where DBT_INTERNAL_SOURCE.dbt_change_type::text = 'insert'::text;\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.754163, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__dateadd\": {\"unique_id\": \"macro.dbt_postgres.postgres__dateadd\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/gerda/FTA/dbt/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/utils/dateadd.sql\", \"original_file_path\": \"macros/utils/dateadd.sql\", \"name\": \"postgres__dateadd\", \"macro_sql\": \"{% macro postgres__dateadd(datepart, interval, from_date_or_timestamp) %}\\n\\n    {{ from_date_or_timestamp }} + ((interval '1 {{ datepart }}') * ({{ interval }}))\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.755116, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__listagg\": {\"unique_id\": \"macro.dbt_postgres.postgres__listagg\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/gerda/FTA/dbt/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/utils/listagg.sql\", \"original_file_path\": \"macros/utils/listagg.sql\", \"name\": \"postgres__listagg\", \"macro_sql\": \"{% macro postgres__listagg(measure, delimiter_text, order_by_clause, limit_num) -%}\\n\\n    {% if limit_num -%}\\n    array_to_string(\\n        (array_agg(\\n            {{ measure }}\\n            {% if order_by_clause -%}\\n            {{ order_by_clause }}\\n            {%- endif %}\\n        ))[1:{{ limit_num }}],\\n        {{ delimiter_text }}\\n        )\\n    {%- else %}\\n    string_agg(\\n        {{ measure }},\\n        {{ delimiter_text }}\\n        {% if order_by_clause -%}\\n        {{ order_by_clause }}\\n        {%- endif %}\\n        )\\n    {%- endif %}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.757173, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__datediff\": {\"unique_id\": \"macro.dbt_postgres.postgres__datediff\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/gerda/FTA/dbt/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/utils/datediff.sql\", \"original_file_path\": \"macros/utils/datediff.sql\", \"name\": \"postgres__datediff\", \"macro_sql\": \"{% macro postgres__datediff(first_date, second_date, datepart) -%}\\n\\n    {% if datepart == 'year' %}\\n        (date_part('year', ({{second_date}})::date) - date_part('year', ({{first_date}})::date))\\n    {% elif datepart == 'quarter' %}\\n        ({{ datediff(first_date, second_date, 'year') }} * 4 + date_part('quarter', ({{second_date}})::date) - date_part('quarter', ({{first_date}})::date))\\n    {% elif datepart == 'month' %}\\n        ({{ datediff(first_date, second_date, 'year') }} * 12 + date_part('month', ({{second_date}})::date) - date_part('month', ({{first_date}})::date))\\n    {% elif datepart == 'day' %}\\n        (({{second_date}})::date - ({{first_date}})::date)\\n    {% elif datepart == 'week' %}\\n        ({{ datediff(first_date, second_date, 'day') }} / 7 + case\\n            when date_part('dow', ({{first_date}})::timestamp) <= date_part('dow', ({{second_date}})::timestamp) then\\n                case when {{first_date}} <= {{second_date}} then 0 else -1 end\\n            else\\n                case when {{first_date}} <= {{second_date}} then 1 else 0 end\\n        end)\\n    {% elif datepart == 'hour' %}\\n        ({{ datediff(first_date, second_date, 'day') }} * 24 + date_part('hour', ({{second_date}})::timestamp) - date_part('hour', ({{first_date}})::timestamp))\\n    {% elif datepart == 'minute' %}\\n        ({{ datediff(first_date, second_date, 'hour') }} * 60 + date_part('minute', ({{second_date}})::timestamp) - date_part('minute', ({{first_date}})::timestamp))\\n    {% elif datepart == 'second' %}\\n        ({{ datediff(first_date, second_date, 'minute') }} * 60 + floor(date_part('second', ({{second_date}})::timestamp)) - floor(date_part('second', ({{first_date}})::timestamp)))\\n    {% elif datepart == 'millisecond' %}\\n        ({{ datediff(first_date, second_date, 'minute') }} * 60000 + floor(date_part('millisecond', ({{second_date}})::timestamp)) - floor(date_part('millisecond', ({{first_date}})::timestamp)))\\n    {% elif datepart == 'microsecond' %}\\n        ({{ datediff(first_date, second_date, 'minute') }} * 60000000 + floor(date_part('microsecond', ({{second_date}})::timestamp)) - floor(date_part('microsecond', ({{first_date}})::timestamp)))\\n    {% else %}\\n        {{ exceptions.raise_compiler_error(\\\"Unsupported datepart for macro datediff in postgres: {!r}\\\".format(datepart)) }}\\n    {% endif %}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.datediff\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.765253, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__any_value\": {\"unique_id\": \"macro.dbt_postgres.postgres__any_value\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/gerda/FTA/dbt/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/utils/any_value.sql\", \"original_file_path\": \"macros/utils/any_value.sql\", \"name\": \"postgres__any_value\", \"macro_sql\": \"{% macro postgres__any_value(expression) -%}\\n\\n    min({{ expression }})\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.766171, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__last_day\": {\"unique_id\": \"macro.dbt_postgres.postgres__last_day\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/gerda/FTA/dbt/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/utils/last_day.sql\", \"original_file_path\": \"macros/utils/last_day.sql\", \"name\": \"postgres__last_day\", \"macro_sql\": \"{% macro postgres__last_day(date, datepart) -%}\\n\\n    {%- if datepart == 'quarter' -%}\\n    -- postgres dateadd does not support quarter interval.\\n    cast(\\n        {{dbt.dateadd('day', '-1',\\n        dbt.dateadd('month', '3', dbt.date_trunc(datepart, date))\\n        )}}\\n        as date)\\n    {%- else -%}\\n    {{dbt.default_last_day(date, datepart)}}\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.dateadd\", \"macro.dbt.date_trunc\", \"macro.dbt.default_last_day\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.767721, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__split_part\": {\"unique_id\": \"macro.dbt_postgres.postgres__split_part\", \"package_name\": \"dbt_postgres\", \"root_path\": \"/Users/gerda/FTA/dbt/plugins/postgres/dbt/include/postgres\", \"path\": \"macros/utils/split_part.sql\", \"original_file_path\": \"macros/utils/split_part.sql\", \"name\": \"postgres__split_part\", \"macro_sql\": \"{% macro postgres__split_part(string_text, delimiter_text, part_number) %}\\n\\n  {% if part_number >= 0 %}\\n    {{ dbt.default__split_part(string_text, delimiter_text, part_number) }}\\n  {% else %}\\n    {{ dbt._split_part_negative(string_text, delimiter_text, part_number) }}\\n  {% endif %}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__split_part\", \"macro.dbt._split_part_negative\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.7690408, \"supported_languages\": null}, \"macro.dbt.run_hooks\": {\"unique_id\": \"macro.dbt.run_hooks\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"name\": \"run_hooks\", \"macro_sql\": \"{% macro run_hooks(hooks, inside_transaction=True) %}\\n  {% for hook in hooks | selectattr('transaction', 'equalto', inside_transaction)  %}\\n    {% if not inside_transaction and loop.first %}\\n      {% call statement(auto_begin=inside_transaction) %}\\n        commit;\\n      {% endcall %}\\n    {% endif %}\\n    {% set rendered = render(hook.get('sql')) | trim %}\\n    {% if (rendered | length) > 0 %}\\n      {% call statement(auto_begin=inside_transaction) %}\\n        {{ rendered }}\\n      {% endcall %}\\n    {% endif %}\\n  {% endfor %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.7719731, \"supported_languages\": null}, \"macro.dbt.make_hook_config\": {\"unique_id\": \"macro.dbt.make_hook_config\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"name\": \"make_hook_config\", \"macro_sql\": \"{% macro make_hook_config(sql, inside_transaction) %}\\n    {{ tojson({\\\"sql\\\": sql, \\\"transaction\\\": inside_transaction}) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.772469, \"supported_languages\": null}, \"macro.dbt.before_begin\": {\"unique_id\": \"macro.dbt.before_begin\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"name\": \"before_begin\", \"macro_sql\": \"{% macro before_begin(sql) %}\\n    {{ make_hook_config(sql, inside_transaction=False) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.make_hook_config\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.7729542, \"supported_languages\": null}, \"macro.dbt.in_transaction\": {\"unique_id\": \"macro.dbt.in_transaction\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"name\": \"in_transaction\", \"macro_sql\": \"{% macro in_transaction(sql) %}\\n    {{ make_hook_config(sql, inside_transaction=True) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.make_hook_config\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.773334, \"supported_languages\": null}, \"macro.dbt.after_commit\": {\"unique_id\": \"macro.dbt.after_commit\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"name\": \"after_commit\", \"macro_sql\": \"{% macro after_commit(sql) %}\\n    {{ make_hook_config(sql, inside_transaction=False) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.make_hook_config\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.773783, \"supported_languages\": null}, \"macro.dbt.set_sql_header\": {\"unique_id\": \"macro.dbt.set_sql_header\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/configs.sql\", \"original_file_path\": \"macros/materializations/configs.sql\", \"name\": \"set_sql_header\", \"macro_sql\": \"{% macro set_sql_header(config) -%}\\n  {{ config.set('sql_header', caller()) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.7750452, \"supported_languages\": null}, \"macro.dbt.should_full_refresh\": {\"unique_id\": \"macro.dbt.should_full_refresh\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/configs.sql\", \"original_file_path\": \"macros/materializations/configs.sql\", \"name\": \"should_full_refresh\", \"macro_sql\": \"{% macro should_full_refresh() %}\\n  {% set config_full_refresh = config.get('full_refresh') %}\\n  {% if config_full_refresh is none %}\\n    {% set config_full_refresh = flags.FULL_REFRESH %}\\n  {% endif %}\\n  {% do return(config_full_refresh) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.775828, \"supported_languages\": null}, \"macro.dbt.should_store_failures\": {\"unique_id\": \"macro.dbt.should_store_failures\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/configs.sql\", \"original_file_path\": \"macros/materializations/configs.sql\", \"name\": \"should_store_failures\", \"macro_sql\": \"{% macro should_store_failures() %}\\n  {% set config_store_failures = config.get('store_failures') %}\\n  {% if config_store_failures is none %}\\n    {% set config_store_failures = flags.STORE_FAILURES %}\\n  {% endif %}\\n  {% do return(config_store_failures) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.776683, \"supported_languages\": null}, \"macro.dbt.snapshot_merge_sql\": {\"unique_id\": \"macro.dbt.snapshot_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/snapshot_merge.sql\", \"original_file_path\": \"macros/materializations/snapshots/snapshot_merge.sql\", \"name\": \"snapshot_merge_sql\", \"macro_sql\": \"{% macro snapshot_merge_sql(target, source, insert_cols) -%}\\n  {{ adapter.dispatch('snapshot_merge_sql', 'dbt')(target, source, insert_cols) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__snapshot_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.778024, \"supported_languages\": null}, \"macro.dbt.default__snapshot_merge_sql\": {\"unique_id\": \"macro.dbt.default__snapshot_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/snapshot_merge.sql\", \"original_file_path\": \"macros/materializations/snapshots/snapshot_merge.sql\", \"name\": \"default__snapshot_merge_sql\", \"macro_sql\": \"{% macro default__snapshot_merge_sql(target, source, insert_cols) -%}\\n    {%- set insert_cols_csv = insert_cols | join(', ') -%}\\n\\n    merge into {{ target }} as DBT_INTERNAL_DEST\\n    using {{ source }} as DBT_INTERNAL_SOURCE\\n    on DBT_INTERNAL_SOURCE.dbt_scd_id = DBT_INTERNAL_DEST.dbt_scd_id\\n\\n    when matched\\n     and DBT_INTERNAL_DEST.dbt_valid_to is null\\n     and DBT_INTERNAL_SOURCE.dbt_change_type in ('update', 'delete')\\n        then update\\n        set dbt_valid_to = DBT_INTERNAL_SOURCE.dbt_valid_to\\n\\n    when not matched\\n     and DBT_INTERNAL_SOURCE.dbt_change_type = 'insert'\\n        then insert ({{ insert_cols_csv }})\\n        values ({{ insert_cols_csv }})\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.778701, \"supported_languages\": null}, \"macro.dbt.strategy_dispatch\": {\"unique_id\": \"macro.dbt.strategy_dispatch\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"name\": \"strategy_dispatch\", \"macro_sql\": \"{% macro strategy_dispatch(name) -%}\\n{% set original_name = name %}\\n  {% if '.' in name %}\\n    {% set package_name, name = name.split(\\\".\\\", 1) %}\\n  {% else %}\\n    {% set package_name = none %}\\n  {% endif %}\\n\\n  {% if package_name is none %}\\n    {% set package_context = context %}\\n  {% elif package_name in context %}\\n    {% set package_context = context[package_name] %}\\n  {% else %}\\n    {% set error_msg %}\\n        Could not find package '{{package_name}}', called with '{{original_name}}'\\n    {% endset %}\\n    {{ exceptions.raise_compiler_error(error_msg | trim) }}\\n  {% endif %}\\n\\n  {%- set search_name = 'snapshot_' ~ name ~ '_strategy' -%}\\n\\n  {% if search_name not in package_context %}\\n    {% set error_msg %}\\n        The specified strategy macro '{{name}}' was not found in package '{{ package_name }}'\\n    {% endset %}\\n    {{ exceptions.raise_compiler_error(error_msg | trim) }}\\n  {% endif %}\\n  {{ return(package_context[search_name]) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.786231, \"supported_languages\": null}, \"macro.dbt.snapshot_hash_arguments\": {\"unique_id\": \"macro.dbt.snapshot_hash_arguments\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"name\": \"snapshot_hash_arguments\", \"macro_sql\": \"{% macro snapshot_hash_arguments(args) -%}\\n  {{ adapter.dispatch('snapshot_hash_arguments', 'dbt')(args) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__snapshot_hash_arguments\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.78667, \"supported_languages\": null}, \"macro.dbt.default__snapshot_hash_arguments\": {\"unique_id\": \"macro.dbt.default__snapshot_hash_arguments\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"name\": \"default__snapshot_hash_arguments\", \"macro_sql\": \"{% macro default__snapshot_hash_arguments(args) -%}\\n    md5({%- for arg in args -%}\\n        coalesce(cast({{ arg }} as varchar ), '')\\n        {% if not loop.last %} || '|' || {% endif %}\\n    {%- endfor -%})\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.787231, \"supported_languages\": null}, \"macro.dbt.snapshot_timestamp_strategy\": {\"unique_id\": \"macro.dbt.snapshot_timestamp_strategy\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"name\": \"snapshot_timestamp_strategy\", \"macro_sql\": \"{% macro snapshot_timestamp_strategy(node, snapshotted_rel, current_rel, config, target_exists) %}\\n    {% set primary_key = config['unique_key'] %}\\n    {% set updated_at = config['updated_at'] %}\\n    {% set invalidate_hard_deletes = config.get('invalidate_hard_deletes', false) %}\\n\\n    {#/*\\n        The snapshot relation might not have an {{ updated_at }} value if the\\n        snapshot strategy is changed from `check` to `timestamp`. We\\n        should use a dbt-created column for the comparison in the snapshot\\n        table instead of assuming that the user-supplied {{ updated_at }}\\n        will be present in the historical data.\\n\\n        See https://github.com/dbt-labs/dbt-core/issues/2350\\n    */ #}\\n    {% set row_changed_expr -%}\\n        ({{ snapshotted_rel }}.dbt_valid_from < {{ current_rel }}.{{ updated_at }})\\n    {%- endset %}\\n\\n    {% set scd_id_expr = snapshot_hash_arguments([primary_key, updated_at]) %}\\n\\n    {% do return({\\n        \\\"unique_key\\\": primary_key,\\n        \\\"updated_at\\\": updated_at,\\n        \\\"row_changed\\\": row_changed_expr,\\n        \\\"scd_id\\\": scd_id_expr,\\n        \\\"invalidate_hard_deletes\\\": invalidate_hard_deletes\\n    }) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.snapshot_hash_arguments\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.788982, \"supported_languages\": null}, \"macro.dbt.snapshot_string_as_time\": {\"unique_id\": \"macro.dbt.snapshot_string_as_time\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"name\": \"snapshot_string_as_time\", \"macro_sql\": \"{% macro snapshot_string_as_time(timestamp) -%}\\n    {{ adapter.dispatch('snapshot_string_as_time', 'dbt')(timestamp) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__snapshot_string_as_time\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.789396, \"supported_languages\": null}, \"macro.dbt.default__snapshot_string_as_time\": {\"unique_id\": \"macro.dbt.default__snapshot_string_as_time\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"name\": \"default__snapshot_string_as_time\", \"macro_sql\": \"{% macro default__snapshot_string_as_time(timestamp) %}\\n    {% do exceptions.raise_not_implemented(\\n        'snapshot_string_as_time macro not implemented for adapter '+adapter.type()\\n    ) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.789981, \"supported_languages\": null}, \"macro.dbt.snapshot_check_all_get_existing_columns\": {\"unique_id\": \"macro.dbt.snapshot_check_all_get_existing_columns\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"name\": \"snapshot_check_all_get_existing_columns\", \"macro_sql\": \"{% macro snapshot_check_all_get_existing_columns(node, target_exists, check_cols_config) -%}\\n    {%- if not target_exists -%}\\n        {#-- no table yet -> return whatever the query does --#}\\n        {{ return((false, query_columns)) }}\\n    {%- endif -%}\\n\\n    {#-- handle any schema changes --#}\\n    {%- set target_relation = adapter.get_relation(database=node.database, schema=node.schema, identifier=node.alias) -%}\\n\\n    {% if check_cols_config == 'all' %}\\n        {%- set query_columns = get_columns_in_query(node['compiled_code']) -%}\\n\\n    {% elif check_cols_config is iterable and (check_cols_config | length) > 0 %}\\n        {#-- query for proper casing/quoting, to support comparison below --#}\\n        {%- set select_check_cols_from_target -%}\\n          select {{ check_cols_config | join(', ') }} from ({{ node['compiled_code'] }}) subq\\n        {%- endset -%}\\n        {% set query_columns = get_columns_in_query(select_check_cols_from_target) %}\\n\\n    {% else %}\\n        {% do exceptions.raise_compiler_error(\\\"Invalid value for 'check_cols': \\\" ~ check_cols_config) %}\\n    {% endif %}\\n\\n    {%- set existing_cols = adapter.get_columns_in_relation(target_relation) | map(attribute = 'name') | list -%}\\n    {%- set ns = namespace() -%} {#-- handle for-loop scoping with a namespace --#}\\n    {%- set ns.column_added = false -%}\\n\\n    {%- set intersection = [] -%}\\n    {%- for col in query_columns -%}\\n        {%- if col in existing_cols -%}\\n            {%- do intersection.append(adapter.quote(col)) -%}\\n        {%- else -%}\\n            {% set ns.column_added = true %}\\n        {%- endif -%}\\n    {%- endfor -%}\\n    {{ return((ns.column_added, intersection)) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_columns_in_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.793568, \"supported_languages\": null}, \"macro.dbt.snapshot_check_strategy\": {\"unique_id\": \"macro.dbt.snapshot_check_strategy\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"name\": \"snapshot_check_strategy\", \"macro_sql\": \"{% macro snapshot_check_strategy(node, snapshotted_rel, current_rel, config, target_exists) %}\\n    {% set check_cols_config = config['check_cols'] %}\\n    {% set primary_key = config['unique_key'] %}\\n    {% set invalidate_hard_deletes = config.get('invalidate_hard_deletes', false) %}\\n    {% set updated_at = config.get('updated_at', snapshot_get_time()) %}\\n\\n    {% set column_added = false %}\\n\\n    {% set column_added, check_cols = snapshot_check_all_get_existing_columns(node, target_exists, check_cols_config) %}\\n\\n    {%- set row_changed_expr -%}\\n    (\\n    {%- if column_added -%}\\n        {{ get_true_sql() }}\\n    {%- else -%}\\n    {%- for col in check_cols -%}\\n        {{ snapshotted_rel }}.{{ col }} != {{ current_rel }}.{{ col }}\\n        or\\n        (\\n            (({{ snapshotted_rel }}.{{ col }} is null) and not ({{ current_rel }}.{{ col }} is null))\\n            or\\n            ((not {{ snapshotted_rel }}.{{ col }} is null) and ({{ current_rel }}.{{ col }} is null))\\n        )\\n        {%- if not loop.last %} or {% endif -%}\\n    {%- endfor -%}\\n    {%- endif -%}\\n    )\\n    {%- endset %}\\n\\n    {% set scd_id_expr = snapshot_hash_arguments([primary_key, updated_at]) %}\\n\\n    {% do return({\\n        \\\"unique_key\\\": primary_key,\\n        \\\"updated_at\\\": updated_at,\\n        \\\"row_changed\\\": row_changed_expr,\\n        \\\"scd_id\\\": scd_id_expr,\\n        \\\"invalidate_hard_deletes\\\": invalidate_hard_deletes\\n    }) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.snapshot_get_time\", \"macro.dbt.snapshot_check_all_get_existing_columns\", \"macro.dbt.get_true_sql\", \"macro.dbt.snapshot_hash_arguments\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.7968981, \"supported_languages\": null}, \"macro.dbt.create_columns\": {\"unique_id\": \"macro.dbt.create_columns\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"name\": \"create_columns\", \"macro_sql\": \"{% macro create_columns(relation, columns) %}\\n  {{ adapter.dispatch('create_columns', 'dbt')(relation, columns) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__create_columns\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.80455, \"supported_languages\": null}, \"macro.dbt.default__create_columns\": {\"unique_id\": \"macro.dbt.default__create_columns\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"name\": \"default__create_columns\", \"macro_sql\": \"{% macro default__create_columns(relation, columns) %}\\n  {% for column in columns %}\\n    {% call statement() %}\\n      alter table {{ relation }} add column \\\"{{ column.name }}\\\" {{ column.data_type }};\\n    {% endcall %}\\n  {% endfor %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.805295, \"supported_languages\": null}, \"macro.dbt.post_snapshot\": {\"unique_id\": \"macro.dbt.post_snapshot\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"name\": \"post_snapshot\", \"macro_sql\": \"{% macro post_snapshot(staging_relation) %}\\n  {{ adapter.dispatch('post_snapshot', 'dbt')(staging_relation) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__post_snapshot\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.805722, \"supported_languages\": null}, \"macro.dbt.default__post_snapshot\": {\"unique_id\": \"macro.dbt.default__post_snapshot\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"name\": \"default__post_snapshot\", \"macro_sql\": \"{% macro default__post_snapshot(staging_relation) %}\\n    {# no-op #}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.805967, \"supported_languages\": null}, \"macro.dbt.get_true_sql\": {\"unique_id\": \"macro.dbt.get_true_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"name\": \"get_true_sql\", \"macro_sql\": \"{% macro get_true_sql() %}\\n  {{ adapter.dispatch('get_true_sql', 'dbt')() }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_true_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.8063412, \"supported_languages\": null}, \"macro.dbt.default__get_true_sql\": {\"unique_id\": \"macro.dbt.default__get_true_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"name\": \"default__get_true_sql\", \"macro_sql\": \"{% macro default__get_true_sql() %}\\n    {{ return('TRUE') }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.806646, \"supported_languages\": null}, \"macro.dbt.snapshot_staging_table\": {\"unique_id\": \"macro.dbt.snapshot_staging_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"name\": \"snapshot_staging_table\", \"macro_sql\": \"{% macro snapshot_staging_table(strategy, source_sql, target_relation) -%}\\n  {{ adapter.dispatch('snapshot_staging_table', 'dbt')(strategy, source_sql, target_relation) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__snapshot_staging_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.807165, \"supported_languages\": null}, \"macro.dbt.default__snapshot_staging_table\": {\"unique_id\": \"macro.dbt.default__snapshot_staging_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"name\": \"default__snapshot_staging_table\", \"macro_sql\": \"{% macro default__snapshot_staging_table(strategy, source_sql, target_relation) -%}\\n\\n    with snapshot_query as (\\n\\n        {{ source_sql }}\\n\\n    ),\\n\\n    snapshotted_data as (\\n\\n        select *,\\n            {{ strategy.unique_key }} as dbt_unique_key\\n\\n        from {{ target_relation }}\\n        where dbt_valid_to is null\\n\\n    ),\\n\\n    insertions_source_data as (\\n\\n        select\\n            *,\\n            {{ strategy.unique_key }} as dbt_unique_key,\\n            {{ strategy.updated_at }} as dbt_updated_at,\\n            {{ strategy.updated_at }} as dbt_valid_from,\\n            nullif({{ strategy.updated_at }}, {{ strategy.updated_at }}) as dbt_valid_to,\\n            {{ strategy.scd_id }} as dbt_scd_id\\n\\n        from snapshot_query\\n    ),\\n\\n    updates_source_data as (\\n\\n        select\\n            *,\\n            {{ strategy.unique_key }} as dbt_unique_key,\\n            {{ strategy.updated_at }} as dbt_updated_at,\\n            {{ strategy.updated_at }} as dbt_valid_from,\\n            {{ strategy.updated_at }} as dbt_valid_to\\n\\n        from snapshot_query\\n    ),\\n\\n    {%- if strategy.invalidate_hard_deletes %}\\n\\n    deletes_source_data as (\\n\\n        select\\n            *,\\n            {{ strategy.unique_key }} as dbt_unique_key\\n        from snapshot_query\\n    ),\\n    {% endif %}\\n\\n    insertions as (\\n\\n        select\\n            'insert' as dbt_change_type,\\n            source_data.*\\n\\n        from insertions_source_data as source_data\\n        left outer join snapshotted_data on snapshotted_data.dbt_unique_key = source_data.dbt_unique_key\\n        where snapshotted_data.dbt_unique_key is null\\n           or (\\n                snapshotted_data.dbt_unique_key is not null\\n            and (\\n                {{ strategy.row_changed }}\\n            )\\n        )\\n\\n    ),\\n\\n    updates as (\\n\\n        select\\n            'update' as dbt_change_type,\\n            source_data.*,\\n            snapshotted_data.dbt_scd_id\\n\\n        from updates_source_data as source_data\\n        join snapshotted_data on snapshotted_data.dbt_unique_key = source_data.dbt_unique_key\\n        where (\\n            {{ strategy.row_changed }}\\n        )\\n    )\\n\\n    {%- if strategy.invalidate_hard_deletes -%}\\n    ,\\n\\n    deletes as (\\n\\n        select\\n            'delete' as dbt_change_type,\\n            source_data.*,\\n            {{ snapshot_get_time() }} as dbt_valid_from,\\n            {{ snapshot_get_time() }} as dbt_updated_at,\\n            {{ snapshot_get_time() }} as dbt_valid_to,\\n            snapshotted_data.dbt_scd_id\\n\\n        from snapshotted_data\\n        left join deletes_source_data as source_data on snapshotted_data.dbt_unique_key = source_data.dbt_unique_key\\n        where source_data.dbt_unique_key is null\\n    )\\n    {%- endif %}\\n\\n    select * from insertions\\n    union all\\n    select * from updates\\n    {%- if strategy.invalidate_hard_deletes %}\\n    union all\\n    select * from deletes\\n    {%- endif %}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.snapshot_get_time\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.80939, \"supported_languages\": null}, \"macro.dbt.build_snapshot_table\": {\"unique_id\": \"macro.dbt.build_snapshot_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"name\": \"build_snapshot_table\", \"macro_sql\": \"{% macro build_snapshot_table(strategy, sql) -%}\\n  {{ adapter.dispatch('build_snapshot_table', 'dbt')(strategy, sql) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__build_snapshot_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.809878, \"supported_languages\": null}, \"macro.dbt.default__build_snapshot_table\": {\"unique_id\": \"macro.dbt.default__build_snapshot_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"name\": \"default__build_snapshot_table\", \"macro_sql\": \"{% macro default__build_snapshot_table(strategy, sql) %}\\n\\n    select *,\\n        {{ strategy.scd_id }} as dbt_scd_id,\\n        {{ strategy.updated_at }} as dbt_updated_at,\\n        {{ strategy.updated_at }} as dbt_valid_from,\\n        nullif({{ strategy.updated_at }}, {{ strategy.updated_at }}) as dbt_valid_to\\n    from (\\n        {{ sql }}\\n    ) sbq\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.810522, \"supported_languages\": null}, \"macro.dbt.build_snapshot_staging_table\": {\"unique_id\": \"macro.dbt.build_snapshot_staging_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"name\": \"build_snapshot_staging_table\", \"macro_sql\": \"{% macro build_snapshot_staging_table(strategy, sql, target_relation) %}\\n    {% set temp_relation = make_temp_relation(target_relation) %}\\n\\n    {% set select = snapshot_staging_table(strategy, sql, target_relation) %}\\n\\n    {% call statement('build_snapshot_staging_relation') %}\\n        {{ create_table_as(True, temp_relation, select) }}\\n    {% endcall %}\\n\\n    {% do return(temp_relation) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.make_temp_relation\", \"macro.dbt.snapshot_staging_table\", \"macro.dbt.statement\", \"macro.dbt.create_table_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.811589, \"supported_languages\": null}, \"macro.dbt.materialization_snapshot_default\": {\"unique_id\": \"macro.dbt.materialization_snapshot_default\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/snapshots/snapshot.sql\", \"original_file_path\": \"macros/materializations/snapshots/snapshot.sql\", \"name\": \"materialization_snapshot_default\", \"macro_sql\": \"{% materialization snapshot, default %}\\n  {%- set config = model['config'] -%}\\n\\n  {%- set target_table = model.get('alias', model.get('name')) -%}\\n\\n  {%- set strategy_name = config.get('strategy') -%}\\n  {%- set unique_key = config.get('unique_key') %}\\n  -- grab current tables grants config for comparision later on\\n  {%- set grant_config = config.get('grants') -%}\\n\\n  {% set target_relation_exists, target_relation = get_or_create_relation(\\n          database=model.database,\\n          schema=model.schema,\\n          identifier=target_table,\\n          type='table') -%}\\n\\n  {%- if not target_relation.is_table -%}\\n    {% do exceptions.relation_wrong_type(target_relation, 'table') %}\\n  {%- endif -%}\\n\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  {% set strategy_macro = strategy_dispatch(strategy_name) %}\\n  {% set strategy = strategy_macro(model, \\\"snapshotted_data\\\", \\\"source_data\\\", config, target_relation_exists) %}\\n\\n  {% if not target_relation_exists %}\\n\\n      {% set build_sql = build_snapshot_table(strategy, model['compiled_code']) %}\\n      {% set final_sql = create_table_as(False, target_relation, build_sql) %}\\n\\n  {% else %}\\n\\n      {{ adapter.valid_snapshot_target(target_relation) }}\\n\\n      {% set staging_table = build_snapshot_staging_table(strategy, sql, target_relation) %}\\n\\n      -- this may no-op if the database does not require column expansion\\n      {% do adapter.expand_target_column_types(from_relation=staging_table,\\n                                               to_relation=target_relation) %}\\n\\n      {% set missing_columns = adapter.get_missing_columns(staging_table, target_relation)\\n                                   | rejectattr('name', 'equalto', 'dbt_change_type')\\n                                   | rejectattr('name', 'equalto', 'DBT_CHANGE_TYPE')\\n                                   | rejectattr('name', 'equalto', 'dbt_unique_key')\\n                                   | rejectattr('name', 'equalto', 'DBT_UNIQUE_KEY')\\n                                   | list %}\\n\\n      {% do create_columns(target_relation, missing_columns) %}\\n\\n      {% set source_columns = adapter.get_columns_in_relation(staging_table)\\n                                   | rejectattr('name', 'equalto', 'dbt_change_type')\\n                                   | rejectattr('name', 'equalto', 'DBT_CHANGE_TYPE')\\n                                   | rejectattr('name', 'equalto', 'dbt_unique_key')\\n                                   | rejectattr('name', 'equalto', 'DBT_UNIQUE_KEY')\\n                                   | list %}\\n\\n      {% set quoted_source_columns = [] %}\\n      {% for column in source_columns %}\\n        {% do quoted_source_columns.append(adapter.quote(column.name)) %}\\n      {% endfor %}\\n\\n      {% set final_sql = snapshot_merge_sql(\\n            target = target_relation,\\n            source = staging_table,\\n            insert_cols = quoted_source_columns\\n         )\\n      %}\\n\\n  {% endif %}\\n\\n  {% call statement('main') %}\\n      {{ final_sql }}\\n  {% endcall %}\\n\\n  {% set should_revoke = should_revoke(target_relation_exists, full_refresh_mode=False) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {% if not target_relation_exists %}\\n    {% do create_indexes(target_relation) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  {{ adapter.commit() }}\\n\\n  {% if staging_table is defined %}\\n      {% do post_snapshot(staging_table) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{% endmaterialization %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_or_create_relation\", \"macro.dbt.run_hooks\", \"macro.dbt.strategy_dispatch\", \"macro.dbt.build_snapshot_table\", \"macro.dbt.create_table_as\", \"macro.dbt.build_snapshot_staging_table\", \"macro.dbt.create_columns\", \"macro.dbt.snapshot_merge_sql\", \"macro.dbt.statement\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\", \"macro.dbt.persist_docs\", \"macro.dbt.create_indexes\", \"macro.dbt.post_snapshot\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.826415, \"supported_languages\": [\"sql\"]}, \"macro.dbt.materialization_test_default\": {\"unique_id\": \"macro.dbt.materialization_test_default\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/tests/test.sql\", \"original_file_path\": \"macros/materializations/tests/test.sql\", \"name\": \"materialization_test_default\", \"macro_sql\": \"{%- materialization test, default -%}\\n\\n  {% set relations = [] %}\\n\\n  {% if should_store_failures() %}\\n\\n    {% set identifier = model['alias'] %}\\n    {% set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) %}\\n    {% set target_relation = api.Relation.create(\\n        identifier=identifier, schema=schema, database=database, type='table') -%} %}\\n\\n    {% if old_relation %}\\n        {% do adapter.drop_relation(old_relation) %}\\n    {% endif %}\\n\\n    {% call statement(auto_begin=True) %}\\n        {{ create_table_as(False, target_relation, sql) }}\\n    {% endcall %}\\n\\n    {% do relations.append(target_relation) %}\\n\\n    {% set main_sql %}\\n        select *\\n        from {{ target_relation }}\\n    {% endset %}\\n\\n    {{ adapter.commit() }}\\n\\n  {% else %}\\n\\n      {% set main_sql = sql %}\\n\\n  {% endif %}\\n\\n  {% set limit = config.get('limit') %}\\n  {% set fail_calc = config.get('fail_calc') %}\\n  {% set warn_if = config.get('warn_if') %}\\n  {% set error_if = config.get('error_if') %}\\n\\n  {% call statement('main', fetch_result=True) -%}\\n\\n    {{ get_test_sql(main_sql, fail_calc, warn_if, error_if, limit)}}\\n\\n  {%- endcall %}\\n\\n  {{ return({'relations': relations}) }}\\n\\n{%- endmaterialization -%}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.should_store_failures\", \"macro.dbt.statement\", \"macro.dbt.create_table_as\", \"macro.dbt.get_test_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.831668, \"supported_languages\": [\"sql\"]}, \"macro.dbt.get_test_sql\": {\"unique_id\": \"macro.dbt.get_test_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/tests/helpers.sql\", \"original_file_path\": \"macros/materializations/tests/helpers.sql\", \"name\": \"get_test_sql\", \"macro_sql\": \"{% macro get_test_sql(main_sql, fail_calc, warn_if, error_if, limit) -%}\\n  {{ adapter.dispatch('get_test_sql', 'dbt')(main_sql, fail_calc, warn_if, error_if, limit) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_test_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.8331032, \"supported_languages\": null}, \"macro.dbt.default__get_test_sql\": {\"unique_id\": \"macro.dbt.default__get_test_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/tests/helpers.sql\", \"original_file_path\": \"macros/materializations/tests/helpers.sql\", \"name\": \"default__get_test_sql\", \"macro_sql\": \"{% macro default__get_test_sql(main_sql, fail_calc, warn_if, error_if, limit) -%}\\n    select\\n      {{ fail_calc }} as failures,\\n      {{ fail_calc }} {{ warn_if }} as should_warn,\\n      {{ fail_calc }} {{ error_if }} as should_error\\n    from (\\n      {{ main_sql }}\\n      {{ \\\"limit \\\" ~ limit if limit != none }}\\n    ) dbt_internal_test\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.8338718, \"supported_languages\": null}, \"macro.dbt.get_where_subquery\": {\"unique_id\": \"macro.dbt.get_where_subquery\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/tests/where_subquery.sql\", \"original_file_path\": \"macros/materializations/tests/where_subquery.sql\", \"name\": \"get_where_subquery\", \"macro_sql\": \"{% macro get_where_subquery(relation) -%}\\n    {% do return(adapter.dispatch('get_where_subquery', 'dbt')(relation)) %}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_where_subquery\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.8350341, \"supported_languages\": null}, \"macro.dbt.default__get_where_subquery\": {\"unique_id\": \"macro.dbt.default__get_where_subquery\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/tests/where_subquery.sql\", \"original_file_path\": \"macros/materializations/tests/where_subquery.sql\", \"name\": \"default__get_where_subquery\", \"macro_sql\": \"{% macro default__get_where_subquery(relation) -%}\\n    {% set where = config.get('where', '') %}\\n    {% if where %}\\n        {%- set filtered -%}\\n            (select * from {{ relation }} where {{ where }}) dbt_subquery\\n        {%- endset -%}\\n        {% do return(filtered) %}\\n    {%- else -%}\\n        {% do return(relation) %}\\n    {%- endif -%}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.835979, \"supported_languages\": null}, \"macro.dbt.get_quoted_csv\": {\"unique_id\": \"macro.dbt.get_quoted_csv\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"name\": \"get_quoted_csv\", \"macro_sql\": \"{% macro get_quoted_csv(column_names) %}\\n\\n    {% set quoted = [] %}\\n    {% for col in column_names -%}\\n        {%- do quoted.append(adapter.quote(col)) -%}\\n    {%- endfor %}\\n\\n    {%- set dest_cols_csv = quoted | join(', ') -%}\\n    {{ return(dest_cols_csv) }}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.8394618, \"supported_languages\": null}, \"macro.dbt.diff_columns\": {\"unique_id\": \"macro.dbt.diff_columns\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"name\": \"diff_columns\", \"macro_sql\": \"{% macro diff_columns(source_columns, target_columns) %}\\n\\n  {% set result = [] %}\\n  {% set source_names = source_columns | map(attribute = 'column') | list %}\\n  {% set target_names = target_columns | map(attribute = 'column') | list %}\\n\\n   {# --check whether the name attribute exists in the target - this does not perform a data type check #}\\n   {% for sc in source_columns %}\\n     {% if sc.name not in target_names %}\\n        {{ result.append(sc) }}\\n     {% endif %}\\n   {% endfor %}\\n\\n  {{ return(result) }}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.8409832, \"supported_languages\": null}, \"macro.dbt.diff_column_data_types\": {\"unique_id\": \"macro.dbt.diff_column_data_types\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"name\": \"diff_column_data_types\", \"macro_sql\": \"{% macro diff_column_data_types(source_columns, target_columns) %}\\n\\n  {% set result = [] %}\\n  {% for sc in source_columns %}\\n    {% set tc = target_columns | selectattr(\\\"name\\\", \\\"equalto\\\", sc.name) | list | first %}\\n    {% if tc %}\\n      {% if sc.data_type != tc.data_type and not sc.can_expand_to(other_column=tc) %}\\n        {{ result.append( { 'column_name': tc.name, 'new_type': sc.data_type } ) }}\\n      {% endif %}\\n    {% endif %}\\n  {% endfor %}\\n\\n  {{ return(result) }}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.842655, \"supported_languages\": null}, \"macro.dbt.get_merge_update_columns\": {\"unique_id\": \"macro.dbt.get_merge_update_columns\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"name\": \"get_merge_update_columns\", \"macro_sql\": \"{% macro get_merge_update_columns(merge_update_columns, merge_exclude_columns, dest_columns) %}\\n  {{ return(adapter.dispatch('get_merge_update_columns', 'dbt')(merge_update_columns, merge_exclude_columns, dest_columns)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_merge_update_columns\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.8432481, \"supported_languages\": null}, \"macro.dbt.default__get_merge_update_columns\": {\"unique_id\": \"macro.dbt.default__get_merge_update_columns\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"name\": \"default__get_merge_update_columns\", \"macro_sql\": \"{% macro default__get_merge_update_columns(merge_update_columns, merge_exclude_columns, dest_columns) %}\\n  {%- set default_cols = dest_columns | map(attribute=\\\"quoted\\\") | list -%}\\n\\n  {%- if merge_update_columns and merge_exclude_columns -%}\\n    {{ exceptions.raise_compiler_error(\\n        'Model cannot specify merge_update_columns and merge_exclude_columns. Please update model to use only one config'\\n    )}}\\n  {%- elif merge_update_columns -%}\\n    {%- set update_columns = merge_update_columns -%}\\n  {%- elif merge_exclude_columns -%}\\n    {%- set update_columns = [] -%}\\n    {%- for column in dest_columns -%}\\n      {% if column.column | lower not in merge_exclude_columns | map(\\\"lower\\\") | list %}\\n        {%- do update_columns.append(column.quoted) -%}\\n      {% endif %}\\n    {%- endfor -%}\\n  {%- else -%}\\n    {%- set update_columns = default_cols -%}\\n  {%- endif -%}\\n\\n  {{ return(update_columns) }}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.845012, \"supported_languages\": null}, \"macro.dbt.get_merge_sql\": {\"unique_id\": \"macro.dbt.get_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"name\": \"get_merge_sql\", \"macro_sql\": \"{% macro get_merge_sql(target, source, unique_key, dest_columns, predicates=none) -%}\\n  {{ adapter.dispatch('get_merge_sql', 'dbt')(target, source, unique_key, dest_columns, predicates) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.8534558, \"supported_languages\": null}, \"macro.dbt.default__get_merge_sql\": {\"unique_id\": \"macro.dbt.default__get_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"name\": \"default__get_merge_sql\", \"macro_sql\": \"{% macro default__get_merge_sql(target, source, unique_key, dest_columns, predicates) -%}\\n    {%- set predicates = [] if predicates is none else [] + predicates -%}\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n    {%- set merge_update_columns = config.get('merge_update_columns') -%}\\n    {%- set merge_exclude_columns = config.get('merge_exclude_columns') -%}\\n    {%- set update_columns = get_merge_update_columns(merge_update_columns, merge_exclude_columns, dest_columns) -%}\\n    {%- set sql_header = config.get('sql_header', none) -%}\\n\\n    {% if unique_key %}\\n        {% if unique_key is sequence and unique_key is not mapping and unique_key is not string %}\\n            {% for key in unique_key %}\\n                {% set this_key_match %}\\n                    DBT_INTERNAL_SOURCE.{{ key }} = DBT_INTERNAL_DEST.{{ key }}\\n                {% endset %}\\n                {% do predicates.append(this_key_match) %}\\n            {% endfor %}\\n        {% else %}\\n            {% set unique_key_match %}\\n                DBT_INTERNAL_SOURCE.{{ unique_key }} = DBT_INTERNAL_DEST.{{ unique_key }}\\n            {% endset %}\\n            {% do predicates.append(unique_key_match) %}\\n        {% endif %}\\n    {% else %}\\n        {% do predicates.append('FALSE') %}\\n    {% endif %}\\n\\n    {{ sql_header if sql_header is not none }}\\n\\n    merge into {{ target }} as DBT_INTERNAL_DEST\\n        using {{ source }} as DBT_INTERNAL_SOURCE\\n        on {{ predicates | join(' and ') }}\\n\\n    {% if unique_key %}\\n    when matched then update set\\n        {% for column_name in update_columns -%}\\n            {{ column_name }} = DBT_INTERNAL_SOURCE.{{ column_name }}\\n            {%- if not loop.last %}, {%- endif %}\\n        {%- endfor %}\\n    {% endif %}\\n\\n    when not matched then insert\\n        ({{ dest_cols_csv }})\\n    values\\n        ({{ dest_cols_csv }})\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_quoted_csv\", \"macro.dbt.get_merge_update_columns\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.857812, \"supported_languages\": null}, \"macro.dbt.get_delete_insert_merge_sql\": {\"unique_id\": \"macro.dbt.get_delete_insert_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"name\": \"get_delete_insert_merge_sql\", \"macro_sql\": \"{% macro get_delete_insert_merge_sql(target, source, unique_key, dest_columns) -%}\\n  {{ adapter.dispatch('get_delete_insert_merge_sql', 'dbt')(target, source, unique_key, dest_columns) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_delete_insert_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.85844, \"supported_languages\": null}, \"macro.dbt.default__get_delete_insert_merge_sql\": {\"unique_id\": \"macro.dbt.default__get_delete_insert_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"name\": \"default__get_delete_insert_merge_sql\", \"macro_sql\": \"{% macro default__get_delete_insert_merge_sql(target, source, unique_key, dest_columns) -%}\\n\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n\\n    {% if unique_key %}\\n        {% if unique_key is sequence and unique_key is not string %}\\n            delete from {{target }}\\n            using {{ source }}\\n            where (\\n                {% for key in unique_key %}\\n                    {{ source }}.{{ key }} = {{ target }}.{{ key }}\\n                    {{ \\\"and \\\" if not loop.last }}\\n                {% endfor %}\\n            );\\n        {% else %}\\n            delete from {{ target }}\\n            where (\\n                {{ unique_key }}) in (\\n                select ({{ unique_key }})\\n                from {{ source }}\\n            );\\n\\n        {% endif %}\\n    {% endif %}\\n\\n    insert into {{ target }} ({{ dest_cols_csv }})\\n    (\\n        select {{ dest_cols_csv }}\\n        from {{ source }}\\n    )\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_quoted_csv\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.8602839, \"supported_languages\": null}, \"macro.dbt.get_insert_overwrite_merge_sql\": {\"unique_id\": \"macro.dbt.get_insert_overwrite_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"name\": \"get_insert_overwrite_merge_sql\", \"macro_sql\": \"{% macro get_insert_overwrite_merge_sql(target, source, dest_columns, predicates, include_sql_header=false) -%}\\n  {{ adapter.dispatch('get_insert_overwrite_merge_sql', 'dbt')(target, source, dest_columns, predicates, include_sql_header) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_insert_overwrite_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.860947, \"supported_languages\": null}, \"macro.dbt.default__get_insert_overwrite_merge_sql\": {\"unique_id\": \"macro.dbt.default__get_insert_overwrite_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"name\": \"default__get_insert_overwrite_merge_sql\", \"macro_sql\": \"{% macro default__get_insert_overwrite_merge_sql(target, source, dest_columns, predicates, include_sql_header) -%}\\n    {#-- The only time include_sql_header is True: --#}\\n    {#-- BigQuery + insert_overwrite strategy + \\\"static\\\" partitions config --#}\\n    {#-- We should consider including the sql header at the materialization level instead --#}\\n\\n    {%- set predicates = [] if predicates is none else [] + predicates -%}\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n    {%- set sql_header = config.get('sql_header', none) -%}\\n\\n    {{ sql_header if sql_header is not none and include_sql_header }}\\n\\n    merge into {{ target }} as DBT_INTERNAL_DEST\\n        using {{ source }} as DBT_INTERNAL_SOURCE\\n        on FALSE\\n\\n    when not matched by source\\n        {% if predicates %} and {{ predicates | join(' and ') }} {% endif %}\\n        then delete\\n\\n    when not matched then insert\\n        ({{ dest_cols_csv }})\\n    values\\n        ({{ dest_cols_csv }})\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_quoted_csv\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.862558, \"supported_languages\": null}, \"macro.dbt.is_incremental\": {\"unique_id\": \"macro.dbt.is_incremental\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/is_incremental.sql\", \"original_file_path\": \"macros/materializations/models/incremental/is_incremental.sql\", \"name\": \"is_incremental\", \"macro_sql\": \"{% macro is_incremental() %}\\n    {#-- do not run introspective queries in parsing #}\\n    {% if not execute %}\\n        {{ return(False) }}\\n    {% else %}\\n        {% set relation = adapter.get_relation(this.database, this.schema, this.table) %}\\n        {{ return(relation is not none\\n                  and relation.type == 'table'\\n                  and model.config.materialized == 'incremental'\\n                  and not should_full_refresh()) }}\\n    {% endif %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.should_full_refresh\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.864465, \"supported_languages\": null}, \"macro.dbt.get_incremental_append_sql\": {\"unique_id\": \"macro.dbt.get_incremental_append_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"name\": \"get_incremental_append_sql\", \"macro_sql\": \"{% macro get_incremental_append_sql(arg_dict) %}\\n\\n  {{ return(adapter.dispatch('get_incremental_append_sql', 'dbt')(arg_dict)) }}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_incremental_append_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.866665, \"supported_languages\": null}, \"macro.dbt.default__get_incremental_append_sql\": {\"unique_id\": \"macro.dbt.default__get_incremental_append_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"name\": \"default__get_incremental_append_sql\", \"macro_sql\": \"{% macro default__get_incremental_append_sql(arg_dict) %}\\n\\n  {% do return(get_insert_into_sql(arg_dict[\\\"target_relation\\\"], arg_dict[\\\"temp_relation\\\"], arg_dict[\\\"dest_columns\\\"])) %}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_insert_into_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.867279, \"supported_languages\": null}, \"macro.dbt.get_incremental_delete_insert_sql\": {\"unique_id\": \"macro.dbt.get_incremental_delete_insert_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"name\": \"get_incremental_delete_insert_sql\", \"macro_sql\": \"{% macro get_incremental_delete_insert_sql(arg_dict) %}\\n\\n  {{ return(adapter.dispatch('get_incremental_delete_insert_sql', 'dbt')(arg_dict)) }}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_incremental_delete_insert_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.867753, \"supported_languages\": null}, \"macro.dbt.default__get_incremental_delete_insert_sql\": {\"unique_id\": \"macro.dbt.default__get_incremental_delete_insert_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"name\": \"default__get_incremental_delete_insert_sql\", \"macro_sql\": \"{% macro default__get_incremental_delete_insert_sql(arg_dict) %}\\n\\n  {% do return(get_delete_insert_merge_sql(arg_dict[\\\"target_relation\\\"], arg_dict[\\\"temp_relation\\\"], arg_dict[\\\"unique_key\\\"], arg_dict[\\\"dest_columns\\\"])) %}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_delete_insert_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.868414, \"supported_languages\": null}, \"macro.dbt.get_incremental_merge_sql\": {\"unique_id\": \"macro.dbt.get_incremental_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"name\": \"get_incremental_merge_sql\", \"macro_sql\": \"{% macro get_incremental_merge_sql(arg_dict) %}\\n\\n  {{ return(adapter.dispatch('get_incremental_merge_sql', 'dbt')(arg_dict)) }}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_incremental_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.868883, \"supported_languages\": null}, \"macro.dbt.default__get_incremental_merge_sql\": {\"unique_id\": \"macro.dbt.default__get_incremental_merge_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"name\": \"default__get_incremental_merge_sql\", \"macro_sql\": \"{% macro default__get_incremental_merge_sql(arg_dict) %}\\n\\n  {% do return(get_merge_sql(arg_dict[\\\"target_relation\\\"], arg_dict[\\\"temp_relation\\\"], arg_dict[\\\"unique_key\\\"], arg_dict[\\\"dest_columns\\\"])) %}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.8695412, \"supported_languages\": null}, \"macro.dbt.get_incremental_insert_overwrite_sql\": {\"unique_id\": \"macro.dbt.get_incremental_insert_overwrite_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"name\": \"get_incremental_insert_overwrite_sql\", \"macro_sql\": \"{% macro get_incremental_insert_overwrite_sql(arg_dict) %}\\n\\n  {{ return(adapter.dispatch('get_incremental_insert_overwrite_sql', 'dbt')(arg_dict)) }}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_incremental_insert_overwrite_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.870015, \"supported_languages\": null}, \"macro.dbt.default__get_incremental_insert_overwrite_sql\": {\"unique_id\": \"macro.dbt.default__get_incremental_insert_overwrite_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"name\": \"default__get_incremental_insert_overwrite_sql\", \"macro_sql\": \"{% macro default__get_incremental_insert_overwrite_sql(arg_dict) %}\\n\\n  {% do return(get_insert_overwrite_merge_sql(arg_dict[\\\"target_relation\\\"], arg_dict[\\\"temp_relation\\\"], arg_dict[\\\"dest_columns\\\"], arg_dict[\\\"predicates\\\"])) %}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_insert_overwrite_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.8706748, \"supported_languages\": null}, \"macro.dbt.get_incremental_default_sql\": {\"unique_id\": \"macro.dbt.get_incremental_default_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"name\": \"get_incremental_default_sql\", \"macro_sql\": \"{% macro get_incremental_default_sql(arg_dict) %}\\n\\n  {{ return(adapter.dispatch('get_incremental_default_sql', 'dbt')(arg_dict)) }}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_incremental_default_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.8712032, \"supported_languages\": null}, \"macro.dbt.default__get_incremental_default_sql\": {\"unique_id\": \"macro.dbt.default__get_incremental_default_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"name\": \"default__get_incremental_default_sql\", \"macro_sql\": \"{% macro default__get_incremental_default_sql(arg_dict) %}\\n\\n  {% do return(get_incremental_append_sql(arg_dict)) %}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_incremental_append_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.871608, \"supported_languages\": null}, \"macro.dbt.get_insert_into_sql\": {\"unique_id\": \"macro.dbt.get_insert_into_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"name\": \"get_insert_into_sql\", \"macro_sql\": \"{% macro get_insert_into_sql(target_relation, temp_relation, dest_columns) %}\\n\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n\\n    insert into {{ target_relation }} ({{ dest_cols_csv }})\\n    (\\n        select {{ dest_cols_csv }}\\n        from {{ temp_relation }}\\n    )\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_quoted_csv\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.872406, \"supported_languages\": null}, \"macro.dbt.materialization_incremental_default\": {\"unique_id\": \"macro.dbt.materialization_incremental_default\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/incremental.sql\", \"original_file_path\": \"macros/materializations/models/incremental/incremental.sql\", \"name\": \"materialization_incremental_default\", \"macro_sql\": \"{% materialization incremental, default -%}\\n\\n  -- relations\\n  {%- set existing_relation = load_cached_relation(this) -%}\\n  {%- set target_relation = this.incorporate(type='table') -%}\\n  {%- set temp_relation = make_temp_relation(target_relation)-%}\\n  {%- set intermediate_relation = make_intermediate_relation(target_relation)-%}\\n  {%- set backup_relation_type = 'table' if existing_relation is none else existing_relation.type -%}\\n  {%- set backup_relation = make_backup_relation(target_relation, backup_relation_type) -%}\\n\\n  -- configs\\n  {%- set unique_key = config.get('unique_key') -%}\\n  {%- set full_refresh_mode = (should_full_refresh()  or existing_relation.is_view) -%}\\n  {%- set on_schema_change = incremental_validate_on_schema_change(config.get('on_schema_change'), default='ignore') -%}\\n\\n  -- the temp_ and backup_ relations should not already exist in the database; get_relation\\n  -- will return None in that case. Otherwise, we get a relation that we can drop\\n  -- later, before we try to use this name for the current operation. This has to happen before\\n  -- BEGIN, in a separate transaction\\n  {%- set preexisting_intermediate_relation = load_cached_relation(intermediate_relation)-%}\\n  {%- set preexisting_backup_relation = load_cached_relation(backup_relation) -%}\\n   -- grab current tables grants config for comparision later on\\n  {% set grant_config = config.get('grants') %}\\n  {{ drop_relation_if_exists(preexisting_intermediate_relation) }}\\n  {{ drop_relation_if_exists(preexisting_backup_relation) }}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  {% set to_drop = [] %}\\n\\n  {% if existing_relation is none %}\\n      {% set build_sql = get_create_table_as_sql(False, target_relation, sql) %}\\n  {% elif full_refresh_mode %}\\n      {% set build_sql = get_create_table_as_sql(False, intermediate_relation, sql) %}\\n      {% set need_swap = true %}\\n  {% else %}\\n    {% do run_query(get_create_table_as_sql(True, temp_relation, sql)) %}\\n    {% do adapter.expand_target_column_types(\\n             from_relation=temp_relation,\\n             to_relation=target_relation) %}\\n    {#-- Process schema changes. Returns dict of changes if successful. Use source columns for upserting/merging --#}\\n    {% set dest_columns = process_schema_changes(on_schema_change, temp_relation, existing_relation) %}\\n    {% if not dest_columns %}\\n      {% set dest_columns = adapter.get_columns_in_relation(existing_relation) %}\\n    {% endif %}\\n\\n    {#-- Get the incremental_strategy, the macro to use for the strategy, and build the sql --#}\\n    {% set incremental_strategy = config.get('incremental_strategy') or 'default' %}\\n    {% set incremental_predicates = config.get('incremental_predicates', none) %}\\n    {% set strategy_sql_macro_func = adapter.get_incremental_strategy_macro(context, incremental_strategy) %}\\n    {% set strategy_arg_dict = ({'target_relation': target_relation, 'temp_relation': temp_relation, 'unique_key': unique_key, 'dest_columns': dest_columns, 'predicates': incremental_predicates }) %}\\n    {% set build_sql = strategy_sql_macro_func(strategy_arg_dict) %}\\n\\n  {% endif %}\\n\\n  {% call statement(\\\"main\\\") %}\\n      {{ build_sql }}\\n  {% endcall %}\\n\\n  {% if need_swap %}\\n      {% do adapter.rename_relation(target_relation, backup_relation) %}\\n      {% do adapter.rename_relation(intermediate_relation, target_relation) %}\\n      {% do to_drop.append(backup_relation) %}\\n  {% endif %}\\n\\n  {% set should_revoke = should_revoke(existing_relation, full_refresh_mode) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {% if existing_relation is none or existing_relation.is_view or should_full_refresh() %}\\n    {% do create_indexes(target_relation) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  -- `COMMIT` happens here\\n  {% do adapter.commit() %}\\n\\n  {% for rel in to_drop %}\\n      {% do adapter.drop_relation(rel) %}\\n  {% endfor %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{%- endmaterialization %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.load_cached_relation\", \"macro.dbt.make_temp_relation\", \"macro.dbt.make_intermediate_relation\", \"macro.dbt.make_backup_relation\", \"macro.dbt.should_full_refresh\", \"macro.dbt.incremental_validate_on_schema_change\", \"macro.dbt.drop_relation_if_exists\", \"macro.dbt.run_hooks\", \"macro.dbt.get_create_table_as_sql\", \"macro.dbt.run_query\", \"macro.dbt.process_schema_changes\", \"macro.dbt.statement\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\", \"macro.dbt.persist_docs\", \"macro.dbt.create_indexes\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.8839822, \"supported_languages\": [\"sql\"]}, \"macro.dbt.incremental_validate_on_schema_change\": {\"unique_id\": \"macro.dbt.incremental_validate_on_schema_change\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"original_file_path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"name\": \"incremental_validate_on_schema_change\", \"macro_sql\": \"{% macro incremental_validate_on_schema_change(on_schema_change, default='ignore') %}\\n\\n   {% if on_schema_change not in ['sync_all_columns', 'append_new_columns', 'fail', 'ignore'] %}\\n\\n     {% set log_message = 'Invalid value for on_schema_change (%s) specified. Setting default value of %s.' % (on_schema_change, default) %}\\n     {% do log(log_message) %}\\n\\n     {{ return(default) }}\\n\\n   {% else %}\\n\\n     {{ return(on_schema_change) }}\\n\\n   {% endif %}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.894743, \"supported_languages\": null}, \"macro.dbt.check_for_schema_changes\": {\"unique_id\": \"macro.dbt.check_for_schema_changes\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"original_file_path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"name\": \"check_for_schema_changes\", \"macro_sql\": \"{% macro check_for_schema_changes(source_relation, target_relation) %}\\n\\n  {% set schema_changed = False %}\\n\\n  {%- set source_columns = adapter.get_columns_in_relation(source_relation) -%}\\n  {%- set target_columns = adapter.get_columns_in_relation(target_relation) -%}\\n  {%- set source_not_in_target = diff_columns(source_columns, target_columns) -%}\\n  {%- set target_not_in_source = diff_columns(target_columns, source_columns) -%}\\n\\n  {% set new_target_types = diff_column_data_types(source_columns, target_columns) %}\\n\\n  {% if source_not_in_target != [] %}\\n    {% set schema_changed = True %}\\n  {% elif target_not_in_source != [] or new_target_types != [] %}\\n    {% set schema_changed = True %}\\n  {% elif new_target_types != [] %}\\n    {% set schema_changed = True %}\\n  {% endif %}\\n\\n  {% set changes_dict = {\\n    'schema_changed': schema_changed,\\n    'source_not_in_target': source_not_in_target,\\n    'target_not_in_source': target_not_in_source,\\n    'source_columns': source_columns,\\n    'target_columns': target_columns,\\n    'new_target_types': new_target_types\\n  } %}\\n\\n  {% set msg %}\\n    In {{ target_relation }}:\\n        Schema changed: {{ schema_changed }}\\n        Source columns not in target: {{ source_not_in_target }}\\n        Target columns not in source: {{ target_not_in_source }}\\n        New column types: {{ new_target_types }}\\n  {% endset %}\\n\\n  {% do log(msg) %}\\n\\n  {{ return(changes_dict) }}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.diff_columns\", \"macro.dbt.diff_column_data_types\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.8977559, \"supported_languages\": null}, \"macro.dbt.sync_column_schemas\": {\"unique_id\": \"macro.dbt.sync_column_schemas\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"original_file_path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"name\": \"sync_column_schemas\", \"macro_sql\": \"{% macro sync_column_schemas(on_schema_change, target_relation, schema_changes_dict) %}\\n\\n  {%- set add_to_target_arr = schema_changes_dict['source_not_in_target'] -%}\\n\\n  {%- if on_schema_change == 'append_new_columns'-%}\\n     {%- if add_to_target_arr | length > 0 -%}\\n       {%- do alter_relation_add_remove_columns(target_relation, add_to_target_arr, none) -%}\\n     {%- endif -%}\\n\\n  {% elif on_schema_change == 'sync_all_columns' %}\\n     {%- set remove_from_target_arr = schema_changes_dict['target_not_in_source'] -%}\\n     {%- set new_target_types = schema_changes_dict['new_target_types'] -%}\\n\\n     {% if add_to_target_arr | length > 0 or remove_from_target_arr | length > 0 %}\\n       {%- do alter_relation_add_remove_columns(target_relation, add_to_target_arr, remove_from_target_arr) -%}\\n     {% endif %}\\n\\n     {% if new_target_types != [] %}\\n       {% for ntt in new_target_types %}\\n         {% set column_name = ntt['column_name'] %}\\n         {% set new_type = ntt['new_type'] %}\\n         {% do alter_column_type(target_relation, column_name, new_type) %}\\n       {% endfor %}\\n     {% endif %}\\n\\n  {% endif %}\\n\\n  {% set schema_change_message %}\\n    In {{ target_relation }}:\\n        Schema change approach: {{ on_schema_change }}\\n        Columns added: {{ add_to_target_arr }}\\n        Columns removed: {{ remove_from_target_arr }}\\n        Data types changed: {{ new_target_types }}\\n  {% endset %}\\n\\n  {% do log(schema_change_message) %}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.alter_relation_add_remove_columns\", \"macro.dbt.alter_column_type\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.900897, \"supported_languages\": null}, \"macro.dbt.process_schema_changes\": {\"unique_id\": \"macro.dbt.process_schema_changes\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"original_file_path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"name\": \"process_schema_changes\", \"macro_sql\": \"{% macro process_schema_changes(on_schema_change, source_relation, target_relation) %}\\n\\n    {% if on_schema_change == 'ignore' %}\\n\\n     {{ return({}) }}\\n\\n    {% else %}\\n\\n      {% set schema_changes_dict = check_for_schema_changes(source_relation, target_relation) %}\\n\\n      {% if schema_changes_dict['schema_changed'] %}\\n\\n        {% if on_schema_change == 'fail' %}\\n\\n          {% set fail_msg %}\\n              The source and target schemas on this incremental model are out of sync!\\n              They can be reconciled in several ways:\\n                - set the `on_schema_change` config to either append_new_columns or sync_all_columns, depending on your situation.\\n                - Re-run the incremental model with `full_refresh: True` to update the target schema.\\n                - update the schema manually and re-run the process.\\n\\n              Additional troubleshooting context:\\n                 Source columns not in target: {{ schema_changes_dict['source_not_in_target'] }}\\n                 Target columns not in source: {{ schema_changes_dict['target_not_in_source'] }}\\n                 New column types: {{ schema_changes_dict['new_target_types'] }}\\n          {% endset %}\\n\\n          {% do exceptions.raise_compiler_error(fail_msg) %}\\n\\n        {# -- unless we ignore, run the sync operation per the config #}\\n        {% else %}\\n\\n          {% do sync_column_schemas(on_schema_change, target_relation, schema_changes_dict) %}\\n\\n        {% endif %}\\n\\n      {% endif %}\\n\\n      {{ return(schema_changes_dict['source_columns']) }}\\n\\n    {% endif %}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.check_for_schema_changes\", \"macro.dbt.sync_column_schemas\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.9030159, \"supported_languages\": null}, \"macro.dbt.materialization_table_default\": {\"unique_id\": \"macro.dbt.materialization_table_default\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/models/table/table.sql\", \"original_file_path\": \"macros/materializations/models/table/table.sql\", \"name\": \"materialization_table_default\", \"macro_sql\": \"{% materialization table, default %}\\n\\n  {%- set existing_relation = load_cached_relation(this) -%}\\n  {%- set target_relation = this.incorporate(type='table') %}\\n  {%- set intermediate_relation =  make_intermediate_relation(target_relation) -%}\\n  -- the intermediate_relation should not already exist in the database; get_relation\\n  -- will return None in that case. Otherwise, we get a relation that we can drop\\n  -- later, before we try to use this name for the current operation\\n  {%- set preexisting_intermediate_relation = load_cached_relation(intermediate_relation) -%}\\n  /*\\n      See ../view/view.sql for more information about this relation.\\n  */\\n  {%- set backup_relation_type = 'table' if existing_relation is none else existing_relation.type -%}\\n  {%- set backup_relation = make_backup_relation(target_relation, backup_relation_type) -%}\\n  -- as above, the backup_relation should not already exist\\n  {%- set preexisting_backup_relation = load_cached_relation(backup_relation) -%}\\n  -- grab current tables grants config for comparision later on\\n  {% set grant_config = config.get('grants') %}\\n\\n  -- drop the temp relations if they exist already in the database\\n  {{ drop_relation_if_exists(preexisting_intermediate_relation) }}\\n  {{ drop_relation_if_exists(preexisting_backup_relation) }}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  -- build model\\n  {% call statement('main') -%}\\n    {{ get_create_table_as_sql(False, intermediate_relation, sql) }}\\n  {%- endcall %}\\n\\n  -- cleanup\\n  {% if existing_relation is not none %}\\n      {{ adapter.rename_relation(existing_relation, backup_relation) }}\\n  {% endif %}\\n\\n  {{ adapter.rename_relation(intermediate_relation, target_relation) }}\\n\\n  {% do create_indexes(target_relation) %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  {% set should_revoke = should_revoke(existing_relation, full_refresh_mode=True) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  -- `COMMIT` happens here\\n  {{ adapter.commit() }}\\n\\n  -- finally, drop the existing/backup relation after the commit\\n  {{ drop_relation_if_exists(backup_relation) }}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n{% endmaterialization %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.load_cached_relation\", \"macro.dbt.make_intermediate_relation\", \"macro.dbt.make_backup_relation\", \"macro.dbt.drop_relation_if_exists\", \"macro.dbt.run_hooks\", \"macro.dbt.statement\", \"macro.dbt.get_create_table_as_sql\", \"macro.dbt.create_indexes\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\", \"macro.dbt.persist_docs\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.909476, \"supported_languages\": [\"sql\"]}, \"macro.dbt.get_create_table_as_sql\": {\"unique_id\": \"macro.dbt.get_create_table_as_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/models/table/create_table_as.sql\", \"original_file_path\": \"macros/materializations/models/table/create_table_as.sql\", \"name\": \"get_create_table_as_sql\", \"macro_sql\": \"{% macro get_create_table_as_sql(temporary, relation, sql) -%}\\n  {{ adapter.dispatch('get_create_table_as_sql', 'dbt')(temporary, relation, sql) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_create_table_as_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.911144, \"supported_languages\": null}, \"macro.dbt.default__get_create_table_as_sql\": {\"unique_id\": \"macro.dbt.default__get_create_table_as_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/models/table/create_table_as.sql\", \"original_file_path\": \"macros/materializations/models/table/create_table_as.sql\", \"name\": \"default__get_create_table_as_sql\", \"macro_sql\": \"{% macro default__get_create_table_as_sql(temporary, relation, sql) -%}\\n  {{ return(create_table_as(temporary, relation, sql)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.create_table_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.911638, \"supported_languages\": null}, \"macro.dbt.create_table_as\": {\"unique_id\": \"macro.dbt.create_table_as\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/models/table/create_table_as.sql\", \"original_file_path\": \"macros/materializations/models/table/create_table_as.sql\", \"name\": \"create_table_as\", \"macro_sql\": \"{% macro create_table_as(temporary, relation, compiled_code, language='sql') -%}\\n  {# backward compatibility for create_table_as that does not support language #}\\n  {% if language == \\\"sql\\\" %}\\n    {{ adapter.dispatch('create_table_as', 'dbt')(temporary, relation, compiled_code)}}\\n  {% else %}\\n    {{ adapter.dispatch('create_table_as', 'dbt')(temporary, relation, compiled_code, language) }}\\n  {% endif %}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__create_table_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.912726, \"supported_languages\": null}, \"macro.dbt.default__create_table_as\": {\"unique_id\": \"macro.dbt.default__create_table_as\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/models/table/create_table_as.sql\", \"original_file_path\": \"macros/materializations/models/table/create_table_as.sql\", \"name\": \"default__create_table_as\", \"macro_sql\": \"{% macro default__create_table_as(temporary, relation, sql) -%}\\n  {%- set sql_header = config.get('sql_header', none) -%}\\n\\n  {{ sql_header if sql_header is not none }}\\n\\n  create {% if temporary: -%}temporary{%- endif %} table\\n    {{ relation.include(database=(not temporary), schema=(not temporary)) }}\\n  as (\\n    {{ sql }}\\n  );\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.9137652, \"supported_languages\": null}, \"macro.dbt.materialization_view_default\": {\"unique_id\": \"macro.dbt.materialization_view_default\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/models/view/view.sql\", \"original_file_path\": \"macros/materializations/models/view/view.sql\", \"name\": \"materialization_view_default\", \"macro_sql\": \"{%- materialization view, default -%}\\n\\n  {%- set existing_relation = load_cached_relation(this) -%}\\n  {%- set target_relation = this.incorporate(type='view') -%}\\n  {%- set intermediate_relation =  make_intermediate_relation(target_relation) -%}\\n\\n  -- the intermediate_relation should not already exist in the database; get_relation\\n  -- will return None in that case. Otherwise, we get a relation that we can drop\\n  -- later, before we try to use this name for the current operation\\n  {%- set preexisting_intermediate_relation = load_cached_relation(intermediate_relation) -%}\\n  /*\\n     This relation (probably) doesn't exist yet. If it does exist, it's a leftover from\\n     a previous run, and we're going to try to drop it immediately. At the end of this\\n     materialization, we're going to rename the \\\"existing_relation\\\" to this identifier,\\n     and then we're going to drop it. In order to make sure we run the correct one of:\\n       - drop view ...\\n       - drop table ...\\n\\n     We need to set the type of this relation to be the type of the existing_relation, if it exists,\\n     or else \\\"view\\\" as a sane default if it does not. Note that if the existing_relation does not\\n     exist, then there is nothing to move out of the way and subsequentally drop. In that case,\\n     this relation will be effectively unused.\\n  */\\n  {%- set backup_relation_type = 'view' if existing_relation is none else existing_relation.type -%}\\n  {%- set backup_relation = make_backup_relation(target_relation, backup_relation_type) -%}\\n  -- as above, the backup_relation should not already exist\\n  {%- set preexisting_backup_relation = load_cached_relation(backup_relation) -%}\\n  -- grab current tables grants config for comparision later on\\n  {% set grant_config = config.get('grants') %}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- drop the temp relations if they exist already in the database\\n  {{ drop_relation_if_exists(preexisting_intermediate_relation) }}\\n  {{ drop_relation_if_exists(preexisting_backup_relation) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  -- build model\\n  {% call statement('main') -%}\\n    {{ get_create_view_as_sql(intermediate_relation, sql) }}\\n  {%- endcall %}\\n\\n  -- cleanup\\n  -- move the existing view out of the way\\n  {% if existing_relation is not none %}\\n    {{ adapter.rename_relation(existing_relation, backup_relation) }}\\n  {% endif %}\\n  {{ adapter.rename_relation(intermediate_relation, target_relation) }}\\n\\n  {% set should_revoke = should_revoke(existing_relation, full_refresh_mode=True) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  {{ adapter.commit() }}\\n\\n  {{ drop_relation_if_exists(backup_relation) }}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{%- endmaterialization -%}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.load_cached_relation\", \"macro.dbt.make_intermediate_relation\", \"macro.dbt.make_backup_relation\", \"macro.dbt.run_hooks\", \"macro.dbt.drop_relation_if_exists\", \"macro.dbt.statement\", \"macro.dbt.get_create_view_as_sql\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\", \"macro.dbt.persist_docs\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.919893, \"supported_languages\": [\"sql\"]}, \"macro.dbt.handle_existing_table\": {\"unique_id\": \"macro.dbt.handle_existing_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/models/view/helpers.sql\", \"original_file_path\": \"macros/materializations/models/view/helpers.sql\", \"name\": \"handle_existing_table\", \"macro_sql\": \"{% macro handle_existing_table(full_refresh, old_relation) %}\\n    {{ adapter.dispatch('handle_existing_table', 'dbt')(full_refresh, old_relation) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__handle_existing_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.921067, \"supported_languages\": null}, \"macro.dbt.default__handle_existing_table\": {\"unique_id\": \"macro.dbt.default__handle_existing_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/models/view/helpers.sql\", \"original_file_path\": \"macros/materializations/models/view/helpers.sql\", \"name\": \"default__handle_existing_table\", \"macro_sql\": \"{% macro default__handle_existing_table(full_refresh, old_relation) %}\\n    {{ log(\\\"Dropping relation \\\" ~ old_relation ~ \\\" because it is of type \\\" ~ old_relation.type) }}\\n    {{ adapter.drop_relation(old_relation) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.921632, \"supported_languages\": null}, \"macro.dbt.create_or_replace_view\": {\"unique_id\": \"macro.dbt.create_or_replace_view\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/models/view/create_or_replace_view.sql\", \"original_file_path\": \"macros/materializations/models/view/create_or_replace_view.sql\", \"name\": \"create_or_replace_view\", \"macro_sql\": \"{% macro create_or_replace_view() %}\\n  {%- set identifier = model['alias'] -%}\\n\\n  {%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%}\\n  {%- set exists_as_view = (old_relation is not none and old_relation.is_view) -%}\\n\\n  {%- set target_relation = api.Relation.create(\\n      identifier=identifier, schema=schema, database=database,\\n      type='view') -%}\\n  {% set grant_config = config.get('grants') %}\\n\\n  {{ run_hooks(pre_hooks) }}\\n\\n  -- If there's a table with the same name and we weren't told to full refresh,\\n  -- that's an error. If we were told to full refresh, drop it. This behavior differs\\n  -- for Snowflake and BigQuery, so multiple dispatch is used.\\n  {%- if old_relation is not none and old_relation.is_table -%}\\n    {{ handle_existing_table(should_full_refresh(), old_relation) }}\\n  {%- endif -%}\\n\\n  -- build model\\n  {% call statement('main') -%}\\n    {{ get_create_view_as_sql(target_relation, sql) }}\\n  {%- endcall %}\\n\\n  {% set should_revoke = should_revoke(exists_as_view, full_refresh_mode=True) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=True) %}\\n\\n  {{ run_hooks(post_hooks) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.run_hooks\", \"macro.dbt.handle_existing_table\", \"macro.dbt.should_full_refresh\", \"macro.dbt.statement\", \"macro.dbt.get_create_view_as_sql\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.925656, \"supported_languages\": null}, \"macro.dbt.get_create_view_as_sql\": {\"unique_id\": \"macro.dbt.get_create_view_as_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/models/view/create_view_as.sql\", \"original_file_path\": \"macros/materializations/models/view/create_view_as.sql\", \"name\": \"get_create_view_as_sql\", \"macro_sql\": \"{% macro get_create_view_as_sql(relation, sql) -%}\\n  {{ adapter.dispatch('get_create_view_as_sql', 'dbt')(relation, sql) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_create_view_as_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.926919, \"supported_languages\": null}, \"macro.dbt.default__get_create_view_as_sql\": {\"unique_id\": \"macro.dbt.default__get_create_view_as_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/models/view/create_view_as.sql\", \"original_file_path\": \"macros/materializations/models/view/create_view_as.sql\", \"name\": \"default__get_create_view_as_sql\", \"macro_sql\": \"{% macro default__get_create_view_as_sql(relation, sql) -%}\\n  {{ return(create_view_as(relation, sql)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.create_view_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.927346, \"supported_languages\": null}, \"macro.dbt.create_view_as\": {\"unique_id\": \"macro.dbt.create_view_as\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/models/view/create_view_as.sql\", \"original_file_path\": \"macros/materializations/models/view/create_view_as.sql\", \"name\": \"create_view_as\", \"macro_sql\": \"{% macro create_view_as(relation, sql) -%}\\n  {{ adapter.dispatch('create_view_as', 'dbt')(relation, sql) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__create_view_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.9278772, \"supported_languages\": null}, \"macro.dbt.default__create_view_as\": {\"unique_id\": \"macro.dbt.default__create_view_as\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/models/view/create_view_as.sql\", \"original_file_path\": \"macros/materializations/models/view/create_view_as.sql\", \"name\": \"default__create_view_as\", \"macro_sql\": \"{% macro default__create_view_as(relation, sql) -%}\\n  {%- set sql_header = config.get('sql_header', none) -%}\\n\\n  {{ sql_header if sql_header is not none }}\\n  create view {{ relation }} as (\\n    {{ sql }}\\n  );\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.928556, \"supported_languages\": null}, \"macro.dbt.materialization_seed_default\": {\"unique_id\": \"macro.dbt.materialization_seed_default\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/seed.sql\", \"original_file_path\": \"macros/materializations/seeds/seed.sql\", \"name\": \"materialization_seed_default\", \"macro_sql\": \"{% materialization seed, default %}\\n\\n  {%- set identifier = model['alias'] -%}\\n  {%- set full_refresh_mode = (should_full_refresh()) -%}\\n\\n  {%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%}\\n\\n  {%- set exists_as_table = (old_relation is not none and old_relation.is_table) -%}\\n  {%- set exists_as_view = (old_relation is not none and old_relation.is_view) -%}\\n\\n  {%- set grant_config = config.get('grants') -%}\\n  {%- set agate_table = load_agate_table() -%}\\n  -- grab current tables grants config for comparision later on\\n\\n  {%- do store_result('agate_table', response='OK', agate_table=agate_table) -%}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  -- build model\\n  {% set create_table_sql = \\\"\\\" %}\\n  {% if exists_as_view %}\\n    {{ exceptions.raise_compiler_error(\\\"Cannot seed to '{}', it is a view\\\".format(old_relation)) }}\\n  {% elif exists_as_table %}\\n    {% set create_table_sql = reset_csv_table(model, full_refresh_mode, old_relation, agate_table) %}\\n  {% else %}\\n    {% set create_table_sql = create_csv_table(model, agate_table) %}\\n  {% endif %}\\n\\n  {% set code = 'CREATE' if full_refresh_mode else 'INSERT' %}\\n  {% set rows_affected = (agate_table.rows | length) %}\\n  {% set sql = load_csv_rows(model, agate_table) %}\\n\\n  {% call noop_statement('main', code ~ ' ' ~ rows_affected, code, rows_affected) %}\\n    {{ get_csv_sql(create_table_sql, sql) }};\\n  {% endcall %}\\n\\n  {% set target_relation = this.incorporate(type='table') %}\\n\\n  {% set should_revoke = should_revoke(old_relation, full_refresh_mode) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {% if full_refresh_mode or not exists_as_table %}\\n    {% do create_indexes(target_relation) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  -- `COMMIT` happens here\\n  {{ adapter.commit() }}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{% endmaterialization %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.should_full_refresh\", \"macro.dbt.run_hooks\", \"macro.dbt.reset_csv_table\", \"macro.dbt.create_csv_table\", \"macro.dbt.load_csv_rows\", \"macro.dbt.noop_statement\", \"macro.dbt.get_csv_sql\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\", \"macro.dbt.persist_docs\", \"macro.dbt.create_indexes\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.9364128, \"supported_languages\": [\"sql\"]}, \"macro.dbt.create_csv_table\": {\"unique_id\": \"macro.dbt.create_csv_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"create_csv_table\", \"macro_sql\": \"{% macro create_csv_table(model, agate_table) -%}\\n  {{ adapter.dispatch('create_csv_table', 'dbt')(model, agate_table) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__create_csv_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.9457762, \"supported_languages\": null}, \"macro.dbt.default__create_csv_table\": {\"unique_id\": \"macro.dbt.default__create_csv_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"default__create_csv_table\", \"macro_sql\": \"{% macro default__create_csv_table(model, agate_table) %}\\n  {%- set column_override = model['config'].get('column_types', {}) -%}\\n  {%- set quote_seed_column = model['config'].get('quote_columns', None) -%}\\n\\n  {% set sql %}\\n    create table {{ this.render() }} (\\n        {%- for col_name in agate_table.column_names -%}\\n            {%- set inferred_type = adapter.convert_type(agate_table, loop.index0) -%}\\n            {%- set type = column_override.get(col_name, inferred_type) -%}\\n            {%- set column_name = (col_name | string) -%}\\n            {{ adapter.quote_seed_column(column_name, quote_seed_column) }} {{ type }} {%- if not loop.last -%}, {%- endif -%}\\n        {%- endfor -%}\\n    )\\n  {% endset %}\\n\\n  {% call statement('_') -%}\\n    {{ sql }}\\n  {%- endcall %}\\n\\n  {{ return(sql) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.948132, \"supported_languages\": null}, \"macro.dbt.reset_csv_table\": {\"unique_id\": \"macro.dbt.reset_csv_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"reset_csv_table\", \"macro_sql\": \"{% macro reset_csv_table(model, full_refresh, old_relation, agate_table) -%}\\n  {{ adapter.dispatch('reset_csv_table', 'dbt')(model, full_refresh, old_relation, agate_table) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__reset_csv_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.948717, \"supported_languages\": null}, \"macro.dbt.default__reset_csv_table\": {\"unique_id\": \"macro.dbt.default__reset_csv_table\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"default__reset_csv_table\", \"macro_sql\": \"{% macro default__reset_csv_table(model, full_refresh, old_relation, agate_table) %}\\n    {% set sql = \\\"\\\" %}\\n    {% if full_refresh %}\\n        {{ adapter.drop_relation(old_relation) }}\\n        {% set sql = create_csv_table(model, agate_table) %}\\n    {% else %}\\n        {{ adapter.truncate_relation(old_relation) }}\\n        {% set sql = \\\"truncate table \\\" ~ old_relation %}\\n    {% endif %}\\n\\n    {{ return(sql) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.create_csv_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.9499142, \"supported_languages\": null}, \"macro.dbt.get_csv_sql\": {\"unique_id\": \"macro.dbt.get_csv_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"get_csv_sql\", \"macro_sql\": \"{% macro get_csv_sql(create_or_truncate_sql, insert_sql) %}\\n    {{ adapter.dispatch('get_csv_sql', 'dbt')(create_or_truncate_sql, insert_sql) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_csv_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.9503942, \"supported_languages\": null}, \"macro.dbt.default__get_csv_sql\": {\"unique_id\": \"macro.dbt.default__get_csv_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"default__get_csv_sql\", \"macro_sql\": \"{% macro default__get_csv_sql(create_or_truncate_sql, insert_sql) %}\\n    {{ create_or_truncate_sql }};\\n    -- dbt seed --\\n    {{ insert_sql }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.950737, \"supported_languages\": null}, \"macro.dbt.get_binding_char\": {\"unique_id\": \"macro.dbt.get_binding_char\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"get_binding_char\", \"macro_sql\": \"{% macro get_binding_char() -%}\\n  {{ adapter.dispatch('get_binding_char', 'dbt')() }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_binding_char\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.9510899, \"supported_languages\": null}, \"macro.dbt.default__get_binding_char\": {\"unique_id\": \"macro.dbt.default__get_binding_char\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"default__get_binding_char\", \"macro_sql\": \"{% macro default__get_binding_char() %}\\n  {{ return('%s') }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.951392, \"supported_languages\": null}, \"macro.dbt.get_batch_size\": {\"unique_id\": \"macro.dbt.get_batch_size\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"get_batch_size\", \"macro_sql\": \"{% macro get_batch_size() -%}\\n  {{ return(adapter.dispatch('get_batch_size', 'dbt')()) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_batch_size\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.9517949, \"supported_languages\": null}, \"macro.dbt.default__get_batch_size\": {\"unique_id\": \"macro.dbt.default__get_batch_size\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"default__get_batch_size\", \"macro_sql\": \"{% macro default__get_batch_size() %}\\n  {{ return(10000) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.9521081, \"supported_languages\": null}, \"macro.dbt.get_seed_column_quoted_csv\": {\"unique_id\": \"macro.dbt.get_seed_column_quoted_csv\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"get_seed_column_quoted_csv\", \"macro_sql\": \"{% macro get_seed_column_quoted_csv(model, column_names) %}\\n  {%- set quote_seed_column = model['config'].get('quote_columns', None) -%}\\n    {% set quoted = [] %}\\n    {% for col in column_names -%}\\n        {%- do quoted.append(adapter.quote_seed_column(col, quote_seed_column)) -%}\\n    {%- endfor %}\\n\\n    {%- set dest_cols_csv = quoted | join(', ') -%}\\n    {{ return(dest_cols_csv) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.9532878, \"supported_languages\": null}, \"macro.dbt.load_csv_rows\": {\"unique_id\": \"macro.dbt.load_csv_rows\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"load_csv_rows\", \"macro_sql\": \"{% macro load_csv_rows(model, agate_table) -%}\\n  {{ adapter.dispatch('load_csv_rows', 'dbt')(model, agate_table) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__load_csv_rows\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.9537542, \"supported_languages\": null}, \"macro.dbt.default__load_csv_rows\": {\"unique_id\": \"macro.dbt.default__load_csv_rows\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"name\": \"default__load_csv_rows\", \"macro_sql\": \"{% macro default__load_csv_rows(model, agate_table) %}\\n\\n  {% set batch_size = get_batch_size() %}\\n\\n  {% set cols_sql = get_seed_column_quoted_csv(model, agate_table.column_names) %}\\n  {% set bindings = [] %}\\n\\n  {% set statements = [] %}\\n\\n  {% for chunk in agate_table.rows | batch(batch_size) %}\\n      {% set bindings = [] %}\\n\\n      {% for row in chunk %}\\n          {% do bindings.extend(row) %}\\n      {% endfor %}\\n\\n      {% set sql %}\\n          insert into {{ this.render() }} ({{ cols_sql }}) values\\n          {% for row in chunk -%}\\n              ({%- for column in agate_table.column_names -%}\\n                  {{ get_binding_char() }}\\n                  {%- if not loop.last%},{%- endif %}\\n              {%- endfor -%})\\n              {%- if not loop.last%},{%- endif %}\\n          {%- endfor %}\\n      {% endset %}\\n\\n      {% do adapter.add_query(sql, bindings=bindings, abridge_sql_log=True) %}\\n\\n      {% if loop.index0 == 0 %}\\n          {% do statements.append(sql) %}\\n      {% endif %}\\n  {% endfor %}\\n\\n  {# Return SQL so we can render it out into the compiled files #}\\n  {{ return(statements[0]) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_batch_size\", \"macro.dbt.get_seed_column_quoted_csv\", \"macro.dbt.get_binding_char\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.957227, \"supported_languages\": null}, \"macro.dbt.generate_alias_name\": {\"unique_id\": \"macro.dbt.generate_alias_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/get_custom_name/get_custom_alias.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_alias.sql\", \"name\": \"generate_alias_name\", \"macro_sql\": \"{% macro generate_alias_name(custom_alias_name=none, node=none) -%}\\n    {% do return(adapter.dispatch('generate_alias_name', 'dbt')(custom_alias_name, node)) %}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__generate_alias_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.958654, \"supported_languages\": null}, \"macro.dbt.default__generate_alias_name\": {\"unique_id\": \"macro.dbt.default__generate_alias_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/get_custom_name/get_custom_alias.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_alias.sql\", \"name\": \"default__generate_alias_name\", \"macro_sql\": \"{% macro default__generate_alias_name(custom_alias_name=none, node=none) -%}\\n\\n    {%- if custom_alias_name is none -%}\\n\\n        {{ node.name }}\\n\\n    {%- else -%}\\n\\n        {{ custom_alias_name | trim }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.959223, \"supported_languages\": null}, \"macro.dbt.generate_schema_name\": {\"unique_id\": \"macro.dbt.generate_schema_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/get_custom_name/get_custom_schema.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_schema.sql\", \"name\": \"generate_schema_name\", \"macro_sql\": \"{% macro generate_schema_name(custom_schema_name=none, node=none) -%}\\n    {{ return(adapter.dispatch('generate_schema_name', 'dbt')(custom_schema_name, node)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__generate_schema_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.9607859, \"supported_languages\": null}, \"macro.dbt.default__generate_schema_name\": {\"unique_id\": \"macro.dbt.default__generate_schema_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/get_custom_name/get_custom_schema.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_schema.sql\", \"name\": \"default__generate_schema_name\", \"macro_sql\": \"{% macro default__generate_schema_name(custom_schema_name, node) -%}\\n\\n    {%- set default_schema = target.schema -%}\\n    {%- if custom_schema_name is none -%}\\n\\n        {{ default_schema }}\\n\\n    {%- else -%}\\n\\n        {{ default_schema }}_{{ custom_schema_name | trim }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.961487, \"supported_languages\": null}, \"macro.dbt.generate_schema_name_for_env\": {\"unique_id\": \"macro.dbt.generate_schema_name_for_env\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/get_custom_name/get_custom_schema.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_schema.sql\", \"name\": \"generate_schema_name_for_env\", \"macro_sql\": \"{% macro generate_schema_name_for_env(custom_schema_name, node) -%}\\n\\n    {%- set default_schema = target.schema -%}\\n    {%- if target.name == 'prod' and custom_schema_name is not none -%}\\n\\n        {{ custom_schema_name | trim }}\\n\\n    {%- else -%}\\n\\n        {{ default_schema }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.962187, \"supported_languages\": null}, \"macro.dbt.generate_database_name\": {\"unique_id\": \"macro.dbt.generate_database_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/get_custom_name/get_custom_database.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_database.sql\", \"name\": \"generate_database_name\", \"macro_sql\": \"{% macro generate_database_name(custom_database_name=none, node=none) -%}\\n    {% do return(adapter.dispatch('generate_database_name', 'dbt')(custom_database_name, node)) %}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__generate_database_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.963528, \"supported_languages\": null}, \"macro.dbt.default__generate_database_name\": {\"unique_id\": \"macro.dbt.default__generate_database_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/get_custom_name/get_custom_database.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_database.sql\", \"name\": \"default__generate_database_name\", \"macro_sql\": \"{% macro default__generate_database_name(custom_database_name=none, node=none) -%}\\n    {%- set default_database = target.database -%}\\n    {%- if custom_database_name is none -%}\\n\\n        {{ default_database }}\\n\\n    {%- else -%}\\n\\n        {{ custom_database_name }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.9641569, \"supported_languages\": null}, \"macro.dbt.default__test_relationships\": {\"unique_id\": \"macro.dbt.default__test_relationships\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/generic_test_sql/relationships.sql\", \"original_file_path\": \"macros/generic_test_sql/relationships.sql\", \"name\": \"default__test_relationships\", \"macro_sql\": \"{% macro default__test_relationships(model, column_name, to, field) %}\\n\\nwith child as (\\n    select {{ column_name }} as from_field\\n    from {{ model }}\\n    where {{ column_name }} is not null\\n),\\n\\nparent as (\\n    select {{ field }} as to_field\\n    from {{ to }}\\n)\\n\\nselect\\n    from_field\\n\\nfrom child\\nleft join parent\\n    on child.from_field = parent.to_field\\n\\nwhere parent.to_field is null\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.9653509, \"supported_languages\": null}, \"macro.dbt.default__test_not_null\": {\"unique_id\": \"macro.dbt.default__test_not_null\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/generic_test_sql/not_null.sql\", \"original_file_path\": \"macros/generic_test_sql/not_null.sql\", \"name\": \"default__test_not_null\", \"macro_sql\": \"{% macro default__test_not_null(model, column_name) %}\\n\\n{% set column_list = '*' if should_store_failures() else column_name %}\\n\\nselect {{ column_list }}\\nfrom {{ model }}\\nwhere {{ column_name }} is null\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.should_store_failures\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.966414, \"supported_languages\": null}, \"macro.dbt.default__test_unique\": {\"unique_id\": \"macro.dbt.default__test_unique\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/generic_test_sql/unique.sql\", \"original_file_path\": \"macros/generic_test_sql/unique.sql\", \"name\": \"default__test_unique\", \"macro_sql\": \"{% macro default__test_unique(model, column_name) %}\\n\\nselect\\n    {{ column_name }} as unique_field,\\n    count(*) as n_records\\n\\nfrom {{ model }}\\nwhere {{ column_name }} is not null\\ngroup by {{ column_name }}\\nhaving count(*) > 1\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.967387, \"supported_languages\": null}, \"macro.dbt.default__test_accepted_values\": {\"unique_id\": \"macro.dbt.default__test_accepted_values\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/generic_test_sql/accepted_values.sql\", \"original_file_path\": \"macros/generic_test_sql/accepted_values.sql\", \"name\": \"default__test_accepted_values\", \"macro_sql\": \"{% macro default__test_accepted_values(model, column_name, values, quote=True) %}\\n\\nwith all_values as (\\n\\n    select\\n        {{ column_name }} as value_field,\\n        count(*) as n_records\\n\\n    from {{ model }}\\n    group by {{ column_name }}\\n\\n)\\n\\nselect *\\nfrom all_values\\nwhere value_field not in (\\n    {% for value in values -%}\\n        {% if quote -%}\\n        '{{ value }}'\\n        {%- else -%}\\n        {{ value }}\\n        {%- endif -%}\\n        {%- if not loop.last -%},{%- endif %}\\n    {%- endfor %}\\n)\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.969207, \"supported_languages\": null}, \"macro.dbt.statement\": {\"unique_id\": \"macro.dbt.statement\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/etc/statement.sql\", \"original_file_path\": \"macros/etc/statement.sql\", \"name\": \"statement\", \"macro_sql\": \"\\n{%- macro statement(name=None, fetch_result=False, auto_begin=True, language='sql') -%}\\n  {%- if execute: -%}\\n    {%- set compiled_code = caller() -%}\\n\\n    {%- if name == 'main' -%}\\n      {{ log('Writing runtime {} for node \\\"{}\\\"'.format(language, model['unique_id'])) }}\\n      {{ write(compiled_code) }}\\n    {%- endif -%}\\n    {%- if language == 'sql'-%}\\n      {%- set res, table = adapter.execute(compiled_code, auto_begin=auto_begin, fetch=fetch_result) -%}\\n    {%- elif language == 'python' -%}\\n      {%- set res = submit_python_job(model, compiled_code) -%}\\n      {#-- TODO: What should table be for python models? --#}\\n      {%- set table = None -%}\\n    {%- else -%}\\n      {% do exceptions.raise_compiler_error(\\\"statement macro didn't get supported language\\\") %}\\n    {%- endif -%}\\n\\n    {%- if name is not none -%}\\n      {{ store_result(name, response=res, agate_table=table) }}\\n    {%- endif -%}\\n\\n  {%- endif -%}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.973081, \"supported_languages\": null}, \"macro.dbt.noop_statement\": {\"unique_id\": \"macro.dbt.noop_statement\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/etc/statement.sql\", \"original_file_path\": \"macros/etc/statement.sql\", \"name\": \"noop_statement\", \"macro_sql\": \"{% macro noop_statement(name=None, message=None, code=None, rows_affected=None, res=None) -%}\\n  {%- set sql = caller() -%}\\n\\n  {%- if name == 'main' -%}\\n    {{ log('Writing runtime SQL for node \\\"{}\\\"'.format(model['unique_id'])) }}\\n    {{ write(sql) }}\\n  {%- endif -%}\\n\\n  {%- if name is not none -%}\\n    {{ store_raw_result(name, message=message, code=code, rows_affected=rows_affected, agate_table=res) }}\\n  {%- endif -%}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.974716, \"supported_languages\": null}, \"macro.dbt.run_query\": {\"unique_id\": \"macro.dbt.run_query\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/etc/statement.sql\", \"original_file_path\": \"macros/etc/statement.sql\", \"name\": \"run_query\", \"macro_sql\": \"{% macro run_query(sql) %}\\n  {% call statement(\\\"run_query_statement\\\", fetch_result=true, auto_begin=false) %}\\n    {{ sql }}\\n  {% endcall %}\\n\\n  {% do return(load_result(\\\"run_query_statement\\\").table) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.9754639, \"supported_languages\": null}, \"macro.dbt.convert_datetime\": {\"unique_id\": \"macro.dbt.convert_datetime\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"name\": \"convert_datetime\", \"macro_sql\": \"{% macro convert_datetime(date_str, date_fmt) %}\\n\\n  {% set error_msg -%}\\n      The provided partition date '{{ date_str }}' does not match the expected format '{{ date_fmt }}'\\n  {%- endset %}\\n\\n  {% set res = try_or_compiler_error(error_msg, modules.datetime.datetime.strptime, date_str.strip(), date_fmt) %}\\n  {{ return(res) }}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.979558, \"supported_languages\": null}, \"macro.dbt.dates_in_range\": {\"unique_id\": \"macro.dbt.dates_in_range\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"name\": \"dates_in_range\", \"macro_sql\": \"{% macro dates_in_range(start_date_str, end_date_str=none, in_fmt=\\\"%Y%m%d\\\", out_fmt=\\\"%Y%m%d\\\") %}\\n    {% set end_date_str = start_date_str if end_date_str is none else end_date_str %}\\n\\n    {% set start_date = convert_datetime(start_date_str, in_fmt) %}\\n    {% set end_date = convert_datetime(end_date_str, in_fmt) %}\\n\\n    {% set day_count = (end_date - start_date).days %}\\n    {% if day_count < 0 %}\\n        {% set msg -%}\\n            Partition start date is after the end date ({{ start_date }}, {{ end_date }})\\n        {%- endset %}\\n\\n        {{ exceptions.raise_compiler_error(msg, model) }}\\n    {% endif %}\\n\\n    {% set date_list = [] %}\\n    {% for i in range(0, day_count + 1) %}\\n        {% set the_date = (modules.datetime.timedelta(days=i) + start_date) %}\\n        {% if not out_fmt %}\\n            {% set _ = date_list.append(the_date) %}\\n        {% else %}\\n            {% set _ = date_list.append(the_date.strftime(out_fmt)) %}\\n        {% endif %}\\n    {% endfor %}\\n\\n    {{ return(date_list) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.convert_datetime\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.982544, \"supported_languages\": null}, \"macro.dbt.partition_range\": {\"unique_id\": \"macro.dbt.partition_range\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"name\": \"partition_range\", \"macro_sql\": \"{% macro partition_range(raw_partition_date, date_fmt='%Y%m%d') %}\\n    {% set partition_range = (raw_partition_date | string).split(\\\",\\\") %}\\n\\n    {% if (partition_range | length) == 1 %}\\n      {% set start_date = partition_range[0] %}\\n      {% set end_date = none %}\\n    {% elif (partition_range | length) == 2 %}\\n      {% set start_date = partition_range[0] %}\\n      {% set end_date = partition_range[1] %}\\n    {% else %}\\n      {{ exceptions.raise_compiler_error(\\\"Invalid partition time. Expected format: {Start Date}[,{End Date}]. Got: \\\" ~ raw_partition_date) }}\\n    {% endif %}\\n\\n    {{ return(dates_in_range(start_date, end_date, in_fmt=date_fmt)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.dates_in_range\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.984403, \"supported_languages\": null}, \"macro.dbt.py_current_timestring\": {\"unique_id\": \"macro.dbt.py_current_timestring\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"name\": \"py_current_timestring\", \"macro_sql\": \"{% macro py_current_timestring() %}\\n    {% set dt = modules.datetime.datetime.now() %}\\n    {% do return(dt.strftime(\\\"%Y%m%d%H%M%S%f\\\")) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.9849951, \"supported_languages\": null}, \"macro.dbt.except\": {\"unique_id\": \"macro.dbt.except\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/except.sql\", \"original_file_path\": \"macros/utils/except.sql\", \"name\": \"except\", \"macro_sql\": \"{% macro except() %}\\n  {{ return(adapter.dispatch('except', 'dbt')()) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__except\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.98597, \"supported_languages\": null}, \"macro.dbt.default__except\": {\"unique_id\": \"macro.dbt.default__except\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/except.sql\", \"original_file_path\": \"macros/utils/except.sql\", \"name\": \"default__except\", \"macro_sql\": \"{% macro default__except() %}\\n\\n    except\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.986175, \"supported_languages\": null}, \"macro.dbt.replace\": {\"unique_id\": \"macro.dbt.replace\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/replace.sql\", \"original_file_path\": \"macros/utils/replace.sql\", \"name\": \"replace\", \"macro_sql\": \"{% macro replace(field, old_chars, new_chars) -%}\\n    {{ return(adapter.dispatch('replace', 'dbt') (field, old_chars, new_chars)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__replace\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.9873059, \"supported_languages\": null}, \"macro.dbt.default__replace\": {\"unique_id\": \"macro.dbt.default__replace\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/replace.sql\", \"original_file_path\": \"macros/utils/replace.sql\", \"name\": \"default__replace\", \"macro_sql\": \"{% macro default__replace(field, old_chars, new_chars) %}\\n\\n    replace(\\n        {{ field }},\\n        {{ old_chars }},\\n        {{ new_chars }}\\n    )\\n\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.987733, \"supported_languages\": null}, \"macro.dbt.concat\": {\"unique_id\": \"macro.dbt.concat\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/concat.sql\", \"original_file_path\": \"macros/utils/concat.sql\", \"name\": \"concat\", \"macro_sql\": \"{% macro concat(fields) -%}\\n  {{ return(adapter.dispatch('concat', 'dbt')(fields)) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__concat\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.98864, \"supported_languages\": null}, \"macro.dbt.default__concat\": {\"unique_id\": \"macro.dbt.default__concat\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/concat.sql\", \"original_file_path\": \"macros/utils/concat.sql\", \"name\": \"default__concat\", \"macro_sql\": \"{% macro default__concat(fields) -%}\\n    {{ fields|join(' || ') }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.988965, \"supported_languages\": null}, \"macro.dbt.length\": {\"unique_id\": \"macro.dbt.length\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/length.sql\", \"original_file_path\": \"macros/utils/length.sql\", \"name\": \"length\", \"macro_sql\": \"{% macro length(expression) -%}\\n    {{ return(adapter.dispatch('length', 'dbt') (expression)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__length\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.990331, \"supported_languages\": null}, \"macro.dbt.default__length\": {\"unique_id\": \"macro.dbt.default__length\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/length.sql\", \"original_file_path\": \"macros/utils/length.sql\", \"name\": \"default__length\", \"macro_sql\": \"{% macro default__length(expression) %}\\n\\n    length(\\n        {{ expression }}\\n    )\\n\\n{%- endmacro -%}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.9906292, \"supported_languages\": null}, \"macro.dbt.dateadd\": {\"unique_id\": \"macro.dbt.dateadd\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/dateadd.sql\", \"original_file_path\": \"macros/utils/dateadd.sql\", \"name\": \"dateadd\", \"macro_sql\": \"{% macro dateadd(datepart, interval, from_date_or_timestamp) %}\\n  {{ return(adapter.dispatch('dateadd', 'dbt')(datepart, interval, from_date_or_timestamp)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__dateadd\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.991911, \"supported_languages\": null}, \"macro.dbt.default__dateadd\": {\"unique_id\": \"macro.dbt.default__dateadd\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/dateadd.sql\", \"original_file_path\": \"macros/utils/dateadd.sql\", \"name\": \"default__dateadd\", \"macro_sql\": \"{% macro default__dateadd(datepart, interval, from_date_or_timestamp) %}\\n\\n    dateadd(\\n        {{ datepart }},\\n        {{ interval }},\\n        {{ from_date_or_timestamp }}\\n        )\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.9923341, \"supported_languages\": null}, \"macro.dbt.intersect\": {\"unique_id\": \"macro.dbt.intersect\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/intersect.sql\", \"original_file_path\": \"macros/utils/intersect.sql\", \"name\": \"intersect\", \"macro_sql\": \"{% macro intersect() %}\\n  {{ return(adapter.dispatch('intersect', 'dbt')()) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__intersect\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.993244, \"supported_languages\": null}, \"macro.dbt.default__intersect\": {\"unique_id\": \"macro.dbt.default__intersect\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/intersect.sql\", \"original_file_path\": \"macros/utils/intersect.sql\", \"name\": \"default__intersect\", \"macro_sql\": \"{% macro default__intersect() %}\\n\\n    intersect\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.993451, \"supported_languages\": null}, \"macro.dbt.escape_single_quotes\": {\"unique_id\": \"macro.dbt.escape_single_quotes\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/escape_single_quotes.sql\", \"original_file_path\": \"macros/utils/escape_single_quotes.sql\", \"name\": \"escape_single_quotes\", \"macro_sql\": \"{% macro escape_single_quotes(expression) %}\\n      {{ return(adapter.dispatch('escape_single_quotes', 'dbt') (expression)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__escape_single_quotes\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.994604, \"supported_languages\": null}, \"macro.dbt.default__escape_single_quotes\": {\"unique_id\": \"macro.dbt.default__escape_single_quotes\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/escape_single_quotes.sql\", \"original_file_path\": \"macros/utils/escape_single_quotes.sql\", \"name\": \"default__escape_single_quotes\", \"macro_sql\": \"{% macro default__escape_single_quotes(expression) -%}\\n{{ expression | replace(\\\"'\\\",\\\"''\\\") }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.995014, \"supported_languages\": null}, \"macro.dbt.right\": {\"unique_id\": \"macro.dbt.right\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/right.sql\", \"original_file_path\": \"macros/utils/right.sql\", \"name\": \"right\", \"macro_sql\": \"{% macro right(string_text, length_expression) -%}\\n    {{ return(adapter.dispatch('right', 'dbt') (string_text, length_expression)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__right\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.9960818, \"supported_languages\": null}, \"macro.dbt.default__right\": {\"unique_id\": \"macro.dbt.default__right\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/right.sql\", \"original_file_path\": \"macros/utils/right.sql\", \"name\": \"default__right\", \"macro_sql\": \"{% macro default__right(string_text, length_expression) %}\\n\\n    right(\\n        {{ string_text }},\\n        {{ length_expression }}\\n    )\\n\\n{%- endmacro -%}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.9965801, \"supported_languages\": null}, \"macro.dbt.listagg\": {\"unique_id\": \"macro.dbt.listagg\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/listagg.sql\", \"original_file_path\": \"macros/utils/listagg.sql\", \"name\": \"listagg\", \"macro_sql\": \"{% macro listagg(measure, delimiter_text=\\\"','\\\", order_by_clause=none, limit_num=none) -%}\\n    {{ return(adapter.dispatch('listagg', 'dbt') (measure, delimiter_text, order_by_clause, limit_num)) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__listagg\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.9982479, \"supported_languages\": null}, \"macro.dbt.default__listagg\": {\"unique_id\": \"macro.dbt.default__listagg\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/listagg.sql\", \"original_file_path\": \"macros/utils/listagg.sql\", \"name\": \"default__listagg\", \"macro_sql\": \"{% macro default__listagg(measure, delimiter_text, order_by_clause, limit_num) -%}\\n\\n    {% if limit_num -%}\\n    array_to_string(\\n        array_slice(\\n            array_agg(\\n                {{ measure }}\\n            ){% if order_by_clause -%}\\n            within group ({{ order_by_clause }})\\n            {%- endif %}\\n            ,0\\n            ,{{ limit_num }}\\n        ),\\n        {{ delimiter_text }}\\n        )\\n    {%- else %}\\n    listagg(\\n        {{ measure }},\\n        {{ delimiter_text }}\\n        )\\n        {% if order_by_clause -%}\\n        within group ({{ order_by_clause }})\\n        {%- endif %}\\n    {%- endif %}\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324074.999271, \"supported_languages\": null}, \"macro.dbt.datediff\": {\"unique_id\": \"macro.dbt.datediff\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/datediff.sql\", \"original_file_path\": \"macros/utils/datediff.sql\", \"name\": \"datediff\", \"macro_sql\": \"{% macro datediff(first_date, second_date, datepart) %}\\n  {{ return(adapter.dispatch('datediff', 'dbt')(first_date, second_date, datepart)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__datediff\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.000368, \"supported_languages\": null}, \"macro.dbt.default__datediff\": {\"unique_id\": \"macro.dbt.default__datediff\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/datediff.sql\", \"original_file_path\": \"macros/utils/datediff.sql\", \"name\": \"default__datediff\", \"macro_sql\": \"{% macro default__datediff(first_date, second_date, datepart) -%}\\n\\n    datediff(\\n        {{ datepart }},\\n        {{ first_date }},\\n        {{ second_date }}\\n        )\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.0007942, \"supported_languages\": null}, \"macro.dbt.safe_cast\": {\"unique_id\": \"macro.dbt.safe_cast\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/safe_cast.sql\", \"original_file_path\": \"macros/utils/safe_cast.sql\", \"name\": \"safe_cast\", \"macro_sql\": \"{% macro safe_cast(field, type) %}\\n  {{ return(adapter.dispatch('safe_cast', 'dbt') (field, type)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__safe_cast\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.0018618, \"supported_languages\": null}, \"macro.dbt.default__safe_cast\": {\"unique_id\": \"macro.dbt.default__safe_cast\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/safe_cast.sql\", \"original_file_path\": \"macros/utils/safe_cast.sql\", \"name\": \"default__safe_cast\", \"macro_sql\": \"{% macro default__safe_cast(field, type) %}\\n    {# most databases don't support this function yet\\n    so we just need to use cast #}\\n    cast({{field}} as {{type}})\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.002232, \"supported_languages\": null}, \"macro.dbt.hash\": {\"unique_id\": \"macro.dbt.hash\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/hash.sql\", \"original_file_path\": \"macros/utils/hash.sql\", \"name\": \"hash\", \"macro_sql\": \"{% macro hash(field) -%}\\n  {{ return(adapter.dispatch('hash', 'dbt') (field)) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__hash\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.003175, \"supported_languages\": null}, \"macro.dbt.default__hash\": {\"unique_id\": \"macro.dbt.default__hash\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/hash.sql\", \"original_file_path\": \"macros/utils/hash.sql\", \"name\": \"default__hash\", \"macro_sql\": \"{% macro default__hash(field) -%}\\n    md5(cast({{ field }} as {{ api.Column.translate_type('string') }}))\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.0035892, \"supported_languages\": null}, \"macro.dbt.cast_bool_to_text\": {\"unique_id\": \"macro.dbt.cast_bool_to_text\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/cast_bool_to_text.sql\", \"original_file_path\": \"macros/utils/cast_bool_to_text.sql\", \"name\": \"cast_bool_to_text\", \"macro_sql\": \"{% macro cast_bool_to_text(field) %}\\n  {{ adapter.dispatch('cast_bool_to_text', 'dbt') (field) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__cast_bool_to_text\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.004607, \"supported_languages\": null}, \"macro.dbt.default__cast_bool_to_text\": {\"unique_id\": \"macro.dbt.default__cast_bool_to_text\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/cast_bool_to_text.sql\", \"original_file_path\": \"macros/utils/cast_bool_to_text.sql\", \"name\": \"default__cast_bool_to_text\", \"macro_sql\": \"{% macro default__cast_bool_to_text(field) %}\\n    cast({{ field }} as {{ api.Column.translate_type('string') }})\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.005036, \"supported_languages\": null}, \"macro.dbt.any_value\": {\"unique_id\": \"macro.dbt.any_value\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/any_value.sql\", \"original_file_path\": \"macros/utils/any_value.sql\", \"name\": \"any_value\", \"macro_sql\": \"{% macro any_value(expression) -%}\\n    {{ return(adapter.dispatch('any_value', 'dbt') (expression)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__any_value\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.00601, \"supported_languages\": null}, \"macro.dbt.default__any_value\": {\"unique_id\": \"macro.dbt.default__any_value\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/any_value.sql\", \"original_file_path\": \"macros/utils/any_value.sql\", \"name\": \"default__any_value\", \"macro_sql\": \"{% macro default__any_value(expression) -%}\\n\\n    any_value({{ expression }})\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.0063071, \"supported_languages\": null}, \"macro.dbt.position\": {\"unique_id\": \"macro.dbt.position\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/position.sql\", \"original_file_path\": \"macros/utils/position.sql\", \"name\": \"position\", \"macro_sql\": \"{% macro position(substring_text, string_text) -%}\\n    {{ return(adapter.dispatch('position', 'dbt') (substring_text, string_text)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__position\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.007398, \"supported_languages\": null}, \"macro.dbt.default__position\": {\"unique_id\": \"macro.dbt.default__position\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/position.sql\", \"original_file_path\": \"macros/utils/position.sql\", \"name\": \"default__position\", \"macro_sql\": \"{% macro default__position(substring_text, string_text) %}\\n\\n    position(\\n        {{ substring_text }} in {{ string_text }}\\n    )\\n\\n{%- endmacro -%}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.007754, \"supported_languages\": null}, \"macro.dbt.string_literal\": {\"unique_id\": \"macro.dbt.string_literal\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/literal.sql\", \"original_file_path\": \"macros/utils/literal.sql\", \"name\": \"string_literal\", \"macro_sql\": \"{%- macro string_literal(value) -%}\\n  {{ return(adapter.dispatch('string_literal', 'dbt') (value)) }}\\n{%- endmacro -%}\\n\\n\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__string_literal\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.008699, \"supported_languages\": null}, \"macro.dbt.default__string_literal\": {\"unique_id\": \"macro.dbt.default__string_literal\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/literal.sql\", \"original_file_path\": \"macros/utils/literal.sql\", \"name\": \"default__string_literal\", \"macro_sql\": \"{% macro default__string_literal(value) -%}\\n    '{{ value }}'\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.008971, \"supported_languages\": null}, \"macro.dbt.type_string\": {\"unique_id\": \"macro.dbt.type_string\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"name\": \"type_string\", \"macro_sql\": \"\\n\\n{%- macro type_string() -%}\\n  {{ return(adapter.dispatch('type_string', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__type_string\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.011225, \"supported_languages\": null}, \"macro.dbt.default__type_string\": {\"unique_id\": \"macro.dbt.default__type_string\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"name\": \"default__type_string\", \"macro_sql\": \"{% macro default__type_string() %}\\n    {{ return(api.Column.translate_type(\\\"string\\\")) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.011629, \"supported_languages\": null}, \"macro.dbt.type_timestamp\": {\"unique_id\": \"macro.dbt.type_timestamp\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"name\": \"type_timestamp\", \"macro_sql\": \"\\n\\n{%- macro type_timestamp() -%}\\n  {{ return(adapter.dispatch('type_timestamp', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__type_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.012175, \"supported_languages\": null}, \"macro.dbt.default__type_timestamp\": {\"unique_id\": \"macro.dbt.default__type_timestamp\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"name\": \"default__type_timestamp\", \"macro_sql\": \"{% macro default__type_timestamp() %}\\n    {{ return(api.Column.translate_type(\\\"timestamp\\\")) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.0125592, \"supported_languages\": null}, \"macro.dbt.type_float\": {\"unique_id\": \"macro.dbt.type_float\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"name\": \"type_float\", \"macro_sql\": \"\\n\\n{%- macro type_float() -%}\\n  {{ return(adapter.dispatch('type_float', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__type_float\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.012963, \"supported_languages\": null}, \"macro.dbt.default__type_float\": {\"unique_id\": \"macro.dbt.default__type_float\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"name\": \"default__type_float\", \"macro_sql\": \"{% macro default__type_float() %}\\n    {{ return(api.Column.translate_type(\\\"float\\\")) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.013345, \"supported_languages\": null}, \"macro.dbt.type_numeric\": {\"unique_id\": \"macro.dbt.type_numeric\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"name\": \"type_numeric\", \"macro_sql\": \"\\n\\n{%- macro type_numeric() -%}\\n  {{ return(adapter.dispatch('type_numeric', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__type_numeric\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.013751, \"supported_languages\": null}, \"macro.dbt.default__type_numeric\": {\"unique_id\": \"macro.dbt.default__type_numeric\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"name\": \"default__type_numeric\", \"macro_sql\": \"{% macro default__type_numeric() %}\\n    {{ return(api.Column.numeric_type(\\\"numeric\\\", 28, 6)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.0141928, \"supported_languages\": null}, \"macro.dbt.type_bigint\": {\"unique_id\": \"macro.dbt.type_bigint\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"name\": \"type_bigint\", \"macro_sql\": \"\\n\\n{%- macro type_bigint() -%}\\n  {{ return(adapter.dispatch('type_bigint', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__type_bigint\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.014601, \"supported_languages\": null}, \"macro.dbt.default__type_bigint\": {\"unique_id\": \"macro.dbt.default__type_bigint\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"name\": \"default__type_bigint\", \"macro_sql\": \"{% macro default__type_bigint() %}\\n    {{ return(api.Column.translate_type(\\\"bigint\\\")) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.014984, \"supported_languages\": null}, \"macro.dbt.type_int\": {\"unique_id\": \"macro.dbt.type_int\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"name\": \"type_int\", \"macro_sql\": \"\\n\\n{%- macro type_int() -%}\\n  {{ return(adapter.dispatch('type_int', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__type_int\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.015394, \"supported_languages\": null}, \"macro.dbt.default__type_int\": {\"unique_id\": \"macro.dbt.default__type_int\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"name\": \"default__type_int\", \"macro_sql\": \"{%- macro default__type_int() -%}\\n  {{ return(api.Column.translate_type(\\\"integer\\\")) }}\\n{%- endmacro -%}\\n\\n\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.015761, \"supported_languages\": null}, \"macro.dbt.type_boolean\": {\"unique_id\": \"macro.dbt.type_boolean\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"name\": \"type_boolean\", \"macro_sql\": \"\\n\\n{%- macro type_boolean() -%}\\n  {{ return(adapter.dispatch('type_boolean', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__type_boolean\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.016257, \"supported_languages\": null}, \"macro.dbt.default__type_boolean\": {\"unique_id\": \"macro.dbt.default__type_boolean\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"name\": \"default__type_boolean\", \"macro_sql\": \"{%- macro default__type_boolean() -%}\\n  {{ return(api.Column.translate_type(\\\"boolean\\\")) }}\\n{%- endmacro -%}\\n\\n\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.01665, \"supported_languages\": null}, \"macro.dbt.array_concat\": {\"unique_id\": \"macro.dbt.array_concat\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/array_concat.sql\", \"original_file_path\": \"macros/utils/array_concat.sql\", \"name\": \"array_concat\", \"macro_sql\": \"{% macro array_concat(array_1, array_2) -%}\\n  {{ return(adapter.dispatch('array_concat', 'dbt')(array_1, array_2)) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__array_concat\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.017704, \"supported_languages\": null}, \"macro.dbt.default__array_concat\": {\"unique_id\": \"macro.dbt.default__array_concat\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/array_concat.sql\", \"original_file_path\": \"macros/utils/array_concat.sql\", \"name\": \"default__array_concat\", \"macro_sql\": \"{% macro default__array_concat(array_1, array_2) -%}\\n    array_cat({{ array_1 }}, {{ array_2 }})\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.0180538, \"supported_languages\": null}, \"macro.dbt.bool_or\": {\"unique_id\": \"macro.dbt.bool_or\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/bool_or.sql\", \"original_file_path\": \"macros/utils/bool_or.sql\", \"name\": \"bool_or\", \"macro_sql\": \"{% macro bool_or(expression) -%}\\n    {{ return(adapter.dispatch('bool_or', 'dbt') (expression)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__bool_or\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.01898, \"supported_languages\": null}, \"macro.dbt.default__bool_or\": {\"unique_id\": \"macro.dbt.default__bool_or\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/bool_or.sql\", \"original_file_path\": \"macros/utils/bool_or.sql\", \"name\": \"default__bool_or\", \"macro_sql\": \"{% macro default__bool_or(expression) -%}\\n\\n    bool_or({{ expression }})\\n\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.019255, \"supported_languages\": null}, \"macro.dbt.last_day\": {\"unique_id\": \"macro.dbt.last_day\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/last_day.sql\", \"original_file_path\": \"macros/utils/last_day.sql\", \"name\": \"last_day\", \"macro_sql\": \"{% macro last_day(date, datepart) %}\\n  {{ return(adapter.dispatch('last_day', 'dbt') (date, datepart)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__last_day\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.020355, \"supported_languages\": null}, \"macro.dbt.default_last_day\": {\"unique_id\": \"macro.dbt.default_last_day\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/last_day.sql\", \"original_file_path\": \"macros/utils/last_day.sql\", \"name\": \"default_last_day\", \"macro_sql\": \"\\n\\n{%- macro default_last_day(date, datepart) -%}\\n    cast(\\n        {{dbt.dateadd('day', '-1',\\n        dbt.dateadd(datepart, '1', dbt.date_trunc(datepart, date))\\n        )}}\\n        as date)\\n{%- endmacro -%}\\n\\n\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.dateadd\", \"macro.dbt.date_trunc\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.0210161, \"supported_languages\": null}, \"macro.dbt.default__last_day\": {\"unique_id\": \"macro.dbt.default__last_day\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/last_day.sql\", \"original_file_path\": \"macros/utils/last_day.sql\", \"name\": \"default__last_day\", \"macro_sql\": \"{% macro default__last_day(date, datepart) -%}\\n    {{dbt.default_last_day(date, datepart)}}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default_last_day\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.021465, \"supported_languages\": null}, \"macro.dbt.split_part\": {\"unique_id\": \"macro.dbt.split_part\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/split_part.sql\", \"original_file_path\": \"macros/utils/split_part.sql\", \"name\": \"split_part\", \"macro_sql\": \"{% macro split_part(string_text, delimiter_text, part_number) %}\\n  {{ return(adapter.dispatch('split_part', 'dbt') (string_text, delimiter_text, part_number)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__split_part\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.023027, \"supported_languages\": null}, \"macro.dbt.default__split_part\": {\"unique_id\": \"macro.dbt.default__split_part\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/split_part.sql\", \"original_file_path\": \"macros/utils/split_part.sql\", \"name\": \"default__split_part\", \"macro_sql\": \"{% macro default__split_part(string_text, delimiter_text, part_number) %}\\n\\n    split_part(\\n        {{ string_text }},\\n        {{ delimiter_text }},\\n        {{ part_number }}\\n        )\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.023608, \"supported_languages\": null}, \"macro.dbt._split_part_negative\": {\"unique_id\": \"macro.dbt._split_part_negative\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/split_part.sql\", \"original_file_path\": \"macros/utils/split_part.sql\", \"name\": \"_split_part_negative\", \"macro_sql\": \"{% macro _split_part_negative(string_text, delimiter_text, part_number) %}\\n\\n    split_part(\\n        {{ string_text }},\\n        {{ delimiter_text }},\\n          length({{ string_text }})\\n          - length(\\n              replace({{ string_text }},  {{ delimiter_text }}, '')\\n          ) + 2 {{ part_number }}\\n        )\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.024339, \"supported_languages\": null}, \"macro.dbt.date_trunc\": {\"unique_id\": \"macro.dbt.date_trunc\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/date_trunc.sql\", \"original_file_path\": \"macros/utils/date_trunc.sql\", \"name\": \"date_trunc\", \"macro_sql\": \"{% macro date_trunc(datepart, date) -%}\\n  {{ return(adapter.dispatch('date_trunc', 'dbt') (datepart, date)) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__date_trunc\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.02547, \"supported_languages\": null}, \"macro.dbt.default__date_trunc\": {\"unique_id\": \"macro.dbt.default__date_trunc\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/date_trunc.sql\", \"original_file_path\": \"macros/utils/date_trunc.sql\", \"name\": \"default__date_trunc\", \"macro_sql\": \"{% macro default__date_trunc(datepart, date) -%}\\n    date_trunc('{{datepart}}', {{date}})\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.0258088, \"supported_languages\": null}, \"macro.dbt.array_construct\": {\"unique_id\": \"macro.dbt.array_construct\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/array_construct.sql\", \"original_file_path\": \"macros/utils/array_construct.sql\", \"name\": \"array_construct\", \"macro_sql\": \"{% macro array_construct(inputs=[], data_type=api.Column.translate_type('integer')) -%}\\n  {{ return(adapter.dispatch('array_construct', 'dbt')(inputs, data_type)) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__array_construct\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.0271108, \"supported_languages\": null}, \"macro.dbt.default__array_construct\": {\"unique_id\": \"macro.dbt.default__array_construct\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/array_construct.sql\", \"original_file_path\": \"macros/utils/array_construct.sql\", \"name\": \"default__array_construct\", \"macro_sql\": \"{% macro default__array_construct(inputs, data_type) -%}\\n    {% if inputs|length > 0 %}\\n    array[ {{ inputs|join(' , ') }} ]\\n    {% else %}\\n    array[]::{{data_type}}[]\\n    {% endif %}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.027744, \"supported_languages\": null}, \"macro.dbt.array_append\": {\"unique_id\": \"macro.dbt.array_append\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/array_append.sql\", \"original_file_path\": \"macros/utils/array_append.sql\", \"name\": \"array_append\", \"macro_sql\": \"{% macro array_append(array, new_element) -%}\\n  {{ return(adapter.dispatch('array_append', 'dbt')(array, new_element)) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__array_append\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.028975, \"supported_languages\": null}, \"macro.dbt.default__array_append\": {\"unique_id\": \"macro.dbt.default__array_append\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/utils/array_append.sql\", \"original_file_path\": \"macros/utils/array_append.sql\", \"name\": \"default__array_append\", \"macro_sql\": \"{% macro default__array_append(array, new_element) -%}\\n    array_append({{ array }}, {{ new_element }})\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.0293288, \"supported_languages\": null}, \"macro.dbt.create_schema\": {\"unique_id\": \"macro.dbt.create_schema\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/schema.sql\", \"original_file_path\": \"macros/adapters/schema.sql\", \"name\": \"create_schema\", \"macro_sql\": \"{% macro create_schema(relation) -%}\\n  {{ adapter.dispatch('create_schema', 'dbt')(relation) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__create_schema\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.030483, \"supported_languages\": null}, \"macro.dbt.default__create_schema\": {\"unique_id\": \"macro.dbt.default__create_schema\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/schema.sql\", \"original_file_path\": \"macros/adapters/schema.sql\", \"name\": \"default__create_schema\", \"macro_sql\": \"{% macro default__create_schema(relation) -%}\\n  {%- call statement('create_schema') -%}\\n    create schema if not exists {{ relation.without_identifier() }}\\n  {% endcall %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.0309591, \"supported_languages\": null}, \"macro.dbt.drop_schema\": {\"unique_id\": \"macro.dbt.drop_schema\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/schema.sql\", \"original_file_path\": \"macros/adapters/schema.sql\", \"name\": \"drop_schema\", \"macro_sql\": \"{% macro drop_schema(relation) -%}\\n  {{ adapter.dispatch('drop_schema', 'dbt')(relation) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__drop_schema\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.031368, \"supported_languages\": null}, \"macro.dbt.default__drop_schema\": {\"unique_id\": \"macro.dbt.default__drop_schema\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/schema.sql\", \"original_file_path\": \"macros/adapters/schema.sql\", \"name\": \"default__drop_schema\", \"macro_sql\": \"{% macro default__drop_schema(relation) -%}\\n  {%- call statement('drop_schema') -%}\\n    drop schema if exists {{ relation.without_identifier() }} cascade\\n  {% endcall %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.0318341, \"supported_languages\": null}, \"macro.dbt.current_timestamp\": {\"unique_id\": \"macro.dbt.current_timestamp\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"name\": \"current_timestamp\", \"macro_sql\": \"{%- macro current_timestamp() -%}\\n    {{ adapter.dispatch('current_timestamp', 'dbt')() }}\\n{%- endmacro -%}\\n\\n\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.033173, \"supported_languages\": null}, \"macro.dbt.default__current_timestamp\": {\"unique_id\": \"macro.dbt.default__current_timestamp\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"name\": \"default__current_timestamp\", \"macro_sql\": \"{% macro default__current_timestamp() -%}\\n  {{ exceptions.raise_not_implemented(\\n    'current_timestamp macro not implemented for adapter ' + adapter.type()) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.033555, \"supported_languages\": null}, \"macro.dbt.snapshot_get_time\": {\"unique_id\": \"macro.dbt.snapshot_get_time\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"name\": \"snapshot_get_time\", \"macro_sql\": \"\\n\\n{%- macro snapshot_get_time() -%}\\n    {{ adapter.dispatch('snapshot_get_time', 'dbt')() }}\\n{%- endmacro -%}\\n\\n\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__snapshot_get_time\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.0339258, \"supported_languages\": null}, \"macro.dbt.default__snapshot_get_time\": {\"unique_id\": \"macro.dbt.default__snapshot_get_time\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"name\": \"default__snapshot_get_time\", \"macro_sql\": \"{% macro default__snapshot_get_time() %}\\n    {{ current_timestamp() }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.034244, \"supported_languages\": null}, \"macro.dbt.current_timestamp_backcompat\": {\"unique_id\": \"macro.dbt.current_timestamp_backcompat\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"name\": \"current_timestamp_backcompat\", \"macro_sql\": \"{% macro current_timestamp_backcompat() %}\\n    {{ return(adapter.dispatch('current_timestamp_backcompat', 'dbt')()) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__current_timestamp_backcompat\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.034715, \"supported_languages\": null}, \"macro.dbt.default__current_timestamp_backcompat\": {\"unique_id\": \"macro.dbt.default__current_timestamp_backcompat\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"name\": \"default__current_timestamp_backcompat\", \"macro_sql\": \"{% macro default__current_timestamp_backcompat() %}\\n    current_timestamp::timestamp\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.0349262, \"supported_languages\": null}, \"macro.dbt.current_timestamp_in_utc_backcompat\": {\"unique_id\": \"macro.dbt.current_timestamp_in_utc_backcompat\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"name\": \"current_timestamp_in_utc_backcompat\", \"macro_sql\": \"{% macro current_timestamp_in_utc_backcompat() %}\\n    {{ return(adapter.dispatch('current_timestamp_in_utc_backcompat', 'dbt')()) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__current_timestamp_in_utc_backcompat\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.035347, \"supported_languages\": null}, \"macro.dbt.default__current_timestamp_in_utc_backcompat\": {\"unique_id\": \"macro.dbt.default__current_timestamp_in_utc_backcompat\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"name\": \"default__current_timestamp_in_utc_backcompat\", \"macro_sql\": \"{% macro default__current_timestamp_in_utc_backcompat() %}\\n    {{ return(adapter.dispatch('current_timestamp_backcompat', 'dbt')()) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.current_timestamp_backcompat\", \"macro.dbt_postgres.postgres__current_timestamp_backcompat\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.035771, \"supported_languages\": null}, \"macro.dbt.get_create_index_sql\": {\"unique_id\": \"macro.dbt.get_create_index_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"name\": \"get_create_index_sql\", \"macro_sql\": \"{% macro get_create_index_sql(relation, index_dict) -%}\\n  {{ return(adapter.dispatch('get_create_index_sql', 'dbt')(relation, index_dict)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_create_index_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.0371048, \"supported_languages\": null}, \"macro.dbt.default__get_create_index_sql\": {\"unique_id\": \"macro.dbt.default__get_create_index_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"name\": \"default__get_create_index_sql\", \"macro_sql\": \"{% macro default__get_create_index_sql(relation, index_dict) -%}\\n  {% do return(None) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.037695, \"supported_languages\": null}, \"macro.dbt.create_indexes\": {\"unique_id\": \"macro.dbt.create_indexes\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"name\": \"create_indexes\", \"macro_sql\": \"{% macro create_indexes(relation) -%}\\n  {{ adapter.dispatch('create_indexes', 'dbt')(relation) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__create_indexes\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.038136, \"supported_languages\": null}, \"macro.dbt.default__create_indexes\": {\"unique_id\": \"macro.dbt.default__create_indexes\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"name\": \"default__create_indexes\", \"macro_sql\": \"{% macro default__create_indexes(relation) -%}\\n  {%- set _indexes = config.get('indexes', default=[]) -%}\\n\\n  {% for _index_dict in _indexes %}\\n    {% set create_index_sql = get_create_index_sql(relation, _index_dict) %}\\n    {% if create_index_sql %}\\n      {% do run_query(create_index_sql) %}\\n    {% endif %}\\n  {% endfor %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.get_create_index_sql\", \"macro.dbt.run_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.039148, \"supported_languages\": null}, \"macro.dbt.make_intermediate_relation\": {\"unique_id\": \"macro.dbt.make_intermediate_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"make_intermediate_relation\", \"macro_sql\": \"{% macro make_intermediate_relation(base_relation, suffix='__dbt_tmp') %}\\n  {{ return(adapter.dispatch('make_intermediate_relation', 'dbt')(base_relation, suffix)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_intermediate_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.0456681, \"supported_languages\": null}, \"macro.dbt.default__make_intermediate_relation\": {\"unique_id\": \"macro.dbt.default__make_intermediate_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"default__make_intermediate_relation\", \"macro_sql\": \"{% macro default__make_intermediate_relation(base_relation, suffix) %}\\n    {{ return(default__make_temp_relation(base_relation, suffix)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__make_temp_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.046104, \"supported_languages\": null}, \"macro.dbt.make_temp_relation\": {\"unique_id\": \"macro.dbt.make_temp_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"make_temp_relation\", \"macro_sql\": \"{% macro make_temp_relation(base_relation, suffix='__dbt_tmp') %}\\n  {{ return(adapter.dispatch('make_temp_relation', 'dbt')(base_relation, suffix)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_temp_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.0466611, \"supported_languages\": null}, \"macro.dbt.default__make_temp_relation\": {\"unique_id\": \"macro.dbt.default__make_temp_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"default__make_temp_relation\", \"macro_sql\": \"{% macro default__make_temp_relation(base_relation, suffix) %}\\n    {%- set temp_identifier = base_relation.identifier ~ suffix -%}\\n    {%- set temp_relation = base_relation.incorporate(\\n                                path={\\\"identifier\\\": temp_identifier}) -%}\\n\\n    {{ return(temp_relation) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.047403, \"supported_languages\": null}, \"macro.dbt.make_backup_relation\": {\"unique_id\": \"macro.dbt.make_backup_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"make_backup_relation\", \"macro_sql\": \"{% macro make_backup_relation(base_relation, backup_relation_type, suffix='__dbt_backup') %}\\n    {{ return(adapter.dispatch('make_backup_relation', 'dbt')(base_relation, backup_relation_type, suffix)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_backup_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.0480168, \"supported_languages\": null}, \"macro.dbt.default__make_backup_relation\": {\"unique_id\": \"macro.dbt.default__make_backup_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"default__make_backup_relation\", \"macro_sql\": \"{% macro default__make_backup_relation(base_relation, backup_relation_type, suffix) %}\\n    {%- set backup_identifier = base_relation.identifier ~ suffix -%}\\n    {%- set backup_relation = base_relation.incorporate(\\n                                  path={\\\"identifier\\\": backup_identifier},\\n                                  type=backup_relation_type\\n    ) -%}\\n    {{ return(backup_relation) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.048809, \"supported_languages\": null}, \"macro.dbt.drop_relation\": {\"unique_id\": \"macro.dbt.drop_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"drop_relation\", \"macro_sql\": \"{% macro drop_relation(relation) -%}\\n  {{ return(adapter.dispatch('drop_relation', 'dbt')(relation)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__drop_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.049268, \"supported_languages\": null}, \"macro.dbt.default__drop_relation\": {\"unique_id\": \"macro.dbt.default__drop_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"default__drop_relation\", \"macro_sql\": \"{% macro default__drop_relation(relation) -%}\\n  {% call statement('drop_relation', auto_begin=False) -%}\\n    drop {{ relation.type }} if exists {{ relation }} cascade\\n  {%- endcall %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.049806, \"supported_languages\": null}, \"macro.dbt.truncate_relation\": {\"unique_id\": \"macro.dbt.truncate_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"truncate_relation\", \"macro_sql\": \"{% macro truncate_relation(relation) -%}\\n  {{ return(adapter.dispatch('truncate_relation', 'dbt')(relation)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__truncate_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.050257, \"supported_languages\": null}, \"macro.dbt.default__truncate_relation\": {\"unique_id\": \"macro.dbt.default__truncate_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"default__truncate_relation\", \"macro_sql\": \"{% macro default__truncate_relation(relation) -%}\\n  {% call statement('truncate_relation') -%}\\n    truncate table {{ relation }}\\n  {%- endcall %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.050667, \"supported_languages\": null}, \"macro.dbt.rename_relation\": {\"unique_id\": \"macro.dbt.rename_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"rename_relation\", \"macro_sql\": \"{% macro rename_relation(from_relation, to_relation) -%}\\n  {{ return(adapter.dispatch('rename_relation', 'dbt')(from_relation, to_relation)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__rename_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.051177, \"supported_languages\": null}, \"macro.dbt.default__rename_relation\": {\"unique_id\": \"macro.dbt.default__rename_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"default__rename_relation\", \"macro_sql\": \"{% macro default__rename_relation(from_relation, to_relation) -%}\\n  {% set target_name = adapter.quote_as_configured(to_relation.identifier, 'identifier') %}\\n  {% call statement('rename_relation') -%}\\n    alter table {{ from_relation }} rename to {{ target_name }}\\n  {%- endcall %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.051893, \"supported_languages\": null}, \"macro.dbt.get_or_create_relation\": {\"unique_id\": \"macro.dbt.get_or_create_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"get_or_create_relation\", \"macro_sql\": \"{% macro get_or_create_relation(database, schema, identifier, type) -%}\\n  {{ return(adapter.dispatch('get_or_create_relation', 'dbt')(database, schema, identifier, type)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_or_create_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.052501, \"supported_languages\": null}, \"macro.dbt.default__get_or_create_relation\": {\"unique_id\": \"macro.dbt.default__get_or_create_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"default__get_or_create_relation\", \"macro_sql\": \"{% macro default__get_or_create_relation(database, schema, identifier, type) %}\\n  {%- set target_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) %}\\n\\n  {% if target_relation %}\\n    {% do return([true, target_relation]) %}\\n  {% endif %}\\n\\n  {%- set new_relation = api.Relation.create(\\n      database=database,\\n      schema=schema,\\n      identifier=identifier,\\n      type=type\\n  ) -%}\\n  {% do return([false, new_relation]) %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.053866, \"supported_languages\": null}, \"macro.dbt.load_cached_relation\": {\"unique_id\": \"macro.dbt.load_cached_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"load_cached_relation\", \"macro_sql\": \"{% macro load_cached_relation(relation) %}\\n  {% do return(adapter.get_relation(\\n    database=relation.database,\\n    schema=relation.schema,\\n    identifier=relation.identifier\\n  )) -%}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.054573, \"supported_languages\": null}, \"macro.dbt.load_relation\": {\"unique_id\": \"macro.dbt.load_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"load_relation\", \"macro_sql\": \"{% macro load_relation(relation) %}\\n    {{ return(load_cached_relation(relation)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.load_cached_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.0549362, \"supported_languages\": null}, \"macro.dbt.drop_relation_if_exists\": {\"unique_id\": \"macro.dbt.drop_relation_if_exists\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"name\": \"drop_relation_if_exists\", \"macro_sql\": \"{% macro drop_relation_if_exists(relation) %}\\n  {% if relation is not none %}\\n    {{ adapter.drop_relation(relation) }}\\n  {% endif %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.055425, \"supported_languages\": null}, \"macro.dbt.collect_freshness\": {\"unique_id\": \"macro.dbt.collect_freshness\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/freshness.sql\", \"original_file_path\": \"macros/adapters/freshness.sql\", \"name\": \"collect_freshness\", \"macro_sql\": \"{% macro collect_freshness(source, loaded_at_field, filter) %}\\n  {{ return(adapter.dispatch('collect_freshness', 'dbt')(source, loaded_at_field, filter))}}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__collect_freshness\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.0570502, \"supported_languages\": null}, \"macro.dbt.default__collect_freshness\": {\"unique_id\": \"macro.dbt.default__collect_freshness\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/freshness.sql\", \"original_file_path\": \"macros/adapters/freshness.sql\", \"name\": \"default__collect_freshness\", \"macro_sql\": \"{% macro default__collect_freshness(source, loaded_at_field, filter) %}\\n  {% call statement('collect_freshness', fetch_result=True, auto_begin=False) -%}\\n    select\\n      max({{ loaded_at_field }}) as max_loaded_at,\\n      {{ current_timestamp() }} as snapshotted_at\\n    from {{ source }}\\n    {% if filter %}\\n    where {{ filter }}\\n    {% endif %}\\n  {% endcall %}\\n  {{ return(load_result('collect_freshness').table) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\", \"macro.dbt.current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.0581172, \"supported_languages\": null}, \"macro.dbt.copy_grants\": {\"unique_id\": \"macro.dbt.copy_grants\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"name\": \"copy_grants\", \"macro_sql\": \"{% macro copy_grants() %}\\n    {{ return(adapter.dispatch('copy_grants', 'dbt')()) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__copy_grants\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.06205, \"supported_languages\": null}, \"macro.dbt.default__copy_grants\": {\"unique_id\": \"macro.dbt.default__copy_grants\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"name\": \"default__copy_grants\", \"macro_sql\": \"{% macro default__copy_grants() %}\\n    {{ return(True) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.062446, \"supported_languages\": null}, \"macro.dbt.support_multiple_grantees_per_dcl_statement\": {\"unique_id\": \"macro.dbt.support_multiple_grantees_per_dcl_statement\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"name\": \"support_multiple_grantees_per_dcl_statement\", \"macro_sql\": \"{% macro support_multiple_grantees_per_dcl_statement() %}\\n    {{ return(adapter.dispatch('support_multiple_grantees_per_dcl_statement', 'dbt')()) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__support_multiple_grantees_per_dcl_statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.062894, \"supported_languages\": null}, \"macro.dbt.default__support_multiple_grantees_per_dcl_statement\": {\"unique_id\": \"macro.dbt.default__support_multiple_grantees_per_dcl_statement\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"name\": \"default__support_multiple_grantees_per_dcl_statement\", \"macro_sql\": \"\\n\\n{%- macro default__support_multiple_grantees_per_dcl_statement() -%}\\n    {{ return(True) }}\\n{%- endmacro -%}\\n\\n\\n\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.063191, \"supported_languages\": null}, \"macro.dbt.should_revoke\": {\"unique_id\": \"macro.dbt.should_revoke\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"name\": \"should_revoke\", \"macro_sql\": \"{% macro should_revoke(existing_relation, full_refresh_mode=True) %}\\n\\n    {% if not existing_relation %}\\n        {#-- The table doesn't already exist, so no grants to copy over --#}\\n        {{ return(False) }}\\n    {% elif full_refresh_mode %}\\n        {#-- The object is being REPLACED -- whether grants are copied over depends on the value of user config --#}\\n        {{ return(copy_grants()) }}\\n    {% else %}\\n        {#-- The table is being merged/upserted/inserted -- grants will be carried over --#}\\n        {{ return(True) }}\\n    {% endif %}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.copy_grants\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.064117, \"supported_languages\": null}, \"macro.dbt.get_show_grant_sql\": {\"unique_id\": \"macro.dbt.get_show_grant_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"name\": \"get_show_grant_sql\", \"macro_sql\": \"{% macro get_show_grant_sql(relation) %}\\n    {{ return(adapter.dispatch(\\\"get_show_grant_sql\\\", \\\"dbt\\\")(relation)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_show_grant_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.0646179, \"supported_languages\": null}, \"macro.dbt.default__get_show_grant_sql\": {\"unique_id\": \"macro.dbt.default__get_show_grant_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"name\": \"default__get_show_grant_sql\", \"macro_sql\": \"{% macro default__get_show_grant_sql(relation) %}\\n    show grants on {{ relation }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.0649018, \"supported_languages\": null}, \"macro.dbt.get_grant_sql\": {\"unique_id\": \"macro.dbt.get_grant_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"name\": \"get_grant_sql\", \"macro_sql\": \"{% macro get_grant_sql(relation, privilege, grantees) %}\\n    {{ return(adapter.dispatch('get_grant_sql', 'dbt')(relation, privilege, grantees)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_grant_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.065465, \"supported_languages\": null}, \"macro.dbt.default__get_grant_sql\": {\"unique_id\": \"macro.dbt.default__get_grant_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"name\": \"default__get_grant_sql\", \"macro_sql\": \"\\n\\n{%- macro default__get_grant_sql(relation, privilege, grantees) -%}\\n    grant {{ privilege }} on {{ relation }} to {{ grantees | join(', ') }}\\n{%- endmacro -%}\\n\\n\\n\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.0659552, \"supported_languages\": null}, \"macro.dbt.get_revoke_sql\": {\"unique_id\": \"macro.dbt.get_revoke_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"name\": \"get_revoke_sql\", \"macro_sql\": \"{% macro get_revoke_sql(relation, privilege, grantees) %}\\n    {{ return(adapter.dispatch('get_revoke_sql', 'dbt')(relation, privilege, grantees)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_revoke_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.066529, \"supported_languages\": null}, \"macro.dbt.default__get_revoke_sql\": {\"unique_id\": \"macro.dbt.default__get_revoke_sql\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"name\": \"default__get_revoke_sql\", \"macro_sql\": \"\\n\\n{%- macro default__get_revoke_sql(relation, privilege, grantees) -%}\\n    revoke {{ privilege }} on {{ relation }} from {{ grantees | join(', ') }}\\n{%- endmacro -%}\\n\\n\\n\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.0670002, \"supported_languages\": null}, \"macro.dbt.get_dcl_statement_list\": {\"unique_id\": \"macro.dbt.get_dcl_statement_list\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"name\": \"get_dcl_statement_list\", \"macro_sql\": \"{% macro get_dcl_statement_list(relation, grant_config, get_dcl_macro) %}\\n    {{ return(adapter.dispatch('get_dcl_statement_list', 'dbt')(relation, grant_config, get_dcl_macro)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_dcl_statement_list\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.0675662, \"supported_languages\": null}, \"macro.dbt.default__get_dcl_statement_list\": {\"unique_id\": \"macro.dbt.default__get_dcl_statement_list\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"name\": \"default__get_dcl_statement_list\", \"macro_sql\": \"\\n\\n{%- macro default__get_dcl_statement_list(relation, grant_config, get_dcl_macro) -%}\\n    {#\\n      -- Unpack grant_config into specific privileges and the set of users who need them granted/revoked.\\n      -- Depending on whether this database supports multiple grantees per statement, pass in the list of\\n      -- all grantees per privilege, or (if not) template one statement per privilege-grantee pair.\\n      -- `get_dcl_macro` will be either `get_grant_sql` or `get_revoke_sql`\\n    #}\\n    {%- set dcl_statements = [] -%}\\n    {%- for privilege, grantees in grant_config.items() %}\\n        {%- if support_multiple_grantees_per_dcl_statement() and grantees -%}\\n          {%- set dcl = get_dcl_macro(relation, privilege, grantees) -%}\\n          {%- do dcl_statements.append(dcl) -%}\\n        {%- else -%}\\n          {%- for grantee in grantees -%}\\n              {% set dcl = get_dcl_macro(relation, privilege, [grantee]) %}\\n              {%- do dcl_statements.append(dcl) -%}\\n          {% endfor -%}\\n        {%- endif -%}\\n    {%- endfor -%}\\n    {{ return(dcl_statements) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.support_multiple_grantees_per_dcl_statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.069387, \"supported_languages\": null}, \"macro.dbt.call_dcl_statements\": {\"unique_id\": \"macro.dbt.call_dcl_statements\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"name\": \"call_dcl_statements\", \"macro_sql\": \"{% macro call_dcl_statements(dcl_statement_list) %}\\n    {{ return(adapter.dispatch(\\\"call_dcl_statements\\\", \\\"dbt\\\")(dcl_statement_list)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__call_dcl_statements\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.070018, \"supported_languages\": null}, \"macro.dbt.default__call_dcl_statements\": {\"unique_id\": \"macro.dbt.default__call_dcl_statements\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"name\": \"default__call_dcl_statements\", \"macro_sql\": \"{% macro default__call_dcl_statements(dcl_statement_list) %}\\n    {#\\n      -- By default, supply all grant + revoke statements in a single semicolon-separated block,\\n      -- so that they're all processed together.\\n\\n      -- Some databases do not support this. Those adapters will need to override this macro\\n      -- to run each statement individually.\\n    #}\\n    {% call statement('grants') %}\\n        {% for dcl_statement in dcl_statement_list %}\\n            {{ dcl_statement }};\\n        {% endfor %}\\n    {% endcall %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.070652, \"supported_languages\": null}, \"macro.dbt.apply_grants\": {\"unique_id\": \"macro.dbt.apply_grants\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"name\": \"apply_grants\", \"macro_sql\": \"{% macro apply_grants(relation, grant_config, should_revoke) %}\\n    {{ return(adapter.dispatch(\\\"apply_grants\\\", \\\"dbt\\\")(relation, grant_config, should_revoke)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__apply_grants\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.071306, \"supported_languages\": null}, \"macro.dbt.default__apply_grants\": {\"unique_id\": \"macro.dbt.default__apply_grants\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"name\": \"default__apply_grants\", \"macro_sql\": \"{% macro default__apply_grants(relation, grant_config, should_revoke=True) %}\\n    {#-- If grant_config is {} or None, this is a no-op --#}\\n    {% if grant_config %}\\n        {% if should_revoke %}\\n            {#-- We think previous grants may have carried over --#}\\n            {#-- Show current grants and calculate diffs --#}\\n            {% set current_grants_table = run_query(get_show_grant_sql(relation)) %}\\n            {% set current_grants_dict = adapter.standardize_grants_dict(current_grants_table) %}\\n            {% set needs_granting = diff_of_two_dicts(grant_config, current_grants_dict) %}\\n            {% set needs_revoking = diff_of_two_dicts(current_grants_dict, grant_config) %}\\n            {% if not (needs_granting or needs_revoking) %}\\n                {{ log('On ' ~ relation ~': All grants are in place, no revocation or granting needed.')}}\\n            {% endif %}\\n        {% else %}\\n            {#-- We don't think there's any chance of previous grants having carried over. --#}\\n            {#-- Jump straight to granting what the user has configured. --#}\\n            {% set needs_revoking = {} %}\\n            {% set needs_granting = grant_config %}\\n        {% endif %}\\n        {% if needs_granting or needs_revoking %}\\n            {% set revoke_statement_list = get_dcl_statement_list(relation, needs_revoking, get_revoke_sql) %}\\n            {% set grant_statement_list = get_dcl_statement_list(relation, needs_granting, get_grant_sql) %}\\n            {% set dcl_statement_list = revoke_statement_list + grant_statement_list %}\\n            {% if dcl_statement_list %}\\n                {{ call_dcl_statements(dcl_statement_list) }}\\n            {% endif %}\\n        {% endif %}\\n    {% endif %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.run_query\", \"macro.dbt.get_show_grant_sql\", \"macro.dbt.get_dcl_statement_list\", \"macro.dbt.call_dcl_statements\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.074133, \"supported_languages\": null}, \"macro.dbt.alter_column_comment\": {\"unique_id\": \"macro.dbt.alter_column_comment\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"name\": \"alter_column_comment\", \"macro_sql\": \"{% macro alter_column_comment(relation, column_dict) -%}\\n  {{ return(adapter.dispatch('alter_column_comment', 'dbt')(relation, column_dict)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__alter_column_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.07601, \"supported_languages\": null}, \"macro.dbt.default__alter_column_comment\": {\"unique_id\": \"macro.dbt.default__alter_column_comment\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"name\": \"default__alter_column_comment\", \"macro_sql\": \"{% macro default__alter_column_comment(relation, column_dict) -%}\\n  {{ exceptions.raise_not_implemented(\\n    'alter_column_comment macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.076446, \"supported_languages\": null}, \"macro.dbt.alter_relation_comment\": {\"unique_id\": \"macro.dbt.alter_relation_comment\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"name\": \"alter_relation_comment\", \"macro_sql\": \"{% macro alter_relation_comment(relation, relation_comment) -%}\\n  {{ return(adapter.dispatch('alter_relation_comment', 'dbt')(relation, relation_comment)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__alter_relation_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.0769558, \"supported_languages\": null}, \"macro.dbt.default__alter_relation_comment\": {\"unique_id\": \"macro.dbt.default__alter_relation_comment\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"name\": \"default__alter_relation_comment\", \"macro_sql\": \"{% macro default__alter_relation_comment(relation, relation_comment) -%}\\n  {{ exceptions.raise_not_implemented(\\n    'alter_relation_comment macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.077386, \"supported_languages\": null}, \"macro.dbt.persist_docs\": {\"unique_id\": \"macro.dbt.persist_docs\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"name\": \"persist_docs\", \"macro_sql\": \"{% macro persist_docs(relation, model, for_relation=true, for_columns=true) -%}\\n  {{ return(adapter.dispatch('persist_docs', 'dbt')(relation, model, for_relation, for_columns)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__persist_docs\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.078047, \"supported_languages\": null}, \"macro.dbt.default__persist_docs\": {\"unique_id\": \"macro.dbt.default__persist_docs\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"name\": \"default__persist_docs\", \"macro_sql\": \"{% macro default__persist_docs(relation, model, for_relation, for_columns) -%}\\n  {% if for_relation and config.persist_relation_docs() and model.description %}\\n    {% do run_query(alter_relation_comment(relation, model.description)) %}\\n  {% endif %}\\n\\n  {% if for_columns and config.persist_column_docs() and model.columns %}\\n    {% do run_query(alter_column_comment(relation, model.columns)) %}\\n  {% endif %}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.run_query\", \"macro.dbt.alter_relation_comment\", \"macro.dbt.alter_column_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.0792341, \"supported_languages\": null}, \"macro.dbt.get_catalog\": {\"unique_id\": \"macro.dbt.get_catalog\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"name\": \"get_catalog\", \"macro_sql\": \"{% macro get_catalog(information_schema, schemas) -%}\\n  {{ return(adapter.dispatch('get_catalog', 'dbt')(information_schema, schemas)) }}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_catalog\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.0824351, \"supported_languages\": null}, \"macro.dbt.default__get_catalog\": {\"unique_id\": \"macro.dbt.default__get_catalog\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"name\": \"default__get_catalog\", \"macro_sql\": \"{% macro default__get_catalog(information_schema, schemas) -%}\\n\\n  {% set typename = adapter.type() %}\\n  {% set msg -%}\\n    get_catalog not implemented for {{ typename }}\\n  {%- endset %}\\n\\n  {{ exceptions.raise_compiler_error(msg) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.0830872, \"supported_languages\": null}, \"macro.dbt.information_schema_name\": {\"unique_id\": \"macro.dbt.information_schema_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"name\": \"information_schema_name\", \"macro_sql\": \"{% macro information_schema_name(database) %}\\n  {{ return(adapter.dispatch('information_schema_name', 'dbt')(database)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__information_schema_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.083549, \"supported_languages\": null}, \"macro.dbt.default__information_schema_name\": {\"unique_id\": \"macro.dbt.default__information_schema_name\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"name\": \"default__information_schema_name\", \"macro_sql\": \"{% macro default__information_schema_name(database) -%}\\n  {%- if database -%}\\n    {{ database }}.INFORMATION_SCHEMA\\n  {%- else -%}\\n    INFORMATION_SCHEMA\\n  {%- endif -%}\\n{%- endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.083961, \"supported_languages\": null}, \"macro.dbt.list_schemas\": {\"unique_id\": \"macro.dbt.list_schemas\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"name\": \"list_schemas\", \"macro_sql\": \"{% macro list_schemas(database) -%}\\n  {{ return(adapter.dispatch('list_schemas', 'dbt')(database)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__list_schemas\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.0844128, \"supported_languages\": null}, \"macro.dbt.default__list_schemas\": {\"unique_id\": \"macro.dbt.default__list_schemas\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"name\": \"default__list_schemas\", \"macro_sql\": \"{% macro default__list_schemas(database) -%}\\n  {% set sql %}\\n    select distinct schema_name\\n    from {{ information_schema_name(database) }}.SCHEMATA\\n    where catalog_name ilike '{{ database }}'\\n  {% endset %}\\n  {{ return(run_query(sql)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.information_schema_name\", \"macro.dbt.run_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.085026, \"supported_languages\": null}, \"macro.dbt.check_schema_exists\": {\"unique_id\": \"macro.dbt.check_schema_exists\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"name\": \"check_schema_exists\", \"macro_sql\": \"{% macro check_schema_exists(information_schema, schema) -%}\\n  {{ return(adapter.dispatch('check_schema_exists', 'dbt')(information_schema, schema)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__check_schema_exists\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.0855522, \"supported_languages\": null}, \"macro.dbt.default__check_schema_exists\": {\"unique_id\": \"macro.dbt.default__check_schema_exists\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"name\": \"default__check_schema_exists\", \"macro_sql\": \"{% macro default__check_schema_exists(information_schema, schema) -%}\\n  {% set sql -%}\\n        select count(*)\\n        from {{ information_schema.replace(information_schema_view='SCHEMATA') }}\\n        where catalog_name='{{ information_schema.database }}'\\n          and schema_name='{{ schema }}'\\n  {%- endset %}\\n  {{ return(run_query(sql)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.replace\", \"macro.dbt.run_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.0863092, \"supported_languages\": null}, \"macro.dbt.list_relations_without_caching\": {\"unique_id\": \"macro.dbt.list_relations_without_caching\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"name\": \"list_relations_without_caching\", \"macro_sql\": \"{% macro list_relations_without_caching(schema_relation) %}\\n  {{ return(adapter.dispatch('list_relations_without_caching', 'dbt')(schema_relation)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__list_relations_without_caching\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.086777, \"supported_languages\": null}, \"macro.dbt.default__list_relations_without_caching\": {\"unique_id\": \"macro.dbt.default__list_relations_without_caching\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"name\": \"default__list_relations_without_caching\", \"macro_sql\": \"{% macro default__list_relations_without_caching(schema_relation) %}\\n  {{ exceptions.raise_not_implemented(\\n    'list_relations_without_caching macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.087187, \"supported_languages\": null}, \"macro.dbt.get_columns_in_relation\": {\"unique_id\": \"macro.dbt.get_columns_in_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"name\": \"get_columns_in_relation\", \"macro_sql\": \"{% macro get_columns_in_relation(relation) -%}\\n  {{ return(adapter.dispatch('get_columns_in_relation', 'dbt')(relation)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_columns_in_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.09098, \"supported_languages\": null}, \"macro.dbt.default__get_columns_in_relation\": {\"unique_id\": \"macro.dbt.default__get_columns_in_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"name\": \"default__get_columns_in_relation\", \"macro_sql\": \"{% macro default__get_columns_in_relation(relation) -%}\\n  {{ exceptions.raise_not_implemented(\\n    'get_columns_in_relation macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.0918489, \"supported_languages\": null}, \"macro.dbt.sql_convert_columns_in_relation\": {\"unique_id\": \"macro.dbt.sql_convert_columns_in_relation\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"name\": \"sql_convert_columns_in_relation\", \"macro_sql\": \"{% macro sql_convert_columns_in_relation(table) -%}\\n  {% set columns = [] %}\\n  {% for row in table %}\\n    {% do columns.append(api.Column(*row)) %}\\n  {% endfor %}\\n  {{ return(columns) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.092635, \"supported_languages\": null}, \"macro.dbt.get_columns_in_query\": {\"unique_id\": \"macro.dbt.get_columns_in_query\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"name\": \"get_columns_in_query\", \"macro_sql\": \"{% macro get_columns_in_query(select_sql) -%}\\n  {{ return(adapter.dispatch('get_columns_in_query', 'dbt')(select_sql)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__get_columns_in_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.0931032, \"supported_languages\": null}, \"macro.dbt.default__get_columns_in_query\": {\"unique_id\": \"macro.dbt.default__get_columns_in_query\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"name\": \"default__get_columns_in_query\", \"macro_sql\": \"{% macro default__get_columns_in_query(select_sql) %}\\n    {% call statement('get_columns_in_query', fetch_result=True, auto_begin=False) -%}\\n        select * from (\\n            {{ select_sql }}\\n        ) as __dbt_sbq\\n        where false\\n        limit 0\\n    {% endcall %}\\n\\n    {{ return(load_result('get_columns_in_query').table.columns | map(attribute='name') | list) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.09394, \"supported_languages\": null}, \"macro.dbt.alter_column_type\": {\"unique_id\": \"macro.dbt.alter_column_type\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"name\": \"alter_column_type\", \"macro_sql\": \"{% macro alter_column_type(relation, column_name, new_column_type) -%}\\n  {{ return(adapter.dispatch('alter_column_type', 'dbt')(relation, column_name, new_column_type)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__alter_column_type\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.094506, \"supported_languages\": null}, \"macro.dbt.default__alter_column_type\": {\"unique_id\": \"macro.dbt.default__alter_column_type\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"name\": \"default__alter_column_type\", \"macro_sql\": \"{% macro default__alter_column_type(relation, column_name, new_column_type) -%}\\n  {#\\n    1. Create a new column (w/ temp name and correct type)\\n    2. Copy data over to it\\n    3. Drop the existing column (cascade!)\\n    4. Rename the new column to existing column\\n  #}\\n  {%- set tmp_column = column_name + \\\"__dbt_alter\\\" -%}\\n\\n  {% call statement('alter_column_type') %}\\n    alter table {{ relation }} add column {{ adapter.quote(tmp_column) }} {{ new_column_type }};\\n    update {{ relation }} set {{ adapter.quote(tmp_column) }} = {{ adapter.quote(column_name) }};\\n    alter table {{ relation }} drop column {{ adapter.quote(column_name) }} cascade;\\n    alter table {{ relation }} rename column {{ adapter.quote(tmp_column) }} to {{ adapter.quote(column_name) }}\\n  {% endcall %}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.0959759, \"supported_languages\": null}, \"macro.dbt.alter_relation_add_remove_columns\": {\"unique_id\": \"macro.dbt.alter_relation_add_remove_columns\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"name\": \"alter_relation_add_remove_columns\", \"macro_sql\": \"{% macro alter_relation_add_remove_columns(relation, add_columns = none, remove_columns = none) -%}\\n  {{ return(adapter.dispatch('alter_relation_add_remove_columns', 'dbt')(relation, add_columns, remove_columns)) }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__alter_relation_add_remove_columns\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.096619, \"supported_languages\": null}, \"macro.dbt.default__alter_relation_add_remove_columns\": {\"unique_id\": \"macro.dbt.default__alter_relation_add_remove_columns\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"name\": \"default__alter_relation_add_remove_columns\", \"macro_sql\": \"{% macro default__alter_relation_add_remove_columns(relation, add_columns, remove_columns) %}\\n\\n  {% if add_columns is none %}\\n    {% set add_columns = [] %}\\n  {% endif %}\\n  {% if remove_columns is none %}\\n    {% set remove_columns = [] %}\\n  {% endif %}\\n\\n  {% set sql -%}\\n\\n     alter {{ relation.type }} {{ relation }}\\n\\n            {% for column in add_columns %}\\n               add column {{ column.name }} {{ column.data_type }}{{ ',' if not loop.last }}\\n            {% endfor %}{{ ',' if add_columns and remove_columns }}\\n\\n            {% for column in remove_columns %}\\n                drop column {{ column.name }}{{ ',' if not loop.last }}\\n            {% endfor %}\\n\\n  {%- endset -%}\\n\\n  {% do run_query(sql) %}\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.run_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.098658, \"supported_languages\": null}, \"macro.dbt.build_ref_function\": {\"unique_id\": \"macro.dbt.build_ref_function\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/python_model/python.sql\", \"original_file_path\": \"macros/python_model/python.sql\", \"name\": \"build_ref_function\", \"macro_sql\": \"{% macro build_ref_function(model) %}\\n\\n    {%- set ref_dict = {} -%}\\n    {%- for _ref in model.refs -%}\\n        {%- set resolved = ref(*_ref) -%}\\n        {%- do ref_dict.update({_ref | join(\\\".\\\"): resolved.quote(database=False, schema=False, identifier=False) | string}) -%}\\n    {%- endfor -%}\\n\\ndef ref(*args,dbt_load_df_function):\\n    refs = {{ ref_dict | tojson }}\\n    key = \\\".\\\".join(args)\\n    return dbt_load_df_function(refs[key])\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.10208, \"supported_languages\": null}, \"macro.dbt.build_source_function\": {\"unique_id\": \"macro.dbt.build_source_function\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/python_model/python.sql\", \"original_file_path\": \"macros/python_model/python.sql\", \"name\": \"build_source_function\", \"macro_sql\": \"{% macro build_source_function(model) %}\\n\\n    {%- set source_dict = {} -%}\\n    {%- for _source in model.sources -%}\\n        {%- set resolved = source(*_source) -%}\\n        {%- do source_dict.update({_source | join(\\\".\\\"): resolved.quote(database=False, schema=False, identifier=False) | string}) -%}\\n    {%- endfor -%}\\n\\ndef source(*args, dbt_load_df_function):\\n    sources = {{ source_dict | tojson }}\\n    key = \\\".\\\".join(args)\\n    return dbt_load_df_function(sources[key])\\n\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.103234, \"supported_languages\": null}, \"macro.dbt.build_config_dict\": {\"unique_id\": \"macro.dbt.build_config_dict\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/python_model/python.sql\", \"original_file_path\": \"macros/python_model/python.sql\", \"name\": \"build_config_dict\", \"macro_sql\": \"{% macro build_config_dict(model) %}\\n    {%- set config_dict = {} -%}\\n    {%- for key in model.config.config_keys_used -%}\\n        {# weird type testing with enum, would be much easier to write this logic in Python! #}\\n        {%- if key == 'language' -%}\\n          {%- set value = 'python' -%}\\n        {%- endif -%}\\n        {%- set value = model.config[key] -%}\\n        {%- do config_dict.update({key: value}) -%}\\n    {%- endfor -%}\\nconfig_dict = {{ config_dict }}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.104405, \"supported_languages\": null}, \"macro.dbt.py_script_postfix\": {\"unique_id\": \"macro.dbt.py_script_postfix\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/python_model/python.sql\", \"original_file_path\": \"macros/python_model/python.sql\", \"name\": \"py_script_postfix\", \"macro_sql\": \"{% macro py_script_postfix(model) %}\\n# This part is user provided model code\\n# you will need to copy the next section to run the code\\n# COMMAND ----------\\n# this part is dbt logic for get ref work, do not modify\\n\\n{{ build_ref_function(model ) }}\\n{{ build_source_function(model ) }}\\n{{ build_config_dict(model) }}\\n\\nclass config:\\n    def __init__(self, *args, **kwargs):\\n        pass\\n\\n    @staticmethod\\n    def get(key, default=None):\\n        return config_dict.get(key, default)\\n\\nclass this:\\n    \\\"\\\"\\\"dbt.this() or dbt.this.identifier\\\"\\\"\\\"\\n    database = '{{ this.database }}'\\n    schema = '{{ this.schema }}'\\n    identifier = '{{ this.identifier }}'\\n    def __repr__(self):\\n        return '{{ this }}'\\n\\n\\nclass dbtObj:\\n    def __init__(self, load_df_function) -> None:\\n        self.source = lambda *args: source(*args, dbt_load_df_function=load_df_function)\\n        self.ref = lambda *args: ref(*args, dbt_load_df_function=load_df_function)\\n        self.config = config\\n        self.this = this()\\n        self.is_incremental = {{ is_incremental() }}\\n\\n# COMMAND ----------\\n{{py_script_comment()}}\\n{% endmacro %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.build_ref_function\", \"macro.dbt.build_source_function\", \"macro.dbt.build_config_dict\", \"macro.dbt.is_incremental\", \"macro.dbt.py_script_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.105411, \"supported_languages\": null}, \"macro.dbt.py_script_comment\": {\"unique_id\": \"macro.dbt.py_script_comment\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"macros/python_model/python.sql\", \"original_file_path\": \"macros/python_model/python.sql\", \"name\": \"py_script_comment\", \"macro_sql\": \"{%macro py_script_comment()%}\\n{%endmacro%}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.105611, \"supported_languages\": null}, \"macro.dbt.test_unique\": {\"unique_id\": \"macro.dbt.test_unique\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"tests/generic/builtin.sql\", \"original_file_path\": \"tests/generic/builtin.sql\", \"name\": \"test_unique\", \"macro_sql\": \"{% test unique(model, column_name) %}\\n    {% set macro = adapter.dispatch('test_unique', 'dbt') %}\\n    {{ macro(model, column_name) }}\\n{% endtest %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__test_unique\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.107241, \"supported_languages\": null}, \"macro.dbt.test_not_null\": {\"unique_id\": \"macro.dbt.test_not_null\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"tests/generic/builtin.sql\", \"original_file_path\": \"tests/generic/builtin.sql\", \"name\": \"test_not_null\", \"macro_sql\": \"{% test not_null(model, column_name) %}\\n    {% set macro = adapter.dispatch('test_not_null', 'dbt') %}\\n    {{ macro(model, column_name) }}\\n{% endtest %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__test_not_null\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.10783, \"supported_languages\": null}, \"macro.dbt.test_accepted_values\": {\"unique_id\": \"macro.dbt.test_accepted_values\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"tests/generic/builtin.sql\", \"original_file_path\": \"tests/generic/builtin.sql\", \"name\": \"test_accepted_values\", \"macro_sql\": \"{% test accepted_values(model, column_name, values, quote=True) %}\\n    {% set macro = adapter.dispatch('test_accepted_values', 'dbt') %}\\n    {{ macro(model, column_name, values, quote) }}\\n{% endtest %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__test_accepted_values\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.108544, \"supported_languages\": null}, \"macro.dbt.test_relationships\": {\"unique_id\": \"macro.dbt.test_relationships\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"tests/generic/builtin.sql\", \"original_file_path\": \"tests/generic/builtin.sql\", \"name\": \"test_relationships\", \"macro_sql\": \"{% test relationships(model, column_name, to, field) %}\\n    {% set macro = adapter.dispatch('test_relationships', 'dbt') %}\\n    {{ macro(model, column_name, to, field) }}\\n{% endtest %}\", \"resource_type\": \"macro\", \"tags\": [], \"depends_on\": {\"macros\": [\"macro.dbt.default__test_relationships\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676324075.109239, \"supported_languages\": null}}, \"docs\": {\"test.somedoc\": {\"unique_id\": \"test.somedoc\", \"package_name\": \"test\", \"root_path\": \"/private/var/folders/qt/vw8wqdgx4w381wh14b9y25m40000gn/T/pytest-of-gerda/pytest-126/project0\", \"path\": \"somedoc.md\", \"original_file_path\": \"models/somedoc.md\", \"name\": \"somedoc\", \"block_contents\": \"Testing, testing\"}, \"dbt.__overview__\": {\"unique_id\": \"dbt.__overview__\", \"package_name\": \"dbt\", \"root_path\": \"/Users/gerda/FTA/dbt/core/dbt/include/global_project\", \"path\": \"overview.md\", \"original_file_path\": \"docs/overview.md\", \"name\": \"__overview__\", \"block_contents\": \"### Welcome!\\n\\nWelcome to the auto-generated documentation for your dbt project!\\n\\n### Navigation\\n\\nYou can use the `Project` and `Database` navigation tabs on the left side of the window to explore the models\\nin your project.\\n\\n#### Project Tab\\nThe `Project` tab mirrors the directory structure of your dbt project. In this tab, you can see all of the\\nmodels defined in your dbt project, as well as models imported from dbt packages.\\n\\n#### Database Tab\\nThe `Database` tab also exposes your models, but in a format that looks more like a database explorer. This view\\nshows relations (tables and views) grouped into database schemas. Note that ephemeral models are _not_ shown\\nin this interface, as they do not exist in the database.\\n\\n### Graph Exploration\\nYou can click the blue icon on the bottom-right corner of the page to view the lineage graph of your models.\\n\\nOn model pages, you'll see the immediate parents and children of the model you're exploring. By clicking the `Expand`\\nbutton at the top-right of this lineage pane, you'll be able to see all of the models that are used to build,\\nor are built from, the model you're exploring.\\n\\nOnce expanded, you'll be able to use the `--select` and `--exclude` model selection syntax to filter the\\nmodels in the graph. For more information on model selection, check out the [dbt docs](https://docs.getdbt.com/docs/model-selection-syntax).\\n\\nNote that you can also right-click on models to interactively filter and explore the graph.\\n\\n---\\n\\n### More information\\n\\n- [What is dbt](https://docs.getdbt.com/docs/introduction)?\\n- Read the [dbt viewpoint](https://docs.getdbt.com/docs/viewpoint)\\n- [Installation](https://docs.getdbt.com/docs/installation)\\n- Join the [dbt Community](https://www.getdbt.com/community/) for questions and discussion\"}}, \"exposures\": {\"exposure.test.simple_exposure\": {\"fqn\": [\"test\", \"simple_exposure\"], \"unique_id\": \"exposure.test.simple_exposure\", \"package_name\": \"test\", \"root_path\": \"/private/var/folders/qt/vw8wqdgx4w381wh14b9y25m40000gn/T/pytest-of-gerda/pytest-126/project0\", \"path\": \"schema.yml\", \"original_file_path\": \"models/schema.yml\", \"name\": \"simple_exposure\", \"type\": \"dashboard\", \"owner\": {\"email\": \"something@example.com\", \"name\": null}, \"resource_type\": \"exposure\", \"description\": \"\", \"label\": null, \"maturity\": null, \"meta\": {}, \"tags\": [], \"config\": {\"enabled\": true}, \"unrendered_config\": {}, \"url\": null, \"depends_on\": {\"macros\": [], \"nodes\": [\"source.test.my_source.my_table\", \"model.test.my_model\"]}, \"refs\": [[\"my_model\"]], \"sources\": [[\"my_source\", \"my_table\"]], \"created_at\": 1676324075.609121}}, \"metrics\": {\"metric.test.my_metric\": {\"fqn\": [\"test\", \"my_metric\"], \"unique_id\": \"metric.test.my_metric\", \"package_name\": \"test\", \"root_path\": \"/private/var/folders/qt/vw8wqdgx4w381wh14b9y25m40000gn/T/pytest-of-gerda/pytest-126/project0\", \"path\": \"schema.yml\", \"original_file_path\": \"models/schema.yml\", \"name\": \"my_metric\", \"description\": \"\", \"label\": \"Count records\", \"calculation_method\": \"count\", \"timestamp\": \"updated_at\", \"expression\": \"*\", \"filters\": [], \"time_grains\": [\"day\"], \"dimensions\": [], \"window\": null, \"model\": \"ref('my_model')\", \"model_unique_id\": null, \"resource_type\": \"metric\", \"meta\": {}, \"tags\": [], \"config\": {\"enabled\": true}, \"unrendered_config\": {}, \"sources\": [], \"depends_on\": {\"macros\": [], \"nodes\": [\"model.test.my_model\"]}, \"refs\": [[\"my_model\"]], \"metrics\": [], \"created_at\": 1676324075.618992}}, \"selectors\": {}, \"disabled\": {\"model.test.disabled_model\": [{\"resource_type\": \"model\", \"depends_on\": {\"macros\": [], \"nodes\": []}, \"config\": {\"enabled\": false, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"materialized\": \"view\", \"incremental_strategy\": null, \"persist_docs\": {}, \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": null, \"on_schema_change\": \"ignore\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"post-hook\": [], \"pre-hook\": []}, \"database\": \"dbt\", \"schema\": \"test16763240740000063267_test_previous_version_state\", \"fqn\": [\"test\", \"disabled_model\"], \"unique_id\": \"model.test.disabled_model\", \"raw_code\": \"{{ config(enabled=False) }}\\nselect 2 as id\", \"language\": \"sql\", \"package_name\": \"test\", \"root_path\": \"/private/var/folders/qt/vw8wqdgx4w381wh14b9y25m40000gn/T/pytest-of-gerda/pytest-126/project0\", \"path\": \"disabled_model.sql\", \"original_file_path\": \"models/disabled_model.sql\", \"name\": \"disabled_model\", \"alias\": \"disabled_model\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"34f7b8e60d9e7933469c48d6c92b0a53918d0ba626a9ce2c30ab2f1532145827\"}, \"tags\": [], \"refs\": [], \"sources\": [], \"metrics\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"compiled_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {\"enabled\": false}, \"created_at\": 1676324075.4071748, \"config_call_dict\": {\"enabled\": false}}], \"snapshot.test.disabled_snapshot_seed\": [{\"resource_type\": \"snapshot\", \"depends_on\": {\"macros\": [], \"nodes\": []}, \"config\": {\"enabled\": false, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"materialized\": \"snapshot\", \"incremental_strategy\": null, \"persist_docs\": {}, \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": \"id\", \"on_schema_change\": \"ignore\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"strategy\": \"check\", \"target_schema\": \"test16763240740000063267_test_previous_version_state\", \"target_database\": null, \"updated_at\": null, \"check_cols\": \"all\", \"post-hook\": [], \"pre-hook\": []}, \"database\": \"dbt\", \"schema\": \"test16763240740000063267_test_previous_version_state\", \"fqn\": [\"test\", \"disabled_snapshot_seed\", \"disabled_snapshot_seed\"], \"unique_id\": \"snapshot.test.disabled_snapshot_seed\", \"raw_code\": \"\\n{{\\n    config(\\n      unique_key='id',\\n      strategy='check',\\n      check_cols='all',\\n      target_schema=schema,\\n      enabled=False,\\n    )\\n}}\\nselect * from {{ ref('my_seed') }}\\n\", \"language\": \"sql\", \"package_name\": \"test\", \"root_path\": \"/private/var/folders/qt/vw8wqdgx4w381wh14b9y25m40000gn/T/pytest-of-gerda/pytest-126/project0\", \"path\": \"disabled_snapshot_seed.sql\", \"original_file_path\": \"snapshots/disabled_snapshot_seed.sql\", \"name\": \"disabled_snapshot_seed\", \"alias\": \"disabled_snapshot_seed\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"52b08465e16dcbc364162dfbdb34cf25e04295bc13d63ab0b420f60d15234c76\"}, \"tags\": [], \"refs\": [[\"my_seed\"]], \"sources\": [], \"metrics\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"compiled_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {\"unique_key\": \"id\", \"strategy\": \"check\", \"check_cols\": \"all\", \"target_schema\": \"test16763240740000063267_test_previous_version_state\", \"enabled\": false}, \"created_at\": 1676324075.4334059, \"config_call_dict\": {\"unique_key\": \"id\", \"strategy\": \"check\", \"check_cols\": \"all\", \"target_schema\": \"test16763240740000063267_test_previous_version_state\", \"enabled\": false}}], \"analysis.test.disabled_al\": [{\"resource_type\": \"analysis\", \"depends_on\": {\"macros\": [], \"nodes\": []}, \"config\": {\"enabled\": false, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"materialized\": \"view\", \"incremental_strategy\": null, \"persist_docs\": {}, \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": null, \"on_schema_change\": \"ignore\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"post-hook\": [], \"pre-hook\": []}, \"database\": \"dbt\", \"schema\": \"test16763240740000063267_test_previous_version_state\", \"fqn\": [\"test\", \"analysis\", \"disabled_al\"], \"unique_id\": \"analysis.test.disabled_al\", \"raw_code\": \"{{ config(enabled=False) }}\\nselect 9 as id\", \"language\": \"sql\", \"package_name\": \"test\", \"root_path\": \"/private/var/folders/qt/vw8wqdgx4w381wh14b9y25m40000gn/T/pytest-of-gerda/pytest-126/project0\", \"path\": \"analysis/disabled_al.sql\", \"original_file_path\": \"analyses/disabled_al.sql\", \"name\": \"disabled_al\", \"alias\": \"disabled_al\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"76b8579816eac97721616fd429dcd1a93c311c6358830a65d40ebe5661572610\"}, \"tags\": [], \"refs\": [], \"sources\": [], \"metrics\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"compiled_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {\"enabled\": false}, \"created_at\": 1676324075.4483929, \"config_call_dict\": {\"enabled\": false}}], \"test.test.disabled_just_my\": [{\"resource_type\": \"test\", \"depends_on\": {\"macros\": [], \"nodes\": []}, \"config\": {\"enabled\": false, \"alias\": null, \"schema\": \"dbt_test__audit\", \"database\": null, \"tags\": [], \"meta\": {}, \"materialized\": \"test\", \"severity\": \"ERROR\", \"store_failures\": null, \"where\": null, \"limit\": null, \"fail_calc\": \"count(*)\", \"warn_if\": \"!= 0\", \"error_if\": \"!= 0\"}, \"database\": \"dbt\", \"schema\": \"test16763240740000063267_test_previous_version_state_dbt_test__audit\", \"fqn\": [\"test\", \"disabled_just_my\"], \"unique_id\": \"test.test.disabled_just_my\", \"raw_code\": \"{{ config(enabled=False) }}\\n\\nselect * from {{ ref('my_model') }}\\nwhere false\", \"language\": \"sql\", \"package_name\": \"test\", \"root_path\": \"/private/var/folders/qt/vw8wqdgx4w381wh14b9y25m40000gn/T/pytest-of-gerda/pytest-126/project0\", \"path\": \"disabled_just_my.sql\", \"original_file_path\": \"tests/disabled_just_my.sql\", \"name\": \"disabled_just_my\", \"alias\": \"disabled_just_my\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"0b5827d08d1e3c97e8fb865bea00031b2e90ecef7884a42429cc48d0f48b8c20\"}, \"tags\": [], \"refs\": [[\"my_model\"]], \"sources\": [], \"metrics\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"compiled_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {\"enabled\": false}, \"created_at\": 1676324075.5147672, \"config_call_dict\": {\"enabled\": false}}], \"test.test.disabled_check_nothing_my_model_.f2c6a72d37\": [{\"test_metadata\": {\"name\": \"disabled_check_nothing\", \"kwargs\": {\"model\": \"{{ get_where_subquery(ref('my_model')) }}\"}, \"namespace\": null}, \"resource_type\": \"test\", \"depends_on\": {\"macros\": [\"macro.test.test_disabled_check_nothing\", \"macro.dbt.get_where_subquery\"], \"nodes\": []}, \"config\": {\"enabled\": false, \"alias\": null, \"schema\": \"dbt_test__audit\", \"database\": null, \"tags\": [], \"meta\": {}, \"materialized\": \"test\", \"severity\": \"ERROR\", \"store_failures\": null, \"where\": null, \"limit\": null, \"fail_calc\": \"count(*)\", \"warn_if\": \"!= 0\", \"error_if\": \"!= 0\"}, \"database\": \"dbt\", \"schema\": \"test16763240740000063267_test_previous_version_state_dbt_test__audit\", \"fqn\": [\"test\", \"disabled_check_nothing_my_model_\"], \"unique_id\": \"test.test.disabled_check_nothing_my_model_.f2c6a72d37\", \"raw_code\": \"{{ test_disabled_check_nothing(**_dbt_generic_test_kwargs) }}\", \"language\": \"sql\", \"package_name\": \"test\", \"root_path\": \"/private/var/folders/qt/vw8wqdgx4w381wh14b9y25m40000gn/T/pytest-of-gerda/pytest-126/project0\", \"path\": \"disabled_check_nothing_my_model_.sql\", \"original_file_path\": \"models/schema.yml\", \"name\": \"disabled_check_nothing_my_model_\", \"alias\": \"disabled_check_nothing_my_model_\", \"checksum\": {\"name\": \"none\", \"checksum\": \"\"}, \"tags\": [], \"refs\": [[\"my_model\"]], \"sources\": [], \"metrics\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"compiled_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {\"enabled\": false}, \"created_at\": 1676324075.587028, \"config_call_dict\": {\"enabled\": false}, \"column_name\": null, \"file_key_name\": \"models.my_model\"}], \"exposure.test.disabled_exposure\": [{\"fqn\": [\"test\", \"disabled_exposure\"], \"unique_id\": \"exposure.test.disabled_exposure\", \"package_name\": \"test\", \"root_path\": \"/private/var/folders/qt/vw8wqdgx4w381wh14b9y25m40000gn/T/pytest-of-gerda/pytest-126/project0\", \"path\": \"schema.yml\", \"original_file_path\": \"models/schema.yml\", \"name\": \"disabled_exposure\", \"type\": \"dashboard\", \"owner\": {\"email\": \"something@example.com\", \"name\": null}, \"resource_type\": \"exposure\", \"description\": \"\", \"label\": null, \"maturity\": null, \"meta\": {}, \"tags\": [], \"config\": {\"enabled\": false}, \"unrendered_config\": {\"enabled\": false}, \"url\": null, \"depends_on\": {\"macros\": [], \"nodes\": []}, \"refs\": [[\"my_model\"]], \"sources\": [], \"created_at\": 1676324075.612152}], \"metric.test.disabled_metric\": [{\"fqn\": [\"test\", \"disabled_metric\"], \"unique_id\": \"metric.test.disabled_metric\", \"package_name\": \"test\", \"root_path\": \"/private/var/folders/qt/vw8wqdgx4w381wh14b9y25m40000gn/T/pytest-of-gerda/pytest-126/project0\", \"path\": \"schema.yml\", \"original_file_path\": \"models/schema.yml\", \"name\": \"disabled_metric\", \"description\": \"\", \"label\": \"Count records\", \"calculation_method\": \"count\", \"timestamp\": \"updated_at\", \"expression\": \"*\", \"filters\": [], \"time_grains\": [\"day\"], \"dimensions\": [], \"window\": null, \"model\": \"ref('my_model')\", \"model_unique_id\": null, \"resource_type\": \"metric\", \"meta\": {}, \"tags\": [], \"config\": {\"enabled\": false}, \"unrendered_config\": {\"enabled\": false}, \"sources\": [], \"depends_on\": {\"macros\": [], \"nodes\": []}, \"refs\": [[\"my_model\"]], \"metrics\": [], \"created_at\": 1676324075.622605}], \"seed.test.disabled_seed\": [{\"resource_type\": \"seed\", \"depends_on\": {\"macros\": [], \"nodes\": []}, \"config\": {\"enabled\": false, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"materialized\": \"seed\", \"incremental_strategy\": null, \"persist_docs\": {}, \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": null, \"on_schema_change\": \"ignore\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"quote_columns\": null, \"post-hook\": [], \"pre-hook\": []}, \"database\": \"dbt\", \"schema\": \"test16763240740000063267_test_previous_version_state\", \"fqn\": [\"test\", \"disabled_seed\"], \"unique_id\": \"seed.test.disabled_seed\", \"raw_code\": \"\", \"language\": \"sql\", \"package_name\": \"test\", \"root_path\": \"/private/var/folders/qt/vw8wqdgx4w381wh14b9y25m40000gn/T/pytest-of-gerda/pytest-126/project0\", \"path\": \"disabled_seed.csv\", \"original_file_path\": \"seeds/disabled_seed.csv\", \"name\": \"disabled_seed\", \"alias\": \"disabled_seed\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"c6c08a913b5a382014ef0ba248d97b12fc801beb369fdbd24aff1a3912ee3773\"}, \"tags\": [], \"refs\": [], \"sources\": [], \"metrics\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": \"test://models/schema.yml\", \"compiled_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {\"enabled\": false}, \"created_at\": 1676324075.594186, \"config_call_dict\": {}}], \"source.test.my_source.disabled_table\": [{\"fqn\": [\"test\", \"my_source\", \"disabled_table\"], \"database\": \"dbt\", \"schema\": \"my_source\", \"unique_id\": \"source.test.my_source.disabled_table\", \"package_name\": \"test\", \"root_path\": \"/private/var/folders/qt/vw8wqdgx4w381wh14b9y25m40000gn/T/pytest-of-gerda/pytest-126/project0\", \"path\": \"models/schema.yml\", \"original_file_path\": \"models/schema.yml\", \"name\": \"disabled_table\", \"source_name\": \"my_source\", \"source_description\": \"My source\", \"loader\": \"a_loader\", \"identifier\": \"disabled_table\", \"resource_type\": \"source\", \"quoting\": {\"database\": null, \"schema\": null, \"identifier\": null, \"column\": null}, \"loaded_at_field\": null, \"freshness\": {\"warn_after\": {\"count\": null, \"period\": null}, \"error_after\": {\"count\": null, \"period\": null}, \"filter\": null}, \"external\": null, \"description\": \"Disabled table\", \"columns\": {}, \"meta\": {}, \"source_meta\": {}, \"tags\": [], \"config\": {\"enabled\": false}, \"patch_path\": null, \"unrendered_config\": {\"enabled\": false}, \"relation_name\": \"\\\"dbt\\\".\\\"my_source\\\".\\\"disabled_table\\\"\", \"created_at\": 1676324075.625102}]}, \"parent_map\": {\"model.test.my_model\": [], \"snapshot.test.snapshot_seed\": [\"seed.test.my_seed\"], \"analysis.test.a\": [], \"test.test.just_my\": [\"model.test.my_model\"], \"seed.test.my_seed\": [], \"test.test.not_null_my_model_id.43e0e9183a\": [\"model.test.my_model\"], \"test.test.check_nothing_my_model_.d5a5e66110\": [\"model.test.my_model\"], \"source.test.my_source.my_table\": [], \"exposure.test.simple_exposure\": [\"model.test.my_model\", \"source.test.my_source.my_table\"], \"metric.test.my_metric\": [\"model.test.my_model\"]}, \"child_map\": {\"model.test.my_model\": [\"exposure.test.simple_exposure\", \"metric.test.my_metric\", \"test.test.check_nothing_my_model_.d5a5e66110\", \"test.test.just_my\", \"test.test.not_null_my_model_id.43e0e9183a\"], \"snapshot.test.snapshot_seed\": [], \"analysis.test.a\": [], \"test.test.just_my\": [], \"seed.test.my_seed\": [\"snapshot.test.snapshot_seed\"], \"test.test.not_null_my_model_id.43e0e9183a\": [], \"test.test.check_nothing_my_model_.d5a5e66110\": [], \"source.test.my_source.my_table\": [\"exposure.test.simple_exposure\"], \"exposure.test.simple_exposure\": [], \"metric.test.my_metric\": []}}\n"
  },
  {
    "path": "tests/functional/artifacts/data/state/v8/manifest.json",
    "content": "{\"metadata\": {\"dbt_schema_version\": \"https://schemas.getdbt.com/dbt/manifest/v8.json\", \"dbt_version\": \"1.5.0a1\", \"generated_at\": \"2023-02-13T21:04:43.788883Z\", \"invocation_id\": \"c7896040-31e1-487d-8438-19d703edb137\", \"env\": {}, \"project_id\": \"098f6bcd4621d373cade4e832627b4f6\", \"user_id\": null, \"send_anonymous_usage_stats\": false, \"adapter_type\": \"postgres\"}, \"nodes\": {\"model.test.my_model\": {\"database\": \"dbt\", \"schema\": \"test16763222812618906995_test_previous_version_state\", \"name\": \"my_model\", \"resource_type\": \"model\", \"package_name\": \"test\", \"path\": \"my_model.sql\", \"original_file_path\": \"models/my_model.sql\", \"unique_id\": \"model.test.my_model\", \"fqn\": [\"test\", \"my_model\"], \"alias\": \"my_model\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"2b9123e04ab8bb798f7c565afdc3ee0e56fcd66b4bfbdb435b4891c878d947c5\"}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"materialized\": \"view\", \"incremental_strategy\": null, \"persist_docs\": {}, \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": null, \"on_schema_change\": \"ignore\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"post-hook\": [], \"pre-hook\": []}, \"tags\": [], \"description\": \"Example model\", \"columns\": {\"id\": {\"name\": \"id\", \"description\": \"\", \"meta\": {}, \"data_type\": null, \"quote\": null, \"tags\": []}}, \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": \"test://models/schema.yml\", \"build_path\": null, \"deferred\": false, \"unrendered_config\": {}, \"created_at\": 1676322282.4291918, \"relation_name\": \"\\\"dbt\\\".\\\"test16763222812618906995_test_previous_version_state\\\".\\\"my_model\\\"\", \"raw_code\": \"select 1 as id\", \"language\": \"sql\", \"refs\": [], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [], \"nodes\": []}, \"compiled_path\": null}, \"snapshot.test.snapshot_seed\": {\"database\": \"dbt\", \"schema\": \"test16763222812618906995_test_previous_version_state\", \"name\": \"snapshot_seed\", \"resource_type\": \"snapshot\", \"package_name\": \"test\", \"path\": \"snapshot_seed.sql\", \"original_file_path\": \"snapshots/snapshot_seed.sql\", \"unique_id\": \"snapshot.test.snapshot_seed\", \"fqn\": [\"test\", \"snapshot_seed\", \"snapshot_seed\"], \"alias\": \"snapshot_seed\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"00c13c306831070996970605fbc4c901aa456e1ed1c028725a932e4e6a4ffb0a\"}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"materialized\": \"snapshot\", \"incremental_strategy\": null, \"persist_docs\": {}, \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": \"id\", \"on_schema_change\": \"ignore\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"strategy\": \"check\", \"target_schema\": \"test16763222812618906995_test_previous_version_state\", \"target_database\": null, \"updated_at\": null, \"check_cols\": \"all\", \"post-hook\": [], \"pre-hook\": []}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {\"unique_key\": \"id\", \"strategy\": \"check\", \"check_cols\": \"all\", \"target_schema\": \"test16763222812618906995_test_previous_version_state\"}, \"created_at\": 1676322282.28191, \"relation_name\": \"\\\"dbt\\\".\\\"test16763222812618906995_test_previous_version_state\\\".\\\"snapshot_seed\\\"\", \"raw_code\": \"\\n{{\\n    config(\\n      unique_key='id',\\n      strategy='check',\\n      check_cols='all',\\n      target_schema=schema,\\n    )\\n}}\\nselect * from {{ ref('my_seed') }}\\n\", \"language\": \"sql\", \"refs\": [[\"my_seed\"]], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [], \"nodes\": [\"seed.test.my_seed\"]}, \"compiled_path\": null}, \"analysis.test.a\": {\"database\": \"dbt\", \"schema\": \"test16763222812618906995_test_previous_version_state\", \"name\": \"a\", \"resource_type\": \"analysis\", \"package_name\": \"test\", \"path\": \"analysis/a.sql\", \"original_file_path\": \"analyses/a.sql\", \"unique_id\": \"analysis.test.a\", \"fqn\": [\"test\", \"analysis\", \"a\"], \"alias\": \"a\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"bd1ee600e4e80d03f488fee52a66e8d51b5be2b98acc20df1cf8be4670d86ae5\"}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"materialized\": \"view\", \"incremental_strategy\": null, \"persist_docs\": {}, \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": null, \"on_schema_change\": \"ignore\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"post-hook\": [], \"pre-hook\": []}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {}, \"created_at\": 1676322282.338664, \"relation_name\": null, \"raw_code\": \"select 4 as id\", \"language\": \"sql\", \"refs\": [], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [], \"nodes\": []}, \"compiled_path\": null}, \"test.test.just_my\": {\"database\": \"dbt\", \"schema\": \"test16763222812618906995_test_previous_version_state_dbt_test__audit\", \"name\": \"just_my\", \"resource_type\": \"test\", \"package_name\": \"test\", \"path\": \"just_my.sql\", \"original_file_path\": \"tests/just_my.sql\", \"unique_id\": \"test.test.just_my\", \"fqn\": [\"test\", \"just_my\"], \"alias\": \"just_my\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"f30b7a814e0e3761d1a8042aa40d658d6c33affb28cd92782b0f56559c414fd8\"}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": \"dbt_test__audit\", \"database\": null, \"tags\": [\"data_test_tag\"], \"meta\": {}, \"materialized\": \"test\", \"severity\": \"ERROR\", \"store_failures\": null, \"where\": null, \"limit\": null, \"fail_calc\": \"count(*)\", \"warn_if\": \"!= 0\", \"error_if\": \"!= 0\"}, \"tags\": [\"data_test_tag\"], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {\"tags\": [\"data_test_tag\"]}, \"created_at\": 1676322282.365304, \"relation_name\": null, \"raw_code\": \"{{ config(tags = ['data_test_tag']) }}\\n\\nselect * from {{ ref('my_model') }}\\nwhere false\", \"language\": \"sql\", \"refs\": [[\"my_model\"]], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [], \"nodes\": [\"model.test.my_model\"]}, \"compiled_path\": null}, \"seed.test.my_seed\": {\"database\": \"dbt\", \"schema\": \"test16763222812618906995_test_previous_version_state\", \"name\": \"my_seed\", \"resource_type\": \"seed\", \"package_name\": \"test\", \"path\": \"my_seed.csv\", \"original_file_path\": \"seeds/my_seed.csv\", \"unique_id\": \"seed.test.my_seed\", \"fqn\": [\"test\", \"my_seed\"], \"alias\": \"my_seed\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"22697c9b76d73a6c7561554ddb2ce101428ea2737ba8dc500d52ebcfdcfcfc13\"}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"materialized\": \"seed\", \"incremental_strategy\": null, \"persist_docs\": {}, \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": null, \"on_schema_change\": \"ignore\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"quote_columns\": null, \"post-hook\": [], \"pre-hook\": []}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {}, \"created_at\": 1676322282.395373, \"relation_name\": \"\\\"dbt\\\".\\\"test16763222812618906995_test_previous_version_state\\\".\\\"my_seed\\\"\", \"raw_code\": \"\", \"root_path\": \"/private/var/folders/qt/vw8wqdgx4w381wh14b9y25m40000gn/T/pytest-of-gerda/pytest-115/project0\", \"depends_on\": {\"macros\": []}}, \"test.test.not_null_my_model_id.43e0e9183a\": {\"test_metadata\": {\"name\": \"not_null\", \"kwargs\": {\"column_name\": \"id\", \"model\": \"{{ get_where_subquery(ref('my_model')) }}\"}, \"namespace\": null}, \"database\": \"dbt\", \"schema\": \"test16763222812618906995_test_previous_version_state_dbt_test__audit\", \"name\": \"not_null_my_model_id\", \"resource_type\": \"test\", \"package_name\": \"test\", \"path\": \"not_null_my_model_id.sql\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"test.test.not_null_my_model_id.43e0e9183a\", \"fqn\": [\"test\", \"not_null_my_model_id\"], \"alias\": \"not_null_my_model_id\", \"checksum\": {\"name\": \"none\", \"checksum\": \"\"}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": \"dbt_test__audit\", \"database\": null, \"tags\": [], \"meta\": {}, \"materialized\": \"test\", \"severity\": \"ERROR\", \"store_failures\": null, \"where\": null, \"limit\": null, \"fail_calc\": \"count(*)\", \"warn_if\": \"!= 0\", \"error_if\": \"!= 0\"}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {}, \"created_at\": 1676322282.439473, \"relation_name\": null, \"raw_code\": \"{{ test_not_null(**_dbt_generic_test_kwargs) }}\", \"language\": \"sql\", \"refs\": [[\"my_model\"]], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [\"macro.dbt.test_not_null\"], \"nodes\": [\"model.test.my_model\"]}, \"compiled_path\": null, \"column_name\": \"id\", \"file_key_name\": \"models.my_model\"}, \"test.test.check_nothing_my_model_.d5a5e66110\": {\"test_metadata\": {\"name\": \"check_nothing\", \"kwargs\": {\"model\": \"{{ get_where_subquery(ref('my_model')) }}\"}, \"namespace\": null}, \"database\": \"dbt\", \"schema\": \"test16763222812618906995_test_previous_version_state_dbt_test__audit\", \"name\": \"check_nothing_my_model_\", \"resource_type\": \"test\", \"package_name\": \"test\", \"path\": \"check_nothing_my_model_.sql\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"test.test.check_nothing_my_model_.d5a5e66110\", \"fqn\": [\"test\", \"check_nothing_my_model_\"], \"alias\": \"check_nothing_my_model_\", \"checksum\": {\"name\": \"none\", \"checksum\": \"\"}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": \"dbt_test__audit\", \"database\": null, \"tags\": [], \"meta\": {}, \"materialized\": \"test\", \"severity\": \"ERROR\", \"store_failures\": null, \"where\": null, \"limit\": null, \"fail_calc\": \"count(*)\", \"warn_if\": \"!= 0\", \"error_if\": \"!= 0\"}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {}, \"created_at\": 1676322282.4446359, \"relation_name\": null, \"raw_code\": \"{{ test_check_nothing(**_dbt_generic_test_kwargs) }}\", \"language\": \"sql\", \"refs\": [[\"my_model\"]], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [\"macro.test.test_check_nothing\", \"macro.dbt.get_where_subquery\"], \"nodes\": [\"model.test.my_model\"]}, \"compiled_path\": null, \"column_name\": null, \"file_key_name\": \"models.my_model\"}}, \"sources\": {\"source.test.my_source.my_table\": {\"database\": \"dbt\", \"schema\": \"my_source\", \"name\": \"my_table\", \"resource_type\": \"source\", \"package_name\": \"test\", \"path\": \"models/schema.yml\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"source.test.my_source.my_table\", \"fqn\": [\"test\", \"my_source\", \"my_table\"], \"source_name\": \"my_source\", \"source_description\": \"My source\", \"loader\": \"a_loader\", \"identifier\": \"my_seed\", \"quoting\": {\"database\": null, \"schema\": null, \"identifier\": null, \"column\": null}, \"loaded_at_field\": null, \"freshness\": {\"warn_after\": {\"count\": null, \"period\": null}, \"error_after\": {\"count\": null, \"period\": null}, \"filter\": null}, \"external\": null, \"description\": \"My table\", \"columns\": {}, \"meta\": {}, \"source_meta\": {}, \"tags\": [], \"config\": {\"enabled\": true}, \"patch_path\": null, \"unrendered_config\": {}, \"relation_name\": \"\\\"dbt\\\".\\\"my_source\\\".\\\"my_seed\\\"\", \"created_at\": 1676322282.498101}}, \"macros\": {\"macro.test.test_check_nothing\": {\"name\": \"test_check_nothing\", \"resource_type\": \"macro\", \"package_name\": \"test\", \"path\": \"macros/dummy_test.sql\", \"original_file_path\": \"macros/dummy_test.sql\", \"unique_id\": \"macro.test.test_check_nothing\", \"macro_sql\": \"{% test check_nothing(model) %}\\n-- a silly test to make sure that table-level tests show up in the manifest\\n-- without a column_name field\\n\\nselect 0\\n\\n{% endtest %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.4094772, \"supported_languages\": null}, \"macro.test.test_disabled_check_nothing\": {\"name\": \"test_disabled_check_nothing\", \"resource_type\": \"macro\", \"package_name\": \"test\", \"path\": \"macros/disabled_dummy_test.sql\", \"original_file_path\": \"macros/disabled_dummy_test.sql\", \"unique_id\": \"macro.test.test_disabled_check_nothing\", \"macro_sql\": \"{% test disabled_check_nothing(model) %}\\n-- a silly test to make sure that table-level tests show up in the manifest\\n-- without a column_name field\\n\\n{{ config(enabled=False) }}\\nselect 0\\n\\n{% endtest %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.410033, \"supported_languages\": null}, \"macro.test.do_nothing\": {\"name\": \"do_nothing\", \"resource_type\": \"macro\", \"package_name\": \"test\", \"path\": \"macros/do_nothing.sql\", \"original_file_path\": \"macros/do_nothing.sql\", \"unique_id\": \"macro.test.do_nothing\", \"macro_sql\": \"{% macro do_nothing(foo2, bar2) %}\\n    select\\n        '{{ foo2 }}' as foo2,\\n        '{{ bar2 }}' as bar2\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.41051, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__current_timestamp\": {\"name\": \"postgres__current_timestamp\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/timestamps.sql\", \"original_file_path\": \"macros/timestamps.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__current_timestamp\", \"macro_sql\": \"{% macro postgres__current_timestamp() -%}\\n    now()\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.411176, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__snapshot_string_as_time\": {\"name\": \"postgres__snapshot_string_as_time\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/timestamps.sql\", \"original_file_path\": \"macros/timestamps.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__snapshot_string_as_time\", \"macro_sql\": \"{% macro postgres__snapshot_string_as_time(timestamp) -%}\\n    {%- set result = \\\"'\\\" ~ timestamp ~ \\\"'::timestamp without time zone\\\" -%}\\n    {{ return(result) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.411718, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__snapshot_get_time\": {\"name\": \"postgres__snapshot_get_time\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/timestamps.sql\", \"original_file_path\": \"macros/timestamps.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__snapshot_get_time\", \"macro_sql\": \"{% macro postgres__snapshot_get_time() -%}\\n  {{ current_timestamp() }}::timestamp without time zone\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.412009, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__current_timestamp_backcompat\": {\"name\": \"postgres__current_timestamp_backcompat\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/timestamps.sql\", \"original_file_path\": \"macros/timestamps.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__current_timestamp_backcompat\", \"macro_sql\": \"{% macro postgres__current_timestamp_backcompat() %}\\n    current_timestamp::{{ type_timestamp() }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.type_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.41232, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__current_timestamp_in_utc_backcompat\": {\"name\": \"postgres__current_timestamp_in_utc_backcompat\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/timestamps.sql\", \"original_file_path\": \"macros/timestamps.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__current_timestamp_in_utc_backcompat\", \"macro_sql\": \"{% macro postgres__current_timestamp_in_utc_backcompat() %}\\n    (current_timestamp at time zone 'utc')::{{ type_timestamp() }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.type_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.412619, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_catalog\": {\"name\": \"postgres__get_catalog\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/catalog.sql\", \"original_file_path\": \"macros/catalog.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_catalog\", \"macro_sql\": \"{% macro postgres__get_catalog(information_schema, schemas) -%}\\n\\n  {%- call statement('catalog', fetch_result=True) -%}\\n    {#\\n      If the user has multiple databases set and the first one is wrong, this will fail.\\n      But we won't fail in the case where there are multiple quoting-difference-only dbs, which is better.\\n    #}\\n    {% set database = information_schema.database %}\\n    {{ adapter.verify_database(database) }}\\n\\n    select\\n        '{{ database }}' as table_database,\\n        sch.nspname as table_schema,\\n        tbl.relname as table_name,\\n        case tbl.relkind\\n            when 'v' then 'VIEW'\\n            else 'BASE TABLE'\\n        end as table_type,\\n        tbl_desc.description as table_comment,\\n        col.attname as column_name,\\n        col.attnum as column_index,\\n        pg_catalog.format_type(col.atttypid, col.atttypmod) as column_type,\\n        col_desc.description as column_comment,\\n        pg_get_userbyid(tbl.relowner) as table_owner\\n\\n    from pg_catalog.pg_namespace sch\\n    join pg_catalog.pg_class tbl on tbl.relnamespace = sch.oid\\n    join pg_catalog.pg_attribute col on col.attrelid = tbl.oid\\n    left outer join pg_catalog.pg_description tbl_desc on (tbl_desc.objoid = tbl.oid and tbl_desc.objsubid = 0)\\n    left outer join pg_catalog.pg_description col_desc on (col_desc.objoid = tbl.oid and col_desc.objsubid = col.attnum)\\n\\n    where (\\n        {%- for schema in schemas -%}\\n          upper(sch.nspname) = upper('{{ schema }}'){%- if not loop.last %} or {% endif -%}\\n        {%- endfor -%}\\n      )\\n      and not pg_is_other_temp_schema(sch.oid) -- not a temporary schema belonging to another session\\n      and tbl.relpersistence in ('p', 'u') -- [p]ermanent table or [u]nlogged table. Exclude [t]emporary tables\\n      and tbl.relkind in ('r', 'v', 'f', 'p') -- o[r]dinary table, [v]iew, [f]oreign table, [p]artitioned table. Other values are [i]ndex, [S]equence, [c]omposite type, [t]OAST table, [m]aterialized view\\n      and col.attnum > 0 -- negative numbers are used for system columns such as oid\\n      and not col.attisdropped -- column as not been dropped\\n\\n    order by\\n        sch.nspname,\\n        tbl.relname,\\n        col.attnum\\n\\n  {%- endcall -%}\\n\\n  {{ return(load_result('catalog').table) }}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.4152992, \"supported_languages\": null}, \"macro.dbt_postgres.postgres_get_relations\": {\"name\": \"postgres_get_relations\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/relations.sql\", \"original_file_path\": \"macros/relations.sql\", \"unique_id\": \"macro.dbt_postgres.postgres_get_relations\", \"macro_sql\": \"{% macro postgres_get_relations () -%}\\n\\n  {#\\n      -- in pg_depend, objid is the dependent, refobjid is the referenced object\\n      --  > a pg_depend entry indicates that the referenced object cannot be\\n      --  > dropped without also dropping the dependent object.\\n  #}\\n\\n  {%- call statement('relations', fetch_result=True) -%}\\n    with relation as (\\n        select\\n            pg_rewrite.ev_class as class,\\n            pg_rewrite.oid as id\\n        from pg_rewrite\\n    ),\\n    class as (\\n        select\\n            oid as id,\\n            relname as name,\\n            relnamespace as schema,\\n            relkind as kind\\n        from pg_class\\n    ),\\n    dependency as (\\n        select distinct\\n            pg_depend.objid as id,\\n            pg_depend.refobjid as ref\\n        from pg_depend\\n    ),\\n    schema as (\\n        select\\n            pg_namespace.oid as id,\\n            pg_namespace.nspname as name\\n        from pg_namespace\\n        where nspname != 'information_schema' and nspname not like 'pg\\\\_%'\\n    ),\\n    referenced as (\\n        select\\n            relation.id AS id,\\n            referenced_class.name ,\\n            referenced_class.schema ,\\n            referenced_class.kind\\n        from relation\\n        join class as referenced_class on relation.class=referenced_class.id\\n        where referenced_class.kind in ('r', 'v')\\n    ),\\n    relationships as (\\n        select\\n            referenced.name as referenced_name,\\n            referenced.schema as referenced_schema_id,\\n            dependent_class.name as dependent_name,\\n            dependent_class.schema as dependent_schema_id,\\n            referenced.kind as kind\\n        from referenced\\n        join dependency on referenced.id=dependency.id\\n        join class as dependent_class on dependency.ref=dependent_class.id\\n        where\\n            (referenced.name != dependent_class.name or\\n             referenced.schema != dependent_class.schema)\\n    )\\n\\n    select\\n        referenced_schema.name as referenced_schema,\\n        relationships.referenced_name as referenced_name,\\n        dependent_schema.name as dependent_schema,\\n        relationships.dependent_name as dependent_name\\n    from relationships\\n    join schema as dependent_schema on relationships.dependent_schema_id=dependent_schema.id\\n    join schema as referenced_schema on relationships.referenced_schema_id=referenced_schema.id\\n    group by referenced_schema, referenced_name, dependent_schema, dependent_name\\n    order by referenced_schema, referenced_name, dependent_schema, dependent_name;\\n\\n  {%- endcall -%}\\n\\n  {{ return(load_result('relations').table) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.4168088, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__create_table_as\": {\"name\": \"postgres__create_table_as\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__create_table_as\", \"macro_sql\": \"{% macro postgres__create_table_as(temporary, relation, sql) -%}\\n  {%- set unlogged = config.get('unlogged', default=false) -%}\\n  {%- set sql_header = config.get('sql_header', none) -%}\\n\\n  {{ sql_header if sql_header is not none }}\\n\\n  create {% if temporary -%}\\n    temporary\\n  {%- elif unlogged -%}\\n    unlogged\\n  {%- endif %} table {{ relation }}\\n  as (\\n    {{ sql }}\\n  );\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.428651, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_create_index_sql\": {\"name\": \"postgres__get_create_index_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_create_index_sql\", \"macro_sql\": \"{% macro postgres__get_create_index_sql(relation, index_dict) -%}\\n  {%- set index_config = adapter.parse_index(index_dict) -%}\\n  {%- set comma_separated_columns = \\\", \\\".join(index_config.columns) -%}\\n  {%- set index_name = index_config.render(relation) -%}\\n\\n  create {% if index_config.unique -%}\\n    unique\\n  {%- endif %} index if not exists\\n  \\\"{{ index_name }}\\\"\\n  on {{ relation }} {% if index_config.type -%}\\n    using {{ index_config.type }}\\n  {%- endif %}\\n  ({{ comma_separated_columns }});\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.430589, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__create_schema\": {\"name\": \"postgres__create_schema\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__create_schema\", \"macro_sql\": \"{% macro postgres__create_schema(relation) -%}\\n  {% if relation.database -%}\\n    {{ adapter.verify_database(relation.database) }}\\n  {%- endif -%}\\n  {%- call statement('create_schema') -%}\\n    create schema if not exists {{ relation.without_identifier().include(database=False) }}\\n  {%- endcall -%}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.4315221, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__drop_schema\": {\"name\": \"postgres__drop_schema\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__drop_schema\", \"macro_sql\": \"{% macro postgres__drop_schema(relation) -%}\\n  {% if relation.database -%}\\n    {{ adapter.verify_database(relation.database) }}\\n  {%- endif -%}\\n  {%- call statement('drop_schema') -%}\\n    drop schema if exists {{ relation.without_identifier().include(database=False) }} cascade\\n  {%- endcall -%}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.432323, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_columns_in_relation\": {\"name\": \"postgres__get_columns_in_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_columns_in_relation\", \"macro_sql\": \"{% macro postgres__get_columns_in_relation(relation) -%}\\n  {% call statement('get_columns_in_relation', fetch_result=True) %}\\n      select\\n          column_name,\\n          data_type,\\n          character_maximum_length,\\n          numeric_precision,\\n          numeric_scale\\n\\n      from {{ relation.information_schema('columns') }}\\n      where table_name = '{{ relation.identifier }}'\\n        {% if relation.schema %}\\n        and table_schema = '{{ relation.schema }}'\\n        {% endif %}\\n      order by ordinal_position\\n\\n  {% endcall %}\\n  {% set table = load_result('get_columns_in_relation').table %}\\n  {{ return(sql_convert_columns_in_relation(table)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\", \"macro.dbt.sql_convert_columns_in_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.433569, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__list_relations_without_caching\": {\"name\": \"postgres__list_relations_without_caching\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__list_relations_without_caching\", \"macro_sql\": \"{% macro postgres__list_relations_without_caching(schema_relation) %}\\n  {% call statement('list_relations_without_caching', fetch_result=True) -%}\\n    select\\n      '{{ schema_relation.database }}' as database,\\n      tablename as name,\\n      schemaname as schema,\\n      'table' as type\\n    from pg_tables\\n    where schemaname ilike '{{ schema_relation.schema }}'\\n    union all\\n    select\\n      '{{ schema_relation.database }}' as database,\\n      viewname as name,\\n      schemaname as schema,\\n      'view' as type\\n    from pg_views\\n    where schemaname ilike '{{ schema_relation.schema }}'\\n  {% endcall %}\\n  {{ return(load_result('list_relations_without_caching').table) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.434568, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__information_schema_name\": {\"name\": \"postgres__information_schema_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__information_schema_name\", \"macro_sql\": \"{% macro postgres__information_schema_name(database) -%}\\n  {% if database_name -%}\\n    {{ adapter.verify_database(database_name) }}\\n  {%- endif -%}\\n  information_schema\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.4350138, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__list_schemas\": {\"name\": \"postgres__list_schemas\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__list_schemas\", \"macro_sql\": \"{% macro postgres__list_schemas(database) %}\\n  {% if database -%}\\n    {{ adapter.verify_database(database) }}\\n  {%- endif -%}\\n  {% call statement('list_schemas', fetch_result=True, auto_begin=False) %}\\n    select distinct nspname from pg_namespace\\n  {% endcall %}\\n  {{ return(load_result('list_schemas').table) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.435891, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__check_schema_exists\": {\"name\": \"postgres__check_schema_exists\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__check_schema_exists\", \"macro_sql\": \"{% macro postgres__check_schema_exists(information_schema, schema) -%}\\n  {% if information_schema.database -%}\\n    {{ adapter.verify_database(information_schema.database) }}\\n  {%- endif -%}\\n  {% call statement('check_schema_exists', fetch_result=True, auto_begin=False) %}\\n    select count(*) from pg_namespace where nspname = '{{ schema }}'\\n  {% endcall %}\\n  {{ return(load_result('check_schema_exists').table) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.436857, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__make_relation_with_suffix\": {\"name\": \"postgres__make_relation_with_suffix\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__make_relation_with_suffix\", \"macro_sql\": \"{% macro postgres__make_relation_with_suffix(base_relation, suffix, dstring) %}\\n    {% if dstring %}\\n      {% set dt = modules.datetime.datetime.now() %}\\n      {% set dtstring = dt.strftime(\\\"%H%M%S%f\\\") %}\\n      {% set suffix = suffix ~ dtstring %}\\n    {% endif %}\\n    {% set suffix_length = suffix|length %}\\n    {% set relation_max_name_length = base_relation.relation_max_name_length() %}\\n    {% if suffix_length > relation_max_name_length %}\\n        {% do exceptions.raise_compiler_error('Relation suffix is too long (' ~ suffix_length ~ ' characters). Maximum length is ' ~ relation_max_name_length ~ ' characters.') %}\\n    {% endif %}\\n    {% set identifier = base_relation.identifier[:relation_max_name_length - suffix_length] ~ suffix %}\\n\\n    {{ return(base_relation.incorporate(path={\\\"identifier\\\": identifier })) }}\\n\\n  {% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.4389682, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__make_intermediate_relation\": {\"name\": \"postgres__make_intermediate_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__make_intermediate_relation\", \"macro_sql\": \"{% macro postgres__make_intermediate_relation(base_relation, suffix) %}\\n    {{ return(postgres__make_relation_with_suffix(base_relation, suffix, dstring=False)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_relation_with_suffix\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.439469, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__make_temp_relation\": {\"name\": \"postgres__make_temp_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__make_temp_relation\", \"macro_sql\": \"{% macro postgres__make_temp_relation(base_relation, suffix) %}\\n    {% set temp_relation = postgres__make_relation_with_suffix(base_relation, suffix, dstring=True) %}\\n    {{ return(temp_relation.incorporate(path={\\\"schema\\\": none,\\n                                              \\\"database\\\": none})) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_relation_with_suffix\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.4407659, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__make_backup_relation\": {\"name\": \"postgres__make_backup_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__make_backup_relation\", \"macro_sql\": \"{% macro postgres__make_backup_relation(base_relation, backup_relation_type, suffix) %}\\n    {% set backup_relation = postgres__make_relation_with_suffix(base_relation, suffix, dstring=False) %}\\n    {{ return(backup_relation.incorporate(type=backup_relation_type)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_relation_with_suffix\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.441967, \"supported_languages\": null}, \"macro.dbt_postgres.postgres_escape_comment\": {\"name\": \"postgres_escape_comment\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres_escape_comment\", \"macro_sql\": \"{% macro postgres_escape_comment(comment) -%}\\n  {% if comment is not string %}\\n    {% do exceptions.raise_compiler_error('cannot escape a non-string: ' ~ comment) %}\\n  {% endif %}\\n  {%- set magic = '$dbt_comment_literal_block$' -%}\\n  {%- if magic in comment -%}\\n    {%- do exceptions.raise_compiler_error('The string ' ~ magic ~ ' is not allowed in comments.') -%}\\n  {%- endif -%}\\n  {{ magic }}{{ comment }}{{ magic }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.443386, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__alter_relation_comment\": {\"name\": \"postgres__alter_relation_comment\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__alter_relation_comment\", \"macro_sql\": \"{% macro postgres__alter_relation_comment(relation, comment) %}\\n  {% set escaped_comment = postgres_escape_comment(comment) %}\\n  comment on {{ relation.type }} {{ relation }} is {{ escaped_comment }};\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres_escape_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.4441102, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__alter_column_comment\": {\"name\": \"postgres__alter_column_comment\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__alter_column_comment\", \"macro_sql\": \"{% macro postgres__alter_column_comment(relation, column_dict) %}\\n  {% set existing_columns = adapter.get_columns_in_relation(relation) | map(attribute=\\\"name\\\") | list %}\\n  {% for column_name in column_dict if (column_name in existing_columns) %}\\n    {% set comment = column_dict[column_name]['description'] %}\\n    {% set escaped_comment = postgres_escape_comment(comment) %}\\n    comment on column {{ relation }}.{{ adapter.quote(column_name) if column_dict[column_name]['quote'] else column_name }} is {{ escaped_comment }};\\n  {% endfor %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres_escape_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.446302, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_show_grant_sql\": {\"name\": \"postgres__get_show_grant_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_show_grant_sql\", \"macro_sql\": \"\\n\\n{%- macro postgres__get_show_grant_sql(relation) -%}\\n  select grantee, privilege_type\\n  from {{ relation.information_schema('role_table_grants') }}\\n      where grantor = current_role\\n        and grantee != current_role\\n        and table_schema = '{{ relation.schema }}'\\n        and table_name = '{{ relation.identifier }}'\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.4471622, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__copy_grants\": {\"name\": \"postgres__copy_grants\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__copy_grants\", \"macro_sql\": \"{% macro postgres__copy_grants() %}\\n    {{ return(False) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.447847, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_incremental_default_sql\": {\"name\": \"postgres__get_incremental_default_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/materializations/incremental_strategies.sql\", \"original_file_path\": \"macros/materializations/incremental_strategies.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_incremental_default_sql\", \"macro_sql\": \"{% macro postgres__get_incremental_default_sql(arg_dict) %}\\n\\n  {% if arg_dict[\\\"unique_key\\\"] %}\\n    {% do return(get_incremental_delete_insert_sql(arg_dict)) %}\\n  {% else %}\\n    {% do return(get_incremental_append_sql(arg_dict)) %}\\n  {% endif %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_incremental_delete_insert_sql\", \"macro.dbt.get_incremental_append_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.449656, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__snapshot_merge_sql\": {\"name\": \"postgres__snapshot_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/materializations/snapshot_merge.sql\", \"original_file_path\": \"macros/materializations/snapshot_merge.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__snapshot_merge_sql\", \"macro_sql\": \"{% macro postgres__snapshot_merge_sql(target, source, insert_cols) -%}\\n    {%- set insert_cols_csv = insert_cols | join(', ') -%}\\n\\n    update {{ target }}\\n    set dbt_valid_to = DBT_INTERNAL_SOURCE.dbt_valid_to\\n    from {{ source }} as DBT_INTERNAL_SOURCE\\n    where DBT_INTERNAL_SOURCE.dbt_scd_id::text = {{ target }}.dbt_scd_id::text\\n      and DBT_INTERNAL_SOURCE.dbt_change_type::text in ('update'::text, 'delete'::text)\\n      and {{ target }}.dbt_valid_to is null;\\n\\n    insert into {{ target }} ({{ insert_cols_csv }})\\n    select {% for column in insert_cols -%}\\n        DBT_INTERNAL_SOURCE.{{ column }} {%- if not loop.last %}, {%- endif %}\\n    {%- endfor %}\\n    from {{ source }} as DBT_INTERNAL_SOURCE\\n    where DBT_INTERNAL_SOURCE.dbt_change_type::text = 'insert'::text;\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.452299, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__dateadd\": {\"name\": \"postgres__dateadd\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/utils/dateadd.sql\", \"original_file_path\": \"macros/utils/dateadd.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__dateadd\", \"macro_sql\": \"{% macro postgres__dateadd(datepart, interval, from_date_or_timestamp) %}\\n\\n    {{ from_date_or_timestamp }} + ((interval '1 {{ datepart }}') * ({{ interval }}))\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.453088, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__listagg\": {\"name\": \"postgres__listagg\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/utils/listagg.sql\", \"original_file_path\": \"macros/utils/listagg.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__listagg\", \"macro_sql\": \"{% macro postgres__listagg(measure, delimiter_text, order_by_clause, limit_num) -%}\\n\\n    {% if limit_num -%}\\n    array_to_string(\\n        (array_agg(\\n            {{ measure }}\\n            {% if order_by_clause -%}\\n            {{ order_by_clause }}\\n            {%- endif %}\\n        ))[1:{{ limit_num }}],\\n        {{ delimiter_text }}\\n        )\\n    {%- else %}\\n    string_agg(\\n        {{ measure }},\\n        {{ delimiter_text }}\\n        {% if order_by_clause -%}\\n        {{ order_by_clause }}\\n        {%- endif %}\\n        )\\n    {%- endif %}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.455125, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__datediff\": {\"name\": \"postgres__datediff\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/utils/datediff.sql\", \"original_file_path\": \"macros/utils/datediff.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__datediff\", \"macro_sql\": \"{% macro postgres__datediff(first_date, second_date, datepart) -%}\\n\\n    {% if datepart == 'year' %}\\n        (date_part('year', ({{second_date}})::date) - date_part('year', ({{first_date}})::date))\\n    {% elif datepart == 'quarter' %}\\n        ({{ datediff(first_date, second_date, 'year') }} * 4 + date_part('quarter', ({{second_date}})::date) - date_part('quarter', ({{first_date}})::date))\\n    {% elif datepart == 'month' %}\\n        ({{ datediff(first_date, second_date, 'year') }} * 12 + date_part('month', ({{second_date}})::date) - date_part('month', ({{first_date}})::date))\\n    {% elif datepart == 'day' %}\\n        (({{second_date}})::date - ({{first_date}})::date)\\n    {% elif datepart == 'week' %}\\n        ({{ datediff(first_date, second_date, 'day') }} / 7 + case\\n            when date_part('dow', ({{first_date}})::timestamp) <= date_part('dow', ({{second_date}})::timestamp) then\\n                case when {{first_date}} <= {{second_date}} then 0 else -1 end\\n            else\\n                case when {{first_date}} <= {{second_date}} then 1 else 0 end\\n        end)\\n    {% elif datepart == 'hour' %}\\n        ({{ datediff(first_date, second_date, 'day') }} * 24 + date_part('hour', ({{second_date}})::timestamp) - date_part('hour', ({{first_date}})::timestamp))\\n    {% elif datepart == 'minute' %}\\n        ({{ datediff(first_date, second_date, 'hour') }} * 60 + date_part('minute', ({{second_date}})::timestamp) - date_part('minute', ({{first_date}})::timestamp))\\n    {% elif datepart == 'second' %}\\n        ({{ datediff(first_date, second_date, 'minute') }} * 60 + floor(date_part('second', ({{second_date}})::timestamp)) - floor(date_part('second', ({{first_date}})::timestamp)))\\n    {% elif datepart == 'millisecond' %}\\n        ({{ datediff(first_date, second_date, 'minute') }} * 60000 + floor(date_part('millisecond', ({{second_date}})::timestamp)) - floor(date_part('millisecond', ({{first_date}})::timestamp)))\\n    {% elif datepart == 'microsecond' %}\\n        ({{ datediff(first_date, second_date, 'minute') }} * 60000000 + floor(date_part('microsecond', ({{second_date}})::timestamp)) - floor(date_part('microsecond', ({{first_date}})::timestamp)))\\n    {% else %}\\n        {{ exceptions.raise_compiler_error(\\\"Unsupported datepart for macro datediff in postgres: {!r}\\\".format(datepart)) }}\\n    {% endif %}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.datediff\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.462395, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__any_value\": {\"name\": \"postgres__any_value\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/utils/any_value.sql\", \"original_file_path\": \"macros/utils/any_value.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__any_value\", \"macro_sql\": \"{% macro postgres__any_value(expression) -%}\\n\\n    min({{ expression }})\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.463126, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__last_day\": {\"name\": \"postgres__last_day\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/utils/last_day.sql\", \"original_file_path\": \"macros/utils/last_day.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__last_day\", \"macro_sql\": \"{% macro postgres__last_day(date, datepart) -%}\\n\\n    {%- if datepart == 'quarter' -%}\\n    -- postgres dateadd does not support quarter interval.\\n    cast(\\n        {{dbt.dateadd('day', '-1',\\n        dbt.dateadd('month', '3', dbt.date_trunc(datepart, date))\\n        )}}\\n        as date)\\n    {%- else -%}\\n    {{dbt.default_last_day(date, datepart)}}\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.dateadd\", \"macro.dbt.date_trunc\", \"macro.dbt.default_last_day\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.464517, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__split_part\": {\"name\": \"postgres__split_part\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/utils/split_part.sql\", \"original_file_path\": \"macros/utils/split_part.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__split_part\", \"macro_sql\": \"{% macro postgres__split_part(string_text, delimiter_text, part_number) %}\\n\\n  {% if part_number >= 0 %}\\n    {{ dbt.default__split_part(string_text, delimiter_text, part_number) }}\\n  {% else %}\\n    {{ dbt._split_part_negative(string_text, delimiter_text, part_number) }}\\n  {% endif %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__split_part\", \"macro.dbt._split_part_negative\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.4655108, \"supported_languages\": null}, \"macro.dbt.run_hooks\": {\"name\": \"run_hooks\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"unique_id\": \"macro.dbt.run_hooks\", \"macro_sql\": \"{% macro run_hooks(hooks, inside_transaction=True) %}\\n  {% for hook in hooks | selectattr('transaction', 'equalto', inside_transaction)  %}\\n    {% if not inside_transaction and loop.first %}\\n      {% call statement(auto_begin=inside_transaction) %}\\n        commit;\\n      {% endcall %}\\n    {% endif %}\\n    {% set rendered = render(hook.get('sql')) | trim %}\\n    {% if (rendered | length) > 0 %}\\n      {% call statement(auto_begin=inside_transaction) %}\\n        {{ rendered }}\\n      {% endcall %}\\n    {% endif %}\\n  {% endfor %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.468192, \"supported_languages\": null}, \"macro.dbt.make_hook_config\": {\"name\": \"make_hook_config\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"unique_id\": \"macro.dbt.make_hook_config\", \"macro_sql\": \"{% macro make_hook_config(sql, inside_transaction) %}\\n    {{ tojson({\\\"sql\\\": sql, \\\"transaction\\\": inside_transaction}) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.468693, \"supported_languages\": null}, \"macro.dbt.before_begin\": {\"name\": \"before_begin\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"unique_id\": \"macro.dbt.before_begin\", \"macro_sql\": \"{% macro before_begin(sql) %}\\n    {{ make_hook_config(sql, inside_transaction=False) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.make_hook_config\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.469058, \"supported_languages\": null}, \"macro.dbt.in_transaction\": {\"name\": \"in_transaction\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"unique_id\": \"macro.dbt.in_transaction\", \"macro_sql\": \"{% macro in_transaction(sql) %}\\n    {{ make_hook_config(sql, inside_transaction=True) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.make_hook_config\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.4694211, \"supported_languages\": null}, \"macro.dbt.after_commit\": {\"name\": \"after_commit\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"unique_id\": \"macro.dbt.after_commit\", \"macro_sql\": \"{% macro after_commit(sql) %}\\n    {{ make_hook_config(sql, inside_transaction=False) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.make_hook_config\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.469785, \"supported_languages\": null}, \"macro.dbt.set_sql_header\": {\"name\": \"set_sql_header\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/configs.sql\", \"original_file_path\": \"macros/materializations/configs.sql\", \"unique_id\": \"macro.dbt.set_sql_header\", \"macro_sql\": \"{% macro set_sql_header(config) -%}\\n  {{ config.set('sql_header', caller()) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.470596, \"supported_languages\": null}, \"macro.dbt.should_full_refresh\": {\"name\": \"should_full_refresh\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/configs.sql\", \"original_file_path\": \"macros/materializations/configs.sql\", \"unique_id\": \"macro.dbt.should_full_refresh\", \"macro_sql\": \"{% macro should_full_refresh() %}\\n  {% set config_full_refresh = config.get('full_refresh') %}\\n  {% if config_full_refresh is none %}\\n    {% set config_full_refresh = flags.FULL_REFRESH %}\\n  {% endif %}\\n  {% do return(config_full_refresh) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.471361, \"supported_languages\": null}, \"macro.dbt.should_store_failures\": {\"name\": \"should_store_failures\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/configs.sql\", \"original_file_path\": \"macros/materializations/configs.sql\", \"unique_id\": \"macro.dbt.should_store_failures\", \"macro_sql\": \"{% macro should_store_failures() %}\\n  {% set config_store_failures = config.get('store_failures') %}\\n  {% if config_store_failures is none %}\\n    {% set config_store_failures = flags.STORE_FAILURES %}\\n  {% endif %}\\n  {% do return(config_store_failures) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.472131, \"supported_languages\": null}, \"macro.dbt.snapshot_merge_sql\": {\"name\": \"snapshot_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/snapshot_merge.sql\", \"original_file_path\": \"macros/materializations/snapshots/snapshot_merge.sql\", \"unique_id\": \"macro.dbt.snapshot_merge_sql\", \"macro_sql\": \"{% macro snapshot_merge_sql(target, source, insert_cols) -%}\\n  {{ adapter.dispatch('snapshot_merge_sql', 'dbt')(target, source, insert_cols) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__snapshot_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.473068, \"supported_languages\": null}, \"macro.dbt.default__snapshot_merge_sql\": {\"name\": \"default__snapshot_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/snapshot_merge.sql\", \"original_file_path\": \"macros/materializations/snapshots/snapshot_merge.sql\", \"unique_id\": \"macro.dbt.default__snapshot_merge_sql\", \"macro_sql\": \"{% macro default__snapshot_merge_sql(target, source, insert_cols) -%}\\n    {%- set insert_cols_csv = insert_cols | join(', ') -%}\\n\\n    merge into {{ target }} as DBT_INTERNAL_DEST\\n    using {{ source }} as DBT_INTERNAL_SOURCE\\n    on DBT_INTERNAL_SOURCE.dbt_scd_id = DBT_INTERNAL_DEST.dbt_scd_id\\n\\n    when matched\\n     and DBT_INTERNAL_DEST.dbt_valid_to is null\\n     and DBT_INTERNAL_SOURCE.dbt_change_type in ('update', 'delete')\\n        then update\\n        set dbt_valid_to = DBT_INTERNAL_SOURCE.dbt_valid_to\\n\\n    when not matched\\n     and DBT_INTERNAL_SOURCE.dbt_change_type = 'insert'\\n        then insert ({{ insert_cols_csv }})\\n        values ({{ insert_cols_csv }})\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.4737349, \"supported_languages\": null}, \"macro.dbt.strategy_dispatch\": {\"name\": \"strategy_dispatch\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"unique_id\": \"macro.dbt.strategy_dispatch\", \"macro_sql\": \"{% macro strategy_dispatch(name) -%}\\n{% set original_name = name %}\\n  {% if '.' in name %}\\n    {% set package_name, name = name.split(\\\".\\\", 1) %}\\n  {% else %}\\n    {% set package_name = none %}\\n  {% endif %}\\n\\n  {% if package_name is none %}\\n    {% set package_context = context %}\\n  {% elif package_name in context %}\\n    {% set package_context = context[package_name] %}\\n  {% else %}\\n    {% set error_msg %}\\n        Could not find package '{{package_name}}', called with '{{original_name}}'\\n    {% endset %}\\n    {{ exceptions.raise_compiler_error(error_msg | trim) }}\\n  {% endif %}\\n\\n  {%- set search_name = 'snapshot_' ~ name ~ '_strategy' -%}\\n\\n  {% if search_name not in package_context %}\\n    {% set error_msg %}\\n        The specified strategy macro '{{name}}' was not found in package '{{ package_name }}'\\n    {% endset %}\\n    {{ exceptions.raise_compiler_error(error_msg | trim) }}\\n  {% endif %}\\n  {{ return(package_context[search_name]) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.481837, \"supported_languages\": null}, \"macro.dbt.snapshot_hash_arguments\": {\"name\": \"snapshot_hash_arguments\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"unique_id\": \"macro.dbt.snapshot_hash_arguments\", \"macro_sql\": \"{% macro snapshot_hash_arguments(args) -%}\\n  {{ adapter.dispatch('snapshot_hash_arguments', 'dbt')(args) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__snapshot_hash_arguments\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.4828649, \"supported_languages\": null}, \"macro.dbt.default__snapshot_hash_arguments\": {\"name\": \"default__snapshot_hash_arguments\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"unique_id\": \"macro.dbt.default__snapshot_hash_arguments\", \"macro_sql\": \"{% macro default__snapshot_hash_arguments(args) -%}\\n    md5({%- for arg in args -%}\\n        coalesce(cast({{ arg }} as varchar ), '')\\n        {% if not loop.last %} || '|' || {% endif %}\\n    {%- endfor -%})\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.4835358, \"supported_languages\": null}, \"macro.dbt.snapshot_timestamp_strategy\": {\"name\": \"snapshot_timestamp_strategy\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"unique_id\": \"macro.dbt.snapshot_timestamp_strategy\", \"macro_sql\": \"{% macro snapshot_timestamp_strategy(node, snapshotted_rel, current_rel, config, target_exists) %}\\n    {% set primary_key = config['unique_key'] %}\\n    {% set updated_at = config['updated_at'] %}\\n    {% set invalidate_hard_deletes = config.get('invalidate_hard_deletes', false) %}\\n\\n    {#/*\\n        The snapshot relation might not have an {{ updated_at }} value if the\\n        snapshot strategy is changed from `check` to `timestamp`. We\\n        should use a dbt-created column for the comparison in the snapshot\\n        table instead of assuming that the user-supplied {{ updated_at }}\\n        will be present in the historical data.\\n\\n        See https://github.com/dbt-labs/dbt-core/issues/2350\\n    */ #}\\n    {% set row_changed_expr -%}\\n        ({{ snapshotted_rel }}.dbt_valid_from < {{ current_rel }}.{{ updated_at }})\\n    {%- endset %}\\n\\n    {% set scd_id_expr = snapshot_hash_arguments([primary_key, updated_at]) %}\\n\\n    {% do return({\\n        \\\"unique_key\\\": primary_key,\\n        \\\"updated_at\\\": updated_at,\\n        \\\"row_changed\\\": row_changed_expr,\\n        \\\"scd_id\\\": scd_id_expr,\\n        \\\"invalidate_hard_deletes\\\": invalidate_hard_deletes\\n    }) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.snapshot_hash_arguments\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.4857202, \"supported_languages\": null}, \"macro.dbt.snapshot_string_as_time\": {\"name\": \"snapshot_string_as_time\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"unique_id\": \"macro.dbt.snapshot_string_as_time\", \"macro_sql\": \"{% macro snapshot_string_as_time(timestamp) -%}\\n    {{ adapter.dispatch('snapshot_string_as_time', 'dbt')(timestamp) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__snapshot_string_as_time\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.4861922, \"supported_languages\": null}, \"macro.dbt.default__snapshot_string_as_time\": {\"name\": \"default__snapshot_string_as_time\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"unique_id\": \"macro.dbt.default__snapshot_string_as_time\", \"macro_sql\": \"{% macro default__snapshot_string_as_time(timestamp) %}\\n    {% do exceptions.raise_not_implemented(\\n        'snapshot_string_as_time macro not implemented for adapter '+adapter.type()\\n    ) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.486644, \"supported_languages\": null}, \"macro.dbt.snapshot_check_all_get_existing_columns\": {\"name\": \"snapshot_check_all_get_existing_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"unique_id\": \"macro.dbt.snapshot_check_all_get_existing_columns\", \"macro_sql\": \"{% macro snapshot_check_all_get_existing_columns(node, target_exists, check_cols_config) -%}\\n    {%- if not target_exists -%}\\n        {#-- no table yet -> return whatever the query does --#}\\n        {{ return((false, query_columns)) }}\\n    {%- endif -%}\\n\\n    {#-- handle any schema changes --#}\\n    {%- set target_relation = adapter.get_relation(database=node.database, schema=node.schema, identifier=node.alias) -%}\\n\\n    {% if check_cols_config == 'all' %}\\n        {%- set query_columns = get_columns_in_query(node['compiled_code']) -%}\\n\\n    {% elif check_cols_config is iterable and (check_cols_config | length) > 0 %}\\n        {#-- query for proper casing/quoting, to support comparison below --#}\\n        {%- set select_check_cols_from_target -%}\\n          select {{ check_cols_config | join(', ') }} from ({{ node['compiled_code'] }}) subq\\n        {%- endset -%}\\n        {% set query_columns = get_columns_in_query(select_check_cols_from_target) %}\\n\\n    {% else %}\\n        {% do exceptions.raise_compiler_error(\\\"Invalid value for 'check_cols': \\\" ~ check_cols_config) %}\\n    {% endif %}\\n\\n    {%- set existing_cols = adapter.get_columns_in_relation(target_relation) | map(attribute = 'name') | list -%}\\n    {%- set ns = namespace() -%} {#-- handle for-loop scoping with a namespace --#}\\n    {%- set ns.column_added = false -%}\\n\\n    {%- set intersection = [] -%}\\n    {%- for col in query_columns -%}\\n        {%- if col in existing_cols -%}\\n            {%- do intersection.append(adapter.quote(col)) -%}\\n        {%- else -%}\\n            {% set ns.column_added = true %}\\n        {%- endif -%}\\n    {%- endfor -%}\\n    {{ return((ns.column_added, intersection)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_columns_in_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.490088, \"supported_languages\": null}, \"macro.dbt.snapshot_check_strategy\": {\"name\": \"snapshot_check_strategy\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"unique_id\": \"macro.dbt.snapshot_check_strategy\", \"macro_sql\": \"{% macro snapshot_check_strategy(node, snapshotted_rel, current_rel, config, target_exists) %}\\n    {% set check_cols_config = config['check_cols'] %}\\n    {% set primary_key = config['unique_key'] %}\\n    {% set invalidate_hard_deletes = config.get('invalidate_hard_deletes', false) %}\\n    {% set updated_at = config.get('updated_at', snapshot_get_time()) %}\\n\\n    {% set column_added = false %}\\n\\n    {% set column_added, check_cols = snapshot_check_all_get_existing_columns(node, target_exists, check_cols_config) %}\\n\\n    {%- set row_changed_expr -%}\\n    (\\n    {%- if column_added -%}\\n        {{ get_true_sql() }}\\n    {%- else -%}\\n    {%- for col in check_cols -%}\\n        {{ snapshotted_rel }}.{{ col }} != {{ current_rel }}.{{ col }}\\n        or\\n        (\\n            (({{ snapshotted_rel }}.{{ col }} is null) and not ({{ current_rel }}.{{ col }} is null))\\n            or\\n            ((not {{ snapshotted_rel }}.{{ col }} is null) and ({{ current_rel }}.{{ col }} is null))\\n        )\\n        {%- if not loop.last %} or {% endif -%}\\n    {%- endfor -%}\\n    {%- endif -%}\\n    )\\n    {%- endset %}\\n\\n    {% set scd_id_expr = snapshot_hash_arguments([primary_key, updated_at]) %}\\n\\n    {% do return({\\n        \\\"unique_key\\\": primary_key,\\n        \\\"updated_at\\\": updated_at,\\n        \\\"row_changed\\\": row_changed_expr,\\n        \\\"scd_id\\\": scd_id_expr,\\n        \\\"invalidate_hard_deletes\\\": invalidate_hard_deletes\\n    }) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.snapshot_get_time\", \"macro.dbt.snapshot_check_all_get_existing_columns\", \"macro.dbt.get_true_sql\", \"macro.dbt.snapshot_hash_arguments\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.4935129, \"supported_languages\": null}, \"macro.dbt.create_columns\": {\"name\": \"create_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.create_columns\", \"macro_sql\": \"{% macro create_columns(relation, columns) %}\\n  {{ adapter.dispatch('create_columns', 'dbt')(relation, columns) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__create_columns\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.5012, \"supported_languages\": null}, \"macro.dbt.default__create_columns\": {\"name\": \"default__create_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.default__create_columns\", \"macro_sql\": \"{% macro default__create_columns(relation, columns) %}\\n  {% for column in columns %}\\n    {% call statement() %}\\n      alter table {{ relation }} add column \\\"{{ column.name }}\\\" {{ column.data_type }};\\n    {% endcall %}\\n  {% endfor %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.501941, \"supported_languages\": null}, \"macro.dbt.post_snapshot\": {\"name\": \"post_snapshot\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.post_snapshot\", \"macro_sql\": \"{% macro post_snapshot(staging_relation) %}\\n  {{ adapter.dispatch('post_snapshot', 'dbt')(staging_relation) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__post_snapshot\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.502363, \"supported_languages\": null}, \"macro.dbt.default__post_snapshot\": {\"name\": \"default__post_snapshot\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.default__post_snapshot\", \"macro_sql\": \"{% macro default__post_snapshot(staging_relation) %}\\n    {# no-op #}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.5025961, \"supported_languages\": null}, \"macro.dbt.get_true_sql\": {\"name\": \"get_true_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.get_true_sql\", \"macro_sql\": \"{% macro get_true_sql() %}\\n  {{ adapter.dispatch('get_true_sql', 'dbt')() }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_true_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.502961, \"supported_languages\": null}, \"macro.dbt.default__get_true_sql\": {\"name\": \"default__get_true_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.default__get_true_sql\", \"macro_sql\": \"{% macro default__get_true_sql() %}\\n    {{ return('TRUE') }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.5032582, \"supported_languages\": null}, \"macro.dbt.snapshot_staging_table\": {\"name\": \"snapshot_staging_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.snapshot_staging_table\", \"macro_sql\": \"{% macro snapshot_staging_table(strategy, source_sql, target_relation) -%}\\n  {{ adapter.dispatch('snapshot_staging_table', 'dbt')(strategy, source_sql, target_relation) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__snapshot_staging_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.50385, \"supported_languages\": null}, \"macro.dbt.default__snapshot_staging_table\": {\"name\": \"default__snapshot_staging_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.default__snapshot_staging_table\", \"macro_sql\": \"{% macro default__snapshot_staging_table(strategy, source_sql, target_relation) -%}\\n\\n    with snapshot_query as (\\n\\n        {{ source_sql }}\\n\\n    ),\\n\\n    snapshotted_data as (\\n\\n        select *,\\n            {{ strategy.unique_key }} as dbt_unique_key\\n\\n        from {{ target_relation }}\\n        where dbt_valid_to is null\\n\\n    ),\\n\\n    insertions_source_data as (\\n\\n        select\\n            *,\\n            {{ strategy.unique_key }} as dbt_unique_key,\\n            {{ strategy.updated_at }} as dbt_updated_at,\\n            {{ strategy.updated_at }} as dbt_valid_from,\\n            nullif({{ strategy.updated_at }}, {{ strategy.updated_at }}) as dbt_valid_to,\\n            {{ strategy.scd_id }} as dbt_scd_id\\n\\n        from snapshot_query\\n    ),\\n\\n    updates_source_data as (\\n\\n        select\\n            *,\\n            {{ strategy.unique_key }} as dbt_unique_key,\\n            {{ strategy.updated_at }} as dbt_updated_at,\\n            {{ strategy.updated_at }} as dbt_valid_from,\\n            {{ strategy.updated_at }} as dbt_valid_to\\n\\n        from snapshot_query\\n    ),\\n\\n    {%- if strategy.invalidate_hard_deletes %}\\n\\n    deletes_source_data as (\\n\\n        select\\n            *,\\n            {{ strategy.unique_key }} as dbt_unique_key\\n        from snapshot_query\\n    ),\\n    {% endif %}\\n\\n    insertions as (\\n\\n        select\\n            'insert' as dbt_change_type,\\n            source_data.*\\n\\n        from insertions_source_data as source_data\\n        left outer join snapshotted_data on snapshotted_data.dbt_unique_key = source_data.dbt_unique_key\\n        where snapshotted_data.dbt_unique_key is null\\n           or (\\n                snapshotted_data.dbt_unique_key is not null\\n            and (\\n                {{ strategy.row_changed }}\\n            )\\n        )\\n\\n    ),\\n\\n    updates as (\\n\\n        select\\n            'update' as dbt_change_type,\\n            source_data.*,\\n            snapshotted_data.dbt_scd_id\\n\\n        from updates_source_data as source_data\\n        join snapshotted_data on snapshotted_data.dbt_unique_key = source_data.dbt_unique_key\\n        where (\\n            {{ strategy.row_changed }}\\n        )\\n    )\\n\\n    {%- if strategy.invalidate_hard_deletes -%}\\n    ,\\n\\n    deletes as (\\n\\n        select\\n            'delete' as dbt_change_type,\\n            source_data.*,\\n            {{ snapshot_get_time() }} as dbt_valid_from,\\n            {{ snapshot_get_time() }} as dbt_updated_at,\\n            {{ snapshot_get_time() }} as dbt_valid_to,\\n            snapshotted_data.dbt_scd_id\\n\\n        from snapshotted_data\\n        left join deletes_source_data as source_data on snapshotted_data.dbt_unique_key = source_data.dbt_unique_key\\n        where source_data.dbt_unique_key is null\\n    )\\n    {%- endif %}\\n\\n    select * from insertions\\n    union all\\n    select * from updates\\n    {%- if strategy.invalidate_hard_deletes %}\\n    union all\\n    select * from deletes\\n    {%- endif %}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.snapshot_get_time\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.5059588, \"supported_languages\": null}, \"macro.dbt.build_snapshot_table\": {\"name\": \"build_snapshot_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.build_snapshot_table\", \"macro_sql\": \"{% macro build_snapshot_table(strategy, sql) -%}\\n  {{ adapter.dispatch('build_snapshot_table', 'dbt')(strategy, sql) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__build_snapshot_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.5064478, \"supported_languages\": null}, \"macro.dbt.default__build_snapshot_table\": {\"name\": \"default__build_snapshot_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.default__build_snapshot_table\", \"macro_sql\": \"{% macro default__build_snapshot_table(strategy, sql) %}\\n\\n    select *,\\n        {{ strategy.scd_id }} as dbt_scd_id,\\n        {{ strategy.updated_at }} as dbt_updated_at,\\n        {{ strategy.updated_at }} as dbt_valid_from,\\n        nullif({{ strategy.updated_at }}, {{ strategy.updated_at }}) as dbt_valid_to\\n    from (\\n        {{ sql }}\\n    ) sbq\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.5070798, \"supported_languages\": null}, \"macro.dbt.build_snapshot_staging_table\": {\"name\": \"build_snapshot_staging_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.build_snapshot_staging_table\", \"macro_sql\": \"{% macro build_snapshot_staging_table(strategy, sql, target_relation) %}\\n    {% set temp_relation = make_temp_relation(target_relation) %}\\n\\n    {% set select = snapshot_staging_table(strategy, sql, target_relation) %}\\n\\n    {% call statement('build_snapshot_staging_relation') %}\\n        {{ create_table_as(True, temp_relation, select) }}\\n    {% endcall %}\\n\\n    {% do return(temp_relation) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.make_temp_relation\", \"macro.dbt.snapshot_staging_table\", \"macro.dbt.statement\", \"macro.dbt.create_table_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.508459, \"supported_languages\": null}, \"macro.dbt.materialization_snapshot_default\": {\"name\": \"materialization_snapshot_default\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/snapshot.sql\", \"original_file_path\": \"macros/materializations/snapshots/snapshot.sql\", \"unique_id\": \"macro.dbt.materialization_snapshot_default\", \"macro_sql\": \"{% materialization snapshot, default %}\\n  {%- set config = model['config'] -%}\\n\\n  {%- set target_table = model.get('alias', model.get('name')) -%}\\n\\n  {%- set strategy_name = config.get('strategy') -%}\\n  {%- set unique_key = config.get('unique_key') %}\\n  -- grab current tables grants config for comparision later on\\n  {%- set grant_config = config.get('grants') -%}\\n\\n  {% set target_relation_exists, target_relation = get_or_create_relation(\\n          database=model.database,\\n          schema=model.schema,\\n          identifier=target_table,\\n          type='table') -%}\\n\\n  {%- if not target_relation.is_table -%}\\n    {% do exceptions.relation_wrong_type(target_relation, 'table') %}\\n  {%- endif -%}\\n\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  {% set strategy_macro = strategy_dispatch(strategy_name) %}\\n  {% set strategy = strategy_macro(model, \\\"snapshotted_data\\\", \\\"source_data\\\", config, target_relation_exists) %}\\n\\n  {% if not target_relation_exists %}\\n\\n      {% set build_sql = build_snapshot_table(strategy, model['compiled_code']) %}\\n      {% set final_sql = create_table_as(False, target_relation, build_sql) %}\\n\\n  {% else %}\\n\\n      {{ adapter.valid_snapshot_target(target_relation) }}\\n\\n      {% set staging_table = build_snapshot_staging_table(strategy, sql, target_relation) %}\\n\\n      -- this may no-op if the database does not require column expansion\\n      {% do adapter.expand_target_column_types(from_relation=staging_table,\\n                                               to_relation=target_relation) %}\\n\\n      {% set missing_columns = adapter.get_missing_columns(staging_table, target_relation)\\n                                   | rejectattr('name', 'equalto', 'dbt_change_type')\\n                                   | rejectattr('name', 'equalto', 'DBT_CHANGE_TYPE')\\n                                   | rejectattr('name', 'equalto', 'dbt_unique_key')\\n                                   | rejectattr('name', 'equalto', 'DBT_UNIQUE_KEY')\\n                                   | list %}\\n\\n      {% do create_columns(target_relation, missing_columns) %}\\n\\n      {% set source_columns = adapter.get_columns_in_relation(staging_table)\\n                                   | rejectattr('name', 'equalto', 'dbt_change_type')\\n                                   | rejectattr('name', 'equalto', 'DBT_CHANGE_TYPE')\\n                                   | rejectattr('name', 'equalto', 'dbt_unique_key')\\n                                   | rejectattr('name', 'equalto', 'DBT_UNIQUE_KEY')\\n                                   | list %}\\n\\n      {% set quoted_source_columns = [] %}\\n      {% for column in source_columns %}\\n        {% do quoted_source_columns.append(adapter.quote(column.name)) %}\\n      {% endfor %}\\n\\n      {% set final_sql = snapshot_merge_sql(\\n            target = target_relation,\\n            source = staging_table,\\n            insert_cols = quoted_source_columns\\n         )\\n      %}\\n\\n  {% endif %}\\n\\n  {% call statement('main') %}\\n      {{ final_sql }}\\n  {% endcall %}\\n\\n  {% set should_revoke = should_revoke(target_relation_exists, full_refresh_mode=False) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {% if not target_relation_exists %}\\n    {% do create_indexes(target_relation) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  {{ adapter.commit() }}\\n\\n  {% if staging_table is defined %}\\n      {% do post_snapshot(staging_table) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{% endmaterialization %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_or_create_relation\", \"macro.dbt.run_hooks\", \"macro.dbt.strategy_dispatch\", \"macro.dbt.build_snapshot_table\", \"macro.dbt.create_table_as\", \"macro.dbt.build_snapshot_staging_table\", \"macro.dbt.create_columns\", \"macro.dbt.snapshot_merge_sql\", \"macro.dbt.statement\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\", \"macro.dbt.persist_docs\", \"macro.dbt.create_indexes\", \"macro.dbt.post_snapshot\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.523073, \"supported_languages\": [\"sql\"]}, \"macro.dbt.materialization_test_default\": {\"name\": \"materialization_test_default\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/tests/test.sql\", \"original_file_path\": \"macros/materializations/tests/test.sql\", \"unique_id\": \"macro.dbt.materialization_test_default\", \"macro_sql\": \"{%- materialization test, default -%}\\n\\n  {% set relations = [] %}\\n\\n  {% if should_store_failures() %}\\n\\n    {% set identifier = model['alias'] %}\\n    {% set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) %}\\n    {% set target_relation = api.Relation.create(\\n        identifier=identifier, schema=schema, database=database, type='table') -%} %}\\n\\n    {% if old_relation %}\\n        {% do adapter.drop_relation(old_relation) %}\\n    {% endif %}\\n\\n    {% call statement(auto_begin=True) %}\\n        {{ create_table_as(False, target_relation, sql) }}\\n    {% endcall %}\\n\\n    {% do relations.append(target_relation) %}\\n\\n    {% set main_sql %}\\n        select *\\n        from {{ target_relation }}\\n    {% endset %}\\n\\n    {{ adapter.commit() }}\\n\\n  {% else %}\\n\\n      {% set main_sql = sql %}\\n\\n  {% endif %}\\n\\n  {% set limit = config.get('limit') %}\\n  {% set fail_calc = config.get('fail_calc') %}\\n  {% set warn_if = config.get('warn_if') %}\\n  {% set error_if = config.get('error_if') %}\\n\\n  {% call statement('main', fetch_result=True) -%}\\n\\n    {{ get_test_sql(main_sql, fail_calc, warn_if, error_if, limit)}}\\n\\n  {%- endcall %}\\n\\n  {{ return({'relations': relations}) }}\\n\\n{%- endmaterialization -%}\", \"depends_on\": {\"macros\": [\"macro.dbt.should_store_failures\", \"macro.dbt.statement\", \"macro.dbt.create_table_as\", \"macro.dbt.get_test_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.528616, \"supported_languages\": [\"sql\"]}, \"macro.dbt.get_test_sql\": {\"name\": \"get_test_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/tests/helpers.sql\", \"original_file_path\": \"macros/materializations/tests/helpers.sql\", \"unique_id\": \"macro.dbt.get_test_sql\", \"macro_sql\": \"{% macro get_test_sql(main_sql, fail_calc, warn_if, error_if, limit) -%}\\n  {{ adapter.dispatch('get_test_sql', 'dbt')(main_sql, fail_calc, warn_if, error_if, limit) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_test_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.52976, \"supported_languages\": null}, \"macro.dbt.default__get_test_sql\": {\"name\": \"default__get_test_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/tests/helpers.sql\", \"original_file_path\": \"macros/materializations/tests/helpers.sql\", \"unique_id\": \"macro.dbt.default__get_test_sql\", \"macro_sql\": \"{% macro default__get_test_sql(main_sql, fail_calc, warn_if, error_if, limit) -%}\\n    select\\n      {{ fail_calc }} as failures,\\n      {{ fail_calc }} {{ warn_if }} as should_warn,\\n      {{ fail_calc }} {{ error_if }} as should_error\\n    from (\\n      {{ main_sql }}\\n      {{ \\\"limit \\\" ~ limit if limit != none }}\\n    ) dbt_internal_test\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.531104, \"supported_languages\": null}, \"macro.dbt.get_where_subquery\": {\"name\": \"get_where_subquery\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/tests/where_subquery.sql\", \"original_file_path\": \"macros/materializations/tests/where_subquery.sql\", \"unique_id\": \"macro.dbt.get_where_subquery\", \"macro_sql\": \"{% macro get_where_subquery(relation) -%}\\n    {% do return(adapter.dispatch('get_where_subquery', 'dbt')(relation)) %}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_where_subquery\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.5320342, \"supported_languages\": null}, \"macro.dbt.default__get_where_subquery\": {\"name\": \"default__get_where_subquery\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/tests/where_subquery.sql\", \"original_file_path\": \"macros/materializations/tests/where_subquery.sql\", \"unique_id\": \"macro.dbt.default__get_where_subquery\", \"macro_sql\": \"{% macro default__get_where_subquery(relation) -%}\\n    {% set where = config.get('where', '') %}\\n    {% if where %}\\n        {%- set filtered -%}\\n            (select * from {{ relation }} where {{ where }}) dbt_subquery\\n        {%- endset -%}\\n        {% do return(filtered) %}\\n    {%- else -%}\\n        {% do return(relation) %}\\n    {%- endif -%}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.533005, \"supported_languages\": null}, \"macro.dbt.get_quoted_csv\": {\"name\": \"get_quoted_csv\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"unique_id\": \"macro.dbt.get_quoted_csv\", \"macro_sql\": \"{% macro get_quoted_csv(column_names) %}\\n\\n    {% set quoted = [] %}\\n    {% for col in column_names -%}\\n        {%- do quoted.append(adapter.quote(col)) -%}\\n    {%- endfor %}\\n\\n    {%- set dest_cols_csv = quoted | join(', ') -%}\\n    {{ return(dest_cols_csv) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.536449, \"supported_languages\": null}, \"macro.dbt.diff_columns\": {\"name\": \"diff_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"unique_id\": \"macro.dbt.diff_columns\", \"macro_sql\": \"{% macro diff_columns(source_columns, target_columns) %}\\n\\n  {% set result = [] %}\\n  {% set source_names = source_columns | map(attribute = 'column') | list %}\\n  {% set target_names = target_columns | map(attribute = 'column') | list %}\\n\\n   {# --check whether the name attribute exists in the target - this does not perform a data type check #}\\n   {% for sc in source_columns %}\\n     {% if sc.name not in target_names %}\\n        {{ result.append(sc) }}\\n     {% endif %}\\n   {% endfor %}\\n\\n  {{ return(result) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.537867, \"supported_languages\": null}, \"macro.dbt.diff_column_data_types\": {\"name\": \"diff_column_data_types\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"unique_id\": \"macro.dbt.diff_column_data_types\", \"macro_sql\": \"{% macro diff_column_data_types(source_columns, target_columns) %}\\n\\n  {% set result = [] %}\\n  {% for sc in source_columns %}\\n    {% set tc = target_columns | selectattr(\\\"name\\\", \\\"equalto\\\", sc.name) | list | first %}\\n    {% if tc %}\\n      {% if sc.data_type != tc.data_type and not sc.can_expand_to(other_column=tc) %}\\n        {{ result.append( { 'column_name': tc.name, 'new_type': sc.data_type } ) }}\\n      {% endif %}\\n    {% endif %}\\n  {% endfor %}\\n\\n  {{ return(result) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.539545, \"supported_languages\": null}, \"macro.dbt.get_merge_update_columns\": {\"name\": \"get_merge_update_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"unique_id\": \"macro.dbt.get_merge_update_columns\", \"macro_sql\": \"{% macro get_merge_update_columns(merge_update_columns, merge_exclude_columns, dest_columns) %}\\n  {{ return(adapter.dispatch('get_merge_update_columns', 'dbt')(merge_update_columns, merge_exclude_columns, dest_columns)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_merge_update_columns\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.5401359, \"supported_languages\": null}, \"macro.dbt.default__get_merge_update_columns\": {\"name\": \"default__get_merge_update_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"unique_id\": \"macro.dbt.default__get_merge_update_columns\", \"macro_sql\": \"{% macro default__get_merge_update_columns(merge_update_columns, merge_exclude_columns, dest_columns) %}\\n  {%- set default_cols = dest_columns | map(attribute=\\\"quoted\\\") | list -%}\\n\\n  {%- if merge_update_columns and merge_exclude_columns -%}\\n    {{ exceptions.raise_compiler_error(\\n        'Model cannot specify merge_update_columns and merge_exclude_columns. Please update model to use only one config'\\n    )}}\\n  {%- elif merge_update_columns -%}\\n    {%- set update_columns = merge_update_columns -%}\\n  {%- elif merge_exclude_columns -%}\\n    {%- set update_columns = [] -%}\\n    {%- for column in dest_columns -%}\\n      {% if column.column | lower not in merge_exclude_columns | map(\\\"lower\\\") | list %}\\n        {%- do update_columns.append(column.quoted) -%}\\n      {% endif %}\\n    {%- endfor -%}\\n  {%- else -%}\\n    {%- set update_columns = default_cols -%}\\n  {%- endif -%}\\n\\n  {{ return(update_columns) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.5423229, \"supported_languages\": null}, \"macro.dbt.get_merge_sql\": {\"name\": \"get_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"unique_id\": \"macro.dbt.get_merge_sql\", \"macro_sql\": \"{% macro get_merge_sql(target, source, unique_key, dest_columns, incremental_predicates=none) -%}\\n   -- back compat for old kwarg name\\n  {% set incremental_predicates = kwargs.get('predicates', incremental_predicates) %}\\n  {{ adapter.dispatch('get_merge_sql', 'dbt')(target, source, unique_key, dest_columns, incremental_predicates) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.554441, \"supported_languages\": null}, \"macro.dbt.default__get_merge_sql\": {\"name\": \"default__get_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"unique_id\": \"macro.dbt.default__get_merge_sql\", \"macro_sql\": \"{% macro default__get_merge_sql(target, source, unique_key, dest_columns, incremental_predicates=none) -%}\\n    {%- set predicates = [] if incremental_predicates is none else [] + incremental_predicates -%}\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n    {%- set merge_update_columns = config.get('merge_update_columns') -%}\\n    {%- set merge_exclude_columns = config.get('merge_exclude_columns') -%}\\n    {%- set update_columns = get_merge_update_columns(merge_update_columns, merge_exclude_columns, dest_columns) -%}\\n    {%- set sql_header = config.get('sql_header', none) -%}\\n\\n    {% if unique_key %}\\n        {% if unique_key is sequence and unique_key is not mapping and unique_key is not string %}\\n            {% for key in unique_key %}\\n                {% set this_key_match %}\\n                    DBT_INTERNAL_SOURCE.{{ key }} = DBT_INTERNAL_DEST.{{ key }}\\n                {% endset %}\\n                {% do predicates.append(this_key_match) %}\\n            {% endfor %}\\n        {% else %}\\n            {% set unique_key_match %}\\n                DBT_INTERNAL_SOURCE.{{ unique_key }} = DBT_INTERNAL_DEST.{{ unique_key }}\\n            {% endset %}\\n            {% do predicates.append(unique_key_match) %}\\n        {% endif %}\\n    {% else %}\\n        {% do predicates.append('FALSE') %}\\n    {% endif %}\\n\\n    {{ sql_header if sql_header is not none }}\\n\\n    merge into {{ target }} as DBT_INTERNAL_DEST\\n        using {{ source }} as DBT_INTERNAL_SOURCE\\n        on {{\\\"(\\\" ~ predicates | join(\\\") and (\\\") ~ \\\")\\\"}}\\n\\n    {% if unique_key %}\\n    when matched then update set\\n        {% for column_name in update_columns -%}\\n            {{ column_name }} = DBT_INTERNAL_SOURCE.{{ column_name }}\\n            {%- if not loop.last %}, {%- endif %}\\n        {%- endfor %}\\n    {% endif %}\\n\\n    when not matched then insert\\n        ({{ dest_cols_csv }})\\n    values\\n        ({{ dest_cols_csv }})\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_quoted_csv\", \"macro.dbt.get_merge_update_columns\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.558579, \"supported_languages\": null}, \"macro.dbt.get_delete_insert_merge_sql\": {\"name\": \"get_delete_insert_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"unique_id\": \"macro.dbt.get_delete_insert_merge_sql\", \"macro_sql\": \"{% macro get_delete_insert_merge_sql(target, source, unique_key, dest_columns, incremental_predicates) -%}\\n  {{ adapter.dispatch('get_delete_insert_merge_sql', 'dbt')(target, source, unique_key, dest_columns, incremental_predicates) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_delete_insert_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.559229, \"supported_languages\": null}, \"macro.dbt.default__get_delete_insert_merge_sql\": {\"name\": \"default__get_delete_insert_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"unique_id\": \"macro.dbt.default__get_delete_insert_merge_sql\", \"macro_sql\": \"{% macro default__get_delete_insert_merge_sql(target, source, unique_key, dest_columns, incremental_predicates) -%}\\n\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n\\n    {% if unique_key %}\\n        {% if unique_key is sequence and unique_key is not string %}\\n            delete from {{target }}\\n            using {{ source }}\\n            where (\\n                {% for key in unique_key %}\\n                    {{ source }}.{{ key }} = {{ target }}.{{ key }}\\n                    {{ \\\"and \\\" if not loop.last}}\\n                {% endfor %}\\n                {% if incremental_predicates %}\\n                    {% for predicate in incremental_predicates %}\\n                        and {{ predicate }}\\n                    {% endfor %}\\n                {% endif %}\\n            );\\n        {% else %}\\n            delete from {{ target }}\\n            where (\\n                {{ unique_key }}) in (\\n                select ({{ unique_key }})\\n                from {{ source }}\\n            )\\n            {%- if incremental_predicates %}\\n                {% for predicate in incremental_predicates %}\\n                    and {{ predicate }}\\n                {% endfor %}\\n            {%- endif -%};\\n\\n        {% endif %}\\n    {% endif %}\\n\\n    insert into {{ target }} ({{ dest_cols_csv }})\\n    (\\n        select {{ dest_cols_csv }}\\n        from {{ source }}\\n    )\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_quoted_csv\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.561732, \"supported_languages\": null}, \"macro.dbt.get_insert_overwrite_merge_sql\": {\"name\": \"get_insert_overwrite_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"unique_id\": \"macro.dbt.get_insert_overwrite_merge_sql\", \"macro_sql\": \"{% macro get_insert_overwrite_merge_sql(target, source, dest_columns, predicates, include_sql_header=false) -%}\\n  {{ adapter.dispatch('get_insert_overwrite_merge_sql', 'dbt')(target, source, dest_columns, predicates, include_sql_header) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_insert_overwrite_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.56239, \"supported_languages\": null}, \"macro.dbt.default__get_insert_overwrite_merge_sql\": {\"name\": \"default__get_insert_overwrite_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"unique_id\": \"macro.dbt.default__get_insert_overwrite_merge_sql\", \"macro_sql\": \"{% macro default__get_insert_overwrite_merge_sql(target, source, dest_columns, predicates, include_sql_header) -%}\\n    {#-- The only time include_sql_header is True: --#}\\n    {#-- BigQuery + insert_overwrite strategy + \\\"static\\\" partitions config --#}\\n    {#-- We should consider including the sql header at the materialization level instead --#}\\n\\n    {%- set predicates = [] if predicates is none else [] + predicates -%}\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n    {%- set sql_header = config.get('sql_header', none) -%}\\n\\n    {{ sql_header if sql_header is not none and include_sql_header }}\\n\\n    merge into {{ target }} as DBT_INTERNAL_DEST\\n        using {{ source }} as DBT_INTERNAL_SOURCE\\n        on FALSE\\n\\n    when not matched by source\\n        {% if predicates %} and {{ predicates | join(' and ') }} {% endif %}\\n        then delete\\n\\n    when not matched then insert\\n        ({{ dest_cols_csv }})\\n    values\\n        ({{ dest_cols_csv }})\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_quoted_csv\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.564075, \"supported_languages\": null}, \"macro.dbt.is_incremental\": {\"name\": \"is_incremental\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/is_incremental.sql\", \"original_file_path\": \"macros/materializations/models/incremental/is_incremental.sql\", \"unique_id\": \"macro.dbt.is_incremental\", \"macro_sql\": \"{% macro is_incremental() %}\\n    {#-- do not run introspective queries in parsing #}\\n    {% if not execute %}\\n        {{ return(False) }}\\n    {% else %}\\n        {% set relation = adapter.get_relation(this.database, this.schema, this.table) %}\\n        {{ return(relation is not none\\n                  and relation.type == 'table'\\n                  and model.config.materialized == 'incremental'\\n                  and not should_full_refresh()) }}\\n    {% endif %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.should_full_refresh\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.565938, \"supported_languages\": null}, \"macro.dbt.get_incremental_append_sql\": {\"name\": \"get_incremental_append_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.get_incremental_append_sql\", \"macro_sql\": \"{% macro get_incremental_append_sql(arg_dict) %}\\n\\n  {{ return(adapter.dispatch('get_incremental_append_sql', 'dbt')(arg_dict)) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_incremental_append_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.567849, \"supported_languages\": null}, \"macro.dbt.default__get_incremental_append_sql\": {\"name\": \"default__get_incremental_append_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.default__get_incremental_append_sql\", \"macro_sql\": \"{% macro default__get_incremental_append_sql(arg_dict) %}\\n\\n  {% do return(get_insert_into_sql(arg_dict[\\\"target_relation\\\"], arg_dict[\\\"temp_relation\\\"], arg_dict[\\\"dest_columns\\\"])) %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_insert_into_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.568505, \"supported_languages\": null}, \"macro.dbt.get_incremental_delete_insert_sql\": {\"name\": \"get_incremental_delete_insert_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.get_incremental_delete_insert_sql\", \"macro_sql\": \"{% macro get_incremental_delete_insert_sql(arg_dict) %}\\n\\n  {{ return(adapter.dispatch('get_incremental_delete_insert_sql', 'dbt')(arg_dict)) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_incremental_delete_insert_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.5689778, \"supported_languages\": null}, \"macro.dbt.default__get_incremental_delete_insert_sql\": {\"name\": \"default__get_incremental_delete_insert_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.default__get_incremental_delete_insert_sql\", \"macro_sql\": \"{% macro default__get_incremental_delete_insert_sql(arg_dict) %}\\n\\n  {% do return(get_delete_insert_merge_sql(arg_dict[\\\"target_relation\\\"], arg_dict[\\\"temp_relation\\\"], arg_dict[\\\"unique_key\\\"], arg_dict[\\\"dest_columns\\\"], arg_dict[\\\"incremental_predicates\\\"])) %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_delete_insert_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.569709, \"supported_languages\": null}, \"macro.dbt.get_incremental_merge_sql\": {\"name\": \"get_incremental_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.get_incremental_merge_sql\", \"macro_sql\": \"{% macro get_incremental_merge_sql(arg_dict) %}\\n\\n  {{ return(adapter.dispatch('get_incremental_merge_sql', 'dbt')(arg_dict)) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_incremental_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.570188, \"supported_languages\": null}, \"macro.dbt.default__get_incremental_merge_sql\": {\"name\": \"default__get_incremental_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.default__get_incremental_merge_sql\", \"macro_sql\": \"{% macro default__get_incremental_merge_sql(arg_dict) %}\\n\\n  {% do return(get_merge_sql(arg_dict[\\\"target_relation\\\"], arg_dict[\\\"temp_relation\\\"], arg_dict[\\\"unique_key\\\"], arg_dict[\\\"dest_columns\\\"], arg_dict[\\\"incremental_predicates\\\"])) %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.5709162, \"supported_languages\": null}, \"macro.dbt.get_incremental_insert_overwrite_sql\": {\"name\": \"get_incremental_insert_overwrite_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.get_incremental_insert_overwrite_sql\", \"macro_sql\": \"{% macro get_incremental_insert_overwrite_sql(arg_dict) %}\\n\\n  {{ return(adapter.dispatch('get_incremental_insert_overwrite_sql', 'dbt')(arg_dict)) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_incremental_insert_overwrite_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.57139, \"supported_languages\": null}, \"macro.dbt.default__get_incremental_insert_overwrite_sql\": {\"name\": \"default__get_incremental_insert_overwrite_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.default__get_incremental_insert_overwrite_sql\", \"macro_sql\": \"{% macro default__get_incremental_insert_overwrite_sql(arg_dict) %}\\n\\n  {% do return(get_insert_overwrite_merge_sql(arg_dict[\\\"target_relation\\\"], arg_dict[\\\"temp_relation\\\"], arg_dict[\\\"dest_columns\\\"], arg_dict[\\\"incremental_predicates\\\"])) %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_insert_overwrite_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.572049, \"supported_languages\": null}, \"macro.dbt.get_incremental_default_sql\": {\"name\": \"get_incremental_default_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.get_incremental_default_sql\", \"macro_sql\": \"{% macro get_incremental_default_sql(arg_dict) %}\\n\\n  {{ return(adapter.dispatch('get_incremental_default_sql', 'dbt')(arg_dict)) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_incremental_default_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.572522, \"supported_languages\": null}, \"macro.dbt.default__get_incremental_default_sql\": {\"name\": \"default__get_incremental_default_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.default__get_incremental_default_sql\", \"macro_sql\": \"{% macro default__get_incremental_default_sql(arg_dict) %}\\n\\n  {% do return(get_incremental_append_sql(arg_dict)) %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_incremental_append_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.5729191, \"supported_languages\": null}, \"macro.dbt.get_insert_into_sql\": {\"name\": \"get_insert_into_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.get_insert_into_sql\", \"macro_sql\": \"{% macro get_insert_into_sql(target_relation, temp_relation, dest_columns) %}\\n\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n\\n    insert into {{ target_relation }} ({{ dest_cols_csv }})\\n    (\\n        select {{ dest_cols_csv }}\\n        from {{ temp_relation }}\\n    )\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_quoted_csv\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.57362, \"supported_languages\": null}, \"macro.dbt.materialization_incremental_default\": {\"name\": \"materialization_incremental_default\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/incremental.sql\", \"original_file_path\": \"macros/materializations/models/incremental/incremental.sql\", \"unique_id\": \"macro.dbt.materialization_incremental_default\", \"macro_sql\": \"{% materialization incremental, default -%}\\n\\n  -- relations\\n  {%- set existing_relation = load_cached_relation(this) -%}\\n  {%- set target_relation = this.incorporate(type='table') -%}\\n  {%- set temp_relation = make_temp_relation(target_relation)-%}\\n  {%- set intermediate_relation = make_intermediate_relation(target_relation)-%}\\n  {%- set backup_relation_type = 'table' if existing_relation is none else existing_relation.type -%}\\n  {%- set backup_relation = make_backup_relation(target_relation, backup_relation_type) -%}\\n\\n  -- configs\\n  {%- set unique_key = config.get('unique_key') -%}\\n  {%- set full_refresh_mode = (should_full_refresh()  or existing_relation.is_view) -%}\\n  {%- set on_schema_change = incremental_validate_on_schema_change(config.get('on_schema_change'), default='ignore') -%}\\n\\n  -- the temp_ and backup_ relations should not already exist in the database; get_relation\\n  -- will return None in that case. Otherwise, we get a relation that we can drop\\n  -- later, before we try to use this name for the current operation. This has to happen before\\n  -- BEGIN, in a separate transaction\\n  {%- set preexisting_intermediate_relation = load_cached_relation(intermediate_relation)-%}\\n  {%- set preexisting_backup_relation = load_cached_relation(backup_relation) -%}\\n   -- grab current tables grants config for comparision later on\\n  {% set grant_config = config.get('grants') %}\\n  {{ drop_relation_if_exists(preexisting_intermediate_relation) }}\\n  {{ drop_relation_if_exists(preexisting_backup_relation) }}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  {% set to_drop = [] %}\\n\\n  {% if existing_relation is none %}\\n      {% set build_sql = get_create_table_as_sql(False, target_relation, sql) %}\\n  {% elif full_refresh_mode %}\\n      {% set build_sql = get_create_table_as_sql(False, intermediate_relation, sql) %}\\n      {% set need_swap = true %}\\n  {% else %}\\n    {% do run_query(get_create_table_as_sql(True, temp_relation, sql)) %}\\n    {% do adapter.expand_target_column_types(\\n             from_relation=temp_relation,\\n             to_relation=target_relation) %}\\n    {#-- Process schema changes. Returns dict of changes if successful. Use source columns for upserting/merging --#}\\n    {% set dest_columns = process_schema_changes(on_schema_change, temp_relation, existing_relation) %}\\n    {% if not dest_columns %}\\n      {% set dest_columns = adapter.get_columns_in_relation(existing_relation) %}\\n    {% endif %}\\n\\n    {#-- Get the incremental_strategy, the macro to use for the strategy, and build the sql --#}\\n    {% set incremental_strategy = config.get('incremental_strategy') or 'default' %}\\n    {% set incremental_predicates = config.get('predicates', none) or config.get('incremental_predicates', none) %}\\n    {% set strategy_sql_macro_func = adapter.get_incremental_strategy_macro(context, incremental_strategy) %}\\n    {% set strategy_arg_dict = ({'target_relation': target_relation, 'temp_relation': temp_relation, 'unique_key': unique_key, 'dest_columns': dest_columns, 'incremental_predicates': incremental_predicates }) %}\\n    {% set build_sql = strategy_sql_macro_func(strategy_arg_dict) %}\\n\\n  {% endif %}\\n\\n  {% call statement(\\\"main\\\") %}\\n      {{ build_sql }}\\n  {% endcall %}\\n\\n  {% if need_swap %}\\n      {% do adapter.rename_relation(target_relation, backup_relation) %}\\n      {% do adapter.rename_relation(intermediate_relation, target_relation) %}\\n      {% do to_drop.append(backup_relation) %}\\n  {% endif %}\\n\\n  {% set should_revoke = should_revoke(existing_relation, full_refresh_mode) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {% if existing_relation is none or existing_relation.is_view or should_full_refresh() %}\\n    {% do create_indexes(target_relation) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  -- `COMMIT` happens here\\n  {% do adapter.commit() %}\\n\\n  {% for rel in to_drop %}\\n      {% do adapter.drop_relation(rel) %}\\n  {% endfor %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{%- endmaterialization %}\", \"depends_on\": {\"macros\": [\"macro.dbt.load_cached_relation\", \"macro.dbt.make_temp_relation\", \"macro.dbt.make_intermediate_relation\", \"macro.dbt.make_backup_relation\", \"macro.dbt.should_full_refresh\", \"macro.dbt.incremental_validate_on_schema_change\", \"macro.dbt.drop_relation_if_exists\", \"macro.dbt.run_hooks\", \"macro.dbt.get_create_table_as_sql\", \"macro.dbt.run_query\", \"macro.dbt.process_schema_changes\", \"macro.dbt.statement\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\", \"macro.dbt.persist_docs\", \"macro.dbt.create_indexes\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.585784, \"supported_languages\": [\"sql\"]}, \"macro.dbt.incremental_validate_on_schema_change\": {\"name\": \"incremental_validate_on_schema_change\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"original_file_path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"unique_id\": \"macro.dbt.incremental_validate_on_schema_change\", \"macro_sql\": \"{% macro incremental_validate_on_schema_change(on_schema_change, default='ignore') %}\\n\\n   {% if on_schema_change not in ['sync_all_columns', 'append_new_columns', 'fail', 'ignore'] %}\\n\\n     {% set log_message = 'Invalid value for on_schema_change (%s) specified. Setting default value of %s.' % (on_schema_change, default) %}\\n     {% do log(log_message) %}\\n\\n     {{ return(default) }}\\n\\n   {% else %}\\n\\n     {{ return(on_schema_change) }}\\n\\n   {% endif %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.59618, \"supported_languages\": null}, \"macro.dbt.check_for_schema_changes\": {\"name\": \"check_for_schema_changes\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"original_file_path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"unique_id\": \"macro.dbt.check_for_schema_changes\", \"macro_sql\": \"{% macro check_for_schema_changes(source_relation, target_relation) %}\\n\\n  {% set schema_changed = False %}\\n\\n  {%- set source_columns = adapter.get_columns_in_relation(source_relation) -%}\\n  {%- set target_columns = adapter.get_columns_in_relation(target_relation) -%}\\n  {%- set source_not_in_target = diff_columns(source_columns, target_columns) -%}\\n  {%- set target_not_in_source = diff_columns(target_columns, source_columns) -%}\\n\\n  {% set new_target_types = diff_column_data_types(source_columns, target_columns) %}\\n\\n  {% if source_not_in_target != [] %}\\n    {% set schema_changed = True %}\\n  {% elif target_not_in_source != [] or new_target_types != [] %}\\n    {% set schema_changed = True %}\\n  {% elif new_target_types != [] %}\\n    {% set schema_changed = True %}\\n  {% endif %}\\n\\n  {% set changes_dict = {\\n    'schema_changed': schema_changed,\\n    'source_not_in_target': source_not_in_target,\\n    'target_not_in_source': target_not_in_source,\\n    'source_columns': source_columns,\\n    'target_columns': target_columns,\\n    'new_target_types': new_target_types\\n  } %}\\n\\n  {% set msg %}\\n    In {{ target_relation }}:\\n        Schema changed: {{ schema_changed }}\\n        Source columns not in target: {{ source_not_in_target }}\\n        Target columns not in source: {{ target_not_in_source }}\\n        New column types: {{ new_target_types }}\\n  {% endset %}\\n\\n  {% do log(msg) %}\\n\\n  {{ return(changes_dict) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.diff_columns\", \"macro.dbt.diff_column_data_types\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.60002, \"supported_languages\": null}, \"macro.dbt.sync_column_schemas\": {\"name\": \"sync_column_schemas\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"original_file_path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"unique_id\": \"macro.dbt.sync_column_schemas\", \"macro_sql\": \"{% macro sync_column_schemas(on_schema_change, target_relation, schema_changes_dict) %}\\n\\n  {%- set add_to_target_arr = schema_changes_dict['source_not_in_target'] -%}\\n\\n  {%- if on_schema_change == 'append_new_columns'-%}\\n     {%- if add_to_target_arr | length > 0 -%}\\n       {%- do alter_relation_add_remove_columns(target_relation, add_to_target_arr, none) -%}\\n     {%- endif -%}\\n\\n  {% elif on_schema_change == 'sync_all_columns' %}\\n     {%- set remove_from_target_arr = schema_changes_dict['target_not_in_source'] -%}\\n     {%- set new_target_types = schema_changes_dict['new_target_types'] -%}\\n\\n     {% if add_to_target_arr | length > 0 or remove_from_target_arr | length > 0 %}\\n       {%- do alter_relation_add_remove_columns(target_relation, add_to_target_arr, remove_from_target_arr) -%}\\n     {% endif %}\\n\\n     {% if new_target_types != [] %}\\n       {% for ntt in new_target_types %}\\n         {% set column_name = ntt['column_name'] %}\\n         {% set new_type = ntt['new_type'] %}\\n         {% do alter_column_type(target_relation, column_name, new_type) %}\\n       {% endfor %}\\n     {% endif %}\\n\\n  {% endif %}\\n\\n  {% set schema_change_message %}\\n    In {{ target_relation }}:\\n        Schema change approach: {{ on_schema_change }}\\n        Columns added: {{ add_to_target_arr }}\\n        Columns removed: {{ remove_from_target_arr }}\\n        Data types changed: {{ new_target_types }}\\n  {% endset %}\\n\\n  {% do log(schema_change_message) %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.alter_relation_add_remove_columns\", \"macro.dbt.alter_column_type\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.603049, \"supported_languages\": null}, \"macro.dbt.process_schema_changes\": {\"name\": \"process_schema_changes\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"original_file_path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"unique_id\": \"macro.dbt.process_schema_changes\", \"macro_sql\": \"{% macro process_schema_changes(on_schema_change, source_relation, target_relation) %}\\n\\n    {% if on_schema_change == 'ignore' %}\\n\\n     {{ return({}) }}\\n\\n    {% else %}\\n\\n      {% set schema_changes_dict = check_for_schema_changes(source_relation, target_relation) %}\\n\\n      {% if schema_changes_dict['schema_changed'] %}\\n\\n        {% if on_schema_change == 'fail' %}\\n\\n          {% set fail_msg %}\\n              The source and target schemas on this incremental model are out of sync!\\n              They can be reconciled in several ways:\\n                - set the `on_schema_change` config to either append_new_columns or sync_all_columns, depending on your situation.\\n                - Re-run the incremental model with `full_refresh: True` to update the target schema.\\n                - update the schema manually and re-run the process.\\n\\n              Additional troubleshooting context:\\n                 Source columns not in target: {{ schema_changes_dict['source_not_in_target'] }}\\n                 Target columns not in source: {{ schema_changes_dict['target_not_in_source'] }}\\n                 New column types: {{ schema_changes_dict['new_target_types'] }}\\n          {% endset %}\\n\\n          {% do exceptions.raise_compiler_error(fail_msg) %}\\n\\n        {# -- unless we ignore, run the sync operation per the config #}\\n        {% else %}\\n\\n          {% do sync_column_schemas(on_schema_change, target_relation, schema_changes_dict) %}\\n\\n        {% endif %}\\n\\n      {% endif %}\\n\\n      {{ return(schema_changes_dict['source_columns']) }}\\n\\n    {% endif %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.check_for_schema_changes\", \"macro.dbt.sync_column_schemas\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.605203, \"supported_languages\": null}, \"macro.dbt.materialization_table_default\": {\"name\": \"materialization_table_default\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/table/table.sql\", \"original_file_path\": \"macros/materializations/models/table/table.sql\", \"unique_id\": \"macro.dbt.materialization_table_default\", \"macro_sql\": \"{% materialization table, default %}\\n\\n  {%- set existing_relation = load_cached_relation(this) -%}\\n  {%- set target_relation = this.incorporate(type='table') %}\\n  {%- set intermediate_relation =  make_intermediate_relation(target_relation) -%}\\n  -- the intermediate_relation should not already exist in the database; get_relation\\n  -- will return None in that case. Otherwise, we get a relation that we can drop\\n  -- later, before we try to use this name for the current operation\\n  {%- set preexisting_intermediate_relation = load_cached_relation(intermediate_relation) -%}\\n  /*\\n      See ../view/view.sql for more information about this relation.\\n  */\\n  {%- set backup_relation_type = 'table' if existing_relation is none else existing_relation.type -%}\\n  {%- set backup_relation = make_backup_relation(target_relation, backup_relation_type) -%}\\n  -- as above, the backup_relation should not already exist\\n  {%- set preexisting_backup_relation = load_cached_relation(backup_relation) -%}\\n  -- grab current tables grants config for comparision later on\\n  {% set grant_config = config.get('grants') %}\\n\\n  -- drop the temp relations if they exist already in the database\\n  {{ drop_relation_if_exists(preexisting_intermediate_relation) }}\\n  {{ drop_relation_if_exists(preexisting_backup_relation) }}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  -- build model\\n  {% call statement('main') -%}\\n    {{ get_create_table_as_sql(False, intermediate_relation, sql) }}\\n  {%- endcall %}\\n\\n  -- cleanup\\n  {% if existing_relation is not none %}\\n      {{ adapter.rename_relation(existing_relation, backup_relation) }}\\n  {% endif %}\\n\\n  {{ adapter.rename_relation(intermediate_relation, target_relation) }}\\n\\n  {% do create_indexes(target_relation) %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  {% set should_revoke = should_revoke(existing_relation, full_refresh_mode=True) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  -- `COMMIT` happens here\\n  {{ adapter.commit() }}\\n\\n  -- finally, drop the existing/backup relation after the commit\\n  {{ drop_relation_if_exists(backup_relation) }}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n{% endmaterialization %}\", \"depends_on\": {\"macros\": [\"macro.dbt.load_cached_relation\", \"macro.dbt.make_intermediate_relation\", \"macro.dbt.make_backup_relation\", \"macro.dbt.drop_relation_if_exists\", \"macro.dbt.run_hooks\", \"macro.dbt.statement\", \"macro.dbt.get_create_table_as_sql\", \"macro.dbt.create_indexes\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\", \"macro.dbt.persist_docs\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.611255, \"supported_languages\": [\"sql\"]}, \"macro.dbt.get_create_table_as_sql\": {\"name\": \"get_create_table_as_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/table/create_table_as.sql\", \"original_file_path\": \"macros/materializations/models/table/create_table_as.sql\", \"unique_id\": \"macro.dbt.get_create_table_as_sql\", \"macro_sql\": \"{% macro get_create_table_as_sql(temporary, relation, sql) -%}\\n  {{ adapter.dispatch('get_create_table_as_sql', 'dbt')(temporary, relation, sql) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_create_table_as_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.612431, \"supported_languages\": null}, \"macro.dbt.default__get_create_table_as_sql\": {\"name\": \"default__get_create_table_as_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/table/create_table_as.sql\", \"original_file_path\": \"macros/materializations/models/table/create_table_as.sql\", \"unique_id\": \"macro.dbt.default__get_create_table_as_sql\", \"macro_sql\": \"{% macro default__get_create_table_as_sql(temporary, relation, sql) -%}\\n  {{ return(create_table_as(temporary, relation, sql)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.create_table_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.6129012, \"supported_languages\": null}, \"macro.dbt.create_table_as\": {\"name\": \"create_table_as\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/table/create_table_as.sql\", \"original_file_path\": \"macros/materializations/models/table/create_table_as.sql\", \"unique_id\": \"macro.dbt.create_table_as\", \"macro_sql\": \"{% macro create_table_as(temporary, relation, compiled_code, language='sql') -%}\\n  {# backward compatibility for create_table_as that does not support language #}\\n  {% if language == \\\"sql\\\" %}\\n    {{ adapter.dispatch('create_table_as', 'dbt')(temporary, relation, compiled_code)}}\\n  {% else %}\\n    {{ adapter.dispatch('create_table_as', 'dbt')(temporary, relation, compiled_code, language) }}\\n  {% endif %}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__create_table_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.613973, \"supported_languages\": null}, \"macro.dbt.default__create_table_as\": {\"name\": \"default__create_table_as\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/table/create_table_as.sql\", \"original_file_path\": \"macros/materializations/models/table/create_table_as.sql\", \"unique_id\": \"macro.dbt.default__create_table_as\", \"macro_sql\": \"{% macro default__create_table_as(temporary, relation, sql) -%}\\n  {%- set sql_header = config.get('sql_header', none) -%}\\n\\n  {{ sql_header if sql_header is not none }}\\n\\n  create {% if temporary: -%}temporary{%- endif %} table\\n    {{ relation.include(database=(not temporary), schema=(not temporary)) }}\\n  as (\\n    {{ sql }}\\n  );\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.614995, \"supported_languages\": null}, \"macro.dbt.materialization_view_default\": {\"name\": \"materialization_view_default\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/view/view.sql\", \"original_file_path\": \"macros/materializations/models/view/view.sql\", \"unique_id\": \"macro.dbt.materialization_view_default\", \"macro_sql\": \"{%- materialization view, default -%}\\n\\n  {%- set existing_relation = load_cached_relation(this) -%}\\n  {%- set target_relation = this.incorporate(type='view') -%}\\n  {%- set intermediate_relation =  make_intermediate_relation(target_relation) -%}\\n\\n  -- the intermediate_relation should not already exist in the database; get_relation\\n  -- will return None in that case. Otherwise, we get a relation that we can drop\\n  -- later, before we try to use this name for the current operation\\n  {%- set preexisting_intermediate_relation = load_cached_relation(intermediate_relation) -%}\\n  /*\\n     This relation (probably) doesn't exist yet. If it does exist, it's a leftover from\\n     a previous run, and we're going to try to drop it immediately. At the end of this\\n     materialization, we're going to rename the \\\"existing_relation\\\" to this identifier,\\n     and then we're going to drop it. In order to make sure we run the correct one of:\\n       - drop view ...\\n       - drop table ...\\n\\n     We need to set the type of this relation to be the type of the existing_relation, if it exists,\\n     or else \\\"view\\\" as a sane default if it does not. Note that if the existing_relation does not\\n     exist, then there is nothing to move out of the way and subsequentally drop. In that case,\\n     this relation will be effectively unused.\\n  */\\n  {%- set backup_relation_type = 'view' if existing_relation is none else existing_relation.type -%}\\n  {%- set backup_relation = make_backup_relation(target_relation, backup_relation_type) -%}\\n  -- as above, the backup_relation should not already exist\\n  {%- set preexisting_backup_relation = load_cached_relation(backup_relation) -%}\\n  -- grab current tables grants config for comparision later on\\n  {% set grant_config = config.get('grants') %}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- drop the temp relations if they exist already in the database\\n  {{ drop_relation_if_exists(preexisting_intermediate_relation) }}\\n  {{ drop_relation_if_exists(preexisting_backup_relation) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  -- build model\\n  {% call statement('main') -%}\\n    {{ get_create_view_as_sql(intermediate_relation, sql) }}\\n  {%- endcall %}\\n\\n  -- cleanup\\n  -- move the existing view out of the way\\n  {% if existing_relation is not none %}\\n    {{ adapter.rename_relation(existing_relation, backup_relation) }}\\n  {% endif %}\\n  {{ adapter.rename_relation(intermediate_relation, target_relation) }}\\n\\n  {% set should_revoke = should_revoke(existing_relation, full_refresh_mode=True) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  {{ adapter.commit() }}\\n\\n  {{ drop_relation_if_exists(backup_relation) }}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{%- endmaterialization -%}\", \"depends_on\": {\"macros\": [\"macro.dbt.load_cached_relation\", \"macro.dbt.make_intermediate_relation\", \"macro.dbt.make_backup_relation\", \"macro.dbt.run_hooks\", \"macro.dbt.drop_relation_if_exists\", \"macro.dbt.statement\", \"macro.dbt.get_create_view_as_sql\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\", \"macro.dbt.persist_docs\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.621283, \"supported_languages\": [\"sql\"]}, \"macro.dbt.handle_existing_table\": {\"name\": \"handle_existing_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/view/helpers.sql\", \"original_file_path\": \"macros/materializations/models/view/helpers.sql\", \"unique_id\": \"macro.dbt.handle_existing_table\", \"macro_sql\": \"{% macro handle_existing_table(full_refresh, old_relation) %}\\n    {{ adapter.dispatch('handle_existing_table', 'dbt')(full_refresh, old_relation) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__handle_existing_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.6220968, \"supported_languages\": null}, \"macro.dbt.default__handle_existing_table\": {\"name\": \"default__handle_existing_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/view/helpers.sql\", \"original_file_path\": \"macros/materializations/models/view/helpers.sql\", \"unique_id\": \"macro.dbt.default__handle_existing_table\", \"macro_sql\": \"{% macro default__handle_existing_table(full_refresh, old_relation) %}\\n    {{ log(\\\"Dropping relation \\\" ~ old_relation ~ \\\" because it is of type \\\" ~ old_relation.type) }}\\n    {{ adapter.drop_relation(old_relation) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.622665, \"supported_languages\": null}, \"macro.dbt.create_or_replace_view\": {\"name\": \"create_or_replace_view\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/view/create_or_replace_view.sql\", \"original_file_path\": \"macros/materializations/models/view/create_or_replace_view.sql\", \"unique_id\": \"macro.dbt.create_or_replace_view\", \"macro_sql\": \"{% macro create_or_replace_view() %}\\n  {%- set identifier = model['alias'] -%}\\n\\n  {%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%}\\n  {%- set exists_as_view = (old_relation is not none and old_relation.is_view) -%}\\n\\n  {%- set target_relation = api.Relation.create(\\n      identifier=identifier, schema=schema, database=database,\\n      type='view') -%}\\n  {% set grant_config = config.get('grants') %}\\n\\n  {{ run_hooks(pre_hooks) }}\\n\\n  -- If there's a table with the same name and we weren't told to full refresh,\\n  -- that's an error. If we were told to full refresh, drop it. This behavior differs\\n  -- for Snowflake and BigQuery, so multiple dispatch is used.\\n  {%- if old_relation is not none and old_relation.is_table -%}\\n    {{ handle_existing_table(should_full_refresh(), old_relation) }}\\n  {%- endif -%}\\n\\n  -- build model\\n  {% call statement('main') -%}\\n    {{ get_create_view_as_sql(target_relation, sql) }}\\n  {%- endcall %}\\n\\n  {% set should_revoke = should_revoke(exists_as_view, full_refresh_mode=True) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=True) %}\\n\\n  {{ run_hooks(post_hooks) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.run_hooks\", \"macro.dbt.handle_existing_table\", \"macro.dbt.should_full_refresh\", \"macro.dbt.statement\", \"macro.dbt.get_create_view_as_sql\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.626231, \"supported_languages\": null}, \"macro.dbt.get_create_view_as_sql\": {\"name\": \"get_create_view_as_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/view/create_view_as.sql\", \"original_file_path\": \"macros/materializations/models/view/create_view_as.sql\", \"unique_id\": \"macro.dbt.get_create_view_as_sql\", \"macro_sql\": \"{% macro get_create_view_as_sql(relation, sql) -%}\\n  {{ adapter.dispatch('get_create_view_as_sql', 'dbt')(relation, sql) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_create_view_as_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.627094, \"supported_languages\": null}, \"macro.dbt.default__get_create_view_as_sql\": {\"name\": \"default__get_create_view_as_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/view/create_view_as.sql\", \"original_file_path\": \"macros/materializations/models/view/create_view_as.sql\", \"unique_id\": \"macro.dbt.default__get_create_view_as_sql\", \"macro_sql\": \"{% macro default__get_create_view_as_sql(relation, sql) -%}\\n  {{ return(create_view_as(relation, sql)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.create_view_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.627518, \"supported_languages\": null}, \"macro.dbt.create_view_as\": {\"name\": \"create_view_as\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/view/create_view_as.sql\", \"original_file_path\": \"macros/materializations/models/view/create_view_as.sql\", \"unique_id\": \"macro.dbt.create_view_as\", \"macro_sql\": \"{% macro create_view_as(relation, sql) -%}\\n  {{ adapter.dispatch('create_view_as', 'dbt')(relation, sql) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__create_view_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.627975, \"supported_languages\": null}, \"macro.dbt.default__create_view_as\": {\"name\": \"default__create_view_as\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/view/create_view_as.sql\", \"original_file_path\": \"macros/materializations/models/view/create_view_as.sql\", \"unique_id\": \"macro.dbt.default__create_view_as\", \"macro_sql\": \"{% macro default__create_view_as(relation, sql) -%}\\n  {%- set sql_header = config.get('sql_header', none) -%}\\n\\n  {{ sql_header if sql_header is not none }}\\n  create view {{ relation }} as (\\n    {{ sql }}\\n  );\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.628621, \"supported_languages\": null}, \"macro.dbt.materialization_seed_default\": {\"name\": \"materialization_seed_default\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/seed.sql\", \"original_file_path\": \"macros/materializations/seeds/seed.sql\", \"unique_id\": \"macro.dbt.materialization_seed_default\", \"macro_sql\": \"{% materialization seed, default %}\\n\\n  {%- set identifier = model['alias'] -%}\\n  {%- set full_refresh_mode = (should_full_refresh()) -%}\\n\\n  {%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%}\\n\\n  {%- set exists_as_table = (old_relation is not none and old_relation.is_table) -%}\\n  {%- set exists_as_view = (old_relation is not none and old_relation.is_view) -%}\\n\\n  {%- set grant_config = config.get('grants') -%}\\n  {%- set agate_table = load_agate_table() -%}\\n  -- grab current tables grants config for comparision later on\\n\\n  {%- do store_result('agate_table', response='OK', agate_table=agate_table) -%}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  -- build model\\n  {% set create_table_sql = \\\"\\\" %}\\n  {% if exists_as_view %}\\n    {{ exceptions.raise_compiler_error(\\\"Cannot seed to '{}', it is a view\\\".format(old_relation)) }}\\n  {% elif exists_as_table %}\\n    {% set create_table_sql = reset_csv_table(model, full_refresh_mode, old_relation, agate_table) %}\\n  {% else %}\\n    {% set create_table_sql = create_csv_table(model, agate_table) %}\\n  {% endif %}\\n\\n  {% set code = 'CREATE' if full_refresh_mode else 'INSERT' %}\\n  {% set rows_affected = (agate_table.rows | length) %}\\n  {% set sql = load_csv_rows(model, agate_table) %}\\n\\n  {% call noop_statement('main', code ~ ' ' ~ rows_affected, code, rows_affected) %}\\n    {{ get_csv_sql(create_table_sql, sql) }};\\n  {% endcall %}\\n\\n  {% set target_relation = this.incorporate(type='table') %}\\n\\n  {% set should_revoke = should_revoke(old_relation, full_refresh_mode) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {% if full_refresh_mode or not exists_as_table %}\\n    {% do create_indexes(target_relation) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  -- `COMMIT` happens here\\n  {{ adapter.commit() }}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{% endmaterialization %}\", \"depends_on\": {\"macros\": [\"macro.dbt.should_full_refresh\", \"macro.dbt.run_hooks\", \"macro.dbt.reset_csv_table\", \"macro.dbt.create_csv_table\", \"macro.dbt.load_csv_rows\", \"macro.dbt.noop_statement\", \"macro.dbt.get_csv_sql\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\", \"macro.dbt.persist_docs\", \"macro.dbt.create_indexes\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.6366222, \"supported_languages\": [\"sql\"]}, \"macro.dbt.create_csv_table\": {\"name\": \"create_csv_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.create_csv_table\", \"macro_sql\": \"{% macro create_csv_table(model, agate_table) -%}\\n  {{ adapter.dispatch('create_csv_table', 'dbt')(model, agate_table) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__create_csv_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.6457422, \"supported_languages\": null}, \"macro.dbt.default__create_csv_table\": {\"name\": \"default__create_csv_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.default__create_csv_table\", \"macro_sql\": \"{% macro default__create_csv_table(model, agate_table) %}\\n  {%- set column_override = model['config'].get('column_types', {}) -%}\\n  {%- set quote_seed_column = model['config'].get('quote_columns', None) -%}\\n\\n  {% set sql %}\\n    create table {{ this.render() }} (\\n        {%- for col_name in agate_table.column_names -%}\\n            {%- set inferred_type = adapter.convert_type(agate_table, loop.index0) -%}\\n            {%- set type = column_override.get(col_name, inferred_type) -%}\\n            {%- set column_name = (col_name | string) -%}\\n            {{ adapter.quote_seed_column(column_name, quote_seed_column) }} {{ type }} {%- if not loop.last -%}, {%- endif -%}\\n        {%- endfor -%}\\n    )\\n  {% endset %}\\n\\n  {% call statement('_') -%}\\n    {{ sql }}\\n  {%- endcall %}\\n\\n  {{ return(sql) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.648115, \"supported_languages\": null}, \"macro.dbt.reset_csv_table\": {\"name\": \"reset_csv_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.reset_csv_table\", \"macro_sql\": \"{% macro reset_csv_table(model, full_refresh, old_relation, agate_table) -%}\\n  {{ adapter.dispatch('reset_csv_table', 'dbt')(model, full_refresh, old_relation, agate_table) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__reset_csv_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.648722, \"supported_languages\": null}, \"macro.dbt.default__reset_csv_table\": {\"name\": \"default__reset_csv_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.default__reset_csv_table\", \"macro_sql\": \"{% macro default__reset_csv_table(model, full_refresh, old_relation, agate_table) %}\\n    {% set sql = \\\"\\\" %}\\n    {% if full_refresh %}\\n        {{ adapter.drop_relation(old_relation) }}\\n        {% set sql = create_csv_table(model, agate_table) %}\\n    {% else %}\\n        {{ adapter.truncate_relation(old_relation) }}\\n        {% set sql = \\\"truncate table \\\" ~ old_relation %}\\n    {% endif %}\\n\\n    {{ return(sql) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.create_csv_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.650075, \"supported_languages\": null}, \"macro.dbt.get_csv_sql\": {\"name\": \"get_csv_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.get_csv_sql\", \"macro_sql\": \"{% macro get_csv_sql(create_or_truncate_sql, insert_sql) %}\\n    {{ adapter.dispatch('get_csv_sql', 'dbt')(create_or_truncate_sql, insert_sql) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_csv_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.65061, \"supported_languages\": null}, \"macro.dbt.default__get_csv_sql\": {\"name\": \"default__get_csv_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.default__get_csv_sql\", \"macro_sql\": \"{% macro default__get_csv_sql(create_or_truncate_sql, insert_sql) %}\\n    {{ create_or_truncate_sql }};\\n    -- dbt seed --\\n    {{ insert_sql }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.6509619, \"supported_languages\": null}, \"macro.dbt.get_binding_char\": {\"name\": \"get_binding_char\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.get_binding_char\", \"macro_sql\": \"{% macro get_binding_char() -%}\\n  {{ adapter.dispatch('get_binding_char', 'dbt')() }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_binding_char\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.6513228, \"supported_languages\": null}, \"macro.dbt.default__get_binding_char\": {\"name\": \"default__get_binding_char\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.default__get_binding_char\", \"macro_sql\": \"{% macro default__get_binding_char() %}\\n  {{ return('%s') }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.6516201, \"supported_languages\": null}, \"macro.dbt.get_batch_size\": {\"name\": \"get_batch_size\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.get_batch_size\", \"macro_sql\": \"{% macro get_batch_size() -%}\\n  {{ return(adapter.dispatch('get_batch_size', 'dbt')()) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_batch_size\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.652027, \"supported_languages\": null}, \"macro.dbt.default__get_batch_size\": {\"name\": \"default__get_batch_size\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.default__get_batch_size\", \"macro_sql\": \"{% macro default__get_batch_size() %}\\n  {{ return(10000) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.6523268, \"supported_languages\": null}, \"macro.dbt.get_seed_column_quoted_csv\": {\"name\": \"get_seed_column_quoted_csv\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.get_seed_column_quoted_csv\", \"macro_sql\": \"{% macro get_seed_column_quoted_csv(model, column_names) %}\\n  {%- set quote_seed_column = model['config'].get('quote_columns', None) -%}\\n    {% set quoted = [] %}\\n    {% for col in column_names -%}\\n        {%- do quoted.append(adapter.quote_seed_column(col, quote_seed_column)) -%}\\n    {%- endfor %}\\n\\n    {%- set dest_cols_csv = quoted | join(', ') -%}\\n    {{ return(dest_cols_csv) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.6536052, \"supported_languages\": null}, \"macro.dbt.load_csv_rows\": {\"name\": \"load_csv_rows\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.load_csv_rows\", \"macro_sql\": \"{% macro load_csv_rows(model, agate_table) -%}\\n  {{ adapter.dispatch('load_csv_rows', 'dbt')(model, agate_table) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__load_csv_rows\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.654092, \"supported_languages\": null}, \"macro.dbt.default__load_csv_rows\": {\"name\": \"default__load_csv_rows\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.default__load_csv_rows\", \"macro_sql\": \"{% macro default__load_csv_rows(model, agate_table) %}\\n\\n  {% set batch_size = get_batch_size() %}\\n\\n  {% set cols_sql = get_seed_column_quoted_csv(model, agate_table.column_names) %}\\n  {% set bindings = [] %}\\n\\n  {% set statements = [] %}\\n\\n  {% for chunk in agate_table.rows | batch(batch_size) %}\\n      {% set bindings = [] %}\\n\\n      {% for row in chunk %}\\n          {% do bindings.extend(row) %}\\n      {% endfor %}\\n\\n      {% set sql %}\\n          insert into {{ this.render() }} ({{ cols_sql }}) values\\n          {% for row in chunk -%}\\n              ({%- for column in agate_table.column_names -%}\\n                  {{ get_binding_char() }}\\n                  {%- if not loop.last%},{%- endif %}\\n              {%- endfor -%})\\n              {%- if not loop.last%},{%- endif %}\\n          {%- endfor %}\\n      {% endset %}\\n\\n      {% do adapter.add_query(sql, bindings=bindings, abridge_sql_log=True) %}\\n\\n      {% if loop.index0 == 0 %}\\n          {% do statements.append(sql) %}\\n      {% endif %}\\n  {% endfor %}\\n\\n  {# Return SQL so we can render it out into the compiled files #}\\n  {{ return(statements[0]) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_batch_size\", \"macro.dbt.get_seed_column_quoted_csv\", \"macro.dbt.get_binding_char\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.657616, \"supported_languages\": null}, \"macro.dbt.generate_alias_name\": {\"name\": \"generate_alias_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/get_custom_name/get_custom_alias.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_alias.sql\", \"unique_id\": \"macro.dbt.generate_alias_name\", \"macro_sql\": \"{% macro generate_alias_name(custom_alias_name=none, node=none) -%}\\n    {% do return(adapter.dispatch('generate_alias_name', 'dbt')(custom_alias_name, node)) %}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__generate_alias_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.658516, \"supported_languages\": null}, \"macro.dbt.default__generate_alias_name\": {\"name\": \"default__generate_alias_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/get_custom_name/get_custom_alias.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_alias.sql\", \"unique_id\": \"macro.dbt.default__generate_alias_name\", \"macro_sql\": \"{% macro default__generate_alias_name(custom_alias_name=none, node=none) -%}\\n\\n    {%- if custom_alias_name is none -%}\\n\\n        {{ node.name }}\\n\\n    {%- else -%}\\n\\n        {{ custom_alias_name | trim }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.659103, \"supported_languages\": null}, \"macro.dbt.generate_schema_name\": {\"name\": \"generate_schema_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/get_custom_name/get_custom_schema.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_schema.sql\", \"unique_id\": \"macro.dbt.generate_schema_name\", \"macro_sql\": \"{% macro generate_schema_name(custom_schema_name=none, node=none) -%}\\n    {{ return(adapter.dispatch('generate_schema_name', 'dbt')(custom_schema_name, node)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__generate_schema_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.660212, \"supported_languages\": null}, \"macro.dbt.default__generate_schema_name\": {\"name\": \"default__generate_schema_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/get_custom_name/get_custom_schema.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_schema.sql\", \"unique_id\": \"macro.dbt.default__generate_schema_name\", \"macro_sql\": \"{% macro default__generate_schema_name(custom_schema_name, node) -%}\\n\\n    {%- set default_schema = target.schema -%}\\n    {%- if custom_schema_name is none -%}\\n\\n        {{ default_schema }}\\n\\n    {%- else -%}\\n\\n        {{ default_schema }}_{{ custom_schema_name | trim }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.660863, \"supported_languages\": null}, \"macro.dbt.generate_schema_name_for_env\": {\"name\": \"generate_schema_name_for_env\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/get_custom_name/get_custom_schema.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_schema.sql\", \"unique_id\": \"macro.dbt.generate_schema_name_for_env\", \"macro_sql\": \"{% macro generate_schema_name_for_env(custom_schema_name, node) -%}\\n\\n    {%- set default_schema = target.schema -%}\\n    {%- if target.name == 'prod' and custom_schema_name is not none -%}\\n\\n        {{ custom_schema_name | trim }}\\n\\n    {%- else -%}\\n\\n        {{ default_schema }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.661577, \"supported_languages\": null}, \"macro.dbt.generate_database_name\": {\"name\": \"generate_database_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/get_custom_name/get_custom_database.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_database.sql\", \"unique_id\": \"macro.dbt.generate_database_name\", \"macro_sql\": \"{% macro generate_database_name(custom_database_name=none, node=none) -%}\\n    {% do return(adapter.dispatch('generate_database_name', 'dbt')(custom_database_name, node)) %}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__generate_database_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.662461, \"supported_languages\": null}, \"macro.dbt.default__generate_database_name\": {\"name\": \"default__generate_database_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/get_custom_name/get_custom_database.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_database.sql\", \"unique_id\": \"macro.dbt.default__generate_database_name\", \"macro_sql\": \"{% macro default__generate_database_name(custom_database_name=none, node=none) -%}\\n    {%- set default_database = target.database -%}\\n    {%- if custom_database_name is none -%}\\n\\n        {{ default_database }}\\n\\n    {%- else -%}\\n\\n        {{ custom_database_name }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.6631, \"supported_languages\": null}, \"macro.dbt.default__test_relationships\": {\"name\": \"default__test_relationships\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/generic_test_sql/relationships.sql\", \"original_file_path\": \"macros/generic_test_sql/relationships.sql\", \"unique_id\": \"macro.dbt.default__test_relationships\", \"macro_sql\": \"{% macro default__test_relationships(model, column_name, to, field) %}\\n\\nwith child as (\\n    select {{ column_name }} as from_field\\n    from {{ model }}\\n    where {{ column_name }} is not null\\n),\\n\\nparent as (\\n    select {{ field }} as to_field\\n    from {{ to }}\\n)\\n\\nselect\\n    from_field\\n\\nfrom child\\nleft join parent\\n    on child.from_field = parent.to_field\\n\\nwhere parent.to_field is null\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.664021, \"supported_languages\": null}, \"macro.dbt.default__test_not_null\": {\"name\": \"default__test_not_null\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/generic_test_sql/not_null.sql\", \"original_file_path\": \"macros/generic_test_sql/not_null.sql\", \"unique_id\": \"macro.dbt.default__test_not_null\", \"macro_sql\": \"{% macro default__test_not_null(model, column_name) %}\\n\\n{% set column_list = '*' if should_store_failures() else column_name %}\\n\\nselect {{ column_list }}\\nfrom {{ model }}\\nwhere {{ column_name }} is null\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.should_store_failures\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.664862, \"supported_languages\": null}, \"macro.dbt.default__test_unique\": {\"name\": \"default__test_unique\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/generic_test_sql/unique.sql\", \"original_file_path\": \"macros/generic_test_sql/unique.sql\", \"unique_id\": \"macro.dbt.default__test_unique\", \"macro_sql\": \"{% macro default__test_unique(model, column_name) %}\\n\\nselect\\n    {{ column_name }} as unique_field,\\n    count(*) as n_records\\n\\nfrom {{ model }}\\nwhere {{ column_name }} is not null\\ngroup by {{ column_name }}\\nhaving count(*) > 1\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.665466, \"supported_languages\": null}, \"macro.dbt.default__test_accepted_values\": {\"name\": \"default__test_accepted_values\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/generic_test_sql/accepted_values.sql\", \"original_file_path\": \"macros/generic_test_sql/accepted_values.sql\", \"unique_id\": \"macro.dbt.default__test_accepted_values\", \"macro_sql\": \"{% macro default__test_accepted_values(model, column_name, values, quote=True) %}\\n\\nwith all_values as (\\n\\n    select\\n        {{ column_name }} as value_field,\\n        count(*) as n_records\\n\\n    from {{ model }}\\n    group by {{ column_name }}\\n\\n)\\n\\nselect *\\nfrom all_values\\nwhere value_field not in (\\n    {% for value in values -%}\\n        {% if quote -%}\\n        '{{ value }}'\\n        {%- else -%}\\n        {{ value }}\\n        {%- endif -%}\\n        {%- if not loop.last -%},{%- endif %}\\n    {%- endfor %}\\n)\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.666805, \"supported_languages\": null}, \"macro.dbt.statement\": {\"name\": \"statement\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/etc/statement.sql\", \"original_file_path\": \"macros/etc/statement.sql\", \"unique_id\": \"macro.dbt.statement\", \"macro_sql\": \"\\n{%- macro statement(name=None, fetch_result=False, auto_begin=True, language='sql') -%}\\n  {%- if execute: -%}\\n    {%- set compiled_code = caller() -%}\\n\\n    {%- if name == 'main' -%}\\n      {{ log('Writing runtime {} for node \\\"{}\\\"'.format(language, model['unique_id'])) }}\\n      {{ write(compiled_code) }}\\n    {%- endif -%}\\n    {%- if language == 'sql'-%}\\n      {%- set res, table = adapter.execute(compiled_code, auto_begin=auto_begin, fetch=fetch_result) -%}\\n    {%- elif language == 'python' -%}\\n      {%- set res = submit_python_job(model, compiled_code) -%}\\n      {#-- TODO: What should table be for python models? --#}\\n      {%- set table = None -%}\\n    {%- else -%}\\n      {% do exceptions.raise_compiler_error(\\\"statement macro didn't get supported language\\\") %}\\n    {%- endif -%}\\n\\n    {%- if name is not none -%}\\n      {{ store_result(name, response=res, agate_table=table) }}\\n    {%- endif -%}\\n\\n  {%- endif -%}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.670157, \"supported_languages\": null}, \"macro.dbt.noop_statement\": {\"name\": \"noop_statement\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/etc/statement.sql\", \"original_file_path\": \"macros/etc/statement.sql\", \"unique_id\": \"macro.dbt.noop_statement\", \"macro_sql\": \"{% macro noop_statement(name=None, message=None, code=None, rows_affected=None, res=None) -%}\\n  {%- set sql = caller() -%}\\n\\n  {%- if name == 'main' -%}\\n    {{ log('Writing runtime SQL for node \\\"{}\\\"'.format(model['unique_id'])) }}\\n    {{ write(sql) }}\\n  {%- endif -%}\\n\\n  {%- if name is not none -%}\\n    {{ store_raw_result(name, message=message, code=code, rows_affected=rows_affected, agate_table=res) }}\\n  {%- endif -%}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.671575, \"supported_languages\": null}, \"macro.dbt.run_query\": {\"name\": \"run_query\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/etc/statement.sql\", \"original_file_path\": \"macros/etc/statement.sql\", \"unique_id\": \"macro.dbt.run_query\", \"macro_sql\": \"{% macro run_query(sql) %}\\n  {% call statement(\\\"run_query_statement\\\", fetch_result=true, auto_begin=false) %}\\n    {{ sql }}\\n  {% endcall %}\\n\\n  {% do return(load_result(\\\"run_query_statement\\\").table) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.672309, \"supported_languages\": null}, \"macro.dbt.convert_datetime\": {\"name\": \"convert_datetime\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"unique_id\": \"macro.dbt.convert_datetime\", \"macro_sql\": \"{% macro convert_datetime(date_str, date_fmt) %}\\n\\n  {% set error_msg -%}\\n      The provided partition date '{{ date_str }}' does not match the expected format '{{ date_fmt }}'\\n  {%- endset %}\\n\\n  {% set res = try_or_compiler_error(error_msg, modules.datetime.datetime.strptime, date_str.strip(), date_fmt) %}\\n  {{ return(res) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.675864, \"supported_languages\": null}, \"macro.dbt.dates_in_range\": {\"name\": \"dates_in_range\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"unique_id\": \"macro.dbt.dates_in_range\", \"macro_sql\": \"{% macro dates_in_range(start_date_str, end_date_str=none, in_fmt=\\\"%Y%m%d\\\", out_fmt=\\\"%Y%m%d\\\") %}\\n    {% set end_date_str = start_date_str if end_date_str is none else end_date_str %}\\n\\n    {% set start_date = convert_datetime(start_date_str, in_fmt) %}\\n    {% set end_date = convert_datetime(end_date_str, in_fmt) %}\\n\\n    {% set day_count = (end_date - start_date).days %}\\n    {% if day_count < 0 %}\\n        {% set msg -%}\\n            Partition start date is after the end date ({{ start_date }}, {{ end_date }})\\n        {%- endset %}\\n\\n        {{ exceptions.raise_compiler_error(msg, model) }}\\n    {% endif %}\\n\\n    {% set date_list = [] %}\\n    {% for i in range(0, day_count + 1) %}\\n        {% set the_date = (modules.datetime.timedelta(days=i) + start_date) %}\\n        {% if not out_fmt %}\\n            {% set _ = date_list.append(the_date) %}\\n        {% else %}\\n            {% set _ = date_list.append(the_date.strftime(out_fmt)) %}\\n        {% endif %}\\n    {% endfor %}\\n\\n    {{ return(date_list) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.convert_datetime\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.678925, \"supported_languages\": null}, \"macro.dbt.partition_range\": {\"name\": \"partition_range\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"unique_id\": \"macro.dbt.partition_range\", \"macro_sql\": \"{% macro partition_range(raw_partition_date, date_fmt='%Y%m%d') %}\\n    {% set partition_range = (raw_partition_date | string).split(\\\",\\\") %}\\n\\n    {% if (partition_range | length) == 1 %}\\n      {% set start_date = partition_range[0] %}\\n      {% set end_date = none %}\\n    {% elif (partition_range | length) == 2 %}\\n      {% set start_date = partition_range[0] %}\\n      {% set end_date = partition_range[1] %}\\n    {% else %}\\n      {{ exceptions.raise_compiler_error(\\\"Invalid partition time. Expected format: {Start Date}[,{End Date}]. Got: \\\" ~ raw_partition_date) }}\\n    {% endif %}\\n\\n    {{ return(dates_in_range(start_date, end_date, in_fmt=date_fmt)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.dates_in_range\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.680963, \"supported_languages\": null}, \"macro.dbt.py_current_timestring\": {\"name\": \"py_current_timestring\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"unique_id\": \"macro.dbt.py_current_timestring\", \"macro_sql\": \"{% macro py_current_timestring() %}\\n    {% set dt = modules.datetime.datetime.now() %}\\n    {% do return(dt.strftime(\\\"%Y%m%d%H%M%S%f\\\")) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.681591, \"supported_languages\": null}, \"macro.dbt.except\": {\"name\": \"except\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/except.sql\", \"original_file_path\": \"macros/utils/except.sql\", \"unique_id\": \"macro.dbt.except\", \"macro_sql\": \"{% macro except() %}\\n  {{ return(adapter.dispatch('except', 'dbt')()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__except\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.682165, \"supported_languages\": null}, \"macro.dbt.default__except\": {\"name\": \"default__except\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/except.sql\", \"original_file_path\": \"macros/utils/except.sql\", \"unique_id\": \"macro.dbt.default__except\", \"macro_sql\": \"{% macro default__except() %}\\n\\n    except\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.682366, \"supported_languages\": null}, \"macro.dbt.replace\": {\"name\": \"replace\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/replace.sql\", \"original_file_path\": \"macros/utils/replace.sql\", \"unique_id\": \"macro.dbt.replace\", \"macro_sql\": \"{% macro replace(field, old_chars, new_chars) -%}\\n    {{ return(adapter.dispatch('replace', 'dbt') (field, old_chars, new_chars)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__replace\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.6831412, \"supported_languages\": null}, \"macro.dbt.default__replace\": {\"name\": \"default__replace\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/replace.sql\", \"original_file_path\": \"macros/utils/replace.sql\", \"unique_id\": \"macro.dbt.default__replace\", \"macro_sql\": \"{% macro default__replace(field, old_chars, new_chars) %}\\n\\n    replace(\\n        {{ field }},\\n        {{ old_chars }},\\n        {{ new_chars }}\\n    )\\n\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.683658, \"supported_languages\": null}, \"macro.dbt.concat\": {\"name\": \"concat\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/concat.sql\", \"original_file_path\": \"macros/utils/concat.sql\", \"unique_id\": \"macro.dbt.concat\", \"macro_sql\": \"{% macro concat(fields) -%}\\n  {{ return(adapter.dispatch('concat', 'dbt')(fields)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__concat\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.684277, \"supported_languages\": null}, \"macro.dbt.default__concat\": {\"name\": \"default__concat\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/concat.sql\", \"original_file_path\": \"macros/utils/concat.sql\", \"unique_id\": \"macro.dbt.default__concat\", \"macro_sql\": \"{% macro default__concat(fields) -%}\\n    {{ fields|join(' || ') }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.6846101, \"supported_languages\": null}, \"macro.dbt.length\": {\"name\": \"length\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/length.sql\", \"original_file_path\": \"macros/utils/length.sql\", \"unique_id\": \"macro.dbt.length\", \"macro_sql\": \"{% macro length(expression) -%}\\n    {{ return(adapter.dispatch('length', 'dbt') (expression)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__length\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.685228, \"supported_languages\": null}, \"macro.dbt.default__length\": {\"name\": \"default__length\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/length.sql\", \"original_file_path\": \"macros/utils/length.sql\", \"unique_id\": \"macro.dbt.default__length\", \"macro_sql\": \"{% macro default__length(expression) %}\\n\\n    length(\\n        {{ expression }}\\n    )\\n\\n{%- endmacro -%}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.685508, \"supported_languages\": null}, \"macro.dbt.dateadd\": {\"name\": \"dateadd\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/dateadd.sql\", \"original_file_path\": \"macros/utils/dateadd.sql\", \"unique_id\": \"macro.dbt.dateadd\", \"macro_sql\": \"{% macro dateadd(datepart, interval, from_date_or_timestamp) %}\\n  {{ return(adapter.dispatch('dateadd', 'dbt')(datepart, interval, from_date_or_timestamp)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__dateadd\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.6863098, \"supported_languages\": null}, \"macro.dbt.default__dateadd\": {\"name\": \"default__dateadd\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/dateadd.sql\", \"original_file_path\": \"macros/utils/dateadd.sql\", \"unique_id\": \"macro.dbt.default__dateadd\", \"macro_sql\": \"{% macro default__dateadd(datepart, interval, from_date_or_timestamp) %}\\n\\n    dateadd(\\n        {{ datepart }},\\n        {{ interval }},\\n        {{ from_date_or_timestamp }}\\n        )\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.6870232, \"supported_languages\": null}, \"macro.dbt.intersect\": {\"name\": \"intersect\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/intersect.sql\", \"original_file_path\": \"macros/utils/intersect.sql\", \"unique_id\": \"macro.dbt.intersect\", \"macro_sql\": \"{% macro intersect() %}\\n  {{ return(adapter.dispatch('intersect', 'dbt')()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__intersect\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.687619, \"supported_languages\": null}, \"macro.dbt.default__intersect\": {\"name\": \"default__intersect\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/intersect.sql\", \"original_file_path\": \"macros/utils/intersect.sql\", \"unique_id\": \"macro.dbt.default__intersect\", \"macro_sql\": \"{% macro default__intersect() %}\\n\\n    intersect\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.6878238, \"supported_languages\": null}, \"macro.dbt.escape_single_quotes\": {\"name\": \"escape_single_quotes\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/escape_single_quotes.sql\", \"original_file_path\": \"macros/utils/escape_single_quotes.sql\", \"unique_id\": \"macro.dbt.escape_single_quotes\", \"macro_sql\": \"{% macro escape_single_quotes(expression) %}\\n      {{ return(adapter.dispatch('escape_single_quotes', 'dbt') (expression)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__escape_single_quotes\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.688459, \"supported_languages\": null}, \"macro.dbt.default__escape_single_quotes\": {\"name\": \"default__escape_single_quotes\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/escape_single_quotes.sql\", \"original_file_path\": \"macros/utils/escape_single_quotes.sql\", \"unique_id\": \"macro.dbt.default__escape_single_quotes\", \"macro_sql\": \"{% macro default__escape_single_quotes(expression) -%}\\n{{ expression | replace(\\\"'\\\",\\\"''\\\") }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.688828, \"supported_languages\": null}, \"macro.dbt.right\": {\"name\": \"right\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/right.sql\", \"original_file_path\": \"macros/utils/right.sql\", \"unique_id\": \"macro.dbt.right\", \"macro_sql\": \"{% macro right(string_text, length_expression) -%}\\n    {{ return(adapter.dispatch('right', 'dbt') (string_text, length_expression)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__right\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.689515, \"supported_languages\": null}, \"macro.dbt.default__right\": {\"name\": \"default__right\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/right.sql\", \"original_file_path\": \"macros/utils/right.sql\", \"unique_id\": \"macro.dbt.default__right\", \"macro_sql\": \"{% macro default__right(string_text, length_expression) %}\\n\\n    right(\\n        {{ string_text }},\\n        {{ length_expression }}\\n    )\\n\\n{%- endmacro -%}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.689863, \"supported_languages\": null}, \"macro.dbt.listagg\": {\"name\": \"listagg\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/listagg.sql\", \"original_file_path\": \"macros/utils/listagg.sql\", \"unique_id\": \"macro.dbt.listagg\", \"macro_sql\": \"{% macro listagg(measure, delimiter_text=\\\"','\\\", order_by_clause=none, limit_num=none) -%}\\n    {{ return(adapter.dispatch('listagg', 'dbt') (measure, delimiter_text, order_by_clause, limit_num)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__listagg\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.691304, \"supported_languages\": null}, \"macro.dbt.default__listagg\": {\"name\": \"default__listagg\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/listagg.sql\", \"original_file_path\": \"macros/utils/listagg.sql\", \"unique_id\": \"macro.dbt.default__listagg\", \"macro_sql\": \"{% macro default__listagg(measure, delimiter_text, order_by_clause, limit_num) -%}\\n\\n    {% if limit_num -%}\\n    array_to_string(\\n        array_slice(\\n            array_agg(\\n                {{ measure }}\\n            ){% if order_by_clause -%}\\n            within group ({{ order_by_clause }})\\n            {%- endif %}\\n            ,0\\n            ,{{ limit_num }}\\n        ),\\n        {{ delimiter_text }}\\n        )\\n    {%- else %}\\n    listagg(\\n        {{ measure }},\\n        {{ delimiter_text }}\\n        )\\n        {% if order_by_clause -%}\\n        within group ({{ order_by_clause }})\\n        {%- endif %}\\n    {%- endif %}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.6924748, \"supported_languages\": null}, \"macro.dbt.datediff\": {\"name\": \"datediff\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/datediff.sql\", \"original_file_path\": \"macros/utils/datediff.sql\", \"unique_id\": \"macro.dbt.datediff\", \"macro_sql\": \"{% macro datediff(first_date, second_date, datepart) %}\\n  {{ return(adapter.dispatch('datediff', 'dbt')(first_date, second_date, datepart)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__datediff\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.693249, \"supported_languages\": null}, \"macro.dbt.default__datediff\": {\"name\": \"default__datediff\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/datediff.sql\", \"original_file_path\": \"macros/utils/datediff.sql\", \"unique_id\": \"macro.dbt.default__datediff\", \"macro_sql\": \"{% macro default__datediff(first_date, second_date, datepart) -%}\\n\\n    datediff(\\n        {{ datepart }},\\n        {{ first_date }},\\n        {{ second_date }}\\n        )\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.69366, \"supported_languages\": null}, \"macro.dbt.safe_cast\": {\"name\": \"safe_cast\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/safe_cast.sql\", \"original_file_path\": \"macros/utils/safe_cast.sql\", \"unique_id\": \"macro.dbt.safe_cast\", \"macro_sql\": \"{% macro safe_cast(field, type) %}\\n  {{ return(adapter.dispatch('safe_cast', 'dbt') (field, type)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__safe_cast\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.694339, \"supported_languages\": null}, \"macro.dbt.default__safe_cast\": {\"name\": \"default__safe_cast\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/safe_cast.sql\", \"original_file_path\": \"macros/utils/safe_cast.sql\", \"unique_id\": \"macro.dbt.default__safe_cast\", \"macro_sql\": \"{% macro default__safe_cast(field, type) %}\\n    {# most databases don't support this function yet\\n    so we just need to use cast #}\\n    cast({{field}} as {{type}})\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.6946921, \"supported_languages\": null}, \"macro.dbt.hash\": {\"name\": \"hash\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/hash.sql\", \"original_file_path\": \"macros/utils/hash.sql\", \"unique_id\": \"macro.dbt.hash\", \"macro_sql\": \"{% macro hash(field) -%}\\n  {{ return(adapter.dispatch('hash', 'dbt') (field)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__hash\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.695292, \"supported_languages\": null}, \"macro.dbt.default__hash\": {\"name\": \"default__hash\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/hash.sql\", \"original_file_path\": \"macros/utils/hash.sql\", \"unique_id\": \"macro.dbt.default__hash\", \"macro_sql\": \"{% macro default__hash(field) -%}\\n    md5(cast({{ field }} as {{ api.Column.translate_type('string') }}))\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.695692, \"supported_languages\": null}, \"macro.dbt.cast_bool_to_text\": {\"name\": \"cast_bool_to_text\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/cast_bool_to_text.sql\", \"original_file_path\": \"macros/utils/cast_bool_to_text.sql\", \"unique_id\": \"macro.dbt.cast_bool_to_text\", \"macro_sql\": \"{% macro cast_bool_to_text(field) %}\\n  {{ adapter.dispatch('cast_bool_to_text', 'dbt') (field) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__cast_bool_to_text\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.696287, \"supported_languages\": null}, \"macro.dbt.default__cast_bool_to_text\": {\"name\": \"default__cast_bool_to_text\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/cast_bool_to_text.sql\", \"original_file_path\": \"macros/utils/cast_bool_to_text.sql\", \"unique_id\": \"macro.dbt.default__cast_bool_to_text\", \"macro_sql\": \"{% macro default__cast_bool_to_text(field) %}\\n    cast({{ field }} as {{ api.Column.translate_type('string') }})\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.696754, \"supported_languages\": null}, \"macro.dbt.any_value\": {\"name\": \"any_value\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/any_value.sql\", \"original_file_path\": \"macros/utils/any_value.sql\", \"unique_id\": \"macro.dbt.any_value\", \"macro_sql\": \"{% macro any_value(expression) -%}\\n    {{ return(adapter.dispatch('any_value', 'dbt') (expression)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__any_value\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.697381, \"supported_languages\": null}, \"macro.dbt.default__any_value\": {\"name\": \"default__any_value\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/any_value.sql\", \"original_file_path\": \"macros/utils/any_value.sql\", \"unique_id\": \"macro.dbt.default__any_value\", \"macro_sql\": \"{% macro default__any_value(expression) -%}\\n\\n    any_value({{ expression }})\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.6978078, \"supported_languages\": null}, \"macro.dbt.position\": {\"name\": \"position\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/position.sql\", \"original_file_path\": \"macros/utils/position.sql\", \"unique_id\": \"macro.dbt.position\", \"macro_sql\": \"{% macro position(substring_text, string_text) -%}\\n    {{ return(adapter.dispatch('position', 'dbt') (substring_text, string_text)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__position\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.698524, \"supported_languages\": null}, \"macro.dbt.default__position\": {\"name\": \"default__position\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/position.sql\", \"original_file_path\": \"macros/utils/position.sql\", \"unique_id\": \"macro.dbt.default__position\", \"macro_sql\": \"{% macro default__position(substring_text, string_text) %}\\n\\n    position(\\n        {{ substring_text }} in {{ string_text }}\\n    )\\n\\n{%- endmacro -%}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.6990662, \"supported_languages\": null}, \"macro.dbt.string_literal\": {\"name\": \"string_literal\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/literal.sql\", \"original_file_path\": \"macros/utils/literal.sql\", \"unique_id\": \"macro.dbt.string_literal\", \"macro_sql\": \"{%- macro string_literal(value) -%}\\n  {{ return(adapter.dispatch('string_literal', 'dbt') (value)) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__string_literal\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.69984, \"supported_languages\": null}, \"macro.dbt.default__string_literal\": {\"name\": \"default__string_literal\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/literal.sql\", \"original_file_path\": \"macros/utils/literal.sql\", \"unique_id\": \"macro.dbt.default__string_literal\", \"macro_sql\": \"{% macro default__string_literal(value) -%}\\n    '{{ value }}'\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.700127, \"supported_languages\": null}, \"macro.dbt.type_string\": {\"name\": \"type_string\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.type_string\", \"macro_sql\": \"\\n\\n{%- macro type_string() -%}\\n  {{ return(adapter.dispatch('type_string', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__type_string\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.702124, \"supported_languages\": null}, \"macro.dbt.default__type_string\": {\"name\": \"default__type_string\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.default__type_string\", \"macro_sql\": \"{% macro default__type_string() %}\\n    {{ return(api.Column.translate_type(\\\"string\\\")) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.702521, \"supported_languages\": null}, \"macro.dbt.type_timestamp\": {\"name\": \"type_timestamp\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.type_timestamp\", \"macro_sql\": \"\\n\\n{%- macro type_timestamp() -%}\\n  {{ return(adapter.dispatch('type_timestamp', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__type_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.702935, \"supported_languages\": null}, \"macro.dbt.default__type_timestamp\": {\"name\": \"default__type_timestamp\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.default__type_timestamp\", \"macro_sql\": \"{% macro default__type_timestamp() %}\\n    {{ return(api.Column.translate_type(\\\"timestamp\\\")) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.703326, \"supported_languages\": null}, \"macro.dbt.type_float\": {\"name\": \"type_float\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.type_float\", \"macro_sql\": \"\\n\\n{%- macro type_float() -%}\\n  {{ return(adapter.dispatch('type_float', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__type_float\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.703733, \"supported_languages\": null}, \"macro.dbt.default__type_float\": {\"name\": \"default__type_float\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.default__type_float\", \"macro_sql\": \"{% macro default__type_float() %}\\n    {{ return(api.Column.translate_type(\\\"float\\\")) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.704247, \"supported_languages\": null}, \"macro.dbt.type_numeric\": {\"name\": \"type_numeric\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.type_numeric\", \"macro_sql\": \"\\n\\n{%- macro type_numeric() -%}\\n  {{ return(adapter.dispatch('type_numeric', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__type_numeric\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.7046552, \"supported_languages\": null}, \"macro.dbt.default__type_numeric\": {\"name\": \"default__type_numeric\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.default__type_numeric\", \"macro_sql\": \"{% macro default__type_numeric() %}\\n    {{ return(api.Column.numeric_type(\\\"numeric\\\", 28, 6)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.705098, \"supported_languages\": null}, \"macro.dbt.type_bigint\": {\"name\": \"type_bigint\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.type_bigint\", \"macro_sql\": \"\\n\\n{%- macro type_bigint() -%}\\n  {{ return(adapter.dispatch('type_bigint', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__type_bigint\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.705503, \"supported_languages\": null}, \"macro.dbt.default__type_bigint\": {\"name\": \"default__type_bigint\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.default__type_bigint\", \"macro_sql\": \"{% macro default__type_bigint() %}\\n    {{ return(api.Column.translate_type(\\\"bigint\\\")) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.705885, \"supported_languages\": null}, \"macro.dbt.type_int\": {\"name\": \"type_int\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.type_int\", \"macro_sql\": \"\\n\\n{%- macro type_int() -%}\\n  {{ return(adapter.dispatch('type_int', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__type_int\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.7063448, \"supported_languages\": null}, \"macro.dbt.default__type_int\": {\"name\": \"default__type_int\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.default__type_int\", \"macro_sql\": \"{%- macro default__type_int() -%}\\n  {{ return(api.Column.translate_type(\\\"integer\\\")) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.7067552, \"supported_languages\": null}, \"macro.dbt.type_boolean\": {\"name\": \"type_boolean\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.type_boolean\", \"macro_sql\": \"\\n\\n{%- macro type_boolean() -%}\\n  {{ return(adapter.dispatch('type_boolean', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__type_boolean\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.7071831, \"supported_languages\": null}, \"macro.dbt.default__type_boolean\": {\"name\": \"default__type_boolean\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.default__type_boolean\", \"macro_sql\": \"{%- macro default__type_boolean() -%}\\n  {{ return(api.Column.translate_type(\\\"boolean\\\")) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.707561, \"supported_languages\": null}, \"macro.dbt.array_concat\": {\"name\": \"array_concat\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/array_concat.sql\", \"original_file_path\": \"macros/utils/array_concat.sql\", \"unique_id\": \"macro.dbt.array_concat\", \"macro_sql\": \"{% macro array_concat(array_1, array_2) -%}\\n  {{ return(adapter.dispatch('array_concat', 'dbt')(array_1, array_2)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__array_concat\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.708241, \"supported_languages\": null}, \"macro.dbt.default__array_concat\": {\"name\": \"default__array_concat\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/array_concat.sql\", \"original_file_path\": \"macros/utils/array_concat.sql\", \"unique_id\": \"macro.dbt.default__array_concat\", \"macro_sql\": \"{% macro default__array_concat(array_1, array_2) -%}\\n    array_cat({{ array_1 }}, {{ array_2 }})\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.7085838, \"supported_languages\": null}, \"macro.dbt.bool_or\": {\"name\": \"bool_or\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/bool_or.sql\", \"original_file_path\": \"macros/utils/bool_or.sql\", \"unique_id\": \"macro.dbt.bool_or\", \"macro_sql\": \"{% macro bool_or(expression) -%}\\n    {{ return(adapter.dispatch('bool_or', 'dbt') (expression)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__bool_or\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.709186, \"supported_languages\": null}, \"macro.dbt.default__bool_or\": {\"name\": \"default__bool_or\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/bool_or.sql\", \"original_file_path\": \"macros/utils/bool_or.sql\", \"unique_id\": \"macro.dbt.default__bool_or\", \"macro_sql\": \"{% macro default__bool_or(expression) -%}\\n\\n    bool_or({{ expression }})\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.7094588, \"supported_languages\": null}, \"macro.dbt.last_day\": {\"name\": \"last_day\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/last_day.sql\", \"original_file_path\": \"macros/utils/last_day.sql\", \"unique_id\": \"macro.dbt.last_day\", \"macro_sql\": \"{% macro last_day(date, datepart) %}\\n  {{ return(adapter.dispatch('last_day', 'dbt') (date, datepart)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__last_day\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.7102468, \"supported_languages\": null}, \"macro.dbt.default_last_day\": {\"name\": \"default_last_day\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/last_day.sql\", \"original_file_path\": \"macros/utils/last_day.sql\", \"unique_id\": \"macro.dbt.default_last_day\", \"macro_sql\": \"\\n\\n{%- macro default_last_day(date, datepart) -%}\\n    cast(\\n        {{dbt.dateadd('day', '-1',\\n        dbt.dateadd(datepart, '1', dbt.date_trunc(datepart, date))\\n        )}}\\n        as date)\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.dateadd\", \"macro.dbt.date_trunc\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.710925, \"supported_languages\": null}, \"macro.dbt.default__last_day\": {\"name\": \"default__last_day\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/last_day.sql\", \"original_file_path\": \"macros/utils/last_day.sql\", \"unique_id\": \"macro.dbt.default__last_day\", \"macro_sql\": \"{% macro default__last_day(date, datepart) -%}\\n    {{dbt.default_last_day(date, datepart)}}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default_last_day\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.711309, \"supported_languages\": null}, \"macro.dbt.split_part\": {\"name\": \"split_part\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/split_part.sql\", \"original_file_path\": \"macros/utils/split_part.sql\", \"unique_id\": \"macro.dbt.split_part\", \"macro_sql\": \"{% macro split_part(string_text, delimiter_text, part_number) %}\\n  {{ return(adapter.dispatch('split_part', 'dbt') (string_text, delimiter_text, part_number)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__split_part\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.712547, \"supported_languages\": null}, \"macro.dbt.default__split_part\": {\"name\": \"default__split_part\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/split_part.sql\", \"original_file_path\": \"macros/utils/split_part.sql\", \"unique_id\": \"macro.dbt.default__split_part\", \"macro_sql\": \"{% macro default__split_part(string_text, delimiter_text, part_number) %}\\n\\n    split_part(\\n        {{ string_text }},\\n        {{ delimiter_text }},\\n        {{ part_number }}\\n        )\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.71298, \"supported_languages\": null}, \"macro.dbt._split_part_negative\": {\"name\": \"_split_part_negative\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/split_part.sql\", \"original_file_path\": \"macros/utils/split_part.sql\", \"unique_id\": \"macro.dbt._split_part_negative\", \"macro_sql\": \"{% macro _split_part_negative(string_text, delimiter_text, part_number) %}\\n\\n    split_part(\\n        {{ string_text }},\\n        {{ delimiter_text }},\\n          length({{ string_text }})\\n          - length(\\n              replace({{ string_text }},  {{ delimiter_text }}, '')\\n          ) + 2 {{ part_number }}\\n        )\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.713571, \"supported_languages\": null}, \"macro.dbt.date_trunc\": {\"name\": \"date_trunc\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/date_trunc.sql\", \"original_file_path\": \"macros/utils/date_trunc.sql\", \"unique_id\": \"macro.dbt.date_trunc\", \"macro_sql\": \"{% macro date_trunc(datepart, date) -%}\\n  {{ return(adapter.dispatch('date_trunc', 'dbt') (datepart, date)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__date_trunc\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.714258, \"supported_languages\": null}, \"macro.dbt.default__date_trunc\": {\"name\": \"default__date_trunc\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/date_trunc.sql\", \"original_file_path\": \"macros/utils/date_trunc.sql\", \"unique_id\": \"macro.dbt.default__date_trunc\", \"macro_sql\": \"{% macro default__date_trunc(datepart, date) -%}\\n    date_trunc('{{datepart}}', {{date}})\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.714612, \"supported_languages\": null}, \"macro.dbt.array_construct\": {\"name\": \"array_construct\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/array_construct.sql\", \"original_file_path\": \"macros/utils/array_construct.sql\", \"unique_id\": \"macro.dbt.array_construct\", \"macro_sql\": \"{% macro array_construct(inputs=[], data_type=api.Column.translate_type('integer')) -%}\\n  {{ return(adapter.dispatch('array_construct', 'dbt')(inputs, data_type)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__array_construct\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.7155101, \"supported_languages\": null}, \"macro.dbt.default__array_construct\": {\"name\": \"default__array_construct\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/array_construct.sql\", \"original_file_path\": \"macros/utils/array_construct.sql\", \"unique_id\": \"macro.dbt.default__array_construct\", \"macro_sql\": \"{% macro default__array_construct(inputs, data_type) -%}\\n    {% if inputs|length > 0 %}\\n    array[ {{ inputs|join(' , ') }} ]\\n    {% else %}\\n    array[]::{{data_type}}[]\\n    {% endif %}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.716278, \"supported_languages\": null}, \"macro.dbt.array_append\": {\"name\": \"array_append\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/array_append.sql\", \"original_file_path\": \"macros/utils/array_append.sql\", \"unique_id\": \"macro.dbt.array_append\", \"macro_sql\": \"{% macro array_append(array, new_element) -%}\\n  {{ return(adapter.dispatch('array_append', 'dbt')(array, new_element)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__array_append\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.7171369, \"supported_languages\": null}, \"macro.dbt.default__array_append\": {\"name\": \"default__array_append\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/array_append.sql\", \"original_file_path\": \"macros/utils/array_append.sql\", \"unique_id\": \"macro.dbt.default__array_append\", \"macro_sql\": \"{% macro default__array_append(array, new_element) -%}\\n    array_append({{ array }}, {{ new_element }})\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.717506, \"supported_languages\": null}, \"macro.dbt.create_schema\": {\"name\": \"create_schema\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/schema.sql\", \"original_file_path\": \"macros/adapters/schema.sql\", \"unique_id\": \"macro.dbt.create_schema\", \"macro_sql\": \"{% macro create_schema(relation) -%}\\n  {{ adapter.dispatch('create_schema', 'dbt')(relation) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__create_schema\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.718344, \"supported_languages\": null}, \"macro.dbt.default__create_schema\": {\"name\": \"default__create_schema\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/schema.sql\", \"original_file_path\": \"macros/adapters/schema.sql\", \"unique_id\": \"macro.dbt.default__create_schema\", \"macro_sql\": \"{% macro default__create_schema(relation) -%}\\n  {%- call statement('create_schema') -%}\\n    create schema if not exists {{ relation.without_identifier() }}\\n  {% endcall %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.71883, \"supported_languages\": null}, \"macro.dbt.drop_schema\": {\"name\": \"drop_schema\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/schema.sql\", \"original_file_path\": \"macros/adapters/schema.sql\", \"unique_id\": \"macro.dbt.drop_schema\", \"macro_sql\": \"{% macro drop_schema(relation) -%}\\n  {{ adapter.dispatch('drop_schema', 'dbt')(relation) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__drop_schema\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.7192378, \"supported_languages\": null}, \"macro.dbt.default__drop_schema\": {\"name\": \"default__drop_schema\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/schema.sql\", \"original_file_path\": \"macros/adapters/schema.sql\", \"unique_id\": \"macro.dbt.default__drop_schema\", \"macro_sql\": \"{% macro default__drop_schema(relation) -%}\\n  {%- call statement('drop_schema') -%}\\n    drop schema if exists {{ relation.without_identifier() }} cascade\\n  {% endcall %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.719709, \"supported_languages\": null}, \"macro.dbt.current_timestamp\": {\"name\": \"current_timestamp\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"unique_id\": \"macro.dbt.current_timestamp\", \"macro_sql\": \"{%- macro current_timestamp() -%}\\n    {{ adapter.dispatch('current_timestamp', 'dbt')() }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.720729, \"supported_languages\": null}, \"macro.dbt.default__current_timestamp\": {\"name\": \"default__current_timestamp\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"unique_id\": \"macro.dbt.default__current_timestamp\", \"macro_sql\": \"{% macro default__current_timestamp() -%}\\n  {{ exceptions.raise_not_implemented(\\n    'current_timestamp macro not implemented for adapter ' + adapter.type()) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.7211258, \"supported_languages\": null}, \"macro.dbt.snapshot_get_time\": {\"name\": \"snapshot_get_time\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"unique_id\": \"macro.dbt.snapshot_get_time\", \"macro_sql\": \"\\n\\n{%- macro snapshot_get_time() -%}\\n    {{ adapter.dispatch('snapshot_get_time', 'dbt')() }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__snapshot_get_time\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.721498, \"supported_languages\": null}, \"macro.dbt.default__snapshot_get_time\": {\"name\": \"default__snapshot_get_time\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"unique_id\": \"macro.dbt.default__snapshot_get_time\", \"macro_sql\": \"{% macro default__snapshot_get_time() %}\\n    {{ current_timestamp() }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.721788, \"supported_languages\": null}, \"macro.dbt.current_timestamp_backcompat\": {\"name\": \"current_timestamp_backcompat\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"unique_id\": \"macro.dbt.current_timestamp_backcompat\", \"macro_sql\": \"{% macro current_timestamp_backcompat() %}\\n    {{ return(adapter.dispatch('current_timestamp_backcompat', 'dbt')()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__current_timestamp_backcompat\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.722215, \"supported_languages\": null}, \"macro.dbt.default__current_timestamp_backcompat\": {\"name\": \"default__current_timestamp_backcompat\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"unique_id\": \"macro.dbt.default__current_timestamp_backcompat\", \"macro_sql\": \"{% macro default__current_timestamp_backcompat() %}\\n    current_timestamp::timestamp\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.7224221, \"supported_languages\": null}, \"macro.dbt.current_timestamp_in_utc_backcompat\": {\"name\": \"current_timestamp_in_utc_backcompat\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"unique_id\": \"macro.dbt.current_timestamp_in_utc_backcompat\", \"macro_sql\": \"{% macro current_timestamp_in_utc_backcompat() %}\\n    {{ return(adapter.dispatch('current_timestamp_in_utc_backcompat', 'dbt')()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__current_timestamp_in_utc_backcompat\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.7228422, \"supported_languages\": null}, \"macro.dbt.default__current_timestamp_in_utc_backcompat\": {\"name\": \"default__current_timestamp_in_utc_backcompat\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"unique_id\": \"macro.dbt.default__current_timestamp_in_utc_backcompat\", \"macro_sql\": \"{% macro default__current_timestamp_in_utc_backcompat() %}\\n    {{ return(adapter.dispatch('current_timestamp_backcompat', 'dbt')()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.current_timestamp_backcompat\", \"macro.dbt_postgres.postgres__current_timestamp_backcompat\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.723277, \"supported_languages\": null}, \"macro.dbt.get_create_index_sql\": {\"name\": \"get_create_index_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"unique_id\": \"macro.dbt.get_create_index_sql\", \"macro_sql\": \"{% macro get_create_index_sql(relation, index_dict) -%}\\n  {{ return(adapter.dispatch('get_create_index_sql', 'dbt')(relation, index_dict)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_create_index_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.724287, \"supported_languages\": null}, \"macro.dbt.default__get_create_index_sql\": {\"name\": \"default__get_create_index_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"unique_id\": \"macro.dbt.default__get_create_index_sql\", \"macro_sql\": \"{% macro default__get_create_index_sql(relation, index_dict) -%}\\n  {% do return(None) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.7246542, \"supported_languages\": null}, \"macro.dbt.create_indexes\": {\"name\": \"create_indexes\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"unique_id\": \"macro.dbt.create_indexes\", \"macro_sql\": \"{% macro create_indexes(relation) -%}\\n  {{ adapter.dispatch('create_indexes', 'dbt')(relation) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__create_indexes\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.725062, \"supported_languages\": null}, \"macro.dbt.default__create_indexes\": {\"name\": \"default__create_indexes\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"unique_id\": \"macro.dbt.default__create_indexes\", \"macro_sql\": \"{% macro default__create_indexes(relation) -%}\\n  {%- set _indexes = config.get('indexes', default=[]) -%}\\n\\n  {% for _index_dict in _indexes %}\\n    {% set create_index_sql = get_create_index_sql(relation, _index_dict) %}\\n    {% if create_index_sql %}\\n      {% do run_query(create_index_sql) %}\\n    {% endif %}\\n  {% endfor %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_create_index_sql\", \"macro.dbt.run_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.726084, \"supported_languages\": null}, \"macro.dbt.make_intermediate_relation\": {\"name\": \"make_intermediate_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.make_intermediate_relation\", \"macro_sql\": \"{% macro make_intermediate_relation(base_relation, suffix='__dbt_tmp') %}\\n  {{ return(adapter.dispatch('make_intermediate_relation', 'dbt')(base_relation, suffix)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_intermediate_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.732279, \"supported_languages\": null}, \"macro.dbt.default__make_intermediate_relation\": {\"name\": \"default__make_intermediate_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.default__make_intermediate_relation\", \"macro_sql\": \"{% macro default__make_intermediate_relation(base_relation, suffix) %}\\n    {{ return(default__make_temp_relation(base_relation, suffix)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__make_temp_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.732851, \"supported_languages\": null}, \"macro.dbt.make_temp_relation\": {\"name\": \"make_temp_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.make_temp_relation\", \"macro_sql\": \"{% macro make_temp_relation(base_relation, suffix='__dbt_tmp') %}\\n  {{ return(adapter.dispatch('make_temp_relation', 'dbt')(base_relation, suffix)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_temp_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.7335029, \"supported_languages\": null}, \"macro.dbt.default__make_temp_relation\": {\"name\": \"default__make_temp_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.default__make_temp_relation\", \"macro_sql\": \"{% macro default__make_temp_relation(base_relation, suffix) %}\\n    {%- set temp_identifier = base_relation.identifier ~ suffix -%}\\n    {%- set temp_relation = base_relation.incorporate(\\n                                path={\\\"identifier\\\": temp_identifier}) -%}\\n\\n    {{ return(temp_relation) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.734247, \"supported_languages\": null}, \"macro.dbt.make_backup_relation\": {\"name\": \"make_backup_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.make_backup_relation\", \"macro_sql\": \"{% macro make_backup_relation(base_relation, backup_relation_type, suffix='__dbt_backup') %}\\n    {{ return(adapter.dispatch('make_backup_relation', 'dbt')(base_relation, backup_relation_type, suffix)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_backup_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.7348611, \"supported_languages\": null}, \"macro.dbt.default__make_backup_relation\": {\"name\": \"default__make_backup_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.default__make_backup_relation\", \"macro_sql\": \"{% macro default__make_backup_relation(base_relation, backup_relation_type, suffix) %}\\n    {%- set backup_identifier = base_relation.identifier ~ suffix -%}\\n    {%- set backup_relation = base_relation.incorporate(\\n                                  path={\\\"identifier\\\": backup_identifier},\\n                                  type=backup_relation_type\\n    ) -%}\\n    {{ return(backup_relation) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.7356532, \"supported_languages\": null}, \"macro.dbt.drop_relation\": {\"name\": \"drop_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.drop_relation\", \"macro_sql\": \"{% macro drop_relation(relation) -%}\\n  {{ return(adapter.dispatch('drop_relation', 'dbt')(relation)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__drop_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.7361112, \"supported_languages\": null}, \"macro.dbt.default__drop_relation\": {\"name\": \"default__drop_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.default__drop_relation\", \"macro_sql\": \"{% macro default__drop_relation(relation) -%}\\n  {% call statement('drop_relation', auto_begin=False) -%}\\n    drop {{ relation.type }} if exists {{ relation }} cascade\\n  {%- endcall %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.7366579, \"supported_languages\": null}, \"macro.dbt.truncate_relation\": {\"name\": \"truncate_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.truncate_relation\", \"macro_sql\": \"{% macro truncate_relation(relation) -%}\\n  {{ return(adapter.dispatch('truncate_relation', 'dbt')(relation)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__truncate_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.7371142, \"supported_languages\": null}, \"macro.dbt.default__truncate_relation\": {\"name\": \"default__truncate_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.default__truncate_relation\", \"macro_sql\": \"{% macro default__truncate_relation(relation) -%}\\n  {% call statement('truncate_relation') -%}\\n    truncate table {{ relation }}\\n  {%- endcall %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.737532, \"supported_languages\": null}, \"macro.dbt.rename_relation\": {\"name\": \"rename_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.rename_relation\", \"macro_sql\": \"{% macro rename_relation(from_relation, to_relation) -%}\\n  {{ return(adapter.dispatch('rename_relation', 'dbt')(from_relation, to_relation)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__rename_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.738038, \"supported_languages\": null}, \"macro.dbt.default__rename_relation\": {\"name\": \"default__rename_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.default__rename_relation\", \"macro_sql\": \"{% macro default__rename_relation(from_relation, to_relation) -%}\\n  {% set target_name = adapter.quote_as_configured(to_relation.identifier, 'identifier') %}\\n  {% call statement('rename_relation') -%}\\n    alter table {{ from_relation }} rename to {{ target_name }}\\n  {%- endcall %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.7387478, \"supported_languages\": null}, \"macro.dbt.get_or_create_relation\": {\"name\": \"get_or_create_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.get_or_create_relation\", \"macro_sql\": \"{% macro get_or_create_relation(database, schema, identifier, type) -%}\\n  {{ return(adapter.dispatch('get_or_create_relation', 'dbt')(database, schema, identifier, type)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_or_create_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.7393658, \"supported_languages\": null}, \"macro.dbt.default__get_or_create_relation\": {\"name\": \"default__get_or_create_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.default__get_or_create_relation\", \"macro_sql\": \"{% macro default__get_or_create_relation(database, schema, identifier, type) %}\\n  {%- set target_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) %}\\n\\n  {% if target_relation %}\\n    {% do return([true, target_relation]) %}\\n  {% endif %}\\n\\n  {%- set new_relation = api.Relation.create(\\n      database=database,\\n      schema=schema,\\n      identifier=identifier,\\n      type=type\\n  ) -%}\\n  {% do return([false, new_relation]) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.740736, \"supported_languages\": null}, \"macro.dbt.load_cached_relation\": {\"name\": \"load_cached_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.load_cached_relation\", \"macro_sql\": \"{% macro load_cached_relation(relation) %}\\n  {% do return(adapter.get_relation(\\n    database=relation.database,\\n    schema=relation.schema,\\n    identifier=relation.identifier\\n  )) -%}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.741308, \"supported_languages\": null}, \"macro.dbt.load_relation\": {\"name\": \"load_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.load_relation\", \"macro_sql\": \"{% macro load_relation(relation) %}\\n    {{ return(load_cached_relation(relation)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.load_cached_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.741668, \"supported_languages\": null}, \"macro.dbt.drop_relation_if_exists\": {\"name\": \"drop_relation_if_exists\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.drop_relation_if_exists\", \"macro_sql\": \"{% macro drop_relation_if_exists(relation) %}\\n  {% if relation is not none %}\\n    {{ adapter.drop_relation(relation) }}\\n  {% endif %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.7421598, \"supported_languages\": null}, \"macro.dbt.collect_freshness\": {\"name\": \"collect_freshness\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/freshness.sql\", \"original_file_path\": \"macros/adapters/freshness.sql\", \"unique_id\": \"macro.dbt.collect_freshness\", \"macro_sql\": \"{% macro collect_freshness(source, loaded_at_field, filter) %}\\n  {{ return(adapter.dispatch('collect_freshness', 'dbt')(source, loaded_at_field, filter))}}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__collect_freshness\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.743146, \"supported_languages\": null}, \"macro.dbt.default__collect_freshness\": {\"name\": \"default__collect_freshness\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/freshness.sql\", \"original_file_path\": \"macros/adapters/freshness.sql\", \"unique_id\": \"macro.dbt.default__collect_freshness\", \"macro_sql\": \"{% macro default__collect_freshness(source, loaded_at_field, filter) %}\\n  {% call statement('collect_freshness', fetch_result=True, auto_begin=False) -%}\\n    select\\n      max({{ loaded_at_field }}) as max_loaded_at,\\n      {{ current_timestamp() }} as snapshotted_at\\n    from {{ source }}\\n    {% if filter %}\\n    where {{ filter }}\\n    {% endif %}\\n  {% endcall %}\\n  {{ return(load_result('collect_freshness')) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\", \"macro.dbt.current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.7441761, \"supported_languages\": null}, \"macro.dbt.copy_grants\": {\"name\": \"copy_grants\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.copy_grants\", \"macro_sql\": \"{% macro copy_grants() %}\\n    {{ return(adapter.dispatch('copy_grants', 'dbt')()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__copy_grants\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.7475011, \"supported_languages\": null}, \"macro.dbt.default__copy_grants\": {\"name\": \"default__copy_grants\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.default__copy_grants\", \"macro_sql\": \"{% macro default__copy_grants() %}\\n    {{ return(True) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.7478158, \"supported_languages\": null}, \"macro.dbt.support_multiple_grantees_per_dcl_statement\": {\"name\": \"support_multiple_grantees_per_dcl_statement\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.support_multiple_grantees_per_dcl_statement\", \"macro_sql\": \"{% macro support_multiple_grantees_per_dcl_statement() %}\\n    {{ return(adapter.dispatch('support_multiple_grantees_per_dcl_statement', 'dbt')()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__support_multiple_grantees_per_dcl_statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.748252, \"supported_languages\": null}, \"macro.dbt.default__support_multiple_grantees_per_dcl_statement\": {\"name\": \"default__support_multiple_grantees_per_dcl_statement\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.default__support_multiple_grantees_per_dcl_statement\", \"macro_sql\": \"\\n\\n{%- macro default__support_multiple_grantees_per_dcl_statement() -%}\\n    {{ return(True) }}\\n{%- endmacro -%}\\n\\n\\n\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.7485409, \"supported_languages\": null}, \"macro.dbt.should_revoke\": {\"name\": \"should_revoke\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.should_revoke\", \"macro_sql\": \"{% macro should_revoke(existing_relation, full_refresh_mode=True) %}\\n\\n    {% if not existing_relation %}\\n        {#-- The table doesn't already exist, so no grants to copy over --#}\\n        {{ return(False) }}\\n    {% elif full_refresh_mode %}\\n        {#-- The object is being REPLACED -- whether grants are copied over depends on the value of user config --#}\\n        {{ return(copy_grants()) }}\\n    {% else %}\\n        {#-- The table is being merged/upserted/inserted -- grants will be carried over --#}\\n        {{ return(True) }}\\n    {% endif %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.copy_grants\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.749697, \"supported_languages\": null}, \"macro.dbt.get_show_grant_sql\": {\"name\": \"get_show_grant_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.get_show_grant_sql\", \"macro_sql\": \"{% macro get_show_grant_sql(relation) %}\\n    {{ return(adapter.dispatch(\\\"get_show_grant_sql\\\", \\\"dbt\\\")(relation)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_show_grant_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.750331, \"supported_languages\": null}, \"macro.dbt.default__get_show_grant_sql\": {\"name\": \"default__get_show_grant_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.default__get_show_grant_sql\", \"macro_sql\": \"{% macro default__get_show_grant_sql(relation) %}\\n    show grants on {{ relation }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.7506151, \"supported_languages\": null}, \"macro.dbt.get_grant_sql\": {\"name\": \"get_grant_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.get_grant_sql\", \"macro_sql\": \"{% macro get_grant_sql(relation, privilege, grantees) %}\\n    {{ return(adapter.dispatch('get_grant_sql', 'dbt')(relation, privilege, grantees)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_grant_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.751184, \"supported_languages\": null}, \"macro.dbt.default__get_grant_sql\": {\"name\": \"default__get_grant_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.default__get_grant_sql\", \"macro_sql\": \"\\n\\n{%- macro default__get_grant_sql(relation, privilege, grantees) -%}\\n    grant {{ privilege }} on {{ relation }} to {{ grantees | join(', ') }}\\n{%- endmacro -%}\\n\\n\\n\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.7516642, \"supported_languages\": null}, \"macro.dbt.get_revoke_sql\": {\"name\": \"get_revoke_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.get_revoke_sql\", \"macro_sql\": \"{% macro get_revoke_sql(relation, privilege, grantees) %}\\n    {{ return(adapter.dispatch('get_revoke_sql', 'dbt')(relation, privilege, grantees)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_revoke_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.752241, \"supported_languages\": null}, \"macro.dbt.default__get_revoke_sql\": {\"name\": \"default__get_revoke_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.default__get_revoke_sql\", \"macro_sql\": \"\\n\\n{%- macro default__get_revoke_sql(relation, privilege, grantees) -%}\\n    revoke {{ privilege }} on {{ relation }} from {{ grantees | join(', ') }}\\n{%- endmacro -%}\\n\\n\\n\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.752723, \"supported_languages\": null}, \"macro.dbt.get_dcl_statement_list\": {\"name\": \"get_dcl_statement_list\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.get_dcl_statement_list\", \"macro_sql\": \"{% macro get_dcl_statement_list(relation, grant_config, get_dcl_macro) %}\\n    {{ return(adapter.dispatch('get_dcl_statement_list', 'dbt')(relation, grant_config, get_dcl_macro)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_dcl_statement_list\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.7532978, \"supported_languages\": null}, \"macro.dbt.default__get_dcl_statement_list\": {\"name\": \"default__get_dcl_statement_list\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.default__get_dcl_statement_list\", \"macro_sql\": \"\\n\\n{%- macro default__get_dcl_statement_list(relation, grant_config, get_dcl_macro) -%}\\n    {#\\n      -- Unpack grant_config into specific privileges and the set of users who need them granted/revoked.\\n      -- Depending on whether this database supports multiple grantees per statement, pass in the list of\\n      -- all grantees per privilege, or (if not) template one statement per privilege-grantee pair.\\n      -- `get_dcl_macro` will be either `get_grant_sql` or `get_revoke_sql`\\n    #}\\n    {%- set dcl_statements = [] -%}\\n    {%- for privilege, grantees in grant_config.items() %}\\n        {%- if support_multiple_grantees_per_dcl_statement() and grantees -%}\\n          {%- set dcl = get_dcl_macro(relation, privilege, grantees) -%}\\n          {%- do dcl_statements.append(dcl) -%}\\n        {%- else -%}\\n          {%- for grantee in grantees -%}\\n              {% set dcl = get_dcl_macro(relation, privilege, [grantee]) %}\\n              {%- do dcl_statements.append(dcl) -%}\\n          {% endfor -%}\\n        {%- endif -%}\\n    {%- endfor -%}\\n    {{ return(dcl_statements) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.support_multiple_grantees_per_dcl_statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.7553658, \"supported_languages\": null}, \"macro.dbt.call_dcl_statements\": {\"name\": \"call_dcl_statements\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.call_dcl_statements\", \"macro_sql\": \"{% macro call_dcl_statements(dcl_statement_list) %}\\n    {{ return(adapter.dispatch(\\\"call_dcl_statements\\\", \\\"dbt\\\")(dcl_statement_list)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__call_dcl_statements\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.756046, \"supported_languages\": null}, \"macro.dbt.default__call_dcl_statements\": {\"name\": \"default__call_dcl_statements\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.default__call_dcl_statements\", \"macro_sql\": \"{% macro default__call_dcl_statements(dcl_statement_list) %}\\n    {#\\n      -- By default, supply all grant + revoke statements in a single semicolon-separated block,\\n      -- so that they're all processed together.\\n\\n      -- Some databases do not support this. Those adapters will need to override this macro\\n      -- to run each statement individually.\\n    #}\\n    {% call statement('grants') %}\\n        {% for dcl_statement in dcl_statement_list %}\\n            {{ dcl_statement }};\\n        {% endfor %}\\n    {% endcall %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.7566988, \"supported_languages\": null}, \"macro.dbt.apply_grants\": {\"name\": \"apply_grants\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.apply_grants\", \"macro_sql\": \"{% macro apply_grants(relation, grant_config, should_revoke) %}\\n    {{ return(adapter.dispatch(\\\"apply_grants\\\", \\\"dbt\\\")(relation, grant_config, should_revoke)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__apply_grants\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.7572742, \"supported_languages\": null}, \"macro.dbt.default__apply_grants\": {\"name\": \"default__apply_grants\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.default__apply_grants\", \"macro_sql\": \"{% macro default__apply_grants(relation, grant_config, should_revoke=True) %}\\n    {#-- If grant_config is {} or None, this is a no-op --#}\\n    {% if grant_config %}\\n        {% if should_revoke %}\\n            {#-- We think previous grants may have carried over --#}\\n            {#-- Show current grants and calculate diffs --#}\\n            {% set current_grants_table = run_query(get_show_grant_sql(relation)) %}\\n            {% set current_grants_dict = adapter.standardize_grants_dict(current_grants_table) %}\\n            {% set needs_granting = diff_of_two_dicts(grant_config, current_grants_dict) %}\\n            {% set needs_revoking = diff_of_two_dicts(current_grants_dict, grant_config) %}\\n            {% if not (needs_granting or needs_revoking) %}\\n                {{ log('On ' ~ relation ~': All grants are in place, no revocation or granting needed.')}}\\n            {% endif %}\\n        {% else %}\\n            {#-- We don't think there's any chance of previous grants having carried over. --#}\\n            {#-- Jump straight to granting what the user has configured. --#}\\n            {% set needs_revoking = {} %}\\n            {% set needs_granting = grant_config %}\\n        {% endif %}\\n        {% if needs_granting or needs_revoking %}\\n            {% set revoke_statement_list = get_dcl_statement_list(relation, needs_revoking, get_revoke_sql) %}\\n            {% set grant_statement_list = get_dcl_statement_list(relation, needs_granting, get_grant_sql) %}\\n            {% set dcl_statement_list = revoke_statement_list + grant_statement_list %}\\n            {% if dcl_statement_list %}\\n                {{ call_dcl_statements(dcl_statement_list) }}\\n            {% endif %}\\n        {% endif %}\\n    {% endif %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.run_query\", \"macro.dbt.get_show_grant_sql\", \"macro.dbt.get_dcl_statement_list\", \"macro.dbt.call_dcl_statements\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.760213, \"supported_languages\": null}, \"macro.dbt.alter_column_comment\": {\"name\": \"alter_column_comment\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"unique_id\": \"macro.dbt.alter_column_comment\", \"macro_sql\": \"{% macro alter_column_comment(relation, column_dict) -%}\\n  {{ return(adapter.dispatch('alter_column_comment', 'dbt')(relation, column_dict)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__alter_column_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.761635, \"supported_languages\": null}, \"macro.dbt.default__alter_column_comment\": {\"name\": \"default__alter_column_comment\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"unique_id\": \"macro.dbt.default__alter_column_comment\", \"macro_sql\": \"{% macro default__alter_column_comment(relation, column_dict) -%}\\n  {{ exceptions.raise_not_implemented(\\n    'alter_column_comment macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.762066, \"supported_languages\": null}, \"macro.dbt.alter_relation_comment\": {\"name\": \"alter_relation_comment\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"unique_id\": \"macro.dbt.alter_relation_comment\", \"macro_sql\": \"{% macro alter_relation_comment(relation, relation_comment) -%}\\n  {{ return(adapter.dispatch('alter_relation_comment', 'dbt')(relation, relation_comment)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__alter_relation_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.762573, \"supported_languages\": null}, \"macro.dbt.default__alter_relation_comment\": {\"name\": \"default__alter_relation_comment\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"unique_id\": \"macro.dbt.default__alter_relation_comment\", \"macro_sql\": \"{% macro default__alter_relation_comment(relation, relation_comment) -%}\\n  {{ exceptions.raise_not_implemented(\\n    'alter_relation_comment macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.762995, \"supported_languages\": null}, \"macro.dbt.persist_docs\": {\"name\": \"persist_docs\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"unique_id\": \"macro.dbt.persist_docs\", \"macro_sql\": \"{% macro persist_docs(relation, model, for_relation=true, for_columns=true) -%}\\n  {{ return(adapter.dispatch('persist_docs', 'dbt')(relation, model, for_relation, for_columns)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__persist_docs\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.7636638, \"supported_languages\": null}, \"macro.dbt.default__persist_docs\": {\"name\": \"default__persist_docs\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"unique_id\": \"macro.dbt.default__persist_docs\", \"macro_sql\": \"{% macro default__persist_docs(relation, model, for_relation, for_columns) -%}\\n  {% if for_relation and config.persist_relation_docs() and model.description %}\\n    {% do run_query(alter_relation_comment(relation, model.description)) %}\\n  {% endif %}\\n\\n  {% if for_columns and config.persist_column_docs() and model.columns %}\\n    {% do run_query(alter_column_comment(relation, model.columns)) %}\\n  {% endif %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.run_query\", \"macro.dbt.alter_relation_comment\", \"macro.dbt.alter_column_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.76503, \"supported_languages\": null}, \"macro.dbt.get_catalog\": {\"name\": \"get_catalog\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.get_catalog\", \"macro_sql\": \"{% macro get_catalog(information_schema, schemas) -%}\\n  {{ return(adapter.dispatch('get_catalog', 'dbt')(information_schema, schemas)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_catalog\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.767971, \"supported_languages\": null}, \"macro.dbt.default__get_catalog\": {\"name\": \"default__get_catalog\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.default__get_catalog\", \"macro_sql\": \"{% macro default__get_catalog(information_schema, schemas) -%}\\n\\n  {% set typename = adapter.type() %}\\n  {% set msg -%}\\n    get_catalog not implemented for {{ typename }}\\n  {%- endset %}\\n\\n  {{ exceptions.raise_compiler_error(msg) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.7686348, \"supported_languages\": null}, \"macro.dbt.information_schema_name\": {\"name\": \"information_schema_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.information_schema_name\", \"macro_sql\": \"{% macro information_schema_name(database) %}\\n  {{ return(adapter.dispatch('information_schema_name', 'dbt')(database)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__information_schema_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.769115, \"supported_languages\": null}, \"macro.dbt.default__information_schema_name\": {\"name\": \"default__information_schema_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.default__information_schema_name\", \"macro_sql\": \"{% macro default__information_schema_name(database) -%}\\n  {%- if database -%}\\n    {{ database }}.INFORMATION_SCHEMA\\n  {%- else -%}\\n    INFORMATION_SCHEMA\\n  {%- endif -%}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.769671, \"supported_languages\": null}, \"macro.dbt.list_schemas\": {\"name\": \"list_schemas\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.list_schemas\", \"macro_sql\": \"{% macro list_schemas(database) -%}\\n  {{ return(adapter.dispatch('list_schemas', 'dbt')(database)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__list_schemas\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.770122, \"supported_languages\": null}, \"macro.dbt.default__list_schemas\": {\"name\": \"default__list_schemas\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.default__list_schemas\", \"macro_sql\": \"{% macro default__list_schemas(database) -%}\\n  {% set sql %}\\n    select distinct schema_name\\n    from {{ information_schema_name(database) }}.SCHEMATA\\n    where catalog_name ilike '{{ database }}'\\n  {% endset %}\\n  {{ return(run_query(sql)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.information_schema_name\", \"macro.dbt.run_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.770835, \"supported_languages\": null}, \"macro.dbt.check_schema_exists\": {\"name\": \"check_schema_exists\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.check_schema_exists\", \"macro_sql\": \"{% macro check_schema_exists(information_schema, schema) -%}\\n  {{ return(adapter.dispatch('check_schema_exists', 'dbt')(information_schema, schema)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__check_schema_exists\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.771361, \"supported_languages\": null}, \"macro.dbt.default__check_schema_exists\": {\"name\": \"default__check_schema_exists\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.default__check_schema_exists\", \"macro_sql\": \"{% macro default__check_schema_exists(information_schema, schema) -%}\\n  {% set sql -%}\\n        select count(*)\\n        from {{ information_schema.replace(information_schema_view='SCHEMATA') }}\\n        where catalog_name='{{ information_schema.database }}'\\n          and schema_name='{{ schema }}'\\n  {%- endset %}\\n  {{ return(run_query(sql)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.replace\", \"macro.dbt.run_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.772129, \"supported_languages\": null}, \"macro.dbt.list_relations_without_caching\": {\"name\": \"list_relations_without_caching\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.list_relations_without_caching\", \"macro_sql\": \"{% macro list_relations_without_caching(schema_relation) %}\\n  {{ return(adapter.dispatch('list_relations_without_caching', 'dbt')(schema_relation)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__list_relations_without_caching\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.772596, \"supported_languages\": null}, \"macro.dbt.default__list_relations_without_caching\": {\"name\": \"default__list_relations_without_caching\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.default__list_relations_without_caching\", \"macro_sql\": \"{% macro default__list_relations_without_caching(schema_relation) %}\\n  {{ exceptions.raise_not_implemented(\\n    'list_relations_without_caching macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.7730088, \"supported_languages\": null}, \"macro.dbt.get_columns_in_relation\": {\"name\": \"get_columns_in_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.get_columns_in_relation\", \"macro_sql\": \"{% macro get_columns_in_relation(relation) -%}\\n  {{ return(adapter.dispatch('get_columns_in_relation', 'dbt')(relation)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_columns_in_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.776206, \"supported_languages\": null}, \"macro.dbt.default__get_columns_in_relation\": {\"name\": \"default__get_columns_in_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.default__get_columns_in_relation\", \"macro_sql\": \"{% macro default__get_columns_in_relation(relation) -%}\\n  {{ exceptions.raise_not_implemented(\\n    'get_columns_in_relation macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.776611, \"supported_languages\": null}, \"macro.dbt.sql_convert_columns_in_relation\": {\"name\": \"sql_convert_columns_in_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.sql_convert_columns_in_relation\", \"macro_sql\": \"{% macro sql_convert_columns_in_relation(table) -%}\\n  {% set columns = [] %}\\n  {% for row in table %}\\n    {% do columns.append(api.Column(*row)) %}\\n  {% endfor %}\\n  {{ return(columns) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.777584, \"supported_languages\": null}, \"macro.dbt.get_columns_in_query\": {\"name\": \"get_columns_in_query\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.get_columns_in_query\", \"macro_sql\": \"{% macro get_columns_in_query(select_sql) -%}\\n  {{ return(adapter.dispatch('get_columns_in_query', 'dbt')(select_sql)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_columns_in_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.77807, \"supported_languages\": null}, \"macro.dbt.default__get_columns_in_query\": {\"name\": \"default__get_columns_in_query\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.default__get_columns_in_query\", \"macro_sql\": \"{% macro default__get_columns_in_query(select_sql) %}\\n    {% call statement('get_columns_in_query', fetch_result=True, auto_begin=False) -%}\\n        select * from (\\n            {{ select_sql }}\\n        ) as __dbt_sbq\\n        where false\\n        limit 0\\n    {% endcall %}\\n\\n    {{ return(load_result('get_columns_in_query').table.columns | map(attribute='name') | list) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.77891, \"supported_languages\": null}, \"macro.dbt.alter_column_type\": {\"name\": \"alter_column_type\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.alter_column_type\", \"macro_sql\": \"{% macro alter_column_type(relation, column_name, new_column_type) -%}\\n  {{ return(adapter.dispatch('alter_column_type', 'dbt')(relation, column_name, new_column_type)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__alter_column_type\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.77949, \"supported_languages\": null}, \"macro.dbt.default__alter_column_type\": {\"name\": \"default__alter_column_type\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.default__alter_column_type\", \"macro_sql\": \"{% macro default__alter_column_type(relation, column_name, new_column_type) -%}\\n  {#\\n    1. Create a new column (w/ temp name and correct type)\\n    2. Copy data over to it\\n    3. Drop the existing column (cascade!)\\n    4. Rename the new column to existing column\\n  #}\\n  {%- set tmp_column = column_name + \\\"__dbt_alter\\\" -%}\\n\\n  {% call statement('alter_column_type') %}\\n    alter table {{ relation }} add column {{ adapter.quote(tmp_column) }} {{ new_column_type }};\\n    update {{ relation }} set {{ adapter.quote(tmp_column) }} = {{ adapter.quote(column_name) }};\\n    alter table {{ relation }} drop column {{ adapter.quote(column_name) }} cascade;\\n    alter table {{ relation }} rename column {{ adapter.quote(tmp_column) }} to {{ adapter.quote(column_name) }}\\n  {% endcall %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.7810528, \"supported_languages\": null}, \"macro.dbt.alter_relation_add_remove_columns\": {\"name\": \"alter_relation_add_remove_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.alter_relation_add_remove_columns\", \"macro_sql\": \"{% macro alter_relation_add_remove_columns(relation, add_columns = none, remove_columns = none) -%}\\n  {{ return(adapter.dispatch('alter_relation_add_remove_columns', 'dbt')(relation, add_columns, remove_columns)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__alter_relation_add_remove_columns\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.781748, \"supported_languages\": null}, \"macro.dbt.default__alter_relation_add_remove_columns\": {\"name\": \"default__alter_relation_add_remove_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.default__alter_relation_add_remove_columns\", \"macro_sql\": \"{% macro default__alter_relation_add_remove_columns(relation, add_columns, remove_columns) %}\\n\\n  {% if add_columns is none %}\\n    {% set add_columns = [] %}\\n  {% endif %}\\n  {% if remove_columns is none %}\\n    {% set remove_columns = [] %}\\n  {% endif %}\\n\\n  {% set sql -%}\\n\\n     alter {{ relation.type }} {{ relation }}\\n\\n            {% for column in add_columns %}\\n               add column {{ column.name }} {{ column.data_type }}{{ ',' if not loop.last }}\\n            {% endfor %}{{ ',' if add_columns and remove_columns }}\\n\\n            {% for column in remove_columns %}\\n                drop column {{ column.name }}{{ ',' if not loop.last }}\\n            {% endfor %}\\n\\n  {%- endset -%}\\n\\n  {% do run_query(sql) %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.run_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.7839968, \"supported_languages\": null}, \"macro.dbt.build_ref_function\": {\"name\": \"build_ref_function\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/python_model/python.sql\", \"original_file_path\": \"macros/python_model/python.sql\", \"unique_id\": \"macro.dbt.build_ref_function\", \"macro_sql\": \"{% macro build_ref_function(model) %}\\n\\n    {%- set ref_dict = {} -%}\\n    {%- for _ref in model.refs -%}\\n        {%- set resolved = ref(*_ref) -%}\\n        {%- do ref_dict.update({_ref | join(\\\".\\\"): resolved | string | replace('\\\"', '\\\\\\\"')}) -%}\\n    {%- endfor -%}\\n\\ndef ref(*args,dbt_load_df_function):\\n    refs = {{ ref_dict | tojson }}\\n    key = \\\".\\\".join(args)\\n    return dbt_load_df_function(refs[key])\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.787274, \"supported_languages\": null}, \"macro.dbt.build_source_function\": {\"name\": \"build_source_function\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/python_model/python.sql\", \"original_file_path\": \"macros/python_model/python.sql\", \"unique_id\": \"macro.dbt.build_source_function\", \"macro_sql\": \"{% macro build_source_function(model) %}\\n\\n    {%- set source_dict = {} -%}\\n    {%- for _source in model.sources -%}\\n        {%- set resolved = source(*_source) -%}\\n        {%- do source_dict.update({_source | join(\\\".\\\"): resolved | string | replace('\\\"', '\\\\\\\"')}) -%}\\n    {%- endfor -%}\\n\\ndef source(*args, dbt_load_df_function):\\n    sources = {{ source_dict | tojson }}\\n    key = \\\".\\\".join(args)\\n    return dbt_load_df_function(sources[key])\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.788432, \"supported_languages\": null}, \"macro.dbt.build_config_dict\": {\"name\": \"build_config_dict\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/python_model/python.sql\", \"original_file_path\": \"macros/python_model/python.sql\", \"unique_id\": \"macro.dbt.build_config_dict\", \"macro_sql\": \"{% macro build_config_dict(model) %}\\n    {%- set config_dict = {} -%}\\n    {% set config_dbt_used = zip(model.config.config_keys_used, model.config.config_keys_defaults) | list %}\\n    {%- for key, default in config_dbt_used -%}\\n        {# weird type testing with enum, would be much easier to write this logic in Python! #}\\n        {%- if key == \\\"language\\\" -%}\\n          {%- set value = \\\"python\\\" -%}\\n        {%- endif -%}\\n        {%- set value = model.config.get(key, default) -%}\\n        {%- do config_dict.update({key: value}) -%}\\n    {%- endfor -%}\\nconfig_dict = {{ config_dict }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.790293, \"supported_languages\": null}, \"macro.dbt.py_script_postfix\": {\"name\": \"py_script_postfix\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/python_model/python.sql\", \"original_file_path\": \"macros/python_model/python.sql\", \"unique_id\": \"macro.dbt.py_script_postfix\", \"macro_sql\": \"{% macro py_script_postfix(model) %}\\n# This part is user provided model code\\n# you will need to copy the next section to run the code\\n# COMMAND ----------\\n# this part is dbt logic for get ref work, do not modify\\n\\n{{ build_ref_function(model ) }}\\n{{ build_source_function(model ) }}\\n{{ build_config_dict(model) }}\\n\\nclass config:\\n    def __init__(self, *args, **kwargs):\\n        pass\\n\\n    @staticmethod\\n    def get(key, default=None):\\n        return config_dict.get(key, default)\\n\\nclass this:\\n    \\\"\\\"\\\"dbt.this() or dbt.this.identifier\\\"\\\"\\\"\\n    database = \\\"{{ this.database }}\\\"\\n    schema = \\\"{{ this.schema }}\\\"\\n    identifier = \\\"{{ this.identifier }}\\\"\\n    {% set this_relation_name = this | string | replace('\\\"', '\\\\\\\\\\\"') %}\\n    def __repr__(self):\\n        return \\\"{{ this_relation_name  }}\\\"\\n\\n\\nclass dbtObj:\\n    def __init__(self, load_df_function) -> None:\\n        self.source = lambda *args: source(*args, dbt_load_df_function=load_df_function)\\n        self.ref = lambda *args: ref(*args, dbt_load_df_function=load_df_function)\\n        self.config = config\\n        self.this = this()\\n        self.is_incremental = {{ is_incremental() }}\\n\\n# COMMAND ----------\\n{{py_script_comment()}}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.build_ref_function\", \"macro.dbt.build_source_function\", \"macro.dbt.build_config_dict\", \"macro.dbt.is_incremental\", \"macro.dbt.py_script_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.791504, \"supported_languages\": null}, \"macro.dbt.py_script_comment\": {\"name\": \"py_script_comment\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/python_model/python.sql\", \"original_file_path\": \"macros/python_model/python.sql\", \"unique_id\": \"macro.dbt.py_script_comment\", \"macro_sql\": \"{%macro py_script_comment()%}\\n{%endmacro%}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.791784, \"supported_languages\": null}, \"macro.dbt.test_unique\": {\"name\": \"test_unique\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"tests/generic/builtin.sql\", \"original_file_path\": \"tests/generic/builtin.sql\", \"unique_id\": \"macro.dbt.test_unique\", \"macro_sql\": \"{% test unique(model, column_name) %}\\n    {% set macro = adapter.dispatch('test_unique', 'dbt') %}\\n    {{ macro(model, column_name) }}\\n{% endtest %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__test_unique\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.7929192, \"supported_languages\": null}, \"macro.dbt.test_not_null\": {\"name\": \"test_not_null\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"tests/generic/builtin.sql\", \"original_file_path\": \"tests/generic/builtin.sql\", \"unique_id\": \"macro.dbt.test_not_null\", \"macro_sql\": \"{% test not_null(model, column_name) %}\\n    {% set macro = adapter.dispatch('test_not_null', 'dbt') %}\\n    {{ macro(model, column_name) }}\\n{% endtest %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__test_not_null\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.793498, \"supported_languages\": null}, \"macro.dbt.test_accepted_values\": {\"name\": \"test_accepted_values\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"tests/generic/builtin.sql\", \"original_file_path\": \"tests/generic/builtin.sql\", \"unique_id\": \"macro.dbt.test_accepted_values\", \"macro_sql\": \"{% test accepted_values(model, column_name, values, quote=True) %}\\n    {% set macro = adapter.dispatch('test_accepted_values', 'dbt') %}\\n    {{ macro(model, column_name, values, quote) }}\\n{% endtest %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__test_accepted_values\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.794215, \"supported_languages\": null}, \"macro.dbt.test_relationships\": {\"name\": \"test_relationships\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"tests/generic/builtin.sql\", \"original_file_path\": \"tests/generic/builtin.sql\", \"unique_id\": \"macro.dbt.test_relationships\", \"macro_sql\": \"{% test relationships(model, column_name, to, field) %}\\n    {% set macro = adapter.dispatch('test_relationships', 'dbt') %}\\n    {{ macro(model, column_name, to, field) }}\\n{% endtest %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__test_relationships\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1676322281.7948952, \"supported_languages\": null}}, \"docs\": {\"doc.test.somedoc\": {\"name\": \"somedoc\", \"resource_type\": \"doc\", \"package_name\": \"test\", \"path\": \"somedoc.md\", \"original_file_path\": \"models/somedoc.md\", \"unique_id\": \"doc.test.somedoc\", \"block_contents\": \"Testing, testing\"}, \"doc.dbt.__overview__\": {\"name\": \"__overview__\", \"resource_type\": \"doc\", \"package_name\": \"dbt\", \"path\": \"overview.md\", \"original_file_path\": \"docs/overview.md\", \"unique_id\": \"doc.dbt.__overview__\", \"block_contents\": \"### Welcome!\\n\\nWelcome to the auto-generated documentation for your dbt project!\\n\\n### Navigation\\n\\nYou can use the `Project` and `Database` navigation tabs on the left side of the window to explore the models\\nin your project.\\n\\n#### Project Tab\\nThe `Project` tab mirrors the directory structure of your dbt project. In this tab, you can see all of the\\nmodels defined in your dbt project, as well as models imported from dbt packages.\\n\\n#### Database Tab\\nThe `Database` tab also exposes your models, but in a format that looks more like a database explorer. This view\\nshows relations (tables and views) grouped into database schemas. Note that ephemeral models are _not_ shown\\nin this interface, as they do not exist in the database.\\n\\n### Graph Exploration\\nYou can click the blue icon on the bottom-right corner of the page to view the lineage graph of your models.\\n\\nOn model pages, you'll see the immediate parents and children of the model you're exploring. By clicking the `Expand`\\nbutton at the top-right of this lineage pane, you'll be able to see all of the models that are used to build,\\nor are built from, the model you're exploring.\\n\\nOnce expanded, you'll be able to use the `--select` and `--exclude` model selection syntax to filter the\\nmodels in the graph. For more information on model selection, check out the [dbt docs](https://docs.getdbt.com/docs/model-selection-syntax).\\n\\nNote that you can also right-click on models to interactively filter and explore the graph.\\n\\n---\\n\\n### More information\\n\\n- [What is dbt](https://docs.getdbt.com/docs/introduction)?\\n- Read the [dbt viewpoint](https://docs.getdbt.com/docs/viewpoint)\\n- [Installation](https://docs.getdbt.com/docs/installation)\\n- Join the [dbt Community](https://www.getdbt.com/community/) for questions and discussion\"}}, \"exposures\": {\"exposure.test.simple_exposure\": {\"name\": \"simple_exposure\", \"resource_type\": \"exposure\", \"package_name\": \"test\", \"path\": \"schema.yml\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"exposure.test.simple_exposure\", \"fqn\": [\"test\", \"simple_exposure\"], \"type\": \"dashboard\", \"owner\": {\"email\": \"something@example.com\", \"name\": null}, \"description\": \"\", \"label\": null, \"maturity\": null, \"meta\": {}, \"tags\": [], \"config\": {\"enabled\": true}, \"unrendered_config\": {}, \"url\": null, \"depends_on\": {\"macros\": [], \"nodes\": [\"source.test.my_source.my_table\", \"model.test.my_model\"]}, \"refs\": [[\"my_model\"]], \"sources\": [[\"my_source\", \"my_table\"]], \"metrics\": [], \"created_at\": 1676322282.478955}}, \"metrics\": {\"metric.test.my_metric\": {\"name\": \"my_metric\", \"resource_type\": \"metric\", \"package_name\": \"test\", \"path\": \"schema.yml\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"metric.test.my_metric\", \"fqn\": [\"test\", \"my_metric\"], \"description\": \"\", \"label\": \"Count records\", \"calculation_method\": \"count\", \"expression\": \"*\", \"filters\": [], \"time_grains\": [\"day\"], \"dimensions\": [], \"timestamp\": \"updated_at\", \"window\": null, \"model\": \"ref('my_model')\", \"model_unique_id\": null, \"meta\": {}, \"tags\": [], \"config\": {\"enabled\": true}, \"unrendered_config\": {}, \"sources\": [], \"depends_on\": {\"macros\": [], \"nodes\": [\"model.test.my_model\"]}, \"refs\": [[\"my_model\"]], \"metrics\": [], \"created_at\": 1676322282.491698}}, \"selectors\": {}, \"disabled\": {\"model.test.disabled_model\": [{\"database\": \"dbt\", \"schema\": \"test16763222812618906995_test_previous_version_state\", \"name\": \"disabled_model\", \"resource_type\": \"model\", \"package_name\": \"test\", \"path\": \"disabled_model.sql\", \"original_file_path\": \"models/disabled_model.sql\", \"unique_id\": \"model.test.disabled_model\", \"fqn\": [\"test\", \"disabled_model\"], \"alias\": \"disabled_model\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"34f7b8e60d9e7933469c48d6c92b0a53918d0ba626a9ce2c30ab2f1532145827\"}, \"config\": {\"enabled\": false, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"materialized\": \"view\", \"incremental_strategy\": null, \"persist_docs\": {}, \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": null, \"on_schema_change\": \"ignore\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"post-hook\": [], \"pre-hook\": []}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {\"enabled\": false}, \"created_at\": 1676322282.224511, \"config_call_dict\": {\"enabled\": false}, \"relation_name\": \"\\\"dbt\\\".\\\"test16763222812618906995_test_previous_version_state\\\".\\\"disabled_model\\\"\", \"raw_code\": \"{{ config(enabled=False) }}\\nselect 2 as id\", \"language\": \"sql\", \"refs\": [], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [], \"nodes\": []}, \"compiled_path\": null}], \"snapshot.test.disabled_snapshot_seed\": [{\"database\": \"dbt\", \"schema\": \"test16763222812618906995_test_previous_version_state\", \"name\": \"disabled_snapshot_seed\", \"resource_type\": \"snapshot\", \"package_name\": \"test\", \"path\": \"disabled_snapshot_seed.sql\", \"original_file_path\": \"snapshots/disabled_snapshot_seed.sql\", \"unique_id\": \"snapshot.test.disabled_snapshot_seed\", \"fqn\": [\"test\", \"disabled_snapshot_seed\", \"disabled_snapshot_seed\"], \"alias\": \"disabled_snapshot_seed\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"52b08465e16dcbc364162dfbdb34cf25e04295bc13d63ab0b420f60d15234c76\"}, \"config\": {\"enabled\": false, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"materialized\": \"snapshot\", \"incremental_strategy\": null, \"persist_docs\": {}, \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": \"id\", \"on_schema_change\": \"ignore\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"strategy\": \"check\", \"target_schema\": \"test16763222812618906995_test_previous_version_state\", \"target_database\": null, \"updated_at\": null, \"check_cols\": \"all\", \"post-hook\": [], \"pre-hook\": []}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {\"unique_key\": \"id\", \"strategy\": \"check\", \"check_cols\": \"all\", \"target_schema\": \"test16763222812618906995_test_previous_version_state\", \"enabled\": false}, \"created_at\": 1676322282.303265, \"config_call_dict\": {\"unique_key\": \"id\", \"strategy\": \"check\", \"check_cols\": \"all\", \"target_schema\": \"test16763222812618906995_test_previous_version_state\", \"enabled\": false}, \"relation_name\": \"\\\"dbt\\\".\\\"test16763222812618906995_test_previous_version_state\\\".\\\"disabled_snapshot_seed\\\"\", \"raw_code\": \"\\n{{\\n    config(\\n      unique_key='id',\\n      strategy='check',\\n      check_cols='all',\\n      target_schema=schema,\\n      enabled=False,\\n    )\\n}}\\nselect * from {{ ref('my_seed') }}\\n\", \"language\": \"sql\", \"refs\": [[\"my_seed\"]], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [], \"nodes\": []}, \"compiled_path\": null}], \"analysis.test.disabled_al\": [{\"database\": \"dbt\", \"schema\": \"test16763222812618906995_test_previous_version_state\", \"name\": \"disabled_al\", \"resource_type\": \"analysis\", \"package_name\": \"test\", \"path\": \"analysis/disabled_al.sql\", \"original_file_path\": \"analyses/disabled_al.sql\", \"unique_id\": \"analysis.test.disabled_al\", \"fqn\": [\"test\", \"analysis\", \"disabled_al\"], \"alias\": \"disabled_al\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"76b8579816eac97721616fd429dcd1a93c311c6358830a65d40ebe5661572610\"}, \"config\": {\"enabled\": false, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"materialized\": \"view\", \"incremental_strategy\": null, \"persist_docs\": {}, \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": null, \"on_schema_change\": \"ignore\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"post-hook\": [], \"pre-hook\": []}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {\"enabled\": false}, \"created_at\": 1676322282.3320582, \"config_call_dict\": {\"enabled\": false}, \"relation_name\": null, \"raw_code\": \"{{ config(enabled=False) }}\\nselect 9 as id\", \"language\": \"sql\", \"refs\": [], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [], \"nodes\": []}, \"compiled_path\": null}], \"test.test.disabled_just_my\": [{\"database\": \"dbt\", \"schema\": \"test16763222812618906995_test_previous_version_state_dbt_test__audit\", \"name\": \"disabled_just_my\", \"resource_type\": \"test\", \"package_name\": \"test\", \"path\": \"disabled_just_my.sql\", \"original_file_path\": \"tests/disabled_just_my.sql\", \"unique_id\": \"test.test.disabled_just_my\", \"fqn\": [\"test\", \"disabled_just_my\"], \"alias\": \"disabled_just_my\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"0b5827d08d1e3c97e8fb865bea00031b2e90ecef7884a42429cc48d0f48b8c20\"}, \"config\": {\"enabled\": false, \"alias\": null, \"schema\": \"dbt_test__audit\", \"database\": null, \"tags\": [], \"meta\": {}, \"materialized\": \"test\", \"severity\": \"ERROR\", \"store_failures\": null, \"where\": null, \"limit\": null, \"fail_calc\": \"count(*)\", \"warn_if\": \"!= 0\", \"error_if\": \"!= 0\"}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {\"enabled\": false}, \"created_at\": 1676322282.359573, \"config_call_dict\": {\"enabled\": false}, \"relation_name\": null, \"raw_code\": \"{{ config(enabled=False) }}\\n\\nselect * from {{ ref('my_model') }}\\nwhere false\", \"language\": \"sql\", \"refs\": [[\"my_model\"]], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [], \"nodes\": []}, \"compiled_path\": null}], \"test.test.disabled_check_nothing_my_model_.f2c6a72d37\": [{\"test_metadata\": {\"name\": \"disabled_check_nothing\", \"kwargs\": {\"model\": \"{{ get_where_subquery(ref('my_model')) }}\"}, \"namespace\": null}, \"database\": \"dbt\", \"schema\": \"test16763222812618906995_test_previous_version_state_dbt_test__audit\", \"name\": \"disabled_check_nothing_my_model_\", \"resource_type\": \"test\", \"package_name\": \"test\", \"path\": \"disabled_check_nothing_my_model_.sql\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"test.test.disabled_check_nothing_my_model_.f2c6a72d37\", \"fqn\": [\"test\", \"disabled_check_nothing_my_model_\"], \"alias\": \"disabled_check_nothing_my_model_\", \"checksum\": {\"name\": \"none\", \"checksum\": \"\"}, \"config\": {\"enabled\": false, \"alias\": null, \"schema\": \"dbt_test__audit\", \"database\": null, \"tags\": [], \"meta\": {}, \"materialized\": \"test\", \"severity\": \"ERROR\", \"store_failures\": null, \"where\": null, \"limit\": null, \"fail_calc\": \"count(*)\", \"warn_if\": \"!= 0\", \"error_if\": \"!= 0\"}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {\"enabled\": false}, \"created_at\": 1676322282.455549, \"config_call_dict\": {\"enabled\": false}, \"relation_name\": null, \"raw_code\": \"{{ test_disabled_check_nothing(**_dbt_generic_test_kwargs) }}\", \"language\": \"sql\", \"refs\": [[\"my_model\"]], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [\"macro.test.test_disabled_check_nothing\", \"macro.dbt.get_where_subquery\"], \"nodes\": []}, \"compiled_path\": null, \"column_name\": null, \"file_key_name\": \"models.my_model\"}], \"exposure.test.disabled_exposure\": [{\"name\": \"disabled_exposure\", \"resource_type\": \"exposure\", \"package_name\": \"test\", \"path\": \"schema.yml\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"exposure.test.disabled_exposure\", \"fqn\": [\"test\", \"disabled_exposure\"], \"type\": \"dashboard\", \"owner\": {\"email\": \"something@example.com\", \"name\": null}, \"description\": \"\", \"label\": null, \"maturity\": null, \"meta\": {}, \"tags\": [], \"config\": {\"enabled\": false}, \"unrendered_config\": {\"enabled\": false}, \"url\": null, \"depends_on\": {\"macros\": [], \"nodes\": []}, \"refs\": [[\"my_model\"]], \"sources\": [], \"metrics\": [], \"created_at\": 1676322282.482795}], \"metric.test.disabled_metric\": [{\"name\": \"disabled_metric\", \"resource_type\": \"metric\", \"package_name\": \"test\", \"path\": \"schema.yml\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"metric.test.disabled_metric\", \"fqn\": [\"test\", \"disabled_metric\"], \"description\": \"\", \"label\": \"Count records\", \"calculation_method\": \"count\", \"expression\": \"*\", \"filters\": [], \"time_grains\": [\"day\"], \"dimensions\": [], \"timestamp\": \"updated_at\", \"window\": null, \"model\": \"ref('my_model')\", \"model_unique_id\": null, \"meta\": {}, \"tags\": [], \"config\": {\"enabled\": false}, \"unrendered_config\": {\"enabled\": false}, \"sources\": [], \"depends_on\": {\"macros\": [], \"nodes\": []}, \"refs\": [[\"my_model\"]], \"metrics\": [], \"created_at\": 1676322282.495338}], \"seed.test.disabled_seed\": [{\"database\": \"dbt\", \"schema\": \"test16763222812618906995_test_previous_version_state\", \"name\": \"disabled_seed\", \"resource_type\": \"seed\", \"package_name\": \"test\", \"path\": \"disabled_seed.csv\", \"original_file_path\": \"seeds/disabled_seed.csv\", \"unique_id\": \"seed.test.disabled_seed\", \"fqn\": [\"test\", \"disabled_seed\"], \"alias\": \"disabled_seed\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"c6c08a913b5a382014ef0ba248d97b12fc801beb369fdbd24aff1a3912ee3773\"}, \"config\": {\"enabled\": false, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"materialized\": \"seed\", \"incremental_strategy\": null, \"persist_docs\": {}, \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": null, \"on_schema_change\": \"ignore\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"quote_columns\": null, \"post-hook\": [], \"pre-hook\": []}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": \"test://models/schema.yml\", \"build_path\": null, \"deferred\": false, \"unrendered_config\": {\"enabled\": false}, \"created_at\": 1676322282.462719, \"config_call_dict\": {}, \"relation_name\": \"\\\"dbt\\\".\\\"test16763222812618906995_test_previous_version_state\\\".\\\"disabled_seed\\\"\", \"raw_code\": \"\", \"root_path\": \"/private/var/folders/qt/vw8wqdgx4w381wh14b9y25m40000gn/T/pytest-of-gerda/pytest-115/project0\", \"depends_on\": {\"macros\": []}}], \"source.test.my_source.disabled_table\": [{\"database\": \"dbt\", \"schema\": \"my_source\", \"name\": \"disabled_table\", \"resource_type\": \"source\", \"package_name\": \"test\", \"path\": \"models/schema.yml\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"source.test.my_source.disabled_table\", \"fqn\": [\"test\", \"my_source\", \"disabled_table\"], \"source_name\": \"my_source\", \"source_description\": \"My source\", \"loader\": \"a_loader\", \"identifier\": \"disabled_table\", \"quoting\": {\"database\": null, \"schema\": null, \"identifier\": null, \"column\": null}, \"loaded_at_field\": null, \"freshness\": {\"warn_after\": {\"count\": null, \"period\": null}, \"error_after\": {\"count\": null, \"period\": null}, \"filter\": null}, \"external\": null, \"description\": \"Disabled table\", \"columns\": {}, \"meta\": {}, \"source_meta\": {}, \"tags\": [], \"config\": {\"enabled\": false}, \"patch_path\": null, \"unrendered_config\": {\"enabled\": false}, \"relation_name\": \"\\\"dbt\\\".\\\"my_source\\\".\\\"disabled_table\\\"\", \"created_at\": 1676322282.498409}]}, \"parent_map\": {\"model.test.my_model\": [], \"snapshot.test.snapshot_seed\": [\"seed.test.my_seed\"], \"analysis.test.a\": [], \"test.test.just_my\": [\"model.test.my_model\"], \"seed.test.my_seed\": [], \"test.test.not_null_my_model_id.43e0e9183a\": [\"model.test.my_model\"], \"test.test.check_nothing_my_model_.d5a5e66110\": [\"model.test.my_model\"], \"source.test.my_source.my_table\": [], \"exposure.test.simple_exposure\": [\"model.test.my_model\", \"source.test.my_source.my_table\"], \"metric.test.my_metric\": [\"model.test.my_model\"]}, \"child_map\": {\"model.test.my_model\": [\"exposure.test.simple_exposure\", \"metric.test.my_metric\", \"test.test.check_nothing_my_model_.d5a5e66110\", \"test.test.just_my\", \"test.test.not_null_my_model_id.43e0e9183a\"], \"snapshot.test.snapshot_seed\": [], \"analysis.test.a\": [], \"test.test.just_my\": [], \"seed.test.my_seed\": [\"snapshot.test.snapshot_seed\"], \"test.test.not_null_my_model_id.43e0e9183a\": [], \"test.test.check_nothing_my_model_.d5a5e66110\": [], \"source.test.my_source.my_table\": [\"exposure.test.simple_exposure\"], \"exposure.test.simple_exposure\": [], \"metric.test.my_metric\": []}}\n"
  },
  {
    "path": "tests/functional/artifacts/data/state/v9/manifest.json",
    "content": "{\"metadata\": {\"dbt_schema_version\": \"https://schemas.getdbt.com/dbt/manifest/v9.json\", \"dbt_version\": \"1.5.0b5\", \"generated_at\": \"2023-04-10T02:53:50.434615Z\", \"invocation_id\": \"7e6390ca-c227-4a45-b9e0-85eeb260e9a8\", \"env\": {}, \"project_id\": \"098f6bcd4621d373cade4e832627b4f6\", \"user_id\": null, \"send_anonymous_usage_stats\": false, \"adapter_type\": \"postgres\"}, \"nodes\": {\"model.test.my_model\": {\"database\": \"dbt\", \"schema\": \"test16810952296205305560_test_previous_version_state\", \"name\": \"my_model\", \"resource_type\": \"model\", \"package_name\": \"test\", \"path\": \"my_model.sql\", \"original_file_path\": \"models/my_model.sql\", \"unique_id\": \"model.test.my_model\", \"fqn\": [\"test\", \"my_model\"], \"alias\": \"my_model\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"3ea0f972fa1b56aa2dc2f56ee784b6a5796312f9a813d59ae70fd8855f10d16d\"}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"view\", \"incremental_strategy\": null, \"persist_docs\": {}, \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": null, \"on_schema_change\": \"ignore\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"contract\": {\"enforced\": false}, \"post-hook\": [], \"pre-hook\": []}, \"tags\": [], \"description\": \"Example model\", \"columns\": {\"id\": {\"name\": \"id\", \"description\": \"\", \"meta\": {}, \"data_type\": null, \"constraints\": [], \"quote\": null, \"tags\": []}}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": \"test://models/schema.yml\", \"build_path\": null, \"deferred\": false, \"unrendered_config\": {}, \"created_at\": 1681095229.898038, \"relation_name\": \"\\\"dbt\\\".\\\"test16810952296205305560_test_previous_version_state\\\".\\\"my_model\\\"\", \"raw_code\": \"select 1 as id\", \"language\": \"sql\", \"refs\": [], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [], \"nodes\": []}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"checksum\": null}, \"access\": \"protected\", \"version\": null, \"is_latest_version\": null}, \"snapshot.test.snapshot_seed\": {\"database\": \"dbt\", \"schema\": \"test16810952296205305560_test_previous_version_state\", \"name\": \"snapshot_seed\", \"resource_type\": \"snapshot\", \"package_name\": \"test\", \"path\": \"snapshot_seed.sql\", \"original_file_path\": \"snapshots/snapshot_seed.sql\", \"unique_id\": \"snapshot.test.snapshot_seed\", \"fqn\": [\"test\", \"snapshot_seed\", \"snapshot_seed\"], \"alias\": \"snapshot_seed\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"5fc998f39655f8fe52443a919e749b6e23883ef90202b040412baac13c6bfe18\"}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"snapshot\", \"incremental_strategy\": null, \"persist_docs\": {}, \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": \"id\", \"on_schema_change\": \"ignore\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"contract\": {\"enforced\": false}, \"strategy\": \"check\", \"target_schema\": \"test16810952296205305560_test_previous_version_state\", \"target_database\": null, \"updated_at\": null, \"check_cols\": \"all\", \"post-hook\": [], \"pre-hook\": []}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {\"unique_key\": \"id\", \"strategy\": \"check\", \"check_cols\": \"all\", \"target_schema\": \"test16810952296205305560_test_previous_version_state\"}, \"created_at\": 1681095229.843765, \"relation_name\": \"\\\"dbt\\\".\\\"test16810952296205305560_test_previous_version_state\\\".\\\"snapshot_seed\\\"\", \"raw_code\": \"\\n{{\\n    config(\\n      unique_key='id',\\n      strategy='check',\\n      check_cols='all',\\n      target_schema=schema,\\n    )\\n}}\\nselect * from {{ ref('my_seed') }}\\n\", \"language\": \"sql\", \"refs\": [{\"name\": \"my_seed\", \"package\": null, \"version\": null}], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [], \"nodes\": [\"seed.test.my_seed\"]}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"checksum\": null}}, \"analysis.test.a\": {\"database\": \"dbt\", \"schema\": \"test16810952296205305560_test_previous_version_state\", \"name\": \"a\", \"resource_type\": \"analysis\", \"package_name\": \"test\", \"path\": \"analysis/a.sql\", \"original_file_path\": \"analyses/a.sql\", \"unique_id\": \"analysis.test.a\", \"fqn\": [\"test\", \"analysis\", \"a\"], \"alias\": \"a\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"a389c282f569f0bbdc2a8a4f174dea746c28582fdaf2048d31d9226af9feab23\"}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"view\", \"incremental_strategy\": null, \"persist_docs\": {}, \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": null, \"on_schema_change\": \"ignore\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"contract\": {\"enforced\": false}, \"post-hook\": [], \"pre-hook\": []}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {}, \"created_at\": 1681095229.8655732, \"relation_name\": null, \"raw_code\": \"select 4 as id\", \"language\": \"sql\", \"refs\": [], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [], \"nodes\": []}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"checksum\": null}}, \"test.test.just_my\": {\"database\": \"dbt\", \"schema\": \"test16810952296205305560_test_previous_version_state_dbt_test__audit\", \"name\": \"just_my\", \"resource_type\": \"test\", \"package_name\": \"test\", \"path\": \"just_my.sql\", \"original_file_path\": \"tests/just_my.sql\", \"unique_id\": \"test.test.just_my\", \"fqn\": [\"test\", \"just_my\"], \"alias\": \"just_my\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"744889a2e2d9ce380619265e1217d7ccf6e6ca896c048d42ebe0f9cfb74d7156\"}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": \"dbt_test__audit\", \"database\": null, \"tags\": [\"data_test_tag\"], \"meta\": {}, \"group\": null, \"materialized\": \"test\", \"severity\": \"ERROR\", \"store_failures\": null, \"where\": null, \"limit\": null, \"fail_calc\": \"count(*)\", \"warn_if\": \"!= 0\", \"error_if\": \"!= 0\"}, \"tags\": [\"data_test_tag\"], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {\"tags\": [\"data_test_tag\"]}, \"created_at\": 1681095229.884334, \"relation_name\": null, \"raw_code\": \"{{ config(tags = ['data_test_tag']) }}\\n\\nselect * from {{ ref('my_model') }}\\nwhere false\", \"language\": \"sql\", \"refs\": [{\"name\": \"my_model\", \"package\": null, \"version\": null}], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [], \"nodes\": [\"model.test.my_model\"]}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"checksum\": null}}, \"seed.test.my_seed\": {\"database\": \"dbt\", \"schema\": \"test16810952296205305560_test_previous_version_state\", \"name\": \"my_seed\", \"resource_type\": \"seed\", \"package_name\": \"test\", \"path\": \"my_seed.csv\", \"original_file_path\": \"seeds/my_seed.csv\", \"unique_id\": \"seed.test.my_seed\", \"fqn\": [\"test\", \"my_seed\"], \"alias\": \"my_seed\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"f7ede83f36165ac6b7a047aa2c3f212dff385bfa9f35f395108cd06fc8e96943\"}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"seed\", \"incremental_strategy\": null, \"persist_docs\": {}, \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": null, \"on_schema_change\": \"ignore\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"contract\": {\"enforced\": false}, \"quote_columns\": null, \"post-hook\": [], \"pre-hook\": []}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {}, \"created_at\": 1681095229.889285, \"relation_name\": \"\\\"dbt\\\".\\\"test16810952296205305560_test_previous_version_state\\\".\\\"my_seed\\\"\", \"raw_code\": \"\", \"root_path\": \"/private/var/folders/k6/gtt07v8j2vn51m_z05xk_fjc0000gp/T/pytest-of-michelleark/pytest-80/project5\", \"depends_on\": {\"macros\": []}}, \"test.test.not_null_my_model_id.43e0e9183a\": {\"test_metadata\": {\"name\": \"not_null\", \"kwargs\": {\"column_name\": \"id\", \"model\": \"{{ get_where_subquery(ref('my_model')) }}\"}, \"namespace\": null}, \"database\": \"dbt\", \"schema\": \"test16810952296205305560_test_previous_version_state_dbt_test__audit\", \"name\": \"not_null_my_model_id\", \"resource_type\": \"test\", \"package_name\": \"test\", \"path\": \"not_null_my_model_id.sql\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"test.test.not_null_my_model_id.43e0e9183a\", \"fqn\": [\"test\", \"not_null_my_model_id\"], \"alias\": \"not_null_my_model_id\", \"checksum\": {\"name\": \"none\", \"checksum\": \"\"}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": \"dbt_test__audit\", \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"test\", \"severity\": \"ERROR\", \"store_failures\": null, \"where\": null, \"limit\": null, \"fail_calc\": \"count(*)\", \"warn_if\": \"!= 0\", \"error_if\": \"!= 0\"}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {}, \"created_at\": 1681095229.898516, \"relation_name\": null, \"raw_code\": \"{{ test_not_null(**_dbt_generic_test_kwargs) }}\", \"language\": \"sql\", \"refs\": [{\"name\": \"my_model\", \"package\": null, \"version\": null}], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [\"macro.dbt.test_not_null\"], \"nodes\": [\"model.test.my_model\"]}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"checksum\": null}, \"column_name\": \"id\", \"file_key_name\": \"models.my_model\", \"attached_node\": \"model.test.my_model\"}, \"test.test.check_nothing_my_model_.d5a5e66110\": {\"test_metadata\": {\"name\": \"check_nothing\", \"kwargs\": {\"model\": \"{{ get_where_subquery(ref('my_model')) }}\"}, \"namespace\": null}, \"database\": \"dbt\", \"schema\": \"test16810952296205305560_test_previous_version_state_dbt_test__audit\", \"name\": \"check_nothing_my_model_\", \"resource_type\": \"test\", \"package_name\": \"test\", \"path\": \"check_nothing_my_model_.sql\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"test.test.check_nothing_my_model_.d5a5e66110\", \"fqn\": [\"test\", \"check_nothing_my_model_\"], \"alias\": \"check_nothing_my_model_\", \"checksum\": {\"name\": \"none\", \"checksum\": \"\"}, \"config\": {\"enabled\": true, \"alias\": null, \"schema\": \"dbt_test__audit\", \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"test\", \"severity\": \"ERROR\", \"store_failures\": null, \"where\": null, \"limit\": null, \"fail_calc\": \"count(*)\", \"warn_if\": \"!= 0\", \"error_if\": \"!= 0\"}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {}, \"created_at\": 1681095229.900049, \"relation_name\": null, \"raw_code\": \"{{ test_check_nothing(**_dbt_generic_test_kwargs) }}\", \"language\": \"sql\", \"refs\": [{\"name\": \"my_model\", \"package\": null, \"version\": null}], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [\"macro.test.test_check_nothing\", \"macro.dbt.get_where_subquery\"], \"nodes\": [\"model.test.my_model\"]}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"checksum\": null}, \"column_name\": null, \"file_key_name\": \"models.my_model\", \"attached_node\": \"model.test.my_model\"}}, \"sources\": {\"source.test.my_source.my_table\": {\"database\": \"dbt\", \"schema\": \"my_source\", \"name\": \"my_table\", \"resource_type\": \"source\", \"package_name\": \"test\", \"path\": \"models/schema.yml\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"source.test.my_source.my_table\", \"fqn\": [\"test\", \"my_source\", \"my_table\"], \"source_name\": \"my_source\", \"source_description\": \"My source\", \"loader\": \"a_loader\", \"identifier\": \"my_seed\", \"quoting\": {\"database\": null, \"schema\": null, \"identifier\": null, \"column\": null}, \"loaded_at_field\": null, \"freshness\": {\"warn_after\": {\"count\": null, \"period\": null}, \"error_after\": {\"count\": null, \"period\": null}, \"filter\": null}, \"external\": null, \"description\": \"My table\", \"columns\": {}, \"meta\": {}, \"source_meta\": {}, \"tags\": [], \"config\": {\"enabled\": true}, \"patch_path\": null, \"unrendered_config\": {}, \"relation_name\": \"\\\"dbt\\\".\\\"my_source\\\".\\\"my_seed\\\"\", \"created_at\": 1681095229.938866}}, \"macros\": {\"macro.test.test_check_nothing\": {\"name\": \"test_check_nothing\", \"resource_type\": \"macro\", \"package_name\": \"test\", \"path\": \"macros/dummy_test.sql\", \"original_file_path\": \"macros/dummy_test.sql\", \"unique_id\": \"macro.test.test_check_nothing\", \"macro_sql\": \"{% test check_nothing(model) %}\\n-- a silly test to make sure that table-level tests show up in the manifest\\n-- without a column_name field\\n\\nselect 0\\n\\n{% endtest %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.549095, \"supported_languages\": null}, \"macro.test.test_disabled_check_nothing\": {\"name\": \"test_disabled_check_nothing\", \"resource_type\": \"macro\", \"package_name\": \"test\", \"path\": \"macros/disabled_dummy_test.sql\", \"original_file_path\": \"macros/disabled_dummy_test.sql\", \"unique_id\": \"macro.test.test_disabled_check_nothing\", \"macro_sql\": \"{% test disabled_check_nothing(model) %}\\n-- a silly test to make sure that table-level tests show up in the manifest\\n-- without a column_name field\\n\\n{{ config(enabled=False) }}\\nselect 0\\n\\n{% endtest %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.549314, \"supported_languages\": null}, \"macro.test.do_nothing\": {\"name\": \"do_nothing\", \"resource_type\": \"macro\", \"package_name\": \"test\", \"path\": \"macros/do_nothing.sql\", \"original_file_path\": \"macros/do_nothing.sql\", \"unique_id\": \"macro.test.do_nothing\", \"macro_sql\": \"{% macro do_nothing(foo2, bar2) %}\\n    select\\n        '{{ foo2 }}' as foo2,\\n        '{{ bar2 }}' as bar2\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.549501, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__current_timestamp\": {\"name\": \"postgres__current_timestamp\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/timestamps.sql\", \"original_file_path\": \"macros/timestamps.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__current_timestamp\", \"macro_sql\": \"{% macro postgres__current_timestamp() -%}\\n    now()\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.5497909, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__snapshot_string_as_time\": {\"name\": \"postgres__snapshot_string_as_time\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/timestamps.sql\", \"original_file_path\": \"macros/timestamps.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__snapshot_string_as_time\", \"macro_sql\": \"{% macro postgres__snapshot_string_as_time(timestamp) -%}\\n    {%- set result = \\\"'\\\" ~ timestamp ~ \\\"'::timestamp without time zone\\\" -%}\\n    {{ return(result) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.549994, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__snapshot_get_time\": {\"name\": \"postgres__snapshot_get_time\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/timestamps.sql\", \"original_file_path\": \"macros/timestamps.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__snapshot_get_time\", \"macro_sql\": \"{% macro postgres__snapshot_get_time() -%}\\n  {{ current_timestamp() }}::timestamp without time zone\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.5501041, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__current_timestamp_backcompat\": {\"name\": \"postgres__current_timestamp_backcompat\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/timestamps.sql\", \"original_file_path\": \"macros/timestamps.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__current_timestamp_backcompat\", \"macro_sql\": \"{% macro postgres__current_timestamp_backcompat() %}\\n    current_timestamp::{{ type_timestamp() }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.type_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.5502121, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__current_timestamp_in_utc_backcompat\": {\"name\": \"postgres__current_timestamp_in_utc_backcompat\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/timestamps.sql\", \"original_file_path\": \"macros/timestamps.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__current_timestamp_in_utc_backcompat\", \"macro_sql\": \"{% macro postgres__current_timestamp_in_utc_backcompat() %}\\n    (current_timestamp at time zone 'utc')::{{ type_timestamp() }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.type_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.5503209, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_catalog\": {\"name\": \"postgres__get_catalog\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/catalog.sql\", \"original_file_path\": \"macros/catalog.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_catalog\", \"macro_sql\": \"{% macro postgres__get_catalog(information_schema, schemas) -%}\\n\\n  {%- call statement('catalog', fetch_result=True) -%}\\n    {#\\n      If the user has multiple databases set and the first one is wrong, this will fail.\\n      But we won't fail in the case where there are multiple quoting-difference-only dbs, which is better.\\n    #}\\n    {% set database = information_schema.database %}\\n    {{ adapter.verify_database(database) }}\\n\\n    select\\n        '{{ database }}' as table_database,\\n        sch.nspname as table_schema,\\n        tbl.relname as table_name,\\n        case tbl.relkind\\n            when 'v' then 'VIEW'\\n            else 'BASE TABLE'\\n        end as table_type,\\n        tbl_desc.description as table_comment,\\n        col.attname as column_name,\\n        col.attnum as column_index,\\n        pg_catalog.format_type(col.atttypid, col.atttypmod) as column_type,\\n        col_desc.description as column_comment,\\n        pg_get_userbyid(tbl.relowner) as table_owner\\n\\n    from pg_catalog.pg_namespace sch\\n    join pg_catalog.pg_class tbl on tbl.relnamespace = sch.oid\\n    join pg_catalog.pg_attribute col on col.attrelid = tbl.oid\\n    left outer join pg_catalog.pg_description tbl_desc on (tbl_desc.objoid = tbl.oid and tbl_desc.objsubid = 0)\\n    left outer join pg_catalog.pg_description col_desc on (col_desc.objoid = tbl.oid and col_desc.objsubid = col.attnum)\\n\\n    where (\\n        {%- for schema in schemas -%}\\n          upper(sch.nspname) = upper('{{ schema }}'){%- if not loop.last %} or {% endif -%}\\n        {%- endfor -%}\\n      )\\n      and not pg_is_other_temp_schema(sch.oid) -- not a temporary schema belonging to another session\\n      and tbl.relpersistence in ('p', 'u') -- [p]ermanent table or [u]nlogged table. Exclude [t]emporary tables\\n      and tbl.relkind in ('r', 'v', 'f', 'p') -- o[r]dinary table, [v]iew, [f]oreign table, [p]artitioned table. Other values are [i]ndex, [S]equence, [c]omposite type, [t]OAST table, [m]aterialized view\\n      and col.attnum > 0 -- negative numbers are used for system columns such as oid\\n      and not col.attisdropped -- column as not been dropped\\n\\n    order by\\n        sch.nspname,\\n        tbl.relname,\\n        col.attnum\\n\\n  {%- endcall -%}\\n\\n  {{ return(load_result('catalog').table) }}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.551399, \"supported_languages\": null}, \"macro.dbt_postgres.postgres_get_relations\": {\"name\": \"postgres_get_relations\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/relations.sql\", \"original_file_path\": \"macros/relations.sql\", \"unique_id\": \"macro.dbt_postgres.postgres_get_relations\", \"macro_sql\": \"{% macro postgres_get_relations () -%}\\n\\n  {#\\n      -- in pg_depend, objid is the dependent, refobjid is the referenced object\\n      --  > a pg_depend entry indicates that the referenced object cannot be\\n      --  > dropped without also dropping the dependent object.\\n  #}\\n\\n  {%- call statement('relations', fetch_result=True) -%}\\n    with relation as (\\n        select\\n            pg_rewrite.ev_class as class,\\n            pg_rewrite.oid as id\\n        from pg_rewrite\\n    ),\\n    class as (\\n        select\\n            oid as id,\\n            relname as name,\\n            relnamespace as schema,\\n            relkind as kind\\n        from pg_class\\n    ),\\n    dependency as (\\n        select distinct\\n            pg_depend.objid as id,\\n            pg_depend.refobjid as ref\\n        from pg_depend\\n    ),\\n    schema as (\\n        select\\n            pg_namespace.oid as id,\\n            pg_namespace.nspname as name\\n        from pg_namespace\\n        where nspname != 'information_schema' and nspname not like 'pg\\\\_%'\\n    ),\\n    referenced as (\\n        select\\n            relation.id AS id,\\n            referenced_class.name ,\\n            referenced_class.schema ,\\n            referenced_class.kind\\n        from relation\\n        join class as referenced_class on relation.class=referenced_class.id\\n        where referenced_class.kind in ('r', 'v')\\n    ),\\n    relationships as (\\n        select\\n            referenced.name as referenced_name,\\n            referenced.schema as referenced_schema_id,\\n            dependent_class.name as dependent_name,\\n            dependent_class.schema as dependent_schema_id,\\n            referenced.kind as kind\\n        from referenced\\n        join dependency on referenced.id=dependency.id\\n        join class as dependent_class on dependency.ref=dependent_class.id\\n        where\\n            (referenced.name != dependent_class.name or\\n             referenced.schema != dependent_class.schema)\\n    )\\n\\n    select\\n        referenced_schema.name as referenced_schema,\\n        relationships.referenced_name as referenced_name,\\n        dependent_schema.name as dependent_schema,\\n        relationships.dependent_name as dependent_name\\n    from relationships\\n    join schema as dependent_schema on relationships.dependent_schema_id=dependent_schema.id\\n    join schema as referenced_schema on relationships.referenced_schema_id=referenced_schema.id\\n    group by referenced_schema, referenced_name, dependent_schema, dependent_name\\n    order by referenced_schema, referenced_name, dependent_schema, dependent_name;\\n\\n  {%- endcall -%}\\n\\n  {{ return(load_result('relations').table) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.552023, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__create_table_as\": {\"name\": \"postgres__create_table_as\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__create_table_as\", \"macro_sql\": \"{% macro postgres__create_table_as(temporary, relation, sql) -%}\\n  {%- set unlogged = config.get('unlogged', default=false) -%}\\n  {%- set sql_header = config.get('sql_header', none) -%}\\n\\n  {{ sql_header if sql_header is not none }}\\n\\n  create {% if temporary -%}\\n    temporary\\n  {%- elif unlogged -%}\\n    unlogged\\n  {%- endif %} table {{ relation }}\\n  {% set contract_config = config.get('contract') %}\\n  {% if contract_config.enforced %}\\n    {{ get_assert_columns_equivalent(sql) }}\\n    {{ get_columns_spec_ddl() }} ;\\n    insert into {{ relation }} {{ get_column_names() }}\\n    {%- set sql = get_select_subquery(sql) %}\\n  {% else %}\\n    as\\n  {% endif %}\\n  (\\n    {{ sql }}\\n  );\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_assert_columns_equivalent\", \"macro.dbt.get_columns_spec_ddl\", \"macro.dbt_postgres.get_column_names\", \"macro.dbt.get_select_subquery\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.5590951, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_create_index_sql\": {\"name\": \"postgres__get_create_index_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_create_index_sql\", \"macro_sql\": \"{% macro postgres__get_create_index_sql(relation, index_dict) -%}\\n  {%- set index_config = adapter.parse_index(index_dict) -%}\\n  {%- set comma_separated_columns = \\\", \\\".join(index_config.columns) -%}\\n  {%- set index_name = index_config.render(relation) -%}\\n\\n  create {% if index_config.unique -%}\\n    unique\\n  {%- endif %} index if not exists\\n  \\\"{{ index_name }}\\\"\\n  on {{ relation }} {% if index_config.type -%}\\n    using {{ index_config.type }}\\n  {%- endif %}\\n  ({{ comma_separated_columns }});\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.559607, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__create_schema\": {\"name\": \"postgres__create_schema\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__create_schema\", \"macro_sql\": \"{% macro postgres__create_schema(relation) -%}\\n  {% if relation.database -%}\\n    {{ adapter.verify_database(relation.database) }}\\n  {%- endif -%}\\n  {%- call statement('create_schema') -%}\\n    create schema if not exists {{ relation.without_identifier().include(database=False) }}\\n  {%- endcall -%}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.5599282, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__drop_schema\": {\"name\": \"postgres__drop_schema\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__drop_schema\", \"macro_sql\": \"{% macro postgres__drop_schema(relation) -%}\\n  {% if relation.database -%}\\n    {{ adapter.verify_database(relation.database) }}\\n  {%- endif -%}\\n  {%- call statement('drop_schema') -%}\\n    drop schema if exists {{ relation.without_identifier().include(database=False) }} cascade\\n  {%- endcall -%}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.560247, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_columns_in_relation\": {\"name\": \"postgres__get_columns_in_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_columns_in_relation\", \"macro_sql\": \"{% macro postgres__get_columns_in_relation(relation) -%}\\n  {% call statement('get_columns_in_relation', fetch_result=True) %}\\n      select\\n          column_name,\\n          data_type,\\n          character_maximum_length,\\n          numeric_precision,\\n          numeric_scale\\n\\n      from {{ relation.information_schema('columns') }}\\n      where table_name = '{{ relation.identifier }}'\\n        {% if relation.schema %}\\n        and table_schema = '{{ relation.schema }}'\\n        {% endif %}\\n      order by ordinal_position\\n\\n  {% endcall %}\\n  {% set table = load_result('get_columns_in_relation').table %}\\n  {{ return(sql_convert_columns_in_relation(table)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\", \"macro.dbt.sql_convert_columns_in_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.5607271, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__list_relations_without_caching\": {\"name\": \"postgres__list_relations_without_caching\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__list_relations_without_caching\", \"macro_sql\": \"{% macro postgres__list_relations_without_caching(schema_relation) %}\\n  {% call statement('list_relations_without_caching', fetch_result=True) -%}\\n    select\\n      '{{ schema_relation.database }}' as database,\\n      tablename as name,\\n      schemaname as schema,\\n      'table' as type\\n    from pg_tables\\n    where schemaname ilike '{{ schema_relation.schema }}'\\n    union all\\n    select\\n      '{{ schema_relation.database }}' as database,\\n      viewname as name,\\n      schemaname as schema,\\n      'view' as type\\n    from pg_views\\n    where schemaname ilike '{{ schema_relation.schema }}'\\n  {% endcall %}\\n  {{ return(load_result('list_relations_without_caching').table) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.5611079, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__information_schema_name\": {\"name\": \"postgres__information_schema_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__information_schema_name\", \"macro_sql\": \"{% macro postgres__information_schema_name(database) -%}\\n  {% if database_name -%}\\n    {{ adapter.verify_database(database_name) }}\\n  {%- endif -%}\\n  information_schema\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.561283, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__list_schemas\": {\"name\": \"postgres__list_schemas\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__list_schemas\", \"macro_sql\": \"{% macro postgres__list_schemas(database) %}\\n  {% if database -%}\\n    {{ adapter.verify_database(database) }}\\n  {%- endif -%}\\n  {% call statement('list_schemas', fetch_result=True, auto_begin=False) %}\\n    select distinct nspname from pg_namespace\\n  {% endcall %}\\n  {{ return(load_result('list_schemas').table) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.561631, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__check_schema_exists\": {\"name\": \"postgres__check_schema_exists\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__check_schema_exists\", \"macro_sql\": \"{% macro postgres__check_schema_exists(information_schema, schema) -%}\\n  {% if information_schema.database -%}\\n    {{ adapter.verify_database(information_schema.database) }}\\n  {%- endif -%}\\n  {% call statement('check_schema_exists', fetch_result=True, auto_begin=False) %}\\n    select count(*) from pg_namespace where nspname = '{{ schema }}'\\n  {% endcall %}\\n  {{ return(load_result('check_schema_exists').table) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.56203, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__make_relation_with_suffix\": {\"name\": \"postgres__make_relation_with_suffix\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__make_relation_with_suffix\", \"macro_sql\": \"{% macro postgres__make_relation_with_suffix(base_relation, suffix, dstring) %}\\n    {% if dstring %}\\n      {% set dt = modules.datetime.datetime.now() %}\\n      {% set dtstring = dt.strftime(\\\"%H%M%S%f\\\") %}\\n      {% set suffix = suffix ~ dtstring %}\\n    {% endif %}\\n    {% set suffix_length = suffix|length %}\\n    {% set relation_max_name_length = base_relation.relation_max_name_length() %}\\n    {% if suffix_length > relation_max_name_length %}\\n        {% do exceptions.raise_compiler_error('Relation suffix is too long (' ~ suffix_length ~ ' characters). Maximum length is ' ~ relation_max_name_length ~ ' characters.') %}\\n    {% endif %}\\n    {% set identifier = base_relation.identifier[:relation_max_name_length - suffix_length] ~ suffix %}\\n\\n    {{ return(base_relation.incorporate(path={\\\"identifier\\\": identifier })) }}\\n\\n  {% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.562905, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__make_intermediate_relation\": {\"name\": \"postgres__make_intermediate_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__make_intermediate_relation\", \"macro_sql\": \"{% macro postgres__make_intermediate_relation(base_relation, suffix) %}\\n    {{ return(postgres__make_relation_with_suffix(base_relation, suffix, dstring=False)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_relation_with_suffix\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.5631082, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__make_temp_relation\": {\"name\": \"postgres__make_temp_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__make_temp_relation\", \"macro_sql\": \"{% macro postgres__make_temp_relation(base_relation, suffix) %}\\n    {% set temp_relation = postgres__make_relation_with_suffix(base_relation, suffix, dstring=True) %}\\n    {{ return(temp_relation.incorporate(path={\\\"schema\\\": none,\\n                                              \\\"database\\\": none})) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_relation_with_suffix\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.563437, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__make_backup_relation\": {\"name\": \"postgres__make_backup_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__make_backup_relation\", \"macro_sql\": \"{% macro postgres__make_backup_relation(base_relation, backup_relation_type, suffix) %}\\n    {% set backup_relation = postgres__make_relation_with_suffix(base_relation, suffix, dstring=False) %}\\n    {{ return(backup_relation.incorporate(type=backup_relation_type)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_relation_with_suffix\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.563714, \"supported_languages\": null}, \"macro.dbt_postgres.postgres_escape_comment\": {\"name\": \"postgres_escape_comment\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres_escape_comment\", \"macro_sql\": \"{% macro postgres_escape_comment(comment) -%}\\n  {% if comment is not string %}\\n    {% do exceptions.raise_compiler_error('cannot escape a non-string: ' ~ comment) %}\\n  {% endif %}\\n  {%- set magic = '$dbt_comment_literal_block$' -%}\\n  {%- if magic in comment -%}\\n    {%- do exceptions.raise_compiler_error('The string ' ~ magic ~ ' is not allowed in comments.') -%}\\n  {%- endif -%}\\n  {{ magic }}{{ comment }}{{ magic }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.564138, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__alter_relation_comment\": {\"name\": \"postgres__alter_relation_comment\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__alter_relation_comment\", \"macro_sql\": \"{% macro postgres__alter_relation_comment(relation, comment) %}\\n  {% set escaped_comment = postgres_escape_comment(comment) %}\\n  comment on {{ relation.type }} {{ relation }} is {{ escaped_comment }};\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres_escape_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.564367, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__alter_column_comment\": {\"name\": \"postgres__alter_column_comment\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__alter_column_comment\", \"macro_sql\": \"{% macro postgres__alter_column_comment(relation, column_dict) %}\\n  {% set existing_columns = adapter.get_columns_in_relation(relation) | map(attribute=\\\"name\\\") | list %}\\n  {% for column_name in column_dict if (column_name in existing_columns) %}\\n    {% set comment = column_dict[column_name]['description'] %}\\n    {% set escaped_comment = postgres_escape_comment(comment) %}\\n    comment on column {{ relation }}.{{ adapter.quote(column_name) if column_dict[column_name]['quote'] else column_name }} is {{ escaped_comment }};\\n  {% endfor %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres_escape_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.5649762, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_show_grant_sql\": {\"name\": \"postgres__get_show_grant_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_show_grant_sql\", \"macro_sql\": \"\\n\\n{%- macro postgres__get_show_grant_sql(relation) -%}\\n  select grantee, privilege_type\\n  from {{ relation.information_schema('role_table_grants') }}\\n      where grantor = current_role\\n        and grantee != current_role\\n        and table_schema = '{{ relation.schema }}'\\n        and table_name = '{{ relation.identifier }}'\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.565191, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__copy_grants\": {\"name\": \"postgres__copy_grants\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/adapters.sql\", \"original_file_path\": \"macros/adapters.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__copy_grants\", \"macro_sql\": \"{% macro postgres__copy_grants() %}\\n    {{ return(False) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.565307, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__get_incremental_default_sql\": {\"name\": \"postgres__get_incremental_default_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/materializations/incremental_strategies.sql\", \"original_file_path\": \"macros/materializations/incremental_strategies.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__get_incremental_default_sql\", \"macro_sql\": \"{% macro postgres__get_incremental_default_sql(arg_dict) %}\\n\\n  {% if arg_dict[\\\"unique_key\\\"] %}\\n    {% do return(get_incremental_delete_insert_sql(arg_dict)) %}\\n  {% else %}\\n    {% do return(get_incremental_append_sql(arg_dict)) %}\\n  {% endif %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_incremental_delete_insert_sql\", \"macro.dbt.get_incremental_append_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.565693, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__snapshot_merge_sql\": {\"name\": \"postgres__snapshot_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/materializations/snapshot_merge.sql\", \"original_file_path\": \"macros/materializations/snapshot_merge.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__snapshot_merge_sql\", \"macro_sql\": \"{% macro postgres__snapshot_merge_sql(target, source, insert_cols) -%}\\n    {%- set insert_cols_csv = insert_cols | join(', ') -%}\\n\\n    update {{ target }}\\n    set dbt_valid_to = DBT_INTERNAL_SOURCE.dbt_valid_to\\n    from {{ source }} as DBT_INTERNAL_SOURCE\\n    where DBT_INTERNAL_SOURCE.dbt_scd_id::text = {{ target }}.dbt_scd_id::text\\n      and DBT_INTERNAL_SOURCE.dbt_change_type::text in ('update'::text, 'delete'::text)\\n      and {{ target }}.dbt_valid_to is null;\\n\\n    insert into {{ target }} ({{ insert_cols_csv }})\\n    select {% for column in insert_cols -%}\\n        DBT_INTERNAL_SOURCE.{{ column }} {%- if not loop.last %}, {%- endif %}\\n    {%- endfor %}\\n    from {{ source }} as DBT_INTERNAL_SOURCE\\n    where DBT_INTERNAL_SOURCE.dbt_change_type::text = 'insert'::text;\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.5664032, \"supported_languages\": null}, \"macro.dbt_postgres.get_column_names\": {\"name\": \"get_column_names\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/utils/columns_spec_ddl.sql\", \"original_file_path\": \"macros/utils/columns_spec_ddl.sql\", \"unique_id\": \"macro.dbt_postgres.get_column_names\", \"macro_sql\": \"{% macro get_column_names() %}\\n  {# loop through user_provided_columns to get column names #}\\n    {%- set user_provided_columns = model['columns'] -%}\\n    (\\n    {% for i in user_provided_columns %}\\n      {% set col = user_provided_columns[i] %}\\n      {{ col['name'] }} {{ \\\",\\\" if not loop.last }}\\n    {% endfor %}\\n  )\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.566866, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__dateadd\": {\"name\": \"postgres__dateadd\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/utils/dateadd.sql\", \"original_file_path\": \"macros/utils/dateadd.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__dateadd\", \"macro_sql\": \"{% macro postgres__dateadd(datepart, interval, from_date_or_timestamp) %}\\n\\n    {{ from_date_or_timestamp }} + ((interval '1 {{ datepart }}') * ({{ interval }}))\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.567093, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__listagg\": {\"name\": \"postgres__listagg\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/utils/listagg.sql\", \"original_file_path\": \"macros/utils/listagg.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__listagg\", \"macro_sql\": \"{% macro postgres__listagg(measure, delimiter_text, order_by_clause, limit_num) -%}\\n\\n    {% if limit_num -%}\\n    array_to_string(\\n        (array_agg(\\n            {{ measure }}\\n            {% if order_by_clause -%}\\n            {{ order_by_clause }}\\n            {%- endif %}\\n        ))[1:{{ limit_num }}],\\n        {{ delimiter_text }}\\n        )\\n    {%- else %}\\n    string_agg(\\n        {{ measure }},\\n        {{ delimiter_text }}\\n        {% if order_by_clause -%}\\n        {{ order_by_clause }}\\n        {%- endif %}\\n        )\\n    {%- endif %}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.5678, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__datediff\": {\"name\": \"postgres__datediff\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/utils/datediff.sql\", \"original_file_path\": \"macros/utils/datediff.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__datediff\", \"macro_sql\": \"{% macro postgres__datediff(first_date, second_date, datepart) -%}\\n\\n    {% if datepart == 'year' %}\\n        (date_part('year', ({{second_date}})::date) - date_part('year', ({{first_date}})::date))\\n    {% elif datepart == 'quarter' %}\\n        ({{ datediff(first_date, second_date, 'year') }} * 4 + date_part('quarter', ({{second_date}})::date) - date_part('quarter', ({{first_date}})::date))\\n    {% elif datepart == 'month' %}\\n        ({{ datediff(first_date, second_date, 'year') }} * 12 + date_part('month', ({{second_date}})::date) - date_part('month', ({{first_date}})::date))\\n    {% elif datepart == 'day' %}\\n        (({{second_date}})::date - ({{first_date}})::date)\\n    {% elif datepart == 'week' %}\\n        ({{ datediff(first_date, second_date, 'day') }} / 7 + case\\n            when date_part('dow', ({{first_date}})::timestamp) <= date_part('dow', ({{second_date}})::timestamp) then\\n                case when {{first_date}} <= {{second_date}} then 0 else -1 end\\n            else\\n                case when {{first_date}} <= {{second_date}} then 1 else 0 end\\n        end)\\n    {% elif datepart == 'hour' %}\\n        ({{ datediff(first_date, second_date, 'day') }} * 24 + date_part('hour', ({{second_date}})::timestamp) - date_part('hour', ({{first_date}})::timestamp))\\n    {% elif datepart == 'minute' %}\\n        ({{ datediff(first_date, second_date, 'hour') }} * 60 + date_part('minute', ({{second_date}})::timestamp) - date_part('minute', ({{first_date}})::timestamp))\\n    {% elif datepart == 'second' %}\\n        ({{ datediff(first_date, second_date, 'minute') }} * 60 + floor(date_part('second', ({{second_date}})::timestamp)) - floor(date_part('second', ({{first_date}})::timestamp)))\\n    {% elif datepart == 'millisecond' %}\\n        ({{ datediff(first_date, second_date, 'minute') }} * 60000 + floor(date_part('millisecond', ({{second_date}})::timestamp)) - floor(date_part('millisecond', ({{first_date}})::timestamp)))\\n    {% elif datepart == 'microsecond' %}\\n        ({{ datediff(first_date, second_date, 'minute') }} * 60000000 + floor(date_part('microsecond', ({{second_date}})::timestamp)) - floor(date_part('microsecond', ({{first_date}})::timestamp)))\\n    {% else %}\\n        {{ exceptions.raise_compiler_error(\\\"Unsupported datepart for macro datediff in postgres: {!r}\\\".format(datepart)) }}\\n    {% endif %}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.datediff\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.571049, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__any_value\": {\"name\": \"postgres__any_value\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/utils/any_value.sql\", \"original_file_path\": \"macros/utils/any_value.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__any_value\", \"macro_sql\": \"{% macro postgres__any_value(expression) -%}\\n\\n    min({{ expression }})\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.5712, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__last_day\": {\"name\": \"postgres__last_day\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/utils/last_day.sql\", \"original_file_path\": \"macros/utils/last_day.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__last_day\", \"macro_sql\": \"{% macro postgres__last_day(date, datepart) -%}\\n\\n    {%- if datepart == 'quarter' -%}\\n    -- postgres dateadd does not support quarter interval.\\n    cast(\\n        {{dbt.dateadd('day', '-1',\\n        dbt.dateadd('month', '3', dbt.date_trunc(datepart, date))\\n        )}}\\n        as date)\\n    {%- else -%}\\n    {{dbt.default_last_day(date, datepart)}}\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.dateadd\", \"macro.dbt.date_trunc\", \"macro.dbt.default_last_day\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.571703, \"supported_languages\": null}, \"macro.dbt_postgres.postgres__split_part\": {\"name\": \"postgres__split_part\", \"resource_type\": \"macro\", \"package_name\": \"dbt_postgres\", \"path\": \"macros/utils/split_part.sql\", \"original_file_path\": \"macros/utils/split_part.sql\", \"unique_id\": \"macro.dbt_postgres.postgres__split_part\", \"macro_sql\": \"{% macro postgres__split_part(string_text, delimiter_text, part_number) %}\\n\\n  {% if part_number >= 0 %}\\n    {{ dbt.default__split_part(string_text, delimiter_text, part_number) }}\\n  {% else %}\\n    {{ dbt._split_part_negative(string_text, delimiter_text, part_number) }}\\n  {% endif %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__split_part\", \"macro.dbt._split_part_negative\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.572116, \"supported_languages\": null}, \"macro.dbt.run_hooks\": {\"name\": \"run_hooks\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"unique_id\": \"macro.dbt.run_hooks\", \"macro_sql\": \"{% macro run_hooks(hooks, inside_transaction=True) %}\\n  {% for hook in hooks | selectattr('transaction', 'equalto', inside_transaction)  %}\\n    {% if not inside_transaction and loop.first %}\\n      {% call statement(auto_begin=inside_transaction) %}\\n        commit;\\n      {% endcall %}\\n    {% endif %}\\n    {% set rendered = render(hook.get('sql')) | trim %}\\n    {% if (rendered | length) > 0 %}\\n      {% call statement(auto_begin=inside_transaction) %}\\n        {{ rendered }}\\n      {% endcall %}\\n    {% endif %}\\n  {% endfor %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.573218, \"supported_languages\": null}, \"macro.dbt.make_hook_config\": {\"name\": \"make_hook_config\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"unique_id\": \"macro.dbt.make_hook_config\", \"macro_sql\": \"{% macro make_hook_config(sql, inside_transaction) %}\\n    {{ tojson({\\\"sql\\\": sql, \\\"transaction\\\": inside_transaction}) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.573418, \"supported_languages\": null}, \"macro.dbt.before_begin\": {\"name\": \"before_begin\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"unique_id\": \"macro.dbt.before_begin\", \"macro_sql\": \"{% macro before_begin(sql) %}\\n    {{ make_hook_config(sql, inside_transaction=False) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.make_hook_config\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.57356, \"supported_languages\": null}, \"macro.dbt.in_transaction\": {\"name\": \"in_transaction\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"unique_id\": \"macro.dbt.in_transaction\", \"macro_sql\": \"{% macro in_transaction(sql) %}\\n    {{ make_hook_config(sql, inside_transaction=True) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.make_hook_config\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.5737019, \"supported_languages\": null}, \"macro.dbt.after_commit\": {\"name\": \"after_commit\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/hooks.sql\", \"original_file_path\": \"macros/materializations/hooks.sql\", \"unique_id\": \"macro.dbt.after_commit\", \"macro_sql\": \"{% macro after_commit(sql) %}\\n    {{ make_hook_config(sql, inside_transaction=False) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.make_hook_config\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.573847, \"supported_languages\": null}, \"macro.dbt.set_sql_header\": {\"name\": \"set_sql_header\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/configs.sql\", \"original_file_path\": \"macros/materializations/configs.sql\", \"unique_id\": \"macro.dbt.set_sql_header\", \"macro_sql\": \"{% macro set_sql_header(config) -%}\\n  {{ config.set('sql_header', caller()) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.5742688, \"supported_languages\": null}, \"macro.dbt.should_full_refresh\": {\"name\": \"should_full_refresh\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/configs.sql\", \"original_file_path\": \"macros/materializations/configs.sql\", \"unique_id\": \"macro.dbt.should_full_refresh\", \"macro_sql\": \"{% macro should_full_refresh() %}\\n  {% set config_full_refresh = config.get('full_refresh') %}\\n  {% if config_full_refresh is none %}\\n    {% set config_full_refresh = flags.FULL_REFRESH %}\\n  {% endif %}\\n  {% do return(config_full_refresh) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.5745878, \"supported_languages\": null}, \"macro.dbt.should_store_failures\": {\"name\": \"should_store_failures\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/configs.sql\", \"original_file_path\": \"macros/materializations/configs.sql\", \"unique_id\": \"macro.dbt.should_store_failures\", \"macro_sql\": \"{% macro should_store_failures() %}\\n  {% set config_store_failures = config.get('store_failures') %}\\n  {% if config_store_failures is none %}\\n    {% set config_store_failures = flags.STORE_FAILURES %}\\n  {% endif %}\\n  {% do return(config_store_failures) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.574906, \"supported_languages\": null}, \"macro.dbt.snapshot_merge_sql\": {\"name\": \"snapshot_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/snapshot_merge.sql\", \"original_file_path\": \"macros/materializations/snapshots/snapshot_merge.sql\", \"unique_id\": \"macro.dbt.snapshot_merge_sql\", \"macro_sql\": \"{% macro snapshot_merge_sql(target, source, insert_cols) -%}\\n  {{ adapter.dispatch('snapshot_merge_sql', 'dbt')(target, source, insert_cols) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__snapshot_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.575354, \"supported_languages\": null}, \"macro.dbt.default__snapshot_merge_sql\": {\"name\": \"default__snapshot_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/snapshot_merge.sql\", \"original_file_path\": \"macros/materializations/snapshots/snapshot_merge.sql\", \"unique_id\": \"macro.dbt.default__snapshot_merge_sql\", \"macro_sql\": \"{% macro default__snapshot_merge_sql(target, source, insert_cols) -%}\\n    {%- set insert_cols_csv = insert_cols | join(', ') -%}\\n\\n    merge into {{ target }} as DBT_INTERNAL_DEST\\n    using {{ source }} as DBT_INTERNAL_SOURCE\\n    on DBT_INTERNAL_SOURCE.dbt_scd_id = DBT_INTERNAL_DEST.dbt_scd_id\\n\\n    when matched\\n     and DBT_INTERNAL_DEST.dbt_valid_to is null\\n     and DBT_INTERNAL_SOURCE.dbt_change_type in ('update', 'delete')\\n        then update\\n        set dbt_valid_to = DBT_INTERNAL_SOURCE.dbt_valid_to\\n\\n    when not matched\\n     and DBT_INTERNAL_SOURCE.dbt_change_type = 'insert'\\n        then insert ({{ insert_cols_csv }})\\n        values ({{ insert_cols_csv }})\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.5756302, \"supported_languages\": null}, \"macro.dbt.strategy_dispatch\": {\"name\": \"strategy_dispatch\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"unique_id\": \"macro.dbt.strategy_dispatch\", \"macro_sql\": \"{% macro strategy_dispatch(name) -%}\\n{% set original_name = name %}\\n  {% if '.' in name %}\\n    {% set package_name, name = name.split(\\\".\\\", 1) %}\\n  {% else %}\\n    {% set package_name = none %}\\n  {% endif %}\\n\\n  {% if package_name is none %}\\n    {% set package_context = context %}\\n  {% elif package_name in context %}\\n    {% set package_context = context[package_name] %}\\n  {% else %}\\n    {% set error_msg %}\\n        Could not find package '{{package_name}}', called with '{{original_name}}'\\n    {% endset %}\\n    {{ exceptions.raise_compiler_error(error_msg | trim) }}\\n  {% endif %}\\n\\n  {%- set search_name = 'snapshot_' ~ name ~ '_strategy' -%}\\n\\n  {% if search_name not in package_context %}\\n    {% set error_msg %}\\n        The specified strategy macro '{{name}}' was not found in package '{{ package_name }}'\\n    {% endset %}\\n    {{ exceptions.raise_compiler_error(error_msg | trim) }}\\n  {% endif %}\\n  {{ return(package_context[search_name]) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.579268, \"supported_languages\": null}, \"macro.dbt.snapshot_hash_arguments\": {\"name\": \"snapshot_hash_arguments\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"unique_id\": \"macro.dbt.snapshot_hash_arguments\", \"macro_sql\": \"{% macro snapshot_hash_arguments(args) -%}\\n  {{ adapter.dispatch('snapshot_hash_arguments', 'dbt')(args) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__snapshot_hash_arguments\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.579456, \"supported_languages\": null}, \"macro.dbt.default__snapshot_hash_arguments\": {\"name\": \"default__snapshot_hash_arguments\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"unique_id\": \"macro.dbt.default__snapshot_hash_arguments\", \"macro_sql\": \"{% macro default__snapshot_hash_arguments(args) -%}\\n    md5({%- for arg in args -%}\\n        coalesce(cast({{ arg }} as varchar ), '')\\n        {% if not loop.last %} || '|' || {% endif %}\\n    {%- endfor -%})\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.579693, \"supported_languages\": null}, \"macro.dbt.snapshot_timestamp_strategy\": {\"name\": \"snapshot_timestamp_strategy\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"unique_id\": \"macro.dbt.snapshot_timestamp_strategy\", \"macro_sql\": \"{% macro snapshot_timestamp_strategy(node, snapshotted_rel, current_rel, config, target_exists) %}\\n    {% set primary_key = config['unique_key'] %}\\n    {% set updated_at = config['updated_at'] %}\\n    {% set invalidate_hard_deletes = config.get('invalidate_hard_deletes', false) %}\\n\\n    {#/*\\n        The snapshot relation might not have an {{ updated_at }} value if the\\n        snapshot strategy is changed from `check` to `timestamp`. We\\n        should use a dbt-created column for the comparison in the snapshot\\n        table instead of assuming that the user-supplied {{ updated_at }}\\n        will be present in the historical data.\\n\\n        See https://github.com/dbt-labs/dbt-core/issues/2350\\n    */ #}\\n    {% set row_changed_expr -%}\\n        ({{ snapshotted_rel }}.dbt_valid_from < {{ current_rel }}.{{ updated_at }})\\n    {%- endset %}\\n\\n    {% set scd_id_expr = snapshot_hash_arguments([primary_key, updated_at]) %}\\n\\n    {% do return({\\n        \\\"unique_key\\\": primary_key,\\n        \\\"updated_at\\\": updated_at,\\n        \\\"row_changed\\\": row_changed_expr,\\n        \\\"scd_id\\\": scd_id_expr,\\n        \\\"invalidate_hard_deletes\\\": invalidate_hard_deletes\\n    }) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.snapshot_hash_arguments\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.5804448, \"supported_languages\": null}, \"macro.dbt.snapshot_string_as_time\": {\"name\": \"snapshot_string_as_time\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"unique_id\": \"macro.dbt.snapshot_string_as_time\", \"macro_sql\": \"{% macro snapshot_string_as_time(timestamp) -%}\\n    {{ adapter.dispatch('snapshot_string_as_time', 'dbt')(timestamp) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__snapshot_string_as_time\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.5806148, \"supported_languages\": null}, \"macro.dbt.default__snapshot_string_as_time\": {\"name\": \"default__snapshot_string_as_time\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"unique_id\": \"macro.dbt.default__snapshot_string_as_time\", \"macro_sql\": \"{% macro default__snapshot_string_as_time(timestamp) %}\\n    {% do exceptions.raise_not_implemented(\\n        'snapshot_string_as_time macro not implemented for adapter '+adapter.type()\\n    ) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.5807948, \"supported_languages\": null}, \"macro.dbt.snapshot_check_all_get_existing_columns\": {\"name\": \"snapshot_check_all_get_existing_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"unique_id\": \"macro.dbt.snapshot_check_all_get_existing_columns\", \"macro_sql\": \"{% macro snapshot_check_all_get_existing_columns(node, target_exists, check_cols_config) -%}\\n    {%- if not target_exists -%}\\n        {#-- no table yet -> return whatever the query does --#}\\n        {{ return((false, query_columns)) }}\\n    {%- endif -%}\\n\\n    {#-- handle any schema changes --#}\\n    {%- set target_relation = adapter.get_relation(database=node.database, schema=node.schema, identifier=node.alias) -%}\\n\\n    {% if check_cols_config == 'all' %}\\n        {%- set query_columns = get_columns_in_query(node['compiled_code']) -%}\\n\\n    {% elif check_cols_config is iterable and (check_cols_config | length) > 0 %}\\n        {#-- query for proper casing/quoting, to support comparison below --#}\\n        {%- set select_check_cols_from_target -%}\\n          select {{ check_cols_config | join(', ') }} from ({{ node['compiled_code'] }}) subq\\n        {%- endset -%}\\n        {% set query_columns = get_columns_in_query(select_check_cols_from_target) %}\\n\\n    {% else %}\\n        {% do exceptions.raise_compiler_error(\\\"Invalid value for 'check_cols': \\\" ~ check_cols_config) %}\\n    {% endif %}\\n\\n    {%- set existing_cols = adapter.get_columns_in_relation(target_relation) | map(attribute = 'name') | list -%}\\n    {%- set ns = namespace() -%} {#-- handle for-loop scoping with a namespace --#}\\n    {%- set ns.column_added = false -%}\\n\\n    {%- set intersection = [] -%}\\n    {%- for col in query_columns -%}\\n        {%- if col in existing_cols -%}\\n            {%- do intersection.append(adapter.quote(col)) -%}\\n        {%- else -%}\\n            {% set ns.column_added = true %}\\n        {%- endif -%}\\n    {%- endfor -%}\\n    {{ return((ns.column_added, intersection)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_columns_in_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.5822341, \"supported_languages\": null}, \"macro.dbt.snapshot_check_strategy\": {\"name\": \"snapshot_check_strategy\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/strategies.sql\", \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\", \"unique_id\": \"macro.dbt.snapshot_check_strategy\", \"macro_sql\": \"{% macro snapshot_check_strategy(node, snapshotted_rel, current_rel, config, target_exists) %}\\n    {% set check_cols_config = config['check_cols'] %}\\n    {% set primary_key = config['unique_key'] %}\\n    {% set invalidate_hard_deletes = config.get('invalidate_hard_deletes', false) %}\\n    {% set updated_at = config.get('updated_at', snapshot_get_time()) %}\\n\\n    {% set column_added = false %}\\n\\n    {% set column_added, check_cols = snapshot_check_all_get_existing_columns(node, target_exists, check_cols_config) %}\\n\\n    {%- set row_changed_expr -%}\\n    (\\n    {%- if column_added -%}\\n        {{ get_true_sql() }}\\n    {%- else -%}\\n    {%- for col in check_cols -%}\\n        {{ snapshotted_rel }}.{{ col }} != {{ current_rel }}.{{ col }}\\n        or\\n        (\\n            (({{ snapshotted_rel }}.{{ col }} is null) and not ({{ current_rel }}.{{ col }} is null))\\n            or\\n            ((not {{ snapshotted_rel }}.{{ col }} is null) and ({{ current_rel }}.{{ col }} is null))\\n        )\\n        {%- if not loop.last %} or {% endif -%}\\n    {%- endfor -%}\\n    {%- endif -%}\\n    )\\n    {%- endset %}\\n\\n    {% set scd_id_expr = snapshot_hash_arguments([primary_key, updated_at]) %}\\n\\n    {% do return({\\n        \\\"unique_key\\\": primary_key,\\n        \\\"updated_at\\\": updated_at,\\n        \\\"row_changed\\\": row_changed_expr,\\n        \\\"scd_id\\\": scd_id_expr,\\n        \\\"invalidate_hard_deletes\\\": invalidate_hard_deletes\\n    }) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.snapshot_get_time\", \"macro.dbt.snapshot_check_all_get_existing_columns\", \"macro.dbt.get_true_sql\", \"macro.dbt.snapshot_hash_arguments\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.583667, \"supported_languages\": null}, \"macro.dbt.create_columns\": {\"name\": \"create_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.create_columns\", \"macro_sql\": \"{% macro create_columns(relation, columns) %}\\n  {{ adapter.dispatch('create_columns', 'dbt')(relation, columns) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__create_columns\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.587839, \"supported_languages\": null}, \"macro.dbt.default__create_columns\": {\"name\": \"default__create_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.default__create_columns\", \"macro_sql\": \"{% macro default__create_columns(relation, columns) %}\\n  {% for column in columns %}\\n    {% call statement() %}\\n      alter table {{ relation }} add column \\\"{{ column.name }}\\\" {{ column.data_type }};\\n    {% endcall %}\\n  {% endfor %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.58813, \"supported_languages\": null}, \"macro.dbt.post_snapshot\": {\"name\": \"post_snapshot\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.post_snapshot\", \"macro_sql\": \"{% macro post_snapshot(staging_relation) %}\\n  {{ adapter.dispatch('post_snapshot', 'dbt')(staging_relation) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__post_snapshot\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.5883, \"supported_languages\": null}, \"macro.dbt.default__post_snapshot\": {\"name\": \"default__post_snapshot\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.default__post_snapshot\", \"macro_sql\": \"{% macro default__post_snapshot(staging_relation) %}\\n    {# no-op #}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.588392, \"supported_languages\": null}, \"macro.dbt.get_true_sql\": {\"name\": \"get_true_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.get_true_sql\", \"macro_sql\": \"{% macro get_true_sql() %}\\n  {{ adapter.dispatch('get_true_sql', 'dbt')() }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_true_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.5885382, \"supported_languages\": null}, \"macro.dbt.default__get_true_sql\": {\"name\": \"default__get_true_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.default__get_true_sql\", \"macro_sql\": \"{% macro default__get_true_sql() %}\\n    {{ return('TRUE') }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.588657, \"supported_languages\": null}, \"macro.dbt.snapshot_staging_table\": {\"name\": \"snapshot_staging_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.snapshot_staging_table\", \"macro_sql\": \"{% macro snapshot_staging_table(strategy, source_sql, target_relation) -%}\\n  {{ adapter.dispatch('snapshot_staging_table', 'dbt')(strategy, source_sql, target_relation) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__snapshot_staging_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.588872, \"supported_languages\": null}, \"macro.dbt.default__snapshot_staging_table\": {\"name\": \"default__snapshot_staging_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.default__snapshot_staging_table\", \"macro_sql\": \"{% macro default__snapshot_staging_table(strategy, source_sql, target_relation) -%}\\n\\n    with snapshot_query as (\\n\\n        {{ source_sql }}\\n\\n    ),\\n\\n    snapshotted_data as (\\n\\n        select *,\\n            {{ strategy.unique_key }} as dbt_unique_key\\n\\n        from {{ target_relation }}\\n        where dbt_valid_to is null\\n\\n    ),\\n\\n    insertions_source_data as (\\n\\n        select\\n            *,\\n            {{ strategy.unique_key }} as dbt_unique_key,\\n            {{ strategy.updated_at }} as dbt_updated_at,\\n            {{ strategy.updated_at }} as dbt_valid_from,\\n            nullif({{ strategy.updated_at }}, {{ strategy.updated_at }}) as dbt_valid_to,\\n            {{ strategy.scd_id }} as dbt_scd_id\\n\\n        from snapshot_query\\n    ),\\n\\n    updates_source_data as (\\n\\n        select\\n            *,\\n            {{ strategy.unique_key }} as dbt_unique_key,\\n            {{ strategy.updated_at }} as dbt_updated_at,\\n            {{ strategy.updated_at }} as dbt_valid_from,\\n            {{ strategy.updated_at }} as dbt_valid_to\\n\\n        from snapshot_query\\n    ),\\n\\n    {%- if strategy.invalidate_hard_deletes %}\\n\\n    deletes_source_data as (\\n\\n        select\\n            *,\\n            {{ strategy.unique_key }} as dbt_unique_key\\n        from snapshot_query\\n    ),\\n    {% endif %}\\n\\n    insertions as (\\n\\n        select\\n            'insert' as dbt_change_type,\\n            source_data.*\\n\\n        from insertions_source_data as source_data\\n        left outer join snapshotted_data on snapshotted_data.dbt_unique_key = source_data.dbt_unique_key\\n        where snapshotted_data.dbt_unique_key is null\\n           or (\\n                snapshotted_data.dbt_unique_key is not null\\n            and (\\n                {{ strategy.row_changed }}\\n            )\\n        )\\n\\n    ),\\n\\n    updates as (\\n\\n        select\\n            'update' as dbt_change_type,\\n            source_data.*,\\n            snapshotted_data.dbt_scd_id\\n\\n        from updates_source_data as source_data\\n        join snapshotted_data on snapshotted_data.dbt_unique_key = source_data.dbt_unique_key\\n        where (\\n            {{ strategy.row_changed }}\\n        )\\n    )\\n\\n    {%- if strategy.invalidate_hard_deletes -%}\\n    ,\\n\\n    deletes as (\\n\\n        select\\n            'delete' as dbt_change_type,\\n            source_data.*,\\n            {{ snapshot_get_time() }} as dbt_valid_from,\\n            {{ snapshot_get_time() }} as dbt_updated_at,\\n            {{ snapshot_get_time() }} as dbt_valid_to,\\n            snapshotted_data.dbt_scd_id\\n\\n        from snapshotted_data\\n        left join deletes_source_data as source_data on snapshotted_data.dbt_unique_key = source_data.dbt_unique_key\\n        where source_data.dbt_unique_key is null\\n    )\\n    {%- endif %}\\n\\n    select * from insertions\\n    union all\\n    select * from updates\\n    {%- if strategy.invalidate_hard_deletes %}\\n    union all\\n    select * from deletes\\n    {%- endif %}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.snapshot_get_time\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.5897758, \"supported_languages\": null}, \"macro.dbt.build_snapshot_table\": {\"name\": \"build_snapshot_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.build_snapshot_table\", \"macro_sql\": \"{% macro build_snapshot_table(strategy, sql) -%}\\n  {{ adapter.dispatch('build_snapshot_table', 'dbt')(strategy, sql) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__build_snapshot_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.589972, \"supported_languages\": null}, \"macro.dbt.default__build_snapshot_table\": {\"name\": \"default__build_snapshot_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.default__build_snapshot_table\", \"macro_sql\": \"{% macro default__build_snapshot_table(strategy, sql) %}\\n\\n    select *,\\n        {{ strategy.scd_id }} as dbt_scd_id,\\n        {{ strategy.updated_at }} as dbt_updated_at,\\n        {{ strategy.updated_at }} as dbt_valid_from,\\n        nullif({{ strategy.updated_at }}, {{ strategy.updated_at }}) as dbt_valid_to\\n    from (\\n        {{ sql }}\\n    ) sbq\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.590228, \"supported_languages\": null}, \"macro.dbt.build_snapshot_staging_table\": {\"name\": \"build_snapshot_staging_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/helpers.sql\", \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\", \"unique_id\": \"macro.dbt.build_snapshot_staging_table\", \"macro_sql\": \"{% macro build_snapshot_staging_table(strategy, sql, target_relation) %}\\n    {% set temp_relation = make_temp_relation(target_relation) %}\\n\\n    {% set select = snapshot_staging_table(strategy, sql, target_relation) %}\\n\\n    {% call statement('build_snapshot_staging_relation') %}\\n        {{ create_table_as(True, temp_relation, select) }}\\n    {% endcall %}\\n\\n    {% do return(temp_relation) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.make_temp_relation\", \"macro.dbt.snapshot_staging_table\", \"macro.dbt.statement\", \"macro.dbt.create_table_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.5906692, \"supported_languages\": null}, \"macro.dbt.materialization_snapshot_default\": {\"name\": \"materialization_snapshot_default\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/snapshots/snapshot.sql\", \"original_file_path\": \"macros/materializations/snapshots/snapshot.sql\", \"unique_id\": \"macro.dbt.materialization_snapshot_default\", \"macro_sql\": \"{% materialization snapshot, default %}\\n  {%- set config = model['config'] -%}\\n\\n  {%- set target_table = model.get('alias', model.get('name')) -%}\\n\\n  {%- set strategy_name = config.get('strategy') -%}\\n  {%- set unique_key = config.get('unique_key') %}\\n  -- grab current tables grants config for comparision later on\\n  {%- set grant_config = config.get('grants') -%}\\n\\n  {% set target_relation_exists, target_relation = get_or_create_relation(\\n          database=model.database,\\n          schema=model.schema,\\n          identifier=target_table,\\n          type='table') -%}\\n\\n  {%- if not target_relation.is_table -%}\\n    {% do exceptions.relation_wrong_type(target_relation, 'table') %}\\n  {%- endif -%}\\n\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  {% set strategy_macro = strategy_dispatch(strategy_name) %}\\n  {% set strategy = strategy_macro(model, \\\"snapshotted_data\\\", \\\"source_data\\\", config, target_relation_exists) %}\\n\\n  {% if not target_relation_exists %}\\n\\n      {% set build_sql = build_snapshot_table(strategy, model['compiled_code']) %}\\n      {% set final_sql = create_table_as(False, target_relation, build_sql) %}\\n\\n  {% else %}\\n\\n      {{ adapter.valid_snapshot_target(target_relation) }}\\n\\n      {% set staging_table = build_snapshot_staging_table(strategy, sql, target_relation) %}\\n\\n      -- this may no-op if the database does not require column expansion\\n      {% do adapter.expand_target_column_types(from_relation=staging_table,\\n                                               to_relation=target_relation) %}\\n\\n      {% set missing_columns = adapter.get_missing_columns(staging_table, target_relation)\\n                                   | rejectattr('name', 'equalto', 'dbt_change_type')\\n                                   | rejectattr('name', 'equalto', 'DBT_CHANGE_TYPE')\\n                                   | rejectattr('name', 'equalto', 'dbt_unique_key')\\n                                   | rejectattr('name', 'equalto', 'DBT_UNIQUE_KEY')\\n                                   | list %}\\n\\n      {% do create_columns(target_relation, missing_columns) %}\\n\\n      {% set source_columns = adapter.get_columns_in_relation(staging_table)\\n                                   | rejectattr('name', 'equalto', 'dbt_change_type')\\n                                   | rejectattr('name', 'equalto', 'DBT_CHANGE_TYPE')\\n                                   | rejectattr('name', 'equalto', 'dbt_unique_key')\\n                                   | rejectattr('name', 'equalto', 'DBT_UNIQUE_KEY')\\n                                   | list %}\\n\\n      {% set quoted_source_columns = [] %}\\n      {% for column in source_columns %}\\n        {% do quoted_source_columns.append(adapter.quote(column.name)) %}\\n      {% endfor %}\\n\\n      {% set final_sql = snapshot_merge_sql(\\n            target = target_relation,\\n            source = staging_table,\\n            insert_cols = quoted_source_columns\\n         )\\n      %}\\n\\n  {% endif %}\\n\\n  {% call statement('main') %}\\n      {{ final_sql }}\\n  {% endcall %}\\n\\n  {% set should_revoke = should_revoke(target_relation_exists, full_refresh_mode=False) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {% if not target_relation_exists %}\\n    {% do create_indexes(target_relation) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  {{ adapter.commit() }}\\n\\n  {% if staging_table is defined %}\\n      {% do post_snapshot(staging_table) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{% endmaterialization %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_or_create_relation\", \"macro.dbt.run_hooks\", \"macro.dbt.strategy_dispatch\", \"macro.dbt.build_snapshot_table\", \"macro.dbt.create_table_as\", \"macro.dbt.build_snapshot_staging_table\", \"macro.dbt.create_columns\", \"macro.dbt.snapshot_merge_sql\", \"macro.dbt.statement\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\", \"macro.dbt.persist_docs\", \"macro.dbt.create_indexes\", \"macro.dbt.post_snapshot\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.5969589, \"supported_languages\": [\"sql\"]}, \"macro.dbt.materialization_test_default\": {\"name\": \"materialization_test_default\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/tests/test.sql\", \"original_file_path\": \"macros/materializations/tests/test.sql\", \"unique_id\": \"macro.dbt.materialization_test_default\", \"macro_sql\": \"{%- materialization test, default -%}\\n\\n  {% set relations = [] %}\\n\\n  {% if should_store_failures() %}\\n\\n    {% set identifier = model['alias'] %}\\n    {% set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) %}\\n    {% set target_relation = api.Relation.create(\\n        identifier=identifier, schema=schema, database=database, type='table') -%} %}\\n\\n    {% if old_relation %}\\n        {% do adapter.drop_relation(old_relation) %}\\n    {% endif %}\\n\\n    {% call statement(auto_begin=True) %}\\n        {{ create_table_as(False, target_relation, sql) }}\\n    {% endcall %}\\n\\n    {% do relations.append(target_relation) %}\\n\\n    {% set main_sql %}\\n        select *\\n        from {{ target_relation }}\\n    {% endset %}\\n\\n    {{ adapter.commit() }}\\n\\n  {% else %}\\n\\n      {% set main_sql = sql %}\\n\\n  {% endif %}\\n\\n  {% set limit = config.get('limit') %}\\n  {% set fail_calc = config.get('fail_calc') %}\\n  {% set warn_if = config.get('warn_if') %}\\n  {% set error_if = config.get('error_if') %}\\n\\n  {% call statement('main', fetch_result=True) -%}\\n\\n    {{ get_test_sql(main_sql, fail_calc, warn_if, error_if, limit)}}\\n\\n  {%- endcall %}\\n\\n  {{ return({'relations': relations}) }}\\n\\n{%- endmaterialization -%}\", \"depends_on\": {\"macros\": [\"macro.dbt.should_store_failures\", \"macro.dbt.statement\", \"macro.dbt.create_table_as\", \"macro.dbt.get_test_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.599081, \"supported_languages\": [\"sql\"]}, \"macro.dbt.get_test_sql\": {\"name\": \"get_test_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/tests/helpers.sql\", \"original_file_path\": \"macros/materializations/tests/helpers.sql\", \"unique_id\": \"macro.dbt.get_test_sql\", \"macro_sql\": \"{% macro get_test_sql(main_sql, fail_calc, warn_if, error_if, limit) -%}\\n  {{ adapter.dispatch('get_test_sql', 'dbt')(main_sql, fail_calc, warn_if, error_if, limit) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_test_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.5995462, \"supported_languages\": null}, \"macro.dbt.default__get_test_sql\": {\"name\": \"default__get_test_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/tests/helpers.sql\", \"original_file_path\": \"macros/materializations/tests/helpers.sql\", \"unique_id\": \"macro.dbt.default__get_test_sql\", \"macro_sql\": \"{% macro default__get_test_sql(main_sql, fail_calc, warn_if, error_if, limit) -%}\\n    select\\n      {{ fail_calc }} as failures,\\n      {{ fail_calc }} {{ warn_if }} as should_warn,\\n      {{ fail_calc }} {{ error_if }} as should_error\\n    from (\\n      {{ main_sql }}\\n      {{ \\\"limit \\\" ~ limit if limit != none }}\\n    ) dbt_internal_test\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.599873, \"supported_languages\": null}, \"macro.dbt.get_where_subquery\": {\"name\": \"get_where_subquery\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/tests/where_subquery.sql\", \"original_file_path\": \"macros/materializations/tests/where_subquery.sql\", \"unique_id\": \"macro.dbt.get_where_subquery\", \"macro_sql\": \"{% macro get_where_subquery(relation) -%}\\n    {% do return(adapter.dispatch('get_where_subquery', 'dbt')(relation)) %}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_where_subquery\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.600277, \"supported_languages\": null}, \"macro.dbt.default__get_where_subquery\": {\"name\": \"default__get_where_subquery\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/tests/where_subquery.sql\", \"original_file_path\": \"macros/materializations/tests/where_subquery.sql\", \"unique_id\": \"macro.dbt.default__get_where_subquery\", \"macro_sql\": \"{% macro default__get_where_subquery(relation) -%}\\n    {% set where = config.get('where', '') %}\\n    {% if where %}\\n        {%- set filtered -%}\\n            (select * from {{ relation }} where {{ where }}) dbt_subquery\\n        {%- endset -%}\\n        {% do return(filtered) %}\\n    {%- else -%}\\n        {% do return(relation) %}\\n    {%- endif -%}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.600673, \"supported_languages\": null}, \"macro.dbt.get_quoted_csv\": {\"name\": \"get_quoted_csv\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"unique_id\": \"macro.dbt.get_quoted_csv\", \"macro_sql\": \"{% macro get_quoted_csv(column_names) %}\\n\\n    {% set quoted = [] %}\\n    {% for col in column_names -%}\\n        {%- do quoted.append(adapter.quote(col)) -%}\\n    {%- endfor %}\\n\\n    {%- set dest_cols_csv = quoted | join(', ') -%}\\n    {{ return(dest_cols_csv) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6024802, \"supported_languages\": null}, \"macro.dbt.diff_columns\": {\"name\": \"diff_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"unique_id\": \"macro.dbt.diff_columns\", \"macro_sql\": \"{% macro diff_columns(source_columns, target_columns) %}\\n\\n  {% set result = [] %}\\n  {% set source_names = source_columns | map(attribute = 'column') | list %}\\n  {% set target_names = target_columns | map(attribute = 'column') | list %}\\n\\n   {# --check whether the name attribute exists in the target - this does not perform a data type check #}\\n   {% for sc in source_columns %}\\n     {% if sc.name not in target_names %}\\n        {{ result.append(sc) }}\\n     {% endif %}\\n   {% endfor %}\\n\\n  {{ return(result) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.603078, \"supported_languages\": null}, \"macro.dbt.diff_column_data_types\": {\"name\": \"diff_column_data_types\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"unique_id\": \"macro.dbt.diff_column_data_types\", \"macro_sql\": \"{% macro diff_column_data_types(source_columns, target_columns) %}\\n\\n  {% set result = [] %}\\n  {% for sc in source_columns %}\\n    {% set tc = target_columns | selectattr(\\\"name\\\", \\\"equalto\\\", sc.name) | list | first %}\\n    {% if tc %}\\n      {% if sc.data_type != tc.data_type and not sc.can_expand_to(other_column=tc) %}\\n        {{ result.append( { 'column_name': tc.name, 'new_type': sc.data_type } ) }}\\n      {% endif %}\\n    {% endif %}\\n  {% endfor %}\\n\\n  {{ return(result) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.603765, \"supported_languages\": null}, \"macro.dbt.get_merge_update_columns\": {\"name\": \"get_merge_update_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"unique_id\": \"macro.dbt.get_merge_update_columns\", \"macro_sql\": \"{% macro get_merge_update_columns(merge_update_columns, merge_exclude_columns, dest_columns) %}\\n  {{ return(adapter.dispatch('get_merge_update_columns', 'dbt')(merge_update_columns, merge_exclude_columns, dest_columns)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_merge_update_columns\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6040099, \"supported_languages\": null}, \"macro.dbt.default__get_merge_update_columns\": {\"name\": \"default__get_merge_update_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\", \"unique_id\": \"macro.dbt.default__get_merge_update_columns\", \"macro_sql\": \"{% macro default__get_merge_update_columns(merge_update_columns, merge_exclude_columns, dest_columns) %}\\n  {%- set default_cols = dest_columns | map(attribute=\\\"quoted\\\") | list -%}\\n\\n  {%- if merge_update_columns and merge_exclude_columns -%}\\n    {{ exceptions.raise_compiler_error(\\n        'Model cannot specify merge_update_columns and merge_exclude_columns. Please update model to use only one config'\\n    )}}\\n  {%- elif merge_update_columns -%}\\n    {%- set update_columns = merge_update_columns -%}\\n  {%- elif merge_exclude_columns -%}\\n    {%- set update_columns = [] -%}\\n    {%- for column in dest_columns -%}\\n      {% if column.column | lower not in merge_exclude_columns | map(\\\"lower\\\") | list %}\\n        {%- do update_columns.append(column.quoted) -%}\\n      {% endif %}\\n    {%- endfor -%}\\n  {%- else -%}\\n    {%- set update_columns = default_cols -%}\\n  {%- endif -%}\\n\\n  {{ return(update_columns) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.604749, \"supported_languages\": null}, \"macro.dbt.get_merge_sql\": {\"name\": \"get_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"unique_id\": \"macro.dbt.get_merge_sql\", \"macro_sql\": \"{% macro get_merge_sql(target, source, unique_key, dest_columns, incremental_predicates=none) -%}\\n   -- back compat for old kwarg name\\n  {% set incremental_predicates = kwargs.get('predicates', incremental_predicates) %}\\n  {{ adapter.dispatch('get_merge_sql', 'dbt')(target, source, unique_key, dest_columns, incremental_predicates) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.61131, \"supported_languages\": null}, \"macro.dbt.default__get_merge_sql\": {\"name\": \"default__get_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"unique_id\": \"macro.dbt.default__get_merge_sql\", \"macro_sql\": \"{% macro default__get_merge_sql(target, source, unique_key, dest_columns, incremental_predicates=none) -%}\\n    {%- set predicates = [] if incremental_predicates is none else [] + incremental_predicates -%}\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n    {%- set merge_update_columns = config.get('merge_update_columns') -%}\\n    {%- set merge_exclude_columns = config.get('merge_exclude_columns') -%}\\n    {%- set update_columns = get_merge_update_columns(merge_update_columns, merge_exclude_columns, dest_columns) -%}\\n    {%- set sql_header = config.get('sql_header', none) -%}\\n\\n    {% if unique_key %}\\n        {% if unique_key is sequence and unique_key is not mapping and unique_key is not string %}\\n            {% for key in unique_key %}\\n                {% set this_key_match %}\\n                    DBT_INTERNAL_SOURCE.{{ key }} = DBT_INTERNAL_DEST.{{ key }}\\n                {% endset %}\\n                {% do predicates.append(this_key_match) %}\\n            {% endfor %}\\n        {% else %}\\n            {% set unique_key_match %}\\n                DBT_INTERNAL_SOURCE.{{ unique_key }} = DBT_INTERNAL_DEST.{{ unique_key }}\\n            {% endset %}\\n            {% do predicates.append(unique_key_match) %}\\n        {% endif %}\\n    {% else %}\\n        {% do predicates.append('FALSE') %}\\n    {% endif %}\\n\\n    {{ sql_header if sql_header is not none }}\\n\\n    merge into {{ target }} as DBT_INTERNAL_DEST\\n        using {{ source }} as DBT_INTERNAL_SOURCE\\n        on {{\\\"(\\\" ~ predicates | join(\\\") and (\\\") ~ \\\")\\\"}}\\n\\n    {% if unique_key %}\\n    when matched then update set\\n        {% for column_name in update_columns -%}\\n            {{ column_name }} = DBT_INTERNAL_SOURCE.{{ column_name }}\\n            {%- if not loop.last %}, {%- endif %}\\n        {%- endfor %}\\n    {% endif %}\\n\\n    when not matched then insert\\n        ({{ dest_cols_csv }})\\n    values\\n        ({{ dest_cols_csv }})\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_quoted_csv\", \"macro.dbt.get_merge_update_columns\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.613036, \"supported_languages\": null}, \"macro.dbt.get_delete_insert_merge_sql\": {\"name\": \"get_delete_insert_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"unique_id\": \"macro.dbt.get_delete_insert_merge_sql\", \"macro_sql\": \"{% macro get_delete_insert_merge_sql(target, source, unique_key, dest_columns, incremental_predicates) -%}\\n  {{ adapter.dispatch('get_delete_insert_merge_sql', 'dbt')(target, source, unique_key, dest_columns, incremental_predicates) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_delete_insert_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6133099, \"supported_languages\": null}, \"macro.dbt.default__get_delete_insert_merge_sql\": {\"name\": \"default__get_delete_insert_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"unique_id\": \"macro.dbt.default__get_delete_insert_merge_sql\", \"macro_sql\": \"{% macro default__get_delete_insert_merge_sql(target, source, unique_key, dest_columns, incremental_predicates) -%}\\n\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n\\n    {% if unique_key %}\\n        {% if unique_key is sequence and unique_key is not string %}\\n            delete from {{target }}\\n            using {{ source }}\\n            where (\\n                {% for key in unique_key %}\\n                    {{ source }}.{{ key }} = {{ target }}.{{ key }}\\n                    {{ \\\"and \\\" if not loop.last}}\\n                {% endfor %}\\n                {% if incremental_predicates %}\\n                    {% for predicate in incremental_predicates %}\\n                        and {{ predicate }}\\n                    {% endfor %}\\n                {% endif %}\\n            );\\n        {% else %}\\n            delete from {{ target }}\\n            where (\\n                {{ unique_key }}) in (\\n                select ({{ unique_key }})\\n                from {{ source }}\\n            )\\n            {%- if incremental_predicates %}\\n                {% for predicate in incremental_predicates %}\\n                    and {{ predicate }}\\n                {% endfor %}\\n            {%- endif -%};\\n\\n        {% endif %}\\n    {% endif %}\\n\\n    insert into {{ target }} ({{ dest_cols_csv }})\\n    (\\n        select {{ dest_cols_csv }}\\n        from {{ source }}\\n    )\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_quoted_csv\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.614329, \"supported_languages\": null}, \"macro.dbt.get_insert_overwrite_merge_sql\": {\"name\": \"get_insert_overwrite_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"unique_id\": \"macro.dbt.get_insert_overwrite_merge_sql\", \"macro_sql\": \"{% macro get_insert_overwrite_merge_sql(target, source, dest_columns, predicates, include_sql_header=false) -%}\\n  {{ adapter.dispatch('get_insert_overwrite_merge_sql', 'dbt')(target, source, dest_columns, predicates, include_sql_header) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_insert_overwrite_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6146078, \"supported_languages\": null}, \"macro.dbt.default__get_insert_overwrite_merge_sql\": {\"name\": \"default__get_insert_overwrite_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/merge.sql\", \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\", \"unique_id\": \"macro.dbt.default__get_insert_overwrite_merge_sql\", \"macro_sql\": \"{% macro default__get_insert_overwrite_merge_sql(target, source, dest_columns, predicates, include_sql_header) -%}\\n    {#-- The only time include_sql_header is True: --#}\\n    {#-- BigQuery + insert_overwrite strategy + \\\"static\\\" partitions config --#}\\n    {#-- We should consider including the sql header at the materialization level instead --#}\\n\\n    {%- set predicates = [] if predicates is none else [] + predicates -%}\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n    {%- set sql_header = config.get('sql_header', none) -%}\\n\\n    {{ sql_header if sql_header is not none and include_sql_header }}\\n\\n    merge into {{ target }} as DBT_INTERNAL_DEST\\n        using {{ source }} as DBT_INTERNAL_SOURCE\\n        on FALSE\\n\\n    when not matched by source\\n        {% if predicates %} and {{ predicates | join(' and ') }} {% endif %}\\n        then delete\\n\\n    when not matched then insert\\n        ({{ dest_cols_csv }})\\n    values\\n        ({{ dest_cols_csv }})\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_quoted_csv\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.615274, \"supported_languages\": null}, \"macro.dbt.is_incremental\": {\"name\": \"is_incremental\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/is_incremental.sql\", \"original_file_path\": \"macros/materializations/models/incremental/is_incremental.sql\", \"unique_id\": \"macro.dbt.is_incremental\", \"macro_sql\": \"{% macro is_incremental() %}\\n    {#-- do not run introspective queries in parsing #}\\n    {% if not execute %}\\n        {{ return(False) }}\\n    {% else %}\\n        {% set relation = adapter.get_relation(this.database, this.schema, this.table) %}\\n        {{ return(relation is not none\\n                  and relation.type == 'table'\\n                  and model.config.materialized == 'incremental'\\n                  and not should_full_refresh()) }}\\n    {% endif %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.should_full_refresh\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6159291, \"supported_languages\": null}, \"macro.dbt.get_incremental_append_sql\": {\"name\": \"get_incremental_append_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.get_incremental_append_sql\", \"macro_sql\": \"{% macro get_incremental_append_sql(arg_dict) %}\\n\\n  {{ return(adapter.dispatch('get_incremental_append_sql', 'dbt')(arg_dict)) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_incremental_append_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.616825, \"supported_languages\": null}, \"macro.dbt.default__get_incremental_append_sql\": {\"name\": \"default__get_incremental_append_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.default__get_incremental_append_sql\", \"macro_sql\": \"{% macro default__get_incremental_append_sql(arg_dict) %}\\n\\n  {% do return(get_insert_into_sql(arg_dict[\\\"target_relation\\\"], arg_dict[\\\"temp_relation\\\"], arg_dict[\\\"dest_columns\\\"])) %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_insert_into_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.617065, \"supported_languages\": null}, \"macro.dbt.get_incremental_delete_insert_sql\": {\"name\": \"get_incremental_delete_insert_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.get_incremental_delete_insert_sql\", \"macro_sql\": \"{% macro get_incremental_delete_insert_sql(arg_dict) %}\\n\\n  {{ return(adapter.dispatch('get_incremental_delete_insert_sql', 'dbt')(arg_dict)) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_incremental_delete_insert_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6172569, \"supported_languages\": null}, \"macro.dbt.default__get_incremental_delete_insert_sql\": {\"name\": \"default__get_incremental_delete_insert_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.default__get_incremental_delete_insert_sql\", \"macro_sql\": \"{% macro default__get_incremental_delete_insert_sql(arg_dict) %}\\n\\n  {% do return(get_delete_insert_merge_sql(arg_dict[\\\"target_relation\\\"], arg_dict[\\\"temp_relation\\\"], arg_dict[\\\"unique_key\\\"], arg_dict[\\\"dest_columns\\\"], arg_dict[\\\"incremental_predicates\\\"])) %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_delete_insert_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.617557, \"supported_languages\": null}, \"macro.dbt.get_incremental_merge_sql\": {\"name\": \"get_incremental_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.get_incremental_merge_sql\", \"macro_sql\": \"{% macro get_incremental_merge_sql(arg_dict) %}\\n\\n  {{ return(adapter.dispatch('get_incremental_merge_sql', 'dbt')(arg_dict)) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_incremental_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6177459, \"supported_languages\": null}, \"macro.dbt.default__get_incremental_merge_sql\": {\"name\": \"default__get_incremental_merge_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.default__get_incremental_merge_sql\", \"macro_sql\": \"{% macro default__get_incremental_merge_sql(arg_dict) %}\\n\\n  {% do return(get_merge_sql(arg_dict[\\\"target_relation\\\"], arg_dict[\\\"temp_relation\\\"], arg_dict[\\\"unique_key\\\"], arg_dict[\\\"dest_columns\\\"], arg_dict[\\\"incremental_predicates\\\"])) %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.618047, \"supported_languages\": null}, \"macro.dbt.get_incremental_insert_overwrite_sql\": {\"name\": \"get_incremental_insert_overwrite_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.get_incremental_insert_overwrite_sql\", \"macro_sql\": \"{% macro get_incremental_insert_overwrite_sql(arg_dict) %}\\n\\n  {{ return(adapter.dispatch('get_incremental_insert_overwrite_sql', 'dbt')(arg_dict)) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_incremental_insert_overwrite_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.618237, \"supported_languages\": null}, \"macro.dbt.default__get_incremental_insert_overwrite_sql\": {\"name\": \"default__get_incremental_insert_overwrite_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.default__get_incremental_insert_overwrite_sql\", \"macro_sql\": \"{% macro default__get_incremental_insert_overwrite_sql(arg_dict) %}\\n\\n  {% do return(get_insert_overwrite_merge_sql(arg_dict[\\\"target_relation\\\"], arg_dict[\\\"temp_relation\\\"], arg_dict[\\\"dest_columns\\\"], arg_dict[\\\"incremental_predicates\\\"])) %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_insert_overwrite_merge_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.618508, \"supported_languages\": null}, \"macro.dbt.get_incremental_default_sql\": {\"name\": \"get_incremental_default_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.get_incremental_default_sql\", \"macro_sql\": \"{% macro get_incremental_default_sql(arg_dict) %}\\n\\n  {{ return(adapter.dispatch('get_incremental_default_sql', 'dbt')(arg_dict)) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_incremental_default_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6187038, \"supported_languages\": null}, \"macro.dbt.default__get_incremental_default_sql\": {\"name\": \"default__get_incremental_default_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.default__get_incremental_default_sql\", \"macro_sql\": \"{% macro default__get_incremental_default_sql(arg_dict) %}\\n\\n  {% do return(get_incremental_append_sql(arg_dict)) %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_incremental_append_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.618857, \"supported_languages\": null}, \"macro.dbt.get_insert_into_sql\": {\"name\": \"get_insert_into_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/strategies.sql\", \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\", \"unique_id\": \"macro.dbt.get_insert_into_sql\", \"macro_sql\": \"{% macro get_insert_into_sql(target_relation, temp_relation, dest_columns) %}\\n\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n\\n    insert into {{ target_relation }} ({{ dest_cols_csv }})\\n    (\\n        select {{ dest_cols_csv }}\\n        from {{ temp_relation }}\\n    )\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_quoted_csv\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.619138, \"supported_languages\": null}, \"macro.dbt.materialization_incremental_default\": {\"name\": \"materialization_incremental_default\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/incremental.sql\", \"original_file_path\": \"macros/materializations/models/incremental/incremental.sql\", \"unique_id\": \"macro.dbt.materialization_incremental_default\", \"macro_sql\": \"{% materialization incremental, default -%}\\n\\n  -- relations\\n  {%- set existing_relation = load_cached_relation(this) -%}\\n  {%- set target_relation = this.incorporate(type='table') -%}\\n  {%- set temp_relation = make_temp_relation(target_relation)-%}\\n  {%- set intermediate_relation = make_intermediate_relation(target_relation)-%}\\n  {%- set backup_relation_type = 'table' if existing_relation is none else existing_relation.type -%}\\n  {%- set backup_relation = make_backup_relation(target_relation, backup_relation_type) -%}\\n\\n  -- configs\\n  {%- set unique_key = config.get('unique_key') -%}\\n  {%- set full_refresh_mode = (should_full_refresh()  or existing_relation.is_view) -%}\\n  {%- set on_schema_change = incremental_validate_on_schema_change(config.get('on_schema_change'), default='ignore') -%}\\n\\n  -- the temp_ and backup_ relations should not already exist in the database; get_relation\\n  -- will return None in that case. Otherwise, we get a relation that we can drop\\n  -- later, before we try to use this name for the current operation. This has to happen before\\n  -- BEGIN, in a separate transaction\\n  {%- set preexisting_intermediate_relation = load_cached_relation(intermediate_relation)-%}\\n  {%- set preexisting_backup_relation = load_cached_relation(backup_relation) -%}\\n   -- grab current tables grants config for comparision later on\\n  {% set grant_config = config.get('grants') %}\\n  {{ drop_relation_if_exists(preexisting_intermediate_relation) }}\\n  {{ drop_relation_if_exists(preexisting_backup_relation) }}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  {% set to_drop = [] %}\\n\\n  {% if existing_relation is none %}\\n      {% set build_sql = get_create_table_as_sql(False, target_relation, sql) %}\\n  {% elif full_refresh_mode %}\\n      {% set build_sql = get_create_table_as_sql(False, intermediate_relation, sql) %}\\n      {% set need_swap = true %}\\n  {% else %}\\n    {% do run_query(get_create_table_as_sql(True, temp_relation, sql)) %}\\n    {% do adapter.expand_target_column_types(\\n             from_relation=temp_relation,\\n             to_relation=target_relation) %}\\n    {#-- Process schema changes. Returns dict of changes if successful. Use source columns for upserting/merging --#}\\n    {% set dest_columns = process_schema_changes(on_schema_change, temp_relation, existing_relation) %}\\n    {% if not dest_columns %}\\n      {% set dest_columns = adapter.get_columns_in_relation(existing_relation) %}\\n    {% endif %}\\n\\n    {#-- Get the incremental_strategy, the macro to use for the strategy, and build the sql --#}\\n    {% set incremental_strategy = config.get('incremental_strategy') or 'default' %}\\n    {% set incremental_predicates = config.get('predicates', none) or config.get('incremental_predicates', none) %}\\n    {% set strategy_sql_macro_func = adapter.get_incremental_strategy_macro(context, incremental_strategy) %}\\n    {% set strategy_arg_dict = ({'target_relation': target_relation, 'temp_relation': temp_relation, 'unique_key': unique_key, 'dest_columns': dest_columns, 'incremental_predicates': incremental_predicates }) %}\\n    {% set build_sql = strategy_sql_macro_func(strategy_arg_dict) %}\\n\\n  {% endif %}\\n\\n  {% call statement(\\\"main\\\") %}\\n      {{ build_sql }}\\n  {% endcall %}\\n\\n  {% if need_swap %}\\n      {% do adapter.rename_relation(target_relation, backup_relation) %}\\n      {% do adapter.rename_relation(intermediate_relation, target_relation) %}\\n      {% do to_drop.append(backup_relation) %}\\n  {% endif %}\\n\\n  {% set should_revoke = should_revoke(existing_relation, full_refresh_mode) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {% if existing_relation is none or existing_relation.is_view or should_full_refresh() %}\\n    {% do create_indexes(target_relation) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  -- `COMMIT` happens here\\n  {% do adapter.commit() %}\\n\\n  {% for rel in to_drop %}\\n      {% do adapter.drop_relation(rel) %}\\n  {% endfor %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{%- endmaterialization %}\", \"depends_on\": {\"macros\": [\"macro.dbt.load_cached_relation\", \"macro.dbt.make_temp_relation\", \"macro.dbt.make_intermediate_relation\", \"macro.dbt.make_backup_relation\", \"macro.dbt.should_full_refresh\", \"macro.dbt.incremental_validate_on_schema_change\", \"macro.dbt.drop_relation_if_exists\", \"macro.dbt.run_hooks\", \"macro.dbt.get_create_table_as_sql\", \"macro.dbt.run_query\", \"macro.dbt.process_schema_changes\", \"macro.dbt.statement\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\", \"macro.dbt.persist_docs\", \"macro.dbt.create_indexes\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.624626, \"supported_languages\": [\"sql\"]}, \"macro.dbt.incremental_validate_on_schema_change\": {\"name\": \"incremental_validate_on_schema_change\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"original_file_path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"unique_id\": \"macro.dbt.incremental_validate_on_schema_change\", \"macro_sql\": \"{% macro incremental_validate_on_schema_change(on_schema_change, default='ignore') %}\\n\\n   {% if on_schema_change not in ['sync_all_columns', 'append_new_columns', 'fail', 'ignore'] %}\\n\\n     {% set log_message = 'Invalid value for on_schema_change (%s) specified. Setting default value of %s.' % (on_schema_change, default) %}\\n     {% do log(log_message) %}\\n\\n     {{ return(default) }}\\n\\n   {% else %}\\n\\n     {{ return(on_schema_change) }}\\n\\n   {% endif %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.630311, \"supported_languages\": null}, \"macro.dbt.check_for_schema_changes\": {\"name\": \"check_for_schema_changes\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"original_file_path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"unique_id\": \"macro.dbt.check_for_schema_changes\", \"macro_sql\": \"{% macro check_for_schema_changes(source_relation, target_relation) %}\\n\\n  {% set schema_changed = False %}\\n\\n  {%- set source_columns = adapter.get_columns_in_relation(source_relation) -%}\\n  {%- set target_columns = adapter.get_columns_in_relation(target_relation) -%}\\n  {%- set source_not_in_target = diff_columns(source_columns, target_columns) -%}\\n  {%- set target_not_in_source = diff_columns(target_columns, source_columns) -%}\\n\\n  {% set new_target_types = diff_column_data_types(source_columns, target_columns) %}\\n\\n  {% if source_not_in_target != [] %}\\n    {% set schema_changed = True %}\\n  {% elif target_not_in_source != [] or new_target_types != [] %}\\n    {% set schema_changed = True %}\\n  {% elif new_target_types != [] %}\\n    {% set schema_changed = True %}\\n  {% endif %}\\n\\n  {% set changes_dict = {\\n    'schema_changed': schema_changed,\\n    'source_not_in_target': source_not_in_target,\\n    'target_not_in_source': target_not_in_source,\\n    'source_columns': source_columns,\\n    'target_columns': target_columns,\\n    'new_target_types': new_target_types\\n  } %}\\n\\n  {% set msg %}\\n    In {{ target_relation }}:\\n        Schema changed: {{ schema_changed }}\\n        Source columns not in target: {{ source_not_in_target }}\\n        Target columns not in source: {{ target_not_in_source }}\\n        New column types: {{ new_target_types }}\\n  {% endset %}\\n\\n  {% do log(msg) %}\\n\\n  {{ return(changes_dict) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.diff_columns\", \"macro.dbt.diff_column_data_types\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.631569, \"supported_languages\": null}, \"macro.dbt.sync_column_schemas\": {\"name\": \"sync_column_schemas\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"original_file_path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"unique_id\": \"macro.dbt.sync_column_schemas\", \"macro_sql\": \"{% macro sync_column_schemas(on_schema_change, target_relation, schema_changes_dict) %}\\n\\n  {%- set add_to_target_arr = schema_changes_dict['source_not_in_target'] -%}\\n\\n  {%- if on_schema_change == 'append_new_columns'-%}\\n     {%- if add_to_target_arr | length > 0 -%}\\n       {%- do alter_relation_add_remove_columns(target_relation, add_to_target_arr, none) -%}\\n     {%- endif -%}\\n\\n  {% elif on_schema_change == 'sync_all_columns' %}\\n     {%- set remove_from_target_arr = schema_changes_dict['target_not_in_source'] -%}\\n     {%- set new_target_types = schema_changes_dict['new_target_types'] -%}\\n\\n     {% if add_to_target_arr | length > 0 or remove_from_target_arr | length > 0 %}\\n       {%- do alter_relation_add_remove_columns(target_relation, add_to_target_arr, remove_from_target_arr) -%}\\n     {% endif %}\\n\\n     {% if new_target_types != [] %}\\n       {% for ntt in new_target_types %}\\n         {% set column_name = ntt['column_name'] %}\\n         {% set new_type = ntt['new_type'] %}\\n         {% do alter_column_type(target_relation, column_name, new_type) %}\\n       {% endfor %}\\n     {% endif %}\\n\\n  {% endif %}\\n\\n  {% set schema_change_message %}\\n    In {{ target_relation }}:\\n        Schema change approach: {{ on_schema_change }}\\n        Columns added: {{ add_to_target_arr }}\\n        Columns removed: {{ remove_from_target_arr }}\\n        Data types changed: {{ new_target_types }}\\n  {% endset %}\\n\\n  {% do log(schema_change_message) %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.alter_relation_add_remove_columns\", \"macro.dbt.alter_column_type\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6327949, \"supported_languages\": null}, \"macro.dbt.process_schema_changes\": {\"name\": \"process_schema_changes\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"original_file_path\": \"macros/materializations/models/incremental/on_schema_change.sql\", \"unique_id\": \"macro.dbt.process_schema_changes\", \"macro_sql\": \"{% macro process_schema_changes(on_schema_change, source_relation, target_relation) %}\\n\\n    {% if on_schema_change == 'ignore' %}\\n\\n     {{ return({}) }}\\n\\n    {% else %}\\n\\n      {% set schema_changes_dict = check_for_schema_changes(source_relation, target_relation) %}\\n\\n      {% if schema_changes_dict['schema_changed'] %}\\n\\n        {% if on_schema_change == 'fail' %}\\n\\n          {% set fail_msg %}\\n              The source and target schemas on this incremental model are out of sync!\\n              They can be reconciled in several ways:\\n                - set the `on_schema_change` config to either append_new_columns or sync_all_columns, depending on your situation.\\n                - Re-run the incremental model with `full_refresh: True` to update the target schema.\\n                - update the schema manually and re-run the process.\\n\\n              Additional troubleshooting context:\\n                 Source columns not in target: {{ schema_changes_dict['source_not_in_target'] }}\\n                 Target columns not in source: {{ schema_changes_dict['target_not_in_source'] }}\\n                 New column types: {{ schema_changes_dict['new_target_types'] }}\\n          {% endset %}\\n\\n          {% do exceptions.raise_compiler_error(fail_msg) %}\\n\\n        {# -- unless we ignore, run the sync operation per the config #}\\n        {% else %}\\n\\n          {% do sync_column_schemas(on_schema_change, target_relation, schema_changes_dict) %}\\n\\n        {% endif %}\\n\\n      {% endif %}\\n\\n      {{ return(schema_changes_dict['source_columns']) }}\\n\\n    {% endif %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.check_for_schema_changes\", \"macro.dbt.sync_column_schemas\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.633666, \"supported_languages\": null}, \"macro.dbt.get_columns_spec_ddl\": {\"name\": \"get_columns_spec_ddl\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/table/columns_spec_ddl.sql\", \"original_file_path\": \"macros/materializations/models/table/columns_spec_ddl.sql\", \"unique_id\": \"macro.dbt.get_columns_spec_ddl\", \"macro_sql\": \"{%- macro get_columns_spec_ddl() -%}\\n  {{ adapter.dispatch('get_columns_spec_ddl', 'dbt')() }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_columns_spec_ddl\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.634799, \"supported_languages\": null}, \"macro.dbt.default__get_columns_spec_ddl\": {\"name\": \"default__get_columns_spec_ddl\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/table/columns_spec_ddl.sql\", \"original_file_path\": \"macros/materializations/models/table/columns_spec_ddl.sql\", \"unique_id\": \"macro.dbt.default__get_columns_spec_ddl\", \"macro_sql\": \"{% macro default__get_columns_spec_ddl() -%}\\n  {{ return(columns_spec_ddl()) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.columns_spec_ddl\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.634922, \"supported_languages\": null}, \"macro.dbt.columns_spec_ddl\": {\"name\": \"columns_spec_ddl\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/table/columns_spec_ddl.sql\", \"original_file_path\": \"macros/materializations/models/table/columns_spec_ddl.sql\", \"unique_id\": \"macro.dbt.columns_spec_ddl\", \"macro_sql\": \"{% macro columns_spec_ddl() %}\\n  {# loop through user_provided_columns to create DDL with data types and constraints #}\\n    {%- set user_provided_columns = model['columns'] -%}\\n    (\\n    {% for i in user_provided_columns %}\\n      {%- set col = user_provided_columns[i] -%}\\n      {%- set constraints = col['constraints'] -%}\\n      {{ col['name'] }} {{ col['data_type'] }}{% for c in constraints %} {{ adapter.render_raw_column_constraint(c) }}{% endfor %}{{ \\\",\\\" if not loop.last }}\\n    {% endfor -%}\\n    )\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6354618, \"supported_languages\": null}, \"macro.dbt.get_assert_columns_equivalent\": {\"name\": \"get_assert_columns_equivalent\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/table/columns_spec_ddl.sql\", \"original_file_path\": \"macros/materializations/models/table/columns_spec_ddl.sql\", \"unique_id\": \"macro.dbt.get_assert_columns_equivalent\", \"macro_sql\": \"\\n\\n{%- macro get_assert_columns_equivalent(sql) -%}\\n  {{ adapter.dispatch('get_assert_columns_equivalent', 'dbt')(sql) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_assert_columns_equivalent\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6356301, \"supported_languages\": null}, \"macro.dbt.default__get_assert_columns_equivalent\": {\"name\": \"default__get_assert_columns_equivalent\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/table/columns_spec_ddl.sql\", \"original_file_path\": \"macros/materializations/models/table/columns_spec_ddl.sql\", \"unique_id\": \"macro.dbt.default__get_assert_columns_equivalent\", \"macro_sql\": \"{% macro default__get_assert_columns_equivalent(sql) -%}\\n  {{ return(assert_columns_equivalent(sql)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.assert_columns_equivalent\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.635766, \"supported_languages\": null}, \"macro.dbt.assert_columns_equivalent\": {\"name\": \"assert_columns_equivalent\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/table/columns_spec_ddl.sql\", \"original_file_path\": \"macros/materializations/models/table/columns_spec_ddl.sql\", \"unique_id\": \"macro.dbt.assert_columns_equivalent\", \"macro_sql\": \"{% macro assert_columns_equivalent(sql) %}\\n  {#-- Obtain the column schema provided by sql file. #}\\n  {%- set sql_file_provided_columns = get_column_schema_from_query(sql) -%}\\n  {#--Obtain the column schema provided by the schema file by generating an 'empty schema' query from the model's columns. #}\\n  {%- set schema_file_provided_columns = get_column_schema_from_query(get_empty_schema_sql(model['columns'])) -%}\\n\\n  {#-- create dictionaries with name and formatted data type and strings for exception #}\\n  {%- set sql_columns = format_columns(sql_file_provided_columns) -%}\\n  {%- set string_sql_columns = stringify_formatted_columns(sql_columns) -%}\\n  {%- set yaml_columns = format_columns(schema_file_provided_columns)  -%}\\n  {%- set string_yaml_columns = stringify_formatted_columns(yaml_columns) -%}\\n\\n  {%- if sql_columns|length != yaml_columns|length -%}\\n    {%- do exceptions.raise_contract_error(string_yaml_columns, string_sql_columns) -%}\\n  {%- endif -%}\\n\\n  {%- for sql_col in sql_columns -%}\\n    {%- set yaml_col = [] -%}\\n    {%- for this_col in yaml_columns -%}\\n      {%- if this_col['name'] == sql_col['name'] -%}\\n        {%- do yaml_col.append(this_col) -%}\\n        {%- break -%}\\n      {%- endif -%}\\n    {%- endfor -%}\\n    {%- if not yaml_col -%}\\n      {#-- Column with name not found in yaml #}\\n      {%- do exceptions.raise_contract_error(string_yaml_columns, string_sql_columns) -%}\\n    {%- endif -%}\\n    {%- if sql_col['formatted'] != yaml_col[0]['formatted'] -%}\\n      {#-- Column data types don't match #}\\n      {%- do exceptions.raise_contract_error(string_yaml_columns, string_sql_columns) -%}\\n    {%- endif -%}\\n  {%- endfor -%}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_column_schema_from_query\", \"macro.dbt.get_empty_schema_sql\", \"macro.dbt.format_columns\", \"macro.dbt.stringify_formatted_columns\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.636966, \"supported_languages\": null}, \"macro.dbt.format_columns\": {\"name\": \"format_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/table/columns_spec_ddl.sql\", \"original_file_path\": \"macros/materializations/models/table/columns_spec_ddl.sql\", \"unique_id\": \"macro.dbt.format_columns\", \"macro_sql\": \"{% macro format_columns(columns) %}\\n  {% set formatted_columns = [] %}\\n  {% for column in columns %}\\n    {%- set formatted_column = adapter.dispatch('format_column', 'dbt')(column) -%}\\n    {%- do formatted_columns.append({'name': column.name, 'formatted': formatted_column}) -%}\\n  {% endfor %}\\n  {{ return(formatted_columns) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__format_column\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.637417, \"supported_languages\": null}, \"macro.dbt.stringify_formatted_columns\": {\"name\": \"stringify_formatted_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/table/columns_spec_ddl.sql\", \"original_file_path\": \"macros/materializations/models/table/columns_spec_ddl.sql\", \"unique_id\": \"macro.dbt.stringify_formatted_columns\", \"macro_sql\": \"{% macro stringify_formatted_columns(formatted_columns) %}\\n  {% set column_strings = [] %}\\n  {% for column in formatted_columns %}\\n     {% do column_strings.append(column['formatted']) %}\\n  {% endfor %}\\n  {{ return(column_strings|join(', ')) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6377542, \"supported_languages\": null}, \"macro.dbt.default__format_column\": {\"name\": \"default__format_column\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/table/columns_spec_ddl.sql\", \"original_file_path\": \"macros/materializations/models/table/columns_spec_ddl.sql\", \"unique_id\": \"macro.dbt.default__format_column\", \"macro_sql\": \"{% macro default__format_column(column) -%}\\n  {{ return(column.column.lower() ~ \\\" \\\" ~ column.dtype) }}\\n{%- endmacro -%}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6379352, \"supported_languages\": null}, \"macro.dbt.materialization_table_default\": {\"name\": \"materialization_table_default\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/table/table.sql\", \"original_file_path\": \"macros/materializations/models/table/table.sql\", \"unique_id\": \"macro.dbt.materialization_table_default\", \"macro_sql\": \"{% materialization table, default %}\\n\\n  {%- set existing_relation = load_cached_relation(this) -%}\\n  {%- set target_relation = this.incorporate(type='table') %}\\n  {%- set intermediate_relation =  make_intermediate_relation(target_relation) -%}\\n  -- the intermediate_relation should not already exist in the database; get_relation\\n  -- will return None in that case. Otherwise, we get a relation that we can drop\\n  -- later, before we try to use this name for the current operation\\n  {%- set preexisting_intermediate_relation = load_cached_relation(intermediate_relation) -%}\\n  /*\\n      See ../view/view.sql for more information about this relation.\\n  */\\n  {%- set backup_relation_type = 'table' if existing_relation is none else existing_relation.type -%}\\n  {%- set backup_relation = make_backup_relation(target_relation, backup_relation_type) -%}\\n  -- as above, the backup_relation should not already exist\\n  {%- set preexisting_backup_relation = load_cached_relation(backup_relation) -%}\\n  -- grab current tables grants config for comparision later on\\n  {% set grant_config = config.get('grants') %}\\n\\n  -- drop the temp relations if they exist already in the database\\n  {{ drop_relation_if_exists(preexisting_intermediate_relation) }}\\n  {{ drop_relation_if_exists(preexisting_backup_relation) }}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  -- build model\\n  {% call statement('main') -%}\\n    {{ get_create_table_as_sql(False, intermediate_relation, sql) }}\\n  {%- endcall %}\\n\\n  -- cleanup\\n  {% if existing_relation is not none %}\\n      {{ adapter.rename_relation(existing_relation, backup_relation) }}\\n  {% endif %}\\n\\n  {{ adapter.rename_relation(intermediate_relation, target_relation) }}\\n\\n  {% do create_indexes(target_relation) %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  {% set should_revoke = should_revoke(existing_relation, full_refresh_mode=True) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  -- `COMMIT` happens here\\n  {{ adapter.commit() }}\\n\\n  -- finally, drop the existing/backup relation after the commit\\n  {{ drop_relation_if_exists(backup_relation) }}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n{% endmaterialization %}\", \"depends_on\": {\"macros\": [\"macro.dbt.load_cached_relation\", \"macro.dbt.make_intermediate_relation\", \"macro.dbt.make_backup_relation\", \"macro.dbt.drop_relation_if_exists\", \"macro.dbt.run_hooks\", \"macro.dbt.statement\", \"macro.dbt.get_create_table_as_sql\", \"macro.dbt.create_indexes\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\", \"macro.dbt.persist_docs\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.640608, \"supported_languages\": [\"sql\"]}, \"macro.dbt.get_create_table_as_sql\": {\"name\": \"get_create_table_as_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/table/create_table_as.sql\", \"original_file_path\": \"macros/materializations/models/table/create_table_as.sql\", \"unique_id\": \"macro.dbt.get_create_table_as_sql\", \"macro_sql\": \"{% macro get_create_table_as_sql(temporary, relation, sql) -%}\\n  {{ adapter.dispatch('get_create_table_as_sql', 'dbt')(temporary, relation, sql) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_create_table_as_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.641506, \"supported_languages\": null}, \"macro.dbt.default__get_create_table_as_sql\": {\"name\": \"default__get_create_table_as_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/table/create_table_as.sql\", \"original_file_path\": \"macros/materializations/models/table/create_table_as.sql\", \"unique_id\": \"macro.dbt.default__get_create_table_as_sql\", \"macro_sql\": \"{% macro default__get_create_table_as_sql(temporary, relation, sql) -%}\\n  {{ return(create_table_as(temporary, relation, sql)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.create_table_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.641694, \"supported_languages\": null}, \"macro.dbt.create_table_as\": {\"name\": \"create_table_as\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/table/create_table_as.sql\", \"original_file_path\": \"macros/materializations/models/table/create_table_as.sql\", \"unique_id\": \"macro.dbt.create_table_as\", \"macro_sql\": \"{% macro create_table_as(temporary, relation, compiled_code, language='sql') -%}\\n  {# backward compatibility for create_table_as that does not support language #}\\n  {% if language == \\\"sql\\\" %}\\n    {{ adapter.dispatch('create_table_as', 'dbt')(temporary, relation, compiled_code)}}\\n  {% else %}\\n    {{ adapter.dispatch('create_table_as', 'dbt')(temporary, relation, compiled_code, language) }}\\n  {% endif %}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__create_table_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.642134, \"supported_languages\": null}, \"macro.dbt.default__create_table_as\": {\"name\": \"default__create_table_as\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/table/create_table_as.sql\", \"original_file_path\": \"macros/materializations/models/table/create_table_as.sql\", \"unique_id\": \"macro.dbt.default__create_table_as\", \"macro_sql\": \"{% macro default__create_table_as(temporary, relation, sql) -%}\\n  {%- set sql_header = config.get('sql_header', none) -%}\\n\\n  {{ sql_header if sql_header is not none }}\\n\\n  create {% if temporary: -%}temporary{%- endif %} table\\n    {{ relation.include(database=(not temporary), schema=(not temporary)) }}\\n  {% set contract_config = config.get('contract') %}\\n  {% if contract_config.enforced %}\\n    {{ get_assert_columns_equivalent(sql) }}\\n    {{ get_columns_spec_ddl() }}\\n    {%- set sql = get_select_subquery(sql) %}\\n  {% endif %}\\n  as (\\n    {{ sql }}\\n  );\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_assert_columns_equivalent\", \"macro.dbt.get_columns_spec_ddl\", \"macro.dbt.get_select_subquery\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.642807, \"supported_languages\": null}, \"macro.dbt.get_select_subquery\": {\"name\": \"get_select_subquery\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/table/create_table_as.sql\", \"original_file_path\": \"macros/materializations/models/table/create_table_as.sql\", \"unique_id\": \"macro.dbt.get_select_subquery\", \"macro_sql\": \"{% macro get_select_subquery(sql) %}\\n  {{ return(adapter.dispatch('get_select_subquery', 'dbt')(sql)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_select_subquery\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.643002, \"supported_languages\": null}, \"macro.dbt.default__get_select_subquery\": {\"name\": \"default__get_select_subquery\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/table/create_table_as.sql\", \"original_file_path\": \"macros/materializations/models/table/create_table_as.sql\", \"unique_id\": \"macro.dbt.default__get_select_subquery\", \"macro_sql\": \"{% macro default__get_select_subquery(sql) %}\\n    select\\n    {% for column in model['columns'] %}\\n      {{ column }}{{ \\\", \\\" if not loop.last }}\\n    {% endfor %}\\n    from (\\n        {{ sql }}\\n    ) as model_subq\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.643258, \"supported_languages\": null}, \"macro.dbt.materialization_view_default\": {\"name\": \"materialization_view_default\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/view/view.sql\", \"original_file_path\": \"macros/materializations/models/view/view.sql\", \"unique_id\": \"macro.dbt.materialization_view_default\", \"macro_sql\": \"{%- materialization view, default -%}\\n\\n  {%- set existing_relation = load_cached_relation(this) -%}\\n  {%- set target_relation = this.incorporate(type='view') -%}\\n  {%- set intermediate_relation =  make_intermediate_relation(target_relation) -%}\\n\\n  -- the intermediate_relation should not already exist in the database; get_relation\\n  -- will return None in that case. Otherwise, we get a relation that we can drop\\n  -- later, before we try to use this name for the current operation\\n  {%- set preexisting_intermediate_relation = load_cached_relation(intermediate_relation) -%}\\n  /*\\n     This relation (probably) doesn't exist yet. If it does exist, it's a leftover from\\n     a previous run, and we're going to try to drop it immediately. At the end of this\\n     materialization, we're going to rename the \\\"existing_relation\\\" to this identifier,\\n     and then we're going to drop it. In order to make sure we run the correct one of:\\n       - drop view ...\\n       - drop table ...\\n\\n     We need to set the type of this relation to be the type of the existing_relation, if it exists,\\n     or else \\\"view\\\" as a sane default if it does not. Note that if the existing_relation does not\\n     exist, then there is nothing to move out of the way and subsequentally drop. In that case,\\n     this relation will be effectively unused.\\n  */\\n  {%- set backup_relation_type = 'view' if existing_relation is none else existing_relation.type -%}\\n  {%- set backup_relation = make_backup_relation(target_relation, backup_relation_type) -%}\\n  -- as above, the backup_relation should not already exist\\n  {%- set preexisting_backup_relation = load_cached_relation(backup_relation) -%}\\n  -- grab current tables grants config for comparision later on\\n  {% set grant_config = config.get('grants') %}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- drop the temp relations if they exist already in the database\\n  {{ drop_relation_if_exists(preexisting_intermediate_relation) }}\\n  {{ drop_relation_if_exists(preexisting_backup_relation) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  -- build model\\n  {% call statement('main') -%}\\n    {{ get_create_view_as_sql(intermediate_relation, sql) }}\\n  {%- endcall %}\\n\\n  -- cleanup\\n  -- move the existing view out of the way\\n  {% if existing_relation is not none %}\\n    {{ adapter.rename_relation(existing_relation, backup_relation) }}\\n  {% endif %}\\n  {{ adapter.rename_relation(intermediate_relation, target_relation) }}\\n\\n  {% set should_revoke = should_revoke(existing_relation, full_refresh_mode=True) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  {{ adapter.commit() }}\\n\\n  {{ drop_relation_if_exists(backup_relation) }}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{%- endmaterialization -%}\", \"depends_on\": {\"macros\": [\"macro.dbt.load_cached_relation\", \"macro.dbt.make_intermediate_relation\", \"macro.dbt.make_backup_relation\", \"macro.dbt.run_hooks\", \"macro.dbt.drop_relation_if_exists\", \"macro.dbt.statement\", \"macro.dbt.get_create_view_as_sql\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\", \"macro.dbt.persist_docs\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.645857, \"supported_languages\": [\"sql\"]}, \"macro.dbt.handle_existing_table\": {\"name\": \"handle_existing_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/view/helpers.sql\", \"original_file_path\": \"macros/materializations/models/view/helpers.sql\", \"unique_id\": \"macro.dbt.handle_existing_table\", \"macro_sql\": \"{% macro handle_existing_table(full_refresh, old_relation) %}\\n    {{ adapter.dispatch('handle_existing_table', 'dbt')(full_refresh, old_relation) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__handle_existing_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.64616, \"supported_languages\": null}, \"macro.dbt.default__handle_existing_table\": {\"name\": \"default__handle_existing_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/view/helpers.sql\", \"original_file_path\": \"macros/materializations/models/view/helpers.sql\", \"unique_id\": \"macro.dbt.default__handle_existing_table\", \"macro_sql\": \"{% macro default__handle_existing_table(full_refresh, old_relation) %}\\n    {{ log(\\\"Dropping relation \\\" ~ old_relation ~ \\\" because it is of type \\\" ~ old_relation.type) }}\\n    {{ adapter.drop_relation(old_relation) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6463842, \"supported_languages\": null}, \"macro.dbt.create_or_replace_view\": {\"name\": \"create_or_replace_view\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/view/create_or_replace_view.sql\", \"original_file_path\": \"macros/materializations/models/view/create_or_replace_view.sql\", \"unique_id\": \"macro.dbt.create_or_replace_view\", \"macro_sql\": \"{% macro create_or_replace_view() %}\\n  {%- set identifier = model['alias'] -%}\\n\\n  {%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%}\\n  {%- set exists_as_view = (old_relation is not none and old_relation.is_view) -%}\\n\\n  {%- set target_relation = api.Relation.create(\\n      identifier=identifier, schema=schema, database=database,\\n      type='view') -%}\\n  {% set grant_config = config.get('grants') %}\\n\\n  {{ run_hooks(pre_hooks) }}\\n\\n  -- If there's a table with the same name and we weren't told to full refresh,\\n  -- that's an error. If we were told to full refresh, drop it. This behavior differs\\n  -- for Snowflake and BigQuery, so multiple dispatch is used.\\n  {%- if old_relation is not none and old_relation.is_table -%}\\n    {{ handle_existing_table(should_full_refresh(), old_relation) }}\\n  {%- endif -%}\\n\\n  -- build model\\n  {% call statement('main') -%}\\n    {{ get_create_view_as_sql(target_relation, sql) }}\\n  {%- endcall %}\\n\\n  {% set should_revoke = should_revoke(exists_as_view, full_refresh_mode=True) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=True) %}\\n\\n  {{ run_hooks(post_hooks) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.run_hooks\", \"macro.dbt.handle_existing_table\", \"macro.dbt.should_full_refresh\", \"macro.dbt.statement\", \"macro.dbt.get_create_view_as_sql\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6479082, \"supported_languages\": null}, \"macro.dbt.get_create_view_as_sql\": {\"name\": \"get_create_view_as_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/view/create_view_as.sql\", \"original_file_path\": \"macros/materializations/models/view/create_view_as.sql\", \"unique_id\": \"macro.dbt.get_create_view_as_sql\", \"macro_sql\": \"{% macro get_create_view_as_sql(relation, sql) -%}\\n  {{ adapter.dispatch('get_create_view_as_sql', 'dbt')(relation, sql) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_create_view_as_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.648345, \"supported_languages\": null}, \"macro.dbt.default__get_create_view_as_sql\": {\"name\": \"default__get_create_view_as_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/view/create_view_as.sql\", \"original_file_path\": \"macros/materializations/models/view/create_view_as.sql\", \"unique_id\": \"macro.dbt.default__get_create_view_as_sql\", \"macro_sql\": \"{% macro default__get_create_view_as_sql(relation, sql) -%}\\n  {{ return(create_view_as(relation, sql)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.create_view_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.648515, \"supported_languages\": null}, \"macro.dbt.create_view_as\": {\"name\": \"create_view_as\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/view/create_view_as.sql\", \"original_file_path\": \"macros/materializations/models/view/create_view_as.sql\", \"unique_id\": \"macro.dbt.create_view_as\", \"macro_sql\": \"{% macro create_view_as(relation, sql) -%}\\n  {{ adapter.dispatch('create_view_as', 'dbt')(relation, sql) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__create_view_as\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6487029, \"supported_languages\": null}, \"macro.dbt.default__create_view_as\": {\"name\": \"default__create_view_as\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/models/view/create_view_as.sql\", \"original_file_path\": \"macros/materializations/models/view/create_view_as.sql\", \"unique_id\": \"macro.dbt.default__create_view_as\", \"macro_sql\": \"{% macro default__create_view_as(relation, sql) -%}\\n  {%- set sql_header = config.get('sql_header', none) -%}\\n\\n  {{ sql_header if sql_header is not none }}\\n  create view {{ relation }}\\n    {% set contract_config = config.get('contract') %}\\n    {% if contract_config.enforced %}\\n      {{ get_assert_columns_equivalent(sql) }}\\n    {%- endif %}\\n  as (\\n    {{ sql }}\\n  );\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_assert_columns_equivalent\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6491442, \"supported_languages\": null}, \"macro.dbt.materialization_seed_default\": {\"name\": \"materialization_seed_default\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/seed.sql\", \"original_file_path\": \"macros/materializations/seeds/seed.sql\", \"unique_id\": \"macro.dbt.materialization_seed_default\", \"macro_sql\": \"{% materialization seed, default %}\\n\\n  {%- set identifier = model['alias'] -%}\\n  {%- set full_refresh_mode = (should_full_refresh()) -%}\\n\\n  {%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%}\\n\\n  {%- set exists_as_table = (old_relation is not none and old_relation.is_table) -%}\\n  {%- set exists_as_view = (old_relation is not none and old_relation.is_view) -%}\\n\\n  {%- set grant_config = config.get('grants') -%}\\n  {%- set agate_table = load_agate_table() -%}\\n  -- grab current tables grants config for comparision later on\\n\\n  {%- do store_result('agate_table', response='OK', agate_table=agate_table) -%}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  -- build model\\n  {% set create_table_sql = \\\"\\\" %}\\n  {% if exists_as_view %}\\n    {{ exceptions.raise_compiler_error(\\\"Cannot seed to '{}', it is a view\\\".format(old_relation)) }}\\n  {% elif exists_as_table %}\\n    {% set create_table_sql = reset_csv_table(model, full_refresh_mode, old_relation, agate_table) %}\\n  {% else %}\\n    {% set create_table_sql = create_csv_table(model, agate_table) %}\\n  {% endif %}\\n\\n  {% set code = 'CREATE' if full_refresh_mode else 'INSERT' %}\\n  {% set rows_affected = (agate_table.rows | length) %}\\n  {% set sql = load_csv_rows(model, agate_table) %}\\n\\n  {% call noop_statement('main', code ~ ' ' ~ rows_affected, code, rows_affected) %}\\n    {{ get_csv_sql(create_table_sql, sql) }};\\n  {% endcall %}\\n\\n  {% set target_relation = this.incorporate(type='table') %}\\n\\n  {% set should_revoke = should_revoke(old_relation, full_refresh_mode) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {% if full_refresh_mode or not exists_as_table %}\\n    {% do create_indexes(target_relation) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  -- `COMMIT` happens here\\n  {{ adapter.commit() }}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{% endmaterialization %}\", \"depends_on\": {\"macros\": [\"macro.dbt.should_full_refresh\", \"macro.dbt.run_hooks\", \"macro.dbt.reset_csv_table\", \"macro.dbt.create_csv_table\", \"macro.dbt.load_csv_rows\", \"macro.dbt.noop_statement\", \"macro.dbt.get_csv_sql\", \"macro.dbt.should_revoke\", \"macro.dbt.apply_grants\", \"macro.dbt.persist_docs\", \"macro.dbt.create_indexes\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.652572, \"supported_languages\": [\"sql\"]}, \"macro.dbt.create_csv_table\": {\"name\": \"create_csv_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.create_csv_table\", \"macro_sql\": \"{% macro create_csv_table(model, agate_table) -%}\\n  {{ adapter.dispatch('create_csv_table', 'dbt')(model, agate_table) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__create_csv_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.657813, \"supported_languages\": null}, \"macro.dbt.default__create_csv_table\": {\"name\": \"default__create_csv_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.default__create_csv_table\", \"macro_sql\": \"{% macro default__create_csv_table(model, agate_table) %}\\n  {%- set column_override = model['config'].get('column_types', {}) -%}\\n  {%- set quote_seed_column = model['config'].get('quote_columns', None) -%}\\n\\n  {% set sql %}\\n    create table {{ this.render() }} (\\n        {%- for col_name in agate_table.column_names -%}\\n            {%- set inferred_type = adapter.convert_type(agate_table, loop.index0) -%}\\n            {%- set type = column_override.get(col_name, inferred_type) -%}\\n            {%- set column_name = (col_name | string) -%}\\n            {{ adapter.quote_seed_column(column_name, quote_seed_column) }} {{ type }} {%- if not loop.last -%}, {%- endif -%}\\n        {%- endfor -%}\\n    )\\n  {% endset %}\\n\\n  {% call statement('_') -%}\\n    {{ sql }}\\n  {%- endcall %}\\n\\n  {{ return(sql) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.65873, \"supported_languages\": null}, \"macro.dbt.reset_csv_table\": {\"name\": \"reset_csv_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.reset_csv_table\", \"macro_sql\": \"{% macro reset_csv_table(model, full_refresh, old_relation, agate_table) -%}\\n  {{ adapter.dispatch('reset_csv_table', 'dbt')(model, full_refresh, old_relation, agate_table) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__reset_csv_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.658967, \"supported_languages\": null}, \"macro.dbt.default__reset_csv_table\": {\"name\": \"default__reset_csv_table\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.default__reset_csv_table\", \"macro_sql\": \"{% macro default__reset_csv_table(model, full_refresh, old_relation, agate_table) %}\\n    {% set sql = \\\"\\\" %}\\n    {% if full_refresh %}\\n        {{ adapter.drop_relation(old_relation) }}\\n        {% set sql = create_csv_table(model, agate_table) %}\\n    {% else %}\\n        {{ adapter.truncate_relation(old_relation) }}\\n        {% set sql = \\\"truncate table \\\" ~ old_relation %}\\n    {% endif %}\\n\\n    {{ return(sql) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.create_csv_table\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.659456, \"supported_languages\": null}, \"macro.dbt.get_csv_sql\": {\"name\": \"get_csv_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.get_csv_sql\", \"macro_sql\": \"{% macro get_csv_sql(create_or_truncate_sql, insert_sql) %}\\n    {{ adapter.dispatch('get_csv_sql', 'dbt')(create_or_truncate_sql, insert_sql) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_csv_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.659651, \"supported_languages\": null}, \"macro.dbt.default__get_csv_sql\": {\"name\": \"default__get_csv_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.default__get_csv_sql\", \"macro_sql\": \"{% macro default__get_csv_sql(create_or_truncate_sql, insert_sql) %}\\n    {{ create_or_truncate_sql }};\\n    -- dbt seed --\\n    {{ insert_sql }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.659791, \"supported_languages\": null}, \"macro.dbt.get_binding_char\": {\"name\": \"get_binding_char\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.get_binding_char\", \"macro_sql\": \"{% macro get_binding_char() -%}\\n  {{ adapter.dispatch('get_binding_char', 'dbt')() }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_binding_char\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.659935, \"supported_languages\": null}, \"macro.dbt.default__get_binding_char\": {\"name\": \"default__get_binding_char\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.default__get_binding_char\", \"macro_sql\": \"{% macro default__get_binding_char() %}\\n  {{ return('%s') }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6600509, \"supported_languages\": null}, \"macro.dbt.get_batch_size\": {\"name\": \"get_batch_size\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.get_batch_size\", \"macro_sql\": \"{% macro get_batch_size() -%}\\n  {{ return(adapter.dispatch('get_batch_size', 'dbt')()) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_batch_size\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6602108, \"supported_languages\": null}, \"macro.dbt.default__get_batch_size\": {\"name\": \"default__get_batch_size\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.default__get_batch_size\", \"macro_sql\": \"{% macro default__get_batch_size() %}\\n  {{ return(10000) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6603289, \"supported_languages\": null}, \"macro.dbt.get_seed_column_quoted_csv\": {\"name\": \"get_seed_column_quoted_csv\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.get_seed_column_quoted_csv\", \"macro_sql\": \"{% macro get_seed_column_quoted_csv(model, column_names) %}\\n  {%- set quote_seed_column = model['config'].get('quote_columns', None) -%}\\n    {% set quoted = [] %}\\n    {% for col in column_names -%}\\n        {%- do quoted.append(adapter.quote_seed_column(col, quote_seed_column)) -%}\\n    {%- endfor %}\\n\\n    {%- set dest_cols_csv = quoted | join(', ') -%}\\n    {{ return(dest_cols_csv) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.660815, \"supported_languages\": null}, \"macro.dbt.load_csv_rows\": {\"name\": \"load_csv_rows\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.load_csv_rows\", \"macro_sql\": \"{% macro load_csv_rows(model, agate_table) -%}\\n  {{ adapter.dispatch('load_csv_rows', 'dbt')(model, agate_table) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__load_csv_rows\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6610072, \"supported_languages\": null}, \"macro.dbt.default__load_csv_rows\": {\"name\": \"default__load_csv_rows\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/materializations/seeds/helpers.sql\", \"original_file_path\": \"macros/materializations/seeds/helpers.sql\", \"unique_id\": \"macro.dbt.default__load_csv_rows\", \"macro_sql\": \"{% macro default__load_csv_rows(model, agate_table) %}\\n\\n  {% set batch_size = get_batch_size() %}\\n\\n  {% set cols_sql = get_seed_column_quoted_csv(model, agate_table.column_names) %}\\n  {% set bindings = [] %}\\n\\n  {% set statements = [] %}\\n\\n  {% for chunk in agate_table.rows | batch(batch_size) %}\\n      {% set bindings = [] %}\\n\\n      {% for row in chunk %}\\n          {% do bindings.extend(row) %}\\n      {% endfor %}\\n\\n      {% set sql %}\\n          insert into {{ this.render() }} ({{ cols_sql }}) values\\n          {% for row in chunk -%}\\n              ({%- for column in agate_table.column_names -%}\\n                  {{ get_binding_char() }}\\n                  {%- if not loop.last%},{%- endif %}\\n              {%- endfor -%})\\n              {%- if not loop.last%},{%- endif %}\\n          {%- endfor %}\\n      {% endset %}\\n\\n      {% do adapter.add_query(sql, bindings=bindings, abridge_sql_log=True) %}\\n\\n      {% if loop.index0 == 0 %}\\n          {% do statements.append(sql) %}\\n      {% endif %}\\n  {% endfor %}\\n\\n  {# Return SQL so we can render it out into the compiled files #}\\n  {{ return(statements[0]) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_batch_size\", \"macro.dbt.get_seed_column_quoted_csv\", \"macro.dbt.get_binding_char\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.66231, \"supported_languages\": null}, \"macro.dbt.generate_alias_name\": {\"name\": \"generate_alias_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/get_custom_name/get_custom_alias.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_alias.sql\", \"unique_id\": \"macro.dbt.generate_alias_name\", \"macro_sql\": \"{% macro generate_alias_name(custom_alias_name=none, node=none) -%}\\n    {% do return(adapter.dispatch('generate_alias_name', 'dbt')(custom_alias_name, node)) %}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__generate_alias_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.662733, \"supported_languages\": null}, \"macro.dbt.default__generate_alias_name\": {\"name\": \"default__generate_alias_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/get_custom_name/get_custom_alias.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_alias.sql\", \"unique_id\": \"macro.dbt.default__generate_alias_name\", \"macro_sql\": \"{% macro default__generate_alias_name(custom_alias_name=none, node=none) -%}\\n\\n    {%- if custom_alias_name -%}\\n\\n        {{ custom_alias_name | trim }}\\n\\n    {%- elif node.version -%}\\n\\n        {{ return(node.name ~ \\\"_v\\\" ~ node.version) }}\\n\\n    {%- else -%}\\n\\n        {{ node.name }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6630669, \"supported_languages\": null}, \"macro.dbt.generate_schema_name\": {\"name\": \"generate_schema_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/get_custom_name/get_custom_schema.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_schema.sql\", \"unique_id\": \"macro.dbt.generate_schema_name\", \"macro_sql\": \"{% macro generate_schema_name(custom_schema_name=none, node=none) -%}\\n    {{ return(adapter.dispatch('generate_schema_name', 'dbt')(custom_schema_name, node)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__generate_schema_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6635892, \"supported_languages\": null}, \"macro.dbt.default__generate_schema_name\": {\"name\": \"default__generate_schema_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/get_custom_name/get_custom_schema.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_schema.sql\", \"unique_id\": \"macro.dbt.default__generate_schema_name\", \"macro_sql\": \"{% macro default__generate_schema_name(custom_schema_name, node) -%}\\n\\n    {%- set default_schema = target.schema -%}\\n    {%- if custom_schema_name is none -%}\\n\\n        {{ default_schema }}\\n\\n    {%- else -%}\\n\\n        {{ default_schema }}_{{ custom_schema_name | trim }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.663862, \"supported_languages\": null}, \"macro.dbt.generate_schema_name_for_env\": {\"name\": \"generate_schema_name_for_env\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/get_custom_name/get_custom_schema.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_schema.sql\", \"unique_id\": \"macro.dbt.generate_schema_name_for_env\", \"macro_sql\": \"{% macro generate_schema_name_for_env(custom_schema_name, node) -%}\\n\\n    {%- set default_schema = target.schema -%}\\n    {%- if target.name == 'prod' and custom_schema_name is not none -%}\\n\\n        {{ custom_schema_name | trim }}\\n\\n    {%- else -%}\\n\\n        {{ default_schema }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.664153, \"supported_languages\": null}, \"macro.dbt.generate_database_name\": {\"name\": \"generate_database_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/get_custom_name/get_custom_database.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_database.sql\", \"unique_id\": \"macro.dbt.generate_database_name\", \"macro_sql\": \"{% macro generate_database_name(custom_database_name=none, node=none) -%}\\n    {% do return(adapter.dispatch('generate_database_name', 'dbt')(custom_database_name, node)) %}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__generate_database_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6645498, \"supported_languages\": null}, \"macro.dbt.default__generate_database_name\": {\"name\": \"default__generate_database_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/get_custom_name/get_custom_database.sql\", \"original_file_path\": \"macros/get_custom_name/get_custom_database.sql\", \"unique_id\": \"macro.dbt.default__generate_database_name\", \"macro_sql\": \"{% macro default__generate_database_name(custom_database_name=none, node=none) -%}\\n    {%- set default_database = target.database -%}\\n    {%- if custom_database_name is none -%}\\n\\n        {{ default_database }}\\n\\n    {%- else -%}\\n\\n        {{ custom_database_name }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.664808, \"supported_languages\": null}, \"macro.dbt.default__test_relationships\": {\"name\": \"default__test_relationships\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/generic_test_sql/relationships.sql\", \"original_file_path\": \"macros/generic_test_sql/relationships.sql\", \"unique_id\": \"macro.dbt.default__test_relationships\", \"macro_sql\": \"{% macro default__test_relationships(model, column_name, to, field) %}\\n\\nwith child as (\\n    select {{ column_name }} as from_field\\n    from {{ model }}\\n    where {{ column_name }} is not null\\n),\\n\\nparent as (\\n    select {{ field }} as to_field\\n    from {{ to }}\\n)\\n\\nselect\\n    from_field\\n\\nfrom child\\nleft join parent\\n    on child.from_field = parent.to_field\\n\\nwhere parent.to_field is null\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6651552, \"supported_languages\": null}, \"macro.dbt.default__test_not_null\": {\"name\": \"default__test_not_null\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/generic_test_sql/not_null.sql\", \"original_file_path\": \"macros/generic_test_sql/not_null.sql\", \"unique_id\": \"macro.dbt.default__test_not_null\", \"macro_sql\": \"{% macro default__test_not_null(model, column_name) %}\\n\\n{% set column_list = '*' if should_store_failures() else column_name %}\\n\\nselect {{ column_list }}\\nfrom {{ model }}\\nwhere {{ column_name }} is null\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.should_store_failures\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.66545, \"supported_languages\": null}, \"macro.dbt.default__test_unique\": {\"name\": \"default__test_unique\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/generic_test_sql/unique.sql\", \"original_file_path\": \"macros/generic_test_sql/unique.sql\", \"unique_id\": \"macro.dbt.default__test_unique\", \"macro_sql\": \"{% macro default__test_unique(model, column_name) %}\\n\\nselect\\n    {{ column_name }} as unique_field,\\n    count(*) as n_records\\n\\nfrom {{ model }}\\nwhere {{ column_name }} is not null\\ngroup by {{ column_name }}\\nhaving count(*) > 1\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.665698, \"supported_languages\": null}, \"macro.dbt.default__test_accepted_values\": {\"name\": \"default__test_accepted_values\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/generic_test_sql/accepted_values.sql\", \"original_file_path\": \"macros/generic_test_sql/accepted_values.sql\", \"unique_id\": \"macro.dbt.default__test_accepted_values\", \"macro_sql\": \"{% macro default__test_accepted_values(model, column_name, values, quote=True) %}\\n\\nwith all_values as (\\n\\n    select\\n        {{ column_name }} as value_field,\\n        count(*) as n_records\\n\\n    from {{ model }}\\n    group by {{ column_name }}\\n\\n)\\n\\nselect *\\nfrom all_values\\nwhere value_field not in (\\n    {% for value in values -%}\\n        {% if quote -%}\\n        '{{ value }}'\\n        {%- else -%}\\n        {{ value }}\\n        {%- endif -%}\\n        {%- if not loop.last -%},{%- endif %}\\n    {%- endfor %}\\n)\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6662662, \"supported_languages\": null}, \"macro.dbt.statement\": {\"name\": \"statement\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/etc/statement.sql\", \"original_file_path\": \"macros/etc/statement.sql\", \"unique_id\": \"macro.dbt.statement\", \"macro_sql\": \"\\n{%- macro statement(name=None, fetch_result=False, auto_begin=True, language='sql') -%}\\n  {%- if execute: -%}\\n    {%- set compiled_code = caller() -%}\\n\\n    {%- if name == 'main' -%}\\n      {{ log('Writing runtime {} for node \\\"{}\\\"'.format(language, model['unique_id'])) }}\\n      {{ write(compiled_code) }}\\n    {%- endif -%}\\n    {%- if language == 'sql'-%}\\n      {%- set res, table = adapter.execute(compiled_code, auto_begin=auto_begin, fetch=fetch_result) -%}\\n    {%- elif language == 'python' -%}\\n      {%- set res = submit_python_job(model, compiled_code) -%}\\n      {#-- TODO: What should table be for python models? --#}\\n      {%- set table = None -%}\\n    {%- else -%}\\n      {% do exceptions.raise_compiler_error(\\\"statement macro didn't get supported language\\\") %}\\n    {%- endif -%}\\n\\n    {%- if name is not none -%}\\n      {{ store_result(name, response=res, agate_table=table) }}\\n    {%- endif -%}\\n\\n  {%- endif -%}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.667764, \"supported_languages\": null}, \"macro.dbt.noop_statement\": {\"name\": \"noop_statement\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/etc/statement.sql\", \"original_file_path\": \"macros/etc/statement.sql\", \"unique_id\": \"macro.dbt.noop_statement\", \"macro_sql\": \"{% macro noop_statement(name=None, message=None, code=None, rows_affected=None, res=None) -%}\\n  {%- set sql = caller() -%}\\n\\n  {%- if name == 'main' -%}\\n    {{ log('Writing runtime SQL for node \\\"{}\\\"'.format(model['unique_id'])) }}\\n    {{ write(sql) }}\\n  {%- endif -%}\\n\\n  {%- if name is not none -%}\\n    {{ store_raw_result(name, message=message, code=code, rows_affected=rows_affected, agate_table=res) }}\\n  {%- endif -%}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6684191, \"supported_languages\": null}, \"macro.dbt.run_query\": {\"name\": \"run_query\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/etc/statement.sql\", \"original_file_path\": \"macros/etc/statement.sql\", \"unique_id\": \"macro.dbt.run_query\", \"macro_sql\": \"{% macro run_query(sql) %}\\n  {% call statement(\\\"run_query_statement\\\", fetch_result=true, auto_begin=false) %}\\n    {{ sql }}\\n  {% endcall %}\\n\\n  {% do return(load_result(\\\"run_query_statement\\\").table) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.668716, \"supported_languages\": null}, \"macro.dbt.convert_datetime\": {\"name\": \"convert_datetime\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"unique_id\": \"macro.dbt.convert_datetime\", \"macro_sql\": \"{% macro convert_datetime(date_str, date_fmt) %}\\n\\n  {% set error_msg -%}\\n      The provided partition date '{{ date_str }}' does not match the expected format '{{ date_fmt }}'\\n  {%- endset %}\\n\\n  {% set res = try_or_compiler_error(error_msg, modules.datetime.datetime.strptime, date_str.strip(), date_fmt) %}\\n  {{ return(res) }}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.670603, \"supported_languages\": null}, \"macro.dbt.dates_in_range\": {\"name\": \"dates_in_range\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"unique_id\": \"macro.dbt.dates_in_range\", \"macro_sql\": \"{% macro dates_in_range(start_date_str, end_date_str=none, in_fmt=\\\"%Y%m%d\\\", out_fmt=\\\"%Y%m%d\\\") %}\\n    {% set end_date_str = start_date_str if end_date_str is none else end_date_str %}\\n\\n    {% set start_date = convert_datetime(start_date_str, in_fmt) %}\\n    {% set end_date = convert_datetime(end_date_str, in_fmt) %}\\n\\n    {% set day_count = (end_date - start_date).days %}\\n    {% if day_count < 0 %}\\n        {% set msg -%}\\n            Partition start date is after the end date ({{ start_date }}, {{ end_date }})\\n        {%- endset %}\\n\\n        {{ exceptions.raise_compiler_error(msg, model) }}\\n    {% endif %}\\n\\n    {% set date_list = [] %}\\n    {% for i in range(0, day_count + 1) %}\\n        {% set the_date = (modules.datetime.timedelta(days=i) + start_date) %}\\n        {% if not out_fmt %}\\n            {% set _ = date_list.append(the_date) %}\\n        {% else %}\\n            {% set _ = date_list.append(the_date.strftime(out_fmt)) %}\\n        {% endif %}\\n    {% endfor %}\\n\\n    {{ return(date_list) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.convert_datetime\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.671814, \"supported_languages\": null}, \"macro.dbt.partition_range\": {\"name\": \"partition_range\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"unique_id\": \"macro.dbt.partition_range\", \"macro_sql\": \"{% macro partition_range(raw_partition_date, date_fmt='%Y%m%d') %}\\n    {% set partition_range = (raw_partition_date | string).split(\\\",\\\") %}\\n\\n    {% if (partition_range | length) == 1 %}\\n      {% set start_date = partition_range[0] %}\\n      {% set end_date = none %}\\n    {% elif (partition_range | length) == 2 %}\\n      {% set start_date = partition_range[0] %}\\n      {% set end_date = partition_range[1] %}\\n    {% else %}\\n      {{ exceptions.raise_compiler_error(\\\"Invalid partition time. Expected format: {Start Date}[,{End Date}]. Got: \\\" ~ raw_partition_date) }}\\n    {% endif %}\\n\\n    {{ return(dates_in_range(start_date, end_date, in_fmt=date_fmt)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.dates_in_range\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6726348, \"supported_languages\": null}, \"macro.dbt.py_current_timestring\": {\"name\": \"py_current_timestring\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/etc/datetime.sql\", \"original_file_path\": \"macros/etc/datetime.sql\", \"unique_id\": \"macro.dbt.py_current_timestring\", \"macro_sql\": \"{% macro py_current_timestring() %}\\n    {% set dt = modules.datetime.datetime.now() %}\\n    {% do return(dt.strftime(\\\"%Y%m%d%H%M%S%f\\\")) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.672904, \"supported_languages\": null}, \"macro.dbt.except\": {\"name\": \"except\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/except.sql\", \"original_file_path\": \"macros/utils/except.sql\", \"unique_id\": \"macro.dbt.except\", \"macro_sql\": \"{% macro except() %}\\n  {{ return(adapter.dispatch('except', 'dbt')()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__except\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6731641, \"supported_languages\": null}, \"macro.dbt.default__except\": {\"name\": \"default__except\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/except.sql\", \"original_file_path\": \"macros/utils/except.sql\", \"unique_id\": \"macro.dbt.default__except\", \"macro_sql\": \"{% macro default__except() %}\\n\\n    except\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.673249, \"supported_languages\": null}, \"macro.dbt.replace\": {\"name\": \"replace\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/replace.sql\", \"original_file_path\": \"macros/utils/replace.sql\", \"unique_id\": \"macro.dbt.replace\", \"macro_sql\": \"{% macro replace(field, old_chars, new_chars) -%}\\n    {{ return(adapter.dispatch('replace', 'dbt') (field, old_chars, new_chars)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__replace\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.673606, \"supported_languages\": null}, \"macro.dbt.default__replace\": {\"name\": \"default__replace\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/replace.sql\", \"original_file_path\": \"macros/utils/replace.sql\", \"unique_id\": \"macro.dbt.default__replace\", \"macro_sql\": \"{% macro default__replace(field, old_chars, new_chars) %}\\n\\n    replace(\\n        {{ field }},\\n        {{ old_chars }},\\n        {{ new_chars }}\\n    )\\n\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.673785, \"supported_languages\": null}, \"macro.dbt.concat\": {\"name\": \"concat\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/concat.sql\", \"original_file_path\": \"macros/utils/concat.sql\", \"unique_id\": \"macro.dbt.concat\", \"macro_sql\": \"{% macro concat(fields) -%}\\n  {{ return(adapter.dispatch('concat', 'dbt')(fields)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__concat\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.674051, \"supported_languages\": null}, \"macro.dbt.default__concat\": {\"name\": \"default__concat\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/concat.sql\", \"original_file_path\": \"macros/utils/concat.sql\", \"unique_id\": \"macro.dbt.default__concat\", \"macro_sql\": \"{% macro default__concat(fields) -%}\\n    {{ fields|join(' || ') }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6741881, \"supported_languages\": null}, \"macro.dbt.length\": {\"name\": \"length\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/length.sql\", \"original_file_path\": \"macros/utils/length.sql\", \"unique_id\": \"macro.dbt.length\", \"macro_sql\": \"{% macro length(expression) -%}\\n    {{ return(adapter.dispatch('length', 'dbt') (expression)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__length\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.674554, \"supported_languages\": null}, \"macro.dbt.default__length\": {\"name\": \"default__length\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/length.sql\", \"original_file_path\": \"macros/utils/length.sql\", \"unique_id\": \"macro.dbt.default__length\", \"macro_sql\": \"{% macro default__length(expression) %}\\n\\n    length(\\n        {{ expression }}\\n    )\\n\\n{%- endmacro -%}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.674687, \"supported_languages\": null}, \"macro.dbt.dateadd\": {\"name\": \"dateadd\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/dateadd.sql\", \"original_file_path\": \"macros/utils/dateadd.sql\", \"unique_id\": \"macro.dbt.dateadd\", \"macro_sql\": \"{% macro dateadd(datepart, interval, from_date_or_timestamp) %}\\n  {{ return(adapter.dispatch('dateadd', 'dbt')(datepart, interval, from_date_or_timestamp)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__dateadd\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.675072, \"supported_languages\": null}, \"macro.dbt.default__dateadd\": {\"name\": \"default__dateadd\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/dateadd.sql\", \"original_file_path\": \"macros/utils/dateadd.sql\", \"unique_id\": \"macro.dbt.default__dateadd\", \"macro_sql\": \"{% macro default__dateadd(datepart, interval, from_date_or_timestamp) %}\\n\\n    dateadd(\\n        {{ datepart }},\\n        {{ interval }},\\n        {{ from_date_or_timestamp }}\\n        )\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6752498, \"supported_languages\": null}, \"macro.dbt.intersect\": {\"name\": \"intersect\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/intersect.sql\", \"original_file_path\": \"macros/utils/intersect.sql\", \"unique_id\": \"macro.dbt.intersect\", \"macro_sql\": \"{% macro intersect() %}\\n  {{ return(adapter.dispatch('intersect', 'dbt')()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__intersect\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.675481, \"supported_languages\": null}, \"macro.dbt.default__intersect\": {\"name\": \"default__intersect\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/intersect.sql\", \"original_file_path\": \"macros/utils/intersect.sql\", \"unique_id\": \"macro.dbt.default__intersect\", \"macro_sql\": \"{% macro default__intersect() %}\\n\\n    intersect\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.675561, \"supported_languages\": null}, \"macro.dbt.escape_single_quotes\": {\"name\": \"escape_single_quotes\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/escape_single_quotes.sql\", \"original_file_path\": \"macros/utils/escape_single_quotes.sql\", \"unique_id\": \"macro.dbt.escape_single_quotes\", \"macro_sql\": \"{% macro escape_single_quotes(expression) %}\\n      {{ return(adapter.dispatch('escape_single_quotes', 'dbt') (expression)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__escape_single_quotes\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6758258, \"supported_languages\": null}, \"macro.dbt.default__escape_single_quotes\": {\"name\": \"default__escape_single_quotes\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/escape_single_quotes.sql\", \"original_file_path\": \"macros/utils/escape_single_quotes.sql\", \"unique_id\": \"macro.dbt.default__escape_single_quotes\", \"macro_sql\": \"{% macro default__escape_single_quotes(expression) -%}\\n{{ expression | replace(\\\"'\\\",\\\"''\\\") }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6759732, \"supported_languages\": null}, \"macro.dbt.right\": {\"name\": \"right\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/right.sql\", \"original_file_path\": \"macros/utils/right.sql\", \"unique_id\": \"macro.dbt.right\", \"macro_sql\": \"{% macro right(string_text, length_expression) -%}\\n    {{ return(adapter.dispatch('right', 'dbt') (string_text, length_expression)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__right\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.676275, \"supported_languages\": null}, \"macro.dbt.default__right\": {\"name\": \"default__right\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/right.sql\", \"original_file_path\": \"macros/utils/right.sql\", \"unique_id\": \"macro.dbt.default__right\", \"macro_sql\": \"{% macro default__right(string_text, length_expression) %}\\n\\n    right(\\n        {{ string_text }},\\n        {{ length_expression }}\\n    )\\n\\n{%- endmacro -%}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6765099, \"supported_languages\": null}, \"macro.dbt.listagg\": {\"name\": \"listagg\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/listagg.sql\", \"original_file_path\": \"macros/utils/listagg.sql\", \"unique_id\": \"macro.dbt.listagg\", \"macro_sql\": \"{% macro listagg(measure, delimiter_text=\\\"','\\\", order_by_clause=none, limit_num=none) -%}\\n    {{ return(adapter.dispatch('listagg', 'dbt') (measure, delimiter_text, order_by_clause, limit_num)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__listagg\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6771588, \"supported_languages\": null}, \"macro.dbt.default__listagg\": {\"name\": \"default__listagg\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/listagg.sql\", \"original_file_path\": \"macros/utils/listagg.sql\", \"unique_id\": \"macro.dbt.default__listagg\", \"macro_sql\": \"{% macro default__listagg(measure, delimiter_text, order_by_clause, limit_num) -%}\\n\\n    {% if limit_num -%}\\n    array_to_string(\\n        array_slice(\\n            array_agg(\\n                {{ measure }}\\n            ){% if order_by_clause -%}\\n            within group ({{ order_by_clause }})\\n            {%- endif %}\\n            ,0\\n            ,{{ limit_num }}\\n        ),\\n        {{ delimiter_text }}\\n        )\\n    {%- else %}\\n    listagg(\\n        {{ measure }},\\n        {{ delimiter_text }}\\n        )\\n        {% if order_by_clause -%}\\n        within group ({{ order_by_clause }})\\n        {%- endif %}\\n    {%- endif %}\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.677581, \"supported_languages\": null}, \"macro.dbt.datediff\": {\"name\": \"datediff\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/datediff.sql\", \"original_file_path\": \"macros/utils/datediff.sql\", \"unique_id\": \"macro.dbt.datediff\", \"macro_sql\": \"{% macro datediff(first_date, second_date, datepart) %}\\n  {{ return(adapter.dispatch('datediff', 'dbt')(first_date, second_date, datepart)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__datediff\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.677927, \"supported_languages\": null}, \"macro.dbt.default__datediff\": {\"name\": \"default__datediff\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/datediff.sql\", \"original_file_path\": \"macros/utils/datediff.sql\", \"unique_id\": \"macro.dbt.default__datediff\", \"macro_sql\": \"{% macro default__datediff(first_date, second_date, datepart) -%}\\n\\n    datediff(\\n        {{ datepart }},\\n        {{ first_date }},\\n        {{ second_date }}\\n        )\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.678091, \"supported_languages\": null}, \"macro.dbt.safe_cast\": {\"name\": \"safe_cast\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/safe_cast.sql\", \"original_file_path\": \"macros/utils/safe_cast.sql\", \"unique_id\": \"macro.dbt.safe_cast\", \"macro_sql\": \"{% macro safe_cast(field, type) %}\\n  {{ return(adapter.dispatch('safe_cast', 'dbt') (field, type)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__safe_cast\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6783779, \"supported_languages\": null}, \"macro.dbt.default__safe_cast\": {\"name\": \"default__safe_cast\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/safe_cast.sql\", \"original_file_path\": \"macros/utils/safe_cast.sql\", \"unique_id\": \"macro.dbt.default__safe_cast\", \"macro_sql\": \"{% macro default__safe_cast(field, type) %}\\n    {# most databases don't support this function yet\\n    so we just need to use cast #}\\n    cast({{field}} as {{type}})\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6785228, \"supported_languages\": null}, \"macro.dbt.hash\": {\"name\": \"hash\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/hash.sql\", \"original_file_path\": \"macros/utils/hash.sql\", \"unique_id\": \"macro.dbt.hash\", \"macro_sql\": \"{% macro hash(field) -%}\\n  {{ return(adapter.dispatch('hash', 'dbt') (field)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__hash\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6787798, \"supported_languages\": null}, \"macro.dbt.default__hash\": {\"name\": \"default__hash\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/hash.sql\", \"original_file_path\": \"macros/utils/hash.sql\", \"unique_id\": \"macro.dbt.default__hash\", \"macro_sql\": \"{% macro default__hash(field) -%}\\n    md5(cast({{ field }} as {{ api.Column.translate_type('string') }}))\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6789498, \"supported_languages\": null}, \"macro.dbt.cast_bool_to_text\": {\"name\": \"cast_bool_to_text\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/cast_bool_to_text.sql\", \"original_file_path\": \"macros/utils/cast_bool_to_text.sql\", \"unique_id\": \"macro.dbt.cast_bool_to_text\", \"macro_sql\": \"{% macro cast_bool_to_text(field) %}\\n  {{ adapter.dispatch('cast_bool_to_text', 'dbt') (field) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__cast_bool_to_text\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.679196, \"supported_languages\": null}, \"macro.dbt.default__cast_bool_to_text\": {\"name\": \"default__cast_bool_to_text\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/cast_bool_to_text.sql\", \"original_file_path\": \"macros/utils/cast_bool_to_text.sql\", \"unique_id\": \"macro.dbt.default__cast_bool_to_text\", \"macro_sql\": \"{% macro default__cast_bool_to_text(field) %}\\n    cast({{ field }} as {{ api.Column.translate_type('string') }})\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6793652, \"supported_languages\": null}, \"macro.dbt.any_value\": {\"name\": \"any_value\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/any_value.sql\", \"original_file_path\": \"macros/utils/any_value.sql\", \"unique_id\": \"macro.dbt.any_value\", \"macro_sql\": \"{% macro any_value(expression) -%}\\n    {{ return(adapter.dispatch('any_value', 'dbt') (expression)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__any_value\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6796181, \"supported_languages\": null}, \"macro.dbt.default__any_value\": {\"name\": \"default__any_value\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/any_value.sql\", \"original_file_path\": \"macros/utils/any_value.sql\", \"unique_id\": \"macro.dbt.default__any_value\", \"macro_sql\": \"{% macro default__any_value(expression) -%}\\n\\n    any_value({{ expression }})\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6797252, \"supported_languages\": null}, \"macro.dbt.position\": {\"name\": \"position\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/position.sql\", \"original_file_path\": \"macros/utils/position.sql\", \"unique_id\": \"macro.dbt.position\", \"macro_sql\": \"{% macro position(substring_text, string_text) -%}\\n    {{ return(adapter.dispatch('position', 'dbt') (substring_text, string_text)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__position\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.680025, \"supported_languages\": null}, \"macro.dbt.default__position\": {\"name\": \"default__position\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/position.sql\", \"original_file_path\": \"macros/utils/position.sql\", \"unique_id\": \"macro.dbt.default__position\", \"macro_sql\": \"{% macro default__position(substring_text, string_text) %}\\n\\n    position(\\n        {{ substring_text }} in {{ string_text }}\\n    )\\n\\n{%- endmacro -%}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6801689, \"supported_languages\": null}, \"macro.dbt.string_literal\": {\"name\": \"string_literal\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/literal.sql\", \"original_file_path\": \"macros/utils/literal.sql\", \"unique_id\": \"macro.dbt.string_literal\", \"macro_sql\": \"{%- macro string_literal(value) -%}\\n  {{ return(adapter.dispatch('string_literal', 'dbt') (value)) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__string_literal\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.680419, \"supported_languages\": null}, \"macro.dbt.default__string_literal\": {\"name\": \"default__string_literal\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/literal.sql\", \"original_file_path\": \"macros/utils/literal.sql\", \"unique_id\": \"macro.dbt.default__string_literal\", \"macro_sql\": \"{% macro default__string_literal(value) -%}\\n    '{{ value }}'\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6805272, \"supported_languages\": null}, \"macro.dbt.type_string\": {\"name\": \"type_string\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.type_string\", \"macro_sql\": \"\\n\\n{%- macro type_string() -%}\\n  {{ return(adapter.dispatch('type_string', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__type_string\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.681462, \"supported_languages\": null}, \"macro.dbt.default__type_string\": {\"name\": \"default__type_string\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.default__type_string\", \"macro_sql\": \"{% macro default__type_string() %}\\n    {{ return(api.Column.translate_type(\\\"string\\\")) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.681621, \"supported_languages\": null}, \"macro.dbt.type_timestamp\": {\"name\": \"type_timestamp\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.type_timestamp\", \"macro_sql\": \"\\n\\n{%- macro type_timestamp() -%}\\n  {{ return(adapter.dispatch('type_timestamp', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__type_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6818528, \"supported_languages\": null}, \"macro.dbt.default__type_timestamp\": {\"name\": \"default__type_timestamp\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.default__type_timestamp\", \"macro_sql\": \"{% macro default__type_timestamp() %}\\n    {{ return(api.Column.translate_type(\\\"timestamp\\\")) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6820118, \"supported_languages\": null}, \"macro.dbt.type_float\": {\"name\": \"type_float\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.type_float\", \"macro_sql\": \"\\n\\n{%- macro type_float() -%}\\n  {{ return(adapter.dispatch('type_float', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__type_float\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6821811, \"supported_languages\": null}, \"macro.dbt.default__type_float\": {\"name\": \"default__type_float\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.default__type_float\", \"macro_sql\": \"{% macro default__type_float() %}\\n    {{ return(api.Column.translate_type(\\\"float\\\")) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.682334, \"supported_languages\": null}, \"macro.dbt.type_numeric\": {\"name\": \"type_numeric\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.type_numeric\", \"macro_sql\": \"\\n\\n{%- macro type_numeric() -%}\\n  {{ return(adapter.dispatch('type_numeric', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__type_numeric\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6826391, \"supported_languages\": null}, \"macro.dbt.default__type_numeric\": {\"name\": \"default__type_numeric\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.default__type_numeric\", \"macro_sql\": \"{% macro default__type_numeric() %}\\n    {{ return(api.Column.numeric_type(\\\"numeric\\\", 28, 6)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.682859, \"supported_languages\": null}, \"macro.dbt.type_bigint\": {\"name\": \"type_bigint\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.type_bigint\", \"macro_sql\": \"\\n\\n{%- macro type_bigint() -%}\\n  {{ return(adapter.dispatch('type_bigint', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__type_bigint\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.683039, \"supported_languages\": null}, \"macro.dbt.default__type_bigint\": {\"name\": \"default__type_bigint\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.default__type_bigint\", \"macro_sql\": \"{% macro default__type_bigint() %}\\n    {{ return(api.Column.translate_type(\\\"bigint\\\")) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.683199, \"supported_languages\": null}, \"macro.dbt.type_int\": {\"name\": \"type_int\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.type_int\", \"macro_sql\": \"\\n\\n{%- macro type_int() -%}\\n  {{ return(adapter.dispatch('type_int', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__type_int\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.683383, \"supported_languages\": null}, \"macro.dbt.default__type_int\": {\"name\": \"default__type_int\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.default__type_int\", \"macro_sql\": \"{%- macro default__type_int() -%}\\n  {{ return(api.Column.translate_type(\\\"integer\\\")) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.683554, \"supported_languages\": null}, \"macro.dbt.type_boolean\": {\"name\": \"type_boolean\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.type_boolean\", \"macro_sql\": \"\\n\\n{%- macro type_boolean() -%}\\n  {{ return(adapter.dispatch('type_boolean', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.default__type_boolean\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.683734, \"supported_languages\": null}, \"macro.dbt.default__type_boolean\": {\"name\": \"default__type_boolean\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/data_types.sql\", \"original_file_path\": \"macros/utils/data_types.sql\", \"unique_id\": \"macro.dbt.default__type_boolean\", \"macro_sql\": \"{%- macro default__type_boolean() -%}\\n  {{ return(api.Column.translate_type(\\\"boolean\\\")) }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.683891, \"supported_languages\": null}, \"macro.dbt.array_concat\": {\"name\": \"array_concat\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/array_concat.sql\", \"original_file_path\": \"macros/utils/array_concat.sql\", \"unique_id\": \"macro.dbt.array_concat\", \"macro_sql\": \"{% macro array_concat(array_1, array_2) -%}\\n  {{ return(adapter.dispatch('array_concat', 'dbt')(array_1, array_2)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__array_concat\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.684203, \"supported_languages\": null}, \"macro.dbt.default__array_concat\": {\"name\": \"default__array_concat\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/array_concat.sql\", \"original_file_path\": \"macros/utils/array_concat.sql\", \"unique_id\": \"macro.dbt.default__array_concat\", \"macro_sql\": \"{% macro default__array_concat(array_1, array_2) -%}\\n    array_cat({{ array_1 }}, {{ array_2 }})\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.684342, \"supported_languages\": null}, \"macro.dbt.bool_or\": {\"name\": \"bool_or\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/bool_or.sql\", \"original_file_path\": \"macros/utils/bool_or.sql\", \"unique_id\": \"macro.dbt.bool_or\", \"macro_sql\": \"{% macro bool_or(expression) -%}\\n    {{ return(adapter.dispatch('bool_or', 'dbt') (expression)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__bool_or\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6845891, \"supported_languages\": null}, \"macro.dbt.default__bool_or\": {\"name\": \"default__bool_or\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/bool_or.sql\", \"original_file_path\": \"macros/utils/bool_or.sql\", \"unique_id\": \"macro.dbt.default__bool_or\", \"macro_sql\": \"{% macro default__bool_or(expression) -%}\\n\\n    bool_or({{ expression }})\\n\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.684702, \"supported_languages\": null}, \"macro.dbt.last_day\": {\"name\": \"last_day\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/last_day.sql\", \"original_file_path\": \"macros/utils/last_day.sql\", \"unique_id\": \"macro.dbt.last_day\", \"macro_sql\": \"{% macro last_day(date, datepart) %}\\n  {{ return(adapter.dispatch('last_day', 'dbt') (date, datepart)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__last_day\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.685059, \"supported_languages\": null}, \"macro.dbt.default_last_day\": {\"name\": \"default_last_day\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/last_day.sql\", \"original_file_path\": \"macros/utils/last_day.sql\", \"unique_id\": \"macro.dbt.default_last_day\", \"macro_sql\": \"\\n\\n{%- macro default_last_day(date, datepart) -%}\\n    cast(\\n        {{dbt.dateadd('day', '-1',\\n        dbt.dateadd(datepart, '1', dbt.date_trunc(datepart, date))\\n        )}}\\n        as date)\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt.dateadd\", \"macro.dbt.date_trunc\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.685353, \"supported_languages\": null}, \"macro.dbt.default__last_day\": {\"name\": \"default__last_day\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/last_day.sql\", \"original_file_path\": \"macros/utils/last_day.sql\", \"unique_id\": \"macro.dbt.default__last_day\", \"macro_sql\": \"{% macro default__last_day(date, datepart) -%}\\n    {{dbt.default_last_day(date, datepart)}}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default_last_day\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.685507, \"supported_languages\": null}, \"macro.dbt.split_part\": {\"name\": \"split_part\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/split_part.sql\", \"original_file_path\": \"macros/utils/split_part.sql\", \"unique_id\": \"macro.dbt.split_part\", \"macro_sql\": \"{% macro split_part(string_text, delimiter_text, part_number) %}\\n  {{ return(adapter.dispatch('split_part', 'dbt') (string_text, delimiter_text, part_number)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__split_part\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6860402, \"supported_languages\": null}, \"macro.dbt.default__split_part\": {\"name\": \"default__split_part\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/split_part.sql\", \"original_file_path\": \"macros/utils/split_part.sql\", \"unique_id\": \"macro.dbt.default__split_part\", \"macro_sql\": \"{% macro default__split_part(string_text, delimiter_text, part_number) %}\\n\\n    split_part(\\n        {{ string_text }},\\n        {{ delimiter_text }},\\n        {{ part_number }}\\n        )\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.686302, \"supported_languages\": null}, \"macro.dbt._split_part_negative\": {\"name\": \"_split_part_negative\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/split_part.sql\", \"original_file_path\": \"macros/utils/split_part.sql\", \"unique_id\": \"macro.dbt._split_part_negative\", \"macro_sql\": \"{% macro _split_part_negative(string_text, delimiter_text, part_number) %}\\n\\n    split_part(\\n        {{ string_text }},\\n        {{ delimiter_text }},\\n          length({{ string_text }})\\n          - length(\\n              replace({{ string_text }},  {{ delimiter_text }}, '')\\n          ) + 2 {{ part_number }}\\n        )\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.686583, \"supported_languages\": null}, \"macro.dbt.date_trunc\": {\"name\": \"date_trunc\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/date_trunc.sql\", \"original_file_path\": \"macros/utils/date_trunc.sql\", \"unique_id\": \"macro.dbt.date_trunc\", \"macro_sql\": \"{% macro date_trunc(datepart, date) -%}\\n  {{ return(adapter.dispatch('date_trunc', 'dbt') (datepart, date)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__date_trunc\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6868732, \"supported_languages\": null}, \"macro.dbt.default__date_trunc\": {\"name\": \"default__date_trunc\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/date_trunc.sql\", \"original_file_path\": \"macros/utils/date_trunc.sql\", \"unique_id\": \"macro.dbt.default__date_trunc\", \"macro_sql\": \"{% macro default__date_trunc(datepart, date) -%}\\n    date_trunc('{{datepart}}', {{date}})\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.687006, \"supported_languages\": null}, \"macro.dbt.array_construct\": {\"name\": \"array_construct\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/array_construct.sql\", \"original_file_path\": \"macros/utils/array_construct.sql\", \"unique_id\": \"macro.dbt.array_construct\", \"macro_sql\": \"{% macro array_construct(inputs=[], data_type=api.Column.translate_type('integer')) -%}\\n  {{ return(adapter.dispatch('array_construct', 'dbt')(inputs, data_type)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__array_construct\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.687397, \"supported_languages\": null}, \"macro.dbt.default__array_construct\": {\"name\": \"default__array_construct\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/array_construct.sql\", \"original_file_path\": \"macros/utils/array_construct.sql\", \"unique_id\": \"macro.dbt.default__array_construct\", \"macro_sql\": \"{% macro default__array_construct(inputs, data_type) -%}\\n    {% if inputs|length > 0 %}\\n    array[ {{ inputs|join(' , ') }} ]\\n    {% else %}\\n    array[]::{{data_type}}[]\\n    {% endif %}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.687667, \"supported_languages\": null}, \"macro.dbt.array_append\": {\"name\": \"array_append\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/array_append.sql\", \"original_file_path\": \"macros/utils/array_append.sql\", \"unique_id\": \"macro.dbt.array_append\", \"macro_sql\": \"{% macro array_append(array, new_element) -%}\\n  {{ return(adapter.dispatch('array_append', 'dbt')(array, new_element)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__array_append\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.687964, \"supported_languages\": null}, \"macro.dbt.default__array_append\": {\"name\": \"default__array_append\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/utils/array_append.sql\", \"original_file_path\": \"macros/utils/array_append.sql\", \"unique_id\": \"macro.dbt.default__array_append\", \"macro_sql\": \"{% macro default__array_append(array, new_element) -%}\\n    array_append({{ array }}, {{ new_element }})\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.688101, \"supported_languages\": null}, \"macro.dbt.create_schema\": {\"name\": \"create_schema\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/schema.sql\", \"original_file_path\": \"macros/adapters/schema.sql\", \"unique_id\": \"macro.dbt.create_schema\", \"macro_sql\": \"{% macro create_schema(relation) -%}\\n  {{ adapter.dispatch('create_schema', 'dbt')(relation) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__create_schema\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.688492, \"supported_languages\": null}, \"macro.dbt.default__create_schema\": {\"name\": \"default__create_schema\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/schema.sql\", \"original_file_path\": \"macros/adapters/schema.sql\", \"unique_id\": \"macro.dbt.default__create_schema\", \"macro_sql\": \"{% macro default__create_schema(relation) -%}\\n  {%- call statement('create_schema') -%}\\n    create schema if not exists {{ relation.without_identifier() }}\\n  {% endcall %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.688687, \"supported_languages\": null}, \"macro.dbt.drop_schema\": {\"name\": \"drop_schema\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/schema.sql\", \"original_file_path\": \"macros/adapters/schema.sql\", \"unique_id\": \"macro.dbt.drop_schema\", \"macro_sql\": \"{% macro drop_schema(relation) -%}\\n  {{ adapter.dispatch('drop_schema', 'dbt')(relation) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__drop_schema\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.688858, \"supported_languages\": null}, \"macro.dbt.default__drop_schema\": {\"name\": \"default__drop_schema\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/schema.sql\", \"original_file_path\": \"macros/adapters/schema.sql\", \"unique_id\": \"macro.dbt.default__drop_schema\", \"macro_sql\": \"{% macro default__drop_schema(relation) -%}\\n  {%- call statement('drop_schema') -%}\\n    drop schema if exists {{ relation.without_identifier() }} cascade\\n  {% endcall %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.689048, \"supported_languages\": null}, \"macro.dbt.current_timestamp\": {\"name\": \"current_timestamp\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"unique_id\": \"macro.dbt.current_timestamp\", \"macro_sql\": \"{%- macro current_timestamp() -%}\\n    {{ adapter.dispatch('current_timestamp', 'dbt')() }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6895611, \"supported_languages\": null}, \"macro.dbt.default__current_timestamp\": {\"name\": \"default__current_timestamp\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"unique_id\": \"macro.dbt.default__current_timestamp\", \"macro_sql\": \"{% macro default__current_timestamp() -%}\\n  {{ exceptions.raise_not_implemented(\\n    'current_timestamp macro not implemented for adapter ' + adapter.type()) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.689718, \"supported_languages\": null}, \"macro.dbt.snapshot_get_time\": {\"name\": \"snapshot_get_time\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"unique_id\": \"macro.dbt.snapshot_get_time\", \"macro_sql\": \"\\n\\n{%- macro snapshot_get_time() -%}\\n    {{ adapter.dispatch('snapshot_get_time', 'dbt')() }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__snapshot_get_time\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.689871, \"supported_languages\": null}, \"macro.dbt.default__snapshot_get_time\": {\"name\": \"default__snapshot_get_time\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"unique_id\": \"macro.dbt.default__snapshot_get_time\", \"macro_sql\": \"{% macro default__snapshot_get_time() %}\\n    {{ current_timestamp() }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6899788, \"supported_languages\": null}, \"macro.dbt.current_timestamp_backcompat\": {\"name\": \"current_timestamp_backcompat\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"unique_id\": \"macro.dbt.current_timestamp_backcompat\", \"macro_sql\": \"{% macro current_timestamp_backcompat() %}\\n    {{ return(adapter.dispatch('current_timestamp_backcompat', 'dbt')()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__current_timestamp_backcompat\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.690153, \"supported_languages\": null}, \"macro.dbt.default__current_timestamp_backcompat\": {\"name\": \"default__current_timestamp_backcompat\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"unique_id\": \"macro.dbt.default__current_timestamp_backcompat\", \"macro_sql\": \"{% macro default__current_timestamp_backcompat() %}\\n    current_timestamp::timestamp\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.690235, \"supported_languages\": null}, \"macro.dbt.current_timestamp_in_utc_backcompat\": {\"name\": \"current_timestamp_in_utc_backcompat\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"unique_id\": \"macro.dbt.current_timestamp_in_utc_backcompat\", \"macro_sql\": \"{% macro current_timestamp_in_utc_backcompat() %}\\n    {{ return(adapter.dispatch('current_timestamp_in_utc_backcompat', 'dbt')()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__current_timestamp_in_utc_backcompat\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6904068, \"supported_languages\": null}, \"macro.dbt.default__current_timestamp_in_utc_backcompat\": {\"name\": \"default__current_timestamp_in_utc_backcompat\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/timestamps.sql\", \"original_file_path\": \"macros/adapters/timestamps.sql\", \"unique_id\": \"macro.dbt.default__current_timestamp_in_utc_backcompat\", \"macro_sql\": \"{% macro default__current_timestamp_in_utc_backcompat() %}\\n    {{ return(adapter.dispatch('current_timestamp_backcompat', 'dbt')()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.current_timestamp_backcompat\", \"macro.dbt_postgres.postgres__current_timestamp_backcompat\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.690679, \"supported_languages\": null}, \"macro.dbt.get_create_index_sql\": {\"name\": \"get_create_index_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"unique_id\": \"macro.dbt.get_create_index_sql\", \"macro_sql\": \"{% macro get_create_index_sql(relation, index_dict) -%}\\n  {{ return(adapter.dispatch('get_create_index_sql', 'dbt')(relation, index_dict)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_create_index_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.691232, \"supported_languages\": null}, \"macro.dbt.default__get_create_index_sql\": {\"name\": \"default__get_create_index_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"unique_id\": \"macro.dbt.default__get_create_index_sql\", \"macro_sql\": \"{% macro default__get_create_index_sql(relation, index_dict) -%}\\n  {% do return(None) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6913862, \"supported_languages\": null}, \"macro.dbt.create_indexes\": {\"name\": \"create_indexes\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"unique_id\": \"macro.dbt.create_indexes\", \"macro_sql\": \"{% macro create_indexes(relation) -%}\\n  {{ adapter.dispatch('create_indexes', 'dbt')(relation) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__create_indexes\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.69156, \"supported_languages\": null}, \"macro.dbt.default__create_indexes\": {\"name\": \"default__create_indexes\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/indexes.sql\", \"original_file_path\": \"macros/adapters/indexes.sql\", \"unique_id\": \"macro.dbt.default__create_indexes\", \"macro_sql\": \"{% macro default__create_indexes(relation) -%}\\n  {%- set _indexes = config.get('indexes', default=[]) -%}\\n\\n  {% for _index_dict in _indexes %}\\n    {% set create_index_sql = get_create_index_sql(relation, _index_dict) %}\\n    {% if create_index_sql %}\\n      {% do run_query(create_index_sql) %}\\n    {% endif %}\\n  {% endfor %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_create_index_sql\", \"macro.dbt.run_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.692, \"supported_languages\": null}, \"macro.dbt.make_intermediate_relation\": {\"name\": \"make_intermediate_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.make_intermediate_relation\", \"macro_sql\": \"{% macro make_intermediate_relation(base_relation, suffix='__dbt_tmp') %}\\n  {{ return(adapter.dispatch('make_intermediate_relation', 'dbt')(base_relation, suffix)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_intermediate_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.695603, \"supported_languages\": null}, \"macro.dbt.default__make_intermediate_relation\": {\"name\": \"default__make_intermediate_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.default__make_intermediate_relation\", \"macro_sql\": \"{% macro default__make_intermediate_relation(base_relation, suffix) %}\\n    {{ return(default__make_temp_relation(base_relation, suffix)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__make_temp_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6958349, \"supported_languages\": null}, \"macro.dbt.make_temp_relation\": {\"name\": \"make_temp_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.make_temp_relation\", \"macro_sql\": \"{% macro make_temp_relation(base_relation, suffix='__dbt_tmp') %}\\n  {{ return(adapter.dispatch('make_temp_relation', 'dbt')(base_relation, suffix)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_temp_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6960871, \"supported_languages\": null}, \"macro.dbt.default__make_temp_relation\": {\"name\": \"default__make_temp_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.default__make_temp_relation\", \"macro_sql\": \"{% macro default__make_temp_relation(base_relation, suffix) %}\\n    {%- set temp_identifier = base_relation.identifier ~ suffix -%}\\n    {%- set temp_relation = base_relation.incorporate(\\n                                path={\\\"identifier\\\": temp_identifier}) -%}\\n\\n    {{ return(temp_relation) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.696411, \"supported_languages\": null}, \"macro.dbt.make_backup_relation\": {\"name\": \"make_backup_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.make_backup_relation\", \"macro_sql\": \"{% macro make_backup_relation(base_relation, backup_relation_type, suffix='__dbt_backup') %}\\n    {{ return(adapter.dispatch('make_backup_relation', 'dbt')(base_relation, backup_relation_type, suffix)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__make_backup_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6966882, \"supported_languages\": null}, \"macro.dbt.default__make_backup_relation\": {\"name\": \"default__make_backup_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.default__make_backup_relation\", \"macro_sql\": \"{% macro default__make_backup_relation(base_relation, backup_relation_type, suffix) %}\\n    {%- set backup_identifier = base_relation.identifier ~ suffix -%}\\n    {%- set backup_relation = base_relation.incorporate(\\n                                  path={\\\"identifier\\\": backup_identifier},\\n                                  type=backup_relation_type\\n    ) -%}\\n    {{ return(backup_relation) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.697024, \"supported_languages\": null}, \"macro.dbt.drop_relation\": {\"name\": \"drop_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.drop_relation\", \"macro_sql\": \"{% macro drop_relation(relation) -%}\\n  {{ return(adapter.dispatch('drop_relation', 'dbt')(relation)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__drop_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6972108, \"supported_languages\": null}, \"macro.dbt.default__drop_relation\": {\"name\": \"default__drop_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.default__drop_relation\", \"macro_sql\": \"{% macro default__drop_relation(relation) -%}\\n  {% call statement('drop_relation', auto_begin=False) -%}\\n    drop {{ relation.type }} if exists {{ relation }} cascade\\n  {%- endcall %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.697429, \"supported_languages\": null}, \"macro.dbt.truncate_relation\": {\"name\": \"truncate_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.truncate_relation\", \"macro_sql\": \"{% macro truncate_relation(relation) -%}\\n  {{ return(adapter.dispatch('truncate_relation', 'dbt')(relation)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__truncate_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6976268, \"supported_languages\": null}, \"macro.dbt.default__truncate_relation\": {\"name\": \"default__truncate_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.default__truncate_relation\", \"macro_sql\": \"{% macro default__truncate_relation(relation) -%}\\n  {% call statement('truncate_relation') -%}\\n    truncate table {{ relation }}\\n  {%- endcall %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.697804, \"supported_languages\": null}, \"macro.dbt.rename_relation\": {\"name\": \"rename_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.rename_relation\", \"macro_sql\": \"{% macro rename_relation(from_relation, to_relation) -%}\\n  {{ return(adapter.dispatch('rename_relation', 'dbt')(from_relation, to_relation)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__rename_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.69802, \"supported_languages\": null}, \"macro.dbt.default__rename_relation\": {\"name\": \"default__rename_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.default__rename_relation\", \"macro_sql\": \"{% macro default__rename_relation(from_relation, to_relation) -%}\\n  {% set target_name = adapter.quote_as_configured(to_relation.identifier, 'identifier') %}\\n  {% call statement('rename_relation') -%}\\n    alter table {{ from_relation }} rename to {{ target_name }}\\n  {%- endcall %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6983092, \"supported_languages\": null}, \"macro.dbt.get_or_create_relation\": {\"name\": \"get_or_create_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.get_or_create_relation\", \"macro_sql\": \"{% macro get_or_create_relation(database, schema, identifier, type) -%}\\n  {{ return(adapter.dispatch('get_or_create_relation', 'dbt')(database, schema, identifier, type)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_or_create_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.698685, \"supported_languages\": null}, \"macro.dbt.default__get_or_create_relation\": {\"name\": \"default__get_or_create_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.default__get_or_create_relation\", \"macro_sql\": \"{% macro default__get_or_create_relation(database, schema, identifier, type) %}\\n  {%- set target_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) %}\\n\\n  {% if target_relation %}\\n    {% do return([true, target_relation]) %}\\n  {% endif %}\\n\\n  {%- set new_relation = api.Relation.create(\\n      database=database,\\n      schema=schema,\\n      identifier=identifier,\\n      type=type\\n  ) -%}\\n  {% do return([false, new_relation]) %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.6992798, \"supported_languages\": null}, \"macro.dbt.load_cached_relation\": {\"name\": \"load_cached_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.load_cached_relation\", \"macro_sql\": \"{% macro load_cached_relation(relation) %}\\n  {% do return(adapter.get_relation(\\n    database=relation.database,\\n    schema=relation.schema,\\n    identifier=relation.identifier\\n  )) -%}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.699531, \"supported_languages\": null}, \"macro.dbt.load_relation\": {\"name\": \"load_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.load_relation\", \"macro_sql\": \"{% macro load_relation(relation) %}\\n    {{ return(load_cached_relation(relation)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.load_cached_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.699724, \"supported_languages\": null}, \"macro.dbt.drop_relation_if_exists\": {\"name\": \"drop_relation_if_exists\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/relation.sql\", \"original_file_path\": \"macros/adapters/relation.sql\", \"unique_id\": \"macro.dbt.drop_relation_if_exists\", \"macro_sql\": \"{% macro drop_relation_if_exists(relation) %}\\n  {% if relation is not none %}\\n    {{ adapter.drop_relation(relation) }}\\n  {% endif %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.699935, \"supported_languages\": null}, \"macro.dbt.collect_freshness\": {\"name\": \"collect_freshness\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/freshness.sql\", \"original_file_path\": \"macros/adapters/freshness.sql\", \"unique_id\": \"macro.dbt.collect_freshness\", \"macro_sql\": \"{% macro collect_freshness(source, loaded_at_field, filter) %}\\n  {{ return(adapter.dispatch('collect_freshness', 'dbt')(source, loaded_at_field, filter))}}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__collect_freshness\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.700392, \"supported_languages\": null}, \"macro.dbt.default__collect_freshness\": {\"name\": \"default__collect_freshness\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/freshness.sql\", \"original_file_path\": \"macros/adapters/freshness.sql\", \"unique_id\": \"macro.dbt.default__collect_freshness\", \"macro_sql\": \"{% macro default__collect_freshness(source, loaded_at_field, filter) %}\\n  {% call statement('collect_freshness', fetch_result=True, auto_begin=False) -%}\\n    select\\n      max({{ loaded_at_field }}) as max_loaded_at,\\n      {{ current_timestamp() }} as snapshotted_at\\n    from {{ source }}\\n    {% if filter %}\\n    where {{ filter }}\\n    {% endif %}\\n  {% endcall %}\\n  {{ return(load_result('collect_freshness')) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\", \"macro.dbt.current_timestamp\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.7008178, \"supported_languages\": null}, \"macro.dbt.copy_grants\": {\"name\": \"copy_grants\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.copy_grants\", \"macro_sql\": \"{% macro copy_grants() %}\\n    {{ return(adapter.dispatch('copy_grants', 'dbt')()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__copy_grants\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.7027688, \"supported_languages\": null}, \"macro.dbt.default__copy_grants\": {\"name\": \"default__copy_grants\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.default__copy_grants\", \"macro_sql\": \"{% macro default__copy_grants() %}\\n    {{ return(True) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.702912, \"supported_languages\": null}, \"macro.dbt.support_multiple_grantees_per_dcl_statement\": {\"name\": \"support_multiple_grantees_per_dcl_statement\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.support_multiple_grantees_per_dcl_statement\", \"macro_sql\": \"{% macro support_multiple_grantees_per_dcl_statement() %}\\n    {{ return(adapter.dispatch('support_multiple_grantees_per_dcl_statement', 'dbt')()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__support_multiple_grantees_per_dcl_statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.7031, \"supported_languages\": null}, \"macro.dbt.default__support_multiple_grantees_per_dcl_statement\": {\"name\": \"default__support_multiple_grantees_per_dcl_statement\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.default__support_multiple_grantees_per_dcl_statement\", \"macro_sql\": \"\\n\\n{%- macro default__support_multiple_grantees_per_dcl_statement() -%}\\n    {{ return(True) }}\\n{%- endmacro -%}\\n\\n\\n\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.703357, \"supported_languages\": null}, \"macro.dbt.should_revoke\": {\"name\": \"should_revoke\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.should_revoke\", \"macro_sql\": \"{% macro should_revoke(existing_relation, full_refresh_mode=True) %}\\n\\n    {% if not existing_relation %}\\n        {#-- The table doesn't already exist, so no grants to copy over --#}\\n        {{ return(False) }}\\n    {% elif full_refresh_mode %}\\n        {#-- The object is being REPLACED -- whether grants are copied over depends on the value of user config --#}\\n        {{ return(copy_grants()) }}\\n    {% else %}\\n        {#-- The table is being merged/upserted/inserted -- grants will be carried over --#}\\n        {{ return(True) }}\\n    {% endif %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.copy_grants\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.7037492, \"supported_languages\": null}, \"macro.dbt.get_show_grant_sql\": {\"name\": \"get_show_grant_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.get_show_grant_sql\", \"macro_sql\": \"{% macro get_show_grant_sql(relation) %}\\n    {{ return(adapter.dispatch(\\\"get_show_grant_sql\\\", \\\"dbt\\\")(relation)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_show_grant_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.7039511, \"supported_languages\": null}, \"macro.dbt.default__get_show_grant_sql\": {\"name\": \"default__get_show_grant_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.default__get_show_grant_sql\", \"macro_sql\": \"{% macro default__get_show_grant_sql(relation) %}\\n    show grants on {{ relation }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.7040598, \"supported_languages\": null}, \"macro.dbt.get_grant_sql\": {\"name\": \"get_grant_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.get_grant_sql\", \"macro_sql\": \"{% macro get_grant_sql(relation, privilege, grantees) %}\\n    {{ return(adapter.dispatch('get_grant_sql', 'dbt')(relation, privilege, grantees)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_grant_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.704402, \"supported_languages\": null}, \"macro.dbt.default__get_grant_sql\": {\"name\": \"default__get_grant_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.default__get_grant_sql\", \"macro_sql\": \"\\n\\n{%- macro default__get_grant_sql(relation, privilege, grantees) -%}\\n    grant {{ privilege }} on {{ relation }} to {{ grantees | join(', ') }}\\n{%- endmacro -%}\\n\\n\\n\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.704654, \"supported_languages\": null}, \"macro.dbt.get_revoke_sql\": {\"name\": \"get_revoke_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.get_revoke_sql\", \"macro_sql\": \"{% macro get_revoke_sql(relation, privilege, grantees) %}\\n    {{ return(adapter.dispatch('get_revoke_sql', 'dbt')(relation, privilege, grantees)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_revoke_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.704913, \"supported_languages\": null}, \"macro.dbt.default__get_revoke_sql\": {\"name\": \"default__get_revoke_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.default__get_revoke_sql\", \"macro_sql\": \"\\n\\n{%- macro default__get_revoke_sql(relation, privilege, grantees) -%}\\n    revoke {{ privilege }} on {{ relation }} from {{ grantees | join(', ') }}\\n{%- endmacro -%}\\n\\n\\n\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.705131, \"supported_languages\": null}, \"macro.dbt.get_dcl_statement_list\": {\"name\": \"get_dcl_statement_list\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.get_dcl_statement_list\", \"macro_sql\": \"{% macro get_dcl_statement_list(relation, grant_config, get_dcl_macro) %}\\n    {{ return(adapter.dispatch('get_dcl_statement_list', 'dbt')(relation, grant_config, get_dcl_macro)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_dcl_statement_list\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.705385, \"supported_languages\": null}, \"macro.dbt.default__get_dcl_statement_list\": {\"name\": \"default__get_dcl_statement_list\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.default__get_dcl_statement_list\", \"macro_sql\": \"\\n\\n{%- macro default__get_dcl_statement_list(relation, grant_config, get_dcl_macro) -%}\\n    {#\\n      -- Unpack grant_config into specific privileges and the set of users who need them granted/revoked.\\n      -- Depending on whether this database supports multiple grantees per statement, pass in the list of\\n      -- all grantees per privilege, or (if not) template one statement per privilege-grantee pair.\\n      -- `get_dcl_macro` will be either `get_grant_sql` or `get_revoke_sql`\\n    #}\\n    {%- set dcl_statements = [] -%}\\n    {%- for privilege, grantees in grant_config.items() %}\\n        {%- if support_multiple_grantees_per_dcl_statement() and grantees -%}\\n          {%- set dcl = get_dcl_macro(relation, privilege, grantees) -%}\\n          {%- do dcl_statements.append(dcl) -%}\\n        {%- else -%}\\n          {%- for grantee in grantees -%}\\n              {% set dcl = get_dcl_macro(relation, privilege, [grantee]) %}\\n              {%- do dcl_statements.append(dcl) -%}\\n          {% endfor -%}\\n        {%- endif -%}\\n    {%- endfor -%}\\n    {{ return(dcl_statements) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.support_multiple_grantees_per_dcl_statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.7062578, \"supported_languages\": null}, \"macro.dbt.call_dcl_statements\": {\"name\": \"call_dcl_statements\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.call_dcl_statements\", \"macro_sql\": \"{% macro call_dcl_statements(dcl_statement_list) %}\\n    {{ return(adapter.dispatch(\\\"call_dcl_statements\\\", \\\"dbt\\\")(dcl_statement_list)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__call_dcl_statements\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.706471, \"supported_languages\": null}, \"macro.dbt.default__call_dcl_statements\": {\"name\": \"default__call_dcl_statements\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.default__call_dcl_statements\", \"macro_sql\": \"{% macro default__call_dcl_statements(dcl_statement_list) %}\\n    {#\\n      -- By default, supply all grant + revoke statements in a single semicolon-separated block,\\n      -- so that they're all processed together.\\n\\n      -- Some databases do not support this. Those adapters will need to override this macro\\n      -- to run each statement individually.\\n    #}\\n    {% call statement('grants') %}\\n        {% for dcl_statement in dcl_statement_list %}\\n            {{ dcl_statement }};\\n        {% endfor %}\\n    {% endcall %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.706742, \"supported_languages\": null}, \"macro.dbt.apply_grants\": {\"name\": \"apply_grants\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.apply_grants\", \"macro_sql\": \"{% macro apply_grants(relation, grant_config, should_revoke) %}\\n    {{ return(adapter.dispatch(\\\"apply_grants\\\", \\\"dbt\\\")(relation, grant_config, should_revoke)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__apply_grants\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.707036, \"supported_languages\": null}, \"macro.dbt.default__apply_grants\": {\"name\": \"default__apply_grants\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/apply_grants.sql\", \"original_file_path\": \"macros/adapters/apply_grants.sql\", \"unique_id\": \"macro.dbt.default__apply_grants\", \"macro_sql\": \"{% macro default__apply_grants(relation, grant_config, should_revoke=True) %}\\n    {#-- If grant_config is {} or None, this is a no-op --#}\\n    {% if grant_config %}\\n        {% if should_revoke %}\\n            {#-- We think previous grants may have carried over --#}\\n            {#-- Show current grants and calculate diffs --#}\\n            {% set current_grants_table = run_query(get_show_grant_sql(relation)) %}\\n            {% set current_grants_dict = adapter.standardize_grants_dict(current_grants_table) %}\\n            {% set needs_granting = diff_of_two_dicts(grant_config, current_grants_dict) %}\\n            {% set needs_revoking = diff_of_two_dicts(current_grants_dict, grant_config) %}\\n            {% if not (needs_granting or needs_revoking) %}\\n                {{ log('On ' ~ relation ~': All grants are in place, no revocation or granting needed.')}}\\n            {% endif %}\\n        {% else %}\\n            {#-- We don't think there's any chance of previous grants having carried over. --#}\\n            {#-- Jump straight to granting what the user has configured. --#}\\n            {% set needs_revoking = {} %}\\n            {% set needs_granting = grant_config %}\\n        {% endif %}\\n        {% if needs_granting or needs_revoking %}\\n            {% set revoke_statement_list = get_dcl_statement_list(relation, needs_revoking, get_revoke_sql) %}\\n            {% set grant_statement_list = get_dcl_statement_list(relation, needs_granting, get_grant_sql) %}\\n            {% set dcl_statement_list = revoke_statement_list + grant_statement_list %}\\n            {% if dcl_statement_list %}\\n                {{ call_dcl_statements(dcl_statement_list) }}\\n            {% endif %}\\n        {% endif %}\\n    {% endif %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.run_query\", \"macro.dbt.get_show_grant_sql\", \"macro.dbt.get_dcl_statement_list\", \"macro.dbt.call_dcl_statements\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.708344, \"supported_languages\": null}, \"macro.dbt.alter_column_comment\": {\"name\": \"alter_column_comment\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"unique_id\": \"macro.dbt.alter_column_comment\", \"macro_sql\": \"{% macro alter_column_comment(relation, column_dict) -%}\\n  {{ return(adapter.dispatch('alter_column_comment', 'dbt')(relation, column_dict)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__alter_column_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.7090821, \"supported_languages\": null}, \"macro.dbt.default__alter_column_comment\": {\"name\": \"default__alter_column_comment\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"unique_id\": \"macro.dbt.default__alter_column_comment\", \"macro_sql\": \"{% macro default__alter_column_comment(relation, column_dict) -%}\\n  {{ exceptions.raise_not_implemented(\\n    'alter_column_comment macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.709265, \"supported_languages\": null}, \"macro.dbt.alter_relation_comment\": {\"name\": \"alter_relation_comment\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"unique_id\": \"macro.dbt.alter_relation_comment\", \"macro_sql\": \"{% macro alter_relation_comment(relation, relation_comment) -%}\\n  {{ return(adapter.dispatch('alter_relation_comment', 'dbt')(relation, relation_comment)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__alter_relation_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.7094889, \"supported_languages\": null}, \"macro.dbt.default__alter_relation_comment\": {\"name\": \"default__alter_relation_comment\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"unique_id\": \"macro.dbt.default__alter_relation_comment\", \"macro_sql\": \"{% macro default__alter_relation_comment(relation, relation_comment) -%}\\n  {{ exceptions.raise_not_implemented(\\n    'alter_relation_comment macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.7096682, \"supported_languages\": null}, \"macro.dbt.persist_docs\": {\"name\": \"persist_docs\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"unique_id\": \"macro.dbt.persist_docs\", \"macro_sql\": \"{% macro persist_docs(relation, model, for_relation=true, for_columns=true) -%}\\n  {{ return(adapter.dispatch('persist_docs', 'dbt')(relation, model, for_relation, for_columns)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__persist_docs\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.709949, \"supported_languages\": null}, \"macro.dbt.default__persist_docs\": {\"name\": \"default__persist_docs\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/persist_docs.sql\", \"original_file_path\": \"macros/adapters/persist_docs.sql\", \"unique_id\": \"macro.dbt.default__persist_docs\", \"macro_sql\": \"{% macro default__persist_docs(relation, model, for_relation, for_columns) -%}\\n  {% if for_relation and config.persist_relation_docs() and model.description %}\\n    {% do run_query(alter_relation_comment(relation, model.description)) %}\\n  {% endif %}\\n\\n  {% if for_columns and config.persist_column_docs() and model.columns %}\\n    {% do run_query(alter_column_comment(relation, model.columns)) %}\\n  {% endif %}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.run_query\", \"macro.dbt.alter_relation_comment\", \"macro.dbt.alter_column_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.7104452, \"supported_languages\": null}, \"macro.dbt.get_catalog\": {\"name\": \"get_catalog\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.get_catalog\", \"macro_sql\": \"{% macro get_catalog(information_schema, schemas) -%}\\n  {{ return(adapter.dispatch('get_catalog', 'dbt')(information_schema, schemas)) }}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_catalog\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.711974, \"supported_languages\": null}, \"macro.dbt.default__get_catalog\": {\"name\": \"default__get_catalog\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.default__get_catalog\", \"macro_sql\": \"{% macro default__get_catalog(information_schema, schemas) -%}\\n\\n  {% set typename = adapter.type() %}\\n  {% set msg -%}\\n    get_catalog not implemented for {{ typename }}\\n  {%- endset %}\\n\\n  {{ exceptions.raise_compiler_error(msg) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.712246, \"supported_languages\": null}, \"macro.dbt.information_schema_name\": {\"name\": \"information_schema_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.information_schema_name\", \"macro_sql\": \"{% macro information_schema_name(database) %}\\n  {{ return(adapter.dispatch('information_schema_name', 'dbt')(database)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__information_schema_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.712435, \"supported_languages\": null}, \"macro.dbt.default__information_schema_name\": {\"name\": \"default__information_schema_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.default__information_schema_name\", \"macro_sql\": \"{% macro default__information_schema_name(database) -%}\\n  {%- if database -%}\\n    {{ database }}.INFORMATION_SCHEMA\\n  {%- else -%}\\n    INFORMATION_SCHEMA\\n  {%- endif -%}\\n{%- endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.7125928, \"supported_languages\": null}, \"macro.dbt.list_schemas\": {\"name\": \"list_schemas\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.list_schemas\", \"macro_sql\": \"{% macro list_schemas(database) -%}\\n  {{ return(adapter.dispatch('list_schemas', 'dbt')(database)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__list_schemas\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.712777, \"supported_languages\": null}, \"macro.dbt.default__list_schemas\": {\"name\": \"default__list_schemas\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.default__list_schemas\", \"macro_sql\": \"{% macro default__list_schemas(database) -%}\\n  {% set sql %}\\n    select distinct schema_name\\n    from {{ information_schema_name(database) }}.SCHEMATA\\n    where catalog_name ilike '{{ database }}'\\n  {% endset %}\\n  {{ return(run_query(sql)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.information_schema_name\", \"macro.dbt.run_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.7130291, \"supported_languages\": null}, \"macro.dbt.check_schema_exists\": {\"name\": \"check_schema_exists\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.check_schema_exists\", \"macro_sql\": \"{% macro check_schema_exists(information_schema, schema) -%}\\n  {{ return(adapter.dispatch('check_schema_exists', 'dbt')(information_schema, schema)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__check_schema_exists\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.7132502, \"supported_languages\": null}, \"macro.dbt.default__check_schema_exists\": {\"name\": \"default__check_schema_exists\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.default__check_schema_exists\", \"macro_sql\": \"{% macro default__check_schema_exists(information_schema, schema) -%}\\n  {% set sql -%}\\n        select count(*)\\n        from {{ information_schema.replace(information_schema_view='SCHEMATA') }}\\n        where catalog_name='{{ information_schema.database }}'\\n          and schema_name='{{ schema }}'\\n  {%- endset %}\\n  {{ return(run_query(sql)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.replace\", \"macro.dbt.run_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.713568, \"supported_languages\": null}, \"macro.dbt.list_relations_without_caching\": {\"name\": \"list_relations_without_caching\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.list_relations_without_caching\", \"macro_sql\": \"{% macro list_relations_without_caching(schema_relation) %}\\n  {{ return(adapter.dispatch('list_relations_without_caching', 'dbt')(schema_relation)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__list_relations_without_caching\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.713761, \"supported_languages\": null}, \"macro.dbt.default__list_relations_without_caching\": {\"name\": \"default__list_relations_without_caching\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/metadata.sql\", \"original_file_path\": \"macros/adapters/metadata.sql\", \"unique_id\": \"macro.dbt.default__list_relations_without_caching\", \"macro_sql\": \"{% macro default__list_relations_without_caching(schema_relation) %}\\n  {{ exceptions.raise_not_implemented(\\n    'list_relations_without_caching macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.713928, \"supported_languages\": null}, \"macro.dbt.get_columns_in_relation\": {\"name\": \"get_columns_in_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.get_columns_in_relation\", \"macro_sql\": \"{% macro get_columns_in_relation(relation) -%}\\n  {{ return(adapter.dispatch('get_columns_in_relation', 'dbt')(relation)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt_postgres.postgres__get_columns_in_relation\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.716088, \"supported_languages\": null}, \"macro.dbt.default__get_columns_in_relation\": {\"name\": \"default__get_columns_in_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.default__get_columns_in_relation\", \"macro_sql\": \"{% macro default__get_columns_in_relation(relation) -%}\\n  {{ exceptions.raise_not_implemented(\\n    'get_columns_in_relation macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.7163389, \"supported_languages\": null}, \"macro.dbt.sql_convert_columns_in_relation\": {\"name\": \"sql_convert_columns_in_relation\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.sql_convert_columns_in_relation\", \"macro_sql\": \"{% macro sql_convert_columns_in_relation(table) -%}\\n  {% set columns = [] %}\\n  {% for row in table %}\\n    {% do columns.append(api.Column(*row)) %}\\n  {% endfor %}\\n  {{ return(columns) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.716653, \"supported_languages\": null}, \"macro.dbt.get_empty_subquery_sql\": {\"name\": \"get_empty_subquery_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.get_empty_subquery_sql\", \"macro_sql\": \"{% macro get_empty_subquery_sql(select_sql) -%}\\n  {{ return(adapter.dispatch('get_empty_subquery_sql', 'dbt')(select_sql)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_empty_subquery_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.71684, \"supported_languages\": null}, \"macro.dbt.default__get_empty_subquery_sql\": {\"name\": \"default__get_empty_subquery_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.default__get_empty_subquery_sql\", \"macro_sql\": \"{% macro default__get_empty_subquery_sql(select_sql) %}\\n    select * from (\\n        {{ select_sql }}\\n    ) as __dbt_sbq\\n    where false\\n    limit 0\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.71695, \"supported_languages\": null}, \"macro.dbt.get_empty_schema_sql\": {\"name\": \"get_empty_schema_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.get_empty_schema_sql\", \"macro_sql\": \"{% macro get_empty_schema_sql(columns) -%}\\n  {{ return(adapter.dispatch('get_empty_schema_sql', 'dbt')(columns)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_empty_schema_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.717133, \"supported_languages\": null}, \"macro.dbt.default__get_empty_schema_sql\": {\"name\": \"default__get_empty_schema_sql\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.default__get_empty_schema_sql\", \"macro_sql\": \"{% macro default__get_empty_schema_sql(columns) %}\\n    {%- set col_err = [] -%}\\n    select\\n    {% for i in columns %}\\n      {%- set col = columns[i] -%}\\n      {%- if col['data_type'] is not defined -%}\\n        {{ col_err.append(col['name']) }}\\n      {%- endif -%}\\n      cast(null as {{ col['data_type'] }}) as {{ col['name'] }}{{ \\\", \\\" if not loop.last }}\\n    {%- endfor -%}\\n    {%- if (col_err | length) > 0 -%}\\n      {{ exceptions.column_type_missing(column_names=col_err) }}\\n    {%- endif -%}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.717796, \"supported_languages\": null}, \"macro.dbt.get_column_schema_from_query\": {\"name\": \"get_column_schema_from_query\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.get_column_schema_from_query\", \"macro_sql\": \"{% macro get_column_schema_from_query(select_sql) -%}\\n    {% set columns = [] %}\\n    {# -- Using an 'empty subquery' here to get the same schema as the given select_sql statement, without necessitating a data scan.#}\\n    {% set sql = get_empty_subquery_sql(select_sql) %}\\n    {% set column_schema = adapter.get_column_schema_from_query(sql) %}\\n    {{ return(column_schema) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.get_empty_subquery_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.718113, \"supported_languages\": null}, \"macro.dbt.get_columns_in_query\": {\"name\": \"get_columns_in_query\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.get_columns_in_query\", \"macro_sql\": \"{% macro get_columns_in_query(select_sql) -%}\\n  {{ return(adapter.dispatch('get_columns_in_query', 'dbt')(select_sql)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__get_columns_in_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.7183008, \"supported_languages\": null}, \"macro.dbt.default__get_columns_in_query\": {\"name\": \"default__get_columns_in_query\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.default__get_columns_in_query\", \"macro_sql\": \"{% macro default__get_columns_in_query(select_sql) %}\\n    {% call statement('get_columns_in_query', fetch_result=True, auto_begin=False) -%}\\n        {{ get_empty_subquery_sql(select_sql) }}\\n    {% endcall %}\\n    {{ return(load_result('get_columns_in_query').table.columns | map(attribute='name') | list) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\", \"macro.dbt.get_empty_subquery_sql\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.7186701, \"supported_languages\": null}, \"macro.dbt.alter_column_type\": {\"name\": \"alter_column_type\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.alter_column_type\", \"macro_sql\": \"{% macro alter_column_type(relation, column_name, new_column_type) -%}\\n  {{ return(adapter.dispatch('alter_column_type', 'dbt')(relation, column_name, new_column_type)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__alter_column_type\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.718902, \"supported_languages\": null}, \"macro.dbt.default__alter_column_type\": {\"name\": \"default__alter_column_type\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.default__alter_column_type\", \"macro_sql\": \"{% macro default__alter_column_type(relation, column_name, new_column_type) -%}\\n  {#\\n    1. Create a new column (w/ temp name and correct type)\\n    2. Copy data over to it\\n    3. Drop the existing column (cascade!)\\n    4. Rename the new column to existing column\\n  #}\\n  {%- set tmp_column = column_name + \\\"__dbt_alter\\\" -%}\\n\\n  {% call statement('alter_column_type') %}\\n    alter table {{ relation }} add column {{ adapter.quote(tmp_column) }} {{ new_column_type }};\\n    update {{ relation }} set {{ adapter.quote(tmp_column) }} = {{ adapter.quote(column_name) }};\\n    alter table {{ relation }} drop column {{ adapter.quote(column_name) }} cascade;\\n    alter table {{ relation }} rename column {{ adapter.quote(tmp_column) }} to {{ adapter.quote(column_name) }}\\n  {% endcall %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.statement\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.719517, \"supported_languages\": null}, \"macro.dbt.alter_relation_add_remove_columns\": {\"name\": \"alter_relation_add_remove_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.alter_relation_add_remove_columns\", \"macro_sql\": \"{% macro alter_relation_add_remove_columns(relation, add_columns = none, remove_columns = none) -%}\\n  {{ return(adapter.dispatch('alter_relation_add_remove_columns', 'dbt')(relation, add_columns, remove_columns)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__alter_relation_add_remove_columns\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.7197812, \"supported_languages\": null}, \"macro.dbt.default__alter_relation_add_remove_columns\": {\"name\": \"default__alter_relation_add_remove_columns\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/adapters/columns.sql\", \"original_file_path\": \"macros/adapters/columns.sql\", \"unique_id\": \"macro.dbt.default__alter_relation_add_remove_columns\", \"macro_sql\": \"{% macro default__alter_relation_add_remove_columns(relation, add_columns, remove_columns) %}\\n\\n  {% if add_columns is none %}\\n    {% set add_columns = [] %}\\n  {% endif %}\\n  {% if remove_columns is none %}\\n    {% set remove_columns = [] %}\\n  {% endif %}\\n\\n  {% set sql -%}\\n\\n     alter {{ relation.type }} {{ relation }}\\n\\n            {% for column in add_columns %}\\n               add column {{ column.name }} {{ column.data_type }}{{ ',' if not loop.last }}\\n            {% endfor %}{{ ',' if add_columns and remove_columns }}\\n\\n            {% for column in remove_columns %}\\n                drop column {{ column.name }}{{ ',' if not loop.last }}\\n            {% endfor %}\\n\\n  {%- endset -%}\\n\\n  {% do run_query(sql) %}\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.run_query\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.720577, \"supported_languages\": null}, \"macro.dbt.resolve_model_name\": {\"name\": \"resolve_model_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/python_model/python.sql\", \"original_file_path\": \"macros/python_model/python.sql\", \"unique_id\": \"macro.dbt.resolve_model_name\", \"macro_sql\": \"{% macro resolve_model_name(input_model_name) %}\\n    {{ return(adapter.dispatch('resolve_model_name', 'dbt')(input_model_name)) }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__resolve_model_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.7219672, \"supported_languages\": null}, \"macro.dbt.default__resolve_model_name\": {\"name\": \"default__resolve_model_name\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/python_model/python.sql\", \"original_file_path\": \"macros/python_model/python.sql\", \"unique_id\": \"macro.dbt.default__resolve_model_name\", \"macro_sql\": \"\\n\\n{%- macro default__resolve_model_name(input_model_name) -%}\\n    {{  input_model_name | string | replace('\\\"', '\\\\\\\"') }}\\n{%- endmacro -%}\\n\\n\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.722124, \"supported_languages\": null}, \"macro.dbt.build_ref_function\": {\"name\": \"build_ref_function\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/python_model/python.sql\", \"original_file_path\": \"macros/python_model/python.sql\", \"unique_id\": \"macro.dbt.build_ref_function\", \"macro_sql\": \"{% macro build_ref_function(model) %}\\n\\n    {%- set ref_dict = {} -%}\\n    {%- for _ref in model.refs -%}\\n        {%- set resolved = ref(*_ref) -%}\\n        {%- do ref_dict.update({_ref | join('.'): resolve_model_name(resolved)}) -%}\\n    {%- endfor -%}\\n\\ndef ref(*args,dbt_load_df_function):\\n    refs = {{ ref_dict | tojson }}\\n    key = '.'.join(args)\\n    return dbt_load_df_function(refs[key])\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.resolve_model_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.722541, \"supported_languages\": null}, \"macro.dbt.build_source_function\": {\"name\": \"build_source_function\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/python_model/python.sql\", \"original_file_path\": \"macros/python_model/python.sql\", \"unique_id\": \"macro.dbt.build_source_function\", \"macro_sql\": \"{% macro build_source_function(model) %}\\n\\n    {%- set source_dict = {} -%}\\n    {%- for _source in model.sources -%}\\n        {%- set resolved = source(*_source) -%}\\n        {%- do source_dict.update({_source | join('.'): resolve_model_name(resolved)}) -%}\\n    {%- endfor -%}\\n\\ndef source(*args, dbt_load_df_function):\\n    sources = {{ source_dict | tojson }}\\n    key = '.'.join(args)\\n    return dbt_load_df_function(sources[key])\\n\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.resolve_model_name\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.722951, \"supported_languages\": null}, \"macro.dbt.build_config_dict\": {\"name\": \"build_config_dict\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/python_model/python.sql\", \"original_file_path\": \"macros/python_model/python.sql\", \"unique_id\": \"macro.dbt.build_config_dict\", \"macro_sql\": \"{% macro build_config_dict(model) %}\\n    {%- set config_dict = {} -%}\\n    {% set config_dbt_used = zip(model.config.config_keys_used, model.config.config_keys_defaults) | list %}\\n    {%- for key, default in config_dbt_used -%}\\n        {# weird type testing with enum, would be much easier to write this logic in Python! #}\\n        {%- if key == \\\"language\\\" -%}\\n          {%- set value = \\\"python\\\" -%}\\n        {%- endif -%}\\n        {%- set value = model.config.get(key, default) -%}\\n        {%- do config_dict.update({key: value}) -%}\\n    {%- endfor -%}\\nconfig_dict = {{ config_dict }}\\n{% endmacro %}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.723784, \"supported_languages\": null}, \"macro.dbt.py_script_postfix\": {\"name\": \"py_script_postfix\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/python_model/python.sql\", \"original_file_path\": \"macros/python_model/python.sql\", \"unique_id\": \"macro.dbt.py_script_postfix\", \"macro_sql\": \"{% macro py_script_postfix(model) %}\\n# This part is user provided model code\\n# you will need to copy the next section to run the code\\n# COMMAND ----------\\n# this part is dbt logic for get ref work, do not modify\\n\\n{{ build_ref_function(model ) }}\\n{{ build_source_function(model ) }}\\n{{ build_config_dict(model) }}\\n\\nclass config:\\n    def __init__(self, *args, **kwargs):\\n        pass\\n\\n    @staticmethod\\n    def get(key, default=None):\\n        return config_dict.get(key, default)\\n\\nclass this:\\n    \\\"\\\"\\\"dbt.this() or dbt.this.identifier\\\"\\\"\\\"\\n    database = \\\"{{ this.database }}\\\"\\n    schema = \\\"{{ this.schema }}\\\"\\n    identifier = \\\"{{ this.identifier }}\\\"\\n    {% set this_relation_name = resolve_model_name(this) %}\\n    def __repr__(self):\\n        return '{{ this_relation_name  }}'\\n\\n\\nclass dbtObj:\\n    def __init__(self, load_df_function) -> None:\\n        self.source = lambda *args: source(*args, dbt_load_df_function=load_df_function)\\n        self.ref = lambda *args: ref(*args, dbt_load_df_function=load_df_function)\\n        self.config = config\\n        self.this = this()\\n        self.is_incremental = {{ is_incremental() }}\\n\\n# COMMAND ----------\\n{{py_script_comment()}}\\n{% endmacro %}\", \"depends_on\": {\"macros\": [\"macro.dbt.build_ref_function\", \"macro.dbt.build_source_function\", \"macro.dbt.build_config_dict\", \"macro.dbt.resolve_model_name\", \"macro.dbt.is_incremental\", \"macro.dbt.py_script_comment\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.724266, \"supported_languages\": null}, \"macro.dbt.py_script_comment\": {\"name\": \"py_script_comment\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"macros/python_model/python.sql\", \"original_file_path\": \"macros/python_model/python.sql\", \"unique_id\": \"macro.dbt.py_script_comment\", \"macro_sql\": \"{%macro py_script_comment()%}\\n{%endmacro%}\", \"depends_on\": {\"macros\": []}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.724343, \"supported_languages\": null}, \"macro.dbt.test_unique\": {\"name\": \"test_unique\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"tests/generic/builtin.sql\", \"original_file_path\": \"tests/generic/builtin.sql\", \"unique_id\": \"macro.dbt.test_unique\", \"macro_sql\": \"{% test unique(model, column_name) %}\\n    {% set macro = adapter.dispatch('test_unique', 'dbt') %}\\n    {{ macro(model, column_name) }}\\n{% endtest %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__test_unique\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.724848, \"supported_languages\": null}, \"macro.dbt.test_not_null\": {\"name\": \"test_not_null\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"tests/generic/builtin.sql\", \"original_file_path\": \"tests/generic/builtin.sql\", \"unique_id\": \"macro.dbt.test_not_null\", \"macro_sql\": \"{% test not_null(model, column_name) %}\\n    {% set macro = adapter.dispatch('test_not_null', 'dbt') %}\\n    {{ macro(model, column_name) }}\\n{% endtest %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__test_not_null\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.7250812, \"supported_languages\": null}, \"macro.dbt.test_accepted_values\": {\"name\": \"test_accepted_values\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"tests/generic/builtin.sql\", \"original_file_path\": \"tests/generic/builtin.sql\", \"unique_id\": \"macro.dbt.test_accepted_values\", \"macro_sql\": \"{% test accepted_values(model, column_name, values, quote=True) %}\\n    {% set macro = adapter.dispatch('test_accepted_values', 'dbt') %}\\n    {{ macro(model, column_name, values, quote) }}\\n{% endtest %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__test_accepted_values\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.725373, \"supported_languages\": null}, \"macro.dbt.test_relationships\": {\"name\": \"test_relationships\", \"resource_type\": \"macro\", \"package_name\": \"dbt\", \"path\": \"tests/generic/builtin.sql\", \"original_file_path\": \"tests/generic/builtin.sql\", \"unique_id\": \"macro.dbt.test_relationships\", \"macro_sql\": \"{% test relationships(model, column_name, to, field) %}\\n    {% set macro = adapter.dispatch('test_relationships', 'dbt') %}\\n    {{ macro(model, column_name, to, field) }}\\n{% endtest %}\", \"depends_on\": {\"macros\": [\"macro.dbt.default__test_relationships\"]}, \"description\": \"\", \"meta\": {}, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"arguments\": [], \"created_at\": 1681095229.725664, \"supported_languages\": null}}, \"docs\": {\"doc.test.somedoc\": {\"name\": \"somedoc\", \"resource_type\": \"doc\", \"package_name\": \"test\", \"path\": \"somedoc.md\", \"original_file_path\": \"models/somedoc.md\", \"unique_id\": \"doc.test.somedoc\", \"block_contents\": \"Testing, testing\"}, \"doc.dbt.__overview__\": {\"name\": \"__overview__\", \"resource_type\": \"doc\", \"package_name\": \"dbt\", \"path\": \"overview.md\", \"original_file_path\": \"docs/overview.md\", \"unique_id\": \"doc.dbt.__overview__\", \"block_contents\": \"### Welcome!\\n\\nWelcome to the auto-generated documentation for your dbt project!\\n\\n### Navigation\\n\\nYou can use the `Project` and `Database` navigation tabs on the left side of the window to explore the models\\nin your project.\\n\\n#### Project Tab\\nThe `Project` tab mirrors the directory structure of your dbt project. In this tab, you can see all of the\\nmodels defined in your dbt project, as well as models imported from dbt packages.\\n\\n#### Database Tab\\nThe `Database` tab also exposes your models, but in a format that looks more like a database explorer. This view\\nshows relations (tables and views) grouped into database schemas. Note that ephemeral models are _not_ shown\\nin this interface, as they do not exist in the database.\\n\\n### Graph Exploration\\nYou can click the blue icon on the bottom-right corner of the page to view the lineage graph of your models.\\n\\nOn model pages, you'll see the immediate parents and children of the model you're exploring. By clicking the `Expand`\\nbutton at the top-right of this lineage pane, you'll be able to see all of the models that are used to build,\\nor are built from, the model you're exploring.\\n\\nOnce expanded, you'll be able to use the `--select` and `--exclude` model selection syntax to filter the\\nmodels in the graph. For more information on model selection, check out the [dbt docs](https://docs.getdbt.com/docs/model-selection-syntax).\\n\\nNote that you can also right-click on models to interactively filter and explore the graph.\\n\\n---\\n\\n### More information\\n\\n- [What is dbt](https://docs.getdbt.com/docs/introduction)?\\n- Read the [dbt viewpoint](https://docs.getdbt.com/docs/viewpoint)\\n- [Installation](https://docs.getdbt.com/docs/installation)\\n- Join the [dbt Community](https://www.getdbt.com/community/) for questions and discussion\"}}, \"exposures\": {\"exposure.test.simple_exposure\": {\"name\": \"simple_exposure\", \"resource_type\": \"exposure\", \"package_name\": \"test\", \"path\": \"schema.yml\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"exposure.test.simple_exposure\", \"fqn\": [\"test\", \"simple_exposure\"], \"type\": \"dashboard\", \"owner\": {\"email\": \"something@example.com\", \"name\": null}, \"description\": \"\", \"label\": null, \"maturity\": null, \"meta\": {}, \"tags\": [], \"config\": {\"enabled\": true}, \"unrendered_config\": {}, \"url\": null, \"depends_on\": {\"macros\": [], \"nodes\": [\"source.test.my_source.my_table\", \"model.test.my_model\"]}, \"refs\": [{\"name\": \"my_model\", \"package\": null, \"version\": null}], \"sources\": [[\"my_source\", \"my_table\"]], \"metrics\": [], \"created_at\": 1681095229.907179}}, \"metrics\": {\"metric.test.my_metric\": {\"name\": \"my_metric\", \"resource_type\": \"metric\", \"package_name\": \"test\", \"path\": \"schema.yml\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"metric.test.my_metric\", \"fqn\": [\"test\", \"my_metric\"], \"description\": \"\", \"label\": \"Count records\", \"calculation_method\": \"count\", \"expression\": \"*\", \"filters\": [], \"time_grains\": [\"day\"], \"dimensions\": [], \"timestamp\": \"updated_at\", \"window\": null, \"model\": \"ref('my_model')\", \"model_unique_id\": null, \"meta\": {}, \"tags\": [], \"config\": {\"enabled\": true, \"group\": null}, \"unrendered_config\": {}, \"sources\": [], \"depends_on\": {\"macros\": [], \"nodes\": [\"model.test.my_model\"]}, \"refs\": [{\"name\": \"my_model\", \"package\": null, \"version\": null}], \"metrics\": [], \"created_at\": 1681095229.936167, \"group\": null}}, \"groups\": {}, \"selectors\": {}, \"disabled\": {\"model.test.disabled_model\": [{\"database\": \"dbt\", \"schema\": \"test16810952296205305560_test_previous_version_state\", \"name\": \"disabled_model\", \"resource_type\": \"model\", \"package_name\": \"test\", \"path\": \"disabled_model.sql\", \"original_file_path\": \"models/disabled_model.sql\", \"unique_id\": \"model.test.disabled_model\", \"fqn\": [\"test\", \"disabled_model\"], \"alias\": \"disabled_model\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"597106d23ce34e3cd2430588e5c1cf474ebdd138fc47e09b925a4ab258a27acc\"}, \"config\": {\"enabled\": false, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"view\", \"incremental_strategy\": null, \"persist_docs\": {}, \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": null, \"on_schema_change\": \"ignore\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"contract\": {\"enforced\": false}, \"post-hook\": [], \"pre-hook\": []}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {\"enabled\": false}, \"created_at\": 1681095229.840684, \"config_call_dict\": {\"enabled\": false}, \"relation_name\": \"\\\"dbt\\\".\\\"test16810952296205305560_test_previous_version_state\\\".\\\"disabled_model\\\"\", \"raw_code\": \"{{ config(enabled=False) }}\\nselect 2 as id\", \"language\": \"sql\", \"refs\": [], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [], \"nodes\": []}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"checksum\": null}, \"access\": \"protected\", \"version\": null, \"is_latest_version\": null}], \"snapshot.test.disabled_snapshot_seed\": [{\"database\": \"dbt\", \"schema\": \"test16810952296205305560_test_previous_version_state\", \"name\": \"disabled_snapshot_seed\", \"resource_type\": \"snapshot\", \"package_name\": \"test\", \"path\": \"disabled_snapshot_seed.sql\", \"original_file_path\": \"snapshots/disabled_snapshot_seed.sql\", \"unique_id\": \"snapshot.test.disabled_snapshot_seed\", \"fqn\": [\"test\", \"disabled_snapshot_seed\", \"disabled_snapshot_seed\"], \"alias\": \"disabled_snapshot_seed\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"fe76c9dd437341c9e82a0f2a8baf3148f961b768eaa0a4410cd27d3c071bd617\"}, \"config\": {\"enabled\": false, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"snapshot\", \"incremental_strategy\": null, \"persist_docs\": {}, \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": \"id\", \"on_schema_change\": \"ignore\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"contract\": {\"enforced\": false}, \"strategy\": \"check\", \"target_schema\": \"test16810952296205305560_test_previous_version_state\", \"target_database\": null, \"updated_at\": null, \"check_cols\": \"all\", \"post-hook\": [], \"pre-hook\": []}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {\"unique_key\": \"id\", \"strategy\": \"check\", \"check_cols\": \"all\", \"target_schema\": \"test16810952296205305560_test_previous_version_state\", \"enabled\": false}, \"created_at\": 1681095229.846447, \"config_call_dict\": {\"unique_key\": \"id\", \"strategy\": \"check\", \"check_cols\": \"all\", \"target_schema\": \"test16810952296205305560_test_previous_version_state\", \"enabled\": false}, \"relation_name\": \"\\\"dbt\\\".\\\"test16810952296205305560_test_previous_version_state\\\".\\\"disabled_snapshot_seed\\\"\", \"raw_code\": \"\\n{{\\n    config(\\n      unique_key='id',\\n      strategy='check',\\n      check_cols='all',\\n      target_schema=schema,\\n      enabled=False,\\n    )\\n}}\\nselect * from {{ ref('my_seed') }}\\n\", \"language\": \"sql\", \"refs\": [{\"name\": \"my_seed\", \"package\": null, \"version\": null}], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [], \"nodes\": []}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"checksum\": null}}], \"analysis.test.disabled_al\": [{\"database\": \"dbt\", \"schema\": \"test16810952296205305560_test_previous_version_state\", \"name\": \"disabled_al\", \"resource_type\": \"analysis\", \"package_name\": \"test\", \"path\": \"analysis/disabled_al.sql\", \"original_file_path\": \"analyses/disabled_al.sql\", \"unique_id\": \"analysis.test.disabled_al\", \"fqn\": [\"test\", \"analysis\", \"disabled_al\"], \"alias\": \"disabled_al\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"32d36ad6cff0786eb562440ba60ef6c9b9a7f4c282dfb7a52eaf19d36370f0e1\"}, \"config\": {\"enabled\": false, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"view\", \"incremental_strategy\": null, \"persist_docs\": {}, \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": null, \"on_schema_change\": \"ignore\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"contract\": {\"enforced\": false}, \"post-hook\": [], \"pre-hook\": []}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {\"enabled\": false}, \"created_at\": 1681095229.863457, \"config_call_dict\": {\"enabled\": false}, \"relation_name\": null, \"raw_code\": \"{{ config(enabled=False) }}\\nselect 9 as id\", \"language\": \"sql\", \"refs\": [], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [], \"nodes\": []}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"checksum\": null}}], \"test.test.disabled_just_my\": [{\"database\": \"dbt\", \"schema\": \"test16810952296205305560_test_previous_version_state_dbt_test__audit\", \"name\": \"disabled_just_my\", \"resource_type\": \"test\", \"package_name\": \"test\", \"path\": \"disabled_just_my.sql\", \"original_file_path\": \"tests/disabled_just_my.sql\", \"unique_id\": \"test.test.disabled_just_my\", \"fqn\": [\"test\", \"disabled_just_my\"], \"alias\": \"disabled_just_my\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"4f2268fd89a3b4ef899264ada6d7aa33603671cbc5d5acead7dc2eadf1add985\"}, \"config\": {\"enabled\": false, \"alias\": null, \"schema\": \"dbt_test__audit\", \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"test\", \"severity\": \"ERROR\", \"store_failures\": null, \"where\": null, \"limit\": null, \"fail_calc\": \"count(*)\", \"warn_if\": \"!= 0\", \"error_if\": \"!= 0\"}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {\"enabled\": false}, \"created_at\": 1681095229.882241, \"config_call_dict\": {\"enabled\": false}, \"relation_name\": null, \"raw_code\": \"{{ config(enabled=False) }}\\n\\nselect * from {{ ref('my_model') }}\\nwhere false\", \"language\": \"sql\", \"refs\": [{\"name\": \"my_model\", \"package\": null, \"version\": null}], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [], \"nodes\": []}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"checksum\": null}}], \"test.test.disabled_check_nothing_my_model_.f2c6a72d37\": [{\"test_metadata\": {\"name\": \"disabled_check_nothing\", \"kwargs\": {\"model\": \"{{ get_where_subquery(ref('my_model')) }}\"}, \"namespace\": null}, \"database\": \"dbt\", \"schema\": \"test16810952296205305560_test_previous_version_state_dbt_test__audit\", \"name\": \"disabled_check_nothing_my_model_\", \"resource_type\": \"test\", \"package_name\": \"test\", \"path\": \"disabled_check_nothing_my_model_.sql\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"test.test.disabled_check_nothing_my_model_.f2c6a72d37\", \"fqn\": [\"test\", \"disabled_check_nothing_my_model_\"], \"alias\": \"disabled_check_nothing_my_model_\", \"checksum\": {\"name\": \"none\", \"checksum\": \"\"}, \"config\": {\"enabled\": false, \"alias\": null, \"schema\": \"dbt_test__audit\", \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"test\", \"severity\": \"ERROR\", \"store_failures\": null, \"where\": null, \"limit\": null, \"fail_calc\": \"count(*)\", \"warn_if\": \"!= 0\", \"error_if\": \"!= 0\"}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": null, \"build_path\": null, \"deferred\": false, \"unrendered_config\": {\"enabled\": false}, \"created_at\": 1681095229.9022238, \"config_call_dict\": {\"enabled\": false}, \"relation_name\": null, \"raw_code\": \"{{ test_disabled_check_nothing(**_dbt_generic_test_kwargs) }}\", \"language\": \"sql\", \"refs\": [{\"name\": \"my_model\", \"package\": null, \"version\": null}], \"sources\": [], \"metrics\": [], \"depends_on\": {\"macros\": [\"macro.test.test_disabled_check_nothing\", \"macro.dbt.get_where_subquery\"], \"nodes\": []}, \"compiled_path\": null, \"contract\": {\"enforced\": false, \"checksum\": null}, \"column_name\": null, \"file_key_name\": \"models.my_model\", \"attached_node\": \"model.test.my_model\"}], \"exposure.test.disabled_exposure\": [{\"name\": \"disabled_exposure\", \"resource_type\": \"exposure\", \"package_name\": \"test\", \"path\": \"schema.yml\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"exposure.test.disabled_exposure\", \"fqn\": [\"test\", \"disabled_exposure\"], \"type\": \"dashboard\", \"owner\": {\"email\": \"something@example.com\", \"name\": null}, \"description\": \"\", \"label\": null, \"maturity\": null, \"meta\": {}, \"tags\": [], \"config\": {\"enabled\": false}, \"unrendered_config\": {\"enabled\": false}, \"url\": null, \"depends_on\": {\"macros\": [], \"nodes\": []}, \"refs\": [{\"name\": \"my_model\", \"package\": null, \"version\": null}], \"sources\": [], \"metrics\": [], \"created_at\": 1681095229.9083421}], \"metric.test.disabled_metric\": [{\"name\": \"disabled_metric\", \"resource_type\": \"metric\", \"package_name\": \"test\", \"path\": \"schema.yml\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"metric.test.disabled_metric\", \"fqn\": [\"test\", \"disabled_metric\"], \"description\": \"\", \"label\": \"Count records\", \"calculation_method\": \"count\", \"expression\": \"*\", \"filters\": [], \"time_grains\": [\"day\"], \"dimensions\": [], \"timestamp\": \"updated_at\", \"window\": null, \"model\": \"ref('my_model')\", \"model_unique_id\": null, \"meta\": {}, \"tags\": [], \"config\": {\"enabled\": false, \"group\": null}, \"unrendered_config\": {\"enabled\": false}, \"sources\": [], \"depends_on\": {\"macros\": [], \"nodes\": []}, \"refs\": [{\"name\": \"my_model\", \"package\": null, \"version\": null}], \"metrics\": [], \"created_at\": 1681095229.937823, \"group\": null}], \"seed.test.disabled_seed\": [{\"database\": \"dbt\", \"schema\": \"test16810952296205305560_test_previous_version_state\", \"name\": \"disabled_seed\", \"resource_type\": \"seed\", \"package_name\": \"test\", \"path\": \"disabled_seed.csv\", \"original_file_path\": \"seeds/disabled_seed.csv\", \"unique_id\": \"seed.test.disabled_seed\", \"fqn\": [\"test\", \"disabled_seed\"], \"alias\": \"disabled_seed\", \"checksum\": {\"name\": \"sha256\", \"checksum\": \"31fddd8ec40c6aba6a3a8e7d83fedea2fd0a56c47b64ea3df1847ec1b018e2d1\"}, \"config\": {\"enabled\": false, \"alias\": null, \"schema\": null, \"database\": null, \"tags\": [], \"meta\": {}, \"group\": null, \"materialized\": \"seed\", \"incremental_strategy\": null, \"persist_docs\": {}, \"quoting\": {}, \"column_types\": {}, \"full_refresh\": null, \"unique_key\": null, \"on_schema_change\": \"ignore\", \"grants\": {}, \"packages\": [], \"docs\": {\"show\": true, \"node_color\": null}, \"contract\": {\"enforced\": false}, \"quote_columns\": null, \"post-hook\": [], \"pre-hook\": []}, \"tags\": [], \"description\": \"\", \"columns\": {}, \"meta\": {}, \"group\": null, \"docs\": {\"show\": true, \"node_color\": null}, \"patch_path\": \"test://models/schema.yml\", \"build_path\": null, \"deferred\": false, \"unrendered_config\": {\"enabled\": false}, \"created_at\": 1681095229.905121, \"config_call_dict\": {}, \"relation_name\": \"\\\"dbt\\\".\\\"test16810952296205305560_test_previous_version_state\\\".\\\"disabled_seed\\\"\", \"raw_code\": \"\", \"root_path\": \"/private/var/folders/k6/gtt07v8j2vn51m_z05xk_fjc0000gp/T/pytest-of-michelleark/pytest-80/project5\", \"depends_on\": {\"macros\": []}}], \"source.test.my_source.disabled_table\": [{\"database\": \"dbt\", \"schema\": \"my_source\", \"name\": \"disabled_table\", \"resource_type\": \"source\", \"package_name\": \"test\", \"path\": \"models/schema.yml\", \"original_file_path\": \"models/schema.yml\", \"unique_id\": \"source.test.my_source.disabled_table\", \"fqn\": [\"test\", \"my_source\", \"disabled_table\"], \"source_name\": \"my_source\", \"source_description\": \"My source\", \"loader\": \"a_loader\", \"identifier\": \"disabled_table\", \"quoting\": {\"database\": null, \"schema\": null, \"identifier\": null, \"column\": null}, \"loaded_at_field\": null, \"freshness\": {\"warn_after\": {\"count\": null, \"period\": null}, \"error_after\": {\"count\": null, \"period\": null}, \"filter\": null}, \"external\": null, \"description\": \"Disabled table\", \"columns\": {}, \"meta\": {}, \"source_meta\": {}, \"tags\": [], \"config\": {\"enabled\": false}, \"patch_path\": null, \"unrendered_config\": {\"enabled\": false}, \"relation_name\": \"\\\"dbt\\\".\\\"my_source\\\".\\\"disabled_table\\\"\", \"created_at\": 1681095229.939002}]}, \"parent_map\": {\"model.test.my_model\": [], \"snapshot.test.snapshot_seed\": [\"seed.test.my_seed\"], \"analysis.test.a\": [], \"test.test.just_my\": [\"model.test.my_model\"], \"seed.test.my_seed\": [], \"test.test.not_null_my_model_id.43e0e9183a\": [\"model.test.my_model\"], \"test.test.check_nothing_my_model_.d5a5e66110\": [\"model.test.my_model\"], \"source.test.my_source.my_table\": [], \"exposure.test.simple_exposure\": [\"model.test.my_model\", \"source.test.my_source.my_table\"], \"metric.test.my_metric\": [\"model.test.my_model\"]}, \"child_map\": {\"model.test.my_model\": [\"exposure.test.simple_exposure\", \"metric.test.my_metric\", \"test.test.check_nothing_my_model_.d5a5e66110\", \"test.test.just_my\", \"test.test.not_null_my_model_id.43e0e9183a\"], \"snapshot.test.snapshot_seed\": [], \"analysis.test.a\": [], \"test.test.just_my\": [], \"seed.test.my_seed\": [\"snapshot.test.snapshot_seed\"], \"test.test.not_null_my_model_id.43e0e9183a\": [], \"test.test.check_nothing_my_model_.d5a5e66110\": [], \"source.test.my_source.my_table\": [\"exposure.test.simple_exposure\"], \"exposure.test.simple_exposure\": [], \"metric.test.my_metric\": []}, \"group_map\": {}}\n"
  },
  {
    "path": "tests/functional/artifacts/expected_manifest.py",
    "content": "import hashlib\nimport os\nfrom unittest.mock import ANY\n\nimport dbt\nfrom dbt.tests.util import AnyStringWith\n\n# This produces an \"expected manifest\", with a number of the fields\n# modified to avoid ephemeral changes.\n#   ANY\n#   AnyStringWith\n#   LineIndifferent\n# It also uses some convenience methods to generate the\n# various config dictionaries.\n\n\ndef get_rendered_model_config(**updates):\n    result = {\n        \"database\": None,\n        \"schema\": None,\n        \"alias\": None,\n        \"enabled\": True,\n        \"group\": None,\n        \"materialized\": \"view\",\n        \"pre-hook\": [],\n        \"post-hook\": [],\n        \"column_types\": {},\n        \"quoting\": {},\n        \"tags\": [],\n        \"persist_docs\": {},\n        \"full_refresh\": None,\n        \"on_schema_change\": \"ignore\",\n        \"on_configuration_change\": \"apply\",\n        \"meta\": {},\n        \"unique_key\": None,\n        \"grants\": {},\n        \"packages\": [],\n        \"incremental_strategy\": None,\n        \"docs\": {\"node_color\": None, \"show\": True},\n        \"contract\": {\"enforced\": False, \"alias_types\": True},\n        \"access\": \"protected\",\n        \"event_time\": None,\n        \"lookback\": 1,\n        \"batch_size\": None,\n        \"begin\": None,\n        \"concurrent_batches\": None,\n        \"freshness\": None,\n    }\n    result.update(updates)\n    return result\n\n\ndef get_unrendered_model_config(**updates):\n    return updates\n\n\ndef get_rendered_seed_config(**updates):\n    result = {\n        \"enabled\": True,\n        \"group\": None,\n        \"materialized\": \"seed\",\n        \"persist_docs\": {},\n        \"pre-hook\": [],\n        \"post-hook\": [],\n        \"column_types\": {},\n        \"delimiter\": \",\",\n        \"quoting\": {},\n        \"tags\": [],\n        \"quote_columns\": True,\n        \"full_refresh\": None,\n        \"on_schema_change\": \"ignore\",\n        \"on_configuration_change\": \"apply\",\n        \"database\": None,\n        \"schema\": None,\n        \"alias\": None,\n        \"meta\": {},\n        \"unique_key\": None,\n        \"grants\": {},\n        \"packages\": [],\n        \"incremental_strategy\": None,\n        \"docs\": {\"node_color\": None, \"show\": True},\n        \"contract\": {\"enforced\": False, \"alias_types\": True},\n        \"event_time\": None,\n        \"lookback\": 1,\n        \"batch_size\": None,\n        \"begin\": None,\n        \"concurrent_batches\": None,\n    }\n    result.update(updates)\n    return result\n\n\ndef get_unrendered_seed_config(**updates):\n    result = {\"quote_columns\": True}\n    result.update(updates)\n    return result\n\n\ndef get_rendered_snapshot_config(**updates):\n    result = {\n        \"database\": None,\n        \"schema\": None,\n        \"alias\": None,\n        \"enabled\": True,\n        \"group\": None,\n        \"materialized\": \"snapshot\",\n        \"pre-hook\": [],\n        \"post-hook\": [],\n        \"column_types\": {},\n        \"quoting\": {},\n        \"snapshot_meta_column_names\": {\n            \"dbt_valid_to\": None,\n            \"dbt_valid_from\": None,\n            \"dbt_updated_at\": None,\n            \"dbt_scd_id\": None,\n            \"dbt_is_deleted\": None,\n        },\n        \"dbt_valid_to_current\": None,\n        \"tags\": [],\n        \"persist_docs\": {},\n        \"full_refresh\": None,\n        \"on_schema_change\": \"ignore\",\n        \"on_configuration_change\": \"apply\",\n        \"strategy\": \"check\",\n        \"check_cols\": \"all\",\n        \"unique_key\": \"id\",\n        \"target_database\": None,\n        \"target_schema\": None,\n        \"updated_at\": None,\n        \"meta\": {},\n        \"grants\": {},\n        \"packages\": [],\n        \"incremental_strategy\": None,\n        \"docs\": {\"node_color\": None, \"show\": True},\n        \"contract\": {\"enforced\": False, \"alias_types\": True},\n        \"event_time\": None,\n        \"lookback\": 1,\n        \"batch_size\": None,\n        \"begin\": None,\n        \"concurrent_batches\": None,\n    }\n    result.update(updates)\n    return result\n\n\ndef get_unrendered_snapshot_config(**updates):\n    result = {\"check_cols\": \"all\", \"strategy\": \"check\", \"target_schema\": None, \"unique_key\": \"id\"}\n    result.update(updates)\n    return result\n\n\ndef get_rendered_tst_config(**updates):\n    result = {\n        \"enabled\": True,\n        \"group\": None,\n        \"materialized\": \"test\",\n        \"tags\": [],\n        \"severity\": \"ERROR\",\n        \"store_failures\": None,\n        \"store_failures_as\": None,\n        \"sql_header\": None,\n        \"warn_if\": \"!= 0\",\n        \"error_if\": \"!= 0\",\n        \"fail_calc\": \"count(*)\",\n        \"where\": None,\n        \"limit\": None,\n        \"database\": None,\n        \"schema\": \"dbt_test__audit\",\n        \"alias\": None,\n        \"meta\": {},\n    }\n    result.update(updates)\n    return result\n\n\ndef get_unrendered_tst_config(**updates):\n    result = {}\n    result.update(updates)\n    return result\n\n\ndef quote(value):\n    quote_char = '\"'\n    return \"{0}{1}{0}\".format(quote_char, value)\n\n\ndef relation_name_format(quote_database: bool, quote_schema: bool, quote_identifier: bool):\n    return \".\".join(\n        (\n            quote(\"{0}\") if quote_database else \"{0}\",\n            quote(\"{1}\") if quote_schema else \"{1}\",\n            quote(\"{2}\") if quote_identifier else \"{2}\",\n        )\n    )\n\n\ndef checksum_file(path):\n    \"\"\"windows has silly git behavior that adds newlines, and python does\n    silly things if we just open(..., 'r').encode('utf-8').\n\n    seed files should not have their contents normalized to mirror the normalize_file_contents usage during file loading\n    \"\"\"\n    with open(path, \"rb\") as fp:\n        # We strip the file contents because we want the checksum to match the stored contents\n        file_contents = fp.read().strip()\n        # Normalize non-seed contents\n        if not path.endswith(\".csv\"):\n            file_contents = \" \".join(file_contents.decode(\"utf-8\").split()).encode(\"utf-8\")\n\n        hashed = hashlib.sha256(file_contents).hexdigest()\n\n    return {\n        \"name\": \"sha256\",\n        \"checksum\": hashed,\n    }\n\n\ndef read_file_replace_returns(path):\n    with open(path, \"r\") as fp:\n        return fp.read().replace(\"\\r\", \"\").replace(\"\\n\", \"\")\n\n\nclass LineIndifferent:\n    def __init__(self, expected):\n        self.expected = expected.replace(\"\\r\", \"\")\n\n    def __eq__(self, other):\n        got = other.replace(\"\\r\", \"\").replace(\"\\n\", \"\")\n        return self.expected == got\n\n    def __repr__(self):\n        return \"LineIndifferent({!r})\".format(self.expected)\n\n    def __str__(self):\n        return self.__repr__()\n\n\ndef expected_seeded_manifest(project, model_database=None, quote_model=False):\n\n    model_sql_path = os.path.join(\"models\", \"model.sql\")\n    second_model_sql_path = os.path.join(\"models\", \"second_model.sql\")\n    model_schema_yml_path = os.path.join(\"models\", \"schema.yml\")\n    seed_schema_yml_path = os.path.join(\"seeds\", \"schema.yml\")\n    seed_path = os.path.join(\"seeds\", \"seed.csv\")\n    snapshot_path = os.path.join(\"snapshots\", \"snapshot_seed.sql\")\n\n    my_schema_name = project.test_schema\n    alternate_schema = project.test_schema + \"_test\"\n    test_audit_schema = my_schema_name + \"_dbt_test__audit\"\n\n    model_database = project.database\n\n    model_config = get_rendered_model_config(docs={\"node_color\": None, \"show\": False})\n    second_config = get_rendered_model_config(\n        schema=\"test\", docs={\"node_color\": None, \"show\": False}\n    )\n\n    unrendered_model_config = get_unrendered_model_config(\n        materialized=\"view\", docs={\"show\": False}\n    )\n\n    unrendered_second_config = get_unrendered_model_config(\n        schema=\"test\", materialized=\"view\", docs={\"show\": False}\n    )\n\n    seed_config = get_rendered_seed_config()\n    unrendered_seed_config = get_unrendered_seed_config()\n\n    test_config = get_rendered_tst_config()\n    unrendered_test_config = get_unrendered_tst_config()\n\n    snapshot_config = get_rendered_snapshot_config(target_schema=alternate_schema)\n    unrendered_snapshot_config = get_unrendered_snapshot_config(target_schema=alternate_schema)\n\n    quote_database = quote_schema = True\n    relation_name_node_format = relation_name_format(quote_database, quote_schema, quote_model)\n    relation_name_source_format = relation_name_format(\n        quote_database, quote_schema, quote_identifier=True\n    )\n\n    compiled_model_path = os.path.join(\"target\", \"compiled\", \"test\", \"models\")\n\n    model_raw_code = read_file_replace_returns(model_sql_path).rstrip(\"\\r\\n\")\n\n    return {\n        \"dbt_schema_version\": \"https://schemas.getdbt.com/dbt/manifest/v7.json\",\n        \"dbt_version\": dbt.version.__version__,\n        \"nodes\": {\n            \"model.test.model\": {\n                \"compiled_path\": os.path.join(compiled_model_path, \"model.sql\"),\n                \"build_path\": None,\n                \"created_at\": ANY,\n                \"name\": \"model\",\n                \"relation_name\": relation_name_node_format.format(\n                    model_database, my_schema_name, \"model\"\n                ),\n                \"resource_type\": \"model\",\n                \"path\": \"model.sql\",\n                \"original_file_path\": model_sql_path,\n                \"package_name\": \"test\",\n                \"raw_code\": LineIndifferent(model_raw_code),\n                \"language\": \"sql\",\n                \"refs\": [{\"name\": \"seed\", \"package\": None, \"version\": None}],\n                \"sources\": [],\n                \"functions\": [],\n                \"depends_on\": {\"nodes\": [\"seed.test.seed\"], \"macros\": []},\n                \"deprecation_date\": None,\n                \"unique_id\": \"model.test.model\",\n                \"fqn\": [\"test\", \"model\"],\n                \"metrics\": [],\n                \"tags\": [],\n                \"meta\": {},\n                \"config\": model_config,\n                \"group\": None,\n                \"schema\": my_schema_name,\n                \"database\": model_database,\n                \"alias\": \"model\",\n                \"description\": \"The test model\",\n                \"primary_key\": [\"id\"],\n                \"columns\": {\n                    \"id\": {\n                        \"name\": \"id\",\n                        \"description\": \"The user ID number\",\n                        \"dimension\": None,\n                        \"entity\": None,\n                        \"data_type\": None,\n                        \"meta\": {},\n                        \"quote\": None,\n                        \"tags\": [],\n                        \"constraints\": [],\n                        \"granularity\": None,\n                        \"doc_blocks\": [],\n                        \"config\": {\"meta\": {}, \"tags\": []},\n                    },\n                    \"first_name\": {\n                        \"name\": \"first_name\",\n                        \"description\": \"The user's first name\",\n                        \"dimension\": None,\n                        \"entity\": None,\n                        \"data_type\": None,\n                        \"meta\": {},\n                        \"quote\": None,\n                        \"tags\": [],\n                        \"constraints\": [],\n                        \"granularity\": None,\n                        \"doc_blocks\": [],\n                        \"config\": {\"meta\": {}, \"tags\": []},\n                    },\n                    \"email\": {\n                        \"name\": \"email\",\n                        \"description\": \"The user's email\",\n                        \"dimension\": None,\n                        \"entity\": None,\n                        \"data_type\": None,\n                        \"meta\": {},\n                        \"quote\": None,\n                        \"tags\": [],\n                        \"constraints\": [],\n                        \"granularity\": None,\n                        \"doc_blocks\": [],\n                        \"config\": {\"meta\": {}, \"tags\": []},\n                    },\n                    \"ip_address\": {\n                        \"name\": \"ip_address\",\n                        \"description\": \"The user's IP address\",\n                        \"dimension\": None,\n                        \"entity\": None,\n                        \"data_type\": None,\n                        \"meta\": {},\n                        \"quote\": None,\n                        \"tags\": [],\n                        \"constraints\": [],\n                        \"granularity\": None,\n                        \"doc_blocks\": [],\n                        \"config\": {\"meta\": {}, \"tags\": []},\n                    },\n                    \"updated_at\": {\n                        \"name\": \"updated_at\",\n                        \"description\": \"The last time this user's email was updated\",\n                        \"dimension\": None,\n                        \"entity\": None,\n                        \"data_type\": None,\n                        \"meta\": {},\n                        \"quote\": None,\n                        \"tags\": [],\n                        \"constraints\": [],\n                        \"granularity\": None,\n                        \"doc_blocks\": [],\n                        \"config\": {\"meta\": {}, \"tags\": []},\n                    },\n                },\n                \"contract\": {\"checksum\": None, \"enforced\": False, \"alias_types\": True},\n                \"constraints\": [],\n                \"patch_path\": \"test://\" + model_schema_yml_path,\n                \"docs\": {\"node_color\": None, \"show\": False},\n                \"compiled\": True,\n                \"compiled_code\": ANY,\n                \"extra_ctes_injected\": True,\n                \"extra_ctes\": [],\n                \"checksum\": checksum_file(model_sql_path),\n                \"unrendered_config\": unrendered_model_config,\n                \"access\": \"protected\",\n                \"version\": None,\n                \"latest_version\": None,\n                \"time_spine\": None,\n                \"doc_blocks\": [],\n            },\n            \"model.test.second_model\": {\n                \"compiled_path\": os.path.join(compiled_model_path, \"second_model.sql\"),\n                \"build_path\": None,\n                \"created_at\": ANY,\n                \"name\": \"second_model\",\n                \"relation_name\": relation_name_node_format.format(\n                    project.database, alternate_schema, \"second_model\"\n                ),\n                \"resource_type\": \"model\",\n                \"path\": \"second_model.sql\",\n                \"original_file_path\": second_model_sql_path,\n                \"package_name\": \"test\",\n                \"raw_code\": LineIndifferent(\n                    read_file_replace_returns(second_model_sql_path).rstrip(\"\\r\\n\")\n                ),\n                \"language\": \"sql\",\n                \"refs\": [{\"name\": \"seed\", \"package\": None, \"version\": None}],\n                \"sources\": [],\n                \"functions\": [],\n                \"depends_on\": {\"nodes\": [\"seed.test.seed\"], \"macros\": []},\n                \"deprecation_date\": None,\n                \"unique_id\": \"model.test.second_model\",\n                \"fqn\": [\"test\", \"second_model\"],\n                \"metrics\": [],\n                \"tags\": [],\n                \"meta\": {},\n                \"config\": second_config,\n                \"group\": None,\n                \"schema\": alternate_schema,\n                \"database\": project.database,\n                \"alias\": \"second_model\",\n                \"description\": \"The second test model\",\n                \"primary_key\": [],\n                \"columns\": {\n                    \"id\": {\n                        \"name\": \"id\",\n                        \"description\": \"The user ID number\",\n                        \"dimension\": None,\n                        \"entity\": None,\n                        \"data_type\": None,\n                        \"meta\": {},\n                        \"quote\": None,\n                        \"tags\": [],\n                        \"constraints\": [],\n                        \"granularity\": None,\n                        \"doc_blocks\": [],\n                        \"config\": {\"meta\": {}, \"tags\": []},\n                    },\n                    \"first_name\": {\n                        \"name\": \"first_name\",\n                        \"description\": \"The user's first name\",\n                        \"dimension\": None,\n                        \"entity\": None,\n                        \"data_type\": None,\n                        \"meta\": {},\n                        \"quote\": None,\n                        \"tags\": [],\n                        \"constraints\": [],\n                        \"granularity\": None,\n                        \"doc_blocks\": [],\n                        \"config\": {\"meta\": {}, \"tags\": []},\n                    },\n                    \"email\": {\n                        \"name\": \"email\",\n                        \"description\": \"The user's email\",\n                        \"dimension\": None,\n                        \"entity\": None,\n                        \"data_type\": None,\n                        \"meta\": {},\n                        \"quote\": None,\n                        \"tags\": [],\n                        \"constraints\": [],\n                        \"granularity\": None,\n                        \"doc_blocks\": [],\n                        \"config\": {\"meta\": {}, \"tags\": []},\n                    },\n                    \"ip_address\": {\n                        \"name\": \"ip_address\",\n                        \"description\": \"The user's IP address\",\n                        \"dimension\": None,\n                        \"entity\": None,\n                        \"data_type\": None,\n                        \"meta\": {},\n                        \"quote\": None,\n                        \"tags\": [],\n                        \"constraints\": [],\n                        \"granularity\": None,\n                        \"doc_blocks\": [],\n                        \"config\": {\"meta\": {}, \"tags\": []},\n                    },\n                    \"updated_at\": {\n                        \"name\": \"updated_at\",\n                        \"description\": \"The last time this user's email was updated\",\n                        \"dimension\": None,\n                        \"entity\": None,\n                        \"data_type\": None,\n                        \"meta\": {},\n                        \"quote\": None,\n                        \"tags\": [],\n                        \"constraints\": [],\n                        \"granularity\": None,\n                        \"doc_blocks\": [],\n                        \"config\": {\"meta\": {}, \"tags\": []},\n                    },\n                },\n                \"contract\": {\"checksum\": None, \"enforced\": False, \"alias_types\": True},\n                \"constraints\": [],\n                \"patch_path\": \"test://\" + model_schema_yml_path,\n                \"docs\": {\"node_color\": None, \"show\": False},\n                \"compiled\": True,\n                \"compiled_code\": ANY,\n                \"extra_ctes_injected\": True,\n                \"extra_ctes\": [],\n                \"checksum\": checksum_file(second_model_sql_path),\n                \"unrendered_config\": unrendered_second_config,\n                \"access\": \"protected\",\n                \"version\": None,\n                \"latest_version\": None,\n                \"time_spine\": None,\n                \"doc_blocks\": [],\n            },\n            \"seed.test.seed\": {\n                \"build_path\": None,\n                \"created_at\": ANY,\n                \"config\": seed_config,\n                \"group\": None,\n                \"patch_path\": \"test://\" + seed_schema_yml_path,\n                \"path\": \"seed.csv\",\n                \"name\": \"seed\",\n                \"root_path\": project.project_root,\n                \"resource_type\": \"seed\",\n                \"raw_code\": \"\",\n                \"package_name\": \"test\",\n                \"original_file_path\": seed_path,\n                \"unique_id\": \"seed.test.seed\",\n                \"fqn\": [\"test\", \"seed\"],\n                \"tags\": [],\n                \"meta\": {},\n                \"depends_on\": {\"macros\": []},\n                \"schema\": my_schema_name,\n                \"database\": project.database,\n                \"alias\": \"seed\",\n                \"description\": \"The test seed\",\n                \"columns\": {\n                    \"id\": {\n                        \"name\": \"id\",\n                        \"description\": \"The user ID number\",\n                        \"dimension\": None,\n                        \"entity\": None,\n                        \"data_type\": None,\n                        \"meta\": {},\n                        \"quote\": None,\n                        \"tags\": [],\n                        \"constraints\": [],\n                        \"granularity\": None,\n                        \"doc_blocks\": [],\n                        \"config\": {\"meta\": {}, \"tags\": []},\n                    },\n                    \"first_name\": {\n                        \"name\": \"first_name\",\n                        \"description\": \"The user's first name\",\n                        \"dimension\": None,\n                        \"entity\": None,\n                        \"data_type\": None,\n                        \"meta\": {},\n                        \"quote\": None,\n                        \"tags\": [],\n                        \"constraints\": [],\n                        \"granularity\": None,\n                        \"doc_blocks\": [],\n                        \"config\": {\"meta\": {}, \"tags\": []},\n                    },\n                    \"email\": {\n                        \"name\": \"email\",\n                        \"description\": \"The user's email\",\n                        \"dimension\": None,\n                        \"entity\": None,\n                        \"data_type\": None,\n                        \"meta\": {},\n                        \"quote\": None,\n                        \"tags\": [],\n                        \"constraints\": [],\n                        \"granularity\": None,\n                        \"doc_blocks\": [],\n                        \"config\": {\"meta\": {}, \"tags\": []},\n                    },\n                    \"ip_address\": {\n                        \"name\": \"ip_address\",\n                        \"description\": \"The user's IP address\",\n                        \"dimension\": None,\n                        \"entity\": None,\n                        \"data_type\": None,\n                        \"meta\": {},\n                        \"quote\": None,\n                        \"tags\": [],\n                        \"constraints\": [],\n                        \"granularity\": None,\n                        \"doc_blocks\": [],\n                        \"config\": {\"meta\": {}, \"tags\": []},\n                    },\n                    \"updated_at\": {\n                        \"name\": \"updated_at\",\n                        \"description\": \"The last time this user's email was updated\",\n                        \"dimension\": None,\n                        \"entity\": None,\n                        \"data_type\": None,\n                        \"meta\": {},\n                        \"quote\": None,\n                        \"tags\": [],\n                        \"constraints\": [],\n                        \"granularity\": None,\n                        \"doc_blocks\": [],\n                        \"config\": {\"meta\": {}, \"tags\": []},\n                    },\n                },\n                \"docs\": {\"node_color\": None, \"show\": True},\n                \"checksum\": checksum_file(seed_path),\n                \"unrendered_config\": unrendered_seed_config,\n                \"relation_name\": relation_name_node_format.format(\n                    project.database, my_schema_name, \"seed\"\n                ),\n                \"doc_blocks\": [],\n            },\n            \"test.test.not_null_model_id.d01cc630e6\": {\n                \"alias\": \"not_null_model_id\",\n                \"attached_node\": \"model.test.model\",\n                \"compiled_path\": os.path.join(\n                    compiled_model_path, \"schema.yml\", \"not_null_model_id.sql\"\n                ),\n                \"build_path\": None,\n                \"created_at\": ANY,\n                \"column_name\": \"id\",\n                \"columns\": {},\n                \"config\": test_config,\n                \"sources\": [],\n                \"functions\": [],\n                \"group\": None,\n                \"depends_on\": {\n                    \"macros\": [\"macro.dbt.test_not_null\", \"macro.dbt.get_where_subquery\"],\n                    \"nodes\": [\"model.test.model\"],\n                },\n                \"description\": \"\",\n                \"file_key_name\": \"models.model\",\n                \"fqn\": [\"test\", \"not_null_model_id\"],\n                \"metrics\": [],\n                \"name\": \"not_null_model_id\",\n                \"original_file_path\": model_schema_yml_path,\n                \"package_name\": \"test\",\n                \"patch_path\": None,\n                \"path\": \"not_null_model_id.sql\",\n                \"raw_code\": \"{{ test_not_null(**_dbt_generic_test_kwargs) }}\",\n                \"language\": \"sql\",\n                \"refs\": [{\"name\": \"model\", \"package\": None, \"version\": None}],\n                \"relation_name\": None,\n                \"resource_type\": \"test\",\n                \"schema\": test_audit_schema,\n                \"database\": project.database,\n                \"tags\": [],\n                \"meta\": {},\n                \"unique_id\": \"test.test.not_null_model_id.d01cc630e6\",\n                \"docs\": {\"node_color\": None, \"show\": True},\n                \"compiled\": True,\n                \"compiled_code\": AnyStringWith(\"where id is null\"),\n                \"extra_ctes_injected\": True,\n                \"extra_ctes\": [],\n                \"test_metadata\": {\n                    \"namespace\": None,\n                    \"name\": \"not_null\",\n                    \"kwargs\": {\n                        \"column_name\": \"id\",\n                        \"model\": \"{{ get_where_subquery(ref('model')) }}\",\n                    },\n                },\n                \"checksum\": {\"name\": \"none\", \"checksum\": \"\"},\n                \"unrendered_config\": unrendered_test_config,\n                \"contract\": {\"checksum\": None, \"enforced\": False, \"alias_types\": True},\n                \"doc_blocks\": [],\n            },\n            \"snapshot.test.snapshot_seed\": {\n                \"alias\": \"snapshot_seed\",\n                \"compiled_path\": os.path.join(\n                    \"target\", \"compiled\", \"test\", \"snapshots\", \"snapshot_seed.sql\"\n                ),\n                \"build_path\": None,\n                \"created_at\": ANY,\n                \"checksum\": checksum_file(snapshot_path),\n                \"columns\": {},\n                \"compiled\": True,\n                \"compiled_code\": ANY,\n                \"config\": snapshot_config,\n                \"contract\": {\"checksum\": None, \"enforced\": False, \"alias_types\": True},\n                \"database\": project.database,\n                \"group\": None,\n                \"depends_on\": {\n                    \"macros\": [],\n                    \"nodes\": [\"seed.test.seed\"],\n                },\n                \"description\": \"\",\n                \"docs\": {\"node_color\": None, \"show\": True},\n                \"extra_ctes\": [],\n                \"extra_ctes_injected\": True,\n                \"fqn\": [\"test\", \"snapshot_seed\", \"snapshot_seed\"],\n                \"metrics\": [],\n                \"meta\": {},\n                \"name\": \"snapshot_seed\",\n                \"original_file_path\": snapshot_path,\n                \"package_name\": \"test\",\n                \"patch_path\": None,\n                \"path\": \"snapshot_seed.sql\",\n                \"raw_code\": LineIndifferent(\n                    read_file_replace_returns(snapshot_path)\n                    .replace(\"{% snapshot snapshot_seed %}\", \"\")\n                    .replace(\"{% endsnapshot %}\", \"\")\n                ),\n                \"language\": \"sql\",\n                \"refs\": [{\"name\": \"seed\", \"package\": None, \"version\": None}],\n                \"relation_name\": relation_name_node_format.format(\n                    project.database, alternate_schema, \"snapshot_seed\"\n                ),\n                \"resource_type\": \"snapshot\",\n                \"schema\": alternate_schema,\n                \"sources\": [],\n                \"functions\": [],\n                \"tags\": [],\n                \"unique_id\": \"snapshot.test.snapshot_seed\",\n                \"unrendered_config\": unrendered_snapshot_config,\n                \"doc_blocks\": [],\n            },\n            \"test.test.test_nothing_model_.5d38568946\": {\n                \"alias\": \"test_nothing_model_\",\n                \"attached_node\": \"model.test.model\",\n                \"compiled_path\": os.path.join(\n                    compiled_model_path, \"schema.yml\", \"test_nothing_model_.sql\"\n                ),\n                \"build_path\": None,\n                \"created_at\": ANY,\n                \"column_name\": None,\n                \"columns\": {},\n                \"config\": test_config,\n                \"group\": None,\n                \"contract\": {\"checksum\": None, \"enforced\": False, \"alias_types\": True},\n                \"sources\": [],\n                \"functions\": [],\n                \"depends_on\": {\n                    \"macros\": [\"macro.test.test_nothing\", \"macro.dbt.get_where_subquery\"],\n                    \"nodes\": [\"model.test.model\"],\n                },\n                \"description\": \"\",\n                \"file_key_name\": \"models.model\",\n                \"fqn\": [\"test\", \"test_nothing_model_\"],\n                \"metrics\": [],\n                \"name\": \"test_nothing_model_\",\n                \"original_file_path\": model_schema_yml_path,\n                \"package_name\": \"test\",\n                \"patch_path\": None,\n                \"path\": \"test_nothing_model_.sql\",\n                \"raw_code\": \"{{ test.test_nothing(**_dbt_generic_test_kwargs) }}\",\n                \"language\": \"sql\",\n                \"refs\": [{\"name\": \"model\", \"package\": None, \"version\": None}],\n                \"relation_name\": None,\n                \"resource_type\": \"test\",\n                \"schema\": test_audit_schema,\n                \"database\": project.database,\n                \"tags\": [],\n                \"meta\": {},\n                \"unique_id\": \"test.test.test_nothing_model_.5d38568946\",\n                \"docs\": {\"node_color\": None, \"show\": True},\n                \"compiled\": True,\n                \"compiled_code\": AnyStringWith(\"select 0\"),\n                \"extra_ctes_injected\": True,\n                \"extra_ctes\": [],\n                \"test_metadata\": {\n                    \"namespace\": \"test\",\n                    \"name\": \"nothing\",\n                    \"kwargs\": {\n                        \"model\": \"{{ get_where_subquery(ref('model')) }}\",\n                    },\n                },\n                \"checksum\": {\"name\": \"none\", \"checksum\": \"\"},\n                \"unrendered_config\": unrendered_test_config,\n                \"doc_blocks\": [],\n            },\n            \"test.test.unique_model_id.67b76558ff\": {\n                \"alias\": \"unique_model_id\",\n                \"attached_node\": \"model.test.model\",\n                \"compiled_path\": os.path.join(\n                    compiled_model_path, \"schema.yml\", \"unique_model_id.sql\"\n                ),\n                \"build_path\": None,\n                \"created_at\": ANY,\n                \"column_name\": \"id\",\n                \"columns\": {},\n                \"config\": test_config,\n                \"group\": None,\n                \"contract\": {\"checksum\": None, \"enforced\": False, \"alias_types\": True},\n                \"sources\": [],\n                \"functions\": [],\n                \"depends_on\": {\n                    \"macros\": [\"macro.dbt.test_unique\", \"macro.dbt.get_where_subquery\"],\n                    \"nodes\": [\"model.test.model\"],\n                },\n                \"description\": \"\",\n                \"file_key_name\": \"models.model\",\n                \"fqn\": [\"test\", \"unique_model_id\"],\n                \"metrics\": [],\n                \"name\": \"unique_model_id\",\n                \"original_file_path\": model_schema_yml_path,\n                \"package_name\": \"test\",\n                \"patch_path\": None,\n                \"path\": \"unique_model_id.sql\",\n                \"raw_code\": \"{{ test_unique(**_dbt_generic_test_kwargs) }}\",\n                \"language\": \"sql\",\n                \"refs\": [{\"name\": \"model\", \"package\": None, \"version\": None}],\n                \"relation_name\": None,\n                \"resource_type\": \"test\",\n                \"schema\": test_audit_schema,\n                \"database\": project.database,\n                \"tags\": [],\n                \"meta\": {},\n                \"unique_id\": \"test.test.unique_model_id.67b76558ff\",\n                \"docs\": {\"node_color\": None, \"show\": True},\n                \"compiled\": True,\n                \"compiled_code\": AnyStringWith(\"count(*)\"),\n                \"extra_ctes_injected\": True,\n                \"extra_ctes\": [],\n                \"test_metadata\": {\n                    \"namespace\": None,\n                    \"name\": \"unique\",\n                    \"kwargs\": {\n                        \"column_name\": \"id\",\n                        \"model\": \"{{ get_where_subquery(ref('model')) }}\",\n                    },\n                },\n                \"checksum\": {\"name\": \"none\", \"checksum\": \"\"},\n                \"unrendered_config\": unrendered_test_config,\n                \"doc_blocks\": [],\n            },\n        },\n        \"sources\": {\n            \"source.test.my_source.my_table\": {\n                \"created_at\": ANY,\n                \"columns\": {\n                    \"id\": {\n                        \"description\": \"An ID field\",\n                        \"name\": \"id\",\n                        \"dimension\": None,\n                        \"entity\": None,\n                        \"data_type\": None,\n                        \"meta\": {},\n                        \"quote\": None,\n                        \"tags\": [],\n                        \"constraints\": [],\n                        \"granularity\": None,\n                        \"doc_blocks\": [],\n                        \"config\": {\"meta\": {}, \"tags\": []},\n                    }\n                },\n                \"config\": {\n                    \"enabled\": True,\n                    \"event_time\": None,\n                    \"freshness\": {\n                        \"error_after\": {\"count\": None, \"period\": None},\n                        \"warn_after\": {\"count\": None, \"period\": None},\n                        \"filter\": None,\n                    },\n                    \"loaded_at_query\": None,\n                    \"loaded_at_field\": None,\n                    \"meta\": {},\n                    \"tags\": [],\n                },\n                \"quoting\": {\n                    \"database\": None,\n                    \"schema\": None,\n                    \"identifier\": True,\n                    \"column\": None,\n                },\n                \"database\": project.database,\n                \"description\": \"My table\",\n                \"external\": None,\n                \"freshness\": {\n                    \"error_after\": {\"count\": None, \"period\": None},\n                    \"warn_after\": {\"count\": None, \"period\": None},\n                    \"filter\": None,\n                },\n                \"identifier\": \"seed\",\n                \"loaded_at_field\": None,\n                \"loaded_at_query\": None,\n                \"loader\": \"a_loader\",\n                \"meta\": {},\n                \"name\": \"my_table\",\n                \"original_file_path\": os.path.join(\"models\", \"schema.yml\"),\n                \"package_name\": \"test\",\n                \"path\": os.path.join(\"models\", \"schema.yml\"),\n                \"patch_path\": None,\n                \"relation_name\": relation_name_source_format.format(\n                    project.database, my_schema_name, \"seed\"\n                ),\n                \"resource_type\": \"source\",\n                \"schema\": my_schema_name,\n                \"source_description\": \"My source\",\n                \"source_name\": \"my_source\",\n                \"source_meta\": {},\n                \"tags\": [],\n                \"unique_id\": \"source.test.my_source.my_table\",\n                \"fqn\": [\"test\", \"my_source\", \"my_table\"],\n                \"unrendered_config\": {\n                    \"loaded_at_field\": None,\n                    \"loaded_at_query\": None,\n                    \"meta\": {},\n                    \"tags\": [],\n                },\n                \"unrendered_database\": None,\n                \"unrendered_schema\": \"{{ var('test_schema') }}\",\n                \"doc_blocks\": [],\n            },\n        },\n        \"exposures\": {\n            \"exposure.test.notebook_exposure\": {\n                \"created_at\": ANY,\n                \"depends_on\": {\n                    \"macros\": [],\n                    \"nodes\": [\"model.test.model\", \"model.test.second_model\"],\n                },\n                \"description\": \"A description of the complex exposure\\n\",\n                \"label\": None,\n                \"config\": {\n                    \"enabled\": True,\n                    \"meta\": {\"tool\": \"my_tool\", \"languages\": [\"python\"]},\n                    \"tags\": [\"my_department\"],\n                },\n                \"fqn\": [\"test\", \"notebook_exposure\"],\n                \"maturity\": \"medium\",\n                \"meta\": {\"tool\": \"my_tool\", \"languages\": [\"python\"]},\n                \"metrics\": [],\n                \"tags\": [\"my_department\"],\n                \"name\": \"notebook_exposure\",\n                \"original_file_path\": os.path.join(\"models\", \"schema.yml\"),\n                \"owner\": {\"email\": \"something@example.com\", \"name\": \"Some name\"},\n                \"package_name\": \"test\",\n                \"path\": \"schema.yml\",\n                \"refs\": [\n                    {\"name\": \"model\", \"package\": None, \"version\": None},\n                    {\"name\": \"second_model\", \"package\": None, \"version\": None},\n                ],\n                \"resource_type\": \"exposure\",\n                \"sources\": [],\n                \"type\": \"notebook\",\n                \"unique_id\": \"exposure.test.notebook_exposure\",\n                \"url\": \"http://example.com/notebook/1\",\n                \"unrendered_config\": {},\n            },\n            \"exposure.test.simple_exposure\": {\n                \"created_at\": ANY,\n                \"depends_on\": {\n                    \"macros\": [],\n                    \"nodes\": [\"source.test.my_source.my_table\", \"model.test.model\"],\n                },\n                \"description\": \"\",\n                \"label\": None,\n                \"config\": {\n                    \"enabled\": True,\n                    \"meta\": {},\n                    \"tags\": [],\n                },\n                \"fqn\": [\"test\", \"simple_exposure\"],\n                \"metrics\": [],\n                \"name\": \"simple_exposure\",\n                \"original_file_path\": os.path.join(\"models\", \"schema.yml\"),\n                \"owner\": {\n                    \"email\": \"something@example.com\",\n                    \"name\": None,\n                },\n                \"package_name\": \"test\",\n                \"path\": \"schema.yml\",\n                \"refs\": [{\"name\": \"model\", \"package\": None, \"version\": None}],\n                \"resource_type\": \"exposure\",\n                \"sources\": [[\"my_source\", \"my_table\"]],\n                \"type\": \"dashboard\",\n                \"unique_id\": \"exposure.test.simple_exposure\",\n                \"url\": None,\n                \"maturity\": None,\n                \"meta\": {},\n                \"tags\": [],\n                \"unrendered_config\": {},\n            },\n        },\n        \"metrics\": {},\n        \"groups\": {},\n        \"selectors\": {},\n        \"parent_map\": {\n            \"model.test.model\": [\"seed.test.seed\"],\n            \"model.test.second_model\": [\"seed.test.seed\"],\n            \"exposure.test.notebook_exposure\": [\"model.test.model\", \"model.test.second_model\"],\n            \"exposure.test.simple_exposure\": [\n                \"model.test.model\",\n                \"source.test.my_source.my_table\",\n            ],\n            \"seed.test.seed\": [],\n            \"snapshot.test.snapshot_seed\": [\"seed.test.seed\"],\n            \"source.test.my_source.my_table\": [],\n            \"test.test.not_null_model_id.d01cc630e6\": [\"model.test.model\"],\n            \"test.test.test_nothing_model_.5d38568946\": [\"model.test.model\"],\n            \"test.test.unique_model_id.67b76558ff\": [\"model.test.model\"],\n        },\n        \"child_map\": {\n            \"model.test.model\": [\n                \"exposure.test.notebook_exposure\",\n                \"exposure.test.simple_exposure\",\n                \"test.test.not_null_model_id.d01cc630e6\",\n                \"test.test.test_nothing_model_.5d38568946\",\n                \"test.test.unique_model_id.67b76558ff\",\n            ],\n            \"model.test.second_model\": [\"exposure.test.notebook_exposure\"],\n            \"exposure.test.notebook_exposure\": [],\n            \"exposure.test.simple_exposure\": [],\n            \"seed.test.seed\": [\n                \"model.test.model\",\n                \"model.test.second_model\",\n                \"snapshot.test.snapshot_seed\",\n            ],\n            \"snapshot.test.snapshot_seed\": [],\n            \"source.test.my_source.my_table\": [\"exposure.test.simple_exposure\"],\n            \"test.test.not_null_model_id.d01cc630e6\": [],\n            \"test.test.test_nothing_model_.5d38568946\": [],\n            \"test.test.unique_model_id.67b76558ff\": [],\n        },\n        \"group_map\": {},\n        \"docs\": {\n            \"doc.dbt.__overview__\": ANY,\n            \"doc.test.macro_info\": ANY,\n            \"doc.test.macro_arg_info\": ANY,\n        },\n        \"disabled\": {},\n        \"semantic_models\": {},\n        \"unit_tests\": {},\n        \"saved_queries\": {},\n        \"functions\": {},\n    }\n\n\ndef expected_references_manifest(project):\n    model_database = project.database\n    my_schema_name = project.test_schema\n    docs_path = os.path.join(\"models\", \"docs.md\")\n    ephemeral_copy_path = os.path.join(\"models\", \"ephemeral_copy.sql\")\n    ephemeral_summary_path = os.path.join(\"models\", \"ephemeral_summary.sql\")\n    view_summary_path = os.path.join(\"models\", \"view_summary.sql\")\n    seed_path = os.path.join(\"seeds\", \"seed.csv\")\n    snapshot_path = os.path.join(\"snapshots\", \"snapshot_seed.sql\")\n    compiled_model_path = os.path.join(\"target\", \"compiled\", \"test\", \"models\")\n    schema_yml_path = os.path.join(\"models\", \"schema.yml\")\n\n    ephemeral_copy_sql = read_file_replace_returns(ephemeral_copy_path).rstrip(\"\\r\\n\")\n    ephemeral_summary_sql = read_file_replace_returns(ephemeral_summary_path).rstrip(\"\\r\\n\")\n    view_summary_sql = read_file_replace_returns(view_summary_path).rstrip(\"\\r\\n\")\n    alternate_schema = project.test_schema + \"_test\"\n\n    return {\n        \"dbt_schema_version\": \"https://schemas.getdbt.com/dbt/manifest/v7.json\",\n        \"dbt_version\": dbt.version.__version__,\n        \"nodes\": {\n            \"model.test.ephemeral_copy\": {\n                \"alias\": \"ephemeral_copy\",\n                \"compiled_path\": os.path.join(compiled_model_path, \"ephemeral_copy.sql\"),\n                \"build_path\": None,\n                \"created_at\": ANY,\n                \"columns\": {},\n                \"config\": get_rendered_model_config(materialized=\"ephemeral\"),\n                \"sources\": [[\"my_source\", \"my_table\"]],\n                \"depends_on\": {\n                    \"macros\": [],\n                    \"nodes\": [\"source.test.my_source.my_table\"],\n                },\n                \"deprecation_date\": None,\n                \"description\": \"\",\n                \"primary_key\": [],\n                \"docs\": {\"node_color\": None, \"show\": True},\n                \"fqn\": [\"test\", \"ephemeral_copy\"],\n                \"group\": None,\n                \"metrics\": [],\n                \"functions\": [],\n                \"name\": \"ephemeral_copy\",\n                \"original_file_path\": ephemeral_copy_path,\n                \"package_name\": \"test\",\n                \"patch_path\": None,\n                \"path\": \"ephemeral_copy.sql\",\n                \"raw_code\": LineIndifferent(ephemeral_copy_sql),\n                \"language\": \"sql\",\n                \"refs\": [],\n                \"relation_name\": None,\n                \"resource_type\": \"model\",\n                \"schema\": my_schema_name,\n                \"database\": project.database,\n                \"tags\": [],\n                \"meta\": {},\n                \"unique_id\": \"model.test.ephemeral_copy\",\n                \"compiled\": True,\n                \"compiled_code\": ANY,\n                \"contract\": {\"checksum\": None, \"enforced\": False, \"alias_types\": True},\n                \"extra_ctes_injected\": True,\n                \"extra_ctes\": [],\n                \"checksum\": checksum_file(ephemeral_copy_path),\n                \"unrendered_config\": get_unrendered_model_config(materialized=\"ephemeral\"),\n                \"access\": \"protected\",\n                \"version\": None,\n                \"latest_version\": None,\n                \"constraints\": [],\n                \"time_spine\": None,\n                \"doc_blocks\": [],\n            },\n            \"model.test.ephemeral_summary\": {\n                \"alias\": \"ephemeral_summary\",\n                \"compiled_path\": os.path.join(compiled_model_path, \"ephemeral_summary.sql\"),\n                \"build_path\": None,\n                \"created_at\": ANY,\n                \"columns\": {\n                    \"first_name\": {\n                        \"description\": \"The first name being summarized\",\n                        \"name\": \"first_name\",\n                        \"dimension\": None,\n                        \"entity\": None,\n                        \"data_type\": None,\n                        \"meta\": {},\n                        \"quote\": None,\n                        \"tags\": [],\n                        \"constraints\": [],\n                        \"granularity\": None,\n                        \"doc_blocks\": [\"doc.test.summary_first_name\"],\n                        \"config\": {\"meta\": {}, \"tags\": []},\n                    },\n                    \"ct\": {\n                        \"description\": \"The number of instances of the first name\",\n                        \"name\": \"ct\",\n                        \"dimension\": None,\n                        \"entity\": None,\n                        \"data_type\": None,\n                        \"meta\": {},\n                        \"quote\": None,\n                        \"tags\": [],\n                        \"constraints\": [],\n                        \"granularity\": None,\n                        \"doc_blocks\": [\"doc.test.summary_count\"],\n                        \"config\": {\"meta\": {}, \"tags\": []},\n                    },\n                },\n                \"config\": get_rendered_model_config(materialized=\"table\", group=\"test_group\"),\n                \"contract\": {\"checksum\": None, \"enforced\": False, \"alias_types\": True},\n                \"sources\": [],\n                \"functions\": [],\n                \"depends_on\": {\n                    \"macros\": [],\n                    \"nodes\": [\"model.test.ephemeral_copy\"],\n                },\n                \"deprecation_date\": None,\n                \"description\": \"A summmary table of the ephemeral copy of the seed data\",\n                \"primary_key\": [],\n                \"docs\": {\"node_color\": None, \"show\": True},\n                \"fqn\": [\"test\", \"ephemeral_summary\"],\n                \"group\": \"test_group\",\n                \"metrics\": [],\n                \"name\": \"ephemeral_summary\",\n                \"original_file_path\": ephemeral_summary_path,\n                \"package_name\": \"test\",\n                \"patch_path\": \"test://\" + os.path.join(\"models\", \"schema.yml\"),\n                \"path\": \"ephemeral_summary.sql\",\n                \"raw_code\": LineIndifferent(ephemeral_summary_sql),\n                \"language\": \"sql\",\n                \"refs\": [{\"name\": \"ephemeral_copy\", \"package\": None, \"version\": None}],\n                \"relation_name\": '\"{0}\".\"{1}\".ephemeral_summary'.format(\n                    model_database, my_schema_name\n                ),\n                \"resource_type\": \"model\",\n                \"schema\": my_schema_name,\n                \"database\": project.database,\n                \"tags\": [],\n                \"meta\": {},\n                \"unique_id\": \"model.test.ephemeral_summary\",\n                \"compiled\": True,\n                \"compiled_code\": ANY,\n                \"extra_ctes_injected\": True,\n                \"extra_ctes\": [ANY],\n                \"checksum\": checksum_file(ephemeral_summary_path),\n                \"unrendered_config\": get_unrendered_model_config(\n                    materialized=\"table\", group=\"test_group\"\n                ),\n                \"access\": \"protected\",\n                \"version\": None,\n                \"latest_version\": None,\n                \"constraints\": [],\n                \"time_spine\": None,\n                \"doc_blocks\": [\"doc.test.ephemeral_summary\"],\n            },\n            \"model.test.view_summary\": {\n                \"alias\": \"view_summary\",\n                \"compiled_path\": os.path.join(compiled_model_path, \"view_summary.sql\"),\n                \"build_path\": None,\n                \"created_at\": ANY,\n                \"columns\": {\n                    \"first_name\": {\n                        \"description\": \"The first name being summarized\",\n                        \"name\": \"first_name\",\n                        \"dimension\": None,\n                        \"entity\": None,\n                        \"data_type\": None,\n                        \"meta\": {},\n                        \"quote\": None,\n                        \"tags\": [],\n                        \"constraints\": [],\n                        \"granularity\": None,\n                        \"doc_blocks\": [\"doc.test.summary_first_name\"],\n                        \"config\": {\"meta\": {}, \"tags\": []},\n                    },\n                    \"ct\": {\n                        \"description\": \"The number of instances of the first name\",\n                        \"name\": \"ct\",\n                        \"dimension\": None,\n                        \"entity\": None,\n                        \"data_type\": None,\n                        \"meta\": {},\n                        \"quote\": None,\n                        \"tags\": [],\n                        \"constraints\": [],\n                        \"granularity\": None,\n                        \"doc_blocks\": [\"doc.test.summary_count\"],\n                        \"config\": {\"meta\": {}, \"tags\": []},\n                    },\n                },\n                \"config\": get_rendered_model_config(),\n                \"contract\": {\"checksum\": None, \"enforced\": False, \"alias_types\": True},\n                \"database\": project.database,\n                \"depends_on\": {\n                    \"macros\": [],\n                    \"nodes\": [\"model.test.ephemeral_summary\"],\n                },\n                \"deprecation_date\": None,\n                \"description\": \"A view of the summary of the ephemeral copy of the seed data\",\n                \"primary_key\": [],\n                \"docs\": {\"node_color\": None, \"show\": True},\n                \"fqn\": [\"test\", \"view_summary\"],\n                \"group\": None,\n                \"metrics\": [],\n                \"name\": \"view_summary\",\n                \"original_file_path\": view_summary_path,\n                \"package_name\": \"test\",\n                \"patch_path\": \"test://\" + schema_yml_path,\n                \"path\": \"view_summary.sql\",\n                \"raw_code\": LineIndifferent(view_summary_sql),\n                \"language\": \"sql\",\n                \"refs\": [{\"name\": \"ephemeral_summary\", \"package\": None, \"version\": None}],\n                \"relation_name\": '\"{0}\".\"{1}\".view_summary'.format(model_database, my_schema_name),\n                \"resource_type\": \"model\",\n                \"schema\": my_schema_name,\n                \"sources\": [],\n                \"functions\": [],\n                \"tags\": [],\n                \"meta\": {},\n                \"unique_id\": \"model.test.view_summary\",\n                \"compiled\": True,\n                \"compiled_code\": ANY,\n                \"extra_ctes_injected\": True,\n                \"extra_ctes\": [],\n                \"checksum\": checksum_file(view_summary_path),\n                \"unrendered_config\": get_unrendered_model_config(materialized=\"view\"),\n                \"access\": \"protected\",\n                \"version\": None,\n                \"latest_version\": None,\n                \"constraints\": [],\n                \"time_spine\": None,\n                \"doc_blocks\": [\"doc.test.view_summary\"],\n            },\n            \"seed.test.seed\": {\n                \"alias\": \"seed\",\n                \"build_path\": None,\n                \"created_at\": ANY,\n                \"columns\": {\n                    \"id\": {\n                        \"name\": \"id\",\n                        \"description\": \"The user ID number\",\n                        \"dimension\": None,\n                        \"entity\": None,\n                        \"data_type\": None,\n                        \"meta\": {},\n                        \"quote\": None,\n                        \"tags\": [],\n                        \"constraints\": [],\n                        \"granularity\": None,\n                        \"doc_blocks\": [],\n                        \"config\": {\"meta\": {}, \"tags\": []},\n                    },\n                    \"first_name\": {\n                        \"name\": \"first_name\",\n                        \"description\": \"The user's first name\",\n                        \"dimension\": None,\n                        \"entity\": None,\n                        \"data_type\": None,\n                        \"meta\": {},\n                        \"quote\": None,\n                        \"tags\": [],\n                        \"constraints\": [],\n                        \"granularity\": None,\n                        \"doc_blocks\": [],\n                        \"config\": {\"meta\": {}, \"tags\": []},\n                    },\n                    \"email\": {\n                        \"name\": \"email\",\n                        \"description\": \"The user's email\",\n                        \"dimension\": None,\n                        \"entity\": None,\n                        \"data_type\": None,\n                        \"meta\": {},\n                        \"quote\": None,\n                        \"tags\": [],\n                        \"constraints\": [],\n                        \"granularity\": None,\n                        \"doc_blocks\": [],\n                        \"config\": {\"meta\": {}, \"tags\": []},\n                    },\n                    \"ip_address\": {\n                        \"name\": \"ip_address\",\n                        \"description\": \"The user's IP address\",\n                        \"dimension\": None,\n                        \"entity\": None,\n                        \"data_type\": None,\n                        \"meta\": {},\n                        \"quote\": None,\n                        \"tags\": [],\n                        \"constraints\": [],\n                        \"granularity\": None,\n                        \"doc_blocks\": [],\n                        \"config\": {\"meta\": {}, \"tags\": []},\n                    },\n                    \"updated_at\": {\n                        \"name\": \"updated_at\",\n                        \"description\": \"The last time this user's email was updated\",\n                        \"dimension\": None,\n                        \"entity\": None,\n                        \"data_type\": None,\n                        \"meta\": {},\n                        \"quote\": None,\n                        \"tags\": [],\n                        \"constraints\": [],\n                        \"granularity\": None,\n                        \"doc_blocks\": [],\n                        \"config\": {\"meta\": {}, \"tags\": []},\n                    },\n                },\n                \"config\": get_rendered_seed_config(),\n                \"depends_on\": {\"macros\": []},\n                \"description\": \"The test seed\",\n                \"docs\": {\"node_color\": None, \"show\": True},\n                \"fqn\": [\"test\", \"seed\"],\n                \"group\": None,\n                \"name\": \"seed\",\n                \"original_file_path\": seed_path,\n                \"package_name\": \"test\",\n                \"patch_path\": \"test://\" + os.path.join(\"seeds\", \"schema.yml\"),\n                \"path\": \"seed.csv\",\n                \"raw_code\": \"\",\n                \"resource_type\": \"seed\",\n                \"root_path\": project.project_root,\n                \"schema\": my_schema_name,\n                \"database\": project.database,\n                \"tags\": [],\n                \"meta\": {},\n                \"unique_id\": \"seed.test.seed\",\n                \"checksum\": checksum_file(seed_path),\n                \"unrendered_config\": get_unrendered_seed_config(),\n                \"relation_name\": '\"{0}\".\"{1}\".seed'.format(project.database, my_schema_name),\n                \"doc_blocks\": [],\n            },\n            \"snapshot.test.snapshot_seed\": {\n                \"alias\": \"snapshot_seed\",\n                \"compiled_path\": os.path.join(\n                    \"target\", \"compiled\", \"test\", \"snapshots\", \"snapshot_seed.sql\"\n                ),\n                \"build_path\": None,\n                \"created_at\": ANY,\n                \"checksum\": checksum_file(snapshot_path),\n                \"columns\": {},\n                \"compiled\": True,\n                \"compiled_code\": ANY,\n                \"config\": get_rendered_snapshot_config(target_schema=alternate_schema),\n                \"contract\": {\"checksum\": None, \"enforced\": False, \"alias_types\": True},\n                \"database\": model_database,\n                \"depends_on\": {\"macros\": [], \"nodes\": [\"seed.test.seed\"]},\n                \"description\": \"\",\n                \"docs\": {\"node_color\": None, \"show\": True},\n                \"extra_ctes\": [],\n                \"extra_ctes_injected\": True,\n                \"fqn\": [\"test\", \"snapshot_seed\", \"snapshot_seed\"],\n                \"group\": None,\n                \"metrics\": [],\n                \"functions\": [],\n                \"meta\": {},\n                \"name\": \"snapshot_seed\",\n                \"original_file_path\": snapshot_path,\n                \"package_name\": \"test\",\n                \"patch_path\": None,\n                \"path\": \"snapshot_seed.sql\",\n                \"raw_code\": ANY,\n                \"language\": \"sql\",\n                \"refs\": [{\"name\": \"seed\", \"package\": None, \"version\": None}],\n                \"relation_name\": '\"{0}\".\"{1}\".snapshot_seed'.format(\n                    model_database, alternate_schema\n                ),\n                \"resource_type\": \"snapshot\",\n                \"schema\": alternate_schema,\n                \"sources\": [],\n                \"tags\": [],\n                \"unique_id\": \"snapshot.test.snapshot_seed\",\n                \"unrendered_config\": get_unrendered_snapshot_config(\n                    target_schema=alternate_schema\n                ),\n                \"doc_blocks\": [],\n            },\n        },\n        \"sources\": {\n            \"source.test.my_source.my_table\": {\n                \"columns\": {\n                    \"id\": {\n                        \"description\": \"An ID field\",\n                        \"dimension\": None,\n                        \"entity\": None,\n                        \"name\": \"id\",\n                        \"data_type\": None,\n                        \"meta\": {},\n                        \"quote\": None,\n                        \"tags\": [],\n                        \"constraints\": [],\n                        \"granularity\": None,\n                        \"doc_blocks\": [\"doc.test.column_info\"],\n                        \"config\": {\"meta\": {}, \"tags\": []},\n                    }\n                },\n                \"config\": {\n                    \"enabled\": True,\n                    \"event_time\": None,\n                    \"freshness\": {\n                        \"error_after\": {\"count\": None, \"period\": None},\n                        \"warn_after\": {\"count\": None, \"period\": None},\n                        \"filter\": None,\n                    },\n                    \"loaded_at_field\": None,\n                    \"loaded_at_query\": None,\n                    \"meta\": {},\n                    \"tags\": [],\n                },\n                \"quoting\": {\n                    \"database\": False,\n                    \"schema\": None,\n                    \"identifier\": True,\n                    \"column\": None,\n                },\n                \"created_at\": ANY,\n                \"database\": project.database,\n                \"description\": \"My table\",\n                \"external\": None,\n                \"freshness\": {\n                    \"error_after\": {\"count\": None, \"period\": None},\n                    \"warn_after\": {\"count\": None, \"period\": None},\n                    \"filter\": None,\n                },\n                \"identifier\": \"seed\",\n                \"loaded_at_field\": None,\n                \"loaded_at_query\": None,\n                \"loader\": \"a_loader\",\n                \"meta\": {},\n                \"name\": \"my_table\",\n                \"original_file_path\": os.path.join(\"models\", \"schema.yml\"),\n                \"package_name\": \"test\",\n                \"path\": os.path.join(\"models\", \"schema.yml\"),\n                \"patch_path\": None,\n                \"relation_name\": '{0}.\"{1}\".\"seed\"'.format(project.database, my_schema_name),\n                \"resource_type\": \"source\",\n                \"schema\": my_schema_name,\n                \"source_description\": \"My source\",\n                \"source_name\": \"my_source\",\n                \"source_meta\": {},\n                \"tags\": [],\n                \"unique_id\": \"source.test.my_source.my_table\",\n                \"fqn\": [\"test\", \"my_source\", \"my_table\"],\n                \"unrendered_config\": {\n                    \"loaded_at_field\": None,\n                    \"loaded_at_query\": None,\n                    \"meta\": {},\n                    \"tags\": [],\n                },\n                \"unrendered_database\": None,\n                \"unrendered_schema\": \"{{ var('test_schema') }}\",\n                \"doc_blocks\": [\"doc.test.table_info\"],\n            },\n        },\n        \"exposures\": {\n            \"exposure.test.notebook_exposure\": {\n                \"created_at\": ANY,\n                \"depends_on\": {\n                    \"macros\": [],\n                    \"nodes\": [\"model.test.view_summary\"],\n                },\n                \"description\": \"A description of the complex exposure\",\n                \"label\": None,\n                \"config\": {\n                    \"enabled\": True,\n                    \"meta\": {\"tool\": \"my_tool\", \"languages\": [\"python\"]},\n                    \"tags\": [\"my_department\"],\n                },\n                \"fqn\": [\"test\", \"notebook_exposure\"],\n                \"maturity\": \"medium\",\n                \"meta\": {\"tool\": \"my_tool\", \"languages\": [\"python\"]},\n                \"metrics\": [],\n                \"tags\": [\"my_department\"],\n                \"name\": \"notebook_exposure\",\n                \"original_file_path\": os.path.join(\"models\", \"schema.yml\"),\n                \"owner\": {\"email\": \"something@example.com\", \"name\": \"Some name\"},\n                \"package_name\": \"test\",\n                \"path\": \"schema.yml\",\n                \"refs\": [{\"name\": \"view_summary\", \"package\": None, \"version\": None}],\n                \"resource_type\": \"exposure\",\n                \"sources\": [],\n                \"type\": \"notebook\",\n                \"unique_id\": \"exposure.test.notebook_exposure\",\n                \"url\": \"http://example.com/notebook/1\",\n                \"unrendered_config\": {},\n            },\n        },\n        \"metrics\": {},\n        \"groups\": {\n            \"group.test.test_group\": {\n                \"name\": \"test_group\",\n                \"resource_type\": \"group\",\n                \"original_file_path\": os.path.join(\"models\", \"schema.yml\"),\n                \"owner\": {\"email\": \"test_group@test.com\", \"name\": None},\n                \"package_name\": \"test\",\n                \"path\": \"schema.yml\",\n                \"unique_id\": \"group.test.test_group\",\n                \"description\": None,\n                \"config\": {\"meta\": {}},\n            }\n        },\n        \"selectors\": {},\n        \"docs\": {\n            \"doc.dbt.__overview__\": ANY,\n            \"doc.test.column_info\": {\n                \"block_contents\": \"An ID field\",\n                \"resource_type\": \"doc\",\n                \"name\": \"column_info\",\n                \"original_file_path\": docs_path,\n                \"package_name\": \"test\",\n                \"path\": \"docs.md\",\n                \"unique_id\": \"doc.test.column_info\",\n            },\n            \"doc.test.ephemeral_summary\": {\n                \"block_contents\": (\"A summmary table of the ephemeral copy of the seed data\"),\n                \"resource_type\": \"doc\",\n                \"name\": \"ephemeral_summary\",\n                \"original_file_path\": docs_path,\n                \"package_name\": \"test\",\n                \"path\": \"docs.md\",\n                \"unique_id\": \"doc.test.ephemeral_summary\",\n            },\n            \"doc.test.source_info\": {\n                \"block_contents\": \"My source\",\n                \"resource_type\": \"doc\",\n                \"name\": \"source_info\",\n                \"original_file_path\": docs_path,\n                \"package_name\": \"test\",\n                \"path\": \"docs.md\",\n                \"unique_id\": \"doc.test.source_info\",\n            },\n            \"doc.test.summary_count\": {\n                \"block_contents\": \"The number of instances of the first name\",\n                \"resource_type\": \"doc\",\n                \"name\": \"summary_count\",\n                \"original_file_path\": docs_path,\n                \"package_name\": \"test\",\n                \"path\": \"docs.md\",\n                \"unique_id\": \"doc.test.summary_count\",\n            },\n            \"doc.test.summary_first_name\": {\n                \"block_contents\": \"The first name being summarized\",\n                \"resource_type\": \"doc\",\n                \"name\": \"summary_first_name\",\n                \"original_file_path\": docs_path,\n                \"package_name\": \"test\",\n                \"path\": \"docs.md\",\n                \"unique_id\": \"doc.test.summary_first_name\",\n            },\n            \"doc.test.table_info\": {\n                \"block_contents\": \"My table\",\n                \"resource_type\": \"doc\",\n                \"name\": \"table_info\",\n                \"original_file_path\": docs_path,\n                \"package_name\": \"test\",\n                \"path\": \"docs.md\",\n                \"unique_id\": \"doc.test.table_info\",\n            },\n            \"doc.test.view_summary\": {\n                \"block_contents\": (\"A view of the summary of the ephemeral copy of the seed data\"),\n                \"resource_type\": \"doc\",\n                \"name\": \"view_summary\",\n                \"original_file_path\": docs_path,\n                \"package_name\": \"test\",\n                \"path\": \"docs.md\",\n                \"unique_id\": \"doc.test.view_summary\",\n            },\n            \"doc.test.macro_info\": {\n                \"block_contents\": \"My custom test that I wrote that does nothing\",\n                \"resource_type\": \"doc\",\n                \"name\": \"macro_info\",\n                \"original_file_path\": os.path.join(\"macros\", \"macro.md\"),\n                \"package_name\": \"test\",\n                \"path\": \"macro.md\",\n                \"unique_id\": \"doc.test.macro_info\",\n            },\n            \"doc.test.notebook_info\": {\n                \"block_contents\": \"A description of the complex exposure\",\n                \"resource_type\": \"doc\",\n                \"name\": \"notebook_info\",\n                \"original_file_path\": docs_path,\n                \"package_name\": \"test\",\n                \"path\": \"docs.md\",\n                \"unique_id\": \"doc.test.notebook_info\",\n            },\n            \"doc.test.macro_arg_info\": {\n                \"block_contents\": \"The model for my custom test\",\n                \"resource_type\": \"doc\",\n                \"name\": \"macro_arg_info\",\n                \"original_file_path\": os.path.join(\"macros\", \"macro.md\"),\n                \"package_name\": \"test\",\n                \"path\": \"macro.md\",\n                \"unique_id\": \"doc.test.macro_arg_info\",\n            },\n        },\n        \"child_map\": {\n            \"model.test.ephemeral_copy\": [\"model.test.ephemeral_summary\"],\n            \"exposure.test.notebook_exposure\": [],\n            \"model.test.ephemeral_summary\": [\"model.test.view_summary\"],\n            \"model.test.view_summary\": [\"exposure.test.notebook_exposure\"],\n            \"seed.test.seed\": [\"snapshot.test.snapshot_seed\"],\n            \"snapshot.test.snapshot_seed\": [],\n            \"source.test.my_source.my_table\": [\"model.test.ephemeral_copy\"],\n        },\n        \"parent_map\": {\n            \"model.test.ephemeral_copy\": [\"source.test.my_source.my_table\"],\n            \"model.test.ephemeral_summary\": [\"model.test.ephemeral_copy\"],\n            \"model.test.view_summary\": [\"model.test.ephemeral_summary\"],\n            \"exposure.test.notebook_exposure\": [\"model.test.view_summary\"],\n            \"seed.test.seed\": [],\n            \"snapshot.test.snapshot_seed\": [\"seed.test.seed\"],\n            \"source.test.my_source.my_table\": [],\n        },\n        \"group_map\": {\"test_group\": [\"model.test.ephemeral_summary\"]},\n        \"disabled\": {},\n        \"macros\": {\n            \"macro.test.test_nothing\": {\n                \"name\": \"test_nothing\",\n                \"depends_on\": {\"macros\": []},\n                \"created_at\": ANY,\n                \"description\": \"My custom test that I wrote that does nothing\",\n                \"docs\": {\"node_color\": None, \"show\": True},\n                \"macro_sql\": AnyStringWith(\"test nothing\"),\n                \"original_file_path\": os.path.join(\"macros\", \"dummy_test.sql\"),\n                \"path\": os.path.join(\"macros\", \"dummy_test.sql\"),\n                \"package_name\": \"test\",\n                \"meta\": {\n                    \"some_key\": 100,\n                },\n                \"config\": {\n                    \"meta\": {\n                        \"some_key\": 100,\n                    },\n                    \"docs\": {\"node_color\": None, \"show\": True},\n                },\n                \"patch_path\": \"test://\" + os.path.join(\"macros\", \"schema.yml\"),\n                \"resource_type\": \"macro\",\n                \"unique_id\": \"macro.test.test_nothing\",\n                \"supported_languages\": None,\n                \"arguments\": [\n                    {\n                        \"name\": \"model\",\n                        \"type\": \"Relation\",\n                        \"description\": \"The model for my custom test\",\n                    },\n                ],\n            }\n        },\n        \"semantic_models\": {},\n        \"unit_tests\": {},\n        \"saved_queries\": {},\n        \"functions\": {},\n    }\n\n\ndef expected_versions_manifest(project):\n    model_database = project.database\n    my_schema_name = project.test_schema\n\n    versioned_model_v1_path = os.path.join(\"models\", \"arbitrary_file_name.sql\")\n    versioned_model_v2_path = os.path.join(\"models\", \"versioned_model_v2.sql\")\n    ref_versioned_model_path = os.path.join(\"models\", \"ref_versioned_model.sql\")\n    compiled_model_path = os.path.join(\"target\", \"compiled\", \"test\", \"models\")\n    schema_yml_path = os.path.join(\"models\", \"schema.yml\")\n\n    versioned_model_v1_sql = read_file_replace_returns(versioned_model_v1_path).rstrip(\"\\r\\n\")\n    versioned_model_v2_sql = read_file_replace_returns(versioned_model_v2_path).rstrip(\"\\r\\n\")\n    ref_versioned_model_sql = read_file_replace_returns(ref_versioned_model_path).rstrip(\"\\r\\n\")\n\n    test_config = get_rendered_tst_config()\n    unrendered_test_config = get_unrendered_tst_config()\n    test_audit_schema = my_schema_name + \"_dbt_test__audit\"\n    model_schema_yml_path = os.path.join(\"models\", \"schema.yml\")\n\n    return {\n        \"dbt_schema_version\": \"https://schemas.getdbt.com/dbt/manifest/v7.json\",\n        \"dbt_version\": dbt.version.__version__,\n        \"nodes\": {\n            \"model.test.versioned_model.v1\": {\n                \"alias\": \"versioned_model_v1\",\n                \"compiled_path\": os.path.join(compiled_model_path, \"arbitrary_file_name.sql\"),\n                \"build_path\": None,\n                \"created_at\": ANY,\n                \"columns\": {\n                    \"first_name\": {\n                        \"description\": \"The first name being summarized\",\n                        \"name\": \"first_name\",\n                        \"dimension\": None,\n                        \"entity\": None,\n                        \"data_type\": None,\n                        \"meta\": {},\n                        \"quote\": None,\n                        \"tags\": [],\n                        \"constraints\": [],\n                        \"granularity\": None,\n                        \"doc_blocks\": [],\n                        \"config\": {\n                            \"meta\": {},\n                            \"tags\": [],\n                        },\n                    },\n                    \"ct\": {\n                        \"description\": \"The number of instances of the first name\",\n                        \"name\": \"ct\",\n                        \"dimension\": None,\n                        \"entity\": None,\n                        \"data_type\": None,\n                        \"meta\": {},\n                        \"quote\": None,\n                        \"tags\": [],\n                        \"constraints\": [],\n                        \"granularity\": None,\n                        \"doc_blocks\": [],\n                        \"config\": {\n                            \"meta\": {},\n                            \"tags\": [],\n                        },\n                    },\n                },\n                \"config\": get_rendered_model_config(\n                    materialized=\"table\",\n                    group=\"test_group\",\n                    meta={\"size\": \"large\", \"color\": \"blue\"},\n                ),\n                \"constraints\": [],\n                \"sources\": [],\n                \"functions\": [],\n                \"depends_on\": {\"macros\": [], \"nodes\": []},\n                \"description\": \"A versioned model\",\n                \"primary_key\": [\"count\", \"first_name\"],\n                \"deprecation_date\": ANY,\n                \"docs\": {\"node_color\": None, \"show\": True},\n                \"fqn\": [\"test\", \"versioned_model\", \"v1\"],\n                \"group\": \"test_group\",\n                \"metrics\": [],\n                \"name\": \"versioned_model\",\n                \"original_file_path\": versioned_model_v1_path,\n                \"package_name\": \"test\",\n                \"patch_path\": \"test://\" + os.path.join(\"models\", \"schema.yml\"),\n                \"path\": \"arbitrary_file_name.sql\",\n                \"raw_code\": LineIndifferent(versioned_model_v1_sql),\n                \"language\": \"sql\",\n                \"refs\": [],\n                \"relation_name\": '\"{0}\".\"{1}\".versioned_model_v1'.format(\n                    model_database, my_schema_name\n                ),\n                \"resource_type\": \"model\",\n                \"schema\": my_schema_name,\n                \"database\": project.database,\n                \"tags\": [],\n                \"meta\": {\"size\": \"large\", \"color\": \"blue\"},\n                \"unique_id\": \"model.test.versioned_model.v1\",\n                \"compiled\": True,\n                \"compiled_code\": ANY,\n                \"contract\": {\"checksum\": None, \"enforced\": False, \"alias_types\": True},\n                \"extra_ctes_injected\": True,\n                \"extra_ctes\": [],\n                \"checksum\": checksum_file(versioned_model_v1_path),\n                \"unrendered_config\": get_unrendered_model_config(\n                    materialized=\"table\",\n                    group=\"test_group\",\n                    meta={\"size\": \"large\", \"color\": \"blue\"},\n                ),\n                \"access\": \"protected\",\n                \"version\": 1,\n                \"latest_version\": 2,\n                \"time_spine\": None,\n                \"doc_blocks\": [],\n            },\n            \"model.test.versioned_model.v2\": {\n                \"alias\": \"versioned_model_v2\",\n                \"compiled_path\": os.path.join(compiled_model_path, \"versioned_model_v2.sql\"),\n                \"build_path\": None,\n                \"created_at\": ANY,\n                \"columns\": {\n                    \"first_name\": {\n                        \"description\": \"The first name being summarized\",\n                        \"name\": \"first_name\",\n                        \"dimension\": None,\n                        \"entity\": None,\n                        \"data_type\": None,\n                        \"meta\": {},\n                        \"quote\": None,\n                        \"tags\": [],\n                        \"constraints\": [],\n                        \"granularity\": None,\n                        \"doc_blocks\": [],\n                        \"config\": {\n                            \"meta\": {},\n                            \"tags\": [],\n                        },\n                    },\n                    \"extra\": {\n                        \"description\": \"\",\n                        \"name\": \"extra\",\n                        \"dimension\": None,\n                        \"entity\": None,\n                        \"data_type\": None,\n                        \"meta\": {},\n                        \"quote\": None,\n                        \"tags\": [],\n                        \"constraints\": [],\n                        \"granularity\": None,\n                        \"doc_blocks\": [],\n                        \"config\": {\n                            \"meta\": {},\n                            \"tags\": [],\n                        },\n                    },\n                },\n                \"config\": get_rendered_model_config(\n                    materialized=\"view\", group=\"test_group\", meta={\"size\": \"large\", \"color\": \"red\"}\n                ),\n                \"constraints\": [],\n                \"contract\": {\"checksum\": None, \"enforced\": False, \"alias_types\": True},\n                \"sources\": [],\n                \"functions\": [],\n                \"depends_on\": {\"macros\": [], \"nodes\": []},\n                \"description\": \"A versioned model\",\n                \"primary_key\": [\"first_name\"],\n                \"deprecation_date\": None,\n                \"docs\": {\"node_color\": None, \"show\": True},\n                \"fqn\": [\"test\", \"versioned_model\", \"v2\"],\n                \"group\": \"test_group\",\n                \"metrics\": [],\n                \"name\": \"versioned_model\",\n                \"original_file_path\": versioned_model_v2_path,\n                \"package_name\": \"test\",\n                \"patch_path\": \"test://\" + os.path.join(\"models\", \"schema.yml\"),\n                \"path\": \"versioned_model_v2.sql\",\n                \"raw_code\": LineIndifferent(versioned_model_v2_sql),\n                \"language\": \"sql\",\n                \"refs\": [],\n                \"relation_name\": '\"{0}\".\"{1}\".versioned_model_v2'.format(\n                    model_database, my_schema_name\n                ),\n                \"resource_type\": \"model\",\n                \"schema\": my_schema_name,\n                \"database\": project.database,\n                \"tags\": [],\n                \"meta\": {\"size\": \"large\", \"color\": \"red\"},\n                \"unique_id\": \"model.test.versioned_model.v2\",\n                \"compiled\": True,\n                \"compiled_code\": ANY,\n                \"extra_ctes_injected\": True,\n                \"extra_ctes\": [],\n                \"checksum\": checksum_file(versioned_model_v2_path),\n                \"unrendered_config\": get_unrendered_model_config(\n                    materialized=\"view\", group=\"test_group\", meta={\"size\": \"large\", \"color\": \"red\"}\n                ),\n                \"access\": \"protected\",\n                \"version\": 2,\n                \"latest_version\": 2,\n                \"time_spine\": None,\n                \"doc_blocks\": [],\n            },\n            \"model.test.ref_versioned_model\": {\n                \"alias\": \"ref_versioned_model\",\n                \"compiled_path\": os.path.join(compiled_model_path, \"ref_versioned_model.sql\"),\n                \"build_path\": None,\n                \"created_at\": ANY,\n                \"columns\": {},\n                \"config\": get_rendered_model_config(),\n                \"constraints\": [],\n                \"contract\": {\"checksum\": None, \"enforced\": False, \"alias_types\": True},\n                \"database\": project.database,\n                \"depends_on\": {\n                    \"macros\": [],\n                    \"nodes\": [\n                        \"model.test.versioned_model.v2\",\n                        \"model.test.versioned_model.v1\",\n                    ],\n                },\n                \"deprecation_date\": None,\n                \"description\": \"\",\n                \"primary_key\": [],\n                \"docs\": {\"node_color\": None, \"show\": True},\n                \"fqn\": [\"test\", \"ref_versioned_model\"],\n                \"group\": None,\n                \"metrics\": [],\n                \"name\": \"ref_versioned_model\",\n                \"original_file_path\": ref_versioned_model_path,\n                \"package_name\": \"test\",\n                \"patch_path\": \"test://\" + schema_yml_path,\n                \"path\": \"ref_versioned_model.sql\",\n                \"raw_code\": LineIndifferent(ref_versioned_model_sql),\n                \"language\": \"sql\",\n                \"refs\": [\n                    {\"name\": \"versioned_model\", \"package\": None, \"version\": 2},\n                    {\"name\": \"versioned_model\", \"package\": None, \"version\": \"2\"},\n                    {\"name\": \"versioned_model\", \"package\": None, \"version\": 2},\n                    {\"name\": \"versioned_model\", \"package\": None, \"version\": None},\n                    {\"name\": \"versioned_model\", \"package\": None, \"version\": 1},\n                ],\n                \"relation_name\": '\"{0}\".\"{1}\".ref_versioned_model'.format(\n                    model_database, my_schema_name\n                ),\n                \"resource_type\": \"model\",\n                \"schema\": my_schema_name,\n                \"sources\": [],\n                \"functions\": [],\n                \"tags\": [],\n                \"meta\": {},\n                \"unique_id\": \"model.test.ref_versioned_model\",\n                \"compiled\": True,\n                \"compiled_code\": ANY,\n                \"extra_ctes_injected\": True,\n                \"extra_ctes\": [],\n                \"checksum\": checksum_file(ref_versioned_model_path),\n                \"unrendered_config\": get_unrendered_model_config(),\n                \"access\": \"protected\",\n                \"version\": None,\n                \"latest_version\": None,\n                \"time_spine\": None,\n                \"doc_blocks\": [],\n            },\n            \"test.test.unique_versioned_model_v1_first_name.6138195dec\": {\n                \"alias\": \"unique_versioned_model_v1_first_name\",\n                \"attached_node\": \"model.test.versioned_model.v1\",\n                \"compiled_path\": os.path.join(\n                    compiled_model_path, \"schema.yml\", \"unique_versioned_model_v1_first_name.sql\"\n                ),\n                \"build_path\": None,\n                \"created_at\": ANY,\n                \"column_name\": \"first_name\",\n                \"columns\": {},\n                \"config\": test_config,\n                \"group\": \"test_group\",\n                \"contract\": {\"checksum\": None, \"enforced\": False, \"alias_types\": True},\n                \"sources\": [],\n                \"functions\": [],\n                \"depends_on\": {\n                    \"macros\": [\"macro.dbt.test_unique\", \"macro.dbt.get_where_subquery\"],\n                    \"nodes\": [\"model.test.versioned_model.v1\"],\n                },\n                \"description\": \"\",\n                \"file_key_name\": \"models.versioned_model\",\n                \"fqn\": [\"test\", \"unique_versioned_model_v1_first_name\"],\n                \"metrics\": [],\n                \"name\": \"unique_versioned_model_v1_first_name\",\n                \"original_file_path\": model_schema_yml_path,\n                \"package_name\": \"test\",\n                \"patch_path\": None,\n                \"path\": \"unique_versioned_model_v1_first_name.sql\",\n                \"raw_code\": \"{{ test_unique(**_dbt_generic_test_kwargs) }}\",\n                \"language\": \"sql\",\n                \"refs\": [{\"name\": \"versioned_model\", \"package\": None, \"version\": 1}],\n                \"relation_name\": None,\n                \"resource_type\": \"test\",\n                \"schema\": test_audit_schema,\n                \"database\": project.database,\n                \"tags\": [],\n                \"meta\": {},\n                \"unique_id\": \"test.test.unique_versioned_model_v1_first_name.6138195dec\",\n                \"docs\": {\"node_color\": None, \"show\": True},\n                \"compiled\": True,\n                \"compiled_code\": AnyStringWith(\"count(*)\"),\n                \"extra_ctes_injected\": True,\n                \"extra_ctes\": [],\n                \"test_metadata\": {\n                    \"namespace\": None,\n                    \"name\": \"unique\",\n                    \"kwargs\": {\n                        \"column_name\": \"first_name\",\n                        \"model\": \"{{ get_where_subquery(ref('versioned_model', version='1')) }}\",\n                    },\n                },\n                \"checksum\": {\"name\": \"none\", \"checksum\": \"\"},\n                \"unrendered_config\": unrendered_test_config,\n                \"doc_blocks\": [],\n            },\n            \"test.test.unique_versioned_model_v1_count.0b4c0b688a\": {\n                \"alias\": \"unique_versioned_model_v1_count\",\n                \"attached_node\": \"model.test.versioned_model.v1\",\n                \"compiled_path\": os.path.join(\n                    compiled_model_path, \"schema.yml\", \"unique_versioned_model_v1_count.sql\"\n                ),\n                \"build_path\": None,\n                \"created_at\": ANY,\n                \"column_name\": None,\n                \"columns\": {},\n                \"config\": test_config,\n                \"group\": \"test_group\",\n                \"contract\": {\"checksum\": None, \"enforced\": False, \"alias_types\": True},\n                \"sources\": [],\n                \"functions\": [],\n                \"depends_on\": {\n                    \"macros\": [\"macro.dbt.test_unique\", \"macro.dbt.get_where_subquery\"],\n                    \"nodes\": [\"model.test.versioned_model.v1\"],\n                },\n                \"description\": \"\",\n                \"file_key_name\": \"models.versioned_model\",\n                \"fqn\": [\"test\", \"unique_versioned_model_v1_count\"],\n                \"metrics\": [],\n                \"name\": \"unique_versioned_model_v1_count\",\n                \"original_file_path\": model_schema_yml_path,\n                \"package_name\": \"test\",\n                \"patch_path\": None,\n                \"path\": \"unique_versioned_model_v1_count.sql\",\n                \"raw_code\": \"{{ test_unique(**_dbt_generic_test_kwargs) }}\",\n                \"language\": \"sql\",\n                \"refs\": [{\"name\": \"versioned_model\", \"package\": None, \"version\": 1}],\n                \"relation_name\": None,\n                \"resource_type\": \"test\",\n                \"schema\": test_audit_schema,\n                \"database\": project.database,\n                \"tags\": [],\n                \"meta\": {},\n                \"unique_id\": \"test.test.unique_versioned_model_v1_count.0b4c0b688a\",\n                \"docs\": {\"node_color\": None, \"show\": True},\n                \"compiled\": True,\n                \"compiled_code\": AnyStringWith(\"count(*)\"),\n                \"extra_ctes_injected\": True,\n                \"extra_ctes\": [],\n                \"test_metadata\": {\n                    \"namespace\": None,\n                    \"name\": \"unique\",\n                    \"kwargs\": {\n                        \"column_name\": \"count\",\n                        \"model\": \"{{ get_where_subquery(ref('versioned_model', version='1')) }}\",\n                    },\n                },\n                \"checksum\": {\"name\": \"none\", \"checksum\": \"\"},\n                \"unrendered_config\": unrendered_test_config,\n                \"doc_blocks\": [],\n            },\n            \"test.test.unique_versioned_model_v2_first_name.998430d28e\": {\n                \"alias\": \"unique_versioned_model_v2_first_name\",\n                \"attached_node\": \"model.test.versioned_model.v2\",\n                \"compiled_path\": os.path.join(\n                    compiled_model_path, \"schema.yml\", \"unique_versioned_model_v2_first_name.sql\"\n                ),\n                \"build_path\": None,\n                \"created_at\": ANY,\n                \"column_name\": \"first_name\",\n                \"columns\": {},\n                \"config\": test_config,\n                \"group\": \"test_group\",\n                \"contract\": {\"checksum\": None, \"enforced\": False, \"alias_types\": True},\n                \"sources\": [],\n                \"functions\": [],\n                \"depends_on\": {\n                    \"macros\": [\"macro.dbt.test_unique\", \"macro.dbt.get_where_subquery\"],\n                    \"nodes\": [\"model.test.versioned_model.v2\"],\n                },\n                \"description\": \"\",\n                \"file_key_name\": \"models.versioned_model\",\n                \"fqn\": [\"test\", \"unique_versioned_model_v2_first_name\"],\n                \"metrics\": [],\n                \"name\": \"unique_versioned_model_v2_first_name\",\n                \"original_file_path\": model_schema_yml_path,\n                \"package_name\": \"test\",\n                \"patch_path\": None,\n                \"path\": \"unique_versioned_model_v2_first_name.sql\",\n                \"raw_code\": \"{{ test_unique(**_dbt_generic_test_kwargs) }}\",\n                \"language\": \"sql\",\n                \"refs\": [{\"name\": \"versioned_model\", \"package\": None, \"version\": 2}],\n                \"relation_name\": None,\n                \"resource_type\": \"test\",\n                \"schema\": test_audit_schema,\n                \"database\": project.database,\n                \"tags\": [],\n                \"meta\": {},\n                \"unique_id\": \"test.test.unique_versioned_model_v2_first_name.998430d28e\",\n                \"docs\": {\"node_color\": None, \"show\": True},\n                \"compiled\": True,\n                \"compiled_code\": AnyStringWith(\"count(*)\"),\n                \"extra_ctes_injected\": True,\n                \"extra_ctes\": [],\n                \"test_metadata\": {\n                    \"namespace\": None,\n                    \"name\": \"unique\",\n                    \"kwargs\": {\n                        \"column_name\": \"first_name\",\n                        \"model\": \"{{ get_where_subquery(ref('versioned_model', version='2')) }}\",\n                    },\n                },\n                \"checksum\": {\"name\": \"none\", \"checksum\": \"\"},\n                \"unrendered_config\": unrendered_test_config,\n                \"doc_blocks\": [],\n            },\n        },\n        \"exposures\": {\n            \"exposure.test.notebook_exposure\": {\n                \"created_at\": ANY,\n                \"depends_on\": {\n                    \"macros\": [],\n                    \"nodes\": [\"model.test.versioned_model.v2\"],\n                },\n                \"description\": \"notebook_info\",\n                \"label\": None,\n                \"config\": {\n                    \"enabled\": True,\n                    \"meta\": {},\n                    \"tags\": [],\n                },\n                \"fqn\": [\"test\", \"notebook_exposure\"],\n                \"maturity\": None,\n                \"meta\": {},\n                \"metrics\": [],\n                \"tags\": [],\n                \"name\": \"notebook_exposure\",\n                \"original_file_path\": os.path.join(\"models\", \"schema.yml\"),\n                \"owner\": {\"email\": \"something@example.com\", \"name\": \"Some name\"},\n                \"package_name\": \"test\",\n                \"path\": \"schema.yml\",\n                \"refs\": [{\"name\": \"versioned_model\", \"package\": None, \"version\": 2}],\n                \"resource_type\": \"exposure\",\n                \"sources\": [],\n                \"type\": \"notebook\",\n                \"unique_id\": \"exposure.test.notebook_exposure\",\n                \"url\": None,\n                \"unrendered_config\": {},\n            },\n        },\n        \"metrics\": {},\n        \"groups\": {\n            \"group.test.test_group\": {\n                \"name\": \"test_group\",\n                \"resource_type\": \"group\",\n                \"original_file_path\": os.path.join(\"models\", \"schema.yml\"),\n                \"owner\": {\"email\": \"test_group@test.com\", \"name\": None},\n                \"package_name\": \"test\",\n                \"path\": \"schema.yml\",\n                \"unique_id\": \"group.test.test_group\",\n                \"description\": None,\n                \"config\": {\"meta\": {}},\n            }\n        },\n        \"sources\": {},\n        \"functions\": {},\n        \"selectors\": {},\n        \"docs\": {},\n        \"child_map\": {\n            \"model.test.versioned_model.v1\": [\n                \"model.test.ref_versioned_model\",\n                \"test.test.unique_versioned_model_v1_count.0b4c0b688a\",\n                \"test.test.unique_versioned_model_v1_first_name.6138195dec\",\n            ],\n            \"model.test.versioned_model.v2\": [\n                \"exposure.test.notebook_exposure\",\n                \"model.test.ref_versioned_model\",\n                \"test.test.unique_versioned_model_v2_first_name.998430d28e\",\n            ],\n            \"model.test.ref_versioned_model\": [],\n            \"exposure.test.notebook_exposure\": [],\n            \"test.test.unique_versioned_model_v1_first_name.6138195dec\": [],\n            \"test.test.unique_versioned_model_v1_count.0b4c0b688a\": [],\n            \"test.test.unique_versioned_model_v2_first_name.998430d28e\": [],\n        },\n        \"parent_map\": {\n            \"model.test.versioned_model.v1\": [],\n            \"model.test.versioned_model.v2\": [],\n            \"model.test.ref_versioned_model\": [\n                \"model.test.versioned_model.v1\",\n                \"model.test.versioned_model.v2\",\n            ],\n            \"exposure.test.notebook_exposure\": [\"model.test.versioned_model.v2\"],\n            \"test.test.unique_versioned_model_v1_first_name.6138195dec\": [\n                \"model.test.versioned_model.v1\"\n            ],\n            \"test.test.unique_versioned_model_v1_count.0b4c0b688a\": [\n                \"model.test.versioned_model.v1\"\n            ],\n            \"test.test.unique_versioned_model_v2_first_name.998430d28e\": [\n                \"model.test.versioned_model.v2\"\n            ],\n        },\n        \"group_map\": {\n            \"test_group\": [\n                \"model.test.versioned_model.v1\",\n                \"model.test.versioned_model.v2\",\n                \"test.test.unique_versioned_model_v1_first_name.6138195dec\",\n                \"test.test.unique_versioned_model_v1_count.0b4c0b688a\",\n                \"test.test.unique_versioned_model_v2_first_name.998430d28e\",\n            ]\n        },\n        \"disabled\": {},\n        \"macros\": {},\n        \"semantic_models\": {},\n        \"unit_tests\": {},\n        \"saved_queries\": {},\n    }\n"
  },
  {
    "path": "tests/functional/artifacts/expected_run_results.py",
    "content": "from unittest.mock import ANY\n\nfrom dbt.tests.util import AnyFloat\n\n\ndef expected_run_results():\n    \"\"\"\n    The expected results of this run.\n    \"\"\"\n\n    return [\n        {\n            \"status\": \"success\",\n            \"message\": None,\n            \"execution_time\": AnyFloat(),\n            \"unique_id\": \"model.test.model\",\n            \"adapter_response\": ANY,\n            \"thread_id\": ANY,\n            \"timing\": [ANY, ANY],\n            \"failures\": ANY,\n            \"compiled\": True,\n            \"compiled_code\": ANY,\n            \"relation_name\": ANY,\n            \"batch_results\": None,\n        },\n        {\n            \"status\": \"success\",\n            \"message\": None,\n            \"execution_time\": AnyFloat(),\n            \"unique_id\": \"model.test.second_model\",\n            \"adapter_response\": ANY,\n            \"thread_id\": ANY,\n            \"timing\": [ANY, ANY],\n            \"failures\": ANY,\n            \"compiled\": True,\n            \"compiled_code\": ANY,\n            \"relation_name\": ANY,\n            \"batch_results\": None,\n        },\n        {\n            \"status\": \"success\",\n            \"message\": None,\n            \"execution_time\": AnyFloat(),\n            \"unique_id\": \"seed.test.seed\",\n            \"adapter_response\": ANY,\n            \"thread_id\": ANY,\n            \"timing\": [ANY, ANY],\n            \"failures\": ANY,\n            \"compiled\": None,\n            \"compiled_code\": ANY,\n            \"relation_name\": None,\n            \"batch_results\": None,\n        },\n        {\n            \"status\": \"success\",\n            \"message\": None,\n            \"execution_time\": AnyFloat(),\n            \"unique_id\": \"snapshot.test.snapshot_seed\",\n            \"adapter_response\": ANY,\n            \"thread_id\": ANY,\n            \"timing\": [ANY, ANY],\n            \"failures\": ANY,\n            \"compiled\": True,\n            \"compiled_code\": ANY,\n            \"relation_name\": ANY,\n            \"batch_results\": None,\n        },\n        {\n            \"status\": \"success\",\n            \"message\": None,\n            \"execution_time\": AnyFloat(),\n            \"unique_id\": \"test.test.not_null_model_id.d01cc630e6\",\n            \"adapter_response\": ANY,\n            \"thread_id\": ANY,\n            \"timing\": [ANY, ANY],\n            \"failures\": ANY,\n            \"compiled\": True,\n            \"compiled_code\": ANY,\n            \"relation_name\": None,\n            \"batch_results\": None,\n        },\n        {\n            \"status\": \"success\",\n            \"message\": None,\n            \"execution_time\": AnyFloat(),\n            \"unique_id\": \"test.test.test_nothing_model_.5d38568946\",\n            \"adapter_response\": ANY,\n            \"thread_id\": ANY,\n            \"timing\": [ANY, ANY],\n            \"failures\": ANY,\n            \"compiled\": True,\n            \"compiled_code\": ANY,\n            \"relation_name\": None,\n            \"batch_results\": None,\n        },\n        {\n            \"status\": \"success\",\n            \"message\": None,\n            \"execution_time\": AnyFloat(),\n            \"unique_id\": \"test.test.unique_model_id.67b76558ff\",\n            \"adapter_response\": ANY,\n            \"thread_id\": ANY,\n            \"timing\": [ANY, ANY],\n            \"failures\": ANY,\n            \"compiled\": True,\n            \"compiled_code\": ANY,\n            \"relation_name\": None,\n            \"batch_results\": None,\n        },\n    ]\n\n\ndef expected_references_run_results():\n    return [\n        {\n            \"status\": \"success\",\n            \"message\": None,\n            \"execution_time\": AnyFloat(),\n            \"unique_id\": \"model.test.ephemeral_summary\",\n            \"adapter_response\": ANY,\n            \"thread_id\": ANY,\n            \"timing\": [ANY, ANY],\n            \"failures\": ANY,\n            \"compiled\": True,\n            \"compiled_code\": ANY,\n            \"relation_name\": ANY,\n            \"batch_results\": None,\n        },\n        {\n            \"status\": \"success\",\n            \"message\": None,\n            \"execution_time\": AnyFloat(),\n            \"unique_id\": \"model.test.view_summary\",\n            \"adapter_response\": ANY,\n            \"thread_id\": ANY,\n            \"timing\": [ANY, ANY],\n            \"failures\": ANY,\n            \"compiled\": True,\n            \"compiled_code\": ANY,\n            \"relation_name\": ANY,\n            \"batch_results\": None,\n        },\n        {\n            \"status\": \"success\",\n            \"message\": None,\n            \"execution_time\": AnyFloat(),\n            \"unique_id\": \"seed.test.seed\",\n            \"adapter_response\": ANY,\n            \"thread_id\": ANY,\n            \"timing\": [ANY, ANY],\n            \"failures\": ANY,\n            \"compiled\": None,\n            \"compiled_code\": ANY,\n            \"relation_name\": ANY,\n            \"batch_results\": None,\n        },\n        {\n            \"status\": \"success\",\n            \"message\": None,\n            \"execution_time\": AnyFloat(),\n            \"unique_id\": \"snapshot.test.snapshot_seed\",\n            \"adapter_response\": ANY,\n            \"thread_id\": ANY,\n            \"timing\": [ANY, ANY],\n            \"failures\": ANY,\n            \"compiled\": True,\n            \"compiled_code\": ANY,\n            \"relation_name\": ANY,\n            \"batch_results\": None,\n        },\n    ]\n\n\ndef expected_versions_run_results():\n    return [\n        {\n            \"status\": \"success\",\n            \"message\": None,\n            \"execution_time\": AnyFloat(),\n            \"unique_id\": \"model.test.ref_versioned_model\",\n            \"adapter_response\": ANY,\n            \"thread_id\": ANY,\n            \"timing\": [ANY, ANY],\n            \"failures\": ANY,\n            \"compiled\": True,\n            \"compiled_code\": ANY,\n            \"relation_name\": ANY,\n            \"batch_results\": None,\n        },\n        {\n            \"status\": \"success\",\n            \"message\": None,\n            \"execution_time\": AnyFloat(),\n            \"unique_id\": \"model.test.versioned_model.v1\",\n            \"adapter_response\": ANY,\n            \"thread_id\": ANY,\n            \"timing\": [ANY, ANY],\n            \"failures\": ANY,\n            \"compiled\": True,\n            \"compiled_code\": ANY,\n            \"relation_name\": ANY,\n            \"batch_results\": None,\n        },\n        {\n            \"status\": \"success\",\n            \"message\": None,\n            \"execution_time\": AnyFloat(),\n            \"unique_id\": \"model.test.versioned_model.v2\",\n            \"adapter_response\": ANY,\n            \"thread_id\": ANY,\n            \"timing\": [ANY, ANY],\n            \"failures\": ANY,\n            \"compiled\": True,\n            \"compiled_code\": ANY,\n            \"relation_name\": ANY,\n            \"batch_results\": None,\n        },\n        {\n            \"status\": \"success\",\n            \"message\": None,\n            \"execution_time\": AnyFloat(),\n            \"unique_id\": \"test.test.unique_versioned_model_v1_count.0b4c0b688a\",\n            \"adapter_response\": ANY,\n            \"thread_id\": ANY,\n            \"timing\": [ANY, ANY],\n            \"failures\": ANY,\n            \"compiled\": True,\n            \"compiled_code\": ANY,\n            \"relation_name\": ANY,\n            \"batch_results\": None,\n        },\n        {\n            \"status\": \"success\",\n            \"message\": None,\n            \"execution_time\": AnyFloat(),\n            \"unique_id\": \"test.test.unique_versioned_model_v1_first_name.6138195dec\",\n            \"adapter_response\": ANY,\n            \"thread_id\": ANY,\n            \"timing\": [ANY, ANY],\n            \"failures\": ANY,\n            \"compiled\": True,\n            \"compiled_code\": ANY,\n            \"relation_name\": ANY,\n            \"batch_results\": None,\n        },\n        {\n            \"status\": \"success\",\n            \"message\": None,\n            \"execution_time\": AnyFloat(),\n            \"unique_id\": \"test.test.unique_versioned_model_v2_first_name.998430d28e\",\n            \"adapter_response\": ANY,\n            \"thread_id\": ANY,\n            \"timing\": [ANY, ANY],\n            \"failures\": ANY,\n            \"compiled\": True,\n            \"compiled_code\": ANY,\n            \"relation_name\": ANY,\n            \"batch_results\": None,\n        },\n    ]\n"
  },
  {
    "path": "tests/functional/artifacts/test_artifact_fields.py",
    "content": "import pytest\n\nfrom dbt.tests.util import get_artifact, get_manifest, run_dbt\n\n# This is a place to put specific tests for contents of artifacts that we\n# don't want to bother putting in the big artifact output test, which is\n# hard to update.\n\nmy_model_sql = \"select 1 as fun\"\n\nschema_yml = \"\"\"\nversion: 2\nmodels:\n  - name: my_model\n    columns:\n      - name: fun\n        data_tests:\n          - not_null\n\"\"\"\n\n\nclass TestRelationNameInTests:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": my_model_sql,\n            \"schema.yml\": schema_yml,\n        }\n\n    def test_relation_name_in_tests(self, project):\n        results = run_dbt([\"run\"])\n        assert len(results) == 1\n        manifest = get_manifest(project.project_root)\n        test_id = \"test.test.not_null_my_model_fun.bf3b032a01\"\n        assert test_id in manifest.nodes\n        assert manifest.nodes[test_id].relation_name is None\n\n        results = run_dbt([\"test\", \"--store-failures\"])\n        assert len(results) == 1\n        # The relation_name for tests with previously generated manifest and\n        # store_failures passed in on the command line, will be in the manifest.json\n        # but not in the parsed manifest.\n        manifest = get_manifest(project.project_root)\n        assert manifest.nodes[test_id].relation_name is None\n        manifest_json = get_artifact(project.project_root, \"target\", \"manifest.json\")\n        assert test_id in manifest_json[\"nodes\"]\n        relation_name = manifest_json[\"nodes\"][test_id][\"relation_name\"]\n        assert relation_name\n        assert '\"not_null_my_model_fun\"' in relation_name\n"
  },
  {
    "path": "tests/functional/artifacts/test_artifacts.py",
    "content": "import os\nfrom datetime import datetime, timezone\n\nimport jsonschema\nimport pytest\n\nimport dbt\nfrom dbt.artifacts.schemas.results import RunStatus\nfrom dbt.artifacts.schemas.run import RunResultsArtifact\nfrom dbt.contracts.graph.manifest import WritableManifest\nfrom dbt.events.types import ArtifactWritten\nfrom dbt.tests.util import (\n    check_datetime_between,\n    get_artifact,\n    run_dbt,\n    run_dbt_and_capture,\n)\nfrom dbt_common.events.event_catcher import EventCatcher\nfrom tests.functional.artifacts.expected_manifest import (\n    expected_references_manifest,\n    expected_seeded_manifest,\n    expected_versions_manifest,\n)\nfrom tests.functional.artifacts.expected_run_results import (\n    expected_references_run_results,\n    expected_run_results,\n    expected_versions_run_results,\n)\n\nmodels__schema_yml = \"\"\"\nversion: 2\n\nmodels:\n  - name: model\n    description: \"The test model\"\n    docs:\n      show: false\n    columns:\n      - name: id\n        description: The user ID number\n        data_tests:\n          - unique\n          - not_null\n      - name: first_name\n        description: The user's first name\n      - name: email\n        description: The user's email\n      - name: ip_address\n        description: The user's IP address\n      - name: updated_at\n        description: The last time this user's email was updated\n    data_tests:\n      - test.nothing\n\n  - name: second_model\n    description: \"The second test model\"\n    docs:\n      show: false\n    columns:\n      - name: id\n        description: The user ID number\n      - name: first_name\n        description: The user's first name\n      - name: email\n        description: The user's email\n      - name: ip_address\n        description: The user's IP address\n      - name: updated_at\n        description: The last time this user's email was updated\n\n\nsources:\n  - name: my_source\n    description: \"My source\"\n    loader: a_loader\n    schema: \"{{ var('test_schema') }}\"\n    tables:\n      - name: my_table\n        description: \"My table\"\n        identifier: seed\n        quoting:\n          identifier: True\n        columns:\n          - name: id\n            description: \"An ID field\"\n\n\nexposures:\n  - name: simple_exposure\n    type: dashboard\n    depends_on:\n      - ref('model')\n      - source('my_source', 'my_table')\n    owner:\n      email: something@example.com\n  - name: notebook_exposure\n    type: notebook\n    depends_on:\n      - ref('model')\n      - ref('second_model')\n    owner:\n      email: something@example.com\n      name: Some name\n    description: >\n      A description of the complex exposure\n    maturity: medium\n    meta:\n      tool: 'my_tool'\n      languages:\n        - python\n    tags: ['my_department']\n    url: http://example.com/notebook/1\n\"\"\"\n\nmodels__second_model_sql = \"\"\"\n{{\n    config(\n        materialized='view',\n        schema='test',\n    )\n}}\n\nselect * from {{ ref('seed') }}\n\"\"\"\n\nmodels__readme_md = \"\"\"\nThis is a readme.md file with {{ invalid-ish jinja }} in it\n\"\"\"\n\nmodels__model_sql = \"\"\"\n{{\n    config(\n        materialized='view',\n    )\n}}\n\nselect * from {{ ref('seed') }}\n\"\"\"\n\nmodels__model_with_pre_hook_sql = \"\"\"\n{{\n    config(\n        pre_hook={\n            \"sql\": \"{{ alter_timezone(timezone='Etc/UTC') }}\"\n        }\n    )\n}}\nselect current_setting('timezone') as timezone\n\"\"\"\n\nseed__schema_yml = \"\"\"\nversion: 2\nseeds:\n  - name: seed\n    description: \"The test seed\"\n    columns:\n      - name: id\n        description: The user ID number\n      - name: first_name\n        description: The user's first name\n      - name: email\n        description: The user's email\n      - name: ip_address\n        description: The user's IP address\n      - name: updated_at\n        description: The last time this user's email was updated\n\"\"\"\n\nseed__seed_csv = \"\"\"id,first_name,email,ip_address,updated_at\n1,Larry,lking0@miitbeian.gov.cn,69.135.206.194,2008-09-12 19:08:31\n\"\"\"\n\nmacros__schema_yml = \"\"\"\nversion: 2\nmacros:\n  - name: test_nothing\n    description: \"{{ doc('macro_info') }}\"\n    meta:\n      some_key: 100\n    arguments:\n      - name: model\n        type: Relation\n        description: \"{{ doc('macro_arg_info') }}\"\n\"\"\"\n\nmacros__macro_md = \"\"\"\n{% docs macro_info %}\nMy custom test that I wrote that does nothing\n{% enddocs %}\n\n{% docs macro_arg_info %}\nThe model for my custom test\n{% enddocs %}\n\"\"\"\n\nmacros__dummy_test_sql = \"\"\"\n{% test nothing(model) %}\n\n-- a silly test to make sure that table-level tests show up in the manifest\n-- without a column_name field\nselect 0\n\n{% endtest %}\n\"\"\"\n\nmacros__alter_timezone_sql = \"\"\"\n{% macro alter_timezone(timezone='America/Los_Angeles') %}\n{% set sql %}\n    SET TimeZone='{{ timezone }}';\n{% endset %}\n\n{% do run_query(sql) %}\n{% do log(\"Timezone set to: \" + timezone, info=True) %}\n{% endmacro %}\n\"\"\"\n\nsnapshot__snapshot_seed_sql = \"\"\"\n{% snapshot snapshot_seed %}\n{{\n    config(\n      unique_key='id',\n      strategy='check',\n      check_cols='all',\n      target_schema=var('alternate_schema')\n    )\n}}\nselect * from {{ ref('seed') }}\n{% endsnapshot %}\n\"\"\"\n\nref_models__schema_yml = \"\"\"\nversion: 2\n\ngroups:\n  - name: test_group\n    owner:\n      email: test_group@test.com\n\nmodels:\n  - name: ephemeral_summary\n    description: \"{{ doc('ephemeral_summary') }}\"\n    config:\n      group: test_group\n    columns: &summary_columns\n      - name: first_name\n        description: \"{{ doc('summary_first_name') }}\"\n      - name: ct\n        description: \"{{ doc('summary_count') }}\"\n  - name: view_summary\n    description: \"{{ doc('view_summary') }}\"\n    columns: *summary_columns\n\nsources:\n  - name: my_source\n    description: \"{{ doc('source_info') }}\"\n    loader: a_loader\n    schema: \"{{ var('test_schema') }}\"\n    quoting:\n      database: False\n      identifier: False\n    tables:\n      - name: my_table\n        description: \"{{ doc('table_info') }}\"\n        identifier: seed\n        quoting:\n          identifier: True\n        columns:\n          - name: id\n            description: \"{{ doc('column_info') }}\"\n\nexposures:\n  - name: notebook_exposure\n    type: notebook\n    depends_on:\n      - ref('view_summary')\n    owner:\n      email: something@example.com\n      name: Some name\n    description: \"{{ doc('notebook_info') }}\"\n    maturity: medium\n    url: http://example.com/notebook/1\n    meta:\n      tool: 'my_tool'\n      languages:\n        - python\n    tags: ['my_department']\n\n\"\"\"\n\nref_models__view_summary_sql = \"\"\"\n{{\n  config(\n    materialized = \"view\"\n  )\n}}\n\nselect first_name, ct from {{ref('ephemeral_summary')}}\norder by ct asc\n\n\"\"\"\n\nref_models__ephemeral_summary_sql = \"\"\"\n{{\n  config(\n    materialized = \"table\"\n  )\n}}\n\nselect first_name, count(*) as ct from {{ref('ephemeral_copy')}}\ngroup by first_name\norder by first_name asc\n\n\"\"\"\n\nref_models__ephemeral_copy_sql = \"\"\"\n{{\n  config(\n    materialized = \"ephemeral\"\n  )\n}}\n\nselect * from {{ source(\"my_source\", \"my_table\") }}\n\n\"\"\"\n\nref_models__docs_md = \"\"\"\n{% docs ephemeral_summary %}\nA summmary table of the ephemeral copy of the seed data\n{% enddocs %}\n\n{% docs summary_first_name %}\nThe first name being summarized\n{% enddocs %}\n\n{% docs summary_count %}\nThe number of instances of the first name\n{% enddocs %}\n\n{% docs view_summary %}\nA view of the summary of the ephemeral copy of the seed data\n{% enddocs %}\n\n{% docs source_info %}\nMy source\n{% enddocs %}\n\n{% docs table_info %}\nMy table\n{% enddocs %}\n\n{% docs column_info %}\nAn ID field\n{% enddocs %}\n\n{% docs notebook_info %}\nA description of the complex exposure\n{% enddocs %}\n\n\"\"\"\n\nversioned_models__schema_yml = \"\"\"\nversion: 2\n\ngroups:\n  - name: test_group\n    owner:\n      email: test_group@test.com\n\nmodels:\n  - name: versioned_model\n    description: \"A versioned model\"\n    latest_version: 2\n    config:\n      group: test_group\n      materialized: table\n      meta:\n        color: blue\n        size: large\n    data_tests:\n      - unique:\n          column_name: count\n    columns:\n      - name: first_name\n        description: \"The first name being summarized\"\n        data_tests:\n          - unique\n      - name: ct\n        description: \"The number of instances of the first name\"\n    versions:\n      - v: 1\n        defined_in: arbitrary_file_name\n        deprecation_date: 2022-07-11\n      - v: 2\n        config:\n          materialized: view\n          meta:\n            color: red\n        data_tests: []\n        columns:\n          - include: '*'\n            exclude: ['ct']\n          - name: extra\n  - name: ref_versioned_model\n\nexposures:\n  - name: notebook_exposure\n    type: notebook\n    depends_on:\n      - ref('versioned_model', v=2)\n    owner:\n      email: something@example.com\n      name: Some name\n    description: \"notebook_info\"\n\"\"\"\n\nversioned_models__v1_sql = \"\"\"\nselect \"test first name\" as first_name, 1 as ct\n\"\"\"\n\nversioned_models__v2_sql = \"\"\"\nselect \"test first name\" as first_name, 1 as extra\n\"\"\"\n\nversioned_models___ref_sql = \"\"\"\nselect first_name from {{ ref(\"versioned_model\", version=2) }}\nUNION ALL\nselect first_name from {{ ref(\"versioned_model\", version=\"2\") }}\nUNION ALL\nselect first_name from {{ ref(\"versioned_model\", v=2) }}\nUNION ALL\nselect first_name from {{ ref(\"versioned_model\") }}\nUNION ALL\nselect first_name from {{ ref(\"versioned_model\", version=1) }}\n\"\"\"\n\n\ndef verify_metadata(metadata, dbt_schema_version, start_time):\n    assert \"generated_at\" in metadata\n    check_datetime_between(metadata[\"generated_at\"], start=start_time)\n    assert \"dbt_version\" in metadata\n    assert metadata[\"dbt_version\"] == dbt.version.__version__\n    assert \"dbt_schema_version\" in metadata\n    assert metadata[\"dbt_schema_version\"] == dbt_schema_version\n    key = \"env_key\"\n    if os.name == \"nt\":\n        key = key.upper()\n    assert metadata[\"env\"] == {key: \"env_value\"}\n\n\ndef verify_manifest(project, expected_manifest, start_time, manifest_schema_path):\n    manifest_path = os.path.join(project.project_root, \"target\", \"manifest.json\")\n    assert os.path.exists(manifest_path)\n    manifest = get_artifact(manifest_path)\n    # Verify that manifest jsonschema from WritableManifest works\n    manifest_schema = WritableManifest.json_schema()\n    validate(manifest_schema, manifest)\n\n    # Verify that stored manifest jsonschema works.\n    # If this fails, schemas need to be updated with:\n    #   scripts/collect-artifact-schema.py --path schemas --artifact manifest\n    stored_manifest_schema = get_artifact(manifest_schema_path)\n    validate(stored_manifest_schema, manifest)\n\n    manifest_keys = {\n        \"nodes\",\n        \"sources\",\n        \"macros\",\n        \"parent_map\",\n        \"child_map\",\n        \"group_map\",\n        \"metrics\",\n        \"groups\",\n        \"docs\",\n        \"metadata\",\n        \"docs\",\n        \"disabled\",\n        \"exposures\",\n        \"functions\",\n        \"selectors\",\n        \"semantic_models\",\n        \"unit_tests\",\n        \"saved_queries\",\n    }\n\n    assert set(manifest.keys()) == manifest_keys\n\n    for key in manifest_keys:\n        if key == \"macros\":\n            verify_manifest_macros(manifest, expected_manifest.get(\"macros\"))\n        elif key == \"metadata\":\n            metadata = manifest[\"metadata\"]\n            dbt_schema_version = str(WritableManifest.dbt_schema_version)\n            verify_metadata(metadata, dbt_schema_version, start_time)\n            assert (\n                \"project_id\" in metadata\n                and metadata[\"project_id\"] == \"098f6bcd4621d373cade4e832627b4f6\"\n            )\n            assert \"project_name\" in metadata and metadata[\"project_name\"] == \"test\"\n            assert (\n                \"send_anonymous_usage_stats\" in metadata\n                and metadata[\"send_anonymous_usage_stats\"] is False\n            )\n            assert \"adapter_type\" in metadata and metadata[\"adapter_type\"] == project.adapter_type\n        elif key in [\"nodes\", \"sources\", \"exposures\", \"metrics\", \"disabled\", \"docs\"]:\n            for unique_id, node in expected_manifest[key].items():\n                assert unique_id in manifest[key]\n                assert manifest[key][unique_id] == node, f\"{unique_id} did not match\"\n        else:  # ['docs', 'parent_map', 'child_map', 'group_map', 'selectors', 'semantic_models', 'saved_queries']\n            assert manifest[key] == expected_manifest[key]\n\n\ndef verify_manifest_macros(manifest, expected=None):\n    assert \"macros\" in manifest\n    if expected:\n        for unique_id, expected_macro in expected.items():\n            assert unique_id in manifest[\"macros\"]\n            actual_macro = manifest[\"macros\"][unique_id]\n            assert expected_macro == actual_macro\n\n\ndef verify_run_results(project, expected_run_results, start_time, run_results_schema_path):\n    run_results_path = os.path.join(project.project_root, \"target\", \"run_results.json\")\n    run_results = get_artifact(run_results_path)\n    assert \"metadata\" in run_results\n\n    # Verify that jsonschema for RunResultsArtifact works\n    run_results_schema = RunResultsArtifact.json_schema()\n    validate(run_results_schema, run_results)\n\n    # Verify that stored run_results jsonschema works.\n    # If this fails, schemas need to be updated with:\n    #   scripts/collect-artifact-schema.py --path schemas --artifact run-results\n    stored_run_results_schema = get_artifact(run_results_schema_path)\n    validate(stored_run_results_schema, run_results)\n\n    dbt_schema_version = str(RunResultsArtifact.dbt_schema_version)\n    verify_metadata(run_results[\"metadata\"], dbt_schema_version, start_time)\n    assert \"elapsed_time\" in run_results\n    assert run_results[\"elapsed_time\"] > 0\n    assert isinstance(run_results[\"elapsed_time\"], float)\n    assert \"args\" in run_results\n    # sort the results so we can make reasonable assertions\n    run_results[\"results\"].sort(key=lambda r: r[\"unique_id\"])\n    assert run_results[\"results\"] == expected_run_results\n    assert set(run_results) == {\"elapsed_time\", \"results\", \"metadata\", \"args\"}\n\n\nclass BaseVerifyProject:\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setup(self, project):\n        alternate_schema_name = project.test_schema + \"_test\"\n        project.create_test_schema(schema_name=alternate_schema_name)\n        os.environ[\"DBT_ENV_CUSTOM_ENV_env_key\"] = \"env_value\"\n        run_dbt([\"seed\"])\n        yield\n        del os.environ[\"DBT_ENV_CUSTOM_ENV_env_key\"]\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\"schema.yml\": seed__schema_yml, \"seed.csv\": seed__seed_csv}\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\n            \"schema.yml\": macros__schema_yml,\n            \"macro.md\": macros__macro_md,\n            \"dummy_test.sql\": macros__dummy_test_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def snapshots(self):\n        return {\"snapshot_seed.sql\": snapshot__snapshot_seed_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self, unique_schema):\n        alternate_schema = unique_schema + \"_test\"\n        return {\n            \"vars\": {\n                \"test_schema\": unique_schema,\n                \"alternate_schema\": alternate_schema,\n            },\n            \"seeds\": {\n                \"quote_columns\": True,\n            },\n            \"quoting\": {\"identifier\": False},\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def manifest_schema_path(self, request):\n        schema_version_paths = WritableManifest.dbt_schema_version.path.split(\"/\")\n        manifest_schema_path = os.path.join(\n            request.config.rootdir, \"schemas\", *schema_version_paths\n        )\n        return manifest_schema_path\n\n    @pytest.fixture(scope=\"class\")\n    def run_results_schema_path(self, request):\n        schema_version_paths = RunResultsArtifact.dbt_schema_version.path.split(\"/\")\n        run_results_schema_path = os.path.join(\n            request.config.rootdir, \"schemas\", *schema_version_paths\n        )\n        return run_results_schema_path\n\n\ndef validate(artifact_schema, artifact_dict):\n    validator = jsonschema.Draft7Validator(artifact_schema)\n    error = next(iter(validator.iter_errors(artifact_dict)), None)\n    assert error is None\n\n\nclass TestVerifyArtifacts(BaseVerifyProject):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": models__schema_yml,\n            \"second_model.sql\": models__second_model_sql,\n            \"readme.md\": models__readme_md,\n            \"model.sql\": models__model_sql,\n        }\n\n    # Test generic \"docs generate\" command\n    def test_run_and_generate(self, project, manifest_schema_path, run_results_schema_path):\n        catcher = EventCatcher(ArtifactWritten)\n        start_time = datetime.now(timezone.utc).replace(tzinfo=None)\n        results = run_dbt(args=[\"compile\"], callbacks=[catcher.catch])\n        assert len(results) == 7\n        verify_manifest(\n            project,\n            expected_seeded_manifest(project, quote_model=False),\n            start_time,\n            manifest_schema_path,\n        )\n        verify_run_results(project, expected_run_results(), start_time, run_results_schema_path)\n        # manifest written twice, semantic manifest written twice, run results written once\n        assert len(catcher.caught_events) == 5\n        assert (\n            len(\n                [\n                    event\n                    for event in catcher.caught_events\n                    if event.data.artifact_type == \"WritableManifest\"\n                ]\n            )\n            > 0\n        )\n        assert (\n            len(\n                [\n                    event\n                    for event in catcher.caught_events\n                    if event.data.artifact_type == \"SemanticManifest\"\n                ]\n            )\n            > 0\n        )\n        assert (\n            len(\n                [\n                    event\n                    for event in catcher.caught_events\n                    if event.data.artifact_type == \"RunExecutionResult\"\n                ]\n            )\n            > 0\n        )\n\n    # Test artifact with additional fields load fine\n    def test_load_artifact(self, project, manifest_schema_path, run_results_schema_path):\n        catcher = EventCatcher(ArtifactWritten)\n        results = run_dbt(args=[\"compile\"], callbacks=[catcher.catch])\n        assert len(results) == 7\n        manifest_dct = get_artifact(os.path.join(project.project_root, \"target\", \"manifest.json\"))\n        # add a field that is not in the schema\n        for _, node in manifest_dct[\"nodes\"].items():\n            node[\"something_else\"] = \"something_else\"\n        # load the manifest with the additional field\n        loaded_manifest = WritableManifest.from_dict(manifest_dct)\n\n        # successfully loaded the manifest with the additional field, but the field should not be present\n        for _, node in loaded_manifest.nodes.items():\n            assert not hasattr(node, \"something_else\")\n\n\nclass TestVerifyArtifactsReferences(BaseVerifyProject):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": ref_models__schema_yml,\n            \"view_summary.sql\": ref_models__view_summary_sql,\n            \"ephemeral_summary.sql\": ref_models__ephemeral_summary_sql,\n            \"ephemeral_copy.sql\": ref_models__ephemeral_copy_sql,\n            \"docs.md\": ref_models__docs_md,\n        }\n\n    def test_references(self, project, manifest_schema_path, run_results_schema_path):\n        start_time = datetime.now(timezone.utc).replace(tzinfo=None)\n        results = run_dbt([\"compile\"])\n        assert len(results) == 4\n        verify_manifest(\n            project, expected_references_manifest(project), start_time, manifest_schema_path\n        )\n        verify_run_results(\n            project, expected_references_run_results(), start_time, run_results_schema_path\n        )\n\n\nclass TestVerifyArtifactsVersions(BaseVerifyProject):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": versioned_models__schema_yml,\n            \"versioned_model_v2.sql\": versioned_models__v2_sql,\n            \"arbitrary_file_name.sql\": versioned_models__v1_sql,\n            \"ref_versioned_model.sql\": versioned_models___ref_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {}\n\n    @pytest.fixture(scope=\"class\")\n    def snapshots(self):\n        return {}\n\n    def test_versions(self, project, manifest_schema_path, run_results_schema_path):\n        start_time = datetime.now(timezone.utc).replace(tzinfo=None)\n        results = run_dbt([\"compile\"])\n        assert len(results) == 6\n        verify_manifest(\n            project, expected_versions_manifest(project), start_time, manifest_schema_path\n        )\n        verify_run_results(\n            project, expected_versions_run_results(), start_time, run_results_schema_path\n        )\n\n\nclass TestVerifyRunOperation(BaseVerifyProject):\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"alter_timezone.sql\": macros__alter_timezone_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_with_pre_hook.sql\": models__model_with_pre_hook_sql,\n        }\n\n    def test_run_operation(self, project):\n        results, log_output = run_dbt_and_capture([\"run-operation\", \"alter_timezone\"])\n        assert len(results) == 1\n        assert results[0].status == RunStatus.Success\n        assert results[0].unique_id == \"macro.test.alter_timezone\"\n        assert \"Timezone set to: America/Los_Angeles\" in log_output\n\n    def test_run_model_with_operation(self, project):\n        # pre-hooks are not included in run_results since they are an attribute of the node and not a node in their\n        # own right\n        results, log_output = run_dbt_and_capture([\"run\", \"--select\", \"model_with_pre_hook\"])\n        assert len(results) == 1\n        assert results[0].status == RunStatus.Success\n        assert \"Timezone set to: Etc/UTC\" in log_output\n"
  },
  {
    "path": "tests/functional/artifacts/test_docs_generate_defer.py",
    "content": "import os\nimport shutil\n\nimport pytest\n\nfrom dbt.tests.util import run_dbt\n\nmodel_sql = \"\"\"\nselect 1 as id\n\"\"\"\n\n\nclass TestDocsGenerateDefer:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model.sql\": model_sql}\n\n    def copy_state(self):\n        assert not os.path.exists(\"state\")\n        os.makedirs(\"state\")\n        shutil.copyfile(\"target/manifest.json\", \"state/manifest.json\")\n\n    def test_generate_defer(\n        self,\n        project,\n    ):\n        results = run_dbt([\"run\"])\n        assert len(results) == 1\n\n        # copy state files\n        self.copy_state()\n\n        # defer test, it succeeds\n        catalog = run_dbt([\"docs\", \"generate\", \"--state\", \"./state\", \"--defer\"])\n        assert catalog.nodes[\"model.test.model\"]\n\n        # Check that catalog validates with jsonschema\n        catalog_dict = catalog.to_dict()\n        try:\n            catalog.validate(catalog_dict)\n        except Exception:\n            raise pytest.fail(\"Catalog validation failed\")\n"
  },
  {
    "path": "tests/functional/artifacts/test_override.py",
    "content": "import pytest\n\nfrom dbt.exceptions import CompilationError\nfrom dbt.tests.util import run_dbt\n\nmodel_sql = \"\"\"\nselect 1 as id\n\"\"\"\n\nfail_macros__failure_sql = \"\"\"\n{% macro get_catalog_relations(information_schema, relations) %}\n    {% do exceptions.raise_compiler_error('rejected: no catalogs for you') %}\n{% endmacro %}\n\n\"\"\"\n\n\nclass TestDocsGenerateOverride:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model.sql\": model_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"failure.sql\": fail_macros__failure_sql}\n\n    def test_override_used(\n        self,\n        project,\n    ):\n        results = run_dbt([\"run\"])\n        assert len(results) == 1\n        # this should pick up our failure macro and raise a compilation exception\n        with pytest.raises(CompilationError) as excinfo:\n            run_dbt([\"--warn-error\", \"docs\", \"generate\"])\n        assert \"rejected: no catalogs for you\" in str(excinfo.value)\n"
  },
  {
    "path": "tests/functional/artifacts/test_previous_version_state.py",
    "content": "import json\nimport os\nimport shutil\n\nimport pytest\n\nfrom dbt.artifacts.exceptions import IncompatibleSchemaError\nfrom dbt.artifacts.schemas.base import get_artifact_schema_version\nfrom dbt.artifacts.schemas.run import RunResultsArtifact\nfrom dbt.contracts.graph.manifest import WritableManifest\nfrom dbt.tests.util import get_manifest, run_dbt\n\n# This project must have one of each kind of node type, plus disabled versions, for\n# test coverage to be complete.\nmodels__my_model_sql = \"\"\"\nselect 1 as id\n\"\"\"\n\nmodels__disabled_model_sql = \"\"\"\n{{ config(enabled=False) }}\nselect 2 as id\n\"\"\"\n\nseeds__my_seed_csv = \"\"\"\nid,value\n4,2\n\"\"\"\n\nseeds__disabled_seed_csv = \"\"\"\nid,value\n6,4\n\"\"\"\n\ndocs__somedoc_md = \"\"\"\n{% docs somedoc %}\nTesting, testing\n{% enddocs %}\n\"\"\"\n\nmacros__do_nothing_sql = \"\"\"\n{% macro do_nothing(foo2, bar2) %}\n    select\n        '{{ foo2 }}' as foo2,\n        '{{ bar2 }}' as bar2\n{% endmacro %}\n\"\"\"\n\nmacros__dummy_test_sql = \"\"\"\n{% test check_nothing(model) %}\n-- a silly test to make sure that table-level tests show up in the manifest\n-- without a column_name field\n\nselect 0\n\n{% endtest %}\n\"\"\"\n\nmacros__disabled_dummy_test_sql = \"\"\"\n{% test disabled_check_nothing(model) %}\n-- a silly test to make sure that table-level tests show up in the manifest\n-- without a column_name field\n\n{{ config(enabled=False) }}\nselect 0\n\n{% endtest %}\n\"\"\"\n\nsnapshot__snapshot_seed_sql = \"\"\"\n{% snapshot snapshot_seed %}\n{{\n    config(\n      unique_key='id',\n      strategy='check',\n      check_cols='all',\n      target_schema=schema,\n    )\n}}\nselect * from {{ ref('my_seed') }}\n{% endsnapshot %}\n\"\"\"\n\nsnapshot__disabled_snapshot_seed_sql = \"\"\"\n{% snapshot disabled_snapshot_seed %}\n{{\n    config(\n      unique_key='id',\n      strategy='check',\n      check_cols='all',\n      target_schema=schema,\n      enabled=False,\n    )\n}}\nselect * from {{ ref('my_seed') }}\n{% endsnapshot %}\n\"\"\"\n\ntests__just_my_sql = \"\"\"\n{{ config(tags = ['data_test_tag']) }}\n\nselect * from {{ ref('my_model') }}\nwhere false\n\"\"\"\n\ntests__disabled_just_my_sql = \"\"\"\n{{ config(enabled=False) }}\n\nselect * from {{ ref('my_model') }}\nwhere false\n\"\"\"\n\nanalyses__a_sql = \"\"\"\nselect 4 as id\n\"\"\"\n\nanalyses__disabled_a_sql = \"\"\"\n{{ config(enabled=False) }}\nselect 9 as id\n\"\"\"\n\nmetricflow_time_spine_sql = \"\"\"\nSELECT to_date('02/20/2023', 'mm/dd/yyyy') as date_day\n\"\"\"\n\n# Use old attribute names (v1.0-1.2) to test forward/backward compatibility with the rename in v1.3\nmodels__schema_yml = \"\"\"\nversion: 2\nmodels:\n  - name: my_model\n    description: \"Example model\"\n    data_tests:\n      - check_nothing\n      - disabled_check_nothing\n    columns:\n     - name: id\n       data_tests:\n       - not_null\n\nsemantic_models:\n  - name: semantic_people\n    model: ref('my_model')\n    dimensions:\n      - name: favorite_color\n        type: categorical\n      - name: created_at\n        type: TIME\n        type_params:\n          time_granularity: day\n    measures:\n      - name: years_tenure\n        agg: SUM\n        expr: tenure\n      - name: people\n        agg: count\n        expr: id\n      - name: customers\n        agg: count\n        expr: id\n    entities:\n      - name: id\n        type: primary\n    defaults:\n      agg_time_dimension: created_at\n\nmetrics:\n  - name: blue_customers_post_2010\n    label: Blue Customers since 2010\n    type: simple\n    filter: \"{{ TimeDimension('id__created_at', 'day') }} > '2010-01-01'\"\n    type_params:\n      measure:\n        name: customers\n        filter: \"{{ Dimension('id__favorite_color') }} = 'blue'\"\n  - name: customers\n    label: Customers Metric\n    type: simple\n    type_params:\n      measure: customers\n  - name: disabled_metric\n    label: Count records\n    config:\n        enabled: False\n    filter: \"{{ Dimension('id__favorite_color') }} = 'blue'\"\n    type: simple\n    type_params:\n      measure: customers\n  - name: ratio_of_blue_customers_to_red_customers\n    label: Very Important Customer Color Ratio\n    type: ratio\n    type_params:\n      numerator:\n        name: customers\n        filter: \"{{ Dimension('id__favorite_color')}} = 'blue'\"\n      denominator:\n        name: customers\n        filter: \"{{ Dimension('id__favorite_color')}} = 'red'\"\n  - name: doubled_blue_customers\n    type: derived\n    label: Inflated blue customer numbers\n    type_params:\n      expr: 'customers * 2'\n      metrics:\n        - name: customers\n          filter: \"{{ Dimension('id__favorite_color')}} = 'blue'\"\n\n\nsources:\n  - name: my_source\n    description: \"My source\"\n    loader: a_loader\n    tables:\n      - name: my_table\n        description: \"My table\"\n        identifier: my_seed\n      - name: disabled_table\n        description: \"Disabled table\"\n        config:\n           enabled: False\n\nexposures:\n  - name: simple_exposure\n    type: dashboard\n    depends_on:\n      - ref('my_model')\n      - source('my_source', 'my_table')\n    owner:\n      email: something@example.com\n  - name: disabled_exposure\n    type: dashboard\n    config:\n      enabled: False\n    depends_on:\n      - ref('my_model')\n    owner:\n      email: something@example.com\n\nseeds:\n  - name: disabled_seed\n    config:\n      enabled: False\n\"\"\"\n\n# SETUP: Using this project, we have run past minor versions of dbt\n# to generate each contracted version of `manifest.json`.\n\n# Whenever we bump the manifest version, we should add a new entry for that version\n# into `data`, generated from this same project, and update the CURRENT_EXPECTED_MANIFEST_VERSION.\n# You can generate the manifest using the generate_latest_manifest() method below.\n\n# TEST: Then, using the *current* version of dbt (this branch),\n# we will perform a `--state` comparison against those older manifests.\n\n# Some comparisons should succeed, where we expect backward/forward compatibility.\n\n# Comparisons against older versions should fail, because the structure of the\n# WritableManifest class has changed in ways that prevent successful deserialization\n# of older JSON manifests.\n\n\n# We are creating enabled versions of every node type that might be in the manifest,\n# plus disabled versions for types that support it (everything except macros and docs).\n\n\nclass TestPreviousVersionState:\n    CURRENT_EXPECTED_MANIFEST_VERSION = 12\n    CURRENT_EXPECTED_RUN_RESULTS_VERSION = 6\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": models__my_model_sql,\n            \"schema.yml\": models__schema_yml,\n            \"somedoc.md\": docs__somedoc_md,\n            \"disabled_model.sql\": models__disabled_model_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\n            \"my_seed.csv\": seeds__my_seed_csv,\n            \"disabled_seed.csv\": seeds__disabled_seed_csv,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def snapshots(self):\n        return {\n            \"snapshot_seed.sql\": snapshot__snapshot_seed_sql,\n            \"disabled_snapshot_seed.sql\": snapshot__disabled_snapshot_seed_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def tests(self):\n        return {\n            \"just_my.sql\": tests__just_my_sql,\n            \"disabled_just_my.sql\": tests__disabled_just_my_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\n            \"do_nothing.sql\": macros__do_nothing_sql,\n            \"dummy_test.sql\": macros__dummy_test_sql,\n            \"disabled_dummy_test.sql\": macros__disabled_dummy_test_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def analyses(self):\n        return {\n            \"a.sql\": analyses__a_sql,\n            \"disabled_al.sql\": analyses__disabled_a_sql,\n        }\n\n    def test_project(self, project):\n        # This is mainly used to test changes to the test project in isolation from\n        # the other noise.\n        results = run_dbt([\"run\"])\n        assert len(results) == 2\n        manifest = get_manifest(project.project_root)\n        # model, snapshot, seed, singular test, generic test, analysis\n        assert len(manifest.nodes) == 8\n        assert len(manifest.sources) == 1\n        assert len(manifest.exposures) == 1\n        assert len(manifest.metrics) == 4\n        # disabled model, snapshot, seed, singular test, generic test, analysis, source, exposure, metric\n        assert len(manifest.disabled) == 9\n        assert \"macro.test.do_nothing\" in manifest.macros\n\n    # Use this method when generating a new manifest version for the first time.\n    # Once generated, we shouldn't need to re-generate or modify the manifest.\n    def generate_latest_manifest(\n        self,\n        project,\n        current_manifest_version,\n    ):\n        run_dbt([\"parse\"])\n        source_path = os.path.join(project.project_root, \"target/manifest.json\")\n        state_path = os.path.join(project.test_data_dir, f\"state/v{current_manifest_version}\")\n        target_path = os.path.join(state_path, \"manifest.json\")\n        os.makedirs(state_path, exist_ok=True)\n        shutil.copyfile(source_path, target_path)\n\n    # Use this method when generating a new run_results version for the first time.\n    # Once generated, we shouldn't need to re-generate or modify the manifest.\n    def generate_latest_run_results(\n        self,\n        project,\n        current_run_results_version,\n    ):\n        run_dbt([\"run\"])\n        source_path = os.path.join(project.project_root, \"target/run_results.json\")\n        state_path = os.path.join(project.test_data_dir, f\"results/v{current_run_results_version}\")\n        target_path = os.path.join(state_path, \"run_results.json\")\n        os.makedirs(state_path, exist_ok=True)\n        shutil.copyfile(source_path, target_path)\n\n    # The actual test method. Run `dbt list --select state:modified --state ...`\n    # once for each past manifest version. They all have the same content, but different\n    # schema/structure, only some of which are forward-compatible with the\n    # current WritableManifest class.\n    def compare_previous_state(\n        self,\n        project,\n        compare_manifest_version,\n        expect_pass,\n        num_results,\n    ):\n        state_path = os.path.join(project.test_data_dir, f\"state/v{compare_manifest_version}\")\n        cli_args = [\n            \"list\",\n            \"--resource-types\",\n            \"model\",\n            \"--select\",\n            \"state:modified\",\n            \"--state\",\n            state_path,\n        ]\n        if expect_pass:\n            results = run_dbt(cli_args, expect_pass=expect_pass)\n            assert len(results) == num_results\n        else:\n            with pytest.raises(IncompatibleSchemaError):\n                run_dbt(cli_args, expect_pass=expect_pass)\n\n    # The actual test method. Run `dbt retry --state ...`\n    # once for each past run_results version. They all have the same content, but different\n    # schema/structure, only some of which are forward-compatible with the\n    # current WritableManifest class.\n    def compare_previous_results(\n        self,\n        project,\n        compare_run_results_version,\n        expect_pass,\n        num_results,\n    ):\n        state_path = os.path.join(project.test_data_dir, f\"results/v{compare_run_results_version}\")\n        cli_args = [\n            \"retry\",\n            \"--state\",\n            state_path,\n        ]\n        if expect_pass:\n            results = run_dbt(cli_args, expect_pass=expect_pass)\n            assert len(results) == num_results\n        else:\n            with pytest.raises(IncompatibleSchemaError):\n                run_dbt(cli_args, expect_pass=expect_pass)\n\n    def test_compare_state_current(self, project):\n        current_manifest_schema_version = WritableManifest.dbt_schema_version.version\n        assert (\n            current_manifest_schema_version == self.CURRENT_EXPECTED_MANIFEST_VERSION\n        ), \"Sounds like you've bumped the manifest version and need to update this test!\"\n        # If we need a newly generated manifest, uncomment the following line and commit the result\n        # self.generate_latest_manifest(project, current_manifest_schema_version)\n        self.compare_previous_state(project, current_manifest_schema_version, True, 0)\n\n    def test_backwards_compatible_versions(self, project):\n        # manifest schema version 4 and greater should always be forward compatible\n        for schema_version in range(4, 10):\n            self.compare_previous_state(project, schema_version, True, 1)\n        for schema_version in range(10, self.CURRENT_EXPECTED_MANIFEST_VERSION):\n            self.compare_previous_state(project, schema_version, True, 0)\n\n    def test_nonbackwards_compatible_versions(self, project):\n        # schema versions 1, 2, 3 are all not forward compatible\n        for schema_version in range(1, 4):\n            self.compare_previous_state(project, schema_version, False, 0)\n\n    def test_get_manifest_schema_version(self, project):\n        for schema_version in range(1, self.CURRENT_EXPECTED_MANIFEST_VERSION):\n            manifest_path = os.path.join(\n                project.test_data_dir, f\"state/v{schema_version}/manifest.json\"\n            )\n            manifest = json.load(open(manifest_path))\n\n            manifest_version = get_artifact_schema_version(manifest)\n            assert manifest_version == schema_version\n\n    def test_compare_results_current(self, project):\n        current_run_results_schema_version = RunResultsArtifact.dbt_schema_version.version\n        assert (\n            current_run_results_schema_version == self.CURRENT_EXPECTED_RUN_RESULTS_VERSION\n        ), \"Sounds like you've bumped the run_results version and need to update this test!\"\n        # If we need a newly generated run_results, uncomment the following line and commit the result\n        # self.generate_latest_run_results(project, current_run_results_schema_version)\n        self.compare_previous_results(project, current_run_results_schema_version, True, 0)\n\n    def test_backwards_compatible_run_results_versions(self, project):\n        # run_results schema version 4 and greater should always be forward compatible\n        for schema_version in range(4, self.CURRENT_EXPECTED_RUN_RESULTS_VERSION):\n            self.compare_previous_results(project, schema_version, True, 0)\n"
  },
  {
    "path": "tests/functional/artifacts/test_run_execution_result.py",
    "content": "import pytest\nfrom dateutil.tz import tzutc\n\nfrom dbt.contracts.results import RunExecutionResult\nfrom dbt.tests.util import run_dbt, write_file\n\nsample_model_sql = \"\"\"\nselect 1 as id\n\"\"\"\n\n\n@pytest.fixture(scope=\"function\", autouse=True)\ndef sample_model(project):\n    write_file(\n        sample_model_sql,\n        project.project_root,\n        \"models\",\n        \"model.sql\",\n    )\n\n\ndef test_run_execution_result_compiled_serialization(project):\n\n    result = run_dbt([\"compile\"])\n    result_from_dict = RunExecutionResult.from_dict(result.to_dict())\n\n    assert isinstance(result, RunExecutionResult)\n    assert len(result.results) > 0\n    assert result.results[0].status.name == \"Success\"\n\n    assert result_from_dict.args == result.args\n    assert len(result_from_dict.results) == len(result.results)\n\n    assert result.generated_at.tzinfo is None\n    assert result_from_dict.generated_at.tzinfo == tzutc()\n    assert result_from_dict.generated_at.replace(tzinfo=None) == result.generated_at\n\n    for original in result.results:\n        for deserialized in result_from_dict.results:\n            if original.node.unique_id == deserialized.node.unique_id:\n                assert original.node.created_at == deserialized.node.created_at\n"
  },
  {
    "path": "tests/functional/artifacts/test_run_results.py",
    "content": "import json\nfrom multiprocessing import Process\nfrom pathlib import Path\n\nimport pytest\n\nfrom dbt.tests.util import run_dbt\n\ngood_model_sql = \"\"\"\nselect 1 as id\n\"\"\"\n\nbad_model_sql = \"\"\"\nsomething bad\n\"\"\"\n\nslow_model_sql = \"\"\"\n{{ config(materialized='table') }}\nselect id from {{ ref('good_model') }}, pg_sleep(5)\n\"\"\"\n\n\nclass TestRunResultsTimingSuccess:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model.sql\": good_model_sql}\n\n    def test_timing_exists(self, project):\n        results = run_dbt([\"run\"])\n        assert len(results.results) == 1\n        assert len(results.results[0].timing) > 0\n\n\nclass TestRunResultsTimingFailure:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model.sql\": bad_model_sql}\n\n    def test_timing_exists(self, project):\n        results = run_dbt([\"run\"], expect_pass=False)\n        assert len(results.results) == 1\n        assert len(results.results[0].timing) > 0\n\n\nclass TestRunResultsSerializableInContext:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model.sql\": good_model_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"on-run-end\": [\"{% for result in results %}{{ log(result.to_dict()) }}{% endfor %}\"]\n        }\n\n    def test_results_serializable(self, project):\n        results = run_dbt([\"run\"])\n        assert len(results.results) == 2\n\n\n# This test is failing due to the faulty assumptions that run_results.json would\n# be written multiple times. Temporarily disabling.\n@pytest.mark.skip()\nclass TestRunResultsWritesFileOnSignal:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"good_model.sql\": good_model_sql, \"slow_model.sql\": slow_model_sql}\n\n    def test_run_results_are_written_on_signal(self, project):\n        # Start the runner in a seperate process.\n        external_process_dbt = Process(\n            target=run_dbt, args=([[\"run\"]]), kwargs={\"expect_pass\": False}\n        )\n        external_process_dbt.start()\n        assert external_process_dbt.is_alive()\n\n        # Wait until the first file write, then kill the process.\n        run_results_file = Path(project.project_root) / \"target/run_results.json\"\n        while run_results_file.is_file() is False:\n            pass\n        external_process_dbt.terminate()\n\n        # Wait until the process is dead, then check the file that there is only one result.\n        while external_process_dbt.is_alive() is True:\n            pass\n        with run_results_file.open() as run_results_str:\n            run_results = json.loads(run_results_str.read())\n            assert len(run_results[\"results\"]) == 1\n"
  },
  {
    "path": "tests/functional/assertions/test_runner.py",
    "content": "import os\nfrom typing import Callable, List, Optional\n\nfrom dbt.cli.main import dbtRunner, dbtRunnerResult\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.tests.util import get_run_results\nfrom dbt_common.events.base_types import EventMsg\n\n\ndef assert_run_results_have_compiled_node_attributes(\n    args: List[str], result: dbtRunnerResult\n) -> None:\n    commands_with_run_results = [\"build\", \"compile\", \"docs\", \"run\", \"test\"]\n    if not [a for a in args if a in commands_with_run_results] or not result.success:\n        return\n\n    run_results = get_run_results(os.getcwd())\n    for r in run_results[\"results\"]:\n        if r[\"unique_id\"].startswith(\"model\") and r[\"status\"] == \"success\":\n            assert \"compiled_code\" in r\n            assert \"compiled\" in r\n\n\n_STANDARD_ASSERTIONS = [assert_run_results_have_compiled_node_attributes]\n\n\nclass dbtTestRunner(dbtRunner):\n    def __init__(\n        self,\n        manifest: Optional[Manifest] = None,\n        callbacks: Optional[List[Callable[[EventMsg], None]]] = None,\n        exit_assertions: Optional[List[Callable[[List[str], dbtRunnerResult], None]]] = None,\n    ):\n        self.exit_assertions = exit_assertions if exit_assertions else _STANDARD_ASSERTIONS\n        super().__init__(manifest, callbacks)\n\n    def invoke(self, args: List[str], **kwargs) -> dbtRunnerResult:\n        result = super().invoke(args, **kwargs)\n\n        for assertion in self.exit_assertions:\n            assertion(args, result)\n\n        return result\n"
  },
  {
    "path": "tests/functional/basic/data/seed-initial.csv",
    "content": "id,first_name,last_name,email,gender,ip_address\n1,Jack,Hunter,jhunter0@pbs.org,Male,59.80.20.168\n2,Kathryn,Walker,kwalker1@ezinearticles.com,Female,194.121.179.35\n3,Gerald,Ryan,gryan2@com.com,Male,11.3.212.243\n4,Bonnie,Spencer,bspencer3@ameblo.jp,Female,216.32.196.175\n5,Harold,Taylor,htaylor4@people.com.cn,Male,253.10.246.136\n6,Jacqueline,Griffin,jgriffin5@t.co,Female,16.13.192.220\n7,Wanda,Arnold,warnold6@google.nl,Female,232.116.150.64\n8,Craig,Ortiz,cortiz7@sciencedaily.com,Male,199.126.106.13\n9,Gary,Day,gday8@nih.gov,Male,35.81.68.186\n10,Rose,Wright,rwright9@yahoo.co.jp,Female,236.82.178.100\n11,Raymond,Kelley,rkelleya@fc2.com,Male,213.65.166.67\n12,Gerald,Robinson,grobinsonb@disqus.com,Male,72.232.194.193\n13,Mildred,Martinez,mmartinezc@samsung.com,Female,198.29.112.5\n14,Dennis,Arnold,darnoldd@google.com,Male,86.96.3.250\n15,Judy,Gray,jgraye@opensource.org,Female,79.218.162.245\n16,Theresa,Garza,tgarzaf@epa.gov,Female,21.59.100.54\n17,Gerald,Robertson,grobertsong@csmonitor.com,Male,131.134.82.96\n18,Philip,Hernandez,phernandezh@adobe.com,Male,254.196.137.72\n19,Julia,Gonzalez,jgonzalezi@cam.ac.uk,Female,84.240.227.174\n20,Andrew,Davis,adavisj@patch.com,Male,9.255.67.25\n21,Kimberly,Harper,kharperk@foxnews.com,Female,198.208.120.253\n22,Mark,Martin,mmartinl@marketwatch.com,Male,233.138.182.153\n23,Cynthia,Ruiz,cruizm@google.fr,Female,18.178.187.201\n24,Samuel,Carroll,scarrolln@youtu.be,Male,128.113.96.122\n25,Jennifer,Larson,jlarsono@vinaora.com,Female,98.234.85.95\n26,Ashley,Perry,aperryp@rakuten.co.jp,Female,247.173.114.52\n27,Howard,Rodriguez,hrodriguezq@shutterfly.com,Male,231.188.95.26\n28,Amy,Brooks,abrooksr@theatlantic.com,Female,141.199.174.118\n29,Louise,Warren,lwarrens@adobe.com,Female,96.105.158.28\n30,Tina,Watson,twatsont@myspace.com,Female,251.142.118.177\n31,Janice,Kelley,jkelleyu@creativecommons.org,Female,239.167.34.233\n32,Terry,Mccoy,tmccoyv@bravesites.com,Male,117.201.183.203\n33,Jeffrey,Morgan,jmorganw@surveymonkey.com,Male,78.101.78.149\n34,Louis,Harvey,lharveyx@sina.com.cn,Male,51.50.0.167\n35,Philip,Miller,pmillery@samsung.com,Male,103.255.222.110\n36,Willie,Marshall,wmarshallz@ow.ly,Male,149.219.91.68\n37,Patrick,Lopez,plopez10@redcross.org,Male,250.136.229.89\n38,Adam,Jenkins,ajenkins11@harvard.edu,Male,7.36.112.81\n39,Benjamin,Cruz,bcruz12@linkedin.com,Male,32.38.98.15\n40,Ruby,Hawkins,rhawkins13@gmpg.org,Female,135.171.129.255\n41,Carlos,Barnes,cbarnes14@a8.net,Male,240.197.85.140\n42,Ruby,Griffin,rgriffin15@bravesites.com,Female,19.29.135.24\n43,Sean,Mason,smason16@icq.com,Male,159.219.155.249\n44,Anthony,Payne,apayne17@utexas.edu,Male,235.168.199.218\n45,Steve,Cruz,scruz18@pcworld.com,Male,238.201.81.198\n46,Anthony,Garcia,agarcia19@flavors.me,Male,25.85.10.18\n47,Doris,Lopez,dlopez1a@sphinn.com,Female,245.218.51.238\n48,Susan,Nichols,snichols1b@freewebs.com,Female,199.99.9.61\n49,Wanda,Ferguson,wferguson1c@yahoo.co.jp,Female,236.241.135.21\n50,Andrea,Pierce,apierce1d@google.co.uk,Female,132.40.10.209\n51,Lawrence,Phillips,lphillips1e@jugem.jp,Male,72.226.82.87\n52,Judy,Gilbert,jgilbert1f@multiply.com,Female,196.250.15.142\n53,Eric,Williams,ewilliams1g@joomla.org,Male,222.202.73.126\n54,Ralph,Romero,rromero1h@sogou.com,Male,123.184.125.212\n55,Jean,Wilson,jwilson1i@ocn.ne.jp,Female,176.106.32.194\n56,Lori,Reynolds,lreynolds1j@illinois.edu,Female,114.181.203.22\n57,Donald,Moreno,dmoreno1k@bbc.co.uk,Male,233.249.97.60\n58,Steven,Berry,sberry1l@eepurl.com,Male,186.193.50.50\n59,Theresa,Shaw,tshaw1m@people.com.cn,Female,120.37.71.222\n60,John,Stephens,jstephens1n@nationalgeographic.com,Male,191.87.127.115\n61,Richard,Jacobs,rjacobs1o@state.tx.us,Male,66.210.83.155\n62,Andrew,Lawson,alawson1p@over-blog.com,Male,54.98.36.94\n63,Peter,Morgan,pmorgan1q@rambler.ru,Male,14.77.29.106\n64,Nicole,Garrett,ngarrett1r@zimbio.com,Female,21.127.74.68\n65,Joshua,Kim,jkim1s@edublogs.org,Male,57.255.207.41\n66,Ralph,Roberts,rroberts1t@people.com.cn,Male,222.143.131.109\n67,George,Montgomery,gmontgomery1u@smugmug.com,Male,76.75.111.77\n68,Gerald,Alvarez,galvarez1v@flavors.me,Male,58.157.186.194\n69,Donald,Olson,dolson1w@whitehouse.gov,Male,69.65.74.135\n70,Carlos,Morgan,cmorgan1x@pbs.org,Male,96.20.140.87\n71,Aaron,Stanley,astanley1y@webnode.com,Male,163.119.217.44\n72,Virginia,Long,vlong1z@spiegel.de,Female,204.150.194.182\n73,Robert,Berry,rberry20@tripadvisor.com,Male,104.19.48.241\n74,Antonio,Brooks,abrooks21@unesco.org,Male,210.31.7.24\n75,Ruby,Garcia,rgarcia22@ovh.net,Female,233.218.162.214\n76,Jack,Hanson,jhanson23@blogtalkradio.com,Male,31.55.46.199\n77,Kathryn,Nelson,knelson24@walmart.com,Female,14.189.146.41\n78,Jason,Reed,jreed25@printfriendly.com,Male,141.189.89.255\n79,George,Coleman,gcoleman26@people.com.cn,Male,81.189.221.144\n80,Rose,King,rking27@ucoz.com,Female,212.123.168.231\n81,Johnny,Holmes,jholmes28@boston.com,Male,177.3.93.188\n82,Katherine,Gilbert,kgilbert29@altervista.org,Female,199.215.169.61\n83,Joshua,Thomas,jthomas2a@ustream.tv,Male,0.8.205.30\n84,Julie,Perry,jperry2b@opensource.org,Female,60.116.114.192\n85,Richard,Perry,rperry2c@oracle.com,Male,181.125.70.232\n86,Kenneth,Ruiz,kruiz2d@wikimedia.org,Male,189.105.137.109\n87,Jose,Morgan,jmorgan2e@webnode.com,Male,101.134.215.156\n88,Donald,Campbell,dcampbell2f@goo.ne.jp,Male,102.120.215.84\n89,Debra,Collins,dcollins2g@uol.com.br,Female,90.13.153.235\n90,Jesse,Johnson,jjohnson2h@stumbleupon.com,Male,225.178.125.53\n91,Elizabeth,Stone,estone2i@histats.com,Female,123.184.126.221\n92,Angela,Rogers,arogers2j@goodreads.com,Female,98.104.132.187\n93,Emily,Dixon,edixon2k@mlb.com,Female,39.190.75.57\n94,Albert,Scott,ascott2l@tinypic.com,Male,40.209.13.189\n95,Barbara,Peterson,bpeterson2m@ow.ly,Female,75.249.136.180\n96,Adam,Greene,agreene2n@fastcompany.com,Male,184.173.109.144\n97,Earl,Sanders,esanders2o@hc360.com,Male,247.34.90.117\n98,Angela,Brooks,abrooks2p@mtv.com,Female,10.63.249.126\n99,Harold,Foster,hfoster2q@privacy.gov.au,Male,139.214.40.244\n100,Carl,Meyer,cmeyer2r@disqus.com,Male,204.117.7.88\n"
  },
  {
    "path": "tests/functional/basic/data/seed-update.csv",
    "content": "id,first_name,last_name,email,gender,ip_address\n1,Jack,Hunter,jhunter0@pbs.org,Male,59.80.20.168\n2,Kathryn,Walker,kwalker1@ezinearticles.com,Female,194.121.179.35\n3,Gerald,Ryan,gryan2@com.com,Male,11.3.212.243\n4,Bonnie,Spencer,bspencer3@ameblo.jp,Female,216.32.196.175\n5,Harold,Taylor,htaylor4@people.com.cn,Male,253.10.246.136\n6,Jacqueline,Griffin,jgriffin5@t.co,Female,16.13.192.220\n7,Wanda,Arnold,warnold6@google.nl,Female,232.116.150.64\n8,Craig,Ortiz,cortiz7@sciencedaily.com,Male,199.126.106.13\n9,Gary,Day,gday8@nih.gov,Male,35.81.68.186\n10,Rose,Wright,rwright9@yahoo.co.jp,Female,236.82.178.100\n11,Raymond,Kelley,rkelleya@fc2.com,Male,213.65.166.67\n12,Gerald,Robinson,grobinsonb@disqus.com,Male,72.232.194.193\n13,Mildred,Martinez,mmartinezc@samsung.com,Female,198.29.112.5\n14,Dennis,Arnold,darnoldd@google.com,Male,86.96.3.250\n15,Judy,Gray,jgraye@opensource.org,Female,79.218.162.245\n16,Theresa,Garza,tgarzaf@epa.gov,Female,21.59.100.54\n17,Gerald,Robertson,grobertsong@csmonitor.com,Male,131.134.82.96\n18,Philip,Hernandez,phernandezh@adobe.com,Male,254.196.137.72\n19,Julia,Gonzalez,jgonzalezi@cam.ac.uk,Female,84.240.227.174\n20,Andrew,Davis,adavisj@patch.com,Male,9.255.67.25\n21,Kimberly,Harper,kharperk@foxnews.com,Female,198.208.120.253\n22,Mark,Martin,mmartinl@marketwatch.com,Male,233.138.182.153\n23,Cynthia,Ruiz,cruizm@google.fr,Female,18.178.187.201\n24,Samuel,Carroll,scarrolln@youtu.be,Male,128.113.96.122\n25,Jennifer,Larson,jlarsono@vinaora.com,Female,98.234.85.95\n26,Ashley,Perry,aperryp@rakuten.co.jp,Female,247.173.114.52\n27,Howard,Rodriguez,hrodriguezq@shutterfly.com,Male,231.188.95.26\n28,Amy,Brooks,abrooksr@theatlantic.com,Female,141.199.174.118\n29,Louise,Warren,lwarrens@adobe.com,Female,96.105.158.28\n30,Tina,Watson,twatsont@myspace.com,Female,251.142.118.177\n31,Janice,Kelley,jkelleyu@creativecommons.org,Female,239.167.34.233\n32,Terry,Mccoy,tmccoyv@bravesites.com,Male,117.201.183.203\n33,Jeffrey,Morgan,jmorganw@surveymonkey.com,Male,78.101.78.149\n34,Louis,Harvey,lharveyx@sina.com.cn,Male,51.50.0.167\n35,Philip,Miller,pmillery@samsung.com,Male,103.255.222.110\n36,Willie,Marshall,wmarshallz@ow.ly,Male,149.219.91.68\n37,Patrick,Lopez,plopez10@redcross.org,Male,250.136.229.89\n38,Adam,Jenkins,ajenkins11@harvard.edu,Male,7.36.112.81\n39,Benjamin,Cruz,bcruz12@linkedin.com,Male,32.38.98.15\n40,Ruby,Hawkins,rhawkins13@gmpg.org,Female,135.171.129.255\n41,Carlos,Barnes,cbarnes14@a8.net,Male,240.197.85.140\n42,Ruby,Griffin,rgriffin15@bravesites.com,Female,19.29.135.24\n43,Sean,Mason,smason16@icq.com,Male,159.219.155.249\n44,Anthony,Payne,apayne17@utexas.edu,Male,235.168.199.218\n45,Steve,Cruz,scruz18@pcworld.com,Male,238.201.81.198\n46,Anthony,Garcia,agarcia19@flavors.me,Male,25.85.10.18\n47,Doris,Lopez,dlopez1a@sphinn.com,Female,245.218.51.238\n48,Susan,Nichols,snichols1b@freewebs.com,Female,199.99.9.61\n49,Wanda,Ferguson,wferguson1c@yahoo.co.jp,Female,236.241.135.21\n50,Andrea,Pierce,apierce1d@google.co.uk,Female,132.40.10.209\n51,Lawrence,Phillips,lphillips1e@jugem.jp,Male,72.226.82.87\n52,Judy,Gilbert,jgilbert1f@multiply.com,Female,196.250.15.142\n53,Eric,Williams,ewilliams1g@joomla.org,Male,222.202.73.126\n54,Ralph,Romero,rromero1h@sogou.com,Male,123.184.125.212\n55,Jean,Wilson,jwilson1i@ocn.ne.jp,Female,176.106.32.194\n56,Lori,Reynolds,lreynolds1j@illinois.edu,Female,114.181.203.22\n57,Donald,Moreno,dmoreno1k@bbc.co.uk,Male,233.249.97.60\n58,Steven,Berry,sberry1l@eepurl.com,Male,186.193.50.50\n59,Theresa,Shaw,tshaw1m@people.com.cn,Female,120.37.71.222\n60,John,Stephens,jstephens1n@nationalgeographic.com,Male,191.87.127.115\n61,Richard,Jacobs,rjacobs1o@state.tx.us,Male,66.210.83.155\n62,Andrew,Lawson,alawson1p@over-blog.com,Male,54.98.36.94\n63,Peter,Morgan,pmorgan1q@rambler.ru,Male,14.77.29.106\n64,Nicole,Garrett,ngarrett1r@zimbio.com,Female,21.127.74.68\n65,Joshua,Kim,jkim1s@edublogs.org,Male,57.255.207.41\n66,Ralph,Roberts,rroberts1t@people.com.cn,Male,222.143.131.109\n67,George,Montgomery,gmontgomery1u@smugmug.com,Male,76.75.111.77\n68,Gerald,Alvarez,galvarez1v@flavors.me,Male,58.157.186.194\n69,Donald,Olson,dolson1w@whitehouse.gov,Male,69.65.74.135\n70,Carlos,Morgan,cmorgan1x@pbs.org,Male,96.20.140.87\n71,Aaron,Stanley,astanley1y@webnode.com,Male,163.119.217.44\n72,Virginia,Long,vlong1z@spiegel.de,Female,204.150.194.182\n73,Robert,Berry,rberry20@tripadvisor.com,Male,104.19.48.241\n74,Antonio,Brooks,abrooks21@unesco.org,Male,210.31.7.24\n75,Ruby,Garcia,rgarcia22@ovh.net,Female,233.218.162.214\n76,Jack,Hanson,jhanson23@blogtalkradio.com,Male,31.55.46.199\n77,Kathryn,Nelson,knelson24@walmart.com,Female,14.189.146.41\n78,Jason,Reed,jreed25@printfriendly.com,Male,141.189.89.255\n79,George,Coleman,gcoleman26@people.com.cn,Male,81.189.221.144\n80,Rose,King,rking27@ucoz.com,Female,212.123.168.231\n81,Johnny,Holmes,jholmes28@boston.com,Male,177.3.93.188\n82,Katherine,Gilbert,kgilbert29@altervista.org,Female,199.215.169.61\n83,Joshua,Thomas,jthomas2a@ustream.tv,Male,0.8.205.30\n84,Julie,Perry,jperry2b@opensource.org,Female,60.116.114.192\n85,Richard,Perry,rperry2c@oracle.com,Male,181.125.70.232\n86,Kenneth,Ruiz,kruiz2d@wikimedia.org,Male,189.105.137.109\n87,Jose,Morgan,jmorgan2e@webnode.com,Male,101.134.215.156\n88,Donald,Campbell,dcampbell2f@goo.ne.jp,Male,102.120.215.84\n89,Debra,Collins,dcollins2g@uol.com.br,Female,90.13.153.235\n90,Jesse,Johnson,jjohnson2h@stumbleupon.com,Male,225.178.125.53\n91,Elizabeth,Stone,estone2i@histats.com,Female,123.184.126.221\n92,Angela,Rogers,arogers2j@goodreads.com,Female,98.104.132.187\n93,Emily,Dixon,edixon2k@mlb.com,Female,39.190.75.57\n94,Albert,Scott,ascott2l@tinypic.com,Male,40.209.13.189\n95,Barbara,Peterson,bpeterson2m@ow.ly,Female,75.249.136.180\n96,Adam,Greene,agreene2n@fastcompany.com,Male,184.173.109.144\n97,Earl,Sanders,esanders2o@hc360.com,Male,247.34.90.117\n98,Angela,Brooks,abrooks2p@mtv.com,Female,10.63.249.126\n99,Harold,Foster,hfoster2q@privacy.gov.au,Male,139.214.40.244\n100,Carl,Meyer,cmeyer2r@disqus.com,Male,204.117.7.88\n101,Michael,Perez,mperez0@chronoengine.com,Male,106.239.70.175\n102,Shawn,Mccoy,smccoy1@reddit.com,Male,24.165.76.182\n103,Kathleen,Payne,kpayne2@cargocollective.com,Female,113.207.168.106\n104,Jimmy,Cooper,jcooper3@cargocollective.com,Male,198.24.63.114\n105,Katherine,Rice,krice4@typepad.com,Female,36.97.186.238\n106,Sarah,Ryan,sryan5@gnu.org,Female,119.117.152.40\n107,Martin,Mcdonald,mmcdonald6@opera.com,Male,8.76.38.115\n108,Frank,Robinson,frobinson7@wunderground.com,Male,186.14.64.194\n109,Jennifer,Franklin,jfranklin8@mail.ru,Female,91.216.3.131\n110,Henry,Welch,hwelch9@list-manage.com,Male,176.35.182.168\n111,Fred,Snyder,fsnydera@reddit.com,Male,217.106.196.54\n112,Amy,Dunn,adunnb@nba.com,Female,95.39.163.195\n113,Kathleen,Meyer,kmeyerc@cdc.gov,Female,164.142.188.214\n114,Steve,Ferguson,sfergusond@reverbnation.com,Male,138.22.204.251\n115,Teresa,Hill,thille@dion.ne.jp,Female,82.84.228.235\n116,Amanda,Harper,aharperf@mail.ru,Female,16.123.56.176\n117,Kimberly,Ray,krayg@xing.com,Female,48.66.48.12\n118,Johnny,Knight,jknighth@jalbum.net,Male,99.30.138.123\n119,Virginia,Freeman,vfreemani@tiny.cc,Female,225.172.182.63\n120,Anna,Austin,aaustinj@diigo.com,Female,62.111.227.148\n121,Willie,Hill,whillk@mail.ru,Male,0.86.232.249\n122,Sean,Harris,sharrisl@zdnet.com,Male,117.165.133.249\n123,Mildred,Adams,madamsm@usatoday.com,Female,163.44.97.46\n124,David,Graham,dgrahamn@zimbio.com,Male,78.13.246.202\n125,Victor,Hunter,vhuntero@ehow.com,Male,64.156.179.139\n126,Aaron,Ruiz,aruizp@weebly.com,Male,34.194.68.78\n127,Benjamin,Brooks,bbrooksq@jalbum.net,Male,20.192.189.107\n128,Lisa,Wilson,lwilsonr@japanpost.jp,Female,199.152.130.217\n129,Benjamin,King,bkings@comsenz.com,Male,29.189.189.213\n130,Christina,Williamson,cwilliamsont@boston.com,Female,194.101.52.60\n131,Jane,Gonzalez,jgonzalezu@networksolutions.com,Female,109.119.12.87\n132,Thomas,Owens,towensv@psu.edu,Male,84.168.213.153\n133,Katherine,Moore,kmoorew@naver.com,Female,183.150.65.24\n134,Jennifer,Stewart,jstewartx@yahoo.com,Female,38.41.244.58\n135,Sara,Tucker,stuckery@topsy.com,Female,181.130.59.184\n136,Harold,Ortiz,hortizz@vkontakte.ru,Male,198.231.63.137\n137,Shirley,James,sjames10@yelp.com,Female,83.27.160.104\n138,Dennis,Johnson,djohnson11@slate.com,Male,183.178.246.101\n139,Louise,Weaver,lweaver12@china.com.cn,Female,1.14.110.18\n140,Maria,Armstrong,marmstrong13@prweb.com,Female,181.142.1.249\n141,Gloria,Cruz,gcruz14@odnoklassniki.ru,Female,178.232.140.243\n142,Diana,Spencer,dspencer15@ifeng.com,Female,125.153.138.244\n143,Kelly,Nguyen,knguyen16@altervista.org,Female,170.13.201.119\n144,Jane,Rodriguez,jrodriguez17@biblegateway.com,Female,12.102.249.81\n145,Scott,Brown,sbrown18@geocities.jp,Male,108.174.99.192\n146,Norma,Cruz,ncruz19@si.edu,Female,201.112.156.197\n147,Marie,Peters,mpeters1a@mlb.com,Female,231.121.197.144\n148,Lillian,Carr,lcarr1b@typepad.com,Female,206.179.164.163\n149,Judy,Nichols,jnichols1c@t-online.de,Female,158.190.209.194\n150,Billy,Long,blong1d@yahoo.com,Male,175.20.23.160\n151,Howard,Reid,hreid1e@exblog.jp,Male,118.99.196.20\n152,Laura,Ferguson,lferguson1f@tuttocitta.it,Female,22.77.87.110\n153,Anne,Bailey,abailey1g@geocities.com,Female,58.144.159.245\n154,Rose,Morgan,rmorgan1h@ehow.com,Female,118.127.97.4\n155,Nicholas,Reyes,nreyes1i@google.ru,Male,50.135.10.252\n156,Joshua,Kennedy,jkennedy1j@house.gov,Male,154.6.163.209\n157,Paul,Watkins,pwatkins1k@upenn.edu,Male,177.236.120.87\n158,Kathryn,Kelly,kkelly1l@businessweek.com,Female,70.28.61.86\n159,Adam,Armstrong,aarmstrong1m@techcrunch.com,Male,133.235.24.202\n160,Norma,Wallace,nwallace1n@phoca.cz,Female,241.119.227.128\n161,Timothy,Reyes,treyes1o@google.cn,Male,86.28.23.26\n162,Elizabeth,Patterson,epatterson1p@sun.com,Female,139.97.159.149\n163,Edward,Gomez,egomez1q@google.fr,Male,158.103.108.255\n164,David,Cox,dcox1r@friendfeed.com,Male,206.80.80.58\n165,Brenda,Wood,bwood1s@over-blog.com,Female,217.207.44.179\n166,Adam,Walker,awalker1t@blogs.com,Male,253.211.54.93\n167,Michael,Hart,mhart1u@wix.com,Male,230.206.200.22\n168,Jesse,Ellis,jellis1v@google.co.uk,Male,213.254.162.52\n169,Janet,Powell,jpowell1w@un.org,Female,27.192.194.86\n170,Helen,Ford,hford1x@creativecommons.org,Female,52.160.102.168\n171,Gerald,Carpenter,gcarpenter1y@about.me,Male,36.30.194.218\n172,Kathryn,Oliver,koliver1z@army.mil,Female,202.63.103.69\n173,Alan,Berry,aberry20@gov.uk,Male,246.157.112.211\n174,Harry,Andrews,handrews21@ameblo.jp,Male,195.108.0.12\n175,Andrea,Hall,ahall22@hp.com,Female,149.162.163.28\n176,Barbara,Wells,bwells23@behance.net,Female,224.70.72.1\n177,Anne,Wells,awells24@apache.org,Female,180.168.81.153\n178,Harry,Harper,hharper25@rediff.com,Male,151.87.130.21\n179,Jack,Ray,jray26@wufoo.com,Male,220.109.38.178\n180,Phillip,Hamilton,phamilton27@joomla.org,Male,166.40.47.30\n181,Shirley,Hunter,shunter28@newsvine.com,Female,97.209.140.194\n182,Arthur,Daniels,adaniels29@reuters.com,Male,5.40.240.86\n183,Virginia,Rodriguez,vrodriguez2a@walmart.com,Female,96.80.164.184\n184,Christina,Ryan,cryan2b@hibu.com,Female,56.35.5.52\n185,Theresa,Mendoza,tmendoza2c@vinaora.com,Female,243.42.0.210\n186,Jason,Cole,jcole2d@ycombinator.com,Male,198.248.39.129\n187,Phillip,Bryant,pbryant2e@rediff.com,Male,140.39.116.251\n188,Adam,Torres,atorres2f@sun.com,Male,101.75.187.135\n189,Margaret,Johnston,mjohnston2g@ucsd.edu,Female,159.30.69.149\n190,Paul,Payne,ppayne2h@hhs.gov,Male,199.234.140.220\n191,Todd,Willis,twillis2i@businessweek.com,Male,191.59.136.214\n192,Willie,Oliver,woliver2j@noaa.gov,Male,44.212.35.197\n193,Frances,Robertson,frobertson2k@go.com,Female,31.117.65.136\n194,Gregory,Hawkins,ghawkins2l@joomla.org,Male,91.3.22.49\n195,Lisa,Perkins,lperkins2m@si.edu,Female,145.95.31.186\n196,Jacqueline,Anderson,janderson2n@cargocollective.com,Female,14.176.0.187\n197,Shirley,Diaz,sdiaz2o@ucla.edu,Female,207.12.95.46\n198,Nicole,Meyer,nmeyer2p@flickr.com,Female,231.79.115.13\n199,Mary,Gray,mgray2q@constantcontact.com,Female,210.116.64.253\n200,Jean,Mcdonald,jmcdonald2r@baidu.com,Female,122.239.235.117\n"
  },
  {
    "path": "tests/functional/basic/data/summary_expected.csv",
    "content": "gender,ct\nFemale,40\nMale,60\n"
  },
  {
    "path": "tests/functional/basic/data/summary_expected_update.csv",
    "content": "gender,ct\nFemale,94\nMale,106\n"
  },
  {
    "path": "tests/functional/basic/data/varchar10_seed.sql",
    "content": "create table {schema}.seed (\n\tid BIGSERIAL PRIMARY KEY,\n\tfirst_name VARCHAR(50),\n\tlast_name VARCHAR(50),\n\temail VARCHAR(50),\n\t\"GenDEr\" VARCHAR(10),\n\tip_address VARCHAR(20)\n);\n\ninsert into {schema}.seed (first_name, last_name, email, \"GenDEr\", ip_address) values\n('Jack', 'Hunter', 'jhunter0@pbs.org', 'Male', '59.80.20.168'),\n('Kathryn', 'Walker', 'kwalker1@ezinearticles.com', 'Female', '194.121.179.35'),\n('Gerald', 'Ryan', 'gryan2@com.com', 'Male', '11.3.212.243'),\n('Bonnie', 'Spencer', 'bspencer3@ameblo.jp', 'Female', '216.32.196.175'),\n('Harold', 'Taylor', 'htaylor4@people.com.cn', 'Male', '253.10.246.136'),\n('Jacqueline', 'Griffin', 'jgriffin5@t.co', 'Female', '16.13.192.220'),\n('Wanda', 'Arnold', 'warnold6@google.nl', 'Female', '232.116.150.64'),\n('Craig', 'Ortiz', 'cortiz7@sciencedaily.com', 'Male', '199.126.106.13'),\n('Gary', 'Day', 'gday8@nih.gov', 'Male', '35.81.68.186'),\n('Rose', 'Wright', 'rwright9@yahoo.co.jp', 'Female', '236.82.178.100'),\n('Raymond', 'Kelley', 'rkelleya@fc2.com', 'Male', '213.65.166.67'),\n('Gerald', 'Robinson', 'grobinsonb@disqus.com', 'Male', '72.232.194.193'),\n('Mildred', 'Martinez', 'mmartinezc@samsung.com', 'Female', '198.29.112.5'),\n('Dennis', 'Arnold', 'darnoldd@google.com', 'Male', '86.96.3.250'),\n('Judy', 'Gray', 'jgraye@opensource.org', 'Female', '79.218.162.245'),\n('Theresa', 'Garza', 'tgarzaf@epa.gov', 'Female', '21.59.100.54'),\n('Gerald', 'Robertson', 'grobertsong@csmonitor.com', 'Male', '131.134.82.96'),\n('Philip', 'Hernandez', 'phernandezh@adobe.com', 'Male', '254.196.137.72'),\n('Julia', 'Gonzalez', 'jgonzalezi@cam.ac.uk', 'Female', '84.240.227.174'),\n('Andrew', 'Davis', 'adavisj@patch.com', 'Male', '9.255.67.25'),\n('Kimberly', 'Harper', 'kharperk@foxnews.com', 'Female', '198.208.120.253'),\n('Mark', 'Martin', 'mmartinl@marketwatch.com', 'Male', '233.138.182.153'),\n('Cynthia', 'Ruiz', 'cruizm@google.fr', 'Female', '18.178.187.201'),\n('Samuel', 'Carroll', 'scarrolln@youtu.be', 'Male', '128.113.96.122'),\n('Jennifer', 'Larson', 'jlarsono@vinaora.com', 'Female', '98.234.85.95'),\n('Ashley', 'Perry', 'aperryp@rakuten.co.jp', 'Female', '247.173.114.52'),\n('Howard', 'Rodriguez', 'hrodriguezq@shutterfly.com', 'Male', '231.188.95.26'),\n('Amy', 'Brooks', 'abrooksr@theatlantic.com', 'Female', '141.199.174.118'),\n('Louise', 'Warren', 'lwarrens@adobe.com', 'Female', '96.105.158.28'),\n('Tina', 'Watson', 'twatsont@myspace.com', 'Female', '251.142.118.177'),\n('Janice', 'Kelley', 'jkelleyu@creativecommons.org', 'Female', '239.167.34.233'),\n('Terry', 'Mccoy', 'tmccoyv@bravesites.com', 'Male', '117.201.183.203'),\n('Jeffrey', 'Morgan', 'jmorganw@surveymonkey.com', 'Male', '78.101.78.149'),\n('Louis', 'Harvey', 'lharveyx@sina.com.cn', 'Male', '51.50.0.167'),\n('Philip', 'Miller', 'pmillery@samsung.com', 'Male', '103.255.222.110'),\n('Willie', 'Marshall', 'wmarshallz@ow.ly', 'Male', '149.219.91.68'),\n('Patrick', 'Lopez', 'plopez10@redcross.org', 'Male', '250.136.229.89'),\n('Adam', 'Jenkins', 'ajenkins11@harvard.edu', 'Male', '7.36.112.81'),\n('Benjamin', 'Cruz', 'bcruz12@linkedin.com', 'Male', '32.38.98.15'),\n('Ruby', 'Hawkins', 'rhawkins13@gmpg.org', 'Female', '135.171.129.255'),\n('Carlos', 'Barnes', 'cbarnes14@a8.net', 'Male', '240.197.85.140'),\n('Ruby', 'Griffin', 'rgriffin15@bravesites.com', 'Female', '19.29.135.24'),\n('Sean', 'Mason', 'smason16@icq.com', 'Male', '159.219.155.249'),\n('Anthony', 'Payne', 'apayne17@utexas.edu', 'Male', '235.168.199.218'),\n('Steve', 'Cruz', 'scruz18@pcworld.com', 'Male', '238.201.81.198'),\n('Anthony', 'Garcia', 'agarcia19@flavors.me', 'Male', '25.85.10.18'),\n('Doris', 'Lopez', 'dlopez1a@sphinn.com', 'Female', '245.218.51.238'),\n('Susan', 'Nichols', 'snichols1b@freewebs.com', 'Female', '199.99.9.61'),\n('Wanda', 'Ferguson', 'wferguson1c@yahoo.co.jp', 'Female', '236.241.135.21'),\n('Andrea', 'Pierce', 'apierce1d@google.co.uk', 'Female', '132.40.10.209'),\n('Lawrence', 'Phillips', 'lphillips1e@jugem.jp', 'Male', '72.226.82.87'),\n('Judy', 'Gilbert', 'jgilbert1f@multiply.com', 'Female', '196.250.15.142'),\n('Eric', 'Williams', 'ewilliams1g@joomla.org', 'Male', '222.202.73.126'),\n('Ralph', 'Romero', 'rromero1h@sogou.com', 'Male', '123.184.125.212'),\n('Jean', 'Wilson', 'jwilson1i@ocn.ne.jp', 'Female', '176.106.32.194'),\n('Lori', 'Reynolds', 'lreynolds1j@illinois.edu', 'Female', '114.181.203.22'),\n('Donald', 'Moreno', 'dmoreno1k@bbc.co.uk', 'Male', '233.249.97.60'),\n('Steven', 'Berry', 'sberry1l@eepurl.com', 'Male', '186.193.50.50'),\n('Theresa', 'Shaw', 'tshaw1m@people.com.cn', 'Female', '120.37.71.222'),\n('John', 'Stephens', 'jstephens1n@nationalgeographic.com', 'Male', '191.87.127.115'),\n('Richard', 'Jacobs', 'rjacobs1o@state.tx.us', 'Male', '66.210.83.155'),\n('Andrew', 'Lawson', 'alawson1p@over-blog.com', 'Male', '54.98.36.94'),\n('Peter', 'Morgan', 'pmorgan1q@rambler.ru', 'Male', '14.77.29.106'),\n('Nicole', 'Garrett', 'ngarrett1r@zimbio.com', 'Female', '21.127.74.68'),\n('Joshua', 'Kim', 'jkim1s@edublogs.org', 'Male', '57.255.207.41'),\n('Ralph', 'Roberts', 'rroberts1t@people.com.cn', 'Male', '222.143.131.109'),\n('George', 'Montgomery', 'gmontgomery1u@smugmug.com', 'Male', '76.75.111.77'),\n('Gerald', 'Alvarez', 'galvarez1v@flavors.me', 'Male', '58.157.186.194'),\n('Donald', 'Olson', 'dolson1w@whitehouse.gov', 'Male', '69.65.74.135'),\n('Carlos', 'Morgan', 'cmorgan1x@pbs.org', 'Male', '96.20.140.87'),\n('Aaron', 'Stanley', 'astanley1y@webnode.com', 'Male', '163.119.217.44'),\n('Virginia', 'Long', 'vlong1z@spiegel.de', 'Female', '204.150.194.182'),\n('Robert', 'Berry', 'rberry20@tripadvisor.com', 'Male', '104.19.48.241'),\n('Antonio', 'Brooks', 'abrooks21@unesco.org', 'Male', '210.31.7.24'),\n('Ruby', 'Garcia', 'rgarcia22@ovh.net', 'Female', '233.218.162.214'),\n('Jack', 'Hanson', 'jhanson23@blogtalkradio.com', 'Male', '31.55.46.199'),\n('Kathryn', 'Nelson', 'knelson24@walmart.com', 'Female', '14.189.146.41'),\n('Jason', 'Reed', 'jreed25@printfriendly.com', 'Male', '141.189.89.255'),\n('George', 'Coleman', 'gcoleman26@people.com.cn', 'Male', '81.189.221.144'),\n('Rose', 'King', 'rking27@ucoz.com', 'Female', '212.123.168.231'),\n('Johnny', 'Holmes', 'jholmes28@boston.com', 'Male', '177.3.93.188'),\n('Katherine', 'Gilbert', 'kgilbert29@altervista.org', 'Female', '199.215.169.61'),\n('Joshua', 'Thomas', 'jthomas2a@ustream.tv', 'Male', '0.8.205.30'),\n('Julie', 'Perry', 'jperry2b@opensource.org', 'Female', '60.116.114.192'),\n('Richard', 'Perry', 'rperry2c@oracle.com', 'Male', '181.125.70.232'),\n('Kenneth', 'Ruiz', 'kruiz2d@wikimedia.org', 'Male', '189.105.137.109'),\n('Jose', 'Morgan', 'jmorgan2e@webnode.com', 'Male', '101.134.215.156'),\n('Donald', 'Campbell', 'dcampbell2f@goo.ne.jp', 'Male', '102.120.215.84'),\n('Debra', 'Collins', 'dcollins2g@uol.com.br', 'Female', '90.13.153.235'),\n('Jesse', 'Johnson', 'jjohnson2h@stumbleupon.com', 'Male', '225.178.125.53'),\n('Elizabeth', 'Stone', 'estone2i@histats.com', 'Female', '123.184.126.221'),\n('Angela', 'Rogers', 'arogers2j@goodreads.com', 'Female', '98.104.132.187'),\n('Emily', 'Dixon', 'edixon2k@mlb.com', 'Female', '39.190.75.57'),\n('Albert', 'Scott', 'ascott2l@tinypic.com', 'Male', '40.209.13.189'),\n('Barbara', 'Peterson', 'bpeterson2m@ow.ly', 'Female', '75.249.136.180'),\n('Adam', 'Greene', 'agreene2n@fastcompany.com', 'Male', '184.173.109.144'),\n('Earl', 'Sanders', 'esanders2o@hc360.com', 'Male', '247.34.90.117'),\n('Angela', 'Brooks', 'abrooks2p@mtv.com', 'Female', '10.63.249.126'),\n('Harold', 'Foster', 'hfoster2q@privacy.gov.au', 'Male', '139.214.40.244'),\n('Carl', 'Meyer', 'cmeyer2r@disqus.com', 'Male', '204.117.7.88');\n"
  },
  {
    "path": "tests/functional/basic/data/varchar300_seed.sql",
    "content": "ALTER TABLE {schema}.seed ALTER COLUMN \"GenDEr\" TYPE varchar(300);\n\ninsert into {schema}.seed (first_name, last_name, email, \"GenDEr\", ip_address) values\n('Annie', 'Reynolds', 'areynolds0@nifty.com', 'Amerisource Bergen', '133.30.242.211'),\n('Doris', 'Wood', 'dwood1@skyrock.com', 'Bliss World, LLC', '128.229.89.207'),\n('Andrea', 'Ray', 'aray2@google.co.jp', 'Nelco Laboratories, Inc.', '109.74.153.45'),\n('Frank', 'Morgan', 'fmorgan3@1688.com', 'ALK-Abello, Inc.', '252.211.209.9'),\n('Angela', 'Stanley', 'astanley4@google.fr', 'Gemini Pharmaceuticals, Inc. dba ONDRA Pharmaceuticals', '134.142.194.184'),\n('Ruby', 'Jordan', 'rjordan5@nymag.com', 'Watson Pharma, Inc.', '195.104.60.172'),\n('Kathleen', 'Ryan', 'kryan6@scientificamerican.com', 'SHISEIDO AMERICAS CORPORATION', '209.110.160.192'),\n('Margaret', 'Jacobs', 'mjacobs7@example.com', 'Cardinal Health', '72.36.52.20'),\n('Ernest', 'Brown', 'ebrown8@360.cn', 'West-ward Pharmaceutical Corp', '138.157.61.255'),\n('Elizabeth', 'Phillips', 'ephillips9@japanpost.jp', 'Cellex-C International Inc', '68.46.195.188'),\n('Annie', 'Ellis', 'aellisa@weather.com', 'NATURE REPUBLIC CO., LTD.', '163.128.214.142'),\n('Melissa', 'Olson', 'molsonb@theguardian.com', 'Nelco Laboratories, Inc.', '202.22.153.188'),\n('Timothy', 'Martinez', 'tmartinezc@zimbio.com', 'Lake Erie Medical & Surgical Supply DBA Quality Care Products LLC', '45.64.205.47'),\n('Mark', 'Nelson', 'mnelsond@bloomberg.com', '7-Eleven', '91.99.195.160'),\n('Kenneth', 'Hart', 'kharte@berkeley.edu', 'Preferred Pharmaceuticals, Inc.', '207.240.9.102'),\n('Kathryn', 'White', 'kwhitef@csmonitor.com', 'Cantrell Drug Company', '191.178.162.18'),\n('Mary', 'Greene', 'mgreeneg@usnews.com', 'Neutrogena Corporation', '251.226.65.64'),\n('Bruce', 'Peters', 'bpetersh@blogspot.com', 'Sun & Skin Care Research, LLC', '153.227.91.121'),\n('Albert', 'Armstrong', 'aarmstrongi@weather.com', 'Access Business Group LLC', '199.146.159.228'),\n('Beverly', 'Gray', 'bgrayj@spiegel.de', 'Church & Dwight Co., Inc.', '47.3.135.226'),\n('Catherine', 'Taylor', 'ctaylork@walmart.com', 'Matrixx Initiatives, Inc.', '82.24.129.147'),\n('Paula', 'Bradley', 'pbradleyl@edublogs.org', 'Nash-Finch Company', '14.145.193.163'),\n('Terry', 'Campbell', 'tcampbellm@artisteer.com', 'MedVantx, Inc.', '89.181.95.177'),\n('Bruce', 'Stevens', 'bstevensn@ucla.edu', 'Global Pharmaceuticals', '128.81.126.144'),\n('Ruby', 'Bishop', 'rbishopo@telegraph.co.uk', 'General Injectables & Vaccines, Inc.', '191.191.17.173'),\n('Denise', 'Duncan', 'dduncanp@reference.com', 'Bare Escentuals Beauty, Inc.', '150.207.3.163'),\n('Dennis', 'Perkins', 'dperkinsq@1und1.de', 'Altaire Pharmaceuticals Inc.', '21.150.103.133'),\n('Brandon', 'Ray', 'brayr@psu.edu', 'Meijer Distribution Inc', '216.53.187.191'),\n('Ernest', 'Graham', 'egrahams@tinyurl.com', 'BioComp Pharma, Inc.', '49.85.236.162'),\n('Denise', 'Matthews', 'dmatthewst@digg.com', 'Procter & Gamble Manufacturing Co.', '160.4.119.137'),\n('Randy', 'Alexander', 'ralexanderu@goo.gl', 'Reckitt Benckiser Pharmaceuticals Inc', '211.72.176.12'),\n('Aaron', 'Jackson', 'ajacksonv@gizmodo.com', 'Molton Brown LTD (UK)', '226.178.48.73'),\n('Wanda', 'Turner', 'wturnerw@reverbnation.com', 'American Health Packaging', '43.22.122.56'),\n('Stephen', 'Ferguson', 'sfergusonx@kickstarter.com', 'Amneal Pharmaceuticals of New York, LLC', '110.211.112.233'),\n('Jane', 'Bradley', 'jbradleyy@usgs.gov', 'Kroger Company', '186.153.255.125'),\n('Phillip', 'Wood', 'pwoodz@about.com', 'Unit Dose Services', '112.65.6.93'),\n('Jeffrey', 'Howell', 'jhowell10@symantec.com', 'Midlothian Laboratories', '232.92.208.248'),\n('Howard', 'Harvey', 'hharvey11@nhs.uk', 'Novartis Pharmaceuticals Corporation', '50.212.26.218'),\n('Benjamin', 'Johnston', 'bjohnston12@diigo.com', 'Nelco Laboratories, Inc.', '131.109.13.9'),\n('Ernest', 'Burke', 'eburke13@toplist.cz', 'Apotex Corp.', '151.176.178.175'),\n('Joe', 'Wright', 'jwright14@mapy.cz', 'MULTALER & CIE S.A.', '233.55.33.63'),\n('Ronald', 'Griffin', 'rgriffin15@topsy.com', 'Gavis Pharmaceuticals, LLC', '174.233.67.86'),\n('Susan', 'Oliver', 'soliver16@goo.gl', 'Bath & Body Works, Inc.', '104.171.43.12'),\n('Karen', 'Cox', 'kcox17@hp.com', 'Home Sweet Homeopathics', '225.51.182.192'),\n('Antonio', 'Larson', 'alarson18@gov.uk', 'Eight and Company', '243.118.98.188'),\n('Brandon', 'Cook', 'bcook19@mozilla.com', 'Chain Drug Consortium, LLC', '38.64.44.255'),\n('Gary', 'Gray', 'ggray1a@alexa.com', 'Lil'' Drug Store Products, Inc', '43.34.161.60'),\n('Doris', 'Harrison', 'dharrison1b@wiley.com', 'Dispensing Solutions, Inc.', '153.66.74.140'),\n('Clarence', 'Perry', 'cperry1c@issuu.com', 'Nelco Laboratories, Inc.', '14.72.110.59'),\n('Emily', 'George', 'egeorge1d@blogtalkradio.com', 'State of Florida DOH Central Pharmacy', '148.35.114.224'),\n('Dennis', 'Larson', 'dlarson1e@trellian.com', 'G&W Laboratories, Inc.', '134.158.117.11'),\n('Ashley', 'Peters', 'apeters1f@de.vu', 'Mylan Pharmaceuticals Inc.', '50.193.252.146'),\n('Douglas', 'Andrews', 'dandrews1g@mac.com', 'Jubilant HollisterStier LLC', '159.134.237.86'),\n('Craig', 'Dunn', 'cdunn1h@cornell.edu', 'Antigen Laboratories, Inc.', '227.11.100.112'),\n('Heather', 'Black', 'hblack1i@harvard.edu', 'Hospira, Inc.', '61.9.121.22'),\n('Shirley', 'Ruiz', 'sruiz1j@tmall.com', 'Hankuk Bowonbio Co., Ltd', '171.144.250.254'),\n('Carl', 'Martinez', 'cmartinez1k@geocities.jp', 'ALK-Abello, Inc.', '128.216.69.116'),\n('Stephen', 'Anderson', 'sanderson1l@odnoklassniki.ru', 'Cardinal Health', '145.154.63.186'),\n('Diana', 'Payne', 'dpayne1m@ftc.gov', 'Pharmaceutical Associates, Inc.', '98.9.155.136'),\n('Judy', 'Gonzalez', 'jgonzalez1n@walmart.com', 'SHISEIDO CO., LTD.', '73.96.109.149'),\n('Steve', 'Cole', 'scole1o@flickr.com', 'Walgreen Company', '251.244.20.117'),\n('Johnny', 'Ellis', 'jellis1p@time.com', 'Jubilant HollisterStier LLC', '188.153.76.182'),\n('Andrea', 'Hamilton', 'ahamilton1q@dailymail.co.uk', 'ALK-Abello, Inc.', '229.58.149.141'),\n('Sean', 'Kennedy', 'skennedy1r@nifty.com', 'Newton Laboratories, Inc.', '227.105.251.134'),\n('Sara', 'Grant', 'sgrant1s@flickr.com', 'Rubbermaid Commercial Products LLC', '96.211.162.73'),\n('Joan', 'Bennett', 'jbennett1t@forbes.com', 'Nelco Laboratories, Inc.', '143.27.240.163'),\n('Judith', 'Daniels', 'jdaniels1u@theguardian.com', 'Newton Laboratories, Inc.', '164.99.249.153'),\n('Irene', 'Bennett', 'ibennett1v@comsenz.com', 'Cellab Co., Ltd.', '112.104.12.122'),\n('Katherine', 'Perez', 'kperez1w@phpbb.com', 'Temple Industrial Welding Supply Co', '211.31.214.131'),\n('Jean', 'Kim', 'jkim1x@umich.edu', 'Bryant Ranch Prepack', '245.252.150.110'),\n('Walter', 'Hernandez', 'whernandez1y@nbcnews.com', 'Virtus Pharmaceuticals LLC', '200.201.83.21'),\n('Larry', 'Scott', 'lscott1z@quantcast.com', 'BIOKEY INC.', '122.141.109.98'),\n('Gerald', 'Palmer', 'gpalmer20@usgs.gov', 'JAFRA COSMETICS INTERNATIONAL', '60.173.159.145'),\n('Harry', 'Andrews', 'handrews21@alexa.com', 'NCS HealthCare of KY, Inc dba Vangard Labs', '210.64.37.91'),\n('Jerry', 'Morrison', 'jmorrison22@drupal.org', 'Teva Pharmaceuticals USA Inc', '83.190.174.61'),\n('Irene', 'Diaz', 'idiaz23@joomla.org', 'Dolgencorp, LLC', '214.16.44.235'),\n('Brenda', 'Hansen', 'bhansen24@wisc.edu', 'REMEDYREPACK INC.', '167.231.200.232'),\n('Carlos', 'Williamson', 'cwilliamson25@w3.org', 'Kroger Company', '251.202.210.204'),\n('David', 'Fuller', 'dfuller26@canalblog.com', 'Supervalu Inc', '175.125.205.131'),\n('Norma', 'Bishop', 'nbishop27@jugem.jp', 'Mylan Institutional Inc.', '208.162.25.149'),\n('Brenda', 'Daniels', 'bdaniels28@mediafire.com', 'Space Brands Limited', '92.235.250.138'),\n('Kathy', 'Reed', 'kreed29@prweb.com', 'Rugby Laboratories Inc.', '182.114.174.63'),\n('Anthony', 'Long', 'along2a@dropbox.com', 'Fresenius Kabi USA, LLC', '160.146.121.173'),\n('Craig', 'Palmer', 'cpalmer2b@desdev.cn', 'Bio-Pharm, Inc.', '135.77.134.24'),\n('Rachel', 'Banks', 'rbanks2c@devhub.com', 'Sam''s West Inc', '35.72.5.193'),\n('Kenneth', 'Peters', 'kpeters2d@ocn.ne.jp', 'International Labs, Inc.', '11.38.191.65'),\n('Susan', 'Clark', 'sclark2e@ed.gov', 'Shionogi Inc.', '19.243.67.80'),\n('Walter', 'Sullivan', 'wsullivan2f@vinaora.com', 'STAT Rx USA LLC', '154.137.170.227'),\n('Kathleen', 'Wood', 'kwood2g@salon.com', 'Freds Inc', '155.54.131.149'),\n('Phyllis', 'Henderson', 'phenderson2h@walmart.com', 'REMEDYREPACK INC.', '146.65.150.251'),\n('Cheryl', 'Wells', 'cwells2i@gov.uk', 'Rebel Distributors Corp', '69.127.148.31'),\n('Rose', 'Bradley', 'rbradley2j@un.org', 'Hi-Tech Pharmacal Co., Inc.', '150.101.165.102'),\n('Aaron', 'Moreno', 'amoreno2k@tinypic.com', 'Pharmacia and Upjohn Company', '50.27.226.40'),\n('Amy', 'Campbell', 'acampbell2l@auda.org.au', 'Chi Research, Inc.', '242.64.63.241'),\n('Rebecca', 'Butler', 'rbutler2m@godaddy.com', 'Cardinal Health', '40.55.159.66'),\n('Justin', 'Rodriguez', 'jrodriguez2n@meetup.com', 'Hikma Pharmaceutical', '118.9.132.156'),\n('Donald', 'Nelson', 'dnelson2o@narod.ru', 'Nature''s Way Products, Inc.', '165.174.28.134'),\n('Edward', 'Lawson', 'elawson2p@addtoany.com', 'Apotheca Company', '135.17.238.170'),\n('Paul', 'Bell', 'pbell2q@simplemachines.org', 'Washington Homeopathic Products', '235.149.137.62'),\n('Mark', 'Rose', 'mrose2r@google.pl', 'AMERICAN SALES COMPANY', '164.108.170.187');\n"
  },
  {
    "path": "tests/functional/basic/test_basic.py",
    "content": "import pytest\n\nfrom dbt.tests.util import get_manifest, run_dbt\n\nmy_model_sql = \"\"\"\n  select 1 as fun\n\"\"\"\n\n\n@pytest.fixture(scope=\"class\")\ndef models():\n    return {\"my_model.sql\": my_model_sql}\n\n\ndef test_basic(project):\n    # Tests that a project with a single model works\n    results = run_dbt([\"run\"])\n    assert len(results) == 1\n    manifest = get_manifest(project.project_root)\n    assert \"model.test.my_model\" in manifest.nodes\n"
  },
  {
    "path": "tests/functional/basic/test_invalid_reference.py",
    "content": "import pytest\n\nfrom dbt.exceptions import CompilationError\nfrom dbt.tests.util import run_dbt\n\ndescendant_sql = \"\"\"\n-- should be ref('model')\nselect * from {{ ref(model) }}\n\"\"\"\n\n\nmodel_sql = \"\"\"\nselect 1 as id\n\"\"\"\n\n\n@pytest.fixture(scope=\"class\")\ndef models():\n    return {\n        \"descendant.sql\": descendant_sql,\n        \"model.sql\": model_sql,\n    }\n\n\ndef test_undefined_value(project):\n    # Tests that a project with an invalid reference fails\n    with pytest.raises(CompilationError):\n        run_dbt([\"compile\"])\n"
  },
  {
    "path": "tests/functional/basic/test_jaffle_shop.py",
    "content": "from dbt.tests.util import get_manifest, run_dbt, run_dbt_and_capture, write_file\nfrom tests.fixtures.jaffle_shop import JaffleShopProject\n\n\nclass TestBasic(JaffleShopProject):\n    def test_basic(self, project):\n        # test .dbtignore works\n        write_file(\"models/ignore*.sql\\nignore_folder\", project.project_root, \".dbtignore\")\n        # Create the data from seeds\n        results = run_dbt([\"seed\"])\n\n        # Tests that the jaffle_shop project runs\n        results = run_dbt([\"run\"])\n        assert len(results) == 5\n        manifest = get_manifest(project.project_root)\n        assert \"model.jaffle_shop.orders\" in manifest.nodes\n\n    def test_execution_time_format_is_humanized(self, project):\n        # Create the data from seeds\n        run_dbt([\"seed\"])\n        _, log_output = run_dbt_and_capture([\"run\"])\n\n        assert \" in 0 hours 0 minutes and \" in log_output\n        assert \" seconds\" in log_output\n"
  },
  {
    "path": "tests/functional/basic/test_mixed_case_db.py",
    "content": "import pytest\n\nfrom dbt.tests.util import get_manifest, run_dbt\n\nmodel_sql = \"\"\"\n  select 1 as id\n\"\"\"\n\n\n@pytest.fixture(scope=\"class\")\ndef models():\n    return {\"model.sql\": model_sql}\n\n\n@pytest.fixture(scope=\"class\")\ndef dbt_profile_data(unique_schema):\n\n    return {\n        \"test\": {\n            \"outputs\": {\n                \"default\": {\n                    \"type\": \"postgres\",\n                    \"threads\": 4,\n                    \"host\": \"localhost\",\n                    \"port\": 5432,\n                    \"user\": \"root\",\n                    \"pass\": \"password\",\n                    \"dbname\": \"dbtMixedCase\",\n                    \"schema\": unique_schema,\n                },\n            },\n            \"target\": \"default\",\n        },\n    }\n\n\ndef test_basic(project_root, project):\n\n    assert project.database == \"dbtMixedCase\"\n\n    # Tests that a project with a single model works\n    results = run_dbt([\"run\"])\n    assert len(results) == 1\n    manifest = get_manifest(project_root)\n    assert \"model.test.model\" in manifest.nodes\n    # Running a second time works\n    results = run_dbt([\"run\"])\n"
  },
  {
    "path": "tests/functional/basic/test_project.py",
    "content": "import os\nfrom pathlib import Path\n\nimport pytest\nimport yaml\n\nfrom dbt.cli.main import dbtRunner\nfrom dbt.exceptions import DbtProjectError, ProjectContractError\nfrom dbt.tests.util import run_dbt, update_config_file, write_config_file\n\nsimple_model_sql = \"\"\"\nselect true as my_column\n\"\"\"\n\nsimple_model_yml = \"\"\"\nmodels:\n  - name: simple_model\n    description: \"is sythentic data ok? my column:\"\n    columns:\n      - name: my_column\n        description: asked and answered\n\"\"\"\n\n\nclass TestSchemaYmlVersionMissing:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"simple_model.sql\": simple_model_sql, \"simple_model.yml\": simple_model_yml}\n\n    def test_empty_version(self, project):\n        run_dbt([\"run\"], expect_pass=True)\n\n\nclass TestProjectConfigVersionMissing:\n    # default dbt_project.yml has config-version: 2\n    @pytest.fixture(scope=\"class\")\n    def project_config_remove(self):\n        return [\"config-version\"]\n\n    def test_empty_version(self, project):\n        run_dbt([\"run\"], expect_pass=True)\n\n\nclass TestProjectYamlVersionMissing:\n    # default dbt_project.yml does not fill version\n\n    def test_empty_version(self, project):\n        run_dbt([\"run\"], expect_pass=True)\n\n\nclass TestProjectYamlVersionValid:\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\"version\": \"1.0.0\"}\n\n    def test_valid_version(self, project):\n        run_dbt([\"run\"], expect_pass=True)\n\n\nclass TestProjectYamlVersionInvalid:\n    def test_invalid_version(self, project):\n        # we need to run it so the project gets set up first, otherwise we hit the semver error in setting up the test project\n        run_dbt()\n        update_config_file({\"version\": \"invalid\"}, \"dbt_project.yml\")\n        with pytest.raises(ProjectContractError) as excinfo:\n            run_dbt()\n        assert \"at path ['version']: 'invalid' is not valid under any of the given schemas\" in str(\n            excinfo.value\n        )\n\n\nclass TestProjectDbtCloudConfig:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"simple_model.sql\": simple_model_sql, \"simple_model.yml\": simple_model_yml}\n\n    def test_dbt_cloud(self, project):\n        run_dbt([\"parse\"], expect_pass=True)\n        conf = yaml.safe_load(\n            Path(os.path.join(project.project_root, \"dbt_project.yml\")).read_text()\n        )\n        assert conf == {\n            \"name\": \"test\",\n            \"profile\": \"test\",\n            \"flags\": {\"send_anonymous_usage_stats\": False},\n        }\n\n        config = {\n            \"name\": \"test\",\n            \"profile\": \"test\",\n            \"flags\": {\"send_anonymous_usage_stats\": False},\n            \"dbt-cloud\": {\n                \"account_id\": \"123\",\n                \"application\": \"test\",\n                \"environment\": \"test\",\n                \"api_key\": \"test\",\n            },\n        }\n        write_config_file(config, project.project_root, \"dbt_project.yml\")\n        run_dbt([\"parse\"], expect_pass=True)\n        conf = yaml.safe_load(\n            Path(os.path.join(project.project_root, \"dbt_project.yml\")).read_text()\n        )\n        assert conf == config\n\n\nclass TestProjectDbtCloudConfigString:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"simple_model.sql\": simple_model_sql, \"simple_model.yml\": simple_model_yml}\n\n    def test_dbt_cloud_invalid(self, project):\n        run_dbt()\n        config = {\"name\": \"test\", \"profile\": \"test\", \"dbt-cloud\": \"Some string\"}\n        update_config_file(config, \"dbt_project.yml\")\n        expected_err = (\n            \"at path ['dbt-cloud']: 'Some string' is not valid under any of the given schemas\"\n        )\n        with pytest.raises(ProjectContractError) as excinfo:\n            run_dbt()\n        assert expected_err in str(excinfo.value)\n\n\nclass TestVersionSpecifierChecksComeBeforeYamlValidation:\n    def test_version_specifier_checks_before_yaml_validation(self, project) -> None:\n        runner = dbtRunner()\n\n        # if no version specifier error, we should get a yaml validation error\n        config_update = {\"this-is-not-a-valid-key\": \"my-value-for-invalid-key\"}\n        update_config_file(config_update, \"dbt_project.yml\")\n        result = runner.invoke([\"parse\"])\n        assert result.exception is not None\n        assert isinstance(result.exception, ProjectContractError)\n        assert \"Additional properties are not allowed\" in str(result.exception)\n\n        # add bad version specifier, and assert we get the error for that\n        update_config_file({\"require-dbt-version\": [\">0.0.0\", \"<=0.0.1\"]}, \"dbt_project.yml\")\n        result = runner.invoke([\"parse\"])\n        assert result.exception is not None\n        assert isinstance(result.exception, DbtProjectError)\n        assert \"This version of dbt is not supported\"\n\n\nclass TestArchiveNotAllowed:\n    \"\"\"At one point in time we supported an 'archive' key in projects, but no longer\"\"\"\n\n    def test_archive_not_allowed(self, project):\n        runner = dbtRunner()\n\n        config_update = {\n            \"archive\": {\n                \"source_schema\": \"a\",\n                \"target_schema\": \"b\",\n                \"tables\": [\n                    {\n                        \"source_table\": \"seed\",\n                        \"target_table\": \"archive_actual\",\n                        \"updated_at\": \"updated_at\",\n                        \"unique_key\": \"\"\"id || '-' || first_name\"\"\",\n                    },\n                ],\n            }\n        }\n        update_config_file(config_update, \"dbt_project.yml\")\n\n        result = runner.invoke([\"parse\"])\n        assert result.exception is not None\n        assert isinstance(result.exception, ProjectContractError)\n        assert \"Additional properties are not allowed\" in str(result.exception)\n"
  },
  {
    "path": "tests/functional/basic/test_simple_reference.py",
    "content": "import pytest\n\nfrom dbt.tests.util import check_relations_equal, copy_file, read_file, run_dbt\n\nephemeral_copy_sql = \"\"\"\n{{\n  config(\n    materialized = \"ephemeral\"\n  )\n}}\n\nselect * from {{ this.schema }}.users\n\"\"\"\n\nephemeral_summary_sql = \"\"\"\n{{\n  config(\n    materialized = \"table\"\n  )\n}}\n\nselect gender, count(*) as ct from {{ref('ephemeral_copy')}}\ngroup by gender\norder by gender asc\n\"\"\"\n\nincremental_copy_sql = \"\"\"\n{{\n  config(\n    materialized = \"incremental\"\n  )\n}}\n\nselect * from {{ this.schema }}.users\n\n{% if is_incremental() %}\n\n    where id > (select max(id) from {{this}})\n\n{% endif %}\n\"\"\"\n\nincremental_summary_sql = \"\"\"\n{{\n  config(\n    materialized = \"table\",\n  )\n}}\n\nselect gender, count(*) as ct from {{ref('incremental_copy')}}\ngroup by gender\norder by gender asc\n\"\"\"\n\nmaterialized_copy_sql = \"\"\"\n{{\n  config(\n    materialized = \"table\"\n  )\n}}\n\nselect * from {{ this.schema }}.users\n\"\"\"\n\nmaterialized_summary_sql = \"\"\"\n{{\n  config(\n    materialized = \"table\"\n  )\n}}\n\nselect gender, count(*) as ct from {{ref('materialized_copy')}}\ngroup by gender\norder by gender asc\n\"\"\"\n\nview_copy_sql = \"\"\"\n{{\n  config(\n    materialized = \"view\"\n  )\n}}\n\nselect * from {{ this.schema }}.users\n\"\"\"\n\nview_summary_sql = \"\"\"\n{{\n  config(\n    materialized = \"view\"\n  )\n}}\n\nselect gender, count(*) as ct from {{ref('view_copy')}}\ngroup by gender\norder by gender asc\n\"\"\"\n\nview_using_ref_sql = \"\"\"\n{{\n  config(\n    materialized = \"view\"\n  )\n}}\n\nselect gender, count(*) as ct from {{ var('var_ref') }}\ngroup by gender\norder by gender asc\n\"\"\"\n\nproperties_yml = \"\"\"\nversion: 2\nseeds:\n  - name: summary_expected\n    config:\n      column_types:\n        ct: BIGINT\n        gender: text\n\"\"\"\n\n\n@pytest.fixture(scope=\"class\")\ndef models():\n    return {\n        \"ephemeral_copy.sql\": ephemeral_copy_sql,\n        \"ephemeral_summary.sql\": ephemeral_summary_sql,\n        \"incremental_copy.sql\": incremental_copy_sql,\n        \"incremental_summary.sql\": incremental_summary_sql,\n        \"materialized_copy.sql\": materialized_copy_sql,\n        \"materialized_summary.sql\": materialized_summary_sql,\n        \"view_copy.sql\": view_copy_sql,\n        \"view_summary.sql\": view_summary_sql,\n        \"view_using_ref.sql\": view_using_ref_sql,\n    }\n\n\n@pytest.fixture(scope=\"class\")\ndef seeds(test_data_dir):\n    # Read seed file and return\n    seeds = {\"properties.yml\": properties_yml}\n    seed_csv = read_file(test_data_dir, \"seed-initial.csv\")\n    seeds[\"users.csv\"] = seed_csv\n    summary_csv = read_file(test_data_dir, \"summary_expected.csv\")\n    seeds[\"summary_expected.csv\"] = summary_csv\n    return seeds\n\n\n@pytest.fixture(scope=\"class\")\ndef project_config_update():\n    return {\n        \"vars\": {\n            \"test\": {\n                \"var_ref\": '{{ ref(\"view_copy\") }}',\n            },\n        },\n        \"seeds\": {\"quote_columns\": False},\n    }\n\n\n# This test checks that with different materializations we get the right\n# tables copied or built.\ndef test_simple_reference(project):\n    results = run_dbt([\"seed\"])\n    assert len(results) == 2\n\n    # Now run dbt\n    results = run_dbt()\n    assert len(results) == 8\n\n    # Copies should match\n    check_relations_equal(\n        project.adapter, [\"users\", \"incremental_copy\", \"materialized_copy\", \"view_copy\"]\n    )\n\n    # Summaries should match\n    check_relations_equal(\n        project.adapter,\n        [\n            \"summary_expected\",\n            \"incremental_summary\",\n            \"materialized_summary\",\n            \"view_summary\",\n            \"ephemeral_summary\",\n            \"view_using_ref\",\n        ],\n    )\n\n    # update the seed files and run seed\n    copy_file(\n        project.test_data_dir, \"seed-update.csv\", project.project_root, [\"seeds\", \"users.csv\"]\n    )\n    copy_file(\n        project.test_data_dir,\n        \"summary_expected_update.csv\",\n        project.project_root,\n        [\"seeds\", \"summary_expected.csv\"],\n    )\n    results = run_dbt([\"seed\"])\n    assert len(results) == 2\n\n    results = run_dbt()\n    assert len(results) == 8\n\n    # Copies should match\n    check_relations_equal(\n        project.adapter, [\"users\", \"incremental_copy\", \"materialized_copy\", \"view_copy\"]\n    )\n\n    # Summaries should match\n    check_relations_equal(\n        project.adapter,\n        [\n            \"summary_expected\",\n            \"incremental_summary\",\n            \"materialized_summary\",\n            \"view_summary\",\n            \"ephemeral_summary\",\n            \"view_using_ref\",\n        ],\n    )\n\n\ndef test_simple_reference_with_models_and_children(project):\n    results = run_dbt([\"seed\"])\n    assert len(results) == 2\n\n    # Run materialized_copy, ephemeral_copy, and their dependents\n    results = run_dbt([\"run\", \"--models\", \"materialized_copy+\", \"ephemeral_copy+\"])\n    assert len(results) == 3\n\n    # Copies should match\n    check_relations_equal(project.adapter, [\"users\", \"materialized_copy\"])\n\n    # Summaries should match\n    check_relations_equal(\n        project.adapter, [\"summary_expected\", \"materialized_summary\", \"ephemeral_summary\"]\n    )\n\n    created_tables = project.get_tables_in_schema()\n\n    assert \"incremental_copy\" not in created_tables\n    assert \"incremental_summary\" not in created_tables\n    assert \"view_copy\" not in created_tables\n    assert \"view_summary\" not in created_tables\n\n    # make sure this wasn't errantly materialized\n    assert \"ephemeral_copy\" not in created_tables\n\n    assert \"materialized_copy\" in created_tables\n    assert \"materialized_summary\" in created_tables\n    assert created_tables[\"materialized_copy\"] == \"table\"\n    assert created_tables[\"materialized_summary\"] == \"table\"\n\n    assert \"ephemeral_summary\" in created_tables\n    assert created_tables[\"ephemeral_summary\"] == \"table\"\n\n\ndef test_simple_ref_with_models(project):\n    results = run_dbt([\"seed\"])\n    assert len(results) == 2\n\n    # Run materialized_copy, ephemeral_copy, and their dependents\n    # ephemeral_copy should not actually be materialized b/c it is ephemeral\n    results = run_dbt([\"run\", \"--models\", \"materialized_copy\", \"ephemeral_copy\"])\n    assert len(results) == 1\n\n    # Copies should match\n    check_relations_equal(project.adapter, [\"users\", \"materialized_copy\"])\n\n    created_tables = project.get_tables_in_schema()\n    assert \"materialized_copy\" in created_tables\n"
  },
  {
    "path": "tests/functional/basic/test_varchar_widening.py",
    "content": "import os\n\nimport pytest\n\nfrom dbt.tests.util import check_relations_equal, run_dbt\n\nincremental_sql = \"\"\"\n{{\n  config(\n    materialized = \"incremental\"\n  )\n}}\n\nselect * from {{ this.schema }}.seed\n\n{% if is_incremental() %}\n\n    where id > (select max(id) from {{this}})\n\n{% endif %}\n\"\"\"\n\nmaterialized_sql = \"\"\"\n{{\n  config(\n    materialized = \"table\"\n  )\n}}\n\nselect * from {{ this.schema }}.seed\n\"\"\"\n\n\n@pytest.fixture(scope=\"class\")\ndef models():\n    return {\"incremental.sql\": incremental_sql, \"materialized.sql\": materialized_sql}\n\n\ndef test_varchar_widening(project):\n    path = os.path.join(project.test_data_dir, \"varchar10_seed.sql\")\n    project.run_sql_file(path)\n\n    results = run_dbt([\"run\"])\n    assert len(results) == 2\n\n    check_relations_equal(project.adapter, [\"seed\", \"incremental\"])\n    check_relations_equal(project.adapter, [\"seed\", \"materialized\"])\n\n    path = os.path.join(project.test_data_dir, \"varchar300_seed.sql\")\n    project.run_sql_file(path)\n\n    results = run_dbt([\"run\"])\n    assert len(results) == 2\n\n    check_relations_equal(project.adapter, [\"seed\", \"incremental\"])\n    check_relations_equal(project.adapter, [\"seed\", \"materialized\"])\n"
  },
  {
    "path": "tests/functional/build_command/fixtures.py",
    "content": "seeds__country_csv = \"\"\"iso3,name,iso2,iso_numeric,cow_alpha,cow_numeric,fao_code,un_code,wb_code,imf_code,fips,geonames_name,geonames_id,r_name,aiddata_name,aiddata_code,oecd_name,oecd_code,historical_name,historical_iso3,historical_iso2,historical_iso_numeric\nABW,Aruba,AW,533,,,,533,ABW,314,AA,Aruba,3577279,ARUBA,Aruba,12,Aruba,373,,,,\nAFG,Afghanistan,AF,4,AFG,700,2,4,AFG,512,AF,Afghanistan,1149361,AFGHANISTAN,Afghanistan,1,Afghanistan,625,,,,\nAGO,Angola,AO,24,ANG,540,7,24,AGO,614,AO,Angola,3351879,ANGOLA,Angola,7,Angola,225,,,,\nAIA,Anguilla,AI,660,,,,660,AIA,312,AV,Anguilla,3573511,ANGUILLA,Anguilla,8,Anguilla,376,,,,\nALA,Aland Islands,AX,248,,,,248,ALA,,,Aland Islands,661882,ALAND ISLANDS,,,,,,,,\nALB,Albania,AL,8,ALB,339,3,8,ALB,914,AL,Albania,783754,ALBANIA,Albania,3,Albania,71,,,,\nAND,Andorra,AD,20,AND,232,6,20,ADO,,AN,Andorra,3041565,ANDORRA,,,,,,,,\nANT,Netherlands Antilles,AN,530,,,,,ANT,353,NT,Netherlands Antilles,,NETHERLANDS ANTILLES,Netherlands Antilles,211,Netherlands Antilles,361,Netherlands Antilles,ANT,AN,530\nARE,United Arab Emirates,AE,784,UAE,696,225,784,ARE,466,AE,United Arab Emirates,290557,UNITED ARAB EMIRATES,United Arab Emirates,140,United Arab Emirates,576,,,,\n\"\"\"\n\nsnapshots__snap_0 = \"\"\"\n{% snapshot snap_0 %}\n\n{{\n    config(\n      target_database=database,\n      target_schema=schema,\n      unique_key='iso3',\n\n      strategy='timestamp',\n      updated_at='snap_0_updated_at',\n    )\n}}\n\nselect *, current_timestamp as snap_0_updated_at from {{ ref('model_0') }}\n\n{% endsnapshot %}\n\"\"\"\n\nsnapshots__snap_1 = \"\"\"\n{% snapshot snap_1 %}\n\n{{\n    config(\n      target_database=database,\n      target_schema=schema,\n      unique_key='iso3',\n\n      strategy='timestamp',\n      updated_at='snap_1_updated_at',\n    )\n}}\n\nSELECT\n  iso3,\n  name,\n  iso2,\n  iso_numeric,\n  cow_alpha,\n  cow_numeric,\n  fao_code,\n  un_code,\n  wb_code,\n  imf_code,\n  fips,\n  geonames_name,\n  geonames_id,\n  r_name,\n  aiddata_name,\n  aiddata_code,\n  oecd_name,\n  oecd_code,\n  historical_name,\n  historical_iso3,\n  historical_iso2,\n  historical_iso_numeric,\n  current_timestamp as snap_1_updated_at from {{ ref('model_1') }}\n\n{% endsnapshot %}\n\"\"\"\n\nsnapshots__snap_99 = \"\"\"\n{% snapshot snap_99 %}\n\n{{\n    config(\n      target_database=database,\n      target_schema=schema,\n      strategy='timestamp',\n      unique_key='num',\n      updated_at='snap_99_updated_at',\n    )\n}}\n\nselect *, current_timestamp as snap_99_updated_at from {{ ref('model_99') }}\n\n{% endsnapshot %}\n\"\"\"\n\nmodels__model_0_sql = \"\"\"\n{{ config(materialized='table') }}\n\nselect * from {{ ref('countries') }}\n\"\"\"\n\nmodels__model_1_sql = \"\"\"\n{{ config(materialized='table') }}\n\nselect * from {{ ref('snap_0') }}\n\"\"\"\n\nmodels__model_2_sql = \"\"\"\n{{ config(materialized='table') }}\n\nselect * from {{ ref('snap_1') }}\n\"\"\"\n\nmodels__model_3_sql = \"\"\"\n{{ config(materialized='table') }}\n\nselect * from {{ ref('model_1') }}\n\"\"\"\n\nmodels__model_99_sql = \"\"\"\n{{ config(materialized='table') }}\n\nselect '1' as \"num\"\n\"\"\"\n\nmodels__test_yml = \"\"\"\nversion: 2\n\nmodels:\n  - name: model_0\n    columns:\n      - name: iso3\n        data_tests:\n          - unique\n          - not_null\n  - name: model_2\n    columns:\n      - name: iso3\n        data_tests:\n          - unique\n          - not_null\n\"\"\"\n\nunit_tests__yml = \"\"\"\nunit_tests:\n  - name: ut_model_3\n    model: model_3\n    given:\n      - input: ref('model_1')\n        rows:\n          - {iso3: ABW, name: Aruba}\n    expect:\n      rows:\n        - {iso3: ABW, name: Aruba}\n\"\"\"\n\nmodels_failing_tests__tests_yml = \"\"\"\nversion: 2\n\nmodels:\n  - name: model_0\n    columns:\n      - name: iso3\n        data_tests:\n          - unique\n          - not_null\n      - name: historical_iso_numeric\n        data_tests:\n          - not_null\n  - name: model_2\n    columns:\n      - name: iso3\n        data_tests:\n          - unique\n          - not_null\n\"\"\"\n\nmodels_failing__model_1_sql = \"\"\"\n{{ config(materialized='table') }}\n\nselect bad_column from {{ ref('snap_0') }}\n\"\"\"\n\n\nmodels_circular_relationship__test_yml = \"\"\"\nversion: 2\n\nmodels:\n  - name: model_0\n    columns:\n      - name: iso3\n        data_tests:\n          - relationships:\n              to: ref('model_1')\n              field: iso3\n\n  - name: model_1\n    columns:\n      - name: iso3\n        data_tests:\n          - relationships:\n              to: ref('model_0')\n              field: iso3\n\n\"\"\"\n\nmodels_simple_blocking__model_a_sql = \"\"\"\nselect null as id\n\"\"\"\n\nmodels_simple_blocking__model_b_sql = \"\"\"\nselect * from {{ ref('model_a') }}\n\"\"\"\n\nmodels_simple_blocking__test_yml = \"\"\"\nversion: 2\n\nmodels:\n  - name: model_a\n    columns:\n      - name: id\n        data_tests:\n          - not_null\n\"\"\"\n\nmodels_triple_blocking__test_yml = \"\"\"\nversion: 2\n\nmodels:\n  - name: model_a\n    columns:\n      - name: id\n        data_tests:\n          - not_null\n  - name: model_b\n    columns:\n      - name: id\n        data_tests:\n          - not_null\n  - name: model_c\n    columns:\n      - name: id\n        data_tests:\n          - not_null\n\"\"\"\n\nmodels_interdependent__model_a_sql = \"\"\"\nselect 1 as id\n\"\"\"\n\nmodels_interdependent__model_b_sql = \"\"\"\nselect * from {{ ref('model_a') }}\n\"\"\"\n\nmodels_interdependent__model_b_null_sql = \"\"\"\nselect null from {{ ref('model_a') }}\n\"\"\"\n\n\nmodels_interdependent__model_c_sql = \"\"\"\nselect * from {{ ref('model_b') }}\n\"\"\"\n\nmodels_interdependent__test_yml = \"\"\"\nversion: 2\n\nmodels:\n  - name: model_a\n    columns:\n      - name: id\n        data_tests:\n          - unique\n          - not_null\n          - relationships:\n              to: ref('model_b')\n              field: id\n          - relationships:\n              to: ref('model_c')\n              field: id\n\n  - name: model_b\n    columns:\n      - name: id\n        data_tests:\n          - unique\n          - not_null\n          - relationships:\n              to: ref('model_a')\n              field: id\n          - relationships:\n              to: ref('model_c')\n              field: id\n\n  - name: model_c\n    columns:\n      - name: id\n        data_tests:\n          - unique\n          - not_null\n          - relationships:\n              to: ref('model_a')\n              field: id\n          - relationships:\n              to: ref('model_b')\n              field: id\n\"\"\"\n"
  },
  {
    "path": "tests/functional/build_command/test_build.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt\nfrom tests.functional.build_command.fixtures import (\n    models__model_0_sql,\n    models__model_1_sql,\n    models__model_2_sql,\n    models__model_3_sql,\n    models__model_99_sql,\n    models__test_yml,\n    models_circular_relationship__test_yml,\n    models_failing__model_1_sql,\n    models_failing_tests__tests_yml,\n    models_interdependent__model_a_sql,\n    models_interdependent__model_b_null_sql,\n    models_interdependent__model_b_sql,\n    models_interdependent__model_c_sql,\n    models_interdependent__test_yml,\n    models_simple_blocking__model_a_sql,\n    models_simple_blocking__model_b_sql,\n    models_simple_blocking__test_yml,\n    models_triple_blocking__test_yml,\n    seeds__country_csv,\n    snapshots__snap_0,\n    snapshots__snap_1,\n    snapshots__snap_99,\n    unit_tests__yml,\n)\n\n\nclass TestBuildBase:\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\"countries.csv\": seeds__country_csv}\n\n    @pytest.fixture(scope=\"class\")\n    def snapshots(self):\n        return {\n            \"snap_0.sql\": snapshots__snap_0,\n            \"snap_1.sql\": snapshots__snap_1,\n            \"snap_99.sql\": snapshots__snap_99,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"seeds\": {\n                \"quote_columns\": False,\n            },\n        }\n\n\nclass TestPassingBuild(TestBuildBase):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_0.sql\": models__model_0_sql,\n            \"model_1.sql\": models__model_1_sql,\n            \"model_2.sql\": models__model_2_sql,\n            \"model_3.sql\": models__model_3_sql,\n            \"model_99.sql\": models__model_99_sql,\n            \"test.yml\": models__test_yml + unit_tests__yml,\n        }\n\n    def test_build_happy_path(self, project):\n        run_dbt([\"build\"])\n\n\nclass TestFailingBuild(TestBuildBase):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_0.sql\": models__model_0_sql,\n            \"model_1.sql\": models_failing__model_1_sql,\n            \"model_2.sql\": models__model_2_sql,\n            \"model_3.sql\": models__model_3_sql,\n            \"model_99.sql\": models__model_99_sql,\n            \"test.yml\": models__test_yml + unit_tests__yml,\n        }\n\n    def test_failing_test_skips_downstream(self, project):\n        results = run_dbt([\"build\"], expect_pass=False)\n        assert len(results) == 14\n        actual = [str(r.status) for r in results]\n        expected = [\"error\"] * 1 + [\"skipped\"] * 6 + [\"pass\"] * 2 + [\"success\"] * 5\n\n        assert sorted(actual) == sorted(expected)\n\n\nclass TestFailingTestsBuild(TestBuildBase):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_0.sql\": models__model_0_sql,\n            \"model_1.sql\": models__model_1_sql,\n            \"model_2.sql\": models__model_2_sql,\n            \"model_99.sql\": models__model_99_sql,\n            \"test.yml\": models_failing_tests__tests_yml,\n        }\n\n    def test_failing_test_skips_downstream(self, project):\n        results = run_dbt([\"build\"], expect_pass=False)\n        assert len(results) == 13\n        actual = [str(r.status) for r in results]\n        expected = [\"fail\"] + [\"skipped\"] * 6 + [\"pass\"] * 2 + [\"success\"] * 4\n        assert sorted(actual) == sorted(expected)\n\n\nclass TestCircularRelationshipTestsBuild(TestBuildBase):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_0.sql\": models__model_0_sql,\n            \"model_1.sql\": models__model_1_sql,\n            \"model_99.sql\": models__model_99_sql,\n            \"test.yml\": models_circular_relationship__test_yml,\n        }\n\n    def test_circular_relationship_test_success(self, project):\n        \"\"\"Ensure that tests that refer to each other's model don't create\n        a circular dependency.\"\"\"\n        results = run_dbt([\"build\"])\n        actual = [str(r.status) for r in results]\n        expected = [\"success\"] * 7 + [\"pass\"] * 2\n\n        assert sorted(actual) == sorted(expected)\n\n\nclass TestSimpleBlockingTest:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_a.sql\": models_simple_blocking__model_a_sql,\n            \"model_b.sql\": models_simple_blocking__model_b_sql,\n            \"test.yml\": models_simple_blocking__test_yml,\n        }\n\n    def test_simple_blocking_test(self, project):\n        \"\"\"Ensure that a failed test on model_a always blocks model_b\"\"\"\n        results = run_dbt([\"build\"], expect_pass=False)\n        actual = [r.status for r in results]\n        expected = [\"success\", \"fail\", \"skipped\"]\n        assert sorted(actual) == sorted(expected)\n\n\nclass TestInterdependentModels:\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\"countries.csv\": seeds__country_csv}\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"seeds\": {\n                \"quote_columns\": False,\n            },\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_a.sql\": models_interdependent__model_a_sql,\n            \"model_b.sql\": models_interdependent__model_b_sql,\n            \"model_c.sql\": models_interdependent__model_c_sql,\n            \"test.yml\": models_interdependent__test_yml,\n        }\n\n    def test_interdependent_models(self, project):\n        results = run_dbt([\"build\"])\n        assert len(results) == 16\n\n\nclass TestInterdependentModelsFail:\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\"countries.csv\": seeds__country_csv}\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"seeds\": {\n                \"quote_columns\": False,\n            },\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_a.sql\": models_interdependent__model_a_sql,\n            \"model_b.sql\": models_interdependent__model_b_null_sql,\n            \"model_c.sql\": models_interdependent__model_c_sql,\n            \"test.yml\": models_interdependent__test_yml,\n        }\n\n    def test_interdependent_models_fail(self, project):\n        results = run_dbt([\"build\"], expect_pass=False)\n        assert len(results) == 16\n\n        actual = [str(r.status) for r in results]\n        expected = [\"error\"] * 4 + [\"skipped\"] * 7 + [\"pass\"] * 2 + [\"success\"] * 3\n        assert sorted(actual) == sorted(expected)\n\n\nclass TestDownstreamSelection:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_a.sql\": models_simple_blocking__model_a_sql,\n            \"model_b.sql\": models_simple_blocking__model_b_sql,\n            \"test.yml\": models_simple_blocking__test_yml,\n        }\n\n    def test_downstream_selection(self, project):\n        \"\"\"Ensure that selecting test+ does not select model_a's other children\"\"\"\n        # fails with \"Got 1 result, configured to fail if != 0\"\n        # model_a is defined as select null as id\n        results = run_dbt([\"build\", \"--select\", \"model_a not_null_model_a_id+\"], expect_pass=False)\n        assert len(results) == 2\n\n\nclass TestLimitedUpstreamSelection:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_a.sql\": models_interdependent__model_a_sql,\n            \"model_b.sql\": models_interdependent__model_b_sql,\n            \"model_c.sql\": models_interdependent__model_c_sql,\n            \"test.yml\": models_triple_blocking__test_yml,\n        }\n\n    def test_limited_upstream_selection(self, project):\n        \"\"\"Ensure that selecting 1+model_c only selects up to model_b (+ tests of both)\"\"\"\n        # Fails with \"relation \"test17005969872609282880_test_build.model_a\" does not exist\"\n        results = run_dbt([\"build\", \"--select\", \"1+model_c\"], expect_pass=False)\n        assert len(results) == 4\n"
  },
  {
    "path": "tests/functional/catalogs/test_catalogs_parsing.py",
    "content": "from unittest import mock\n\nimport pytest\n\nfrom dbt.adapters.catalogs import CatalogIntegration, CatalogIntegrationConfig\nfrom dbt.tests.util import run_dbt, write_config_file\nfrom dbt_common.exceptions import DbtValidationError\n\nwrite_integration_1 = {\n    \"name\": \"write_integration_1\",\n    \"external_volume\": \"write_external_volume\",\n    \"table_format\": \"write_format\",\n    \"catalog_type\": \"write\",\n    \"adapter_properties\": {\"my_custom_property\": \"foo_1\"},\n}\n\nwrite_integration_2 = {\n    \"name\": \"write_integration_2\",\n    \"external_volume\": \"write_external_volume\",\n    \"table_format\": \"write_format\",\n    \"catalog_type\": \"write\",\n    \"adapter_properties\": {\"my_custom_property\": \"foo_2\"},\n}\n\n\nclass WriteCatalogIntegration(CatalogIntegration):\n    catalog_type = \"write\"\n    allows_writes = True\n\n    def __init__(self, config: CatalogIntegrationConfig):\n        super().__init__(config)\n        for key, value in config.adapter_properties.items():\n            setattr(self, key, value)\n\n\nclass TestSingleWriteIntegration:\n    @pytest.fixture\n    def catalogs(self):\n        return {\n            \"catalogs\": [\n                {\"name\": \"write_catalog_1\", \"write_integrations\": [write_integration_1]},\n                {\"name\": \"write_catalog_2\", \"write_integrations\": [write_integration_2]},\n            ]\n        }\n\n    def test_integration(self, project, catalogs, adapter):\n        write_config_file(catalogs, project.project_root, \"catalogs.yml\")\n\n        with mock.patch.object(\n            type(project.adapter), \"CATALOG_INTEGRATIONS\", [WriteCatalogIntegration]\n        ):\n            run_dbt([\"run\"])\n\n            for i in range(1, 3):\n                write_integration = project.adapter.get_catalog_integration(f\"write_catalog_{i}\")\n                assert isinstance(write_integration, WriteCatalogIntegration)\n                assert write_integration.name == f\"write_catalog_{i}\"\n                assert write_integration.catalog_type == \"write\"\n                assert write_integration.catalog_name == f\"write_integration_{i}\"\n                assert write_integration.table_format == \"write_format\"\n                assert write_integration.external_volume == \"write_external_volume\"\n                assert write_integration.allows_writes is True\n                assert write_integration.my_custom_property == f\"foo_{i}\"\n\n\nclass TestMultipleWriteIntegration:\n    @pytest.fixture\n    def catalogs(self):\n        return {\n            \"catalogs\": [\n                {\n                    \"name\": \"write_catalog\",\n                    \"write_integrations\": [write_integration_1, write_integration_2],\n                    \"active_write_integration\": \"write_integration_2\",\n                },\n            ]\n        }\n\n    def test_integration(self, project, catalogs, adapter):\n        write_config_file(catalogs, project.project_root, \"catalogs.yml\")\n\n        with mock.patch.object(\n            type(project.adapter), \"CATALOG_INTEGRATIONS\", [WriteCatalogIntegration]\n        ):\n            run_dbt([\"build\"])\n\n            write_integration = project.adapter.get_catalog_integration(\"write_catalog\")\n            assert write_integration.name == \"write_catalog\"\n            assert write_integration.catalog_name == \"write_integration_2\"\n            assert write_integration.my_custom_property == \"foo_2\"\n\n\nclass TestNoActiveWriteIntegration:\n    @pytest.fixture\n    def catalogs(self):\n        return {\n            \"catalogs\": [\n                {\n                    \"name\": \"write_catalog\",\n                    \"write_integrations\": [write_integration_1, write_integration_2],\n                },\n            ]\n        }\n\n    def test_integration(self, project, catalogs, adapter):\n        write_config_file(catalogs, project.project_root, \"catalogs.yml\")\n\n        with mock.patch.object(\n            type(project.adapter), \"CATALOG_INTEGRATIONS\", [WriteCatalogIntegration]\n        ):\n            error_msg = \"Catalog 'write_catalog' must specify an 'active_write_integration' when multiple 'write_integrations' are provided.\"\n            with pytest.raises(DbtValidationError, match=error_msg):\n                run_dbt([\"run\"])\n\n\nclass TestInvalidWriteIntegration:\n    @pytest.fixture\n    def catalogs(self):\n        return {\n            \"catalogs\": [\n                {\n                    \"name\": \"write_catalog\",\n                    \"write_integrations\": [write_integration_1, write_integration_2],\n                    \"active_write_integration\": \"write_integration_3\",\n                },\n            ]\n        }\n\n    def test_integration(self, project, catalogs, adapter):\n        write_config_file(catalogs, project.project_root, \"catalogs.yml\")\n\n        with mock.patch.object(\n            type(project.adapter), \"CATALOG_INTEGRATIONS\", [WriteCatalogIntegration]\n        ):\n            error_msg = \"Catalog 'write_catalog' must specify an 'active_write_integration' from its set of defined 'write_integrations'\"\n            with pytest.raises(DbtValidationError, match=error_msg):\n                run_dbt([\"run\"])\n\n\nclass TestDuplicateWriteIntegration:\n    @pytest.fixture\n    def catalogs(self):\n        return {\n            \"catalogs\": [\n                {\n                    \"name\": \"write_catalog\",\n                    \"write_integrations\": [write_integration_1, write_integration_1],\n                    \"active_write_integration\": \"write_integration_1\",\n                },\n            ]\n        }\n\n    def test_integration(self, project, catalogs, adapter):\n        write_config_file(catalogs, project.project_root, \"catalogs.yml\")\n\n        with mock.patch.object(\n            type(project.adapter), \"CATALOG_INTEGRATIONS\", [WriteCatalogIntegration]\n        ):\n            error_msg = \"Catalog 'write_catalog' cannot have multiple 'write_integrations' with the same name: 'write_integration_1'.\"\n            with pytest.raises(DbtValidationError, match=error_msg):\n                run_dbt([\"run\"])\n"
  },
  {
    "path": "tests/functional/clean/test_clean.py",
    "content": "from pathlib import Path\n\nimport pytest\n\nfrom dbt.exceptions import DbtRuntimeError\nfrom dbt.tests.util import run_dbt\nfrom tests.functional.utils import up_one\n\n\nclass TestCleanSourcePath:\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return \"clean-targets: ['models']\"\n\n    def test_clean_source_path(self, project):\n        with pytest.raises(DbtRuntimeError, match=\"dbt will not clean the following source paths\"):\n            run_dbt([\"clean\"])\n\n\nclass TestCleanPathOutsideProjectRelative:\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return \"clean-targets: ['..']\"\n\n    def test_clean_path_outside_project(self, project):\n        with pytest.raises(\n            DbtRuntimeError,\n            match=\"dbt will not clean the following directories outside the project\",\n        ):\n            run_dbt([\"clean\"])\n\n\nclass TestCleanPathOutsideProjectAbsolute:\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return \"clean-targets: ['/']\"\n\n    def test_clean_path_outside_project(self, project):\n        with pytest.raises(\n            DbtRuntimeError,\n            match=\"dbt will not clean the following directories outside the project\",\n        ):\n            run_dbt([\"clean\"])\n\n\nclass TestCleanPathOutsideProjectWithFlag:\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return \"clean-targets: ['/tmp/foo']\"\n\n    def test_clean_path_outside_project(self, project):\n        # Doesn't fail because flag is set\n        run_dbt([\"clean\", \"--no-clean-project-files-only\"])\n\n        with pytest.raises(\n            DbtRuntimeError,\n            match=\"dbt will not clean the following directories outside the project\",\n        ):\n            run_dbt([\"clean\", \"--clean-project-files-only\"])\n\n\nclass TestCleanRelativeProjectDir:\n    def test_clean_relative_project_dir(self, project):\n        with up_one():\n            project_dir = Path(project.project_root).relative_to(Path.cwd())\n            run_dbt([\"clean\", \"--project-dir\", str(project_dir)])\n"
  },
  {
    "path": "tests/functional/cli/test_cli_exit_codes.py",
    "content": "import pytest\n\nfrom dbt.cli.exceptions import ResultExit\nfrom dbt.cli.main import cli\n\ngood_sql = \"\"\"\nselect 1 as fun\n\"\"\"\n\nbad_sql = \"\"\"\nsometing bad\n\"\"\"\n\n\nclass CliRunnerBase:\n    def run_cli(self):\n        ctx = cli.make_context(cli.name, [\"run\"])\n        return cli.invoke(ctx)\n\n\nclass TestExitCodeZero(CliRunnerBase):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model_one.sql\": good_sql}\n\n    def test_no_exc_thrown(self, project):\n        self.run_cli()\n\n\nclass TestExitCodeOne(CliRunnerBase):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model_one.sql\": bad_sql}\n\n    def test_exc_thrown(self, project):\n        with pytest.raises(ResultExit):\n            self.run_cli()\n"
  },
  {
    "path": "tests/functional/cli/test_click_flags.py",
    "content": "import os\nfrom unittest import mock\n\nimport pytest\n\nfrom dbt.exceptions import DbtProjectError\nfrom dbt.tests.util import run_dbt, update_config_file\n\n\nclass TestClickCLIFlagsResolveTruthy:\n    def test_resolve_truthy(self, project):\n        # we can't do this in a fixture because the project will error out before the test can run\n        update_config_file({\"require-dbt-version\": \"0.0.0\"}, \"dbt_project.yml\")\n        with pytest.raises(DbtProjectError):\n            run_dbt([\"parse\", \"--version-check\"])\n\n\nclass TestClickEnvVarFlagsResolveTruthy:\n    @pytest.mark.parametrize(\"env_var_value\", [\"yes\", \"y\", \"true\", \"t\", \"on\", \"1\"])\n    def test_resolve_truthy(self, project, env_var_value: str):\n        # we can't do this in a fixture because the project will error out before the test can run\n        update_config_file({\"require-dbt-version\": \"0.0.0\"}, \"dbt_project.yml\")\n\n        with mock.patch.dict(os.environ, {\"DBT_VERSION_CHECK\": env_var_value}):\n            # should raise\n            with pytest.raises(DbtProjectError):\n                run_dbt([\"parse\"])\n\n\nclass TestClickCLIFlagsResolveFalsey:\n    def test_resolve_falsey(self, project):\n        # we can't do this in a fixture because the project will error out before the test can run\n        update_config_file({\"require-dbt-version\": \"0.0.0\"}, \"dbt_project.yml\")\n\n        # shouldn't raise\n        run_dbt([\"parse\", \"--no-version-check\"])\n\n\nclass TestClickEnvVarFlagsResolveFalsey:\n    @pytest.mark.parametrize(\"env_var_value\", [\"no\", \"n\", \"false\", \"f\", \"off\", \"0\"])\n    def test_resolve_falsey(self, project, env_var_value: str):\n        # we can't do this in a fixture because the project will error out before the test can run\n        update_config_file({\"require-dbt-version\": \"0.0.0\"}, \"dbt_project.yml\")\n\n        with mock.patch.dict(os.environ, {\"DBT_VERSION_CHECK\": env_var_value}):\n            # shouldn't raise\n            run_dbt([\"parse\"])\n"
  },
  {
    "path": "tests/functional/cli/test_env_var_deprecations.py",
    "content": "import os\n\nimport pytest\n\nfrom dbt.tests.util import read_file, run_dbt\n\nmodel_one_sql = \"\"\"\n    select 1 as fun\n\"\"\"\n\n\nclass TestDeprecatedEnvVars:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model_one.sql\": model_one_sql}\n\n    def test_defer(self, project, logs_dir):\n        self.assert_deprecated(\n            logs_dir,\n            \"DBT_DEFER_TO_STATE\",\n            \"DBT_ENGINE_DEFER\",\n        )\n\n    def test_favor_state(self, project, logs_dir):\n        self.assert_deprecated(\n            logs_dir,\n            \"DBT_FAVOR_STATE_MODE\",\n            \"DBT_ENGINE_FAVOR_STATE\",\n            command=\"build\",\n        )\n\n    def test_print(self, project, logs_dir):\n        self.assert_deprecated(\n            logs_dir,\n            \"DBT_NO_PRINT\",\n            \"DBT_ENGINE_PRINT\",\n        )\n\n    def test_state(self, project, logs_dir):\n        self.assert_deprecated(\n            logs_dir,\n            \"DBT_ARTIFACT_STATE_PATH\",\n            \"DBT_ENGINE_STATE\",\n            old_val=\".\",\n        )\n\n    def assert_deprecated(self, logs_dir, old_env_var, new_env_var, command=\"run\", old_val=\"0\"):\n        os.environ[old_env_var] = old_val\n        run_dbt([command])\n\n        # replacing new lines with spaces accounts for text wrapping\n        log_file = read_file(logs_dir, \"dbt.log\").replace(\"\\n\", \" \").replace(\"\\\\n\", \" \")\n        dep_str = f\"The environment variable `{old_env_var}` has been renamed as `{new_env_var}`\"\n\n        try:\n            assert dep_str in log_file\n        except Exception as e:\n            del os.environ[old_env_var]\n            raise e\n        del os.environ[old_env_var]\n"
  },
  {
    "path": "tests/functional/cli/test_error_handling.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt\n\nmodel_one_sql = \"\"\"\nsometing bad\n\"\"\"\n\n\nclass TestHandledExit:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model_one.sql\": model_one_sql}\n\n    def test_failed_run_does_not_throw(self, project):\n        run_dbt([\"run\"], expect_pass=False)\n\n    def test_fail_fast_failed_run_does_not_throw(self, project):\n        run_dbt([\"--fail-fast\", \"run\"], expect_pass=False)\n"
  },
  {
    "path": "tests/functional/cli/test_multioption.py",
    "content": "import json\n\nimport pytest\n\nfrom dbt.tests.util import run_dbt\n\nmodel_one_sql = \"\"\"\nselect 1 as fun\n\"\"\"\n\nmodel_with_materialization_sql = \"\"\"\n{{ config(materialized='table') }}\nselect 1 as fun\n\"\"\"\n\nmodel_with_meta_sql = \"\"\"\n{{ config(\n    materialized='incremental',\n    meta={'owner': 'data-team', 'criticality': 'high'}\n) }}\nselect 2 as id, 'meta_test' as name\n\"\"\"\n\nschema_sql = \"\"\"\nsources:\n  - name: my_source\n    description: \"My source\"\n    schema: test_schema\n    tables:\n      - name: my_table\n      - name: my_other_table\n\nexposures:\n  - name: weekly_jaffle_metrics\n    label: By the Week\n    type: dashboard\n    maturity: high\n    url: https://bi.tool/dashboards/1\n    description: >\n      Did someone say \"exponential growth\"?\n    depends_on:\n      - ref('model_one')\n    owner:\n      name: dbt Labs\n      email: data@jaffleshop.com\n\"\"\"\n\n\nclass TestResourceType:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"schema.yml\": schema_sql, \"model_one.sql\": model_one_sql}\n\n    def test_resource_type_single(self, project):\n        result = run_dbt([\"-q\", \"ls\", \"--resource-types\", \"model\"])\n        assert len(result) == 1\n        assert result == [\"test.model_one\"]\n\n    def test_resource_type_quoted(self, project):\n        result = run_dbt([\"-q\", \"ls\", \"--resource-types\", \"model source\"])\n        assert len(result) == 3\n        expected_result = {\n            \"test.model_one\",\n            \"source:test.my_source.my_table\",\n            \"source:test.my_source.my_other_table\",\n        }\n        assert set(result) == expected_result\n\n    def test_resource_type_args(self, project):\n        result = run_dbt(\n            [\n                \"-q\",\n                \"ls\",\n                \"--resource-type\",\n                \"model\",\n                \"--resource-type\",\n                \"source\",\n                \"--resource-type\",\n                \"exposure\",\n            ]\n        )\n        assert len(result) == 4\n        expected_result = {\n            \"test.model_one\",\n            \"source:test.my_source.my_table\",\n            \"source:test.my_source.my_other_table\",\n            \"exposure:test.weekly_jaffle_metrics\",\n        }\n        assert set(result) == expected_result\n\n\nclass TestOutputKeys:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_one.sql\": model_one_sql,\n            \"model_table.sql\": model_with_materialization_sql,\n            \"model_meta.sql\": model_with_meta_sql,\n        }\n\n    def test_output_key_single(self, project):\n        result = run_dbt([\"-q\", \"ls\", \"--output\", \"json\", \"--output-keys\", \"name\"])\n        assert len(result) == 3\n        expected_names = [\"model_one\", \"model_table\", \"model_meta\"]\n        actual_names = [json.loads(r)[\"name\"] for r in result]\n        assert set(actual_names) == set(expected_names)\n\n    def test_output_key_quoted(self, project):\n        result = run_dbt([\"-q\", \"ls\", \"--output\", \"json\", \"--output-keys\", \"name resource_type\"])\n\n        assert len(result) == 3\n        # All should be models with names\n        for r in result:\n            result_json = json.loads(r)\n            assert result_json[\"resource_type\"] == \"model\"\n            assert \"name\" in result_json\n\n    def test_output_key_args(self, project):\n        result = run_dbt(\n            [\n                \"-q\",\n                \"ls\",\n                \"--output\",\n                \"json\",\n                \"--output-keys\",\n                \"name\",\n                \"--output-keys\",\n                \"resource_type\",\n            ]\n        )\n\n        assert len(result) == 3\n        # All should be models with names\n        for r in result:\n            result_json = json.loads(r)\n            assert result_json[\"resource_type\"] == \"model\"\n            assert \"name\" in result_json\n\n    def test_output_key_nested(self, project):\n        result = run_dbt(\n            [\n                \"-q\",\n                \"ls\",\n                \"--output\",\n                \"json\",\n                \"--output-keys\",\n                \"name\",\n                \"--output-keys\",\n                \"config.materialized\",\n                \"--select\",\n                \"model_table\",\n            ]\n        )\n\n        assert len(result) == 1\n        import json\n\n        result_json = json.loads(result[0])\n        assert result_json[\"name\"] == \"model_table\"\n        assert result_json[\"config.materialized\"] == \"table\"\n\n    def test_output_key_nested_single_arg(self, project):\n        result = run_dbt(\n            [\n                \"-q\",\n                \"ls\",\n                \"--output\",\n                \"json\",\n                \"--output-keys\",\n                \"config.materialized name\",\n                \"--select\",\n                \"model_table\",\n            ]\n        )\n\n        assert len(result) == 1\n        import json\n\n        result_json = json.loads(result[0])\n        assert result_json[\"name\"] == \"model_table\"\n        assert result_json[\"config.materialized\"] == \"table\"\n\n    def test_output_key_nested_nonexistent(self, project):\n        \"\"\"Test that non-existent nested keys return empty objects\"\"\"\n        result = run_dbt(\n            [\n                \"-q\",\n                \"ls\",\n                \"--output\",\n                \"json\",\n                \"--output-keys\",\n                \"config.nonexistent\",\n                \"--select\",\n                \"model_table\",\n            ]\n        )\n\n        assert len(result) == 1\n        import json\n\n        result_json = json.loads(result[0])\n        assert result_json == {}  # Non-existent key should result in empty object\n\n    def test_output_key_nested_mixed_existent_nonexistent(self, project):\n        \"\"\"Test mixing existent and non-existent nested keys\"\"\"\n        result = run_dbt(\n            [\n                \"-q\",\n                \"ls\",\n                \"--output\",\n                \"json\",\n                \"--output-keys\",\n                \"name\",\n                \"--output-keys\",\n                \"config.materialized\",\n                \"--output-keys\",\n                \"config.nonexistent\",\n                \"--select\",\n                \"model_table\",\n            ]\n        )\n\n        assert len(result) == 1\n        import json\n\n        result_json = json.loads(result[0])\n        assert result_json[\"name\"] == \"model_table\"\n        assert result_json[\"config.materialized\"] == \"table\"\n        # Non-existent key should not appear in result\n        assert \"config.nonexistent\" not in result_json\n\n    def test_output_key_nested_deep_nonexistent(self, project):\n        \"\"\"Test deeply nested non-existent keys\"\"\"\n        result = run_dbt(\n            [\n                \"-q\",\n                \"ls\",\n                \"--output\",\n                \"json\",\n                \"--output-keys\",\n                \"config.meta.owner.nonexistent\",\n                \"--select\",\n                \"model_table\",\n            ]\n        )\n\n        assert len(result) == 1\n        import json\n\n        result_json = json.loads(result[0])\n        assert result_json == {}  # Deep non-existent key should result in empty object\n\n    def test_output_key_nested_deep_meta(self, project):\n        \"\"\"Test deeply nested meta keys that exist\"\"\"\n        result = run_dbt(\n            [\n                \"-q\",\n                \"ls\",\n                \"--output\",\n                \"json\",\n                \"--output-keys\",\n                \"name\",\n                \"--output-keys\",\n                \"config.meta.owner\",\n                \"--select\",\n                \"model_meta\",\n            ]\n        )\n\n        assert len(result) == 1\n        result_json = json.loads(result[0])\n        assert result_json[\"name\"] == \"model_meta\"\n        assert result_json[\"config.meta.owner\"] == \"data-team\"\n\n    def test_output_key_nested_whole_meta_object(self, project):\n        \"\"\"Test getting the whole meta object as nested key\"\"\"\n        result = run_dbt(\n            [\n                \"-q\",\n                \"ls\",\n                \"--output\",\n                \"json\",\n                \"--output-keys\",\n                \"config.meta\",\n                \"--select\",\n                \"model_meta\",\n            ]\n        )\n\n        assert len(result) == 1\n        result_json = json.loads(result[0])\n        expected_meta = {\"owner\": \"data-team\", \"criticality\": \"high\"}\n        assert result_json[\"config.meta\"] == expected_meta\n\n\nclass TestSelectExclude:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_one.sql\": model_one_sql,\n            \"model_two.sql\": model_one_sql,\n            \"model_three.sql\": model_one_sql,\n        }\n\n    def test_select_exclude_single(self, project):\n        result = run_dbt([\"-q\", \"ls\", \"--select\", \"model_one\"])\n        assert len(result) == 1\n        assert result == [\"test.model_one\"]\n        result = run_dbt([\"-q\", \"ls\", \"--exclude\", \"model_one\"])\n        assert len(result) == 2\n        assert \"test.model_one\" not in result\n\n    def test_select_exclude_quoted(self, project):\n        result = run_dbt([\"-q\", \"ls\", \"--select\", \"model_one model_two\"])\n        assert len(result) == 2\n        assert \"test.model_three\" not in result\n        result = run_dbt([\"-q\", \"ls\", \"--exclude\", \"model_one model_two\"])\n        assert len(result) == 1\n        assert result == [\"test.model_three\"]\n\n    def test_select_exclude_args(self, project):\n        result = run_dbt([\"-q\", \"ls\", \"--select\", \"model_one\", \"--select\", \"model_two\"])\n        assert len(result) == 2\n        assert \"test.model_three\" not in result\n        result = run_dbt([\"-q\", \"ls\", \"--exclude\", \"model_one\", \"--exclude\", \"model_two\"])\n        assert len(result) == 1\n        assert result == [\"test.model_three\"]\n"
  },
  {
    "path": "tests/functional/cli/test_option_interaction_validations.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt\n\n\nclass TestEventTimeEndEventTimeStart:\n    @pytest.mark.parametrize(\n        \"event_time_start,event_time_end,expect_pass\",\n        [\n            (\"2024-10-01\", \"2024-10-02\", True),\n            (\"2024-10-02\", \"2024-10-01\", False),\n        ],\n    )\n    def test_option_combo(self, project, event_time_start, event_time_end, expect_pass):\n        try:\n            run_dbt(\n                [\n                    \"build\",\n                    \"--event-time-start\",\n                    event_time_start,\n                    \"--event-time-end\",\n                    event_time_end,\n                ]\n            )\n            assert expect_pass\n        except Exception as e:\n            assert (\n                \"Value for `--event-time-start` must be less than `--event-time-end`\"\n                in e.__str__()\n            )\n            assert not expect_pass\n\n\nclass TestEventTimeEndEventTimeStartMutuallyRequired:\n    @pytest.mark.parametrize(\n        \"specified,missing\",\n        [\n            (\"--event-time-start\", \"--event-time-end\"),\n            (\"--event-time-end\", \"--event-time-start\"),\n        ],\n    )\n    def test_option_combo(self, project, specified, missing):\n        try:\n            run_dbt([\"build\", specified, \"2024-10-01\"])\n            assert False, f\"An error should have been raised for missing `{missing}` flag\"\n        except Exception as e:\n            assert (\n                f\"When specifying `{specified}`, `{missing}` must also be present.\" in e.__str__()\n            )\n"
  },
  {
    "path": "tests/functional/cli/test_requires.py",
    "content": "import os\n\nimport pytest\nfrom pytest_mock import MockerFixture\n\nfrom dbt.events.types import JinjaLogInfo, PartialParsingNotEnabled\nfrom dbt.tests.util import run_dbt\nfrom dbt_common.events.event_catcher import EventCatcher\n\nmodel_one_sql = \"\"\"\n    {{ log(\"DBT_ENGINE_SHOW_RESOURCE_REPORT: \" ~ env_var('DBT_ENGINE_SHOW_RESOURCE_REPORT', default=\"0\"), info=True) }}\n    {{ log(\"DBT_SHOW_RESOURCE_REPORT: \" ~ env_var('DBT_SHOW_RESOURCE_REPORT', default=\"0\"), info=True) }}\n    select 1 as fun\n\"\"\"\n\n\nclass TestOldEngineEnvVarPropagation:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model_one.sql\": model_one_sql}\n\n    @pytest.mark.parametrize(\n        \"set_old,set_new, expect\",\n        [(False, False, 0), (True, False, False), (False, True, True), (True, True, True)],\n    )\n    def test_engine_env_var_propagation(\n        self, project, mocker: MockerFixture, set_old: bool, set_new: bool, expect: bool\n    ):\n        # Of note, the default value for DBT_PARTIAL_PARSE is True\n        if set_old:\n            mocker.patch.dict(os.environ, {\"DBT_SHOW_RESOURCE_REPORT\": \"False\"})\n        if set_new:\n            mocker.patch.dict(os.environ, {\"DBT_ENGINE_SHOW_RESOURCE_REPORT\": \"True\"})\n\n        event_catcher = EventCatcher(event_to_catch=JinjaLogInfo)\n        run_dbt([\"parse\", \"--no-partial-parse\"], callbacks=[event_catcher.catch])\n\n        assert len(event_catcher.caught_events) == 2\n\n        for event in event_catcher.caught_events:\n            if event.data.msg.startswith(\"DBT_ENGINE_SHOW_RESOURCE_REPORT\"):\n                assert event.data.msg.endswith(f\"{expect}\")\n            elif event.data.msg.startswith(\"DBT_SHOW_RESOURCE_REPORT\"):\n                assert event.data.msg.endswith(f\"{expect}\")\n            else:\n                assert False, \"Unexpected log message\"\n\n\nclass TestEngineEnvVarPickedUpByClick:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model_one.sql\": model_one_sql}\n\n    def test_engine_env_var_picked_up_by_cli_flags(self, project, mocker: MockerFixture):\n        event_catcher = EventCatcher(event_to_catch=PartialParsingNotEnabled)\n\n        run_dbt([\"parse\"], callbacks=[event_catcher.catch])\n        assert len(event_catcher.caught_events) == 0\n\n        run_dbt([\"parse\"], callbacks=[event_catcher.catch])\n        assert len(event_catcher.caught_events) == 0\n\n        mocker.patch.dict(os.environ, {\"DBT_ENGINE_PARTIAL_PARSE\": \"False\"})\n        run_dbt([\"parse\"], callbacks=[event_catcher.catch])\n        assert len(event_catcher.caught_events) == 1\n\n\nclass TestKnownEngineEnvVarsExplicit:\n    def test_allow_list_is_correct(self, project):\n        run_dbt([\"parse\"])\n\n        hard_coded_allow_list = {\n            \"DBT_ENGINE_NO_PRINT\",\n            \"DBT_ENGINE_EXCLUDE_RESOURCE_TYPES\",\n            \"DBT_ENGINE_TARGET\",\n            \"DBT_ENGINE_PROJECT_DIR\",\n            \"DBT_ENGINE_MACRO_DEBUGGING\",\n            \"DBT_ENGINE_EVENT_TIME_END\",\n            \"DBT_ENGINE_PRINTER_WIDTH\",\n            \"DBT_ENGINE_PACKAGE_HUB_URL\",\n            \"DBT_ENGINE_TARGET_PATH\",\n            \"DBT_ENGINE_EMPTY\",\n            \"DBT_ENGINE_DOWNLOAD_DIR\",\n            \"DBT_ENGINE_INDIRECT_SELECTION\",\n            \"DBT_ENGINE_SHOW_RESOURCE_REPORT\",\n            \"DBT_ENGINE_EVENT_TIME_START\",\n            \"DBT_ENGINE_LOG_CACHE_EVENTS\",\n            \"DBT_ENGINE_USE_COLORS_FILE\",\n            \"DBT_ENGINE_LOG_FILE_MAX_BYTES\",\n            \"DBT_ENGINE_DEFER_TO_STATE\",\n            \"DBT_ENGINE_RESOURCE_TYPES\",\n            \"DBT_ENGINE_HOST\",\n            \"DBT_ENGINE_STATE\",\n            \"DBT_ENGINE_PP_FILE_DIFF_TEST\",\n            \"DBT_ENGINE_STORE_FAILURES\",\n            \"DBT_ENGINE_LOG_PATH\",\n            \"DBT_ENGINE_EXPORT_SAVED_QUERIES\",\n            \"DBT_ENGINE_CLEAN_PROJECT_FILES_ONLY\",\n            \"DBT_ENGINE_CACHE_SELECTED_ONLY\",\n            \"DBT_ENGINE_WRITE_JSON\",\n            \"DBT_ENGINE_SEND_ANONYMOUS_USAGE_STATS\",\n            \"DBT_ENGINE_RECORDED_FILE_PATH\",\n            \"DBT_ENGINE_PARTIAL_PARSE_FILE_DIFF\",\n            \"DBT_ENGINE_PP_TEST\",\n            \"DBT_ENGINE_INTROSPECT\",\n            \"DBT_ENGINE_USE_FAST_TEST_EDGES\",\n            \"DBT_ENGINE_VERSION_CHECK\",\n            \"DBT_ENGINE_QUIET\",\n            \"DBT_ENGINE_SINGLE_THREADED\",\n            \"DBT_ENGINE_SQLPARSE\",\n            \"DBT_ENGINE_ARTIFACT_STATE_PATH\",\n            \"DBT_ENGINE_FULL_REFRESH\",\n            \"DBT_ENGINE_FAIL_FAST\",\n            \"DBT_ENGINE_INCLUDE_SAVED_QUERY\",\n            \"DBT_ENGINE_WARN_ERROR\",\n            \"DBT_ENGINE_PROFILES_DIR\",\n            \"DBT_ENGINE_LOG_LEVEL\",\n            \"DBT_ENGINE_STATIC_PARSER\",\n            \"DBT_ENGINE_PROFILE\",\n            \"DBT_ENGINE_PARTIAL_PARSE\",\n            \"DBT_ENGINE_POPULATE_CACHE\",\n            \"DBT_ENGINE_DEFER\",\n            \"DBT_ENGINE_FAVOR_STATE_MODE\",\n            \"DBT_ENGINE_USE_COLORS\",\n            \"DBT_ENGINE_DEFER_STATE\",\n            \"DBT_ENGINE_LOG_FORMAT\",\n            \"DBT_ENGINE_PARTIAL_PARSE_FILE_PATH\",\n            \"DBT_ENGINE_WARN_ERROR_OPTIONS\",\n            \"DBT_ENGINE_INVOCATION_ENV\",\n            \"DBT_ENGINE_FAVOR_STATE\",\n            \"DBT_ENGINE_LOG_FORMAT_FILE\",\n            \"DBT_ENGINE_TEST_STATE_MODIFIED\",\n            \"DBT_ENGINE_LOG_LEVEL_FILE\",\n            \"DBT_ENGINE_USE_EXPERIMENTAL_PARSER\",\n            \"DBT_ENGINE_UPLOAD_TO_ARTIFACTS_INGEST_API\",\n            \"DBT_ENGINE_DEBUG\",\n            \"DBT_ENGINE_PRINT\",\n            \"DBT_ENGINE_SAMPLE\",\n        }\n        from dbt.env_vars import _ALLOWED_ENV_VARS\n\n        assert hard_coded_allow_list == _ALLOWED_ENV_VARS\n"
  },
  {
    "path": "tests/functional/cli/test_resolvers.py",
    "content": "from pathlib import Path\n\nimport pytest\n\nfrom dbt.cli.resolvers import default_log_path\n\n\nclass TestDefaultLogPathNoProject:\n    def test_default_log_path_no_project(self):\n        expected_log_path = Path(\"logs\")\n        actual_log_path = default_log_path(\"nonexistent_project_dir\")\n\n        assert actual_log_path == expected_log_path\n\n\nclass TestDefaultLogPathWithProject:\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\"log-path\": \"test_default_log_path\"}\n\n    def test_default_log_path_with_project(self, project, project_config_update):\n        expected_log_path = Path(project.project_root) / \"test_default_log_path\"\n        actual_log_path = default_log_path(project.project_root)\n\n        assert actual_log_path == expected_log_path\n\n\nclass TestDefaultLogPathWithProjectNoConfiguredLogPath:\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\"log-path\": None}\n\n    def test_default_log_path_with_project(self, project, project_config_update):\n        expected_log_path = Path(project.project_root) / \"logs\"\n        actual_log_path = default_log_path(project.project_root)\n\n        assert actual_log_path == expected_log_path\n"
  },
  {
    "path": "tests/functional/colors/test_colors.py",
    "content": "import re\n\nimport pytest\n\nfrom dbt.tests.util import run_dbt_and_capture\n\nmodels__do_nothing_then_fail_sql = \"\"\"\nselect 1,\n\n\"\"\"\n\n\n@pytest.fixture(scope=\"class\")\ndef models():\n    return {\"do_nothing_then_fail.sql\": models__do_nothing_then_fail_sql}\n\n\n@pytest.fixture(scope=\"class\")\ndef project_config_update():\n    return {\"config-version\": 2}\n\n\nclass TestColors:\n    def test_use_colors(self, project):\n        self.assert_colors_used(\n            \"--use-colors\",\n            expect_colors=True,\n        )\n\n    def test_no_use_colors(self, project):\n        self.assert_colors_used(\n            \"--no-use-colors\",\n            expect_colors=False,\n        )\n\n    def assert_colors_used(self, flag, expect_colors):\n        _, stdout = run_dbt_and_capture(args=[flag, \"run\"], expect_pass=False)\n        # pattern to match formatted log output\n        pattern = re.compile(r\"\\[31m.*|\\[33m.*\")\n        stdout_contains_formatting_characters = bool(pattern.search(stdout))\n        if expect_colors:\n            assert stdout_contains_formatting_characters\n        else:\n            assert not stdout_contains_formatting_characters\n"
  },
  {
    "path": "tests/functional/column_quoting/test_column_quotes.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt\n\n_MODELS__COLUMN_QUOTING_DEFAULT = \"\"\"\n{% set col_a = '\"col_A\"' %}\n{% set col_b = '\"col_B\"' %}\n\n{{\n  config(\n    materialized = 'incremental',\n    unique_key = col_a,\n  )\n}}\n\nselect\n  {{ col_a }},\n  {{ col_b }}\nfrom {{ref('seed')}}\n\"\"\"\n\n_MODELS__COLUMN_QUOTING_NO_QUOTING = \"\"\"\n{% set col_a = '\"col_a\"' %}\n{% set col_b = '\"col_b\"' %}\n\n{{\n  config(\n    materialized = 'incremental',\n    unique_key = col_a,\n  )\n}}\n\nselect\n  {{ col_a }},\n  {{ col_b }}\nfrom {{ref('seed')}}\n\"\"\"\n\n_SEEDS_BASIC_SEED = \"\"\"col_A,col_B\n1,2\n3,4\n5,6\n\"\"\"\n\n\nclass BaseColumnQuotingTest:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model.sql\": _MODELS__COLUMN_QUOTING_DEFAULT}\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\"seed.csv\": _SEEDS_BASIC_SEED}\n\n    @pytest.fixture(scope=\"function\")\n    def run_column_quotes(self, project):\n        def fixt():\n            results = run_dbt([\"seed\"])\n            assert len(results) == 1\n            results = run_dbt([\"run\"])\n            assert len(results) == 1\n            results = run_dbt([\"run\"])\n            assert len(results) == 1\n\n        return fixt\n\n\nclass TestColumnQuotingDefault(BaseColumnQuotingTest):\n    def test_column_quotes(self, run_column_quotes):\n        run_column_quotes()\n\n\nclass TestColumnQuotingEnabled(BaseColumnQuotingTest):\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"seeds\": {\n                \"quote_columns\": True,\n            },\n        }\n\n    def test_column_quotes(self, run_column_quotes):\n        run_column_quotes()\n\n\nclass TestColumnQuotingDisabled(BaseColumnQuotingTest):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model.sql\": _MODELS__COLUMN_QUOTING_NO_QUOTING}\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"seeds\": {\n                \"quote_columns\": False,\n            },\n        }\n\n    def test_column_quotes(self, run_column_quotes):\n        run_column_quotes()\n"
  },
  {
    "path": "tests/functional/compile/fixtures.py",
    "content": "first_model_sql = \"\"\"\nselect 1 as fun\n\"\"\"\n\nsecond_model_sql = \"\"\"\n{%- set columns = adapter.get_columns_in_relation(ref('first_model')) -%}\nselect\n    *,\n    {{ this.schema }} as schema\nfrom {{ ref('first_model') }}\n\"\"\"\n\nfirst_ephemeral_model_sql = \"\"\"\n{{ config(materialized = 'ephemeral') }}\nselect 1 as fun\n\"\"\"\n\nsecond_ephemeral_model_sql = \"\"\"\n{{ config(materialized = 'ephemeral') }}\nselect * from {{ ref('first_ephemeral_model') }}\n\"\"\"\n\nthird_ephemeral_model_sql = \"\"\"\nselect * from {{ ref('second_ephemeral_model')}}\nunion all\nselect 2 as fun\n\"\"\"\n\nmodel_multiline_jinja = \"\"\"\nselect {{\n    1 + 1\n}} as fun\n\"\"\"\n\nwith_recursive_model_sql = \"\"\"\n{{ config(materialized = 'ephemeral') }}\nwith recursive t(n) as (\n    select * from {{ ref('first_ephemeral_model') }}\n  union all\n    select n+1 from t where n < 100\n)\nselect sum(n) from t;\n\"\"\"\n\nfirst_ephemeral_model_with_alias_sql = \"\"\"\n{{ config(materialized = 'ephemeral', alias = 'first_alias') }}\nselect 1 as fun\n\"\"\"\n\nsecond_ephemeral_model_with_alias_sql = \"\"\"\nselect * from {{ ref('first_ephemeral_model_with_alias') }}\n\"\"\"\n\nschema_yml = \"\"\"\nversion: 2\n\nmodels:\n  - name: second_model\n    description: \"The second model\"\n    columns:\n      - name: fun\n        data_tests:\n          - not_null\n      - name: schema\n        data_tests:\n          - unique\n\"\"\"\n"
  },
  {
    "path": "tests/functional/compile/test_compile.py",
    "content": "import json\nimport pathlib\nimport re\n\nimport pytest\nimport sqlparse\n\nfrom dbt.tests.util import read_file, run_dbt, run_dbt_and_capture\nfrom dbt_common.exceptions import DbtBaseException as DbtException\nfrom dbt_common.exceptions import DbtRuntimeError\nfrom tests.functional.assertions.test_runner import dbtTestRunner\nfrom tests.functional.compile.fixtures import (\n    first_ephemeral_model_sql,\n    first_ephemeral_model_with_alias_sql,\n    first_model_sql,\n    model_multiline_jinja,\n    schema_yml,\n    second_ephemeral_model_sql,\n    second_ephemeral_model_with_alias_sql,\n    second_model_sql,\n    third_ephemeral_model_sql,\n    with_recursive_model_sql,\n)\n\n\ndef norm_whitespace(string):\n    _RE_COMBINE_WHITESPACE = re.compile(r\"\\s+\")\n    string = _RE_COMBINE_WHITESPACE.sub(\" \", string).strip()\n    return string\n\n\ndef get_lines(model_name):\n    f = read_file(\"target\", \"compiled\", \"test\", \"models\", model_name + \".sql\")\n    return [line for line in f.splitlines() if line]\n\n\ndef file_exists(model_name):\n    from dbt.tests.util import file_exists\n\n    return file_exists(\"target\", \"compiled\", \"test\", \"models\", model_name + \".sql\")\n\n\nclass TestIntrospectFlag:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"first_model.sql\": first_model_sql,\n            \"second_model.sql\": second_model_sql,\n            \"schema.yml\": schema_yml,\n        }\n\n    def test_default(self, project):\n        run_dbt([\"compile\"])\n        assert get_lines(\"first_model\") == [\"select 1 as fun\"]\n        assert any(\"_test_compile as schema\" in line for line in get_lines(\"second_model\"))\n\n    def test_no_introspect(self, project):\n        with pytest.raises(DbtRuntimeError, match=\"connection never acquired for thread\"):\n            run_dbt([\"compile\", \"--no-introspect\"])\n\n\nclass TestEphemeralModels:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"first_ephemeral_model.sql\": first_ephemeral_model_sql,\n            \"second_ephemeral_model.sql\": second_ephemeral_model_sql,\n            \"third_ephemeral_model.sql\": third_ephemeral_model_sql,\n            \"with_recursive_model.sql\": with_recursive_model_sql,\n        }\n\n    def test_first_selector(self, project):\n        (results, log_output) = run_dbt_and_capture(\n            [\"compile\", \"--select\", \"first_ephemeral_model\"]\n        )\n        assert file_exists(\"first_ephemeral_model\")\n        assert not file_exists(\"second_ephemeral_model\")\n        assert not file_exists(\"third_ephemeral_model\")\n        assert \"Compiled node 'first_ephemeral_model' is\" in log_output\n\n    def test_middle_selector(self, project):\n        (results, log_output) = run_dbt_and_capture(\n            [\"compile\", \"--select\", \"second_ephemeral_model\"]\n        )\n        assert file_exists(\"first_ephemeral_model\")\n        assert file_exists(\"second_ephemeral_model\")\n        assert not file_exists(\"third_ephemeral_model\")\n        assert \"Compiled node 'second_ephemeral_model' is\" in log_output\n\n    def test_last_selector(self, project):\n        (results, log_output) = run_dbt_and_capture(\n            [\"compile\", \"--select\", \"third_ephemeral_model\"]\n        )\n        assert file_exists(\"first_ephemeral_model\")\n        assert file_exists(\"second_ephemeral_model\")\n        assert file_exists(\"third_ephemeral_model\")\n        assert \"Compiled node 'third_ephemeral_model' is\" in log_output\n\n    def test_no_selector(self, project):\n        run_dbt([\"compile\"])\n\n        sql = read_file(\"target\", \"compiled\", \"test\", \"models\", \"first_ephemeral_model.sql\")\n        assert norm_whitespace(sql) == norm_whitespace(\"select 1 as fun\")\n        sql = read_file(\"target\", \"compiled\", \"test\", \"models\", \"second_ephemeral_model.sql\")\n        expected_sql = \"\"\"with __dbt__cte__first_ephemeral_model as (\n            select 1 as fun\n            ) select * from __dbt__cte__first_ephemeral_model\"\"\"\n        assert norm_whitespace(sql) == norm_whitespace(expected_sql)\n        sql = read_file(\"target\", \"compiled\", \"test\", \"models\", \"third_ephemeral_model.sql\")\n        expected_sql = \"\"\"with __dbt__cte__first_ephemeral_model as (\n            select 1 as fun\n            ),  __dbt__cte__second_ephemeral_model as (\n            select * from __dbt__cte__first_ephemeral_model\n            ) select * from __dbt__cte__second_ephemeral_model\n            union all\n            select 2 as fun\"\"\"\n        assert norm_whitespace(sql) == norm_whitespace(expected_sql)\n\n    def test_with_recursive_cte(self, project):\n        run_dbt([\"compile\"])\n\n        assert get_lines(\"with_recursive_model\") == [\n            \"with recursive  __dbt__cte__first_ephemeral_model as (\",\n            \"select 1 as fun\",\n            \"), t(n) as (\",\n            \"    select * from __dbt__cte__first_ephemeral_model\",\n            \"  union all\",\n            \"    select n+1 from t where n < 100\",\n            \")\",\n            \"select sum(n) from t;\",\n        ]\n\n\nclass TestEphemeralModelWithAlias:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"first_ephemeral_model_with_alias.sql\": first_ephemeral_model_with_alias_sql,\n            \"second_ephemeral_model_with_alias.sql\": second_ephemeral_model_with_alias_sql,\n        }\n\n    def test_compile(self, project):\n        run_dbt([\"compile\"])\n\n        assert get_lines(\"second_ephemeral_model_with_alias\") == [\n            \"with __dbt__cte__first_alias as (\",\n            \"select 1 as fun\",\n            \") select * from __dbt__cte__first_alias\",\n        ]\n\n\nclass TestCompile:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"first_model.sql\": first_model_sql,\n            \"second_model.sql\": second_model_sql,\n            \"schema.yml\": schema_yml,\n        }\n\n    def test_none(self, project):\n        (results, log_output) = run_dbt_and_capture([\"compile\"])\n        assert len(results) == 4\n        assert \"Compiled node\" not in log_output\n\n    def test_inline_pass(self, project):\n        (results, log_output) = run_dbt_and_capture(\n            [\"compile\", \"--inline\", \"select * from {{ ref('first_model') }}\"]\n        )\n        assert len(results) == 1\n        assert \"Compiled inline node is:\" in log_output\n\n    def test_inline_pass_quiet(self, project):\n        (results, log_output) = run_dbt_and_capture(\n            [\"compile\", \"--quiet\", \"--inline\", \"select * from {{ ref('first_model') }}\"]\n        )\n        assert len(results) == 1\n        assert \"Compiled inline node is:\" not in log_output\n\n    def test_select_pass(self, project):\n        (results, log_output) = run_dbt_and_capture([\"compile\", \"--select\", \"second_model\"])\n        assert len(results) == 3\n        assert \"Compiled node 'second_model' is:\" in log_output\n\n    def test_select_pass_quiet(self, project):\n        (results, log_output) = run_dbt_and_capture(\n            [\"compile\", \"--quiet\", \"--select\", \"second_model\"]\n        )\n        assert len(results) == 3\n        assert \"Compiled node 'second_model' is:\" not in log_output\n\n    def test_select_pass_empty(self, project):\n        (results, log_output) = run_dbt_and_capture(\n            [\"compile\", \"--indirect-selection\", \"empty\", \"--select\", \"second_model\"]\n        )\n        assert len(results) == 1\n        assert \"Compiled node 'second_model' is:\" in log_output\n\n    def test_inline_fail(self, project):\n        with pytest.raises(DbtException, match=\"Error parsing inline query\"):\n            run_dbt([\"compile\", \"--inline\", \"select * from {{ ref('third_model') }}\"])\n\n    def test_inline_fail_database_error(self, project):\n        with pytest.raises(DbtRuntimeError, match=\"Database Error\"):\n            run_dbt([\"show\", \"--inline\", \"slect asdlkjfsld;j\"])\n\n    def test_multiline_jinja(self, project):\n        (results, log_output) = run_dbt_and_capture([\"compile\", \"--inline\", model_multiline_jinja])\n        assert len(results) == 1\n        assert \"Compiled inline node is:\" in log_output\n\n    def test_output_json_select(self, project):\n        (results, log_output) = run_dbt_and_capture(\n            [\"compile\", \"--select\", \"second_model\", \"--output\", \"json\"]\n        )\n        assert len(results) == 3\n        assert \"node\" in log_output\n        assert \"compiled\" in log_output\n        with pytest.raises(json.JSONDecodeError):\n            json.loads(log_output)\n\n    def test_output_json_select_quiet(self, project):\n        (results, log_output) = run_dbt_and_capture(\n            [\"compile\", \"--quiet\", \"--select\", \"second_model\", \"--output\", \"json\"]\n        )\n        assert len(results) == 3\n        assert \"node\" in log_output\n        assert \"compiled\" in log_output\n        json.loads(log_output)\n\n    def test_output_json_inline(self, project):\n        (results, log_output) = run_dbt_and_capture(\n            [\"compile\", \"--inline\", \"select * from {{ ref('second_model') }}\", \"--output\", \"json\"]\n        )\n        assert len(results) == 1\n        assert '\"node\"' not in log_output\n        assert '\"compiled\"' in log_output\n        with pytest.raises(json.JSONDecodeError):\n            json.loads(log_output)\n\n    def test_output_json_inline_quiet(self, project):\n        (results, log_output) = run_dbt_and_capture(\n            [\n                \"compile\",\n                \"--quiet\",\n                \"--inline\",\n                \"select * from {{ ref('second_model') }}\",\n                \"--output\",\n                \"json\",\n            ]\n        )\n        assert len(results) == 1\n        assert '\"node\"' not in log_output\n        assert '\"compiled\"' in log_output\n        json.loads(log_output)\n\n    def test_compile_inline_not_add_node(self, project):\n        dbt = dbtTestRunner()\n        parse_result = dbt.invoke([\"parse\"])\n        manifest = parse_result.result\n        assert len(manifest.nodes) == 4\n        dbt = dbtTestRunner(manifest=manifest)\n        dbt.invoke(\n            [\"compile\", \"--inline\", \"select * from {{ ref('second_model') }}\"],\n            populate_cache=False,\n        )\n        assert len(manifest.nodes) == 4\n\n    def test_compile_inline_syntax_error(self, project, mocker):\n        patched_fire_event = mocker.patch(\"dbt.task.compile.fire_event\")\n        with pytest.raises(DbtException, match=\"Error parsing inline query\"):\n            run_dbt([\"compile\", \"--inline\", \"select * from {{ ref(1) }}\"])\n        # Event for parsing error fired\n        patched_fire_event.assert_called_once()\n\n    def test_compile_inline_ref_node_not_exist(self, project, mocker):\n        patched_fire_event = mocker.patch(\"dbt.task.compile.fire_event\")\n        with pytest.raises(DbtException, match=\"Error parsing inline query\"):\n            run_dbt([\"compile\", \"--inline\", \"select * from {{ ref('third_model') }}\"])\n        # Event for parsing error fired\n        patched_fire_event.assert_called_once()\n\n    def test_graph_summary_output(self, project):\n        \"\"\"Ensure that the compile command generates a file named graph_summary.json\n        in the target directory, that the file contains valid json, and that the\n        json has the high level structure it should.\"\"\"\n        dbtTestRunner().invoke([\"compile\"])\n        summary_path = pathlib.Path(project.project_root, \"target/graph_summary.json\")\n        with open(summary_path, \"r\") as summary_file:\n            summary = json.load(summary_file)\n            assert \"_invocation_id\" in summary\n            assert \"linked\" in summary\n\n\nclass TestSqlParseGroupingTokenLimit:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"first_ephemeral_model.sql\": first_ephemeral_model_sql,\n            \"second_ephemeral_model.sql\": second_ephemeral_model_sql,\n            \"third_ephemeral_model.sql\": third_ephemeral_model_sql,\n            \"with_recursive_model.sql\": with_recursive_model_sql,\n        }\n\n    def test_sqlparse_grouping_token_limit(self, project):\n        # No flag: compile succeeds (default is no limit)\n        run_dbt([\"compile\"])\n        assert sqlparse.engine.grouping.MAX_GROUPING_TOKENS is None\n\n        # Flag set to 0: compile fails because token limit is exceeded\n        with pytest.raises(DbtRuntimeError, match=\"You may raise the limit via --sqlparse\"):\n            run_dbt([\"compile\", \"--sqlparse\", '{\"MAX_GROUPING_TOKENS\": \"0\"}'])\n\n        # Flag set to 10000: compile succeeds\n        run_dbt([\"compile\", \"--sqlparse\", '{\"MAX_GROUPING_TOKENS\": \"10000\"}'])\n\n\nclass TestSqlParseGroupingDepthLimit:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"first_ephemeral_model.sql\": first_ephemeral_model_sql,\n            \"second_ephemeral_model.sql\": second_ephemeral_model_sql,\n            \"third_ephemeral_model.sql\": third_ephemeral_model_sql,\n            \"with_recursive_model.sql\": with_recursive_model_sql,\n        }\n\n    def test_sqlparse_grouping_depth_limit(self, project):\n        # No flag: compile succeeds (default is no limit)\n        run_dbt([\"compile\"])\n        assert sqlparse.engine.grouping.MAX_GROUPING_DEPTH is None\n\n        # Flag set to 0: compile fails because depth limit is exceeded\n        with pytest.raises(DbtRuntimeError, match=\"You may raise the limit via --sqlparse\"):\n            run_dbt([\"compile\", \"--sqlparse\", '{\"MAX_GROUPING_DEPTH\": \"0\"}'])\n\n        # Flag set to 10000: compile succeeds\n        run_dbt([\"compile\", \"--sqlparse\", '{\"MAX_GROUPING_DEPTH\": \"10000\"}'])\n"
  },
  {
    "path": "tests/functional/configs/fixtures.py",
    "content": "import pytest\n\nmodels__schema_yml = \"\"\"\nversion: 2\nsources:\n  - name: raw\n    database: \"{{ target.database }}\"\n    schema: \"{{ target.schema }}\"\n    tables:\n      - name: 'seed'\n        identifier: \"{{ var('seed_name', 'invalid') }}\"\n        columns:\n          - name: id\n            data_tests:\n              - unique:\n                  enabled: \"{{ var('enabled_direct', None) | as_native }}\"\n              - accepted_values:\n                  enabled: \"{{ var('enabled_direct', None) | as_native }}\"\n                  severity: \"{{ var('severity_direct', None) | as_native }}\"\n                  values: [1,2]\n\nmodels:\n  - name: model\n    columns:\n      - name: id\n        data_tests:\n          - unique\n          - accepted_values:\n              values: [1,2,3,4]\n\n\"\"\"\n\nmodels__untagged_sql = \"\"\"\n{{\n    config(materialized='table')\n}}\n\nselect id, value from {{ source('raw', 'seed') }}\n\n\"\"\"\n\nmodels__tagged__model_sql = \"\"\"\n{{\n    config(\n        materialized='view',\n        tags=['tag_two'],\n    )\n}}\n\n{{\n    config(\n        materialized='table',\n        tags=['tag_three'],\n    )\n}}\n\nselect 4 as id, 2 as value\n\n\"\"\"\n\nseeds__seed_csv = \"\"\"id,value\n4,2\n\"\"\"\n\ntests__failing_sql = \"\"\"\n\nselect 1 as fun\n\n\"\"\"\n\ntests__sleeper_agent_sql = \"\"\"\n{{ config(\n    enabled = var('enabled_direct', False),\n    severity = var('severity_direct', 'WARN')\n) }}\n\nselect 1 as fun\n\n\"\"\"\n\nmy_model = \"\"\"\nselect 1 as user\n\"\"\"\n\nmy_model_2 = \"\"\"\nselect * from {{ ref('my_model') }}\n\"\"\"\n\nmy_model_3 = \"\"\"\nselect * from {{ ref('my_model_2') }}\n\"\"\"\n\nmy_model_2_disabled = \"\"\"\n{{ config(enabled=false) }}\nselect * from {{ ref('my_model') }}\n\"\"\"\n\nmy_model_3_disabled = \"\"\"\n{{ config(enabled=false) }}\nselect * from {{ ref('my_model_2') }}\n\"\"\"\n\nmy_model_2_enabled = \"\"\"\n{{ config(enabled=true) }}\nselect * from {{ ref('my_model') }}\n\"\"\"\n\nmy_model_3_enabled = \"\"\"\n{{ config(enabled=true) }}\nselect * from {{ ref('my_model') }}\n\"\"\"\n\nschema_all_disabled_yml = \"\"\"\nversion: 2\nmodels:\n  - name: my_model\n  - name: my_model_2\n    config:\n      enabled: false\n  - name: my_model_3\n    config:\n      enabled: false\n\"\"\"\n\nschema_explicit_enabled_yml = \"\"\"\nversion: 2\nmodels:\n  - name: my_model\n  - name: my_model_2\n    config:\n      enabled: true\n  - name: my_model_3\n    config:\n      enabled: true\n\"\"\"\n\nschema_partial_disabled_yml = \"\"\"\nversion: 2\nmodels:\n  - name: my_model\n  - name: my_model_2\n    config:\n      enabled: false\n  - name: my_model_3\n\"\"\"\n\nschema_partial_enabled_yml = \"\"\"\nversion: 2\nmodels:\n  - name: my_model\n  - name: my_model_2\n    config:\n      enabled: True\n  - name: my_model_3\n\"\"\"\n\nschema_invalid_enabled_yml = \"\"\"\nversion: 2\nmodels:\n  - name: my_model\n    config:\n      enabled: True and False\n  - name: my_model_3\n\"\"\"\n\nsimple_snapshot = \"\"\"{% snapshot mysnapshot %}\n\n    {{\n        config(\n          target_schema='snapshots',\n          strategy='timestamp',\n          unique_key='id',\n          updated_at='updated_at'\n        )\n    }}\n\n    select * from dummy\n\n{% endsnapshot %}\"\"\"\n\n\nclass BaseConfigProject:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": models__schema_yml,\n            \"untagged.sql\": models__untagged_sql,\n            \"tagged\": {\"model.sql\": models__tagged__model_sql},\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\"seed.csv\": seeds__seed_csv}\n\n    @pytest.fixture(scope=\"class\")\n    def tests(self):\n        return {\n            \"failing.sql\": tests__failing_sql,\n            \"sleeper_agent.sql\": tests__sleeper_agent_sql,\n        }\n"
  },
  {
    "path": "tests/functional/configs/test_configs.py",
    "content": "import os\n\nimport pytest\n\nfrom dbt.exceptions import SchemaConfigError\nfrom dbt.tests.util import (\n    check_relations_equal,\n    run_dbt,\n    update_config_file,\n    write_file,\n)\nfrom dbt_common.dataclass_schema import ValidationError\nfrom tests.functional.configs.fixtures import BaseConfigProject, simple_snapshot\n\n\nclass TestConfigs(BaseConfigProject):\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"models\": {\n                \"test\": {\n                    \"tagged\": {\n                        # the model configs will override this\n                        \"materialized\": \"invalid\",\n                        # the model configs will append to these\n                        \"tags\": [\"tag_one\"],\n                    }\n                },\n            },\n            \"seeds\": {\n                \"quote_columns\": False,\n            },\n        }\n\n    def test_config_layering(\n        self,\n        project,\n    ):\n        # run seed\n        results = run_dbt([\"seed\"])\n        assert len(results) == 1\n\n        # test the project-level tag, and both config() call tags\n        assert len(run_dbt([\"run\", \"--model\", \"tag:tag_one\"])) == 1\n        assert len(run_dbt([\"run\", \"--model\", \"tag:tag_two\"])) == 1\n        assert len(run_dbt([\"run\", \"--model\", \"tag:tag_three\"])) == 1\n        check_relations_equal(project.adapter, [\"seed\", \"model\"])\n\n        # make sure we overwrote the materialization properly\n        tables = project.get_tables_in_schema()\n        assert tables[\"model\"] == \"table\"\n\n\n# In addition to testing an alternative target-paths setting, it tests that\n# the attribute is jinja rendered and that the context \"modules\" works.\nclass TestTargetConfigs(BaseConfigProject):\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"target-path\": \"target_{{ modules.datetime.datetime.now(modules.pytz.timezone('Etc/UTC')).strftime('%Y%m%dT%H%M%S') }}\",\n            \"seeds\": {\n                \"quote_columns\": False,\n            },\n        }\n\n    def test_alternative_target_paths(self, project):\n        # chdir to a different directory to test creation of target directory under project_root\n        os.chdir(project.profiles_dir)\n        run_dbt([\"seed\"])\n\n        target_path = \"\"\n        for d in os.listdir(project.project_root):\n            if os.path.isdir(os.path.join(project.project_root, d)) and d.startswith(\"target_\"):\n                target_path = d\n        assert os.path.exists(os.path.join(project.project_root, target_path, \"manifest.json\"))\n\n\nclass TestInvalidTestsMaterializationProj(object):\n    def test_tests_materialization_proj_config(self, project):\n        config_patch = {\"data_tests\": {\"materialized\": \"table\"}}\n        update_config_file(config_patch, project.project_root, \"dbt_project.yml\")\n        tests_dir = os.path.join(project.project_root, \"tests\")\n        write_file(\"select * from foo\", tests_dir, \"test.sql\")\n\n        with pytest.raises(SchemaConfigError):\n            run_dbt()\n\n\nclass TestInvalidSeedsMaterializationProj(object):\n    def test_seeds_materialization_proj_config(self, project):\n        config_patch = {\"seeds\": {\"materialized\": \"table\"}}\n        update_config_file(config_patch, project.project_root, \"dbt_project.yml\")\n\n        seeds_dir = os.path.join(project.project_root, \"seeds\")\n        write_file(\"id1, id2\\n1, 2\", seeds_dir, \"seed.csv\")\n\n        with pytest.raises(SchemaConfigError):\n            run_dbt()\n\n\nclass TestInvalidSeedsMaterializationSchema(object):\n    def test_seeds_materialization_schema_config(self, project):\n        seeds_dir = os.path.join(project.project_root, \"seeds\")\n        write_file(\n            \"version: 2\\nseeds:\\n  - name: myseed\\n    config:\\n      materialized: table\",\n            seeds_dir,\n            \"schema.yml\",\n        )\n        write_file(\"id1, id2\\n1, 2\", seeds_dir, \"myseed.csv\")\n\n        with pytest.raises(SchemaConfigError):\n            run_dbt()\n\n\nclass TestInvalidSnapshotsMaterializationProj(object):\n    def test_snapshots_materialization_proj_config(self, project):\n        config_patch = {\"snapshots\": {\"materialized\": \"table\"}}\n        update_config_file(config_patch, project.project_root, \"dbt_project.yml\")\n\n        snapshots_dir = os.path.join(project.project_root, \"snapshots\")\n        write_file(simple_snapshot, snapshots_dir, \"mysnapshot.sql\")\n\n        with pytest.raises(ValidationError):\n            run_dbt()\n\n\nclass TestInvalidSnapshotsMaterializationSchema(object):\n    def test_snapshots_materialization_schema_config(self, project):\n        snapshots_dir = os.path.join(project.project_root, \"snapshots\")\n        write_file(\n            \"version: 2\\nsnapshots:\\n  - name: mysnapshot\\n    config:\\n      materialized: table\",\n            snapshots_dir,\n            \"schema.yml\",\n        )\n        write_file(simple_snapshot, snapshots_dir, \"mysnapshot.sql\")\n\n        with pytest.raises(ValidationError):\n            run_dbt()\n"
  },
  {
    "path": "tests/functional/configs/test_configs_in_schema_files.py",
    "content": "import pytest\n\nfrom dbt.exceptions import CompilationError, ParsingError\nfrom dbt.tests.util import check_relations_equal, get_manifest, run_dbt, write_file\n\nmodels_alt__schema_yml = \"\"\"\nversion: 2\nsources:\n  - name: raw\n    database: \"{{ target.database }}\"\n    schema: \"{{ target.schema }}\"\n    tables:\n      - name: 'some_seed'\n        columns:\n          - name: id\n\nmodels:\n  - name: model\n    description: \"This is a model description\"\n    config:\n        tags: ['tag_in_schema']\n        meta:\n            owner: 'Julie Smith'\n            my_attr: \"{{ var('my_var') }}\"\n        materialized: view\n\n    columns:\n      - name: id\n        data_tests:\n          - not_null:\n              meta:\n                  owner: 'Simple Simon'\n          - unique:\n              config:\n                  meta:\n                      owner: 'John Doe'\n\"\"\"\n\nmodels_alt__untagged_sql = \"\"\"\n{{\n    config(materialized='table')\n}}\n\nselect id, value from {{ source('raw', 'some_seed') }}\n\"\"\"\n\nmodels_alt__tagged__model_sql = \"\"\"\n{{\n    config(\n        materialized='view',\n        tags=['tag_1_in_model'],\n    )\n}}\n\n{{\n    config(\n        materialized='table',\n        tags=['tag_2_in_model'],\n    )\n}}\n\nselect 4 as id, 2 as value\n\"\"\"\n\nmodels_no_materialized__model_sql = \"\"\"\n{{\n    config(\n        tags=['tag_1_in_model'],\n    )\n}}\n\n{{\n    config(\n        tags=['tag_2_in_model'],\n    )\n}}\n\nselect 4 as id, 2 as value\n\"\"\"\n\nseeds_alt__some_seed_csv = \"\"\"id,value\n4,2\n\"\"\"\n\nextra_alt__untagged_yml = \"\"\"\nversion: 2\n\nmodels:\n  - name: untagged\n    description: \"This is a model description\"\n    meta:\n      owner: 'Somebody Else'\n    config:\n        meta:\n            owner: 'Julie Smith'\n\"\"\"\n\nextra_alt__untagged2_yml = \"\"\"\nversion: 2\n\nmodels:\n  - name: untagged\n    description: \"This is a model description\"\n    data_tests:\n      - not_null:\n          error_if: \">2\"\n          config:\n            error_if: \">2\"\n\"\"\"\n\n\nclass TestSchemaFileConfigs:\n    @pytest.fixture(scope=\"class\")\n    def expected_unrendered_config(self):\n        # my_attr is unrendered when state_modified_compare_more_unrendered_values: True\n        return {\n            \"materialized\": \"view\",\n            \"meta\": {\"my_attr\": \"{{ var('my_var') }}\", \"owner\": \"Julie Smith\"},\n            \"tags\": [\"tag_1_in_model\", \"tag_2_in_model\"],\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": models_alt__schema_yml,\n            \"untagged.sql\": models_alt__untagged_sql,\n            \"tagged\": {\"model.sql\": models_alt__tagged__model_sql},\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\"some_seed.csv\": seeds_alt__some_seed_csv}\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"flags\": {\n                \"state_modified_compare_more_unrendered_values\": True,\n            },\n            \"models\": {\n                \"+meta\": {\n                    \"company\": \"NuMade\",\n                },\n                \"test\": {\n                    \"+meta\": {\n                        \"project\": \"test\",\n                    },\n                    \"tagged\": {\n                        \"+meta\": {\n                            \"team\": \"Core Team\",\n                        },\n                        \"tags\": [\"tag_in_project\"],\n                        \"model\": {\n                            \"materialized\": \"table\",\n                            \"+meta\": {\n                                \"owner\": \"Julie Dent\",\n                            },\n                        },\n                    },\n                },\n            },\n            \"vars\": {\n                \"test\": {\n                    \"my_var\": \"TESTING\",\n                }\n            },\n            \"seeds\": {\n                \"quote_columns\": False,\n            },\n        }\n\n    def test_config_layering(\n        self,\n        project,\n        expected_unrendered_config,\n    ):\n\n        # run seed\n        assert len(run_dbt([\"seed\"])) == 1\n\n        # test the project-level tag, and both config() call tags\n        assert len(run_dbt([\"run\", \"--model\", \"tag:tag_in_project\"])) == 1\n        assert len(run_dbt([\"run\", \"--model\", \"tag:tag_1_in_model\"])) == 1\n        assert len(run_dbt([\"run\", \"--model\", \"tag:tag_2_in_model\"])) == 1\n        assert len(run_dbt([\"run\", \"--model\", \"tag:tag_in_schema\"])) == 1\n\n        # Verify that model nodes have expected tags and meta\n        manifest = get_manifest(project.project_root)\n        model_id = \"model.test.model\"\n        model_node = manifest.nodes[model_id]\n        meta_expected = {\n            \"company\": \"NuMade\",\n            \"project\": \"test\",\n            \"team\": \"Core Team\",\n            \"owner\": \"Julie Smith\",\n            \"my_attr\": \"TESTING\",\n        }\n        assert model_node.meta == meta_expected\n        assert model_node.config.meta == meta_expected\n        model_tags = [\"tag_1_in_model\", \"tag_2_in_model\", \"tag_in_project\", \"tag_in_schema\"]\n        model_node_tags = model_node.tags.copy()\n        model_node_tags.sort()\n        assert model_node_tags == model_tags\n        model_node_config_tags = model_node.config.tags.copy()\n        model_node_config_tags.sort()\n        assert model_node_config_tags == model_tags\n        model_meta = {\n            \"company\": \"NuMade\",\n            \"project\": \"test\",\n            \"team\": \"Core Team\",\n            \"owner\": \"Julie Smith\",\n            \"my_attr\": \"TESTING\",\n        }\n        assert model_node.config.meta == model_meta\n\n        # make sure we overwrote the materialization properly\n        tables = project.get_tables_in_schema()\n        assert tables[\"model\"] == \"table\"\n        check_relations_equal(project.adapter, [\"some_seed\", \"model\"])\n\n        # Remove materialized config from model\n        write_file(\n            models_no_materialized__model_sql,\n            project.project_root,\n            \"models\",\n            \"tagged\",\n            \"model.sql\",\n        )\n        results = run_dbt([\"run\"])\n        assert len(results) == 2\n        manifest = get_manifest(project.project_root)\n        model_node = manifest.nodes[model_id]\n\n        assert model_node.config.materialized == \"view\"\n        model_unrendered_config = expected_unrendered_config\n        assert model_node.unrendered_config == model_unrendered_config\n\n        # look for test meta\n        schema_file_id = model_node.patch_path\n        schema_file = manifest.files[schema_file_id]\n        tests = schema_file.get_tests(\"models\", \"model\")\n        assert tests[0] in manifest.nodes\n        test = manifest.nodes[tests[0]]\n        expected_meta = {\"owner\": \"Simple Simon\"}\n        assert test.config.meta == expected_meta\n        test = manifest.nodes[tests[1]]\n        expected_meta = {\"owner\": \"John Doe\"}\n        assert test.config.meta == expected_meta\n\n        # copy a schema file with multiple metas\n        #       shutil.copyfile('extra-alt/untagged.yml', 'models-alt/untagged.yml')\n        write_file(extra_alt__untagged_yml, project.project_root, \"models\", \"untagged.yml\")\n        with pytest.raises(ParsingError):\n            run_dbt([\"run\"])\n\n        # copy a schema file with config key in top-level of test and in config dict\n        #       shutil.copyfile('extra-alt/untagged2.yml', 'models-alt/untagged.yml')\n        write_file(extra_alt__untagged2_yml, project.project_root, \"models\", \"untagged.yml\")\n        with pytest.raises(CompilationError):\n            run_dbt([\"run\"])\n\n\nclass TestLegacySchemaFileConfigs(TestSchemaFileConfigs):\n    @pytest.fixture(scope=\"class\")\n    def expected_unrendered_config(self):\n        # my_attr is rendered (\"TESTING\") when state_modified_compare_more_unrendered_values: False\n        return {\n            \"materialized\": \"view\",\n            \"meta\": {\"my_attr\": \"TESTING\", \"owner\": \"Julie Smith\"},\n            \"tags\": [\"tag_1_in_model\", \"tag_2_in_model\"],\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            # The uncommented below lines can be removed once the default behaviour is flipped.\n            # state_modified_compare_more_unrendered_values defaults to false currently\n            # \"flags\": {\n            #     \"state_modified_compare_more_unrendered_values\": False,\n            # },\n            \"models\": {\n                \"+meta\": {\n                    \"company\": \"NuMade\",\n                },\n                \"test\": {\n                    \"+meta\": {\n                        \"project\": \"test\",\n                    },\n                    \"tagged\": {\n                        \"+meta\": {\n                            \"team\": \"Core Team\",\n                        },\n                        \"tags\": [\"tag_in_project\"],\n                        \"model\": {\n                            \"materialized\": \"table\",\n                            \"+meta\": {\n                                \"owner\": \"Julie Dent\",\n                            },\n                        },\n                    },\n                },\n            },\n            \"vars\": {\n                \"test\": {\n                    \"my_var\": \"TESTING\",\n                }\n            },\n            \"seeds\": {\n                \"quote_columns\": False,\n            },\n        }\n\n\nlist_schema_yml = \"\"\"\n- name: my_name\n- name: alt_name\n\"\"\"\n\n\nclass TestListSchemaFile:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": \"select 1 as id\",\n            \"schema.yml\": list_schema_yml,\n        }\n\n    def test_list_schema(self, project):\n        with pytest.raises(ParsingError) as excinfo:\n            run_dbt([\"run\"])\n        assert \"Dictionary expected\" in str(excinfo.value)\n"
  },
  {
    "path": "tests/functional/configs/test_contract_configs.py",
    "content": "import os\n\nimport pytest\n\nfrom dbt.artifacts.resources.v1.components import ColumnInfo\nfrom dbt.exceptions import ParsingError, ValidationError\nfrom dbt.tests.util import (\n    get_artifact,\n    get_manifest,\n    run_dbt,\n    run_dbt_and_capture,\n    write_file,\n)\nfrom dbt_common.contracts.constraints import ColumnLevelConstraint, ConstraintType\n\nmy_model_sql = \"\"\"\n{{\n  config(\n    materialized = \"table\"\n  )\n}}\n\nselect\n  'blue' as color,\n  1 as id,\n  cast('2019-01-01' as date) as date_day\n\"\"\"\n\nmy_model_contract_sql = \"\"\"\n{{\n  config(\n    materialized = \"table\",\n    contract = {\"enforced\": true}\n  )\n}}\n\nselect\n  1 as id,\n  'blue' as color,\n  cast('2019-01-01' as date) as date_day\n\"\"\"\n\nmy_model_contract_disabled_sql = \"\"\"\n{{\n  config(\n    materialized = \"table\",\n    contract = {\"enforced\": false}\n  )\n}}\n\nselect\n  1 as id,\n  'blue' as color,\n  cast('2019-01-01' as date) as date_day\n\"\"\"\n\nmy_incremental_model_sql = \"\"\"\n{{\n  config(\n    materialized = \"incremental\"\n  )\n}}\n\nselect\n  1 as id,\n  'blue' as color,\n  cast('2019-01-01' as date) as date_day\n\"\"\"\n\nmy_view_model_sql = \"\"\"\n{{\n  config(\n    materialized = \"view\"\n  )\n}}\n\nselect\n  1 as id,\n  'blue' as color,\n  cast('2019-01-01' as date) as date_day\n\"\"\"\n\nmy_model_python_error = \"\"\"\nimport holidays, s3fs\n\n\ndef model(dbt, _):\n    dbt.config(\n        materialized=\"table\",\n        packages=[\"holidays\", \"s3fs\"],  # how to import python libraries in dbt's context\n    )\n    df = dbt.ref(\"my_model\")\n    df_describe = df.describe()  # basic statistics profiling\n    return df_describe\n\"\"\"\n\nmodel_schema_yml = \"\"\"\nmodels:\n  - name: my_model\n    config:\n      contract:\n        enforced: true\n    columns:\n      - name: id\n        quote: true\n        data_type: integer\n        description: hello\n        constraints:\n            - type: not_null\n            - type: primary_key\n            - type: check\n              expression: (id > 0)\n        data_tests:\n          - unique\n      - name: color\n        data_type: string\n      - name: date_day\n        data_type: date\n\"\"\"\n\nmodel_pk_model_column_schema_yml = \"\"\"\nmodels:\n  - name: my_model\n    config:\n      contract:\n        enforced: true\n    constraints:\n      - type: primary_key\n        columns: [id]\n    columns:\n      - name: id\n        data_type: integer\n        description: hello\n        constraints:\n            - type: not_null\n            - type: primary_key\n            - type: check\n              expression: (id > 0)\n        data_tests:\n          - unique\n      - name: color\n        data_type: string\n      - name: date_day\n        data_type: date\n\"\"\"\n\nmodel_pk_mult_column_schema_yml = \"\"\"\nmodels:\n  - name: my_model\n    config:\n      contract:\n        enforced: true\n    columns:\n      - name: id\n        quote: true\n        data_type: integer\n        description: hello\n        constraints:\n            - type: not_null\n            - type: primary_key\n            - type: check\n              expression: (id > 0)\n        data_tests:\n          - unique\n      - name: color\n        data_type: string\n        constraints:\n            - type: not_null\n            - type: primary_key\n      - name: date_day\n        data_type: date\n\"\"\"\n\nmodel_schema_alias_types_false_yml = \"\"\"\nmodels:\n  - name: my_model\n    config:\n      contract:\n        enforced: true\n        alias_types: false\n    columns:\n      - name: id\n        quote: true\n        data_type: integer\n        description: hello\n        constraints:\n            - type: not_null\n            - type: primary_key\n            - type: check\n              expression: (id > 0)\n        data_tests:\n          - unique\n      - name: color\n        data_type: string\n      - name: date_day\n        data_type: date\n\"\"\"\n\nmodel_schema_ignore_unsupported_yml = \"\"\"\nmodels:\n  - name: my_model\n    config:\n      contract:\n        enforced: true\n    columns:\n      - name: id\n        quote: true\n        data_type: integer\n        description: hello\n        constraints:\n            - type: not_null\n              warn_unsupported: False\n            - type: primary_key\n              warn_unsupported: False\n            - type: check\n              warn_unsupported: False\n              expression: (id > 0)\n        data_tests:\n          - unique\n      - name: color\n        data_type: text\n      - name: date_day\n        data_type: date\n\"\"\"\n\nmodel_schema_errors_yml = \"\"\"\nmodels:\n  - name: my_model\n    config:\n      contract:\n        enforced: true\n    columns:\n      - name: id\n        data_type: integer\n        description: hello\n        constraints:\n            - type: not_null\n            - type: primary_key\n            - type: check\n              expression: (id > 0)\n        data_tests:\n          - unique\n      - name: color\n        data_type: text\n      - name: date_day\n  - name: python_model\n    config:\n      contract:\n        enforced: true\n    columns:\n      - name: id\n        data_type: integer\n        description: hello\n        constraints:\n            - type: not_null\n            - type: primary_key\n            - type: check\n              expression: (id > 0)\n        data_tests:\n          - unique\n      - name: color\n        data_type: text\n      - name: date_day\n        data_type: date\n\"\"\"\n\nmodel_schema_blank_yml = \"\"\"\nmodels:\n  - name: my_model\n    config:\n      contract:\n        enforced: true\n\"\"\"\n\nmodel_schema_complete_datatypes_yml = \"\"\"\nmodels:\n  - name: my_model\n    columns:\n      - name: id\n        quote: true\n        data_type: integer\n        description: hello\n        constraints:\n          - type: not_null\n          - type: primary_key\n          - type: check\n            expression: (id > 0)\n        data_tests:\n          - unique\n      - name: color\n        data_type: text\n      - name: date_day\n        data_type: date\n\"\"\"\n\nmodel_schema_incomplete_datatypes_yml = \"\"\"\nmodels:\n  - name: my_model\n    columns:\n      - name: id\n        quote: true\n        data_type: integer\n        description: hello\n        constraints:\n          - type: not_null\n          - type: primary_key\n          - type: check\n            expression: (id > 0)\n        data_tests:\n          - unique\n      - name: color\n      - name: date_day\n        data_type: date\n\"\"\"\n\n\nclass TestModelLevelContractEnabledConfigs:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": my_model_sql,\n            \"constraints_schema.yml\": model_schema_yml,\n        }\n\n    def test__model_contract_true(self, project):\n        run_dbt([\"run\"])\n        manifest = get_manifest(project.project_root)\n        model_id = \"model.test.my_model\"\n        model = manifest.nodes[model_id]\n        my_model_columns = model.columns\n        my_model_config = model.config\n        contract_actual_config = my_model_config.contract\n\n        assert contract_actual_config.enforced is True\n\n        expected_columns = {\n            \"id\": ColumnInfo(\n                name=\"id\",\n                description=\"hello\",\n                meta={},\n                data_type=\"integer\",\n                doc_blocks=[],\n                constraints=[\n                    ColumnLevelConstraint(\n                        type=ConstraintType.not_null,\n                        name=None,\n                        expression=None,\n                        warn_unenforced=True,\n                        warn_unsupported=True,\n                        to=None,\n                        to_columns=[],\n                    ),\n                    ColumnLevelConstraint(\n                        type=ConstraintType.primary_key,\n                        name=None,\n                        expression=None,\n                        warn_unenforced=True,\n                        warn_unsupported=True,\n                        to=None,\n                        to_columns=[],\n                    ),\n                    ColumnLevelConstraint(\n                        type=ConstraintType.check,\n                        name=None,\n                        expression=\"(id > 0)\",\n                        warn_unenforced=True,\n                        warn_unsupported=True,\n                        to=None,\n                        to_columns=[],\n                    ),\n                ],\n                quote=True,\n                tags=[],\n                _extra={},\n                granularity=None,\n            ),\n            \"color\": ColumnInfo(\n                name=\"color\",\n                description=\"\",\n                doc_blocks=[],\n                meta={},\n                data_type=\"string\",\n                constraints=[],\n                quote=None,\n                tags=[],\n                _extra={},\n                granularity=None,\n            ),\n            \"date_day\": ColumnInfo(\n                name=\"date_day\",\n                description=\"\",\n                doc_blocks=[],\n                meta={},\n                data_type=\"date\",\n                constraints=[],\n                quote=None,\n                tags=[],\n                _extra={},\n                granularity=None,\n            ),\n        }\n\n        assert expected_columns == my_model_columns\n\n        # compiled fields aren't in the manifest above because it only has parsed fields\n        manifest_json = get_artifact(project.project_root, \"target\", \"manifest.json\")\n        compiled_code = manifest_json[\"nodes\"][model_id][\"compiled_code\"]\n        cleaned_code = \" \".join(compiled_code.split())\n        assert (\n            \"select 'blue' as color, 1 as id, cast('2019-01-01' as date) as date_day\"\n            == cleaned_code\n        )\n\n        # set alias_types to false (should fail to compile)\n        write_file(\n            model_schema_alias_types_false_yml,\n            project.project_root,\n            \"models\",\n            \"constraints_schema.yml\",\n        )\n        run_dbt([\"run\"], expect_pass=False)\n\n\nclass TestProjectContractEnabledConfigs:\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\"models\": {\"test\": {\"+contract\": {\"enforced\": True}}}}\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": my_model_sql,\n            \"constraints_schema.yml\": model_schema_complete_datatypes_yml,\n        }\n\n    def test_defined_column_type(self, project):\n        run_dbt([\"run\"], expect_pass=True)\n        manifest = get_manifest(project.project_root)\n        model_id = \"model.test.my_model\"\n        my_model_config = manifest.nodes[model_id].config\n        contract_actual_config = my_model_config.contract\n        assert contract_actual_config.enforced is True\n\n\nclass TestProjectContractEnabledConfigsError:\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"models\": {\n                \"test\": {\n                    \"+contract\": {\n                        \"enforced\": True,\n                    },\n                }\n            }\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": my_model_sql,\n            \"constraints_schema.yml\": model_schema_incomplete_datatypes_yml,\n        }\n\n    def test_undefined_column_type(self, project):\n        _, log_output = run_dbt_and_capture([\"run\", \"-s\", \"my_model\"], expect_pass=False)\n        manifest = get_manifest(project.project_root)\n        model_id = \"model.test.my_model\"\n        my_model_config = manifest.nodes[model_id].config\n        contract_actual_config = my_model_config.contract\n\n        assert contract_actual_config.enforced is True\n\n        expected_compile_error = \"Please ensure that the column name and data_type are defined within the YAML configuration for the ['color'] column(s).\"\n\n        assert expected_compile_error in log_output\n\n\nclass TestModelContractEnabledConfigs:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"my_model.sql\": my_model_contract_sql, \"constraints_schema.yml\": model_schema_yml}\n\n    def test__model_contract(self, project):\n        run_dbt([\"run\"])\n        manifest = get_manifest(project.project_root)\n        model_id = \"model.test.my_model\"\n        my_model_config = manifest.nodes[model_id].config\n        contract_actual_config = my_model_config.contract\n        assert contract_actual_config.enforced is True\n\n\nclass TestModelContractEnabledConfigsMissingDataTypes:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": my_model_contract_sql,\n            \"constraints_schema.yml\": model_schema_incomplete_datatypes_yml,\n        }\n\n    def test_undefined_column_type(self, project):\n        _, log_output = run_dbt_and_capture([\"run\", \"-s\", \"my_model\"], expect_pass=False)\n        manifest = get_manifest(project.project_root)\n        model_id = \"model.test.my_model\"\n        my_model_config = manifest.nodes[model_id].config\n        contract_actual_config = my_model_config.contract\n\n        assert contract_actual_config.enforced is True\n\n        expected_compile_error = \"Please ensure that the column name and data_type are defined within the YAML configuration for the ['color'] column(s).\"\n\n        assert expected_compile_error in log_output\n\n\nclass TestModelLevelContractDisabledConfigs:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": my_model_contract_disabled_sql,\n            \"constraints_schema.yml\": model_schema_yml,\n        }\n\n    def test__model_contract_false(self, project):\n\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n        model_id = \"model.test.my_model\"\n        my_model_config = manifest.nodes[model_id].config\n        contract_actual_config = my_model_config.contract\n\n        assert contract_actual_config.enforced is False\n\n\nclass TestModelLevelContractErrorMessages:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": my_incremental_model_sql,\n            \"constraints_schema.yml\": model_schema_yml,\n        }\n\n    def test__config_errors(self, project):\n        with pytest.raises(ValidationError) as err_info:\n            run_dbt([\"run\"], expect_pass=False)\n\n        exc_str = \" \".join(str(err_info.value).split())\n        expected_materialization_error = \"Invalid value for on_schema_change: ignore. Models materialized as incremental with contracts enabled must set on_schema_change to 'append_new_columns' or 'fail'\"\n        assert expected_materialization_error in str(exc_str)\n\n\nclass TestModelLevelConstraintsErrorMessages:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.py\": my_model_python_error,\n            \"constraints_schema.yml\": model_schema_yml,\n        }\n\n    def test__config_errors(self, project):\n        with pytest.raises(ParsingError) as err_info:\n            run_dbt([\"run\"], expect_pass=False)\n\n        exc_str = \" \".join(str(err_info.value).split())\n        expected_materialization_error = \"Language Error: Expected 'sql' but found 'python'\"\n        assert expected_materialization_error in str(exc_str)\n        # This is a compile time error and we won't get here because the materialization check is parse time\n        expected_empty_data_type_error = \"Columns with `data_type` Blank/Null not allowed on contracted models. Columns Blank/Null: ['date_day']\"\n        assert expected_empty_data_type_error not in str(exc_str)\n\n\nclass TestModelLevelConstraintsWarningMessages:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": my_view_model_sql,\n            \"constraints_schema.yml\": model_schema_yml,\n        }\n\n    def test__config_warning(self, project):\n        _, log_output = run_dbt_and_capture([\"run\"])\n\n        expected_materialization_warning = (\n            \"Constraint types are not supported for view materializations\"\n        )\n        assert expected_materialization_warning in str(log_output)\n\n        # change to not show warnings, message should not be in logs\n        models_dir = os.path.join(project.project_root, \"models\")\n        write_file(model_schema_ignore_unsupported_yml, models_dir, \"constraints_schema.yml\")\n        _, log_output = run_dbt_and_capture([\"run\"])\n\n        expected_materialization_warning = (\n            \"Constraint types are not supported for view materializations\"\n        )\n        assert expected_materialization_warning not in str(log_output)\n\n\nclass TestSchemaContractEnabledConfigs:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": my_model_sql,\n            \"constraints_schema.yml\": model_schema_blank_yml,\n        }\n\n    def test__schema_error(self, project):\n        with pytest.raises(ParsingError) as err_info:\n            run_dbt([\"parse\"], expect_pass=False)\n\n        exc_str = \" \".join(str(err_info.value).split())\n        schema_error_expected = \"Constraints must be defined in a `yml` schema configuration file\"\n        assert schema_error_expected in str(exc_str)\n\n\nclass TestPythonModelLevelContractErrorMessages:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"python_model.py\": my_model_python_error,\n            \"constraints_schema.yml\": model_schema_errors_yml,\n        }\n\n    def test__python_errors(self, project):\n        with pytest.raises(ParsingError) as err_info:\n            run_dbt([\"parse\"], expect_pass=False)\n\n        exc_str = \" \".join(str(err_info.value).split())\n        expected_python_error = \"Language Error: Expected 'sql' but found 'python'\"\n        assert expected_python_error in exc_str\n\n\nclass TestModelContractMissingYAMLColumns:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": my_model_contract_sql,\n        }\n\n    def test__missing_column_contract_error(self, project):\n        results = run_dbt([\"run\"], expect_pass=False)\n        expected_error = (\n            \"This model has an enforced contract, and its 'columns' specification is missing\"\n        )\n        assert expected_error in results[0].message\n\n\n# test primary key defined across model and column level constraints, expect error\nclass TestPrimaryKeysModelAndColumnLevelConstraints:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"constraints_schema.yml\": model_pk_model_column_schema_yml,\n            \"my_model.sql\": my_model_sql,\n        }\n\n    def test_model_column_pk_error(self, project):\n        expected_error = \"Primary key constraints defined at the model level and the columns level\"\n        with pytest.raises(ParsingError) as exc_info:\n            run_dbt([\"run\"])\n        assert expected_error in str(exc_info.value)\n\n\n# test primary key defined across multiple columns, expect error\nclass TestPrimaryKeysMultipleColumns:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"constraints_schema.yml\": model_pk_mult_column_schema_yml,\n            \"my_model.sql\": my_model_sql,\n        }\n\n    def test_pk_multiple_columns(self, project):\n        expected_error = \"Found 2 columns (['id', 'color']) with primary key constraints defined\"\n        with pytest.raises(ParsingError) as exc_info:\n            run_dbt([\"run\"])\n        assert expected_error in str(exc_info.value)\n"
  },
  {
    "path": "tests/functional/configs/test_custom_node_colors_configs.py",
    "content": "import pytest\n\nfrom dbt.exceptions import ConfigUpdateError\nfrom dbt.tests.util import get_manifest, run_dbt\nfrom dbt_common.dataclass_schema import ValidationError\n\nCUSTOM_NODE_COLOR_MODEL_LEVEL = \"red\"\nCUSTOM_NODE_COLOR_SCHEMA_LEVEL = \"blue\"\nCUSTOM_NODE_COLOR_PROJECT_LEVEL_ROOT = \"#121212\"\nCUSTOM_NODE_COLOR_PROJECT_LEVEL_FOLDER = \"purple\"\nCUSTOM_NODE_COLOR_INVALID_HEX = '\"#xxx111\"'\nCUSTOM_NODE_COLOR_INVALID_NAME = \"notacolor\"\n\n# F strings are a pain here so replacing XXX with the config above instead\nmodels__custom_node_color__model_sql = \"\"\"\n{{ config(materialized='view', docs={'node_color': 'XXX'}) }}\n\nselect 1 as id\n\n\"\"\".replace(\n    \"XXX\", CUSTOM_NODE_COLOR_MODEL_LEVEL\n)\n\nmodels__non_custom_node_color__model_sql = \"\"\"\n{{ config(materialized='view') }}\n\nselect 1 as id\n\n\"\"\"\n\nmodels__show_docs_false__model_sql = \"\"\"\n{{ config(materialized='view', docs={\"show\": True}) }}\n\nselect 1 as id\n\"\"\"\n\nmodels__custom_node_color__schema_yml = \"\"\"\nversion: 2\n\nmodels:\n  - name: custom_color_model\n    description: \"This is a model description\"\n    config:\n      docs:\n        node_color: {}\n\"\"\".format(\n    CUSTOM_NODE_COLOR_SCHEMA_LEVEL\n)\n\n\nmodels__non_custom_node_color__schema_yml = \"\"\"\nversion: 2\n\nmodels:\n  - name: non_custom_color_model\n    description: \"This is a model description\"\n    config:\n      docs:\n        node_color: {}\n        show: True\n\"\"\".format(\n    CUSTOM_NODE_COLOR_SCHEMA_LEVEL\n)\n\n# To check that incorect configs are raising errors\nmodels__non_custom_node_color_invalid_config_docs__schema_yml = \"\"\"\nversion: 2\n\nmodels:\n  - name: non_custom_node_color\n    description: \"This is a model description\"\n    config:\n      docs:\n        node_color: {}\n        show: True\n\"\"\".format(\n    CUSTOM_NODE_COLOR_INVALID_HEX\n)\n\nmodels__non_custom_node_color_invalid_docs__schema_yml = \"\"\"\nversion: 2\n\nmodels:\n  - name: non_custom_node_color\n    description: \"This is a model description\"\n    docs:\n      node_color: {}\n      show: True\n\"\"\".format(\n    CUSTOM_NODE_COLOR_INVALID_NAME\n)\n\nmodels__custom_node_color_invalid_hex__model_sql = \"\"\"\n{{ config(materialized='view', docs={\"show\": True, \"node_color\": XXX }) }}\n\nselect 1 as id\n\"\"\".replace(\n    \"XXX\", CUSTOM_NODE_COLOR_INVALID_HEX\n)\n\n\nclass BaseCustomNodeColorModelvsProject:\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"models\": {\n                \"test\": {\n                    \"+docs\": {\"node_color\": CUSTOM_NODE_COLOR_PROJECT_LEVEL_ROOT, \"show\": False},\n                    \"subdirectory\": {\n                        \"+docs\": {\n                            \"node_color\": CUSTOM_NODE_COLOR_PROJECT_LEVEL_FOLDER,\n                            \"show\": True,\n                        },\n                    },\n                }\n            }\n        }\n\n\n# validation that model level node_color configs supercede dbt_project.yml\nclass TestModelLevelProjectColorConfigs(BaseCustomNodeColorModelvsProject):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"custom_color_model.sql\": models__custom_node_color__model_sql}\n\n    def test__model_override_project(self, project):\n\n        run_dbt([\"compile\"])\n        manifest = get_manifest(project.project_root)\n        model_id = \"model.test.custom_color_model\"\n        my_model_config = manifest.nodes[model_id].config\n        my_model_docs = manifest.nodes[model_id].docs\n\n        node_color_actual_config = my_model_config[\"docs\"].node_color\n        show_actual_config = my_model_config[\"docs\"].show\n        node_color_actual_docs = my_model_docs.node_color\n        show_actual_docs = my_model_docs.show\n\n        # check node_color config is in the right spots for each model\n        assert node_color_actual_config == CUSTOM_NODE_COLOR_MODEL_LEVEL\n        assert node_color_actual_docs == CUSTOM_NODE_COLOR_MODEL_LEVEL\n        assert not show_actual_config\n        assert not show_actual_docs\n\n\n# validation that model level node_color configs supercede schema.yml\nclass TestModelLevelSchemaColorConfigs(BaseCustomNodeColorModelvsProject):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"custom_color_model.sql\": models__custom_node_color__model_sql,\n            \"custom_color_schema.yml\": models__custom_node_color__schema_yml,\n        }\n\n    def test__model_override_schema(self, project):\n\n        run_dbt([\"compile\"])\n        manifest = get_manifest(project.project_root)\n        model_id = \"model.test.custom_color_model\"\n        my_model_config = manifest.nodes[model_id].config\n        my_model_docs = manifest.nodes[model_id].docs\n\n        node_color_actual_config = my_model_config[\"docs\"].node_color\n        show_actual_config = my_model_config[\"docs\"].show\n        node_color_actual_docs = my_model_docs.node_color\n        show_actual_docs = my_model_docs.show\n\n        # check node_color config is in the right spots for each model\n        assert node_color_actual_config == CUSTOM_NODE_COLOR_MODEL_LEVEL\n        assert node_color_actual_docs == CUSTOM_NODE_COLOR_MODEL_LEVEL\n        assert not show_actual_config\n        assert not show_actual_docs\n\n\n# validation that node_color configured on subdirectories in dbt_project.yml supercedes project root\nclass TestSubdirectoryColorConfigs(BaseCustomNodeColorModelvsProject):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"subdirectory\": {\n                \"non_custom_color_model_subdirectory.sql\": models__non_custom_node_color__model_sql\n            }\n        }\n\n    def test__project_folder_override_project_root(self, project):\n        run_dbt([\"compile\"])\n        manifest = get_manifest(project.project_root)\n        model_id = \"model.test.non_custom_color_model_subdirectory\"\n        my_model_config = manifest.nodes[model_id].config\n        my_model_docs = manifest.nodes[model_id].docs\n\n        node_color_actual_config = my_model_config[\"docs\"].node_color\n        show_actual_config = my_model_config[\"docs\"].show\n        node_color_actual_docs = my_model_docs.node_color\n        show_actual_docs = my_model_docs.show\n\n        # check node_color config is in the right spots for each model\n        assert node_color_actual_config == CUSTOM_NODE_COLOR_PROJECT_LEVEL_FOLDER\n        assert node_color_actual_docs == CUSTOM_NODE_COLOR_PROJECT_LEVEL_FOLDER\n        # in this case show should be True since the dbt_project.yml overrides the root setting for /subdirectory\n        assert show_actual_config\n        assert show_actual_docs\n\n\n# validation that node_color configured in schema.yml supercedes dbt_project.yml\nclass TestSchemaOverProjectColorConfigs(BaseCustomNodeColorModelvsProject):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"non_custom_color_model.sql\": models__non_custom_node_color__model_sql,\n            \"non_custom_color_schema.yml\": models__non_custom_node_color__schema_yml,\n        }\n\n    def test__schema_override_project(\n        self,\n        project,\n    ):\n\n        run_dbt([\"compile\"])\n        manifest = get_manifest(project.project_root)\n\n        model_id = \"model.test.non_custom_color_model\"\n        my_model_config = manifest.nodes[model_id].config\n        my_model_docs = manifest.nodes[model_id].docs\n\n        node_color_actual_config = my_model_config[\"docs\"].node_color\n        show_actual_config = my_model_config[\"docs\"].show\n        node_color_actual_docs = my_model_docs.node_color\n        show_actual_docs = my_model_docs.show\n\n        # check node_color config is in the right spots for each model\n        assert node_color_actual_config == CUSTOM_NODE_COLOR_SCHEMA_LEVEL\n        assert node_color_actual_docs == CUSTOM_NODE_COLOR_SCHEMA_LEVEL\n        # in this case show should be True since the schema.yml overrides the dbt_project.yml\n        assert show_actual_config\n        assert show_actual_docs\n\n\n# validation that docs: show configured in model file supercedes dbt_project.yml\nclass TestModelOverProjectColorConfigs(BaseCustomNodeColorModelvsProject):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"show_docs_override_model.sql\": models__show_docs_false__model_sql}\n\n    def test__model_show_overrides_dbt_project(\n        self,\n        project,\n    ):\n\n        run_dbt([\"compile\"])\n        manifest = get_manifest(project.project_root)\n\n        model_id = \"model.test.show_docs_override_model\"\n        my_model_config = manifest.nodes[model_id].config\n        my_model_docs = manifest.nodes[model_id].docs\n\n        node_color_actual_config = my_model_config[\"docs\"].node_color\n        show_actual_config = my_model_config[\"docs\"].show\n        node_color_actual_docs = my_model_docs.node_color\n        show_actual_docs = my_model_docs.show\n\n        # check node_color config is in the right spots for each model\n        assert node_color_actual_config == CUSTOM_NODE_COLOR_PROJECT_LEVEL_ROOT\n        assert node_color_actual_docs == CUSTOM_NODE_COLOR_PROJECT_LEVEL_ROOT\n        # in this case show should be True since the schema.yml overrides the dbt_project.yml\n        assert show_actual_config\n        assert show_actual_docs\n\n\n# validation that an incorrect color in dbt_project.yml raises an exception\nclass TestCustomNodeColorIncorrectColorProject:\n    @pytest.fixture(scope=\"class\")\n    def models(self):  # noqa: F811\n        return {\"non_custom_node_color.sql\": models__non_custom_node_color__model_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"models\": {\n                \"test\": {\"+docs\": {\"node_color\": CUSTOM_NODE_COLOR_INVALID_NAME, \"show\": False}}\n            }\n        }\n\n    def test__invalid_color_project(\n        self,\n        project,\n    ):\n        with pytest.raises(ValidationError):\n            run_dbt([\"compile\"])\n\n\n# validation that an incorrect color in the config block raises an exception\nclass TestCustomNodeColorIncorrectColorModelConfig:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"custom_node_color_invalid_hex.sql\": models__custom_node_color_invalid_hex__model_sql\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\"models\": {\"+docs\": {\"node_color\": \"blue\", \"show\": False}}}\n\n    def test__invalid_color_config_block(\n        self,\n        project,\n    ):\n        with pytest.raises((ValidationError, ConfigUpdateError)):\n            run_dbt([\"compile\"])\n\n\n# validation that an incorrect color in the YML file raises an exception\nclass TestCustomNodeColorIncorrectColorNameYMLConfig:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"non_custom_node_color.sql\": models__non_custom_node_color__model_sql,\n            \"invalid_custom_color.yml\": models__non_custom_node_color_invalid_docs__schema_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\"models\": {\"+docs\": {\"node_color\": \"blue\", \"show\": False}}}\n\n    def test__invalid_color_docs_not_under_config(\n        self,\n        project,\n    ):\n        with pytest.raises(ValidationError):\n            run_dbt([\"compile\"])\n\n\nclass TestCustomNodeColorIncorrectColorHEXYMLConfig:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"non_custom_node_color.sql\": models__non_custom_node_color__model_sql,\n            \"invalid_custom_color.yml\": models__non_custom_node_color_invalid_config_docs__schema_yml,\n        }\n\n    def test__invalid_color_docs_under_config(\n        self,\n        project,\n    ):\n        with pytest.raises(ValidationError):\n            run_dbt([\"compile\"])\n"
  },
  {
    "path": "tests/functional/configs/test_disabled_configs.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt\nfrom tests.functional.configs.fixtures import BaseConfigProject\n\n\nclass TestDisabledConfigs(BaseConfigProject):\n    @pytest.fixture(scope=\"class\")\n    def dbt_profile_data(self, unique_schema):\n        return {\n            \"test\": {\n                \"outputs\": {\n                    \"default\": {\n                        \"type\": \"postgres\",\n                        # make sure you can do this and get an int out\n                        \"threads\": \"{{ (1 + 3) | as_number }}\",\n                        \"host\": \"localhost\",\n                        \"port\": \"{{ (5400 + 32) | as_number }}\",\n                        \"user\": \"root\",\n                        \"pass\": \"password\",\n                        \"dbname\": \"dbt\",\n                        \"schema\": unique_schema,\n                    },\n                    \"disabled\": {\n                        \"type\": \"postgres\",\n                        # make sure you can do this and get an int out\n                        \"threads\": \"{{ (1 + 3) | as_number }}\",\n                        \"host\": \"localhost\",\n                        \"port\": \"{{ (5400 + 32) | as_number }}\",\n                        \"user\": \"root\",\n                        \"pass\": \"password\",\n                        \"dbname\": \"dbt\",\n                        \"schema\": unique_schema,\n                    },\n                },\n                \"target\": \"default\",\n            },\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"models\": {\n                \"test\": {\n                    \"enabled\": \"{{ (target.name == 'default' | as_bool) }}\",\n                },\n            },\n            # set the `var` result in schema.yml to be 'seed', so that the\n            # `source` call can suceed.\n            \"vars\": {\n                \"test\": {\n                    \"seed_name\": \"seed\",\n                }\n            },\n            \"seeds\": {\n                \"quote_columns\": False,\n                \"test\": {\n                    \"seed\": {\n                        \"enabled\": \"{{ (target.name == 'default') | as_bool }}\",\n                    },\n                },\n            },\n            \"data_tests\": {\n                \"test\": {\n                    \"enabled\": \"{{ (target.name == 'default') | as_bool }}\",\n                    \"severity\": \"WARN\",\n                },\n            },\n        }\n\n    def test_disable_seed_partial_parse(self, project):\n        run_dbt([\"--partial-parse\", \"seed\", \"--target\", \"disabled\"])\n        run_dbt([\"--partial-parse\", \"seed\", \"--target\", \"disabled\"])\n\n    def test_conditional_model(self, project):\n        # no seeds/models - enabled should eval to False because of the target\n        results = run_dbt([\"seed\", \"--target\", \"disabled\"])\n        assert len(results) == 0\n        results = run_dbt([\"run\", \"--target\", \"disabled\"])\n        assert len(results) == 0\n        results = run_dbt([\"test\", \"--target\", \"disabled\"])\n        assert len(results) == 0\n\n        # has seeds/models - enabled should eval to True because of the target\n        results = run_dbt([\"seed\"])\n        assert len(results) == 1\n        results = run_dbt([\"run\"])\n        assert len(results) == 2\n        results = run_dbt([\"test\"])\n        assert len(results) == 5\n\n\nmy_analysis_sql = \"\"\"\n{{\n    config(enabled=False)\n}}\nselect 1 as id\n\"\"\"\n\n\nschema_yml = \"\"\"\nmodels:\n  - name: my_analysis\n    description: \"A Sample model\"\n    config:\n        meta:\n          owner: Joe\n\nanalyses:\n  - name: my_analysis\n    description: \"A sample analysis\"\n    config:\n      enabled: false\n\"\"\"\n\n\nclass TestDisabledConfigsSameName:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_analysis.sql\": my_analysis_sql,\n            \"schema.yml\": schema_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def analyses(self):\n        return {\n            \"my_analysis.sql\": my_analysis_sql,\n        }\n\n    def test_disabled_analysis(self, project):\n        manifest = run_dbt([\"parse\"])\n        assert len(manifest.disabled) == 2\n        assert len(manifest.nodes) == 0\n"
  },
  {
    "path": "tests/functional/configs/test_disabled_model.py",
    "content": "import pytest\n\nfrom dbt.exceptions import CompilationError, ParsingError, SchemaConfigError\nfrom dbt.tests.util import get_manifest, run_dbt\nfrom tests.functional.configs.fixtures import (\n    my_model,\n    my_model_2,\n    my_model_2_disabled,\n    my_model_2_enabled,\n    my_model_3,\n    my_model_3_disabled,\n    my_model_3_enabled,\n    schema_all_disabled_yml,\n    schema_explicit_enabled_yml,\n    schema_invalid_enabled_yml,\n    schema_partial_disabled_yml,\n    schema_partial_enabled_yml,\n)\n\n\n# ensure double disabled doesn't throw error when set at schema level\nclass TestSchemaDisabledConfigs:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": schema_all_disabled_yml,\n            \"my_model.sql\": my_model,\n            \"my_model_2.sql\": my_model_2,\n            \"my_model_3.sql\": my_model_3,\n        }\n\n    def test_disabled_config(self, project):\n        run_dbt([\"parse\"])\n\n\n# ensure this throws a specific error that the model is disabled\nclass TestSchemaDisabledConfigsFailure:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": schema_partial_disabled_yml,\n            \"my_model.sql\": my_model,\n            \"my_model_2.sql\": my_model_2,\n            \"my_model_3.sql\": my_model_3,\n        }\n\n    def test_disabled_config(self, project):\n        with pytest.raises(CompilationError) as exc:\n            run_dbt([\"parse\"])\n        exc_str = \" \".join(str(exc.value).split())  # flatten all whitespace\n        expected_msg = \"which is disabled\"\n        assert expected_msg in exc_str\n\n\n# ensure double disabled doesn't throw error when set in model configs\nclass TestModelDisabledConfigs:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": my_model,\n            \"my_model_2.sql\": my_model_2_disabled,\n            \"my_model_3.sql\": my_model_3_disabled,\n        }\n\n    def test_disabled_config(self, project):\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n        assert \"model.test.my_model_2\" not in manifest.nodes\n        assert \"model.test.my_model_3\" not in manifest.nodes\n\n        assert \"model.test.my_model_2\" in manifest.disabled\n        assert \"model.test.my_model_3\" in manifest.disabled\n\n\n# ensure config set in project.yml can be overridden in yaml file\nclass TestOverrideProjectConfigsInYaml:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": schema_partial_enabled_yml,\n            \"my_model.sql\": my_model,\n            \"my_model_2.sql\": my_model_2,\n            \"my_model_3.sql\": my_model_3,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"models\": {\n                \"test\": {\n                    \"my_model_2\": {\n                        \"enabled\": False,\n                    },\n                    \"my_model_3\": {\n                        \"enabled\": False,\n                    },\n                },\n            }\n        }\n\n    def test_override_project_yaml_config(self, project):\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n        assert \"model.test.my_model_2\" in manifest.nodes\n        assert \"model.test.my_model_3\" not in manifest.nodes\n\n        assert \"model.test.my_model_2\" not in manifest.disabled\n        assert \"model.test.my_model_3\" in manifest.disabled\n\n\n# ensure config set in project.yml can be overridden in sql file\nclass TestOverrideProjectConfigsInSQL:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": my_model,\n            \"my_model_2.sql\": my_model_2_enabled,\n            \"my_model_3.sql\": my_model_3,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"models\": {\n                \"test\": {\n                    \"my_model_2\": {\n                        \"enabled\": False,\n                    },\n                    \"my_model_3\": {\n                        \"enabled\": False,\n                    },\n                },\n            }\n        }\n\n    def test_override_project_sql_config(self, project):\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n        assert \"model.test.my_model_2\" in manifest.nodes\n        assert \"model.test.my_model_3\" not in manifest.nodes\n\n        assert \"model.test.my_model_2\" not in manifest.disabled\n        assert \"model.test.my_model_3\" in manifest.disabled\n\n\n# ensure false config set in yaml file can be overridden in sql file\nclass TestOverrideFalseYAMLConfigsInSQL:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": schema_all_disabled_yml,\n            \"my_model.sql\": my_model,\n            \"my_model_2.sql\": my_model_2_enabled,\n            \"my_model_3.sql\": my_model_3,\n        }\n\n    def test_override_yaml_sql_config(self, project):\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n        assert \"model.test.my_model_2\" in manifest.nodes\n        assert \"model.test.my_model_3\" not in manifest.nodes\n\n        assert \"model.test.my_model_2\" not in manifest.disabled\n        assert \"model.test.my_model_3\" in manifest.disabled\n\n\n# ensure true config set in yaml file can be overridden by false in sql file\nclass TestOverrideTrueYAMLConfigsInSQL:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": schema_explicit_enabled_yml,\n            \"my_model.sql\": my_model,\n            \"my_model_2.sql\": my_model_2_enabled,\n            \"my_model_3.sql\": my_model_3_disabled,\n        }\n\n    def test_override_yaml_sql_config(self, project):\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n        assert \"model.test.my_model_2\" in manifest.nodes\n        assert \"model.test.my_model_3\" not in manifest.nodes\n\n        assert \"model.test.my_model_2\" not in manifest.disabled\n        assert \"model.test.my_model_3\" in manifest.disabled\n\n\n# ensure error when enabling in schema file when multiple nodes exist within disabled\nclass TestMultipleDisabledNodesForUniqueIDFailure:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": schema_partial_enabled_yml,\n            \"my_model.sql\": my_model,\n            \"folder_1\": {\n                \"my_model_2.sql\": my_model_2_disabled,\n                \"my_model_3.sql\": my_model_3_disabled,\n            },\n            \"folder_2\": {\n                \"my_model_2.sql\": my_model_2_disabled,\n                \"my_model_3.sql\": my_model_3_disabled,\n            },\n            \"folder_3\": {\n                \"my_model_2.sql\": my_model_2_disabled,\n                \"my_model_3.sql\": my_model_3_disabled,\n            },\n        }\n\n    def test_disabled_config(self, project):\n        with pytest.raises(ParsingError) as exc:\n            run_dbt([\"parse\"])\n        exc_str = \" \".join(str(exc.value).split())  # flatten all whitespace\n        expected_msg = \"Found 3 matching disabled nodes for model 'my_model_2'\"\n        assert expected_msg in exc_str\n\n\n# ensure error when enabling in schema file when multiple nodes exist within disabled\nclass TestMultipleDisabledNodesSuccess:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": my_model,\n            \"folder_1\": {\n                \"my_model_2.sql\": my_model_2,\n                \"my_model_3.sql\": my_model_3,\n            },\n            \"folder_2\": {\n                \"my_model_2.sql\": my_model_2,\n                \"my_model_3.sql\": my_model_3,\n            },\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"models\": {\n                \"test\": {\n                    \"folder_1\": {\n                        \"enabled\": False,\n                    },\n                    \"folder_2\": {\n                        \"enabled\": True,\n                    },\n                },\n            }\n        }\n\n    def test_multiple_disabled_config(self, project):\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n        assert \"model.test.my_model_2\" in manifest.nodes\n        assert \"model.test.my_model_3\" in manifest.nodes\n\n        expected_file_path = \"folder_2\"\n        assert expected_file_path in manifest.nodes[\"model.test.my_model_2\"].original_file_path\n        assert expected_file_path in manifest.nodes[\"model.test.my_model_3\"].original_file_path\n\n        assert \"model.test.my_model_2\" in manifest.disabled\n        assert \"model.test.my_model_3\" in manifest.disabled\n\n        expected_disabled_file_path = \"folder_1\"\n        assert (\n            expected_disabled_file_path\n            in manifest.disabled[\"model.test.my_model_2\"][0].original_file_path\n        )\n        assert (\n            expected_disabled_file_path\n            in manifest.disabled[\"model.test.my_model_3\"][0].original_file_path\n        )\n\n\n# ensure overrides work when enabling in sql file when multiple nodes exist within disabled\nclass TestMultipleDisabledNodesOverrideModel:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": my_model,\n            \"folder_1\": {\n                \"my_model_2.sql\": my_model_2_enabled,\n                \"my_model_3.sql\": my_model_3,\n            },\n            \"folder_2\": {\n                \"my_model_2.sql\": my_model_2,\n                \"my_model_3.sql\": my_model_3_enabled,\n            },\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"models\": {\n                \"test\": {\n                    \"folder_1\": {\n                        \"enabled\": False,\n                    },\n                    \"folder_2\": {\n                        \"enabled\": False,\n                    },\n                },\n            }\n        }\n\n    def test_multiple_disabled_config(self, project):\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n        assert \"model.test.my_model_2\" in manifest.nodes\n        assert \"model.test.my_model_3\" in manifest.nodes\n\n        expected_file_path_2 = \"folder_1\"\n        assert expected_file_path_2 in manifest.nodes[\"model.test.my_model_2\"].original_file_path\n        expected_file_path_3 = \"folder_2\"\n        assert expected_file_path_3 in manifest.nodes[\"model.test.my_model_3\"].original_file_path\n\n        assert \"model.test.my_model_2\" in manifest.disabled\n        assert \"model.test.my_model_3\" in manifest.disabled\n\n        expected_disabled_file_path_2 = \"folder_2\"\n        assert (\n            expected_disabled_file_path_2\n            in manifest.disabled[\"model.test.my_model_2\"][0].original_file_path\n        )\n        expected_disabled_file_path_3 = \"folder_1\"\n        assert (\n            expected_disabled_file_path_3\n            in manifest.disabled[\"model.test.my_model_3\"][0].original_file_path\n        )\n\n\n# ensure everything lands where it should when disabling multiple nodes with the same unique id\nclass TestManyDisabledNodesSuccess:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": my_model,\n            \"folder_1\": {\n                \"my_model_2.sql\": my_model_2,\n                \"my_model_3.sql\": my_model_3,\n            },\n            \"folder_2\": {\n                \"my_model_2.sql\": my_model_2,\n                \"my_model_3.sql\": my_model_3,\n            },\n            \"folder_3\": {\n                \"my_model_2.sql\": my_model_2,\n                \"my_model_3.sql\": my_model_3,\n            },\n            \"folder_4\": {\n                \"my_model_2.sql\": my_model_2,\n                \"my_model_3.sql\": my_model_3,\n            },\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"models\": {\n                \"test\": {\n                    \"folder_1\": {\n                        \"enabled\": False,\n                    },\n                    \"folder_2\": {\n                        \"enabled\": True,\n                    },\n                    \"folder_3\": {\n                        \"enabled\": False,\n                    },\n                    \"folder_4\": {\n                        \"enabled\": False,\n                    },\n                },\n            }\n        }\n\n    def test_many_disabled_config(self, project):\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n        assert \"model.test.my_model_2\" in manifest.nodes\n        assert \"model.test.my_model_3\" in manifest.nodes\n\n        expected_file_path = \"folder_2\"\n        assert expected_file_path in manifest.nodes[\"model.test.my_model_2\"].original_file_path\n        assert expected_file_path in manifest.nodes[\"model.test.my_model_3\"].original_file_path\n\n        assert len(manifest.disabled[\"model.test.my_model_2\"]) == 3\n        assert len(manifest.disabled[\"model.test.my_model_3\"]) == 3\n\n\nclass TestInvalidEnabledConfig:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": schema_invalid_enabled_yml,\n            \"my_model.sql\": my_model,\n        }\n\n    def test_invalid_config(self, project):\n        with pytest.raises(SchemaConfigError) as exc:\n            run_dbt([\"parse\"])\n        exc_str = \" \".join(str(exc.value).split())  # flatten all whitespace\n        expected_msg = \"'True and False' is not of type 'boolean'\"\n        assert expected_msg in exc_str\n"
  },
  {
    "path": "tests/functional/configs/test_dupe_paths.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt\n\nmy_model_sql = \"\"\"\nselect 1 as fun\n\"\"\"\n\nseed_csv = \"\"\"id,value\n4,2\n\"\"\"\n\nsomedoc_md = \"\"\"\n{% docs somedoc %}\nTesting, testing\n{% enddocs %}\n\"\"\"\n\nschema_yml = \"\"\"\nversion: 2\nmodels:\n  - name: my_model\n    description: testing model\n\"\"\"\n\n\n# Either a docs or a yml file is necessary to see the problem\n# when two of the paths in 'all_source_paths' are the same\nclass TestDupeProjectPaths:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": my_model_sql,\n            \"seed.csv\": seed_csv,\n            \"somedoc.md\": somedoc_md,\n            \"schema.yml\": schema_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"model-paths\": [\"models\"],\n            \"seed-paths\": [\"models\"],\n        }\n\n    def test_config_with_dupe_paths(self, project, dbt_project_yml):\n        results = run_dbt([\"seed\"])\n        assert len(results) == 1\n        results = run_dbt([\"run\"])\n        assert len(results) == 1\n\n\nclass TestDupeStrippedProjectPaths:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": my_model_sql,\n            \"seed.csv\": seed_csv,\n            \"somedoc.md\": somedoc_md,\n            \"schema.yml\": schema_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"model-paths\": [\"models/\"],\n            \"seed-paths\": [\"models\"],\n        }\n\n    def test_config_with_dupe_paths(self, project, dbt_project_yml):\n        results = run_dbt([\"seed\"])\n        assert len(results) == 1\n        results = run_dbt([\"run\"])\n        assert len(results) == 1\n"
  },
  {
    "path": "tests/functional/configs/test_get_default.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt, write_file\n\nmodels_get__any_model_sql = \"\"\"\n-- models/any_model.sql\nselect {{ config.get('made_up_nonexistent_key', 'default_value') }} as col_value\n\n\"\"\"\n\nmeta_model_get_sql = \"\"\"\n-- models/meta_model.sql\nselect {{ config.get('meta_key', 'meta_default_value') }} as col_value\n\"\"\"\n\nmeta_model_meta_get_sql = \"\"\"\n-- models/meta_model.sql\nselect {{ config.meta_get('meta_key', 'meta_default_value') }} as col_value\n\"\"\"\n\nschema_yml = \"\"\"\nmodels:\n - name: meta_model\n   config:\n     meta:\n       meta_key: my_meta_value\n\"\"\"\n\nmeta_model_require_sql = \"\"\"\n-- models/meta_model.sql\nselect {{ config.require('meta_key') }} as col_value\n\"\"\"\n\nmeta_model_meta_require_sql = \"\"\"\n-- models/meta_model.sql\nselect {{ config.meta_require('meta_key') }} as col_value\n\"\"\"\n\n\nclass TestConfigGetDefault:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"any_model.sql\": models_get__any_model_sql}\n\n    def test_config_with_get_default(\n        self,\n        project,\n    ):\n        # This test runs a model with a config.get(key, default)\n        # The default value is 'default_value' and causes an error\n        results = run_dbt([\"run\"], expect_pass=False)\n        assert len(results) == 1\n        assert str(results[0].status) == \"error\"\n        assert 'column \"default_value\" does not exist' in results[0].message\n\n\nclass TestConfigGetMeta:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"meta_model.sql\": meta_model_get_sql,\n            \"schema.yml\": schema_yml,\n        }\n\n    def test_config_with_meta_key(\n        self,\n        project,\n    ):\n        # This test runs a model with a config.get(key, default) -> default value returned\n        results = run_dbt([\"run\"], expect_pass=False)\n        assert len(results) == 1\n        assert str(results[0].status) == \"error\"\n        assert 'column \"meta_default_value\" does not exist' in results[0].message\n\n        write_file(meta_model_meta_get_sql, \"models\", \"meta_model.sql\")\n        results = run_dbt([\"run\"], expect_pass=False)\n        assert len(results) == 1\n        assert str(results[0].status) == \"error\"\n        assert 'column \"my_meta_value\" does not exist' in results[0].message\n\n\nclass TestConfigGetMetaRequire:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"meta_model.sql\": meta_model_require_sql,\n            \"schema.yml\": schema_yml,\n        }\n\n    def test_config_with_meta_require(\n        self,\n        project,\n    ):\n        # This test runs a model with a config.require(key)\n        results = run_dbt([\"run\"], expect_pass=False)\n        assert len(results) == 1\n        assert str(results[0].status) == \"error\"\n        assert \"does not define a required config parameter 'meta_key'\" in results[0].message\n\n        write_file(meta_model_meta_require_sql, \"models\", \"meta_model.sql\")\n        results = run_dbt([\"run\"], expect_pass=False)\n        assert len(results) == 1\n        assert str(results[0].status) == \"error\"\n        assert 'column \"my_meta_value\" does not exist' in results[0].message\n"
  },
  {
    "path": "tests/functional/configs/test_grant_configs.py",
    "content": "import pytest\n\nfrom dbt.tests.util import get_manifest, run_dbt, write_config_file, write_file\n\ndbt_project_yml = \"\"\"\nmodels:\n  test:\n    my_model:\n      +grants:\n        my_select: [\"reporter\", \"bi\"]\n\"\"\"\n\nappend_schema_yml = \"\"\"\nversion: 2\nmodels:\n  - name: my_model\n    config:\n      grants:\n        +my_select: [\"someone\"]\n\"\"\"\n\n\nmy_model_base_sql = \"\"\"\nselect 1 as fun\n\"\"\"\n\n\nmy_model_clobber_sql = \"\"\"\n{{ config(grants={'my_select': ['other_user']}) }}\nselect 1 as fun\n\"\"\"\n\nmy_model_extend_sql = \"\"\"\n{{ config(grants={'+my_select': ['other_user']}) }}\nselect 1 as fun\n\"\"\"\n\nmy_model_extend_string_sql = \"\"\"\n{{ config(grants={'+my_select': 'other_user'}) }}\nselect 1 as fun\n\"\"\"\n\nmy_model_extend_twice_sql = \"\"\"\n{{ config(grants={'+my_select': ['other_user']}) }}\n{{ config(grants={'+my_select': ['alt_user']}) }}\nselect 1 as fun\n\"\"\"\n\n\nclass TestGrantConfigs:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"my_model.sql\": my_model_base_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return dbt_project_yml\n\n    def test_model_grant_config(self, project, logs_dir):\n        # This test uses \"my_select\" instead of \"select\", so we need\n        # use \"parse\" instead of \"run\" because we will get compilation\n        # errors for the grants.\n        run_dbt([\"parse\"])\n\n        manifest = get_manifest(project.project_root)\n        model_id = \"model.test.my_model\"\n        assert model_id in manifest.nodes\n\n        model = manifest.nodes[model_id]\n        model_config = model.config\n        assert hasattr(model_config, \"grants\")\n\n        # no schema grant, no model grant, just project\n        expected = {\"my_select\": [\"reporter\", \"bi\"]}\n        assert model_config.grants == expected\n\n        # add model grant with clobber\n        write_file(my_model_clobber_sql, project.project_root, \"models\", \"my_model.sql\")\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n        model_config = manifest.nodes[model_id].config\n\n        expected = {\"my_select\": [\"other_user\"]}\n        assert model_config.grants == expected\n\n        # change model to extend grants\n        write_file(my_model_extend_sql, project.project_root, \"models\", \"my_model.sql\")\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n        model_config = manifest.nodes[model_id].config\n\n        expected = {\"my_select\": [\"reporter\", \"bi\", \"other_user\"]}\n        assert model_config.grants == expected\n\n        # add schema file with extend\n        write_file(append_schema_yml, project.project_root, \"models\", \"schema.yml\")\n        run_dbt([\"parse\"])\n\n        manifest = get_manifest(project.project_root)\n        model_config = manifest.nodes[model_id].config\n\n        expected = {\"my_select\": [\"reporter\", \"bi\", \"someone\", \"other_user\"]}\n        assert model_config.grants == expected\n\n        # change model file to have string instead of list\n        write_file(my_model_extend_string_sql, project.project_root, \"models\", \"my_model.sql\")\n        run_dbt([\"parse\"])\n\n        manifest = get_manifest(project.project_root)\n        model_config = manifest.nodes[model_id].config\n\n        expected = {\"my_select\": [\"reporter\", \"bi\", \"someone\", \"other_user\"]}\n        assert model_config.grants == expected\n\n        # change model file to have string instead of list\n        write_file(my_model_extend_twice_sql, project.project_root, \"models\", \"my_model.sql\")\n        run_dbt([\"parse\"])\n\n        manifest = get_manifest(project.project_root)\n        model_config = manifest.nodes[model_id].config\n\n        expected = {\"my_select\": [\"reporter\", \"bi\", \"someone\", \"other_user\", \"alt_user\"]}\n        assert model_config.grants == expected\n\n        # Remove grant from dbt_project\n        config = {\n            \"config-version\": 2,\n            \"name\": \"test\",\n            \"version\": \"0.1.0\",\n            \"profile\": \"test\",\n            \"log-path\": logs_dir,\n        }\n        write_config_file(config, project.project_root, \"dbt_project.yml\")\n        run_dbt([\"parse\"])\n\n        manifest = get_manifest(project.project_root)\n        model_config = manifest.nodes[model_id].config\n\n        expected = {\"my_select\": [\"someone\", \"other_user\", \"alt_user\"]}\n        assert model_config.grants == expected\n\n        # Remove my_model config, leaving only schema file\n        write_file(my_model_base_sql, project.project_root, \"models\", \"my_model.sql\")\n        run_dbt([\"parse\"])\n\n        manifest = get_manifest(project.project_root)\n        model_config = manifest.nodes[model_id].config\n\n        expected = {\"my_select\": [\"someone\"]}\n        assert model_config.grants == expected\n"
  },
  {
    "path": "tests/functional/configs/test_indiv_tests.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt\nfrom tests.functional.configs.fixtures import BaseConfigProject\n\n\nclass TestConfigIndivTests(BaseConfigProject):\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"seeds\": {\n                \"quote_columns\": False,\n            },\n            \"vars\": {\n                \"test\": {\n                    \"seed_name\": \"seed\",\n                }\n            },\n            \"data_tests\": {\"test\": {\"enabled\": True, \"severity\": \"WARN\"}},\n        }\n\n    def test_configuring_individual_tests(\n        self,\n        project,\n    ):\n        assert len(run_dbt([\"seed\"])) == 1\n        assert len(run_dbt([\"run\"])) == 2\n\n        # all tests on (minus sleeper_agent) + WARN\n        assert len(run_dbt([\"test\"])) == 5\n\n        # turn off two of them directly\n        assert len(run_dbt([\"test\", \"--vars\", '{\"enabled_direct\": False}'])) == 3\n\n        # turn on sleeper_agent data test directly\n        assert (\n            len(\n                run_dbt(\n                    [\"test\", \"--models\", \"sleeper_agent\", \"--vars\", '{\"enabled_direct\": True}']\n                )\n            )\n            == 1\n        )\n\n        # set three to ERROR directly\n        results = run_dbt(\n            [\n                \"test\",\n                \"--models\",\n                \"config.severity:error\",\n                \"--vars\",\n                '{\"enabled_direct\": True, \"severity_direct\": \"ERROR\"}',\n            ],\n            expect_pass=False,\n        )\n        assert len(results) == 2\n        assert results[0].status == \"fail\"\n        assert results[1].status == \"fail\"\n"
  },
  {
    "path": "tests/functional/configs/test_unused_configs.py",
    "content": "import pytest\n\nfrom dbt.exceptions import CompilationError\nfrom dbt.tests.util import run_dbt\n\nseeds__seed_csv = \"\"\"id,value\n4,2\n\"\"\"\n\n\nclass TestUnusedModelConfigs:\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\"seed.csv\": seeds__seed_csv}\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"test-paths\": [\"does-not-exist\"],\n            \"models\": {\n                \"test\": {\n                    \"enabled\": True,\n                }\n            },\n            \"seeds\": {\n                \"quote_columns\": False,\n            },\n            \"sources\": {\n                \"test\": {\n                    \"enabled\": True,\n                }\n            },\n            \"data_tests\": {\n                \"test\": {\n                    \"enabled\": True,\n                }\n            },\n        }\n\n    def test_warn_unused_configuration_paths(\n        self,\n        project,\n    ):\n        with pytest.raises(CompilationError) as excinfo:\n            run_dbt([\"--warn-error\", \"seed\"])\n\n        assert \"Configuration paths exist\" in str(excinfo.value)\n        assert \"- sources.test\" in str(excinfo.value)\n        assert \"- models.test\" in str(excinfo.value)\n        assert \"- models.test\" in str(excinfo.value)\n\n        run_dbt([\"seed\"])\n"
  },
  {
    "path": "tests/functional/configs/test_vars_file.py",
    "content": "import pytest\nimport yaml\n\nfrom dbt.artifacts.schemas.results import RunStatus\nfrom dbt.exceptions import DbtProjectError\nfrom dbt.tests.util import get_manifest, relation_from_name, run_dbt\nfrom dbt_common.exceptions import CompilationError\n\n# =============================================================================\n# Fixtures - Models, Macros, etc.\n# =============================================================================\n\n# SQL model that uses a var\nmodel_with_var_sql = \"\"\"\n{{ config(materialized='table') }}\nselect '{{ var(\"my_var\") }}' as my_var_value\n\"\"\"\n\n# SQL model that uses multiple vars\nmodel_with_multiple_vars_sql = \"\"\"\n{{ config(materialized='table') }}\nselect\n    '{{ var(\"var_one\") }}' as var_one_value,\n    '{{ var(\"var_two\") }}' as var_two_value\n\"\"\"\n\n# SQL model that uses a package-scoped var\nmodel_with_package_var_sql = \"\"\"\n{{ config(materialized='table') }}\nselect '{{ var(\"package_var\") }}' as package_var_value\n\"\"\"\n\n# SQL model that calls a macro which uses a var\nmodel_calling_macro_sql = \"\"\"\n{{ config(materialized='table') }}\nselect '{{ get_var_value() }}' as macro_var_value\n\"\"\"\n\n# Macro that uses a var\nmacro_with_var_sql = \"\"\"\n{% macro get_var_value() -%}\n{{ var(\"macro_var\") }}\n{%- endmacro %}\n\"\"\"\n\n\nclass TestDbtProjectVarFromVarsFile:\n    \"\"\"dbt_project.yml with var should be rendered properly when var is set through vars.yml\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model_with_var.sql\": model_with_var_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"models\": {\n                \"+meta\": {\n                    \"project_var\": \"{{ var('project_var') }}\",\n                }\n            }\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def vars_yml_update(self):\n        return {\"vars\": {\"my_var\": \"from_file\", \"project_var\": \"project_var_from_file\"}}\n\n    def test_dbt_project_var_from_vars_file(self, project):\n        results = run_dbt([\"run\"])\n        assert len(results) == 1\n        assert results[0].status == RunStatus.Success\n\n        manifest = get_manifest(project.project_root)\n        assert manifest is not None\n        model = manifest.nodes[\"model.test.model_with_var\"]\n        assert model.config.meta[\"project_var\"] == \"project_var_from_file\"\n\n\nclass TestDbtProjectVarCliOverridesFile:\n    \"\"\"dbt_project.yml with var should use CLI value when set in both vars.yml and cli\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model_with_var.sql\": model_with_var_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"models\": {\n                \"+meta\": {\n                    \"project_var\": \"{{ var('project_var') }}\",\n                }\n            }\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def vars_yml_update(self):\n        return {\"vars\": {\"my_var\": \"from_file\", \"project_var\": \"from_file\"}}\n\n    def test_cli_overrides_vars_file(self, project):\n        cli_vars = {\"my_var\": \"from_cli\", \"project_var\": \"from_cli\"}\n        results = run_dbt([\"run\", \"--vars\", yaml.safe_dump(cli_vars)])\n        assert len(results) == 1\n\n        # Verify CLI value was used in SQL model\n        relation = relation_from_name(project.adapter, \"model_with_var\")\n        result = project.run_sql(f\"select my_var_value from {relation}\", fetch=\"one\")\n        assert result[0] == \"from_cli\"\n\n        # Verify CLI value was used to render dbt_project.yml\n        manifest = get_manifest(project.project_root)\n        model = manifest.nodes[\"model.test.model_with_var\"]\n        assert model.config.meta[\"project_var\"] == \"from_cli\"\n\n\nclass TestDbtProjectVarMissingFromVarsFile:\n    \"\"\"dbt should throw error if dbt_project.yml expects a var not present in vars.yml\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model_with_var.sql\": model_with_var_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"models\": {\n                \"+meta\": {\n                    \"missing_var\": \"{{ var('missing_var') }}\",\n                }\n            }\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def vars_yml_update(self):\n        return {\"vars\": {\"my_var\": \"from_file\"}}\n\n    def test_error_when_var_missing(\n        self, project_root, profiles_root, profiles_yml, dbt_project_yml\n    ):\n        # This test expects an error during project setup, so we can't use the project fixture.\n        # We must pass --project-dir and --profiles-dir explicitly since the adapter fixture\n        # (which normally sets these flags) is not used.\n        with pytest.raises(\n            CompilationError, match=\"Required var 'missing_var' not found in config\"\n        ):\n            run_dbt(\n                [\n                    \"run\",\n                    \"--project-dir\",\n                    str(project_root),\n                    \"--profiles-dir\",\n                    str(profiles_root),\n                ],\n                expect_pass=False,\n            )\n\n\nclass TestSqlModelVarFromVarsFile:\n    \"\"\"SQL model with variable should be rendered properly when var is set through vars.yml\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model_with_var.sql\": model_with_var_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def vars_yml_update(self, project_root):\n        return {\"vars\": {\"my_var\": \"sql_var_from_file\"}}\n\n    def test_sql_model_var_from_file(self, project):\n        results = run_dbt([\"run\"])\n        assert len(results) == 1\n        relation = relation_from_name(project.adapter, \"model_with_var\")\n        result = project.run_sql(f\"select my_var_value from {relation}\", fetch=\"one\")\n        assert result[0] == \"sql_var_from_file\"\n\n\nclass TestSqlModelVarCliOverridesFile:\n    \"\"\"SQL model with variable should use CLI value when set in both vars.yml and cli\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model_with_var.sql\": model_with_var_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def vars_yml_udpate(self, project_root):\n        return {\"vars\": {\"my_var\": \"from_file\"}}\n\n    def test_sql_model_cli_overrides_file(self, project):\n        cli_vars = {\"my_var\": \"from_cli\"}\n        results = run_dbt([\"run\", \"--vars\", yaml.safe_dump(cli_vars)])\n        assert len(results) == 1\n        relation = relation_from_name(project.adapter, \"model_with_var\")\n        result = project.run_sql(f\"select my_var_value from {relation}\", fetch=\"one\")\n        assert result[0] == \"from_cli\"\n\n\nclass TestSqlModelVarMissingFromVarsFile:\n    \"\"\"dbt should throw an error if sql model expects a var not set in vars.yml\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        # Model expects 'my_var' but it won't be provided\n        return {\"model_with_var.sql\": model_with_var_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def vars_yml(self, project_root):\n        return {\"vars\": {\"other_var\": \"value\"}}\n\n    def test_error_when_model_var_missing(self, project):\n        # run_dbt with expect_pass=False doesn't raise, it returns results with errors\n        results = run_dbt([\"run\"], expect_pass=False)\n        # The run should have an error for the missing var\n        assert len(results) == 1\n        assert results[0].status == \"error\"\n\n\nclass TestMacroVarFromVarsFile:\n    \"\"\"Macro using var should be rendered properly when var is set through vars.yml\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model_calling_macro.sql\": model_calling_macro_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"my_macro.sql\": macro_with_var_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def vars_yml_update(self, project_root):\n        return {\"vars\": {\"macro_var\": \"macro_var_from_file\"}}\n\n    def test_macro_var_from_file(self, project):\n        results = run_dbt([\"run\"])\n        assert len(results) == 1\n        relation = relation_from_name(project.adapter, \"model_calling_macro\")\n        result = project.run_sql(f\"select macro_var_value from {relation}\", fetch=\"one\")\n        assert result[0] == \"macro_var_from_file\"\n\n\nclass TestMacroVarCliOverridesFile:\n    \"\"\"Macro using var should use CLI value when set in both vars.yml and cli\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model_calling_macro.sql\": model_calling_macro_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"my_macro.sql\": macro_with_var_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def vars_yml(self, project_root):\n        return {\"vars\": {\"macro_var\": \"from_file\"}}\n\n    def test_macro_var_cli_overrides_file(self, project):\n        cli_vars = {\"macro_var\": \"from_cli\"}\n        results = run_dbt([\"run\", \"--vars\", yaml.safe_dump(cli_vars)])\n        assert len(results) == 1\n        relation = relation_from_name(project.adapter, \"model_calling_macro\")\n        result = project.run_sql(f\"select macro_var_value from {relation}\", fetch=\"one\")\n        assert result[0] == \"from_cli\"\n\n\nclass TestMutualExclusivityError:\n    \"\"\"Project should throw error when variables are set in both vars.yml and dbt_project.yml\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model_with_var.sql\": model_with_var_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"name\": \"test\",\n            \"vars\": {\n                \"my_var\": \"from_project\",\n            },\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def vars_yml_update(self, project_root):\n        return {\"vars\": {\"my_var\": \"from_file\"}}\n\n    def test_error_when_both_have_vars(\n        self, project_root, profiles_root, profiles_yml, dbt_project_yml\n    ):\n        # run_dbt catches exceptions, so we use run_dbt_and_capture to check output\n        with pytest.raises(\n            DbtProjectError,\n            match=\"Variables cannot be defined in both vars.yml and dbt_project.yml.\",\n        ):\n            run_dbt(\n                [\n                    \"run\",\n                    \"--project-dir\",\n                    str(project_root),\n                    \"--profiles-dir\",\n                    str(profiles_root),\n                ],\n                expect_pass=False,\n            )\n\n\nclass TestEmptyVarsFileAllowsProjectVars:\n    \"\"\"If vars.yml file is empty, vars from dbt_project.yml should be used\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model_with_var.sql\": model_with_var_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"vars\": {\n                \"my_var\": \"from_project\",\n            }\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def vars_yml_update(self, project_root):\n        return {}\n\n    def test_empty_vars_file_uses_project_vars(self, project):\n        results = run_dbt([\"run\"])\n        assert len(results) == 1\n        relation = relation_from_name(project.adapter, \"model_with_var\")\n        result = project.run_sql(f\"select my_var_value from {relation}\", fetch=\"one\")\n        assert result[0] == \"from_project\"\n\n\nclass TestVarsFileWithoutVarsKeyAllowsProjectVars:\n    \"\"\"Vars declared in vars.yml without a top level 'vars' key should use vars from dbt_project.yml\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model_with_var.sql\": model_with_var_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"vars\": {\n                \"my_var\": \"from_project\",\n            }\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def vars_yml_update(self, project_root):\n        return {\"other_key\": \"some_value\"}\n\n    def test_vars_file_without_vars_key_uses_project_vars(self, project):\n        results = run_dbt([\"run\"])\n        assert len(results) == 1\n        relation = relation_from_name(project.adapter, \"model_with_var\")\n        result = project.run_sql(f\"select my_var_value from {relation}\", fetch=\"one\")\n        assert result[0] == \"from_project\"\n\n\nclass TestPartialCliOverride:\n    \"\"\"Variables from vars.yml and CLI should be merged\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model_with_multiple_vars.sql\": model_with_multiple_vars_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def vars_yml_update(self, project_root):\n        return {\n            \"vars\": {\n                \"var_two\": \"var_two_from_file\",\n            }\n        }\n\n    def test_partial_cli_override(self, project):\n        # Only override var_one, var_two should come from file\n        cli_vars = {\"var_one\": \"var_one_from_cli\"}\n        results = run_dbt([\"run\", \"--vars\", yaml.safe_dump(cli_vars)])\n        assert len(results) == 1\n        relation = relation_from_name(project.adapter, \"model_with_multiple_vars\")\n        result = project.run_sql(\n            f\"select var_one_value, var_two_value from {relation}\", fetch=\"one\"\n        )\n        assert result[0] == \"var_one_from_cli\"  # From CLI\n        assert result[1] == \"var_two_from_file\"  # From file\n\n\nclass TestComplexVarValues:\n    \"\"\"Complex var values like lists and dicts should work from vars.yml\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_with_list_var.sql\": \"\"\"\n{{ config(materialized='table') }}\nselect '{{ var(\"list_var\") | join(\",\") }}' as list_value\n\"\"\",\n            \"model_with_dict_var.sql\": \"\"\"\n{{ config(materialized='table') }}\nselect '{{ var(\"dict_var\").key1 }}' as dict_value\n\"\"\",\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def vars_yml_update(self, project_root):\n        return {\n            \"vars\": {\n                \"list_var\": [\"a\", \"b\", \"c\"],\n                \"dict_var\": {\"key1\": \"value1\", \"key2\": \"value2\"},\n            }\n        }\n\n    def test_complex_var_values(self, project):\n        results = run_dbt([\"run\"])\n        assert len(results) == 2\n\n        list_relation = relation_from_name(project.adapter, \"model_with_list_var\")\n        list_result = project.run_sql(f\"select list_value from {list_relation}\", fetch=\"one\")\n        assert list_result[0] == \"a,b,c\"\n\n        dict_relation = relation_from_name(project.adapter, \"model_with_dict_var\")\n        dict_result = project.run_sql(f\"select dict_value from {dict_relation}\", fetch=\"one\")\n        assert dict_result[0] == \"value1\"\n"
  },
  {
    "path": "tests/functional/configs/test_versioned_model_constraint.py",
    "content": "import pytest\n\nfrom dbt.exceptions import ParsingError\nfrom dbt.tests.util import get_manifest, rm_file, run_dbt, write_file\n\nschema_yml = \"\"\"\nmodels:\n  - name: foo\n    config:\n      materialized: table\n      contract:\n        enforced: true\n    constraints:\n      - type: primary_key\n        columns: [id, user_name]\n    columns:\n      - name: id\n        data_type: int\n        constraints:\n          - type: not_null\n      - name: user_name\n        data_type: text\n\"\"\"\n\nfoo_sql = \"\"\"\nselect 1 as id, 'alice' as user_name\n\"\"\"\n\nfoo_v2_sql = \"\"\"\nselect 1 as id, 'alice' as user_name, 2 as another_pk\n\"\"\"\n\nversioned_schema_yml = \"\"\"\nmodels:\n  - name: foo\n    latest_version: 1\n    config:\n      materialized: table\n      contract:\n        enforced: true\n    constraints:\n      - type: primary_key\n        columns: [id, user_name]\n    columns:\n      - name: id\n        data_type: int\n        constraints:\n          - type: not_null\n      - name: user_name\n        data_type: text\n    versions:\n      - v: 1\n\"\"\"\n\nversioned_pk_model_column_schema_yml = \"\"\"\nmodels:\n  - name: foo\n    latest_version: 2\n    config:\n      materialized: table\n      contract:\n        enforced: true\n    constraints:\n      - type: primary_key\n        columns: [id]\n    columns:\n      - name: id\n        data_type: int\n        constraints:\n          - type: not_null\n      - name: user_name\n        data_type: text\n    versions:\n      - v: 1\n      - v: 2\n        columns:\n          - name: id\n            data_type: int\n            constraints:\n              - type: not_null\n              - type: primary_key\n          - name: user_name\n            data_type: text\n\"\"\"\n\nversioned_pk_mult_columns_schema_yml = \"\"\"\nmodels:\n  - name: foo\n    latest_version: 2\n    config:\n      materialized: table\n      contract:\n        enforced: true\n    columns:\n      - name: id\n        data_type: int\n        constraints:\n          - type: not_null\n          - type: primary_key\n      - name: user_name\n        data_type: text\n    versions:\n      - v: 1\n      - v: 2\n        columns:\n          - name: id\n            data_type: int\n            constraints:\n              - type: not_null\n              - type: primary_key\n          - name: user_name\n            data_type: text\n            constraints:\n              - type: primary_key\n\n\"\"\"\n\n\nclass TestVersionedModelConstraints:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"foo.sql\": foo_sql,\n            \"schema.yml\": schema_yml,\n        }\n\n    def test_versioned_model_constraints(self, project):\n        results = run_dbt([\"run\"])\n        assert len(results) == 1\n        manifest = get_manifest(project.project_root)\n        model_node = manifest.nodes[\"model.test.foo\"]\n        assert len(model_node.constraints) == 1\n\n        # remove foo.sql and create foo_v1.sql\n        rm_file(project.project_root, \"models\", \"foo.sql\")\n        write_file(foo_sql, project.project_root, \"models\", \"foo_v1.sql\")\n        write_file(versioned_schema_yml, project.project_root, \"models\", \"schema.yml\")\n        results = run_dbt([\"run\"])\n        assert len(results) == 1\n\n        manifest = get_manifest(project.project_root)\n        model_node = manifest.nodes[\"model.test.foo.v1\"]\n        assert model_node.contract.enforced is True\n        assert len(model_node.constraints) == 1\n\n\n# test primary key defined across model and column level constraints, expect error\nclass TestPrimaryKeysModelAndColumnLevelConstraints:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"foo.sql\": foo_sql,\n            \"schema.yml\": schema_yml,\n        }\n\n    def test_model_column_pk_error(self, project):\n        results = run_dbt([\"run\"])\n        assert len(results) == 1\n        manifest = get_manifest(project.project_root)\n        model_node = manifest.nodes[\"model.test.foo\"]\n        assert len(model_node.constraints) == 1\n\n        # remove foo.sql and create foo_v1.sql\n        rm_file(project.project_root, \"models\", \"foo.sql\")\n        write_file(foo_sql, project.project_root, \"models\", \"foo_v1.sql\")\n        write_file(versioned_schema_yml, project.project_root, \"models\", \"schema.yml\")\n        results = run_dbt([\"run\"])\n        assert len(results) == 1\n\n        manifest = get_manifest(project.project_root)\n        model_node = manifest.nodes[\"model.test.foo.v1\"]\n        assert model_node.contract.enforced is True\n        assert len(model_node.constraints) == 1\n\n        # add foo_v2.sql\n        write_file(foo_sql, project.project_root, \"models\", \"foo_v2.sql\")\n        write_file(\n            versioned_pk_model_column_schema_yml, project.project_root, \"models\", \"schema.yml\"\n        )\n\n        expected_error = \"Primary key constraints defined at the model level and the columns level\"\n        with pytest.raises(ParsingError) as exc_info:\n            run_dbt([\"run\"])\n        assert expected_error in str(exc_info.value)\n\n\n# test primary key defined across multiple columns, expect error\nclass TestPrimaryKeysMultipleColumns:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"foo.sql\": foo_sql,\n            \"schema.yml\": schema_yml,\n        }\n\n    def test_pk_multiple_columns(self, project):\n        results = run_dbt([\"run\"])\n        assert len(results) == 1\n        manifest = get_manifest(project.project_root)\n        model_node = manifest.nodes[\"model.test.foo\"]\n        assert len(model_node.constraints) == 1\n\n        # remove foo.sql and create foo_v1.sql\n        rm_file(project.project_root, \"models\", \"foo.sql\")\n        write_file(foo_sql, project.project_root, \"models\", \"foo_v1.sql\")\n        write_file(versioned_schema_yml, project.project_root, \"models\", \"schema.yml\")\n        results = run_dbt([\"run\"])\n        assert len(results) == 1\n\n        manifest = get_manifest(project.project_root)\n        model_node = manifest.nodes[\"model.test.foo.v1\"]\n        assert model_node.contract.enforced is True\n        assert len(model_node.constraints) == 1\n\n        # add foo_v2.sql\n        write_file(foo_sql, project.project_root, \"models\", \"foo_v2.sql\")\n        write_file(\n            versioned_pk_mult_columns_schema_yml, project.project_root, \"models\", \"schema.yml\"\n        )\n\n        expected_error = (\n            \"Found 2 columns (['id', 'user_name']) with primary key constraints defined\"\n        )\n        with pytest.raises(ParsingError) as exc_info:\n            run_dbt([\"run\"])\n        assert expected_error in str(exc_info.value)\n"
  },
  {
    "path": "tests/functional/configs/test_warn_error_options.py",
    "content": "from typing import Any, Dict, Union\n\nimport pytest\n\nfrom dbt.cli.main import dbtRunner, dbtRunnerResult\nfrom dbt.events.types import (\n    DeprecatedModel,\n    MainEncounteredError,\n    MicrobatchModelNoEventTimeInputs,\n)\nfrom dbt.flags import get_flags\nfrom dbt.tests.util import run_dbt, update_config_file\nfrom dbt_common.events.base_types import EventLevel\nfrom dbt_common.events.event_catcher import EventCatcher\n\nModelsDictSpec = Dict[str, Union[str, \"ModelsDictSpec\"]]\n\nmy_model_sql = \"\"\"SELECT 1 AS id, 'cats are cute' AS description\"\"\"\nschema_yml = \"\"\"\nversion: 2\nmodels:\n  - name: my_model\n    deprecation_date: 2020-01-01\n\"\"\"\n\n\nclass BaseTestWarnErrorOptions:\n    @pytest.fixture(scope=\"class\")\n    def models(self) -> ModelsDictSpec:\n        return {\"my_model.sql\": my_model_sql, \"schema.yml\": schema_yml}\n\n    @pytest.fixture(scope=\"function\")\n    def catcher(self) -> EventCatcher:\n        return EventCatcher(event_to_catch=DeprecatedModel)\n\n    @pytest.fixture(scope=\"function\")\n    def runner(self, catcher: EventCatcher) -> dbtRunner:\n        return dbtRunner(callbacks=[catcher.catch])\n\n    def assert_deprecation_warning(self, result: dbtRunnerResult, catcher: EventCatcher) -> None:\n        assert result.success\n        assert result.exception is None\n        assert len(catcher.caught_events) == 1\n        assert catcher.caught_events[0].info.level == EventLevel.WARN.value\n\n    def assert_deprecation_error(self, result: dbtRunnerResult) -> None:\n        assert not result.success\n        assert result.exception is not None\n        assert \"Model my_model has passed its deprecation date of\" in str(result.exception)\n\n\nclass TestWarnErrorOptionsFromCLICanSilence(BaseTestWarnErrorOptions):\n    def test_can_silence(self, project, catcher: EventCatcher, runner: dbtRunner) -> None:\n        result = runner.invoke([\"run\"])\n        self.assert_deprecation_warning(result, catcher)\n\n        catcher.flush()\n        result = runner.invoke([\"run\", \"--warn-error-options\", \"{'silence': ['DeprecatedModel']}\"])\n        assert result.success\n        assert len(catcher.caught_events) == 0\n\n\nclass TestWarnErrorOptionsFromCLICanRaiseWarningToError(BaseTestWarnErrorOptions):\n    def test_can_raise_warning_to_error(\n        self, project, catcher: EventCatcher, runner: dbtRunner\n    ) -> None:\n        result = runner.invoke([\"run\"])\n        self.assert_deprecation_warning(result, catcher)\n\n        catcher.flush()\n        result = runner.invoke([\"run\", \"--warn-error-options\", \"{'include': ['DeprecatedModel']}\"])\n        self.assert_deprecation_error(result)\n\n        catcher.flush()\n        result = runner.invoke(\n            [\n                \"run\",\n                \"--warn-error-options\",\n                \"{'include': 'all', 'warn': ['DeprecationsSummary', 'WEOIncludeExcludeDeprecation']}\",\n            ]\n        )\n        self.assert_deprecation_error(result)\n\n        catcher.flush()\n        result = runner.invoke([\"run\", \"--warn-error-options\", \"{'error': ['DeprecatedModel']}\"])\n        self.assert_deprecation_error(result)\n\n        catcher.flush()\n        result = runner.invoke(\n            [\"run\", \"--warn-error-options\", \"{'error': 'all', 'warn': ['DeprecationsSummary']}\"]\n        )\n        self.assert_deprecation_error(result)\n\n\nclass TestWarnErrorOptionsFromCLICanExcludeSpecificEvent(BaseTestWarnErrorOptions):\n    def test_can_exclude_specific_event(\n        self, project, catcher: EventCatcher, runner: dbtRunner\n    ) -> None:\n        result = runner.invoke(\n            [\"run\", \"--warn-error-options\", \"{'error': 'all', 'warn': ['DeprecationsSummary']}\"]\n        )\n        self.assert_deprecation_error(result)\n\n        catcher.flush()\n        result = runner.invoke(\n            [\n                \"run\",\n                \"--warn-error-options\",\n                \"{'error': 'all', 'exclude': ['DeprecatedModel', 'WEOIncludeExcludeDeprecation', 'DeprecationsSummary']}\",\n            ]\n        )\n        self.assert_deprecation_warning(result, catcher)\n\n        catcher.flush()\n        result = runner.invoke(\n            [\n                \"run\",\n                \"--warn-error-options\",\n                \"{'error': 'all', 'warn': ['DeprecatedModel', 'DeprecationsSummary']}\",\n            ]\n        )\n        self.assert_deprecation_warning(result, catcher)\n\n\nclass TestWarnErrorOptionsFromCLICantSetBothIncludeAndError(BaseTestWarnErrorOptions):\n    def test_cant_set_both_include_and_error(self, project, runner: dbtRunner) -> None:\n        result = runner.invoke(\n            [\"run\", \"--warn-error-options\", \"{'include': 'all', 'error': 'all'}\"]\n        )\n        assert not result.success\n        assert result.exception is not None\n        assert \"Only `include` or `error` can be specified\" in str(result.exception)\n\n    def test_cant_set_both_exclude_and_warn(self, project, runner: dbtRunner) -> None:\n        result = runner.invoke(\n            [\n                \"run\",\n                \"--warn-error-options\",\n                \"{'include': 'all', 'exclude': ['DeprecatedModel'], 'warn': ['DeprecatedModel']}\",\n            ]\n        )\n        assert not result.success\n        assert result.exception is not None\n        assert \"Only `exclude` or `warn` can be specified\" in str(result.exception)\n\n\nclass BaseTestWarnErrorOptionsFromProject(BaseTestWarnErrorOptions):\n    @pytest.fixture(scope=\"function\")\n    def clear_project_flags(self, project_root) -> None:\n        # TODO: Is this still necessary now that the project based tests are broken into separate test classes?\n        flags: Dict[str, Any] = {\"flags\": {}}\n        update_config_file(flags, project_root, \"dbt_project.yml\")\n\n\nclass TestWarnErrorOptionsFromProjectCanSilence(BaseTestWarnErrorOptionsFromProject):\n    def test_can_silence(\n        self, project, clear_project_flags, project_root, catcher: EventCatcher, runner: dbtRunner\n    ) -> None:\n        result = runner.invoke([\"run\"])\n        self.assert_deprecation_warning(result, catcher)\n\n        silence_options = {\"flags\": {\"warn_error_options\": {\"silence\": [\"DeprecatedModel\"]}}}\n        update_config_file(silence_options, project_root, \"dbt_project.yml\")\n\n        catcher.flush()\n        result = runner.invoke([\"run\"])\n        assert result.success\n        assert len(catcher.caught_events) == 0\n\n\nclass TestWarnErrorOptionsFromProjectCanRaiseWarningToError(BaseTestWarnErrorOptionsFromProject):\n    def test_can_raise_warning_to_error(\n        self, project, clear_project_flags, project_root, catcher: EventCatcher, runner: dbtRunner\n    ) -> None:\n        result = runner.invoke([\"run\"])\n        self.assert_deprecation_warning(result, catcher)\n\n        warn_error_options: Dict[str, Any] = {\n            \"flags\": {\"warn_error_options\": {\"error\": [\"DeprecatedModel\"]}}\n        }\n        update_config_file(warn_error_options, project_root, \"dbt_project.yml\")\n\n        catcher.flush()\n        result = runner.invoke([\"run\"])\n        self.assert_deprecation_error(result)\n\n        warn_error_options = {\n            \"flags\": {\"warn_error_options\": {\"error\": \"all\", \"warn\": [\"DeprecationsSummary\"]}}\n        }\n        update_config_file(warn_error_options, project_root, \"dbt_project.yml\")\n\n        catcher.flush()\n        result = runner.invoke([\"run\"])\n        self.assert_deprecation_error(result)\n\n\nclass TestWarnErrorOptionsFromProjectCanExcludeSpecificEvent(BaseTestWarnErrorOptionsFromProject):\n    @pytest.mark.skip(\n        reason=\"Flaky on structured logging tests, EventCatcher inexplicably picks up on 'include' usage across classes\"\n    )\n    def test_can_exclude_specific_event(\n        self, project, clear_project_flags, project_root, catcher: EventCatcher, runner: dbtRunner\n    ) -> None:\n        warn_error_options: Dict[str, Any] = {\n            \"flags\": {\"warn_error_options\": {\"error\": \"all\", \"warn\": [\"DeprecationsSummary\"]}}\n        }\n        update_config_file(warn_error_options, project_root, \"dbt_project.yml\")\n        result = runner.invoke([\"run\"])\n        self.assert_deprecation_error(result)\n\n        warn_error_options = {\n            \"flags\": {\n                \"warn_error_options\": {\n                    \"error\": \"all\",\n                    \"warn\": [\"DeprecatedModel\", \"DeprecationsSummary\"],\n                }\n            }\n        }\n        update_config_file(warn_error_options, project_root, \"dbt_project.yml\")\n\n        catcher.flush()\n        result = runner.invoke([\"run\"])\n        self.assert_deprecation_warning(result, catcher)\n\n\nclass TestWarnErrorOptionsFromProjectCantSetBothIncludeAndError(\n    BaseTestWarnErrorOptionsFromProject\n):\n    def test_cant_set_both_include_and_error(\n        self, project, clear_project_flags, project_root, runner: dbtRunner\n    ) -> None:\n        warn_error_options = {\"flags\": {\"warn_error_options\": {\"include\": \"all\", \"error\": \"all\"}}}\n        update_config_file(warn_error_options, project_root, \"dbt_project.yml\")\n        result = runner.invoke([\"run\"])\n        assert not result.success\n        assert result.exception is not None\n        assert \"Only `include` or `error` can be specified\" in str(result.exception)\n\n\nclass TestWarnErrorOptionsFromProjectCantSetBothExcludeAndWarn(\n    BaseTestWarnErrorOptionsFromProject\n):\n    def test_cant_set_both_exclude_and_warn(\n        self, project, clear_project_flags, project_root, runner: dbtRunner\n    ) -> None:\n        warn_error_options = {\n            \"flags\": {\n                \"warn_error_options\": {\n                    \"error\": \"all\",\n                    \"exclude\": [\"DeprecatedModel\"],\n                    \"warn\": [\"DeprecatedModel\"],\n                }\n            }\n        }\n        update_config_file(warn_error_options, project_root, \"dbt_project.yml\")\n        result = runner.invoke([\"run\"])\n        assert not result.success\n        assert result.exception is not None\n        assert \"Only `exclude` or `warn` can be specified\" in str(result.exception)\n\n\nclass TestEmptyWarnError:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"my_model.sql\": my_model_sql, \"schema.yml\": schema_yml}\n\n    # This tests for a bug in creating WarnErrorOptions when warn or\n    # error are set to None (in yaml =  warn:)\n    def test_project_flags(self, project):\n        project_flags = {\n            \"flags\": {\n                \"send_anonymous_usage_stats\": False,\n                \"warn_error_options\": {\n                    \"warn\": None,\n                    \"error\": None,\n                    \"silence\": [\"TestsConfigDeprecation\"],\n                },\n            }\n        }\n        update_config_file(project_flags, project.project_root, \"dbt_project.yml\")\n        run_dbt([\"run\"])\n        flags = get_flags()\n        assert flags.warn_error_options.silence == [\"TestsConfigDeprecation\"]\n\n\ninput_model_without_event_time_sql = \"\"\"\n{{ config(materialized='table') }}\n\nselect 1 as id, TIMESTAMP '2020-01-01 00:00:00-0' as event_time\nunion all\nselect 2 as id, TIMESTAMP '2020-01-02 00:00:00-0' as event_time\nunion all\nselect 3 as id, TIMESTAMP '2020-01-03 00:00:00-0' as event_time\n\"\"\"\n\nmicrobatch_model_sql = \"\"\"\n{{config(materialized='incremental', incremental_strategy='microbatch', unique_key='id', event_time='event_time', batch_size='day', begin=modules.datetime.datetime.now())}}\nSELECT id, event_time FROM {{ ref('input_model') }}\n\"\"\"\n\n\nclass TestRequireAllWarningsHandledByWarnErrorBehaviorFlag:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"input_model.sql\": input_model_without_event_time_sql,\n            \"microbatch_model.sql\": microbatch_model_sql,\n        }\n\n    def test_require_all_warnings_handed_by_warn_error_behavior_flag(self, project):\n        # Setup the event catchers\n        microbatch_warning_catcher = EventCatcher(event_to_catch=MicrobatchModelNoEventTimeInputs)\n        microbatch_error_catcher = EventCatcher(event_to_catch=MainEncounteredError)\n        dbt_runner = dbtRunner(\n            callbacks=[microbatch_warning_catcher.catch, microbatch_error_catcher.catch]\n        )\n\n        # Run the command without the behavior flag off\n        project_flags = {\n            \"flags\": {\n                \"send_anonymous_usage_stats\": False,\n                \"require_all_warnings_handled_by_warn_error\": False,\n            }\n        }\n        update_config_file(project_flags, project.project_root, \"dbt_project.yml\")\n        dbt_runner.invoke([\"run\", \"--warn-error\"])\n\n        assert len(microbatch_warning_catcher.caught_events) == 1\n        assert len(microbatch_error_catcher.caught_events) == 0\n\n        # Reset the event catchers\n        microbatch_warning_catcher.flush()\n        microbatch_error_catcher.flush()\n\n        # Run the command with the behavior flag on\n        project_flags = {\n            \"flags\": {\n                \"send_anonymous_usage_stats\": False,\n                \"require_all_warnings_handled_by_warn_error\": True,\n            }\n        }\n        update_config_file(project_flags, project.project_root, \"dbt_project.yml\")\n        dbt_runner.invoke([\"run\", \"--warn-error\", \"--log-format\", \"json\"])\n\n        assert len(microbatch_warning_catcher.caught_events) == 0\n        assert len(microbatch_error_catcher.caught_events) == 1\n"
  },
  {
    "path": "tests/functional/conftest.py",
    "content": "import pytest\n\nfrom tests.functional.fixtures.happy_path_fixture import (  # noqa:D\n    happy_path_project,\n    happy_path_project_files,\n)\n\n\n@pytest.fixture(scope=\"function\", autouse=True)\ndef clear_memoized_get_package_with_retries():\n    # This fixture is used to clear the memoized cache for _get_package_with_retries\n    # in dbt.clients.registry. This is necessary because the cache is shared across\n    # tests and can cause unexpected behavior if not cleared as some tests depend on\n    # the deprecation warning that _get_package_with_retries fires\n    yield\n    from dbt.clients.registry import _get_cached\n\n    _get_cached.cache = {}\n\n\n@pytest.fixture(autouse=True)\ndef clear_buffered_deprecations():\n    # buffered_deprecations is a module-level list that can retain stale entries\n    # across tests in the same process. This happens when Flags.__init__ buffers\n    # a deprecation (via normalize_warn_error_options) but then raises before\n    # fire_buffered_deprecations() is called to drain and clear the buffer.\n    # The stale entry then fires in the next test's invocation, potentially\n    # causing spurious failures (e.g. WEOIncludeExcludeDeprecation + --warn-error).\n    from dbt.deprecations import buffered_deprecations\n\n    buffered_deprecations.clear()\n"
  },
  {
    "path": "tests/functional/constraints/fixtures.py",
    "content": "model_foreign_key_model_schema_yml = \"\"\"\nmodels:\n  - name: my_model\n    constraints:\n      - type: foreign_key\n        columns: [id]\n        to: ref('my_model_to')\n        to_columns: [id]\n    columns:\n      - name: id\n        data_type: integer\n\"\"\"\n\n\nmodel_foreign_key_source_schema_yml = \"\"\"\nsources:\n  - name: test_source\n    tables:\n      - name: test_table\n\nmodels:\n  - name: my_model\n    constraints:\n      - type: foreign_key\n        columns: [id]\n        to: source('test_source', 'test_table')\n        to_columns: [id]\n    columns:\n      - name: id\n        data_type: integer\n\"\"\"\n\n\nmodel_foreign_key_model_node_not_found_schema_yml = \"\"\"\nmodels:\n  - name: my_model\n    constraints:\n      - type: foreign_key\n        columns: [id]\n        to: ref('doesnt_exist')\n        to_columns: [id]\n    columns:\n      - name: id\n        data_type: integer\n\"\"\"\n\n\nmodel_foreign_key_model_invalid_syntax_schema_yml = \"\"\"\nmodels:\n  - name: my_model\n    constraints:\n      - type: foreign_key\n        columns: [id]\n        to: invalid\n        to_columns: [id]\n    columns:\n      - name: id\n        data_type: integer\n\"\"\"\n\n\nmodel_foreign_key_model_column_schema_yml = \"\"\"\nmodels:\n  - name: my_model\n    columns:\n      - name: id\n        data_type: integer\n        constraints:\n        - type: foreign_key\n          to: ref('my_model_to')\n          to_columns: [id]\n\"\"\"\n\n\nmodel_foreign_key_column_invalid_syntax_schema_yml = \"\"\"\nmodels:\n  - name: my_model\n    columns:\n      - name: id\n        data_type: integer\n        constraints:\n        - type: foreign_key\n          to: invalid\n          to_columns: [id]\n\"\"\"\n\n\nmodel_foreign_key_column_node_not_found_schema_yml = \"\"\"\nmodels:\n  - name: my_model\n    columns:\n      - name: id\n        data_type: integer\n        constraints:\n        - type: foreign_key\n          to: ref('doesnt_exist')\n          to_columns: [id]\n\"\"\"\n\nmodel_column_level_foreign_key_source_schema_yml = \"\"\"\nsources:\n  - name: test_source\n    tables:\n      - name: test_table\n\nmodels:\n  - name: my_model\n    columns:\n      - name: id\n        data_type: integer\n        constraints:\n        - type: foreign_key\n          to: source('test_source', 'test_table')\n          to_columns: [id]\n\"\"\"\n\n\nstateful_generate_alias_name_macros_sql = \"\"\"\n{% macro generate_alias_name(custom_alias_name, node) -%}\n    {{ node.name }}_{{ var(\"state\", \"dev\") }}\n{%- endmacro %}\n\"\"\"\n"
  },
  {
    "path": "tests/functional/constraints/test_foreign_key_constraints.py",
    "content": "import os\nimport shutil\n\nimport pytest\n\nfrom dbt.artifacts.resources import RefArgs\nfrom dbt.exceptions import CompilationError, ParsingError\nfrom dbt.tests.util import get_artifact, run_dbt\nfrom dbt_common.contracts.constraints import (\n    ColumnLevelConstraint,\n    ConstraintType,\n    ModelLevelConstraint,\n)\nfrom tests.functional.constraints.fixtures import (\n    model_column_level_foreign_key_source_schema_yml,\n    model_foreign_key_column_invalid_syntax_schema_yml,\n    model_foreign_key_column_node_not_found_schema_yml,\n    model_foreign_key_model_column_schema_yml,\n    model_foreign_key_model_invalid_syntax_schema_yml,\n    model_foreign_key_model_node_not_found_schema_yml,\n    model_foreign_key_model_schema_yml,\n    model_foreign_key_source_schema_yml,\n    stateful_generate_alias_name_macros_sql,\n)\n\n\nclass TestModelLevelForeignKeyConstraintToRef:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"constraints_schema.yml\": model_foreign_key_model_schema_yml,\n            \"my_model.sql\": \"select 1 as id\",\n            \"my_model_to.sql\": \"select 1 as id\",\n        }\n\n    def test_model_level_fk_to(self, project, unique_schema):\n        manifest = run_dbt([\"parse\"])\n        node_with_fk_constraint = manifest.nodes[\"model.test.my_model\"]\n        assert len(node_with_fk_constraint.constraints) == 1\n\n        parsed_constraint = node_with_fk_constraint.constraints[0]\n        assert parsed_constraint == ModelLevelConstraint(\n            type=ConstraintType.foreign_key,\n            columns=[\"id\"],\n            to=\"ref('my_model_to')\",\n            to_columns=[\"id\"],\n        )\n        # Assert column-level constraint source included in node.depends_on\n        assert node_with_fk_constraint.refs == [RefArgs(\"my_model_to\")]\n        assert node_with_fk_constraint.depends_on.nodes == [\"model.test.my_model_to\"]\n        assert node_with_fk_constraint.sources == []\n\n        # Assert compilation renders to from 'ref' to relation identifer\n        run_dbt([\"compile\"])\n        manifest = get_artifact(project.project_root, \"target\", \"manifest.json\")\n        assert len(manifest[\"nodes\"][\"model.test.my_model\"][\"constraints\"]) == 1\n\n        compiled_constraint = manifest[\"nodes\"][\"model.test.my_model\"][\"constraints\"][0]\n        assert compiled_constraint[\"to\"] == f'\"dbt\".\"{unique_schema}\".\"my_model_to\"'\n        # Other constraint fields should remain as parsed\n        assert compiled_constraint[\"to_columns\"] == parsed_constraint.to_columns\n        assert compiled_constraint[\"columns\"] == parsed_constraint.columns\n        assert compiled_constraint[\"type\"] == parsed_constraint.type\n\n\nclass TestModelLevelForeignKeyConstraintToSource:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"constraints_schema.yml\": model_foreign_key_source_schema_yml,\n            \"my_model.sql\": \"select 1 as id\",\n            \"my_model_to.sql\": \"select 1 as id\",\n        }\n\n    def test_model_level_fk_to(self, project, unique_schema):\n        manifest = run_dbt([\"parse\"])\n        node_with_fk_constraint = manifest.nodes[\"model.test.my_model\"]\n        assert len(node_with_fk_constraint.constraints) == 1\n\n        parsed_constraint = node_with_fk_constraint.constraints[0]\n        assert parsed_constraint == ModelLevelConstraint(\n            type=ConstraintType.foreign_key,\n            columns=[\"id\"],\n            to=\"source('test_source', 'test_table')\",\n            to_columns=[\"id\"],\n        )\n        # Assert column-level constraint source included in node.depends_on\n        assert node_with_fk_constraint.refs == []\n        assert node_with_fk_constraint.depends_on.nodes == [\"source.test.test_source.test_table\"]\n        assert node_with_fk_constraint.sources == [[\"test_source\", \"test_table\"]]\n\n        # Assert compilation renders to from 'ref' to relation identifer\n        run_dbt([\"compile\"])\n        manifest = get_artifact(project.project_root, \"target\", \"manifest.json\")\n        assert len(manifest[\"nodes\"][\"model.test.my_model\"][\"constraints\"]) == 1\n\n        compiled_constraint = manifest[\"nodes\"][\"model.test.my_model\"][\"constraints\"][0]\n        assert compiled_constraint[\"to\"] == '\"dbt\".\"test_source\".\"test_table\"'\n        # Other constraint fields should remain as parsed\n        assert compiled_constraint[\"to_columns\"] == parsed_constraint.to_columns\n        assert compiled_constraint[\"columns\"] == parsed_constraint.columns\n        assert compiled_constraint[\"type\"] == parsed_constraint.type\n\n\nclass TestModelLevelForeignKeyConstraintRefNotFoundError:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"constraints_schema.yml\": model_foreign_key_model_node_not_found_schema_yml,\n            \"my_model.sql\": \"select 1 as id\",\n            \"my_model_to.sql\": \"select 1 as id\",\n        }\n\n    def test_model_level_fk_to_doesnt_exist(self, project):\n        with pytest.raises(\n            CompilationError, match=\"depends on a node named 'doesnt_exist' which was not found\"\n        ):\n            run_dbt([\"parse\"])\n\n\nclass TestModelLevelForeignKeyConstraintRefSyntaxError:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"constraints_schema.yml\": model_foreign_key_model_invalid_syntax_schema_yml,\n            \"my_model.sql\": \"select 1 as id\",\n            \"my_model_to.sql\": \"select 1 as id\",\n        }\n\n    def test_model_level_fk_to(self, project):\n        with pytest.raises(\n            ParsingError,\n            match=\"Invalid 'ref' or 'source' syntax on foreign key constraint 'to' on model my_model: invalid\",\n        ):\n            run_dbt([\"parse\"])\n\n\nclass TestColumnLevelForeignKeyConstraintToRef:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"constraints_schema.yml\": model_foreign_key_model_column_schema_yml,\n            \"my_model.sql\": \"select 1 as id\",\n            \"my_model_to.sql\": \"select 1 as id\",\n        }\n\n    def test_column_level_fk_to(self, project, unique_schema):\n        manifest = run_dbt([\"parse\"])\n        node_with_fk_constraint = manifest.nodes[\"model.test.my_model\"]\n        assert len(node_with_fk_constraint.columns[\"id\"].constraints) == 1\n\n        parsed_constraint = node_with_fk_constraint.columns[\"id\"].constraints[0]\n        # Assert column-level constraint parsed\n        assert parsed_constraint == ColumnLevelConstraint(\n            type=ConstraintType.foreign_key, to=\"ref('my_model_to')\", to_columns=[\"id\"]\n        )\n        # Assert column-level constraint ref included in node.depends_on\n        assert node_with_fk_constraint.refs == [RefArgs(name=\"my_model_to\")]\n        assert node_with_fk_constraint.sources == []\n        assert node_with_fk_constraint.depends_on.nodes == [\"model.test.my_model_to\"]\n\n        # Assert compilation renders to from 'ref' to relation identifer\n        run_dbt([\"compile\"])\n        manifest = get_artifact(project.project_root, \"target\", \"manifest.json\")\n        assert len(manifest[\"nodes\"][\"model.test.my_model\"][\"columns\"][\"id\"][\"constraints\"]) == 1\n\n        compiled_constraint = manifest[\"nodes\"][\"model.test.my_model\"][\"columns\"][\"id\"][\n            \"constraints\"\n        ][0]\n        assert compiled_constraint[\"to\"] == f'\"dbt\".\"{unique_schema}\".\"my_model_to\"'\n        # Other constraint fields should remain as parsed\n        assert compiled_constraint[\"to_columns\"] == parsed_constraint.to_columns\n        assert compiled_constraint[\"type\"] == parsed_constraint.type\n\n\nclass TestColumnLevelForeignKeyConstraintToSource:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"constraints_schema.yml\": model_column_level_foreign_key_source_schema_yml,\n            \"my_model.sql\": \"select 1 as id\",\n            \"my_model_to.sql\": \"select 1 as id\",\n        }\n\n    def test_model_level_fk_to(self, project, unique_schema):\n        manifest = run_dbt([\"parse\"])\n        node_with_fk_constraint = manifest.nodes[\"model.test.my_model\"]\n        assert len(node_with_fk_constraint.columns[\"id\"].constraints) == 1\n\n        parsed_constraint = node_with_fk_constraint.columns[\"id\"].constraints[0]\n        assert parsed_constraint == ColumnLevelConstraint(\n            type=ConstraintType.foreign_key,\n            to=\"source('test_source', 'test_table')\",\n            to_columns=[\"id\"],\n        )\n        # Assert column-level constraint source included in node.depends_on\n        assert node_with_fk_constraint.refs == []\n        assert node_with_fk_constraint.depends_on.nodes == [\"source.test.test_source.test_table\"]\n        assert node_with_fk_constraint.sources == [[\"test_source\", \"test_table\"]]\n\n        # Assert compilation renders to from 'ref' to relation identifer\n        run_dbt([\"compile\"])\n        manifest = get_artifact(project.project_root, \"target\", \"manifest.json\")\n        assert len(manifest[\"nodes\"][\"model.test.my_model\"][\"columns\"][\"id\"][\"constraints\"]) == 1\n\n        compiled_constraint = manifest[\"nodes\"][\"model.test.my_model\"][\"columns\"][\"id\"][\n            \"constraints\"\n        ][0]\n        assert compiled_constraint[\"to\"] == '\"dbt\".\"test_source\".\"test_table\"'\n        # # Other constraint fields should remain as parsed\n        assert compiled_constraint[\"to_columns\"] == parsed_constraint.to_columns\n        assert compiled_constraint[\"type\"] == parsed_constraint.type\n\n\nclass TestColumnLevelForeignKeyConstraintRefNotFoundError:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"constraints_schema.yml\": model_foreign_key_column_node_not_found_schema_yml,\n            \"my_model.sql\": \"select 1 as id\",\n            \"my_model_to.sql\": \"select 1 as id\",\n        }\n\n    def test_model_level_fk_to_doesnt_exist(self, project):\n        with pytest.raises(\n            CompilationError, match=\"depends on a node named 'doesnt_exist' which was not found\"\n        ):\n            run_dbt([\"parse\"])\n\n\nclass TestColumnLevelForeignKeyConstraintRefSyntaxError:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"constraints_schema.yml\": model_foreign_key_column_invalid_syntax_schema_yml,\n            \"my_model.sql\": \"select 1 as id\",\n            \"my_model_to.sql\": \"select 1 as id\",\n        }\n\n    def test_model_level_fk_to(self, project):\n        with pytest.raises(\n            ParsingError,\n            match=\"Invalid 'ref' or 'source' syntax on foreign key constraint 'to' on model my_model: invalid.\",\n        ):\n            run_dbt([\"parse\"])\n\n\nclass BaseForeignKeyDeferState:\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\n            \"generate_alias_name.sql\": stateful_generate_alias_name_macros_sql,\n        }\n\n    def copy_state(self, project_root):\n        state_path = os.path.join(project_root, \"state\")\n        if not os.path.exists(state_path):\n            os.makedirs(state_path)\n        shutil.copyfile(\n            f\"{project_root}/target/manifest.json\", f\"{project_root}/state/manifest.json\"\n        )\n\n\nclass TestModelLevelForeignKeyConstraintRefToDeferRelation(BaseForeignKeyDeferState):\n    \"\"\"Test FK constraint uses deferred relation when FK target is NOT selected.\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"constraints_schema.yml\": model_foreign_key_model_schema_yml,\n            \"my_model.sql\": \"select 1 as id\",\n            \"my_model_to.sql\": \"select 1 as id\",\n        }\n\n    def test_model_level_fk_to_defer_relation_when_target_not_selected(self, project):\n        \"\"\"When FK target is NOT selected, use deferred (prod) relation.\"\"\"\n        results = run_dbt([\"run\", \"--vars\", \"state: prod\"])\n        self.copy_state(project.project_root)\n\n        # Only select my_model, not my_model_to - FK should use deferred relation\n        results = run_dbt([\"compile\", \"-s\", \"my_model\", \"--defer\", \"--state\", \"state\"])\n\n        my_model_node = [r.node for r in results.results if r.node.name == \"my_model\"][0]\n        assert my_model_node.constraints[0].to.split(\".\")[-1] == '\"my_model_to_prod\"'\n\n    def test_model_level_fk_to_current_relation_when_target_selected(self, project):\n        \"\"\"When FK target IS selected (being built), use current relation, not deferred.\"\"\"\n        results = run_dbt([\"run\", \"--vars\", \"state: prod\"])\n        self.copy_state(project.project_root)\n\n        # Select both models - FK should use current (dev) relation since target is being built\n        results = run_dbt([\"compile\", \"--defer\", \"--state\", \"state\"])\n\n        my_model_node = [r.node for r in results.results if r.node.name == \"my_model\"][0]\n        # When both models are selected, FK should point to current (dev) relation\n        assert my_model_node.constraints[0].to.split(\".\")[-1] == '\"my_model_to_dev\"'\n\n\nclass TestColumnLevelForeignKeyConstraintToRefDeferRelation(BaseForeignKeyDeferState):\n    \"\"\"Test column-level FK constraint uses deferred relation when FK target is NOT selected.\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"constraints_schema.yml\": model_foreign_key_model_column_schema_yml,\n            \"my_model.sql\": \"select 1 as id\",\n            \"my_model_to.sql\": \"select 1 as id\",\n        }\n\n    def test_column_level_fk_to_defer_relation_when_target_not_selected(self, project):\n        \"\"\"When FK target is NOT selected, use deferred (prod) relation.\"\"\"\n        results = run_dbt([\"run\", \"--vars\", \"state: prod\"])\n        self.copy_state(project.project_root)\n\n        # Only select my_model, not my_model_to - FK should use deferred relation\n        results = run_dbt([\"compile\", \"-s\", \"my_model\", \"--defer\", \"--state\", \"state\"])\n\n        my_model_node = [r.node for r in results.results if r.node.name == \"my_model\"][0]\n        assert my_model_node.columns[\"id\"].constraints[0].to.split(\".\")[-1] == '\"my_model_to_prod\"'\n\n    def test_column_level_fk_to_current_relation_when_target_selected(self, project):\n        \"\"\"When FK target IS selected (being built), use current relation, not deferred.\"\"\"\n        results = run_dbt([\"run\", \"--vars\", \"state: prod\"])\n        self.copy_state(project.project_root)\n\n        # Select both models - FK should use current (dev) relation since target is being built\n        results = run_dbt([\"compile\", \"--defer\", \"--state\", \"state\"])\n\n        my_model_node = [r.node for r in results.results if r.node.name == \"my_model\"][0]\n        # When both models are selected, FK should point to current (dev) relation\n        assert my_model_node.columns[\"id\"].constraints[0].to.split(\".\")[-1] == '\"my_model_to_dev\"'\n"
  },
  {
    "path": "tests/functional/context_methods/first_dependency.py",
    "content": "import pytest\n\nfrom dbt.tests.fixtures.project import write_project_files\n\nfirst_dependency__dbt_project_yml = \"\"\"\nname: 'first_dep'\nversion: '1.0'\nconfig-version: 2\n\nprofile: 'default'\n\nmodel-paths: [\"models\"]\nanalysis-paths: [\"analyses\"]\ntest-paths: [\"tests\"]\nseed-paths: [\"seeds\"]\nmacro-paths: [\"macros\"]\n\nrequire-dbt-version: '>=0.1.0'\n\ntarget-path: \"target\"  # directory which will store compiled SQL files\nclean-targets:         # directories to be removed by `dbt clean`\n    - \"target\"\n    - \"dbt_packages\"\n\nvars:\n  first_dep:\n    first_dep_global: 'first_dep_global_value_overridden'\n    test_config_root_override: 'configured_from_dependency'\n    test_config_package: 'configured_from_dependency'\n\nseeds:\n  quote_columns: True\n\n\"\"\"\n\nfirst_dependency__models__nested__first_dep_model_sql = \"\"\"\nselect\n    '{{ var(\"first_dep_global\") }}' as first_dep_global,\n    '{{ var(\"from_root_to_first\") }}' as from_root\n\"\"\"\n\nfirst_dependency__seeds__first_dep_expected_csv = \"\"\"first_dep_global,from_root\nfirst_dep_global_value_overridden,root_first_value\n\"\"\"\n\nfirst_dependency__models__nested__first_dep_model_var_expected_csv = \"\"\"test_config_root_override,test_config_package\nconfigured_from_root,configured_from_dependency\n\"\"\"\n\nfirst_dependency__models__nested__first_dep_model_var_sql = \"\"\"\nselect\n    '{{ config.get(\"test_config_root_override\") }}' as test_config_root_override,\n    '{{ config.get(\"test_config_package\") }}' as test_config_package\n\"\"\"\n\nfirst_dependency__model_var_in_config_schema = \"\"\"\nmodels:\n- name: first_dep_model\n  config:\n    test_config_root_override: \"{{ var('test_config_root_override') }}\"\n    test_config_package: \"{{ var('test_config_package') }}\"\n\"\"\"\n\n\nclass FirstDependencyProject:\n    @pytest.fixture(scope=\"class\")\n    def first_dependency(self, project):\n        first_dependency_files = {\n            \"dbt_project.yml\": first_dependency__dbt_project_yml,\n            \"models\": {\n                \"nested\": {\n                    \"first_dep_model.sql\": first_dependency__models__nested__first_dep_model_sql\n                }\n            },\n            \"seeds\": {\"first_dep_expected.csv\": first_dependency__seeds__first_dep_expected_csv},\n        }\n        write_project_files(project.project_root, \"first_dependency\", first_dependency_files)\n\n\nclass FirstDependencyConfigProject:\n    @pytest.fixture(scope=\"class\")\n    def first_dependency(self, project):\n        first_dependency_files = {\n            \"dbt_project.yml\": first_dependency__dbt_project_yml,\n            \"models\": {\n                \"nested\": {\n                    \"first_dep_model.sql\": first_dependency__models__nested__first_dep_model_var_sql,\n                    \"schema.yml\": first_dependency__model_var_in_config_schema,\n                }\n            },\n            \"seeds\": {\n                \"first_dep_expected.csv\": first_dependency__models__nested__first_dep_model_var_expected_csv\n            },\n        }\n        write_project_files(project.project_root, \"first_dependency\", first_dependency_files)\n"
  },
  {
    "path": "tests/functional/context_methods/test_builtin_functions.py",
    "content": "import json\nimport os\n\nimport pytest\n\nfrom dbt.exceptions import CompilationError\nfrom dbt.tests.util import run_dbt, run_dbt_and_capture, write_file\n\nmacros__validate_set_sql = \"\"\"\n{% macro validate_set() %}\n    {% set set_result = set([1, 2, 2, 3, 'foo', False]) %}\n    {{ log(\"set_result: \" ~ set_result) }}\n    {% set set_strict_result = set_strict([1, 2, 2, 3, 'foo', False]) %}\n    {{ log(\"set_strict_result: \" ~ set_strict_result) }}\n{% endmacro %}\n\"\"\"\n\nmacros__validate_zip_sql = \"\"\"\n{% macro validate_zip() %}\n    {% set list_a = [1, 2] %}\n    {% set list_b = ['foo', 'bar'] %}\n    {% set zip_result = zip(list_a, list_b) | list %}\n    {{ log(\"zip_result: \" ~ zip_result) }}\n    {% set zip_strict_result = zip_strict(list_a, list_b) | list %}\n    {{ log(\"zip_strict_result: \" ~ zip_strict_result) }}\n{% endmacro %}\n\"\"\"\n\nmacros__validate_invocation_sql = \"\"\"\n{% macro validate_invocation(my_variable) %}\n    -- check a specific value\n    {{ log(\"use_colors: \"~ invocation_args_dict['use_colors']) }}\n    -- whole dictionary (as string)\n    {{ log(\"invocation_result: \"~ invocation_args_dict) }}\n{% endmacro %}\n\"\"\"\n\nmacros__validate_dbt_metadata_envs_sql = \"\"\"\n{% macro validate_dbt_metadata_envs() %}\n    {{ log(\"dbt_metadata_envs_result:\"~ dbt_metadata_envs) }}\n{% endmacro %}\n\"\"\"\n\nmodels__set_exception_sql = \"\"\"\n{% set set_strict_result = set_strict(1) %}\n\"\"\"\n\nmodels__zip_exception_sql = \"\"\"\n{% set zip_strict_result = zip_strict(1) %}\n\"\"\"\n\n\ndef parse_json_logs(json_log_output):\n    parsed_logs = []\n    for line in json_log_output.split(\"\\n\"):\n        try:\n            log = json.loads(line)\n        except ValueError:\n            continue\n\n        parsed_logs.append(log)\n\n    return parsed_logs\n\n\ndef find_result_in_parsed_logs(parsed_logs, result_name):\n    return next(\n        (\n            item[\"data\"][\"msg\"]\n            for item in parsed_logs\n            if result_name in item[\"data\"].get(\"msg\", \"msg\")\n        ),\n        False,\n    )\n\n\nclass TestContextBuiltins:\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\n            \"validate_set.sql\": macros__validate_set_sql,\n            \"validate_zip.sql\": macros__validate_zip_sql,\n            \"validate_invocation.sql\": macros__validate_invocation_sql,\n            \"validate_dbt_metadata_envs.sql\": macros__validate_dbt_metadata_envs_sql,\n        }\n\n    def test_builtin_set_function(self, project):\n        _, log_output = run_dbt_and_capture([\"--debug\", \"run-operation\", \"validate_set\"])\n\n        # The order of the set isn't guaranteed so we can't check for the actual set in the logs\n        assert \"set_result: \" in log_output\n        assert \"False\" in log_output\n        assert \"set_strict_result: \" in log_output\n\n    def test_builtin_zip_function(self, project):\n        _, log_output = run_dbt_and_capture([\"--debug\", \"run-operation\", \"validate_zip\"])\n\n        expected_zip = [(1, \"foo\"), (2, \"bar\")]\n        assert f\"zip_result: {expected_zip}\" in log_output\n        assert f\"zip_strict_result: {expected_zip}\" in log_output\n\n    def test_builtin_invocation_args_dict_function(self, project):\n        _, log_output = run_dbt_and_capture(\n            [\n                \"--debug\",\n                \"--log-format=json\",\n                \"run-operation\",\n                \"validate_invocation\",\n                \"--args\",\n                \"{my_variable: test_variable}\",\n            ]\n        )\n\n        parsed_logs = parse_json_logs(log_output)\n        use_colors = result = find_result_in_parsed_logs(parsed_logs, \"use_colors\")\n        assert use_colors == \"use_colors: True\"\n        invocation_dict = find_result_in_parsed_logs(parsed_logs, \"invocation_result\")\n        assert result\n        # The result should include a dictionary of all flags with values that aren't None\n        expected = (\n            \"'send_anonymous_usage_stats': False\",\n            \"'quiet': False\",\n            \"'print': True\",\n            \"'cache_selected_only': False\",\n            \"'macro': 'validate_invocation'\",\n            \"'args': {'my_variable': 'test_variable'}\",\n            \"'which': 'run-operation'\",\n            \"'indirect_selection': 'eager'\",\n        )\n        assert all(element in invocation_dict for element in expected)\n\n    def test_builtin_dbt_metadata_envs_function(self, project, monkeypatch):\n        envs = {\n            \"DBT_ENV_CUSTOM_ENV_RUN_ID\": \"1234\",\n            \"DBT_ENV_CUSTOM_ENV_JOB_ID\": \"5678\",\n            \"DBT_ENV_RUN_ID\": \"91011\",\n            \"RANDOM_ENV\": \"121314\",\n        }\n        monkeypatch.setattr(os, \"environ\", envs)\n\n        _, log_output = run_dbt_and_capture(\n            [\"--debug\", \"--log-format=json\", \"run-operation\", \"validate_dbt_metadata_envs\"]\n        )\n\n        parsed_logs = parse_json_logs(log_output)\n        result = find_result_in_parsed_logs(parsed_logs, \"dbt_metadata_envs_result\")\n\n        assert result\n\n        expected = \"dbt_metadata_envs_result:{'RUN_ID': '1234', 'JOB_ID': '5678'}\"\n        assert expected in str(result)\n\n\nclass TestContextBuiltinExceptions:\n    # Assert compilation errors are raised with _strict equivalents\n    def test_builtin_function_exception(self, project):\n        write_file(models__set_exception_sql, project.project_root, \"models\", \"raise.sql\")\n        with pytest.raises(CompilationError):\n            run_dbt([\"compile\"])\n\n        write_file(models__zip_exception_sql, project.project_root, \"models\", \"raise.sql\")\n        with pytest.raises(CompilationError):\n            run_dbt([\"compile\"])\n"
  },
  {
    "path": "tests/functional/context_methods/test_cli_var_override.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt\n\nmodels_override__schema_yml = \"\"\"\nversion: 2\nmodels:\n- name: test_vars\n  columns:\n  - name: field\n    data_tests:\n    - accepted_values:\n        values:\n        - override\n\"\"\"\n\nmodels_override__test_vars_sql = \"\"\"\nselect '{{ var(\"required\") }}'::varchar as field\n\"\"\"\n\n\n# Tests that cli vars override vars set in the project config\nclass TestCLIVarOverride:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": models_override__schema_yml,\n            \"test_vars.sql\": models_override__test_vars_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"vars\": {\n                \"required\": \"present\",\n            },\n        }\n\n    def test__override_vars_global(self, project):\n        run_dbt([\"run\", \"--vars\", \"{required: override}\"])\n        run_dbt([\"test\"])\n\n\n# This one switches to setting a var in 'test'\nclass TestCLIVarOverridePorject:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": models_override__schema_yml,\n            \"test_vars.sql\": models_override__test_vars_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"vars\": {\n                \"test\": {\n                    \"required\": \"present\",\n                },\n            },\n        }\n\n    def test__override_vars_project_level(self, project):\n\n        # This should be \"override\"\n        run_dbt([\"run\", \"--vars\", \"{required: override}\"])\n        run_dbt([\"test\"])\n"
  },
  {
    "path": "tests/functional/context_methods/test_cli_vars.py",
    "content": "import pytest\nimport yaml\n\nfrom dbt.exceptions import CompilationError, DbtRuntimeError\nfrom dbt.tests.fixtures.project import write_project_files\nfrom dbt.tests.util import (\n    get_artifact,\n    get_logging_events,\n    run_dbt,\n    run_dbt_and_capture,\n    write_config_file,\n)\nfrom tests.fixtures.dbt_integration_project import dbt_integration_project  # noqa: F401\n\nmodels_complex__schema_yml = \"\"\"\nversion: 2\nmodels:\n- name: complex_model\n  columns:\n  - name: var_1\n    data_tests:\n    - accepted_values:\n        values:\n        - abc\n  - name: var_2\n    data_tests:\n    - accepted_values:\n        values:\n        - def\n  - name: var_3\n    data_tests:\n    - accepted_values:\n        values:\n        - jkl\n\"\"\"\n\nmodels_complex__complex_model_sql = \"\"\"\nselect\n    '{{ var(\"variable_1\") }}'::varchar as var_1,\n    '{{ var(\"variable_2\")[0] }}'::varchar as var_2,\n    '{{ var(\"variable_3\")[\"value\"] }}'::varchar as var_3\n\"\"\"\n\nmodels_simple__schema_yml = \"\"\"\nversion: 2\nmodels:\n- name: simple_model\n  columns:\n  - name: simple\n    data_tests:\n    - accepted_values:\n        values:\n        - abc\n\"\"\"\n\nmodels_simple__simple_model_sql = \"\"\"\nselect\n    '{{ var(\"simple\") }}'::varchar as simple\n\"\"\"\n\nreally_simple_model_sql = \"\"\"\nselect 'abc' as simple\n\"\"\"\n\n\nclass TestCLIVars:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": models_complex__schema_yml,\n            \"complex_model.sql\": models_complex__complex_model_sql,\n        }\n\n    def test__cli_vars_longform(self, project):\n        cli_vars = {\n            \"variable_1\": \"abc\",\n            \"variable_2\": [\"def\", \"ghi\"],\n            \"variable_3\": {\"value\": \"jkl\"},\n        }\n        results = run_dbt([\"run\", \"--vars\", yaml.dump(cli_vars)])\n        assert len(results) == 1\n        results = run_dbt([\"test\", \"--vars\", yaml.dump(cli_vars)])\n        assert len(results) == 3\n\n\nclass TestCLIVarsSimple:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": models_simple__schema_yml,\n            \"simple_model.sql\": models_simple__simple_model_sql,\n        }\n\n    def test__cli_vars_shorthand(self, project):\n        results = run_dbt([\"run\", \"--vars\", \"simple: abc\"])\n        assert len(results) == 1\n        results = run_dbt([\"test\", \"--vars\", \"simple: abc\"])\n        assert len(results) == 1\n\n    def test__cli_vars_longer(self, project):\n        results = run_dbt([\"run\", \"--vars\", \"{simple: abc, unused: def}\"])\n        assert len(results) == 1\n        results = run_dbt([\"test\", \"--vars\", \"{simple: abc, unused: def}\"])\n        assert len(results) == 1\n        run_results = get_artifact(project.project_root, \"target\", \"run_results.json\")\n        assert run_results[\"args\"][\"vars\"] == {\"simple\": \"abc\", \"unused\": \"def\"}\n\n\nclass TestCLIVarsProfile:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": models_simple__schema_yml,\n            \"simple_model.sql\": really_simple_model_sql,\n        }\n\n    def test_cli_vars_in_profile(self, project, dbt_profile_data):\n        profile = dbt_profile_data\n        profile[\"test\"][\"outputs\"][\"default\"][\"host\"] = \"{{ var('db_host') }}\"\n        write_config_file(profile, project.profiles_dir, \"profiles.yml\")\n        with pytest.raises(DbtRuntimeError):\n            results = run_dbt([\"run\"])\n        results = run_dbt([\"run\", \"--vars\", \"db_host: localhost\"])\n        assert len(results) == 1\n\n\nclass TestCLIVarsPackages:\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project_root, dbt_integration_project):  # noqa: F811\n        write_project_files(project_root, \"dbt_integration_project\", dbt_integration_project)\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": models_simple__schema_yml,\n            \"simple_model.sql\": really_simple_model_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def packages_config(self):\n        return {\"packages\": [{\"local\": \"dbt_integration_project\"}]}\n\n    def test_cli_vars_in_packages(self, project, packages_config):\n        # Run working deps and run commands\n        run_dbt([\"deps\"])\n        results = run_dbt([\"run\"])\n        assert len(results) == 1\n\n        # Change packages.yml to contain a var\n        packages = packages_config\n        packages[\"packages\"][0][\"local\"] = \"{{ var('path_to_project') }}\"\n        write_config_file(packages, project.project_root, \"packages.yml\")\n\n        # Without vars args deps fails\n        with pytest.raises(DbtRuntimeError):\n            run_dbt([\"deps\"])\n\n        # With vars arg deps succeeds\n        results = run_dbt([\"deps\", \"--vars\", \"path_to_project: dbt_integration_project\"])\n        assert results is None\n\n\ninitial_selectors_yml = \"\"\"\nselectors:\n  - name: dev_defer_snapshots\n    default: \"{{ target.name == 'dev' | as_bool }}\"\n    definition:\n      method: fqn\n      value: '*'\n      exclude:\n        - method: config.materialized\n          value: snapshot\n\"\"\"\n\nvar_selectors_yml = \"\"\"\nselectors:\n  - name: dev_defer_snapshots\n    default: \"{{ var('snapshot_target') == 'dev' | as_bool }}\"\n    definition:\n      method: fqn\n      value: '*'\n      exclude:\n        - method: config.materialized\n          value: snapshot\n\"\"\"\n\n\nclass TestCLIVarsSelectors:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": models_simple__schema_yml,\n            \"simple_model.sql\": really_simple_model_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def selectors(self):\n        return initial_selectors_yml\n\n    def test_vars_in_selectors(self, project):\n        # initially runs ok\n        results = run_dbt([\"run\"])\n        assert len(results) == 1\n\n        # Update the selectors.yml file to have a var\n        write_config_file(var_selectors_yml, project.project_root, \"selectors.yml\")\n        with pytest.raises(CompilationError):\n            run_dbt([\"run\"])\n\n        # Var in cli_vars works\n        results = run_dbt([\"run\", \"--vars\", \"snapshot_target: dev\"])\n        assert len(results) == 1\n\n\nmodels_scrubbing__schema_yml = \"\"\"\nversion: 2\nmodels:\n- name: simple_model\n  columns:\n  - name: simple\n    data_tests:\n    - accepted_values:\n        values:\n        - abc\n\"\"\"\n\nmodels_scrubbing__simple_model_sql = \"\"\"\nselect\n    '{{ var(\"DBT_ENV_SECRET_simple\") }}'::varchar as simple\n\"\"\"\n\n\nclass TestCLIVarsScrubbing:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": models_scrubbing__schema_yml,\n            \"simple_model.sql\": models_scrubbing__simple_model_sql,\n        }\n\n    def test__run_results_scrubbing(self, project):\n        results, output = run_dbt_and_capture(\n            [\n                \"--debug\",\n                \"--log-format\",\n                \"json\",\n                \"run\",\n                \"--vars\",\n                \"{DBT_ENV_SECRET_simple: abc, unused: def}\",\n            ]\n        )\n        assert len(results) == 1\n\n        run_results = get_artifact(project.project_root, \"target\", \"run_results.json\")\n        assert run_results[\"args\"][\"vars\"] == {\n            \"DBT_ENV_SECRET_simple\": \"*****\",\n            \"unused\": \"def\",\n        }\n\n        log_events = get_logging_events(log_output=output, event_name=\"StateCheckVarsHash\")\n        assert len(log_events) == 1\n        assert (\n            log_events[0][\"data\"][\"vars\"] == \"{'DBT_ENV_SECRET_simple': '*****', 'unused': 'def'}\"\n        )\n\n    def test__exception_scrubbing(self, project):\n        results, output = run_dbt_and_capture(\n            [\n                \"--debug\",\n                \"--log-format\",\n                \"json\",\n                \"run\",\n                \"--vars\",\n                \"{DBT_ENV_SECRET_unused: abc, unused: def}\",\n            ],\n            False,\n        )\n        assert len(results) == 1\n\n        log_events = get_logging_events(log_output=output, event_name=\"CatchableExceptionOnRun\")\n        assert len(log_events) == 1\n        assert (\n            '{\\n      \"DBT_ENV_SECRET_unused\": \"*****\",\\n      \"unused\": \"def\"\\n  }'\n            in log_events[0][\"info\"][\"msg\"]\n        )\n"
  },
  {
    "path": "tests/functional/context_methods/test_custom_env_vars.py",
    "content": "import json\nimport os\n\nimport pytest\n\nfrom dbt.tests.util import run_dbt_and_capture\n\n\ndef parse_json_logs(json_log_output):\n    parsed_logs = []\n    for line in json_log_output.split(\"\\n\"):\n        try:\n            log = json.loads(line)\n        except ValueError:\n            continue\n\n        parsed_logs.append(log)\n\n    return parsed_logs\n\n\nclass TestCustomVarInLogs:\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setup(self):\n        # on windows, python uppercases env var names because windows is case insensitive\n        os.environ[\"DBT_ENV_CUSTOM_ENV_SOME_VAR\"] = \"value\"\n        yield\n        del os.environ[\"DBT_ENV_CUSTOM_ENV_SOME_VAR\"]\n\n    def test_extra_filled(self, project):\n        _, log_output = run_dbt_and_capture(\n            [\"--log-format=json\", \"deps\"],\n        )\n        logs = parse_json_logs(log_output)\n        for log in logs:\n            assert log[\"info\"].get(\"extra\") == {\"SOME_VAR\": \"value\"}\n"
  },
  {
    "path": "tests/functional/context_methods/test_env_vars.py",
    "content": "import os\n\nimport pytest\n\nfrom dbt.constants import DEFAULT_ENV_PLACEHOLDER\nfrom dbt.tests.util import get_manifest, run_dbt, run_dbt_and_capture\nfrom dbt_common.constants import SECRET_ENV_PREFIX\n\ncontext_sql = \"\"\"\n\n{{\n    config(\n        materialized='table'\n    )\n}}\n\nselect\n\n    -- compile-time variables\n    '{{ this }}'        as \"this\",\n    '{{ this.name }}'   as \"this.name\",\n    '{{ this.schema }}' as \"this.schema\",\n    '{{ this.table }}'  as \"this.table\",\n\n    '{{ target.dbname }}'  as \"target.dbname\",\n    '{{ target.host }}'    as \"target.host\",\n    '{{ target.name }}'    as \"target.name\",\n    '{{ target.schema }}'  as \"target.schema\",\n    '{{ target.type }}'    as \"target.type\",\n    '{{ target.user }}'    as \"target.user\",\n    '{{ target.get(\"pass\", \"\") }}'    as \"target.pass\", -- not actually included, here to test that it is _not_ present!\n    {{ target.port }}      as \"target.port\",\n    {{ target.threads }}   as \"target.threads\",\n\n    -- runtime variables\n    '{{ run_started_at }}' as run_started_at,\n    '{{ invocation_id }}'  as invocation_id,\n    '{{ thread_id }}'  as thread_id,\n\n    '{{ env_var(\"DBT_TEST_ENV_VAR\") }}' as env_var,\n    '{{ env_var(\"DBT_TEST_IGNORE_DEFAULT\", \"ignored_default_val\") }}' as env_var_ignore_default,\n    '{{ env_var(\"DBT_TEST_USE_DEFAULT\", \"use_my_default_val\") }}' as env_var_use_default,\n    'secret_variable' as env_var_secret, -- make sure the value itself is scrubbed from the logs\n    '{{ env_var(\"DBT_TEST_NOT_SECRET\") }}' as env_var_not_secret\n\n\"\"\"\n\n\nclass TestEnvVars:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"context.sql\": context_sql}\n\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setup(self):\n        os.environ[\"DBT_TEST_ENV_VAR\"] = \"1\"\n        os.environ[\"DBT_TEST_USER\"] = \"root\"\n        os.environ[\"DBT_TEST_PASS\"] = \"password\"\n        os.environ[SECRET_ENV_PREFIX + \"_SECRET\"] = \"secret_variable\"\n        os.environ[\"DBT_TEST_NOT_SECRET\"] = \"regular_variable\"\n        os.environ[\"DBT_TEST_IGNORE_DEFAULT\"] = \"ignored_default\"\n        yield\n        del os.environ[\"DBT_TEST_ENV_VAR\"]\n        del os.environ[\"DBT_TEST_USER\"]\n        del os.environ[SECRET_ENV_PREFIX + \"_SECRET\"]\n        del os.environ[\"DBT_TEST_NOT_SECRET\"]\n        del os.environ[\"DBT_TEST_IGNORE_DEFAULT\"]\n\n    @pytest.fixture(scope=\"class\")\n    def profiles_config_update(self, unique_schema):\n        return {\n            \"test\": {\n                \"outputs\": {\n                    # don't use env_var's here so the integration tests can run\n                    # seed sql statements and the like. default target is used\n                    \"dev\": {\n                        \"type\": \"postgres\",\n                        \"threads\": 1,\n                        \"host\": \"localhost\",\n                        \"port\": 5432,\n                        \"user\": \"root\",\n                        \"pass\": \"password\",\n                        \"dbname\": \"dbt\",\n                        \"schema\": unique_schema,\n                    },\n                    \"prod\": {\n                        \"type\": \"postgres\",\n                        \"threads\": 1,\n                        \"host\": \"localhost\",\n                        \"port\": 5432,\n                        # root/password\n                        \"user\": \"{{ env_var('DBT_TEST_USER') }}\",\n                        \"pass\": \"{{ env_var('DBT_TEST_PASS') }}\",\n                        \"dbname\": \"dbt\",\n                        \"schema\": unique_schema,\n                    },\n                },\n                \"target\": \"dev\",\n            }\n        }\n\n    def get_ctx_vars(self, project):\n        fields = [\n            \"this\",\n            \"this.name\",\n            \"this.schema\",\n            \"this.table\",\n            \"target.dbname\",\n            \"target.host\",\n            \"target.name\",\n            \"target.port\",\n            \"target.schema\",\n            \"target.threads\",\n            \"target.type\",\n            \"target.user\",\n            \"target.pass\",\n            \"run_started_at\",\n            \"invocation_id\",\n            \"thread_id\",\n            \"env_var\",\n        ]\n        field_list = \", \".join(['\"{}\"'.format(f) for f in fields])\n        query = \"select {field_list} from {schema}.context\".format(\n            field_list=field_list, schema=project.test_schema\n        )\n        vals = project.run_sql(query, fetch=\"all\")\n        ctx = dict([(k, v) for (k, v) in zip(fields, vals[0])])\n        return ctx\n\n    def test_env_vars_dev(\n        self,\n        project,\n    ):\n        results = run_dbt([\"run\"])\n        assert len(results) == 1\n        ctx = self.get_ctx_vars(project)\n\n        manifest = get_manifest(project.project_root)\n        expected = {\n            \"DBT_TEST_ENV_VAR\": \"1\",\n            \"DBT_TEST_NOT_SECRET\": \"regular_variable\",\n            \"DBT_TEST_IGNORE_DEFAULT\": \"ignored_default\",\n            \"DBT_TEST_USE_DEFAULT\": DEFAULT_ENV_PLACEHOLDER,\n        }\n        assert manifest.env_vars == expected\n\n        this = '\"{}\".\"{}\".\"context\"'.format(project.database, project.test_schema)\n        assert ctx[\"this\"] == this\n\n        assert ctx[\"this.name\"] == \"context\"\n        assert ctx[\"this.schema\"] == project.test_schema\n        assert ctx[\"this.table\"] == \"context\"\n\n        assert ctx[\"target.dbname\"] == \"dbt\"\n        assert ctx[\"target.host\"] == \"localhost\"\n        assert ctx[\"target.name\"] == \"dev\"\n        assert ctx[\"target.port\"] == 5432\n        assert ctx[\"target.schema\"] == project.test_schema\n        assert ctx[\"target.threads\"] == 1\n        assert ctx[\"target.type\"] == \"postgres\"\n        assert ctx[\"target.user\"] == \"root\"\n        assert ctx[\"target.pass\"] == \"\"\n\n        assert ctx[\"env_var\"] == \"1\"\n\n    def test_env_vars_prod(self, project):\n        results = run_dbt([\"run\", \"--target\", \"prod\"])\n        assert len(results) == 1\n        ctx = self.get_ctx_vars(project)\n\n        this = '\"{}\".\"{}\".\"context\"'.format(project.database, project.test_schema)\n        assert ctx[\"this\"] == this\n\n        assert ctx[\"this.name\"] == \"context\"\n        assert ctx[\"this.schema\"] == project.test_schema\n        assert ctx[\"this.table\"] == \"context\"\n\n        assert ctx[\"target.dbname\"] == \"dbt\"\n        assert ctx[\"target.host\"] == \"localhost\"\n        assert ctx[\"target.name\"] == \"prod\"\n        assert ctx[\"target.port\"] == 5432\n        assert ctx[\"target.schema\"] == project.test_schema\n        assert ctx[\"target.threads\"] == 1\n        assert ctx[\"target.type\"] == \"postgres\"\n        assert ctx[\"target.user\"] == \"root\"\n        assert ctx[\"target.pass\"] == \"\"\n        assert ctx[\"env_var\"] == \"1\"\n\n    def test_env_vars_secrets(self, project):\n        os.environ[\"DBT_DEBUG\"] = \"True\"\n        _, log_output = run_dbt_and_capture([\"run\", \"--target\", \"prod\"])\n\n        assert not (\"secret_variable\" in log_output)\n        assert \"regular_variable\" in log_output\n        del os.environ[\"DBT_DEBUG\"]\n\n\nclass TestEnvVarInCreateSchema:\n    \"\"\"Test that the env_var() method works in overrides of the create_schema\n    macro, which is called during a different phase of execution than most\n    macros, causing problems.\"\"\"\n\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setup(self):\n        os.environ[\"DBT_TEST_ENV_VAR\"] = \"1\"\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\n            \"macros.sql\": \"\"\"\n                {% macro create_schema(relation) %}\n                  {%- call statement('create_schema') -%}\n                     SELECT {{ env_var('DBT_TEST_ENV_VAR') }} as TEST\n                  {% endcall %}\n                {% endmacro %}%\n            \"\"\"\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"mymodel.sql\": \"\"\"\n            SELECT 1 as TEST -- {%- do adapter.create_schema(this) -%}\n        \"\"\"\n        }\n\n    def test_env_var_in_create_schema(self, project):\n        run_dbt([\"run\"])\n"
  },
  {
    "path": "tests/functional/context_methods/test_secret_env_vars.py",
    "content": "import os\n\nimport pytest\n\nfrom dbt.exceptions import DbtInternalError, ParsingError\nfrom dbt.tests.util import read_file, run_dbt, run_dbt_and_capture\nfrom dbt_common.constants import SECRET_ENV_PREFIX\nfrom tests.functional.context_methods.first_dependency import FirstDependencyProject\n\nsecret_bad__context_sql = \"\"\"\n\n{{\n    config(\n        materialized='table'\n    )\n}}\n\nselect\n\n    '{{ env_var(\"DBT_TEST_ENV_VAR\") }}' as env_var,\n    '{{ env_var(\"DBT_ENV_SECRET_SECRET\") }}' as env_var_secret, -- this should raise an error!\n    '{{ env_var(\"DBT_TEST_NOT_SECRET\") }}' as env_var_not_secret\n\n\"\"\"\n\n\nclass TestDisallowSecretModel:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"context.sql\": secret_bad__context_sql}\n\n    def test_disallow_secret(self, project):\n        with pytest.raises(ParsingError):\n            run_dbt([\"compile\"])\n\n\nmodels__context_sql = \"\"\"\n{{\n    config(\n        materialized='table'\n    )\n}}\n\nselect\n\n    -- compile-time variables\n    '{{ this }}'        as \"this\",\n    '{{ this.name }}'   as \"this.name\",\n    '{{ this.schema }}' as \"this.schema\",\n    '{{ this.table }}'  as \"this.table\",\n\n    '{{ target.dbname }}'  as \"target.dbname\",\n    '{{ target.host }}'    as \"target.host\",\n    '{{ target.name }}'    as \"target.name\",\n    '{{ target.schema }}'  as \"target.schema\",\n    '{{ target.type }}'    as \"target.type\",\n    '{{ target.user }}'    as \"target.user\",\n    '{{ target.get(\"pass\", \"\") }}'    as \"target.pass\", -- not actually included, here to test that it is _not_ present!\n    {{ target.port }}      as \"target.port\",\n    {{ target.threads }}   as \"target.threads\",\n\n    -- runtime variables\n    '{{ run_started_at }}' as run_started_at,\n    '{{ invocation_id }}'  as invocation_id,\n    '{{ thread_id }}'  as thread_id,\n\n    '{{ env_var(\"DBT_TEST_ENV_VAR\") }}' as env_var,\n    'secret_variable' as env_var_secret, -- make sure the value itself is scrubbed from the logs\n    '{{ env_var(\"DBT_TEST_NOT_SECRET\") }}' as env_var_not_secret\n\"\"\"\n\n\nclass TestAllowSecretProfilePackage(FirstDependencyProject):\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setup(self):\n        os.environ[SECRET_ENV_PREFIX + \"_USER\"] = \"root\"\n        os.environ[SECRET_ENV_PREFIX + \"_PASS\"] = \"password\"\n        os.environ[SECRET_ENV_PREFIX + \"_PACKAGE\"] = \"first_dependency\"\n        os.environ[SECRET_ENV_PREFIX + \"_GIT_TOKEN\"] = \"abc123\"\n        yield\n        del os.environ[SECRET_ENV_PREFIX + \"_USER\"]\n        del os.environ[SECRET_ENV_PREFIX + \"_PASS\"]\n        del os.environ[SECRET_ENV_PREFIX + \"_PACKAGE\"]\n        del os.environ[SECRET_ENV_PREFIX + \"_GIT_TOKEN\"]\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"context.sql\": models__context_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\n            \"packages\": [\n                {\n                    # the raw value of this secret *will* be written to lock file\n                    \"local\": \"{{ env_var('DBT_ENV_SECRET_PACKAGE') }}\"\n                },\n                {\n                    # this secret env var will *not* be written to lock file\n                    \"git\": \"https://{{ env_var('DBT_ENV_SECRET_GIT_TOKEN') }}@github.com/dbt-labs/dbt-external-tables.git\"\n                },\n                {\n                    # this secret env var will *not* be written to lock file\n                    \"tarball\": \"https://{{ env_var('DBT_ENV_SECRET_GIT_TOKEN') }}@github.com/dbt-labs/dbt-utils/archive/refs/tags/1.1.1.tar.gz\",\n                    \"name\": \"dbt_utils\",\n                },\n            ]\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def profile_target(self):\n        return {\n            \"type\": \"postgres\",\n            \"threads\": 1,\n            \"host\": \"localhost\",\n            \"port\": 5432,\n            # root/password\n            \"user\": \"{{ env_var('DBT_ENV_SECRET_USER') }}\",\n            \"pass\": \"{{ env_var('DBT_ENV_SECRET_PASS') }}\",\n            \"dbname\": \"dbt\",\n        }\n\n    def test_allow_secrets(self, project, first_dependency):\n        _, log_output = run_dbt_and_capture([\"deps\"])\n        lock_file_contents = read_file(\"package-lock.yml\")\n\n        # this will not be written to logs or lock file\n        assert not (\"abc123\" in log_output)\n        assert not (\"abc123\" in lock_file_contents)\n        assert \"{{ env_var('DBT_ENV_SECRET_GIT_TOKEN') }}\" in lock_file_contents\n\n        # this will be scrubbed from logs, but not from the lock file\n        assert not (\"first_dependency\" in log_output)\n        assert \"first_dependency\" in lock_file_contents\n\n\nclass TestCloneFailSecretScrubbed:\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setup(self):\n        os.environ[SECRET_ENV_PREFIX + \"_GIT_TOKEN\"] = \"abc123\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"context.sql\": models__context_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\n            \"packages\": [\n                {\n                    \"git\": \"https://fakeuser:{{ env_var('DBT_ENV_SECRET_GIT_TOKEN') }}@github.com/dbt-labs/fake-repo.git\"\n                },\n            ]\n        }\n\n    def test_fail_clone_with_scrubbing(self, project):\n        with pytest.raises(DbtInternalError) as excinfo:\n            _, log_output = run_dbt_and_capture([\"deps\"])\n\n        assert \"abc123\" not in str(excinfo.value)\n\n\nclass TestCloneFailSecretNotRendered(TestCloneFailSecretScrubbed):\n    # as above, with some Jinja manipulation\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\n            \"packages\": [\n                {\n                    \"git\": \"https://fakeuser:{{ env_var('DBT_ENV_SECRET_GIT_TOKEN') | join(' ') }}@github.com/dbt-labs/fake-repo.git\"\n                },\n            ]\n        }\n\n    def test_fail_clone_with_scrubbing(self, project):\n        with pytest.raises(DbtInternalError) as excinfo:\n            _, log_output = run_dbt_and_capture([\"deps\"])\n\n        # we should not see any manipulated form of the secret value (abc123) here\n        # we should see a manipulated form of the placeholder instead\n        assert \"a b c 1 2 3\" not in str(excinfo.value)\n        assert \"D B T _ E N V _ S E C R E T _ G I T _ T O K E N\" in str(excinfo.value)\n"
  },
  {
    "path": "tests/functional/context_methods/test_var_dependency.py",
    "content": "import pytest\n\nfrom dbt.tests.util import check_relations_equal, run_dbt\nfrom tests.functional.context_methods.first_dependency import (\n    FirstDependencyConfigProject,\n    FirstDependencyProject,\n)\n\ndependency_seeds__root_model_expected_csv = \"\"\"first_dep_global,from_root\ndep_never_overridden,root_root_value\n\"\"\"\n\ndependency_models__inside__model_sql = \"\"\"\nselect\n    '{{ var(\"first_dep_override\") }}' as first_dep_global,\n    '{{ var(\"from_root_to_root\") }}' as from_root\n\n\"\"\"\n\n\nclass TestVarDependencyInheritance(FirstDependencyProject):\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\"root_model_expected.csv\": dependency_seeds__root_model_expected_csv}\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"inside\": {\"model.sql\": dependency_models__inside__model_sql}}\n\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\n            \"packages\": [\n                {\"local\": \"first_dependency\"},\n            ]\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"vars\": {\n                \"first_dep_override\": \"dep_never_overridden\",\n                \"test\": {\n                    \"from_root_to_root\": \"root_root_value\",\n                },\n                \"first_dep\": {\n                    \"from_root_to_first\": \"root_first_value\",\n                },\n            },\n        }\n\n    def test_var_mutual_overrides_v1_conversion(self, project, first_dependency):\n        run_dbt([\"deps\"])\n        assert len(run_dbt([\"seed\"])) == 2\n        assert len(run_dbt([\"run\"])) == 2\n        check_relations_equal(project.adapter, [\"root_model_expected\", \"model\"])\n        check_relations_equal(project.adapter, [\"first_dep_expected\", \"first_dep_model\"])\n\n\nclass TestVarConfigDependencyInheritance(FirstDependencyConfigProject):\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\n            \"packages\": [\n                {\"local\": \"first_dependency\"},\n            ]\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"vars\": {\n                \"test_config_root_override\": \"configured_from_root\",\n            },\n        }\n\n    def test_root_var_overrides_package_var(self, project, first_dependency):\n        run_dbt([\"deps\"])\n        run_dbt([\"seed\"])\n        assert len(run_dbt([\"run\"])) == 1\n        check_relations_equal(project.adapter, [\"first_dep_expected\", \"first_dep_model\"])\n"
  },
  {
    "path": "tests/functional/context_methods/test_var_in_generate_name.py",
    "content": "import pytest\n\nfrom dbt.exceptions import CompilationError\nfrom dbt.tests.util import run_dbt, update_config_file\n\nmodel_sql = \"\"\"\nselect 1 as id\n\"\"\"\n\nbad_generate_macros__generate_names_sql = \"\"\"\n{% macro generate_schema_name(custom_schema_name, node) -%}\n    {% do var('somevar') %}\n    {% do return(dbt.generate_schema_name(custom_schema_name, node)) %}\n{%- endmacro %}\n\n\"\"\"\n\n\nclass TestMissingVarGenerateNameMacro:\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"generate_names.sql\": bad_generate_macros__generate_names_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model.sql\": model_sql}\n\n    def test_generate_schema_name_var(self, project):\n        # var isn't set, so generate_name macro fails\n        with pytest.raises(CompilationError) as excinfo:\n            run_dbt([\"compile\"])\n\n        assert \"Required var 'somevar' not found in config\" in str(excinfo.value)\n\n        # globally scoped -- var is set at top-level\n        update_config_file({\"vars\": {\"somevar\": 1}}, project.project_root, \"dbt_project.yml\")\n        run_dbt([\"compile\"])\n\n        # locally scoped -- var is set in 'test' scope\n        update_config_file(\n            {\"vars\": {\"test\": {\"somevar\": 1}}}, project.project_root, \"dbt_project.yml\"\n        )\n        run_dbt([\"compile\"])\n"
  },
  {
    "path": "tests/functional/context_methods/test_yaml_functions.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt\n\ntests__from_yaml_sql = \"\"\"\n{% set simplest = (fromyaml('a: 1') == {'a': 1}) %}\n{% set nested_data %}\na:\n  b:\n   - c: 1\n     d: 2\n   - c: 3\n     d: 4\n{% endset %}\n{% set nested = (fromyaml(nested_data) == {'a': {'b': [{'c': 1, 'd': 2}, {'c': 3, 'd': 4}]}}) %}\n\n(select 'simplest' as name {% if simplest %}limit 0{% endif %})\nunion all\n(select 'nested' as name {% if nested %}limit 0{% endif %})\n\"\"\"\n\ntests__to_yaml_sql = \"\"\"\n{% set simplest = (toyaml({'a': 1}) == 'a: 1\\\\n') %}\n{% set default_sort = (toyaml({'b': 2, 'a': 1}) == 'b: 2\\\\na: 1\\\\n') %}\n{% set unsorted = (toyaml({'b': 2, 'a': 1}, sort_keys=False) == 'b: 2\\\\na: 1\\\\n') %}\n{% set sorted = (toyaml({'b': 2, 'a': 1}, sort_keys=True) == 'a: 1\\\\nb: 2\\\\n') %}\n{% set default_results = (toyaml({'a': adapter}, 'failed') == 'failed') %}\n\n(select 'simplest' as name {% if simplest %}limit 0{% endif %})\nunion all\n(select 'default_sort' as name {% if default_sort %}limit 0{% endif %})\nunion all\n(select 'unsorted' as name {% if unsorted %}limit 0{% endif %})\nunion all\n(select 'sorted' as name {% if sorted %}limit 0{% endif %})\nunion all\n(select 'default_results' as name {% if default_results %}limit 0{% endif %})\n\"\"\"\n\n\nclass TestContextVars:\n    # This test has no actual models\n\n    @pytest.fixture(scope=\"class\")\n    def tests(self):\n        return {\"from_yaml.sql\": tests__from_yaml_sql, \"to_yaml.sql\": tests__to_yaml_sql}\n\n    def test_json_data_tests(self, project):\n        assert len(run_dbt([\"test\"])) == 2\n"
  },
  {
    "path": "tests/functional/contracts/test_contract_enforcement.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt, write_file\n\nmy_model_sql = \"\"\"\nselect 'some string' as string_column\n\"\"\"\n\nmy_model_int_sql = \"\"\"\nselect 123 as int_column\n\"\"\"\n\nmodel_schema_yml = \"\"\"\nmodels:\n  - name: my_model\n    config:\n      materialized: incremental\n      on_schema_change: append_new_columns\n      contract: {enforced: true}\n    columns:\n      - name: string_column\n        data_type: text\n\"\"\"\n\n\nclass TestIncrementalModelContractEnforcement:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": my_model_sql,\n            \"schema.yml\": model_schema_yml,\n        }\n\n    def test_contracted_incremental(self, project):\n        results = run_dbt()\n        assert len(results) == 1\n        # now update the column type in the model to break the contract\n        write_file(my_model_int_sql, project.project_root, \"models\", \"my_model.sql\")\n\n        expected_msg = \"This model has an enforced contract that failed.\"\n        results = run_dbt(expect_pass=False)\n        assert len(results) == 1\n        msg = results[0].message\n        assert expected_msg in msg\n"
  },
  {
    "path": "tests/functional/contracts/test_contract_precision.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt_and_capture\n\nmy_numeric_model_sql = \"\"\"\nselect\n  1.234 as non_integer\n\"\"\"\n\nmodel_schema_numerics_yml = \"\"\"\nversion: 2\nmodels:\n  - name: my_numeric_model\n    config:\n      contract:\n        enforced: true\n    columns:\n      - name: non_integer\n        data_type: numeric\n\"\"\"\n\nmodel_schema_numerics_precision_yml = \"\"\"\nversion: 2\nmodels:\n  - name: my_numeric_model\n    config:\n      contract:\n        enforced: true\n    columns:\n      - name: non_integer\n        data_type: numeric(38,3)\n\"\"\"\n\n\nclass TestModelContractNumericNoPrecision:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_numeric_model.sql\": my_numeric_model_sql,\n            \"schema.yml\": model_schema_numerics_yml,\n        }\n\n    def test_contracted_numeric_without_precision(self, project):\n        expected_msg = \"Detected columns with numeric type and unspecified precision/scale, this can lead to unintended rounding: ['non_integer']\"\n        _, logs = run_dbt_and_capture([\"run\"], expect_pass=True)\n        assert expected_msg in logs\n        _, logs = run_dbt_and_capture(\n            [\"--warn-error-options\", \"{'error': 'all', 'warn': ['DeprecationsSummary']}\", \"run\"],\n            expect_pass=False,\n        )\n        assert \"Compilation Error in model my_numeric_model\" in logs\n        assert expected_msg in logs\n\n\nclass TestModelContractNumericPrecision:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_numeric_model.sql\": my_numeric_model_sql,\n            \"schema.yml\": model_schema_numerics_precision_yml,\n        }\n\n    def test_contracted_numeric_with_precision(self, project):\n        expected_msg = \"Detected columns with numeric type and unspecified precision/scale, this can lead to unintended rounding: ['non_integer']\"\n        _, logs = run_dbt_and_capture([\"run\"], expect_pass=True)\n        assert expected_msg not in logs\n"
  },
  {
    "path": "tests/functional/contracts/test_nonstandard_data_type.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt, run_dbt_and_capture\n\nmy_numeric_model_sql = \"\"\"\nselect\n  12.34 as price\n\"\"\"\n\nmy_money_model_sql = \"\"\"\nselect\n  cast('12.34' as money) as price\n\"\"\"\n\nmodel_schema_money_yml = \"\"\"\nmodels:\n  - name: my_model\n    config:\n      contract:\n        enforced: true\n    columns:\n      - name: price\n        data_type: money\n\"\"\"\n\nmodel_schema_numeric_yml = \"\"\"\nmodels:\n  - name: my_model\n    config:\n      contract:\n        enforced: true\n    columns:\n      - name: price\n        data_type: numeric\n\"\"\"\n\n\nclass TestModelContractUnrecognizedTypeCode1:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": my_money_model_sql,\n            \"schema.yml\": model_schema_money_yml,\n        }\n\n    def test_nonstandard_data_type(self, project):\n        run_dbt([\"run\"], expect_pass=True)\n\n\nclass TestModelContractUnrecognizedTypeCodeActualMismatch:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": my_money_model_sql,\n            \"schema.yml\": model_schema_numeric_yml,\n        }\n\n    def test_nonstandard_data_type(self, project):\n        expected_msg = \"unknown type_code 790 | DECIMAL       | data type mismatch\"\n        _, logs = run_dbt_and_capture([\"run\"], expect_pass=False)\n        assert expected_msg in logs\n\n\nclass TestModelContractUnrecognizedTypeCodeExpectedMismatch:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": my_numeric_model_sql,\n            \"schema.yml\": model_schema_money_yml,\n        }\n\n    def test_nonstandard_data_type(self, project):\n        expected_msg = \"DECIMAL         | unknown type_code 790 | data type mismatch\"\n        _, logs = run_dbt_and_capture([\"run\"], expect_pass=False)\n        print(logs)\n        assert expected_msg in logs\n"
  },
  {
    "path": "tests/functional/custom_aliases/fixtures.py",
    "content": "model1_sql = \"\"\"\n{{ config(materialized='table', alias='alias') }}\n\nselect {{ string_literal(this.name) }} as model_name\n\"\"\"\n\nmodel2_sql = \"\"\"\n{{ config(materialized='table') }}\n\nselect {{ string_literal(this.name) }} as model_name\n\"\"\"\n\nmacros_sql = \"\"\"\n{% macro generate_alias_name(custom_alias_name, node) -%}\n    {%- if custom_alias_name is none -%}\n        {{ node.name }}\n    {%- else -%}\n        custom_{{ custom_alias_name | trim }}\n    {%- endif -%}\n{%- endmacro %}\n\n\n{% macro string_literal(s) -%}\n  {{ adapter.dispatch('string_literal', macro_namespace='test')(s) }}\n{%- endmacro %}\n\n{% macro default__string_literal(s) %}\n    '{{ s }}'::text\n{% endmacro %}\n\"\"\"\n\nmacros_config_sql = \"\"\"\n{#-- Verify that the config['alias'] key is present #}\n{% macro generate_alias_name(custom_alias_name, node) -%}\n    {%- if custom_alias_name is none -%}\n        {{ node.name }}\n    {%- else -%}\n        custom_{{ node.config['alias'] if 'alias' in node.config else '' | trim }}\n    {%- endif -%}\n{%- endmacro %}\n\n{% macro string_literal(s) -%}\n  {{ adapter.dispatch('string_literal', macro_namespace='test')(s) }}\n{%- endmacro %}\n\n{% macro default__string_literal(s) %}\n    '{{ s }}'::text\n{% endmacro %}\n\"\"\"\n\nschema_yml = \"\"\"\nversion: 2\n\nmodels:\n  - name: model1\n    columns:\n      - name: model_name\n        data_tests:\n          - accepted_values:\n             values: ['custom_alias']\n  - name: model2\n    columns:\n      - name: model_name\n        data_tests:\n          - accepted_values:\n             values: ['model2']\n\n\"\"\"\n"
  },
  {
    "path": "tests/functional/custom_aliases/test_custom_aliases.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt\nfrom tests.functional.custom_aliases.fixtures import (\n    macros_config_sql,\n    macros_sql,\n    model1_sql,\n    model2_sql,\n    schema_yml,\n)\n\n\nclass TestAliases:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model1.sql\": model1_sql, \"model2.sql\": model2_sql, \"schema.yml\": schema_yml}\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\n            \"macros.sql\": macros_sql,\n        }\n\n    def test_customer_alias_name(self, project):\n        results = run_dbt([\"run\"])\n        assert len(results) == 2\n\n        results = run_dbt([\"test\"])\n        assert len(results) == 2\n\n\nclass TestAliasesWithConfig:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model1.sql\": model1_sql, \"model2.sql\": model2_sql, \"schema.yml\": schema_yml}\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\n            \"macros.sql\": macros_config_sql,\n        }\n\n    def test_customer_alias_name(self, project):\n        results = run_dbt([\"run\"])\n        assert len(results) == 2\n\n        results = run_dbt([\"test\"])\n        assert len(results) == 2\n"
  },
  {
    "path": "tests/functional/custom_schemas/test_custom_schemas.py",
    "content": "import pytest\n\nfrom dbt.exceptions import ParsingError\nfrom dbt.tests.util import run_dbt\n\ngenerate_schema_name_macro_sql = \"\"\"\n{% macro generate_schema_name(custom_schema_name, node) %}\n    test_schema\n{% endmacro %}\n\"\"\"\n\n# this macro returns none when custom_schema_name (from config schema) is unset\ngenerate_schema_name_macro_null_return = \"\"\"\n{% macro generate_schema_name(custom_schema_name, node) %}\n    {{ return(custom_schema_name) }}\n{% endmacro %}\n\"\"\"\n\n\nclass TestCustomSchema:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model.sql\": \"select 1 as id\"}\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\n            \"generate_schema_name_null_return.sql\": generate_schema_name_macro_sql,\n        }\n\n    def test_custom_schema(self, project):\n        results = run_dbt([\"run\"])\n        assert len(results) == 1\n        assert results.results[0].node.schema == \"test_schema\"\n\n\nclass TestCustomSchemaNullReturn:\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"flags\": {\n                \"require_valid_schema_from_generate_schema_name\": True,\n            },\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model.sql\": \"select 1 as id\"}\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\n            \"generate_schema_name_null_return.sql\": generate_schema_name_macro_null_return,\n        }\n\n    def test_custom_schema_null_return(self, project):\n        with pytest.raises(ParsingError) as excinfo:\n            run_dbt([\"run\"])\n        assert (\n            \"Node 'model.test.model' has a schema set to None as a result of a generate_schema_name call.\"\n            in str(excinfo.value)\n        )\n\n\nclass TestCustomSchemaNullReturnLegacy:\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"flags\": {\n                \"require_valid_schema_from_generate_schema_name\": False,\n            },\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model.sql\": \"select 1 as id\",\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\n            \"generate_schema_name_null_return.sql\": generate_schema_name_macro_null_return,\n        }\n\n    def test_custom_schema_null_return_legacy(self, project):\n        manifest = run_dbt([\"parse\"], expect_pass=True)\n        # This was buggy behavior (non-conformant to manifest schemas published in v12) but nonetheless legacy behavior\n        assert manifest.nodes[\"model.test.model\"].schema is None\n\n\n# Should be updated to TestCustomSchemaNullReturn instead of TestCustomSchemaNullReturnLegacy once\n# required_valid_schema_from_generate_schema_name flag is set to True by default\nclass TestCustomSchemaNullReturnDefault(TestCustomSchemaNullReturnLegacy):\n    pass\n"
  },
  {
    "path": "tests/functional/custom_singular_tests/data/seed_expected.sql",
    "content": "create table {schema}.seed (\n    favorite_color VARCHAR(10),\n\tid INTEGER,\n\tfirst_name VARCHAR(11),\n\temail VARCHAR(31),\n\tip_address VARCHAR(15),\n\tupdated_at TIMESTAMP WITHOUT TIME ZONE\n);\n\n\nINSERT INTO {schema}.seed\n    (favorite_color, id, first_name, email, ip_address, updated_at)\nVALUES\n    ('blue', 1,'Larry','lking0@miitbeian.gov.cn','69.135.206.194','2008-09-12 19:08:31'),\n    ('blue', 2,'Larry','lperkins1@toplist.cz','64.210.133.162','1978-05-09 04:15:14'),\n    ('blue', 3,'Anna','amontgomery2@miitbeian.gov.cn','168.104.64.114','2011-10-16 04:07:57'),\n    ('blue', 4,'Sandra','sgeorge3@livejournal.com','229.235.252.98','1973-07-19 10:52:43'),\n    ('blue', 5,'Fred','fwoods4@google.cn','78.229.170.124','2012-09-30 16:38:29'),\n    ('blue', 6,'Stephen','shanson5@livejournal.com','182.227.157.105','1995-11-07 21:40:50'),\n    ('blue', 7,'William','wmartinez6@upenn.edu','135.139.249.50','1982-09-05 03:11:59'),\n    ('blue', 8,'Jessica','jlong7@hao123.com','203.62.178.210','1991-10-16 11:03:15'),\n    ('blue', 9,'Douglas','dwhite8@tamu.edu','178.187.247.1','1979-10-01 09:49:48'),\n    ('blue', 10,'Lisa','lcoleman9@nydailynews.com','168.234.128.249','2011-05-26 07:45:49'),\n    ('blue', 11,'Ralph','rfieldsa@home.pl','55.152.163.149','1972-11-18 19:06:11'),\n    ('blue', 12,'Louise','lnicholsb@samsung.com','141.116.153.154','2014-11-25 20:56:14'),\n    ('blue', 13,'Clarence','cduncanc@sfgate.com','81.171.31.133','2011-11-17 07:02:36'),\n    ('blue', 14,'Daniel','dfranklind@omniture.com','8.204.211.37','1980-09-13 00:09:04'),\n    ('blue', 15,'Katherine','klanee@auda.org.au','176.96.134.59','1997-08-22 19:36:56'),\n    ('blue', 16,'Billy','bwardf@wikia.com','214.108.78.85','2003-10-19 02:14:47'),\n    ('blue', 17,'Annie','agarzag@ocn.ne.jp','190.108.42.70','1988-10-28 15:12:35'),\n    ('blue', 18,'Shirley','scolemanh@fastcompany.com','109.251.164.84','1988-08-24 10:50:57'),\n    ('blue', 19,'Roger','rfrazieri@scribd.com','38.145.218.108','1985-12-31 15:17:15'),\n    ('blue', 20,'Lillian','lstanleyj@goodreads.com','47.57.236.17','1970-06-08 02:09:05'),\n    ('blue', 21,'Aaron','arodriguezk@nps.gov','205.245.118.221','1985-10-11 23:07:49'),\n    ('blue', 22,'Patrick','pparkerl@techcrunch.com','19.8.100.182','2006-03-29 12:53:56'),\n    ('blue', 23,'Phillip','pmorenom@intel.com','41.38.254.103','2011-11-07 15:35:43'),\n    ('blue', 24,'Henry','hgarcian@newsvine.com','1.191.216.252','2008-08-28 08:30:44'),\n    ('blue', 25,'Irene','iturnero@opera.com','50.17.60.190','1994-04-01 07:15:02'),\n    ('blue', 26,'Andrew','adunnp@pen.io','123.52.253.176','2000-11-01 06:03:25'),\n    ('blue', 27,'David','dgutierrezq@wp.com','238.23.203.42','1988-01-25 07:29:18'),\n    ('blue', 28,'Henry','hsanchezr@cyberchimps.com','248.102.2.185','1983-01-01 13:36:37'),\n    ('blue', 29,'Evelyn','epetersons@gizmodo.com','32.80.46.119','1979-07-16 17:24:12'),\n    ('blue', 30,'Tammy','tmitchellt@purevolume.com','249.246.167.88','2001-04-03 10:00:23'),\n    ('blue', 31,'Jacqueline','jlittleu@domainmarket.com','127.181.97.47','1986-02-11 21:35:50'),\n    ('blue', 32,'Earl','eortizv@opera.com','166.47.248.240','1996-07-06 08:16:27'),\n    ('blue', 33,'Juan','jgordonw@sciencedirect.com','71.77.2.200','1987-01-31 03:46:44'),\n    ('blue', 34,'Diane','dhowellx@nyu.edu','140.94.133.12','1994-06-11 02:30:05'),\n    ('blue', 35,'Randy','rkennedyy@microsoft.com','73.255.34.196','2005-05-26 20:28:39'),\n    ('blue', 36,'Janice','jriveraz@time.com','22.214.227.32','1990-02-09 04:16:52'),\n    ('blue', 37,'Laura','lperry10@diigo.com','159.148.145.73','2015-03-17 05:59:25'),\n    ('blue', 38,'Gary','gray11@statcounter.com','40.193.124.56','1970-01-27 10:04:51'),\n    ('blue', 39,'Jesse','jmcdonald12@typepad.com','31.7.86.103','2009-03-14 08:14:29'),\n    ('blue', 40,'Sandra','sgonzalez13@goodreads.com','223.80.168.239','1993-05-21 14:08:54'),\n    ('blue', 41,'Scott','smoore14@archive.org','38.238.46.83','1980-08-30 11:16:56'),\n    ('blue', 42,'Phillip','pevans15@cisco.com','158.234.59.34','2011-12-15 23:26:31'),\n    ('blue', 43,'Steven','sriley16@google.ca','90.247.57.68','2011-10-29 19:03:28'),\n    ('blue', 44,'Deborah','dbrown17@hexun.com','179.125.143.240','1995-04-10 14:36:07'),\n    ('blue', 45,'Lori','lross18@ow.ly','64.80.162.180','1980-12-27 16:49:15'),\n    ('blue', 46,'Sean','sjackson19@tumblr.com','240.116.183.69','1988-06-12 21:24:45'),\n    ('blue', 47,'Terry','tbarnes1a@163.com','118.38.213.137','1997-09-22 16:43:19'),\n    ('blue', 48,'Dorothy','dross1b@ebay.com','116.81.76.49','2005-02-28 13:33:24'),\n    ('blue', 49,'Samuel','swashington1c@house.gov','38.191.253.40','1989-01-19 21:15:48'),\n    ('blue', 50,'Ralph','rcarter1d@tinyurl.com','104.84.60.174','2007-08-11 10:21:49'),\n    ('green', 51,'Wayne','whudson1e@princeton.edu','90.61.24.102','1983-07-03 16:58:12'),\n    ('green', 52,'Rose','rjames1f@plala.or.jp','240.83.81.10','1995-06-08 11:46:23'),\n    ('green', 53,'Louise','lcox1g@theglobeandmail.com','105.11.82.145','2016-09-19 14:45:51'),\n    ('green', 54,'Kenneth','kjohnson1h@independent.co.uk','139.5.45.94','1976-08-17 11:26:19'),\n    ('green', 55,'Donna','dbrown1i@amazon.co.uk','19.45.169.45','2006-05-27 16:51:40'),\n    ('green', 56,'Johnny','jvasquez1j@trellian.com','118.202.238.23','1975-11-17 08:42:32'),\n    ('green', 57,'Patrick','pramirez1k@tamu.edu','231.25.153.198','1997-08-06 11:51:09'),\n    ('green', 58,'Helen','hlarson1l@prweb.com','8.40.21.39','1993-08-04 19:53:40'),\n    ('green', 59,'Patricia','pspencer1m@gmpg.org','212.198.40.15','1977-08-03 16:37:27'),\n    ('green', 60,'Joseph','jspencer1n@marriott.com','13.15.63.238','2005-07-23 20:22:06'),\n    ('green', 61,'Phillip','pschmidt1o@blogtalkradio.com','177.98.201.190','1976-05-19 21:47:44'),\n    ('green', 62,'Joan','jwebb1p@google.ru','105.229.170.71','1972-09-07 17:53:47'),\n    ('green', 63,'Phyllis','pkennedy1q@imgur.com','35.145.8.244','2000-01-01 22:33:37'),\n    ('green', 64,'Katherine','khunter1r@smh.com.au','248.168.205.32','1991-01-09 06:40:24'),\n    ('green', 65,'Laura','lvasquez1s@wiley.com','128.129.115.152','1997-10-23 12:04:56'),\n    ('green', 66,'Juan','jdunn1t@state.gov','44.228.124.51','2004-11-10 05:07:35'),\n    ('green', 67,'Judith','jholmes1u@wiley.com','40.227.179.115','1977-08-02 17:01:45'),\n    ('green', 68,'Beverly','bbaker1v@wufoo.com','208.34.84.59','2016-03-06 20:07:23'),\n    ('green', 69,'Lawrence','lcarr1w@flickr.com','59.158.212.223','1988-09-13 06:07:21'),\n    ('green', 70,'Gloria','gwilliams1x@mtv.com','245.231.88.33','1995-03-18 22:32:46'),\n    ('green', 71,'Steven','ssims1y@cbslocal.com','104.50.58.255','2001-08-05 21:26:20'),\n    ('green', 72,'Betty','bmills1z@arstechnica.com','103.177.214.220','1981-12-14 21:26:54'),\n    ('green', 73,'Mildred','mfuller20@prnewswire.com','151.158.8.130','2000-04-19 10:13:55'),\n    ('green', 74,'Donald','dday21@icq.com','9.178.102.255','1972-12-03 00:58:24'),\n    ('green', 75,'Eric','ethomas22@addtoany.com','85.2.241.227','1992-11-01 05:59:30'),\n    ('green', 76,'Joyce','jarmstrong23@sitemeter.com','169.224.20.36','1985-10-24 06:50:01'),\n    ('green', 77,'Maria','mmartinez24@amazonaws.com','143.189.167.135','2005-10-05 05:17:42'),\n    ('green', 78,'Harry','hburton25@youtube.com','156.47.176.237','1978-03-26 05:53:33'),\n    ('green', 79,'Kevin','klawrence26@hao123.com','79.136.183.83','1994-10-12 04:38:52'),\n    ('green', 80,'David','dhall27@prweb.com','133.149.172.153','1976-12-15 16:24:24'),\n    ('green', 81,'Kathy','kperry28@twitter.com','229.242.72.228','1979-03-04 02:58:56'),\n    ('green', 82,'Adam','aprice29@elegantthemes.com','13.145.21.10','1982-11-07 11:46:59'),\n    ('green', 83,'Brandon','bgriffin2a@va.gov','73.249.128.212','2013-10-30 05:30:36'),\n    ('green', 84,'Henry','hnguyen2b@discovery.com','211.36.214.242','1985-01-09 06:37:27'),\n    ('green', 85,'Eric','esanchez2c@edublogs.org','191.166.188.251','2004-05-01 23:21:42'),\n    ('green', 86,'Jason','jlee2d@jimdo.com','193.92.16.182','1973-01-08 09:05:39'),\n    ('green', 87,'Diana','drichards2e@istockphoto.com','19.130.175.245','1994-10-05 22:50:49'),\n    ('green', 88,'Andrea','awelch2f@abc.net.au','94.155.233.96','2002-04-26 08:41:44'),\n    ('green', 89,'Louis','lwagner2g@miitbeian.gov.cn','26.217.34.111','2003-08-25 07:56:39'),\n    ('green', 90,'Jane','jsims2h@seesaa.net','43.4.220.135','1987-03-20 20:39:04'),\n    ('green', 91,'Larry','lgrant2i@si.edu','97.126.79.34','2000-09-07 20:26:19'),\n    ('green', 92,'Louis','ldean2j@prnewswire.com','37.148.40.127','2011-09-16 20:12:14'),\n    ('green', 93,'Jennifer','jcampbell2k@xing.com','38.106.254.142','1988-07-15 05:06:49'),\n    ('green', 94,'Wayne','wcunningham2l@google.com.hk','223.28.26.187','2009-12-15 06:16:54'),\n    ('green', 95,'Lori','lstevens2m@icq.com','181.250.181.58','1984-10-28 03:29:19'),\n    ('green', 96,'Judy','jsimpson2n@marriott.com','180.121.239.219','1986-02-07 15:18:10'),\n    ('green', 97,'Phillip','phoward2o@usa.gov','255.247.0.175','2002-12-26 08:44:45'),\n    ('green', 98,'Gloria','gwalker2p@usa.gov','156.140.7.128','1997-10-04 07:58:58'),\n    ('green', 99,'Paul','pjohnson2q@umn.edu','183.59.198.197','1991-11-14 12:33:55'),\n    ('green', 100,'Frank','fgreene2r@blogspot.com','150.143.68.121','2010-06-12 23:55:39');\n"
  },
  {
    "path": "tests/functional/custom_singular_tests/test_custom_singular_tests.py",
    "content": "from pathlib import Path\n\nimport pytest\n\nfrom dbt.tests.util import run_dbt\n\n# from `test/integration/009_data_test`\n\n#\n# Models\n#\n\nmodels__table_copy = \"\"\"\n{{\n    config(\n        materialized='table'\n    )\n}}\n\nselect * from {{ this.schema }}.seed\n\"\"\"\n\n#\n# Tests\n#\n\ntests__fail_email_is_always_null = \"\"\"\nselect *\nfrom {{ ref('table_copy') }}\nwhere email is not null\n\"\"\"\n\ntests__fail_no_ref = \"\"\"\nselect 1\n\"\"\"\n\ntests__dotted_path_pass_id_not_null = \"\"\"\n{# Same as `pass_id_not_null` but with dots in its name #}\n\nselect *\nfrom {{ ref('table_copy') }}\nwhere id is null\n\"\"\"\n\ntests__pass_id_not_null = \"\"\"\nselect *\nfrom {{ ref('table_copy') }}\nwhere id is null\n\"\"\"\n\ntests__pass_no_ref = \"\"\"\nselect 1 limit 0\n\"\"\"\n\n\nclass CustomSingularTestsBase(object):\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project):\n        \"\"\"Create seed and downstream model tests are to be run on\"\"\"\n        project.run_sql_file(project.test_data_dir / Path(\"seed_expected.sql\"))\n\n        results = run_dbt()\n        assert len(results) == 1\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"table_copy.sql\": models__table_copy}\n\n\nclass TestPassingTests(CustomSingularTestsBase):\n    @pytest.fixture(scope=\"class\")\n    def tests(self):\n        return {\n            \"my_db.my_schema.table_copy.pass_id_not_null.sql\": tests__dotted_path_pass_id_not_null,\n            \"tests__pass_id_not_null.sql\": tests__pass_id_not_null,\n            \"tests__pass_no_ref.sql\": tests__pass_no_ref,\n        }\n\n    def test_data_tests(self, project, tests):\n        test_results = run_dbt([\"test\"])\n        assert len(test_results) == len(tests)\n\n        for result in test_results:\n            assert result.status == \"pass\"\n            assert not result.skipped\n            assert result.failures == 0\n\n\nclass TestFailingTests(CustomSingularTestsBase):\n    @pytest.fixture(scope=\"class\")\n    def tests(self):\n        return {\n            \"tests__fail_email_is_always_null.sql\": tests__fail_email_is_always_null,\n            \"tests__fail_no_ref.sql\": tests__fail_no_ref,\n        }\n\n    def test_data_tests(self, project, tests):\n        \"\"\"assert that all deliberately failing tests actually fail\"\"\"\n        test_results = run_dbt([\"test\"], expect_pass=False)\n        assert len(test_results) == len(tests)\n\n        for result in test_results:\n            assert result.status == \"fail\"\n            assert not result.skipped\n            assert result.failures > 0\n            assert result.adapter_response == {\n                \"_message\": \"SELECT 1\",\n                \"code\": \"SELECT\",\n                \"rows_affected\": 1,\n            }\n"
  },
  {
    "path": "tests/functional/custom_target_path/test_custom_target_path.py",
    "content": "from pathlib import Path\n\nimport pytest\n\nfrom dbt.tests.util import run_dbt\n\n\nclass TestTargetPathConfig:\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\"config-version\": 2, \"target-path\": \"project_target\"}\n\n    def test_target_path(self, project):\n        run_dbt([\"run\"])\n        assert Path(\"project_target\").is_dir()\n        assert not Path(\"target\").is_dir()\n\n\nclass TestTargetPathEnvVar:\n    def test_target_path(self, project, monkeypatch):\n        monkeypatch.setenv(\"DBT_TARGET_PATH\", \"env_target\")\n        run_dbt([\"run\"])\n        assert Path(\"env_target\").is_dir()\n        assert not Path(\"project_target\").is_dir()\n        assert not Path(\"target\").is_dir()\n\n\nclass TestTargetPathCliArg:\n    def test_target_path(self, project, monkeypatch):\n        monkeypatch.setenv(\"DBT_TARGET_PATH\", \"env_target\")\n        run_dbt([\"run\", \"--target-path\", \"cli_target\"])\n        assert Path(\"cli_target\").is_dir()\n        assert not Path(\"env_target\").is_dir()\n        assert not Path(\"project_target\").is_dir()\n        assert not Path(\"target\").is_dir()\n"
  },
  {
    "path": "tests/functional/cycles/test_cycles.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt\n\nmodel_a_sql = \"\"\"\nselect * from {{ ref('model_b') }}\n\"\"\"\n\nmodel_b_sql = \"\"\"\nselect * from {{ ref('model_a') }}\n\"\"\"\n\ncomplex_cycle__model_a_sql = \"\"\"\nselect 1 as id\n\"\"\"\n\ncomplex_cycle__model_b_sql = \"\"\"\nselect * from {{ ref('model_a') }}s\nunion all\nselect * from {{ ref('model_e') }}\n\"\"\"\n\ncomplex_cycle__model_c_sql = \"\"\"\nselect * from {{ ref('model_b') }}\n\"\"\"\n\ncomplex_cycle__model_d_sql = \"\"\"\nselect * from {{ ref('model_c') }}\n\"\"\"\n\ncomplex_cycle__model_e_sql = \"\"\"\nselect * from {{ ref('model_e') }}\n\"\"\"\n\n\nclass TestSimpleCycle:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model_a.sql\": model_a_sql, \"model_b.sql\": model_b_sql}\n\n    def test_simple_cycle(self, project):\n        with pytest.raises(RuntimeError) as exc:\n            run_dbt([\"run\"])\n        expected_msg = \"Found a cycle\"\n        assert expected_msg in str(exc.value)\n\n\nclass TestComplexCycle:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        # The cycle in this graph looks like:\n        #   A -> B -> C -> D\n        #        ^         |\n        #        |         |\n        #        +--- E <--+\n        return {\n            \"model_a.sql\": complex_cycle__model_a_sql,\n            \"model_b.sql\": complex_cycle__model_b_sql,\n            \"model_c.sql\": complex_cycle__model_c_sql,\n            \"model_d.sql\": complex_cycle__model_d_sql,\n            \"model_e.sql\": complex_cycle__model_e_sql,\n        }\n\n    def test_complex_cycle(self, project):\n        with pytest.raises(RuntimeError) as exc:\n            run_dbt([\"run\"])\n        expected_msg = \"Found a cycle\"\n        assert expected_msg in str(exc.value)\n"
  },
  {
    "path": "tests/functional/data_test_patch/fixtures.py",
    "content": "tests__my_singular_test_sql = \"\"\"\nwith my_cte as (\n    select 1 as id, 'foo' as name\n    union all\n    select 2 as id, 'bar' as name\n)\nselect * from my_cte\n\"\"\"\n\ntests__schema_yml = \"\"\"\ndata_tests:\n  - name: my_singular_test\n    description: \"{{ doc('my_singular_test_documentation') }}\"\n    config:\n      error_if: \">10\"\n      meta:\n        some_key: some_val\n\"\"\"\n\ntests__schema_2_yml = \"\"\"\ndata_tests:\n  - name: my_singular_test\n    description: \"My singular test description\"\n    config:\n      error_if: \">10\"\n      meta:\n        some_key: another_val\n\"\"\"\n\ntests__doc_block_md = \"\"\"\n{% docs my_singular_test_documentation %}\n\nSome docs from a doc block\n\n{% enddocs %}\n\"\"\"\n\ntests__invalid_name_schema_yml = \"\"\"\ndata_tests:\n  - name: my_double_test\n    description: documentation, but make it double\n\"\"\"\n\ntests__malformed_schema_yml = \"\"\"\ndata_tests: &not_null\n  - not_null:\n      where: some_condition\n\"\"\"\n"
  },
  {
    "path": "tests/functional/data_test_patch/test_singular_test_patch.py",
    "content": "from pathlib import Path\n\nimport pytest\n\nfrom dbt.tests.util import get_manifest, run_dbt, run_dbt_and_capture, write_file\nfrom tests.functional.data_test_patch.fixtures import (\n    tests__doc_block_md,\n    tests__invalid_name_schema_yml,\n    tests__malformed_schema_yml,\n    tests__my_singular_test_sql,\n    tests__schema_2_yml,\n    tests__schema_yml,\n)\n\n\nclass TestPatchSingularTest:\n    @pytest.fixture(scope=\"class\")\n    def tests(self):\n        return {\n            \"my_singular_test.sql\": tests__my_singular_test_sql,\n            \"schema.yml\": tests__schema_yml,\n            \"doc_block.md\": tests__doc_block_md,\n        }\n\n    def test_compile(self, project):\n        run_dbt([\"compile\"])\n        manifest = get_manifest(project.project_root)\n        assert len(manifest.nodes) == 1\n\n        my_singular_test_node = manifest.nodes[\"test.test.my_singular_test\"]\n        assert my_singular_test_node.description == \"Some docs from a doc block\"\n        assert my_singular_test_node.config.error_if == \">10\"\n        assert my_singular_test_node.config.meta == {\"some_key\": \"some_val\"}\n        assert my_singular_test_node.meta == {\"some_key\": \"some_val\"}\n\n        # partial parsing test\n        write_file(tests__schema_2_yml, project.project_root, \"tests\", \"schema.yml\")\n        manifest = run_dbt([\"parse\"])\n        test_node = manifest.nodes[\"test.test.my_singular_test\"]\n        assert test_node.description == \"My singular test description\"\n        assert test_node.config.meta == {\"some_key\": \"another_val\"}\n        assert test_node.meta == {\"some_key\": \"another_val\"}\n\n\nclass TestPatchSingularTestInvalidName:\n    @pytest.fixture(scope=\"class\")\n    def tests(self):\n        return {\n            \"my_singular_test.sql\": tests__my_singular_test_sql,\n            \"schema_with_invalid_name.yml\": tests__invalid_name_schema_yml,\n        }\n\n    def test_compile(self, project):\n        _, log_output = run_dbt_and_capture([\"compile\"])\n\n        file_path = Path(\"tests/schema_with_invalid_name.yml\")\n        assert (\n            f\"Did not find matching node for patch with name 'my_double_test' in the 'data_tests' section of file '{file_path}'\"\n            in log_output\n        )\n\n\nclass TestPatchSingularTestMalformedYaml:\n    @pytest.fixture(scope=\"class\")\n    def tests(self):\n        return {\n            \"my_singular_test.sql\": tests__my_singular_test_sql,\n            \"schema.yml\": tests__malformed_schema_yml,\n        }\n\n    def test_compile(self, project):\n        _, log_output = run_dbt_and_capture([\"compile\"])\n        file_path = Path(\"tests/schema.yml\")\n        assert f\"Unable to parse 'data_tests' section of file '{file_path}'\" in log_output\n        assert \"Entry did not contain a name\" in log_output\n"
  },
  {
    "path": "tests/functional/data_tests/test_hooks.py",
    "content": "from unittest import mock\n\nimport pytest\n\nfrom dbt.tests.util import run_dbt, run_dbt_and_capture\nfrom dbt_common.exceptions import CompilationError\n\norders_csv = \"\"\"order_id,order_date,customer_id\n1,2024-06-01,1001\n2,2024-06-02,1002\n3,2024-06-03,1003\n4,2024-06-04,1004\n\"\"\"\n\n\norders_model_sql = \"\"\"\nwith source as (\n    select\n        order_id,\n        order_date,\n        customer_id\n    from {{ ref('seed_orders') }}\n),\nfinal as (\n    select\n        order_id,\n        order_date,\n        customer_id\n    from source\n)\nselect * from final\n\"\"\"\n\n\norders_test_sql = \"\"\"\nselect *\nfrom {{ ref('orders') }}\nwhere order_id is null\n\"\"\"\n\n\nclass BaseSingularTestHooks:\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\"seed_orders.csv\": orders_csv}\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"orders.sql\": orders_model_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def tests(self):\n        return {\"orders_test.sql\": orders_test_sql}\n\n\nclass TestSingularTestPreHook(BaseSingularTestHooks):\n    def test_data_test_runs_adapter_pre_hook_pass(self, project):\n        results = run_dbt([\"seed\"])\n        assert len(results) == 1\n\n        results = run_dbt([\"run\"])\n        assert len(results) == 1\n\n        mock_pre_model_hook = mock.Mock()\n        with mock.patch.object(type(project.adapter), \"pre_model_hook\", mock_pre_model_hook):\n            results = run_dbt([\"test\"], expect_pass=True)\n            assert len(results) == 1\n            mock_pre_model_hook.assert_called_once()\n\n    def test_data_test_runs_adapter_pre_hook_fails(self, project):\n        results = run_dbt([\"seed\"])\n        assert len(results) == 1\n\n        results = run_dbt([\"run\"])\n        assert len(results) == 1\n\n        mock_pre_model_hook = mock.Mock()\n        mock_pre_model_hook.side_effect = CompilationError(\"exception from adapter.pre_model_hook\")\n        with mock.patch.object(type(project.adapter), \"pre_model_hook\", mock_pre_model_hook):\n            (_, log_output) = run_dbt_and_capture([\"test\"], expect_pass=False)\n            assert \"exception from adapter.pre_model_hook\" in log_output\n\n\nclass TestSingularTestPostHook(BaseSingularTestHooks):\n    def test_data_test_runs_adapter_post_hook_pass(self, project):\n        results = run_dbt([\"seed\"])\n        assert len(results) == 1\n\n        results = run_dbt([\"run\"])\n        assert len(results) == 1\n\n        mock_post_model_hook = mock.Mock()\n        with mock.patch.object(type(project.adapter), \"post_model_hook\", mock_post_model_hook):\n            results = run_dbt([\"test\"], expect_pass=True)\n            assert len(results) == 1\n            mock_post_model_hook.assert_called_once()\n\n    def test_data_test_runs_adapter_post_hook_fails(self, project):\n        results = run_dbt([\"seed\"])\n        assert len(results) == 1\n\n        results = run_dbt([\"run\"])\n        assert len(results) == 1\n\n        mock_post_model_hook = mock.Mock()\n        mock_post_model_hook.side_effect = CompilationError(\n            \"exception from adapter.post_model_hook\"\n        )\n        with mock.patch.object(type(project.adapter), \"post_model_hook\", mock_post_model_hook):\n            (_, log_output) = run_dbt_and_capture([\"test\"], expect_pass=False)\n            assert \"exception from adapter.post_model_hook\" in log_output\n"
  },
  {
    "path": "tests/functional/dbt_runner/test_dbt_runner.py",
    "content": "import os\nfrom unittest import mock\n\nimport pytest\n\nfrom dbt.adapters.factory import FACTORY, reset_adapters\nfrom dbt.cli.exceptions import DbtUsageException\nfrom dbt.cli.main import dbtRunner\nfrom dbt.exceptions import DbtProjectError\nfrom dbt.tests.util import read_file, write_file\nfrom dbt.version import __version__ as dbt_version\nfrom dbt_common.events.contextvars import get_node_info\n\n\nclass TestDbtRunner:\n    @pytest.fixture\n    def dbt(self) -> dbtRunner:\n        return dbtRunner()\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"models.sql\": \"select 1 as id\",\n        }\n\n    def test_group_invalid_option(self, dbt: dbtRunner) -> None:\n        res = dbt.invoke([\"--invalid-option\"])\n        assert type(res.exception) == DbtUsageException\n\n    def test_command_invalid_option(self, dbt: dbtRunner) -> None:\n        res = dbt.invoke([\"deps\", \"--invalid-option\"])\n        assert type(res.exception) == DbtUsageException\n\n    def test_command_mutually_exclusive_option(self, dbt: dbtRunner) -> None:\n        res = dbt.invoke([\"--warn-error\", \"--warn-error-options\", '{\"error\": \"all\"}', \"deps\"])\n        assert type(res.exception) == DbtUsageException\n        res = dbt.invoke([\"deps\", \"--warn-error\", \"--warn-error-options\", '{\"error\": \"all\"}'])\n        assert type(res.exception) == DbtUsageException\n\n        res = dbt.invoke([\"compile\", \"--select\", \"models\", \"--inline\", \"select 1 as id\"])\n        assert type(res.exception) == DbtUsageException\n\n    def test_invalid_command(self, dbt: dbtRunner) -> None:\n        res = dbt.invoke([\"invalid-command\"])\n        assert type(res.exception) == DbtUsageException\n\n    def test_invoke_version(self, dbt: dbtRunner) -> None:\n        dbt.invoke([\"--version\"])\n\n    def test_callbacks(self) -> None:\n        mock_callback = mock.MagicMock()\n        dbt = dbtRunner(callbacks=[mock_callback])\n        # the `debug` command is one of the few commands wherein you don't need\n        # to have a project to run it and it will emit events\n        dbt.invoke([\"debug\"])\n        mock_callback.assert_called()\n\n    def test_callback_node_finished_exceptions_are_raised(self, project):\n        from dbt_common.events.base_types import EventMsg\n\n        def callback_with_exception(event: EventMsg):\n            if event.info.name == \"NodeFinished\":\n                raise Exception(\"This should let continue the execution registering the failure\")\n\n        dbt = dbtRunner(callbacks=[callback_with_exception])\n        result = dbt.invoke([\"run\", \"--select\", \"models\"])\n\n        assert result is not None\n        assert (\n            result.result.results[0].message\n            == \"Exception on worker thread. This should let continue the execution registering the failure\"\n        )\n\n    def test_invoke_kwargs(self, project, dbt):\n        res = dbt.invoke(\n            [\"run\"],\n            log_format=\"json\",\n            log_path=\"some_random_path\",\n            version_check=False,\n            profile_name=\"some_random_profile_name\",\n            target_dir=\"some_random_target_dir\",\n        )\n        assert res.result.args[\"log_format\"] == \"json\"\n        assert res.result.args[\"log_path\"] == \"some_random_path\"\n        assert res.result.args[\"version_check\"] is False\n        assert res.result.args[\"profile_name\"] == \"some_random_profile_name\"\n        assert res.result.args[\"target_dir\"] == \"some_random_target_dir\"\n\n    def test_invoke_kwargs_project_dir(self, project, dbt):\n        res = dbt.invoke([\"run\"], project_dir=\"some_random_project_dir\")\n        assert type(res.exception) == DbtProjectError\n\n        msg = \"No dbt_project.yml found at expected path some_random_project_dir\"\n        assert msg in res.exception.msg\n\n    def test_invoke_kwargs_profiles_dir(self, project, dbt):\n        res = dbt.invoke([\"run\"], profiles_dir=\"some_random_profiles_dir\")\n        assert type(res.exception) == DbtProjectError\n        msg = \"Could not find profile named 'test'\"\n        assert msg in res.exception.msg\n\n    def test_invoke_kwargs_and_flags(self, project, dbt):\n        res = dbt.invoke([\"--log-format=text\", \"run\"], log_format=\"json\")\n        assert res.result.args[\"log_format\"] == \"json\"\n\n    def test_pass_in_manifest(self, project, dbt):\n        result = dbt.invoke([\"parse\"])\n        manifest = result.result\n\n        reset_adapters()\n        assert len(FACTORY.adapters) == 0\n        result = dbtRunner(manifest=manifest).invoke([\"run\"])\n        # Check that the adapters are registered again.\n        assert result.success\n        assert len(FACTORY.adapters) == 1\n\n    def test_pass_in_args_variable(self, dbt):\n        args = [\"--log-format\", \"text\"]\n        args_before = args.copy()\n        dbt.invoke(args)\n        assert args == args_before\n\n    def test_directory_does_not_change(self, project, dbt: dbtRunner) -> None:\n        project_dir = os.getcwd()  # The directory where dbt_project.yml exists.\n        os.chdir(\"../\")\n        cmd_execution_dir = os.getcwd()  # The directory where dbt command will be run\n\n        commands = [\"init\", \"deps\", \"clean\"]\n        for command in commands:\n            args = [command, \"--project-dir\", project_dir]\n            if command == \"init\":\n                args.append(\"--skip-profile-setup\")\n            res = dbt.invoke(args)\n            after_dir = os.getcwd()\n            assert res.success is True\n            assert cmd_execution_dir == after_dir\n\n\nclass TestDbtRunnerQueryComments:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"models.sql\": \"select 1 as id\",\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"query-comment\": {\n                \"comment\": f\"comment: {dbt_version}\",\n                \"append\": True,\n            }\n        }\n\n    def test_query_comment_saved_manifest(self, project, logs_dir):\n        dbt = dbtRunner()\n        dbt.invoke([\"build\", \"--select\", \"models\"])\n        result = dbt.invoke([\"parse\"])\n        write_file(\"\", logs_dir, \"dbt.log\")\n        # pass in manifest from parse command\n        dbt = dbtRunner(result.result)\n        dbt.invoke([\"build\", \"--select\", \"models\"])\n        log_file = read_file(logs_dir, \"dbt.log\")\n        assert f\"comment: {dbt_version}\" in log_file\n\n\nclass TestDbtRunnerHooks:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"models.sql\": \"select 1 as id\",\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\"on-run-end\": [\"select 1;\"]}\n\n    def test_node_info_non_persistence(self, project):\n        dbt = dbtRunner()\n        dbt.invoke([\"run\", \"--select\", \"models\"])\n        assert get_node_info() == {}\n"
  },
  {
    "path": "tests/functional/defer_state/data/manifest.json",
    "content": "{\n  \"metadata\": {\n    \"dbt_schema_version\": \"https://schemas.getdbt.com/dbt/manifest/v12.json\",\n    \"dbt_version\": \"PREVIOUS\",\n    \"generated_at\": \"2025-11-19T17:45:05.479140Z\",\n    \"invocation_id\": \"e78f29e3-abf6-480a-a16c-b1f6cca0242e\",\n    \"invocation_started_at\": \"2025-11-19T17:45:05.337658Z\",\n    \"env\": {},\n    \"project_name\": \"test\",\n    \"project_id\": \"098f6bcd4621d373cade4e832627b4f6\",\n    \"user_id\": null,\n    \"send_anonymous_usage_stats\": false,\n    \"adapter_type\": \"postgres\",\n    \"quoting\": {\n      \"database\": true,\n      \"schema\": true,\n      \"identifier\": true,\n      \"column\": null\n    },\n    \"run_started_at\": \"2025-11-19T17:45:05.337822+00:00\"\n  },\n  \"nodes\": {\n    \"model.test.model_with_lots_of_schema_configs\": {\n      \"database\": \"dbt\",\n      \"schema\": \"test17635743055401889788_test_modified_state_schema_evolution_test\",\n      \"name\": \"model_with_lots_of_schema_configs\",\n      \"resource_type\": \"model\",\n      \"package_name\": \"test\",\n      \"path\": \"model_with_lots_of_schema_configs.sql\",\n      \"original_file_path\": \"models/model_with_lots_of_schema_configs.sql\",\n      \"unique_id\": \"model.test.model_with_lots_of_schema_configs\",\n      \"fqn\": [\n        \"test\",\n        \"model_with_lots_of_schema_configs\"\n      ],\n      \"alias\": \"outer_alias\",\n      \"checksum\": {\n        \"name\": \"sha256\",\n        \"checksum\": \"0cb8913f9c7b25d64892882b5f85341353fd6862ae5b2b69df3da19a5bf474f2\"\n      },\n      \"config\": {\n        \"enabled\": true,\n        \"alias\": \"outer_alias\",\n        \"schema\": \"test\",\n        \"database\": \"dbt\",\n        \"tags\": [\n          \"string_tag\"\n        ],\n        \"meta\": {\n          \"my_custom_property\": \"string_meta\"\n        },\n        \"group\": null,\n        \"materialized\": \"table\",\n        \"incremental_strategy\": null,\n        \"batch_size\": \"day\",\n        \"lookback\": 5,\n        \"begin\": \"2020-01-01\",\n        \"persist_docs\": {\n          \"columns\": true,\n          \"relation\": true\n        },\n        \"post-hook\": [\n          {\n            \"sql\": \"SELECT 'string_post_hook' as my_post_hook;\",\n            \"transaction\": true,\n            \"index\": null\n          }\n        ],\n        \"pre-hook\": [\n          {\n            \"sql\": \"SELECT 'string_pre_hook' as my_pre_hook;\",\n            \"transaction\": true,\n            \"index\": null\n          }\n        ],\n        \"quoting\": {},\n        \"column_types\": {},\n        \"full_refresh\": false,\n        \"unique_key\": \"id\",\n        \"on_schema_change\": \"ignore\",\n        \"on_configuration_change\": \"apply\",\n        \"grants\": {\n          \"select\": [\n            \"root\"\n          ]\n        },\n        \"packages\": [],\n        \"docs\": {\n          \"show\": true,\n          \"node_color\": \"purple\"\n        },\n        \"contract\": {\n          \"enforced\": false,\n          \"alias_types\": true\n        },\n        \"event_time\": null,\n        \"concurrent_batches\": false,\n        \"access\": \"public\",\n        \"freshness\": null,\n        \"sql_header\": \"SELECT 1 as header;\"\n      },\n      \"tags\": [\n        \"string_tag\"\n      ],\n      \"description\": \"A model with lots of configs\",\n      \"columns\": {\n        \"id\": {\n          \"name\": \"id\",\n          \"description\": \"The id value\",\n          \"meta\": {\n            \"column_meta\": \"column_meta_value\"\n          },\n          \"data_type\": null,\n          \"constraints\": [],\n          \"quote\": null,\n          \"config\": {\n            \"meta\": {\n              \"column_meta\": \"column_meta_value\"\n            },\n            \"tags\": [\n              \"column_level_tag\"\n            ]\n          },\n          \"tags\": [\n            \"column_level_tag\"\n          ],\n          \"granularity\": null,\n          \"doc_blocks\": []\n        },\n        \"created_at\": {\n          \"name\": \"created_at\",\n          \"description\": \"The date the row was created\",\n          \"meta\": {},\n          \"data_type\": null,\n          \"constraints\": [],\n          \"quote\": null,\n          \"config\": {\n            \"meta\": {},\n            \"tags\": []\n          },\n          \"tags\": [],\n          \"granularity\": null,\n          \"doc_blocks\": []\n        }\n      },\n      \"meta\": {\n        \"my_custom_property\": \"string_meta\"\n      },\n      \"group\": null,\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": \"purple\"\n      },\n      \"patch_path\": \"test://models/schema.yml\",\n      \"build_path\": null,\n      \"unrendered_config\": {\n        \"enabled\": true,\n        \"access\": \"public\",\n        \"alias\": \"outer_alias\",\n        \"batch_size\": \"day\",\n        \"begin\": \"2020-01-01\",\n        \"concurrent_batches\": false,\n        \"contract\": {\n          \"alias_types\": true,\n          \"enforce\": true\n        },\n        \"docs\": {\n          \"node_color\": \"purple\",\n          \"show\": true\n        },\n        \"database\": \"dbt\",\n        \"full_refresh\": false,\n        \"grants\": {\n          \"select\": [\n            \"root\",\n            \"root\"\n          ]\n        },\n        \"lookback\": 5,\n        \"materialized\": \"table\",\n        \"meta\": {\n          \"my_custom_property\": \"string_meta\"\n        },\n        \"on_configuration_change\": \"apply\",\n        \"persist_docs\": {\n          \"columns\": true,\n          \"relation\": true\n        },\n        \"post_hook\": \"SELECT 'string_post_hook' as my_post_hook;\",\n        \"pre_hook\": \"SELECT 'string_pre_hook' as my_pre_hook;\",\n        \"schema\": \"test\",\n        \"sql_header\": \"SELECT 1 as header;\",\n        \"tags\": \"string_tag\",\n        \"unique_key\": \"id\"\n      },\n      \"created_at\": 1763574306.275303,\n      \"relation_name\": \"\\\"dbt\\\".\\\"test17635743055401889788_test_modified_state_schema_evolution_test\\\".\\\"outer_alias\\\"\",\n      \"raw_code\": \"select * from {{ ref('ephemeral') }}\",\n      \"doc_blocks\": [],\n      \"language\": \"sql\",\n      \"refs\": [\n        {\n          \"name\": \"ephemeral\",\n          \"package\": null,\n          \"version\": null\n        }\n      ],\n      \"sources\": [\n        [\n          \"my_source\",\n          \"my_table\"\n        ]\n      ],\n      \"metrics\": [],\n      \"functions\": [],\n      \"depends_on\": {\n        \"macros\": [],\n        \"nodes\": [\n          \"source.test.my_source.my_table\",\n          \"model.test.ephemeral\"\n        ]\n      },\n      \"compiled_path\": null,\n      \"contract\": {\n        \"enforced\": false,\n        \"alias_types\": true,\n        \"checksum\": null\n      },\n      \"access\": \"public\",\n      \"constraints\": [\n        {\n          \"type\": \"primary_key\",\n          \"name\": null,\n          \"expression\": null,\n          \"warn_unenforced\": true,\n          \"warn_unsupported\": false,\n          \"to\": null,\n          \"to_columns\": [],\n          \"columns\": [\n            \"id\"\n          ]\n        },\n        {\n          \"type\": \"foreign_key\",\n          \"name\": null,\n          \"expression\": null,\n          \"warn_unenforced\": true,\n          \"warn_unsupported\": true,\n          \"to\": \"source('my_source', 'my_table')\",\n          \"to_columns\": [\n            \"id\"\n          ],\n          \"columns\": [\n            \"id\"\n          ]\n        },\n        {\n          \"type\": \"check\",\n          \"name\": \"Check that id is greater than 0\",\n          \"expression\": \"id > 0\",\n          \"warn_unenforced\": true,\n          \"warn_unsupported\": true,\n          \"to\": null,\n          \"to_columns\": [],\n          \"columns\": [\n            \"id\"\n          ]\n        }\n      ],\n      \"version\": null,\n      \"latest_version\": null,\n      \"deprecation_date\": \"2052-05-01T00:00:00-04:00\",\n      \"primary_key\": [\n        \"id\"\n      ],\n      \"time_spine\": null\n    },\n    \"model.test.snapshot_source\": {\n      \"database\": \"dbt\",\n      \"schema\": \"test17635743055401889788_test_modified_state_schema_evolution\",\n      \"name\": \"snapshot_source\",\n      \"resource_type\": \"model\",\n      \"package_name\": \"test\",\n      \"path\": \"snapshot_source.sql\",\n      \"original_file_path\": \"models/snapshot_source.sql\",\n      \"unique_id\": \"model.test.snapshot_source\",\n      \"fqn\": [\n        \"test\",\n        \"snapshot_source\"\n      ],\n      \"alias\": \"snapshot_source\",\n      \"checksum\": {\n        \"name\": \"sha256\",\n        \"checksum\": \"0e0757d1f14cdd418b570e1d0206e397b732254483eea28663600385370d3b74\"\n      },\n      \"config\": {\n        \"enabled\": true,\n        \"alias\": null,\n        \"schema\": null,\n        \"database\": null,\n        \"tags\": [],\n        \"meta\": {},\n        \"group\": null,\n        \"materialized\": \"view\",\n        \"incremental_strategy\": null,\n        \"batch_size\": null,\n        \"lookback\": 1,\n        \"begin\": null,\n        \"persist_docs\": {},\n        \"post-hook\": [],\n        \"pre-hook\": [],\n        \"quoting\": {},\n        \"column_types\": {},\n        \"full_refresh\": null,\n        \"unique_key\": null,\n        \"on_schema_change\": \"ignore\",\n        \"on_configuration_change\": \"apply\",\n        \"grants\": {},\n        \"packages\": [],\n        \"docs\": {\n          \"show\": true,\n          \"node_color\": null\n        },\n        \"contract\": {\n          \"enforced\": false,\n          \"alias_types\": true\n        },\n        \"event_time\": null,\n        \"concurrent_batches\": null,\n        \"access\": \"protected\",\n        \"freshness\": null\n      },\n      \"tags\": [],\n      \"description\": \"\",\n      \"columns\": {},\n      \"meta\": {},\n      \"group\": null,\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"build_path\": null,\n      \"unrendered_config\": {\n        \"enabled\": true\n      },\n      \"created_at\": 1763574305.7719748,\n      \"relation_name\": \"\\\"dbt\\\".\\\"test17635743055401889788_test_modified_state_schema_evolution\\\".\\\"snapshot_source\\\"\",\n      \"raw_code\": \"select 0 as id, 1 as col1, 2 as col2, 3 as col3\",\n      \"doc_blocks\": [],\n      \"language\": \"sql\",\n      \"refs\": [],\n      \"sources\": [],\n      \"metrics\": [],\n      \"functions\": [],\n      \"depends_on\": {\n        \"macros\": [],\n        \"nodes\": []\n      },\n      \"compiled_path\": null,\n      \"contract\": {\n        \"enforced\": false,\n        \"alias_types\": true,\n        \"checksum\": null\n      },\n      \"access\": \"protected\",\n      \"constraints\": [],\n      \"version\": null,\n      \"latest_version\": null,\n      \"deprecation_date\": null,\n      \"primary_key\": [],\n      \"time_spine\": null\n    },\n    \"model.test.ephemeral\": {\n      \"database\": \"dbt\",\n      \"schema\": \"test17635743055401889788_test_modified_state_schema_evolution\",\n      \"name\": \"ephemeral\",\n      \"resource_type\": \"model\",\n      \"package_name\": \"test\",\n      \"path\": \"ephemeral.sql\",\n      \"original_file_path\": \"models/ephemeral.sql\",\n      \"unique_id\": \"model.test.ephemeral\",\n      \"fqn\": [\n        \"test\",\n        \"ephemeral\"\n      ],\n      \"alias\": \"ephemeral\",\n      \"checksum\": {\n        \"name\": \"sha256\",\n        \"checksum\": \"3cd361ea49139705c81325d9312d7a959b9afa7144d06fd04ea575ee3abd7467\"\n      },\n      \"config\": {\n        \"enabled\": true,\n        \"alias\": null,\n        \"schema\": null,\n        \"database\": null,\n        \"tags\": [],\n        \"meta\": {},\n        \"group\": null,\n        \"materialized\": \"ephemeral\",\n        \"incremental_strategy\": null,\n        \"batch_size\": null,\n        \"lookback\": 1,\n        \"begin\": null,\n        \"persist_docs\": {},\n        \"post-hook\": [],\n        \"pre-hook\": [],\n        \"quoting\": {},\n        \"column_types\": {},\n        \"full_refresh\": null,\n        \"unique_key\": null,\n        \"on_schema_change\": \"ignore\",\n        \"on_configuration_change\": \"apply\",\n        \"grants\": {},\n        \"packages\": [],\n        \"docs\": {\n          \"show\": true,\n          \"node_color\": null\n        },\n        \"contract\": {\n          \"enforced\": false,\n          \"alias_types\": true\n        },\n        \"event_time\": null,\n        \"concurrent_batches\": null,\n        \"access\": \"protected\",\n        \"freshness\": null\n      },\n      \"tags\": [],\n      \"description\": \"\",\n      \"columns\": {},\n      \"meta\": {},\n      \"group\": null,\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"build_path\": null,\n      \"unrendered_config\": {\n        \"enabled\": true,\n        \"materialized\": \"Keyword(key='materialized', value=Const(value='ephemeral'))\"\n      },\n      \"created_at\": 1763574305.772938,\n      \"relation_name\": null,\n      \"raw_code\": \"{{ config(materialized='ephemeral') }}\\n\\nselect\\n  1 as id,\\n  {{ dbt.date_trunc('day', dbt.current_timestamp()) }} as created_at\",\n      \"doc_blocks\": [],\n      \"language\": \"sql\",\n      \"refs\": [],\n      \"sources\": [],\n      \"metrics\": [],\n      \"functions\": [],\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.current_timestamp\",\n          \"macro.dbt.date_trunc\"\n        ],\n        \"nodes\": []\n      },\n      \"compiled_path\": null,\n      \"contract\": {\n        \"enforced\": false,\n        \"alias_types\": true,\n        \"checksum\": null\n      },\n      \"access\": \"protected\",\n      \"constraints\": [],\n      \"version\": null,\n      \"latest_version\": null,\n      \"deprecation_date\": null,\n      \"primary_key\": [],\n      \"time_spine\": null\n    },\n    \"model.test.metricflow_time_spine\": {\n      \"database\": \"dbt\",\n      \"schema\": \"test17635743055401889788_test_modified_state_schema_evolution\",\n      \"name\": \"metricflow_time_spine\",\n      \"resource_type\": \"model\",\n      \"package_name\": \"test\",\n      \"path\": \"metricflow_time_spine.sql\",\n      \"original_file_path\": \"models/metricflow_time_spine.sql\",\n      \"unique_id\": \"model.test.metricflow_time_spine\",\n      \"fqn\": [\n        \"test\",\n        \"metricflow_time_spine\"\n      ],\n      \"alias\": \"metricflow_time_spine\",\n      \"checksum\": {\n        \"name\": \"sha256\",\n        \"checksum\": \"dc614982c2a9f37c6a0db29f72c795e9b04b36edd4130b293c0237835c05c163\"\n      },\n      \"config\": {\n        \"enabled\": true,\n        \"alias\": null,\n        \"schema\": null,\n        \"database\": null,\n        \"tags\": [\n          \"list\",\n          \"of\",\n          \"tags\"\n        ],\n        \"meta\": {},\n        \"group\": \"finance\",\n        \"materialized\": \"view\",\n        \"incremental_strategy\": null,\n        \"batch_size\": null,\n        \"lookback\": 1,\n        \"begin\": null,\n        \"persist_docs\": {},\n        \"post-hook\": [\n          {\n            \"sql\": \"SELECT 'string_post_hook' as my_post_hook;\",\n            \"transaction\": true,\n            \"index\": null\n          }\n        ],\n        \"pre-hook\": [\n          {\n            \"sql\": \"SELECT 'string_pre_hook' as my_pre_hook;\",\n            \"transaction\": true,\n            \"index\": null\n          }\n        ],\n        \"quoting\": {},\n        \"column_types\": {},\n        \"full_refresh\": null,\n        \"unique_key\": null,\n        \"on_schema_change\": \"ignore\",\n        \"on_configuration_change\": \"apply\",\n        \"grants\": {},\n        \"packages\": [],\n        \"docs\": {\n          \"show\": true,\n          \"node_color\": null\n        },\n        \"contract\": {\n          \"enforced\": false,\n          \"alias_types\": true\n        },\n        \"event_time\": null,\n        \"concurrent_batches\": null,\n        \"access\": \"protected\",\n        \"freshness\": null\n      },\n      \"tags\": [\n        \"list\",\n        \"of\",\n        \"tags\"\n      ],\n      \"description\": \"Day time spine\",\n      \"columns\": {\n        \"date_day\": {\n          \"name\": \"date_day\",\n          \"description\": \"\",\n          \"meta\": {},\n          \"data_type\": null,\n          \"constraints\": [],\n          \"quote\": null,\n          \"config\": {\n            \"meta\": {},\n            \"tags\": []\n          },\n          \"tags\": [],\n          \"granularity\": \"day\",\n          \"doc_blocks\": []\n        }\n      },\n      \"meta\": {},\n      \"group\": \"finance\",\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": \"test://models/schema.yml\",\n      \"build_path\": null,\n      \"unrendered_config\": {\n        \"enabled\": true,\n        \"tags\": [\n          \"list\",\n          \"of\",\n          \"tags\",\n          \"list\",\n          \"of\",\n          \"tags\"\n        ],\n        \"pre_hook\": [\n          \"SELECT 'string_pre_hook' as my_pre_hook;\",\n          \"SELECT 'string_pre_hook' as my_pre_hook;\"\n        ],\n        \"post_hook\": [\n          \"SELECT 'string_post_hook' as my_post_hook;\",\n          \"SELECT 'string_post_hook' as my_post_hook;\"\n        ],\n        \"group\": \"finance\"\n      },\n      \"created_at\": 1763574306.268285,\n      \"relation_name\": \"\\\"dbt\\\".\\\"test17635743055401889788_test_modified_state_schema_evolution\\\".\\\"metricflow_time_spine\\\"\",\n      \"raw_code\": \"select\\n  {{ dbt.date_trunc('day', dbt.current_timestamp()) }} as date_day\",\n      \"doc_blocks\": [],\n      \"language\": \"sql\",\n      \"refs\": [],\n      \"sources\": [],\n      \"metrics\": [],\n      \"functions\": [],\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.current_timestamp\",\n          \"macro.dbt.date_trunc\"\n        ],\n        \"nodes\": []\n      },\n      \"compiled_path\": null,\n      \"contract\": {\n        \"enforced\": false,\n        \"alias_types\": true,\n        \"checksum\": null\n      },\n      \"access\": \"protected\",\n      \"constraints\": [],\n      \"version\": null,\n      \"latest_version\": null,\n      \"deprecation_date\": null,\n      \"primary_key\": [],\n      \"time_spine\": {\n        \"standard_granularity_column\": \"date_day\",\n        \"custom_granularities\": []\n      }\n    },\n    \"model.test.incremental\": {\n      \"database\": \"dbt\",\n      \"schema\": \"test17635743055401889788_test_modified_state_schema_evolution\",\n      \"name\": \"incremental\",\n      \"resource_type\": \"model\",\n      \"package_name\": \"test\",\n      \"path\": \"incremental.sql\",\n      \"original_file_path\": \"models/incremental.sql\",\n      \"unique_id\": \"model.test.incremental\",\n      \"fqn\": [\n        \"test\",\n        \"incremental\"\n      ],\n      \"alias\": \"incremental\",\n      \"checksum\": {\n        \"name\": \"sha256\",\n        \"checksum\": \"cc19247f485dc040e2ab4b141f6e01b07e2d9a4e133f74e3cb19e235f8d73297\"\n      },\n      \"config\": {\n        \"enabled\": true,\n        \"alias\": null,\n        \"schema\": null,\n        \"database\": null,\n        \"tags\": [],\n        \"meta\": {},\n        \"group\": null,\n        \"materialized\": \"incremental\",\n        \"incremental_strategy\": \"delete+insert\",\n        \"batch_size\": null,\n        \"lookback\": 1,\n        \"begin\": null,\n        \"persist_docs\": {},\n        \"post-hook\": [],\n        \"pre-hook\": [],\n        \"quoting\": {},\n        \"column_types\": {},\n        \"full_refresh\": null,\n        \"unique_key\": null,\n        \"on_schema_change\": \"ignore\",\n        \"on_configuration_change\": \"apply\",\n        \"grants\": {},\n        \"packages\": [],\n        \"docs\": {\n          \"show\": true,\n          \"node_color\": null\n        },\n        \"contract\": {\n          \"enforced\": false,\n          \"alias_types\": true\n        },\n        \"event_time\": null,\n        \"concurrent_batches\": null,\n        \"access\": \"protected\",\n        \"freshness\": null\n      },\n      \"tags\": [],\n      \"description\": \"\",\n      \"columns\": {},\n      \"meta\": {},\n      \"group\": null,\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"build_path\": null,\n      \"unrendered_config\": {\n        \"enabled\": true,\n        \"materialized\": \"Keyword(key='materialized', value=Const(value='incremental'))\",\n        \"incremental_strategy\": \"Keyword(key='incremental_strategy', value=Const(value='delete+insert'))\"\n      },\n      \"created_at\": 1763574305.783703,\n      \"relation_name\": \"\\\"dbt\\\".\\\"test17635743055401889788_test_modified_state_schema_evolution\\\".\\\"incremental\\\"\",\n      \"raw_code\": \"{{\\n  config(\\n    materialized = \\\"incremental\\\",\\n    incremental_strategy = \\\"delete+insert\\\",\\n  )\\n}}\\n\\nselect * from {{ ref('seed') }}\\n\\n{% if is_incremental() %}\\n    where a > (select max(a) from {{this}})\\n{% endif %}\",\n      \"doc_blocks\": [],\n      \"language\": \"sql\",\n      \"refs\": [\n        {\n          \"name\": \"seed\",\n          \"package\": null,\n          \"version\": null\n        }\n      ],\n      \"sources\": [],\n      \"metrics\": [],\n      \"functions\": [],\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.is_incremental\"\n        ],\n        \"nodes\": [\n          \"seed.test.seed\"\n        ]\n      },\n      \"compiled_path\": null,\n      \"contract\": {\n        \"enforced\": false,\n        \"alias_types\": true,\n        \"checksum\": null\n      },\n      \"access\": \"protected\",\n      \"constraints\": [],\n      \"version\": null,\n      \"latest_version\": null,\n      \"deprecation_date\": null,\n      \"primary_key\": [],\n      \"time_spine\": null\n    },\n    \"model.test.model_to_unit_test\": {\n      \"database\": \"dbt\",\n      \"schema\": \"test17635743055401889788_test_modified_state_schema_evolution\",\n      \"name\": \"model_to_unit_test\",\n      \"resource_type\": \"model\",\n      \"package_name\": \"test\",\n      \"path\": \"model_to_unit_test.sql\",\n      \"original_file_path\": \"models/model_to_unit_test.sql\",\n      \"unique_id\": \"model.test.model_to_unit_test\",\n      \"fqn\": [\n        \"test\",\n        \"model_to_unit_test\"\n      ],\n      \"alias\": \"model_to_unit_test\",\n      \"checksum\": {\n        \"name\": \"sha256\",\n        \"checksum\": \"480d7b0969f63e01b8aa3355cd6b52043c81d0570f5f9a04bd4ffc124413cd43\"\n      },\n      \"config\": {\n        \"enabled\": true,\n        \"alias\": null,\n        \"schema\": null,\n        \"database\": null,\n        \"tags\": [],\n        \"meta\": {},\n        \"group\": null,\n        \"materialized\": \"table\",\n        \"incremental_strategy\": null,\n        \"batch_size\": null,\n        \"lookback\": 1,\n        \"begin\": null,\n        \"persist_docs\": {},\n        \"post-hook\": [],\n        \"pre-hook\": [],\n        \"quoting\": {},\n        \"column_types\": {},\n        \"full_refresh\": null,\n        \"unique_key\": null,\n        \"on_schema_change\": \"ignore\",\n        \"on_configuration_change\": \"apply\",\n        \"grants\": {},\n        \"packages\": [],\n        \"docs\": {\n          \"show\": true,\n          \"node_color\": null\n        },\n        \"contract\": {\n          \"enforced\": false,\n          \"alias_types\": true\n        },\n        \"event_time\": null,\n        \"concurrent_batches\": null,\n        \"access\": \"protected\",\n        \"freshness\": null\n      },\n      \"tags\": [],\n      \"description\": \"\",\n      \"columns\": {},\n      \"meta\": {},\n      \"group\": null,\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"build_path\": null,\n      \"unrendered_config\": {\n        \"enabled\": true,\n        \"materialized\": \"table\"\n      },\n      \"created_at\": 1763574305.787908,\n      \"relation_name\": \"\\\"dbt\\\".\\\"test17635743055401889788_test_modified_state_schema_evolution\\\".\\\"model_to_unit_test\\\"\",\n      \"raw_code\": \"{{ config(materialized='table') }}\\n\\nSELECT * FROM {{ ref('seed')}}\",\n      \"doc_blocks\": [],\n      \"language\": \"sql\",\n      \"refs\": [\n        {\n          \"name\": \"seed\",\n          \"package\": null,\n          \"version\": null\n        }\n      ],\n      \"sources\": [],\n      \"metrics\": [],\n      \"functions\": [],\n      \"depends_on\": {\n        \"macros\": [],\n        \"nodes\": [\n          \"seed.test.seed\"\n        ]\n      },\n      \"compiled_path\": null,\n      \"contract\": {\n        \"enforced\": false,\n        \"alias_types\": true,\n        \"checksum\": null\n      },\n      \"access\": \"protected\",\n      \"constraints\": [],\n      \"version\": null,\n      \"latest_version\": null,\n      \"deprecation_date\": null,\n      \"primary_key\": [],\n      \"time_spine\": null\n    },\n    \"model.test.outer\": {\n      \"database\": \"dbt\",\n      \"schema\": \"test17635743055401889788_test_modified_state_schema_evolution\",\n      \"name\": \"outer\",\n      \"resource_type\": \"model\",\n      \"package_name\": \"test\",\n      \"path\": \"outer.sql\",\n      \"original_file_path\": \"models/outer.sql\",\n      \"unique_id\": \"model.test.outer\",\n      \"fqn\": [\n        \"test\",\n        \"outer\"\n      ],\n      \"alias\": \"outer\",\n      \"checksum\": {\n        \"name\": \"sha256\",\n        \"checksum\": \"0cb8913f9c7b25d64892882b5f85341353fd6862ae5b2b69df3da19a5bf474f2\"\n      },\n      \"config\": {\n        \"enabled\": true,\n        \"alias\": null,\n        \"schema\": null,\n        \"database\": null,\n        \"tags\": [],\n        \"meta\": {},\n        \"group\": null,\n        \"materialized\": \"view\",\n        \"incremental_strategy\": null,\n        \"batch_size\": null,\n        \"lookback\": 1,\n        \"begin\": null,\n        \"persist_docs\": {},\n        \"post-hook\": [],\n        \"pre-hook\": [],\n        \"quoting\": {},\n        \"column_types\": {},\n        \"full_refresh\": null,\n        \"unique_key\": null,\n        \"on_schema_change\": \"ignore\",\n        \"on_configuration_change\": \"apply\",\n        \"grants\": {},\n        \"packages\": [],\n        \"docs\": {\n          \"show\": true,\n          \"node_color\": null\n        },\n        \"contract\": {\n          \"enforced\": false,\n          \"alias_types\": true\n        },\n        \"event_time\": null,\n        \"concurrent_batches\": null,\n        \"access\": \"protected\",\n        \"freshness\": null\n      },\n      \"tags\": [],\n      \"description\": \"The outer table\",\n      \"columns\": {\n        \"id\": {\n          \"name\": \"id\",\n          \"description\": \"The id value\",\n          \"meta\": {},\n          \"data_type\": null,\n          \"constraints\": [],\n          \"quote\": null,\n          \"config\": {\n            \"meta\": {},\n            \"tags\": []\n          },\n          \"tags\": [],\n          \"granularity\": null,\n          \"doc_blocks\": []\n        }\n      },\n      \"meta\": {},\n      \"group\": null,\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": \"test://models/schema.yml\",\n      \"build_path\": null,\n      \"unrendered_config\": {\n        \"enabled\": true\n      },\n      \"created_at\": 1763574306.265461,\n      \"relation_name\": \"\\\"dbt\\\".\\\"test17635743055401889788_test_modified_state_schema_evolution\\\".\\\"outer\\\"\",\n      \"raw_code\": \"select * from {{ ref('ephemeral') }}\",\n      \"doc_blocks\": [],\n      \"language\": \"sql\",\n      \"refs\": [\n        {\n          \"name\": \"ephemeral\",\n          \"package\": null,\n          \"version\": null\n        }\n      ],\n      \"sources\": [],\n      \"metrics\": [],\n      \"functions\": [],\n      \"depends_on\": {\n        \"macros\": [],\n        \"nodes\": [\n          \"model.test.ephemeral\"\n        ]\n      },\n      \"compiled_path\": null,\n      \"contract\": {\n        \"enforced\": false,\n        \"alias_types\": true,\n        \"checksum\": null\n      },\n      \"access\": \"protected\",\n      \"constraints\": [],\n      \"version\": null,\n      \"latest_version\": null,\n      \"deprecation_date\": null,\n      \"primary_key\": [\n        \"id\"\n      ],\n      \"time_spine\": null\n    },\n    \"model.test.metricflow_time_spine_second\": {\n      \"database\": \"dbt\",\n      \"schema\": \"test17635743055401889788_test_modified_state_schema_evolution\",\n      \"name\": \"metricflow_time_spine_second\",\n      \"resource_type\": \"model\",\n      \"package_name\": \"test\",\n      \"path\": \"metricflow_time_spine_second.sql\",\n      \"original_file_path\": \"models/metricflow_time_spine_second.sql\",\n      \"unique_id\": \"model.test.metricflow_time_spine_second\",\n      \"fqn\": [\n        \"test\",\n        \"metricflow_time_spine_second\"\n      ],\n      \"alias\": \"metricflow_time_spine_second\",\n      \"checksum\": {\n        \"name\": \"sha256\",\n        \"checksum\": \"7b2cca2e77552af42f8fd890f2c271bd8b462b9c04f138f39c59cb2d4aa6a2fb\"\n      },\n      \"config\": {\n        \"enabled\": true,\n        \"alias\": null,\n        \"schema\": null,\n        \"database\": null,\n        \"tags\": [],\n        \"meta\": {},\n        \"group\": null,\n        \"materialized\": \"view\",\n        \"incremental_strategy\": null,\n        \"batch_size\": null,\n        \"lookback\": 1,\n        \"begin\": null,\n        \"persist_docs\": {},\n        \"post-hook\": [],\n        \"pre-hook\": [],\n        \"quoting\": {},\n        \"column_types\": {},\n        \"full_refresh\": null,\n        \"unique_key\": null,\n        \"on_schema_change\": \"ignore\",\n        \"on_configuration_change\": \"apply\",\n        \"grants\": {},\n        \"packages\": [],\n        \"docs\": {\n          \"show\": true,\n          \"node_color\": null\n        },\n        \"contract\": {\n          \"enforced\": false,\n          \"alias_types\": true\n        },\n        \"event_time\": \"ts_second\",\n        \"concurrent_batches\": null,\n        \"access\": \"protected\",\n        \"freshness\": null\n      },\n      \"tags\": [],\n      \"description\": \"Second time spine\",\n      \"columns\": {\n        \"ts_second\": {\n          \"name\": \"ts_second\",\n          \"description\": \"\",\n          \"meta\": {},\n          \"data_type\": null,\n          \"constraints\": [],\n          \"quote\": null,\n          \"config\": {\n            \"meta\": {},\n            \"tags\": []\n          },\n          \"tags\": [],\n          \"granularity\": \"second\",\n          \"doc_blocks\": []\n        }\n      },\n      \"meta\": {},\n      \"group\": null,\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": \"test://models/schema.yml\",\n      \"build_path\": null,\n      \"unrendered_config\": {\n        \"enabled\": true,\n        \"event_time\": \"ts_second\"\n      },\n      \"created_at\": 1763574306.269429,\n      \"relation_name\": \"\\\"dbt\\\".\\\"test17635743055401889788_test_modified_state_schema_evolution\\\".\\\"metricflow_time_spine_second\\\"\",\n      \"raw_code\": \"select\\n  {{ dbt.date_trunc('second', dbt.current_timestamp()) }} as ts_second\",\n      \"doc_blocks\": [],\n      \"language\": \"sql\",\n      \"refs\": [],\n      \"sources\": [],\n      \"metrics\": [],\n      \"functions\": [],\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.current_timestamp\",\n          \"macro.dbt.date_trunc\"\n        ],\n        \"nodes\": []\n      },\n      \"compiled_path\": null,\n      \"contract\": {\n        \"enforced\": false,\n        \"alias_types\": true,\n        \"checksum\": null\n      },\n      \"access\": \"protected\",\n      \"constraints\": [],\n      \"version\": null,\n      \"latest_version\": null,\n      \"deprecation_date\": null,\n      \"primary_key\": [],\n      \"time_spine\": null\n    },\n    \"model.test.inner\": {\n      \"database\": \"dbt\",\n      \"schema\": \"test17635743055401889788_test_modified_state_schema_evolution\",\n      \"name\": \"inner\",\n      \"resource_type\": \"model\",\n      \"package_name\": \"test\",\n      \"path\": \"sub/inner.sql\",\n      \"original_file_path\": \"models/sub/inner.sql\",\n      \"unique_id\": \"model.test.inner\",\n      \"fqn\": [\n        \"test\",\n        \"sub\",\n        \"inner\"\n      ],\n      \"alias\": \"inner\",\n      \"checksum\": {\n        \"name\": \"sha256\",\n        \"checksum\": \"61c1448ee04b0ef968040b9ff7724bd19419bb3af70761211289ee7f53993cb5\"\n      },\n      \"config\": {\n        \"enabled\": true,\n        \"alias\": null,\n        \"schema\": null,\n        \"database\": null,\n        \"tags\": [],\n        \"meta\": {},\n        \"group\": null,\n        \"materialized\": \"view\",\n        \"incremental_strategy\": null,\n        \"batch_size\": null,\n        \"lookback\": 1,\n        \"begin\": null,\n        \"persist_docs\": {},\n        \"post-hook\": [],\n        \"pre-hook\": [],\n        \"quoting\": {},\n        \"column_types\": {},\n        \"full_refresh\": null,\n        \"unique_key\": null,\n        \"on_schema_change\": \"ignore\",\n        \"on_configuration_change\": \"apply\",\n        \"grants\": {},\n        \"packages\": [],\n        \"docs\": {\n          \"show\": true,\n          \"node_color\": null\n        },\n        \"contract\": {\n          \"enforced\": false,\n          \"alias_types\": true\n        },\n        \"event_time\": null,\n        \"concurrent_batches\": null,\n        \"access\": \"protected\",\n        \"freshness\": null\n      },\n      \"tags\": [],\n      \"description\": \"\",\n      \"columns\": {},\n      \"meta\": {},\n      \"group\": null,\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"build_path\": null,\n      \"unrendered_config\": {\n        \"enabled\": true\n      },\n      \"created_at\": 1763574305.792904,\n      \"relation_name\": \"\\\"dbt\\\".\\\"test17635743055401889788_test_modified_state_schema_evolution\\\".\\\"inner\\\"\",\n      \"raw_code\": \"select * from {{ ref('outer') }}\",\n      \"doc_blocks\": [],\n      \"language\": \"sql\",\n      \"refs\": [\n        {\n          \"name\": \"outer\",\n          \"package\": null,\n          \"version\": null\n        }\n      ],\n      \"sources\": [],\n      \"metrics\": [],\n      \"functions\": [],\n      \"depends_on\": {\n        \"macros\": [],\n        \"nodes\": [\n          \"model.test.outer\"\n        ]\n      },\n      \"compiled_path\": null,\n      \"contract\": {\n        \"enforced\": false,\n        \"alias_types\": true,\n        \"checksum\": null\n      },\n      \"access\": \"protected\",\n      \"constraints\": [],\n      \"version\": null,\n      \"latest_version\": null,\n      \"deprecation_date\": null,\n      \"primary_key\": [],\n      \"time_spine\": null\n    },\n    \"snapshot.test.my_snapshot\": {\n      \"database\": \"dbt\",\n      \"schema\": \"test17635743055401889788_test_modified_state_schema_evolution_test17635743055401889788_test_modified_state_schema_evolution\",\n      \"name\": \"my_snapshot\",\n      \"resource_type\": \"snapshot\",\n      \"package_name\": \"test\",\n      \"path\": \"snapshot.sql\",\n      \"original_file_path\": \"snapshots/snapshot.sql\",\n      \"unique_id\": \"snapshot.test.my_snapshot\",\n      \"fqn\": [\n        \"test\",\n        \"snapshot\",\n        \"my_snapshot\"\n      ],\n      \"alias\": \"my_snapshot\",\n      \"checksum\": {\n        \"name\": \"sha256\",\n        \"checksum\": \"a13f80cecda78dbbcada4125f66e98de708321d6ca0765f2023e046a8679ed0f\"\n      },\n      \"config\": {\n        \"enabled\": true,\n        \"alias\": null,\n        \"schema\": \"test17635743055401889788_test_modified_state_schema_evolution\",\n        \"database\": \"dbt\",\n        \"tags\": [],\n        \"meta\": {},\n        \"group\": null,\n        \"materialized\": \"snapshot\",\n        \"incremental_strategy\": null,\n        \"batch_size\": null,\n        \"lookback\": 1,\n        \"begin\": null,\n        \"persist_docs\": {},\n        \"post-hook\": [],\n        \"pre-hook\": [],\n        \"quoting\": {},\n        \"column_types\": {},\n        \"full_refresh\": null,\n        \"unique_key\": \"id\",\n        \"on_schema_change\": \"ignore\",\n        \"on_configuration_change\": \"apply\",\n        \"grants\": {},\n        \"packages\": [],\n        \"docs\": {\n          \"show\": true,\n          \"node_color\": null\n        },\n        \"contract\": {\n          \"enforced\": false,\n          \"alias_types\": true\n        },\n        \"event_time\": null,\n        \"concurrent_batches\": null,\n        \"strategy\": \"timestamp\",\n        \"target_schema\": null,\n        \"target_database\": null,\n        \"updated_at\": \"updated_at\",\n        \"check_cols\": null,\n        \"snapshot_meta_column_names\": {\n          \"dbt_valid_to\": null,\n          \"dbt_valid_from\": null,\n          \"dbt_scd_id\": null,\n          \"dbt_updated_at\": null,\n          \"dbt_is_deleted\": null\n        },\n        \"dbt_valid_to_current\": null\n      },\n      \"tags\": [],\n      \"description\": \"\",\n      \"columns\": {},\n      \"meta\": {},\n      \"group\": null,\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"build_path\": null,\n      \"unrendered_config\": {\n        \"database\": \"Keyword(key='database', value=Call(node=Name(name='var', ctx='load'), args=[Const(value='target_database'), Name(name='database', ctx='load')], kwargs=[], dyn_args=None, dyn_kwargs=None))\",\n        \"schema\": \"Keyword(key='schema', value=Name(name='schema', ctx='load'))\",\n        \"unique_key\": \"Keyword(key='unique_key', value=Const(value='id'))\",\n        \"strategy\": \"Keyword(key='strategy', value=Const(value='timestamp'))\",\n        \"updated_at\": \"Keyword(key='updated_at', value=Const(value='updated_at'))\"\n      },\n      \"created_at\": 1763574305.874798,\n      \"relation_name\": \"\\\"dbt\\\".\\\"test17635743055401889788_test_modified_state_schema_evolution_test17635743055401889788_test_modified_state_schema_evolution\\\".\\\"my_snapshot\\\"\",\n      \"raw_code\": \"\\n    {{\\n        config(\\n            database=var('target_database', database),\\n            schema=schema,\\n            unique_key='id',\\n            strategy='timestamp',\\n            updated_at='updated_at',\\n        )\\n    }}\\n    select * from {{database}}.{{schema}}.seed\\n\",\n      \"doc_blocks\": [],\n      \"language\": \"sql\",\n      \"refs\": [],\n      \"sources\": [],\n      \"metrics\": [],\n      \"functions\": [],\n      \"depends_on\": {\n        \"macros\": [],\n        \"nodes\": []\n      },\n      \"compiled_path\": null,\n      \"contract\": {\n        \"enforced\": false,\n        \"alias_types\": true,\n        \"checksum\": null\n      }\n    },\n    \"analysis.test.a\": {\n      \"database\": \"dbt\",\n      \"schema\": \"test17635743055401889788_test_modified_state_schema_evolution\",\n      \"name\": \"a\",\n      \"resource_type\": \"analysis\",\n      \"package_name\": \"test\",\n      \"path\": \"analysis/a.sql\",\n      \"original_file_path\": \"analyses/a.sql\",\n      \"unique_id\": \"analysis.test.a\",\n      \"fqn\": [\n        \"test\",\n        \"analysis\",\n        \"a\"\n      ],\n      \"alias\": \"a\",\n      \"checksum\": {\n        \"name\": \"sha256\",\n        \"checksum\": \"a389c282f569f0bbdc2a8a4f174dea746c28582fdaf2048d31d9226af9feab23\"\n      },\n      \"config\": {\n        \"enabled\": true,\n        \"alias\": null,\n        \"schema\": null,\n        \"database\": null,\n        \"tags\": [\n          \"tag\"\n        ],\n        \"meta\": {\n          \"test\": 1\n        },\n        \"group\": \"finance\",\n        \"materialized\": \"view\",\n        \"incremental_strategy\": null,\n        \"batch_size\": null,\n        \"lookback\": 1,\n        \"begin\": null,\n        \"persist_docs\": {},\n        \"post-hook\": [],\n        \"pre-hook\": [],\n        \"quoting\": {},\n        \"column_types\": {},\n        \"full_refresh\": null,\n        \"unique_key\": null,\n        \"on_schema_change\": \"ignore\",\n        \"on_configuration_change\": \"apply\",\n        \"grants\": {},\n        \"packages\": [],\n        \"docs\": {\n          \"show\": true,\n          \"node_color\": \"purple\"\n        },\n        \"contract\": {\n          \"enforced\": false,\n          \"alias_types\": true\n        },\n        \"event_time\": null,\n        \"concurrent_batches\": null\n      },\n      \"tags\": [\n        \"tag\"\n      ],\n      \"description\": \"description\",\n      \"columns\": {\n        \"id\": {\n          \"name\": \"id\",\n          \"description\": \"id description\",\n          \"meta\": {},\n          \"data_type\": null,\n          \"constraints\": [],\n          \"quote\": null,\n          \"config\": {\n            \"meta\": {},\n            \"tags\": []\n          },\n          \"tags\": [],\n          \"granularity\": null,\n          \"doc_blocks\": []\n        }\n      },\n      \"meta\": {\n        \"test\": 1\n      },\n      \"group\": \"finance\",\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": \"purple\"\n      },\n      \"patch_path\": \"test://analyses/a.yml\",\n      \"build_path\": null,\n      \"unrendered_config\": {\n        \"enabled\": true,\n        \"tags\": [\n          \"tag\",\n          \"tag\"\n        ],\n        \"meta\": {\n          \"test\": 1\n        },\n        \"docs\": {\n          \"show\": true,\n          \"node_color\": \"purple\"\n        },\n        \"group\": \"finance\"\n      },\n      \"created_at\": 1763574306.459871,\n      \"relation_name\": null,\n      \"raw_code\": \"select 4 as id\",\n      \"doc_blocks\": [],\n      \"language\": \"sql\",\n      \"refs\": [],\n      \"sources\": [],\n      \"metrics\": [],\n      \"functions\": [],\n      \"depends_on\": {\n        \"macros\": [],\n        \"nodes\": []\n      },\n      \"compiled_path\": null,\n      \"contract\": {\n        \"enforced\": false,\n        \"alias_types\": true,\n        \"checksum\": null\n      }\n    },\n    \"test.test.t\": {\n      \"database\": \"dbt\",\n      \"schema\": \"test17635743055401889788_test_modified_state_schema_evolution_dbt_test__audit\",\n      \"name\": \"t\",\n      \"resource_type\": \"test\",\n      \"package_name\": \"test\",\n      \"path\": \"t.sql\",\n      \"original_file_path\": \"tests/t.sql\",\n      \"unique_id\": \"test.test.t\",\n      \"fqn\": [\n        \"test\",\n        \"t\"\n      ],\n      \"alias\": \"test_alias\",\n      \"checksum\": {\n        \"name\": \"sha256\",\n        \"checksum\": \"26307df23d5d989e0b3bcc6c6079c1f2060a9b831945c7898678d18b0b6257c7\"\n      },\n      \"config\": {\n        \"enabled\": true,\n        \"alias\": \"test_alias\",\n        \"schema\": \"dbt_test__audit\",\n        \"database\": \"dbt\",\n        \"tags\": [\n          \"test_tag\"\n        ],\n        \"meta\": {\n          \"my_custom_meta_key\": \"my_custom_meta_value\"\n        },\n        \"group\": \"important_tests\",\n        \"materialized\": \"test\",\n        \"severity\": \"warn\",\n        \"store_failures\": true,\n        \"store_failures_as\": \"table\",\n        \"where\": \"1 = 1\",\n        \"limit\": 10,\n        \"fail_calc\": \"count(*)\",\n        \"warn_if\": \"!= 0\",\n        \"error_if\": \"!= 0\"\n      },\n      \"tags\": [\n        \"test_tag\"\n      ],\n      \"description\": \"Single Data Test in happy path fixture\",\n      \"columns\": {},\n      \"meta\": {\n        \"my_custom_meta_key\": \"my_custom_meta_value\"\n      },\n      \"group\": \"important_tests\",\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": \"test://tests/schema.yml\",\n      \"build_path\": null,\n      \"unrendered_config\": {\n        \"alias\": \"test_alias\",\n        \"database\": \"dbt\",\n        \"group\": \"important_tests\",\n        \"enabled\": true,\n        \"error_if\": \"!= 0\",\n        \"fail_calc\": \"count(*)\",\n        \"limit\": 10,\n        \"meta\": {\n          \"my_custom_meta_key\": \"my_custom_meta_value\"\n        },\n        \"schema\": \"dbt_test__audit\",\n        \"severity\": \"warn\",\n        \"store_failures\": true,\n        \"store_failures_as\": \"table\",\n        \"tags\": [\n          \"test_tag\"\n        ],\n        \"warn_if\": \"!= 0\",\n        \"where\": \"1 = 1\"\n      },\n      \"created_at\": 1763574306.435062,\n      \"relation_name\": \"\\\"dbt\\\".\\\"test17635743055401889788_test_modified_state_schema_evolution_dbt_test__audit\\\".\\\"test_alias\\\"\",\n      \"raw_code\": \"select 1 as id WHERE 1 = 2\",\n      \"doc_blocks\": [],\n      \"language\": \"sql\",\n      \"refs\": [],\n      \"sources\": [],\n      \"metrics\": [],\n      \"functions\": [],\n      \"depends_on\": {\n        \"macros\": [],\n        \"nodes\": []\n      },\n      \"compiled_path\": null,\n      \"contract\": {\n        \"enforced\": false,\n        \"alias_types\": true,\n        \"checksum\": null\n      }\n    },\n    \"seed.test.seed\": {\n      \"database\": \"dbt\",\n      \"schema\": \"test17635743055401889788_test_modified_state_schema_evolution_test\",\n      \"name\": \"seed\",\n      \"resource_type\": \"seed\",\n      \"package_name\": \"test\",\n      \"path\": \"seed.csv\",\n      \"original_file_path\": \"seeds/seed.csv\",\n      \"unique_id\": \"seed.test.seed\",\n      \"fqn\": [\n        \"test\",\n        \"seed\"\n      ],\n      \"alias\": \"test_alias\",\n      \"checksum\": {\n        \"name\": \"sha256\",\n        \"checksum\": \"aeedab1ee7a1043753c9ab768594bc8420d7b85491d0be9421edc3813c237f4c\"\n      },\n      \"config\": {\n        \"enabled\": true,\n        \"alias\": \"test_alias\",\n        \"schema\": \"test\",\n        \"database\": \"dbt\",\n        \"tags\": [\n          \"tag\"\n        ],\n        \"meta\": {\n          \"meta_key\": \"meta_value\"\n        },\n        \"group\": \"finance\",\n        \"materialized\": \"seed\",\n        \"incremental_strategy\": null,\n        \"batch_size\": null,\n        \"lookback\": 1,\n        \"begin\": null,\n        \"persist_docs\": {},\n        \"post-hook\": [\n          {\n            \"sql\": \"select 1\",\n            \"transaction\": true,\n            \"index\": null\n          }\n        ],\n        \"pre-hook\": [\n          {\n            \"sql\": \"select 1\",\n            \"transaction\": true,\n            \"index\": null\n          }\n        ],\n        \"quoting\": {},\n        \"column_types\": {\n          \"a\": \"BIGINT\"\n        },\n        \"full_refresh\": true,\n        \"unique_key\": null,\n        \"on_schema_change\": \"ignore\",\n        \"on_configuration_change\": \"apply\",\n        \"grants\": {},\n        \"packages\": [],\n        \"docs\": {\n          \"show\": true,\n          \"node_color\": \"purple\"\n        },\n        \"contract\": {\n          \"enforced\": false,\n          \"alias_types\": true\n        },\n        \"event_time\": \"my_time_field\",\n        \"concurrent_batches\": null,\n        \"delimiter\": \",\",\n        \"quote_columns\": false\n      },\n      \"tags\": [\n        \"tag\"\n      ],\n      \"description\": \"test_description\",\n      \"columns\": {\n        \"a\": {\n          \"name\": \"a\",\n          \"description\": \"a description\",\n          \"meta\": {},\n          \"data_type\": null,\n          \"constraints\": [],\n          \"quote\": true,\n          \"config\": {\n            \"meta\": {},\n            \"tags\": [\n              \"tag\"\n            ]\n          },\n          \"tags\": [\n            \"tag\"\n          ],\n          \"granularity\": null,\n          \"doc_blocks\": []\n        },\n        \"b\": {\n          \"name\": \"b\",\n          \"description\": \"b description\",\n          \"meta\": {},\n          \"data_type\": null,\n          \"constraints\": [],\n          \"quote\": true,\n          \"config\": {\n            \"meta\": {},\n            \"tags\": [\n              \"tag\"\n            ]\n          },\n          \"tags\": [\n            \"tag\"\n          ],\n          \"granularity\": null,\n          \"doc_blocks\": []\n        }\n      },\n      \"meta\": {\n        \"meta_key\": \"meta_value\"\n      },\n      \"group\": \"finance\",\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": \"purple\"\n      },\n      \"patch_path\": \"test://seeds/s.yml\",\n      \"build_path\": null,\n      \"unrendered_config\": {\n        \"quote_columns\": false,\n        \"docs\": {\n          \"show\": true,\n          \"node_color\": \"purple\"\n        },\n        \"column_types\": {\n          \"a\": \"BIGINT\"\n        },\n        \"delimiter\": \",\",\n        \"enabled\": true,\n        \"tags\": \"tag\",\n        \"pre_hook\": \"select 1\",\n        \"post_hook\": \"select 1\",\n        \"database\": \"dbt\",\n        \"schema\": \"test\",\n        \"alias\": \"test_alias\",\n        \"persist_docs\": {},\n        \"full_refresh\": true,\n        \"meta\": {\n          \"meta_key\": \"meta_value\"\n        },\n        \"grants\": {},\n        \"event_time\": \"my_time_field\",\n        \"group\": \"finance\"\n      },\n      \"created_at\": 1763574306.141397,\n      \"relation_name\": \"\\\"dbt\\\".\\\"test17635743055401889788_test_modified_state_schema_evolution_test\\\".\\\"test_alias\\\"\",\n      \"raw_code\": \"\",\n      \"doc_blocks\": [],\n      \"root_path\": \"/private/var/folders/yj/7kyhyl8s3ql8bb1vjwkh_8pr0000gp/T/pytest-of-michelleark/pytest-20/project0\",\n      \"depends_on\": {\n        \"macros\": []\n      }\n    },\n    \"test.test.not_null_seed__a_.6b59640cde\": {\n      \"database\": \"dbt\",\n      \"schema\": \"test17635743055401889788_test_modified_state_schema_evolution_dbt_test__audit\",\n      \"name\": \"not_null_seed__a_\",\n      \"resource_type\": \"test\",\n      \"package_name\": \"test\",\n      \"path\": \"not_null_seed__a_.sql\",\n      \"original_file_path\": \"seeds/s.yml\",\n      \"unique_id\": \"test.test.not_null_seed__a_.6b59640cde\",\n      \"fqn\": [\n        \"test\",\n        \"not_null_seed__a_\"\n      ],\n      \"alias\": \"not_null_seed__a_\",\n      \"checksum\": {\n        \"name\": \"none\",\n        \"checksum\": \"\"\n      },\n      \"config\": {\n        \"enabled\": true,\n        \"alias\": null,\n        \"schema\": \"dbt_test__audit\",\n        \"database\": null,\n        \"tags\": [],\n        \"meta\": {},\n        \"group\": null,\n        \"materialized\": \"test\",\n        \"severity\": \"ERROR\",\n        \"store_failures\": null,\n        \"store_failures_as\": null,\n        \"where\": null,\n        \"limit\": null,\n        \"fail_calc\": \"count(*)\",\n        \"warn_if\": \"!= 0\",\n        \"error_if\": \"!= 0\"\n      },\n      \"tags\": [\n        \"tag\"\n      ],\n      \"description\": \"\",\n      \"columns\": {},\n      \"meta\": {},\n      \"group\": \"finance\",\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"build_path\": null,\n      \"unrendered_config\": {},\n      \"created_at\": 1763574306.232834,\n      \"relation_name\": null,\n      \"raw_code\": \"{{ test_not_null(**_dbt_generic_test_kwargs) }}\",\n      \"doc_blocks\": [],\n      \"language\": \"sql\",\n      \"refs\": [\n        {\n          \"name\": \"seed\",\n          \"package\": null,\n          \"version\": null\n        }\n      ],\n      \"sources\": [],\n      \"metrics\": [],\n      \"functions\": [],\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.test_not_null\"\n        ],\n        \"nodes\": [\n          \"seed.test.seed\"\n        ]\n      },\n      \"compiled_path\": null,\n      \"contract\": {\n        \"enforced\": false,\n        \"alias_types\": true,\n        \"checksum\": null\n      },\n      \"column_name\": \"\\\"a\\\"\",\n      \"file_key_name\": \"seeds.seed\",\n      \"attached_node\": \"seed.test.seed\",\n      \"test_metadata\": {\n        \"name\": \"not_null\",\n        \"kwargs\": {\n          \"column_name\": \"\\\"a\\\"\",\n          \"model\": \"{{ get_where_subquery(ref('seed')) }}\"\n        },\n        \"namespace\": null\n      }\n    },\n    \"test.test.not_null_seed__b_.a088b263cb\": {\n      \"database\": \"dbt\",\n      \"schema\": \"test17635743055401889788_test_modified_state_schema_evolution_dbt_test__audit\",\n      \"name\": \"not_null_seed__b_\",\n      \"resource_type\": \"test\",\n      \"package_name\": \"test\",\n      \"path\": \"not_null_seed__b_.sql\",\n      \"original_file_path\": \"seeds/s.yml\",\n      \"unique_id\": \"test.test.not_null_seed__b_.a088b263cb\",\n      \"fqn\": [\n        \"test\",\n        \"not_null_seed__b_\"\n      ],\n      \"alias\": \"not_null_seed__b_\",\n      \"checksum\": {\n        \"name\": \"none\",\n        \"checksum\": \"\"\n      },\n      \"config\": {\n        \"enabled\": true,\n        \"alias\": null,\n        \"schema\": \"dbt_test__audit\",\n        \"database\": null,\n        \"tags\": [],\n        \"meta\": {},\n        \"group\": null,\n        \"materialized\": \"test\",\n        \"severity\": \"ERROR\",\n        \"store_failures\": null,\n        \"store_failures_as\": null,\n        \"where\": null,\n        \"limit\": null,\n        \"fail_calc\": \"count(*)\",\n        \"warn_if\": \"!= 0\",\n        \"error_if\": \"!= 0\"\n      },\n      \"tags\": [\n        \"tag\"\n      ],\n      \"description\": \"\",\n      \"columns\": {},\n      \"meta\": {},\n      \"group\": \"finance\",\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"build_path\": null,\n      \"unrendered_config\": {},\n      \"created_at\": 1763574306.2336462,\n      \"relation_name\": null,\n      \"raw_code\": \"{{ test_not_null(**_dbt_generic_test_kwargs) }}\",\n      \"doc_blocks\": [],\n      \"language\": \"sql\",\n      \"refs\": [\n        {\n          \"name\": \"seed\",\n          \"package\": null,\n          \"version\": null\n        }\n      ],\n      \"sources\": [],\n      \"metrics\": [],\n      \"functions\": [],\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.test_not_null\"\n        ],\n        \"nodes\": [\n          \"seed.test.seed\"\n        ]\n      },\n      \"compiled_path\": null,\n      \"contract\": {\n        \"enforced\": false,\n        \"alias_types\": true,\n        \"checksum\": null\n      },\n      \"column_name\": \"\\\"b\\\"\",\n      \"file_key_name\": \"seeds.seed\",\n      \"attached_node\": \"seed.test.seed\",\n      \"test_metadata\": {\n        \"name\": \"not_null\",\n        \"kwargs\": {\n          \"column_name\": \"\\\"b\\\"\",\n          \"model\": \"{{ get_where_subquery(ref('seed')) }}\"\n        },\n        \"namespace\": null\n      }\n    },\n    \"test.test.expression_is_true_seed_b_2.4e0babbea4\": {\n      \"database\": \"dbt\",\n      \"schema\": \"test17635743055401889788_test_modified_state_schema_evolution_dbt_test__audit\",\n      \"name\": \"expression_is_true_seed_b_2\",\n      \"resource_type\": \"test\",\n      \"package_name\": \"test\",\n      \"path\": \"expression_is_true_seed_b_2.sql\",\n      \"original_file_path\": \"seeds/s.yml\",\n      \"unique_id\": \"test.test.expression_is_true_seed_b_2.4e0babbea4\",\n      \"fqn\": [\n        \"test\",\n        \"expression_is_true_seed_b_2\"\n      ],\n      \"alias\": \"expression_is_true_seed_b_2\",\n      \"checksum\": {\n        \"name\": \"none\",\n        \"checksum\": \"\"\n      },\n      \"config\": {\n        \"enabled\": true,\n        \"alias\": null,\n        \"schema\": \"dbt_test__audit\",\n        \"database\": null,\n        \"tags\": [],\n        \"meta\": {},\n        \"group\": null,\n        \"materialized\": \"test\",\n        \"severity\": \"ERROR\",\n        \"store_failures\": null,\n        \"store_failures_as\": null,\n        \"where\": null,\n        \"limit\": null,\n        \"fail_calc\": \"count(*)\",\n        \"warn_if\": \"!= 0\",\n        \"error_if\": \"!= 0\"\n      },\n      \"tags\": [],\n      \"description\": \"\",\n      \"columns\": {},\n      \"meta\": {},\n      \"group\": \"finance\",\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"build_path\": null,\n      \"unrendered_config\": {},\n      \"created_at\": 1763574306.234266,\n      \"relation_name\": null,\n      \"raw_code\": \"{{ test_expression_is_true(**_dbt_generic_test_kwargs) }}\",\n      \"doc_blocks\": [],\n      \"language\": \"sql\",\n      \"refs\": [\n        {\n          \"name\": \"seed\",\n          \"package\": null,\n          \"version\": null\n        }\n      ],\n      \"sources\": [],\n      \"metrics\": [],\n      \"functions\": [],\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.test.test_expression_is_true\",\n          \"macro.dbt.get_where_subquery\"\n        ],\n        \"nodes\": [\n          \"seed.test.seed\"\n        ]\n      },\n      \"compiled_path\": null,\n      \"contract\": {\n        \"enforced\": false,\n        \"alias_types\": true,\n        \"checksum\": null\n      },\n      \"column_name\": null,\n      \"file_key_name\": \"seeds.seed\",\n      \"attached_node\": \"seed.test.seed\",\n      \"test_metadata\": {\n        \"name\": \"expression_is_true\",\n        \"kwargs\": {\n          \"expression\": \"b = 2\",\n          \"model\": \"{{ get_where_subquery(ref('seed')) }}\"\n        },\n        \"namespace\": null\n      }\n    },\n    \"test.test.unique_outer_id.2195e332d3\": {\n      \"database\": \"dbt\",\n      \"schema\": \"test17635743055401889788_test_modified_state_schema_evolution_dbt_test__audit\",\n      \"name\": \"unique_outer_id\",\n      \"resource_type\": \"test\",\n      \"package_name\": \"test\",\n      \"path\": \"unique_outer_id.sql\",\n      \"original_file_path\": \"models/schema.yml\",\n      \"unique_id\": \"test.test.unique_outer_id.2195e332d3\",\n      \"fqn\": [\n        \"test\",\n        \"unique_outer_id\"\n      ],\n      \"alias\": \"unique_outer_id\",\n      \"checksum\": {\n        \"name\": \"none\",\n        \"checksum\": \"\"\n      },\n      \"config\": {\n        \"enabled\": true,\n        \"alias\": null,\n        \"schema\": \"dbt_test__audit\",\n        \"database\": null,\n        \"tags\": [],\n        \"meta\": {},\n        \"group\": null,\n        \"materialized\": \"test\",\n        \"severity\": \"ERROR\",\n        \"store_failures\": null,\n        \"store_failures_as\": null,\n        \"where\": null,\n        \"limit\": null,\n        \"fail_calc\": \"count(*)\",\n        \"warn_if\": \"!= 0\",\n        \"error_if\": \"!= 0\"\n      },\n      \"tags\": [],\n      \"description\": \"\",\n      \"columns\": {},\n      \"meta\": {},\n      \"group\": null,\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"build_path\": null,\n      \"unrendered_config\": {},\n      \"created_at\": 1763574306.276534,\n      \"relation_name\": null,\n      \"raw_code\": \"{{ test_unique(**_dbt_generic_test_kwargs) }}\",\n      \"doc_blocks\": [],\n      \"language\": \"sql\",\n      \"refs\": [\n        {\n          \"name\": \"outer\",\n          \"package\": null,\n          \"version\": null\n        }\n      ],\n      \"sources\": [],\n      \"metrics\": [],\n      \"functions\": [],\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.test_unique\"\n        ],\n        \"nodes\": [\n          \"model.test.outer\"\n        ]\n      },\n      \"compiled_path\": null,\n      \"contract\": {\n        \"enforced\": false,\n        \"alias_types\": true,\n        \"checksum\": null\n      },\n      \"column_name\": \"id\",\n      \"file_key_name\": \"models.outer\",\n      \"attached_node\": \"model.test.outer\",\n      \"test_metadata\": {\n        \"name\": \"unique\",\n        \"kwargs\": {\n          \"column_name\": \"id\",\n          \"model\": \"{{ get_where_subquery(ref('outer')) }}\"\n        },\n        \"namespace\": null\n      }\n    },\n    \"test.test.not_null_outer_id.a226f4fb36\": {\n      \"database\": \"dbt\",\n      \"schema\": \"test17635743055401889788_test_modified_state_schema_evolution_dbt_test__audit\",\n      \"name\": \"not_null_outer_id\",\n      \"resource_type\": \"test\",\n      \"package_name\": \"test\",\n      \"path\": \"not_null_outer_id.sql\",\n      \"original_file_path\": \"models/schema.yml\",\n      \"unique_id\": \"test.test.not_null_outer_id.a226f4fb36\",\n      \"fqn\": [\n        \"test\",\n        \"not_null_outer_id\"\n      ],\n      \"alias\": \"not_null_outer_id\",\n      \"checksum\": {\n        \"name\": \"none\",\n        \"checksum\": \"\"\n      },\n      \"config\": {\n        \"enabled\": true,\n        \"alias\": null,\n        \"schema\": \"dbt_test__audit\",\n        \"database\": null,\n        \"tags\": [],\n        \"meta\": {},\n        \"group\": null,\n        \"materialized\": \"test\",\n        \"severity\": \"ERROR\",\n        \"store_failures\": null,\n        \"store_failures_as\": null,\n        \"where\": null,\n        \"limit\": null,\n        \"fail_calc\": \"count(*)\",\n        \"warn_if\": \"!= 0\",\n        \"error_if\": \"!= 0\"\n      },\n      \"tags\": [],\n      \"description\": \"\",\n      \"columns\": {},\n      \"meta\": {},\n      \"group\": null,\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"build_path\": null,\n      \"unrendered_config\": {},\n      \"created_at\": 1763574306.277153,\n      \"relation_name\": null,\n      \"raw_code\": \"{{ test_not_null(**_dbt_generic_test_kwargs) }}\",\n      \"doc_blocks\": [],\n      \"language\": \"sql\",\n      \"refs\": [\n        {\n          \"name\": \"outer\",\n          \"package\": null,\n          \"version\": null\n        }\n      ],\n      \"sources\": [],\n      \"metrics\": [],\n      \"functions\": [],\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.test_not_null\"\n        ],\n        \"nodes\": [\n          \"model.test.outer\"\n        ]\n      },\n      \"compiled_path\": null,\n      \"contract\": {\n        \"enforced\": false,\n        \"alias_types\": true,\n        \"checksum\": null\n      },\n      \"column_name\": \"id\",\n      \"file_key_name\": \"models.outer\",\n      \"attached_node\": \"model.test.outer\",\n      \"test_metadata\": {\n        \"name\": \"not_null\",\n        \"kwargs\": {\n          \"column_name\": \"id\",\n          \"model\": \"{{ get_where_subquery(ref('outer')) }}\"\n        },\n        \"namespace\": null\n      }\n    },\n    \"test.test.unique_model_with_lots_of_schema_configs_id.8328d84982\": {\n      \"database\": \"dbt\",\n      \"schema\": \"test17635743055401889788_test_modified_state_schema_evolution_dbt_test__audit\",\n      \"name\": \"unique_model_with_lots_of_schema_configs_id\",\n      \"resource_type\": \"test\",\n      \"package_name\": \"test\",\n      \"path\": \"unique_model_with_lots_of_schema_configs_id.sql\",\n      \"original_file_path\": \"models/schema.yml\",\n      \"unique_id\": \"test.test.unique_model_with_lots_of_schema_configs_id.8328d84982\",\n      \"fqn\": [\n        \"test\",\n        \"unique_model_with_lots_of_schema_configs_id\"\n      ],\n      \"alias\": \"unique_model_with_lots_of_schema_configs_id\",\n      \"checksum\": {\n        \"name\": \"none\",\n        \"checksum\": \"\"\n      },\n      \"config\": {\n        \"enabled\": true,\n        \"alias\": null,\n        \"schema\": \"dbt_test__audit\",\n        \"database\": null,\n        \"tags\": [],\n        \"meta\": {},\n        \"group\": null,\n        \"materialized\": \"test\",\n        \"severity\": \"ERROR\",\n        \"store_failures\": null,\n        \"store_failures_as\": null,\n        \"where\": null,\n        \"limit\": null,\n        \"fail_calc\": \"count(*)\",\n        \"warn_if\": \"!= 0\",\n        \"error_if\": \"!= 0\"\n      },\n      \"tags\": [\n        \"column_level_tag\"\n      ],\n      \"description\": \"\",\n      \"columns\": {},\n      \"meta\": {},\n      \"group\": null,\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"build_path\": null,\n      \"unrendered_config\": {},\n      \"created_at\": 1763574306.277745,\n      \"relation_name\": null,\n      \"raw_code\": \"{{ test_unique(**_dbt_generic_test_kwargs) }}\",\n      \"doc_blocks\": [],\n      \"language\": \"sql\",\n      \"refs\": [\n        {\n          \"name\": \"model_with_lots_of_schema_configs\",\n          \"package\": null,\n          \"version\": null\n        }\n      ],\n      \"sources\": [],\n      \"metrics\": [],\n      \"functions\": [],\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.test_unique\"\n        ],\n        \"nodes\": [\n          \"model.test.model_with_lots_of_schema_configs\"\n        ]\n      },\n      \"compiled_path\": null,\n      \"contract\": {\n        \"enforced\": false,\n        \"alias_types\": true,\n        \"checksum\": null\n      },\n      \"column_name\": \"id\",\n      \"file_key_name\": \"models.model_with_lots_of_schema_configs\",\n      \"attached_node\": \"model.test.model_with_lots_of_schema_configs\",\n      \"test_metadata\": {\n        \"name\": \"unique\",\n        \"kwargs\": {\n          \"column_name\": \"id\",\n          \"model\": \"{{ get_where_subquery(ref('model_with_lots_of_schema_configs')) }}\"\n        },\n        \"namespace\": null\n      }\n    },\n    \"test.test.my_favorite_test.b488d63233\": {\n      \"database\": \"dbt\",\n      \"schema\": \"test17635743055401889788_test_modified_state_schema_evolution_dbt_test__audit\",\n      \"name\": \"my_favorite_test\",\n      \"resource_type\": \"test\",\n      \"package_name\": \"test\",\n      \"path\": \"my_favorite_test.sql\",\n      \"original_file_path\": \"models/schema.yml\",\n      \"unique_id\": \"test.test.my_favorite_test.b488d63233\",\n      \"fqn\": [\n        \"test\",\n        \"my_favorite_test\"\n      ],\n      \"alias\": \"not_null__id__alias\",\n      \"checksum\": {\n        \"name\": \"none\",\n        \"checksum\": \"\"\n      },\n      \"config\": {\n        \"enabled\": true,\n        \"alias\": \"not_null__id__alias\",\n        \"schema\": \"dbt_test__audit\",\n        \"database\": \"dbt\",\n        \"tags\": [\n          \"test_tag\"\n        ],\n        \"meta\": {\n          \"my_custom_meta_key\": \"my_custom_meta_value\"\n        },\n        \"group\": \"important_tests\",\n        \"materialized\": \"test\",\n        \"severity\": \"warn\",\n        \"store_failures\": true,\n        \"store_failures_as\": \"table\",\n        \"where\": \"1 = 1\",\n        \"limit\": 10,\n        \"fail_calc\": \"count(*)\",\n        \"warn_if\": \"!= 0\",\n        \"error_if\": \"!= 0\"\n      },\n      \"tags\": [\n        \"column_level_tag\",\n        \"test_tag\"\n      ],\n      \"description\": \"A test that should pass\",\n      \"columns\": {},\n      \"meta\": {\n        \"my_custom_meta_key\": \"my_custom_meta_value\"\n      },\n      \"group\": null,\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"build_path\": null,\n      \"unrendered_config\": {\n        \"severity\": \"warn\",\n        \"tags\": [\n          \"test_tag\"\n        ],\n        \"enabled\": true,\n        \"where\": \"1 = 1\",\n        \"limit\": 10,\n        \"warn_if\": \"!= 0\",\n        \"error_if\": \"!= 0\",\n        \"fail_calc\": \"count(*)\",\n        \"store_failures\": true,\n        \"store_failures_as\": \"table\",\n        \"meta\": {\n          \"my_custom_meta_key\": \"my_custom_meta_value\"\n        },\n        \"database\": \"dbt\",\n        \"schema\": \"dbt_test__audit\",\n        \"alias\": \"not_null__id__alias\",\n        \"group\": \"important_tests\"\n      },\n      \"created_at\": 1763574306.2793431,\n      \"relation_name\": \"\\\"dbt\\\".\\\"test17635743055401889788_test_modified_state_schema_evolution_dbt_test__audit\\\".\\\"not_null__id__alias\\\"\",\n      \"raw_code\": \"{{ test_not_null(**_dbt_generic_test_kwargs) }}{{ config(severity=\\\"warn\\\",tags=['test_tag'],enabled=True,where=\\\"1 = 1\\\",limit=10,warn_if=\\\"!= 0\\\",error_if=\\\"!= 0\\\",fail_calc=\\\"count(*)\\\",store_failures=True,store_failures_as=\\\"table\\\",meta={'my_custom_meta_key': 'my_custom_meta_value'},database=\\\"dbt\\\",schema=\\\"dbt_test__audit\\\",alias=\\\"not_null__id__alias\\\",group=\\\"important_tests\\\") }}\",\n      \"doc_blocks\": [],\n      \"language\": \"sql\",\n      \"refs\": [\n        {\n          \"name\": \"model_with_lots_of_schema_configs\",\n          \"package\": null,\n          \"version\": null\n        }\n      ],\n      \"sources\": [],\n      \"metrics\": [],\n      \"functions\": [],\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.test_not_null\"\n        ],\n        \"nodes\": [\n          \"model.test.model_with_lots_of_schema_configs\"\n        ]\n      },\n      \"compiled_path\": null,\n      \"contract\": {\n        \"enforced\": false,\n        \"alias_types\": true,\n        \"checksum\": null\n      },\n      \"column_name\": \"id\",\n      \"file_key_name\": \"models.model_with_lots_of_schema_configs\",\n      \"attached_node\": \"model.test.model_with_lots_of_schema_configs\",\n      \"test_metadata\": {\n        \"name\": \"not_null\",\n        \"kwargs\": {\n          \"column_name\": \"id\",\n          \"model\": \"{{ get_where_subquery(ref('model_with_lots_of_schema_configs')) }}\"\n        },\n        \"namespace\": null\n      }\n    },\n    \"test.test.my_second_favorite_test.c8955109ad\": {\n      \"database\": \"dbt\",\n      \"schema\": \"test17635743055401889788_test_modified_state_schema_evolution_dbt_test__audit\",\n      \"name\": \"my_second_favorite_test\",\n      \"resource_type\": \"test\",\n      \"package_name\": \"test\",\n      \"path\": \"my_second_favorite_test.sql\",\n      \"original_file_path\": \"models/schema.yml\",\n      \"unique_id\": \"test.test.my_second_favorite_test.c8955109ad\",\n      \"fqn\": [\n        \"test\",\n        \"my_second_favorite_test\"\n      ],\n      \"alias\": \"my_generic_test__created_at__alias\",\n      \"checksum\": {\n        \"name\": \"none\",\n        \"checksum\": \"\"\n      },\n      \"config\": {\n        \"enabled\": true,\n        \"alias\": \"my_generic_test__created_at__alias\",\n        \"schema\": \"dbt_test__audit\",\n        \"database\": \"dbt\",\n        \"tags\": [\n          \"test_tag\",\n          \"test_tag\"\n        ],\n        \"meta\": {\n          \"my_custom_meta_key\": \"my_custom_meta_value\"\n        },\n        \"group\": \"important_tests\",\n        \"materialized\": \"test\",\n        \"severity\": \"warn\",\n        \"store_failures\": true,\n        \"store_failures_as\": \"table\",\n        \"where\": \"1 = 1\",\n        \"limit\": 10,\n        \"fail_calc\": \"count(*)\",\n        \"warn_if\": \"!= 0\",\n        \"error_if\": \"!= 0\"\n      },\n      \"tags\": [\n        \"test_tag\"\n      ],\n      \"description\": \"A test that should pass\",\n      \"columns\": {},\n      \"meta\": {\n        \"my_custom_meta_key\": \"my_custom_meta_value\"\n      },\n      \"group\": null,\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"build_path\": null,\n      \"unrendered_config\": {\n        \"severity\": \"Keyword(key='severity', value=Const(value='warn'))\",\n        \"tags\": \"Keyword(key='tags', value=List(items=[Const(value='test_tag')]))\",\n        \"enabled\": \"Keyword(key='enabled', value=Const(value=True))\",\n        \"where\": \"Keyword(key='where', value=Const(value='1 = 1'))\",\n        \"limit\": \"Keyword(key='limit', value=Const(value=10))\",\n        \"warn_if\": \"Keyword(key='warn_if', value=Const(value='!= 0'))\",\n        \"error_if\": \"Keyword(key='error_if', value=Const(value='!= 0'))\",\n        \"fail_calc\": \"Keyword(key='fail_calc', value=Const(value='count(*)'))\",\n        \"store_failures\": \"Keyword(key='store_failures', value=Const(value=True))\",\n        \"store_failures_as\": \"Keyword(key='store_failures_as', value=Const(value='table'))\",\n        \"meta\": \"Keyword(key='meta', value=Dict(items=[Pair(key=Const(value='my_custom_meta_key'), value=Const(value='my_custom_meta_value'))]))\",\n        \"database\": \"Keyword(key='database', value=Const(value='dbt'))\",\n        \"schema\": \"Keyword(key='schema', value=Const(value='dbt_test__audit'))\",\n        \"alias\": \"Keyword(key='alias', value=Const(value='my_generic_test__created_at__alias'))\",\n        \"group\": \"Keyword(key='group', value=Const(value='important_tests'))\"\n      },\n      \"created_at\": 1763574306.2801669,\n      \"relation_name\": \"\\\"dbt\\\".\\\"test17635743055401889788_test_modified_state_schema_evolution_dbt_test__audit\\\".\\\"my_generic_test__created_at__alias\\\"\",\n      \"raw_code\": \"{{ test_my_generic_test(**_dbt_generic_test_kwargs) }}{{ config(severity=\\\"warn\\\",tags=['test_tag'],enabled=True,where=\\\"1 = 1\\\",limit=10,warn_if=\\\"!= 0\\\",error_if=\\\"!= 0\\\",fail_calc=\\\"count(*)\\\",store_failures=True,store_failures_as=\\\"table\\\",meta={'my_custom_meta_key': 'my_custom_meta_value'},database=\\\"dbt\\\",schema=\\\"dbt_test__audit\\\",alias=\\\"my_generic_test__created_at__alias\\\",group=\\\"important_tests\\\") }}\",\n      \"doc_blocks\": [],\n      \"language\": \"sql\",\n      \"refs\": [\n        {\n          \"name\": \"model_with_lots_of_schema_configs\",\n          \"package\": null,\n          \"version\": null\n        }\n      ],\n      \"sources\": [],\n      \"metrics\": [],\n      \"functions\": [],\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.test.test_my_generic_test\",\n          \"macro.dbt.get_where_subquery\"\n        ],\n        \"nodes\": [\n          \"model.test.model_with_lots_of_schema_configs\"\n        ]\n      },\n      \"compiled_path\": null,\n      \"contract\": {\n        \"enforced\": false,\n        \"alias_types\": true,\n        \"checksum\": null\n      },\n      \"column_name\": \"created_at\",\n      \"file_key_name\": \"models.model_with_lots_of_schema_configs\",\n      \"attached_node\": \"model.test.model_with_lots_of_schema_configs\",\n      \"test_metadata\": {\n        \"name\": \"my_generic_test\",\n        \"kwargs\": {\n          \"column_name\": \"created_at\",\n          \"model\": \"{{ get_where_subquery(ref('model_with_lots_of_schema_configs')) }}\"\n        },\n        \"namespace\": null\n      }\n    },\n    \"snapshot.test.snapshot_2\": {\n      \"database\": \"mydb\",\n      \"schema\": \"test17635743055401889788_test_modified_state_schema_evolution_myschema\",\n      \"name\": \"snapshot_2\",\n      \"resource_type\": \"snapshot\",\n      \"package_name\": \"test\",\n      \"path\": \"snapshot_2.yml/snapshot_2.sql\",\n      \"original_file_path\": \"snapshots/snapshot_2.yml\",\n      \"unique_id\": \"snapshot.test.snapshot_2\",\n      \"fqn\": [\n        \"test\",\n        \"snapshot_2\"\n      ],\n      \"alias\": \"snapshot_2\",\n      \"checksum\": {\n        \"name\": \"sha256\",\n        \"checksum\": \"a2b723667ee663b45eed04aeccb8accd9de12c66fa7e291cd053c67795093630\"\n      },\n      \"config\": {\n        \"enabled\": true,\n        \"alias\": null,\n        \"schema\": \"myschema\",\n        \"database\": \"mydb\",\n        \"tags\": [],\n        \"meta\": {\n          \"owner\": \"@alice\",\n          \"maturity\": \"in dev\"\n        },\n        \"group\": null,\n        \"materialized\": \"snapshot\",\n        \"incremental_strategy\": null,\n        \"batch_size\": null,\n        \"lookback\": 1,\n        \"begin\": null,\n        \"persist_docs\": {},\n        \"post-hook\": [],\n        \"pre-hook\": [],\n        \"quoting\": {},\n        \"column_types\": {},\n        \"full_refresh\": null,\n        \"unique_key\": \"id\",\n        \"on_schema_change\": \"ignore\",\n        \"on_configuration_change\": \"apply\",\n        \"grants\": {},\n        \"packages\": [],\n        \"docs\": {\n          \"show\": true,\n          \"node_color\": \"purple\"\n        },\n        \"contract\": {\n          \"enforced\": false,\n          \"alias_types\": true\n        },\n        \"event_time\": null,\n        \"concurrent_batches\": null,\n        \"strategy\": \"check\",\n        \"target_schema\": null,\n        \"target_database\": null,\n        \"updated_at\": \"updated_at\",\n        \"check_cols\": [\n          \"alpha\",\n          \"beta\",\n          \"delta\"\n        ],\n        \"snapshot_meta_column_names\": {\n          \"dbt_valid_to\": \"my_valid_to_col\",\n          \"dbt_valid_from\": \"my_from_col\",\n          \"dbt_scd_id\": \"my_scd_col\",\n          \"dbt_updated_at\": \"my_updated_at_col\",\n          \"dbt_is_deleted\": \"my_is_deleted_col\"\n        },\n        \"dbt_valid_to_current\": \"valid_to_current\",\n        \"hard_deletes\": \"new_record\"\n      },\n      \"tags\": [],\n      \"description\": \"Description of snapshot_2\",\n      \"columns\": {},\n      \"meta\": {\n        \"owner\": \"@alice\",\n        \"maturity\": \"in dev\"\n      },\n      \"group\": null,\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": \"purple\"\n      },\n      \"patch_path\": \"test://snapshots/snapshot_2.yml\",\n      \"build_path\": null,\n      \"unrendered_config\": {\n        \"database\": \"mydb\",\n        \"schema\": \"myschema\",\n        \"unique_key\": \"id\",\n        \"strategy\": \"check\",\n        \"updated_at\": \"updated_at\",\n        \"check_cols\": [\n          \"alpha\",\n          \"beta\",\n          \"delta\",\n          \"alpha\",\n          \"beta\",\n          \"delta\"\n        ],\n        \"snapshot_meta_column_names\": {\n          \"dbt_valid_from\": \"my_from_col\",\n          \"dbt_valid_to\": \"my_valid_to_col\",\n          \"dbt_scd_id\": \"my_scd_col\",\n          \"dbt_updated_at\": \"my_updated_at_col\",\n          \"dbt_is_deleted\": \"my_is_deleted_col\"\n        },\n        \"hard_deletes\": \"new_record\",\n        \"dbt_valid_to_current\": \"valid_to_current\",\n        \"meta\": {\n          \"owner\": \"@alice\",\n          \"maturity\": \"in dev\"\n        },\n        \"docs\": {\n          \"sfhow\": true,\n          \"node_color\": \"purple\"\n        }\n      },\n      \"created_at\": 1763574306.447405,\n      \"relation_name\": \"\\\"mydb\\\".\\\"test17635743055401889788_test_modified_state_schema_evolution_myschema\\\".\\\"snapshot_2\\\"\",\n      \"raw_code\": \"select * from {{ ref(\\\"snapshot_source\\\") }}\",\n      \"doc_blocks\": [],\n      \"language\": \"sql\",\n      \"refs\": [\n        {\n          \"name\": \"snapshot_source\",\n          \"package\": null,\n          \"version\": null\n        }\n      ],\n      \"sources\": [],\n      \"metrics\": [],\n      \"functions\": [],\n      \"depends_on\": {\n        \"macros\": [],\n        \"nodes\": [\n          \"model.test.snapshot_source\"\n        ]\n      },\n      \"compiled_path\": null,\n      \"contract\": {\n        \"enforced\": false,\n        \"alias_types\": true,\n        \"checksum\": null\n      }\n    },\n    \"snapshot.test.snapshot_3\": {\n      \"database\": \"mydb\",\n      \"schema\": \"test17635743055401889788_test_modified_state_schema_evolution_myschema\",\n      \"name\": \"snapshot_3\",\n      \"resource_type\": \"snapshot\",\n      \"package_name\": \"test\",\n      \"path\": \"snapshot_3.yml/snapshot_3.sql\",\n      \"original_file_path\": \"snapshots/snapshot_3.yml\",\n      \"unique_id\": \"snapshot.test.snapshot_3\",\n      \"fqn\": [\n        \"test\",\n        \"snapshot_3\"\n      ],\n      \"alias\": \"snapshot_3\",\n      \"checksum\": {\n        \"name\": \"sha256\",\n        \"checksum\": \"0310dbfcd03499e4cdc206b694a207008604fb45b7a7c6ee6849b55ecd64b1fe\"\n      },\n      \"config\": {\n        \"enabled\": true,\n        \"alias\": null,\n        \"schema\": \"myschema\",\n        \"database\": \"mydb\",\n        \"tags\": [],\n        \"meta\": {\n          \"owner\": \"@alice\",\n          \"maturity\": \"in dev\"\n        },\n        \"group\": null,\n        \"materialized\": \"snapshot\",\n        \"incremental_strategy\": null,\n        \"batch_size\": null,\n        \"lookback\": 1,\n        \"begin\": null,\n        \"persist_docs\": {},\n        \"post-hook\": [],\n        \"pre-hook\": [],\n        \"quoting\": {},\n        \"column_types\": {},\n        \"full_refresh\": null,\n        \"unique_key\": \"id\",\n        \"on_schema_change\": \"ignore\",\n        \"on_configuration_change\": \"apply\",\n        \"grants\": {},\n        \"packages\": [],\n        \"docs\": {\n          \"show\": true,\n          \"node_color\": \"purple\"\n        },\n        \"contract\": {\n          \"enforced\": false,\n          \"alias_types\": true\n        },\n        \"event_time\": null,\n        \"concurrent_batches\": null,\n        \"strategy\": \"timestamp\",\n        \"target_schema\": null,\n        \"target_database\": null,\n        \"updated_at\": \"updated_at\",\n        \"check_cols\": null,\n        \"snapshot_meta_column_names\": {\n          \"dbt_valid_to\": \"my_valid_to_col\",\n          \"dbt_valid_from\": \"my_from_col\",\n          \"dbt_scd_id\": \"my_scd_col\",\n          \"dbt_updated_at\": \"my_updated_at_col\",\n          \"dbt_is_deleted\": \"my_is_deleted_col\"\n        },\n        \"dbt_valid_to_current\": \"valid_to_current\",\n        \"invalidate_hard_deletes\": true\n      },\n      \"tags\": [],\n      \"description\": \"Description of snapshot_3\",\n      \"columns\": {},\n      \"meta\": {\n        \"owner\": \"@alice\",\n        \"maturity\": \"in dev\"\n      },\n      \"group\": null,\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": \"purple\"\n      },\n      \"patch_path\": \"test://snapshots/snapshot_3.yml\",\n      \"build_path\": null,\n      \"unrendered_config\": {\n        \"database\": \"mydb\",\n        \"schema\": \"myschema\",\n        \"unique_key\": \"id\",\n        \"strategy\": \"timestamp\",\n        \"updated_at\": \"updated_at\",\n        \"snapshot_meta_column_names\": {\n          \"dbt_valid_from\": \"my_from_col\",\n          \"dbt_valid_to\": \"my_valid_to_col\",\n          \"dbt_scd_id\": \"my_scd_col\",\n          \"dbt_updated_at\": \"my_updated_at_col\",\n          \"dbt_is_deleted\": \"my_is_deleted_col\"\n        },\n        \"invalidate_hard_deletes\": true,\n        \"dbt_valid_to_current\": \"valid_to_current\",\n        \"meta\": {\n          \"owner\": \"@alice\",\n          \"maturity\": \"in dev\"\n        },\n        \"docs\": {\n          \"sfhow\": true,\n          \"node_color\": \"purple\"\n        }\n      },\n      \"created_at\": 1763574306.4514718,\n      \"relation_name\": \"\\\"mydb\\\".\\\"test17635743055401889788_test_modified_state_schema_evolution_myschema\\\".\\\"snapshot_3\\\"\",\n      \"raw_code\": \"select * from {{ ref(\\\"snapshot_source\\\") }}\",\n      \"doc_blocks\": [],\n      \"language\": \"sql\",\n      \"refs\": [\n        {\n          \"name\": \"snapshot_source\",\n          \"package\": null,\n          \"version\": null\n        }\n      ],\n      \"sources\": [],\n      \"metrics\": [],\n      \"functions\": [],\n      \"depends_on\": {\n        \"macros\": [],\n        \"nodes\": [\n          \"model.test.snapshot_source\"\n        ]\n      },\n      \"compiled_path\": null,\n      \"contract\": {\n        \"enforced\": false,\n        \"alias_types\": true,\n        \"checksum\": null\n      }\n    }\n  },\n  \"sources\": {\n    \"source.test.my_source.my_table\": {\n      \"database\": \"raw\",\n      \"schema\": \"jaffle_shop\",\n      \"name\": \"my_table\",\n      \"resource_type\": \"source\",\n      \"package_name\": \"test\",\n      \"path\": \"models/schema.yml\",\n      \"original_file_path\": \"models/schema.yml\",\n      \"unique_id\": \"source.test.my_source.my_table\",\n      \"fqn\": [\n        \"test\",\n        \"my_source\",\n        \"my_table\"\n      ],\n      \"source_name\": \"my_source\",\n      \"source_description\": \"description\",\n      \"loader\": \"test\",\n      \"identifier\": \"table_identifier\",\n      \"quoting\": {\n        \"database\": true,\n        \"schema\": true,\n        \"identifier\": true,\n        \"column\": null\n      },\n      \"loaded_at_field\": \"column_name\",\n      \"loaded_at_query\": null,\n      \"freshness\": {\n        \"warn_after\": {\n          \"count\": 1,\n          \"period\": \"minute\"\n        },\n        \"error_after\": {\n          \"count\": 2,\n          \"period\": \"hour\"\n        },\n        \"filter\": \"column_name = 1\"\n      },\n      \"external\": {\n        \"location\": \"location\",\n        \"file_format\": \"file_format\",\n        \"row_format\": \"row_format\",\n        \"tbl_properties\": \"tbl_properties\",\n        \"partitions\": [\n          {\n            \"name\": \"column_name\",\n            \"data_type\": \"data_type\",\n            \"description\": \"description\",\n            \"meta\": {\n              \"test\": 1\n            }\n          }\n        ],\n        \"additional_property\": \"additional_value\"\n      },\n      \"description\": \"description\",\n      \"columns\": {\n        \"column_name\": {\n          \"name\": \"column_name\",\n          \"description\": \"description\",\n          \"meta\": {\n            \"test\": 1\n          },\n          \"data_type\": null,\n          \"constraints\": [],\n          \"quote\": true,\n          \"config\": {\n            \"meta\": {\n              \"test\": 1\n            },\n            \"tags\": [\n              \"column_tag\"\n            ]\n          },\n          \"tags\": [\n            \"column_tag\"\n          ],\n          \"granularity\": null,\n          \"doc_blocks\": []\n        }\n      },\n      \"meta\": {\n        \"source_meta\": 1,\n        \"table_meta\": 1\n      },\n      \"source_meta\": {\n        \"source_meta\": 1\n      },\n      \"tags\": [\n        \"source_tag\",\n        \"table_tag\"\n      ],\n      \"config\": {\n        \"enabled\": true,\n        \"event_time\": \"column_name\",\n        \"freshness\": {\n          \"warn_after\": {\n            \"count\": 1,\n            \"period\": \"minute\"\n          },\n          \"error_after\": {\n            \"count\": 2,\n            \"period\": \"hour\"\n          },\n          \"filter\": \"column_name = 1\"\n        },\n        \"loaded_at_field\": \"column_name\",\n        \"loaded_at_query\": null,\n        \"meta\": {\n          \"source_meta\": 1,\n          \"table_meta\": 1\n        },\n        \"tags\": [\n          \"source_tag\",\n          \"table_tag\"\n        ]\n      },\n      \"patch_path\": null,\n      \"unrendered_config\": {\n        \"enabled\": true,\n        \"event_time\": \"column_name\",\n        \"loaded_at_field\": \"column_name\",\n        \"meta\": {\n          \"source_meta\": 1,\n          \"table_meta\": 1\n        },\n        \"tags\": [\n          \"source_tag\",\n          \"table_tag\"\n        ],\n        \"freshness\": {\n          \"warn_after\": {\n            \"count\": 1,\n            \"period\": \"minute\"\n          },\n          \"error_after\": {\n            \"count\": 2,\n            \"period\": \"hour\"\n          },\n          \"filter\": \"column_name = 1\"\n        },\n        \"loaded_at_query\": null\n      },\n      \"relation_name\": \"\\\"raw\\\".\\\"jaffle_shop\\\".\\\"table_identifier\\\"\",\n      \"created_at\": 1763574306.468715,\n      \"unrendered_database\": \"raw\",\n      \"unrendered_schema\": \"jaffle_shop\",\n      \"doc_blocks\": []\n    }\n  },\n  \"macros\": {\n    \"macro.test.test_expression_is_true\": {\n      \"name\": \"test_expression_is_true\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"test\",\n      \"path\": \"macros/expression_is_true.sql\",\n      \"original_file_path\": \"macros/expression_is_true.sql\",\n      \"unique_id\": \"macro.test.test_expression_is_true\",\n      \"macro_sql\": \"{% test expression_is_true(model, expression, column_name=None) %}\\n\\n{% set column_list = '*' if should_store_failures() else \\\"1\\\" %}\\n\\nselect\\n    {{ column_list }}\\nfrom {{ model }}\\n{% if column_name is none %}\\nwhere not({{ expression }})\\n{%- else %}\\nwhere not({{ column_name }} {{ expression }})\\n{%- endif %}\\n\\n{% endtest %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.should_store_failures\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.494549,\n      \"supported_languages\": null\n    },\n    \"macro.test.cool_macro\": {\n      \"name\": \"cool_macro\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"test\",\n      \"path\": \"macros/macro_stuff.sql\",\n      \"original_file_path\": \"macros/macro_stuff.sql\",\n      \"unique_id\": \"macro.test.cool_macro\",\n      \"macro_sql\": \"{% macro cool_macro() %}\\n  wow!\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4946592,\n      \"supported_languages\": null\n    },\n    \"macro.test.other_cool_macro\": {\n      \"name\": \"other_cool_macro\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"test\",\n      \"path\": \"macros/macro_stuff.sql\",\n      \"original_file_path\": \"macros/macro_stuff.sql\",\n      \"unique_id\": \"macro.test.other_cool_macro\",\n      \"macro_sql\": \"{% macro other_cool_macro(a, b) %}\\n  cool!\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.494739,\n      \"supported_languages\": null\n    },\n    \"macro.test.test_my_generic_test\": {\n      \"name\": \"test_my_generic_test\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"test\",\n      \"path\": \"tests/generic/my_generic_test.sql\",\n      \"original_file_path\": \"tests/generic/my_generic_test.sql\",\n      \"unique_id\": \"macro.test.test_my_generic_test\",\n      \"macro_sql\": \"{% test my_generic_test(model, column_name) %}\\n    SELECT 1 as a_column WHERE 1 = 2\\n{% endtest %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4948502,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__current_timestamp\": {\n      \"name\": \"postgres__current_timestamp\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/timestamps.sql\",\n      \"original_file_path\": \"macros/timestamps.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__current_timestamp\",\n      \"macro_sql\": \"{% macro postgres__current_timestamp() -%}\\n    now()\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4948668,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__snapshot_string_as_time\": {\n      \"name\": \"postgres__snapshot_string_as_time\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/timestamps.sql\",\n      \"original_file_path\": \"macros/timestamps.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__snapshot_string_as_time\",\n      \"macro_sql\": \"{% macro postgres__snapshot_string_as_time(timestamp) -%}\\n    {%- set result = \\\"'\\\" ~ timestamp ~ \\\"'::timestamp without time zone\\\" -%}\\n    {{ return(result) }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4948711,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__snapshot_get_time\": {\n      \"name\": \"postgres__snapshot_get_time\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/timestamps.sql\",\n      \"original_file_path\": \"macros/timestamps.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__snapshot_get_time\",\n      \"macro_sql\": \"{% macro postgres__snapshot_get_time() -%}\\n  {{ current_timestamp() }}::timestamp without time zone\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.current_timestamp\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.494874,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__current_timestamp_backcompat\": {\n      \"name\": \"postgres__current_timestamp_backcompat\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/timestamps.sql\",\n      \"original_file_path\": \"macros/timestamps.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__current_timestamp_backcompat\",\n      \"macro_sql\": \"{% macro postgres__current_timestamp_backcompat() %}\\n    current_timestamp::{{ type_timestamp() }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.type_timestamp\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.49488,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__current_timestamp_in_utc_backcompat\": {\n      \"name\": \"postgres__current_timestamp_in_utc_backcompat\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/timestamps.sql\",\n      \"original_file_path\": \"macros/timestamps.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__current_timestamp_in_utc_backcompat\",\n      \"macro_sql\": \"{% macro postgres__current_timestamp_in_utc_backcompat() %}\\n    (current_timestamp at time zone 'utc')::{{ type_timestamp() }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.type_timestamp\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.494883,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__get_catalog_relations\": {\n      \"name\": \"postgres__get_catalog_relations\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/catalog.sql\",\n      \"original_file_path\": \"macros/catalog.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__get_catalog_relations\",\n      \"macro_sql\": \"{% macro postgres__get_catalog_relations(information_schema, relations) -%}\\n  {%- call statement('catalog', fetch_result=True) -%}\\n\\n    {#\\n      If the user has multiple databases set and the first one is wrong, this will fail.\\n      But we won't fail in the case where there are multiple quoting-difference-only dbs, which is better.\\n    #}\\n    {% set database = information_schema.database %}\\n    {{ adapter.verify_database(database) }}\\n\\n    select\\n        '{{ database }}' as table_database,\\n        sch.nspname as table_schema,\\n        tbl.relname as table_name,\\n        case tbl.relkind\\n            when 'v' then 'VIEW'\\n            when 'm' then 'MATERIALIZED VIEW'\\n            else 'BASE TABLE'\\n        end as table_type,\\n        tbl_desc.description as table_comment,\\n        col.attname as column_name,\\n        col.attnum as column_index,\\n        pg_catalog.format_type(col.atttypid, col.atttypmod) as column_type,\\n        col_desc.description as column_comment,\\n        pg_get_userbyid(tbl.relowner) as table_owner\\n\\n    from pg_catalog.pg_namespace sch\\n    join pg_catalog.pg_class tbl on tbl.relnamespace = sch.oid\\n    join pg_catalog.pg_attribute col on col.attrelid = tbl.oid\\n    left outer join pg_catalog.pg_description tbl_desc on (tbl_desc.objoid = tbl.oid and tbl_desc.objsubid = 0)\\n    left outer join pg_catalog.pg_description col_desc on (col_desc.objoid = tbl.oid and col_desc.objsubid = col.attnum)\\n    where (\\n      {%- for relation in relations -%}\\n        {%- if relation.identifier -%}\\n          (upper(sch.nspname) = upper('{{ relation.schema }}') and\\n           upper(tbl.relname) = upper('{{ relation.identifier }}'))\\n        {%- else-%}\\n          upper(sch.nspname) = upper('{{ relation.schema }}')\\n        {%- endif -%}\\n        {%- if not loop.last %} or {% endif -%}\\n      {%- endfor -%}\\n    )\\n      and not pg_is_other_temp_schema(sch.oid) -- not a temporary schema belonging to another session\\n      and tbl.relpersistence in ('p', 'u') -- [p]ermanent table or [u]nlogged table. Exclude [t]emporary tables\\n      and tbl.relkind in ('r', 'v', 'f', 'p', 'm') -- o[r]dinary table, [v]iew, [f]oreign table, [p]artitioned table, [m]aterialized view. Other values are [i]ndex, [S]equence, [c]omposite type, [t]OAST table\\n      and col.attnum > 0 -- negative numbers are used for system columns such as oid\\n      and not col.attisdropped -- column as not been dropped\\n\\n    order by\\n        sch.nspname,\\n        tbl.relname,\\n        col.attnum\\n\\n  {%- endcall -%}\\n\\n  {{ return(load_result('catalog').table) }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.statement\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4948952,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__get_catalog\": {\n      \"name\": \"postgres__get_catalog\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/catalog.sql\",\n      \"original_file_path\": \"macros/catalog.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__get_catalog\",\n      \"macro_sql\": \"{% macro postgres__get_catalog(information_schema, schemas) -%}\\n  {%- set relations = [] -%}\\n  {%- for schema in schemas -%}\\n    {%- set dummy = relations.append({'schema': schema}) -%}\\n  {%- endfor -%}\\n  {{ return(postgres__get_catalog_relations(information_schema, relations)) }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__get_catalog_relations\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.494899,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__get_relations\": {\n      \"name\": \"postgres__get_relations\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/relations.sql\",\n      \"original_file_path\": \"macros/relations.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__get_relations\",\n      \"macro_sql\": \"{% macro postgres__get_relations() -%}\\n\\n  {#\\n      -- in pg_depend, objid is the dependent, refobjid is the referenced object\\n      --  > a pg_depend entry indicates that the referenced object cannot be\\n      --  > dropped without also dropping the dependent object.\\n  #}\\n\\n  {%- call statement('relations', fetch_result=True) -%}\\n    select distinct\\n        dependent_namespace.nspname as dependent_schema,\\n        dependent_class.relname as dependent_name,\\n        referenced_namespace.nspname as referenced_schema,\\n        referenced_class.relname as referenced_name\\n\\n    -- Query for views: views are entries in pg_class with an entry in pg_rewrite, but we avoid\\n    -- a seq scan on pg_rewrite by leveraging the fact there is an \\\"internal\\\" row in pg_depend for\\n    -- the view...\\n    from pg_class as dependent_class\\n    join pg_namespace as dependent_namespace on dependent_namespace.oid = dependent_class.relnamespace\\n    join pg_depend as dependent_depend on dependent_depend.refobjid = dependent_class.oid\\n        and dependent_depend.classid = 'pg_rewrite'::regclass\\n        and dependent_depend.refclassid = 'pg_class'::regclass\\n        and dependent_depend.deptype = 'i'\\n\\n    -- ... and via pg_depend (that has a row per column, hence the need for \\\"distinct\\\" above, and\\n    -- making sure to exclude the internal row to avoid a view appearing to depend on itself)...\\n    join pg_depend as joining_depend on joining_depend.objid = dependent_depend.objid\\n        and joining_depend.classid = 'pg_rewrite'::regclass\\n        and joining_depend.refclassid = 'pg_class'::regclass\\n        and joining_depend.refobjid != dependent_depend.refobjid\\n\\n    -- ... we can find the tables they query from in pg_class, but excluding system tables. Note we\\n    -- don't need need to exclude _dependent_ system tables, because they only query from other\\n    -- system tables, and so are automatically excluded by excluding _referenced_ system tables\\n    join pg_class as referenced_class on referenced_class.oid = joining_depend.refobjid\\n    join pg_namespace as referenced_namespace on referenced_namespace.oid = referenced_class.relnamespace\\n        and referenced_namespace.nspname != 'information_schema'\\n        and referenced_namespace.nspname not like 'pg\\\\_%'\\n\\n    order by\\n        dependent_schema, dependent_name, referenced_schema, referenced_name;\\n\\n  {%- endcall -%}\\n\\n  {{ return(load_result('relations').table) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.statement\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4949079,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres_get_relations\": {\n      \"name\": \"postgres_get_relations\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/relations.sql\",\n      \"original_file_path\": \"macros/relations.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres_get_relations\",\n      \"macro_sql\": \"{% macro postgres_get_relations() %}\\n  {{ return(postgres__get_relations()) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__get_relations\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.494912,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__create_table_as\": {\n      \"name\": \"postgres__create_table_as\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/adapters.sql\",\n      \"original_file_path\": \"macros/adapters.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__create_table_as\",\n      \"macro_sql\": \"{% macro postgres__create_table_as(temporary, relation, sql) -%}\\n  {%- set unlogged = config.get('unlogged', default=false) -%}\\n  {%- set sql_header = config.get('sql_header', none) -%}\\n\\n  {{ sql_header if sql_header is not none }}\\n\\n  create {% if temporary -%}\\n    temporary\\n  {%- elif unlogged -%}\\n    unlogged\\n  {%- endif %} table {{ relation }}\\n  {% set contract_config = config.get('contract') %}\\n  {% if contract_config.enforced %}\\n    {{ get_assert_columns_equivalent(sql) }}\\n  {% endif -%}\\n  {% if contract_config.enforced and (not temporary) -%}\\n      {{ get_table_columns_and_constraints() }} ;\\n    insert into {{ relation }} (\\n      {{ adapter.dispatch('get_column_names', 'dbt')() }}\\n    )\\n    {%- set sql = get_select_subquery(sql) %}\\n  {% else %}\\n    as\\n  {% endif %}\\n  (\\n    {{ sql }}\\n  );\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.get_assert_columns_equivalent\",\n          \"macro.dbt.get_table_columns_and_constraints\",\n          \"macro.dbt.default__get_column_names\",\n          \"macro.dbt.get_select_subquery\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.494923,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__get_create_index_sql\": {\n      \"name\": \"postgres__get_create_index_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/adapters.sql\",\n      \"original_file_path\": \"macros/adapters.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__get_create_index_sql\",\n      \"macro_sql\": \"{% macro postgres__get_create_index_sql(relation, index_dict) -%}\\n  {%- set index_config = adapter.parse_index(index_dict) -%}\\n  {%- set comma_separated_columns = \\\", \\\".join(index_config.columns) -%}\\n  {%- set index_name = index_config.render(relation) -%}\\n\\n  create {% if index_config.unique -%}\\n    unique\\n  {%- endif %} index if not exists\\n  \\\"{{ index_name }}\\\"\\n  on {{ relation }} {% if index_config.type -%}\\n    using {{ index_config.type }}\\n  {%- endif %}\\n  ({{ comma_separated_columns }})\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.494926,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__create_schema\": {\n      \"name\": \"postgres__create_schema\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/adapters.sql\",\n      \"original_file_path\": \"macros/adapters.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__create_schema\",\n      \"macro_sql\": \"{% macro postgres__create_schema(relation) -%}\\n  {% if relation.database -%}\\n    {{ adapter.verify_database(relation.database) }}\\n  {%- endif -%}\\n  {%- call statement('create_schema') -%}\\n    create schema if not exists {{ relation.without_identifier().include(database=False) }}\\n  {%- endcall -%}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.statement\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4949288,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__drop_schema\": {\n      \"name\": \"postgres__drop_schema\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/adapters.sql\",\n      \"original_file_path\": \"macros/adapters.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__drop_schema\",\n      \"macro_sql\": \"{% macro postgres__drop_schema(relation) -%}\\n  {% if relation.database -%}\\n    {{ adapter.verify_database(relation.database) }}\\n  {%- endif -%}\\n  {%- call statement('drop_schema') -%}\\n    drop schema if exists {{ relation.without_identifier().include(database=False) }} cascade\\n  {%- endcall -%}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.statement\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.494932,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__get_columns_in_relation\": {\n      \"name\": \"postgres__get_columns_in_relation\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/adapters.sql\",\n      \"original_file_path\": \"macros/adapters.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__get_columns_in_relation\",\n      \"macro_sql\": \"{% macro postgres__get_columns_in_relation(relation) -%}\\n  {% call statement('get_columns_in_relation', fetch_result=True) %}\\n      select\\n          column_name,\\n          data_type,\\n          character_maximum_length,\\n          numeric_precision,\\n          numeric_scale\\n\\n      from {{ relation.information_schema('columns') }}\\n      where table_name = '{{ relation.identifier }}'\\n        {% if relation.schema %}\\n        and table_schema = '{{ relation.schema }}'\\n        {% endif %}\\n      order by ordinal_position\\n\\n  {% endcall %}\\n  {% set table = load_result('get_columns_in_relation').table %}\\n  {{ return(sql_convert_columns_in_relation(table)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.statement\",\n          \"macro.dbt.sql_convert_columns_in_relation\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4949381,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__list_relations_without_caching\": {\n      \"name\": \"postgres__list_relations_without_caching\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/adapters.sql\",\n      \"original_file_path\": \"macros/adapters.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__list_relations_without_caching\",\n      \"macro_sql\": \"{% macro postgres__list_relations_without_caching(schema_relation) %}\\n  {% call statement('list_relations_without_caching', fetch_result=True) -%}\\n    select\\n      '{{ schema_relation.database }}' as database,\\n      tablename as name,\\n      schemaname as schema,\\n      'table' as type\\n    from pg_tables\\n    where schemaname ilike '{{ schema_relation.schema }}'\\n    union all\\n    select\\n      '{{ schema_relation.database }}' as database,\\n      viewname as name,\\n      schemaname as schema,\\n      'view' as type\\n    from pg_views\\n    where schemaname ilike '{{ schema_relation.schema }}'\\n    union all\\n    select\\n      '{{ schema_relation.database }}' as database,\\n      matviewname as name,\\n      schemaname as schema,\\n      'materialized_view' as type\\n    from pg_matviews\\n    where schemaname ilike '{{ schema_relation.schema }}'\\n  {% endcall %}\\n  {{ return(load_result('list_relations_without_caching').table) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.statement\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.494941,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__information_schema_name\": {\n      \"name\": \"postgres__information_schema_name\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/adapters.sql\",\n      \"original_file_path\": \"macros/adapters.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__information_schema_name\",\n      \"macro_sql\": \"{% macro postgres__information_schema_name(database) -%}\\n  {% if database_name -%}\\n    {{ adapter.verify_database(database_name) }}\\n  {%- endif -%}\\n  information_schema\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.494977,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__list_schemas\": {\n      \"name\": \"postgres__list_schemas\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/adapters.sql\",\n      \"original_file_path\": \"macros/adapters.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__list_schemas\",\n      \"macro_sql\": \"{% macro postgres__list_schemas(database) %}\\n  {% if database -%}\\n    {{ adapter.verify_database(database) }}\\n  {%- endif -%}\\n  {% call statement('list_schemas', fetch_result=True, auto_begin=False) %}\\n    select distinct nspname from pg_namespace\\n  {% endcall %}\\n  {{ return(load_result('list_schemas').table) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.statement\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.494981,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__check_schema_exists\": {\n      \"name\": \"postgres__check_schema_exists\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/adapters.sql\",\n      \"original_file_path\": \"macros/adapters.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__check_schema_exists\",\n      \"macro_sql\": \"{% macro postgres__check_schema_exists(information_schema, schema) -%}\\n  {% if information_schema.database -%}\\n    {{ adapter.verify_database(information_schema.database) }}\\n  {%- endif -%}\\n  {% call statement('check_schema_exists', fetch_result=True, auto_begin=False) %}\\n    select count(*) from pg_namespace where nspname = '{{ schema }}'\\n  {% endcall %}\\n  {{ return(load_result('check_schema_exists').table) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.statement\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.494984,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__make_relation_with_suffix\": {\n      \"name\": \"postgres__make_relation_with_suffix\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/adapters.sql\",\n      \"original_file_path\": \"macros/adapters.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__make_relation_with_suffix\",\n      \"macro_sql\": \"{% macro postgres__make_relation_with_suffix(base_relation, suffix, dstring) %}\\n    {% if dstring %}\\n      {% set dt = modules.datetime.datetime.now() %}\\n      {% set dtstring = dt.strftime(\\\"%H%M%S%f\\\") %}\\n      {% set suffix = suffix ~ dtstring %}\\n    {% endif %}\\n    {% set suffix_length = suffix|length %}\\n    {% set relation_max_name_length = base_relation.relation_max_name_length() %}\\n    {% if suffix_length > relation_max_name_length %}\\n        {% do exceptions.raise_compiler_error('Relation suffix is too long (' ~ suffix_length ~ ' characters). Maximum length is ' ~ relation_max_name_length ~ ' characters.') %}\\n    {% endif %}\\n    {% set identifier = base_relation.identifier[:relation_max_name_length - suffix_length] ~ suffix %}\\n\\n    {{ return(base_relation.incorporate(path={\\\"identifier\\\": identifier })) }}\\n\\n  {% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4949892,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__make_intermediate_relation\": {\n      \"name\": \"postgres__make_intermediate_relation\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/adapters.sql\",\n      \"original_file_path\": \"macros/adapters.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__make_intermediate_relation\",\n      \"macro_sql\": \"{% macro postgres__make_intermediate_relation(base_relation, suffix) %}\\n    {{ return(postgres__make_relation_with_suffix(base_relation, suffix, dstring=False)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__make_relation_with_suffix\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.494993,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__make_temp_relation\": {\n      \"name\": \"postgres__make_temp_relation\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/adapters.sql\",\n      \"original_file_path\": \"macros/adapters.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__make_temp_relation\",\n      \"macro_sql\": \"{% macro postgres__make_temp_relation(base_relation, suffix) %}\\n    {% set temp_relation = postgres__make_relation_with_suffix(base_relation, suffix, dstring=True) %}\\n    {{ return(temp_relation.incorporate(path={\\\"schema\\\": none,\\n                                              \\\"database\\\": none})) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__make_relation_with_suffix\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4950001,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__make_backup_relation\": {\n      \"name\": \"postgres__make_backup_relation\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/adapters.sql\",\n      \"original_file_path\": \"macros/adapters.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__make_backup_relation\",\n      \"macro_sql\": \"{% macro postgres__make_backup_relation(base_relation, backup_relation_type, suffix) %}\\n    {% set backup_relation = postgres__make_relation_with_suffix(base_relation, suffix, dstring=False) %}\\n    {{ return(backup_relation.incorporate(type=backup_relation_type)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__make_relation_with_suffix\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495003,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres_escape_comment\": {\n      \"name\": \"postgres_escape_comment\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/adapters.sql\",\n      \"original_file_path\": \"macros/adapters.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres_escape_comment\",\n      \"macro_sql\": \"{% macro postgres_escape_comment(comment) -%}\\n  {% if comment is not string %}\\n    {% do exceptions.raise_compiler_error('cannot escape a non-string: ' ~ comment) %}\\n  {% endif %}\\n  {%- set magic = '$dbt_comment_literal_block$' -%}\\n  {%- if magic in comment -%}\\n    {%- do exceptions.raise_compiler_error('The string ' ~ magic ~ ' is not allowed in comments.') -%}\\n  {%- endif -%}\\n  {{ magic }}{{ comment }}{{ magic }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495008,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__alter_relation_comment\": {\n      \"name\": \"postgres__alter_relation_comment\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/adapters.sql\",\n      \"original_file_path\": \"macros/adapters.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__alter_relation_comment\",\n      \"macro_sql\": \"{% macro postgres__alter_relation_comment(relation, comment) %}\\n  {% set escaped_comment = postgres_escape_comment(comment) %}\\n  {% if relation.type == 'materialized_view' -%}\\n    {% set relation_type = \\\"materialized view\\\" %}\\n  {%- else -%}\\n    {%- set relation_type = relation.type -%}\\n  {%- endif -%}\\n  comment on {{ relation_type }} {{ relation }} is {{ escaped_comment }};\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres_escape_comment\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4950101,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__alter_column_comment\": {\n      \"name\": \"postgres__alter_column_comment\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/adapters.sql\",\n      \"original_file_path\": \"macros/adapters.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__alter_column_comment\",\n      \"macro_sql\": \"{% macro postgres__alter_column_comment(relation, column_dict) %}\\n  {% set existing_columns = adapter.get_columns_in_relation(relation) | map(attribute=\\\"name\\\") | list %}\\n  {% for column_name in column_dict if (column_name in existing_columns) %}\\n    {% set comment = column_dict[column_name]['description'] %}\\n    {% set escaped_comment = postgres_escape_comment(comment) %}\\n    comment on column {{ relation }}.{{ adapter.quote(column_name) if column_dict[column_name]['quote'] else column_name }} is {{ escaped_comment }};\\n  {% endfor %}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres_escape_comment\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4950132,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__get_show_grant_sql\": {\n      \"name\": \"postgres__get_show_grant_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/adapters.sql\",\n      \"original_file_path\": \"macros/adapters.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__get_show_grant_sql\",\n      \"macro_sql\": \"\\n\\n{%- macro postgres__get_show_grant_sql(relation) -%}\\n  select grantee, privilege_type\\n  from {{ relation.information_schema('role_table_grants') }}\\n      where grantor = current_role\\n        and grantee != current_role\\n        and table_schema = '{{ relation.schema }}'\\n        and table_name = '{{ relation.identifier }}'\\n{%- endmacro -%}\\n\\n\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495018,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__copy_grants\": {\n      \"name\": \"postgres__copy_grants\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/adapters.sql\",\n      \"original_file_path\": \"macros/adapters.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__copy_grants\",\n      \"macro_sql\": \"{% macro postgres__copy_grants() %}\\n    {{ return(False) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495021,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__get_show_indexes_sql\": {\n      \"name\": \"postgres__get_show_indexes_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/adapters.sql\",\n      \"original_file_path\": \"macros/adapters.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__get_show_indexes_sql\",\n      \"macro_sql\": \"{% macro postgres__get_show_indexes_sql(relation) %}\\n    select\\n        i.relname                                   as name,\\n        m.amname                                    as method,\\n        ix.indisunique                              as \\\"unique\\\",\\n        array_to_string(array_agg(a.attname), ',')  as column_names\\n    from pg_index ix\\n    join pg_class i\\n        on i.oid = ix.indexrelid\\n    join pg_am m\\n        on m.oid=i.relam\\n    join pg_class t\\n        on t.oid = ix.indrelid\\n    join pg_namespace n\\n        on n.oid = t.relnamespace\\n    join pg_attribute a\\n        on a.attrelid = t.oid\\n        and a.attnum = ANY(ix.indkey)\\n    where t.relname = '{{ relation.identifier }}'\\n      and n.nspname = '{{ relation.schema }}'\\n      and t.relkind in ('r', 'm')\\n    group by 1, 2, 3\\n    order by 1, 2, 3\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4950242,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__get_drop_index_sql\": {\n      \"name\": \"postgres__get_drop_index_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/adapters.sql\",\n      \"original_file_path\": \"macros/adapters.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__get_drop_index_sql\",\n      \"macro_sql\": \"\\n\\n\\n{%- macro postgres__get_drop_index_sql(relation, index_name) -%}\\n    drop index if exists \\\"{{ relation.schema }}\\\".\\\"{{ index_name }}\\\"\\n{%- endmacro -%}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4950268,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__get_incremental_default_sql\": {\n      \"name\": \"postgres__get_incremental_default_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/materializations/incremental_strategies.sql\",\n      \"original_file_path\": \"macros/materializations/incremental_strategies.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__get_incremental_default_sql\",\n      \"macro_sql\": \"{% macro postgres__get_incremental_default_sql(arg_dict) %}\\n\\n  {% if arg_dict[\\\"unique_key\\\"] %}\\n    {% do return(get_incremental_delete_insert_sql(arg_dict)) %}\\n  {% else %}\\n    {% do return(get_incremental_append_sql(arg_dict)) %}\\n  {% endif %}\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.get_incremental_delete_insert_sql\",\n          \"macro.dbt.get_incremental_append_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495036,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__get_incremental_microbatch_sql\": {\n      \"name\": \"postgres__get_incremental_microbatch_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/materializations/incremental_strategies.sql\",\n      \"original_file_path\": \"macros/materializations/incremental_strategies.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__get_incremental_microbatch_sql\",\n      \"macro_sql\": \"{% macro postgres__get_incremental_microbatch_sql(arg_dict) %}\\n\\n  {% if arg_dict[\\\"unique_key\\\"] %}\\n    {% do return(adapter.dispatch('get_incremental_merge_sql', 'dbt')(arg_dict)) %}\\n  {% else %}\\n    {{ exceptions.raise_compiler_error(\\\"dbt-postgres 'microbatch' requires a `unique_key` config\\\") }}\\n  {% endif %}\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.get_incremental_merge_sql\",\n          \"macro.dbt.default__get_incremental_merge_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495039,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__snapshot_merge_sql\": {\n      \"name\": \"postgres__snapshot_merge_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/materializations/snapshot_merge.sql\",\n      \"original_file_path\": \"macros/materializations/snapshot_merge.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__snapshot_merge_sql\",\n      \"macro_sql\": \"{% macro postgres__snapshot_merge_sql(target, source, insert_cols) -%}\\n    {%- set insert_cols_csv = insert_cols | join(', ') -%}\\n\\n    {%- set columns = config.get(\\\"snapshot_table_column_names\\\") or get_snapshot_table_column_names() -%}\\n\\n    update {{ target }}\\n    set {{ columns.dbt_valid_to }} = DBT_INTERNAL_SOURCE.{{ columns.dbt_valid_to }}\\n    from {{ source }} as DBT_INTERNAL_SOURCE\\n    where DBT_INTERNAL_SOURCE.{{ columns.dbt_scd_id }}::text = {{ target }}.{{ columns.dbt_scd_id }}::text\\n      and DBT_INTERNAL_SOURCE.dbt_change_type::text in ('update'::text, 'delete'::text)\\n      {% if config.get(\\\"dbt_valid_to_current\\\") %}\\n        and ({{ target }}.{{ columns.dbt_valid_to }} = {{ config.get('dbt_valid_to_current') }} or {{ target }}.{{ columns.dbt_valid_to }} is null);\\n      {% else %}\\n        and {{ target }}.{{ columns.dbt_valid_to }} is null;\\n      {% endif %}\\n\\n\\n    insert into {{ target }} ({{ insert_cols_csv }})\\n    select {% for column in insert_cols -%}\\n        DBT_INTERNAL_SOURCE.{{ column }} {%- if not loop.last %}, {%- endif %}\\n    {%- endfor %}\\n    from {{ source }} as DBT_INTERNAL_SOURCE\\n    where DBT_INTERNAL_SOURCE.dbt_change_type::text = 'insert'::text;\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.get_snapshot_table_column_names\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495046,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__drop_materialized_view\": {\n      \"name\": \"postgres__drop_materialized_view\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/relations/materialized_view/drop.sql\",\n      \"original_file_path\": \"macros/relations/materialized_view/drop.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__drop_materialized_view\",\n      \"macro_sql\": \"{% macro postgres__drop_materialized_view(relation) -%}\\n    drop materialized view if exists {{ relation }} cascade\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495053,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__describe_materialized_view\": {\n      \"name\": \"postgres__describe_materialized_view\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/relations/materialized_view/describe.sql\",\n      \"original_file_path\": \"macros/relations/materialized_view/describe.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__describe_materialized_view\",\n      \"macro_sql\": \"{% macro postgres__describe_materialized_view(relation) %}\\n    -- for now just get the indexes, we don't need the name or the query yet\\n    {% set _indexes = run_query(get_show_indexes_sql(relation)) %}\\n    {% do return({'indexes': _indexes}) %}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.run_query\",\n          \"macro.dbt.get_show_indexes_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495059,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__refresh_materialized_view\": {\n      \"name\": \"postgres__refresh_materialized_view\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/relations/materialized_view/refresh.sql\",\n      \"original_file_path\": \"macros/relations/materialized_view/refresh.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__refresh_materialized_view\",\n      \"macro_sql\": \"{% macro postgres__refresh_materialized_view(relation) %}\\n    refresh materialized view {{ relation }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495064,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__get_rename_materialized_view_sql\": {\n      \"name\": \"postgres__get_rename_materialized_view_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/relations/materialized_view/rename.sql\",\n      \"original_file_path\": \"macros/relations/materialized_view/rename.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__get_rename_materialized_view_sql\",\n      \"macro_sql\": \"{% macro postgres__get_rename_materialized_view_sql(relation, new_name) %}\\n    alter materialized view {{ relation }} rename to {{ new_name }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495074,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__get_alter_materialized_view_as_sql\": {\n      \"name\": \"postgres__get_alter_materialized_view_as_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/relations/materialized_view/alter.sql\",\n      \"original_file_path\": \"macros/relations/materialized_view/alter.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__get_alter_materialized_view_as_sql\",\n      \"macro_sql\": \"{% macro postgres__get_alter_materialized_view_as_sql(\\n    relation,\\n    configuration_changes,\\n    sql,\\n    existing_relation,\\n    backup_relation,\\n    intermediate_relation\\n) %}\\n\\n    -- apply a full refresh immediately if needed\\n    {% if configuration_changes.requires_full_refresh %}\\n\\n        {{ get_replace_sql(existing_relation, relation, sql) }}\\n\\n    -- otherwise apply individual changes as needed\\n    {% else %}\\n\\n        {{ postgres__update_indexes_on_materialized_view(relation, configuration_changes.indexes) }}\\n\\n    {%- endif -%}\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.get_replace_sql\",\n          \"macro.dbt_postgres.postgres__update_indexes_on_materialized_view\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.49508,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__update_indexes_on_materialized_view\": {\n      \"name\": \"postgres__update_indexes_on_materialized_view\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/relations/materialized_view/alter.sql\",\n      \"original_file_path\": \"macros/relations/materialized_view/alter.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__update_indexes_on_materialized_view\",\n      \"macro_sql\": \"\\n\\n\\n{%- macro postgres__update_indexes_on_materialized_view(relation, index_changes) -%}\\n    {{- log(\\\"Applying UPDATE INDEXES to: \\\" ~ relation) -}}\\n\\n    {%- for _index_change in index_changes -%}\\n        {%- set _index = _index_change.context -%}\\n\\n        {%- if _index_change.action == \\\"drop\\\" -%}\\n\\n            {{ postgres__get_drop_index_sql(relation, _index.name) }}\\n\\n        {%- elif _index_change.action == \\\"create\\\" -%}\\n\\n            {{ postgres__get_create_index_sql(relation, _index.as_node_config) }}\\n\\n        {%- endif -%}\\n\\t{{ ';' if not loop.last else \\\"\\\" }}\\n\\n    {%- endfor -%}\\n\\n{%- endmacro -%}\\n\\n\\n\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__get_drop_index_sql\",\n          \"macro.dbt_postgres.postgres__get_create_index_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495084,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__get_materialized_view_configuration_changes\": {\n      \"name\": \"postgres__get_materialized_view_configuration_changes\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/relations/materialized_view/alter.sql\",\n      \"original_file_path\": \"macros/relations/materialized_view/alter.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__get_materialized_view_configuration_changes\",\n      \"macro_sql\": \"{% macro postgres__get_materialized_view_configuration_changes(existing_relation, new_config) %}\\n    {% set _existing_materialized_view = postgres__describe_materialized_view(existing_relation) %}\\n    {% set _configuration_changes = existing_relation.get_materialized_view_config_change_collection(_existing_materialized_view, new_config.model) %}\\n    {% do return(_configuration_changes) %}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__describe_materialized_view\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4950888,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__get_create_materialized_view_as_sql\": {\n      \"name\": \"postgres__get_create_materialized_view_as_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/relations/materialized_view/create.sql\",\n      \"original_file_path\": \"macros/relations/materialized_view/create.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__get_create_materialized_view_as_sql\",\n      \"macro_sql\": \"{% macro postgres__get_create_materialized_view_as_sql(relation, sql) %}\\n    create materialized view if not exists {{ relation }} as {{ sql }};\\n\\n    {% for _index_dict in config.get('indexes', []) -%}\\n        {{- get_create_index_sql(relation, _index_dict) -}}{{ ';' if not loop.last else \\\"\\\" }}\\n    {%- endfor -%}\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.get_create_index_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495095,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__drop_table\": {\n      \"name\": \"postgres__drop_table\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/relations/table/drop.sql\",\n      \"original_file_path\": \"macros/relations/table/drop.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__drop_table\",\n      \"macro_sql\": \"{% macro postgres__drop_table(relation) -%}\\n    drop table if exists {{ relation }} cascade\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495102,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__get_replace_table_sql\": {\n      \"name\": \"postgres__get_replace_table_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/relations/table/replace.sql\",\n      \"original_file_path\": \"macros/relations/table/replace.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__get_replace_table_sql\",\n      \"macro_sql\": \"{% macro postgres__get_replace_table_sql(relation, sql) -%}\\n\\n    {%- set sql_header = config.get('sql_header', none) -%}\\n    {{ sql_header if sql_header is not none }}\\n\\n    create or replace table {{ relation }}\\n        {% set contract_config = config.get('contract') %}\\n        {% if contract_config.enforced %}\\n            {{ get_assert_columns_equivalent(sql) }}\\n            {{ get_table_columns_and_constraints() }}\\n            {%- set sql = get_select_subquery(sql) %}\\n        {% endif %}\\n    as (\\n        {{ sql }}\\n    );\\n\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.get_assert_columns_equivalent\",\n          \"macro.dbt.get_table_columns_and_constraints\",\n          \"macro.dbt.get_select_subquery\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495109,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__get_rename_table_sql\": {\n      \"name\": \"postgres__get_rename_table_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/relations/table/rename.sql\",\n      \"original_file_path\": \"macros/relations/table/rename.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__get_rename_table_sql\",\n      \"macro_sql\": \"{% macro postgres__get_rename_table_sql(relation, new_name) %}\\n    alter table {{ relation }} rename to {{ new_name }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495114,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__drop_view\": {\n      \"name\": \"postgres__drop_view\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/relations/view/drop.sql\",\n      \"original_file_path\": \"macros/relations/view/drop.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__drop_view\",\n      \"macro_sql\": \"{% macro postgres__drop_view(relation) -%}\\n    drop view if exists {{ relation }} cascade\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4951198,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__get_replace_view_sql\": {\n      \"name\": \"postgres__get_replace_view_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/relations/view/replace.sql\",\n      \"original_file_path\": \"macros/relations/view/replace.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__get_replace_view_sql\",\n      \"macro_sql\": \"{% macro postgres__get_replace_view_sql(relation, sql) -%}\\n\\n    {%- set sql_header = config.get('sql_header', none) -%}\\n    {{ sql_header if sql_header is not none }}\\n\\n    create or replace view {{ relation }}\\n        {% set contract_config = config.get('contract') %}\\n        {% if contract_config.enforced %}\\n            {{ get_assert_columns_equivalent(sql) }}\\n        {%- endif %}\\n    as (\\n        {{ sql }}\\n    );\\n\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.get_assert_columns_equivalent\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495129,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__get_rename_view_sql\": {\n      \"name\": \"postgres__get_rename_view_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/relations/view/rename.sql\",\n      \"original_file_path\": \"macros/relations/view/rename.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__get_rename_view_sql\",\n      \"macro_sql\": \"{% macro postgres__get_rename_view_sql(relation, new_name) %}\\n    alter view {{ relation }} rename to {{ new_name }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495135,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__dateadd\": {\n      \"name\": \"postgres__dateadd\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/utils/dateadd.sql\",\n      \"original_file_path\": \"macros/utils/dateadd.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__dateadd\",\n      \"macro_sql\": \"{% macro postgres__dateadd(datepart, interval, from_date_or_timestamp) %}\\n\\n    {{ from_date_or_timestamp }} + ((interval '1 {{ datepart }}') * ({{ interval }}))\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495144,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__listagg\": {\n      \"name\": \"postgres__listagg\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/utils/listagg.sql\",\n      \"original_file_path\": \"macros/utils/listagg.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__listagg\",\n      \"macro_sql\": \"{% macro postgres__listagg(measure, delimiter_text, order_by_clause, limit_num) -%}\\n\\n    {% if limit_num -%}\\n    array_to_string(\\n        (array_agg(\\n            {{ measure }}\\n            {% if order_by_clause -%}\\n            {{ order_by_clause }}\\n            {%- endif %}\\n        ))[1:{{ limit_num }}],\\n        {{ delimiter_text }}\\n        )\\n    {%- else %}\\n    string_agg(\\n        {{ measure }},\\n        {{ delimiter_text }}\\n        {% if order_by_clause -%}\\n        {{ order_by_clause }}\\n        {%- endif %}\\n        )\\n    {%- endif %}\\n\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495154,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__datediff\": {\n      \"name\": \"postgres__datediff\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/utils/datediff.sql\",\n      \"original_file_path\": \"macros/utils/datediff.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__datediff\",\n      \"macro_sql\": \"{% macro postgres__datediff(first_date, second_date, datepart) -%}\\n\\n    {% if datepart == 'year' %}\\n        (date_part('year', ({{second_date}})::date) - date_part('year', ({{first_date}})::date))\\n    {% elif datepart == 'quarter' %}\\n        ({{ datediff(first_date, second_date, 'year') }} * 4 + date_part('quarter', ({{second_date}})::date) - date_part('quarter', ({{first_date}})::date))\\n    {% elif datepart == 'month' %}\\n        ({{ datediff(first_date, second_date, 'year') }} * 12 + date_part('month', ({{second_date}})::date) - date_part('month', ({{first_date}})::date))\\n    {% elif datepart == 'day' %}\\n        (({{second_date}})::date - ({{first_date}})::date)\\n    {% elif datepart == 'week' %}\\n        ({{ datediff(first_date, second_date, 'day') }} / 7 + case\\n            when date_part('dow', ({{first_date}})::timestamp) <= date_part('dow', ({{second_date}})::timestamp) then\\n                case when {{first_date}} <= {{second_date}} then 0 else -1 end\\n            else\\n                case when {{first_date}} <= {{second_date}} then 1 else 0 end\\n        end)\\n    {% elif datepart == 'hour' %}\\n        ({{ datediff(first_date, second_date, 'day') }} * 24 + date_part('hour', ({{second_date}})::timestamp) - date_part('hour', ({{first_date}})::timestamp))\\n    {% elif datepart == 'minute' %}\\n        ({{ datediff(first_date, second_date, 'hour') }} * 60 + date_part('minute', ({{second_date}})::timestamp) - date_part('minute', ({{first_date}})::timestamp))\\n    {% elif datepart == 'second' %}\\n        ({{ datediff(first_date, second_date, 'minute') }} * 60 + floor(date_part('second', ({{second_date}})::timestamp)) - floor(date_part('second', ({{first_date}})::timestamp)))\\n    {% elif datepart == 'millisecond' %}\\n        ({{ datediff(first_date, second_date, 'minute') }} * 60000 + floor(date_part('millisecond', ({{second_date}})::timestamp)) - floor(date_part('millisecond', ({{first_date}})::timestamp)))\\n    {% elif datepart == 'microsecond' %}\\n        ({{ datediff(first_date, second_date, 'minute') }} * 60000000 + floor(date_part('microsecond', ({{second_date}})::timestamp)) - floor(date_part('microsecond', ({{first_date}})::timestamp)))\\n    {% else %}\\n        {{ exceptions.raise_compiler_error(\\\"Unsupported datepart for macro datediff in postgres: {!r}\\\".format(datepart)) }}\\n    {% endif %}\\n\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.datediff\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495161,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__any_value\": {\n      \"name\": \"postgres__any_value\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/utils/any_value.sql\",\n      \"original_file_path\": \"macros/utils/any_value.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__any_value\",\n      \"macro_sql\": \"{% macro postgres__any_value(expression) -%}\\n\\n    min({{ expression }})\\n\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495168,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__last_day\": {\n      \"name\": \"postgres__last_day\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/utils/last_day.sql\",\n      \"original_file_path\": \"macros/utils/last_day.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__last_day\",\n      \"macro_sql\": \"{% macro postgres__last_day(date, datepart) -%}\\n\\n    {%- if datepart == 'quarter' -%}\\n    -- postgres dateadd does not support quarter interval.\\n    cast(\\n        {{dbt.dateadd('day', '-1',\\n        dbt.dateadd('month', '3', dbt.date_trunc(datepart, date))\\n        )}}\\n        as date)\\n    {%- else -%}\\n    {{dbt.default_last_day(date, datepart)}}\\n    {%- endif -%}\\n\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.dateadd\",\n          \"macro.dbt.date_trunc\",\n          \"macro.dbt.default_last_day\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495174,\n      \"supported_languages\": null\n    },\n    \"macro.dbt_postgres.postgres__split_part\": {\n      \"name\": \"postgres__split_part\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt_postgres\",\n      \"path\": \"macros/utils/split_part.sql\",\n      \"original_file_path\": \"macros/utils/split_part.sql\",\n      \"unique_id\": \"macro.dbt_postgres.postgres__split_part\",\n      \"macro_sql\": \"{% macro postgres__split_part(string_text, delimiter_text, part_number) %}\\n\\n  {% if part_number >= 0 %}\\n    {{ dbt.default__split_part(string_text, delimiter_text, part_number) }}\\n  {% else %}\\n    {{ dbt._split_part_negative(string_text, delimiter_text, part_number) }}\\n  {% endif %}\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__split_part\",\n          \"macro.dbt._split_part_negative\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4951801,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.run_hooks\": {\n      \"name\": \"run_hooks\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/hooks.sql\",\n      \"original_file_path\": \"macros/materializations/hooks.sql\",\n      \"unique_id\": \"macro.dbt.run_hooks\",\n      \"macro_sql\": \"{% macro run_hooks(hooks, inside_transaction=True) %}\\n  {% for hook in hooks | selectattr('transaction', 'equalto', inside_transaction)  %}\\n    {% if not inside_transaction and loop.first %}\\n      {% call statement(auto_begin=inside_transaction) %}\\n        commit;\\n      {% endcall %}\\n    {% endif %}\\n    {% set rendered = render(hook.get('sql')) | trim %}\\n    {% if (rendered | length) > 0 %}\\n      {% call statement(auto_begin=inside_transaction) %}\\n        {{ rendered }}\\n      {% endcall %}\\n    {% endif %}\\n  {% endfor %}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.statement\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495187,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.make_hook_config\": {\n      \"name\": \"make_hook_config\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/hooks.sql\",\n      \"original_file_path\": \"macros/materializations/hooks.sql\",\n      \"unique_id\": \"macro.dbt.make_hook_config\",\n      \"macro_sql\": \"{% macro make_hook_config(sql, inside_transaction) %}\\n    {{ tojson({\\\"sql\\\": sql, \\\"transaction\\\": inside_transaction}) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.49519,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.before_begin\": {\n      \"name\": \"before_begin\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/hooks.sql\",\n      \"original_file_path\": \"macros/materializations/hooks.sql\",\n      \"unique_id\": \"macro.dbt.before_begin\",\n      \"macro_sql\": \"{% macro before_begin(sql) %}\\n    {{ make_hook_config(sql, inside_transaction=False) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.make_hook_config\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495193,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.in_transaction\": {\n      \"name\": \"in_transaction\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/hooks.sql\",\n      \"original_file_path\": \"macros/materializations/hooks.sql\",\n      \"unique_id\": \"macro.dbt.in_transaction\",\n      \"macro_sql\": \"{% macro in_transaction(sql) %}\\n    {{ make_hook_config(sql, inside_transaction=True) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.make_hook_config\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4951968,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.after_commit\": {\n      \"name\": \"after_commit\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/hooks.sql\",\n      \"original_file_path\": \"macros/materializations/hooks.sql\",\n      \"unique_id\": \"macro.dbt.after_commit\",\n      \"macro_sql\": \"{% macro after_commit(sql) %}\\n    {{ make_hook_config(sql, inside_transaction=False) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.make_hook_config\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4952,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.set_sql_header\": {\n      \"name\": \"set_sql_header\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/configs.sql\",\n      \"original_file_path\": \"macros/materializations/configs.sql\",\n      \"unique_id\": \"macro.dbt.set_sql_header\",\n      \"macro_sql\": \"{% macro set_sql_header(config) -%}\\n  {{ config.set('sql_header', caller()) }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4952059,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.should_full_refresh\": {\n      \"name\": \"should_full_refresh\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/configs.sql\",\n      \"original_file_path\": \"macros/materializations/configs.sql\",\n      \"unique_id\": \"macro.dbt.should_full_refresh\",\n      \"macro_sql\": \"{% macro should_full_refresh() %}\\n  {% set config_full_refresh = config.get('full_refresh') %}\\n  {% if config_full_refresh is none %}\\n    {% set config_full_refresh = flags.FULL_REFRESH %}\\n  {% endif %}\\n  {% do return(config_full_refresh) %}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495209,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.should_store_failures\": {\n      \"name\": \"should_store_failures\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/configs.sql\",\n      \"original_file_path\": \"macros/materializations/configs.sql\",\n      \"unique_id\": \"macro.dbt.should_store_failures\",\n      \"macro_sql\": \"{% macro should_store_failures() %}\\n  {% set config_store_failures = config.get('store_failures') %}\\n  {% if config_store_failures is none %}\\n    {% set config_store_failures = flags.STORE_FAILURES %}\\n  {% endif %}\\n  {% do return(config_store_failures) %}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495212,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.snapshot_merge_sql\": {\n      \"name\": \"snapshot_merge_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/snapshots/snapshot_merge.sql\",\n      \"original_file_path\": \"macros/materializations/snapshots/snapshot_merge.sql\",\n      \"unique_id\": \"macro.dbt.snapshot_merge_sql\",\n      \"macro_sql\": \"{% macro snapshot_merge_sql(target, source, insert_cols) -%}\\n  {{ adapter.dispatch('snapshot_merge_sql', 'dbt')(target, source, insert_cols) }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__snapshot_merge_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495222,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__snapshot_merge_sql\": {\n      \"name\": \"default__snapshot_merge_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/snapshots/snapshot_merge.sql\",\n      \"original_file_path\": \"macros/materializations/snapshots/snapshot_merge.sql\",\n      \"unique_id\": \"macro.dbt.default__snapshot_merge_sql\",\n      \"macro_sql\": \"{% macro default__snapshot_merge_sql(target, source, insert_cols) -%}\\n    {%- set insert_cols_csv = insert_cols | join(', ') -%}\\n\\n    {%- set columns = config.get(\\\"snapshot_table_column_names\\\") or get_snapshot_table_column_names() -%}\\n\\n    merge into {{ target.render() }} as DBT_INTERNAL_DEST\\n    using {{ source }} as DBT_INTERNAL_SOURCE\\n    on DBT_INTERNAL_SOURCE.{{ columns.dbt_scd_id }} = DBT_INTERNAL_DEST.{{ columns.dbt_scd_id }}\\n\\n    when matched\\n     {% if config.get(\\\"dbt_valid_to_current\\\") %}\\n\\t{% set source_unique_key = (\\\"DBT_INTERNAL_DEST.\\\" ~ columns.dbt_valid_to) | trim %}\\n\\t{% set target_unique_key = config.get('dbt_valid_to_current') | trim %}\\n\\tand ({{ equals(source_unique_key, target_unique_key) }} or {{ source_unique_key }} is null)\\n\\n     {% else %}\\n       and DBT_INTERNAL_DEST.{{ columns.dbt_valid_to }} is null\\n     {% endif %}\\n     and DBT_INTERNAL_SOURCE.dbt_change_type in ('update', 'delete')\\n        then update\\n        set {{ columns.dbt_valid_to }} = DBT_INTERNAL_SOURCE.{{ columns.dbt_valid_to }}\\n\\n    when not matched\\n     and DBT_INTERNAL_SOURCE.dbt_change_type = 'insert'\\n        then insert ({{ insert_cols_csv }})\\n        values ({{ insert_cols_csv }})\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.get_snapshot_table_column_names\",\n          \"macro.dbt.equals\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4952261,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.strategy_dispatch\": {\n      \"name\": \"strategy_dispatch\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/snapshots/strategies.sql\",\n      \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\",\n      \"unique_id\": \"macro.dbt.strategy_dispatch\",\n      \"macro_sql\": \"{% macro strategy_dispatch(name) -%}\\n{% set original_name = name %}\\n  {% if '.' in name %}\\n    {% set package_name, name = name.split(\\\".\\\", 1) %}\\n  {% else %}\\n    {% set package_name = none %}\\n  {% endif %}\\n\\n  {% if package_name is none %}\\n    {% set package_context = context %}\\n  {% elif package_name in context %}\\n    {% set package_context = context[package_name] %}\\n  {% else %}\\n    {% set error_msg %}\\n        Could not find package '{{package_name}}', called with '{{original_name}}'\\n    {% endset %}\\n    {{ exceptions.raise_compiler_error(error_msg | trim) }}\\n  {% endif %}\\n\\n  {%- set search_name = 'snapshot_' ~ name ~ '_strategy' -%}\\n\\n  {% if search_name not in package_context %}\\n    {% set error_msg %}\\n        The specified strategy macro '{{name}}' was not found in package '{{ package_name }}'\\n    {% endset %}\\n    {{ exceptions.raise_compiler_error(error_msg | trim) }}\\n  {% endif %}\\n  {{ return(package_context[search_name]) }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4952419,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.snapshot_hash_arguments\": {\n      \"name\": \"snapshot_hash_arguments\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/snapshots/strategies.sql\",\n      \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\",\n      \"unique_id\": \"macro.dbt.snapshot_hash_arguments\",\n      \"macro_sql\": \"{% macro snapshot_hash_arguments(args) -%}\\n  {{ adapter.dispatch('snapshot_hash_arguments', 'dbt')(args) }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__snapshot_hash_arguments\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495244,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__snapshot_hash_arguments\": {\n      \"name\": \"default__snapshot_hash_arguments\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/snapshots/strategies.sql\",\n      \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\",\n      \"unique_id\": \"macro.dbt.default__snapshot_hash_arguments\",\n      \"macro_sql\": \"{% macro default__snapshot_hash_arguments(args) -%}\\n    md5({%- for arg in args -%}\\n        coalesce(cast({{ arg }} as varchar ), '')\\n        {% if not loop.last %} || '|' || {% endif %}\\n    {%- endfor -%})\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4952478,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.snapshot_timestamp_strategy\": {\n      \"name\": \"snapshot_timestamp_strategy\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/snapshots/strategies.sql\",\n      \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\",\n      \"unique_id\": \"macro.dbt.snapshot_timestamp_strategy\",\n      \"macro_sql\": \"{% macro snapshot_timestamp_strategy(node, snapshotted_rel, current_rel, model_config, target_exists) %}\\n    {# The model_config parameter is no longer used, but is passed in anyway for compatibility. #}\\n    {% set primary_key = config.get('unique_key') %}\\n    {% set updated_at = config.get('updated_at') %}\\n    {% set hard_deletes = adapter.get_hard_deletes_behavior(config) %}\\n    {% set invalidate_hard_deletes = hard_deletes == 'invalidate' %}\\n    {% set columns = config.get(\\\"snapshot_table_column_names\\\") or get_snapshot_table_column_names() %}\\n\\n    {#/*\\n        The snapshot relation might not have an {{ updated_at }} value if the\\n        snapshot strategy is changed from `check` to `timestamp`. We\\n        should use a dbt-created column for the comparison in the snapshot\\n        table instead of assuming that the user-supplied {{ updated_at }}\\n        will be present in the historical data.\\n\\n        See https://github.com/dbt-labs/dbt-core/issues/2350\\n    */ #}\\n    {% set row_changed_expr -%}\\n        ({{ snapshotted_rel }}.{{ columns.dbt_valid_from }} < {{ current_rel }}.{{ updated_at }})\\n    {%- endset %}\\n\\n    {% set scd_args = api.Relation.scd_args(primary_key, updated_at) %}\\n    {% set scd_id_expr = snapshot_hash_arguments(scd_args) %}\\n\\n    {% do return({\\n        \\\"unique_key\\\": primary_key,\\n        \\\"updated_at\\\": updated_at,\\n        \\\"row_changed\\\": row_changed_expr,\\n        \\\"scd_id\\\": scd_id_expr,\\n        \\\"invalidate_hard_deletes\\\": invalidate_hard_deletes,\\n        \\\"hard_deletes\\\": hard_deletes\\n    }) %}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.get_snapshot_table_column_names\",\n          \"macro.dbt.snapshot_hash_arguments\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495252,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.snapshot_string_as_time\": {\n      \"name\": \"snapshot_string_as_time\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/snapshots/strategies.sql\",\n      \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\",\n      \"unique_id\": \"macro.dbt.snapshot_string_as_time\",\n      \"macro_sql\": \"{% macro snapshot_string_as_time(timestamp) -%}\\n    {{ adapter.dispatch('snapshot_string_as_time', 'dbt')(timestamp) }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__snapshot_string_as_time\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495255,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__snapshot_string_as_time\": {\n      \"name\": \"default__snapshot_string_as_time\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/snapshots/strategies.sql\",\n      \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\",\n      \"unique_id\": \"macro.dbt.default__snapshot_string_as_time\",\n      \"macro_sql\": \"{% macro default__snapshot_string_as_time(timestamp) %}\\n    {% do exceptions.raise_not_implemented(\\n        'snapshot_string_as_time macro not implemented for adapter '+adapter.type()\\n    ) %}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4952588,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.snapshot_check_all_get_existing_columns\": {\n      \"name\": \"snapshot_check_all_get_existing_columns\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/snapshots/strategies.sql\",\n      \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\",\n      \"unique_id\": \"macro.dbt.snapshot_check_all_get_existing_columns\",\n      \"macro_sql\": \"{% macro snapshot_check_all_get_existing_columns(node, target_exists, check_cols_config) -%}\\n    {%- if not target_exists -%}\\n        {#-- no table yet -> return whatever the query does --#}\\n        {{ return((false, query_columns)) }}\\n    {%- endif -%}\\n\\n    {#-- handle any schema changes --#}\\n    {%- set target_relation = adapter.get_relation(database=node.database, schema=node.schema, identifier=node.alias) -%}\\n\\n    {% if check_cols_config == 'all' %}\\n        {%- set query_columns = get_columns_in_query(node['compiled_code']) -%}\\n\\n    {% elif check_cols_config is iterable and (check_cols_config | length) > 0 %}\\n        {#-- query for proper casing/quoting, to support comparison below --#}\\n        {%- set select_check_cols_from_target -%}\\n            {#-- N.B. The whitespace below is necessary to avoid edge case issue with comments --#}\\n            {#-- See: https://github.com/dbt-labs/dbt-core/issues/6781 --#}\\n            select {{ check_cols_config | join(', ') }} from (\\n                {{ node['compiled_code'] }}\\n            ) subq\\n        {%- endset -%}\\n        {% set query_columns = get_columns_in_query(select_check_cols_from_target) %}\\n\\n    {% else %}\\n        {% do exceptions.raise_compiler_error(\\\"Invalid value for 'check_cols': \\\" ~ check_cols_config) %}\\n    {% endif %}\\n\\n    {%- set existing_cols = adapter.get_columns_in_relation(target_relation) | map(attribute = 'name') | list -%}\\n    {%- set ns = namespace() -%} {#-- handle for-loop scoping with a namespace --#}\\n    {%- set ns.column_added = false -%}\\n\\n    {%- set intersection = [] -%}\\n    {%- for col in query_columns -%}\\n        {%- if col in existing_cols -%}\\n            {%- do intersection.append(adapter.quote(col)) -%}\\n        {%- else -%}\\n            {% set ns.column_added = true %}\\n        {%- endif -%}\\n    {%- endfor -%}\\n    {{ return((ns.column_added, intersection)) }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.get_columns_in_query\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495264,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.snapshot_check_strategy\": {\n      \"name\": \"snapshot_check_strategy\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/snapshots/strategies.sql\",\n      \"original_file_path\": \"macros/materializations/snapshots/strategies.sql\",\n      \"unique_id\": \"macro.dbt.snapshot_check_strategy\",\n      \"macro_sql\": \"{% macro snapshot_check_strategy(node, snapshotted_rel, current_rel, model_config, target_exists) %}\\n    {# The model_config parameter is no longer used, but is passed in anyway for compatibility. #}\\n    {% set check_cols_config = config.get('check_cols') %}\\n    {% set primary_key = config.get('unique_key') %}\\n    {% set hard_deletes = adapter.get_hard_deletes_behavior(config) %}\\n    {% set invalidate_hard_deletes = hard_deletes == 'invalidate' %}\\n    {% set updated_at = config.get('updated_at') or snapshot_get_time() %}\\n\\n    {% set column_added = false %}\\n\\n    {% set column_added, check_cols = snapshot_check_all_get_existing_columns(node, target_exists, check_cols_config) %}\\n\\n    {%- set row_changed_expr -%}\\n    (\\n    {%- if column_added -%}\\n        {{ get_true_sql() }}\\n    {%- else -%}\\n    {%- for col in check_cols -%}\\n        {{ snapshotted_rel }}.{{ col }} != {{ current_rel }}.{{ col }}\\n        or\\n        (\\n            (({{ snapshotted_rel }}.{{ col }} is null) and not ({{ current_rel }}.{{ col }} is null))\\n            or\\n            ((not {{ snapshotted_rel }}.{{ col }} is null) and ({{ current_rel }}.{{ col }} is null))\\n        )\\n        {%- if not loop.last %} or {% endif -%}\\n    {%- endfor -%}\\n    {%- endif -%}\\n    )\\n    {%- endset %}\\n\\n    {% set scd_args = api.Relation.scd_args(primary_key, updated_at) %}\\n    {% set scd_id_expr = snapshot_hash_arguments(scd_args) %}\\n\\n    {% do return({\\n        \\\"unique_key\\\": primary_key,\\n        \\\"updated_at\\\": updated_at,\\n        \\\"row_changed\\\": row_changed_expr,\\n        \\\"scd_id\\\": scd_id_expr,\\n        \\\"invalidate_hard_deletes\\\": invalidate_hard_deletes,\\n        \\\"hard_deletes\\\": hard_deletes\\n    }) %}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.snapshot_get_time\",\n          \"macro.dbt.snapshot_check_all_get_existing_columns\",\n          \"macro.dbt.get_true_sql\",\n          \"macro.dbt.snapshot_hash_arguments\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4952672,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.create_columns\": {\n      \"name\": \"create_columns\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/snapshots/helpers.sql\",\n      \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\",\n      \"unique_id\": \"macro.dbt.create_columns\",\n      \"macro_sql\": \"{% macro create_columns(relation, columns) %}\\n  {{ adapter.dispatch('create_columns', 'dbt')(relation, columns) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__create_columns\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495279,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__create_columns\": {\n      \"name\": \"default__create_columns\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/snapshots/helpers.sql\",\n      \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\",\n      \"unique_id\": \"macro.dbt.default__create_columns\",\n      \"macro_sql\": \"{% macro default__create_columns(relation, columns) %}\\n  {% for column in columns %}\\n    {% call statement() %}\\n      alter table {{ relation.render() }} add column {{ adapter.quote(column.name) }} {{ column.data_type }};\\n    {% endcall %}\\n  {% endfor %}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.statement\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495282,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.post_snapshot\": {\n      \"name\": \"post_snapshot\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/snapshots/helpers.sql\",\n      \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\",\n      \"unique_id\": \"macro.dbt.post_snapshot\",\n      \"macro_sql\": \"{% macro post_snapshot(staging_relation) %}\\n  {{ adapter.dispatch('post_snapshot', 'dbt')(staging_relation) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__post_snapshot\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495286,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__post_snapshot\": {\n      \"name\": \"default__post_snapshot\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/snapshots/helpers.sql\",\n      \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\",\n      \"unique_id\": \"macro.dbt.default__post_snapshot\",\n      \"macro_sql\": \"{% macro default__post_snapshot(staging_relation) %}\\n    {# no-op #}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4952881,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_true_sql\": {\n      \"name\": \"get_true_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/snapshots/helpers.sql\",\n      \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\",\n      \"unique_id\": \"macro.dbt.get_true_sql\",\n      \"macro_sql\": \"{% macro get_true_sql() %}\\n  {{ adapter.dispatch('get_true_sql', 'dbt')() }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_true_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495291,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_true_sql\": {\n      \"name\": \"default__get_true_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/snapshots/helpers.sql\",\n      \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\",\n      \"unique_id\": \"macro.dbt.default__get_true_sql\",\n      \"macro_sql\": \"{% macro default__get_true_sql() %}\\n    {{ return('TRUE') }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495295,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.snapshot_staging_table\": {\n      \"name\": \"snapshot_staging_table\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/snapshots/helpers.sql\",\n      \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\",\n      \"unique_id\": \"macro.dbt.snapshot_staging_table\",\n      \"macro_sql\": \"{% macro snapshot_staging_table(strategy, source_sql, target_relation) -%}\\n  {{ adapter.dispatch('snapshot_staging_table', 'dbt')(strategy, source_sql, target_relation) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__snapshot_staging_table\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495297,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_snapshot_table_column_names\": {\n      \"name\": \"get_snapshot_table_column_names\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/snapshots/helpers.sql\",\n      \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\",\n      \"unique_id\": \"macro.dbt.get_snapshot_table_column_names\",\n      \"macro_sql\": \"{% macro get_snapshot_table_column_names() %}\\n    {{ return({'dbt_valid_to': 'dbt_valid_to', 'dbt_valid_from': 'dbt_valid_from', 'dbt_scd_id': 'dbt_scd_id', 'dbt_updated_at': 'dbt_updated_at', 'dbt_is_deleted': 'dbt_is_deleted'}) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495301,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__snapshot_staging_table\": {\n      \"name\": \"default__snapshot_staging_table\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/snapshots/helpers.sql\",\n      \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\",\n      \"unique_id\": \"macro.dbt.default__snapshot_staging_table\",\n      \"macro_sql\": \"{% macro default__snapshot_staging_table(strategy, source_sql, target_relation) -%}\\n    {% set columns = config.get('snapshot_table_column_names') or get_snapshot_table_column_names() %}\\n    {% if strategy.hard_deletes == 'new_record' %}\\n        {% set new_scd_id = snapshot_hash_arguments([columns.dbt_scd_id, snapshot_get_time()]) %}\\n    {% endif %}\\n    with snapshot_query as (\\n\\n        {{ source_sql }}\\n\\n    ),\\n\\n    snapshotted_data as (\\n\\n        select *, {{ unique_key_fields(strategy.unique_key) }}\\n        from {{ target_relation }}\\n        where\\n            {% if config.get('dbt_valid_to_current') %}\\n\\t\\t{% set source_unique_key = columns.dbt_valid_to | trim %}\\n\\t\\t{% set target_unique_key = config.get('dbt_valid_to_current') | trim %}\\n\\n\\t\\t{# The exact equals semantics between NULL values depends on the current behavior flag set. Also, update records if the source field is null #}\\n                ( {{ equals(source_unique_key, target_unique_key) }} or {{ source_unique_key }} is null )\\n            {% else %}\\n                {{ columns.dbt_valid_to }} is null\\n            {% endif %}\\n\\n    ),\\n\\n    insertions_source_data as (\\n\\n        select *, {{ unique_key_fields(strategy.unique_key) }},\\n            {{ strategy.updated_at }} as {{ columns.dbt_updated_at }},\\n            {{ strategy.updated_at }} as {{ columns.dbt_valid_from }},\\n            {{ get_dbt_valid_to_current(strategy, columns) }},\\n            {{ strategy.scd_id }} as {{ columns.dbt_scd_id }}\\n\\n        from snapshot_query\\n    ),\\n\\n    updates_source_data as (\\n\\n        select *, {{ unique_key_fields(strategy.unique_key) }},\\n            {{ strategy.updated_at }} as {{ columns.dbt_updated_at }},\\n            {{ strategy.updated_at }} as {{ columns.dbt_valid_from }},\\n            {{ strategy.updated_at }} as {{ columns.dbt_valid_to }}\\n\\n        from snapshot_query\\n    ),\\n\\n    {%- if strategy.hard_deletes == 'invalidate' or strategy.hard_deletes == 'new_record' %}\\n\\n    deletes_source_data as (\\n\\n        select *, {{ unique_key_fields(strategy.unique_key) }}\\n        from snapshot_query\\n    ),\\n    {% endif %}\\n\\n    insertions as (\\n\\n        select\\n            'insert' as dbt_change_type,\\n            source_data.*\\n          {%- if strategy.hard_deletes == 'new_record' -%}\\n            ,'False' as {{ columns.dbt_is_deleted }}\\n          {%- endif %}\\n\\n        from insertions_source_data as source_data\\n        left outer join snapshotted_data\\n            on {{ unique_key_join_on(strategy.unique_key, \\\"snapshotted_data\\\", \\\"source_data\\\") }}\\n            where {{ unique_key_is_null(strategy.unique_key, \\\"snapshotted_data\\\") }}\\n            or ({{ unique_key_is_not_null(strategy.unique_key, \\\"snapshotted_data\\\") }} and (\\n               {{ strategy.row_changed }} {%- if strategy.hard_deletes == 'new_record' -%} or snapshotted_data.{{ columns.dbt_is_deleted }} = 'True' {% endif %}\\n            )\\n\\n        )\\n\\n    ),\\n\\n    updates as (\\n\\n        select\\n            'update' as dbt_change_type,\\n            source_data.*,\\n            snapshotted_data.{{ columns.dbt_scd_id }}\\n          {%- if strategy.hard_deletes == 'new_record' -%}\\n            , snapshotted_data.{{ columns.dbt_is_deleted }}\\n          {%- endif %}\\n\\n        from updates_source_data as source_data\\n        join snapshotted_data\\n            on {{ unique_key_join_on(strategy.unique_key, \\\"snapshotted_data\\\", \\\"source_data\\\") }}\\n        where (\\n            {{ strategy.row_changed }}  {%- if strategy.hard_deletes == 'new_record' -%} or snapshotted_data.{{ columns.dbt_is_deleted }} = 'True' {% endif %}\\n        )\\n    )\\n\\n    {%- if strategy.hard_deletes == 'invalidate' or strategy.hard_deletes == 'new_record' %}\\n    ,\\n    deletes as (\\n\\n        select\\n            'delete' as dbt_change_type,\\n            source_data.*,\\n            {{ snapshot_get_time() }} as {{ columns.dbt_valid_from }},\\n            {{ snapshot_get_time() }} as {{ columns.dbt_updated_at }},\\n            {{ snapshot_get_time() }} as {{ columns.dbt_valid_to }},\\n            snapshotted_data.{{ columns.dbt_scd_id }}\\n          {%- if strategy.hard_deletes == 'new_record' -%}\\n            , snapshotted_data.{{ columns.dbt_is_deleted }}\\n          {%- endif %}\\n        from snapshotted_data\\n        left join deletes_source_data as source_data\\n            on {{ unique_key_join_on(strategy.unique_key, \\\"snapshotted_data\\\", \\\"source_data\\\") }}\\n            where {{ unique_key_is_null(strategy.unique_key, \\\"source_data\\\") }}\\n\\n            {%- if strategy.hard_deletes == 'new_record' %}\\n            and not (\\n                --avoid updating the record's valid_to if the latest entry is marked as deleted\\n                snapshotted_data.{{ columns.dbt_is_deleted }} = 'True'\\n                and\\n                {% if config.get('dbt_valid_to_current') -%}\\n                    snapshotted_data.{{ columns.dbt_valid_to }} = {{ config.get('dbt_valid_to_current') }}\\n                {%- else -%}\\n                    snapshotted_data.{{ columns.dbt_valid_to }} is null\\n                {%- endif %}\\n            )\\n            {%- endif %}\\n    )\\n    {%- endif %}\\n\\n    {%- if strategy.hard_deletes == 'new_record' %}\\n        {% set snapshotted_cols = get_list_of_column_names(get_columns_in_relation(target_relation)) %}\\n        {% set source_sql_cols = get_column_schema_from_query(source_sql) %}\\n    ,\\n    deletion_records as (\\n\\n        select\\n            'insert' as dbt_change_type,\\n            {#/*\\n                If a column has been added to the source it won't yet exist in the\\n                snapshotted table so we insert a null value as a placeholder for the column.\\n             */#}\\n            {%- for col in source_sql_cols -%}\\n            {%- if col.name in snapshotted_cols -%}\\n            snapshotted_data.{{ adapter.quote(col.column) }},\\n            {%- else -%}\\n            NULL as {{ adapter.quote(col.column) }},\\n            {%- endif -%}\\n            {% endfor -%}\\n            {%- if strategy.unique_key | is_list -%}\\n                {%- for key in strategy.unique_key -%}\\n            snapshotted_data.{{ key }} as dbt_unique_key_{{ loop.index }},\\n                {% endfor -%}\\n            {%- else -%}\\n            snapshotted_data.dbt_unique_key as dbt_unique_key,\\n            {% endif -%}\\n            {{ snapshot_get_time() }} as {{ columns.dbt_valid_from }},\\n            {{ snapshot_get_time() }} as {{ columns.dbt_updated_at }},\\n            snapshotted_data.{{ columns.dbt_valid_to }} as {{ columns.dbt_valid_to }},\\n            {{ new_scd_id }} as {{ columns.dbt_scd_id }},\\n            'True' as {{ columns.dbt_is_deleted }}\\n        from snapshotted_data\\n        left join deletes_source_data as source_data\\n            on {{ unique_key_join_on(strategy.unique_key, \\\"snapshotted_data\\\", \\\"source_data\\\") }}\\n        where {{ unique_key_is_null(strategy.unique_key, \\\"source_data\\\") }}\\n        and not (\\n            --avoid inserting a new record if the latest one is marked as deleted\\n            snapshotted_data.{{ columns.dbt_is_deleted }} = 'True'\\n            and\\n            {% if config.get('dbt_valid_to_current') -%}\\n                snapshotted_data.{{ columns.dbt_valid_to }} = {{ config.get('dbt_valid_to_current') }}\\n            {%- else -%}\\n                snapshotted_data.{{ columns.dbt_valid_to }} is null\\n            {%- endif %}\\n            )\\n\\n    )\\n    {%- endif %}\\n\\n    select * from insertions\\n    union all\\n    select * from updates\\n    {%- if strategy.hard_deletes == 'invalidate' or strategy.hard_deletes == 'new_record' %}\\n    union all\\n    select * from deletes\\n    {%- endif %}\\n    {%- if strategy.hard_deletes == 'new_record' %}\\n    union all\\n    select * from deletion_records\\n    {%- endif %}\\n\\n\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.get_snapshot_table_column_names\",\n          \"macro.dbt.snapshot_hash_arguments\",\n          \"macro.dbt.snapshot_get_time\",\n          \"macro.dbt.unique_key_fields\",\n          \"macro.dbt.equals\",\n          \"macro.dbt.get_dbt_valid_to_current\",\n          \"macro.dbt.unique_key_join_on\",\n          \"macro.dbt.unique_key_is_null\",\n          \"macro.dbt.unique_key_is_not_null\",\n          \"macro.dbt.get_list_of_column_names\",\n          \"macro.dbt.get_columns_in_relation\",\n          \"macro.dbt.get_column_schema_from_query\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495305,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.build_snapshot_table\": {\n      \"name\": \"build_snapshot_table\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/snapshots/helpers.sql\",\n      \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\",\n      \"unique_id\": \"macro.dbt.build_snapshot_table\",\n      \"macro_sql\": \"{% macro build_snapshot_table(strategy, sql) -%}\\n  {{ adapter.dispatch('build_snapshot_table', 'dbt')(strategy, sql) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__build_snapshot_table\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495308,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__build_snapshot_table\": {\n      \"name\": \"default__build_snapshot_table\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/snapshots/helpers.sql\",\n      \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\",\n      \"unique_id\": \"macro.dbt.default__build_snapshot_table\",\n      \"macro_sql\": \"{% macro default__build_snapshot_table(strategy, sql) %}\\n    {% set columns = config.get('snapshot_table_column_names') or get_snapshot_table_column_names() %}\\n\\n    select *,\\n        {{ strategy.scd_id }} as {{ columns.dbt_scd_id }},\\n        {{ strategy.updated_at }} as {{ columns.dbt_updated_at }},\\n        {{ strategy.updated_at }} as {{ columns.dbt_valid_from }},\\n        {{ get_dbt_valid_to_current(strategy, columns) }}\\n      {%- if strategy.hard_deletes == 'new_record' -%}\\n        , 'False' as {{ columns.dbt_is_deleted }}\\n      {% endif -%}\\n    from (\\n        {{ sql }}\\n    ) sbq\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.get_snapshot_table_column_names\",\n          \"macro.dbt.get_dbt_valid_to_current\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495311,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.build_snapshot_staging_table\": {\n      \"name\": \"build_snapshot_staging_table\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/snapshots/helpers.sql\",\n      \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\",\n      \"unique_id\": \"macro.dbt.build_snapshot_staging_table\",\n      \"macro_sql\": \"{% macro build_snapshot_staging_table(strategy, sql, target_relation) %}\\n    {% set temp_relation = make_temp_relation(target_relation) %}\\n\\n    {% set select = snapshot_staging_table(strategy, sql, target_relation) %}\\n\\n    {% call statement('build_snapshot_staging_relation') %}\\n        {{ create_table_as(True, temp_relation, select) }}\\n    {% endcall %}\\n\\n    {% do return(temp_relation) %}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.make_temp_relation\",\n          \"macro.dbt.snapshot_staging_table\",\n          \"macro.dbt.statement\",\n          \"macro.dbt.create_table_as\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4953148,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_updated_at_column_data_type\": {\n      \"name\": \"get_updated_at_column_data_type\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/snapshots/helpers.sql\",\n      \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\",\n      \"unique_id\": \"macro.dbt.get_updated_at_column_data_type\",\n      \"macro_sql\": \"{% macro get_updated_at_column_data_type(snapshot_sql) %}\\n    {% set snapshot_sql_column_schema = get_column_schema_from_query(snapshot_sql) %}\\n    {% set dbt_updated_at_data_type = null %}\\n    {% set ns = namespace() -%} {#-- handle for-loop scoping with a namespace --#}\\n    {% set ns.dbt_updated_at_data_type = null -%}\\n    {% for column in snapshot_sql_column_schema %}\\n    {%   if ((column.column == 'dbt_updated_at') or (column.column == 'DBT_UPDATED_AT')) %}\\n    {%     set ns.dbt_updated_at_data_type = column.dtype %}\\n    {%   endif %}\\n    {% endfor %}\\n    {{ return(ns.dbt_updated_at_data_type or none)  }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.get_column_schema_from_query\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495318,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.check_time_data_types\": {\n      \"name\": \"check_time_data_types\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/snapshots/helpers.sql\",\n      \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\",\n      \"unique_id\": \"macro.dbt.check_time_data_types\",\n      \"macro_sql\": \"{% macro check_time_data_types(sql) %}\\n  {% set dbt_updated_at_data_type = get_updated_at_column_data_type(sql) %}\\n  {% set snapshot_get_time_data_type = get_snapshot_get_time_data_type() %}\\n  {% if snapshot_get_time_data_type is not none and dbt_updated_at_data_type is not none and snapshot_get_time_data_type != dbt_updated_at_data_type %}\\n  {%   if exceptions.warn_snapshot_timestamp_data_types %}\\n  {{     exceptions.warn_snapshot_timestamp_data_types(snapshot_get_time_data_type, dbt_updated_at_data_type) }}\\n  {%   endif %}\\n  {% endif %}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.get_updated_at_column_data_type\",\n          \"macro.dbt.get_snapshot_get_time_data_type\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.49532,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_dbt_valid_to_current\": {\n      \"name\": \"get_dbt_valid_to_current\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/snapshots/helpers.sql\",\n      \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\",\n      \"unique_id\": \"macro.dbt.get_dbt_valid_to_current\",\n      \"macro_sql\": \"{% macro get_dbt_valid_to_current(strategy, columns) %}\\n  {% set dbt_valid_to_current = config.get('dbt_valid_to_current') or \\\"null\\\" %}\\n  coalesce(nullif({{ strategy.updated_at }}, {{ strategy.updated_at }}), {{dbt_valid_to_current}})\\n  as {{ columns.dbt_valid_to }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495323,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.unique_key_fields\": {\n      \"name\": \"unique_key_fields\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/snapshots/helpers.sql\",\n      \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\",\n      \"unique_id\": \"macro.dbt.unique_key_fields\",\n      \"macro_sql\": \"{% macro unique_key_fields(unique_key) %}\\n    {% if unique_key | is_list %}\\n        {% for key in unique_key %}\\n            {{ key }} as dbt_unique_key_{{ loop.index }}\\n            {%- if not loop.last %} , {%- endif %}\\n        {% endfor %}\\n    {% else %}\\n        {{ unique_key }} as dbt_unique_key\\n    {% endif %}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495326,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.unique_key_join_on\": {\n      \"name\": \"unique_key_join_on\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/snapshots/helpers.sql\",\n      \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\",\n      \"unique_id\": \"macro.dbt.unique_key_join_on\",\n      \"macro_sql\": \"{% macro unique_key_join_on(unique_key, identifier, from_identifier) %}\\n    {% if unique_key | is_list %}\\n        {% for key in unique_key %}\\n\\t    {% set source_unique_key = (identifier ~ \\\".dbt_unique_key_\\\" ~ loop.index) | trim %}\\n\\t    {% set target_unique_key = (from_identifier ~ \\\".dbt_unique_key_\\\" ~ loop.index) | trim %}\\n\\t    {{ equals(source_unique_key, target_unique_key) }}\\n            {%- if not loop.last %} and {%- endif %}\\n        {% endfor %}\\n    {% else %}\\n        {{ identifier }}.dbt_unique_key = {{ from_identifier }}.dbt_unique_key\\n    {% endif %}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.equals\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4953291,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.unique_key_is_null\": {\n      \"name\": \"unique_key_is_null\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/snapshots/helpers.sql\",\n      \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\",\n      \"unique_id\": \"macro.dbt.unique_key_is_null\",\n      \"macro_sql\": \"{% macro unique_key_is_null(unique_key, identifier) %}\\n    {% if unique_key | is_list %}\\n        {{ identifier }}.dbt_unique_key_1 is null\\n    {% else %}\\n        {{ identifier }}.dbt_unique_key is null\\n    {% endif %}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495331,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.unique_key_is_not_null\": {\n      \"name\": \"unique_key_is_not_null\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/snapshots/helpers.sql\",\n      \"original_file_path\": \"macros/materializations/snapshots/helpers.sql\",\n      \"unique_id\": \"macro.dbt.unique_key_is_not_null\",\n      \"macro_sql\": \"{% macro unique_key_is_not_null(unique_key, identifier) %}\\n    {% if unique_key | is_list %}\\n        {{ identifier }}.dbt_unique_key_1 is not null\\n    {% else %}\\n        {{ identifier }}.dbt_unique_key is not null\\n    {% endif %}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4953349,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.materialization_snapshot_default\": {\n      \"name\": \"materialization_snapshot_default\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/snapshots/snapshot.sql\",\n      \"original_file_path\": \"macros/materializations/snapshots/snapshot.sql\",\n      \"unique_id\": \"macro.dbt.materialization_snapshot_default\",\n      \"macro_sql\": \"{% materialization snapshot, default %}\\n\\n  {%- set target_table = model.get('alias', model.get('name')) -%}\\n\\n  {%- set strategy_name = config.get('strategy') -%}\\n  {%- set unique_key = config.get('unique_key') %}\\n  -- grab current tables grants config for comparision later on\\n  {%- set grant_config = config.get('grants') -%}\\n\\n  {% set target_relation_exists, target_relation = get_or_create_relation(\\n          database=model.database,\\n          schema=model.schema,\\n          identifier=target_table,\\n          type='table') -%}\\n\\n  {%- if not target_relation.is_table -%}\\n    {% do exceptions.relation_wrong_type(target_relation, 'table') %}\\n  {%- endif -%}\\n\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  {% set strategy_macro = strategy_dispatch(strategy_name) %}\\n  {# The model['config'] parameter below is no longer used, but passing anyway for compatibility #}\\n  {# It was a dictionary of config, instead of the config object from the context #}\\n  {% set strategy = strategy_macro(model, \\\"snapshotted_data\\\", \\\"source_data\\\", model['config'], target_relation_exists) %}\\n\\n  {% if not target_relation_exists %}\\n\\n      {% set build_sql = build_snapshot_table(strategy, model['compiled_code']) %}\\n      {% set build_or_select_sql = build_sql %}\\n      {% set final_sql = create_table_as(False, target_relation, build_sql) %}\\n\\n  {% else %}\\n\\n      {% set columns = config.get(\\\"snapshot_table_column_names\\\") or get_snapshot_table_column_names() %}\\n\\n      {{ adapter.assert_valid_snapshot_target_given_strategy(target_relation, columns, strategy) }}\\n\\n      {% set build_or_select_sql = snapshot_staging_table(strategy, sql, target_relation) %}\\n      {% set staging_table = build_snapshot_staging_table(strategy, sql, target_relation) %}\\n\\n      -- this may no-op if the database does not require column expansion\\n      {% do adapter.expand_target_column_types(from_relation=staging_table,\\n                                               to_relation=target_relation) %}\\n\\n      {% set remove_columns = ['dbt_change_type', 'DBT_CHANGE_TYPE', 'dbt_unique_key', 'DBT_UNIQUE_KEY'] %}\\n      {% if unique_key | is_list %}\\n          {% for key in strategy.unique_key %}\\n              {{ remove_columns.append('dbt_unique_key_' + loop.index|string) }}\\n              {{ remove_columns.append('DBT_UNIQUE_KEY_' + loop.index|string) }}\\n          {% endfor %}\\n      {% endif %}\\n\\n      {% set missing_columns = adapter.get_missing_columns(staging_table, target_relation)\\n                                   | rejectattr('name', 'in', remove_columns)\\n                                   | list %}\\n\\n      {% do create_columns(target_relation, missing_columns) %}\\n\\n      {% set source_columns = adapter.get_columns_in_relation(staging_table)\\n                                   | rejectattr('name', 'in', remove_columns)\\n                                   | list %}\\n\\n      {% set quoted_source_columns = [] %}\\n      {% for column in source_columns %}\\n        {% do quoted_source_columns.append(adapter.quote(column.name)) %}\\n      {% endfor %}\\n\\n      {% set final_sql = snapshot_merge_sql(\\n            target = target_relation,\\n            source = staging_table,\\n            insert_cols = quoted_source_columns\\n         )\\n      %}\\n\\n  {% endif %}\\n\\n\\n  {{ check_time_data_types(build_or_select_sql) }}\\n\\n  {% call statement('main') %}\\n      {{ final_sql }}\\n  {% endcall %}\\n\\n  {% set should_revoke = should_revoke(target_relation_exists, full_refresh_mode=False) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {% if not target_relation_exists %}\\n    {% do create_indexes(target_relation) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  {{ adapter.commit() }}\\n\\n  {% if staging_table is defined %}\\n      {% do post_snapshot(staging_table) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{% endmaterialization %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.get_or_create_relation\",\n          \"macro.dbt.run_hooks\",\n          \"macro.dbt.strategy_dispatch\",\n          \"macro.dbt.build_snapshot_table\",\n          \"macro.dbt.create_table_as\",\n          \"macro.dbt.get_snapshot_table_column_names\",\n          \"macro.dbt.snapshot_staging_table\",\n          \"macro.dbt.build_snapshot_staging_table\",\n          \"macro.dbt.create_columns\",\n          \"macro.dbt.snapshot_merge_sql\",\n          \"macro.dbt.check_time_data_types\",\n          \"macro.dbt.statement\",\n          \"macro.dbt.should_revoke\",\n          \"macro.dbt.apply_grants\",\n          \"macro.dbt.persist_docs\",\n          \"macro.dbt.create_indexes\",\n          \"macro.dbt.post_snapshot\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4953442,\n      \"supported_languages\": [\n        \"sql\"\n      ]\n    },\n    \"macro.dbt.materialization_test_default\": {\n      \"name\": \"materialization_test_default\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/tests/test.sql\",\n      \"original_file_path\": \"macros/materializations/tests/test.sql\",\n      \"unique_id\": \"macro.dbt.materialization_test_default\",\n      \"macro_sql\": \"{%- materialization test, default -%}\\n\\n  {% set relations = [] %}\\n  {% set limit = config.get('limit') %}\\n\\n  {% set sql_with_limit %}\\n    {{ get_limit_subquery_sql(sql, limit) }}\\n  {% endset %}\\n\\n  {% if should_store_failures() %}\\n\\n    {% set identifier = model['alias'] %}\\n    {% set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) %}\\n\\n    {% set store_failures_as = config.get('store_failures_as') %}\\n    -- if `--store-failures` is invoked via command line and `store_failures_as` is not set,\\n    -- config.get('store_failures_as', 'table') returns None, not 'table'\\n    {% if store_failures_as == none %}{% set store_failures_as = 'table' %}{% endif %}\\n    {% if store_failures_as not in ['table', 'view'] %}\\n        {{ exceptions.raise_compiler_error(\\n            \\\"'\\\" ~ store_failures_as ~ \\\"' is not a valid value for `store_failures_as`. \\\"\\n            \\\"Accepted values are: ['ephemeral', 'table', 'view']\\\"\\n        ) }}\\n    {% endif %}\\n\\n    {% set target_relation = api.Relation.create(\\n        identifier=identifier, schema=schema, database=database, type=store_failures_as) -%} %}\\n\\n    {% if old_relation %}\\n        {% do adapter.drop_relation(old_relation) %}\\n    {% endif %}\\n\\n    {% call statement(auto_begin=True) %}\\n        {{ get_create_sql(target_relation, sql_with_limit) }}\\n    {% endcall %}\\n\\n    {% do relations.append(target_relation) %}\\n\\n    {# Since the test failures have already been saved to the database, reuse that result rather than querying again #}\\n    {% set main_sql %}\\n        select *\\n        from {{ target_relation }}\\n    {% endset %}\\n\\n    {{ adapter.commit() }}\\n\\n  {% else %}\\n\\n      {% set main_sql = sql_with_limit %}\\n\\n  {% endif %}\\n\\n  {% set fail_calc = config.get('fail_calc') %}\\n  {% set warn_if = config.get('warn_if') %}\\n  {% set error_if = config.get('error_if') %}\\n\\n  {% call statement('main', fetch_result=True) -%}\\n\\n    {# The limit has already been included above, and we do not want to duplicate it again. We also want to be safe for macro overrides treating `limit` as a required parameter. #}\\n    {{ get_test_sql(main_sql, fail_calc, warn_if, error_if, limit=none)}}\\n\\n  {%- endcall %}\\n\\n  {{ return({'relations': relations}) }}\\n\\n{%- endmaterialization -%}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.get_limit_subquery_sql\",\n          \"macro.dbt.should_store_failures\",\n          \"macro.dbt.statement\",\n          \"macro.dbt.get_create_sql\",\n          \"macro.dbt.get_test_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495357,\n      \"supported_languages\": [\n        \"sql\"\n      ]\n    },\n    \"macro.dbt.get_test_sql\": {\n      \"name\": \"get_test_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/tests/helpers.sql\",\n      \"original_file_path\": \"macros/materializations/tests/helpers.sql\",\n      \"unique_id\": \"macro.dbt.get_test_sql\",\n      \"macro_sql\": \"{% macro get_test_sql(main_sql, fail_calc, warn_if, error_if, limit) -%}\\n  {{ adapter.dispatch('get_test_sql', 'dbt')(main_sql, fail_calc, warn_if, error_if, limit) }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_test_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4953668,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_test_sql\": {\n      \"name\": \"default__get_test_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/tests/helpers.sql\",\n      \"original_file_path\": \"macros/materializations/tests/helpers.sql\",\n      \"unique_id\": \"macro.dbt.default__get_test_sql\",\n      \"macro_sql\": \"{% macro default__get_test_sql(main_sql, fail_calc, warn_if, error_if, limit) -%}\\n    select\\n      {{ fail_calc }} as failures,\\n      {{ fail_calc }} {{ warn_if }} as should_warn,\\n      {{ fail_calc }} {{ error_if }} as should_error\\n    from (\\n      {{ main_sql }}\\n      {{ \\\"limit \\\" ~ limit if limit != none }}\\n    ) dbt_internal_test\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495369,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_unit_test_sql\": {\n      \"name\": \"get_unit_test_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/tests/helpers.sql\",\n      \"original_file_path\": \"macros/materializations/tests/helpers.sql\",\n      \"unique_id\": \"macro.dbt.get_unit_test_sql\",\n      \"macro_sql\": \"{% macro get_unit_test_sql(main_sql, expected_fixture_sql, expected_column_names) -%}\\n  {{ adapter.dispatch('get_unit_test_sql', 'dbt')(main_sql, expected_fixture_sql, expected_column_names) }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_unit_test_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495373,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_unit_test_sql\": {\n      \"name\": \"default__get_unit_test_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/tests/helpers.sql\",\n      \"original_file_path\": \"macros/materializations/tests/helpers.sql\",\n      \"unique_id\": \"macro.dbt.default__get_unit_test_sql\",\n      \"macro_sql\": \"{% macro default__get_unit_test_sql(main_sql, expected_fixture_sql, expected_column_names) -%}\\n-- Build actual result given inputs\\nwith dbt_internal_unit_test_actual as (\\n  select\\n    {% for expected_column_name in expected_column_names %}{{expected_column_name}}{% if not loop.last -%},{% endif %}{%- endfor -%}, {{ dbt.string_literal(\\\"actual\\\") }} as {{ adapter.quote(\\\"actual_or_expected\\\") }}\\n  from (\\n    {{ main_sql }}\\n  ) _dbt_internal_unit_test_actual\\n),\\n-- Build expected result\\ndbt_internal_unit_test_expected as (\\n  select\\n    {% for expected_column_name in expected_column_names %}{{expected_column_name}}{% if not loop.last -%}, {% endif %}{%- endfor -%}, {{ dbt.string_literal(\\\"expected\\\") }} as {{ adapter.quote(\\\"actual_or_expected\\\") }}\\n  from (\\n    {{ expected_fixture_sql }}\\n  ) _dbt_internal_unit_test_expected\\n)\\n-- Union actual and expected results\\nselect * from dbt_internal_unit_test_actual\\nunion all\\nselect * from dbt_internal_unit_test_expected\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.string_literal\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.49538,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_where_subquery\": {\n      \"name\": \"get_where_subquery\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/tests/where_subquery.sql\",\n      \"original_file_path\": \"macros/materializations/tests/where_subquery.sql\",\n      \"unique_id\": \"macro.dbt.get_where_subquery\",\n      \"macro_sql\": \"{% macro get_where_subquery(relation) -%}\\n    {% do return(adapter.dispatch('get_where_subquery', 'dbt')(relation)) %}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_where_subquery\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4953852,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_where_subquery\": {\n      \"name\": \"default__get_where_subquery\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/tests/where_subquery.sql\",\n      \"original_file_path\": \"macros/materializations/tests/where_subquery.sql\",\n      \"unique_id\": \"macro.dbt.default__get_where_subquery\",\n      \"macro_sql\": \"{% macro default__get_where_subquery(relation) -%}\\n    {% set where = config.get('where', '') %}\\n    {% if where %}\\n        {%- set filtered -%}\\n            (select * from {{ relation }} where {{ where }}) dbt_subquery\\n        {%- endset -%}\\n        {% do return(filtered) %}\\n    {%- else -%}\\n        {% do return(relation) %}\\n    {%- endif -%}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4953878,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.materialization_unit_default\": {\n      \"name\": \"materialization_unit_default\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/tests/unit.sql\",\n      \"original_file_path\": \"macros/materializations/tests/unit.sql\",\n      \"unique_id\": \"macro.dbt.materialization_unit_default\",\n      \"macro_sql\": \"{%- materialization unit, default -%}\\n\\n  {% set relations = [] %}\\n\\n  {% set expected_rows = config.get('expected_rows') %}\\n  {% set expected_sql = config.get('expected_sql') %}\\n  {% set tested_expected_column_names = expected_rows[0].keys() if (expected_rows | length ) > 0 else get_columns_in_query(sql) %}\\n\\n  {%- set target_relation = this.incorporate(type='table') -%}\\n  {%- set temp_relation = make_temp_relation(target_relation)-%}\\n  {% do run_query(get_create_table_as_sql(True, temp_relation, get_empty_subquery_sql(sql))) %}\\n  {%- set columns_in_relation = adapter.get_columns_in_relation(temp_relation) -%}\\n  {%- set column_name_to_data_types = {} -%}\\n  {%- set column_name_to_quoted = {} -%}\\n  {%- for column in columns_in_relation -%}\\n  {%-   do column_name_to_data_types.update({column.name|lower: column.data_type}) -%}\\n  {%-   do column_name_to_quoted.update({column.name|lower: column.quoted}) -%}\\n  {%- endfor -%}\\n\\n  {%- set expected_column_names_quoted = [] -%}\\n  {%- for column_name in tested_expected_column_names -%}\\n  {%-   do expected_column_names_quoted.append(column_name_to_quoted[column_name|lower]) -%}\\n  {%- endfor -%}\\n\\n  {% if not expected_sql %}\\n  {%   set expected_sql = get_expected_sql(expected_rows, column_name_to_data_types, column_name_to_quoted) %}\\n  {% endif %}\\n  {% set unit_test_sql = get_unit_test_sql(sql, expected_sql, expected_column_names_quoted) %}\\n\\n  {% call statement('main', fetch_result=True) -%}\\n\\n    {{ unit_test_sql }}\\n\\n  {%- endcall %}\\n\\n  {% do adapter.drop_relation(temp_relation) %}\\n\\n  {{ return({'relations': relations}) }}\\n\\n{%- endmaterialization -%}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.get_columns_in_query\",\n          \"macro.dbt.make_temp_relation\",\n          \"macro.dbt.run_query\",\n          \"macro.dbt.get_create_table_as_sql\",\n          \"macro.dbt.get_empty_subquery_sql\",\n          \"macro.dbt.get_expected_sql\",\n          \"macro.dbt.get_unit_test_sql\",\n          \"macro.dbt.statement\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495394,\n      \"supported_languages\": [\n        \"sql\"\n      ]\n    },\n    \"macro.dbt.materialization_materialized_view_default\": {\n      \"name\": \"materialization_materialized_view_default\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/models/materialized_view.sql\",\n      \"original_file_path\": \"macros/materializations/models/materialized_view.sql\",\n      \"unique_id\": \"macro.dbt.materialization_materialized_view_default\",\n      \"macro_sql\": \"{% materialization materialized_view, default %}\\n    {% set existing_relation = load_cached_relation(this) %}\\n    {% set target_relation = this.incorporate(type=this.MaterializedView) %}\\n    {% set intermediate_relation = make_intermediate_relation(target_relation) %}\\n    {% set backup_relation_type = target_relation.MaterializedView if existing_relation is none else existing_relation.type %}\\n    {% set backup_relation = make_backup_relation(target_relation, backup_relation_type) %}\\n\\n    {{ materialized_view_setup(backup_relation, intermediate_relation, pre_hooks) }}\\n\\n        {% set build_sql = materialized_view_get_build_sql(existing_relation, target_relation, backup_relation, intermediate_relation) %}\\n\\n        {% if build_sql == '' %}\\n            {{ materialized_view_execute_no_op(target_relation) }}\\n        {% else %}\\n            {{ materialized_view_execute_build_sql(build_sql, existing_relation, target_relation, post_hooks) }}\\n        {% endif %}\\n\\n    {{ materialized_view_teardown(backup_relation, intermediate_relation, post_hooks) }}\\n\\n    {{ return({'relations': [target_relation]}) }}\\n\\n{% endmaterialization %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.load_cached_relation\",\n          \"macro.dbt.make_intermediate_relation\",\n          \"macro.dbt.make_backup_relation\",\n          \"macro.dbt.materialized_view_setup\",\n          \"macro.dbt.materialized_view_get_build_sql\",\n          \"macro.dbt.materialized_view_execute_no_op\",\n          \"macro.dbt.materialized_view_execute_build_sql\",\n          \"macro.dbt.materialized_view_teardown\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495407,\n      \"supported_languages\": [\n        \"sql\"\n      ]\n    },\n    \"macro.dbt.materialized_view_setup\": {\n      \"name\": \"materialized_view_setup\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/models/materialized_view.sql\",\n      \"original_file_path\": \"macros/materializations/models/materialized_view.sql\",\n      \"unique_id\": \"macro.dbt.materialized_view_setup\",\n      \"macro_sql\": \"{% macro materialized_view_setup(backup_relation, intermediate_relation, pre_hooks) %}\\n\\n    -- backup_relation and intermediate_relation should not already exist in the database\\n    -- it's possible these exist because of a previous run that exited unexpectedly\\n    {% set preexisting_backup_relation = load_cached_relation(backup_relation) %}\\n    {% set preexisting_intermediate_relation = load_cached_relation(intermediate_relation) %}\\n\\n    -- drop the temp relations if they exist already in the database\\n    {{ drop_relation_if_exists(preexisting_backup_relation) }}\\n    {{ drop_relation_if_exists(preexisting_intermediate_relation) }}\\n\\n    {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.load_cached_relation\",\n          \"macro.dbt.drop_relation_if_exists\",\n          \"macro.dbt.run_hooks\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4954119,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.materialized_view_teardown\": {\n      \"name\": \"materialized_view_teardown\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/models/materialized_view.sql\",\n      \"original_file_path\": \"macros/materializations/models/materialized_view.sql\",\n      \"unique_id\": \"macro.dbt.materialized_view_teardown\",\n      \"macro_sql\": \"{% macro materialized_view_teardown(backup_relation, intermediate_relation, post_hooks) %}\\n\\n    -- drop the temp relations if they exist to leave the database clean for the next run\\n    {{ drop_relation_if_exists(backup_relation) }}\\n    {{ drop_relation_if_exists(intermediate_relation) }}\\n\\n    {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.drop_relation_if_exists\",\n          \"macro.dbt.run_hooks\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495414,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.materialized_view_get_build_sql\": {\n      \"name\": \"materialized_view_get_build_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/models/materialized_view.sql\",\n      \"original_file_path\": \"macros/materializations/models/materialized_view.sql\",\n      \"unique_id\": \"macro.dbt.materialized_view_get_build_sql\",\n      \"macro_sql\": \"{% macro materialized_view_get_build_sql(existing_relation, target_relation, backup_relation, intermediate_relation) %}\\n\\n    {% set full_refresh_mode = should_full_refresh() %}\\n\\n    -- determine the scenario we're in: create, full_refresh, alter, refresh data\\n    {% if existing_relation is none %}\\n        {% set build_sql = get_create_materialized_view_as_sql(target_relation, sql) %}\\n    {% elif full_refresh_mode or not existing_relation.is_materialized_view %}\\n        {% set build_sql = get_replace_sql(existing_relation, target_relation, sql) %}\\n    {% else %}\\n\\n        -- get config options\\n        {% set on_configuration_change = config.get('on_configuration_change') %}\\n        {% set configuration_changes = get_materialized_view_configuration_changes(existing_relation, config) %}\\n\\n        {% if configuration_changes is none %}\\n            {% set build_sql = refresh_materialized_view(target_relation) %}\\n\\n        {% elif on_configuration_change == 'apply' %}\\n            {% set build_sql = get_alter_materialized_view_as_sql(target_relation, configuration_changes, sql, existing_relation, backup_relation, intermediate_relation) %}\\n        {% elif on_configuration_change == 'continue' %}\\n            {% set build_sql = '' %}\\n            {{ exceptions.warn(\\\"Configuration changes were identified and `on_configuration_change` was set to `continue` for `\\\" ~ target_relation.render() ~ \\\"`\\\") }}\\n        {% elif on_configuration_change == 'fail' %}\\n            {{ exceptions.raise_fail_fast_error(\\\"Configuration changes were identified and `on_configuration_change` was set to `fail` for `\\\" ~ target_relation.render() ~ \\\"`\\\") }}\\n\\n        {% else %}\\n            -- this only happens if the user provides a value other than `apply`, 'skip', 'fail'\\n            {{ exceptions.raise_compiler_error(\\\"Unexpected configuration scenario\\\") }}\\n\\n        {% endif %}\\n\\n    {% endif %}\\n\\n    {% do return(build_sql) %}\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.should_full_refresh\",\n          \"macro.dbt.get_create_materialized_view_as_sql\",\n          \"macro.dbt.get_replace_sql\",\n          \"macro.dbt.get_materialized_view_configuration_changes\",\n          \"macro.dbt.refresh_materialized_view\",\n          \"macro.dbt.get_alter_materialized_view_as_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495417,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.materialized_view_execute_no_op\": {\n      \"name\": \"materialized_view_execute_no_op\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/models/materialized_view.sql\",\n      \"original_file_path\": \"macros/materializations/models/materialized_view.sql\",\n      \"unique_id\": \"macro.dbt.materialized_view_execute_no_op\",\n      \"macro_sql\": \"{% macro materialized_view_execute_no_op(target_relation) %}\\n    {% do store_raw_result(\\n        name=\\\"main\\\",\\n        message=\\\"skip \\\" ~ target_relation,\\n        code=\\\"skip\\\",\\n        rows_affected=\\\"-1\\\"\\n    ) %}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.49542,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.materialized_view_execute_build_sql\": {\n      \"name\": \"materialized_view_execute_build_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/models/materialized_view.sql\",\n      \"original_file_path\": \"macros/materializations/models/materialized_view.sql\",\n      \"unique_id\": \"macro.dbt.materialized_view_execute_build_sql\",\n      \"macro_sql\": \"{% macro materialized_view_execute_build_sql(build_sql, existing_relation, target_relation, post_hooks) %}\\n\\n    -- `BEGIN` happens here:\\n    {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n    {% set grant_config = config.get('grants') %}\\n\\n    {% call statement(name=\\\"main\\\") %}\\n        {{ build_sql }}\\n    {% endcall %}\\n\\n    {% set should_revoke = should_revoke(existing_relation, full_refresh_mode=True) %}\\n    {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n    {% do persist_docs(target_relation, model) %}\\n\\n    {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n    {{ adapter.commit() }}\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.run_hooks\",\n          \"macro.dbt.statement\",\n          \"macro.dbt.should_revoke\",\n          \"macro.dbt.apply_grants\",\n          \"macro.dbt.persist_docs\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495422,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.materialization_view_default\": {\n      \"name\": \"materialization_view_default\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/models/view.sql\",\n      \"original_file_path\": \"macros/materializations/models/view.sql\",\n      \"unique_id\": \"macro.dbt.materialization_view_default\",\n      \"macro_sql\": \"{%- materialization view, default -%}\\n\\n  {%- set existing_relation = load_cached_relation(this) -%}\\n  {%- set target_relation = this.incorporate(type='view') -%}\\n  {%- set intermediate_relation =  make_intermediate_relation(target_relation) -%}\\n\\n  -- the intermediate_relation should not already exist in the database; get_relation\\n  -- will return None in that case. Otherwise, we get a relation that we can drop\\n  -- later, before we try to use this name for the current operation\\n  {%- set preexisting_intermediate_relation = load_cached_relation(intermediate_relation) -%}\\n  /*\\n     This relation (probably) doesn't exist yet. If it does exist, it's a leftover from\\n     a previous run, and we're going to try to drop it immediately. At the end of this\\n     materialization, we're going to rename the \\\"existing_relation\\\" to this identifier,\\n     and then we're going to drop it. In order to make sure we run the correct one of:\\n       - drop view ...\\n       - drop table ...\\n\\n     We need to set the type of this relation to be the type of the existing_relation, if it exists,\\n     or else \\\"view\\\" as a sane default if it does not. Note that if the existing_relation does not\\n     exist, then there is nothing to move out of the way and subsequentally drop. In that case,\\n     this relation will be effectively unused.\\n  */\\n  {%- set backup_relation_type = 'view' if existing_relation is none else existing_relation.type -%}\\n  {%- set backup_relation = make_backup_relation(target_relation, backup_relation_type) -%}\\n  -- as above, the backup_relation should not already exist\\n  {%- set preexisting_backup_relation = load_cached_relation(backup_relation) -%}\\n  -- grab current tables grants config for comparision later on\\n  {% set grant_config = config.get('grants') %}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- drop the temp relations if they exist already in the database\\n  {{ drop_relation_if_exists(preexisting_intermediate_relation) }}\\n  {{ drop_relation_if_exists(preexisting_backup_relation) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  -- build model\\n  {% call statement('main') -%}\\n    {{ get_create_view_as_sql(intermediate_relation, sql) }}\\n  {%- endcall %}\\n\\n  -- cleanup\\n  -- move the existing view out of the way\\n  {% if existing_relation is not none %}\\n     /* Do the equivalent of rename_if_exists. 'existing_relation' could have been dropped\\n        since the variable was first set. */\\n    {% set existing_relation = load_cached_relation(existing_relation) %}\\n    {% if existing_relation is not none %}\\n        {{ adapter.rename_relation(existing_relation, backup_relation) }}\\n    {% endif %}\\n  {% endif %}\\n  {{ adapter.rename_relation(intermediate_relation, target_relation) }}\\n\\n  {% set should_revoke = should_revoke(existing_relation, full_refresh_mode=True) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  {{ adapter.commit() }}\\n\\n  {{ drop_relation_if_exists(backup_relation) }}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{%- endmaterialization -%}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.load_cached_relation\",\n          \"macro.dbt.make_intermediate_relation\",\n          \"macro.dbt.make_backup_relation\",\n          \"macro.dbt.run_hooks\",\n          \"macro.dbt.drop_relation_if_exists\",\n          \"macro.dbt.statement\",\n          \"macro.dbt.get_create_view_as_sql\",\n          \"macro.dbt.should_revoke\",\n          \"macro.dbt.apply_grants\",\n          \"macro.dbt.persist_docs\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495431,\n      \"supported_languages\": [\n        \"sql\"\n      ]\n    },\n    \"macro.dbt.materialization_table_default\": {\n      \"name\": \"materialization_table_default\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/models/table.sql\",\n      \"original_file_path\": \"macros/materializations/models/table.sql\",\n      \"unique_id\": \"macro.dbt.materialization_table_default\",\n      \"macro_sql\": \"{% materialization table, default %}\\n\\n  {%- set existing_relation = load_cached_relation(this) -%}\\n  {%- set target_relation = this.incorporate(type='table') %}\\n  {%- set intermediate_relation =  make_intermediate_relation(target_relation) -%}\\n  -- the intermediate_relation should not already exist in the database; get_relation\\n  -- will return None in that case. Otherwise, we get a relation that we can drop\\n  -- later, before we try to use this name for the current operation\\n  {%- set preexisting_intermediate_relation = load_cached_relation(intermediate_relation) -%}\\n  /*\\n      See ../view/view.sql for more information about this relation.\\n  */\\n  {%- set backup_relation_type = 'table' if existing_relation is none else existing_relation.type -%}\\n  {%- set backup_relation = make_backup_relation(target_relation, backup_relation_type) -%}\\n  -- as above, the backup_relation should not already exist\\n  {%- set preexisting_backup_relation = load_cached_relation(backup_relation) -%}\\n  -- grab current tables grants config for comparision later on\\n  {% set grant_config = config.get('grants') %}\\n\\n  -- drop the temp relations if they exist already in the database\\n  {{ drop_relation_if_exists(preexisting_intermediate_relation) }}\\n  {{ drop_relation_if_exists(preexisting_backup_relation) }}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  -- build model\\n  {% call statement('main') -%}\\n    {{ get_create_table_as_sql(False, intermediate_relation, sql) }}\\n  {%- endcall %}\\n\\n  {% do create_indexes(intermediate_relation) %}\\n\\n  -- cleanup\\n  {% if existing_relation is not none %}\\n     /* Do the equivalent of rename_if_exists. 'existing_relation' could have been dropped\\n        since the variable was first set. */\\n    {% set existing_relation = load_cached_relation(existing_relation) %}\\n    {% if existing_relation is not none %}\\n        {{ adapter.rename_relation(existing_relation, backup_relation) }}\\n    {% endif %}\\n  {% endif %}\\n\\n  {{ adapter.rename_relation(intermediate_relation, target_relation) }}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  {% set should_revoke = should_revoke(existing_relation, full_refresh_mode=True) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  -- `COMMIT` happens here\\n  {{ adapter.commit() }}\\n\\n  -- finally, drop the existing/backup relation after the commit\\n  {{ drop_relation_if_exists(backup_relation) }}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n{% endmaterialization %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.load_cached_relation\",\n          \"macro.dbt.make_intermediate_relation\",\n          \"macro.dbt.make_backup_relation\",\n          \"macro.dbt.drop_relation_if_exists\",\n          \"macro.dbt.run_hooks\",\n          \"macro.dbt.statement\",\n          \"macro.dbt.get_create_table_as_sql\",\n          \"macro.dbt.create_indexes\",\n          \"macro.dbt.should_revoke\",\n          \"macro.dbt.apply_grants\",\n          \"macro.dbt.persist_docs\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495441,\n      \"supported_languages\": [\n        \"sql\"\n      ]\n    },\n    \"macro.dbt.get_quoted_csv\": {\n      \"name\": \"get_quoted_csv\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/models/incremental/column_helpers.sql\",\n      \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\",\n      \"unique_id\": \"macro.dbt.get_quoted_csv\",\n      \"macro_sql\": \"{% macro get_quoted_csv(column_names) %}\\n\\n    {% set quoted = [] %}\\n    {% for col in column_names -%}\\n        {%- do quoted.append(adapter.quote(col)) -%}\\n    {%- endfor %}\\n\\n    {%- set dest_cols_csv = quoted | join(', ') -%}\\n    {{ return(dest_cols_csv) }}\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495455,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.diff_columns\": {\n      \"name\": \"diff_columns\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/models/incremental/column_helpers.sql\",\n      \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\",\n      \"unique_id\": \"macro.dbt.diff_columns\",\n      \"macro_sql\": \"{% macro diff_columns(source_columns, target_columns) %}\\n\\n  {% set result = [] %}\\n  {% set source_names = source_columns | map(attribute = 'column') | list %}\\n  {% set target_names = target_columns | map(attribute = 'column') | list %}\\n\\n   {# --check whether the name attribute exists in the target - this does not perform a data type check #}\\n   {% for sc in source_columns %}\\n     {% if sc.name not in target_names %}\\n        {{ result.append(sc) }}\\n     {% endif %}\\n   {% endfor %}\\n\\n  {{ return(result) }}\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4954581,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.diff_column_data_types\": {\n      \"name\": \"diff_column_data_types\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/models/incremental/column_helpers.sql\",\n      \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\",\n      \"unique_id\": \"macro.dbt.diff_column_data_types\",\n      \"macro_sql\": \"{% macro diff_column_data_types(source_columns, target_columns) %}\\n\\n  {% set result = [] %}\\n  {% for sc in source_columns %}\\n    {% set tc = target_columns | selectattr(\\\"name\\\", \\\"equalto\\\", sc.name) | list | first %}\\n    {% if tc %}\\n      {% if sc.data_type != tc.data_type and not sc.can_expand_to(other_column=tc) %}\\n        {{ result.append( { 'column_name': tc.name, 'new_type': sc.data_type } ) }}\\n      {% endif %}\\n    {% endif %}\\n  {% endfor %}\\n\\n  {{ return(result) }}\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4954612,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_merge_update_columns\": {\n      \"name\": \"get_merge_update_columns\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/models/incremental/column_helpers.sql\",\n      \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\",\n      \"unique_id\": \"macro.dbt.get_merge_update_columns\",\n      \"macro_sql\": \"{% macro get_merge_update_columns(merge_update_columns, merge_exclude_columns, dest_columns) %}\\n  {{ return(adapter.dispatch('get_merge_update_columns', 'dbt')(merge_update_columns, merge_exclude_columns, dest_columns)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_merge_update_columns\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495462,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_merge_update_columns\": {\n      \"name\": \"default__get_merge_update_columns\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/models/incremental/column_helpers.sql\",\n      \"original_file_path\": \"macros/materializations/models/incremental/column_helpers.sql\",\n      \"unique_id\": \"macro.dbt.default__get_merge_update_columns\",\n      \"macro_sql\": \"{% macro default__get_merge_update_columns(merge_update_columns, merge_exclude_columns, dest_columns) %}\\n  {%- set default_cols = dest_columns | map(attribute=\\\"quoted\\\") | list -%}\\n\\n  {%- if merge_update_columns and merge_exclude_columns -%}\\n    {{ exceptions.raise_compiler_error(\\n        'Model cannot specify merge_update_columns and merge_exclude_columns. Please update model to use only one config'\\n    )}}\\n  {%- elif merge_update_columns -%}\\n    {%- set update_columns = merge_update_columns -%}\\n  {%- elif merge_exclude_columns -%}\\n    {%- set update_columns = [] -%}\\n    {%- for column in dest_columns -%}\\n      {% if column.column | lower not in merge_exclude_columns | map(\\\"lower\\\") | list %}\\n        {%- do update_columns.append(column.quoted) -%}\\n      {% endif %}\\n    {%- endfor -%}\\n  {%- else -%}\\n    {%- set update_columns = default_cols -%}\\n  {%- endif -%}\\n\\n  {{ return(update_columns) }}\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495465,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_merge_sql\": {\n      \"name\": \"get_merge_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/models/incremental/merge.sql\",\n      \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\",\n      \"unique_id\": \"macro.dbt.get_merge_sql\",\n      \"macro_sql\": \"{% macro get_merge_sql(target, source, unique_key, dest_columns, incremental_predicates=none) -%}\\n   -- back compat for old kwarg name\\n  {% set incremental_predicates = kwargs.get('predicates', incremental_predicates) %}\\n  {{ adapter.dispatch('get_merge_sql', 'dbt')(target, source, unique_key, dest_columns, incremental_predicates) }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_merge_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.49549,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_merge_sql\": {\n      \"name\": \"default__get_merge_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/models/incremental/merge.sql\",\n      \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\",\n      \"unique_id\": \"macro.dbt.default__get_merge_sql\",\n      \"macro_sql\": \"{% macro default__get_merge_sql(target, source, unique_key, dest_columns, incremental_predicates=none) -%}\\n    {%- set predicates = [] if incremental_predicates is none else [] + incremental_predicates -%}\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n    {%- set merge_update_columns = config.get('merge_update_columns') -%}\\n    {%- set merge_exclude_columns = config.get('merge_exclude_columns') -%}\\n    {%- set update_columns = get_merge_update_columns(merge_update_columns, merge_exclude_columns, dest_columns) -%}\\n    {%- set sql_header = config.get('sql_header', none) -%}\\n\\n    {% if unique_key %}\\n        {% if unique_key is sequence and unique_key is not mapping and unique_key is not string %}\\n            {% for key in unique_key %}\\n                {% set this_key_match %}\\n                    DBT_INTERNAL_SOURCE.{{ key }} = DBT_INTERNAL_DEST.{{ key }}\\n                {% endset %}\\n                {% do predicates.append(this_key_match) %}\\n            {% endfor %}\\n        {% else %}\\n            {% set source_unique_key = (\\\"DBT_INTERNAL_SOURCE.\\\" ~ unique_key) | trim %}\\n\\t    {% set target_unique_key = (\\\"DBT_INTERNAL_DEST.\\\" ~ unique_key) | trim %}\\n\\t    {% set unique_key_match = equals(source_unique_key, target_unique_key) | trim %}\\n            {% do predicates.append(unique_key_match) %}\\n        {% endif %}\\n    {% else %}\\n        {% do predicates.append('FALSE') %}\\n    {% endif %}\\n\\n    {{ sql_header if sql_header is not none }}\\n\\n    merge into {{ target }} as DBT_INTERNAL_DEST\\n        using {{ source }} as DBT_INTERNAL_SOURCE\\n        on {{\\\"(\\\" ~ predicates | join(\\\") and (\\\") ~ \\\")\\\"}}\\n\\n    {% if unique_key %}\\n    when matched then update set\\n        {% for column_name in update_columns -%}\\n            {{ column_name }} = DBT_INTERNAL_SOURCE.{{ column_name }}\\n            {%- if not loop.last %}, {%- endif %}\\n        {%- endfor %}\\n    {% endif %}\\n\\n    when not matched then insert\\n        ({{ dest_cols_csv }})\\n    values\\n        ({{ dest_cols_csv }})\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.get_quoted_csv\",\n          \"macro.dbt.get_merge_update_columns\",\n          \"macro.dbt.equals\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4954932,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_delete_insert_merge_sql\": {\n      \"name\": \"get_delete_insert_merge_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/models/incremental/merge.sql\",\n      \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\",\n      \"unique_id\": \"macro.dbt.get_delete_insert_merge_sql\",\n      \"macro_sql\": \"{% macro get_delete_insert_merge_sql(target, source, unique_key, dest_columns, incremental_predicates) -%}\\n  {{ adapter.dispatch('get_delete_insert_merge_sql', 'dbt')(target, source, unique_key, dest_columns, incremental_predicates) }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_delete_insert_merge_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495501,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_delete_insert_merge_sql\": {\n      \"name\": \"default__get_delete_insert_merge_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/models/incremental/merge.sql\",\n      \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\",\n      \"unique_id\": \"macro.dbt.default__get_delete_insert_merge_sql\",\n      \"macro_sql\": \"{% macro default__get_delete_insert_merge_sql(target, source, unique_key, dest_columns, incremental_predicates) -%}\\n\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n\\n    {% if unique_key %}\\n        {% if unique_key is string %}\\n        {% set unique_key = [unique_key] %}\\n        {% endif %}\\n\\n        {%- set unique_key_str = unique_key|join(', ') -%}\\n\\n        delete from {{ target }} as DBT_INTERNAL_DEST\\n        where ({{ unique_key_str }}) in (\\n            select distinct {{ unique_key_str }}\\n            from {{ source }} as DBT_INTERNAL_SOURCE\\n        )\\n        {%- if incremental_predicates %}\\n            {% for predicate in incremental_predicates %}\\n                and {{ predicate }}\\n            {% endfor %}\\n        {%- endif -%};\\n\\n    {% endif %}\\n\\n    insert into {{ target }} ({{ dest_cols_csv }})\\n    (\\n        select {{ dest_cols_csv }}\\n        from {{ source }}\\n    )\\n\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.get_quoted_csv\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4955049,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_insert_overwrite_merge_sql\": {\n      \"name\": \"get_insert_overwrite_merge_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/models/incremental/merge.sql\",\n      \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\",\n      \"unique_id\": \"macro.dbt.get_insert_overwrite_merge_sql\",\n      \"macro_sql\": \"{% macro get_insert_overwrite_merge_sql(target, source, dest_columns, predicates, include_sql_header=false) -%}\\n  {{ adapter.dispatch('get_insert_overwrite_merge_sql', 'dbt')(target, source, dest_columns, predicates, include_sql_header) }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_insert_overwrite_merge_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495507,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_insert_overwrite_merge_sql\": {\n      \"name\": \"default__get_insert_overwrite_merge_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/models/incremental/merge.sql\",\n      \"original_file_path\": \"macros/materializations/models/incremental/merge.sql\",\n      \"unique_id\": \"macro.dbt.default__get_insert_overwrite_merge_sql\",\n      \"macro_sql\": \"{% macro default__get_insert_overwrite_merge_sql(target, source, dest_columns, predicates, include_sql_header) -%}\\n    {#-- The only time include_sql_header is True: --#}\\n    {#-- BigQuery + insert_overwrite strategy + \\\"static\\\" partitions config --#}\\n    {#-- We should consider including the sql header at the materialization level instead --#}\\n\\n    {%- set predicates = [] if predicates is none else [] + predicates -%}\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n    {%- set sql_header = config.get('sql_header', none) -%}\\n\\n    {{ sql_header if sql_header is not none and include_sql_header }}\\n\\n    merge into {{ target }} as DBT_INTERNAL_DEST\\n        using {{ source }} as DBT_INTERNAL_SOURCE\\n        on FALSE\\n\\n    when not matched by source\\n        {% if predicates %} and {{ predicates | join(' and ') }} {% endif %}\\n        then delete\\n\\n    when not matched then insert\\n        ({{ dest_cols_csv }})\\n    values\\n        ({{ dest_cols_csv }})\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.get_quoted_csv\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495509,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.is_incremental\": {\n      \"name\": \"is_incremental\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/models/incremental/is_incremental.sql\",\n      \"original_file_path\": \"macros/materializations/models/incremental/is_incremental.sql\",\n      \"unique_id\": \"macro.dbt.is_incremental\",\n      \"macro_sql\": \"{% macro is_incremental() %}\\n    {#-- do not run introspective queries in parsing #}\\n    {% if not execute %}\\n        {{ return(False) }}\\n    {% else %}\\n        {% set relation = adapter.get_relation(this.database, this.schema, this.table) %}\\n        {{ return(relation is not none\\n                  and relation.type == 'table'\\n                  and model.config.materialized == 'incremental'\\n                  and not should_full_refresh()) }}\\n    {% endif %}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.should_full_refresh\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495518,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_incremental_append_sql\": {\n      \"name\": \"get_incremental_append_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/models/incremental/strategies.sql\",\n      \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\",\n      \"unique_id\": \"macro.dbt.get_incremental_append_sql\",\n      \"macro_sql\": \"{% macro get_incremental_append_sql(arg_dict) %}\\n\\n  {{ return(adapter.dispatch('get_incremental_append_sql', 'dbt')(arg_dict)) }}\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_incremental_append_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4955251,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_incremental_append_sql\": {\n      \"name\": \"default__get_incremental_append_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/models/incremental/strategies.sql\",\n      \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\",\n      \"unique_id\": \"macro.dbt.default__get_incremental_append_sql\",\n      \"macro_sql\": \"{% macro default__get_incremental_append_sql(arg_dict) %}\\n\\n  {% do return(get_insert_into_sql(arg_dict[\\\"target_relation\\\"], arg_dict[\\\"temp_relation\\\"], arg_dict[\\\"dest_columns\\\"])) %}\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.get_insert_into_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495527,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_incremental_delete_insert_sql\": {\n      \"name\": \"get_incremental_delete_insert_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/models/incremental/strategies.sql\",\n      \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\",\n      \"unique_id\": \"macro.dbt.get_incremental_delete_insert_sql\",\n      \"macro_sql\": \"{% macro get_incremental_delete_insert_sql(arg_dict) %}\\n\\n  {{ return(adapter.dispatch('get_incremental_delete_insert_sql', 'dbt')(arg_dict)) }}\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_incremental_delete_insert_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.49553,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_incremental_delete_insert_sql\": {\n      \"name\": \"default__get_incremental_delete_insert_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/models/incremental/strategies.sql\",\n      \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\",\n      \"unique_id\": \"macro.dbt.default__get_incremental_delete_insert_sql\",\n      \"macro_sql\": \"{% macro default__get_incremental_delete_insert_sql(arg_dict) %}\\n\\n  {% do return(get_delete_insert_merge_sql(arg_dict[\\\"target_relation\\\"], arg_dict[\\\"temp_relation\\\"], arg_dict[\\\"unique_key\\\"], arg_dict[\\\"dest_columns\\\"], arg_dict[\\\"incremental_predicates\\\"])) %}\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.get_delete_insert_merge_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495532,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_incremental_merge_sql\": {\n      \"name\": \"get_incremental_merge_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/models/incremental/strategies.sql\",\n      \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\",\n      \"unique_id\": \"macro.dbt.get_incremental_merge_sql\",\n      \"macro_sql\": \"{% macro get_incremental_merge_sql(arg_dict) %}\\n\\n  {{ return(adapter.dispatch('get_incremental_merge_sql', 'dbt')(arg_dict)) }}\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_incremental_merge_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4955342,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_incremental_merge_sql\": {\n      \"name\": \"default__get_incremental_merge_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/models/incremental/strategies.sql\",\n      \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\",\n      \"unique_id\": \"macro.dbt.default__get_incremental_merge_sql\",\n      \"macro_sql\": \"{% macro default__get_incremental_merge_sql(arg_dict) %}\\n\\n  {% do return(get_merge_sql(arg_dict[\\\"target_relation\\\"], arg_dict[\\\"temp_relation\\\"], arg_dict[\\\"unique_key\\\"], arg_dict[\\\"dest_columns\\\"], arg_dict[\\\"incremental_predicates\\\"])) %}\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.get_merge_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495536,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_incremental_insert_overwrite_sql\": {\n      \"name\": \"get_incremental_insert_overwrite_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/models/incremental/strategies.sql\",\n      \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\",\n      \"unique_id\": \"macro.dbt.get_incremental_insert_overwrite_sql\",\n      \"macro_sql\": \"{% macro get_incremental_insert_overwrite_sql(arg_dict) %}\\n\\n  {{ return(adapter.dispatch('get_incremental_insert_overwrite_sql', 'dbt')(arg_dict)) }}\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_incremental_insert_overwrite_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495538,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_incremental_insert_overwrite_sql\": {\n      \"name\": \"default__get_incremental_insert_overwrite_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/models/incremental/strategies.sql\",\n      \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\",\n      \"unique_id\": \"macro.dbt.default__get_incremental_insert_overwrite_sql\",\n      \"macro_sql\": \"{% macro default__get_incremental_insert_overwrite_sql(arg_dict) %}\\n\\n  {% do return(get_insert_overwrite_merge_sql(arg_dict[\\\"target_relation\\\"], arg_dict[\\\"temp_relation\\\"], arg_dict[\\\"dest_columns\\\"], arg_dict[\\\"incremental_predicates\\\"])) %}\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.get_insert_overwrite_merge_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.49554,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_incremental_default_sql\": {\n      \"name\": \"get_incremental_default_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/models/incremental/strategies.sql\",\n      \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\",\n      \"unique_id\": \"macro.dbt.get_incremental_default_sql\",\n      \"macro_sql\": \"{% macro get_incremental_default_sql(arg_dict) %}\\n\\n  {{ return(adapter.dispatch('get_incremental_default_sql', 'dbt')(arg_dict)) }}\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__get_incremental_default_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495543,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_incremental_default_sql\": {\n      \"name\": \"default__get_incremental_default_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/models/incremental/strategies.sql\",\n      \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\",\n      \"unique_id\": \"macro.dbt.default__get_incremental_default_sql\",\n      \"macro_sql\": \"{% macro default__get_incremental_default_sql(arg_dict) %}\\n\\n  {% do return(get_incremental_append_sql(arg_dict)) %}\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.get_incremental_append_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495546,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_incremental_microbatch_sql\": {\n      \"name\": \"get_incremental_microbatch_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/models/incremental/strategies.sql\",\n      \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\",\n      \"unique_id\": \"macro.dbt.get_incremental_microbatch_sql\",\n      \"macro_sql\": \"{% macro get_incremental_microbatch_sql(arg_dict) %}\\n\\n  {{ return(adapter.dispatch('get_incremental_microbatch_sql', 'dbt')(arg_dict)) }}\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__get_incremental_microbatch_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495548,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_incremental_microbatch_sql\": {\n      \"name\": \"default__get_incremental_microbatch_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/models/incremental/strategies.sql\",\n      \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\",\n      \"unique_id\": \"macro.dbt.default__get_incremental_microbatch_sql\",\n      \"macro_sql\": \"{% macro default__get_incremental_microbatch_sql(arg_dict) %}\\n\\n  {{ exceptions.raise_not_implemented('microbatch materialization strategy not implemented for adapter ' + adapter.type()) }}\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.49555,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_insert_into_sql\": {\n      \"name\": \"get_insert_into_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/models/incremental/strategies.sql\",\n      \"original_file_path\": \"macros/materializations/models/incremental/strategies.sql\",\n      \"unique_id\": \"macro.dbt.get_insert_into_sql\",\n      \"macro_sql\": \"{% macro get_insert_into_sql(target_relation, temp_relation, dest_columns) %}\\n\\n    {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute=\\\"name\\\")) -%}\\n\\n    insert into {{ target_relation }} ({{ dest_cols_csv }})\\n    (\\n        select {{ dest_cols_csv }}\\n        from {{ temp_relation }}\\n    )\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.get_quoted_csv\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495553,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.materialization_incremental_default\": {\n      \"name\": \"materialization_incremental_default\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/models/incremental/incremental.sql\",\n      \"original_file_path\": \"macros/materializations/models/incremental/incremental.sql\",\n      \"unique_id\": \"macro.dbt.materialization_incremental_default\",\n      \"macro_sql\": \"{% materialization incremental, default -%}\\n\\n  -- relations\\n  {%- set existing_relation = load_cached_relation(this) -%}\\n  {%- set target_relation = this.incorporate(type='table') -%}\\n  {%- set temp_relation = make_temp_relation(target_relation)-%}\\n  {%- set intermediate_relation = make_intermediate_relation(target_relation)-%}\\n  {%- set backup_relation_type = 'table' if existing_relation is none else existing_relation.type -%}\\n  {%- set backup_relation = make_backup_relation(target_relation, backup_relation_type) -%}\\n\\n  -- configs\\n  {%- set unique_key = config.get('unique_key') -%}\\n  {%- set full_refresh_mode = (should_full_refresh()  or existing_relation.is_view) -%}\\n  {%- set on_schema_change = incremental_validate_on_schema_change(config.get('on_schema_change'), default='ignore') -%}\\n\\n  -- the temp_ and backup_ relations should not already exist in the database; get_relation\\n  -- will return None in that case. Otherwise, we get a relation that we can drop\\n  -- later, before we try to use this name for the current operation. This has to happen before\\n  -- BEGIN, in a separate transaction\\n  {%- set preexisting_intermediate_relation = load_cached_relation(intermediate_relation)-%}\\n  {%- set preexisting_backup_relation = load_cached_relation(backup_relation) -%}\\n   -- grab current tables grants config for comparision later on\\n  {% set grant_config = config.get('grants') %}\\n  {{ drop_relation_if_exists(preexisting_intermediate_relation) }}\\n  {{ drop_relation_if_exists(preexisting_backup_relation) }}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  {% set to_drop = [] %}\\n\\n  {% set incremental_strategy = config.get('incremental_strategy') or 'default' %}\\n  {% set strategy_sql_macro_func = adapter.get_incremental_strategy_macro(context, incremental_strategy) %}\\n\\n  {% if existing_relation is none %}\\n      {% set build_sql = get_create_table_as_sql(False, target_relation, sql) %}\\n      {% set relation_for_indexes = target_relation %}\\n  {% elif full_refresh_mode %}\\n      {% set build_sql = get_create_table_as_sql(False, intermediate_relation, sql) %}\\n      {% set relation_for_indexes = intermediate_relation %}\\n      {% set need_swap = true %}\\n  {% else %}\\n    {% do run_query(get_create_table_as_sql(True, temp_relation, sql)) %}\\n    {% set relation_for_indexes = temp_relation %}\\n    {% set contract_config = config.get('contract') %}\\n    {% if not contract_config or not contract_config.enforced %}\\n      {% do adapter.expand_target_column_types(\\n               from_relation=temp_relation,\\n               to_relation=target_relation) %}\\n    {% endif %}\\n    {#-- Process schema changes. Returns dict of changes if successful. Use source columns for upserting/merging --#}\\n    {% set dest_columns = process_schema_changes(on_schema_change, temp_relation, existing_relation) %}\\n    {% if not dest_columns %}\\n      {% set dest_columns = adapter.get_columns_in_relation(existing_relation) %}\\n    {% endif %}\\n\\n    {#-- Get the incremental_strategy, the macro to use for the strategy, and build the sql --#}\\n    {% set incremental_predicates = config.get('predicates', none) or config.get('incremental_predicates', none) %}\\n    {% set strategy_arg_dict = ({'target_relation': target_relation, 'temp_relation': temp_relation, 'unique_key': unique_key, 'dest_columns': dest_columns, 'incremental_predicates': incremental_predicates }) %}\\n    {% set build_sql = strategy_sql_macro_func(strategy_arg_dict) %}\\n\\n  {% endif %}\\n\\n  {% call statement(\\\"main\\\") %}\\n      {{ build_sql }}\\n  {% endcall %}\\n\\n  {% if existing_relation is none or existing_relation.is_view or should_full_refresh() %}\\n    {% do create_indexes(relation_for_indexes) %}\\n  {% endif %}\\n\\n  {% if need_swap %}\\n      {% do adapter.rename_relation(target_relation, backup_relation) %}\\n      {% do adapter.rename_relation(intermediate_relation, target_relation) %}\\n      {% do to_drop.append(backup_relation) %}\\n  {% endif %}\\n\\n  {% set should_revoke = should_revoke(existing_relation, full_refresh_mode) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  -- `COMMIT` happens here\\n  {% do adapter.commit() %}\\n\\n  {% for rel in to_drop %}\\n      {% do adapter.drop_relation(rel) %}\\n  {% endfor %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{%- endmaterialization %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.load_cached_relation\",\n          \"macro.dbt.make_temp_relation\",\n          \"macro.dbt.make_intermediate_relation\",\n          \"macro.dbt.make_backup_relation\",\n          \"macro.dbt.should_full_refresh\",\n          \"macro.dbt.incremental_validate_on_schema_change\",\n          \"macro.dbt.drop_relation_if_exists\",\n          \"macro.dbt.run_hooks\",\n          \"macro.dbt.get_create_table_as_sql\",\n          \"macro.dbt.run_query\",\n          \"macro.dbt.process_schema_changes\",\n          \"macro.dbt.statement\",\n          \"macro.dbt.create_indexes\",\n          \"macro.dbt.should_revoke\",\n          \"macro.dbt.apply_grants\",\n          \"macro.dbt.persist_docs\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495564,\n      \"supported_languages\": [\n        \"sql\"\n      ]\n    },\n    \"macro.dbt.incremental_validate_on_schema_change\": {\n      \"name\": \"incremental_validate_on_schema_change\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/models/incremental/on_schema_change.sql\",\n      \"original_file_path\": \"macros/materializations/models/incremental/on_schema_change.sql\",\n      \"unique_id\": \"macro.dbt.incremental_validate_on_schema_change\",\n      \"macro_sql\": \"{% macro incremental_validate_on_schema_change(on_schema_change, default='ignore') %}\\n\\n   {% if on_schema_change not in ['sync_all_columns', 'append_new_columns', 'fail', 'ignore'] %}\\n\\n     {% set log_message = 'Invalid value for on_schema_change (%s) specified. Setting default value of %s.' % (on_schema_change, default) %}\\n     {% do log(log_message) %}\\n\\n     {{ return(default) }}\\n\\n   {% else %}\\n\\n     {{ return(on_schema_change) }}\\n\\n   {% endif %}\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495577,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.check_for_schema_changes\": {\n      \"name\": \"check_for_schema_changes\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/models/incremental/on_schema_change.sql\",\n      \"original_file_path\": \"macros/materializations/models/incremental/on_schema_change.sql\",\n      \"unique_id\": \"macro.dbt.check_for_schema_changes\",\n      \"macro_sql\": \"{% macro check_for_schema_changes(source_relation, target_relation) %}\\n\\n  {% set schema_changed = False %}\\n\\n  {%- set source_columns = adapter.get_columns_in_relation(source_relation) -%}\\n  {%- set target_columns = adapter.get_columns_in_relation(target_relation) -%}\\n  {%- set source_not_in_target = diff_columns(source_columns, target_columns) -%}\\n  {%- set target_not_in_source = diff_columns(target_columns, source_columns) -%}\\n\\n  {% set new_target_types = diff_column_data_types(source_columns, target_columns) %}\\n\\n  {% if source_not_in_target != [] %}\\n    {% set schema_changed = True %}\\n  {% elif target_not_in_source != [] or new_target_types != [] %}\\n    {% set schema_changed = True %}\\n  {% elif new_target_types != [] %}\\n    {% set schema_changed = True %}\\n  {% endif %}\\n\\n  {% set changes_dict = {\\n    'schema_changed': schema_changed,\\n    'source_not_in_target': source_not_in_target,\\n    'target_not_in_source': target_not_in_source,\\n    'source_columns': source_columns,\\n    'target_columns': target_columns,\\n    'new_target_types': new_target_types\\n  } %}\\n\\n  {% set msg %}\\n    In {{ target_relation }}:\\n        Schema changed: {{ schema_changed }}\\n        Source columns not in target: {{ source_not_in_target }}\\n        Target columns not in source: {{ target_not_in_source }}\\n        New column types: {{ new_target_types }}\\n  {% endset %}\\n\\n  {% do log(msg) %}\\n\\n  {{ return(changes_dict) }}\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.diff_columns\",\n          \"macro.dbt.diff_column_data_types\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4955788,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.sync_column_schemas\": {\n      \"name\": \"sync_column_schemas\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/models/incremental/on_schema_change.sql\",\n      \"original_file_path\": \"macros/materializations/models/incremental/on_schema_change.sql\",\n      \"unique_id\": \"macro.dbt.sync_column_schemas\",\n      \"macro_sql\": \"{% macro sync_column_schemas(on_schema_change, target_relation, schema_changes_dict) %}\\n\\n  {%- set add_to_target_arr = schema_changes_dict['source_not_in_target'] -%}\\n\\n  {%- if on_schema_change == 'append_new_columns'-%}\\n     {%- if add_to_target_arr | length > 0 -%}\\n       {%- do alter_relation_add_remove_columns(target_relation, add_to_target_arr, none) -%}\\n     {%- endif -%}\\n\\n  {% elif on_schema_change == 'sync_all_columns' %}\\n     {%- set remove_from_target_arr = schema_changes_dict['target_not_in_source'] -%}\\n     {%- set new_target_types = schema_changes_dict['new_target_types'] -%}\\n\\n     {% if add_to_target_arr | length > 0 or remove_from_target_arr | length > 0 %}\\n       {%- do alter_relation_add_remove_columns(target_relation, add_to_target_arr, remove_from_target_arr) -%}\\n     {% endif %}\\n\\n     {% if new_target_types != [] %}\\n       {% for ntt in new_target_types %}\\n         {% set column_name = ntt['column_name'] %}\\n         {% set new_type = ntt['new_type'] %}\\n         {% do alter_column_type(target_relation, column_name, new_type) %}\\n       {% endfor %}\\n     {% endif %}\\n\\n  {% endif %}\\n\\n  {% set schema_change_message %}\\n    In {{ target_relation }}:\\n        Schema change approach: {{ on_schema_change }}\\n        Columns added: {{ add_to_target_arr }}\\n        Columns removed: {{ remove_from_target_arr }}\\n        Data types changed: {{ new_target_types }}\\n  {% endset %}\\n\\n  {% do log(schema_change_message) %}\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.alter_relation_add_remove_columns\",\n          \"macro.dbt.alter_column_type\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495583,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.process_schema_changes\": {\n      \"name\": \"process_schema_changes\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/models/incremental/on_schema_change.sql\",\n      \"original_file_path\": \"macros/materializations/models/incremental/on_schema_change.sql\",\n      \"unique_id\": \"macro.dbt.process_schema_changes\",\n      \"macro_sql\": \"{% macro process_schema_changes(on_schema_change, source_relation, target_relation) %}\\n\\n    {% if on_schema_change == 'ignore' %}\\n\\n     {{ return({}) }}\\n\\n    {% else %}\\n\\n      {% set schema_changes_dict = check_for_schema_changes(source_relation, target_relation) %}\\n\\n      {% if schema_changes_dict['schema_changed'] %}\\n\\n        {% if on_schema_change == 'fail' %}\\n\\n          {% set fail_msg %}\\n              The source and target schemas on this incremental model are out of sync!\\n              They can be reconciled in several ways:\\n                - set the `on_schema_change` config to either append_new_columns or sync_all_columns, depending on your situation.\\n                - Re-run the incremental model with `full_refresh: True` to update the target schema.\\n                - update the schema manually and re-run the process.\\n\\n              Additional troubleshooting context:\\n                 Source columns not in target: {{ schema_changes_dict['source_not_in_target'] }}\\n                 Target columns not in source: {{ schema_changes_dict['target_not_in_source'] }}\\n                 New column types: {{ schema_changes_dict['new_target_types'] }}\\n          {% endset %}\\n\\n          {% do exceptions.raise_compiler_error(fail_msg) %}\\n\\n        {# -- unless we ignore, run the sync operation per the config #}\\n        {% else %}\\n\\n          {% do sync_column_schemas(on_schema_change, target_relation, schema_changes_dict) %}\\n\\n        {% endif %}\\n\\n      {% endif %}\\n\\n      {{ return(schema_changes_dict['source_columns']) }}\\n\\n    {% endif %}\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.check_for_schema_changes\",\n          \"macro.dbt.sync_column_schemas\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4955862,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.can_clone_table\": {\n      \"name\": \"can_clone_table\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/models/clone/can_clone_table.sql\",\n      \"original_file_path\": \"macros/materializations/models/clone/can_clone_table.sql\",\n      \"unique_id\": \"macro.dbt.can_clone_table\",\n      \"macro_sql\": \"{% macro can_clone_table() %}\\n    {{ return(adapter.dispatch('can_clone_table', 'dbt')()) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__can_clone_table\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495593,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__can_clone_table\": {\n      \"name\": \"default__can_clone_table\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/models/clone/can_clone_table.sql\",\n      \"original_file_path\": \"macros/materializations/models/clone/can_clone_table.sql\",\n      \"unique_id\": \"macro.dbt.default__can_clone_table\",\n      \"macro_sql\": \"{% macro default__can_clone_table() %}\\n    {{ return(False) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4955971,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.create_or_replace_clone\": {\n      \"name\": \"create_or_replace_clone\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/models/clone/create_or_replace_clone.sql\",\n      \"original_file_path\": \"macros/materializations/models/clone/create_or_replace_clone.sql\",\n      \"unique_id\": \"macro.dbt.create_or_replace_clone\",\n      \"macro_sql\": \"{% macro create_or_replace_clone(this_relation, defer_relation) %}\\n    {{ return(adapter.dispatch('create_or_replace_clone', 'dbt')(this_relation, defer_relation)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__create_or_replace_clone\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495604,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__create_or_replace_clone\": {\n      \"name\": \"default__create_or_replace_clone\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/models/clone/create_or_replace_clone.sql\",\n      \"original_file_path\": \"macros/materializations/models/clone/create_or_replace_clone.sql\",\n      \"unique_id\": \"macro.dbt.default__create_or_replace_clone\",\n      \"macro_sql\": \"{% macro default__create_or_replace_clone(this_relation, defer_relation) %}\\n    create or replace table {{ this_relation.render() }} clone {{ defer_relation.render() }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495606,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.materialization_clone_default\": {\n      \"name\": \"materialization_clone_default\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/models/clone/clone.sql\",\n      \"original_file_path\": \"macros/materializations/models/clone/clone.sql\",\n      \"unique_id\": \"macro.dbt.materialization_clone_default\",\n      \"macro_sql\": \"{%- materialization clone, default -%}\\n\\n  {%- set relations = {'relations': []} -%}\\n\\n  {%- if not defer_relation -%}\\n      -- nothing to do\\n      {{ log(\\\"No relation found in state manifest for \\\" ~ model.unique_id, info=True) }}\\n      {{ return(relations) }}\\n  {%- endif -%}\\n\\n  {%- set existing_relation = load_cached_relation(this) -%}\\n\\n  {%- if existing_relation and not flags.FULL_REFRESH -%}\\n      -- noop!\\n      {{ log(\\\"Relation \\\" ~ existing_relation ~ \\\" already exists\\\", info=True) }}\\n      {{ return(relations) }}\\n  {%- endif -%}\\n\\n  {%- set other_existing_relation = load_cached_relation(defer_relation) -%}\\n\\n  -- If this is a database that can do zero-copy cloning of tables, and the other relation is a table, then this will be a table\\n  -- Otherwise, this will be a view\\n\\n  {% set can_clone_table = can_clone_table() %}\\n\\n  {%- if other_existing_relation and other_existing_relation.type == 'table' and can_clone_table -%}\\n\\n      {%- set target_relation = this.incorporate(type='table') -%}\\n      {% if existing_relation is not none and not existing_relation.is_table %}\\n        {{ log(\\\"Dropping relation \\\" ~ existing_relation.render() ~ \\\" because it is of type \\\" ~ existing_relation.type) }}\\n        {{ drop_relation_if_exists(existing_relation) }}\\n      {% endif %}\\n\\n      -- as a general rule, data platforms that can clone tables can also do atomic 'create or replace'\\n      {% if target_relation.database == defer_relation.database and\\n            target_relation.schema == defer_relation.schema and\\n            target_relation.identifier == defer_relation.identifier %}\\n        {{ log(\\\"Target relation and defer relation are the same, skipping clone for relation: \\\" ~ target_relation.render()) }}\\n      {% else %}\\n        {% call statement('main') %}\\n            {{ create_or_replace_clone(target_relation, defer_relation) }}\\n        {% endcall %}\\n      {% endif %}\\n      {% set should_revoke = should_revoke(existing_relation, full_refresh_mode=True) %}\\n      {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n      {% do persist_docs(target_relation, model) %}\\n\\n      {{ return({'relations': [target_relation]}) }}\\n\\n  {%- else -%}\\n\\n      {%- set target_relation = this.incorporate(type='view') -%}\\n\\n      -- reuse the view materialization\\n      -- TODO: support actual dispatch for materialization macros\\n      -- Tracking ticket: https://github.com/dbt-labs/dbt-core/issues/7799\\n      {% set search_name = \\\"materialization_view_\\\" ~ adapter.type() %}\\n      {% if not search_name in context %}\\n          {% set search_name = \\\"materialization_view_default\\\" %}\\n      {% endif %}\\n      {% set materialization_macro = context[search_name] %}\\n      {% set relations = materialization_macro() %}\\n      {{ return(relations) }}\\n\\n  {%- endif -%}\\n\\n{%- endmaterialization -%}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.load_cached_relation\",\n          \"macro.dbt.can_clone_table\",\n          \"macro.dbt.drop_relation_if_exists\",\n          \"macro.dbt.statement\",\n          \"macro.dbt.create_or_replace_clone\",\n          \"macro.dbt.should_revoke\",\n          \"macro.dbt.apply_grants\",\n          \"macro.dbt.persist_docs\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4956129,\n      \"supported_languages\": [\n        \"sql\"\n      ]\n    },\n    \"macro.dbt.materialization_seed_default\": {\n      \"name\": \"materialization_seed_default\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/seeds/seed.sql\",\n      \"original_file_path\": \"macros/materializations/seeds/seed.sql\",\n      \"unique_id\": \"macro.dbt.materialization_seed_default\",\n      \"macro_sql\": \"{% materialization seed, default %}\\n\\n  {%- set identifier = model['alias'] -%}\\n  {%- set full_refresh_mode = (should_full_refresh()) -%}\\n\\n  {%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%}\\n\\n  {%- set exists_as_table = (old_relation is not none and old_relation.is_table) -%}\\n  {%- set exists_as_view = (old_relation is not none and old_relation.is_view) -%}\\n\\n  {%- set grant_config = config.get('grants') -%}\\n  {%- set agate_table = load_agate_table() -%}\\n  -- grab current tables grants config for comparison later on\\n\\n  {%- do store_result('agate_table', response='OK', agate_table=agate_table) -%}\\n\\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\\n\\n  -- `BEGIN` happens here:\\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\\n\\n  -- build model\\n  {% set create_table_sql = \\\"\\\" %}\\n  {% if exists_as_view %}\\n    {{ exceptions.raise_compiler_error(\\\"Cannot seed to '{}', it is a view\\\".format(old_relation.render())) }}\\n  {% elif exists_as_table %}\\n    {% set create_table_sql = reset_csv_table(model, full_refresh_mode, old_relation, agate_table) %}\\n  {% else %}\\n    {% set create_table_sql = create_csv_table(model, agate_table) %}\\n  {% endif %}\\n\\n  {% set code = 'CREATE' if full_refresh_mode else 'INSERT' %}\\n  {% set rows_affected = (agate_table.rows | length) %}\\n  {% set sql = load_csv_rows(model, agate_table) %}\\n\\n  {% call noop_statement('main', code ~ ' ' ~ rows_affected, code, rows_affected) %}\\n    {{ get_csv_sql(create_table_sql, sql) }};\\n  {% endcall %}\\n\\n  {% set target_relation = this.incorporate(type='table') %}\\n\\n  {% set should_revoke = should_revoke(old_relation, full_refresh_mode) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {% do persist_docs(target_relation, model) %}\\n\\n  {% if full_refresh_mode or not exists_as_table %}\\n    {% do create_indexes(target_relation) %}\\n  {% endif %}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\\n\\n  -- `COMMIT` happens here\\n  {{ adapter.commit() }}\\n\\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{% endmaterialization %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.should_full_refresh\",\n          \"macro.dbt.run_hooks\",\n          \"macro.dbt.reset_csv_table\",\n          \"macro.dbt.create_csv_table\",\n          \"macro.dbt.load_csv_rows\",\n          \"macro.dbt.noop_statement\",\n          \"macro.dbt.get_csv_sql\",\n          \"macro.dbt.should_revoke\",\n          \"macro.dbt.apply_grants\",\n          \"macro.dbt.persist_docs\",\n          \"macro.dbt.create_indexes\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495622,\n      \"supported_languages\": [\n        \"sql\"\n      ]\n    },\n    \"macro.dbt.create_csv_table\": {\n      \"name\": \"create_csv_table\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/seeds/helpers.sql\",\n      \"original_file_path\": \"macros/materializations/seeds/helpers.sql\",\n      \"unique_id\": \"macro.dbt.create_csv_table\",\n      \"macro_sql\": \"{% macro create_csv_table(model, agate_table) -%}\\n  {{ adapter.dispatch('create_csv_table', 'dbt')(model, agate_table) }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__create_csv_table\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495633,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__create_csv_table\": {\n      \"name\": \"default__create_csv_table\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/seeds/helpers.sql\",\n      \"original_file_path\": \"macros/materializations/seeds/helpers.sql\",\n      \"unique_id\": \"macro.dbt.default__create_csv_table\",\n      \"macro_sql\": \"{% macro default__create_csv_table(model, agate_table) %}\\n  {%- set column_override = model['config'].get('column_types', {}) -%}\\n  {%- set quote_seed_column = model['config'].get('quote_columns', None) -%}\\n\\n  {% set sql %}\\n    create table {{ this.render() }} (\\n        {%- for col_name in agate_table.column_names -%}\\n            {%- set inferred_type = adapter.convert_type(agate_table, loop.index0) -%}\\n            {%- set type = column_override.get(col_name, inferred_type) -%}\\n            {%- set column_name = (col_name | string) -%}\\n            {{ adapter.quote_seed_column(column_name, quote_seed_column) }} {{ type }} {%- if not loop.last -%}, {%- endif -%}\\n        {%- endfor -%}\\n    )\\n  {% endset %}\\n\\n  {% call statement('_') -%}\\n    {{ sql }}\\n  {%- endcall %}\\n\\n  {{ return(sql) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.statement\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495637,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.reset_csv_table\": {\n      \"name\": \"reset_csv_table\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/seeds/helpers.sql\",\n      \"original_file_path\": \"macros/materializations/seeds/helpers.sql\",\n      \"unique_id\": \"macro.dbt.reset_csv_table\",\n      \"macro_sql\": \"{% macro reset_csv_table(model, full_refresh, old_relation, agate_table) -%}\\n  {{ adapter.dispatch('reset_csv_table', 'dbt')(model, full_refresh, old_relation, agate_table) }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__reset_csv_table\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495639,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__reset_csv_table\": {\n      \"name\": \"default__reset_csv_table\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/seeds/helpers.sql\",\n      \"original_file_path\": \"macros/materializations/seeds/helpers.sql\",\n      \"unique_id\": \"macro.dbt.default__reset_csv_table\",\n      \"macro_sql\": \"{% macro default__reset_csv_table(model, full_refresh, old_relation, agate_table) %}\\n    {% set sql = \\\"\\\" %}\\n    {% if full_refresh %}\\n        {{ adapter.drop_relation(old_relation) }}\\n        {% set sql = create_csv_table(model, agate_table) %}\\n    {% else %}\\n        {{ adapter.truncate_relation(old_relation) }}\\n        {% set sql = \\\"truncate table \\\" ~ old_relation.render() %}\\n    {% endif %}\\n\\n    {{ return(sql) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.create_csv_table\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495641,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_csv_sql\": {\n      \"name\": \"get_csv_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/seeds/helpers.sql\",\n      \"original_file_path\": \"macros/materializations/seeds/helpers.sql\",\n      \"unique_id\": \"macro.dbt.get_csv_sql\",\n      \"macro_sql\": \"{% macro get_csv_sql(create_or_truncate_sql, insert_sql) %}\\n    {{ adapter.dispatch('get_csv_sql', 'dbt')(create_or_truncate_sql, insert_sql) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_csv_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4956439,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_csv_sql\": {\n      \"name\": \"default__get_csv_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/seeds/helpers.sql\",\n      \"original_file_path\": \"macros/materializations/seeds/helpers.sql\",\n      \"unique_id\": \"macro.dbt.default__get_csv_sql\",\n      \"macro_sql\": \"{% macro default__get_csv_sql(create_or_truncate_sql, insert_sql) %}\\n    {{ create_or_truncate_sql }};\\n    -- dbt seed --\\n    {{ insert_sql }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495646,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_binding_char\": {\n      \"name\": \"get_binding_char\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/seeds/helpers.sql\",\n      \"original_file_path\": \"macros/materializations/seeds/helpers.sql\",\n      \"unique_id\": \"macro.dbt.get_binding_char\",\n      \"macro_sql\": \"{% macro get_binding_char() -%}\\n  {{ adapter.dispatch('get_binding_char', 'dbt')() }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_binding_char\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495656,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_binding_char\": {\n      \"name\": \"default__get_binding_char\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/seeds/helpers.sql\",\n      \"original_file_path\": \"macros/materializations/seeds/helpers.sql\",\n      \"unique_id\": \"macro.dbt.default__get_binding_char\",\n      \"macro_sql\": \"{% macro default__get_binding_char() %}\\n  {{ return('%s') }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495659,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_batch_size\": {\n      \"name\": \"get_batch_size\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/seeds/helpers.sql\",\n      \"original_file_path\": \"macros/materializations/seeds/helpers.sql\",\n      \"unique_id\": \"macro.dbt.get_batch_size\",\n      \"macro_sql\": \"{% macro get_batch_size() -%}\\n  {{ return(adapter.dispatch('get_batch_size', 'dbt')()) }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_batch_size\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495661,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_batch_size\": {\n      \"name\": \"default__get_batch_size\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/seeds/helpers.sql\",\n      \"original_file_path\": \"macros/materializations/seeds/helpers.sql\",\n      \"unique_id\": \"macro.dbt.default__get_batch_size\",\n      \"macro_sql\": \"{% macro default__get_batch_size() %}\\n  {{ return(10000) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4956632,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_seed_column_quoted_csv\": {\n      \"name\": \"get_seed_column_quoted_csv\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/seeds/helpers.sql\",\n      \"original_file_path\": \"macros/materializations/seeds/helpers.sql\",\n      \"unique_id\": \"macro.dbt.get_seed_column_quoted_csv\",\n      \"macro_sql\": \"{% macro get_seed_column_quoted_csv(model, column_names) %}\\n  {%- set quote_seed_column = model['config'].get('quote_columns', None) -%}\\n    {% set quoted = [] %}\\n    {% for col in column_names -%}\\n        {%- do quoted.append(adapter.quote_seed_column(col, quote_seed_column)) -%}\\n    {%- endfor %}\\n\\n    {%- set dest_cols_csv = quoted | join(', ') -%}\\n    {{ return(dest_cols_csv) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4956648,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.load_csv_rows\": {\n      \"name\": \"load_csv_rows\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/seeds/helpers.sql\",\n      \"original_file_path\": \"macros/materializations/seeds/helpers.sql\",\n      \"unique_id\": \"macro.dbt.load_csv_rows\",\n      \"macro_sql\": \"{% macro load_csv_rows(model, agate_table) -%}\\n  {{ adapter.dispatch('load_csv_rows', 'dbt')(model, agate_table) }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__load_csv_rows\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495668,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__load_csv_rows\": {\n      \"name\": \"default__load_csv_rows\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/seeds/helpers.sql\",\n      \"original_file_path\": \"macros/materializations/seeds/helpers.sql\",\n      \"unique_id\": \"macro.dbt.default__load_csv_rows\",\n      \"macro_sql\": \"{% macro default__load_csv_rows(model, agate_table) %}\\n\\n  {% set batch_size = get_batch_size() %}\\n\\n  {% set cols_sql = get_seed_column_quoted_csv(model, agate_table.column_names) %}\\n  {% set bindings = [] %}\\n\\n  {% set statements = [] %}\\n\\n  {% for chunk in agate_table.rows | batch(batch_size) %}\\n      {% set bindings = [] %}\\n\\n      {% for row in chunk %}\\n          {% do bindings.extend(row) %}\\n      {% endfor %}\\n\\n      {% set sql %}\\n          insert into {{ this.render() }} ({{ cols_sql }}) values\\n          {% for row in chunk -%}\\n              ({%- for column in agate_table.column_names -%}\\n                  {{ get_binding_char() }}\\n                  {%- if not loop.last%},{%- endif %}\\n              {%- endfor -%})\\n              {%- if not loop.last%},{%- endif %}\\n          {%- endfor %}\\n      {% endset %}\\n\\n      {% do adapter.add_query(sql, bindings=bindings, abridge_sql_log=True) %}\\n\\n      {% if loop.index0 == 0 %}\\n          {% do statements.append(sql) %}\\n      {% endif %}\\n  {% endfor %}\\n\\n  {# Return SQL so we can render it out into the compiled files #}\\n  {{ return(statements[0]) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.get_batch_size\",\n          \"macro.dbt.get_seed_column_quoted_csv\",\n          \"macro.dbt.get_binding_char\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495672,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.scalar_function_sql\": {\n      \"name\": \"scalar_function_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/functions/scalar.sql\",\n      \"original_file_path\": \"macros/materializations/functions/scalar.sql\",\n      \"unique_id\": \"macro.dbt.scalar_function_sql\",\n      \"macro_sql\": \"{% macro scalar_function_sql(target_relation) %}\\n    {{ return(adapter.dispatch('scalar_function_sql', 'dbt')(target_relation)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__scalar_function_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495681,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__scalar_function_sql\": {\n      \"name\": \"default__scalar_function_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/functions/scalar.sql\",\n      \"original_file_path\": \"macros/materializations/functions/scalar.sql\",\n      \"unique_id\": \"macro.dbt.default__scalar_function_sql\",\n      \"macro_sql\": \"{% macro default__scalar_function_sql(target_relation) %}\\n    {{ scalar_function_create_replace_signature_sql(target_relation) }}\\n    {{ scalar_function_body_sql() }};\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.scalar_function_create_replace_signature_sql\",\n          \"macro.dbt.scalar_function_body_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4956841,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.scalar_function_create_replace_signature_sql\": {\n      \"name\": \"scalar_function_create_replace_signature_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/functions/scalar.sql\",\n      \"original_file_path\": \"macros/materializations/functions/scalar.sql\",\n      \"unique_id\": \"macro.dbt.scalar_function_create_replace_signature_sql\",\n      \"macro_sql\": \"{% macro scalar_function_create_replace_signature_sql(target_relation) %}\\n    {{ return(adapter.dispatch('scalar_function_create_replace_signature_sql', 'dbt')(target_relation)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__scalar_function_create_replace_signature_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4956858,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__scalar_function_create_replace_signature_sql\": {\n      \"name\": \"default__scalar_function_create_replace_signature_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/functions/scalar.sql\",\n      \"original_file_path\": \"macros/materializations/functions/scalar.sql\",\n      \"unique_id\": \"macro.dbt.default__scalar_function_create_replace_signature_sql\",\n      \"macro_sql\": \"{% macro default__scalar_function_create_replace_signature_sql(target_relation) %}\\n    CREATE OR REPLACE FUNCTION {{ target_relation.render() }} ({{ formatted_scalar_function_args_sql()}})\\n    RETURNS {{ model.returns.data_type }}\\n    {{ scalar_function_volatility_sql() }}\\n    AS\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.formatted_scalar_function_args_sql\",\n          \"macro.dbt.scalar_function_volatility_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495688,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.formatted_scalar_function_args_sql\": {\n      \"name\": \"formatted_scalar_function_args_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/functions/scalar.sql\",\n      \"original_file_path\": \"macros/materializations/functions/scalar.sql\",\n      \"unique_id\": \"macro.dbt.formatted_scalar_function_args_sql\",\n      \"macro_sql\": \"{% macro formatted_scalar_function_args_sql() %}\\n    {{ return(adapter.dispatch('formatted_scalar_function_args_sql', 'dbt')()) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__formatted_scalar_function_args_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495691,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__formatted_scalar_function_args_sql\": {\n      \"name\": \"default__formatted_scalar_function_args_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/functions/scalar.sql\",\n      \"original_file_path\": \"macros/materializations/functions/scalar.sql\",\n      \"unique_id\": \"macro.dbt.default__formatted_scalar_function_args_sql\",\n      \"macro_sql\": \"{% macro default__formatted_scalar_function_args_sql() %}\\n    {% set args = [] %}\\n    {% for arg in model.arguments -%}\\n        {%- do args.append(arg.name ~ ' ' ~ arg.data_type) -%}\\n    {%- endfor %}\\n    {{ args | join(', ') }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495693,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.scalar_function_body_sql\": {\n      \"name\": \"scalar_function_body_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/functions/scalar.sql\",\n      \"original_file_path\": \"macros/materializations/functions/scalar.sql\",\n      \"unique_id\": \"macro.dbt.scalar_function_body_sql\",\n      \"macro_sql\": \"{% macro scalar_function_body_sql() %}\\n    {{ return(adapter.dispatch('scalar_function_body_sql', 'dbt')()) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__scalar_function_body_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4956958,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__scalar_function_body_sql\": {\n      \"name\": \"default__scalar_function_body_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/functions/scalar.sql\",\n      \"original_file_path\": \"macros/materializations/functions/scalar.sql\",\n      \"unique_id\": \"macro.dbt.default__scalar_function_body_sql\",\n      \"macro_sql\": \"{% macro default__scalar_function_body_sql() %}\\n    $$\\n       {{ model.compiled_code }}\\n    $$ LANGUAGE SQL\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495698,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.scalar_function_volatility_sql\": {\n      \"name\": \"scalar_function_volatility_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/functions/scalar.sql\",\n      \"original_file_path\": \"macros/materializations/functions/scalar.sql\",\n      \"unique_id\": \"macro.dbt.scalar_function_volatility_sql\",\n      \"macro_sql\": \"{% macro scalar_function_volatility_sql() %}\\n    {{ return(adapter.dispatch('scalar_function_volatility_sql', 'dbt')()) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__scalar_function_volatility_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4957,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__scalar_function_volatility_sql\": {\n      \"name\": \"default__scalar_function_volatility_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/functions/scalar.sql\",\n      \"original_file_path\": \"macros/materializations/functions/scalar.sql\",\n      \"unique_id\": \"macro.dbt.default__scalar_function_volatility_sql\",\n      \"macro_sql\": \"{% macro default__scalar_function_volatility_sql() %}\\n    {% set volatility = model.config.get('volatility') %}\\n    {% if volatility == 'deterministic' %}\\n        IMMUTABLE\\n    {% elif volatility == 'stable' %}\\n        STABLE\\n    {% elif volatility == 'non-deterministic' %}\\n        VOLATILE\\n    {% elif volatility != none %}\\n        {# This shouldn't happen unless a new volatility is invented #}\\n        {% do unsupported_volatility_warning(volatility) %}\\n    {% endif %}\\n    {# If no volatility is set, don't add anything and let the data warehouse default it #}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.unsupported_volatility_warning\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4957042,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.unsupported_volatility_warning\": {\n      \"name\": \"unsupported_volatility_warning\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/functions/scalar.sql\",\n      \"original_file_path\": \"macros/materializations/functions/scalar.sql\",\n      \"unique_id\": \"macro.dbt.unsupported_volatility_warning\",\n      \"macro_sql\": \"{% macro unsupported_volatility_warning(volatility) %}\\n    {{ return(adapter.dispatch('unsupported_volatility_warning', 'dbt')(volatility)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__unsupported_volatility_warning\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495706,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__unsupported_volatility_warning\": {\n      \"name\": \"default__unsupported_volatility_warning\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/functions/scalar.sql\",\n      \"original_file_path\": \"macros/materializations/functions/scalar.sql\",\n      \"unique_id\": \"macro.dbt.default__unsupported_volatility_warning\",\n      \"macro_sql\": \"{% macro default__unsupported_volatility_warning(volatility) %}\\n    {% set msg = \\\"Found `\\\" ~ volatility ~ \\\"` volatility specified on function `\\\" ~ model.name ~ \\\"`. This volatility is not supported by \\\" ~ adapter.type() ~ \\\", and will be ignored\\\" %}\\n    {% do exceptions.warn(msg) %}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495708,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.function_execute_build_sql\": {\n      \"name\": \"function_execute_build_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/functions/helpers.sql\",\n      \"original_file_path\": \"macros/materializations/functions/helpers.sql\",\n      \"unique_id\": \"macro.dbt.function_execute_build_sql\",\n      \"macro_sql\": \"{% macro function_execute_build_sql(build_sql, existing_relation, target_relation) %}\\n    {{ return(adapter.dispatch('function_execute_build_sql', 'dbt')(build_sql, existing_relation, target_relation)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__function_execute_build_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495718,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__function_execute_build_sql\": {\n      \"name\": \"default__function_execute_build_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/functions/helpers.sql\",\n      \"original_file_path\": \"macros/materializations/functions/helpers.sql\",\n      \"unique_id\": \"macro.dbt.default__function_execute_build_sql\",\n      \"macro_sql\": \"{% macro default__function_execute_build_sql(build_sql, existing_relation, target_relation) %}\\n\\n    {% set grant_config = config.get('grants') %}\\n\\n    {% call statement(name=\\\"main\\\") %}\\n        {{ build_sql }}\\n    {% endcall %}\\n\\n    {% set should_revoke = should_revoke(existing_relation, full_refresh_mode=True) %}\\n    {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n    {% do persist_docs(target_relation, model) %}\\n\\n    {{ adapter.commit() }}\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.statement\",\n          \"macro.dbt.should_revoke\",\n          \"macro.dbt.apply_grants\",\n          \"macro.dbt.persist_docs\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4957209,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_aggregate_function_create_replace_signature\": {\n      \"name\": \"get_aggregate_function_create_replace_signature\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/functions/aggregate.sql\",\n      \"original_file_path\": \"macros/materializations/functions/aggregate.sql\",\n      \"unique_id\": \"macro.dbt.get_aggregate_function_create_replace_signature\",\n      \"macro_sql\": \"{% macro get_aggregate_function_create_replace_signature(target_relation) %}\\n    {{ return(adapter.dispatch('get_aggregate_function_create_replace_signature', 'dbt')(target_relation)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_aggregate_function_create_replace_signature\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495728,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_aggregate_function_create_replace_signature\": {\n      \"name\": \"default__get_aggregate_function_create_replace_signature\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/functions/aggregate.sql\",\n      \"original_file_path\": \"macros/materializations/functions/aggregate.sql\",\n      \"unique_id\": \"macro.dbt.default__get_aggregate_function_create_replace_signature\",\n      \"macro_sql\": \"{% macro default__get_aggregate_function_create_replace_signature(target_relation) %}\\n    CREATE OR REPLACE AGGREGATE FUNCTION {{ target_relation.render() }} ({{ get_formatted_aggregate_function_args()}})\\n    RETURNS {{ model.returns.data_type }}\\n    {{ get_function_language_specifier() }}\\n    {% if model.get('language') == 'python' %}\\n        {{ get_function_python_options() }}\\n    {% endif %}\\n    {{ scalar_function_volatility_sql() }}\\n    AS\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.get_formatted_aggregate_function_args\",\n          \"macro.dbt.get_function_language_specifier\",\n          \"macro.dbt.get_function_python_options\",\n          \"macro.dbt.scalar_function_volatility_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4957309,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_formatted_aggregate_function_args\": {\n      \"name\": \"get_formatted_aggregate_function_args\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/functions/aggregate.sql\",\n      \"original_file_path\": \"macros/materializations/functions/aggregate.sql\",\n      \"unique_id\": \"macro.dbt.get_formatted_aggregate_function_args\",\n      \"macro_sql\": \"{% macro get_formatted_aggregate_function_args() %}\\n    {{ return(adapter.dispatch('get_formatted_aggregate_function_args', 'dbt')()) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_formatted_aggregate_function_args\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495733,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_formatted_aggregate_function_args\": {\n      \"name\": \"default__get_formatted_aggregate_function_args\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/functions/aggregate.sql\",\n      \"original_file_path\": \"macros/materializations/functions/aggregate.sql\",\n      \"unique_id\": \"macro.dbt.default__get_formatted_aggregate_function_args\",\n      \"macro_sql\": \"{% macro default__get_formatted_aggregate_function_args() %}\\n    {# conveniently we can reuse the sql scalar function args #}\\n    {{ formatted_scalar_function_args_sql() }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.formatted_scalar_function_args_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4957361,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_function_language_specifier\": {\n      \"name\": \"get_function_language_specifier\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/functions/aggregate.sql\",\n      \"original_file_path\": \"macros/materializations/functions/aggregate.sql\",\n      \"unique_id\": \"macro.dbt.get_function_language_specifier\",\n      \"macro_sql\": \"{% macro get_function_language_specifier() %}\\n    {{ return(adapter.dispatch('get_function_language_specifier', 'dbt')()) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_function_language_specifier\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495738,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_function_language_specifier\": {\n      \"name\": \"default__get_function_language_specifier\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/functions/aggregate.sql\",\n      \"original_file_path\": \"macros/materializations/functions/aggregate.sql\",\n      \"unique_id\": \"macro.dbt.default__get_function_language_specifier\",\n      \"macro_sql\": \"{% macro default__get_function_language_specifier() %}\\n    {% set language = model.get('language') %}\\n    {% if language == 'sql' %}\\n        {# generally you dont need to specify the language for sql functions #}\\n    {% elif language == 'python' %}\\n        LANGUAGE PYTHON\\n    {% else %}\\n        {{ 'LANGUAGE ' ~ language.upper() }}\\n    {% endif %}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495739,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_aggregate_function_volatility_specifier\": {\n      \"name\": \"get_aggregate_function_volatility_specifier\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/functions/aggregate.sql\",\n      \"original_file_path\": \"macros/materializations/functions/aggregate.sql\",\n      \"unique_id\": \"macro.dbt.get_aggregate_function_volatility_specifier\",\n      \"macro_sql\": \"{% macro get_aggregate_function_volatility_specifier() %}\\n    {{ return(adapter.dispatch('get_aggregate_function_volatility_specifier', 'dbt')()) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_aggregate_function_volatility_specifier\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495743,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_aggregate_function_volatility_specifier\": {\n      \"name\": \"default__get_aggregate_function_volatility_specifier\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/functions/aggregate.sql\",\n      \"original_file_path\": \"macros/materializations/functions/aggregate.sql\",\n      \"unique_id\": \"macro.dbt.default__get_aggregate_function_volatility_specifier\",\n      \"macro_sql\": \"{% macro default__get_aggregate_function_volatility_specifier() %}\\n    {{ scalar_function_volatility_sql() }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.scalar_function_volatility_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495745,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_function_python_options\": {\n      \"name\": \"get_function_python_options\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/functions/aggregate.sql\",\n      \"original_file_path\": \"macros/materializations/functions/aggregate.sql\",\n      \"unique_id\": \"macro.dbt.get_function_python_options\",\n      \"macro_sql\": \"{% macro get_function_python_options() %}\\n    {{ return(adapter.dispatch('get_function_python_options', 'dbt')()) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_function_python_options\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4957519,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_function_python_options\": {\n      \"name\": \"default__get_function_python_options\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/functions/aggregate.sql\",\n      \"original_file_path\": \"macros/materializations/functions/aggregate.sql\",\n      \"unique_id\": \"macro.dbt.default__get_function_python_options\",\n      \"macro_sql\": \"{% macro default__get_function_python_options() %}\\n    RUNTIME_VERSION = '{{ model.config.get('runtime_version') }}'\\n    HANDLER = '{{ model.config.get('entry_point') }}'\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495754,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.materialization_function_default\": {\n      \"name\": \"materialization_function_default\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/materializations/functions/function.sql\",\n      \"original_file_path\": \"macros/materializations/functions/function.sql\",\n      \"unique_id\": \"macro.dbt.materialization_function_default\",\n      \"macro_sql\": \"{% materialization function, default, supported_languages=['sql', 'python'] %}\\n    {% set existing_relation = load_cached_relation(this) %}\\n    {% set target_relation = this.incorporate(type=this.Function) %}\\n\\n    {{ run_hooks(pre_hooks) }}\\n\\n    {% set function_config = this.get_function_config(model) %}\\n    {% set macro_name = this.get_function_macro_name(function_config) %}\\n\\n    {# Doing this aliasing of adapter.dispatch is a hacky way to disable the static analysis of actually calling adapter.dispatch #}\\n    {# This is necessary because the static analysis breaks being able to dynamically pass a macro_name #}\\n    {% set _dispatch = adapter.dispatch %}\\n\\n    {% set build_sql = _dispatch(macro_name, 'dbt')(target_relation) %}\\n    {{ function_execute_build_sql(build_sql, existing_relation, target_relation) }}\\n    {{ run_hooks(post_hooks) }}\\n\\n    {{ return({'relations': [target_relation]}) }}\\n\\n{% endmaterialization %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.load_cached_relation\",\n          \"macro.dbt.run_hooks\",\n          \"macro.dbt.function_execute_build_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.49576,\n      \"supported_languages\": [\n        \"sql\",\n        \"python\"\n      ]\n    },\n    \"macro.dbt.generate_alias_name\": {\n      \"name\": \"generate_alias_name\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/get_custom_name/get_custom_alias.sql\",\n      \"original_file_path\": \"macros/get_custom_name/get_custom_alias.sql\",\n      \"unique_id\": \"macro.dbt.generate_alias_name\",\n      \"macro_sql\": \"{% macro generate_alias_name(custom_alias_name=none, node=none) -%}\\n    {% do return(adapter.dispatch('generate_alias_name', 'dbt')(custom_alias_name, node)) %}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__generate_alias_name\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495768,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__generate_alias_name\": {\n      \"name\": \"default__generate_alias_name\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/get_custom_name/get_custom_alias.sql\",\n      \"original_file_path\": \"macros/get_custom_name/get_custom_alias.sql\",\n      \"unique_id\": \"macro.dbt.default__generate_alias_name\",\n      \"macro_sql\": \"{% macro default__generate_alias_name(custom_alias_name=none, node=none) -%}\\n\\n    {%- if custom_alias_name -%}\\n\\n        {{ custom_alias_name | trim }}\\n\\n    {%- elif node.version -%}\\n\\n        {{ return(node.name ~ \\\"_v\\\" ~ (node.version | replace(\\\".\\\", \\\"_\\\"))) }}\\n\\n    {%- else -%}\\n\\n        {{ node.name }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495771,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.generate_schema_name\": {\n      \"name\": \"generate_schema_name\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/get_custom_name/get_custom_schema.sql\",\n      \"original_file_path\": \"macros/get_custom_name/get_custom_schema.sql\",\n      \"unique_id\": \"macro.dbt.generate_schema_name\",\n      \"macro_sql\": \"{% macro generate_schema_name(custom_schema_name=none, node=none) -%}\\n    {{ return(adapter.dispatch('generate_schema_name', 'dbt')(custom_schema_name, node)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__generate_schema_name\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4957771,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__generate_schema_name\": {\n      \"name\": \"default__generate_schema_name\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/get_custom_name/get_custom_schema.sql\",\n      \"original_file_path\": \"macros/get_custom_name/get_custom_schema.sql\",\n      \"unique_id\": \"macro.dbt.default__generate_schema_name\",\n      \"macro_sql\": \"{% macro default__generate_schema_name(custom_schema_name, node) -%}\\n\\n    {%- set default_schema = target.schema -%}\\n    {%- if custom_schema_name is none -%}\\n\\n        {{ default_schema }}\\n\\n    {%- else -%}\\n\\n        {{ default_schema }}_{{ custom_schema_name | trim }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.49578,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.generate_schema_name_for_env\": {\n      \"name\": \"generate_schema_name_for_env\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/get_custom_name/get_custom_schema.sql\",\n      \"original_file_path\": \"macros/get_custom_name/get_custom_schema.sql\",\n      \"unique_id\": \"macro.dbt.generate_schema_name_for_env\",\n      \"macro_sql\": \"{% macro generate_schema_name_for_env(custom_schema_name, node) -%}\\n\\n    {%- set default_schema = target.schema -%}\\n    {%- if target.name == 'prod' and custom_schema_name is not none -%}\\n\\n        {{ custom_schema_name | trim }}\\n\\n    {%- else -%}\\n\\n        {{ default_schema }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495782,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.generate_database_name\": {\n      \"name\": \"generate_database_name\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/get_custom_name/get_custom_database.sql\",\n      \"original_file_path\": \"macros/get_custom_name/get_custom_database.sql\",\n      \"unique_id\": \"macro.dbt.generate_database_name\",\n      \"macro_sql\": \"{% macro generate_database_name(custom_database_name=none, node=none) -%}\\n    {% do return(adapter.dispatch('generate_database_name', 'dbt')(custom_database_name, node)) %}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__generate_database_name\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495787,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__generate_database_name\": {\n      \"name\": \"default__generate_database_name\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/get_custom_name/get_custom_database.sql\",\n      \"original_file_path\": \"macros/get_custom_name/get_custom_database.sql\",\n      \"unique_id\": \"macro.dbt.default__generate_database_name\",\n      \"macro_sql\": \"{% macro default__generate_database_name(custom_database_name=none, node=none) -%}\\n    {%- set default_database = target.database -%}\\n    {%- if custom_database_name is none -%}\\n\\n        {{ default_database }}\\n\\n    {%- else -%}\\n\\n        {{ custom_database_name }}\\n\\n    {%- endif -%}\\n\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495789,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_drop_sql\": {\n      \"name\": \"get_drop_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/drop.sql\",\n      \"original_file_path\": \"macros/relations/drop.sql\",\n      \"unique_id\": \"macro.dbt.get_drop_sql\",\n      \"macro_sql\": \"{%- macro get_drop_sql(relation) -%}\\n    {{- log('Applying DROP to: ' ~ relation) -}}\\n    {{- adapter.dispatch('get_drop_sql', 'dbt')(relation) -}}\\n{%- endmacro -%}\\n\\n\\n\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_drop_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4957938,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_drop_sql\": {\n      \"name\": \"default__get_drop_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/drop.sql\",\n      \"original_file_path\": \"macros/relations/drop.sql\",\n      \"unique_id\": \"macro.dbt.default__get_drop_sql\",\n      \"macro_sql\": \"{%- macro default__get_drop_sql(relation) -%}\\n\\n    {%- if relation.is_view -%}\\n        {{ drop_view(relation) }}\\n\\n    {%- elif relation.is_table -%}\\n        {{ drop_table(relation) }}\\n\\n    {%- elif relation.is_materialized_view -%}\\n        {{ drop_materialized_view(relation) }}\\n\\n    {%- else -%}\\n        drop {{ relation.type }} if exists {{ relation.render() }} cascade\\n\\n    {%- endif -%}\\n\\n{%- endmacro -%}\\n\\n\\n\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.drop_view\",\n          \"macro.dbt.drop_table\",\n          \"macro.dbt.drop_materialized_view\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495797,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.drop_relation\": {\n      \"name\": \"drop_relation\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/drop.sql\",\n      \"original_file_path\": \"macros/relations/drop.sql\",\n      \"unique_id\": \"macro.dbt.drop_relation\",\n      \"macro_sql\": \"{% macro drop_relation(relation) -%}\\n    {{ return(adapter.dispatch('drop_relation', 'dbt')(relation)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__drop_relation\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495799,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__drop_relation\": {\n      \"name\": \"default__drop_relation\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/drop.sql\",\n      \"original_file_path\": \"macros/relations/drop.sql\",\n      \"unique_id\": \"macro.dbt.default__drop_relation\",\n      \"macro_sql\": \"{% macro default__drop_relation(relation) -%}\\n    {% call statement('drop_relation', auto_begin=False) -%}\\n        {{ get_drop_sql(relation) }}\\n    {%- endcall %}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.statement\",\n          \"macro.dbt.get_drop_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495801,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.drop_relation_if_exists\": {\n      \"name\": \"drop_relation_if_exists\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/drop.sql\",\n      \"original_file_path\": \"macros/relations/drop.sql\",\n      \"unique_id\": \"macro.dbt.drop_relation_if_exists\",\n      \"macro_sql\": \"{% macro drop_relation_if_exists(relation) %}\\n  {% if relation is not none %}\\n    {{ adapter.drop_relation(relation) }}\\n  {% endif %}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4958038,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_replace_sql\": {\n      \"name\": \"get_replace_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/replace.sql\",\n      \"original_file_path\": \"macros/relations/replace.sql\",\n      \"unique_id\": \"macro.dbt.get_replace_sql\",\n      \"macro_sql\": \"{% macro get_replace_sql(existing_relation, target_relation, sql) %}\\n    {{- log('Applying REPLACE to: ' ~ existing_relation) -}}\\n    {{- adapter.dispatch('get_replace_sql', 'dbt')(existing_relation, target_relation, sql) -}}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_replace_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495811,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_replace_sql\": {\n      \"name\": \"default__get_replace_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/replace.sql\",\n      \"original_file_path\": \"macros/relations/replace.sql\",\n      \"unique_id\": \"macro.dbt.default__get_replace_sql\",\n      \"macro_sql\": \"{% macro default__get_replace_sql(existing_relation, target_relation, sql) %}\\n\\n    {# /* use a create or replace statement if possible */ #}\\n\\n    {% set is_replaceable = existing_relation.type == target_relation.type and existing_relation.can_be_replaced %}\\n\\n    {% if is_replaceable and existing_relation.is_view %}\\n        {{ get_replace_view_sql(target_relation, sql) }}\\n\\n    {% elif is_replaceable and existing_relation.is_table %}\\n        {{ get_replace_table_sql(target_relation, sql) }}\\n\\n    {% elif is_replaceable and existing_relation.is_materialized_view %}\\n        {{ get_replace_materialized_view_sql(target_relation, sql) }}\\n\\n    {# /* a create or replace statement is not possible, so try to stage and/or backup to be safe */ #}\\n\\n    {# /* create target_relation as an intermediate relation, then swap it out with the existing one using a backup */ #}\\n    {%- elif target_relation.can_be_renamed and existing_relation.can_be_renamed -%}\\n        {{ get_create_intermediate_sql(target_relation, sql) }};\\n        {{ get_create_backup_sql(existing_relation) }};\\n        {{ get_rename_intermediate_sql(target_relation) }};\\n        {{ get_drop_backup_sql(existing_relation) }}\\n\\n    {# /* create target_relation as an intermediate relation, then swap it out with the existing one without using a backup */ #}\\n    {%- elif target_relation.can_be_renamed -%}\\n        {{ get_create_intermediate_sql(target_relation, sql) }};\\n        {{ get_drop_sql(existing_relation) }};\\n        {{ get_rename_intermediate_sql(target_relation) }}\\n\\n    {# /* create target_relation in place by first backing up the existing relation */ #}\\n    {%- elif existing_relation.can_be_renamed -%}\\n        {{ get_create_backup_sql(existing_relation) }};\\n        {{ get_create_sql(target_relation, sql) }};\\n        {{ get_drop_backup_sql(existing_relation) }}\\n\\n    {# /* no renaming is allowed, so just drop and create */ #}\\n    {%- else -%}\\n        {{ get_drop_sql(existing_relation) }};\\n        {{ get_create_sql(target_relation, sql) }}\\n\\n    {%- endif -%}\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.get_replace_view_sql\",\n          \"macro.dbt.get_replace_table_sql\",\n          \"macro.dbt.get_replace_materialized_view_sql\",\n          \"macro.dbt.get_create_intermediate_sql\",\n          \"macro.dbt.get_create_backup_sql\",\n          \"macro.dbt.get_rename_intermediate_sql\",\n          \"macro.dbt.get_drop_backup_sql\",\n          \"macro.dbt.get_drop_sql\",\n          \"macro.dbt.get_create_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4958138,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_create_intermediate_sql\": {\n      \"name\": \"get_create_intermediate_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/create_intermediate.sql\",\n      \"original_file_path\": \"macros/relations/create_intermediate.sql\",\n      \"unique_id\": \"macro.dbt.get_create_intermediate_sql\",\n      \"macro_sql\": \"{%- macro get_create_intermediate_sql(relation, sql) -%}\\n    {{- log('Applying CREATE INTERMEDIATE to: ' ~ relation) -}}\\n    {{- adapter.dispatch('get_create_intermediate_sql', 'dbt')(relation, sql) -}}\\n{%- endmacro -%}\\n\\n\\n\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_create_intermediate_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.49582,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_create_intermediate_sql\": {\n      \"name\": \"default__get_create_intermediate_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/create_intermediate.sql\",\n      \"original_file_path\": \"macros/relations/create_intermediate.sql\",\n      \"unique_id\": \"macro.dbt.default__get_create_intermediate_sql\",\n      \"macro_sql\": \"{%- macro default__get_create_intermediate_sql(relation, sql) -%}\\n\\n    -- get the standard intermediate name\\n    {% set intermediate_relation = make_intermediate_relation(relation) %}\\n\\n    -- drop any pre-existing intermediate\\n    {{ get_drop_sql(intermediate_relation) }};\\n\\n    {{ get_create_sql(intermediate_relation, sql) }}\\n\\n{%- endmacro -%}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.make_intermediate_relation\",\n          \"macro.dbt.get_drop_sql\",\n          \"macro.dbt.get_create_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4958231,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.drop_schema_named\": {\n      \"name\": \"drop_schema_named\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/schema.sql\",\n      \"original_file_path\": \"macros/relations/schema.sql\",\n      \"unique_id\": \"macro.dbt.drop_schema_named\",\n      \"macro_sql\": \"{% macro drop_schema_named(schema_name) %}\\n    {{ return(adapter.dispatch('drop_schema_named', 'dbt') (schema_name)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__drop_schema_named\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495828,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__drop_schema_named\": {\n      \"name\": \"default__drop_schema_named\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/schema.sql\",\n      \"original_file_path\": \"macros/relations/schema.sql\",\n      \"unique_id\": \"macro.dbt.default__drop_schema_named\",\n      \"macro_sql\": \"{% macro default__drop_schema_named(schema_name) %}\\n  {% set schema_relation = api.Relation.create(schema=schema_name) %}\\n  {{ adapter.drop_schema(schema_relation) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.49583,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_drop_backup_sql\": {\n      \"name\": \"get_drop_backup_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/drop_backup.sql\",\n      \"original_file_path\": \"macros/relations/drop_backup.sql\",\n      \"unique_id\": \"macro.dbt.get_drop_backup_sql\",\n      \"macro_sql\": \"{%- macro get_drop_backup_sql(relation) -%}\\n    {{- log('Applying DROP BACKUP to: ' ~ relation) -}}\\n    {{- adapter.dispatch('get_drop_backup_sql', 'dbt')(relation) -}}\\n{%- endmacro -%}\\n\\n\\n\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_drop_backup_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495837,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_drop_backup_sql\": {\n      \"name\": \"default__get_drop_backup_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/drop_backup.sql\",\n      \"original_file_path\": \"macros/relations/drop_backup.sql\",\n      \"unique_id\": \"macro.dbt.default__get_drop_backup_sql\",\n      \"macro_sql\": \"{%- macro default__get_drop_backup_sql(relation) -%}\\n\\n    -- get the standard backup name\\n    {% set backup_relation = make_backup_relation(relation, relation.type) %}\\n\\n    {{ get_drop_sql(backup_relation) }}\\n\\n{%- endmacro -%}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.make_backup_relation\",\n          \"macro.dbt.get_drop_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4958389,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_rename_sql\": {\n      \"name\": \"get_rename_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/rename.sql\",\n      \"original_file_path\": \"macros/relations/rename.sql\",\n      \"unique_id\": \"macro.dbt.get_rename_sql\",\n      \"macro_sql\": \"{%- macro get_rename_sql(relation, new_name) -%}\\n    {{- log('Applying RENAME to: ' ~ relation) -}}\\n    {{- adapter.dispatch('get_rename_sql', 'dbt')(relation, new_name) -}}\\n{%- endmacro -%}\\n\\n\\n\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_rename_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4958441,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_rename_sql\": {\n      \"name\": \"default__get_rename_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/rename.sql\",\n      \"original_file_path\": \"macros/relations/rename.sql\",\n      \"unique_id\": \"macro.dbt.default__get_rename_sql\",\n      \"macro_sql\": \"{%- macro default__get_rename_sql(relation, new_name) -%}\\n\\n    {%- if relation.is_view -%}\\n        {{ get_rename_view_sql(relation, new_name) }}\\n\\n    {%- elif relation.is_table -%}\\n        {{ get_rename_table_sql(relation, new_name) }}\\n\\n    {%- elif relation.is_materialized_view -%}\\n        {{ get_rename_materialized_view_sql(relation, new_name) }}\\n\\n    {%- else -%}\\n        {{- exceptions.raise_compiler_error(\\\"`get_rename_sql` has not been implemented for: \\\" ~ relation.type ) -}}\\n\\n    {%- endif -%}\\n\\n{%- endmacro -%}\\n\\n\\n\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.get_rename_view_sql\",\n          \"macro.dbt.get_rename_table_sql\",\n          \"macro.dbt.get_rename_materialized_view_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495848,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.rename_relation\": {\n      \"name\": \"rename_relation\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/rename.sql\",\n      \"original_file_path\": \"macros/relations/rename.sql\",\n      \"unique_id\": \"macro.dbt.rename_relation\",\n      \"macro_sql\": \"{% macro rename_relation(from_relation, to_relation) -%}\\n  {{ return(adapter.dispatch('rename_relation', 'dbt')(from_relation, to_relation)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__rename_relation\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495851,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__rename_relation\": {\n      \"name\": \"default__rename_relation\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/rename.sql\",\n      \"original_file_path\": \"macros/relations/rename.sql\",\n      \"unique_id\": \"macro.dbt.default__rename_relation\",\n      \"macro_sql\": \"{% macro default__rename_relation(from_relation, to_relation) -%}\\n  {% set target_name = adapter.quote_as_configured(to_relation.identifier, 'identifier') %}\\n  {% call statement('rename_relation') -%}\\n    alter table {{ from_relation.render() }} rename to {{ target_name }}\\n  {%- endcall %}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.statement\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495853,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_create_backup_sql\": {\n      \"name\": \"get_create_backup_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/create_backup.sql\",\n      \"original_file_path\": \"macros/relations/create_backup.sql\",\n      \"unique_id\": \"macro.dbt.get_create_backup_sql\",\n      \"macro_sql\": \"{%- macro get_create_backup_sql(relation) -%}\\n    {{- log('Applying CREATE BACKUP to: ' ~ relation) -}}\\n    {{- adapter.dispatch('get_create_backup_sql', 'dbt')(relation) -}}\\n{%- endmacro -%}\\n\\n\\n\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_create_backup_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495857,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_create_backup_sql\": {\n      \"name\": \"default__get_create_backup_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/create_backup.sql\",\n      \"original_file_path\": \"macros/relations/create_backup.sql\",\n      \"unique_id\": \"macro.dbt.default__get_create_backup_sql\",\n      \"macro_sql\": \"{%- macro default__get_create_backup_sql(relation) -%}\\n\\n    -- get the standard backup name\\n    {% set backup_relation = make_backup_relation(relation, relation.type) %}\\n\\n    -- drop any pre-existing backup\\n    {{ get_drop_sql(backup_relation) }};\\n\\n    {{ get_rename_sql(relation, backup_relation.identifier) }}\\n\\n{%- endmacro -%}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.make_backup_relation\",\n          \"macro.dbt.get_drop_sql\",\n          \"macro.dbt.get_rename_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495859,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_create_sql\": {\n      \"name\": \"get_create_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/create.sql\",\n      \"original_file_path\": \"macros/relations/create.sql\",\n      \"unique_id\": \"macro.dbt.get_create_sql\",\n      \"macro_sql\": \"{%- macro get_create_sql(relation, sql) -%}\\n    {{- log('Applying CREATE to: ' ~ relation) -}}\\n    {{- adapter.dispatch('get_create_sql', 'dbt')(relation, sql) -}}\\n{%- endmacro -%}\\n\\n\\n\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_create_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4958699,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_create_sql\": {\n      \"name\": \"default__get_create_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/create.sql\",\n      \"original_file_path\": \"macros/relations/create.sql\",\n      \"unique_id\": \"macro.dbt.default__get_create_sql\",\n      \"macro_sql\": \"{%- macro default__get_create_sql(relation, sql) -%}\\n\\n    {%- if relation.is_view -%}\\n        {{ get_create_view_as_sql(relation, sql) }}\\n\\n    {%- elif relation.is_table -%}\\n        {{ get_create_table_as_sql(False, relation, sql) }}\\n\\n    {%- elif relation.is_materialized_view -%}\\n        {{ get_create_materialized_view_as_sql(relation, sql) }}\\n\\n    {%- else -%}\\n        {{- exceptions.raise_compiler_error(\\\"`get_create_sql` has not been implemented for: \\\" ~ relation.type ) -}}\\n\\n    {%- endif -%}\\n\\n{%- endmacro -%}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.get_create_view_as_sql\",\n          \"macro.dbt.get_create_table_as_sql\",\n          \"macro.dbt.get_create_materialized_view_as_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495872,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_rename_intermediate_sql\": {\n      \"name\": \"get_rename_intermediate_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/rename_intermediate.sql\",\n      \"original_file_path\": \"macros/relations/rename_intermediate.sql\",\n      \"unique_id\": \"macro.dbt.get_rename_intermediate_sql\",\n      \"macro_sql\": \"{%- macro get_rename_intermediate_sql(relation) -%}\\n    {{- log('Applying RENAME INTERMEDIATE to: ' ~ relation) -}}\\n    {{- adapter.dispatch('get_rename_intermediate_sql', 'dbt')(relation) -}}\\n{%- endmacro -%}\\n\\n\\n\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_rename_intermediate_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495897,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_rename_intermediate_sql\": {\n      \"name\": \"default__get_rename_intermediate_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/rename_intermediate.sql\",\n      \"original_file_path\": \"macros/relations/rename_intermediate.sql\",\n      \"unique_id\": \"macro.dbt.default__get_rename_intermediate_sql\",\n      \"macro_sql\": \"{%- macro default__get_rename_intermediate_sql(relation) -%}\\n\\n    -- get the standard intermediate name\\n    {% set intermediate_relation = make_intermediate_relation(relation) %}\\n\\n    {{ get_rename_sql(intermediate_relation, relation.identifier) }}\\n\\n{%- endmacro -%}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.make_intermediate_relation\",\n          \"macro.dbt.get_rename_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4959,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.drop_materialized_view\": {\n      \"name\": \"drop_materialized_view\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/materialized_view/drop.sql\",\n      \"original_file_path\": \"macros/relations/materialized_view/drop.sql\",\n      \"unique_id\": \"macro.dbt.drop_materialized_view\",\n      \"macro_sql\": \"{% macro drop_materialized_view(relation) -%}\\n    {{- adapter.dispatch('drop_materialized_view', 'dbt')(relation) -}}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__drop_materialized_view\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495905,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__drop_materialized_view\": {\n      \"name\": \"default__drop_materialized_view\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/materialized_view/drop.sql\",\n      \"original_file_path\": \"macros/relations/materialized_view/drop.sql\",\n      \"unique_id\": \"macro.dbt.default__drop_materialized_view\",\n      \"macro_sql\": \"{% macro default__drop_materialized_view(relation) -%}\\n    drop materialized view if exists {{ relation.render() }} cascade\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495907,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_replace_materialized_view_sql\": {\n      \"name\": \"get_replace_materialized_view_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/materialized_view/replace.sql\",\n      \"original_file_path\": \"macros/relations/materialized_view/replace.sql\",\n      \"unique_id\": \"macro.dbt.get_replace_materialized_view_sql\",\n      \"macro_sql\": \"{% macro get_replace_materialized_view_sql(relation, sql) %}\\n    {{- adapter.dispatch('get_replace_materialized_view_sql', 'dbt')(relation, sql) -}}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_replace_materialized_view_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4959118,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_replace_materialized_view_sql\": {\n      \"name\": \"default__get_replace_materialized_view_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/materialized_view/replace.sql\",\n      \"original_file_path\": \"macros/relations/materialized_view/replace.sql\",\n      \"unique_id\": \"macro.dbt.default__get_replace_materialized_view_sql\",\n      \"macro_sql\": \"{% macro default__get_replace_materialized_view_sql(relation, sql) %}\\n    {{ exceptions.raise_compiler_error(\\n        \\\"`get_replace_materialized_view_sql` has not been implemented for this adapter.\\\"\\n    ) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495914,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.refresh_materialized_view\": {\n      \"name\": \"refresh_materialized_view\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/materialized_view/refresh.sql\",\n      \"original_file_path\": \"macros/relations/materialized_view/refresh.sql\",\n      \"unique_id\": \"macro.dbt.refresh_materialized_view\",\n      \"macro_sql\": \"{% macro refresh_materialized_view(relation) %}\\n    {{- log('Applying REFRESH to: ' ~ relation) -}}\\n    {{- adapter.dispatch('refresh_materialized_view', 'dbt')(relation) -}}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__refresh_materialized_view\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495919,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__refresh_materialized_view\": {\n      \"name\": \"default__refresh_materialized_view\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/materialized_view/refresh.sql\",\n      \"original_file_path\": \"macros/relations/materialized_view/refresh.sql\",\n      \"unique_id\": \"macro.dbt.default__refresh_materialized_view\",\n      \"macro_sql\": \"{% macro default__refresh_materialized_view(relation) %}\\n    {{ exceptions.raise_compiler_error(\\\"`refresh_materialized_view` has not been implemented for this adapter.\\\") }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495921,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_rename_materialized_view_sql\": {\n      \"name\": \"get_rename_materialized_view_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/materialized_view/rename.sql\",\n      \"original_file_path\": \"macros/relations/materialized_view/rename.sql\",\n      \"unique_id\": \"macro.dbt.get_rename_materialized_view_sql\",\n      \"macro_sql\": \"{% macro get_rename_materialized_view_sql(relation, new_name) %}\\n    {{- adapter.dispatch('get_rename_materialized_view_sql', 'dbt')(relation, new_name) -}}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__get_rename_materialized_view_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495926,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_rename_materialized_view_sql\": {\n      \"name\": \"default__get_rename_materialized_view_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/materialized_view/rename.sql\",\n      \"original_file_path\": \"macros/relations/materialized_view/rename.sql\",\n      \"unique_id\": \"macro.dbt.default__get_rename_materialized_view_sql\",\n      \"macro_sql\": \"{% macro default__get_rename_materialized_view_sql(relation, new_name) %}\\n    {{ exceptions.raise_compiler_error(\\n        \\\"`get_rename_materialized_view_sql` has not been implemented for this adapter.\\\"\\n    ) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495928,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_alter_materialized_view_as_sql\": {\n      \"name\": \"get_alter_materialized_view_as_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/materialized_view/alter.sql\",\n      \"original_file_path\": \"macros/relations/materialized_view/alter.sql\",\n      \"unique_id\": \"macro.dbt.get_alter_materialized_view_as_sql\",\n      \"macro_sql\": \"{% macro get_alter_materialized_view_as_sql(\\n    relation,\\n    configuration_changes,\\n    sql,\\n    existing_relation,\\n    backup_relation,\\n    intermediate_relation\\n) %}\\n    {{- log('Applying ALTER to: ' ~ relation) -}}\\n    {{- adapter.dispatch('get_alter_materialized_view_as_sql', 'dbt')(\\n        relation,\\n        configuration_changes,\\n        sql,\\n        existing_relation,\\n        backup_relation,\\n        intermediate_relation\\n    ) -}}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__get_alter_materialized_view_as_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495934,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_alter_materialized_view_as_sql\": {\n      \"name\": \"default__get_alter_materialized_view_as_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/materialized_view/alter.sql\",\n      \"original_file_path\": \"macros/relations/materialized_view/alter.sql\",\n      \"unique_id\": \"macro.dbt.default__get_alter_materialized_view_as_sql\",\n      \"macro_sql\": \"{% macro default__get_alter_materialized_view_as_sql(\\n    relation,\\n    configuration_changes,\\n    sql,\\n    existing_relation,\\n    backup_relation,\\n    intermediate_relation\\n) %}\\n    {{ exceptions.raise_compiler_error(\\\"Materialized views have not been implemented for this adapter.\\\") }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495937,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_materialized_view_configuration_changes\": {\n      \"name\": \"get_materialized_view_configuration_changes\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/materialized_view/alter.sql\",\n      \"original_file_path\": \"macros/relations/materialized_view/alter.sql\",\n      \"unique_id\": \"macro.dbt.get_materialized_view_configuration_changes\",\n      \"macro_sql\": \"{% macro get_materialized_view_configuration_changes(existing_relation, new_config) %}\\n    /* {#\\n    It's recommended that configuration changes be formatted as follows:\\n    {\\\"<change_category>\\\": [{\\\"action\\\": \\\"<name>\\\", \\\"context\\\": ...}]}\\n\\n    For example:\\n    {\\n        \\\"indexes\\\": [\\n            {\\\"action\\\": \\\"drop\\\", \\\"context\\\": \\\"index_abc\\\"},\\n            {\\\"action\\\": \\\"create\\\", \\\"context\\\": {\\\"columns\\\": [\\\"column_1\\\", \\\"column_2\\\"], \\\"type\\\": \\\"hash\\\", \\\"unique\\\": True}},\\n        ],\\n    }\\n\\n    Either way, `get_materialized_view_configuration_changes` needs to align with `get_alter_materialized_view_as_sql`.\\n    #} */\\n    {{- log('Determining configuration changes on: ' ~ existing_relation) -}}\\n    {%- do return(adapter.dispatch('get_materialized_view_configuration_changes', 'dbt')(existing_relation, new_config)) -%}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__get_materialized_view_configuration_changes\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4959412,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_materialized_view_configuration_changes\": {\n      \"name\": \"default__get_materialized_view_configuration_changes\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/materialized_view/alter.sql\",\n      \"original_file_path\": \"macros/relations/materialized_view/alter.sql\",\n      \"unique_id\": \"macro.dbt.default__get_materialized_view_configuration_changes\",\n      \"macro_sql\": \"{% macro default__get_materialized_view_configuration_changes(existing_relation, new_config) %}\\n    {{ exceptions.raise_compiler_error(\\\"Materialized views have not been implemented for this adapter.\\\") }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4959428,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_create_materialized_view_as_sql\": {\n      \"name\": \"get_create_materialized_view_as_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/materialized_view/create.sql\",\n      \"original_file_path\": \"macros/relations/materialized_view/create.sql\",\n      \"unique_id\": \"macro.dbt.get_create_materialized_view_as_sql\",\n      \"macro_sql\": \"{% macro get_create_materialized_view_as_sql(relation, sql) -%}\\n    {{- adapter.dispatch('get_create_materialized_view_as_sql', 'dbt')(relation, sql) -}}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__get_create_materialized_view_as_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4959471,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_create_materialized_view_as_sql\": {\n      \"name\": \"default__get_create_materialized_view_as_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/materialized_view/create.sql\",\n      \"original_file_path\": \"macros/relations/materialized_view/create.sql\",\n      \"unique_id\": \"macro.dbt.default__get_create_materialized_view_as_sql\",\n      \"macro_sql\": \"{% macro default__get_create_materialized_view_as_sql(relation, sql) -%}\\n    {{ exceptions.raise_compiler_error(\\n        \\\"`get_create_materialized_view_as_sql` has not been implemented for this adapter.\\\"\\n    ) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.49595,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_table_columns_and_constraints\": {\n      \"name\": \"get_table_columns_and_constraints\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/column/columns_spec_ddl.sql\",\n      \"original_file_path\": \"macros/relations/column/columns_spec_ddl.sql\",\n      \"unique_id\": \"macro.dbt.get_table_columns_and_constraints\",\n      \"macro_sql\": \"{%- macro get_table_columns_and_constraints() -%}\\n  {{ adapter.dispatch('get_table_columns_and_constraints', 'dbt')() }}\\n{%- endmacro -%}\\n\\n\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_table_columns_and_constraints\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495956,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_table_columns_and_constraints\": {\n      \"name\": \"default__get_table_columns_and_constraints\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/column/columns_spec_ddl.sql\",\n      \"original_file_path\": \"macros/relations/column/columns_spec_ddl.sql\",\n      \"unique_id\": \"macro.dbt.default__get_table_columns_and_constraints\",\n      \"macro_sql\": \"{% macro default__get_table_columns_and_constraints() -%}\\n  {{ return(table_columns_and_constraints()) }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.table_columns_and_constraints\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495958,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.table_columns_and_constraints\": {\n      \"name\": \"table_columns_and_constraints\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/column/columns_spec_ddl.sql\",\n      \"original_file_path\": \"macros/relations/column/columns_spec_ddl.sql\",\n      \"unique_id\": \"macro.dbt.table_columns_and_constraints\",\n      \"macro_sql\": \"{% macro table_columns_and_constraints() %}\\n  {# loop through user_provided_columns to create DDL with data types and constraints #}\\n    {%- set raw_column_constraints = adapter.render_raw_columns_constraints(raw_columns=model['columns']) -%}\\n    {%- set raw_model_constraints = adapter.render_raw_model_constraints(raw_constraints=model['constraints']) -%}\\n    (\\n    {% for c in raw_column_constraints -%}\\n      {{ c }}{{ \\\",\\\" if not loop.last or raw_model_constraints }}\\n    {% endfor %}\\n    {% for c in raw_model_constraints -%}\\n        {{ c }}{{ \\\",\\\" if not loop.last }}\\n    {% endfor -%}\\n    )\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.49596,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_assert_columns_equivalent\": {\n      \"name\": \"get_assert_columns_equivalent\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/column/columns_spec_ddl.sql\",\n      \"original_file_path\": \"macros/relations/column/columns_spec_ddl.sql\",\n      \"unique_id\": \"macro.dbt.get_assert_columns_equivalent\",\n      \"macro_sql\": \"\\n\\n{%- macro get_assert_columns_equivalent(sql) -%}\\n  {{ adapter.dispatch('get_assert_columns_equivalent', 'dbt')(sql) }}\\n{%- endmacro -%}\\n\\n\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_assert_columns_equivalent\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4959621,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_assert_columns_equivalent\": {\n      \"name\": \"default__get_assert_columns_equivalent\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/column/columns_spec_ddl.sql\",\n      \"original_file_path\": \"macros/relations/column/columns_spec_ddl.sql\",\n      \"unique_id\": \"macro.dbt.default__get_assert_columns_equivalent\",\n      \"macro_sql\": \"{% macro default__get_assert_columns_equivalent(sql) -%}\\n  {{ return(assert_columns_equivalent(sql)) }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.assert_columns_equivalent\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4959638,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.assert_columns_equivalent\": {\n      \"name\": \"assert_columns_equivalent\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/column/columns_spec_ddl.sql\",\n      \"original_file_path\": \"macros/relations/column/columns_spec_ddl.sql\",\n      \"unique_id\": \"macro.dbt.assert_columns_equivalent\",\n      \"macro_sql\": \"{% macro assert_columns_equivalent(sql) %}\\n\\n  {#-- First ensure the user has defined 'columns' in yaml specification --#}\\n  {%- set user_defined_columns = model['columns'] -%}\\n  {%- if not user_defined_columns -%}\\n      {{ exceptions.raise_contract_error([], []) }}\\n  {%- endif -%}\\n\\n  {#-- Obtain the column schema provided by sql file. #}\\n  {%- set sql_file_provided_columns = get_column_schema_from_query(sql, config.get('sql_header', none)) -%}\\n  {#--Obtain the column schema provided by the schema file by generating an 'empty schema' query from the model's columns. #}\\n  {%- set schema_file_provided_columns = get_column_schema_from_query(get_empty_schema_sql(user_defined_columns)) -%}\\n\\n  {#-- create dictionaries with name and formatted data type and strings for exception #}\\n  {%- set sql_columns = format_columns(sql_file_provided_columns) -%}\\n  {%- set yaml_columns = format_columns(schema_file_provided_columns)  -%}\\n\\n  {%- if sql_columns|length != yaml_columns|length -%}\\n    {%- do exceptions.raise_contract_error(yaml_columns, sql_columns) -%}\\n  {%- endif -%}\\n\\n  {%- for sql_col in sql_columns -%}\\n    {%- set yaml_col = [] -%}\\n    {%- for this_col in yaml_columns -%}\\n      {%- if this_col['name'] == sql_col['name'] -%}\\n        {%- do yaml_col.append(this_col) -%}\\n        {%- break -%}\\n      {%- endif -%}\\n    {%- endfor -%}\\n    {%- if not yaml_col -%}\\n      {#-- Column with name not found in yaml #}\\n      {%- do exceptions.raise_contract_error(yaml_columns, sql_columns) -%}\\n    {%- endif -%}\\n    {%- if sql_col['formatted'] != yaml_col[0]['formatted'] -%}\\n      {#-- Column data types don't match #}\\n      {%- do exceptions.raise_contract_error(yaml_columns, sql_columns) -%}\\n    {%- endif -%}\\n  {%- endfor -%}\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.get_column_schema_from_query\",\n          \"macro.dbt.get_empty_schema_sql\",\n          \"macro.dbt.format_columns\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495967,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.format_columns\": {\n      \"name\": \"format_columns\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/column/columns_spec_ddl.sql\",\n      \"original_file_path\": \"macros/relations/column/columns_spec_ddl.sql\",\n      \"unique_id\": \"macro.dbt.format_columns\",\n      \"macro_sql\": \"{% macro format_columns(columns) %}\\n  {% set formatted_columns = [] %}\\n  {% for column in columns %}\\n    {%- set formatted_column = adapter.dispatch('format_column', 'dbt')(column) -%}\\n    {%- do formatted_columns.append(formatted_column) -%}\\n  {% endfor %}\\n  {{ return(formatted_columns) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__format_column\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495973,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__format_column\": {\n      \"name\": \"default__format_column\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/column/columns_spec_ddl.sql\",\n      \"original_file_path\": \"macros/relations/column/columns_spec_ddl.sql\",\n      \"unique_id\": \"macro.dbt.default__format_column\",\n      \"macro_sql\": \"{% macro default__format_column(column) -%}\\n  {% set data_type = column.dtype %}\\n  {% set formatted = column.column.lower() ~ \\\" \\\" ~ data_type %}\\n  {{ return({'name': column.name, 'data_type': data_type, 'formatted': formatted}) }}\\n{%- endmacro -%}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495976,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.drop_table\": {\n      \"name\": \"drop_table\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/table/drop.sql\",\n      \"original_file_path\": \"macros/relations/table/drop.sql\",\n      \"unique_id\": \"macro.dbt.drop_table\",\n      \"macro_sql\": \"{% macro drop_table(relation) -%}\\n    {{- adapter.dispatch('drop_table', 'dbt')(relation) -}}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__drop_table\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4959831,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__drop_table\": {\n      \"name\": \"default__drop_table\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/table/drop.sql\",\n      \"original_file_path\": \"macros/relations/table/drop.sql\",\n      \"unique_id\": \"macro.dbt.default__drop_table\",\n      \"macro_sql\": \"{% macro default__drop_table(relation) -%}\\n    drop table if exists {{ relation.render() }} cascade\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495986,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_replace_table_sql\": {\n      \"name\": \"get_replace_table_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/table/replace.sql\",\n      \"original_file_path\": \"macros/relations/table/replace.sql\",\n      \"unique_id\": \"macro.dbt.get_replace_table_sql\",\n      \"macro_sql\": \"{% macro get_replace_table_sql(relation, sql) %}\\n    {{- adapter.dispatch('get_replace_table_sql', 'dbt')(relation, sql) -}}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__get_replace_table_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.49599,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_replace_table_sql\": {\n      \"name\": \"default__get_replace_table_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/table/replace.sql\",\n      \"original_file_path\": \"macros/relations/table/replace.sql\",\n      \"unique_id\": \"macro.dbt.default__get_replace_table_sql\",\n      \"macro_sql\": \"{% macro default__get_replace_table_sql(relation, sql) %}\\n    {{ exceptions.raise_compiler_error(\\n        \\\"`get_replace_table_sql` has not been implemented for this adapter.\\\"\\n    ) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495992,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_rename_table_sql\": {\n      \"name\": \"get_rename_table_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/table/rename.sql\",\n      \"original_file_path\": \"macros/relations/table/rename.sql\",\n      \"unique_id\": \"macro.dbt.get_rename_table_sql\",\n      \"macro_sql\": \"{% macro get_rename_table_sql(relation, new_name) %}\\n    {{- adapter.dispatch('get_rename_table_sql', 'dbt')(relation, new_name) -}}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__get_rename_table_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.495998,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_rename_table_sql\": {\n      \"name\": \"default__get_rename_table_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/table/rename.sql\",\n      \"original_file_path\": \"macros/relations/table/rename.sql\",\n      \"unique_id\": \"macro.dbt.default__get_rename_table_sql\",\n      \"macro_sql\": \"{% macro default__get_rename_table_sql(relation, new_name) %}\\n    {{ exceptions.raise_compiler_error(\\n        \\\"`get_rename_table_sql` has not been implemented for this adapter.\\\"\\n    ) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_create_table_as_sql\": {\n      \"name\": \"get_create_table_as_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/table/create.sql\",\n      \"original_file_path\": \"macros/relations/table/create.sql\",\n      \"unique_id\": \"macro.dbt.get_create_table_as_sql\",\n      \"macro_sql\": \"{% macro get_create_table_as_sql(temporary, relation, sql) -%}\\n  {{ adapter.dispatch('get_create_table_as_sql', 'dbt')(temporary, relation, sql) }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_create_table_as_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4960058,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_create_table_as_sql\": {\n      \"name\": \"default__get_create_table_as_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/table/create.sql\",\n      \"original_file_path\": \"macros/relations/table/create.sql\",\n      \"unique_id\": \"macro.dbt.default__get_create_table_as_sql\",\n      \"macro_sql\": \"{% macro default__get_create_table_as_sql(temporary, relation, sql) -%}\\n  {{ return(create_table_as(temporary, relation, sql)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.create_table_as\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496008,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.create_table_as\": {\n      \"name\": \"create_table_as\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/table/create.sql\",\n      \"original_file_path\": \"macros/relations/table/create.sql\",\n      \"unique_id\": \"macro.dbt.create_table_as\",\n      \"macro_sql\": \"{% macro create_table_as(temporary, relation, compiled_code, language='sql') -%}\\n  {# backward compatibility for create_table_as that does not support language #}\\n  {% if language == \\\"sql\\\" %}\\n    {{ adapter.dispatch('create_table_as', 'dbt')(temporary, relation, compiled_code)}}\\n  {% else %}\\n    {{ adapter.dispatch('create_table_as', 'dbt')(temporary, relation, compiled_code, language) }}\\n  {% endif %}\\n\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__create_table_as\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.49601,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__create_table_as\": {\n      \"name\": \"default__create_table_as\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/table/create.sql\",\n      \"original_file_path\": \"macros/relations/table/create.sql\",\n      \"unique_id\": \"macro.dbt.default__create_table_as\",\n      \"macro_sql\": \"{% macro default__create_table_as(temporary, relation, sql) -%}\\n  {%- set sql_header = config.get('sql_header', none) -%}\\n\\n  {{ sql_header if sql_header is not none }}\\n\\n  create {% if temporary: -%}temporary{%- endif %} table\\n    {{ relation.include(database=(not temporary), schema=(not temporary)) }}\\n  {% set contract_config = config.get('contract') %}\\n  {% if contract_config.enforced and (not temporary) %}\\n    {{ get_assert_columns_equivalent(sql) }}\\n    {{ get_table_columns_and_constraints() }}\\n    {%- set sql = get_select_subquery(sql) %}\\n  {% endif %}\\n  as (\\n    {{ sql }}\\n  );\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.get_assert_columns_equivalent\",\n          \"macro.dbt.get_table_columns_and_constraints\",\n          \"macro.dbt.get_select_subquery\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496012,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_column_names\": {\n      \"name\": \"default__get_column_names\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/table/create.sql\",\n      \"original_file_path\": \"macros/relations/table/create.sql\",\n      \"unique_id\": \"macro.dbt.default__get_column_names\",\n      \"macro_sql\": \"{% macro default__get_column_names() %}\\n  {#- loop through user_provided_columns to get column names -#}\\n    {%- set user_provided_columns = model['columns'] -%}\\n    {%- for i in user_provided_columns %}\\n      {%- set col = user_provided_columns[i] -%}\\n      {%- set col_name = adapter.quote(col['name']) if col.get('quote') else col['name'] -%}\\n      {{ col_name }}{{ \\\", \\\" if not loop.last }}\\n    {%- endfor -%}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496014,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_select_subquery\": {\n      \"name\": \"get_select_subquery\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/table/create.sql\",\n      \"original_file_path\": \"macros/relations/table/create.sql\",\n      \"unique_id\": \"macro.dbt.get_select_subquery\",\n      \"macro_sql\": \"{% macro get_select_subquery(sql) %}\\n  {{ return(adapter.dispatch('get_select_subquery', 'dbt')(sql)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_select_subquery\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4960158,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_select_subquery\": {\n      \"name\": \"default__get_select_subquery\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/table/create.sql\",\n      \"original_file_path\": \"macros/relations/table/create.sql\",\n      \"unique_id\": \"macro.dbt.default__get_select_subquery\",\n      \"macro_sql\": \"{% macro default__get_select_subquery(sql) %}\\n    select {{ adapter.dispatch('get_column_names', 'dbt')() }}\\n    from (\\n        {{ sql }}\\n    ) as model_subq\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_column_names\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496019,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.drop_view\": {\n      \"name\": \"drop_view\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/view/drop.sql\",\n      \"original_file_path\": \"macros/relations/view/drop.sql\",\n      \"unique_id\": \"macro.dbt.drop_view\",\n      \"macro_sql\": \"{% macro drop_view(relation) -%}\\n    {{- adapter.dispatch('drop_view', 'dbt')(relation) -}}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__drop_view\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496028,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__drop_view\": {\n      \"name\": \"default__drop_view\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/view/drop.sql\",\n      \"original_file_path\": \"macros/relations/view/drop.sql\",\n      \"unique_id\": \"macro.dbt.default__drop_view\",\n      \"macro_sql\": \"{% macro default__drop_view(relation) -%}\\n    drop view if exists {{ relation.render() }} cascade\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496031,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_replace_view_sql\": {\n      \"name\": \"get_replace_view_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/view/replace.sql\",\n      \"original_file_path\": \"macros/relations/view/replace.sql\",\n      \"unique_id\": \"macro.dbt.get_replace_view_sql\",\n      \"macro_sql\": \"{% macro get_replace_view_sql(relation, sql) %}\\n    {{- adapter.dispatch('get_replace_view_sql', 'dbt')(relation, sql) -}}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__get_replace_view_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496036,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_replace_view_sql\": {\n      \"name\": \"default__get_replace_view_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/view/replace.sql\",\n      \"original_file_path\": \"macros/relations/view/replace.sql\",\n      \"unique_id\": \"macro.dbt.default__get_replace_view_sql\",\n      \"macro_sql\": \"{% macro default__get_replace_view_sql(relation, sql) %}\\n    {{ exceptions.raise_compiler_error(\\n        \\\"`get_replace_view_sql` has not been implemented for this adapter.\\\"\\n    ) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496038,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.create_or_replace_view\": {\n      \"name\": \"create_or_replace_view\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/view/replace.sql\",\n      \"original_file_path\": \"macros/relations/view/replace.sql\",\n      \"unique_id\": \"macro.dbt.create_or_replace_view\",\n      \"macro_sql\": \"{% macro create_or_replace_view() %}\\n  {%- set identifier = model['alias'] -%}\\n\\n  {%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%}\\n  {%- set exists_as_view = (old_relation is not none and old_relation.is_view) -%}\\n\\n  {%- set target_relation = api.Relation.create(\\n      identifier=identifier, schema=schema, database=database,\\n      type='view') -%}\\n  {% set grant_config = config.get('grants') %}\\n\\n  {{ run_hooks(pre_hooks) }}\\n\\n  -- If there's a table with the same name and we weren't told to full refresh,\\n  -- that's an error. If we were told to full refresh, drop it. This behavior differs\\n  -- for Snowflake and BigQuery, so multiple dispatch is used.\\n  {%- if old_relation is not none and old_relation.is_table -%}\\n    {{ handle_existing_table(should_full_refresh(), old_relation) }}\\n  {%- endif -%}\\n\\n  -- build model\\n  {% call statement('main') -%}\\n    {{ get_create_view_as_sql(target_relation, sql) }}\\n  {%- endcall %}\\n\\n  {% set should_revoke = should_revoke(exists_as_view, full_refresh_mode=True) %}\\n  {% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}\\n\\n  {{ run_hooks(post_hooks) }}\\n\\n  {{ return({'relations': [target_relation]}) }}\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.run_hooks\",\n          \"macro.dbt.handle_existing_table\",\n          \"macro.dbt.should_full_refresh\",\n          \"macro.dbt.statement\",\n          \"macro.dbt.get_create_view_as_sql\",\n          \"macro.dbt.should_revoke\",\n          \"macro.dbt.apply_grants\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496041,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.handle_existing_table\": {\n      \"name\": \"handle_existing_table\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/view/replace.sql\",\n      \"original_file_path\": \"macros/relations/view/replace.sql\",\n      \"unique_id\": \"macro.dbt.handle_existing_table\",\n      \"macro_sql\": \"{% macro handle_existing_table(full_refresh, old_relation) %}\\n    {{ adapter.dispatch('handle_existing_table', 'dbt')(full_refresh, old_relation) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__handle_existing_table\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496043,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__handle_existing_table\": {\n      \"name\": \"default__handle_existing_table\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/view/replace.sql\",\n      \"original_file_path\": \"macros/relations/view/replace.sql\",\n      \"unique_id\": \"macro.dbt.default__handle_existing_table\",\n      \"macro_sql\": \"{% macro default__handle_existing_table(full_refresh, old_relation) %}\\n    {{ log(\\\"Dropping relation \\\" ~ old_relation.render() ~ \\\" because it is of type \\\" ~ old_relation.type) }}\\n    {{ adapter.drop_relation(old_relation) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496045,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_rename_view_sql\": {\n      \"name\": \"get_rename_view_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/view/rename.sql\",\n      \"original_file_path\": \"macros/relations/view/rename.sql\",\n      \"unique_id\": \"macro.dbt.get_rename_view_sql\",\n      \"macro_sql\": \"{% macro get_rename_view_sql(relation, new_name) %}\\n    {{- adapter.dispatch('get_rename_view_sql', 'dbt')(relation, new_name) -}}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__get_rename_view_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4960551,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_rename_view_sql\": {\n      \"name\": \"default__get_rename_view_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/view/rename.sql\",\n      \"original_file_path\": \"macros/relations/view/rename.sql\",\n      \"unique_id\": \"macro.dbt.default__get_rename_view_sql\",\n      \"macro_sql\": \"{% macro default__get_rename_view_sql(relation, new_name) %}\\n    {{ exceptions.raise_compiler_error(\\n        \\\"`get_rename_view_sql` has not been implemented for this adapter.\\\"\\n    ) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4960582,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_create_view_as_sql\": {\n      \"name\": \"get_create_view_as_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/view/create.sql\",\n      \"original_file_path\": \"macros/relations/view/create.sql\",\n      \"unique_id\": \"macro.dbt.get_create_view_as_sql\",\n      \"macro_sql\": \"{% macro get_create_view_as_sql(relation, sql) -%}\\n  {{ adapter.dispatch('get_create_view_as_sql', 'dbt')(relation, sql) }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_create_view_as_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496064,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_create_view_as_sql\": {\n      \"name\": \"default__get_create_view_as_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/view/create.sql\",\n      \"original_file_path\": \"macros/relations/view/create.sql\",\n      \"unique_id\": \"macro.dbt.default__get_create_view_as_sql\",\n      \"macro_sql\": \"{% macro default__get_create_view_as_sql(relation, sql) -%}\\n  {{ return(create_view_as(relation, sql)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.create_view_as\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496066,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.create_view_as\": {\n      \"name\": \"create_view_as\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/view/create.sql\",\n      \"original_file_path\": \"macros/relations/view/create.sql\",\n      \"unique_id\": \"macro.dbt.create_view_as\",\n      \"macro_sql\": \"{% macro create_view_as(relation, sql) -%}\\n  {{ adapter.dispatch('create_view_as', 'dbt')(relation, sql) }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__create_view_as\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496068,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__create_view_as\": {\n      \"name\": \"default__create_view_as\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/relations/view/create.sql\",\n      \"original_file_path\": \"macros/relations/view/create.sql\",\n      \"unique_id\": \"macro.dbt.default__create_view_as\",\n      \"macro_sql\": \"{% macro default__create_view_as(relation, sql) -%}\\n  {%- set sql_header = config.get('sql_header', none) -%}\\n\\n  {{ sql_header if sql_header is not none }}\\n  create view {{ relation.render() }}\\n    {% set contract_config = config.get('contract') %}\\n    {% if contract_config.enforced %}\\n      {{ get_assert_columns_equivalent(sql) }}\\n    {%- endif %}\\n  as (\\n    {{ sql }}\\n  );\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.get_assert_columns_equivalent\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4960709,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__test_relationships\": {\n      \"name\": \"default__test_relationships\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/generic_test_sql/relationships.sql\",\n      \"original_file_path\": \"macros/generic_test_sql/relationships.sql\",\n      \"unique_id\": \"macro.dbt.default__test_relationships\",\n      \"macro_sql\": \"{% macro default__test_relationships(model, column_name, to, field) %}\\n\\nwith child as (\\n    select {{ column_name }} as from_field\\n    from {{ model }}\\n    where {{ column_name }} is not null\\n),\\n\\nparent as (\\n    select {{ field }} as to_field\\n    from {{ to }}\\n)\\n\\nselect\\n    from_field\\n\\nfrom child\\nleft join parent\\n    on child.from_field = parent.to_field\\n\\nwhere parent.to_field is null\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496075,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__test_not_null\": {\n      \"name\": \"default__test_not_null\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/generic_test_sql/not_null.sql\",\n      \"original_file_path\": \"macros/generic_test_sql/not_null.sql\",\n      \"unique_id\": \"macro.dbt.default__test_not_null\",\n      \"macro_sql\": \"{% macro default__test_not_null(model, column_name) %}\\n\\n{% set column_list = '*' if should_store_failures() else column_name %}\\n\\nselect {{ column_list }}\\nfrom {{ model }}\\nwhere {{ column_name }} is null\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.should_store_failures\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4960809,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__test_unique\": {\n      \"name\": \"default__test_unique\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/generic_test_sql/unique.sql\",\n      \"original_file_path\": \"macros/generic_test_sql/unique.sql\",\n      \"unique_id\": \"macro.dbt.default__test_unique\",\n      \"macro_sql\": \"{% macro default__test_unique(model, column_name) %}\\n\\nselect\\n    {{ column_name }} as unique_field,\\n    count(*) as n_records\\n\\nfrom {{ model }}\\nwhere {{ column_name }} is not null\\ngroup by {{ column_name }}\\nhaving count(*) > 1\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4960861,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__test_accepted_values\": {\n      \"name\": \"default__test_accepted_values\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/generic_test_sql/accepted_values.sql\",\n      \"original_file_path\": \"macros/generic_test_sql/accepted_values.sql\",\n      \"unique_id\": \"macro.dbt.default__test_accepted_values\",\n      \"macro_sql\": \"{% macro default__test_accepted_values(model, column_name, values, quote=True) %}\\n\\nwith all_values as (\\n\\n    select\\n        {{ column_name }} as value_field,\\n        count(*) as n_records\\n\\n    from {{ model }}\\n    group by {{ column_name }}\\n\\n)\\n\\nselect *\\nfrom all_values\\nwhere value_field not in (\\n    {% for value in values -%}\\n        {% if quote -%}\\n        '{{ value }}'\\n        {%- else -%}\\n        {{ value }}\\n        {%- endif -%}\\n        {%- if not loop.last -%},{%- endif %}\\n    {%- endfor %}\\n)\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496091,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.statement\": {\n      \"name\": \"statement\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/etc/statement.sql\",\n      \"original_file_path\": \"macros/etc/statement.sql\",\n      \"unique_id\": \"macro.dbt.statement\",\n      \"macro_sql\": \"\\n{%- macro statement(name=None, fetch_result=False, auto_begin=True, language='sql') -%}\\n  {%- if execute: -%}\\n    {%- set compiled_code = caller() -%}\\n\\n    {%- if name == 'main' -%}\\n      {{ log('Writing runtime {} for node \\\"{}\\\"'.format(language, model['unique_id'])) }}\\n      {{ write(compiled_code) }}\\n    {%- endif -%}\\n    {%- if language == 'sql'-%}\\n      {%- set res, table = adapter.execute(compiled_code, auto_begin=auto_begin, fetch=fetch_result) -%}\\n    {%- elif language == 'python' -%}\\n      {%- set res = submit_python_job(model, compiled_code) -%}\\n      {#-- TODO: What should table be for python models? --#}\\n      {%- set table = None -%}\\n    {%- else -%}\\n      {% do exceptions.raise_compiler_error(\\\"statement macro didn't get supported language\\\") %}\\n    {%- endif -%}\\n\\n    {%- if name is not none -%}\\n      {{ store_result(name, response=res, agate_table=table) }}\\n    {%- endif -%}\\n\\n  {%- endif -%}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496097,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.noop_statement\": {\n      \"name\": \"noop_statement\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/etc/statement.sql\",\n      \"original_file_path\": \"macros/etc/statement.sql\",\n      \"unique_id\": \"macro.dbt.noop_statement\",\n      \"macro_sql\": \"{% macro noop_statement(name=None, message=None, code=None, rows_affected=None, res=None) -%}\\n  {%- set sql = caller() -%}\\n\\n  {%- if name == 'main' -%}\\n    {{ log('Writing runtime SQL for node \\\"{}\\\"'.format(model['unique_id'])) }}\\n    {{ write(sql) }}\\n  {%- endif -%}\\n\\n  {%- if name is not none -%}\\n    {{ store_raw_result(name, message=message, code=code, rows_affected=rows_affected, agate_table=res) }}\\n  {%- endif -%}\\n\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4961002,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.run_query\": {\n      \"name\": \"run_query\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/etc/statement.sql\",\n      \"original_file_path\": \"macros/etc/statement.sql\",\n      \"unique_id\": \"macro.dbt.run_query\",\n      \"macro_sql\": \"{% macro run_query(sql) %}\\n  {% call statement(\\\"run_query_statement\\\", fetch_result=true, auto_begin=false) %}\\n    {{ sql }}\\n  {% endcall %}\\n\\n  {% do return(load_result(\\\"run_query_statement\\\").table) %}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.statement\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4961028,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.convert_datetime\": {\n      \"name\": \"convert_datetime\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/etc/datetime.sql\",\n      \"original_file_path\": \"macros/etc/datetime.sql\",\n      \"unique_id\": \"macro.dbt.convert_datetime\",\n      \"macro_sql\": \"{% macro convert_datetime(date_str, date_fmt) %}\\n\\n  {% set error_msg -%}\\n      The provided partition date '{{ date_str }}' does not match the expected format '{{ date_fmt }}'\\n  {%- endset %}\\n\\n  {% set res = try_or_compiler_error(error_msg, modules.datetime.datetime.strptime, date_str.strip(), date_fmt) %}\\n  {{ return(res) }}\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.49611,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.dates_in_range\": {\n      \"name\": \"dates_in_range\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/etc/datetime.sql\",\n      \"original_file_path\": \"macros/etc/datetime.sql\",\n      \"unique_id\": \"macro.dbt.dates_in_range\",\n      \"macro_sql\": \"{% macro dates_in_range(start_date_str, end_date_str=none, in_fmt=\\\"%Y%m%d\\\", out_fmt=\\\"%Y%m%d\\\") %}\\n    {% set end_date_str = start_date_str if end_date_str is none else end_date_str %}\\n\\n    {% set start_date = convert_datetime(start_date_str, in_fmt) %}\\n    {% set end_date = convert_datetime(end_date_str, in_fmt) %}\\n\\n    {% set day_count = (end_date - start_date).days %}\\n    {% if day_count < 0 %}\\n        {% set msg -%}\\n            Partition start date is after the end date ({{ start_date }}, {{ end_date }})\\n        {%- endset %}\\n\\n        {{ exceptions.raise_compiler_error(msg, model) }}\\n    {% endif %}\\n\\n    {% set date_list = [] %}\\n    {% for i in range(0, day_count + 1) %}\\n        {% set the_date = (modules.datetime.timedelta(days=i) + start_date) %}\\n        {% if not out_fmt %}\\n            {% set _ = date_list.append(the_date) %}\\n        {% else %}\\n            {% set _ = date_list.append(the_date.strftime(out_fmt)) %}\\n        {% endif %}\\n    {% endfor %}\\n\\n    {{ return(date_list) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.convert_datetime\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4961128,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.partition_range\": {\n      \"name\": \"partition_range\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/etc/datetime.sql\",\n      \"original_file_path\": \"macros/etc/datetime.sql\",\n      \"unique_id\": \"macro.dbt.partition_range\",\n      \"macro_sql\": \"{% macro partition_range(raw_partition_date, date_fmt='%Y%m%d') %}\\n    {% set partition_range = (raw_partition_date | string).split(\\\",\\\") %}\\n\\n    {% if (partition_range | length) == 1 %}\\n      {% set start_date = partition_range[0] %}\\n      {% set end_date = none %}\\n    {% elif (partition_range | length) == 2 %}\\n      {% set start_date = partition_range[0] %}\\n      {% set end_date = partition_range[1] %}\\n    {% else %}\\n      {{ exceptions.raise_compiler_error(\\\"Invalid partition time. Expected format: {Start Date}[,{End Date}]. Got: \\\" ~ raw_partition_date) }}\\n    {% endif %}\\n\\n    {{ return(dates_in_range(start_date, end_date, in_fmt=date_fmt)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.dates_in_range\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496115,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.py_current_timestring\": {\n      \"name\": \"py_current_timestring\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/etc/datetime.sql\",\n      \"original_file_path\": \"macros/etc/datetime.sql\",\n      \"unique_id\": \"macro.dbt.py_current_timestring\",\n      \"macro_sql\": \"{% macro py_current_timestring() %}\\n    {% set dt = modules.datetime.datetime.now() %}\\n    {% do return(dt.strftime(\\\"%Y%m%d%H%M%S%f\\\")) %}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4961169,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.except\": {\n      \"name\": \"except\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/except.sql\",\n      \"original_file_path\": \"macros/utils/except.sql\",\n      \"unique_id\": \"macro.dbt.except\",\n      \"macro_sql\": \"{% macro except() %}\\n  {{ return(adapter.dispatch('except', 'dbt')()) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__except\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4961221,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__except\": {\n      \"name\": \"default__except\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/except.sql\",\n      \"original_file_path\": \"macros/utils/except.sql\",\n      \"unique_id\": \"macro.dbt.default__except\",\n      \"macro_sql\": \"{% macro default__except() %}\\n\\n    except\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4961238,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_intervals_between\": {\n      \"name\": \"get_intervals_between\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/date_spine.sql\",\n      \"original_file_path\": \"macros/utils/date_spine.sql\",\n      \"unique_id\": \"macro.dbt.get_intervals_between\",\n      \"macro_sql\": \"{% macro get_intervals_between(start_date, end_date, datepart) -%}\\n    {{ return(adapter.dispatch('get_intervals_between', 'dbt')(start_date, end_date, datepart)) }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_intervals_between\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4961321,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_intervals_between\": {\n      \"name\": \"default__get_intervals_between\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/date_spine.sql\",\n      \"original_file_path\": \"macros/utils/date_spine.sql\",\n      \"unique_id\": \"macro.dbt.default__get_intervals_between\",\n      \"macro_sql\": \"{% macro default__get_intervals_between(start_date, end_date, datepart) -%}\\n    {%- call statement('get_intervals_between', fetch_result=True) %}\\n\\n        select {{ dbt.datediff(start_date, end_date, datepart) }}\\n\\n    {%- endcall -%}\\n\\n    {%- set value_list = load_result('get_intervals_between') -%}\\n\\n    {%- if value_list and value_list['data'] -%}\\n        {%- set values = value_list['data'] | map(attribute=0) | list %}\\n        {{ return(values[0]) }}\\n    {%- else -%}\\n        {{ return(1) }}\\n    {%- endif -%}\\n\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.statement\",\n          \"macro.dbt.datediff\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496139,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.date_spine\": {\n      \"name\": \"date_spine\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/date_spine.sql\",\n      \"original_file_path\": \"macros/utils/date_spine.sql\",\n      \"unique_id\": \"macro.dbt.date_spine\",\n      \"macro_sql\": \"{% macro date_spine(datepart, start_date, end_date) %}\\n    {{ return(adapter.dispatch('date_spine', 'dbt')(datepart, start_date, end_date)) }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__date_spine\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496141,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__date_spine\": {\n      \"name\": \"default__date_spine\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/date_spine.sql\",\n      \"original_file_path\": \"macros/utils/date_spine.sql\",\n      \"unique_id\": \"macro.dbt.default__date_spine\",\n      \"macro_sql\": \"{% macro default__date_spine(datepart, start_date, end_date) %}\\n\\n\\n    {# call as follows:\\n\\n    date_spine(\\n        \\\"day\\\",\\n        \\\"to_date('01/01/2016', 'mm/dd/yyyy')\\\",\\n        \\\"dbt.dateadd(week, 1, current_date)\\\"\\n    ) #}\\n\\n\\n    with rawdata as (\\n\\n        {{dbt.generate_series(\\n            dbt.get_intervals_between(start_date, end_date, datepart)\\n        )}}\\n\\n    ),\\n\\n    all_periods as (\\n\\n        select (\\n            {{\\n                dbt.dateadd(\\n                    datepart,\\n                    \\\"row_number() over (order by 1) - 1\\\",\\n                    start_date\\n                )\\n            }}\\n        ) as date_{{datepart}}\\n        from rawdata\\n\\n    ),\\n\\n    filtered as (\\n\\n        select *\\n        from all_periods\\n        where date_{{datepart}} <= {{ end_date }}\\n\\n    )\\n\\n    select * from filtered\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.generate_series\",\n          \"macro.dbt.get_intervals_between\",\n          \"macro.dbt.dateadd\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4961438,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.date\": {\n      \"name\": \"date\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/date.sql\",\n      \"original_file_path\": \"macros/utils/date.sql\",\n      \"unique_id\": \"macro.dbt.date\",\n      \"macro_sql\": \"{% macro date(year, month, day) %}\\n  {{ return(adapter.dispatch('date', 'dbt') (year, month, day)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__date\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496149,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__date\": {\n      \"name\": \"default__date\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/date.sql\",\n      \"original_file_path\": \"macros/utils/date.sql\",\n      \"unique_id\": \"macro.dbt.default__date\",\n      \"macro_sql\": \"{% macro default__date(year, month, day) -%}\\n    {%- set dt = modules.datetime.date(year, month, day) -%}\\n    {%- set iso_8601_formatted_date = dt.strftime('%Y-%m-%d') -%}\\n    to_date('{{ iso_8601_formatted_date }}', 'YYYY-MM-DD')\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496151,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.replace\": {\n      \"name\": \"replace\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/replace.sql\",\n      \"original_file_path\": \"macros/utils/replace.sql\",\n      \"unique_id\": \"macro.dbt.replace\",\n      \"macro_sql\": \"{% macro replace(field, old_chars, new_chars) -%}\\n    {{ return(adapter.dispatch('replace', 'dbt') (field, old_chars, new_chars)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__replace\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496158,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__replace\": {\n      \"name\": \"default__replace\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/replace.sql\",\n      \"original_file_path\": \"macros/utils/replace.sql\",\n      \"unique_id\": \"macro.dbt.default__replace\",\n      \"macro_sql\": \"{% macro default__replace(field, old_chars, new_chars) %}\\n\\n    replace(\\n        {{ field }},\\n        {{ old_chars }},\\n        {{ new_chars }}\\n    )\\n\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496161,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.concat\": {\n      \"name\": \"concat\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/concat.sql\",\n      \"original_file_path\": \"macros/utils/concat.sql\",\n      \"unique_id\": \"macro.dbt.concat\",\n      \"macro_sql\": \"{% macro concat(fields) -%}\\n  {{ return(adapter.dispatch('concat', 'dbt')(fields)) }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__concat\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496165,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__concat\": {\n      \"name\": \"default__concat\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/concat.sql\",\n      \"original_file_path\": \"macros/utils/concat.sql\",\n      \"unique_id\": \"macro.dbt.default__concat\",\n      \"macro_sql\": \"{% macro default__concat(fields) -%}\\n    {{ fields|join(' || ') }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496167,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_powers_of_two\": {\n      \"name\": \"get_powers_of_two\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/generate_series.sql\",\n      \"original_file_path\": \"macros/utils/generate_series.sql\",\n      \"unique_id\": \"macro.dbt.get_powers_of_two\",\n      \"macro_sql\": \"{% macro get_powers_of_two(upper_bound) %}\\n    {{ return(adapter.dispatch('get_powers_of_two', 'dbt')(upper_bound)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_powers_of_two\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496172,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_powers_of_two\": {\n      \"name\": \"default__get_powers_of_two\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/generate_series.sql\",\n      \"original_file_path\": \"macros/utils/generate_series.sql\",\n      \"unique_id\": \"macro.dbt.default__get_powers_of_two\",\n      \"macro_sql\": \"{% macro default__get_powers_of_two(upper_bound) %}\\n\\n    {% if upper_bound <= 0 %}\\n    {{ exceptions.raise_compiler_error(\\\"upper bound must be positive\\\") }}\\n    {% endif %}\\n\\n    {% for _ in range(1, 100) %}\\n       {% if upper_bound <= 2 ** loop.index %}{{ return(loop.index) }}{% endif %}\\n    {% endfor %}\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496174,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.generate_series\": {\n      \"name\": \"generate_series\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/generate_series.sql\",\n      \"original_file_path\": \"macros/utils/generate_series.sql\",\n      \"unique_id\": \"macro.dbt.generate_series\",\n      \"macro_sql\": \"{% macro generate_series(upper_bound) %}\\n    {{ return(adapter.dispatch('generate_series', 'dbt')(upper_bound)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__generate_series\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.49618,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__generate_series\": {\n      \"name\": \"default__generate_series\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/generate_series.sql\",\n      \"original_file_path\": \"macros/utils/generate_series.sql\",\n      \"unique_id\": \"macro.dbt.default__generate_series\",\n      \"macro_sql\": \"{% macro default__generate_series(upper_bound) %}\\n\\n    {% set n = dbt.get_powers_of_two(upper_bound) %}\\n\\n    with p as (\\n        select 0 as generated_number union all select 1\\n    ), unioned as (\\n\\n    select\\n\\n    {% for i in range(n) %}\\n    p{{i}}.generated_number * power(2, {{i}})\\n    {% if not loop.last %} + {% endif %}\\n    {% endfor %}\\n    + 1\\n    as generated_number\\n\\n    from\\n\\n    {% for i in range(n) %}\\n    p as p{{i}}\\n    {% if not loop.last %} cross join {% endif %}\\n    {% endfor %}\\n\\n    )\\n\\n    select *\\n    from unioned\\n    where generated_number <= {{upper_bound}}\\n    order by generated_number\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.get_powers_of_two\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496184,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.length\": {\n      \"name\": \"length\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/length.sql\",\n      \"original_file_path\": \"macros/utils/length.sql\",\n      \"unique_id\": \"macro.dbt.length\",\n      \"macro_sql\": \"{% macro length(expression) -%}\\n    {{ return(adapter.dispatch('length', 'dbt') (expression)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__length\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496188,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__length\": {\n      \"name\": \"default__length\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/length.sql\",\n      \"original_file_path\": \"macros/utils/length.sql\",\n      \"unique_id\": \"macro.dbt.default__length\",\n      \"macro_sql\": \"{% macro default__length(expression) %}\\n\\n    length(\\n        {{ expression }}\\n    )\\n\\n{%- endmacro -%}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.49619,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.dateadd\": {\n      \"name\": \"dateadd\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/dateadd.sql\",\n      \"original_file_path\": \"macros/utils/dateadd.sql\",\n      \"unique_id\": \"macro.dbt.dateadd\",\n      \"macro_sql\": \"{% macro dateadd(datepart, interval, from_date_or_timestamp) %}\\n  {{ return(adapter.dispatch('dateadd', 'dbt')(datepart, interval, from_date_or_timestamp)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__dateadd\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496195,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__dateadd\": {\n      \"name\": \"default__dateadd\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/dateadd.sql\",\n      \"original_file_path\": \"macros/utils/dateadd.sql\",\n      \"unique_id\": \"macro.dbt.default__dateadd\",\n      \"macro_sql\": \"{% macro default__dateadd(datepart, interval, from_date_or_timestamp) %}\\n\\n    dateadd(\\n        {{ datepart }},\\n        {{ interval }},\\n        {{ from_date_or_timestamp }}\\n        )\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4961972,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.intersect\": {\n      \"name\": \"intersect\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/intersect.sql\",\n      \"original_file_path\": \"macros/utils/intersect.sql\",\n      \"unique_id\": \"macro.dbt.intersect\",\n      \"macro_sql\": \"{% macro intersect() %}\\n  {{ return(adapter.dispatch('intersect', 'dbt')()) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__intersect\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496201,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__intersect\": {\n      \"name\": \"default__intersect\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/intersect.sql\",\n      \"original_file_path\": \"macros/utils/intersect.sql\",\n      \"unique_id\": \"macro.dbt.default__intersect\",\n      \"macro_sql\": \"{% macro default__intersect() %}\\n\\n    intersect\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496203,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.escape_single_quotes\": {\n      \"name\": \"escape_single_quotes\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/escape_single_quotes.sql\",\n      \"original_file_path\": \"macros/utils/escape_single_quotes.sql\",\n      \"unique_id\": \"macro.dbt.escape_single_quotes\",\n      \"macro_sql\": \"{% macro escape_single_quotes(expression) %}\\n      {{ return(adapter.dispatch('escape_single_quotes', 'dbt') (expression)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__escape_single_quotes\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496208,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__escape_single_quotes\": {\n      \"name\": \"default__escape_single_quotes\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/escape_single_quotes.sql\",\n      \"original_file_path\": \"macros/utils/escape_single_quotes.sql\",\n      \"unique_id\": \"macro.dbt.default__escape_single_quotes\",\n      \"macro_sql\": \"{% macro default__escape_single_quotes(expression) -%}\\n{{ expression | replace(\\\"'\\\",\\\"''\\\") }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4962099,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.right\": {\n      \"name\": \"right\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/right.sql\",\n      \"original_file_path\": \"macros/utils/right.sql\",\n      \"unique_id\": \"macro.dbt.right\",\n      \"macro_sql\": \"{% macro right(string_text, length_expression) -%}\\n    {{ return(adapter.dispatch('right', 'dbt') (string_text, length_expression)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__right\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496214,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__right\": {\n      \"name\": \"default__right\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/right.sql\",\n      \"original_file_path\": \"macros/utils/right.sql\",\n      \"unique_id\": \"macro.dbt.default__right\",\n      \"macro_sql\": \"{% macro default__right(string_text, length_expression) %}\\n\\n    right(\\n        {{ string_text }},\\n        {{ length_expression }}\\n    )\\n\\n{%- endmacro -%}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496217,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.listagg\": {\n      \"name\": \"listagg\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/listagg.sql\",\n      \"original_file_path\": \"macros/utils/listagg.sql\",\n      \"unique_id\": \"macro.dbt.listagg\",\n      \"macro_sql\": \"{% macro listagg(measure, delimiter_text=\\\"','\\\", order_by_clause=none, limit_num=none) -%}\\n    {{ return(adapter.dispatch('listagg', 'dbt') (measure, delimiter_text, order_by_clause, limit_num)) }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__listagg\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496222,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__listagg\": {\n      \"name\": \"default__listagg\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/listagg.sql\",\n      \"original_file_path\": \"macros/utils/listagg.sql\",\n      \"unique_id\": \"macro.dbt.default__listagg\",\n      \"macro_sql\": \"{% macro default__listagg(measure, delimiter_text, order_by_clause, limit_num) -%}\\n\\n    {% if limit_num -%}\\n    array_to_string(\\n        array_slice(\\n            array_agg(\\n                {{ measure }}\\n            ){% if order_by_clause -%}\\n            within group ({{ order_by_clause }})\\n            {%- endif %}\\n            ,0\\n            ,{{ limit_num }}\\n        ),\\n        {{ delimiter_text }}\\n        )\\n    {%- else %}\\n    listagg(\\n        {{ measure }},\\n        {{ delimiter_text }}\\n        )\\n        {% if order_by_clause -%}\\n        within group ({{ order_by_clause }})\\n        {%- endif %}\\n    {%- endif %}\\n\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496226,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.datediff\": {\n      \"name\": \"datediff\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/datediff.sql\",\n      \"original_file_path\": \"macros/utils/datediff.sql\",\n      \"unique_id\": \"macro.dbt.datediff\",\n      \"macro_sql\": \"{% macro datediff(first_date, second_date, datepart) %}\\n  {{ return(adapter.dispatch('datediff', 'dbt')(first_date, second_date, datepart)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__datediff\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496232,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__datediff\": {\n      \"name\": \"default__datediff\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/datediff.sql\",\n      \"original_file_path\": \"macros/utils/datediff.sql\",\n      \"unique_id\": \"macro.dbt.default__datediff\",\n      \"macro_sql\": \"{% macro default__datediff(first_date, second_date, datepart) -%}\\n\\n    datediff(\\n        {{ datepart }},\\n        {{ first_date }},\\n        {{ second_date }}\\n        )\\n\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496234,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.safe_cast\": {\n      \"name\": \"safe_cast\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/safe_cast.sql\",\n      \"original_file_path\": \"macros/utils/safe_cast.sql\",\n      \"unique_id\": \"macro.dbt.safe_cast\",\n      \"macro_sql\": \"{% macro safe_cast(field, type) %}\\n  {{ return(adapter.dispatch('safe_cast', 'dbt') (field, type)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__safe_cast\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4962418,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__safe_cast\": {\n      \"name\": \"default__safe_cast\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/safe_cast.sql\",\n      \"original_file_path\": \"macros/utils/safe_cast.sql\",\n      \"unique_id\": \"macro.dbt.default__safe_cast\",\n      \"macro_sql\": \"{% macro default__safe_cast(field, type) %}\\n    {# most databases don't support this function yet\\n    so we just need to use cast #}\\n    cast({{field}} as {{type}})\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496245,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.equals\": {\n      \"name\": \"equals\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/equals.sql\",\n      \"original_file_path\": \"macros/utils/equals.sql\",\n      \"unique_id\": \"macro.dbt.equals\",\n      \"macro_sql\": \"{% macro equals(expr1, expr2) %}\\n    {{ return(adapter.dispatch('equals', 'dbt') (expr1, expr2)) }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__equals\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4962492,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__equals\": {\n      \"name\": \"default__equals\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/equals.sql\",\n      \"original_file_path\": \"macros/utils/equals.sql\",\n      \"unique_id\": \"macro.dbt.default__equals\",\n      \"macro_sql\": \"{% macro default__equals(expr1, expr2) -%}\\n{%- if adapter.behavior.enable_truthy_nulls_equals_macro.no_warn %}\\n    case when (({{ expr1 }} = {{ expr2 }}) or ({{ expr1 }} is null and {{ expr2 }} is null))\\n        then 0\\n        else 1\\n    end = 0\\n{%- else -%}\\n    ({{ expr1 }} = {{ expr2 }})\\n{%- endif %}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4962518,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.hash\": {\n      \"name\": \"hash\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/hash.sql\",\n      \"original_file_path\": \"macros/utils/hash.sql\",\n      \"unique_id\": \"macro.dbt.hash\",\n      \"macro_sql\": \"{% macro hash(field) -%}\\n  {{ return(adapter.dispatch('hash', 'dbt') (field)) }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__hash\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496257,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__hash\": {\n      \"name\": \"default__hash\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/hash.sql\",\n      \"original_file_path\": \"macros/utils/hash.sql\",\n      \"unique_id\": \"macro.dbt.default__hash\",\n      \"macro_sql\": \"{% macro default__hash(field) -%}\\n    md5(cast({{ field }} as {{ api.Column.translate_type('string') }}))\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496259,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.cast_bool_to_text\": {\n      \"name\": \"cast_bool_to_text\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/cast_bool_to_text.sql\",\n      \"original_file_path\": \"macros/utils/cast_bool_to_text.sql\",\n      \"unique_id\": \"macro.dbt.cast_bool_to_text\",\n      \"macro_sql\": \"{% macro cast_bool_to_text(field) %}\\n  {{ adapter.dispatch('cast_bool_to_text', 'dbt') (field) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__cast_bool_to_text\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496264,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__cast_bool_to_text\": {\n      \"name\": \"default__cast_bool_to_text\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/cast_bool_to_text.sql\",\n      \"original_file_path\": \"macros/utils/cast_bool_to_text.sql\",\n      \"unique_id\": \"macro.dbt.default__cast_bool_to_text\",\n      \"macro_sql\": \"{% macro default__cast_bool_to_text(field) %}\\n    cast({{ field }} as {{ api.Column.translate_type('string') }})\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496267,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.cast\": {\n      \"name\": \"cast\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/cast.sql\",\n      \"original_file_path\": \"macros/utils/cast.sql\",\n      \"unique_id\": \"macro.dbt.cast\",\n      \"macro_sql\": \"{% macro cast(field, type) %}\\n  {{ return(adapter.dispatch('cast', 'dbt') (field, type)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__cast\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.49629,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__cast\": {\n      \"name\": \"default__cast\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/cast.sql\",\n      \"original_file_path\": \"macros/utils/cast.sql\",\n      \"unique_id\": \"macro.dbt.default__cast\",\n      \"macro_sql\": \"{% macro default__cast(field, type) %}\\n    cast({{field}} as {{type}})\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496292,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.any_value\": {\n      \"name\": \"any_value\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/any_value.sql\",\n      \"original_file_path\": \"macros/utils/any_value.sql\",\n      \"unique_id\": \"macro.dbt.any_value\",\n      \"macro_sql\": \"{% macro any_value(expression) -%}\\n    {{ return(adapter.dispatch('any_value', 'dbt') (expression)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__any_value\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496297,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__any_value\": {\n      \"name\": \"default__any_value\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/any_value.sql\",\n      \"original_file_path\": \"macros/utils/any_value.sql\",\n      \"unique_id\": \"macro.dbt.default__any_value\",\n      \"macro_sql\": \"{% macro default__any_value(expression) -%}\\n\\n    any_value({{ expression }})\\n\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496299,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.position\": {\n      \"name\": \"position\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/position.sql\",\n      \"original_file_path\": \"macros/utils/position.sql\",\n      \"unique_id\": \"macro.dbt.position\",\n      \"macro_sql\": \"{% macro position(substring_text, string_text) -%}\\n    {{ return(adapter.dispatch('position', 'dbt') (substring_text, string_text)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__position\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496305,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__position\": {\n      \"name\": \"default__position\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/position.sql\",\n      \"original_file_path\": \"macros/utils/position.sql\",\n      \"unique_id\": \"macro.dbt.default__position\",\n      \"macro_sql\": \"{% macro default__position(substring_text, string_text) %}\\n\\n    position(\\n        {{ substring_text }} in {{ string_text }}\\n    )\\n\\n{%- endmacro -%}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496307,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.string_literal\": {\n      \"name\": \"string_literal\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/literal.sql\",\n      \"original_file_path\": \"macros/utils/literal.sql\",\n      \"unique_id\": \"macro.dbt.string_literal\",\n      \"macro_sql\": \"{%- macro string_literal(value) -%}\\n  {{ return(adapter.dispatch('string_literal', 'dbt') (value)) }}\\n{%- endmacro -%}\\n\\n\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__string_literal\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496311,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__string_literal\": {\n      \"name\": \"default__string_literal\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/literal.sql\",\n      \"original_file_path\": \"macros/utils/literal.sql\",\n      \"unique_id\": \"macro.dbt.default__string_literal\",\n      \"macro_sql\": \"{% macro default__string_literal(value) -%}\\n    '{{ value }}'\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4963148,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.type_string\": {\n      \"name\": \"type_string\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/data_types.sql\",\n      \"original_file_path\": \"macros/utils/data_types.sql\",\n      \"unique_id\": \"macro.dbt.type_string\",\n      \"macro_sql\": \"\\n\\n{%- macro type_string() -%}\\n  {{ return(adapter.dispatch('type_string', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__type_string\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4963222,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__type_string\": {\n      \"name\": \"default__type_string\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/data_types.sql\",\n      \"original_file_path\": \"macros/utils/data_types.sql\",\n      \"unique_id\": \"macro.dbt.default__type_string\",\n      \"macro_sql\": \"{% macro default__type_string() %}\\n    {{ return(api.Column.translate_type(\\\"string\\\")) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496324,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.type_timestamp\": {\n      \"name\": \"type_timestamp\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/data_types.sql\",\n      \"original_file_path\": \"macros/utils/data_types.sql\",\n      \"unique_id\": \"macro.dbt.type_timestamp\",\n      \"macro_sql\": \"\\n\\n{%- macro type_timestamp() -%}\\n  {{ return(adapter.dispatch('type_timestamp', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__type_timestamp\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496326,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__type_timestamp\": {\n      \"name\": \"default__type_timestamp\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/data_types.sql\",\n      \"original_file_path\": \"macros/utils/data_types.sql\",\n      \"unique_id\": \"macro.dbt.default__type_timestamp\",\n      \"macro_sql\": \"{% macro default__type_timestamp() %}\\n    {{ return(api.Column.translate_type(\\\"timestamp\\\")) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496331,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.type_float\": {\n      \"name\": \"type_float\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/data_types.sql\",\n      \"original_file_path\": \"macros/utils/data_types.sql\",\n      \"unique_id\": \"macro.dbt.type_float\",\n      \"macro_sql\": \"\\n\\n{%- macro type_float() -%}\\n  {{ return(adapter.dispatch('type_float', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__type_float\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4963331,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__type_float\": {\n      \"name\": \"default__type_float\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/data_types.sql\",\n      \"original_file_path\": \"macros/utils/data_types.sql\",\n      \"unique_id\": \"macro.dbt.default__type_float\",\n      \"macro_sql\": \"{% macro default__type_float() %}\\n    {{ return(api.Column.translate_type(\\\"float\\\")) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496335,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.type_numeric\": {\n      \"name\": \"type_numeric\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/data_types.sql\",\n      \"original_file_path\": \"macros/utils/data_types.sql\",\n      \"unique_id\": \"macro.dbt.type_numeric\",\n      \"macro_sql\": \"\\n\\n{%- macro type_numeric() -%}\\n  {{ return(adapter.dispatch('type_numeric', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__type_numeric\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496342,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__type_numeric\": {\n      \"name\": \"default__type_numeric\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/data_types.sql\",\n      \"original_file_path\": \"macros/utils/data_types.sql\",\n      \"unique_id\": \"macro.dbt.default__type_numeric\",\n      \"macro_sql\": \"{% macro default__type_numeric() %}\\n    {{ return(api.Column.numeric_type(\\\"numeric\\\", 28, 6)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496344,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.type_bigint\": {\n      \"name\": \"type_bigint\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/data_types.sql\",\n      \"original_file_path\": \"macros/utils/data_types.sql\",\n      \"unique_id\": \"macro.dbt.type_bigint\",\n      \"macro_sql\": \"\\n\\n{%- macro type_bigint() -%}\\n  {{ return(adapter.dispatch('type_bigint', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__type_bigint\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496346,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__type_bigint\": {\n      \"name\": \"default__type_bigint\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/data_types.sql\",\n      \"original_file_path\": \"macros/utils/data_types.sql\",\n      \"unique_id\": \"macro.dbt.default__type_bigint\",\n      \"macro_sql\": \"{% macro default__type_bigint() %}\\n    {{ return(api.Column.translate_type(\\\"bigint\\\")) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4963489,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.type_int\": {\n      \"name\": \"type_int\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/data_types.sql\",\n      \"original_file_path\": \"macros/utils/data_types.sql\",\n      \"unique_id\": \"macro.dbt.type_int\",\n      \"macro_sql\": \"\\n\\n{%- macro type_int() -%}\\n  {{ return(adapter.dispatch('type_int', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__type_int\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496351,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__type_int\": {\n      \"name\": \"default__type_int\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/data_types.sql\",\n      \"original_file_path\": \"macros/utils/data_types.sql\",\n      \"unique_id\": \"macro.dbt.default__type_int\",\n      \"macro_sql\": \"{%- macro default__type_int() -%}\\n  {{ return(api.Column.translate_type(\\\"integer\\\")) }}\\n{%- endmacro -%}\\n\\n\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496354,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.type_boolean\": {\n      \"name\": \"type_boolean\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/data_types.sql\",\n      \"original_file_path\": \"macros/utils/data_types.sql\",\n      \"unique_id\": \"macro.dbt.type_boolean\",\n      \"macro_sql\": \"\\n\\n{%- macro type_boolean() -%}\\n  {{ return(adapter.dispatch('type_boolean', 'dbt')()) }}\\n{%- endmacro -%}\\n\\n\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__type_boolean\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496356,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__type_boolean\": {\n      \"name\": \"default__type_boolean\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/data_types.sql\",\n      \"original_file_path\": \"macros/utils/data_types.sql\",\n      \"unique_id\": \"macro.dbt.default__type_boolean\",\n      \"macro_sql\": \"{%- macro default__type_boolean() -%}\\n  {{ return(api.Column.translate_type(\\\"boolean\\\")) }}\\n{%- endmacro -%}\\n\\n\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4963589,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.array_concat\": {\n      \"name\": \"array_concat\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/array_concat.sql\",\n      \"original_file_path\": \"macros/utils/array_concat.sql\",\n      \"unique_id\": \"macro.dbt.array_concat\",\n      \"macro_sql\": \"{% macro array_concat(array_1, array_2) -%}\\n  {{ return(adapter.dispatch('array_concat', 'dbt')(array_1, array_2)) }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__array_concat\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496364,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__array_concat\": {\n      \"name\": \"default__array_concat\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/array_concat.sql\",\n      \"original_file_path\": \"macros/utils/array_concat.sql\",\n      \"unique_id\": \"macro.dbt.default__array_concat\",\n      \"macro_sql\": \"{% macro default__array_concat(array_1, array_2) -%}\\n    array_cat({{ array_1 }}, {{ array_2 }})\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496366,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.bool_or\": {\n      \"name\": \"bool_or\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/bool_or.sql\",\n      \"original_file_path\": \"macros/utils/bool_or.sql\",\n      \"unique_id\": \"macro.dbt.bool_or\",\n      \"macro_sql\": \"{% macro bool_or(expression) -%}\\n    {{ return(adapter.dispatch('bool_or', 'dbt') (expression)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__bool_or\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496372,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__bool_or\": {\n      \"name\": \"default__bool_or\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/bool_or.sql\",\n      \"original_file_path\": \"macros/utils/bool_or.sql\",\n      \"unique_id\": \"macro.dbt.default__bool_or\",\n      \"macro_sql\": \"{% macro default__bool_or(expression) -%}\\n\\n    bool_or({{ expression }})\\n\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4963741,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.last_day\": {\n      \"name\": \"last_day\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/last_day.sql\",\n      \"original_file_path\": \"macros/utils/last_day.sql\",\n      \"unique_id\": \"macro.dbt.last_day\",\n      \"macro_sql\": \"{% macro last_day(date, datepart) %}\\n  {{ return(adapter.dispatch('last_day', 'dbt') (date, datepart)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__last_day\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496379,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default_last_day\": {\n      \"name\": \"default_last_day\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/last_day.sql\",\n      \"original_file_path\": \"macros/utils/last_day.sql\",\n      \"unique_id\": \"macro.dbt.default_last_day\",\n      \"macro_sql\": \"\\n\\n{%- macro default_last_day(date, datepart) -%}\\n    cast(\\n        {{dbt.dateadd('day', '-1',\\n        dbt.dateadd(datepart, '1', dbt.date_trunc(datepart, date))\\n        )}}\\n        as date)\\n{%- endmacro -%}\\n\\n\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.dateadd\",\n          \"macro.dbt.date_trunc\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496383,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__last_day\": {\n      \"name\": \"default__last_day\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/last_day.sql\",\n      \"original_file_path\": \"macros/utils/last_day.sql\",\n      \"unique_id\": \"macro.dbt.default__last_day\",\n      \"macro_sql\": \"{% macro default__last_day(date, datepart) -%}\\n    {{dbt.default_last_day(date, datepart)}}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default_last_day\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496385,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.split_part\": {\n      \"name\": \"split_part\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/split_part.sql\",\n      \"original_file_path\": \"macros/utils/split_part.sql\",\n      \"unique_id\": \"macro.dbt.split_part\",\n      \"macro_sql\": \"{% macro split_part(string_text, delimiter_text, part_number) %}\\n  {{ return(adapter.dispatch('split_part', 'dbt') (string_text, delimiter_text, part_number)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__split_part\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4963892,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__split_part\": {\n      \"name\": \"default__split_part\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/split_part.sql\",\n      \"original_file_path\": \"macros/utils/split_part.sql\",\n      \"unique_id\": \"macro.dbt.default__split_part\",\n      \"macro_sql\": \"{% macro default__split_part(string_text, delimiter_text, part_number) %}\\n\\n    split_part(\\n        {{ string_text }},\\n        {{ delimiter_text }},\\n        {{ part_number }}\\n        )\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4963908,\n      \"supported_languages\": null\n    },\n    \"macro.dbt._split_part_negative\": {\n      \"name\": \"_split_part_negative\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/split_part.sql\",\n      \"original_file_path\": \"macros/utils/split_part.sql\",\n      \"unique_id\": \"macro.dbt._split_part_negative\",\n      \"macro_sql\": \"{% macro _split_part_negative(string_text, delimiter_text, part_number) %}\\n\\n    split_part(\\n        {{ string_text }},\\n        {{ delimiter_text }},\\n          length({{ string_text }})\\n          - length(\\n              replace({{ string_text }},  {{ delimiter_text }}, '')\\n          ) + 2 + {{ part_number }}\\n        )\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496397,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.date_trunc\": {\n      \"name\": \"date_trunc\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/date_trunc.sql\",\n      \"original_file_path\": \"macros/utils/date_trunc.sql\",\n      \"unique_id\": \"macro.dbt.date_trunc\",\n      \"macro_sql\": \"{% macro date_trunc(datepart, date) -%}\\n  {{ return(adapter.dispatch('date_trunc', 'dbt') (datepart, date)) }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__date_trunc\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496402,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__date_trunc\": {\n      \"name\": \"default__date_trunc\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/date_trunc.sql\",\n      \"original_file_path\": \"macros/utils/date_trunc.sql\",\n      \"unique_id\": \"macro.dbt.default__date_trunc\",\n      \"macro_sql\": \"{% macro default__date_trunc(datepart, date) -%}\\n    date_trunc('{{datepart}}', {{date}})\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496404,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.array_construct\": {\n      \"name\": \"array_construct\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/array_construct.sql\",\n      \"original_file_path\": \"macros/utils/array_construct.sql\",\n      \"unique_id\": \"macro.dbt.array_construct\",\n      \"macro_sql\": \"{% macro array_construct(inputs=[], data_type=api.Column.translate_type('integer')) -%}\\n  {{ return(adapter.dispatch('array_construct', 'dbt')(inputs, data_type)) }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__array_construct\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4964101,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__array_construct\": {\n      \"name\": \"default__array_construct\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/array_construct.sql\",\n      \"original_file_path\": \"macros/utils/array_construct.sql\",\n      \"unique_id\": \"macro.dbt.default__array_construct\",\n      \"macro_sql\": \"{% macro default__array_construct(inputs, data_type) -%}\\n    {% if inputs|length > 0 %}\\n    array[ {{ inputs|join(' , ') }} ]\\n    {% else %}\\n    array[]::{{data_type}}[]\\n    {% endif %}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4964118,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.array_append\": {\n      \"name\": \"array_append\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/array_append.sql\",\n      \"original_file_path\": \"macros/utils/array_append.sql\",\n      \"unique_id\": \"macro.dbt.array_append\",\n      \"macro_sql\": \"{% macro array_append(array, new_element) -%}\\n  {{ return(adapter.dispatch('array_append', 'dbt')(array, new_element)) }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__array_append\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496416,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__array_append\": {\n      \"name\": \"default__array_append\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/utils/array_append.sql\",\n      \"original_file_path\": \"macros/utils/array_append.sql\",\n      \"unique_id\": \"macro.dbt.default__array_append\",\n      \"macro_sql\": \"{% macro default__array_append(array, new_element) -%}\\n    array_append({{ array }}, {{ new_element }})\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496418,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.create_schema\": {\n      \"name\": \"create_schema\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/schema.sql\",\n      \"original_file_path\": \"macros/adapters/schema.sql\",\n      \"unique_id\": \"macro.dbt.create_schema\",\n      \"macro_sql\": \"{% macro create_schema(relation) -%}\\n  {{ adapter.dispatch('create_schema', 'dbt')(relation) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__create_schema\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496423,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__create_schema\": {\n      \"name\": \"default__create_schema\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/schema.sql\",\n      \"original_file_path\": \"macros/adapters/schema.sql\",\n      \"unique_id\": \"macro.dbt.default__create_schema\",\n      \"macro_sql\": \"{% macro default__create_schema(relation) -%}\\n  {%- call statement('create_schema') -%}\\n    create schema if not exists {{ relation.without_identifier() }}\\n  {% endcall %}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.statement\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496425,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.drop_schema\": {\n      \"name\": \"drop_schema\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/schema.sql\",\n      \"original_file_path\": \"macros/adapters/schema.sql\",\n      \"unique_id\": \"macro.dbt.drop_schema\",\n      \"macro_sql\": \"{% macro drop_schema(relation) -%}\\n  {{ adapter.dispatch('drop_schema', 'dbt')(relation) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__drop_schema\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496435,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__drop_schema\": {\n      \"name\": \"default__drop_schema\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/schema.sql\",\n      \"original_file_path\": \"macros/adapters/schema.sql\",\n      \"unique_id\": \"macro.dbt.default__drop_schema\",\n      \"macro_sql\": \"{% macro default__drop_schema(relation) -%}\\n  {%- call statement('drop_schema') -%}\\n    drop schema if exists {{ relation.without_identifier() }} cascade\\n  {% endcall %}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.statement\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496437,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.current_timestamp\": {\n      \"name\": \"current_timestamp\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/timestamps.sql\",\n      \"original_file_path\": \"macros/adapters/timestamps.sql\",\n      \"unique_id\": \"macro.dbt.current_timestamp\",\n      \"macro_sql\": \"{%- macro current_timestamp() -%}\\n    {{ adapter.dispatch('current_timestamp', 'dbt')() }}\\n{%- endmacro -%}\\n\\n\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__current_timestamp\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496442,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__current_timestamp\": {\n      \"name\": \"default__current_timestamp\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/timestamps.sql\",\n      \"original_file_path\": \"macros/adapters/timestamps.sql\",\n      \"unique_id\": \"macro.dbt.default__current_timestamp\",\n      \"macro_sql\": \"{% macro default__current_timestamp() -%}\\n  {{ exceptions.raise_not_implemented(\\n    'current_timestamp macro not implemented for adapter ' + adapter.type()) }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496445,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.snapshot_get_time\": {\n      \"name\": \"snapshot_get_time\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/timestamps.sql\",\n      \"original_file_path\": \"macros/adapters/timestamps.sql\",\n      \"unique_id\": \"macro.dbt.snapshot_get_time\",\n      \"macro_sql\": \"\\n\\n{%- macro snapshot_get_time() -%}\\n    {{ adapter.dispatch('snapshot_get_time', 'dbt')() }}\\n{%- endmacro -%}\\n\\n\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__snapshot_get_time\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496447,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__snapshot_get_time\": {\n      \"name\": \"default__snapshot_get_time\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/timestamps.sql\",\n      \"original_file_path\": \"macros/adapters/timestamps.sql\",\n      \"unique_id\": \"macro.dbt.default__snapshot_get_time\",\n      \"macro_sql\": \"{% macro default__snapshot_get_time() %}\\n    {{ current_timestamp() }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.current_timestamp\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496449,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_snapshot_get_time_data_type\": {\n      \"name\": \"get_snapshot_get_time_data_type\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/timestamps.sql\",\n      \"original_file_path\": \"macros/adapters/timestamps.sql\",\n      \"unique_id\": \"macro.dbt.get_snapshot_get_time_data_type\",\n      \"macro_sql\": \"{% macro get_snapshot_get_time_data_type() %}\\n    {% set snapshot_time = adapter.dispatch('snapshot_get_time', 'dbt')() %}\\n    {% set time_data_type_sql = 'select ' ~ snapshot_time ~ ' as dbt_snapshot_time' %}\\n    {% set snapshot_time_column_schema = get_column_schema_from_query(time_data_type_sql) %}\\n    {% set time_data_type = snapshot_time_column_schema[0].dtype %}\\n    {{ return(time_data_type or none) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.snapshot_get_time\",\n          \"macro.dbt_postgres.postgres__snapshot_get_time\",\n          \"macro.dbt.get_column_schema_from_query\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4964511,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.current_timestamp_backcompat\": {\n      \"name\": \"current_timestamp_backcompat\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/timestamps.sql\",\n      \"original_file_path\": \"macros/adapters/timestamps.sql\",\n      \"unique_id\": \"macro.dbt.current_timestamp_backcompat\",\n      \"macro_sql\": \"{% macro current_timestamp_backcompat() %}\\n    {{ return(adapter.dispatch('current_timestamp_backcompat', 'dbt')()) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__current_timestamp_backcompat\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496452,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__current_timestamp_backcompat\": {\n      \"name\": \"default__current_timestamp_backcompat\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/timestamps.sql\",\n      \"original_file_path\": \"macros/adapters/timestamps.sql\",\n      \"unique_id\": \"macro.dbt.default__current_timestamp_backcompat\",\n      \"macro_sql\": \"{% macro default__current_timestamp_backcompat() %}\\n    current_timestamp::timestamp\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496454,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.current_timestamp_in_utc_backcompat\": {\n      \"name\": \"current_timestamp_in_utc_backcompat\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/timestamps.sql\",\n      \"original_file_path\": \"macros/adapters/timestamps.sql\",\n      \"unique_id\": \"macro.dbt.current_timestamp_in_utc_backcompat\",\n      \"macro_sql\": \"{% macro current_timestamp_in_utc_backcompat() %}\\n    {{ return(adapter.dispatch('current_timestamp_in_utc_backcompat', 'dbt')()) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__current_timestamp_in_utc_backcompat\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496458,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__current_timestamp_in_utc_backcompat\": {\n      \"name\": \"default__current_timestamp_in_utc_backcompat\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/timestamps.sql\",\n      \"original_file_path\": \"macros/adapters/timestamps.sql\",\n      \"unique_id\": \"macro.dbt.default__current_timestamp_in_utc_backcompat\",\n      \"macro_sql\": \"{% macro default__current_timestamp_in_utc_backcompat() %}\\n    {{ return(adapter.dispatch('current_timestamp_backcompat', 'dbt')()) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.current_timestamp_backcompat\",\n          \"macro.dbt_postgres.postgres__current_timestamp_backcompat\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.49646,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_create_index_sql\": {\n      \"name\": \"get_create_index_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/indexes.sql\",\n      \"original_file_path\": \"macros/adapters/indexes.sql\",\n      \"unique_id\": \"macro.dbt.get_create_index_sql\",\n      \"macro_sql\": \"{% macro get_create_index_sql(relation, index_dict) -%}\\n  {{ return(adapter.dispatch('get_create_index_sql', 'dbt')(relation, index_dict)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__get_create_index_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4964669,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_create_index_sql\": {\n      \"name\": \"default__get_create_index_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/indexes.sql\",\n      \"original_file_path\": \"macros/adapters/indexes.sql\",\n      \"unique_id\": \"macro.dbt.default__get_create_index_sql\",\n      \"macro_sql\": \"{% macro default__get_create_index_sql(relation, index_dict) -%}\\n  {% do return(None) %}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496469,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.create_indexes\": {\n      \"name\": \"create_indexes\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/indexes.sql\",\n      \"original_file_path\": \"macros/adapters/indexes.sql\",\n      \"unique_id\": \"macro.dbt.create_indexes\",\n      \"macro_sql\": \"{% macro create_indexes(relation) -%}\\n  {{ adapter.dispatch('create_indexes', 'dbt')(relation) }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__create_indexes\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496471,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__create_indexes\": {\n      \"name\": \"default__create_indexes\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/indexes.sql\",\n      \"original_file_path\": \"macros/adapters/indexes.sql\",\n      \"unique_id\": \"macro.dbt.default__create_indexes\",\n      \"macro_sql\": \"{% macro default__create_indexes(relation) -%}\\n  {%- set _indexes = config.get('indexes', default=[]) -%}\\n\\n  {% for _index_dict in _indexes %}\\n    {% set create_index_sql = get_create_index_sql(relation, _index_dict) %}\\n    {% if create_index_sql %}\\n      {% do run_query(create_index_sql) %}\\n    {% endif %}\\n  {% endfor %}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.get_create_index_sql\",\n          \"macro.dbt.run_query\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496473,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_drop_index_sql\": {\n      \"name\": \"get_drop_index_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/indexes.sql\",\n      \"original_file_path\": \"macros/adapters/indexes.sql\",\n      \"unique_id\": \"macro.dbt.get_drop_index_sql\",\n      \"macro_sql\": \"{% macro get_drop_index_sql(relation, index_name) -%}\\n    {{ adapter.dispatch('get_drop_index_sql', 'dbt')(relation, index_name) }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__get_drop_index_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496475,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_drop_index_sql\": {\n      \"name\": \"default__get_drop_index_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/indexes.sql\",\n      \"original_file_path\": \"macros/adapters/indexes.sql\",\n      \"unique_id\": \"macro.dbt.default__get_drop_index_sql\",\n      \"macro_sql\": \"{% macro default__get_drop_index_sql(relation, index_name) -%}\\n    {{ exceptions.raise_compiler_error(\\\"`get_drop_index_sql has not been implemented for this adapter.\\\") }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496477,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_show_indexes_sql\": {\n      \"name\": \"get_show_indexes_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/indexes.sql\",\n      \"original_file_path\": \"macros/adapters/indexes.sql\",\n      \"unique_id\": \"macro.dbt.get_show_indexes_sql\",\n      \"macro_sql\": \"{% macro get_show_indexes_sql(relation) -%}\\n    {{ adapter.dispatch('get_show_indexes_sql', 'dbt')(relation) }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__get_show_indexes_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496479,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_show_indexes_sql\": {\n      \"name\": \"default__get_show_indexes_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/indexes.sql\",\n      \"original_file_path\": \"macros/adapters/indexes.sql\",\n      \"unique_id\": \"macro.dbt.default__get_show_indexes_sql\",\n      \"macro_sql\": \"{% macro default__get_show_indexes_sql(relation) -%}\\n    {{ exceptions.raise_compiler_error(\\\"`get_show_indexes_sql has not been implemented for this adapter.\\\") }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496481,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.make_intermediate_relation\": {\n      \"name\": \"make_intermediate_relation\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/relation.sql\",\n      \"original_file_path\": \"macros/adapters/relation.sql\",\n      \"unique_id\": \"macro.dbt.make_intermediate_relation\",\n      \"macro_sql\": \"{% macro make_intermediate_relation(base_relation, suffix='__dbt_tmp') %}\\n  {{ return(adapter.dispatch('make_intermediate_relation', 'dbt')(base_relation, suffix)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__make_intermediate_relation\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496489,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__make_intermediate_relation\": {\n      \"name\": \"default__make_intermediate_relation\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/relation.sql\",\n      \"original_file_path\": \"macros/adapters/relation.sql\",\n      \"unique_id\": \"macro.dbt.default__make_intermediate_relation\",\n      \"macro_sql\": \"{% macro default__make_intermediate_relation(base_relation, suffix) %}\\n    {{ return(default__make_temp_relation(base_relation, suffix)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__make_temp_relation\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496491,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.make_temp_relation\": {\n      \"name\": \"make_temp_relation\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/relation.sql\",\n      \"original_file_path\": \"macros/adapters/relation.sql\",\n      \"unique_id\": \"macro.dbt.make_temp_relation\",\n      \"macro_sql\": \"{% macro make_temp_relation(base_relation, suffix='__dbt_tmp') %}\\n  {#-- This ensures microbatch batches get unique temp relations to avoid clobbering --#}\\n  {% if suffix == '__dbt_tmp' and model.batch %}\\n    {% set suffix = suffix ~ '_' ~ model.batch.id %}\\n  {% endif %}\\n\\n  {{ return(adapter.dispatch('make_temp_relation', 'dbt')(base_relation, suffix)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__make_temp_relation\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496495,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__make_temp_relation\": {\n      \"name\": \"default__make_temp_relation\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/relation.sql\",\n      \"original_file_path\": \"macros/adapters/relation.sql\",\n      \"unique_id\": \"macro.dbt.default__make_temp_relation\",\n      \"macro_sql\": \"{% macro default__make_temp_relation(base_relation, suffix) %}\\n    {%- set temp_identifier = base_relation.identifier ~ suffix -%}\\n    {%- set temp_relation = base_relation.incorporate(\\n                                path={\\\"identifier\\\": temp_identifier}) -%}\\n\\n    {{ return(temp_relation) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496497,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.make_backup_relation\": {\n      \"name\": \"make_backup_relation\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/relation.sql\",\n      \"original_file_path\": \"macros/adapters/relation.sql\",\n      \"unique_id\": \"macro.dbt.make_backup_relation\",\n      \"macro_sql\": \"{% macro make_backup_relation(base_relation, backup_relation_type, suffix='__dbt_backup') %}\\n    {{ return(adapter.dispatch('make_backup_relation', 'dbt')(base_relation, backup_relation_type, suffix)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__make_backup_relation\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496499,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__make_backup_relation\": {\n      \"name\": \"default__make_backup_relation\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/relation.sql\",\n      \"original_file_path\": \"macros/adapters/relation.sql\",\n      \"unique_id\": \"macro.dbt.default__make_backup_relation\",\n      \"macro_sql\": \"{% macro default__make_backup_relation(base_relation, backup_relation_type, suffix) %}\\n    {%- set backup_identifier = base_relation.identifier ~ suffix -%}\\n    {%- set backup_relation = base_relation.incorporate(\\n                                  path={\\\"identifier\\\": backup_identifier},\\n                                  type=backup_relation_type\\n    ) -%}\\n    {{ return(backup_relation) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496501,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.truncate_relation\": {\n      \"name\": \"truncate_relation\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/relation.sql\",\n      \"original_file_path\": \"macros/adapters/relation.sql\",\n      \"unique_id\": \"macro.dbt.truncate_relation\",\n      \"macro_sql\": \"{% macro truncate_relation(relation) -%}\\n  {{ return(adapter.dispatch('truncate_relation', 'dbt')(relation)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__truncate_relation\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496503,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__truncate_relation\": {\n      \"name\": \"default__truncate_relation\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/relation.sql\",\n      \"original_file_path\": \"macros/adapters/relation.sql\",\n      \"unique_id\": \"macro.dbt.default__truncate_relation\",\n      \"macro_sql\": \"{% macro default__truncate_relation(relation) -%}\\n  {% call statement('truncate_relation') -%}\\n    truncate table {{ relation.render() }}\\n  {%- endcall %}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.statement\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496505,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_or_create_relation\": {\n      \"name\": \"get_or_create_relation\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/relation.sql\",\n      \"original_file_path\": \"macros/adapters/relation.sql\",\n      \"unique_id\": \"macro.dbt.get_or_create_relation\",\n      \"macro_sql\": \"{% macro get_or_create_relation(database, schema, identifier, type) -%}\\n  {{ return(adapter.dispatch('get_or_create_relation', 'dbt')(database, schema, identifier, type)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_or_create_relation\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496507,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_or_create_relation\": {\n      \"name\": \"default__get_or_create_relation\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/relation.sql\",\n      \"original_file_path\": \"macros/adapters/relation.sql\",\n      \"unique_id\": \"macro.dbt.default__get_or_create_relation\",\n      \"macro_sql\": \"{% macro default__get_or_create_relation(database, schema, identifier, type) %}\\n  {%- set target_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) %}\\n\\n  {% if target_relation %}\\n    {% do return([true, target_relation]) %}\\n  {% endif %}\\n\\n  {%- set new_relation = api.Relation.create(\\n      database=database,\\n      schema=schema,\\n      identifier=identifier,\\n      type=type\\n  ) -%}\\n  {% do return([false, new_relation]) %}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4965088,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.load_cached_relation\": {\n      \"name\": \"load_cached_relation\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/relation.sql\",\n      \"original_file_path\": \"macros/adapters/relation.sql\",\n      \"unique_id\": \"macro.dbt.load_cached_relation\",\n      \"macro_sql\": \"{% macro load_cached_relation(relation) %}\\n  {% do return(adapter.get_relation(\\n    database=relation.database,\\n    schema=relation.schema,\\n    identifier=relation.identifier\\n  )) -%}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496511,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.load_relation\": {\n      \"name\": \"load_relation\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/relation.sql\",\n      \"original_file_path\": \"macros/adapters/relation.sql\",\n      \"unique_id\": \"macro.dbt.load_relation\",\n      \"macro_sql\": \"{% macro load_relation(relation) %}\\n    {{ return(load_cached_relation(relation)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.load_cached_relation\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496512,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.collect_freshness\": {\n      \"name\": \"collect_freshness\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/freshness.sql\",\n      \"original_file_path\": \"macros/adapters/freshness.sql\",\n      \"unique_id\": \"macro.dbt.collect_freshness\",\n      \"macro_sql\": \"{% macro collect_freshness(source, loaded_at_field, filter) %}\\n  {{ return(adapter.dispatch('collect_freshness', 'dbt')(source, loaded_at_field, filter))}}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__collect_freshness\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4965189,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__collect_freshness\": {\n      \"name\": \"default__collect_freshness\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/freshness.sql\",\n      \"original_file_path\": \"macros/adapters/freshness.sql\",\n      \"unique_id\": \"macro.dbt.default__collect_freshness\",\n      \"macro_sql\": \"{% macro default__collect_freshness(source, loaded_at_field, filter) %}\\n  {% call statement('collect_freshness', fetch_result=True, auto_begin=False) -%}\\n    select\\n      max({{ loaded_at_field }}) as max_loaded_at,\\n      {{ current_timestamp() }} as snapshotted_at\\n    from {{ source }}\\n    {% if filter %}\\n    where {{ filter }}\\n    {% endif %}\\n  {% endcall %}\\n  {{ return(load_result('collect_freshness')) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.statement\",\n          \"macro.dbt.current_timestamp\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496521,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.collect_freshness_custom_sql\": {\n      \"name\": \"collect_freshness_custom_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/freshness.sql\",\n      \"original_file_path\": \"macros/adapters/freshness.sql\",\n      \"unique_id\": \"macro.dbt.collect_freshness_custom_sql\",\n      \"macro_sql\": \"{% macro collect_freshness_custom_sql(source, loaded_at_query) %}\\n  {{ return(adapter.dispatch('collect_freshness_custom_sql', 'dbt')(source, loaded_at_query))}}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__collect_freshness_custom_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496523,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__collect_freshness_custom_sql\": {\n      \"name\": \"default__collect_freshness_custom_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/freshness.sql\",\n      \"original_file_path\": \"macros/adapters/freshness.sql\",\n      \"unique_id\": \"macro.dbt.default__collect_freshness_custom_sql\",\n      \"macro_sql\": \"{% macro default__collect_freshness_custom_sql(source, loaded_at_query) %}\\n  {% call statement('collect_freshness_custom_sql', fetch_result=True, auto_begin=False) -%}\\n  with source_query as (\\n    {{ loaded_at_query }}\\n  )\\n  select\\n    (select * from source_query) as max_loaded_at,\\n    {{ current_timestamp() }} as snapshotted_at\\n  {% endcall %}\\n  {{ return(load_result('collect_freshness_custom_sql')) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.statement\",\n          \"macro.dbt.current_timestamp\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496525,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.validate_sql\": {\n      \"name\": \"validate_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/validate_sql.sql\",\n      \"original_file_path\": \"macros/adapters/validate_sql.sql\",\n      \"unique_id\": \"macro.dbt.validate_sql\",\n      \"macro_sql\": \"{% macro validate_sql(sql) -%}\\n  {{ return(adapter.dispatch('validate_sql', 'dbt')(sql)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__validate_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4965298,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__validate_sql\": {\n      \"name\": \"default__validate_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/validate_sql.sql\",\n      \"original_file_path\": \"macros/adapters/validate_sql.sql\",\n      \"unique_id\": \"macro.dbt.default__validate_sql\",\n      \"macro_sql\": \"{% macro default__validate_sql(sql) -%}\\n  {% call statement('validate_sql') -%}\\n    explain {{ sql }}\\n  {% endcall %}\\n  {{ return(load_result('validate_sql')) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.statement\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496532,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.copy_grants\": {\n      \"name\": \"copy_grants\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/apply_grants.sql\",\n      \"original_file_path\": \"macros/adapters/apply_grants.sql\",\n      \"unique_id\": \"macro.dbt.copy_grants\",\n      \"macro_sql\": \"{% macro copy_grants() %}\\n    {{ return(adapter.dispatch('copy_grants', 'dbt')()) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__copy_grants\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4965398,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__copy_grants\": {\n      \"name\": \"default__copy_grants\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/apply_grants.sql\",\n      \"original_file_path\": \"macros/adapters/apply_grants.sql\",\n      \"unique_id\": \"macro.dbt.default__copy_grants\",\n      \"macro_sql\": \"{% macro default__copy_grants() %}\\n    {{ return(True) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496543,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.support_multiple_grantees_per_dcl_statement\": {\n      \"name\": \"support_multiple_grantees_per_dcl_statement\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/apply_grants.sql\",\n      \"original_file_path\": \"macros/adapters/apply_grants.sql\",\n      \"unique_id\": \"macro.dbt.support_multiple_grantees_per_dcl_statement\",\n      \"macro_sql\": \"{% macro support_multiple_grantees_per_dcl_statement() %}\\n    {{ return(adapter.dispatch('support_multiple_grantees_per_dcl_statement', 'dbt')()) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__support_multiple_grantees_per_dcl_statement\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496545,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__support_multiple_grantees_per_dcl_statement\": {\n      \"name\": \"default__support_multiple_grantees_per_dcl_statement\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/apply_grants.sql\",\n      \"original_file_path\": \"macros/adapters/apply_grants.sql\",\n      \"unique_id\": \"macro.dbt.default__support_multiple_grantees_per_dcl_statement\",\n      \"macro_sql\": \"\\n\\n{%- macro default__support_multiple_grantees_per_dcl_statement() -%}\\n    {{ return(True) }}\\n{%- endmacro -%}\\n\\n\\n\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496547,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.should_revoke\": {\n      \"name\": \"should_revoke\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/apply_grants.sql\",\n      \"original_file_path\": \"macros/adapters/apply_grants.sql\",\n      \"unique_id\": \"macro.dbt.should_revoke\",\n      \"macro_sql\": \"{% macro should_revoke(existing_relation, full_refresh_mode=True) %}\\n\\n    {% if not existing_relation %}\\n        {#-- The table doesn't already exist, so no grants to copy over --#}\\n        {{ return(False) }}\\n    {% elif full_refresh_mode %}\\n        {#-- The object is being REPLACED -- whether grants are copied over depends on the value of user config --#}\\n        {{ return(copy_grants()) }}\\n    {% else %}\\n        {#-- The table is being merged/upserted/inserted -- grants will be carried over --#}\\n        {{ return(True) }}\\n    {% endif %}\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.copy_grants\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4965498,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_show_grant_sql\": {\n      \"name\": \"get_show_grant_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/apply_grants.sql\",\n      \"original_file_path\": \"macros/adapters/apply_grants.sql\",\n      \"unique_id\": \"macro.dbt.get_show_grant_sql\",\n      \"macro_sql\": \"{% macro get_show_grant_sql(relation) %}\\n    {{ return(adapter.dispatch(\\\"get_show_grant_sql\\\", \\\"dbt\\\")(relation)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__get_show_grant_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496552,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_show_grant_sql\": {\n      \"name\": \"default__get_show_grant_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/apply_grants.sql\",\n      \"original_file_path\": \"macros/adapters/apply_grants.sql\",\n      \"unique_id\": \"macro.dbt.default__get_show_grant_sql\",\n      \"macro_sql\": \"{% macro default__get_show_grant_sql(relation) %}\\n    show grants on {{ relation.render() }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496554,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_grant_sql\": {\n      \"name\": \"get_grant_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/apply_grants.sql\",\n      \"original_file_path\": \"macros/adapters/apply_grants.sql\",\n      \"unique_id\": \"macro.dbt.get_grant_sql\",\n      \"macro_sql\": \"{% macro get_grant_sql(relation, privilege, grantees) %}\\n    {{ return(adapter.dispatch('get_grant_sql', 'dbt')(relation, privilege, grantees)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_grant_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496556,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_grant_sql\": {\n      \"name\": \"default__get_grant_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/apply_grants.sql\",\n      \"original_file_path\": \"macros/adapters/apply_grants.sql\",\n      \"unique_id\": \"macro.dbt.default__get_grant_sql\",\n      \"macro_sql\": \"\\n\\n{%- macro default__get_grant_sql(relation, privilege, grantees) -%}\\n    grant {{ privilege }} on {{ relation.render() }} to {{ grantees | join(', ') }}\\n{%- endmacro -%}\\n\\n\\n\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4965582,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_revoke_sql\": {\n      \"name\": \"get_revoke_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/apply_grants.sql\",\n      \"original_file_path\": \"macros/adapters/apply_grants.sql\",\n      \"unique_id\": \"macro.dbt.get_revoke_sql\",\n      \"macro_sql\": \"{% macro get_revoke_sql(relation, privilege, grantees) %}\\n    {{ return(adapter.dispatch('get_revoke_sql', 'dbt')(relation, privilege, grantees)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_revoke_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.49656,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_revoke_sql\": {\n      \"name\": \"default__get_revoke_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/apply_grants.sql\",\n      \"original_file_path\": \"macros/adapters/apply_grants.sql\",\n      \"unique_id\": \"macro.dbt.default__get_revoke_sql\",\n      \"macro_sql\": \"\\n\\n{%- macro default__get_revoke_sql(relation, privilege, grantees) -%}\\n    revoke {{ privilege }} on {{ relation.render() }} from {{ grantees | join(', ') }}\\n{%- endmacro -%}\\n\\n\\n\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496568,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_dcl_statement_list\": {\n      \"name\": \"get_dcl_statement_list\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/apply_grants.sql\",\n      \"original_file_path\": \"macros/adapters/apply_grants.sql\",\n      \"unique_id\": \"macro.dbt.get_dcl_statement_list\",\n      \"macro_sql\": \"{% macro get_dcl_statement_list(relation, grant_config, get_dcl_macro) %}\\n    {{ return(adapter.dispatch('get_dcl_statement_list', 'dbt')(relation, grant_config, get_dcl_macro)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_dcl_statement_list\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.49657,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_dcl_statement_list\": {\n      \"name\": \"default__get_dcl_statement_list\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/apply_grants.sql\",\n      \"original_file_path\": \"macros/adapters/apply_grants.sql\",\n      \"unique_id\": \"macro.dbt.default__get_dcl_statement_list\",\n      \"macro_sql\": \"\\n\\n{%- macro default__get_dcl_statement_list(relation, grant_config, get_dcl_macro) -%}\\n    {#\\n      -- Unpack grant_config into specific privileges and the set of users who need them granted/revoked.\\n      -- Depending on whether this database supports multiple grantees per statement, pass in the list of\\n      -- all grantees per privilege, or (if not) template one statement per privilege-grantee pair.\\n      -- `get_dcl_macro` will be either `get_grant_sql` or `get_revoke_sql`\\n    #}\\n    {%- set dcl_statements = [] -%}\\n    {%- for privilege, grantees in grant_config.items() %}\\n        {%- if support_multiple_grantees_per_dcl_statement() and grantees -%}\\n          {%- set dcl = get_dcl_macro(relation, privilege, grantees) -%}\\n          {%- do dcl_statements.append(dcl) -%}\\n        {%- else -%}\\n          {%- for grantee in grantees -%}\\n              {% set dcl = get_dcl_macro(relation, privilege, [grantee]) %}\\n              {%- do dcl_statements.append(dcl) -%}\\n          {% endfor -%}\\n        {%- endif -%}\\n    {%- endfor -%}\\n    {{ return(dcl_statements) }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.support_multiple_grantees_per_dcl_statement\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496572,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.call_dcl_statements\": {\n      \"name\": \"call_dcl_statements\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/apply_grants.sql\",\n      \"original_file_path\": \"macros/adapters/apply_grants.sql\",\n      \"unique_id\": \"macro.dbt.call_dcl_statements\",\n      \"macro_sql\": \"{% macro call_dcl_statements(dcl_statement_list) %}\\n    {{ return(adapter.dispatch(\\\"call_dcl_statements\\\", \\\"dbt\\\")(dcl_statement_list)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__call_dcl_statements\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4965749,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__call_dcl_statements\": {\n      \"name\": \"default__call_dcl_statements\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/apply_grants.sql\",\n      \"original_file_path\": \"macros/adapters/apply_grants.sql\",\n      \"unique_id\": \"macro.dbt.default__call_dcl_statements\",\n      \"macro_sql\": \"{% macro default__call_dcl_statements(dcl_statement_list) %}\\n    {#\\n      -- By default, supply all grant + revoke statements in a single semicolon-separated block,\\n      -- so that they're all processed together.\\n\\n      -- Some databases do not support this. Those adapters will need to override this macro\\n      -- to run each statement individually.\\n    #}\\n    {% call statement('grants') %}\\n        {% for dcl_statement in dcl_statement_list %}\\n            {{ dcl_statement }};\\n        {% endfor %}\\n    {% endcall %}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.statement\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496577,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.apply_grants\": {\n      \"name\": \"apply_grants\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/apply_grants.sql\",\n      \"original_file_path\": \"macros/adapters/apply_grants.sql\",\n      \"unique_id\": \"macro.dbt.apply_grants\",\n      \"macro_sql\": \"{% macro apply_grants(relation, grant_config, should_revoke) %}\\n    {{ return(adapter.dispatch(\\\"apply_grants\\\", \\\"dbt\\\")(relation, grant_config, should_revoke)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__apply_grants\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4965792,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__apply_grants\": {\n      \"name\": \"default__apply_grants\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/apply_grants.sql\",\n      \"original_file_path\": \"macros/adapters/apply_grants.sql\",\n      \"unique_id\": \"macro.dbt.default__apply_grants\",\n      \"macro_sql\": \"{% macro default__apply_grants(relation, grant_config, should_revoke=True) %}\\n    {#-- If grant_config is {} or None, this is a no-op --#}\\n    {% if grant_config %}\\n        {% if should_revoke %}\\n            {#-- We think previous grants may have carried over --#}\\n            {#-- Show current grants and calculate diffs --#}\\n            {% set current_grants_table = run_query(get_show_grant_sql(relation)) %}\\n            {% set current_grants_dict = adapter.standardize_grants_dict(current_grants_table) %}\\n            {% set needs_granting = diff_of_two_dicts(grant_config, current_grants_dict) %}\\n            {% set needs_revoking = diff_of_two_dicts(current_grants_dict, grant_config) %}\\n            {% if not (needs_granting or needs_revoking) %}\\n                {{ log('On ' ~ relation.render() ~': All grants are in place, no revocation or granting needed.')}}\\n            {% endif %}\\n        {% else %}\\n            {#-- We don't think there's any chance of previous grants having carried over. --#}\\n            {#-- Jump straight to granting what the user has configured. --#}\\n            {% set needs_revoking = {} %}\\n            {% set needs_granting = grant_config %}\\n        {% endif %}\\n        {% if needs_granting or needs_revoking %}\\n            {% set revoke_statement_list = get_dcl_statement_list(relation, needs_revoking, get_revoke_sql) %}\\n            {% set grant_statement_list = get_dcl_statement_list(relation, needs_granting, get_grant_sql) %}\\n            {% set dcl_statement_list = revoke_statement_list + grant_statement_list %}\\n            {% if dcl_statement_list %}\\n                {{ call_dcl_statements(dcl_statement_list) }}\\n            {% endif %}\\n        {% endif %}\\n    {% endif %}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.run_query\",\n          \"macro.dbt.get_show_grant_sql\",\n          \"macro.dbt.get_dcl_statement_list\",\n          \"macro.dbt.call_dcl_statements\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496586,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_show_sql\": {\n      \"name\": \"get_show_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/show.sql\",\n      \"original_file_path\": \"macros/adapters/show.sql\",\n      \"unique_id\": \"macro.dbt.get_show_sql\",\n      \"macro_sql\": \"{% macro get_show_sql(compiled_code, sql_header, limit) -%}\\n  {%- if sql_header is not none -%}\\n  {{ sql_header }}\\n  {%- endif %}\\n  {{ get_limit_subquery_sql(compiled_code, limit) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.get_limit_subquery_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4965918,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_limit_subquery_sql\": {\n      \"name\": \"get_limit_subquery_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/show.sql\",\n      \"original_file_path\": \"macros/adapters/show.sql\",\n      \"unique_id\": \"macro.dbt.get_limit_subquery_sql\",\n      \"macro_sql\": \"\\n{%- macro get_limit_subquery_sql(sql, limit) -%}\\n  {{ adapter.dispatch('get_limit_sql', 'dbt')(sql, limit) }}\\n{%- endmacro -%}\\n\\n\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_limit_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496594,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_limit_sql\": {\n      \"name\": \"default__get_limit_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/show.sql\",\n      \"original_file_path\": \"macros/adapters/show.sql\",\n      \"unique_id\": \"macro.dbt.default__get_limit_sql\",\n      \"macro_sql\": \"{% macro default__get_limit_sql(sql, limit) %}\\n  {{ sql }}\\n  {% if limit is not none %}\\n  limit {{ limit }}\\n  {%- endif -%}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496597,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.alter_column_comment\": {\n      \"name\": \"alter_column_comment\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/persist_docs.sql\",\n      \"original_file_path\": \"macros/adapters/persist_docs.sql\",\n      \"unique_id\": \"macro.dbt.alter_column_comment\",\n      \"macro_sql\": \"{% macro alter_column_comment(relation, column_dict) -%}\\n  {{ return(adapter.dispatch('alter_column_comment', 'dbt')(relation, column_dict)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__alter_column_comment\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496609,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__alter_column_comment\": {\n      \"name\": \"default__alter_column_comment\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/persist_docs.sql\",\n      \"original_file_path\": \"macros/adapters/persist_docs.sql\",\n      \"unique_id\": \"macro.dbt.default__alter_column_comment\",\n      \"macro_sql\": \"{% macro default__alter_column_comment(relation, column_dict) -%}\\n  {{ exceptions.raise_not_implemented(\\n    'alter_column_comment macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4966102,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.alter_relation_comment\": {\n      \"name\": \"alter_relation_comment\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/persist_docs.sql\",\n      \"original_file_path\": \"macros/adapters/persist_docs.sql\",\n      \"unique_id\": \"macro.dbt.alter_relation_comment\",\n      \"macro_sql\": \"{% macro alter_relation_comment(relation, relation_comment) -%}\\n  {{ return(adapter.dispatch('alter_relation_comment', 'dbt')(relation, relation_comment)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__alter_relation_comment\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496612,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__alter_relation_comment\": {\n      \"name\": \"default__alter_relation_comment\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/persist_docs.sql\",\n      \"original_file_path\": \"macros/adapters/persist_docs.sql\",\n      \"unique_id\": \"macro.dbt.default__alter_relation_comment\",\n      \"macro_sql\": \"{% macro default__alter_relation_comment(relation, relation_comment) -%}\\n  {{ exceptions.raise_not_implemented(\\n    'alter_relation_comment macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496615,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.persist_docs\": {\n      \"name\": \"persist_docs\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/persist_docs.sql\",\n      \"original_file_path\": \"macros/adapters/persist_docs.sql\",\n      \"unique_id\": \"macro.dbt.persist_docs\",\n      \"macro_sql\": \"{% macro persist_docs(relation, model, for_relation=true, for_columns=true) -%}\\n  {{ return(adapter.dispatch('persist_docs', 'dbt')(relation, model, for_relation, for_columns)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__persist_docs\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.49684,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__persist_docs\": {\n      \"name\": \"default__persist_docs\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/persist_docs.sql\",\n      \"original_file_path\": \"macros/adapters/persist_docs.sql\",\n      \"unique_id\": \"macro.dbt.default__persist_docs\",\n      \"macro_sql\": \"{% macro default__persist_docs(relation, model, for_relation, for_columns) -%}\\n  {% if for_relation and config.persist_relation_docs() and model.description %}\\n    {% do run_query(alter_relation_comment(relation, model.description)) %}\\n  {% endif %}\\n\\n  {% if for_columns and config.persist_column_docs() and model.columns %}\\n    {% do run_query(alter_column_comment(relation, model.columns)) %}\\n  {% endif %}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.run_query\",\n          \"macro.dbt.alter_relation_comment\",\n          \"macro.dbt.alter_column_comment\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496843,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_catalog_relations\": {\n      \"name\": \"get_catalog_relations\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/metadata.sql\",\n      \"original_file_path\": \"macros/adapters/metadata.sql\",\n      \"unique_id\": \"macro.dbt.get_catalog_relations\",\n      \"macro_sql\": \"{% macro get_catalog_relations(information_schema, relations) -%}\\n  {{ return(adapter.dispatch('get_catalog_relations', 'dbt')(information_schema, relations)) }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__get_catalog_relations\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4968488,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_catalog_relations\": {\n      \"name\": \"default__get_catalog_relations\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/metadata.sql\",\n      \"original_file_path\": \"macros/adapters/metadata.sql\",\n      \"unique_id\": \"macro.dbt.default__get_catalog_relations\",\n      \"macro_sql\": \"{% macro default__get_catalog_relations(information_schema, relations) -%}\\n  {% set typename = adapter.type() %}\\n  {% set msg -%}\\n    get_catalog_relations not implemented for {{ typename }}\\n  {%- endset %}\\n\\n  {{ exceptions.raise_compiler_error(msg) }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496851,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_catalog\": {\n      \"name\": \"get_catalog\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/metadata.sql\",\n      \"original_file_path\": \"macros/adapters/metadata.sql\",\n      \"unique_id\": \"macro.dbt.get_catalog\",\n      \"macro_sql\": \"{% macro get_catalog(information_schema, schemas) -%}\\n  {{ return(adapter.dispatch('get_catalog', 'dbt')(information_schema, schemas)) }}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__get_catalog\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4968529,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_catalog\": {\n      \"name\": \"default__get_catalog\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/metadata.sql\",\n      \"original_file_path\": \"macros/adapters/metadata.sql\",\n      \"unique_id\": \"macro.dbt.default__get_catalog\",\n      \"macro_sql\": \"{% macro default__get_catalog(information_schema, schemas) -%}\\n\\n  {% set typename = adapter.type() %}\\n  {% set msg -%}\\n    get_catalog not implemented for {{ typename }}\\n  {%- endset %}\\n\\n  {{ exceptions.raise_compiler_error(msg) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496855,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.information_schema_name\": {\n      \"name\": \"information_schema_name\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/metadata.sql\",\n      \"original_file_path\": \"macros/adapters/metadata.sql\",\n      \"unique_id\": \"macro.dbt.information_schema_name\",\n      \"macro_sql\": \"{% macro information_schema_name(database) %}\\n  {{ return(adapter.dispatch('information_schema_name', 'dbt')(database)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__information_schema_name\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4968572,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__information_schema_name\": {\n      \"name\": \"default__information_schema_name\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/metadata.sql\",\n      \"original_file_path\": \"macros/adapters/metadata.sql\",\n      \"unique_id\": \"macro.dbt.default__information_schema_name\",\n      \"macro_sql\": \"{% macro default__information_schema_name(database) -%}\\n  {%- if database -%}\\n    {{ database }}.INFORMATION_SCHEMA\\n  {%- else -%}\\n    INFORMATION_SCHEMA\\n  {%- endif -%}\\n{%- endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496861,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.list_schemas\": {\n      \"name\": \"list_schemas\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/metadata.sql\",\n      \"original_file_path\": \"macros/adapters/metadata.sql\",\n      \"unique_id\": \"macro.dbt.list_schemas\",\n      \"macro_sql\": \"{% macro list_schemas(database) -%}\\n  {{ return(adapter.dispatch('list_schemas', 'dbt')(database)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__list_schemas\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4968681,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__list_schemas\": {\n      \"name\": \"default__list_schemas\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/metadata.sql\",\n      \"original_file_path\": \"macros/adapters/metadata.sql\",\n      \"unique_id\": \"macro.dbt.default__list_schemas\",\n      \"macro_sql\": \"{% macro default__list_schemas(database) -%}\\n  {% set sql %}\\n    select distinct schema_name\\n    from {{ information_schema_name(database) }}.SCHEMATA\\n    where catalog_name ilike '{{ database }}'\\n  {% endset %}\\n  {{ return(run_query(sql)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.information_schema_name\",\n          \"macro.dbt.run_query\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4968698,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.check_schema_exists\": {\n      \"name\": \"check_schema_exists\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/metadata.sql\",\n      \"original_file_path\": \"macros/adapters/metadata.sql\",\n      \"unique_id\": \"macro.dbt.check_schema_exists\",\n      \"macro_sql\": \"{% macro check_schema_exists(information_schema, schema) -%}\\n  {{ return(adapter.dispatch('check_schema_exists', 'dbt')(information_schema, schema)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__check_schema_exists\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496872,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__check_schema_exists\": {\n      \"name\": \"default__check_schema_exists\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/metadata.sql\",\n      \"original_file_path\": \"macros/adapters/metadata.sql\",\n      \"unique_id\": \"macro.dbt.default__check_schema_exists\",\n      \"macro_sql\": \"{% macro default__check_schema_exists(information_schema, schema) -%}\\n  {% set sql -%}\\n        select count(*)\\n        from {{ information_schema.replace(information_schema_view='SCHEMATA') }}\\n        where catalog_name='{{ information_schema.database }}'\\n          and schema_name='{{ schema }}'\\n  {%- endset %}\\n  {{ return(run_query(sql)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.replace\",\n          \"macro.dbt.run_query\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496874,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.list_relations_without_caching\": {\n      \"name\": \"list_relations_without_caching\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/metadata.sql\",\n      \"original_file_path\": \"macros/adapters/metadata.sql\",\n      \"unique_id\": \"macro.dbt.list_relations_without_caching\",\n      \"macro_sql\": \"{% macro list_relations_without_caching(schema_relation) %}\\n  {{ return(adapter.dispatch('list_relations_without_caching', 'dbt')(schema_relation)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__list_relations_without_caching\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496876,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__list_relations_without_caching\": {\n      \"name\": \"default__list_relations_without_caching\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/metadata.sql\",\n      \"original_file_path\": \"macros/adapters/metadata.sql\",\n      \"unique_id\": \"macro.dbt.default__list_relations_without_caching\",\n      \"macro_sql\": \"{% macro default__list_relations_without_caching(schema_relation) %}\\n  {{ exceptions.raise_not_implemented(\\n    'list_relations_without_caching macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4968781,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_catalog_for_single_relation\": {\n      \"name\": \"get_catalog_for_single_relation\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/metadata.sql\",\n      \"original_file_path\": \"macros/adapters/metadata.sql\",\n      \"unique_id\": \"macro.dbt.get_catalog_for_single_relation\",\n      \"macro_sql\": \"{% macro get_catalog_for_single_relation(relation) %}\\n  {{ return(adapter.dispatch('get_catalog_for_single_relation', 'dbt')(relation)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_catalog_for_single_relation\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.49688,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_catalog_for_single_relation\": {\n      \"name\": \"default__get_catalog_for_single_relation\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/metadata.sql\",\n      \"original_file_path\": \"macros/adapters/metadata.sql\",\n      \"unique_id\": \"macro.dbt.default__get_catalog_for_single_relation\",\n      \"macro_sql\": \"{% macro default__get_catalog_for_single_relation(relation) %}\\n  {{ exceptions.raise_not_implemented(\\n    'get_catalog_for_single_relation macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496882,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_relations\": {\n      \"name\": \"get_relations\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/metadata.sql\",\n      \"original_file_path\": \"macros/adapters/metadata.sql\",\n      \"unique_id\": \"macro.dbt.get_relations\",\n      \"macro_sql\": \"{% macro get_relations() %}\\n  {{ return(adapter.dispatch('get_relations', 'dbt')()) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__get_relations\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4968882,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_relations\": {\n      \"name\": \"default__get_relations\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/metadata.sql\",\n      \"original_file_path\": \"macros/adapters/metadata.sql\",\n      \"unique_id\": \"macro.dbt.default__get_relations\",\n      \"macro_sql\": \"{% macro default__get_relations() %}\\n  {{ exceptions.raise_not_implemented(\\n    'get_relations macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4968908,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_relation_last_modified\": {\n      \"name\": \"get_relation_last_modified\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/metadata.sql\",\n      \"original_file_path\": \"macros/adapters/metadata.sql\",\n      \"unique_id\": \"macro.dbt.get_relation_last_modified\",\n      \"macro_sql\": \"{% macro get_relation_last_modified(information_schema, relations) %}\\n  {{ return(adapter.dispatch('get_relation_last_modified', 'dbt')(information_schema, relations)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_relation_last_modified\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496893,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_relation_last_modified\": {\n      \"name\": \"default__get_relation_last_modified\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/metadata.sql\",\n      \"original_file_path\": \"macros/adapters/metadata.sql\",\n      \"unique_id\": \"macro.dbt.default__get_relation_last_modified\",\n      \"macro_sql\": \"{% macro default__get_relation_last_modified(information_schema, relations) %}\\n  {{ exceptions.raise_not_implemented(\\n    'get_relation_last_modified macro not implemented for adapter ' + adapter.type()) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496895,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_columns_in_relation\": {\n      \"name\": \"get_columns_in_relation\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/columns.sql\",\n      \"original_file_path\": \"macros/adapters/columns.sql\",\n      \"unique_id\": \"macro.dbt.get_columns_in_relation\",\n      \"macro_sql\": \"{% macro get_columns_in_relation(relation) -%}\\n  {{ return(adapter.dispatch('get_columns_in_relation', 'dbt')(relation)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt_postgres.postgres__get_columns_in_relation\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496903,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_columns_in_relation\": {\n      \"name\": \"default__get_columns_in_relation\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/columns.sql\",\n      \"original_file_path\": \"macros/adapters/columns.sql\",\n      \"unique_id\": \"macro.dbt.default__get_columns_in_relation\",\n      \"macro_sql\": \"{% macro default__get_columns_in_relation(relation) -%}\\n  {{ exceptions.raise_not_implemented(\\n    'get_columns_in_relation macro not implemented for adapter '+adapter.type()) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4969049,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.sql_convert_columns_in_relation\": {\n      \"name\": \"sql_convert_columns_in_relation\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/columns.sql\",\n      \"original_file_path\": \"macros/adapters/columns.sql\",\n      \"unique_id\": \"macro.dbt.sql_convert_columns_in_relation\",\n      \"macro_sql\": \"{% macro sql_convert_columns_in_relation(table) -%}\\n  {% set columns = [] %}\\n  {% for row in table %}\\n    {% do columns.append(api.Column(*row)) %}\\n  {% endfor %}\\n  {{ return(columns) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496907,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_list_of_column_names\": {\n      \"name\": \"get_list_of_column_names\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/columns.sql\",\n      \"original_file_path\": \"macros/adapters/columns.sql\",\n      \"unique_id\": \"macro.dbt.get_list_of_column_names\",\n      \"macro_sql\": \"\\n\\n{%- macro get_list_of_column_names(columns) -%}\\n  {% set col_names = [] %}\\n  {% for col in columns %}\\n    {% do col_names.append(col.name) %}\\n  {% endfor %}\\n  {{ return(col_names) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.49691,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_empty_subquery_sql\": {\n      \"name\": \"get_empty_subquery_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/columns.sql\",\n      \"original_file_path\": \"macros/adapters/columns.sql\",\n      \"unique_id\": \"macro.dbt.get_empty_subquery_sql\",\n      \"macro_sql\": \"{% macro get_empty_subquery_sql(select_sql, select_sql_header=none) -%}\\n  {{ return(adapter.dispatch('get_empty_subquery_sql', 'dbt')(select_sql, select_sql_header)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_empty_subquery_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4969118,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_empty_subquery_sql\": {\n      \"name\": \"default__get_empty_subquery_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/columns.sql\",\n      \"original_file_path\": \"macros/adapters/columns.sql\",\n      \"unique_id\": \"macro.dbt.default__get_empty_subquery_sql\",\n      \"macro_sql\": \"{% macro default__get_empty_subquery_sql(select_sql, select_sql_header=none) %}\\n    {%- if select_sql_header is not none -%}\\n    {{ select_sql_header }}\\n    {%- endif -%}\\n    select * from (\\n        {{ select_sql }}\\n    ) as __dbt_sbq\\n    where false\\n    limit 0\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496913,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_empty_schema_sql\": {\n      \"name\": \"get_empty_schema_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/columns.sql\",\n      \"original_file_path\": \"macros/adapters/columns.sql\",\n      \"unique_id\": \"macro.dbt.get_empty_schema_sql\",\n      \"macro_sql\": \"{% macro get_empty_schema_sql(columns) -%}\\n  {{ return(adapter.dispatch('get_empty_schema_sql', 'dbt')(columns)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_empty_schema_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4969149,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_empty_schema_sql\": {\n      \"name\": \"default__get_empty_schema_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/columns.sql\",\n      \"original_file_path\": \"macros/adapters/columns.sql\",\n      \"unique_id\": \"macro.dbt.default__get_empty_schema_sql\",\n      \"macro_sql\": \"{% macro default__get_empty_schema_sql(columns) %}\\n    {%- set col_err = [] -%}\\n    {%- set col_naked_numeric = [] -%}\\n    select\\n    {% for i in columns %}\\n      {%- set col = columns[i] -%}\\n      {%- if col['data_type'] is not defined -%}\\n        {%- do col_err.append(col['name']) -%}\\n      {#-- If this column's type is just 'numeric' then it is missing precision/scale, raise a warning --#}\\n      {%- elif col['data_type'].strip().lower() in ('numeric', 'decimal', 'number') -%}\\n        {%- do col_naked_numeric.append(col['name']) -%}\\n      {%- endif -%}\\n      {% set col_name = adapter.quote(col['name']) if col.get('quote') else col['name'] %}\\n      {{ cast('null', col['data_type']) }} as {{ col_name }}{{ \\\", \\\" if not loop.last }}\\n    {%- endfor -%}\\n    {%- if (col_err | length) > 0 -%}\\n      {{ exceptions.column_type_missing(column_names=col_err) }}\\n    {%- elif (col_naked_numeric | length) > 0 -%}\\n      {{ exceptions.warn(\\\"Detected columns with numeric type and unspecified precision/scale, this can lead to unintended rounding: \\\" ~ col_naked_numeric ~ \\\"`\\\") }}\\n    {%- endif -%}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.cast\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4969249,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_column_schema_from_query\": {\n      \"name\": \"get_column_schema_from_query\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/columns.sql\",\n      \"original_file_path\": \"macros/adapters/columns.sql\",\n      \"unique_id\": \"macro.dbt.get_column_schema_from_query\",\n      \"macro_sql\": \"{% macro get_column_schema_from_query(select_sql, select_sql_header=none) -%}\\n    {% set columns = [] %}\\n    {# -- Using an 'empty subquery' here to get the same schema as the given select_sql statement, without necessitating a data scan.#}\\n    {% set sql = get_empty_subquery_sql(select_sql, select_sql_header) %}\\n    {% set column_schema = adapter.get_column_schema_from_query(sql) %}\\n    {{ return(column_schema) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.get_empty_subquery_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496927,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_columns_in_query\": {\n      \"name\": \"get_columns_in_query\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/columns.sql\",\n      \"original_file_path\": \"macros/adapters/columns.sql\",\n      \"unique_id\": \"macro.dbt.get_columns_in_query\",\n      \"macro_sql\": \"{% macro get_columns_in_query(select_sql) -%}\\n  {{ return(adapter.dispatch('get_columns_in_query', 'dbt')(select_sql)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__get_columns_in_query\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496929,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__get_columns_in_query\": {\n      \"name\": \"default__get_columns_in_query\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/columns.sql\",\n      \"original_file_path\": \"macros/adapters/columns.sql\",\n      \"unique_id\": \"macro.dbt.default__get_columns_in_query\",\n      \"macro_sql\": \"{% macro default__get_columns_in_query(select_sql) %}\\n    {% call statement('get_columns_in_query', fetch_result=True, auto_begin=False) -%}\\n        {{ get_empty_subquery_sql(select_sql) }}\\n    {% endcall %}\\n    {{ return(load_result('get_columns_in_query').table.columns | map(attribute='name') | list) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.statement\",\n          \"macro.dbt.get_empty_subquery_sql\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496932,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.alter_column_type\": {\n      \"name\": \"alter_column_type\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/columns.sql\",\n      \"original_file_path\": \"macros/adapters/columns.sql\",\n      \"unique_id\": \"macro.dbt.alter_column_type\",\n      \"macro_sql\": \"{% macro alter_column_type(relation, column_name, new_column_type) -%}\\n  {{ return(adapter.dispatch('alter_column_type', 'dbt')(relation, column_name, new_column_type)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__alter_column_type\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496935,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__alter_column_type\": {\n      \"name\": \"default__alter_column_type\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/columns.sql\",\n      \"original_file_path\": \"macros/adapters/columns.sql\",\n      \"unique_id\": \"macro.dbt.default__alter_column_type\",\n      \"macro_sql\": \"{% macro default__alter_column_type(relation, column_name, new_column_type) -%}\\n  {#\\n    1. Create a new column (w/ temp name and correct type)\\n    2. Copy data over to it\\n    3. Drop the existing column (cascade!)\\n    4. Rename the new column to existing column\\n  #}\\n  {%- set tmp_column = column_name + \\\"__dbt_alter\\\" -%}\\n\\n  {% call statement('alter_column_type') %}\\n    alter table {{ relation.render() }} add column {{ adapter.quote(tmp_column) }} {{ new_column_type }};\\n    update {{ relation.render() }} set {{ adapter.quote(tmp_column) }} = {{ adapter.quote(column_name) }};\\n    alter table {{ relation.render() }} drop column {{ adapter.quote(column_name) }} cascade;\\n    alter table {{ relation.render() }} rename column {{ adapter.quote(tmp_column) }} to {{ adapter.quote(column_name) }}\\n  {% endcall %}\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.statement\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496942,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.alter_relation_add_remove_columns\": {\n      \"name\": \"alter_relation_add_remove_columns\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/columns.sql\",\n      \"original_file_path\": \"macros/adapters/columns.sql\",\n      \"unique_id\": \"macro.dbt.alter_relation_add_remove_columns\",\n      \"macro_sql\": \"{% macro alter_relation_add_remove_columns(relation, add_columns = none, remove_columns = none) -%}\\n  {{ return(adapter.dispatch('alter_relation_add_remove_columns', 'dbt')(relation, add_columns, remove_columns)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__alter_relation_add_remove_columns\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4969442,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__alter_relation_add_remove_columns\": {\n      \"name\": \"default__alter_relation_add_remove_columns\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/adapters/columns.sql\",\n      \"original_file_path\": \"macros/adapters/columns.sql\",\n      \"unique_id\": \"macro.dbt.default__alter_relation_add_remove_columns\",\n      \"macro_sql\": \"{% macro default__alter_relation_add_remove_columns(relation, add_columns, remove_columns) %}\\n\\n  {% if add_columns is none %}\\n    {% set add_columns = [] %}\\n  {% endif %}\\n  {% if remove_columns is none %}\\n    {% set remove_columns = [] %}\\n  {% endif %}\\n\\n  {% set sql -%}\\n\\n     alter {{ relation.type }} {{ relation.render() }}\\n\\n            {% for column in add_columns %}\\n               add column {{ column.quoted }} {{ column.data_type }}{{ ',' if not loop.last }}\\n            {% endfor %}{{ ',' if add_columns and remove_columns }}\\n\\n            {% for column in remove_columns %}\\n                drop column {{ column.quoted }}{{ ',' if not loop.last }}\\n            {% endfor %}\\n\\n  {%- endset -%}\\n\\n  {% do run_query(sql) %}\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.run_query\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4969459,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_fixture_sql\": {\n      \"name\": \"get_fixture_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/unit_test_sql/get_fixture_sql.sql\",\n      \"original_file_path\": \"macros/unit_test_sql/get_fixture_sql.sql\",\n      \"unique_id\": \"macro.dbt.get_fixture_sql\",\n      \"macro_sql\": \"{% macro get_fixture_sql(rows, column_name_to_data_types) %}\\n-- Fixture for {{ model.name }}\\n{% set default_row = {} %}\\n\\n{%- if not column_name_to_data_types -%}\\n{#-- Use defer_relation IFF it is available in the manifest and 'this' is missing from the database --#}\\n{%-   set this_or_defer_relation = defer_relation if (defer_relation and not load_relation(this)) else this -%}\\n{%-   set columns_in_relation = adapter.get_columns_in_relation(this_or_defer_relation) -%}\\n\\n{%-   set column_name_to_data_types = {} -%}\\n{%-   set column_name_to_quoted = {} -%}\\n{%-   for column in columns_in_relation -%}\\n\\n{#-- This needs to be a case-insensitive comparison --#}\\n{%-     do column_name_to_data_types.update({column.name|lower: column.data_type}) -%}\\n{%-     do column_name_to_quoted.update({column.name|lower: column.quoted}) -%}\\n{%-   endfor -%}\\n{%- endif -%}\\n\\n{%- if not column_name_to_data_types -%}\\n    {{ exceptions.raise_compiler_error(\\\"Not able to get columns for unit test '\\\" ~ model.name ~ \\\"' from relation \\\" ~ this ~ \\\" because the relation doesn't exist\\\") }}\\n{%- endif -%}\\n\\n{%- for column_name, column_type in column_name_to_data_types.items() -%}\\n    {%- do default_row.update({column_name: (safe_cast(\\\"null\\\", column_type) | trim )}) -%}\\n{%- endfor -%}\\n\\n{{ validate_fixture_rows(rows, row_number) }}\\n\\n{%- for row in rows -%}\\n{%-   set formatted_row = format_row(row, column_name_to_data_types) -%}\\n{%-   set default_row_copy = default_row.copy() -%}\\n{%-   do default_row_copy.update(formatted_row) -%}\\nselect\\n{%-   for column_name, column_value in default_row_copy.items() %} {{ column_value }} as {{ column_name_to_quoted[column_name] }}{% if not loop.last -%}, {%- endif %}\\n{%-   endfor %}\\n{%-   if not loop.last %}\\nunion all\\n{%    endif %}\\n{%- endfor -%}\\n\\n{%- if (rows | length) == 0 -%}\\n    select\\n    {%- for column_name, column_value in default_row.items() %} {{ column_value }} as {{ column_name_to_quoted[column_name] }}{% if not loop.last -%},{%- endif %}\\n    {%- endfor %}\\n    limit 0\\n{%- endif -%}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.load_relation\",\n          \"macro.dbt.safe_cast\",\n          \"macro.dbt.validate_fixture_rows\",\n          \"macro.dbt.format_row\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496955,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.get_expected_sql\": {\n      \"name\": \"get_expected_sql\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/unit_test_sql/get_fixture_sql.sql\",\n      \"original_file_path\": \"macros/unit_test_sql/get_fixture_sql.sql\",\n      \"unique_id\": \"macro.dbt.get_expected_sql\",\n      \"macro_sql\": \"{% macro get_expected_sql(rows, column_name_to_data_types, column_name_to_quoted) %}\\n\\n{%- if (rows | length) == 0 -%}\\n    select * from dbt_internal_unit_test_actual\\n    limit 0\\n{%- else -%}\\n{%- for row in rows -%}\\n{%- set formatted_row = format_row(row, column_name_to_data_types) -%}\\nselect\\n{%- for column_name, column_value in formatted_row.items() %} {{ column_value }} as {{ column_name_to_quoted[column_name] }}{% if not loop.last -%}, {%- endif %}\\n{%- endfor %}\\n{%- if not loop.last %}\\nunion all\\n{% endif %}\\n{%- endfor -%}\\n{%- endif -%}\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.format_row\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4969568,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.format_row\": {\n      \"name\": \"format_row\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/unit_test_sql/get_fixture_sql.sql\",\n      \"original_file_path\": \"macros/unit_test_sql/get_fixture_sql.sql\",\n      \"unique_id\": \"macro.dbt.format_row\",\n      \"macro_sql\": \"\\n\\n{%- macro format_row(row, column_name_to_data_types) -%}\\n    {#-- generate case-insensitive formatted row --#}\\n    {% set formatted_row = {} %}\\n    {%- for column_name, column_value in row.items() -%}\\n        {% set column_name = column_name|lower %}\\n\\n        {%- if column_name not in column_name_to_data_types %}\\n            {#-- if user-provided row contains column name that relation does not contain, raise an error --#}\\n            {% set fixture_name = \\\"expected output\\\" if model.resource_type == 'unit_test' else (\\\"'\\\" ~ model.name ~ \\\"'\\\") %}\\n            {{ exceptions.raise_compiler_error(\\n                \\\"Invalid column name: '\\\" ~ column_name ~ \\\"' in unit test fixture for \\\" ~ fixture_name ~ \\\".\\\"\\n                \\\"\\\\nAccepted columns for \\\" ~ fixture_name ~ \\\" are: \\\" ~ (column_name_to_data_types.keys()|list)\\n            ) }}\\n        {%- endif -%}\\n\\n        {%- set column_type = column_name_to_data_types[column_name] %}\\n\\n        {#-- sanitize column_value: wrap yaml strings in quotes, apply cast --#}\\n        {%- set column_value_clean = column_value -%}\\n        {%- if column_value is string -%}\\n            {%- set column_value_clean = dbt.string_literal(dbt.escape_single_quotes(column_value)) -%}\\n        {%- elif column_value is none -%}\\n            {%- set column_value_clean = 'null' -%}\\n        {%- endif -%}\\n\\n        {%- set row_update = {column_name: safe_cast(column_value_clean, column_type) } -%}\\n        {%- do formatted_row.update(row_update) -%}\\n    {%- endfor -%}\\n    {{ return(formatted_row) }}\\n{%- endmacro -%}\\n\\n\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.string_literal\",\n          \"macro.dbt.escape_single_quotes\",\n          \"macro.dbt.safe_cast\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496959,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.validate_fixture_rows\": {\n      \"name\": \"validate_fixture_rows\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/unit_test_sql/get_fixture_sql.sql\",\n      \"original_file_path\": \"macros/unit_test_sql/get_fixture_sql.sql\",\n      \"unique_id\": \"macro.dbt.validate_fixture_rows\",\n      \"macro_sql\": \"{%- macro validate_fixture_rows(rows, row_number) -%}\\n  {{ return(adapter.dispatch('validate_fixture_rows', 'dbt')(rows, row_number)) }}\\n{%- endmacro -%}\\n\\n\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__validate_fixture_rows\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496963,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__validate_fixture_rows\": {\n      \"name\": \"default__validate_fixture_rows\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/unit_test_sql/get_fixture_sql.sql\",\n      \"original_file_path\": \"macros/unit_test_sql/get_fixture_sql.sql\",\n      \"unique_id\": \"macro.dbt.default__validate_fixture_rows\",\n      \"macro_sql\": \"{%- macro default__validate_fixture_rows(rows, row_number) -%}\\n  {# This is an abstract method for adapter overrides as needed #}\\n{%- endmacro -%}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4969652,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.resolve_model_name\": {\n      \"name\": \"resolve_model_name\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/python_model/python.sql\",\n      \"original_file_path\": \"macros/python_model/python.sql\",\n      \"unique_id\": \"macro.dbt.resolve_model_name\",\n      \"macro_sql\": \"{% macro resolve_model_name(input_model_name) %}\\n    {{ return(adapter.dispatch('resolve_model_name', 'dbt')(input_model_name)) }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__resolve_model_name\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496973,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.default__resolve_model_name\": {\n      \"name\": \"default__resolve_model_name\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/python_model/python.sql\",\n      \"original_file_path\": \"macros/python_model/python.sql\",\n      \"unique_id\": \"macro.dbt.default__resolve_model_name\",\n      \"macro_sql\": \"\\n\\n{%- macro default__resolve_model_name(input_model_name) -%}\\n    {{  input_model_name | string | replace('\\\"', '\\\\\\\"') }}\\n{%- endmacro -%}\\n\\n\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4969752,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.build_ref_function\": {\n      \"name\": \"build_ref_function\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/python_model/python.sql\",\n      \"original_file_path\": \"macros/python_model/python.sql\",\n      \"unique_id\": \"macro.dbt.build_ref_function\",\n      \"macro_sql\": \"{% macro build_ref_function(model) %}\\n\\n    {%- set ref_dict = {} -%}\\n    {%- for _ref in model.refs -%}\\n        {% set _ref_args = [_ref.get('package'), _ref['name']] if _ref.get('package') else [_ref['name'],] %}\\n        {%- set resolved = ref(*_ref_args, v=_ref.get('version')) -%}\\n\\n        {#\\n            We want to get the string of the returned relation by calling .render() in order to skip sample/empty\\n            mode rendering logic. However, people override the default ref macro, and often return a string instead\\n            of a relation (like the ref macro does by default). Thus, to make sure we dont blow things up, we have\\n            to ensure the resolved relation has a .render() method.\\n        #}\\n        {%- if resolved.render is defined and resolved.render is callable -%}\\n            {%- set resolved = resolved.render() -%}\\n        {%- endif -%}\\n\\n        {%- if _ref.get('version') -%}\\n            {% do _ref_args.extend([\\\"v\\\" ~ _ref['version']]) %}\\n        {%- endif -%}\\n       {%- do ref_dict.update({_ref_args | join('.'): resolve_model_name(resolved)}) -%}\\n    {%- endfor -%}\\n\\ndef ref(*args, **kwargs):\\n    refs = {{ ref_dict | tojson }}\\n    key = '.'.join(args)\\n    version = kwargs.get(\\\"v\\\") or kwargs.get(\\\"version\\\")\\n    if version:\\n        key += f\\\".v{version}\\\"\\n    dbt_load_df_function = kwargs.get(\\\"dbt_load_df_function\\\")\\n    return dbt_load_df_function(refs[key])\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.resolve_model_name\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4969778,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.build_source_function\": {\n      \"name\": \"build_source_function\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/python_model/python.sql\",\n      \"original_file_path\": \"macros/python_model/python.sql\",\n      \"unique_id\": \"macro.dbt.build_source_function\",\n      \"macro_sql\": \"{% macro build_source_function(model) %}\\n\\n    {%- set source_dict = {} -%}\\n    {%- for _source in model.sources -%}\\n        {%- set resolved = source(*_source) -%}\\n        {%- do source_dict.update({_source | join('.'): resolve_model_name(resolved)}) -%}\\n    {%- endfor -%}\\n\\ndef source(*args, dbt_load_df_function):\\n    sources = {{ source_dict | tojson }}\\n    key = '.'.join(args)\\n    return dbt_load_df_function(sources[key])\\n\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.resolve_model_name\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.49698,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.build_config_dict\": {\n      \"name\": \"build_config_dict\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/python_model/python.sql\",\n      \"original_file_path\": \"macros/python_model/python.sql\",\n      \"unique_id\": \"macro.dbt.build_config_dict\",\n      \"macro_sql\": \"{% macro build_config_dict(model) %}\\n    {%- set config_dict = {} -%}\\n    {% set config_dbt_used = zip(model.config.config_keys_used, model.config.config_keys_defaults) | list %}\\n    {%- for key, default in config_dbt_used -%}\\n        {# weird type testing with enum, would be much easier to write this logic in Python! #}\\n        {%- if key == \\\"language\\\" -%}\\n          {%- set value = \\\"python\\\" -%}\\n        {%- endif -%}\\n        {%- set value = model.config.get(key, default) -%}\\n        {%- do config_dict.update({key: value}) -%}\\n    {%- endfor -%}\\nconfig_dict = {{ config_dict }}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496982,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.py_script_postfix\": {\n      \"name\": \"py_script_postfix\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/python_model/python.sql\",\n      \"original_file_path\": \"macros/python_model/python.sql\",\n      \"unique_id\": \"macro.dbt.py_script_postfix\",\n      \"macro_sql\": \"{% macro py_script_postfix(model) %}\\n# This part is user provided model code\\n# you will need to copy the next section to run the code\\n# COMMAND ----------\\n# this part is dbt logic for get ref work, do not modify\\n\\n{{ build_ref_function(model ) }}\\n{{ build_source_function(model ) }}\\n{{ build_config_dict(model) }}\\n\\nclass config:\\n    def __init__(self, *args, **kwargs):\\n        pass\\n\\n    @staticmethod\\n    def get(key, default=None):\\n        return config_dict.get(key, default)\\n\\nclass this:\\n    \\\"\\\"\\\"dbt.this() or dbt.this.identifier\\\"\\\"\\\"\\n    database = \\\"{{ this.database }}\\\"\\n    schema = \\\"{{ this.schema }}\\\"\\n    identifier = \\\"{{ this.identifier }}\\\"\\n    {% set this_relation_name = resolve_model_name(this) %}\\n    def __repr__(self):\\n        return '{{ this_relation_name  }}'\\n\\n\\nclass dbtObj:\\n    def __init__(self, load_df_function) -> None:\\n        self.source = lambda *args: source(*args, dbt_load_df_function=load_df_function)\\n        self.ref = lambda *args, **kwargs: ref(*args, **kwargs, dbt_load_df_function=load_df_function)\\n        self.config = config\\n        self.this = this()\\n        self.is_incremental = {{ is_incremental() }}\\n\\n# COMMAND ----------\\n{{py_script_comment()}}\\n{% endmacro %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.build_ref_function\",\n          \"macro.dbt.build_source_function\",\n          \"macro.dbt.build_config_dict\",\n          \"macro.dbt.resolve_model_name\",\n          \"macro.dbt.is_incremental\",\n          \"macro.dbt.py_script_comment\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.496984,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.py_script_comment\": {\n      \"name\": \"py_script_comment\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"macros/python_model/python.sql\",\n      \"original_file_path\": \"macros/python_model/python.sql\",\n      \"unique_id\": \"macro.dbt.py_script_comment\",\n      \"macro_sql\": \"{%macro py_script_comment()%}\\n{%endmacro%}\",\n      \"depends_on\": {\n        \"macros\": []\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4969862,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.test_unique\": {\n      \"name\": \"test_unique\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"tests/generic/builtin.sql\",\n      \"original_file_path\": \"tests/generic/builtin.sql\",\n      \"unique_id\": \"macro.dbt.test_unique\",\n      \"macro_sql\": \"{% test unique(model, column_name) %}\\n    {% set macro = adapter.dispatch('test_unique', 'dbt') %}\\n    {{ macro(model, column_name) }}\\n{% endtest %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__test_unique\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.4973178,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.test_not_null\": {\n      \"name\": \"test_not_null\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"tests/generic/builtin.sql\",\n      \"original_file_path\": \"tests/generic/builtin.sql\",\n      \"unique_id\": \"macro.dbt.test_not_null\",\n      \"macro_sql\": \"{% test not_null(model, column_name) %}\\n    {% set macro = adapter.dispatch('test_not_null', 'dbt') %}\\n    {{ macro(model, column_name) }}\\n{% endtest %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__test_not_null\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.497498,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.test_accepted_values\": {\n      \"name\": \"test_accepted_values\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"tests/generic/builtin.sql\",\n      \"original_file_path\": \"tests/generic/builtin.sql\",\n      \"unique_id\": \"macro.dbt.test_accepted_values\",\n      \"macro_sql\": \"{% test accepted_values(model, column_name, values, quote=True) %}\\n    {% set macro = adapter.dispatch('test_accepted_values', 'dbt') %}\\n    {{ macro(model, column_name, values, quote) }}\\n{% endtest %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__test_accepted_values\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.497705,\n      \"supported_languages\": null\n    },\n    \"macro.dbt.test_relationships\": {\n      \"name\": \"test_relationships\",\n      \"resource_type\": \"macro\",\n      \"package_name\": \"dbt\",\n      \"path\": \"tests/generic/builtin.sql\",\n      \"original_file_path\": \"tests/generic/builtin.sql\",\n      \"unique_id\": \"macro.dbt.test_relationships\",\n      \"macro_sql\": \"{% test relationships(model, column_name, to, field) %}\\n    {% set macro = adapter.dispatch('test_relationships', 'dbt') %}\\n    {{ macro(model, column_name, to, field) }}\\n{% endtest %}\",\n      \"depends_on\": {\n        \"macros\": [\n          \"macro.dbt.default__test_relationships\"\n        ]\n      },\n      \"description\": \"\",\n      \"meta\": {},\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": null,\n      \"arguments\": [],\n      \"created_at\": 1763574305.497903,\n      \"supported_languages\": null\n    }\n  },\n  \"docs\": {\n    \"doc.test.my_docs\": {\n      \"name\": \"my_docs\",\n      \"resource_type\": \"doc\",\n      \"package_name\": \"test\",\n      \"path\": \"docs.md\",\n      \"original_file_path\": \"models/docs.md\",\n      \"unique_id\": \"doc.test.my_docs\",\n      \"block_contents\": \"some docs\"\n    },\n    \"doc.dbt.__overview__\": {\n      \"name\": \"__overview__\",\n      \"resource_type\": \"doc\",\n      \"package_name\": \"dbt\",\n      \"path\": \"overview.md\",\n      \"original_file_path\": \"docs/overview.md\",\n      \"unique_id\": \"doc.dbt.__overview__\",\n      \"block_contents\": \"### Welcome!\\n\\nWelcome to the auto-generated documentation for your dbt project!\\n\\n### Navigation\\n\\nYou can use the `Project` and `Database` navigation tabs on the left side of the window to explore the models\\nin your project.\\n\\n#### Project Tab\\nThe `Project` tab mirrors the directory structure of your dbt project. In this tab, you can see all of the\\nmodels defined in your dbt project, as well as models imported from dbt packages.\\n\\n#### Database Tab\\nThe `Database` tab also exposes your models, but in a format that looks more like a database explorer. This view\\nshows relations (tables and views) grouped into database schemas. Note that ephemeral models are _not_ shown\\nin this interface, as they do not exist in the database.\\n\\n### Graph Exploration\\nYou can click the blue icon on the bottom-right corner of the page to view the lineage graph of your models.\\n\\nOn model pages, you'll see the immediate parents and children of the model you're exploring. By clicking the `Expand`\\nbutton at the top-right of this lineage pane, you'll be able to see all of the models that are used to build,\\nor are built from, the model you're exploring.\\n\\nOnce expanded, you'll be able to use the `--select` and `--exclude` model selection syntax to filter the\\nmodels in the graph. For more information on model selection, check out the [dbt docs](https://docs.getdbt.com/docs/model-selection-syntax).\\n\\nNote that you can also right-click on models to interactively filter and explore the graph.\\n\\n---\\n\\n### More information\\n\\n- [What is dbt](https://docs.getdbt.com/docs/introduction)?\\n- Read the [dbt viewpoint](https://docs.getdbt.com/docs/viewpoint)\\n- [Installation](https://docs.getdbt.com/docs/installation)\\n- Join the [dbt Community](https://www.getdbt.com/community/) for questions and discussion\"\n    }\n  },\n  \"exposures\": {\n    \"exposure.test.weekly_jaffle_metrics\": {\n      \"name\": \"weekly_jaffle_metrics\",\n      \"resource_type\": \"exposure\",\n      \"package_name\": \"test\",\n      \"path\": \"e.yml\",\n      \"original_file_path\": \"models/e.yml\",\n      \"unique_id\": \"exposure.test.weekly_jaffle_metrics\",\n      \"fqn\": [\n        \"test\",\n        \"weekly_jaffle_metrics\"\n      ],\n      \"type\": \"dashboard\",\n      \"owner\": {\n        \"email\": \"data@jaffleshop.com\",\n        \"name\": \"Callum McData\"\n      },\n      \"description\": \"Did someone say \\\"exponential growth\\\"?\\n\",\n      \"label\": \"Jaffles by the Week\",\n      \"maturity\": \"high\",\n      \"meta\": {},\n      \"tags\": [\n        \"tag\"\n      ],\n      \"config\": {\n        \"enabled\": true,\n        \"tags\": [\n          \"tag\"\n        ],\n        \"meta\": {}\n      },\n      \"unrendered_config\": {\n        \"enabled\": true,\n        \"meta\": {},\n        \"tags\": [\n          \"tag\"\n        ]\n      },\n      \"url\": \"https://bi.tool/dashboards/1\",\n      \"depends_on\": {\n        \"macros\": [],\n        \"nodes\": [\n          \"model.test.incremental\"\n        ]\n      },\n      \"refs\": [\n        {\n          \"name\": \"incremental\",\n          \"package\": null,\n          \"version\": null\n        }\n      ],\n      \"sources\": [],\n      \"metrics\": [],\n      \"created_at\": 1763574306.332556\n    }\n  },\n  \"metrics\": {\n    \"metric.test.discrete_order_value_p99\": {\n      \"name\": \"discrete_order_value_p99\",\n      \"resource_type\": \"metric\",\n      \"package_name\": \"test\",\n      \"path\": \"sm.yml\",\n      \"original_file_path\": \"models/sm.yml\",\n      \"unique_id\": \"metric.test.discrete_order_value_p99\",\n      \"fqn\": [\n        \"test\",\n        \"discrete_order_value_p99\"\n      ],\n      \"description\": \"Metric created from measure discrete_order_value_p99\",\n      \"label\": \"discrete_order_value_p99\",\n      \"type\": \"simple\",\n      \"type_params\": {\n        \"measure\": {\n          \"name\": \"discrete_order_value_p99\",\n          \"filter\": null,\n          \"alias\": null,\n          \"join_to_timespine\": false,\n          \"fill_nulls_with\": null\n        },\n        \"input_measures\": [\n          {\n            \"name\": \"discrete_order_value_p99\",\n            \"filter\": null,\n            \"alias\": null,\n            \"join_to_timespine\": false,\n            \"fill_nulls_with\": null\n          }\n        ],\n        \"numerator\": null,\n        \"denominator\": null,\n        \"expr\": \"order_total\",\n        \"window\": null,\n        \"grain_to_date\": null,\n        \"metrics\": [],\n        \"conversion_type_params\": null,\n        \"cumulative_type_params\": null,\n        \"metric_aggregation_params\": null\n      },\n      \"filter\": null,\n      \"metadata\": null,\n      \"time_granularity\": null,\n      \"meta\": {},\n      \"tags\": [],\n      \"config\": {\n        \"enabled\": true,\n        \"group\": null,\n        \"meta\": {}\n      },\n      \"unrendered_config\": {\n        \"enabled\": true,\n        \"meta\": {}\n      },\n      \"sources\": [],\n      \"depends_on\": {\n        \"macros\": [],\n        \"nodes\": [\n          \"semantic_model.test.my_sm\"\n        ]\n      },\n      \"refs\": [],\n      \"metrics\": [],\n      \"created_at\": 1763574306.37896,\n      \"group\": null\n    },\n    \"metric.test.total_outer\": {\n      \"name\": \"total_outer\",\n      \"resource_type\": \"metric\",\n      \"package_name\": \"test\",\n      \"path\": \"m.yml\",\n      \"original_file_path\": \"models/m.yml\",\n      \"unique_id\": \"metric.test.total_outer\",\n      \"fqn\": [\n        \"test\",\n        \"total_outer\"\n      ],\n      \"description\": \"The total count of outer\",\n      \"label\": \"Total Outer\",\n      \"type\": \"simple\",\n      \"type_params\": {\n        \"measure\": {\n          \"name\": \"total_outer_count\",\n          \"filter\": null,\n          \"alias\": null,\n          \"join_to_timespine\": false,\n          \"fill_nulls_with\": null\n        },\n        \"input_measures\": [\n          {\n            \"name\": \"total_outer_count\",\n            \"filter\": null,\n            \"alias\": null,\n            \"join_to_timespine\": false,\n            \"fill_nulls_with\": null\n          }\n        ],\n        \"numerator\": null,\n        \"denominator\": null,\n        \"expr\": null,\n        \"window\": null,\n        \"grain_to_date\": null,\n        \"metrics\": [],\n        \"conversion_type_params\": null,\n        \"cumulative_type_params\": null,\n        \"metric_aggregation_params\": null\n      },\n      \"filter\": null,\n      \"metadata\": null,\n      \"time_granularity\": \"month\",\n      \"meta\": {},\n      \"tags\": [],\n      \"config\": {\n        \"enabled\": true,\n        \"group\": null,\n        \"meta\": {}\n      },\n      \"unrendered_config\": {},\n      \"sources\": [],\n      \"depends_on\": {\n        \"macros\": [],\n        \"nodes\": [\n          \"semantic_model.test.my_sm\"\n        ]\n      },\n      \"refs\": [],\n      \"metrics\": [],\n      \"created_at\": 1763574306.423567,\n      \"group\": null\n    },\n    \"metric.test.simple_ratio_metric\": {\n      \"name\": \"simple_ratio_metric\",\n      \"resource_type\": \"metric\",\n      \"package_name\": \"test\",\n      \"path\": \"m.yml\",\n      \"original_file_path\": \"models/m.yml\",\n      \"unique_id\": \"metric.test.simple_ratio_metric\",\n      \"fqn\": [\n        \"test\",\n        \"simple_ratio_metric\"\n      ],\n      \"description\": \"a simple ratio metric\",\n      \"label\": \"Simple Ratio Metric\",\n      \"type\": \"ratio\",\n      \"type_params\": {\n        \"measure\": null,\n        \"input_measures\": [\n          {\n            \"name\": \"total_outer_count\",\n            \"filter\": null,\n            \"alias\": null,\n            \"join_to_timespine\": false,\n            \"fill_nulls_with\": null\n          }\n        ],\n        \"numerator\": {\n          \"name\": \"total_outer\",\n          \"filter\": null,\n          \"alias\": null,\n          \"offset_window\": null,\n          \"offset_to_grain\": null\n        },\n        \"denominator\": {\n          \"name\": \"total_outer\",\n          \"filter\": null,\n          \"alias\": \"filtered_total_outer\",\n          \"offset_window\": null,\n          \"offset_to_grain\": null\n        },\n        \"expr\": null,\n        \"window\": null,\n        \"grain_to_date\": null,\n        \"metrics\": [],\n        \"conversion_type_params\": null,\n        \"cumulative_type_params\": null,\n        \"metric_aggregation_params\": null\n      },\n      \"filter\": null,\n      \"metadata\": null,\n      \"time_granularity\": null,\n      \"meta\": {},\n      \"tags\": [],\n      \"config\": {\n        \"enabled\": true,\n        \"group\": null,\n        \"meta\": {}\n      },\n      \"unrendered_config\": {},\n      \"sources\": [],\n      \"depends_on\": {\n        \"macros\": [],\n        \"nodes\": [\n          \"metric.test.total_outer\"\n        ]\n      },\n      \"refs\": [],\n      \"metrics\": [],\n      \"created_at\": 1763574306.42508,\n      \"group\": null\n    },\n    \"metric.test.filtered_ratio_metric\": {\n      \"name\": \"filtered_ratio_metric\",\n      \"resource_type\": \"metric\",\n      \"package_name\": \"test\",\n      \"path\": \"m.yml\",\n      \"original_file_path\": \"models/m.yml\",\n      \"unique_id\": \"metric.test.filtered_ratio_metric\",\n      \"fqn\": [\n        \"test\",\n        \"filtered_ratio_metric\"\n      ],\n      \"description\": \"a ratio metric\",\n      \"label\": \"Ratio Metric 2\",\n      \"type\": \"ratio\",\n      \"type_params\": {\n        \"measure\": null,\n        \"input_measures\": [\n          {\n            \"name\": \"total_outer_count\",\n            \"filter\": null,\n            \"alias\": null,\n            \"join_to_timespine\": false,\n            \"fill_nulls_with\": null\n          }\n        ],\n        \"numerator\": {\n          \"name\": \"total_outer\",\n          \"filter\": {\n            \"where_filters\": [\n              {\n                \"where_sql_template\": \"1 = 1\"\n              }\n            ]\n          },\n          \"alias\": null,\n          \"offset_window\": null,\n          \"offset_to_grain\": null\n        },\n        \"denominator\": {\n          \"name\": \"total_outer\",\n          \"filter\": {\n            \"where_filters\": [\n              {\n                \"where_sql_template\": \"1 = 1\"\n              },\n              {\n                \"where_sql_template\": \"2 = 2\"\n              }\n            ]\n          },\n          \"alias\": \"filtered_total_outer_again\",\n          \"offset_window\": null,\n          \"offset_to_grain\": null\n        },\n        \"expr\": null,\n        \"window\": null,\n        \"grain_to_date\": null,\n        \"metrics\": [],\n        \"conversion_type_params\": null,\n        \"cumulative_type_params\": null,\n        \"metric_aggregation_params\": null\n      },\n      \"filter\": null,\n      \"metadata\": null,\n      \"time_granularity\": null,\n      \"meta\": {},\n      \"tags\": [],\n      \"config\": {\n        \"enabled\": true,\n        \"group\": null,\n        \"meta\": {}\n      },\n      \"unrendered_config\": {},\n      \"sources\": [],\n      \"depends_on\": {\n        \"macros\": [],\n        \"nodes\": [\n          \"metric.test.total_outer\"\n        ]\n      },\n      \"refs\": [],\n      \"metrics\": [],\n      \"created_at\": 1763574306.425653,\n      \"group\": null\n    },\n    \"metric.test.cumulative_metric\": {\n      \"name\": \"cumulative_metric\",\n      \"resource_type\": \"metric\",\n      \"package_name\": \"test\",\n      \"path\": \"m.yml\",\n      \"original_file_path\": \"models/m.yml\",\n      \"unique_id\": \"metric.test.cumulative_metric\",\n      \"fqn\": [\n        \"test\",\n        \"cumulative_metric\"\n      ],\n      \"description\": \"a cumulative metric\",\n      \"label\": \"Cumulative Metric\",\n      \"type\": \"cumulative\",\n      \"type_params\": {\n        \"measure\": {\n          \"name\": \"total_outer_count\",\n          \"filter\": {\n            \"where_filters\": [\n              {\n                \"where_sql_template\": \"1 = 1\"\n              }\n            ]\n          },\n          \"alias\": \"filtered_total_outer_count\",\n          \"join_to_timespine\": false,\n          \"fill_nulls_with\": 0\n        },\n        \"input_measures\": [\n          {\n            \"name\": \"total_outer_count\",\n            \"filter\": {\n              \"where_filters\": [\n                {\n                  \"where_sql_template\": \"1 = 1\"\n                }\n              ]\n            },\n            \"alias\": \"filtered_total_outer_count\",\n            \"join_to_timespine\": false,\n            \"fill_nulls_with\": 0\n          }\n        ],\n        \"numerator\": null,\n        \"denominator\": null,\n        \"expr\": null,\n        \"window\": null,\n        \"grain_to_date\": null,\n        \"metrics\": [],\n        \"conversion_type_params\": null,\n        \"cumulative_type_params\": {\n          \"window\": null,\n          \"grain_to_date\": \"day\",\n          \"period_agg\": \"first\",\n          \"metric\": null\n        },\n        \"metric_aggregation_params\": null\n      },\n      \"filter\": null,\n      \"metadata\": null,\n      \"time_granularity\": null,\n      \"meta\": {},\n      \"tags\": [],\n      \"config\": {\n        \"enabled\": true,\n        \"group\": null,\n        \"meta\": {}\n      },\n      \"unrendered_config\": {},\n      \"sources\": [],\n      \"depends_on\": {\n        \"macros\": [],\n        \"nodes\": [\n          \"semantic_model.test.my_sm\"\n        ]\n      },\n      \"refs\": [],\n      \"metrics\": [],\n      \"created_at\": 1763574306.426938,\n      \"group\": null\n    },\n    \"metric.test.cumulative_metric_2\": {\n      \"name\": \"cumulative_metric_2\",\n      \"resource_type\": \"metric\",\n      \"package_name\": \"test\",\n      \"path\": \"m.yml\",\n      \"original_file_path\": \"models/m.yml\",\n      \"unique_id\": \"metric.test.cumulative_metric_2\",\n      \"fqn\": [\n        \"test\",\n        \"cumulative_metric_2\"\n      ],\n      \"description\": \"a cumulative metric\",\n      \"label\": \"Cumulative Metric 2\",\n      \"type\": \"cumulative\",\n      \"type_params\": {\n        \"measure\": {\n          \"name\": \"total_outer_count\",\n          \"filter\": {\n            \"where_filters\": [\n              {\n                \"where_sql_template\": \"1 = 1\"\n              }\n            ]\n          },\n          \"alias\": \"filtered_total_outer_count_2\",\n          \"join_to_timespine\": false,\n          \"fill_nulls_with\": 0\n        },\n        \"input_measures\": [\n          {\n            \"name\": \"total_outer_count\",\n            \"filter\": {\n              \"where_filters\": [\n                {\n                  \"where_sql_template\": \"1 = 1\"\n                }\n              ]\n            },\n            \"alias\": \"filtered_total_outer_count_2\",\n            \"join_to_timespine\": false,\n            \"fill_nulls_with\": 0\n          }\n        ],\n        \"numerator\": null,\n        \"denominator\": null,\n        \"expr\": null,\n        \"window\": null,\n        \"grain_to_date\": null,\n        \"metrics\": [],\n        \"conversion_type_params\": null,\n        \"cumulative_type_params\": {\n          \"window\": {\n            \"count\": 1,\n            \"granularity\": \"day\"\n          },\n          \"grain_to_date\": null,\n          \"period_agg\": \"first\",\n          \"metric\": null\n        },\n        \"metric_aggregation_params\": null\n      },\n      \"filter\": null,\n      \"metadata\": null,\n      \"time_granularity\": null,\n      \"meta\": {},\n      \"tags\": [],\n      \"config\": {\n        \"enabled\": true,\n        \"group\": null,\n        \"meta\": {}\n      },\n      \"unrendered_config\": {},\n      \"sources\": [],\n      \"depends_on\": {\n        \"macros\": [],\n        \"nodes\": [\n          \"semantic_model.test.my_sm\"\n        ]\n      },\n      \"refs\": [],\n      \"metrics\": [],\n      \"created_at\": 1763574306.4276102,\n      \"group\": null\n    },\n    \"metric.test.conversion_metric\": {\n      \"name\": \"conversion_metric\",\n      \"resource_type\": \"metric\",\n      \"package_name\": \"test\",\n      \"path\": \"m.yml\",\n      \"original_file_path\": \"models/m.yml\",\n      \"unique_id\": \"metric.test.conversion_metric\",\n      \"fqn\": [\n        \"test\",\n        \"conversion_metric\"\n      ],\n      \"description\": \"a conversion metric\",\n      \"label\": \"Conversion Metric\",\n      \"type\": \"conversion\",\n      \"type_params\": {\n        \"measure\": null,\n        \"input_measures\": [\n          {\n            \"name\": \"total_outer_count\",\n            \"filter\": null,\n            \"alias\": null,\n            \"join_to_timespine\": false,\n            \"fill_nulls_with\": null\n          },\n          {\n            \"name\": \"total_outer_count\",\n            \"filter\": null,\n            \"alias\": null,\n            \"join_to_timespine\": false,\n            \"fill_nulls_with\": 0\n          }\n        ],\n        \"numerator\": null,\n        \"denominator\": null,\n        \"expr\": null,\n        \"window\": null,\n        \"grain_to_date\": null,\n        \"metrics\": [],\n        \"conversion_type_params\": {\n          \"base_measure\": {\n            \"name\": \"total_outer_count\",\n            \"filter\": null,\n            \"alias\": null,\n            \"join_to_timespine\": false,\n            \"fill_nulls_with\": null\n          },\n          \"conversion_measure\": {\n            \"name\": \"total_outer_count\",\n            \"filter\": null,\n            \"alias\": null,\n            \"join_to_timespine\": false,\n            \"fill_nulls_with\": 0\n          },\n          \"entity\": \"my_entity\",\n          \"calculation\": \"conversion_rate\",\n          \"window\": {\n            \"count\": 1,\n            \"granularity\": \"day\"\n          },\n          \"constant_properties\": [\n            {\n              \"base_property\": \"my_entity\",\n              \"conversion_property\": \"created_at\"\n            }\n          ]\n        },\n        \"cumulative_type_params\": null,\n        \"metric_aggregation_params\": null\n      },\n      \"filter\": null,\n      \"metadata\": null,\n      \"time_granularity\": null,\n      \"meta\": {},\n      \"tags\": [],\n      \"config\": {\n        \"enabled\": true,\n        \"group\": null,\n        \"meta\": {}\n      },\n      \"unrendered_config\": {},\n      \"sources\": [],\n      \"depends_on\": {\n        \"macros\": [],\n        \"nodes\": [\n          \"semantic_model.test.my_sm\"\n        ]\n      },\n      \"refs\": [],\n      \"metrics\": [],\n      \"created_at\": 1763574306.429516,\n      \"group\": null\n    },\n    \"metric.test.derived_metric\": {\n      \"name\": \"derived_metric\",\n      \"resource_type\": \"metric\",\n      \"package_name\": \"test\",\n      \"path\": \"m.yml\",\n      \"original_file_path\": \"models/m.yml\",\n      \"unique_id\": \"metric.test.derived_metric\",\n      \"fqn\": [\n        \"test\",\n        \"derived_metric\"\n      ],\n      \"description\": \"a derived metric\",\n      \"label\": \"Derived Metric\",\n      \"type\": \"derived\",\n      \"type_params\": {\n        \"measure\": null,\n        \"input_measures\": [\n          {\n            \"name\": \"total_outer_count\",\n            \"filter\": null,\n            \"alias\": null,\n            \"join_to_timespine\": false,\n            \"fill_nulls_with\": null\n          },\n          {\n            \"name\": \"total_outer_count\",\n            \"filter\": null,\n            \"alias\": null,\n            \"join_to_timespine\": false,\n            \"fill_nulls_with\": 0\n          }\n        ],\n        \"numerator\": null,\n        \"denominator\": null,\n        \"expr\": \"srm - cm + filtered_ratio_metric\",\n        \"window\": null,\n        \"grain_to_date\": null,\n        \"metrics\": [\n          {\n            \"name\": \"simple_ratio_metric\",\n            \"filter\": {\n              \"where_filters\": [\n                {\n                  \"where_sql_template\": \"1 = 1\"\n                }\n              ]\n            },\n            \"alias\": \"srm\",\n            \"offset_window\": {\n              \"count\": 1,\n              \"granularity\": \"month\"\n            },\n            \"offset_to_grain\": null\n          },\n          {\n            \"name\": \"conversion_metric\",\n            \"filter\": null,\n            \"alias\": \"cm\",\n            \"offset_window\": null,\n            \"offset_to_grain\": \"month\"\n          },\n          {\n            \"name\": \"filtered_ratio_metric\",\n            \"filter\": null,\n            \"alias\": null,\n            \"offset_window\": null,\n            \"offset_to_grain\": null\n          }\n        ],\n        \"conversion_type_params\": null,\n        \"cumulative_type_params\": null,\n        \"metric_aggregation_params\": null\n      },\n      \"filter\": null,\n      \"metadata\": null,\n      \"time_granularity\": null,\n      \"meta\": {},\n      \"tags\": [],\n      \"config\": {\n        \"enabled\": true,\n        \"group\": null,\n        \"meta\": {}\n      },\n      \"unrendered_config\": {},\n      \"sources\": [],\n      \"depends_on\": {\n        \"macros\": [],\n        \"nodes\": [\n          \"metric.test.simple_ratio_metric\",\n          \"metric.test.conversion_metric\",\n          \"metric.test.filtered_ratio_metric\"\n        ]\n      },\n      \"refs\": [],\n      \"metrics\": [],\n      \"created_at\": 1763574306.430549,\n      \"group\": null\n    }\n  },\n  \"groups\": {\n    \"group.test.finance\": {\n      \"name\": \"finance\",\n      \"resource_type\": \"group\",\n      \"package_name\": \"test\",\n      \"path\": \"g.yml\",\n      \"original_file_path\": \"models/g.yml\",\n      \"unique_id\": \"group.test.finance\",\n      \"owner\": {\n        \"email\": \"finance@jaffleshop.com\",\n        \"name\": null\n      },\n      \"description\": \"description\",\n      \"config\": {\n        \"meta\": {\n          \"custom_field\": \"value\"\n        },\n        \"enabled\": true\n      }\n    },\n    \"group.test.important_tests\": {\n      \"name\": \"important_tests\",\n      \"resource_type\": \"group\",\n      \"package_name\": \"test\",\n      \"path\": \"schema.yml\",\n      \"original_file_path\": \"tests/schema.yml\",\n      \"unique_id\": \"group.test.important_tests\",\n      \"owner\": {\n        \"email\": \"data@example.com\",\n        \"name\": null\n      },\n      \"description\": null,\n      \"config\": {\n        \"meta\": {},\n        \"enabled\": true\n      }\n    }\n  },\n  \"selectors\": {},\n  \"disabled\": {},\n  \"parent_map\": {\n    \"model.test.model_with_lots_of_schema_configs\": [\n      \"model.test.ephemeral\",\n      \"source.test.my_source.my_table\"\n    ],\n    \"model.test.snapshot_source\": [],\n    \"model.test.ephemeral\": [],\n    \"model.test.metricflow_time_spine\": [],\n    \"model.test.incremental\": [\n      \"seed.test.seed\"\n    ],\n    \"model.test.model_to_unit_test\": [\n      \"seed.test.seed\"\n    ],\n    \"model.test.outer\": [\n      \"model.test.ephemeral\"\n    ],\n    \"model.test.metricflow_time_spine_second\": [],\n    \"model.test.inner\": [\n      \"model.test.outer\"\n    ],\n    \"snapshot.test.my_snapshot\": [],\n    \"analysis.test.a\": [],\n    \"test.test.t\": [],\n    \"seed.test.seed\": [],\n    \"test.test.not_null_seed__a_.6b59640cde\": [\n      \"seed.test.seed\"\n    ],\n    \"test.test.not_null_seed__b_.a088b263cb\": [\n      \"seed.test.seed\"\n    ],\n    \"test.test.expression_is_true_seed_b_2.4e0babbea4\": [\n      \"seed.test.seed\"\n    ],\n    \"test.test.unique_outer_id.2195e332d3\": [\n      \"model.test.outer\"\n    ],\n    \"test.test.not_null_outer_id.a226f4fb36\": [\n      \"model.test.outer\"\n    ],\n    \"test.test.unique_model_with_lots_of_schema_configs_id.8328d84982\": [\n      \"model.test.model_with_lots_of_schema_configs\"\n    ],\n    \"test.test.my_favorite_test.b488d63233\": [\n      \"model.test.model_with_lots_of_schema_configs\"\n    ],\n    \"test.test.my_second_favorite_test.c8955109ad\": [\n      \"model.test.model_with_lots_of_schema_configs\"\n    ],\n    \"snapshot.test.snapshot_2\": [\n      \"model.test.snapshot_source\"\n    ],\n    \"snapshot.test.snapshot_3\": [\n      \"model.test.snapshot_source\"\n    ],\n    \"source.test.my_source.my_table\": [],\n    \"exposure.test.weekly_jaffle_metrics\": [\n      \"model.test.incremental\"\n    ],\n    \"function.test.area_of_circle\": [],\n    \"metric.test.discrete_order_value_p99\": [\n      \"semantic_model.test.my_sm\"\n    ],\n    \"metric.test.total_outer\": [\n      \"semantic_model.test.my_sm\"\n    ],\n    \"metric.test.simple_ratio_metric\": [\n      \"metric.test.total_outer\"\n    ],\n    \"metric.test.filtered_ratio_metric\": [\n      \"metric.test.total_outer\"\n    ],\n    \"metric.test.cumulative_metric\": [\n      \"semantic_model.test.my_sm\"\n    ],\n    \"metric.test.cumulative_metric_2\": [\n      \"semantic_model.test.my_sm\"\n    ],\n    \"metric.test.conversion_metric\": [\n      \"semantic_model.test.my_sm\"\n    ],\n    \"metric.test.derived_metric\": [\n      \"metric.test.conversion_metric\",\n      \"metric.test.filtered_ratio_metric\",\n      \"metric.test.simple_ratio_metric\"\n    ],\n    \"semantic_model.test.my_sm\": [\n      \"model.test.outer\"\n    ],\n    \"saved_query.test.my_saved_query\": [\n      \"metric.test.total_outer\"\n    ],\n    \"unit_test.test.model_to_unit_test.test_model_to_unit_test\": [\n      \"model.test.model_to_unit_test\"\n    ],\n    \"unit_test.test.model_to_unit_test.test_model_to_unit_test_2\": [\n      \"model.test.model_to_unit_test\"\n    ]\n  },\n  \"child_map\": {\n    \"model.test.model_with_lots_of_schema_configs\": [\n      \"test.test.my_favorite_test.b488d63233\",\n      \"test.test.my_second_favorite_test.c8955109ad\",\n      \"test.test.unique_model_with_lots_of_schema_configs_id.8328d84982\"\n    ],\n    \"model.test.snapshot_source\": [\n      \"snapshot.test.snapshot_2\",\n      \"snapshot.test.snapshot_3\"\n    ],\n    \"model.test.ephemeral\": [\n      \"model.test.model_with_lots_of_schema_configs\",\n      \"model.test.outer\"\n    ],\n    \"model.test.metricflow_time_spine\": [],\n    \"model.test.incremental\": [\n      \"exposure.test.weekly_jaffle_metrics\"\n    ],\n    \"model.test.model_to_unit_test\": [\n      \"unit_test.test.model_to_unit_test.test_model_to_unit_test\",\n      \"unit_test.test.model_to_unit_test.test_model_to_unit_test_2\"\n    ],\n    \"model.test.outer\": [\n      \"model.test.inner\",\n      \"semantic_model.test.my_sm\",\n      \"test.test.not_null_outer_id.a226f4fb36\",\n      \"test.test.unique_outer_id.2195e332d3\"\n    ],\n    \"model.test.metricflow_time_spine_second\": [],\n    \"model.test.inner\": [],\n    \"snapshot.test.my_snapshot\": [],\n    \"analysis.test.a\": [],\n    \"test.test.t\": [],\n    \"seed.test.seed\": [\n      \"model.test.incremental\",\n      \"model.test.model_to_unit_test\",\n      \"test.test.expression_is_true_seed_b_2.4e0babbea4\",\n      \"test.test.not_null_seed__a_.6b59640cde\",\n      \"test.test.not_null_seed__b_.a088b263cb\"\n    ],\n    \"test.test.not_null_seed__a_.6b59640cde\": [],\n    \"test.test.not_null_seed__b_.a088b263cb\": [],\n    \"test.test.expression_is_true_seed_b_2.4e0babbea4\": [],\n    \"test.test.unique_outer_id.2195e332d3\": [],\n    \"test.test.not_null_outer_id.a226f4fb36\": [],\n    \"test.test.unique_model_with_lots_of_schema_configs_id.8328d84982\": [],\n    \"test.test.my_favorite_test.b488d63233\": [],\n    \"test.test.my_second_favorite_test.c8955109ad\": [],\n    \"snapshot.test.snapshot_2\": [],\n    \"snapshot.test.snapshot_3\": [],\n    \"source.test.my_source.my_table\": [\n      \"model.test.model_with_lots_of_schema_configs\"\n    ],\n    \"exposure.test.weekly_jaffle_metrics\": [],\n    \"function.test.area_of_circle\": [],\n    \"metric.test.discrete_order_value_p99\": [],\n    \"metric.test.total_outer\": [\n      \"metric.test.filtered_ratio_metric\",\n      \"metric.test.simple_ratio_metric\",\n      \"saved_query.test.my_saved_query\"\n    ],\n    \"metric.test.simple_ratio_metric\": [\n      \"metric.test.derived_metric\"\n    ],\n    \"metric.test.filtered_ratio_metric\": [\n      \"metric.test.derived_metric\"\n    ],\n    \"metric.test.cumulative_metric\": [],\n    \"metric.test.cumulative_metric_2\": [],\n    \"metric.test.conversion_metric\": [\n      \"metric.test.derived_metric\"\n    ],\n    \"metric.test.derived_metric\": [],\n    \"semantic_model.test.my_sm\": [\n      \"metric.test.conversion_metric\",\n      \"metric.test.cumulative_metric\",\n      \"metric.test.cumulative_metric_2\",\n      \"metric.test.discrete_order_value_p99\",\n      \"metric.test.total_outer\"\n    ],\n    \"saved_query.test.my_saved_query\": [],\n    \"unit_test.test.model_to_unit_test.test_model_to_unit_test\": [],\n    \"unit_test.test.model_to_unit_test.test_model_to_unit_test_2\": []\n  },\n  \"group_map\": {\n    \"finance\": [\n      \"model.test.metricflow_time_spine\",\n      \"analysis.test.a\",\n      \"seed.test.seed\",\n      \"test.test.not_null_seed__a_.6b59640cde\",\n      \"test.test.not_null_seed__b_.a088b263cb\",\n      \"test.test.expression_is_true_seed_b_2.4e0babbea4\"\n    ],\n    \"important_tests\": [\n      \"test.test.t\"\n    ]\n  },\n  \"saved_queries\": {\n    \"saved_query.test.my_saved_query\": {\n      \"name\": \"my_saved_query\",\n      \"resource_type\": \"saved_query\",\n      \"package_name\": \"test\",\n      \"path\": \"sq.yml\",\n      \"original_file_path\": \"models/sq.yml\",\n      \"unique_id\": \"saved_query.test.my_saved_query\",\n      \"fqn\": [\n        \"test\",\n        \"my_saved_query\"\n      ],\n      \"query_params\": {\n        \"metrics\": [\n          \"total_outer\"\n        ],\n        \"group_by\": [\n          \"Dimension('my_entity__created_at')\"\n        ],\n        \"where\": null,\n        \"order_by\": [],\n        \"limit\": null\n      },\n      \"exports\": [\n        {\n          \"name\": \"my_export\",\n          \"config\": {\n            \"export_as\": \"table\",\n            \"schema_name\": \"my_export_schema_name\",\n            \"alias\": \"my_export_alias\",\n            \"database\": \"dbt\"\n          },\n          \"unrendered_config\": {\n            \"alias\": \"my_export_alias\",\n            \"export_as\": \"table\",\n            \"schema\": \"my_export_schema_name\"\n          }\n        }\n      ],\n      \"description\": null,\n      \"label\": \"My Saved Query\",\n      \"metadata\": null,\n      \"config\": {\n        \"enabled\": true,\n        \"group\": null,\n        \"meta\": {},\n        \"export_as\": null,\n        \"schema\": null,\n        \"cache\": {\n          \"enabled\": false\n        }\n      },\n      \"unrendered_config\": {},\n      \"group\": null,\n      \"depends_on\": {\n        \"macros\": [],\n        \"nodes\": [\n          \"metric.test.total_outer\"\n        ]\n      },\n      \"created_at\": 1763574306.391684,\n      \"refs\": [],\n      \"tags\": []\n    }\n  },\n  \"semantic_models\": {\n    \"semantic_model.test.my_sm\": {\n      \"name\": \"my_sm\",\n      \"resource_type\": \"semantic_model\",\n      \"package_name\": \"test\",\n      \"path\": \"sm.yml\",\n      \"original_file_path\": \"models/sm.yml\",\n      \"unique_id\": \"semantic_model.test.my_sm\",\n      \"fqn\": [\n        \"test\",\n        \"my_sm\"\n      ],\n      \"model\": \"ref('outer')\",\n      \"node_relation\": {\n        \"alias\": \"outer\",\n        \"schema_name\": \"test17635743055401889788_test_modified_state_schema_evolution\",\n        \"database\": \"dbt\",\n        \"relation_name\": \"\\\"dbt\\\".\\\"test17635743055401889788_test_modified_state_schema_evolution\\\".\\\"outer\\\"\"\n      },\n      \"description\": null,\n      \"label\": null,\n      \"defaults\": {\n        \"agg_time_dimension\": \"created_at\"\n      },\n      \"entities\": [\n        {\n          \"name\": \"my_entity\",\n          \"type\": \"primary\",\n          \"description\": null,\n          \"label\": null,\n          \"role\": null,\n          \"expr\": \"id\",\n          \"config\": {\n            \"meta\": {}\n          }\n        },\n        {\n          \"name\": \"user\",\n          \"type\": \"foreign\",\n          \"description\": null,\n          \"label\": null,\n          \"role\": null,\n          \"expr\": \"user_id\",\n          \"config\": {\n            \"meta\": {}\n          }\n        }\n      ],\n      \"measures\": [\n        {\n          \"name\": \"total_outer_count\",\n          \"agg\": \"count\",\n          \"description\": null,\n          \"label\": null,\n          \"create_metric\": false,\n          \"expr\": \"1\",\n          \"agg_params\": null,\n          \"non_additive_dimension\": null,\n          \"agg_time_dimension\": null,\n          \"config\": {\n            \"meta\": {}\n          }\n        },\n        {\n          \"name\": \"discrete_order_value_p99\",\n          \"agg\": \"percentile\",\n          \"description\": null,\n          \"label\": null,\n          \"create_metric\": false,\n          \"expr\": \"order_total\",\n          \"agg_params\": {\n            \"percentile\": 0.99,\n            \"use_discrete_percentile\": true,\n            \"use_approximate_percentile\": false\n          },\n          \"non_additive_dimension\": null,\n          \"agg_time_dimension\": \"created_at\",\n          \"config\": {\n            \"meta\": {}\n          }\n        },\n        {\n          \"name\": \"sum_of_things\",\n          \"agg\": \"sum\",\n          \"description\": null,\n          \"label\": null,\n          \"create_metric\": false,\n          \"expr\": \"2\",\n          \"agg_params\": null,\n          \"non_additive_dimension\": null,\n          \"agg_time_dimension\": \"created_at\",\n          \"config\": {\n            \"meta\": {}\n          }\n        },\n        {\n          \"name\": \"has_revenue\",\n          \"agg\": \"sum_boolean\",\n          \"description\": null,\n          \"label\": null,\n          \"create_metric\": false,\n          \"expr\": \"True\",\n          \"agg_params\": null,\n          \"non_additive_dimension\": null,\n          \"agg_time_dimension\": \"created_at\",\n          \"config\": {\n            \"meta\": {}\n          }\n        },\n        {\n          \"name\": \"test_non_additive\",\n          \"agg\": \"sum\",\n          \"description\": null,\n          \"label\": null,\n          \"create_metric\": false,\n          \"expr\": \"txn_revenue\",\n          \"agg_params\": null,\n          \"non_additive_dimension\": {\n            \"name\": \"created_at\",\n            \"window_choice\": \"max\",\n            \"window_groupings\": []\n          },\n          \"agg_time_dimension\": null,\n          \"config\": {\n            \"meta\": {}\n          }\n        }\n      ],\n      \"dimensions\": [\n        {\n          \"name\": \"created_at\",\n          \"type\": \"time\",\n          \"description\": null,\n          \"label\": null,\n          \"is_partition\": false,\n          \"type_params\": {\n            \"time_granularity\": \"day\",\n            \"validity_params\": null\n          },\n          \"expr\": null,\n          \"metadata\": null,\n          \"config\": {\n            \"meta\": {}\n          }\n        }\n      ],\n      \"metadata\": null,\n      \"depends_on\": {\n        \"macros\": [],\n        \"nodes\": [\n          \"model.test.outer\"\n        ]\n      },\n      \"refs\": [\n        {\n          \"name\": \"outer\",\n          \"package\": null,\n          \"version\": null\n        }\n      ],\n      \"created_at\": 1763574306.3763149,\n      \"config\": {\n        \"enabled\": true,\n        \"group\": null,\n        \"meta\": {}\n      },\n      \"unrendered_config\": {},\n      \"primary_entity\": null,\n      \"group\": null\n    }\n  },\n  \"unit_tests\": {\n    \"unit_test.test.model_to_unit_test.test_model_to_unit_test\": {\n      \"model\": \"model_to_unit_test\",\n      \"given\": [\n        {\n          \"input\": \"ref('seed')\",\n          \"rows\": [\n            {\n              \"a\": \"1\",\n              \"b\": \"2\"\n            },\n            {\n              \"a\": \"2\",\n              \"b\": \"3\"\n            }\n          ],\n          \"format\": \"csv\",\n          \"fixture\": \"test_incremental_fixture\"\n        }\n      ],\n      \"expect\": {\n        \"rows\": [\n          {\n            \"a\": \"1\",\n            \"b\": \"2\"\n          },\n          {\n            \"a\": \"2\",\n            \"b\": \"3\"\n          }\n        ],\n        \"format\": \"csv\",\n        \"fixture\": \"test_incremental_fixture\"\n      },\n      \"name\": \"test_model_to_unit_test\",\n      \"resource_type\": \"unit_test\",\n      \"package_name\": \"test\",\n      \"path\": \"unit_tests.yml\",\n      \"original_file_path\": \"models/unit_tests.yml\",\n      \"unique_id\": \"unit_test.test.model_to_unit_test.test_model_to_unit_test\",\n      \"fqn\": [\n        \"test\",\n        \"model_to_unit_test\",\n        \"test_model_to_unit_test\"\n      ],\n      \"description\": \"A simple test of the outer model\",\n      \"overrides\": null,\n      \"depends_on\": {\n        \"macros\": [],\n        \"nodes\": [\n          \"model.test.model_to_unit_test\"\n        ]\n      },\n      \"config\": {\n        \"tags\": [],\n        \"meta\": {},\n        \"enabled\": true\n      },\n      \"checksum\": \"e7987dd2500df4fa4db5715bd41e0998f25587ddd344be97dfe038f1535b0230\",\n      \"schema\": \"test17635743055401889788_test_modified_state_schema_evolution\",\n      \"created_at\": 1763574306.34929,\n      \"versions\": null,\n      \"version\": null\n    },\n    \"unit_test.test.model_to_unit_test.test_model_to_unit_test_2\": {\n      \"model\": \"model_to_unit_test\",\n      \"given\": [\n        {\n          \"input\": \"ref('seed')\",\n          \"rows\": \"SELECT 2 as a, 3 as b\",\n          \"format\": \"sql\",\n          \"fixture\": null\n        }\n      ],\n      \"expect\": {\n        \"rows\": [\n          {\n            \"a\": 2,\n            \"b\": 3\n          }\n        ],\n        \"format\": \"dict\",\n        \"fixture\": null\n      },\n      \"name\": \"test_model_to_unit_test_2\",\n      \"resource_type\": \"unit_test\",\n      \"package_name\": \"test\",\n      \"path\": \"unit_tests.yml\",\n      \"original_file_path\": \"models/unit_tests.yml\",\n      \"unique_id\": \"unit_test.test.model_to_unit_test.test_model_to_unit_test_2\",\n      \"fqn\": [\n        \"test\",\n        \"model_to_unit_test\",\n        \"test_model_to_unit_test_2\"\n      ],\n      \"description\": \"A simple test of the outer model\",\n      \"overrides\": {\n        \"macros\": {\n          \"is_incremental\": false\n        },\n        \"vars\": {},\n        \"env_vars\": {}\n      },\n      \"depends_on\": {\n        \"macros\": [],\n        \"nodes\": [\n          \"model.test.model_to_unit_test\"\n        ]\n      },\n      \"config\": {\n        \"tags\": [\n          \"test_tag\"\n        ],\n        \"meta\": {\n          \"my_custom_meta_key\": \"my_custom_meta_value\"\n        },\n        \"enabled\": true\n      },\n      \"checksum\": \"635a3c7a84af38b2f3c52a526773bef3df93278099e2ccefc011986cf26060c2\",\n      \"schema\": \"test17635743055401889788_test_modified_state_schema_evolution\",\n      \"created_at\": 1763574306.3518012,\n      \"versions\": {\n        \"include\": null,\n        \"exclude\": null\n      },\n      \"version\": null\n    }\n  },\n  \"functions\": {\n    \"function.test.area_of_circle\": {\n      \"returns\": {\n        \"data_type\": \"float\",\n        \"description\": null\n      },\n      \"database\": \"dbt\",\n      \"schema\": \"test17635743055401889788_test_modified_state_schema_evolution\",\n      \"name\": \"area_of_circle\",\n      \"resource_type\": \"function\",\n      \"package_name\": \"test\",\n      \"path\": \"area_of_circle.sql\",\n      \"original_file_path\": \"functions/area_of_circle.sql\",\n      \"unique_id\": \"function.test.area_of_circle\",\n      \"fqn\": [\n        \"test\",\n        \"area_of_circle\"\n      ],\n      \"alias\": \"area_of_circle\",\n      \"checksum\": {\n        \"name\": \"sha256\",\n        \"checksum\": \"5f20c7f9790d05c41d31e0e4032104143372a588e9ca7ca04a337f4b652a6e84\"\n      },\n      \"config\": {\n        \"enabled\": true,\n        \"alias\": null,\n        \"schema\": null,\n        \"database\": null,\n        \"tags\": [],\n        \"meta\": {},\n        \"group\": null,\n        \"materialized\": \"function\",\n        \"incremental_strategy\": null,\n        \"batch_size\": null,\n        \"lookback\": 1,\n        \"begin\": null,\n        \"persist_docs\": {},\n        \"post-hook\": [],\n        \"pre-hook\": [],\n        \"quoting\": {},\n        \"column_types\": {},\n        \"full_refresh\": null,\n        \"unique_key\": null,\n        \"on_schema_change\": \"ignore\",\n        \"on_configuration_change\": \"apply\",\n        \"grants\": {},\n        \"packages\": [],\n        \"docs\": {\n          \"show\": true,\n          \"node_color\": null\n        },\n        \"contract\": {\n          \"enforced\": false,\n          \"alias_types\": true\n        },\n        \"event_time\": null,\n        \"concurrent_batches\": null,\n        \"type\": \"scalar\",\n        \"volatility\": null,\n        \"runtime_version\": null,\n        \"entry_point\": null\n      },\n      \"tags\": [],\n      \"description\": \"Calculates the area of a circle for a given radius\",\n      \"columns\": {},\n      \"meta\": {},\n      \"group\": null,\n      \"docs\": {\n        \"show\": true,\n        \"node_color\": null\n      },\n      \"patch_path\": \"test://functions/area_of_circle.yml\",\n      \"build_path\": null,\n      \"unrendered_config\": {\n        \"enabled\": true\n      },\n      \"created_at\": 1763574306.4420989,\n      \"relation_name\": null,\n      \"raw_code\": \"SELECT pi() * radius * radius\",\n      \"doc_blocks\": [],\n      \"language\": \"sql\",\n      \"refs\": [],\n      \"sources\": [],\n      \"metrics\": [],\n      \"functions\": [],\n      \"depends_on\": {\n        \"macros\": [],\n        \"nodes\": []\n      },\n      \"compiled_path\": null,\n      \"contract\": {\n        \"enforced\": false,\n        \"alias_types\": true,\n        \"checksum\": null\n      },\n      \"arguments\": [\n        {\n          \"name\": \"radius\",\n          \"data_type\": \"float\",\n          \"description\": \"A floating point number representing the radius of the circle\"\n        }\n      ]\n    }\n  }\n}\n"
  },
  {
    "path": "tests/functional/defer_state/fixtures.py",
    "content": "seed_csv = \"\"\"id,name\n1,Alice\n2,Bob\n\"\"\"\n\ntable_model_sql = \"\"\"\n{{ config(materialized='table') }}\nselect * from {{ ref('ephemeral_model') }}\n\n-- establish a macro dependency to trigger state:modified.macros\n-- depends on: {{ my_macro() }}\n\"\"\"\n\ntable_model_now_view_sql = \"\"\"\n{{ config(materialized='view') }}\nselect * from {{ ref('ephemeral_model') }}\n\n-- establish a macro dependency to trigger state:modified.macros\n-- depends on: {{ my_macro() }}\n\"\"\"\n\ntable_model_now_incremental_sql = \"\"\"\n{{ config(materialized='incremental', on_schema_change='append_new_columns') }}\nselect * from {{ ref('ephemeral_model') }}\n\n-- establish a macro dependency to trigger state:modified.macros\n-- depends on: {{ my_macro() }}\n\"\"\"\n\nchanged_table_model_sql = \"\"\"\n{{ config(materialized='table') }}\nselect 1 as fun\n\"\"\"\n\nview_model_sql = \"\"\"\nselect * from {{ ref('seed') }}\n\n-- establish a macro dependency that trips infinite recursion if not handled\n-- depends on: {{ my_infinitely_recursive_macro() }}\n\"\"\"\n\nview_model_now_table_sql = \"\"\"\n{{ config(materialized='table') }}\nselect * from {{ ref('seed') }}\n\n-- establish a macro dependency that trips infinite recursion if not handled\n-- depends on: {{ my_infinitely_recursive_macro() }}\n\"\"\"\n\nchanged_view_model_sql = \"\"\"\nselect * from no.such.table\n\"\"\"\n\nephemeral_model_sql = \"\"\"\n{{ config(materialized='ephemeral') }}\nselect * from {{ ref('view_model') }}\n\"\"\"\n\nchanged_ephemeral_model_sql = \"\"\"\n{{ config(materialized='ephemeral') }}\nselect * from no.such.table\n\"\"\"\n\nschema_yml = \"\"\"\nversion: 2\nmodels:\n  - name: view_model\n    columns:\n      - name: id\n        data_tests:\n          - unique:\n              config:\n                severity: error\n          - not_null\n      - name: name\n\"\"\"\n\nno_contract_schema_yml = \"\"\"\nversion: 2\nmodels:\n  - name: table_model\n    config: {}\n    columns:\n      - name: id\n        data_type: integer\n        data_tests:\n          - unique:\n              severity: error\n          - not_null\n      - name: name\n        data_type: text\n\"\"\"\n\ncontract_schema_yml = \"\"\"\nversion: 2\nmodels:\n  - name: table_model\n    config:\n      contract:\n        enforced: True\n    columns:\n      - name: id\n        data_type: integer\n        data_tests:\n          - unique:\n              severity: error\n          - not_null\n      - name: name\n        data_type: text\n\"\"\"\n\ndisabled_contract_schema_yml = \"\"\"\nversion: 2\nmodels:\n  - name: table_model\n    config:\n      contract:\n        enforced: True\n      enabled: False\n    columns:\n      - name: id\n        data_type: integer\n        data_tests:\n          - unique:\n              severity: error\n          - not_null\n      - name: name\n        data_type: text\n\"\"\"\n\nmodified_contract_schema_yml = \"\"\"\nversion: 2\nmodels:\n  - name: table_model\n    config:\n      contract:\n        enforced: True\n    columns:\n      - name: id\n        data_type: integer\n        data_tests:\n          - unique:\n              severity: error\n          - not_null\n      - name: user_name\n        data_type: text\n\"\"\"\n\nunenforced_contract_schema_yml = \"\"\"\nversion: 2\nmodels:\n  - name: table_model\n    config:\n      contract:\n        enforced: False\n    columns:\n      - name: id\n        data_type: integer\n        data_tests:\n          - unique:\n              severity: error\n          - not_null\n      - name: name\n        data_type: text\n\"\"\"\n\ndisabled_unenforced_contract_schema_yml = \"\"\"\nversion: 2\nmodels:\n  - name: table_model\n    config:\n      contract:\n        enforced: False\n      enabled: False\n    columns:\n      - name: id\n        data_type: integer\n        data_tests:\n          - unique:\n              severity: error\n          - not_null\n      - name: name\n        data_type: text\n\"\"\"\n\nversioned_no_contract_schema_yml = \"\"\"\nversion: 2\nmodels:\n  - name: table_model\n    config: {}\n    versions:\n      - v: 1\n    columns:\n      - name: id\n        data_type: integer\n        data_tests:\n          - unique:\n              severity: error\n          - not_null\n      - name: name\n        data_type: text\n\"\"\"\n\nversioned_contract_schema_yml = \"\"\"\nversion: 2\nmodels:\n  - name: table_model\n    config:\n      contract:\n        enforced: True\n    versions:\n      - v: 1\n    columns:\n      - name: id\n        data_type: integer\n        data_tests:\n          - unique:\n              severity: error\n          - not_null\n      - name: name\n        data_type: text\n\"\"\"\n\ndisabled_versioned_contract_schema_yml = \"\"\"\nversion: 2\nmodels:\n  - name: table_model\n    config:\n      contract:\n        enforced: True\n      enabled: False\n    versions:\n      - v: 1\n    columns:\n      - name: id\n        data_type: integer\n        data_tests:\n          - unique:\n              severity: error\n          - not_null\n      - name: name\n        data_type: text\n\"\"\"\n\nversioned_modified_contract_schema_yml = \"\"\"\nversion: 2\nmodels:\n  - name: table_model\n    config:\n      contract:\n        enforced: True\n    versions:\n      - v: 1\n    columns:\n      - name: id\n        data_type: integer\n        data_tests:\n          - unique:\n              severity: error\n          - not_null\n      - name: user_name\n        data_type: text\n\"\"\"\n\ndisabled_versioned_unenforced_contract_schema_yml = \"\"\"\nversion: 2\nmodels:\n  - name: table_model\n    config:\n      contract:\n        enforced: False\n      enabled: False\n    versions:\n      - v: 1\n    columns:\n      - name: id\n        data_type: integer\n        data_tests:\n          - unique:\n              severity: error\n          - not_null\n      - name: name\n        data_type: text\n\"\"\"\n\nversioned_unenforced_contract_schema_yml = \"\"\"\nversion: 2\nmodels:\n  - name: table_model\n    config:\n      contract:\n        enforced: False\n    versions:\n      - v: 1\n    columns:\n      - name: id\n        data_type: integer\n        data_tests:\n          - unique:\n              severity: error\n          - not_null\n      - name: name\n        data_type: text\n\"\"\"\n\nconstraint_schema_yml = \"\"\"\nversion: 2\nmodels:\n  - name: view_model\n    columns:\n      - name: id\n        data_tests:\n          - unique:\n              severity: error\n          - not_null\n      - name: name\n  - name: table_model\n    config:\n      contract:\n        enforced: True\n    constraints:\n      - type: primary_key\n        columns: [id]\n    columns:\n      - name: id\n        constraints:\n          - type: not_null\n        data_type: integer\n        data_tests:\n          - unique:\n              severity: error\n          - not_null\n      - name: name\n        data_type: text\n\"\"\"\n\nmodified_column_constraint_schema_yml = \"\"\"\nversion: 2\nmodels:\n  - name: view_model\n    columns:\n      - name: id\n        data_tests:\n          - unique:\n              severity: error\n          - not_null\n      - name: name\n  - name: table_model\n    config:\n      contract:\n        enforced: True\n    constraints:\n      - type: primary_key\n        columns: [id]\n    columns:\n      - name: id\n        data_type: integer\n        data_tests:\n          - unique:\n              severity: error\n          - not_null\n      - name: name\n        data_type: text\n\"\"\"\n\nmodified_model_constraint_schema_yml = \"\"\"\nversion: 2\nmodels:\n  - name: view_model\n    columns:\n      - name: id\n        data_tests:\n          - unique:\n              severity: error\n          - not_null\n      - name: name\n  - name: table_model\n    config:\n      contract:\n        enforced: True\n    columns:\n      - name: id\n        constraints:\n          - type: not_null\n        data_type: integer\n        data_tests:\n          - unique:\n              severity: error\n          - not_null\n      - name: name\n        data_type: text\n\"\"\"\n\nexposures_yml = \"\"\"\nversion: 2\nexposures:\n  - name: my_exposure\n    type: application\n    depends_on:\n      - ref('view_model')\n    owner:\n      email: test@example.com\n\"\"\"\n\nmacros_sql = \"\"\"\n{% macro my_macro() %}\n    {% do log('in a macro' ) %}\n{% endmacro %}\n\"\"\"\n\ninfinite_macros_sql = \"\"\"\n{# trigger infinite recursion if not handled #}\n\n{% macro my_infinitely_recursive_macro() %}\n  {{ return(adapter.dispatch('my_infinitely_recursive_macro')()) }}\n{% endmacro %}\n\n{% macro default__my_infinitely_recursive_macro() %}\n    {% if unmet_condition %}\n        {{ my_infinitely_recursive_macro() }}\n    {% else %}\n        {{ return('') }}\n    {% endif %}\n{% endmacro %}\n\"\"\"\n\nsnapshot_sql = \"\"\"\n{% snapshot my_cool_snapshot %}\n\n    {{\n        config(\n            target_database=database,\n            target_schema=schema,\n            unique_key='id',\n            strategy='check',\n            check_cols=['id'],\n        )\n    }}\n    select * from {{ ref('view_model') }}\n\n{% endsnapshot %}\n\"\"\"\n\n\nsemantic_model_schema_yml = \"\"\"\nmodels:\n  - name: view_model\n    columns:\n      - name: id\n        data_tests:\n          - unique:\n              severity: error\n          - not_null\n      - name: name\n\nsemantic_models:\n  - name: my_sm\n    model: ref('view_model')\n\"\"\"\n\nmodified_semantic_model_schema_yml = \"\"\"\nmodels:\n  - name: view_model\n    columns:\n      - name: id\n        data_tests:\n          - unique:\n              severity: error\n          - not_null\n      - name: name\n\nsemantic_models:\n  - name: my_sm\n    model: ref('view_model')\n    description: modified description\n\"\"\"\n\nmodel_1_sql = \"\"\"\nselect * from {{ ref('seed') }}\n\"\"\"\n\nmodified_model_1_sql = \"\"\"\nselect * from  {{ ref('seed') }}\norder by 1\n\"\"\"\n\nmodel_2_sql = \"\"\"\nselect id from  {{ ref('model_1') }}\n\"\"\"\n\nmodified_model_2_sql = \"\"\"\nselect * from  {{ ref('model_1') }}\norder by 1\n\"\"\"\n\n\ngroup_schema_yml = \"\"\"\ngroups:\n  - name: finance\n    owner:\n      email: finance@jaffleshop.com\n\nmodels:\n  - name: model_1\n    config:\n      group: finance\n  - name: model_2\n    config:\n      group: finance\n\"\"\"\n\n\ngroup_modified_schema_yml = \"\"\"\ngroups:\n  - name: accounting\n    owner:\n      email: finance@jaffleshop.com\nmodels:\n  - name: model_1\n    config:\n      group: accounting\n  - name: model_2\n    config:\n      group: accounting\n\"\"\"\n\ngroup_modified_fail_schema_yml = \"\"\"\ngroups:\n  - name: finance\n    owner:\n      email: finance@jaffleshop.com\nmodels:\n  - name: model_1\n    config:\n      group: accounting\n  - name: model_2\n    config:\n      group: finance\n\"\"\"\n\nmetricflow_time_spine_sql = \"\"\"\nSELECT to_date('02/20/2023', 'mm/dd/yyyy') as date_day\n\"\"\"\n\n\nmodel_with_env_var_in_config_sql = \"\"\"\n{{ config(materialized=env_var('DBT_TEST_STATE_MODIFIED')) }}\nselect 1 as id\n\"\"\"\n\nmodel_with_no_in_config_sql = \"\"\"\nselect 1 as id\n\"\"\"\n\n\nschema_model_with_env_var_in_config_yml = \"\"\"\nmodels:\n  - name: model\n    config:\n      materialized: \"{{ env_var('DBT_TEST_STATE_MODIFIED') }}\"\n\n\"\"\"\n\n\nmodel_with_var_in_config_sql = \"\"\"\n{{ config(materialized=var('DBT_TEST_STATE_MODIFIED')) }}\nselect 1 as id\n\"\"\"\n\nmodel_with_jinja_in_config_sql = \"\"\"\n{{ config(\n    materialized = ('table' if execute else 'view')\n) }}\n\nselect 1 as id\n\"\"\"\n\nmodel_with_updated_jinja_in_config_sql = \"\"\"\n{{ config(\n    materialized = ('view' if execute else 'table')\n) }}\n\nselect 1 as id\n\"\"\"\n\nschema_model_with_jinja_in_config_yml = \"\"\"\nmodels:\n  - name: model\n    config:\n      materialized: \"{{ ('table' if execute else 'view') }}\"\n\"\"\"\n\nschema_model_with_updated_jinja_in_config_yml = \"\"\"\nmodels:\n  - name: model\n    config:\n      materialized: \"{{ ('view' if execute else 'table') }}\"\n\"\"\"\n\nschema_source_with_env_var_as_database_property_yml = \"\"\"\nsources:\n  - name: jaffle_shop\n    database: \"{{ env_var('DBT_TEST_STATE_MODIFIED') }}\"\n    tables:\n      - name: customers\n\"\"\"\n\nschema_source_with_env_var_as_schema_property_yml = \"\"\"\nsources:\n  - name: jaffle_shop\n    database: \"test\"\n    schema: \"{{ env_var('DBT_TEST_STATE_MODIFIED') }}\"\n    tables:\n      - name: customers\n\"\"\"\n\nschema_source_with_updated_env_var_as_schema_property_yml = \"\"\"\nsources:\n  - name: jaffle_shop\n    database: \"test\"\n    schema: \"updated\"\n    tables:\n      - name: customers\n\"\"\"\n\nschema_source_with_jinja_as_database_property_yml = \"\"\"\nsources:\n  - name: jaffle_shop\n    database: \"{{ ('foo' if execute else 'bar') }}\"\n    tables:\n      - name: customers\n\"\"\"\n\nschema_source_with_updated_jinja_as_database_property_yml = \"\"\"\nsources:\n  - name: jaffle_shop\n    database: \"{{ ('bar' if execute else 'foo') }}\"\n    tables:\n      - name: customers\n\"\"\"\n\nschema_source_with_jinja_as_schema_property_yml = \"\"\"\nsources:\n  - name: jaffle_shop\n    database: \"test\"\n    schema: \"{{ ('foo' if execute else 'bar') }}\"\n    tables:\n      - name: customers\n\"\"\"\n\nschema_source_with_updated_jinja_as_schema_property_yml = \"\"\"\nsources:\n  - name: jaffle_shop\n    database: \"test\"\n    schema: \"{{ ('bar' if execute else 'foo') }}\"\n    tables:\n      - name: customers\n\"\"\"\n\n# Fixtures for test_removed_test_state.py\nsample_test_sql = \"\"\"\n{% test sample_test(model, column_name) %}\n    select * from {{ model }} where {{ column_name }} is null\n{% endtest %}\n\"\"\"\n\nremoved_test_model_sql = \"\"\"\nselect 1 as id\n\"\"\"\n\nremoved_test_schema_yml = \"\"\"\nversion: 2\nmodels:\n  - name: model_a\n    columns:\n      - name: id\n        data_tests:\n          - sample_test\n\"\"\"\n\n# Fixtures for test_modified_state.py - varchar/numeric size changes\nvarchar_size_contract_schema_yml = \"\"\"\nversion: 2\nmodels:\n  - name: table_model\n    config:\n      contract:\n        enforced: true\n    versions:\n      - v: 1\n    columns:\n      - name: id\n        data_type: integer\n      - name: name\n        data_type: varchar(5)\n\"\"\"\n\nvarchar_size_increased_contract_schema_yml = \"\"\"\nversion: 2\nmodels:\n  - name: table_model\n    config:\n      contract:\n        enforced: true\n    versions:\n      - v: 1\n    columns:\n      - name: id\n        data_type: integer\n      - name: name\n        data_type: varchar(20)\n\"\"\"\n\nnumeric_precision_contract_schema_yml = \"\"\"\nversion: 2\nmodels:\n  - name: table_model\n    config:\n      contract:\n        enforced: true\n    versions:\n      - v: 1\n    columns:\n      - name: id\n        data_type: integer\n      - name: amount\n        data_type: numeric(10,2)\n\"\"\"\n\nnumeric_precision_increased_contract_schema_yml = \"\"\"\nversion: 2\nmodels:\n  - name: table_model\n    config:\n      contract:\n        enforced: true\n    versions:\n      - v: 1\n    columns:\n      - name: id\n        data_type: integer\n      - name: amount\n        data_type: numeric(12,4)\n\"\"\"\n\n# Case sensitivity test fixtures\nvarchar_size_uppercase_contract_schema_yml = \"\"\"\nversion: 2\nmodels:\n  - name: table_model\n    config:\n      contract:\n        enforced: true\n    versions:\n      - v: 1\n    columns:\n      - name: id\n        data_type: integer\n      - name: name\n        data_type: VARCHAR(5)\n\"\"\"\n\nvarchar_size_lowercase_increased_contract_schema_yml = \"\"\"\nversion: 2\nmodels:\n  - name: table_model\n    config:\n      contract:\n        enforced: true\n    versions:\n      - v: 1\n    columns:\n      - name: id\n        data_type: integer\n      - name: name\n        data_type: varchar(20)\n\"\"\"\n\n# Unversioned model fixtures\nvarchar_size_unversioned_contract_schema_yml = \"\"\"\nversion: 2\nmodels:\n  - name: table_model\n    config:\n      contract:\n        enforced: true\n    columns:\n      - name: id\n        data_type: integer\n      - name: name\n        data_type: varchar(5)\n\"\"\"\n\nvarchar_size_unversioned_increased_contract_schema_yml = \"\"\"\nversion: 2\nmodels:\n  - name: table_model\n    config:\n      contract:\n        enforced: true\n    columns:\n      - name: id\n        data_type: integer\n      - name: name\n        data_type: varchar(20)\n\"\"\"\n\n\ndouble_it_sql = \"\"\"\nSELECT value * 2\n\"\"\"\n\ndouble_it_yml = \"\"\"\nfunctions:\n  - name: double_it\n    description: Doubles whatever number is passed in\n    arguments:\n      - name: value\n        data_type: float\n        description: A number to be doubled\n    returns:\n      data_type: float\n\"\"\"\n"
  },
  {
    "path": "tests/functional/defer_state/test_defer_state.py",
    "content": "import os\nimport shutil\nfrom copy import deepcopy\nfrom typing import Dict\n\nimport pytest\n\nfrom dbt.contracts.results import RunStatus\nfrom dbt.exceptions import DbtRuntimeError\nfrom dbt.tests.util import rm_file, run_dbt, write_file\nfrom tests.functional.defer_state.fixtures import (\n    changed_ephemeral_model_sql,\n    changed_table_model_sql,\n    changed_view_model_sql,\n    double_it_sql,\n    double_it_yml,\n    ephemeral_model_sql,\n    exposures_yml,\n    infinite_macros_sql,\n    macros_sql,\n    schema_yml,\n    seed_csv,\n    snapshot_sql,\n    table_model_sql,\n    view_model_now_table_sql,\n    view_model_sql,\n)\n\n\nclass BaseDeferState:\n    _models = {\n        \"table_model.sql\": table_model_sql,\n        \"view_model.sql\": view_model_sql,\n        \"ephemeral_model.sql\": ephemeral_model_sql,\n        \"schema.yml\": schema_yml,\n        \"exposures.yml\": exposures_yml,\n    }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return self._models\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\n            \"macros.sql\": macros_sql,\n            \"infinite_macros.sql\": infinite_macros_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\n            \"seed.csv\": seed_csv,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def snapshots(self):\n        return {\n            \"snapshot.sql\": snapshot_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def other_schema(self, unique_schema):\n        return unique_schema + \"_other\"\n\n    @property\n    def project_config_update(self):\n        return {\n            \"seeds\": {\n                \"test\": {\n                    \"quote_columns\": False,\n                }\n            }\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def profiles_config_update(self, dbt_profile_target, unique_schema, other_schema):\n        outputs = {\"default\": dbt_profile_target, \"otherschema\": deepcopy(dbt_profile_target)}\n        outputs[\"default\"][\"schema\"] = unique_schema\n        outputs[\"otherschema\"][\"schema\"] = other_schema\n        return {\"test\": {\"outputs\": outputs, \"target\": \"default\"}}\n\n    def copy_state(self, project_root):\n        state_path = os.path.join(project_root, \"state\")\n        if not os.path.exists(state_path):\n            os.makedirs(state_path)\n        shutil.copyfile(\n            f\"{project_root}/target/manifest.json\", f\"{project_root}/state/manifest.json\"\n        )\n\n    def run_and_save_state(self, project_root, with_snapshot=False):\n        results = run_dbt([\"seed\"])\n        assert len(results) == 1\n        results = run_dbt([\"run\"])\n        assert len(results) == 2\n        results = run_dbt([\"test\"])\n        assert len(results) == 2\n\n        if with_snapshot:\n            results = run_dbt([\"snapshot\"])\n            assert len(results) == 1\n\n        # copy files\n        self.copy_state(project_root)\n\n\nclass TestDeferStateUnsupportedCommands(BaseDeferState):\n    def test_no_state(self, project):\n        # no \"state\" files present, snapshot fails\n        with pytest.raises(DbtRuntimeError):\n            run_dbt([\"snapshot\", \"--state\", \"state\", \"--defer\"])\n\n\nclass TestRunCompileState(BaseDeferState):\n    def test_run_and_compile_defer(self, project):\n        self.run_and_save_state(project.project_root)\n\n        # defer test, it succeeds\n        # Change directory to ensure that state directory is underneath\n        # project directory.\n        os.chdir(project.profiles_dir)\n        results = run_dbt([\"compile\", \"--state\", \"state\", \"--defer\"])\n        assert len(results.results) == 6\n        assert results.results[0].node.name == \"seed\"\n\n\nclass TestSnapshotState(BaseDeferState):\n    def test_snapshot_state_defer(self, project):\n        self.run_and_save_state(project.project_root)\n        # snapshot succeeds without --defer\n        run_dbt([\"snapshot\"])\n        # copy files\n        self.copy_state(project.project_root)\n        # defer test, it succeeds\n        run_dbt([\"snapshot\", \"--state\", \"state\", \"--defer\"])\n        # favor_state test, it succeeds\n        run_dbt([\"snapshot\", \"--state\", \"state\", \"--defer\", \"--favor-state\"])\n\n\nclass TestRunDeferState(BaseDeferState):\n    def test_run_and_defer(self, project, unique_schema, other_schema):\n        project.create_test_schema(other_schema)\n        self.run_and_save_state(project.project_root)\n\n        # test tests first, because run will change things\n        # no state, wrong schema, failure.\n        run_dbt([\"test\", \"--target\", \"otherschema\"], expect_pass=False)\n\n        # test generate docs\n        # no state, wrong schema, empty nodes\n        catalog = run_dbt([\"docs\", \"generate\", \"--target\", \"otherschema\"])\n        assert not catalog.nodes\n\n        # no state, run also fails\n        run_dbt([\"run\", \"--target\", \"otherschema\"], expect_pass=False)\n\n        # defer test, it succeeds\n        results = run_dbt(\n            [\"test\", \"-m\", \"view_model+\", \"--state\", \"state\", \"--defer\", \"--target\", \"otherschema\"]\n        )\n\n        # defer docs generate with state, catalog refers schema from the happy times\n        catalog = run_dbt(\n            [\n                \"docs\",\n                \"generate\",\n                \"-m\",\n                \"view_model+\",\n                \"--state\",\n                \"state\",\n                \"--defer\",\n                \"--target\",\n                \"otherschema\",\n            ]\n        )\n        assert \"seed.test.seed\" not in catalog.nodes\n\n        # with state it should work though\n        results = run_dbt(\n            [\"run\", \"-m\", \"view_model\", \"--state\", \"state\", \"--defer\", \"--target\", \"otherschema\"]\n        )\n        assert other_schema not in results[0].node.compiled_code\n        assert unique_schema in results[0].node.compiled_code\n\n        assert len(results) == 1\n\n\nclass TestRunDeferStateChangedModel(BaseDeferState):\n    def test_run_defer_state_changed_model(self, project):\n        self.run_and_save_state(project.project_root)\n\n        # change \"view_model\"\n        write_file(changed_view_model_sql, \"models\", \"view_model.sql\")\n\n        # the sql here is just wrong, so it should fail\n        run_dbt(\n            [\"run\", \"-m\", \"view_model\", \"--state\", \"state\", \"--defer\", \"--target\", \"otherschema\"],\n            expect_pass=False,\n        )\n        # but this should work since we just use the old happy model\n        run_dbt(\n            [\"run\", \"-m\", \"table_model\", \"--state\", \"state\", \"--defer\", \"--target\", \"otherschema\"],\n            expect_pass=True,\n        )\n\n        # change \"ephemeral_model\"\n        write_file(changed_ephemeral_model_sql, \"models\", \"ephemeral_model.sql\")\n        # this should fail because the table model refs a broken ephemeral\n        # model, which it should see\n        run_dbt(\n            [\"run\", \"-m\", \"table_model\", \"--state\", \"state\", \"--defer\", \"--target\", \"otherschema\"],\n            expect_pass=False,\n        )\n\n\nclass TestRunDeferStateIFFNotExists(BaseDeferState):\n    def test_run_defer_iff_not_exists(self, project, unique_schema, other_schema):\n        project.create_test_schema(other_schema)\n        self.run_and_save_state(project.project_root)\n\n        results = run_dbt([\"seed\", \"--target\", \"otherschema\"])\n        assert len(results) == 1\n        results = run_dbt([\"run\", \"--state\", \"state\", \"--defer\", \"--target\", \"otherschema\"])\n        assert len(results) == 2\n\n        # because the seed now exists in our \"other\" schema, we should prefer it over the one\n        # available from state\n        assert other_schema in results[0].node.compiled_code\n\n        # this time with --favor-state: even though the seed now exists in our \"other\" schema,\n        # we should still favor the one available from state\n        results = run_dbt(\n            [\"run\", \"--state\", \"state\", \"--defer\", \"--favor-state\", \"--target\", \"otherschema\"]\n        )\n        assert len(results) == 2\n        assert other_schema not in results[0].node.compiled_code\n\n        # again with --favor-state, but this time select both the seed and the view\n        # because the seed is also selected, the view should select from the seed in our schema ('other_schema')\n        results = run_dbt(\n            [\n                \"build\",\n                \"--state\",\n                \"state\",\n                \"--select\",\n                \"seed view_model\",\n                \"--resource-type\",\n                \"seed model\",\n                \"--defer\",\n                \"--favor-state\",\n                \"--target\",\n                \"otherschema\",\n            ]\n        )\n        assert len(results) == 2\n        assert other_schema in results[1].node.compiled_code\n\n\nclass TestDeferStateDeletedUpstream(BaseDeferState):\n    def test_run_defer_deleted_upstream(self, project, unique_schema, other_schema):\n        project.create_test_schema(other_schema)\n        self.run_and_save_state(project.project_root)\n\n        # remove \"ephemeral_model\" + change \"table_model\"\n        rm_file(\"models\", \"ephemeral_model.sql\")\n        write_file(changed_table_model_sql, \"models\", \"table_model.sql\")\n\n        # ephemeral_model is now gone. previously this caused a\n        # keyerror (dbt#2875), now it should pass\n        run_dbt(\n            [\"run\", \"-m\", \"view_model\", \"--state\", \"state\", \"--defer\", \"--target\", \"otherschema\"],\n            expect_pass=True,\n        )\n\n        # despite deferral, we should use models just created in our schema\n        results = run_dbt([\"test\", \"--state\", \"state\", \"--defer\", \"--target\", \"otherschema\"])\n        assert other_schema in results[0].node.compiled_code\n\n        # this time with --favor-state: prefer the models in the \"other\" schema, even though they exist in ours\n        run_dbt(\n            [\n                \"run\",\n                \"-m\",\n                \"view_model\",\n                \"--state\",\n                \"state\",\n                \"--defer\",\n                \"--favor-state\",\n                \"--target\",\n                \"otherschema\",\n            ],\n            expect_pass=True,\n        )\n        results = run_dbt([\"test\", \"--state\", \"state\", \"--defer\", \"--favor-state\"])\n        assert other_schema not in results[0].node.compiled_code\n\n\nclass TestDeferStateFlag(BaseDeferState):\n    def test_defer_state_flag(self, project, unique_schema, other_schema):\n        project.create_test_schema(other_schema)\n\n        # test that state deferral works correctly\n        run_dbt([\"compile\", \"--target-path\", \"target_compile\"])\n        write_file(view_model_now_table_sql, \"models\", \"table_model.sql\")\n\n        results = run_dbt([\"ls\", \"--select\", \"state:modified\", \"--state\", \"target_compile\"])\n        assert results == [\"test.table_model\"]\n\n        run_dbt([\"seed\", \"--target\", \"otherschema\", \"--target-path\", \"target_otherschema\"])\n\n        # this will fail because we haven't loaded the seed in the default schema\n        run_dbt(\n            [\n                \"run\",\n                \"--select\",\n                \"state:modified\",\n                \"--defer\",\n                \"--state\",\n                \"target_compile\",\n                \"--favor-state\",\n            ],\n            expect_pass=False,\n        )\n\n        # Test that retry of a defer command works\n        run_dbt([\"retry\"], expect_pass=False)\n\n        # this will fail because we haven't passed in --state\n        with pytest.raises(\n            DbtRuntimeError, match=\"Got a state selector method, but no comparison manifest\"\n        ):\n            run_dbt(\n                [\n                    \"run\",\n                    \"--select\",\n                    \"state:modified\",\n                    \"--defer\",\n                    \"--defer-state\",\n                    \"target_otherschema\",\n                    \"--favor-state\",\n                ],\n                expect_pass=False,\n            )\n\n        # this will succeed because we've loaded the seed in other schema and are successfully deferring to it instead\n        results = run_dbt(\n            [\n                \"run\",\n                \"--select\",\n                \"state:modified\",\n                \"--defer\",\n                \"--state\",\n                \"target_compile\",\n                \"--defer-state\",\n                \"target_otherschema\",\n                \"--favor-state\",\n            ]\n        )\n\n        assert len(results.results) == 1\n        assert results.results[0].status == RunStatus.Success\n        assert results.results[0].node.name == \"table_model\"\n        assert results.results[0].adapter_response[\"rows_affected\"] == 2\n\n\nclass TestFunctionDeferral(BaseDeferState):\n    @pytest.fixture(scope=\"class\")\n    def functions(self) -> Dict[str, str]:\n        return {\n            \"double_it.sql\": double_it_sql,\n            \"double_it.yml\": double_it_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            **self._models,\n            \"double_it_model.sql\": \"select {{ function('double_it') }}(1) as double_it\",\n        }\n\n    def test_build_with_other_schema_defer(self, project, other_schema):\n        project.create_test_schema(other_schema)\n        run_dbt([\"build\"])\n        self.copy_state(project.project_root)\n\n        result = run_dbt(\n            [\n                \"run\",\n                \"-s\",\n                \"double_it_model\",\n                \"--state\",\n                \"state\",\n                \"--defer\",\n                \"--target\",\n                \"otherschema\",\n            ]\n        )\n        assert len(result.results) == 1\n        assert result.results[0].node.name == \"double_it_model\"\n"
  },
  {
    "path": "tests/functional/defer_state/test_group_updates.py",
    "content": "import os\n\nimport pytest\n\nfrom dbt.exceptions import ParsingError\nfrom dbt.tests.util import copy_file, run_dbt, write_file\nfrom tests.functional.defer_state.fixtures import (\n    group_modified_fail_schema_yml,\n    group_modified_schema_yml,\n    group_schema_yml,\n    model_1_sql,\n    model_2_sql,\n    modified_model_1_sql,\n    modified_model_2_sql,\n    seed_csv,\n)\n\n\nclass GroupSetup:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_1.sql\": model_1_sql,\n            \"model_2.sql\": model_2_sql,\n            \"schema.yml\": group_schema_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\n            \"seed.csv\": seed_csv,\n        }\n\n    def group_setup(self):\n        # save initial state\n        run_dbt([\"seed\"])\n        results = run_dbt([\"compile\"])\n\n        # add sanity checks for first result\n        assert len(results) == 3\n        seed_result = results[0].node\n        assert seed_result.unique_id == \"seed.test.seed\"\n        model_1_result = results[1].node\n        assert model_1_result.unique_id == \"model.test.model_1\"\n        assert model_1_result.group == \"finance\"\n        model_2_result = results[2].node\n        assert model_2_result.unique_id == \"model.test.model_2\"\n        assert model_2_result.group == \"finance\"\n\n\nclass TestFullyModifiedGroups(GroupSetup):\n    def test_changed_groups(self, project):\n        self.group_setup()\n\n        # copy manifest.json to \"state\" directory\n        os.makedirs(\"state\")\n        target_path = os.path.join(project.project_root, \"target\")\n        copy_file(target_path, \"manifest.json\", project.project_root, [\"state\", \"manifest.json\"])\n\n        # update group name, modify model so it gets picked up\n        write_file(modified_model_1_sql, \"models\", \"model_1.sql\")\n        write_file(modified_model_2_sql, \"models\", \"model_2.sql\")\n        write_file(group_modified_schema_yml, \"models\", \"schema.yml\")\n\n        # this test is flaky if you don't clean first before the build\n        run_dbt([\"clean\"])\n        # only thing in results should be model_1\n        results = run_dbt([\"build\", \"-s\", \"state:modified\", \"--defer\", \"--state\", \"./state\"])\n\n        assert len(results) == 2\n        model_1_result = results[0].node\n        assert model_1_result.unique_id == \"model.test.model_1\"\n        assert model_1_result.group == \"accounting\"  # new group name!\n        model_2_result = results[1].node\n        assert model_2_result.unique_id == \"model.test.model_2\"\n        assert model_2_result.group == \"accounting\"  # new group name!\n\n\nclass TestPartiallyModifiedGroups(GroupSetup):\n    def test_changed_groups(self, project):\n        self.group_setup()\n\n        # copy manifest.json to \"state\" directory\n        os.makedirs(\"state\")\n        target_path = os.path.join(project.project_root, \"target\")\n        copy_file(target_path, \"manifest.json\", project.project_root, [\"state\", \"manifest.json\"])\n\n        # update group name, modify model so it gets picked up\n        write_file(modified_model_1_sql, \"models\", \"model_1.sql\")\n        write_file(group_modified_schema_yml, \"models\", \"schema.yml\")\n\n        # this test is flaky if you don't clean first before the build\n        run_dbt([\"clean\"])\n        # only thing in results should be model_1\n        results = run_dbt([\"build\", \"-s\", \"state:modified\", \"--defer\", \"--state\", \"./state\"])\n\n        assert len(results) == 1\n        model_1_result = results[0].node\n        assert model_1_result.unique_id == \"model.test.model_1\"\n        assert model_1_result.group == \"accounting\"  # new group name!\n\n\nclass TestBadGroups(GroupSetup):\n    def test_changed_groups(self, project):\n        self.group_setup()\n\n        # copy manifest.json to \"state\" directory\n        os.makedirs(\"state\")\n        target_path = os.path.join(project.project_root, \"target\")\n        copy_file(target_path, \"manifest.json\", project.project_root, [\"state\", \"manifest.json\"])\n\n        # update group with invalid name, modify model so it gets picked up\n        write_file(modified_model_1_sql, \"models\", \"model_1.sql\")\n        write_file(group_modified_fail_schema_yml, \"models\", \"schema.yml\")\n\n        # this test is flaky if you don't clean first before the build\n        run_dbt([\"clean\"])\n        with pytest.raises(ParsingError, match=\"Invalid group 'accounting'\"):\n            run_dbt([\"build\", \"-s\", \"state:modified\", \"--defer\", \"--state\", \"./state\"])\n"
  },
  {
    "path": "tests/functional/defer_state/test_modified_state.py",
    "content": "import os\nimport random\nimport shutil\nimport string\n\nimport pytest\n\nfrom dbt.exceptions import CompilationError, ContractBreakingChangeError\nfrom dbt.tests.util import (\n    get_manifest,\n    rm_file,\n    run_dbt,\n    run_dbt_and_capture,\n    update_config_file,\n    write_file,\n)\nfrom tests.functional.defer_state.fixtures import (\n    constraint_schema_yml,\n    contract_schema_yml,\n    disabled_contract_schema_yml,\n    disabled_unenforced_contract_schema_yml,\n    disabled_versioned_contract_schema_yml,\n    disabled_versioned_unenforced_contract_schema_yml,\n    ephemeral_model_sql,\n    exposures_yml,\n    infinite_macros_sql,\n    macros_sql,\n    metricflow_time_spine_sql,\n    modified_column_constraint_schema_yml,\n    modified_contract_schema_yml,\n    modified_model_constraint_schema_yml,\n    modified_semantic_model_schema_yml,\n    no_contract_schema_yml,\n    numeric_precision_contract_schema_yml,\n    numeric_precision_increased_contract_schema_yml,\n    schema_yml,\n    seed_csv,\n    semantic_model_schema_yml,\n    table_model_now_incremental_sql,\n    table_model_now_view_sql,\n    table_model_sql,\n    unenforced_contract_schema_yml,\n    varchar_size_contract_schema_yml,\n    varchar_size_increased_contract_schema_yml,\n    varchar_size_lowercase_increased_contract_schema_yml,\n    varchar_size_unversioned_contract_schema_yml,\n    varchar_size_unversioned_increased_contract_schema_yml,\n    varchar_size_uppercase_contract_schema_yml,\n    versioned_contract_schema_yml,\n    versioned_modified_contract_schema_yml,\n    versioned_no_contract_schema_yml,\n    versioned_unenforced_contract_schema_yml,\n    view_model_now_table_sql,\n    view_model_sql,\n)\n\n\nclass BaseModifiedState:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"table_model.sql\": table_model_sql,\n            \"view_model.sql\": view_model_sql,\n            \"ephemeral_model.sql\": ephemeral_model_sql,\n            \"schema.yml\": schema_yml,\n            \"exposures.yml\": exposures_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\n            \"macros.sql\": macros_sql,\n            \"infinite_macros.sql\": infinite_macros_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\n            \"seed.csv\": seed_csv,\n        }\n\n    @property\n    def project_config_update(self):\n        return {\n            \"seeds\": {\n                \"test\": {\n                    \"quote_columns\": False,\n                }\n            }\n        }\n\n    def copy_state(self):\n        if not os.path.exists(\"state\"):\n            os.makedirs(\"state\")\n        shutil.copyfile(\"target/manifest.json\", \"state/manifest.json\")\n\n    def run_and_save_state(self):\n        run_dbt([\"seed\"])\n        run_dbt([\"run\"])\n        self.copy_state()\n\n\nclass TestChangedSeedContents(BaseModifiedState):\n    def test_changed_seed_contents_state(self, project):\n        self.run_and_save_state()\n        results = run_dbt(\n            [\"ls\", \"--resource-type\", \"seed\", \"--select\", \"state:modified\", \"--state\", \"./state\"],\n            expect_pass=True,\n        )\n        assert len(results) == 0\n\n        results = run_dbt(\n            [\n                \"ls\",\n                \"--resource-type\",\n                \"seed\",\n                \"--exclude\",\n                \"state:unmodified\",\n                \"--state\",\n                \"./state\",\n            ],\n            expect_pass=True,\n        )\n        assert len(results) == 0\n\n        results = run_dbt(\n            [\n                \"ls\",\n                \"--resource-type\",\n                \"seed\",\n                \"--select\",\n                \"state:unmodified\",\n                \"--state\",\n                \"./state\",\n            ],\n            expect_pass=True,\n        )\n        assert len(results) == 1\n\n        # add a new row to the seed\n        changed_seed_contents = seed_csv + \"\\n\" + \"3,carl\"\n        write_file(changed_seed_contents, \"seeds\", \"seed.csv\")\n\n        results = run_dbt(\n            [\"ls\", \"--resource-type\", \"seed\", \"--select\", \"state:modified\", \"--state\", \"./state\"]\n        )\n        assert len(results) == 1\n        assert results[0] == \"test.seed\"\n\n        results = run_dbt(\n            [\n                \"ls\",\n                \"--resource-type\",\n                \"seed\",\n                \"--exclude\",\n                \"state:unmodified\",\n                \"--state\",\n                \"./state\",\n            ]\n        )\n        assert len(results) == 1\n        assert results[0] == \"test.seed\"\n\n        results = run_dbt(\n            [\"ls\", \"--resource-type\", \"seed\", \"--select\", \"state:unmodified\", \"--state\", \"./state\"]\n        )\n        assert len(results) == 0\n\n        results = run_dbt([\"ls\", \"--select\", \"state:modified\", \"--state\", \"./state\"])\n        assert len(results) == 1\n        assert results[0] == \"test.seed\"\n\n        results = run_dbt([\"ls\", \"--exclude\", \"state:unmodified\", \"--state\", \"./state\"])\n        assert len(results) == 1\n        assert results[0] == \"test.seed\"\n\n        results = run_dbt([\"ls\", \"--select\", \"state:unmodified\", \"--state\", \"./state\"])\n        assert len(results) == 6\n\n        results = run_dbt([\"ls\", \"--select\", \"state:modified+\", \"--state\", \"./state\"])\n        assert len(results) == 7\n        assert set(results) == {\n            \"test.seed\",\n            \"test.table_model\",\n            \"test.view_model\",\n            \"test.ephemeral_model\",\n            \"test.not_null_view_model_id\",\n            \"test.unique_view_model_id\",\n            \"exposure:test.my_exposure\",\n        }\n\n        results = run_dbt([\"ls\", \"--select\", \"state:unmodified+\", \"--state\", \"./state\"])\n        assert len(results) == 6\n        assert set(results) == {\n            \"test.table_model\",\n            \"test.view_model\",\n            \"test.ephemeral_model\",\n            \"test.not_null_view_model_id\",\n            \"test.unique_view_model_id\",\n            \"exposure:test.my_exposure\",\n        }\n\n        shutil.rmtree(\"./state\")\n        self.copy_state()\n\n        # make a very big seed\n        # assume each line is ~2 bytes + len(name)\n        target_size = 1 * 1024 * 1024\n        line_size = 64\n        num_lines = target_size // line_size\n        maxlines = num_lines + 4\n        seed_lines = [seed_csv]\n        for idx in range(4, maxlines):\n            value = \"\".join(random.choices(string.ascii_letters, k=62))\n            seed_lines.append(f\"{idx},{value}\")\n        seed_contents = \"\\n\".join(seed_lines)\n        write_file(seed_contents, \"seeds\", \"seed.csv\")\n\n        # now if we run again, we should get a warning\n        results = run_dbt(\n            [\"ls\", \"--resource-type\", \"seed\", \"--select\", \"state:modified\", \"--state\", \"./state\"]\n        )\n        assert len(results) == 1\n        assert results[0] == \"test.seed\"\n\n        with pytest.raises(CompilationError) as exc:\n            run_dbt(\n                [\n                    \"--warn-error\",\n                    \"ls\",\n                    \"--resource-type\",\n                    \"seed\",\n                    \"--select\",\n                    \"state:modified\",\n                    \"--state\",\n                    \"./state\",\n                ]\n            )\n        assert \">1MB\" in str(exc.value)\n\n        # now check if unmodified returns none\n        results = run_dbt(\n            [\"ls\", \"--resource-type\", \"seed\", \"--select\", \"state:unmodified\", \"--state\", \"./state\"]\n        )\n        assert len(results) == 0\n\n        shutil.rmtree(\"./state\")\n        self.copy_state()\n\n        # once it\"s in path mode, we don\"t mark it as modified if it changes\n        write_file(seed_contents + \"\\n1,test\", \"seeds\", \"seed.csv\")\n\n        results = run_dbt(\n            [\"ls\", \"--resource-type\", \"seed\", \"--select\", \"state:modified\", \"--state\", \"./state\"],\n            expect_pass=True,\n        )\n        assert len(results) == 0\n\n        results = run_dbt(\n            [\n                \"ls\",\n                \"--resource-type\",\n                \"seed\",\n                \"--exclude\",\n                \"state:unmodified\",\n                \"--state\",\n                \"./state\",\n            ],\n            expect_pass=True,\n        )\n        assert len(results) == 0\n\n        results = run_dbt(\n            [\n                \"ls\",\n                \"--resource-type\",\n                \"seed\",\n                \"--select\",\n                \"state:unmodified\",\n                \"--state\",\n                \"./state\",\n            ],\n            expect_pass=True,\n        )\n        assert len(results) == 1\n\n\nclass TestChangedSeedConfig(BaseModifiedState):\n    def test_changed_seed_config(self, project):\n        self.run_and_save_state()\n        results = run_dbt(\n            [\"ls\", \"--resource-type\", \"seed\", \"--select\", \"state:modified\", \"--state\", \"./state\"],\n            expect_pass=True,\n        )\n        assert len(results) == 0\n\n        results = run_dbt(\n            [\n                \"ls\",\n                \"--resource-type\",\n                \"seed\",\n                \"--exclude\",\n                \"state:unmodified\",\n                \"--state\",\n                \"./state\",\n            ],\n            expect_pass=True,\n        )\n        assert len(results) == 0\n\n        results = run_dbt(\n            [\n                \"ls\",\n                \"--resource-type\",\n                \"seed\",\n                \"--select\",\n                \"state:unmodified\",\n                \"--state\",\n                \"./state\",\n            ],\n            expect_pass=True,\n        )\n        assert len(results) == 1\n\n        update_config_file({\"seeds\": {\"test\": {\"quote_columns\": False}}}, \"dbt_project.yml\")\n\n        # quoting change -> seed changed\n        results = run_dbt(\n            [\"ls\", \"--resource-type\", \"seed\", \"--select\", \"state:modified\", \"--state\", \"./state\"]\n        )\n        assert len(results) == 1\n        assert results[0] == \"test.seed\"\n\n        results = run_dbt(\n            [\n                \"ls\",\n                \"--resource-type\",\n                \"seed\",\n                \"--exclude\",\n                \"state:unmodified\",\n                \"--state\",\n                \"./state\",\n            ]\n        )\n        assert len(results) == 1\n        assert results[0] == \"test.seed\"\n\n        results = run_dbt(\n            [\"ls\", \"--resource-type\", \"seed\", \"--select\", \"state:unmodified\", \"--state\", \"./state\"]\n        )\n        assert len(results) == 0\n\n\nclass TestUnrenderedConfigSame(BaseModifiedState):\n    def test_unrendered_config_same(self, project):\n        self.run_and_save_state()\n        results = run_dbt(\n            [\"ls\", \"--resource-type\", \"model\", \"--select\", \"state:modified\", \"--state\", \"./state\"],\n            expect_pass=True,\n        )\n        assert len(results) == 0\n\n        results = run_dbt(\n            [\n                \"ls\",\n                \"--resource-type\",\n                \"model\",\n                \"--exclude\",\n                \"state:unmodified\",\n                \"--state\",\n                \"./state\",\n            ],\n            expect_pass=True,\n        )\n        assert len(results) == 0\n\n        results = run_dbt(\n            [\n                \"ls\",\n                \"--resource-type\",\n                \"model\",\n                \"--select\",\n                \"state:unmodified\",\n                \"--state\",\n                \"./state\",\n            ],\n            expect_pass=True,\n        )\n        assert len(results) == 3\n\n        # although this is the default value, dbt will recognize it as a change\n        # for previously-unconfigured models, because it\"s been explicitly set\n        update_config_file({\"models\": {\"test\": {\"materialized\": \"view\"}}}, \"dbt_project.yml\")\n        results = run_dbt(\n            [\"ls\", \"--resource-type\", \"model\", \"--select\", \"state:modified\", \"--state\", \"./state\"]\n        )\n        assert len(results) == 1\n        assert results[0] == \"test.view_model\"\n\n        # converse of above statement\n        results = run_dbt(\n            [\n                \"ls\",\n                \"--resource-type\",\n                \"model\",\n                \"--exclude\",\n                \"state:unmodified\",\n                \"--state\",\n                \"./state\",\n            ]\n        )\n        assert len(results) == 1\n        assert results[0] == \"test.view_model\"\n\n        results = run_dbt(\n            [\n                \"ls\",\n                \"--resource-type\",\n                \"model\",\n                \"--select\",\n                \"state:unmodified\",\n                \"--state\",\n                \"./state\",\n            ]\n        )\n        assert len(results) == 2\n        assert set(results) == {\n            \"test.table_model\",\n            \"test.ephemeral_model\",\n        }\n\n\nclass TestChangedModelContents(BaseModifiedState):\n    def test_changed_model_contents(self, project):\n        self.run_and_save_state()\n        results = run_dbt([\"run\", \"--models\", \"state:modified\", \"--state\", \"./state\"])\n        assert len(results) == 0\n\n        table_model_update = \"\"\"\n        {{ config(materialized=\"table\") }}\n\n        select * from {{ ref(\"seed\") }}\n        \"\"\"\n\n        write_file(table_model_update, \"models\", \"table_model.sql\")\n\n        results = run_dbt([\"run\", \"--models\", \"state:modified\", \"--state\", \"./state\"])\n        assert len(results) == 1\n        assert results[0].node.name == \"table_model\"\n\n        results = run_dbt([\"run\", \"--exclude\", \"state:unmodified\", \"--state\", \"./state\"])\n        assert len(results) == 1\n        assert results[0].node.name == \"table_model\"\n\n\nclass TestNewMacro(BaseModifiedState):\n    def test_new_macro(self, project):\n        self.run_and_save_state()\n\n        new_macro = \"\"\"\n            {% macro my_other_macro() %}\n            {% endmacro %}\n        \"\"\"\n\n        # add a new macro to a new file\n        write_file(new_macro, \"macros\", \"second_macro.sql\")\n\n        results = run_dbt([\"run\", \"--models\", \"state:modified\", \"--state\", \"./state\"])\n        assert len(results) == 0\n\n        os.remove(\"macros/second_macro.sql\")\n        # add a new macro to the existing file\n        with open(\"macros/macros.sql\", \"a\") as fp:\n            fp.write(new_macro)\n\n        results = run_dbt([\"run\", \"--models\", \"state:modified\", \"--state\", \"./state\"])\n        assert len(results) == 0\n\n        results = run_dbt([\"run\", \"--exclude\", \"state:unmodified\", \"--state\", \"./state\"])\n        assert len(results) == 0\n\n\nclass TestChangedMacroContents(BaseModifiedState):\n    def test_changed_macro_contents(self, project):\n        self.run_and_save_state()\n\n        # modify an existing macro\n        updated_macro = \"\"\"\n        {% macro my_macro() %}\n            {% do log(\"in a macro\", info=True) %}\n        {% endmacro %}\n        \"\"\"\n        write_file(updated_macro, \"macros\", \"macros.sql\")\n\n        # table_model calls this macro\n        results = run_dbt([\"run\", \"--models\", \"state:modified\", \"--state\", \"./state\"])\n        assert len(results) == 1\n\n        results = run_dbt([\"run\", \"--exclude\", \"state:unmodified\", \"--state\", \"./state\"])\n        assert len(results) == 1\n\n\nclass TestChangedExposure(BaseModifiedState):\n    def test_changed_exposure(self, project):\n        self.run_and_save_state()\n\n        # add an \"owner.name\" to existing exposure\n        updated_exposure = exposures_yml + \"\\n      name: John Doe\\n\"\n        write_file(updated_exposure, \"models\", \"exposures.yml\")\n\n        results = run_dbt([\"run\", \"--models\", \"+state:modified\", \"--state\", \"./state\"])\n        assert len(results) == 1\n        assert results[0].node.name == \"view_model\"\n\n        results = run_dbt([\"run\", \"--exclude\", \"state:unmodified\", \"--state\", \"./state\"])\n        assert len(results) == 0\n\n\nclass TestChangedContractUnversioned(BaseModifiedState):\n    MODEL_UNIQUE_ID = \"model.test.table_model\"\n    CONTRACT_SCHEMA_YML = contract_schema_yml\n    MODIFIED_SCHEMA_YML = modified_contract_schema_yml\n    UNENFORCED_SCHEMA_YML = unenforced_contract_schema_yml\n    NO_CONTRACT_SCHEMA_YML = no_contract_schema_yml\n\n    def test_changed_contract(self, project):\n        self.run_and_save_state()\n\n        # update contract for table_model\n        write_file(self.CONTRACT_SCHEMA_YML, \"models\", \"schema.yml\")\n\n        # This will find the table_model node modified both through a config change\n        # and by a non-breaking change to contract: true\n        results = run_dbt([\"run\", \"--models\", \"state:modified\", \"--state\", \"./state\"])\n        assert len(results) == 1\n        assert results[0].node.name == \"table_model\"\n\n        results = run_dbt([\"run\", \"--exclude\", \"state:unmodified\", \"--state\", \"./state\"])\n        assert len(results) == 1\n        assert results[0].node.name == \"table_model\"\n\n        manifest = get_manifest(project.project_root)\n        model_unique_id = self.MODEL_UNIQUE_ID\n        model = manifest.nodes[model_unique_id]\n        expected_unrendered_config = {\"contract\": {\"enforced\": True}, \"materialized\": \"table\"}\n        assert model.unrendered_config == expected_unrendered_config\n\n        # Run it again with \"state:modified:contract\", still finds modified due to contract: true\n        results = run_dbt([\"run\", \"--models\", \"state:modified.contract\", \"--state\", \"./state\"])\n        assert len(results) == 1\n        manifest = get_manifest(project.project_root)\n        model = manifest.nodes[model_unique_id]\n        first_contract_checksum = model.contract.checksum\n        assert first_contract_checksum\n        # save a new state\n        self.copy_state()\n\n        # This should raise because a column name has changed\n        write_file(self.MODIFIED_SCHEMA_YML, \"models\", \"schema.yml\")\n        results = run_dbt([\"run\"], expect_pass=False)\n        assert len(results) == 2\n        manifest = get_manifest(project.project_root)\n        model = manifest.nodes[model_unique_id]\n        second_contract_checksum = model.contract.checksum\n        # double check different contract_checksums\n        assert first_contract_checksum != second_contract_checksum\n\n        _, logs = run_dbt_and_capture(\n            [\"run\", \"--models\", \"state:modified.contract\", \"--state\", \"./state\"], expect_pass=False\n        )\n        expected_error = \"This model has an enforced contract that failed.\"\n        expected_warning = \"While comparing to previous project state, dbt detected a breaking change to an unversioned model\"\n        expected_change = \"Please ensure the name, data_type, and number of columns in your contract match the columns in your model's definition\"\n        assert expected_error in logs\n        assert expected_warning in logs\n        assert expected_change in logs\n\n        # Go back to schema file without contract. Should throw a warning.\n        write_file(self.NO_CONTRACT_SCHEMA_YML, \"models\", \"schema.yml\")\n        _, logs = run_dbt_and_capture(\n            [\"run\", \"--models\", \"state:modified.contract\", \"--state\", \"./state\"]\n        )\n        expected_warning = \"While comparing to previous project state, dbt detected a breaking change to an unversioned model\"\n        expected_change = \"Contract enforcement was removed\"\n\n        # Now unenforce the contract. Should throw a warning - force warning into an error.\n        write_file(self.UNENFORCED_SCHEMA_YML, \"models\", \"schema.yml\")\n        with pytest.raises(CompilationError):\n            _, logs = run_dbt_and_capture(\n                [\n                    \"--warn-error\",\n                    \"run\",\n                    \"--models\",\n                    \"state:modified.contract\",\n                    \"--state\",\n                    \"./state\",\n                ]\n            )\n            expected_warning = \"While comparing to previous project state, dbt detected a breaking change to an unversioned model\"\n            expected_change = \"Contract enforcement was removed\"\n\n\nclass TestChangedContractVersioned(BaseModifiedState):\n    MODEL_UNIQUE_ID = \"model.test.table_model.v1\"\n    CONTRACT_SCHEMA_YML = versioned_contract_schema_yml\n    MODIFIED_SCHEMA_YML = versioned_modified_contract_schema_yml\n    UNENFORCED_SCHEMA_YML = versioned_unenforced_contract_schema_yml\n    NO_CONTRACT_SCHEMA_YML = versioned_no_contract_schema_yml\n\n    def test_changed_contract_versioned(self, project):\n        self.run_and_save_state()\n\n        # update contract for table_model\n        write_file(self.CONTRACT_SCHEMA_YML, \"models\", \"schema.yml\")\n\n        # This will find the table_model node modified both through a config change\n        # and by a non-breaking change to contract: true\n        results = run_dbt([\"run\", \"--models\", \"state:modified\", \"--state\", \"./state\"])\n        assert len(results) == 1\n        assert results[0].node.name == \"table_model\"\n\n        results = run_dbt([\"run\", \"--exclude\", \"state:unmodified\", \"--state\", \"./state\"])\n        assert len(results) == 1\n        assert results[0].node.name == \"table_model\"\n\n        manifest = get_manifest(project.project_root)\n        model_unique_id = self.MODEL_UNIQUE_ID\n        model = manifest.nodes[model_unique_id]\n        expected_unrendered_config = {\"contract\": {\"enforced\": True}, \"materialized\": \"table\"}\n        assert model.unrendered_config == expected_unrendered_config\n\n        # Run it again with \"state:modified:contract\", still finds modified due to contract: true\n        results = run_dbt([\"run\", \"--models\", \"state:modified.contract\", \"--state\", \"./state\"])\n        assert len(results) == 1\n        manifest = get_manifest(project.project_root)\n        model = manifest.nodes[model_unique_id]\n        first_contract_checksum = model.contract.checksum\n        assert first_contract_checksum\n        # save a new state\n        self.copy_state()\n\n        # This should raise because a column name has changed\n        write_file(self.MODIFIED_SCHEMA_YML, \"models\", \"schema.yml\")\n        results = run_dbt([\"run\"], expect_pass=False)\n        assert len(results) == 2\n        manifest = get_manifest(project.project_root)\n        model = manifest.nodes[model_unique_id]\n        second_contract_checksum = model.contract.checksum\n        # double check different contract_checksums\n        assert first_contract_checksum != second_contract_checksum\n        with pytest.raises(ContractBreakingChangeError):\n            results = run_dbt([\"run\", \"--models\", \"state:modified.contract\", \"--state\", \"./state\"])\n\n        # Go back to schema file without contract. Should raise an error.\n        write_file(self.NO_CONTRACT_SCHEMA_YML, \"models\", \"schema.yml\")\n        with pytest.raises(ContractBreakingChangeError):\n            results = run_dbt([\"run\", \"--models\", \"state:modified.contract\", \"--state\", \"./state\"])\n\n        # Now unenforce the contract. Should raise an error.\n        write_file(self.UNENFORCED_SCHEMA_YML, \"models\", \"schema.yml\")\n        with pytest.raises(ContractBreakingChangeError):\n            results = run_dbt([\"run\", \"--models\", \"state:modified.contract\", \"--state\", \"./state\"])\n\n\nclass TestDeleteUnversionedContractedModel(BaseModifiedState):\n    MODEL_UNIQUE_ID = \"model.test.table_model\"\n    CONTRACT_SCHEMA_YML = contract_schema_yml\n\n    def test_delete_unversioned_contracted_model(self, project):\n        # ensure table_model is contracted\n        write_file(self.CONTRACT_SCHEMA_YML, \"models\", \"schema.yml\")\n        self.run_and_save_state()\n\n        # delete versioned contracted model\n        rm_file(project.project_root, \"models\", \"table_model.sql\")\n\n        # since the models are unversioned, they raise a warning but not an error\n        _, logs = run_dbt_and_capture(\n            [\"run\", \"--models\", \"state:modified.contract\", \"--state\", \"./state\"]\n        )\n\n        expected_warning = \"While comparing to previous project state, dbt detected a breaking change to an unversioned model\"\n        expected_change = \"Contracted model 'model.test.table_model' was deleted or renamed\"\n        assert expected_warning in logs\n        assert expected_change in logs\n\n        # the same but for general-purpose state:modified\n        _, logs = run_dbt_and_capture(\n            [\"run\", \"--models\", \"state:modified.contract\", \"--state\", \"./state\"]\n        )\n        expected_warning = \"While comparing to previous project state, dbt detected a breaking change to an unversioned model\"\n        expected_change = \"Contracted model 'model.test.table_model' was deleted or renamed\"\n        assert expected_warning in logs\n        assert expected_change in logs\n\n\nclass TestDeleteVersionedContractedModel(BaseModifiedState):\n    MODEL_UNIQUE_ID = \"model.test.table_model.v1\"\n    CONTRACT_SCHEMA_YML = versioned_contract_schema_yml\n\n    def test_delete_versioned_contracted_model(self, project):\n        # ensure table_model is versioned + contracted\n        write_file(self.CONTRACT_SCHEMA_YML, \"models\", \"schema.yml\")\n        self.run_and_save_state()\n\n        # delete versioned contracted model\n        rm_file(project.project_root, \"models\", \"table_model.sql\")\n\n        # since the models are versioned, they raise an error\n        with pytest.raises(ContractBreakingChangeError) as e:\n            run_dbt([\"run\", \"--models\", \"state:modified.contract\", \"--state\", \"./state\"])\n\n        assert \"Contracted model 'model.test.table_model.v1' was deleted or renamed.\" in str(\n            e.value\n        )\n\n        # the same but for general-purpose state:modified\n        with pytest.raises(ContractBreakingChangeError) as e:\n            run_dbt([\"run\", \"--models\", \"state:modified\", \"--state\", \"./state\"])\n\n        assert \"Contracted model 'model.test.table_model.v1' was deleted or renamed.\" in str(\n            e.value\n        )\n\n\nclass TestDisableUnversionedContractedModel(BaseModifiedState):\n    MODEL_UNIQUE_ID = \"model.test.table_model\"\n    CONTRACT_SCHEMA_YML = contract_schema_yml\n    DISABLED_CONTRACT_SCHEMA_YML = disabled_contract_schema_yml\n\n    def test_disable_unversioned_contracted_model(self, project):\n        # ensure table_model is contracted and enabled\n        write_file(self.CONTRACT_SCHEMA_YML, \"models\", \"schema.yml\")\n        self.run_and_save_state()\n\n        # disable unversioned + contracted model\n        write_file(self.DISABLED_CONTRACT_SCHEMA_YML, \"models\", \"schema.yml\")\n\n        # since the models are unversioned, they raise a warning but not an error\n        _, logs = run_dbt_and_capture(\n            [\"run\", \"--models\", \"state:modified.contract\", \"--state\", \"./state\"]\n        )\n\n        expected_warning = \"While comparing to previous project state, dbt detected a breaking change to an unversioned model\"\n        expected_change = \"Contracted model 'model.test.table_model' was disabled\"\n        assert expected_warning in logs\n        assert expected_change in logs\n\n\nclass TestDisableVersionedContractedModel(BaseModifiedState):\n    MODEL_UNIQUE_ID = \"model.test.table_model.v1\"\n    CONTRACT_SCHEMA_YML = versioned_contract_schema_yml\n    DISABLED_CONTRACT_SCHEMA_YML = disabled_versioned_contract_schema_yml\n\n    def test_disable_versioned_contracted_model(self, project):\n        # ensure table_model is versioned + contracted\n        write_file(self.CONTRACT_SCHEMA_YML, \"models\", \"schema.yml\")\n        self.run_and_save_state()\n\n        # disable versioned + contracted model\n        write_file(self.DISABLED_CONTRACT_SCHEMA_YML, \"models\", \"schema.yml\")\n\n        # since the models are versioned, they raise an error\n        with pytest.raises(ContractBreakingChangeError) as e:\n            run_dbt([\"run\", \"--models\", \"state:modified.contract\", \"--state\", \"./state\"])\n\n        assert \"Contracted model 'model.test.table_model.v1' was disabled.\" in str(e.value)\n\n\nclass TestDisableUnversionedUncontractedModel(BaseModifiedState):\n    MODEL_UNIQUE_ID = \"model.test.table_model\"\n    NO_CONTRACT_SCHEMA_YML = unenforced_contract_schema_yml\n    DISABLED_NO_CONTRACT_SCHEMA_YML = disabled_unenforced_contract_schema_yml\n\n    def test_delete_versioned_contracted_model(self, project):\n        # ensure table_model is not contracted\n        write_file(self.NO_CONTRACT_SCHEMA_YML, \"models\", \"schema.yml\")\n        self.run_and_save_state()\n\n        # disable uncontracted model\n        write_file(self.DISABLED_NO_CONTRACT_SCHEMA_YML, \"models\", \"schema.yml\")\n\n        # since the models are unversioned, no warning or error is raised\n        _, logs = run_dbt_and_capture(\n            [\"run\", \"--models\", \"state:modified.contract\", \"--state\", \"./state\"]\n        )\n\n        assert \"breaking change\" not in logs.lower()\n\n\nclass TestDisableVersionedUncontractedModel(BaseModifiedState):\n    MODEL_UNIQUE_ID = \"model.test.table_model.v1\"\n    NO_CONTRACT_SCHEMA_YML = versioned_unenforced_contract_schema_yml\n    DISABLED_NO_CONTRACT_SCHEMA_YML = disabled_versioned_unenforced_contract_schema_yml\n\n    def test_delete_versioned_contracted_model(self, project):\n        # ensure table_model is not contracted\n        write_file(self.NO_CONTRACT_SCHEMA_YML, \"models\", \"schema.yml\")\n        self.run_and_save_state()\n\n        # disable uncontracted model\n        write_file(self.DISABLED_NO_CONTRACT_SCHEMA_YML, \"models\", \"schema.yml\")\n\n        # since the models are unversioned, no warning or error is raised\n        run_dbt_and_capture([\"run\", \"--models\", \"state:modified.contract\", \"--state\", \"./state\"])\n\n\nclass TestChangedConstraintUnversioned(BaseModifiedState):\n    def test_changed_constraint(self, project):\n        self.run_and_save_state()\n\n        # update constraint for table_model\n        write_file(constraint_schema_yml, \"models\", \"schema.yml\")\n\n        # This will find the table_model node modified both through adding constraint\n        # and by a non-breaking change to contract: true\n        results = run_dbt([\"run\", \"--models\", \"state:modified\", \"--state\", \"./state\"])\n        assert len(results) == 1\n        assert results[0].node.name == \"table_model\"\n\n        results = run_dbt([\"run\", \"--exclude\", \"state:unmodified\", \"--state\", \"./state\"])\n        assert len(results) == 1\n        assert results[0].node.name == \"table_model\"\n\n        manifest = get_manifest(project.project_root)\n        model_unique_id = \"model.test.table_model\"\n        model = manifest.nodes[model_unique_id]\n        expected_unrendered_config = {\"contract\": {\"enforced\": True}, \"materialized\": \"table\"}\n        assert model.unrendered_config == expected_unrendered_config\n\n        # Run it again with \"state:modified:contract\", still finds modified due to contract: true\n        results = run_dbt([\"run\", \"--models\", \"state:modified.contract\", \"--state\", \"./state\"])\n        assert len(results) == 1\n        manifest = get_manifest(project.project_root)\n        model = manifest.nodes[model_unique_id]\n        first_contract_checksum = model.contract.checksum\n        assert first_contract_checksum\n        # save a new state\n        self.copy_state()\n\n        # This should raise because a column level constraint was removed\n        write_file(modified_column_constraint_schema_yml, \"models\", \"schema.yml\")\n        # we don't have a way to know this failed unless we have a previous state to refer to, so the run succeeds\n        results = run_dbt([\"run\"])\n        assert len(results) == 2\n        manifest = get_manifest(project.project_root)\n        model = manifest.nodes[model_unique_id]\n        second_contract_checksum = model.contract.checksum\n        # double check different contract_checksums\n        assert first_contract_checksum != second_contract_checksum\n        # since the models are unversioned, they raise a warning but not an error\n        _, logs = run_dbt_and_capture(\n            [\"run\", \"--models\", \"state:modified.contract\", \"--state\", \"./state\"]\n        )\n        expected_warning = \"While comparing to previous project state, dbt detected a breaking change to an unversioned model\"\n        expected_change = \"Enforced column level constraints were removed\"\n        assert expected_warning in logs\n        assert expected_change in logs\n\n        # This should raise because a model level constraint was removed (primary_key on id)\n        write_file(modified_model_constraint_schema_yml, \"models\", \"schema.yml\")\n        # we don't have a way to know this failed unless we have a previous state to refer to, so the run succeeds\n        results = run_dbt([\"run\"])\n        assert len(results) == 2\n        manifest = get_manifest(project.project_root)\n        model = manifest.nodes[model_unique_id]\n        second_contract_checksum = model.contract.checksum\n        # double check different contract_checksums\n        assert first_contract_checksum != second_contract_checksum\n        _, logs = run_dbt_and_capture(\n            [\"run\", \"--models\", \"state:modified.contract\", \"--state\", \"./state\"]\n        )\n        expected_warning = \"While comparing to previous project state, dbt detected a breaking change to an unversioned model\"\n        expected_change = \"Enforced model level constraints were removed\"\n        assert expected_warning in logs\n        assert expected_change in logs\n\n\nclass TestChangedMaterializationConstraint(BaseModifiedState):\n    def test_changed_materialization(self, project):\n        self.run_and_save_state()\n\n        # update constraint for table_model\n        write_file(constraint_schema_yml, \"models\", \"schema.yml\")\n\n        # This will find the table_model node modified both through adding constraint\n        # and by a non-breaking change to contract: true\n        results = run_dbt([\"run\", \"--models\", \"state:modified\", \"--state\", \"./state\"])\n        assert len(results) == 1\n        assert results[0].node.name == \"table_model\"\n\n        results = run_dbt([\"run\", \"--exclude\", \"state:unmodified\", \"--state\", \"./state\"])\n        assert len(results) == 1\n        assert results[0].node.name == \"table_model\"\n\n        manifest = get_manifest(project.project_root)\n        model_unique_id = \"model.test.table_model\"\n        model = manifest.nodes[model_unique_id]\n        expected_unrendered_config = {\"contract\": {\"enforced\": True}, \"materialized\": \"table\"}\n        assert model.unrendered_config == expected_unrendered_config\n\n        # Run it again with \"state:modified:contract\", still finds modified due to contract: true\n        results = run_dbt([\"run\", \"--models\", \"state:modified.contract\", \"--state\", \"./state\"])\n        assert len(results) == 1\n        manifest = get_manifest(project.project_root)\n        model = manifest.nodes[model_unique_id]\n        first_contract_checksum = model.contract.checksum\n        assert first_contract_checksum\n        # save a new state\n        self.copy_state()\n\n        # This should raise because materialization changed from table to view\n        write_file(table_model_now_view_sql, \"models\", \"table_model.sql\")\n        # we don't have a way to know this failed unless we have a previous state to refer to, so the run succeeds\n        results = run_dbt([\"run\"])\n        assert len(results) == 2\n        manifest = get_manifest(project.project_root)\n        model = manifest.nodes[model_unique_id]\n        second_contract_checksum = model.contract.checksum\n        # double check different contract_checksums\n        assert first_contract_checksum != second_contract_checksum\n        _, logs = run_dbt_and_capture(\n            [\"run\", \"--models\", \"state:modified.contract\", \"--state\", \"./state\"]\n        )\n        expected_warning = \"While comparing to previous project state, dbt detected a breaking change to an unversioned model\"\n        expected_change = \"Materialization changed with enforced constraints\"\n        assert expected_warning in logs\n        assert expected_change in logs\n\n        # This should not raise because materialization changed from table to incremental, both enforce constraints\n        write_file(table_model_now_incremental_sql, \"models\", \"table_model.sql\")\n        # we don't have a way to know this failed unless we have a previous state to refer to, so the run succeeds\n        results = run_dbt([\"run\"])\n        assert len(results) == 2\n\n        # This should pass because materialization changed from view to table which is the same as just adding new constraint, not breaking\n        write_file(view_model_now_table_sql, \"models\", \"view_model.sql\")\n        write_file(table_model_sql, \"models\", \"table_model.sql\")\n        results = run_dbt([\"run\"])\n        assert len(results) == 2\n        manifest = get_manifest(project.project_root)\n        model = manifest.nodes[model_unique_id]\n        second_contract_checksum = model.contract.checksum\n        # contract_checksums should be equal because we only save constraint related changes if the materialization is table/incremental\n        assert first_contract_checksum == second_contract_checksum\n        run_dbt([\"run\", \"--models\", \"state:modified.contract\", \"--state\", \"./state\"])\n        assert len(results) == 2\n\n\nmy_model_sql = \"\"\"\nselect 1 as id\n\"\"\"\n\nmodified_my_model_sql = \"\"\"\n-- a comment\nselect 1 as id\n\"\"\"\n\nmodified_my_model_non_breaking_sql = \"\"\"\n-- a comment\nselect 1 as id, 'blue' as color\n\"\"\"\n\nmy_model_yml = \"\"\"\nmodels:\n  - name: my_model\n    latest_version: 1\n    config:\n      contract:\n        enforced: true\n    columns:\n      - name: id\n        data_type: int\n    versions:\n      - v: 1\n\"\"\"\n\nmodified_my_model_yml = \"\"\"\nmodels:\n  - name: my_model\n    latest_version: 1\n    config:\n      contract:\n        enforced: true\n    columns:\n      - name: id\n        data_type: text\n    versions:\n      - v: 1\n\"\"\"\n\nmodified_my_model_non_breaking_yml = \"\"\"\nmodels:\n  - name: my_model\n    latest_version: 1\n    config:\n      contract:\n        enforced: true\n    columns:\n      - name: id\n        data_type: int\n      - name: color\n        data_type: text\n    versions:\n      - v: 1\n\"\"\"\n\n\nclass TestModifiedBodyAndContract:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": my_model_sql,\n            \"my_model.yml\": my_model_yml,\n        }\n\n    def copy_state(self):\n        if not os.path.exists(\"state\"):\n            os.makedirs(\"state\")\n        shutil.copyfile(\"target/manifest.json\", \"state/manifest.json\")\n\n    def test_modified_body_and_contract(self, project):\n        results = run_dbt([\"run\"])\n        assert len(results) == 1\n        self.copy_state()\n\n        # Change both body and contract in a *breaking* way (= changing data_type of existing column)\n        write_file(modified_my_model_yml, \"models\", \"my_model.yml\")\n        write_file(modified_my_model_sql, \"models\", \"my_model.sql\")\n\n        # Should raise even without specifying state:modified.contract\n        with pytest.raises(ContractBreakingChangeError):\n            results = run_dbt([\"run\", \"-s\", \"state:modified\", \"--state\", \"./state\"])\n\n        with pytest.raises(ContractBreakingChangeError):\n            results = run_dbt([\"run\", \"--exclude\", \"state:unmodified\", \"--state\", \"./state\"])\n\n        # Change both body and contract in a *non-breaking* way (= adding a new column)\n        write_file(modified_my_model_non_breaking_yml, \"models\", \"my_model.yml\")\n        write_file(modified_my_model_non_breaking_sql, \"models\", \"my_model.sql\")\n\n        # Should pass\n        run_dbt([\"run\", \"-s\", \"state:modified\", \"--state\", \"./state\"])\n\n        # The model's contract has changed, even if non-breaking, so it should be selected by 'state:modified.contract'\n        results = run_dbt([\"list\", \"-s\", \"state:modified.contract\", \"--state\", \"./state\"])\n        assert results == [\"test.my_model.v1\"]\n\n\nmodified_table_model_access_yml = \"\"\"\nversion: 2\nmodels:\n  - name: table_model\n    access: public\n\"\"\"\n\n\nclass TestModifiedAccess(BaseModifiedState):\n    def test_changed_access(self, project):\n        self.run_and_save_state()\n\n        # No access change\n        assert not run_dbt([\"list\", \"-s\", \"state:modified\", \"--state\", \"./state\"])\n\n        # Modify access (protected -> public)\n        write_file(modified_table_model_access_yml, \"models\", \"schema.yml\")\n        assert run_dbt([\"list\", \"-s\", \"state:modified\", \"--state\", \"./state\"])\n\n        results = run_dbt([\"list\", \"-s\", \"state:modified\", \"--state\", \"./state\"])\n        assert results == [\"test.table_model\"]\n\n\nmodified_table_model_access_yml = \"\"\"\nversion: 2\nmodels:\n  - name: table_model\n    deprecation_date: 2020-01-01\n\"\"\"\n\n\nclass TestModifiedDeprecationDate(BaseModifiedState):\n    def test_changed_access(self, project):\n        self.run_and_save_state()\n\n        # No access change\n        assert not run_dbt([\"list\", \"-s\", \"state:modified\", \"--state\", \"./state\"])\n\n        # Modify deprecation_date (None -> 2020-01-01)\n        write_file(modified_table_model_access_yml, \"models\", \"schema.yml\")\n        assert run_dbt([\"list\", \"-s\", \"state:modified\", \"--state\", \"./state\"])\n\n        results = run_dbt([\"list\", \"-s\", \"state:modified\", \"--state\", \"./state\"])\n        assert results == [\"test.table_model\"]\n\n\nmodified_table_model_version_yml = \"\"\"\nversion: 2\nmodels:\n  - name: table_model\n    versions:\n      - v: 1\n        defined_in: table_model\n\"\"\"\n\n\nclass TestModifiedVersion(BaseModifiedState):\n    def test_changed_access(self, project):\n        self.run_and_save_state()\n\n        # Change version (null -> v1)\n        write_file(modified_table_model_version_yml, \"models\", \"schema.yml\")\n\n        results = run_dbt([\"list\", \"-s\", \"state:modified\", \"--state\", \"./state\"])\n        assert results == [\"test.table_model.v1\"]\n\n\ntable_model_latest_version_yml = \"\"\"\nversion: 2\nmodels:\n  - name: table_model\n    latest_version: 1\n    versions:\n      - v: 1\n        defined_in: table_model\n\"\"\"\n\n\nmodified_table_model_latest_version_yml = \"\"\"\nversion: 2\nmodels:\n  - name: table_model\n    latest_version: 2\n    versions:\n      - v: 1\n        defined_in: table_model\n      - v: 2\n\"\"\"\n\n\nclass TestModifiedLatestVersion(BaseModifiedState):\n    def test_changed_access(self, project):\n        # Setup initial latest_version: 1\n        write_file(table_model_latest_version_yml, \"models\", \"schema.yml\")\n\n        self.run_and_save_state()\n\n        # Bump latest version\n        write_file(table_model_sql, \"models\", \"table_model_v2.sql\")\n        write_file(modified_table_model_latest_version_yml, \"models\", \"schema.yml\")\n\n        results = run_dbt([\"list\", \"-s\", \"state:modified\", \"--state\", \"./state\"])\n        assert results == [\"test.table_model.v1\", \"test.table_model.v2\"]\n\n\nclass TestChangedSemanticModelContents(BaseModifiedState):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"view_model.sql\": view_model_sql,\n            \"schema.yml\": semantic_model_schema_yml,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n        }\n\n    def test_changed_semantic_model_contents(self, project):\n        self.run_and_save_state()\n        results = run_dbt([\"list\", \"-s\", \"state:modified\", \"--state\", \"./state\"])\n        assert len(results) == 0\n\n        write_file(modified_semantic_model_schema_yml, \"models\", \"schema.yml\")\n        results = run_dbt([\"list\", \"-s\", \"state:modified\", \"--state\", \"./state\"])\n        assert len(results) == 1\n\n\nclass TestVersionedContractVarcharSizeChange(BaseModifiedState):\n    \"\"\"\n    Test that changing varchar size (e.g., varchar(5) to varchar(20))\n    does not trigger a breaking change error for versioned models.\n    Per dbt docs, size/precision/scale changes should NOT be breaking changes.\n    Reproduces issue: https://github.com/dbt-labs/dbt-core/issues/11186\n    \"\"\"\n\n    MODEL_UNIQUE_ID = \"model.test.table_model.v1\"\n\n    def test_varchar_size_increase_not_breaking(self, project):\n        # Start with varchar(5)\n        write_file(varchar_size_contract_schema_yml, \"models\", \"schema.yml\")\n        self.run_and_save_state()\n\n        # Change to varchar(20) - should NOT be a breaking change\n        write_file(varchar_size_increased_contract_schema_yml, \"models\", \"schema.yml\")\n\n        # This should PASS without errors or breaking change warnings\n        _, logs = run_dbt_and_capture(\n            [\"run\", \"--models\", \"state:modified.contract\", \"--state\", \"./state\"]\n        )\n        # Verify no breaking change warning/error\n        assert \"breaking change\" not in logs.lower()\n        assert \"ContractBreakingChangeError\" not in logs\n\n    def test_varchar_case_sensitivity_not_breaking(self, project):\n        # Start with VARCHAR(5) - uppercase\n        write_file(varchar_size_uppercase_contract_schema_yml, \"models\", \"schema.yml\")\n        self.run_and_save_state()\n\n        # Change to varchar(20) - lowercase with different size\n        # Should NOT be a breaking change (case-insensitive comparison)\n        write_file(varchar_size_lowercase_increased_contract_schema_yml, \"models\", \"schema.yml\")\n\n        # This should PASS without errors or breaking change warnings\n        _, logs = run_dbt_and_capture(\n            [\"run\", \"--models\", \"state:modified.contract\", \"--state\", \"./state\"]\n        )\n        # Verify no breaking change warning/error\n        assert \"breaking change\" not in logs.lower()\n        assert \"ContractBreakingChangeError\" not in logs\n\n    def test_numeric_precision_increase_not_breaking(self, project):\n        # Start with numeric(10,2)\n        write_file(numeric_precision_contract_schema_yml, \"models\", \"schema.yml\")\n        # Need to modify the table_model.sql to have an amount column instead of name\n        modified_table_model = \"\"\"\nselect 1 as id, 100.50 as amount\n\"\"\"\n        write_file(modified_table_model, \"models\", \"table_model.sql\")\n        self.run_and_save_state()\n\n        # Change to numeric(12,4) - should NOT be a breaking change\n        write_file(numeric_precision_increased_contract_schema_yml, \"models\", \"schema.yml\")\n\n        # This should PASS without errors or breaking change warnings\n        _, logs = run_dbt_and_capture(\n            [\"run\", \"--models\", \"state:modified.contract\", \"--state\", \"./state\"]\n        )\n        # Verify no breaking change warning/error\n        assert \"breaking change\" not in logs.lower()\n        assert \"ContractBreakingChangeError\" not in logs\n\n\nclass TestUnversionedContractVarcharSizeChange(BaseModifiedState):\n    \"\"\"\n    Test that changing varchar size for UNVERSIONED models behaves correctly.\n    Unversioned models should also NOT issue warnings for size-only changes.\n    This ensures versioned and unversioned models handle size changes consistently.\n    \"\"\"\n\n    MODEL_UNIQUE_ID = \"model.test.table_model\"\n\n    def test_varchar_size_increase_not_breaking_unversioned(self, project):\n        # Start with varchar(5) - no version\n        write_file(varchar_size_unversioned_contract_schema_yml, \"models\", \"schema.yml\")\n        self.run_and_save_state()\n\n        # Change to varchar(20) - should NOT be a breaking change\n        write_file(varchar_size_unversioned_increased_contract_schema_yml, \"models\", \"schema.yml\")\n\n        # For unversioned models, should also have no breaking change warnings\n        _, logs = run_dbt_and_capture(\n            [\"run\", \"--models\", \"state:modified.contract\", \"--state\", \"./state\"]\n        )\n        # Verify no breaking change warning (consistent with versioned behavior)\n        assert \"breaking change\" not in logs.lower()\n        # Model should still be detected as modified and run successfully\n        assert \"Completed successfully\" in logs\n"
  },
  {
    "path": "tests/functional/defer_state/test_modified_state_environment_vars.py",
    "content": "import os\n\nimport pytest\n\nfrom dbt.tests.util import run_dbt\nfrom tests.functional.defer_state.fixtures import (\n    model_with_env_var_in_config_sql,\n    model_with_no_in_config_sql,\n    schema_model_with_env_var_in_config_yml,\n)\nfrom tests.functional.defer_state.test_modified_state import BaseModifiedState\n\n\nclass BaseTestStateSelectionEnvVarConfig(BaseModifiedState):\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setup(self):\n        os.environ[\"DBT_TEST_STATE_MODIFIED\"] = \"table\"\n        yield\n        del os.environ[\"DBT_TEST_STATE_MODIFIED\"]\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"flags\": {\n                \"state_modified_compare_more_unrendered_values\": True,\n            }\n        }\n\n    def test_change_env_var(self, project):\n        # Generate ./state without changing environment variable value\n        run_dbt([\"run\"])\n        self.copy_state()\n\n        # Assert no false positive\n        results = run_dbt([\"list\", \"-s\", \"state:modified\", \"--state\", \"./state\"])\n        assert len(results) == 0\n\n        # Change environment variable and assert no false positive\n        # Environment variables do not have an effect on state:modified\n        os.environ[\"DBT_TEST_STATE_MODIFIED\"] = \"view\"\n        results = run_dbt([\"list\", \"-s\", \"state:modified\", \"--state\", \"./state\"])\n        assert len(results) == 0\n\n\nclass TestModelNodeWithEnvVarConfigInSqlFile(BaseTestStateSelectionEnvVarConfig):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model.sql\": model_with_env_var_in_config_sql,\n        }\n\n\nclass TestModelNodeWithEnvVarConfigInSchemaYml(BaseTestStateSelectionEnvVarConfig):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model.sql\": model_with_no_in_config_sql,\n            \"schema.yml\": schema_model_with_env_var_in_config_yml,\n        }\n\n\nclass TestModelNodeWithEnvVarConfigInProjectYml(BaseTestStateSelectionEnvVarConfig):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model.sql\": model_with_no_in_config_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"models\": {\n                \"test\": {\n                    \"+materialized\": \"{{ env_var('DBT_TEST_STATE_MODIFIED') }}\",\n                }\n            }\n        }\n\n\nclass TestModelNodeWithEnvVarConfigInProjectYmlAndSchemaYml(BaseTestStateSelectionEnvVarConfig):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model.sql\": model_with_no_in_config_sql,\n            \"schema.yml\": schema_model_with_env_var_in_config_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"flags\": {\n                \"state_modified_compare_more_unrendered_values\": True,\n            },\n            \"models\": {\n                \"test\": {\n                    \"+materialized\": \"{{ env_var('DBT_TEST_STATE_MODIFIED') }}\",\n                }\n            },\n        }\n\n\nclass TestModelNodeWithEnvVarConfigInSqlAndSchemaYml(BaseTestStateSelectionEnvVarConfig):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model.sql\": model_with_env_var_in_config_sql,\n            \"schema.yml\": schema_model_with_env_var_in_config_yml,\n        }\n"
  },
  {
    "path": "tests/functional/defer_state/test_modified_state_jinja.py",
    "content": "import pytest\n\nfrom dbt.tests.util import (\n    get_artifact,\n    get_project_config,\n    run_dbt,\n    update_config_file,\n    write_file,\n)\nfrom tests.functional.defer_state.fixtures import (\n    model_with_jinja_in_config_sql,\n    model_with_no_in_config_sql,\n    model_with_updated_jinja_in_config_sql,\n    schema_model_with_jinja_in_config_yml,\n    schema_model_with_updated_jinja_in_config_yml,\n)\nfrom tests.functional.defer_state.test_modified_state import BaseModifiedState\n\n\nclass BaseTestStateSelectionJinjaInConfig(BaseModifiedState):\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"flags\": {\n                \"state_modified_compare_more_unrendered_values\": True,\n            }\n        }\n\n    def update_jinja_expression_in_config(self, project):\n        pass\n\n    def test_change_jinja_if(self, project):\n        run_dbt([\"run\"])\n        self.copy_state()\n        # Model is table when execute = True\n        manifest_json = get_artifact(project.project_root, \"target\", \"manifest.json\")\n        assert manifest_json[\"nodes\"][\"model.test.model\"][\"config\"][\"materialized\"] == \"view\"\n\n        # Assert no false positive (execute = False)\n        results = run_dbt([\"list\", \"-s\", \"state:modified\", \"--state\", \"./state\"])\n        assert len(results) == 0\n\n        # Update unrendered config (change jinja expression)\n        self.update_jinja_expression_in_config(project)\n        # Assert no false negatives (jinja expression has changed)\n        results = run_dbt([\"list\", \"-s\", \"state:modified\", \"--state\", \"./state\"])\n        assert len(results) == 1\n\n\nclass TestModelNodeWithJinjaConfigInSqlFile(BaseTestStateSelectionJinjaInConfig):\n    def update_jinja_expression_in_config(self, project):\n        write_file(\n            model_with_updated_jinja_in_config_sql, project.project_root, \"models\", \"model.sql\"\n        )\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model.sql\": model_with_jinja_in_config_sql,\n        }\n\n\nclass TestModelNodeWithEnvVarConfigInSchemaYml(BaseTestStateSelectionJinjaInConfig):\n    def update_jinja_expression_in_config(self, project):\n        write_file(\n            schema_model_with_updated_jinja_in_config_yml,\n            project.project_root,\n            \"models\",\n            \"schema.yml\",\n        )\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model.sql\": model_with_no_in_config_sql,\n            \"schema.yml\": schema_model_with_jinja_in_config_yml,\n        }\n\n\nclass TestModelNodeWithJinjaConfigInProjectYml(BaseTestStateSelectionJinjaInConfig):\n    def update_jinja_expression_in_config(self, project):\n        config = get_project_config(project)\n        config[\"models\"][\"test\"][\"+materialized\"] = \"{{ ('view' if execute else 'table') }}\"\n        update_config_file(config, \"dbt_project.yml\")\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model.sql\": model_with_no_in_config_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"models\": {\n                \"test\": {\n                    \"+materialized\": \"{{ ('table' if execute else 'view') }}\",\n                }\n            }\n        }\n\n\nclass TestModelNodeWithJinjaConfigInProjectYmlAndSchemaYml(BaseTestStateSelectionJinjaInConfig):\n    def update_jinja_expression_in_config(self, project):\n        write_file(\n            schema_model_with_updated_jinja_in_config_yml,\n            project.project_root,\n            \"models\",\n            \"schema.yml\",\n        )\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model.sql\": model_with_no_in_config_sql,\n            \"schema.yml\": schema_model_with_jinja_in_config_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"flags\": {\n                \"state_modified_compare_more_unrendered_values\": True,\n            },\n            \"models\": {\n                \"test\": {\n                    \"+materialized\": \"{{ ('view' if execute else 'table') }}\",\n                }\n            },\n        }\n\n\nclass TestModelNodeWithJinjaConfigInSqlAndSchemaYml(BaseTestStateSelectionJinjaInConfig):\n    def update_jinja_expression_in_config(self, project):\n        write_file(\n            model_with_updated_jinja_in_config_sql, project.project_root, \"models\", \"model.sql\"\n        )\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model.sql\": model_with_jinja_in_config_sql,\n            \"schema.yml\": schema_model_with_jinja_in_config_yml,\n        }\n"
  },
  {
    "path": "tests/functional/defer_state/test_modified_state_schema_evolution.py",
    "content": "import json\nimport os\nimport shutil\nimport sys\n\nimport pytest\n\nfrom dbt.tests.util import run_dbt\n\n\nclass TestModifiedStateSchemaEvolution:\n    def update_state(self, test_data_dir):\n        run_dbt([\"parse\"])\n\n        shutil.copyfile(\"target/manifest.json\", os.path.join(test_data_dir, \"manifest.json\"))\n\n        # Set dbt_version to PREVIOUS to trigger manifest upgrades on state:modified\n        state_manifest_path = os.path.join(test_data_dir, \"manifest.json\")\n        with open(state_manifest_path, \"r\") as f:\n            manifest = json.load(f)\n            manifest[\"metadata\"][\"dbt_version\"] = \"PREVIOUS\"\n\n        with open(state_manifest_path, \"w\") as f:\n            json.dump(manifest, f, indent=2)\n\n    @pytest.mark.skipif(sys.platform == \"win32\", reason=\"Flaky on Windows\")\n    def test_modified_state_schema_evolution(self, happy_path_project):\n        # Uncomment this line when happy_path_project is updated\n        # If the happy_path_project needs to be updated in order to\n        # test schema evolutions not introducing state:modified false positives,\n        # make sure to update state off of main so that the functional changes of the\n        # schema evolution branch do not get reflected in the 'previous' state.\n        # self.update_state(happy_path_project.test_data_dir)\n\n        results = run_dbt(\n            [\"ls\", \"--select\", \"state:modified\", \"--state\", happy_path_project.test_data_dir]\n        )\n\n        # No false positives when no project changes are made\n        assert len(results) == 0\n"
  },
  {
    "path": "tests/functional/defer_state/test_modified_state_sources_unrendered.py",
    "content": "import os\n\nimport pytest\n\nfrom dbt.tests.util import get_artifact, run_dbt, write_file\nfrom tests.functional.defer_state.fixtures import (\n    schema_source_with_env_var_as_database_property_yml,\n    schema_source_with_env_var_as_schema_property_yml,\n    schema_source_with_jinja_as_database_property_yml,\n    schema_source_with_jinja_as_schema_property_yml,\n    schema_source_with_updated_env_var_as_schema_property_yml,\n    schema_source_with_updated_jinja_as_database_property_yml,\n    schema_source_with_updated_jinja_as_schema_property_yml,\n)\nfrom tests.functional.defer_state.test_modified_state import BaseModifiedState\nfrom tests.functional.defer_state.test_modified_state_environment_vars import (\n    BaseTestStateSelectionEnvVarConfig,\n)\n\n\nclass TestSourceNodeWithEnvVarConfigInDatabase(BaseTestStateSelectionEnvVarConfig):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": schema_source_with_env_var_as_database_property_yml,\n        }\n\n\nclass TestSourceNodeWithEnvVarConfigInSchema(BaseTestStateSelectionEnvVarConfig):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": schema_source_with_env_var_as_schema_property_yml,\n        }\n\n    def test_change_env_var(self, project):\n        # Generate ./state without changing environment variable value\n        run_dbt([\"run\"])\n        self.copy_state()\n\n        manifest_json = get_artifact(project.project_root, \"target\", \"manifest.json\")\n        assert manifest_json[\"sources\"][\"source.test.jaffle_shop.customers\"][\"schema\"] == \"table\"\n        assert (\n            manifest_json[\"sources\"][\"source.test.jaffle_shop.customers\"][\"unrendered_schema\"]\n            == \"{{ env_var('DBT_TEST_STATE_MODIFIED') }}\"\n        )\n\n        # Assert no false positive\n        results = run_dbt([\"list\", \"-s\", \"state:modified\", \"--state\", \"./state\"])\n        assert len(results) == 0\n\n        # Change environment variable and assert no false positive\n        # Environment variables do not have an effect on state:modified\n        os.environ[\"DBT_TEST_STATE_MODIFIED\"] = \"view\"\n        results = run_dbt([\"list\", \"-s\", \"state:modified\", \"--state\", \"./state\"])\n        assert len(results) == 0\n\n        # Confirm env change changed schema, but not unrendered_schema\n        manifest_json = get_artifact(project.project_root, \"target\", \"manifest.json\")\n        assert manifest_json[\"sources\"][\"source.test.jaffle_shop.customers\"][\"schema\"] == \"view\"\n        assert (\n            manifest_json[\"sources\"][\"source.test.jaffle_shop.customers\"][\"unrendered_schema\"]\n            == \"{{ env_var('DBT_TEST_STATE_MODIFIED') }}\"\n        )\n\n        # Assert no false negative after actual change to schema\n        write_file(\n            schema_source_with_updated_env_var_as_schema_property_yml,\n            project.project_root,\n            \"models\",\n            \"schema.yml\",\n        )\n        results = run_dbt([\"list\", \"-s\", \"state:modified\", \"--state\", \"./state\"])\n        assert len(results) == 1\n\n        manifest_json = get_artifact(project.project_root, \"target\", \"manifest.json\")\n        assert manifest_json[\"sources\"][\"source.test.jaffle_shop.customers\"][\"schema\"] == \"updated\"\n        assert (\n            manifest_json[\"sources\"][\"source.test.jaffle_shop.customers\"][\"unrendered_schema\"]\n            == \"updated\"\n        )\n\n\nclass TestSourceNodeWithJinjaInDatabase(BaseModifiedState):\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"flags\": {\n                \"state_modified_compare_more_unrendered_values\": True,\n            }\n        }\n\n    def update_jinja_expression_in_config(self, project):\n        write_file(\n            schema_source_with_updated_jinja_as_database_property_yml,\n            project.project_root,\n            \"models\",\n            \"schema.yml\",\n        )\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": schema_source_with_jinja_as_database_property_yml,\n        }\n\n    def test_change_jinja_if(self, project):\n        run_dbt([\"run\"])\n        self.copy_state()\n        # source database is 'bar' when execute = False\n        manifest_json = get_artifact(project.project_root, \"target\", \"manifest.json\")\n        assert manifest_json[\"sources\"][\"source.test.jaffle_shop.customers\"][\"database\"] == \"bar\"\n        assert (\n            manifest_json[\"sources\"][\"source.test.jaffle_shop.customers\"][\"unrendered_database\"]\n            == \"{{ ('foo' if execute else 'bar') }}\"\n        )\n\n        # Assert no false positive (execute = False)\n        results = run_dbt([\"list\", \"-s\", \"state:modified\", \"--state\", \"./state\"])\n        assert len(results) == 0\n\n        # Update unrendered config (change jinja expression)\n        self.update_jinja_expression_in_config(project)\n        # Assert no false negatives (jinja expression has changed)\n        results = run_dbt([\"list\", \"-s\", \"state:modified\", \"--state\", \"./state\"])\n        assert len(results) == 1\n\n\nclass TestSourceNodeWithJinjaInSchema(BaseModifiedState):\n    def update_jinja_expression_in_config(self, project):\n        write_file(\n            schema_source_with_updated_jinja_as_schema_property_yml,\n            project.project_root,\n            \"models\",\n            \"schema.yml\",\n        )\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": schema_source_with_jinja_as_schema_property_yml,\n        }\n\n    def test_change_jinja_if(self, project):\n        run_dbt([\"run\"])\n        self.copy_state()\n        # source database is 'bar' when execute = False\n        manifest_json = get_artifact(project.project_root, \"target\", \"manifest.json\")\n        assert manifest_json[\"sources\"][\"source.test.jaffle_shop.customers\"][\"schema\"] == \"bar\"\n        assert (\n            manifest_json[\"sources\"][\"source.test.jaffle_shop.customers\"][\"unrendered_schema\"]\n            == \"{{ ('foo' if execute else 'bar') }}\"\n        )\n\n        # Assert no false positive (execute = False)\n        results = run_dbt([\"list\", \"-s\", \"state:modified\", \"--state\", \"./state\"])\n        assert len(results) == 0\n\n        # Update unrendered config (change jinja expression)\n        self.update_jinja_expression_in_config(project)\n        # Assert no false negatives (jinja expression has changed)\n        results = run_dbt([\"list\", \"-s\", \"state:modified\", \"--state\", \"./state\"])\n        assert len(results) == 1\n"
  },
  {
    "path": "tests/functional/defer_state/test_modified_state_vars.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt\nfrom tests.functional.defer_state.fixtures import model_with_var_in_config_sql\nfrom tests.functional.defer_state.test_modified_state import BaseModifiedState\n\n\nclass TestStateSelectionVarConfigLegacy(BaseModifiedState):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model.sql\": model_with_var_in_config_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"flags\": {\n                \"state_modified_compare_more_unrendered_values\": False,\n            }\n        }\n\n    def test_change_var(self, project):\n        # Generate ./state without changing variable value\n        run_dbt([\"run\", \"--vars\", \"DBT_TEST_STATE_MODIFIED: view\"])\n        self.copy_state()\n\n        # Assert no false positive\n        results = run_dbt(\n            [\n                \"list\",\n                \"-s\",\n                \"state:modified\",\n                \"--state\",\n                \"./state\",\n                \"--vars\",\n                \"DBT_TEST_STATE_MODIFIED: view\",\n            ]\n        )\n        assert len(results) == 0\n\n        # Change var and assert no false negative - legacy behaviour\n        results = run_dbt(\n            [\n                \"list\",\n                \"-s\",\n                \"state:modified\",\n                \"--state\",\n                \"./state\",\n                \"--vars\",\n                \"DBT_TEST_STATE_MODIFIED: table\",\n            ]\n        )\n        assert len(results) == 1\n\n\nclass TestStateSelectionVarConfig(BaseModifiedState):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model.sql\": model_with_var_in_config_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"flags\": {\n                \"state_modified_compare_more_unrendered_values\": True,\n            }\n        }\n\n    def test_change_var(self, project):\n        # Generate ./state without changing variable value\n        run_dbt([\"run\", \"--vars\", \"DBT_TEST_STATE_MODIFIED: view\"])\n        self.copy_state()\n\n        # Assert no false positive\n        results = run_dbt(\n            [\n                \"list\",\n                \"-s\",\n                \"state:modified\",\n                \"--state\",\n                \"./state\",\n                \"--vars\",\n                \"DBT_TEST_STATE_MODIFIED: view\",\n            ]\n        )\n        assert len(results) == 0\n\n        # Change var and assert no sensitivity to var changes -- new behaviour until state:modified.vars included in state:modified by default\n        results = run_dbt(\n            [\n                \"list\",\n                \"-s\",\n                \"state:modified\",\n                \"--state\",\n                \"./state\",\n                \"--vars\",\n                \"DBT_TEST_STATE_MODIFIED: table\",\n            ]\n        )\n        assert len(results) == 0\n"
  },
  {
    "path": "tests/functional/defer_state/test_removed_test_state.py",
    "content": "import pytest\n\nfrom dbt.exceptions import CompilationError\nfrom dbt.tests.util import run_dbt\nfrom tests.functional.defer_state.fixtures import (\n    removed_test_model_sql,\n    removed_test_schema_yml,\n    sample_test_sql,\n)\n\n\nclass TestRemovedGenericTest:\n    \"\"\"Test that removing a generic test while it's still referenced gives a clear error message.\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_a.sql\": removed_test_model_sql,\n            \"schema.yml\": removed_test_schema_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def tests(self):\n        return {\n            \"generic\": {\n                \"sample_test.sql\": sample_test_sql,\n            }\n        }\n\n    def copy_state(self, project):\n        import os\n        import shutil\n\n        if not os.path.exists(f\"{project.project_root}/state\"):\n            os.makedirs(f\"{project.project_root}/state\")\n        shutil.copyfile(\n            f\"{project.project_root}/target/manifest.json\",\n            f\"{project.project_root}/state/manifest.json\",\n        )\n\n    def test_removed_generic_test_with_state_modified(self, project):\n        \"\"\"\n        Test that state:modified selector handles missing test macros gracefully.\n\n        Issue #10630: When a generic test is removed but still referenced, using\n        --select state:modified would crash with KeyError: None.\n\n        Solution: We check for None macro_uid in the state selector and raise a clear error.\n        \"\"\"\n        # Initial run - everything works\n        results = run_dbt([\"run\"])\n        assert len(results) == 1\n\n        # Save state\n        self.copy_state(project)\n\n        # Remove the generic test file but keep the reference in schema.yml\n        import os\n\n        test_file_path = os.path.join(project.project_root, \"tests\", \"generic\", \"sample_test.sql\")\n        if os.path.exists(test_file_path):\n            os.remove(test_file_path)\n\n        # The key bug fix: dbt run --select state:modified used to crash with KeyError: None\n        # After fix: it should give a clear compilation error during the selection phase\n        with pytest.raises(CompilationError, match=\"does not exist|macro or test\"):\n            run_dbt([\"run\", \"--select\", \"state:modified\", \"--state\", \"state\"])\n\n\nclass TestRemovedGenericTestStateModifiedGracefulError:\n    \"\"\"Test that state:modified selector handles missing test macros gracefully.\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_a.sql\": removed_test_model_sql,\n            \"schema.yml\": removed_test_schema_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def tests(self):\n        return {\n            \"generic\": {\n                \"sample_test.sql\": sample_test_sql,\n            }\n        }\n\n    def copy_state(self, project):\n        import os\n        import shutil\n\n        if not os.path.exists(f\"{project.project_root}/state\"):\n            os.makedirs(f\"{project.project_root}/state\")\n        shutil.copyfile(\n            f\"{project.project_root}/target/manifest.json\",\n            f\"{project.project_root}/state/manifest.json\",\n        )\n\n    def test_list_with_state_modified_after_test_removal(self, project):\n        \"\"\"\n        Test that state:modified selector handles missing test macros gracefully.\n        This exercises the selector_methods.py code path that was failing with KeyError: None.\n        \"\"\"\n        # Initial run - everything works\n        results = run_dbt([\"run\"])\n        assert len(results) == 1\n\n        # Save state\n        self.copy_state(project)\n\n        # Remove the generic test file but keep the reference in schema.yml\n        import os\n\n        test_file_path = os.path.join(project.project_root, \"tests\", \"generic\", \"sample_test.sql\")\n        if os.path.exists(test_file_path):\n            os.remove(test_file_path)\n\n        # dbt run with state:modified should not crash with KeyError: None\n        # After the fix, it should give a clear CompilationError about the missing test\n        # Previously this crashed with KeyError: None in recursively_check_macros_modified\n        with pytest.raises(\n            CompilationError, match=\"sample_test|does not exist|macro or generic test\"\n        ):\n            run_dbt([\"run\", \"--select\", \"state:modified\", \"--state\", \"state\"])\n"
  },
  {
    "path": "tests/functional/defer_state/test_run_results_state.py",
    "content": "import os\nimport shutil\n\nimport pytest\n\nfrom dbt.tests.util import run_dbt, write_file\nfrom tests.functional.defer_state.fixtures import (\n    ephemeral_model_sql,\n    exposures_yml,\n    infinite_macros_sql,\n    macros_sql,\n    schema_yml,\n    seed_csv,\n    table_model_sql,\n    view_model_sql,\n)\n\n\nclass BaseRunResultsState:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"table_model.sql\": table_model_sql,\n            \"view_model.sql\": view_model_sql,\n            \"ephemeral_model.sql\": ephemeral_model_sql,\n            \"schema.yml\": schema_yml,\n            \"exposures.yml\": exposures_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\n            \"macros.sql\": macros_sql,\n            \"infinite_macros.sql\": infinite_macros_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\n            \"seed.csv\": seed_csv,\n        }\n\n    @property\n    def project_config_update(self):\n        return {\n            \"seeds\": {\n                \"test\": {\n                    \"quote_columns\": False,\n                }\n            }\n        }\n\n    def clear_state(self):\n        shutil.rmtree(\"./state\")\n\n    def copy_state(self):\n        if not os.path.exists(\"state\"):\n            os.makedirs(\"state\")\n        shutil.copyfile(\"target/manifest.json\", \"state/manifest.json\")\n        shutil.copyfile(\"target/run_results.json\", \"state/run_results.json\")\n\n    def run_and_save_state(self):\n        run_dbt([\"build\"])\n        self.copy_state()\n\n    def rebuild_run_dbt(self, expect_pass=True):\n        self.clear_state()\n        run_dbt([\"build\"], expect_pass=expect_pass)\n        self.copy_state()\n\n    def update_view_model_bad_sql(self):\n        # update view model to generate a failure case\n        not_unique_sql = \"select * from forced_error\"\n        write_file(not_unique_sql, \"models\", \"view_model.sql\")\n\n    def update_view_model_failing_tests(self, with_dupes=True, with_nulls=False):\n        # test failure on build tests\n        # fail the unique test\n        select_1 = \"select 1 as id\"\n        select_stmts = [select_1]\n        if with_dupes:\n            select_stmts.append(select_1)\n        if with_nulls:\n            select_stmts.append(\"select null as id\")\n        failing_tests_sql = \" union all \".join(select_stmts)\n        write_file(failing_tests_sql, \"models\", \"view_model.sql\")\n\n    def update_unique_test_severity_warn(self):\n        # change the unique test severity from error to warn and reuse the same view_model.sql changes above\n        new_config = schema_yml.replace(\"error\", \"warn\")\n        write_file(new_config, \"models\", \"schema.yml\")\n\n\nclass TestSeedRunResultsState(BaseRunResultsState):\n    def test_seed_run_results_state(self, project):\n        self.run_and_save_state()\n        self.clear_state()\n        run_dbt([\"seed\"])\n        self.copy_state()\n        results = run_dbt(\n            [\"ls\", \"--resource-type\", \"seed\", \"--select\", \"result:success\", \"--state\", \"./state\"],\n            expect_pass=True,\n        )\n        assert len(results) == 1\n        assert results[0] == \"test.seed\"\n\n        results = run_dbt([\"ls\", \"--select\", \"result:success\", \"--state\", \"./state\"])\n        assert len(results) == 1\n        assert results[0] == \"test.seed\"\n\n        results = run_dbt([\"ls\", \"--select\", \"result:success+\", \"--state\", \"./state\"])\n        assert len(results) == 7\n        assert set(results) == {\n            \"test.seed\",\n            \"test.table_model\",\n            \"test.view_model\",\n            \"test.ephemeral_model\",\n            \"test.not_null_view_model_id\",\n            \"test.unique_view_model_id\",\n            \"exposure:test.my_exposure\",\n        }\n\n        # add a new faulty row to the seed\n        changed_seed_contents = seed_csv + \"\\n\" + \"\\\\\\3,carl\"\n        write_file(changed_seed_contents, \"seeds\", \"seed.csv\")\n\n        self.clear_state()\n        run_dbt([\"seed\"], expect_pass=False)\n        self.copy_state()\n\n        results = run_dbt(\n            [\"ls\", \"--resource-type\", \"seed\", \"--select\", \"result:error\", \"--state\", \"./state\"],\n            expect_pass=True,\n        )\n        assert len(results) == 1\n        assert results[0] == \"test.seed\"\n\n        results = run_dbt([\"ls\", \"--select\", \"result:error\", \"--state\", \"./state\"])\n        assert len(results) == 1\n        assert results[0] == \"test.seed\"\n\n        results = run_dbt([\"ls\", \"--select\", \"result:error+\", \"--state\", \"./state\"])\n        assert len(results) == 7\n        assert set(results) == {\n            \"test.seed\",\n            \"test.table_model\",\n            \"test.view_model\",\n            \"test.ephemeral_model\",\n            \"test.not_null_view_model_id\",\n            \"test.unique_view_model_id\",\n            \"exposure:test.my_exposure\",\n        }\n\n\nclass TestBuildRunResultsState(BaseRunResultsState):\n    def test_build_run_results_state(self, project):\n        self.run_and_save_state()\n        results = run_dbt([\"build\", \"--select\", \"result:error\", \"--state\", \"./state\"])\n        assert len(results) == 0\n\n        self.update_view_model_bad_sql()\n        self.rebuild_run_dbt(expect_pass=False)\n\n        results = run_dbt(\n            [\"build\", \"--select\", \"result:error\", \"--state\", \"./state\"], expect_pass=False\n        )\n        assert len(results) == 3\n        nodes = set([elem.node.name for elem in results])\n        assert nodes == {\"view_model\", \"not_null_view_model_id\", \"unique_view_model_id\"}\n\n        results = run_dbt([\"ls\", \"--select\", \"result:error\", \"--state\", \"./state\"])\n        assert len(results) == 3\n        assert set(results) == {\n            \"test.view_model\",\n            \"test.not_null_view_model_id\",\n            \"test.unique_view_model_id\",\n        }\n\n        results = run_dbt(\n            [\"build\", \"--select\", \"result:error+\", \"--state\", \"./state\"], expect_pass=False\n        )\n        assert len(results) == 5\n        nodes = set([elem.node.name for elem in results])\n        assert nodes == {\n            \"table_model\",\n            \"view_model\",\n            \"not_null_view_model_id\",\n            \"unique_view_model_id\",\n            \"my_exposure\",\n        }\n\n        results = run_dbt([\"ls\", \"--select\", \"result:error+\", \"--state\", \"./state\"])\n        assert len(results) == 6  # includes exposure\n        assert set(results) == {\n            \"test.table_model\",\n            \"test.view_model\",\n            \"test.ephemeral_model\",\n            \"test.not_null_view_model_id\",\n            \"test.unique_view_model_id\",\n            \"exposure:test.my_exposure\",\n        }\n\n        self.update_view_model_failing_tests()\n        self.rebuild_run_dbt(expect_pass=False)\n\n        results = run_dbt(\n            [\"build\", \"--select\", \"result:fail\", \"--state\", \"./state\"], expect_pass=False\n        )\n        assert len(results) == 1\n        assert results[0].node.name == \"unique_view_model_id\"\n\n        results = run_dbt([\"ls\", \"--select\", \"result:fail\", \"--state\", \"./state\"])\n        assert len(results) == 1\n        assert results[0] == \"test.unique_view_model_id\"\n\n        results = run_dbt(\n            [\"build\", \"--select\", \"result:fail+\", \"--state\", \"./state\"], expect_pass=False\n        )\n        assert len(results) == 1\n        nodes = set([elem.node.name for elem in results])\n        assert nodes == {\"unique_view_model_id\"}\n\n        results = run_dbt([\"ls\", \"--select\", \"result:fail+\", \"--state\", \"./state\"])\n        assert len(results) == 1\n        assert set(results) == {\"test.unique_view_model_id\"}\n\n        self.update_unique_test_severity_warn()\n        self.rebuild_run_dbt(expect_pass=True)\n\n        results = run_dbt(\n            [\"build\", \"--select\", \"result:warn\", \"--state\", \"./state\"], expect_pass=True\n        )\n        assert len(results) == 1\n        assert results[0].node.name == \"unique_view_model_id\"\n\n        results = run_dbt([\"ls\", \"--select\", \"result:warn\", \"--state\", \"./state\"])\n        assert len(results) == 1\n        assert results[0] == \"test.unique_view_model_id\"\n\n        results = run_dbt(\n            [\"build\", \"--select\", \"result:warn+\", \"--state\", \"./state\"], expect_pass=True\n        )\n        assert len(results) == 1\n        nodes = set([elem.node.name for elem in results])\n        assert nodes == {\"unique_view_model_id\"}\n\n        results = run_dbt([\"ls\", \"--select\", \"result:warn+\", \"--state\", \"./state\"])\n        assert len(results) == 1\n        assert set(results) == {\"test.unique_view_model_id\"}\n\n\nclass TestRunRunResultsState(BaseRunResultsState):\n    def test_run_run_results_state(self, project):\n        self.run_and_save_state()\n        results = run_dbt(\n            [\"run\", \"--select\", \"result:success\", \"--state\", \"./state\"], expect_pass=True\n        )\n        assert len(results) == 2\n        assert results[0].node.name == \"view_model\"\n        assert results[1].node.name == \"table_model\"\n\n        # clear state and rerun upstream view model to test + operator\n        self.clear_state()\n        run_dbt([\"run\", \"--select\", \"view_model\"], expect_pass=True)\n        self.copy_state()\n        results = run_dbt(\n            [\"run\", \"--select\", \"result:success+\", \"--state\", \"./state\"], expect_pass=True\n        )\n        assert len(results) == 2\n        assert results[0].node.name == \"view_model\"\n        assert results[1].node.name == \"table_model\"\n\n        # check we are starting from a place with 0 errors\n        results = run_dbt([\"run\", \"--select\", \"result:error\", \"--state\", \"./state\"])\n        assert len(results) == 0\n\n        self.update_view_model_bad_sql()\n        self.clear_state()\n        run_dbt([\"run\"], expect_pass=False)\n        self.copy_state()\n\n        # test single result selector on error\n        results = run_dbt(\n            [\"run\", \"--select\", \"result:error\", \"--state\", \"./state\"], expect_pass=False\n        )\n        assert len(results) == 1\n        assert results[0].node.name == \"view_model\"\n\n        # test + operator selection on error\n        results = run_dbt(\n            [\"run\", \"--select\", \"result:error+\", \"--state\", \"./state\"], expect_pass=False\n        )\n        assert len(results) == 2\n        assert results[0].node.name == \"view_model\"\n        assert results[1].node.name == \"table_model\"\n\n        # single result selector on skipped. Expect this to pass becase underlying view already defined above\n        results = run_dbt(\n            [\"run\", \"--select\", \"result:skipped\", \"--state\", \"./state\"], expect_pass=True\n        )\n        assert len(results) == 1\n        assert results[0].node.name == \"table_model\"\n\n        # add a downstream model that depends on table_model for skipped+ selector\n        downstream_model_sql = \"select * from {{ref('table_model')}}\"\n        write_file(downstream_model_sql, \"models\", \"table_model_downstream.sql\")\n\n        self.clear_state()\n        run_dbt([\"run\"], expect_pass=False)\n        self.copy_state()\n\n        results = run_dbt(\n            [\"run\", \"--select\", \"result:skipped+\", \"--state\", \"./state\"], expect_pass=True\n        )\n        assert len(results) == 2\n        assert results[0].node.name == \"table_model\"\n        assert results[1].node.name == \"table_model_downstream\"\n\n\nclass TestTestRunResultsState(BaseRunResultsState):\n    def test_test_run_results_state(self, project):\n        self.run_and_save_state()\n        # run passed nodes\n        results = run_dbt(\n            [\"test\", \"--select\", \"result:pass\", \"--state\", \"./state\"], expect_pass=True\n        )\n        assert len(results) == 2\n        nodes = set([elem.node.name for elem in results])\n        assert nodes == {\"unique_view_model_id\", \"not_null_view_model_id\"}\n\n        # run passed nodes with + operator\n        results = run_dbt(\n            [\"test\", \"--select\", \"result:pass+\", \"--state\", \"./state\"], expect_pass=True\n        )\n        assert len(results) == 2\n        nodes = set([elem.node.name for elem in results])\n        assert nodes == {\"unique_view_model_id\", \"not_null_view_model_id\"}\n\n        self.update_view_model_failing_tests()\n        self.rebuild_run_dbt(expect_pass=False)\n\n        # test with failure selector\n        results = run_dbt(\n            [\"test\", \"--select\", \"result:fail\", \"--state\", \"./state\"], expect_pass=False\n        )\n        assert len(results) == 1\n        assert results[0].node.name == \"unique_view_model_id\"\n\n        # test with failure selector and + operator\n        results = run_dbt(\n            [\"test\", \"--select\", \"result:fail+\", \"--state\", \"./state\"], expect_pass=False\n        )\n        assert len(results) == 1\n        assert results[0].node.name == \"unique_view_model_id\"\n\n        self.update_unique_test_severity_warn()\n        # rebuild - expect_pass = True because we changed the error to a warning this time around\n        self.rebuild_run_dbt(expect_pass=True)\n\n        # test with warn selector\n        results = run_dbt(\n            [\"test\", \"--select\", \"result:warn\", \"--state\", \"./state\"], expect_pass=True\n        )\n        assert len(results) == 1\n        assert results[0].node.name == \"unique_view_model_id\"\n\n        # test with warn selector and + operator\n        results = run_dbt(\n            [\"test\", \"--select\", \"result:warn+\", \"--state\", \"./state\"], expect_pass=True\n        )\n        assert len(results) == 1\n        assert results[0].node.name == \"unique_view_model_id\"\n\n\nclass TestConcurrentSelectionRunResultsState(BaseRunResultsState):\n    def test_concurrent_selection_run_run_results_state(self, project):\n        self.run_and_save_state()\n        results = run_dbt(\n            [\"run\", \"--select\", \"state:modified+\", \"result:error+\", \"--state\", \"./state\"]\n        )\n        assert len(results) == 0\n\n        self.update_view_model_bad_sql()\n        self.clear_state()\n        run_dbt([\"run\"], expect_pass=False)\n        self.copy_state()\n\n        # add a new failing dbt model\n        bad_sql = \"select * from forced_error\"\n        write_file(bad_sql, \"models\", \"table_model_modified_example.sql\")\n\n        results = run_dbt(\n            [\"run\", \"--select\", \"state:modified+\", \"result:error+\", \"--state\", \"./state\"],\n            expect_pass=False,\n        )\n        assert len(results) == 3\n        nodes = set([elem.node.name for elem in results])\n        assert nodes == {\"view_model\", \"table_model_modified_example\", \"table_model\"}\n\n\nclass TestConcurrentSelectionTestRunResultsState(BaseRunResultsState):\n    def test_concurrent_selection_test_run_results_state(self, project):\n        self.run_and_save_state()\n        # create failure test case for result:fail selector\n        self.update_view_model_failing_tests(with_nulls=True)\n\n        # run dbt build again to trigger test errors\n        self.rebuild_run_dbt(expect_pass=False)\n\n        # get the failures from\n        results = run_dbt(\n            [\n                \"test\",\n                \"--select\",\n                \"result:fail\",\n                \"--exclude\",\n                \"not_null_view_model_id\",\n                \"--state\",\n                \"./state\",\n            ],\n            expect_pass=False,\n        )\n        assert len(results) == 1\n        nodes = set([elem.node.name for elem in results])\n        assert nodes == {\"unique_view_model_id\"}\n\n\nclass TestConcurrentSelectionBuildRunResultsState(BaseRunResultsState):\n    def test_concurrent_selectors_build_run_results_state(self, project):\n        self.run_and_save_state()\n        results = run_dbt(\n            [\"build\", \"--select\", \"state:modified+\", \"result:error+\", \"--state\", \"./state\"]\n        )\n        assert len(results) == 0\n\n        self.update_view_model_bad_sql()\n        self.rebuild_run_dbt(expect_pass=False)\n\n        # add a new failing dbt model\n        bad_sql = \"select * from forced_error\"\n        write_file(bad_sql, \"models\", \"table_model_modified_example.sql\")\n\n        results = run_dbt(\n            [\"build\", \"--select\", \"state:modified+\", \"result:error+\", \"--state\", \"./state\"],\n            expect_pass=False,\n        )\n        assert len(results) == 6\n        nodes = set([elem.node.name for elem in results])\n        assert nodes == {\n            \"table_model_modified_example\",\n            \"view_model\",\n            \"table_model\",\n            \"not_null_view_model_id\",\n            \"unique_view_model_id\",\n            \"my_exposure\",\n        }\n\n        self.update_view_model_failing_tests()\n\n        # create error model case for result:error selector\n        more_bad_sql = \"select 1 as id from not_exists\"\n        write_file(more_bad_sql, \"models\", \"error_model.sql\")\n\n        # create something downstream from the error model to rerun\n        downstream_model_sql = \"select * from {{ ref('error_model') }} )\"\n        write_file(downstream_model_sql, \"models\", \"downstream_of_error_model.sql\")\n\n        # regenerate build state\n        self.rebuild_run_dbt(expect_pass=False)\n\n        # modify model again to trigger the state:modified selector\n        bad_again_sql = \"select * from forced_anothererror\"\n        write_file(bad_again_sql, \"models\", \"table_model_modified_example.sql\")\n\n        results = run_dbt(\n            [\n                \"build\",\n                \"--select\",\n                \"state:modified+\",\n                \"result:error+\",\n                \"result:fail+\",\n                \"--state\",\n                \"./state\",\n            ],\n            expect_pass=False,\n        )\n        assert len(results) == 4\n        nodes = set([elem.node.name for elem in results])\n        assert nodes == {\n            \"error_model\",\n            \"downstream_of_error_model\",\n            \"table_model_modified_example\",\n            \"unique_view_model_id\",\n        }\n"
  },
  {
    "path": "tests/functional/defer_state/test_unrendered_config.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt\n\ndbt_project_update = \"\"\"\nmodels:\n  my_dbt_project:\n    +materialized: table\n\ntests:\n  +store_failures: true\n\"\"\"\n\nfoo_sql = \"\"\"\nselect 1 as id\n\"\"\"\n\nschema_yml = \"\"\"\nmodels:\n  - name: foo\n    columns:\n      - name: id\n        tests:\n          - unique\n\"\"\"\n\n\nclass TestGenericTestUnrenderedConfig:\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return dbt_project_update\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"foo.sql\": foo_sql,\n            \"schema.yml\": schema_yml,\n        }\n\n    def test_unrendered_config(self, project):\n        manifest = run_dbt([\"parse\"])\n        assert manifest\n        test_node_id = \"test.test.unique_foo_id.fa8c520a2e\"\n        test_node = manifest.nodes[test_node_id]\n        assert test_node.unrendered_config == {\"store_failures\": True}\n"
  },
  {
    "path": "tests/functional/dependencies/data/seed.sql",
    "content": "create table {schema}.seed (\n\tid INTEGER,\n\tfirst_name VARCHAR(11),\n\temail VARCHAR(31),\n\tip_address VARCHAR(15),\n\tupdated_at TIMESTAMP WITHOUT TIME ZONE\n);\n\n\nINSERT INTO {schema}.seed\n    (\"id\",\"first_name\",\"email\",\"ip_address\",\"updated_at\")\nVALUES\n    (1,'Larry','lking0@miitbeian.gov.cn','69.135.206.194','2008-09-12 19:08:31'),\n    (2,'Larry','lperkins1@toplist.cz','64.210.133.162','1978-05-09 04:15:14'),\n    (3,'Anna','amontgomery2@miitbeian.gov.cn','168.104.64.114','2011-10-16 04:07:57'),\n    (4,'Sandra','sgeorge3@livejournal.com','229.235.252.98','1973-07-19 10:52:43'),\n    (5,'Fred','fwoods4@google.cn','78.229.170.124','2012-09-30 16:38:29'),\n    (6,'Stephen','shanson5@livejournal.com','182.227.157.105','1995-11-07 21:40:50'),\n    (7,'William','wmartinez6@upenn.edu','135.139.249.50','1982-09-05 03:11:59'),\n    (8,'Jessica','jlong7@hao123.com','203.62.178.210','1991-10-16 11:03:15'),\n    (9,'Douglas','dwhite8@tamu.edu','178.187.247.1','1979-10-01 09:49:48'),\n    (10,'Lisa','lcoleman9@nydailynews.com','168.234.128.249','2011-05-26 07:45:49'),\n    (11,'Ralph','rfieldsa@home.pl','55.152.163.149','1972-11-18 19:06:11'),\n    (12,'Louise','lnicholsb@samsung.com','141.116.153.154','2014-11-25 20:56:14'),\n    (13,'Clarence','cduncanc@sfgate.com','81.171.31.133','2011-11-17 07:02:36'),\n    (14,'Daniel','dfranklind@omniture.com','8.204.211.37','1980-09-13 00:09:04'),\n    (15,'Katherine','klanee@auda.org.au','176.96.134.59','1997-08-22 19:36:56'),\n    (16,'Billy','bwardf@wikia.com','214.108.78.85','2003-10-19 02:14:47'),\n    (17,'Annie','agarzag@ocn.ne.jp','190.108.42.70','1988-10-28 15:12:35'),\n    (18,'Shirley','scolemanh@fastcompany.com','109.251.164.84','1988-08-24 10:50:57'),\n    (19,'Roger','rfrazieri@scribd.com','38.145.218.108','1985-12-31 15:17:15'),\n    (20,'Lillian','lstanleyj@goodreads.com','47.57.236.17','1970-06-08 02:09:05'),\n    (21,'Aaron','arodriguezk@nps.gov','205.245.118.221','1985-10-11 23:07:49'),\n    (22,'Patrick','pparkerl@techcrunch.com','19.8.100.182','2006-03-29 12:53:56'),\n    (23,'Phillip','pmorenom@intel.com','41.38.254.103','2011-11-07 15:35:43'),\n    (24,'Henry','hgarcian@newsvine.com','1.191.216.252','2008-08-28 08:30:44'),\n    (25,'Irene','iturnero@opera.com','50.17.60.190','1994-04-01 07:15:02'),\n    (26,'Andrew','adunnp@pen.io','123.52.253.176','2000-11-01 06:03:25'),\n    (27,'David','dgutierrezq@wp.com','238.23.203.42','1988-01-25 07:29:18'),\n    (28,'Henry','hsanchezr@cyberchimps.com','248.102.2.185','1983-01-01 13:36:37'),\n    (29,'Evelyn','epetersons@gizmodo.com','32.80.46.119','1979-07-16 17:24:12'),\n    (30,'Tammy','tmitchellt@purevolume.com','249.246.167.88','2001-04-03 10:00:23'),\n    (31,'Jacqueline','jlittleu@domainmarket.com','127.181.97.47','1986-02-11 21:35:50'),\n    (32,'Earl','eortizv@opera.com','166.47.248.240','1996-07-06 08:16:27'),\n    (33,'Juan','jgordonw@sciencedirect.com','71.77.2.200','1987-01-31 03:46:44'),\n    (34,'Diane','dhowellx@nyu.edu','140.94.133.12','1994-06-11 02:30:05'),\n    (35,'Randy','rkennedyy@microsoft.com','73.255.34.196','2005-05-26 20:28:39'),\n    (36,'Janice','jriveraz@time.com','22.214.227.32','1990-02-09 04:16:52'),\n    (37,'Laura','lperry10@diigo.com','159.148.145.73','2015-03-17 05:59:25'),\n    (38,'Gary','gray11@statcounter.com','40.193.124.56','1970-01-27 10:04:51'),\n    (39,'Jesse','jmcdonald12@typepad.com','31.7.86.103','2009-03-14 08:14:29'),\n    (40,'Sandra','sgonzalez13@goodreads.com','223.80.168.239','1993-05-21 14:08:54'),\n    (41,'Scott','smoore14@archive.org','38.238.46.83','1980-08-30 11:16:56'),\n    (42,'Phillip','pevans15@cisco.com','158.234.59.34','2011-12-15 23:26:31'),\n    (43,'Steven','sriley16@google.ca','90.247.57.68','2011-10-29 19:03:28'),\n    (44,'Deborah','dbrown17@hexun.com','179.125.143.240','1995-04-10 14:36:07'),\n    (45,'Lori','lross18@ow.ly','64.80.162.180','1980-12-27 16:49:15'),\n    (46,'Sean','sjackson19@tumblr.com','240.116.183.69','1988-06-12 21:24:45'),\n    (47,'Terry','tbarnes1a@163.com','118.38.213.137','1997-09-22 16:43:19'),\n    (48,'Dorothy','dross1b@ebay.com','116.81.76.49','2005-02-28 13:33:24'),\n    (49,'Samuel','swashington1c@house.gov','38.191.253.40','1989-01-19 21:15:48'),\n    (50,'Ralph','rcarter1d@tinyurl.com','104.84.60.174','2007-08-11 10:21:49'),\n    (51,'Wayne','whudson1e@princeton.edu','90.61.24.102','1983-07-03 16:58:12'),\n    (52,'Rose','rjames1f@plala.or.jp','240.83.81.10','1995-06-08 11:46:23'),\n    (53,'Louise','lcox1g@theglobeandmail.com','105.11.82.145','2016-09-19 14:45:51'),\n    (54,'Kenneth','kjohnson1h@independent.co.uk','139.5.45.94','1976-08-17 11:26:19'),\n    (55,'Donna','dbrown1i@amazon.co.uk','19.45.169.45','2006-05-27 16:51:40'),\n    (56,'Johnny','jvasquez1j@trellian.com','118.202.238.23','1975-11-17 08:42:32'),\n    (57,'Patrick','pramirez1k@tamu.edu','231.25.153.198','1997-08-06 11:51:09'),\n    (58,'Helen','hlarson1l@prweb.com','8.40.21.39','1993-08-04 19:53:40'),\n    (59,'Patricia','pspencer1m@gmpg.org','212.198.40.15','1977-08-03 16:37:27'),\n    (60,'Joseph','jspencer1n@marriott.com','13.15.63.238','2005-07-23 20:22:06'),\n    (61,'Phillip','pschmidt1o@blogtalkradio.com','177.98.201.190','1976-05-19 21:47:44'),\n    (62,'Joan','jwebb1p@google.ru','105.229.170.71','1972-09-07 17:53:47'),\n    (63,'Phyllis','pkennedy1q@imgur.com','35.145.8.244','2000-01-01 22:33:37'),\n    (64,'Katherine','khunter1r@smh.com.au','248.168.205.32','1991-01-09 06:40:24'),\n    (65,'Laura','lvasquez1s@wiley.com','128.129.115.152','1997-10-23 12:04:56'),\n    (66,'Juan','jdunn1t@state.gov','44.228.124.51','2004-11-10 05:07:35'),\n    (67,'Judith','jholmes1u@wiley.com','40.227.179.115','1977-08-02 17:01:45'),\n    (68,'Beverly','bbaker1v@wufoo.com','208.34.84.59','2016-03-06 20:07:23'),\n    (69,'Lawrence','lcarr1w@flickr.com','59.158.212.223','1988-09-13 06:07:21'),\n    (70,'Gloria','gwilliams1x@mtv.com','245.231.88.33','1995-03-18 22:32:46'),\n    (71,'Steven','ssims1y@cbslocal.com','104.50.58.255','2001-08-05 21:26:20'),\n    (72,'Betty','bmills1z@arstechnica.com','103.177.214.220','1981-12-14 21:26:54'),\n    (73,'Mildred','mfuller20@prnewswire.com','151.158.8.130','2000-04-19 10:13:55'),\n    (74,'Donald','dday21@icq.com','9.178.102.255','1972-12-03 00:58:24'),\n    (75,'Eric','ethomas22@addtoany.com','85.2.241.227','1992-11-01 05:59:30'),\n    (76,'Joyce','jarmstrong23@sitemeter.com','169.224.20.36','1985-10-24 06:50:01'),\n    (77,'Maria','mmartinez24@amazonaws.com','143.189.167.135','2005-10-05 05:17:42'),\n    (78,'Harry','hburton25@youtube.com','156.47.176.237','1978-03-26 05:53:33'),\n    (79,'Kevin','klawrence26@hao123.com','79.136.183.83','1994-10-12 04:38:52'),\n    (80,'David','dhall27@prweb.com','133.149.172.153','1976-12-15 16:24:24'),\n    (81,'Kathy','kperry28@twitter.com','229.242.72.228','1979-03-04 02:58:56'),\n    (82,'Adam','aprice29@elegantthemes.com','13.145.21.10','1982-11-07 11:46:59'),\n    (83,'Brandon','bgriffin2a@va.gov','73.249.128.212','2013-10-30 05:30:36'),\n    (84,'Henry','hnguyen2b@discovery.com','211.36.214.242','1985-01-09 06:37:27'),\n    (85,'Eric','esanchez2c@edublogs.org','191.166.188.251','2004-05-01 23:21:42'),\n    (86,'Jason','jlee2d@jimdo.com','193.92.16.182','1973-01-08 09:05:39'),\n    (87,'Diana','drichards2e@istockphoto.com','19.130.175.245','1994-10-05 22:50:49'),\n    (88,'Andrea','awelch2f@abc.net.au','94.155.233.96','2002-04-26 08:41:44'),\n    (89,'Louis','lwagner2g@miitbeian.gov.cn','26.217.34.111','2003-08-25 07:56:39'),\n    (90,'Jane','jsims2h@seesaa.net','43.4.220.135','1987-03-20 20:39:04'),\n    (91,'Larry','lgrant2i@si.edu','97.126.79.34','2000-09-07 20:26:19'),\n    (92,'Louis','ldean2j@prnewswire.com','37.148.40.127','2011-09-16 20:12:14'),\n    (93,'Jennifer','jcampbell2k@xing.com','38.106.254.142','1988-07-15 05:06:49'),\n    (94,'Wayne','wcunningham2l@google.com.hk','223.28.26.187','2009-12-15 06:16:54'),\n    (95,'Lori','lstevens2m@icq.com','181.250.181.58','1984-10-28 03:29:19'),\n    (96,'Judy','jsimpson2n@marriott.com','180.121.239.219','1986-02-07 15:18:10'),\n    (97,'Phillip','phoward2o@usa.gov','255.247.0.175','2002-12-26 08:44:45'),\n    (98,'Gloria','gwalker2p@usa.gov','156.140.7.128','1997-10-04 07:58:58'),\n    (99,'Paul','pjohnson2q@umn.edu','183.59.198.197','1991-11-14 12:33:55'),\n    (100,'Frank','fgreene2r@blogspot.com','150.143.68.121','2010-06-12 23:55:39'),\n    (101,'Deborah','dknight2s@reverbnation.com','222.131.211.191','1970-07-08 08:54:23'),\n    (102,'Sandra','sblack2t@tripadvisor.com','254.183.128.254','2000-04-12 02:39:36'),\n    (103,'Edward','eburns2u@dailymotion.com','253.89.118.18','1993-10-10 10:54:01'),\n    (104,'Anthony','ayoung2v@ustream.tv','118.4.193.176','1978-08-26 17:07:29'),\n    (105,'Donald','dlawrence2w@wp.com','139.200.159.227','2007-07-21 20:56:20'),\n    (106,'Matthew','mfreeman2x@google.fr','205.26.239.92','2014-12-05 17:05:39'),\n    (107,'Sean','ssanders2y@trellian.com','143.89.82.108','1993-07-14 21:45:02'),\n    (108,'Sharon','srobinson2z@soundcloud.com','66.234.247.54','1977-04-06 19:07:03'),\n    (109,'Jennifer','jwatson30@t-online.de','196.102.127.7','1998-03-07 05:12:23'),\n    (110,'Clarence','cbrooks31@si.edu','218.93.234.73','2002-11-06 17:22:25'),\n    (111,'Jose','jflores32@goo.gl','185.105.244.231','1995-01-05 06:32:21'),\n    (112,'George','glee33@adobe.com','173.82.249.196','2015-01-04 02:47:46'),\n    (113,'Larry','lhill34@linkedin.com','66.5.206.195','2010-11-02 10:21:17'),\n    (114,'Marie','mmeyer35@mysql.com','151.152.88.107','1990-05-22 20:52:51'),\n    (115,'Clarence','cwebb36@skype.com','130.198.55.217','1972-10-27 07:38:54'),\n    (116,'Sarah','scarter37@answers.com','80.89.18.153','1971-08-24 19:29:30'),\n    (117,'Henry','hhughes38@webeden.co.uk','152.60.114.174','1973-01-27 09:00:42'),\n    (118,'Teresa','thenry39@hao123.com','32.187.239.106','2015-11-06 01:48:44'),\n    (119,'Billy','bgutierrez3a@sun.com','52.37.70.134','2002-03-19 03:20:19'),\n    (120,'Anthony','agibson3b@github.io','154.251.232.213','1991-04-19 01:08:15'),\n    (121,'Sandra','sromero3c@wikia.com','44.124.171.2','1998-09-06 20:30:34'),\n    (122,'Paula','pandrews3d@blogs.com','153.142.118.226','2003-06-24 16:31:24'),\n    (123,'Terry','tbaker3e@csmonitor.com','99.120.45.219','1970-12-09 23:57:21'),\n    (124,'Lois','lwilson3f@reuters.com','147.44.171.83','1971-01-09 22:28:51'),\n    (125,'Sara','smorgan3g@nature.com','197.67.192.230','1992-01-28 20:33:24'),\n    (126,'Charles','ctorres3h@china.com.cn','156.115.216.2','1993-10-02 19:36:34'),\n    (127,'Richard','ralexander3i@marriott.com','248.235.180.59','1999-02-03 18:40:55'),\n    (128,'Christina','charper3j@cocolog-nifty.com','152.114.116.129','1978-09-13 00:37:32'),\n    (129,'Steve','sadams3k@economist.com','112.248.91.98','2004-03-21 09:07:43'),\n    (130,'Katherine','krobertson3l@ow.ly','37.220.107.28','1977-03-18 19:28:50'),\n    (131,'Donna','dgibson3m@state.gov','222.218.76.221','1999-02-01 06:46:16'),\n    (132,'Christina','cwest3n@mlb.com','152.114.6.160','1979-12-24 15:30:35'),\n    (133,'Sandra','swillis3o@meetup.com','180.71.49.34','1984-09-27 08:05:54'),\n    (134,'Clarence','cedwards3p@smugmug.com','10.64.180.186','1979-04-16 16:52:10'),\n    (135,'Ruby','rjames3q@wp.com','98.61.54.20','2007-01-13 14:25:52'),\n    (136,'Sarah','smontgomery3r@tripod.com','91.45.164.172','2009-07-25 04:34:30'),\n    (137,'Sarah','soliver3s@eventbrite.com','30.106.39.146','2012-05-09 22:12:33'),\n    (138,'Deborah','dwheeler3t@biblegateway.com','59.105.213.173','1999-11-09 08:08:44'),\n    (139,'Deborah','dray3u@i2i.jp','11.108.186.217','2014-02-04 03:15:19'),\n    (140,'Paul','parmstrong3v@alexa.com','6.250.59.43','2009-12-21 10:08:53'),\n    (141,'Aaron','abishop3w@opera.com','207.145.249.62','1996-04-25 23:20:23'),\n    (142,'Henry','hsanders3x@google.ru','140.215.203.171','2012-01-29 11:52:32'),\n    (143,'Anne','aanderson3y@1688.com','74.150.102.118','1982-04-03 13:46:17'),\n    (144,'Victor','vmurphy3z@hugedomains.com','222.155.99.152','1987-11-03 19:58:41'),\n    (145,'Evelyn','ereid40@pbs.org','249.122.33.117','1977-12-14 17:09:57'),\n    (146,'Brian','bgonzalez41@wikia.com','246.254.235.141','1991-02-24 00:45:58'),\n    (147,'Sandra','sgray42@squarespace.com','150.73.28.159','1972-07-28 17:26:32'),\n    (148,'Alice','ajones43@a8.net','78.253.12.177','2002-12-05 16:57:46'),\n    (149,'Jessica','jhanson44@mapquest.com','87.229.30.160','1994-01-30 11:40:04'),\n    (150,'Louise','lbailey45@reuters.com','191.219.31.101','2011-09-07 21:11:45'),\n    (151,'Christopher','cgonzalez46@printfriendly.com','83.137.213.239','1984-10-24 14:58:04'),\n    (152,'Gregory','gcollins47@yandex.ru','28.176.10.115','1998-07-25 17:17:10'),\n    (153,'Jane','jperkins48@usnews.com','46.53.164.159','1979-08-19 15:25:00'),\n    (154,'Phyllis','plong49@yahoo.co.jp','208.140.88.2','1985-07-06 02:16:36'),\n    (155,'Adam','acarter4a@scribd.com','78.48.148.204','2005-07-20 03:31:09'),\n    (156,'Frank','fweaver4b@angelfire.com','199.180.255.224','2011-03-04 23:07:54'),\n    (157,'Ronald','rmurphy4c@cloudflare.com','73.42.97.231','1991-01-11 10:39:41'),\n    (158,'Richard','rmorris4d@e-recht24.de','91.9.97.223','2009-01-17 21:05:15'),\n    (159,'Rose','rfoster4e@woothemes.com','203.169.53.16','1991-04-21 02:09:38'),\n    (160,'George','ggarrett4f@uiuc.edu','186.61.5.167','1989-11-11 11:29:42'),\n    (161,'Victor','vhamilton4g@biblegateway.com','121.229.138.38','2012-06-22 18:01:23'),\n    (162,'Mark','mbennett4h@businessinsider.com','209.184.29.203','1980-04-16 15:26:34'),\n    (163,'Martin','mwells4i@ifeng.com','97.223.55.105','2010-05-26 14:08:18'),\n    (164,'Diana','dstone4j@google.ru','90.155.52.47','2013-02-11 00:14:54'),\n    (165,'Walter','wferguson4k@blogger.com','30.63.212.44','1986-02-20 17:46:46'),\n    (166,'Denise','dcoleman4l@vistaprint.com','10.209.153.77','1992-05-13 20:14:14'),\n    (167,'Philip','pknight4m@xing.com','15.28.135.167','2000-09-11 18:41:13'),\n    (168,'Russell','rcarr4n@youtube.com','113.55.165.50','2008-07-10 17:49:27'),\n    (169,'Donna','dburke4o@dion.ne.jp','70.0.105.111','1992-02-10 17:24:58'),\n    (170,'Anne','along4p@squidoo.com','36.154.58.107','2012-08-19 23:35:31'),\n    (171,'Clarence','cbanks4q@webeden.co.uk','94.57.53.114','1972-03-11 21:46:44'),\n    (172,'Betty','bbowman4r@cyberchimps.com','178.115.209.69','2013-01-13 21:34:51'),\n    (173,'Andrew','ahudson4s@nytimes.com','84.32.252.144','1998-09-15 14:20:04'),\n    (174,'Keith','kgordon4t@cam.ac.uk','189.237.211.102','2009-01-22 05:34:38'),\n    (175,'Patrick','pwheeler4u@mysql.com','47.22.117.226','1984-09-05 22:33:15'),\n    (176,'Jesse','jfoster4v@mapquest.com','229.95.131.46','1990-01-20 12:19:15'),\n    (177,'Arthur','afisher4w@jugem.jp','107.255.244.98','1983-10-13 11:08:46'),\n    (178,'Nicole','nryan4x@wsj.com','243.211.33.221','1974-05-30 23:19:14'),\n    (179,'Bruce','bjohnson4y@sfgate.com','17.41.200.101','1992-09-23 02:02:19'),\n    (180,'Terry','tcox4z@reference.com','20.189.120.106','1982-02-13 12:43:14'),\n    (181,'Ashley','astanley50@kickstarter.com','86.3.56.98','1976-05-09 01:27:16'),\n    (182,'Michael','mrivera51@about.me','72.118.249.0','1971-11-11 17:28:37'),\n    (183,'Steven','sgonzalez52@mozilla.org','169.112.247.47','2002-08-24 14:59:25'),\n    (184,'Kathleen','kfuller53@bloglovin.com','80.93.59.30','2002-03-11 13:41:29'),\n    (185,'Nicole','nhenderson54@usda.gov','39.253.60.30','1995-04-24 05:55:07'),\n    (186,'Ralph','rharper55@purevolume.com','167.147.142.189','1980-02-10 18:35:45'),\n    (187,'Heather','hcunningham56@photobucket.com','96.222.196.229','2007-06-15 05:37:50'),\n    (188,'Nancy','nlittle57@cbc.ca','241.53.255.175','2007-07-12 23:42:48'),\n    (189,'Juan','jramirez58@pinterest.com','190.128.84.27','1978-11-07 23:37:37'),\n    (190,'Beverly','bfowler59@chronoengine.com','54.144.230.49','1979-03-31 23:27:28'),\n    (191,'Shirley','sstevens5a@prlog.org','200.97.231.248','2011-12-06 07:08:50'),\n    (192,'Annie','areyes5b@squidoo.com','223.32.182.101','2011-05-28 02:42:09'),\n    (193,'Jack','jkelley5c@tiny.cc','47.34.118.150','1981-12-05 17:31:40'),\n    (194,'Keith','krobinson5d@1und1.de','170.210.209.31','1999-03-09 11:05:43'),\n    (195,'Joseph','jmiller5e@google.com.au','136.74.212.139','1984-10-08 13:18:20'),\n    (196,'Annie','aday5f@blogspot.com','71.99.186.69','1986-02-18 12:27:34'),\n    (197,'Nancy','nperez5g@liveinternet.ru','28.160.6.107','1983-10-20 17:51:20'),\n    (198,'Tammy','tward5h@ucoz.ru','141.43.164.70','1980-03-31 04:45:29'),\n    (199,'Doris','dryan5i@ted.com','239.117.202.188','1985-07-03 03:17:53'),\n    (200,'Rose','rmendoza5j@photobucket.com','150.200.206.79','1973-04-21 21:36:40'),\n    (201,'Cynthia','cbutler5k@hubpages.com','80.153.174.161','2001-01-20 01:42:26'),\n    (202,'Samuel','soliver5l@people.com.cn','86.127.246.140','1970-09-02 02:19:00'),\n    (203,'Carl','csanchez5m@mysql.com','50.149.237.107','1993-12-01 07:02:09'),\n    (204,'Kathryn','kowens5n@geocities.jp','145.166.205.201','2004-07-06 18:39:33'),\n    (205,'Nicholas','nnichols5o@parallels.com','190.240.66.170','2014-11-11 18:52:19'),\n    (206,'Keith','kwillis5p@youtube.com','181.43.206.100','1998-06-13 06:30:51'),\n    (207,'Justin','jwebb5q@intel.com','211.54.245.74','2000-11-04 16:58:26'),\n    (208,'Gary','ghicks5r@wikipedia.org','196.154.213.104','1992-12-01 19:48:28'),\n    (209,'Martin','mpowell5s@flickr.com','153.67.12.241','1983-06-30 06:24:32'),\n    (210,'Brenda','bkelley5t@xinhuanet.com','113.100.5.172','2005-01-08 20:50:22'),\n    (211,'Edward','eray5u@a8.net','205.187.246.65','2011-09-26 08:04:44'),\n    (212,'Steven','slawson5v@senate.gov','238.150.250.36','1978-11-22 02:48:09'),\n    (213,'Robert','rthompson5w@furl.net','70.7.89.236','2001-09-12 08:52:07'),\n    (214,'Jack','jporter5x@diigo.com','220.172.29.99','1976-07-26 14:29:21'),\n    (215,'Lisa','ljenkins5y@oakley.com','150.151.170.180','2010-03-20 19:21:16'),\n    (216,'Theresa','tbell5z@mayoclinic.com','247.25.53.173','2001-03-11 05:36:40'),\n    (217,'Jimmy','jstephens60@weather.com','145.101.93.235','1983-04-12 09:35:30'),\n    (218,'Louis','lhunt61@amazon.co.jp','78.137.6.253','1997-08-29 19:34:34'),\n    (219,'Lawrence','lgilbert62@ted.com','243.132.8.78','2015-04-08 22:06:56'),\n    (220,'David','dgardner63@4shared.com','204.40.46.136','1971-07-09 03:29:11'),\n    (221,'Charles','ckennedy64@gmpg.org','211.83.233.2','2011-02-26 11:55:04'),\n    (222,'Lillian','lbanks65@msu.edu','124.233.12.80','2010-05-16 20:29:02'),\n    (223,'Ernest','enguyen66@baidu.com','82.45.128.148','1996-07-04 10:07:04'),\n    (224,'Ryan','rrussell67@cloudflare.com','202.53.240.223','1983-08-05 12:36:29'),\n    (225,'Donald','ddavis68@ustream.tv','47.39.218.137','1989-05-27 02:30:56'),\n    (226,'Joe','jscott69@blogspot.com','140.23.131.75','1973-03-16 12:21:31'),\n    (227,'Anne','amarshall6a@google.ca','113.162.200.197','1988-12-09 03:38:29'),\n    (228,'Willie','wturner6b@constantcontact.com','85.83.182.249','1991-10-06 01:51:10'),\n    (229,'Nicole','nwilson6c@sogou.com','30.223.51.135','1977-05-29 19:54:56'),\n    (230,'Janet','jwheeler6d@stumbleupon.com','153.194.27.144','2011-03-13 12:48:47'),\n    (231,'Lois','lcarr6e@statcounter.com','0.41.36.53','1993-02-06 04:52:01'),\n    (232,'Shirley','scruz6f@tmall.com','37.156.39.223','2007-02-18 17:47:01'),\n    (233,'Patrick','pford6g@reverbnation.com','36.198.200.89','1977-03-06 15:47:24'),\n    (234,'Lisa','lhudson6h@usatoday.com','134.213.58.137','2014-10-28 01:56:56'),\n    (235,'Pamela','pmartinez6i@opensource.org','5.151.127.202','1987-11-30 16:44:47'),\n    (236,'Larry','lperez6j@infoseek.co.jp','235.122.96.148','1979-01-18 06:33:45'),\n    (237,'Pamela','pramirez6k@census.gov','138.233.34.163','2012-01-29 10:35:20'),\n    (238,'Daniel','dcarr6l@php.net','146.21.152.242','1984-11-17 08:22:59'),\n    (239,'Patrick','psmith6m@indiegogo.com','136.222.199.36','2001-05-30 22:16:44'),\n    (240,'Raymond','rhenderson6n@hc360.com','116.31.112.38','2000-01-05 20:35:41'),\n    (241,'Teresa','treynolds6o@miitbeian.gov.cn','198.126.205.220','1996-11-08 01:27:31'),\n    (242,'Johnny','jmason6p@flickr.com','192.8.232.114','2013-05-14 05:35:50'),\n    (243,'Angela','akelly6q@guardian.co.uk','234.116.60.197','1977-08-20 02:05:17'),\n    (244,'Douglas','dcole6r@cmu.edu','128.135.212.69','2016-10-26 17:40:36'),\n    (245,'Frances','fcampbell6s@twitpic.com','94.22.243.235','1987-04-26 07:07:13'),\n    (246,'Donna','dgreen6t@chron.com','227.116.46.107','2011-07-25 12:59:54'),\n    (247,'Benjamin','bfranklin6u@redcross.org','89.141.142.89','1974-05-03 20:28:18'),\n    (248,'Randy','rpalmer6v@rambler.ru','70.173.63.178','2011-12-20 17:40:18'),\n    (249,'Melissa','mmurray6w@bbb.org','114.234.118.137','1991-02-26 12:45:44'),\n    (250,'Jean','jlittle6x@epa.gov','141.21.163.254','1991-08-16 04:57:09'),\n    (251,'Daniel','dolson6y@nature.com','125.75.104.97','2010-04-23 06:25:54'),\n    (252,'Kathryn','kwells6z@eventbrite.com','225.104.28.249','2015-01-31 02:21:50'),\n    (253,'Theresa','tgonzalez70@ox.ac.uk','91.93.156.26','1971-12-11 10:31:31'),\n    (254,'Beverly','broberts71@bluehost.com','244.40.158.89','2013-09-21 13:02:31'),\n    (255,'Pamela','pmurray72@netscape.com','218.54.95.216','1985-04-16 00:34:00'),\n    (256,'Timothy','trichardson73@amazonaws.com','235.49.24.229','2000-11-11 09:48:28'),\n    (257,'Mildred','mpalmer74@is.gd','234.125.95.132','1992-05-25 02:25:02'),\n    (258,'Jessica','jcampbell75@google.it','55.98.30.140','2014-08-26 00:26:34'),\n    (259,'Beverly','bthomas76@cpanel.net','48.78.228.176','1970-08-18 10:40:05'),\n    (260,'Eugene','eward77@cargocollective.com','139.226.204.2','1996-12-04 23:17:00'),\n    (261,'Andrea','aallen78@webnode.com','160.31.214.38','2009-07-06 07:22:37'),\n    (262,'Justin','jruiz79@merriam-webster.com','150.149.246.122','2005-06-06 11:44:19'),\n    (263,'Kenneth','kedwards7a@networksolutions.com','98.82.193.128','2001-07-03 02:00:10'),\n    (264,'Rachel','rday7b@miibeian.gov.cn','114.15.247.221','1994-08-18 19:45:40'),\n    (265,'Russell','rmiller7c@instagram.com','184.130.152.253','1977-11-06 01:58:12'),\n    (266,'Bonnie','bhudson7d@cornell.edu','235.180.186.206','1990-12-03 22:45:24'),\n    (267,'Raymond','rknight7e@yandex.ru','161.2.44.252','1995-08-25 04:31:19'),\n    (268,'Bonnie','brussell7f@elpais.com','199.237.57.207','1991-03-29 08:32:06'),\n    (269,'Marie','mhenderson7g@elpais.com','52.203.131.144','2004-06-04 21:50:28'),\n    (270,'Alan','acarr7h@trellian.com','147.51.205.72','2005-03-03 10:51:31'),\n    (271,'Barbara','bturner7i@hugedomains.com','103.160.110.226','2004-08-04 13:42:40'),\n    (272,'Christina','cdaniels7j@census.gov','0.238.61.251','1972-10-18 12:47:33'),\n    (273,'Jeremy','jgomez7k@reuters.com','111.26.65.56','2013-01-13 10:41:35'),\n    (274,'Laura','lwood7l@icio.us','149.153.38.205','2011-06-25 09:33:59'),\n    (275,'Matthew','mbowman7m@auda.org.au','182.138.206.172','1999-03-05 03:25:36'),\n    (276,'Denise','dparker7n@icq.com','0.213.88.138','2011-11-04 09:43:06'),\n    (277,'Phillip','pparker7o@discuz.net','219.242.165.240','1973-10-19 04:22:29'),\n    (278,'Joan','jpierce7p@salon.com','63.31.213.202','1989-04-09 22:06:24'),\n    (279,'Irene','ibaker7q@cbc.ca','102.33.235.114','1992-09-04 13:00:57'),\n    (280,'Betty','bbowman7r@ted.com','170.91.249.242','2015-09-28 08:14:22'),\n    (281,'Teresa','truiz7s@boston.com','82.108.158.207','1999-07-18 05:17:09'),\n    (282,'Helen','hbrooks7t@slideshare.net','102.87.162.187','2003-01-06 15:45:29'),\n    (283,'Karen','kgriffin7u@wunderground.com','43.82.44.184','2010-05-28 01:56:37'),\n    (284,'Lisa','lfernandez7v@mtv.com','200.238.218.220','1993-04-03 20:33:51'),\n    (285,'Jesse','jlawrence7w@timesonline.co.uk','95.122.105.78','1990-01-05 17:28:43'),\n    (286,'Terry','tross7x@macromedia.com','29.112.114.133','2009-08-29 21:32:17'),\n    (287,'Angela','abradley7y@icq.com','177.44.27.72','1989-10-04 21:46:06'),\n    (288,'Maria','mhart7z@dailymotion.com','55.27.55.202','1975-01-21 01:22:57'),\n    (289,'Raymond','randrews80@pinterest.com','88.90.78.67','1992-03-16 21:37:40'),\n    (290,'Kathy','krice81@bluehost.com','212.63.196.102','2000-12-14 03:06:44'),\n    (291,'Cynthia','cramos82@nymag.com','107.89.190.6','2005-06-28 02:02:33'),\n    (292,'Kimberly','kjones83@mysql.com','86.169.101.101','2007-06-13 22:56:49'),\n    (293,'Timothy','thansen84@microsoft.com','108.100.254.90','2003-04-04 10:31:57'),\n    (294,'Carol','cspencer85@berkeley.edu','75.118.144.187','1999-03-30 14:53:21'),\n    (295,'Louis','lmedina86@latimes.com','141.147.163.24','1991-04-11 17:53:13'),\n    (296,'Margaret','mcole87@google.fr','53.184.26.83','1991-12-19 01:54:10'),\n    (297,'Mary','mgomez88@yellowpages.com','208.56.57.99','1976-05-21 18:05:08'),\n    (298,'Amanda','aanderson89@geocities.com','147.73.15.252','1987-08-22 15:05:28'),\n    (299,'Kathryn','kgarrett8a@nature.com','27.29.177.220','1976-07-15 04:25:04'),\n    (300,'Dorothy','dmason8b@shareasale.com','106.210.99.193','1990-09-03 21:39:31'),\n    (301,'Lois','lkennedy8c@amazon.de','194.169.29.187','2007-07-29 14:09:31'),\n    (302,'Irene','iburton8d@washingtonpost.com','196.143.110.249','2013-09-05 11:32:46'),\n    (303,'Betty','belliott8e@wired.com','183.105.222.199','1979-09-19 19:29:13'),\n    (304,'Bobby','bmeyer8f@census.gov','36.13.161.145','2014-05-24 14:34:39'),\n    (305,'Ann','amorrison8g@sfgate.com','72.154.54.137','1978-10-05 14:22:34'),\n    (306,'Daniel','djackson8h@wunderground.com','144.95.32.34','1990-07-27 13:23:05'),\n    (307,'Joe','jboyd8i@alibaba.com','187.105.86.178','2011-09-28 16:46:32'),\n    (308,'Ralph','rdunn8j@fc2.com','3.19.87.255','1984-10-18 08:00:40'),\n    (309,'Craig','ccarter8k@gizmodo.com','235.152.76.215','1998-07-04 12:15:21'),\n    (310,'Paula','pdean8l@hhs.gov','161.100.173.197','1973-02-13 09:38:55'),\n    (311,'Andrew','agarrett8m@behance.net','199.253.123.218','1991-02-14 13:36:32'),\n    (312,'Janet','jhowell8n@alexa.com','39.189.139.79','2012-11-24 20:17:33'),\n    (313,'Keith','khansen8o@godaddy.com','116.186.223.196','1987-08-23 21:22:05'),\n    (314,'Nicholas','nedwards8p@state.gov','142.175.142.11','1977-03-28 18:27:27'),\n    (315,'Jacqueline','jallen8q@oaic.gov.au','189.66.135.192','1994-10-26 11:44:26'),\n    (316,'Frank','fgardner8r@mapy.cz','154.77.119.169','1983-01-29 19:19:51'),\n    (317,'Eric','eharrison8s@google.cn','245.139.65.123','1984-02-04 09:54:36'),\n    (318,'Gregory','gcooper8t@go.com','171.147.0.221','2004-06-14 05:22:08'),\n    (319,'Jean','jfreeman8u@rakuten.co.jp','67.243.121.5','1977-01-07 18:23:43'),\n    (320,'Juan','jlewis8v@shinystat.com','216.181.171.189','2001-08-23 17:32:43'),\n    (321,'Randy','rwilliams8w@shinystat.com','105.152.146.28','1983-02-17 00:05:50'),\n    (322,'Stephen','shart8x@sciencedirect.com','196.131.205.148','2004-02-15 10:12:03'),\n    (323,'Annie','ahunter8y@example.com','63.36.34.103','2003-07-23 21:15:25'),\n    (324,'Melissa','mflores8z@cbc.ca','151.230.217.90','1983-11-02 14:53:56'),\n    (325,'Jane','jweaver90@about.me','0.167.235.217','1987-07-29 00:13:44'),\n    (326,'Anthony','asmith91@oracle.com','97.87.48.41','2001-05-31 18:44:11'),\n    (327,'Terry','tdavis92@buzzfeed.com','46.20.12.51','2015-09-12 23:13:55'),\n    (328,'Brandon','bmontgomery93@gravatar.com','252.101.48.186','2010-10-28 08:26:27'),\n    (329,'Chris','cmurray94@bluehost.com','25.158.167.97','2004-05-05 16:10:31'),\n    (330,'Denise','dfuller95@hugedomains.com','216.210.149.28','1979-04-20 08:57:24'),\n    (331,'Arthur','amcdonald96@sakura.ne.jp','206.42.36.213','2009-08-15 03:26:16'),\n    (332,'Jesse','jhoward97@google.cn','46.181.118.30','1974-04-18 14:08:41'),\n    (333,'Frank','fsimpson98@domainmarket.com','163.220.211.87','2006-06-30 14:46:52'),\n    (334,'Janice','jwoods99@pen.io','229.245.237.182','1988-04-06 11:52:58'),\n    (335,'Rebecca','rroberts9a@huffingtonpost.com','148.96.15.80','1976-10-05 08:44:16'),\n    (336,'Joshua','jray9b@opensource.org','192.253.12.198','1971-12-25 22:27:07'),\n    (337,'Joyce','jcarpenter9c@statcounter.com','125.171.46.215','2001-12-31 22:08:13'),\n    (338,'Andrea','awest9d@privacy.gov.au','79.101.180.201','1983-02-18 20:07:47'),\n    (339,'Christine','chudson9e@yelp.com','64.198.43.56','1997-09-08 08:03:43'),\n    (340,'Joe','jparker9f@earthlink.net','251.215.148.153','1973-11-04 05:08:18'),\n    (341,'Thomas','tkim9g@answers.com','49.187.34.47','1991-08-07 21:13:48'),\n    (342,'Janice','jdean9h@scientificamerican.com','4.197.117.16','2009-12-08 02:35:49'),\n    (343,'James','jmitchell9i@umich.edu','43.121.18.147','2011-04-28 17:04:09'),\n    (344,'Charles','cgardner9j@purevolume.com','197.78.240.240','1998-02-11 06:47:07'),\n    (345,'Robert','rhenderson9k@friendfeed.com','215.84.180.88','2002-05-10 15:33:14'),\n    (346,'Chris','cgray9l@4shared.com','249.70.192.240','1998-10-03 16:43:42'),\n    (347,'Gloria','ghayes9m@hibu.com','81.103.138.26','1999-12-26 11:23:13'),\n    (348,'Edward','eramirez9n@shareasale.com','38.136.90.136','2010-08-19 08:01:06'),\n    (349,'Cheryl','cbutler9o@google.ca','172.180.78.172','1995-05-27 20:03:52'),\n    (350,'Margaret','mwatkins9p@sfgate.com','3.20.198.6','2014-10-21 01:42:58'),\n    (351,'Rebecca','rwelch9q@examiner.com','45.81.42.208','2001-02-08 12:19:06'),\n    (352,'Joe','jpalmer9r@phpbb.com','163.202.92.190','1970-01-05 11:29:12'),\n    (353,'Sandra','slewis9s@dyndns.org','77.215.201.236','1974-01-05 07:04:04'),\n    (354,'Todd','tfranklin9t@g.co','167.125.181.82','2009-09-28 10:13:58'),\n    (355,'Joseph','jlewis9u@webmd.com','244.204.6.11','1990-10-21 15:49:57'),\n    (356,'Alan','aknight9v@nydailynews.com','152.197.95.83','1996-03-08 08:43:17'),\n    (357,'Sharon','sdean9w@123-reg.co.uk','237.46.40.26','1985-11-30 12:09:24'),\n    (358,'Annie','awright9x@cafepress.com','190.45.231.111','2000-08-24 11:56:06'),\n    (359,'Diane','dhamilton9y@youtube.com','85.146.171.196','2015-02-24 02:03:57'),\n    (360,'Antonio','alane9z@auda.org.au','61.63.146.203','2001-05-13 03:43:34'),\n    (361,'Matthew','mallena0@hhs.gov','29.97.32.19','1973-02-19 23:43:32'),\n    (362,'Bonnie','bfowlera1@soup.io','251.216.99.53','2013-08-01 15:35:41'),\n    (363,'Margaret','mgraya2@examiner.com','69.255.151.79','1998-01-23 22:24:59'),\n    (364,'Joan','jwagnera3@printfriendly.com','192.166.120.61','1973-07-13 00:30:22'),\n    (365,'Catherine','cperkinsa4@nytimes.com','58.21.24.214','2006-11-19 11:52:26'),\n    (366,'Mark','mcartera5@cpanel.net','220.33.102.142','2007-09-09 09:43:27'),\n    (367,'Paula','ppricea6@msn.com','36.182.238.124','2009-11-11 09:13:05'),\n    (368,'Catherine','cgreena7@army.mil','228.203.58.19','2005-08-09 16:52:15'),\n    (369,'Helen','hhamiltona8@symantec.com','155.56.194.99','2005-02-01 05:40:36'),\n    (370,'Jane','jmeyera9@ezinearticles.com','133.244.113.213','2013-11-06 22:10:23'),\n    (371,'Wanda','wevansaa@bloglovin.com','233.125.192.48','1994-12-26 23:43:42'),\n    (372,'Mark','mmarshallab@tumblr.com','114.74.60.47','2016-09-29 18:03:01'),\n    (373,'Andrew','amartinezac@google.cn','182.54.37.130','1976-06-06 17:04:17'),\n    (374,'Helen','hmoralesad@e-recht24.de','42.45.4.123','1977-03-28 19:06:59'),\n    (375,'Bonnie','bstoneae@php.net','196.149.79.137','1970-02-05 17:05:58'),\n    (376,'Douglas','dfreemanaf@nasa.gov','215.65.124.218','2008-11-20 21:51:55'),\n    (377,'Willie','wwestag@army.mil','35.189.92.118','1992-07-24 05:08:08'),\n    (378,'Cheryl','cwagnerah@upenn.edu','228.239.222.141','2010-01-25 06:29:01'),\n    (379,'Sandra','swardai@baidu.com','63.11.113.240','1985-05-23 08:07:37'),\n    (380,'Julie','jrobinsonaj@jugem.jp','110.58.202.50','2015-03-05 09:42:07'),\n    (381,'Larry','lwagnerak@shop-pro.jp','98.234.25.24','1975-07-22 22:22:02'),\n    (382,'Juan','jcastilloal@yelp.com','24.174.74.202','2007-01-17 09:32:43'),\n    (383,'Donna','dfrazieram@artisteer.com','205.26.147.45','1990-02-11 20:55:46'),\n    (384,'Rachel','rfloresan@w3.org','109.60.216.162','1983-05-22 22:42:18'),\n    (385,'Robert','rreynoldsao@theguardian.com','122.65.209.130','2009-05-01 18:02:51'),\n    (386,'Donald','dbradleyap@etsy.com','42.54.35.126','1997-01-16 16:31:52'),\n    (387,'Rachel','rfisheraq@nih.gov','160.243.250.45','2006-02-17 22:05:49'),\n    (388,'Nicholas','nhamiltonar@princeton.edu','156.211.37.111','1976-06-21 03:36:29'),\n    (389,'Timothy','twhiteas@ca.gov','36.128.23.70','1975-09-24 03:51:18'),\n    (390,'Diana','dbradleyat@odnoklassniki.ru','44.102.120.184','1983-04-27 09:02:50'),\n    (391,'Billy','bfowlerau@jimdo.com','91.200.68.196','1995-01-29 06:57:35'),\n    (392,'Bruce','bandrewsav@ucoz.com','48.12.101.125','1992-10-27 04:31:39'),\n    (393,'Linda','lromeroaw@usa.gov','100.71.233.19','1992-06-08 15:13:18'),\n    (394,'Debra','dwatkinsax@ucoz.ru','52.160.233.193','2001-11-11 06:51:01'),\n    (395,'Katherine','kburkeay@wix.com','151.156.242.141','2010-06-14 19:54:28'),\n    (396,'Martha','mharrisonaz@youku.com','21.222.10.199','1989-10-16 14:17:55'),\n    (397,'Dennis','dwellsb0@youtu.be','103.16.29.3','1985-12-21 06:05:51'),\n    (398,'Gloria','grichardsb1@bloglines.com','90.147.120.234','1982-08-27 01:04:43'),\n    (399,'Brenda','bfullerb2@t.co','33.253.63.90','2011-04-20 05:00:35'),\n    (400,'Larry','lhendersonb3@disqus.com','88.95.132.128','1982-08-31 02:15:12'),\n    (401,'Richard','rlarsonb4@wisc.edu','13.48.231.150','1979-04-15 14:08:09'),\n    (402,'Terry','thuntb5@usa.gov','65.91.103.240','1998-05-15 11:50:49'),\n    (403,'Harry','hburnsb6@nasa.gov','33.38.21.244','1981-04-12 14:02:20'),\n    (404,'Diana','dellisb7@mlb.com','218.229.81.135','1997-01-29 00:17:25'),\n    (405,'Jack','jburkeb8@tripadvisor.com','210.227.182.216','1984-03-09 17:24:03'),\n    (406,'Julia','jlongb9@fotki.com','10.210.12.104','2005-10-26 03:54:13'),\n    (407,'Lois','lscottba@msu.edu','188.79.136.138','1973-02-02 18:40:39'),\n    (408,'Sandra','shendersonbb@shareasale.com','114.171.220.108','2012-06-09 18:22:26'),\n    (409,'Irene','isanchezbc@cdbaby.com','109.255.50.119','1983-09-28 21:11:27'),\n    (410,'Emily','ebrooksbd@bandcamp.com','227.81.93.79','1970-08-31 21:08:01'),\n    (411,'Michelle','mdiazbe@businessweek.com','236.249.6.226','1993-05-22 08:07:07'),\n    (412,'Tammy','tbennettbf@wisc.edu','145.253.239.152','1978-12-31 20:24:51'),\n    (413,'Christine','cgreenebg@flickr.com','97.25.140.118','1978-07-17 12:55:30'),\n    (414,'Patricia','pgarzabh@tuttocitta.it','139.246.192.211','1984-02-27 13:40:08'),\n    (415,'Kimberly','kromerobi@aol.com','73.56.88.247','1976-09-16 14:22:04'),\n    (416,'George','gjohnstonbj@fda.gov','240.36.245.185','1979-07-24 14:36:02'),\n    (417,'Eugene','efullerbk@sciencedaily.com','42.38.105.140','2012-09-12 01:56:41'),\n    (418,'Andrea','astevensbl@goo.gl','31.152.207.204','1979-05-24 11:06:21'),\n    (419,'Shirley','sreidbm@scientificamerican.com','103.60.31.241','1984-02-23 04:07:41'),\n    (420,'Terry','tmorenobn@blinklist.com','92.161.34.42','1994-06-25 14:01:35'),\n    (421,'Christopher','cmorenobo@go.com','158.86.176.82','1973-09-05 09:18:47'),\n    (422,'Dennis','dhansonbp@ning.com','40.160.81.75','1982-01-20 10:19:41'),\n    (423,'Beverly','brussellbq@de.vu','138.32.56.204','1997-11-06 07:20:19'),\n    (424,'Howard','hparkerbr@163.com','103.171.134.171','2015-06-24 15:37:10'),\n    (425,'Helen','hmccoybs@fema.gov','61.200.4.71','1995-06-20 08:59:10'),\n    (426,'Ann','ahudsonbt@cafepress.com','239.187.71.125','1977-04-11 07:59:28'),\n    (427,'Tina','twestbu@nhs.uk','80.213.117.74','1992-08-19 05:54:44'),\n    (428,'Terry','tnguyenbv@noaa.gov','21.93.118.95','1991-09-19 23:22:55'),\n    (429,'Ashley','aburtonbw@wix.com','233.176.205.109','2009-11-10 05:01:20'),\n    (430,'Eric','emyersbx@1und1.de','168.91.212.67','1987-08-10 07:16:20'),\n    (431,'Barbara','blittleby@lycos.com','242.14.189.239','2008-08-02 12:13:04'),\n    (432,'Sean','sevansbz@instagram.com','14.39.177.13','2007-04-16 17:28:49'),\n    (433,'Shirley','sburtonc0@newsvine.com','34.107.138.76','1980-12-10 02:19:29'),\n    (434,'Patricia','pfreemanc1@so-net.ne.jp','219.213.142.117','1987-03-01 02:25:45'),\n    (435,'Paula','pfosterc2@vkontakte.ru','227.14.138.141','1972-09-22 12:59:34'),\n    (436,'Nicole','nstewartc3@1688.com','8.164.23.115','1998-10-27 00:10:17'),\n    (437,'Earl','ekimc4@ovh.net','100.26.244.177','2013-01-22 10:05:46'),\n    (438,'Beverly','breedc5@reuters.com','174.12.226.27','1974-09-22 07:29:36'),\n    (439,'Lawrence','lbutlerc6@a8.net','105.164.42.164','1992-06-05 00:43:40'),\n    (440,'Charles','cmoorec7@ucoz.com','252.197.131.69','1990-04-09 02:34:05'),\n    (441,'Alice','alawsonc8@live.com','183.73.220.232','1989-02-28 09:11:04'),\n    (442,'Dorothy','dcarpenterc9@arstechnica.com','241.47.200.14','2005-05-02 19:57:21'),\n    (443,'Carolyn','cfowlerca@go.com','213.109.55.202','1978-09-10 20:18:20'),\n    (444,'Anthony','alongcb@free.fr','169.221.158.204','1984-09-13 01:59:23'),\n    (445,'Annie','amoorecc@e-recht24.de','50.34.148.61','2009-03-26 03:41:07'),\n    (446,'Carlos','candrewscd@ihg.com','236.69.59.212','1972-03-29 22:42:48'),\n    (447,'Beverly','bramosce@google.ca','164.250.184.49','1982-11-10 04:34:01'),\n    (448,'Teresa','tlongcf@umich.edu','174.88.53.223','1987-05-17 12:48:00'),\n    (449,'Roy','rboydcg@uol.com.br','91.58.243.215','1974-06-16 17:59:54'),\n    (450,'Ashley','afieldsch@tamu.edu','130.138.11.126','1983-09-15 05:52:36'),\n    (451,'Judith','jhawkinsci@cmu.edu','200.187.103.245','2003-10-22 12:24:03'),\n    (452,'Rebecca','rwestcj@ocn.ne.jp','72.85.3.103','1980-11-13 11:01:26'),\n    (453,'Raymond','rporterck@infoseek.co.jp','146.33.216.151','1982-05-17 23:58:03'),\n    (454,'Janet','jmarshallcl@odnoklassniki.ru','52.46.193.166','1998-10-04 00:02:21'),\n    (455,'Shirley','speterscm@salon.com','248.126.31.15','1987-01-30 06:04:59'),\n    (456,'Annie','abowmancn@economist.com','222.213.248.59','2006-03-14 23:52:59'),\n    (457,'Jean','jlarsonco@blogspot.com','71.41.25.195','2007-09-08 23:49:45'),\n    (458,'Phillip','pmoralescp@stanford.edu','74.119.87.28','2011-03-14 20:25:40'),\n    (459,'Norma','nrobinsoncq@economist.com','28.225.21.54','1989-10-21 01:22:43'),\n    (460,'Kimberly','kclarkcr@dion.ne.jp','149.171.132.153','2008-06-27 02:27:30'),\n    (461,'Ruby','rmorriscs@ucla.edu','177.85.163.249','2016-01-28 16:43:44'),\n    (462,'Jonathan','jcastilloct@tripod.com','78.4.28.77','2000-05-24 17:33:06'),\n    (463,'Edward','ebryantcu@jigsy.com','140.31.98.193','1992-12-17 08:32:47'),\n    (464,'Chris','chamiltoncv@eepurl.com','195.171.234.206','1970-12-05 03:42:19'),\n    (465,'Michael','mweavercw@reference.com','7.233.133.213','1987-03-29 02:30:54'),\n    (466,'Howard','hlawrencecx@businessweek.com','113.225.124.224','1990-07-30 07:20:57'),\n    (467,'Philip','phowardcy@comsenz.com','159.170.247.249','2010-10-15 10:18:37'),\n    (468,'Mary','mmarshallcz@xing.com','125.132.189.70','2007-07-19 13:48:47'),\n    (469,'Scott','salvarezd0@theguardian.com','78.49.103.230','1987-10-31 06:10:44'),\n    (470,'Wayne','wcarrolld1@blog.com','238.1.120.204','1980-11-19 03:26:10'),\n    (471,'Jennifer','jwoodsd2@multiply.com','92.20.224.49','2010-05-06 22:17:04'),\n    (472,'Raymond','rwelchd3@toplist.cz','176.158.35.240','2007-12-12 19:02:51'),\n    (473,'Steven','sdixond4@wisc.edu','167.55.237.52','1984-05-05 11:44:37'),\n    (474,'Ralph','rjamesd5@ameblo.jp','241.190.50.133','2000-07-06 08:44:37'),\n    (475,'Jason','jrobinsond6@hexun.com','138.119.139.56','2006-02-03 05:27:45'),\n    (476,'Doris','dwoodd7@fema.gov','180.220.156.190','1978-05-11 20:14:20'),\n    (477,'Elizabeth','eberryd8@youtu.be','74.188.53.229','2006-11-18 08:29:06'),\n    (478,'Irene','igilbertd9@privacy.gov.au','194.152.218.1','1985-09-17 02:46:52'),\n    (479,'Jessica','jdeanda@ameblo.jp','178.103.93.118','1974-06-07 19:04:05'),\n    (480,'Rachel','ralvarezdb@phoca.cz','17.22.223.174','1999-03-08 02:43:25'),\n    (481,'Kenneth','kthompsondc@shinystat.com','229.119.91.234','2007-05-15 13:17:32'),\n    (482,'Harold','hmurraydd@parallels.com','133.26.188.80','1993-11-15 03:42:07'),\n    (483,'Paula','phowellde@samsung.com','34.215.28.216','1993-11-29 15:55:00'),\n    (484,'Ruth','rpiercedf@tripadvisor.com','111.30.130.123','1986-08-17 10:19:38'),\n    (485,'Phyllis','paustindg@vk.com','50.84.34.178','1994-04-13 03:05:24'),\n    (486,'Laura','lfosterdh@usnews.com','37.8.101.33','2001-06-30 08:58:59'),\n    (487,'Eric','etaylordi@com.com','103.183.253.45','2006-09-15 20:18:46'),\n    (488,'Doris','driveradj@prweb.com','247.16.2.199','1989-05-08 09:27:09'),\n    (489,'Ryan','rhughesdk@elegantthemes.com','103.234.153.232','1989-08-01 18:36:06'),\n    (490,'Steve','smoralesdl@jigsy.com','3.76.84.207','2011-03-13 17:01:05'),\n    (491,'Louis','lsullivandm@who.int','78.135.44.208','1975-11-26 16:01:23'),\n    (492,'Catherine','ctuckerdn@seattletimes.com','93.137.106.21','1990-03-13 16:14:56'),\n    (493,'Ann','adixondo@gmpg.org','191.136.222.111','2002-06-05 14:22:18'),\n    (494,'Johnny','jhartdp@amazon.com','103.252.198.39','1988-07-30 23:54:49'),\n    (495,'Susan','srichardsdq@skype.com','126.247.192.11','2005-01-09 12:08:14'),\n    (496,'Brenda','bparkerdr@skype.com','63.232.216.86','1974-05-18 05:58:29'),\n    (497,'Tammy','tmurphyds@constantcontact.com','56.56.37.112','2014-08-05 18:22:25'),\n    (498,'Larry','lhayesdt@wordpress.com','162.146.13.46','1997-02-26 14:01:53'),\n    (499,'Evelyn','ethomasdu@hhs.gov','6.241.88.250','2007-09-14 13:03:34'),\n    (500,'Paula','pshawdv@networksolutions.com','123.27.47.249','2003-10-30 21:19:20');\n\ncreate table {schema}.seed_config_expected_1 as (\n\n    select *, 'default'::text as c1, 'default'::text as c2, 'was true'::text as some_bool from {schema}.seed\n\n);\n\ncreate table {schema}.seed_config_expected_2 as (\n\n    select *, 'abc'::text as c1, 'def'::text as c2, 'was true'::text as some_bool from {schema}.seed\n\n);\n\ncreate table {schema}.seed_config_expected_3 as (\n\n    select *, 'ghi'::text as c1, 'jkl'::text as c2, 'was true'::text as some_bool from {schema}.seed\n\n);\n\ncreate table {schema}.seed_summary (\n    year timestamp without time zone,\n    count bigint\n);\n\nINSERT INTO {schema}.seed_summary\n    (\"year\",\"count\")\nVALUES\n    ('1970-01-01 00:00:00',10),\n    ('1971-01-01 00:00:00',6),\n    ('1972-01-01 00:00:00',9),\n    ('1973-01-01 00:00:00',12),\n    ('1974-01-01 00:00:00',8),\n    ('1975-01-01 00:00:00',5),\n    ('1976-01-01 00:00:00',11),\n    ('1977-01-01 00:00:00',13),\n    ('1978-01-01 00:00:00',11),\n    ('1979-01-01 00:00:00',13),\n    ('1980-01-01 00:00:00',9),\n    ('1981-01-01 00:00:00',3),\n    ('1982-01-01 00:00:00',9),\n    ('1983-01-01 00:00:00',15),\n    ('1984-01-01 00:00:00',13),\n    ('1985-01-01 00:00:00',11),\n    ('1986-01-01 00:00:00',5),\n    ('1987-01-01 00:00:00',14),\n    ('1988-01-01 00:00:00',9),\n    ('1989-01-01 00:00:00',10),\n    ('1990-01-01 00:00:00',12),\n    ('1991-01-01 00:00:00',16),\n    ('1992-01-01 00:00:00',15),\n    ('1993-01-01 00:00:00',11),\n    ('1994-01-01 00:00:00',10),\n    ('1995-01-01 00:00:00',10),\n    ('1996-01-01 00:00:00',6),\n    ('1997-01-01 00:00:00',11),\n    ('1998-01-01 00:00:00',12),\n    ('1999-01-01 00:00:00',9),\n    ('2000-01-01 00:00:00',13),\n    ('2001-01-01 00:00:00',14),\n    ('2002-01-01 00:00:00',9),\n    ('2003-01-01 00:00:00',8),\n    ('2004-01-01 00:00:00',9),\n    ('2005-01-01 00:00:00',14),\n    ('2006-01-01 00:00:00',9),\n    ('2007-01-01 00:00:00',16),\n    ('2008-01-01 00:00:00',6),\n    ('2009-01-01 00:00:00',15),\n    ('2010-01-01 00:00:00',13),\n    ('2011-01-01 00:00:00',23),\n    ('2012-01-01 00:00:00',9),\n    ('2013-01-01 00:00:00',10),\n    ('2014-01-01 00:00:00',9),\n    ('2015-01-01 00:00:00',10),\n    ('2016-01-01 00:00:00',5);\n"
  },
  {
    "path": "tests/functional/dependencies/data/update.sql",
    "content": "\nUPDATE {schema}.seed set first_name = 'Paul', updated_at = now() where id = 500;\n\nINSERT INTO {schema}.seed\n    (\"id\",\"first_name\",\"email\",\"ip_address\",\"updated_at\")\nVALUES\n    (501, 'Steve', 'sthomas@hhs.gov', '6.241.88.251', now());\n"
  },
  {
    "path": "tests/functional/dependencies/duplicate_dependency/dbt_project.yml",
    "content": "name: 'test'\nversion: '1.0'\nconfig-version: 2\n\nprofile: 'default'\n"
  },
  {
    "path": "tests/functional/dependencies/early_hook_dependency/dbt_project.yml",
    "content": "name: early_hooks\nversion: '1.0'\nconfig-version: 2\non-run-start:\n  - create table {{ var('test_create_table') }} as (select 1 as id)\n  - create table {{ var('test_create_second_table') }} as (select 3 as id)\n"
  },
  {
    "path": "tests/functional/dependencies/inverted_ref_dependency/dbt_project.yml",
    "content": "name: 'inverted_ref_dependency'\nversion: '1.0'\nconfig-version: 2\n\nprofile: 'default'\n\nmodel-paths: [\"models\"]\nanalysis-paths: [\"analyses\"]\ntest-paths: [\"tests\"]\nseed-paths: [\"seeds\"]\nmacro-paths: [\"macros\"]\n\nrequire-dbt-version: '>=0.1.0'\n\ntarget-path: \"target\"  # directory which will store compiled SQL files\nclean-targets:         # directories to be removed by `dbt clean`\n    - \"target\"\n    - \"dbt_packages\"\n\n\nseeds:\n  quote_columns: False\n"
  },
  {
    "path": "tests/functional/dependencies/inverted_ref_dependency/models/a.sql",
    "content": "{{ config(alias='package_a')}}\n\nselect 1 as id\n"
  },
  {
    "path": "tests/functional/dependencies/inverted_ref_dependency/models/b.sql",
    "content": "select * from {{ ref('a') }}\n"
  },
  {
    "path": "tests/functional/dependencies/inverted_ref_dependency/models/b_root_package_in_ref.sql",
    "content": "select * from {{ ref('test', 'a') }}\n"
  },
  {
    "path": "tests/functional/dependencies/late_hook_dependency/dbt_project.yml",
    "content": "name: late_hooks\nversion: '1.0'\nconfig-version: 2\non-run-start:\n  - insert into {{ var('test_create_table') }} values (2)\n  - insert into {{ var('test_create_second_table') }} values (4)\n"
  },
  {
    "path": "tests/functional/dependencies/local_dependency/dbt_project.yml",
    "content": "\nname: 'local_dep'\nversion: '1.0'\nconfig-version: 2\n\nprofile: 'default'\n\nmodel-paths: [\"models\"]\nanalysis-paths: [\"analyses\"]\ntest-paths: [\"tests\"]\nseed-paths: [\"seeds\"]\nmacro-paths: [\"macros\"]\n\nrequire-dbt-version: '>=0.1.0'\n\ntarget-path: \"target\"  # directory which will store compiled SQL files\nclean-targets:         # directories to be removed by `dbt clean`\n    - \"target\"\n    - \"dbt_packages\"\n\n\nseeds:\n  quote_columns: False\n"
  },
  {
    "path": "tests/functional/dependencies/local_dependency/macros/dep_macro.sql",
    "content": "{% macro some_overridden_macro() -%}\n100\n{%- endmacro %}\n"
  },
  {
    "path": "tests/functional/dependencies/local_dependency/macros/generate_schema_name.sql",
    "content": "{# This should not be ignored, even as it's in a subpackage #}\n{% macro generate_schema_name(custom_schema_name=none, node=none) -%}\n  {{ var('schema_override', target.schema) }}\n{%- endmacro %}\n\n{# This should not be ignored, even as it's in a subpackage #}\n{% macro generate_database_name(custom_database_name=none, node=none) -%}\n  {{ 'dbt' }}\n{%- endmacro %}\n\n\n{# This should not be ignored, even as it's in a subpackage #}\n{% macro generate_alias_name(custom_alias_name=none, node=none) -%}\n  {{ node.name ~ '_subpackage_generate_alias_name' }}\n{%- endmacro %}\n"
  },
  {
    "path": "tests/functional/dependencies/local_dependency/models/model_to_import.sql",
    "content": "select * from {{ ref('seed') }}\n"
  },
  {
    "path": "tests/functional/dependencies/local_dependency/models/schema.yml",
    "content": "version: 2\nsources:\n  - name: my_source\n    schema: invalid_schema\n    tables:\n      - name: my_table\n  - name: seed_source\n    schema: \"{{ var('schema_override', target.schema) }}\"\n    tables:\n      - name: \"seed\"\n        identifier: \"seed_subpackage_generate_alias_name\"\n"
  },
  {
    "path": "tests/functional/dependencies/local_dependency/seeds/seed.csv",
    "content": "id\n1\n"
  },
  {
    "path": "tests/functional/dependencies/models_local/dep_source_model.sql",
    "content": "{# If our dependency source didn't exist, this would be an errror #}\nselect * from {{ source('seed_source', 'seed') }}\n"
  },
  {
    "path": "tests/functional/dependencies/models_local/my_configured_model.sql",
    "content": "{{\n    config(schema='configured')\n}}\nselect * from {{ ref('model_to_import') }}\n"
  },
  {
    "path": "tests/functional/dependencies/models_local/my_model.sql",
    "content": "\nselect * from {{ ref('model_to_import') }}\n"
  },
  {
    "path": "tests/functional/dependencies/models_local/schema.yml",
    "content": "version: 2\nsources:\n  - name: my_source\n    schema: \"{{ var('schema_override', target.schema) }}\"\n    tables:\n      - name: my_table\n        identifier: seed\n"
  },
  {
    "path": "tests/functional/dependencies/models_local/source_override_model.sql",
    "content": "{# If our source override didn't take, this would be an errror #}\nselect * from {{ source('my_source', 'my_table') }}\n"
  },
  {
    "path": "tests/functional/dependencies/nested_dependency/dbt_project.yml",
    "content": "name: 'nested_dependency'\nversion: '1.0'\nconfig-version: 2\n\nmodel-paths: [\"models\"]\n"
  },
  {
    "path": "tests/functional/dependencies/nested_dependency/models/model.sql",
    "content": "select 1 as id\n"
  },
  {
    "path": "tests/functional/dependencies/nested_dependency/packages.yml",
    "content": "packages:\n  - package: godatadriven/dbt_date\n    version: \">=0.10.0\"\n"
  },
  {
    "path": "tests/functional/dependencies/test_add_package_edge_cases.py",
    "content": "import os\nimport shutil\n\nimport pytest\n\nfrom dbt.tests.util import run_dbt\n\n\nclass TestAddPackageWithWarnUnpinnedInYaml:\n    \"\"\"Functional test: Adding packages works even with warn-unpinned in packages.yml.\n\n    This is a regression test for issue #9104. The bug occurred when packages.yml\n    contained warn-unpinned: false and dbt deps --add-package was run. The code\n    would fail with \"TypeError: argument of type 'bool' is not iterable\".\n    \"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        # Start with a git package that has warn-unpinned (matching the bug report)\n        return {\n            \"packages\": [\n                {\n                    \"git\": \"https://github.com/fivetran/dbt_amplitude\",\n                    \"warn-unpinned\": False,  # This is the config that caused the bug\n                },\n            ]\n        }\n\n    @pytest.fixture\n    def clean_start(self, project):\n        if os.path.exists(\"dbt_packages\"):\n            shutil.rmtree(\"dbt_packages\")\n        if os.path.exists(\"package-lock.yml\"):\n            os.remove(\"package-lock.yml\")\n\n    def test_add_package_with_warn_unpinned_in_yaml(self, clean_start):\n        \"\"\"Test that adding a package works when packages.yml contains warn-unpinned: false\"\"\"\n        # Before the fix, this would raise: TypeError: argument of type 'bool' is not iterable\n        # This matches the exact scenario from issue #9104\n        run_dbt([\"deps\", \"--add-package\", \"dbt-labs/dbt_utils@1.0.0\"])\n\n        with open(\"packages.yml\") as fp:\n            contents = fp.read()\n\n        # Verify both packages are present\n        assert \"dbt_amplitude\" in contents or \"fivetran/dbt_amplitude\" in contents\n        assert \"dbt-labs/dbt_utils\" in contents or \"dbt_utils\" in contents\n        # The warn-unpinned should still be there\n        assert \"warn-unpinned:\" in contents or \"warn_unpinned:\" in contents\n"
  },
  {
    "path": "tests/functional/dependencies/test_dependency_inverted_ref.py",
    "content": "import shutil\nfrom pathlib import Path\n\nimport pytest\n\nfrom dbt.events.types import PackageNodeDependsOnRootProjectNode\nfrom dbt.tests.util import run_dbt\nfrom dbt_common.events.event_catcher import EventCatcher\n\n\nclass BaseInvertedRefDependencyTest(object):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"a.sql\": \"select 1 as id\",\n        }\n\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project):\n        shutil.copytree(\n            project.test_dir / Path(\"inverted_ref_dependency\"),\n            project.project_root / Path(\"inverted_ref_dependency\"),\n        )\n\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\"packages\": [{\"local\": \"inverted_ref_dependency\"}]}\n\n\nclass TestInvertedRefDependency(BaseInvertedRefDependencyTest):\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"flags\": {\n                \"require_ref_searches_node_package_before_root\": True,\n            }\n        }\n\n    def test_inverted_ref_dependency(self, project):\n        event_catcher = EventCatcher(PackageNodeDependsOnRootProjectNode)\n        run_dbt([\"deps\"])\n\n        manifest = run_dbt([\"parse\"], callbacks=[event_catcher.catch])\n\n        assert len(manifest.nodes) == 4\n        # Correct behavior - package node depends on node from same package\n        assert manifest.nodes[\"model.inverted_ref_dependency.b\"].depends_on.nodes == [\n            \"model.inverted_ref_dependency.a\"\n        ]\n        # If a package explicitly references a root project node, it still resolves to root project\n        manifest.nodes[\"model.inverted_ref_dependency.b_root_package_in_ref\"].depends_on.nodes == [\n            \"model.test.a\"\n        ]\n\n        # No inverted ref warning raised\n        assert len(event_catcher.caught_events) == 0\n\n\nclass TestInvertedRefDependencyLegacy(BaseInvertedRefDependencyTest):\n    def test_inverted_ref_dependency(self, project):\n        event_catcher = EventCatcher(PackageNodeDependsOnRootProjectNode)\n        run_dbt([\"deps\"])\n\n        manifest = run_dbt([\"parse\"], callbacks=[event_catcher.catch])\n\n        assert len(manifest.nodes) == 4\n        # Legacy behavior - package node depends on node from root project\n        assert manifest.nodes[\"model.inverted_ref_dependency.b\"].depends_on.nodes == [\n            \"model.test.a\"\n        ]\n        assert manifest.nodes[\n            \"model.inverted_ref_dependency.b_root_package_in_ref\"\n        ].depends_on.nodes == [\"model.test.a\"]\n\n        # Inverted ref warning raised - only for b, not b_root_package_in_ref\n        assert len(event_catcher.caught_events) == 1\n        assert event_catcher.caught_events[0].data.node_name == \"b\"\n        assert event_catcher.caught_events[0].data.package_name == \"inverted_ref_dependency\"\n"
  },
  {
    "path": "tests/functional/dependencies/test_dependency_options.py",
    "content": "import os\nimport shutil\n\nimport pytest\n\nfrom dbt.tests.util import run_dbt\n\n\nclass TestDepsOptions(object):\n    # this revision of dbt-integration-project requires dbt-utils.git@0.5.0, which the\n    # package config handling should detect\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\n            \"packages\": [\n                {\n                    \"package\": \"fivetran/fivetran_utils\",\n                    \"version\": \"0.4.7\",\n                },\n            ]\n        }\n\n    @pytest.fixture\n    def clean_start(self, project):\n        if os.path.exists(\"dbt_packages\"):\n            shutil.rmtree(\"dbt_packages\")\n        if os.path.exists(\"package-lock.yml\"):\n            os.remove(\"package-lock.yml\")\n\n    def test_deps_lock(self, clean_start):\n        run_dbt([\"deps\", \"--lock\"])\n        assert not os.path.exists(\"dbt_packages\")\n        assert os.path.exists(\"package-lock.yml\")\n        with open(\"package-lock.yml\") as fp:\n            contents = fp.read()\n\n        fivetran_package = \"\"\"\n  - name: fivetran_utils\n    package: fivetran/fivetran_utils\n    version: 0.4.7\n\"\"\"\n\n        # dbt-utils is a dep in fivetran so we can't check for a specific version or this test fails everytime a new dbt-utils version comes out\n        dbt_labs_package = \"\"\"\n  - name: dbt_utils\n    package: dbt-labs/dbt_utils\n\"\"\"\n        package_sha = \"sha1_hash: 71304bca2138cf8004070b3573a1e17183c0c1a8\"\n        assert fivetran_package in contents\n        assert dbt_labs_package in contents\n        assert package_sha in contents\n\n    def test_deps_default(self, clean_start):\n        run_dbt([\"deps\"])\n        assert len(os.listdir(\"dbt_packages\")) == 2\n        assert os.path.exists(\"package-lock.yml\")\n        with open(\"package-lock.yml\") as fp:\n            contents = fp.read()\n        fivetran_package = \"\"\"\n  - name: fivetran_utils\n    package: fivetran/fivetran_utils\n    version: 0.4.7\n\"\"\"\n\n        # dbt-utils is a dep in fivetran so we can't check for a specific version or this test fails everytime a new dbt-utils version comes out\n        dbt_labs_package = \"\"\"\n  - name: dbt_utils\n    package: dbt-labs/dbt_utils\n\"\"\"\n        package_sha = \"sha1_hash: 71304bca2138cf8004070b3573a1e17183c0c1a8\"\n        assert fivetran_package in contents\n        assert dbt_labs_package in contents\n        assert package_sha in contents\n\n    def test_deps_add(self, clean_start):\n        run_dbt([\"deps\", \"--add-package\", \"dbt-labs/audit_helper@0.9.0\"])\n        with open(\"packages.yml\") as fp:\n            contents = fp.read()\n        assert (\n            contents\n            == \"\"\"packages:\n  - package: fivetran/fivetran_utils\n    version: 0.4.7\n  - package: dbt-labs/audit_helper\n    version: 0.9.0\n\"\"\"\n        )\n        assert len(os.listdir(\"dbt_packages\")) == 3\n\n    def test_deps_add_without_install(self, clean_start):\n        os.rename(\"packages.yml\", \"dependencies.yml\")\n        run_dbt(\n            [\n                \"deps\",\n                \"--add-package\",\n                \"dbt-labs/audit_helper@0.9.0\",\n                \"--lock\",\n            ]\n        )\n        assert not os.path.exists(\"dbt_packages\")\n        assert not os.path.exists(\"packages.yml\")\n        with open(\"dependencies.yml\") as fp:\n            contents = fp.read()\n        assert (\n            contents\n            == \"\"\"packages:\n  - package: fivetran/fivetran_utils\n    version: 0.4.7\n  - package: dbt-labs/audit_helper\n    version: 0.9.0\n\"\"\"\n        )\n\n    def test_deps_upgrade(self, clean_start, mocker):\n        run_dbt([\"deps\", \"--lock\"])\n        patched_lock = mocker.patch(\"dbt.task.deps.DepsTask.lock\")\n        run_dbt([\"deps\", \"--upgrade\"])\n        assert patched_lock.call_count == 1\n"
  },
  {
    "path": "tests/functional/dependencies/test_dependency_secrets.py",
    "content": "import os\n\nimport pytest\n\nfrom dbt.tests.util import run_dbt_and_capture\nfrom dbt_common.constants import SECRET_ENV_PREFIX\n\n\nclass TestSecretInPackage:\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self):\n        os.environ[SECRET_ENV_PREFIX + \"_FOR_LOGGING\"] = \"super secret\"\n        yield\n        del os.environ[SECRET_ENV_PREFIX + \"_FOR_LOGGING\"]\n\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\n            \"packages\": [\n                {\n                    \"package\": \"dbt-labs/dbt_utils{{ log(env_var('DBT_ENV_SECRET_FOR_LOGGING'), info = true) }}\",\n                    \"version\": \"1.0.0\",\n                }\n            ]\n        }\n\n    def test_mask_secrets(self, project):\n        _, log_output = run_dbt_and_capture([\"deps\"])\n        # this will not be written to logs\n        assert not (\"super secret\" in log_output)\n        assert \"*****\" in log_output\n        assert not (\"DBT_ENV_SECRET_FOR_LOGGING\" in log_output)\n"
  },
  {
    "path": "tests/functional/dependencies/test_local_dependency.py",
    "content": "import json\nimport os\nimport shutil\nfrom pathlib import Path\nfrom unittest import mock\n\nimport pytest\nimport yaml\n\nimport dbt.config\nimport dbt.exceptions\nimport dbt_common.exceptions\nimport dbt_common.semver as semver\nfrom dbt import deprecations\nfrom dbt.tests.util import (\n    check_relations_equal,\n    run_dbt,\n    run_dbt_and_capture,\n    write_file,\n)\nfrom tests.functional.utils import up_one\n\n# todo: make self.unique_schema to fixture\n\n\nmodels__dep_source = \"\"\"\n{# If our dependency source didn't exist, this would be an errror #}\nselect * from {{ source('seed_source', 'seed') }}\n\"\"\"\n\nmodels__my_configured_model = \"\"\"\n{{\n    config(schema='configured')\n}}\nselect * from {{ ref('model_to_import') }}\n\"\"\"\n\nmodels__my_model = \"\"\"\nselect * from {{ ref('model_to_import') }}\n\"\"\"\n\nmodels__source_override_model = \"\"\"\n{# If our source override didn't take, this would be an errror #}\nselect * from {{ source('my_source', 'my_table') }}\n\"\"\"\n\nmodels__iterate = \"\"\"\n{% for x in no_such_dependency.no_such_method() %}\n{% endfor %}\n\"\"\"\n\nmodels__hooks_actual = \"\"\"\nselect * from {{ var('test_create_table') }}\nunion all\nselect * from {{ var('test_create_second_table') }}\n\"\"\"\n\nmodels__hooks_expected = \"\"\"\n{# surely there is a better way to do this! #}\n\n{% for _ in range(1, 5) %}\nselect {{ loop.index }} as id\n{% if not loop.last %}union all{% endif %}\n{% endfor %}\n\"\"\"\n\nproperties__schema_yml = \"\"\"\nversion: 2\nsources:\n  - name: my_source\n    schema: \"{{ var('schema_override', target.schema) }}\"\n    tables:\n      - name: my_table\n        identifier: seed_subpackage_generate_alias_name\n\"\"\"\n\nmacros__macro_sql = \"\"\"\n{# This macro also exists in the dependency -dbt should be fine with that #}\n{% macro some_overridden_macro() -%}\n999\n{%- endmacro %}\n\"\"\"\n\nmacros__macro_override_schema_sql = \"\"\"\n{% macro generate_schema_name(schema_name, node) -%}\n\n    {{ schema_name }}_{{ node.schema }}_macro\n\n{%- endmacro %}\n\"\"\"\n\n\nclass BaseDependencyTest(object):\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"macro.sql\": macros__macro_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"dep_source_model.sql\": models__dep_source,\n            \"my_configured_model.sql\": models__my_configured_model,\n            \"my_model.sql\": models__my_model,\n            \"source_override_model.sql\": models__source_override_model,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def properties(self):\n        return {\n            \"schema.yml\": properties__schema_yml,\n        }\n\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def modify_schema_fqn(self, project):\n        schema_fqn = \"{}.{}\".format(\n            project.database,\n            project.test_schema,\n        )\n        schema_fqn_configured = \"{}.{}\".format(\n            project.database,\n            project.test_schema + \"_configured\",\n        )\n\n        project.created_schemas.append(schema_fqn)\n        project.created_schemas.append(schema_fqn_configured)\n\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project, modify_schema_fqn):\n        shutil.copytree(\n            project.test_dir / Path(\"local_dependency\"),\n            project.project_root / Path(\"local_dependency\"),\n        )\n\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\"packages\": [{\"local\": \"local_dependency\"}]}\n\n\nclass TestSimpleDependency(BaseDependencyTest):\n    def test_local_dependency(self, project):\n        run_dbt([\"deps\"])\n        run_dbt([\"seed\"])\n        results = run_dbt()\n        assert len(results) == 5\n\n        assert {r.node.schema for r in results} == {\n            project.test_schema,\n            project.test_schema + \"_configured\",\n        }\n\n        base_schema_nodes = [r.node for r in results if r.node.schema == project.test_schema]\n        assert len(base_schema_nodes) == 4\n\n        check_relations_equal(\n            project.adapter,\n            [\n                f\"{project.test_schema}.source_override_model\",\n                f\"{project.test_schema}.seed_subpackage_generate_alias_name\",\n            ],\n        )\n        check_relations_equal(\n            project.adapter,\n            [\n                f\"{project.test_schema}.dep_source_model\",\n                f\"{project.test_schema}.seed_subpackage_generate_alias_name\",\n            ],\n        )\n\n    def test_no_dependency_paths(self, project):\n        run_dbt([\"deps\"])\n        run_dbt([\"seed\"])\n\n        # prove dependency does not exist as model in project\n        dep_path = os.path.join(\"models_local\", \"model_to_import.sql\")\n        results = run_dbt(\n            [\"run\", \"--models\", f\"+{dep_path}\"],\n        )\n        assert len(results) == 0\n\n        # prove model can run when importing that dependency\n        local_path = Path(\"models\") / \"my_model.sql\"\n        results = run_dbt(\n            [\"run\", \"--models\", f\"+{local_path}\"],\n        )\n        assert len(results) == 2\n\n\nclass TestSimpleDependencyRelativePath(BaseDependencyTest):\n    def test_local_dependency_relative_path(self, project):\n        last_dir = Path(project.project_root).name\n        with up_one():\n            _, stdout = run_dbt_and_capture([\"deps\", \"--project-dir\", last_dir])\n            assert (\n                \"Installed from <local @ local_dependency>\" in stdout\n            ), \"Test output didn't contain expected string\"\n\n\nclass TestMissingDependency(object):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"iterate.sql\": models__iterate,\n        }\n\n    def test_missing_dependency(self, project):\n        # dbt should raise a runtime exception\n        with pytest.raises(dbt_common.exceptions.DbtRuntimeError):\n            run_dbt([\"compile\"])\n\n\nclass TestSimpleDependencyWithSchema(BaseDependencyTest):\n    def dbt_vargs(self, schema):\n        # we can't add this to the config because Sources don't respect dbt_project.yml\n        vars_arg = yaml.safe_dump({\"schema_override\": \"dbt_test_{}_macro\".format(schema)})\n        return [\"--vars\", vars_arg]\n\n    def project_config(self):\n        return {\n            \"models\": {\n                \"schema\": \"dbt_test\",\n            },\n            \"seeds\": {\n                \"schema\": \"dbt_test\",\n            },\n        }\n\n    @mock.patch(\"dbt.config.project.get_installed_version\")\n    def test_local_dependency_out_of_date(self, mock_get, project):\n        mock_get.return_value = semver.VersionSpecifier.from_version_string(\"0.0.1\")\n        run_dbt([\"deps\"] + self.dbt_vargs(project.test_schema))\n        # check seed\n        with pytest.raises(dbt.exceptions.DbtProjectError) as exc:\n            run_dbt([\"seed\"] + self.dbt_vargs(project.test_schema))\n        assert \"--no-version-check\" in str(exc.value)\n        # check run too\n        with pytest.raises(dbt.exceptions.DbtProjectError) as exc:\n            run_dbt([\"run\"] + self.dbt_vargs(project.test_schema))\n        assert \"--no-version-check\" in str(exc.value)\n\n    @mock.patch(\"dbt.config.project.get_installed_version\")\n    def test_local_dependency_out_of_date_no_check(self, mock_get):\n        mock_get.return_value = semver.VersionSpecifier.from_version_string(\"0.0.1\")\n        run_dbt([\"deps\"])\n        run_dbt([\"seed\", \"--no-version-check\"])\n        results = run_dbt([\"run\", \"--no-version-check\"])\n        assert len(results) == 5\n\n\nclass TestSimpleDependencyNoVersionCheckConfig(BaseDependencyTest):\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"flags\": {\n                \"send_anonymous_usage_stats\": False,\n                \"version_check\": False,\n            },\n            \"models\": {\n                \"schema\": \"dbt_test\",\n            },\n            \"seeds\": {\n                \"schema\": \"dbt_test\",\n            },\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"macro.sql\": macros__macro_override_schema_sql}\n\n    @mock.patch(\"dbt.config.project.get_installed_version\")\n    def test_local_dependency_out_of_date_no_check(self, mock_get, project):\n        # we can't add this to the config because Sources don't respect dbt_project.yml\n        base_schema = \"dbt_test_{}_macro\".format(project.test_schema)\n        vars_arg = yaml.safe_dump(\n            {\n                \"schema_override\": base_schema,\n            }\n        )\n\n        mock_get.return_value = semver.VersionSpecifier.from_version_string(\"0.0.1\")\n        run_dbt([\"deps\", \"--vars\", vars_arg])\n        run_dbt([\"seed\", \"--vars\", vars_arg])\n        results = run_dbt([\"run\", \"--vars\", vars_arg])\n        len(results) == 5\n\n\nclass TestSimpleDependencyHooks(BaseDependencyTest):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"actual.sql\": models__hooks_actual,\n            \"expected.sql\": models__hooks_expected,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        # these hooks should run first, so nothing to drop\n        return {\n            \"on-run-start\": [\n                \"drop table if exists {{ var('test_create_table') }}\",\n                \"drop table if exists {{ var('test_create_second_table') }}\",\n            ]\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\n            \"packages\": [{\"local\": \"early_hook_dependency\"}, {\"local\": \"late_hook_dependency\"}]\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def prepare_dependencies(self, project):\n        shutil.copytree(\n            project.test_dir / Path(\"early_hook_dependency\"),\n            project.project_root / Path(\"early_hook_dependency\"),\n        )\n        shutil.copytree(\n            project.test_dir / Path(\"late_hook_dependency\"),\n            project.project_root / Path(\"late_hook_dependency\"),\n        )\n\n    def test_hook_dependency(self, prepare_dependencies, project):\n        cli_vars = json.dumps(\n            {\n                \"test_create_table\": '\"{}\".\"hook_test\"'.format(project.test_schema),\n                \"test_create_second_table\": '\"{}\".\"hook_test_2\"'.format(project.test_schema),\n            }\n        )\n\n        run_dbt([\"deps\", \"--vars\", cli_vars])\n        results = run_dbt([\"run\", \"--vars\", cli_vars])\n        assert len(results) == 8\n        check_relations_equal(project.adapter, [\"actual\", \"expected\"])\n\n\nclass TestSimpleDependencyDuplicateName(BaseDependencyTest):\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self):\n        pass  # do not copy local dependency automatically\n\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\"packages\": [{\"local\": \"duplicate_dependency\"}]}\n\n    @pytest.fixture(scope=\"class\")\n    def prepare_dependencies(self, project):\n        shutil.copytree(\n            project.test_dir / Path(\"duplicate_dependency\"),\n            project.project_root / Path(\"duplicate_dependency\"),\n        )\n\n    def test_local_dependency_same_name(self, prepare_dependencies, project):\n        with pytest.raises(dbt.exceptions.DependencyError):\n            run_dbt([\"deps\"], expect_pass=False)\n\n    def test_local_dependency_same_name_sneaky(self, prepare_dependencies, project):\n        shutil.copytree(\"duplicate_dependency\", \"./dbt_packages/duplicate_dependency\")\n        with pytest.raises(dbt_common.exceptions.CompilationError):\n            run_dbt([\"compile\"])\n\n        # needed to avoid compilation errors from duplicate package names in test autocleanup\n        run_dbt([\"clean\"])\n\n\nsource_with_tests = \"\"\"\nsources:\n  - name: my_source\n    schema: invalid_schema\n    tables:\n      - name: my_table\n  - name: seed_source\n    schema: \"{{ var('schema_override', target.schema) }}\"\n    tables:\n      - name: \"seed\"\n        identifier: \"seed_subpackage_generate_alias_name\"\n        columns:\n          - name: id\n            tests:\n              - unique\n              - not_null\n\"\"\"\n\n\nclass TestDependencyTestsConfig(BaseDependencyTest):\n    def test_dependency_tests_config(self, project):\n        run_dbt([\"deps\"])\n        # Write a file to local_dependency with a \"tests\" config\n        write_file(\n            source_with_tests, project.project_root, \"local_dependency\", \"models\", \"schema.yml\"\n        )\n        run_dbt([\"parse\"])\n        # Check that project-test-config is NOT in active deprecations, since \"tests\" is only\n        # in a dependent project.\n        assert \"project-test-config\" not in deprecations.active_deprecations\n"
  },
  {
    "path": "tests/functional/dependencies/test_simple_dependency.py",
    "content": "import os\nimport tempfile\nfrom pathlib import Path\n\nimport pytest\n\nfrom dbt.exceptions import DbtProjectError\nfrom dbt.tests.util import check_relations_equal, run_dbt, write_config_file\n\nmodels__disabled_one = \"\"\"\n{{config(enabled=False)}}\n\nselect 1\n\"\"\"\n\nmodels__disabled_two = \"\"\"\n{{config(enabled=False)}}\n\nselect * from {{ref('disabled_one')}}\n\"\"\"\n\nmodels__empty = \"\"\"\n\"\"\"\n\nmodels__view_summary = \"\"\"\n{{\n    config(\n        materialized='view'\n    )\n}}\n\n\nwith t as (\n\n    select * from {{ ref('view_model') }}\n\n)\n\nselect date_trunc('year', updated_at) as year,\n       count(*)\nfrom t\ngroup by 1\n\"\"\"\n\n\nclass SimpleDependencyBase(object):\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project):\n        project.run_sql_file(project.test_data_dir / Path(\"seed.sql\"))\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"empty.sql\": models__empty,\n            \"view_summary.sql\": models__view_summary,\n            \"view_summary.sql\": models__view_summary,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\n            \"packages\": [\n                {\n                    \"git\": \"https://github.com/dbt-labs/dbt-integration-project\",\n                    \"revision\": \"1.1\",\n                }\n            ]\n        }\n\n    # These two functions included to enable override in ...NoProfile derived test class\n    @pytest.fixture(scope=\"class\")\n    def run_deps(self, project):\n        return run_dbt([\"deps\"])\n\n    @pytest.fixture(scope=\"function\")\n    def run_clean(self, project):\n        yield\n\n        # clear test schema\n        assert os.path.exists(\"target\")\n        run_dbt([\"clean\"])\n        assert not os.path.exists(\"target\")\n\n\nclass TestSimpleDependency(SimpleDependencyBase):\n    def test_simple_dependency(self, run_deps, project, run_clean):\n        \"\"\"dependencies should draw from a changing base table\"\"\"\n        results = run_dbt()\n        assert len(results) == 4\n\n        check_relations_equal(project.adapter, [\"seed\", \"table_model\"])\n        check_relations_equal(project.adapter, [\"seed\", \"view_model\"])\n        check_relations_equal(project.adapter, [\"seed\", \"incremental\"])\n        check_relations_equal(project.adapter, [\"seed_summary\", \"view_summary\"])\n\n        project.run_sql_file(project.test_data_dir / Path(\"update.sql\"))\n        results = run_dbt()\n        assert len(results) == 4\n\n        check_relations_equal(project.adapter, [\"seed\", \"table_model\"])\n        check_relations_equal(project.adapter, [\"seed\", \"view_model\"])\n        check_relations_equal(project.adapter, [\"seed\", \"incremental\"])\n\n\nclass TestSimpleDependencyWithDependenciesFile(SimpleDependencyBase):\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {}\n\n    @pytest.fixture(scope=\"class\")\n    def dependencies(self):\n        return {\n            \"packages\": [\n                {\n                    \"git\": \"https://github.com/dbt-labs/dbt-integration-project\",\n                    \"warn-unpinned\": True,\n                }\n            ]\n        }\n\n    def test_dependency_with_dependencies_file(self, run_deps, project):\n        # Tests that \"packages\" defined in a dependencies.yml file works\n        run_dbt([\"deps\"])\n        results = run_dbt()\n        assert len(results) == 4\n\n\nclass TestSimpleDependencyWithEmptyPackagesFile(SimpleDependencyBase):\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return \" \"\n\n    def test_dependency_with_empty_packages_file(self, run_deps, project):\n        # Tests that an empty packages file doesn't fail with a Python error\n        run_dbt([\"deps\"])\n\n\nclass TestSimpleDependencyNoProfile(SimpleDependencyBase):\n    \"\"\"dbt deps and clean commands should not require a profile.\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def run_deps(self, project):\n        with tempfile.TemporaryDirectory() as tmpdir:\n            result = run_dbt([\"deps\", \"--profiles-dir\", tmpdir])\n        return result\n\n    @pytest.fixture(scope=\"class\")\n    def run_clean(self, project):\n        with tempfile.TemporaryDirectory() as tmpdir:\n            result = run_dbt([\"clean\", \"--profiles-dir\", tmpdir])\n        return result\n\n    def test_simple_dependency_no_profile(self, project, run_deps, run_clean):\n        \"\"\"only need fixtures as opposed to any model assertions since those are\n        irrelevant and won't occur within the same runtime as a dbt run -s ...\"\"\"\n        pass\n\n\nclass TestSimpleDependencyWithModels(SimpleDependencyBase):\n    def test_simple_dependency_with_models(self, run_deps, project, run_clean):\n        results = run_dbt([\"run\", \"--models\", \"view_model+\"])\n        len(results) == 2\n\n        check_relations_equal(project.adapter, [\"seed\", \"view_model\"])\n        check_relations_equal(project.adapter, [\"seed_summary\", \"view_summary\"])\n\n        created_models = project.get_tables_in_schema()\n\n        assert \"table_model\" not in created_models\n        assert \"incremental\" not in created_models\n        assert created_models[\"view_model\"] == \"view\"\n        assert created_models[\"view_summary\"] == \"view\"\n\n\nclass TestSimpleDependencyUnpinned(object):\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project):\n        project.run_sql_file(project.test_data_dir / Path(\"seed.sql\"))\n\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\n            \"packages\": [\n                {\n                    \"git\": \"https://github.com/dbt-labs/dbt-integration-project\",\n                    \"warn-unpinned\": True,\n                }\n            ]\n        }\n\n    def test_simple_dependency(self, project):\n        run_dbt([\"deps\"])\n\n\nclass TestSimpleDependencyWithDuplicates(object):\n    # dbt should convert these into a single dependency internally\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\n            \"packages\": [\n                {\n                    \"git\": \"https://github.com/dbt-labs/dbt-integration-project\",\n                    \"revision\": \"dbt/1.0.0\",\n                },\n                {\n                    \"git\": \"https://github.com/dbt-labs/dbt-integration-project.git\",\n                    \"revision\": \"dbt/1.0.0\",\n                },\n            ]\n        }\n\n    def test_simple_dependency_deps(self, project):\n        run_dbt([\"deps\"])\n\n\nclass TestSimpleDependencyWithSubdirs(object):\n    # dbt should convert these into a single dependency internally\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\n            \"packages\": [\n                {\n                    \"git\": \"https://github.com/dbt-labs/dbt-multipe-packages.git\",\n                    \"subdirectory\": \"dbt-utils-main\",\n                    \"revision\": \"v0.1.0\",\n                },\n                {\n                    \"git\": \"https://github.com/dbt-labs/dbt-multipe-packages.git\",\n                    \"subdirectory\": \"dbt-date-main\",\n                    \"revision\": \"v0.1.0\",\n                },\n            ]\n        }\n\n    def test_git_with_multiple_subdir(self, project):\n        run_dbt([\"deps\"])\n        assert os.path.exists(\"package-lock.yml\")\n        expected = \"\"\"packages:\n  - git: https://github.com/dbt-labs/dbt-multipe-packages.git\n    name: dbt_utils\n    revision: 53782f3ede8fdf307ee1d8e418aa65733a4b72fa\n    subdirectory: dbt-utils-main\n  - git: https://github.com/dbt-labs/dbt-multipe-packages.git\n    name: dbt_date\n    revision: 53782f3ede8fdf307ee1d8e418aa65733a4b72fa\n    subdirectory: dbt-date-main\nsha1_hash: b9c8042f29446c55a33f9f211737f445a640c7a1\n\"\"\"\n        with open(\"package-lock.yml\") as fp:\n            contents = fp.read()\n        assert contents == expected\n        assert len(os.listdir(\"dbt_packages\")) == 2\n\n\nclass TestRekeyedDependencyWithSubduplicates(object):\n    # this revision of dbt-integration-project requires dbt-utils.git@0.5.0, which the\n    # package config handling should detect\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\n            \"packages\": [\n                {\n                    \"git\": \"https://github.com/dbt-labs/dbt-integration-project\",\n                    \"revision\": \"config-1.0.0-deps\",\n                },\n                {\n                    \"git\": \"https://github.com/dbt-labs/dbt-utils\",\n                    \"revision\": \"0.5.0\",\n                },\n            ]\n        }\n\n    def test_simple_dependency_deps(self, project):\n        run_dbt([\"deps\"])\n        assert len(os.listdir(\"dbt_packages\")) == 2\n\n\nclass TestTarballNestedDependencies(object):\n    # this version of dbt_expectations has a dependency on dbt_date, which the\n    # package config handling should detect\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\n            \"packages\": [\n                {\n                    \"tarball\": \"https://github.com/calogica/dbt-expectations/archive/refs/tags/0.9.0.tar.gz\",\n                    \"name\": \"dbt_expectations\",\n                },\n            ]\n        }\n\n    def test_simple_dependency_deps(self, project):\n        run_dbt([\"deps\"])\n        assert set(os.listdir(\"dbt_packages\")) == set([\"dbt_expectations\", \"dbt_date\"])\n\n\nclass DependencyBranchBase(object):\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project):\n        project.run_sql_file(project.test_data_dir / Path(\"seed.sql\"))\n\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\n            \"packages\": [\n                {\n                    \"git\": \"https://github.com/dbt-labs/dbt-integration-project\",\n                    \"revision\": \"dbt/1.0.0\",\n                },\n            ]\n        }\n\n    def deps_run_assert_equality(self, project):\n        run_dbt([\"deps\"])\n        results = run_dbt()\n        assert len(results) == 4\n\n        check_relations_equal(project.adapter, [\"seed\", \"table_model\"])\n        check_relations_equal(project.adapter, [\"seed\", \"view_model\"])\n        check_relations_equal(project.adapter, [\"seed\", \"incremental\"])\n\n        created_models = project.get_tables_in_schema()\n\n        assert created_models[\"table_model\"] == \"table\"\n        assert created_models[\"view_model\"] == \"view\"\n        assert created_models[\"view_summary\"] == \"view\"\n        assert created_models[\"incremental\"] == \"table\"\n\n\nclass TestSimpleDependencyBranch(DependencyBranchBase):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"view_summary.sql\": models__view_summary,\n        }\n\n    def test_simple_dependency(self, project):\n        self.deps_run_assert_equality(project)\n        check_relations_equal(project.adapter, [\"seed_summary\", \"view_summary\"])\n\n        project.run_sql_file(project.test_data_dir / Path(\"update.sql\"))\n        self.deps_run_assert_equality(project)\n\n\nclass TestSimpleDependencyBranchWithEmpty(DependencyBranchBase):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        \"\"\"extra models included\"\"\"\n        return {\n            \"disabled_one.sql\": models__disabled_one,\n            \"disabled_two.sql\": models__disabled_two,\n            \"view_summary.sql\": models__view_summary,\n            \"empty.sql\": models__empty,\n        }\n\n    def test_empty_models_not_compiled_in_dependencies(self, project):\n        self.deps_run_assert_equality(project)\n\n        models = project.get_tables_in_schema()\n\n        assert \"empty\" not in models.keys()\n\n\nclass TestSimpleDependencyBadProfile(object):\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"config-version\": 2,\n            \"models\": {\n                \"+any_config\": \"{{ target.name }}\",\n                \"+enabled\": \"{{ target.name in ['redshift', 'postgres'] | as_bool }}\",\n            },\n        }\n\n    # Write out the profile data as a yaml file\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def dbt_profile_target(self):\n        # Need to set the environment variable here initially because\n        # the unittest setup does a load_config.\n        os.environ[\"PROFILE_TEST_HOST\"] = \"localhost\"\n        return {\n            \"type\": \"postgres\",\n            \"threads\": 4,\n            \"host\": \"{{ env_var('PROFILE_TEST_HOST') }}\",\n            \"port\": 5432,\n            \"user\": \"root\",\n            \"pass\": \"password\",\n            \"dbname\": \"dbt\",\n        }\n\n    def test_deps_bad_profile(self, project):\n        del os.environ[\"PROFILE_TEST_HOST\"]\n        run_dbt([\"deps\"])\n        run_dbt([\"clean\"])\n\n\nclass TestSimpleDependcyTarball(object):\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\n            \"packages\": [\n                {\n                    \"tarball\": \"https://codeload.github.com/dbt-labs/dbt-utils/tar.gz/0.9.6\",\n                    \"name\": \"dbt_utils\",\n                }\n            ]\n        }\n\n    def test_deps_simple_tarball_doesnt_error_out(self, project):\n        run_dbt([\"deps\"])\n        assert len(os.listdir(\"dbt_packages\")) == 1\n\n\nclass TestBadTarballDependency(object):\n    def test_malformed_tarball_package_causes_exception(self, project):\n        # We have to specify the bad formatted package here because if we do it\n        # in a `packages` fixture, the test will blow up in the setup phase, meaning\n        # we can't appropriately catch it with a `pytest.raises`\n        bad_tarball_package_spec = {\n            \"packages\": [\n                {\n                    \"tarball\": \"https://codeload.github.com/dbt-labs/dbt-utils/tar.gz/0.9.6\",\n                    \"version\": \"dbt_utils\",\n                }\n            ]\n        }\n        write_config_file(bad_tarball_package_spec, \"packages.yml\")\n\n        with pytest.raises(\n            DbtProjectError, match=r\"The packages.yml file in this project is malformed\"\n        ) as e:\n            run_dbt([\"deps\"])\n            assert e is not None\n\n\nclass TestEmptyDependency:\n    def test_empty_package(self, project):\n        # We have to specify the bad formatted package here because if we do it\n        # in a `packages` fixture, the test will blow up in the setup phase, meaning\n        # we can't appropriately catch it with a `pytest.raises`\n        empty_hub_package = {\n            \"packages\": [\n                {\n                    \"package\": \"\",\n                    \"version\": \"1.0.0\",\n                }\n            ]\n        }\n        write_config_file(empty_hub_package, \"packages.yml\")\n        with pytest.raises(DbtProjectError, match=\"A hub package is missing the value\"):\n            run_dbt([\"deps\"])\n\n        empty_git_package = {\n            \"packages\": [\n                {\n                    \"git\": \"\",\n                    \"revision\": \"1.0.0\",\n                }\n            ]\n        }\n        write_config_file(empty_git_package, \"packages.yml\")\n        with pytest.raises(DbtProjectError, match=\"A git package is missing the value\"):\n            run_dbt([\"deps\"])\n\n        empty_local_package = {\n            \"packages\": [\n                {\n                    \"local\": \"\",\n                }\n            ]\n        }\n        write_config_file(empty_local_package, \"packages.yml\")\n        with pytest.raises(DbtProjectError, match=\"A local package is missing the value\"):\n            run_dbt([\"deps\"])\n"
  },
  {
    "path": "tests/functional/dependencies/test_simple_dependency_with_configs.py",
    "content": "from pathlib import Path\n\nimport pytest\n\nfrom dbt.tests.util import check_relations_equal, run_dbt\n\nmodels__view_summary = \"\"\"\n{{\n    config(\n        materialized='view'\n    )\n}}\n\n\nwith t as (\n\n    select * from {{ ref('view_model') }}\n\n)\n\nselect date_trunc('year', updated_at) as year,\n       count(*)\nfrom t\ngroup by 1\n\"\"\"\n\n\nclass BaseTestSimpleDependencyWithConfigs(object):\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project):\n        project.run_sql_file(project.test_data_dir / Path(\"seed.sql\"))\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"view_summary.sql\": models__view_summary,\n        }\n\n\nclass TestSimpleDependencyWithConfigs(BaseTestSimpleDependencyWithConfigs):\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\n            \"packages\": [\n                {\n                    \"git\": \"https://github.com/dbt-labs/dbt-integration-project\",\n                    \"revision\": \"with-configs-1.0.0\",\n                },\n            ]\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"config-version\": 2,\n            \"vars\": {\n                \"dbt_integration_project\": {\"bool_config\": True},\n            },\n        }\n\n    def test_simple_dependency(self, project):\n        run_dbt([\"deps\"])\n        results = run_dbt()\n        assert len(results) == 5\n\n        check_relations_equal(project.adapter, [\"seed_config_expected_1\", \"config\"])\n        check_relations_equal(project.adapter, [\"seed\", \"table_model\"])\n        check_relations_equal(project.adapter, [\"seed\", \"view_model\"])\n        check_relations_equal(project.adapter, [\"seed\", \"incremental\"])\n\n\nclass TestSimpleDependencyWithOverriddenConfigs(BaseTestSimpleDependencyWithConfigs):\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\n            \"packages\": [\n                {\n                    \"git\": \"https://github.com/dbt-labs/dbt-integration-project\",\n                    \"revision\": \"with-configs-1.0.0\",\n                },\n            ]\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"config-version\": 2,\n            \"vars\": {\n                # project-level configs\n                \"dbt_integration_project\": {\n                    \"config_1\": \"abc\",\n                    \"config_2\": \"def\",\n                    \"bool_config\": True,\n                },\n            },\n        }\n\n    def test_simple_dependency(self, project):\n        run_dbt([\"deps\"])\n        results = run_dbt([\"run\"])\n        len(results) == 5\n\n        check_relations_equal(project.adapter, [\"seed_config_expected_2\", \"config\"])\n        check_relations_equal(project.adapter, [\"seed\", \"table_model\"])\n        check_relations_equal(project.adapter, [\"seed\", \"view_model\"])\n        check_relations_equal(project.adapter, [\"seed\", \"incremental\"])\n"
  },
  {
    "path": "tests/functional/dependencies/test_uninstalled_package_found_error.py",
    "content": "import shutil\nfrom pathlib import Path\n\nimport pytest\n\nfrom dbt.exceptions import UninstalledPackagesFoundError\nfrom dbt.tests.util import run_dbt\n\n\nclass TestUninstalledPackageWithNestedDependency:\n    \"\"\"When package_a and package_b are specified, package_b has a recursive dependency\n    on package_c, and package_a is uninstalled (missing from dbt_packages),\n    UninstalledPackagesFoundError should be raised.\n    \"\"\"\n\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project):\n        shutil.copytree(\n            project.test_dir / Path(\"nested_dependency\"),\n            project.project_root / Path(\"nested_dependency\"),\n        )\n\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\n            \"packages\": [\n                {\"package\": \"dbt-labs/dbt_utils\", \"version\": \"1.1.1\"},\n                {\"local\": \"nested_dependency\"},\n            ]\n        }\n\n    def test_uninstalled_package_with_nested_dependency(self, project):\n        run_dbt([\"deps\"])\n\n        # Remove the local package by removing the symlink\n        nested_dep_pkg = Path(project.project_root) / \"dbt_packages\" / \"nested_dependency\"\n        nested_dep_pkg.unlink()\n\n        with pytest.raises(UninstalledPackagesFoundError) as exc_info:\n            run_dbt([\"parse\"])\n\n        assert exc_info.value.count_packages_specified == 3\n        assert exc_info.value.count_packages_installed == 2\n        assert \"nested_dependency\" in exc_info.value.uninstalled_packages\n\n\nclass TestUninstalledPackagesErrorRaisedIfPackageLockDoesNotExist:\n    \"\"\"When package_lock.yml does not exist, error should be raised if packages.yml is non empty.\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\n            \"packages\": [\n                {\"package\": \"dbt-labs/dbt_utils\", \"version\": \"1.1.1\"},\n            ]\n        }\n\n    def test_error_raised_if_package_lock_does_not_exist(self, project):\n        package_lock_path = Path(project.project_root) / \"package-lock.yml\"\n        # ensure that package lock does not exist\n        package_lock_path.unlink(missing_ok=True)\n\n        with pytest.raises(UninstalledPackagesFoundError) as exc_info:\n            run_dbt([\"parse\"])\n\n        assert len(exc_info.value.uninstalled_packages) == 0\n        assert exc_info.value.count_packages_specified == 1\n        assert exc_info.value.count_packages_installed == 0\n\n\nclass TestNoErrorIfPackageYamlDoesNotExist:\n    \"\"\"When packages.yml does not exist, no error should be raised.\"\"\"\n\n    def test_no_error_raised_if_package_yml_does_not_exist(self, project):\n        packages_yml_path = Path(project.project_root) / \"packages.yml\"\n        packages_yml_path.unlink(missing_ok=True)\n\n        run_dbt([\"parse\"])\n"
  },
  {
    "path": "tests/functional/deprecations/fixtures.py",
    "content": "models__already_exists_sql = \"\"\"\nselect 1 as id\n\n{% if adapter.already_exists(this.schema, this.identifier) and not should_full_refresh() %}\n    where id > (select max(id) from {{this}})\n{% endif %}\n\"\"\"\n\nmodels_trivial__model_sql = \"\"\"\nselect 1 as id\n\"\"\"\n\nmodels_custom_key_in_config_sql = \"\"\"\n{{ config(my_custom_key=\"my_custom_value\") }}\nselect 1 as id\n\"\"\"\n\nmodels_custom_key_in_config_non_static_parser_sql = \"\"\"\n{{ config(my_custom_key=\"my_custom_value\") }}\n\nselect {{ dbt.current_timestamp() }} as my_timestamp\n\"\"\"\n\nmacros__custom_test_sql = \"\"\"\n{% test custom(model) %}\n  select * from {{ model }}\n  limit 0\n{% endtest %}\n\"\"\"\n\nmodels_pre_post_hook_in_config_sql = \"\"\"\n{{ config(post_hook=\"select 1\", pre_hook=\"select 2\") }}\n\nselect 1 as id\n\"\"\"\n\nbad_name_yaml = \"\"\"\nversion: 2\n\nexposures:\n  - name: simple exposure spaced!!\n    type: dashboard\n    depends_on:\n      - ref('model')\n    owner:\n      email: something@example.com\n\"\"\"\n\n\ndeprecated_model_exposure_yaml = \"\"\"\nversion: 2\n\nmodels:\n  - name: model\n    deprecation_date: 1999-01-01 00:00:00.00+00:00\n\nexposures:\n  - name: simple_exposure\n    type: dashboard\n    depends_on:\n      - ref('model')\n    owner:\n      email: something@example.com\n\"\"\"\n\n# deprecated test config fixtures\ndata_tests_yaml = \"\"\"\nmodels:\n  - name: model\n    columns:\n     - name: id\n       data_tests:\n         - not_null\n\"\"\"\n\ntest_type_mixed_yaml = \"\"\"\nmodels:\n  - name: model\n    columns:\n     - name: id\n       data_tests:\n         - not_null\n       tests:\n         - unique\n\"\"\"\n\nold_tests_yml = \"\"\"\nmodels:\n  - name: model\n    tests:\n      - custom\n    columns:\n      - name: id\n        tests:\n          - not_null\n\n  - name: versioned_model\n    tests:\n      - custom\n    versions:\n      - v: 1\n        tests:\n        columns:\n          - name: id\n            tests:\n              - not_null\n\"\"\"\n\nsources_old_tests_yaml = \"\"\"\nsources:\n  - name: seed_source\n    schema: \"{{ var('schema_override', target.schema) }}\"\n    tables:\n      - name: \"seed\"\n        tests:\n          - custom\n        columns:\n          - name: id\n            tests:\n              - unique\n\"\"\"\n\nseed_csv = \"\"\"id,name\n1,Mary\n2,Sam\n3,John\n\"\"\"\n\n\nlocal_dependency__dbt_project_yml = \"\"\"\n\nname: 'local_dep'\nversion: '1.0'\n\nseeds:\n  quote_columns: False\n\n\"\"\"\n\nlocal_dependency__schema_yml = \"\"\"\nsources:\n  - name: seed_source\n    schema: \"{{ var('schema_override', target.schema) }}\"\n    tables:\n      - name: \"seed\"\n        columns:\n          - name: id\n            tests:\n              - unique\n\"\"\"\n\nlocal_dependency__seed_csv = \"\"\"id,name\n1,Mary\n2,Sam\n3,John\n\"\"\"\n\n\ninvalid_deprecation_date_yaml = \"\"\"\nmodels:\n  - name: models_trivial\n    description: \"This is a test model\"\n    deprecation_date: 1\n\"\"\"\n\nduplicate_keys_yaml = \"\"\"\nmodels:\n  - name: models_trivial\n    description: \"This is a test model\"\n    deprecation_date: 1999-01-01 00:00:00.00+00:00\n\nmodels:\n  - name: models_trivial\n    description: \"This is a test model\"\n    deprecation_date: 1999-01-01 00:00:00.00+00:00\n\"\"\"\n\ncustom_key_in_config_yaml = \"\"\"\nmodels:\n  - name: models_trivial\n    description: \"This is a test model\"\n    deprecation_date: 1999-01-01 00:00:00.00+00:00\n    config:\n      my_custom_key: \"my_custom_value\"\n\"\"\"\n\nmultiple_custom_keys_in_config_yaml = \"\"\"\nmodels:\n  - name: models_trivial\n    description: \"This is a test model\"\n    deprecation_date: 1999-01-01 00:00:00.00+00:00\n    config:\n      my_custom_key: \"my_custom_value\"\n      my_custom_key2: \"my_custom_value2\"\n\"\"\"\n\ncustom_key_in_object_yaml = \"\"\"\nmodels:\n  - name: models_trivial\n    description: \"This is a test model\"\n    deprecation_date: 1999-01-01 00:00:00.00+00:00\n    my_custom_property: \"It's over, I have the high ground\"\n\"\"\"\n\n\npre_post_hook_in_config_yaml = \"\"\"\nmodels:\n  - name: model_with_hook_configs\n    config:\n      post_hook: \"select 1\"\n      pre_hook: \"select 2\"\n\"\"\"\n\n\nproperty_moved_to_config_yaml = \"\"\"\nmodels:\n  - name: models_trivial\n    description: \"This is a test model\"\n    access: public  # deprecated - should be in config\n    columns:\n      - name: id\n        tags: [\"test\"]  # deprecated - should be in config\n\nsources:\n  - name: seed_source\n    schema: \"{{ var('schema_override', target.schema) }}\"\n    tags: [\"test\"]  # deprecated - should be in config\n    freshness: # deprecated - should be in config\n      warn_after:\n        count: 1\n        period: day\n    tables:\n      - name: \"seed\"\n        tags: [\"test\"]  # deprecated - should be in config\n        freshness: # deprecated - should be in config\n          warn_after:\n            count: 1\n            period: day\n        columns:\n          - name: id\n            tags: [\"test\"]  # deprecated - should be in config\n      - name: \"another_table\"\n\"\"\"\n\npython_model_py = \"\"\"\ndef model(dbt, session):\n    finalized_model = dbt.ref(\"trivial_model\")\n    dbt.config.get(\"materialized\")\n    return finalized_model\n\"\"\"\n\npython_model_yml = \"\"\"\nmodels:\n  - name: python_model\n    config:\n      materialized: table\n\"\"\"\n\ntest_with_arguments_yaml = \"\"\"\nmodels:\n  - name: models_trivial\n    tests:\n      - test_name: unique\n        arguments:\n          custom: arg\n      - custom_test:\n          arguments:\n            custom: arg\n      - unique\n      - not_null:\n          where: \"1=1\"\n\"\"\"\n\n\ntest_with_arguments_yaml = \"\"\"\nmodels:\n  - name: models_trivial\n    tests:\n      - test_name: unique\n        arguments:\n          custom: arg\n      - custom_test:\n          arguments:\n            custom: arg\n      - unique\n      - not_null:\n          where: \"1=1\"\n    columns:\n      - name: column\n        tests:\n          - test_name: unique\n            arguments:\n              custom: arg\n          - custom_test:\n              arguments:\n                custom: arg\n          - custom_test2_valid:\n              column_name: id\n              config:\n                where: \"1=1\"\n              custom: arg\n\"\"\"\n\n\ntest_missing_arguments_property_yaml = \"\"\"\nmodels:\n  - name: models_trivial\n    tests:\n      - test_name: unique\n        custom: arg\n      - custom_test:\n          custom: arg\n      - custom_test2_valid:\n          column_name: id\n          config:\n            where: \"1=1\"\n          arguments:\n            custom: arg\n    columns:\n      - name: column\n        tests:\n          - test_name: unique\n            custom: arg\n          - custom_test:\n              custom: arg\n          - custom_test2_valid:\n              column_name: id\n              config:\n                where: \"1=1\"\n              arguments:\n                custom: arg\n      \"\"\"\n\ngenerate_schema_name_null_return_macro_sql = \"\"\"\n{% macro generate_schema_name(custom_schema_name, node) %}\n    {{ return(custom_schema_name) }}\n{% endmacro %}\n\"\"\"\n"
  },
  {
    "path": "tests/functional/deprecations/test_config_deprecations.py",
    "content": "import os\nfrom collections import defaultdict\nfrom typing import Dict\n\nimport pytest\nfrom pytest_mock import MockerFixture\n\nfrom dbt import deprecations\nfrom dbt.exceptions import CompilationError, ProjectContractError, YamlParseDictError\nfrom dbt.tests.fixtures.project import write_project_files\nfrom dbt.tests.util import run_dbt, update_config_file\nfrom tests.functional.deprecations.fixtures import (\n    data_tests_yaml,\n    local_dependency__dbt_project_yml,\n    local_dependency__schema_yml,\n    local_dependency__seed_csv,\n    macros__custom_test_sql,\n    models_trivial__model_sql,\n    old_tests_yml,\n    seed_csv,\n    sources_old_tests_yaml,\n    test_type_mixed_yaml,\n)\n\n\n# TODO: This is now defined 4 times throughout the test suite. We should move it to a utils file.\ndef normalize(path):\n    \"\"\"On windows, neither is enough on its own:\n\n    >>> normcase('C:\\\\documents/ALL CAPS/subdir\\\\..')\n    'c:\\\\documents\\\\all caps\\\\subdir\\\\..'\n    >>> normpath('C:\\\\documents/ALL CAPS/subdir\\\\..')\n    'C:\\\\documents\\\\ALL CAPS'\n    >>> normpath(normcase('C:\\\\documents/ALL CAPS/subdir\\\\..'))\n    'c:\\\\documents\\\\all caps'\n    \"\"\"\n    return os.path.normcase(os.path.normpath(path))\n\n\n# test deprecation messages\nclass TestTestsConfigDeprecation:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model.sql\": models_trivial__model_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self, unique_schema):\n        return {\"tests\": {\"enabled\": \"true\"}}\n\n    def test_project_tests_config(self, project):\n        deprecations.reset_deprecations()\n        assert deprecations.active_deprecations == defaultdict(int)\n        run_dbt([\"parse\"])\n        assert deprecations.active_deprecations == defaultdict(int)\n\n    def test_project_tests_config_fail(self, project):\n        deprecations.reset_deprecations()\n        assert deprecations.active_deprecations == defaultdict(int)\n        with pytest.raises(CompilationError) as exc:\n            run_dbt([\"--warn-error\", \"--no-partial-parse\", \"parse\"])\n        exc_str = \" \".join(str(exc.value).split())  # flatten all whitespace\n        expected_msg = \"Configuration paths exist in your dbt_project.yml file which do not apply to any resources. There are 1 unused configuration paths: - data_tests\"\n        assert expected_msg in exc_str\n\n\nclass TestSchemaTestDeprecation:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model.sql\": models_trivial__model_sql,\n            \"versioned_model.sql\": models_trivial__model_sql,\n            \"schema.yml\": old_tests_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"custom.sql\": macros__custom_test_sql}\n\n    def test_generic_tests_config(self, project):\n        deprecations.reset_deprecations()\n        assert deprecations.active_deprecations == defaultdict(int)\n        run_dbt([\"parse\"])\n        assert deprecations.active_deprecations == defaultdict(int)\n\n    def test_generic_tests_fail(self, project):\n        deprecations.reset_deprecations()\n        assert deprecations.active_deprecations == defaultdict(int)\n        run_dbt([\"--warn-error\", \"--no-partial-parse\", \"parse\"])\n\n    def test_generic_data_test_parsing(self, project):\n        results = run_dbt([\"list\", \"--resource-type\", \"test\"])\n        assert len(results) == 4\n\n\nclass TestSourceSchemaTestDeprecation:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"schema.yml\": sources_old_tests_yaml}\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"custom.sql\": macros__custom_test_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\n            \"seed.csv\": seed_csv,\n        }\n\n    def test_source_tests_config(self, project):\n        deprecations.reset_deprecations()\n        assert deprecations.active_deprecations == defaultdict(int)\n        run_dbt([\"parse\"])\n        assert deprecations.active_deprecations == defaultdict(int)\n\n    def test_generic_data_tests(self, project):\n        run_dbt([\"seed\"])\n        results = run_dbt([\"test\"])\n        assert len(results) == 2\n\n\n# test for failure with test and data_tests in the same file\nclass TestBothSchemaTestDeprecation:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model.sql\": models_trivial__model_sql, \"schema.yml\": test_type_mixed_yaml}\n\n    def test_schema(self, project):\n        expected_msg = \"Invalid test config: cannot have both 'tests' and 'data_tests' defined\"\n        with pytest.raises(YamlParseDictError) as excinfo:\n            run_dbt([\"parse\"])\n        assert expected_msg in str(excinfo.value)\n\n\n# test for failure with  test and data_tests in the same dbt_project.yml\nclass TestBothProjectTestDeprecation:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model.sql\": models_trivial__model_sql}\n\n    def test_tests_config(self, project):\n        config_patch = {\"tests\": {\"+enabled\": \"true\"}, \"data_tests\": {\"+tags\": \"super\"}}\n        update_config_file(config_patch, project.project_root, \"dbt_project.yml\")\n\n        expected_msg = \"Invalid project config: cannot have both 'tests' and 'data_tests' defined\"\n        with pytest.raises(ProjectContractError) as excinfo:\n            run_dbt([\"parse\"])\n        assert expected_msg in str(excinfo.value)\n\n\n# test a local dependency can have tests while the rest of the project uses data_tests\nclass TestTestConfigInDependency:\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project_root):\n        local_dependency_files = {\n            \"dbt_project.yml\": local_dependency__dbt_project_yml,\n            \"models\": {\n                \"schema.yml\": local_dependency__schema_yml,\n            },\n            \"seeds\": {\"seed.csv\": local_dependency__seed_csv},\n        }\n        write_project_files(project_root, \"local_dependency\", local_dependency_files)\n\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\"packages\": [{\"local\": \"local_dependency\"}]}\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model.sql\": models_trivial__model_sql,\n            \"schema.yml\": data_tests_yaml,\n        }\n\n    def test_test_dep(self, project):\n        run_dbt([\"deps\"])\n        run_dbt([\"seed\"])\n        run_dbt([\"run\"])\n        results = run_dbt([\"test\"])\n        # 1 data_test in the dep and 1 in the project\n        assert len(results) == 2\n\n\nclass TestValidateModelConfigOnlyCalledOncePerModel:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model.sql\": models_trivial__model_sql,\n            \"versioned_model.sql\": models_trivial__model_sql,\n            \"schema.yml\": old_tests_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"custom.sql\": macros__custom_test_sql}\n\n    def test_validate_model_config_only_called_once_per_model(\n        self, project, models: Dict[str, str], mocker: MockerFixture\n    ):\n        mocked_vmc = mocker.patch(\"dbt.parser.base.validate_model_config\")\n        run_dbt(\n            [\"parse\", \"--no-partial-parse\"],\n        )\n        # this is a list of all the files that validate_model_config was called on\n        called_on_files = [call.args[1] for call in mocked_vmc.call_args_list]\n\n        # this entire test is only useful if we have validated more than one file\n        assert len(called_on_files) > 1\n\n        # Each model sql file should have been validated once\n        assert len(called_on_files) == len(set(called_on_files))\n\n        # Only model sql files should have been validated\n        sql_model_files = [file for file in models.keys() if file.endswith(\".sql\")]\n        assert len(called_on_files) == len(sql_model_files)\n        for file in sql_model_files:\n            assert normalize(f\"models/{file}\") in called_on_files\n"
  },
  {
    "path": "tests/functional/deprecations/test_deprecations.py",
    "content": "import os\nimport sys\nfrom collections import defaultdict\nfrom unittest import mock\n\nimport pytest\nimport yaml\nfrom pytest_mock import MockerFixture\n\nimport dbt_common\nfrom dbt import deprecations\nfrom dbt.cli.main import dbtRunner\nfrom dbt.clients.registry import _get_cached\nfrom dbt.events.types import (\n    ArgumentsPropertyInGenericTestDeprecation,\n    CustomKeyInConfigDeprecation,\n    CustomKeyInObjectDeprecation,\n    CustomOutputPathInSourceFreshnessDeprecation,\n    DeprecationsSummary,\n    DuplicateYAMLKeysDeprecation,\n    EnvironmentVariableNamespaceDeprecation,\n    GenerateSchemaNameNullValueDeprecation,\n    GenericJSONSchemaValidationDeprecation,\n    MissingArgumentsPropertyInGenericTestDeprecation,\n    ModelParamUsageDeprecation,\n    ModulesItertoolsUsageDeprecation,\n    PackageRedirectDeprecation,\n    PropertyMovedToConfigDeprecation,\n    WEOIncludeExcludeDeprecation,\n)\nfrom dbt.tests.util import read_file, run_dbt, run_dbt_and_capture, write_file\nfrom dbt_common.events.event_catcher import EventCatcher\nfrom dbt_common.events.types import Note\nfrom dbt_common.exceptions import EventCompilationError\nfrom tests.functional.deprecations.fixtures import (\n    bad_name_yaml,\n    custom_key_in_config_yaml,\n    custom_key_in_object_yaml,\n    deprecated_model_exposure_yaml,\n    duplicate_keys_yaml,\n    generate_schema_name_null_return_macro_sql,\n    invalid_deprecation_date_yaml,\n    models_custom_key_in_config_non_static_parser_sql,\n    models_custom_key_in_config_sql,\n    models_pre_post_hook_in_config_sql,\n    models_trivial__model_sql,\n    multiple_custom_keys_in_config_yaml,\n    pre_post_hook_in_config_yaml,\n    property_moved_to_config_yaml,\n    python_model_py,\n    python_model_yml,\n    test_missing_arguments_property_yaml,\n    test_with_arguments_yaml,\n)\n\n\nclass TestConfigPathDeprecation:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"already_exists.sql\": models_trivial__model_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"config-version\": 2,\n            \"data-paths\": [\"data\"],\n            \"log-path\": \"customlogs\",\n            \"target-path\": \"customtarget\",\n        }\n\n    def test_data_path(self, project):\n        deprecations.reset_deprecations()\n        assert deprecations.active_deprecations == defaultdict(int)\n        run_dbt([\"debug\"])\n        expected = {\n            \"project-config-data-paths\",\n            \"project-config-log-path\",\n            \"project-config-target-path\",\n        }\n        for deprecation in expected:\n            assert deprecation in deprecations.active_deprecations\n\n    def test_data_path_fail(self, project):\n        deprecations.reset_deprecations()\n        assert deprecations.active_deprecations == defaultdict(int)\n        with pytest.raises(dbt_common.exceptions.CompilationError) as exc:\n            run_dbt([\"--warn-error\", \"debug\"])\n        exc_str = \" \".join(str(exc.value).split())  # flatten all whitespace\n        expected_msg = \"The `data-paths` config has been renamed\"\n        assert expected_msg in exc_str\n\n\nclass TestPackageInstallPathDeprecation:\n    @pytest.fixture(scope=\"class\")\n    def models_trivial(self):\n        return {\"model.sql\": models_trivial__model_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\"config-version\": 2, \"clean-targets\": [\"dbt_modules\"]}\n\n    def test_package_path(self, project):\n        deprecations.reset_deprecations()\n        assert deprecations.active_deprecations == defaultdict(int)\n        run_dbt([\"clean\"])\n        assert \"install-packages-path\" in deprecations.active_deprecations\n\n    def test_package_path_not_set(self, project):\n        deprecations.reset_deprecations()\n        assert deprecations.active_deprecations == defaultdict(int)\n        with pytest.raises(dbt_common.exceptions.CompilationError) as exc:\n            run_dbt([\"--warn-error\", \"clean\"])\n        exc_str = \" \".join(str(exc.value).split())  # flatten all whitespace\n        expected_msg = \"path has changed from `dbt_modules` to `dbt_packages`.\"\n        assert expected_msg in exc_str\n\n\nclass TestPackageRedirectDeprecation:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"already_exists.sql\": models_trivial__model_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\"packages\": [{\"package\": \"fishtown-analytics/dbt_utils\", \"version\": \"0.7.0\"}]}\n\n    def test_package_redirect(self, project):\n        deprecations.reset_deprecations()\n        assert deprecations.active_deprecations == defaultdict(int)\n        run_dbt([\"deps\"])\n        assert \"package-redirect\" in deprecations.active_deprecations\n\n    # if this test comes before test_package_redirect it will raise an exception as expected\n    def test_package_redirect_fail(self, project):\n        deprecations.reset_deprecations()\n        assert deprecations.active_deprecations == defaultdict(int)\n        with pytest.raises(dbt_common.exceptions.CompilationError) as exc:\n            run_dbt([\"--warn-error\", \"deps\"])\n        exc_str = \" \".join(str(exc.value).split())  # flatten all whitespace\n        expected_msg = \"The `fishtown-analytics/dbt_utils` package is deprecated in favor of `dbt-labs/dbt_utils`\"\n        assert expected_msg in exc_str\n\n\nclass TestDeprecatedModelExposure:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model.sql\": models_trivial__model_sql,\n            \"exposure.yml\": deprecated_model_exposure_yaml,\n        }\n\n    def test_exposure_with_deprecated_model(self, project):\n        run_dbt([\"parse\"])\n\n\nclass TestExposureNameDeprecation:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model.sql\": models_trivial__model_sql, \"bad_name.yml\": bad_name_yaml}\n\n    def test_exposure_name(self, project):\n        deprecations.reset_deprecations()\n        assert deprecations.active_deprecations == defaultdict(int)\n        run_dbt([\"parse\"])\n        assert \"exposure-name\" in deprecations.active_deprecations\n\n    def test_exposure_name_fail(self, project):\n        deprecations.reset_deprecations()\n        assert deprecations.active_deprecations == defaultdict(int)\n        with pytest.raises(dbt_common.exceptions.CompilationError) as exc:\n            run_dbt([\"--warn-error\", \"--no-partial-parse\", \"parse\"])\n        exc_str = \" \".join(str(exc.value).split())  # flatten all whitespace\n        expected_msg = \"Starting in v1.3, the 'name' of an exposure should contain only letters, numbers, and underscores.\"\n        assert expected_msg in exc_str\n\n\nclass TestProjectFlagsMovedDeprecation:\n    @pytest.fixture(scope=\"class\")\n    def profiles_config_update(self):\n        return {\n            \"config\": {\"send_anonymous_usage_stats\": False},\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def dbt_project_yml(self, project_root, project_config_update):\n        project_config = {\n            \"name\": \"test\",\n            \"profile\": \"test\",\n        }\n        write_file(yaml.safe_dump(project_config), project_root, \"dbt_project.yml\")\n        return project_config\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"my_model.sql\": \"select 1 as fun\"}\n\n    def test_profile_config_deprecation(self, project):\n        deprecations.reset_deprecations()\n        assert deprecations.active_deprecations == defaultdict(int)\n\n        _, logs = run_dbt_and_capture([\"parse\"])\n\n        assert (\n            \"User config should be moved from the 'config' key in profiles.yml to the 'flags' key in dbt_project.yml.\"\n            in logs\n        )\n        assert \"project-flags-moved\" in deprecations.active_deprecations\n\n\nclass TestProjectFlagsMovedDeprecationQuiet(TestProjectFlagsMovedDeprecation):\n    def test_profile_config_deprecation(self, project):\n        deprecations.reset_deprecations()\n        assert deprecations.active_deprecations == defaultdict(int)\n\n        _, logs = run_dbt_and_capture([\"--quiet\", \"parse\"])\n\n        assert (\n            \"User config should be moved from the 'config' key in profiles.yml to the 'flags' key in dbt_project.yml.\"\n            not in logs\n        )\n        assert \"project-flags-moved\" in deprecations.active_deprecations\n\n\nclass TestProjectFlagsMovedDeprecationWarnErrorOptions(TestProjectFlagsMovedDeprecation):\n    def test_profile_config_deprecation(self, project):\n        deprecations.reset_deprecations()\n        with pytest.raises(EventCompilationError):\n            run_dbt([\"--warn-error-options\", \"{'error': 'all'}\", \"parse\"])\n\n        with pytest.raises(EventCompilationError):\n            run_dbt(\n                [\"--warn-error-options\", \"{'error': ['ProjectFlagsMovedDeprecation']}\", \"parse\"]\n            )\n\n        _, logs = run_dbt_and_capture(\n            [\"--warn-error-options\", \"{'silence': ['ProjectFlagsMovedDeprecation']}\", \"parse\"]\n        )\n        assert (\n            \"User config should be moved from the 'config' key in profiles.yml to the 'flags' key in dbt_project.yml.\"\n            not in logs\n        )\n\n\nclass TestShowAllDeprecationsFlag:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"already_exists.sql\": models_trivial__model_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\n            \"packages\": [\n                {\"package\": \"fishtown-analytics/dbt_utils\", \"version\": \"0.7.0\"},\n                {\"package\": \"calogica/dbt_date\", \"version\": \"0.10.0\"},\n            ]\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def event_catcher(self) -> EventCatcher:\n        return EventCatcher(event_to_catch=PackageRedirectDeprecation)\n\n    def test_package_redirect(self, project, event_catcher: EventCatcher):\n        deprecations.reset_deprecations()\n        assert deprecations.active_deprecations == defaultdict(int)\n        run_dbt([\"deps\"], callbacks=[event_catcher.catch])\n        assert \"package-redirect\" in deprecations.active_deprecations\n        assert deprecations.active_deprecations[\"package-redirect\"] == 2\n        assert len(event_catcher.caught_events) == 1\n\n        deprecations.reset_deprecations()\n        _get_cached.cache = {}\n        event_catcher.flush()\n        run_dbt([\"deps\", \"--show-all-deprecations\"], callbacks=[event_catcher.catch])\n        assert \"package-redirect\" in deprecations.active_deprecations\n        assert deprecations.active_deprecations[\"package-redirect\"] == 2\n        assert len(event_catcher.caught_events) == 2\n\n\nclass TestDeprecationSummary:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"already_exists.sql\": models_trivial__model_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\n            \"packages\": [\n                {\"package\": \"fishtown-analytics/dbt_utils\", \"version\": \"0.7.0\"},\n                {\"package\": \"calogica/dbt_date\", \"version\": \"0.10.0\"},\n            ]\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def event_catcher(self) -> EventCatcher:\n        return EventCatcher(event_to_catch=DeprecationsSummary)\n\n    def test_package_redirect(self, project, event_catcher: EventCatcher):\n        deprecations.reset_deprecations()\n        assert deprecations.active_deprecations == defaultdict(int)\n        run_dbt([\"deps\"], callbacks=[event_catcher.catch])\n        assert \"package-redirect\" in deprecations.active_deprecations\n        assert deprecations.active_deprecations[\"package-redirect\"] == 2\n        assert len(event_catcher.caught_events) == 1\n        for summary in event_catcher.caught_events[0].data.summaries:  # type: ignore\n            found_summary = False\n            if summary.event_name == \"PackageRedirectDeprecation\":\n                assert (\n                    summary.occurrences == 2\n                ), f\"Expected 2 occurrences of PackageRedirectDeprecation, got {summary.occurrences}\"\n                found_summary = True\n\n        assert found_summary, \"Expected to find PackageRedirectDeprecation in deprecations summary\"\n\n\n@mock.patch(\"dbt.jsonschemas.jsonschemas._JSONSCHEMA_SUPPORTED_ADAPTERS\", {\"postgres\"})\nclass TestDeprecatedInvalidDeprecationDate:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"models_trivial.sql\": models_trivial__model_sql,\n            \"models.yml\": invalid_deprecation_date_yaml,\n        }\n\n    def test_deprecated_invalid_deprecation_date(self, project):\n        event_catcher = EventCatcher(GenericJSONSchemaValidationDeprecation)\n        note_catcher = EventCatcher(Note)\n        try:\n            run_dbt(\n                [\"parse\", \"--no-partial-parse\"],\n                callbacks=[event_catcher.catch, note_catcher.catch],\n            )\n        except:  # noqa\n            assert (\n                True\n            ), \"Expected an exception to be raised, because a model object can't be created with a deprecation_date as an int\"\n\n        # type-based jsonschema validation is not enabled, so no deprecations are raised even though deprecation_date is an int\n        assert len(event_catcher.caught_events) == 0\n        assert len(note_catcher.caught_events) == 0\n\n\nclass TestDuplicateYAMLKeysInSchemaFiles:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"models_trivial.sql\": models_trivial__model_sql,\n            \"models.yml\": duplicate_keys_yaml,\n        }\n\n    def test_duplicate_yaml_keys_in_schema_files(self, project):\n        event_catcher = EventCatcher(DuplicateYAMLKeysDeprecation)\n        run_dbt([\"parse\", \"--no-partial-parse\"], callbacks=[event_catcher.catch])\n        assert len(event_catcher.caught_events) == 1\n        assert (\n            \"Duplicate key 'models' in \\\"<unicode string>\\\", line 6, column 1 in file\"\n            in event_catcher.caught_events[0].info.msg\n        )\n\n\nclass TestCustomKeyInConfigDeprecation:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"models_trivial.sql\": models_trivial__model_sql,\n            \"models.yml\": custom_key_in_config_yaml,\n        }\n\n    @mock.patch(\"dbt.jsonschemas.jsonschemas._JSONSCHEMA_SUPPORTED_ADAPTERS\", {\"postgres\"})\n    def test_custom_key_in_config_deprecation(self, project):\n        event_catcher = EventCatcher(CustomKeyInConfigDeprecation)\n        run_dbt(\n            [\"parse\", \"--no-partial-parse\", \"--show-all-deprecations\"],\n            callbacks=[event_catcher.catch],\n        )\n        assert len(event_catcher.caught_events) == 1\n        assert (\n            \"Custom key `my_custom_key` found in `config` at path `models[0].config`\"\n            in event_catcher.caught_events[0].info.msg\n        )\n\n\nclass TestCustomKeyInConfigSQLDeprecation:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_custom_key_in_config.sql\": models_custom_key_in_config_sql,\n        }\n\n    @mock.patch(\"dbt.jsonschemas.jsonschemas._JSONSCHEMA_SUPPORTED_ADAPTERS\", {\"postgres\"})\n    def test_custom_key_in_config_sql_deprecation(self, project):\n        event_catcher = EventCatcher(CustomKeyInConfigDeprecation)\n        run_dbt(\n            [\"parse\", \"--no-partial-parse\", \"--show-all-deprecations\"],\n            callbacks=[event_catcher.catch],\n        )\n        assert len(event_catcher.caught_events) == 1\n        assert (\n            \"Custom key `my_custom_key` found in `config`\"\n            in event_catcher.caught_events[0].info.msg\n        )\n\n    @mock.patch(\"dbt.jsonschemas.jsonschemas._JSONSCHEMA_SUPPORTED_ADAPTERS\", {\"postgres\"})\n    @mock.patch(\n        \"dbt.jsonschemas.jsonschemas._get_allowed_config_key_aliases\",\n        return_value=[\"my_custom_key\"],\n    )\n    def test_custom_key_in_config_sql_deprecation_adapter_specific_config_key_aliases(\n        self, mock_get_aliases, project\n    ):\n        event_catcher = EventCatcher(CustomKeyInConfigDeprecation)\n        run_dbt(\n            [\"parse\", \"--no-partial-parse\", \"--show-all-deprecations\"],\n            callbacks=[event_catcher.catch],\n        )\n        assert len(event_catcher.caught_events) == 0\n\n\nclass TestCustomKeyInConfigComplexSQLDeprecation(TestCustomKeyInConfigSQLDeprecation):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_custom_key_in_config.sql\": models_custom_key_in_config_non_static_parser_sql,\n        }\n\n\nclass TestMultipleCustomKeysInConfigDeprecation:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"models_trivial.sql\": models_trivial__model_sql,\n            \"models.yml\": multiple_custom_keys_in_config_yaml,\n        }\n\n    @mock.patch(\"dbt.jsonschemas.jsonschemas._JSONSCHEMA_SUPPORTED_ADAPTERS\", {\"postgres\"})\n    def test_multiple_custom_keys_in_config_deprecation(self, project):\n        event_catcher = EventCatcher(CustomKeyInConfigDeprecation)\n        run_dbt(\n            [\"parse\", \"--no-partial-parse\", \"--show-all-deprecations\"],\n            callbacks=[event_catcher.catch],\n        )\n        assert len(event_catcher.caught_events) == 2\n        assert (\n            \"Custom key `my_custom_key` found in `config` at path `models[0].config`\"\n            in event_catcher.caught_events[0].info.msg\n        )\n        assert (\n            \"Custom key `my_custom_key2` found in `config` at path `models[0].config`\"\n            in event_catcher.caught_events[1].info.msg\n        )\n\n\nclass TestCustomKeyInObjectDeprecation:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"models_trivial.sql\": models_trivial__model_sql,\n            \"models.yml\": custom_key_in_object_yaml,\n        }\n\n    @mock.patch(\"dbt.jsonschemas.jsonschemas._JSONSCHEMA_SUPPORTED_ADAPTERS\", {\"postgres\"})\n    def test_custom_key_in_object_deprecation(self, project):\n        event_catcher = EventCatcher(CustomKeyInObjectDeprecation)\n        run_dbt([\"parse\", \"--no-partial-parse\"], callbacks=[event_catcher.catch])\n        assert len(event_catcher.caught_events) == 1\n        assert (\n            \"Custom key `my_custom_property` found at `models[0]` in file\"\n            in event_catcher.caught_events[0].info.msg\n        )\n\n\nclass TestJsonschemaValidationDeprecationsArentRunWithoutEnvVar:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"models_trivial.sql\": models_trivial__model_sql,\n            \"models.yml\": custom_key_in_object_yaml,\n        }\n\n    def test_jsonschema_validation_deprecations_arent_run_without_env_var(self, project):\n        event_catcher = EventCatcher(CustomKeyInObjectDeprecation)\n        run_dbt([\"parse\", \"--no-partial-parse\"], callbacks=[event_catcher.catch])\n        assert len(event_catcher.caught_events) == 0\n\n\nclass TestCustomOutputPathInSourceFreshnessDeprecation:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {}\n\n    def test_jsonschema_validation_deprecations_arent_run_without_env_var(\n        self, project, project_root\n    ):\n        event_catcher = EventCatcher(CustomOutputPathInSourceFreshnessDeprecation)\n\n        write_file(yaml.safe_dump({}), project_root, \"custom_output.json\")\n        run_dbt(\n            [\"source\", \"freshness\", \"--output\", \"custom_output.json\"],\n            callbacks=[event_catcher.catch],\n        )\n        assert len(event_catcher.caught_events) == 1\n\n\nclass TestHappyPathProjectHasNoDeprecations:\n    @mock.patch(\"dbt.jsonschemas.jsonschemas._JSONSCHEMA_SUPPORTED_ADAPTERS\", {\"postgres\"})\n    def test_happy_path_project_has_no_deprecations(self, happy_path_project):\n        event_cathcer = EventCatcher(DeprecationsSummary)\n        run_dbt(\n            [\"parse\", \"--no-partial-parse\", \"--show-all-deprecations\"],\n            callbacks=[event_cathcer.catch],\n        )\n        assert len(event_cathcer.caught_events) == 0\n\n\nclass TestBaseProjectHasNoDeprecations:\n    @mock.patch(\"dbt.jsonschemas.jsonschemas._JSONSCHEMA_SUPPORTED_ADAPTERS\", {\"postgres\"})\n    def test_base_project_has_no_deprecations(self, project):\n        event_cathcer = EventCatcher(DeprecationsSummary)\n        run_dbt(\n            [\"parse\", \"--no-partial-parse\", \"--show-all-deprecations\"],\n            callbacks=[event_cathcer.catch],\n        )\n        assert len(event_cathcer.caught_events) == 0\n\n\nclass TestWEOIncludeExcludeDeprecation:\n    @pytest.mark.parametrize(\n        \"include_error,exclude_warn,expect_deprecation\",\n        [\n            (\"include\", \"exclude\", 1),\n            (\"include\", \"warn\", 1),\n            (\"error\", \"exclude\", 1),\n            (\"error\", \"warn\", 0),\n        ],\n    )\n    def test_weo_include_exclude_deprecation(\n        self,\n        project,\n        include_error: str,\n        exclude_warn: str,\n        expect_deprecation: int,\n    ):\n        event_catcher = EventCatcher(WEOIncludeExcludeDeprecation)\n        warn_error_options = f\"{{'{include_error}': 'all', '{exclude_warn}': ['Deprecations']}}\"\n        run_dbt(\n            [\"parse\", \"--show-all-deprecations\", \"--warn-error-options\", warn_error_options],\n            callbacks=[event_catcher.catch],\n        )\n\n        assert len(event_catcher.caught_events) == expect_deprecation\n        if expect_deprecation > 0:\n            if include_error == \"include\":\n                assert \"include\" in event_catcher.caught_events[0].info.msg\n            else:\n                assert \"include\" not in event_catcher.caught_events[0].info.msg\n            if exclude_warn == \"exclude\":\n                assert \"exclude\" in event_catcher.caught_events[0].info.msg\n            else:\n                assert \"exclude\" not in event_catcher.caught_events[0].info.msg\n\n\nclass TestModulesItertoolsDeprecation:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"models_itertools.sql\": \"\"\"\n            {%- set A = [1] -%}\n            {%- set B = ['x'] -%}\n            {%- set AB_cartesian = modules.itertools.product(A, B) -%}\n\n            {%- for item in AB_cartesian %}\n              select {{ item[0] }}\n            {%- endfor -%}\n            \"\"\",\n        }\n\n    def test_models_itertools(self, project):\n        event_catcher = EventCatcher(ModulesItertoolsUsageDeprecation)\n\n        run_dbt([\"run\", \"--no-partial-parse\"], callbacks=[event_catcher.catch])\n\n        assert len(event_catcher.caught_events) == 1\n        assert (\n            \"Usage of itertools modules is deprecated\" in event_catcher.caught_events[0].info.msg\n        )\n\n        assert (\n            read_file(\"target/compiled/test/models/models_itertools.sql\").strip()\n            == \"select 1\".strip()\n        )\n\n\nclass TestNoModulesItertoolsDeprecation:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"models_itertools.sql\": \"select {{ modules.datetime.datetime.now() }}\",\n        }\n\n    def test_models_itertools(self, project):\n        event_catcher = EventCatcher(ModulesItertoolsUsageDeprecation)\n\n        run_dbt([\"parse\", \"--no-partial-parse\"], callbacks=[event_catcher.catch])\n\n        assert len(event_catcher.caught_events) == 0\n\n\nclass TestModelsParamUsageDeprecation:\n\n    @mock.patch.object(sys, \"argv\", [\"dbt\", \"ls\", \"--models\", \"some_model\"])\n    def test_models_usage(self, project):\n        event_catcher = EventCatcher(ModelParamUsageDeprecation)\n\n        assert len(event_catcher.caught_events) == 0\n        run_dbt(\n            [\"ls\", \"--models\", \"some_model\"],\n            callbacks=[event_catcher.catch],\n        )\n        assert len(event_catcher.caught_events) == 1\n\n\nclass TestModelsParamUsageRunnerDeprecation:\n\n    def test_models_usage(self, project):\n        event_catcher = EventCatcher(ModelParamUsageDeprecation)\n\n        assert len(event_catcher.caught_events) == 0\n        dbtRunner(callbacks=[event_catcher.catch]).invoke([\"ls\", \"--models\", \"some_model\"])\n        assert len(event_catcher.caught_events) == 1\n\n\nclass TestModelParamUsageDeprecation:\n    @mock.patch.object(sys, \"argv\", [\"dbt\", \"ls\", \"--model\", \"some_model\"])\n    def test_model_usage(self, project):\n        event_catcher = EventCatcher(ModelParamUsageDeprecation)\n\n        assert len(event_catcher.caught_events) == 0\n        run_dbt(\n            [\"ls\", \"--model\", \"some_model\"],\n            callbacks=[event_catcher.catch],\n        )\n        assert len(event_catcher.caught_events) == 1\n\n\nclass TestModelParamUsageRunnerDeprecation:\n\n    def test_model_usage(self, project):\n        event_catcher = EventCatcher(ModelParamUsageDeprecation)\n\n        assert len(event_catcher.caught_events) == 0\n        dbtRunner(callbacks=[event_catcher.catch]).invoke([\"ls\", \"--model\", \"some_model\"])\n        assert len(event_catcher.caught_events) == 1\n\n\nclass TestMParamUsageDeprecation:\n    @mock.patch.object(sys, \"argv\", [\"dbt\", \"ls\", \"-m\", \"some_model\"])\n    def test_m_usage(self, project):\n        event_catcher = EventCatcher(ModelParamUsageDeprecation)\n\n        assert len(event_catcher.caught_events) == 0\n        run_dbt(\n            [\"ls\", \"-m\", \"some_model\"],\n            callbacks=[event_catcher.catch],\n        )\n        assert len(event_catcher.caught_events) == 1\n\n\nclass TestMParamUsageRunnerDeprecation:\n    def test_m_usage(self, project):\n        event_catcher = EventCatcher(ModelParamUsageDeprecation)\n\n        assert len(event_catcher.caught_events) == 0\n        dbtRunner(callbacks=[event_catcher.catch]).invoke([\"ls\", \"-m\", \"some_model\"])\n        assert len(event_catcher.caught_events) == 1\n\n\nclass TestSelectParamNoModelUsageDeprecation:\n\n    @mock.patch.object(sys, \"argv\", [\"dbt\", \"ls\", \"--select\", \"some_model\"])\n    def test_select_usage(self, project):\n        event_catcher = EventCatcher(ModelParamUsageDeprecation)\n\n        assert len(event_catcher.caught_events) == 0\n        run_dbt(\n            [\"ls\", \"--select\", \"some_model\"],\n            callbacks=[event_catcher.catch],\n        )\n        assert len(event_catcher.caught_events) == 0\n\n\nclass TestSelectParamNoModelUsageRunnerDeprecation:\n    def test_select_usage(self, project):\n        event_catcher = EventCatcher(ModelParamUsageDeprecation)\n\n        assert len(event_catcher.caught_events) == 0\n        dbtRunner(callbacks=[event_catcher.catch]).invoke([\"ls\", \"--select\", \"some_model\"])\n        assert len(event_catcher.caught_events) == 0\n\n\nclass TestEnvironmentVariableNamespaceDeprecation:\n    @mock.patch.dict(\n        os.environ,\n        {\n            \"DBT_ENGINE_PARTIAL_PARSE\": \"False\",\n            \"DBT_ENGINE_MY_CUSTOM_ENV_VAR_FOR_TESTING\": \"True\",\n        },\n    )\n    def test_environment_variable_namespace_deprecation(self, project):\n        event_catcher = EventCatcher(event_to_catch=EnvironmentVariableNamespaceDeprecation)\n\n        run_dbt([\"parse\", \"--show-all-deprecations\"], callbacks=[event_catcher.catch])\n        assert len(event_catcher.caught_events) == 1\n        assert (\n            \"DBT_ENGINE_MY_CUSTOM_ENV_VAR_FOR_TESTING\"\n            == event_catcher.caught_events[0].data.env_var\n        )\n\n\nclass TestCustomConfigInDbtProjectYmlNoDeprecation:\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\"seeds\": {\"path\": {\"+custom_config\": True}}}\n\n    @mock.patch(\"dbt.jsonschemas.jsonschemas._JSONSCHEMA_SUPPORTED_ADAPTERS\", {\"postgres\"})\n    def test_missing_plus_prefix_deprecation_sub_path(self, project):\n        note_catcher = EventCatcher(Note)\n        run_dbt([\"parse\", \"--no-partial-parse\"], callbacks=[note_catcher.catch])\n        assert len(note_catcher.caught_events) == 0\n\n\nclass TestJsonSchemaValidationGating:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"models_trivial.sql\": models_trivial__model_sql,\n            \"models.yml\": custom_key_in_config_yaml,\n        }\n\n    @pytest.mark.parametrize(\n        \"postgres_is_valid,dbt_private_run_jsonschema_validations,expected_events\",\n        [\n            (True, \"True\", 1),\n            (False, \"True\", 0),\n            (False, \"False\", 0),\n            (False, \"False\", 0),\n        ],\n    )\n    def test_jsonschema_validation_gating(\n        self,\n        project,\n        mocker: MockerFixture,\n        postgres_is_valid: bool,\n        dbt_private_run_jsonschema_validations: bool,\n        expected_events: int,\n    ) -> None:\n\n        if postgres_is_valid:\n            supported_adapters_with_postgres = {\n                \"postgres\",\n                \"bigquery\",\n                \"databricks\",\n                \"redshift\",\n                \"snowflake\",\n            }\n            mocker.patch(\n                \"dbt.jsonschemas.jsonschemas._JSONSCHEMA_SUPPORTED_ADAPTERS\",\n                supported_adapters_with_postgres,\n            )\n\n        event_catcher = EventCatcher(CustomKeyInConfigDeprecation)\n        run_dbt(\n            [\"parse\", \"--no-partial-parse\", \"--show-all-deprecations\"],\n            callbacks=[event_catcher.catch],\n        )\n        assert len(event_catcher.caught_events) == expected_events\n\n\nclass TestArgumentsPropertyInGenericTestDeprecationFalse:\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"config-version\": 2,\n            \"flags\": {\n                \"require_generic_test_arguments_property\": False,\n            },\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"models_trivial.sql\": models_trivial__model_sql,\n            \"models.yml\": test_with_arguments_yaml,\n        }\n\n    def test_arguments_property_in_generic_test_deprecation(self, project):\n        event_catcher = EventCatcher(ArgumentsPropertyInGenericTestDeprecation)\n        run_dbt(\n            [\"parse\", \"--no-partial-parse\", \"--show-all-deprecations\"],\n            callbacks=[event_catcher.catch],\n        )\n        assert len(event_catcher.caught_events) == 4\n\n\nclass TestArgumentsPropertyInGenericTestDeprecationBehaviorChangeDefault:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"models_trivial.sql\": models_trivial__model_sql,\n            \"models.yml\": test_with_arguments_yaml,\n        }\n\n    def test_arguments_property_in_generic_test_deprecation(self, project):\n        event_catcher = EventCatcher(ArgumentsPropertyInGenericTestDeprecation)\n        run_dbt(\n            [\"parse\", \"--no-partial-parse\", \"--show-all-deprecations\"],\n            callbacks=[event_catcher.catch],\n        )\n        assert len(event_catcher.caught_events) == 0\n\n\nclass TestArgumentsPropertyInGenericTestDeprecationTrue:\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"config-version\": 2,\n            \"flags\": {\n                \"require_generic_test_arguments_property\": True,\n            },\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"models_trivial.sql\": models_trivial__model_sql,\n            \"models.yml\": test_with_arguments_yaml,\n        }\n\n    def test_arguments_property_in_generic_test_deprecation(self, project):\n        event_catcher = EventCatcher(ArgumentsPropertyInGenericTestDeprecation)\n        run_dbt(\n            [\"parse\", \"--no-partial-parse\", \"--show-all-deprecations\"],\n            callbacks=[event_catcher.catch],\n        )\n        assert len(event_catcher.caught_events) == 0\n\n\nclass TestMissingArgumentsPropertyInGenericTestDeprecation:\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"config-version\": 2,\n            \"flags\": {\n                \"require_generic_test_arguments_property\": True,\n            },\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"models_trivial.sql\": models_trivial__model_sql,\n            \"models.yml\": test_missing_arguments_property_yaml,\n        }\n\n    def test_missing_arguments_property_in_generic_test_deprecation(self, project):\n        event_catcher = EventCatcher(MissingArgumentsPropertyInGenericTestDeprecation)\n        run_dbt(\n            [\"parse\", \"--no-partial-parse\", \"--show-all-deprecations\"],\n            callbacks=[event_catcher.catch],\n        )\n        assert len(event_catcher.caught_events) == 4\n\n\nclass TestPropertyMovedToConfigDeprecation:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"models_trivial.sql\": models_trivial__model_sql,\n            \"models.yml\": property_moved_to_config_yaml,\n        }\n\n    @mock.patch(\"dbt.jsonschemas.jsonschemas._JSONSCHEMA_SUPPORTED_ADAPTERS\", {\"postgres\"})\n    def test_property_moved_to_config_deprecation(self, project):\n        event_catcher = EventCatcher(PropertyMovedToConfigDeprecation)\n        run_dbt(\n            [\"parse\", \"--no-partial-parse\", \"--show-all-deprecations\"],\n            callbacks=[event_catcher.catch],\n        )\n        assert len(event_catcher.caught_events) == 7\n\n\nclass TestPrePostHookNoFalsePositiveDeprecation:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_hook_configs.sql\": models_pre_post_hook_in_config_sql,\n            \"schema.yml\": pre_post_hook_in_config_yaml,\n        }\n\n    @mock.patch(\"dbt.jsonschemas.jsonschemas._JSONSCHEMA_SUPPORTED_ADAPTERS\", {\"postgres\"})\n    def test_pre_post_hook_no_false_positive_deprecation(self, project):\n        event_catcher = EventCatcher(CustomKeyInConfigDeprecation)\n        run_dbt(\n            [\"parse\", \"--no-partial-parse\", \"--show-all-deprecations\"],\n            callbacks=[event_catcher.catch],\n        )\n        assert len(event_catcher.caught_events) == 0\n\n\nclass TestGenerateSchemaNameNullValueDeprecation:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"models_trivial.sql\": models_trivial__model_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\n            \"macros.sql\": generate_schema_name_null_return_macro_sql,\n        }\n\n    def test_generate_schema_name_null_value_deprecation(self, project):\n        event_catcher = EventCatcher(GenerateSchemaNameNullValueDeprecation)\n        run_dbt(\n            [\"parse\", \"--no-partial-parse\", \"--show-all-deprecations\"],\n            callbacks=[event_catcher.catch],\n        )\n        assert len(event_catcher.caught_events) == 1\n        assert \"Node 'model.test.models_trivial' has a schema set to None as a result of a generate_schema_name call.\" in event_catcher.caught_events[\n            0\n        ].info.msg.replace(\n            \"\\n\", \" \"\n        )\n\n\nclass TestPythonModelConfigAdditionsDontRaiseDeprecations:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"trivial_model.sql\": models_trivial__model_sql,\n            \"python_model.py\": python_model_py,\n            \"python_model.yml\": python_model_yml,\n        }\n\n    @mock.patch(\"dbt.jsonschemas.jsonschemas._JSONSCHEMA_SUPPORTED_ADAPTERS\", {\"postgres\"})\n    def test_python_model_config_additions_dont_raise_deprecations(self, project):\n        event_catcher = EventCatcher(CustomKeyInConfigDeprecation)\n        run_dbt(\n            [\"parse\", \"--no-partial-parse\", \"--show-all-deprecations\"],\n            callbacks=[event_catcher.catch],\n        )\n        assert len(event_catcher.caught_events) == 0\n"
  },
  {
    "path": "tests/functional/deprecations/test_missing_plus_in_config_deprecations.py",
    "content": "from unittest import mock\n\nimport pytest\n\nfrom dbt.events.types import MissingPlusPrefixDeprecation\nfrom dbt.tests.util import run_dbt\nfrom dbt_common.events.event_catcher import EventCatcher\n\n\n@mock.patch(\"dbt.jsonschemas.jsonschemas._JSONSCHEMA_SUPPORTED_ADAPTERS\", {\"postgres\"})\nclass TestEmptyConfig:\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\"models\": None}\n\n    def test_no_warning(self, project):\n        event_catcher = EventCatcher(MissingPlusPrefixDeprecation)\n        run_dbt([\"parse\", \"--no-partial-parse\"], callbacks=[event_catcher.catch])\n        assert len(event_catcher.caught_events) == 0\n\n\n@mock.patch(\"dbt.jsonschemas.jsonschemas._JSONSCHEMA_SUPPORTED_ADAPTERS\", {\"postgres\"})\nclass TestEmptyNestedDir:\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\"models\": {\"nested_dir\": None}}\n\n    def test_no_warning(self, project):\n        event_catcher = EventCatcher(MissingPlusPrefixDeprecation)\n        run_dbt([\"parse\", \"--no-partial-parse\"], callbacks=[event_catcher.catch])\n        assert len(event_catcher.caught_events) == 0\n\n\n@mock.patch(\"dbt.jsonschemas.jsonschemas._JSONSCHEMA_SUPPORTED_ADAPTERS\", {\"postgres\"})\nclass TestValidConfigKey:\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\"models\": {\"docs\": None}}\n\n    def test_raises_warning(self, project):\n        event_catcher = EventCatcher(MissingPlusPrefixDeprecation)\n        run_dbt([\"parse\", \"--no-partial-parse\"], callbacks=[event_catcher.catch])\n        assert len(event_catcher.caught_events) == 1\n        assert \"Missing '+' prefix on `docs`\" in event_catcher.caught_events[0].info.msg\n\n\n@mock.patch(\"dbt.jsonschemas.jsonschemas._JSONSCHEMA_SUPPORTED_ADAPTERS\", {\"postgres\"})\nclass TestValidPlusPrefixConfigKeyWithNonPlusPrefixProperty:\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\"models\": {\"+docs\": {\"show\": True}}}\n\n    def test_no_warning(self, project):\n        event_catcher = EventCatcher(MissingPlusPrefixDeprecation)\n        run_dbt([\"parse\", \"--no-partial-parse\"], callbacks=[event_catcher.catch])\n        assert len(event_catcher.caught_events) == 0\n\n\n@mock.patch(\"dbt.jsonschemas.jsonschemas._JSONSCHEMA_SUPPORTED_ADAPTERS\", {\"postgres\"})\nclass TestValidPlusPrefixConfigKeyWithPlusPrefixInNestedDir:\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"models\": {\n                \"nested_dir_l1\": {\n                    \"nested_dir_l2\": {\"+enabled\": True},\n                },\n            },\n        }\n\n    def test_no_warning(self, project):\n        event_catcher = EventCatcher(MissingPlusPrefixDeprecation)\n        run_dbt([\"parse\", \"--no-partial-parse\"], callbacks=[event_catcher.catch])\n        assert len(event_catcher.caught_events) == 0\n\n\n@mock.patch(\"dbt.jsonschemas.jsonschemas._JSONSCHEMA_SUPPORTED_ADAPTERS\", {\"postgres\"})\nclass TestValidConfigKeyWithNonPlusPrefixInNestedDir:\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"models\": {\n                \"nested_dir_l1\": {\n                    \"nested_dir_l2\": {\"enabled\": True},\n                },\n            },\n        }\n\n    def test_raises_warning(self, project):\n        event_catcher = EventCatcher(MissingPlusPrefixDeprecation)\n        run_dbt([\"parse\", \"--no-partial-parse\"], callbacks=[event_catcher.catch])\n        assert len(event_catcher.caught_events) == 1\n        assert \"Missing '+' prefix on `enabled`\" in event_catcher.caught_events[0].info.msg\n\n\nclass TestMissingPlusPrefixDeprecation:\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\"seeds\": {\"path\": {\"enabled\": True}}}\n\n    @mock.patch(\"dbt.jsonschemas.jsonschemas._JSONSCHEMA_SUPPORTED_ADAPTERS\", {\"postgres\"})\n    def test_missing_plus_prefix_deprecation(self, project):\n        event_catcher = EventCatcher(MissingPlusPrefixDeprecation)\n        run_dbt([\"parse\", \"--no-partial-parse\"], callbacks=[event_catcher.catch])\n        assert len(event_catcher.caught_events) == 1\n        assert \"Missing '+' prefix on `enabled`\" in event_catcher.caught_events[0].info.msg\n\n\nclass TestMissingPlusPrefixDeprecationSubPath:\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\"seeds\": {\"path\": {\"+enabled\": True, \"sub_path\": {\"enabled\": True}}}}\n\n    @mock.patch(\"dbt.jsonschemas.jsonschemas._JSONSCHEMA_SUPPORTED_ADAPTERS\", {\"postgres\"})\n    def test_missing_plus_prefix_deprecation_sub_path(self, project):\n        event_catcher = EventCatcher(MissingPlusPrefixDeprecation)\n        run_dbt([\"parse\", \"--no-partial-parse\"], callbacks=[event_catcher.catch])\n        assert len(event_catcher.caught_events) == 1\n        assert \"Missing '+' prefix on `enabled`\" in event_catcher.caught_events[0].info.msg\n"
  },
  {
    "path": "tests/functional/deprecations/test_model_deprecations.py",
    "content": "import pytest\n\nfrom dbt.cli.main import dbtRunner\nfrom dbt.tests.util import run_dbt\nfrom dbt_common.exceptions import EventCompilationError\n\ndeprecated_model__yml = \"\"\"\nversion: 2\n\nmodels:\n  - name: my_model\n    description: deprecated\n    deprecation_date: 1999-01-01\n\"\"\"\n\ndeprecating_model__yml = \"\"\"\nversion: 2\n\nmodels:\n  - name: my_model\n    description: deprecating in the future\n    deprecation_date: 2999-01-01\n\"\"\"\n\nmodel__sql = \"\"\"\nselect 1 as Id\n\"\"\"\n\ndependant_model__sql = \"\"\"\nselect * from {{ ref(\"my_model\") }}\n\"\"\"\n\n\nclass TestModelDeprecationWarning:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"my_model.sql\": model__sql, \"my_schema.yml\": deprecated_model__yml}\n\n    def test_deprecation_warning(self, project):\n        events = []\n        dbtRunner(callbacks=[events.append]).invoke([\"parse\"])\n        matches = list([e for e in events if e.info.name == \"DeprecatedModel\"])\n        assert len(matches) == 1\n        assert matches[0].data.model_name == \"my_model\"\n\n    def test_deprecation_warning_error(self, project):\n        with pytest.raises(EventCompilationError):\n            run_dbt([\"--warn-error\", \"parse\"])\n\n    def test_deprecation_warning_error_options(self, project):\n        with pytest.raises(EventCompilationError):\n            run_dbt([\"--warn-error-options\", '{\"error\": [\"DeprecatedModel\"]}', \"parse\"])\n\n\nclass TestUpcomingReferenceDeprecationWarning:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": model__sql,\n            \"my_dependant_model.sql\": dependant_model__sql,\n            \"my_schema.yml\": deprecating_model__yml,\n        }\n\n    def test_deprecation_warning(self, project):\n        events = []\n        dbtRunner(callbacks=[events.append]).invoke([\"parse\"])\n        matches = list([e for e in events if e.info.name == \"UpcomingReferenceDeprecation\"])\n        assert len(matches) == 1\n        assert matches[0].data.model_name == \"my_dependant_model\"\n        assert matches[0].data.ref_model_name == \"my_model\"\n\n    def test_deprecation_warning_error(self, project):\n        with pytest.raises(EventCompilationError):\n            run_dbt([\"--warn-error\", \"parse\"])\n\n    def test_deprecation_warning_error_options(self, project):\n        with pytest.raises(EventCompilationError):\n            run_dbt(\n                [\"--warn-error-options\", '{\"error\": [\"UpcomingReferenceDeprecation\"]}', \"parse\"]\n            )\n\n\nclass TestDeprecatedReferenceWarning:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": model__sql,\n            \"my_dependant_model.sql\": dependant_model__sql,\n            \"my_schema.yml\": deprecated_model__yml,\n        }\n\n    def test_deprecation_warning(self, project):\n        events = []\n        dbtRunner(callbacks=[events.append]).invoke([\"parse\"])\n        matches = list([e for e in events if e.info.name == \"DeprecatedReference\"])\n        assert len(matches) == 1\n        assert matches[0].data.model_name == \"my_dependant_model\"\n        assert matches[0].data.ref_model_name == \"my_model\"\n\n    def test_deprecation_warning_error(self, project):\n        with pytest.raises(EventCompilationError):\n            run_dbt([\"--warn-error\", \"parse\"])\n\n    def test_deprecation_warning_error_options(self, project):\n        with pytest.raises(EventCompilationError):\n            run_dbt([\"--warn-error-options\", '{\"error\": [\"DeprecatedReference\"]}', \"parse\"])\n"
  },
  {
    "path": "tests/functional/deps/test_deps_with_vars.py",
    "content": "\"\"\"Test that dbt deps works when vars are used in dbt_project.yml without defaults.\n\nThe key behavior being tested:\n- dbt deps uses lenient mode (require_vars=False) and succeeds even with missing vars\n- dbt run/compile/build/debug use strict mode (require_vars=True) and show the right error messages\n\nExpected behavior from reviewer's scenario:\n1. dbt deps succeeds (doesn't need vars)\n2. dbt run fails with error \"Required var 'X' not found\"\n3. dbt run --vars succeeds when vars provided\n\"\"\"\n\nimport pytest\n\nfrom dbt.tests.util import run_dbt, update_config_file\nfrom dbt_common.exceptions import CompilationError\n\n# Simple model for testing\nmodel_sql = \"\"\"\nselect 1 as id\n\"\"\"\n\n\n# Base class with common fixtures\nclass VarTestingBase:\n    \"\"\"Base class for var testing with common fixtures\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"test_model.sql\": model_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"models\": {\"test_project\": {\"+materialized\": \"{{ var('materialized_var', 'view') }}\"}}\n        }\n\n\n# Test 1: Happy path - deps with defaults\nclass TestDepsSucceedsWithVarDefaults(VarTestingBase):\n    \"\"\"Test that dbt deps succeeds when vars have default values\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        # config: +dataset: \"{{ var('my_dataset', 'default') }}\"\n        return {\"models\": {\"test_project\": {\"+dataset\": \"dqm_{{ var('my_dataset', 'default') }}\"}}}\n\n    def test_deps_succeeds(self, project):\n        # run: dbt deps\n        # assert: succeeds\n        results = run_dbt([\"deps\"])\n        assert results is None or results == []\n\n\n# Test 2: Happy path - run with defaults\nclass TestRunSucceedsWithVarDefaults(VarTestingBase):\n    \"\"\"Test that dbt run succeeds when vars have default values\"\"\"\n\n    def test_run_succeeds(self, project):\n        # run: dbt run\n        # assert: succeeds\n        results = run_dbt([\"run\"])\n        assert len(results) == 1\n\n\n# Test 3: Happy path - run with explicit vars\nclass TestRunSucceedsWithExplicitVars(VarTestingBase):\n    \"\"\"Test that dbt run succeeds when vars provided via --vars\"\"\"\n\n    def test_run_succeeds_with_vars(self, project):\n        # run: dbt run --vars '{\"my_var\": \"table\"}'\n        # assert: succeeds\n        results = run_dbt([\"run\", \"--vars\", '{\"materialized_var\": \"table\"}'])\n        assert len(results) == 1\n\n\n# Test 4: Run fails with the right error message\nclass TestRunFailsWithMissingVar(VarTestingBase):\n    \"\"\"Test dbt run fails with right error\"\"\"\n\n    def test_run_fails_with_error(self, project):\n        # IN TEST: dynamically remove default\n        update_config_file(\n            {\"models\": {\"test_project\": {\"+materialized\": \"{{ var('materialized_var') }}\"}}},\n            project.project_root,\n            \"dbt_project.yml\",\n        )\n\n        # run: dbt run\n        # assert: fails with \"Required var 'X' not found\"\n        try:\n            run_dbt([\"run\"], expect_pass=False)\n            assert False, \"Expected run to fail with missing required var\"\n        except CompilationError as e:\n            error_msg = str(e)\n            # ✅ Verify error message\n            assert \"materialized_var\" in error_msg, \"Error should mention var name\"\n            assert (\n                \"Required var\" in error_msg or \"not found\" in error_msg\n            ), \"Error should say 'Required var' or 'not found'\"\n\n\n# Test 5: compile also fails with the correct error\nclass TestCompileFailsWithMissingVar(VarTestingBase):\n    \"\"\"Test dbt compile fails with error for missing vars\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        # config: start with simple hardcoded value (no var)\n        return {\"models\": {\"test_project\": {\"+materialized\": \"view\"}}}\n\n    def test_compile_fails_with_error(self, project):\n        # IN TEST: dynamically add var without default\n        update_config_file(\n            {\"models\": {\"test_project\": {\"+materialized\": \"{{ var('compile_var_no_default') }}\"}}},\n            project.project_root,\n            \"dbt_project.yml\",\n        )\n\n        # run: dbt compile\n        # assert: fails with \"Required var 'X' not found\"\n        try:\n            run_dbt([\"compile\"], expect_pass=False)\n            assert False, \"Expected compile to fail with missing var\"\n        except CompilationError as e:\n            error_msg = str(e)\n            assert \"compile_var_no_default\" in error_msg\n            assert \"Required var\" in error_msg or \"not found\" in error_msg\n\n\n# Test 6: deps succeeds even when var missing\nclass TestDepsSucceedsEvenWhenVarMissing(VarTestingBase):\n    \"\"\"Test dbt deps succeeds even when var has no default\"\"\"\n\n    def test_deps_still_succeeds(self, project):\n        # run: dbt deps (succeeds)\n        results = run_dbt([\"deps\"])\n        assert results is None or results == []\n\n        # IN TEST: modify config to remove var default\n        update_config_file(\n            {\"models\": {\"test_project\": {\"+materialized\": \"{{ var('materialized_var') }}\"}}},\n            project.project_root,\n            \"dbt_project.yml\",\n        )\n\n        # run: dbt deps again (still succeeds - lenient mode)\n        results = run_dbt([\"deps\"])\n        assert results is None or results == []\n\n        # run: dbt run (fails - strict mode)\n        try:\n            run_dbt([\"run\"], expect_pass=False)\n            assert False, \"Expected run to fail with missing var\"\n        except CompilationError as e:\n            error_msg = str(e)\n            assert \"materialized_var\" in error_msg\n            assert \"Required var\" in error_msg or \"not found\" in error_msg\n\n\n# Test 7: build also fails\nclass TestBuildFailsWithMissingVar(VarTestingBase):\n    \"\"\"Test dbt build fails with error for missing vars\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        # config: start with simple hardcoded value (no var)\n        return {\"models\": {\"test_project\": {\"+materialized\": \"view\"}}}\n\n    def test_build_fails_with_error(self, project):\n        # IN TEST: dynamically add var without default\n        update_config_file(\n            {\"models\": {\"test_project\": {\"+materialized\": \"{{ var('build_var_no_default') }}\"}}},\n            project.project_root,\n            \"dbt_project.yml\",\n        )\n\n        # run: dbt build\n        # assert: fails with \"Required var 'X' not found\"\n        try:\n            run_dbt([\"build\"], expect_pass=False)\n            assert False, \"Expected build to fail with missing var\"\n        except CompilationError as e:\n            error_msg = str(e)\n            assert \"build_var_no_default\" in error_msg\n            assert \"Required var\" in error_msg or \"not found\" in error_msg\n\n\n# Test 8: debug with defaults\nclass TestDebugSucceedsWithVarDefaults(VarTestingBase):\n    \"\"\"Test dbt debug succeeds when vars have defaults (no regression)\"\"\"\n\n    def test_debug_succeeds(self, project):\n        # run: dbt debug\n        # assert: succeeds (no regression)\n        run_dbt([\"debug\"])\n\n\n# Test 9: debug fails like run/compile (strict mode)\nclass TestDebugFailsWithMissingVar(VarTestingBase):\n    \"\"\"Test dbt debug fails with error (strict mode like run/compile)\"\"\"\n\n    def test_debug_fails_with_error(self, project):\n        # First verify debug works with default\n        run_dbt([\"debug\"])\n\n        # IN TEST: dynamically remove default\n        update_config_file(\n            {\"models\": {\"test_project\": {\"+materialized\": \"{{ var('materialized_var') }}\"}}},\n            project.project_root,\n            \"dbt_project.yml\",\n        )\n\n        # run: dbt debug\n        # assert: fails with \"Required var 'X' not found\"\n        try:\n            run_dbt([\"debug\"], expect_pass=False)\n            assert False, \"Expected debug to fail with missing var\"\n        except CompilationError as e:\n            error_msg = str(e)\n            assert \"materialized_var\" in error_msg\n            assert \"Required var\" in error_msg or \"not found\" in error_msg\n"
  },
  {
    "path": "tests/functional/docs/test_doc_blocks_backcompat.py",
    "content": "import json\nimport os\n\nimport pytest\n\nfrom dbt.tests.util import run_dbt\n\nschema_yml = \"\"\"\nmodels:\n  - name: my_colors\n    doc_blocks: 2\n    columns:\n      - name: id\n        doc_blocks: 2\n      - name: color\n        doc_blocks: [\"hello\", 2, \"world\"]\n\"\"\"\n\n\nclass TestDocBlocksBackCompat:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_colors.sql\": \"select 1 as id, 'blue' as color\",\n            \"schema.yml\": schema_yml,\n        }\n\n    def test_doc_blocks_back_compat(self, project):\n        run_dbt([\"parse\"])\n\n        assert os.path.exists(\"./target/manifest.json\")\n\n        with open(\"./target/manifest.json\") as fp:\n            manifest = json.load(fp)\n\n        model_data = manifest[\"nodes\"][\"model.test.my_colors\"]\n        assert model_data[\"doc_blocks\"] == []\n        assert all(column[\"doc_blocks\"] == [] for column in model_data[\"columns\"].values())\n"
  },
  {
    "path": "tests/functional/docs/test_doc_blocks_formatting.py",
    "content": "import json\nimport os\n\nimport pytest\n\nfrom dbt.tests.util import run_dbt\n\ndocs_md = \"\"\"{% docs test_doc %}\nThis is a test for column {test_name}\n{% enddocs %}\n\"\"\"\n\nschema_yml = \"\"\"\nmodels:\n  - name: my_colors\n    columns:\n      - name: id\n        description: \"{{ doc('test_doc').format(test_name = 'id') }}\"\n      - name: color\n        description: \"{{ 'This is a test for column {test_name}'.format(test_name = 'color') }}\"\n\"\"\"\n\n\nclass TestDocBlocksBackCompat:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_colors.sql\": \"select 1 as id, 'blue' as color\",\n            \"schema.yml\": schema_yml,\n            \"docs.md\": docs_md,\n        }\n\n    def test_doc_blocks_back_compat(self, project):\n        run_dbt([\"parse\"])\n\n        assert os.path.exists(\"./target/manifest.json\")\n\n        with open(\"./target/manifest.json\") as fp:\n            manifest = json.load(fp)\n\n        model_data = manifest[\"nodes\"][\"model.test.my_colors\"]\n\n        for column_name, column in model_data[\"columns\"].items():\n            assert column[\"description\"] == f\"This is a test for column {column_name}\"\n            assert column[\"doc_blocks\"] == []\n"
  },
  {
    "path": "tests/functional/docs/test_doc_concat_arg.py",
    "content": "import json\n\nimport pytest\n\nfrom dbt.tests.util import run_dbt\n\ndocs_md = \"\"\"{% docs test_doc %}\nthis is a docs block\n{% enddocs %}\n\"\"\"\n\nschema_yml = \"\"\"\nmodels:\n  - name: my_model\n    description: \"{{ doc('test_' ~ 'doc') }}\"\n    columns:\n      - name: id\n        description: \"{{ doc('test_' ~ 'doc') }}\"\n\"\"\"\n\n\nclass TestDocConcatArg:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": \"select 1 as id\",\n            \"schema.yml\": schema_yml,\n            \"docs.md\": docs_md,\n        }\n\n    def test_concat_arg_succeeds(self, project):\n        run_dbt([\"parse\"])\n\n        with open(\"./target/manifest.json\") as fp:\n            manifest = json.load(fp)\n\n        model_data = manifest[\"nodes\"][\"model.test.my_model\"]\n        assert model_data[\"description\"] == \"this is a docs block\"\n        # Ideally, this would be able to track the doc block in lineage.\n        # However, Const jinja nodes are not handled statically for this resolution.\n        assert model_data[\"doc_blocks\"] == []\n\n        column_data = model_data[\"columns\"][\"id\"]\n        assert column_data[\"description\"] == \"this is a docs block\"\n        # Ideally, this would be able to track the doc block in lineage.\n        # However, Const jinja nodes are not handled statically for this resolution.\n        assert column_data[\"doc_blocks\"] == []\n"
  },
  {
    "path": "tests/functional/docs/test_doc_variable_arg.py",
    "content": "import pytest\n\nfrom dbt.exceptions import DocTargetNotFoundError\nfrom dbt.tests.util import run_dbt\n\nschema_yml = \"\"\"\nmodels:\n  - name: my_model\n    description: \"{{ doc(my_variable) }}\"\n    columns:\n      - name: id\n        description: \"{{ doc(some_var) }}\"\n\"\"\"\n\n\nclass TestDocVariableArg:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": \"select 1 as id\",\n            \"schema.yml\": schema_yml,\n        }\n\n    def test_variable_arg_raises_doc_not_found_not_attribute_error(self, project):\n        with pytest.raises(DocTargetNotFoundError):\n            run_dbt([\"parse\"])\n"
  },
  {
    "path": "tests/functional/docs/test_duplicate_docs_block.py",
    "content": "import pytest\n\nimport dbt_common.exceptions\nfrom dbt.tests.util import run_dbt\n\nduplicate_doc_blocks_model_sql = \"select 1 as id, 'joe' as first_name\"\n\nduplicate_doc_blocks_docs_md = \"\"\"{% docs my_model_doc %}\n    a doc string\n{% enddocs %}\n\n{% docs my_model_doc %}\n    duplicate doc string\n{% enddocs %}\"\"\"\n\nduplicate_doc_blocks_schema_yml = \"\"\"version: 2\n\nmodels:\n  - name: model\n    description: \"{{ doc('my_model_doc') }}\"\n\"\"\"\n\n\nclass TestDuplicateDocsBlock:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model.sql\": duplicate_doc_blocks_model_sql,\n            \"schema.yml\": duplicate_doc_blocks_schema_yml,\n        }\n\n    def test_duplicate_doc_ref(self, project):\n        with pytest.raises(dbt_common.exceptions.CompilationError):\n            run_dbt(expect_pass=False)\n"
  },
  {
    "path": "tests/functional/docs/test_generate.py",
    "content": "from unittest import mock\n\nimport pytest\n\nfrom dbt.plugins.manifest import ModelNodeArgs, PluginNodes\nfrom dbt.tests.util import get_manifest, run_dbt\n\nsample_seed = \"\"\"sample_num,sample_bool\n1,true\n2,false\n3,true\n\"\"\"\n\nsecond_seed = \"\"\"sample_num,sample_bool\n4,true\n5,false\n6,true\n\"\"\"\n\nsample_config = \"\"\"\nsources:\n  - name: my_source_schema\n    schema: \"{{ target.schema }}\"\n    tables:\n      - name: sample_source\n      - name: second_source\n      - name: non_existent_source\n      - name: source_from_seed\n\"\"\"\n\n\nclass TestBaseGenerate:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": \"select 1 as fun\",\n            \"alt_model.sql\": \"select 1 as notfun\",\n            \"sample_config.yml\": sample_config,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\n            \"sample_seed.csv\": sample_seed,\n            \"second_seed.csv\": sample_seed,\n        }\n\n\nclass TestGenerateManifestNotCompiled(TestBaseGenerate):\n    def test_manifest_not_compiled(self, project):\n        run_dbt([\"docs\", \"generate\", \"--no-compile\"])\n        # manifest.json is written out in parsing now, but it\n        # shouldn't be compiled because of the --no-compile flag\n        manifest = get_manifest(project.project_root)\n        model_id = \"model.test.my_model\"\n        assert model_id in manifest.nodes\n        assert manifest.nodes[model_id].compiled is False\n\n\nclass TestGenerateEmptyCatalog(TestBaseGenerate):\n    def test_generate_empty_catalog(self, project):\n        catalog = run_dbt([\"docs\", \"generate\", \"--empty-catalog\"])\n        assert catalog.nodes == {}, \"nodes should be empty\"\n        assert catalog.sources == {}, \"sources should be empty\"\n        assert catalog.errors is None, \"errors should be null\"\n\n\nclass TestGenerateSelectLimitsCatalog(TestBaseGenerate):\n    def test_select_limits_catalog(self, project):\n        run_dbt([\"run\"])\n        catalog = run_dbt([\"docs\", \"generate\", \"--select\", \"my_model\"])\n        assert len(catalog.nodes) == 1\n        assert \"model.test.my_model\" in catalog.nodes\n\n\nclass TestGenerateSelectLimitsNoMatch(TestBaseGenerate):\n    def test_select_limits_no_match(self, project):\n        run_dbt([\"run\"])\n        catalog = run_dbt([\"docs\", \"generate\", \"--select\", \"my_missing_model\"])\n        assert len(catalog.nodes) == 0\n        assert len(catalog.sources) == 0\n\n\nclass TestGenerateCatalogWithSources(TestBaseGenerate):\n    def test_catalog_with_sources(self, project):\n        # populate sources other than non_existent_source\n        project.run_sql(\"create table {}.sample_source (id int)\".format(project.test_schema))\n        project.run_sql(\"create table {}.second_source (id int)\".format(project.test_schema))\n\n        # build nodes\n        run_dbt([\"build\"])\n\n        catalog = run_dbt([\"docs\", \"generate\"])\n\n        # 2 seeds + 2 models\n        assert len(catalog.nodes) == 4\n        # 2 sources (only ones that exist)\n        assert len(catalog.sources) == 2\n\n\nclass TestGenerateCatalogWithExternalNodes(TestBaseGenerate):\n    @mock.patch(\"dbt.plugins.get_plugin_manager\")\n    def test_catalog_with_external_node(self, get_plugin_manager, project):\n        project.run_sql(\"create table {}.external_model (id int)\".format(project.test_schema))\n\n        run_dbt([\"build\"])\n\n        external_nodes = PluginNodes()\n        external_model_node = ModelNodeArgs(\n            name=\"external_model\",\n            package_name=\"external_package\",\n            identifier=\"external_model\",\n            schema=project.test_schema,\n            database=\"dbt\",\n        )\n        external_nodes.add_model(external_model_node)\n        get_plugin_manager.return_value.get_nodes.return_value = external_nodes\n        catalog = run_dbt([\"docs\", \"generate\"])\n\n        assert \"model.external_package.external_model\" in catalog.nodes\n\n\nclass TestGenerateSelectSource(TestBaseGenerate):\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\n            \"sample_seed.csv\": sample_seed,\n            \"second_seed.csv\": sample_seed,\n            \"source_from_seed.csv\": sample_seed,\n        }\n\n    def test_select_source(self, project):\n        run_dbt([\"build\"])\n\n        project.run_sql(\"create table {}.sample_source (id int)\".format(project.test_schema))\n        project.run_sql(\"create table {}.second_source (id int)\".format(project.test_schema))\n\n        # 2 existing sources, 1 selected\n        catalog = run_dbt(\n            [\"docs\", \"generate\", \"--select\", \"source:test.my_source_schema.sample_source\"]\n        )\n        assert len(catalog.sources) == 1\n        assert \"source.test.my_source_schema.sample_source\" in catalog.sources\n        # no nodes selected\n        assert len(catalog.nodes) == 0\n\n        # 2 existing sources sources, 1 selected that has relation as a seed\n        catalog = run_dbt(\n            [\"docs\", \"generate\", \"--select\", \"source:test.my_source_schema.source_from_seed\"]\n        )\n        assert len(catalog.sources) == 1\n        assert \"source.test.my_source_schema.source_from_seed\" in catalog.sources\n        # seed with same relation that was not selected not in catalog\n        assert len(catalog.nodes) == 0\n\n\nclass TestGenerateSelectOverMaxSchemaMetadataRelations(TestBaseGenerate):\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\n            \"sample_seed.csv\": sample_seed,\n            \"second_seed.csv\": sample_seed,\n            \"source_from_seed.csv\": sample_seed,\n        }\n\n    def test_select_source(self, project):\n        run_dbt([\"build\"])\n\n        project.run_sql(\"create table {}.sample_source (id int)\".format(project.test_schema))\n        project.run_sql(\"create table {}.second_source (id int)\".format(project.test_schema))\n\n        with mock.patch.object(type(project.adapter), \"MAX_SCHEMA_METADATA_RELATIONS\", 1):\n            # more relations than MAX_SCHEMA_METADATA_RELATIONS -> all sources and nodes correctly returned\n            catalog = run_dbt([\"docs\", \"generate\"])\n            assert len(catalog.sources) == 3\n            assert len(catalog.nodes) == 5\n\n            # full source selection respected\n            catalog = run_dbt([\"docs\", \"generate\", \"--select\", \"source:*\"])\n            assert len(catalog.sources) == 3\n            assert len(catalog.nodes) == 0\n\n            # full node selection respected\n            catalog = run_dbt([\"docs\", \"generate\", \"--exclude\", \"source:*\"])\n            assert len(catalog.sources) == 0\n            assert len(catalog.nodes) == 5\n\n            # granular source selection respected (> MAX_SCHEMA_METADATA_RELATIONS selected sources)\n            catalog = run_dbt(\n                [\n                    \"docs\",\n                    \"generate\",\n                    \"--select\",\n                    \"source:test.my_source_schema.sample_source\",\n                    \"source:test.my_source_schema.second_source\",\n                ]\n            )\n            assert len(catalog.sources) == 2\n            assert len(catalog.nodes) == 0\n\n            # granular node selection respected (> MAX_SCHEMA_METADATA_RELATIONS selected nodes)\n            catalog = run_dbt([\"docs\", \"generate\", \"--select\", \"my_model\", \"alt_model\"])\n            assert len(catalog.sources) == 0\n            assert len(catalog.nodes) == 2\n\n\nclass TestGenerateSelectSeed(TestBaseGenerate):\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\n            \"sample_seed.csv\": sample_seed,\n            \"second_seed.csv\": sample_seed,\n            \"source_from_seed.csv\": sample_seed,\n        }\n\n    def test_select_seed(self, project):\n        run_dbt([\"build\"])\n\n        # 3 seeds, 1 selected\n        catalog = run_dbt([\"docs\", \"generate\", \"--select\", \"sample_seed\"])\n        assert len(catalog.nodes) == 1\n        assert \"seed.test.sample_seed\" in catalog.nodes\n        # no sources selected\n        assert len(catalog.sources) == 0\n\n        # 3 seeds, 1 selected that has same relation as a source\n        catalog = run_dbt([\"docs\", \"generate\", \"--select\", \"source_from_seed\"])\n        assert len(catalog.nodes) == 1\n        assert \"seed.test.source_from_seed\" in catalog.nodes\n        # source with same relation that was not selected not in catalog\n        assert len(catalog.sources) == 0\n"
  },
  {
    "path": "tests/functional/docs/test_good_docs_blocks.py",
    "content": "import json\nimport os\nfrom pathlib import Path\n\nimport pytest\n\nfrom dbt.tests.util import run_dbt, update_config_file, write_file\n\ngood_docs_blocks_model_sql = \"select 1 as id, 'joe' as first_name\"\n\ngood_docs_blocks_docs_md = \"\"\"{% docs my_model_doc %}\nMy model is just a copy of the seed\n{% enddocs %}\n\n{% docs my_model_doc__id %}\nThe user ID number\n{% enddocs %}\n\nThe following doc is never used, which should be fine.\n{% docs my_model_doc__first_name %}\nThe user's first name (should not be shown!)\n{% enddocs %}\n\nThis doc is referenced by its full name\n{% docs my_model_doc__last_name %}\nThe user's last name\n{% enddocs %}\n\"\"\"\n\ngood_doc_blocks_alt_docs_md = \"\"\"{% docs my_model_doc %}\nAlt text about the model\n{% enddocs %}\n\n{% docs my_model_doc__id %}\nThe user ID number with alternative text\n{% enddocs %}\n\nThe following doc is never used, which should be fine.\n{% docs my_model_doc__first_name %}\nThe user's first name - don't show this text!\n{% enddocs %}\n\nThis doc is referenced by its full name\n{% docs my_model_doc__last_name %}\nThe user's last name in this other file\n{% enddocs %}\n\"\"\"\n\ngood_docs_blocks_schema_yml = \"\"\"version: 2\n\nmodels:\n  - name: model\n    description: \"{{ doc('my_model_doc') }}\"\n    columns:\n      - name: id\n        description: \"{{ doc('my_model_doc__id') }}\"\n      - name: first_name\n        description: The user's first name\n      - name: last_name\n        description: \"{{ doc('test', 'my_model_doc__last_name') }}\"\n      - name: tricky\n        description: \"{{ doc('my_model_doc__id') }} The user's first name {{ doc('test', 'my_model_doc__last_name') }}\"\n\"\"\"\n\n\nclass TestGoodDocsBlocks:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model.sql\": good_docs_blocks_model_sql,\n            \"schema.yml\": good_docs_blocks_schema_yml,\n            \"docs.md\": good_docs_blocks_docs_md,\n        }\n\n    def test_valid_doc_ref(self, project):\n        result = run_dbt()\n        assert len(result.results) == 1\n\n        assert os.path.exists(\"./target/manifest.json\")\n\n        with open(\"./target/manifest.json\") as fp:\n            manifest = json.load(fp)\n\n        model_data = manifest[\"nodes\"][\"model.test.model\"]\n\n        assert model_data[\"description\"] == \"My model is just a copy of the seed\"\n        assert model_data[\"doc_blocks\"] == [\"doc.test.my_model_doc\"]\n\n        assert {\n            \"name\": \"id\",\n            \"description\": \"The user ID number\",\n            \"dimension\": None,\n            \"entity\": None,\n            \"data_type\": None,\n            \"constraints\": [],\n            \"meta\": {},\n            \"quote\": None,\n            \"tags\": [],\n            \"granularity\": None,\n            \"doc_blocks\": [\"doc.test.my_model_doc__id\"],\n            \"config\": {\"meta\": {}, \"tags\": []},\n        } == model_data[\"columns\"][\"id\"]\n\n        assert {\n            \"name\": \"first_name\",\n            \"description\": \"The user's first name\",\n            \"dimension\": None,\n            \"entity\": None,\n            \"data_type\": None,\n            \"constraints\": [],\n            \"meta\": {},\n            \"quote\": None,\n            \"tags\": [],\n            \"granularity\": None,\n            \"doc_blocks\": [],\n            \"config\": {\"meta\": {}, \"tags\": []},\n        } == model_data[\"columns\"][\"first_name\"]\n\n        assert {\n            \"name\": \"last_name\",\n            \"description\": \"The user's last name\",\n            \"dimension\": None,\n            \"entity\": None,\n            \"data_type\": None,\n            \"constraints\": [],\n            \"meta\": {},\n            \"quote\": None,\n            \"tags\": [],\n            \"granularity\": None,\n            \"doc_blocks\": [\"doc.test.my_model_doc__last_name\"],\n            \"config\": {\"meta\": {}, \"tags\": []},\n        } == model_data[\"columns\"][\"last_name\"]\n\n        assert {\n            \"name\": \"tricky\",\n            \"description\": \"The user ID number The user's first name The user's last name\",\n            \"dimension\": None,\n            \"entity\": None,\n            \"data_type\": None,\n            \"constraints\": [],\n            \"meta\": {},\n            \"quote\": None,\n            \"tags\": [],\n            \"granularity\": None,\n            \"doc_blocks\": [\n                \"doc.test.my_model_doc__id\",\n                \"doc.test.my_model_doc__last_name\",\n            ],\n            \"config\": {\"meta\": {}, \"tags\": []},\n        } == model_data[\"columns\"][\"tricky\"]\n\n        assert len(model_data[\"columns\"]) == 4\n\n\nclass TestGoodDocsBlocksAltPath:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model.sql\": good_docs_blocks_model_sql, \"schema.yml\": good_docs_blocks_schema_yml}\n\n    def test_alternative_docs_path(self, project):\n        # self.use_default_project({\"docs-paths\": [self.dir(\"docs\")]})\n        docs_path = Path(project.project_root, \"alt-docs\")\n        docs_path.mkdir()\n        write_file(good_doc_blocks_alt_docs_md, project.project_root, \"alt-docs\", \"docs.md\")\n\n        update_config_file(\n            {\"docs-paths\": [str(docs_path)]}, project.project_root, \"dbt_project.yml\"\n        )\n\n        result = run_dbt()\n\n        assert len(result.results) == 1\n\n        assert os.path.exists(\"./target/manifest.json\")\n\n        with open(\"./target/manifest.json\") as fp:\n            manifest = json.load(fp)\n\n        model_data = manifest[\"nodes\"][\"model.test.model\"]\n\n        assert model_data[\"description\"] == \"Alt text about the model\"\n        assert model_data[\"doc_blocks\"] == [\"doc.test.my_model_doc\"]\n\n        assert {\n            \"name\": \"id\",\n            \"description\": \"The user ID number with alternative text\",\n            \"dimension\": None,\n            \"entity\": None,\n            \"data_type\": None,\n            \"constraints\": [],\n            \"meta\": {},\n            \"quote\": None,\n            \"tags\": [],\n            \"granularity\": None,\n            \"doc_blocks\": [\"doc.test.my_model_doc__id\"],\n            \"config\": {\"meta\": {}, \"tags\": []},\n        } == model_data[\"columns\"][\"id\"]\n\n        assert {\n            \"name\": \"first_name\",\n            \"description\": \"The user's first name\",\n            \"dimension\": None,\n            \"entity\": None,\n            \"data_type\": None,\n            \"constraints\": [],\n            \"meta\": {},\n            \"quote\": None,\n            \"tags\": [],\n            \"granularity\": None,\n            \"doc_blocks\": [],\n            \"config\": {\"meta\": {}, \"tags\": []},\n        } == model_data[\"columns\"][\"first_name\"]\n\n        assert {\n            \"name\": \"last_name\",\n            \"description\": \"The user's last name in this other file\",\n            \"dimension\": None,\n            \"entity\": None,\n            \"data_type\": None,\n            \"constraints\": [],\n            \"meta\": {},\n            \"quote\": None,\n            \"tags\": [],\n            \"granularity\": None,\n            \"doc_blocks\": [\"doc.test.my_model_doc__last_name\"],\n            \"config\": {\"meta\": {}, \"tags\": []},\n        } == model_data[\"columns\"][\"last_name\"]\n\n        assert {\n            \"name\": \"tricky\",\n            \"description\": \"The user ID number with alternative text The user's first name The user's last name in this other file\",\n            \"dimension\": None,\n            \"entity\": None,\n            \"data_type\": None,\n            \"constraints\": [],\n            \"meta\": {},\n            \"quote\": None,\n            \"tags\": [],\n            \"granularity\": None,\n            \"doc_blocks\": [\n                \"doc.test.my_model_doc__id\",\n                \"doc.test.my_model_doc__last_name\",\n            ],\n            \"config\": {\"meta\": {}, \"tags\": []},\n        } == model_data[\"columns\"][\"tricky\"]\n\n        assert len(model_data[\"columns\"]) == 4\n"
  },
  {
    "path": "tests/functional/docs/test_invalid_doc_ref.py",
    "content": "import pytest\n\nimport dbt_common.exceptions\nfrom dbt.tests.util import run_dbt\n\ninvalid_doc_ref_model_sql = \"select 1 as id, 'joe' as first_name\"\n\ninvalid_doc_ref_docs_md = \"\"\"{% docs my_model_doc %}\nMy model is just a copy of the seed\n{% enddocs %}\n\n{% docs my_model_doc__id %}\nThe user ID number\n{% enddocs %}\n\nThe following doc is never used, which should be fine.\n{% docs my_model_doc__first_name %}\nThe user's first name\n{% enddocs %}\"\"\"\n\ninvalid_doc_ref_schema_yml = \"\"\"version: 2\n\nmodels:\n  - name: model\n    description: \"{{ doc('my_model_doc') }}\"\n    columns:\n      - name: id\n        description: \"{{ doc('my_model_doc__id') }}\"\n      - name: first_name\n        description: \"{{ doc('foo.bar.my_model_doc__id') }}\"\n\"\"\"\n\n\nclass TestInvalidDocRef:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model.sql\": invalid_doc_ref_model_sql,\n            \"docs.md\": invalid_doc_ref_docs_md,\n            \"schema.yml\": invalid_doc_ref_schema_yml,\n        }\n\n    def test_invalid_doc_ref(self, project):\n        # The run should fail since we could not find the docs reference.\n        with pytest.raises(dbt_common.exceptions.CompilationError):\n            run_dbt(expect_pass=False)\n"
  },
  {
    "path": "tests/functional/docs/test_missing_docs_blocks.py",
    "content": "import pytest\n\nimport dbt_common.exceptions\nfrom dbt.tests.util import run_dbt\n\nmissing_docs_blocks_model_sql = \"select 1 as id, 'joe' as first_name\"\n\nmissing_docs_blocks_docs_md = \"\"\"{% docs my_model_doc %}\nMy model is just a copy of the seed\n{% enddocs %}\n\n{% docs my_model_doc__id %}\nThe user ID number\n{% enddocs %}\"\"\"\n\nmissing_docs_blocks_schema_yml = \"\"\"version: 2\n\nmodels:\n  - name: model\n    description: \"{{ doc('my_model_doc') }}\"\n    columns:\n      - name: id\n        description: \"{{ doc('my_model_doc__id') }}\"\n      - name: first_name\n      # invalid reference\n        description: \"{{ doc('my_model_doc__first_name') }}\"\n\"\"\"\n\n\nclass TestMissingDocsBlocks:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model.sql\": missing_docs_blocks_model_sql,\n            \"schema.yml\": missing_docs_blocks_schema_yml,\n            \"docs.md\": missing_docs_blocks_docs_md,\n        }\n\n    def test_missing_doc_ref(self, project):\n        # The run should fail since we could not find the docs reference.\n        with pytest.raises(dbt_common.exceptions.CompilationError):\n            run_dbt()\n"
  },
  {
    "path": "tests/functional/docs/test_model_version_docs_blocks.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt\n\nmodel_1 = \"\"\"\nselect 1 as id, 'joe' as first_name\n\"\"\"\n\nmodel_versioned = \"\"\"\nselect 1 as id, 'joe' as first_name\n\"\"\"\n\ndocs_md = \"\"\"\n{% docs model_description %}\nunversioned model\n{% enddocs %}\n\n{% docs column_id_doc %}\ncolumn id for some thing\n{% enddocs %}\n\n{% docs versioned_model_description %}\nversioned model\n{% enddocs %}\n\n\"\"\"\n\nschema_yml = \"\"\"\nmodels:\n  - name: model_1\n    description: '{{ doc(\"model_description\") }}'\n    columns:\n        - name: id\n          description: '{{ doc(\"column_id_doc\") }}'\n\n  - name: model_versioned\n    description: '{{ doc(\"versioned_model_description\") }}'\n    latest_version: 1\n    versions:\n      - v: 1\n        config:\n          alias: my_alias\n        columns:\n          - name: id\n            description: '{{ doc(\"column_id_doc\") }}'\n          - name: first_name\n            description: 'plain text'\n      - v: 2\n        columns:\n          - name: other_id\n\"\"\"\n\n\nclass TestVersionedModelDocsBlock:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_1.sql\": model_1,\n            \"model_versioned.sql\": model_versioned,\n            \"schema.yml\": schema_yml,\n            \"docs.md\": docs_md,\n        }\n\n    def test_versioned_doc_ref(self, project):\n        manifest = run_dbt([\"parse\"])\n        model_1 = manifest.nodes[\"model.test.model_1\"]\n        model_v1 = manifest.nodes[\"model.test.model_versioned.v1\"]\n\n        assert model_1.description == \"unversioned model\"\n        assert model_v1.description == \"versioned model\"\n\n        assert model_1.columns[\"id\"].description == \"column id for some thing\"\n        assert model_v1.columns[\"id\"].description == \"column id for some thing\"\n        assert model_v1.columns[\"first_name\"].description == \"plain text\"\n"
  },
  {
    "path": "tests/functional/docs/test_static.py",
    "content": "import os\n\nimport pytest\n\nfrom dbt.task.docs import DOCS_INDEX_FILE_PATH\nfrom dbt.tests.util import run_dbt\nfrom dbt_common.clients.system import load_file_contents\n\n\nclass TestStaticGenerate:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"my_model.sql\": \"select 1 as fun\"}\n\n    def test_static_generated(self, project):\n        run_dbt([\"docs\", \"generate\", \"--static\"])\n\n        source_index_html = load_file_contents(DOCS_INDEX_FILE_PATH)\n\n        target_index_html = load_file_contents(\n            os.path.join(project.project_root, \"target\", \"index.html\")\n        )\n\n        # Validate index.html was copied correctly\n        assert len(target_index_html) == len(source_index_html)\n        assert hash(target_index_html) == hash(source_index_html)\n\n        manifest_data = load_file_contents(\n            os.path.join(project.project_root, \"target\", \"manifest.json\")\n        )\n\n        catalog_data = load_file_contents(\n            os.path.join(project.project_root, \"target\", \"catalog.json\")\n        )\n\n        static_index_html = load_file_contents(\n            os.path.join(project.project_root, \"target\", \"static_index.html\")\n        )\n\n        # Calculate expected static_index.html\n        expected_static_index_html = source_index_html\n        expected_static_index_html = expected_static_index_html.replace(\n            '\"MANIFEST.JSON INLINE DATA\"', manifest_data\n        )\n        expected_static_index_html = expected_static_index_html.replace(\n            '\"CATALOG.JSON INLINE DATA\"', catalog_data\n        )\n\n        # Validate static_index.html was generated correctly\n        assert len(expected_static_index_html) == len(static_index_html)\n        assert hash(expected_static_index_html) == hash(static_index_html)\n"
  },
  {
    "path": "tests/functional/duplicates/test_duplicate_analysis.py",
    "content": "import pytest\n\nfrom dbt.exceptions import CompilationError\nfrom dbt.tests.util import run_dbt\n\nmy_model_sql = \"\"\"\nselect 1 as id\n\"\"\"\n\nmy_analysis_sql = \"\"\"\nselect * from {{ ref('my_model') }}\n\"\"\"\n\n\nclass TestDuplicateAnalysis:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"my_model.sql\": my_model_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def analyses(self):\n        return {\n            \"anlysis-1\": {\"model.sql\": my_analysis_sql},\n            \"anlysis-2\": {\"model.sql\": my_analysis_sql},\n        }\n\n    def test_duplicate_model_enabled(self, project):\n        message = \"dbt found two analyses with the name\"\n        with pytest.raises(CompilationError) as exc:\n            run_dbt([\"compile\"])\n        exc_str = \" \".join(str(exc.value).split())  # flatten all whitespace\n        assert message in exc_str\n"
  },
  {
    "path": "tests/functional/duplicates/test_duplicate_exposure.py",
    "content": "import pytest\n\nfrom dbt.exceptions import CompilationError\nfrom dbt.tests.util import run_dbt\n\nexposure_dupes_schema_yml = \"\"\"\nversion: 2\nexposures:\n  - name: something\n    type: dashboard\n    owner:\n      email: test@example.com\n  - name: something\n    type: dashboard\n    owner:\n      email: test@example.com\n\n\"\"\"\n\n\nclass TestDuplicateExposure:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"schema.yml\": exposure_dupes_schema_yml}\n\n    def test_duplicate_exposure(self, project):\n        message = \"dbt found two exposures with the name\"\n        with pytest.raises(CompilationError) as exc:\n            run_dbt([\"compile\"])\n        assert message in str(exc.value)\n"
  },
  {
    "path": "tests/functional/duplicates/test_duplicate_macro.py",
    "content": "import pytest\n\nfrom dbt.exceptions import CompilationError\nfrom dbt.tests.util import run_dbt\n\nbad_same_macros_sql = \"\"\"\n{% macro some_macro() %}\n{% endmacro %}\n\n{% macro some_macro() %}\n{% endmacro %}\n\n\"\"\"\n\nbad_separate_one_sql = \"\"\"\n{% macro some_macro() %}\n{% endmacro %}\n\n\"\"\"\n\nbad_separate_two_sql = \"\"\"\n{% macro some_macro() %}\n{% endmacro %}\n\n\"\"\"\n\nmodel_sql = \"\"\"\nselect 1 as value\n\"\"\"\n\n\nclass TestDuplicateMacroEnabledSameFile:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model.sql\": model_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\n            \"macro.sql\": bad_same_macros_sql,\n        }\n\n    def test_duplicate_macros(self, project):\n        message = 'dbt found multiple macros named \"some_macro\" in the project'\n        with pytest.raises(CompilationError) as exc:\n            run_dbt([\"parse\"])\n        exc_str = \" \".join(str(exc.value).split())  # flatten all whitespace\n        assert message in exc_str\n        assert \"macro.sql\" in exc_str\n\n\nclass TestDuplicateMacroEnabledDifferentFiles:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model.sql\": model_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\n            \"one.sql\": bad_separate_one_sql,\n            \"two.sql\": bad_separate_two_sql,\n        }\n\n    def test_duplicate_macros(self, project):\n        message = 'dbt found multiple macros named \"some_macro\" in the project'\n        with pytest.raises(CompilationError) as exc:\n            run_dbt([\"compile\"])\n        exc_str = \" \".join(str(exc.value).split())  # flatten all whitespace\n        assert message in exc_str\n        assert \"one.sql\" in exc_str\n        assert \"two.sql\" in exc_str\n"
  },
  {
    "path": "tests/functional/duplicates/test_duplicate_metric.py",
    "content": "import pytest\n\nfrom dbt.exceptions import CompilationError\nfrom dbt.tests.util import run_dbt\n\nmetric_dupes_schema_yml = \"\"\"\nversion: 2\n\nmetrics:\n\n  - name: number_of_people\n    label: \"Number of people\"\n    description: Total count of people\n    type: simple\n    type_params:\n      measure: \"people\"\n    meta:\n        my_meta: 'testing'\n\n  - name: number_of_people\n    label: \"Collective tenure\"\n    description: Total number of years of team experience\n    type: simple\n    type_params:\n      measure:\n        name: \"years_tenure\"\n        filter: \"{{ Dimension('people_entity__loves_dbt') }} is true\"\n\"\"\"\n\n\nclass TestDuplicateMetric:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"schema.yml\": metric_dupes_schema_yml}\n\n    def test_duplicate_metric(self, project):\n        message = \"dbt found two metrics with the name\"\n        with pytest.raises(CompilationError) as exc:\n            run_dbt([\"compile\"])\n        assert message in str(exc.value)\n"
  },
  {
    "path": "tests/functional/duplicates/test_duplicate_model.py",
    "content": "import pytest\n\nfrom dbt.exceptions import AmbiguousAliasError, CompilationError\nfrom dbt.tests.fixtures.project import write_project_files\nfrom dbt.tests.util import get_manifest, run_dbt\n\ndisabled_model_sql = \"\"\"\n{{\n    config(\n        enabled=False,\n        materialized=\"table\",\n    )\n}}\n\nselect 1\n\n\"\"\"\n\nenabled_model_sql = \"\"\"\n{{\n    config(\n        enabled=True,\n        materialized=\"table\",\n    )\n}}\n\nselect 1 as value\n\n\"\"\"\n\ndbt_project_yml = \"\"\"\nname: 'local_dep'\nversion: '1.0'\nconfig-version: 2\n\nprofile: 'default'\n\nmodel-paths: [\"models\"]\n\nseeds:\n  quote_columns: False\n\n\"\"\"\n\nlocal_dep_schema_yml = \"\"\"\nmodels:\n  - name: table_model\n    config:\n      alias: table_model_local_dep\n    columns:\n      - name: id\n        data_tests:\n          - unique\n\"\"\"\n\nlocal_dep_versions_schema_yml = \"\"\"\nmodels:\n  - name: table_model\n    config:\n      alias: table_model_local_dep\n    versions:\n      - v: 1\n\"\"\"\n\n\nclass TestDuplicateModelEnabled:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model-enabled-1\": {\"model.sql\": enabled_model_sql},\n            \"model-enabled-2\": {\"model.sql\": enabled_model_sql},\n        }\n\n    def test_duplicate_model_enabled(self, project):\n        message = \"dbt found two models with the name\"\n        with pytest.raises(CompilationError) as exc:\n            run_dbt([\"compile\"])\n        exc_str = \" \".join(str(exc.value).split())  # flatten all whitespace\n        assert message in exc_str\n\n\nclass TestDuplicateModelDisabled:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model-disabled\": {\"model.sql\": disabled_model_sql},\n            \"model-enabled\": {\"model.sql\": enabled_model_sql},\n        }\n\n    def test_duplicate_model_disabled(self, project):\n        results = run_dbt([\"compile\"])\n        assert len(results) == 1\n\n        manifest = get_manifest(project.project_root)\n\n        model_id = \"model.test.model\"\n        assert model_id in manifest.nodes\n        assert model_id in manifest.disabled\n\n    def test_duplicate_model_disabled_partial_parsing(self, project):\n        run_dbt([\"clean\"])\n        results = run_dbt([\"--partial-parse\", \"compile\"])\n        assert len(results) == 1\n        results = run_dbt([\"--partial-parse\", \"compile\"])\n        assert len(results) == 1\n        results = run_dbt([\"--partial-parse\", \"compile\"])\n        assert len(results) == 1\n\n\nclass TestDuplicateModelAliasEnabledAcrossPackages:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"table_model.sql\": enabled_model_sql}\n\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project_root):\n        local_dependency_files = {\n            \"dbt_project.yml\": dbt_project_yml,\n            \"models\": {\"table_model.sql\": enabled_model_sql},\n        }\n        write_project_files(project_root, \"local_dependency\", local_dependency_files)\n\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\"packages\": [{\"local\": \"local_dependency\"}]}\n\n    def test_duplicate_model_alias_enabled_across_packages(self, project):\n        run_dbt([\"deps\"])\n        message = \"dbt found two resources with the database representation\"\n        with pytest.raises(AmbiguousAliasError) as exc:\n            run_dbt([\"run\"])\n        assert message in str(exc.value)\n\n\nclass TestDuplicateModelDisabledAcrossPackages:\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project_root):\n        local_dependency_files = {\n            \"dbt_project.yml\": dbt_project_yml,\n            \"models\": {\"table_model.sql\": enabled_model_sql},\n        }\n        write_project_files(project_root, \"local_dependency\", local_dependency_files)\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"table_model.sql\": disabled_model_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\"packages\": [{\"local\": \"local_dependency\"}]}\n\n    def test_duplicate_model_disabled_across_packages(self, project):\n        run_dbt([\"deps\"])\n        results = run_dbt([\"compile\"])\n        assert len(results) == 1\n\n        manifest = get_manifest(project.project_root)\n        local_dep_model_id = \"model.local_dep.table_model\"\n        model_id = \"model.test.table_model\"\n        assert local_dep_model_id in manifest.nodes\n        assert model_id in manifest.disabled\n\n\nclass TestDuplicateModelNameWithTestAcrossPackages:\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project_root):\n        local_dependency_files = {\n            \"dbt_project.yml\": dbt_project_yml,\n            \"models\": {\"table_model.sql\": enabled_model_sql, \"schema.yml\": local_dep_schema_yml},\n        }\n        write_project_files(project_root, \"local_dependency\", local_dependency_files)\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"table_model.sql\": enabled_model_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\"packages\": [{\"local\": \"local_dependency\"}]}\n\n    def test_duplicate_model_name_with_test_across_packages(self, project):\n        run_dbt([\"deps\"])\n        manifest = run_dbt([\"parse\"])\n        assert len(manifest.nodes) == 3\n\n        # model nodes with duplicate names exist\n        local_dep_model_node_id = \"model.local_dep.table_model\"\n        root_model_node_id = \"model.test.table_model\"\n        assert local_dep_model_node_id in manifest.nodes\n        assert root_model_node_id in manifest.nodes\n\n        # test node exists and is attached to correct node\n        test_node_id = \"test.local_dep.unique_table_model_id.1da9e464d9\"\n        assert test_node_id in manifest.nodes\n        assert manifest.nodes[test_node_id].attached_node == local_dep_model_node_id\n\n\nclass TestDuplicateModelNameWithVersionAcrossPackages:\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project_root):\n        local_dependency_files = {\n            \"dbt_project.yml\": dbt_project_yml,\n            \"models\": {\n                \"table_model.sql\": enabled_model_sql,\n                \"schema.yml\": local_dep_versions_schema_yml,\n            },\n        }\n        write_project_files(project_root, \"local_dependency\", local_dependency_files)\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"table_model.sql\": enabled_model_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\"packages\": [{\"local\": \"local_dependency\"}]}\n\n    def test_duplicate_model_name_with_test_across_packages(self, project):\n        run_dbt([\"deps\"])\n        manifest = run_dbt([\"parse\"])\n        assert len(manifest.nodes) == 2\n\n        # model nodes with duplicate names exist\n        local_dep_model_node_id = \"model.local_dep.table_model.v1\"\n        root_model_node_id = \"model.test.table_model\"\n        assert local_dep_model_node_id in manifest.nodes\n        assert root_model_node_id in manifest.nodes\n\n\nclass TestModelTestOverlap:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"table_model.sql\": enabled_model_sql}\n\n    @property\n    def project_config(self):\n        return {\n            \"config-version\": 2,\n            \"test-paths\": [\"models\"],\n        }\n\n    def test_duplicate_test_model_paths(self, project):\n        # this should be ok: test/model overlap is fine\n        run_dbt([\"compile\"])\n        run_dbt([\"--partial-parse\", \"compile\"])\n        run_dbt([\"--partial-parse\", \"compile\"])\n\n\nclass TestMultipleDisabledModels:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"subdir3\": {\"model_alt.sql\": disabled_model_sql},\n            \"subdir2\": {\"model_alt.sql\": disabled_model_sql},\n            \"subdir1\": {\"model_alt.sql\": enabled_model_sql},\n        }\n\n    def test_multiple_disabled_models(self, project):\n        run_dbt([\"compile\"])\n        manifest = get_manifest(project.project_root)\n        model_id = \"model.test.model_alt\"\n        assert model_id in manifest.nodes\n"
  },
  {
    "path": "tests/functional/duplicates/test_duplicate_resource.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt\n\nmodels_naming_dupes_schema_yml = \"\"\"\nversion: 2\nmodels:\n  - name: something\n    description: This table has basic information about orders, as well as some derived facts based on payments\nexposure:\n  - name: something\n\n\"\"\"\n\nsomething_model_sql = \"\"\"\n\nselect 1 as item\n\n\"\"\"\n\n\nclass TestDuplicateSchemaResource:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": models_naming_dupes_schema_yml,\n            \"something.sql\": something_model_sql,\n        }\n\n    # a model and an exposure can share the same name\n    def test_duplicate_model_and_exposure(self, project):\n        result = run_dbt([\"compile\"])\n        assert len(result) == 1\n"
  },
  {
    "path": "tests/functional/duplicates/test_duplicate_resource_names.py",
    "content": "from collections import defaultdict\n\nimport pytest\n\nimport dbt.deprecations as deprecations\nfrom dbt.exceptions import DuplicateResourceNameError\nfrom dbt.tests.fixtures.project import write_project_files\nfrom dbt.tests.util import run_dbt\n\n# Test resources with duplicate names but different database aliases\nmodel_sql = \"\"\"\nselect 1 as id, 'test' as name\n\"\"\"\n\nseed_csv = \"\"\"\nid,value\n1,test\n2,another\n\"\"\"\n\n\nmacros_sql = \"\"\"\n{% macro generate_alias_name(custom_alias_name, node) -%}\n    {{ node.name }}_{{ node.resource_type }}\n{%- endmacro %}\n\"\"\"\n\nversioned_model_yml = \"\"\"\nmodels:\n  - name: same_name\n    versions:\n      - v: 1\n\"\"\"\n\nlocal_dependency__dbt_project_yml = \"\"\"\n\nname: 'local_dep'\nversion: '1.0'\n\"\"\"\n\n\n@pytest.fixture(scope=\"class\")\ndef set_up_deprecations():\n    deprecations.reset_deprecations()\n    assert deprecations.active_deprecations == defaultdict(int)\n\n\nclass BaseTestDuplicateNames:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"same_name.sql\": model_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\n            \"same_name.csv\": seed_csv,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\n            \"generate_alias_name.sql\": macros_sql,\n        }\n\n\nclass TestDuplicateNamesRequireUniqueResourceNamesTrue(BaseTestDuplicateNames):\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"flags\": {\n                \"require_unique_project_resource_names\": True,\n            }\n        }\n\n    def test_duplicate_names_with_flag_enabled(self, project):\n        \"\"\"When require_unique_project_resource_names is True, duplicate unversioned names should raise DuplicateResourceNameError\"\"\"\n        with pytest.raises(DuplicateResourceNameError):\n            run_dbt([\"parse\"])\n\n\nclass TestDuplicateNamesRequireUniqueResourceNamesTrueDifferentPackages(BaseTestDuplicateNames):\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"flags\": {\n                \"require_unique_project_resource_names\": True,\n            }\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        # Seed in local dep instead\n        return {}\n\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\"packages\": [{\"local\": \"local_dependency\"}]}\n\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project_root):\n        local_dependency_files = {\n            \"dbt_project.yml\": local_dependency__dbt_project_yml,\n            \"seeds\": {\"same_name.csv\": seed_csv},\n        }\n        write_project_files(project_root, \"local_dependency\", local_dependency_files)\n\n    def test_duplicate_names_with_flag_enabled_different_packages(self, project):\n        run_dbt([\"deps\"])\n        # Behavior flag is true, however, the seed is in a different package.\n        # No error is raised when encountering duplicate names between different packages.\n        manifest = run_dbt([\"parse\"])\n\n        assert len(manifest.nodes) == 2\n        assert \"model.test.same_name\" in manifest.nodes\n        assert \"seed.local_dep.same_name\" in manifest.nodes\n\n\nclass TestDuplicateNamesRequireUniqueResourceNamesFalse(BaseTestDuplicateNames):\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"flags\": {\n                \"require_unique_project_resource_names\": False,\n            }\n        }\n\n    def test_duplicate_names_with_flag_disabled(self, project, set_up_deprecations):\n        \"\"\"When require_unique_project_resource_names is False, duplicate unversioned names should be allowed (continue behavior)\"\"\"\n        manifest = run_dbt([\"parse\"])\n\n        assert (\n            manifest.nodes[\"model.test.same_name\"].name\n            == manifest.nodes[\"seed.test.same_name\"].name\n        )\n\n        assert \"duplicate-name-distinct-node-types-deprecation\" in deprecations.active_deprecations\n\n\nclass TestDuplicateNamesDefaultBehavior(TestDuplicateNamesRequireUniqueResourceNamesFalse):\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {}\n\n\nclass TestDuplicateNamesDifferentResourceTypesVersionedUnversioned(BaseTestDuplicateNames):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"same_name.sql\": model_sql,\n            \"schema.yml\": versioned_model_yml,\n        }\n\n    def test_duplicate_names_versioned_unversioned(self, project):\n        # DuplicateVersionedUnversionedError is not raised because parsing fails upstream.\n        # However, parsing still fails with an AssertionError because versioning is attempted on a non-model node.\n        with pytest.raises(AssertionError):\n            run_dbt([\"parse\"])\n"
  },
  {
    "path": "tests/functional/duplicates/test_duplicate_source.py",
    "content": "import pytest\n\nfrom dbt.exceptions import CompilationError\nfrom dbt.tests.util import run_dbt\n\nsource_dupes_schema_yml = \"\"\"\nversion: 2\nsources:\n  - name: something\n    tables:\n     - name: dupe\n     - name: dupe\n\n\"\"\"\n\n\nclass TestDuplicateSourceEnabled:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"schema.yml\": source_dupes_schema_yml}\n\n    def test_duplicate_source_enabled(self, project):\n        message = \"dbt found two sources with the name\"\n        with pytest.raises(CompilationError) as exc:\n            run_dbt([\"compile\"])\n        assert message in str(exc.value)\n"
  },
  {
    "path": "tests/functional/events/events.py",
    "content": "import os\n\nfrom dbt.cli.main import dbtRunner\nfrom dbt_common.events.base_types import EventLevel\n\n\ndef test_performance_report(project):\n\n    resource_report_level = None\n\n    def check_for_report(e):\n        # If we see a ResourceReport event, record its level\n        if e.info.name == \"ResourceReport\":\n            nonlocal resource_report_level\n            resource_report_level = e.info.level\n\n    runner = dbtRunner(callbacks=[check_for_report])\n\n    runner.invoke([\"run\"])\n\n    # With not cli flag or env var set, ResourceReport should be debug level.\n    assert resource_report_level == EventLevel.DEBUG\n\n    try:\n        os.environ[\"DBT_SHOW_RESOURCE_REPORT\"] = \"1\"\n        runner.invoke([\"run\"])\n\n        # With the appropriate env var set, ResourceReport should be info level.\n        # This allows this fairly technical log line to be omitted by default\n        # but still available in production scenarios.\n        assert resource_report_level == EventLevel.INFO\n    finally:\n        del os.environ[\"DBT_SHOW_RESOURCE_REPORT\"]\n"
  },
  {
    "path": "tests/functional/exit_codes/fixtures.py",
    "content": "import pytest\n\nbad_sql = \"\"\"\nselect bad sql here\n\"\"\"\n\ndupe_sql = \"\"\"\nselect 1 as id, current_date as updated_at\nunion all\nselect 2 as id, current_date as updated_at\nunion all\nselect 3 as id, current_date as updated_at\nunion all\nselect 4 as id, current_date as updated_at\n\"\"\"\n\ngood_sql = \"\"\"\nselect 1 as id, current_date as updated_at\nunion all\nselect 2 as id, current_date as updated_at\nunion all\nselect 3 as id, current_date as updated_at\nunion all\nselect 4 as id, current_date as updated_at\n\"\"\"\n\nsnapshots_good_sql = \"\"\"\n{% snapshot good_snapshot %}\n    {{ config(target_schema=schema, target_database=database, strategy='timestamp', unique_key='id', updated_at='updated_at')}}\n    select * from {{ schema }}.good\n{% endsnapshot %}\n\"\"\"\n\nsnapshots_bad_sql = \"\"\"\n{% snapshot good_snapshot %}\n    {{ config(target_schema=schema, target_database=database, strategy='timestamp', unique_key='id', updated_at='updated_at_not_real')}}\n    select * from {{ schema }}.good\n{% endsnapshot %}\n\"\"\"\n\nschema_yml = \"\"\"\nversion: 2\nmodels:\n- name: good\n  columns:\n  - name: updated_at\n    data_tests:\n    - not_null\n- name: bad\n  columns:\n  - name: updated_at\n    data_tests:\n    - not_null\n- name: dupe\n  columns:\n  - name: updated_at\n    data_tests:\n    - unique\n\"\"\"\n\ndata_seed_good_csv = \"\"\"a,b,c\n1,2,3\n\"\"\"\n\ndata_seed_bad_csv = \"\"\"a,b,c\n1,\\2,3,a,a,a\n\"\"\"\n\n\nclass BaseConfigProject:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"bad.sql\": bad_sql,\n            \"dupe.sql\": dupe_sql,\n            \"good.sql\": good_sql,\n            \"schema.yml\": schema_yml,\n        }\n"
  },
  {
    "path": "tests/functional/exit_codes/test_exit_codes.py",
    "content": "import pytest\n\nimport dbt.exceptions\nfrom dbt.tests.util import check_table_does_exist, check_table_does_not_exist, run_dbt\nfrom tests.functional.exit_codes.fixtures import (\n    BaseConfigProject,\n    data_seed_bad_csv,\n    data_seed_good_csv,\n    snapshots_bad_sql,\n    snapshots_good_sql,\n)\n\n\nclass TestExitCodes(BaseConfigProject):\n    @pytest.fixture(scope=\"class\")\n    def snapshots(self):\n        return {\"g.sql\": snapshots_good_sql}\n\n    def test_exit_code_run_succeed(self, project):\n        results = run_dbt([\"run\", \"--model\", \"good\"])\n        assert len(results) == 1\n        check_table_does_exist(project.adapter, \"good\")\n\n    def test_exit_code_run_fail(self, project):\n        results = run_dbt([\"run\", \"--model\", \"bad\"], expect_pass=False)\n        assert len(results) == 1\n        check_table_does_not_exist(project.adapter, \"bad\")\n\n    def test_schema_test_pass(self, project):\n        results = run_dbt([\"run\", \"--model\", \"good\"])\n        assert len(results) == 1\n\n        results = run_dbt([\"test\", \"--model\", \"good\"])\n        assert len(results) == 1\n\n    def test_schema_test_fail(self, project):\n        results = run_dbt([\"run\", \"--model\", \"dupe\"])\n        assert len(results) == 1\n\n        results = run_dbt([\"test\", \"--model\", \"dupe\"], expect_pass=False)\n        assert len(results) == 1\n\n    def test_compile(self, project):\n        results = run_dbt([\"compile\"])\n        assert len(results) == 7\n\n    def test_snapshot_pass(self, project):\n        run_dbt([\"run\", \"--model\", \"good\"])\n        results = run_dbt([\"snapshot\"])\n        assert len(results) == 1\n        check_table_does_exist(project.adapter, \"good_snapshot\")\n\n\nclass TestExitCodesSnapshotFail(BaseConfigProject):\n    @pytest.fixture(scope=\"class\")\n    def snapshots(self):\n        return {\"b.sql\": snapshots_bad_sql}\n\n    def test_snapshot_fail(self, project):\n        results = run_dbt([\"run\", \"--model\", \"good\"])\n        assert len(results) == 1\n\n        results = run_dbt([\"snapshot\"], expect_pass=False)\n        assert len(results) == 1\n        check_table_does_not_exist(project.adapter, \"good_snapshot\")\n\n\nclass TestExitCodesDeps:\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\n            \"packages\": [\n                {\n                    \"git\": \"https://github.com/dbt-labs/dbt-integration-project\",\n                    \"revision\": \"dbt/1.0.0\",\n                }\n            ]\n        }\n\n    def test_deps(self, project):\n        results = run_dbt([\"deps\"])\n        assert results is None\n\n\nclass TestExitCodesDepsFail:\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\n            \"packages\": [\n                {\n                    \"git\": \"https://github.com/dbt-labs/dbt-integration-project\",\n                    \"revision\": \"bad-branch\",\n                },\n            ]\n        }\n\n    def test_deps_fail(self, project):\n        with pytest.raises(dbt.exceptions.GitCheckoutError) as exc:\n            run_dbt([\"deps\"])\n        expected_msg = \"Error checking out spec='bad-branch'\"\n        assert expected_msg in str(exc.value)\n\n\nclass TestExitCodesSeed:\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\"good.csv\": data_seed_good_csv}\n\n    def test_seed(self, project):\n        results = run_dbt([\"seed\"])\n        assert len(results) == 1\n\n\nclass TestExitCodesSeedFail:\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\"bad.csv\": data_seed_bad_csv}\n\n    def test_seed(self, project):\n        run_dbt([\"seed\"], expect_pass=False)\n"
  },
  {
    "path": "tests/functional/experimental_parser/test_all_experimental_parser.py",
    "content": "import os\n\nimport pytest\n\nfrom dbt.artifacts.resources import RefArgs\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.tests.util import run_dbt\n\n\ndef get_manifest():\n    path = \"./target/partial_parse.msgpack\"\n    if os.path.exists(path):\n        with open(path, \"rb\") as fp:\n            manifest_mp = fp.read()\n        manifest: Manifest = Manifest.from_msgpack(manifest_mp)\n        return manifest\n    else:\n        return None\n\n\nbasic__schema_yml = \"\"\"\nversion: 2\n\nsources:\n  - name: my_src\n    schema: \"{{ target.schema }}\"\n    tables:\n      - name: my_tbl\n\nmodels:\n  - name: model_a\n    columns:\n      - name: fun\n\n\"\"\"\n\nbasic__model_a_sql = \"\"\"\n{{ config(tags='hello', x=False) }}\n{{ config(tags='world', x=True) }}\n\nselect * from {{ ref('model_b') }}\ncross join {{ source('my_src', 'my_tbl') }}\nwhere false as boop\n\n\"\"\"\n\nbasic__model_b_sql = \"\"\"\nselect 1 as fun\n\"\"\"\n\n\nclass BasicExperimentalParser:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_a.sql\": basic__model_a_sql,\n            \"model_b.sql\": basic__model_b_sql,\n            \"schema.yml\": basic__schema_yml,\n        }\n\n\nclass TestBasicExperimentalParser(BasicExperimentalParser):\n    # test that the experimental parser extracts some basic ref, source, and config calls.\n    def test_experimental_parser_basic(\n        self,\n        project,\n    ):\n        run_dbt([\"--use-experimental-parser\", \"parse\"])\n        manifest = get_manifest()\n        node = manifest.nodes[\"model.test.model_a\"]\n        assert node.refs == [RefArgs(name=\"model_b\")]\n        assert node.sources == [[\"my_src\", \"my_tbl\"]]\n        assert node.config._extra == {\"x\": True}\n        assert node.config.tags == [\"hello\", \"world\"]\n\n\nclass TestBasicStaticParser(BasicExperimentalParser):\n    # test that the static parser extracts some basic ref, source, and config calls by default\n    # without the experimental flag and without rendering jinja\n    def test_static_parser_basic(self, project):\n        run_dbt([\"--debug\", \"parse\"])\n\n        manifest = get_manifest()\n        node = manifest.nodes[\"model.test.model_a\"]\n        assert node.refs == [RefArgs(name=\"model_b\")]\n        assert node.sources == [[\"my_src\", \"my_tbl\"]]\n        assert node.config._extra == {\"x\": True}\n        assert node.config.tags == [\"hello\", \"world\"]\n\n\nclass TestBasicNoStaticParser(BasicExperimentalParser):\n    # test that the static parser doesn't run when the flag is set\n    def test_static_parser_is_disabled(self, project):\n        run_dbt([\"--debug\", \"--no-static-parser\", \"parse\"])\n\n        manifest = get_manifest()\n        node = manifest.nodes[\"model.test.model_a\"]\n        assert node.refs == [RefArgs(name=\"model_b\")]\n        assert node.sources == [[\"my_src\", \"my_tbl\"]]\n        assert node.config._extra == {\"x\": True}\n        assert node.config.tags == [\"hello\", \"world\"]\n"
  },
  {
    "path": "tests/functional/exposures/fixtures.py",
    "content": "models_sql = \"\"\"\nselect 1 as id\n\"\"\"\n\nsecond_model_sql = \"\"\"\nselect 1 as id\n\"\"\"\n\n\nmetricflow_time_spine_sql = \"\"\"\nSELECT to_date('02/20/2023', 'mm/dd/yyyy') as date_day\n\"\"\"\n\n\nsource_schema_yml = \"\"\"version: 2\n\nsources:\n  - name: test_source\n    tables:\n      - name: test_table\n\"\"\"\n\n\nsemantic_models_schema_yml = \"\"\"version: 2\n\nsemantic_models:\n  - name: semantic_model\n    model: ref('model')\n    dimensions:\n      - name: created_at\n        type: time\n    measures:\n      - name: distinct_metrics\n        agg: count_distinct\n        expr: id\n    entities:\n      - name: model\n        type: primary\n        expr: id\n    defaults:\n      agg_time_dimension: created_at\n\"\"\"\n\n\nmetrics_schema_yml = \"\"\"version: 2\n\nmetrics:\n  - name: metric\n    label: \"label\"\n    type: simple\n    type_params:\n      measure: \"distinct_metrics\"\n\"\"\"\n\nsimple_exposure_yml = \"\"\"\nversion: 2\n\nexposures:\n  - name: simple_exposure\n    label: simple exposure label\n    type: dashboard\n    depends_on:\n      - ref('model')\n      - source('test_source', 'test_table')\n      - metric('metric')\n    owner:\n      email: something@example.com\n  - name: notebook_exposure\n    type: notebook\n    depends_on:\n      - ref('model')\n      - ref('second_model')\n    owner:\n      email: something@example.com\n      name: Some name\n    description: >\n      A description of the complex exposure\n    maturity: medium\n    meta:\n      tool: 'my_tool'\n      languages:\n        - python\n    tags: ['my_department']\n    url: http://example.com/notebook/1\n\"\"\"\n\ndisabled_models_exposure_yml = \"\"\"\nversion: 2\n\nexposures:\n  - name: simple_exposure\n    type: dashboard\n    config:\n      enabled: False\n    depends_on:\n      - ref('model')\n    owner:\n      email: something@example.com\n  - name: notebook_exposure\n    type: notebook\n    depends_on:\n      - ref('model')\n      - ref('second_model')\n    owner:\n      email: something@example.com\n      name: Some name\n    description: >\n      A description of the complex exposure\n    maturity: medium\n    meta:\n      tool: 'my_tool'\n      languages:\n        - python\n    tags: ['my_department']\n    url: http://example.com/notebook/1\n\"\"\"\n\nenabled_yaml_level_exposure_yml = \"\"\"\nversion: 2\n\nexposures:\n  - name: simple_exposure\n    type: dashboard\n    config:\n      enabled: True\n      tags: ['local_tag', 'common_tag']\n      meta:\n        some_key: 'some_value'\n        type_change: 123\n    depends_on:\n      - ref('model')\n    owner:\n      email: something@example.com\n  - name: notebook_exposure\n    type: notebook\n    depends_on:\n      - ref('model')\n      - ref('second_model')\n    owner:\n      email: something@example.com\n      name: Some name\n    description: >\n      A description of the complex exposure\n    maturity: medium\n    meta:\n      tool: 'my_tool'\n      languages:\n        - python\n    tags: ['my_department']\n    url: http://example.com/notebook/1\n\"\"\"\n\ninvalid_config_exposure_yml = \"\"\"\nversion: 2\n\nexposures:\n  - name: simple_exposure\n    type: dashboard\n    config:\n      enabled: True and False\n    depends_on:\n      - ref('model')\n    owner:\n      email: something@example.com\n\"\"\"\n"
  },
  {
    "path": "tests/functional/exposures/test_exposure_configs.py",
    "content": "import pytest\n\nfrom dbt.artifacts.resources import ExposureConfig\nfrom dbt.tests.util import get_manifest, run_dbt, update_config_file\nfrom dbt_common.dataclass_schema import ValidationError\nfrom tests.functional.exposures.fixtures import (\n    disabled_models_exposure_yml,\n    enabled_yaml_level_exposure_yml,\n    invalid_config_exposure_yml,\n    metricflow_time_spine_sql,\n    metrics_schema_yml,\n    models_sql,\n    second_model_sql,\n    semantic_models_schema_yml,\n    simple_exposure_yml,\n    source_schema_yml,\n)\n\n\n# Test enabled config for exposure in dbt_project.yml\nclass TestExposureEnabledConfigProjectLevel:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model.sql\": models_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"second_model.sql\": second_model_sql,\n            \"exposure.yml\": simple_exposure_yml,\n            \"schema.yml\": source_schema_yml,\n            \"semantic_models.yml\": semantic_models_schema_yml,\n            \"metrics.yml\": metrics_schema_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"exposures\": {\n                \"simple_exposure\": {\n                    \"enabled\": True,\n                },\n            }\n        }\n\n    def test_enabled_exposure_config_dbt_project(self, project):\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n        assert \"exposure.test.simple_exposure\" in manifest.exposures\n\n        new_enabled_config = {\n            \"exposures\": {\n                \"test\": {\n                    \"simple_exposure\": {\n                        \"enabled\": False,\n                    },\n                }\n            }\n        }\n        update_config_file(new_enabled_config, project.project_root, \"dbt_project.yml\")\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n        assert \"exposure.test.simple_exposure\" not in manifest.exposures\n        assert \"exposure.test.notebook_exposure\" in manifest.exposures\n\n\n# Test disabled config at exposure level in yml file\nclass TestConfigYamlLevel:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model.sql\": models_sql,\n            \"second_model.sql\": second_model_sql,\n            \"schema.yml\": disabled_models_exposure_yml,\n        }\n\n    def test_exposure_config_yaml_level(self, project):\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n        assert \"exposure.test.simple_exposure\" not in manifest.exposures\n        assert \"exposure.test.notebook_exposure\" in manifest.exposures\n\n\n# Test inheritence - set configs at project and exposure level - expect exposure level to win\nclass TestExposureConfigsInheritence:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model.sql\": models_sql,\n            \"second_model.sql\": second_model_sql,\n            \"schema.yml\": enabled_yaml_level_exposure_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"exposures\": {\n                \"enabled\": False,\n                \"tags\": [\"global_tag\", \"common_tag\"],\n                \"meta\": {\n                    \"some_key\": \"should_be_overridden\",\n                    \"another_key\": \"should_stay\",\n                    \"type_change\": [\"foo\", \"bar\"],\n                },\n            }\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def expected_config(self):\n        return ExposureConfig(\n            enabled=True,\n            tags=[\"common_tag\", \"global_tag\", \"local_tag\"],\n            meta={\"some_key\": \"some_value\", \"another_key\": \"should_stay\", \"type_change\": 123},\n        )\n\n    def test_exposure_all_configs(self, project, expected_config):\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n        # This should be overridden\n        assert \"exposure.test.simple_exposure\" in manifest.exposures\n        # This should stay disabled\n        assert \"exposure.test.notebook_exposure\" not in manifest.exposures\n\n        exposure = manifest.exposures.get(\"exposure.test.simple_exposure\")\n        assert exposure.tags == expected_config.tags\n        assert exposure.meta == expected_config.meta\n\n        assert isinstance(exposure.config, ExposureConfig)\n        assert exposure.config.enabled == expected_config.enabled\n        assert exposure.config.tags == expected_config.tags\n        assert exposure.config.meta == expected_config.meta\n\n\n# Test invalid config triggers error\nclass TestInvalidConfig:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model.sql\": models_sql,\n            \"second_model.sql\": second_model_sql,\n            \"schema.yml\": invalid_config_exposure_yml,\n        }\n\n    def test_exposure_config_yaml_level(self, project):\n        with pytest.raises(ValidationError) as excinfo:\n            run_dbt([\"parse\"])\n        expected_msg = \"'True and False' is not of type 'boolean'\"\n        assert expected_msg in str(excinfo.value)\n"
  },
  {
    "path": "tests/functional/exposures/test_exposures.py",
    "content": "import pytest\n\nfrom dbt.artifacts.schemas.results import RunStatus\nfrom dbt.contracts.graph.nodes import Exposure\nfrom dbt.tests.util import get_manifest, run_dbt\nfrom tests.functional.exposures.fixtures import (\n    metricflow_time_spine_sql,\n    metrics_schema_yml,\n    models_sql,\n    second_model_sql,\n    semantic_models_schema_yml,\n    simple_exposure_yml,\n    source_schema_yml,\n)\n\n\nclass TestBasicExposures:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"exposure.yml\": simple_exposure_yml,\n            \"model.sql\": models_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"second_model.sql\": second_model_sql,\n            \"schema.yml\": source_schema_yml,\n            \"semantic_models.yml\": semantic_models_schema_yml,\n            \"metrics.yml\": metrics_schema_yml,\n        }\n\n    def test_compilation_names_with_spaces(self, project):\n        run_dbt([\"compile\"])\n        manifest = get_manifest(project.project_root)\n        exposure_ids = list(manifest.exposures.keys())\n        expected_exposure_ids = [\n            \"exposure.test.simple_exposure\",\n            \"exposure.test.notebook_exposure\",\n        ]\n        assert exposure_ids == expected_exposure_ids\n        assert manifest.exposures[\"exposure.test.simple_exposure\"].label == \"simple exposure label\"\n\n    def test_compilation_depends_on(self, project):\n        run_dbt([\"compile\"])\n        manifest = get_manifest(project.project_root)\n        exposure_depends_on = manifest.exposures[\"exposure.test.simple_exposure\"].depends_on.nodes\n        expected_exposure_depends_on = [\n            \"source.test.test_source.test_table\",\n            \"model.test.model\",\n            \"metric.test.metric\",\n        ]\n        assert sorted(exposure_depends_on) == sorted(expected_exposure_depends_on)\n\n    def test_execution_default(self, project):\n        results = run_dbt([\"build\"])\n        exposure_results = (\n            result for result in results.results if isinstance(result.node, Exposure)\n        )\n        assert {result.node.name for result in exposure_results} == {\n            \"simple_exposure\",\n            \"notebook_exposure\",\n        }\n        assert all(result.status == RunStatus.NoOp for result in exposure_results)\n        assert all(\"NO-OP\" in result.message for result in exposure_results)\n\n    def test_execution_exclude(self, project):\n        results = run_dbt([\"build\", \"--exclude\", \"simple_exposure\"])\n        exposure_results = (\n            result for result in results.results if isinstance(result.node, Exposure)\n        )\n        assert {result.node.name for result in exposure_results} == {\"notebook_exposure\"}\n\n    def test_execution_select(self, project):\n        results = run_dbt([\"build\", \"--select\", \"simple_exposure\"])\n        exposure_results = (\n            result for result in results.results if isinstance(result.node, Exposure)\n        )\n        assert {result.node.name for result in exposure_results} == {\"simple_exposure\"}\n"
  },
  {
    "path": "tests/functional/external_reference/test_external_reference.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt\n\nexternal_model_sql = \"\"\"\n{{\n  config(\n    materialized = \"view\"\n  )\n}}\n\nselect * from \"{{ this.schema + 'z' }}\".\"external\"\n\"\"\"\n\nmodel_sql = \"\"\"\nselect 1 as id\n\"\"\"\n\n\nclass TestExternalReference:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model.sql\": external_model_sql}\n\n    def test_external_reference(self, project, unique_schema):\n        external_schema = unique_schema + \"z\"\n        project.run_sql(f'create schema \"{external_schema}\"')\n        project.run_sql(f'create table \"{external_schema}\".\"external\" (id integer)')\n        project.run_sql(f'insert into \"{external_schema}\".\"external\" values (1), (2)')\n\n        results = run_dbt([\"run\"])\n        assert len(results) == 1\n\n        # running it again should succeed\n        results = run_dbt([\"run\"])\n        assert len(results) == 1\n\n\n# The opposite of the test above -- check that external relations that\n# depend on a dbt model do not create issues with caching\nclass TestExternalDependency:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model.sql\": model_sql}\n\n    def test_external_reference(self, project, unique_schema):\n        results = run_dbt([\"run\"])\n        assert len(results) == 1\n\n        external_schema = unique_schema + \"z\"\n        project.run_sql(f'create schema \"{external_schema}\"')\n        project.run_sql(\n            f'create view \"{external_schema}\".\"external\" as (select * from {unique_schema}.model)'\n        )\n\n        # running it again should succeed\n        results = run_dbt([\"run\"])\n        assert len(results) == 1\n"
  },
  {
    "path": "tests/functional/fail_fast/test_fail_fast_run.py",
    "content": "import json\nfrom pathlib import Path\n\nimport pytest\n\nfrom dbt.tests.util import run_dbt\n\nmodels__one_sql = \"\"\"\nselect 1\n\"\"\"\n\nmodels__two_sql = \"\"\"\n-- depends_on: {{ ref('one') }}\nselect 1 /failed\n\"\"\"\n\n\nclass FailFastBase:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"one.sql\": models__one_sql, \"two.sql\": models__two_sql}\n\n\nclass TestFastFailingDuringRun(FailFastBase):\n    def test_fail_fast_run(\n        self,\n        project,\n        models,  # noqa: F811\n    ):\n        res = run_dbt([\"run\", \"--fail-fast\", \"--threads\", \"1\"], expect_pass=False)\n        assert {r.node.unique_id: r.status for r in res.results} == {\n            \"model.test.one\": \"success\",\n            \"model.test.two\": \"error\",\n        }\n\n        run_results_file = Path(project.project_root) / \"target/run_results.json\"\n        assert run_results_file.is_file()\n        with run_results_file.open() as run_results_str:\n            run_results = json.loads(run_results_str.read())\n            assert len(run_results[\"results\"]) == 2\n            assert run_results[\"results\"][0][\"status\"] == \"success\"\n            assert run_results[\"results\"][1][\"status\"] == \"error\"\n\n\nclass TestFailFastFromConfig(FailFastBase):\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"flags\": {\n                \"send_anonymous_usage_stats\": False,\n                \"fail_fast\": True,\n            }\n        }\n\n    def test_fail_fast_run_project_flags(\n        self,\n        project,\n        models,  # noqa: F811\n    ):\n        res = run_dbt([\"run\", \"--threads\", \"1\"], expect_pass=False)\n        assert {r.node.unique_id: r.status for r in res.results} == {\n            \"model.test.one\": \"success\",\n            \"model.test.two\": \"error\",\n        }\n"
  },
  {
    "path": "tests/functional/fixtures/__init__.py",
    "content": ""
  },
  {
    "path": "tests/functional/fixtures/happy_path_fixture.py",
    "content": "import os\nfrom distutils.dir_util import copy_tree\n\nimport pytest\n\n\ndef delete_files_in_directory(directory_path):\n    try:\n        with os.scandir(directory_path) as entries:\n            for entry in entries:\n                if entry.is_file():\n                    os.unlink(entry.path)\n        print(\"All files deleted successfully.\")\n    except OSError:\n        print(\"Error occurred while deleting files.\")\n\n\n@pytest.fixture(scope=\"class\")\ndef happy_path_project_files(project_root):\n    # copy fixture files to the project root\n    delete_files_in_directory(project_root)\n    copy_tree(\n        os.path.dirname(os.path.realpath(__file__)) + \"/happy_path_project\", str(project_root)\n    )\n\n\n# We do project_setup first because it will write out a dbt_project.yml.\n# This file will be overwritten by the files in happy_path_project later on.\n@pytest.fixture(scope=\"class\")\ndef happy_path_project(project_setup, happy_path_project_files):\n    # A fixture that gives functional test the project living in happy_path_project\n    return project_setup\n"
  },
  {
    "path": "tests/functional/fixtures/happy_path_project/analyses/a.sql",
    "content": "select 4 as id\n"
  },
  {
    "path": "tests/functional/fixtures/happy_path_project/analyses/a.yml",
    "content": "analyses:\n  - name: a\n    description: description\n    config:\n      tags: [\"tag\"]\n      enabled: true\n      meta: {\n        \"test\": 1\n      }\n      docs:\n        show: true\n        node_color: purple\n      group: \"finance\"\n    columns:\n      - name: id\n        description: id description\n"
  },
  {
    "path": "tests/functional/fixtures/happy_path_project/dbt_project.yml",
    "content": "analysis-paths:\n- analyses\nconfig-version: 2\nflags:\n  send_anonymous_usage_stats: false\n  state_modified_compare_more_unrendered_values: true\nmacro-paths:\n- macros\nname: test\nprofile: test\nseed-paths:\n- seeds\nmodels:\n  +enabled: true\n  test:\n    +enabled: true\n    sub:\n      +enabled: true\n      inner:\n        +enabled: true\nseeds:\n  +quote_columns: true\n  test:\n    +quote_columns: false\nsnapshot-paths:\n- snapshots\ntest-paths:\n- tests\n"
  },
  {
    "path": "tests/functional/fixtures/happy_path_project/functions/area_of_circle.sql",
    "content": "SELECT pi() * radius * radius\n"
  },
  {
    "path": "tests/functional/fixtures/happy_path_project/functions/area_of_circle.yml",
    "content": "functions:\n  - name: area_of_circle\n    description: Calculates the area of a circle for a given radius\n    arguments:\n      - name: radius\n        data_type: float\n        description: A floating point number representing the radius of the circle\n    returns:\n      data_type: float\n"
  },
  {
    "path": "tests/functional/fixtures/happy_path_project/macros/expression_is_true.sql",
    "content": "{% test expression_is_true(model, expression, column_name=None) %}\n\n{% set column_list = '*' if should_store_failures() else \"1\" %}\n\nselect\n    {{ column_list }}\nfrom {{ model }}\n{% if column_name is none %}\nwhere not({{ expression }})\n{%- else %}\nwhere not({{ column_name }} {{ expression }})\n{%- endif %}\n\n{% endtest %}\n"
  },
  {
    "path": "tests/functional/fixtures/happy_path_project/macros/macro_stuff.sql",
    "content": "{% macro cool_macro() %}\n  wow!\n{% endmacro %}\n\n{% macro other_cool_macro(a, b) %}\n  cool!\n{% endmacro %}\n"
  },
  {
    "path": "tests/functional/fixtures/happy_path_project/models/docs.md",
    "content": "{% docs my_docs %}\n  some docs\n{% enddocs %}\n"
  },
  {
    "path": "tests/functional/fixtures/happy_path_project/models/e.yml",
    "content": "exposures:\n  - name: weekly_jaffle_metrics\n    label: Jaffles by the Week\n    type: dashboard\n    maturity: high\n    url: https://bi.tool/dashboards/1\n    description: >\n      Did someone say \"exponential growth\"?\n    depends_on:\n      - ref('incremental')\n    owner:\n      name: Callum McData\n      email: data@jaffleshop.com\n    config:\n      enabled: true\n      meta: {}\n      tags: [\"tag\"]\n"
  },
  {
    "path": "tests/functional/fixtures/happy_path_project/models/ephemeral.sql",
    "content": "{{ config(materialized='ephemeral') }}\n\nselect\n  1 as id,\n  {{ dbt.date_trunc('day', dbt.current_timestamp()) }} as created_at\n"
  },
  {
    "path": "tests/functional/fixtures/happy_path_project/models/g.yml",
    "content": "groups:\n  - name: finance\n    description: description\n    config:\n      meta:\n        custom_field: value\n    owner:\n      # one of 'name' or 'email' is required;\n      email: finance@jaffleshop.com\n"
  },
  {
    "path": "tests/functional/fixtures/happy_path_project/models/incremental.sql",
    "content": "{{\n  config(\n    materialized = \"incremental\",\n    incremental_strategy = \"delete+insert\",\n  )\n}}\n\nselect * from {{ ref('seed') }}\n\n{% if is_incremental() %}\n    where a > (select max(a) from {{this}})\n{% endif %}\n"
  },
  {
    "path": "tests/functional/fixtures/happy_path_project/models/m.yml",
    "content": "metrics:\n  - name: total_outer\n    type: simple\n    description: The total count of outer\n    label: Total Outer\n    type_params:\n      measure: total_outer_count\n    time_granularity: month\n\n  - name: simple_ratio_metric\n    description: a simple ratio metric\n    type: ratio\n    label: Simple Ratio Metric\n    type_params:\n      numerator: total_outer\n      denominator:\n        name: total_outer\n        alias: filtered_total_outer\n\n  - name: filtered_ratio_metric\n    description: a ratio metric\n    type: ratio\n    label: Ratio Metric 2\n    type_params:\n      numerator:\n        name: total_outer\n        filter: 1 = 1\n      denominator:\n        name: total_outer\n        filter:\n          - 1 = 1\n          - 2 = 2\n        alias: filtered_total_outer_again\n\n  - name: cumulative_metric\n    description: a cumulative metric\n    type: cumulative\n    label: Cumulative Metric\n    type_params:\n      measure:\n        name: total_outer_count\n        fill_nulls_with: 0\n        join_to_timespine: false\n        filter: 1 = 1\n        alias: filtered_total_outer_count\n      cumulative_type_params:\n        grain_to_date: day\n        period_agg: first\n\n  - name: cumulative_metric_2\n    description: a cumulative metric\n    type: cumulative\n    label: Cumulative Metric 2\n    type_params:\n      measure:\n        name: total_outer_count\n        fill_nulls_with: 0\n        join_to_timespine: false\n        filter: 1 = 1\n        alias: filtered_total_outer_count_2\n      cumulative_type_params:\n        period_agg: first\n        window: 1 day\n\n  - name: conversion_metric\n    description: a conversion metric\n    type: conversion\n    label: Conversion Metric\n    type_params:\n      conversion_type_params:\n        entity: my_entity\n        calculation: conversion_rate\n        base_measure: total_outer_count\n        conversion_measure:\n          name: total_outer_count\n          fill_nulls_with: 0\n          join_to_timespine: false\n        window: 1 day\n        constant_properties:\n          - base_property: my_entity\n            conversion_property: created_at\n\n  - name: derived_metric\n    description: a derived metric\n    type: derived\n    label: Derived Metric\n    type_params:\n      expr: srm - cm + filtered_ratio_metric\n      metrics:\n        - name: simple_ratio_metric\n          alias: srm\n          filter: 1 = 1\n          offset_window: 1 month\n        - name: conversion_metric\n          alias: cm\n          offset_to_grain: month\n        - filtered_ratio_metric\n"
  },
  {
    "path": "tests/functional/fixtures/happy_path_project/models/macros.yml",
    "content": "macros:\n  - name: some_macro\n    description: a description\n    config:\n      meta:\n        owner: \"person@gmail.com\"\n"
  },
  {
    "path": "tests/functional/fixtures/happy_path_project/models/metricflow_time_spine.sql",
    "content": "select\n  {{ dbt.date_trunc('day', dbt.current_timestamp()) }} as date_day\n"
  },
  {
    "path": "tests/functional/fixtures/happy_path_project/models/metricflow_time_spine_second.sql",
    "content": "select\n  {{ dbt.date_trunc('second', dbt.current_timestamp()) }} as ts_second\n"
  },
  {
    "path": "tests/functional/fixtures/happy_path_project/models/model_to_unit_test.sql",
    "content": "{{ config(materialized='table') }}\n\nSELECT * FROM {{ ref('seed')}}\n"
  },
  {
    "path": "tests/functional/fixtures/happy_path_project/models/model_with_lots_of_schema_configs.sql",
    "content": "select * from {{ ref('ephemeral') }}\n"
  },
  {
    "path": "tests/functional/fixtures/happy_path_project/models/outer.sql",
    "content": "select * from {{ ref('ephemeral') }}\n"
  },
  {
    "path": "tests/functional/fixtures/happy_path_project/models/schema.yml",
    "content": "version: 2\nmodels:\n  - name: outer\n    description: The outer table\n    columns:\n      - name: id\n        description: The id value\n        data_tests:\n          - unique\n          - not_null\n  - name: metricflow_time_spine\n    description: Day time spine\n    time_spine:\n      standard_granularity_column: date_day\n    columns:\n      - name: date_day\n        granularity: day\n    config:\n      tags:\n        - \"list\"\n        - \"of\"\n        - \"tags\"\n      pre_hook:\n        - \"SELECT 'string_pre_hook' as my_pre_hook;\"\n      post_hook:\n        - \"SELECT 'string_post_hook' as my_post_hook;\"\n      group: \"finance\"\n  - name: metricflow_time_spine_second\n    description: Second time spine\n    config:\n      event_time: ts_second\n    columns:\n      - name: ts_second\n        granularity: second\n  - name: model_with_lots_of_schema_configs\n    columns:\n      - name: id\n        description: The id value\n        config:\n          tags:\n            - \"column_level_tag\"\n          meta:\n            column_meta: \"column_meta_value\"\n        data_tests:\n          - unique\n          - not_null:\n              name: \"my_favorite_test\"\n              description: \"A test that should pass\"\n              config:\n                alias: \"not_null__id__alias\"\n                database: \"dbt\"\n                group: \"important_tests\"\n                enabled: true\n                error_if: \"!= 0\"\n                fail_calc: \"count(*)\"\n                limit: 10\n                meta:\n                  my_custom_meta_key: \"my_custom_meta_value\"\n                schema: \"dbt_test__audit\"\n                severity: \"warn\"\n                store_failures: true\n                store_failures_as: \"table\"\n                tags:\n                  - \"test_tag\"\n                warn_if: \"!= 0\"\n                where: \"1 = 1\"\n      - name: created_at\n        description: The date the row was created\n        data_tests:\n          - my_generic_test:\n              name: \"my_second_favorite_test\"\n              description: \"A test that should pass\"\n              config:\n                alias: \"my_generic_test__created_at__alias\"\n                database: \"dbt\"\n                group: \"important_tests\"\n                enabled: true\n                error_if: \"!= 0\"\n                fail_calc: \"count(*)\"\n                limit: 10\n                meta:\n                  my_custom_meta_key: \"my_custom_meta_value\"\n                schema: \"dbt_test__audit\"\n                severity: \"warn\"\n                store_failures: true\n                store_failures_as: \"table\"\n                tags:\n                  - \"test_tag\"\n                warn_if: \"!= 0\"\n                where: \"1 = 1\"\n\n    config:\n      access: public\n      alias: \"outer_alias\"\n      batch_size: day\n      begin: \"2020-01-01\"\n      concurrent_batches: false\n      contract:\n        alias_types: true\n        enforce: true\n      docs:\n        node_color: purple\n        show: true\n      database: \"dbt\"\n      enabled: true\n      full_refresh: false\n      grants:\n        select: [\"root\"]\n      lookback: 5\n      materialized: table\n      meta:\n        my_custom_property: \"string_meta\"\n      on_configuration_change: apply\n      persist_docs:\n        columns: true\n        relation: true\n      post_hook: \"SELECT 'string_post_hook' as my_post_hook;\"\n      pre_hook: \"SELECT 'string_pre_hook' as my_pre_hook;\"\n      schema: \"test\"\n      sql_header: \"SELECT 1 as header;\"\n      tags: \"string_tag\"\n      unique_key: id\n    constraints:\n      - type: primary_key\n        columns: [\"id\"]\n        warn_unsupported: false\n      - type: foreign_key\n        columns: [\"id\"]\n        to: source('my_source', 'my_table')\n        to_columns: [\"id\"]\n      - type: check\n        columns: [\"id\"]\n        expression: \"id > 0\"\n        name: \"Check that id is greater than 0\"\n    deprecation_date: \"2052-05-01 00:00:00-04:00\"\n    description: A model with lots of configs\n\nsources:\n  - name: my_source\n    description: description\n    database: raw\n    schema: jaffle_shop\n    loader: test\n    config:\n      enabled: true\n      event_time: column_name\n      loaded_at_field: column_name\n      meta:\n        source_meta: 1\n      tags: [\"source_tag\"]\n      freshness:\n        warn_after:\n          count: 1\n          period: minute\n        error_after:\n          count: 2\n          period: hour\n        filter: \"column_name = 1\"\n\n    # # overrides: test\n\n    quoting:\n      database: true\n      schema: true\n      identifier: true\n\n    tables:\n      - name: my_table\n        description: description\n        identifier: table_identifier\n        tests: []\n        quoting:\n          database: true\n          schema: true\n          identifier: true\n        external:\n          location: location\n          file_format: file_format\n          row_format: row_format\n          tbl_properties: tbl_properties\n          partitions:\n            - name: column_name\n              data_type: data_type\n              description: description\n              meta:\n                test: 1\n          additional_property: additional_value\n        columns:\n          - name: column_name\n            description: description\n            quote: true\n            tests: []\n            config:\n              meta:\n                test: 1\n              tags: [\"column_tag\"]\n        config:\n          enabled: true\n          event_time: column_name\n          loaded_at_field: column_name\n          meta:\n            table_meta: 1\n          tags: [\"table_tag\"]\n          freshness:\n            warn_after:\n              count: 1\n              period: minute\n            error_after:\n              count: 2\n              period: hour\n            filter: \"column_name = 1\"\n"
  },
  {
    "path": "tests/functional/fixtures/happy_path_project/models/sm.yml",
    "content": "semantic_models:\n  - name: my_sm\n    model: ref('outer')\n    defaults:\n      agg_time_dimension: created_at\n    entities:\n      - name: my_entity\n        type: primary\n        expr: id\n      - name: user\n        type: foreign\n        expr: user_id\n    dimensions:\n      - name: created_at\n        type: time\n        type_params:\n          time_granularity: day\n    measures:\n      - name: total_outer_count\n        agg: count\n        expr: 1\n      - name: discrete_order_value_p99\n        expr: order_total\n        agg: percentile\n        agg_time_dimension: created_at\n        agg_params:\n          percentile: 0.99\n          use_discrete_percentile: True\n          use_approximate_percentile: False\n        create_metric: true\n      - name: sum_of_things\n        expr: 2\n        agg: sum\n        agg_time_dimension: created_at\n      - name: has_revenue\n        expr: true\n        agg: sum_boolean\n        agg_time_dimension: created_at\n      - name: test_non_additive\n        expr: txn_revenue\n        agg: sum\n        non_additive_dimension:\n          name: created_at\n          window_choice: max\n"
  },
  {
    "path": "tests/functional/fixtures/happy_path_project/models/snapshot_source.sql",
    "content": "select 0 as id, 1 as col1, 2 as col2, 3 as col3\n"
  },
  {
    "path": "tests/functional/fixtures/happy_path_project/models/sq.yml",
    "content": "saved_queries:\n  - name: my_saved_query\n    label: My Saved Query\n    query_params:\n        metrics:\n            - total_outer\n        group_by:\n            - \"Dimension('my_entity__created_at')\"\n    exports:\n        - name: my_export\n          config:\n            alias: my_export_alias\n            export_as: table\n            schema: my_export_schema_name\n"
  },
  {
    "path": "tests/functional/fixtures/happy_path_project/models/sub/inner.sql",
    "content": "select * from {{ ref('outer') }}\n"
  },
  {
    "path": "tests/functional/fixtures/happy_path_project/models/unit_tests.yml",
    "content": "unit_tests:\n  - name: test_model_to_unit_test\n    description: \"A simple test of the outer model\"\n    model: model_to_unit_test\n    given:\n      - input: ref('seed')\n        format: csv\n        fixture: test_incremental_fixture\n    expect:\n      format: csv\n      fixture: test_incremental_fixture\n  - name: test_model_to_unit_test_2\n    description: \"A simple test of the outer model\"\n    model: model_to_unit_test\n    versions:\n      include:\n      exclude:\n    config:\n      enabled: true\n      meta:\n        my_custom_meta_key: \"my_custom_meta_value\"\n      tags:\n        - \"test_tag\"\n    given:\n      - input: ref('seed')\n        format: sql\n        rows: |\n          SELECT 2 as a, 3 as b\n    expect:\n      format: dict\n      rows:\n        - {a: 2, b: 3}\n    overrides:\n      macros:\n        is_incremental: false\n      vars: {}\n      env_vars: {}\n"
  },
  {
    "path": "tests/functional/fixtures/happy_path_project/seeds/s.yml",
    "content": "seeds:\n  - name: seed\n    description: 'test_description'\n    data_tests:\n      - expression_is_true:\n          arguments:\n            expression: \"b = 2\"\n    columns:\n      - name: a\n        description: a description\n        quote: true\n        tests:\n          - not_null\n        config:\n          tags: [\"tag\"]\n          meta: {}\n      - name: b\n        description: b description\n        quote: true\n        tests:\n          - not_null\n        config:\n          meta: {}\n          tags: [\"tag\"]\n    config:\n      docs:\n        show: true\n        node_color: purple\n      quote_columns: false\n      column_types:\n        a: BIGINT\n      delimiter: \",\"\n      enabled: true\n      tags: \"tag\"\n      pre_hook: \"select 1\"\n      post_hook: \"select 1\"\n      database: \"dbt\"\n      schema: \"test\"\n      alias: test_alias\n      persist_docs: {}\n      full_refresh: true\n      meta: {'meta_key': 'meta_value'}\n      grants: {}\n      event_time: my_time_field\n      group: finance\n"
  },
  {
    "path": "tests/functional/fixtures/happy_path_project/seeds/seed.csv",
    "content": "a,b\n1,2\n"
  },
  {
    "path": "tests/functional/fixtures/happy_path_project/snapshots/snapshot.sql",
    "content": "{% snapshot my_snapshot %}\n    {{\n        config(\n            database=var('target_database', database),\n            schema=schema,\n            unique_key='id',\n            strategy='timestamp',\n            updated_at='updated_at',\n        )\n    }}\n    select * from {{database}}.{{schema}}.seed\n{% endsnapshot %}\n"
  },
  {
    "path": "tests/functional/fixtures/happy_path_project/snapshots/snapshot_2.yml",
    "content": "version: 2\n\nsnapshots:\n  - name: snapshot_2\n    relation: ref(\"snapshot_source\")\n    description: Description of snapshot_2\n    config:\n      database: mydb\n      schema: myschema\n      unique_key: id\n      strategy: check\n      updated_at: updated_at\n      check_cols: [ \"alpha\", \"beta\", \"delta\" ]\n      snapshot_meta_column_names:\n        dbt_valid_from: my_from_col\n        dbt_valid_to: my_valid_to_col\n        dbt_scd_id: my_scd_col\n        dbt_updated_at: my_updated_at_col\n        dbt_is_deleted: my_is_deleted_col\n      hard_deletes: new_record\n      dbt_valid_to_current: valid_to_current\n      meta:\n        owner: \"@alice\"\n        maturity: in dev\n      docs:\n        sfhow: true\n        node_color: purple\n"
  },
  {
    "path": "tests/functional/fixtures/happy_path_project/snapshots/snapshot_3.yml",
    "content": "version: 2\n\nsnapshots:\n  - name: snapshot_3\n    relation: ref(\"snapshot_source\")\n    description: Description of snapshot_3\n    config:\n      database: mydb\n      schema: myschema\n      unique_key: id\n      strategy: timestamp\n      updated_at: updated_at\n      snapshot_meta_column_names:\n        dbt_valid_from: my_from_col\n        dbt_valid_to: my_valid_to_col\n        dbt_scd_id: my_scd_col\n        dbt_updated_at: my_updated_at_col\n        dbt_is_deleted: my_is_deleted_col\n      invalidate_hard_deletes: true\n      dbt_valid_to_current: valid_to_current\n      meta:\n        owner: \"@alice\"\n        maturity: in dev\n      docs:\n        sfhow: true\n        node_color: purple\n"
  },
  {
    "path": "tests/functional/fixtures/happy_path_project/tests/fixtures/test_incremental_fixture.csv",
    "content": "a,b\n1,2\n2,3\n"
  },
  {
    "path": "tests/functional/fixtures/happy_path_project/tests/generic/my_generic_test.sql",
    "content": "{% test my_generic_test(model, column_name) %}\n    SELECT 1 as a_column WHERE 1 = 2\n{% endtest %}\n"
  },
  {
    "path": "tests/functional/fixtures/happy_path_project/tests/schema.yml",
    "content": "version: 2\n\ndata_tests:\n  - name: t\n    description: \"Single Data Test in happy path fixture\"\n    config:\n      alias: \"test_alias\"\n      database: \"dbt\"\n      group: \"important_tests\"\n      enabled: true\n      error_if: \"!= 0\"\n      fail_calc: \"count(*)\"\n      limit: 10\n      meta:\n        my_custom_meta_key: \"my_custom_meta_value\"\n      schema: \"dbt_test__audit\"\n      severity: \"warn\"\n      store_failures: true\n      store_failures_as: \"table\"\n      tags:\n        - \"test_tag\"\n      warn_if: \"!= 0\"\n      where: \"1 = 1\"\n\ngroups:\n  - name: important_tests\n    owner:\n      email: data@example.com\n"
  },
  {
    "path": "tests/functional/fixtures/happy_path_project/tests/t.sql",
    "content": "select 1 as id WHERE 1 = 2\n"
  },
  {
    "path": "tests/functional/fixtures.py",
    "content": "models__my_model_sql = \"\"\"\nwith my_cte as (\n    select 1 as id, 'blue' as color\n    union all\n    select 2 as id, 'green' as red\n    union all\n    select 3 as id, 'red' as red\n)\nselect * from my_cte\n\"\"\"\n\nmodels__schema_yml = \"\"\"\nmodels:\n  - name: my_model\n    columns:\n      - name: id\n        tests:\n          - unique:\n              description: \"id must be unique\"\n          - not_null\n      - name: color\n        tests:\n          - accepted_values:\n              values: ['blue', 'green', 'red']\n              description: \"{{ doc('color_accepted_values') }}\"\n\"\"\"\n\nmodels__doc_block_md = \"\"\"\n{% docs color_accepted_values %}\n\nThe `color` column must be one of 'blue', 'green', or 'red'.\n\n{% enddocs %}\n\"\"\"\n"
  },
  {
    "path": "tests/functional/functions/test_udafs.py",
    "content": "from typing import Dict\n\nimport pytest\n\nfrom dbt.artifacts.resources import FunctionReturns\nfrom dbt.artifacts.resources.types import FunctionType\nfrom dbt.contracts.graph.nodes import FunctionNode\nfrom dbt.tests.util import run_dbt\n\ndouble_total_sql = \"\"\"\nSELECT SUM(values) * 2\n\"\"\"\n\ndouble_total_yml = \"\"\"\nfunctions:\n  - name: double_total\n    description: Sums the sequence of numbers and then doubles the result\n    config:\n      type: aggregate\n    arguments:\n      - name: values\n        data_type: float\n        description: A sequence of numbers\n    returns:\n      data_type: float\n\"\"\"\n\n\nclass BasicUDAFSetup:\n    @pytest.fixture(scope=\"class\")\n    def functions(self) -> Dict[str, str]:\n        return {\n            \"double_total.sql\": double_total_sql,\n            \"double_total.yml\": double_total_yml,\n        }\n\n\nclass TestBasicSQLUDAF(BasicUDAFSetup):\n    def test_basic_sql_udaf_parsing(self, project):\n        manifest = run_dbt([\"parse\"])\n        assert len(manifest.functions) == 1\n        assert \"function.test.double_total\" in manifest.functions\n        function_node = manifest.functions[\"function.test.double_total\"]\n        assert isinstance(function_node, FunctionNode)\n        assert (\n            function_node.description == \"Sums the sequence of numbers and then doubles the result\"\n        )\n        assert function_node.config.type == FunctionType.Aggregate\n        assert len(function_node.arguments) == 1\n        argument = function_node.arguments[0]\n        assert argument.name == \"values\"\n        assert argument.data_type == \"float\"\n        assert argument.description == \"A sequence of numbers\"\n        assert function_node.returns == FunctionReturns(data_type=\"float\")\n"
  },
  {
    "path": "tests/functional/functions/test_udfs.py",
    "content": "from typing import Dict\n\nimport agate\nimport pytest\n\nfrom dbt.artifacts.resources import FunctionReturns\nfrom dbt.artifacts.resources.types import FunctionType, FunctionVolatility\nfrom dbt.contracts.graph.nodes import FunctionNode\nfrom dbt.exceptions import ParsingError\nfrom dbt.tests.util import run_dbt, write_file\n\ndouble_it_sql = \"\"\"\nSELECT value * 2\n\"\"\"\n\ndouble_it_py = \"\"\"\ndef entry(value):\n    return value * 2\n\"\"\"\n\ndouble_it_py_with_jinja = \"\"\"\ndef entry(value):\n    {% if 1 == 1 %}\n    return value * 2\n    {% else %}\n    {# this should never happen #}\n    return value * 3\n    {% endif %}\n\"\"\"\n\ndouble_it_deterministic_sql = \"\"\"\n{{ config(volatility='deterministic') }}\nSELECT value * 2\n\"\"\"\n\ndouble_it_deterministic_py = \"\"\"\n{{ config(volatility='deterministic') }}\ndef entry(value):\n    return value * 2\n\"\"\"\n\ndouble_it_yml = \"\"\"\nfunctions:\n  - name: double_it\n    description: Doubles whatever number is passed in\n    arguments:\n      - name: value\n        data_type: float\n        description: A number to be doubled\n    returns:\n      data_type: float\n\"\"\"\n\ndouble_it_python_yml = \"\"\"\nfunctions:\n  - name: double_it\n    description: Doubles whatever number is passed in\n    config:\n        runtime_version: \"3.11\"\n        entry_point: entry\n    arguments:\n      - name: value\n        data_type: float\n        description: A number to be doubled\n    returns:\n      data_type: float\n\"\"\"\n\ndouble_it_non_deterministic_yml = \"\"\"\nfunctions:\n  - name: double_it\n    description: Doubles whatever number is passed in\n    config:\n      volatility: non-deterministic\n    arguments:\n      - name: value\n        data_type: float\n        description: A number to be doubled\n    returns:\n      data_type: float\n\"\"\"\n\ndouble_it_non_deterministic_python_yml = \"\"\"\nfunctions:\n  - name: double_it\n    description: Doubles whatever number is passed in\n    config:\n      volatility: non-deterministic\n      language_version: \"3.11\"\n      entry_point: entry\n    arguments:\n      - name: value\n        data_type: float\n        description: A number to be doubled\n    returns:\n      data_type: float\n\"\"\"\n\nnumbers_model_sql = \"\"\"\nSELECT 1 as number\nUNION ALL\nSELECT 2 as number\nUNION ALL\nSELECT 3 as number\n\"\"\"\n\nsum_numbers_function_sql = \"\"\"\nSELECT sum(number) as sum_numbers FROM {{ ref('numbers_model') }}\n\"\"\"\n\nsum_numbers_function_yml = \"\"\"\nfunctions:\n  - name: sum_numbers_function\n    description: Sums the numbers in the numbers_model\n    returns:\n      data_type: integer\n\"\"\"\n\nnumbers_seed_csv = \"\"\"number\n1\n2\n3\n\"\"\"\n\nnumbers_source_yml = \"\"\"\nsources:\n  - name: test_source\n    schema: \"{{ target.schema }}\"\n    tables:\n      - name: numbers_seed\n\"\"\"\n\nsum_numbers_function_from_source_sql = \"\"\"\nSELECT sum(number) as sum_numbers FROM {{ source('test_source', 'numbers_seed') }}\n\"\"\"\n\n\nclass BasicUDFSetup:\n    @pytest.fixture(scope=\"class\")\n    def functions(self) -> Dict[str, str]:\n        return {\n            \"double_it.sql\": double_it_sql,\n            \"double_it.yml\": double_it_yml,\n        }\n\n\nscalar_function_python_macro = \"\"\"\n{% macro postgres__scalar_function_python(target_relation) %}\n  SELECT 1;\n{% endmacro %}\n\"\"\"\n\nsum_2_values_sql = \"\"\"\nSELECT val1 + val2 as sum_2_values\n\"\"\"\n\nsum_2_values_yml = \"\"\"\nfunctions:\n  - name: sum_2_values\n    description: Add two values together\n    arguments:\n      - name: val1\n        data_type: integer\n        description: The first value\n      - name: val2\n        data_type: integer\n        description: The second value\n        default_value: 0\n    returns:\n      data_type: integer\n\"\"\"\n\nsum_2_values_bad_default_arg_order_yml = \"\"\"\nfunctions:\n  - name: sum_2_values\n    description: Add two values together\n    arguments:\n      - name: val1\n        data_type: integer\n        description: The first value\n        default_value: 0\n      - name: val2\n        data_type: integer\n        description: The second value\n    returns:\n      data_type: integer\n\"\"\"\n\n\nclass TestBasicSQLUDF(BasicUDFSetup):\n    def test_basic_parsing(self, project):\n        # Simple parsing\n        manifest = run_dbt([\"parse\"])\n        assert len(manifest.functions) == 1\n        assert \"function.test.double_it\" in manifest.functions\n        function_node = manifest.functions[\"function.test.double_it\"]\n        assert isinstance(function_node, FunctionNode)\n        assert function_node.description == \"Doubles whatever number is passed in\"\n        assert function_node.language == \"sql\"\n        assert function_node.config.type == FunctionType.Scalar\n        assert function_node.config.volatility is None\n        assert len(function_node.arguments) == 1\n        argument = function_node.arguments[0]\n        assert argument.name == \"value\"\n        assert argument.data_type == \"float\"\n        assert argument.description == \"A number to be doubled\"\n        assert function_node.returns == FunctionReturns(data_type=\"float\")\n\n        # Update with volatility specified in sql\n        write_file(double_it_deterministic_sql, project.project_root, \"functions\", \"double_it.sql\")\n        manifest = run_dbt([\"parse\", \"--no-partial-parse\"])\n        assert len(manifest.functions) == 1\n        assert \"function.test.double_it\" in manifest.functions\n        function_node = manifest.functions[\"function.test.double_it\"]\n        assert function_node.config.volatility == FunctionVolatility.Deterministic\n\n        # Update with volatility specified in yml\n        write_file(\n            double_it_non_deterministic_yml, project.project_root, \"functions\", \"double_it.yml\"\n        )\n        write_file(double_it_sql, project.project_root, \"functions\", \"double_it.sql\")\n        manifest = run_dbt([\"parse\", \"--no-partial-parse\"])\n        assert len(manifest.functions) == 1\n        assert \"function.test.double_it\" in manifest.functions\n        function_node = manifest.functions[\"function.test.double_it\"]\n        assert function_node.config.volatility == FunctionVolatility.NonDeterministic\n\n\nclass TestBasicPythonUDF(BasicUDFSetup):\n    @pytest.fixture(scope=\"class\")\n    def functions(self) -> Dict[str, str]:\n        return {\n            \"double_it.py\": double_it_py,\n            \"double_it.yml\": double_it_python_yml,\n        }\n\n    def test_basic_parsing(self, project):\n        # Simple parsing\n        manifest = run_dbt([\"parse\"])\n        assert len(manifest.functions) == 1\n        assert \"function.test.double_it\" in manifest.functions\n        function_node = manifest.functions[\"function.test.double_it\"]\n        assert isinstance(function_node, FunctionNode)\n        assert function_node.description == \"Doubles whatever number is passed in\"\n        assert function_node.language == \"python\"\n        assert function_node.config.type == FunctionType.Scalar\n        assert function_node.config.volatility is None\n        assert function_node.config.runtime_version == \"3.11\"\n        assert function_node.config.entry_point == \"entry\"\n        assert len(function_node.arguments) == 1\n        argument = function_node.arguments[0]\n        assert argument.name == \"value\"\n        assert argument.data_type == \"float\"\n        assert argument.description == \"A number to be doubled\"\n        assert function_node.returns == FunctionReturns(data_type=\"float\")\n\n        # Update with volatility specified in sql\n        write_file(double_it_deterministic_py, project.project_root, \"functions\", \"double_it.py\")\n        manifest = run_dbt([\"parse\", \"--no-partial-parse\"])\n        assert len(manifest.functions) == 1\n        assert \"function.test.double_it\" in manifest.functions\n        function_node = manifest.functions[\"function.test.double_it\"]\n        assert function_node.config.volatility == FunctionVolatility.Deterministic\n\n        # Update with volatility specified in yml\n        write_file(\n            double_it_non_deterministic_python_yml,\n            project.project_root,\n            \"functions\",\n            \"double_it.yml\",\n        )\n        write_file(double_it_py, project.project_root, \"functions\", \"double_it.py\")\n        manifest = run_dbt([\"parse\", \"--no-partial-parse\"])\n        assert len(manifest.functions) == 1\n        assert \"function.test.double_it\" in manifest.functions\n        function_node = manifest.functions[\"function.test.double_it\"]\n        assert function_node.config.volatility == FunctionVolatility.NonDeterministic\n\n\nclass TestCreationOfUDFs(BasicUDFSetup):\n    def test_can_create_udf(self, project):\n        results = run_dbt([\"build\"])\n        assert len(results) == 1\n\n        function_node = results[0].node\n        assert isinstance(function_node, FunctionNode)\n        assert function_node.name == \"double_it\"\n        assert function_node.description == \"Doubles whatever number is passed in\"\n\n        argument = function_node.arguments[0]\n        assert argument.name == \"value\"\n        assert argument.data_type == \"float\"\n        assert results[0].node.returns == FunctionReturns(data_type=\"float\")\n\n\nclass TestCanInlineShowUDF(BasicUDFSetup):\n    def test_can_inline_show_udf(self, project):\n        run_dbt([\"build\"])\n\n        result = run_dbt([\"show\", \"--inline\", \"select {{ function('double_it') }}(1)\"])\n        assert len(result.results) == 1\n        agate_table = result.results[0].agate_table\n        assert isinstance(agate_table, agate.Table)\n        assert agate_table.column_names == (\"double_it\",)\n        assert agate_table.rows == [(2.0,)]\n\n\nclass TestCanCallUDFInModel(BasicUDFSetup):\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"double_it_model.sql\": \"select {{ function('double_it') }}(1) as double_it\",\n        }\n\n    def test_can_call_udf_in_model(self, project):\n        run_dbt([\"build\"])\n\n        result = run_dbt([\"show\", \"--select\", \"double_it_model\"])\n        assert len(result.results) == 1\n        agate_table = result.results[0].agate_table\n        assert isinstance(agate_table, agate.Table)\n        assert agate_table.column_names == (\"double_it\",)\n        assert agate_table.rows == [(2.0,)]\n\n\nclass TestCanUseWithEmptyMode(BasicUDFSetup):\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"double_it_model.sql\": \"select {{ function('double_it') }}(1) as double_it\",\n        }\n\n    def test_can_use_with_empty_model(self, project):\n        run_dbt([\"build\", \"--empty\"])\n\n        result = run_dbt([\"show\", \"--select\", \"double_it_model\"])\n        assert len(result.results) == 1\n        agate_table = result.results[0].agate_table\n        assert isinstance(agate_table, agate.Table)\n        assert agate_table.column_names == (\"double_it\",)\n        assert agate_table.rows == [(2.0,)]\n\n\nclass TestCanUseRefInUDF:\n    @pytest.fixture(scope=\"class\")\n    def functions(self) -> Dict[str, str]:\n        return {\n            \"sum_numbers_function.sql\": sum_numbers_function_sql,\n            \"sum_numbers_function.yml\": sum_numbers_function_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self) -> Dict[str, str]:\n        return {\n            \"numbers_model.sql\": numbers_model_sql,\n        }\n\n    def test_can_use_ref_in_udf(self, project):\n        run_dbt([\"build\"])\n\n        result = run_dbt(\n            [\n                \"show\",\n                \"--inline\",\n                \"select {{ function('sum_numbers_function') }}() as summed_numbers\",\n            ]\n        )\n        assert len(result.results) == 1\n        agate_table = result.results[0].agate_table\n        assert isinstance(agate_table, agate.Table)\n        assert agate_table.column_names == (\"summed_numbers\",)\n        assert agate_table.rows == [(6,)]\n\n\nclass TestCanUseSourceInUDF:\n    @pytest.fixture(scope=\"class\")\n    def functions(self) -> Dict[str, str]:\n        return {\n            \"sum_numbers_function.sql\": sum_numbers_function_from_source_sql,\n            \"sum_numbers_function.yml\": sum_numbers_function_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self) -> Dict[str, str]:\n        return {\n            \"numbers_source.yml\": numbers_source_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self) -> Dict[str, str]:\n        return {\n            \"numbers_seed.csv\": numbers_seed_csv,\n        }\n\n    def test_can_use_ref_in_udf(self, project):\n        run_dbt([\"seed\"])\n        run_dbt([\"build\"])\n\n        result = run_dbt(\n            [\n                \"show\",\n                \"--inline\",\n                \"select {{ function('sum_numbers_function') }}() as summed_numbers\",\n            ]\n        )\n        assert len(result.results) == 1\n        agate_table = result.results[0].agate_table\n        assert isinstance(agate_table, agate.Table)\n        assert agate_table.column_names == (\"summed_numbers\",)\n        assert agate_table.rows == [(6,)]\n\n\nclass TestCanConfigFunctionsFromProjectConfig:\n    @pytest.fixture(scope=\"class\")\n    def functions(self) -> Dict[str, str]:\n        return {\n            \"double_it.sql\": double_it_sql,\n            \"double_it.yml\": double_it_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"functions\": {\"+volatility\": \"stable\"},\n        }\n\n    def test_can_config_functions_from_project_config(self, project):\n        manifest = run_dbt([\"parse\"])\n        assert len(manifest.functions) == 1\n        assert \"function.test.double_it\" in manifest.functions\n        function_node = manifest.functions[\"function.test.double_it\"]\n        assert function_node.config.volatility == FunctionVolatility.Stable\n\n        # Update with volatility specified in sql\n        write_file(double_it_deterministic_sql, project.project_root, \"functions\", \"double_it.sql\")\n        manifest = run_dbt([\"parse\", \"--no-partial-parse\"])\n        assert len(manifest.functions) == 1\n        assert \"function.test.double_it\" in manifest.functions\n        function_node = manifest.functions[\"function.test.double_it\"]\n        # Volatility from sql should take precedence over the project config\n        assert function_node.config.volatility == FunctionVolatility.Deterministic\n\n\nclass TestPythonFunctionWithoutJinjaHasEquivalentRawCodeAndCompiledCode:\n    @pytest.fixture(scope=\"class\")\n    def functions(self) -> Dict[str, str]:\n        return {\n            \"double_it.py\": double_it_py,\n            \"double_it.yml\": double_it_python_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self) -> Dict[str, str]:\n        return {\n            \"postgres__scalar_function_python.sql\": scalar_function_python_macro,\n        }\n\n    def test_udfs(self, project):\n        run_dbt([\"build\"])\n        result = run_dbt([\"compile\"])\n        assert len(result.results) == 1\n        node = result.results[0].node\n        assert isinstance(node, FunctionNode)\n        assert node.raw_code == node.compiled_code\n\n\nclass TestPythonFunctionWithJinjaHasCorrectCompiledCode:\n    @pytest.fixture(scope=\"class\")\n    def functions(self) -> Dict[str, str]:\n        return {\n            \"double_it.py\": double_it_py_with_jinja,\n            \"double_it.yml\": double_it_python_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self) -> Dict[str, str]:\n        return {\n            \"postgres__scalar_function_python.sql\": scalar_function_python_macro,\n        }\n\n    def test_udfs(self, project):\n        result = run_dbt([\"compile\"])\n        assert len(result.results) == 1\n        node = result.results[0].node\n        assert isinstance(node, FunctionNode)\n        assert node.compiled_code == \"def entry(value):\\n    \\n    return value * 2\\n    \"\n\n\nclass TestDefaultArgumentsBasic:\n    @pytest.fixture(scope=\"class\")\n    def functions(self) -> Dict[str, str]:\n        return {\n            \"sum_2_values.py\": sum_2_values_sql,\n            \"sum_2_values.yml\": sum_2_values_yml,\n        }\n\n    def test_udfs(self, project):\n        manifest = run_dbt([\"parse\"])\n        assert len(manifest.functions) == 1\n        function_node = manifest.functions[\"function.test.sum_2_values\"]\n        assert isinstance(function_node, FunctionNode)\n        assert len(function_node.arguments) == 2\n        assert function_node.arguments[0].default_value is None\n        assert function_node.arguments[1].default_value == 0\n\n\nclass TestDefaultArgumentsMustComeLast:\n    @pytest.fixture(scope=\"class\")\n    def functions(self) -> Dict[str, str]:\n        return {\n            \"sum_2_values.py\": sum_2_values_sql,\n            \"sum_2_values.yml\": sum_2_values_bad_default_arg_order_yml,\n        }\n\n    def test_udfs(self, project):\n        with pytest.raises(ParsingError) as excinfo:\n            run_dbt([\"parse\"])\n        assert (\n            \"Non-defaulted argument 'val2' of function 'sum_2_values' comes after a defaulted argument. Non-defaulted arguments cannot come after defaulted arguments. \"\n            in str(excinfo.value)\n        )\n\n\nclass TestFunctionsIncludeAndExcludeByResourceType:\n    @pytest.fixture(scope=\"class\")\n    def functions(self) -> Dict[str, str]:\n        return {\n            \"double_it.sql\": double_it_sql,\n            \"double_it.yml\": double_it_yml,\n        }\n\n    def test_udfs(self, project):\n        result = run_dbt([\"build\", \"--resource-type\", \"function\"])\n        assert len(result.results) == 1\n        function_node = result.results[0].node\n        assert isinstance(function_node, FunctionNode)\n\n        result = run_dbt([\"build\", \"--exclude-resource-type\", \"function\"])\n        assert len(result.results) == 0\n\n\ndouble_it_py_with_packages = \"\"\"\n{{ config(packages=['scikit-learn', 'pandas==1.5.0']) }}\ndef entry(value):\n    return value * 2\n\"\"\"\n\ndouble_it_python_with_packages_yml = \"\"\"\nfunctions:\n  - name: double_it\n    description: Doubles whatever number is passed in\n    config:\n        runtime_version: \"3.11\"\n        entry_point: entry\n        packages:\n          - scikit-learn\n          - pandas==1.5.0\n    arguments:\n      - name: value\n        data_type: float\n        description: A number to be doubled\n    returns:\n      data_type: float\n\"\"\"\n\n\nclass TestPythonFunctionPackagesViaJinjaConfig:\n    @pytest.fixture(scope=\"class\")\n    def functions(self) -> Dict[str, str]:\n        return {\n            \"double_it.py\": double_it_py_with_packages,\n            \"double_it.yml\": double_it_python_yml,\n        }\n\n    def test_packages_set_via_jinja_config(self, project):\n        manifest = run_dbt([\"parse\"])\n        assert len(manifest.functions) == 1\n        function_node = manifest.functions[\"function.test.double_it\"]\n        assert isinstance(function_node, FunctionNode)\n        assert function_node.language == \"python\"\n        assert function_node.config.packages == [\"scikit-learn\", \"pandas==1.5.0\"]\n\n\nclass TestPythonFunctionPackagesViaYamlConfig:\n    @pytest.fixture(scope=\"class\")\n    def functions(self) -> Dict[str, str]:\n        return {\n            \"double_it.py\": double_it_py,\n            \"double_it.yml\": double_it_python_with_packages_yml,\n        }\n\n    def test_packages_set_via_yaml_config(self, project):\n        manifest = run_dbt([\"parse\"])\n        assert len(manifest.functions) == 1\n        function_node = manifest.functions[\"function.test.double_it\"]\n        assert isinstance(function_node, FunctionNode)\n        assert function_node.language == \"python\"\n        assert function_node.config.packages == [\"scikit-learn\", \"pandas==1.5.0\"]\n\n\nclass TestPythonFunctionPackagesViaProjectConfig:\n    @pytest.fixture(scope=\"class\")\n    def functions(self) -> Dict[str, str]:\n        return {\n            \"double_it.py\": double_it_py,\n            \"double_it.yml\": double_it_python_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"functions\": {\"+packages\": [\"scikit-learn\"]},\n        }\n\n    def test_packages_set_via_project_config(self, project):\n        manifest = run_dbt([\"parse\"])\n        assert len(manifest.functions) == 1\n        function_node = manifest.functions[\"function.test.double_it\"]\n        assert isinstance(function_node, FunctionNode)\n        assert function_node.language == \"python\"\n        assert function_node.config.packages == [\"scikit-learn\"]\n\n\nclass TestFunctionsGetSchemaCreatedIfNecessary:\n    @pytest.fixture(scope=\"class\")\n    def functions(self) -> Dict[str, str]:\n        return {\n            \"double_it.sql\": double_it_sql,\n            \"double_it.yml\": double_it_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"functions\": {\"+schema\": \"{{ 'alt_function_schema_' ~ target.schema }}\"},\n        }\n\n    def test_functions_get_schema_created_if_necessary(self, project):\n        # previously an error occurred because the function schema wasn't guaranteed to be created.\n        # so it just not erroring out is a good indicator that that's been fixed\n        result = run_dbt([\"build\", \"--debug\"])\n\n        # some additional saqnity validations\n        assert len(result.results) == 1\n        function_node = result.results[0].node\n        assert isinstance(function_node, FunctionNode)\n        assert \"alt_function_schema_\" in function_node.schema\n"
  },
  {
    "path": "tests/functional/generic_test_description/fixtures.py",
    "content": "models__my_model_sql = \"\"\"\nwith my_cte as (\n    select 1 as id, 'blue' as color\n    union all\n    select 2 as id, 'green' as red\n    union all\n    select 3 as id, 'red' as red\n)\nselect * from my_cte\n\"\"\"\n\nmodels__schema_yml = \"\"\"\nmodels:\n  - name: my_model\n    columns:\n      - name: id\n        tests:\n          - unique:\n              description: \"id must be unique\"\n          - not_null\n      - name: color\n        tests:\n          - accepted_values:\n              values: ['blue', 'green', 'red']\n              description: \"{{ doc('color_accepted_values') }}\"\n\"\"\"\n\nmodels__doc_block_md = \"\"\"\n{% docs color_accepted_values %}\n\nThe `color` column must be one of 'blue', 'green', or 'red'.\n\n{% enddocs %}\n\"\"\"\n"
  },
  {
    "path": "tests/functional/generic_test_description/test_generic_test_description.py",
    "content": "import pytest\n\nfrom dbt.tests.util import get_artifact, run_dbt\nfrom tests.functional.generic_test_description.fixtures import (\n    models__doc_block_md,\n    models__my_model_sql,\n    models__schema_yml,\n)\n\n\nclass TestBuiltinGenericTestDescription:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": models__my_model_sql,\n            \"schema.yml\": models__schema_yml,\n            \"doc_block.md\": models__doc_block_md,\n        }\n\n    def test_compile(self, project):\n        run_dbt([\"compile\"])\n        manifest = get_artifact(project.project_root, \"target\", \"manifest.json\")\n        assert len(manifest[\"nodes\"]) == 4\n\n        nodes = {node[\"alias\"]: node for node in manifest[\"nodes\"].values()}\n\n        assert nodes[\"unique_my_model_id\"][\"description\"] == \"id must be unique\"\n        assert nodes[\"not_null_my_model_id\"][\"description\"] == \"\"\n        assert (\n            nodes[\"accepted_values_my_model_color__blue__green__red\"][\"description\"]\n            == \"The `color` column must be one of 'blue', 'green', or 'red'.\"\n        )\n"
  },
  {
    "path": "tests/functional/graph_selection/data/seed.csv",
    "content": "id,first_name,last_name,email,gender,ip_address,updated_at\n1,Jack,Hunter,jhunter0@pbs.org,Male,59.80.20.168,2015-12-24 12:19:28\n2,Kathryn,Walker,kwalker1@ezinearticles.com,Female,194.121.179.35,2015-12-24 12:19:28\n3,Gerald,Ryan,gryan2@com.com,Male,11.3.212.243,2015-12-24 12:19:28\n4,Bonnie,Spencer,bspencer3@ameblo.jp,Female,216.32.196.175,2015-12-24 12:19:28\n5,Harold,Taylor,htaylor4@people.com.cn,Male,253.10.246.136,2015-12-24 12:19:28\n6,Jacqueline,Griffin,jgriffin5@t.co,Female,16.13.192.220,2015-12-24 12:19:28\n7,Wanda,Arnold,warnold6@google.nl,Female,232.116.150.64,2015-12-24 12:19:28\n8,Craig,Ortiz,cortiz7@sciencedaily.com,Male,199.126.106.13,2015-12-24 12:19:28\n9,Gary,Day,gday8@nih.gov,Male,35.81.68.186,2015-12-24 12:19:28\n10,Rose,Wright,rwright9@yahoo.co.jp,Female,236.82.178.100,2015-12-24 12:19:28\n11,Raymond,Kelley,rkelleya@fc2.com,Male,213.65.166.67,2015-12-24 12:19:28\n12,Gerald,Robinson,grobinsonb@disqus.com,Male,72.232.194.193,2015-12-24 12:19:28\n13,Mildred,Martinez,mmartinezc@samsung.com,Female,198.29.112.5,2015-12-24 12:19:28\n14,Dennis,Arnold,darnoldd@google.com,Male,86.96.3.250,2015-12-24 12:19:28\n15,Judy,Gray,jgraye@opensource.org,Female,79.218.162.245,2015-12-24 12:19:28\n16,Theresa,Garza,tgarzaf@epa.gov,Female,21.59.100.54,2015-12-24 12:19:28\n17,Gerald,Robertson,grobertsong@csmonitor.com,Male,131.134.82.96,2015-12-24 12:19:28\n18,Philip,Hernandez,phernandezh@adobe.com,Male,254.196.137.72,2015-12-24 12:19:28\n19,Julia,Gonzalez,jgonzalezi@cam.ac.uk,Female,84.240.227.174,2015-12-24 12:19:28\n20,Andrew,Davis,adavisj@patch.com,Male,9.255.67.25,2015-12-24 12:19:28\n21,Kimberly,Harper,kharperk@foxnews.com,Female,198.208.120.253,2015-12-24 12:19:28\n22,Mark,Martin,mmartinl@marketwatch.com,Male,233.138.182.153,2015-12-24 12:19:28\n23,Cynthia,Ruiz,cruizm@google.fr,Female,18.178.187.201,2015-12-24 12:19:28\n24,Samuel,Carroll,scarrolln@youtu.be,Male,128.113.96.122,2015-12-24 12:19:28\n25,Jennifer,Larson,jlarsono@vinaora.com,Female,98.234.85.95,2015-12-24 12:19:28\n26,Ashley,Perry,aperryp@rakuten.co.jp,Female,247.173.114.52,2015-12-24 12:19:28\n27,Howard,Rodriguez,hrodriguezq@shutterfly.com,Male,231.188.95.26,2015-12-24 12:19:28\n28,Amy,Brooks,abrooksr@theatlantic.com,Female,141.199.174.118,2015-12-24 12:19:28\n29,Louise,Warren,lwarrens@adobe.com,Female,96.105.158.28,2015-12-24 12:19:28\n30,Tina,Watson,twatsont@myspace.com,Female,251.142.118.177,2015-12-24 12:19:28\n31,Janice,Kelley,jkelleyu@creativecommons.org,Female,239.167.34.233,2015-12-24 12:19:28\n32,Terry,Mccoy,tmccoyv@bravesites.com,Male,117.201.183.203,2015-12-24 12:19:28\n33,Jeffrey,Morgan,jmorganw@surveymonkey.com,Male,78.101.78.149,2015-12-24 12:19:28\n34,Louis,Harvey,lharveyx@sina.com.cn,Male,51.50.0.167,2015-12-24 12:19:28\n35,Philip,Miller,pmillery@samsung.com,Male,103.255.222.110,2015-12-24 12:19:28\n36,Willie,Marshall,wmarshallz@ow.ly,Male,149.219.91.68,2015-12-24 12:19:28\n37,Patrick,Lopez,plopez10@redcross.org,Male,250.136.229.89,2015-12-24 12:19:28\n38,Adam,Jenkins,ajenkins11@harvard.edu,Male,7.36.112.81,2015-12-24 12:19:28\n39,Benjamin,Cruz,bcruz12@linkedin.com,Male,32.38.98.15,2015-12-24 12:19:28\n40,Ruby,Hawkins,rhawkins13@gmpg.org,Female,135.171.129.255,2015-12-24 12:19:28\n41,Carlos,Barnes,cbarnes14@a8.net,Male,240.197.85.140,2015-12-24 12:19:28\n42,Ruby,Griffin,rgriffin15@bravesites.com,Female,19.29.135.24,2015-12-24 12:19:28\n43,Sean,Mason,smason16@icq.com,Male,159.219.155.249,2015-12-24 12:19:28\n44,Anthony,Payne,apayne17@utexas.edu,Male,235.168.199.218,2015-12-24 12:19:28\n45,Steve,Cruz,scruz18@pcworld.com,Male,238.201.81.198,2015-12-24 12:19:28\n46,Anthony,Garcia,agarcia19@flavors.me,Male,25.85.10.18,2015-12-24 12:19:28\n47,Doris,Lopez,dlopez1a@sphinn.com,Female,245.218.51.238,2015-12-24 12:19:28\n48,Susan,Nichols,snichols1b@freewebs.com,Female,199.99.9.61,2015-12-24 12:19:28\n49,Wanda,Ferguson,wferguson1c@yahoo.co.jp,Female,236.241.135.21,2015-12-24 12:19:28\n50,Andrea,Pierce,apierce1d@google.co.uk,Female,132.40.10.209,2015-12-24 12:19:28\n51,Lawrence,Phillips,lphillips1e@jugem.jp,Male,72.226.82.87,2015-12-24 12:19:28\n52,Judy,Gilbert,jgilbert1f@multiply.com,Female,196.250.15.142,2015-12-24 12:19:28\n53,Eric,Williams,ewilliams1g@joomla.org,Male,222.202.73.126,2015-12-24 12:19:28\n54,Ralph,Romero,rromero1h@sogou.com,Male,123.184.125.212,2015-12-24 12:19:28\n55,Jean,Wilson,jwilson1i@ocn.ne.jp,Female,176.106.32.194,2015-12-24 12:19:28\n56,Lori,Reynolds,lreynolds1j@illinois.edu,Female,114.181.203.22,2015-12-24 12:19:28\n57,Donald,Moreno,dmoreno1k@bbc.co.uk,Male,233.249.97.60,2015-12-24 12:19:28\n58,Steven,Berry,sberry1l@eepurl.com,Male,186.193.50.50,2015-12-24 12:19:28\n59,Theresa,Shaw,tshaw1m@people.com.cn,Female,120.37.71.222,2015-12-24 12:19:28\n60,John,Stephens,jstephens1n@nationalgeographic.com,Male,191.87.127.115,2015-12-24 12:19:28\n61,Richard,Jacobs,rjacobs1o@state.tx.us,Male,66.210.83.155,2015-12-24 12:19:28\n62,Andrew,Lawson,alawson1p@over-blog.com,Male,54.98.36.94,2015-12-24 12:19:28\n63,Peter,Morgan,pmorgan1q@rambler.ru,Male,14.77.29.106,2015-12-24 12:19:28\n64,Nicole,Garrett,ngarrett1r@zimbio.com,Female,21.127.74.68,2015-12-24 12:19:28\n65,Joshua,Kim,jkim1s@edublogs.org,Male,57.255.207.41,2015-12-24 12:19:28\n66,Ralph,Roberts,rroberts1t@people.com.cn,Male,222.143.131.109,2015-12-24 12:19:28\n67,George,Montgomery,gmontgomery1u@smugmug.com,Male,76.75.111.77,2015-12-24 12:19:28\n68,Gerald,Alvarez,galvarez1v@flavors.me,Male,58.157.186.194,2015-12-24 12:19:28\n69,Donald,Olson,dolson1w@whitehouse.gov,Male,69.65.74.135,2015-12-24 12:19:28\n70,Carlos,Morgan,cmorgan1x@pbs.org,Male,96.20.140.87,2015-12-24 12:19:28\n71,Aaron,Stanley,astanley1y@webnode.com,Male,163.119.217.44,2015-12-24 12:19:28\n72,Virginia,Long,vlong1z@spiegel.de,Female,204.150.194.182,2015-12-24 12:19:28\n73,Robert,Berry,rberry20@tripadvisor.com,Male,104.19.48.241,2015-12-24 12:19:28\n74,Antonio,Brooks,abrooks21@unesco.org,Male,210.31.7.24,2015-12-24 12:19:28\n75,Ruby,Garcia,rgarcia22@ovh.net,Female,233.218.162.214,2015-12-24 12:19:28\n76,Jack,Hanson,jhanson23@blogtalkradio.com,Male,31.55.46.199,2015-12-24 12:19:28\n77,Kathryn,Nelson,knelson24@walmart.com,Female,14.189.146.41,2015-12-24 12:19:28\n78,Jason,Reed,jreed25@printfriendly.com,Male,141.189.89.255,2015-12-24 12:19:28\n79,George,Coleman,gcoleman26@people.com.cn,Male,81.189.221.144,2015-12-24 12:19:28\n80,Rose,King,rking27@ucoz.com,Female,212.123.168.231,2015-12-24 12:19:28\n81,Johnny,Holmes,jholmes28@boston.com,Male,177.3.93.188,2015-12-24 12:19:28\n82,Katherine,Gilbert,kgilbert29@altervista.org,Female,199.215.169.61,2015-12-24 12:19:28\n83,Joshua,Thomas,jthomas2a@ustream.tv,Male,0.8.205.30,2015-12-24 12:19:28\n84,Julie,Perry,jperry2b@opensource.org,Female,60.116.114.192,2015-12-24 12:19:28\n85,Richard,Perry,rperry2c@oracle.com,Male,181.125.70.232,2015-12-24 12:19:28\n86,Kenneth,Ruiz,kruiz2d@wikimedia.org,Male,189.105.137.109,2015-12-24 12:19:28\n87,Jose,Morgan,jmorgan2e@webnode.com,Male,101.134.215.156,2015-12-24 12:19:28\n88,Donald,Campbell,dcampbell2f@goo.ne.jp,Male,102.120.215.84,2015-12-24 12:19:28\n89,Debra,Collins,dcollins2g@uol.com.br,Female,90.13.153.235,2015-12-24 12:19:28\n90,Jesse,Johnson,jjohnson2h@stumbleupon.com,Male,225.178.125.53,2015-12-24 12:19:28\n91,Elizabeth,Stone,estone2i@histats.com,Female,123.184.126.221,2015-12-24 12:19:28\n92,Angela,Rogers,arogers2j@goodreads.com,Female,98.104.132.187,2015-12-24 12:19:28\n93,Emily,Dixon,edixon2k@mlb.com,Female,39.190.75.57,2015-12-24 12:19:28\n94,Albert,Scott,ascott2l@tinypic.com,Male,40.209.13.189,2015-12-24 12:19:28\n95,Barbara,Peterson,bpeterson2m@ow.ly,Female,75.249.136.180,2015-12-24 12:19:28\n96,Adam,Greene,agreene2n@fastcompany.com,Male,184.173.109.144,2015-12-24 12:19:28\n97,Earl,Sanders,esanders2o@hc360.com,Male,247.34.90.117,2015-12-24 12:19:28\n98,Angela,Brooks,abrooks2p@mtv.com,Female,10.63.249.126,2015-12-24 12:19:28\n99,Harold,Foster,hfoster2q@privacy.gov.au,Male,139.214.40.244,2015-12-24 12:19:28\n100,Carl,Meyer,cmeyer2r@disqus.com,Male,204.117.7.88,2015-12-24 12:19:28\n"
  },
  {
    "path": "tests/functional/graph_selection/data/summary_expected.csv",
    "content": "gender,ct\nFemale,40\nMale,60\n"
  },
  {
    "path": "tests/functional/graph_selection/fixtures.py",
    "content": "import pytest\n\nfrom dbt.tests.util import read_file\n\nschema_yml = \"\"\"\nversion: 2\n\ngroups:\n  - name: emails_group\n    owner:\n      name: Jeremy\n      email: data@jer.co\n      slack: talk-jerco-memes\n      github: jtcohen6\n      whatever: you want\n  - name: users_group\n    owner:\n      name: Jeremy\n      email: data@jer.co\n      slack: talk-jerco-memes\n      github: jtcohen6\n      whatever: you want\n  - name: users_rollup_group\n    owner:\n      name: Jeremy\n      email: data@jer.co\n      slack: talk-jerco-memes\n      github: jtcohen6\n      whatever: you want\n\nmodels:\n  - name: emails\n    group: emails_group\n    columns:\n    - name: email\n      data_tests:\n      - not_null:\n          severity: warn\n  - name: users\n    group: users_group\n    columns:\n    - name: id\n      data_tests:\n      - unique\n  - name: users_rollup\n    group: users_rollup_group\n    columns:\n    - name: gender\n      data_tests:\n      - unique\n  - name: versioned\n    latest_version: 2\n    versions:\n      - v: 0\n      - v: 1\n      - v: 2\n      - v: 3\n      - v: 4.5\n      - v: \"5.0\"\n      - v: 21\n      - v: \"test\"\n\nsources:\n  - name: raw\n    schema: '{{ target.schema }}'\n    tables:\n      - name: seed\n\nexposures:\n  - name: user_exposure\n    type: dashboard\n    depends_on:\n      - ref('users')\n      - ref('users_rollup')\n      - ref('versioned', v=3)\n    owner:\n      email: nope@example.com\n  - name: seed_ml_exposure\n    type: ml\n    depends_on:\n      - source('raw', 'seed')\n    owner:\n      email: nope@example.com\n\"\"\"\n\npatch_path_selection_schema_yml = \"\"\"\nversion: 2\n\nmodels:\n  - name: subdir\n    description: submarine sandwich directory\n\n\"\"\"\n\nbase_users_sql = \"\"\"\n\n{{\n    config(\n        materialized = 'ephemeral',\n        tags = ['base']\n    )\n}}\n\nselect * from {{ source('raw', 'seed') }}\n\"\"\"\n\nusers_sql = \"\"\"\n\n{{\n    config(\n        materialized = 'table',\n        tags=['bi', 'users']\n    )\n}}\n\nselect * from {{ ref('base_users') }}\n\"\"\"\n\nusers_rollup_sql = \"\"\"\n\n{{\n    config(\n        materialized = 'view',\n        tags = 'bi'\n    )\n}}\n\nwith users as (\n\n    select * from {{ ref('users') }}\n\n)\n\nselect\n    gender,\n    count(*) as ct\nfrom users\ngroup by 1\n\"\"\"\n\nusers_rollup_dependency_sql = \"\"\"\n{{\n  config(materialized='table')\n}}\n\nselect * from {{ ref('users_rollup') }}\n\"\"\"\n\nemails_sql = \"\"\"\n\n{{\n    config(materialized='ephemeral', tags=['base'])\n}}\n\nselect distinct email from {{ ref('base_users') }}\n\"\"\"\n\nemails_alt_sql = \"\"\"\nselect distinct email from {{ ref('users') }}\n\"\"\"\n\nalternative_users_sql = \"\"\"\n{# Same as ´users´ model, but with dots in the model name #}\n{{\n    config(\n        materialized = 'table',\n        tags=['dots']\n    )\n}}\n\nselect * from {{ ref('base_users') }}\n\"\"\"\n\nnever_selected_sql = \"\"\"\n{{\n  config(schema='_and_then')\n}}\n\nselect * from {{ this.schema }}.seed\n\"\"\"\n\nsubdir_sql = \"\"\"\nselect 1 as id\n\"\"\"\n\nnested_users_sql = \"\"\"\nselect 1 as id\n\"\"\"\n\nproperties_yml = \"\"\"\nversion: 2\nseeds:\n  - name: summary_expected\n    config:\n      column_types:\n        ct: BIGINT\n        gender: text\n\"\"\"\n\n\nclass SelectionFixtures:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": schema_yml,\n            \"patch_path_selection_schema.yml\": patch_path_selection_schema_yml,\n            \"base_users.sql\": base_users_sql,\n            \"users.sql\": users_sql,\n            \"versioned_v3.sql\": base_users_sql,\n            \"users_rollup.sql\": users_rollup_sql,\n            \"users_rollup_dependency.sql\": users_rollup_dependency_sql,\n            \"emails.sql\": emails_sql,\n            \"emails_alt.sql\": emails_alt_sql,\n            \"alternative.users.sql\": alternative_users_sql,\n            \"never_selected.sql\": never_selected_sql,\n            \"test\": {\n                \"subdir.sql\": subdir_sql,\n                \"versioned_v2.sql\": subdir_sql,\n                \"subdir\": {\n                    \"nested_users.sql\": nested_users_sql,\n                    \"versioned_v1.sql\": nested_users_sql,\n                },\n            },\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self, test_data_dir):\n        # Read seed file and return\n        seeds = {\"properties.yml\": properties_yml}\n        for seed_file in [\"seed.csv\", \"summary_expected.csv\"]:\n            seeds[seed_file] = read_file(test_data_dir, seed_file)\n        return seeds\n"
  },
  {
    "path": "tests/functional/graph_selection/test_graph_selection.py",
    "content": "import json\nimport os\n\nimport pytest\n\nfrom dbt.tests.util import check_result_nodes_by_name, run_dbt\nfrom tests.functional.graph_selection.fixtures import SelectionFixtures\n\nselectors_yml = \"\"\"\n            selectors:\n            - name: bi_selector\n              description: This is a BI selector\n              definition:\n                method: tag\n                value: bi\n        \"\"\"\n\n\ndef assert_correct_schemas(project):\n    adapter = project.adapter\n    with adapter.connection_named(\"__test\"):\n        exists = adapter.check_schema_exists(project.database, project.test_schema)\n        assert exists\n\n        schema = project.test_schema + \"_and_then\"\n        exists = adapter.check_schema_exists(project.database, schema)\n        assert not exists\n\n\ndef clear_schema(project):\n    project.run_sql(\"drop schema if exists {schema} cascade\")\n    project.run_sql(\"create schema {schema}\")\n\n\nclass TestGraphSelection(SelectionFixtures):\n    # The tests here aiming to test whether the correct node is selected,\n    # we don't need the run to pass\n    @pytest.fixture(scope=\"class\")\n    def selectors(self):\n        return selectors_yml\n\n    def test_specific_model(self, project):\n        results = run_dbt([\"run\", \"--select\", \"users\"], expect_pass=False)\n        check_result_nodes_by_name(results, [\"users\"])\n        assert_correct_schemas(project)\n\n    def test_tags(self, project, project_root):\n        results = run_dbt([\"run\", \"--selector\", \"bi_selector\"], expect_pass=False)\n        check_result_nodes_by_name(results, [\"users\", \"users_rollup\"])\n        assert_correct_schemas(project)\n        manifest_path = project_root.join(\"target/manifest.json\")\n        assert os.path.exists(manifest_path)\n        with open(manifest_path) as fp:\n            manifest = json.load(fp)\n            assert \"selectors\" in manifest\n\n    def test_tags_and_children(self, project):\n        results = run_dbt([\"run\", \"--select\", \"tag:base+\"], expect_pass=False)\n        check_result_nodes_by_name(\n            results,\n            [\n                \"emails_alt\",\n                \"users_rollup\",\n                \"users\",\n                \"alternative.users\",\n                \"users_rollup_dependency\",\n            ],\n        )\n        assert_correct_schemas(project)\n\n    def test_tags_and_children_limited(self, project):\n        results = run_dbt([\"run\", \"--select\", \"tag:base+2\"], expect_pass=False)\n        check_result_nodes_by_name(\n            results, [\"emails_alt\", \"users_rollup\", \"users\", \"alternative.users\"]\n        )\n        assert_correct_schemas(project)\n\n    def test_group(self, project):\n        expected = [\"test.unique_users_id\", \"test.users\"]\n        results = run_dbt([\"ls\", \"--select\", \"group:users_group\"])\n        assert sorted(results) == expected\n\n    def test_specific_model_and_children(self, project):\n        results = run_dbt([\"run\", \"--select\", \"users+\"], expect_pass=False)\n        check_result_nodes_by_name(\n            results, [\"users\", \"users_rollup\", \"emails_alt\", \"users_rollup_dependency\"]\n        )\n        assert_correct_schemas(project)\n\n    def test_specific_model_and_children_limited(self, project):\n        results = run_dbt([\"run\", \"--select\", \"users+1\"], expect_pass=False)\n        check_result_nodes_by_name(results, [\"users\", \"users_rollup\", \"emails_alt\"])\n        assert_correct_schemas(project)\n\n    def test_specific_model_and_parents(self, project):\n        results = run_dbt([\"run\", \"--select\", \"+users_rollup\"], expect_pass=False)\n        check_result_nodes_by_name(results, [\"users_rollup\", \"users\"])\n        assert_correct_schemas(project)\n\n    def test_specific_model_and_parents_limited(self, project):\n        results = run_dbt([\"run\", \"--select\", \"1+users_rollup\"], expect_pass=False)\n        check_result_nodes_by_name(results, [\"users\", \"users_rollup\"])\n        assert_correct_schemas(project)\n\n    def test_specific_model_with_exclusion(self, project):\n        results = run_dbt(\n            [\n                \"run\",\n                \"--select\",\n                \"+users_rollup\",\n                \"--exclude\",\n                \"models/users_rollup.sql\",\n            ],\n            expect_pass=False,\n        )\n        check_result_nodes_by_name(results, [\"users\"])\n        assert_correct_schemas(project)\n\n    def test_locally_qualified_name(self, project):\n        results = run_dbt([\"run\", \"--select\", \"test.subdir\"])\n        check_result_nodes_by_name(results, [\"nested_users\", \"subdir\", \"versioned\"])\n        assert_correct_schemas(project)\n\n        os.chdir(\n            project.profiles_dir\n        )  # Change to random directory to test that Path selector works with project-dir\n        results = run_dbt(\n            [\"run\", \"--project-dir\", str(project.project_root), \"--select\", \"models/test/subdir*\"]\n        )\n        check_result_nodes_by_name(results, [\"nested_users\", \"subdir\", \"versioned\"])\n        assert_correct_schemas(project)\n\n        results = run_dbt(\n            [\n                \"build\",\n                \"--project-dir\",\n                str(project.project_root),\n                \"--select\",\n                \"models/patch_path_selection_schema.yml\",\n            ]\n        )\n        check_result_nodes_by_name(results, [\"subdir\"])\n        assert_correct_schemas(project)\n\n        # Check that list command works\n        os.chdir(\n            project.profiles_dir\n        )  # Change to random directory to test that Path selector works with project-dir\n        results = run_dbt(\n            [\n                \"-q\",\n                \"ls\",\n                \"-s\",\n                \"path:models/test/subdir.sql\",\n                \"--project-dir\",\n                str(project.project_root),\n            ]\n            #           [\"list\", \"--project-dir\", str(project.project_root), \"--select\", \"models/test/subdir*\"]\n        )\n        assert len(results) == 1\n\n    def test_locally_qualified_name_model_with_dots(self, project):\n        results = run_dbt([\"run\", \"--select\", \"alternative.users\"], expect_pass=False)\n        check_result_nodes_by_name(results, [\"alternative.users\"])\n        assert_correct_schemas(project)\n\n        results = run_dbt([\"run\", \"--select\", \"models/alternative.*\"], expect_pass=False)\n        check_result_nodes_by_name(results, [\"alternative.users\"])\n        assert_correct_schemas(project)\n\n    def test_childrens_parents(self, project):\n        results = run_dbt([\"run\", \"--select\", \"@base_users\"], expect_pass=False)\n        check_result_nodes_by_name(\n            results,\n            [\n                \"alternative.users\",\n                \"users_rollup\",\n                \"users\",\n                \"emails_alt\",\n                \"users_rollup_dependency\",\n            ],\n        )\n\n        results = run_dbt([\"test\", \"--select\", \"test_name:not_null\"], expect_pass=False)\n        check_result_nodes_by_name(results, [\"not_null_emails_email\"])\n\n    def test_more_childrens_parents(self, project):\n        results = run_dbt([\"run\", \"--select\", \"@users\"], expect_pass=False)\n        check_result_nodes_by_name(\n            results, [\"users_rollup\", \"users\", \"emails_alt\", \"users_rollup_dependency\"]\n        )\n\n        results = run_dbt([\"test\", \"--select\", \"test_name:unique\"], expect_pass=False)\n        check_result_nodes_by_name(results, [\"unique_users_id\", \"unique_users_rollup_gender\"])\n\n    def test_concat(self, project):\n        results = run_dbt([\"run\", \"--select\", \"@emails_alt\", \"users_rollup\"], expect_pass=False)\n        check_result_nodes_by_name(results, [\"users_rollup\", \"users\", \"emails_alt\"])\n\n    def test_concat_multiple(self, project):\n        results = run_dbt(\n            [\"run\", \"--select\", \"@emails_alt\", \"--select\", \"users_rollup\"], expect_pass=False\n        )\n        check_result_nodes_by_name(results, [\"users_rollup\", \"users\", \"emails_alt\"])\n\n    def test_concat_exclude(self, project):\n        results = run_dbt(\n            [\n                \"run\",\n                \"--select\",\n                \"@emails_alt\",\n                \"users_rollup\",\n                \"--exclude\",\n                \"emails_alt\",\n            ],\n            expect_pass=False,\n        )\n        check_result_nodes_by_name(results, [\"users_rollup\", \"users\"])\n\n    def test_concat_exclude_multiple(self, project):\n        results = run_dbt(\n            [\n                \"run\",\n                \"--select\",\n                \"@emails_alt\",\n                \"users_rollup\",\n                \"--exclude\",\n                \"users\",\n                \"--exclude\",\n                \"emails_alt\",\n            ],\n            expect_pass=False,\n        )\n        check_result_nodes_by_name(results, [\"users_rollup\"])\n\n    def test_concat_exclude_concat(self, project):\n        results = run_dbt(\n            [\n                \"run\",\n                \"--select\",\n                \"@emails_alt\",\n                \"users_rollup\",\n                \"--exclude\",\n                \"emails_alt\",\n                \"users_rollup\",\n            ],\n            expect_pass=False,\n        )\n        check_result_nodes_by_name(results, [\"users\"])\n\n        results = run_dbt(\n            [\n                \"test\",\n                \"--select\",\n                \"@emails_alt\",\n                \"users_rollup\",\n                \"--exclude\",\n                \"emails_alt\",\n                \"users_rollup\",\n            ],\n            expect_pass=False,\n        )\n        check_result_nodes_by_name(results, [\"unique_users_id\"])\n\n    def test_exposure_parents(self, project):\n        results = run_dbt([\"ls\", \"--select\", \"+exposure:seed_ml_exposure\"])\n        assert sorted(results) == [\n            \"exposure:test.seed_ml_exposure\",\n            \"source:test.raw.seed\",\n        ]\n        results = run_dbt([\"ls\", \"--select\", \"1+exposure:user_exposure\"])\n        assert sorted(results) == [\n            \"exposure:test.user_exposure\",\n            \"test.unique_users_id\",\n            \"test.unique_users_rollup_gender\",\n            \"test.users\",\n            \"test.users_rollup\",\n            \"test.versioned.v3\",\n        ]\n        results = run_dbt([\"run\", \"-m\", \"+exposure:user_exposure\"], expect_pass=False)\n        check_result_nodes_by_name(\n            results,\n            [\n                \"users_rollup\",\n                \"users\",\n            ],\n        )\n\n\nclass TestListPathGraphSelection(SelectionFixtures):\n    def test_list_select_with_project_dir(self, project):\n        # Check that list command works\n        os.chdir(\n            project.profiles_dir\n        )  # Change to random directory to test that Path selector works with project-dir\n        results = run_dbt(\n            [\n                \"-q\",\n                \"ls\",\n                \"-s\",\n                \"path:models/test/subdir.sql\",\n                \"--project-dir\",\n                str(project.project_root),\n            ]\n        )\n        assert results == [\"test.test.subdir\"]\n"
  },
  {
    "path": "tests/functional/graph_selection/test_group_selection.py",
    "content": "import pytest\n\nfrom dbt.tests.util import read_file, run_dbt\nfrom tests.functional.graph_selection.fixtures import (\n    alternative_users_sql,\n    base_users_sql,\n    emails_alt_sql,\n    emails_sql,\n    nested_users_sql,\n    never_selected_sql,\n    properties_yml,\n    schema_yml,\n    subdir_sql,\n    users_rollup_dependency_sql,\n    users_rollup_sql,\n    users_sql,\n)\n\nselectors_yml = \"\"\"\n            selectors:\n              - name: group_specified_as_string_str\n                definition: group:users_group\n              - name: group_specified_as_string_dict\n                definition:\n                  method: group\n                  value: users_group\n              - name: users_grouped_childrens_parents\n                definition:\n                  method: group\n                  value: users_group\n                  childrens_parents: true\n\"\"\"\n\n\nclass TestGroupSelection:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": schema_yml,\n            \"base_users.sql\": base_users_sql,\n            \"users.sql\": users_sql,\n            \"users_rollup.sql\": users_rollup_sql,\n            \"versioned_v3.sql\": base_users_sql,\n            \"users_rollup_dependency.sql\": users_rollup_dependency_sql,\n            \"emails.sql\": emails_sql,\n            \"emails_alt.sql\": emails_alt_sql,\n            \"alternative.users.sql\": alternative_users_sql,\n            \"never_selected.sql\": never_selected_sql,\n            \"test\": {\n                \"subdir.sql\": subdir_sql,\n                \"subdir\": {\"nested_users.sql\": nested_users_sql},\n            },\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self, test_data_dir):\n        # Read seed file and return\n        seeds = {\"properties.yml\": properties_yml}\n        for seed_file in [\"seed.csv\", \"summary_expected.csv\"]:\n            seeds[seed_file] = read_file(test_data_dir, seed_file)\n        return seeds\n\n    @pytest.fixture(scope=\"class\")\n    def selectors(self):\n        return selectors_yml\n\n    def test_select_models_by_group(self, project):\n        results = run_dbt([\"ls\", \"--model\", \"group:users_group\"])\n        assert sorted(results) == [\"test.users\"]\n\n    def test_select_group_selector_str(self, project):\n        results = run_dbt([\"ls\", \"--selector\", \"group_specified_as_string_str\"])\n        assert sorted(results) == [\"test.unique_users_id\", \"test.users\"]\n\n    def test_select_group_selector_dict(self, project):\n        results = run_dbt([\"ls\", \"--selector\", \"group_specified_as_string_dict\"])\n        assert sorted(results) == [\"test.unique_users_id\", \"test.users\"]\n\n    def test_select_models_by_group_and_children(self, project):  # noqa\n        results = run_dbt([\"ls\", \"--models\", \"+group:users_group+\"])\n        assert sorted(results) == [\n            \"test.base_users\",\n            \"test.emails_alt\",\n            \"test.users\",\n            \"test.users_rollup\",\n            \"test.users_rollup_dependency\",\n        ]\n\n    def test_select_group_and_children(self, project):  # noqa\n        expected = [\n            \"exposure:test.user_exposure\",\n            \"source:test.raw.seed\",\n            \"test.base_users\",\n            \"test.emails_alt\",\n            \"test.unique_users_id\",\n            \"test.unique_users_rollup_gender\",\n            \"test.users\",\n            \"test.users_rollup\",\n            \"test.users_rollup_dependency\",\n        ]\n        results = run_dbt([\"ls\", \"--select\", \"+group:users_group+\"])\n        assert sorted(results) == expected\n\n    def test_select_group_and_children_selector_str(self, project):  # noqa\n        expected = [\n            \"exposure:test.user_exposure\",\n            \"source:test.raw.seed\",\n            \"test.base_users\",\n            \"test.emails_alt\",\n            \"test.unique_users_id\",\n            \"test.unique_users_rollup_gender\",\n            \"test.users\",\n            \"test.users_rollup\",\n            \"test.users_rollup_dependency\",\n            \"test.versioned.v3\",\n        ]\n        results = run_dbt([\"ls\", \"--selector\", \"users_grouped_childrens_parents\"])\n        assert sorted(results) == expected\n\n    # 2 groups\n    def test_select_models_two_groups(self, project):\n        expected = [\"test.base_users\", \"test.emails\", \"test.users\"]\n        results = run_dbt([\"ls\", \"--models\", \"@group:emails_group group:users_group\"])\n        assert sorted(results) == expected\n"
  },
  {
    "path": "tests/functional/graph_selection/test_inline.py",
    "content": "import pytest\n\nfrom dbt.cli.exceptions import DbtUsageException\nfrom dbt.tests.util import run_dbt, run_dbt_and_capture, write_file\n\nselectors_yml = \"\"\"\n    selectors:\n      - name: test_selector\n        description: Exclude everything\n        default: true\n        definition:\n           method: package\n           value: \"foo\"\n    \"\"\"\n\ndbt_project_yml = \"\"\"\nname: test\nprofile: test\nflags:\n  send_anonymous_usage_stats: false\n\"\"\"\n\ndbt_project_yml_disabled_models = \"\"\"\nname: test\nprofile: test\nflags:\n  send_anonymous_usage_stats: false\nmodels:\n  +enabled: false\n\"\"\"\n\n\nclass TestCompileInlineWithSelector:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"first_model.sql\": \"select 1 as id\",\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def selectors(self):\n        return selectors_yml\n\n    def test_inline_selectors(self, project):\n        (results, log_output) = run_dbt_and_capture(\n            [\"compile\", \"--inline\", \"select * from {{ ref('first_model') }}\"]\n        )\n        assert len(results) == 1\n        assert \"Compiled inline node is:\" in log_output\n\n        # Set all models to disabled, check that we still get inline result\n        write_file(dbt_project_yml_disabled_models, project.project_root, \"dbt_project.yml\")\n        (results, log_output) = run_dbt_and_capture([\"compile\", \"--inline\", \"select 1 as id\"])\n        assert len(results) == 1\n\n        # put back non-disabled dbt_project and check for mutually exclusive error message\n        # for --select and --inline\n        write_file(dbt_project_yml, project.project_root, \"dbt_project.yml\")\n        with pytest.raises(DbtUsageException):\n            run_dbt([\"compile\", \"--select\", \"first_model\", \"--inline\", \"select 1 as id\"])\n\n        # check for mutually exclusive --selector and --inline\n        with pytest.raises(DbtUsageException):\n            run_dbt([\"compile\", \"--selector\", \"test_selector\", \"--inline\", \"select 1 as id\"])\n"
  },
  {
    "path": "tests/functional/graph_selection/test_intersection_syntax.py",
    "content": "import pytest\n\nfrom dbt.tests.util import check_result_nodes_by_name, run_dbt\nfrom tests.functional.graph_selection.fixtures import SelectionFixtures\n\nselectors_yml = \"\"\"\n            selectors:\n            - name: same_intersection\n              definition:\n                intersection:\n                  - fqn: users\n                  - fqn: users\n            - name: tags_intersection\n              definition:\n                intersection:\n                  - tag: bi\n                  - tag: users\n            - name: triple_descending\n              definition:\n                intersection:\n                  - fqn: \"*\"\n                  - tag: bi\n                  - tag: users\n            - name: triple_ascending\n              definition:\n                intersection:\n                  - tag: users\n                  - tag: bi\n                  - fqn: \"*\"\n            - name: intersection_with_exclusion\n              definition:\n                intersection:\n                  - method: fqn\n                    value: users_rollup_dependency\n                    parents: true\n                  - method: fqn\n                    value: users\n                    children: true\n                  - exclude:\n                    - users_rollup_dependency\n            - name: intersection_exclude_intersection\n              definition:\n                intersection:\n                  - tag:bi\n                  - \"@users\"\n                  - exclude:\n                      - intersection:\n                        - tag:bi\n                        - method: fqn\n                          value: users_rollup\n                          children: true\n            - name: intersection_exclude_intersection_lack\n              definition:\n                intersection:\n                  - tag:bi\n                  - \"@users\"\n                  - exclude:\n                      - intersection:\n                        - method: fqn\n                          value: emails\n                          children_parents: true\n                        - method: fqn\n                          value: emails_alt\n                          children_parents: true\n        \"\"\"\n\n\n# The project and run_seed fixtures will be executed for each test method\nclass TestIntersectionSyncs(SelectionFixtures):\n    # The tests here aiming to test whether the correct node is selected,\n    # we don't need the run to pass\n    @pytest.fixture(scope=\"class\")\n    def selectors(self):\n        return selectors_yml\n\n    def test_same_model_intersection(self, project):\n        results = run_dbt([\"run\", \"--models\", \"users,users\"], expect_pass=False)\n        check_result_nodes_by_name(results, [\"users\"])\n\n    def test_same_model_intersection_selectors(self, project):\n\n        results = run_dbt([\"run\", \"--selector\", \"same_intersection\"], expect_pass=False)\n        check_result_nodes_by_name(results, [\"users\"])\n\n    def test_tags_intersection(self, project):\n\n        results = run_dbt([\"run\", \"--models\", \"tag:bi,tag:users\"], expect_pass=False)\n        check_result_nodes_by_name(results, [\"users\"])\n\n    def test_tags_intersection_selectors(self, project):\n\n        results = run_dbt([\"run\", \"--selector\", \"tags_intersection\"], expect_pass=False)\n        check_result_nodes_by_name(results, [\"users\"])\n\n    def test_intersection_triple_descending(self, project):\n\n        results = run_dbt([\"run\", \"--models\", \"*,tag:bi,tag:users\"], expect_pass=False)\n        check_result_nodes_by_name(results, [\"users\"])\n\n    def test_intersection_triple_descending_schema(self, project):\n\n        results = run_dbt([\"run\", \"--models\", \"*,tag:bi,tag:users\"], expect_pass=False)\n        check_result_nodes_by_name(results, [\"users\"])\n\n    def test_intersection_triple_descending_schema_selectors(self, project):\n\n        results = run_dbt([\"run\", \"--selector\", \"triple_descending\"], expect_pass=False)\n        check_result_nodes_by_name(results, [\"users\"])\n\n    def test_intersection_triple_ascending(self, project):\n\n        results = run_dbt([\"run\", \"--models\", \"tag:users,tag:bi,*\"], expect_pass=False)\n        check_result_nodes_by_name(results, [\"users\"])\n\n    def test_intersection_triple_ascending_schema_selectors(self, project):\n\n        results = run_dbt([\"run\", \"--selector\", \"triple_ascending\"], expect_pass=False)\n        check_result_nodes_by_name(results, [\"users\"])\n\n    def test_intersection_with_exclusion(self, project):\n\n        results = run_dbt(\n            [\n                \"run\",\n                \"--models\",\n                \"+users_rollup_dependency,users+\",\n                \"--exclude\",\n                \"users_rollup_dependency\",\n            ],\n            expect_pass=False,\n        )\n        check_result_nodes_by_name(results, [\"users\", \"users_rollup\"])\n\n    def test_intersection_with_exclusion_selectors(self, project):\n\n        results = run_dbt([\"run\", \"--selector\", \"intersection_with_exclusion\"], expect_pass=False)\n        check_result_nodes_by_name(results, [\"users\", \"users_rollup\"])\n\n    def test_intersection_exclude_intersection(self, project):\n\n        results = run_dbt(\n            [\"run\", \"--models\", \"tag:bi,@users\", \"--exclude\", \"tag:bi,users_rollup+\"],\n            expect_pass=False,\n        )\n        check_result_nodes_by_name(results, [\"users\"])\n\n    def test_intersection_exclude_intersection_selectors(self, project):\n\n        results = run_dbt(\n            [\"run\", \"--selector\", \"intersection_exclude_intersection\"],\n            expect_pass=False,\n        )\n        check_result_nodes_by_name(results, [\"users\"])\n\n    def test_intersection_exclude_intersection_lack(self, project):\n\n        results = run_dbt(\n            [\"run\", \"--models\", \"tag:bi,@users\", \"--exclude\", \"@emails,@emails_alt\"],\n            expect_pass=False,\n        )\n        check_result_nodes_by_name(results, [\"users\", \"users_rollup\"])\n\n    def test_intersection_exclude_intersection_lack_selector(self, project):\n\n        results = run_dbt(\n            [\"run\", \"--selector\", \"intersection_exclude_intersection_lack\"],\n            expect_pass=False,\n        )\n        check_result_nodes_by_name(results, [\"users\", \"users_rollup\"])\n\n    def test_intersection_exclude_triple_intersection(self, project):\n\n        results = run_dbt(\n            [\"run\", \"--models\", \"tag:bi,@users\", \"--exclude\", \"*,tag:bi,users_rollup\"],\n            expect_pass=False,\n        )\n        check_result_nodes_by_name(results, [\"users\"])\n\n    def test_intersection_concat(self, project):\n\n        results = run_dbt([\"run\", \"--models\", \"tag:bi,@users\", \"emails_alt\"], expect_pass=False)\n        check_result_nodes_by_name(results, [\"users\", \"users_rollup\", \"emails_alt\"])\n\n    def test_intersection_concat_intersection(self, project):\n\n        results = run_dbt(\n            [\"run\", \"--models\", \"tag:bi,@users\", \"@emails_alt,emails_alt\"],\n            expect_pass=False,\n        )\n        check_result_nodes_by_name(results, [\"users\", \"users_rollup\", \"emails_alt\"])\n\n    def test_intersection_concat_exclude(self, project):\n\n        results = run_dbt(\n            [\n                \"run\",\n                \"--models\",\n                \"tag:bi,@users\",\n                \"emails_alt\",\n                \"--exclude\",\n                \"users_rollup\",\n            ],\n            expect_pass=False,\n        )\n        check_result_nodes_by_name(results, [\"users\", \"emails_alt\"])\n\n    def test_intersection_concat_exclude_concat(self, project):\n\n        results = run_dbt(\n            [\n                \"run\",\n                \"--models\",\n                \"tag:bi,@users\",\n                \"emails_alt,@users\",\n                \"--exclude\",\n                \"users_rollup_dependency\",\n                \"users_rollup\",\n            ],\n            expect_pass=False,\n        )\n        check_result_nodes_by_name(results, [\"users\", \"emails_alt\"])\n\n    def test_intersection_concat_exclude_intersection_concat(self, project):\n\n        results = run_dbt(\n            [\n                \"run\",\n                \"--models\",\n                \"tag:bi,@users\",\n                \"emails_alt,@users\",\n                \"--exclude\",\n                \"@users,users_rollup_dependency\",\n                \"@users,users_rollup\",\n            ],\n            expect_pass=False,\n        )\n        check_result_nodes_by_name(results, [\"users\", \"emails_alt\"])\n"
  },
  {
    "path": "tests/functional/graph_selection/test_schema_test_graph_selection.py",
    "content": "import pytest\n\nfrom dbt.tests.fixtures.project import write_project_files\nfrom dbt.tests.util import run_dbt\nfrom tests.fixtures.dbt_integration_project import dbt_integration_project  # noqa: F401\nfrom tests.functional.graph_selection.fixtures import SelectionFixtures\n\n\ndef run_schema_and_assert(project, include, exclude, expected_tests):\n    # deps must run before seed\n    run_dbt([\"deps\"])\n    run_dbt([\"seed\"])\n    results = run_dbt([\"run\", \"--exclude\", \"never_selected\"])\n    assert len(results) == 12\n\n    test_args = [\"test\"]\n    if include:\n        test_args += [\"--select\", include]\n    if exclude:\n        test_args += [\"--exclude\", exclude]\n    test_results = run_dbt(test_args)\n\n    ran_tests = sorted([test.node.name for test in test_results])\n    expected_sorted = sorted(expected_tests)\n\n    assert ran_tests == expected_sorted\n\n\nclass TestSchemaTestGraphSelection(SelectionFixtures):\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project_root, dbt_integration_project):  # noqa: F811\n        write_project_files(project_root, \"dbt_integration_project\", dbt_integration_project)\n\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\"packages\": [{\"local\": \"dbt_integration_project\"}]}\n\n    def test_schema_tests_no_specifiers(self, project):\n        run_schema_and_assert(\n            project,\n            None,\n            None,\n            [\n                \"not_null_emails_email\",\n                \"unique_table_model_id\",\n                \"unique_users_id\",\n                \"unique_users_rollup_gender\",\n            ],\n        )\n\n    def test_schema_tests_specify_model(self, project):\n        run_schema_and_assert(project, \"users\", None, [\"unique_users_id\"])\n\n    def test_schema_tests_specify_tag(self, project):\n        run_schema_and_assert(\n            project, \"tag:bi\", None, [\"unique_users_id\", \"unique_users_rollup_gender\"]\n        )\n\n    def test_schema_tests_specify_model_and_children(self, project):\n        run_schema_and_assert(\n            project, \"users+\", None, [\"unique_users_id\", \"unique_users_rollup_gender\"]\n        )\n\n    def test_schema_tests_specify_tag_and_children(self, project):\n        run_schema_and_assert(\n            project,\n            \"tag:base+\",\n            None,\n            [\"not_null_emails_email\", \"unique_users_id\", \"unique_users_rollup_gender\"],\n        )\n\n    def test_schema_tests_specify_model_and_parents(self, project):\n        run_schema_and_assert(\n            project,\n            \"+users_rollup\",\n            None,\n            [\"unique_users_id\", \"unique_users_rollup_gender\"],\n        )\n\n    def test_schema_tests_specify_model_and_parents_with_exclude(self, project):\n        run_schema_and_assert(project, \"+users_rollup\", \"users_rollup\", [\"unique_users_id\"])\n\n    def test_schema_tests_specify_exclude_only(self, project):\n        run_schema_and_assert(\n            project,\n            None,\n            \"users_rollup\",\n            [\"not_null_emails_email\", \"unique_table_model_id\", \"unique_users_id\"],\n        )\n\n    def test_schema_tests_specify_model_in_pkg(self, project):\n        run_schema_and_assert(\n            project,\n            \"test.users_rollup\",\n            None,\n            # TODO: change this. there's no way to select only direct ancestors\n            # atm.\n            [\"unique_users_rollup_gender\"],\n        )\n\n    def test_schema_tests_with_glob(self, project):\n        run_schema_and_assert(\n            project,\n            \"*\",\n            \"users\",\n            [\n                \"not_null_emails_email\",\n                \"unique_table_model_id\",\n                \"unique_users_rollup_gender\",\n            ],\n        )\n\n    def test_schema_tests_dep_package_only(self, project):\n        run_schema_and_assert(project, \"dbt_integration_project\", None, [\"unique_table_model_id\"])\n\n    def test_schema_tests_model_in_dep_pkg(self, project):\n        run_schema_and_assert(\n            project,\n            \"dbt_integration_project.table_model\",\n            None,\n            [\"unique_table_model_id\"],\n        )\n\n    def test_schema_tests_exclude_pkg(self, project):\n        run_schema_and_assert(\n            project,\n            None,\n            \"dbt_integration_project\",\n            [\"not_null_emails_email\", \"unique_users_id\", \"unique_users_rollup_gender\"],\n        )\n"
  },
  {
    "path": "tests/functional/graph_selection/test_tag_selection.py",
    "content": "import pytest\n\nfrom dbt.events.types import NoNodesForSelectionCriteria\nfrom dbt.tests.util import check_result_nodes_by_name, run_dbt\nfrom dbt_common.events.event_catcher import EventCatcher\nfrom tests.functional.graph_selection.fixtures import SelectionFixtures\n\nselectors_yml = \"\"\"\n            selectors:\n              - name: tag_specified_as_string_str\n                definition: tag:specified_as_string\n              - name: tag_specified_as_string_dict\n                definition:\n                  method: tag\n                  value: specified_as_string\n              - name: tag_specified_in_project_children_str\n                definition: +tag:specified_in_project+\n              - name: tag_specified_in_project_children_dict\n                definition:\n                  method: tag\n                  value: specified_in_project\n                  parents: true\n                  children: true\n              - name: tagged-bi\n                definition:\n                  method: tag\n                  value: bi\n              - name: user_tagged_childrens_parents\n                definition:\n                  method: tag\n                  value: users\n                  childrens_parents: true\n              - name: base_ephemerals\n                definition:\n                  union:\n                    - tag: base\n                    - method: config.materialized\n                      value: ephemeral\n              - name: warn-severity\n                definition:\n                    config.severity: warn\n              - name: roundabout-everything\n                definition:\n                    union:\n                        - \"@tag:users\"\n                        - intersection:\n                            - tag: base\n                            - config.materialized: ephemeral\n    \"\"\"\n\n\nclass TestTagSelection(SelectionFixtures):\n    # The tests here aiming to test whether the correct node is selected,\n    # we don't need the run to pass\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"config-version\": 2,\n            \"models\": {\n                \"test\": {\n                    \"users\": {\"tags\": \"specified_as_string\"},\n                    \"users_rollup\": {\n                        \"tags\": [\"specified_in_project\"],\n                    },\n                }\n            },\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def selectors(self):\n        return selectors_yml\n\n    def test_select_tag(self, project):\n        results = run_dbt([\"run\", \"--models\", \"tag:specified_as_string\"], expect_pass=False)\n        check_result_nodes_by_name(results, [\"users\"])\n\n    def test_select_tag_selector_str(self, project):\n        results = run_dbt([\"run\", \"--selector\", \"tag_specified_as_string_str\"], expect_pass=False)\n        check_result_nodes_by_name(results, [\"users\"])\n\n    def test_select_tag_selector_dict(self, project):\n        results = run_dbt([\"run\", \"--selector\", \"tag_specified_as_string_dict\"], expect_pass=False)\n        check_result_nodes_by_name(results, [\"users\"])\n\n    def test_select_tag_and_children(self, project):  # noqa\n        results = run_dbt([\"run\", \"--models\", \"+tag:specified_in_project+\"], expect_pass=False)\n        check_result_nodes_by_name(results, [\"users\", \"users_rollup\", \"users_rollup_dependency\"])\n\n    def test_select_tag_and_children_selector_str(self, project):  # noqa\n        results = run_dbt(\n            [\"run\", \"--selector\", \"tag_specified_in_project_children_str\"],\n            expect_pass=False,\n        )\n        check_result_nodes_by_name(results, [\"users\", \"users_rollup\", \"users_rollup_dependency\"])\n\n    def test_select_tag_and_children_selector_dict(self, project):  # noqa\n        results = run_dbt(\n            [\"run\", \"--selector\", \"tag_specified_in_project_children_dict\"],\n            expect_pass=False,\n        )\n        check_result_nodes_by_name(results, [\"users\", \"users_rollup\", \"users_rollup_dependency\"])\n\n    def test_select_tag_in_model_with_project_config(self, project):  # noqa\n        results = run_dbt([\"run\", \"--models\", \"tag:bi\"], expect_pass=False)\n        check_result_nodes_by_name(results, [\"users\", \"users_rollup\"])\n\n    def test_select_tag_in_model_with_project_config_selector(self, project):  # noqa\n        results = run_dbt([\"run\", \"--selector\", \"tagged-bi\"], expect_pass=False)\n        check_result_nodes_by_name(results, [\"users\", \"users_rollup\"])\n\n    # check that model configs aren't squashed by project configs\n    def test_select_tag_in_model_with_project_config_parents_children(self, project):  # noqa\n        results = run_dbt([\"run\", \"--models\", \"@tag:users\"], expect_pass=False)\n        check_result_nodes_by_name(\n            results, [\"users\", \"users_rollup\", \"emails_alt\", \"users_rollup_dependency\"]\n        )\n\n        # just the users/users_rollup tests\n        results = run_dbt([\"test\", \"--models\", \"@tag:users\"], expect_pass=False)\n        check_result_nodes_by_name(results, [\"unique_users_rollup_gender\", \"unique_users_id\"])\n\n        # just the email test\n        results = run_dbt(\n            [\"test\", \"--models\", \"tag:base,config.materialized:ephemeral\"],\n            expect_pass=False,\n        )\n        check_result_nodes_by_name(results, [\"not_null_emails_email\"])\n\n        # also just the email test\n        results = run_dbt([\"test\", \"--models\", \"config.severity:warn\"], expect_pass=False)\n        check_result_nodes_by_name(results, [\"not_null_emails_email\"])\n\n        # all 3 tests\n        results = run_dbt(\n            [\"test\", \"--models\", \"@tag:users tag:base,config.materialized:ephemeral\"],\n            expect_pass=False,\n        )\n        check_result_nodes_by_name(\n            results,\n            [\"not_null_emails_email\", \"unique_users_id\", \"unique_users_rollup_gender\"],\n        )\n\n    def test_select_tag_in_model_with_project_config_parents_children_selectors(self, project):\n        results = run_dbt(\n            [\"run\", \"--selector\", \"user_tagged_childrens_parents\"], expect_pass=False\n        )\n        check_result_nodes_by_name(\n            results, [\"users\", \"users_rollup\", \"emails_alt\", \"users_rollup_dependency\"]\n        )\n\n        # just the users/users_rollup tests\n        results = run_dbt(\n            [\"test\", \"--selector\", \"user_tagged_childrens_parents\"], expect_pass=False\n        )\n        check_result_nodes_by_name(results, [\"unique_users_id\", \"unique_users_rollup_gender\"])\n\n        # just the email test\n        results = run_dbt([\"test\", \"--selector\", \"base_ephemerals\"], expect_pass=False)\n        check_result_nodes_by_name(results, [\"not_null_emails_email\"])\n\n        # also just the email test\n        results = run_dbt([\"test\", \"--selector\", \"warn-severity\"], expect_pass=False)\n        check_result_nodes_by_name(results, [\"not_null_emails_email\"])\n\n        # all 3 tests\n        results = run_dbt([\"test\", \"--selector\", \"roundabout-everything\"], expect_pass=False)\n        check_result_nodes_by_name(\n            results,\n            [\"unique_users_rollup_gender\", \"unique_users_id\", \"not_null_emails_email\"],\n        )\n\n\nclass TestTagSelectionNoMatch:\n    def test_no_match(self, project):\n        no_match_catcher = EventCatcher(event_to_catch=NoNodesForSelectionCriteria)\n\n        # check `run` command\n        run_dbt([\"run\", \"--select\", \"tag:no_such_tag\"], callbacks=[no_match_catcher.catch])\n        assert len(no_match_catcher.caught_events) == 1\n\n        # clear the catcher\n        no_match_catcher.flush()\n\n        # check `test` command\n        run_dbt([\"test\", \"--select\", \"tag:no_such_tag\"], callbacks=[no_match_catcher.catch])\n        assert len(no_match_catcher.caught_events) == 1\n\n        # clear the catcher\n        no_match_catcher.flush()\n\n        # check `build` command\n        run_dbt([\"build\", \"--select\", \"tag:no_such_tag\"], callbacks=[no_match_catcher.catch])\n        assert len(no_match_catcher.caught_events) == 1\n"
  },
  {
    "path": "tests/functional/graph_selection/test_version_selection.py",
    "content": "import pytest\n\nfrom dbt.tests.util import read_file, run_dbt\nfrom tests.functional.graph_selection.fixtures import (\n    base_users_sql,\n    properties_yml,\n    schema_yml,\n    users_rollup_sql,\n    users_sql,\n)\n\nselectors_yml = \"\"\"\n            selectors:\n              - name: version_specified_as_string_str\n                definition: version:latest\n              - name: version_specified_as_string_dict\n                definition:\n                  method: version\n                  value: latest\n              - name: version_childrens_parents\n                definition:\n                  method: version\n                  value: latest\n                  childrens_parents: true\n\"\"\"\n\n\nclass TestVersionSelection:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": schema_yml,\n            \"versioned_v1.sql\": users_sql,\n            \"versioned_v2.sql\": users_sql,\n            \"versioned_v3.sql\": users_sql,\n            \"versioned_v4.5.sql\": users_sql,\n            \"versioned_v5.0.sql\": users_sql,\n            \"versioned_v21.sql\": users_sql,\n            \"versioned_vtest.sql\": users_sql,\n            \"base_users.sql\": base_users_sql,\n            \"users.sql\": users_sql,\n            \"users_rollup.sql\": users_rollup_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self, test_data_dir):\n        # Read seed file and return\n        seeds = {\"properties.yml\": properties_yml}\n        for seed_file in [\"seed.csv\", \"summary_expected.csv\"]:\n            seeds[seed_file] = read_file(test_data_dir, seed_file)\n        return seeds\n\n    @pytest.fixture(scope=\"class\")\n    def selectors(self):\n        return selectors_yml\n\n    def test_select_none_versions(self, project):\n        results = run_dbt([\"ls\", \"--select\", \"version:none\"])\n        assert sorted(results) == [\n            \"test.base_users\",\n            \"test.unique_users_id\",\n            \"test.unique_users_rollup_gender\",\n            \"test.users\",\n            \"test.users_rollup\",\n        ]\n\n    def test_select_latest_versions(self, project):\n        results = run_dbt([\"ls\", \"--select\", \"version:latest\"])\n        assert sorted(results) == [\"test.versioned.v2\"]\n\n    def test_select_old_versions(self, project):\n        results = run_dbt([\"ls\", \"--select\", \"version:old\"])\n        assert sorted(results) == [\"test.versioned.v1\"]\n\n    def test_select_prerelease_versions(self, project):\n        results = run_dbt([\"ls\", \"--select\", \"version:prerelease\"])\n        assert sorted(results) == [\n            \"test.versioned.v21\",\n            \"test.versioned.v3\",\n            \"test.versioned.v4.5\",\n            \"test.versioned.v5.0\",\n            \"test.versioned.vtest\",\n        ]\n\n    def test_select_version_selector_str(self, project):\n        results = run_dbt([\"ls\", \"--selector\", \"version_specified_as_string_str\"])\n        assert sorted(results) == [\"test.versioned.v2\"]\n\n    def test_select_version_selector_dict(self, project):\n        results = run_dbt([\"ls\", \"--selector\", \"version_specified_as_string_dict\"])\n        assert sorted(results) == [\"test.versioned.v2\"]\n\n    def test_select_models_by_version_and_children(self, project):  # noqa\n        results = run_dbt([\"ls\", \"--models\", \"+version:latest+\"])\n        assert sorted(results) == [\"test.base_users\", \"test.versioned.v2\"]\n\n    def test_select_version_and_children(self, project):  # noqa\n        expected = [\"source:test.raw.seed\", \"test.base_users\", \"test.versioned.v2\"]\n        results = run_dbt([\"ls\", \"--select\", \"+version:latest+\"])\n        assert sorted(results) == expected\n\n    def test_select_group_and_children_selector_str(self, project):  # noqa\n        expected = [\"source:test.raw.seed\", \"test.base_users\", \"test.versioned.v2\"]\n        results = run_dbt([\"ls\", \"--selector\", \"version_childrens_parents\"])\n        assert sorted(results) == expected\n\n    # 2 versions\n    def test_select_models_two_versions(self, project):\n        results = run_dbt([\"ls\", \"--models\", \"version:latest version:old\"])\n        assert sorted(results) == [\"test.versioned.v1\", \"test.versioned.v2\"]\n\n\nmy_model_yml = \"\"\"\nmodels:\n  - name: my_model\n    versions:\n      - v: 0\n\"\"\"\n\n\nclass TestVersionZero:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": \"select 1 as id\",\n            \"another.sql\": \"select * from {{ ref('my_model') }}\",\n            \"schema.yml\": my_model_yml,\n        }\n\n    def test_version_zero(self, project):\n        results = run_dbt([\"run\"])\n        assert len(results) == 2\n"
  },
  {
    "path": "tests/functional/incremental_schema_tests/fixtures.py",
    "content": "#\n# Properties\n#\n_PROPERTIES__SCHEMA = \"\"\"\nversion: 2\n\nmodels:\n  - name: model_a\n    columns:\n      - name: id\n        tags: [column_level_tag]\n        data_tests:\n          - unique\n\n  - name: incremental_ignore\n    columns:\n      - name: id\n        tags: [column_level_tag]\n        data_tests:\n          - unique\n\n  - name: incremental_ignore_target\n    columns:\n      - name: id\n        tags: [column_level_tag]\n        data_tests:\n          - unique\n\n  - name: incremental_append_new_columns\n    columns:\n      - name: id\n        tags: [column_level_tag]\n        data_tests:\n          - unique\n\n  - name: incremental_append_new_columns_target\n    columns:\n      - name: id\n        tags: [column_level_tag]\n        data_tests:\n          - unique\n\n  - name: incremental_sync_all_columns\n    columns:\n      - name: id\n        tags: [column_level_tag]\n        data_tests:\n          - unique\n\n  - name: incremental_sync_all_columns_target\n    columns:\n      - name: id\n        tags: [column_leveL_tag]\n        data_tests:\n          - unique\n\"\"\"\n\n#\n# Models\n#\n_MODELS__INCREMENTAL_SYNC_REMOVE_ONLY = \"\"\"\n{{\n    config(\n        materialized='incremental',\n        unique_key='id',\n        on_schema_change='sync_all_columns'\n\n    )\n}}\n\nWITH source_data AS (SELECT * FROM {{ ref('model_a') }} )\n\n{% set string_type = 'varchar(10)' %}\n\n{% if is_incremental() %}\n\nSELECT id,\n       cast(field1 as {{string_type}}) as field1\n\nFROM source_data WHERE id NOT IN (SELECT id from {{ this }} )\n\n{% else %}\n\nselect id,\n       cast(field1 as {{string_type}}) as field1,\n       cast(field2 as {{string_type}}) as field2\n\nfrom source_data where id <= 3\n\n{% endif %}\n\"\"\"\n\n_MODELS__INCREMENTAL_IGNORE = \"\"\"\n{{\n    config(\n        materialized='incremental',\n        unique_key='id',\n        on_schema_change='ignore'\n    )\n}}\n\nWITH source_data AS (SELECT * FROM {{ ref('model_a') }} )\n\n{% if is_incremental() %}\n\nSELECT id, field1, field2, field3, field4 FROM source_data WHERE id NOT IN (SELECT id from {{ this }} )\n\n{% else %}\n\nSELECT id, field1, field2 FROM source_data LIMIT 3\n\n{% endif %}\n\"\"\"\n\n_MODELS__INCREMENTAL_SYNC_REMOVE_ONLY_TARGET = \"\"\"\n{{\n    config(materialized='table')\n}}\n\nwith source_data as (\n\n    select * from {{ ref('model_a') }}\n\n)\n\n{% set string_type = 'varchar(10)' %}\n\nselect id\n       ,cast(field1 as {{string_type}}) as field1\n\nfrom source_data\norder by id\n\"\"\"\n\n_MODELS__INCREMENTAL_IGNORE_TARGET = \"\"\"\n{{\n    config(materialized='table')\n}}\n\nwith source_data as (\n\n    select * from {{ ref('model_a') }}\n\n)\n\nselect id\n       ,field1\n       ,field2\n\nfrom source_data\n\"\"\"\n\n_MODELS__INCREMENTAL_FAIL = \"\"\"\n{{\n    config(\n        materialized='incremental',\n        unique_key='id',\n        on_schema_change='fail'\n    )\n}}\n\nWITH source_data AS (SELECT * FROM {{ ref('model_a') }} )\n\n{% if is_incremental()  %}\n\nSELECT id, field1, field2 FROM source_data\n\n{% else %}\n\nSELECT id, field1, field3 FROm source_data\n\n{% endif %}\n\"\"\"\n\n_MODELS__INCREMENTAL_SYNC_ALL_COLUMNS = \"\"\"\n{{\n    config(\n        materialized='incremental',\n        unique_key='id',\n        on_schema_change='sync_all_columns'\n\n    )\n}}\n\nWITH source_data AS (SELECT * FROM {{ ref('model_a') }} )\n\n{% set string_type = 'varchar(10)' %}\n\n{% if is_incremental() %}\n\nSELECT id,\n       cast(field1 as {{string_type}}) as field1,\n       cast(field3 as {{string_type}}) as field3, -- to validate new fields\n       cast(field4 as {{string_type}}) AS field4 -- to validate new fields\n\nFROM source_data WHERE id NOT IN (SELECT id from {{ this }} )\n\n{% else %}\n\nselect id,\n       cast(field1 as {{string_type}}) as field1,\n       cast(field2 as {{string_type}}) as field2\n\nfrom source_data where id <= 3\n\n{% endif %}\n\"\"\"\n\n_MODELS__INCREMENTAL_APPEND_NEW_COLUMNS_REMOVE_ONE = \"\"\"\n{{\n    config(\n        materialized='incremental',\n        unique_key='id',\n        on_schema_change='append_new_columns'\n    )\n}}\n\n{% set string_type = 'varchar(10)' %}\n\nWITH source_data AS (SELECT * FROM {{ ref('model_a') }} )\n\n{% if is_incremental()  %}\n\nSELECT id,\n       cast(field1 as {{string_type}}) as field1,\n       cast(field3 as {{string_type}}) as field3,\n       cast(field4 as {{string_type}}) as field4\nFROM source_data WHERE id NOT IN (SELECT id from {{ this }} )\n\n{% else %}\n\nSELECT id,\n       cast(field1 as {{string_type}}) as field1,\n       cast(field2 as {{string_type}}) as field2\nFROM source_data where id <= 3\n\n{% endif %}\n\"\"\"\n\n_MODELS__A = \"\"\"\n{{\n    config(materialized='table')\n}}\n\nwith source_data as (\n\n    select 1 as id, 'aaa' as field1, 'bbb' as field2, 111 as field3, 'TTT' as field4\n    union all select 2 as id, 'ccc' as field1, 'ddd' as field2, 222 as field3, 'UUU' as field4\n    union all select 3 as id, 'eee' as field1, 'fff' as field2, 333 as field3, 'VVV' as field4\n    union all select 4 as id, 'ggg' as field1, 'hhh' as field2, 444 as field3, 'WWW' as field4\n    union all select 5 as id, 'iii' as field1, 'jjj' as field2, 555 as field3, 'XXX' as field4\n    union all select 6 as id, 'kkk' as field1, 'lll' as field2, 666 as field3, 'YYY' as field4\n\n)\n\nselect id\n       ,field1\n       ,field2\n       ,field3\n       ,field4\n\nfrom source_data\n\"\"\"\n\n_MODELS__INCREMENTAL_APPEND_NEW_COLUMNS_TARGET = \"\"\"\n{{\n    config(materialized='table')\n}}\n\n{% set string_type = 'varchar(10)' %}\n\nwith source_data as (\n\n    select * from {{ ref('model_a') }}\n\n)\n\nselect id\n       ,cast(field1 as {{string_type}}) as field1\n       ,cast(field2 as {{string_type}}) as field2\n       ,cast(CASE WHEN id <= 3 THEN NULL ELSE field3 END as {{string_type}}) AS field3\n       ,cast(CASE WHEN id <= 3 THEN NULL ELSE field4 END as {{string_type}}) AS field4\n\nfrom source_data\n\"\"\"\n\n_MODELS__INCREMENTAL_APPEND_NEW_COLUMNS = \"\"\"\n{{\n    config(\n        materialized='incremental',\n        unique_key='id',\n        on_schema_change='append_new_columns'\n    )\n}}\n\n{% set string_type = 'varchar(10)' %}\n\nWITH source_data AS (SELECT * FROM {{ ref('model_a') }} )\n\n{% if is_incremental()  %}\n\nSELECT id,\n       cast(field1 as {{string_type}}) as field1,\n       cast(field2 as {{string_type}}) as field2,\n       cast(field3 as {{string_type}}) as field3,\n       cast(field4 as {{string_type}}) as field4\nFROM source_data WHERE id NOT IN (SELECT id from {{ this }} )\n\n{% else %}\n\nSELECT id,\n       cast(field1 as {{string_type}}) as field1,\n       cast(field2 as {{string_type}}) as field2\nFROM source_data where id <= 3\n\n{% endif %}\n\"\"\"\n\n_MODELS__INCREMENTAL_SYNC_ALL_COLUMNS_TARGET = \"\"\"\n{{\n    config(materialized='table')\n}}\n\nwith source_data as (\n\n    select * from {{ ref('model_a') }}\n\n)\n\n{% set string_type = 'varchar(10)' %}\n\nselect id\n       ,cast(field1 as {{string_type}}) as field1\n       --,field2\n       ,cast(case when id <= 3 then null else field3 end as {{string_type}}) as field3\n       ,cast(case when id <= 3 then null else field4 end as {{string_type}}) as field4\n\nfrom source_data\norder by id\n\"\"\"\n\n_MODELS__INCREMENTAL_APPEND_NEW_COLUMNS_REMOVE_ONE_TARGET = \"\"\"\n{{\n    config(materialized='table')\n}}\n\n{% set string_type = 'varchar(10)' %}\n\nwith source_data as (\n\n    select * from {{ ref('model_a') }}\n\n)\n\nselect id,\n       cast(field1 as {{string_type}}) as field1,\n       cast(CASE WHEN id >  3 THEN NULL ELSE field2 END as {{string_type}}) AS field2,\n       cast(CASE WHEN id <= 3 THEN NULL ELSE field3 END as {{string_type}}) AS field3,\n       cast(CASE WHEN id <= 3 THEN NULL ELSE field4 END as {{string_type}}) AS field4\n\nfrom source_data\n\"\"\"\n\n#\n# Tests\n#\n\n_TESTS__SELECT_FROM_INCREMENTAL_IGNORE = \"\"\"\nselect * from {{ ref('incremental_ignore') }} where false\n\"\"\"\n\n_TESTS__SELECT_FROM_A = \"\"\"\nselect * from {{ ref('model_a') }} where false\n\"\"\"\n\n_TESTS__SELECT_FROM_INCREMENTAL_APPEND_NEW_COLUMNS_TARGET = \"\"\"\nselect * from {{ ref('incremental_append_new_columns_target') }} where false\n\"\"\"\n\n_TESTS__SELECT_FROM_INCREMENTAL_SYNC_ALL_COLUMNS = \"\"\"\nselect * from {{ ref('incremental_sync_all_columns') }} where false\n\"\"\"\n\n_TESTS__SELECT_FROM_INCREMENTAL_SYNC_ALL_COLUMNS_TARGET = \"\"\"\nselect * from {{ ref('incremental_sync_all_columns_target') }} where false\n\"\"\"\n\n_TESTS__SELECT_FROM_INCREMENTAL_IGNORE_TARGET = \"\"\"\nselect * from {{ ref('incremental_ignore_target') }} where false\n\"\"\"\n\n_TESTS__SELECT_FROM_INCREMENTAL_APPEND_NEW_COLUMNS = \"\"\"\nselect * from {{ ref('incremental_append_new_columns') }} where false\n\"\"\"\n"
  },
  {
    "path": "tests/functional/incremental_schema_tests/test_incremental_schema.py",
    "content": "import pytest\n\nfrom dbt.tests.util import check_relations_equal, run_dbt\nfrom tests.functional.incremental_schema_tests.fixtures import (\n    _MODELS__A,\n    _MODELS__INCREMENTAL_APPEND_NEW_COLUMNS,\n    _MODELS__INCREMENTAL_APPEND_NEW_COLUMNS_REMOVE_ONE,\n    _MODELS__INCREMENTAL_APPEND_NEW_COLUMNS_REMOVE_ONE_TARGET,\n    _MODELS__INCREMENTAL_APPEND_NEW_COLUMNS_TARGET,\n    _MODELS__INCREMENTAL_FAIL,\n    _MODELS__INCREMENTAL_IGNORE,\n    _MODELS__INCREMENTAL_IGNORE_TARGET,\n    _MODELS__INCREMENTAL_SYNC_ALL_COLUMNS,\n    _MODELS__INCREMENTAL_SYNC_ALL_COLUMNS_TARGET,\n    _MODELS__INCREMENTAL_SYNC_REMOVE_ONLY,\n    _MODELS__INCREMENTAL_SYNC_REMOVE_ONLY_TARGET,\n    _PROPERTIES__SCHEMA,\n    _TESTS__SELECT_FROM_A,\n    _TESTS__SELECT_FROM_INCREMENTAL_APPEND_NEW_COLUMNS,\n    _TESTS__SELECT_FROM_INCREMENTAL_APPEND_NEW_COLUMNS_TARGET,\n    _TESTS__SELECT_FROM_INCREMENTAL_IGNORE,\n    _TESTS__SELECT_FROM_INCREMENTAL_IGNORE_TARGET,\n    _TESTS__SELECT_FROM_INCREMENTAL_SYNC_ALL_COLUMNS,\n    _TESTS__SELECT_FROM_INCREMENTAL_SYNC_ALL_COLUMNS_TARGET,\n)\n\n\nclass TestIncrementalSchemaChange:\n    @pytest.fixture(scope=\"class\")\n    def properties(self):\n        return {\n            \"schema.yml\": _PROPERTIES__SCHEMA,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"incremental_sync_remove_only.sql\": _MODELS__INCREMENTAL_SYNC_REMOVE_ONLY,\n            \"incremental_ignore.sql\": _MODELS__INCREMENTAL_IGNORE,\n            \"incremental_sync_remove_only_target.sql\": _MODELS__INCREMENTAL_SYNC_REMOVE_ONLY_TARGET,\n            \"incremental_ignore_target.sql\": _MODELS__INCREMENTAL_IGNORE_TARGET,\n            \"incremental_fail.sql\": _MODELS__INCREMENTAL_FAIL,\n            \"incremental_sync_all_columns.sql\": _MODELS__INCREMENTAL_SYNC_ALL_COLUMNS,\n            \"incremental_append_new_columns_remove_one.sql\": _MODELS__INCREMENTAL_APPEND_NEW_COLUMNS_REMOVE_ONE,\n            \"model_a.sql\": _MODELS__A,\n            \"incremental_append_new_columns_target.sql\": _MODELS__INCREMENTAL_APPEND_NEW_COLUMNS_TARGET,\n            \"incremental_append_new_columns.sql\": _MODELS__INCREMENTAL_APPEND_NEW_COLUMNS,\n            \"incremental_sync_all_columns_target.sql\": _MODELS__INCREMENTAL_SYNC_ALL_COLUMNS_TARGET,\n            \"incremental_append_new_columns_remove_one_target.sql\": _MODELS__INCREMENTAL_APPEND_NEW_COLUMNS_REMOVE_ONE_TARGET,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def tests(self):\n        return {\n            \"select_from_incremental.sql\": _TESTS__SELECT_FROM_INCREMENTAL_IGNORE,\n            \"select_from_a.sql\": _TESTS__SELECT_FROM_A,\n            \"select_from_incremental_append_new_columns_target.sql\": _TESTS__SELECT_FROM_INCREMENTAL_APPEND_NEW_COLUMNS_TARGET,\n            \"select_from_incremental_sync_all_columns.sql\": _TESTS__SELECT_FROM_INCREMENTAL_SYNC_ALL_COLUMNS,\n            \"select_from_incremental_sync_all_columns_target.sql\": _TESTS__SELECT_FROM_INCREMENTAL_SYNC_ALL_COLUMNS_TARGET,\n            \"select_from_incremental_ignore_target.sql\": _TESTS__SELECT_FROM_INCREMENTAL_IGNORE_TARGET,\n            \"select_from_incremental_append_new_columns.sql\": _TESTS__SELECT_FROM_INCREMENTAL_APPEND_NEW_COLUMNS,\n        }\n\n    def run_twice_and_assert(self, include, compare_source, compare_target, project):\n\n        # dbt run (twice)\n        run_args = [\"run\"]\n        if include:\n            run_args.extend((\"--select\", include))\n        results_one = run_dbt(run_args)\n        assert len(results_one) == 3\n\n        results_two = run_dbt(run_args)\n        assert len(results_two) == 3\n\n        check_relations_equal(project.adapter, [compare_source, compare_target])\n\n    def run_incremental_append_new_columns(self, project):\n        select = \"model_a incremental_append_new_columns incremental_append_new_columns_target\"\n        compare_source = \"incremental_append_new_columns\"\n        compare_target = \"incremental_append_new_columns_target\"\n        self.run_twice_and_assert(select, compare_source, compare_target, project)\n\n    def run_incremental_append_new_columns_remove_one(self, project):\n        select = \"model_a incremental_append_new_columns_remove_one incremental_append_new_columns_remove_one_target\"\n        compare_source = \"incremental_append_new_columns_remove_one\"\n        compare_target = \"incremental_append_new_columns_remove_one_target\"\n        self.run_twice_and_assert(select, compare_source, compare_target, project)\n\n    def run_incremental_sync_all_columns(self, project):\n        select = \"model_a incremental_sync_all_columns incremental_sync_all_columns_target\"\n        compare_source = \"incremental_sync_all_columns\"\n        compare_target = \"incremental_sync_all_columns_target\"\n        self.run_twice_and_assert(select, compare_source, compare_target, project)\n\n    def run_incremental_sync_remove_only(self, project):\n        select = \"model_a incremental_sync_remove_only incremental_sync_remove_only_target\"\n        compare_source = \"incremental_sync_remove_only\"\n        compare_target = \"incremental_sync_remove_only_target\"\n        self.run_twice_and_assert(select, compare_source, compare_target, project)\n\n    def test_run_incremental_ignore(self, project):\n        select = \"model_a incremental_ignore incremental_ignore_target\"\n        compare_source = \"incremental_ignore\"\n        compare_target = \"incremental_ignore_target\"\n        self.run_twice_and_assert(select, compare_source, compare_target, project)\n\n    def test_run_incremental_append_new_columns(self, project):\n        self.run_incremental_append_new_columns(project)\n        self.run_incremental_append_new_columns_remove_one(project)\n\n    def test_run_incremental_sync_all_columns(self, project):\n        self.run_incremental_sync_all_columns(project)\n        self.run_incremental_sync_remove_only(project)\n\n    def test_run_incremental_fail_on_schema_change(self, project):\n        select = \"model_a incremental_fail\"\n        run_dbt([\"run\", \"--models\", select, \"--full-refresh\"])\n        results_two = run_dbt([\"run\", \"--models\", select], expect_pass=False)\n        assert \"Compilation Error\" in results_two[1].message\n"
  },
  {
    "path": "tests/functional/init/test_init.py",
    "content": "import os\nfrom pathlib import Path\nfrom unittest import mock\nfrom unittest.mock import Mock, call\n\nimport click\nimport pytest\nimport yaml\n\nfrom dbt.exceptions import DbtRuntimeError\nfrom dbt.task.init import InitTask\nfrom dbt.tests.util import run_dbt\n\n\nclass TestInitProjectWithExistingProfilesYml:\n    @mock.patch(\"dbt.task.init.InitTask._run_debug\")\n    @mock.patch(\"dbt.task.init._get_adapter_plugin_names\")\n    @mock.patch(\"click.confirm\")\n    @mock.patch(\"click.prompt\")\n    def test_init_task_in_project_with_existing_profiles_yml(\n        self, mock_prompt, mock_confirm, mock_get_adapter, mock_run_debug, project\n    ):\n        manager = Mock()\n        manager.attach_mock(mock_prompt, \"prompt\")\n        manager.attach_mock(mock_confirm, \"confirm\")\n        manager.confirm.side_effect = [\"y\"]\n        manager.prompt.side_effect = [\n            1,\n            \"localhost\",\n            5432,\n            \"test_user\",\n            \"test_password\",\n            \"test_db\",\n            \"test_schema\",\n            4,\n        ]\n        mock_get_adapter.return_value = [project.adapter.type()]\n\n        run_dbt([\"init\"])\n\n        manager.assert_has_calls(\n            [\n                call.confirm(\n                    f\"The profile test already exists in {os.path.join(project.profiles_dir, 'profiles.yml')}. Continue and overwrite it?\"\n                ),\n                call.prompt(\n                    \"Which database would you like to use?\\n[1] postgres\\n\\n(Don't see the one you want? https://docs.getdbt.com/docs/available-adapters)\\n\\nEnter a number\",\n                    type=click.INT,\n                ),\n                call.prompt(\n                    \"host (hostname for the instance)\", default=None, hide_input=False, type=None\n                ),\n                call.prompt(\"port\", default=5432, hide_input=False, type=click.INT),\n                call.prompt(\"user (dev username)\", default=None, hide_input=False, type=None),\n                call.prompt(\"pass (dev password)\", default=None, hide_input=True, type=None),\n                call.prompt(\n                    \"dbname (default database that dbt will build objects in)\",\n                    default=None,\n                    hide_input=False,\n                    type=None,\n                ),\n                call.prompt(\n                    \"schema (default schema that dbt will build objects in)\",\n                    default=None,\n                    hide_input=False,\n                    type=None,\n                ),\n                call.prompt(\"threads (1 or more)\", default=1, hide_input=False, type=click.INT),\n            ]\n        )\n\n        with open(os.path.join(project.profiles_dir, \"profiles.yml\"), \"r\") as f:\n            assert (\n                f.read()\n                == \"\"\"test:\n  outputs:\n    dev:\n      dbname: test_db\n      host: localhost\n      pass: test_password\n      port: 5432\n      schema: test_schema\n      threads: 4\n      type: postgres\n      user: test_user\n  target: dev\n\"\"\"\n            )\n\n        mock_run_debug.assert_called_once()\n\n    def test_init_task_in_project_specifying_profile_errors(self, project):\n        with pytest.raises(DbtRuntimeError) as error:\n            run_dbt([\"init\", \"--profile\", \"test\"], expect_pass=False)\n            assert \"Can not init existing project with specified profile\" in str(error)\n\n\nclass TestInitProjectWithoutExistingProfilesYml:\n    @mock.patch(\"dbt.task.init.InitTask._run_debug\")\n    @mock.patch(\"dbt.task.init._get_adapter_plugin_names\")\n    @mock.patch(\"click.prompt\")\n    @mock.patch.object(Path, \"exists\", autospec=True)\n    def test_init_task_in_project_without_existing_profiles_yml(\n        self, exists, mock_prompt, mock_get_adapter, mock_run_debug, project\n    ):\n        def exists_side_effect(path):\n            # Override responses on specific files, default to 'real world' if not overriden\n            return {\"profiles.yml\": False}.get(path.name, os.path.exists(path))\n\n        exists.side_effect = exists_side_effect\n        manager = Mock()\n        manager.attach_mock(mock_prompt, \"prompt\")\n        manager.prompt.side_effect = [\n            1,\n            \"localhost\",\n            5432,\n            \"test_user\",\n            \"test_password\",\n            \"test_db\",\n            \"test_schema\",\n            4,\n        ]\n        mock_get_adapter.return_value = [project.adapter.type()]\n\n        run_dbt([\"init\"])\n\n        manager.assert_has_calls(\n            [\n                call.prompt(\n                    \"Which database would you like to use?\\n[1] postgres\\n\\n(Don't see the one you want? https://docs.getdbt.com/docs/available-adapters)\\n\\nEnter a number\",\n                    type=click.INT,\n                ),\n                call.prompt(\n                    \"host (hostname for the instance)\", default=None, hide_input=False, type=None\n                ),\n                call.prompt(\"port\", default=5432, hide_input=False, type=click.INT),\n                call.prompt(\"user (dev username)\", default=None, hide_input=False, type=None),\n                call.prompt(\"pass (dev password)\", default=None, hide_input=True, type=None),\n                call.prompt(\n                    \"dbname (default database that dbt will build objects in)\",\n                    default=None,\n                    hide_input=False,\n                    type=None,\n                ),\n                call.prompt(\n                    \"schema (default schema that dbt will build objects in)\",\n                    default=None,\n                    hide_input=False,\n                    type=None,\n                ),\n                call.prompt(\"threads (1 or more)\", default=1, hide_input=False, type=click.INT),\n            ]\n        )\n\n        with open(os.path.join(project.profiles_dir, \"profiles.yml\"), \"r\") as f:\n            assert (\n                f.read()\n                == \"\"\"test:\n  outputs:\n    dev:\n      dbname: test_db\n      host: localhost\n      pass: test_password\n      port: 5432\n      schema: test_schema\n      threads: 4\n      type: postgres\n      user: test_user\n  target: dev\n\"\"\"\n            )\n\n            mock_run_debug.assert_called_once()\n\n    def test_init_task_in_project_without_profile_yml_specifying_profile_errors(self, project):\n        # Even without profiles.yml, init inside a project with --profile should error\n        with pytest.raises(DbtRuntimeError) as error:\n            run_dbt([\"init\", \"--profile\", \"test\"], expect_pass=False)\n            assert \"Can not init existing project with specified profile\" in str(error)\n\n\nclass TestInitProjectWithoutExistingProfilesYmlOrTemplate:\n    @mock.patch(\"dbt.task.init.InitTask._run_debug\")\n    @mock.patch(\"dbt.task.init._get_adapter_plugin_names\")\n    @mock.patch(\"click.confirm\")\n    @mock.patch(\"click.prompt\")\n    @mock.patch.object(Path, \"exists\", autospec=True)\n    def test_init_task_in_project_without_existing_profiles_yml_or_profile_template(\n        self, exists, mock_prompt, mock_confirm, mock_get_adapter, mock_run_debug, project\n    ):\n        def exists_side_effect(path):\n            # Override responses on specific files, default to 'real world' if not overriden\n            return {\n                \"profiles.yml\": False,\n                \"profile_template.yml\": False,\n            }.get(path.name, os.path.exists(path))\n\n        exists.side_effect = exists_side_effect\n        manager = Mock()\n        manager.attach_mock(mock_prompt, \"prompt\")\n        manager.attach_mock(mock_confirm, \"confirm\")\n        manager.prompt.side_effect = [\n            1,\n        ]\n        mock_get_adapter.return_value = [project.adapter.type()]\n        run_dbt([\"init\"])\n        manager.assert_has_calls(\n            [\n                call.prompt(\n                    \"Which database would you like to use?\\n[1] postgres\\n\\n(Don't see the one you want? https://docs.getdbt.com/docs/available-adapters)\\n\\nEnter a number\",\n                    type=click.INT,\n                ),\n            ]\n        )\n\n        with open(os.path.join(project.profiles_dir, \"profiles.yml\"), \"r\") as f:\n            assert (\n                f.read()\n                == \"\"\"test:\n  outputs:\n\n    dev:\n      type: postgres\n      threads: [1 or more]\n      host: [host]\n      port: [port]\n      user: [dev_username]\n      pass: [dev_password]\n      dbname: [dbname]\n      schema: [dev_schema]\n\n    prod:\n      type: postgres\n      threads: [1 or more]\n      host: [host]\n      port: [port]\n      user: [prod_username]\n      pass: [prod_password]\n      dbname: [dbname]\n      schema: [prod_schema]\n\n  target: dev\n\"\"\"\n            )\n            mock_run_debug.assert_called_once()\n\n\nclass TestInitProjectWithProfileTemplateWithoutExistingProfilesYml:\n    @mock.patch(\"dbt.task.init.InitTask._run_debug\")\n    @mock.patch(\"dbt.task.init._get_adapter_plugin_names\")\n    @mock.patch(\"click.confirm\")\n    @mock.patch(\"click.prompt\")\n    @mock.patch.object(Path, \"exists\", autospec=True)\n    def test_init_task_in_project_with_profile_template_without_existing_profiles_yml(\n        self, exists, mock_prompt, mock_confirm, mock_get_adapter, mock_run_debug, project\n    ):\n        def exists_side_effect(path):\n            # Override responses on specific files, default to 'real world' if not overriden\n            return {\n                \"profiles.yml\": False,\n            }.get(path.name, os.path.exists(path))\n\n        exists.side_effect = exists_side_effect\n\n        with open(\"profile_template.yml\", \"w\") as f:\n            f.write(\n                \"\"\"fixed:\n  type: postgres\n  threads: 4\n  host: localhost\n  dbname: my_db\n  schema: my_schema\n  target: my_target\nprompts:\n  target:\n    hint: 'The target name'\n    type: string\n  port:\n    hint: 'The port (for integer test purposes)'\n    type: int\n    default: 5432\n  user:\n    hint: 'Your username'\n  pass:\n    hint: 'Your password'\n    hide_input: true\"\"\"\n            )\n\n        manager = Mock()\n        manager.attach_mock(mock_prompt, \"prompt\")\n        manager.attach_mock(mock_confirm, \"confirm\")\n        manager.prompt.side_effect = [\"my_target\", 5432, \"test_username\", \"test_password\"]\n        mock_get_adapter.return_value = [project.adapter.type()]\n        run_dbt([\"init\"])\n        manager.assert_has_calls(\n            [\n                call.prompt(\n                    \"target (The target name)\", default=None, hide_input=False, type=click.STRING\n                ),\n                call.prompt(\n                    \"port (The port (for integer test purposes))\",\n                    default=5432,\n                    hide_input=False,\n                    type=click.INT,\n                ),\n                call.prompt(\"user (Your username)\", default=None, hide_input=False, type=None),\n                call.prompt(\"pass (Your password)\", default=None, hide_input=True, type=None),\n            ]\n        )\n\n        with open(os.path.join(project.profiles_dir, \"profiles.yml\"), \"r\") as f:\n            assert (\n                f.read()\n                == \"\"\"test:\n  outputs:\n    my_target:\n      dbname: my_db\n      host: localhost\n      pass: test_password\n      port: 5432\n      schema: my_schema\n      threads: 4\n      type: postgres\n      user: test_username\n  target: my_target\n\"\"\"\n            )\n            mock_run_debug.assert_called_once()\n\n\nclass TestInitInvalidProfileTemplate:\n    @mock.patch(\"dbt.task.init.InitTask._run_debug\")\n    @mock.patch(\"dbt.task.init._get_adapter_plugin_names\")\n    @mock.patch(\"click.confirm\")\n    @mock.patch(\"click.prompt\")\n    def test_init_task_in_project_with_invalid_profile_template(\n        self, mock_prompt, mock_confirm, mock_get_adapter, mock_run_debug, project\n    ):\n        \"\"\"Test that when an invalid profile_template.yml is provided in the project,\n        init command falls back to the target's profile_template.yml\"\"\"\n        with open(os.path.join(project.project_root, \"profile_template.yml\"), \"w\") as f:\n            f.write(\"\"\"invalid template\"\"\")\n\n        manager = Mock()\n        manager.attach_mock(mock_prompt, \"prompt\")\n        manager.attach_mock(mock_confirm, \"confirm\")\n        manager.confirm.side_effect = [\"y\"]\n        manager.prompt.side_effect = [\n            1,\n            \"localhost\",\n            5432,\n            \"test_username\",\n            \"test_password\",\n            \"test_db\",\n            \"test_schema\",\n            4,\n        ]\n        mock_get_adapter.return_value = [project.adapter.type()]\n\n        run_dbt([\"init\"])\n\n        manager.assert_has_calls(\n            [\n                call.confirm(\n                    f\"The profile test already exists in {os.path.join(project.profiles_dir, 'profiles.yml')}. Continue and overwrite it?\"\n                ),\n                call.prompt(\n                    \"Which database would you like to use?\\n[1] postgres\\n\\n(Don't see the one you want? https://docs.getdbt.com/docs/available-adapters)\\n\\nEnter a number\",\n                    type=click.INT,\n                ),\n                call.prompt(\n                    \"host (hostname for the instance)\", default=None, hide_input=False, type=None\n                ),\n                call.prompt(\"port\", default=5432, hide_input=False, type=click.INT),\n                call.prompt(\"user (dev username)\", default=None, hide_input=False, type=None),\n                call.prompt(\"pass (dev password)\", default=None, hide_input=True, type=None),\n                call.prompt(\n                    \"dbname (default database that dbt will build objects in)\",\n                    default=None,\n                    hide_input=False,\n                    type=None,\n                ),\n                call.prompt(\n                    \"schema (default schema that dbt will build objects in)\",\n                    default=None,\n                    hide_input=False,\n                    type=None,\n                ),\n                call.prompt(\"threads (1 or more)\", default=1, hide_input=False, type=click.INT),\n            ]\n        )\n\n        with open(os.path.join(project.profiles_dir, \"profiles.yml\"), \"r\") as f:\n            assert (\n                f.read()\n                == \"\"\"test:\n  outputs:\n    dev:\n      dbname: test_db\n      host: localhost\n      pass: test_password\n      port: 5432\n      schema: test_schema\n      threads: 4\n      type: postgres\n      user: test_username\n  target: dev\n\"\"\"\n            )\n            mock_run_debug.assert_called_once()\n\n\nclass TestInitInsideOfProjectBase:\n    @pytest.fixture(scope=\"class\")\n    def project_name(self, unique_schema):\n        return f\"my_project_{unique_schema}\"\n\n\nclass TestInitOutsideOfProjectBase:\n    @pytest.fixture(scope=\"class\")\n    def project_name(self, unique_schema):\n        return f\"my_project_{unique_schema}\"\n\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setup(self, project):\n        # Start by removing the dbt_project.yml so that we're not in an existing project\n        os.remove(os.path.join(project.project_root, \"dbt_project.yml\"))\n\n\nclass TestInitOutsideOfProject(TestInitOutsideOfProjectBase):\n    @pytest.fixture(scope=\"class\")\n    def dbt_profile_data(self, unique_schema):\n        return {\n            \"test\": {\n                \"outputs\": {\n                    \"default2\": {\n                        \"type\": \"postgres\",\n                        \"threads\": 4,\n                        \"host\": \"localhost\",\n                        \"port\": int(os.getenv(\"POSTGRES_TEST_PORT\", 5432)),\n                        \"user\": os.getenv(\"POSTGRES_TEST_USER\", \"root\"),\n                        \"pass\": os.getenv(\"POSTGRES_TEST_PASS\", \"password\"),\n                        \"dbname\": os.getenv(\"POSTGRES_TEST_DATABASE\", \"dbt\"),\n                        \"schema\": unique_schema,\n                    },\n                    \"noaccess\": {\n                        \"type\": \"postgres\",\n                        \"threads\": 4,\n                        \"host\": \"localhost\",\n                        \"port\": int(os.getenv(\"POSTGRES_TEST_PORT\", 5432)),\n                        \"user\": \"noaccess\",\n                        \"pass\": \"password\",\n                        \"dbname\": os.getenv(\"POSTGRES_TEST_DATABASE\", \"dbt\"),\n                        \"schema\": unique_schema,\n                    },\n                },\n                \"target\": \"default2\",\n            },\n        }\n\n    @mock.patch(\"dbt.task.init.InitTask._run_debug\")\n    @mock.patch(\"dbt.task.init._get_adapter_plugin_names\")\n    @mock.patch(\"click.confirm\")\n    @mock.patch(\"click.prompt\")\n    def test_init_task_outside_of_project(\n        self,\n        mock_prompt,\n        mock_confirm,\n        mock_get_adapter,\n        mock_run_debug,\n        project,\n        project_name,\n        unique_schema,\n    ):\n        manager = Mock()\n        manager.attach_mock(mock_prompt, \"prompt\")\n        manager.attach_mock(mock_confirm, \"confirm\")\n        manager.prompt.side_effect = [\n            project_name,\n            1,\n            \"localhost\",\n            5432,\n            \"test_username\",\n            \"test_password\",\n            \"test_db\",\n            \"test_schema\",\n            4,\n        ]\n        mock_get_adapter.return_value = [project.adapter.type()]\n        run_dbt([\"init\"])\n\n        manager.assert_has_calls(\n            [\n                call.prompt(\"Enter a name for your project (letters, digits, underscore)\"),\n                call.prompt(\n                    \"Which database would you like to use?\\n[1] postgres\\n\\n(Don't see the one you want? https://docs.getdbt.com/docs/available-adapters)\\n\\nEnter a number\",\n                    type=click.INT,\n                ),\n                call.prompt(\n                    \"host (hostname for the instance)\", default=None, hide_input=False, type=None\n                ),\n                call.prompt(\"port\", default=5432, hide_input=False, type=click.INT),\n                call.prompt(\"user (dev username)\", default=None, hide_input=False, type=None),\n                call.prompt(\"pass (dev password)\", default=None, hide_input=True, type=None),\n                call.prompt(\n                    \"dbname (default database that dbt will build objects in)\",\n                    default=None,\n                    hide_input=False,\n                    type=None,\n                ),\n                call.prompt(\n                    \"schema (default schema that dbt will build objects in)\",\n                    default=None,\n                    hide_input=False,\n                    type=None,\n                ),\n                call.prompt(\"threads (1 or more)\", default=1, hide_input=False, type=click.INT),\n            ]\n        )\n\n        mock_run_debug.assert_called_once()\n\n        with open(os.path.join(project.profiles_dir, \"profiles.yml\"), \"r\") as f:\n            assert (\n                f.read()\n                == f\"\"\"{project_name}:\n  outputs:\n    dev:\n      dbname: test_db\n      host: localhost\n      pass: test_password\n      port: 5432\n      schema: test_schema\n      threads: 4\n      type: postgres\n      user: test_username\n  target: dev\ntest:\n  outputs:\n    default2:\n      dbname: dbt\n      host: localhost\n      pass: password\n      port: 5432\n      schema: {unique_schema}\n      threads: 4\n      type: postgres\n      user: root\n    noaccess:\n      dbname: dbt\n      host: localhost\n      pass: password\n      port: 5432\n      schema: {unique_schema}\n      threads: 4\n      type: postgres\n      user: noaccess\n  target: default2\n\"\"\"\n            )\n\n        with open(os.path.join(project.project_root, project_name, \"dbt_project.yml\"), \"r\") as f:\n            assert (\n                f.read()\n                == f\"\"\"\n# Name your project! Project names should contain only lowercase characters\n# and underscores. A good package name should reflect your organization's\n# name or the intended use of these models\nname: '{project_name}'\nversion: '1.0.0'\n\n# This setting configures which \"profile\" dbt uses for this project.\nprofile: '{project_name}'\n\n# These configurations specify where dbt should look for different types of files.\n# The `model-paths` config, for example, states that models in this project can be\n# found in the \"models/\" directory. You probably won't need to change these!\nmodel-paths: [\"models\"]\nanalysis-paths: [\"analyses\"]\ntest-paths: [\"tests\"]\nseed-paths: [\"seeds\"]\nmacro-paths: [\"macros\"]\nsnapshot-paths: [\"snapshots\"]\n\nclean-targets:         # directories to be removed by `dbt clean`\n  - \"target\"\n  - \"dbt_packages\"\n\n\n# Configuring models\n# Full documentation: https://docs.getdbt.com/docs/configuring-models\n\n# In this example config, we tell dbt to build all models in the example/\n# directory as views. These settings can be overridden in the individual model\n# files using the `{{{{ config(...) }}}}` macro.\nmodels:\n  {project_name}:\n    # Config indicated by + and applies to all files under models/example/\n    example:\n      +materialized: view\n\"\"\"\n            )\n\n\nclass TestInitInvalidProjectNameCLI(TestInitOutsideOfProjectBase):\n    @mock.patch(\"dbt.task.init._get_adapter_plugin_names\")\n    @mock.patch(\"click.confirm\")\n    @mock.patch(\"click.prompt\")\n    def test_init_invalid_project_name_cli(\n        self, mock_prompt, mock_confirm, mock_get_adapter, project_name, project\n    ):\n        manager = Mock()\n        manager.attach_mock(mock_prompt, \"prompt\")\n        manager.attach_mock(mock_confirm, \"confirm\")\n\n        invalid_name = \"name-with-hyphen\"\n        valid_name = project_name\n        manager.prompt.side_effect = [valid_name]\n        mock_get_adapter.return_value = [project.adapter.type()]\n\n        run_dbt([\"init\", invalid_name, \"--skip-profile-setup\"])\n        manager.assert_has_calls(\n            [\n                call.prompt(\"Enter a name for your project (letters, digits, underscore)\"),\n            ]\n        )\n\n\nclass TestInitInvalidProjectNamePrompt(TestInitOutsideOfProjectBase):\n    @mock.patch(\"dbt.task.init._get_adapter_plugin_names\")\n    @mock.patch(\"click.confirm\")\n    @mock.patch(\"click.prompt\")\n    def test_init_invalid_project_name_prompt(\n        self, mock_prompt, mock_confirm, mock_get_adapter, project_name, project\n    ):\n        manager = Mock()\n        manager.attach_mock(mock_prompt, \"prompt\")\n        manager.attach_mock(mock_confirm, \"confirm\")\n\n        invalid_name = \"name-with-hyphen\"\n        valid_name = project_name\n        manager.prompt.side_effect = [invalid_name, valid_name]\n        mock_get_adapter.return_value = [project.adapter.type()]\n\n        run_dbt([\"init\", \"--skip-profile-setup\"])\n        manager.assert_has_calls(\n            [\n                call.prompt(\"Enter a name for your project (letters, digits, underscore)\"),\n                call.prompt(\"Enter a name for your project (letters, digits, underscore)\"),\n            ]\n        )\n\n\nclass TestInitProvidedProjectNameAndSkipProfileSetup(TestInitOutsideOfProjectBase):\n    @mock.patch(\"dbt.task.init._get_adapter_plugin_names\")\n    @mock.patch(\"click.confirm\")\n    @mock.patch(\"click.prompt\")\n    def test_init_provided_project_name_and_skip_profile_setup(\n        self, mock_prompt, mock_confirm, mock_get, project, project_name\n    ):\n        manager = mock.Mock()\n        manager.attach_mock(mock_prompt, \"prompt\")\n        manager.attach_mock(mock_confirm, \"confirm\")\n        manager.prompt.side_effect = [\n            1,\n            \"localhost\",\n            5432,\n            \"test_username\",\n            \"test_password\",\n            \"test_db\",\n            \"test_schema\",\n            4,\n        ]\n        mock_get.return_value = [project.adapter.type()]\n\n        # provide project name through the init command\n        run_dbt([\"init\", project_name, \"--skip-profile-setup\"])\n        assert len(manager.mock_calls) == 0\n\n        with open(os.path.join(project.project_root, project_name, \"dbt_project.yml\"), \"r\") as f:\n            assert (\n                f.read()\n                == f\"\"\"\n# Name your project! Project names should contain only lowercase characters\n# and underscores. A good package name should reflect your organization's\n# name or the intended use of these models\nname: '{project_name}'\nversion: '1.0.0'\n\n# This setting configures which \"profile\" dbt uses for this project.\nprofile: '{project_name}'\n\n# These configurations specify where dbt should look for different types of files.\n# The `model-paths` config, for example, states that models in this project can be\n# found in the \"models/\" directory. You probably won't need to change these!\nmodel-paths: [\"models\"]\nanalysis-paths: [\"analyses\"]\ntest-paths: [\"tests\"]\nseed-paths: [\"seeds\"]\nmacro-paths: [\"macros\"]\nsnapshot-paths: [\"snapshots\"]\n\nclean-targets:         # directories to be removed by `dbt clean`\n  - \"target\"\n  - \"dbt_packages\"\n\n\n# Configuring models\n# Full documentation: https://docs.getdbt.com/docs/configuring-models\n\n# In this example config, we tell dbt to build all models in the example/\n# directory as views. These settings can be overridden in the individual model\n# files using the `{{{{ config(...) }}}}` macro.\nmodels:\n  {project_name}:\n    # Config indicated by + and applies to all files under models/example/\n    example:\n      +materialized: view\n\"\"\"\n            )\n\n\nclass TestInitInsideProjectAndSkipProfileSetup(TestInitInsideOfProjectBase):\n    @mock.patch(\"dbt.task.init.InitTask._run_debug\")\n    @mock.patch(\"dbt.task.init._get_adapter_plugin_names\")\n    @mock.patch(\"click.confirm\")\n    @mock.patch(\"click.prompt\")\n    def test_init_inside_project_and_skip_profile_setup(\n        self, mock_prompt, mock_confirm, mock_get, mock_debug, project, project_name\n    ):\n        manager = mock.Mock()\n        manager.attach_mock(mock_prompt, \"prompt\")\n        manager.attach_mock(mock_confirm, \"confirm\")\n\n        assert Path(\"dbt_project.yml\").exists()\n\n        # skip interactive profile setup\n        run_dbt([\"init\", \"--skip-profile-setup\"])\n        assert len(manager.mock_calls) == 0\n        mock_debug.assert_not_called()\n\n\nclass TestInitOutsideOfProjectWithSpecifiedProfile(TestInitOutsideOfProjectBase):\n    @mock.patch(\"dbt.task.init.InitTask._run_debug\")\n    @mock.patch(\"dbt.task.init._get_adapter_plugin_names\")\n    @mock.patch(\"click.prompt\")\n    def test_init_task_outside_of_project_with_specified_profile(\n        self,\n        mock_prompt,\n        mock_get_adapter,\n        mock_run_debug,\n        project,\n        project_name,\n        unique_schema,\n        dbt_profile_data,\n    ):\n        manager = Mock()\n        manager.attach_mock(mock_prompt, \"prompt\")\n        manager.prompt.side_effect = [\n            project_name,\n        ]\n        mock_get_adapter.return_value = [project.adapter.type()]\n        run_dbt([\"init\", \"--profile\", \"test\"])\n\n        manager.assert_has_calls(\n            [\n                call.prompt(\"Enter a name for your project (letters, digits, underscore)\"),\n            ]\n        )\n\n        # profiles.yml is NOT overwritten, so assert that the text matches that of the\n        # original fixture\n        with open(os.path.join(project.profiles_dir, \"profiles.yml\"), \"r\") as f:\n            assert f.read() == yaml.safe_dump(dbt_profile_data)\n\n        with open(os.path.join(project.project_root, project_name, \"dbt_project.yml\"), \"r\") as f:\n            assert (\n                f.read()\n                == f\"\"\"\n# Name your project! Project names should contain only lowercase characters\n# and underscores. A good package name should reflect your organization's\n# name or the intended use of these models\nname: '{project_name}'\nversion: '1.0.0'\n\n# This setting configures which \"profile\" dbt uses for this project.\nprofile: 'test'\n\n# These configurations specify where dbt should look for different types of files.\n# The `model-paths` config, for example, states that models in this project can be\n# found in the \"models/\" directory. You probably won't need to change these!\nmodel-paths: [\"models\"]\nanalysis-paths: [\"analyses\"]\ntest-paths: [\"tests\"]\nseed-paths: [\"seeds\"]\nmacro-paths: [\"macros\"]\nsnapshot-paths: [\"snapshots\"]\n\nclean-targets:         # directories to be removed by `dbt clean`\n  - \"target\"\n  - \"dbt_packages\"\n\n\n# Configuring models\n# Full documentation: https://docs.getdbt.com/docs/configuring-models\n\n# In this example config, we tell dbt to build all models in the example/\n# directory as views. These settings can be overridden in the individual model\n# files using the `{{{{ config(...) }}}}` macro.\nmodels:\n  {project_name}:\n    # Config indicated by + and applies to all files under models/example/\n    example:\n      +materialized: view\n\"\"\"\n            )\n\n            mock_run_debug.assert_called_once()\n\n\nclass TestInitOutsideOfProjectSpecifyingInvalidProfile(TestInitOutsideOfProjectBase):\n    @mock.patch(\"dbt.task.init._get_adapter_plugin_names\")\n    @mock.patch(\"click.prompt\")\n    def test_init_task_outside_project_specifying_invalid_profile_errors(\n        self, mock_prompt, mock_get_adapter, project, project_name\n    ):\n        manager = Mock()\n        manager.attach_mock(mock_prompt, \"prompt\")\n        manager.prompt.side_effect = [\n            project_name,\n        ]\n        mock_get_adapter.return_value = [project.adapter.type()]\n\n        with pytest.raises(DbtRuntimeError) as error:\n            run_dbt([\"init\", \"--profile\", \"invalid\"], expect_pass=False)\n            assert \"Could not find profile named invalid\" in str(error)\n\n        manager.assert_has_calls(\n            [\n                call.prompt(\"Enter a name for your project (letters, digits, underscore)\"),\n            ]\n        )\n\n\nclass TestInitOutsideOfProjectSpecifyingProfileNoProfilesYml(TestInitOutsideOfProjectBase):\n    @mock.patch(\"dbt.task.init._get_adapter_plugin_names\")\n    @mock.patch(\"click.prompt\")\n    def test_init_task_outside_project_specifying_profile_no_profiles_yml_errors(\n        self, mock_prompt, mock_get_adapter, project, project_name\n    ):\n        manager = Mock()\n        manager.attach_mock(mock_prompt, \"prompt\")\n        manager.prompt.side_effect = [\n            project_name,\n        ]\n        mock_get_adapter.return_value = [project.adapter.type()]\n\n        # Override responses on specific files, default to 'real world' if not overriden\n        original_isfile = os.path.isfile\n        with mock.patch(\n            \"os.path.isfile\",\n            new=lambda path: {\"profiles.yml\": False}.get(\n                os.path.basename(path), original_isfile(path)\n            ),\n        ):\n            with pytest.raises(DbtRuntimeError) as error:\n                run_dbt([\"init\", \"--profile\", \"test\"], expect_pass=False)\n                assert \"Could not find profile named invalid\" in str(error)\n\n        manager.assert_has_calls(\n            [\n                call.prompt(\"Enter a name for your project (letters, digits, underscore)\"),\n            ]\n        )\n\n\nclass TestInitRunsDebugAfterInit(TestInitInsideOfProjectBase):\n    @mock.patch(\"dbt.task.init._get_adapter_plugin_names\")\n    @mock.patch(\"click.confirm\")\n    @mock.patch(\"click.prompt\")\n    def test_debug_runs_after_init(self, mock_prompt, mock_confirm, mock_get_adapter, project):\n        \"\"\"Verify DebugTask is instantiated and run() is called after init with profile setup.\"\"\"\n        manager = Mock()\n        manager.attach_mock(mock_prompt, \"prompt\")\n        manager.attach_mock(mock_confirm, \"confirm\")\n        manager.confirm.side_effect = [\"y\"]\n        manager.prompt.side_effect = [\n            1,\n            \"localhost\",\n            5432,\n            \"test_user\",\n            \"test_password\",\n            \"test_db\",\n            \"test_schema\",\n            4,\n        ]\n        mock_get_adapter.return_value = [project.adapter.type()]\n\n        mock_debug_task_cls = Mock()\n\n        with mock.patch(\"dbt.task.debug.DebugTask\", mock_debug_task_cls):\n            run_dbt([\"init\"])\n\n        mock_debug_task_cls.return_value.run.assert_called_once()\n\n\nclass TestInitDebugSkippedWithSkipProfileSetup(TestInitInsideOfProjectBase):\n    @mock.patch(\"dbt.task.init.InitTask._run_debug\")\n    @mock.patch(\"dbt.task.init._get_adapter_plugin_names\")\n    @mock.patch(\"click.confirm\")\n    @mock.patch(\"click.prompt\")\n    def test_debug_skipped_with_skip_profile_setup(\n        self, mock_prompt, mock_confirm, mock_get_adapter, mock_run_debug, project\n    ):\n        \"\"\"Verify _run_debug is NOT called when --skip-profile-setup is used.\"\"\"\n        run_dbt([\"init\", \"--skip-profile-setup\"])\n        mock_run_debug.assert_not_called()\n\n\nclass TestInitSkipDebugFlag(TestInitInsideOfProjectBase):\n    @mock.patch(\"dbt.task.init._get_adapter_plugin_names\")\n    @mock.patch(\"click.confirm\")\n    @mock.patch(\"click.prompt\")\n    def test_debug_skipped_with_skip_debug_flag(\n        self, mock_prompt, mock_confirm, mock_get_adapter, project\n    ):\n        \"\"\"Verify DebugTask is NOT instantiated when --skip-debug is used.\"\"\"\n        manager = Mock()\n        manager.attach_mock(mock_prompt, \"prompt\")\n        manager.attach_mock(mock_confirm, \"confirm\")\n        manager.confirm.side_effect = [\"y\"]\n        manager.prompt.side_effect = [\n            1,\n            \"localhost\",\n            5432,\n            \"test_user\",\n            \"test_password\",\n            \"test_db\",\n            \"test_schema\",\n            4,\n        ]\n        mock_get_adapter.return_value = [project.adapter.type()]\n\n        mock_debug_task_cls = Mock()\n\n        with mock.patch(\"dbt.task.debug.DebugTask\", mock_debug_task_cls):\n            run_dbt([\"init\", \"--skip-debug\"])\n\n        mock_debug_task_cls.assert_not_called()\n\n    def test_run_debug_returns_none_when_skip_debug(self):\n        \"\"\"Verify _run_debug returns None when skip_debug is True.\"\"\"\n        task = Mock(spec=InitTask)\n        task.args = Mock(skip_debug=True)\n        assert InitTask._run_debug(task) is None\n\n\nclass TestInitDebugFailureDoesNotFailInit(TestInitInsideOfProjectBase):\n    @mock.patch(\"dbt.task.init._get_adapter_plugin_names\")\n    @mock.patch(\"click.confirm\")\n    @mock.patch(\"click.prompt\")\n    def test_debug_failure_does_not_fail_init(\n        self, mock_prompt, mock_confirm, mock_get_adapter, project\n    ):\n        \"\"\"Verify that if DebugTask.run() raises, init still succeeds.\"\"\"\n        manager = Mock()\n        manager.attach_mock(mock_prompt, \"prompt\")\n        manager.attach_mock(mock_confirm, \"confirm\")\n        manager.confirm.side_effect = [\"y\"]\n        manager.prompt.side_effect = [\n            1,\n            \"localhost\",\n            5432,\n            \"test_user\",\n            \"test_password\",\n            \"test_db\",\n            \"test_schema\",\n            4,\n        ]\n        mock_get_adapter.return_value = [project.adapter.type()]\n\n        mock_debug_task_cls = Mock()\n        mock_debug_task_cls.return_value.run.side_effect = Exception(\"connection failed\")\n\n        with mock.patch(\"dbt.task.debug.DebugTask\", mock_debug_task_cls):\n            # Should not raise — debug failure is informational only\n            run_dbt([\"init\"])\n"
  },
  {
    "path": "tests/functional/invalid_model_tests/test_invalid_models.py",
    "content": "import pytest\n\nfrom dbt.exceptions import CompilationError, ParsingError\nfrom dbt.tests.util import run_dbt\n\n# from `test/integration/011_invalid_model_tests`, invalid_model_tests\n\n#\n# Seeds\n#\n\nseeds__base_seed = \"\"\"\nfirst_name,last_name,email,gender,ip_address\nJack,Hunter,jhunter0@pbs.org,Male,59.80.20.168\nKathryn,Walker,kwalker1@ezinearticles.com,Female,194.121.179.35\nGerald,Ryan,gryan2@com.com,Male,11.3.212.243\nBonnie,Spencer,bspencer3@ameblo.jp,Female,216.32.196.175\nHarold,Taylor,htaylor4@people.com.cn,Male,253.10.246.136\nJacqueline,Griffin,jgriffin5@t.co,Female,16.13.192.220\nWanda,Arnold,warnold6@google.nl,Female,232.116.150.64\nCraig,Ortiz,cortiz7@sciencedaily.com,Male,199.126.106.13\nGary,Day,gday8@nih.gov,Male,35.81.68.186\nRose,Wright,rwright9@yahoo.co.jp,Female,236.82.178.100\n\"\"\"\n\n#\n# Properties\n#\n\nproperties__seed_types_yml = \"\"\"\nversion: 2\nseeds:\n  - name: seeds__base_seed\n    config:\n      +column_types:\n        first_name: varchar(50),\n        last_name:  varchar(50),\n        email:      varchar(50),\n        gender:     varchar(50),\n        ip_address: varchar(20)\n\n\"\"\"\n\n# see config in test class\nproperties__disabled_source_yml = \"\"\"\nversion: 2\nsources:\n  - name: test_source\n    schema: \"{{ target.schema }}\"\n    tables:\n      - name: test_table\n        identifier: seed\n\"\"\"\n\n#\n# Macros\n#\n\nmacros__bad_macros = \"\"\"\n{% macro some_macro(arg) %}\n    {{ arg }}\n{% endmacro %}\n\"\"\"\n\n#\n# Models\n#\n\nmodels__view_bad_enabled_value = \"\"\"\n{{\n  config(\n    enabled = 'false'\n  )\n}}\n\nselect * from {{ this.schema }}.seed\n\"\"\"\n\nmodels__view_disabled = \"\"\"\n{{\n  config(\n    enabled = False\n  )\n}}\n\nselect * from {{ this.schema }}.seed\n\"\"\"\n\nmodels__dependent_on_view = \"\"\"\nselect * from {{ ref('models__view_disabled') }}\n\"\"\"\n\nmodels__with_bad_macro = \"\"\"\n{{ some_macro(invalid='test') }}\nselect 1 as id\n\"\"\"\n\nmodels__referencing_disabled_source = \"\"\"\nselect * from {{ source('test_source', 'test_table') }}\n\"\"\"\n\n#\n# Tests\n#\n\n\nclass InvalidModelBase(object):\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\n            \"seeds__base_seed.csv\": seeds__base_seed,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def properties(self):\n        return {\n            \"properties__seed_types.yml\": properties__seed_types_yml,\n        }\n\n\nclass TestMalformedEnabledParam(InvalidModelBase):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"models__view_bad_enabled_value.sql\": models__view_bad_enabled_value,\n        }\n\n    def test_view_disabled(self, project):\n        with pytest.raises(ParsingError) as exc:\n            run_dbt([\"seed\"])\n\n        assert \"enabled\" in str(exc.value)\n\n\nclass TestReferencingDisabledModel(InvalidModelBase):\n    \"\"\"Expects that the upstream model is disabled\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"models__view_disabled.sql\": models__view_disabled,\n            \"models__dependent_on_view.sql\": models__dependent_on_view,\n        }\n\n    def test_referencing_disabled_model(self, project):\n        with pytest.raises(CompilationError) as exc:\n            run_dbt()\n\n        assert \"which is disabled\" in str(exc.value)\n\n\nclass TestMissingModelReference(InvalidModelBase):\n    \"\"\"Expects that the upstream model is not found\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"models__dependent_on_view.sql\": models__dependent_on_view}\n\n    def test_models_not_found(self, project):\n        with pytest.raises(CompilationError) as exc:\n            run_dbt()\n\n        assert \"which was not found\" in str(exc.value)\n\n\nclass TestInvalidMacroCall(InvalidModelBase):\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"macros__bad_macros.sql\": macros__bad_macros}\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"models__with_bad_macro.sql\": models__with_bad_macro}\n\n    def test_with_invalid_macro_call(self, project):\n        with pytest.raises(CompilationError) as exc:\n            run_dbt([\"compile\"])\n\n        assert \"macro 'dbt_macro__some_macro' takes no keyword argument 'invalid'\" in str(\n            exc.value\n        )\n\n\nclass TestInvalidDisabledSource(InvalidModelBase):\n    @pytest.fixture(scope=\"class\")\n    def properties(self):\n        return {\n            \"properties__seed_types.yml\": properties__seed_types_yml,\n            \"properties__disabled_source.yml\": properties__disabled_source_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"models__referencing_disabled_source.sql\": models__referencing_disabled_source}\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"sources\": {\n                \"test\": {\n                    \"enabled\": False,\n                }\n            }\n        }\n\n    def test_postgres_source_disabled(self, project):\n        with pytest.raises(CompilationError) as exc:\n            run_dbt()\n\n        assert \"which is disabled\" in str(exc.value)\n\n\nclass TestInvalidMissingSource(InvalidModelBase):\n    \"\"\"like TestInvalidDisabledSource but source omitted entirely\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"models__referencing_disabled_source.sql\": models__referencing_disabled_source}\n\n    def test_source_missing(self, project):\n        with pytest.raises(CompilationError) as exc:\n            run_dbt()\n\n        assert \"which was not found\" in str(exc.value)\n"
  },
  {
    "path": "tests/functional/invalid_model_tests/test_model_logging.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt_and_capture\n\nwarnings_sql = \"\"\"\n{{ config(group='my_group') }}\n{% do exceptions.warn('warning: everything is terrible but not that terrible') %}\n{{ exceptions.warn(\"warning: everything is terrible but not that terrible\") }}\nselect 1 as id\n\"\"\"\n\nschema_yml = \"\"\"\nversion: 2\ngroups:\n  - name: my_group\n    owner:\n      name: group_owner\n\"\"\"\n\n\nclass TestModelLogging:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"warnings.sql\": warnings_sql,\n            \"schema.yml\": schema_yml,\n        }\n\n    def test_warn(self, project):\n        results, log_output = run_dbt_and_capture([\"run\", \"--log-format\", \"json\"])\n        log_lines = log_output.split(\"\\n\")\n\n        log_lines_with_warning = [line for line in log_lines if \"JinjaLogWarning\" in line]\n        assert len(log_lines_with_warning) == 4\n        assert all(\"everything is terrible\" in line for line in log_lines_with_warning)\n\n        log_lines_with_group = [line for line in log_lines if \"LogModelResult\" in line]\n        assert len(log_lines_with_group) == 1\n        assert \"group_owner\" in log_lines_with_group[0]\n        assert \"my_group\" in log_lines_with_group[0]\n"
  },
  {
    "path": "tests/functional/list/fixtures.py",
    "content": "import pytest\n\nfrom dbt.tests.fixtures.project import write_project_files\n\nsnapshots__snapshot_sql = \"\"\"\n{% snapshot my_snapshot %}\n    {{\n        config(\n            target_database=var('target_database', database),\n            target_schema=schema,\n            unique_key='id',\n            strategy='timestamp',\n            updated_at='updated_at',\n        )\n    }}\n    select * from {{database}}.{{schema}}.seed\n{% endsnapshot %}\n\n\"\"\"\n\ntests__t_sql = \"\"\"\nselect 1 as id limit 0\n\n\"\"\"\n\nmodels__schema_yml = \"\"\"\nversion: 2\nmodels:\n  - name: outer\n    description: The outer table\n    columns:\n      - name: id\n        description: The id value\n        data_tests:\n          - unique\n          - not_null\n\nsources:\n  - name: my_source\n    tables:\n      - name: my_table\n\n\"\"\"\n\nmodels__ephemeral_sql = \"\"\"\n\n{{ config(materialized='ephemeral') }}\n\nselect\n  1 as id,\n  {{ dbt.date_trunc('day', dbt.current_timestamp()) }} as created_at\n\n\"\"\"\n\nmodels__metric_flow = \"\"\"\n\nselect\n  {{ dbt.date_trunc('day', dbt.current_timestamp()) }} as date_day\n\n\"\"\"\n\nmodels__incremental_sql = \"\"\"\n{{\n  config(\n    materialized = \"incremental\",\n    incremental_strategy = \"delete+insert\",\n  )\n}}\n\nselect * from {{ ref('seed') }}\n\n{% if is_incremental() %}\n    where a > (select max(a) from {{this}})\n{% endif %}\n\n\"\"\"\n\nmodels__docs_md = \"\"\"\n{% docs my_docs %}\n  some docs\n{% enddocs %}\n\n\"\"\"\n\nmodels__outer_sql = \"\"\"\nselect * from {{ ref('ephemeral') }}\n\n\"\"\"\n\nmodels__sub__inner_sql = \"\"\"\nselect * from {{ ref('outer') }}\n\n\"\"\"\n\nmacros__macro_stuff_sql = \"\"\"\n{% macro cool_macro() %}\n  wow!\n{% endmacro %}\n\n{% macro other_cool_macro(a, b) %}\n  cool!\n{% endmacro %}\n\n\"\"\"\n\nseeds__seed_csv = \"\"\"a,b\n1,2\n\"\"\"\n\nanalyses__a_sql = \"\"\"\nselect 4 as id\n\n\"\"\"\n\nsemantic_models__sm_yml = \"\"\"\nsemantic_models:\n  - name: my_sm\n    model: ref('outer')\n    defaults:\n      agg_time_dimension: created_at\n    entities:\n      - name: my_entity\n        type: primary\n        expr: id\n    dimensions:\n      - name: created_at\n        type: time\n        type_params:\n          time_granularity: day\n    measures:\n      - name: total_outer_count\n        agg: count\n        expr: 1\n\n\"\"\"\n\nmetrics__m_yml = \"\"\"\nmetrics:\n  - name: total_outer\n    type: simple\n    description: The total count of outer\n    label: Total Outer\n    type_params:\n      measure: total_outer_count\n\"\"\"\n\n\nsaved_queries__sq_yml = \"\"\"\nsaved_queries:\n  - name: my_saved_query\n    label: My Saved Query\n    query_params:\n        metrics:\n            - total_outer\n        group_by:\n            - \"Dimension('my_entity__created_at')\"\n    exports:\n        - name: my_export\n          config:\n            alias: my_export_alias\n            export_as: table\n            schema: my_export_schema_name\n\"\"\"\n\n\n@pytest.fixture(scope=\"class\")\ndef snapshots():\n    return {\"snapshot.sql\": snapshots__snapshot_sql}\n\n\n@pytest.fixture(scope=\"class\")\ndef tests():\n    return {\"t.sql\": tests__t_sql}\n\n\n@pytest.fixture(scope=\"class\")\ndef models():\n    return {\n        \"schema.yml\": models__schema_yml,\n        \"ephemeral.sql\": models__ephemeral_sql,\n        \"incremental.sql\": models__incremental_sql,\n        \"docs.md\": models__docs_md,\n        \"outer.sql\": models__outer_sql,\n        \"metricflow_time_spine.sql\": models__metric_flow,\n        \"sq.yml\": saved_queries__sq_yml,\n        \"sm.yml\": semantic_models__sm_yml,\n        \"m.yml\": metrics__m_yml,\n        \"sub\": {\"inner.sql\": models__sub__inner_sql},\n    }\n\n\n@pytest.fixture(scope=\"class\")\ndef macros():\n    return {\"macro_stuff.sql\": macros__macro_stuff_sql}\n\n\n@pytest.fixture(scope=\"class\")\ndef seeds():\n    return {\"seed.csv\": seeds__seed_csv}\n\n\n@pytest.fixture(scope=\"class\")\ndef analyses():\n    return {\"a.sql\": analyses__a_sql}\n\n\n@pytest.fixture(scope=\"class\")\ndef semantic_models():\n    return {\"sm.yml\": semantic_models__sm_yml}\n\n\n@pytest.fixture(scope=\"class\")\ndef metrics():\n    return {\"m.yml\": metrics__m_yml}\n\n\n@pytest.fixture(scope=\"class\")\ndef saved_queries():\n    return {\"sq.yml\": saved_queries__sq_yml}\n\n\n@pytest.fixture(scope=\"class\")\ndef project_files(\n    project_root,\n    snapshots,\n    tests,\n    models,\n    macros,\n    seeds,\n    analyses,\n):\n    write_project_files(project_root, \"snapshots\", snapshots)\n    write_project_files(project_root, \"tests\", tests)\n    write_project_files(project_root, \"models\", models)\n    write_project_files(project_root, \"macros\", macros)\n    write_project_files(project_root, \"seeds\", seeds)\n    write_project_files(project_root, \"analyses\", analyses)\n"
  },
  {
    "path": "tests/functional/list/test_commands.py",
    "content": "import shutil\n\nimport pytest\n\nfrom dbt.artifacts.resources.types import NodeType\nfrom dbt.cli.main import dbtRunner\nfrom dbt.cli.types import Command\nfrom dbt.events.types import NoNodesSelected\nfrom dbt.tests.util import run_dbt\nfrom dbt_common.events.event_catcher import EventCatcher\n\n\"\"\"\nTesting different commands against the happy path fixture\n\nThe general flow\n1. Declare the commands to be tested\n2. Write a paramaterized test ensure a given command reaches causes and associated desired state.\n\"\"\"\n\n# These are commands we're skipping as they don't make sense or don't work with the\n# happy path fixture currently\ncommands_to_skip = {\n    \"clone\",\n    \"generate\",\n    \"server\",\n    \"init\",\n    \"list\",\n    \"run-operation\",\n    \"show\",\n    \"snapshot\",\n    \"freshness\",\n    \"serve\",  # this was actually serving up docs and caused issues locally\n}\n\n# Commands to happy path test\ncommands = [command.to_list() for command in Command if command.value not in commands_to_skip]\n\n\nclass TestRunCommands:\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def drop_snapshots(self, happy_path_project, project_root: str) -> None:\n        \"\"\"The snapshots are erroring out, so lets drop them.\n\n        Seems to be database related. Ideally snapshots should work in these tests. It's a bad sign that they don't. That\n        may have more to do with our fixture setup than the source code though.\n\n        Note: that the `happy_path_fixture_files` are a _class_ based fixture. Thus although this fixture _modifies_ the\n        files available to the happy path project, it doesn't affect that fixture for tests in other test classes.\n        \"\"\"\n\n        shutil.rmtree(f\"{project_root}/snapshots\")\n\n    def test_run_commmand(\n        self,\n        happy_path_project,\n    ):\n        for command in commands:\n            run_dbt(command)\n\n\n\"\"\"\nTesting command interactions with specific node types\n\nThe general flow\n1. Declare resource (node) types to be tested\n2. Write a parameterized test that ensures commands interact successfully with each resource type\n\"\"\"\n\n# TODO: Figure out which of these are just missing from the happy path fixture vs which ones aren't selectable\nskipped_resource_types = {\n    \"analysis\",\n    \"operation\",\n    \"rpc\",\n    \"sql_operation\",\n    \"doc\",\n    \"macro\",\n    \"exposure\",\n    \"group\",\n    \"unit_test\",\n    \"fixture\",\n}\nresource_types = [\n    node_type.value for node_type in NodeType if node_type.value not in skipped_resource_types\n]\n\n\nclass TestSelectResourceType:\n    @pytest.fixture(scope=\"function\")\n    def catcher(self) -> EventCatcher:\n        return EventCatcher(event_to_catch=NoNodesSelected)\n\n    @pytest.fixture(scope=\"function\")\n    def runner(self, catcher: EventCatcher) -> dbtRunner:\n        return dbtRunner(callbacks=[catcher.catch])\n\n    @pytest.mark.parametrize(\"resource_type\", resource_types)\n    def test_select_by_resource_type(\n        self,\n        resource_type: str,\n        happy_path_project,\n        runner: dbtRunner,\n        catcher: EventCatcher,\n    ) -> None:\n        runner.invoke([\"list\", \"--select\", f\"resource_type:{resource_type}\"])\n        assert len(catcher.caught_events) == 0\n"
  },
  {
    "path": "tests/functional/list/test_list.py",
    "content": "import json\nimport os\n\nfrom dbt.tests.util import run_dbt\nfrom tests.functional.fixtures.happy_path_fixture import (  # noqa: F401\n    happy_path_project,\n    happy_path_project_files,\n)\n\n# Marker to allow some objects to skip full comparison when a full comparison is\n# unlikely to improve practical test effectiveness.\nANY = object()\n\n\nclass TestList:\n    def dir(self, value):\n        return os.path.normpath(value)\n\n    def test_packages_install_path_does_not_exist(self, happy_path_project):  # noqa: F811\n        run_dbt([\"list\"])\n        packages_install_path = \"dbt_packages\"\n\n        # the packages-install-path should not be created by `dbt list`\n        assert not os.path.exists(packages_install_path)\n\n    def run_dbt_ls(self, args=None, expect_pass=True):\n        full_args = [\"ls\"]\n        if args is not None:\n            full_args += args\n        result = run_dbt(args=full_args, expect_pass=expect_pass)\n\n        return result\n\n    def assert_json_equal(self, json_str, expected):\n        assert json.loads(json_str) == expected\n\n    def expect_given_output(self, args, expectations):\n        for key, values in expectations.items():\n            ls_result = self.run_dbt_ls(args + [\"--output\", key])\n            if not isinstance(values, (list, tuple)):\n                values = [values]\n            assert len(ls_result) == len(values)\n            for got, expected in zip(ls_result, values):\n                if key == \"json\":\n                    if expected != ANY:\n                        self.assert_json_equal(got, expected)\n                else:\n                    assert got == expected\n\n    def expect_snapshot_output(self, happy_path_project):  # noqa: F811\n        expectations = {\n            \"name\": [\"my_snapshot\", \"snapshot_2\", \"snapshot_3\"],\n            \"selector\": [\"test.snapshot.my_snapshot\", \"test.snapshot_2\", \"test.snapshot_3\"],\n            \"json\": [\n                {\n                    \"name\": \"my_snapshot\",\n                    \"package_name\": \"test\",\n                    \"depends_on\": {\"nodes\": [], \"macros\": []},\n                    \"tags\": [],\n                    \"config\": {\n                        \"enabled\": True,\n                        \"group\": None,\n                        \"materialized\": \"snapshot\",\n                        \"post-hook\": [],\n                        \"tags\": [],\n                        \"pre-hook\": [],\n                        \"quoting\": {},\n                        \"column_types\": {},\n                        \"persist_docs\": {},\n                        \"database\": happy_path_project.database,\n                        \"schema\": happy_path_project.test_schema,\n                        \"dbt_valid_to_current\": None,\n                        \"snapshot_meta_column_names\": {\n                            \"dbt_scd_id\": None,\n                            \"dbt_updated_at\": None,\n                            \"dbt_valid_from\": None,\n                            \"dbt_valid_to\": None,\n                            \"dbt_is_deleted\": None,\n                        },\n                        \"unique_key\": \"id\",\n                        \"strategy\": \"timestamp\",\n                        \"updated_at\": \"updated_at\",\n                        \"full_refresh\": None,\n                        \"target_database\": None,\n                        \"target_schema\": None,\n                        \"alias\": None,\n                        \"check_cols\": None,\n                        \"on_schema_change\": \"ignore\",\n                        \"on_configuration_change\": \"apply\",\n                        \"meta\": {},\n                        \"grants\": {},\n                        \"packages\": [],\n                        \"incremental_strategy\": None,\n                        \"docs\": {\"node_color\": None, \"show\": True},\n                        \"contract\": {\"enforced\": False, \"alias_types\": True},\n                        \"event_time\": None,\n                        \"lookback\": 1,\n                        \"batch_size\": None,\n                        \"begin\": None,\n                        \"concurrent_batches\": None,\n                    },\n                    \"unique_id\": \"snapshot.test.my_snapshot\",\n                    \"original_file_path\": normalize(\"snapshots/snapshot.sql\"),\n                    \"alias\": \"my_snapshot\",\n                    \"resource_type\": \"snapshot\",\n                },\n                ANY,\n                ANY,\n            ],\n            \"path\": [\n                self.dir(\"snapshots/snapshot.sql\"),\n                self.dir(\"snapshots/snapshot_2.yml\"),\n                self.dir(\"snapshots/snapshot_3.yml\"),\n            ],\n        }\n        self.expect_given_output([\"--resource-type\", \"snapshot\"], expectations)\n\n    def expect_analyses_output(self):\n        expectations = {\n            \"name\": \"a\",\n            \"selector\": \"test.analysis.a\",\n            \"json\": {\n                \"name\": \"a\",\n                \"package_name\": \"test\",\n                \"depends_on\": {\"nodes\": [], \"macros\": []},\n                \"tags\": [\"tag\"],\n                \"config\": {\n                    \"enabled\": True,\n                    \"group\": \"finance\",\n                    \"materialized\": \"view\",\n                    \"post-hook\": [],\n                    \"tags\": [\"tag\"],\n                    \"pre-hook\": [],\n                    \"quoting\": {},\n                    \"column_types\": {},\n                    \"persist_docs\": {},\n                    \"full_refresh\": None,\n                    \"on_schema_change\": \"ignore\",\n                    \"on_configuration_change\": \"apply\",\n                    \"database\": None,\n                    \"schema\": None,\n                    \"alias\": None,\n                    \"meta\": {\"test\": 1},\n                    \"unique_key\": None,\n                    \"grants\": {},\n                    \"packages\": [],\n                    \"incremental_strategy\": None,\n                    \"docs\": {\"node_color\": \"purple\", \"show\": True},\n                    \"contract\": {\"enforced\": False, \"alias_types\": True},\n                    \"event_time\": None,\n                    \"lookback\": 1,\n                    \"batch_size\": None,\n                    \"begin\": None,\n                    \"concurrent_batches\": None,\n                },\n                \"unique_id\": \"analysis.test.a\",\n                \"original_file_path\": normalize(\"analyses/a.sql\"),\n                \"alias\": \"a\",\n                \"resource_type\": \"analysis\",\n            },\n            \"path\": self.dir(\"analyses/a.sql\"),\n        }\n        self.expect_given_output([\"--resource-type\", \"analysis\"], expectations)\n\n    def expect_model_output(self):\n        expectations = {\n            \"name\": (\n                \"ephemeral\",\n                \"incremental\",\n                \"inner\",\n                \"metricflow_time_spine\",\n                \"metricflow_time_spine_second\",\n                \"model_to_unit_test\",\n                \"model_with_lots_of_schema_configs\",\n                \"outer\",\n                \"snapshot_source\",\n            ),\n            \"selector\": (\n                \"test.ephemeral\",\n                \"test.incremental\",\n                \"test.sub.inner\",\n                \"test.metricflow_time_spine\",\n                \"test.metricflow_time_spine_second\",\n                \"test.model_to_unit_test\",\n                \"test.model_with_lots_of_schema_configs\",\n                \"test.outer\",\n                \"test.snapshot_source\",\n            ),\n            \"json\": (\n                {\n                    \"name\": \"ephemeral\",\n                    \"package_name\": \"test\",\n                    \"depends_on\": {\n                        \"nodes\": [],\n                        \"macros\": [\"macro.dbt.current_timestamp\", \"macro.dbt.date_trunc\"],\n                    },\n                    \"tags\": [],\n                    \"config\": {\n                        \"enabled\": True,\n                        \"group\": None,\n                        \"materialized\": \"ephemeral\",\n                        \"post-hook\": [],\n                        \"tags\": [],\n                        \"pre-hook\": [],\n                        \"quoting\": {},\n                        \"column_types\": {},\n                        \"persist_docs\": {},\n                        \"full_refresh\": None,\n                        \"unique_key\": None,\n                        \"on_schema_change\": \"ignore\",\n                        \"on_configuration_change\": \"apply\",\n                        \"database\": None,\n                        \"schema\": None,\n                        \"alias\": None,\n                        \"meta\": {},\n                        \"grants\": {},\n                        \"packages\": [],\n                        \"incremental_strategy\": None,\n                        \"docs\": {\"node_color\": None, \"show\": True},\n                        \"contract\": {\"enforced\": False, \"alias_types\": True},\n                        \"access\": \"protected\",\n                        \"event_time\": None,\n                        \"lookback\": 1,\n                        \"batch_size\": None,\n                        \"begin\": None,\n                        \"concurrent_batches\": None,\n                        \"freshness\": None,\n                    },\n                    \"original_file_path\": normalize(\"models/ephemeral.sql\"),\n                    \"unique_id\": \"model.test.ephemeral\",\n                    \"alias\": \"ephemeral\",\n                    \"resource_type\": \"model\",\n                },\n                {\n                    \"name\": \"incremental\",\n                    \"package_name\": \"test\",\n                    \"depends_on\": {\n                        \"nodes\": [\"seed.test.seed\"],\n                        \"macros\": [\"macro.dbt.is_incremental\"],\n                    },\n                    \"tags\": [],\n                    \"config\": {\n                        \"enabled\": True,\n                        \"group\": None,\n                        \"materialized\": \"incremental\",\n                        \"post-hook\": [],\n                        \"tags\": [],\n                        \"pre-hook\": [],\n                        \"quoting\": {},\n                        \"column_types\": {},\n                        \"persist_docs\": {},\n                        \"full_refresh\": None,\n                        \"unique_key\": None,\n                        \"on_schema_change\": \"ignore\",\n                        \"on_configuration_change\": \"apply\",\n                        \"database\": None,\n                        \"schema\": None,\n                        \"alias\": None,\n                        \"meta\": {},\n                        \"grants\": {},\n                        \"packages\": [],\n                        \"incremental_strategy\": \"delete+insert\",\n                        \"docs\": {\"node_color\": None, \"show\": True},\n                        \"contract\": {\"enforced\": False, \"alias_types\": True},\n                        \"access\": \"protected\",\n                        \"event_time\": None,\n                        \"lookback\": 1,\n                        \"batch_size\": None,\n                        \"begin\": None,\n                        \"concurrent_batches\": None,\n                        \"freshness\": None,\n                    },\n                    \"original_file_path\": normalize(\"models/incremental.sql\"),\n                    \"unique_id\": \"model.test.incremental\",\n                    \"alias\": \"incremental\",\n                    \"resource_type\": \"model\",\n                },\n                {\n                    \"name\": \"inner\",\n                    \"package_name\": \"test\",\n                    \"depends_on\": {\n                        \"nodes\": [\"model.test.outer\"],\n                        \"macros\": [],\n                    },\n                    \"tags\": [],\n                    \"config\": {\n                        \"enabled\": True,\n                        \"group\": None,\n                        \"materialized\": \"view\",\n                        \"post-hook\": [],\n                        \"tags\": [],\n                        \"pre-hook\": [],\n                        \"quoting\": {},\n                        \"column_types\": {},\n                        \"persist_docs\": {},\n                        \"full_refresh\": None,\n                        \"unique_key\": None,\n                        \"on_schema_change\": \"ignore\",\n                        \"on_configuration_change\": \"apply\",\n                        \"database\": None,\n                        \"schema\": None,\n                        \"alias\": None,\n                        \"meta\": {},\n                        \"grants\": {},\n                        \"packages\": [],\n                        \"incremental_strategy\": None,\n                        \"docs\": {\"node_color\": None, \"show\": True},\n                        \"contract\": {\"enforced\": False, \"alias_types\": True},\n                        \"access\": \"protected\",\n                        \"event_time\": None,\n                        \"lookback\": 1,\n                        \"batch_size\": None,\n                        \"begin\": None,\n                        \"concurrent_batches\": None,\n                        \"freshness\": None,\n                    },\n                    \"original_file_path\": normalize(\"models/sub/inner.sql\"),\n                    \"unique_id\": \"model.test.inner\",\n                    \"alias\": \"inner\",\n                    \"resource_type\": \"model\",\n                },\n                {\n                    \"name\": \"metricflow_time_spine\",\n                    \"package_name\": \"test\",\n                    \"depends_on\": {\n                        \"nodes\": [],\n                        \"macros\": [\"macro.dbt.current_timestamp\", \"macro.dbt.date_trunc\"],\n                    },\n                    \"config\": {\n                        \"enabled\": True,\n                        \"group\": \"finance\",\n                        \"materialized\": \"view\",\n                        \"post-hook\": [\n                            {\n                                \"sql\": \"SELECT 'string_post_hook' as my_post_hook;\",\n                                \"transaction\": True,\n                                \"index\": None,\n                            }\n                        ],\n                        \"tags\": [\"list\", \"of\", \"tags\"],\n                        \"pre-hook\": [\n                            {\n                                \"sql\": \"SELECT 'string_pre_hook' as my_pre_hook;\",\n                                \"transaction\": True,\n                                \"index\": None,\n                            }\n                        ],\n                        \"quoting\": {},\n                        \"column_types\": {},\n                        \"persist_docs\": {},\n                        \"full_refresh\": None,\n                        \"unique_key\": None,\n                        \"on_schema_change\": \"ignore\",\n                        \"on_configuration_change\": \"apply\",\n                        \"database\": None,\n                        \"schema\": None,\n                        \"alias\": None,\n                        \"meta\": {},\n                        \"grants\": {},\n                        \"packages\": [],\n                        \"incremental_strategy\": None,\n                        \"docs\": {\"node_color\": None, \"show\": True},\n                        \"contract\": {\"enforced\": False, \"alias_types\": True},\n                        \"access\": \"protected\",\n                        \"event_time\": None,\n                        \"lookback\": 1,\n                        \"batch_size\": None,\n                        \"begin\": None,\n                        \"concurrent_batches\": None,\n                        \"freshness\": None,\n                    },\n                    \"original_file_path\": normalize(\"models/metricflow_time_spine.sql\"),\n                    \"unique_id\": \"model.test.metricflow_time_spine\",\n                    \"alias\": \"metricflow_time_spine\",\n                    \"resource_type\": \"model\",\n                    \"tags\": [\"list\", \"of\", \"tags\"],\n                },\n                {\n                    \"name\": \"metricflow_time_spine_second\",\n                    \"package_name\": \"test\",\n                    \"depends_on\": {\n                        \"nodes\": [],\n                        \"macros\": [\"macro.dbt.current_timestamp\", \"macro.dbt.date_trunc\"],\n                    },\n                    \"tags\": [],\n                    \"config\": {\n                        \"enabled\": True,\n                        \"group\": None,\n                        \"materialized\": \"view\",\n                        \"post-hook\": [],\n                        \"tags\": [],\n                        \"pre-hook\": [],\n                        \"quoting\": {},\n                        \"column_types\": {},\n                        \"persist_docs\": {},\n                        \"full_refresh\": None,\n                        \"unique_key\": None,\n                        \"on_schema_change\": \"ignore\",\n                        \"on_configuration_change\": \"apply\",\n                        \"database\": None,\n                        \"schema\": None,\n                        \"alias\": None,\n                        \"meta\": {},\n                        \"grants\": {},\n                        \"packages\": [],\n                        \"incremental_strategy\": None,\n                        \"docs\": {\"node_color\": None, \"show\": True},\n                        \"contract\": {\"enforced\": False, \"alias_types\": True},\n                        \"access\": \"protected\",\n                        \"event_time\": \"ts_second\",\n                        \"lookback\": 1,\n                        \"batch_size\": None,\n                        \"begin\": None,\n                        \"concurrent_batches\": None,\n                        \"freshness\": None,\n                    },\n                    \"original_file_path\": normalize(\"models/metricflow_time_spine_second.sql\"),\n                    \"unique_id\": \"model.test.metricflow_time_spine_second\",\n                    \"alias\": \"metricflow_time_spine_second\",\n                    \"resource_type\": \"model\",\n                },\n                {\n                    \"alias\": \"model_to_unit_test\",\n                    \"config\": {\n                        \"access\": \"protected\",\n                        \"alias\": None,\n                        \"batch_size\": None,\n                        \"begin\": None,\n                        \"column_types\": {},\n                        \"concurrent_batches\": None,\n                        \"contract\": {\"alias_types\": True, \"enforced\": False},\n                        \"database\": None,\n                        \"docs\": {\"node_color\": None, \"show\": True},\n                        \"enabled\": True,\n                        \"event_time\": None,\n                        \"freshness\": None,\n                        \"full_refresh\": None,\n                        \"grants\": {},\n                        \"group\": None,\n                        \"incremental_strategy\": None,\n                        \"lookback\": 1,\n                        \"materialized\": \"table\",\n                        \"meta\": {},\n                        \"on_configuration_change\": \"apply\",\n                        \"on_schema_change\": \"ignore\",\n                        \"packages\": [],\n                        \"persist_docs\": {},\n                        \"post-hook\": [],\n                        \"pre-hook\": [],\n                        \"quoting\": {},\n                        \"schema\": None,\n                        \"tags\": [],\n                        \"unique_key\": None,\n                    },\n                    \"depends_on\": {\"macros\": [], \"nodes\": [\"seed.test.seed\"]},\n                    \"name\": \"model_to_unit_test\",\n                    \"original_file_path\": normalize(\"models/model_to_unit_test.sql\"),\n                    \"package_name\": \"test\",\n                    \"resource_type\": \"model\",\n                    \"tags\": [],\n                    \"unique_id\": \"model.test.model_to_unit_test\",\n                },\n                {\n                    \"name\": \"model_with_lots_of_schema_configs\",\n                    \"resource_type\": \"model\",\n                    \"package_name\": \"test\",\n                    \"original_file_path\": normalize(\n                        \"models/model_with_lots_of_schema_configs.sql\"\n                    ),\n                    \"unique_id\": \"model.test.model_with_lots_of_schema_configs\",\n                    \"alias\": \"outer_alias\",\n                    \"config\": {\n                        \"enabled\": True,\n                        \"access\": \"public\",\n                        \"alias\": \"outer_alias\",\n                        \"schema\": \"test\",\n                        \"sql_header\": \"SELECT 1 as header;\",\n                        \"database\": \"dbt\",\n                        \"docs\": {\"node_color\": \"purple\", \"show\": True},\n                        \"event_time\": None,\n                        \"tags\": [\"string_tag\"],\n                        \"meta\": {\"my_custom_property\": \"string_meta\"},\n                        \"group\": None,\n                        \"materialized\": \"table\",\n                        \"incremental_strategy\": None,\n                        \"batch_size\": \"day\",\n                        \"lookback\": 5,\n                        \"begin\": \"2020-01-01\",\n                        \"persist_docs\": {\"columns\": True, \"relation\": True},\n                        \"post-hook\": [\n                            {\n                                \"sql\": \"SELECT 'string_post_hook' as my_post_hook;\",\n                                \"transaction\": True,\n                                \"index\": None,\n                            }\n                        ],\n                        \"pre-hook\": [\n                            {\n                                \"sql\": \"SELECT 'string_pre_hook' as my_pre_hook;\",\n                                \"transaction\": True,\n                                \"index\": None,\n                            }\n                        ],\n                        \"quoting\": {},\n                        \"column_types\": {},\n                        \"concurrent_batches\": False,\n                        \"contract\": {\"alias_types\": True, \"enforced\": False},\n                        \"full_refresh\": False,\n                        \"unique_key\": \"id\",\n                        \"on_schema_change\": \"ignore\",\n                        \"on_configuration_change\": \"apply\",\n                        \"grants\": {\"select\": [\"root\"]},\n                        \"packages\": [],\n                        \"freshness\": None,\n                    },\n                    \"depends_on\": {\n                        \"macros\": [],\n                        \"nodes\": [\"source.test.my_source.my_table\", \"model.test.ephemeral\"],\n                    },\n                    \"tags\": [\"string_tag\"],\n                },\n                {\n                    \"name\": \"outer\",\n                    \"package_name\": \"test\",\n                    \"depends_on\": {\n                        \"nodes\": [\"model.test.ephemeral\"],\n                        \"macros\": [],\n                    },\n                    \"tags\": [],\n                    \"config\": {\n                        \"enabled\": True,\n                        \"group\": None,\n                        \"materialized\": \"view\",\n                        \"post-hook\": [],\n                        \"tags\": [],\n                        \"pre-hook\": [],\n                        \"quoting\": {},\n                        \"column_types\": {},\n                        \"persist_docs\": {},\n                        \"full_refresh\": None,\n                        \"unique_key\": None,\n                        \"on_schema_change\": \"ignore\",\n                        \"on_configuration_change\": \"apply\",\n                        \"database\": None,\n                        \"schema\": None,\n                        \"alias\": None,\n                        \"meta\": {},\n                        \"grants\": {},\n                        \"packages\": [],\n                        \"incremental_strategy\": None,\n                        \"docs\": {\"node_color\": None, \"show\": True},\n                        \"contract\": {\"enforced\": False, \"alias_types\": True},\n                        \"access\": \"protected\",\n                        \"event_time\": None,\n                        \"lookback\": 1,\n                        \"batch_size\": None,\n                        \"begin\": None,\n                        \"concurrent_batches\": None,\n                        \"freshness\": None,\n                    },\n                    \"original_file_path\": normalize(\"models/outer.sql\"),\n                    \"unique_id\": \"model.test.outer\",\n                    \"alias\": \"outer\",\n                    \"resource_type\": \"model\",\n                },\n                ANY,\n            ),\n            \"path\": (\n                self.dir(\"models/ephemeral.sql\"),\n                self.dir(\"models/incremental.sql\"),\n                self.dir(\"models/sub/inner.sql\"),\n                self.dir(\"models/metricflow_time_spine.sql\"),\n                self.dir(\"models/metricflow_time_spine_second.sql\"),\n                self.dir(\"models/model_to_unit_test.sql\"),\n                self.dir(\"models/model_with_lots_of_schema_configs.sql\"),\n                self.dir(\"models/outer.sql\"),\n                self.dir(\"models/snapshot_source.sql\"),\n            ),\n        }\n\n        self.expect_given_output([\"--resource-type\", \"model\"], expectations)\n\n    # Do not include ephemeral model - it was not selected\n    def expect_model_ephemeral_output(self):\n        expectations = {\n            \"name\": (\"outer\"),\n            \"selector\": (\"test.outer\"),\n            \"json\": (\n                {\n                    \"name\": \"outer\",\n                    \"package_name\": \"test\",\n                    \"depends_on\": {\"nodes\": [], \"macros\": []},\n                    \"tags\": [],\n                    \"config\": {\n                        \"enabled\": True,\n                        \"materialized\": \"view\",\n                        \"post-hook\": [],\n                        \"tags\": [],\n                        \"pre-hook\": [],\n                        \"quoting\": {},\n                        \"column_types\": {},\n                        \"persist_docs\": {},\n                        \"full_refresh\": None,\n                        \"on_schema_change\": \"ignore\",\n                        \"on_configuration_change\": \"apply\",\n                        \"database\": None,\n                        \"schema\": None,\n                        \"alias\": None,\n                        \"meta\": {},\n                        \"grants\": {},\n                        \"packages\": [],\n                        \"incremental_strategy\": None,\n                        \"docs\": {\"node_color\": None, \"show\": True},\n                        \"access\": \"protected\",\n                    },\n                    \"unique_id\": \"model.test.ephemeral\",\n                    \"original_file_path\": normalize(\"models/ephemeral.sql\"),\n                    \"alias\": \"outer\",\n                    \"resource_type\": \"model\",\n                },\n            ),\n            \"path\": (self.dir(\"models/outer.sql\"),),\n        }\n        self.expect_given_output([\"--model\", \"outer\"], expectations)\n\n    def expect_source_output(self):\n        expectations = {\n            \"name\": \"my_source.my_table\",\n            \"selector\": \"source:test.my_source.my_table\",\n            \"json\": {\n                \"config\": {\n                    \"enabled\": True,\n                    \"event_time\": \"column_name\",\n                    \"freshness\": {\n                        \"error_after\": {\n                            \"count\": 2,\n                            \"period\": \"hour\",\n                        },\n                        \"warn_after\": {\n                            \"count\": 1,\n                            \"period\": \"minute\",\n                        },\n                        \"filter\": \"column_name = 1\",\n                    },\n                    \"meta\": {\"source_meta\": 1, \"table_meta\": 1},\n                    \"tags\": [\"source_tag\", \"table_tag\"],\n                    \"loaded_at_query\": None,\n                    \"loaded_at_field\": \"column_name\",\n                },\n                \"unique_id\": \"source.test.my_source.my_table\",\n                \"original_file_path\": normalize(\"models/schema.yml\"),\n                \"package_name\": \"test\",\n                \"name\": \"my_table\",\n                \"source_name\": \"my_source\",\n                \"resource_type\": \"source\",\n                \"tags\": [\"source_tag\", \"table_tag\"],\n            },\n            \"path\": self.dir(\"models/schema.yml\"),\n        }\n        # should we do this --select automatically for a user if if 'source' is\n        # in the resource types and there is no '--select' or '--exclude'?\n        self.expect_given_output(\n            [\"--resource-type\", \"source\", \"--select\", \"source:*\"], expectations\n        )\n\n    def expect_seed_output(self):\n        expectations = {\n            \"name\": \"seed\",\n            \"selector\": \"test.seed\",\n            \"json\": {\n                \"name\": \"seed\",\n                \"package_name\": \"test\",\n                \"tags\": [\"tag\"],\n                \"config\": {\n                    \"enabled\": True,\n                    \"group\": \"finance\",\n                    \"materialized\": \"seed\",\n                    \"post-hook\": [{\"sql\": \"select 1\", \"transaction\": True, \"index\": None}],\n                    \"tags\": [\"tag\"],\n                    \"pre-hook\": [{\"sql\": \"select 1\", \"transaction\": True, \"index\": None}],\n                    \"quoting\": {},\n                    \"column_types\": {\"a\": \"BIGINT\"},\n                    \"delimiter\": \",\",\n                    \"persist_docs\": {},\n                    \"quote_columns\": False,\n                    \"full_refresh\": True,\n                    \"unique_key\": None,\n                    \"on_schema_change\": \"ignore\",\n                    \"on_configuration_change\": \"apply\",\n                    \"database\": \"dbt\",\n                    \"schema\": \"test\",\n                    \"alias\": \"test_alias\",\n                    \"meta\": {\"meta_key\": \"meta_value\"},\n                    \"grants\": {},\n                    \"packages\": [],\n                    \"incremental_strategy\": None,\n                    \"docs\": {\"node_color\": \"purple\", \"show\": True},\n                    \"contract\": {\"enforced\": False, \"alias_types\": True},\n                    \"event_time\": \"my_time_field\",\n                    \"lookback\": 1,\n                    \"batch_size\": None,\n                    \"begin\": None,\n                    \"concurrent_batches\": None,\n                },\n                \"depends_on\": {\"macros\": []},\n                \"unique_id\": \"seed.test.seed\",\n                \"original_file_path\": normalize(\"seeds/seed.csv\"),\n                \"alias\": \"test_alias\",\n                \"resource_type\": \"seed\",\n            },\n            \"path\": self.dir(\"seeds/seed.csv\"),\n        }\n        self.expect_given_output([\"--resource-type\", \"seed\"], expectations)\n\n    def expect_test_output(self):\n        # This is order sensitive :grimace:\n        expectations = {\n            \"name\": (\n                \"expression_is_true_seed_b_2\",\n                \"my_favorite_test\",\n                \"my_second_favorite_test\",\n                \"not_null_outer_id\",\n                \"not_null_seed__a_\",\n                \"not_null_seed__b_\",\n                \"t\",\n                \"unique_model_with_lots_of_schema_configs_id\",\n                \"unique_outer_id\",\n            ),\n            \"selector\": (\n                \"test.expression_is_true_seed_b_2\",\n                \"test.my_favorite_test\",\n                \"test.my_second_favorite_test\",\n                \"test.not_null_outer_id\",\n                \"test.not_null_seed__a_\",\n                \"test.not_null_seed__b_\",\n                \"test.t\",\n                \"test.unique_model_with_lots_of_schema_configs_id\",\n                \"test.unique_outer_id\",\n            ),\n            \"json\": (\n                {\n                    \"alias\": \"expression_is_true_seed_b_2\",\n                    \"config\": {\n                        \"alias\": None,\n                        \"database\": None,\n                        \"enabled\": True,\n                        \"error_if\": \"!= 0\",\n                        \"fail_calc\": \"count(*)\",\n                        \"group\": None,\n                        \"limit\": None,\n                        \"materialized\": \"test\",\n                        \"meta\": {},\n                        \"schema\": \"dbt_test__audit\",\n                        \"severity\": \"ERROR\",\n                        \"store_failures\": None,\n                        \"store_failures_as\": None,\n                        \"sql_header\": None,\n                        \"tags\": [],\n                        \"warn_if\": \"!= 0\",\n                        \"where\": None,\n                    },\n                    \"depends_on\": {\n                        \"macros\": [\n                            \"macro.test.test_expression_is_true\",\n                            \"macro.dbt.get_where_subquery\",\n                        ],\n                        \"nodes\": [\"seed.test.seed\"],\n                    },\n                    \"name\": \"expression_is_true_seed_b_2\",\n                    \"original_file_path\": normalize(\"seeds/s.yml\"),\n                    \"package_name\": \"test\",\n                    \"resource_type\": \"test\",\n                    \"tags\": [],\n                    \"unique_id\": \"test.test.expression_is_true_seed_b_2.4e0babbea4\",\n                },\n                {\n                    \"alias\": \"not_null__id__alias\",\n                    \"config\": {\n                        \"alias\": \"not_null__id__alias\",\n                        \"database\": \"dbt\",\n                        \"enabled\": True,\n                        \"error_if\": \"!= 0\",\n                        \"fail_calc\": \"count(*)\",\n                        \"group\": \"important_tests\",\n                        \"limit\": 10,\n                        \"materialized\": \"test\",\n                        \"meta\": {\"my_custom_meta_key\": \"my_custom_meta_value\"},\n                        \"schema\": \"dbt_test__audit\",\n                        \"severity\": \"warn\",\n                        \"store_failures\": True,\n                        \"store_failures_as\": \"table\",\n                        \"sql_header\": None,\n                        \"tags\": [\"test_tag\"],\n                        \"warn_if\": \"!= 0\",\n                        \"where\": \"1 = 1\",\n                    },\n                    \"depends_on\": {\n                        \"macros\": [\"macro.dbt.test_not_null\"],\n                        \"nodes\": [\"model.test.model_with_lots_of_schema_configs\"],\n                    },\n                    \"name\": \"my_favorite_test\",\n                    \"original_file_path\": normalize(\"models/schema.yml\"),\n                    \"package_name\": \"test\",\n                    \"resource_type\": \"test\",\n                    \"tags\": [\"column_level_tag\", \"test_tag\"],\n                    \"unique_id\": \"test.test.my_favorite_test.b488d63233\",\n                },\n                {\n                    \"alias\": \"my_generic_test__created_at__alias\",\n                    \"config\": {\n                        \"alias\": \"my_generic_test__created_at__alias\",\n                        \"database\": \"dbt\",\n                        \"enabled\": True,\n                        \"error_if\": \"!= 0\",\n                        \"fail_calc\": \"count(*)\",\n                        \"group\": \"important_tests\",\n                        \"limit\": 10,\n                        \"materialized\": \"test\",\n                        \"meta\": {\"my_custom_meta_key\": \"my_custom_meta_value\"},\n                        \"schema\": \"dbt_test__audit\",\n                        \"severity\": \"warn\",\n                        \"store_failures\": True,\n                        \"store_failures_as\": \"table\",\n                        \"sql_header\": None,\n                        \"tags\": [\"test_tag\", \"test_tag\"],\n                        \"warn_if\": \"!= 0\",\n                        \"where\": \"1 = 1\",\n                    },\n                    \"depends_on\": {\n                        \"macros\": [\n                            \"macro.test.test_my_generic_test\",\n                            \"macro.dbt.get_where_subquery\",\n                        ],\n                        \"nodes\": [\"model.test.model_with_lots_of_schema_configs\"],\n                    },\n                    \"name\": \"my_second_favorite_test\",\n                    \"original_file_path\": normalize(\"models/schema.yml\"),\n                    \"package_name\": \"test\",\n                    \"resource_type\": \"test\",\n                    \"tags\": [\"test_tag\"],\n                    \"unique_id\": \"test.test.my_second_favorite_test.c8955109ad\",\n                },\n                {\n                    \"name\": \"not_null_outer_id\",\n                    \"package_name\": \"test\",\n                    \"depends_on\": {\n                        \"nodes\": [\"model.test.outer\"],\n                        \"macros\": [\"macro.dbt.test_not_null\"],\n                    },\n                    \"tags\": [],\n                    \"config\": {\n                        \"enabled\": True,\n                        \"group\": None,\n                        \"materialized\": \"test\",\n                        \"severity\": \"ERROR\",\n                        \"store_failures\": None,\n                        \"store_failures_as\": None,\n                        \"sql_header\": None,\n                        \"warn_if\": \"!= 0\",\n                        \"error_if\": \"!= 0\",\n                        \"fail_calc\": \"count(*)\",\n                        \"where\": None,\n                        \"limit\": None,\n                        \"tags\": [],\n                        \"database\": None,\n                        \"schema\": \"dbt_test__audit\",\n                        \"alias\": None,\n                        \"meta\": {},\n                    },\n                    \"unique_id\": \"test.test.not_null_outer_id.a226f4fb36\",\n                    \"original_file_path\": normalize(\"models/schema.yml\"),\n                    \"alias\": \"not_null_outer_id\",\n                    \"resource_type\": \"test\",\n                },\n                {\n                    \"alias\": \"not_null_seed__a_\",\n                    \"config\": {\n                        \"alias\": None,\n                        \"database\": None,\n                        \"enabled\": True,\n                        \"error_if\": \"!= 0\",\n                        \"fail_calc\": \"count(*)\",\n                        \"group\": None,\n                        \"limit\": None,\n                        \"materialized\": \"test\",\n                        \"meta\": {},\n                        \"schema\": \"dbt_test__audit\",\n                        \"severity\": \"ERROR\",\n                        \"store_failures\": None,\n                        \"store_failures_as\": None,\n                        \"sql_header\": None,\n                        # generic test builders don't propagate tags correctly\n                        \"tags\": [],\n                        \"warn_if\": \"!= 0\",\n                        \"where\": None,\n                    },\n                    \"depends_on\": {\n                        \"macros\": [\"macro.dbt.test_not_null\"],\n                        \"nodes\": [\"seed.test.seed\"],\n                    },\n                    \"name\": \"not_null_seed__a_\",\n                    \"original_file_path\": normalize(\"seeds/s.yml\"),\n                    \"package_name\": \"test\",\n                    \"resource_type\": \"test\",\n                    \"tags\": [\"tag\"],\n                    \"unique_id\": \"test.test.not_null_seed__a_.6b59640cde\",\n                },\n                {\n                    \"alias\": \"not_null_seed__b_\",\n                    \"config\": {\n                        \"alias\": None,\n                        \"database\": None,\n                        \"enabled\": True,\n                        \"error_if\": \"!= 0\",\n                        \"fail_calc\": \"count(*)\",\n                        \"group\": None,\n                        \"limit\": None,\n                        \"materialized\": \"test\",\n                        \"meta\": {},\n                        \"schema\": \"dbt_test__audit\",\n                        \"severity\": \"ERROR\",\n                        \"store_failures\": None,\n                        \"store_failures_as\": None,\n                        \"sql_header\": None,\n                        # generic test builders don't propagate tags correctly\n                        \"tags\": [],\n                        \"warn_if\": \"!= 0\",\n                        \"where\": None,\n                    },\n                    \"depends_on\": {\n                        \"macros\": [\"macro.dbt.test_not_null\"],\n                        \"nodes\": [\"seed.test.seed\"],\n                    },\n                    \"name\": \"not_null_seed__b_\",\n                    \"original_file_path\": normalize(\"seeds/s.yml\"),\n                    \"package_name\": \"test\",\n                    \"resource_type\": \"test\",\n                    \"tags\": [\"tag\"],\n                    \"unique_id\": \"test.test.not_null_seed__b_.a088b263cb\",\n                },\n                {\n                    \"name\": \"t\",\n                    \"package_name\": \"test\",\n                    \"alias\": \"test_alias\",\n                    \"config\": {\n                        \"alias\": \"test_alias\",\n                        \"database\": \"dbt\",\n                        \"enabled\": True,\n                        \"error_if\": \"!= 0\",\n                        \"fail_calc\": \"count(*)\",\n                        \"group\": \"important_tests\",\n                        \"limit\": 10,\n                        \"materialized\": \"test\",\n                        \"meta\": {\"my_custom_meta_key\": \"my_custom_meta_value\"},\n                        \"schema\": \"dbt_test__audit\",\n                        \"severity\": \"warn\",\n                        \"store_failures\": True,\n                        \"store_failures_as\": \"table\",\n                        \"sql_header\": None,\n                        \"tags\": [\"test_tag\"],\n                        \"warn_if\": \"!= 0\",\n                        \"where\": \"1 = 1\",\n                    },\n                    \"depends_on\": {\"macros\": [], \"nodes\": []},\n                    \"name\": \"t\",\n                    \"original_file_path\": normalize(\"tests/t.sql\"),\n                    \"package_name\": \"test\",\n                    \"resource_type\": \"test\",\n                    \"tags\": [\"test_tag\"],\n                    \"unique_id\": \"test.test.t\",\n                },\n                {\n                    \"alias\": \"unique_model_with_lots_of_schema_configs_id\",\n                    \"config\": {\n                        \"alias\": None,\n                        \"database\": None,\n                        \"enabled\": True,\n                        \"error_if\": \"!= 0\",\n                        \"fail_calc\": \"count(*)\",\n                        \"group\": None,\n                        \"limit\": None,\n                        \"materialized\": \"test\",\n                        \"meta\": {},\n                        \"schema\": \"dbt_test__audit\",\n                        \"severity\": \"ERROR\",\n                        \"store_failures\": None,\n                        \"store_failures_as\": None,\n                        \"sql_header\": None,\n                        \"tags\": [],\n                        \"warn_if\": \"!= 0\",\n                        \"where\": None,\n                    },\n                    \"depends_on\": {\n                        \"macros\": [\"macro.dbt.test_unique\"],\n                        \"nodes\": [\"model.test.model_with_lots_of_schema_configs\"],\n                    },\n                    \"name\": \"unique_model_with_lots_of_schema_configs_id\",\n                    \"original_file_path\": normalize(\"models/schema.yml\"),\n                    \"package_name\": \"test\",\n                    \"resource_type\": \"test\",\n                    \"tags\": [\"column_level_tag\"],\n                    \"unique_id\": \"test.test.unique_model_with_lots_of_schema_configs_id.8328d84982\",\n                },\n                {\n                    \"name\": \"unique_outer_id\",\n                    \"package_name\": \"test\",\n                    \"depends_on\": {\n                        \"nodes\": [\"model.test.outer\"],\n                        \"macros\": [\"macro.dbt.test_unique\"],\n                    },\n                    \"tags\": [],\n                    \"config\": {\n                        \"enabled\": True,\n                        \"group\": None,\n                        \"materialized\": \"test\",\n                        \"severity\": \"ERROR\",\n                        \"store_failures\": None,\n                        \"store_failures_as\": None,\n                        \"sql_header\": None,\n                        \"warn_if\": \"!= 0\",\n                        \"error_if\": \"!= 0\",\n                        \"fail_calc\": \"count(*)\",\n                        \"where\": None,\n                        \"limit\": None,\n                        \"tags\": [],\n                        \"database\": None,\n                        \"schema\": \"dbt_test__audit\",\n                        \"alias\": None,\n                        \"meta\": {},\n                    },\n                    \"unique_id\": \"test.test.unique_outer_id.2195e332d3\",\n                    \"original_file_path\": normalize(\"models/schema.yml\"),\n                    \"alias\": \"unique_outer_id\",\n                    \"resource_type\": \"test\",\n                },\n            ),\n            \"path\": (\n                self.dir(\"seeds/s.yml\"),\n                self.dir(\"models/schema.yml\"),\n                self.dir(\"models/schema.yml\"),\n                self.dir(\"models/schema.yml\"),\n                self.dir(\"seeds/s.yml\"),\n                self.dir(\"seeds/s.yml\"),\n                self.dir(\"tests/t.sql\"),\n                self.dir(\"models/schema.yml\"),\n                self.dir(\"models/schema.yml\"),\n            ),\n        }\n        self.expect_given_output([\"--resource-type\", \"test\"], expectations)\n\n    def expect_function_output(self):\n        # using `--resource-type`\n        results = self.run_dbt_ls([\"--resource-type\", \"function\"])\n        assert set(results) == {\"test.area_of_circle\"}\n\n        # using `--select` with `resource_type`\n        results = self.run_dbt_ls([\"--select\", \"resource_type:function\"])\n        assert set(results) == {\"test.area_of_circle\"}\n\n        # using `--select` with path spec\n        results = self.run_dbt_ls([\"--select\", \"functions/area_of_circle.sql\"])\n        assert set(results) == {\"test.area_of_circle\"}\n\n        # using `--select` with path function name\n        results = self.run_dbt_ls([\"--select\", \"area_of_circle\"])\n        assert set(results) == {\"test.area_of_circle\"}\n\n    def expect_all_output(self):\n        # generic test FQNS include the resource + column they're defined on\n        # models are just package, subdirectory path, name\n        # sources are like models, ending in source_name.table_name\n        expected_default = {\n            \"exposure:test.weekly_jaffle_metrics\",\n            \"test.ephemeral\",\n            \"test.incremental\",\n            \"test.snapshot.my_snapshot\",\n            \"test.snapshot_2\",\n            \"test.snapshot_3\",\n            \"test.sub.inner\",\n            \"test.outer\",\n            \"test.snapshot_source\",\n            \"test.seed\",\n            \"source:test.my_source.my_table\",\n            \"test.not_null_outer_id\",\n            \"test.unique_outer_id\",\n            \"test.metricflow_time_spine\",\n            \"test.metricflow_time_spine_second\",\n            \"test.model_to_unit_test\",\n            \"test.model_with_lots_of_schema_configs\",\n            \"test.unique_model_with_lots_of_schema_configs_id\",\n            \"test.t\",\n            \"test.my_favorite_test\",\n            \"test.my_second_favorite_test\",\n            \"test.area_of_circle\",\n            \"semantic_model:test.my_sm\",\n            \"metric:test.total_outer\",\n            \"metric:test.conversion_metric\",\n            \"metric:test.cumulative_metric\",\n            \"metric:test.cumulative_metric_2\",\n            \"metric:test.derived_metric\",\n            \"metric:test.filtered_ratio_metric\",\n            \"metric:test.simple_ratio_metric\",\n            \"metric:test.discrete_order_value_p99\",\n            \"saved_query:test.my_saved_query\",\n            \"test.expression_is_true_seed_b_2\",\n            \"test.not_null_seed__a_\",\n            \"test.not_null_seed__b_\",\n            \"unit_test:test.test_model_to_unit_test\",\n            \"unit_test:test.test_model_to_unit_test_2\",\n        }\n        # analyses have their type inserted into their fqn like tests\n        expected_all = expected_default | {\"test.analysis.a\"}\n\n        results = self.run_dbt_ls([\"--resource-type\", \"all\", \"--select\", \"*\", \"source:*\"])\n        assert set(results) == expected_all\n\n        results = self.run_dbt_ls([\"--select\", \"*\", \"source:*\"])\n        assert set(results) == expected_default\n\n        results = self.run_dbt_ls([\"--resource-type\", \"default\", \"--select\", \"*\", \"source:*\"])\n        assert set(results) == expected_default\n\n        results = self.run_dbt_ls\n\n    def expect_select(self):\n        results = self.run_dbt_ls([\"--resource-type\", \"test\", \"--select\", \"outer\"])\n        assert set(results) == {\"test.not_null_outer_id\", \"test.unique_outer_id\"}\n\n        self.run_dbt_ls([\"--resource-type\", \"test\", \"--select\", \"inner\"], expect_pass=True)\n\n        results = self.run_dbt_ls([\"--resource-type\", \"test\", \"--select\", \"+inner\"])\n        assert set(results) == {\"test.not_null_outer_id\", \"test.unique_outer_id\"}\n\n        results = self.run_dbt_ls([\"--resource-type\", \"semantic_model\"])\n        assert set(results) == {\"semantic_model:test.my_sm\"}\n\n        results = self.run_dbt_ls([\"--resource-type\", \"metric\"])\n        assert set(results) == {\n            \"metric:test.total_outer\",\n            \"metric:test.simple_ratio_metric\",\n            \"metric:test.filtered_ratio_metric\",\n            \"metric:test.conversion_metric\",\n            \"metric:test.cumulative_metric\",\n            \"metric:test.cumulative_metric_2\",\n            \"metric:test.derived_metric\",\n            \"metric:test.discrete_order_value_p99\",\n        }\n\n        results = self.run_dbt_ls([\"--resource-type\", \"saved_query\"])\n        assert set(results) == {\"saved_query:test.my_saved_query\"}\n\n        results = self.run_dbt_ls([\"--resource-type\", \"model\", \"--select\", \"outer+\"])\n        assert set(results) == {\"test.outer\", \"test.sub.inner\"}\n\n        results = self.run_dbt_ls([\"--resource-type\", \"model\", \"--exclude\", \"inner\"])\n        assert set(results) == {\n            \"test.ephemeral\",\n            \"test.outer\",\n            \"test.snapshot_source\",\n            \"test.metricflow_time_spine\",\n            \"test.metricflow_time_spine_second\",\n            \"test.model_to_unit_test\",\n            \"test.model_with_lots_of_schema_configs\",\n            \"test.incremental\",\n        }\n\n        results = self.run_dbt_ls([\"--select\", \"config.incremental_strategy:delete+insert\"])\n        assert set(results) == {\"test.incremental\"}\n\n        self.run_dbt_ls(\n            [\"--select\", \"config.incremental_strategy:insert_overwrite\"], expect_pass=True\n        )\n\n    def expect_resource_type_multiple(self):\n        \"\"\"Expect selected resources when --resource-type given multiple times\"\"\"\n        results = self.run_dbt_ls([\"--resource-type\", \"test\", \"--resource-type\", \"model\"])\n        assert set(results) == {\n            \"test.ephemeral\",\n            \"test.incremental\",\n            \"test.not_null_outer_id\",\n            \"test.outer\",\n            \"test.snapshot_source\",\n            \"test.sub.inner\",\n            \"test.metricflow_time_spine\",\n            \"test.metricflow_time_spine_second\",\n            \"test.model_to_unit_test\",\n            \"test.model_with_lots_of_schema_configs\",\n            \"test.t\",\n            \"test.unique_outer_id\",\n            \"test.unique_model_with_lots_of_schema_configs_id\",\n            \"test.expression_is_true_seed_b_2\",\n            \"test.not_null_seed__a_\",\n            \"test.not_null_seed__b_\",\n            \"test.my_favorite_test\",\n            \"test.my_second_favorite_test\",\n        }\n\n        results = self.run_dbt_ls(\n            [\n                \"--resource-type\",\n                \"test\",\n                \"--resource-type\",\n                \"model\",\n                \"--exclude\",\n                \"unique_outer_id\",\n            ]\n        )\n        assert set(results) == {\n            \"test.ephemeral\",\n            \"test.incremental\",\n            \"test.not_null_outer_id\",\n            \"test.outer\",\n            \"test.snapshot_source\",\n            \"test.metricflow_time_spine\",\n            \"test.metricflow_time_spine_second\",\n            \"test.model_to_unit_test\",\n            \"test.model_with_lots_of_schema_configs\",\n            \"test.sub.inner\",\n            \"test.t\",\n            \"test.unique_model_with_lots_of_schema_configs_id\",\n            \"test.expression_is_true_seed_b_2\",\n            \"test.not_null_seed__a_\",\n            \"test.not_null_seed__b_\",\n            \"test.my_favorite_test\",\n            \"test.my_second_favorite_test\",\n        }\n\n        results = self.run_dbt_ls(\n            [\n                \"--resource-type\",\n                \"test\",\n                \"model\",\n                \"--select\",\n                \"+inner\",\n                \"outer+\",\n                \"--exclude\",\n                \"inner\",\n            ]\n        )\n        assert set(results) == {\n            \"test.ephemeral\",\n            \"test.not_null_outer_id\",\n            \"test.unique_outer_id\",\n            \"test.outer\",\n        }\n\n    def expect_resource_type_env_var(self):\n        \"\"\"Expect selected resources when --resource-type given multiple times\"\"\"\n        os.environ[\"DBT_RESOURCE_TYPES\"] = \"test model\"\n        results = self.run_dbt_ls()\n        assert set(results) == {\n            \"test.ephemeral\",\n            \"test.incremental\",\n            \"test.not_null_outer_id\",\n            \"test.outer\",\n            \"test.snapshot_source\",\n            \"test.sub.inner\",\n            \"test.metricflow_time_spine\",\n            \"test.metricflow_time_spine_second\",\n            \"test.model_to_unit_test\",\n            \"test.model_with_lots_of_schema_configs\",\n            \"test.t\",\n            \"test.unique_outer_id\",\n            \"test.unique_model_with_lots_of_schema_configs_id\",\n            \"test.expression_is_true_seed_b_2\",\n            \"test.not_null_seed__a_\",\n            \"test.not_null_seed__b_\",\n            \"test.my_favorite_test\",\n            \"test.my_second_favorite_test\",\n        }\n        del os.environ[\"DBT_RESOURCE_TYPES\"]\n        os.environ[\"DBT_EXCLUDE_RESOURCE_TYPES\"] = (\n            \"test saved_query metric source semantic_model snapshot seed\"\n        )\n        results = self.run_dbt_ls()\n        assert set(results) == {\n            \"exposure:test.weekly_jaffle_metrics\",\n            \"test.area_of_circle\",\n            \"test.ephemeral\",\n            \"test.incremental\",\n            \"test.outer\",\n            \"test.snapshot_source\",\n            \"test.sub.inner\",\n            \"test.metricflow_time_spine\",\n            \"test.metricflow_time_spine_second\",\n            \"test.model_to_unit_test\",\n            \"test.model_with_lots_of_schema_configs\",\n            \"unit_test:test.test_model_to_unit_test\",\n            \"unit_test:test.test_model_to_unit_test_2\",\n        }\n        del os.environ[\"DBT_EXCLUDE_RESOURCE_TYPES\"]\n\n    def expect_selected_keys(self, happy_path_project):  # noqa: F811\n        \"\"\"Expect selected fields of the the selected model\"\"\"\n        expectations = [\n            {\n                \"database\": happy_path_project.database,\n                \"schema\": happy_path_project.test_schema,\n                \"alias\": \"inner\",\n            }\n        ]\n        results = self.run_dbt_ls(\n            [\n                \"--model\",\n                \"inner\",\n                \"--output\",\n                \"json\",\n                \"--output-keys\",\n                \"database\",\n                \"schema\",\n                \"alias\",\n            ]\n        )\n        assert len(results) == len(expectations)\n\n        for got, expected in zip(results, expectations):\n            self.assert_json_equal(got, expected)\n\n        \"\"\"Expect selected fields when --output-keys given multiple times\n        \"\"\"\n        expectations = [\n            {\"database\": happy_path_project.database, \"schema\": happy_path_project.test_schema}\n        ]\n        results = self.run_dbt_ls(\n            [\n                \"--model\",\n                \"inner\",\n                \"--output\",\n                \"json\",\n                \"--output-keys\",\n                \"database\",\n                \"--output-keys\",\n                \"schema\",\n            ]\n        )\n        assert len(results) == len(expectations)\n\n        for got, expected in zip(results, expectations):\n            self.assert_json_equal(got, expected)\n\n        \"\"\"Expect selected fields of the test resource types\n        \"\"\"\n        expectations = [\n            {\"name\": \"expression_is_true_seed_b_2\", \"column_name\": None},\n            {\"name\": \"my_favorite_test\", \"column_name\": \"id\"},\n            {\"name\": \"my_second_favorite_test\", \"column_name\": \"created_at\"},\n            {\"name\": \"not_null_outer_id\", \"column_name\": \"id\"},\n            {\"name\": \"not_null_seed__a_\", \"column_name\": '\"a\"'},\n            {\"name\": \"not_null_seed__b_\", \"column_name\": '\"b\"'},\n            {\"name\": \"t\"},\n            {\"name\": \"unique_model_with_lots_of_schema_configs_id\", \"column_name\": \"id\"},\n            {\"name\": \"unique_outer_id\", \"column_name\": \"id\"},\n        ]\n        results = self.run_dbt_ls(\n            [\n                \"--resource-type\",\n                \"test\",\n                \"--output\",\n                \"json\",\n                \"--output-keys\",\n                \"name\",\n                \"column_name\",\n            ]\n        )\n        assert len(results) == len(expectations)\n\n        for got, expected in zip(\n            sorted(results, key=lambda x: json.loads(x).get(\"name\")),\n            sorted(expectations, key=lambda x: x.get(\"name\")),\n        ):\n            self.assert_json_equal(got, expected)\n\n        \"\"\"Expect nothing (non-existent keys) for the selected models\n        \"\"\"\n        expectations = [{}, {}]\n        results = self.run_dbt_ls(\n            [\n                \"--model\",\n                \"inner outer\",\n                \"--output\",\n                \"json\",\n                \"--output-keys\",\n                \"non_existent_key\",\n            ]\n        )\n        assert len(results) == len(expectations)\n\n        for got, expected in zip(results, expectations):\n            self.assert_json_equal(got, expected)\n\n    def test_ls(self, happy_path_project):  # noqa: F811\n        self.expect_snapshot_output(happy_path_project)\n        self.expect_analyses_output()\n        self.expect_model_output()\n        self.expect_source_output()\n        self.expect_seed_output()\n        self.expect_test_output()\n        self.expect_function_output()\n        self.expect_select()\n        self.expect_resource_type_multiple()\n        self.expect_resource_type_env_var()\n        self.expect_all_output()\n        self.expect_selected_keys(happy_path_project)\n\n\ndef normalize(path):\n    \"\"\"On windows, neither is enough on its own:\n    >>> normcase('C:\\\\documents/ALL CAPS/subdir\\\\..')\n    'c:\\\\documents\\\\all caps\\\\subdir\\\\..'\n    >>> normpath('C:\\\\documents/ALL CAPS/subdir\\\\..')\n    'C:\\\\documents\\\\ALL CAPS'\n    >>> normpath(normcase('C:\\\\documents/ALL CAPS/subdir\\\\..'))\n    'c:\\\\documents\\\\all caps'\n    \"\"\"\n    return os.path.normcase(os.path.normpath(path))\n"
  },
  {
    "path": "tests/functional/logging/test_logging.py",
    "content": "import json\nimport os\n\nimport pytest\n\nfrom dbt.events.types import InvalidOptionYAML\nfrom dbt.tests.util import get_manifest, read_file, run_dbt\nfrom dbt_common.events import EventLevel\nfrom dbt_common.events.functions import fire_event\n\nmy_model_sql = \"\"\"\n  select 1 as fun\n\"\"\"\n\n\n@pytest.fixture(scope=\"class\")\ndef models():\n    return {\"my_model.sql\": my_model_sql}\n\n\n# This test checks that various events contain node_info,\n# which is supplied by the log_contextvars context manager\ndef test_basic(project, logs_dir):\n    results = run_dbt([\"--log-format=json\", \"run\"])\n    assert len(results) == 1\n    manifest = get_manifest(project.project_root)\n    assert \"model.test.my_model\" in manifest.nodes\n\n    # get log file\n    log_file = read_file(logs_dir, \"dbt.log\")\n    assert log_file\n    node_start = False\n    node_finished = False\n    connection_reused_data = []\n    for log_line in log_file.split(\"\\n\"):\n        # skip empty lines\n        if len(log_line) == 0:\n            continue\n        # The adapter logging also shows up, so skip non-json lines\n        if \"[debug]\" in log_line:\n            continue\n        log_dct = json.loads(log_line)\n        log_data = log_dct[\"data\"]\n        log_event = log_dct[\"info\"][\"name\"]\n        if log_event == \"ConnectionReused\":\n            connection_reused_data.append(log_data)\n        if log_event == \"NodeStart\":\n            node_start = True\n        if log_event == \"NodeFinished\":\n            node_finished = True\n            assert log_data[\"run_result\"][\"adapter_response\"]\n        if node_start and not node_finished:\n            if log_event == \"NodeExecuting\":\n                assert \"node_info\" in log_data\n            if log_event == \"JinjaLogDebug\":\n                assert \"node_info\" in log_data\n            if log_event == \"SQLQuery\":\n                assert \"node_info\" in log_data\n            if log_event == \"TimingInfoCollected\":\n                assert \"node_info\" in log_data\n                assert \"timing_info\" in log_data\n\n    # windows doesn't have the same thread/connection flow so the ConnectionReused\n    # events don't show up\n    if os.name != \"nt\":\n        # Verify the ConnectionReused event occurs and has the right data\n        assert connection_reused_data\n        for data in connection_reused_data:\n            assert \"conn_name\" in data and data[\"conn_name\"]\n            assert \"orig_conn_name\" in data and data[\"orig_conn_name\"]\n\n\ndef test_formatted_logs(project, logs_dir):\n    # a basic run of dbt with a single model should have 5 `Formatting` events in the json logs\n    results = run_dbt([\"--log-format=json\", \"run\"])\n    assert len(results) == 1\n\n    # get log file\n    json_log_file = read_file(logs_dir, \"dbt.log\")\n    formatted_json_lines = 0\n    for log_line in json_log_file.split(\"\\n\"):\n        # skip the empty line at the end\n        if len(log_line) == 0:\n            continue\n        log_dct = json.loads(log_line)\n        log_event = log_dct[\"info\"][\"name\"]\n        if log_event == \"Formatting\":\n            formatted_json_lines += 1\n\n    assert formatted_json_lines == 5\n\n\ndef test_invalid_event_value(project, logs_dir):\n    results = run_dbt([\"--log-format=json\", \"run\"])\n    assert len(results) == 1\n    with pytest.raises(Exception):\n        # This should raise because positional arguments are provided to the event\n        fire_event(InvalidOptionYAML(\"testing\"))\n\n    # Provide invalid type to \"option_name\"\n    with pytest.raises(Exception) as excinfo:\n        fire_event(InvalidOptionYAML(option_name=1))\n\n    assert \"[InvalidOptionYAML]: Unable to parse logging event dictionary.\" in str(excinfo.value)\n\n\ngroups_yml = \"\"\"\ngroups:\n  - name: my_group_with_owner_metadata\n    owner:\n      name: my_name\n      email: my.email@gmail.com\n      slack: my_slack\n      other_property: something_else\n\nmodels:\n  - name: my_model\n    group: my_group_with_owner_metadata\n    access: public\n\"\"\"\n\ngroups_yml_with_multiple_emails = \"\"\"\ngroups:\n  - name: my_group_with_multiple_emails\n    owner:\n      name: my_name\n      email:\n        - my.email@gmail.com\n        - my.second.email@gmail.com\n      slack: my_slack\n      other_property: something_else\n\nmodels:\n  - name: my_model\n    group: my_group_with_multiple_emails\n    access: public\n    columns:\n      - name: my_column\n        tests:\n         - not_null\n\"\"\"\n\n\nclass TestRunResultErrorNodeInfo:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": \"select not_found as id\",\n        }\n\n    def test_node_info_on_results(self, project, logs_dir):\n        results = run_dbt([\"--log-format=json\", \"run\"], expect_pass=False)\n        assert len(results) == 1\n\n        log_file = read_file(logs_dir, \"dbt.log\")\n\n        for log_line in log_file.split(\"\\n\"):\n            if not log_line:\n                continue\n\n            log_json = json.loads(log_line)\n            if log_json[\"info\"][\"level\"] == EventLevel.DEBUG:\n                continue\n\n            if log_json[\"info\"][\"name\"] == \"RunResultError\":\n                assert \"node_info\" in log_json[\"data\"]\n                assert log_json[\"data\"][\"node_info\"][\"unique_id\"] == \"model.test.my_model\"\n                assert \"Database Error\" in log_json[\"data\"][\"msg\"]\n\n\ndef assert_group_data(group_data):\n    assert group_data[\"name\"] == \"my_group_with_owner_metadata\"\n    assert group_data[\"owner\"] == {\n        \"name\": \"my_name\",\n        \"email\": \"my.email@gmail.com\",\n        \"slack\": \"my_slack\",\n        \"other_property\": \"something_else\",\n    }\n\n\nclass TestRunResultErrorGroup:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": \"select not_found as id\",\n            \"groups.yml\": groups_yml,\n        }\n\n    def test_node_info_on_results(self, project, logs_dir):\n        results = run_dbt([\"--log-format=json\", \"run\"], expect_pass=False)\n        assert len(results) == 1\n\n        log_file = read_file(logs_dir, \"dbt.log\")\n        run_result_error_count = 0\n\n        for log_line in log_file.split(\"\\n\"):\n            if not log_line:\n                continue\n\n            log_json = json.loads(log_line)\n            if log_json[\"info\"][\"level\"] == EventLevel.DEBUG:\n                continue\n\n            if log_json[\"info\"][\"name\"] == \"RunResultError\":\n                assert \"group\" in log_json[\"data\"]\n                assert_group_data(log_json[\"data\"][\"group\"])\n                run_result_error_count += 1\n\n        assert run_result_error_count == 1\n\n\nclass TestRunResultFailureGroup:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        schema_yml = (\n            groups_yml\n            + \"\"\"\n    columns:\n      - name: my_column\n        tests:\n         - not_null\n\"\"\"\n        )\n        print(schema_yml)\n        return {\n            \"my_model.sql\": \"select 1 as id, null as my_column\",\n            \"groups.yml\": schema_yml,\n        }\n\n    def test_node_info_on_results(self, project, logs_dir):\n        results = run_dbt([\"--log-format=json\", \"build\"], expect_pass=False)\n        assert len(results) == 2\n\n        log_file = read_file(logs_dir, \"dbt.log\")\n        run_result_error_count = 0\n        run_result_failure_count = 0\n\n        for log_line in log_file.split(\"\\n\"):\n            if not log_line:\n                continue\n\n            log_json = json.loads(log_line)\n            if log_json[\"info\"][\"level\"] == EventLevel.DEBUG:\n                continue\n\n            if log_json[\"info\"][\"name\"] == \"RunResultError\":\n                assert \"group\" in log_json[\"data\"]\n                assert_group_data(log_json[\"data\"][\"group\"])\n                run_result_error_count += 1\n\n            if log_json[\"info\"][\"name\"] == \"RunResultFailure\":\n                assert \"group\" in log_json[\"data\"]\n                assert_group_data(log_json[\"data\"][\"group\"])\n                run_result_failure_count += 1\n\n        assert run_result_error_count == 1\n        assert run_result_failure_count == 1\n\n\nclass TestRunResultWarningGroup:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        schema_yml = (\n            groups_yml\n            + \"\"\"\n    columns:\n      - name: my_column\n        tests:\n         - not_null:\n             config:\n               severity: warn\n\"\"\"\n        )\n        print(schema_yml)\n        return {\n            \"my_model.sql\": \"select 1 as id, null as my_column\",\n            \"groups.yml\": schema_yml,\n        }\n\n    def test_node_info_on_results(self, project, logs_dir):\n        results = run_dbt([\"--log-format=json\", \"build\"])\n        assert len(results) == 2\n\n        log_file = read_file(logs_dir, \"dbt.log\")\n        run_result_warning_count = 0\n\n        for log_line in log_file.split(\"\\n\"):\n            if not log_line:\n                continue\n\n            log_json = json.loads(log_line)\n            if log_json[\"info\"][\"level\"] == EventLevel.DEBUG:\n                continue\n\n            if log_json[\"info\"][\"name\"] == \"RunResultWarning\":\n                assert \"group\" in log_json[\"data\"]\n                assert_group_data(log_json[\"data\"][\"group\"])\n                run_result_warning_count += 1\n\n        assert run_result_warning_count == 1\n\n\nclass TestRunResultNoGroup:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": \"select 1 as id\",\n        }\n\n    def test_node_info_on_results(self, project, logs_dir):\n        results = run_dbt([\"--no-write-json\", \"run\"])\n        assert len(results) == 1\n\n\nclass TestRunResultGroupWithMultipleEmails:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": \"select 1 as id, null as my_column\",\n            \"groups.yml\": groups_yml_with_multiple_emails,\n        }\n\n    def test_node_info_on_results(self, project, logs_dir):\n        results = run_dbt([\"--log-format=json\", \"build\"], expect_pass=False)\n        assert len(results) == 2\n\n        log_file = read_file(logs_dir, \"dbt.log\")\n        run_result_error_count = 0\n\n        for log_line in log_file.split(\"\\n\"):\n            if not log_line:\n                continue\n\n            log_json = json.loads(log_line)\n            if log_json[\"info\"][\"level\"] == EventLevel.DEBUG:\n                continue\n\n            if log_json[\"info\"][\"name\"] == \"RunResultError\":\n                assert \"group\" in log_json[\"data\"]\n                group_data = log_json[\"data\"][\"group\"]\n                assert group_data[\"name\"] == \"my_group_with_multiple_emails\"\n                assert group_data[\"owner\"] == {\n                    \"name\": \"my_name\",\n                    \"email\": \"['my.email@gmail.com', 'my.second.email@gmail.com']\",\n                    \"slack\": \"my_slack\",\n                    \"other_property\": \"something_else\",\n                }\n                run_result_error_count += 1\n\n        assert run_result_error_count == 1\n"
  },
  {
    "path": "tests/functional/logging/test_meta_logging.py",
    "content": "import json\n\nimport pytest\n\nfrom dbt.tests.util import read_file, run_dbt\n\nmodel1 = \"select 1 as fun\"\nmodel2 = '{{ config(meta={\"owners\": [\"team1\", \"team2\"]})}} select 1 as fun'\nmodel3 = '{{ config(meta={\"key\": 1})}} select 1 as fun'\n\n\n@pytest.fixture(scope=\"class\")  # noqa\ndef models():\n    return {\"model1.sql\": model1, \"model2.sql\": model2, \"model3.sql\": model3}\n\n\ndef run_and_capture_node_info_logs(logs_dir):\n    run_dbt([\"--log-format=json\", \"run\"])\n\n    # get log file\n    log_file = read_file(logs_dir, \"dbt.log\")\n    assert log_file\n\n    for log_line in log_file.split(\"\\n\"):\n        # skip empty lines\n        if len(log_line) == 0:\n            continue\n        # The adapter logging also shows up, so skip non-json lines\n        if \"[debug]\" in log_line:\n            continue\n\n        log_dct = json.loads(log_line)\n        if \"node_info\" not in log_dct[\"data\"]:\n            continue\n\n        yield log_dct[\"data\"][\"node_info\"]\n\n\n# This test checks that various events contain node_info,\n# which is supplied by the log_contextvars context manager\ndef test_meta(project, logs_dir):\n    for node_info_log in run_and_capture_node_info_logs(logs_dir):\n        if node_info_log[\"unique_id\"] == \"model.test.model1\":\n            assert node_info_log[\"meta\"] == {}\n        elif node_info_log[\"unique_id\"] == \"model.test.model2\":\n            assert node_info_log[\"meta\"] == {\"owners\": [\"team1\", \"team2\"]}\n        elif node_info_log[\"unique_id\"] == \"model.test.model3\":\n            assert node_info_log[\"meta\"] == {\"key\": 1}\n\n\ndef test_checksum(project, logs_dir):\n    for node_info_log in run_and_capture_node_info_logs(logs_dir):\n        if node_info_log[\"unique_id\"] == \"model.test.model1\":\n            assert (\n                node_info_log[\"node_checksum\"]\n                == \"7a72de8ca68190cc1f3a600b99ad24ce701817a5674222778845eb939c64aa76\"\n            )\n        elif node_info_log[\"unique_id\"] == \"model.test.model2\":\n            assert (\n                node_info_log[\"node_checksum\"]\n                == \"4e5b7658359b9a7fec6aa3cbad98ab07725927ccce59ec6e511e599e000b0fd3\"\n            )\n        elif node_info_log[\"unique_id\"] == \"model.test.model3\":\n            assert (\n                node_info_log[\"node_checksum\"]\n                == \"99c67d153920066d43168cc495240f185cec9d8cd552e7778e08437e66f44da7\"\n            )\n"
  },
  {
    "path": "tests/functional/macros/data/seed.sql",
    "content": "create table {schema}.expected_dep_macro (\n\tfoo TEXT,\n\tbar TEXT\n);\n\ncreate table {schema}.expected_local_macro (\n\tfoo2 TEXT,\n\tbar2 TEXT\n);\n\ncreate table {schema}.seed (\n\tid integer,\n\tupdated_at timestamp\n);\n\ninsert into {schema}.expected_dep_macro (foo, bar)\nvalues ('arg1', 'arg2');\n\ninsert into {schema}.expected_local_macro (foo2, bar2)\nvalues ('arg1', 'arg2'), ('arg3', 'arg4');\n\ninsert into {schema}.seed (id, updated_at)\nvalues (1, '2017-01-01'), (2, '2017-01-02');\n"
  },
  {
    "path": "tests/functional/macros/fixtures.py",
    "content": "models__dep_macro = \"\"\"\n{{\n    dbt_integration_project.do_something(\"arg1\", \"arg2\")\n}}\n\"\"\"\n\nmodels__materialization_macro = \"\"\"\n{{\n    materialization_macro()\n}}\n\"\"\"\n\nmodels__with_undefined_macro = \"\"\"\n{{ dispatch_to_nowhere() }}\nselect 1 as id\n\"\"\"\n\nmodels__local_macro = \"\"\"\n{{\n    do_something2(\"arg1\", \"arg2\")\n}}\n\nunion all\n\n{{\n    test.do_something2(\"arg3\", \"arg4\")\n}}\n\"\"\"\n\nmodels__ref_macro = \"\"\"\nselect * from {{ with_ref() }}\n\"\"\"\n\nmodels__override_get_columns_macros = \"\"\"\n{% set result = adapter.get_columns_in_relation(this) %}\n{% if execute and result != 'a string' %}\n  {% do exceptions.raise_compiler_error('overriding get_columns_in_relation failed') %}\n{% endif %}\nselect 1 as id\n\"\"\"\n\nmodels__deprecated_adapter_macro_model = \"\"\"\n{% if some_macro('foo', 'bar') != 'foobar' %}\n  {% do exceptions.raise_compiler_error('invalid foobar') %}\n{% endif %}\nselect 1 as id\n\"\"\"\n\n#\n# Macros\n#\nmacros__my_macros = \"\"\"\n{% macro do_something2(foo2, bar2) %}\n\n    select\n        '{{ foo2 }}' as foo2,\n        '{{ bar2 }}' as bar2\n\n{% endmacro %}\n\n\n{% macro with_ref() %}\n\n    {{ ref('table_model') }}\n\n{% endmacro %}\n\n\n{% macro dispatch_to_parent() %}\n    {% set macro = adapter.dispatch('dispatch_to_parent') %}\n    {{ macro() }}\n{% endmacro %}\n\n{% macro default__dispatch_to_parent() %}\n    {% set msg = 'No default implementation of dispatch_to_parent' %}\n    {{ exceptions.raise_compiler_error(msg) }}\n{% endmacro %}\n\n{% macro postgres__dispatch_to_parent() %}\n    {{ return('') }}\n{% endmacro %}\n\"\"\"\n\nmacros__named_materialization = \"\"\"\n{% macro materialization_macro() %}\n    select 1 as foo\n{% endmacro %}\n\"\"\"\n\nmacros__no_default_macros = \"\"\"\n{% macro do_something2(foo2, bar2) %}\n\n    select\n        '{{ foo2 }}' as foo2,\n        '{{ bar2 }}' as bar2\n\n{% endmacro %}\n\n\n{% macro with_ref() %}\n\n    {{ ref('table_model') }}\n\n{% endmacro %}\n\n{# there is no default__dispatch_to_nowhere! #}\n{% macro dispatch_to_nowhere() %}\n       {% set macro = adapter.dispatch('dispatch_to_nowhere') %}\n       {{ macro() }}\n{% endmacro %}\n\n{% macro dispatch_to_parent() %}\n    {% set macro = adapter.dispatch('dispatch_to_parent') %}\n    {{ macro() }}\n{% endmacro %}\n\n{% macro default__dispatch_to_parent() %}\n    {% set msg = 'No default implementation of dispatch_to_parent' %}\n    {{ exceptions.raise_compiler_error(msg) }}\n{% endmacro %}\n\n{% macro postgres__dispatch_to_parent() %}\n    {{ return('') }}\n{% endmacro %}\n\"\"\"\n\nmacros__override_get_columns_macros = \"\"\"\n{% macro get_columns_in_relation(relation) %}\n    {{ return('a string') }}\n{% endmacro %}\n\"\"\"\n\nmacros__package_override_get_columns_macros = \"\"\"\n{% macro postgres__get_columns_in_relation(relation) %}\n    {{ return('a string') }}\n{% endmacro %}\n\"\"\"\n\nmacros__deprecated_adapter_macro = \"\"\"\n{% macro some_macro(arg1, arg2) -%}\n    {{ adapter_macro('some_macro', arg1, arg2) }}\n{%- endmacro %}\n\"\"\"\n\nmacros__incorrect_dispatch = \"\"\"\n{% macro cowsay() %}\n  {{ return(adapter.dispatch('cowsay', 'farm_utils')()) }}\n{%- endmacro %}\n\n{% macro default__cowsay() %}\n  'moo'\n{% endmacro %}\n\"\"\"\n\n# Note the difference between `test_utils` below and `farm_utils` above\nmodels__incorrect_dispatch = \"\"\"\nselect {{ test_utils.cowsay() }} as cowsay\n\"\"\"\n\ndbt_project__incorrect_dispatch = \"\"\"\nname: 'test_utils'\nversion: '1.0'\nconfig-version: 2\n\nprofile: 'default'\n\nmacro-paths: [\"macros\"]\n\"\"\"\n\n\nmacros__config_sql = \"\"\"\n{% macro macro_config() %}\n{% endmacro %}\n\n{% macro macro_top_only() %}\n{% endmacro %}\n\n{% macro macro_config_only() %}\n{% endmacro %}\n\"\"\"\n\nmacros__config_yml = \"\"\"\nmacros:\n  - name: macro_top_only\n    description: Macro with only top-level meta and docs\n    meta:\n      top_k: top_v\n    docs:\n      show: true\n      node_color: \"#AAAAAA\"\n\n  - name: macro_config_only\n    description: Macro with only config meta and docs\n    config:\n      meta:\n        cm_k: cm_v\n      docs:\n        show: false\n        node_color: \"#BBBBBB\"\n\n  - name: macro_config\n    description: Macro with merged meta and docs\n    meta:\n      top_k: top_v\n    docs:\n      show: true\n      node_color: \"#AAAAAA\"\n    config:\n      meta:\n        cm_k: cm_v\n      docs:\n        node_color: \"#BBBBBB\"\n\"\"\"\n"
  },
  {
    "path": "tests/functional/macros/package_macro_overrides/dbt_project.yml",
    "content": "name: 'package_macro_overrides'\nversion: '1.0'\nconfig-version: 2\n\nprofile: 'default'\n\nmacro-paths: [\"macros\"]\n"
  },
  {
    "path": "tests/functional/macros/package_macro_overrides/macros/macros.sql",
    "content": "{% macro get_columns_in_relation(relation) %}\n\t{{ return('a string') }}\n{% endmacro %}\n"
  },
  {
    "path": "tests/functional/macros/test_macro_annotations.py",
    "content": "import pytest\n\nfrom dbt.events.types import InvalidMacroAnnotation\nfrom dbt.tests.util import run_dbt\nfrom dbt_common.events.event_catcher import EventCatcher\nfrom dbt_common.ui import warning_tag\n\nmacros_sql = \"\"\"\n{% macro my_macro(my_arg_1, my_arg_2, my_arg_3) %}\n{% endmacro %}\n\"\"\"\n\nbad_arg_names_macros_yml = \"\"\"\nmacros:\n  - name: my_macro\n    description: This is the macro description.\n    arguments:\n      - name: my_arg_1\n      - name: my_misnamed_arg_2\n      - name: my_misnamed_arg_3\n\"\"\"\n\nbad_arg_count_macros_yml = \"\"\"\nmacros:\n  - name: my_macro\n    arguments:\n      - name: my_arg_1\n        type: string\n        description: This is an argument description.\n\"\"\"\n\nbad_arg_types_macros_yml = \"\"\"\nmacros:\n  - name: my_macro\n    arguments:\n      - name: my_arg_1\n        type: string\n      - name: my_arg_2\n        type: invalid_type\n      - name: my_arg_3\n        type: int[int]\n\"\"\"\n\n\nbad_everything_types_macros_yml = \"\"\"\nmacros:\n  - name: my_macro\n    arguments:\n      - name: my_arg_1\n        type: string\n      - name: my_wrong_arg_2\n        type: invalid_type\n\"\"\"\n\n\nclass TestMacroDefaultArgMetadata:\n    \"\"\"Test that when the validate_macro_args behavior flag is enabled, macro\n    argument names are included in the manifest even if there is no yml patch.\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"macros.sql\": macros_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\"flags\": {\"validate_macro_args\": True}}\n\n    def test_macro_default_arg_metadata(self, project) -> None:\n        manifest = run_dbt([\"parse\"])\n        my_macro_args = manifest.macros[\"macro.test.my_macro\"].arguments\n        assert my_macro_args[0].name == \"my_arg_1\"\n        assert my_macro_args[1].name == \"my_arg_2\"\n        assert my_macro_args[2].name == \"my_arg_3\"\n\n\nclass TestMacroNameWarnings:\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"macros.sql\": macros_sql, \"macros.yml\": bad_arg_names_macros_yml}\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\"flags\": {\"validate_macro_args\": True}}\n\n    def test_macro_name_enforcement(self, project) -> None:\n        event_catcher = EventCatcher(event_to_catch=InvalidMacroAnnotation)\n        run_dbt([\"parse\"], callbacks=[event_catcher.catch])\n        assert len(event_catcher.caught_events) == 2\n        msg = \"Argument my_misnamed_arg_2 in yaml for macro my_macro does not match the jinja\"\n        assert any(\n            [e for e in event_catcher.caught_events if e.info.msg.startswith(warning_tag(msg))]\n        )\n        msg = \"Argument my_misnamed_arg_3 in yaml for macro my_macro does not match the jinja\"\n        assert any(\n            [e for e in event_catcher.caught_events if e.info.msg.startswith(warning_tag(msg))]\n        )\n\n\nclass TestMacroTypeWarnings:\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"macros.sql\": macros_sql, \"macros.yml\": bad_arg_types_macros_yml}\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\"flags\": {\"validate_macro_args\": True}}\n\n    def test_macro_type_warnings(self, project) -> None:\n        event_catcher = EventCatcher(event_to_catch=InvalidMacroAnnotation)\n        run_dbt([\"parse\"], callbacks=[event_catcher.catch])\n        assert len(event_catcher.caught_events) == 2\n        msg = \"Argument my_arg_2 in the yaml for macro my_macro has an invalid type\"\n        assert any(\n            [e for e in event_catcher.caught_events if e.info.msg.startswith(warning_tag(msg))]\n        )\n        msg = \"Argument my_arg_3 in the yaml for macro my_macro has an invalid type\"\n        assert any(\n            [e for e in event_catcher.caught_events if e.info.msg.startswith(warning_tag(msg))]\n        )\n\n\nclass TestMacroNonEnforcement:\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"macros.yml\": bad_everything_types_macros_yml, \"macros.sql\": macros_sql}\n\n    def test_macro_non_enforcement(self, project) -> None:\n        event_catcher = EventCatcher(event_to_catch=InvalidMacroAnnotation)\n        run_dbt([\"parse\"], callbacks=[event_catcher.catch])\n        assert len(event_catcher.caught_events) == 0\n"
  },
  {
    "path": "tests/functional/macros/test_macros.py",
    "content": "import shutil\nfrom pathlib import Path\n\nimport pytest\n\nimport dbt_common.exceptions\nfrom dbt.tests.fixtures.project import write_project_files\nfrom dbt.tests.util import check_relations_equal, get_manifest, run_dbt\nfrom tests.functional.macros.fixtures import (\n    dbt_project__incorrect_dispatch,\n    macros__config_sql,\n    macros__config_yml,\n    macros__deprecated_adapter_macro,\n    macros__incorrect_dispatch,\n    macros__my_macros,\n    macros__named_materialization,\n    macros__no_default_macros,\n    macros__override_get_columns_macros,\n    macros__package_override_get_columns_macros,\n    models__dep_macro,\n    models__deprecated_adapter_macro_model,\n    models__incorrect_dispatch,\n    models__local_macro,\n    models__materialization_macro,\n    models__override_get_columns_macros,\n    models__ref_macro,\n    models__with_undefined_macro,\n)\n\n\nclass TestMacros:\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project):\n        project.run_sql_file(project.test_data_dir / Path(\"seed.sql\"))\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"dep_macro.sql\": models__dep_macro,\n            \"local_macro.sql\": models__local_macro,\n            \"ref_macro.sql\": models__ref_macro,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"my_macros.sql\": macros__my_macros}\n\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\n            \"packages\": [\n                {\n                    \"git\": \"https://github.com/dbt-labs/dbt-integration-project\",\n                    \"revision\": \"dbt/1.0.0\",\n                },\n            ]\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"config-version\": 2,\n            \"vars\": {\n                \"test\": {\n                    \"test\": \"DUMMY\",\n                },\n            },\n            \"macro-paths\": [\"macros\"],\n        }\n\n    def test_working_macros(self, project):\n        run_dbt([\"deps\"])\n        results = run_dbt()\n        assert len(results) == 6\n\n        check_relations_equal(project.adapter, [\"expected_dep_macro\", \"dep_macro\"])\n        check_relations_equal(project.adapter, [\"expected_local_macro\", \"local_macro\"])\n\n\nclass TestMacrosNamedMaterialization:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"models_materialization_macro.sql\": models__materialization_macro,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"macros_named_materialization.sql\": macros__named_materialization}\n\n    def test_macro_with_materialization_in_name_works(self, project):\n        run_dbt(expect_pass=True)\n\n\nclass TestInvalidMacros:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"dep_macro.sql\": models__dep_macro,\n            \"local_macro.sql\": models__local_macro,\n            \"ref_macro.sql\": models__ref_macro,\n        }\n\n    def test_invalid_macro(self, project):\n        run_dbt(expect_pass=False)\n\n\nclass TestAdapterMacroNoDestination:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model.sql\": models__with_undefined_macro}\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"my_macros.sql\": macros__no_default_macros}\n\n    def test_invalid_macro(self, project):\n        with pytest.raises(dbt_common.exceptions.CompilationError) as exc:\n            run_dbt()\n\n        assert \"In dispatch: No macro named 'dispatch_to_nowhere' found\" in str(exc.value)\n\n\nclass TestMacroOverrideBuiltin:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model.sql\": models__override_get_columns_macros}\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"macros.sql\": macros__override_get_columns_macros}\n\n    def test_overrides(self, project):\n        # the first time, the model doesn't exist\n        run_dbt()\n        run_dbt()\n\n\nclass TestMacroOverridePackage:\n    \"\"\"\n    The macro in `override-postgres-get-columns-macros` should override the\n    `get_columns_in_relation` macro by default.\n    \"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model.sql\": models__override_get_columns_macros}\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"macros.sql\": macros__package_override_get_columns_macros}\n\n    def test_overrides(self, project):\n        # the first time, the model doesn't exist\n        run_dbt()\n        run_dbt()\n\n\nclass TestMacroNotOverridePackage:\n    \"\"\"\n    The macro in `override-postgres-get-columns-macros` does NOT override the\n    `get_columns_in_relation` macro because we tell dispatch to not look at the\n    postgres macros.\n    \"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model.sql\": models__override_get_columns_macros}\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"macros.sql\": macros__package_override_get_columns_macros}\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"dispatch\": [{\"macro_namespace\": \"dbt\", \"search_order\": [\"dbt\"]}],\n        }\n\n    def test_overrides(self, project):\n        # the first time, the model doesn't exist\n        run_dbt(expect_pass=False)\n        run_dbt(expect_pass=False)\n\n\nclass TestDispatchMacroOverrideBuiltin(TestMacroOverrideBuiltin):\n    # test the same functionality as above, but this time,\n    # dbt.get_columns_in_relation will dispatch to a default__ macro\n    # from an installed package, per dispatch config search_order\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project):\n        shutil.copytree(\n            project.test_dir / Path(\"package_macro_overrides\"),\n            project.project_root / Path(\"package_macro_overrides\"),\n        )\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"dispatch\": [\n                {\n                    \"macro_namespace\": \"dbt\",\n                    \"search_order\": [\"test\", \"package_macro_overrides\", \"dbt\"],\n                }\n            ],\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\n            \"packages\": [\n                {\n                    \"local\": \"./package_macro_overrides\",\n                },\n            ]\n        }\n\n    def test_overrides(self, project):\n        run_dbt([\"deps\"])\n        run_dbt()\n        run_dbt()\n\n\nclass TestMisnamedMacroNamespace:\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project_root):\n        test_utils_files = {\n            \"dbt_project.yml\": dbt_project__incorrect_dispatch,\n            \"macros\": {\n                \"cowsay.sql\": macros__incorrect_dispatch,\n            },\n        }\n        write_project_files(project_root, \"test_utils\", test_utils_files)\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": models__incorrect_dispatch,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\n            \"packages\": [\n                {\"local\": \"test_utils\"},\n            ]\n        }\n\n    def test_misnamed_macro_namespace(\n        self,\n        project,\n    ):\n        run_dbt([\"deps\"])\n\n        with pytest.raises(dbt_common.exceptions.CompilationError) as exc:\n            run_dbt()\n\n        assert \"In dispatch: No macro named 'cowsay' found\" in str(exc.value)\n\n\nclass TestAdapterMacroDeprecated:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model.sql\": models__deprecated_adapter_macro_model}\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"macro.sql\": macros__deprecated_adapter_macro}\n\n    def test_invalid_macro(self, project):\n        with pytest.raises(dbt_common.exceptions.CompilationError) as exc:\n            run_dbt()\n\n        assert 'The \"adapter_macro\" macro has been deprecated' in str(exc.value)\n\n\nclass TestMacroMetaDocsMerge:\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"macro_config.sql\": macros__config_sql, \"macro_config.yml\": macros__config_yml}\n\n    def test_only_top_level_defined(self, project) -> None:\n        \"\"\"If only top-level defined then it exists both in top-level and config.\"\"\"\n\n        run_dbt([\"parse\"])\n\n        manifest = get_manifest(project.project_root)\n        assert manifest is not None\n\n        macro = manifest.macros.get(\"macro.test.macro_top_only\")\n        assert macro is not None\n\n        expected_meta = {\"top_k\": \"top_v\"}\n        expected_docs_show = True\n        expected_docs_node_color = \"#AAAAAA\"\n\n        assert macro.meta == expected_meta\n        assert macro.config.meta == expected_meta\n        assert macro.docs.show == expected_docs_show\n        assert macro.docs.node_color == expected_docs_node_color\n        assert macro.config.docs.show == expected_docs_show\n        assert macro.config.docs.node_color == expected_docs_node_color\n\n    def test_only_config_defined(self, project) -> None:\n        \"\"\"If only config defined then it exists both in top-level and config.\"\"\"\n\n        run_dbt([\"parse\"])\n\n        manifest = get_manifest(project.project_root)\n        assert manifest is not None\n\n        macro = manifest.macros.get(\"macro.test.macro_config_only\")\n        assert macro is not None\n\n        expected_meta = {\"cm_k\": \"cm_v\"}\n        expected_docs_show = False\n        expected_docs_node_color = \"#BBBBBB\"\n\n        assert macro.meta == expected_meta\n        assert macro.config.meta == expected_meta\n        assert macro.docs.show == expected_docs_show\n        assert macro.docs.node_color == expected_docs_node_color\n        assert macro.config.docs.show == expected_docs_show\n        assert macro.config.docs.node_color == expected_docs_node_color\n\n    def test_both_config_and_top_level_defined(self, project) -> None:\n        \"\"\"If both defined then config overrides top-level.\"\"\"\n\n        run_dbt([\"parse\"])\n\n        manifest = get_manifest(project.project_root)\n        assert manifest is not None\n\n        macro = manifest.macros.get(\"macro.test.macro_config\")\n        assert macro is not None\n\n        expected_meta = {\n            \"top_k\": \"top_v\",\n            \"cm_k\": \"cm_v\",\n        }\n        expected_docs_show = True\n        expected_docs_node_color = \"#BBBBBB\"\n\n        assert macro.meta == expected_meta\n        assert macro.config.meta == expected_meta\n        assert macro.docs.show == expected_docs_show\n        assert macro.docs.node_color == expected_docs_node_color\n        assert macro.config.docs.show == expected_docs_show\n        assert macro.config.docs.node_color == expected_docs_node_color\n"
  },
  {
    "path": "tests/functional/manifest_validations/test_check_for_spaces_in_model_names.py",
    "content": "from typing import Dict\n\nimport pytest\n\nfrom dbt import deprecations\nfrom dbt.cli.main import dbtRunner\nfrom dbt.events.types import (\n    ResourceNamesWithSpacesDeprecation,\n    SpacesInResourceNameDeprecation,\n)\nfrom dbt.tests.util import update_config_file\nfrom dbt_common.events.base_types import EventLevel\nfrom dbt_common.events.event_catcher import EventCatcher\n\n\nclass TestSpacesInModelNamesHappyPath:\n    def test_no_warnings_when_no_spaces_in_name(self, project) -> None:\n        event_catcher = EventCatcher(SpacesInResourceNameDeprecation)\n        runner = dbtRunner(callbacks=[event_catcher.catch])\n        runner.invoke([\"parse\"])\n        assert len(event_catcher.caught_events) == 0\n\n\nclass TestSpacesInModelNamesSadPath:\n    @pytest.fixture(scope=\"class\")\n    def models(self) -> Dict[str, str]:\n        return {\n            \"my model.sql\": \"select 1 as id\",\n        }\n\n    def tests_warning_when_spaces_in_name(self, project) -> None:\n        config_patch = {\"flags\": {\"require_resource_names_without_spaces\": False}}\n        update_config_file(config_patch, project.project_root, \"dbt_project.yml\")\n        event_catcher = EventCatcher(SpacesInResourceNameDeprecation)\n        total_catcher = EventCatcher(ResourceNamesWithSpacesDeprecation)\n        runner = dbtRunner(callbacks=[event_catcher.catch, total_catcher.catch])\n        runner.invoke([\"parse\"])\n\n        assert len(total_catcher.caught_events) == 1\n        assert len(event_catcher.caught_events) == 1\n        event = event_catcher.caught_events[0]\n        assert \"Found spaces in the name of `model.test.my model`\" in event.info.msg\n        assert event.info.level == EventLevel.WARN\n\n\nclass TestSpaceInModelNamesWithDebug:\n    @pytest.fixture(scope=\"class\")\n    def models(self) -> Dict[str, str]:\n        return {\n            \"my model.sql\": \"select 1 as id\",\n            \"my model2.sql\": \"select 1 as id\",\n        }\n\n    def tests_debug_when_spaces_in_name(self, project) -> None:\n        config_patch = {\"flags\": {\"require_resource_names_without_spaces\": False}}\n        update_config_file(config_patch, project.project_root, \"dbt_project.yml\")\n        deprecations.reset_deprecations()\n        spaces_check_catcher = EventCatcher(SpacesInResourceNameDeprecation)\n        total_catcher = EventCatcher(ResourceNamesWithSpacesDeprecation)\n        runner = dbtRunner(callbacks=[spaces_check_catcher.catch, total_catcher.catch])\n        runner.invoke([\"parse\"])\n        assert len(spaces_check_catcher.caught_events) == 1\n        assert len(total_catcher.caught_events) == 1\n        assert \"Spaces found in 2 resource name(s)\" in total_catcher.caught_events[0].info.msg\n        assert (\n            \"Run again with `--debug` to see them all.\" in total_catcher.caught_events[0].info.msg\n        )\n\n        deprecations.reset_deprecations()\n        spaces_check_catcher = EventCatcher(SpacesInResourceNameDeprecation)\n        total_catcher = EventCatcher(ResourceNamesWithSpacesDeprecation)\n        runner = dbtRunner(callbacks=[spaces_check_catcher.catch, total_catcher.catch])\n        runner.invoke([\"parse\", \"--debug\"])\n        assert len(spaces_check_catcher.caught_events) == 2\n        assert len(total_catcher.caught_events) == 1\n        assert (\n            \"Run again with `--debug` to see them all.\"\n            not in total_catcher.caught_events[0].info.msg\n        )\n\n\nclass TestAllowSpacesInModelNamesFalse:\n    @pytest.fixture(scope=\"class\")\n    def models(self) -> Dict[str, str]:\n        return {\n            \"my model.sql\": \"select 1 as id\",\n        }\n\n    def test_require_resource_names_without_spaces(self, project):\n        config_patch = {\"flags\": {\"require_resource_names_without_spaces\": False}}\n        update_config_file(config_patch, project.project_root, \"dbt_project.yml\")\n        spaces_check_catcher = EventCatcher(SpacesInResourceNameDeprecation)\n        runner = dbtRunner(callbacks=[spaces_check_catcher.catch])\n        runner.invoke([\"parse\"])\n        assert len(spaces_check_catcher.caught_events) == 1\n        assert spaces_check_catcher.caught_events[0].info.level == EventLevel.WARN\n\n        config_patch = {\"flags\": {\"require_resource_names_without_spaces\": True}}\n        update_config_file(config_patch, project.project_root, \"dbt_project.yml\")\n\n        spaces_check_catcher = EventCatcher(SpacesInResourceNameDeprecation)\n        runner = dbtRunner(callbacks=[spaces_check_catcher.catch])\n        result = runner.invoke([\"parse\"])\n        assert not result.success\n        assert \"Resource names cannot contain spaces\" in result.exception.__str__()\n        assert \"my model.sql\" in result.exception.__str__()\n        assert len(spaces_check_catcher.caught_events) == 0\n"
  },
  {
    "path": "tests/functional/materializations/conftest.py",
    "content": "import pytest\n\nfrom dbt.tests.fixtures.project import write_project_files\n\noverride_view_adapter_pass_dep__dbt_project_yml = \"\"\"\nname: view_adapter_override\nversion: '1.0'\nmacro-paths: ['macros']\nconfig-version: 2\n\n\"\"\"\n\noverride_view_adapter_pass_dep__macros__override_view_sql = \"\"\"\n{# copy+pasting the default view impl #}\n{% materialization view, default %}\n\n  {%- set identifier = model['alias'] -%}\n  {%- set tmp_identifier = model['name'] + '__dbt_tmp' -%}\n  {%- set backup_identifier = model['name'] + '__dbt_backup' -%}\n\n  {%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%}\n  {%- set target_relation = api.Relation.create(identifier=identifier, schema=schema, database=database,\n                                                type='view') -%}\n  {%- set intermediate_relation = api.Relation.create(identifier=tmp_identifier,\n                                                      schema=schema, database=database, type='view') -%}\n\n  /*\n     This relation (probably) doesn't exist yet. If it does exist, it's a leftover from\n     a previous run, and we're going to try to drop it immediately. At the end of this\n     materialization, we're going to rename the \"old_relation\" to this identifier,\n     and then we're going to drop it. In order to make sure we run the correct one of:\n       - drop view ...\n       - drop table ...\n\n     We need to set the type of this relation to be the type of the old_relation, if it exists,\n     or else \"view\" as a sane default if it does not. Note that if the old_relation does not\n     exist, then there is nothing to move out of the way and subsequentally drop. In that case,\n     this relation will be effectively unused.\n  */\n  {%- set backup_relation_type = 'view' if old_relation is none else old_relation.type -%}\n  {%- set backup_relation = api.Relation.create(identifier=backup_identifier,\n                                                schema=schema, database=database,\n                                                type=backup_relation_type) -%}\n\n  {%- set exists_as_view = (old_relation is not none and old_relation.is_view) -%}\n\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\n\n  -- drop the temp relations if they exists for some reason\n  {{ adapter.drop_relation(intermediate_relation) }}\n  {{ adapter.drop_relation(backup_relation) }}\n\n  -- `BEGIN` happens here:\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\n\n  -- build model\n  {% call statement('main') -%}\n    {{ create_view_as(intermediate_relation, sql) }}\n  {%- endcall %}\n\n  -- cleanup\n  -- move the existing view out of the way\n  {% if old_relation is not none %}\n    {{ adapter.rename_relation(target_relation, backup_relation) }}\n  {% endif %}\n  {{ adapter.rename_relation(intermediate_relation, target_relation) }}\n\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\n\n  {{ adapter.commit() }}\n\n  {{ drop_relation_if_exists(backup_relation) }}\n\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\n\n  {{ return({'relations': [target_relation]}) }}\n\n{%- endmaterialization -%}\n\n\"\"\"\n\noverride_view_adapter_macros__override_view_sql = \"\"\"\n{%- materialization view, adapter='postgres' -%}\n{{ exceptions.raise_compiler_error('intentionally raising an error in the postgres view materialization') }}\n{%- endmaterialization -%}\n\n{# copy+pasting the default view impl #}\n{% materialization view, default %}\n\n  {%- set identifier = model['alias'] -%}\n  {%- set tmp_identifier = model['name'] + '__dbt_tmp' -%}\n  {%- set backup_identifier = model['name'] + '__dbt_backup' -%}\n\n  {%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%}\n  {%- set target_relation = api.Relation.create(identifier=identifier, schema=schema, database=database,\n                                                type='view') -%}\n  {%- set intermediate_relation = api.Relation.create(identifier=tmp_identifier,\n                                                      schema=schema, database=database, type='view') -%}\n\n  /*\n     This relation (probably) doesn't exist yet. If it does exist, it's a leftover from\n     a previous run, and we're going to try to drop it immediately. At the end of this\n     materialization, we're going to rename the \"old_relation\" to this identifier,\n     and then we're going to drop it. In order to make sure we run the correct one of:\n       - drop view ...\n       - drop table ...\n\n     We need to set the type of this relation to be the type of the old_relation, if it exists,\n     or else \"view\" as a sane default if it does not. Note that if the old_relation does not\n     exist, then there is nothing to move out of the way and subsequentally drop. In that case,\n     this relation will be effectively unused.\n  */\n  {%- set backup_relation_type = 'view' if old_relation is none else old_relation.type -%}\n  {%- set backup_relation = api.Relation.create(identifier=backup_identifier,\n                                                schema=schema, database=database,\n                                                type=backup_relation_type) -%}\n\n  {%- set exists_as_view = (old_relation is not none and old_relation.is_view) -%}\n\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\n\n  -- drop the temp relations if they exists for some reason\n  {{ adapter.drop_relation(intermediate_relation) }}\n  {{ adapter.drop_relation(backup_relation) }}\n\n  -- `BEGIN` happens here:\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\n\n  -- build model\n  {% call statement('main') -%}\n    {{ create_view_as(intermediate_relation, sql) }}\n  {%- endcall %}\n\n  -- cleanup\n  -- move the existing view out of the way\n  {% if old_relation is not none %}\n    {{ adapter.rename_relation(target_relation, backup_relation) }}\n  {% endif %}\n  {{ adapter.rename_relation(intermediate_relation, target_relation) }}\n\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\n\n  {{ adapter.commit() }}\n\n  {{ drop_relation_if_exists(backup_relation) }}\n\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\n\n  {{ return({'relations': [target_relation]}) }}\n\n{%- endmaterialization -%}\n\n\"\"\"\n\noverride_view_adapter_dep__dbt_project_yml = \"\"\"\nname: view_adapter_override\nversion: '1.0'\nmacro-paths: ['macros']\nconfig-version: 2\n\n\"\"\"\n\noverride_view_adapter_dep__macros__override_view_sql = \"\"\"\n{%- materialization view, adapter='postgres' -%}\n{{ exceptions.raise_compiler_error('intentionally raising an error in the postgres view materialization') }}\n{%- endmaterialization -%}\n\n{# copy+pasting the default view impl #}\n{% materialization view, default %}\n\n  {%- set identifier = model['alias'] -%}\n  {%- set tmp_identifier = model['name'] + '__dbt_tmp' -%}\n  {%- set backup_identifier = model['name'] + '__dbt_backup' -%}\n\n  {%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%}\n  {%- set target_relation = api.Relation.create(identifier=identifier, schema=schema, database=database,\n                                                type='view') -%}\n  {%- set intermediate_relation = api.Relation.create(identifier=tmp_identifier,\n                                                      schema=schema, database=database, type='view') -%}\n\n  /*\n     This relation (probably) doesn't exist yet. If it does exist, it's a leftover from\n     a previous run, and we're going to try to drop it immediately. At the end of this\n     materialization, we're going to rename the \"old_relation\" to this identifier,\n     and then we're going to drop it. In order to make sure we run the correct one of:\n       - drop view ...\n       - drop table ...\n\n     We need to set the type of this relation to be the type of the old_relation, if it exists,\n     or else \"view\" as a sane default if it does not. Note that if the old_relation does not\n     exist, then there is nothing to move out of the way and subsequentally drop. In that case,\n     this relation will be effectively unused.\n  */\n  {%- set backup_relation_type = 'view' if old_relation is none else old_relation.type -%}\n  {%- set backup_relation = api.Relation.create(identifier=backup_identifier,\n                                                schema=schema, database=database,\n                                                type=backup_relation_type) -%}\n\n  {%- set exists_as_view = (old_relation is not none and old_relation.is_view) -%}\n\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\n\n  -- drop the temp relations if they exists for some reason\n  {{ adapter.drop_relation(intermediate_relation) }}\n  {{ adapter.drop_relation(backup_relation) }}\n\n  -- `BEGIN` happens here:\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\n\n  -- build model\n  {% call statement('main') -%}\n    {{ create_view_as(intermediate_relation, sql) }}\n  {%- endcall %}\n\n  -- cleanup\n  -- move the existing view out of the way\n  {% if old_relation is not none %}\n    {{ adapter.rename_relation(target_relation, backup_relation) }}\n  {% endif %}\n  {{ adapter.rename_relation(intermediate_relation, target_relation) }}\n\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\n\n  {{ adapter.commit() }}\n\n  {{ drop_relation_if_exists(backup_relation) }}\n\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\n\n  {{ return({'relations': [target_relation]}) }}\n\n{%- endmaterialization -%}\n\n\"\"\"\n\noverride_view_default_dep__dbt_project_yml = \"\"\"\nname: view_default_override\nconfig-version: 2\nversion: '1.0'\nmacro-paths: ['macros']\n\n\"\"\"\n\noverride_view_default_dep__macros__default_view_sql = \"\"\"\n{%- materialization view, default -%}\n{{ exceptions.raise_compiler_error('intentionally raising an error in the default view materialization') }}\n{%- endmaterialization -%}\n\n\"\"\"\n\noverride_view_return_no_relation__dbt_project_yml = \"\"\"\nname: view_adapter_override\nversion: 2\nmacro-paths: ['macros']\nconfig-version: 2\n\n\"\"\"\n\noverride_view_return_no_relation__macros__override_view_sql = \"\"\"\n{# copy+pasting the default view impl #}\n{% materialization view, default %}\n\n  {%- set identifier = model['alias'] -%}\n  {%- set tmp_identifier = model['name'] + '__dbt_tmp' -%}\n  {%- set backup_identifier = model['name'] + '__dbt_backup' -%}\n\n  {%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%}\n  {%- set target_relation = api.Relation.create(identifier=identifier, schema=schema, database=database,\n                                                type='view') -%}\n  {%- set intermediate_relation = api.Relation.create(identifier=tmp_identifier,\n                                                      schema=schema, database=database, type='view') -%}\n\n  /*\n     This relation (probably) doesn't exist yet. If it does exist, it's a leftover from\n     a previous run, and we're going to try to drop it immediately. At the end of this\n     materialization, we're going to rename the \"old_relation\" to this identifier,\n     and then we're going to drop it. In order to make sure we run the correct one of:\n       - drop view ...\n       - drop table ...\n\n     We need to set the type of this relation to be the type of the old_relation, if it exists,\n     or else \"view\" as a sane default if it does not. Note that if the old_relation does not\n     exist, then there is nothing to move out of the way and subsequentally drop. In that case,\n     this relation will be effectively unused.\n  */\n  {%- set backup_relation_type = 'view' if old_relation is none else old_relation.type -%}\n  {%- set backup_relation = api.Relation.create(identifier=backup_identifier,\n                                                schema=schema, database=database,\n                                                type=backup_relation_type) -%}\n\n  {%- set exists_as_view = (old_relation is not none and old_relation.is_view) -%}\n\n  {{ run_hooks(pre_hooks, inside_transaction=False) }}\n\n  -- drop the temp relations if they exists for some reason\n  {{ adapter.drop_relation(intermediate_relation) }}\n  {{ adapter.drop_relation(backup_relation) }}\n\n  -- `BEGIN` happens here:\n  {{ run_hooks(pre_hooks, inside_transaction=True) }}\n\n  -- build model\n  {% call statement('main') -%}\n    {{ create_view_as(intermediate_relation, sql) }}\n  {%- endcall %}\n\n  -- cleanup\n  -- move the existing view out of the way\n  {% if old_relation is not none %}\n    {{ adapter.rename_relation(target_relation, backup_relation) }}\n  {% endif %}\n  {{ adapter.rename_relation(intermediate_relation, target_relation) }}\n\n  {{ run_hooks(post_hooks, inside_transaction=True) }}\n\n  {{ adapter.commit() }}\n\n  {{ drop_relation_if_exists(backup_relation) }}\n\n  {{ run_hooks(post_hooks, inside_transaction=False) }}\n\n  {# do not return anything! #}\n  {# {{ return({'relations': [target_relation]}) }} #}\n\n{%- endmaterialization -%}\n\"\"\"\n\ncustom_materialization_dep__dbt_project_yml = \"\"\"\nname: custom_materialization_default\nmacro-paths: ['macros']\n\"\"\"\n\ncustom_materialization_sql = \"\"\"\n{% materialization custom_materialization, default %}\n    {%- set target_relation = this.incorporate(type='table') %}\n    {% call statement('main') -%}\n        select 1 as column1\n    {%- endcall %}\n    {{ return({'relations': [target_relation]}) }}\n{% endmaterialization %}\n\"\"\"\n\n\n@pytest.fixture(scope=\"class\")\ndef override_view_adapter_pass_dep(project_root):\n    files = {\n        \"dbt_project.yml\": override_view_adapter_pass_dep__dbt_project_yml,\n        \"macros\": {\"override_view.sql\": override_view_adapter_pass_dep__macros__override_view_sql},\n    }\n    write_project_files(project_root, \"override-view-adapter-pass-dep\", files)\n\n\n@pytest.fixture(scope=\"class\")\ndef override_view_adapter_macros(project_root):\n    files = {\"override_view.sql\": override_view_adapter_macros__override_view_sql}\n    write_project_files(project_root, \"override-view-adapter-macros\", files)\n\n\n@pytest.fixture(scope=\"class\")\ndef override_view_adapter_dep(project_root):\n    files = {\n        \"dbt_project.yml\": override_view_adapter_dep__dbt_project_yml,\n        \"macros\": {\"override_view.sql\": override_view_adapter_dep__macros__override_view_sql},\n    }\n    write_project_files(project_root, \"override-view-adapter-dep\", files)\n\n\n@pytest.fixture(scope=\"class\")\ndef override_view_default_dep(project_root):\n    files = {\n        \"dbt_project.yml\": override_view_default_dep__dbt_project_yml,\n        \"macros\": {\"default_view.sql\": override_view_default_dep__macros__default_view_sql},\n    }\n    write_project_files(project_root, \"override-view-default-dep\", files)\n\n\n@pytest.fixture(scope=\"class\")\ndef override_view_return_no_relation(project_root):\n    files = {\n        \"dbt_project.yml\": override_view_return_no_relation__dbt_project_yml,\n        \"macros\": {\n            \"override_view.sql\": override_view_return_no_relation__macros__override_view_sql\n        },\n    }\n    write_project_files(project_root, \"override-view-return-no-relation\", files)\n\n\n@pytest.fixture(scope=\"class\")\ndef custom_materialization_dep(project_root):\n    files = {\n        \"dbt_project.yml\": custom_materialization_dep__dbt_project_yml,\n        \"macros\": {\"custom_materialization.sql\": custom_materialization_sql},\n    }\n    write_project_files(project_root, \"custom-materialization-dep\", files)\n"
  },
  {
    "path": "tests/functional/materializations/fixtures.py",
    "content": "fct_eph_first_sql = \"\"\"\n-- fct_eph_first.sql\n{{ config(materialized='ephemeral') }}\n\nwith int_eph_first as(\n    select * from {{ ref('int_eph_first') }}\n)\n\nselect * from int_eph_first\n\"\"\"\n\nint_eph_first_sql = \"\"\"\n-- int_eph_first.sql\n{{ config(materialized='ephemeral') }}\n\nselect\n    1 as first_column,\n    2 as second_column\n\"\"\"\n\nschema_yml = \"\"\"\nversion: 2\n\nmodels:\n  - name: int_eph_first\n    columns:\n      - name: first_column\n        data_tests:\n          - not_null\n      - name: second_column\n        data_tests:\n          - not_null\n\n  - name: fct_eph_first\n    columns:\n      - name: first_column\n        data_tests:\n          - not_null\n      - name: second_column\n        data_tests:\n          - not_null\n\n\"\"\"\n\nbar_sql = \"\"\"\n{{ config(materialized = 'table') }}\n\nWITH foo AS (\n\n    SELECT * FROM {{ ref('foo') }}\n\n), foo_1 AS (\n\n    SELECT * FROM {{ ref('foo_1') }}\n\n), foo_2 AS (\n\n   SELECT * FROM {{ ref('foo_2') }}\n\n)\n\nSELECT * FROM foo\nUNION ALL\nSELECT * FROM foo_1\nUNION ALL\nSELECT * FROM foo_2\n\"\"\"\n\nbar1_sql = \"\"\"\n{{ config(materialized = 'table') }}\n\nWITH foo AS (\n\n    SELECT * FROM {{ ref('foo') }}\n\n), foo_1 AS (\n\n    SELECT * FROM {{ ref('foo_1') }}\n\n), foo_2 AS (\n\n   SELECT * FROM {{ ref('foo_2') }}\n\n)\n\nSELECT * FROM foo\nUNION ALL\nSELECT * FROM foo_1\nUNION ALL\nSELECT * FROM foo_2\n\"\"\"\n\nbar2_sql = \"\"\"\n{{ config(materialized = 'table') }}\n\nWITH foo AS (\n\n    SELECT * FROM {{ ref('foo') }}\n\n), foo_1 AS (\n\n    SELECT * FROM {{ ref('foo_1') }}\n\n), foo_2 AS (\n\n   SELECT * FROM {{ ref('foo_2') }}\n\n)\n\nSELECT * FROM foo\nUNION ALL\nSELECT * FROM foo_1\nUNION ALL\nSELECT * FROM foo_2\n\"\"\"\n\nbar3_sql = \"\"\"\n{{ config(materialized = 'table') }}\n\nWITH foo AS (\n\n    SELECT * FROM {{ ref('foo') }}\n\n), foo_1 AS (\n\n    SELECT * FROM {{ ref('foo_1') }}\n\n), foo_2 AS (\n\n   SELECT * FROM {{ ref('foo_2') }}\n\n)\n\nSELECT * FROM foo\nUNION ALL\nSELECT * FROM foo_1\nUNION ALL\nSELECT * FROM foo_2\n\"\"\"\n\nbar4_sql = \"\"\"\n{{ config(materialized = 'table') }}\n\nWITH foo AS (\n\n    SELECT * FROM {{ ref('foo') }}\n\n), foo_1 AS (\n\n    SELECT * FROM {{ ref('foo_1') }}\n\n), foo_2 AS (\n\n   SELECT * FROM {{ ref('foo_2') }}\n\n)\n\nSELECT * FROM foo\nUNION ALL\nSELECT * FROM foo_1\nUNION ALL\nSELECT * FROM foo_2\n\"\"\"\n\nbar5_sql = \"\"\"\n{{ config(materialized = 'table') }}\n\nWITH foo AS (\n\n    SELECT * FROM {{ ref('foo') }}\n\n), foo_1 AS (\n\n    SELECT * FROM {{ ref('foo_1') }}\n\n), foo_2 AS (\n\n   SELECT * FROM {{ ref('foo_2') }}\n\n)\n\nSELECT * FROM foo\nUNION ALL\nSELECT * FROM foo_1\nUNION ALL\nSELECT * FROM foo_2\n\"\"\"\n\nbaz_sql = \"\"\"\n{{ config(materialized = 'table') }}\nSELECT * FROM {{ ref('bar') }}\n\"\"\"\n\nbaz1_sql = \"\"\"\n{{ config(materialized = 'table') }}\nSELECT * FROM {{ ref('bar_1') }}\n\"\"\"\n\nfoo_sql = \"\"\"\n{{ config(materialized = 'ephemeral') }}\n\nwith source as (\n\n    select 1 as id\n\n), renamed as (\n\n    select id as uid from source\n\n)\n\nselect * from renamed\n\"\"\"\n\nfoo1_sql = \"\"\"\n{{ config(materialized = 'ephemeral') }}\n\nWITH source AS (\n\n    SELECT 1 AS id\n\n), RENAMED as (\n\n    SELECT id as UID FROM source\n\n)\n\nSELECT * FROM renamed\n\"\"\"\n\nfoo2_sql = \"\"\"\n{{ config(materialized = 'ephemeral') }}\n\nWITH source AS (\n\n    SELECT 1 AS id\n\n), RENAMED as (\n\n    SELECT id as UID FROM source\n\n)\n\nSELECT * FROM renamed\n\"\"\"\n"
  },
  {
    "path": "tests/functional/materializations/test_custom_materialization.py",
    "content": "from collections import defaultdict\n\nimport pytest\n\nfrom dbt import deprecations\nfrom dbt.tests.util import run_dbt\n\nmodels__model_sql = \"\"\"\n{{ config(materialized='view') }}\nselect 1 as id\n\n\"\"\"\n\n\nmodels_custom_materialization__model_sql = \"\"\"\n{{ config(materialized='custom_materialization') }}\nselect 1 as id\n\n\"\"\"\n\n\n@pytest.fixture(scope=\"class\")\ndef models():\n    return {\"model.sql\": models__model_sql}\n\n\n@pytest.fixture(scope=\"class\")\ndef set_up_deprecations():\n    deprecations.reset_deprecations()\n    assert deprecations.active_deprecations == defaultdict(int)\n\n\nclass TestOverrideAdapterDependency:\n    # make sure that if there's a dependency with an adapter-specific\n    # materialization, we honor that materialization\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\"packages\": [{\"local\": \"override-view-adapter-dep\"}]}\n\n    def test_adapter_dependency(self, project, override_view_adapter_dep, set_up_deprecations):\n        run_dbt([\"deps\"])\n        # this should pass because implicit overrides are now deprecated (= disabled by default)\n        run_dbt([\"run\"])\n\n\nclass TestOverrideAdapterDependencyDeprecated:\n    # make sure that if there's a dependency with an adapter-specific\n    # materialization, we honor that materialization\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\"packages\": [{\"local\": \"override-view-adapter-dep\"}]}\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"flags\": {\n                \"require_explicit_package_overrides_for_builtin_materializations\": True,\n            },\n        }\n\n    def test_adapter_dependency_deprecate_overrides(\n        self, project, override_view_adapter_dep, set_up_deprecations\n    ):\n        run_dbt([\"deps\"])\n        # this should pass because the override is buggy and unused\n        run_dbt([\"run\"])\n\n        # no deprecation warning -- flag used correctly\n        assert deprecations.active_deprecations == defaultdict(int)\n\n\nclass TestOverrideAdapterDependencyLegacy:\n    # make sure that if there's a dependency with an adapter-specific\n    # materialization, we honor that materialization\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\"packages\": [{\"local\": \"override-view-adapter-dep\"}]}\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"flags\": {\n                \"require_explicit_package_overrides_for_builtin_materializations\": False,\n            },\n        }\n\n    def test_adapter_dependency(self, project, override_view_adapter_dep, set_up_deprecations):\n        run_dbt([\"deps\"])\n        # this should error because the override is buggy\n        run_dbt([\"run\"], expect_pass=False)\n\n        # overriding a built-in materialization scoped to adapter from package is deprecated\n        assert \"package-materialization-override\" in deprecations.active_deprecations\n\n\nclass TestOverrideDefaultDependency:\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\"packages\": [{\"local\": \"override-view-default-dep\"}]}\n\n    def test_default_dependency(self, project, override_view_default_dep, set_up_deprecations):\n        run_dbt([\"deps\"])\n        # this should pass because implicit overrides are now deprecated (= disabled by default)\n        run_dbt([\"run\"])\n\n\nclass TestOverrideDefaultDependencyDeprecated:\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\"packages\": [{\"local\": \"override-view-default-dep\"}]}\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"flags\": {\n                \"require_explicit_package_overrides_for_builtin_materializations\": True,\n            },\n        }\n\n    def test_default_dependency_deprecated(\n        self, project, override_view_default_dep, set_up_deprecations\n    ):\n        run_dbt([\"deps\"])\n        # this should pass because the override is buggy and unused\n        run_dbt([\"run\"])\n\n        # overriding a built-in materialization from package is deprecated\n        assert deprecations.active_deprecations == defaultdict(int)\n\n\nclass TestOverrideDefaultDependencyLegacy:\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\"packages\": [{\"local\": \"override-view-default-dep\"}]}\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"flags\": {\n                \"require_explicit_package_overrides_for_builtin_materializations\": False,\n            },\n        }\n\n    def test_default_dependency(self, project, override_view_default_dep, set_up_deprecations):\n        run_dbt([\"deps\"])\n        # this should error because the override is buggy\n        run_dbt([\"run\"], expect_pass=False)\n\n        # overriding a built-in materialization from package is deprecated\n        assert \"package-materialization-override\" in deprecations.active_deprecations\n\n\nroot_view_override_macro = \"\"\"\n{% materialization view, default %}\n {{ return(view_default_override.materialization_view_default()) }}\n{% endmaterialization %}\n\"\"\"\n\n\nclass TestOverrideDefaultDependencyRootOverride:\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\"packages\": [{\"local\": \"override-view-default-dep\"}]}\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"my_view.sql\": root_view_override_macro}\n\n    def test_default_dependency_with_root_override(\n        self, project, override_view_default_dep, set_up_deprecations\n    ):\n        run_dbt([\"deps\"])\n        # this should error because the override is buggy\n        run_dbt([\"run\"], expect_pass=False)\n\n        # using an package-overriden built-in materialization in a root matereialization is _not_ deprecated\n        assert deprecations.active_deprecations == defaultdict(int)\n\n\nclass TestCustomMaterializationDependency:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model.sql\": models_custom_materialization__model_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\"packages\": [{\"local\": \"custom-materialization-dep\"}]}\n\n    def test_custom_materialization_deopendency(\n        self, project, custom_materialization_dep, set_up_deprecations\n    ):\n        run_dbt([\"deps\"])\n        # custom materilization is valid\n        run_dbt([\"run\"])\n\n        # using a custom materialization is from an installed package is _not_ deprecated\n        assert deprecations.active_deprecations == defaultdict(int)\n\n\nclass TestOverrideAdapterDependencyPassing:\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\"packages\": [{\"local\": \"override-view-adapter-pass-dep\"}]}\n\n    def test_default_dependency(self, project, override_view_adapter_pass_dep):\n        run_dbt([\"deps\"])\n        # this should pass because the override is ok\n        run_dbt([\"run\"])\n\n\nclass TestOverrideAdapterLocal:\n    # make sure that the local default wins over the dependency\n    # adapter-specific\n\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\"packages\": [{\"local\": \"override-view-adapter-pass-dep\"}]}\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\"macro-paths\": [\"override-view-adapter-macros\"]}\n\n    def test_default_dependency(\n        self, project, override_view_adapter_pass_dep, override_view_adapter_macros\n    ):\n        run_dbt([\"deps\"])\n        # this should error because the override is buggy\n        run_dbt([\"run\"], expect_pass=False)\n\n\nclass TestOverrideDefaultReturn:\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\"macro-paths\": [\"override-view-return-no-relation\"]}\n\n    def test_default_dependency(self, project, override_view_return_no_relation):\n        run_dbt([\"deps\"])\n        results = run_dbt([\"run\"], expect_pass=False)\n        assert \"did not explicitly return a list of relations\" in results[0].message\n"
  },
  {
    "path": "tests/functional/materializations/test_ephemeral_compilation.py",
    "content": "import pytest\n\nfrom dbt.contracts.graph.nodes import ModelNode\nfrom dbt.contracts.results import RunExecutionResult, RunResult\nfrom dbt.tests.util import run_dbt\nfrom tests.functional.materializations.fixtures import (\n    bar1_sql,\n    bar2_sql,\n    bar3_sql,\n    bar4_sql,\n    bar5_sql,\n    bar_sql,\n    baz1_sql,\n    baz_sql,\n    fct_eph_first_sql,\n    foo1_sql,\n    foo2_sql,\n    foo_sql,\n    int_eph_first_sql,\n    schema_yml,\n)\n\n# Note: This tests compilation only, so is a dbt Core test and not an adapter test.\n# There is some complicated logic in core/dbt/compilation.py having to do with\n# ephemeral nodes and handling multiple threads at the same time. This test\n# fails fairly regularly if that is broken, but does occasionally work (depending\n# on the order in which things are compiled). It requires multi-threading to fail.\n\n\nSUPPRESSED_CTE_EXPECTED_OUTPUT = \"\"\"-- fct_eph_first.sql\n\n\nwith int_eph_first as(\n    select * from __dbt__cte__int_eph_first\n)\n\nselect * from int_eph_first\"\"\"\n\n\nclass TestEphemeralCompilation:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"int_eph_first.sql\": int_eph_first_sql,\n            \"fct_eph_first.sql\": fct_eph_first_sql,\n            \"schema.yml\": schema_yml,\n        }\n\n    def test_ephemeral_compilation(self, project):\n        # Note: There are no models that run successfully. This testcase tests running tests.\n        results = run_dbt([\"run\"])\n        assert len(results) == 0\n\n    def test__suppress_injected_ctes(self, project):\n        compile_output = run_dbt(\n            [\"compile\", \"--no-inject-ephemeral-ctes\", \"--select\", \"fct_eph_first\"]\n        )\n        assert isinstance(compile_output, RunExecutionResult)\n        node_result = compile_output.results[0]\n        assert isinstance(node_result, RunResult)\n        node = node_result.node\n        assert isinstance(node, ModelNode)\n        assert node.compiled_code == SUPPRESSED_CTE_EXPECTED_OUTPUT\n\n\n# From: https://github.com/jeremyyeo/ephemeral-invalid-sql-repro/tree/main/models\nclass TestLargeEphemeralCompilation:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n\n        return {\n            \"bar.sql\": bar_sql,\n            \"bar_1.sql\": bar1_sql,\n            \"bar_2.sql\": bar2_sql,\n            \"bar_3.sql\": bar3_sql,\n            \"bar_4.sql\": bar4_sql,\n            \"bar_5.sql\": bar5_sql,\n            \"baz.sql\": baz_sql,\n            \"baz_1.sql\": baz1_sql,\n            \"foo.sql\": foo_sql,\n            \"foo_1.sql\": foo1_sql,\n            \"foo_2.sql\": foo2_sql,\n        }\n\n    def test_ephemeral_compilation(self, project):\n        # 8/11 table models are built as expected. no compilation errors\n        results = run_dbt([\"build\"])\n        assert len(results) == 8\n"
  },
  {
    "path": "tests/functional/materializations/test_incremental.py",
    "content": "import pytest\n\nfrom dbt.context.providers import generate_runtime_model_context\nfrom dbt.exceptions import DbtRuntimeError\nfrom dbt.tests.util import get_manifest, run_dbt\n\nmy_model_sql = \"\"\"\n  select 1 as fun\n\"\"\"\n\n\n@pytest.fixture(scope=\"class\")\ndef models():\n    return {\"my_model.sql\": my_model_sql}\n\n\ndef test_basic(project):\n    results = run_dbt([\"run\"])\n    assert len(results) == 1\n\n    manifest = get_manifest(project.project_root)\n    model = manifest.nodes[\"model.test.my_model\"]\n\n    # Normally the context will be provided by the macro that calls the\n    # get_incrmental_strategy_macro method, but for testing purposes\n    # we create a runtime_model_context.\n    context = generate_runtime_model_context(\n        model,\n        project.adapter.config,\n        manifest,\n    )\n\n    macro_func = project.adapter.get_incremental_strategy_macro(context, \"default\")\n    assert macro_func\n    assert type(macro_func).__name__ == \"MacroGenerator\"\n\n    macro_func = project.adapter.get_incremental_strategy_macro(context, \"append\")\n    assert macro_func\n    assert type(macro_func).__name__ == \"MacroGenerator\"\n\n    macro_func = project.adapter.get_incremental_strategy_macro(context, \"delete+insert\")\n    assert macro_func\n    assert type(macro_func).__name__ == \"MacroGenerator\"\n\n    # This incremental strategy only works for Postgres >= 15\n    macro_func = project.adapter.get_incremental_strategy_macro(context, \"merge\")\n    assert macro_func\n    assert type(macro_func).__name__ == \"MacroGenerator\"\n\n    # This incremental strategy is not valid for Postgres\n    with pytest.raises(DbtRuntimeError) as excinfo:\n        macro_func = project.adapter.get_incremental_strategy_macro(context, \"insert_overwrite\")\n    assert \"insert_overwrite\" in str(excinfo.value)\n"
  },
  {
    "path": "tests/functional/materializations/test_incremental_with_contract.py",
    "content": "import pytest\n\nfrom dbt.tests.util import (\n    check_relations_equal,\n    get_relation_columns,\n    relation_from_name,\n    run_dbt,\n)\n\nseeds_base_csv = \"\"\"\nid,name_xxx,some_date\n1,Easton,1981-05-20T06:46:51\n2,Lillian,1978-09-03T18:10:33\n3,Jeremiah,1982-03-11T03:59:51\n4,Nolan,1976-05-06T20:21:35\n5,Hannah,1982-06-23T05:41:26\n6,Eleanor,1991-08-10T23:12:21\n7,Lily,1971-03-29T14:58:02\n8,Jonathan,1988-02-26T02:55:24\n9,Adrian,1994-02-09T13:14:23\n10,Nora,1976-03-01T16:51:39\n\"\"\".lstrip()\n\n\nseeds_added_csv = (\n    seeds_base_csv\n    + \"\"\"\n11,Mateo,2014-09-07T17:04:27\n12,Julian,2000-02-04T11:48:30\n13,Gabriel,2001-07-10T07:32:52\n14,Isaac,2002-11-24T03:22:28\n15,Levi,2009-11-15T11:57:15\n16,Elizabeth,2005-04-09T03:50:11\n17,Grayson,2019-08-06T19:28:17\n18,Dylan,2014-03-01T11:50:41\n19,Jayden,2009-06-06T07:12:49\n20,Luke,2003-12-05T21:42:18\n\"\"\".lstrip()\n)\n\nincremental_not_schema_change_sql = \"\"\"\n{{ config(materialized=\"incremental\", unique_key=\"user_id_current_time\",on_schema_change=\"sync_all_columns\") }}\nselect\n    1 || '-' || current_timestamp as user_id_current_time,\n    {% if is_incremental() %}\n        'thisis18characters' as platform\n    {% else %}\n        'okthisis20characters' as platform\n    {% endif %}\n\"\"\"\n\nincremental_sql = \"\"\"\n  {{ config(materialized=\"incremental\") }}\n  select * from {{ source('raw', 'seed') }}\n  {% if is_incremental() %}\n  where id > (select max(id) from {{ this }})\n  {% endif %}\n\"\"\"\n\nschema_base_yml = \"\"\"\nsources:\n  - name: raw\n    schema: \"{{ target.schema }}\"\n    tables:\n      - name: seed\n        identifier: \"{{ var('seed_name', 'base') }}\"\n\nmodels:\n  - name: incremental\n    config:\n      contract:\n        enforced: true\n      on_schema_change: append_new_columns\n    columns:\n      - name: id\n        data_type: int\n      - name: name_xxx\n        data_type: character varying(10)\n      - name: some_date\n        data_type: timestamp\n\"\"\"\n\n\nclass TestIncremental:\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\"name\": \"incremental\"}\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"incremental.sql\": incremental_sql, \"schema.yml\": schema_base_yml}\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\"base.csv\": seeds_base_csv, \"added.csv\": seeds_added_csv}\n\n    def test_incremental(self, project):\n        # seed command\n        results = run_dbt([\"seed\"])\n        assert len(results) == 2\n\n        # base table rowcount\n        relation = relation_from_name(project.adapter, \"base\")\n        result = project.run_sql(f\"select count(*) as num_rows from {relation}\", fetch=\"one\")\n        assert result[0] == 10\n\n        # added table rowcount\n        relation = relation_from_name(project.adapter, \"added\")\n        result = project.run_sql(f\"select count(*) as num_rows from {relation}\", fetch=\"one\")\n        assert result[0] == 20\n\n        # run command\n        # the \"seed_name\" var changes the seed identifier in the schema file\n        results = run_dbt([\"run\", \"--vars\", \"seed_name: base\"])\n        assert len(results) == 1\n\n        # check relations equal\n        check_relations_equal(project.adapter, [\"base\", \"incremental\"])\n\n        # change seed_name var\n        # the \"seed_name\" var changes the seed identifier in the schema file\n        results = run_dbt([\"run\", \"--debug\", \"--vars\", \"seed_name: added\"])\n        assert len(results) == 1\n\n        # Error before fix:  Changing col type from character varying(10) to character varying(256) in table:\n        #  \"dbt\".\"test<...>_test_incremental_with_contract\".\"incremental\"\n        columns = get_relation_columns(project.adapter, \"incremental\")\n        # [('id', 'integer', None), ('name_xxx', 'character varying', 10), ('some_date', 'timestamp without time zone', None)]\n        for column in columns:\n            if column[0] == \"name_xxx\":\n                assert column[2] == 10\n"
  },
  {
    "path": "tests/functional/materializations/test_runtime_materialization.py",
    "content": "import pytest\n\nfrom dbt.tests.util import check_relations_equal, check_table_does_not_exist, run_dbt\n\nmodels__view_sql = \"\"\"\n{{\n  config(\n    materialized = \"view\"\n  )\n}}\n\nselect * from {{ this.schema }}.seed\n\n{% if is_incremental() %}\n    {% do exceptions.raise_compiler_error(\"is_incremental() evaluated to True in a view\") %}\n{% endif %}\n\n\"\"\"\n\nmodels__incremental_sql = \"\"\"\n{{\n  config(\n    materialized = \"incremental\"\n  )\n}}\n\nselect * from {{ this.schema }}.seed\n\n{% if is_incremental() %}\n\n    where id > (select max(id) from {{this}})\n\n{% endif %}\n\n\"\"\"\n\nmodels__materialized_sql = \"\"\"\n{{\n  config(\n    materialized = \"table\"\n  )\n}}\n\nselect * from {{ this.schema }}.seed\n\n{% if is_incremental() %}\n    {% do exceptions.raise_compiler_error(\"is_incremental() evaluated to True in a table\") %}\n{% endif %}\n\n\"\"\"\n\nseeds__seed_csv = \"\"\"id,first_name,last_name,email,gender,ip_address\n1,Jack,Hunter,jhunter0@pbs.org,Male,59.80.20.168\n2,Kathryn,Walker,kwalker1@ezinearticles.com,Female,194.121.179.35\n3,Gerald,Ryan,gryan2@com.com,Male,11.3.212.243\n4,Bonnie,Spencer,bspencer3@ameblo.jp,Female,216.32.196.175\n5,Harold,Taylor,htaylor4@people.com.cn,Male,253.10.246.136\n6,Jacqueline,Griffin,jgriffin5@t.co,Female,16.13.192.220\n7,Wanda,Arnold,warnold6@google.nl,Female,232.116.150.64\n8,Craig,Ortiz,cortiz7@sciencedaily.com,Male,199.126.106.13\n9,Gary,Day,gday8@nih.gov,Male,35.81.68.186\n10,Rose,Wright,rwright9@yahoo.co.jp,Female,236.82.178.100\n\"\"\"\n\ninvalidate_incremental_sql = \"\"\"\ninsert into {schema}.incremental (first_name, last_name, email, gender, ip_address) values\n    ('Hank', 'Hund', 'hank@yahoo.com', 'Male', '101.239.70.175');\n\"\"\"\n\nupdate_sql = \"\"\"\n-- create a view on top of the models\ncreate view {schema}.dependent_view as (\n\n    select count(*) from {schema}.materialized\n    union all\n    select count(*) from {schema}.view\n    union all\n    select count(*) from {schema}.incremental\n\n);\n\ninsert into {schema}.seed (id, first_name, last_name, email, gender, ip_address) values (101, 'Michael', 'Perez', 'mperez0@chronoengine.com', 'Male', '106.239.70.175');\ninsert into {schema}.seed (id, first_name, last_name, email, gender, ip_address) values (102, 'Shawn', 'Mccoy', 'smccoy1@reddit.com', 'Male', '24.165.76.182');\ninsert into {schema}.seed (id, first_name, last_name, email, gender, ip_address) values (103, 'Kathleen', 'Payne', 'kpayne2@cargocollective.com', 'Female', '113.207.168.106');\ninsert into {schema}.seed (id, first_name, last_name, email, gender, ip_address) values (104, 'Jimmy', 'Cooper', 'jcooper3@cargocollective.com', 'Male', '198.24.63.114');\ninsert into {schema}.seed (id, first_name, last_name, email, gender, ip_address) values (105, 'Katherine', 'Rice', 'krice4@typepad.com', 'Female', '36.97.186.238');\n\"\"\"\n\ncreate_view__dbt_tmp_sql = \"\"\"\ncreate view {schema}.view__dbt_tmp as (\n    select 1 as id\n);\n\"\"\"\n\ncreate_view__dbt_backup_sql = \"\"\"\ncreate view {schema}.view__dbt_backup as (\n    select 1 as id\n);\n\"\"\"\n\ncreate_incremental__dbt_tmp_sql = \"\"\"\ncreate table {schema}.incremental__dbt_tmp as (\n    select 1 as id\n);\n\"\"\"\n\n\n@pytest.fixture(scope=\"class\")\ndef models():\n    return {\n        \"view.sql\": models__view_sql,\n        \"incremental.sql\": models__incremental_sql,\n        \"materialized.sql\": models__materialized_sql,\n    }\n\n\n@pytest.fixture(scope=\"class\")\ndef seeds():\n    return {\"seed.csv\": seeds__seed_csv}\n\n\n@pytest.fixture(scope=\"class\", autouse=True)\ndef setup(project):\n    run_dbt([\"seed\"])\n\n\nclass TestRuntimeMaterialization:\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"seeds\": {\n                \"quote_columns\": False,\n            }\n        }\n\n    def test_full_refresh(\n        self,\n        project,\n    ):\n        # initial full-refresh should have no effect\n        results = run_dbt([\"run\", \"-f\"])\n        assert len(results) == 3\n\n        check_relations_equal(project.adapter, [\"seed\", \"view\", \"incremental\", \"materialized\"])\n\n        # adds one record to the incremental model. full-refresh should truncate then re-run\n        project.run_sql(invalidate_incremental_sql)\n        results = run_dbt([\"run\", \"-f\"])\n        assert len(results) == 3\n        check_relations_equal(project.adapter, [\"seed\", \"incremental\"])\n\n        project.run_sql(update_sql)\n\n        results = run_dbt([\"run\", \"-f\"])\n        assert len(results) == 3\n\n        check_relations_equal(project.adapter, [\"seed\", \"view\", \"incremental\", \"materialized\"])\n\n    def test_delete_dbt_tmp_relation(\n        self,\n        project,\n    ):\n        # This creates a __dbt_tmp view - make sure it doesn't interfere with the dbt run\n        project.run_sql(create_view__dbt_tmp_sql)\n        results = run_dbt([\"run\", \"--model\", \"view\"])\n        assert len(results) == 1\n\n        check_table_does_not_exist(project.adapter, \"view__dbt_tmp\")\n        check_relations_equal(project.adapter, [\"seed\", \"view\"])\n\n        # Again, but with a __dbt_backup view\n        project.run_sql(create_view__dbt_backup_sql)\n        results = run_dbt([\"run\", \"--model\", \"view\"])\n        assert len(results) == 1\n\n        check_table_does_not_exist(project.adapter, \"view__dbt_backup\")\n        check_relations_equal(project.adapter, [\"seed\", \"view\"])\n\n        # Again, but against the incremental materialization\n        results = run_dbt([\"run\", \"--model\", \"incremental\"])\n        project.run_sql(create_incremental__dbt_tmp_sql)\n        assert len(results) == 1\n\n        results = run_dbt([\"run\", \"--model\", \"incremental\", \"-f\"])\n        assert len(results) == 1\n\n        check_table_does_not_exist(project.adapter, \"incremental__dbt_tmp\")\n        check_relations_equal(project.adapter, [\"seed\", \"incremental\"])\n\n\n# Run same tests with models configured with full_refresh\nclass TestRuntimeMaterializationWithConfig(TestRuntimeMaterialization):\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"seeds\": {\n                \"quote_columns\": False,\n            },\n            \"models\": {\"full_refresh\": True},\n        }\n"
  },
  {
    "path": "tests/functional/materializations/test_supported_languages.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt\n\ncustom_mat_tmpl = \"\"\"\n{% materialization custom_mat{} %}\n    {%- set target_relation = this.incorporate(type='table') %}\n    {% call statement('main') -%}\n        select 1 as column1\n    {%- endcall %}\n    {{ return({'relations': [target_relation]}) }}\n{% endmaterialization %}\n\"\"\"\n\nmodels__sql_model = \"\"\"\n{{ config(materialized='custom_mat') }}\nselect 1 as fun\n\"\"\"\n\nmodels__py_model = \"\"\"\ndef model(dbt, session):\n    dbt.config(materialized='custom_mat')\n    return\n\"\"\"\n\n\nclass SupportedLanguageBase:\n    model_map = {\n        \"sql\": (\"sql_model.sql\", models__sql_model),\n        \"python\": (\"py_model.py\", models__py_model),\n    }\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        custom_mat = custom_mat_tmpl.replace(\"{}\", \"\")\n\n        if hasattr(self, \"supported_langs\"):\n            custom_mat = custom_mat_tmpl.replace(\n                \"{}\", f\", supported_languages=[{self.lang_list()}]\"\n            )\n        return {\"custom_mat.sql\": custom_mat}\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        file_name, model = self.model_map[self.use_lang]\n        return {file_name: model}\n\n    def lang_list(self):\n        return \", \".join([f\"'{l}'\" for l in self.supported_langs])\n\n    def test_language(self, project):\n        result = run_dbt([\"run\"], expect_pass=self.expect_pass)\n        if not self.expect_pass:\n            assert \"only supports languages\" in result.results[0].message\n\n\nclass TestSupportedLanguages_SupportsDefault_UsingSql(SupportedLanguageBase):\n    use_lang = \"sql\"\n    expect_pass = True\n\n\nclass TestSupportedLanguages_SupportsDefault_UsingPython(SupportedLanguageBase):\n    use_lang = \"python\"\n    expect_pass = False\n\n\nclass TestSupportedLanguages_SupportsSql_UsingSql(SupportedLanguageBase):\n    supported_langs = [\"sql\"]\n    use_lang = \"sql\"\n    expect_pass = True\n\n\nclass TestSupportedLanguages_SuppotsSql_UsingPython(SupportedLanguageBase):\n    supported_langs = [\"sql\"]\n    use_lang = \"python\"\n    expect_pass = False\n\n\nclass TestSupportedLanguages_SuppotsPython_UsingSql(SupportedLanguageBase):\n    supported_langs = [\"python\"]\n    use_lang = \"sql\"\n    expect_pass = False\n\n\nclass TestSupportedLanguages_SuppotsPython_UsingPython(SupportedLanguageBase):\n    supported_langs = [\"python\"]\n    use_lang = \"python\"\n    expect_pass = True\n\n\nclass TestSupportedLanguages_SuppotsSqlAndPython_UsingSql(SupportedLanguageBase):\n    supported_langs = [\"sql\", \"python\"]\n    use_lang = \"sql\"\n    expect_pass = True\n\n\nclass TestSupportedLanguages_SuppotsSqlAndPython_UsingPython(SupportedLanguageBase):\n    supported_langs = [\"sql\", \"python\"]\n    use_lang = \"python\"\n    expect_pass = True\n"
  },
  {
    "path": "tests/functional/metrics/fixtures.py",
    "content": "# not strictly necessary, but this reflects the integration tests currently in the 'dbt-metrics' package right now\n# i'm including just the first 10 rows for more concise 'git diff'\n\nmock_purchase_data_csv = \"\"\"purchased_at,payment_type,payment_total\n2021-02-14 17:52:36,maestro,2418.94\n2021-02-15 04:16:50,jcb,3043.28\n2021-02-15 11:30:45,solo,1505.81\n2021-02-16 13:08:18,,1532.85\n2021-02-17 05:41:34,americanexpress,319.91\n2021-02-18 06:47:32,jcb,2143.44\n2021-02-19 01:37:09,jcb,840.1\n2021-02-19 03:38:49,jcb,1388.18\n2021-02-19 04:22:41,jcb,2834.96\n2021-02-19 13:28:50,china-unionpay,2440.98\n\"\"\".strip()\n\nmodels_people_sql = \"\"\"\nselect 1 as id, 'Drew' as first_name, 'Banin' as last_name, 'yellow' as favorite_color, true as loves_dbt, 5 as tenure, current_timestamp as created_at\nunion all\nselect 2 as id, 'Jeremy' as first_name, 'Cohen' as last_name, 'indigo' as favorite_color, true as loves_dbt, 4 as tenure, current_timestamp as created_at\nunion all\nselect 3 as id, 'Callum' as first_name, 'McCann' as last_name, 'emerald' as favorite_color, true as loves_dbt, 0 as tenure, current_timestamp as created_at\n\"\"\"\n\nsemantic_model_people_yml = \"\"\"\nversion: 2\n\nsemantic_models:\n  - name: semantic_people\n    model: ref('people')\n    dimensions:\n      - name: favorite_color\n        type: categorical\n      - name: created_at\n        type: TIME\n        type_params:\n          time_granularity: day\n    measures:\n      - name: years_tenure\n        agg: SUM\n        expr: tenure\n      - name: people\n        agg: count\n        expr: id\n    entities:\n      - name: id\n        type: primary\n    defaults:\n      agg_time_dimension: created_at\n\"\"\"\n\nbasic_metrics_yml = \"\"\"\nversion: 2\n\nmetrics:\n\n  - name: number_of_people\n    label: \"Number of people\"\n    description: Total count of people\n    type: simple\n    type_params:\n      measure: people\n    meta:\n        my_meta: 'testing'\n\n  - name: collective_tenure\n    label: \"Collective tenure\"\n    description: Total number of years of team experience\n    type: simple\n    type_params:\n      measure:\n        name: \"years_tenure\"\n        filter: \"{{ Dimension('id__loves_dbt') }} is true\"\n\n  - name: average_tenure\n    label: \"Average tenure\"\n    description: \"The average tenure per person\"\n    type: ratio\n    type_params:\n      numerator: collective_tenure\n      denominator: number_of_people\n\n  - name: average_tenure_plus_one\n    label: \"Average tenure, plus 1\"\n    description: \"The average tenure per person\"\n    type: derived\n    type_params:\n      metrics:\n        - average_tenure\n      expr: \"average_tenure + 1\"\n\n  - name: tenured_people\n    label: Tenured People\n    description: People who have been here more than 1 year\n    type: simple\n    type_params:\n      measure: people\n    filter: \"{{ Metric('collective_tenure', ['id']) }} > 2\"\n\"\"\"\n\nmetricflow_time_spine_sql = \"\"\"\nSELECT to_date('02/20/2023, 'mm/dd/yyyy') as date_day\n\"\"\"\n\nmodels_people_metrics_yml = \"\"\"\nversion: 2\n\nmetrics:\n\n  - name: number_of_people\n    label: \"Number of people\"\n    description: Total count of people\n    type: simple\n    type_params:\n      measure: people\n    time_granularity: month\n    config:\n      meta:\n        my_meta_config: 'config'\n\n  - name: collective_tenure\n    label: \"Collective tenure\"\n    description: Total number of years of team experience\n    type: simple\n    type_params:\n      measure:\n        name: years_tenure\n        filter: \"{{ Dimension('id__loves_dbt') }} is true\"\n        join_to_timespine: true\n        fill_nulls_with: 0\n\n  - name: collective_window\n    label: \"Collective window\"\n    description: Testing window\n    type: simple\n    type_params:\n      measure:\n        name: years_tenure\n        filter: \"{{ Dimension('id__loves_dbt') }} is true\"\n      window: 14 days\n\n  - name: average_tenure\n    label: Average Tenure\n    description: The average tenure of our people\n    type: ratio\n    type_params:\n      numerator: collective_tenure\n      denominator: number_of_people\n\n  - name: average_tenure_minus_people\n    label: Average Tenure minus People\n    description: Well this isn't really useful is it?\n    type: derived\n    type_params:\n      expr: average_tenure - number_of_people\n      metrics:\n        - average_tenure\n        - number_of_people\n\n\"\"\"\n\nmodels_people_metrics_meta_top_yml = \"\"\"\nversion: 2\n\nmetrics:\n\n  - name: number_of_people\n    label: \"Number of people\"\n    description: Total count of people\n    type: simple\n    type_params:\n      measure: people\n    meta:\n        my_meta_top: 'top'\n\n  - name: collective_tenure\n    label: \"Collective tenure\"\n    description: Total number of years of team experience\n    type: simple\n    type_params:\n      measure:\n        name: years_tenure\n        filter: \"{{ Dimension('id__loves_dbt') }} is true\"\n        join_to_timespine: true\n        fill_nulls_with: 0\n\n  - name: collective_window\n    label: \"Collective window\"\n    description: Testing window\n    type: simple\n    type_params:\n      measure:\n        name: years_tenure\n        filter: \"{{ Dimension('id__loves_dbt') }} is true\"\n      window: 14 days\n\n  - name: average_tenure\n    label: Average Tenure\n    description: The average tenure of our people\n    type: ratio\n    type_params:\n      numerator: collective_tenure\n      denominator: number_of_people\n\n  - name: average_tenure_minus_people\n    label: Average Tenure minus People\n    description: Well this isn't really useful is it?\n    type: derived\n    type_params:\n      expr: average_tenure - number_of_people\n      metrics:\n        - average_tenure\n        - number_of_people\n\n\"\"\"\n\ninvalid_models_people_metrics_yml = \"\"\"\nversion: 2\n\nmetrics:\n\n  - name: number_of_people\n    label: \"Number of people\"\n    description: Total count of people\n    model: \"ref(people)\"\n    calculation_method: count\n    expression: \"*\"\n    timestamp: created_at\n    time_grains: [day, week, month]\n    dimensions:\n      - favorite_color\n      - loves_dbt\n    meta:\n        my_meta: 'testing'\n\n  - name: collective_tenure\n    label: \"Collective tenure\"\n    description: Total number of years of team experience\n    model: \"ref(people)\"\n    calculation_method: sum\n    expression: tenure\n    timestamp: created_at\n    time_grains: [day]\n    filters:\n      - field: loves_dbt\n        operator: 'is'\n        value: 'true'\n\n\"\"\"\n\ninvalid_metrics_missing_model_yml = \"\"\"\nversion: 2\n\nmetrics:\n\n  - name: number_of_people\n    label: \"Number of people\"\n    description: Total count of people\n    calculation_method: count\n    expression: \"*\"\n    timestamp: created_at\n    time_grains: [day, week, month]\n    dimensions:\n      - favorite_color\n      - loves_dbt\n    meta:\n        my_meta: 'testing'\n\n  - name: collective_tenure\n    label: \"Collective tenure\"\n    description: Total number of years of team experience\n    calculation_method: sum\n    expression: tenure\n    timestamp: created_at\n    time_grains: [day]\n    filters:\n      - field: loves_dbt\n        operator: 'is'\n        value: 'true'\n\n\"\"\"\n\ninvalid_metrics_missing_expression_yml = \"\"\"\nversion: 2\nmetrics:\n  - name: number_of_people\n    label: \"Number of people\"\n    model: \"ref(people)\"\n    description: Total count of people\n    calculation_method: count\n    timestamp: created_at\n    time_grains: [day, week, month]\n    dimensions:\n      - favorite_color\n      - loves_dbt\n    meta:\n        my_meta: 'testing'\n\"\"\"\n\nnames_with_spaces_metrics_yml = \"\"\"\nversion: 2\n\nmetrics:\n\n  - name: number of people\n    label: \"Number of people\"\n    description: Total count of people\n    type: simple\n    type_params:\n      measure: people\n    meta:\n        my_meta: 'testing'\n\n\"\"\"\n\nnames_with_special_chars_metrics_yml = \"\"\"\nversion: 2\n\nmetrics:\n\n  - name: number_of_people!\n    label: \"Number of people\"\n    description: Total count of people\n    type: simple\n    type_params:\n      measure: people\n    meta:\n        my_meta: 'testing'\n\n\"\"\"\n\n\nnames_with_leading_numeric_metrics_yml = \"\"\"\nversion: 2\n\nmetrics:\n\n  - name: 1_number_of_people\n    label: \"Number of people\"\n    description: Total count of people\n    type: simple\n    type_params:\n      measure: people\n    meta:\n        my_meta: 'testing'\n\n\"\"\"\n\nlong_name_metrics_yml = \"\"\"\nversion: 2\n\nmetrics:\n\n  - name: this_name_is_going_to_contain_more_than_250_characters_but_be_otherwise_acceptable_and_then_will_throw_an_error_which_I_expect_to_happen_and_repeat_this_name_is_going_to_contain_more_than_250_characters_but_be_otherwise_acceptable_and_then_will_throw_an_error_which_I_expect_to_happen\n    label: \"Number of people\"\n    description: Total count of people\n    type: simple\n    type_params:\n      measure: people\n    meta:\n        my_meta: 'testing'\n\n\"\"\"\n\ndownstream_model_sql = \"\"\"\n-- this model will depend on these three metrics\n{% set some_metrics = [\n    metric('count_orders'),\n    metric('sum_order_revenue'),\n    metric('average_order_value')\n] %}\n\n/*\n{% if not execute %}\n\n    -- the only properties available to us at 'parse' time are:\n    --      'metric_name'\n    --      'package_name' (None if same package)\n\n    {% set metric_names = [] %}\n    {% for m in some_metrics %}\n        {% do metric_names.append(m.metric_name) %}\n    {% endfor %}\n\n    -- this config does nothing, but it lets us check these values below\n    {{ config(metric_names = metric_names) }}\n\n{% else %}\n\n    -- these are the properties available to us at 'execution' time\n\n    {% for m in some_metrics %}\n        name: {{ m.name }}\n        label: {{ m.label }}\n        type: {{ m.type }}\n        type_params: {{ m.type_params }}\n        filter: {{ m.filter }}\n    {% endfor %}\n\n{% endif %}\n\nselect 1 as id\n\"\"\"\n\ninvalid_derived_metric_contains_model_yml = \"\"\"\nversion: 2\nmetrics:\n    - name: count_orders\n      label: Count orders\n      model: ref('mock_purchase_data')\n\n      calculation_method: count\n      expression: \"*\"\n      timestamp: purchased_at\n      time_grains: [day, week, month, quarter, year]\n\n      dimensions:\n        - payment_type\n\n    - name: sum_order_revenue\n      label: Total order revenue\n      model: ref('mock_purchase_data')\n\n      calculation_method: sum\n      expression: \"payment_total\"\n      timestamp: purchased_at\n      time_grains: [day, week, month, quarter, year]\n\n      dimensions:\n        - payment_type\n\n    - name: average_order_value\n      label: Average Order Value\n\n      calculation_method: derived\n      expression:  \"{{metric('sum_order_revenue')}} / {{metric('count_orders')}} \"\n      model: ref('mock_purchase_data')\n      timestamp: purchased_at\n      time_grains: [day, week, month, quarter, year]\n\n      dimensions:\n        - payment_type\n\"\"\"\n\npurchasing_model_sql = \"\"\"\nselect purchased_at, payment_type, payment_total from {{ ref('mock_purchase_data') }}\n\"\"\"\n\nsemantic_model_purchasing_yml = \"\"\"\nversion: 2\n\nsemantic_models:\n  - name: semantic_purchasing\n    model: ref('purchasing')\n    measures:\n      - name: num_orders\n        agg: COUNT\n        expr: purchased_at\n      - name: order_revenue\n        agg: SUM\n        expr: payment_total\n    dimensions:\n      - name: purchased_at\n        type: TIME\n        type_params:\n          time_granularity: day\n    entities:\n      - name: purchase\n        type: primary\n        expr: '1'\n    defaults:\n      agg_time_dimension: purchased_at\n\n\"\"\"\n\nderived_metric_yml = \"\"\"\nversion: 2\nmetrics:\n    - name: count_orders\n      label: Count orders\n      type: simple\n      type_params:\n        measure: num_orders\n\n    - name: sum_order_revenue\n      label: Total order revenue\n      type: simple\n      type_params:\n        measure: order_revenue\n\n    - name: average_order_value\n      label: Average Order Value\n      type: ratio\n      type_params:\n        numerator:\n          name: sum_order_revenue\n        denominator:\n          name: count_orders\n\n    - name: sum_order_revenue_plus_one_custom_offset_window\n      label: \"Total order revenue, plus 1 with custom offset window\"\n      description: \"The total order revenue plus 1 offset by 1 martian day\"\n      type: derived\n      type_params:\n        metrics:\n          - name: sum_order_revenue\n            offset_window: 1 martian_day\n        expr: \"sum_order_revenue + 1\"\n\"\"\"\n\ndisabled_metric_level_schema_yml = \"\"\"\nversion: 2\n\nmetrics:\n\n  - name: number_of_people\n    label: \"Number of people\"\n    description: Total count of people\n    type: simple\n    type_params:\n      measure: people\n    config:\n      enabled: False\n    meta:\n        my_meta: 'testing'\n\n  - name: collective_tenure\n    label: \"Collective tenure\"\n    description: Total number of years of team experience\n    type: simple\n    type_params:\n      measure:\n        name: years_tenure\n        filter: \"{{ Dimension('id__loves_dbt') }} is true\"\n\n\"\"\"\n\nmeta_metric_level_schema_yml = \"\"\"\nversion: 2\n\nmetrics:\n\n  - name: number_of_people\n    label: \"Number of people\"\n    description: Total count of people\n    type: simple\n    type_params:\n      measure: people\n    config:\n      meta:\n         my_meta_config: 'config\n    meta:\n        my_meta_direct: 'direct'\n\n  - name: collective_tenure\n    label: \"Collective tenure\"\n    description: Total number of years of team experience\n    type: simple\n    type_params:\n      measure:\n        name: years_tenure\n        filter: \"{{ Dimension('id__loves_dbt') }} is true\"\n\n\"\"\"\n\nenabled_metric_level_schema_yml = \"\"\"\nversion: 2\n\nmetrics:\n\n  - name: number_of_people\n    label: \"Number of people\"\n    description: Total count of people\n    type: simple\n    type_params:\n      measure: people\n    config:\n      enabled: True\n    meta:\n        my_meta: 'testing'\n\n  - name: collective_tenure\n    label: \"Collective tenure\"\n    description: Total number of years of team experience\n    type: simple\n    type_params:\n      measure:\n        name: years_tenure\n        filter: \"{{ Dimension('id__loves_dbt') }} is true\"\n\n\"\"\"\n\nmodels_people_metrics_sql = \"\"\"\n-- this model will depend on these two metrics\n{% set some_metrics = [\n    metric('number_of_people'),\n    metric('collective_tenure')\n] %}\n\n/*\n{% if not execute %}\n\n    -- the only properties available to us at 'parse' time are:\n    --      'metric_name'\n    --      'package_name' (None if same package)\n\n    {% set metric_names = [] %}\n    {% for m in some_metrics %}\n        {% do metric_names.append(m.metric_name) %}\n    {% endfor %}\n\n    -- this config does nothing, but it lets us check these values below\n    {{ config(metric_names = metric_names) }}\n\n{% else %}\n\n    -- these are the properties available to us at 'execution' time\n\n    {% for m in some_metrics %}\n        name: {{ m.name }}\n        label: {{ m.label }}\n        type: {{ m.type }}\n        type_params: {{ m.type_params }}\n        filter: {{ m.filter }}\n        window: {{ m.window }}\n    {% endfor %}\n\n{% endif %}\n\nselect 1 as id\n\"\"\"\n\nmetrics_1_yml = \"\"\"\nversion: 2\n\nmetrics:\n  - name: some_metric\n    label: Some Metric\n    type: simple\n    type_params:\n      measure: some_measure\n\"\"\"\n\nmetrics_2_yml = \"\"\"\nversion: 2\n\nmetrics:\n  - name: some_metric\n    label: Some Metric\n    type: simple\n    type_params:\n      measure: some_measure\n\"\"\"\n\nmodel_a_sql = \"\"\"\nselect 1 as fun\n\"\"\"\n\nmodel_b_sql = \"\"\"\n-- {{ metric('some_metric') }}\n\n{% if execute %}\n  {% set model_ref_node = graph.nodes.values() | selectattr('name', 'equalto', 'model_a') | first %}\n  {% set relation = api.Relation.create(\n      database = model_ref_node.database,\n      schema = model_ref_node.schema,\n      identifier = model_ref_node.alias\n  )\n  %}\n{% else %}\n  {% set relation = \"\" %}\n{% endif %}\n\n-- this one is a real ref\nselect * from {{ ref('model_a') }}\nunion all\n-- this one is synthesized via 'graph' var\nselect * from {{ relation }}\n\"\"\"\n\ninvalid_config_metric_yml = \"\"\"\nversion: 2\n\nmetrics:\n  - name: number_of_people\n    label: \"Number of people\"\n    config:\n        enabled: True and False\n    description: Total count of people\n    type: simple\n    type_params:\n      measure: people\n    meta:\n        my_meta: 'testing'\n\"\"\"\n\ninvalid_metric_without_timestamp_with_time_grains_yml = \"\"\"\nversion: 2\n\nmetrics:\n  - name: number_of_people\n    label: \"Number of people\"\n    description: Total count of people\n    model: \"ref('people')\"\n    time_grains: [day, week, month]\n    calculation_method: count\n    expression: \"*\"\n    dimensions:\n      - favorite_color\n      - loves_dbt\n    meta:\n        my_meta: 'testing'\n\"\"\"\n\ninvalid_metric_without_timestamp_with_window_yml = \"\"\"\nversion: 2\n\nmetrics:\n  - name: number_of_people\n    label: \"Number of people\"\n    description: Total count of people\n    model: \"ref('people')\"\n    window:\n      count: 14\n      period: day\n    calculation_method: count\n    expression: \"*\"\n    dimensions:\n      - favorite_color\n      - loves_dbt\n    meta:\n        my_meta: 'testing'\n\"\"\"\n\nconversion_semantic_model_purchasing_yml = \"\"\"\nversion: 2\n\nsemantic_models:\n  - name: semantic_purchasing\n    model: ref('purchasing')\n    measures:\n      - name: num_orders\n        agg: COUNT\n        expr: purchased_at\n      - name: num_visits\n        agg: SUM\n        expr: 1\n    dimensions:\n      - name: purchased_at\n        type: TIME\n        type_params:\n          time_granularity: day\n    entities:\n      - name: purchase\n        type: primary\n        expr: '1'\n    defaults:\n      agg_time_dimension: purchased_at\n\n\"\"\"\n\ncumulative_metric_yml = \"\"\"\nversion: 2\nmetrics:\n    - name: weekly_visits\n      label: Rolling sum of visits over the last 7 days\n      type: cumulative\n      type_params:\n        measure: num_visits\n        cumulative_type_params:\n          window: 7 days\n          period_agg: average\n    - name: cumulative_orders\n      label: Rolling total of orders (all time)\n      type: cumulative\n      type_params:\n        measure: num_orders\n        cumulative_type_params:\n          period_agg: last\n    - name: orders_ytd\n      label: Total orders since the start of the year\n      type: cumulative\n      type_params:\n        measure: num_orders\n        cumulative_type_params:\n          grain_to_date: year\n          period_agg: first\n    - name: monthly_orders\n      label: Orders in the past month\n      type: cumulative\n      type_params:\n        measure: num_orders\n        window: 1 month\n        cumulative_type_params:\n          period_agg: average\n    - name: yearly_orders\n      label: Orders in the past year\n      type: cumulative\n      type_params:\n        measure: num_orders\n        window: 1 year\n    - name: visits_mtd\n      label: Visits since start of month\n      type: cumulative\n      type_params:\n        measure: num_visits\n        grain_to_date: month\n    - name: cumulative_visits\n      label: Rolling total of visits (all time)\n      type: cumulative\n      type_params:\n        measure: num_visits\n    # TODO: Re-enable this when custom grain is supported for this type\n    # - name: visits_martian_day\n    #   label: Visits since start of martian_day\n    #   type: cumulative\n    #   type_params:\n    #     measure: num_visits\n    #     cumulative_type_params:\n    #       grain_to_date: martian_day\n    # - name: visits_martian_day_window\n    #   label: Visits since start of martian_day window\n    #   type: cumulative\n    #   type_params:\n    #     measure: num_visits\n    #     cumulative_type_params:\n    #       window: 1 martian_day\n\"\"\"\n\nconversion_metric_yml = \"\"\"\nversion: 2\nmetrics:\n    - name: converted_orders_over_visits\n      label: Number of orders converted from visits\n      type: conversion\n      type_params:\n        conversion_type_params:\n          base_measure: num_visits\n          conversion_measure: num_orders\n          entity: purchase\n    - name: converted_orders_over_visits_with_window\n      label: Number of orders converted from visits with window\n      type: conversion\n      type_params:\n        conversion_type_params:\n          base_measure: num_visits\n          conversion_measure: num_orders\n          entity: purchase\n          window: 4 day\n    # TODO: Re-enable this when custom grain is supported for this type\n    # - name: converted_orders_over_visits_with_custom_window\n    #   label: Number of orders converted from visits with custom window\n    #   type: conversion\n    #   type_params:\n    #     conversion_type_params:\n    #       base_measure: num_visits\n    #       conversion_measure: num_orders\n    #       entity: purchase\n    #       window: 4 martian_day\n\"\"\"\n\nfiltered_metrics_yml = \"\"\"\nversion: 2\n\nmetrics:\n\n  - name: collective_tenure_measure_filter_str\n    label: \"Collective tenure1\"\n    description: Total number of years of team experience\n    type: simple\n    type_params:\n      measure:\n        name: \"years_tenure\"\n        filter: \"{{ Dimension('id__loves_dbt') }} is true\"\n\n  - name: collective_tenure_measure_filter_list\n    label: \"Collective tenure2\"\n    description: Total number of years of team experience\n    type: simple\n    type_params:\n      measure:\n        name: \"years_tenure\"\n        filter:\n          - \"{{ Dimension('id__loves_dbt') }} is true\"\n\n  - name: collective_tenure_metric_filter_str\n    label: Collective tenure3\n    description: Total number of years of team experience\n    type: simple\n    type_params:\n      measure:\n        name: \"years_tenure\"\n    filter: \"{{ Dimension('id__loves_dbt') }} is true\"\n\n  - name: collective_tenure_metric_filter_list\n    label: Collective tenure4\n    description: Total number of years of team experience\n    type: simple\n    type_params:\n      measure:\n        name: \"years_tenure\"\n    filter:\n      - \"{{ Dimension('id__loves_dbt') }} is true\"\n\n  - name: average_tenure_filter_str\n    label: Average tenure of people who love dbt1\n    description: Average tenure of people who love dbt\n    type: derived\n    type_params:\n      expr: \"average_tenure\"\n      metrics:\n        - name: average_tenure\n          filter: \"{{ Dimension('id__loves_dbt') }} is true\"\n\n  - name: average_tenure_filter_list\n    label: Average tenure of people who love dbt2\n    description: Average tenure of people who love dbt\n    type: derived\n    type_params:\n      expr: \"average_tenure\"\n      metrics:\n        - name: average_tenure\n          filter:\n            - \"{{ Dimension('id__loves_dbt') }} is true\"\n\"\"\"\n\nduplicate_measure_metric_yml = \"\"\"\nmetrics:\n  # Simple metrics\n  - name: people_with_tenure\n    description: \"Count of people with tenure\"\n    type: simple\n    label: People with tenure\n    type_params:\n      measure: people\n  - name: ratio_tenure_to_people\n    description: People to years of tenure\n    label: New customers to all customers\n    type: ratio\n    type_params:\n      numerator: people_with_tenure\n      denominator: number_of_people\n\"\"\"\n"
  },
  {
    "path": "tests/functional/metrics/test_metric_configs.py",
    "content": "import pytest\n\nfrom dbt.artifacts.resources import MetricConfig\nfrom dbt.exceptions import CompilationError, ParsingError\nfrom dbt.tests.util import get_manifest, run_dbt, update_config_file\nfrom dbt_common.dataclass_schema import ValidationError\nfrom tests.functional.metrics.fixtures import (\n    disabled_metric_level_schema_yml,\n    enabled_metric_level_schema_yml,\n    invalid_config_metric_yml,\n    metricflow_time_spine_sql,\n    models_people_metrics_meta_top_yml,\n    models_people_metrics_sql,\n    models_people_metrics_yml,\n    models_people_sql,\n    semantic_model_people_yml,\n)\n\n\nclass MetricConfigTests:\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self):\n        pytest.expected_config = MetricConfig(\n            enabled=True,\n        )\n\n\n# Test enabled config in dbt_project.yml\nclass TestMetricEnabledConfigProjectLevel(MetricConfigTests):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"people.sql\": models_people_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"semantic_model_people.yml\": semantic_model_people_yml,\n            \"schema.yml\": models_people_metrics_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"metrics\": {\n                \"test\": {\n                    \"average_tenure_minus_people\": {\n                        \"enabled\": False,\n                    },\n                }\n            }\n        }\n\n    def test_enabled_metric_config_dbt_project(self, project):\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n        assert \"metric.test.average_tenure_minus_people\" not in manifest.metrics\n\n        new_enabled_config = {\n            \"metrics\": {\n                \"test\": {\n                    \"average_tenure_minus_people\": {\n                        \"enabled\": True,\n                    },\n                }\n            }\n        }\n        update_config_file(new_enabled_config, project.project_root, \"dbt_project.yml\")\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n        assert \"metric.test.average_tenure_minus_people\" in manifest.metrics\n        assert \"metric.test.collective_tenure\" in manifest.metrics\n\n\n# Test enabled config at metrics level in yml file\nclass TestConfigYamlMetricLevel(MetricConfigTests):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"people.sql\": models_people_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"semantic_model_people.yml\": semantic_model_people_yml,\n            \"schema.yml\": disabled_metric_level_schema_yml,\n        }\n\n    def test_metric_config_yaml_metric_level(self, project):\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n        assert \"metric.test.number_of_people\" not in manifest.metrics\n        assert \"metric.test.collective_tenure\" in manifest.metrics\n\n\n# Test inheritence - set configs at project and metric level - expect metric level to win\nclass TestMetricConfigsInheritence(MetricConfigTests):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"people.sql\": models_people_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"semantic_model_people.yml\": semantic_model_people_yml,\n            \"schema.yml\": enabled_metric_level_schema_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\"metrics\": {\"enabled\": False}}\n\n    def test_metrics_all_configs(self, project):\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n        # This should be overridden\n        assert \"metric.test.number_of_people\" in manifest.metrics\n        # This should stay disabled\n        assert \"metric.test.collective_tenure\" not in manifest.metrics\n\n        config_test_table = manifest.metrics.get(\"metric.test.number_of_people\").config\n\n        assert isinstance(config_test_table, MetricConfig)\n        assert config_test_table == pytest.expected_config\n\n\n# Test CompilationError if a model references a disabled metric\nclass TestDisabledMetricRef(MetricConfigTests):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"people.sql\": models_people_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"semantic_model_people.yml\": semantic_model_people_yml,\n            \"people_metrics.sql\": models_people_metrics_sql,\n            \"schema.yml\": models_people_metrics_yml,\n        }\n\n    def test_disabled_metric_ref_model(self, project):\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n        assert \"metric.test.number_of_people\" in manifest.metrics\n        assert \"metric.test.collective_tenure\" in manifest.metrics\n        assert \"model.test.people_metrics\" in manifest.nodes\n        assert \"metric.test.average_tenure\" in manifest.metrics\n        assert \"metric.test.average_tenure_minus_people\" in manifest.metrics\n\n        new_enabled_config = {\n            \"metrics\": {\n                \"test\": {\n                    \"number_of_people\": {\n                        \"enabled\": False,\n                    },\n                    \"average_tenure_minus_people\": {\n                        \"enabled\": False,\n                    },\n                    \"average_tenure\": {\n                        \"enabled\": False,\n                    },\n                }\n            }\n        }\n\n        update_config_file(new_enabled_config, project.project_root, \"dbt_project.yml\")\n        with pytest.raises(CompilationError):\n            run_dbt([\"parse\"])\n\n\n# Test invalid metric configs\nclass TestInvalidMetric(MetricConfigTests):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"people.sql\": models_people_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"semantic_model_people.yml\": semantic_model_people_yml,\n            \"schema.yml\": invalid_config_metric_yml,\n        }\n\n    def test_invalid_config_metric(self, project):\n        with pytest.raises(ValidationError) as excinfo:\n            run_dbt([\"parse\"])\n        expected_msg = \"'True and False' is not of type 'boolean'\"\n        assert expected_msg in str(excinfo.value)\n\n\nclass TestDisabledMetric(MetricConfigTests):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"people.sql\": models_people_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"semantic_model_people.yml\": semantic_model_people_yml,\n            \"schema.yml\": models_people_metrics_yml,\n        }\n\n    def test_disabling_upstream_metric_errors(self, project):\n        run_dbt([\"parse\"])  # shouldn't error out yet\n\n        new_enabled_config = {\n            \"metrics\": {\n                \"test\": {\n                    \"number_of_people\": {\n                        \"enabled\": False,\n                    },\n                }\n            }\n        }\n\n        update_config_file(new_enabled_config, project.project_root, \"dbt_project.yml\")\n        with pytest.raises(ParsingError) as excinfo:\n            run_dbt([\"parse\"])\n            expected_msg = (\n                \"The metric `number_of_people` is disabled and thus cannot be referenced.\"\n            )\n            assert expected_msg in str(excinfo.value)\n\n\n# Test meta config in dbt_project.yml\nclass TestMetricMetaConfigProjectLevel(MetricConfigTests):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"people.sql\": models_people_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"semantic_model_people.yml\": semantic_model_people_yml,\n            \"schema.yml\": models_people_metrics_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"metrics\": {\n                \"test\": {\n                    \"average_tenure_minus_people\": {\n                        \"+meta\": {\"project_field\": \"project_value\"},\n                    },\n                }\n            }\n        }\n\n    def test_meta_metric_config_dbt_project(self, project):\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n        assert \"metric.test.average_tenure_minus_people\" in manifest.metrics\n        # for backwards compatibility the config level meta gets copied to the top level meta\n        assert manifest.metrics.get(\"metric.test.average_tenure_minus_people\").config.meta == {\n            \"project_field\": \"project_value\"\n        }\n        assert manifest.metrics.get(\"metric.test.average_tenure_minus_people\").meta == {\n            \"project_field\": \"project_value\"\n        }\n\n\n# Test setting config at config level\nclass TestMetricMetaConfigLevel(MetricConfigTests):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"people.sql\": models_people_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"semantic_model_people.yml\": semantic_model_people_yml,\n            \"schema.yml\": models_people_metrics_yml,\n        }\n\n    def test_meta_metric_config_yaml(self, project):\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n        assert \"metric.test.number_of_people\" in manifest.metrics\n        assert manifest.metrics.get(\"metric.test.number_of_people\").config.meta == {\n            \"my_meta_config\": \"config\"\n        }\n        assert manifest.metrics.get(\"metric.test.number_of_people\").meta == {\n            \"my_meta_config\": \"config\"\n        }\n\n\n# Test setting config at metric level- expect to exist in config after parsing\nclass TestMetricMetaTopLevel(MetricConfigTests):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"people.sql\": models_people_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"semantic_model_people.yml\": semantic_model_people_yml,\n            \"schema.yml\": models_people_metrics_meta_top_yml,\n        }\n\n    def test_meta_metric_config_yaml(self, project):\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n        assert \"metric.test.number_of_people\" in manifest.metrics\n        # for backwards compatibility the config level meta gets copied to the top level meta\n        assert manifest.metrics.get(\"metric.test.number_of_people\").config.meta != {\n            \"my_meta_top\": \"top\"\n        }\n        assert manifest.metrics.get(\"metric.test.number_of_people\").meta == {\"my_meta_top\": \"top\"}\n"
  },
  {
    "path": "tests/functional/metrics/test_metric_deferral.py",
    "content": "import os\nfrom pathlib import Path\n\nimport pytest\n\nfrom dbt.tests.util import copy_file, run_dbt, write_file\nfrom tests.functional.metrics.fixtures import (\n    metrics_1_yml,\n    metrics_2_yml,\n    model_a_sql,\n    model_b_sql,\n)\n\n\nclass TestMetricDeferral:\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setup(self, project):\n        # Create \"prod\" schema\n        prod_schema_name = project.test_schema + \"_prod\"\n        project.create_test_schema(schema_name=prod_schema_name)\n        # Create \"state\" directory\n        path = Path(project.project_root) / \"state\"\n        Path.mkdir(path)\n\n    @pytest.fixture(scope=\"class\")\n    def dbt_profile_data(self, unique_schema):\n        return {\n            \"test\": {\n                \"outputs\": {\n                    \"default\": {\n                        \"type\": \"postgres\",\n                        \"threads\": 4,\n                        \"host\": \"localhost\",\n                        \"port\": int(os.getenv(\"POSTGRES_TEST_PORT\", 5432)),\n                        \"user\": os.getenv(\"POSTGRES_TEST_USER\", \"root\"),\n                        \"pass\": os.getenv(\"POSTGRES_TEST_PASS\", \"password\"),\n                        \"dbname\": os.getenv(\"POSTGRES_TEST_DATABASE\", \"dbt\"),\n                        \"schema\": unique_schema,\n                    },\n                    \"prod\": {\n                        \"type\": \"postgres\",\n                        \"threads\": 4,\n                        \"host\": \"localhost\",\n                        \"port\": int(os.getenv(\"POSTGRES_TEST_PORT\", 5432)),\n                        \"user\": os.getenv(\"POSTGRES_TEST_USER\", \"root\"),\n                        \"pass\": os.getenv(\"POSTGRES_TEST_PASS\", \"password\"),\n                        \"dbname\": os.getenv(\"POSTGRES_TEST_DATABASE\", \"dbt\"),\n                        \"schema\": unique_schema + \"_prod\",\n                    },\n                },\n                \"target\": \"default\",\n            },\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_a.sql\": model_a_sql,\n            \"model_b.sql\": model_b_sql,\n            \"metrics.yml\": metrics_1_yml,\n        }\n\n    @pytest.mark.skip(\"TODO\")\n    def test_metric_deferral(self, project):\n        results = run_dbt([\"run\", \"--target\", \"prod\"])\n        assert len(results) == 2\n\n        # copy manifest.json to \"state\" directory\n        target_path = os.path.join(project.project_root, \"target\")\n        copy_file(target_path, \"manifest.json\", project.project_root, [\"state\", \"manifest.json\"])\n\n        # Change metrics file\n        write_file(metrics_2_yml, project.project_root, \"models\", \"metrics.yml\")\n\n        # Confirm that some_metric + model_b are both selected, and model_a is not selected\n        results = run_dbt([\"ls\", \"-s\", \"state:modified+\", \"--state\", \"state/\", \"--target\", \"prod\"])\n        assert results == [\"metric:test.some_metric\", \"test.model_b\"]\n\n        # Run in default schema\n        results = run_dbt(\n            [\"run\", \"-s\", \"state:modified+\", \"--state\", \"state/\", \"--defer\", \"--target\", \"default\"]\n        )\n        assert len(results) == 1\n"
  },
  {
    "path": "tests/functional/metrics/test_metric_helper_functions.py",
    "content": "import pytest\n\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.contracts.graph.metrics import ResolvedMetricReference\nfrom dbt.tests.util import run_dbt\nfrom tests.functional.metrics.fixtures import (\n    basic_metrics_yml,\n    metricflow_time_spine_sql,\n    models_people_sql,\n    semantic_model_people_yml,\n)\n\n\nclass TestMetricHelperFunctions:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"metrics.yml\": basic_metrics_yml,\n            \"semantic_people.yml\": semantic_model_people_yml,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"people.sql\": models_people_sql,\n        }\n\n    def test_derived_metric(\n        self,\n        project,\n    ):\n\n        # initial parse\n        manifest = run_dbt([\"parse\"])\n        assert isinstance(manifest, Manifest)\n\n        parsed_metric = manifest.metrics[\"metric.test.average_tenure_plus_one\"]\n        testing_metric = ResolvedMetricReference(parsed_metric, manifest)\n\n        full_metric_dependency = set(testing_metric.full_metric_dependency())\n        expected_full_metric_dependency = set(\n            [\"average_tenure_plus_one\", \"average_tenure\", \"collective_tenure\", \"number_of_people\"]\n        )\n        assert full_metric_dependency == expected_full_metric_dependency\n\n        base_metric_dependency = set(testing_metric.base_metric_dependency())\n        expected_base_metric_dependency = set([\"collective_tenure\", \"number_of_people\"])\n        assert base_metric_dependency == expected_base_metric_dependency\n\n        derived_metric_dependency = set(testing_metric.derived_metric_dependency())\n        expected_derived_metric_dependency = set([\"average_tenure_plus_one\", \"average_tenure\"])\n        assert derived_metric_dependency == expected_derived_metric_dependency\n\n        derived_metric_dependency_depth = list(testing_metric.derived_metric_dependency_depth())\n        expected_derived_metric_dependency_depth = list(\n            [{\"average_tenure_plus_one\": 1}, {\"average_tenure\": 2}]\n        )\n        assert derived_metric_dependency_depth == expected_derived_metric_dependency_depth\n"
  },
  {
    "path": "tests/functional/metrics/test_metrics.py",
    "content": "import pytest\n\nfrom dbt.artifacts.resources.v1.metric import CumulativeTypeParams, MetricTimeWindow\nfrom dbt.cli.main import dbtRunner\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.exceptions import ParsingError\nfrom dbt.tests.util import get_manifest, run_dbt\nfrom dbt_semantic_interfaces.type_enums.period_agg import PeriodAggregation\nfrom dbt_semantic_interfaces.type_enums.time_granularity import TimeGranularity\nfrom tests.functional.metrics.fixtures import (\n    basic_metrics_yml,\n    conversion_metric_yml,\n    conversion_semantic_model_purchasing_yml,\n    cumulative_metric_yml,\n    derived_metric_yml,\n    downstream_model_sql,\n    duplicate_measure_metric_yml,\n    filtered_metrics_yml,\n    invalid_derived_metric_contains_model_yml,\n    invalid_metric_without_timestamp_with_time_grains_yml,\n    invalid_metric_without_timestamp_with_window_yml,\n    invalid_metrics_missing_expression_yml,\n    invalid_metrics_missing_model_yml,\n    invalid_models_people_metrics_yml,\n    long_name_metrics_yml,\n    metricflow_time_spine_sql,\n    mock_purchase_data_csv,\n    models_people_metrics_yml,\n    models_people_sql,\n    names_with_leading_numeric_metrics_yml,\n    names_with_spaces_metrics_yml,\n    names_with_special_chars_metrics_yml,\n    purchasing_model_sql,\n    semantic_model_people_yml,\n    semantic_model_purchasing_yml,\n)\nfrom tests.functional.time_spines.fixtures import time_spine_yml\n\n\nclass TestSimpleMetrics:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"people_metrics.yml\": models_people_metrics_yml,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"semantic_model_people.yml\": semantic_model_people_yml,\n            \"people.sql\": models_people_sql,\n        }\n\n    def test_simple_metric(\n        self,\n        project,\n    ):\n        runner = dbtRunner()\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        assert isinstance(result.result, Manifest)\n        manifest = get_manifest(project.project_root)\n        metric_ids = list(manifest.metrics.keys())\n        expected_metric_ids = [\n            \"metric.test.number_of_people\",\n            \"metric.test.collective_tenure\",\n            \"metric.test.collective_window\",\n            \"metric.test.average_tenure\",\n            \"metric.test.average_tenure_minus_people\",\n        ]\n        assert metric_ids == expected_metric_ids\n\n        assert (\n            len(manifest.metrics[\"metric.test.number_of_people\"].type_params.input_measures) == 1\n        )\n        assert (\n            len(manifest.metrics[\"metric.test.collective_tenure\"].type_params.input_measures) == 1\n        )\n        assert (\n            len(manifest.metrics[\"metric.test.collective_window\"].type_params.input_measures) == 1\n        )\n        assert len(manifest.metrics[\"metric.test.average_tenure\"].type_params.input_measures) == 2\n        assert (\n            len(\n                manifest.metrics[\n                    \"metric.test.average_tenure_minus_people\"\n                ].type_params.input_measures\n            )\n            == 2\n        )\n        assert (\n            manifest.metrics[\"metric.test.number_of_people\"].time_granularity\n            == TimeGranularity.MONTH.value\n        )\n        assert manifest.metrics[\"metric.test.collective_tenure\"].time_granularity is None\n\n\nclass TestInvalidRefMetrics:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"people_metrics.yml\": invalid_models_people_metrics_yml,\n            \"people.sql\": models_people_sql,\n        }\n\n    # tests that we get a ParsingError with an invalid model ref, where\n    # the model name does not have quotes\n    def test_simple_metric(\n        self,\n        project,\n    ):\n        # initial run\n        with pytest.raises(ParsingError):\n            run_dbt([\"run\"])\n\n\nclass TestInvalidMetricMissingModel:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"people_metrics.yml\": invalid_metrics_missing_model_yml,\n            \"people.sql\": models_people_sql,\n        }\n\n    # tests that we get a ParsingError with an invalid model ref, where\n    # the model name does not have quotes\n    def test_simple_metric(\n        self,\n        project,\n    ):\n        # initial run\n        with pytest.raises(ParsingError):\n            run_dbt([\"run\"])\n\n\nclass TestInvalidMetricMissingExpression:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"people_metrics.yml\": invalid_metrics_missing_expression_yml,\n            \"people.sql\": models_people_sql,\n        }\n\n    # tests that we get a ParsingError with a missing expression\n    def test_simple_metric(\n        self,\n        project,\n    ):\n        # initial run\n        with pytest.raises(ParsingError):\n            run_dbt([\"run\"])\n\n\nclass TestNamesWithSpaces:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"people_metrics.yml\": names_with_spaces_metrics_yml,\n            \"people.sql\": models_people_sql,\n        }\n\n    def test_names_with_spaces(self, project):\n        with pytest.raises(ParsingError) as exc:\n            run_dbt([\"run\"])\n        assert \"cannot contain spaces\" in str(exc.value)\n\n\nclass TestNamesWithSpecialChar:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"people_metrics.yml\": names_with_special_chars_metrics_yml,\n            \"people.sql\": models_people_sql,\n        }\n\n    def test_names_with_special_char(self, project):\n        with pytest.raises(ParsingError) as exc:\n            run_dbt([\"run\"])\n        assert \"must contain only letters, numbers and underscores\" in str(exc.value)\n\n\nclass TestNamesWithLeandingNumber:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"people_metrics.yml\": names_with_leading_numeric_metrics_yml,\n            \"people.sql\": models_people_sql,\n        }\n\n    def test_names_with_leading_number(self, project):\n        with pytest.raises(ParsingError) as exc:\n            run_dbt([\"run\"])\n        assert \"must begin with a letter\" in str(exc.value)\n\n\nclass TestLongName:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"people_metrics.yml\": long_name_metrics_yml,\n            \"people.sql\": models_people_sql,\n        }\n\n    def test_long_name(self, project):\n        with pytest.raises(ParsingError) as exc:\n            run_dbt([\"run\"])\n        assert \"cannot contain more than 250 characters\" in str(exc.value)\n\n\nclass TestInvalidDerivedMetrics:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"derived_metric.yml\": invalid_derived_metric_contains_model_yml,\n            \"downstream_model.sql\": downstream_model_sql,\n        }\n\n    def test_invalid_derived_metrics(self, project):\n        with pytest.raises(ParsingError):\n            run_dbt([\"run\"])\n\n\nclass TestMetricDependsOn:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"people.sql\": models_people_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"semantic_models.yml\": semantic_model_people_yml,\n            \"people_metrics.yml\": models_people_metrics_yml,\n        }\n\n    def test_metric_depends_on(self, project):\n        manifest = run_dbt([\"parse\"])\n        assert isinstance(manifest, Manifest)\n\n        expected_depends_on_for_number_of_people = [\"semantic_model.test.semantic_people\"]\n        expected_depends_on_for_average_tenure = [\n            \"metric.test.collective_tenure\",\n            \"metric.test.number_of_people\",\n        ]\n\n        number_of_people_metric = manifest.metrics[\"metric.test.number_of_people\"]\n        assert number_of_people_metric.depends_on.nodes == expected_depends_on_for_number_of_people\n\n        average_tenure_metric = manifest.metrics[\"metric.test.average_tenure\"]\n        assert average_tenure_metric.depends_on.nodes == expected_depends_on_for_average_tenure\n\n\nclass TestDerivedMetric:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"downstream_model.sql\": downstream_model_sql,\n            \"purchasing.sql\": purchasing_model_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"semantic_models.yml\": semantic_model_purchasing_yml,\n            \"derived_metric.yml\": derived_metric_yml,\n            \"time_spine.yml\": time_spine_yml,\n        }\n\n    # not strictly necessary to use \"real\" mock data for this test\n    # we just want to make sure that the 'metric' calls match our expectations\n    # but this sort of thing is possible, to have actual data flow through and validate results\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\n            \"mock_purchase_data.csv\": mock_purchase_data_csv,\n        }\n\n    def test_derived_metric(\n        self,\n        project,\n    ):\n        # initial parse\n        results = run_dbt([\"parse\"])\n\n        # make sure all the metrics are in the manifest\n        manifest = get_manifest(project.project_root)\n        metric_ids = list(manifest.metrics.keys())\n        expected_metric_ids = [\n            \"metric.test.count_orders\",\n            \"metric.test.sum_order_revenue\",\n            \"metric.test.average_order_value\",\n            \"metric.test.sum_order_revenue_plus_one_custom_offset_window\",\n        ]\n        assert metric_ids == expected_metric_ids\n\n        # make sure the downstream_model depends on these metrics\n        metric_names = [\"average_order_value\", \"count_orders\", \"sum_order_revenue\"]\n        downstream_model = manifest.nodes[\"model.test.downstream_model\"]\n        assert sorted(downstream_model.metrics) == [[metric_name] for metric_name in metric_names]\n        assert sorted(downstream_model.depends_on.nodes) == [\n            \"metric.test.average_order_value\",\n            \"metric.test.count_orders\",\n            \"metric.test.sum_order_revenue\",\n        ]\n        assert sorted(downstream_model.config[\"metric_names\"]) == metric_names\n\n        # make sure the 'expression' metric depends on the two upstream metrics\n        derived_metric = manifest.metrics[\"metric.test.average_order_value\"]\n        assert sorted(derived_metric.depends_on.nodes) == [\n            \"metric.test.count_orders\",\n            \"metric.test.sum_order_revenue\",\n        ]\n\n        derived_metric_with_custom_offset_window = manifest.metrics[\n            \"metric.test.sum_order_revenue_plus_one_custom_offset_window\"\n        ]\n        assert len(derived_metric_with_custom_offset_window.input_metrics) == 1\n        assert derived_metric_with_custom_offset_window.input_metrics[\n            0\n        ].offset_window == MetricTimeWindow(count=1, granularity=\"martian_day\")\n\n        # actually compile\n        results = run_dbt([\"compile\", \"--select\", \"downstream_model\"])\n        compiled_code = results[0].node.compiled_code\n\n        # make sure all these metrics properties show up in compiled SQL\n        for metric_name in manifest.metrics:\n            if metric_name == \"metric.test.sum_order_revenue_plus_one_custom_offset_window\":\n                # Skip this metric\n                continue\n\n            parsed_metric_node = manifest.metrics[metric_name]\n            for property in [\n                \"name\",\n                \"label\",\n                \"type\",\n                \"type_params\",\n                \"filter\",\n            ]:\n                expected_value = getattr(parsed_metric_node, property)\n                assert f\"{property}: {expected_value}\" in compiled_code\n\n\nclass TestInvalidTimestampTimeGrainsMetrics:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"people_metrics.yml\": invalid_metric_without_timestamp_with_time_grains_yml,\n            \"people.sql\": models_people_sql,\n        }\n\n    # Tests that we get a ParsingError with an invalid metric definition.\n    # This metric definition is missing timestamp but HAS a time_grains property\n    def test_simple_metric(\n        self,\n        project,\n    ):\n        # initial run\n        with pytest.raises(ParsingError):\n            run_dbt([\"run\"])\n\n\nclass TestInvalidTimestampWindowMetrics:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"people_metrics.yml\": invalid_metric_without_timestamp_with_window_yml,\n            \"people.sql\": models_people_sql,\n        }\n\n    # Tests that we get a ParsingError with an invalid metric definition.\n    # This metric definition is missing timestamp but HAS a window property\n    def test_simple_metric(\n        self,\n        project,\n    ):\n        # initial run\n        with pytest.raises(ParsingError):\n            run_dbt([\"run\"])\n\n\nclass TestConversionMetric:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"purchasing.sql\": purchasing_model_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"semantic_models.yml\": conversion_semantic_model_purchasing_yml,\n            \"conversion_metric.yml\": conversion_metric_yml,\n            \"time_spine.yml\": time_spine_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\n            \"mock_purchase_data.csv\": mock_purchase_data_csv,\n        }\n\n    def test_conversion_metric(\n        self,\n        project,\n    ):\n        # initial parse\n        runner = dbtRunner()\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        assert isinstance(result.result, Manifest)\n\n        # make sure the metric is in the manifest\n        manifest = get_manifest(project.project_root)\n        metric_ids = list(manifest.metrics.keys())\n        expected_metric_ids = {\n            \"metric.test.converted_orders_over_visits\": None,\n            \"metric.test.converted_orders_over_visits_with_window\": MetricTimeWindow(\n                count=4, granularity=TimeGranularity.DAY.value\n            ),\n        }\n        assert set(metric_ids) == set(expected_metric_ids.keys())\n        assert manifest.metrics[\n            \"metric.test.converted_orders_over_visits\"\n        ].type_params.conversion_type_params\n        assert (\n            len(\n                manifest.metrics[\n                    \"metric.test.converted_orders_over_visits\"\n                ].type_params.input_measures\n            )\n            == 2\n        )\n        assert (\n            manifest.metrics[\n                \"metric.test.converted_orders_over_visits\"\n            ].type_params.conversion_type_params.window\n            is None\n        )\n        assert (\n            manifest.metrics[\n                \"metric.test.converted_orders_over_visits\"\n            ].type_params.conversion_type_params.entity\n            == \"purchase\"\n        )\n        for (\n            metric_id,\n            expected_window,\n        ) in expected_metric_ids.items():\n            assert (\n                manifest.metrics[metric_id].type_params.conversion_type_params.window\n                == expected_window\n            ), f\"Found unexpected conversion window for {metric_id}\"\n\n\nclass TestCumulativeMetric:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"purchasing.sql\": purchasing_model_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"semantic_models.yml\": conversion_semantic_model_purchasing_yml,\n            \"cumulative_metric.yml\": cumulative_metric_yml,\n            \"time_spine.yml\": time_spine_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\"mock_purchase_data.csv\": mock_purchase_data_csv}\n\n    def test_cumulative_metric(self, project):\n        # initial parse\n        runner = dbtRunner()\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        assert isinstance(result.result, Manifest)\n\n        manifest = get_manifest(project.project_root)\n        metric_ids = set(manifest.metrics.keys())\n        expected_metric_ids_to_cumulative_type_params = {\n            \"metric.test.weekly_visits\": CumulativeTypeParams(\n                window=MetricTimeWindow(count=7, granularity=TimeGranularity.DAY.value),\n                period_agg=PeriodAggregation.AVERAGE,\n            ),\n            \"metric.test.cumulative_orders\": CumulativeTypeParams(\n                period_agg=PeriodAggregation.LAST\n            ),\n            \"metric.test.orders_ytd\": CumulativeTypeParams(\n                grain_to_date=TimeGranularity.YEAR.value, period_agg=PeriodAggregation.FIRST\n            ),\n            \"metric.test.monthly_orders\": CumulativeTypeParams(\n                window=MetricTimeWindow(count=1, granularity=TimeGranularity.MONTH.value),\n                period_agg=PeriodAggregation.AVERAGE,\n            ),\n            \"metric.test.yearly_orders\": CumulativeTypeParams(\n                window=MetricTimeWindow(count=1, granularity=TimeGranularity.YEAR.value),\n                period_agg=PeriodAggregation.FIRST,\n            ),\n            \"metric.test.visits_mtd\": CumulativeTypeParams(\n                grain_to_date=TimeGranularity.MONTH.value, period_agg=PeriodAggregation.FIRST\n            ),\n            \"metric.test.cumulative_visits\": CumulativeTypeParams(\n                period_agg=PeriodAggregation.FIRST\n            ),\n        }\n        assert metric_ids == set(expected_metric_ids_to_cumulative_type_params.keys())\n        for (\n            metric_id,\n            expected_cumulative_type_params,\n        ) in expected_metric_ids_to_cumulative_type_params.items():\n            assert (\n                manifest.metrics[metric_id].type_params.cumulative_type_params\n                == expected_cumulative_type_params\n            ), f\"Found unexpected cumulative type params for {metric_id}\"\n\n\nclass TestFilterParsing:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"basic_metrics.yml\": basic_metrics_yml,\n            \"filtered_metrics.yml\": filtered_metrics_yml,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"semantic_model_people.yml\": semantic_model_people_yml,\n            \"people.sql\": models_people_sql,\n        }\n\n    # Tests that filters are parsed to their appropriate types\n    def test_filter_parsing(\n        self,\n        project,\n    ):\n        runner = dbtRunner()\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        assert isinstance(result.result, Manifest)\n\n        manifest = get_manifest(project.project_root)\n        assert manifest\n\n        # Test metrics with input measure filters.\n        filters1 = (\n            manifest.metrics[\"metric.test.collective_tenure_measure_filter_str\"]\n            .input_measures[0]\n            .filter.where_filters\n        )\n        assert len(filters1) == 1\n        assert filters1[0].where_sql_template == \"{{ Dimension('id__loves_dbt') }} is true\"\n        filters2 = (\n            manifest.metrics[\"metric.test.collective_tenure_measure_filter_list\"]\n            .input_measures[0]\n            .filter.where_filters\n        )\n        assert len(filters2) == 1\n        assert filters2[0].where_sql_template == \"{{ Dimension('id__loves_dbt') }} is true\"\n\n        # Test metrics with metric-level filters.\n        filters3 = manifest.metrics[\n            \"metric.test.collective_tenure_metric_filter_str\"\n        ].filter.where_filters\n        assert len(filters3) == 1\n        assert filters3[0].where_sql_template == \"{{ Dimension('id__loves_dbt') }} is true\"\n        filters4 = manifest.metrics[\n            \"metric.test.collective_tenure_metric_filter_list\"\n        ].filter.where_filters\n        assert len(filters4) == 1\n        assert filters4[0].where_sql_template == \"{{ Dimension('id__loves_dbt') }} is true\"\n\n        # Test derived metrics with input metric filters.\n        filters5 = (\n            manifest.metrics[\"metric.test.average_tenure_filter_str\"]\n            .input_metrics[0]\n            .filter.where_filters\n        )\n        assert len(filters5) == 1\n        assert filters5[0].where_sql_template == \"{{ Dimension('id__loves_dbt') }} is true\"\n        filters6 = (\n            manifest.metrics[\"metric.test.average_tenure_filter_list\"]\n            .input_metrics[0]\n            .filter.where_filters\n        )\n        assert len(filters6) == 1\n        assert filters6[0].where_sql_template == \"{{ Dimension('id__loves_dbt') }} is true\"\n\n\nclass TestDuplicateInputMeasures:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"basic_metrics.yml\": basic_metrics_yml,\n            \"filtered_metrics.yml\": duplicate_measure_metric_yml,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"semantic_model_people.yml\": semantic_model_people_yml,\n            \"people.sql\": models_people_sql,\n        }\n\n    def test_duplicate_input_measures(self, project):\n        runner = dbtRunner()\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        assert isinstance(result.result, Manifest)\n"
  },
  {
    "path": "tests/functional/microbatch/test_microbatch.py",
    "content": "import json\nimport os\nfrom typing import Dict\nfrom unittest import mock\n\nimport pytest\nfrom pytest_mock import MockerFixture\n\nfrom dbt.events.types import (\n    GenericExceptionOnRun,\n    InvalidConcurrentBatchesConfig,\n    JinjaLogDebug,\n    LogBatchResult,\n    LogModelResult,\n    MicrobatchExecutionDebug,\n    MicrobatchMacroOutsideOfBatchesDeprecation,\n    MicrobatchModelNoEventTimeInputs,\n)\nfrom dbt.tests.fixtures.project import TestProjInfo\nfrom dbt.tests.util import (\n    get_artifact,\n    patch_microbatch_end_time,\n    read_file,\n    relation_from_name,\n    run_dbt,\n    run_dbt_and_capture,\n    write_file,\n)\nfrom dbt_common.events.event_catcher import EventCatcher\n\ninput_model_sql = \"\"\"\n{{ config(materialized='table', event_time='event_time') }}\n\nselect 1 as id, TIMESTAMP '2020-01-01 00:00:00-0' as event_time\nunion all\nselect 2 as id, TIMESTAMP '2020-01-02 00:00:00-0' as event_time\nunion all\nselect 3 as id, TIMESTAMP '2020-01-03 00:00:00-0' as event_time\n\"\"\"\n\ninput_model_invalid_sql = \"\"\"\n{{ config(materialized='table', event_time='event_time') }}\n\nselect invalid as event_time\n\"\"\"\n\ninput_model_without_event_time_sql = \"\"\"\n{{ config(materialized='table') }}\n\nselect 1 as id, TIMESTAMP '2020-01-01 00:00:00-0' as event_time\nunion all\nselect 2 as id, TIMESTAMP '2020-01-02 00:00:00-0' as event_time\nunion all\nselect 3 as id, TIMESTAMP '2020-01-03 00:00:00-0' as event_time\n\"\"\"\n\nmicrobatch_model_sql = \"\"\"\n{{ config(materialized='incremental', incremental_strategy='microbatch', unique_key='id', event_time='event_time', batch_size='day', begin=modules.datetime.datetime(2020, 1, 1, 0, 0, 0)) }}\nselect * from {{ ref('input_model') }}\n\"\"\"\n\nmicrobatch_model_hour_sql = \"\"\"\n{{ config(materialized='incremental', incremental_strategy='microbatch', unique_key='id', event_time='event_time', batch_size='hour', begin=modules.datetime.datetime(2020, 1, 1, 0, 0, 0)) }}\nselect * from {{ ref('input_model') }}\n\"\"\"\n\nmicrobatch_model_month_sql = \"\"\"\n{{ config(materialized='incremental', incremental_strategy='microbatch', unique_key='id', event_time='event_time', batch_size='month', begin=modules.datetime.datetime(2020, 1, 1, 0, 0, 0)) }}\nselect * from {{ ref('input_model') }}\n\"\"\"\n\nmicrobatch_model_year_sql = \"\"\"\n{{ config(materialized='incremental', incremental_strategy='microbatch', unique_key='id', event_time='event_time', batch_size='year', begin=modules.datetime.datetime(2020, 1, 1, 0, 0, 0)) }}\nselect * from {{ ref('input_model') }}\n\"\"\"\n\nmicrobatch_model_with_pre_and_post_sql = \"\"\"\n{{ config(\n        materialized='incremental',\n        incremental_strategy='microbatch',\n        unique_key='id',\n        event_time='event_time',\n        batch_size='day',\n        begin=modules.datetime.datetime(2020, 1, 1, 0, 0, 0),\n        pre_hook='{{log(\"execute: \" ~ execute ~ \", pre-hook run by batch \" ~ model.batch.id)}}',\n        post_hook='{{log(\"execute: \" ~ execute ~ \", post-hook run by batch \" ~ model.batch.id)}}',\n    )\n}}\nselect * from {{ ref('input_model') }}\n\"\"\"\n\nmicrobatch_model_force_concurrent_batches_sql = \"\"\"\n{{ config(materialized='incremental', incremental_strategy='microbatch', unique_key='id', event_time='event_time', batch_size='day', begin=modules.datetime.datetime(2020, 1, 1, 0, 0, 0), concurrent_batches=true) }}\nselect * from {{ ref('input_model') }}\n\"\"\"\n\nmicrobatch_yearly_model_sql = \"\"\"\n{{ config(materialized='incremental', incremental_strategy='microbatch', unique_key='id', event_time='event_time', batch_size='year', begin=modules.datetime.datetime(2020, 1, 1, 0, 0, 0)) }}\nselect * from {{ ref('input_model') }}\n\"\"\"\n\nmicrobatch_yearly_model_downstream_sql = \"\"\"\n{{ config(materialized='incremental', incremental_strategy='microbatch', unique_key='id', event_time='event_time', batch_size='year', begin=modules.datetime.datetime(2020, 1, 1, 0, 0, 0)) }}\nselect * from {{ ref('microbatch_model') }}\n\"\"\"\n\ninvalid_batch_jinja_context_macro_sql = \"\"\"\n{% macro check_invalid_batch_jinja_context() %}\n\n{% if model is not mapping %}\n    {{ exceptions.raise_compiler_error(\"`model` is invalid: expected mapping type\") }}\n{% elif compiled_code and compiled_code is not string %}\n    {{ exceptions.raise_compiler_error(\"`compiled_code` is invalid: expected string type\") }}\n{% elif sql and sql is not string %}\n    {{ exceptions.raise_compiler_error(\"`sql` is invalid: expected string type\") }}\n{% elif is_incremental is not callable %}\n    {{ exceptions.raise_compiler_error(\"`is_incremental()` is invalid: expected callable type\") }}\n{% elif should_full_refresh is not callable %}\n    {{ exceptions.raise_compiler_error(\"`should_full_refresh()` is invalid: expected callable type\") }}\n{% endif %}\n\n{% endmacro %}\n\"\"\"\n\nmicrobatch_model_with_context_checks_sql = \"\"\"\n{{ config(pre_hook=\"{{ check_invalid_batch_jinja_context() }}\", materialized='incremental', incremental_strategy='microbatch', unique_key='id', event_time='event_time', batch_size='day', begin=modules.datetime.datetime(2020, 1, 1, 0, 0, 0)) }}\n\n{{ check_invalid_batch_jinja_context() }}\nselect * from {{ ref('input_model') }}\n\"\"\"\n\nmicrobatch_model_downstream_sql = \"\"\"\n{{ config(materialized='incremental', incremental_strategy='microbatch', unique_key='id', event_time='event_time', batch_size='day', begin=modules.datetime.datetime(2020, 1, 1, 0, 0, 0)) }}\nselect * from {{ ref('microbatch_model') }}\n\"\"\"\n\nmicrobatch_model_ref_render_sql = \"\"\"\n{{ config(materialized='incremental', incremental_strategy='microbatch', unique_key='id', event_time='event_time', batch_size='day', begin=modules.datetime.datetime(2020, 1, 1, 0, 0, 0)) }}\nselect * from {{ ref('input_model').render() }}\n\"\"\"\n\nseed_csv = \"\"\"id,event_time\n1,'2020-01-01 00:00:00-0'\n2,'2020-01-02 00:00:00-0'\n3,'2020-01-03 00:00:00-0'\n\"\"\"\n\nseeds_yaml = \"\"\"\nseeds:\n  - name: raw_source\n    config:\n      column_types:\n        event_time: TIMESTAMP\n\"\"\"\n\nsources_yaml = \"\"\"\nsources:\n  - name: seed_sources\n    schema: \"{{ target.schema }}\"\n    tables:\n      - name: raw_source\n        config:\n          event_time: event_time\n\"\"\"\n\nmicrobatch_model_calling_source_sql = \"\"\"\n{{ config(materialized='incremental', incremental_strategy='microbatch', unique_key='id', event_time='event_time', batch_size='day', begin=modules.datetime.datetime(2020, 1, 1, 0, 0, 0)) }}\nselect * from {{ source('seed_sources', 'raw_source') }}\n\"\"\"\n\ncustom_microbatch_strategy = \"\"\"\n{% macro get_incremental_microbatch_sql(arg_dict) %}\n    {% do log('custom microbatch strategy', info=True) %}\n\n     {%- set dest_cols_csv = get_quoted_csv(arg_dict[\"dest_columns\"] | map(attribute=\"name\")) -%}\n\n    insert into {{ arg_dict[\"target_relation\"] }} ({{ dest_cols_csv }})\n    (\n        select {{ dest_cols_csv }}\n        from {{ arg_dict[\"temp_relation\"] }}\n    )\n\n{% endmacro %}\n\"\"\"\n\n\ndownstream_model_of_microbatch_sql = \"\"\"\nSELECT * FROM {{ ref('microbatch_model') }}\n\"\"\"\n\nmicrobatch_model_full_refresh_false_sql = \"\"\"\n{{ config(materialized='incremental', incremental_strategy='microbatch', unique_key='id', event_time='event_time', batch_size='day', begin=modules.datetime.datetime(2020, 1, 1, 0, 0, 0), full_refresh=False) }}\nselect * from {{ ref('input_model') }}\n\"\"\"\n\n\nclass BaseMicrobatchCustomUserStrategy:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"input_model.sql\": input_model_sql,\n            \"microbatch_model.sql\": microbatch_model_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"microbatch.sql\": custom_microbatch_strategy}\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"flags\": {\n                \"require_batched_execution_for_custom_microbatch_strategy\": True,\n            }\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def deprecation_catcher(self) -> EventCatcher:\n        return EventCatcher(MicrobatchMacroOutsideOfBatchesDeprecation)\n\n\nclass TestMicrobatchCustomUserStrategyDefault(BaseMicrobatchCustomUserStrategy):\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"flags\": {\n                \"require_batched_execution_for_custom_microbatch_strategy\": False,\n            }\n        }\n\n    def test_use_custom_microbatch_strategy_by_default(\n        self,\n        project,\n        deprecation_catcher: EventCatcher,\n    ):\n        # Initial run fires deprecation\n        run_dbt([\"run\"], callbacks=[deprecation_catcher.catch])\n        # Deprecation warning about custom microbatch macro fired\n        assert len(deprecation_catcher.caught_events) == 1\n\n        # Incremental run uses custom strategy\n        _, logs = run_dbt_and_capture([\"run\"])\n        assert \"custom microbatch strategy\" in logs\n        # The custom strategy wasn't used with batch functionality\n        assert \"START batch\" not in logs\n\n\nclass TestMicrobatchCustomUserStrategyProjectFlagTrueValid(BaseMicrobatchCustomUserStrategy):\n    def test_use_custom_microbatch_strategy_project_flag_true_invalid_incremental_strategy(\n        self,\n        project,\n        deprecation_catcher: EventCatcher,\n    ):\n        with mock.patch.object(\n            type(project.adapter), \"valid_incremental_strategies\", lambda _: [\"microbatch\"]\n        ):\n            # Initial run\n            with patch_microbatch_end_time(\"2020-01-03 13:57:00\"):\n                run_dbt([\"run\"], callbacks=[deprecation_catcher.catch])\n            # Deprecation warning about custom microbatch macro not fired\n            assert len(deprecation_catcher.caught_events) == 0\n\n            # Incremental run uses custom strategy\n            with patch_microbatch_end_time(\"2020-01-03 13:57:00\"):\n                _, logs = run_dbt_and_capture([\"run\"])\n            assert \"custom microbatch strategy\" in logs\n            # The custom strategy was used with batch functionality\n            assert \"START batch\" in logs\n\n\nclass TestMicrobatchCustomUserStrategyProjectFlagTrueNoValidBuiltin(\n    BaseMicrobatchCustomUserStrategy\n):\n    def test_use_custom_microbatch_strategy_project_flag_true_invalid_incremental_strategy(\n        self, project\n    ):\n        with mock.patch.object(\n            type(project.adapter), \"valid_incremental_strategies\", lambda _: []\n        ):\n            # Run of microbatch model while adapter doesn't have a \"valid\"\n            # microbatch strategy causes no error when behaviour flag set to true\n            # and there is a custom microbatch macro\n            with patch_microbatch_end_time(\"2020-01-03 13:57:00\"):\n                _, logs = run_dbt_and_capture([\"run\"])\n            assert \"'microbatch' is not valid\" not in logs\n            assert (\n                \"The use of a custom microbatch macro outside of batched execution is deprecated\"\n                not in logs\n            )\n\n\nclass BaseMicrobatchTest:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"input_model.sql\": input_model_sql,\n            \"microbatch_model.sql\": microbatch_model_sql,\n        }\n\n    def assert_row_count(self, project, relation_name: str, expected_row_count: int):\n        relation = relation_from_name(project.adapter, relation_name)\n        result = project.run_sql(f\"select count(*) as num_rows from {relation}\", fetch=\"one\")\n\n        if result[0] != expected_row_count:\n            # running show for debugging\n            run_dbt([\"show\", \"--inline\", f\"select * from {relation}\"])\n\n            assert result[0] == expected_row_count\n\n\nclass TestMicrobatchCLI(BaseMicrobatchTest):\n    CLI_COMMAND_NAME = \"run\"\n\n    def test_run_with_event_time(self, project):\n        # run without --event-time-start or --event-time-end - 3 expected rows in output\n\n        model_catcher = EventCatcher(event_to_catch=LogModelResult)\n        batch_catcher = EventCatcher(event_to_catch=LogBatchResult)\n\n        with patch_microbatch_end_time(\"2020-01-03 13:57:00\"):\n            run_dbt([self.CLI_COMMAND_NAME], callbacks=[model_catcher.catch, batch_catcher.catch])\n        self.assert_row_count(project, \"microbatch_model\", 3)\n\n        assert len(model_catcher.caught_events) == 2\n        assert len(batch_catcher.caught_events) == 3\n        batch_creation_events = 0\n        for caught_event in batch_catcher.caught_events:\n            if \"batch 2020\" in caught_event.data.description:\n                batch_creation_events += 1\n                assert caught_event.data.execution_time > 0\n        # 3 batches should have been run, so there should be 3 batch\n        # creation events\n        assert batch_creation_events == 3\n\n        # build model between 2020-01-02 >= event_time < 2020-01-03\n        run_dbt(\n            [\n                self.CLI_COMMAND_NAME,\n                \"--event-time-start\",\n                \"2020-01-02\",\n                \"--event-time-end\",\n                \"2020-01-03\",\n                \"--full-refresh\",\n            ]\n        )\n        self.assert_row_count(project, \"microbatch_model\", 1)\n\n\nclass TestMicrobatchCLIBuild(TestMicrobatchCLI):\n    CLI_COMMAND_NAME = \"build\"\n\n\nclass TestMicrobatchCLIRunOutputJSON(BaseMicrobatchTest):\n    def test_list_output_json(self, project: TestProjInfo):\n        \"\"\"Test whether the command `dbt list --output json` works\"\"\"\n        model_catcher = EventCatcher(event_to_catch=LogModelResult)\n        batch_catcher = EventCatcher(event_to_catch=LogBatchResult)\n\n        _, microbatch_json = run_dbt(\n            [\"list\", \"--output\", \"json\"], callbacks=[model_catcher.catch, batch_catcher.catch]\n        )\n        microbatch_dict = json.loads(microbatch_json)\n        assert microbatch_dict[\"config\"][\"begin\"] == \"2020-01-01T00:00:00\"\n\n\nclass TestMicroBatchBoundsDefault(BaseMicrobatchTest):\n    def test_run_with_event_time(self, project):\n        # initial run -- backfills all data\n        with patch_microbatch_end_time(\"2020-01-03 13:57:00\"):\n            run_dbt([\"run\"])\n        self.assert_row_count(project, \"microbatch_model\", 3)\n\n        # our partition grain is \"day\" so running the same day without new data should produce the same results\n        with patch_microbatch_end_time(\"2020-01-03 14:57:00\"):\n            run_dbt([\"run\"])\n        self.assert_row_count(project, \"microbatch_model\", 3)\n\n        # add next two days of data\n        test_schema_relation = project.adapter.Relation.create(\n            database=project.database, schema=project.test_schema\n        )\n        project.run_sql(\n            f\"insert into {test_schema_relation}.input_model(id, event_time) values (4, TIMESTAMP '2020-01-04 00:00:00-0'), (5, TIMESTAMP '2020-01-05 00:00:00-0')\"\n        )\n        self.assert_row_count(project, \"input_model\", 5)\n\n        # re-run without changing current time => no insert\n        with patch_microbatch_end_time(\"2020-01-03 14:57:00\"):\n            run_dbt([\"run\", \"--select\", \"microbatch_model\"])\n        self.assert_row_count(project, \"microbatch_model\", 3)\n\n        # re-run by advancing time by one day changing current time => insert 1 row\n        with patch_microbatch_end_time(\"2020-01-04 14:57:00\"):\n            run_dbt([\"run\", \"--select\", \"microbatch_model\"])\n        self.assert_row_count(project, \"microbatch_model\", 4)\n\n        # re-run by advancing time by one more day changing current time => insert 1 more row\n        with patch_microbatch_end_time(\"2020-01-05 14:57:00\"):\n            run_dbt([\"run\", \"--select\", \"microbatch_model\"])\n        self.assert_row_count(project, \"microbatch_model\", 5)\n\n\nclass TestMicrobatchWithSource(BaseMicrobatchTest):\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\n            \"raw_source.csv\": seed_csv,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"microbatch_model.sql\": microbatch_model_calling_source_sql,\n            \"sources.yml\": sources_yaml,\n            \"seeds.yml\": seeds_yaml,\n        }\n\n    def test_run_with_event_time(self, project):\n        # ensure seed is created for source\n        run_dbt([\"seed\"])\n\n        # initial run -- backfills all data\n        catcher = EventCatcher(event_to_catch=MicrobatchModelNoEventTimeInputs)\n        with patch_microbatch_end_time(\"2020-01-03 13:57:00\"):\n            run_dbt([\"run\"], callbacks=[catcher.catch])\n        self.assert_row_count(project, \"microbatch_model\", 3)\n        assert len(catcher.caught_events) == 0\n\n        # our partition grain is \"day\" so running the same day without new data should produce the same results\n        with patch_microbatch_end_time(\"2020-01-03 14:57:00\"):\n            run_dbt([\"run\"])\n        self.assert_row_count(project, \"microbatch_model\", 3)\n\n        # add next two days of data\n        test_schema_relation = project.adapter.Relation.create(\n            database=project.database, schema=project.test_schema\n        )\n        project.run_sql(\n            f\"insert into {test_schema_relation}.raw_source(id, event_time) values (4, TIMESTAMP '2020-01-04 00:00:00-0'), (5, TIMESTAMP '2020-01-05 00:00:00-0')\"\n        )\n        self.assert_row_count(project, \"raw_source\", 5)\n\n        # re-run without changing current time => no insert\n        with patch_microbatch_end_time(\"2020-01-03 14:57:00\"):\n            run_dbt([\"run\", \"--select\", \"microbatch_model\"])\n        self.assert_row_count(project, \"microbatch_model\", 3)\n\n        # re-run by advancing time by one day changing current time => insert 1 row\n        with patch_microbatch_end_time(\"2020-01-04 14:57:00\"):\n            run_dbt([\"run\", \"--select\", \"microbatch_model\"])\n        self.assert_row_count(project, \"microbatch_model\", 4)\n\n        # re-run by advancing time by one more day changing current time => insert 1 more row\n        with patch_microbatch_end_time(\"2020-01-05 14:57:00\"):\n            run_dbt([\"run\", \"--select\", \"microbatch_model\"])\n        self.assert_row_count(project, \"microbatch_model\", 5)\n\n\nclass TestMicrobatchJinjaContext(BaseMicrobatchTest):\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"check_batch_jinja_context.sql\": invalid_batch_jinja_context_macro_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"input_model.sql\": input_model_sql,\n            \"microbatch_model.sql\": microbatch_model_with_context_checks_sql,\n        }\n\n    def test_run_with_event_time(self, project):\n        # initial run -- backfills all data\n        with patch_microbatch_end_time(\"2020-01-03 13:57:00\"):\n            run_dbt([\"run\"])\n        self.assert_row_count(project, \"microbatch_model\", 3)\n\n\nclass TestMicrobatchWithInputWithoutEventTime(BaseMicrobatchTest):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"input_model.sql\": input_model_without_event_time_sql,\n            \"microbatch_model.sql\": microbatch_model_sql,\n        }\n\n    def test_run_with_event_time(self, project):\n        catcher = EventCatcher(event_to_catch=MicrobatchModelNoEventTimeInputs)\n\n        # initial run -- backfills all data\n        with patch_microbatch_end_time(\"2020-01-03 13:57:00\"):\n            run_dbt([\"run\"], callbacks=[catcher.catch])\n        self.assert_row_count(project, \"microbatch_model\", 3)\n        assert len(catcher.caught_events) == 1\n\n        # our partition grain is \"day\" so running the same day without new data should produce the same results\n        catcher.caught_events = []\n        with patch_microbatch_end_time(\"2020-01-03 14:57:00\"):\n            run_dbt([\"run\"], callbacks=[catcher.catch])\n        self.assert_row_count(project, \"microbatch_model\", 3)\n        assert len(catcher.caught_events) == 1\n\n        # add next two days of data\n        test_schema_relation = project.adapter.Relation.create(\n            database=project.database, schema=project.test_schema\n        )\n        project.run_sql(\n            f\"insert into {test_schema_relation}.input_model(id, event_time) values (4, TIMESTAMP '2020-01-04 00:00:00-0'), (5, TIMESTAMP '2020-01-05 00:00:00-0')\"\n        )\n        self.assert_row_count(project, \"input_model\", 5)\n\n        # re-run without changing current time => INSERT BECAUSE INPUT MODEL ISN'T BEING FILTERED\n        with patch_microbatch_end_time(\"2020-01-03 14:57:00\"):\n            run_dbt([\"run\", \"--select\", \"microbatch_model\"])\n        self.assert_row_count(project, \"microbatch_model\", 5)\n\n\nclass TestMicrobatchUsingRefRenderSkipsFilter(BaseMicrobatchTest):\n    def test_run_with_event_time(self, project):\n        # initial run -- backfills all data\n        with patch_microbatch_end_time(\"2020-01-03 13:57:00\"):\n            run_dbt([\"run\"])\n        self.assert_row_count(project, \"microbatch_model\", 3)\n\n        # our partition grain is \"day\" so running the same day without new data should produce the same results\n        with patch_microbatch_end_time(\"2020-01-03 14:57:00\"):\n            run_dbt([\"run\"])\n        self.assert_row_count(project, \"microbatch_model\", 3)\n\n        # add next two days of data\n        test_schema_relation = project.adapter.Relation.create(\n            database=project.database, schema=project.test_schema\n        )\n        project.run_sql(\n            f\"insert into {test_schema_relation}.input_model(id, event_time) values (4, TIMESTAMP '2020-01-04 00:00:00-0'), (5, TIMESTAMP '2020-01-05 00:00:00-0')\"\n        )\n        self.assert_row_count(project, \"input_model\", 5)\n\n        # re-run without changing current time => no insert\n        with patch_microbatch_end_time(\"2020-01-03 14:57:00\"):\n            run_dbt([\"run\", \"--select\", \"microbatch_model\"])\n        self.assert_row_count(project, \"microbatch_model\", 3)\n\n        # Update microbatch model to call .render() on ref('input_model')\n        write_file(\n            microbatch_model_ref_render_sql, project.project_root, \"models\", \"microbatch_model.sql\"\n        )\n\n        # re-run without changing current time => INSERT because .render() skips filtering\n        with patch_microbatch_end_time(\"2020-01-03 14:57:00\"):\n            run_dbt([\"run\", \"--select\", \"microbatch_model\"])\n        self.assert_row_count(project, \"microbatch_model\", 5)\n\n\nmicrobatch_model_context_vars = \"\"\"\n{{ config(materialized='incremental', incremental_strategy='microbatch', unique_key='id', event_time='event_time', batch_size='day', begin=modules.datetime.datetime(2020, 1, 1, 0, 0, 0)) }}\n{{ log(\"start: \"~ model.config.__dbt_internal_microbatch_event_time_start, info=True)}}\n{{ log(\"end: \"~ model.config.__dbt_internal_microbatch_event_time_end, info=True)}}\n{% if model.batch %}\n{{ log(\"batch.event_time_start: \"~ model.batch.event_time_start, info=True)}}\n{{ log(\"batch.event_time_end: \"~ model.batch.event_time_end, info=True)}}\n{{ log(\"batch.id: \"~ model.batch.id, info=True)}}\n{{ log(\"start timezone: \"~ model.batch.event_time_start.tzinfo, info=True)}}\n{{ log(\"end timezone: \"~ model.batch.event_time_end.tzinfo, info=True)}}\n{% endif %}\nselect * from {{ ref('input_model') }}\n\"\"\"\n\n\nclass TestMicrobatchJinjaContextVarsAvailable(BaseMicrobatchTest):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"input_model.sql\": input_model_sql,\n            \"microbatch_model.sql\": microbatch_model_context_vars,\n        }\n\n    def test_run_with_event_time_logs(self, project):\n        with patch_microbatch_end_time(\"2020-01-03 13:57:00\"):\n            _, logs = run_dbt_and_capture([\"run\"])\n\n        assert \"start: 2020-01-01 00:00:00+00:00\" in logs\n        assert \"end: 2020-01-02 00:00:00+00:00\" in logs\n        assert \"batch.event_time_start: 2020-01-01 00:00:00+00:00\" in logs\n        assert \"batch.event_time_end: 2020-01-02 00:00:00+00:00\" in logs\n        assert \"batch.id: 20200101\" in logs\n        assert \"start timezone: UTC\" in logs\n        assert \"end timezone: UTC\" in logs\n\n        assert \"start: 2020-01-02 00:00:00+00:00\" in logs\n        assert \"end: 2020-01-03 00:00:00+00:00\" in logs\n        assert \"batch.event_time_start: 2020-01-02 00:00:00+00:00\" in logs\n        assert \"batch.event_time_end: 2020-01-03 00:00:00+00:00\" in logs\n        assert \"batch.id: 20200102\" in logs\n\n        assert \"start: 2020-01-03 00:00:00+00:00\" in logs\n        assert \"end: 2020-01-03 13:57:00+00:00\" in logs\n        assert \"batch.event_time_start: 2020-01-03 00:00:00+00:00\" in logs\n        assert \"batch.event_time_end: 2020-01-03 13:57:00+00:00\" in logs\n        assert \"batch.id: 20200103\" in logs\n\n        # compile does not have access to populated batch context vars, but should not break on access\n        with patch_microbatch_end_time(\"2020-01-03 13:57:00\"):\n            _, compile_logs = run_dbt_and_capture([\"compile\"])\n\n        assert \"start:\" in compile_logs\n        assert \"end:\" in compile_logs\n        assert \"batch.event_time_start:\" not in compile_logs\n        assert \"batch.event_time_end:\" not in compile_logs\n\n\nmicrobatch_model_failing_incremental_partition_sql = \"\"\"\n{{ config(materialized='incremental', incremental_strategy='microbatch', unique_key='id', event_time='event_time', batch_size='day', begin=modules.datetime.datetime(2020, 1, 1, 0, 0, 0)) }}\n{% if '2020-01-02' in (model.config.__dbt_internal_microbatch_event_time_start | string) %}\n invalid_sql\n{% endif %}\nselect * from {{ ref('input_model') }}\n\"\"\"\n\n\nclass TestMicrobatchIncrementalBatchFailure(BaseMicrobatchTest):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"input_model.sql\": input_model_sql,\n            \"microbatch_model.sql\": microbatch_model_failing_incremental_partition_sql,\n            \"downstream_model.sql\": downstream_model_of_microbatch_sql,\n        }\n\n    def test_run_with_event_time(self, project):\n        event_catcher = EventCatcher(\n            GenericExceptionOnRun, predicate=lambda event: event.data.node_info is not None\n        )\n\n        # run all partitions from start - 2 expected rows in output, one failed\n        with patch_microbatch_end_time(\"2020-01-03 13:57:00\"):\n            run_dbt([\"run\"], callbacks=[event_catcher.catch], expect_pass=False)\n\n        assert len(event_catcher.caught_events) == 1\n        self.assert_row_count(project, \"microbatch_model\", 2)\n\n        run_results = get_artifact(project.project_root, \"target\", \"run_results.json\")\n        microbatch_run_result = run_results[\"results\"][1]\n        assert microbatch_run_result[\"status\"] == \"partial success\"\n        batch_results = microbatch_run_result[\"batch_results\"]\n        assert batch_results is not None\n        assert len(batch_results[\"successful\"]) == 2\n        assert len(batch_results[\"failed\"]) == 1\n        assert run_results[\"results\"][2][\"status\"] == \"skipped\"\n\n\nclass TestMicrobatchRetriesPartialSuccesses(BaseMicrobatchTest):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"input_model.sql\": input_model_sql,\n            \"microbatch_model.sql\": microbatch_model_failing_incremental_partition_sql,\n        }\n\n    def test_run_with_event_time(self, project):\n        # run all partitions from start - 2 expected rows in output, one failed\n        with patch_microbatch_end_time(\"2020-01-03 13:57:00\"):\n            _, console_output = run_dbt_and_capture([\"run\"], expect_pass=False)\n\n        assert \"PARTIAL SUCCESS (2/3)\" in console_output\n        assert \"Completed with 1 partial success\" in console_output\n\n        self.assert_row_count(project, \"microbatch_model\", 2)\n\n        run_results = get_artifact(project.project_root, \"target\", \"run_results.json\")\n        microbatch_run_result = run_results[\"results\"][1]\n        assert microbatch_run_result[\"status\"] == \"partial success\"\n        batch_results = microbatch_run_result[\"batch_results\"]\n        assert batch_results is not None\n        assert len(batch_results[\"successful\"]) == 2\n        assert len(batch_results[\"failed\"]) == 1\n\n        # update the microbatch model so that it no longer fails\n        write_file(microbatch_model_sql, project.project_root, \"models\", \"microbatch_model.sql\")\n\n        with patch_microbatch_end_time(\"2020-01-03 13:57:00\"):\n            _, console_output = run_dbt_and_capture([\"retry\"])\n\n        assert \"PARTIAL SUCCESS\" not in console_output\n        assert \"Completed with 1 partial success\" not in console_output\n        assert \"Completed successfully\" in console_output\n\n        self.assert_row_count(project, \"microbatch_model\", 3)\n\n\nclass TestMicrobatchMultipleRetries(BaseMicrobatchTest):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"input_model.sql\": input_model_sql,\n            \"microbatch_model.sql\": microbatch_model_failing_incremental_partition_sql,\n        }\n\n    def test_run_with_event_time(self, project):\n        # run all partitions from start - 2 expected rows in output, one failed\n        with patch_microbatch_end_time(\"2020-01-03 13:57:00\"):\n            _, console_output = run_dbt_and_capture([\"run\"], expect_pass=False)\n\n        assert \"PARTIAL SUCCESS (2/3)\" in console_output\n        assert \"Completed with 1 partial success\" in console_output\n\n        self.assert_row_count(project, \"microbatch_model\", 2)\n\n        with patch_microbatch_end_time(\"2020-01-03 13:57:00\"):\n            _, console_output = run_dbt_and_capture([\"retry\"], expect_pass=False)\n\n        assert \"PARTIAL SUCCESS\" not in console_output\n        assert \"ERROR\" in console_output\n        assert \"Completed with 1 error, 0 partial successes, and 0 warnings\" in console_output\n\n        self.assert_row_count(project, \"microbatch_model\", 2)\n\n        with patch_microbatch_end_time(\"2020-01-03 13:57:00\"):\n            _, console_output = run_dbt_and_capture([\"retry\"], expect_pass=False)\n\n        assert \"PARTIAL SUCCESS\" not in console_output\n        assert \"ERROR\" in console_output\n        assert \"Completed with 1 error, 0 partial successes, and 0 warnings\" in console_output\n\n        self.assert_row_count(project, \"microbatch_model\", 2)\n\n\nmicrobatch_model_first_partition_failing_sql = \"\"\"\n{{ config(materialized='incremental', incremental_strategy='microbatch', unique_key='id', event_time='event_time', batch_size='day', begin=modules.datetime.datetime(2020, 1, 1, 0, 0, 0)) }}\n{% if '2020-01-01' in (model.config.__dbt_internal_microbatch_event_time_start | string) %}\n invalid_sql\n{% endif %}\nselect * from {{ ref('input_model') }}\n\"\"\"\n\nmicrobatch_model_second_batch_failing_sql = \"\"\"\n{{ config(materialized='incremental', incremental_strategy='microbatch', unique_key='id', event_time='event_time', batch_size='day', begin=modules.datetime.datetime(2020, 1, 1, 0, 0, 0)) }}\n{% if '20200102' == model.batch.id %}\n invalid_sql\n{% endif %}\nselect * from {{ ref('input_model') }}\n\"\"\"\n\n\nclass TestMicrobatchInitialBatchFailure(BaseMicrobatchTest):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"input_model.sql\": input_model_sql,\n            \"microbatch_model.sql\": microbatch_model_first_partition_failing_sql,\n        }\n\n    def test_run_with_event_time(self, project):\n        # When the first batch of a microbatch model fails, the rest of the batches should\n        # be skipped and the model marked as failed (not _partial success_)\n\n        general_exc_catcher = EventCatcher(\n            GenericExceptionOnRun,\n            predicate=lambda event: event.data.node_info is not None,\n        )\n        batch_catcher = EventCatcher(\n            event_to_catch=LogBatchResult,\n            predicate=lambda event: event.data.status == \"skipped\",\n        )\n\n        # run all partitions from start - 2 expected rows in output, one failed\n        with patch_microbatch_end_time(\"2020-01-03 13:57:00\"):\n            run_dbt(\n                [\"run\"],\n                expect_pass=False,\n                callbacks=[general_exc_catcher.catch, batch_catcher.catch],\n            )\n\n        assert len(general_exc_catcher.caught_events) == 1\n        assert len(batch_catcher.caught_events) == 2\n\n        # Because the first batch failed, and the rest of the batches were skipped, the table shouldn't\n        # exist in the data warehosue\n        relation_info = relation_from_name(project.adapter, \"microbatch_model\")\n        relation = project.adapter.get_relation(\n            relation_info.database, relation_info.schema, relation_info.name\n        )\n        assert relation is None\n\n\nclass TestMicrobatchSecondBatchFailure(BaseMicrobatchTest):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"input_model.sql\": input_model_sql,\n            \"microbatch_model.sql\": microbatch_model_second_batch_failing_sql,\n        }\n\n    def test_run_with_event_time(self, project):\n        event_catcher = EventCatcher(\n            GenericExceptionOnRun, predicate=lambda event: event.data.node_info is not None\n        )\n\n        # run all partitions from start - 2 expected rows in output, one failed\n        with patch_microbatch_end_time(\"2020-01-03 13:57:00\"):\n            run_dbt([\"run\"], expect_pass=False, callbacks=[event_catcher.catch])\n        assert len(event_catcher.caught_events) == 1\n        self.assert_row_count(project, \"microbatch_model\", 2)\n\n\nclass TestMicrobatchCompiledRunPaths(BaseMicrobatchTest):\n    def test_run_with_event_time(self, project):\n        # run all partitions from start - 2 expected rows in output, one failed\n        with patch_microbatch_end_time(\"2020-01-03 13:57:00\"):\n            run_dbt([\"run\"])\n\n        # Compiled paths - batch compilations\n        assert read_file(\n            project.project_root,\n            \"target\",\n            \"compiled\",\n            \"test\",\n            \"models\",\n            \"microbatch_model\",\n            \"microbatch_model_2020-01-01.sql\",\n        )\n        assert read_file(\n            project.project_root,\n            \"target\",\n            \"compiled\",\n            \"test\",\n            \"models\",\n            \"microbatch_model\",\n            \"microbatch_model_2020-01-02.sql\",\n        )\n        assert read_file(\n            project.project_root,\n            \"target\",\n            \"compiled\",\n            \"test\",\n            \"models\",\n            \"microbatch_model\",\n            \"microbatch_model_2020-01-03.sql\",\n        )\n\n        assert read_file(\n            project.project_root,\n            \"target\",\n            \"run\",\n            \"test\",\n            \"models\",\n            \"microbatch_model\",\n            \"microbatch_model_2020-01-01.sql\",\n        )\n        assert read_file(\n            project.project_root,\n            \"target\",\n            \"run\",\n            \"test\",\n            \"models\",\n            \"microbatch_model\",\n            \"microbatch_model_2020-01-02.sql\",\n        )\n        assert read_file(\n            project.project_root,\n            \"target\",\n            \"run\",\n            \"test\",\n            \"models\",\n            \"microbatch_model\",\n            \"microbatch_model_2020-01-03.sql\",\n        )\n\n\nclass TestMicrobatchCompiledRunPathsHourly(BaseMicrobatchTest):\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"input_model.sql\": input_model_sql,\n            \"microbatch_model.sql\": microbatch_model_hour_sql,\n        }\n\n    def test_run_with_event_time(self, project):\n        # run all partitions from start - 2 expected rows in output, one failed\n        with patch_microbatch_end_time(\"2020-01-03 13:57:00\"):\n            run_dbt([\"run\"])\n\n        # Compiled paths - batch compilations\n        assert read_file(\n            project.project_root,\n            \"target\",\n            \"compiled\",\n            \"test\",\n            \"models\",\n            \"microbatch_model\",\n            \"microbatch_model_2020-01-03T13.sql\",\n        )\n        assert read_file(\n            project.project_root,\n            \"target\",\n            \"run\",\n            \"test\",\n            \"models\",\n            \"microbatch_model\",\n            \"microbatch_model_2020-01-03T13.sql\",\n        )\n\n\nclass TestMicrobatchCompiledRunPathsMonthly(BaseMicrobatchTest):\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"input_model.sql\": input_model_sql,\n            \"microbatch_model.sql\": microbatch_model_month_sql,\n        }\n\n    def test_run_with_event_time(self, project):\n        # run all partitions from start - 2 expected rows in output, one failed\n        with patch_microbatch_end_time(\"2020-01-03 13:57:00\"):\n            run_dbt([\"run\"])\n\n        # Compiled paths - batch compilations\n        assert read_file(\n            project.project_root,\n            \"target\",\n            \"compiled\",\n            \"test\",\n            \"models\",\n            \"microbatch_model\",\n            \"microbatch_model_2020-01.sql\",\n        )\n        assert read_file(\n            project.project_root,\n            \"target\",\n            \"run\",\n            \"test\",\n            \"models\",\n            \"microbatch_model\",\n            \"microbatch_model_2020-01.sql\",\n        )\n\n\nclass TestMicrobatchCompiledRunPathsYearly(BaseMicrobatchTest):\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"input_model.sql\": input_model_sql,\n            \"microbatch_model.sql\": microbatch_model_year_sql,\n        }\n\n    def test_run_with_event_time(self, project):\n        # run all partitions from start - 2 expected rows in output, one failed\n        with patch_microbatch_end_time(\"2020-01-03 13:57:00\"):\n            run_dbt([\"run\"])\n\n        # Compiled paths - batch compilations\n        assert read_file(\n            project.project_root,\n            \"target\",\n            \"compiled\",\n            \"test\",\n            \"models\",\n            \"microbatch_model\",\n            \"microbatch_model_2020.sql\",\n        )\n        assert read_file(\n            project.project_root,\n            \"target\",\n            \"run\",\n            \"test\",\n            \"models\",\n            \"microbatch_model\",\n            \"microbatch_model_2020.sql\",\n        )\n\n\nclass TestMicrobatchFullRefreshConfigFalse(BaseMicrobatchTest):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"input_model.sql\": input_model_sql,\n            \"microbatch_model.sql\": microbatch_model_full_refresh_false_sql,\n            \"downstream_model.sql\": downstream_model_of_microbatch_sql,\n        }\n\n    def test_run_with_event_time(self, project):\n        # run all partitions from 2020-01-02 to spoofed \"now\" - 2 expected rows in output\n        with patch_microbatch_end_time(\"2020-01-03 13:57:00\"):\n            run_dbt(\n                [\n                    \"run\",\n                    \"--event-time-start\",\n                    \"2020-01-02\",\n                    \"--event-time-end\",\n                    \"2020-01-03 13:57:00\",\n                ]\n            )\n        self.assert_row_count(project, \"microbatch_model\", 2)\n\n        # re-running shouldn't change what it's in the data set because there is nothing new\n        with patch_microbatch_end_time(\"2020-01-03 13:57:00\"):\n            run_dbt([\"run\"])\n        self.assert_row_count(project, \"microbatch_model\", 2)\n\n        # running with --full-refresh shouldn't pick up 2020-01-01 BECAUSE the model has\n        # full_refresh = false\n        with patch_microbatch_end_time(\"2020-01-03 13:57:00\"):\n            run_dbt([\"run\", \"--full-refresh\"])\n        self.assert_row_count(project, \"microbatch_model\", 2)\n\n        # update the microbatch model to no longer have full_refresh=False config\n        write_file(microbatch_model_sql, project.project_root, \"models\", \"microbatch_model.sql\")\n\n        # running with full refresh should now pick up the 2020-01-01 data\n        with patch_microbatch_end_time(\"2020-01-03 13:57:00\"):\n            run_dbt([\"run\", \"--full-refresh\"])\n        self.assert_row_count(project, \"microbatch_model\", 3)\n\n\nclass TestMicrbobatchModelsRunWithSameCurrentTime(BaseMicrobatchTest):\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"input_model.sql\": input_model_sql,\n            \"microbatch_model.sql\": microbatch_yearly_model_sql,\n            \"second_microbatch_model.sql\": microbatch_yearly_model_downstream_sql,\n        }\n\n    def test_microbatch(self, project) -> None:\n        run_dbt([\"run\"])\n\n        run_results = get_artifact(project.project_root, \"target\", \"run_results.json\")\n        microbatch_model_last_batch = run_results[\"results\"][1][\"batch_results\"][\"successful\"][-1]\n        second_microbatch_model_last_batch = run_results[\"results\"][2][\"batch_results\"][\n            \"successful\"\n        ][-1]\n\n        # they should have the same last batch because they are using the _same_ \"current_time\"\n        assert microbatch_model_last_batch == second_microbatch_model_last_batch\n\n\nclass TestMicrobatchModelSkipped(BaseMicrobatchTest):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"input_model.sql\": input_model_invalid_sql,\n            \"microbatch_model.sql\": microbatch_model_sql,\n        }\n\n    def test_microbatch_model_skipped(self, project) -> None:\n        run_dbt([\"run\"], expect_pass=False)\n\n        run_results = get_artifact(project.project_root, \"target\", \"run_results.json\")\n\n        microbatch_result = run_results[\"results\"][1]\n        assert microbatch_result[\"status\"] == \"skipped\"\n        assert microbatch_result[\"batch_results\"] is None\n\n\nclass TestMicrobatchCanRunParallelOrSequential(BaseMicrobatchTest):\n    @pytest.fixture\n    def batch_exc_catcher(self) -> EventCatcher:\n        return EventCatcher(MicrobatchExecutionDebug)\n\n    def test_microbatch(\n        self, mocker: MockerFixture, project, batch_exc_catcher: EventCatcher\n    ) -> None:\n        mocked_srip = mocker.patch(\"dbt.task.run.MicrobatchBatchRunner.should_run_in_parallel\")\n\n        # Should be run in parallel\n        mocked_srip.return_value = True\n        with patch_microbatch_end_time(\"2020-01-03 13:57:00\"):\n            _ = run_dbt([\"run\"], callbacks=[batch_exc_catcher.catch])\n\n        assert len(batch_exc_catcher.caught_events) > 1\n        some_batches_run_concurrently = False\n        for caugh_event in batch_exc_catcher.caught_events:\n            if \"is being run concurrently\" in caugh_event.data.msg:  # type: ignore\n                some_batches_run_concurrently = True\n                break\n        assert some_batches_run_concurrently, \"Found no batches being run concurrently!\"\n\n        # reset caught events\n        batch_exc_catcher.caught_events = []\n\n        # Should _not_ run in parallel\n        mocked_srip.return_value = False\n        with patch_microbatch_end_time(\"2020-01-03 13:57:00\"):\n            _ = run_dbt([\"run\"], callbacks=[batch_exc_catcher.catch])\n\n        assert len(batch_exc_catcher.caught_events) > 1\n        some_batches_run_concurrently = False\n        for caugh_event in batch_exc_catcher.caught_events:\n            if \"is being run concurrently\" in caugh_event.data.msg:  # type: ignore\n                some_batches_run_concurrently = True\n                break\n        assert not some_batches_run_concurrently, \"Found a batch being run concurrently!\"\n\n\nclass TestFirstAndLastBatchAlwaysSequential(BaseMicrobatchTest):\n    @pytest.fixture\n    def batch_exc_catcher(self) -> EventCatcher:\n        return EventCatcher(\n            event_to_catch=MicrobatchExecutionDebug,\n            predicate=lambda event: \"is being run\" in event.data.msg,\n        )\n\n    def test_microbatch(\n        self, mocker: MockerFixture, project, batch_exc_catcher: EventCatcher\n    ) -> None:\n        mocked_srip = mocker.patch(\"dbt.task.run.MicrobatchBatchRunner.should_run_in_parallel\")\n\n        # Should be run in parallel\n        mocked_srip.return_value = True\n        with patch_microbatch_end_time(\"2020-01-03 13:57:00\"):\n            _ = run_dbt([\"run\"], callbacks=[batch_exc_catcher.catch])\n\n        assert len(batch_exc_catcher.caught_events) > 1\n\n        first_batch_event = batch_exc_catcher.caught_events[0]\n        last_batch_event = batch_exc_catcher.caught_events[-1]\n\n        for event in [first_batch_event, last_batch_event]:\n            assert \"is being run sequentially\" in event.data.msg  # type: ignore\n\n        for event in batch_exc_catcher.caught_events[1:-1]:\n            assert \"is being run concurrently\" in event.data.msg  # type: ignore\n\n\nclass TestFirstBatchRunsPreHookLastBatchRunsPostHook(BaseMicrobatchTest):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"input_model.sql\": input_model_sql,\n            \"microbatch_model.sql\": microbatch_model_with_pre_and_post_sql,\n        }\n\n    @pytest.fixture\n    def batch_log_catcher(self) -> EventCatcher:\n        def pre_or_post_hook(event) -> bool:\n            return \"execute: True\" in event.data.msg and (\n                \"pre-hook\" in event.data.msg or \"post-hook\" in event.data.msg\n            )\n\n        return EventCatcher(event_to_catch=JinjaLogDebug, predicate=pre_or_post_hook)\n\n    def test_microbatch(\n        self, mocker: MockerFixture, project, batch_log_catcher: EventCatcher\n    ) -> None:\n        with patch_microbatch_end_time(\"2020-01-04 13:57:00\"):\n            _ = run_dbt([\"run\"], callbacks=[batch_log_catcher.catch])\n\n        # There should be two logs as the pre-hook and post-hook should\n        # both only be run once\n        assert len(batch_log_catcher.caught_events) == 2\n\n        for event in batch_log_catcher.caught_events:\n            # batch id that should be firing pre-hook\n            if \"20200101\" in event.data.msg:  # type: ignore\n                assert \"pre-hook\" in event.data.msg  # type: ignore\n\n            # batch id that should be firing the post-hook\n            if \"20200104\" in event.data.msg:  # type: ignore\n                assert \"post-hook\" in event.data.msg  # type: ignore\n\n\nclass TestWhenOnlyOneBatchRunBothPostAndPreHooks(BaseMicrobatchTest):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"input_model.sql\": input_model_sql,\n            \"microbatch_model.sql\": microbatch_model_with_pre_and_post_sql,\n        }\n\n    @pytest.fixture\n    def batch_log_catcher(self) -> EventCatcher:\n        def pre_or_post_hook(event) -> bool:\n            return \"execute: True\" in event.data.msg and (\n                \"pre-hook\" in event.data.msg or \"post-hook\" in event.data.msg\n            )\n\n        return EventCatcher(event_to_catch=JinjaLogDebug, predicate=pre_or_post_hook)\n\n    @pytest.fixture\n    def generic_exception_catcher(self) -> EventCatcher:\n        return EventCatcher(event_to_catch=GenericExceptionOnRun)\n\n    def test_microbatch(\n        self,\n        project,\n        batch_log_catcher: EventCatcher,\n        generic_exception_catcher: EventCatcher,\n    ) -> None:\n        with patch_microbatch_end_time(\"2020-01-01 13:57:00\"):\n            _ = run_dbt(\n                [\"run\"], callbacks=[batch_log_catcher.catch, generic_exception_catcher.catch]\n            )\n\n        # There should be two logs as the pre-hook and post-hook should\n        # both only be run once\n        assert len(batch_log_catcher.caught_events) == 2\n\n        assert \"20200101\" in batch_log_catcher.caught_events[0].data.msg  # type: ignore\n        assert \"pre-hook\" in batch_log_catcher.caught_events[0].data.msg  # type: ignore\n        assert \"20200101\" in batch_log_catcher.caught_events[1].data.msg  # type: ignore\n        assert \"post-hook\" in batch_log_catcher.caught_events[1].data.msg  # type: ignore\n\n        # we had a bug where having only one batch caused a generic exception\n        assert len(generic_exception_catcher.caught_events) == 0\n\n\nclass TestCanSilenceInvalidConcurrentBatchesConfigWarning(BaseMicrobatchTest):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"input_model.sql\": input_model_sql,\n            \"microbatch_model.sql\": microbatch_model_force_concurrent_batches_sql,\n        }\n\n    @pytest.fixture\n    def event_catcher(self) -> EventCatcher:\n        return EventCatcher(event_to_catch=InvalidConcurrentBatchesConfig)\n\n    def test_microbatch(\n        self,\n        project,\n        event_catcher: EventCatcher,\n    ) -> None:\n        # This test works because postgres doesn't support concurrent batch execution\n        # If the postgres adapter starts supporting concurrent batch execution we'll\n        # need to start mocking the return value of `adapter.supports()`\n\n        with patch_microbatch_end_time(\"2020-01-01 13:57:00\"):\n            _ = run_dbt([\"run\"], callbacks=[event_catcher.catch])\n        # We didn't silence the warning, so we get it\n        assert len(event_catcher.caught_events) == 1\n\n        # Clear caught events\n        event_catcher.caught_events = []\n\n        # Run again with silencing\n        with patch_microbatch_end_time(\"2020-01-01 13:57:00\"):\n            _ = run_dbt(\n                [\"run\", \"--warn-error-options\", \"{'silence': ['InvalidConcurrentBatchesConfig']}\"],\n                callbacks=[event_catcher.catch],\n            )\n        # Because we silenced the warning, it shouldn't get fired\n        assert len(event_catcher.caught_events) == 0\n\n\nsingle_batch_microbatch_model_sql = \"\"\"\n{{\n    config(\n        materialized='incremental',\n        incremental_strategy='microbatch',\n        unique_key='tmp',\n        event_time='tmp',\n        begin=modules.datetime.datetime.now(),\n        lookback=0,\n        batch_size='day',\n        meta={'param': 'invalid_param'},\n        pre_hook=[\n            validate_param('param1')\n        ]\n    )\n}}\n\nSELECT current_date as tmp\n\"\"\"\n\nvalidate_param_macro_sql = \"\"\"\n{% macro validate_param(valid_param) %}\n    {% set current_param = config.get('meta')['param'] %}\n\n    {% if execute %}\n        {% if current_param != valid_param %}\n            {% set exceptions_message = \"Invalid param: \" ~ current_param ~ \", valid param: \" ~ valid_param %}\n            {% do exceptions.raise_compiler_error(exceptions_message) %}\n        {% endif %}\n    {% endif %}\n{% endmacro %}\n\"\"\"\n\n\nclass TestCompilationErrorOnSingleBatchRun(BaseMicrobatchTest):\n    @pytest.fixture(scope=\"class\")\n    def models(self) -> Dict[str, str]:\n        return {\n            \"microbatch_model.sql\": single_batch_microbatch_model_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self) -> Dict[str, str]:\n        return {\n            \"validate_param.sql\": validate_param_macro_sql,\n        }\n\n    def test_microbatch(self, project) -> None:\n        _, console_output = run_dbt_and_capture([\"run\"], expect_pass=False)\n        assert \"Completed with 1 error, 0 partial successes, and 0 warnings\" in console_output\n\n\nmicrobatch_model_all_failing_sql = \"\"\"\n{{ config(materialized='incremental', incremental_strategy='microbatch', unique_key='id', event_time='event_time', batch_size='day', begin=modules.datetime.datetime(2020, 1, 1, 0, 0, 0)) }}\n invalid_sql\nselect * from {{ ref('input_model') }}\n\"\"\"\n\n\nclass TestMicrobatchRetryUsesOriginalInvocationTime(BaseMicrobatchTest):\n    \"\"\"When all batches fail and dbt retry is run later, the retry should\n    recompute batches using the original invocation time, not the current time.\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"input_model.sql\": input_model_sql,\n            \"microbatch_model.sql\": microbatch_model_all_failing_sql,\n        }\n\n    def test_retry_uses_original_invocation_time(self, project):\n        # Run with end time of 2020-01-03 — produces 3 batches, all fail\n        with patch_microbatch_end_time(\"2020-01-03 13:57:00\"):\n            run_dbt([\"run\"], expect_pass=False)\n\n        run_results = get_artifact(project.project_root, \"target\", \"run_results.json\")\n        microbatch_result = next(\n            r for r in run_results[\"results\"] if \"microbatch_model\" in r[\"unique_id\"]\n        )\n        assert microbatch_result[\"status\"] == \"error\"\n\n        # Simulate the original run happening at 2020-01-03 by updating\n        # invocation_started_at in the saved run_results.json\n        run_results_path = os.path.join(project.project_root, \"target\", \"run_results.json\")\n        run_results[\"metadata\"][\"invocation_started_at\"] = \"2020-01-03T13:57:00Z\"\n        with open(run_results_path, \"w\") as f:\n            json.dump(run_results, f)\n\n        # Fix the model so retry can succeed\n        write_file(\n            microbatch_model_sql,\n            project.project_root,\n            \"models\",\n            \"microbatch_model.sql\",\n        )\n\n        # Run retry WITHOUT patching end time. The fix ensures retry\n        # uses the original invocation time from run_results.json (2020-01-03),\n        # so only 3 batches are produced. Without the fix, it would use\n        # the current time and produce many more batches.\n        batch_catcher = EventCatcher(event_to_catch=LogBatchResult)\n        run_dbt([\"retry\"], callbacks=[batch_catcher.catch])\n\n        # Should only have 3 batches (2020-01-01, 2020-01-02, 2020-01-03)\n        assert len(batch_catcher.caught_events) == 3\n        self.assert_row_count(project, \"microbatch_model\", 3)\n\n\nclass TestMicrobatchBuildRetryUsesOriginalInvocationTime(BaseMicrobatchTest):\n    \"\"\"Same as above but using dbt build + retry to verify the issubclass\n    check ensures BuildTask also gets original invocation time behavior.\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"input_model.sql\": input_model_sql,\n            \"microbatch_model.sql\": microbatch_model_all_failing_sql,\n        }\n\n    def test_build_retry_uses_original_invocation_time(self, project):\n        # Run build with end time of 2020-01-03 — produces 3 batches, all fail\n        with patch_microbatch_end_time(\"2020-01-03 13:57:00\"):\n            run_dbt([\"build\"], expect_pass=False)\n\n        run_results = get_artifact(project.project_root, \"target\", \"run_results.json\")\n        microbatch_result = next(\n            r for r in run_results[\"results\"] if \"microbatch_model\" in r[\"unique_id\"]\n        )\n        assert microbatch_result[\"status\"] == \"error\"\n\n        # Simulate the original build happening at 2020-01-03 by updating\n        # invocation_started_at in the saved run_results.json\n        run_results_path = os.path.join(project.project_root, \"target\", \"run_results.json\")\n        run_results[\"metadata\"][\"invocation_started_at\"] = \"2020-01-03T13:57:00Z\"\n        with open(run_results_path, \"w\") as f:\n            json.dump(run_results, f)\n\n        # Fix the model so retry can succeed\n        write_file(\n            microbatch_model_sql,\n            project.project_root,\n            \"models\",\n            \"microbatch_model.sql\",\n        )\n\n        # Retry should use the original invocation time, not \"now\"\n        batch_catcher = EventCatcher(event_to_catch=LogBatchResult)\n        run_dbt([\"retry\"], callbacks=[batch_catcher.catch])\n\n        # Should only have 3 batches (2020-01-01, 2020-01-02, 2020-01-03)\n        assert len(batch_catcher.caught_events) == 3\n        self.assert_row_count(project, \"microbatch_model\", 3)\n"
  },
  {
    "path": "tests/functional/microbatch/test_microbatch_config_validation.py",
    "content": "import pytest\n\nfrom dbt.exceptions import ParsingError\nfrom dbt.tests.util import run_dbt\n\nvalid_microbatch_model_sql = \"\"\"\n{{ config(materialized='incremental', incremental_strategy='microbatch', batch_size='day', event_time='event_time') }}\nselect * from {{ ref('input_model') }}\n\"\"\"\n\nvalid_microbatch_model_no_config_sql = \"\"\"\nselect * from {{ ref('input_model') }}\n\"\"\"\n\nvalid_microbatch_model_config_yml = \"\"\"\nmodels:\n  - name: microbatch\n    config:\n      materialized: incremental\n      incremental_strategy: microbatch\n      batch_size: day\n      event_time: event_time\n      begin: 2020-01-01\n\"\"\"\n\ninvalid_microbatch_model_config_yml = \"\"\"\nmodels:\n  - name: microbatch\n    config:\n      materialized: incremental\n      incremental_strategy: microbatch\n      batch_size: day\n      event_time: event_time\n      begin: 2020-01-01 11 PM\n\"\"\"\n\nmissing_event_time_microbatch_model_sql = \"\"\"\n{{ config(materialized='incremental', incremental_strategy='microbatch', batch_size='day') }}\nselect * from {{ ref('input_model') }}\n\"\"\"\n\ninvalid_event_time_microbatch_model_sql = \"\"\"\n{{ config(materialized='incremental', incremental_strategy='microbatch', batch_size='day', event_time=2) }}\nselect * from {{ ref('input_model') }}\n\"\"\"\n\nmissing_begin_microbatch_model_sql = \"\"\"\n{{ config(materialized='incremental', incremental_strategy='microbatch', batch_size='day', event_time='event_time') }}\nselect * from {{ ref('input_model') }}\n\"\"\"\n\ninvalid_begin_microbatch_model_sql = \"\"\"\n{{ config(materialized='incremental', incremental_strategy='microbatch', batch_size='day', event_time='event_time', begin=2) }}\nselect * from {{ ref('input_model') }}\n\"\"\"\n\n\nmissing_batch_size_microbatch_model_sql = \"\"\"\n{{ config(materialized='incremental', incremental_strategy='microbatch', event_time='event_time') }}\nselect * from {{ ref('input_model') }}\n\"\"\"\n\ninvalid_batch_size_microbatch_model_sql = \"\"\"\n{{ config(materialized='incremental', incremental_strategy='microbatch', batch_size='invalid', event_time='event_time') }}\nselect * from {{ ref('input_model') }}\n\"\"\"\n\ninvalid_event_time_input_model_sql = \"\"\"\n{{ config(materialized='table', event_time=1) }}\n\nselect 1 as id, TIMESTAMP '2020-01-01 00:00:00-0' as event_time\n\"\"\"\n\nvalid_input_model_sql = \"\"\"\n{{ config(materialized='table') }}\n\nselect 1 as id, TIMESTAMP '2020-01-01 00:00:00-0' as event_time\n\"\"\"\n\n\nclass BaseMicrobatchTestParseError:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {}\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"flags\": {\n                \"require_batched_execution_for_custom_microbatch_strategy\": True,\n            }\n        }\n\n    def test_parsing_error_raised(self, project):\n        with pytest.raises(ParsingError):\n            run_dbt([\"parse\"])\n\n\nclass BaseMicrobatchTestNoError:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {}\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"flags\": {\n                \"require_batched_execution_for_custom_microbatch_strategy\": True,\n            }\n        }\n\n    def test_parsing_error_not_raised(self, project):\n        run_dbt([\"parse\"])\n\n\nclass TestMissingEventTimeMicrobatch(BaseMicrobatchTestParseError):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"input_model.sql\": valid_input_model_sql,\n            \"microbatch.sql\": missing_event_time_microbatch_model_sql,\n        }\n\n\nclass TestInvalidEventTimeMicrobatch(BaseMicrobatchTestParseError):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"input_model.sql\": valid_input_model_sql,\n            \"microbatch.sql\": invalid_event_time_microbatch_model_sql,\n        }\n\n\nclass TestMissingBeginMicrobatch(BaseMicrobatchTestParseError):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"input_model.sql\": valid_input_model_sql,\n            \"microbatch.sql\": missing_begin_microbatch_model_sql,\n        }\n\n\nclass TestInvaliBeginTypeMicrobatch(BaseMicrobatchTestParseError):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"input_model.sql\": valid_input_model_sql,\n            \"microbatch.sql\": invalid_begin_microbatch_model_sql,\n        }\n\n\nclass TestInvaliBegiFormatMicrobatch(BaseMicrobatchTestParseError):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"input_model.sql\": valid_input_model_sql,\n            \"microbatch.sql\": valid_microbatch_model_no_config_sql,\n            \"microbatch.yml\": invalid_microbatch_model_config_yml,\n        }\n\n\nclass TestMissingBatchSizeMicrobatch(BaseMicrobatchTestParseError):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"input_model.sql\": valid_input_model_sql,\n            \"microbatch.sql\": missing_batch_size_microbatch_model_sql,\n        }\n\n\nclass TestInvalidBatchSizeMicrobatch(BaseMicrobatchTestParseError):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"input_model.sql\": valid_input_model_sql,\n            \"microbatch.sql\": invalid_batch_size_microbatch_model_sql,\n        }\n\n\nclass TestInvalidInputEventTimeMicrobatch(BaseMicrobatchTestParseError):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"input_model.sql\": invalid_event_time_input_model_sql,\n            \"microbatch.sql\": valid_microbatch_model_sql,\n        }\n\n\nclass TestValidBeginMicrobatch(BaseMicrobatchTestNoError):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"input_model.sql\": valid_input_model_sql,\n            \"microbatch.sql\": valid_microbatch_model_no_config_sql,\n            \"schema.yml\": valid_microbatch_model_config_yml,\n        }\n"
  },
  {
    "path": "tests/functional/minimal_cli/fixtures.py",
    "content": "import pytest\nfrom click.testing import CliRunner\n\nmodels__schema_yml = \"\"\"\nversion: 2\nmodels:\n  - name: sample_model\n    columns:\n      - name: sample_num\n        data_tests:\n          - accepted_values:\n              values: [1, 2]\n          - not_null\n      - name: sample_bool\n        data_tests:\n          - not_null\n          - unique\n\"\"\"\n\nmodels__sample_model = \"\"\"\nselect * from {{ ref('sample_seed') }}\n\"\"\"\n\nsnapshots__sample_snapshot = \"\"\"\n{% snapshot orders_snapshot %}\n\n{{\n    config(\n      target_database='dbt',\n      target_schema='snapshots',\n      unique_key='sample_num',\n      strategy='timestamp',\n      updated_at='updated_at',\n    )\n}}\n\nselect * from {{ ref('sample_model') }}\n\n{% endsnapshot %}\n\"\"\"\n\nseeds__sample_seed = \"\"\"sample_num,sample_bool\n1,true\n2,false\n,true\n\"\"\"\n\ntests__failing_sql = \"\"\"\n{{ config(severity = 'warn') }}\nselect 1\n\"\"\"\n\n\nclass BaseConfigProject:\n    @pytest.fixture()\n    def runner(self):\n        return CliRunner()\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"name\": \"jaffle_shop\",\n            \"profile\": \"jaffle_shop\",\n            \"version\": \"0.1.0\",\n            \"config-version\": 2,\n            \"clean-targets\": [\"target\", \"dbt_packages\", \"logs\"],\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def profiles_config_update(self):\n        return {\n            \"jaffle_shop\": {\n                \"outputs\": {\n                    \"dev\": {\n                        \"type\": \"postgres\",\n                        \"dbname\": \"dbt\",\n                        \"schema\": \"jaffle_shop\",\n                        \"host\": \"localhost\",\n                        \"user\": \"root\",\n                        \"port\": 5432,\n                        \"pass\": \"password\",\n                    }\n                },\n                \"target\": \"dev\",\n            }\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\"packages\": [{\"package\": \"dbt-labs/dbt_utils\", \"version\": \"1.0.0\"}]}\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": models__schema_yml,\n            \"sample_model.sql\": models__sample_model,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def snapshots(self):\n        return {\"sample_snapshot.sql\": snapshots__sample_snapshot}\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\"sample_seed.csv\": seeds__sample_seed}\n\n    @pytest.fixture(scope=\"class\")\n    def tests(self):\n        return {\n            \"failing.sql\": tests__failing_sql,\n        }\n"
  },
  {
    "path": "tests/functional/minimal_cli/test_minimal_cli.py",
    "content": "from dbt.cli.main import cli\nfrom tests.functional.minimal_cli.fixtures import BaseConfigProject\nfrom tests.functional.utils import up_one\n\n\nclass TestClean(BaseConfigProject):\n    \"\"\"Test the minimal/happy-path for the CLI using the Click CliRunner\"\"\"\n\n    def test_clean(self, runner, project):\n        result = runner.invoke(cli, [\"clean\"])\n        assert \"target\" in result.output\n        assert \"dbt_packages\" in result.output\n        assert \"logs\" in result.output\n\n\nclass TestCleanUpLevel(BaseConfigProject):\n    def test_clean_one_level_up(self, runner, project):\n        with up_one():\n            result = runner.invoke(cli, [\"clean\"])\n            assert result.exit_code == 2\n            assert \"Runtime Error\" in result.output\n            assert \"No dbt_project.yml\" in result.output\n\n\nclass TestDeps(BaseConfigProject):\n    def test_deps(self, runner, project):\n        result = runner.invoke(cli, [\"deps\"])\n        assert \"dbt-labs/dbt_utils\" in result.output\n        assert \"1.0.0\" in result.output\n\n\nclass TestLS(BaseConfigProject):\n    def test_ls(self, runner, project):\n        runner.invoke(cli, [\"deps\"])\n        ls_result = runner.invoke(cli, [\"ls\"])\n        assert \"1 seed\" in ls_result.output\n        assert \"1 model\" in ls_result.output\n        assert \"5 data tests\" in ls_result.output\n        assert \"1 snapshot\" in ls_result.output\n\n\nclass TestBuild(BaseConfigProject):\n    def test_build(self, runner, project):\n        runner.invoke(cli, [\"deps\"])\n        result = runner.invoke(cli, [\"build\"])\n        # 1 seed, 1 model, 2 data tests\n        assert \"PASS=4\" in result.output\n        # 2 data tests\n        assert \"ERROR=2\" in result.output\n        # Singular test\n        assert \"WARN=1\" in result.output\n        # 1 snapshot\n        assert \"SKIP=1\" in result.output\n\n\nclass TestBuildFailFast(BaseConfigProject):\n    def test_build(self, runner, project):\n        runner.invoke(cli, [\"deps\"])\n        result = runner.invoke(cli, [\"build\", \"--fail-fast\"])\n        # 1 seed, 1 model, 2 data tests\n        assert \"PASS=4\" in result.output\n        # 2 data tests\n        assert \"ERROR=2\" in result.output\n        # Singular test\n        assert \"WARN=1\" in result.output\n        # 1 snapshot\n        assert \"SKIP=1\" in result.output\n        # Skipping due to fail_fast is not shown when --debug is not specified.\n        assert \"Skipping due to fail_fast\" not in result.output\n\n\nclass TestBuildFailFastDebug(BaseConfigProject):\n    def test_build(self, runner, project):\n        runner.invoke(cli, [\"deps\"])\n        result = runner.invoke(cli, [\"build\", \"--fail-fast\", \"--debug\"])\n        # 1 seed, 1 model, 2 data tests\n        assert \"PASS=4\" in result.output\n        # 2 data tests\n        assert \"ERROR=2\" in result.output\n        # Singular test\n        assert \"WARN=1\" in result.output\n        # 1 snapshot\n        assert \"SKIP=1\" in result.output\n        # Skipping due to fail_fast is shown when --debug is specified.\n        assert \"Skipping due to fail_fast\" in result.output\n\n\nclass TestDocsGenerate(BaseConfigProject):\n    def test_docs_generate(self, runner, project):\n        runner.invoke(cli, [\"deps\"])\n        result = runner.invoke(cli, [\"docs\", \"generate\"])\n        assert \"Building catalog\" in result.output\n        assert \"Catalog written\" in result.output\n"
  },
  {
    "path": "tests/functional/model_config/test_freshness_config.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt\nfrom dbt_common.dataclass_schema import ValidationError\n\n# Seed data for source tables\nseeds__source_table_csv = \"\"\"id,_loaded_at\n1,2024-03-20 00:00:00\n2,2024-03-20 00:00:00\n3,2024-03-20 00:00:00\n\"\"\"\n\n\nmodels__no_freshness_sql = \"\"\"\nselect 1 as id\n\"\"\"\n\n# Scenario 2: Model freshness defined with just model freshness spec\nmodels__model_freshness_schema_yml = \"\"\"\nversion: 2\n\nsources:\n  - name: my_source\n    database: \"{{ target.database }}\"\n    schema: \"{{ target.schema }}\"\n    config:\n      freshness:\n        warn_after: {count: 24, period: hour}\n        error_after: {count: 48, period: hour}\n    loaded_at_field: _loaded_at\n    tables:\n      - name: source_table\n        identifier: source_table\n\nmodels:\n  - name: model_a\n    description: Model with no freshness defined\n  - name: model_b\n    description: Model with only model freshness defined\n    config:\n      freshness:\n        build_after:\n          count: 1\n          period: day\n          updates_on: all\n  - name: model_c\n    description: Model with only source freshness defined\n    config:\n      freshness:\n        warn_after: {count: 24, period: hour}\n        error_after: {count: 48, period: hour}\n    loaded_at_field: _loaded_at\n    tables:\n      - name: source_table\n        identifier: source_table\n\"\"\"\n\nmodels__model_freshness_sql = \"\"\"\nselect 1 as id\n\"\"\"\n\nmodels__model_freshness_sql_inline = \"\"\"\n{{ config(\n    materialized='table',\n    freshness={\n        'warn_after': {'count': 24, 'period': 'hour'}\n    }\n) }}\nselect 1 as id\n\"\"\"\n\nmodels__source_freshness_sql = \"\"\"\nselect * from {{ source('my_source', 'source_table') }}\n\"\"\"\n\nmodels__both_freshness_sql = \"\"\"\nselect * from {{ source('my_source', 'source_table') }}\n\"\"\"\n\n\nmodels__model_freshness_schema_yml_build_after_only = \"\"\"\nmodels:\n  - name: model_a\n    description: Model with only model freshness defined\n    config:\n      freshness:\n        build_after:\n          updates_on: all\n\"\"\"\n\n\nmodels__model_freshness_schema_yml_build_period_requires_count = \"\"\"\nmodels:\n  - name: model_a\n    description: Model with only model freshness defined\n    config:\n      freshness:\n        build_after:\n          period: day\n\"\"\"\n\n\nmodels__model_freshness_schema_yml_build_period_has_0_count = \"\"\"\nmodels:\n  - name: model_a\n    description: Model with only model freshness defined\n    config:\n      freshness:\n        build_after:\n          period: day\n          count: 0\n\"\"\"\n\n\nmodels__model_freshness_schema_yml_build_count_requires_period = \"\"\"\nmodels:\n  - name: model_a\n    description: Model with only model freshness defined\n    config:\n      freshness:\n        build_after:\n          count: 1\n\"\"\"\n\n\nclass TestModelFreshnessConfig:\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": models__model_freshness_schema_yml,\n            \"model_a.sql\": models__no_freshness_sql,\n            \"model_b.sql\": models__model_freshness_sql,\n            \"model_c.sql\": models__source_freshness_sql,\n            \"model_d.sql\": models__both_freshness_sql,\n            \"model_e.sql\": models__model_freshness_sql_inline,\n        }\n\n    def test_model_freshness_configs(self, project):\n        run_dbt([\"parse\"])\n        compile_results = run_dbt([\"compile\"])\n        assert len(compile_results) == 5  # All 4 models compiled successfully\n\n\nclass TestModelFreshnessConfigParseBuildAfterOnly:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": models__model_freshness_schema_yml_build_after_only,\n            \"model_a.sql\": models__no_freshness_sql,\n        }\n\n    def test_model_freshness_configs(self, project):\n        run_dbt([\"parse\"])\n\n\nclass TestModelFreshnessConfigParseBuildPeriodRequiresCount:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": models__model_freshness_schema_yml_build_period_requires_count,\n            \"model_a.sql\": models__no_freshness_sql,\n        }\n\n    def test_model_freshness_configs(self, project):\n        with pytest.raises(ValidationError) as excinfo:\n            run_dbt([\"parse\"])\n        expected_msg = (\n            \"`freshness.build_after` must have a value for `count` if a `period` is provided\"\n        )\n        assert expected_msg in str(excinfo.value)\n\n\nclass TestModelFreshnessConfigParseBuildPeriodHas0Count:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": models__model_freshness_schema_yml_build_period_has_0_count,\n            \"model_a.sql\": models__no_freshness_sql,\n        }\n\n    def test_model_freshness_configs(self, project):\n        run_dbt([\"parse\"])\n\n\nclass TestModelFreshnessConfigParseBuildCountRequiresPeriod:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": models__model_freshness_schema_yml_build_count_requires_period,\n            \"model_a.sql\": models__no_freshness_sql,\n        }\n\n    def test_model_freshness_configs(self, project):\n        with pytest.raises(ValidationError) as excinfo:\n            run_dbt([\"parse\"])\n        expected_msg = (\n            \"`freshness.build_after` must have a value for `period` if a `count` is provided\"\n        )\n        assert expected_msg in str(excinfo.value)\n"
  },
  {
    "path": "tests/functional/partial_parsing/fixtures.py",
    "content": "local_dependency__dbt_project_yml = \"\"\"\n\nname: 'local_dep'\nversion: '1.0'\nconfig-version: 2\n\nprofile: 'default'\n\nmodel-paths: [\"models\"]\nanalysis-paths: [\"analyses\"]\ntest-paths: [\"tests\"]\nseed-paths: [\"seeds\"]\nmacro-paths: [\"macros\"]\n\nrequire-dbt-version: '>=0.1.0'\n\ntarget-path: \"target\"  # directory which will store compiled SQL files\nclean-targets:         # directories to be removed by `dbt clean`\n    - \"target\"\n    - \"dbt_packages\"\n\n\nseeds:\n  quote_columns: False\n\n\"\"\"\n\nlocal_dependency__models__schema_yml = \"\"\"\nsources:\n  - name: seed_source\n    schema: \"{{ var('schema_override', target.schema) }}\"\n    tables:\n      - name: \"seed\"\n        columns:\n          - name: id\n            data_tests:\n              - unique\n\n\"\"\"\n\nlocal_dependency__models__model_to_import_sql = \"\"\"\nselect * from {{ ref('seed') }}\n\n\"\"\"\n\nlocal_dependency__macros__dep_macro_sql = \"\"\"\n{% macro some_overridden_macro() -%}\n100\n{%- endmacro %}\n\n\"\"\"\n\nlocal_dependency__seeds__seed_csv = \"\"\"id\n1\n\"\"\"\n\nempty_schema_with_version_yml = \"\"\"\n\n\"\"\"\n\nschema_sources5_yml = \"\"\"\n\nsources:\n  - name: seed_sources\n    schema: \"{{ target.schema }}\"\n    tables:\n      - name: raw_customers\n        columns:\n          - name: id\n            data_tests:\n              - not_null:\n                  severity: \"{{ 'error' if target.name == 'prod' else 'warn' }}\"\n              - unique\n          - name: first_name\n          - name: last_name\n          - name: email\n\nseeds:\n  - name: rad_customers\n    description: \"Raw customer data\"\n    columns:\n      - name: id\n        data_tests:\n          - unique\n          - not_null\n      - name: first_name\n      - name: last_name\n      - name: email\n\n\n\"\"\"\n\nmy_macro2_sql = \"\"\"\n{% macro do_something(foo2, bar2) %}\n\n    select\n        'foo' as foo2,\n        'var' as bar2\n\n{% endmacro %}\n\n\"\"\"\n\nraw_customers_csv = \"\"\"id,first_name,last_name,email\n1,Michael,Perez,mperez0@chronoengine.com\n2,Shawn,Mccoy,smccoy1@reddit.com\n3,Kathleen,Payne,kpayne2@cargocollective.com\n4,Jimmy,Cooper,jcooper3@cargocollective.com\n5,Katherine,Rice,krice4@typepad.com\n6,Sarah,Ryan,sryan5@gnu.org\n7,Martin,Mcdonald,mmcdonald6@opera.com\n8,Frank,Robinson,frobinson7@wunderground.com\n9,Jennifer,Franklin,jfranklin8@mail.ru\n10,Henry,Welch,hwelch9@list-manage.com\n\"\"\"\n\nmodel_three_disabled2_sql = \"\"\"\n- Disabled model\n{{ config(materialized='table', enabled=False) }}\n\nwith source_data as (\n\n    select 1 as id\n    union all\n    select null as id\n\n)\n\nselect *\nfrom source_data\n\n\"\"\"\n\nschema_sources4_yml = \"\"\"\n\nsources:\n  - name: seed_sources\n    schema: \"{{ target.schema }}\"\n    tables:\n      - name: raw_customers\n        columns:\n          - name: id\n            data_tests:\n              - not_null:\n                  severity: \"{{ 'error' if target.name == 'prod' else 'warn' }}\"\n              - unique\n              - every_value_is_blue\n          - name: first_name\n          - name: last_name\n          - name: email\n\nseeds:\n  - name: raw_customers\n    description: \"Raw customer data\"\n    columns:\n      - name: id\n        data_tests:\n          - unique\n          - not_null\n      - name: first_name\n      - name: last_name\n      - name: email\n\n\n\"\"\"\n\nenv_var_schema_yml = \"\"\"\n\nmodels:\n    - name: model_one\n      config:\n        materialized: \"{{ env_var('TEST_SCHEMA_VAR') }}\"\n\n\"\"\"\n\nmy_test_sql = \"\"\"\nselect\n   * from {{ ref('customers') }} where first_name = '{{ macro_something() }}'\n\n\"\"\"\n\nempty_schema_yml = \"\"\"\n\n\"\"\"\n\nschema_models_c_yml = \"\"\"\n\nsources:\n  - name: seed_source\n    description: \"This is a source override\"\n    overrides: local_dep\n    schema: \"{{ var('schema_override', target.schema) }}\"\n    tables:\n      - name: \"seed\"\n        columns:\n          - name: id\n            data_tests:\n              - unique\n              - not_null\n\n\"\"\"\n\nenv_var_sources_yml = \"\"\"\nsources:\n  - name: seed_sources\n    schema: \"{{ target.schema }}\"\n    database: \"{{ env_var('ENV_VAR_DATABASE') }}\"\n    tables:\n      - name: raw_customers\n        columns:\n          - name: id\n            data_tests:\n              - not_null:\n                  severity: \"{{ env_var('ENV_VAR_SEVERITY') }}\"\n              - unique\n          - name: first_name\n          - name: last_name\n          - name: email\n\n\n\n\"\"\"\n\ngeneric_test_edited_sql = \"\"\"\n{% test is_odd(model, column_name) %}\n\nwith validation as (\n\n    select\n        {{ column_name }} as odd_field2\n\n    from {{ model }}\n\n),\n\nvalidation_errors as (\n\n    select\n        odd_field2\n\n    from validation\n    -- if this is true, then odd_field is actually even!\n    where (odd_field2 % 2) = 0\n\n)\n\nselect *\nfrom validation_errors\n\n{% endtest %}\n\"\"\"\n\nschema_sources1_yml = \"\"\"\nsources:\n  - name: seed_sources\n    schema: \"{{ target.schema }}\"\n    tables:\n      - name: raw_customers\n        columns:\n          - name: id\n            data_tests:\n              - not_null:\n                  severity: \"{{ 'error' if target.name == 'prod' else 'warn' }}\"\n              - unique\n          - name: first_name\n          - name: last_name\n          - name: email\n\n\n\n\"\"\"\n\nschema_sources3_yml = \"\"\"\n\nsources:\n  - name: seed_sources\n    schema: \"{{ target.schema }}\"\n    tables:\n      - name: raw_customers\n        columns:\n          - name: id\n            data_tests:\n              - not_null:\n                  severity: \"{{ 'error' if target.name == 'prod' else 'warn' }}\"\n              - unique\n          - name: first_name\n          - name: last_name\n          - name: email\n\nexposures:\n  - name: proxy_for_dashboard\n    description: \"This is for the XXX dashboard\"\n    type: \"dashboard\"\n    owner:\n      name: \"Dashboard Tester\"\n      email: \"tester@dashboard.com\"\n    depends_on:\n      - ref(\"model_one\")\n      - source(\"seed_sources\", \"raw_customers\")\n\n\n\"\"\"\n\nmy_analysis_sql = \"\"\"\nselect * from customers\n\n\"\"\"\n\nschema_sources2_yml = \"\"\"\n\nsources:\n  - name: seed_sources\n    schema: \"{{ target.schema }}\"\n    tables:\n      - name: raw_customers\n        columns:\n          - name: id\n            data_tests:\n              - not_null:\n                  severity: \"{{ 'error' if target.name == 'prod' else 'warn' }}\"\n              - unique\n          - name: first_name\n          - name: last_name\n          - name: email\n\nexposures:\n  - name: proxy_for_dashboard\n    description: \"This is for the XXX dashboard\"\n    type: \"dashboard\"\n    owner:\n      name: \"Dashboard Tester\"\n      email: \"tester@dashboard.com\"\n    depends_on:\n      - ref(\"model_one\")\n      - ref(\"raw_customers\")\n      - source(\"seed_sources\", \"raw_customers\")\n\n\n\"\"\"\n\nmodel_color_sql = \"\"\"\nselect 'blue' as fun\n\n\"\"\"\n\nmy_metric_yml = \"\"\"\nmetrics:\n  - name: new_customers\n    label: New Customers\n    model: customers\n    description: \"The number of paid customers who are using the product\"\n    type: simple\n    type_params:\n      measure:\n        name: customers\n        filter: \"{{ Dimension('id__loves_dbt') }} is true\"\n    +meta:\n        is_okr: True\n    tags:\n      - okrs\n\n\n\n\"\"\"\n\nenv_var_schema2_yml = \"\"\"\n\nmodels:\n    - name: model_one\n      config:\n        materialized: \"{{ env_var('TEST_SCHEMA_VAR') }}\"\n      data_tests:\n        - check_color:\n            column_name: fun\n            color: \"env_var('ENV_VAR_COLOR')\"\n\n\n\"\"\"\n\ngsm_override_sql = \"\"\"\n- custom macro\n{% macro generate_schema_name(schema_name, node) %}\n\n    {{ schema_name }}_{{ target.schema }}\n\n{% endmacro %}\n\n\"\"\"\n\nmodel_four1_sql = \"\"\"\nselect * from {{ ref('model_three') }}\n\n\"\"\"\n\nmodel_one_sql = \"\"\"\nselect 1 as fun\n\n\"\"\"\n\nmetricflow_time_spine_sql = \"\"\"\nSELECT to_date('02/20/2023', 'mm/dd/yyyy') as date_day\n\"\"\"\n\nenv_var_schema3_yml = \"\"\"\n\nmodels:\n    - name: model_one\n      config:\n        materialized: \"{{ env_var('TEST_SCHEMA_VAR') }}\"\n      data_tests:\n        - check_color:\n            column_name: fun\n            color: \"env_var('ENV_VAR_COLOR')\"\n\nexposures:\n  - name: proxy_for_dashboard\n    description: \"This is for the XXX dashboard\"\n    type: \"dashboard\"\n    owner:\n      name: \"{{ env_var('ENV_VAR_OWNER') }}\"\n      email: \"tester@dashboard.com\"\n    depends_on:\n      - ref(\"model_color\")\n      - source(\"seed_sources\", \"raw_customers\")\n\n\"\"\"\n\npeople_semantic_models_yml = \"\"\"\nversion: 2\n\nsemantic_models:\n  - name: semantic_people\n    model: ref('people')\n    dimensions:\n      - name: favorite_color\n        type: categorical\n      - name: created_at\n        type: TIME\n        type_params:\n          time_granularity: day\n    measures:\n      - name: years_tenure\n        agg: SUM\n        expr: tenure\n      - name: people\n        agg: count\n        expr: id\n    entities:\n      - name: id\n        type: primary\n    defaults:\n      agg_time_dimension: created_at\n\"\"\"\n\npeople_sl_yml = \"\"\"\nversion: 2\n\nsemantic_models:\n  - name: semantic_people\n    model: ref('people')\n    dimensions:\n      - name: favorite_color\n        type: categorical\n      - name: created_at\n        type: TIME\n        type_params:\n          time_granularity: day\n    measures:\n      - name: years_tenure\n        agg: SUM\n        expr: tenure\n      - name: people\n        agg: count\n        expr: id\n    entities:\n      - name: id\n        type: primary\n    defaults:\n      agg_time_dimension: created_at\n\nmetrics:\n\n  - name: number_of_people\n    description: Total count of people\n    label: \"Number of people\"\n    type: simple\n    type_params:\n      measure: people\n    meta:\n        my_meta: 'testing'\n\n  - name: collective_tenure\n    description: Total number of years of team experience\n    label: \"Collective tenure\"\n    type: simple\n    type_params:\n      measure:\n        name: years_tenure\n        filter: \"{{ Dimension('id__loves_dbt') }} is true\"\n\n  - name: average_tenure\n    label: Average Tenure\n    type: ratio\n    type_params:\n      numerator: collective_tenure\n      denominator: number_of_people\n\"\"\"\n\nenv_var_metrics_yml = \"\"\"\n\nmetrics:\n\n  - name: number_of_people\n    description: Total count of people\n    label: \"Number of people\"\n    type: simple\n    type_params:\n      measure: people\n    meta:\n        my_meta: '{{ env_var(\"ENV_VAR_METRICS\") }}'\n\n  - name: collective_tenure\n    description: Total number of years of team experience\n    label: \"Collective tenure\"\n    type: simple\n    type_params:\n      measure:\n        name: years_tenure\n        filter: \"{{ Dimension('id__loves_dbt') }} is true\"\n\n\"\"\"\n\ncustomers_sql = \"\"\"\nwith source as (\n\n    select * from {{ source('seed_sources', 'raw_customers') }}\n\n),\n\nrenamed as (\n\n    select\n        id as customer_id,\n        first_name,\n        last_name,\n        email\n\n    from source\n\n)\n\nselect * from renamed\n\n\"\"\"\n\ncustomers_yml = \"\"\"\nmodels:\n  - name: customers\n    description: \"This table contains customer data\"\n\"\"\"\n\nmodel_four2_sql = \"\"\"\nselect fun from {{ ref('model_one') }}\n\n\"\"\"\n\nenv_var_model_sql = \"\"\"\nselect '{{ env_var('ENV_VAR_TEST') }}' as vartest\n\n\"\"\"\n\nenv_var_model_one_sql = \"\"\"\nselect 'blue' as fun\n\n\"\"\"\n\ncustom_schema_tests2_sql = \"\"\"\n{% test type_one(model) %}\n\n    select * from (\n\n        select * from {{ model }}\n        union all\n        select * from {{ ref('model_b') }}\n\n    ) as Foo\n\n{% endtest %}\n\n{% test type_two(model) %}\n\n    {{ config(severity = \"ERROR\") }}\n\n    select * from {{ model }}\n\n{% endtest %}\n\n\"\"\"\n\nmetric_model_a_sql = \"\"\"\n{%\n    set metric_list = [\n        metric('number_of_people'),\n        metric('collective_tenure')\n    ]\n%}\n\n{% if not execute %}\n\n    {% set metric_names = [] %}\n    {% for m in metric_list %}\n        {% do metric_names.append(m.metric_name) %}\n    {% endfor %}\n\n    -- this config does nothing, but it lets us check these values\n    {{ config(metric_names = metric_names) }}\n\n{% endif %}\n\n\nselect 1 as fun\n\n\"\"\"\n\nmodel_b_sql = \"\"\"\nselect 1 as notfun\n\n\"\"\"\n\ncustomers2_md = \"\"\"\n{% docs customer_table %}\n\nLOTS of customer data\n\n{% enddocs %}\n\n\"\"\"\n\ncustom_schema_tests1_sql = \"\"\"\n{% test type_one(model) %}\n\n    select * from (\n\n        select * from {{ model }}\n        union all\n        select * from {{ ref('model_b') }}\n\n    ) as Foo\n\n{% endtest %}\n\n{% test type_two(model) %}\n\n    {{ config(severity = \"WARN\") }}\n\n    select * from {{ model }}\n\n{% endtest %}\n\n\"\"\"\n\npeople_metrics_yml = \"\"\"\n\nmetrics:\n\n  - name: number_of_people\n    description: Total count of people\n    label: \"Number of people\"\n    type: simple\n    type_params:\n      measure: people\n    meta:\n        my_meta: 'testing'\n\n  - name: collective_tenure\n    description: Total number of years of team experience\n    label: \"Collective tenure\"\n    type: simple\n    type_params:\n      measure:\n        name: years_tenure\n        filter: \"{{ Dimension('id__loves_dbt') }} is true\"\n\n\"\"\"\n\npeople_sql = \"\"\"\nselect 1 as id, 'Drew' as first_name, 'Banin' as last_name, 'yellow' as favorite_color, true as loves_dbt, 5 as tenure, current_timestamp as created_at\nunion all\nselect 1 as id, 'Jeremy' as first_name, 'Cohen' as last_name, 'indigo' as favorite_color, true as loves_dbt, 4 as tenure, current_timestamp as created_at\n\n\"\"\"\n\norders_sql = \"\"\"\nselect 1 as id, 101 as user_id, 'pending' as status\n\n\"\"\"\n\norders_sql_modified = \"\"\"\nselect 1 as id, 101 as user_id, 'completed' as status\n\n\"\"\"\n\norders_singular_test_sql = \"\"\"\nselect * from {{ ref('orders') }}\nwhere status = 'invalid'\n\n\"\"\"\n\norders_downstream_sql = \"\"\"\nselect * from {{ ref('orders') }}\n\n\"\"\"\n\nmodel_a_sql = \"\"\"\nselect 1 as fun\n\n\"\"\"\n\nmodel_three_disabled_sql = \"\"\"\n{{ config(materialized='table', enabled=False) }}\n\nwith source_data as (\n\n    select 1 as id\n    union all\n    select null as id\n\n)\n\nselect *\nfrom source_data\n\n\"\"\"\n\nmodels_schema2b_yml = \"\"\"\n\nmodels:\n    - name: model_one\n      description: \"The first model\"\n    - name: model_three\n      description: \"The third model\"\n      columns:\n        - name: id\n          data_tests:\n            - not_null\n\n\"\"\"\n\nenv_var_macros_yml = \"\"\"\nmacros:\n    - name: do_something\n      description: \"This is a test macro\"\n      meta:\n          some_key: \"{{ env_var('ENV_VAR_SOME_KEY') }}\"\n\n\n\"\"\"\n\nmodels_schema4_yml = \"\"\"\n\nmodels:\n    - name: model_one\n      description: \"The first model\"\n    - name: model_three\n      description: \"The third model\"\n      config:\n        enabled: false\n      columns:\n        - name: id\n          data_tests:\n            - unique\n\n\"\"\"\n\nmodel_two_sql = \"\"\"\nselect 1 as notfun\n\n\"\"\"\n\nmodel_two_sql_missing_space = \"\"\"\nselect1asnotfun\n\"\"\"\n\nmodel_two_sql_extra_whitespace = \"\"\"\nselect 1        as notfun\n\n\"\"\"\n\nmodel_two_disabled_sql = \"\"\"\n{{ config(\n  enabled=false\n) }}\n\nselect 1 as notfun\n\"\"\"\n\ngeneric_test_schema_yml = \"\"\"\n\nmodels:\n  - name: orders\n    description: \"Some order data\"\n    columns:\n      - name: id\n        data_tests:\n          - unique\n          - is_odd\n\n\"\"\"\n\ncustomers1_md = \"\"\"\n{% docs customer_table %}\n\nThis table contains customer data\n\n{% enddocs %}\n\n\"\"\"\n\nmodel_three_modified_sql = \"\"\"\n{{ config(materialized='table') }}\n\nwith source_data as (\n\n    {#- This is model three #}\n\n    select 1 as id\n    union all\n    select null as id\n\n)\n\nselect *\nfrom source_data\n\n\"\"\"\n\nmacros_yml = \"\"\"\nmacros:\n    - name: do_something\n      description: \"This is a test macro\"\n\n\"\"\"\n\ntest_color_sql = \"\"\"\n{% test check_color(model, column_name, color) %}\n\n    select *\n    from {{ model }}\n    where {{ column_name }} = '{{ color }}'\n\n{% endtest %}\n\n\"\"\"\n\nmodels_schema2_yml = \"\"\"\n\nmodels:\n    - name: model_one\n      description: \"The first model\"\n    - name: model_three\n      description: \"The third model\"\n      columns:\n        - name: id\n          data_tests:\n            - unique\n\n\"\"\"\n\ngsm_override2_sql = \"\"\"\n- custom macro xxxx\n{% macro generate_schema_name(schema_name, node) %}\n\n    {{ schema_name }}_{{ target.schema }}\n\n{% endmacro %}\n\n\"\"\"\n\nmodels_schema3_yml = \"\"\"\n\nmodels:\n    - name: model_one\n      description: \"The first model\"\n    - name: model_three\n      description: \"The third model\"\n      data_tests:\n          - unique\nmacros:\n    - name: do_something\n      description: \"This is a test macro\"\n\n\"\"\"\n\ngeneric_test_sql = \"\"\"\n{% test is_odd(model, column_name) %}\n\nwith validation as (\n\n    select\n        {{ column_name }} as odd_field\n\n    from {{ model }}\n\n),\n\nvalidation_errors as (\n\n    select\n        odd_field\n\n    from validation\n    -- if this is true, then odd_field is actually even!\n    where (odd_field % 2) = 0\n\n)\n\nselect *\nfrom validation_errors\n\n{% endtest %}\n\"\"\"\n\nenv_var_model_test_yml = \"\"\"\nmodels:\n  - name: model_color\n    columns:\n      - name: fun\n        data_tests:\n          - unique:\n              enabled: \"{{ env_var('ENV_VAR_ENABLED', True) }}\"\n\n\"\"\"\n\nmodel_three_sql = \"\"\"\n{{ config(materialized='table') }}\n\nwith source_data as (\n\n    select 1 as id\n    union all\n    select null as id\n\n)\n\nselect *\nfrom source_data\n\n\"\"\"\n\nref_override2_sql = \"\"\"\n- Macro to override ref xxxx\n{% macro ref(modelname) %}\n{% do return(builtins.ref(modelname)) %}\n{% endmacro %}\n\n\"\"\"\n\nmodels_schema1_yml = \"\"\"\n\nmodels:\n    - name: model_one\n      description: \"The first model\"\n\n\"\"\"\n\nmacros_schema_yml = \"\"\"\n\n\nmodels:\n    - name: model_a\n      data_tests:\n        - type_one\n        - type_two\n\n\"\"\"\n\nmodels_versions_schema_yml = \"\"\"\n\nmodels:\n    - name: model_one\n      description: \"The first model\"\n      versions:\n        - v: 1\n        - v: 2\n\"\"\"\n\nmodels_versions_defined_in_schema_yml = \"\"\"\n\nmodels:\n    - name: model_one\n      description: \"The first model\"\n      versions:\n        - v: 1\n        - v: 2\n          defined_in: model_one_different\n\"\"\"\n\nmodels_versions_updated_schema_yml = \"\"\"\n\nmodels:\n    - name: model_one\n      latest_version: 1\n      description: \"The first model\"\n      versions:\n        - v: 1\n        - v: 2\n          defined_in: model_one_different\n\"\"\"\n\nmy_macro_sql = \"\"\"\n{% macro do_something(foo2, bar2) %}\n\n    select\n        '{{ foo2 }}' as foo2,\n        '{{ bar2 }}' as bar2\n\n{% endmacro %}\n\n\"\"\"\n\nsnapshot_sql = \"\"\"\n{% snapshot orders_snapshot %}\n\n{{\n    config(\n      target_schema=schema,\n      strategy='check',\n      unique_key='id',\n      check_cols=['status'],\n    )\n}}\n\nselect * from {{ ref('orders') }}\n\n{% endsnapshot %}\n\n{% snapshot orders2_snapshot %}\n\n{{\n    config(\n      target_schema=schema,\n      strategy='check',\n      unique_key='id',\n      check_cols=['order_date'],\n    )\n}}\n\nselect * from {{ ref('orders') }}\n\n{% endsnapshot %}\n\n\"\"\"\n\nmodels_schema4b_yml = \"\"\"\n\nmodels:\n    - name: model_one\n      description: \"The first model\"\n    - name: model_three\n      description: \"The third model\"\n      config:\n        enabled: true\n      columns:\n        - name: id\n          data_tests:\n            - unique\n\n\"\"\"\n\ntest_macro_sql = \"\"\"\n{% macro macro_something() %}\n\n    {% do return('macro_something') %}\n\n{% endmacro %}\n\n\"\"\"\n\npeople_metrics2_yml = \"\"\"\n\nmetrics:\n\n  - name: number_of_people\n    description: Total count of people\n    label: \"Number of people\"\n    type: simple\n    type_params:\n      measure: people\n    meta:\n        my_meta: 'replaced'\n\n  - name: collective_tenure\n    description: Total number of years of team experience\n    label: \"Collective tenure\"\n    type: simple\n    type_params:\n      measure:\n        name: years_tenure\n        filter: \"{{ Dimension('id__loves_dbt') }} is true\"\n\n\"\"\"\n\ngeneric_schema_yml = \"\"\"\n\nmodels:\n  - name: orders\n    description: \"Some order data\"\n    columns:\n      - name: id\n        data_tests:\n          - unique\n\n\"\"\"\n\n\ngroups_schema_yml_one_group = \"\"\"\n\ngroups:\n  - name: test_group\n    owner:\n      name: test_group_owner\n\nmodels:\n  - name: orders\n    description: \"Some order data\"\n\"\"\"\n\n\ngroups_schema_yml_two_groups = \"\"\"\n\ngroups:\n  - name: test_group\n    owner:\n      name: test_group_owner\n  - name: test_group2\n    owner:\n      name: test_group_owner2\n\nmodels:\n  - name: orders\n    description: \"Some order data\"\n\"\"\"\n\n\ngroups_schema_yml_two_groups_private_orders_valid_access = \"\"\"\n\ngroups:\n  - name: test_group\n    owner:\n      name: test_group_owner\n  - name: test_group2\n    owner:\n      name: test_group_owner2\n\nmodels:\n  - name: orders\n    group: test_group\n    access: private\n    description: \"Some order data\"\n  - name: orders_downstream\n    group: test_group\n    description: \"Some order data\"\n\"\"\"\n\ngroups_schema_yml_two_groups_private_orders_invalid_access = \"\"\"\n\ngroups:\n  - name: test_group\n    owner:\n      name: test_group_owner\n  - name: test_group2\n    owner:\n      name: test_group_owner2\n\nmodels:\n  - name: orders\n    group: test_group2\n    access: private\n    description: \"Some order data\"\n  - name: orders_downstream\n    group: test_group\n    description: \"Some order data\"\n\"\"\"\n\ngroups_schema_yml_one_group_model_in_group2 = \"\"\"\n\ngroups:\n  - name: test_group\n    owner:\n      name: test_group_owner\n\nmodels:\n  - name: orders\n    description: \"Some order data\"\n    config:\n      group: test_group2\n\"\"\"\n\ngroups_schema_yml_two_groups_edited = \"\"\"\n\ngroups:\n  - name: test_group\n    owner:\n      name: test_group_owner\n  - name: test_group2_edited\n    owner:\n      name: test_group_owner2\n\nmodels:\n  - name: orders\n    description: \"Some order data\"\n\"\"\"\n\n\nsnapshot2_sql = \"\"\"\n- add a comment\n{% snapshot orders_snapshot %}\n\n{{\n    config(\n      target_schema=schema,\n      strategy='check',\n      unique_key='id',\n      check_cols=['status'],\n    )\n}}\n\nselect * from {{ ref('orders') }}\n\n{% endsnapshot %}\n\n{% snapshot orders2_snapshot %}\n\n{{\n    config(\n      target_schema=schema,\n      strategy='check',\n      unique_key='id',\n      check_cols=['order_date'],\n    )\n}}\n\nselect * from {{ ref('orders') }}\n\n{% endsnapshot %}\n\n\"\"\"\n\nsources_tests2_sql = \"\"\"\n\n{% test every_value_is_blue(model, column_name) %}\n\n    select *\n    from {{ model }}\n    where {{ column_name }} != 99\n\n{% endtest %}\n\n\n\"\"\"\n\npeople_metrics3_yml = \"\"\"\n\nmetrics:\n\n  - name: number_of_people\n    description: Total count of people\n    label: \"Number of people\"\n    type: simple\n    type_params:\n      measure: people\n    meta:\n        my_meta: 'replaced'\n\n\"\"\"\n\nref_override_sql = \"\"\"\n- Macro to override ref\n{% macro ref(modelname) %}\n{% do return(builtins.ref(modelname)) %}\n{% endmacro %}\n\n\"\"\"\n\ntest_macro2_sql = \"\"\"\n{% macro macro_something() %}\n\n    {% do return('some_name') %}\n\n{% endmacro %}\n\n\"\"\"\n\nenv_var_macro_sql = \"\"\"\n{% macro do_something(foo2, bar2) %}\n\n    select\n        '{{ foo2 }}' as foo2,\n        '{{ bar2 }}' as bar2\n\n{% endmacro %}\n\n\"\"\"\n\nsources_tests1_sql = \"\"\"\n\n{% test every_value_is_blue(model, column_name) %}\n\n    select *\n    from {{ model }}\n    where {{ column_name }} = 9999\n\n{% endtest %}\n\n\n\"\"\"\n\nmacros_sql = \"\"\"\n{% macro foo() %}\n    foo\n{% endmacro %}\n\n{% macro bar() %}\n    bar\n{% endmacro %}\n\"\"\"\n\nmacros_schema1_yml = \"\"\"\nmacros:\n  - name: foo\n    description: Lorem.\n  - name: bar\n    description: Lorem.\n\"\"\"\n\nmacros_schema2_yml = \"\"\"\nmacros:\n  - name: foo\n    description: Lorem.\n  - name: bar\n    description: Lorem ipsum.\n\"\"\"\n\nmy_func_sql = \"\"\"\nvalue * 2\n\"\"\"\n\nmy_func_yml = \"\"\"\nfunctions:\n  - name: my_func\n    description: \"Doubles an integer\"\n    arguments:\n      - name: value\n        data_type: int\n        description: \"An integer to be doubled\"\n    returns:\n      data_type: int\n\"\"\"\n\nupdated_my_func_sql = \"\"\"\nnumber * 2.0\n\"\"\"\n\nupdated_my_func_yml = \"\"\"\nfunctions:\n  - name: my_func\n    description: \"Doubles a float\"\n    arguments:\n      - name: number\n        data_type: float\n        description: \"A float to be doubled\"\n    returns:\n      data_type: float\n\"\"\"\n\nmodel_using_function_sql = \"\"\"\nSELECT {{ function('my_func') }}(1) as result\n\"\"\"\n"
  },
  {
    "path": "tests/functional/partial_parsing/test_file_diff.py",
    "content": "import os\n\nimport pytest\n\nfrom dbt.tests.util import run_dbt, write_artifact, write_file\nfrom tests.functional.partial_parsing.fixtures import model_one_sql, model_two_sql\n\nfirst_file_diff = {\n    \"deleted\": [],\n    \"changed\": [],\n    \"added\": [{\"path\": \"models/model_one.sql\", \"content\": \"select 1 as fun\"}],\n}\n\n\nsecond_file_diff = {\n    \"deleted\": [],\n    \"changed\": [],\n    \"added\": [{\"path\": \"models/model_two.sql\", \"content\": \"select 123 as notfun\"}],\n}\n\n\nclass TestFileDiffPaths:\n    def test_file_diffs(self, project):\n\n        os.environ[\"DBT_PP_FILE_DIFF_TEST\"] = \"true\"\n\n        run_dbt([\"deps\"])\n        run_dbt([\"seed\"])\n\n        # We start with an empty project\n        results = run_dbt()\n\n        write_artifact(first_file_diff, \"file_diff.json\")\n        results = run_dbt()\n        assert len(results) == 1\n\n        write_artifact(second_file_diff, \"file_diff.json\")\n        results = run_dbt()\n        assert len(results) == 2\n\n\nclass TestFileDiffs:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_one.sql\": model_one_sql,\n        }\n\n    def test_no_file_diffs(self, project):\n        # We start with a project with one model\n        manifest = run_dbt([\"parse\"])\n        assert len(manifest.nodes) == 1\n\n        # add a model file\n        write_file(model_two_sql, project.project_root, \"models\", \"model_two.sql\")\n\n        # parse without computing a file diff\n        manifest = run_dbt([\"--partial-parse\", \"--no-partial-parse-file-diff\", \"parse\"])\n        assert len(manifest.nodes) == 1\n\n        # default behaviour - parse with computing a file diff\n        manifest = run_dbt([\"--partial-parse\", \"parse\"])\n        assert len(manifest.nodes) == 2\n"
  },
  {
    "path": "tests/functional/partial_parsing/test_partial_parsing.py",
    "content": "import os\nimport re\nfrom argparse import Namespace\nfrom unittest import mock\n\nimport pytest\nimport yaml\n\nimport dbt.flags as flags\nfrom dbt.contracts.files import ParseFileType\nfrom dbt.contracts.results import TestStatus\nfrom dbt.events.types import UnableToPartialParse\nfrom dbt.exceptions import CompilationError\nfrom dbt.plugins.manifest import ModelNodeArgs, PluginNodes\nfrom dbt.tests.fixtures.project import write_project_files\nfrom dbt.tests.util import (\n    get_manifest,\n    rename_dir,\n    rm_file,\n    run_dbt,\n    run_dbt_and_capture,\n    write_file,\n)\nfrom dbt_common.events.event_catcher import EventCatcher\nfrom tests.functional.partial_parsing.fixtures import (\n    custom_schema_tests1_sql,\n    custom_schema_tests2_sql,\n    customers1_md,\n    customers2_md,\n    customers_sql,\n    empty_schema_with_version_yml,\n    empty_schema_yml,\n    generic_schema_yml,\n    generic_test_edited_sql,\n    generic_test_schema_yml,\n    generic_test_sql,\n    gsm_override2_sql,\n    gsm_override_sql,\n    local_dependency__dbt_project_yml,\n    local_dependency__macros__dep_macro_sql,\n    local_dependency__models__model_to_import_sql,\n    local_dependency__models__schema_yml,\n    local_dependency__seeds__seed_csv,\n    macros_schema1_yml,\n    macros_schema2_yml,\n    macros_schema_yml,\n    macros_sql,\n    macros_yml,\n    model_a_sql,\n    model_b_sql,\n    model_four1_sql,\n    model_four2_sql,\n    model_one_sql,\n    model_three_disabled2_sql,\n    model_three_disabled_sql,\n    model_three_modified_sql,\n    model_three_sql,\n    model_two_disabled_sql,\n    model_two_sql,\n    model_two_sql_extra_whitespace,\n    model_two_sql_missing_space,\n    models_schema1_yml,\n    models_schema2_yml,\n    models_schema2b_yml,\n    models_schema3_yml,\n    models_schema4_yml,\n    models_schema4b_yml,\n    my_analysis_sql,\n    my_macro2_sql,\n    my_macro_sql,\n    my_test_sql,\n    orders_singular_test_sql,\n    orders_sql,\n    orders_sql_modified,\n    raw_customers_csv,\n    ref_override2_sql,\n    ref_override_sql,\n    schema_models_c_yml,\n    schema_sources1_yml,\n    schema_sources2_yml,\n    schema_sources3_yml,\n    schema_sources4_yml,\n    schema_sources5_yml,\n    snapshot2_sql,\n    snapshot_sql,\n    sources_tests1_sql,\n    sources_tests2_sql,\n    test_macro2_sql,\n    test_macro_sql,\n)\nfrom tests.functional.utils import up_one\n\nos.environ[\"DBT_PP_TEST\"] = \"true\"\n\n\ndef normalize(path):\n    return os.path.normcase(os.path.normpath(path))\n\n\nclass TestModels:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_one.sql\": model_one_sql,\n        }\n\n    def test_pp_models(self, project):\n        # initial run\n        # run_dbt(['clean'])\n        results = run_dbt([\"run\"])\n        assert len(results) == 1\n\n        # add a model file with missing space\n        write_file(model_two_sql_missing_space, project.project_root, \"models\", \"model_two.sql\")\n        run_dbt([\"--partial-parse\", \"run\"], expect_pass=False)\n\n        # update model file - fix missing space issue\n        write_file(model_two_sql, project.project_root, \"models\", \"model_two.sql\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 2\n\n        # update model file - add additional spaces, should not change prior checksum\n        manifest = get_manifest(project.project_root)\n        model_two_checksum = manifest.nodes[\"model.test.model_two\"].checksum\n        write_file(model_two_sql_extra_whitespace, project.project_root, \"models\", \"model_two.sql\")\n        manifest = run_dbt([\"--partial-parse\", \"parse\"])\n        assert manifest.nodes[\"model.test.model_two\"].checksum == model_two_checksum\n\n        # add a schema file\n        write_file(models_schema1_yml, project.project_root, \"models\", \"schema.yml\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 2\n        manifest = get_manifest(project.project_root)\n        assert \"model.test.model_one\" in manifest.nodes\n        model_one_node = manifest.nodes[\"model.test.model_one\"]\n        assert model_one_node.description == \"The first model\"\n        assert model_one_node.patch_path == \"test://\" + normalize(\"models/schema.yml\")\n\n        # add a model and a schema file (with a test) at the same time\n        write_file(models_schema2_yml, project.project_root, \"models\", \"schema.yml\")\n        write_file(model_three_sql, project.project_root, \"models\", \"model_three.sql\")\n        results = run_dbt([\"--partial-parse\", \"test\"], expect_pass=False)\n        assert len(results) == 1\n        manifest = get_manifest(project.project_root)\n        project_files = [f for f in manifest.files if f.startswith(\"test://\")]\n        assert len(project_files) == 4\n        model_3_file_id = \"test://\" + normalize(\"models/model_three.sql\")\n        assert model_3_file_id in manifest.files\n        model_three_file = manifest.files[model_3_file_id]\n        assert model_three_file.parse_file_type == ParseFileType.Model\n        assert type(model_three_file).__name__ == \"SourceFile\"\n        model_three_node = manifest.nodes[model_three_file.nodes[0]]\n        schema_file_id = \"test://\" + normalize(\"models/schema.yml\")\n        assert model_three_node.patch_path == schema_file_id\n        assert model_three_node.description == \"The third model\"\n        schema_file = manifest.files[schema_file_id]\n        assert type(schema_file).__name__ == \"SchemaSourceFile\"\n        assert len(schema_file.data_tests) == 1\n        tests = schema_file.get_all_test_ids()\n        assert tests == [\"test.test.unique_model_three_id.6776ac8160\"]\n        unique_test_id = tests[0]\n        assert unique_test_id in manifest.nodes\n\n        # modify model sql file, ensure description still there\n        write_file(model_three_modified_sql, project.project_root, \"models\", \"model_three.sql\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        manifest = get_manifest(project.project_root)\n        model_id = \"model.test.model_three\"\n        assert model_id in manifest.nodes\n        model_three_node = manifest.nodes[model_id]\n        assert model_three_node.description == \"The third model\"\n\n        # Change the model 3 test from unique to not_null\n        write_file(models_schema2b_yml, project.project_root, \"models\", \"schema.yml\")\n        results = run_dbt([\"--partial-parse\", \"test\"], expect_pass=False)\n        manifest = get_manifest(project.project_root)\n        schema_file_id = \"test://\" + normalize(\"models/schema.yml\")\n        schema_file = manifest.files[schema_file_id]\n        tests = schema_file.get_all_test_ids()\n        assert tests == [\"test.test.not_null_model_three_id.3162ce0a6f\"]\n        not_null_test_id = tests[0]\n        assert not_null_test_id in manifest.nodes.keys()\n        assert unique_test_id not in manifest.nodes.keys()\n        assert len(results) == 1\n\n        # go back to previous version of schema file, removing patch, test, and model for model three\n        write_file(models_schema1_yml, project.project_root, \"models\", \"schema.yml\")\n        rm_file(project.project_root, \"models\", \"model_three.sql\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 2\n\n        # remove schema file, still have 3 models\n        write_file(model_three_sql, project.project_root, \"models\", \"model_three.sql\")\n        rm_file(project.project_root, \"models\", \"schema.yml\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 3\n        manifest = get_manifest(project.project_root)\n        schema_file_id = \"test://\" + normalize(\"models/schema.yml\")\n        assert schema_file_id not in manifest.files\n        project_files = [f for f in manifest.files if f.startswith(\"test://\")]\n        assert len(project_files) == 3\n\n        # Put schema file back and remove a model\n        # referred to in schema file\n        write_file(models_schema2_yml, project.project_root, \"models\", \"schema.yml\")\n        rm_file(project.project_root, \"models\", \"model_three.sql\")\n        with pytest.raises(CompilationError):\n            results = run_dbt([\"--partial-parse\", \"--warn-error\", \"run\"])\n\n        # Put model back again\n        write_file(model_three_sql, project.project_root, \"models\", \"model_three.sql\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 3\n\n        # Add model four refing model three\n        write_file(model_four1_sql, project.project_root, \"models\", \"model_four.sql\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 4\n\n        # Remove model_three and change model_four to ref model_one\n        # and change schema file to remove model_three\n        rm_file(project.project_root, \"models\", \"model_three.sql\")\n        write_file(model_four2_sql, project.project_root, \"models\", \"model_four.sql\")\n        write_file(models_schema1_yml, project.project_root, \"models\", \"schema.yml\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 3\n\n        # Remove model four, put back model three, put back schema file\n        write_file(model_three_sql, project.project_root, \"models\", \"model_three.sql\")\n        write_file(models_schema2_yml, project.project_root, \"models\", \"schema.yml\")\n        rm_file(project.project_root, \"models\", \"model_four.sql\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 3\n\n        # disable model three in the schema file\n        write_file(models_schema4_yml, project.project_root, \"models\", \"schema.yml\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 2\n\n        # update enabled config to be true for model three in the schema file\n        write_file(models_schema4b_yml, project.project_root, \"models\", \"schema.yml\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 3\n\n        # disable model three in the schema file again\n        write_file(models_schema4_yml, project.project_root, \"models\", \"schema.yml\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 2\n\n        # remove disabled config for model three in the schema file to check it gets enabled\n        write_file(models_schema4b_yml, project.project_root, \"models\", \"schema.yml\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 3\n\n        # Add a macro\n        write_file(my_macro_sql, project.project_root, \"macros\", \"my_macro.sql\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 3\n        manifest = get_manifest(project.project_root)\n        macro_id = \"macro.test.do_something\"\n        assert macro_id in manifest.macros\n\n        # Modify the macro\n        write_file(my_macro2_sql, project.project_root, \"macros\", \"my_macro.sql\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 3\n\n        # Add a macro patch\n        write_file(models_schema3_yml, project.project_root, \"models\", \"schema.yml\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 3\n\n        # Remove the macro\n        rm_file(project.project_root, \"macros\", \"my_macro.sql\")\n        with pytest.raises(CompilationError):\n            results = run_dbt([\"--partial-parse\", \"--warn-error\", \"run\"])\n\n        # put back macro file, go back to schema file with no macro\n        # add separate macro patch schema file\n        write_file(models_schema2_yml, project.project_root, \"models\", \"schema.yml\")\n        write_file(my_macro_sql, project.project_root, \"macros\", \"my_macro.sql\")\n        write_file(macros_yml, project.project_root, \"macros\", \"macros.yml\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n\n        # add macro file with two macros and schema file with patches for both\n        write_file(macros_schema1_yml, project.project_root, \"macros\", \"macros_x.yml\")\n        write_file(macros_sql, project.project_root, \"macros\", \"macros_x.sql\")\n        results = run_dbt([\"--partial-parse\", \"parse\"])\n\n        # modify one of the patches\n        write_file(macros_schema2_yml, project.project_root, \"macros\", \"macros_x.yml\")\n        results = run_dbt([\"--partial-parse\", \"parse\"])\n        rm_file(project.project_root, \"macros\", \"macros_x.sql\")\n        rm_file(project.project_root, \"macros\", \"macros_x.yml\")\n\n        # delete macro and schema file\n        rm_file(project.project_root, \"macros\", \"my_macro.sql\")\n        rm_file(project.project_root, \"macros\", \"macros.yml\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 3\n\n        # Add an empty schema file\n        write_file(empty_schema_yml, project.project_root, \"models\", \"eschema.yml\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 3\n\n        # Add version to empty schema file\n        write_file(empty_schema_with_version_yml, project.project_root, \"models\", \"eschema.yml\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 3\n\n        # Disable model_three\n        write_file(model_three_disabled_sql, project.project_root, \"models\", \"model_three.sql\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 2\n        manifest = get_manifest(project.project_root)\n        model_id = \"model.test.model_three\"\n        assert model_id in manifest.disabled\n        assert model_id not in manifest.nodes\n\n        # Edit disabled model three\n        write_file(model_three_disabled2_sql, project.project_root, \"models\", \"model_three.sql\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 2\n        manifest = get_manifest(project.project_root)\n        model_id = \"model.test.model_three\"\n        assert model_id in manifest.disabled\n        assert model_id not in manifest.nodes\n\n        # Remove disabled from model three\n        write_file(model_three_sql, project.project_root, \"models\", \"model_three.sql\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 3\n        manifest = get_manifest(project.project_root)\n        model_id = \"model.test.model_three\"\n        assert model_id in manifest.nodes\n        assert model_id not in manifest.disabled\n\n\nclass TestSources:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_one.sql\": model_one_sql,\n        }\n\n    def test_pp_sources(self, project):\n        # initial run\n        write_file(raw_customers_csv, project.project_root, \"seeds\", \"raw_customers.csv\")\n        write_file(sources_tests1_sql, project.project_root, \"macros\", \"tests.sql\")\n        results = run_dbt([\"run\"])\n        assert len(results) == 1\n\n        # Partial parse running 'seed'\n        run_dbt([\"--partial-parse\", \"seed\"])\n        manifest = get_manifest(project.project_root)\n        seed_file_id = \"test://\" + normalize(\"seeds/raw_customers.csv\")\n        assert seed_file_id in manifest.files\n\n        # Add another seed file\n        write_file(raw_customers_csv, project.project_root, \"seeds\", \"more_customers.csv\")\n        run_dbt([\"--partial-parse\", \"run\"])\n        seed_file_id = \"test://\" + normalize(\"seeds/more_customers.csv\")\n        manifest = get_manifest(project.project_root)\n        assert seed_file_id in manifest.files\n        seed_id = \"seed.test.more_customers\"\n        assert seed_id in manifest.nodes\n\n        # Remove seed file and add a schema files with a source referring to raw_customers\n        rm_file(project.project_root, \"seeds\", \"more_customers.csv\")\n        write_file(schema_sources1_yml, project.project_root, \"models\", \"sources.yml\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        manifest = get_manifest(project.project_root)\n        assert len(manifest.sources) == 1\n        file_id = \"test://\" + normalize(\"models/sources.yml\")\n        assert file_id in manifest.files\n\n        # add a model referring to raw_customers source\n        write_file(customers_sql, project.project_root, \"models\", \"customers.sql\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 2\n\n        # remove sources schema file\n        rm_file(project.project_root, \"models\", \"sources.yml\")\n        with pytest.raises(CompilationError):\n            results = run_dbt([\"--partial-parse\", \"run\"])\n\n        # put back sources and add an exposures file\n        write_file(schema_sources2_yml, project.project_root, \"models\", \"sources.yml\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n\n        # remove seed referenced in exposures file\n        rm_file(project.project_root, \"seeds\", \"raw_customers.csv\")\n        with pytest.raises(CompilationError):\n            results = run_dbt([\"--partial-parse\", \"run\"])\n\n        # put back seed and remove depends_on from exposure\n        write_file(raw_customers_csv, project.project_root, \"seeds\", \"raw_customers.csv\")\n        write_file(schema_sources3_yml, project.project_root, \"models\", \"sources.yml\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n\n        # Add seed config with test to schema.yml, remove exposure\n        write_file(schema_sources4_yml, project.project_root, \"models\", \"sources.yml\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n\n        # Change seed name to wrong name\n        write_file(schema_sources5_yml, project.project_root, \"models\", \"sources.yml\")\n        with pytest.raises(CompilationError):\n            results = run_dbt([\"--partial-parse\", \"--warn-error\", \"run\"])\n\n        # Put back seed name to right name\n        write_file(schema_sources4_yml, project.project_root, \"models\", \"sources.yml\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n\n        # Add docs file customers.md\n        write_file(customers1_md, project.project_root, \"models\", \"customers.md\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n\n        # Change docs file customers.md\n        write_file(customers2_md, project.project_root, \"models\", \"customers.md\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n\n        # Delete docs file\n        rm_file(project.project_root, \"models\", \"customers.md\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n\n        # Add a data test\n        write_file(test_macro_sql, project.project_root, \"macros\", \"test-macro.sql\")\n        write_file(my_test_sql, project.project_root, \"tests\", \"my_test.sql\")\n        results = run_dbt([\"--partial-parse\", \"test\"])\n        manifest = get_manifest(project.project_root)\n        assert len(manifest.nodes) == 9\n        test_id = \"test.test.my_test\"\n        assert test_id in manifest.nodes\n\n        # Change macro that data test depends on\n        write_file(test_macro2_sql, project.project_root, \"macros\", \"test-macro.sql\")\n        results = run_dbt([\"--partial-parse\", \"test\"])\n        manifest = get_manifest(project.project_root)\n\n        # Add an analysis\n        write_file(my_analysis_sql, project.project_root, \"analyses\", \"my_analysis.sql\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        manifest = get_manifest(project.project_root)\n\n        # Remove data test\n        rm_file(project.project_root, \"tests\", \"my_test.sql\")\n        results = run_dbt([\"--partial-parse\", \"test\"])\n        manifest = get_manifest(project.project_root)\n        assert len(manifest.nodes) == 9\n\n        # Remove analysis\n        rm_file(project.project_root, \"analyses\", \"my_analysis.sql\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        manifest = get_manifest(project.project_root)\n        assert len(manifest.nodes) == 8\n\n        # Change source test\n        write_file(sources_tests2_sql, project.project_root, \"macros\", \"tests.sql\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n\n\nclass TestPartialParsingDependency:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_one.sql\": model_one_sql,\n        }\n\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project_root):\n        local_dependency_files = {\n            \"dbt_project.yml\": local_dependency__dbt_project_yml,\n            \"models\": {\n                \"schema.yml\": local_dependency__models__schema_yml,\n                \"model_to_import.sql\": local_dependency__models__model_to_import_sql,\n            },\n            \"macros\": {\"dep_macro.sql\": local_dependency__macros__dep_macro_sql},\n            \"seeds\": {\"seed.csv\": local_dependency__seeds__seed_csv},\n        }\n        write_project_files(project_root, \"local_dependency\", local_dependency_files)\n\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\"packages\": [{\"local\": \"local_dependency\"}]}\n\n    def test_parsing_with_dependency(self, project):\n        run_dbt([\"clean\"])\n        run_dbt([\"deps\"])\n        run_dbt([\"seed\"])\n        run_dbt([\"run\"])\n\n        # Add a source override\n        write_file(schema_models_c_yml, project.project_root, \"models\", \"schema.yml\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 2\n        manifest = get_manifest(project.project_root)\n        assert len(manifest.sources) == 1\n        source_id = \"source.local_dep.seed_source.seed\"\n        assert source_id in manifest.sources\n        # We have 1 root model, 1 local_dep model, 1 local_dep seed, 1 local_dep source test, 2 root source tests\n        assert len(manifest.nodes) == 5\n        test_id = \"test.local_dep.source_unique_seed_source_seed_id.afa94935ed\"\n        assert test_id in manifest.nodes\n\n        # Remove a source override\n        rm_file(project.project_root, \"models\", \"schema.yml\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        manifest = get_manifest(project.project_root)\n        assert len(manifest.sources) == 1\n\n\nclass TestNestedMacros:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_a.sql\": model_a_sql,\n            \"model_b.sql\": model_b_sql,\n            \"schema.yml\": macros_schema_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\n            \"custom_schema_tests.sql\": custom_schema_tests1_sql,\n        }\n\n    def test_nested_macros(self, project):\n        results = run_dbt()\n        assert len(results) == 2\n        manifest = get_manifest(project.project_root)\n        macro_child_map = manifest.build_macro_child_map()\n        macro_unique_id = \"macro.test.test_type_two\"\n        assert macro_unique_id in macro_child_map\n\n        results = run_dbt([\"test\"], expect_pass=False)\n        results = sorted(results, key=lambda r: r.node.name)\n        assert len(results) == 2\n        # type_one_model_a_\n        assert results[0].status == TestStatus.Fail\n        assert re.search(r\"union all\", results[0].node.compiled_code)\n        # type_two_model_a_\n        assert results[1].status == TestStatus.Warn\n        assert results[1].node.config.severity == \"WARN\"\n\n        write_file(\n            custom_schema_tests2_sql, project.project_root, \"macros\", \"custom_schema_tests.sql\"\n        )\n        results = run_dbt([\"--partial-parse\", \"test\"], expect_pass=False)\n        manifest = get_manifest(project.project_root)\n        test_node_id = \"test.test.type_two_model_a_.842bc6c2a7\"\n        assert test_node_id in manifest.nodes\n        results = sorted(results, key=lambda r: r.node.name)\n        assert len(results) == 2\n        # type_two_model_a_\n        assert results[1].status == TestStatus.Fail\n        assert results[1].node.config.severity == \"ERROR\"\n\n\nclass TestSkipMacros:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_one.sql\": model_one_sql,\n            \"eschema.yml\": empty_schema_yml,\n        }\n\n    def test_skip_macros(self, project):\n        # initial run so we have a msgpack file\n        # includes empty_schema file for bug #4850\n        results = run_dbt()\n\n        # add a new ref override macro\n        write_file(ref_override_sql, project.project_root, \"macros\", \"ref_override.sql\")\n        results, log_output = run_dbt_and_capture([\"--partial-parse\", \"run\"])\n        assert \"Starting full parse.\" in log_output\n\n        # modify a ref override macro\n        write_file(ref_override2_sql, project.project_root, \"macros\", \"ref_override.sql\")\n        results, log_output = run_dbt_and_capture([\"--partial-parse\", \"run\"])\n        assert \"Starting full parse.\" in log_output\n\n        # remove a ref override macro\n        rm_file(project.project_root, \"macros\", \"ref_override.sql\")\n        results, log_output = run_dbt_and_capture([\"--partial-parse\", \"run\"])\n        assert \"Starting full parse.\" in log_output\n\n        # custom generate_schema_name macro\n        write_file(gsm_override_sql, project.project_root, \"macros\", \"gsm_override.sql\")\n        results, log_output = run_dbt_and_capture([\"--partial-parse\", \"run\"])\n        assert \"Starting full parse.\" in log_output\n\n        # change generate_schema_name macro\n        write_file(gsm_override2_sql, project.project_root, \"macros\", \"gsm_override.sql\")\n        results, log_output = run_dbt_and_capture([\"--partial-parse\", \"run\"])\n        assert \"Starting full parse.\" in log_output\n\n\nclass TestMacroDescriptionUpdate:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": model_one_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\n            \"macros.sql\": macros_sql,\n            \"schema.yml\": macros_schema1_yml,\n        }\n\n    def test_pp_macro_description_update(self, project):\n        # initial parse\n        run_dbt([\"parse\"])\n\n        manifest = get_manifest(project.project_root)\n        assert \"macro.test.foo\" in manifest.macros\n        assert \"macro.test.bar\" in manifest.macros\n        assert manifest.macros[\"macro.test.foo\"].description == \"Lorem.\"\n        assert manifest.macros[\"macro.test.bar\"].description == \"Lorem.\"\n        assert manifest.macros[\"macro.test.foo\"].patch_path == \"test://\" + normalize(\n            \"macros/schema.yml\"\n        )\n        assert manifest.macros[\"macro.test.bar\"].patch_path == \"test://\" + normalize(\n            \"macros/schema.yml\"\n        )\n\n        # edit YAML in macros-path\n        write_file(macros_schema2_yml, project.project_root, \"macros\", \"schema.yml\")\n\n        # parse again\n        run_dbt([\"--partial-parse\", \"parse\"])\n\n        manifest = get_manifest(project.project_root)\n        assert \"macro.test.foo\" in manifest.macros\n        assert \"macro.test.bar\" in manifest.macros\n        assert manifest.macros[\"macro.test.foo\"].description == \"Lorem.\"\n        assert manifest.macros[\"macro.test.bar\"].description == \"Lorem ipsum.\"\n        assert manifest.macros[\"macro.test.foo\"].patch_path == \"test://\" + normalize(\n            \"macros/schema.yml\"\n        )\n        assert manifest.macros[\"macro.test.bar\"].patch_path == \"test://\" + normalize(\n            \"macros/schema.yml\"\n        )\n\n        # compile\n        run_dbt([\"--partial-parse\", \"compile\"])\n\n\nclass TestSnapshots:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"orders.sql\": orders_sql,\n        }\n\n    def test_pp_snapshots(self, project):\n\n        # initial run\n        results = run_dbt()\n        assert len(results) == 1\n\n        # add snapshot\n        write_file(snapshot_sql, project.project_root, \"snapshots\", \"snapshot.sql\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 1\n        manifest = get_manifest(project.project_root)\n        snapshot_id = \"snapshot.test.orders_snapshot\"\n        assert snapshot_id in manifest.nodes\n        snapshot2_id = \"snapshot.test.orders2_snapshot\"\n        assert snapshot2_id in manifest.nodes\n\n        # run snapshot\n        results = run_dbt([\"--partial-parse\", \"snapshot\"])\n        assert len(results) == 2\n\n        # modify snapshot\n        write_file(snapshot2_sql, project.project_root, \"snapshots\", \"snapshot.sql\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 1\n\n        # delete snapshot\n        rm_file(project.project_root, \"snapshots\", \"snapshot.sql\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 1\n\n\nclass TestGenericTests:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"orders.sql\": orders_sql,\n            \"schema.yml\": generic_schema_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def tests(self):\n        # Make sure \"generic\" directory is created\n        return {\"generic\": {\"readme.md\": \"\"}}\n\n    def test_pp_generic_tests(self, project):\n\n        # initial run\n        results = run_dbt()\n        assert len(results) == 1\n        manifest = get_manifest(project.project_root)\n        expected_nodes = [\"model.test.orders\", \"test.test.unique_orders_id.1360ecc70e\"]\n        assert expected_nodes == list(manifest.nodes.keys())\n\n        # add generic test in test-path\n        write_file(generic_test_sql, project.project_root, \"tests\", \"generic\", \"generic_test.sql\")\n        write_file(generic_test_schema_yml, project.project_root, \"models\", \"schema.yml\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 1\n        manifest = get_manifest(project.project_root)\n        test_id = \"test.test.is_odd_orders_id.82834fdc5b\"\n        assert test_id in manifest.nodes\n        expected_nodes = [\n            \"model.test.orders\",\n            \"test.test.unique_orders_id.1360ecc70e\",\n            \"test.test.is_odd_orders_id.82834fdc5b\",\n        ]\n        assert expected_nodes == list(manifest.nodes.keys())\n\n        # edit generic test in test-path\n        write_file(\n            generic_test_edited_sql, project.project_root, \"tests\", \"generic\", \"generic_test.sql\"\n        )\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 1\n        manifest = get_manifest(project.project_root)\n        test_id = \"test.test.is_odd_orders_id.82834fdc5b\"\n        assert test_id in manifest.nodes\n        expected_nodes = [\n            \"model.test.orders\",\n            \"test.test.unique_orders_id.1360ecc70e\",\n            \"test.test.is_odd_orders_id.82834fdc5b\",\n        ]\n        assert expected_nodes == list(manifest.nodes.keys())\n\n\nclass TestSingularTests:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"orders.sql\": orders_sql,\n            \"schema.yml\": generic_schema_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def tests(self):\n        # Make sure \"generic\" directory is created\n        return {\"generic\": {\"readme.md\": \"\"}}\n\n    def test_pp_singular_tests(self, project):\n\n        # initial run\n        results = run_dbt()\n        assert len(results) == 1\n        manifest = get_manifest(project.project_root)\n        expected_nodes = [\"model.test.orders\", \"test.test.unique_orders_id.1360ecc70e\"]\n        assert expected_nodes == list(manifest.nodes.keys())\n\n        # add singular test in test-path\n        write_file(orders_singular_test_sql, project.project_root, \"tests\", \"singular_test.sql\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 1\n\n        # modify model being tested by singular test\n        write_file(orders_sql_modified, project.project_root, \"models\", \"orders.sql\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 1\n\n\nclass TestExternalModels:\n    @pytest.fixture(scope=\"class\")\n    def external_model_node(self):\n        return ModelNodeArgs(\n            name=\"external_model\",\n            package_name=\"external\",\n            identifier=\"test_identifier\",\n            schema=\"test_schema\",\n        )\n\n    @pytest.fixture(scope=\"class\")\n    def external_model_node_versioned(self):\n        return ModelNodeArgs(\n            name=\"external_model_versioned\",\n            package_name=\"external\",\n            identifier=\"test_identifier_v1\",\n            schema=\"test_schema\",\n            version=1,\n        )\n\n    @pytest.fixture(scope=\"class\")\n    def external_model_node_depends_on(self):\n        return ModelNodeArgs(\n            name=\"external_model_depends_on\",\n            package_name=\"external\",\n            identifier=\"test_identifier_depends_on\",\n            schema=\"test_schema\",\n            depends_on_nodes=[\"model.external.external_model_depends_on_parent\"],\n        )\n\n    @pytest.fixture(scope=\"class\")\n    def external_model_node_depends_on_parent(self):\n        return ModelNodeArgs(\n            name=\"external_model_depends_on_parent\",\n            package_name=\"external\",\n            identifier=\"test_identifier_depends_on_parent\",\n            schema=\"test_schema\",\n        )\n\n    @pytest.fixture(scope=\"class\")\n    def external_model_node_merge(self):\n        return ModelNodeArgs(\n            name=\"model_two\",\n            package_name=\"test\",\n            identifier=\"test_identifier\",\n            schema=\"test_schema\",\n            database=\"dbt\",\n        )\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model_one.sql\": model_one_sql}\n\n    @mock.patch(\"dbt.plugins.get_plugin_manager\")\n    def test_pp_external_models(\n        self,\n        get_plugin_manager,\n        project,\n        external_model_node,\n        external_model_node_versioned,\n        external_model_node_depends_on,\n        external_model_node_depends_on_parent,\n        external_model_node_merge,\n    ):\n        # initial plugin - one external model\n        external_nodes = PluginNodes()\n        external_nodes.add_model(external_model_node)\n        get_plugin_manager.return_value.get_nodes.return_value = external_nodes\n\n        # initial parse\n        manifest = run_dbt([\"parse\"])\n        assert len(manifest.nodes) == 2\n        assert set(manifest.nodes.keys()) == {\n            \"model.external.external_model\",\n            \"model.test.model_one\",\n        }\n        assert len(manifest.external_node_unique_ids) == 1\n        assert manifest.external_node_unique_ids == [\"model.external.external_model\"]\n\n        # add a model file - test.model_two\n        write_file(model_two_sql, project.project_root, \"models\", \"model_two.sql\")\n        manifest = run_dbt([\"--partial-parse\", \"parse\"])\n        assert len(manifest.nodes) == 3\n\n        # add an external model that is already in project - test.model_two\n        # project model should be preferred to external model\n        external_nodes.add_model(external_model_node_merge)\n        manifest = run_dbt([\"--partial-parse\", \"parse\"])\n        assert len(manifest.nodes) == 3\n        assert len(manifest.external_node_unique_ids) == 1\n\n        # disable test.model_two in project\n        # project models should still be preferred to external model\n        write_file(model_two_disabled_sql, project.project_root, \"models\", \"model_two.sql\")\n        manifest = run_dbt([\"--partial-parse\", \"parse\"])\n        assert len(manifest.nodes) == 2\n        assert len(manifest.disabled) == 1\n        assert len(manifest.external_node_unique_ids) == 1\n\n        # re-enable model_2.sql\n        write_file(model_two_sql, project.project_root, \"models\", \"model_two.sql\")\n\n        # add a new external model\n        external_nodes.add_model(external_model_node_versioned)\n        manifest = run_dbt([\"--partial-parse\", \"parse\"])\n        assert len(manifest.nodes) == 4\n        assert len(manifest.external_node_unique_ids) == 2\n\n        # add a model file that depends on external model\n        write_file(\n            \"SELECT * FROM {{ref('external', 'external_model')}}\",\n            project.project_root,\n            \"models\",\n            \"model_depends_on_external.sql\",\n        )\n        manifest = run_dbt([\"--partial-parse\", \"parse\"])\n        assert len(manifest.nodes) == 5\n        assert len(manifest.external_node_unique_ids) == 2\n\n        # remove a model file that depends on external model\n        rm_file(project.project_root, \"models\", \"model_depends_on_external.sql\")\n        manifest = run_dbt([\"--partial-parse\", \"parse\"])\n        assert len(manifest.nodes) == 4\n\n        # add an external node with depends on\n        external_nodes.add_model(external_model_node_depends_on)\n        external_nodes.add_model(external_model_node_depends_on_parent)\n        manifest = run_dbt([\"--partial-parse\", \"parse\"])\n        assert len(manifest.nodes) == 6\n        assert len(manifest.external_node_unique_ids) == 4\n\n        # skip files parsing - ensure no issues\n        run_dbt([\"--partial-parse\", \"parse\"])\n        assert len(manifest.nodes) == 6\n        assert len(manifest.external_node_unique_ids) == 4\n\n\nclass TestPortablePartialParsing:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_one.sql\": model_one_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\"packages\": [{\"local\": \"local_dependency\"}]}\n\n    @pytest.fixture(scope=\"class\")\n    def local_dependency_files(self):\n        return {\n            \"dbt_project.yml\": local_dependency__dbt_project_yml,\n            \"models\": {\n                \"schema.yml\": local_dependency__models__schema_yml,\n                \"model_to_import.sql\": local_dependency__models__model_to_import_sql,\n            },\n            \"macros\": {\"dep_macro.sql\": local_dependency__macros__dep_macro_sql},\n            \"seeds\": {\"seed.csv\": local_dependency__seeds__seed_csv},\n        }\n\n    def rename_project_root(self, project, new_project_root):\n        with up_one(new_project_root):\n            rename_dir(project.project_root, new_project_root)\n            project.project_root = new_project_root\n            # flags.project_dir is set during the project test fixture, and is persisted across run_dbt calls,\n            # so it needs to be reset between invocations\n            flags.set_from_args(Namespace(PROJECT_DIR=new_project_root), None)\n\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def initial_run_and_rename_project_dir(self, project, local_dependency_files):\n        initial_project_root = project.project_root\n        renamed_project_root = os.path.join(project.project_root.dirname, \"renamed_project_dir\")\n\n        write_project_files(project.project_root, \"local_dependency\", local_dependency_files)\n\n        # initial run\n        run_dbt([\"deps\"])\n        assert len(run_dbt([\"seed\"])) == 1\n        assert len(run_dbt([\"run\"])) == 2\n\n        self.rename_project_root(project, renamed_project_root)\n        yield\n        self.rename_project_root(project, initial_project_root)\n\n    def test_pp_renamed_project_dir_unchanged_project_contents(self, project):\n        # partial parse same project in new absolute dir location, using partial_parse.msgpack created in previous dir\n        run_dbt([\"deps\"])\n        assert len(run_dbt([\"--partial-parse\", \"seed\"])) == 1\n        assert len(run_dbt([\"--partial-parse\", \"run\"])) == 2\n\n    def test_pp_renamed_project_dir_changed_project_contents(self, project):\n        write_file(model_two_sql, project.project_root, \"models\", \"model_two.sql\")\n\n        # partial parse changed project in new absolute dir location, using partial_parse.msgpack created in previous dir\n        run_dbt([\"deps\"])\n        len(run_dbt([\"--partial-parse\", \"seed\"])) == 1\n        len(run_dbt([\"--partial-parse\", \"run\"])) == 3\n\n\nclass TestProfileChanges:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model.sql\": \"select 1 as id\",\n        }\n\n    def test_profile_change(self, project, dbt_profile_data):\n        # Fist run not partial parsing\n        _, stdout = run_dbt_and_capture([\"parse\"])\n        assert \"Unable to do partial parsing because saved manifest not found\" in stdout\n\n        _, stdout = run_dbt_and_capture([\"parse\"])\n        assert \"Unable to do partial parsing\" not in stdout\n\n        # change dbname which is included in the connection_info\n        dbt_profile_data[\"test\"][\"outputs\"][\"default\"][\"dbname\"] = \"dbt2\"\n        write_file(yaml.safe_dump(dbt_profile_data), project.profiles_dir, \"profiles.yml\")\n        _, stdout = run_dbt_and_capture([\"parse\"])\n        assert \"Unable to do partial parsing because profile has changed\" in stdout\n\n        # Change the password which is not included in the connection_info\n        dbt_profile_data[\"test\"][\"outputs\"][\"default\"][\"pass\"] = \"another_password\"\n        write_file(yaml.safe_dump(dbt_profile_data), project.profiles_dir, \"profiles.yml\")\n        _, stdout = run_dbt_and_capture([\"parse\"])\n        assert \"Unable to do partial parsing\" not in stdout\n\n\nclass TestExplicitDefaultProfileAndTarget:\n    def test_explicit_default_profile_allows_partial_parse(self, project):\n        event_catcher = EventCatcher(UnableToPartialParse)\n        run_dbt([\"parse\"])\n        run_dbt([\"parse\", \"--profile\", \"test\"], callbacks=[event_catcher.catch])\n        assert len(event_catcher.caught_events) == 0\n\n    def test_explicit_default_target_allows_partial_parse(self, project):\n        event_catcher = EventCatcher(UnableToPartialParse)\n        run_dbt([\"parse\"])\n        run_dbt([\"parse\", \"--target\", \"default\"], callbacks=[event_catcher.catch])\n        assert len(event_catcher.caught_events) == 0\n"
  },
  {
    "path": "tests/functional/partial_parsing/test_pp_disabled_config.py",
    "content": "import pytest\n\nfrom dbt.tests.util import get_manifest, run_dbt, write_file\n\nmodel_one_sql = \"\"\"\nselect 1 as fun\n\"\"\"\n\nmetricflow_time_spine_sql = \"\"\"\nSELECT to_date('02/20/2023', 'mm/dd/yyyy') as date_day\n\"\"\"\n\nschema1_yml = \"\"\"\nversion: 2\n\nmodels:\n    - name: model_one\n\nsemantic_models:\n  - name: semantic_people\n    model: ref('model_one')\n    dimensions:\n      - name: created_at\n        type: TIME\n        type_params:\n          time_granularity: day\n    measures:\n      - name: people\n        agg: count\n        expr: fun\n    entities:\n      - name: fun\n        type: primary\n    defaults:\n      agg_time_dimension: created_at\n\nmetrics:\n\n  - name: number_of_people\n    label: \"Number of people\"\n    description: Total count of people\n    type: simple\n    type_params:\n      measure: people\n    meta:\n        my_meta: 'testing'\n\nexposures:\n  - name: proxy_for_dashboard\n    description: \"My Exposure\"\n    type: \"dashboard\"\n    owner:\n      name: \"Dashboard Tester\"\n      email: \"tester@dashboard.com\"\n    depends_on:\n      - ref(\"model_one\")\n\"\"\"\n\nschema2_yml = \"\"\"\nversion: 2\n\nmodels:\n    - name: model_one\n\nsemantic_models:\n  - name: semantic_people\n    model: ref('model_one')\n    dimensions:\n      - name: created_at\n        type: TIME\n        type_params:\n          time_granularity: day\n    measures:\n      - name: people\n        agg: count\n        expr: fun\n    entities:\n      - name: fun\n        type: primary\n    defaults:\n      agg_time_dimension: created_at\n\nmetrics:\n\n  - name: number_of_people\n    label: \"Number of people\"\n    description: Total count of people\n    config:\n        enabled: false\n    type: simple\n    type_params:\n      measure: people\n    meta:\n        my_meta: 'testing'\n\nexposures:\n  - name: proxy_for_dashboard\n    description: \"My Exposure\"\n    config:\n        enabled: false\n    type: \"dashboard\"\n    owner:\n      name: \"Dashboard Tester\"\n      email: \"tester@dashboard.com\"\n    depends_on:\n      - ref(\"model_one\")\n\"\"\"\n\nschema3_yml = \"\"\"\nversion: 2\n\nmodels:\n    - name: model_one\n\nsemantic_models:\n  - name: semantic_people\n    model: ref('model_one')\n    dimensions:\n      - name: created_at\n        type: TIME\n        type_params:\n          time_granularity: day\n    measures:\n      - name: people\n        agg: count\n        expr: fun\n    entities:\n      - name: fun\n        type: primary\n    defaults:\n      agg_time_dimension: created_at\n\nmetrics:\n\n  - name: number_of_people\n    label: \"Number of people\"\n    description: Total count of people\n    type: simple\n    type_params:\n      measure: people\n    meta:\n        my_meta: 'testing'\n\"\"\"\n\nschema4_yml = \"\"\"\nversion: 2\n\nmodels:\n    - name: model_one\n\nexposures:\n  - name: proxy_for_dashboard\n    description: \"My Exposure\"\n    config:\n        enabled: false\n    type: \"dashboard\"\n    owner:\n      name: \"Dashboard Tester\"\n      email: \"tester@dashboard.com\"\n    depends_on:\n      - ref(\"model_one\")\n\"\"\"\n\n\nclass TestDisabled:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_one.sql\": model_one_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"schema.yml\": schema1_yml,\n        }\n\n    def test_pp_disabled(self, project):\n        expected_exposure = \"exposure.test.proxy_for_dashboard\"\n        expected_metric = \"metric.test.number_of_people\"\n\n        run_dbt([\"seed\"])\n        manifest = run_dbt([\"parse\"])\n\n        assert expected_exposure in manifest.exposures\n        assert expected_metric in manifest.metrics\n        assert expected_exposure not in manifest.disabled\n        assert expected_metric not in manifest.disabled\n\n        # Update schema file with disabled metric and exposure\n        write_file(schema2_yml, project.project_root, \"models\", \"schema.yml\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 2\n        manifest = get_manifest(project.project_root)\n        assert expected_exposure not in manifest.exposures\n        assert expected_metric not in manifest.metrics\n        assert expected_exposure in manifest.disabled\n        assert expected_metric in manifest.disabled\n\n        # Update schema file with enabled metric and exposure\n        write_file(schema1_yml, project.project_root, \"models\", \"schema.yml\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 2\n        manifest = get_manifest(project.project_root)\n        assert expected_exposure in manifest.exposures\n        assert expected_metric in manifest.metrics\n        assert expected_exposure not in manifest.disabled\n        assert expected_metric not in manifest.disabled\n\n        # Update schema file - remove exposure, enable metric\n        write_file(schema3_yml, project.project_root, \"models\", \"schema.yml\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 2\n        manifest = get_manifest(project.project_root)\n        assert expected_exposure not in manifest.exposures\n        assert expected_metric in manifest.metrics\n        assert expected_exposure not in manifest.disabled\n        assert expected_metric not in manifest.disabled\n\n        # Update schema file - add back exposure, remove metric\n        write_file(schema4_yml, project.project_root, \"models\", \"schema.yml\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 2\n        manifest = get_manifest(project.project_root)\n        assert expected_exposure not in manifest.exposures\n        assert expected_metric not in manifest.metrics\n        assert expected_exposure in manifest.disabled\n        assert expected_metric not in manifest.disabled\n"
  },
  {
    "path": "tests/functional/partial_parsing/test_pp_docs.py",
    "content": "import pytest\n\nfrom dbt.tests.util import get_manifest, rm_file, run_dbt, write_file\n\nmodel_one_sql = \"\"\"\nselect 1 as fun\n\"\"\"\n\nraw_customers_csv = \"\"\"id,first_name,last_name,email\n1,Michael,Perez,mperez0@chronoengine.com\n2,Shawn,Mccoy,smccoy1@reddit.com\n3,Kathleen,Payne,kpayne2@cargocollective.com\n4,Jimmy,Cooper,jcooper3@cargocollective.com\n5,Katherine,Rice,krice4@typepad.com\n6,Sarah,Ryan,sryan5@gnu.org\n7,Martin,Mcdonald,mmcdonald6@opera.com\n8,Frank,Robinson,frobinson7@wunderground.com\n9,Jennifer,Franklin,jfranklin8@mail.ru\n10,Henry,Welch,hwelch9@list-manage.com\n\"\"\"\n\nmy_macro_sql = \"\"\"\n{% macro my_macro(something) %}\n\n    select\n        '{{ something }}' as something2\n\n{% endmacro %}\n\n\"\"\"\n\ncustomers1_md = \"\"\"\n{% docs customer_table %}\n\nThis table contains customer data\n\n{% enddocs %}\n\"\"\"\n\ncustomers2_md = \"\"\"\n{% docs customer_table %}\n\nLOTS of customer data\n\n{% enddocs %}\n\n\"\"\"\n\nschema1_yml = \"\"\"\nversion: 2\n\nmodels:\n    - name: model_one\n      description: \"{{ doc('customer_table') }}\"\n\"\"\"\n\nschema2_yml = \"\"\"\nversion: 2\n\nmodels:\n    - name: model_one\n      description: \"{{ doc('customer_table') }}\"\n\nmacros:\n    - name: my_macro\n      description: \"{{ doc('customer_table') }}\"\n\nsources:\n  - name: seed_sources\n    description: \"{{ doc('customer_table') }}\"\n    schema: \"{{ target.schema }}\"\n    tables:\n      - name: raw_customers\n        columns:\n          - name: id\n            data_tests:\n              - not_null:\n                  severity: \"{{ 'error' if target.name == 'prod' else 'warn' }}\"\n              - unique\n          - name: first_name\n          - name: last_name\n          - name: email\n\nexposures:\n  - name: proxy_for_dashboard\n    description: \"{{ doc('customer_table') }}\"\n    type: \"dashboard\"\n    owner:\n      name: \"Dashboard Tester\"\n      email: \"tester@dashboard.com\"\n    depends_on:\n      - ref(\"model_one\")\n      - ref(\"raw_customers\")\n      - source(\"seed_sources\", \"raw_customers\")\n\"\"\"\n\n\nclass TestDocs:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_one.sql\": model_one_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\n            \"raw_customers.csv\": raw_customers_csv,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\n            \"my_macro.sql\": my_macro_sql,\n        }\n\n    def test_pp_docs(self, project):\n        run_dbt([\"seed\"])\n        results = run_dbt([\"run\"])\n        assert len(results) == 1\n\n        # Add docs file customers.md\n        write_file(customers1_md, project.project_root, \"models\", \"customers.md\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        manifest = get_manifest(project.project_root)\n        assert len(manifest.docs) == 2\n\n        # Add schema file with 'docs' description\n        write_file(schema1_yml, project.project_root, \"models\", \"schema.yml\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        manifest = get_manifest(project.project_root)\n        assert len(manifest.docs) == 2\n        doc_id = \"doc.test.customer_table\"\n        assert doc_id in manifest.docs\n        doc = manifest.docs[doc_id]\n        doc_file_id = doc.file_id\n        assert doc_file_id in manifest.files\n        source_file = manifest.files[doc_file_id]\n        assert len(source_file.nodes) == 1\n        model_one_id = \"model.test.model_one\"\n        assert model_one_id in source_file.nodes\n        model_node = manifest.nodes[model_one_id]\n        assert model_node.description == \"This table contains customer data\"\n\n        # Update the doc file\n        write_file(customers2_md, project.project_root, \"models\", \"customers.md\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        manifest = get_manifest(project.project_root)\n        assert len(manifest.docs) == 2\n        assert model_one_id in manifest.nodes\n        model_node = manifest.nodes[model_one_id]\n        assert \"LOTS\" in model_node.description\n\n        # Add a macro patch, source and exposure with doc\n        write_file(schema2_yml, project.project_root, \"models\", \"schema.yml\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 1\n        manifest = get_manifest(project.project_root)\n        doc_file = manifest.files[doc_file_id]\n        expected_nodes = [\n            \"model.test.model_one\",\n            \"source.test.seed_sources.raw_customers\",\n            \"macro.test.my_macro\",\n            \"exposure.test.proxy_for_dashboard\",\n        ]\n        assert expected_nodes == doc_file.nodes\n        source_id = \"source.test.seed_sources.raw_customers\"\n        assert manifest.sources[source_id].source_description == \"LOTS of customer data\"\n        macro_id = \"macro.test.my_macro\"\n        assert manifest.macros[macro_id].description == \"LOTS of customer data\"\n        exposure_id = \"exposure.test.proxy_for_dashboard\"\n        assert manifest.exposures[exposure_id].description == \"LOTS of customer data\"\n\n        # update the doc file again\n        write_file(customers1_md, project.project_root, \"models\", \"customers.md\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        manifest = get_manifest(project.project_root)\n        source_file = manifest.files[doc_file_id]\n        assert model_one_id in source_file.nodes\n        model_node = manifest.nodes[model_one_id]\n        assert model_node.description == \"This table contains customer data\"\n        assert (\n            manifest.sources[source_id].source_description == \"This table contains customer data\"\n        )\n        assert manifest.macros[macro_id].description == \"This table contains customer data\"\n        assert manifest.exposures[exposure_id].description == \"This table contains customer data\"\n\n        # check that _lock is working\n        with manifest._lock:\n            assert manifest._lock\n\n\nmy_model_yml = \"\"\"\nversion: 2\nmodels:\n  - name: my_model\n    columns:\n      - name: id\n        description: \"{{ doc('whatever') }}\"\n\"\"\"\n\nmy_model_no_description_yml = \"\"\"\nversion: 2\nmodels:\n  - name: my_model\n    columns:\n      - name: id\n\"\"\"\n\nmy_model_md = \"\"\"\n{% docs whatever %}\n  cool stuff\n{% enddocs %}\n\"\"\"\n\n\nclass TestDocsRemoveReplace:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": \"select 1 as id\",\n            \"my_model.yml\": my_model_yml,\n            \"my_model.md\": my_model_md,\n        }\n\n    def test_remove_replace(self, project):\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n        doc_id = \"doc.test.whatever\"\n        assert doc_id in manifest.docs\n        doc = manifest.docs[doc_id]\n        doc_file = manifest.files[doc.file_id]\n\n        model_id = \"model.test.my_model\"\n        assert model_id in manifest.nodes\n\n        assert doc_file.nodes == [model_id]\n\n        model = manifest.nodes[model_id]\n        model_file_id = model.file_id\n        assert model_file_id in manifest.files\n\n        # remove the doc file\n        rm_file(project.project_root, \"models\", \"my_model.md\")\n        # remove description from schema file\n        write_file(my_model_no_description_yml, project.project_root, \"models\", \"my_model.yml\")\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n        assert doc_id not in manifest.docs\n        # The bug was that the file still existed in manifest.files\n        assert doc.file_id not in manifest.files\n\n        # put back the doc file\n        write_file(my_model_md, project.project_root, \"models\", \"my_model.md\")\n        # put back the description in the schema file\n        write_file(my_model_yml, project.project_root, \"models\", \"my_model.yml\")\n        run_dbt([\"parse\"])\n"
  },
  {
    "path": "tests/functional/partial_parsing/test_pp_functions.py",
    "content": "import pytest\n\nfrom dbt.artifacts.resources import FunctionArgument, FunctionReturns\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.tests.util import run_dbt, update_config_file, write_file\nfrom dbt_common.events.event_catcher import EventCatcher\nfrom dbt_common.events.types import Note\nfrom tests.functional.partial_parsing.fixtures import (\n    model_using_function_sql,\n    my_func_sql,\n    my_func_yml,\n    updated_my_func_sql,\n    updated_my_func_yml,\n)\n\n\nclass TestPartialParsingFunctions:\n    @pytest.fixture(scope=\"class\")\n    def functions(self):\n        return {\n            \"my_func.sql\": my_func_sql,\n            \"my_func.yml\": my_func_yml,\n        }\n\n    def test_pp_functions(self, project):\n        # initial run\n        manifest = run_dbt([\"parse\"])\n        assert isinstance(manifest, Manifest)\n        assert len(manifest.functions) == 1\n        function = manifest.functions[\"function.test.my_func\"]\n        assert function.raw_code == \"value * 2\"\n        assert function.description == \"Doubles an integer\"\n        assert function.arguments == [\n            FunctionArgument(name=\"value\", data_type=\"int\", description=\"An integer to be doubled\")\n        ]\n        assert function.returns == FunctionReturns(data_type=\"int\")\n\n        # update sql\n        write_file(updated_my_func_sql, project.project_root, \"functions\", \"my_func.sql\")\n        manifest = run_dbt([\"parse\"])\n        assert isinstance(manifest, Manifest)\n        assert len(manifest.functions) == 1\n        function = manifest.functions[\"function.test.my_func\"]\n        assert function.raw_code == \"number * 2.0\"\n        assert function.description == \"Doubles an integer\"\n        assert function.arguments == [\n            FunctionArgument(name=\"value\", data_type=\"int\", description=\"An integer to be doubled\")\n        ]\n        assert function.returns == FunctionReturns(data_type=\"int\")\n\n        # update yml\n        write_file(updated_my_func_yml, project.project_root, \"functions\", \"my_func.yml\")\n        manifest = run_dbt([\"parse\"])\n        assert isinstance(manifest, Manifest)\n        assert len(manifest.functions) == 1\n        function = manifest.functions[\"function.test.my_func\"]\n        assert function.raw_code == \"number * 2.0\"\n        assert function.description == \"Doubles a float\"\n        assert function.arguments == [\n            FunctionArgument(name=\"number\", data_type=\"float\", description=\"A float to be doubled\")\n        ]\n        assert function.returns == FunctionReturns(data_type=\"float\")\n\n        # if we parse again, partial parsing should be skipped\n        note_catcher = EventCatcher(Note)\n        manifest = run_dbt([\"parse\"], callbacks=[note_catcher.catch])\n        assert isinstance(manifest, Manifest)\n        assert len(manifest.functions) == 1\n        assert len(note_catcher.caught_events) == 1\n        assert (\n            note_catcher.caught_events[0].info.msg == \"Nothing changed, skipping partial parsing.\"\n        )\n\n\nclass TestPartialParsingFunctionsAndCompilationOfDownstreamNodes:\n    @pytest.fixture(scope=\"class\")\n    def functions(self):\n        return {\n            \"my_func.sql\": my_func_sql,\n            \"my_func.yml\": my_func_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_using_function.sql\": model_using_function_sql,\n        }\n\n    def test_pp_functions(self, project):\n        result = run_dbt([\"compile\"])\n        # one function node and one model node\n        assert len(result.results) == 2\n        assert result.results[0].node.name == \"my_func\"\n        assert result.results[0].node.config.alias is None\n        assert result.results[1].node.name == \"model_using_function\"\n        # `my_func` should be the third part of the name for the function in the compiled code\n        assert \"my_func\" in result.results[1].node.compiled_code\n\n        # Add an alias to `my_func`\n        add_function_alias = {\n            \"functions\": {\n                \"+alias\": \"aliased_my_func\",\n            }\n        }\n        update_config_file(add_function_alias, \"dbt_project.yml\")\n\n        # Recompile\n        result = run_dbt([\"compile\"])\n        # one function node and one model node\n        assert len(result.results) == 2\n        assert result.results[0].node.name == \"my_func\"\n        assert result.results[0].node.config.alias == \"aliased_my_func\"\n        assert result.results[1].node.name == \"model_using_function\"\n        # `aliased_my_func` should be the third part of the name for the function in the compiled code\n        assert \"aliased_my_func\" in result.results[1].node.compiled_code\n"
  },
  {
    "path": "tests/functional/partial_parsing/test_pp_groups.py",
    "content": "import pytest\n\nfrom dbt.exceptions import ParsingError\nfrom dbt.tests.util import get_manifest, run_dbt, write_file\nfrom tests.functional.partial_parsing.fixtures import (\n    groups_schema_yml_one_group,\n    groups_schema_yml_one_group_model_in_group2,\n    groups_schema_yml_two_groups,\n    groups_schema_yml_two_groups_edited,\n    groups_schema_yml_two_groups_private_orders_invalid_access,\n    groups_schema_yml_two_groups_private_orders_valid_access,\n    orders_downstream_sql,\n    orders_sql,\n)\n\n\nclass TestGroups:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"orders.sql\": orders_sql,\n            \"orders_downstream.sql\": orders_downstream_sql,\n            \"schema.yml\": groups_schema_yml_one_group,\n        }\n\n    def test_pp_groups(self, project):\n\n        # initial run\n        results = run_dbt()\n        assert len(results) == 2\n        manifest = get_manifest(project.project_root)\n        expected_nodes = [\"model.test.orders\", \"model.test.orders_downstream\"]\n        expected_groups = [\"group.test.test_group\"]\n        assert expected_nodes == sorted(list(manifest.nodes.keys()))\n        assert expected_groups == sorted(list(manifest.groups.keys()))\n\n        # add group to schema\n        write_file(groups_schema_yml_two_groups, project.project_root, \"models\", \"schema.yml\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 2\n        manifest = get_manifest(project.project_root)\n        expected_nodes = [\"model.test.orders\", \"model.test.orders_downstream\"]\n        expected_groups = [\"group.test.test_group\", \"group.test.test_group2\"]\n        assert expected_nodes == sorted(list(manifest.nodes.keys()))\n        assert expected_groups == sorted(list(manifest.groups.keys()))\n\n        # edit group in schema\n        write_file(\n            groups_schema_yml_two_groups_edited, project.project_root, \"models\", \"schema.yml\"\n        )\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 2\n        manifest = get_manifest(project.project_root)\n        expected_nodes = [\"model.test.orders\", \"model.test.orders_downstream\"]\n        expected_groups = [\"group.test.test_group\", \"group.test.test_group2_edited\"]\n        assert expected_nodes == sorted(list(manifest.nodes.keys()))\n        assert expected_groups == sorted(list(manifest.groups.keys()))\n\n        # delete group in schema\n        write_file(groups_schema_yml_one_group, project.project_root, \"models\", \"schema.yml\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 2\n        manifest = get_manifest(project.project_root)\n        expected_nodes = [\"model.test.orders\", \"model.test.orders_downstream\"]\n        expected_groups = [\"group.test.test_group\"]\n        assert expected_nodes == sorted(list(manifest.nodes.keys()))\n        assert expected_groups == sorted(list(manifest.groups.keys()))\n\n        # add back second group\n        write_file(groups_schema_yml_two_groups, project.project_root, \"models\", \"schema.yml\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 2\n\n        # remove second group with model still configured to second group\n        write_file(\n            groups_schema_yml_one_group_model_in_group2,\n            project.project_root,\n            \"models\",\n            \"schema.yml\",\n        )\n        with pytest.raises(ParsingError):\n            results = run_dbt([\"--partial-parse\", \"run\"])\n\n        # add back second group, make orders private with valid ref\n        write_file(\n            groups_schema_yml_two_groups_private_orders_valid_access,\n            project.project_root,\n            \"models\",\n            \"schema.yml\",\n        )\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 2\n\n        write_file(\n            groups_schema_yml_two_groups_private_orders_invalid_access,\n            project.project_root,\n            \"models\",\n            \"schema.yml\",\n        )\n        with pytest.raises(ParsingError):\n            results = run_dbt([\"--partial-parse\", \"run\"])\n\n\nmy_model_c = \"\"\"\nselect * from {{ ref(\"my_model_a\") }} union all\nselect * from {{ ref(\"my_model_b\") }}\n\"\"\"\n\nmodels_yml = \"\"\"\nmodels:\n  - name: my_model_a\n  - name: my_model_b\n  - name: my_model_c\n\"\"\"\n\nmodels_and_groups_yml = \"\"\"\ngroups:\n  - name: sales_analytics\n    owner:\n      name: Sales Analytics\n      email: sales@jaffleshop.com\n\nmodels:\n  - name: my_model_a\n    access: private\n    group: sales_analytics\n  - name: my_model_b\n    access: private\n    group: sales_analytics\n  - name: my_model_c\n    access: private\n    group: sales_analytics\n\"\"\"\n\n\nclass TestAddingModelsToNewGroups:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model_a.sql\": \"select 1 as id\",\n            \"my_model_b.sql\": \"select 2 as id\",\n            \"my_model_c.sql\": my_model_c,\n            \"models.yml\": models_yml,\n        }\n\n    def test_adding_models_to_new_groups(self, project):\n        run_dbt([\"compile\"])\n        # This tests that the correct patch is added to my_model_c. The bug\n        # was that it was using the old patch, so model_c didn't have the\n        # correct group and access.\n        write_file(models_and_groups_yml, project.project_root, \"models\", \"models.yml\")\n        run_dbt([\"compile\"])\n        manifest = get_manifest(project.project_root)\n        model_c_node = manifest.nodes[\"model.test.my_model_c\"]\n        assert model_c_node.group == \"sales_analytics\"\n        assert model_c_node.access == \"private\"\n"
  },
  {
    "path": "tests/functional/partial_parsing/test_pp_metrics.py",
    "content": "import pytest\n\nfrom dbt.cli.main import dbtRunner\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.exceptions import CompilationError\nfrom dbt.tests.util import get_manifest, rm_file, run_dbt, write_file\nfrom tests.functional.partial_parsing.fixtures import (\n    metric_model_a_sql,\n    metricflow_time_spine_sql,\n    people_metrics2_yml,\n    people_metrics3_yml,\n    people_metrics_yml,\n    people_semantic_models_yml,\n    people_sl_yml,\n    people_sql,\n)\n\n\nclass TestMetrics:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"people.sql\": people_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n        }\n\n    def test_metrics(self, project):\n        # initial run\n        results = run_dbt([\"run\"])\n        assert len(results) == 2\n        manifest = get_manifest(project.project_root)\n        assert len(manifest.nodes) == 2\n\n        # Add metrics yaml file (and necessary semantic models yaml)\n        write_file(\n            people_semantic_models_yml,\n            project.project_root,\n            \"models\",\n            \"people_semantic_models.yml\",\n        )\n        write_file(people_metrics_yml, project.project_root, \"models\", \"people_metrics.yml\")\n        results = run_dbt([\"run\"])\n        assert len(results) == 2\n        manifest = get_manifest(project.project_root)\n        assert len(manifest.metrics) == 2\n        metric_people_id = \"metric.test.number_of_people\"\n        metric_people = manifest.metrics[metric_people_id]\n        expected_meta = {\"my_meta\": \"testing\"}\n        assert metric_people.meta == expected_meta\n\n        # TODO: Bring back when we resolving `depends_on_nodes`\n        # metric_tenure_id = \"metric.test.collective_tenure\"\n        # metric_tenure = manifest.metrics[metric_tenure_id]\n        # assert metric_people.refs == [RefArgs(name=\"people\")]\n        # assert metric_tenure.refs == [RefArgs(name=\"people\")]\n        # expected_depends_on_nodes = [\"model.test.people\"]\n        # assert metric_people.depends_on.nodes == expected_depends_on_nodes\n\n        # Change metrics yaml files\n        write_file(people_metrics2_yml, project.project_root, \"models\", \"people_metrics.yml\")\n        results = run_dbt([\"run\"])\n        assert len(results) == 2\n        manifest = get_manifest(project.project_root)\n        metric_people = manifest.metrics[metric_people_id]\n        expected_meta = {\"my_meta\": \"replaced\"}\n        assert metric_people.meta == expected_meta\n        # TODO: Bring back when we resolving `depends_on_nodes`\n        # expected_depends_on_nodes = [\"model.test.people\"]\n        # assert metric_people.depends_on.nodes == expected_depends_on_nodes\n\n        # Add model referring to metric\n        write_file(metric_model_a_sql, project.project_root, \"models\", \"metric_model_a.sql\")\n        results = run_dbt([\"run\"])\n        manifest = get_manifest(project.project_root)\n        # TODO: Bring back when we resolving `depends_on_nodes`\n        # model_a = manifest.nodes[\"model.test.metric_model_a\"]\n        # expected_depends_on_nodes = [\n        #     \"metric.test.number_of_people\",\n        #     \"metric.test.collective_tenure\",\n        # ]\n        # assert model_a.depends_on.nodes == expected_depends_on_nodes\n\n        # Then delete a metric\n        write_file(people_metrics3_yml, project.project_root, \"models\", \"people_metrics.yml\")\n        with pytest.raises(CompilationError):\n            # We use \"parse\" here and not \"run\" because we're checking that the CompilationError\n            # occurs at parse time, not compilation\n            results = run_dbt([\"parse\"])\n\n\nclass TestDeleteFileWithMetricsAndSemanticModels:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"people.sql\": people_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"people_sl.yml\": people_sl_yml,\n        }\n\n    def test_metrics(self, project):\n        # Initial parsing\n        runner = dbtRunner()\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        manifest = result.result\n        assert isinstance(manifest, Manifest)\n        assert len(manifest.metrics) == 3\n\n        # Remove metric file\n        rm_file(project.project_root, \"models\", \"people_sl.yml\")\n\n        # Rerun parse, shouldn't fail\n        result = runner.invoke([\"parse\"])\n        assert result.exception is None, result.exception\n"
  },
  {
    "path": "tests/functional/partial_parsing/test_pp_schema_file_order.py",
    "content": "import os\n\nimport pytest\n\nfrom dbt.tests.util import get_manifest, rm_file, run_dbt, write_file\n\nos.environ[\"DBT_PP_TEST\"] = \"true\"\n\ncolors_sql = \"\"\"\n    select 'green' as first, 'red' as second, 'blue' as third\n\"\"\"\n\nanother_v1_sql = \"\"\"\nselect * from {{ ref(\"colors\") }}\n\"\"\"\n\nanother_ref_sql = \"\"\"\nselect * from {{ ref(\"another\") }}\n\"\"\"\n\ncolors_yml = \"\"\"\nmodels:\n  - name: colors\n    description: \"a list of colors\"\n  - name: another\n    description: \"another model\"\n    versions:\n      - v: 1\n\"\"\"\n\ncolors_alt_yml = \"\"\"\nmodels:\n  - name: colors\n    description: \"a list of colors\"\n  - name: another\n    description: \"YET another model\"\n    versions:\n      - v: 1\n\"\"\"\n\nfoo_model_sql = \"\"\"\nselect 1 as id\n\"\"\"\n\nanother_ref_yml = \"\"\"\nmodels:\n  - name: another_ref\n    description: \"model with reference to another ref\"\n  - name: foo_model\n    description: \"some random model\"\n\"\"\"\n\nanother_ref_alt_yml = \"\"\"\nmodels:\n  - name: another_ref\n    description: \"model with reference to another ref\"\n  - name: foo_model\n    description: \"some random other model\"\n\"\"\"\n\n\nclass TestSchemaFileOrder:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"colors.sql\": colors_sql,\n            \"colors.yml\": colors_yml,\n            \"another_v1.sql\": another_v1_sql,\n            \"another_ref.sql\": another_ref_sql,\n            \"foo_model.sql\": foo_model_sql,\n            \"another_ref.yml\": another_ref_yml,\n        }\n\n    def test_schema_file_order(self, project):\n\n        # initial run\n        results = run_dbt([\"run\"])\n        assert len(results) == 4\n\n        manifest = get_manifest(project.project_root)\n        model_id = \"model.test.another_ref\"\n        model = manifest.nodes.get(model_id)\n        assert model.description == \"model with reference to another ref\"\n\n        write_file(colors_alt_yml, project.project_root, \"models\", \"colors.yml\")\n        write_file(another_ref_alt_yml, project.project_root, \"models\", \"another_ref.yml\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 4\n        manifest = get_manifest(project.project_root)\n        model = manifest.nodes.get(model_id)\n        assert model.name == \"another_ref\"\n        # The description here would be '' without the bug fix\n        assert model.description == \"model with reference to another ref\"\n\n\nfoo_sql = \"\"\"\nselect 1 c\n\"\"\"\n\nbar_sql = \"\"\"\nselect 1 c\n\"\"\"\n\nbar_with_ref_sql = \"\"\"\nselect * from {{ ref('foo') }}\n\"\"\"\n\nfoo_v2_sql = \"\"\"\nselect 1 c\n\"\"\"\n\nschema_yml = \"\"\"\n# models/schema.yml\nmodels:\n  - name: foo\n    latest_version: 1\n    versions:\n      - v: 1\n      - v: 2\n\"\"\"\n\nfoo_yml = \"\"\"\n# models/foo.yml\nmodels:\n  - name: foo\n\"\"\"\n\nbar_yml = \"\"\"\n# models/bar.yml\nmodels:\n  - name: bar\n    columns:\n      - name: c\n        tests:\n          - relationships:\n              to: ref('foo')\n              field: c\n\"\"\"\n\nfoo_alt_yml = \"\"\"\n# models/foo.yml\nmodels:\n  - name: foo\n    latest_version: 1\n    versions:\n      - v: 1\n      - v: 2\n\"\"\"\n\n\nclass TestNewVersionedSchemaFile:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"foo.sql\": foo_sql,\n            \"bar.sql\": bar_with_ref_sql,\n        }\n\n    def test_schema_file_order_new_versions(self, project):\n        # This tests that when a model referring to an existing model\n        # which has had a version added in a yaml file has been re-parsed\n        # in order to fix the depends_on to the correct versioned model\n\n        # initial run\n        results = run_dbt([\"compile\"])\n        assert len(results) == 2\n\n        write_file(foo_v2_sql, project.project_root, \"models\", \"foo_v2.sql\")\n        write_file(schema_yml, project.project_root, \"models\", \"schema.yml\")\n\n        results = run_dbt([\"compile\"])\n\n\nclass TestMoreNewVersionedSchemaFile:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"foo.sql\": foo_sql,\n            \"bar.sql\": bar_sql,\n            \"foo.yml\": foo_yml,\n            \"bar.yml\": bar_yml,\n        }\n\n    def test_more_schema_file_new_versions(self, project):\n\n        # initial run\n        results = run_dbt([\"compile\"])\n        assert len(results) == 3\n\n        rm_file(project.project_root, \"models\", \"foo.sql\")\n        write_file(foo_sql, project.project_root, \"models\", \"foo_v1.sql\")\n        write_file(foo_sql, project.project_root, \"models\", \"foo_v2.sql\")\n        write_file(foo_alt_yml, project.project_root, \"models\", \"foo.yml\")\n\n        results = run_dbt([\"compile\"])\n\n\nsources_yml = \"\"\"\nsources:\n  - name: top_source\n    tables:\n      - name: abcd\n      - name: efgh\n      - name: ijkl\n\"\"\"\n\nabcd_sql = \"\"\"\nselect * from {{ source(\"top_source\", \"abcd\") }}\n\"\"\"\n\nefgh_sql = \"\"\"\nselect * from {{ source(\"top_source\", \"efgh\") }}\n\"\"\"\n\nijkl_sql = \"\"\"\nselect * from {{ source(\"top_source\", \"ijkl\") }}\n\"\"\"\n\nmodels_yml = \"\"\"\nmodels:\n  - name: abcd\n    description: \"abcd model\"\n    versions:\n      - v: 1\n  - name: efgh\n    description: \"efgh model\"\n    versions:\n      - v: 1\n  - name: ijkl\n    description: \"ijkl model\"\n    versions:\n      - v: 1\n\"\"\"\n\nappend_sources_yml = \"\"\"\n      - name: mnop\n\"\"\"\n\nappend_models_yml = \"\"\"\n  - name: mnop\n    description: \"mnop model\"\n    versions:\n      - v: 1\n\"\"\"\n\nmnop_sql = \"\"\"\nselect * from {{ source(\"top_source\", \"mnop\") }}\n\"\"\"\n\n\nclass TestSourcesAndSchemaFiles:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"sources.yml\": sources_yml,\n            \"abcd_v1.sql\": abcd_sql,\n            \"efgh_v1.sql\": efgh_sql,\n            \"ijkl_v1.sql\": ijkl_sql,\n            \"_models.yml\": models_yml,\n        }\n\n    def test_schema_file_order_new_versions(self, project):\n\n        # initial run\n        manifest = run_dbt([\"parse\"])\n        assert len(manifest.nodes) == 3\n\n        write_file(models_yml + append_models_yml, project.project_root, \"models\", \"_models.yml\")\n        write_file(mnop_sql, project.project_root, \"models\", \"mnop_v1.sql\")\n        write_file(sources_yml + append_sources_yml, project.project_root, \"models\", \"sources.yml\")\n\n        manifest = run_dbt([\"parse\"])\n        assert len(manifest.nodes) == 4\n\n        # Without the fix the three original nodes will all be missing the\n        # the patch updates, including description, so description will be \"\"\n        for node in manifest.nodes.values():\n            assert node.description == f\"{node.name} model\"\n            assert node.unique_id.endswith(\".v1\")\n"
  },
  {
    "path": "tests/functional/partial_parsing/test_pp_semantic_models.py",
    "content": ""
  },
  {
    "path": "tests/functional/partial_parsing/test_pp_undefined_serialization.py",
    "content": "\"\"\"\nFunctional tests for handling jinja2.Undefined objects during manifest msgpack\nserialization (write_manifest_for_partial_parse).\n\nReproduces: TypeError: can not serialize 'Undefined' object\nThe fix adds isinstance(obj, jinja2.Undefined) -> None handling to\nextended_msgpack_encoder in core/dbt/parser/manifest.py.\n\"\"\"\n\nimport pytest\n\nfrom dbt.tests.util import get_manifest, run_dbt, write_file\n\n# A model whose meta references a Jinja variable that is not in the schema\n# rendering context.  The SchemaYamlRenderer renders these values with\n# native=True, so the result is a raw jinja2.Undefined object stored in the\n# node's meta dict rather than a string.\nmodel_with_undefined_meta_sql = \"\"\"\nselect 1 as id\n\"\"\"\n\n# The value \"{{ undefined_jinja_var }}\" is NOT in the schema YAML rendering\n# context, so it evaluates to jinja2.Undefined and ends up stored in the\n# manifest node's meta dict.\nschema_with_undefined_meta_yml = \"\"\"\nversion: 2\n\nmodels:\n  - name: model_with_undefined_meta\n    meta:\n      key: \"{{ undefined_jinja_var }}\"\n\"\"\"\n\n\nclass TestUndefinedMetaSerializationInPartialParse:\n    \"\"\"\n    When a schema.yml meta value resolves to jinja2.Undefined during parse\n    time, write_manifest_for_partial_parse must not raise TypeError.\n    Without the fix (the isinstance(obj, jinja2.Undefined) branch in\n    extended_msgpack_encoder), this test fails with:\n        TypeError: can not serialize 'Undefined' object\n    \"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_with_undefined_meta.sql\": model_with_undefined_meta_sql,\n            \"schema.yml\": schema_with_undefined_meta_yml,\n        }\n\n    def test_parse_with_undefined_meta_does_not_raise(self, project):\n        # First parse - also triggers write_manifest_for_partial_parse which\n        # is where the TypeError would previously be raised.\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n        assert manifest is not None\n\n        # The manifest was written successfully; the model node exists.\n        assert \"model.test.model_with_undefined_meta\" in manifest.nodes\n\n        # The meta value that was jinja2.Undefined should have been serialized\n        # as None (the fix converts Undefined -> None before msgpack packing).\n        node = manifest.nodes[\"model.test.model_with_undefined_meta\"]\n        assert node.meta.get(\"key\") is None\n\n    def test_partial_parse_with_undefined_meta_does_not_raise(self, project):\n        # Write a trivial change to a different file to trigger the partial\n        # parse path, which re-invokes write_manifest_for_partial_parse.\n        write_file(\n            model_with_undefined_meta_sql + \"\\n-- trigger partial reparse\\n\",\n            project.project_root,\n            \"models\",\n            \"model_with_undefined_meta.sql\",\n        )\n        run_dbt([\"--partial-parse\", \"parse\"])\n        manifest = get_manifest(project.project_root)\n        assert manifest is not None\n        assert \"model.test.model_with_undefined_meta\" in manifest.nodes\n"
  },
  {
    "path": "tests/functional/partial_parsing/test_pp_vars.py",
    "content": "import os\nfrom pathlib import Path\n\nimport pytest\n\nfrom dbt.adapters.exceptions import FailedToConnectError\nfrom dbt.exceptions import ParsingError\nfrom dbt.tests.util import get_manifest, run_dbt, run_dbt_and_capture, write_file\nfrom dbt_common.constants import SECRET_ENV_PREFIX\nfrom tests.functional.partial_parsing.fixtures import (\n    env_var_macro_sql,\n    env_var_macros_yml,\n    env_var_metrics_yml,\n    env_var_model_one_sql,\n    env_var_model_sql,\n    env_var_model_test_yml,\n    env_var_schema2_yml,\n    env_var_schema3_yml,\n    env_var_schema_yml,\n    env_var_sources_yml,\n    metricflow_time_spine_sql,\n    model_color_sql,\n    model_one_sql,\n    people_semantic_models_yml,\n    people_sql,\n    raw_customers_csv,\n    test_color_sql,\n)\n\nos.environ[\"DBT_PP_TEST\"] = \"true\"\n\n\nclass TestEnvVars:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_color.sql\": model_color_sql,\n        }\n\n    def test_env_vars_models(self, project):\n\n        # initial run\n        results = run_dbt([\"run\"])\n        assert len(results) == 1\n\n        # copy a file with an env_var call without an env_var\n        write_file(env_var_model_sql, project.project_root, \"models\", \"env_var_model.sql\")\n        with pytest.raises(ParsingError):\n            results = run_dbt([\"--partial-parse\", \"run\"])\n\n        # set the env var\n        os.environ[\"ENV_VAR_TEST\"] = \"TestingEnvVars\"\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 2\n        manifest = get_manifest(project.project_root)\n        expected_env_vars = {\"ENV_VAR_TEST\": \"TestingEnvVars\"}\n        assert expected_env_vars == manifest.env_vars\n        model_id = \"model.test.env_var_model\"\n        model = manifest.nodes[model_id]\n        model_created_at = model.created_at\n\n        # change the env var\n        os.environ[\"ENV_VAR_TEST\"] = \"second\"\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 2\n        manifest = get_manifest(project.project_root)\n        expected_env_vars = {\"ENV_VAR_TEST\": \"second\"}\n        assert expected_env_vars == manifest.env_vars\n        assert model_created_at != manifest.nodes[model_id].created_at\n\n        # set an env_var in a schema file\n        write_file(env_var_schema_yml, project.project_root, \"models\", \"schema.yml\")\n        write_file(env_var_model_one_sql, project.project_root, \"models\", \"model_one.sql\")\n        with pytest.raises(ParsingError):\n            results = run_dbt([\"--partial-parse\", \"run\"])\n\n        # actually set the env_var\n        os.environ[\"TEST_SCHEMA_VAR\"] = \"view\"\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        manifest = get_manifest(project.project_root)\n        expected_env_vars = {\"ENV_VAR_TEST\": \"second\", \"TEST_SCHEMA_VAR\": \"view\"}\n        assert expected_env_vars == manifest.env_vars\n\n        # env vars in a source\n        os.environ[\"ENV_VAR_DATABASE\"] = \"dbt\"\n        os.environ[\"ENV_VAR_SEVERITY\"] = \"warn\"\n        write_file(raw_customers_csv, project.project_root, \"seeds\", \"raw_customers.csv\")\n        write_file(env_var_sources_yml, project.project_root, \"models\", \"sources.yml\")\n        run_dbt([\"--partial-parse\", \"seed\"])\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 3\n        manifest = get_manifest(project.project_root)\n        expected_env_vars = {\n            \"ENV_VAR_TEST\": \"second\",\n            \"TEST_SCHEMA_VAR\": \"view\",\n            \"ENV_VAR_DATABASE\": \"dbt\",\n            \"ENV_VAR_SEVERITY\": \"warn\",\n        }\n        assert expected_env_vars == manifest.env_vars\n        assert len(manifest.sources) == 1\n        source_id = \"source.test.seed_sources.raw_customers\"\n        source = manifest.sources[source_id]\n        assert source.database == \"dbt\"\n        schema_file = manifest.files[source.file_id]\n        test_id = \"test.test.source_not_null_seed_sources_raw_customers_id.e39ee7bf0d\"\n        test_node = manifest.nodes[test_id]\n        assert test_node.config.severity == \"warn\"\n\n        # Change severity env var\n        os.environ[\"ENV_VAR_SEVERITY\"] = \"error\"\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        manifest = get_manifest(project.project_root)\n        expected_env_vars = {\n            \"ENV_VAR_TEST\": \"second\",\n            \"TEST_SCHEMA_VAR\": \"view\",\n            \"ENV_VAR_DATABASE\": \"dbt\",\n            \"ENV_VAR_SEVERITY\": \"error\",\n        }\n        assert expected_env_vars == manifest.env_vars\n        source_id = \"source.test.seed_sources.raw_customers\"\n        source = manifest.sources[source_id]\n        schema_file = manifest.files[source.file_id]\n        expected_schema_file_env_vars = {\n            \"sources\": {\"seed_sources\": [\"ENV_VAR_DATABASE\", \"ENV_VAR_SEVERITY\"]}\n        }\n        assert expected_schema_file_env_vars == schema_file.env_vars\n        test_node = manifest.nodes[test_id]\n        assert test_node.config.severity == \"error\"\n\n        # Change database env var\n        os.environ[\"ENV_VAR_DATABASE\"] = \"test_dbt\"\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        manifest = get_manifest(project.project_root)\n        expected_env_vars = {\n            \"ENV_VAR_TEST\": \"second\",\n            \"TEST_SCHEMA_VAR\": \"view\",\n            \"ENV_VAR_DATABASE\": \"test_dbt\",\n            \"ENV_VAR_SEVERITY\": \"error\",\n        }\n        assert expected_env_vars == manifest.env_vars\n        source = manifest.sources[source_id]\n        assert source.database == \"test_dbt\"\n\n        # Delete database env var\n        del os.environ[\"ENV_VAR_DATABASE\"]\n        with pytest.raises(ParsingError):\n            results = run_dbt([\"--partial-parse\", \"run\"])\n        os.environ[\"ENV_VAR_DATABASE\"] = \"test_dbt\"\n\n        # Add generic test with test kwarg that's rendered late (no curly brackets)\n        os.environ[\"ENV_VAR_DATABASE\"] = \"dbt\"\n        write_file(test_color_sql, project.project_root, \"macros\", \"test_color.sql\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        # Add source test using test_color and an env_var for color\n        write_file(env_var_schema2_yml, project.project_root, \"models/schema.yml\")\n        with pytest.raises(ParsingError):\n            results = run_dbt([\"--partial-parse\", \"run\"])\n        os.environ[\"ENV_VAR_COLOR\"] = \"green\"\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        manifest = get_manifest(project.project_root)\n        test_color_id = \"test.test.check_color_model_one_env_var_ENV_VAR_COLOR___fun.89638de387\"\n        test_node = manifest.nodes[test_color_id]\n        # kwarg was rendered but not changed (it will be rendered again when compiled)\n        assert test_node.test_metadata.kwargs[\"color\"] == \"env_var('ENV_VAR_COLOR')\"\n        results = run_dbt([\"--partial-parse\", \"test\"])\n\n        # Add an exposure with an env_var\n        os.environ[\"ENV_VAR_OWNER\"] = \"John Doe\"\n        write_file(env_var_schema3_yml, project.project_root, \"models\", \"schema.yml\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        manifest = get_manifest(project.project_root)\n        expected_env_vars = {\n            \"ENV_VAR_TEST\": \"second\",\n            \"TEST_SCHEMA_VAR\": \"view\",\n            \"ENV_VAR_DATABASE\": \"dbt\",\n            \"ENV_VAR_SEVERITY\": \"error\",\n            \"ENV_VAR_COLOR\": \"green\",\n            \"ENV_VAR_OWNER\": \"John Doe\",\n        }\n        assert expected_env_vars == manifest.env_vars\n        exposure = list(manifest.exposures.values())[0]\n        schema_file = manifest.files[exposure.file_id]\n        expected_sf_env_vars = {\n            \"models\": {\"model_one\": [\"TEST_SCHEMA_VAR\", \"ENV_VAR_COLOR\"]},\n            \"exposures\": {\"proxy_for_dashboard\": [\"ENV_VAR_OWNER\"]},\n        }\n        assert expected_sf_env_vars == schema_file.env_vars\n\n        # add a macro and a macro schema file\n        os.environ[\"ENV_VAR_SOME_KEY\"] = \"toodles\"\n        write_file(env_var_macro_sql, project.project_root, \"macros\", \"env_var_macro.sql\")\n        write_file(env_var_macros_yml, project.project_root, \"macros\", \"env_var_macros.yml\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        manifest = get_manifest(project.project_root)\n        expected_env_vars = {\n            \"ENV_VAR_TEST\": \"second\",\n            \"TEST_SCHEMA_VAR\": \"view\",\n            \"ENV_VAR_DATABASE\": \"dbt\",\n            \"ENV_VAR_SEVERITY\": \"error\",\n            \"ENV_VAR_COLOR\": \"green\",\n            \"ENV_VAR_OWNER\": \"John Doe\",\n            \"ENV_VAR_SOME_KEY\": \"toodles\",\n        }\n        assert expected_env_vars == manifest.env_vars\n        macro_id = \"macro.test.do_something\"\n        macro = manifest.macros[macro_id]\n        assert macro.meta == {\"some_key\": \"toodles\"}\n        # change the env var\n        os.environ[\"ENV_VAR_SOME_KEY\"] = \"dumdedum\"\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        manifest = get_manifest(project.project_root)\n        macro = manifest.macros[macro_id]\n        assert macro.meta == {\"some_key\": \"dumdedum\"}\n\n        # Add a schema file with a test on model_color and env_var in test enabled config\n        write_file(env_var_model_test_yml, project.project_root, \"models\", \"schema.yml\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 3\n        manifest = get_manifest(project.project_root)\n        model_color = manifest.nodes[\"model.test.model_color\"]\n        schema_file = manifest.files[model_color.patch_path]\n        expected_env_vars = {\n            \"models\": {\n                \"model_one\": [\"TEST_SCHEMA_VAR\", \"ENV_VAR_COLOR\"],\n                \"model_color\": [\"ENV_VAR_ENABLED\"],\n            },\n            \"exposures\": {\"proxy_for_dashboard\": [\"ENV_VAR_OWNER\"]},\n        }\n        assert expected_env_vars == schema_file.env_vars\n\n        # Add a metrics file with env_vars\n        os.environ[\"ENV_VAR_METRICS\"] = \"TeStInG\"\n        write_file(people_sql, project.project_root, \"models\", \"people.sql\")\n        write_file(\n            metricflow_time_spine_sql, project.project_root, \"models\", \"metricflow_time_spine.sql\"\n        )\n        write_file(\n            people_semantic_models_yml, project.project_root, \"models\", \"semantic_models.yml\"\n        )\n        write_file(env_var_metrics_yml, project.project_root, \"models\", \"metrics.yml\")\n        results = run_dbt([\"run\"])\n        manifest = get_manifest(project.project_root)\n        assert \"ENV_VAR_METRICS\" in manifest.env_vars\n        assert manifest.env_vars[\"ENV_VAR_METRICS\"] == \"TeStInG\"\n        metric_node = manifest.metrics[\"metric.test.number_of_people\"]\n        assert metric_node.meta == {\"my_meta\": \"TeStInG\"}\n\n        # Change metrics env var\n        os.environ[\"ENV_VAR_METRICS\"] = \"Changed!\"\n        results = run_dbt([\"run\"])\n        manifest = get_manifest(project.project_root)\n        metric_node = manifest.metrics[\"metric.test.number_of_people\"]\n        assert metric_node.meta == {\"my_meta\": \"Changed!\"}\n\n        # delete the env vars to cleanup\n        del os.environ[\"ENV_VAR_TEST\"]\n        del os.environ[\"ENV_VAR_SEVERITY\"]\n        del os.environ[\"ENV_VAR_DATABASE\"]\n        del os.environ[\"TEST_SCHEMA_VAR\"]\n        del os.environ[\"ENV_VAR_COLOR\"]\n        del os.environ[\"ENV_VAR_SOME_KEY\"]\n        del os.environ[\"ENV_VAR_OWNER\"]\n        del os.environ[\"ENV_VAR_METRICS\"]\n\n\nclass TestProjectEnvVars:\n    @pytest.fixture(scope=\"class\")\n    def environment(self):\n        custom_env = os.environ.copy()\n        custom_env[\"ENV_VAR_NAME\"] = \"Jane Smith\"\n        return custom_env\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        # Need to set the environment variable here initially because\n        # the project fixture loads the config.\n        return {\"models\": {\"+meta\": {\"meta_name\": \"{{ env_var('ENV_VAR_NAME') }}\"}}}\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_one.sql\": model_one_sql,\n        }\n\n    def test_project_env_vars(self, project):\n        # Initial run\n        os.environ[\"ENV_VAR_NAME\"] = \"Jane Smith\"\n        results = run_dbt([\"run\"])\n        assert len(results) == 1\n        manifest = get_manifest(project.project_root)\n        state_check = manifest.state_check\n        model_id = \"model.test.model_one\"\n        model = manifest.nodes[model_id]\n        assert model.config.meta[\"meta_name\"] == \"Jane Smith\"\n        env_vars_hash_checksum = state_check.project_env_vars_hash.checksum\n\n        # Change the environment variable\n        os.environ[\"ENV_VAR_NAME\"] = \"Jane Doe\"\n        results = run_dbt([\"run\"])\n        assert len(results) == 1\n        manifest = get_manifest(project.project_root)\n        model = manifest.nodes[model_id]\n        assert model.config.meta[\"meta_name\"] == \"Jane Doe\"\n        assert env_vars_hash_checksum != manifest.state_check.project_env_vars_hash.checksum\n\n        # cleanup\n        del os.environ[\"ENV_VAR_NAME\"]\n\n\nclass TestProfileEnvVars:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_one.sql\": model_one_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def environment(self):\n        custom_env = os.environ.copy()\n        custom_env[\"ENV_VAR_HOST\"] = \"localhost\"\n        return custom_env\n\n    @pytest.fixture(scope=\"class\")\n    def dbt_profile_target(self):\n        return {\n            \"type\": \"postgres\",\n            \"threads\": 4,\n            \"host\": \"{{ env_var('ENV_VAR_HOST') }}\",\n            \"port\": 5432,\n            \"user\": \"root\",\n            \"pass\": \"password\",\n            \"dbname\": \"dbt\",\n        }\n\n    def test_profile_env_vars(self, project, logs_dir):\n\n        # Initial run\n        os.environ[\"ENV_VAR_HOST\"] = \"localhost\"\n\n        run_dbt([\"run\"])\n\n        # Change env_vars, the user doesn't exist, this should fail\n        os.environ[\"ENV_VAR_HOST\"] = \"wrong_host\"\n\n        # N.B. run_dbt_and_capture won't work here because FailedToConnectError ends the test entirely\n        with pytest.raises(FailedToConnectError):\n            run_dbt([\"run\"], expect_pass=False)\n\n        log_output = Path(logs_dir, \"dbt.log\").read_text()\n        assert \"Unable to do partial parsing because profile has changed\" in log_output\n\n\nclass TestProfileSecretEnvVars:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_one.sql\": model_one_sql,\n        }\n\n    @property\n    def dbt_profile_target(self):\n        # Need to set these here because the base integration test class\n        # calls 'load_config' before the tests are run.\n        # Note: only the specified profile is rendered, so there's no\n        # point in setting env_vars in non-used profiles.\n\n        # user is secret and password is not. postgres on macos doesn't care if the password\n        # changes so we have to change the user. related: https://github.com/dbt-labs/dbt-core/pull/4250\n        os.environ[SECRET_ENV_PREFIX + \"_USER\"] = \"root\"\n        os.environ[\"ENV_VAR_PASS\"] = \"password\"\n        return {\n            \"type\": \"postgres\",\n            \"threads\": 4,\n            \"host\": \"localhost\",\n            \"port\": 5432,\n            \"user\": \"{{ env_var('DBT_ENV_SECRET_USER') }}\",\n            \"pass\": \"{{ env_var('ENV_VAR_PASS') }}\",\n            \"dbname\": \"dbt\",\n        }\n\n    def test_profile_secret_env_vars(self, project):\n\n        # Initial run\n        os.environ[SECRET_ENV_PREFIX + \"_USER\"] = \"root\"\n        os.environ[\"ENV_VAR_PASS\"] = \"password\"\n\n        results = run_dbt([\"run\"])\n        manifest = get_manifest(project.project_root)\n        env_vars_checksum = manifest.state_check.profile_env_vars_hash.checksum\n\n        # Change a secret var, it shouldn't register because we shouldn't save secrets.\n        os.environ[SECRET_ENV_PREFIX + \"_USER\"] = \"fake_user\"\n        # we just want to see if the manifest has included\n        # the secret in the hash of environment variables.\n        (results, log_output) = run_dbt_and_capture([\"run\"], expect_pass=True)\n        # I020 is the event code for \"env vars used in profiles.yml have changed\"\n        assert not (\"I020\" in log_output)\n        manifest = get_manifest(project.project_root)\n        assert env_vars_checksum == manifest.state_check.profile_env_vars_hash.checksum\n\n\n# Model that uses a var with a default value\nmodel_with_var_sql = \"\"\"\nselect '{{ var(\"my_var\", \"default_value\") }}' as var_value\n\"\"\"\n\n\nclass TestVarsFilePartialParsing:\n    \"\"\"Tests for partial parsing behavior when vars.yml file changes.\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_with_var.sql\": model_with_var_sql,\n        }\n\n    def test_vars_file_partial_parsing(self, project, logs_dir):\n        # Initial run without vars.yml - uses default value\n        results = run_dbt([\"run\"])\n        assert len(results) == 1\n        manifest = get_manifest(project.project_root)\n        initial_vars_hash = manifest.state_check.vars_hash.checksum\n\n        # Add vars.yml file - should trigger full reparse\n        vars_yml_content = \"\"\"\nvars:\n  my_var: \"from_vars_file\"\n\"\"\"\n        write_file(vars_yml_content, project.project_root, \"vars.yml\")\n        (results, log_output) = run_dbt_and_capture([\"--partial-parse\", \"run\"])\n        assert len(results) == 1\n        assert \"Unable to do partial parsing\" in log_output\n\n        manifest = get_manifest(project.project_root)\n        current_vars_hash = manifest.state_check.vars_hash.checksum\n        assert current_vars_hash != initial_vars_hash\n\n        # Run again with no changes - should use partial parsing (no reparse message)\n        (results, log_output) = run_dbt_and_capture([\"--partial-parse\", \"run\"])\n        assert len(results) == 1\n        assert \"Unable to do partial parsing\" not in log_output\n\n        manifest = get_manifest(project.project_root)\n        previous_vars_hash = current_vars_hash\n        current_vars_hash = manifest.state_check.vars_hash.checksum\n        assert current_vars_hash == previous_vars_hash\n\n        # Modify vars.yml - should trigger full reparse\n        vars_yml_content_modified = \"\"\"\nvars:\n  my_var: \"modified_value\"\n\"\"\"\n        write_file(vars_yml_content_modified, project.project_root, \"vars.yml\")\n        (results, log_output) = run_dbt_and_capture([\"--partial-parse\", \"run\"])\n        assert len(results) == 1\n        assert \"Unable to do partial parsing\" in log_output\n\n        manifest = get_manifest(project.project_root)\n        previous_vars_hash = current_vars_hash\n        current_vars_hash = manifest.state_check.vars_hash.checksum\n\n        assert previous_vars_hash != current_vars_hash\n\n        # Delete vars.yml - should trigger full reparse\n        os.remove(os.path.join(project.project_root, \"vars.yml\"))\n        (results, log_output) = run_dbt_and_capture([\"--partial-parse\", \"run\"])\n        assert len(results) == 1\n        assert \"Unable to do partial parsing\" in log_output\n\n        manifest = get_manifest(project.project_root)\n        previous_vars_hash = current_vars_hash\n        current_vars_hash = manifest.state_check.vars_hash.checksum\n\n        assert previous_vars_hash != current_vars_hash\n\n\nclass TestVarsFileBackwardCompatibility:\n    \"\"\"Tests that users not using vars.yml are unaffected by the feature.\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_one.sql\": model_one_sql,\n        }\n\n    def test_no_vars_file_hash_unchanged(self, project):\n        # First run - no vars.yml\n        results, output = run_dbt_and_capture([\"run\"])\n        assert len(results) == 1\n\n        # Second run - still no vars.yml, hash should remain empty\n        results, output = run_dbt_and_capture([\"--partial-parse\", \"run\"])\n        assert len(results) == 1\n        assert \"Unable to do partial parsing\" not in output\n\n    def test_cli_vars_still_trigger_reparse(self, project, logs_dir):\n        # First run with no CLI vars\n        results = run_dbt([\"run\"])\n        assert len(results) == 1\n        manifest = get_manifest(project.project_root)\n        initial_vars_hash = manifest.state_check.vars_hash.checksum\n\n        # Second run with CLI vars - should trigger reparse due to vars_hash change\n        (results, log_output) = run_dbt_and_capture(\n            [\n                \"--partial-parse\",\n                \"run\",\n                \"--vars\",\n                '{\"cli_var\": \"value\"}',\n            ]\n        )\n        assert len(results) == 1\n        assert \"Unable to do partial parsing\" in log_output\n\n        manifest = get_manifest(project.project_root)\n        assert manifest.state_check.vars_hash.checksum != initial_vars_hash\n"
  },
  {
    "path": "tests/functional/partial_parsing/test_versioned_models.py",
    "content": "import pathlib\nfrom typing import Dict\n\nimport pytest\n\nfrom dbt.exceptions import DuplicateVersionedUnversionedError\nfrom dbt.tests.util import get_manifest, read_file, rm_file, run_dbt, write_file\n\nmodel_one_sql = \"\"\"\nselect 1 as fun\n\"\"\"\n\nmodel_one_downstream_sql = \"\"\"\nselect fun from {{ ref('model_one') }}\n\"\"\"\n\nmodels_versions_schema_yml = \"\"\"\n\nmodels:\n    - name: model_one\n      description: \"The first model\"\n      versions:\n        - v: 1\n        - v: 2\n\"\"\"\n\nmodels_versions_defined_in_schema_yml = \"\"\"\nmodels:\n    - name: model_one\n      description: \"The first model\"\n      versions:\n        - v: 1\n        - v: 2\n          defined_in: model_one_different\n\"\"\"\n\nmodels_versions_updated_schema_yml = \"\"\"\nmodels:\n    - name: model_one\n      latest_version: 1\n      description: \"The first model\"\n      versions:\n        - v: 1\n        - v: 2\n          defined_in: model_one_different\n\"\"\"\n\nmodel_two_sql = \"\"\"\nselect 1 as notfun\n\"\"\"\n\n\nclass TestVersionedModels:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_one_v1.sql\": model_one_sql,\n            \"model_one.sql\": model_one_sql,\n            \"model_one_downstream.sql\": model_one_downstream_sql,\n            \"schema.yml\": models_versions_schema_yml,\n        }\n\n    def test_pp_versioned_models(self, project):\n        results = run_dbt([\"run\"])\n        assert len(results) == 3\n\n        manifest = get_manifest(project.project_root)\n        model_one_node = manifest.nodes[\"model.test.model_one.v1\"]\n        assert not model_one_node.is_latest_version\n        model_two_node = manifest.nodes[\"model.test.model_one.v2\"]\n        assert model_two_node.is_latest_version\n        # assert unpinned ref points to latest version\n        model_one_downstream_node = manifest.nodes[\"model.test.model_one_downstream\"]\n        assert model_one_downstream_node.depends_on.nodes == [\"model.test.model_one.v2\"]\n\n        # update schema.yml block - model_one is now 'defined_in: model_one_different'\n        rm_file(project.project_root, \"models\", \"model_one.sql\")\n        write_file(model_one_sql, project.project_root, \"models\", \"model_one_different.sql\")\n        write_file(\n            models_versions_defined_in_schema_yml, project.project_root, \"models\", \"schema.yml\"\n        )\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 3\n\n        # update versions schema.yml block - latest_version from 2 to 1\n        write_file(\n            models_versions_updated_schema_yml, project.project_root, \"models\", \"schema.yml\"\n        )\n        # This is where the test was failings in a CI run with:\n        # relation \\\"test..._test_partial_parsing.model_one_downstream\\\" does not exist\n        # because in core/dbt/include/global_project/macros/materializations/models/view/view.sql\n        # \"existing_relation\" didn't actually exist by the time it gets to the rename of the\n        # existing relation.\n        (pathlib.Path(project.project_root) / \"log_output\").mkdir(parents=True, exist_ok=True)\n        results = run_dbt(\n            [\"--partial-parse\", \"--log-format-file\", \"json\", \"--log-path\", \"log_output\", \"run\"]\n        )\n        assert len(results) == 3\n\n        manifest = get_manifest(project.project_root)\n        model_one_node = manifest.nodes[\"model.test.model_one.v1\"]\n        assert model_one_node.is_latest_version\n        model_two_node = manifest.nodes[\"model.test.model_one.v2\"]\n        assert not model_two_node.is_latest_version\n        # assert unpinned ref points to latest version\n        model_one_downstream_node = manifest.nodes[\"model.test.model_one_downstream\"]\n        assert model_one_downstream_node.depends_on.nodes == [\"model.test.model_one.v1\"]\n\n        # assert unpinned ref to latest-not-max version yields an \"FYI\" info-level log\n        log_output = read_file(\"log_output\", \"dbt.log\").replace(\"\\n\", \" \").replace(\"\\\\n\", \" \")\n        assert \"UnpinnedRefNewVersionAvailable\" in log_output\n\n        # update versioned model\n        write_file(model_two_sql, project.project_root, \"models\", \"model_one_different.sql\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 3\n        manifest = get_manifest(project.project_root)\n        assert len(manifest.nodes) == 3\n\n        # create a new model_one in model_one.sql and re-parse\n        write_file(model_one_sql, project.project_root, \"models\", \"model_one.sql\")\n        with pytest.raises(DuplicateVersionedUnversionedError):\n            run_dbt([\"parse\"])\n\n\nmodel_unversioned_schema_yml = \"\"\"\nmodels:\n    - name: model_one\n      description: \"The first model\"\n\"\"\"\n\n\nmodel_versioned_schema_yml = \"\"\"\nmodels:\n    - name: model_one\n      description: \"The first model\"\n      latest_version: 1\n      versions:\n        - v: 1\n\"\"\"\n\n\nclass TestAddingVersioningToModel:\n    @pytest.fixture(scope=\"class\")\n    def models(self) -> Dict[str, str]:\n        return {\n            \"model_one.sql\": model_one_sql,\n            \"model_one_downstream.sql\": model_one_downstream_sql,\n            \"schema.yml\": model_unversioned_schema_yml,\n        }\n\n    def test_pp_newly_versioned_models(self, project) -> None:\n        results = run_dbt([\"run\"])\n        assert len(results) == 2\n\n        # update schema.yml block - model_one is now versioned\n        write_file(model_versioned_schema_yml, project.project_root, \"models\", \"schema.yml\")\n        results = run_dbt([\"--partial-parse\", \"run\"])\n        assert len(results) == 2\n"
  },
  {
    "path": "tests/functional/permission/data/seed.sql",
    "content": "\ncreate schema if not exists {schema};\n\nrevoke create on database dbt from noaccess;\nrevoke usage on schema {schema} from noaccess;\n\ncreate table {schema}.seed (\n\tid BIGSERIAL PRIMARY KEY,\n\tfirst_name VARCHAR(50),\n\tlast_name VARCHAR(50),\n\temail VARCHAR(50),\n\tgender VARCHAR(50),\n\tip_address VARCHAR(20)\n);\n\n\ninsert into {schema}.seed (first_name, last_name, email, gender, ip_address) values ('Kathryn', 'Walker', 'kwalker1@ezinearticles.com', 'Female', '194.121.179.35');\ninsert into {schema}.seed (first_name, last_name, email, gender, ip_address) values ('Gerald', 'Ryan', 'gryan2@com.com', 'Male', '11.3.212.243');\ninsert into {schema}.seed (first_name, last_name, email, gender, ip_address) values ('Bonnie', 'Spencer', 'bspencer3@ameblo.jp', 'Female', '216.32.196.175');\ninsert into {schema}.seed (first_name, last_name, email, gender, ip_address) values ('Harold', 'Taylor', 'htaylor4@people.com.cn', 'Male', '253.10.246.136');\ninsert into {schema}.seed (first_name, last_name, email, gender, ip_address) values ('Jacqueline', 'Griffin', 'jgriffin5@t.co', 'Female', '16.13.192.220');\ninsert into {schema}.seed (first_name, last_name, email, gender, ip_address) values ('Wanda', 'Arnold', 'warnold6@google.nl', 'Female', '232.116.150.64');\ninsert into {schema}.seed (first_name, last_name, email, gender, ip_address) values ('Craig', 'Ortiz', 'cortiz7@sciencedaily.com', 'Male', '199.126.106.13');\ninsert into {schema}.seed (first_name, last_name, email, gender, ip_address) values ('Gary', 'Day', 'gday8@nih.gov', 'Male', '35.81.68.186');\ninsert into {schema}.seed (first_name, last_name, email, gender, ip_address) values ('Rose', 'Wright', 'rwright9@yahoo.co.jp', 'Female', '236.82.178.100');\ninsert into {schema}.seed (first_name, last_name, email, gender, ip_address) values ('Raymond', 'Kelley', 'rkelleya@fc2.com', 'Male', '213.65.166.67');\n"
  },
  {
    "path": "tests/functional/permission/fixtures.py",
    "content": "import pytest\n\nfrom dbt.tests.fixtures.project import write_project_files\n\nmodels__view_model_sql = \"\"\"\n\nselect * from {{ this.schema }}.seed\n\n\"\"\"\n\n\n@pytest.fixture(scope=\"class\")\ndef models():\n    return {\"view_model.sql\": models__view_model_sql}\n\n\n@pytest.fixture(scope=\"class\")\ndef project_files(\n    project_root,\n    models,\n):\n    write_project_files(project_root, \"models\", models)\n"
  },
  {
    "path": "tests/functional/postgres/fixtures.py",
    "content": "models__incremental_sql = \"\"\"\n{{\n  config(\n    materialized = \"incremental\",\n    indexes=[\n      {'columns': ['column_a'], 'type': 'hash'},\n      {'columns': ['column_a', 'column_b'], 'unique': True},\n    ]\n  )\n}}\n\nselect *\nfrom (\n  select 1 as column_a, 2 as column_b\n) t\n\n{% if is_incremental() %}\n    where column_a > (select max(column_a) from {{this}})\n{% endif %}\n\n\"\"\"\n\nmodels__table_sql = \"\"\"\n{{\n  config(\n    materialized = \"table\",\n    indexes=[\n      {'columns': ['column_a']},\n      {'columns': ['column_b']},\n      {'columns': ['column_a', 'column_b']},\n      {'columns': ['column_b', 'column_a'], 'type': 'btree', 'unique': True},\n      {'columns': ['column_a'], 'type': 'hash'}\n    ]\n  )\n}}\n\nselect 1 as column_a, 2 as column_b\n\n\"\"\"\n\nmodels_invalid__invalid_columns_type_sql = \"\"\"\n{{\n  config(\n    materialized = \"table\",\n    indexes=[\n      {'columns': 'column_a, column_b'},\n    ]\n  )\n}}\n\nselect 1 as column_a, 2 as column_b\n\n\"\"\"\n\nmodels_invalid__invalid_type_sql = \"\"\"\n{{\n  config(\n    materialized = \"table\",\n    indexes=[\n      {'columns': ['column_a'], 'type': 'non_existent_type'},\n    ]\n  )\n}}\n\nselect 1 as column_a, 2 as column_b\n\n\"\"\"\n\nmodels_invalid__invalid_unique_config_sql = \"\"\"\n{{\n  config(\n    materialized = \"table\",\n    indexes=[\n      {'columns': ['column_a'], 'unique': 'yes'},\n    ]\n  )\n}}\n\nselect 1 as column_a, 2 as column_b\n\n\"\"\"\n\nmodels_invalid__missing_columns_sql = \"\"\"\n{{\n  config(\n    materialized = \"table\",\n    indexes=[\n      {'unique': True},\n    ]\n  )\n}}\n\nselect 1 as column_a, 2 as column_b\n\n\"\"\"\n\nsnapshots__colors_sql = \"\"\"\n{% snapshot colors %}\n\n    {{\n        config(\n            target_database=database,\n            target_schema=schema,\n            unique_key='id',\n            strategy='check',\n            check_cols=['color'],\n            indexes=[\n              {'columns': ['id'], 'type': 'hash'},\n              {'columns': ['id', 'color'], 'unique': True},\n            ]\n        )\n    }}\n\n    {% if var('version') == 1 %}\n\n        select 1 as id, 'red' as color union all\n        select 2 as id, 'green' as color\n\n    {% else %}\n\n        select 1 as id, 'blue' as color union all\n        select 2 as id, 'green' as color\n\n    {% endif %}\n\n{% endsnapshot %}\n\n\"\"\"\n\nseeds__seed_csv = \"\"\"country_code,country_name\nUS,United States\nCA,Canada\nGB,United Kingdom\n\"\"\"\n"
  },
  {
    "path": "tests/functional/postgres/test_postgres_indexes.py",
    "content": "import re\n\nimport pytest\n\nfrom dbt.tests.util import run_dbt, run_dbt_and_capture\nfrom tests.functional.postgres.fixtures import (\n    models__incremental_sql,\n    models__table_sql,\n    models_invalid__invalid_columns_type_sql,\n    models_invalid__invalid_type_sql,\n    models_invalid__invalid_unique_config_sql,\n    models_invalid__missing_columns_sql,\n    seeds__seed_csv,\n    snapshots__colors_sql,\n)\n\nINDEX_DEFINITION_PATTERN = re.compile(r\"using\\s+(\\w+)\\s+\\((.+)\\)\\Z\")\n\n\nclass TestPostgresIndex:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"table.sql\": models__table_sql,\n            \"incremental.sql\": models__incremental_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\"seed.csv\": seeds__seed_csv}\n\n    @pytest.fixture(scope=\"class\")\n    def snapshots(self):\n        return {\"colors.sql\": snapshots__colors_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"config-version\": 2,\n            \"seeds\": {\n                \"quote_columns\": False,\n                \"indexes\": [\n                    {\"columns\": [\"country_code\"], \"unique\": False, \"type\": \"hash\"},\n                    {\"columns\": [\"country_code\", \"country_name\"], \"unique\": True},\n                ],\n            },\n            \"vars\": {\n                \"version\": 1,\n            },\n        }\n\n    def test_table(self, project, unique_schema):\n        results = run_dbt([\"run\", \"--models\", \"table\"])\n        assert len(results) == 1\n\n        indexes = self.get_indexes(\"table\", project, unique_schema)\n        expected = [\n            {\"columns\": \"column_a\", \"unique\": False, \"type\": \"btree\"},\n            {\"columns\": \"column_b\", \"unique\": False, \"type\": \"btree\"},\n            {\"columns\": \"column_a, column_b\", \"unique\": False, \"type\": \"btree\"},\n            {\"columns\": \"column_b, column_a\", \"unique\": True, \"type\": \"btree\"},\n            {\"columns\": \"column_a\", \"unique\": False, \"type\": \"hash\"},\n        ]\n        assert len(indexes) == len(expected)\n\n    def test_incremental(self, project, unique_schema):\n        for additional_argument in [[], [], [\"--full-refresh\"]]:\n            results = run_dbt([\"run\", \"--models\", \"incremental\"] + additional_argument)\n            assert len(results) == 1\n\n            indexes = self.get_indexes(\"incremental\", project, unique_schema)\n            expected = [\n                {\"columns\": \"column_a\", \"unique\": False, \"type\": \"hash\"},\n                {\"columns\": \"column_a, column_b\", \"unique\": True, \"type\": \"btree\"},\n            ]\n            assert len(indexes) == len(expected)\n\n    def test_seed(self, project, unique_schema):\n        for additional_argument in [[], [], [\"--full-refresh\"]]:\n            results = run_dbt([\"seed\"] + additional_argument)\n            assert len(results) == 1\n\n            indexes = self.get_indexes(\"seed\", project, unique_schema)\n            expected = [\n                {\"columns\": \"country_code\", \"unique\": False, \"type\": \"hash\"},\n                {\"columns\": \"country_code, country_name\", \"unique\": True, \"type\": \"btree\"},\n            ]\n            assert len(indexes) == len(expected)\n\n    def test_snapshot(self, project, unique_schema):\n        for version in [1, 2]:\n            results = run_dbt([\"snapshot\", \"--vars\", f\"version: {version}\"])\n            assert len(results) == 1\n\n            indexes = self.get_indexes(\"colors\", project, unique_schema)\n            expected = [\n                {\"columns\": \"id\", \"unique\": False, \"type\": \"hash\"},\n                {\"columns\": \"id, color\", \"unique\": True, \"type\": \"btree\"},\n            ]\n            assert len(indexes) == len(expected)\n\n    def get_indexes(self, table_name, project, unique_schema):\n        sql = f\"\"\"\n            SELECT\n              pg_get_indexdef(idx.indexrelid) as index_definition\n            FROM pg_index idx\n            JOIN pg_class tab ON tab.oid = idx.indrelid\n            WHERE\n              tab.relname = '{table_name}'\n              AND tab.relnamespace = (\n                SELECT oid FROM pg_namespace WHERE nspname = '{unique_schema}'\n              );\n        \"\"\"\n        results = project.run_sql(sql, fetch=\"all\")\n        return [self.parse_index_definition(row[0]) for row in results]\n\n    def parse_index_definition(self, index_definition):\n        index_definition = index_definition.lower()\n        is_unique = \"unique\" in index_definition\n        m = INDEX_DEFINITION_PATTERN.search(index_definition)\n        return {\n            \"columns\": m.group(2),\n            \"unique\": is_unique,\n            \"type\": m.group(1),\n        }\n\n    def assertCountEqual(self, a, b):\n        assert len(a) == len(b)\n\n\nclass TestPostgresInvalidIndex:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"invalid_unique_config.sql\": models_invalid__invalid_unique_config_sql,\n            \"invalid_type.sql\": models_invalid__invalid_type_sql,\n            \"invalid_columns_type.sql\": models_invalid__invalid_columns_type_sql,\n            \"missing_columns.sql\": models_invalid__missing_columns_sql,\n        }\n\n    def test_invalid_index_configs(self, project):\n        results, output = run_dbt_and_capture(expect_pass=False)\n        assert len(results) == 4\n        assert re.search(r\"columns.*is not of type 'array'\", output)\n        assert re.search(r\"unique.*is not of type 'boolean'\", output)\n        assert re.search(r\"'columns' is a required property\", output)\n        assert re.search(r\"Database Error in model invalid_type\", output)\n"
  },
  {
    "path": "tests/functional/postgres/test_postgres_unlogged_table.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt\n\nschema_yml = \"\"\"\nversion: 2\nmodels:\n  - name: table_unlogged\n    description: \"Unlogged table model\"\n    columns:\n      - name: column_a\n        description: \"Sample description\"\n        quote: true\n\"\"\"\n\ntable_unlogged_sql = \"\"\"\n{{ config(materialized = 'table', unlogged = True) }}\n\nselect 1 as column_a\n\"\"\"\n\n\nclass TestPostgresUnloggedTable:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": schema_yml,\n            \"table_unlogged.sql\": table_unlogged_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"models\": {\n                \"test\": {\n                    \"materialized\": \"table\",\n                    \"+persist_docs\": {\n                        \"relation\": True,\n                        \"columns\": True,\n                    },\n                }\n            }\n        }\n\n    def test_postgres_unlogged_table_catalog(self, project):\n        table_name = \"table_unlogged\"\n\n        results = run_dbt([\"run\", \"--models\", table_name])\n        assert len(results) == 1\n\n        result = self.get_table_persistence(project, table_name)\n        assert result == \"u\"\n\n        catalog = run_dbt([\"docs\", \"generate\"])\n\n        assert len(catalog.nodes) == 1\n\n        table_node = catalog.nodes[\"model.test.table_unlogged\"]\n        assert table_node\n        assert \"column_a\" in table_node.columns\n\n    def get_table_persistence(self, project, table_name):\n        sql = \"\"\"\n            SELECT\n              relpersistence\n            FROM pg_class\n            WHERE relname = '{table_name}'\n        \"\"\"\n        sql = sql.format(table_name=table_name, schema=project.test_schema)\n        result = project.run_sql(sql, fetch=\"one\")\n        assert len(result) == 1\n\n        return result[0]\n"
  },
  {
    "path": "tests/functional/primary_keys/fixtures.py",
    "content": "simple_model_sql = \"\"\"\nselect 1 as id, 'blue' as color\n\"\"\"\n\nsimple_model_unique_test = \"\"\"\nmodels:\n  - name: simple_model\n    columns:\n      - name: id\n        tests:\n          - unique\n\"\"\"\n\ninvalid_model_unique_test = \"\"\"\nmodels:\n  - name: simple_model\n    data_tests:\n      - unique:\n          column_name: null\n    columns:\n      - name: id\n\"\"\"\n\nsimple_model_disabled_unique_test = \"\"\"\nmodels:\n  - name: simple_model\n    columns:\n      - name: id\n        tests:\n          - unique:\n              enabled: false\n\n\"\"\"\n\nsimple_model_unique_not_null_tests = \"\"\"\nmodels:\n  - name: simple_model\n    columns:\n      - name: id\n        tests:\n          - unique\n          - not_null\n\"\"\"\n\nsimple_model_unique_combo_of_columns = \"\"\"\nmodels:\n  - name: simple_model\n    tests:\n      - dbt_utils.unique_combination_of_columns:\n          combination_of_columns: [id, color]\n\"\"\"\n\ninvalid_model_unique_combo_of_columns = \"\"\"\nmodels:\n  - name: simple_model\n    tests:\n      - dbt_utils.unique_combination_of_columns:\n          combination_of_columns: [null]\n      - dbt_utils.unique_combination_of_columns:\n          combination_of_columns: \"test\"\n\"\"\"\n\nsimple_model_constraints = \"\"\"\nmodels:\n  - name: simple_model\n    config:\n      contract:\n        enforced: true\n    columns:\n      - name: id\n        data_type: int\n        constraints:\n          - type: not_null\n          - type: primary_key\n      - name: color\n        data_type: text\n\"\"\"\n\nsimple_model_two_versions_both_configured = \"\"\"\nmodels:\n  - name: simple_model\n    latest_version: 1\n    columns:\n      - name: id\n        tests:\n          - unique\n          - not_null\n    versions:\n      - v: 1\n      - v: 2\n\"\"\"\n\nsimple_model_two_versions_exclude_col = \"\"\"\nmodels:\n  - name: simple_model\n    latest_version: 1\n    columns:\n      - name: id\n        tests:\n          - unique\n          - not_null\n    versions:\n      - v: 1\n      - v: 2\n        columns:\n          - include: all\n            exclude: [id]\n\"\"\"\n"
  },
  {
    "path": "tests/functional/primary_keys/test_primary_keys.py",
    "content": "import pytest\n\nfrom dbt.tests.util import get_manifest, run_dbt\nfrom tests.functional.primary_keys.fixtures import (\n    invalid_model_unique_combo_of_columns,\n    invalid_model_unique_test,\n    simple_model_constraints,\n    simple_model_disabled_unique_test,\n    simple_model_sql,\n    simple_model_two_versions_both_configured,\n    simple_model_two_versions_exclude_col,\n    simple_model_unique_combo_of_columns,\n    simple_model_unique_not_null_tests,\n    simple_model_unique_test,\n)\n\n\nclass TestSimpleModelNoYml:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"simple_model.sql\": simple_model_sql,\n        }\n\n    def test_simple_model_no_yml(self, project):\n        run_dbt([\"deps\"])\n        run_dbt([\"run\"])\n        manifest = get_manifest(project.project_root)\n        node = manifest.nodes[\"model.test.simple_model\"]\n        assert node.primary_key == []\n\n\nclass TestSimpleModelConstraints:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"simple_model.sql\": simple_model_sql,\n            \"schema.yml\": simple_model_constraints,\n        }\n\n    def test_simple_model_constraints(self, project):\n        run_dbt([\"deps\"])\n        run_dbt([\"run\"])\n        manifest = get_manifest(project.project_root)\n        node = manifest.nodes[\"model.test.simple_model\"]\n        assert node.primary_key == [\"id\"]\n\n\nclass TestSimpleModelUniqueNotNullTests:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"simple_model.sql\": simple_model_sql,\n            \"schema.yml\": simple_model_unique_not_null_tests,\n        }\n\n    def test_simple_model_unique_not_null_tests(self, project):\n        run_dbt([\"deps\"])\n        run_dbt([\"run\"])\n        manifest = get_manifest(project.project_root)\n        node = manifest.nodes[\"model.test.simple_model\"]\n        assert node.primary_key == [\"id\"]\n\n\nclass TestSimpleModelUniqueTests:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"simple_model.sql\": simple_model_sql,\n            \"schema.yml\": simple_model_unique_test,\n        }\n\n    def test_simple_model_unique_test(self, project):\n        run_dbt([\"deps\"])\n        run_dbt([\"run\"])\n        manifest = get_manifest(project.project_root)\n        node = manifest.nodes[\"model.test.simple_model\"]\n        assert node.primary_key == [\"id\"]\n\n\nclass TestSimpleModelDisabledUniqueTests:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"simple_model.sql\": simple_model_sql,\n            \"schema.yml\": simple_model_disabled_unique_test,\n        }\n\n    def test_simple_model_disabled_unique_test(self, project):\n        run_dbt([\"deps\"])\n        run_dbt([\"run\"])\n        manifest = get_manifest(project.project_root)\n        node = manifest.nodes[\"model.test.simple_model\"]\n        assert node.primary_key == [\"id\"]\n\n\nclass TestVersionedSimpleModel:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"simple_model_v1.sql\": simple_model_sql,\n            \"simple_model_v2.sql\": simple_model_sql,\n            \"schema.yml\": simple_model_two_versions_both_configured,\n        }\n\n    def test_versioned_simple_model(self, project):\n        run_dbt([\"deps\"])\n        run_dbt([\"run\"])\n        manifest = get_manifest(project.project_root)\n        node_v1 = manifest.nodes[\"model.test.simple_model.v1\"]\n        node_v2 = manifest.nodes[\"model.test.simple_model.v2\"]\n        assert node_v1.primary_key == [\"id\"]\n        assert node_v2.primary_key == [\"id\"]\n\n\nclass TestVersionedSimpleModelExcludeTests:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"simple_model_v1.sql\": simple_model_sql,\n            \"simple_model_v2.sql\": simple_model_sql,\n            \"schema.yml\": simple_model_two_versions_exclude_col,\n        }\n\n    def test_versioned_simple_model_exclude_col(self, project):\n        run_dbt([\"deps\"])\n        run_dbt([\"run\"])\n        manifest = get_manifest(project.project_root)\n        node_v1 = manifest.nodes[\"model.test.simple_model.v1\"]\n        node_v2 = manifest.nodes[\"model.test.simple_model.v2\"]\n        assert node_v1.primary_key == [\"id\"]\n        assert node_v2.primary_key == []\n\n\nclass TestSimpleModelCombinationOfColumns:\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\n            \"packages\": [\n                {\n                    \"git\": \"https://github.com/dbt-labs/dbt-utils.git\",\n                    \"revision\": \"1.1.0\",\n                },\n            ]\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"simple_model.sql\": simple_model_sql,\n            \"schema.yml\": simple_model_unique_combo_of_columns,\n        }\n\n    def test_versioned_simple_combo_of_columns(self, project):\n        run_dbt([\"deps\"])\n        run_dbt([\"run\"])\n        manifest = get_manifest(project.project_root)\n        node = manifest.nodes[\"model.test.simple_model\"]\n        assert node.primary_key == [\"color\", \"id\"]\n\n\nclass TestInvalidModelCombinationOfColumns:\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\n            \"packages\": [\n                {\n                    \"git\": \"https://github.com/dbt-labs/dbt-utils.git\",\n                    \"revision\": \"1.1.0\",\n                },\n            ]\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"simple_model.sql\": simple_model_sql,\n            \"schema.yml\": invalid_model_unique_combo_of_columns,\n        }\n\n    def test_invalid_combo_of_columns(self, project):\n        run_dbt([\"deps\"])\n        run_dbt([\"run\"])\n        manifest = get_manifest(project.project_root)\n        node = manifest.nodes[\"model.test.simple_model\"]\n        assert node.primary_key == []\n\n\nclass TestInvalidModelUniqueTest:\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\n            \"packages\": [\n                {\n                    \"git\": \"https://github.com/dbt-labs/dbt-utils.git\",\n                    \"revision\": \"1.1.0\",\n                },\n            ]\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"simple_model.sql\": simple_model_sql,\n            \"schema.yml\": invalid_model_unique_test,\n        }\n\n    def test_invalid_combo_of_columns(self, project):\n        run_dbt([\"deps\"])\n        run_dbt([\"run\"])\n        manifest = get_manifest(project.project_root)\n        node = manifest.nodes[\"model.test.simple_model\"]\n        assert node.primary_key == []\n"
  },
  {
    "path": "tests/functional/profiles/test_profile_dir.py",
    "content": "import os\nfrom argparse import Namespace\nfrom contextlib import contextmanager\nfrom pathlib import Path\n\nimport pytest\nimport yaml\n\nimport dbt.flags as flags\nfrom dbt.tests.util import rm_file, run_dbt, run_dbt_and_capture, write_file\n\n\n@pytest.fixture(scope=\"class\")\ndef profiles_yml(profiles_root, dbt_profile_data):\n    write_file(yaml.safe_dump(dbt_profile_data), profiles_root, \"profiles.yml\")\n    return dbt_profile_data\n\n\n@pytest.fixture(scope=\"class\")\ndef profiles_home_root():\n    return os.path.join(os.path.expanduser(\"~\"), \".dbt\")\n\n\n@pytest.fixture(scope=\"class\")\ndef profiles_env_root(tmpdir_factory):\n    path = tmpdir_factory.mktemp(\"profile_env\")\n    # environment variables are lowercased for some reason in _get_flag_value_from_env within dbt.flags\n    return str(path).lower()\n\n\n@pytest.fixture(scope=\"class\")\ndef profiles_flag_root(tmpdir_factory):\n    return tmpdir_factory.mktemp(\"profile_flag\")\n\n\n@pytest.fixture(scope=\"class\")\ndef profiles_project_root(project):\n    return project.project_root\n\n\n@pytest.fixture(scope=\"class\")\ndef cwd():\n    return os.getcwd()\n\n\n@pytest.fixture(scope=\"class\")\ndef cwd_parent(cwd):\n    return os.path.dirname(cwd)\n\n\n@pytest.fixture(scope=\"class\")\ndef cwd_child():\n    # pick any child directory of the dbt project\n    return Path(os.getcwd()) / \"macros\"\n\n\n@pytest.fixture\ndef write_profiles_yml(request):\n    def _write_profiles_yml(profiles_dir, dbt_profile_contents):\n        def cleanup():\n            rm_file(Path(profiles_dir) / \"profiles.yml\")\n\n        request.addfinalizer(cleanup)\n        write_file(yaml.safe_dump(dbt_profile_contents), profiles_dir, \"profiles.yml\")\n\n    return _write_profiles_yml\n\n\n# https://gist.github.com/igniteflow/7267431?permalink_comment_id=2551951#gistcomment-2551951\n@contextmanager\ndef environ(env):\n    \"\"\"Temporarily set environment variables inside the context manager and\n    fully restore previous environment afterwards\n    \"\"\"\n    original_env = {key: os.getenv(key) for key in env}\n    os.environ.update(env)\n    try:\n        yield\n    finally:\n        for key, value in original_env.items():\n            if value is None:\n                del os.environ[key]\n            else:\n                os.environ[key] = value\n\n\nclass TestProfilesMayNotExist:\n    def test_debug(self, project):\n        # The database will not be able to connect; expect neither a pass or a failure (but not an exception)\n        run_dbt([\"debug\", \"--profiles-dir\", \"does_not_exist\"], expect_pass=None)\n\n    def test_deps(self, project):\n        run_dbt([\"deps\", \"--profiles-dir\", \"does_not_exist\"])\n\n\nclass TestProfiles:\n    def dbt_debug(self, project_dir_cli_arg=None, profiles_dir_cli_arg=None):\n        # begin with no command-line args or user config (from profiles.yml)\n        flags.set_from_args(Namespace(), {})\n        command = [\"debug\"]\n\n        if project_dir_cli_arg:\n            command.extend([\"--project-dir\", str(project_dir_cli_arg)])\n\n        if profiles_dir_cli_arg:\n            command.extend([\"--profiles-dir\", str(profiles_dir_cli_arg)])\n\n        # get the output of `dbt debug` regardless of the exit code\n        return run_dbt_and_capture(command, expect_pass=None)\n\n    @pytest.mark.parametrize(\n        \"project_dir_cli_arg, working_directory\",\n        [\n            # 3 different scenarios for `--project-dir` flag and current working directory\n            (None, \"cwd\"),  # no --project-dir flag and cwd is project directory\n            (None, \"cwd_child\"),  # no --project-dir flag and cwd is a project subdirectory\n            (\"cwd\", \"cwd_parent\"),  # use --project-dir flag and cwd is outside of it\n        ],\n    )\n    def test_profiles(\n        self,\n        project_dir_cli_arg,\n        working_directory,\n        write_profiles_yml,\n        dbt_profile_data,\n        profiles_home_root,\n        profiles_project_root,\n        profiles_flag_root,\n        profiles_env_root,\n        request,\n    ):\n        \"\"\"Verify priority order to search for profiles.yml configuration.\n\n        Reverse priority order:\n        1. HOME directory\n        2. DBT_PROFILES_DIR environment variable\n        3. --profiles-dir command-line argument\n\n        Specification later in this list will take priority over earlier ones, even when both are provided.\n        \"\"\"\n\n        # https://pypi.org/project/pytest-lazy-fixture/ is an alternative to using request.getfixturevalue\n        if project_dir_cli_arg is not None:\n            project_dir_cli_arg = request.getfixturevalue(project_dir_cli_arg)\n\n        if working_directory is not None:\n            working_directory = request.getfixturevalue(working_directory)\n\n        # start in the specified directory\n        if working_directory is not None:\n            os.chdir(working_directory)\n        # default case with profiles.yml in the HOME directory\n        _, stdout = self.dbt_debug(project_dir_cli_arg)\n        assert f\"Using profiles.yml file at {profiles_home_root}\" in stdout\n\n        # set DBT_PROFILES_DIR environment variable for the remainder of the cases\n        env_vars = {\"DBT_PROFILES_DIR\": profiles_env_root}\n        with environ(env_vars):\n            _, stdout = self.dbt_debug(project_dir_cli_arg)\n            assert f\"Using profiles.yml file at {profiles_env_root}\" in stdout\n\n            # This additional case is also within the context manager because we want to verify\n            # that it takes priority even when the relevant environment variable is also set\n\n            # set --profiles-dir on the command-line\n            _, stdout = self.dbt_debug(\n                project_dir_cli_arg, profiles_dir_cli_arg=profiles_flag_root\n            )\n            assert f\"Using profiles.yml file at {profiles_flag_root}\" in stdout\n"
  },
  {
    "path": "tests/functional/profiles/test_profiles_yml.py",
    "content": "import pathlib\n\nfrom test_profile_dir import environ\n\nfrom dbt.cli.main import dbtRunner\n\njinjaesque_password = \"no{{jinja{%re{#ndering\"\n\nprofile_with_jinjaesque_password = f\"\"\"test:\n  outputs:\n    default:\n      dbname: my_db\n      host: localhost\n      password: {jinjaesque_password}\n      port: 12345\n      schema: dummy\n      threads: 4\n      type: postgres\n      user: peter.webb\n  target: default\n\"\"\"\n\nprofile_with_env_password = \"\"\"test:\n  outputs:\n    default:\n      dbname: my_db\n      host: localhost\n      password: \"{{ env_var('DBT_PASSWORD') }}\"\n      port: 12345\n      schema: dummy\n      threads: 4\n      type: postgres\n      user: peter.webb\n  target: default\n\"\"\"\n\n\nclass TestProfileParsing:\n    def write_profiles_yml(self, profiles_root, content) -> None:\n        with open(pathlib.Path(profiles_root, \"profiles.yml\"), \"w\") as profiles_yml:\n            profiles_yml.write(content)\n\n    def test_password_not_jinja_rendered_when_invalid(self, project, profiles_root) -> None:\n        \"\"\"Verifies that passwords that contain Jinja control characters, but which are\n        not valid Jinja, do not cause errors.\"\"\"\n        self.write_profiles_yml(profiles_root, profile_with_jinjaesque_password)\n\n        events = []\n        result = dbtRunner(callbacks=[events.append]).invoke([\"parse\"])\n        assert result.success\n\n        for e in events:\n            assert \"no{{jinja{%re{#ndering\" not in e.info.msg\n\n    def test_password_jinja_rendered_when_valid(self, project, profiles_root) -> None:\n        \"\"\"Verifies that a password value that is valid Jinja is rendered as such,\n        and that it doesn't cause problems if the resulting value looks like Jinja\"\"\"\n        self.write_profiles_yml(profiles_root, profile_with_env_password)\n\n        events = []\n        with environ({\"DBT_PASSWORD\": jinjaesque_password}):\n            result = dbtRunner(callbacks=[events.append]).invoke([\"parse\"])\n\n        assert result.success\n        assert project.adapter.config.credentials.password == jinjaesque_password\n"
  },
  {
    "path": "tests/functional/record/test_record.py",
    "content": "import os\n\nimport pytest\n\nfrom dbt.tests.util import run_dbt\n\nTEMP_ENV_VARS = {}\nENV_VARS_TO_SUSPEND = [\"DBT_RECORDER_MODE\"]\n\n\n@pytest.fixture(scope=\"session\", autouse=True)\ndef tests_setup_and_teardown():\n    # Will be executed before the first test\n    old_environ = dict(os.environ)\n    os.environ.update(TEMP_ENV_VARS)\n    for env_var in ENV_VARS_TO_SUSPEND:\n        os.environ.pop(env_var, default=None)\n\n    yield\n    # Will be executed after the last test\n    os.environ.clear()\n    os.environ.update(old_environ)\n\n\n@pytest.fixture(scope=\"session\")\ndef set_dbt_recorder_mode():\n    old_environ = os.environ\n    os.environ[\"DBT_RECORDER_MODE\"] = \"record\"\n    yield\n    os.environ = old_environ\n\n\nclass TestRecord:\n    def test_record_when_env_var_set(self, project, set_dbt_recorder_mode):\n        run_dbt([\"run\"])\n        assert os.path.isfile(os.path.join(project.project_root, \"recording.json\"))\n"
  },
  {
    "path": "tests/functional/ref_override/test_custom_ref_kwargs.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt\n\n# Custom ref macro that accepts and ignores a 'label' kwarg\nmacros__custom_ref_sql = \"\"\"\n{% macro ref() %}\n{% set label = kwargs.get('label') %}\n{% set version = kwargs.get('version') or kwargs.get('v') %}\n{% set packagename = none %}\n{%- if (varargs | length) == 1 -%}\n    {% set modelname = varargs[0] %}\n{%- else -%}\n    {% set packagename = varargs[0] %}\n    {% set modelname = varargs[1] %}\n{% endif %}\n\n{% set rel = None %}\n{% if packagename is not none %}\n    {% set rel = builtins.ref(packagename, modelname, version=version) %}\n{% else %}\n    {% set rel = builtins.ref(modelname, version=version) %}\n{% endif %}\n\n{% do return(rel) %}\n{% endmacro %}\n\"\"\"\n\nmodels__model_a_sql = \"\"\"\nselect 1 as id, 'alice' as name\n\"\"\"\n\nmodels__model_b_sql = \"\"\"\nselect * from {{ ref('model_a', label='staging') }}\n\"\"\"\n\nmodels__schema_yml = \"\"\"\nmodels:\n  - name: model_a\n  - name: model_b\n    columns:\n      - name: id\n        data_tests:\n          - relationships:\n              to: ref('model_a', label='staging')\n              field: id\n\nunit_tests:\n  - name: my_unit_test\n    model: model_b\n    given:\n      - input: ref('model_a', label='staging')\n        rows:\n          - {id: 1, name: 'alice'}\n    expect:\n      rows:\n        - {id: 1, name: 'alice'}\n\"\"\"\n\n# Separate schema with only unit test for the \"without flag\" test\nmodels__schema_unit_only_yml = \"\"\"\nmodels:\n  - name: model_a\n  - name: model_b\n\nunit_tests:\n  - name: my_unit_test\n    model: model_b\n    given:\n      - input: ref('model_a', label='staging')\n        rows:\n          - {id: 1, name: 'alice'}\n    expect:\n      rows:\n        - {id: 1, name: 'alice'}\n\"\"\"\n\n\nclass TestCustomRefKwargsUnitTest:\n    \"\"\"Test that unit tests work with custom ref kwargs when flag is enabled.\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"flags\": {\n                \"support_custom_ref_kwargs\": True,\n            },\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_a.sql\": models__model_a_sql,\n            \"model_b.sql\": models__model_b_sql,\n            \"schema.yml\": models__schema_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"ref.sql\": macros__custom_ref_sql}\n\n    def test_unit_test_with_custom_ref_kwargs(self, project):\n        results = run_dbt([\"run\"])\n        assert len(results) == 2\n\n        results = run_dbt([\"test\", \"--select\", \"test_type:unit\"])\n        assert len(results) == 1\n        assert results[0].status == \"pass\"\n\n\nclass TestCustomRefKwargsGenericTest:\n    \"\"\"Test that generic data tests work with custom ref kwargs when flag is enabled.\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"flags\": {\n                \"support_custom_ref_kwargs\": True,\n            },\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_a.sql\": models__model_a_sql,\n            \"model_b.sql\": models__model_b_sql,\n            \"schema.yml\": models__schema_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"ref.sql\": macros__custom_ref_sql}\n\n    def test_generic_test_with_custom_ref_kwargs(self, project):\n        results = run_dbt([\"run\"])\n        assert len(results) == 2\n\n        results = run_dbt([\"test\", \"--select\", \"test_type:data\"])\n        assert len(results) == 1\n        assert results[0].status == \"pass\"\n\n\nclass TestCustomRefKwargsWithoutFlag:\n    \"\"\"Test that custom ref kwargs in unit tests fail without the behavior flag.\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_a.sql\": models__model_a_sql,\n            \"model_b.sql\": models__model_b_sql,\n            \"schema.yml\": models__schema_unit_only_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"ref.sql\": macros__custom_ref_sql}\n\n    def test_unit_test_fails_without_flag(self, project):\n        results = run_dbt([\"run\"])\n        assert len(results) == 2\n\n        results = run_dbt([\"test\", \"--select\", \"test_type:unit\"], expect_pass=False)\n        assert len(results) == 1\n        assert (\n            \"Unit test given inputs must be either a 'ref', 'source' or 'this' call\"\n            in results.results[0].message\n        )\n"
  },
  {
    "path": "tests/functional/ref_override/test_ref_override.py",
    "content": "import pytest\n\nfrom dbt.tests.util import check_relations_equal, run_dbt\n\nmodels__ref_override_sql = \"\"\"\nselect\n    *\nfrom {{ ref('seed_1') }}\n\"\"\"\n\nmacros__ref_override_macro_sql = \"\"\"\n-- Macro to override ref and always return the same result\n{% macro ref(modelname) %}\n{% do return(builtins.ref(modelname).replace_path(identifier='seed_2')) %}\n{% endmacro %}\n\"\"\"\n\nseeds__seed_2_csv = \"\"\"a,b\n6,2\n12,4\n18,6\"\"\"\n\nseeds__seed_1_csv = \"\"\"a,b\n1,2\n2,4\n3,6\"\"\"\n\n\nclass TestRefOverride:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"ref_override.sql\": models__ref_override_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"ref_override_macro.sql\": macros__ref_override_macro_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\"seed_2.csv\": seeds__seed_2_csv, \"seed_1.csv\": seeds__seed_1_csv}\n\n    def test_ref_override(\n        self,\n        project,\n    ):\n        run_dbt([\"seed\"])\n        run_dbt([\"run\"])\n\n        # We want it to equal seed_2 and not seed_1. If it's\n        # still pointing at seed_1 then the override hasn't worked.\n        check_relations_equal(project.adapter, [\"ref_override\", \"seed_2\"])\n\n\nmodels__version_ref_override_sql = \"\"\"\nselect\n    *\nfrom {{ ref('versioned_model', version=1) }}\n\"\"\"\n\nmodels__package_ref_override_sql = \"\"\"\nselect\n    *\nfrom {{ ref('package', 'versioned_model') }}\n\"\"\"\n\nmodels__package_version_ref_override_sql = \"\"\"\nselect\n    *\nfrom {{ ref('package', 'versioned_model', version=1) }}\n\"\"\"\n\nmodels__v1_sql = \"\"\"\nselect 1\n\"\"\"\n\nmodels__v2_sql = \"\"\"\nselect 2\n\"\"\"\n\nschema__versions_yml = \"\"\"\nmodels:\n  - name: versioned_model\n    versions:\n      - v: 1\n      - v: 2\n\"\"\"\n\nmacros__package_version_ref_override_macro_sql = \"\"\"\n-- Macro to override ref and always return the same result\n{% macro ref() %}\n-- extract user-provided positional and keyword arguments\n{% set version = kwargs.get('version') %}\n{% set packagename = none %}\n{%- if (varargs | length) == 1 -%}\n    {% set modelname = varargs[0] %}\n{%- else -%}\n    {% set packagename = varargs[0] %}\n    {% set modelname = varargs[1] %}\n{% endif %}\n\n{%- set version_override = 2 -%}\n{%- set packagename_override = 'test' -%}\n-- call builtins.ref based on provided positional arguments\n{% if packagename is not none %}\n    {% do return(builtins.ref(packagename_override, modelname, version=version_override)) %}\n{% else %}\n    {% do return(builtins.ref(modelname, version=version_override)) %}\n{% endif %}\n\n{% endmacro %}\n\"\"\"\n\n\nclass TestAdvancedRefOverride:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"version_ref_override.sql\": models__version_ref_override_sql,\n            \"package_ref_override.sql\": models__package_ref_override_sql,\n            \"package_version_ref_override.sql\": models__package_version_ref_override_sql,\n            \"versioned_model_v1.sql\": models__v1_sql,\n            \"versioned_model_v2.sql\": models__v2_sql,\n            \"model.sql\": models__v1_sql,\n            \"schema.yml\": schema__versions_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"ref_override_macro.sql\": macros__package_version_ref_override_macro_sql}\n\n    def test_ref_override(\n        self,\n        project,\n    ):\n        run_dbt([\"run\"])\n\n        # We want versioned_ref_override to equal to versioned_model_v2, otherwise the\n        # ref override macro has not worked\n        check_relations_equal(project.adapter, [\"version_ref_override\", \"versioned_model_v2\"])\n\n        check_relations_equal(project.adapter, [\"package_ref_override\", \"versioned_model_v2\"])\n\n        check_relations_equal(\n            project.adapter, [\"package_version_ref_override\", \"versioned_model_v2\"]\n        )\n"
  },
  {
    "path": "tests/functional/relation_names/test_relation_name.py",
    "content": "import pytest\n\nfrom dbt.contracts.results import RunStatus\nfrom dbt.tests.util import run_dbt\n\n# Test coverage: A relation is a name for a database entity, i.e. a table or view. Every relation has\n# a name. These tests verify the default Postgres rules for relation names are followed. Adapters\n# may override connection rules and thus may have their own tests.\n\nseeds__seed = \"\"\"col_A,col_B\n1,2\n3,4\n5,6\n\"\"\"\n\nmodels__basic_incremental = \"\"\"\nselect * from {{ this.schema }}.seed\n\n{{\n  config({\n    \"unique_key\": \"col_A\",\n    \"materialized\": \"incremental\"\n    })\n}}\n\"\"\"\n\nmodels__basic_table = \"\"\"\nselect * from {{ this.schema }}.seed\n\n{{\n  config({\n    \"materialized\": \"table\"\n    })\n}}\n\"\"\"\n\n\nclass TestGeneratedDDLNameRules:\n    @classmethod\n    def setup_class(self):\n        self.incremental_filename = \"my_name_is_51_characters_incremental_abcdefghijklmn\"\n        # length is 63\n        self.max_length_filename = (\n            \"my_name_is_max_length_chars_abcdefghijklmnopqrstuvwxyz123456789\"\n        )\n        # length is 64\n        self.over_max_length_filename = (\n            \"my_name_is_one_over_max_length_chats_abcdefghijklmnopqrstuvwxyz1\"\n        )\n\n        self.filename_for_backup_file = \"my_name_is_52_characters_abcdefghijklmnopqrstuvwxyz0\"\n\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project):\n        run_dbt([\"seed\"])\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\"seed.csv\": seeds__seed}\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            f\"{self.incremental_filename}.sql\": models__basic_incremental,\n            f\"{self.filename_for_backup_file}.sql\": models__basic_table,\n            f\"{self.max_length_filename}.sql\": models__basic_table,\n            f\"{self.over_max_length_filename}.sql\": models__basic_table,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"seeds\": {\n                \"quote_columns\": False,\n            },\n        }\n\n    # Backup table name generation:\n    #   1. for len(relation name) <= 51, backfills\n    #   2. for len(relation name) > 51 characters, overwrites\n    #  the last 12 characters with __dbt_backup\n    def test_name_shorter_or_equal_to_63_passes(self, project):\n        run_dbt(\n            [\n                \"run\",\n                \"-s\",\n                f\"{self.max_length_filename}\",\n                f\"{self.filename_for_backup_file}\",\n            ],\n        )\n\n    def test_long_name_passes_when_temp_tables_are_generated(self):\n        run_dbt(\n            [\n                \"run\",\n                \"-s\",\n                f\"{self.incremental_filename}\",\n            ],\n        )\n\n        # Run again to trigger incremental materialization\n        run_dbt(\n            [\n                \"run\",\n                \"-s\",\n                f\"{self.incremental_filename}\",\n            ],\n        )\n\n    # 63 characters is the character limit for a table name in a postgres database\n    # (assuming compiled without changes from source)\n    def test_name_longer_than_63_does_not_build(self):\n        err_msg = (\n            \"Relation name 'my_name_is_one_over_max\"\n            \"_length_chats_abcdefghijklmnopqrstuvwxyz1' is longer than 63 characters\"\n        )\n        res = run_dbt(\n            [\n                \"run\",\n                \"-s\",\n                self.over_max_length_filename,\n            ],\n            expect_pass=False,\n        )\n        assert res[0].status == RunStatus.Error\n        assert err_msg in res[0].message\n"
  },
  {
    "path": "tests/functional/relation_quoting/test_relation_quoting.py",
    "content": "import pytest\n\nfrom dbt.tests.util import read_file, run_dbt\n\n_SOURCES_YML = \"\"\"\nsources:\n  - name: source_name\n    database: source_database\n    schema: source_schema\n    tables:\n      - name: customers\n\"\"\"\n\n\nclass TestSourceQuotingGlobalConfigs:\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        # Postgres quoting configs are True by default -- turn them all to False to show they are not respected during source rendering\n        return {\n            \"quoting\": {\n                \"database\": False,\n                \"schema\": False,\n                \"identifier\": False,\n            },\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"sources.yml\": _SOURCES_YML,\n            \"model.sql\": \"select * from {{ source('source_name', 'customers') }}\",\n        }\n\n    def test_sources_ignore_global_quoting_configs(self, project):\n        run_dbt([\"compile\"])\n\n        generated_sql = read_file(\"target\", \"compiled\", \"test\", \"models\", \"model.sql\")\n        assert generated_sql == 'select * from \"source_database\".\"source_schema\".\"customers\"'\n\n\nclass TestModelQuoting:\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        # Postgres quoting configs are True by default -- turn them all to False to show they are respected during model rendering\n        return {\n            \"quoting\": {\n                \"database\": False,\n                \"schema\": False,\n                \"identifier\": False,\n            },\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model.sql\": \"select 1 as id\",\n            \"model_downstream.sql\": \"select * from {{ ref('model') }}\",\n        }\n\n    def test_models_respect_global_quoting_configs(self, project):\n        run_dbt([\"compile\"])\n\n        generated_sql = read_file(\"target\", \"compiled\", \"test\", \"models\", \"model_downstream.sql\")\n        assert generated_sql == f\"select * from dbt.{project.test_schema}.model\"\n"
  },
  {
    "path": "tests/functional/retry/fixtures.py",
    "content": "models__sample_model = \"\"\"select 1 as id, baz as foo\"\"\"\nmodels__second_model = \"\"\"select 1 as id, 2 as bar\"\"\"\nmodels__thread_model = \"\"\"select idx as id\"\"\"\n\nmodels__union_model = \"\"\"\nselect foo + bar as sum3 from {{ ref('sample_model') }}\nleft join {{ ref('second_model') }} on sample_model.id = second_model.id\n\"\"\"\n\nschema_yml = \"\"\"\nmodels:\n  - name: sample_model\n    columns:\n      - name: foo\n        data_tests:\n          - accepted_values:\n              arguments:\n                values: [3]\n                quote: false\n              config:\n                severity: warn\n  - name: second_model\n    columns:\n      - name: bar\n        data_tests:\n          - accepted_values:\n              arguments:\n                values: [3]\n                quote: false\n              config:\n                severity: warn\n  - name: union_model\n    columns:\n      - name: sum3\n        data_tests:\n          - accepted_values:\n              arguments:\n                values: [3]\n                quote: false\n\"\"\"\n\nmacros__alter_timezone_sql = \"\"\"\n{% macro alter_timezone(timezone='America/Los_Angeles') %}\n{{ print('running a macro!') }}\n\n{% set sql %}\n    SET TimeZone='{{ timezone }}';\n{% endset %}\n\n{% do run_query(sql) %}\n{% do log(\"Timezone set to: \" + timezone, info=True) %}\n{% endmacro %}\n\"\"\"\n\nmacros__success_macro_sql = \"\"\"\n{% macro success_macro() %}\n{{ print('running a macro!') }}\nselect 1\n{% endmacro %}\n\"\"\"\n\nsimple_model = \"\"\"\nselect null as id\n\"\"\"\n\nsimple_schema = \"\"\"\nmodels:\n  - name: some_model\n    columns:\n      - name: id\n        data_tests:\n          - not_null\n\"\"\"\n\nschema_test_thread_yml = \"\"\"\nmodels:\n  - name: thread_model\n    columns:\n      - name: id\n        data_tests:\n          - not_null\n\n\"\"\"\n"
  },
  {
    "path": "tests/functional/retry/test_retry.py",
    "content": "from pathlib import Path\nfrom shutil import copytree, move\n\nimport pytest\n\nfrom dbt.contracts.results import RunStatus, TestStatus\nfrom dbt.exceptions import DbtRuntimeError, TargetNotFoundError\nfrom dbt.tests.util import (\n    rm_file,\n    run_dbt,\n    run_dbt_and_capture,\n    update_config_file,\n    write_file,\n)\nfrom tests.functional.retry.fixtures import (\n    macros__alter_timezone_sql,\n    macros__success_macro_sql,\n    models__sample_model,\n    models__second_model,\n    models__union_model,\n    schema_yml,\n    simple_model,\n    simple_schema,\n)\n\n\nclass TestCustomTargetRetry:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"sample_model.sql\": models__sample_model,\n            \"second_model.sql\": models__second_model,\n            \"schema.yml\": schema_yml,\n        }\n\n    def test_custom_target(self, project):\n        run_dbt([\"build\", \"--select\", \"second_model\"])\n        run_dbt(\n            [\"build\", \"--select\", \"sample_model\", \"--target-path\", \"target2\"], expect_pass=False\n        )\n\n        # Regular retry - this is a no op because it's actually running `dbt build --select second_model`\n        # agian because it's looking at the default target since the custom_target wasn't passed in\n        results = run_dbt([\"retry\"])\n        assert len(results) == 0\n\n        # Retry with custom target after fixing the error\n        fixed_sql = \"select 1 as id, 1 as foo\"\n        write_file(fixed_sql, \"models\", \"sample_model.sql\")\n\n        results = run_dbt([\"retry\", \"--state\", \"target2\"])\n        expected_statuses = {\n            \"sample_model\": RunStatus.Success,\n            \"accepted_values_sample_model_foo__False__3\": TestStatus.Warn,\n        }\n\n        assert {n.node.name: n.status for n in results.results} == expected_statuses\n\n        write_file(models__sample_model, \"models\", \"sample_model.sql\")\n\n\nclass BaseTestRetry:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"sample_model.sql\": models__sample_model,\n            \"second_model.sql\": models__second_model,\n            \"union_model.sql\": models__union_model,\n            \"schema.yml\": schema_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\n            \"alter_timezone.sql\": macros__alter_timezone_sql,\n            \"success_macro.sql\": macros__success_macro_sql,\n        }\n\n\nclass TestRetryNoPreviousRun(BaseTestRetry):\n    def test_no_previous_run(self, project):\n        with pytest.raises(\n            DbtRuntimeError, match=\"Could not find previous run in 'target' target directory\"\n        ):\n            run_dbt([\"retry\"])\n\n        with pytest.raises(\n            DbtRuntimeError, match=\"Could not find previous run in 'walmart' target directory\"\n        ):\n            run_dbt([\"retry\", \"--state\", \"walmart\"])\n\n\nclass TestRetryPreviousRun(BaseTestRetry):\n    def test_previous_run(self, project):\n        # Regular build\n        results = run_dbt([\"build\"], expect_pass=False)\n\n        expected_statuses = {\n            \"sample_model\": RunStatus.Error,\n            \"second_model\": RunStatus.Success,\n            \"union_model\": RunStatus.Skipped,\n            \"accepted_values_sample_model_foo__False__3\": RunStatus.Skipped,\n            \"accepted_values_second_model_bar__False__3\": TestStatus.Warn,\n            \"accepted_values_union_model_sum3__False__3\": RunStatus.Skipped,\n        }\n\n        assert {n.node.name: n.status for n in results.results} == expected_statuses\n\n        # Ignore second_model which succeeded\n        results = run_dbt([\"retry\"], expect_pass=False)\n\n        expected_statuses = {\n            \"sample_model\": RunStatus.Error,\n            \"union_model\": RunStatus.Skipped,\n            \"accepted_values_union_model_sum3__False__3\": RunStatus.Skipped,\n            \"accepted_values_sample_model_foo__False__3\": RunStatus.Skipped,\n        }\n\n        assert {n.node.name: n.status for n in results.results} == expected_statuses\n\n        # Fix sample model and retry, everything should pass\n        fixed_sql = \"select 1 as id, 1 as foo\"\n        write_file(fixed_sql, \"models\", \"sample_model.sql\")\n\n        results = run_dbt([\"retry\"])\n\n        expected_statuses = {\n            \"sample_model\": RunStatus.Success,\n            \"union_model\": RunStatus.Success,\n            \"accepted_values_union_model_sum3__False__3\": TestStatus.Pass,\n            \"accepted_values_sample_model_foo__False__3\": TestStatus.Warn,\n        }\n\n        assert {n.node.name: n.status for n in results.results} == expected_statuses\n\n        # No failures in previous run, nothing to retry\n        results = run_dbt([\"retry\"])\n        expected_statuses = {}\n        assert {n.node.name: n.status for n in results.results} == expected_statuses\n\n        write_file(models__sample_model, \"models\", \"sample_model.sql\")\n\n\nclass TestRetryWarnError(BaseTestRetry):\n    def test_warn_error(self, project):\n        # Our test command should succeed when run normally...\n        results = run_dbt([\"build\", \"--select\", \"second_model\"])\n\n        # ...but it should fail when run with warn-error, due to a warning...\n        results = run_dbt([\"--warn-error\", \"build\", \"--select\", \"second_model\"], expect_pass=False)\n\n        expected_statuses = {\n            \"second_model\": RunStatus.Success,\n            \"accepted_values_second_model_bar__False__3\": TestStatus.Fail,\n        }\n\n        assert {n.node.name: n.status for n in results.results} == expected_statuses\n\n        # Retry regular, should pass\n        run_dbt([\"retry\"])\n\n        # Retry with --warn-error, should fail\n        run_dbt([\"--warn-error\", \"retry\"], expect_pass=False)\n\n\nclass TestRetryRunOperation(BaseTestRetry):\n    def test_run_operation(self, project):\n        results, log_output = run_dbt_and_capture(\n            [\"run-operation\", \"alter_timezone\", \"--args\", \"{timezone: abc}\"], expect_pass=False\n        )\n        assert \"running a macro!\" in log_output\n\n        expected_statuses = {\n            \"macro.test.alter_timezone\": RunStatus.Error,\n        }\n\n        assert {n.unique_id: n.status for n in results.results} == expected_statuses\n\n        results, log_output = run_dbt_and_capture([\"retry\"], expect_pass=False)\n        assert \"running a macro!\" in log_output\n        assert {n.unique_id: n.status for n in results.results} == expected_statuses\n\n\nclass TestRetrySuccessfulRunOperation(BaseTestRetry):\n    def test_run_operation(self, project):\n        results, log_output = run_dbt_and_capture([\"run-operation\", \"success_macro\"])\n        assert \"running a macro!\" in log_output\n\n        expected_statuses = {\n            \"macro.test.success_macro\": RunStatus.Success,\n        }\n\n        assert {n.unique_id: n.status for n in results.results} == expected_statuses\n\n        results, log_output = run_dbt_and_capture([\"retry\"])\n        assert \"running a macro!\" not in log_output\n        assert {n.unique_id: n.status for n in results.results} == expected_statuses\n\n\nclass TestRetryRemovedFile(BaseTestRetry):\n    def test_removed_file(self, project):\n        run_dbt([\"build\"], expect_pass=False)\n\n        rm_file(\"models\", \"sample_model.sql\")\n\n        with pytest.raises(\n            TargetNotFoundError, match=\"depends on a node named 'sample_model' which was not found\"\n        ):\n            run_dbt([\"retry\"], expect_pass=False)\n\n        write_file(models__sample_model, \"models\", \"sample_model.sql\")\n\n\nclass TestRetryRemovedFileLeafNode(BaseTestRetry):\n    def test_removed_file_leaf_node(self, project):\n        write_file(models__sample_model, \"models\", \"third_model.sql\")\n        run_dbt([\"build\"], expect_pass=False)\n\n        rm_file(\"models\", \"third_model.sql\")\n        with pytest.raises(ValueError, match=\"Couldn't find model 'model.test.third_model'\"):\n            run_dbt([\"retry\"], expect_pass=False)\n\n\nclass TestFailFast:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"sample_model.sql\": models__sample_model,\n            \"second_model.sql\": models__second_model,\n            \"union_model.sql\": models__union_model,\n            \"final_model.sql\": \"select * from {{ ref('union_model') }};\",\n        }\n\n    def test_fail_fast(self, project):\n        results = run_dbt([\"--fail-fast\", \"build\"], expect_pass=False)\n        assert {r.node.unique_id: r.status for r in results.results} == {\n            \"model.test.sample_model\": RunStatus.Error,\n            \"model.test.second_model\": RunStatus.Success,\n            \"model.test.union_model\": RunStatus.Skipped,\n            \"model.test.final_model\": RunStatus.Skipped,\n        }\n\n        # Check that retry inherits fail-fast from upstream command (build)\n        results = run_dbt([\"retry\"], expect_pass=False)\n        assert {r.node.unique_id: r.status for r in results.results} == {\n            \"model.test.sample_model\": RunStatus.Error,\n            \"model.test.union_model\": RunStatus.Skipped,\n            \"model.test.final_model\": RunStatus.Skipped,\n        }\n\n        fixed_sql = \"select 1 as id, 1 as foo\"\n        write_file(fixed_sql, \"models\", \"sample_model.sql\")\n\n        results = run_dbt([\"retry\"], expect_pass=False)\n        assert {r.node.unique_id: r.status for r in results.results} == {\n            \"model.test.sample_model\": RunStatus.Success,\n            \"model.test.union_model\": RunStatus.Success,\n            \"model.test.final_model\": RunStatus.Error,\n        }\n\n        results = run_dbt([\"retry\"], expect_pass=False)\n        assert {r.node.unique_id: r.status for r in results.results} == {\n            \"model.test.final_model\": RunStatus.Error,\n        }\n\n        fixed_sql = \"select * from {{ ref('union_model') }}\"\n        write_file(fixed_sql, \"models\", \"final_model.sql\")\n\n        results = run_dbt([\"retry\"])\n        assert {r.node.unique_id: r.status for r in results.results} == {\n            \"model.test.final_model\": RunStatus.Success,\n        }\n\n        results = run_dbt([\"retry\"])\n        assert {r.node.unique_id: r.status for r in results.results} == {}\n\n\nclass TestRetryResourceType:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"null_model.sql\": simple_model,\n            \"schema.yml\": simple_schema,\n        }\n\n    def test_resource_type(self, project):\n        # test multiple options in single string\n        results = run_dbt([\"build\", \"--select\", \"null_model\", \"--resource-type\", \"test model\"])\n        assert len(results) == 1\n\n        # nothing to do\n        results = run_dbt([\"retry\"])\n        assert len(results) == 0\n\n        # test multiple options in multiple args\n        results = run_dbt(\n            [\n                \"build\",\n                \"--select\",\n                \"null_model\",\n                \"--resource-type\",\n                \"test\",\n                \"--resource-type\",\n                \"model\",\n            ]\n        )\n        assert len(results) == 1\n\n        # nothing to do\n        results = run_dbt([\"retry\"])\n        assert len(results) == 0\n\n        # test single all option\n        results = run_dbt([\"build\", \"--select\", \"null_model\", \"--resource-type\", \"all\"])\n        assert len(results) == 1\n\n        # nothing to do\n        results = run_dbt([\"retry\"])\n        assert len(results) == 0\n\n\nclass TestRetryOverridePath:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"sample_model.sql\": models__sample_model,\n        }\n\n    def test_retry(self, project):\n        project_root = project.project_root\n        proj_location_1 = project_root / \"proj_location_1\"\n        proj_location_2 = project_root / \"proj_location_2\"\n\n        copytree(project_root, proj_location_1)\n        run_dbt([\"run\", \"--project-dir\", \"proj_location_1\"], expect_pass=False)\n        move(proj_location_1, proj_location_2)\n        run_dbt([\"retry\", \"--project-dir\", \"proj_location_2\"], expect_pass=False)\n\n\nclass TestRetryVars:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"sample_model.sql\": \"select {{ var('myvar_a', '1') + var('myvar_b', '2') }} as mycol\",\n        }\n\n    def test_retry(self, project):\n        # pass because default vars works\n        run_dbt([\"run\"])\n        run_dbt([\"run\", \"--vars\", '{\"myvar_a\": \"12\", \"myvar_b\": \"3 4\"}'], expect_pass=False)\n        # fail because vars are invalid, this shows that the last passed vars are being used\n        # instead of using the default vars\n        run_dbt([\"retry\"], expect_pass=False)\n        results = run_dbt([\"retry\", \"--vars\", '{\"myvar_a\": \"12\", \"myvar_b\": \"34\"}'])\n        assert len(results) == 1\n\n\nclass TestRetryFullRefresh:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"sample_model.sql\": \"{% if flags.FULL_REFRESH %} this is invalid sql {% else %} select 1 as mycol {% endif %}\",\n        }\n\n    def test_retry(self, project):\n        # This run should fail with invalid sql...\n        run_dbt([\"run\", \"--full-refresh\"], expect_pass=False)\n        # ...and so should this one, since the effect of the full-refresh parameter should persist.\n        results = run_dbt([\"retry\"], expect_pass=False)\n        assert len(results) == 1\n\n\nclass TestRetryTargetPathEnvVar:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"sample_model.sql\": models__sample_model,\n        }\n\n    def test_retry_target_path_env_var(self, project, monkeypatch):\n        monkeypatch.setenv(\"DBT_TARGET_PATH\", \"artifacts\")\n        run_dbt([\"run\"], expect_pass=False)\n\n        write_file(models__second_model, \"models\", \"sample_model.sql\")\n\n        results = run_dbt([\"retry\"])\n        assert len(results) == 1\n\n\nclass TestRetryTargetPathFlag:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"sample_model.sql\": models__sample_model,\n        }\n\n    def test_retry_target_path_flag(self, project):\n        run_dbt([\"run\", \"--target-path\", \"target\"], expect_pass=False)\n\n        project_root = project.project_root\n        move(project_root / \"target\", project_root / \"artifacts\")\n\n        write_file(models__second_model, \"models\", \"sample_model.sql\")\n\n        results = run_dbt([\"retry\", \"--state\", \"artifacts\", \"--target-path\", \"my_target_path\"])\n        assert len(results) == 1\n        assert Path(\"my_target_path\").is_dir()\n\n\nclass TestRetryHooksAlwaysRun:\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"on-run-start\": [\"select 1;\"],\n            \"on-run-end\": [\"select 2;\"],\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"sample_model.sql\": models__sample_model,\n        }\n\n    def test_retry_hooks_always_run(self, project):\n        res = run_dbt([\"run\", \"--target-path\", \"target\"], expect_pass=False)\n        assert len(res) == 3\n\n        write_file(models__second_model, \"models\", \"sample_model.sql\")\n        res = run_dbt([\"retry\", \"--state\", \"target\"])\n        assert len(res) == 3\n\n\nclass TestFixRetryHook:\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"flags\": {\n                \"skip_nodes_if_on_run_start_fails\": True,\n            },\n            \"on-run-start\": [\n                \"select 1 as id\",\n                \"select column_does_not_exist\",\n                \"select 2 as id\",\n            ],\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"sample_model.sql\": \"select 1 as id, 1 as foo\",\n            \"second_model.sql\": models__second_model,\n            \"union_model.sql\": models__union_model,\n        }\n\n    def test_fix_retry_hook(self, project):\n        res = run_dbt([\"run\"], expect_pass=False)\n        assert {r.node.unique_id: r.status for r in res.results} == {\n            \"operation.test.test-on-run-start-0\": RunStatus.Success,\n            \"operation.test.test-on-run-start-1\": RunStatus.Error,\n            \"operation.test.test-on-run-start-2\": RunStatus.Skipped,\n            \"model.test.sample_model\": RunStatus.Skipped,\n            \"model.test.second_model\": RunStatus.Skipped,\n            \"model.test.union_model\": RunStatus.Skipped,\n        }\n\n        res = run_dbt([\"retry\"], expect_pass=False)\n        assert {r.node.unique_id: r.status for r in res.results} == {\n            \"operation.test.test-on-run-start-0\": RunStatus.Success,\n            \"operation.test.test-on-run-start-1\": RunStatus.Error,\n            \"operation.test.test-on-run-start-2\": RunStatus.Skipped,\n            \"model.test.sample_model\": RunStatus.Skipped,\n            \"model.test.second_model\": RunStatus.Skipped,\n            \"model.test.union_model\": RunStatus.Skipped,\n        }\n\n        new_dbt_project_yml = {\n            \"flags\": {\n                \"skip_nodes_if_on_run_start_fails\": True,\n            },\n            \"on-run-start\": [\n                \"select 1 as id\",\n                \"select 3 as id\",\n                \"select 2 as id\",\n            ],\n        }\n\n        update_config_file(new_dbt_project_yml, project.project_root, \"dbt_project.yml\")\n        res = run_dbt([\"retry\"])\n        assert {r.node.unique_id: r.status for r in res.results} == {\n            \"operation.test.test-on-run-start-0\": RunStatus.Success,\n            \"operation.test.test-on-run-start-1\": RunStatus.Success,\n            \"operation.test.test-on-run-start-2\": RunStatus.Success,\n            \"model.test.sample_model\": RunStatus.Success,\n            \"model.test.second_model\": RunStatus.Success,\n            \"model.test.union_model\": RunStatus.Success,\n        }\n"
  },
  {
    "path": "tests/functional/retry/test_retry_threads.py",
    "content": "import pytest\n\nfrom dbt.contracts.results import RunStatus, TestStatus\nfrom dbt.tests.util import run_dbt, write_file\nfrom tests.functional.retry.fixtures import models__thread_model, schema_test_thread_yml\n\n\nclass TestCustomThreadRetry:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"thread_model.sql\": models__thread_model,\n            \"schema.yml\": schema_test_thread_yml,\n        }\n\n    def test_thread_target(self, project):\n        # Passing Threads to check\n        results = run_dbt(\n            [\"build\", \"--select\", \"thread_model\", \"--threads\", \"3\"], expect_pass=False\n        )\n        expected_statuses = {\n            \"thread_model\": RunStatus.Error,\n            \"not_null_thread_model_id\": TestStatus.Skipped,\n        }\n        assert {n.node.name: n.status for n in results.results} == expected_statuses\n\n        # Retry Running the Dbt with simple Retry\n        results = run_dbt([\"retry\", \"--threads\", \"2\"], expect_pass=False)\n        expected_statuses = {\n            \"thread_model\": RunStatus.Error,\n            \"not_null_thread_model_id\": TestStatus.Skipped,\n        }\n        assert {n.node.name: n.status for n in results.results} == expected_statuses\n        assert results.args[\"threads\"] == 2\n\n        # running with retry withour threads\n        results = run_dbt([\"retry\"], expect_pass=False)\n        expected_statuses = {\n            \"thread_model\": RunStatus.Error,\n            \"not_null_thread_model_id\": TestStatus.Skipped,\n        }\n        assert {n.node.name: n.status for n in results.results} == expected_statuses\n        assert results.args[\"threads\"] == 2\n\n        # Retry with fixing the model and running with --threads 1\n        fixed_sql = \"select 1 as id\"\n        write_file(fixed_sql, \"models\", \"thread_model.sql\")\n\n        results = run_dbt([\"retry\", \"--threads\", \"1\"])\n        expected_statuses = {\n            \"thread_model\": RunStatus.Success,\n            \"not_null_thread_model_id\": TestStatus.Pass,\n        }\n\n        assert {n.node.name: n.status for n in results.results} == expected_statuses\n        assert results.args[\"threads\"] == 1\n"
  },
  {
    "path": "tests/functional/run_operations/fixtures.py",
    "content": "happy_macros_sql = \"\"\"\n{% macro no_args() %}\n  {% if execute %}\n    {% call statement(auto_begin=True) %}\n      create table \"{{ schema }}\".\"no_args\" (id int);\n      commit;\n    {% endcall %}\n  {% endif %}\n{% endmacro %}\n\n\n{% macro table_name_args(table_name) %}\n  {% if execute %}\n    {% call statement(auto_begin=True) %}\n      create table \"{{ schema }}\".\"{{ table_name }}\" (id int);\n      commit;\n    {% endcall %}\n  {% endif %}\n{% endmacro %}\n\n{% macro select_something(name) %}\n  {% set query %}\n    select 'hello, {{ name }}' as name\n  {% endset %}\n  {% set table = run_query(query) %}\n\n  {% if table.columns['name'][0] != 'hello, world' %}\n    {% do exceptions.raise_compiler_error(\"unexpected result: \" ~ table) %}\n  {% endif %}\n{% endmacro %}\n\n{% macro vacuum(table_name) %}\n  {% set query %}\n    vacuum \"{{ schema }}\".\"{{ table_name }}\"\n  {% endset %}\n  {% do run_query(query) %}\n{% endmacro %}\n\n\n{% macro vacuum_ref(ref_target) %}\n  {% set query %}\n    vacuum {{ ref(ref_target) }}\n  {% endset %}\n  {% do run_query(query) %}\n{% endmacro %}\n\n\n{% macro log_graph() %}\n  {% for node in graph.nodes.values() %}\n    {{ log((node | string), info=True)}}\n  {% endfor %}\n{% endmacro %}\n\n\n{% macro print_something() %}\n  {{ print(\"You're doing awesome!\") }}\n{% endmacro %}\n\"\"\"\n\nsad_macros_sql = \"\"\"\n{% macro syntax_error() %}\n  {% if execute %}\n    {% call statement() %}\n        select NOPE NOT A VALID QUERY\n    {% endcall %}\n  {% endif %}\n{% endmacro %}\n\"\"\"\n\nmodel_sql = \"\"\"\nselect 1 as id\n\"\"\"\n\nprivate_model_sql = \"\"\"\nselect 1 as id\n\"\"\"\n\ngroups_yml = \"\"\"\ngroups:\n  - name: analytics\n    owner:\n      name: analytics_owner\n\"\"\"\n\nprivate_model_schema_yml = \"\"\"\nmodels:\n  - name: private_model\n    access: private\n    group: analytics\n\"\"\"\n\nref_private_model_macro_sql = \"\"\"\n{% macro ref_private_model() %}\n  {% set result = run_query(\"select * from \" ~ ref('private_model')) %}\n  {{ log(\"Successfully referenced private model\", info=true) }}\n{% endmacro %}\n\"\"\"\n"
  },
  {
    "path": "tests/functional/run_operations/test_run_operations.py",
    "content": "import os\n\nimport pytest\nimport yaml\n\nfrom dbt.artifacts.schemas.results import RunStatus\nfrom dbt.tests.util import (\n    check_table_does_exist,\n    mkdir,\n    rm_dir,\n    rm_file,\n    run_dbt,\n    run_dbt_and_capture,\n    write_file,\n)\nfrom dbt_common.exceptions import UndefinedMacroError\nfrom tests.functional.run_operations.fixtures import (\n    groups_yml,\n    happy_macros_sql,\n    model_sql,\n    private_model_schema_yml,\n    private_model_sql,\n    ref_private_model_macro_sql,\n    sad_macros_sql,\n)\n\n\nclass TestOperations:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"model.sql\": model_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"happy_macros.sql\": happy_macros_sql, \"sad_macros.sql\": sad_macros_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def dbt_profile_data(self, unique_schema):\n        return {\n            \"test\": {\n                \"outputs\": {\n                    \"default\": {\n                        \"type\": \"postgres\",\n                        \"threads\": 4,\n                        \"host\": \"localhost\",\n                        \"port\": int(os.getenv(\"POSTGRES_TEST_PORT\", 5432)),\n                        \"user\": os.getenv(\"POSTGRES_TEST_USER\", \"root\"),\n                        \"pass\": os.getenv(\"POSTGRES_TEST_PASS\", \"password\"),\n                        \"dbname\": os.getenv(\"POSTGRES_TEST_DATABASE\", \"dbt\"),\n                        \"schema\": unique_schema,\n                    },\n                    \"noaccess\": {\n                        \"type\": \"postgres\",\n                        \"threads\": 4,\n                        \"host\": \"localhost\",\n                        \"port\": int(os.getenv(\"POSTGRES_TEST_PORT\", 5432)),\n                        \"user\": \"noaccess\",\n                        \"pass\": \"password\",\n                        \"dbname\": os.getenv(\"POSTGRES_TEST_DATABASE\", \"dbt\"),\n                        \"schema\": unique_schema,\n                    },\n                },\n                \"target\": \"default\",\n            },\n        }\n\n    def run_operation(self, macro, expect_pass=True, extra_args=None, **kwargs):\n        args = [\"run-operation\", macro]\n        if kwargs:\n            args.extend((\"--args\", yaml.safe_dump(kwargs)))\n        if extra_args:\n            args.extend(extra_args)\n        return run_dbt(args, expect_pass=expect_pass)\n\n    def test_macro_noargs(self, project):\n        self.run_operation(\"no_args\")\n        check_table_does_exist(project.adapter, \"no_args\")\n\n    def test_macro_args(self, project):\n        self.run_operation(\"table_name_args\", table_name=\"my_fancy_table\")\n        check_table_does_exist(project.adapter, \"my_fancy_table\")\n\n    def test_macro_exception(self, project):\n        self.run_operation(\"syntax_error\", False)\n\n    def test_macro_missing(self, project):\n        with pytest.raises(\n            UndefinedMacroError,\n            match=\"dbt could not find a macro with the name 'this_macro_does_not_exist' in any package\",\n        ):\n            self.run_operation(\"this_macro_does_not_exist\", False)\n\n    def test_cannot_connect(self, project):\n        self.run_operation(\"no_args\", extra_args=[\"--target\", \"noaccess\"], expect_pass=False)\n\n    def test_vacuum(self, project):\n        run_dbt([\"run\"])\n        # this should succeed\n        self.run_operation(\"vacuum\", table_name=\"model\")\n\n    def test_vacuum_ref(self, project):\n        run_dbt([\"run\"])\n        # this should succeed\n        self.run_operation(\"vacuum_ref\", ref_target=\"model\")\n\n    def test_select(self, project):\n        self.run_operation(\"select_something\", name=\"world\")\n\n    def test_access_graph(self, project):\n        self.run_operation(\"log_graph\")\n\n    def test_print(self, project):\n        # Tests that calling the `print()` macro does not cause an exception\n        self.run_operation(\"print_something\")\n\n    def test_run_operation_local_macro(self, project):\n        pkg_macro = \"\"\"\n{% macro something_cool() %}\n    {{ log(\"something cool\", info=true) }}\n{% endmacro %}\n        \"\"\"\n\n        mkdir(\"pkg/macros\")\n\n        write_file(pkg_macro, \"pkg/macros/something_cool.sql\")\n\n        pkg_yaml = \"\"\"\npackages:\n    - local: pkg\n        \"\"\"\n\n        write_file(pkg_yaml, \"packages.yml\")\n\n        pkg_dbt_project = \"\"\"\nname: 'pkg'\n        \"\"\"\n\n        write_file(pkg_dbt_project, \"pkg/dbt_project.yml\")\n\n        run_dbt([\"deps\"])\n\n        results, log_output = run_dbt_and_capture([\"run-operation\", \"something_cool\"])\n\n        for result in results:\n            if result.status == RunStatus.Skipped:\n                continue\n\n            timing_keys = [timing.name for timing in result.timing]\n            assert timing_keys == [\"compile\", \"execute\"]\n\n        assert \"something cool\" in log_output\n\n        results, log_output = run_dbt_and_capture([\"run-operation\", \"pkg.something_cool\"])\n\n        for result in results:\n            if result.status == RunStatus.Skipped:\n                continue\n\n            timing_keys = [timing.name for timing in result.timing]\n            assert timing_keys == [\"compile\", \"execute\"]\n\n        assert \"something cool\" in log_output\n\n        rm_dir(\"pkg\")\n        rm_file(\"packages.yml\")\n\n\nclass TestRunOperationRefPrivateModel:\n    \"\"\"Regression test for https://github.com/dbt-labs/dbt-core/issues/8248\n\n    Macros invoked via run-operation should be able to ref() private models,\n    since macros are outside the group/access control system.\n    \"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"private_model.sql\": private_model_sql,\n            \"schema.yml\": private_model_schema_yml,\n            \"groups.yml\": groups_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"ref_private_model.sql\": ref_private_model_macro_sql}\n\n    def test_run_operation_ref_private_model(self, project):\n        run_dbt([\"run\"])\n        results = run_dbt([\"run-operation\", \"ref_private_model\"])\n        assert results.results[0].status == RunStatus.Success\n"
  },
  {
    "path": "tests/functional/run_query/test_types.py",
    "content": "import pytest\n\nfrom dbt.contracts.results import NodeStatus\nfrom dbt.tests.util import run_dbt\n\nmacros_sql = \"\"\"\n{% macro test_array_results() %}\n\n    {% set sql %}\n        select ARRAY[1, 2, 3, 4] as mydata\n    {% endset %}\n\n    {% set result = run_query(sql) %}\n    {% set value = result.columns['mydata'][0] %}\n\n    {# This will be json-stringified #}\n    {% if value != \"[1, 2, 3, 4]\" %}\n        {% do exceptions.raise_compiler_error(\"Value was \" ~ value) %}\n    {% endif %}\n\n{% endmacro %}\n\"\"\"\n\n\nclass TestTypes:\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\n            \"macros.sql\": macros_sql,\n        }\n\n    def test_nested_types(self, project):\n        result = run_dbt([\"run-operation\", \"test_array_results\"])\n        assert result.results[0].status == NodeStatus.Success\n"
  },
  {
    "path": "tests/functional/sample_mode/test_sample_mode.py",
    "content": "from datetime import datetime\nfrom typing import Optional\n\nimport freezegun\nimport pytest\nimport pytz\n\nfrom dbt.artifacts.resources.types import BatchSize\nfrom dbt.event_time.sample_window import SampleWindow\nfrom dbt.events.types import JinjaLogInfo\nfrom dbt.materializations.incremental.microbatch import MicrobatchBuilder\nfrom dbt.tests.util import read_file, relation_from_name, run_dbt, write_file\nfrom dbt_common.events.event_catcher import EventCatcher\n\ninput_model_sql = \"\"\"\n{{ config(materialized='table', event_time='event_time') }}\nselect 1 as id, TIMESTAMP '2020-01-01 01:25:00-0' as event_time\nUNION ALL\nselect 2 as id, TIMESTAMP '2025-01-02 13:47:00-0' as event_time\nUNION ALL\nselect 3 as id, TIMESTAMP '2025-01-03 01:32:00-0' as event_time\n\"\"\"\n\nlater_input_model_sql = \"\"\"\n{{ config(materialized='table', event_time='event_time') }}\nselect 1 as id, TIMESTAMP '2020-01-01 01:25:00-0' as event_time\nUNION ALL\nselect 2 as id, TIMESTAMP '2025-01-02 13:47:00-0' as event_time\nUNION ALL\nselect 3 as id, TIMESTAMP '2025-01-03 01:32:00-0' as event_time\nUNION ALL\nselect 4 as id, TIMESTAMP '2025-01-04 14:32:00-0' as event_time\nUNION ALL\nselect 5 as id, TIMESTAMP '2025-01-05 20:32:00-0' as event_time\nUNION ALL\nselect 6 as id, TIMESTAMP '2025-01-06 12:32:00-0' as event_time\n\"\"\"\n\ninput_seed_csv = \"\"\"id,event_time\n1,'2020-01-01 01:25:00-0'\n2,'2025-01-02 13:47:00-0'\n3,'2025-01-03 01:32:00-0'\n\"\"\"\n\nseed_properties_yml = \"\"\"\nseeds:\n    - name: input_seed\n      config:\n        event_time: event_time\n        column_types:\n            event_time: timestamp\n\"\"\"\n\nsample_mode_model_sql = \"\"\"\n{{ config(materialized='table', event_time='event_time') }}\n\n{% if execute %}\n    {{ log(\"Sample: \" ~ invocation_args_dict.get(\"sample\"), info=true) }}\n{% endif %}\n\nSELECT * FROM {{ ref(\"input_model\") }}\n\"\"\"\n\nsample_input_seed_sql = \"\"\"\n{{ config(materialized='table') }}\n\nSELECT * FROM {{ ref(\"input_seed\") }}\n\"\"\"\n\nsample_microbatch_model_sql = \"\"\"\n{{ config(materialized='incremental', incremental_strategy='microbatch', event_time='event_time', batch_size='day', lookback=3, begin='2024-12-25', unique_key='id')}}\n\n{% if execute %}\n    {{ log(\"batch.event_time_start: \"~ model.batch.event_time_start, info=True)}}\n    {{ log(\"batch.event_time_end: \"~ model.batch.event_time_end, info=True)}}\n{% endif %}\n\nSELECT * FROM {{ ref(\"input_model\") }}\n\"\"\"\n\nsample_incremental_merge_sql = \"\"\"\n{{ config(materialized='incremental', incremental_strategy='merge', unique_key='id')}}\n\n{% if execute %}\n    {{ log(\"is_incremental: \" ~ is_incremental(), info=true) }}\n    {{ log(\"sample: \" ~ invocation_args_dict.get(\"sample\"), info=true) }}\n{% endif %}\n\nSELECT * FROM {{ ref(\"input_model\") }}\n\n{% if is_incremental() %}\n    WHERE event_time >= (SELECT max(event_time) FROM {{ this }})\n{% endif %}\n\"\"\"\n\nsnapshot_input_model_sql = \"\"\"\n{% snapshot snapshot_input_model %}\n    {{ config(strategy='timestamp', unique_key='id', updated_at='event_time', event_time='event_time') }}\n\n    select * from {{ ref('input_model') }}\n{% endsnapshot %}\n\"\"\"\n\nmodel_from_snapshot_sql = \"\"\"\n{{ config(materialized='table') }}\n\nSELECT * FROM {{ ref('snapshot_input_model') }}\n\"\"\"\n\n\nclass BaseSampleMode:\n    # TODO This is now used in 3 test files, it might be worth turning into a full test utility method\n    def assert_row_count(self, project, relation_name: str, expected_row_count: int):\n        relation = relation_from_name(project.adapter, relation_name)\n        result = project.run_sql(f\"select count(*) as num_rows from {relation}\", fetch=\"one\")\n\n        if result[0] != expected_row_count:\n            # running show for debugging\n            run_dbt([\"show\", \"--inline\", f\"select * from {relation}\"])\n\n            assert result[0] == expected_row_count\n\n    def drop_table(self, project, relation_name: str):\n        relation = relation_from_name(project.adapter, \"snapshot_input_model\")\n        project.run_sql(f\"drop table if exists {relation}\")\n\n\nclass TestBasicSampleMode(BaseSampleMode):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"input_model.sql\": input_model_sql,\n            \"sample_mode_model.sql\": sample_mode_model_sql,\n        }\n\n    @pytest.fixture\n    def event_catcher(self) -> EventCatcher:\n        return EventCatcher(event_to_catch=JinjaLogInfo)  # type: ignore\n\n    @pytest.mark.parametrize(\n        \"dbt_command,run_sample_mode,expected_row_count\",\n        [\n            (\"run\", True, 2),\n            (\"run\", False, 3),\n            (\"build\", True, 2),\n            (\"build\", False, 3),\n        ],\n    )\n    @freezegun.freeze_time(\"2025-01-03T02:03:0Z\")\n    def test_sample_mode(\n        self,\n        project,\n        event_catcher: EventCatcher,\n        dbt_command: str,\n        run_sample_mode: bool,\n        expected_row_count: int,\n    ):\n        run_args = [dbt_command]\n        expected_sample = None\n        if run_sample_mode:\n            run_args.append(\"--sample=1 day\")\n            expected_sample = SampleWindow(\n                start=datetime(2025, 1, 2, 2, 3, 0, 0, tzinfo=pytz.UTC),\n                end=datetime(2025, 1, 3, 2, 3, 0, 0, tzinfo=pytz.UTC),\n            )\n\n        _ = run_dbt(run_args, callbacks=[event_catcher.catch])\n        assert len(event_catcher.caught_events) == 1\n        assert event_catcher.caught_events[0].info.msg == f\"Sample: {expected_sample}\"  # type: ignore\n        self.assert_row_count(\n            project=project,\n            relation_name=\"sample_mode_model\",\n            expected_row_count=expected_row_count,\n        )\n\n\nclass TestMicrobatchSampleMode(BaseSampleMode):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"input_model.sql\": input_model_sql,\n            \"sample_microbatch_model.sql\": sample_microbatch_model_sql,\n        }\n\n    @pytest.fixture\n    def event_time_start_catcher(self) -> EventCatcher:\n        return EventCatcher(event_to_catch=JinjaLogInfo, predicate=lambda event: \"batch.event_time_start\" in event.info.msg)  # type: ignore\n\n    @pytest.fixture\n    def event_time_end_catcher(self) -> EventCatcher:\n        return EventCatcher(event_to_catch=JinjaLogInfo, predicate=lambda event: \"batch.event_time_end\" in event.info.msg)  # type: ignore\n\n    @freezegun.freeze_time(\"2025-01-03T02:03:0Z\")\n    def test_sample_mode(\n        self,\n        project,\n        event_time_end_catcher: EventCatcher,\n        event_time_start_catcher: EventCatcher,\n    ):\n        expected_batches = [\n            (\"2025-01-01 00:00:00\", \"2025-01-02 00:00:00\"),\n            (\"2025-01-02 00:00:00\", \"2025-01-03 00:00:00\"),\n            (\"2025-01-03 00:00:00\", \"2025-01-04 00:00:00\"),\n        ]\n        expected_filters = [\n            \"event_time >= '2025-01-01 02:03:00+00:00' and event_time < '2025-01-02 00:00:00+00:00'\",\n            \"event_time >= '2025-01-02 00:00:00+00:00' and event_time < '2025-01-03 00:00:00+00:00'\",\n            \"event_time >= '2025-01-03 00:00:00+00:00' and event_time < '2025-01-03 02:03:00+00:00'\",\n        ]\n\n        _ = run_dbt(\n            [\"run\", \"--sample=2 day\"],\n            callbacks=[event_time_end_catcher.catch, event_time_start_catcher.catch],\n        )\n        assert len(event_time_start_catcher.caught_events) == len(expected_batches)\n        assert len(event_time_end_catcher.caught_events) == len(expected_batches)\n\n        for index in range(len(expected_batches)):\n            assert expected_batches[index][0] in event_time_start_catcher.caught_events[index].info.msg  # type: ignore\n            assert expected_batches[index][1] in event_time_end_catcher.caught_events[index].info.msg  # type: ignore\n\n            batch_id = MicrobatchBuilder.format_batch_start(\n                datetime.fromisoformat(expected_batches[index][0]), BatchSize.day\n            )\n            batch_file_name = f\"sample_microbatch_model_{batch_id}.sql\"\n            compiled_sql = read_file(\n                project.project_root,\n                \"target\",\n                \"compiled\",\n                \"test\",\n                \"models\",\n                \"sample_microbatch_model\",\n                batch_file_name,\n            )\n            assert expected_filters[index] in compiled_sql\n\n        # The first row of the \"input_model\" should be excluded from the sample because\n        # it falls outside of the filter for the first batch (which is only doing a _partial_ batch selection)\n        self.assert_row_count(\n            project=project,\n            relation_name=\"sample_microbatch_model\",\n            expected_row_count=2,\n        )\n\n\nclass TestIncrementalModelSampleModeRelative(BaseSampleMode):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"input_model.sql\": input_model_sql,\n            \"sample_incremental_merge.sql\": sample_incremental_merge_sql,\n        }\n\n    @pytest.fixture\n    def event_catcher(self) -> EventCatcher:\n        return EventCatcher(event_to_catch=JinjaLogInfo, predicate=lambda event: \"is_incremental: True\" in event.info.msg)  # type: ignore\n\n    @pytest.mark.parametrize(\n        \"sample,expected_rows\",\n        [\n            (None, 6),\n            (\"3 days\", 6),\n            (\"2 days\", 5),\n        ],\n    )\n    @freezegun.freeze_time(\"2025-01-06T18:03:0Z\")\n    def test_incremental_model_sample(\n        self,\n        project,\n        event_catcher: EventCatcher,\n        sample: Optional[str],\n        expected_rows: int,\n    ):\n        # writing the input_model is necessary because we've parametrized the test\n        # thus the \"later_input_model\" will still be present on the \"non-first\" runs\n        write_file(input_model_sql, \"models\", \"input_model.sql\")\n\n        # --full-refresh is necessary because we've parametrized the test\n        _ = run_dbt([\"run\", \"--full-refresh\"], callbacks=[event_catcher.catch])\n\n        assert len(event_catcher.caught_events) == 0\n        self.assert_row_count(\n            project=project,\n            relation_name=\"sample_incremental_merge\",\n            expected_row_count=3,\n        )\n\n        # update the input file to have more rows\n        write_file(later_input_model_sql, \"models\", \"input_model.sql\")\n\n        run_args = [\"run\"]\n        if sample is not None:\n            run_args.extend([f\"--sample={sample}\"])\n\n        _ = run_dbt(run_args, callbacks=[event_catcher.catch])\n\n        assert len(event_catcher.caught_events) == 1\n        self.assert_row_count(\n            project=project,\n            relation_name=\"sample_incremental_merge\",\n            expected_row_count=expected_rows,\n        )\n\n\nclass TestIncrementalModelSampleModeSpecific(BaseSampleMode):\n    # This had to be split out from the \"relative\" tests because `freezegun.freezetime`\n    # breaks how timestamps get created.\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"input_model.sql\": input_model_sql,\n            \"sample_incremental_merge.sql\": sample_incremental_merge_sql,\n        }\n\n    @pytest.fixture\n    def event_catcher(self) -> EventCatcher:\n        return EventCatcher(event_to_catch=JinjaLogInfo, predicate=lambda event: \"is_incremental: True\" in event.info.msg)  # type: ignore\n\n    @pytest.mark.parametrize(\n        \"sample,expected_rows\",\n        [\n            (None, 6),\n            (\"{'start': '2025-01-03', 'end': '2025-01-07'}\", 6),\n            (\"{'start': '2025-01-04', 'end': '2025-01-06'}\", 5),\n            (\"{'start': '2025-01-05', 'end': '2025-01-07'}\", 5),\n            (\"{'start': '2024-12-31', 'end': '2025-01-03'}\", 3),\n        ],\n    )\n    def test_incremental_model_sample(\n        self,\n        project,\n        event_catcher: EventCatcher,\n        sample: Optional[str],\n        expected_rows: int,\n    ):\n        # writing the input_model is necessary because we've parametrized the test\n        # thus the \"later_input_model\" will still be present on the \"non-first\" runs\n        write_file(input_model_sql, \"models\", \"input_model.sql\")\n\n        # --full-refresh is necessary because we've parametrized the test\n        _ = run_dbt([\"run\", \"--full-refresh\"], callbacks=[event_catcher.catch])\n\n        assert len(event_catcher.caught_events) == 0\n        self.assert_row_count(\n            project=project,\n            relation_name=\"sample_incremental_merge\",\n            expected_row_count=3,\n        )\n\n        # update the input file to have more rows\n        write_file(later_input_model_sql, \"models\", \"input_model.sql\")\n\n        run_args = [\"run\"]\n        if sample is not None:\n            run_args.extend([f\"--sample={sample}\"])\n\n        _ = run_dbt(run_args, callbacks=[event_catcher.catch])\n\n        assert len(event_catcher.caught_events) == 1\n        self.assert_row_count(\n            project=project,\n            relation_name=\"sample_incremental_merge\",\n            expected_row_count=expected_rows,\n        )\n\n\nclass TestSampleSeedRefs(BaseSampleMode):\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\n            \"input_seed.csv\": input_seed_csv,\n            \"properties.yml\": seed_properties_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"sample_input_seed.sql\": sample_input_seed_sql,\n        }\n\n    @pytest.mark.parametrize(\n        \"run_sample_mode,expected_row_count\",\n        [\n            (True, 2),\n            (False, 3),\n        ],\n    )\n    @freezegun.freeze_time(\"2025-01-03T02:03:0Z\")\n    def test_sample_mode(\n        self,\n        project,\n        run_sample_mode: bool,\n        expected_row_count: int,\n    ):\n        run_args = [\"run\"]\n        if run_sample_mode:\n            run_args.append(\"--sample=1 day\")\n\n        _ = run_dbt([\"seed\"])\n        _ = run_dbt(run_args)\n        self.assert_row_count(\n            project=project,\n            relation_name=\"sample_input_seed\",\n            expected_row_count=expected_row_count,\n        )\n\n\nclass TestSamplingModelFromSnapshot(BaseSampleMode):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"input_model.sql\": input_model_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def snapshots(self):\n        return {\n            \"snapshot_input_model.sql\": snapshot_input_model_sql,\n        }\n\n    @pytest.mark.parametrize(\n        \"run_sample_mode,expected_row_count\",\n        [\n            (True, 2),\n            (False, 3),\n        ],\n    )\n    @freezegun.freeze_time(\"2025-01-03T02:03:0Z\")\n    def test_sample_mode(\n        self,\n        project,\n        run_sample_mode: bool,\n        expected_row_count: int,\n    ):\n        run_args = [\"build\"]\n        if run_sample_mode:\n            run_args.append(\"--sample=1 day\")\n\n        _ = run_dbt(run_args)\n        self.assert_row_count(\n            project=project,\n            relation_name=\"snapshot_input_model\",\n            expected_row_count=expected_row_count,\n        )\n        self.drop_table(project, \"snapshot_input_model\")\n\n\nclass TestSamplingSnapshot(BaseSampleMode):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"input_model.sql\": input_model_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def snapshots(self):\n        return {\n            \"snapshot_input_model.sql\": snapshot_input_model_sql,\n        }\n\n    @pytest.mark.parametrize(\n        \"run_sample_mode,expected_row_count\",\n        [\n            (True, 2),\n            (False, 3),\n        ],\n    )\n    @freezegun.freeze_time(\"2025-01-03T02:03:0Z\")\n    def test_sample_mode(\n        self,\n        project,\n        run_sample_mode: bool,\n        expected_row_count: int,\n    ):\n        run_args = [\"build\"]\n\n        # create the snapshot before building a model that depends on it\n        _ = run_dbt(run_args)\n        # Snapshot should always have 3 in this test because we don't sample it\n        self.assert_row_count(\n            project=project,\n            relation_name=\"snapshot_input_model\",\n            expected_row_count=3,\n        )\n\n        if run_sample_mode:\n            run_args.append(\"--sample=1 day\")\n\n        # create model that depends on the snapshot\n        write_file(\n            model_from_snapshot_sql, project.project_root, \"models\", \"model_from_snapshot.sql\"\n        )\n\n        _ = run_dbt(run_args)\n        self.assert_row_count(\n            project=project,\n            relation_name=\"model_from_snapshot\",\n            expected_row_count=expected_row_count,\n        )\n        self.drop_table(project, \"snapshot_input_model\")\n"
  },
  {
    "path": "tests/functional/saved_queries/__init__.py",
    "content": ""
  },
  {
    "path": "tests/functional/saved_queries/fixtures.py",
    "content": "saved_query_description = \"\"\"\n{% docs saved_query_description %} My SavedQuery Description {% enddocs %}\n\"\"\"\n\nsaved_queries_yml = \"\"\"\nsaved_queries:\n  - name: test_saved_query\n    description: \"{{ doc('saved_query_description') }}\"\n    label: Test Saved Query\n    query_params:\n        metrics:\n            - simple_metric\n        group_by:\n            - \"Dimension('id__ds')\"\n        where:\n            - \"{{ TimeDimension('id__ds', 'DAY') }} <= now()\"\n            - \"{{ TimeDimension('id__ds', 'DAY') }} >= '2023-01-01'\"\n            - \"{{ Metric('txn_revenue', ['id']) }} > 1\"\n        order_by:\n            - Metric('simple_metric').descending(True)\n            - \"Dimension('id__ds').descending(True)\"\n        limit: 10\n    exports:\n        - name: my_export\n          config:\n            alias: my_export_alias\n            export_as: table\n            schema: my_export_schema_name\n\"\"\"\n\nsaved_queries_with_defaults_yml = \"\"\"\nsaved_queries:\n  - name: test_saved_query\n    description: \"{{ doc('saved_query_description') }}\"\n    label: Test Saved Query\n    query_params:\n        metrics:\n            - simple_metric\n        group_by:\n            - \"Dimension('id__ds')\"\n        where:\n            - \"{{ TimeDimension('id__ds', 'DAY') }} <= now()\"\n            - \"{{ TimeDimension('id__ds', 'DAY') }} >= '2023-01-01'\"\n            - \"{{ Metric('txn_revenue', ['id']) }} > 1\"\n    exports:\n        - name: my_export\n          config:\n            alias: my_export_alias\n            export_as: table\n\"\"\"\n\nsaved_queries_with_diff_filters_yml = \"\"\"\nsaved_queries:\n  - name: test_saved_query_where_list\n    description: \"{{ doc('saved_query_description') }}\"\n    label: Test Saved Query\n    query_params:\n        metrics:\n            - simple_metric\n        group_by:\n            - \"Dimension('id__ds')\"\n        where:\n            - \"{{ TimeDimension('id__ds', 'DAY') }} <= now()\"\n            - \"{{ TimeDimension('id__ds', 'DAY') }} >= '2023-01-01'\"\n    exports:\n        - name: my_export\n          config:\n            alias: my_export_alias\n            export_as: table\n            schema: my_export_schema_name\n\n  - name: test_saved_query_where_str\n    description: \"{{ doc('saved_query_description') }}\"\n    label: Test Saved Query2\n    query_params:\n      metrics:\n        - simple_metric\n      group_by:\n        - \"Dimension('id__ds')\"\n      where: \"{{ TimeDimension('id__ds', 'DAY') }} <= now()\"\n\"\"\"\n\nsaved_query_with_extra_config_attributes_yml = \"\"\"\nsaved_queries:\n  - name: test_saved_query\n    description: \"{{ doc('saved_query_description') }}\"\n    label: Test Saved Query\n    query_params:\n        metrics:\n            - simple_metric\n        group_by:\n            - \"Dimension('id__ds')\"\n        where:\n            - \"{{ TimeDimension('id__ds', 'DAY') }} <= now()\"\n            - \"{{ TimeDimension('id__ds', 'DAY') }} >= '2023-01-01'\"\n    exports:\n        - name: my_export\n          config:\n            my_random_config: 'I have this for some reason'\n            export_as: table\n\"\"\"\n\nsaved_query_with_export_configs_defined_at_saved_query_level_yml = \"\"\"\nsaved_queries:\n  - name: test_saved_query\n    description: \"{{ doc('saved_query_description') }}\"\n    label: Test Saved Query\n    config:\n      export_as: table\n      schema: my_default_export_schema\n    query_params:\n        metrics:\n            - simple_metric\n        group_by:\n            - \"Dimension('id__ds')\"\n        where:\n            - \"{{ TimeDimension('id__ds', 'DAY') }} <= now()\"\n            - \"{{ TimeDimension('id__ds', 'DAY') }} >= '2023-01-01'\"\n    exports:\n        - name: my_export\n          config:\n            export_as: view\n            schema: my_custom_export_schema\n        - name: my_export2\n\"\"\"\n\nsaved_query_without_export_configs_defined_yml = \"\"\"\nsaved_queries:\n  - name: test_saved_query\n    description: \"{{ doc('saved_query_description') }}\"\n    label: Test Saved Query\n    query_params:\n        metrics:\n            - simple_metric\n        group_by:\n            - \"Dimension('id__ds')\"\n        where:\n            - \"{{ TimeDimension('id__ds', 'DAY') }} <= now()\"\n            - \"{{ TimeDimension('id__ds', 'DAY') }} >= '2023-01-01'\"\n    exports:\n        - name: my_export\n\"\"\"\n\nsaved_query_with_cache_configs_defined_yml = \"\"\"\nsaved_queries:\n  - name: test_saved_query\n    description: \"{{ doc('saved_query_description') }}\"\n    label: Test Saved Query\n    config:\n      cache:\n        enabled: True\n    query_params:\n        metrics:\n            - simple_metric\n        group_by:\n            - \"Dimension('id__ds')\"\n        where:\n            - \"{{ TimeDimension('id__ds', 'DAY') }} <= now()\"\n            - \"{{ TimeDimension('id__ds', 'DAY') }} >= '2023-01-01'\"\n    exports:\n        - name: my_export\n          config:\n            alias: my_export_alias\n            export_as: table\n            schema: my_export_schema_name\n\"\"\"\n\nsaved_query_with_tags_defined_yml = \"\"\"\nsaved_queries:\n  - name: test_saved_query\n    description: \"{{ doc('saved_query_description') }}\"\n    label: Test Saved Query\n    tags:\n        - tag_a\n        - tag_c\n    query_params:\n        metrics:\n            - simple_metric\n        group_by:\n            - \"Dimension('id__ds')\"\n        where:\n            - \"{{ TimeDimension('id__ds', 'DAY') }} <= now()\"\n            - \"{{ TimeDimension('id__ds', 'DAY') }} >= '2023-01-01'\"\n    exports:\n        - name: my_export\n          config:\n            alias: my_export_alias\n            export_as: table\n            schema: my_export_schema_name\n\"\"\"\n"
  },
  {
    "path": "tests/functional/saved_queries/test_configs.py",
    "content": "import pytest\n\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.tests.util import update_config_file\nfrom dbt_semantic_interfaces.type_enums.export_destination_type import (\n    ExportDestinationType,\n)\nfrom tests.functional.assertions.test_runner import dbtTestRunner\nfrom tests.functional.configs.fixtures import BaseConfigProject\nfrom tests.functional.saved_queries.fixtures import (\n    saved_queries_with_defaults_yml,\n    saved_queries_yml,\n    saved_query_description,\n    saved_query_with_cache_configs_defined_yml,\n    saved_query_with_export_configs_defined_at_saved_query_level_yml,\n    saved_query_with_extra_config_attributes_yml,\n    saved_query_with_tags_defined_yml,\n    saved_query_without_export_configs_defined_yml,\n)\nfrom tests.functional.semantic_models.fixtures import (\n    fct_revenue_sql,\n    metricflow_time_spine_sql,\n    schema_yml,\n)\n\n\nclass TestSavedQueryConfigs(BaseConfigProject):\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"saved-queries\": {\n                \"test\": {\n                    \"test_saved_query\": {\n                        \"+enabled\": True,\n                        \"+export_as\": ExportDestinationType.VIEW.value,\n                        \"+schema\": \"my_default_export_schema\",\n                        \"+cache\": {\"enabled\": True},\n                    }\n                },\n            },\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"saved_queries.yml\": saved_query_with_extra_config_attributes_yml,\n            \"schema.yml\": schema_yml,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"docs.md\": saved_query_description,\n        }\n\n    def test_basic_saved_query_config(\n        self,\n        project,\n    ):\n        runner = dbtTestRunner()\n\n        # parse with default fixture project config\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        assert isinstance(result.result, Manifest)\n        assert len(result.result.saved_queries) == 1\n        saved_query = result.result.saved_queries[\"saved_query.test.test_saved_query\"]\n        assert saved_query.config.export_as == ExportDestinationType.VIEW\n        assert saved_query.config.schema == \"my_default_export_schema\"\n        assert saved_query.config.cache.enabled is True\n\n        # disable the saved_query via project config and rerun\n        config_patch = {\"saved-queries\": {\"test\": {\"test_saved_query\": {\"+enabled\": False}}}}\n        update_config_file(config_patch, project.project_root, \"dbt_project.yml\")\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        assert len(result.result.saved_queries) == 0\n\n\n# Test that the cache will default to enabled = false if not set in the saved_query config\nclass TestSavedQueryDefaultCacheConfigs(BaseConfigProject):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"saved_queries.yml\": saved_query_with_extra_config_attributes_yml,\n            \"schema.yml\": schema_yml,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"docs.md\": saved_query_description,\n        }\n\n    def test_basic_saved_query_config(\n        self,\n        project,\n    ):\n        runner = dbtTestRunner()\n\n        # parse with default fixture project config\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        assert isinstance(result.result, Manifest)\n        assert len(result.result.saved_queries) == 1\n        saved_query = result.result.saved_queries[\"saved_query.test.test_saved_query\"]\n        assert saved_query.config.cache.enabled is False\n\n\nclass TestExportConfigsWithAdditionalProperties(BaseConfigProject):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"saved_queries.yml\": saved_queries_yml,\n            \"schema.yml\": schema_yml,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"docs.md\": saved_query_description,\n        }\n\n    def test_extra_config_properties_dont_break_parsing(self, project):\n        runner = dbtTestRunner()\n\n        # parse with default fixture project config\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        assert isinstance(result.result, Manifest)\n        assert len(result.result.saved_queries) == 1\n        saved_query = result.result.saved_queries[\"saved_query.test.test_saved_query\"]\n        assert len(saved_query.exports) == 1\n        assert saved_query.exports[0].config.__dict__.get(\"my_random_config\") is None\n\n\nclass TestExportConfigsWithDefaultProperties(BaseConfigProject):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"saved_queries.yml\": saved_queries_with_defaults_yml,\n            \"schema.yml\": schema_yml,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"docs.md\": saved_query_description,\n        }\n\n    def test_default_properties(self, project):\n        runner = dbtTestRunner()\n\n        # parse with default fixture project config\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        assert isinstance(result.result, Manifest)\n        assert len(result.result.saved_queries) == 1\n        saved_query = result.result.saved_queries[\"saved_query.test.test_saved_query\"]\n        assert len(saved_query.exports) == 1\n        export = saved_query.exports[0]\n        assert export.config.alias == \"my_export_alias\"\n        assert export.config.schema_name == project.test_schema\n        assert export.config.database == project.database\n\n\nclass TestInheritingExportConfigFromSavedQueryConfig(BaseConfigProject):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"saved_queries.yml\": saved_query_with_export_configs_defined_at_saved_query_level_yml,\n            \"schema.yml\": schema_yml,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"docs.md\": saved_query_description,\n        }\n\n    def test_export_config_inherits_from_saved_query(self, project):\n        runner = dbtTestRunner()\n\n        # parse with default fixture project config\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        assert isinstance(result.result, Manifest)\n        assert len(result.result.saved_queries) == 1\n        saved_query = result.result.saved_queries[\"saved_query.test.test_saved_query\"]\n        assert len(saved_query.exports) == 2\n\n        # assert Export `my_export` has its configs defined from itself because they should take priority\n        export1 = next(\n            (export for export in saved_query.exports if export.name == \"my_export\"), None\n        )\n        assert export1 is not None\n        assert export1.config.export_as == ExportDestinationType.VIEW\n        assert export1.config.export_as != saved_query.config.export_as\n        assert export1.config.schema_name == \"my_custom_export_schema\"\n        assert export1.config.schema_name != saved_query.config.schema\n        assert export1.config.database == project.database\n\n        # assert Export `my_export` has its configs defined from the saved_query because they should take priority\n        export2 = next(\n            (export for export in saved_query.exports if export.name == \"my_export2\"), None\n        )\n        assert export2 is not None\n        assert export2.config.export_as == ExportDestinationType.TABLE\n        assert export2.config.export_as == saved_query.config.export_as\n        assert export2.config.schema_name == \"my_default_export_schema\"\n        assert export2.config.schema_name == saved_query.config.schema\n        assert export2.config.database == project.database\n\n\nclass TestInheritingExportConfigsFromProject(BaseConfigProject):\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"saved-queries\": {\n                \"test\": {\n                    \"test_saved_query\": {\n                        \"+export_as\": ExportDestinationType.VIEW.value,\n                    }\n                },\n            },\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"saved_queries.yml\": saved_query_without_export_configs_defined_yml,\n            \"schema.yml\": schema_yml,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"docs.md\": saved_query_description,\n        }\n\n    def test_export_config_inherits_from_project(\n        self,\n        project,\n    ):\n        runner = dbtTestRunner()\n\n        # parse with default fixture project config\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        assert isinstance(result.result, Manifest)\n        assert len(result.result.saved_queries) == 1\n        saved_query = result.result.saved_queries[\"saved_query.test.test_saved_query\"]\n        assert saved_query.config.export_as == ExportDestinationType.VIEW\n\n        # change export's `export_as` to `TABLE` via project config\n        config_patch = {\n            \"saved-queries\": {\n                \"test\": {\"test_saved_query\": {\"+export_as\": ExportDestinationType.TABLE.value}}\n            }\n        }\n        update_config_file(config_patch, project.project_root, \"dbt_project.yml\")\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        assert isinstance(result.result, Manifest)\n        assert len(result.result.saved_queries) == 1\n        saved_query = result.result.saved_queries[\"saved_query.test.test_saved_query\"]\n        assert saved_query.config.export_as == ExportDestinationType.TABLE\n\n\n# cache can be specified just in a SavedQuery config\nclass TestSavedQueryLevelCacheConfigs(BaseConfigProject):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"saved_queries.yml\": saved_query_with_cache_configs_defined_yml,\n            \"schema.yml\": schema_yml,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"docs.md\": saved_query_description,\n        }\n\n    def test_basic_saved_query_config(\n        self,\n        project,\n    ):\n        runner = dbtTestRunner()\n\n        # parse with default fixture project config\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        assert isinstance(result.result, Manifest)\n        assert len(result.result.saved_queries) == 1\n        saved_query = result.result.saved_queries[\"saved_query.test.test_saved_query\"]\n        assert saved_query.config.cache.enabled is True\n\n\n# the cache defined in yaml for the SavedQuery overrides settings from the dbt_project.toml\nclass TestSavedQueryCacheConfigsOverride(BaseConfigProject):\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"saved-queries\": {\n                \"test\": {\n                    \"test_saved_query\": {\n                        \"+cache\": {\"enabled\": True},\n                    }\n                },\n            },\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"saved_queries.yml\": saved_query_with_cache_configs_defined_yml,\n            \"schema.yml\": schema_yml,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"docs.md\": saved_query_description,\n        }\n\n    def test_override_saved_query_config(\n        self,\n        project,\n    ):\n        runner = dbtTestRunner()\n\n        # parse with default fixture project config\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        assert isinstance(result.result, Manifest)\n        assert len(result.result.saved_queries) == 1\n        saved_query = result.result.saved_queries[\"saved_query.test.test_saved_query\"]\n        assert saved_query.config.cache.enabled is True\n\n        # set cache to enabled=False via project config but since it's set to true at the saved_query\n        # level, it should stay enabled\n        config_patch = {\n            \"saved-queries\": {\"test\": {\"test_saved_query\": {\"+cache\": {\"enabled\": False}}}}\n        }\n        update_config_file(config_patch, project.project_root, \"dbt_project.yml\")\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        assert saved_query.config.cache.enabled is True\n\n\n# the tags defined in project yaml for the SavedQuery is additive to the query's\nclass TestSavedQueryTagsAdditiveWithConfig(BaseConfigProject):\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"saved-queries\": {\"+tags\": [\"tag_b\", \"tag_c\"]},\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"saved_queries.yml\": saved_query_with_tags_defined_yml,\n            \"schema.yml\": schema_yml,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"docs.md\": saved_query_description,\n        }\n\n    def test_saved_query_tags_are_additive_unique_and_sorted(\n        self,\n        project,\n    ):\n        runner = dbtTestRunner()\n\n        # parse with default fixture project config\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        assert isinstance(result.result, Manifest)\n        assert len(result.result.saved_queries) == 1\n        saved_query = result.result.saved_queries[\"saved_query.test.test_saved_query\"]\n        assert saved_query.tags == [\"tag_a\", \"tag_b\", \"tag_c\"]\n"
  },
  {
    "path": "tests/functional/saved_queries/test_saved_query_build.py",
    "content": "import pytest\n\nfrom dbt.artifacts.schemas.results import RunStatus\nfrom dbt.contracts.graph.nodes import SavedQuery\nfrom dbt.tests.util import run_dbt\nfrom tests.functional.saved_queries.fixtures import (\n    saved_queries_yml,\n    saved_query_description,\n)\nfrom tests.functional.semantic_models.fixtures import (\n    fct_revenue_sql,\n    metricflow_time_spine_sql,\n    schema_yml,\n)\n\n\nclass TestSavedQueryBuild:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"saved_queries.yml\": saved_queries_yml,\n            \"schema.yml\": schema_yml,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"docs.md\": saved_query_description,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return \"\"\"\npackages:\n  - package: dbt-labs/dbt_utils\n    version: 1.1.1\n\"\"\"\n\n    def test_build_saved_queries_no_op(self, project) -> None:\n        \"\"\"Test building saved query exports with no flag, so should be no-op.\"\"\"\n        run_dbt([\"deps\"])\n        result = run_dbt([\"build\"])\n        assert len(result.results) == 3\n\n        saved_query_results = (\n            result for result in result.results if isinstance(result.node, SavedQuery)\n        )\n        assert {result.node.name for result in saved_query_results} == {\"test_saved_query\"}\n        assert all(\"NO-OP\" in result.message for result in saved_query_results)\n        assert all(result.status == RunStatus.NoOp for result in saved_query_results)\n"
  },
  {
    "path": "tests/functional/saved_queries/test_saved_query_parsing.py",
    "content": "import os\nimport shutil\nfrom copy import deepcopy\nfrom typing import List\n\nimport pytest\n\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.tests.util import run_dbt, write_file\nfrom dbt_common.events.base_types import BaseEvent\nfrom dbt_semantic_interfaces.type_enums.export_destination_type import (\n    ExportDestinationType,\n)\nfrom tests.functional.assertions.test_runner import dbtTestRunner\nfrom tests.functional.saved_queries.fixtures import (\n    saved_queries_with_defaults_yml,\n    saved_queries_with_diff_filters_yml,\n    saved_queries_yml,\n    saved_query_description,\n    saved_query_with_cache_configs_defined_yml,\n)\nfrom tests.functional.semantic_models.fixtures import (\n    fct_revenue_sql,\n    metricflow_time_spine_sql,\n    schema_yml,\n)\n\n\nclass TestSavedQueryParsing:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"saved_queries.yml\": saved_queries_yml,\n            \"schema.yml\": schema_yml,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"docs.md\": saved_query_description,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def other_schema(self, unique_schema):\n        return unique_schema + \"_other\"\n\n    @pytest.fixture(scope=\"class\")\n    def profiles_config_update(self, dbt_profile_target, unique_schema, other_schema):\n        outputs = {\"default\": dbt_profile_target, \"prod\": deepcopy(dbt_profile_target)}\n        outputs[\"default\"][\"schema\"] = unique_schema\n        outputs[\"prod\"][\"schema\"] = other_schema\n        return {\"test\": {\"outputs\": outputs, \"target\": \"default\"}}\n\n    def copy_state(self):\n        if not os.path.exists(\"state\"):\n            os.makedirs(\"state\")\n        shutil.copyfile(\"target/manifest.json\", \"state/manifest.json\")\n\n    def test_semantic_model_parsing(self, project):\n        runner = dbtTestRunner()\n        result = runner.invoke([\"parse\", \"--no-partial-parse\"])\n        assert result.success\n        assert isinstance(result.result, Manifest)\n        manifest = result.result\n        assert len(manifest.saved_queries) == 1\n        saved_query = manifest.saved_queries[\"saved_query.test.test_saved_query\"]\n        assert saved_query.name == \"test_saved_query\"\n        assert len(saved_query.query_params.metrics) == 1\n        assert len(saved_query.query_params.group_by) == 1\n        assert len(saved_query.query_params.where.where_filters) == 3\n        assert len(saved_query.depends_on.nodes) == 1\n\n        assert len(saved_query.query_params.order_by) == 2\n        assert saved_query.query_params.limit is not None\n\n        assert saved_query.description == \"My SavedQuery Description\"\n        assert len(saved_query.exports) == 1\n        assert saved_query.exports[0].name == \"my_export\"\n        assert saved_query.exports[0].config.alias == \"my_export_alias\"\n        assert saved_query.exports[0].config.export_as == ExportDestinationType.TABLE\n        assert saved_query.exports[0].config.schema_name == \"my_export_schema_name\"\n        assert saved_query.exports[0].unrendered_config == {\n            \"alias\": \"my_export_alias\",\n            \"export_as\": \"table\",\n            \"schema\": \"my_export_schema_name\",\n        }\n\n        # Save state\n        self.copy_state()\n        # Nothing has changed, so no state:modified results\n        results = run_dbt([\"ls\", \"--select\", \"state:modified\", \"--state\", \"./state\"])\n        assert len(results) == 0\n\n        # Change saved_query\n        write_file(\n            saved_query_with_cache_configs_defined_yml,\n            project.project_root,\n            \"models\",\n            \"saved_queries.yml\",\n        )\n        # State modified finds changed saved_query\n        results = run_dbt([\"ls\", \"--select\", \"state:modified\", \"--state\", \"./state\"])\n        assert len(results) == 1\n\n        # change exports\n        write_file(\n            saved_queries_with_defaults_yml, project.project_root, \"models\", \"saved_queries.yml\"\n        )\n        # State modified finds changed saved_query\n        results = run_dbt([\"ls\", \"--select\", \"state:modified\", \"--state\", \"./state\"])\n        assert len(results) == 1\n\n    def test_semantic_model_parsing_change_export(self, project, other_schema):\n        runner = dbtTestRunner()\n        result = runner.invoke([\"parse\", \"--no-partial-parse\"])\n        assert result.success\n        assert isinstance(result.result, Manifest)\n        manifest = result.result\n        assert len(manifest.saved_queries) == 1\n        saved_query = manifest.saved_queries[\"saved_query.test.test_saved_query\"]\n        assert saved_query.name == \"test_saved_query\"\n        assert saved_query.exports[0].name == \"my_export\"\n\n        # Save state\n        self.copy_state()\n        # Nothing has changed, so no state:modified results\n        results = run_dbt([\"ls\", \"--select\", \"state:modified\", \"--state\", \"./state\"])\n        assert len(results) == 0\n\n        # Change export name\n        write_file(\n            saved_queries_yml.replace(\"name: my_export\", \"name: my_expor2\"),\n            project.project_root,\n            \"models\",\n            \"saved_queries.yml\",\n        )\n        # State modified finds changed saved_query\n        results = run_dbt([\"ls\", \"--select\", \"state:modified\", \"--state\", \"./state\"])\n        assert len(results) == 1\n\n        # Change export schema\n        write_file(\n            saved_queries_yml.replace(\n                \"schema: my_export_schema_name\", \"schema: my_export_schema_name2\"\n            ),\n            project.project_root,\n            \"models\",\n            \"saved_queries.yml\",\n        )\n        # State modified finds changed saved_query\n        results = run_dbt([\"ls\", \"--select\", \"state:modified\", \"--state\", \"./state\"])\n        assert len(results) == 1\n\n    def test_semantic_model_parsing_with_default_schema(self, project, other_schema):\n        write_file(\n            saved_queries_with_defaults_yml, project.project_root, \"models\", \"saved_queries.yml\"\n        )\n        runner = dbtTestRunner()\n        result = runner.invoke([\"parse\", \"--no-partial-parse\", \"--target\", \"prod\"])\n        assert result.success\n        assert isinstance(result.result, Manifest)\n        manifest = result.result\n        assert len(manifest.saved_queries) == 1\n        saved_query = manifest.saved_queries[\"saved_query.test.test_saved_query\"]\n        assert saved_query.name == \"test_saved_query\"\n        assert len(saved_query.query_params.metrics) == 1\n        assert len(saved_query.query_params.group_by) == 1\n        assert len(saved_query.query_params.where.where_filters) == 3\n        assert len(saved_query.depends_on.nodes) == 1\n        assert saved_query.description == \"My SavedQuery Description\"\n        assert len(saved_query.exports) == 1\n        assert saved_query.exports[0].name == \"my_export\"\n        assert saved_query.exports[0].config.alias == \"my_export_alias\"\n        assert saved_query.exports[0].config.export_as == ExportDestinationType.TABLE\n        assert saved_query.exports[0].config.schema_name == other_schema\n        assert saved_query.exports[0].unrendered_config == {\n            \"alias\": \"my_export_alias\",\n            \"export_as\": \"table\",\n        }\n\n        # Save state\n        self.copy_state()\n        # Nothing has changed, so no state:modified results\n        results = run_dbt(\n            [\"ls\", \"--select\", \"state:modified\", \"--state\", \"./state\", \"--target\", \"prod\"]\n        )\n        assert len(results) == 0\n\n        # There should also be no state:modified results when using the default schema\n        results = run_dbt([\"ls\", \"--select\", \"state:modified\", \"--state\", \"./state\"])\n        assert len(results) == 0\n\n    def test_saved_query_error(self, project):\n        error_schema_yml = saved_queries_yml.replace(\"simple_metric\", \"metric_not_found\")\n        write_file(error_schema_yml, project.project_root, \"models\", \"saved_queries.yml\")\n        events: List[BaseEvent] = []\n        runner = dbtTestRunner(callbacks=[events.append])\n\n        result = runner.invoke([\"parse\", \"--no-partial-parse\"])\n        assert not result.success\n        validation_errors = [e for e in events if e.info.name == \"MainEncounteredError\"]\n        assert validation_errors\n\n\nclass TestSavedQueryPartialParsing:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"saved_queries.yml\": saved_queries_yml,\n            \"saved_queries_with_diff_filters.yml\": saved_queries_with_diff_filters_yml,\n            \"schema.yml\": schema_yml,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"docs.md\": saved_query_description,\n        }\n\n    def test_saved_query_filter_types(self, project):\n        runner = dbtTestRunner()\n        result = runner.invoke([\"parse\"])\n        assert result.success\n\n        manifest = result.result\n        saved_query1 = manifest.saved_queries[\"saved_query.test.test_saved_query_where_list\"]\n        saved_query2 = manifest.saved_queries[\"saved_query.test.test_saved_query_where_str\"]\n\n        # List filter\n        assert len(saved_query1.query_params.where.where_filters) == 2\n        assert {\n            where_filter.where_sql_template\n            for where_filter in saved_query1.query_params.where.where_filters\n        } == {\n            \"{{ TimeDimension('id__ds', 'DAY') }} <= now()\",\n            \"{{ TimeDimension('id__ds', 'DAY') }} >= '2023-01-01'\",\n        }\n        # String filter\n        assert len(saved_query2.query_params.where.where_filters) == 1\n        assert (\n            saved_query2.query_params.where.where_filters[0].where_sql_template\n            == \"{{ TimeDimension('id__ds', 'DAY') }} <= now()\"\n        )\n\n    def test_saved_query_metrics_changed(self, project):\n        # First, use the default saved_queries.yml to define our saved_queries, and\n        # run the dbt parse command\n        runner = dbtTestRunner()\n        result = runner.invoke([\"parse\"])\n        assert result.success\n\n        # Next, modify the default saved_queries.yml to change a detail of the saved\n        # query.\n        modified_saved_queries_yml = saved_queries_yml.replace(\"simple_metric\", \"txn_revenue\")\n        write_file(modified_saved_queries_yml, project.project_root, \"models\", \"saved_queries.yml\")\n\n        # Now, run the dbt parse command again.\n        result = runner.invoke([\"parse\"])\n        assert result.success\n\n        # Finally, verify that the manifest reflects the partially parsed change\n        manifest = result.result\n        saved_query = manifest.saved_queries[\"saved_query.test.test_saved_query\"]\n        assert len(saved_query.metrics) == 1\n        assert saved_query.metrics[0] == \"txn_revenue\"\n\n    def test_saved_query_deleted_partial_parsing(self, project):\n        # First, use the default saved_queries.yml to define our saved_query, and\n        # run the dbt parse command\n        runner = dbtTestRunner()\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        assert \"saved_query.test.test_saved_query\" in result.result.saved_queries\n\n        # Next, modify the default saved_queries.yml to remove the saved query.\n        write_file(\"\", project.project_root, \"models\", \"saved_queries.yml\")\n\n        # Now, run the dbt parse command again.\n        result = runner.invoke([\"parse\"])\n        assert result.success\n\n        # Finally, verify that the manifest reflects the deletion\n        assert \"saved_query.test.test_saved_query\" not in result.result.saved_queries\n"
  },
  {
    "path": "tests/functional/schema/fixtures/macros.py",
    "content": "_CUSTOM_MACRO = \"\"\"\n{% macro generate_schema_name(schema_name, node) %}\n\n    {{ schema_name }}_{{ target.schema }}_macro\n\n{% endmacro %}\n\"\"\"\n\n_CUSTOM_MACRO_W_CONFIG = \"\"\"\n{% macro generate_schema_name(schema_name, node) %}\n\n    {{ node.config['schema'] }}_{{ target.schema }}_macro\n\n{% endmacro %}\n\"\"\"\n\n_CUSTOM_MACRO_MULTI_SCHEMA = \"\"\"\n{% macro generate_alias_name(custom_alias_name=none, node=none) -%}\n    {%- set node_name = node.name | trim -%}\n    {%- set split_name = node_name.split('.') -%}\n    {%- set n_parts = split_name | length -%}\n\n    {{ split_name[1] if n_parts>1 else node_name }}\n\n{%- endmacro -%}\n\n\n{% macro generate_schema_name(custom_schema_name=none, node=none) -%}\n    {%- set default_schema = target.schema -%}\n    {%- set node_name = node.name | trim -%}\n    {%- set split_name = node_name.split('.') -%}\n    {%- set n_parts = split_name | length -%}\n\n    {{ split_name[0] if n_parts>1 else default_schema }}\n\n{%- endmacro -%}\n\"\"\"\n"
  },
  {
    "path": "tests/functional/schema/fixtures/sql.py",
    "content": "_TABLE_ONE = \"\"\"\nselect * from {{ ref('seed') }}\n\"\"\"\n_TABLE_ONE_DOT_MODEL_SCHEMA = \"first_schema\"\n_TABLE_ONE_DOT_MODEL_NAME = f\"{_TABLE_ONE_DOT_MODEL_SCHEMA}.view_1\"\n_TABLE_ONE_DOT_MODEL = \"\"\"\nselect * from {{ target.schema }}.seed\n\"\"\"\n\n_TABLE_TWO_SCHEMA = \"custom\"\n_TABLE_TWO = (\n    \"\"\"\n{{ config(schema='\"\"\"\n    + _TABLE_TWO_SCHEMA\n    + \"\"\"') }}\nselect * from {{ ref('view_1') }}\n\"\"\"\n)\n_TABLE_TWO_DOT_MODEL_SCHEMA = \"second_schema\"\n_TABLE_TWO_DOT_MODEL_NAME = f\"{_TABLE_TWO_DOT_MODEL_SCHEMA}.view_2\"\n_TABLE_TWO_DOT_MODEL = \"select * from {{ ref('\" + _TABLE_ONE_DOT_MODEL_NAME + \"') }}\"\n\n_TABLE_THREE_SCHEMA = \"test\"\n_TABLE_THREE = (\n    \"\"\"\n{{ config(materialized='table', schema='\"\"\"\n    + _TABLE_THREE_SCHEMA\n    + \"\"\"') }}\n\n\nwith v1 as (\n\n    select * from{{ ref('view_1') }}\n\n),\n\nv2 as (\n\n    select * from {{ ref('view_2') }}\n\n),\n\ncombined as (\n\n    select last_name from v1\n    union all\n    select last_name from v2\n\n)\n\nselect\n    last_name,\n    count(*) as count\n\nfrom combined\ngroup by 1\n\"\"\"\n)\n\n_TABLE_THREE_DOT_MODEL = \"\"\"\n{{ config(materialized='table') }}\n\n\nwith v1 as (\n\n    select * from {{ ref('first_schema.view_1') }}\n\n),\n\nv2 as (\n\n    select * from {{ ref('second_schema.view_2') }}\n\n),\n\ncombined as (\n\n    select last_name from v1\n    union all\n    select last_name from v2\n\n)\n\nselect\n    last_name,\n    count(*) as count\n\nfrom combined\ngroup by 1\n\"\"\"\n\n_SEED_CSV = \"\"\"id,first_name,last_name,email,gender,ip_address\n1,Jack,Hunter,jhunter0@pbs.org,Male,59.80.20.168\n2,Kathryn,Walker,kwalker1@ezinearticles.com,Female,194.121.179.35\n3,Gerald,Ryan,gryan2@com.com,Male,11.3.212.243\"\"\"\n\n_CUSTOM_CONFIG = \"\"\"\n{{ config(schema='custom') }}\n\nselect * from {{ ref('view_1') }}\n\"\"\"\n\n_VALIDATION_SQL = \"\"\"\ndrop table if exists {database}.{schema}.seed cascade;\ncreate table {database}.{schema}.seed (\n   id BIGSERIAL PRIMARY KEY,\n   first_name VARCHAR(50),\n   last_name VARCHAR(50),\n   email VARCHAR(50),\n   gender VARCHAR(50),\n   ip_address VARCHAR(20)\n);\n\ndrop table if exists {database}.{schema}.agg cascade;\ncreate table {database}.{schema}.agg (\n   last_name VARCHAR(50),\n   count BIGINT\n);\n\n\ninsert into {database}.{schema}.seed (first_name, last_name, email, gender, ip_address) values\n('Jack', 'Hunter', 'jhunter0@pbs.org', 'Male', '59.80.20.168'),\n('Kathryn', 'Walker', 'kwalker1@ezinearticles.com', 'Female', '194.121.179.35'),\n('Gerald', 'Ryan', 'gryan2@com.com', 'Male', '11.3.212.243');\n\ninsert into {database}.{schema}.agg (last_name, count) values\n('Hunter', 2), ('Walker', 2), ('Ryan', 2);\n\"\"\"\n"
  },
  {
    "path": "tests/functional/schema/test_custom_schema.py",
    "content": "import pytest\n\nfrom dbt.tests.util import check_relations_equal, run_dbt\nfrom tests.functional.schema.fixtures.macros import (\n    _CUSTOM_MACRO,\n    _CUSTOM_MACRO_MULTI_SCHEMA,\n    _CUSTOM_MACRO_W_CONFIG,\n)\nfrom tests.functional.schema.fixtures.sql import (\n    _SEED_CSV,\n    _TABLE_ONE,\n    _TABLE_ONE_DOT_MODEL_NAME,\n    _TABLE_ONE_DOT_MODEL_SCHEMA,\n    _TABLE_THREE,\n    _TABLE_THREE_DOT_MODEL,\n    _TABLE_THREE_SCHEMA,\n    _TABLE_TWO,\n    _TABLE_TWO_DOT_MODEL,\n    _TABLE_TWO_DOT_MODEL_NAME,\n    _TABLE_TWO_DOT_MODEL_SCHEMA,\n    _TABLE_TWO_SCHEMA,\n    _VALIDATION_SQL,\n)\n\n_CUSTOM_SCHEMA = \"dbt_test\"\n\n\nclass BaseTestCustomSchema:\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\"seed.csv\": _SEED_CSV}\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"view_1.sql\": _TABLE_ONE,\n            \"view_2.sql\": _TABLE_TWO,\n            \"table_3.sql\": _TABLE_THREE,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\"models\": {\"schema\": _CUSTOM_SCHEMA}}\n\n\nclass TestCustomSchema(BaseTestCustomSchema):\n    def test__postgres_handles__custom_schema_with_no_prefix(self, project, macros):\n        project.run_sql(_VALIDATION_SQL)\n        run_dbt([\"seed\"])\n        results = run_dbt([\"run\"])\n        assert len(results) == 3\n        table_results = {r.node.name: r.node.schema for r in results.results}\n        assert table_results[\"view_1\"] == f\"{project.test_schema}_{_CUSTOM_SCHEMA}\"\n        assert table_results[\"view_2\"] == f\"{project.test_schema}_{_TABLE_TWO_SCHEMA}\"\n        assert table_results[\"table_3\"] == f\"{project.test_schema}_{_TABLE_THREE_SCHEMA}\"\n        check_relations_equal(\n            adapter=project.adapter,\n            relation_names=(\"seed\", f\"{project.test_schema}_{_CUSTOM_SCHEMA}.view_1\"),\n        )\n        check_relations_equal(\n            adapter=project.adapter,\n            relation_names=(\"seed\", f\"{project.test_schema}_{_TABLE_TWO_SCHEMA}.view_2\"),\n        )\n        check_relations_equal(\n            adapter=project.adapter,\n            relation_names=(\"agg\", f\"{project.test_schema}_{_TABLE_THREE_SCHEMA}.table_3\"),\n        )\n\n\nclass TestCustomSchemaWithCustomMacro(BaseTestCustomSchema):\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\n            \"custom_macro.sql\": _CUSTOM_MACRO,\n        }\n\n    def test__postgres_handles__custom_schema_with_custom_macro(self, project, macros):\n        project.run_sql(_VALIDATION_SQL)\n        run_dbt([\"seed\"])\n        results = run_dbt([\"run\"])\n        assert len(results) == 3\n        table_results = {r.node.name: r.node.schema for r in results.results}\n        assert table_results[\"view_1\"] == f\"{_CUSTOM_SCHEMA}_{project.test_schema}_macro\"\n        assert table_results[\"view_2\"] == f\"{_TABLE_TWO_SCHEMA}_{project.test_schema}_macro\"\n        assert table_results[\"table_3\"] == f\"{_TABLE_THREE_SCHEMA}_{project.test_schema}_macro\"\n        check_relations_equal(\n            adapter=project.adapter,\n            relation_names=(\"seed\", f\"{_CUSTOM_SCHEMA}_{project.test_schema}_macro.view_1\"),\n        )\n        check_relations_equal(\n            adapter=project.adapter,\n            relation_names=(\"seed\", f\"{_TABLE_TWO_SCHEMA}_{project.test_schema}_macro.view_2\"),\n        )\n        check_relations_equal(\n            adapter=project.adapter,\n            relation_names=(\"agg\", f\"{_TABLE_THREE_SCHEMA}_{project.test_schema}_macro.table_3\"),\n        )\n\n\nclass TestCustomSchemaWithPrefix(BaseTestCustomSchema):\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\n            \"custom_macro.sql\": _CUSTOM_MACRO_W_CONFIG,\n        }\n\n    def test__postgres__custom_schema_with_prefix(self, project, macros):\n        project.run_sql(_VALIDATION_SQL)\n        run_dbt([\"seed\"])\n        results = run_dbt([\"run\"])\n        assert len(results) == 3\n        table_results = {r.node.name: r.node.schema for r in results.results}\n        assert table_results[\"view_1\"] == f\"{_CUSTOM_SCHEMA}_{project.test_schema}_macro\"\n        assert table_results[\"view_2\"] == f\"{_TABLE_TWO_SCHEMA}_{project.test_schema}_macro\"\n        assert table_results[\"table_3\"] == f\"{_TABLE_THREE_SCHEMA}_{project.test_schema}_macro\"\n        check_relations_equal(\n            adapter=project.adapter,\n            relation_names=(\"seed\", f\"{_CUSTOM_SCHEMA}_{project.test_schema}_macro.view_1\"),\n        )\n        check_relations_equal(\n            adapter=project.adapter,\n            relation_names=(\"seed\", f\"{_TABLE_TWO_SCHEMA}_{project.test_schema}_macro.view_2\"),\n        )\n        check_relations_equal(\n            adapter=project.adapter,\n            relation_names=(\"agg\", f\"{_TABLE_THREE_SCHEMA}_{project.test_schema}_macro.table_3\"),\n        )\n\n\nclass TestCustomSchemaWithPrefixAndDispatch(BaseTestCustomSchema):\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\n            \"custom_macro.sql\": _CUSTOM_MACRO_W_CONFIG,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"models\": {\"schema\": _CUSTOM_SCHEMA},\n            \"dispatch\": [\n                {\n                    \"macro_namespace\": \"dbt\",\n                    \"search_order\": [\"test\", \"package_macro_overrides\", \"dbt\"],\n                }\n            ],\n        }\n\n    def test__postgres__custom_schema_with_prefix_and_dispatch(\n        self, project, macros, project_config_update\n    ):\n        project.run_sql(_VALIDATION_SQL)\n        run_dbt([\"deps\"])\n        run_dbt([\"seed\"])\n        results = run_dbt([\"run\"])\n        assert len(results) == 3\n        table_results = {r.node.name: r.node.schema for r in results.results}\n        assert table_results[\"view_1\"] == f\"{_CUSTOM_SCHEMA}_{project.test_schema}_macro\"\n        assert table_results[\"view_2\"] == f\"{_TABLE_TWO_SCHEMA}_{project.test_schema}_macro\"\n        assert table_results[\"table_3\"] == f\"{_TABLE_THREE_SCHEMA}_{project.test_schema}_macro\"\n        check_relations_equal(\n            adapter=project.adapter,\n            relation_names=(\"seed\", f\"{_CUSTOM_SCHEMA}_{project.test_schema}_macro.view_1\"),\n        )\n        check_relations_equal(\n            adapter=project.adapter,\n            relation_names=(\"seed\", f\"{_TABLE_TWO_SCHEMA}_{project.test_schema}_macro.view_2\"),\n        )\n        check_relations_equal(\n            adapter=project.adapter,\n            relation_names=(\"agg\", f\"{_TABLE_THREE_SCHEMA}_{project.test_schema}_macro.table_3\"),\n        )\n\n\nclass TestCustomSchemaWithCustomMacroFromModelName(BaseTestCustomSchema):\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\n            \"custom_macro.sql\": _CUSTOM_MACRO_MULTI_SCHEMA,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"models\": {\"schema\": _CUSTOM_SCHEMA},\n            \"seeds\": {\n                \"quote_columns\": False,\n            },\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            f\"{_TABLE_ONE_DOT_MODEL_NAME}.sql\": _TABLE_ONE,\n            f\"{_TABLE_TWO_DOT_MODEL_NAME}.sql\": _TABLE_TWO_DOT_MODEL,\n            \"table_3.sql\": _TABLE_THREE_DOT_MODEL,\n        }\n\n    def test__postgres__custom_schema_from_model_name(\n        self, project, macros, project_config_update\n    ):\n        project.run_sql(_VALIDATION_SQL)\n        run_dbt([\"seed\"])\n        results = run_dbt([\"run\"])\n        assert len(results) == 3\n        table_results = {r.node.name: r.node.schema for r in results.results}\n\n        assert table_results[_TABLE_ONE_DOT_MODEL_NAME] == _TABLE_ONE_DOT_MODEL_SCHEMA\n        assert table_results[_TABLE_TWO_DOT_MODEL_NAME] == _TABLE_TWO_DOT_MODEL_SCHEMA\n        assert table_results[\"table_3\"] == f\"{project.test_schema}\"\n        check_relations_equal(\n            adapter=project.adapter, relation_names=(\"seed\", _TABLE_ONE_DOT_MODEL_NAME)\n        )\n        check_relations_equal(\n            adapter=project.adapter, relation_names=(\"seed\", _TABLE_TWO_DOT_MODEL_NAME)\n        )\n        check_relations_equal(\n            adapter=project.adapter, relation_names=(\"agg\", f\"{project.test_schema}.table_3\")\n        )\n"
  },
  {
    "path": "tests/functional/schema_tests/data/seed.sql",
    "content": "create table {schema}.seed (\n    favorite_color VARCHAR(10),\n\tid INTEGER,\n\tfirst_name VARCHAR(11),\n\temail VARCHAR(31),\n\n\tnet_worth NUMERIC(12, 2) DEFAULT '100.00',\n\tfav_number NUMERIC DEFAULT '3.14159265',\n\n\tip_address VARCHAR(15),\n\tupdated_at TIMESTAMP WITHOUT TIME ZONE\n);\n\n\nINSERT INTO {schema}.seed\n    (\"favorite_color\", \"id\",\"first_name\",\"email\",\"ip_address\",\"updated_at\")\nVALUES\n    ('blue', 1,'Larry',null,'69.135.206.194','2008-09-12 19:08:31'),\n    ('blue', 2,'Larry',null,'64.210.133.162','1978-05-09 04:15:14'),\n    ('blue', 3,'Anna','amontgomery2@miitbeian.gov.cn','168.104.64.114','2011-10-16 04:07:57'),\n    ('blue', 4,'Sandra','sgeorge3@livejournal.com','229.235.252.98','1973-07-19 10:52:43'),\n    ('blue', 5,'Fred','fwoods4@google.cn','78.229.170.124','2012-09-30 16:38:29'),\n    ('blue', 6,'Stephen','shanson5@livejournal.com','182.227.157.105','1995-11-07 21:40:50'),\n    ('blue', 7,'William','wmartinez6@upenn.edu','135.139.249.50','1982-09-05 03:11:59'),\n    ('blue', 8,'Jessica','jlong7@hao123.com','203.62.178.210','1991-10-16 11:03:15'),\n    ('blue', 9,'Douglas','dwhite8@tamu.edu','178.187.247.1','1979-10-01 09:49:48'),\n    ('blue', 10,'Lisa','lcoleman9@nydailynews.com','168.234.128.249','2011-05-26 07:45:49'),\n    ('blue', 11,'Ralph','rfieldsa@home.pl','55.152.163.149','1972-11-18 19:06:11'),\n    ('blue', 12,'Louise','lnicholsb@samsung.com','141.116.153.154','2014-11-25 20:56:14'),\n    ('blue', 13,'Clarence','cduncanc@sfgate.com','81.171.31.133','2011-11-17 07:02:36'),\n    ('blue', 14,'Daniel','dfranklind@omniture.com','8.204.211.37','1980-09-13 00:09:04'),\n    ('blue', 15,'Katherine','klanee@auda.org.au','176.96.134.59','1997-08-22 19:36:56'),\n    ('blue', 16,'Billy','bwardf@wikia.com','214.108.78.85','2003-10-19 02:14:47'),\n    ('blue', 17,'Annie','agarzag@ocn.ne.jp','190.108.42.70','1988-10-28 15:12:35'),\n    ('blue', 18,'Shirley','scolemanh@fastcompany.com','109.251.164.84','1988-08-24 10:50:57'),\n    ('blue', 19,'Roger','rfrazieri@scribd.com','38.145.218.108','1985-12-31 15:17:15'),\n    ('blue', 20,'Lillian','lstanleyj@goodreads.com','47.57.236.17','1970-06-08 02:09:05'),\n    ('blue', 21,'Aaron','arodriguezk@nps.gov','205.245.118.221','1985-10-11 23:07:49'),\n    ('blue', 22,'Patrick','pparkerl@techcrunch.com','19.8.100.182','2006-03-29 12:53:56'),\n    ('blue', 23,'Phillip','pmorenom@intel.com','41.38.254.103','2011-11-07 15:35:43'),\n    ('blue', 24,'Henry','hgarcian@newsvine.com','1.191.216.252','2008-08-28 08:30:44'),\n    ('blue', 25,'Irene','iturnero@opera.com','50.17.60.190','1994-04-01 07:15:02'),\n    ('blue', 26,'Andrew','adunnp@pen.io','123.52.253.176','2000-11-01 06:03:25'),\n    ('blue', 27,'David','dgutierrezq@wp.com','238.23.203.42','1988-01-25 07:29:18'),\n    ('blue', 28,'Henry','hsanchezr@cyberchimps.com','248.102.2.185','1983-01-01 13:36:37'),\n    ('blue', 29,'Evelyn','epetersons@gizmodo.com','32.80.46.119','1979-07-16 17:24:12'),\n    ('blue', 30,'Tammy','tmitchellt@purevolume.com','249.246.167.88','2001-04-03 10:00:23'),\n    ('blue', 31,'Jacqueline','jlittleu@domainmarket.com','127.181.97.47','1986-02-11 21:35:50'),\n    ('blue', 32,'Earl','eortizv@opera.com','166.47.248.240','1996-07-06 08:16:27'),\n    ('blue', 33,'Juan','jgordonw@sciencedirect.com','71.77.2.200','1987-01-31 03:46:44'),\n    ('blue', 34,'Diane','dhowellx@nyu.edu','140.94.133.12','1994-06-11 02:30:05'),\n    ('blue', 35,'Randy','rkennedyy@microsoft.com','73.255.34.196','2005-05-26 20:28:39'),\n    ('blue', 36,'Janice','jriveraz@time.com','22.214.227.32','1990-02-09 04:16:52'),\n    ('blue', 37,'Laura','lperry10@diigo.com','159.148.145.73','2015-03-17 05:59:25'),\n    ('blue', 38,'Gary','gray11@statcounter.com','40.193.124.56','1970-01-27 10:04:51'),\n    ('blue', 39,'Jesse','jmcdonald12@typepad.com','31.7.86.103','2009-03-14 08:14:29'),\n    ('blue', 40,'Sandra','sgonzalez13@goodreads.com','223.80.168.239','1993-05-21 14:08:54'),\n    ('blue', 41,'Scott','smoore14@archive.org','38.238.46.83','1980-08-30 11:16:56'),\n    ('blue', 42,'Phillip','pevans15@cisco.com','158.234.59.34','2011-12-15 23:26:31'),\n    ('blue', 43,'Steven','sriley16@google.ca','90.247.57.68','2011-10-29 19:03:28'),\n    ('blue', 44,'Deborah','dbrown17@hexun.com','179.125.143.240','1995-04-10 14:36:07'),\n    ('blue', 45,'Lori','lross18@ow.ly','64.80.162.180','1980-12-27 16:49:15'),\n    ('blue', 46,'Sean','sjackson19@tumblr.com','240.116.183.69','1988-06-12 21:24:45'),\n    ('blue', 47,'Terry','tbarnes1a@163.com','118.38.213.137','1997-09-22 16:43:19'),\n    ('blue', 48,'Dorothy','dross1b@ebay.com','116.81.76.49','2005-02-28 13:33:24'),\n    ('blue', 49,'Samuel','swashington1c@house.gov','38.191.253.40','1989-01-19 21:15:48'),\n    ('blue', 50,'Ralph','rcarter1d@tinyurl.com','104.84.60.174','2007-08-11 10:21:49'),\n    ('green', 51,'Wayne','whudson1e@princeton.edu','90.61.24.102','1983-07-03 16:58:12'),\n    ('green', 52,'Rose','rjames1f@plala.or.jp','240.83.81.10','1995-06-08 11:46:23'),\n    ('green', 53,'Louise','lcox1g@theglobeandmail.com','105.11.82.145','2016-09-19 14:45:51'),\n    ('green', 54,'Kenneth','kjohnson1h@independent.co.uk','139.5.45.94','1976-08-17 11:26:19'),\n    ('green', 55,'Donna','dbrown1i@amazon.co.uk','19.45.169.45','2006-05-27 16:51:40'),\n    ('green', 56,'Johnny','jvasquez1j@trellian.com','118.202.238.23','1975-11-17 08:42:32'),\n    ('green', 57,'Patrick','pramirez1k@tamu.edu','231.25.153.198','1997-08-06 11:51:09'),\n    ('green', 58,'Helen','hlarson1l@prweb.com','8.40.21.39','1993-08-04 19:53:40'),\n    ('green', 59,'Patricia','pspencer1m@gmpg.org','212.198.40.15','1977-08-03 16:37:27'),\n    ('green', 60,'Joseph','jspencer1n@marriott.com','13.15.63.238','2005-07-23 20:22:06'),\n    ('green', 61,'Phillip','pschmidt1o@blogtalkradio.com','177.98.201.190','1976-05-19 21:47:44'),\n    ('green', 62,'Joan','jwebb1p@google.ru','105.229.170.71','1972-09-07 17:53:47'),\n    ('green', 63,'Phyllis','pkennedy1q@imgur.com','35.145.8.244','2000-01-01 22:33:37'),\n    ('green', 64,'Katherine','khunter1r@smh.com.au','248.168.205.32','1991-01-09 06:40:24'),\n    ('green', 65,'Laura','lvasquez1s@wiley.com','128.129.115.152','1997-10-23 12:04:56'),\n    ('green', 66,'Juan','jdunn1t@state.gov','44.228.124.51','2004-11-10 05:07:35'),\n    ('green', 67,'Judith','jholmes1u@wiley.com','40.227.179.115','1977-08-02 17:01:45'),\n    ('green', 68,'Beverly','bbaker1v@wufoo.com','208.34.84.59','2016-03-06 20:07:23'),\n    ('green', 69,'Lawrence','lcarr1w@flickr.com','59.158.212.223','1988-09-13 06:07:21'),\n    ('green', 70,'Gloria','gwilliams1x@mtv.com','245.231.88.33','1995-03-18 22:32:46'),\n    ('green', 71,'Steven','ssims1y@cbslocal.com','104.50.58.255','2001-08-05 21:26:20'),\n    ('green', 72,'Betty','bmills1z@arstechnica.com','103.177.214.220','1981-12-14 21:26:54'),\n    ('green', 73,'Mildred','mfuller20@prnewswire.com','151.158.8.130','2000-04-19 10:13:55'),\n    ('green', 74,'Donald','dday21@icq.com','9.178.102.255','1972-12-03 00:58:24'),\n    ('green', 75,'Eric','ethomas22@addtoany.com','85.2.241.227','1992-11-01 05:59:30'),\n    ('green', 76,'Joyce','jarmstrong23@sitemeter.com','169.224.20.36','1985-10-24 06:50:01'),\n    ('green', 77,'Maria','mmartinez24@amazonaws.com','143.189.167.135','2005-10-05 05:17:42'),\n    ('green', 78,'Harry','hburton25@youtube.com','156.47.176.237','1978-03-26 05:53:33'),\n    ('green', 79,'Kevin','klawrence26@hao123.com','79.136.183.83','1994-10-12 04:38:52'),\n    ('green', 80,'David','dhall27@prweb.com','133.149.172.153','1976-12-15 16:24:24'),\n    ('green', 81,'Kathy','kperry28@twitter.com','229.242.72.228','1979-03-04 02:58:56'),\n    ('green', 82,'Adam','aprice29@elegantthemes.com','13.145.21.10','1982-11-07 11:46:59'),\n    ('green', 83,'Brandon','bgriffin2a@va.gov','73.249.128.212','2013-10-30 05:30:36'),\n    ('green', 84,'Henry','hnguyen2b@discovery.com','211.36.214.242','1985-01-09 06:37:27'),\n    ('green', 85,'Eric','esanchez2c@edublogs.org','191.166.188.251','2004-05-01 23:21:42'),\n    ('green', 86,'Jason','jlee2d@jimdo.com','193.92.16.182','1973-01-08 09:05:39'),\n    ('green', 87,'Diana','drichards2e@istockphoto.com','19.130.175.245','1994-10-05 22:50:49'),\n    ('green', 88,'Andrea','awelch2f@abc.net.au','94.155.233.96','2002-04-26 08:41:44'),\n    ('green', 89,'Louis','lwagner2g@miitbeian.gov.cn','26.217.34.111','2003-08-25 07:56:39'),\n    ('green', 90,'Jane','jsims2h@seesaa.net','43.4.220.135','1987-03-20 20:39:04'),\n    ('green', 91,'Larry','lgrant2i@si.edu','97.126.79.34','2000-09-07 20:26:19'),\n    ('green', 92,'Louis','ldean2j@prnewswire.com','37.148.40.127','2011-09-16 20:12:14'),\n    ('green', 93,'Jennifer','jcampbell2k@xing.com','38.106.254.142','1988-07-15 05:06:49'),\n    ('green', 94,'Wayne','wcunningham2l@google.com.hk','223.28.26.187','2009-12-15 06:16:54'),\n    ('green', 95,'Lori','lstevens2m@icq.com','181.250.181.58','1984-10-28 03:29:19'),\n    ('green', 96,'Judy','jsimpson2n@marriott.com','180.121.239.219','1986-02-07 15:18:10'),\n    ('green', 97,'Phillip','phoward2o@usa.gov','255.247.0.175','2002-12-26 08:44:45'),\n    ('green', 98,'Gloria','gwalker2p@usa.gov','156.140.7.128','1997-10-04 07:58:58'),\n    ('green', 99,'Paul','pjohnson2q@umn.edu','183.59.198.197','1991-11-14 12:33:55'),\n    ('green', 100,'Frank','fgreene2r@blogspot.com','150.143.68.121','2010-06-12 23:55:39');\n"
  },
  {
    "path": "tests/functional/schema_tests/data/seed_failure.sql",
    "content": "create table {schema}.seed_failure (\n    favorite_color VARCHAR(10),\n\tid INTEGER,\n\tfirst_name VARCHAR(11),\n\temail VARCHAR(31),\n\tip_address VARCHAR(15),\n\tupdated_at TIMESTAMP WITHOUT TIME ZONE\n);\n\n\nINSERT INTO {schema}.seed_failure\n    (\"favorite_color\", \"id\",\"first_name\",\"email\",\"ip_address\",\"updated_at\")\nVALUES\n    -- unaccepted 'red' favorite_color\n    ('red', 1,'Larry','lking0@miitbeian.gov.cn','69.135.206.194','2008-09-12 19:08:31'),\n    -- dupicate unique field (id=1)\n    ('blue', 1,'Larry','lperkins1@toplist.cz','64.210.133.162','1978-05-09 04:15:14'),\n    -- null not_null field (id)\n    ('blue', null,'Anna','amontgomery2@miitbeian.gov.cn','168.104.64.114','2011-10-16 04:07:57'),\n    ('blue', 4,'Sandra','sgeorge3@livejournal.com','229.235.252.98','1973-07-19 10:52:43'),\n    ('blue', 5,'Fred','fwoods4@google.cn','78.229.170.124','2012-09-30 16:38:29'),\n    ('blue', 6,'Stephen','shanson5@livejournal.com','182.227.157.105','1995-11-07 21:40:50'),\n    ('blue', 7,'William','wmartinez6@upenn.edu','135.139.249.50','1982-09-05 03:11:59'),\n    ('blue', 8,'Jessica','jlong7@hao123.com','203.62.178.210','1991-10-16 11:03:15'),\n    ('blue', 9,'Douglas','dwhite8@tamu.edu','178.187.247.1','1979-10-01 09:49:48'),\n    ('blue', 10,'Lisa','lcoleman9@nydailynews.com','168.234.128.249','2011-05-26 07:45:49'),\n    ('blue', 11,'Ralph','rfieldsa@home.pl','55.152.163.149','1972-11-18 19:06:11'),\n    ('blue', 12,'Louise','lnicholsb@samsung.com','141.116.153.154','2014-11-25 20:56:14'),\n    ('blue', 13,'Clarence','cduncanc@sfgate.com','81.171.31.133','2011-11-17 07:02:36'),\n    ('blue', 14,'Daniel','dfranklind@omniture.com','8.204.211.37','1980-09-13 00:09:04'),\n    ('blue', 15,'Katherine','klanee@auda.org.au','176.96.134.59','1997-08-22 19:36:56'),\n    ('blue', 16,'Billy','bwardf@wikia.com','214.108.78.85','2003-10-19 02:14:47'),\n    ('blue', 17,'Annie','agarzag@ocn.ne.jp','190.108.42.70','1988-10-28 15:12:35'),\n    ('blue', 18,'Shirley','scolemanh@fastcompany.com','109.251.164.84','1988-08-24 10:50:57'),\n    ('blue', 19,'Roger','rfrazieri@scribd.com','38.145.218.108','1985-12-31 15:17:15'),\n    ('blue', 20,'Lillian','lstanleyj@goodreads.com','47.57.236.17','1970-06-08 02:09:05'),\n    ('blue', 21,'Aaron','arodriguezk@nps.gov','205.245.118.221','1985-10-11 23:07:49'),\n    ('blue', 22,'Patrick','pparkerl@techcrunch.com','19.8.100.182','2006-03-29 12:53:56'),\n    ('blue', 23,'Phillip','pmorenom@intel.com','41.38.254.103','2011-11-07 15:35:43'),\n    ('blue', 24,'Henry','hgarcian@newsvine.com','1.191.216.252','2008-08-28 08:30:44'),\n    ('blue', 25,'Irene','iturnero@opera.com','50.17.60.190','1994-04-01 07:15:02'),\n    ('blue', 26,'Andrew','adunnp@pen.io','123.52.253.176','2000-11-01 06:03:25'),\n    ('blue', 27,'David','dgutierrezq@wp.com','238.23.203.42','1988-01-25 07:29:18'),\n    ('blue', 28,'Henry','hsanchezr@cyberchimps.com','248.102.2.185','1983-01-01 13:36:37'),\n    ('blue', 29,'Evelyn','epetersons@gizmodo.com','32.80.46.119','1979-07-16 17:24:12'),\n    ('blue', 30,'Tammy','tmitchellt@purevolume.com','249.246.167.88','2001-04-03 10:00:23'),\n    ('blue', 31,'Jacqueline','jlittleu@domainmarket.com','127.181.97.47','1986-02-11 21:35:50'),\n    ('blue', 32,'Earl','eortizv@opera.com','166.47.248.240','1996-07-06 08:16:27'),\n    ('blue', 33,'Juan','jgordonw@sciencedirect.com','71.77.2.200','1987-01-31 03:46:44'),\n    ('blue', 34,'Diane','dhowellx@nyu.edu','140.94.133.12','1994-06-11 02:30:05'),\n    ('blue', 35,'Randy','rkennedyy@microsoft.com','73.255.34.196','2005-05-26 20:28:39'),\n    ('blue', 36,'Janice','jriveraz@time.com','22.214.227.32','1990-02-09 04:16:52'),\n    ('blue', 37,'Laura','lperry10@diigo.com','159.148.145.73','2015-03-17 05:59:25'),\n    ('blue', 38,'Gary','gray11@statcounter.com','40.193.124.56','1970-01-27 10:04:51'),\n    ('blue', 39,'Jesse','jmcdonald12@typepad.com','31.7.86.103','2009-03-14 08:14:29'),\n    ('blue', 40,'Sandra','sgonzalez13@goodreads.com','223.80.168.239','1993-05-21 14:08:54'),\n    ('blue', 41,'Scott','smoore14@archive.org','38.238.46.83','1980-08-30 11:16:56'),\n    ('blue', 42,'Phillip','pevans15@cisco.com','158.234.59.34','2011-12-15 23:26:31'),\n    ('blue', 43,'Steven','sriley16@google.ca','90.247.57.68','2011-10-29 19:03:28'),\n    ('blue', 44,'Deborah','dbrown17@hexun.com','179.125.143.240','1995-04-10 14:36:07'),\n    ('blue', 45,'Lori','lross18@ow.ly','64.80.162.180','1980-12-27 16:49:15'),\n    ('blue', 46,'Sean','sjackson19@tumblr.com','240.116.183.69','1988-06-12 21:24:45'),\n    ('blue', 47,'Terry','tbarnes1a@163.com','118.38.213.137','1997-09-22 16:43:19'),\n    ('blue', 48,'Dorothy','dross1b@ebay.com','116.81.76.49','2005-02-28 13:33:24'),\n    ('blue', 49,'Samuel','swashington1c@house.gov','38.191.253.40','1989-01-19 21:15:48'),\n    ('blue', 50,'Ralph','rcarter1d@tinyurl.com','104.84.60.174','2007-08-11 10:21:49'),\n    ('green', 51,'Wayne','whudson1e@princeton.edu','90.61.24.102','1983-07-03 16:58:12'),\n    ('green', 52,'Rose','rjames1f@plala.or.jp','240.83.81.10','1995-06-08 11:46:23'),\n    ('green', 53,'Louise','lcox1g@theglobeandmail.com','105.11.82.145','2016-09-19 14:45:51'),\n    ('green', 54,'Kenneth','kjohnson1h@independent.co.uk','139.5.45.94','1976-08-17 11:26:19'),\n    ('green', 55,'Donna','dbrown1i@amazon.co.uk','19.45.169.45','2006-05-27 16:51:40'),\n    ('green', 56,'Johnny','jvasquez1j@trellian.com','118.202.238.23','1975-11-17 08:42:32'),\n    ('green', 57,'Patrick','pramirez1k@tamu.edu','231.25.153.198','1997-08-06 11:51:09'),\n    ('green', 58,'Helen','hlarson1l@prweb.com','8.40.21.39','1993-08-04 19:53:40'),\n    ('green', 59,'Patricia','pspencer1m@gmpg.org','212.198.40.15','1977-08-03 16:37:27'),\n    ('green', 60,'Joseph','jspencer1n@marriott.com','13.15.63.238','2005-07-23 20:22:06'),\n    ('green', 61,'Phillip','pschmidt1o@blogtalkradio.com','177.98.201.190','1976-05-19 21:47:44'),\n    ('green', 62,'Joan','jwebb1p@google.ru','105.229.170.71','1972-09-07 17:53:47'),\n    ('green', 63,'Phyllis','pkennedy1q@imgur.com','35.145.8.244','2000-01-01 22:33:37'),\n    ('green', 64,'Katherine','khunter1r@smh.com.au','248.168.205.32','1991-01-09 06:40:24'),\n    ('green', 65,'Laura','lvasquez1s@wiley.com','128.129.115.152','1997-10-23 12:04:56'),\n    ('green', 66,'Juan','jdunn1t@state.gov','44.228.124.51','2004-11-10 05:07:35'),\n    ('green', 67,'Judith','jholmes1u@wiley.com','40.227.179.115','1977-08-02 17:01:45'),\n    ('green', 68,'Beverly','bbaker1v@wufoo.com','208.34.84.59','2016-03-06 20:07:23'),\n    ('green', 69,'Lawrence','lcarr1w@flickr.com','59.158.212.223','1988-09-13 06:07:21'),\n    ('green', 70,'Gloria','gwilliams1x@mtv.com','245.231.88.33','1995-03-18 22:32:46'),\n    ('green', 71,'Steven','ssims1y@cbslocal.com','104.50.58.255','2001-08-05 21:26:20'),\n    ('green', 72,'Betty','bmills1z@arstechnica.com','103.177.214.220','1981-12-14 21:26:54'),\n    ('green', 73,'Mildred','mfuller20@prnewswire.com','151.158.8.130','2000-04-19 10:13:55'),\n    ('green', 74,'Donald','dday21@icq.com','9.178.102.255','1972-12-03 00:58:24'),\n    ('green', 75,'Eric','ethomas22@addtoany.com','85.2.241.227','1992-11-01 05:59:30'),\n    ('green', 76,'Joyce','jarmstrong23@sitemeter.com','169.224.20.36','1985-10-24 06:50:01'),\n    ('green', 77,'Maria','mmartinez24@amazonaws.com','143.189.167.135','2005-10-05 05:17:42'),\n    ('green', 78,'Harry','hburton25@youtube.com','156.47.176.237','1978-03-26 05:53:33'),\n    ('green', 79,'Kevin','klawrence26@hao123.com','79.136.183.83','1994-10-12 04:38:52'),\n    ('green', 80,'David','dhall27@prweb.com','133.149.172.153','1976-12-15 16:24:24'),\n    ('green', 81,'Kathy','kperry28@twitter.com','229.242.72.228','1979-03-04 02:58:56'),\n    ('green', 82,'Adam','aprice29@elegantthemes.com','13.145.21.10','1982-11-07 11:46:59'),\n    ('green', 83,'Brandon','bgriffin2a@va.gov','73.249.128.212','2013-10-30 05:30:36'),\n    ('green', 84,'Henry','hnguyen2b@discovery.com','211.36.214.242','1985-01-09 06:37:27'),\n    ('green', 85,'Eric','esanchez2c@edublogs.org','191.166.188.251','2004-05-01 23:21:42'),\n    ('green', 86,'Jason','jlee2d@jimdo.com','193.92.16.182','1973-01-08 09:05:39'),\n    ('green', 87,'Diana','drichards2e@istockphoto.com','19.130.175.245','1994-10-05 22:50:49'),\n    ('green', 88,'Andrea','awelch2f@abc.net.au','94.155.233.96','2002-04-26 08:41:44'),\n    ('green', 89,'Louis','lwagner2g@miitbeian.gov.cn','26.217.34.111','2003-08-25 07:56:39'),\n    ('green', 90,'Jane','jsims2h@seesaa.net','43.4.220.135','1987-03-20 20:39:04'),\n    ('green', 91,'Larry','lgrant2i@si.edu','97.126.79.34','2000-09-07 20:26:19'),\n    ('green', 92,'Louis','ldean2j@prnewswire.com','37.148.40.127','2011-09-16 20:12:14'),\n    ('green', 93,'Jennifer','jcampbell2k@xing.com','38.106.254.142','1988-07-15 05:06:49'),\n    ('green', 94,'Wayne','wcunningham2l@google.com.hk','223.28.26.187','2009-12-15 06:16:54'),\n    ('green', 95,'Lori','lstevens2m@icq.com','181.250.181.58','1984-10-28 03:29:19'),\n    ('green', 96,'Judy','jsimpson2n@marriott.com','180.121.239.219','1986-02-07 15:18:10'),\n    ('green', 97,'Phillip','phoward2o@usa.gov','255.247.0.175','2002-12-26 08:44:45'),\n    ('green', 98,'Gloria','gwalker2p@usa.gov','156.140.7.128','1997-10-04 07:58:58'),\n    ('green', 99,'Paul','pjohnson2q@umn.edu','183.59.198.197','1991-11-14 12:33:55'),\n    ('green', 100,'Frank','fgreene2r@blogspot.com','150.143.68.121','2010-06-12 23:55:39');\n"
  },
  {
    "path": "tests/functional/schema_tests/fixtures.py",
    "content": "wrong_specification_block__schema_yml = \"\"\"\nversion: 2\nmodels:\n  - name: some_seed\n    description: \"This is my seed under a model\"\n\"\"\"\n\ntest_context_where_subq_models__schema_yml = \"\"\"\nversion: 2\n\nmodels:\n  - name: model_a\n    data_tests:\n      - self_referential\n\n\"\"\"\n\ntest_context_where_subq_models__model_a_sql = \"\"\"\nselect 1 as fun\n\n\"\"\"\n\ntest_utils__dbt_project_yml = \"\"\"\nname: 'test_utils'\nversion: '1.0'\nconfig-version: 2\n\nprofile: 'default'\n\nmacro-paths: [\"macros\"]\n\n\n\"\"\"\n\ntest_utils__macros__current_timestamp_sql = \"\"\"\n{% macro current_timestamp() -%}\n  {{ return(adapter.dispatch('current_timestamp', 'test_utils')()) }}\n{%- endmacro %}\n\n{% macro default__current_timestamp() -%}\n  now()\n{%- endmacro %}\n\n\"\"\"\n\ntest_utils__macros__custom_test_sql = \"\"\"\n{% macro test_dispatch(model) -%}\n  {{ return(adapter.dispatch('test_dispatch', macro_namespace = 'test_utils')()) }}\n{%- endmacro %}\n\n{% macro default__test_dispatch(model) %}\n    select {{ adapter.dispatch('current_timestamp', macro_namespace = 'test_utils')() }}\n{% endmacro %}\n\n\"\"\"\n\nlocal_dependency__dbt_project_yml = \"\"\"\nname: 'local_dep'\nversion: '1.0'\nconfig-version: 2\n\nprofile: 'default'\n\nmacro-paths: [\"macros\"]\n\n\"\"\"\n\nlocal_dependency__macros__equality_sql = \"\"\"\n{#-- taken from dbt-utils --#}\n{% test equality(model, compare_model, compare_columns=None) %}\n  {{ return(adapter.dispatch('test_equality')(model, compare_model, compare_columns)) }}\n{% endtest %}\n\n{% macro default__test_equality(model, compare_model, compare_columns=None) %}\n\n{% set set_diff %}\n    count(*) + abs(\n        sum(case when which_diff = 'a_minus_b' then 1 else 0 end) -\n        sum(case when which_diff = 'b_minus_a' then 1 else 0 end)\n    )\n{% endset %}\n\n{#-- Needs to be set at parse time, before we return '' below --#}\n{{ config(fail_calc = set_diff) }}\n\n{#-- Prevent querying of db in parsing mode. This works because this macro does not create any new refs. #}\n{%- if not execute -%}\n    {{ return('') }}\n{% endif %}\n-- setup\n{%- do dbt_utils._is_relation(model, 'test_equality') -%}\n{#-\nIf the compare_cols arg is provided, we can run this test without querying the\ninformation schema — this allows the model to be an ephemeral model\n-#}\n\n{%- if not compare_columns -%}\n    {%- do dbt_utils._is_ephemeral(model, 'test_equality') -%}\n    {%- set compare_columns = adapter.get_columns_in_relation(model) | map(attribute='quoted') -%}\n{%- endif -%}\n\n{% set compare_cols_csv = compare_columns | join(', ') %}\n\nwith a as (\n    select * from {{ model }}\n),\nb as (\n    select * from {{ compare_model }}\n),\na_minus_b as (\n    select {{compare_cols_csv}} from a\n    {{ dbt_utils.except() }}\n    select {{compare_cols_csv}} from b\n),\nb_minus_a as (\n    select {{compare_cols_csv}} from b\n    {{ dbt_utils.except() }}\n    select {{compare_cols_csv}} from a\n),\n\nunioned as (\n\n    select 'a_minus_b' as which_diff, * from a_minus_b\n    union all\n    select 'b_minus_a' as which_diff, * from b_minus_a\n\n)\n\nselect * from unioned\n\n{% endmacro %}\n\n\"\"\"\n\ncase_sensitive_models__schema_yml = \"\"\"\nversion: 2\n\nmodels:\n  - name: lowercase\n    columns:\n      - name: id\n        quote: true\n        data_tests:\n          - unique\n  - name: uppercase\n    columns:\n      - name: id\n        quote: true\n        data_tests:\n          - unique\n\n\"\"\"\n\ncase_sensitive_models__uppercase_SQL = \"\"\"\nselect 1 as id\n\n\"\"\"\n\ncase_sensitive_models__lowercase_sql = \"\"\"\nselect 1 as id\n\n\"\"\"\n\ntest_context_macros__my_test_sql = \"\"\"\n{% macro test_call_pkg_macro(model) %}\n    select {{ adapter.dispatch('current_timestamp', macro_namespace = 'local_utils')() }}\n{% endmacro %}\n\n\"\"\"\n\ntest_context_macros__test_my_datediff_sql = \"\"\"\n{% macro test_my_datediff(model) %}\n    select {{ local_utils.datediff() }}\n{% endmacro %}\n\n\"\"\"\n\ntest_context_macros__custom_schema_tests_sql = \"\"\"\n{% test type_one(model) %}\n\n    select * from (\n\n        select * from {{ model }}\n        union all\n        select * from {{ ref('model_b') }}\n\n    ) as Foo\n\n{% endtest %}\n\n{% test type_two(model) %}\n\n    {{ config(severity = \"WARN\") }}\n\n    select * from {{ model }}\n\n{% endtest %}\n\n\"\"\"\n\ntest_context_models_namespaced__schema_yml = \"\"\"\n\nversion: 2\n\nmodels:\n    - name: model_a\n      data_tests:\n        - type_one\n        - type_two\n    - name: model_c\n      data_tests:\n        - call_pkg_macro\n        - test_utils.dispatch\n\n\"\"\"\n\ntest_context_models_namespaced__model_c_sql = \"\"\"\nselect 1 as fun\n\n\"\"\"\n\ntest_context_models_namespaced__model_b_sql = \"\"\"\nselect 1 as notfun\n\n\"\"\"\n\ntest_context_models_namespaced__model_a_sql = \"\"\"\nselect 1 as fun\n\n\"\"\"\n\nmacros_v2__override_get_test_macros_fail__get_test_sql_sql = \"\"\"\n{% macro get_test_sql(main_sql, fail_calc, warn_if, error_if, limit) -%}\n    select\n      {{ fail_calc }} as failures,\n      case when {{ fail_calc }} {{ warn_if }} then 'x' else 'y' end as should_warn,\n      case when {{ fail_calc }} {{ error_if }} then 'x' else 'y' end as should_error\n    from (\n      {{ main_sql }}\n      {{ \"limit \" ~ limit if limit != none }}\n    ) dbt_internal_test\n{% endmacro %}\n\"\"\"\n\nmacros_v2__macros__tests_sql = \"\"\"\n{% test every_value_is_blue(model, column_name) %}\n\n    select *\n    from {{ model }}\n    where {{ column_name }} != 'blue'\n\n{% endtest %}\n\n\n{% test rejected_values(model, column_name, values) %}\n\n    select *\n    from {{ model }}\n    where {{ column_name }} in (\n        {% for value in values %}\n            '{{ value }}' {% if not loop.last %} , {% endif %}\n        {% endfor %}\n    )\n\n{% endtest %}\n\n\n{% test equivalent(model, value) %}\n    {% set expected = 'foo-bar' %}\n    {% set eq = 1 if value == expected else 0 %}\n    {% set validation_message -%}\n      'got \"{{ value }}\", expected \"{{ expected }}\"'\n    {%- endset %}\n    {% if eq == 0 and execute %}\n        {{ log(validation_message, info=True) }}\n    {% endif %}\n\n    select {{ validation_message }} as validation_error\n    where {{ eq }} = 0\n{% endtest %}\n\n\n\"\"\"\n\nmacros_v2__override_get_test_macros__get_test_sql_sql = \"\"\"\n{% macro get_test_sql(main_sql, fail_calc, warn_if, error_if, limit) -%}\n    select\n      {{ fail_calc }} as failures,\n      case when {{ fail_calc }} {{ warn_if }} then 1 else 0 end as should_warn,\n      case when {{ fail_calc }} {{ error_if }} then 1 else 0 end as should_error\n    from (\n      {{ main_sql }}\n      {{ \"limit \" ~ limit if limit != none }}\n    ) dbt_internal_test\n{%- endmacro %}\n\"\"\"\n\nmacros_v2__custom_configs__test_sql = \"\"\"\n{% test where(model, column_name) %}\n  {{ config(where = \"1 = 0\") }}\n  select * from {{ model }}\n{% endtest %}\n\n{% test error_if(model, column_name) %}\n  {{ config(error_if = \"<= 0\", warn_if = \"<= 0\") }}\n  select * from {{ model }}\n{% endtest %}\n\n\n{% test warn_if(model, column_name) %}\n  {{ config(warn_if = \"<= 0\", severity = \"WARN\") }}\n  select * from {{ model }}\n{% endtest %}\n\n{% test limit(model, column_name) %}\n  {{ config(limit = 0) }}\n  select * from {{ model }}\n{% endtest %}\n\n{% test fail_calc(model, column_name) %}\n  {{ config(fail_calc = \"count(*) - count(*)\") }}\n  select * from {{ model }}\n{% endtest %}\n\n\"\"\"\n\ntest_context_macros_namespaced__my_test_sql = \"\"\"\n{% macro test_call_pkg_macro(model) %}\n    select {{ test_utils.current_timestamp() }}\n{% endmacro %}\n\n\"\"\"\n\ntest_context_macros_namespaced__custom_schema_tests_sql = \"\"\"\n{% test type_one(model) %}\n\n    select * from (\n\n        select * from {{ model }}\n        union all\n        select * from {{ ref('model_b') }}\n\n    ) as Foo\n\n{% endtest %}\n\n{% test type_two(model) %}\n\n    {{ config(severity = \"WARN\") }}\n\n    select * from {{ model }}\n\n{% endtest %}\n\n\"\"\"\n\nseeds__some_seed_csv = \"\"\"\ncol_int,col_str\n1,hello\n2,goodbye\n\"\"\"\n\ntest_context_models__schema_yml = \"\"\"\n\nversion: 2\n\nmodels:\n    - name: model_a\n      data_tests:\n        - type_one\n        - type_two\n    - name: model_c\n      data_tests:\n        - call_pkg_macro\n        - local_utils.dispatch\n        - my_datediff\n\n\"\"\"\n\ntest_context_models__model_c_sql = \"\"\"\nselect 1 as fun\n\n\"\"\"\n\ntest_context_models__model_b_sql = \"\"\"\nselect 1 as notfun\n\n\"\"\"\n\ntest_context_models__model_a_sql = \"\"\"\nselect 1 as fun\n\n\"\"\"\n\nname_collision__schema_yml = \"\"\"\nversion: 2\nmodels:\n- name: base\n  columns:\n  - name: extension_id\n    data_tests:\n    - not_null\n- name: base_extension\n  columns:\n  - name: id\n    data_tests:\n    - not_null\n\n\"\"\"\n\nname_collision__base_sql = \"\"\"\nSELECT 'hello_world' AS extension_id\n\"\"\"\n\nname_collision__base_extension_sql = \"\"\"\nSELECT 'NOT_NULL' AS id\n\"\"\"\n\n\ndupe_generic_tests_collide__schema_yml = \"\"\"\nversion: 2\nmodels:\n- name: model_a\n  columns:\n  - name: id\n    data_tests:\n    - not_null:\n        config:\n          where: \"1=1\"\n    - not_null:\n        config:\n          where: \"1=2\"\n\n\"\"\"\n\ndupe_generic_tests_collide__model_a = \"\"\"\nSELECT 'NOT_NULL' AS id\n\"\"\"\n\n\ncustom_generic_test_config_custom_macro__schema_yml = \"\"\"\nversion: 2\nmodels:\n- name: model_a\n  columns:\n  - name: id\n    data_tests:\n    - not_null:\n        config:\n          where: \"id = (select id from {{ ref('model_a') }} limit 1)\"\n\n\"\"\"\n\ncustom_generic_test_config_custom_macro__model_a = \"\"\"\nSELECT 1 AS id\n\"\"\"\n\n\ncustom_generic_test_names__schema_yml = \"\"\"\nversion: 2\nmodels:\n- name: model_a\n  columns:\n  - name: id\n    data_tests:\n    - not_null:\n        name: not_null_where_1_equals_1\n        config:\n          where: \"1=1\"\n    - not_null:\n        name: not_null_where_1_equals_2\n        config:\n          where: \"1=2\"\n\n\"\"\"\n\ncustom_generic_test_names__model_a = \"\"\"\nSELECT 'NOT_NULL' AS id\n\"\"\"\n\ncustom_generic_test_names_alt_format__schema_yml = \"\"\"\nversion: 2\nmodels:\n- name: model_a\n  columns:\n  - name: id\n    data_tests:\n    - name: not_null_where_1_equals_1\n      test_name: not_null\n      config:\n        where: \"1=1\"\n    - name: not_null_where_1_equals_2\n      test_name: not_null\n      config:\n        where: \"1=2\"\n\n\"\"\"\n\ncustom_generic_test_names_alt_format__model_a = \"\"\"\nSELECT 'NOT_NULL' AS id\n\"\"\"\n\n\ntest_context_where_subq_macros__custom_generic_test_sql = \"\"\"\n/*{# This test will fail if get_where_subquery() is missing from TestContext + TestMacroNamespace #}*/\n\n{% test self_referential(model) %}\n\n    {%- set relation = api.Relation.create(schema=model.schema, identifier=model.table) -%}\n    {%- set columns = adapter.get_columns_in_relation(relation) -%}\n    {%- set columns_csv = columns | map(attribute='name') | list | join(', ') -%}\n\n    select {{ columns_csv }} from {{ model }}\n    limit 0\n\n{% endtest %}\n\n\"\"\"\n\ninvalid_schema_models__schema_yml = \"\"\"\nversion: 2\n\nmodels:\n  name: model\n  columns:\n    - name: Id\n      quote: true\n      data_tests:\n        - unique\n        - not_null\n\n\"\"\"\n\ninvalid_schema_models__model_sql = \"\"\"\nselect 1 as \"Id\"\n\n\"\"\"\n\nall_quotes_schema__schema_yml = \"\"\"# models/schema.yml\n# only comments here, which should be okay!\n# https://github.com/dbt-labs/dbt-core/issues/3568\"\"\"\n\nmodels_v2__render_test_cli_arg_models__schema_yml = \"\"\"\nversion: 2\n\nmodels:\n  - name: model\n    data_tests:\n      - equivalent:\n          value: \"{{ var('myvar', 'baz') }}-bar\"\n\n\"\"\"\n\nmodels_v2__render_test_cli_arg_models__model_sql = \"\"\"\nselect 1 as id\n\n\"\"\"\n\nmodels_v2__override_get_test_models__schema_yml = \"\"\"\nversion: 2\n\nmodels:\n    - name: my_model_pass\n      description: \"The table has 1 null values, and we're okay with that, until it's more than 1.\"\n      columns:\n        - name: id\n          description: \"The number of responses for this favorite color - purple will be null\"\n          data_tests:\n            - not_null:\n                error_if: '>1'\n                warn_if: '>1'\n\n    - name: my_model_warning\n      description: \"The table has 1 null values, and we're okay with that, but let us know\"\n      columns:\n        - name: id\n          description: \"The number of responses for this favorite color - purple will be null\"\n          data_tests:\n            - not_null:\n                error_if: '>1'\n\n    - name: my_model_failure\n      description: \"The table has 2 null values, and we're not okay with that\"\n      columns:\n        - name: id\n          description: \"The number of responses for this favorite color - purple will be null\"\n          data_tests:\n            - not_null:\n                error_if: '>1'\n\n\n\"\"\"\n\nmodels_v2__override_get_test_models__my_model_warning_sql = \"\"\"\nselect * from {{ ref('my_model_pass') }}\n\"\"\"\n\nmodels_v2__override_get_test_models__my_model_pass_sql = \"\"\"\nselect 1 as id\nUNION ALL\nselect null as id\n\"\"\"\n\nmodels_v2__override_get_test_models__my_model_failure_sql = \"\"\"\nselect * from {{ ref('my_model_pass') }}\nUNION ALL\nselect null as id\n\"\"\"\n\nmodels_v2__models__schema_yml = \"\"\"\nversion: 2\n\nmodels:\n    - name: table_copy\n      description: \"A copy of the table\"\n      columns:\n        - name: id\n          description: \"The ID\"\n          data_tests:\n            - not_null\n            - unique\n          tags:\n            - table_id\n        - name: first_name\n          description: \"The user's first name\"\n          data_tests:\n            - not_null\n          tags:\n            - table_first_name\n        - name: ip_address\n          description: \"The user's IP address\"\n          data_tests:\n            - not_null\n        - name: updated_at\n          description: \"The update time of the user\"\n          data_tests:\n            - not_null\n        - name: email\n          description: \"The user's email address\"\n          data_tests:\n            - unique\n        - name: favorite_color\n          description: \"The user's favorite color\"\n          data_tests:\n            - accepted_values: {\n                values: ['blue', 'green'],\n                quote: true,\n                tags: table_copy_favorite_color  # tags can be a single string\n            }\n          tags:\n            - table_favorite_color\n        - name: fav_number\n          description: \"The user's favorite number\"\n          data_tests:\n            - accepted_values:\n                values: [3.14159265]\n                quote: false\n                tags:  # tags can be a list of strings\n                  - favorite_number_is_pi\n\n\n    - name: table_summary\n      description: \"The summary table\"\n      columns:\n        - name: favorite_color_copy\n          description: \"The favorite color\"\n          data_tests:\n            - not_null\n            - unique\n            - accepted_values: { values: ['blue', 'green'] }\n            - relationships: { field: favorite_color, to: ref('table_copy') }\n          tags:\n            - table_favorite_color\n        - name: count\n          description: \"The number of responses for this favorite color\"\n          data_tests:\n            - not_null\n\n# all of these constraints will fail\n    - name: table_failure_copy\n      description: \"The table copy that does not comply with the schema\"\n      columns:\n        - name: id\n          description: \"The user ID\"\n          data_tests:\n            - not_null\n            - unique\n          tags:\n            - xfail\n        - name: favorite_color\n          description: \"The user's favorite color\"\n          data_tests:\n            - accepted_values: { values: ['blue', 'green'] }\n          tags:\n            - xfail\n\n# all of these constraints will fail\n    - name: table_failure_summary\n      description: \"The table summary that does not comply with the schema\"\n      columns:\n        - name: favorite_color\n          description: \"The favorite color\"\n          data_tests:\n            - accepted_values: { values: ['red'] }\n            - relationships: { field: favorite_color, to: ref('table_copy') }\n          tags:\n            - xfail\n\n# this table is disabled so these tests should be ignored\n    - name: table_disabled\n      description: \"A disabled table\"\n      columns:\n        - name: favorite_color\n          description: \"The favorite color\"\n          data_tests:\n            - accepted_values: { values: ['red'] }\n            - relationships: { field: favorite_color, to: ref('table_copy') }\n\n# all of these constraints will fail\n    - name: table_failure_null_relation\n      description: \"A table with a null value where it should be a foreign key\"\n      columns:\n        - name: id\n          description: \"The user ID\"\n          data_tests:\n            - relationships: { field: id, to: ref('table_failure_copy') }\n          tags:\n            - xfail\n\n\"\"\"\n\nmodels_v2__models__table_summary_sql = \"\"\"\n{{\n    config(\n        materialized='table'\n    )\n}}\n\nselect favorite_color as favorite_color_copy, count(*) as count\nfrom {{ ref('table_copy') }}\ngroup by 1\n\n\"\"\"\n\nmodels_v2__models__table_failure_summary_sql = \"\"\"\n{{\n    config(\n        materialized='table'\n    )\n}}\n\n-- force a foreign key constraint failure here\nselect 'purple' as favorite_color, count(*) as count\nfrom {{ ref('table_failure_copy') }}\ngroup by 1\n\n\"\"\"\n\nmodels_v2__models__table_disabled_sql = \"\"\"\n{{\n    config(\n        enabled=False\n    )\n}}\n\n-- force a foreign key constraint failure here\nselect 'purple' as favorite_color, count(*) as count\nfrom {{ ref('table_failure_copy') }}\ngroup by 1\n\n\"\"\"\n\nmodels_v2__models__table_failure_null_relation_sql = \"\"\"\n{{\n    config(\n        materialized='table'\n    )\n}}\n\n-- force a foreign key constraint failure here\nselect 105 as id, count(*) as count\nfrom {{ ref('table_failure_copy') }}\ngroup by 1\n\n\"\"\"\n\nmodels_v2__models__table_failure_copy_sql = \"\"\"\n\n{{\n    config(\n        materialized='table'\n    )\n}}\n\nselect * from {{ this.schema }}.seed_failure\n\n\"\"\"\n\nmodels_v2__models__table_copy_sql = \"\"\"\n\n{{\n    config(\n        materialized='table'\n    )\n}}\n\nselect * from {{ this.schema }}.seed\n\n\"\"\"\n\nmodels_v2__malformed__schema_yml = \"\"\"\nversion: 2\n\nmodels:\n  # this whole model should fail and not run\n  - name: table_copy\n    description: \"A copy of the table\"\n    columns:\n      - name: id\n        description: \"The ID\"\n        data_tests:\n          - not_null\n          - unique\n      - name: favorite_color\n        data_tests:\n          # this is missing a \"-\" and is malformed\n          accepted_values: { values: ['blue', 'green'] }\n\n  # this whole model should pass and run\n  - name: table_summary\n    description: \"The summary table\"\n    columns:\n      - name: favorite_color\n        description: \"The favorite color\"\n        data_tests:\n          - not_null\n          - unique\n          - accepted_values: { values: ['blue', 'green'] }\n          - relationships: { field: favorite_color, to: ref('table_copy') }\n      - name: count\n        description: \"The number of responses for this favorite color\"\n        data_tests:\n          - not_null\n\n\"\"\"\n\nmodels_v2__malformed__table_summary_sql = \"\"\"\n{{\n    config(\n        materialized='table'\n    )\n}}\n\nselect favorite_color, count(*) as count\nfrom {{ ref('table_copy') }}\ngroup by 1\n\n\"\"\"\n\nmodels_v2__malformed__table_copy_sql = \"\"\"\n\n{{\n    config(\n        materialized='table'\n    )\n}}\n\nselect * from {{ this.schema }}.seed\n\n\"\"\"\n\nmodels_v2__override_get_test_models_fail__schema_yml = \"\"\"\nversion: 2\n\nmodels:\n    - name: my_model\n      description: \"The table has 1 null values, and we're not okay with that.\"\n      columns:\n        - name: id\n          description: \"The number of responses for this favorite color - purple will be null\"\n          data_tests:\n            - not_null\n\n\n\n\"\"\"\n\nmodels_v2__override_get_test_models_fail__my_model_sql = \"\"\"\nselect 1 as id\nUNION ALL\nselect null as id\n\"\"\"\n\nmodels_v2__custom_configs__schema_yml = \"\"\"\nversion: 2\n\nmodels:\n  - name: table_copy\n    description: \"A copy of the table\"\n    # passes\n    data_tests:\n      - where\n      - error_if\n      - warn_if\n      - limit\n      - fail_calc\n    columns:\n      - name: id\n        data_tests:\n          # relationships with where\n          - relationships:\n              to: ref('table_copy')  # itself\n              field: id\n              where: 1=1\n  - name: table_copy_another_one\n    data_tests:\n      - where:  # test override + weird quoting\n          config:\n            where: \"\\\\\"favorite_color\\\\\" = 'red'\"\n  - name: \"table.copy.with.dots\"\n    description: \"A copy of the table with a gross name\"\n    # passes, see https://github.com/dbt-labs/dbt-core/issues/3857\n    data_tests:\n      - where\n\n\"\"\"\n\nmodels_v2__custom_configs__table_copy_another_one_sql = \"\"\"\nselect * from {{ ref('table_copy') }}\n\n\"\"\"\n\nmodels_v2__custom_configs__table_copy_sql = \"\"\"\n\n{{\n    config(\n        materialized='table'\n    )\n}}\n\nselect * from {{ this.schema }}.seed\n\n\"\"\"\n\nmodels_v2__custom_configs__table_copy_with_dots_sql = \"\"\"\nselect * from {{ ref('table_copy') }}\n\n\"\"\"\n\nmodels_v2__render_test_configured_arg_models__schema_yml = \"\"\"\nversion: 2\n\nmodels:\n  - name: model\n    data_tests:\n      - equivalent:\n          value: \"{{ var('myvar', 'baz') }}-bar\"\n\n\"\"\"\n\nmodels_v2__render_test_configured_arg_models__model_sql = \"\"\"\nselect 1 as id\n\n\"\"\"\n\nmodels_v2__custom__schema_yml = \"\"\"\nversion: 2\n\nmodels:\n  - name: table_copy\n    description: \"A copy of the table\"\n    columns:\n      - name: email\n        data_tests:\n          - not_null\n      - name: id\n        description: \"The ID\"\n        data_tests:\n          - unique\n      - name: favorite_color\n        data_tests:\n          - every_value_is_blue\n          - rejected_values: { values: ['orange', 'purple'] }\n    # passes\n    data_tests:\n      - local_dep.equality: { compare_model: ref('table_copy') }\n\n\"\"\"\n\nmodels_v2__custom__table_copy_sql = \"\"\"\n\n{{\n    config(\n        materialized='table'\n    )\n}}\n\nselect * from {{ this.schema }}.seed\n\n\"\"\"\n\nmodels_v2__limit_null__schema_yml = \"\"\"\nversion: 2\n\nmodels:\n    - name: table_limit_null\n      description: \"The table has 1 null values, and we're okay with that, until it's more than 1.\"\n      columns:\n        - name: favorite_color_full_list\n          description: \"The favorite color\"\n        - name: count\n          description: \"The number of responses for this favorite color - purple will be null\"\n          data_tests:\n            - not_null:\n                error_if: '>1'\n                warn_if: '>1'\n\n    - name: table_warning_limit_null\n      description: \"The table has 1 null value, and we're okay with 1, but want to know of any.\"\n      columns:\n        - name: favorite_color_full_list\n          description: \"The favorite color\"\n        - name: count\n          description: \"The number of responses for this favorite color - purple will be null\"\n          data_tests:\n            - not_null:\n                error_if: '>1'\n\n    - name: table_failure_limit_null\n      description: \"The table has some 2 null values, and that's not ok.  Warn and error.\"\n      columns:\n        - name: favorite_color_full_list\n          description: \"The favorite color\"\n        - name: count\n          description: \"The number of responses for this favorite color - purple will be null\"\n          data_tests:\n            - not_null:\n                error_if: '>1'\n\n\"\"\"\n\nmodels_v2__limit_null__table_warning_limit_null_sql = \"\"\"\n{{\n    config(\n        materialized='table'\n    )\n}}\n\nselect * from {{ref('table_limit_null')}}\n\"\"\"\n\nmodels_v2__limit_null__table_limit_null_sql = \"\"\"\n{{\n    config(\n        materialized='table'\n    )\n}}\n\nselect favorite_color as favorite_color_full_list, count(*) as count\nfrom {{ this.schema }}.seed\ngroup by 1\n\nUNION ALL\n\nselect 'purple' as favorite_color_full_list, null as count\n\"\"\"\n\nmodels_v2__limit_null__table_failure_limit_null_sql = \"\"\"\n{{\n    config(\n        materialized='table'\n    )\n}}\n\nselect * from {{ref('table_limit_null')}}\n\nUNION ALL\n\nselect 'magenta' as favorite_color_full_list, null as count\n\"\"\"\n\nlocal_utils__dbt_project_yml = \"\"\"\nname: 'local_utils'\nversion: '1.0'\nconfig-version: 2\n\nprofile: 'default'\n\nmacro-paths: [\"macros\"]\n\n\n\"\"\"\n\nlocal_utils__macros__datediff_sql = \"\"\"\n{% macro datediff(first_date, second_date, datepart) %}\n  {{ return(adapter.dispatch('datediff', 'local_utils')(first_date, second_date, datepart)) }}\n{% endmacro %}\n\n\n{% macro default__datediff(first_date, second_date, datepart) %}\n\n    datediff(\n        {{ datepart }},\n        {{ first_date }},\n        {{ second_date }}\n        )\n\n{% endmacro %}\n\n\n{% macro postgres__datediff(first_date, second_date, datepart) %}\n\n    {% if datepart == 'year' %}\n        (date_part('year', ({{second_date}})::date) - date_part('year', ({{first_date}})::date))\n    {% elif datepart == 'quarter' %}\n        ({{ adapter.dispatch('datediff', 'local_utils')(first_date, second_date, 'year') }} * 4 + date_part('quarter', ({{second_date}})::date) - date_part('quarter', ({{first_date}})::date))\n    {% else %}\n        ( 1000 )\n    {% endif %}\n\n{% endmacro %}\n\n\n\"\"\"\n\nlocal_utils__macros__current_timestamp_sql = \"\"\"\n{% macro current_timestamp() -%}\n  {{ return(adapter.dispatch('current_timestamp')) }}\n{%- endmacro %}\n\n{% macro default__current_timestamp() -%}\n  now()\n{%- endmacro %}\n\n\"\"\"\n\nlocal_utils__macros__custom_test_sql = \"\"\"\n{% macro test_dispatch(model) -%}\n  {{ return(adapter.dispatch('test_dispatch', macro_namespace = 'local_utils')()) }}\n{%- endmacro %}\n\n{% macro default__test_dispatch(model) %}\n    select {{ adapter.dispatch('current_timestamp', macro_namespace = 'local_utils')() }}\n{% endmacro %}\n\n\"\"\"\n\nephemeral__schema_yml = \"\"\"\n\nversion: 2\nmodels:\n    - name: ephemeral\n      columns:\n          - name: id\n            data_tests:\n                - unique\n\n\"\"\"\n\nephemeral__ephemeral_sql = \"\"\"\n\n{{ config(materialized='ephemeral') }}\n\nselect 1 as id\n\n\"\"\"\n\nquote_required_models__schema_yml = \"\"\"\nversion: 2\n\nmodels:\n  - name: model\n    columns:\n      - name: Id\n        quote: true\n        data_tests:\n          - unique\n          - not_null\n  - name: model_again\n    quote_columns: true\n    columns:\n      - name: Id\n        data_tests:\n          - unique\n          - not_null\n  - name: model_noquote\n    quote_columns: true\n    columns:\n      - name: Id\n        quote: false\n        data_tests:\n          - unique\n          - not_null\n\nsources:\n  # this should result in column quoting = true\n  - name: my_source\n    schema: \"{{ target.schema }}\"\n    quoting:\n      column: true\n    tables:\n      - name: model\n        quoting:\n          column: false\n        columns:\n          - name: Id\n            quote: true\n            data_tests:\n              - unique\n  - name: my_source_2\n    schema: \"{{ target.schema }}\"\n    quoting:\n      column: false\n    tables:\n      # this should result in column quoting = true\n      - name: model\n        quoting:\n          column: true\n        columns:\n          - name: Id\n            data_tests:\n              - unique\n      # this should result in column quoting = false\n      - name: model_noquote\n        columns:\n          - name: Id\n            data_tests:\n              - unique\n\n\n\"\"\"\n\nquote_required_models__model_again_sql = \"\"\"\nselect 1 as \"Id\"\n\n\"\"\"\n\nquote_required_models__model_noquote_sql = \"\"\"\nselect 1 as id\n\n\"\"\"\n\nquote_required_models__model_sql = \"\"\"\nselect 1 as \"Id\"\n\n\"\"\"\n\nalt_local_utils__macros__type_timestamp_sql = \"\"\"\n{%- macro type_timestamp() -%}\n    {{ return(adapter.dispatch('type_timestamp', 'local_utils')()) }}\n{%- endmacro -%}\n\n{% macro default__type_timestamp() %}\n    {{ return(adapter.dispatch('type_timestamp', 'dbt')()) }}\n{% endmacro %}\n\"\"\"\n\nmacro_resolution_order_macros__my_custom_test_sql = \"\"\"\n{% test my_custom_test(model) %}\n  select cast(current_timestamp as {{ dbt.type_timestamp() }})\n  limit 0\n{% endtest %}\n\"\"\"\n\nmacro_resolution_order_models__my_model_sql = \"\"\"\nselect 1 as id\n\"\"\"\n\nmacro_resolution_order_models__config_yml = \"\"\"\nversion: 2\nmodels:\n  - name: my_model\n    data_tests:\n      - my_custom_test\n\"\"\"\n\nstore_failures_models__my_model_sql = \"\"\"\nselect 1 as id\n\"\"\"\n\nstore_failures_models_true__config_yml = \"\"\"\nversion: 2\nmodels:\n  - name: my_model\n    columns:\n      - name: id\n        tests:\n          - not_null:\n              config:\n                store_failures: true\n\"\"\"\n\nstore_failures_models_false__config_yml = \"\"\"\nversion: 2\nmodels:\n  - name: my_model\n    columns:\n      - name: id\n        tests:\n          - not_null:\n              config:\n                store_failures: false\n\"\"\"\n"
  },
  {
    "path": "tests/functional/schema_tests/test_custom_test_config.py",
    "content": "import re\n\nimport pytest\n\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.contracts.graph.nodes import TestNode\nfrom dbt.exceptions import CompilationError\nfrom dbt.tests.util import get_manifest, run_dbt, update_config_file\n\ncustom_config_yml = \"\"\"\nmodels:\n  - name: table\n    columns:\n      - name: color\n        data_tests:\n          - accepted_values:\n              values: ['blue', 'red']\n              config:\n                custom_config_key: some_value\n          - custom_color_from_config:\n              severity: error\n              config:\n                test_color: orange\n                store_failures: true\n                unlogged: True\n          - not_null:\n              config:\n                not_null_key: abc\n\"\"\"\n\nmixed_config_yml = \"\"\"\nmodels:\n  - name: table\n    columns:\n      - name: color\n        data_tests:\n          - accepted_values:\n              values: ['blue', 'red']\n              config:\n                custom_config_key: some_value\n                severity: warn\n          - custom_color_from_config:\n              severity: error\n              config:\n                test_color: blue\n\"\"\"\n\nsame_key_error_yml = \"\"\"\nmodels:\n  - name: table\n    columns:\n      - name: color\n        data_tests:\n          - accepted_values:\n              values: ['blue', 'red']\n              severity: warn\n              config:\n                severity: error\n\"\"\"\n\nseed_csv = \"\"\"\nid,color,value\n1,blue,10\n2,red,20\n3,green,30\n4,yellow,40\n5,blue,50\n6,red,60\n7,blue,70\n8,green,80\n9,yellow,90\n10,blue,100\n\"\"\".strip()\n\ntable_sql = \"\"\"\n-- content of the table.sql\nselect * from {{ ref('seed') }}\n\"\"\"\n\ntest_custom_color_from_config = \"\"\"\n{% test custom_color_from_config(model, column_name) %}\n    select * from {{ model }}\n    where color = '{{ config.get('test_color') }}'\n{% endtest %}\n\"\"\"\n\n\ndef _select_test_node(manifest: Manifest, pattern: re.Pattern[str]):\n    # Find the test_id dynamically\n    test_id = None\n    for node_id in manifest.nodes:\n        if pattern.match(node_id):\n            test_id = node_id\n            break\n\n    # Ensure the test_id was found\n    assert test_id is not None, \"Test ID matching the pattern was not found in the manifest nodes\"\n    return manifest.nodes[test_id]\n\n\ndef get_table_persistence(project, table_name):\n    sql = f\"\"\"\n        SELECT\n          relpersistence\n        FROM pg_class\n        WHERE relname like '%{table_name}%'\n    \"\"\"\n    result = project.run_sql(sql, fetch=\"one\")\n    assert len(result) == 1\n    return result[0]\n\n\nclass BaseDataTestsConfig:\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\"seed.csv\": seed_csv}\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"custom_color_from_config.sql\": test_custom_color_from_config}\n\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project):\n        run_dbt([\"seed\"])\n\n\nclass TestCustomDataTestConfig(BaseDataTestsConfig):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"table.sql\": table_sql, \"custom_config.yml\": custom_config_yml}\n\n    def test_custom_config(self, project):\n        run_dbt([\"run\"])\n        run_dbt([\"test\"], expect_pass=False)\n\n        manifest = get_manifest(project.project_root)\n        # Pattern to match the test_id without the specific suffix\n        pattern = re.compile(r\"test\\.test\\.accepted_values_table_color__blue__red\\.\\d+\")\n\n        test_node: TestNode = _select_test_node(manifest, pattern)\n        # Proceed with the assertions\n        assert \"custom_config_key\" in test_node.config\n        assert test_node.config[\"custom_config_key\"] == \"some_value\"\n\n        custom_color_pattern = re.compile(r\"test\\.test\\.custom_color_from_config.*\")\n        custom_color_test_node = _select_test_node(manifest, custom_color_pattern)\n        assert custom_color_test_node.config.get(\"test_color\") == \"orange\"\n        assert custom_color_test_node.config.get(\"unlogged\") is True\n        persistence = get_table_persistence(project, \"custom_color_from_config_table_color\")\n        assert persistence == \"u\"\n\n        not_null_pattern = re.compile(r\"test\\.test\\.not_null.*\")\n        not_null_test_node = _select_test_node(manifest, not_null_pattern)\n        assert not_null_test_node.config.get(\"not_null_key\") == \"abc\"\n\n        # set dbt_project.yml config and ensure that schema configs override project configs\n        config_patch = {\n            \"data_tests\": {\"test_color\": \"blue\", \"some_key\": \"strange\", \"not_null_key\": \"def\"}\n        }\n        update_config_file(config_patch, project.project_root, \"dbt_project.yml\")\n        manifest = run_dbt([\"parse\"])\n        custom_color_test_node = _select_test_node(manifest, custom_color_pattern)\n        assert custom_color_test_node.config.get(\"test_color\") == \"orange\"\n        assert custom_color_test_node.config.get(\"some_key\") == \"strange\"\n        not_null_test_node = _select_test_node(manifest, not_null_pattern)\n        assert not_null_test_node.config.get(\"not_null_key\") == \"abc\"\n\n\nclass TestMixedDataTestConfig(BaseDataTestsConfig):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"table.sql\": table_sql, \"mixed_config.yml\": mixed_config_yml}\n\n    def test_mixed_config(self, project):\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n\n        # Pattern to match the test_id without the specific suffix\n        pattern = re.compile(r\"test\\.test\\.accepted_values_table_color__blue__red\\.\\d+\")\n        test_node = _select_test_node(manifest, pattern)\n\n        assert \"custom_config_key\" in test_node.config\n        assert test_node.config[\"custom_config_key\"] == \"some_value\"\n        assert \"severity\" in test_node.config\n        assert test_node.config[\"severity\"] == \"warn\"\n\n\nstring_config_yml = \"\"\"\nmodels:\n  - name: table\n    columns:\n      - name: color\n        data_tests:\n          - not_null:\n              config: \"severity\"\n\"\"\"\n\n\nclass TestConfigNotDictError:\n    \"\"\"\n    Regression test: when 'config' is a non-dict scalar (e.g. a string), dbt should raise\n    a clear ParsingError rather than an opaque AttributeError: 'str' object has no attribute 'pop'.\n    \"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"table.sql\": table_sql, \"string_config.yml\": string_config_yml}\n\n    def test_config_not_dict_raises_error(self, project):\n        from dbt_common.exceptions import DbtBaseException\n\n        with pytest.raises(DbtBaseException) as exc_info:\n            run_dbt([\"parse\"])\n\n        exception_message = str(exc_info.value)\n        assert \"config\" in exception_message.lower()\n        assert \"dict\" in exception_message.lower()\n\n\nclass TestSameKeyErrorDataTestConfig:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"table.sql\": table_sql, \"same_key_error.yml\": same_key_error_yml}\n\n    def test_same_key_error(self, project):\n        \"\"\"\n        Test that verifies dbt raises a CompilationError when the test configuration\n        contains the same key at the top level and inside the config dictionary.\n        \"\"\"\n        # Run dbt and expect a CompilationError due to the invalid configuration\n        with pytest.raises(CompilationError) as exc_info:\n            run_dbt([\"parse\"])\n\n        # Extract the exception message\n        exception_message = str(exc_info.value)\n\n        # Assert that the error message contains the expected text\n        assert \"Test cannot have the same key at the top-level and in config\" in exception_message\n"
  },
  {
    "path": "tests/functional/schema_tests/test_schema_v2_tests.py",
    "content": "import os\nimport re\n\nimport pytest\n\nfrom dbt.contracts.results import TestStatus\nfrom dbt.exceptions import CompilationError, DuplicateResourceNameError, ParsingError\nfrom dbt.tests.fixtures.project import write_project_files\nfrom dbt.tests.util import run_dbt, write_file\nfrom tests.fixtures.dbt_integration_project import dbt_integration_project  # noqa: F401\nfrom tests.functional.schema_tests.fixtures import (\n    all_quotes_schema__schema_yml,\n    alt_local_utils__macros__type_timestamp_sql,\n    case_sensitive_models__lowercase_sql,\n    case_sensitive_models__schema_yml,\n    case_sensitive_models__uppercase_SQL,\n    custom_generic_test_config_custom_macro__model_a,\n    custom_generic_test_config_custom_macro__schema_yml,\n    custom_generic_test_names__model_a,\n    custom_generic_test_names__schema_yml,\n    custom_generic_test_names_alt_format__model_a,\n    custom_generic_test_names_alt_format__schema_yml,\n    dupe_generic_tests_collide__model_a,\n    dupe_generic_tests_collide__schema_yml,\n    ephemeral__ephemeral_sql,\n    ephemeral__schema_yml,\n    invalid_schema_models__model_sql,\n    invalid_schema_models__schema_yml,\n    local_dependency__dbt_project_yml,\n    local_dependency__macros__equality_sql,\n    local_utils__dbt_project_yml,\n    local_utils__macros__current_timestamp_sql,\n    local_utils__macros__custom_test_sql,\n    local_utils__macros__datediff_sql,\n    macro_resolution_order_macros__my_custom_test_sql,\n    macro_resolution_order_models__config_yml,\n    macro_resolution_order_models__my_model_sql,\n    macros_v2__custom_configs__test_sql,\n    macros_v2__macros__tests_sql,\n    macros_v2__override_get_test_macros__get_test_sql_sql,\n    macros_v2__override_get_test_macros_fail__get_test_sql_sql,\n    models_v2__custom__schema_yml,\n    models_v2__custom__table_copy_sql,\n    models_v2__custom_configs__schema_yml,\n    models_v2__custom_configs__table_copy_another_one_sql,\n    models_v2__custom_configs__table_copy_sql,\n    models_v2__custom_configs__table_copy_with_dots_sql,\n    models_v2__limit_null__schema_yml,\n    models_v2__limit_null__table_failure_limit_null_sql,\n    models_v2__limit_null__table_limit_null_sql,\n    models_v2__limit_null__table_warning_limit_null_sql,\n    models_v2__malformed__schema_yml,\n    models_v2__malformed__table_copy_sql,\n    models_v2__malformed__table_summary_sql,\n    models_v2__models__schema_yml,\n    models_v2__models__table_copy_sql,\n    models_v2__models__table_disabled_sql,\n    models_v2__models__table_failure_copy_sql,\n    models_v2__models__table_failure_null_relation_sql,\n    models_v2__models__table_failure_summary_sql,\n    models_v2__models__table_summary_sql,\n    models_v2__override_get_test_models__my_model_failure_sql,\n    models_v2__override_get_test_models__my_model_pass_sql,\n    models_v2__override_get_test_models__my_model_warning_sql,\n    models_v2__override_get_test_models__schema_yml,\n    models_v2__override_get_test_models_fail__my_model_sql,\n    models_v2__override_get_test_models_fail__schema_yml,\n    models_v2__render_test_cli_arg_models__model_sql,\n    models_v2__render_test_cli_arg_models__schema_yml,\n    models_v2__render_test_configured_arg_models__model_sql,\n    models_v2__render_test_configured_arg_models__schema_yml,\n    name_collision__base_extension_sql,\n    name_collision__base_sql,\n    name_collision__schema_yml,\n    quote_required_models__model_again_sql,\n    quote_required_models__model_noquote_sql,\n    quote_required_models__model_sql,\n    quote_required_models__schema_yml,\n    seeds__some_seed_csv,\n    store_failures_models__my_model_sql,\n    store_failures_models_false__config_yml,\n    store_failures_models_true__config_yml,\n    test_context_macros__custom_schema_tests_sql,\n    test_context_macros__my_test_sql,\n    test_context_macros__test_my_datediff_sql,\n    test_context_macros_namespaced__custom_schema_tests_sql,\n    test_context_macros_namespaced__my_test_sql,\n    test_context_models__model_a_sql,\n    test_context_models__model_b_sql,\n    test_context_models__model_c_sql,\n    test_context_models__schema_yml,\n    test_context_models_namespaced__model_a_sql,\n    test_context_models_namespaced__model_b_sql,\n    test_context_models_namespaced__model_c_sql,\n    test_context_models_namespaced__schema_yml,\n    test_context_where_subq_macros__custom_generic_test_sql,\n    test_context_where_subq_models__model_a_sql,\n    test_context_where_subq_models__schema_yml,\n    test_utils__dbt_project_yml,\n    test_utils__macros__current_timestamp_sql,\n    test_utils__macros__custom_test_sql,\n    wrong_specification_block__schema_yml,\n)\n\n\nclass TestSchemaTests:\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project):\n        project.run_sql_file(os.path.join(project.test_data_dir, \"seed.sql\"))\n        project.run_sql_file(os.path.join(project.test_data_dir, \"seed_failure.sql\"))\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": models_v2__models__schema_yml,\n            \"table_summary.sql\": models_v2__models__table_summary_sql,\n            \"table_failure_summary.sql\": models_v2__models__table_failure_summary_sql,\n            \"table_disabled.sql\": models_v2__models__table_disabled_sql,\n            \"table_failure_null_relation.sql\": models_v2__models__table_failure_null_relation_sql,\n            \"table_failure_copy.sql\": models_v2__models__table_failure_copy_sql,\n            \"table_copy.sql\": models_v2__models__table_copy_sql,\n        }\n\n    def assertTestFailed(self, result):\n        assert result.status == \"fail\"\n        assert not result.skipped\n        assert result.failures > 0, \"test {} did not fail\".format(result.node.name)\n\n    def assertTestPassed(self, result):\n        assert result.status == \"pass\"\n        assert not result.skipped\n        assert result.failures == 0, \"test {} failed\".format(result.node.name)\n\n    def test_schema_tests(\n        self,\n        project,\n    ):\n        results = run_dbt()\n        assert len(results) == 5\n        test_results = run_dbt([\"test\"], expect_pass=False)\n        # If the disabled model's tests ran, there would be 20 of these.\n        assert len(test_results) == 19\n\n        for result in test_results:\n            # assert that all deliberately failing tests actually fail\n            if \"failure\" in result.node.name:\n                self.assertTestFailed(result)\n            # assert that actual tests pass\n            else:\n                self.assertTestPassed(result)\n        assert sum(x.failures for x in test_results) == 6\n\n    def test_schema_test_selection(\n        self,\n        project,\n    ):\n        results = run_dbt()\n        assert len(results) == 5\n        test_results = run_dbt([\"test\", \"--models\", \"tag:table_favorite_color\"])\n        # 1 in table_copy, 4 in table_summary\n        assert len(test_results) == 5\n        for result in test_results:\n            self.assertTestPassed(result)\n\n        test_results = run_dbt([\"test\", \"--models\", \"tag:favorite_number_is_pi\"])\n        assert len(test_results) == 1\n        self.assertTestPassed(test_results[0])\n\n        test_results = run_dbt([\"test\", \"--models\", \"tag:table_copy_favorite_color\"])\n        assert len(test_results) == 1\n        self.assertTestPassed(test_results[0])\n\n    def test_schema_test_exclude_failures(\n        self,\n        project,\n    ):\n        results = run_dbt()\n        assert len(results) == 5\n        test_results = run_dbt([\"test\", \"--exclude\", \"tag:xfail\"])\n        # If the failed + disabled model's tests ran, there would be 20 of these.\n        assert len(test_results) == 13\n        for result in test_results:\n            self.assertTestPassed(result)\n        test_results = run_dbt([\"test\", \"--models\", \"tag:xfail\"], expect_pass=False)\n        assert len(test_results) == 6\n        for result in test_results:\n            self.assertTestFailed(result)\n\n\nclass TestLimitedSchemaTests:\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project):\n        project.run_sql_file(os.path.join(project.test_data_dir, \"seed.sql\"))\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": models_v2__limit_null__schema_yml,\n            \"table_warning_limit_null.sql\": models_v2__limit_null__table_warning_limit_null_sql,\n            \"table_limit_null.sql\": models_v2__limit_null__table_limit_null_sql,\n            \"table_failure_limit_null.sql\": models_v2__limit_null__table_failure_limit_null_sql,\n        }\n\n    def assertTestFailed(self, result):\n        assert result.status == \"fail\"\n        assert not result.skipped\n        assert result.failures > 0, \"test {} did not fail\".format(result.node.name)\n\n    def assertTestWarn(self, result):\n        assert result.status == \"warn\"\n        assert not result.skipped\n        assert result.failures > 0, \"test {} passed without expected warning\".format(\n            result.node.name\n        )\n\n    def assertTestPassed(self, result):\n        assert result.status == \"pass\"\n        assert not result.skipped\n        assert result.failures == 0, \"test {} failed\".format(result.node.name)\n\n    def test_limit_schema_tests(\n        self,\n        project,\n    ):\n        results = run_dbt()\n        assert len(results) == 3\n        test_results = run_dbt([\"test\"], expect_pass=False)\n        assert len(test_results) == 3\n\n        for result in test_results:\n            # assert that all deliberately failing tests actually fail\n            if \"failure\" in result.node.name:\n                self.assertTestFailed(result)\n            # assert that tests with warnings have them\n            elif \"warning\" in result.node.name:\n                self.assertTestWarn(result)\n            # assert that actual tests pass\n            else:\n                self.assertTestPassed(result)\n        # warnings are also marked as failures\n        assert sum(x.failures for x in test_results) == 3\n\n\nclass TestDefaultBoolType:\n    # test with default True/False in get_test_sql macro\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": models_v2__override_get_test_models__schema_yml,\n            \"my_model_warning.sql\": models_v2__override_get_test_models__my_model_warning_sql,\n            \"my_model_pass.sql\": models_v2__override_get_test_models__my_model_pass_sql,\n            \"my_model_failure.sql\": models_v2__override_get_test_models__my_model_failure_sql,\n        }\n\n    def assertTestFailed(self, result):\n        assert result.status == \"fail\"\n        assert not result.skipped\n        assert result.failures > 0, \"test {} did not fail\".format(result.node.name)\n\n    def assertTestWarn(self, result):\n        assert result.status == \"warn\"\n        assert not result.skipped\n        assert result.failures > 0, \"test {} passed without expected warning\".format(\n            result.node.name\n        )\n\n    def assertTestPassed(self, result):\n        assert result.status == \"pass\"\n        assert not result.skipped\n        assert result.failures == 0, \"test {} failed\".format(result.node.name)\n\n    def test_limit_schema_tests(\n        self,\n        project,\n    ):\n        results = run_dbt()\n        assert len(results) == 3\n        test_results = run_dbt([\"test\"], expect_pass=False)\n        assert len(test_results) == 3\n\n        for result in test_results:\n            # assert that all deliberately failing tests actually fail\n            if \"failure\" in result.node.name:\n                self.assertTestFailed(result)\n            # assert that tests with warnings have them\n            elif \"warning\" in result.node.name:\n                self.assertTestWarn(result)\n            # assert that actual tests pass\n            else:\n                self.assertTestPassed(result)\n        # warnings are also marked as failures\n        assert sum(x.failures for x in test_results) == 3\n\n\nclass TestOtherBoolType:\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project_root):\n        macros_v2_file = {\n            \"override_get_test_macros\": {\n                \"get_test_sql.sql\": macros_v2__override_get_test_macros__get_test_sql_sql\n            },\n        }\n        write_project_files(project_root, \"macros-v2\", macros_v2_file)\n\n    # test with expected 0/1 in custom get_test_sql macro\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": models_v2__override_get_test_models__schema_yml,\n            \"my_model_warning.sql\": models_v2__override_get_test_models__my_model_warning_sql,\n            \"my_model_pass.sql\": models_v2__override_get_test_models__my_model_pass_sql,\n            \"my_model_failure.sql\": models_v2__override_get_test_models__my_model_failure_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"config-version\": 2,\n            \"macro-paths\": [\"macros-v2/override_get_test_macros\"],\n        }\n\n    def assertTestFailed(self, result):\n        assert result.status == \"fail\"\n        assert not result.skipped\n        assert result.failures > 0, \"test {} did not fail\".format(result.node.name)\n\n    def assertTestWarn(self, result):\n        assert result.status == \"warn\"\n        assert not result.skipped\n        assert result.failures > 0, \"test {} passed without expected warning\".format(\n            result.node.name\n        )\n\n    def assertTestPassed(self, result):\n        assert result.status == \"pass\"\n        assert not result.skipped\n        assert result.failures == 0, \"test {} failed\".format(result.node.name)\n\n    def test_limit_schema_tests(\n        self,\n        project,\n    ):\n        results = run_dbt()\n        assert len(results) == 3\n        test_results = run_dbt([\"test\"], expect_pass=False)\n        assert len(test_results) == 3\n\n        for result in test_results:\n            # assert that all deliberately failing tests actually fail\n            if \"failure\" in result.node.name:\n                self.assertTestFailed(result)\n            # assert that tests with warnings have them\n            elif \"warning\" in result.node.name:\n                self.assertTestWarn(result)\n            # assert that actual tests pass\n            else:\n                self.assertTestPassed(result)\n        # warnings are also marked as failures\n        assert sum(x.failures for x in test_results) == 3\n\n\nclass TestNonBoolType:\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project_root):\n        macros_v2_file = {\n            \"override_get_test_macros_fail\": {\n                \"get_test_sql.sql\": macros_v2__override_get_test_macros_fail__get_test_sql_sql\n            },\n        }\n        write_project_files(project_root, \"macros-v2\", macros_v2_file)\n\n    # test with invalid 'x'/'y' in custom get_test_sql macro\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": models_v2__override_get_test_models_fail__schema_yml,\n            \"my_model.sql\": models_v2__override_get_test_models_fail__my_model_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"config-version\": 2,\n            \"macro-paths\": [\"macros-v2/override_get_test_macros_fail\"],\n        }\n\n    def test_limit_schema_tests(\n        self,\n        project,\n    ):\n        results = run_dbt()\n        assert len(results) == 1\n        run_result = run_dbt([\"test\"], expect_pass=False)\n        results = run_result.results\n        assert len(results) == 1\n        assert results[0].status == TestStatus.Error\n        assert re.search(r\"'get_test_sql' returns 'x'\", results[0].message)\n\n\nclass TestMalformedSchemaTests:\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project):\n        project.run_sql_file(os.path.join(project.test_data_dir, \"seed.sql\"))\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": models_v2__malformed__schema_yml,\n            \"table_summary.sql\": models_v2__malformed__table_summary_sql,\n            \"table_copy.sql\": models_v2__malformed__table_copy_sql,\n        }\n\n    def test_malformed_schema_will_break_run(\n        self,\n        project,\n    ):\n        with pytest.raises(ParsingError):\n            run_dbt()\n\n\nclass TestCustomConfigSchemaTests:\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project, project_root):\n        project.run_sql_file(os.path.join(project.test_data_dir, \"seed.sql\"))\n\n        macros_v2_file = {\"custom-configs\": {\"test.sql\": macros_v2__custom_configs__test_sql}}\n        write_project_files(project_root, \"macros-v2\", macros_v2_file)\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": models_v2__custom_configs__schema_yml,\n            \"table_copy_another_one.sql\": models_v2__custom_configs__table_copy_another_one_sql,\n            \"table_copy.sql\": models_v2__custom_configs__table_copy_sql,\n            \"table.copy.with.dots.sql\": models_v2__custom_configs__table_copy_with_dots_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"config-version\": 2,\n            \"macro-paths\": [\"macros-v2/custom-configs\"],\n        }\n\n    def test_config(\n        self,\n        project,\n    ):\n        \"\"\"Test that tests use configs properly. All tests for\n        this project will fail, configs are set to make test pass.\"\"\"\n        results = run_dbt([\"test\"], expect_pass=False)\n\n        assert len(results) == 8\n        for result in results:\n            assert not result.skipped\n\n\nclass TestHooksInTests:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": ephemeral__schema_yml,\n            \"ephemeral.sql\": ephemeral__ephemeral_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"config-version\": 2,\n            \"on-run-start\": [\"{{ log('hooks called in tests -- good!') if execute }}\"],\n            \"on-run-end\": [\"{{ log('hooks called in tests -- good!') if execute }}\"],\n        }\n\n    def test_hooks_do_run_for_tests(\n        self,\n        project,\n    ):\n        # This passes now that hooks run, a behavior we changed in v1.0\n        results = run_dbt([\"test\", \"--model\", \"ephemeral\"])\n        assert len(results) == 3\n        for result in results:\n            assert result.status in (\"pass\", \"success\")\n            assert not result.skipped\n            assert result.failures == 0, \"test {} failed\".format(result.node.name)\n\n\nclass TestHooksForWhich:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": ephemeral__schema_yml,\n            \"ephemeral.sql\": ephemeral__ephemeral_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"config-version\": 2,\n            \"on-run-start\": [\n                \"{{exceptions.raise_compiler_error('hooks called in tests -- error') if (execute and flags.WHICH != 'test') }}\"\n            ],\n            \"on-run-end\": [\n                \"{{exceptions.raise_compiler_error('hooks called in tests -- error') if (execute and flags.WHICH != 'test') }}\"\n            ],\n        }\n\n    def test_these_hooks_dont_run_for_tests(\n        self,\n        project,\n    ):\n        # This would fail if the hooks ran\n        results = run_dbt([\"test\", \"--model\", \"ephemeral\"])\n        assert len(results) == 3\n        for result in results:\n            assert result.status in (\"pass\", \"success\")\n            assert not result.skipped\n            assert result.failures == 0, \"test {} failed\".format(result.node.name)\n\n\nclass TestCustomSchemaTests:\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project, project_root, dbt_integration_project):  # noqa: F811\n        write_project_files(project_root, \"dbt_integration_project\", dbt_integration_project)\n        project.run_sql_file(os.path.join(project.test_data_dir, \"seed.sql\"))\n\n        local_dependency_files = {\n            \"dbt_project.yml\": local_dependency__dbt_project_yml,\n            \"macros\": {\"equality.sql\": local_dependency__macros__equality_sql},\n        }\n        write_project_files(project_root, \"local_dependency\", local_dependency_files)\n\n        macros_v2_file = {\n            \"macros\": {\"tests.sql\": macros_v2__macros__tests_sql},\n        }\n        write_project_files(project_root, \"macros-v2\", macros_v2_file)\n\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\n            \"packages\": [\n                {\n                    \"local\": \"./local_dependency\",\n                },\n                {\n                    \"local\": \"./dbt_integration_project\",\n                },\n            ]\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        # dbt-utils contains a schema test (equality)\n        # dbt-integration-project contains a schema.yml file\n        # both should work!\n        return {\n            \"config-version\": 2,\n            \"macro-paths\": [\"macros-v2/macros\"],\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": models_v2__custom__schema_yml,\n            \"table_copy.sql\": models_v2__custom__table_copy_sql,\n        }\n\n    def test_schema_tests(\n        self,\n        project,\n    ):\n        run_dbt([\"deps\"])\n        results = run_dbt()\n        assert len(results) == 4\n\n        test_results = run_dbt([\"test\"], expect_pass=False)\n        assert len(test_results) == 6\n\n        expected_failures = [\n            \"not_null_table_copy_email\",\n            \"every_value_is_blue_table_copy_favorite_color\",\n        ]\n\n        for result in test_results:\n            if result.status == \"fail\":\n                assert result.node.name in expected_failures\n\n\nclass TestQuotedSchemaTestColumns:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": quote_required_models__schema_yml,\n            \"model_again.sql\": quote_required_models__model_again_sql,\n            \"model_noquote.sql\": quote_required_models__model_noquote_sql,\n            \"model.sql\": quote_required_models__model_sql,\n        }\n\n    def test_quote_required_column(\n        self,\n        project,\n    ):\n        results = run_dbt()\n        assert len(results) == 3\n        results = run_dbt([\"test\", \"-m\", \"model\"])\n        assert len(results) == 2\n        results = run_dbt([\"test\", \"-m\", \"model_again\"])\n        assert len(results) == 2\n        results = run_dbt([\"test\", \"-m\", \"model_noquote\"])\n        assert len(results) == 2\n        results = run_dbt([\"test\", \"-m\", \"source:my_source\"])\n        assert len(results) == 1\n        results = run_dbt([\"test\", \"-m\", \"source:my_source_2\"])\n        assert len(results) == 2\n\n\nclass TestCliVarsSchemaTests:\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project_root):\n        macros_v2_file = {\n            \"macros\": {\"tests.sql\": macros_v2__macros__tests_sql},\n        }\n        write_project_files(project_root, \"macros-v2\", macros_v2_file)\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": models_v2__render_test_cli_arg_models__schema_yml,\n            \"model.sql\": models_v2__render_test_cli_arg_models__model_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"config-version\": 2,\n            \"macro-paths\": [\"macros-v2/macros\"],\n        }\n\n    def test_argument_rendering(\n        self,\n        project,\n    ):\n        results = run_dbt()\n        assert len(results) == 1\n        results = run_dbt([\"test\", \"--vars\", \"{myvar: foo}\"])\n        assert len(results) == 1\n        run_dbt([\"test\"], expect_pass=False)\n\n\nclass TestConfiguredVarsSchemaTests:\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project_root):\n        macros_v2_file = {\n            \"macros\": {\"tests.sql\": macros_v2__macros__tests_sql},\n        }\n        write_project_files(project_root, \"macros-v2\", macros_v2_file)\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": models_v2__render_test_configured_arg_models__schema_yml,\n            \"model.sql\": models_v2__render_test_configured_arg_models__model_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"config-version\": 2,\n            \"macro-paths\": [\"macros-v2/macros\"],\n            \"vars\": {\"myvar\": \"foo\"},\n        }\n\n    def test_argument_rendering(\n        self,\n        project,\n    ):\n        results = run_dbt()\n        assert len(results) == 1\n        results = run_dbt([\"test\"])\n        assert len(results) == 1\n\n\nclass TestSchemaCaseInsensitive:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": case_sensitive_models__schema_yml,\n            \"lowercase.sql\": case_sensitive_models__lowercase_sql,\n        }\n\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUP(self, project):\n        # Create the uppercase SQL file\n        model_dir = os.path.join(project.project_root, \"models\")\n        write_file(case_sensitive_models__uppercase_SQL, model_dir, \"uppercase.SQL\")\n\n    def test_schema_lowercase_sql(\n        self,\n        project,\n    ):\n        results = run_dbt()\n        assert len(results) == 2\n        results = run_dbt([\"test\", \"-m\", \"lowercase\"])\n        assert len(results) == 1\n\n    def test_schema_uppercase_sql(\n        self,\n        project,\n    ):\n        results = run_dbt()\n        assert len(results) == 2\n        results = run_dbt([\"test\", \"-m\", \"uppercase\"])\n        assert len(results) == 1\n\n\nclass TestSchemaTestContext:\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project_root):\n        local_utils_files = {\n            \"dbt_project.yml\": local_utils__dbt_project_yml,\n            \"macros\": {\n                \"datediff.sql\": local_utils__macros__datediff_sql,\n                \"current_timestamp.sql\": local_utils__macros__current_timestamp_sql,\n                \"custom_test.sql\": local_utils__macros__custom_test_sql,\n            },\n        }\n        write_project_files(project_root, \"local_utils\", local_utils_files)\n\n        test_context_macros_files = {\n            \"my_test.sql\": test_context_macros__my_test_sql,\n            \"test_my_datediff.sql\": test_context_macros__test_my_datediff_sql,\n            \"custom_schema_tests.sql\": test_context_macros__custom_schema_tests_sql,\n        }\n        write_project_files(project_root, \"test-context-macros\", test_context_macros_files)\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": test_context_models__schema_yml,\n            \"model_c.sql\": test_context_models__model_c_sql,\n            \"model_b.sql\": test_context_models__model_b_sql,\n            \"model_a.sql\": test_context_models__model_a_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"config-version\": 2,\n            \"macro-paths\": [\"test-context-macros\"],\n            \"vars\": {\"local_utils_dispatch_list\": [\"local_utils\"]},\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\"packages\": [{\"local\": \"local_utils\"}]}\n\n    def test_test_context_tests(self, project):\n        # This test tests the the TestContext and TestMacroNamespace\n        # are working correctly\n        run_dbt([\"deps\"])\n        results = run_dbt()\n        assert len(results) == 3\n\n        run_result = run_dbt([\"test\"], expect_pass=False)\n        results = run_result.results\n        results = sorted(results, key=lambda r: r.node.name)\n        assert len(results) == 5\n        # call_pkg_macro_model_c_\n        assert results[0].status == TestStatus.Fail\n        # dispatch_model_c_\n        assert results[1].status == TestStatus.Fail\n        # my_datediff\n        assert re.search(r\"1000\", results[2].node.compiled_code)\n        # type_one_model_a_\n        assert results[3].status == TestStatus.Fail\n        assert re.search(r\"union all\", results[3].node.compiled_code)\n        # type_two_model_a_\n        assert results[4].status == TestStatus.Warn\n        assert results[4].node.config.severity == \"WARN\"\n\n\nclass TestSchemaTestContextWithMacroNamespace:\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project_root):\n        test_utils_files = {\n            \"dbt_project.yml\": test_utils__dbt_project_yml,\n            \"macros\": {\n                \"current_timestamp.sql\": test_utils__macros__current_timestamp_sql,\n                \"custom_test.sql\": test_utils__macros__custom_test_sql,\n            },\n        }\n        write_project_files(project_root, \"test_utils\", test_utils_files)\n\n        local_utils_files = {\n            \"dbt_project.yml\": local_utils__dbt_project_yml,\n            \"macros\": {\n                \"datediff.sql\": local_utils__macros__datediff_sql,\n                \"current_timestamp.sql\": local_utils__macros__current_timestamp_sql,\n                \"custom_test.sql\": local_utils__macros__custom_test_sql,\n            },\n        }\n        write_project_files(project_root, \"local_utils\", local_utils_files)\n\n        test_context_macros_namespaced_file = {\n            \"my_test.sql\": test_context_macros_namespaced__my_test_sql,\n            \"custom_schema_tests.sql\": test_context_macros_namespaced__custom_schema_tests_sql,\n        }\n        write_project_files(\n            project_root, \"test-context-macros-namespaced\", test_context_macros_namespaced_file\n        )\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": test_context_models_namespaced__schema_yml,\n            \"model_c.sql\": test_context_models_namespaced__model_c_sql,\n            \"model_b.sql\": test_context_models_namespaced__model_b_sql,\n            \"model_a.sql\": test_context_models_namespaced__model_a_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"config-version\": 2,\n            \"macro-paths\": [\"test-context-macros-namespaced\"],\n            \"dispatch\": [\n                {\n                    \"macro_namespace\": \"test_utils\",\n                    \"search_order\": [\"local_utils\", \"test_utils\"],\n                }\n            ],\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\n            \"packages\": [\n                {\"local\": \"test_utils\"},\n                {\"local\": \"local_utils\"},\n            ]\n        }\n\n    def test_test_context_with_macro_namespace(\n        self,\n        project,\n    ):\n        # This test tests the the TestContext and TestMacroNamespace\n        # are working correctly\n        run_dbt([\"deps\"])\n        results = run_dbt()\n        assert len(results) == 3\n\n        run_result = run_dbt([\"test\"], expect_pass=False)\n        results = run_result.results\n        results = sorted(results, key=lambda r: r.node.name)\n        assert len(results) == 4\n        # call_pkg_macro_model_c_\n        assert results[0].status == TestStatus.Fail\n        # dispatch_model_c_\n        assert results[1].status == TestStatus.Fail\n        # type_one_model_a_\n        assert results[2].status == TestStatus.Fail\n        assert re.search(r\"union all\", results[2].node.compiled_code)\n        # type_two_model_a_\n        assert results[3].status == TestStatus.Warn\n        assert results[3].node.config.severity == \"WARN\"\n\n\nclass TestSchemaTestNameCollision:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": name_collision__schema_yml,\n            \"base.sql\": name_collision__base_sql,\n            \"base_extension.sql\": name_collision__base_extension_sql,\n        }\n\n    def test_collision_test_names_get_hash(\n        self,\n        project,\n    ):\n        \"\"\"The models should produce unique IDs with a has appended\"\"\"\n        results = run_dbt()\n        test_results = run_dbt([\"test\"])\n\n        # both models and both tests run\n        assert len(results) == 2\n        assert len(test_results) == 2\n\n        # both tests have the same unique id except for the hash\n        expected_unique_ids = [\n            \"test.test.not_null_base_extension_id.922d83a56c\",\n            \"test.test.not_null_base_extension_id.c8d18fe069\",\n        ]\n        assert test_results[0].node.unique_id in expected_unique_ids\n        assert test_results[1].node.unique_id in expected_unique_ids\n\n\nclass TestGenericTestsCollide:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": dupe_generic_tests_collide__schema_yml,\n            \"model_a.sql\": dupe_generic_tests_collide__model_a,\n        }\n\n    def test_generic_test_collision(\n        self,\n        project,\n    ):\n        \"\"\"These tests collide, since only the configs differ\"\"\"\n        with pytest.raises(DuplicateResourceNameError) as exc:\n            run_dbt()\n        assert \"dbt found two data_tests with the name\" in str(exc.value)\n\n\nclass TestGenericTestsConfigCustomMacros:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": custom_generic_test_config_custom_macro__schema_yml,\n            \"model_a.sql\": custom_generic_test_config_custom_macro__model_a,\n        }\n\n    def test_generic_test_config_custom_macros(\n        self,\n        project,\n    ):\n        \"\"\"This test has a reference to a custom macro its configs\"\"\"\n        with pytest.raises(CompilationError) as exc:\n            run_dbt()\n        assert \"Invalid generic test configuration\" in str(exc)\n\n\nclass TestGenericTestsCustomNames:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": custom_generic_test_names__schema_yml,\n            \"model_a.sql\": custom_generic_test_names__model_a,\n        }\n\n    # users can define custom names for specific instances of generic tests\n    def test_generic_tests_with_custom_names(\n        self,\n        project,\n    ):\n        \"\"\"These tests don't collide, since they have user-provided custom names\"\"\"\n        results = run_dbt()\n        test_results = run_dbt([\"test\"])\n\n        # model + both tests run\n        assert len(results) == 1\n        assert len(test_results) == 2\n\n        # custom names propagate to the unique_id\n        expected_unique_ids = [\n            \"test.test.not_null_where_1_equals_1.7b96089006\",\n            \"test.test.not_null_where_1_equals_2.8ae586e17f\",\n        ]\n        assert test_results[0].node.unique_id in expected_unique_ids\n        assert test_results[1].node.unique_id in expected_unique_ids\n\n\nclass TestGenericTestsCustomNamesAltFormat(TestGenericTestsCustomNames):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": custom_generic_test_names_alt_format__schema_yml,\n            \"model_a.sql\": custom_generic_test_names_alt_format__model_a,\n        }\n\n    # exactly as above, just alternative format for yaml definition\n    def test_collision_test_names_get_hash(\n        self,\n        project,\n    ):\n        \"\"\"These tests don't collide, since they have user-provided custom names,\n        defined using an alternative format\"\"\"\n        super().test_generic_tests_with_custom_names(project)\n\n\nclass TestInvalidSchema:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": invalid_schema_models__schema_yml,\n            \"model.sql\": invalid_schema_models__model_sql,\n        }\n\n    def test_invalid_schema_file(\n        self,\n        project,\n    ):\n        with pytest.raises(ParsingError) as exc:\n            run_dbt()\n        assert re.search(r\"'models' is not a list\", str(exc))\n\n\nclass TestCommentedSchema:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": all_quotes_schema__schema_yml,\n            \"model.sql\": invalid_schema_models__model_sql,\n        }\n\n    def test_quoted_schema_file(self, project):\n        try:\n            # A schema file consisting entirely of quotes should not be a problem\n            run_dbt([\"parse\"])\n        except TypeError:\n            assert (\n                False\n            ), \"`dbt parse` failed with a yaml file that is all comments with the same exception as 3568\"\n        except Exception:\n            assert False, \"`dbt parse` failed with a yaml file that is all comments\"\n\n\nclass TestWrongSpecificationBlock:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"schema.yml\": wrong_specification_block__schema_yml}\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\"some_seed.csv\": seeds__some_seed_csv}\n\n    def test_wrong_specification_block(\n        self,\n        project,\n    ):\n        with pytest.warns(Warning):\n            results = run_dbt(\n                [\n                    \"ls\",\n                    \"-s\",\n                    \"some_seed\",\n                    \"--output\",\n                    \"json\",\n                    \"--output-keys\",\n                    \"name\",\n                    \"description\",\n                ]\n            )\n\n        assert len(results) == 1\n        assert results[0] == '{\"name\": \"some_seed\", \"description\": \"\"}'\n\n\nclass TestSchemaTestContextWhereSubq:\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project_root):\n        test_context_where_subq_macros_file = {\n            \"custom_generic_test.sql\": test_context_where_subq_macros__custom_generic_test_sql\n        }\n        write_project_files(\n            project_root, \"test-context-where-subq-macros\", test_context_where_subq_macros_file\n        )\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": test_context_where_subq_models__schema_yml,\n            \"model_a.sql\": test_context_where_subq_models__model_a_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"config-version\": 2,\n            \"macro-paths\": [\"test-context-where-subq-macros\"],\n        }\n\n    def test_test_context_tests(\n        self,\n        project,\n    ):\n        # This test tests that get_where_subquery() is included in TestContext + TestMacroNamespace,\n        # otherwise api.Relation.create() will return an error\n        results = run_dbt()\n        assert len(results) == 1\n\n        results = run_dbt([\"test\"])\n        assert len(results) == 1\n\n\nclass TestCustomSchemaTestMacroResolutionOrder:\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project_root):\n        alt_local_utils_file = {\n            \"dbt_project.yml\": local_utils__dbt_project_yml,\n            \"macros\": {\n                \"datediff.sql\": alt_local_utils__macros__type_timestamp_sql,\n            },\n        }\n        write_project_files(project_root, \"alt_local_utils\", alt_local_utils_file)\n\n        macros_resolution_order_file = {\n            \"my_custom_test.sql\": macro_resolution_order_macros__my_custom_test_sql,\n        }\n        write_project_files(\n            project_root, \"macro_resolution_order_macros\", macros_resolution_order_file\n        )\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": macro_resolution_order_models__config_yml,\n            \"my_model.sql\": macro_resolution_order_models__my_model_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"config-version\": 2,\n            \"macro-paths\": [\"macro_resolution_order_macros\"],\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\"packages\": [{\"local\": \"alt_local_utils\"}]}\n\n    def test_macro_resolution_test_namespace(\n        self,\n        project,\n    ):\n        # https://github.com/dbt-labs/dbt-core/issues/5720\n        # Previously, macros called as 'dbt.some_macro' would not correctly\n        # resolve to 'some_macro' from the 'dbt' namespace during static analysis,\n        # if 'some_macro' also existed in an installed package,\n        # leading to the macro being missing in the TestNamespace\n        run_dbt([\"deps\"])\n        run_dbt([\"parse\"])\n\n\nclass TestSchemaTestStoreFailuresTrueParsing:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": store_failures_models_true__config_yml,\n            \"my_model.sql\": store_failures_models__my_model_sql,\n        }\n\n    def test_parse_store_failures_True_as_table(self, project):\n        manifest = run_dbt([\"parse\"])\n        test_node = [\n            node for node in manifest.nodes.values() if \"not_null_my_model_id\" in node.fqn\n        ][0]\n\n        assert test_node.config.store_failures\n        assert test_node.config.store_failures_as == \"table\"\n\n\nclass TestSchemaTestStoreFailuresFalseParsing:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": store_failures_models_false__config_yml,\n            \"my_model.sql\": store_failures_models__my_model_sql,\n        }\n\n    def test_parse_store_failures_False_as_ephemeral(self, project):\n        manifest = run_dbt([\"parse\"])\n        test_node = [\n            node for node in manifest.nodes.values() if \"not_null_my_model_id\" in node.fqn\n        ][0]\n\n        assert not test_node.config.store_failures\n        assert test_node.config.store_failures_as == \"ephemeral\"\n\n\nclass TestSchemaTestStoreFailuresTrueHierarchicalParsing:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": store_failures_models_true__config_yml,\n            \"my_model.sql\": store_failures_models__my_model_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"tests\": {\"+store_failures\": False},\n        }\n\n    def test_parse_store_failures_True_as_table(self, project):\n        manifest = run_dbt([\"parse\"])\n        test_node = [\n            node for node in manifest.nodes.values() if \"not_null_my_model_id\" in node.fqn\n        ][0]\n\n        assert test_node.config.store_failures\n        assert test_node.config.store_failures_as == \"table\"\n\n\nclass TestSchemaTestStoreFailuresFalseHierarchicalParsing:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": store_failures_models_false__config_yml,\n            \"my_model.sql\": store_failures_models__my_model_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"tests\": {\"+store_failures\": True},\n        }\n\n    def test_parse_store_failures_False_as_ephemeral(self, project):\n        manifest = run_dbt([\"parse\"])\n        test_node = [\n            node for node in manifest.nodes.values() if \"not_null_my_model_id\" in node.fqn\n        ][0]\n\n        assert not test_node.config.store_failures\n        assert test_node.config.store_failures_as == \"ephemeral\"\n"
  },
  {
    "path": "tests/functional/schema_tests/test_sql_header_config.py",
    "content": "import re\n\nimport pytest\n\nfrom dbt.contracts.graph.nodes import TestNode\nfrom dbt.events.types import CustomKeyInConfigDeprecation\nfrom dbt.tests.util import get_manifest, run_dbt\nfrom dbt_common.events.event_catcher import EventCatcher\n\nSQL_HEADER_MARKER = \"-- SQL_HEADER_TEST_MARKER\"\n\nseed_csv = \"\"\"\nid,value\n1,10\n2,20\n3,30\n\"\"\".strip()\n\ntable_sql = \"\"\"\nselect * from {{ ref('seed') }}\n\"\"\"\n\n# Singular data test using set_sql_header macro\nsingular_test_with_sql_header = \"\"\"\n{{ config(store_failures_as=\"ephemeral\") }}\n\n{% call set_sql_header(config) %}\n  -- SQL_HEADER_TEST_MARKER\n{% endcall %}\n\nselect id from {{ ref('table') }} where id > 100\n\"\"\"\n\n# Schema YAML with generic test using sql_header config\ngeneric_test_with_sql_header_yml = \"\"\"\nmodels:\n  - name: table\n    columns:\n      - name: id\n        data_tests:\n          - not_null:\n              name: generic_test_with_sql_header\n              config:\n                sql_header: \"-- SQL_HEADER_TEST_MARKER\"\n\"\"\"\n\n\nclass TestSingularDataTestSqlHeader:\n    \"\"\"Test that singular data tests properly parse and store sql_header from set_sql_header macro.\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\"flags\": {\"require_sql_header_in_test_configs\": True}}\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\"seed.csv\": seed_csv}\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"table.sql\": table_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def tests(self):\n        return {\"singular_test_with_sql_header.sql\": singular_test_with_sql_header}\n\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project):\n        run_dbt([\"seed\"])\n\n    def test_singular_test_sql_header_in_config(self, project):\n        run_dbt([\"run\"])\n        run_dbt([\"test\"])\n\n        manifest = get_manifest(project.project_root)\n        pattern = re.compile(r\"test\\.test\\.singular_test_with_sql_header\")\n        test_node = None\n        for node_id, node in manifest.nodes.items():\n            if pattern.search(node_id) and isinstance(node, TestNode):\n                test_node = node\n                break\n\n        assert test_node is not None, \"Singular test node not found in manifest\"\n        sql_header = test_node.config.get(\"sql_header\")\n        assert sql_header is not None, \"sql_header not found in singular test config\"\n        assert SQL_HEADER_MARKER in sql_header\n\n\nclass TestGenericDataTestSqlHeader:\n    \"\"\"Test that generic data tests properly parse and store sql_header from YAML config.\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\"flags\": {\"require_sql_header_in_test_configs\": True}}\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\"seed.csv\": seed_csv}\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"table.sql\": table_sql,\n            \"schema.yml\": generic_test_with_sql_header_yml,\n        }\n\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project):\n        run_dbt([\"seed\"])\n\n    def test_generic_test_sql_header_in_config(self, project):\n        run_dbt([\"run\"])\n        run_dbt([\"test\"])\n\n        manifest = get_manifest(project.project_root)\n        pattern = re.compile(r\"test\\.test\\.generic_test_with_sql_header\")\n        test_node = None\n        for node_id, node in manifest.nodes.items():\n            if pattern.search(node_id) and isinstance(node, TestNode):\n                test_node = node\n                break\n\n        assert test_node is not None, \"Generic test node not found in manifest\"\n        assert test_node.config.sql_header == SQL_HEADER_MARKER\n\n\nclass TestGenericDataTestSqlHeaderDeprecation:\n    \"\"\"Test that sql_header in test config emits deprecation warning when flag is off.\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\"seed.csv\": seed_csv}\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"table.sql\": table_sql,\n            \"schema.yml\": generic_test_with_sql_header_yml,\n        }\n\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project):\n        run_dbt([\"seed\"])\n\n    def test_sql_header_deprecation_warning(self, project):\n        event_catcher = EventCatcher(CustomKeyInConfigDeprecation)\n        run_dbt(\n            [\"parse\", \"--no-partial-parse\", \"--show-all-deprecations\"],\n            callbacks=[event_catcher.catch],\n        )\n        assert len(event_catcher.caught_events) == 1\n        assert (\n            \"Custom key `sql_header` found in `config`\" in event_catcher.caught_events[0].info.msg\n        )\n\n        # Verify sql_header is preserved in the manifest\n        manifest = get_manifest(project.project_root)\n        pattern = re.compile(r\"test\\.test\\.generic_test_with_sql_header\")\n        test_node = None\n        for node_id, node in manifest.nodes.items():\n            if pattern.search(node_id) and isinstance(node, TestNode):\n                test_node = node\n                break\n\n        assert test_node is not None, \"Generic test node not found in manifest\"\n        assert test_node.config.sql_header == SQL_HEADER_MARKER\n"
  },
  {
    "path": "tests/functional/seeds/test_seed_column_type_validation.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt, run_dbt_and_capture\n\nseeds__my_seed_csv = \"\"\"id,name,value\n1,john,100\n2,jane,200\n3,bob,300\n\"\"\"\n\nmy_seed_yml = \"\"\"\nversion: 2\nseeds:\n  - name: my_seed\n    config:\n      column_types:\n        id: integer\n        name: text\n        value: float\n        # This column doesn't exist in the CSV\n        non_existent_column: integer\n\"\"\"\n\nseeds__other_seed_csv = \"\"\"id,name\n1,john\n2,jane\n\"\"\"\n\nother_seed_yml = \"\"\"\nversion: 2\nseeds:\n  - name: other_seed\n    config:\n      column_types:\n        id: integer\n        name: text\n\"\"\"\n\nseeds__mismatched_columns_csv = \"\"\"col_a,col_b,col_c\n1,2,3\n4,5,6\n\"\"\"\n\nmismatched_columns_yml = \"\"\"\nversion: 2\nseeds:\n  - name: mismatched_columns\n    config:\n      column_types:\n        col_a: integer\n        col_b: text\n        col_d: integer  # This doesn't exist\n\"\"\"\n\n\nclass TestSeedColumnTypeValidation:\n    \"\"\"Test that column type validation works for seeds.\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_seed.yml\": my_seed_yml,\n            \"other_seed.yml\": other_seed_yml,\n            \"mismatched_columns.yml\": mismatched_columns_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\n            \"my_seed.csv\": seeds__my_seed_csv,\n            \"other_seed.csv\": seeds__other_seed_csv,\n            \"mismatched_columns.csv\": seeds__mismatched_columns_csv,\n        }\n\n    def test_seed_with_invalid_column_type(self, project):\n        results = run_dbt([\"seed\"])\n        my_seed_result = next((r for r in results if r.node.name == \"my_seed\"), None)\n        assert my_seed_result is not None\n        assert my_seed_result.agate_table is not None\n\n        column_names = [col.name for col in my_seed_result.agate_table.columns]\n        assert \"id\" in column_names\n        assert \"name\" in column_names\n        assert \"value\" in column_names\n        # non_existent_column should not be in the table\n        assert \"non_existent_column\" not in column_names\n        rows = list(my_seed_result.agate_table.rows)\n        assert len(rows) == 3\n        assert int(rows[0][\"id\"]) == 1\n        assert rows[0][\"name\"] == \"john\"\n        assert int(rows[0][\"value\"]) == 100\n\n\nclass TestSeedColumnTypesBasic:\n    \"\"\"Test basic seed column types functionality.\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"other_seed.yml\": other_seed_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\n            \"other_seed.csv\": seeds__other_seed_csv,\n        }\n\n    def test_seed_basic_column_types(self, project):\n        results = run_dbt([\"seed\"])\n        assert len(results) == 1\n        other_seed_result = next((r for r in results if r.node.name == \"other_seed\"), None)\n        assert other_seed_result is not None\n\n        assert other_seed_result.agate_table is not None\n\n        column_names = [col.name for col in other_seed_result.agate_table.columns]\n        assert \"id\" in column_names\n        assert \"name\" in column_names\n\n\nclass TestSeedColumnTypesWithMismatchedColumns:\n    \"\"\"Test seed with column types for columns that don't exist in CSV.\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"mismatched_columns.yml\": mismatched_columns_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\n            \"mismatched_columns.csv\": seeds__mismatched_columns_csv,\n        }\n\n    def test_seed_invalid_column_type_warning(self, project):\n        results, log_output = run_dbt_and_capture([\"seed\"])\n        assert len(results) == 1\n\n        result = next((r for r in results if r.node.name == \"mismatched_columns\"), None)\n        assert result is not None\n        assert result.agate_table is not None\n\n        column_names = [col.name for col in result.agate_table.columns]\n        assert \"col_a\" in column_names\n        assert \"col_b\" in column_names\n        assert \"col_c\" in column_names\n        assert \"col_d\" not in column_names\n\n        rows = list(result.agate_table.rows)\n        assert len(rows) == 2\n        assert int(rows[0][\"col_a\"]) == 1\n        assert rows[0][\"col_b\"] == \"2\"\n        assert int(rows[0][\"col_c\"]) == 3\n        expected_msg_part = (\n            \"Column types specified for non-existent columns in seed 'mismatched_columns'\"\n        )\n\n        assert expected_msg_part in log_output\n        assert \"col_d\" in log_output\n"
  },
  {
    "path": "tests/functional/selected_resources/fixtures.py",
    "content": "on_run_start_macro_assert_selected_models_expected_list = \"\"\"\n{% macro assert_selected_models_expected_list(expected_list) %}\n\n  {% if execute and (expected_list is not none) %}\n\n    {% set sorted_selected_resources = selected_resources | sort %}\n    {% set sorted_expected_list = expected_list | sort %}\n\n    {% if sorted_selected_resources != sorted_expected_list %}\n      {{ exceptions.raise_compiler_error(\"FAIL: sorted_selected_resources\" ~ sorted_selected_resources ~ \" is different from \" ~ sorted_expected_list) }}\n    {% endif %}\n\n  {% endif %}\n\n{% endmacro %}\n\"\"\"\n\n\nmy_model1 = \"\"\"\nselect 1 as id\n\"\"\"\n\nmy_model2 = \"\"\"\nselect * from {{ ref('model1') }}\n\"\"\"\n\nmy_snapshot = \"\"\"\n{% snapshot cc_all_snapshot %}\n    {{ config(\n        check_cols='all', unique_key='id', strategy='check',\n        target_database=database, target_schema=schema\n    ) }}\n    select * from {{ ref('model2') }}\n{% endsnapshot %}\n\"\"\"\n"
  },
  {
    "path": "tests/functional/selected_resources/test_selected_resources.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt\nfrom tests.functional.selected_resources.fixtures import (\n    my_model1,\n    my_model2,\n    my_snapshot,\n    on_run_start_macro_assert_selected_models_expected_list,\n)\n\n\n@pytest.fixture(scope=\"class\")\ndef macros():\n    return {\n        \"assert_selected_models_expected_list.sql\": on_run_start_macro_assert_selected_models_expected_list,\n    }\n\n\n@pytest.fixture(scope=\"class\")\ndef models():\n    return {\"model1.sql\": my_model1, \"model2.sql\": my_model2}\n\n\n@pytest.fixture(scope=\"class\")\ndef snapshots():\n    return {\n        \"my_snapshot.sql\": my_snapshot,\n    }\n\n\n@pytest.fixture(scope=\"class\")\ndef project_config_update():\n    return {\n        \"on-run-start\": \"{{ assert_selected_models_expected_list(var('expected_list',None)) }}\",\n    }\n\n\n@pytest.fixture\ndef build_all(project):\n    run_dbt([\"build\"])\n\n\n@pytest.mark.usefixtures(\"build_all\")\nclass TestSelectedResources:\n    def test_selected_resources_build_selector(self, project):\n        results = run_dbt(\n            [\n                \"build\",\n                \"--select\",\n                \"model1+\",\n                \"--vars\",\n                '{\"expected_list\": [\"model.test.model1\", \"model.test.model2\", \"snapshot.test.cc_all_snapshot\"]}',\n            ]\n        )\n        assert results[0].status == \"success\"\n\n    def test_selected_resources_build_selector_subgraph(self, project):\n        results = run_dbt(\n            [\n                \"build\",\n                \"--select\",\n                \"model2+\",\n                \"--vars\",\n                '{\"expected_list\": [\"model.test.model2\", \"snapshot.test.cc_all_snapshot\"]}',\n            ]\n        )\n        assert results[0].status == \"success\"\n\n    def test_selected_resources_run(self, project):\n        results = run_dbt(\n            [\n                \"run\",\n                \"--select\",\n                \"model1+\",\n                \"--vars\",\n                '{\"expected_list\": [\"model.test.model2\", \"model.test.model1\"]}',\n            ]\n        )\n        assert results[0].status == \"success\"\n\n    def test_selected_resources_build_no_selector(self, project):\n        results = run_dbt(\n            [\n                \"build\",\n                \"--vars\",\n                '{\"expected_list\": [\"model.test.model1\", \"model.test.model2\", \"snapshot.test.cc_all_snapshot\"]}',\n            ]\n        )\n        assert results[0].status == \"success\"\n\n    def test_selected_resources_build_no_model(self, project):\n        results = run_dbt(\n            [\n                \"build\",\n                \"--select\",\n                \"model_that_does_not_exist\",\n                \"--vars\",\n                '{\"expected_list\": []}',\n            ]\n        )\n        assert not results\n\n    def test_selected_resources_test_no_model(self, project):\n        results = run_dbt([\"test\", \"--select\", \"model1+\", \"--vars\", '{\"expected_list\": []}'])\n        assert not results\n"
  },
  {
    "path": "tests/functional/selectors/test_default_selectors.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt\n\nmodels__schema_yml = \"\"\"\nversion: 2\n\nsources:\n  - name: src\n    schema: \"{{ target.schema }}\"\n    freshness:\n      warn_after: {count: 24, period: hour}\n    loaded_at_field: _loaded_at\n    tables:\n      - name: source_a\n        identifier: model_c\n        columns:\n          - name: fun\n          - name: _loaded_at\n  - name: src\n    schema: \"{{ target.schema }}\"\n    freshness:\n      warn_after: {count: 24, period: hour}\n    loaded_at_field: _loaded_at\n    tables:\n      - name: source_b\n        identifier: model_c\n        columns:\n          - name: fun\n          - name: _loaded_at\n\nmodels:\n  - name: model_a\n    columns:\n      - name: fun\n        tags: [marketing]\n  - name: model_b\n    columns:\n      - name: fun\n        tags: [finance]\n\"\"\"\n\nmodels__model_a_sql = \"\"\"\nSELECT 1 AS fun\n\"\"\"\n\nmodels__model_b_sql = \"\"\"\nSELECT 1 AS fun\n\"\"\"\n\nseeds__model_c_csv = \"\"\"fun,_loaded_at\n1,2021-04-19 01:00:00\"\"\"\n\n\n@pytest.fixture(scope=\"class\")\ndef models():\n    return {\n        \"schema.yml\": models__schema_yml,\n        \"model_b.sql\": models__model_b_sql,\n        \"model_a.sql\": models__model_a_sql,\n    }\n\n\n@pytest.fixture(scope=\"class\")\ndef seeds():\n    return {\"model_c.csv\": seeds__model_c_csv}\n\n\n@pytest.fixture(scope=\"class\")\ndef selectors():\n    return \"\"\"\n            selectors:\n            - name: default_selector\n              description: test default selector\n              definition:\n                union:\n                  - method: source\n                    value: \"test.src.source_a\"\n                  - method: fqn\n                    value: \"model_a\"\n              default: true\n        \"\"\"\n\n\nclass TestDefaultSelectors:\n    def test_model__list(self, project):\n        result = run_dbt([\"ls\", \"--resource-type\", \"model\"])\n        assert \"test.model_a\" in result\n\n    def test_model__compile(self, project):\n        result = run_dbt([\"compile\"])\n        assert len(result) == 1\n        assert result.results[0].node.name == \"model_a\"\n\n    def test_source__freshness(self, project):\n        run_dbt([\"seed\", \"-s\", \"test.model_c\"])\n        result = run_dbt([\"source\", \"freshness\"])\n        assert len(result) == 1\n        assert result.results[0].node.name == \"source_a\"\n"
  },
  {
    "path": "tests/functional/selectors/test_selector_selector_method.py",
    "content": "from typing import Any\n\nimport pytest\n\nfrom dbt.events.types import SelectExcludeIgnoredWithSelectorWarning\nfrom dbt.exceptions import DbtSelectorsError\nfrom dbt.tests.util import run_dbt\nfrom dbt_common.events.event_catcher import EventCatcher\nfrom dbt_common.exceptions import RecursionError as DbtRecursionError\n\nmodels__model_a_sql = \"\"\"\nSELECT 1 AS id\n\"\"\"\n\nmodels_model_b_sql = \"\"\"\nSELECT 1 AS id\n\"\"\"\n\nmodels_model_a_plus_1_sql = \"\"\"\nSELECT * FROM {{ ref('model_a') }}\n\"\"\"\n\nmodels_model_a_plus_2_sql = \"\"\"\nSELECT * FROM {{ ref('model_a_plus_1') }}\n\"\"\"\n\nmodels_model_c_sql = \"\"\"\n{{ config(tags=['tag_c']) }}\n\nSELECT * FROM {{ ref('model_a') }}\nUNION ALL\nSELECT * FROM {{ ref('model_b') }}\n\"\"\"\n\n\nselectors__yml = \"\"\"\nselectors:\n  - name: model_a_selector\n    description: Selects model_a\n    definition:\n      method: fqn\n      value: model_a\n\n  - name: model_b_selector\n    description: Selects model_b\n    definition:\n      method: fqn\n      value: model_b\n\n  - name: model_c_selector\n    description: Selects model_c\n    definition:\n      method: fqn\n      value: model_c\n\n  - name: model_a_b_selector\n    description: Selects model_a and model_b\n    definition:\n      union:\n        - method: fqn\n          value: model_a\n        - method: fqn\n          value: model_b\n\n  - name: model_a_plus_1_selector\n    description: Selects model_a_plus_1\n    definition:\n      method: fqn\n      value: model_a_plus_1\n\n  - name: model_a_plus_2_selector\n    description: Selects model_a_plus_2\n    definition:\n      method: fqn\n      value: model_a_plus_2\n      parents: true\n      parents_depth: 2\n\n  - name: recursive_selector\n    description: Selects recursive models\n    definition:\n      union:\n        - model_b\n        - selector:model_a_plus_2_selector\n\n  - name: recursive_with_wildcards\n    description: Selects recursive models with wildcards\n    definition:\n      union:\n        - model_c\n        - selector:model_[ab]_selector\n\n  - name: circular_selection_hop\n    description: Selects circular selection hop models\n    definition:\n      union:\n        - selector:circular_dependency_selector\n\n  - name: circular_dependency_selector\n    description: Selects circular dependency models\n    definition:\n      union:\n        - selector:circular_selection_hop\n\n  - name: model_a_explicit_selector\n    description: Selects model_a with an explicit selector method\n    definition:\n      method: selector\n      value: model_a_selector\n\"\"\"\n\n\n@pytest.fixture(scope=\"class\")\ndef models():\n    return {\n        \"model_a.sql\": models__model_a_sql,\n        \"model_a_plus_1.sql\": models_model_a_plus_1_sql,\n        \"model_a_plus_2.sql\": models_model_a_plus_2_sql,\n        \"model_b.sql\": models_model_b_sql,\n        \"model_c.sql\": models_model_c_sql,\n    }\n\n\n@pytest.fixture(scope=\"class\")\ndef selectors():\n    return selectors__yml\n\n\ndef assert_result_set(actual: Any, expected: set[str]):\n    assert isinstance(actual, list)\n    assert set(actual) == expected\n\n\nclass TestSelectorSelectorMethod:\n    def test_ls_with_selector_returns_model_a(self, project):\n        result = run_dbt([\"ls\", \"--select\", \"selector:model_a_selector\"])\n        assert_result_set(result, {\"test.model_a\"})\n\n    def test_ls_with_selector_union(self, project):\n        result = run_dbt([\"ls\", \"--select\", \"selector:model_a_selector selector:model_b_selector\"])\n        assert_result_set(result, {\"test.model_a\", \"test.model_b\"})\n\n    def test_ls_with_selector_intersection(self, project):\n        result = run_dbt(\n            [\"ls\", \"--select\", \"selector:model_a_b_selector,selector:model_b_selector\"]\n        )\n        assert_result_set(result, {\"test.model_b\"})\n\n    def test_ls_with_graph_operator(self, project):\n        # one child one parent\n        result = run_dbt([\"ls\", \"--select\", \"1+selector:model_a_plus_1_selector+1\"])\n        assert_result_set(\n            result,\n            {\n                \"test.model_a\",\n                \"test.model_a_plus_1\",\n                \"test.model_a_plus_2\",\n            },\n        )\n\n        # two parents\n        result = run_dbt([\"ls\", \"--select\", \"1+selector:model_c_selector\"])\n        assert_result_set(result, {\"test.model_a\", \"test.model_b\", \"test.model_c\"})\n\n    def test_selector_depth_overrides_operator_depth(self, project):\n        result = run_dbt([\"ls\", \"--select\", \"selector:model_a_plus_2_selector\"])\n        assert_result_set(\n            result,\n            {\n                \"test.model_a\",\n                \"test.model_a_plus_1\",\n                \"test.model_a_plus_2\",\n            },\n        )\n\n        result = run_dbt([\"ls\", \"--select\", \"1+selector:model_a_plus_2_selector\"])\n        assert_result_set(result, {\"test.model_a\", \"test.model_a_plus_1\", \"test.model_a_plus_2\"})\n\n    def test_combine_with_other_methods(self, project):\n        result = run_dbt([\"ls\", \"--select\", \"selector:model_a_selector tag:tag_c\"])\n        assert_result_set(result, {\"test.model_a\", \"test.model_c\"})\n\n        result = run_dbt([\"ls\", \"--select\", \"selector:model_a_plus_2_selector model_a model_b\"])\n        assert_result_set(\n            result,\n            {\n                \"test.model_a\",\n                \"test.model_b\",\n                \"test.model_a_plus_1\",\n                \"test.model_a_plus_2\",\n            },\n        )\n\n    def test_recursive_selector(self, project):\n        result = run_dbt([\"ls\", \"--select\", \"selector:recursive_selector\"])\n        assert_result_set(\n            result,\n            {\n                \"test.model_a\",\n                \"test.model_b\",\n                \"test.model_a_plus_1\",\n                \"test.model_a_plus_2\",\n            },\n        )\n\n    def test_select_and_exclude(self, project):\n        result = run_dbt(\n            [\n                \"ls\",\n                \"--select\",\n                \"1+selector:model_a_plus_1_selector\",\n                \"--exclude\",\n                \"selector:model_a_selector\",\n            ]\n        )\n        assert_result_set(result, {\"test.model_a_plus_1\"})\n\n    def test_wildcards(self, project):\n        result = run_dbt([\"ls\", \"--select\", \"selector:model_?_selector\"])\n        assert_result_set(result, {\"test.model_a\", \"test.model_b\", \"test.model_c\"})\n\n        result = run_dbt([\"ls\", \"--select\", \"selector:*_c_*\"])\n        assert_result_set(result, {\"test.model_c\"})\n\n        result = run_dbt([\"ls\", \"--select\", \"selector:model_[ab]_selector\"])\n        assert_result_set(result, {\"test.model_a\", \"test.model_b\"})\n\n        result = run_dbt([\"ls\", \"--select\", \"selector:model_[a-c]_selector\"])\n        assert_result_set(result, {\"test.model_a\", \"test.model_b\", \"test.model_c\"})\n\n    def test_recursive_with_wildcards(self, project):\n        result = run_dbt([\"ls\", \"--select\", \"selector:recursive_with_wildcards\"])\n        assert_result_set(result, {\"test.model_a\", \"test.model_b\", \"test.model_c\"})\n\n    def test_circular_dependency(self, project):\n        with pytest.raises(DbtRecursionError):\n            run_dbt([\"ls\", \"--select\", \"selector:circular_dependency_selector\"], expect_pass=False)\n\n    def test_selector_with_explicit_selector_method(self, project):\n        result = run_dbt([\"ls\", \"--select\", \"selector:model_a_explicit_selector\"])\n        assert_result_set(result, {\"test.model_a\"})\n\n    def test_raises_if_no_selector_matches(self, project):\n        with pytest.raises(DbtSelectorsError):\n            run_dbt([\"ls\", \"--select\", \"selector:nonexistent_selector\"])\n\n\nclass TestSelectExcludeIgnoredWithSelectorWarning:\n    \"\"\"Test that SelectExcludeIgnoredWithSelectorWarning is raised when CLI is invoked with\n    --selector together with --select or --exclude.\n    \"\"\"\n\n    def test_warning_raised_when_selector_and_select(self, project):\n        event_catcher = EventCatcher(SelectExcludeIgnoredWithSelectorWarning)\n        run_dbt(\n            [\"ls\", \"--selector\", \"model_a_selector\", \"--select\", \"model_a\"],\n            callbacks=[event_catcher.catch],\n        )\n        assert len(event_catcher.caught_events) == 1\n\n    def test_warning_raised_when_selector_and_exclude(self, project):\n        event_catcher = EventCatcher(SelectExcludeIgnoredWithSelectorWarning)\n        run_dbt(\n            [\"ls\", \"--selector\", \"model_a_selector\", \"--exclude\", \"model_b\"],\n            callbacks=[event_catcher.catch],\n        )\n        assert len(event_catcher.caught_events) == 1\n\n    def test_no_warning_when_selector_only(self, project):\n        event_catcher = EventCatcher(SelectExcludeIgnoredWithSelectorWarning)\n        run_dbt(\n            [\"ls\", \"--selector\", \"model_a_selector\"],\n            callbacks=[event_catcher.catch],\n        )\n        assert len(event_catcher.caught_events) == 0\n\n    def test_warning_raised_when_selector_and_select_and_exclude(self, project):\n        event_catcher = EventCatcher(SelectExcludeIgnoredWithSelectorWarning)\n        run_dbt(\n            [\n                \"ls\",\n                \"--selector\",\n                \"model_a_selector\",\n                \"--select\",\n                \"model_a\",\n                \"--exclude\",\n                \"model_b\",\n            ],\n            callbacks=[event_catcher.catch],\n        )\n        assert len(event_catcher.caught_events) == 1\n\n    def test_no_warning_when_no_selector(self, project):\n        event_catcher = EventCatcher(SelectExcludeIgnoredWithSelectorWarning)\n        run_dbt(\n            [\"ls\", \"--select\", \"model_a\", \"--exclude\", \"model_b\"],\n            callbacks=[event_catcher.catch],\n        )\n        assert len(event_catcher.caught_events) == 0\n"
  },
  {
    "path": "tests/functional/semantic_models/fixtures.py",
    "content": "import textwrap\n\nsimple_metricflow_time_spine_sql = \"\"\"\nSELECT to_date('02/20/2023', 'mm/dd/yyyy') as date_day\n\"\"\"\n\nmodels_people_sql = \"\"\"\nselect 1 as id, 'Drew' as first_name, 'Banin' as last_name, 'yellow' as favorite_color, true as loves_dbt, 5 as tenure, current_timestamp as created_at\nunion all\nselect 2 as id, 'Jeremy' as first_name, 'Cohen' as last_name, 'indigo' as favorite_color, true as loves_dbt, 4 as tenure, current_timestamp as created_at\nunion all\nselect 3 as id, 'Callum' as first_name, 'McCann' as last_name, 'emerald' as favorite_color, true as loves_dbt, 0 as tenure, current_timestamp as created_at\n\"\"\"\n\ngroups_yml = \"\"\"\nversion: 2\n\ngroups:\n  - name: some_group\n    owner:\n      email: me@gmail.com\n  - name: some_other_group\n    owner:\n      email: me@gmail.com\n\"\"\"\n\nmodels_people_metrics_yml = \"\"\"\nversion: 2\n\nmetrics:\n  - name: number_of_people\n    label: \"Number of people\"\n    description: Total count of people\n    type: simple\n    type_params:\n      measure: people\n    meta:\n        my_meta: 'testing'\n\"\"\"\n\ndisabled_models_people_metrics_yml = \"\"\"\nversion: 2\n\nmetrics:\n  - name: number_of_people\n    config:\n      enabled: false\n      group: some_group\n    label: \"Number of people\"\n    description: Total count of people\n    type: simple\n    type_params:\n      measure: people\n    meta:\n        my_meta: 'testing'\n\"\"\"\n\nsemantic_model_people_yml = \"\"\"\nversion: 2\n\nsemantic_models:\n  - name: semantic_people\n    label: \"Semantic People\"\n    model: ref('people')\n    dimensions:\n      - name: favorite_color\n        label: \"Favorite Color\"\n        type: categorical\n      - name: created_at\n        label: \"Created At\"\n        type: TIME\n        type_params:\n          time_granularity: day\n    measures:\n      - name: years_tenure\n        label: \"Years Tenure\"\n        agg: SUM\n        expr: tenure\n      - name: people\n        label: \"People\"\n        agg: count\n        expr: id\n    entities:\n      - name: id\n        label: \"Primary ID\"\n        type: primary\n    defaults:\n      agg_time_dimension: created_at\n\"\"\"\n\nsemantic_model_people_diff_name_yml = \"\"\"\nversion: 2\n\nsemantic_models:\n  - name: semantic_people_diff_name\n    label: \"Semantic People\"\n    model: ref('people')\n    dimensions:\n      - name: favorite_color\n        label: \"Favorite Color\"\n        type: categorical\n      - name: created_at\n        label: \"Created At\"\n        type: TIME\n        type_params:\n          time_granularity: day\n    measures:\n      - name: years_tenure\n        label: \"Years Tenure\"\n        agg: SUM\n        expr: tenure\n      - name: people\n        label: \"People\"\n        agg: count\n        expr: id\n    entities:\n      - name: id\n        label: \"Primary ID\"\n        type: primary\n    defaults:\n      agg_time_dimension: created_at\n\"\"\"\n\nsemantic_model_descriptions = \"\"\"\n{% docs semantic_model_description %} foo {% enddocs %}\n{% docs dimension_description %} bar {% enddocs %}\n{% docs measure_description %} baz {% enddocs %}\n{% docs entity_description %} qux {% enddocs %}\n{% docs simple_metric_description %} describe away! {% enddocs %}\n\"\"\"\n\nsemantic_model_people_yml_with_docs = \"\"\"\nversion: 2\n\nsemantic_models:\n  - name: semantic_people\n    model: ref('people')\n    description: \"{{ doc('semantic_model_description') }}\"\n    dimensions:\n      - name: favorite_color\n        type: categorical\n        description: \"{{ doc('dimension_description') }}\"\n      - name: created_at\n        type: TIME\n        type_params:\n          time_granularity: day\n    measures:\n      - name: years_tenure\n        agg: SUM\n        expr: tenure\n        description: \"{{ doc('measure_description') }}\"\n      - name: people\n        agg: count\n        expr: id\n    entities:\n      - name: id\n        description: \"{{ doc('entity_description') }}\"\n        type: primary\n    defaults:\n      agg_time_dimension: created_at\n\"\"\"\n\nenabled_semantic_model_people_yml = \"\"\"\nversion: 2\n\nsemantic_models:\n  - name: semantic_people\n    label: \"Semantic People\"\n    model: ref('people')\n    config:\n      enabled: true\n      group: some_group\n      meta:\n        my_meta: 'testing'\n        my_other_meta: 'testing more'\n    dimensions:\n      - name: favorite_color\n        type: categorical\n      - name: created_at\n        type: TIME\n        type_params:\n          time_granularity: day\n    measures:\n      - name: years_tenure\n        agg: SUM\n        expr: tenure\n      - name: people\n        agg: count\n        expr: id\n    entities:\n      - name: id\n        type: primary\n    defaults:\n      agg_time_dimension: created_at\n\"\"\"\n\ndisabled_semantic_model_people_yml = \"\"\"\nversion: 2\n\nsemantic_models:\n  - name: semantic_people\n    label: \"Semantic People\"\n    model: ref('people')\n    config:\n      enabled: false\n    dimensions:\n      - name: favorite_color\n        type: categorical\n      - name: created_at\n        type: TIME\n        type_params:\n          time_granularity: day\n    measures:\n      - name: years_tenure\n        agg: SUM\n        expr: tenure\n      - name: people\n        agg: count\n        expr: id\n    entities:\n      - name: id\n        type: primary\n    defaults:\n      agg_time_dimension: created_at\n\"\"\"\n\n\nsemantic_model_with_disabled_ref_yml = \"\"\"\nversion: 2\n\nmodels:\n  - name: people\n    config:\n      enabled: false\n\nsemantic_models:\n  - name: semantic_people\n    label: \"Semantic People\"\n    model: ref('people')\n    dimensions:\n      - name: favorite_color\n        type: categorical\n      - name: created_at\n        type: TIME\n        type_params:\n          time_granularity: day\n    measures:\n      - name: people\n        label: \"People\"\n        agg: count\n        expr: id\n    entities:\n      - name: id\n        type: primary\n    defaults:\n      agg_time_dimension: created_at\n\"\"\"\n\n\nbase_schema_yml = \"\"\"models:\n  - name: fct_revenue\n    description: This is the model fct_revenue. It should be able to use doc blocks\n\nsemantic_models:\n  - name: revenue\n    description: This is the revenue semantic model. It should be able to use doc blocks\n    model: ref('fct_revenue')\n\n    defaults:\n      agg_time_dimension: ds\n\n    measures:\n      - name: txn_revenue\n        expr: revenue\n        agg: sum\n        agg_time_dimension: ds\n        create_metric: true\n      - name: txn_revenue_with_label\n        label: \"Transaction Revenue with label\"\n        expr: revenue\n        agg: sum\n        agg_time_dimension: ds\n        create_metric: true\n      - name: sum_of_things\n        expr: 2\n        agg: sum\n        agg_time_dimension: ds\n      - name: count_of_things\n        agg: count\n        expr: 1\n        agg_time_dimension: ds\n      - name: count_of_things_2\n        agg: count\n        expr: 1\n        agg_time_dimension: ds\n      - name: has_revenue\n        expr: true\n        agg: sum_boolean\n        agg_time_dimension: ds\n      - name: discrete_order_value_p99\n        expr: order_total\n        agg: percentile\n        agg_time_dimension: ds\n        agg_params:\n          percentile: 0.99\n          use_discrete_percentile: True\n          use_approximate_percentile: False\n      - name: test_agg_params_optional_are_empty\n        expr: order_total\n        agg: percentile\n        agg_time_dimension: ds\n        agg_params:\n          percentile: 0.99\n      - name: test_non_additive\n        expr: txn_revenue\n        agg: sum\n        non_additive_dimension:\n          name: ds\n          window_choice: max\n\n    dimensions:\n      - name: ds\n        type: time\n        expr: created_at\n        type_params:\n          time_granularity: day\n\n    entities:\n      - name: user\n        type: foreign\n        expr: user_id\n      - name: id\n        type: primary\n\nmetrics:\n  - name: simple_metric\n    label: Simple Metric\n    type: simple\n    type_params:\n      measure: sum_of_things\n  - name: test_cumulative_metric\n    label: Cumulative Metric\n    type: cumulative\n    type_params:\n      measure: sum_of_things\n      cumulative_type_params:\n        grain_to_date: day\n        period_agg: first\n\"\"\"\n\nconversion_metric_yml = \"\"\"\n  - name: test_conversion_metric\n    label: Conversion Metric\n    type: conversion\n    type_params:\n      conversion_type_params:\n        base_measure: count_of_things\n        conversion_measure: count_of_things_2\n        entity: user\n        calculation: conversion_rate\n\"\"\"\n\nratio_metric_yml = \"\"\"\n  - name: test_ratio_metric\n    label: Ratio Metric\n    type: ratio\n    type_params:\n      numerator: simple_metric\n      denominator: test_conversion_metric\n\"\"\"\n\nderived_metric_yml = \"\"\"\n  - name: test_derived_metric\n    label: Derived Metric\n    type: derived\n    type_params:\n      metrics:\n        - simple_metric\n        - test_conversion_metric\n      expr: simple_metric + 1\n\"\"\"\n\nschema_yml = base_schema_yml + conversion_metric_yml + ratio_metric_yml + derived_metric_yml\n\nschema_without_semantic_model_yml = \"\"\"models:\n  - name: fct_revenue\n    description: This is the model fct_revenue. It should be able to use doc blocks\n\"\"\"\n\nfct_revenue_sql = \"\"\"select\n  1 as id,\n  10 as user_id,\n  1000 as revenue,\n  current_timestamp as created_at\"\"\"\n\nmetricflow_time_spine_sql = \"\"\"\nwith days as (\n    {{dbt_utils.date_spine('day'\n    , \"to_date('01/01/2000','mm/dd/yyyy')\"\n    , \"to_date('01/01/2027','mm/dd/yyyy')\"\n    )\n    }}\n),\n\nfinal as (\n    select cast(date_day as date) as date_day\n    from days\n)\n\nselect *\nfrom final\n\"\"\"\n\nmulti_sm_schema_yml = \"\"\"\nmodels:\n  - name: fct_revenue\n    description: This is the model fct_revenue.\n\nsemantic_models:\n  - name: revenue\n    description: This is the first semantic model.\n    model: ref('fct_revenue')\n\n    defaults:\n      agg_time_dimension: ds\n\n    measures:\n      - name: txn_revenue\n        expr: revenue\n        agg: sum\n        agg_time_dimension: ds\n        create_metric: true\n      - name: sum_of_things\n        expr: 2\n        agg: sum\n        agg_time_dimension: ds\n\n    dimensions:\n      - name: ds\n        type: time\n        expr: created_at\n        type_params:\n          time_granularity: day\n\n    entities:\n      - name: user\n        type: foreign\n        expr: user_id\n      - name: id\n        type: primary\n\n  - name: alt_revenue\n    description: This is the second revenue semantic model.\n    model: ref('fct_revenue')\n\n    defaults:\n      agg_time_dimension: ads\n\n    measures:\n      - name: alt_txn_revenue\n        expr: revenue\n        agg: sum\n        agg_time_dimension: ads\n        create_metric: true\n      - name: alt_sum_of_things\n        expr: 2\n        agg: sum\n        agg_time_dimension: ads\n\n    dimensions:\n      - name: ads\n        type: time\n        expr: created_at\n        type_params:\n          time_granularity: day\n\n    entities:\n      - name: user\n        type: foreign\n        expr: user_id\n      - name: id\n        type: primary\n\nmetrics:\n  - name: simple_metric\n    label: Simple Metric\n    type: simple\n    type_params:\n      measure: sum_of_things\n\"\"\"\n\nsemantic_model_dimensions_entities_measures_meta_config = \"\"\"\nversion: 2\n\nsemantic_models:\n  - name: semantic_people\n    label: \"Semantic People\"\n    model: ref('people')\n    dimensions:\n      - name: favorite_color\n        label: \"Favorite Color\"\n        type: categorical\n        config:\n          meta:\n            dimension: one\n      - name: created_at\n        label: \"Created At\"\n        type: TIME\n        type_params:\n          time_granularity: day\n    measures:\n      - name: years_tenure\n        label: \"Years Tenure\"\n        agg: SUM\n        expr: tenure\n        config:\n          meta:\n            measure: two\n      - name: people\n        label: \"People\"\n        agg: count\n        expr: id\n    entities:\n      - name: id\n        label: \"Primary ID\"\n        type: primary\n        config:\n          meta:\n            entity: three\n    defaults:\n      agg_time_dimension: created_at\n\"\"\"\n\nsemantic_model_meta_clobbering_yml = \"\"\"\nversion: 2\n\nsemantic_models:\n  - name: semantic_people\n    label: \"Semantic People\"\n    model: ref('people')\n    config:\n      meta:\n        model_level: \"should_be_inherited\"\n        component_level: \"should_be_overridden\"\n    dimensions:\n      - name: favorite_color\n        label: \"Favorite Color\"\n        type: categorical\n        config:\n          meta:\n            component_level: \"dimension_override\"\n      - name: created_at\n        label: \"Created At\"\n        type: TIME\n        type_params:\n          time_granularity: day\n    measures:\n      - name: years_tenure\n        label: \"Years Tenure\"\n        agg: SUM\n        expr: tenure\n        config:\n          meta:\n            component_level: \"measure_override\"\n      - name: people\n        label: \"People\"\n        agg: count\n        expr: id\n    entities:\n      - name: id\n        label: \"Primary ID\"\n        type: primary\n        config:\n          meta:\n            component_level: \"entity_override\"\n    defaults:\n      agg_time_dimension: created_at\n\"\"\"\n\n\nsemantic_model_schema_yml_v2_template_for_model_configs = \"\"\"models:\n  - name: fct_revenue\n    description: This is the model fct_revenue. It should be able to use doc blocks\n    {semantic_model_value}\n    columns:\n      - name: id\n        description: This is the id column dim.\n        config:\n          meta:\n          component_level: \"original_meta\"\n        dimension:\n          name: id_dim\n          label: \"ID Dimension\"\n          type: categorical\n          is_partition: true\n          config:\n            meta:\n              component_level: \"dimension_override\"\n        entity:\n          name: id_entity\n          description: This is the id entity, and it is the primary entity.\n          label: ID Entity\n          type: primary\n          config:\n            meta:\n              component_level: \"entity_override\"\n      - name: second_col\n        description: This is the second column.\n        granularity: day\n        dimension:\n          name: second_dim\n          description: This is the second column (dim).\n          label: Second Dimension\n          type: time\n          validity_params:\n            is_start: true\n            is_end: true\n      - name: foreign_id_col\n        description: This is a foreign id column.\n        entity: foreign\n      - name: col_with_default_dimensions\n        description: This is the column with default dimension settings.\n        dimension: categorical\n        entity:\n          name: col_with_default_entity_testing_default_desc\n          type: natural\n\"\"\"\n\n# You can replace the semantic_model variable in the template like this:\nsemantic_model_schema_yml_v2 = semantic_model_schema_yml_v2_template_for_model_configs.format(\n    semantic_model_value=\"semantic_model: true\",\n)\n\nsemantic_model_schema_yml_v2_disabled = (\n    semantic_model_schema_yml_v2_template_for_model_configs.format(\n        semantic_model_value=\"semantic_model: false\",\n    )\n)\n\nsemantic_model_test_groups_yml = \"\"\"groups:\n  - name: finance\n    owner:\n      # 'name' or 'email' is required; additional properties will no longer be allowed in a future release\n      email: finance@jaffleshop.com\n    config:\n      meta: # optional\n        data_owner: Finance team\n\"\"\"\n\nsemantic_model_schema_yml_v2_renamed = semantic_model_schema_yml_v2_template_for_model_configs.format(\n    semantic_model_value=\"\"\"semantic_model:\n      name: renamed_semantic_model\n      enabled: true\n      group: finance\n      config:\n        meta:\n          meta_tag_1: this_meta\n    \"\"\",\n)\n\nsemantic_model_schema_yml_v2_default_values = semantic_model_schema_yml_v2_template_for_model_configs.format(\n    semantic_model_value=\"\"\"semantic_model:\n      enabled: true\n    \"\"\"\n)\n\nsemantic_model_schema_yml_v2_disabled = semantic_model_schema_yml_v2_template_for_model_configs.format(\n    semantic_model_value=\"\"\"semantic_model:\n      enabled: false\n    \"\"\",\n)\n\nsemantic_model_schema_yml_v2_false_config = (\n    semantic_model_schema_yml_v2_template_for_model_configs.format(\n        semantic_model_value=\"semantic_model: false\",\n    )\n)\n\nsemantic_model_config_does_not_exist = (\n    semantic_model_schema_yml_v2_template_for_model_configs.format(\n        semantic_model_value=\"\",\n    )\n)\n\nsemantic_model_schema_yml_v2_template_for_primary_entity_tests = \"\"\"models:\n  - name: fct_revenue\n    description: This is the model fct_revenue. It should be able to use doc blocks\n    semantic_model: true\n    {primary_entity_setting}\n    columns:\n      - name: id\n        description: This is the id column dim.\n        config:\n          meta:\n          component_level: \"original_meta\"\n        dimension:\n          type: categorical\n        entity:\n          name: id_entity\n          description: This is the id entity, and it is the primary entity.\n          label: ID Entity\n          type: {id_entity_type}\n      - name: second_col\n        description: This is the second column.\n        granularity: day\n        dimension:\n          name: second_dim\n          description: This is the second column (dim).\n          label: Second Dimension\n          type: time\n          validity_params:\n            is_start: true\n            is_end: true\n      - name: other_id_col\n        description: This is the other id column.\n        entity:\n          name: other_id_entity\n          type: {other_id_entity_type}\n      - name: col_with_default_dimensions\n        description: This is the column with default dimension settings.\n        dimension: categorical\n        entity:\n          name: col_with_default_entity_testing_default_desc\n          type: natural\n\"\"\"\n\nsemantic_model_schema_yml_v2_with_primary_entity_only_on_column = (\n    semantic_model_schema_yml_v2_template_for_primary_entity_tests.format(\n        primary_entity_setting=\"\",\n        id_entity_type=\"primary\",\n        other_id_entity_type=\"foreign\",\n    )\n)\n\nsemantic_model_schema_yml_v2_primary_entity_only_on_model = (\n    semantic_model_schema_yml_v2_template_for_primary_entity_tests.format(\n        primary_entity_setting=\"primary_entity: id_entity\",\n        id_entity_type=\"foreign\",\n        other_id_entity_type=\"foreign\",\n    )\n)\n\nsemantic_model_schema_yml_v2 = \"\"\"models:\n  - name: fct_revenue\n    description: This is the model fct_revenue. It should be able to use doc blocks\n    semantic_model: true\n    columns:\n      - name: id\n        description: This is the id column dim.\n        config:\n          meta:\n          component_level: \"original_meta\"\n        dimension:\n          name: id_dim\n          label: \"ID Dimension\"\n          type: categorical\n          is_partition: true\n          config:\n            meta:\n              component_level: \"dimension_override\"\n        entity:\n          name: id_entity\n          description: This is the id entity, and it is the primary entity.\n          label: ID Entity\n          type: primary\n          config:\n            meta:\n              component_level: \"entity_override\"\n      - name: second_col\n        description: This is the second column.\n        granularity: day\n        dimension:\n          name: second_dim\n          description: This is the second column (dim).\n          label: Second Dimension\n          type: time\n          validity_params:\n            is_start: true\n            is_end: true\n      - name: foreign_id_col\n        description: This is a foreign id column.\n        entity: foreign\n      - name: col_with_default_dimensions\n        description: This is the column with default dimension settings.\n        dimension: categorical\n        entity:\n          name: col_with_default_entity_testing_default_desc\n          type: natural\n\"\"\"\n\n# Separate from the full-spectrum entities and dimensions test because some settings\n# interact with metric validations.\nbase_schema_yml_v2 = \"\"\"models:\n  - name: fct_revenue\n    description: This is the model fct_revenue. It should be able to use doc blocks\n    semantic_model: true\n    agg_time_dimension: second_dim\n    columns:\n      - name: id\n        description: This is the id column dim.\n        config:\n          meta:\n          component_level: \"original_meta\"\n        dimension:\n          name: id_dim\n          label: \"ID Dimension\"\n          type: categorical\n          is_partition: true\n          config:\n            meta:\n              component_level: \"dimension_override\"\n        entity:\n          name: id_entity\n          description: This is the id entity, and it is the primary entity.\n          label: ID Entity\n          type: primary\n          config:\n            meta:\n              component_level: \"entity_override\"\n      - name: second_col\n        description: This is the second column.\n        granularity: day\n        dimension:\n          name: second_dim\n          description: This is the second column (dim).\n          label: Second Dimension\n          type: time\n      - name: foreign_id_col\n        description: This is a foreign id column.\n        entity: foreign\n      - name: created_at\n        description: This is the time the entry was created.\n        granularity: day\n        dimension:\n          name: ds\n          description: the ds column\n          label: DS Column\n          type: time\n\"\"\"\n\nschema_yml_v2_simple_metric_on_model_1 = \"\"\"\n    metrics:\n      - name: simple_metric\n        description: This is our first simple metric.\n        label: Simple Metric\n        type: simple\n        agg: count\n        expr: id\n      - name: simple_metric_2\n        description: This is our second simple metric.\n        agg_time_dimension: ds\n        label: Simple Metric 2\n        type: simple\n        agg: count\n        expr: second_col\n      - name: percentile_metric\n        description: This is our percentile metric.\n        label: Percentile Metric\n        type: simple\n        agg: percentile\n        percentile: 0.99\n        percentile_type: discrete\n        expr: second_col\n      - name: cumulative_metric\n        description: This is our cumulative metric.\n        label: Cumulative Metric\n        type: cumulative\n        grain_to_date: day\n        period_agg: first\n        input_metric: simple_metric\n      - name: conversion_metric\n        description: This is our conversion metric.\n        label: Conversion Metric\n        type: conversion\n        entity: id_entity\n        calculation: conversion_rate\n        base_metric: simple_metric\n        conversion_metric: simple_metric_2\n\"\"\"\n\nschema_yml_v2_metrics_with_hidden = \"\"\"\n    metrics:\n      - name: public_metric\n        description: A metric that is not hidden.\n        label: Public Metric\n        type: simple\n        agg: count\n        expr: id\n        hidden: false\n      - name: private_metric\n        description: A metric that is hidden.\n        label: Private Metric\n        type: simple\n        agg: count\n        expr: id\n        hidden: true\n\"\"\"\n\nschema_yml_v2_metric_with_doc_jinja = \"\"\"\n      - name: simple_metric_with_doc_jinja\n        description: \"{{ doc('simple_metric_description') }}\"\n        label: Simple Metric With Doc Jinja\n        type: simple\n        agg: count\n        expr: id\n\"\"\"\n\nschema_yml_v2_metric_with_filter_dimension_jinja = \"\"\"\n      - name: simple_metric_with_filter_dimension_jinja\n        description: This is a description\n        label: Simple Metric With Doc Jinja\n        type: simple\n        agg: count\n        expr: id\n        filter: |\n          {{ Dimension('id_entity__id_dim') }} > 0 and {{ TimeDimension('id_entity__id_dim', 'day') }} > '2020-01-01'\n\"\"\"\n\nschema_yml_v2_metric_with_input_metrics_filter_dimension_jinja = \"\"\"\n    metrics:\n      - name: simple_metric\n        description: This is our first simple metric.\n        label: Simple Metric\n        type: simple\n        agg: count\n        expr: id\n      - name: derived_metric_with_jinja_filter\n        description: This is a derived metric with a jinja filter on an input metric.\n        label: Derived Metric With Jinja Filter\n        type: derived\n        expr: simple_metric - offset_metric\n        input_metrics:\n          - name: simple_metric\n          - name: simple_metric\n            alias: offset_metric\n            filter: |\n              {{ Dimension('id_entity__id_dim') }} > 0\n            offset_window: 1 week\n\"\"\"\n\nschema_yml_v2_metric_with_numerator_filter_dimension_jinja = \"\"\"\n    metrics:\n      - name: simple_metric\n        description: This is our first simple metric.\n        label: Simple Metric\n        type: simple\n        agg: count\n        expr: id\n      - name: simple_metric_2\n        description: This is our second simple metric.\n        label: Simple Metric 2\n        type: simple\n        agg: count\n        expr: second_col\n      - name: ratio_metric_with_jinja_filter\n        description: This is a ratio metric with a jinja filter on the numerator.\n        label: Ratio Metric With Jinja Filter\n        type: ratio\n        numerator:\n          name: simple_metric\n          filter: |\n            {{ Dimension('id_entity__id_dim') }} > 0\n        denominator: simple_metric_2\n\"\"\"\n\nschema_yml_v2_cumulative_metric_missing_input_metric = \"\"\"\n    metrics:\n      - name: cumulative_metric\n        description: This is our cumulative metric.\n        label: Cumulative Metric\n        type: cumulative\n        grain_to_date: day\n        period_agg: first\n\"\"\"\n\nschema_yml_v2_conversion_metric_missing_base_metric = \"\"\"\n    metrics:\n      - name: simple_metric_2\n        description: This is our second simple metric.\n        label: Simple Metric 2\n        type: simple\n        agg: count\n        expr: second_col\n      - name: conversion_metric\n        description: This is our conversion metric.\n        label: Conversion Metric\n        type: conversion\n        entity: id_entity\n        calculation: conversion_rate\n        conversion_metric: simple_metric_2\n\"\"\"\n\nschema_yml_v2_standalone_simple_metric = textwrap.dedent(schema_yml_v2_simple_metric_on_model_1)\n\nschema_yml_v2_standalone_metrics_template = \"\"\"\nmetrics:\n  - name: standalone_conversion_metric\n    description: {description}\n    label: Standalone Conversion Metric\n    type: conversion\n    entity: id_entity\n    calculation: conversion_rate\n    base_metric: simple_metric\n    conversion_metric: simple_metric_2\n    {filter}\n\"\"\"\n\nschema_yml_v2_standalone_metrics = schema_yml_v2_standalone_metrics_template.format(\n    description=\"This is our standalone conversion metric.\",\n    filter=\"filter: id > 0\",\n)\n\nschema_yml_v2_standalone_metrics_with_doc_jinja = schema_yml_v2_standalone_metrics_template.format(\n    description=\"\\\"{{ doc('simple_metric_description') }}\\\"\",\n    filter=\"\"\"filter: |\n      {{ Dimension('id_entity__id_dim') }} > 0\"\"\",\n)\n\nbase_schema_yml_v2_with_custom_sm_name = \"\"\"models:\n  - name: fct_revenue\n    description: This is the model fct_revenue. It should be able to use doc blocks\n    semantic_model:\n      name: custom_semantic_model\n    agg_time_dimension: second_dim\n    columns:\n      - name: id\n        description: This is the id column dim.\n        config:\n          meta:\n          component_level: \"original_meta\"\n        dimension:\n          name: id_dim\n          label: \"ID Dimension\"\n          type: categorical\n          is_partition: true\n          config:\n            meta:\n              component_level: \"dimension_override\"\n        entity:\n          name: id_entity\n          description: This is the id entity, and it is the primary entity.\n          label: ID Entity\n          type: primary\n          config:\n            meta:\n              component_level: \"entity_override\"\n      - name: second_col\n        description: This is the second column.\n        granularity: day\n        dimension:\n          name: second_dim\n          description: This is the second column (dim).\n          label: Second Dimension\n          type: time\n      - name: foreign_id_col\n        description: This is a foreign id column.\n        entity: foreign\n      - name: created_at\n        description: This is the time the entry was created.\n        granularity: day\n        dimension:\n          name: ds\n          description: the ds column\n          label: DS Column\n          type: time\n\"\"\"\n\nderived_semantics_yml = \"\"\"\n    derived_semantics:\n      entities:\n        - name: derived_id_entity\n          description: This is the id entity, and it is the primary entity.\n          label: ID Entity\n          type: foreign\n          expr: \"id + foreign_id_col\"\n          config:\n            meta:\n              test_label_thing: derived_entity_1\n        - name: derived_id_entity_with_no_optional_fields\n          type: foreign\n          expr: id + foreign_id_col\n      dimensions:\n        - name: derived_id_dimension\n          type: categorical\n          expr: id\n          granularity: day\n          validity_params:\n            is_start: true\n            is_end: true\n\"\"\"\n\nderived_semantics_with_doc_jinja_yml = \"\"\"\n    derived_semantics:\n      entities:\n        - name: derived_id_entity\n          description: \"{{ doc('entity_description') }}\"\n          type: foreign\n          expr: \"id + foreign_id_col\"\n      dimensions:\n        - name: derived_id_dimension\n          description: \"{{ doc('dimension_description') }}\"\n          type: categorical\n          expr: id\n\"\"\"\n"
  },
  {
    "path": "tests/functional/semantic_models/test_semantic_model_configs.py",
    "content": "import pytest\n\nfrom dbt.artifacts.resources import SemanticModelConfig\nfrom dbt.exceptions import ParsingError\nfrom dbt.tests.util import get_manifest, run_dbt, update_config_file\nfrom tests.functional.semantic_models.fixtures import (\n    disabled_models_people_metrics_yml,\n    disabled_semantic_model_people_yml,\n    enabled_semantic_model_people_yml,\n    groups_yml,\n    metricflow_time_spine_sql,\n    models_people_metrics_yml,\n    models_people_sql,\n    semantic_model_dimensions_entities_measures_meta_config,\n    semantic_model_meta_clobbering_yml,\n    semantic_model_people_yml,\n)\n\n\n# Test disabled config at semantic_models level in yaml file\nclass TestConfigYamlLevel:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"people.sql\": models_people_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"semantic_models.yml\": disabled_semantic_model_people_yml,\n            \"people_metrics.yml\": disabled_models_people_metrics_yml,\n            \"groups.yml\": groups_yml,\n        }\n\n    def test_yaml_level(self, project):\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n        assert \"semantic_model.test.semantic_people\" not in manifest.semantic_models\n        assert \"semantic_model.test.semantic_people\" in manifest.disabled\n\n        assert \"group.test.some_group\" in manifest.groups\n        assert \"semantic_model.test.semantic_people\" not in manifest.groups\n\n\n# Test disabled config at semantic_models level with a still enabled metric\nclass TestDisabledConfigYamlLevelEnabledMetric:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"people.sql\": models_people_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"semantic_models.yml\": disabled_semantic_model_people_yml,\n            \"people_metrics.yml\": models_people_metrics_yml,\n            \"groups.yml\": groups_yml,\n        }\n\n    def test_yaml_level(self, project):\n        with pytest.raises(\n            ParsingError,\n            match=\"The measure `people` is referenced on disabled semantic model `semantic_people`.\",\n        ):\n            run_dbt([\"parse\"])\n\n\n# Test disabling semantic model config but not metric config in dbt_project.yml\nclass TestMismatchesConfigProjectLevel:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"people.sql\": models_people_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"semantic_models.yml\": semantic_model_people_yml,\n            \"people_metrics.yml\": models_people_metrics_yml,\n            \"groups.yml\": groups_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"semantic-models\": {\n                \"test\": {\n                    \"enabled\": True,\n                }\n            }\n        }\n\n    def test_project_level(self, project):\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n        assert \"semantic_model.test.semantic_people\" in manifest.semantic_models\n        assert \"group.test.some_group\" in manifest.groups\n        assert manifest.semantic_models[\"semantic_model.test.semantic_people\"].group is None\n\n        new_enabled_config = {\n            \"semantic-models\": {\n                \"test\": {\n                    \"enabled\": False,\n                }\n            }\n        }\n        update_config_file(new_enabled_config, project.project_root, \"dbt_project.yml\")\n        with pytest.raises(\n            ParsingError,\n            match=\"The measure `people` is referenced on disabled semantic model `semantic_people`.\",\n        ):\n            run_dbt([\"parse\"])\n\n\n# Test disabling semantic model and metric configs in dbt_project.yml\nclass TestConfigProjectLevel:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"people.sql\": models_people_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"semantic_models.yml\": semantic_model_people_yml,\n            \"people_metrics.yml\": models_people_metrics_yml,\n            \"groups.yml\": groups_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"semantic-models\": {\n                \"test\": {\n                    \"enabled\": True,\n                }\n            },\n            \"metrics\": {\n                \"test\": {\n                    \"enabled\": True,\n                }\n            },\n        }\n\n    def test_project_level(self, project):\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n        assert \"semantic_model.test.semantic_people\" in manifest.semantic_models\n        assert \"group.test.some_group\" in manifest.groups\n        assert \"group.test.some_other_group\" in manifest.groups\n        assert manifest.semantic_models[\"semantic_model.test.semantic_people\"].group is None\n\n        new_group_config = {\n            \"semantic-models\": {\n                \"test\": {\n                    \"group\": \"some_other_group\",\n                }\n            },\n        }\n        update_config_file(new_group_config, project.project_root, \"dbt_project.yml\")\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n\n        assert \"semantic_model.test.semantic_people\" in manifest.semantic_models\n        assert \"group.test.some_other_group\" in manifest.groups\n        assert \"group.test.some_group\" in manifest.groups\n        assert (\n            manifest.semantic_models[\"semantic_model.test.semantic_people\"].group\n            == \"some_other_group\"\n        )\n\n        new_enabled_config = {\n            \"semantic-models\": {\n                \"test\": {\n                    \"enabled\": False,\n                }\n            },\n            \"metrics\": {\n                \"test\": {\n                    \"enabled\": False,\n                }\n            },\n        }\n        update_config_file(new_enabled_config, project.project_root, \"dbt_project.yml\")\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n\n        assert \"semantic_model.test.semantic_people\" not in manifest.semantic_models\n        assert \"semantic_model.test.semantic_people\" in manifest.disabled\n\n        assert \"group.test.some_group\" in manifest.groups\n        assert \"semantic_model.test.semantic_people\" not in manifest.groups\n\n\n# Test inheritence - set configs at project and semantic_model level - expect semantic_model level to win\nclass TestConfigsInheritence:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"people.sql\": models_people_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"semantic_models.yml\": enabled_semantic_model_people_yml,\n            \"people_metrics.yml\": models_people_metrics_yml,\n            \"groups.yml\": groups_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\"semantic-models\": {\"enabled\": False}}\n\n    def test_project_plus_yaml_level(self, project):\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n        assert \"semantic_model.test.semantic_people\" in manifest.semantic_models\n        config_test_table = manifest.semantic_models.get(\n            \"semantic_model.test.semantic_people\"\n        ).config\n\n        assert isinstance(config_test_table, SemanticModelConfig)\n\n\n# test setting meta attributes in semantic model config\nclass TestMetaConfig:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"people.sql\": models_people_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"semantic_models.yml\": enabled_semantic_model_people_yml,\n            \"people_metrics.yml\": models_people_metrics_yml,\n            \"groups.yml\": groups_yml,\n        }\n\n    def test_meta_config(self, project):\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n        sm_id = \"semantic_model.test.semantic_people\"\n        assert sm_id in manifest.semantic_models\n        sm_node = manifest.semantic_models[sm_id]\n        meta_expected = {\"my_meta\": \"testing\", \"my_other_meta\": \"testing more\"}\n        assert sm_node.config.meta == meta_expected\n\n\n# test meta configs on semantic model components (dimensions, measures, entities)\nclass TestMetaConfigForComponents:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"people.sql\": models_people_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"semantic_models.yml\": semantic_model_dimensions_entities_measures_meta_config,\n            \"people_metrics.yml\": models_people_metrics_yml,\n            \"groups.yml\": groups_yml,\n        }\n\n    def test_component_meta_configs(self, project):\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n        sm_id = \"semantic_model.test.semantic_people\"\n        assert sm_id in manifest.semantic_models\n        sm_node = manifest.semantic_models[sm_id]\n\n        # Check dimension meta config\n        favorite_color_dim = next(d for d in sm_node.dimensions if d.name == \"favorite_color\")\n        assert favorite_color_dim.config.meta == {\"dimension\": \"one\"}\n\n        # Check measure meta config\n        years_tenure_measure = next(m for m in sm_node.measures if m.name == \"years_tenure\")\n        assert years_tenure_measure.config.meta == {\"measure\": \"two\"}\n\n        # Check entity meta config\n        id_entity = next(e for e in sm_node.entities if e.name == \"id\")\n        assert id_entity.config.meta == {\"entity\": \"three\"}\n\n\n# test meta config clobbering behavior between semantic model and component levels\nclass TestMetaConfigClobbering:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"people.sql\": models_people_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"semantic_models.yml\": semantic_model_meta_clobbering_yml,\n            \"people_metrics.yml\": models_people_metrics_yml,\n            \"groups.yml\": groups_yml,\n        }\n\n    def test_meta_config_clobbering(self, project):\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n        sm_id = \"semantic_model.test.semantic_people\"\n        assert sm_id in manifest.semantic_models\n        sm_node = manifest.semantic_models[sm_id]\n\n        # Check semantic model level meta config\n        assert sm_node.config.meta == {\n            \"model_level\": \"should_be_inherited\",\n            \"component_level\": \"should_be_overridden\",\n        }\n\n        # Check dimension inherits model-level meta and overrides component-level meta\n        favorite_color_dim = next(d for d in sm_node.dimensions if d.name == \"favorite_color\")\n        assert favorite_color_dim.config.meta == {\n            \"model_level\": \"should_be_inherited\",\n            \"component_level\": \"dimension_override\",\n        }\n\n        # Check measure inherits model-level meta and overrides component-level meta\n        years_tenure_measure = next(m for m in sm_node.measures if m.name == \"years_tenure\")\n        assert years_tenure_measure.config.meta == {\n            \"model_level\": \"should_be_inherited\",\n            \"component_level\": \"measure_override\",\n        }\n\n        # Check entity inherits model-level meta and overrides component-level meta\n        id_entity = next(e for e in sm_node.entities if e.name == \"id\")\n        assert id_entity.config.meta == {\n            \"model_level\": \"should_be_inherited\",\n            \"component_level\": \"entity_override\",\n        }\n\n        # Check component without meta config still inherits model-level meta\n        created_at_dim = next(d for d in sm_node.dimensions if d.name == \"created_at\")\n        assert created_at_dim.config.meta == {\n            \"model_level\": \"should_be_inherited\",\n            \"component_level\": \"should_be_overridden\",\n        }\n"
  },
  {
    "path": "tests/functional/semantic_models/test_semantic_model_parsing.py",
    "content": "from typing import List\n\nimport pytest\n\nfrom dbt.artifacts.resources.v1.semantic_model import MetricType\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.exceptions import CompilationError\nfrom dbt.tests.util import run_dbt, write_file\nfrom dbt_common.events.base_types import BaseEvent\nfrom dbt_semantic_interfaces.type_enums.conversion_calculation_type import (\n    ConversionCalculationType,\n)\nfrom dbt_semantic_interfaces.type_enums.period_agg import PeriodAggregation\nfrom dbt_semantic_interfaces.type_enums.time_granularity import TimeGranularity\nfrom tests.functional.assertions.test_runner import dbtTestRunner\nfrom tests.functional.semantic_models.fixtures import (\n    base_schema_yml,\n    conversion_metric_yml,\n    fct_revenue_sql,\n    metricflow_time_spine_sql,\n    models_people_sql,\n    multi_sm_schema_yml,\n    ratio_metric_yml,\n    schema_without_semantic_model_yml,\n    schema_yml,\n    semantic_model_with_disabled_ref_yml,\n)\n\n\nclass TestSemanticModelParsingWorks:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": schema_yml,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n        }\n\n    def test_semantic_model_parsing(self, project):\n        runner = dbtTestRunner()\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        assert isinstance(result.result, Manifest)\n        manifest = result.result\n        assert len(manifest.semantic_models) == 1\n        semantic_model = manifest.semantic_models[\"semantic_model.test.revenue\"]\n        assert semantic_model.node_relation.alias == \"fct_revenue\"\n        assert (\n            semantic_model.node_relation.relation_name\n            == f'\"dbt\".\"{project.test_schema}\".\"fct_revenue\"'\n        )\n        assert len(semantic_model.measures) == 9\n        # manifest should have two metrics created from measures\n        assert len(manifest.metrics) == 7\n        metric = manifest.metrics[\"metric.test.txn_revenue\"]\n        assert metric.name == \"txn_revenue\"\n        metric_with_label = manifest.metrics[\"metric.test.txn_revenue_with_label\"]\n        assert metric_with_label.name == \"txn_revenue_with_label\"\n        assert metric_with_label.label == \"Transaction Revenue with label\"\n\n\nclass TestSemanticModelParsingErrors:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": schema_yml,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n        }\n\n    def test_semantic_model_error(self, project):\n        # Next, modify the default schema.yml to remove the semantic model.\n        error_schema_yml = schema_yml.replace(\"sum_of_things\", \"has_revenue\")\n        write_file(error_schema_yml, project.project_root, \"models\", \"schema.yml\")\n        events: List[BaseEvent] = []\n        runner = dbtTestRunner(callbacks=[events.append])\n        result = runner.invoke([\"parse\"])\n        assert not result.success\n\n        validation_errors = [e for e in events if e.info.name == \"SemanticValidationFailure\"]\n        assert validation_errors\n\n\nclass TestSemanticModelWithDisabledRef:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": semantic_model_with_disabled_ref_yml,\n            \"people.sql\": models_people_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n        }\n\n    def test_compilation_error_on_disabled_ref(self, project):\n        with pytest.raises(CompilationError) as excinfo:\n            run_dbt([\"parse\"])\n        assert \"depends on a node named 'people' which is disabled\" in str(excinfo.value)\n\n\nclass TestSemanticModelParsingForCumulativeMetrics:\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": schema_yml,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n        }\n\n    def test_cumulative_metric_parsing(self, project):\n        runner = dbtTestRunner()\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        manifest = result.result\n        assert \"metric.test.test_cumulative_metric\" in manifest.metrics\n        metric = manifest.metrics[\"metric.test.test_cumulative_metric\"]\n        assert metric.name == \"test_cumulative_metric\"\n        # Check type and params for cumulative metric\n        assert metric.type is MetricType.CUMULATIVE\n        cumulative_params = metric.type_params.cumulative_type_params\n        assert cumulative_params is not None\n        assert cumulative_params.grain_to_date == \"day\"\n        assert cumulative_params.period_agg is PeriodAggregation.FIRST\n\n        assert len(metric.type_params.input_measures) == 1\n        assert \"sum_of_things\" in [im.name for im in metric.type_params.input_measures]\n\n        # Not sure where dbt uses this, but for now, let's just make sure we know\n        # we're keeping the contract that these metrics are marked as depending on\n        # the semantic model.\n        assert \"semantic_model.test.revenue\" in metric.depends_on.nodes\n\n\nclass TestSemanticModelParsingForConversionMetrics:\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": schema_yml,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n        }\n\n    def test_conversion_metric_parsing(self, project):\n        runner = dbtTestRunner()\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        manifest = result.result\n        assert \"metric.test.test_conversion_metric\" in manifest.metrics\n        metric = manifest.metrics[\"metric.test.test_conversion_metric\"]\n        assert metric.name == \"test_conversion_metric\"\n        # Check type and params for conversion metric\n        assert metric.type is MetricType.CONVERSION\n        conversion_params = metric.type_params.conversion_type_params\n        assert conversion_params is not None\n        # Confirm measures, entity, and calculation are correct\n        assert conversion_params.base_measure.name == \"count_of_things\"\n        assert conversion_params.conversion_measure.name == \"count_of_things_2\"\n        assert conversion_params.entity == \"user\"\n        assert conversion_params.calculation == ConversionCalculationType.CONVERSION_RATE\n\n        assert len(metric.type_params.input_measures) == 2\n        assert \"count_of_things\" in [im.name for im in metric.type_params.input_measures]\n        assert \"count_of_things_2\" in [im.name for im in metric.type_params.input_measures]\n\n        # Not sure where dbt uses this, but for now, let's just make sure\n        # we're keeping the contract that these metrics are marked as depending on\n        # the semantic model.\n        assert \"semantic_model.test.revenue\" in metric.depends_on.nodes\n\n\nclass TestSemanticModelParsingForRatioMetrics:\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": schema_yml,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n        }\n\n    def test_ratio_metric_parsing(self, project):\n        runner = dbtTestRunner()\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        manifest = result.result\n        assert \"metric.test.test_ratio_metric\" in manifest.metrics\n        metric = manifest.metrics[\"metric.test.test_ratio_metric\"]\n        assert metric.name == \"test_ratio_metric\"\n        assert metric.type is MetricType.RATIO\n        type_params = metric.type_params\n        assert type_params.numerator.name == \"simple_metric\"\n        assert type_params.denominator.name == \"test_conversion_metric\"\n\n        assert len(metric.type_params.input_measures) == 3\n        assert \"sum_of_things\" in [im.name for im in metric.type_params.input_measures]\n        assert \"count_of_things\" in [im.name for im in metric.type_params.input_measures]\n        assert \"count_of_things_2\" in [im.name for im in metric.type_params.input_measures]\n\n        # I don't know for sure why, but it seems like we've never marked the\n        # 'depends_on' semantic model for ratio metrics, so let's document that here\n        # as a test.  These are not used in metricflow.\n        assert len(metric.depends_on.nodes) == 2\n        assert \"metric.test.simple_metric\" in metric.depends_on.nodes\n        assert \"metric.test.test_conversion_metric\" in metric.depends_on.nodes\n\n\nclass TestSemanticModelParsingForDerivedMetrics:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": schema_yml,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n        }\n\n    def test_derived_metric_parsing(self, project):\n        runner = dbtTestRunner()\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        manifest = result.result\n        assert \"metric.test.test_derived_metric\" in manifest.metrics\n        metric = manifest.metrics[\"metric.test.test_derived_metric\"]\n        assert metric.name == \"test_derived_metric\"\n        assert metric.type is MetricType.DERIVED\n        assert len(metric.type_params.input_measures) == 3\n        assert \"sum_of_things\" in [im.name for im in metric.type_params.input_measures]\n        assert \"count_of_things\" in [im.name for im in metric.type_params.input_measures]\n        assert \"count_of_things_2\" in [im.name for im in metric.type_params.input_measures]\n\n        assert len(metric.type_params.metrics) == 2\n        assert \"simple_metric\" in [m.name for m in metric.type_params.metrics]\n        assert \"test_conversion_metric\" in [m.name for m in metric.type_params.metrics]\n\n        # I don't know for sure why, but it seems like we've never marked the\n        # 'depends_on' semantic model for derived metrics, so let's document that here\n        # as a test.  These are not used in metricflow.\n        assert len(metric.depends_on.nodes) == 2\n        assert \"metric.test.simple_metric\" in metric.depends_on.nodes\n        assert \"metric.test.test_conversion_metric\" in metric.depends_on.nodes\n\n\n# ------------------------------------------------------------------------------\n# Partial Parsing tests below\n# ------------------------------------------------------------------------------\n\n\nclass TestSemanticModelPartialParsingWithModelChanged:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": schema_yml,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n        }\n\n    def test_semantic_model_changed_partial_parsing(self, project):\n        # First, use the default schema.yml to define our semantic model, and\n        # run the dbt parse command\n        runner = dbtTestRunner()\n        result = runner.invoke([\"parse\"])\n        assert result.success\n\n        # Next, modify the default schema.yml to change a detail of the semantic\n        # model.\n        modified_schema_yml = schema_yml.replace(\"time_granularity: day\", \"time_granularity: week\")\n        write_file(modified_schema_yml, project.project_root, \"models\", \"schema.yml\")\n\n        # Now, run the dbt parse command again.\n        result = runner.invoke([\"parse\"])\n        assert result.success\n\n        # Finally, verify that the manifest reflects the partially parsed change\n        manifest = result.result\n        semantic_model = manifest.semantic_models[\"semantic_model.test.revenue\"]\n        assert semantic_model.dimensions[0].type_params.time_granularity == TimeGranularity.WEEK\n\n\n# TODO DI-4421 (Linear) / SEMANTIC-2997 (Jira): fix the partial parsing bug that breaks this.\n# class TestSemanticModelPartialParsingWithModelDeleted:\n#     @pytest.fixture(scope=\"class\")\n#     def models(self):\n#         return {\n#             \"schema.yml\": schema_yml,\n#             \"fct_revenue.sql\": fct_revenue_sql,\n#             \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n#         }\n\n#     def test_semantic_model_deleted_partial_parsing__dependency_bug_causes_failure(self, project):\n#         # First, use the default schema.yml to define our semantic model, and\n#         # run the dbt parse command\n#         runner = dbtTestRunner()\n#         result = runner.invoke([\"parse\"])\n#         assert result.success\n#         assert \"semantic_model.test.revenue\" in result.result.semantic_models\n\n#         # Next, modify the default schema.yml to remove the semantic model.\n#         write_file(schema_without_semantic_model_yml, project.project_root, \"models\", \"schema.yml\")\n\n#         # Now, run the dbt parse command again.\n#         result = runner.invoke([\"parse\"])\n#         # Known bug: we don't remove metrics in any particular order, so we'll remove\n#         # simple_metric before the metrics that rely on it and have problems... but only SOMETIMES.\n#         assert result.success\n\n\nclass TestSemanticModelPartialParsingWithModelDeletedIteratively:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": base_schema_yml + conversion_metric_yml + ratio_metric_yml,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n        }\n\n    def test_semantic_model_deleted_partial_parsing(self, project):\n        # First, use the default schema.yml to define our semantic model, and\n        # run the dbt parse command\n        runner = dbtTestRunner()\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        assert \"semantic_model.test.revenue\" in result.result.semantic_models\n\n        # Next, modify the default schema.yml to remove the semantic model ITERATIVELY\n        # (removing it all at once doesn't work because of a bug right now.\n        # see test_semantic_model_deleted_partial_parsing__dependency_bug_causes_failure.)\n        write_file(\n            base_schema_yml + conversion_metric_yml,\n            project.project_root,\n            \"models\",\n            \"schema.yml\",\n        )\n        # Now, run the dbt parse command again.\n        result = runner.invoke([\"parse\"])\n        assert result.success\n\n        write_file(base_schema_yml, project.project_root, \"models\", \"schema.yml\")\n        result = runner.invoke([\"parse\"])\n        assert result.success\n\n        write_file(schema_without_semantic_model_yml, project.project_root, \"models\", \"schema.yml\")\n        result = runner.invoke([\"parse\"])\n        assert result.success\n\n        # Finally, verify that the manifest reflects the deletion\n        assert \"semantic_model.test.revenue\" not in result.result.semantic_models\n\n\nclass TestSemanticModelPartialParsingWithModelFlippingCreateMetric:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": schema_yml,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n        }\n\n    def test_semantic_model_flipping_create_metric_partial_parsing(self, project):\n        generated_metric = \"metric.test.txn_revenue\"\n        generated_metric_with_label = \"metric.test.txn_revenue_with_label\"\n        # First, use the default schema.yml to define our semantic model, and\n        # run the dbt parse command\n        runner = dbtTestRunner()\n        result = runner.invoke([\"parse\"])\n        assert result.success\n\n        # Verify the metric created by `create_metric: true` exists\n        metric = result.result.metrics[generated_metric]\n        assert metric.name == \"txn_revenue\"\n        assert metric.label == \"txn_revenue\"\n\n        metric_with_label = result.result.metrics[generated_metric_with_label]\n        assert metric_with_label.name == \"txn_revenue_with_label\"\n        assert metric_with_label.label == \"Transaction Revenue with label\"\n\n        # --- Next, modify the default schema.yml to have no `create_metric: true` ---\n        no_create_metric_schema_yml = schema_yml.replace(\n            \"create_metric: true\", \"create_metric: false\"\n        )\n        write_file(no_create_metric_schema_yml, project.project_root, \"models\", \"schema.yml\")\n\n        # Now, run the dbt parse command again.\n        result = runner.invoke([\"parse\"])\n        assert result.success\n\n        # Verify the metric originally created by `create_metric: true` was removed\n        assert result.result.metrics.get(generated_metric) is None\n\n        # Verify that partial parsing didn't clobber the normal metric\n        assert result.result.metrics.get(\"metric.test.simple_metric\") is not None\n\n        # --- Now bring it back ---\n        create_metric_schema_yml = schema_yml.replace(\n            \"create_metric: false\", \"create_metric: true\"\n        )\n        write_file(create_metric_schema_yml, project.project_root, \"models\", \"schema.yml\")\n\n        # Now, run the dbt parse command again.\n        result = runner.invoke([\"parse\"])\n        assert result.success\n\n        # Verify the metric originally created by `create_metric: true` was removed\n        metric = result.result.metrics[generated_metric]\n        assert metric.name == \"txn_revenue\"\n\n\nclass TestSemanticModelPartialParsingGeneratedMetrics:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": multi_sm_schema_yml,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n        }\n\n    def test_generated_metrics(self, project):\n        manifest = run_dbt([\"parse\"])\n        expected = {\n            \"metric.test.simple_metric\",\n            \"metric.test.txn_revenue\",\n            \"metric.test.alt_txn_revenue\",\n        }\n        assert set(manifest.metrics.keys()) == expected\n\n        # change description of 'revenue' semantic model\n        modified_schema_yml = multi_sm_schema_yml.replace(\"first\", \"FIRST\")\n        write_file(modified_schema_yml, project.project_root, \"models\", \"schema.yml\")\n        manifest = run_dbt([\"parse\"])\n        assert set(manifest.metrics.keys()) == expected\n"
  },
  {
    "path": "tests/functional/semantic_models/test_semantic_model_v2_parsing.py",
    "content": "import pytest\n\nfrom core.dbt.contracts.graph.semantic_manifest import SemanticManifest\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt_semantic_interfaces.type_enums import (\n    AggregationType,\n    ConversionCalculationType,\n    DimensionType,\n    EntityType,\n    MetricType,\n    PeriodAggregation,\n)\nfrom tests.functional.assertions.test_runner import dbtTestRunner\nfrom tests.functional.semantic_models.fixtures import (\n    base_schema_yml_v2,\n    base_schema_yml_v2_with_custom_sm_name,\n    derived_semantics_with_doc_jinja_yml,\n    derived_semantics_yml,\n    fct_revenue_sql,\n    metricflow_time_spine_sql,\n    schema_yml_v2_conversion_metric_missing_base_metric,\n    schema_yml_v2_cumulative_metric_missing_input_metric,\n    schema_yml_v2_metric_with_doc_jinja,\n    schema_yml_v2_metric_with_filter_dimension_jinja,\n    schema_yml_v2_metric_with_input_metrics_filter_dimension_jinja,\n    schema_yml_v2_metric_with_numerator_filter_dimension_jinja,\n    schema_yml_v2_metrics_with_hidden,\n    schema_yml_v2_simple_metric_on_model_1,\n    schema_yml_v2_standalone_metrics,\n    schema_yml_v2_standalone_metrics_with_doc_jinja,\n    schema_yml_v2_standalone_simple_metric,\n    semantic_model_config_does_not_exist,\n    semantic_model_descriptions,\n    semantic_model_schema_yml_v2,\n    semantic_model_schema_yml_v2_default_values,\n    semantic_model_schema_yml_v2_disabled,\n    semantic_model_schema_yml_v2_false_config,\n    semantic_model_schema_yml_v2_primary_entity_only_on_model,\n    semantic_model_schema_yml_v2_renamed,\n    semantic_model_schema_yml_v2_with_primary_entity_only_on_column,\n    semantic_model_test_groups_yml,\n)\n\n\nclass TestSemanticModelParsingWorks:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": semantic_model_schema_yml_v2,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n        }\n\n    def test_semantic_model_parsing(self, project) -> None:\n        runner = dbtTestRunner()\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        assert isinstance(result.result, Manifest)\n        manifest = result.result\n        assert len(manifest.semantic_models) == 1\n        semantic_model = manifest.semantic_models[\"semantic_model.test.fct_revenue\"]\n        assert semantic_model.name == \"fct_revenue\"\n        assert semantic_model.node_relation.alias == \"fct_revenue\"\n        assert (\n            semantic_model.node_relation.relation_name\n            == f'\"dbt\".\"{project.test_schema}\".\"fct_revenue\"'\n        )\n        assert (\n            semantic_model.description\n            == \"This is the model fct_revenue. It should be able to use doc blocks\"\n        )\n        assert semantic_model.config.enabled is True\n        assert semantic_model.config.group is None\n        assert semantic_model.config.meta == {}\n\n        # Dimensions\n\n        assert len(semantic_model.dimensions) == 3\n        dimensions = {dimension.name: dimension for dimension in semantic_model.dimensions}\n        id_dim = dimensions[\"id_dim\"]\n        assert id_dim.type == DimensionType.CATEGORICAL\n        assert id_dim.description == \"This is the id column dim.\"\n        assert id_dim.label == \"ID Dimension\"\n        assert id_dim.is_partition is True\n        assert id_dim.config.meta == {\"component_level\": \"dimension_override\"}\n        # dimension name \"id_dim\" differs from column name \"id\", so expr must\n        # be set to the column name for MetricFlow to query the correct column.\n        assert id_dim.expr == \"id\"\n        second_dim = dimensions[\"second_dim\"]\n        assert second_dim.type == DimensionType.TIME\n        assert second_dim.description == \"This is the second column (dim).\"\n        assert second_dim.label == \"Second Dimension\"\n        assert second_dim.is_partition is False\n        assert second_dim.config.meta == {}\n        assert second_dim.type_params.validity_params.is_start is True\n        assert second_dim.type_params.validity_params.is_end is True\n        # dimension name \"second_dim\" differs from column name \"second_col\",\n        # so expr must be set to the column name.\n        assert second_dim.expr == \"second_col\"\n        col_with_default_dimensions = dimensions[\"col_with_default_dimensions\"]\n        assert col_with_default_dimensions.type == DimensionType.CATEGORICAL\n        assert (\n            col_with_default_dimensions.description\n            == \"This is the column with default dimension settings.\"\n        )\n        assert col_with_default_dimensions.label is None\n        assert col_with_default_dimensions.is_partition is False\n        assert col_with_default_dimensions.config.meta == {}\n        assert col_with_default_dimensions.validity_params is None\n        # dimension name matches column name, so expr should not be set.\n        assert col_with_default_dimensions.expr is None\n\n        # Entities\n        assert len(semantic_model.entities) == 3\n        entities = {entity.name: entity for entity in semantic_model.entities}\n        primary_entity = entities[\"id_entity\"]\n        assert primary_entity.type == EntityType.PRIMARY\n        assert primary_entity.description == \"This is the id entity, and it is the primary entity.\"\n        assert primary_entity.label == \"ID Entity\"\n        assert primary_entity.config.meta == {\"component_level\": \"entity_override\"}\n        # entity name \"id_entity\" differs from column name \"id\", so expr must\n        # be set to the column name for MetricFlow to query the correct column.\n        assert primary_entity.expr == \"id\"\n\n        foreign_id_col = entities[\"foreign_id_col\"]\n        assert foreign_id_col.type == EntityType.FOREIGN\n        assert foreign_id_col.description == \"This is a foreign id column.\"\n        assert foreign_id_col.label is None\n        assert foreign_id_col.config.meta == {}\n        # entity name matches column name, so expr should not be set.\n        assert foreign_id_col.expr is None\n\n        col_with_default_entity_testing_default_desc = entities[\n            \"col_with_default_entity_testing_default_desc\"\n        ]\n        assert col_with_default_entity_testing_default_desc.type == EntityType.NATURAL\n        assert (\n            col_with_default_entity_testing_default_desc.description\n            == \"This is the column with default dimension settings.\"\n        )\n        assert col_with_default_entity_testing_default_desc.label is None\n        assert col_with_default_entity_testing_default_desc.config.meta == {}\n        # entity name differs from column name, so expr must be set.\n        assert col_with_default_entity_testing_default_desc.expr == \"col_with_default_dimensions\"\n\n        # No measures in v2 YAML\n        assert len(semantic_model.measures) == 0\n        assert len(manifest.metrics) == 0\n        # TODO: Dimensions are not parsed yet (for those attached to model columns)\n        # TODO: Dimensions are not parsed yet (for those defined in derived semantics)\n\n\nclass TestSemanticModelConfigOverrides:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": semantic_model_test_groups_yml + semantic_model_schema_yml_v2_renamed,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n        }\n\n    def test_semantic_model_parsing(self, project) -> None:\n        runner = dbtTestRunner()\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        assert isinstance(result.result, Manifest)\n        manifest = result.result\n        assert len(manifest.semantic_models) == 1\n        semantic_model = manifest.semantic_models[\"semantic_model.test.renamed_semantic_model\"]\n\n        assert semantic_model.node_relation.alias == \"fct_revenue\"\n        assert (\n            semantic_model.node_relation.relation_name\n            == f'\"dbt\".\"{project.test_schema}\".\"fct_revenue\"'\n        )\n\n        assert semantic_model.config.enabled is True\n        assert semantic_model.config.group == \"finance\"\n        assert semantic_model.config.meta == {\"meta_tag_1\": \"this_meta\"}\n\n\nclass TestSemanticModelConfigDefaultValues:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": semantic_model_schema_yml_v2_default_values,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n        }\n\n    def test_semantic_model_parsing_defaults(self, project) -> None:\n        runner = dbtTestRunner()\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        assert isinstance(result.result, Manifest)\n        manifest = result.result\n\n        assert len(manifest.semantic_models) == 1\n        semantic_model = list(manifest.semantic_models.values())[0]\n\n        # With no custom name, alias should be based on model name (default test. + model name)\n        assert semantic_model.node_relation.alias == \"fct_revenue\"\n\n        assert (\n            semantic_model.description\n            == \"This is the model fct_revenue. It should be able to use doc blocks\"\n        )\n\n        # Should use default config values\n        assert semantic_model.config.enabled is True\n        assert semantic_model.config.group is None\n        assert semantic_model.config.meta == {}\n\n\nclass TestSemanticModelConfigDoesNotExistPassesWithoutParsingSemanticModel:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": semantic_model_config_does_not_exist,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n        }\n\n    def test_semantic_model_parsing(self, project) -> None:\n        runner = dbtTestRunner()\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        assert isinstance(result.result, Manifest)\n        manifest = result.result\n        assert len(manifest.semantic_models) == 0\n\n\nclass TestSemanticModelDisabledConfigIsNotParsed:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": semantic_model_schema_yml_v2_disabled,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n        }\n\n    def test_semantic_model_parsing(self, project) -> None:\n        runner = dbtTestRunner()\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        assert isinstance(result.result, Manifest)\n        manifest = result.result\n        assert len(manifest.semantic_models) == 0\n\n\nclass TestSemanticModelFalseConfigIsNotParsed:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": semantic_model_schema_yml_v2_false_config,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n        }\n\n    def test_semantic_model_parsing(self, project) -> None:\n        runner = dbtTestRunner()\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        assert isinstance(result.result, Manifest)\n        manifest = result.result\n        assert len(manifest.semantic_models) == 0\n\n\nclass TestMetricOnModelParsingWorks:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": base_schema_yml_v2 + schema_yml_v2_simple_metric_on_model_1,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n        }\n\n    def test_metric_on_model_parsing(self, project):\n        runner = dbtTestRunner()\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        manifest = result.result\n\n        semantic_model = manifest.semantic_models[\"semantic_model.test.fct_revenue\"]\n        assert semantic_model.defaults.agg_time_dimension == \"second_dim\"\n\n        metrics = manifest.metrics\n        semantic_manifest = SemanticManifest(manifest)\n        semantic_manifest_metrics = {\n            metric.name: metric\n            for metric in semantic_manifest._get_pydantic_semantic_manifest().metrics\n        }\n        assert len(metrics) == 5\n\n        simple_metric = metrics[\"metric.test.simple_metric\"]\n        assert simple_metric.name == \"simple_metric\"\n        assert simple_metric.description == \"This is our first simple metric.\"\n        assert simple_metric.type == MetricType.SIMPLE\n        assert simple_metric.type_params.metric_aggregation_params.agg == AggregationType.COUNT\n        assert simple_metric.type_params.metric_aggregation_params.semantic_model == \"fct_revenue\"\n        assert \"semantic_model.test.fct_revenue\" in simple_metric.depends_on.nodes\n        assert (\n            simple_metric.type_params.metric_aggregation_params.agg_time_dimension == \"second_dim\"\n        )\n\n        simple_metric_pydantic = semantic_manifest_metrics[\"simple_metric\"]\n        assert simple_metric_pydantic.name == \"simple_metric\"\n        assert simple_metric_pydantic.description == \"This is our first simple metric.\"\n        assert simple_metric_pydantic.type == MetricType.SIMPLE\n        assert (\n            simple_metric_pydantic.type_params.metric_aggregation_params.agg\n            == AggregationType.COUNT\n        )\n        assert (\n            simple_metric_pydantic.type_params.metric_aggregation_params.semantic_model\n            == \"fct_revenue\"\n        )\n        assert (\n            simple_metric_pydantic.type_params.metric_aggregation_params.agg_time_dimension\n            == \"second_dim\"\n        )\n        # No 'depends_on' in the pydantic metric\n\n        simple_metric_2 = metrics[\"metric.test.simple_metric_2\"]\n        assert simple_metric_2.name == \"simple_metric_2\"\n        assert simple_metric_2.description == \"This is our second simple metric.\"\n        assert simple_metric_2.type == MetricType.SIMPLE\n        assert simple_metric_2.type_params.metric_aggregation_params.agg == AggregationType.COUNT\n        assert (\n            simple_metric_2.type_params.metric_aggregation_params.semantic_model == \"fct_revenue\"\n        )\n        assert \"semantic_model.test.fct_revenue\" in simple_metric_2.depends_on.nodes\n        assert simple_metric_2.type_params.metric_aggregation_params.agg_time_dimension == \"ds\"\n\n        simple_metric_2_pydantic = semantic_manifest_metrics[\"simple_metric_2\"]\n        assert simple_metric_2_pydantic.name == \"simple_metric_2\"\n        assert simple_metric_2_pydantic.description == \"This is our second simple metric.\"\n        assert simple_metric_2_pydantic.type == MetricType.SIMPLE\n        assert (\n            simple_metric_2_pydantic.type_params.metric_aggregation_params.agg\n            == AggregationType.COUNT\n        )\n        assert (\n            simple_metric_2_pydantic.type_params.metric_aggregation_params.semantic_model\n            == \"fct_revenue\"\n        )\n        assert (\n            simple_metric_2_pydantic.type_params.metric_aggregation_params.agg_time_dimension\n            == \"ds\"\n        )\n\n        # No 'depends_on' in the pydantic metric\n        percentile_metric = metrics[\"metric.test.percentile_metric\"]\n        assert percentile_metric.name == \"percentile_metric\"\n        assert percentile_metric.description == \"This is our percentile metric.\"\n        assert percentile_metric.type == MetricType.SIMPLE\n        assert (\n            percentile_metric.type_params.metric_aggregation_params.agg\n            == AggregationType.PERCENTILE\n        )\n        assert (\n            percentile_metric.type_params.metric_aggregation_params.semantic_model == \"fct_revenue\"\n        )\n        assert (\n            percentile_metric.type_params.metric_aggregation_params.agg_params.percentile == 0.99\n        )\n        assert (\n            percentile_metric.type_params.metric_aggregation_params.agg_params.use_discrete_percentile\n            is True\n        )\n        assert (\n            percentile_metric.type_params.metric_aggregation_params.agg_params.use_approximate_percentile\n            is False\n        )\n        assert \"semantic_model.test.fct_revenue\" in percentile_metric.depends_on.nodes\n        assert (\n            percentile_metric.type_params.metric_aggregation_params.agg_time_dimension\n            == \"second_dim\"\n        )\n\n        percentile_metric_pydantic = semantic_manifest_metrics[\"percentile_metric\"]\n        assert percentile_metric_pydantic.name == \"percentile_metric\"\n        assert percentile_metric_pydantic.description == \"This is our percentile metric.\"\n        assert percentile_metric_pydantic.type == MetricType.SIMPLE\n        assert (\n            percentile_metric_pydantic.type_params.metric_aggregation_params.agg\n            == AggregationType.PERCENTILE\n        )\n        assert (\n            percentile_metric_pydantic.type_params.metric_aggregation_params.semantic_model\n            == \"fct_revenue\"\n        )\n        assert (\n            percentile_metric_pydantic.type_params.metric_aggregation_params.agg_params.percentile\n            == 0.99\n        )\n        assert (\n            percentile_metric_pydantic.type_params.metric_aggregation_params.agg_params.use_discrete_percentile\n            is True\n        )\n        assert (\n            percentile_metric_pydantic.type_params.metric_aggregation_params.agg_params.use_approximate_percentile\n            is False\n        )\n        assert (\n            percentile_metric_pydantic.type_params.metric_aggregation_params.agg_time_dimension\n            == \"second_dim\"\n        )\n\n        cumulative_metric = metrics[\"metric.test.cumulative_metric\"]\n        assert cumulative_metric.name == \"cumulative_metric\"\n        assert cumulative_metric.description == \"This is our cumulative metric.\"\n        assert cumulative_metric.type == MetricType.CUMULATIVE\n        assert cumulative_metric.type_params.cumulative_type_params.grain_to_date == \"day\"\n        assert (\n            cumulative_metric.type_params.cumulative_type_params.period_agg\n            == PeriodAggregation.FIRST\n        )\n        assert cumulative_metric.type_params.cumulative_type_params.metric.name == \"simple_metric\"\n        assert \"metric.test.simple_metric\" in cumulative_metric.depends_on.nodes\n        assert cumulative_metric.type_params.metric_aggregation_params is None\n\n        cumulative_metric_pydantic = semantic_manifest_metrics[\"cumulative_metric\"]\n        assert cumulative_metric_pydantic.name == \"cumulative_metric\"\n        assert cumulative_metric_pydantic.description == \"This is our cumulative metric.\"\n        assert cumulative_metric_pydantic.type == MetricType.CUMULATIVE\n        assert cumulative_metric_pydantic.type_params.cumulative_type_params.grain_to_date == \"day\"\n        assert (\n            cumulative_metric_pydantic.type_params.cumulative_type_params.period_agg\n            == PeriodAggregation.FIRST\n        )\n        assert (\n            cumulative_metric_pydantic.type_params.cumulative_type_params.metric.name\n            == \"simple_metric\"\n        )\n        assert cumulative_metric_pydantic.type_params.metric_aggregation_params is None\n\n        conversion_metric = metrics[\"metric.test.conversion_metric\"]\n        assert conversion_metric.name == \"conversion_metric\"\n        assert conversion_metric.description == \"This is our conversion metric.\"\n        assert conversion_metric.type == MetricType.CONVERSION\n        assert conversion_metric.type_params.conversion_type_params.entity == \"id_entity\"\n        assert (\n            conversion_metric.type_params.conversion_type_params.calculation\n            is ConversionCalculationType.CONVERSION_RATE\n        )\n        assert (\n            conversion_metric.type_params.conversion_type_params.base_metric.name\n            == \"simple_metric\"\n        )\n        assert (\n            conversion_metric.type_params.conversion_type_params.conversion_metric.name\n            == \"simple_metric_2\"\n        )\n        assert \"metric.test.simple_metric\" in conversion_metric.depends_on.nodes\n        assert \"metric.test.simple_metric_2\" in conversion_metric.depends_on.nodes\n        assert conversion_metric.type_params.metric_aggregation_params is None\n\n        conversion_metric_pydantic = semantic_manifest_metrics[\"conversion_metric\"]\n        assert conversion_metric_pydantic.name == \"conversion_metric\"\n        assert conversion_metric_pydantic.description == \"This is our conversion metric.\"\n        assert conversion_metric_pydantic.type == MetricType.CONVERSION\n        assert conversion_metric_pydantic.type_params.conversion_type_params.entity == \"id_entity\"\n        assert (\n            conversion_metric_pydantic.type_params.conversion_type_params.calculation\n            is ConversionCalculationType.CONVERSION_RATE\n        )\n        assert (\n            conversion_metric_pydantic.type_params.conversion_type_params.base_metric.name\n            == \"simple_metric\"\n        )\n        assert (\n            conversion_metric_pydantic.type_params.conversion_type_params.conversion_metric.name\n            == \"simple_metric_2\"\n        )\n        assert conversion_metric_pydantic.type_params.metric_aggregation_params is None\n\n\nclass TestMetricHiddenMapsToIsPrivate:\n    \"\"\"Test that a metric's 'hidden' field in YAML is reflected as 'is_private' on the parsed metric.\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": base_schema_yml_v2 + schema_yml_v2_metrics_with_hidden,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n        }\n\n    def test_metric_hidden_yaml_maps_to_is_private(self, project):\n        runner = dbtTestRunner()\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        manifest = result.result\n        metrics = manifest.metrics\n        assert len(metrics) == 2\n\n        public_metric = metrics[\"metric.test.public_metric\"]\n        assert public_metric.type_params.is_private is False\n\n        private_metric = metrics[\"metric.test.private_metric\"]\n        assert private_metric.type_params.is_private is True\n\n\nclass TestStandaloneMetricParsingSimpleMetricFails:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": base_schema_yml_v2 + schema_yml_v2_standalone_simple_metric,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n        }\n\n    def test_standalone_metric_parsing(self, project):\n        runner = dbtTestRunner()\n        result = runner.invoke([\"parse\"])\n        assert not result.success\n        assert (\n            \"simple metrics in v2 YAML must be attached to semantic_model\" in result.exception.msg\n        )\n\n\nclass TestStandaloneMetricParsingWorks:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": base_schema_yml_v2\n            + schema_yml_v2_simple_metric_on_model_1\n            + schema_yml_v2_standalone_metrics,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n        }\n\n    def test_included_metric_parsing(self, project):\n        runner = dbtTestRunner()\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        manifest = result.result\n\n        semantic_model = manifest.semantic_models[\"semantic_model.test.fct_revenue\"]\n        assert semantic_model.defaults.agg_time_dimension == \"second_dim\"\n\n        metrics = manifest.metrics\n        semantic_manifest = SemanticManifest(manifest)\n        semantic_manifest_metrics = {\n            metric.name: metric\n            for metric in semantic_manifest._get_pydantic_semantic_manifest().metrics\n        }\n        assert len(metrics) == 6\n\n        metric = metrics[\"metric.test.standalone_conversion_metric\"]\n        assert metric.name == \"standalone_conversion_metric\"\n        assert metric.description == \"This is our standalone conversion metric.\"\n        assert metric.type == MetricType.CONVERSION\n        assert metric.type_params.conversion_type_params.entity == \"id_entity\"\n        assert (\n            metric.type_params.conversion_type_params.calculation\n            == ConversionCalculationType.CONVERSION_RATE\n        )\n        assert metric.type_params.conversion_type_params.base_metric.name == \"simple_metric\"\n        assert (\n            metric.type_params.conversion_type_params.conversion_metric.name == \"simple_metric_2\"\n        )\n        assert set(metric.depends_on.nodes) == set(\n            [\n                \"metric.test.simple_metric\",\n                \"metric.test.simple_metric_2\",\n            ]\n        )\n        assert metric.type_params.metric_aggregation_params is None\n        assert metric.filter.where_filters[0].where_sql_template == \"id > 0\"\n\n        metric_pydantic = semantic_manifest_metrics[\"standalone_conversion_metric\"]\n        assert metric_pydantic.name == \"standalone_conversion_metric\"\n        assert metric_pydantic.description == \"This is our standalone conversion metric.\"\n        assert metric_pydantic.type == MetricType.CONVERSION\n        assert metric_pydantic.type_params.conversion_type_params.entity == \"id_entity\"\n        assert (\n            metric_pydantic.type_params.conversion_type_params.calculation\n            == ConversionCalculationType.CONVERSION_RATE\n        )\n        assert (\n            metric_pydantic.type_params.conversion_type_params.base_metric.name == \"simple_metric\"\n        )\n        assert (\n            metric_pydantic.type_params.conversion_type_params.conversion_metric.name\n            == \"simple_metric_2\"\n        )\n        assert metric_pydantic.type_params.metric_aggregation_params is None\n        assert metric_pydantic.filter.where_filters[0].where_sql_template == \"id > 0\"\n\n\nclass TestCumulativeMetricNoInputMetricFails:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": base_schema_yml_v2\n            + schema_yml_v2_cumulative_metric_missing_input_metric,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n        }\n\n    def test_cumulative_metric_no_input_metric_parsing_fails(self, project) -> None:\n        runner = dbtTestRunner()\n        result = runner.invoke([\"parse\"])\n        assert not result.success\n        assert \"input_metric is required for cumulative metrics.\" in str(result.exception)\n\n\nclass TestConversionMetricNoBaseMetricFails:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": base_schema_yml_v2 + schema_yml_v2_conversion_metric_missing_base_metric,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n        }\n\n    def test_conversion_metric_no_base_metric_parsing_fails(self, project) -> None:\n        runner = dbtTestRunner()\n        result = runner.invoke([\"parse\"])\n        assert not result.success\n        assert \"base_metric is required for conversion metrics.\" in str(result.exception)\n\n\nclass TestDerivedSemanticsWithDocJinjaParsingWorks:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": semantic_model_schema_yml_v2 + derived_semantics_with_doc_jinja_yml,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"docs.md\": semantic_model_descriptions,\n        }\n\n    def test_derived_semantics_doc_jinja_parsing(self, project) -> None:\n        runner = dbtTestRunner()\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        manifest = result.result\n        assert len(manifest.semantic_models) == 1\n        semantic_model = manifest.semantic_models[\"semantic_model.test.fct_revenue\"]\n        entities = {entity.name: entity for entity in semantic_model.entities}\n        assert entities[\"derived_id_entity\"].description == \"qux\"\n        dimensions = {dimension.name: dimension for dimension in semantic_model.dimensions}\n        assert dimensions[\"derived_id_dimension\"].description == \"bar\"\n\n\nclass TestDerivedSemanticsParsingWorks:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": semantic_model_schema_yml_v2 + derived_semantics_yml,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n        }\n\n    def test_derived_semantics_parsing(self, project) -> None:\n        runner = dbtTestRunner()\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        manifest = result.result\n        assert len(manifest.semantic_models) == 1\n        semantic_model = manifest.semantic_models[\"semantic_model.test.fct_revenue\"]\n        entities = {entity.name: entity for entity in semantic_model.entities}\n        assert (\n            len(entities) == 5\n        )  # length is so long because it is column entities + derived entities\n\n        id_entity = entities[\"derived_id_entity\"]\n        assert id_entity.type == EntityType.FOREIGN\n        assert id_entity.description == \"This is the id entity, and it is the primary entity.\"\n        assert id_entity.expr == \"id + foreign_id_col\"\n        assert id_entity.config.meta == {\"test_label_thing\": \"derived_entity_1\"}\n\n        id_entity_with_no_optional_fields = entities[\"derived_id_entity_with_no_optional_fields\"]\n        assert id_entity_with_no_optional_fields.type == EntityType.FOREIGN\n        assert id_entity_with_no_optional_fields.expr == \"id + foreign_id_col\"\n        assert id_entity_with_no_optional_fields.config.meta == {}\n\n        dimensions = {dimension.name: dimension for dimension in semantic_model.dimensions}\n        assert len(dimensions) == 4  # includes non-derived dimensions\n        assert dimensions[\"derived_id_dimension\"].type == DimensionType.CATEGORICAL\n        assert dimensions[\"derived_id_dimension\"].expr == \"id\"\n        assert dimensions[\"derived_id_dimension\"].config.meta == {}\n        assert dimensions[\"derived_id_dimension\"].type_params.validity_params.is_start is True\n        assert dimensions[\"derived_id_dimension\"].type_params.validity_params.is_end is True\n\n\nclass TestSemanticModelWithPrimaryEntityOnlyOnColumn:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": semantic_model_schema_yml_v2_with_primary_entity_only_on_column,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n        }\n\n    def test_primary_entity_type_is_id_entity(self, project):\n        runner = dbtTestRunner()\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        manifest = result.result\n        assert len(manifest.semantic_models) == 1\n        semantic_model = list(manifest.semantic_models.values())[0]\n        entities = {entity.name: entity for entity in semantic_model.entities}\n        primary_entity = [\n            entity for entity in entities.values() if entity.type == EntityType.PRIMARY\n        ]\n        assert len(primary_entity) == 1\n        primary_entity = primary_entity[0]\n        assert primary_entity.name == \"id_entity\"\n        assert semantic_model.primary_entity is None\n\n\nclass TestSemanticModelWithPrimaryEntityOnlyOnModel:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": semantic_model_schema_yml_v2_primary_entity_only_on_model,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n        }\n\n    def test_primary_entities_empty(self, project):\n        runner = dbtTestRunner()\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        manifest = result.result\n        assert len(manifest.semantic_models) == 1\n        semantic_model = list(manifest.semantic_models.values())[0]\n        entities = {entity.name: entity for entity in semantic_model.entities}\n        primary_entity = [\n            entity for entity in entities.values() if entity.type == EntityType.PRIMARY\n        ]\n        assert len(primary_entity) == 0\n        assert semantic_model.primary_entity == \"id_entity\"\n\n\nclass TestSimpleSemanticModelWithMetricWithDocJinja:\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": base_schema_yml_v2\n            + schema_yml_v2_simple_metric_on_model_1\n            + schema_yml_v2_metric_with_doc_jinja,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"docs.md\": semantic_model_descriptions,\n        }\n\n    def test_simple_metric_with_doc_jinja_parsing(self, project):\n        runner = dbtTestRunner()\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        manifest = result.result\n        assert len(manifest.semantic_models) == 1\n        metric = manifest.metrics[\"metric.test.simple_metric_with_doc_jinja\"]\n        assert metric.description == \"describe away!\"\n\n\nclass TestSimpleSemanticModelWithFilterWithFilterDimensionJinja:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": base_schema_yml_v2\n            + schema_yml_v2_simple_metric_on_model_1\n            + schema_yml_v2_metric_with_filter_dimension_jinja,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"docs.md\": semantic_model_descriptions,\n        }\n\n    def test_simple_metric_with_filter_with_filter_dimension_jinja_parsing(self, project):\n        runner = dbtTestRunner()\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        manifest = result.result\n        assert len(manifest.semantic_models) == 1\n        metric = manifest.metrics[\"metric.test.simple_metric_with_filter_dimension_jinja\"]\n        assert (\n            metric.filter.where_filters[0].where_sql_template\n            == \"{{ Dimension('id_entity__id_dim') }} > 0 and {{ TimeDimension('id_entity__id_dim', 'day') }} > '2020-01-01'\"\n        )\n\n\nclass TestTopLevelSemanticsMetricWithDocJinja:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": base_schema_yml_v2\n            + schema_yml_v2_simple_metric_on_model_1\n            + schema_yml_v2_standalone_metrics_with_doc_jinja,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"docs.md\": semantic_model_descriptions,\n        }\n\n    def test_top_level_metric_with_doc_jinja_parsing(self, project):\n        runner = dbtTestRunner()\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        manifest = result.result\n        assert len(manifest.semantic_models) == 1\n        metric = manifest.metrics[\"metric.test.standalone_conversion_metric\"]\n        assert metric.description == \"describe away!\"\n        assert (\n            metric.filter.where_filters[0].where_sql_template\n            == \"{{ Dimension('id_entity__id_dim') }} > 0\"\n        )\n\n        semantic_manifest = SemanticManifest(manifest)\n        semantic_manifest_metrics = {\n            metric.name: metric\n            for metric in semantic_manifest._get_pydantic_semantic_manifest().metrics\n        }\n        assert (\n            semantic_manifest_metrics[\"standalone_conversion_metric\"]\n            .filter.where_filters[0]\n            .where_sql_template\n            == \"{{ Dimension('id_entity__id_dim') }} > 0\"\n        )\n\n\nclass TestDerivedMetricWithInputMetricsFilterDimensionJinja:\n    \"\"\"Test that {{ Dimension(...) }} jinja in input_metrics[].filter is not rendered at parse time.\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": base_schema_yml_v2\n            + schema_yml_v2_metric_with_input_metrics_filter_dimension_jinja,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n        }\n\n    def test_input_metrics_filter_jinja_not_rendered(self, project):\n        runner = dbtTestRunner()\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        manifest = result.result\n        metric = manifest.metrics[\"metric.test.derived_metric_with_jinja_filter\"]\n        assert metric.type == MetricType.DERIVED\n        # The input metric filter should preserve the Dimension jinja template\n        offset_input = [m for m in metric.type_params.metrics if m.alias == \"offset_metric\"][0]\n        assert \"{{ Dimension('id_entity__id_dim') }} > 0\" in (\n            offset_input.filter.where_filters[0].where_sql_template\n        )\n\n\nclass TestRatioMetricWithNumeratorFilterDimensionJinja:\n    \"\"\"Test that {{ Dimension(...) }} jinja in numerator.filter is not rendered at parse time.\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": base_schema_yml_v2\n            + schema_yml_v2_metric_with_numerator_filter_dimension_jinja,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n        }\n\n    def test_numerator_filter_jinja_not_rendered(self, project):\n        runner = dbtTestRunner()\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        manifest = result.result\n        metric = manifest.metrics[\"metric.test.ratio_metric_with_jinja_filter\"]\n        assert metric.type == MetricType.RATIO\n        # The numerator filter should preserve the Dimension jinja template\n        assert \"{{ Dimension('id_entity__id_dim') }} > 0\" in (\n            metric.type_params.numerator.filter.where_filters[0].where_sql_template\n        )\n\n\nclass TestMetricOnModelWithCustomSemanticModelName:\n    \"\"\"Test that metrics correctly reference the custom semantic model name when\n    semantic_model.name is set, rather than using the dbt model name.\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": base_schema_yml_v2_with_custom_sm_name\n            + schema_yml_v2_simple_metric_on_model_1,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n        }\n\n    def test_metrics_use_custom_semantic_model_name(self, project):\n        runner = dbtTestRunner()\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        manifest = result.result\n\n        # Semantic model should be registered under the custom name\n        assert \"semantic_model.test.custom_semantic_model\" in manifest.semantic_models\n        semantic_model = manifest.semantic_models[\"semantic_model.test.custom_semantic_model\"]\n        assert semantic_model.name == \"custom_semantic_model\"\n        # But it still points to the fct_revenue model\n        assert semantic_model.node_relation.alias == \"fct_revenue\"\n\n        # Simple metrics should reference the custom semantic model name\n        simple_metric = manifest.metrics[\"metric.test.simple_metric\"]\n        assert (\n            simple_metric.type_params.metric_aggregation_params.semantic_model\n            == \"custom_semantic_model\"\n        )\n        assert \"semantic_model.test.custom_semantic_model\" in simple_metric.depends_on.nodes\n\n        simple_metric_2 = manifest.metrics[\"metric.test.simple_metric_2\"]\n        assert (\n            simple_metric_2.type_params.metric_aggregation_params.semantic_model\n            == \"custom_semantic_model\"\n        )\n        assert \"semantic_model.test.custom_semantic_model\" in simple_metric_2.depends_on.nodes\n\n        # Conversion metric should pass validation (it references simple metrics\n        # which are linked to the custom-named semantic model)\n        conversion_metric = manifest.metrics[\"metric.test.conversion_metric\"]\n        assert conversion_metric.type == MetricType.CONVERSION\n        assert (\n            conversion_metric.type_params.conversion_type_params.base_metric.name\n            == \"simple_metric\"\n        )\n        assert (\n            conversion_metric.type_params.conversion_type_params.conversion_metric.name\n            == \"simple_metric_2\"\n        )\n\n        # Verify semantic manifest validation also passes\n        semantic_manifest = SemanticManifest(manifest)\n        semantic_manifest_metrics = {\n            metric.name: metric\n            for metric in semantic_manifest._get_pydantic_semantic_manifest().metrics\n        }\n        assert (\n            semantic_manifest_metrics[\n                \"simple_metric\"\n            ].type_params.metric_aggregation_params.semantic_model\n            == \"custom_semantic_model\"\n        )\n\n\nclass TestMetricOnModelWithoutCustomSemanticModelName:\n    \"\"\"Test that metrics correctly use the dbt model name as the semantic model name\n    when no custom semantic_model.name is set (semantic_model: true).\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": base_schema_yml_v2 + schema_yml_v2_simple_metric_on_model_1,\n            \"fct_revenue.sql\": fct_revenue_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n        }\n\n    def test_metrics_use_model_name_as_semantic_model_name(self, project):\n        runner = dbtTestRunner()\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        manifest = result.result\n\n        # Semantic model should be registered under the model name\n        assert \"semantic_model.test.fct_revenue\" in manifest.semantic_models\n\n        # Simple metrics should reference the model name\n        simple_metric = manifest.metrics[\"metric.test.simple_metric\"]\n        assert simple_metric.type_params.metric_aggregation_params.semantic_model == \"fct_revenue\"\n        assert \"semantic_model.test.fct_revenue\" in simple_metric.depends_on.nodes\n\n        # Conversion metric should pass validation\n        conversion_metric = manifest.metrics[\"metric.test.conversion_metric\"]\n        assert conversion_metric.type == MetricType.CONVERSION\n        assert (\n            conversion_metric.type_params.conversion_type_params.base_metric.name\n            == \"simple_metric\"\n        )\n\n        # Verify semantic manifest validation also passes\n        semantic_manifest = SemanticManifest(manifest)\n        semantic_manifest_metrics = {\n            metric.name: metric\n            for metric in semantic_manifest._get_pydantic_semantic_manifest().metrics\n        }\n        assert (\n            semantic_manifest_metrics[\n                \"simple_metric\"\n            ].type_params.metric_aggregation_params.semantic_model\n            == \"fct_revenue\"\n        )\n\n\n# TODO DI-4605: add enforcement and a test for when there are validity params with no column granularity\n# TODO DI-4603: add enforcement and a test for a TIME type dimension and a column that has no granularity set\n"
  },
  {
    "path": "tests/functional/semantic_models/test_semantic_models.py",
    "content": "import pytest\n\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.exceptions import CompilationError\nfrom dbt.tests.util import run_dbt, write_file\nfrom tests.functional.semantic_models.fixtures import (\n    models_people_metrics_yml,\n    models_people_sql,\n    semantic_model_descriptions,\n    semantic_model_people_diff_name_yml,\n    semantic_model_people_yml,\n    semantic_model_people_yml_with_docs,\n    simple_metricflow_time_spine_sql,\n)\n\n\nclass TestSemanticModelDependsOn:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"people.sql\": models_people_sql,\n            \"metricflow_time_spine.sql\": simple_metricflow_time_spine_sql,\n            \"semantic_models.yml\": semantic_model_people_yml,\n            \"people_metrics.yml\": models_people_metrics_yml,\n        }\n\n    def test_depends_on(self, project):\n        manifest = run_dbt([\"parse\"])\n        assert isinstance(manifest, Manifest)\n\n        expected_depends_on_for_people_semantic_model = [\"model.test.people\"]\n\n        number_of_people_metric = manifest.semantic_models[\"semantic_model.test.semantic_people\"]\n        assert (\n            number_of_people_metric.depends_on.nodes\n            == expected_depends_on_for_people_semantic_model\n        )\n\n\nclass TestSemanticModelNestedDocs:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"people.sql\": models_people_sql,\n            \"metricflow_time_spine.sql\": simple_metricflow_time_spine_sql,\n            \"semantic_models.yml\": semantic_model_people_yml_with_docs,\n            \"people_metrics.yml\": models_people_metrics_yml,\n            \"docs.md\": semantic_model_descriptions,\n        }\n\n    def test_depends_on(self, project):\n        manifest = run_dbt([\"parse\"])\n        node = manifest.semantic_models[\"semantic_model.test.semantic_people\"]\n\n        assert node.description == \"foo\"\n        assert node.dimensions[0].description == \"bar\"\n        assert node.measures[0].description == \"baz\"\n        assert node.entities[0].description == \"qux\"\n\n\nclass TestSemanticModelUnknownModel:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"not_people.sql\": models_people_sql,\n            \"metricflow_time_spine.sql\": simple_metricflow_time_spine_sql,\n            \"semantic_models.yml\": semantic_model_people_yml,\n            \"people_metrics.yml\": models_people_metrics_yml,\n        }\n\n    def test_unknown_model_raises_issue(self, project):\n        with pytest.raises(CompilationError) as excinfo:\n            run_dbt([\"parse\"])\n        assert \"depends on a node named 'people' which was not found\" in str(excinfo.value)\n\n\nclass TestSemanticModelPartialParsing:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"people.sql\": models_people_sql,\n            \"metricflow_time_spine.sql\": simple_metricflow_time_spine_sql,\n            \"semantic_models.yml\": semantic_model_people_yml,\n            \"people_metrics.yml\": models_people_metrics_yml,\n        }\n\n    def test_semantic_model_deleted_partial_parsing(self, project):\n        # First, use the default saved_queries.yml to define our saved_query, and\n        # run the dbt parse command\n        run_dbt([\"parse\"])\n        # Next, modify the default semantic_models.yml to remove the saved query.\n        write_file(\n            semantic_model_people_diff_name_yml,\n            project.project_root,\n            \"models\",\n            \"semantic_models.yml\",\n        )\n        run_dbt([\"compile\"])\n"
  },
  {
    "path": "tests/functional/severity/test_severity.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt\n\nmodels__sample_model_sql = \"\"\"\nselect * from {{ source(\"raw\", \"sample_seed\") }}\n\"\"\"\n\nmodels__schema_yml = \"\"\"\nversion: 2\nsources:\n  - name: raw\n    database: \"{{ target.database }}\"\n    schema: \"{{ target.schema }}\"\n    tables:\n      - name: sample_seed\n        columns:\n          - name: email\n            data_tests:\n              - not_null:\n                  severity: \"{{ 'error' if var('strict', false) else 'warn' }}\"\nmodels:\n  - name: sample_model\n    columns:\n      - name: email\n        data_tests:\n          - not_null:\n              severity: \"{{ 'error' if var('strict', false) else 'warn' }}\"\n\"\"\"\n\nseeds__sample_seed_csv = \"\"\"id,first_name,last_name,email,gender,ip_address,updated_at\n1,Judith,Kennedy,jkennedy0@phpbb.com,Female,54.60.24.128,2015-12-24 12:19:28\n2,Arthur,Kelly,akelly1@eepurl.com,Male,62.56.24.215,2015-10-28 16:22:15\n3,Rachel,Moreno,rmoreno2@msu.edu,Female,31.222.249.23,2016-04-05 02:05:30\n4,Ralph,Turner,rturner3@hp.com,Male,157.83.76.114,2016-08-08 00:06:51\n5,Laura,Gonzales,lgonzales4@howstuffworks.com,Female,30.54.105.168,2016-09-01 08:25:38\n6,Katherine,Lopez,null,Female,169.138.46.89,2016-08-30 18:52:11\n7,Jeremy,Hamilton,jhamilton6@mozilla.org,Male,231.189.13.133,2016-07-17 02:09:46\n8,Heather,Rose,hrose7@goodreads.com,Female,87.165.201.65,2015-12-29 22:03:56\n9,Gregory,Kelly,gkelly8@trellian.com,Male,154.209.99.7,2016-03-24 21:18:16\n10,Rachel,Lopez,rlopez9@themeforest.net,Female,237.165.82.71,2016-08-20 15:44:49\n11,Donna,Welch,dwelcha@shutterfly.com,Female,103.33.110.138,2016-02-27 01:41:48\n12,Russell,Lawrence,rlawrenceb@qq.com,Male,189.115.73.4,2016-06-11 03:07:09\n13,Michelle,Montgomery,mmontgomeryc@scientificamerican.com,Female,243.220.95.82,2016-06-18 16:27:19\n14,Walter,Castillo,null,Male,71.159.238.196,2016-10-06 01:55:44\n15,Robin,Mills,rmillse@vkontakte.ru,Female,172.190.5.50,2016-10-31 11:41:21\n16,Raymond,Holmes,rholmesf@usgs.gov,Male,148.153.166.95,2016-10-03 08:16:38\n17,Gary,Bishop,gbishopg@plala.or.jp,Male,161.108.182.13,2016-08-29 19:35:20\n18,Anna,Riley,arileyh@nasa.gov,Female,253.31.108.22,2015-12-11 04:34:27\n19,Sarah,Knight,sknighti@foxnews.com,Female,222.220.3.177,2016-09-26 00:49:06\n20,Phyllis,Fox,pfoxj@creativecommons.org,Female,163.191.232.95,2016-08-21 10:35:19\n\"\"\"\n\n\ntests__sample_test_sql = \"\"\"\n{{ config(severity='error' if var('strict', false) else 'warn') }}\nselect * from {{ ref(\"sample_model\") }} where email is null\n\"\"\"\n\n\n@pytest.fixture(scope=\"class\")\ndef models():\n    return {\"sample_model.sql\": models__sample_model_sql, \"schema.yml\": models__schema_yml}\n\n\n@pytest.fixture(scope=\"class\")\ndef seeds():\n    return {\"sample_seed.csv\": seeds__sample_seed_csv}\n\n\n@pytest.fixture(scope=\"class\")\ndef tests():\n    return {\"null_email.sql\": tests__sample_test_sql}\n\n\n@pytest.fixture(scope=\"class\")\ndef project_config_update():\n    return {\n        \"config-version\": 2,\n        \"seed-paths\": [\"seeds\"],\n        \"test-paths\": [\"tests\"],\n        \"seeds\": {\n            \"quote_columns\": False,\n        },\n    }\n\n\nclass TestSeverity:\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def seed_and_run(self, project):\n        run_dbt([\"seed\"])\n        run_dbt([\"run\"])\n\n    def test_generic_default(self, project):\n        results = run_dbt([\"test\", \"--select\", \"test_type:generic\"])\n        assert len(results) == 2\n        assert all([r.status == \"warn\" for r in results])\n        assert all([r.failures == 2 for r in results])\n\n    def test_generic_strict(self, project):\n        results = run_dbt(\n            [\"test\", \"--select\", \"test_type:generic\", \"--vars\", '{\"strict\": True}'],\n            expect_pass=False,\n        )\n        assert len(results) == 2\n        assert all([r.status == \"fail\" for r in results])\n        assert all([r.failures == 2 for r in results])\n\n    def test_singular_default(self, project):\n        results = run_dbt([\"test\", \"--select\", \"test_type:singular\"])\n        assert len(results) == 1\n        assert all([r.status == \"warn\" for r in results])\n        assert all([r.failures == 2 for r in results])\n\n    def test_singular_strict(self, project):\n        results = run_dbt(\n            [\"test\", \"--select\", \"test_type:singular\", \"--vars\", '{\"strict\": True}'],\n            expect_pass=False,\n        )\n        assert len(results) == 1\n        assert all([r.status == \"fail\" for r in results])\n        assert all([r.failures == 2 for r in results])\n"
  },
  {
    "path": "tests/functional/show/fixtures.py",
    "content": "models__sample_model = \"\"\"\nselect * from {{ ref('sample_seed') }}\n\"\"\"\n\nmodels__sample_number_model = \"\"\"\nselect\n  cast(1.0 as int) as float_to_int_field,\n  3.0 as float_field,\n  4.3 as float_with_dec_field,\n  5 as int_field\n\"\"\"\n\nmodels__sample_number_model_with_nulls = \"\"\"\nselect\n  cast(1.0 as int) as float_to_int_field,\n  3.0 as float_field,\n  4.3 as float_with_dec_field,\n  5 as int_field\n\nunion all\n\nselect\n  cast(null as int) as float_to_int_field,\n  cast(null as float) as float_field,\n  cast(null as float) as float_with_dec_field,\n  cast(null as int) as int_field\n\n\"\"\"\n\nmodels__second_model = \"\"\"\nselect\n    sample_num as col_one,\n    sample_bool as col_two,\n    42 as answer\nfrom {{ ref('sample_model') }}\n\"\"\"\n\nmodels__sql_header = \"\"\"\n{% call set_sql_header(config) %}\nset session time zone '{{ var(\"timezone\", \"Europe/Paris\") }}';\n{%- endcall %}\nselect current_setting('timezone') as timezone\n\"\"\"\n\nprivate_model_yml = \"\"\"\ngroups:\n  - name: my_cool_group\n    owner: {name: me}\n\nmodels:\n  - name: private_model\n    access: private\n    config:\n      group: my_cool_group\n\"\"\"\n\n\nschema_yml = \"\"\"\nmodels:\n  - name: sample_model\n    latest_version: 1\n\n    # declare the versions, and fully specify them\n    versions:\n      - v: 2\n        config:\n          materialized: table\n        columns:\n          - name: sample_num\n            data_type: int\n          - name: sample_bool\n            data_type: bool\n          - name: answer\n            data_type: int\n\n      - v: 1\n        config:\n          materialized: table\n          contract: {enforced: true}\n        columns:\n          - name: sample_num\n            data_type: int\n          - name: sample_bool\n            data_type: bool\n\"\"\"\n\nmodels__ephemeral_model = \"\"\"\n{{ config(materialized = 'ephemeral') }}\nselect\n    coalesce(sample_num, 0) + 10 as col_deci\nfrom {{ ref('sample_model') }}\n\"\"\"\n\nmodels__second_ephemeral_model = \"\"\"\n{{ config(materialized = 'ephemeral') }}\nselect\n    col_deci + 100 as col_hundo\nfrom {{ ref('ephemeral_model') }}\n\"\"\"\n\nseeds__sample_seed = \"\"\"sample_num,sample_bool\n1,true\n2,false\n3,true\n4,false\n5,true\n6,false\n7,true\n\"\"\"\n"
  },
  {
    "path": "tests/functional/show/test_show.py",
    "content": "import json\n\nimport pytest\n\nfrom dbt.tests.util import run_dbt, run_dbt_and_capture\nfrom dbt_common.exceptions import DbtBaseException as DbtException\nfrom dbt_common.exceptions import DbtRuntimeError\nfrom tests.functional.show.fixtures import (\n    models__ephemeral_model,\n    models__sample_model,\n    models__sample_number_model,\n    models__sample_number_model_with_nulls,\n    models__second_ephemeral_model,\n    models__second_model,\n    private_model_yml,\n    schema_yml,\n    seeds__sample_seed,\n)\n\n\nclass ShowBase:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"sample_model.sql\": models__sample_model,\n            \"sample_number_model.sql\": models__sample_number_model,\n            \"sample_number_model_with_nulls.sql\": models__sample_number_model_with_nulls,\n            \"second_model.sql\": models__second_model,\n            \"ephemeral_model.sql\": models__ephemeral_model,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\"sample_seed.csv\": seeds__sample_seed}\n\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setup(self, project):\n        run_dbt([\"seed\"])\n\n\nclass TestShowNone(ShowBase):\n    def test_none(self, project):\n        with pytest.raises(\n            DbtRuntimeError, match=\"Either --select or --inline must be passed to show\"\n        ):\n            run_dbt([\"show\"])\n\n\nclass TestShowSelectText(ShowBase):\n    def test_select_model_text(self, project):\n        run_dbt([\"build\"])\n        (_, log_output) = run_dbt_and_capture([\"show\", \"--select\", \"second_model\"])\n        assert \"Previewing node 'sample_model'\" not in log_output\n        assert \"Previewing node 'second_model'\" in log_output\n        assert \"col_one\" in log_output\n        assert \"col_two\" in log_output\n        assert \"answer\" in log_output\n\n\nclass TestShowMultiple(ShowBase):\n    def test_select_multiple_model_text(self, project):\n        run_dbt([\"build\"])\n        (_, log_output) = run_dbt_and_capture([\"show\", \"--select\", \"sample_model second_model\"])\n        assert \"Previewing node 'sample_model'\" in log_output\n        assert \"sample_num\" in log_output\n        assert \"sample_bool\" in log_output\n\n\nclass TestShowSingle(ShowBase):\n    def test_select_single_model_json(self, project):\n        run_dbt([\"build\"])\n        (_, log_output) = run_dbt_and_capture(\n            [\"show\", \"--select\", \"sample_model\", \"--output\", \"json\"]\n        )\n        assert \"Previewing node 'sample_model'\" not in log_output\n        assert \"sample_num\" in log_output\n        assert \"sample_bool\" in log_output\n        with pytest.raises(json.JSONDecodeError):\n            json.loads(log_output)\n\n    def test_select_single_model_json_quiet(self, project):\n        run_dbt([\"build\"])\n        (_, log_output) = run_dbt_and_capture(\n            [\"show\", \"--quiet\", \"--select\", \"sample_model\", \"--output\", \"json\"]\n        )\n        assert \"Previewing node 'sample_model'\" not in log_output\n        assert \"sample_num\" in log_output\n        assert \"sample_bool\" in log_output\n        json.loads(log_output)\n\n\nclass TestShowNumeric(ShowBase):\n    def test_numeric_values(self, project):\n        run_dbt([\"build\"])\n        (_, log_output) = run_dbt_and_capture(\n            [\"show\", \"--select\", \"sample_number_model\", \"--output\", \"json\"]\n        )\n        # json log output needs the escapes removed for string matching\n        log_output = log_output.replace(\"\\\\\", \"\")\n        assert \"Previewing node 'sample_number_model'\" not in log_output\n        assert '\"float_to_int_field\": 1.0' not in log_output\n        assert '\"float_to_int_field\": 1' in log_output\n        assert '\"float_field\": 3.0' in log_output\n        assert '\"float_with_dec_field\": 4.3' in log_output\n        assert '\"int_field\": 5' in log_output\n        assert '\"int_field\": 5.0' not in log_output\n\n\nclass TestShowNumericNulls(ShowBase):\n    def test_numeric_values_with_nulls(self, project):\n        run_dbt([\"build\"])\n        (_, log_output) = run_dbt_and_capture(\n            [\"show\", \"--select\", \"sample_number_model_with_nulls\", \"--output\", \"json\"]\n        )\n        # json log output needs the escapes removed for string matching\n        log_output = log_output.replace(\"\\\\\", \"\")\n        assert \"Previewing node 'sample_number_model_with_nulls'\" not in log_output\n        assert '\"float_to_int_field\": 1.0' not in log_output\n        assert '\"float_to_int_field\": 1' in log_output\n        assert '\"float_field\": 3.0' in log_output\n        assert '\"float_with_dec_field\": 4.3' in log_output\n        assert '\"int_field\": 5' in log_output\n        assert '\"int_field\": 5.0' not in log_output\n\n\nclass TestShowInline(ShowBase):\n    def test_inline_pass(self, project):\n        run_dbt([\"build\"])\n        (_, log_output) = run_dbt_and_capture(\n            [\"show\", \"--inline\", \"select * from {{ ref('sample_model') }}\"]\n        )\n        assert \"Previewing inline node\" in log_output\n        assert \"sample_num\" in log_output\n        assert \"sample_bool\" in log_output\n\n    def test_inline_pass_quiet(self, project):\n        run_dbt([\"build\"])\n        (_, log_output) = run_dbt_and_capture(\n            [\"show\", \"--quiet\", \"--inline\", \"select * from {{ ref('sample_model') }}\"]\n        )\n        assert \"Previewing inline node\" not in log_output\n        assert \"sample_num\" in log_output\n        assert \"sample_bool\" in log_output\n\n\nclass TestShowInlineFail(ShowBase):\n    def test_inline_fail(self, project):\n        with pytest.raises(DbtException, match=\"Error parsing inline query\"):\n            run_dbt([\"show\", \"--inline\", \"select * from {{ ref('third_model') }}\"])\n\n\nclass TestShowInlineFailDB(ShowBase):\n    def test_inline_fail_database_error(self, project):\n        with pytest.raises(DbtRuntimeError, match=\"Database Error\"):\n            run_dbt([\"show\", \"--inline\", \"slect asdlkjfsld;j\"])\n\n\nclass TestShowInlineDirect(ShowBase):\n\n    def test_inline_direct_pass(self, project):\n        query = f\"select * from {project.test_schema}.sample_seed\"\n        (_, log_output) = run_dbt_and_capture([\"show\", \"--inline-direct\", query])\n        assert \"Previewing inline node\" in log_output\n        assert \"sample_num\" in log_output\n        assert \"sample_bool\" in log_output\n\n        # This is a bit of a hack. Unfortunately, the test teardown code\n        # expects that dbt loaded an adapter with a macro context the last\n        # time it was called. The '--inline-direct' parameter used on the\n        # previous run explicitly disables macros. So now we call 'dbt seed',\n        # which will load the adapter fully and satisfy the teardown code.\n        run_dbt([\"seed\"])\n\n    def test_inline_direct_pass_quiet(self, project):\n        query = f\"select * from {project.test_schema}.sample_seed\"\n        (_, log_output) = run_dbt_and_capture([\"show\", \"--quiet\", \"--inline-direct\", query])\n        assert \"Previewing inline node\" not in log_output\n        assert \"sample_num\" in log_output\n        assert \"sample_bool\" in log_output\n\n        # See prior test for explanation of why this is here\n        run_dbt([\"seed\"])\n\n    def test_inline_direct_pass_no_limit(self, project):\n        query = f\"select * from {project.test_schema}.sample_seed\"\n        (_, log_output) = run_dbt_and_capture([\"show\", \"--inline-direct\", query, \"--limit\", -1])\n        assert \"Previewing inline node\" in log_output\n        assert \"sample_num\" in log_output\n        assert \"sample_bool\" in log_output\n\n        # See prior test for explanation of why this is here\n        run_dbt([\"seed\"])\n\n\nclass TestShowInlineDirectFail(ShowBase):\n\n    def test_inline_fail_database_error(self, project):\n        with pytest.raises(DbtRuntimeError, match=\"Database Error\"):\n            run_dbt([\"show\", \"--inline-direct\", \"slect asdlkjfsld;j\"])\n\n        # See prior test for explanation of why this is here\n        run_dbt([\"seed\"])\n\n\nclass TestShowEphemeral(ShowBase):\n    def test_ephemeral_model(self, project):\n        run_dbt([\"build\"])\n        (_, log_output) = run_dbt_and_capture([\"show\", \"--select\", \"ephemeral_model\"])\n        assert \"col_deci\" in log_output\n\n\nclass TestShowSecondEphemeral(ShowBase):\n    def test_second_ephemeral_model(self, project):\n        run_dbt([\"build\"])\n        (_, log_output) = run_dbt_and_capture([\"show\", \"--inline\", models__second_ephemeral_model])\n        assert \"col_hundo\" in log_output\n\n\nclass TestShowSeed(ShowBase):\n    def test_seed(self, project):\n        (_, log_output) = run_dbt_and_capture([\"show\", \"--select\", \"sample_seed\"])\n        assert \"Previewing node 'sample_seed'\" in log_output\n\n\nclass TestShowModelVersions:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": schema_yml,\n            \"sample_model.sql\": models__sample_model,\n            \"sample_model_v2.sql\": models__second_model,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\"sample_seed.csv\": seeds__sample_seed}\n\n    def test_version_unspecified(self, project):\n        run_dbt([\"build\"])\n        (results, log_output) = run_dbt_and_capture([\"show\", \"--select\", \"sample_model\"])\n        assert \"Previewing node 'sample_model.v1'\" in log_output\n        assert \"Previewing node 'sample_model.v2'\" in log_output\n\n    def test_none(self, project):\n        run_dbt([\"build\"])\n        (results, log_output) = run_dbt_and_capture([\"show\", \"--select\", \"sample_model.v2\"])\n        assert \"Previewing node 'sample_model.v1'\" not in log_output\n        assert \"Previewing node 'sample_model.v2'\" in log_output\n\n\nclass TestShowPrivateModel:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": private_model_yml,\n            \"private_model.sql\": models__sample_model,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\"sample_seed.csv\": seeds__sample_seed}\n\n    def test_version_unspecified(self, project):\n        run_dbt([\"build\"])\n        run_dbt([\"show\", \"--inline\", \"select * from {{ ref('private_model') }}\"])\n"
  },
  {
    "path": "tests/functional/snapshots/data/invalidate_postgres.sql",
    "content": "\n-- update records 11 - 21. Change email and updated_at field\nupdate {schema}.seed set\n    updated_at = updated_at + interval '1 hour',\n    email      =  case when id = 20 then 'pfoxj@creativecommons.org' else 'new_' || email end\nwhere id >= 10 and id <= 20;\n\n\n-- invalidate records 11 - 21\nupdate {schema}.snapshot_expected set\n    dbt_valid_to   = updated_at + interval '1 hour'\nwhere id >= 10 and id <= 20;\n\n\nupdate {schema}.snapshot_castillo_expected set\n    dbt_valid_to   = \"1-updated_at\" + interval '1 hour'\nwhere id >= 10 and id <= 20;\n\n\nupdate {schema}.snapshot_alvarez_expected set\n    dbt_valid_to   = updated_at + interval '1 hour'\nwhere id >= 10 and id <= 20;\n\n\nupdate {schema}.snapshot_kelly_expected set\n    dbt_valid_to   = updated_at + interval '1 hour'\nwhere id >= 10 and id <= 20;\n"
  },
  {
    "path": "tests/functional/snapshots/data/seed_cn.sql",
    "content": "create table {database}.{schema}.seed (\n\tid INTEGER,\n\tfirst_name VARCHAR(50),\n\tlast_name VARCHAR(50),\n\temail VARCHAR(50),\n\tgender VARCHAR(50),\n\tip_address VARCHAR(20),\n\tupdated_at TIMESTAMP WITHOUT TIME ZONE\n);\n\ncreate table {database}.{schema}.snapshot_expected (\n\tid INTEGER,\n\tfirst_name VARCHAR(50),\n\tlast_name VARCHAR(50),\n\temail VARCHAR(50),\n\tgender VARCHAR(50),\n\tip_address VARCHAR(20),\n\n\t-- snapshotting fields\n\tupdated_at TIMESTAMP WITHOUT TIME ZONE,\n\ttest_valid_from TIMESTAMP WITHOUT TIME ZONE,\n\ttest_valid_to   TIMESTAMP WITHOUT TIME ZONE,\n\ttest_scd_id     TEXT,\n\ttest_updated_at TIMESTAMP WITHOUT TIME ZONE\n);\n\n\n-- seed inserts\n--  use the same email for two users to verify that duplicated check_cols values\n--  are handled appropriately\ninsert into {database}.{schema}.seed (id, first_name, last_name, email, gender, ip_address, updated_at) values\n(1, 'Judith', 'Kennedy', '(not provided)', 'Female', '54.60.24.128', '2015-12-24 12:19:28'),\n(2, 'Arthur', 'Kelly', '(not provided)', 'Male', '62.56.24.215', '2015-10-28 16:22:15'),\n(3, 'Rachel', 'Moreno', 'rmoreno2@msu.edu', 'Female', '31.222.249.23', '2016-04-05 02:05:30'),\n(4, 'Ralph', 'Turner', 'rturner3@hp.com', 'Male', '157.83.76.114', '2016-08-08 00:06:51'),\n(5, 'Laura', 'Gonzales', 'lgonzales4@howstuffworks.com', 'Female', '30.54.105.168', '2016-09-01 08:25:38'),\n(6, 'Katherine', 'Lopez', 'klopez5@yahoo.co.jp', 'Female', '169.138.46.89', '2016-08-30 18:52:11'),\n(7, 'Jeremy', 'Hamilton', 'jhamilton6@mozilla.org', 'Male', '231.189.13.133', '2016-07-17 02:09:46'),\n(8, 'Heather', 'Rose', 'hrose7@goodreads.com', 'Female', '87.165.201.65', '2015-12-29 22:03:56'),\n(9, 'Gregory', 'Kelly', 'gkelly8@trellian.com', 'Male', '154.209.99.7', '2016-03-24 21:18:16'),\n(10, 'Rachel', 'Lopez', 'rlopez9@themeforest.net', 'Female', '237.165.82.71', '2016-08-20 15:44:49'),\n(11, 'Donna', 'Welch', 'dwelcha@shutterfly.com', 'Female', '103.33.110.138', '2016-02-27 01:41:48'),\n(12, 'Russell', 'Lawrence', 'rlawrenceb@qq.com', 'Male', '189.115.73.4', '2016-06-11 03:07:09'),\n(13, 'Michelle', 'Montgomery', 'mmontgomeryc@scientificamerican.com', 'Female', '243.220.95.82', '2016-06-18 16:27:19'),\n(14, 'Walter', 'Castillo', 'wcastillod@pagesperso-orange.fr', 'Male', '71.159.238.196', '2016-10-06 01:55:44'),\n(15, 'Robin', 'Mills', 'rmillse@vkontakte.ru', 'Female', '172.190.5.50', '2016-10-31 11:41:21'),\n(16, 'Raymond', 'Holmes', 'rholmesf@usgs.gov', 'Male', '148.153.166.95', '2016-10-03 08:16:38'),\n(17, 'Gary', 'Bishop', 'gbishopg@plala.or.jp', 'Male', '161.108.182.13', '2016-08-29 19:35:20'),\n(18, 'Anna', 'Riley', 'arileyh@nasa.gov', 'Female', '253.31.108.22', '2015-12-11 04:34:27'),\n(19, 'Sarah', 'Knight', 'sknighti@foxnews.com', 'Female', '222.220.3.177', '2016-09-26 00:49:06'),\n(20, 'Phyllis', 'Fox', null, 'Female', '163.191.232.95', '2016-08-21 10:35:19');\n\n\n-- populate snapshot table\ninsert into {database}.{schema}.snapshot_expected (\n    id,\n    first_name,\n    last_name,\n    email,\n    gender,\n    ip_address,\n    updated_at,\n    test_valid_from,\n    test_valid_to,\n    test_updated_at,\n    test_scd_id\n)\n\nselect\n    id,\n    first_name,\n    last_name,\n    email,\n    gender,\n    ip_address,\n    updated_at,\n    -- fields added by snapshotting\n    updated_at as test_valid_from,\n    null::timestamp as test_valid_to,\n    updated_at as test_updated_at,\n    md5(id || '-' || first_name || '|' || updated_at::text) as test_scd_id\nfrom {database}.{schema}.seed;\n"
  },
  {
    "path": "tests/functional/snapshots/data/seed_dbt_valid_to.sql",
    "content": "create table {database}.{schema}.seed (\n\tid INTEGER,\n\tfirst_name VARCHAR(50),\n\tlast_name VARCHAR(50),\n\temail VARCHAR(50),\n\tgender VARCHAR(50),\n\tip_address VARCHAR(20),\n\tupdated_at TIMESTAMP WITHOUT TIME ZONE\n);\n\ncreate table {database}.{schema}.snapshot_expected (\n\tid INTEGER,\n\tfirst_name VARCHAR(50),\n\tlast_name VARCHAR(50),\n\temail VARCHAR(50),\n\tgender VARCHAR(50),\n\tip_address VARCHAR(20),\n\n\t-- snapshotting fields\n\tupdated_at TIMESTAMP WITHOUT TIME ZONE,\n\ttest_valid_from TIMESTAMP WITHOUT TIME ZONE,\n\ttest_valid_to   TIMESTAMP WITHOUT TIME ZONE,\n\ttest_scd_id     TEXT,\n\ttest_updated_at TIMESTAMP WITHOUT TIME ZONE\n);\n\n\n-- seed inserts\n--  use the same email for two users to verify that duplicated check_cols values\n--  are handled appropriately\ninsert into {database}.{schema}.seed (id, first_name, last_name, email, gender, ip_address, updated_at) values\n(1, 'Judith', 'Kennedy', '(not provided)', 'Female', '54.60.24.128', '2015-12-24 12:19:28'),\n(2, 'Arthur', 'Kelly', '(not provided)', 'Male', '62.56.24.215', '2015-10-28 16:22:15'),\n(3, 'Rachel', 'Moreno', 'rmoreno2@msu.edu', 'Female', '31.222.249.23', '2016-04-05 02:05:30'),\n(4, 'Ralph', 'Turner', 'rturner3@hp.com', 'Male', '157.83.76.114', '2016-08-08 00:06:51'),\n(5, 'Laura', 'Gonzales', 'lgonzales4@howstuffworks.com', 'Female', '30.54.105.168', '2016-09-01 08:25:38'),\n(6, 'Katherine', 'Lopez', 'klopez5@yahoo.co.jp', 'Female', '169.138.46.89', '2016-08-30 18:52:11'),\n(7, 'Jeremy', 'Hamilton', 'jhamilton6@mozilla.org', 'Male', '231.189.13.133', '2016-07-17 02:09:46'),\n(8, 'Heather', 'Rose', 'hrose7@goodreads.com', 'Female', '87.165.201.65', '2015-12-29 22:03:56'),\n(9, 'Gregory', 'Kelly', 'gkelly8@trellian.com', 'Male', '154.209.99.7', '2016-03-24 21:18:16'),\n(10, 'Rachel', 'Lopez', 'rlopez9@themeforest.net', 'Female', '237.165.82.71', '2016-08-20 15:44:49'),\n(11, 'Donna', 'Welch', 'dwelcha@shutterfly.com', 'Female', '103.33.110.138', '2016-02-27 01:41:48'),\n(12, 'Russell', 'Lawrence', 'rlawrenceb@qq.com', 'Male', '189.115.73.4', '2016-06-11 03:07:09'),\n(13, 'Michelle', 'Montgomery', 'mmontgomeryc@scientificamerican.com', 'Female', '243.220.95.82', '2016-06-18 16:27:19'),\n(14, 'Walter', 'Castillo', 'wcastillod@pagesperso-orange.fr', 'Male', '71.159.238.196', '2016-10-06 01:55:44'),\n(15, 'Robin', 'Mills', 'rmillse@vkontakte.ru', 'Female', '172.190.5.50', '2016-10-31 11:41:21'),\n(16, 'Raymond', 'Holmes', 'rholmesf@usgs.gov', 'Male', '148.153.166.95', '2016-10-03 08:16:38'),\n(17, 'Gary', 'Bishop', 'gbishopg@plala.or.jp', 'Male', '161.108.182.13', '2016-08-29 19:35:20'),\n(18, 'Anna', 'Riley', 'arileyh@nasa.gov', 'Female', '253.31.108.22', '2015-12-11 04:34:27'),\n(19, 'Sarah', 'Knight', 'sknighti@foxnews.com', 'Female', '222.220.3.177', '2016-09-26 00:49:06'),\n(20, 'Phyllis', 'Fox', null, 'Female', '163.191.232.95', '2016-08-21 10:35:19');\n\n\n-- populate snapshot table\ninsert into {database}.{schema}.snapshot_expected (\n    id,\n    first_name,\n    last_name,\n    email,\n    gender,\n    ip_address,\n    updated_at,\n    test_valid_from,\n    test_valid_to,\n    test_updated_at,\n    test_scd_id\n)\n\nselect\n    id,\n    first_name,\n    last_name,\n    email,\n    gender,\n    ip_address,\n    updated_at,\n    -- fields added by snapshotting\n    updated_at as test_valid_from,\n    date('2099-12-31') as test_valid_to,\n    updated_at as test_updated_at,\n    md5(id || '-' || first_name || '|' || updated_at::text) as test_scd_id\nfrom {database}.{schema}.seed;\n"
  },
  {
    "path": "tests/functional/snapshots/data/seed_pg.sql",
    "content": "    create table {database}.{schema}.seed (\n\tid INTEGER,\n\tfirst_name VARCHAR(50),\n\tlast_name VARCHAR(50),\n\temail VARCHAR(50),\n\tgender VARCHAR(50),\n\tip_address VARCHAR(20),\n\tupdated_at TIMESTAMP WITHOUT TIME ZONE\n);\n\ncreate table {database}.{schema}.snapshot_expected (\n\tid INTEGER,\n\tfirst_name VARCHAR(50),\n\tlast_name VARCHAR(50),\n\temail VARCHAR(50),\n\tgender VARCHAR(50),\n\tip_address VARCHAR(20),\n\n\t-- snapshotting fields\n\tupdated_at TIMESTAMP WITHOUT TIME ZONE,\n\tdbt_valid_from TIMESTAMP WITHOUT TIME ZONE,\n\tdbt_valid_to   TIMESTAMP WITHOUT TIME ZONE,\n\tdbt_scd_id     TEXT,\n\tdbt_updated_at TIMESTAMP WITHOUT TIME ZONE\n);\n\n\n-- seed inserts\n--  use the same email for two users to verify that duplicated check_cols values\n--  are handled appropriately\ninsert into {database}.{schema}.seed (id, first_name, last_name, email, gender, ip_address, updated_at) values\n(1, 'Judith', 'Kennedy', '(not provided)', 'Female', '54.60.24.128', '2015-12-24 12:19:28'),\n(2, 'Arthur', 'Kelly', '(not provided)', 'Male', '62.56.24.215', '2015-10-28 16:22:15'),\n(3, 'Rachel', 'Moreno', 'rmoreno2@msu.edu', 'Female', '31.222.249.23', '2016-04-05 02:05:30'),\n(4, 'Ralph', 'Turner', 'rturner3@hp.com', 'Male', '157.83.76.114', '2016-08-08 00:06:51'),\n(5, 'Laura', 'Gonzales', 'lgonzales4@howstuffworks.com', 'Female', '30.54.105.168', '2016-09-01 08:25:38'),\n(6, 'Katherine', 'Lopez', 'klopez5@yahoo.co.jp', 'Female', '169.138.46.89', '2016-08-30 18:52:11'),\n(7, 'Jeremy', 'Hamilton', 'jhamilton6@mozilla.org', 'Male', '231.189.13.133', '2016-07-17 02:09:46'),\n(8, 'Heather', 'Rose', 'hrose7@goodreads.com', 'Female', '87.165.201.65', '2015-12-29 22:03:56'),\n(9, 'Gregory', 'Kelly', 'gkelly8@trellian.com', 'Male', '154.209.99.7', '2016-03-24 21:18:16'),\n(10, 'Rachel', 'Lopez', 'rlopez9@themeforest.net', 'Female', '237.165.82.71', '2016-08-20 15:44:49'),\n(11, 'Donna', 'Welch', 'dwelcha@shutterfly.com', 'Female', '103.33.110.138', '2016-02-27 01:41:48'),\n(12, 'Russell', 'Lawrence', 'rlawrenceb@qq.com', 'Male', '189.115.73.4', '2016-06-11 03:07:09'),\n(13, 'Michelle', 'Montgomery', 'mmontgomeryc@scientificamerican.com', 'Female', '243.220.95.82', '2016-06-18 16:27:19'),\n(14, 'Walter', 'Castillo', 'wcastillod@pagesperso-orange.fr', 'Male', '71.159.238.196', '2016-10-06 01:55:44'),\n(15, 'Robin', 'Mills', 'rmillse@vkontakte.ru', 'Female', '172.190.5.50', '2016-10-31 11:41:21'),\n(16, 'Raymond', 'Holmes', 'rholmesf@usgs.gov', 'Male', '148.153.166.95', '2016-10-03 08:16:38'),\n(17, 'Gary', 'Bishop', 'gbishopg@plala.or.jp', 'Male', '161.108.182.13', '2016-08-29 19:35:20'),\n(18, 'Anna', 'Riley', 'arileyh@nasa.gov', 'Female', '253.31.108.22', '2015-12-11 04:34:27'),\n(19, 'Sarah', 'Knight', 'sknighti@foxnews.com', 'Female', '222.220.3.177', '2016-09-26 00:49:06'),\n(20, 'Phyllis', 'Fox', null, 'Female', '163.191.232.95', '2016-08-21 10:35:19');\n\n\n-- populate snapshot table\ninsert into {database}.{schema}.snapshot_expected (\n    id,\n    first_name,\n    last_name,\n    email,\n    gender,\n    ip_address,\n    updated_at,\n    dbt_valid_from,\n    dbt_valid_to,\n    dbt_updated_at,\n    dbt_scd_id\n)\n\nselect\n    id,\n    first_name,\n    last_name,\n    email,\n    gender,\n    ip_address,\n    updated_at,\n    -- fields added by snapshotting\n    updated_at as dbt_valid_from,\n    null::timestamp as dbt_valid_to,\n    updated_at as dbt_updated_at,\n    md5(id || '-' || first_name || '|' || updated_at::text) as dbt_scd_id\nfrom {database}.{schema}.seed;\n\n\n\ncreate table {database}.{schema}.snapshot_castillo_expected (\n    id INTEGER,\n    first_name VARCHAR(50),\n    last_name VARCHAR(50),\n    email VARCHAR(50),\n    gender VARCHAR(50),\n    ip_address VARCHAR(20),\n\n    -- snapshotting fields\n    \"1-updated_at\" TIMESTAMP WITHOUT TIME ZONE,\n    dbt_valid_from TIMESTAMP WITHOUT TIME ZONE,\n    dbt_valid_to   TIMESTAMP WITHOUT TIME ZONE,\n    dbt_scd_id     TEXT,\n    dbt_updated_at TIMESTAMP WITHOUT TIME ZONE\n);\n\n-- one entry\ninsert into {database}.{schema}.snapshot_castillo_expected (\n    id,\n    first_name,\n    last_name,\n    email,\n    gender,\n    ip_address,\n    \"1-updated_at\",\n    dbt_valid_from,\n    dbt_valid_to,\n    dbt_updated_at,\n    dbt_scd_id\n)\n\nselect\n    id,\n    first_name,\n    last_name,\n    email,\n    gender,\n    ip_address,\n    updated_at,\n    -- fields added by snapshotting\n    updated_at as dbt_valid_from,\n    null::timestamp as dbt_valid_to,\n    updated_at as dbt_updated_at,\n    md5(id || '-' || first_name || '|' || updated_at::text) as dbt_scd_id\nfrom {database}.{schema}.seed where last_name = 'Castillo';\n\ncreate table {database}.{schema}.snapshot_alvarez_expected (\n    id INTEGER,\n    first_name VARCHAR(50),\n    last_name VARCHAR(50),\n    email VARCHAR(50),\n    gender VARCHAR(50),\n    ip_address VARCHAR(20),\n\n    -- snapshotting fields\n    updated_at TIMESTAMP WITHOUT TIME ZONE,\n    dbt_valid_from TIMESTAMP WITHOUT TIME ZONE,\n    dbt_valid_to   TIMESTAMP WITHOUT TIME ZONE,\n    dbt_scd_id     TEXT,\n    dbt_updated_at TIMESTAMP WITHOUT TIME ZONE\n);\n\n-- 0 entries\ninsert into {database}.{schema}.snapshot_alvarez_expected (\n    id,\n    first_name,\n    last_name,\n    email,\n    gender,\n    ip_address,\n    updated_at,\n    dbt_valid_from,\n    dbt_valid_to,\n    dbt_updated_at,\n    dbt_scd_id\n)\n\nselect\n    id,\n    first_name,\n    last_name,\n    email,\n    gender,\n    ip_address,\n    updated_at,\n    -- fields added by snapshotting\n    updated_at as dbt_valid_from,\n    null::timestamp as dbt_valid_to,\n    updated_at as dbt_updated_at,\n    md5(id || '-' || first_name || '|' || updated_at::text) as dbt_scd_id\nfrom {database}.{schema}.seed where last_name = 'Alvarez';\n\ncreate table {database}.{schema}.snapshot_kelly_expected (\n    id INTEGER,\n    first_name VARCHAR(50),\n    last_name VARCHAR(50),\n    email VARCHAR(50),\n    gender VARCHAR(50),\n    ip_address VARCHAR(20),\n\n    -- snapshotting fields\n    updated_at TIMESTAMP WITHOUT TIME ZONE,\n    dbt_valid_from TIMESTAMP WITHOUT TIME ZONE,\n    dbt_valid_to   TIMESTAMP WITHOUT TIME ZONE,\n    dbt_scd_id     TEXT,\n    dbt_updated_at TIMESTAMP WITHOUT TIME ZONE\n);\n\n\n-- 2 entries\ninsert into {database}.{schema}.snapshot_kelly_expected (\n    id,\n    first_name,\n    last_name,\n    email,\n    gender,\n    ip_address,\n    updated_at,\n    dbt_valid_from,\n    dbt_valid_to,\n    dbt_updated_at,\n    dbt_scd_id\n)\n\nselect\n    id,\n    first_name,\n    last_name,\n    email,\n    gender,\n    ip_address,\n    updated_at,\n    -- fields added by snapshotting\n    updated_at as dbt_valid_from,\n    null::timestamp as dbt_valid_to,\n    updated_at as dbt_updated_at,\n    md5(id || '-' || first_name || '|' || updated_at::text) as dbt_scd_id\nfrom {database}.{schema}.seed where last_name = 'Kelly';\n"
  },
  {
    "path": "tests/functional/snapshots/data/shared_macros.sql",
    "content": "{% macro get_snapshot_unique_id() -%}\n    {{ return(adapter.dispatch('get_snapshot_unique_id')()) }}\n{%- endmacro %}\n\n{% macro default__get_snapshot_unique_id() -%}\n  {% do return(\"id || '-' || first_name\") %}\n{%- endmacro %}\n\n{#\n    mostly copy+pasted from dbt_utils, but I removed some parameters and added\n    a query that calls get_snapshot_unique_id\n#}\n{% test mutually_exclusive_ranges(model) %}\n\nwith base as (\n    select {{ get_snapshot_unique_id() }} as dbt_unique_id,\n    *\n    from {{ model }}\n),\nwindow_functions as (\n\n    select\n        dbt_valid_from as lower_bound,\n        coalesce(dbt_valid_to, '2099-1-1T00:00:01') as upper_bound,\n\n        lead(dbt_valid_from) over (\n            partition by dbt_unique_id\n            order by dbt_valid_from\n        ) as next_lower_bound,\n\n        row_number() over (\n            partition by dbt_unique_id\n            order by dbt_valid_from desc\n        ) = 1 as is_last_record\n\n    from base\n\n),\n\ncalc as (\n    -- We want to return records where one of our assumptions fails, so we'll use\n    -- the `not` function with `and` statements so we can write our assumptions nore cleanly\n    select\n        *,\n\n        -- For each record: lower_bound should be < upper_bound.\n        -- Coalesce it to return an error on the null case (implicit assumption\n        -- these columns are not_null)\n        coalesce(\n            lower_bound < upper_bound,\n            is_last_record\n        ) as lower_bound_less_than_upper_bound,\n\n        -- For each record: upper_bound {{ allow_gaps_operator }} the next lower_bound.\n        -- Coalesce it to handle null cases for the last record.\n        coalesce(\n            upper_bound = next_lower_bound,\n            is_last_record,\n            false\n        ) as upper_bound_equal_to_next_lower_bound\n\n    from window_functions\n\n),\n\nvalidation_errors as (\n\n    select\n        *\n    from calc\n\n    where not(\n        -- THE FOLLOWING SHOULD BE TRUE --\n        lower_bound_less_than_upper_bound\n        and upper_bound_equal_to_next_lower_bound\n    )\n)\n\nselect * from validation_errors\n{% endtest %}\n"
  },
  {
    "path": "tests/functional/snapshots/data/update.sql",
    "content": "-- insert v2 of the 11 - 21 records\n\ninsert into {database}.{schema}.snapshot_expected (\n    id,\n    first_name,\n    last_name,\n    email,\n    gender,\n    ip_address,\n    updated_at,\n    dbt_valid_from,\n    dbt_valid_to,\n    dbt_updated_at,\n    dbt_scd_id\n)\n\nselect\n    id,\n    first_name,\n    last_name,\n    email,\n    gender,\n    ip_address,\n    updated_at,\n    -- fields added by snapshotting\n    updated_at as dbt_valid_from,\n    null::timestamp as dbt_valid_to,\n    updated_at as dbt_updated_at,\n    md5(id || '-' || first_name || '|' || updated_at::text) as dbt_scd_id\nfrom {database}.{schema}.seed\nwhere id >= 10 and id <= 20;\n\n\ninsert into {database}.{schema}.snapshot_castillo_expected (\n    id,\n    first_name,\n    last_name,\n    email,\n    gender,\n    ip_address,\n    \"1-updated_at\",\n    dbt_valid_from,\n    dbt_valid_to,\n    dbt_updated_at,\n    dbt_scd_id\n)\n\nselect\n    id,\n    first_name,\n    last_name,\n    email,\n    gender,\n    ip_address,\n    updated_at,\n    -- fields added by snapshotting\n    updated_at as dbt_valid_from,\n    null::timestamp as dbt_valid_to,\n    updated_at as dbt_updated_at,\n    md5(id || '-' || first_name || '|' || updated_at::text) as dbt_scd_id\nfrom {database}.{schema}.seed\nwhere id >= 10 and id <= 20 and last_name = 'Castillo';\n\n\ninsert into {database}.{schema}.snapshot_alvarez_expected (\n    id,\n    first_name,\n    last_name,\n    email,\n    gender,\n    ip_address,\n    updated_at,\n    dbt_valid_from,\n    dbt_valid_to,\n    dbt_updated_at,\n    dbt_scd_id\n)\n\nselect\n    id,\n    first_name,\n    last_name,\n    email,\n    gender,\n    ip_address,\n    updated_at,\n    -- fields added by snapshotting\n    updated_at as dbt_valid_from,\n    null::timestamp as dbt_valid_to,\n    updated_at as dbt_updated_at,\n    md5(id || '-' || first_name || '|' || updated_at::text) as dbt_scd_id\nfrom {database}.{schema}.seed\nwhere id >= 10 and id <= 20 and last_name = 'Alvarez';\n\n\ninsert into {database}.{schema}.snapshot_kelly_expected (\n    id,\n    first_name,\n    last_name,\n    email,\n    gender,\n    ip_address,\n    updated_at,\n    dbt_valid_from,\n    dbt_valid_to,\n    dbt_updated_at,\n    dbt_scd_id\n)\n\nselect\n    id,\n    first_name,\n    last_name,\n    email,\n    gender,\n    ip_address,\n    updated_at,\n    -- fields added by snapshotting\n    updated_at as dbt_valid_from,\n    null::timestamp as dbt_valid_to,\n    updated_at as dbt_updated_at,\n    md5(id || '-' || first_name || '|' || updated_at::text) as dbt_scd_id\nfrom {database}.{schema}.seed\nwhere id >= 10 and id <= 20 and last_name = 'Kelly';\n\n-- insert 10 new records\ninsert into {database}.{schema}.seed (id, first_name, last_name, email, gender, ip_address, updated_at) values\n(21, 'Judy', 'Robinson', 'jrobinsonk@blogs.com', 'Female', '208.21.192.232', '2016-09-18 08:27:38'),\n(22, 'Kevin', 'Alvarez', 'kalvarezl@buzzfeed.com', 'Male', '228.106.146.9', '2016-07-29 03:07:37'),\n(23, 'Barbara', 'Carr', 'bcarrm@pen.io', 'Female', '106.165.140.17', '2015-09-24 13:27:23'),\n(24, 'William', 'Watkins', 'wwatkinsn@guardian.co.uk', 'Male', '78.155.84.6', '2016-03-08 19:13:08'),\n(25, 'Judy', 'Cooper', 'jcoopero@google.com.au', 'Female', '24.149.123.184', '2016-10-05 20:49:33'),\n(26, 'Shirley', 'Castillo', 'scastillop@samsung.com', 'Female', '129.252.181.12', '2016-06-20 21:12:21'),\n(27, 'Justin', 'Harper', 'jharperq@opera.com', 'Male', '131.172.103.218', '2016-05-21 22:56:46'),\n(28, 'Marie', 'Medina', 'mmedinar@nhs.uk', 'Female', '188.119.125.67', '2015-10-08 13:44:33'),\n(29, 'Kelly', 'Edwards', 'kedwardss@phoca.cz', 'Female', '47.121.157.66', '2015-09-15 06:33:37'),\n(30, 'Carl', 'Coleman', 'ccolemant@wikipedia.org', 'Male', '82.227.154.83', '2016-05-26 16:46:40');\n\n\n-- add these new records to the snapshot table\ninsert into {database}.{schema}.snapshot_expected (\n    id,\n    first_name,\n    last_name,\n    email,\n    gender,\n    ip_address,\n    updated_at,\n    dbt_valid_from,\n    dbt_valid_to,\n    dbt_updated_at,\n    dbt_scd_id\n)\n\nselect\n    id,\n    first_name,\n    last_name,\n    email,\n    gender,\n    ip_address,\n    updated_at,\n    -- fields added by snapshotting\n    updated_at as dbt_valid_from,\n    null::timestamp as dbt_valid_to,\n    updated_at as dbt_updated_at,\n    md5(id || '-' || first_name || '|' || updated_at::text) as dbt_scd_id\nfrom {database}.{schema}.seed\nwhere id > 20;\n\n\n-- add these new records to the snapshot table\ninsert into {database}.{schema}.snapshot_castillo_expected (\n    id,\n    first_name,\n    last_name,\n    email,\n    gender,\n    ip_address,\n    \"1-updated_at\",\n    dbt_valid_from,\n    dbt_valid_to,\n    dbt_updated_at,\n    dbt_scd_id\n)\n\nselect\n    id,\n    first_name,\n    last_name,\n    email,\n    gender,\n    ip_address,\n    updated_at,\n    -- fields added by snapshotting\n    updated_at as dbt_valid_from,\n    null::timestamp as dbt_valid_to,\n    updated_at as dbt_updated_at,\n    md5(id || '-' || first_name || '|' || updated_at::text) as dbt_scd_id\nfrom {database}.{schema}.seed\nwhere id > 20 and last_name = 'Castillo';\n\ninsert into {database}.{schema}.snapshot_alvarez_expected (\n    id,\n    first_name,\n    last_name,\n    email,\n    gender,\n    ip_address,\n    updated_at,\n    dbt_valid_from,\n    dbt_valid_to,\n    dbt_updated_at,\n    dbt_scd_id\n)\n\nselect\n    id,\n    first_name,\n    last_name,\n    email,\n    gender,\n    ip_address,\n    updated_at,\n    -- fields added by snapshotting\n    updated_at as dbt_valid_from,\n    null::timestamp as dbt_valid_to,\n    updated_at as dbt_updated_at,\n    md5(id || '-' || first_name || '|' || updated_at::text) as dbt_scd_id\nfrom {database}.{schema}.seed\nwhere id > 20 and last_name = 'Alvarez';\n\ninsert into {database}.{schema}.snapshot_kelly_expected (\n    id,\n    first_name,\n    last_name,\n    email,\n    gender,\n    ip_address,\n    updated_at,\n    dbt_valid_from,\n    dbt_valid_to,\n    dbt_updated_at,\n    dbt_scd_id\n)\n\nselect\n    id,\n    first_name,\n    last_name,\n    email,\n    gender,\n    ip_address,\n    updated_at,\n    -- fields added by snapshotting\n    updated_at as dbt_valid_from,\n    null::timestamp as dbt_valid_to,\n    updated_at as dbt_updated_at,\n    md5(id || '-' || first_name || '|' || updated_at::text) as dbt_scd_id\nfrom {database}.{schema}.seed\nwhere id > 20 and last_name = 'Kelly';\n"
  },
  {
    "path": "tests/functional/snapshots/fixtures.py",
    "content": "snapshots_select__snapshot_sql = \"\"\"\n{% snapshot snapshot_castillo %}\n\n    {{\n        config(\n            target_database=var('target_database', database),\n            target_schema=schema,\n            unique_key='id || ' ~ \"'-'\" ~ ' || first_name',\n            strategy='timestamp',\n            updated_at='\"1-updated_at\"',\n        )\n    }}\n    select id,first_name,last_name,email,gender,ip_address,updated_at as \"1-updated_at\" from {{target.database}}.{{schema}}.seed where last_name = 'Castillo'\n\n{% endsnapshot %}\n\n{% snapshot snapshot_alvarez %}\n\n    {{\n        config(\n            target_database=var('target_database', database),\n            target_schema=schema,\n            unique_key='id || ' ~ \"'-'\" ~ ' || first_name',\n            strategy='timestamp',\n            updated_at='updated_at',\n        )\n    }}\n    select * from {{target.database}}.{{schema}}.seed where last_name = 'Alvarez'\n\n{% endsnapshot %}\n\n\n{% snapshot snapshot_kelly %}\n    {# This has no target_database set, which is allowed! #}\n    {{\n        config(\n            target_schema=schema,\n            unique_key='id || ' ~ \"'-'\" ~ ' || first_name',\n            strategy='timestamp',\n            updated_at='updated_at',\n        )\n    }}\n    select * from {{target.database}}.{{schema}}.seed where last_name = 'Kelly'\n\n{% endsnapshot %}\n\"\"\"\n\nsnapshots_pg_custom__snapshot_sql = \"\"\"\n{% snapshot snapshot_actual %}\n\n    {{\n        config(\n            target_database=var('target_database', database),\n            target_schema=var('target_schema', schema),\n            unique_key='id || ' ~ \"'-'\" ~ ' || first_name',\n            strategy='custom',\n            updated_at='updated_at',\n        )\n    }}\n    select * from {{target.database}}.{{target.schema}}.seed\n\n{% endsnapshot %}\n\"\"\"\n\n\nmacros_custom_snapshot__custom_sql = \"\"\"\n{# A \"custom\" strategy that's really just the timestamp one #}\n{% macro snapshot_custom_strategy(node, snapshotted_rel, current_rel, config, target_exists) %}\n    {% set primary_key = config['unique_key'] %}\n    {% set updated_at = config['updated_at'] %}\n\n    {% set row_changed_expr -%}\n        ({{ snapshotted_rel }}.{{ updated_at }} < {{ current_rel }}.{{ updated_at }})\n    {%- endset %}\n\n    {% set scd_id_expr = snapshot_hash_arguments([primary_key, updated_at]) %}\n\n    {% do return({\n        \"unique_key\": primary_key,\n        \"updated_at\": updated_at,\n        \"row_changed\": row_changed_expr,\n        \"scd_id\": scd_id_expr\n    }) %}\n{% endmacro %}\n\"\"\"\n\n\nmodels__schema_yml = \"\"\"\nsnapshots:\n  - name: snapshot_actual\n    data_tests:\n      - mutually_exclusive_ranges\n    config:\n      meta:\n        owner: 'a_owner'\n\"\"\"\n\nmodels__schema_with_target_schema_yml = \"\"\"\nsnapshots:\n  - name: snapshot_actual\n    data_tests:\n      - mutually_exclusive_ranges\n    config:\n      meta:\n        owner: 'a_owner'\n      target_schema: schema_from_schema_yml\n\"\"\"\n\nmodels__ref_snapshot_sql = \"\"\"\nselect * from {{ ref('snapshot_actual') }}\n\"\"\"\n\nmacros__test_no_overlaps_sql = \"\"\"\n{% macro get_snapshot_unique_id() -%}\n    {{ return(adapter.dispatch('get_snapshot_unique_id')()) }}\n{%- endmacro %}\n\n{% macro default__get_snapshot_unique_id() -%}\n  {% do return(\"id || '-' || first_name\") %}\n{%- endmacro %}\n\n{#\n    mostly copy+pasted from dbt_utils, but I removed some parameters and added\n    a query that calls get_snapshot_unique_id\n#}\n{% test mutually_exclusive_ranges(model) %}\n\nwith base as (\n    select {{ get_snapshot_unique_id() }} as dbt_unique_id,\n    *\n    from {{ model }}\n),\nwindow_functions as (\n\n    select\n        dbt_valid_from as lower_bound,\n        coalesce(dbt_valid_to, '2099-1-1T00:00:01') as upper_bound,\n\n        lead(dbt_valid_from) over (\n            partition by dbt_unique_id\n            order by dbt_valid_from\n        ) as next_lower_bound,\n\n        row_number() over (\n            partition by dbt_unique_id\n            order by dbt_valid_from desc\n        ) = 1 as is_last_record\n\n    from base\n\n),\n\ncalc as (\n    -- We want to return records where one of our assumptions fails, so we'll use\n    -- the `not` function with `and` statements so we can write our assumptions nore cleanly\n    select\n        *,\n\n        -- For each record: lower_bound should be < upper_bound.\n        -- Coalesce it to return an error on the null case (implicit assumption\n        -- these columns are not_null)\n        coalesce(\n            lower_bound < upper_bound,\n            is_last_record\n        ) as lower_bound_less_than_upper_bound,\n\n        -- For each record: upper_bound {{ allow_gaps_operator }} the next lower_bound.\n        -- Coalesce it to handle null cases for the last record.\n        coalesce(\n            upper_bound = next_lower_bound,\n            is_last_record,\n            false\n        ) as upper_bound_equal_to_next_lower_bound\n\n    from window_functions\n\n),\n\nvalidation_errors as (\n\n    select\n        *\n    from calc\n\n    where not(\n        -- THE FOLLOWING SHOULD BE TRUE --\n        lower_bound_less_than_upper_bound\n        and upper_bound_equal_to_next_lower_bound\n    )\n)\n\nselect * from validation_errors\n{% endtest %}\n\"\"\"\n\n\nsnapshots_select_noconfig__snapshot_sql = \"\"\"\n{% snapshot snapshot_actual %}\n\n    {{\n        config(\n            target_database=var('target_database', database),\n            target_schema=var('target_schema', schema),\n        )\n    }}\n    select * from {{target.database}}.{{target.schema}}.seed\n\n{% endsnapshot %}\n\n{% snapshot snapshot_castillo %}\n\n    {{\n        config(\n            target_database=var('target_database', database),\n            updated_at='\"1-updated_at\"',\n        )\n    }}\n    select id,first_name,last_name,email,gender,ip_address,updated_at as \"1-updated_at\" from {{target.database}}.{{schema}}.seed where last_name = 'Castillo'\n\n{% endsnapshot %}\n\n{% snapshot snapshot_alvarez %}\n\n    {{\n        config(\n            target_database=var('target_database', database),\n        )\n    }}\n    select * from {{target.database}}.{{schema}}.seed where last_name = 'Alvarez'\n\n{% endsnapshot %}\n\n\n{% snapshot snapshot_kelly %}\n    {# This has no target_database set, which is allowed! #}\n    select * from {{target.database}}.{{schema}}.seed where last_name = 'Kelly'\n\n{% endsnapshot %}\n\"\"\"\n\n\nseeds__seed_newcol_csv = \"\"\"id,first_name,last_name\n1,Judith,Kennedy\n2,Arthur,Kelly\n3,Rachel,Moreno\n\"\"\"\n\nseeds__seed_csv = \"\"\"id,first_name\n1,Judith\n2,Arthur\n3,Rachel\n\"\"\"\n\n\nsnapshots_pg_custom_namespaced__snapshot_sql = \"\"\"\n{% snapshot snapshot_actual %}\n\n    {{\n        config(\n            target_database=var('target_database', database),\n            target_schema=var('target_schema', schema),\n            unique_key='id || ' ~ \"'-'\" ~ ' || first_name',\n            strategy='test.custom',\n            updated_at='updated_at',\n        )\n    }}\n    select * from {{target.database}}.{{target.schema}}.seed\n\n{% endsnapshot %}\n\"\"\"\n\nsnapshots_pg__snapshot_sql = \"\"\"\n{% snapshot snapshot_actual %}\n\n    {{\n        config(\n            target_database=var('target_database', database),\n            target_schema=var('target_schema', schema),\n            unique_key='id || ' ~ \"'-'\" ~ ' || first_name',\n            strategy='timestamp',\n            updated_at='updated_at',\n        )\n    }}\n\n    {% if var('invalidate_hard_deletes', 'false') | as_bool %}\n        {{ config(invalidate_hard_deletes=True) }}\n    {% endif %}\n\n    select * from {{target.database}}.{{target.schema}}.seed\n\n{% endsnapshot %}\n\"\"\"\n\nsnapshots_pg__snapshot_yml = \"\"\"\nsnapshots:\n  - name: snapshot_actual\n    relation: \"ref('seed')\"\n    config:\n      unique_key: \"id || '-' || first_name\"\n      strategy: timestamp\n      updated_at: updated_at\n      meta:\n        owner: 'a_owner'\n    columns:\n      - name: id\n        data_tests:\n          - not_null\n\"\"\"\n\nsnapshots_pg__source_snapshot_yml = \"\"\"\nsnapshots:\n  - name: snapshot_source\n    relation: \"source('information_schema', 'tables')\"\n    config:\n      unique_key: \"table_schema || '-' || table_name\"\n      strategy: check\n      check_cols: all\n\"\"\"\n\nsnapshots_pg__snapshot_mod_yml = \"\"\"\nsnapshots:\n  - name: snapshot_actual\n    relation: \"ref('seed')\"\n    config:\n      unique_key: \"id || '-' || first_name\"\n      strategy: timestamp\n      updated_at: updated_at\n      meta:\n        owner: 'b_owner'\n    columns:\n      - name: id\n        data_tests:\n          - not_null\n\"\"\"\n\nsnapshots_pg__snapshot_no_target_schema_sql = \"\"\"\n{% snapshot snapshot_actual %}\n\n    {{\n        config(\n            target_database=var('target_database', database),\n            unique_key='id || ' ~ \"'-'\" ~ ' || first_name',\n            strategy='timestamp',\n            updated_at='updated_at',\n        )\n    }}\n\n    {% if var('invalidate_hard_deletes', 'false') | as_bool %}\n        {{ config(invalidate_hard_deletes=True) }}\n    {% endif %}\n\n    select * from {{target.database}}.{{target.schema}}.seed\n\n{% endsnapshot %}\n\"\"\"\n\nmodels_slow__gen_sql = \"\"\"\n\n{{ config(materialized='ephemeral') }}\n\n\n/*\n    Generates 50 rows that \"appear\" to update every\n    second to a query-er.\n\n    1\t2020-04-21 20:44:00-04\t0\n    2\t2020-04-21 20:43:59-04\t59\n    3\t2020-04-21 20:43:58-04\t58\n    4\t2020-04-21 20:43:57-04\t57\n\n    .... 1 second later ....\n\n    1\t2020-04-21 20:44:01-04\t1\n    2\t2020-04-21 20:44:00-04\t0\n    3\t2020-04-21 20:43:59-04\t59\n    4\t2020-04-21 20:43:58-04\t58\n\n    This view uses pg_sleep(2) to make queries against\n    the view take a non-trivial amount of time\n\n    Use statement_timestamp() as it changes during a transactions.\n    If we used now() or current_time or similar, then the timestamp\n    of the start of the transaction would be returned instead.\n*/\n\nwith gen as (\n\n    select\n        id,\n        date_trunc('second', statement_timestamp()) - (interval '1 second' * id) as updated_at\n\n    from generate_series(1, 10) id\n\n)\n\nselect\n    id,\n    updated_at,\n    extract(seconds from updated_at)::int as seconds\n\nfrom gen, pg_sleep(2)\n\"\"\"\n\nsnapshots_longtext__snapshot_sql = \"\"\"\n{% snapshot snapshot_actual %}\n    {{\n        config(\n            target_database=var('target_database', database),\n            target_schema=schema,\n            unique_key='id',\n            strategy='timestamp',\n            updated_at='updated_at',\n        )\n    }}\n    select * from {{target.database}}.{{schema}}.super_long\n{% endsnapshot %}\n\"\"\"\n\nsnapshots_check_col_noconfig__snapshot_sql = \"\"\"\n{% snapshot snapshot_actual %}\n    select * from {{target.database}}.{{schema}}.seed\n{% endsnapshot %}\n\n{# This should be exactly the same #}\n{% snapshot snapshot_checkall %}\n    {{ config(check_cols='all') }}\n    select * from {{target.database}}.{{schema}}.seed\n{% endsnapshot %}\n\"\"\"\n\n\nsources_pg__source_yml = \"\"\"\nsources:\n  - name: information_schema\n    database: dbt\n    schema: information_schema\n    tables:\n      - name: tables\n\"\"\"\n\nsources_pg__source_mod_yml = \"\"\"\nsources:\n  - name: information_schema\n    database: dbt\n    schema: information_schema\n    tables:\n      - name: tables\n        description: tables\n\"\"\"\n"
  },
  {
    "path": "tests/functional/snapshots/test_basic_snapshot.py",
    "content": "import os\nfrom datetime import datetime\n\nimport pytest\nimport pytz\n\nfrom dbt.tests.util import (\n    check_relations_equal,\n    relation_from_name,\n    run_dbt,\n    update_config_file,\n    write_file,\n)\nfrom tests.functional.snapshots.fixtures import (\n    macros__test_no_overlaps_sql,\n    macros_custom_snapshot__custom_sql,\n    models__ref_snapshot_sql,\n    models__schema_with_target_schema_yml,\n    models__schema_yml,\n    seeds__seed_csv,\n    seeds__seed_newcol_csv,\n    snapshots_pg__snapshot_mod_yml,\n    snapshots_pg__snapshot_no_target_schema_sql,\n    snapshots_pg__snapshot_sql,\n    snapshots_pg__snapshot_yml,\n    snapshots_pg__source_snapshot_yml,\n    snapshots_pg_custom__snapshot_sql,\n    snapshots_pg_custom_namespaced__snapshot_sql,\n    sources_pg__source_mod_yml,\n    sources_pg__source_yml,\n)\n\nsnapshots_check_col__snapshot_sql = \"\"\"\n{% snapshot snapshot_actual %}\n\n    {{\n        config(\n            target_database=var('target_database', database),\n            target_schema=schema,\n            unique_key='id || ' ~ \"'-'\" ~ ' || first_name',\n            strategy='check',\n            check_cols=['email'],\n        )\n    }}\n    select * from {{target.database}}.{{schema}}.seed\n\n{% endsnapshot %}\n\n{# This should be exactly the same #}\n{% snapshot snapshot_checkall %}\n    {{\n        config(\n            target_database=var('target_database', database),\n            target_schema=schema,\n            unique_key='id || ' ~ \"'-'\" ~ ' || first_name',\n            strategy='check',\n            check_cols='all',\n        )\n    }}\n    select * from {{target.database}}.{{schema}}.seed\n{% endsnapshot %}\n\"\"\"\n\n\nsnapshots_check_col_noconfig__snapshot_sql = \"\"\"\n{% snapshot snapshot_actual %}\n    select * from {{target.database}}.{{schema}}.seed\n{% endsnapshot %}\n\n{# This should be exactly the same #}\n{% snapshot snapshot_checkall %}\n    {{ config(check_cols='all') }}\n    select * from {{target.database}}.{{schema}}.seed\n{% endsnapshot %}\n\"\"\"\n\n\ndef snapshot_setup(project, num_snapshot_models=1):\n    path = os.path.join(project.test_data_dir, \"seed_pg.sql\")\n    project.run_sql_file(path)\n    results = run_dbt([\"snapshot\"])\n    assert len(results) == num_snapshot_models\n\n    run_dbt([\"test\"])\n    check_relations_equal(project.adapter, [\"snapshot_actual\", \"snapshot_expected\"])\n\n    path = os.path.join(project.test_data_dir, \"invalidate_postgres.sql\")\n    project.run_sql_file(path)\n\n    path = os.path.join(project.test_data_dir, \"update.sql\")\n    project.run_sql_file(path)\n\n    results = run_dbt([\"snapshot\"])\n    assert len(results) == num_snapshot_models\n\n    run_dbt([\"test\"])\n    check_relations_equal(project.adapter, [\"snapshot_actual\", \"snapshot_expected\"])\n\n\ndef ref_setup(project, num_snapshot_models=1):\n    path = os.path.join(project.test_data_dir, \"seed_pg.sql\")\n    project.run_sql_file(path)\n    results = run_dbt([\"snapshot\"])\n    assert len(results) == num_snapshot_models\n\n    results = run_dbt([\"run\"])\n    assert len(results) == 1\n\n\nclass Basic:\n    @pytest.fixture(scope=\"class\")\n    def snapshots(self):\n        return {\"snapshot.sql\": snapshots_pg__snapshot_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": models__schema_yml,\n            \"ref_snapshot.sql\": models__ref_snapshot_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"test_no_overlaps.sql\": macros__test_no_overlaps_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\"seed_newcol.csv\": seeds__seed_newcol_csv, \"seed.csv\": seeds__seed_csv}\n\n\nclass TestBasicSnapshot(Basic):\n    def test_basic_snapshot(self, project):\n        snapshot_setup(project, num_snapshot_models=1)\n\n\nclass TestBasicRef(Basic):\n    def test_basic_ref(self, project):\n        ref_setup(project, num_snapshot_models=1)\n\n\nclass TestBasicTargetSchemaConfig(Basic):\n    @pytest.fixture(scope=\"class\")\n    def snapshots(self):\n        return {\"snapshot.sql\": snapshots_pg__snapshot_no_target_schema_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self, unique_schema):\n        return {\n            \"snapshots\": {\n                \"test\": {\n                    \"schema\": \"alt\",\n                }\n            }\n        }\n\n    def test_target_schema(self, project):\n        manifest = run_dbt([\"parse\"])\n        assert len(manifest.nodes) == 5\n        # ensure that the schema in the snapshot node is the same as target_schema\n        snapshot_id = \"snapshot.test.snapshot_actual\"\n        snapshot_node = manifest.nodes[snapshot_id]\n        # The schema field be changed by the default \"generate_schema_name\"\n        # to append an underscore plus the configured schema of \"alt\".\n        assert snapshot_node.schema == f\"{project.test_schema}_alt\"\n        assert (\n            snapshot_node.relation_name\n            == f'\"{project.database}\".\"{project.test_schema}_alt\".\"snapshot_actual\"'\n        )\n        assert snapshot_node.meta == {\"owner\": \"a_owner\"}\n\n        # write out schema.yml file and check again\n        write_file(models__schema_with_target_schema_yml, \"models\", \"schema.yml\")\n        manifest = run_dbt([\"parse\"])\n        snapshot_node = manifest.nodes[snapshot_id]\n        assert snapshot_node.schema == \"schema_from_schema_yml\"\n\n\nclass CustomNamespace:\n    @pytest.fixture(scope=\"class\")\n    def snapshots(self):\n        return {\"snapshot.sql\": snapshots_pg_custom_namespaced__snapshot_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\n            \"test_no_overlaps.sql\": macros__test_no_overlaps_sql,\n            \"custom.sql\": macros_custom_snapshot__custom_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": models__schema_yml,\n            \"ref_snapshot.sql\": models__ref_snapshot_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\"seed_newcol.csv\": seeds__seed_newcol_csv, \"seed.csv\": seeds__seed_csv}\n\n\nclass TestBasicCustomNamespace(CustomNamespace):\n    def test_custom_namespace_snapshot(self, project):\n        snapshot_setup(project, num_snapshot_models=1)\n\n\nclass TestRefCustomNamespace(CustomNamespace):\n    def test_custom_namespace_ref(self, project):\n        ref_setup(project, num_snapshot_models=1)\n\n\nclass CustomSnapshot:\n    @pytest.fixture(scope=\"class\")\n    def snapshots(self):\n        return {\"snapshot.sql\": snapshots_pg_custom__snapshot_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\n            \"test_no_overlaps.sql\": macros__test_no_overlaps_sql,\n            \"custom.sql\": macros_custom_snapshot__custom_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": models__schema_yml,\n            \"ref_snapshot.sql\": models__ref_snapshot_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\"seed_newcol.csv\": seeds__seed_newcol_csv, \"seed.csv\": seeds__seed_csv}\n\n\nclass TestBasicCustomSnapshot(CustomSnapshot):\n    def test_custom_snapshot(self, project):\n        snapshot_setup(project, num_snapshot_models=1)\n\n\nclass TestRefCustomSnapshot(CustomSnapshot):\n    def test_custom_ref(self, project):\n        ref_setup(project, num_snapshot_models=1)\n\n\nclass CheckCols:\n    @pytest.fixture(scope=\"class\")\n    def snapshots(self):\n        return {\"snapshot.sql\": snapshots_check_col__snapshot_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": models__schema_yml,\n            \"ref_snapshot.sql\": models__ref_snapshot_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"test_no_overlaps.sql\": macros__test_no_overlaps_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\"seed_newcol.csv\": seeds__seed_newcol_csv, \"seed.csv\": seeds__seed_csv}\n\n\nclass TestBasicCheckCols(CheckCols):\n    def test_basic_snapshot(self, project):\n        snapshot_setup(project, num_snapshot_models=2)\n\n\nclass TestRefCheckCols(CheckCols):\n    def test_check_cols_ref(self, project):\n        ref_setup(project, num_snapshot_models=2)\n\n\nclass ConfiguredCheckCols:\n    @pytest.fixture(scope=\"class\")\n    def snapshots(self):\n        return {\"snapshot.sql\": snapshots_check_col_noconfig__snapshot_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": models__schema_yml,\n            \"ref_snapshot.sql\": models__ref_snapshot_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"test_no_overlaps.sql\": macros__test_no_overlaps_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\"seed_newcol.csv\": seeds__seed_newcol_csv, \"seed.csv\": seeds__seed_csv}\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        snapshot_config = {\n            \"snapshots\": {\n                \"test\": {\n                    \"target_schema\": \"{{ target.schema }}\",\n                    \"unique_key\": \"id || '-' || first_name\",\n                    \"strategy\": \"check\",\n                    \"check_cols\": [\"email\"],\n                }\n            }\n        }\n        return snapshot_config\n\n\nclass TestBasicConfiguredCheckCols(ConfiguredCheckCols):\n    def test_configured_snapshot(self, project):\n        snapshot_setup(project, num_snapshot_models=2)\n\n\nclass TestRefConfiguredCheckCols(ConfiguredCheckCols):\n    def test_configured_ref(self, project):\n        ref_setup(project, num_snapshot_models=2)\n\n\nclass UpdatedAtCheckCols:\n    @pytest.fixture(scope=\"class\")\n    def snapshots(self):\n        return {\"snapshot.sql\": snapshots_check_col_noconfig__snapshot_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": models__schema_yml,\n            \"ref_snapshot.sql\": models__ref_snapshot_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"test_no_overlaps.sql\": macros__test_no_overlaps_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\"seed_newcol.csv\": seeds__seed_newcol_csv, \"seed.csv\": seeds__seed_csv}\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        snapshot_config = {\n            \"snapshots\": {\n                \"test\": {\n                    \"target_schema\": \"{{ target.schema }}\",\n                    \"unique_key\": \"id || '-' || first_name\",\n                    \"strategy\": \"check\",\n                    \"check_cols\": \"all\",\n                    \"updated_at\": \"updated_at\",\n                }\n            }\n        }\n        return snapshot_config\n\n\nclass TestBasicUpdatedAtCheckCols(UpdatedAtCheckCols):\n    def test_updated_at_snapshot(self, project):\n        snapshot_setup(project, num_snapshot_models=2)\n\n        snapshot_expected_relation = relation_from_name(project.adapter, \"snapshot_expected\")\n        revived_records = project.run_sql(\n            \"\"\"\n            select id, updated_at, dbt_valid_from from {}\n            \"\"\".format(\n                snapshot_expected_relation\n            ),\n            fetch=\"all\",\n        )\n        for result in revived_records:\n            # result is a tuple, the updated_at is second and dbt_valid_from is latest\n            assert isinstance(result[1], datetime)\n            assert isinstance(result[2], datetime)\n            assert result[1].replace(tzinfo=pytz.UTC) == result[2].replace(tzinfo=pytz.UTC)\n\n\nclass TestRefUpdatedAtCheckCols(UpdatedAtCheckCols):\n    def test_updated_at_ref(self, project):\n        ref_setup(project, num_snapshot_models=2)\n\n\nclass BasicYaml(Basic):\n    @pytest.fixture(scope=\"class\")\n    def snapshots(self):\n        \"\"\"Overrides the same function in Basic to use the YAML method of\n        defining a snapshot.\"\"\"\n        return {\n            \"snapshot.yml\": snapshots_pg__snapshot_yml,\n            \"source_snapshot.yml\": snapshots_pg__source_snapshot_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        \"\"\"Overrides the same function in Basic to use a modified version of\n        schema.yml without snapshot config.\"\"\"\n        return {\n            \"sources.yml\": sources_pg__source_yml,\n            \"ref_snapshot.sql\": models__ref_snapshot_sql,\n        }\n\n\nclass TestBasicSnapshotYaml(BasicYaml):\n    def test_basic_snapshot_yaml(self, project):\n        snapshot_setup(project, num_snapshot_models=2)\n\n\nclass TestYamlSnapshotCompiledPath(BasicYaml):\n    def test_compiled_path(self, project):\n        \"\"\"Verify yml-based snapshots get correct compiled paths without doubling.\"\"\"\n        manifest = run_dbt([\"parse\"])\n        node = manifest.nodes[\"snapshot.test.snapshot_actual\"]\n        assert node.path == \"snapshot_actual.sql\"\n        assert node.original_file_path == os.path.join(\"snapshots\", \"snapshot.yml\")\n\n        run_dbt([\"compile\"])\n        expected = os.path.join(\n            project.project_root,\n            \"target\",\n            \"compiled\",\n            \"test\",\n            \"snapshots\",\n            \"snapshot.yml\",\n            \"snapshot_actual.sql\",\n        )\n        assert os.path.exists(expected), f\"Compiled file not found: {expected}\"\n\n\nclass TestYamlSnapshotPartialParsing(BasicYaml):\n    def test_snapshot_partial_parsing(self, project):\n        manifest = run_dbt([\"parse\"])\n        snapshot_id = \"snapshot.test.snapshot_actual\"\n        assert snapshot_id in manifest.nodes\n        snapshot = manifest.nodes[snapshot_id]\n        assert snapshot.meta[\"owner\"] == \"a_owner\"\n\n        # change an unrelated source file\n        write_file(sources_pg__source_mod_yml, \"models\", \"sources.yml\")\n        manifest = run_dbt([\"parse\"])\n        snapshot = manifest.nodes[snapshot_id]\n        assert snapshot.meta[\"owner\"] == \"a_owner\"\n\n        # change snapshot yml file and re-parse\n        write_file(snapshots_pg__snapshot_mod_yml, \"snapshots\", \"snapshot.yml\")\n        manifest = run_dbt([\"parse\"])\n        snapshot = manifest.nodes[snapshot_id]\n        assert snapshot.meta[\"owner\"] == \"b_owner\"\n\n        # modify dbt_project.yml and re-parse\n        config_updates = {\n            \"snapshots\": {\n                \"test\": {\n                    \"+snapshot_meta_column_names\": {\n                        \"dbt_valid_to\": \"test_valid_to\",\n                        \"dbt_valid_from\": \"test_valid_from\",\n                    },\n                }\n            }\n        }\n        update_config_file(config_updates, \"dbt_project.yml\")\n        manifest = run_dbt([\"parse\"])\n        snapshot = manifest.nodes[snapshot_id]\n        assert snapshot.config.snapshot_meta_column_names.dbt_valid_to == \"test_valid_to\"\n"
  },
  {
    "path": "tests/functional/snapshots/test_changing_check_cols_snapshot.py",
    "content": "import pytest\n\nfrom dbt.tests.util import check_relations_equal, run_dbt\n\nsnapshot_sql = \"\"\"\n{% snapshot snapshot_check_cols_new_column %}\n    {{\n        config(\n            target_database=database,\n            target_schema=schema,\n            strategy='check',\n            unique_key='id',\n            check_cols=var(\"check_cols\", ['name']),\n            updated_at=\"'\" ~ var(\"updated_at\") ~  \"'::timestamp\",\n        )\n    }}\n\n    {% if var('version') == 1 %}\n\n        select 1 as id, 'foo' as name\n\n    {% else %}\n\n        select 1 as id, 'foo' as name, 'bar' as other\n\n    {% endif %}\n\n{% endsnapshot %}\n\"\"\"\n\nexpected_csv = \"\"\"\nid,name,other,dbt_scd_id,dbt_updated_at,dbt_valid_from,dbt_valid_to\n1,foo,NULL,0d73ad1b216ad884c9f7395d799c912c,2016-07-01 00:00:00.000,2016-07-01 00:00:00.000,2016-07-02 00:00:00.000\n1,foo,bar,7df3783934a6a707d51254859260b9ff,2016-07-02 00:00:00.000,2016-07-02 00:00:00.000,\n\"\"\".lstrip()\n\n\n@pytest.fixture(scope=\"class\")\ndef snapshots():\n    return {\"snapshot_check_cols_new_column.sql\": snapshot_sql}\n\n\n@pytest.fixture(scope=\"class\")\ndef seeds():\n    return {\"snapshot_check_cols_new_column_expected.csv\": expected_csv}\n\n\n@pytest.fixture(scope=\"class\")\ndef project_config_update():\n    return {\n        \"seeds\": {\n            \"quote_columns\": False,\n            \"test\": {\n                \"snapshot_check_cols_new_column_expected\": {\n                    \"+column_types\": {\n                        \"dbt_updated_at\": \"timestamp without time zone\",\n                        \"dbt_valid_from\": \"timestamp without time zone\",\n                        \"dbt_valid_to\": \"timestamp without time zone\",\n                    },\n                },\n            },\n        },\n    }\n\n\ndef run_check_cols_snapshot_with_schema_change(project, check_cols_override=None):\n    \"\"\"\n    Test that snapshots using the \"check\" strategy and explicit check_cols support adding columns.\n\n    Approach:\n    1. Take a snapshot that checks a single non-id column\n    2. Add a new column to the data\n    3. Take a snapshot that checks the new non-id column too\n\n    As long as no error is thrown, then the snapshot was successful\n    \"\"\"\n\n    check_cols = check_cols_override or [\"name\", \"other\"]\n\n    # 1. Create a table that represents the expected data after a series of snapshots\n    vars_dict = {\"version\": 1, \"updated_at\": \"2016-07-01\"}\n    results = run_dbt([\"seed\", \"--show\", \"--vars\", str(vars_dict)])\n    assert len(results) == 1\n\n    # Snapshot 1\n    # Use only 'name' for check_cols\n    vars_dict = {\"version\": 1, \"check_cols\": [check_cols[0]], \"updated_at\": \"2016-07-01\"}\n    results = run_dbt([\"snapshot\", \"--vars\", str(vars_dict)])\n    assert len(results) == 1\n\n    # Snapshot 2\n    # Use both 'name' and 'other' for check_cols\n    vars_dict = {\"version\": 2, \"check_cols\": check_cols, \"updated_at\": \"2016-07-02\"}\n    results = run_dbt([\"snapshot\", \"--vars\", str(vars_dict)])\n    assert len(results) == 1\n\n    check_relations_equal(\n        project.adapter,\n        [\"snapshot_check_cols_new_column\", \"snapshot_check_cols_new_column_expected\"],\n        compare_snapshot_cols=True,\n    )\n\n    # Snapshot 3\n    # Run it again. Nothing has changed — ensure we don't detect changes\n    vars_dict = {\"version\": 2, \"check_cols\": check_cols, \"updated_at\": \"2016-07-02\"}\n    results = run_dbt([\"snapshot\", \"--vars\", str(vars_dict)])\n    assert len(results) == 1\n\n    check_relations_equal(\n        project.adapter,\n        [\"snapshot_check_cols_new_column\", \"snapshot_check_cols_new_column_expected\"],\n        compare_snapshot_cols=True,\n    )\n\n\ndef test_check_cols_snapshot_with_schema_change(project):\n    run_check_cols_snapshot_with_schema_change(project)\n\n\ndef test_check_cols_snapshot_with_schema_change_and_mismatched_casing(project):\n    \"\"\"\n    Test that this still works if the database-stored version of 'name' + 'other'\n    differs from the user-configured 'NAME' and 'OTHER'\n    \"\"\"\n    run_check_cols_snapshot_with_schema_change(\n        project=project, check_cols_override=[\"NAME\", \"OTHER\"]\n    )\n"
  },
  {
    "path": "tests/functional/snapshots/test_changing_strategy_snapshot.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt\nfrom tests.functional.snapshots.fixtures import models_slow__gen_sql\n\ntest_snapshots_changing_strategy__test_snapshot_sql = \"\"\"\n\n{# /*\n    Given the repro case for the snapshot build, we'd\n    expect to see both records have color='pink'\n    in their most recent rows.\n*/ #}\n\nwith expected as (\n\n    select 1 as id, 'pink' as color union all\n    select 2 as id, 'pink' as color\n\n),\n\nactual as (\n\n    select id, color\n    from {{ ref('my_snapshot') }}\n    where color = 'pink'\n      and dbt_valid_to is null\n\n)\n\nselect * from expected\nexcept\nselect * from actual\n\nunion all\n\nselect * from actual\nexcept\nselect * from expected\n\"\"\"\n\n\nsnapshots_changing_strategy__snapshot_sql = \"\"\"\n\n{#\n    REPRO:\n        1. Run with check strategy\n        2. Add a new ts column and run with check strategy\n        3. Run with timestamp strategy on new ts column\n\n        Expect: new entry is added for changed rows in (3)\n#}\n\n\n{% snapshot my_snapshot %}\n\n    {#--------------- Configuration ------------ #}\n\n    {{ config(\n        target_schema=schema,\n        unique_key='id'\n    ) }}\n\n    {% if var('strategy') == 'timestamp' %}\n        {{ config(strategy='timestamp', updated_at='updated_at') }}\n    {% else %}\n        {{ config(strategy='check', check_cols=['color']) }}\n    {% endif %}\n\n    {#--------------- Test setup ------------ #}\n\n    {% if var('step') == 1 %}\n\n        select 1 as id, 'blue' as color\n        union all\n        select 2 as id, 'red' as color\n\n    {% elif var('step') == 2 %}\n\n        -- change id=1 color from blue to green\n        -- id=2 is unchanged when using the check strategy\n        select 1 as id, 'green' as color, '2020-01-01'::date as updated_at\n        union all\n        select 2 as id, 'red' as color, '2020-01-01'::date as updated_at\n\n    {% elif var('step') == 3 %}\n\n        -- bump timestamp for both records. Expect that after this runs\n        -- using the timestamp strategy, both ids should have the color\n        -- 'pink' in the database. This should be in the future b/c we're\n        -- going to compare to the check timestamp, which will be _now_\n        select 1 as id, 'pink' as color, (now() + interval '1 day')::date as updated_at\n        union all\n        select 2 as id, 'pink' as color, (now() + interval '1 day')::date as updated_at\n\n    {% endif %}\n\n{% endsnapshot %}\n\"\"\"\n\n\n@pytest.fixture(scope=\"class\")\ndef models():\n    return {\"gen.sql\": models_slow__gen_sql}\n\n\n@pytest.fixture(scope=\"class\")\ndef snapshots():\n    return {\"snapshot.sql\": snapshots_changing_strategy__snapshot_sql}\n\n\n@pytest.fixture(scope=\"class\")\ndef tests():\n    return {\"test_snapshot.sql\": test_snapshots_changing_strategy__test_snapshot_sql}\n\n\ndef test_changing_strategy(project):\n    results = run_dbt([\"snapshot\", \"--vars\", \"{strategy: check, step: 1}\"])\n    assert len(results) == 1\n\n    results = run_dbt([\"snapshot\", \"--vars\", \"{strategy: check, step: 2}\"])\n    assert len(results) == 1\n\n    results = run_dbt([\"snapshot\", \"--vars\", \"{strategy: timestamp, step: 3}\"])\n    assert len(results) == 1\n\n    results = run_dbt([\"test\"])\n    assert len(results) == 1\n"
  },
  {
    "path": "tests/functional/snapshots/test_check_cols_snapshot.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt\n\nsnapshot_sql = \"\"\"\n{% snapshot check_cols_cycle %}\n\n    {{\n        config(\n            target_database=database,\n            target_schema=schema,\n            unique_key='id',\n            strategy='check',\n            check_cols=['color']\n        )\n    }}\n\n    {% if var('version') == 1 %}\n\n        select 1 as id, 'red' as color union all\n        select 2 as id, 'green' as color\n\n    {% elif var('version') == 2 %}\n\n        select 1 as id, 'blue' as color union all\n        select 2 as id, 'green' as color\n\n    {% elif var('version') == 3 %}\n\n        select 1 as id, 'red' as color union all\n        select 2 as id, 'pink' as color\n\n    {% else %}\n        {% do exceptions.raise_compiler_error(\"Got bad version: \" ~ var('version')) %}\n    {% endif %}\n\n{% endsnapshot %}\n\"\"\"\n\nsnapshot_test_sql = \"\"\"\nwith query as (\n\n    -- check that the current value for id=1 is red\n    select case when (\n        select count(*)\n        from {{ ref('check_cols_cycle') }}\n        where id = 1 and color = 'red' and dbt_valid_to is null\n    ) = 1 then 0 else 1 end as failures\n\n    union all\n\n    -- check that the previous 'red' value for id=1 is invalidated\n    select case when (\n        select count(*)\n        from {{ ref('check_cols_cycle') }}\n        where id = 1 and color = 'red' and dbt_valid_to is not null\n    ) = 1 then 0 else 1 end as failures\n\n    union all\n\n    -- check that there's only one current record for id=2\n    select case when (\n        select count(*)\n        from {{ ref('check_cols_cycle') }}\n        where id = 2 and color = 'pink' and dbt_valid_to is null\n    ) = 1 then 0 else 1 end as failures\n\n    union all\n\n    -- check that the previous value for id=2 is represented\n    select case when (\n        select count(*)\n        from {{ ref('check_cols_cycle') }}\n        where id = 2 and color = 'green' and dbt_valid_to is not null\n    ) = 1 then 0 else 1 end as failures\n\n    union all\n\n    -- check that there are 5 records total in the table\n    select case when (\n        select count(*)\n        from {{ ref('check_cols_cycle') }}\n    ) = 5 then 0 else 1 end as failures\n\n)\n\nselect *\nfrom query\nwhere failures = 1\n\"\"\"\n\n\n@pytest.fixture(scope=\"class\")\ndef snapshots():\n    return {\"my_snapshot.sql\": snapshot_sql}\n\n\n@pytest.fixture(scope=\"class\")\ndef tests():\n    return {\"my_test.sql\": snapshot_test_sql}\n\n\ndef test_snapshots(project):\n\n    results = run_dbt([\"snapshot\", \"--vars\", \"version: 1\"])\n    assert len(results) == 1\n\n    results = run_dbt([\"snapshot\", \"--vars\", \"version: 2\"])\n    assert len(results) == 1\n\n    results = run_dbt([\"snapshot\", \"--vars\", \"version: 3\"])\n    assert len(results) == 1\n\n    run_dbt([\"test\", \"--select\", \"test_type:singular\", \"--vars\", \"version: 3\"])\n"
  },
  {
    "path": "tests/functional/snapshots/test_check_cols_updated_at_snapshot.py",
    "content": "import pytest\n\nfrom dbt.tests.util import check_relations_equal, run_dbt\n\nsnapshot_sql = \"\"\"\n{% snapshot snapshot_check_cols_updated_at_actual %}\n    {{\n        config(\n            target_database=database,\n            target_schema=schema,\n            unique_key='id',\n            strategy='check',\n            check_cols='all',\n            updated_at=\"'\" ~ var(\"updated_at\") ~  \"'::timestamp\",\n        )\n    }}\n\n    {% if var('version') == 1 %}\n\n        select 'a' as id, 10 as counter, '2016-01-01T00:00:00Z'::timestamp as timestamp_col union all\n        select 'b' as id, 20 as counter, '2016-01-01T00:00:00Z'::timestamp as timestamp_col\n\n    {% elif var('version') == 2 %}\n\n        select 'a' as id, 30 as counter, '2016-01-02T00:00:00Z'::timestamp as timestamp_col union all\n        select 'b' as id, 20 as counter, '2016-01-01T00:00:00Z'::timestamp as timestamp_col union all\n        select 'c' as id, 40 as counter, '2016-01-02T00:00:00Z'::timestamp as timestamp_col\n\n    {% else %}\n\n        select 'a' as id, 30 as counter, '2016-01-02T00:00:00Z'::timestamp as timestamp_col union all\n        select 'c' as id, 40 as counter, '2016-01-02T00:00:00Z'::timestamp as timestamp_col\n\n    {% endif %}\n\n{% endsnapshot %}\n\"\"\"\n\nexpected_csv = \"\"\"\nid,counter,timestamp_col,dbt_scd_id,dbt_updated_at,dbt_valid_from,dbt_valid_to\na,10,2016-01-01 00:00:00.000,927354aa091feffd9437ead0bdae7ae1,2016-07-01 00:00:00.000,2016-07-01 00:00:00.000,2016-07-02 00:00:00.000\nb,20,2016-01-01 00:00:00.000,40ace4cbf8629f1720ec8a529ed76f8c,2016-07-01 00:00:00.000,2016-07-01 00:00:00.000,\na,30,2016-01-02 00:00:00.000,e9133f2b302c50e36f43e770944cec9b,2016-07-02 00:00:00.000,2016-07-02 00:00:00.000,\nc,40,2016-01-02 00:00:00.000,09d33d35101e788c152f65d0530b6837,2016-07-02 00:00:00.000,2016-07-02 00:00:00.000,\n\"\"\".lstrip()\n\n\n@pytest.fixture(scope=\"class\")\ndef snapshots():\n    return {\"snapshot_check_cols_updated_at_actual.sql\": snapshot_sql}\n\n\n@pytest.fixture(scope=\"class\")\ndef seeds():\n    return {\"snapshot_check_cols_updated_at_expected.csv\": expected_csv}\n\n\n@pytest.fixture(scope=\"class\")\ndef project_config_update():\n    return {\n        \"seeds\": {\n            \"quote_columns\": False,\n            \"test\": {\n                \"snapshot_check_cols_updated_at_expected\": {\n                    \"+column_types\": {\n                        \"timestamp_col\": \"timestamp without time zone\",\n                        \"dbt_updated_at\": \"timestamp without time zone\",\n                        \"dbt_valid_from\": \"timestamp without time zone\",\n                        \"dbt_valid_to\": \"timestamp without time zone\",\n                    },\n                },\n            },\n        },\n    }\n\n\ndef test_snapshots(project):\n    \"\"\"\n    Test that the `dbt_updated_at` column reflects the `updated_at` timestamp expression in the config.\n\n    Approach:\n    1. Create a table that represents the expected data after a series of snapshots\n        - Use dbt seed to create the expected relation (`snapshot_check_cols_updated_at_expected`)\n    2. Execute a series of snapshots to create the data\n        - Use a series of (3) dbt snapshot commands to create the actual relation (`snapshot_check_cols_updated_at_actual`)\n        - The logic can switch between 3 different versions of the data (depending on the `version` number)\n        - The `updated_at` value is passed in via `--vars` and cast to a timestamp in the snapshot config\n    3. Compare the two relations for equality\n    \"\"\"\n\n    # 1. Create a table that represents the expected data after a series of snapshots\n    results = run_dbt([\"seed\", \"--show\", \"--vars\", \"{version: 1, updated_at: 2016-07-01}\"])\n    assert len(results) == 1\n\n    # 2. Execute a series of snapshots to create the data\n\n    # Snapshot day 1\n    results = run_dbt([\"snapshot\", \"--vars\", \"{version: 1, updated_at: 2016-07-01}\"])\n    assert len(results) == 1\n\n    # Snapshot day 2\n    results = run_dbt([\"snapshot\", \"--vars\", \"{version: 2, updated_at: 2016-07-02}\"])\n    assert len(results) == 1\n\n    # Snapshot day 3\n    results = run_dbt([\"snapshot\", \"--vars\", \"{version: 3, updated_at: 2016-07-03}\"])\n    assert len(results) == 1\n\n    # 3. Compare the two relations for equality\n    check_relations_equal(\n        project.adapter,\n        [\"snapshot_check_cols_updated_at_actual\", \"snapshot_check_cols_updated_at_expected\"],\n        compare_snapshot_cols=True,\n    )\n"
  },
  {
    "path": "tests/functional/snapshots/test_comment_ending_snapshot.py",
    "content": "import os\n\nimport pytest\n\nfrom dbt.tests.util import run_dbt\n\nsnapshots_with_comment_at_end__snapshot_sql = \"\"\"\n{% snapshot snapshot_actual %}\n    {{\n        config(\n            target_database=var('target_database', database),\n            target_schema=schema,\n            unique_key='id',\n            strategy='check',\n            check_cols=['email'],\n        )\n    }}\n    select * from {{target.database}}.{{schema}}.seed\n    -- Test comment to prevent recurrence of https://github.com/dbt-labs/dbt-core/issues/6781\n{% endsnapshot %}\n\"\"\"\n\n\nclass TestSnapshotsWithCommentAtEnd:\n    @pytest.fixture(scope=\"class\")\n    def snapshots(self):\n        return {\"snapshot.sql\": snapshots_with_comment_at_end__snapshot_sql}\n\n    def test_comment_ending(self, project):\n        path = os.path.join(project.test_data_dir, \"seed_pg.sql\")\n        project.run_sql_file(path)\n        # N.B. Snapshot is run twice to ensure snapshot_check_all_get_existing_columns is fully run\n        # (it exits early if the table doesn't already exist)\n        run_dbt([\"snapshot\"])\n        results = run_dbt([\"snapshot\"])\n        assert len(results) == 1\n"
  },
  {
    "path": "tests/functional/snapshots/test_cross_schema_snapshot.py",
    "content": "import os\n\nimport pytest\n\nfrom dbt.tests.util import run_dbt\nfrom tests.functional.snapshots.fixtures import (\n    macros__test_no_overlaps_sql,\n    models__ref_snapshot_sql,\n    models__schema_yml,\n    snapshots_pg__snapshot_sql,\n)\n\nNUM_SNAPSHOT_MODELS = 1\n\n\n@pytest.fixture(scope=\"class\")\ndef snapshots():\n    return {\"snapshot.sql\": snapshots_pg__snapshot_sql}\n\n\n@pytest.fixture(scope=\"class\")\ndef models():\n    return {\n        \"schema.yml\": models__schema_yml,\n        \"ref_snapshot.sql\": models__ref_snapshot_sql,\n    }\n\n\n@pytest.fixture(scope=\"class\")\ndef macros():\n    return {\"test_no_overlaps.sql\": macros__test_no_overlaps_sql}\n\n\ndef test_cross_schema_snapshot(project):\n    # populate seed and snapshot tables\n    path = os.path.join(project.test_data_dir, \"seed_pg.sql\")\n    project.run_sql_file(path)\n\n    target_schema = \"{}_snapshotted\".format(project.test_schema)\n\n    # create a snapshot using the new schema\n    results = run_dbt([\"snapshot\", \"--vars\", '{{\"target_schema\": \"{}\"}}'.format(target_schema)])\n    assert len(results) == NUM_SNAPSHOT_MODELS\n\n    # run dbt from test_schema with a ref to to new target_schema\n    results = run_dbt([\"run\", \"--vars\", '{{\"target_schema\": {}}}'.format(target_schema)])\n    assert len(results) == 1\n"
  },
  {
    "path": "tests/functional/snapshots/test_hard_delete_snapshot.py",
    "content": "import os\nfrom datetime import datetime, timedelta\n\nimport pytest\nimport pytz\n\nfrom dbt.tests.util import check_relations_equal, run_dbt\nfrom tests.functional.snapshots.fixtures import (\n    macros__test_no_overlaps_sql,\n    models__ref_snapshot_sql,\n    models__schema_yml,\n    snapshots_pg__snapshot_sql,\n)\nfrom tests.functional.utils import is_aware\n\n# These tests uses the same seed data, containing 20 records of which we hard delete the last 10.\n# These deleted records set the dbt_valid_to to time the snapshot was ran.\n\n\ndef convert_to_aware(d: datetime) -> datetime:\n    # There are two types of datetime objects in Python: naive and aware\n    # Add timezone info for consistent comparison\n    if d is None:\n        return d\n    elif is_aware(d):\n        return d\n    else:\n        # Naive datetime from database - add timezone info for comparison\n        # Note: The timestamp is actually in the database's local timezone,\n        # but we add UTC tzinfo for consistency since both test and snapshot\n        # timestamps are treated the same way\n        return d.replace(tzinfo=pytz.UTC)\n\n\ndef is_close_datetime(\n    dt1: datetime, dt2: datetime, atol: timedelta = timedelta(microseconds=1)\n) -> bool:\n    # Similar to pytest.approx, math.isclose, and numpy.isclose\n    # Use an absolute tolerance to compare datetimes that may not be perfectly equal.\n    # Two None values will compare as equal.\n    if dt1 is None and dt2 is None:\n        return True\n    elif dt1 is not None and dt2 is not None:\n        return (dt1 > (dt2 - atol)) and (dt1 < (dt2 + atol))\n    else:\n        return False\n\n\ndef datetime_snapshot(project):\n    NUM_SNAPSHOT_MODELS = 1\n    # Get the timestamp from the database instead of Python to ensure timezone consistency\n    # between local runs and CI runs\n    # Use the same timestamp format that dbt uses for snapshots: timestamp without time zone\n    begin_snapshot_datetime = project.run_sql(\n        \"select current_timestamp::timestamp without time zone\", fetch=\"one\"\n    )[0]\n    results = run_dbt([\"snapshot\", \"--vars\", \"{invalidate_hard_deletes: true}\"])\n    assert len(results) == NUM_SNAPSHOT_MODELS\n\n    return convert_to_aware(begin_snapshot_datetime)\n\n\n@pytest.fixture(scope=\"class\", autouse=True)\ndef setUp(project):\n    path = os.path.join(project.test_data_dir, \"seed_pg.sql\")\n    project.run_sql_file(path)\n\n\n@pytest.fixture(scope=\"class\")\ndef snapshots():\n    return {\"snapshot.sql\": snapshots_pg__snapshot_sql}\n\n\n@pytest.fixture(scope=\"class\")\ndef models():\n    return {\n        \"schema.yml\": models__schema_yml,\n        \"ref_snapshot.sql\": models__ref_snapshot_sql,\n    }\n\n\n@pytest.fixture(scope=\"class\")\ndef macros():\n    return {\"test_no_overlaps.sql\": macros__test_no_overlaps_sql}\n\n\ndef test_snapshot_hard_delete(project):\n    # run the first snapshot\n    datetime_snapshot(project)\n\n    check_relations_equal(project.adapter, [\"snapshot_expected\", \"snapshot_actual\"])\n\n    invalidated_snapshot_datetime = None\n    revived_snapshot_datetime = None\n\n    # hard delete last 10 records\n    project.run_sql(\n        \"delete from {}.{}.seed where id >= 10;\".format(project.database, project.test_schema)\n    )\n\n    # snapshot and assert invalidated\n    invalidated_snapshot_datetime = datetime_snapshot(project)\n\n    snapshotted = project.run_sql(\n        \"\"\"\n        select\n            id,\n            dbt_valid_to\n        from {}.{}.snapshot_actual\n        order by id\n        \"\"\".format(\n            project.database, project.test_schema\n        ),\n        fetch=\"all\",\n    )\n\n    assert len(snapshotted) == 20\n    for result in snapshotted[10:]:\n        # result is a tuple, the dbt_valid_to column is the latest\n        assert isinstance(result[-1], datetime)\n        dbt_valid_to = convert_to_aware(result[-1])\n\n        # Plenty of wiggle room if clocks aren't perfectly sync'd, etc\n        assert is_close_datetime(\n            dbt_valid_to, invalidated_snapshot_datetime, timedelta(minutes=1)\n        ), f\"SQL timestamp {dbt_valid_to.isoformat()} is not close enough to test timestamp {invalidated_snapshot_datetime.isoformat()}\"\n\n    # revive records\n    # Timestamp must have microseconds for tests below to be meaningful\n    revival_timestamp_dt = project.run_sql(\n        \"select current_timestamp::timestamp without time zone\", fetch=\"one\"\n    )[0]\n    revival_timestamp = revival_timestamp_dt.strftime(\"%Y-%m-%d %H:%M:%S.%f\")\n    project.run_sql(\n        \"\"\"\n        insert into {}.{}.seed (id, first_name, last_name, email, gender, ip_address, updated_at) values\n        (10, 'Rachel', 'Lopez', 'rlopez9@themeforest.net', 'Female', '237.165.82.71', '{}'),\n        (11, 'Donna', 'Welch', 'dwelcha@shutterfly.com', 'Female', '103.33.110.138', '{}')\n        \"\"\".format(\n            project.database, project.test_schema, revival_timestamp, revival_timestamp\n        )\n    )\n\n    # snapshot and assert records were revived\n    # Note: the revived_snapshot_datetime here is later than the revival_timestamp above\n    revived_snapshot_datetime = datetime_snapshot(project)\n\n    # records which weren't revived (id != 10, 11)\n    # dbt_valid_to is not null\n    invalidated_records = project.run_sql(\n        \"\"\"\n        select\n            id,\n            dbt_valid_to\n        from {}.{}.snapshot_actual\n        where dbt_valid_to is not null\n        order by id\n        \"\"\".format(\n            project.database, project.test_schema\n        ),\n        fetch=\"all\",\n    )\n\n    assert len(invalidated_records) == 11\n    for result in invalidated_records:\n        # result is a tuple, the dbt_valid_to column is the latest\n        assert isinstance(result[1], datetime)\n        dbt_valid_to = convert_to_aware(result[1])\n\n        # Plenty of wiggle room if clocks aren't perfectly sync'd, etc\n        assert is_close_datetime(\n            dbt_valid_to, invalidated_snapshot_datetime, timedelta(minutes=1)\n        ), f\"SQL timestamp {dbt_valid_to.isoformat()} is not close enough to test timestamp {invalidated_snapshot_datetime.isoformat()}\"\n\n    # records which were revived (id = 10, 11)\n    # dbt_valid_to is null\n    revived_records = project.run_sql(\n        \"\"\"\n        select\n            id,\n            dbt_valid_from,\n            dbt_valid_to\n        from {}.{}.snapshot_actual\n        where dbt_valid_to is null\n        and id IN (10, 11)\n        \"\"\".format(\n            project.database, project.test_schema\n        ),\n        fetch=\"all\",\n    )\n\n    assert len(revived_records) == 2\n    for result in revived_records:\n        # result is a tuple, the dbt_valid_from is second and dbt_valid_to is latest\n        # dbt_valid_from is the same as the 'updated_at' added in the revived_rows\n        # dbt_valid_to is null\n        assert isinstance(result[1], datetime)\n        dbt_valid_from = convert_to_aware(result[1])\n        dbt_valid_to = result[2]\n\n        assert dbt_valid_from <= revived_snapshot_datetime\n        assert dbt_valid_to is None\n"
  },
  {
    "path": "tests/functional/snapshots/test_invalid_namespace_snapshot.py",
    "content": "import os\n\nimport pytest\n\nfrom dbt.tests.util import run_dbt\nfrom tests.functional.snapshots.fixtures import (\n    macros__test_no_overlaps_sql,\n    macros_custom_snapshot__custom_sql,\n    models__ref_snapshot_sql,\n    models__schema_yml,\n    seeds__seed_csv,\n    seeds__seed_newcol_csv,\n)\n\nNUM_SNAPSHOT_MODELS = 1\n\n\nsnapshots_pg_custom_invalid__snapshot_sql = \"\"\"\n{% snapshot snapshot_actual %}\n    {# this custom strategy does not exist  in the 'dbt' package #}\n    {{\n        config(\n            target_database=var('target_database', database),\n            target_schema=var('target_schema', schema),\n            unique_key='id || ' ~ \"'-'\" ~ ' || first_name',\n            strategy='dbt.custom',\n            updated_at='updated_at',\n        )\n    }}\n    select * from {{target.database}}.{{target.schema}}.seed\n\n{% endsnapshot %}\n\"\"\"\n\n\n@pytest.fixture(scope=\"class\")\ndef snapshots():\n    return {\"snapshots.sql\": snapshots_pg_custom_invalid__snapshot_sql}\n\n\n@pytest.fixture(scope=\"class\")\ndef macros():\n    return {\n        \"test_no_overlaps.sql\": macros__test_no_overlaps_sql,\n        \"custom.sql\": macros_custom_snapshot__custom_sql,\n    }\n\n\n@pytest.fixture(scope=\"class\")\ndef models():\n    return {\n        \"schema.yml\": models__schema_yml,\n        \"ref_snapshot.sql\": models__ref_snapshot_sql,\n    }\n\n\n@pytest.fixture(scope=\"class\")\ndef seeds():\n    return {\"seed_newcol.csv\": seeds__seed_newcol_csv, \"seed.csv\": seeds__seed_csv}\n\n\ndef test_custom_snapshot_invalid_namespace(project):\n    path = os.path.join(project.test_data_dir, \"seed_pg.sql\")\n    project.run_sql_file(path)\n    results = run_dbt([\"snapshot\"], expect_pass=False)\n    assert len(results) == NUM_SNAPSHOT_MODELS\n"
  },
  {
    "path": "tests/functional/snapshots/test_long_text_snapshot.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt\nfrom tests.functional.snapshots.fixtures import (\n    macros__test_no_overlaps_sql,\n    models__ref_snapshot_sql,\n    models__schema_yml,\n)\n\nseed_longtext_sql = \"\"\"\ncreate table {database}.{schema}.super_long (\n    id INTEGER,\n    longstring TEXT,\n    updated_at TIMESTAMP WITHOUT TIME ZONE\n);\n\ninsert into {database}.{schema}.super_long (id, longstring, updated_at) VALUES\n(1, 'short', current_timestamp),\n(2, repeat('a', 500), current_timestamp);\n\"\"\"\n\nsnapshots_longtext__snapshot_sql = \"\"\"\n{% snapshot snapshot_actual %}\n    {{\n        config(\n            target_database=var('target_database', database),\n            target_schema=schema,\n            unique_key='id',\n            strategy='timestamp',\n            updated_at='updated_at',\n        )\n    }}\n    select * from {{target.database}}.{{schema}}.super_long\n{% endsnapshot %}\n\"\"\"\n\n\n@pytest.fixture(scope=\"class\")\ndef snapshots():\n    return {\"snapshot.sql\": snapshots_longtext__snapshot_sql}\n\n\n@pytest.fixture(scope=\"class\")\ndef models():\n    return {\n        \"schema.yml\": models__schema_yml,\n        \"ref_snapshot.sql\": models__ref_snapshot_sql,\n    }\n\n\n@pytest.fixture(scope=\"class\")\ndef macros():\n    return {\"test_no_overlaps.sql\": macros__test_no_overlaps_sql}\n\n\ndef test_long_text(project):\n    project.run_sql(seed_longtext_sql)\n\n    results = run_dbt([\"snapshot\"])\n    assert len(results) == 1\n\n    with project.adapter.connection_named(\"test\"):\n        status, results = project.adapter.execute(\n            \"select * from {}.{}.snapshot_actual\".format(project.database, project.test_schema),\n            fetch=True,\n        )\n    assert len(results) == 2\n    got_names = set(r.get(\"longstring\") for r in results)\n    assert got_names == {\"a\" * 500, \"short\"}\n"
  },
  {
    "path": "tests/functional/snapshots/test_missing_strategy_snapshot.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt\nfrom dbt_common.dataclass_schema import ValidationError\nfrom tests.functional.snapshots.fixtures import (\n    macros__test_no_overlaps_sql,\n    models__ref_snapshot_sql,\n    models__schema_yml,\n)\n\nsnapshots_invalid__snapshot_sql = \"\"\"\n{% snapshot snapshot_actual %}\n    {# missing the mandatory strategy parameter #}\n    {{\n        config(\n            unique_key='id || ' ~ \"'-'\" ~ ' || first_name',\n            updated_at='updated_at',\n        )\n    }}\n    select * from {{target.database}}.{{schema}}.seed\n\n{% endsnapshot %}\n\"\"\"\n\n\n@pytest.fixture(scope=\"class\")\ndef snapshots():\n    return {\"snapshot.sql\": snapshots_invalid__snapshot_sql}\n\n\n@pytest.fixture(scope=\"class\")\ndef models():\n    return {\n        \"schema.yml\": models__schema_yml,\n        \"ref_snapshot.sql\": models__ref_snapshot_sql,\n    }\n\n\n@pytest.fixture(scope=\"class\")\ndef macros():\n    return {\"test_no_overlaps.sql\": macros__test_no_overlaps_sql}\n\n\ndef test_missing_strategy(project):\n    with pytest.raises(ValidationError) as exc:\n        run_dbt([\"compile\"], expect_pass=False)\n\n    assert \"Snapshots must be configured with a 'strategy' and 'unique_key'\" in str(exc.value)\n"
  },
  {
    "path": "tests/functional/snapshots/test_renamed_source_snapshot.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt\nfrom tests.functional.snapshots.fixtures import (\n    macros__test_no_overlaps_sql,\n    macros_custom_snapshot__custom_sql,\n    seeds__seed_csv,\n    seeds__seed_newcol_csv,\n)\n\nsnapshots_checkall__snapshot_sql = \"\"\"\n{% snapshot my_snapshot %}\n    {{ config(check_cols='all', unique_key='id', strategy='check', target_database=database, target_schema=schema) }}\n    select * from {{ ref(var('seed_name', 'seed')) }}\n{% endsnapshot %}\n\"\"\"\n\n\n@pytest.fixture(scope=\"class\")\ndef snapshots():\n    return {\"snapshot.sql\": snapshots_checkall__snapshot_sql}\n\n\n@pytest.fixture(scope=\"class\")\ndef macros():\n    return {\n        \"test_no_overlaps.sql\": macros__test_no_overlaps_sql,\n        \"custom.sql\": macros_custom_snapshot__custom_sql,\n    }\n\n\n@pytest.fixture(scope=\"class\")\ndef seeds():\n    return {\"seed_newcol.csv\": seeds__seed_newcol_csv, \"seed.csv\": seeds__seed_csv}\n\n\ndef test_renamed_source(project):\n    run_dbt([\"seed\"])\n    run_dbt([\"snapshot\"])\n    database = project.database\n    results = project.run_sql(\n        \"select * from {}.{}.my_snapshot\".format(database, project.test_schema),\n        fetch=\"all\",\n    )\n    assert len(results) == 3\n    for result in results:\n        assert len(result) == 6\n\n    # over ride the ref var in the snapshot definition to use a seed with an additional column, last_name\n    run_dbt([\"snapshot\", \"--vars\", \"{seed_name: seed_newcol}\"])\n    results = project.run_sql(\n        \"select * from {}.{}.my_snapshot where last_name is not NULL\".format(\n            database, project.test_schema\n        ),\n        fetch=\"all\",\n    )\n    assert len(results) == 3\n\n    for result in results:\n        # new column\n        assert len(result) == 7\n        assert result[-1] is not None\n\n    results = project.run_sql(\n        \"select * from {}.{}.my_snapshot where last_name is NULL\".format(\n            database, project.test_schema\n        ),\n        fetch=\"all\",\n    )\n    assert len(results) == 3\n    for result in results:\n        # new column\n        assert len(result) == 7\n"
  },
  {
    "path": "tests/functional/snapshots/test_select_exclude_snapshot.py",
    "content": "import os\n\nimport pytest\n\nfrom dbt.tests.util import check_relations_equal, check_table_does_not_exist, run_dbt\nfrom tests.functional.snapshots.fixtures import (\n    macros__test_no_overlaps_sql,\n    models__ref_snapshot_sql,\n    models__schema_yml,\n    seeds__seed_csv,\n    seeds__seed_newcol_csv,\n    snapshots_pg__snapshot_sql,\n    snapshots_select__snapshot_sql,\n    snapshots_select_noconfig__snapshot_sql,\n)\n\n\ndef all_snapshots(project):\n    path = os.path.join(project.test_data_dir, \"seed_pg.sql\")\n    project.run_sql_file(path)\n\n    results = run_dbt([\"snapshot\"])\n    assert len(results) == 4\n\n    check_relations_equal(project.adapter, [\"snapshot_castillo\", \"snapshot_castillo_expected\"])\n    check_relations_equal(project.adapter, [\"snapshot_alvarez\", \"snapshot_alvarez_expected\"])\n    check_relations_equal(project.adapter, [\"snapshot_kelly\", \"snapshot_kelly_expected\"])\n    check_relations_equal(project.adapter, [\"snapshot_actual\", \"snapshot_expected\"])\n\n    path = os.path.join(project.test_data_dir, \"invalidate_postgres.sql\")\n    project.run_sql_file(path)\n\n    path = os.path.join(project.test_data_dir, \"update.sql\")\n    project.run_sql_file(path)\n\n    results = run_dbt([\"snapshot\"])\n    assert len(results) == 4\n    check_relations_equal(project.adapter, [\"snapshot_castillo\", \"snapshot_castillo_expected\"])\n    check_relations_equal(project.adapter, [\"snapshot_alvarez\", \"snapshot_alvarez_expected\"])\n    check_relations_equal(project.adapter, [\"snapshot_kelly\", \"snapshot_kelly_expected\"])\n    check_relations_equal(project.adapter, [\"snapshot_actual\", \"snapshot_expected\"])\n\n\ndef exclude_snapshots(project):\n    path = os.path.join(project.test_data_dir, \"seed_pg.sql\")\n    project.run_sql_file(path)\n    results = run_dbt([\"snapshot\", \"--exclude\", \"snapshot_castillo\"])\n    assert len(results) == 3\n\n    check_table_does_not_exist(project.adapter, \"snapshot_castillo\")\n    check_relations_equal(project.adapter, [\"snapshot_alvarez\", \"snapshot_alvarez_expected\"])\n    check_relations_equal(project.adapter, [\"snapshot_kelly\", \"snapshot_kelly_expected\"])\n    check_relations_equal(project.adapter, [\"snapshot_actual\", \"snapshot_expected\"])\n\n\ndef select_snapshots(project):\n    path = os.path.join(project.test_data_dir, \"seed_pg.sql\")\n    project.run_sql_file(path)\n    results = run_dbt([\"snapshot\", \"--select\", \"snapshot_castillo\"])\n    assert len(results) == 1\n\n    check_relations_equal(project.adapter, [\"snapshot_castillo\", \"snapshot_castillo_expected\"])\n    check_table_does_not_exist(project.adapter, \"snapshot_alvarez\")\n    check_table_does_not_exist(project.adapter, \"snapshot_kelly\")\n    check_table_does_not_exist(project.adapter, \"snapshot_actual\")\n\n\n# all of the tests below use one of both of the above tests with\n# various combinations of snapshots and macros\nclass SelectBasicSetup:\n    @pytest.fixture(scope=\"class\")\n    def snapshots(self):\n        return {\n            \"snapshot.sql\": snapshots_pg__snapshot_sql,\n            \"snapshot_select.sql\": snapshots_select__snapshot_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\"seed_newcol.csv\": seeds__seed_newcol_csv, \"seed.csv\": seeds__seed_csv}\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": models__schema_yml,\n            \"ref_snapshot.sql\": models__ref_snapshot_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"test_no_overlaps.sql\": macros__test_no_overlaps_sql}\n\n\nclass TestAllBasic(SelectBasicSetup):\n    def test_all_snapshots(self, project):\n        all_snapshots(project)\n\n\nclass TestExcludeBasic(SelectBasicSetup):\n    def test_exclude_snapshots(self, project):\n        exclude_snapshots(project)\n\n\nclass TestSelectBasic(SelectBasicSetup):\n    def test_select_snapshots(self, project):\n        select_snapshots(project)\n\n\nclass SelectConfiguredSetup:\n    @pytest.fixture(scope=\"class\")\n    def snapshots(self):\n        return {\"snapshot.sql\": snapshots_select_noconfig__snapshot_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\"seed_newcol.csv\": seeds__seed_newcol_csv, \"seed.csv\": seeds__seed_csv}\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": models__schema_yml,\n            \"ref_snapshot.sql\": models__ref_snapshot_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"test_no_overlaps.sql\": macros__test_no_overlaps_sql}\n\n    # TODO: don't have access to project here so this breaks\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        snapshot_config = {\n            \"snapshots\": {\n                \"test\": {\n                    \"target_schema\": \"{{ target.schema }}\",\n                    \"unique_key\": \"id || '-' || first_name\",\n                    \"strategy\": \"timestamp\",\n                    \"updated_at\": \"updated_at\",\n                }\n            }\n        }\n        return snapshot_config\n\n\nclass TestConfigured(SelectConfiguredSetup):\n    def test_all_configured_snapshots(self, project):\n        all_snapshots(project)\n\n\nclass TestConfiguredExclude(SelectConfiguredSetup):\n    def test_exclude_configured_snapshots(self, project):\n        exclude_snapshots(project)\n\n\nclass TestConfiguredSelect(SelectConfiguredSetup):\n    def test_select_configured_snapshots(self, project):\n        select_snapshots(project)\n"
  },
  {
    "path": "tests/functional/snapshots/test_slow_query_snapshot.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt\nfrom tests.functional.snapshots.fixtures import models_slow__gen_sql\n\nsnapshots_slow__snapshot_sql = \"\"\"\n\n{% snapshot my_slow_snapshot %}\n\n    {{\n        config(\n            target_database=var('target_database', database),\n            target_schema=schema,\n            unique_key='id',\n            strategy='timestamp',\n            updated_at='updated_at'\n        )\n    }}\n\n    select\n        id,\n        updated_at,\n        seconds\n\n    from {{ ref('gen') }}\n\n{% endsnapshot %}\n\"\"\"\n\n\ntest_snapshots_slow__test_timestamps_sql = \"\"\"\n\n/*\n    Assert that the dbt_valid_from of the latest record\n    is equal to the dbt_valid_to of the previous record\n*/\n\nwith snapshot as (\n\n    select * from {{ ref('my_slow_snapshot') }}\n\n)\n\nselect\n    snap1.id,\n    snap1.dbt_valid_from as new_valid_from,\n    snap2.dbt_valid_from as old_valid_from,\n    snap2.dbt_valid_to as old_valid_to\n\nfrom snapshot as snap1\njoin snapshot as snap2 on snap1.id = snap2.id\nwhere snap1.dbt_valid_to is null\n  and snap2.dbt_valid_to is not null\n  and snap1.dbt_valid_from != snap2.dbt_valid_to\n\"\"\"\n\n\n@pytest.fixture(scope=\"class\")\ndef models():\n    return {\"gen.sql\": models_slow__gen_sql}\n\n\n@pytest.fixture(scope=\"class\")\ndef snapshots():\n    return {\"snapshot.sql\": snapshots_slow__snapshot_sql}\n\n\n@pytest.fixture(scope=\"class\")\ndef tests():\n    return {\"test_timestamps.sql\": test_snapshots_slow__test_timestamps_sql}\n\n\ndef test_slow(project):\n    results = run_dbt([\"snapshot\"])\n    assert len(results) == 1\n\n    results = run_dbt([\"snapshot\"])\n    assert len(results) == 1\n\n    results = run_dbt([\"test\"])\n    assert len(results) == 1\n"
  },
  {
    "path": "tests/functional/snapshots/test_snapshot_column_names.py",
    "content": "import os\n\nimport pytest\n\nfrom dbt.tests.util import (\n    check_relations_equal,\n    get_manifest,\n    run_dbt,\n    run_dbt_and_capture,\n    update_config_file,\n)\n\nsnapshot_actual_sql = \"\"\"\n{% snapshot snapshot_actual %}\n\n    {{\n        config(\n            unique_key='id || ' ~ \"'-'\" ~ ' || first_name',\n        )\n    }}\n\n    select * from {{target.database}}.{{target.schema}}.seed\n\n{% endsnapshot %}\n\"\"\"\n\nsnapshots_yml = \"\"\"\nsnapshots:\n  - name: snapshot_actual\n    config:\n      strategy: timestamp\n      updated_at: updated_at\n      snapshot_meta_column_names:\n          dbt_valid_to: test_valid_to\n          dbt_valid_from: test_valid_from\n          dbt_scd_id: test_scd_id\n          dbt_updated_at: test_updated_at\n\"\"\"\n\nsnapshots_no_column_names_yml = \"\"\"\nsnapshots:\n  - name: snapshot_actual\n    config:\n      strategy: timestamp\n      updated_at: updated_at\n\"\"\"\n\nref_snapshot_sql = \"\"\"\nselect * from {{ ref('snapshot_actual') }}\n\"\"\"\n\n\ninvalidate_sql = \"\"\"\n-- update records 11 - 21. Change email and updated_at field\nupdate {schema}.seed set\n    updated_at = updated_at + interval '1 hour',\n    email      =  case when id = 20 then 'pfoxj@creativecommons.org' else 'new_' || email end\nwhere id >= 10 and id <= 20;\n\n\n-- invalidate records 11 - 21\nupdate {schema}.snapshot_expected set\n    test_valid_to   = updated_at + interval '1 hour'\nwhere id >= 10 and id <= 20;\n\n\"\"\"\n\nupdate_sql = \"\"\"\n-- insert v2 of the 11 - 21 records\n\ninsert into {database}.{schema}.snapshot_expected (\n    id,\n    first_name,\n    last_name,\n    email,\n    gender,\n    ip_address,\n    updated_at,\n    test_valid_from,\n    test_valid_to,\n    test_updated_at,\n    test_scd_id\n)\n\nselect\n    id,\n    first_name,\n    last_name,\n    email,\n    gender,\n    ip_address,\n    updated_at,\n    -- fields added by snapshotting\n    updated_at as test_valid_from,\n    null::timestamp as test_valid_to,\n    updated_at as test_updated_at,\n    md5(id || '-' || first_name || '|' || updated_at::text) as test_scd_id\nfrom {database}.{schema}.seed\nwhere id >= 10 and id <= 20;\n\"\"\"\n\n\nclass TestSnapshotColumnNames:\n    @pytest.fixture(scope=\"class\")\n    def snapshots(self):\n        return {\"snapshot.sql\": snapshot_actual_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"snapshots.yml\": snapshots_yml,\n            \"ref_snapshot.sql\": ref_snapshot_sql,\n        }\n\n    def test_snapshot_column_names(self, project):\n        path = os.path.join(project.test_data_dir, \"seed_cn.sql\")\n        project.run_sql_file(path)\n        results = run_dbt([\"snapshot\"])\n        assert len(results) == 1\n\n        project.run_sql(invalidate_sql)\n        project.run_sql(update_sql)\n\n        results = run_dbt([\"snapshot\"])\n        assert len(results) == 1\n\n        # run_dbt([\"test\"])\n        check_relations_equal(project.adapter, [\"snapshot_actual\", \"snapshot_expected\"])\n\n\nclass TestSnapshotColumnNamesFromDbtProject:\n    @pytest.fixture(scope=\"class\")\n    def snapshots(self):\n        return {\"snapshot.sql\": snapshot_actual_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"snapshots.yml\": snapshots_no_column_names_yml,\n            \"ref_snapshot.sql\": ref_snapshot_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"snapshots\": {\n                \"test\": {\n                    \"+snapshot_meta_column_names\": {\n                        \"dbt_valid_to\": \"test_valid_to\",\n                        \"dbt_valid_from\": \"test_valid_from\",\n                        \"dbt_scd_id\": \"test_scd_id\",\n                        \"dbt_updated_at\": \"test_updated_at\",\n                    }\n                }\n            }\n        }\n\n    def test_snapshot_column_names_from_project(self, project):\n        path = os.path.join(project.test_data_dir, \"seed_cn.sql\")\n        project.run_sql_file(path)\n        results = run_dbt([\"snapshot\"])\n        assert len(results) == 1\n\n        project.run_sql(invalidate_sql)\n        project.run_sql(update_sql)\n\n        results = run_dbt([\"snapshot\"])\n        assert len(results) == 1\n\n        # run_dbt([\"test\"])\n        check_relations_equal(project.adapter, [\"snapshot_actual\", \"snapshot_expected\"])\n\n\nclass TestSnapshotInvalidColumnNames:\n    @pytest.fixture(scope=\"class\")\n    def snapshots(self):\n        return {\"snapshot.sql\": snapshot_actual_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"snapshots.yml\": snapshots_no_column_names_yml,\n            \"ref_snapshot.sql\": ref_snapshot_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"snapshots\": {\n                \"test\": {\n                    \"+snapshot_meta_column_names\": {\n                        \"dbt_valid_to\": \"test_valid_to\",\n                        \"dbt_valid_from\": \"test_valid_from\",\n                        \"dbt_scd_id\": \"test_scd_id\",\n                        \"dbt_updated_at\": \"test_updated_at\",\n                    }\n                }\n            }\n        }\n\n    def test_snapshot_invalid_column_names(self, project):\n        path = os.path.join(project.test_data_dir, \"seed_cn.sql\")\n        project.run_sql_file(path)\n        results = run_dbt([\"snapshot\"])\n        assert len(results) == 1\n        manifest = get_manifest(project.project_root)\n        snapshot_node = manifest.nodes[\"snapshot.test.snapshot_actual\"]\n        snapshot_node.config.snapshot_meta_column_names == {\n            \"dbt_valid_to\": \"test_valid_to\",\n            \"dbt_valid_from\": \"test_valid_from\",\n            \"dbt_scd_id\": \"test_scd_id\",\n            \"dbt_updated_at\": \"test_updated_at\",\n        }\n\n        project.run_sql(invalidate_sql)\n        project.run_sql(update_sql)\n\n        # Change snapshot_meta_columns and look for an error\n        different_columns = {\n            \"snapshots\": {\n                \"test\": {\n                    \"+snapshot_meta_column_names\": {\n                        \"dbt_valid_to\": \"test_valid_to\",\n                        \"dbt_updated_at\": \"test_updated_at\",\n                    }\n                }\n            }\n        }\n        update_config_file(different_columns, \"dbt_project.yml\")\n\n        results, log_output = run_dbt_and_capture([\"snapshot\"], expect_pass=False)\n        assert len(results) == 1\n        assert \"Compilation Error in snapshot snapshot_actual\" in log_output\n        assert \"Snapshot target is missing configured columns\" in log_output\n"
  },
  {
    "path": "tests/functional/snapshots/test_snapshot_config.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt, write_file\n\norders_sql = \"\"\"\nselect 1 as id, 101 as user_id, 'pending' as status\n\"\"\"\n\nsnapshot_sql = \"\"\"\n{% snapshot orders_snapshot %}\n\n{{\n    config(\n      target_schema=schema,\n      strategy='check',\n      unique_key='id',\n      check_cols=['status'],\n    )\n}}\n\nselect * from {{ ref('orders') }}\n\n{% endsnapshot %}\n\"\"\"\n\nsnapshot_no_config_sql = \"\"\"\n{% snapshot orders_snapshot %}\n\nselect * from {{ ref('orders') }}\n\n{% endsnapshot %}\n\"\"\"\n\nsnapshot_schema_yml = \"\"\"\nsnapshots:\n  - name: orders_snapshot\n    config:\n      target_schema: test\n      strategy: check\n      unique_key: id\n      check_cols: ['status']\n\"\"\"\n\n\nclass TestSnapshotConfig:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"orders.sql\": orders_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def snapshots(self):\n        return {\"snapshot_orders.sql\": snapshot_sql}\n\n    def test_config(self, project):\n        run_dbt([\"run\"])\n        results = run_dbt([\"snapshot\"])\n        assert len(results) == 1\n\n        # try to parse with config in schema file\n        write_file(\n            snapshot_no_config_sql, project.project_root, \"snapshots\", \"snapshot_orders.sql\"\n        )\n        write_file(snapshot_schema_yml, project.project_root, \"snapshots\", \"snapshot.yml\")\n        results = run_dbt([\"parse\"])\n\n        results = run_dbt([\"snapshot\"])\n        assert len(results) == 1\n"
  },
  {
    "path": "tests/functional/snapshots/test_snapshot_empty.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt\n\nmy_model_sql = \"\"\"\nselect 1 as id, {{ dbt.current_timestamp() }} as updated_at\n\"\"\"\n\nsnapshots_yml = \"\"\"\nsnapshots:\n  - name: my_snapshot\n    relation: \"ref('my_model')\"\n    config:\n      unique_key: id\n      strategy: check\n      check_cols: all\n      dbt_valid_to_current: \"date('9999-12-31')\"\n\"\"\"\n\n\nclass TestSnapshotEmpty:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": my_model_sql,\n            \"snapshots.yml\": snapshots_yml,\n        }\n\n    def test_check(self, project):\n        run_dbt([\"run\"])\n        run_dbt([\"snapshot\", \"--empty\"])\n\n        query = \"select id, updated_at, dbt_valid_from, dbt_valid_to from {database}.{schema}.my_snapshot order by updated_at asc\"\n        snapshot_out1 = project.run_sql(query, fetch=\"all\")\n        assert snapshot_out1 == []\n\n        run_dbt([\"run\"])\n        run_dbt([\"snapshot\", \"--empty\"])\n        snapshot_out2 = project.run_sql(query, fetch=\"all\")\n        assert snapshot_out2 == []\n"
  },
  {
    "path": "tests/functional/snapshots/test_snapshot_timestamps.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt, run_dbt_and_capture\n\ncreate_source_sql = \"\"\"\ncreate table {database}.{schema}.source_users (\n    id INTEGER,\n    first_name VARCHAR(50),\n    last_name VARCHAR(50),\n    email VARCHAR(50),\n    gender VARCHAR(50),\n    ip_address VARCHAR(20),\n    updated_time TIMESTAMP WITH TIME ZONE\n);\ninsert into {database}.{schema}.source_users (id, first_name, last_name, email, gender, ip_address, updated_time) values\n(1, 'Judith', 'Kennedy', '(not provided)', 'Female', '54.60.24.128', '2015-12-24 12:19:28'),\n(2, 'Arthur', 'Kelly', '(not provided)', 'Male', '62.56.24.215', '2015-10-28 16:22:15'),\n(3, 'Rachel', 'Moreno', 'rmoreno2@msu.edu', 'Female', '31.222.249.23', '2016-04-05 02:05:30');\n\"\"\"\n\nmodel_users_sql = \"\"\"\nselect * from {{ source('test_source', 'source_users') }}\n\"\"\"\n\nsnapshot_sql = \"\"\"\n{% snapshot users_snapshot %}\n\nselect * from {{ ref('users') }}\n\n{% endsnapshot %}\n\"\"\"\n\nsource_schema_yml = \"\"\"\nsources:\n  - name: test_source\n    loader: custom\n    schema: \"{{ target.schema }}\"\n    tables:\n      - name: source_users\n        loaded_at_field: updated_time\n\"\"\"\n\nsnapshot_schema_yml = \"\"\"\nsnapshots:\n  - name: users_snapshot\n    config:\n      target_schema: \"{{ target.schema }}\"\n      strategy: timestamp\n      unique_key: id\n      updated_at: updated_time\n\"\"\"\n\n\nclass TestSnapshotConfig:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"users.sql\": model_users_sql,\n            \"source_schema.yml\": source_schema_yml,\n            \"snapshot_schema.yml\": snapshot_schema_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def snapshots(self):\n        return {\"snapshot.sql\": snapshot_sql}\n\n    def test_timestamp_snapshot(self, project):\n        project.run_sql(create_source_sql)\n        run_dbt([\"run\"])\n        results, log_output = run_dbt_and_capture([\"snapshot\"])\n        assert len(results) == 1\n        assert \"Please update snapshot config\" in log_output\n"
  },
  {
    "path": "tests/functional/source_overrides/fixtures.py",
    "content": "import pytest\n\ndupe_models__schema2_yml = \"\"\"\nversion: 2\nsources:\n  - name: my_source\n    overrides: localdep\n    schema: \"{{ target.schema }}\"\n    database: \"{{ target.database }}\"\n    freshness:\n      error_after: {count: 3, period: day}\n    tables:\n      - name: my_table\n        freshness: null\n        identifier: my_real_seed\n        # on the override, the \"color\" column is only unique, it can be null!\n        columns:\n          - name: id\n            data_tests:\n              - not_null\n              - unique\n          - name: color\n            data_tests:\n              - unique\n      - name: my_other_table\n        freshness: null\n        identifier: my_real_other_seed\n      - name: snapshot_freshness\n        identifier: snapshot_freshness_base\n\n        freshness:\n          error_after: {count: 1, period: day}\n\n\"\"\"\n\ndupe_models__schema1_yml = \"\"\"\nversion: 2\nsources:\n  - name: my_source\n    overrides: localdep\n    schema: \"{{ target.schema }}\"\n    database: \"{{ target.database }}\"\n    freshness:\n      error_after: {count: 3, period: day}\n    tables:\n      - name: my_table\n        freshness: null\n        identifier: my_real_seed\n        # on the override, the \"color\" column is only unique, it can be null!\n        columns:\n          - name: id\n            data_tests:\n              - not_null\n              - unique\n          - name: color\n            data_tests:\n              - unique\n      - name: my_other_table\n        freshness: null\n        identifier: my_real_other_seed\n      - name: snapshot_freshness\n        identifier: snapshot_freshness_base\n        loaded_at_field: updated_at\n        freshness:\n          error_after: {count: 1, period: day}\n\n\"\"\"\n\nlocal_dependency__dbt_project_yml = \"\"\"\nconfig-version: 2\nname: localdep\n\nversion: '1.0'\n\nprofile: 'default'\n\nseeds:\n  quote_columns: False\n\nseed-paths: ['seeds']\n\n\"\"\"\n\nlocal_dependency__models__schema_yml = \"\"\"\nversion: 2\nsources:\n  - name: my_source\n    schema: invalid_schema\n    database: invalid_database\n    freshness:\n      error_after: {count: 3, period: hour}\n    tables:\n      - name: my_table\n        freshness: null\n        identifier: my_seed\n        columns:\n          - name: id\n            data_tests:\n              - unique\n              - not_null\n          - name: color\n            data_tests:\n              - unique\n              - not_null\n      - name: my_other_table\n        identifier: my_other_seed\n        columns:\n          - name: id\n            data_tests:\n              - unique\n              - not_null\n          - name: letter\n            data_tests:\n              - unique\n              - not_null\n      - name: snapshot_freshness\n        identifier: snapshot_freshness_base\n        loaded_at_field: updated_at\n        freshness:\n          error_after: {count: 1, period: hour}\n  - name: my_other_source\n    schema: \"{{ target.schema }}\"\n    database: \"{{ target.database }}\"\n    freshness:\n      error_after: {count: 1, period: day}\n    tables:\n      - name: never_fresh\n        loaded_at_field: updated_at\n\n\"\"\"\n\nlocal_dependency__models__my_model_sql = \"\"\"\n\n{{ config(materialized=\"table\") }}\n\nwith colors as (\n  select id, color from {{ source('my_source', 'my_table') }}\n),\nletters as (\n  select id, letter from {{ source('my_source', 'my_other_table') }}\n)\nselect letter, color from colors join letters using (id)\n\n\"\"\"\n\nlocal_dependency__seeds__my_other_seed_csv = \"\"\"id,letter\n1,r\n2,g\n3,b\n\"\"\"\n\nlocal_dependency__seeds__my_seed_csv = \"\"\"id,color\n1,red\n2,green\n3,blue\n\"\"\"\n\nlocal_dependency__seeds__keep__never_fresh_csv = \"\"\"favorite_color,id,first_name,email,ip_address,updated_at\nblue,1,Larry,lking0@miitbeian.gov.cn,'69.135.206.194',2008-09-12 19:08:31\nblue,2,Larry,lperkins1@toplist.cz,'64.210.133.162',1978-05-09 04:15:14\nblue,3,Anna,amontgomery2@miitbeian.gov.cn,'168.104.64.114',2011-10-16 04:07:57\nblue,4,Sandra,sgeorge3@livejournal.com,'229.235.252.98',1973-07-19 10:52:43\nblue,5,Fred,fwoods4@google.cn,'78.229.170.124',2012-09-30 16:38:29\nblue,6,Stephen,shanson5@livejournal.com,'182.227.157.105',1995-11-07 21:40:50\nblue,7,William,wmartinez6@upenn.edu,'135.139.249.50',1982-09-05 03:11:59\nblue,8,Jessica,jlong7@hao123.com,'203.62.178.210',1991-10-16 11:03:15\nblue,9,Douglas,dwhite8@tamu.edu,'178.187.247.1',1979-10-01 09:49:48\nblue,10,Lisa,lcoleman9@nydailynews.com,'168.234.128.249',2011-05-26 07:45:49\nblue,11,Ralph,rfieldsa@home.pl,'55.152.163.149',1972-11-18 19:06:11\nblue,12,Louise,lnicholsb@samsung.com,'141.116.153.154',2014-11-25 20:56:14\nblue,13,Clarence,cduncanc@sfgate.com,'81.171.31.133',2011-11-17 07:02:36\nblue,14,Daniel,dfranklind@omniture.com,'8.204.211.37',1980-09-13 00:09:04\nblue,15,Katherine,klanee@auda.org.au,'176.96.134.59',1997-08-22 19:36:56\nblue,16,Billy,bwardf@wikia.com,'214.108.78.85',2003-10-19 02:14:47\nblue,17,Annie,agarzag@ocn.ne.jp,'190.108.42.70',1988-10-28 15:12:35\nblue,18,Shirley,scolemanh@fastcompany.com,'109.251.164.84',1988-08-24 10:50:57\nblue,19,Roger,rfrazieri@scribd.com,'38.145.218.108',1985-12-31 15:17:15\nblue,20,Lillian,lstanleyj@goodreads.com,'47.57.236.17',1970-06-08 02:09:05\nblue,21,Aaron,arodriguezk@nps.gov,'205.245.118.221',1985-10-11 23:07:49\nblue,22,Patrick,pparkerl@techcrunch.com,'19.8.100.182',2006-03-29 12:53:56\nblue,23,Phillip,pmorenom@intel.com,'41.38.254.103',2011-11-07 15:35:43\nblue,24,Henry,hgarcian@newsvine.com,'1.191.216.252',2008-08-28 08:30:44\nblue,25,Irene,iturnero@opera.com,'50.17.60.190',1994-04-01 07:15:02\nblue,26,Andrew,adunnp@pen.io,'123.52.253.176',2000-11-01 06:03:25\nblue,27,David,dgutierrezq@wp.com,'238.23.203.42',1988-01-25 07:29:18\nblue,28,Henry,hsanchezr@cyberchimps.com,'248.102.2.185',1983-01-01 13:36:37\nblue,29,Evelyn,epetersons@gizmodo.com,'32.80.46.119',1979-07-16 17:24:12\nblue,30,Tammy,tmitchellt@purevolume.com,'249.246.167.88',2001-04-03 10:00:23\nblue,31,Jacqueline,jlittleu@domainmarket.com,'127.181.97.47',1986-02-11 21:35:50\nblue,32,Earl,eortizv@opera.com,'166.47.248.240',1996-07-06 08:16:27\nblue,33,Juan,jgordonw@sciencedirect.com,'71.77.2.200',1987-01-31 03:46:44\nblue,34,Diane,dhowellx@nyu.edu,'140.94.133.12',1994-06-11 02:30:05\nblue,35,Randy,rkennedyy@microsoft.com,'73.255.34.196',2005-05-26 20:28:39\nblue,36,Janice,jriveraz@time.com,'22.214.227.32',1990-02-09 04:16:52\nblue,37,Laura,lperry10@diigo.com,'159.148.145.73',2015-03-17 05:59:25\nblue,38,Gary,gray11@statcounter.com,'40.193.124.56',1970-01-27 10:04:51\nblue,39,Jesse,jmcdonald12@typepad.com,'31.7.86.103',2009-03-14 08:14:29\nblue,40,Sandra,sgonzalez13@goodreads.com,'223.80.168.239',1993-05-21 14:08:54\nblue,41,Scott,smoore14@archive.org,'38.238.46.83',1980-08-30 11:16:56\nblue,42,Phillip,pevans15@cisco.com,'158.234.59.34',2011-12-15 23:26:31\nblue,43,Steven,sriley16@google.ca,'90.247.57.68',2011-10-29 19:03:28\nblue,44,Deborah,dbrown17@hexun.com,'179.125.143.240',1995-04-10 14:36:07\nblue,45,Lori,lross18@ow.ly,'64.80.162.180',1980-12-27 16:49:15\nblue,46,Sean,sjackson19@tumblr.com,'240.116.183.69',1988-06-12 21:24:45\nblue,47,Terry,tbarnes1a@163.com,'118.38.213.137',1997-09-22 16:43:19\nblue,48,Dorothy,dross1b@ebay.com,'116.81.76.49',2005-02-28 13:33:24\nblue,49,Samuel,swashington1c@house.gov,'38.191.253.40',1989-01-19 21:15:48\nblue,50,Ralph,rcarter1d@tinyurl.com,'104.84.60.174',2007-08-11 10:21:49\n\"\"\"\n\nlocal_dependency__seeds__keep__snapshot_freshness_base_csv = \"\"\"favorite_color,id,first_name,email,ip_address,updated_at\nblue,1,Larry,lking0@miitbeian.gov.cn,'69.135.206.194',2008-09-12 19:08:31\nblue,2,Larry,lperkins1@toplist.cz,'64.210.133.162',1978-05-09 04:15:14\nblue,3,Anna,amontgomery2@miitbeian.gov.cn,'168.104.64.114',2011-10-16 04:07:57\nblue,4,Sandra,sgeorge3@livejournal.com,'229.235.252.98',1973-07-19 10:52:43\nblue,5,Fred,fwoods4@google.cn,'78.229.170.124',2012-09-30 16:38:29\nblue,6,Stephen,shanson5@livejournal.com,'182.227.157.105',1995-11-07 21:40:50\nblue,7,William,wmartinez6@upenn.edu,'135.139.249.50',1982-09-05 03:11:59\nblue,8,Jessica,jlong7@hao123.com,'203.62.178.210',1991-10-16 11:03:15\nblue,9,Douglas,dwhite8@tamu.edu,'178.187.247.1',1979-10-01 09:49:48\nblue,10,Lisa,lcoleman9@nydailynews.com,'168.234.128.249',2011-05-26 07:45:49\nblue,11,Ralph,rfieldsa@home.pl,'55.152.163.149',1972-11-18 19:06:11\nblue,12,Louise,lnicholsb@samsung.com,'141.116.153.154',2014-11-25 20:56:14\nblue,13,Clarence,cduncanc@sfgate.com,'81.171.31.133',2011-11-17 07:02:36\nblue,14,Daniel,dfranklind@omniture.com,'8.204.211.37',1980-09-13 00:09:04\nblue,15,Katherine,klanee@auda.org.au,'176.96.134.59',1997-08-22 19:36:56\nblue,16,Billy,bwardf@wikia.com,'214.108.78.85',2003-10-19 02:14:47\nblue,17,Annie,agarzag@ocn.ne.jp,'190.108.42.70',1988-10-28 15:12:35\nblue,18,Shirley,scolemanh@fastcompany.com,'109.251.164.84',1988-08-24 10:50:57\nblue,19,Roger,rfrazieri@scribd.com,'38.145.218.108',1985-12-31 15:17:15\nblue,20,Lillian,lstanleyj@goodreads.com,'47.57.236.17',1970-06-08 02:09:05\nblue,21,Aaron,arodriguezk@nps.gov,'205.245.118.221',1985-10-11 23:07:49\nblue,22,Patrick,pparkerl@techcrunch.com,'19.8.100.182',2006-03-29 12:53:56\nblue,23,Phillip,pmorenom@intel.com,'41.38.254.103',2011-11-07 15:35:43\nblue,24,Henry,hgarcian@newsvine.com,'1.191.216.252',2008-08-28 08:30:44\nblue,25,Irene,iturnero@opera.com,'50.17.60.190',1994-04-01 07:15:02\nblue,26,Andrew,adunnp@pen.io,'123.52.253.176',2000-11-01 06:03:25\nblue,27,David,dgutierrezq@wp.com,'238.23.203.42',1988-01-25 07:29:18\nblue,28,Henry,hsanchezr@cyberchimps.com,'248.102.2.185',1983-01-01 13:36:37\nblue,29,Evelyn,epetersons@gizmodo.com,'32.80.46.119',1979-07-16 17:24:12\nblue,30,Tammy,tmitchellt@purevolume.com,'249.246.167.88',2001-04-03 10:00:23\nblue,31,Jacqueline,jlittleu@domainmarket.com,'127.181.97.47',1986-02-11 21:35:50\nblue,32,Earl,eortizv@opera.com,'166.47.248.240',1996-07-06 08:16:27\nblue,33,Juan,jgordonw@sciencedirect.com,'71.77.2.200',1987-01-31 03:46:44\nblue,34,Diane,dhowellx@nyu.edu,'140.94.133.12',1994-06-11 02:30:05\nblue,35,Randy,rkennedyy@microsoft.com,'73.255.34.196',2005-05-26 20:28:39\nblue,36,Janice,jriveraz@time.com,'22.214.227.32',1990-02-09 04:16:52\nblue,37,Laura,lperry10@diigo.com,'159.148.145.73',2015-03-17 05:59:25\nblue,38,Gary,gray11@statcounter.com,'40.193.124.56',1970-01-27 10:04:51\nblue,39,Jesse,jmcdonald12@typepad.com,'31.7.86.103',2009-03-14 08:14:29\nblue,40,Sandra,sgonzalez13@goodreads.com,'223.80.168.239',1993-05-21 14:08:54\nblue,41,Scott,smoore14@archive.org,'38.238.46.83',1980-08-30 11:16:56\nblue,42,Phillip,pevans15@cisco.com,'158.234.59.34',2011-12-15 23:26:31\nblue,43,Steven,sriley16@google.ca,'90.247.57.68',2011-10-29 19:03:28\nblue,44,Deborah,dbrown17@hexun.com,'179.125.143.240',1995-04-10 14:36:07\nblue,45,Lori,lross18@ow.ly,'64.80.162.180',1980-12-27 16:49:15\nblue,46,Sean,sjackson19@tumblr.com,'240.116.183.69',1988-06-12 21:24:45\nblue,47,Terry,tbarnes1a@163.com,'118.38.213.137',1997-09-22 16:43:19\nblue,48,Dorothy,dross1b@ebay.com,'116.81.76.49',2005-02-28 13:33:24\nblue,49,Samuel,swashington1c@house.gov,'38.191.253.40',1989-01-19 21:15:48\nblue,50,Ralph,rcarter1d@tinyurl.com,'104.84.60.174',2007-08-11 10:21:49\ngreen,51,Wayne,whudson1e@princeton.edu,'90.61.24.102',1983-07-03 16:58:12\ngreen,52,Rose,rjames1f@plala.or.jp,'240.83.81.10',1995-06-08 11:46:23\ngreen,53,Louise,lcox1g@theglobeandmail.com,'105.11.82.145',2016-09-19 14:45:51\ngreen,54,Kenneth,kjohnson1h@independent.co.uk,'139.5.45.94',1976-08-17 11:26:19\ngreen,55,Donna,dbrown1i@amazon.co.uk,'19.45.169.45',2006-05-27 16:51:40\ngreen,56,Johnny,jvasquez1j@trellian.com,'118.202.238.23',1975-11-17 08:42:32\ngreen,57,Patrick,pramirez1k@tamu.edu,'231.25.153.198',1997-08-06 11:51:09\ngreen,58,Helen,hlarson1l@prweb.com,'8.40.21.39',1993-08-04 19:53:40\ngreen,59,Patricia,pspencer1m@gmpg.org,'212.198.40.15',1977-08-03 16:37:27\ngreen,60,Joseph,jspencer1n@marriott.com,'13.15.63.238',2005-07-23 20:22:06\ngreen,61,Phillip,pschmidt1o@blogtalkradio.com,'177.98.201.190',1976-05-19 21:47:44\ngreen,62,Joan,jwebb1p@google.ru,'105.229.170.71',1972-09-07 17:53:47\ngreen,63,Phyllis,pkennedy1q@imgur.com,'35.145.8.244',2000-01-01 22:33:37\ngreen,64,Katherine,khunter1r@smh.com.au,'248.168.205.32',1991-01-09 06:40:24\ngreen,65,Laura,lvasquez1s@wiley.com,'128.129.115.152',1997-10-23 12:04:56\ngreen,66,Juan,jdunn1t@state.gov,'44.228.124.51',2004-11-10 05:07:35\ngreen,67,Judith,jholmes1u@wiley.com,'40.227.179.115',1977-08-02 17:01:45\ngreen,68,Beverly,bbaker1v@wufoo.com,'208.34.84.59',2016-03-06 20:07:23\ngreen,69,Lawrence,lcarr1w@flickr.com,'59.158.212.223',1988-09-13 06:07:21\ngreen,70,Gloria,gwilliams1x@mtv.com,'245.231.88.33',1995-03-18 22:32:46\ngreen,71,Steven,ssims1y@cbslocal.com,'104.50.58.255',2001-08-05 21:26:20\ngreen,72,Betty,bmills1z@arstechnica.com,'103.177.214.220',1981-12-14 21:26:54\ngreen,73,Mildred,mfuller20@prnewswire.com,'151.158.8.130',2000-04-19 10:13:55\ngreen,74,Donald,dday21@icq.com,'9.178.102.255',1972-12-03 00:58:24\ngreen,75,Eric,ethomas22@addtoany.com,'85.2.241.227',1992-11-01 05:59:30\ngreen,76,Joyce,jarmstrong23@sitemeter.com,'169.224.20.36',1985-10-24 06:50:01\ngreen,77,Maria,mmartinez24@amazonaws.com,'143.189.167.135',2005-10-05 05:17:42\ngreen,78,Harry,hburton25@youtube.com,'156.47.176.237',1978-03-26 05:53:33\ngreen,79,Kevin,klawrence26@hao123.com,'79.136.183.83',1994-10-12 04:38:52\ngreen,80,David,dhall27@prweb.com,'133.149.172.153',1976-12-15 16:24:24\ngreen,81,Kathy,kperry28@twitter.com,'229.242.72.228',1979-03-04 02:58:56\ngreen,82,Adam,aprice29@elegantthemes.com,'13.145.21.10',1982-11-07 11:46:59\ngreen,83,Brandon,bgriffin2a@va.gov,'73.249.128.212',2013-10-30 05:30:36\ngreen,84,Henry,hnguyen2b@discovery.com,'211.36.214.242',1985-01-09 06:37:27\ngreen,85,Eric,esanchez2c@edublogs.org,'191.166.188.251',2004-05-01 23:21:42\ngreen,86,Jason,jlee2d@jimdo.com,'193.92.16.182',1973-01-08 09:05:39\ngreen,87,Diana,drichards2e@istockphoto.com,'19.130.175.245',1994-10-05 22:50:49\ngreen,88,Andrea,awelch2f@abc.net.au,'94.155.233.96',2002-04-26 08:41:44\ngreen,89,Louis,lwagner2g@miitbeian.gov.cn,'26.217.34.111',2003-08-25 07:56:39\ngreen,90,Jane,jsims2h@seesaa.net,'43.4.220.135',1987-03-20 20:39:04\ngreen,91,Larry,lgrant2i@si.edu,'97.126.79.34',2000-09-07 20:26:19\ngreen,92,Louis,ldean2j@prnewswire.com,'37.148.40.127',2011-09-16 20:12:14\ngreen,93,Jennifer,jcampbell2k@xing.com,'38.106.254.142',1988-07-15 05:06:49\ngreen,94,Wayne,wcunningham2l@google.com.hk,'223.28.26.187',2009-12-15 06:16:54\ngreen,95,Lori,lstevens2m@icq.com,'181.250.181.58',1984-10-28 03:29:19\ngreen,96,Judy,jsimpson2n@marriott.com,'180.121.239.219',1986-02-07 15:18:10\ngreen,97,Phillip,phoward2o@usa.gov,'255.247.0.175',2002-12-26 08:44:45\ngreen,98,Gloria,gwalker2p@usa.gov,'156.140.7.128',1997-10-04 07:58:58\ngreen,99,Paul,pjohnson2q@umn.edu,'183.59.198.197',1991-11-14 12:33:55\ngreen,100,Frank,fgreene2r@blogspot.com,'150.143.68.121',2010-06-12 23:55:39\n\"\"\"\n\nmodels__schema_yml = \"\"\"\nversion: 2\nsources:\n  - name: my_source\n    overrides: localdep\n    schema: \"{{ target.schema }}\"\n    database: \"{{ target.database }}\"\n    freshness:\n      error_after: {count: 3, period: day}\n    tables:\n      - name: my_table\n        freshness: null\n        identifier: my_real_seed\n        # on the override, the \"color\" column is only unique, it can be null!\n        columns:\n          - name: id\n            data_tests:\n              - not_null\n              - unique\n          - name: color\n            data_tests:\n              - unique\n      - name: my_other_table\n        freshness: null\n        identifier: my_real_other_seed\n      - name: snapshot_freshness\n        identifier: snapshot_freshness_base\n        loaded_at_field: updated_at\n        freshness:\n          error_after: {count: 1, period: day}\n\n\"\"\"\n\nseeds__expected_result_csv = \"\"\"letter,color\nc,cyan\nm,magenta\ny,yellow\nk,key\n\"\"\"\n\nseeds__my_real_other_seed_csv = \"\"\"id,letter\n1,c\n2,m\n3,y\n4,k\n\"\"\"\n\nseeds__my_real_seed_csv = \"\"\"id,color\n1,cyan\n2,magenta\n3,yellow\n4,key\n5,NULL\n\"\"\"\n\n\n@pytest.fixture(scope=\"class\")\ndef local_dependency():\n    return {\n        \"dbt_project.yml\": local_dependency__dbt_project_yml,\n        \"models\": {\n            \"schema.yml\": local_dependency__models__schema_yml,\n            \"my_model.sql\": local_dependency__models__my_model_sql,\n        },\n        \"seeds\": {\n            \"my_other_seed.csv\": local_dependency__seeds__my_other_seed_csv,\n            \"my_seed.csv\": local_dependency__seeds__my_seed_csv,\n            \"keep\": {\n                \"never_fresh.csv\": local_dependency__seeds__keep__never_fresh_csv,\n                \"snapshot_freshness_base.csv\": local_dependency__seeds__keep__snapshot_freshness_base_csv,\n            },\n        },\n    }\n"
  },
  {
    "path": "tests/functional/source_overrides/test_simple_source_override.py",
    "content": "from datetime import datetime, timedelta, timezone\nfrom unittest import mock\n\nimport pytest\n\nfrom dbt.tests.fixtures.project import write_project_files\nfrom dbt.tests.util import (\n    check_relations_equal,\n    run_dbt,\n    run_dbt_and_capture,\n    update_config_file,\n)\nfrom tests.functional.source_overrides.fixtures import (  # noqa: F401\n    local_dependency,\n    models__schema_yml,\n    seeds__expected_result_csv,\n    seeds__my_real_other_seed_csv,\n    seeds__my_real_seed_csv,\n)\n\n\nclass TestSourceOverride:\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project_root, local_dependency):  # noqa: F811\n        write_project_files(project_root, \"local_dependency\", local_dependency)\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"schema.yml\": models__schema_yml}\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\n            \"expected_result.csv\": seeds__expected_result_csv,\n            \"my_real_other_seed.csv\": seeds__my_real_other_seed_csv,\n            \"my_real_seed.csv\": seeds__my_real_seed_csv,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\n            \"packages\": [\n                {\n                    \"local\": \"local_dependency\",\n                },\n            ]\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"seeds\": {\n                \"localdep\": {\n                    \"enabled\": False,\n                    \"keep\": {\n                        \"enabled\": True,\n                    },\n                },\n                \"quote_columns\": False,\n            },\n            \"sources\": {\n                \"localdep\": {\n                    \"my_other_source\": {\n                        \"enabled\": False,\n                    }\n                }\n            },\n        }\n\n    def _set_updated_at_to(self, insert_id, delta, project):\n        insert_time = datetime.now(timezone.utc).replace(tzinfo=None) + delta\n        timestr = insert_time.strftime(\"%Y-%m-%d %H:%M:%S\")\n        # favorite_color,id,first_name,email,ip_address,updated_at\n\n        quoted_columns = \",\".join(\n            project.adapter.quote(c)\n            for c in (\"favorite_color\", \"id\", \"first_name\", \"email\", \"ip_address\", \"updated_at\")\n        )\n\n        kwargs = {\n            \"schema\": project.test_schema,\n            \"time\": timestr,\n            \"id\": insert_id,\n            \"source\": project.adapter.quote(\"snapshot_freshness_base\"),\n            \"quoted_columns\": quoted_columns,\n        }\n\n        raw_code = \"\"\"INSERT INTO {schema}.{source}\n            ({quoted_columns})\n        VALUES (\n            'blue',{id},'Jake','abc@example.com','192.168.1.1','{time}'\n        )\"\"\".format(\n            **kwargs\n        )\n\n        project.run_sql(raw_code)\n\n        return insert_id + 1\n\n    @mock.patch(\"dbt.jsonschemas.jsonschemas._JSONSCHEMA_SUPPORTED_ADAPTERS\", {\"postgres\"})\n    def test_source_overrides(self, project):\n        insert_id = 101\n\n        run_dbt([\"deps\"])\n\n        seed_results = run_dbt([\"seed\"])\n        assert len(seed_results) == 5\n\n        # There should be 7, as we disabled 1 test of the original 8\n        test_results = run_dbt([\"test\"])\n        assert len(test_results) == 7\n\n        results, logs = run_dbt_and_capture([\"run\"])\n        assert len(results) == 1\n\n        # Since source overrides are now deprecated, shoehorn a check for the\n        # deprecation warning into this existing test.\n        assert \"SourceOverrideDeprecation: 1 occurrence\" in logs\n\n        check_relations_equal(project.adapter, [\"expected_result\", \"my_model\"])\n\n        # set the updated_at field of this seed to last week\n        insert_id = self._set_updated_at_to(insert_id, timedelta(days=-7), project)\n        # if snapshot-freshness fails, freshness just didn't happen!\n        results = run_dbt([\"source\", \"snapshot-freshness\"], expect_pass=False)\n        # we disabled my_other_source, so we only run the one freshness check\n        # in\n        assert len(results) == 1\n        # If snapshot-freshness passes, that means error_after was\n        # applied from the source override but not the source table override\n        insert_id = self._set_updated_at_to(insert_id, timedelta(days=-2), project)\n        results = run_dbt(\n            [\"source\", \"snapshot-freshness\"],\n            expect_pass=False,\n        )\n        assert len(results) == 1\n\n        insert_id = self._set_updated_at_to(insert_id, timedelta(hours=-12), project)\n        results = run_dbt([\"source\", \"snapshot-freshness\"], expect_pass=True)\n        assert len(results) == 1\n\n        # update source to be enabled\n        new_source_config = {\n            \"sources\": {\n                \"localdep\": {\n                    \"my_other_source\": {\n                        \"enabled\": True,\n                    }\n                }\n            }\n        }\n        update_config_file(new_source_config, project.project_root, \"dbt_project.yml\")\n\n        # enable my_other_source, snapshot freshness should fail due to the new\n        # not-fresh source\n        results = run_dbt([\"source\", \"snapshot-freshness\"], expect_pass=False)\n        assert len(results) == 2\n"
  },
  {
    "path": "tests/functional/source_overrides/test_source_overrides_duplicate_model.py",
    "content": "import os\n\nimport pytest\n\nfrom dbt.exceptions import CompilationError\nfrom dbt.tests.fixtures.project import write_project_files\nfrom dbt.tests.util import run_dbt\nfrom tests.functional.source_overrides.fixtures import (  # noqa: F401\n    dupe_models__schema1_yml,\n    dupe_models__schema2_yml,\n    local_dependency,\n)\n\n\nclass TestSourceOverrideDuplicates:\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project_root, local_dependency):  # noqa: F811\n        write_project_files(project_root, \"local_dependency\", local_dependency)\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema2.yml\": dupe_models__schema2_yml,\n            \"schema1.yml\": dupe_models__schema1_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\n            \"packages\": [\n                {\n                    \"local\": \"local_dependency\",\n                },\n            ]\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"seeds\": {\n                \"localdep\": {\n                    \"enabled\": False,\n                    \"keep\": {\n                        \"enabled\": True,\n                    },\n                },\n                \"quote_columns\": False,\n            },\n            \"sources\": {\n                \"localdep\": {\n                    \"my_other_source\": {\n                        \"enabled\": False,\n                    }\n                }\n            },\n        }\n\n    def test_source_duplicate_overrides(self, project):\n        run_dbt([\"deps\"])\n        with pytest.raises(CompilationError) as exc:\n            run_dbt([\"compile\"])\n\n        assert \"dbt found two schema.yml entries for the same source named\" in str(exc.value)\n        assert \"one of these files\" in str(exc.value)\n        schema1_path = os.path.join(\"models\", \"schema1.yml\")\n        schema2_path = os.path.join(\"models\", \"schema2.yml\")\n        assert schema1_path in str(exc.value)\n        assert schema2_path in str(exc.value)\n"
  },
  {
    "path": "tests/functional/sources/common_source_setup.py",
    "content": "import os\n\nimport pytest\nimport yaml\n\nfrom dbt.tests.util import run_dbt, run_dbt_and_capture\nfrom tests.functional.sources.fixtures import (\n    models_descendant_model_sql,\n    models_ephemeral_model_sql,\n    models_multi_source_model_sql,\n    models_nonsource_descendant_sql,\n    models_schema_yml,\n    models_view_model_sql,\n    seeds_expected_multi_source_csv,\n    seeds_other_source_table_csv,\n    seeds_other_table_csv,\n    seeds_source_csv,\n)\n\n\nclass BaseSourcesTest:\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setEnvVars(self):\n        os.environ[\"DBT_TEST_SCHEMA_NAME_VARIABLE\"] = \"test_run_schema\"\n\n        yield\n\n        del os.environ[\"DBT_TEST_SCHEMA_NAME_VARIABLE\"]\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": models_schema_yml,\n            \"view_model.sql\": models_view_model_sql,\n            \"ephemeral_model.sql\": models_ephemeral_model_sql,\n            \"descendant_model.sql\": models_descendant_model_sql,\n            \"multi_source_model.sql\": models_multi_source_model_sql,\n            \"nonsource_descendant.sql\": models_nonsource_descendant_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\n            \"source.csv\": seeds_source_csv,\n            \"other_table.csv\": seeds_other_table_csv,\n            \"expected_multi_source.csv\": seeds_expected_multi_source_csv,\n            \"other_source_table.csv\": seeds_other_source_table_csv,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"config-version\": 2,\n            \"seed-paths\": [\"seeds\"],\n            \"quoting\": {\"database\": True, \"schema\": True, \"identifier\": True},\n            \"seeds\": {\n                \"quote_columns\": True,\n            },\n        }\n\n    def _extend_cmd_with_vars(self, project, cmd):\n        vars_dict = {\n            \"test_run_schema\": project.test_schema,\n            \"test_loaded_at\": project.adapter.quote(\"updated_at\"),\n        }\n        cmd.extend([\"--vars\", yaml.safe_dump(vars_dict)])\n\n    def run_dbt_with_vars(self, project, cmd, *args, **kwargs):\n        self._extend_cmd_with_vars(project, cmd)\n        return run_dbt(cmd, *args, **kwargs)\n\n    def run_dbt_and_capture_with_vars(self, project, cmd, *args, **kwargs):\n        self._extend_cmd_with_vars(project, cmd)\n        return run_dbt_and_capture(cmd, *args, **kwargs)\n"
  },
  {
    "path": "tests/functional/sources/data/seed.sql",
    "content": "create table {schema}.seed_expected (\n    favorite_color TEXT,\n\tid INTEGER,\n\tfirst_name TEXT,\n\temail TEXT,\n\tip_address TEXT,\n\tupdated_at TIMESTAMP WITHOUT TIME ZONE\n);\n\n\nINSERT INTO {schema}.seed_expected\n    (\"favorite_color\",\"id\",\"first_name\",\"email\",\"ip_address\",\"updated_at\")\nVALUES\n    ('blue',1,'Larry','lking0@miitbeian.gov.cn','''69.135.206.194''','2008-09-12 19:08:31'),\n    ('blue',2,'Larry','lperkins1@toplist.cz','''64.210.133.162''','1978-05-09 04:15:14'),\n    ('blue',3,'Anna','amontgomery2@miitbeian.gov.cn','''168.104.64.114''','2011-10-16 04:07:57'),\n    ('blue',4,'Sandra','sgeorge3@livejournal.com','''229.235.252.98''','1973-07-19 10:52:43'),\n    ('blue',5,'Fred','fwoods4@google.cn','''78.229.170.124''','2012-09-30 16:38:29'),\n    ('blue',6,'Stephen','shanson5@livejournal.com','''182.227.157.105''','1995-11-07 21:40:50'),\n    ('blue',7,'William','wmartinez6@upenn.edu','''135.139.249.50''','1982-09-05 03:11:59'),\n    ('blue',8,'Jessica','jlong7@hao123.com','''203.62.178.210''','1991-10-16 11:03:15'),\n    ('blue',9,'Douglas','dwhite8@tamu.edu','''178.187.247.1''','1979-10-01 09:49:48'),\n    ('blue',10,'Lisa','lcoleman9@nydailynews.com','''168.234.128.249''','2011-05-26 07:45:49'),\n    ('blue',11,'Ralph','rfieldsa@home.pl','''55.152.163.149''','1972-11-18 19:06:11'),\n    ('blue',12,'Louise','lnicholsb@samsung.com','''141.116.153.154''','2014-11-25 20:56:14'),\n    ('blue',13,'Clarence','cduncanc@sfgate.com','''81.171.31.133''','2011-11-17 07:02:36'),\n    ('blue',14,'Daniel','dfranklind@omniture.com','''8.204.211.37''','1980-09-13 00:09:04'),\n    ('blue',15,'Katherine','klanee@auda.org.au','''176.96.134.59''','1997-08-22 19:36:56'),\n    ('blue',16,'Billy','bwardf@wikia.com','''214.108.78.85''','2003-10-19 02:14:47'),\n    ('blue',17,'Annie','agarzag@ocn.ne.jp','''190.108.42.70''','1988-10-28 15:12:35'),\n    ('blue',18,'Shirley','scolemanh@fastcompany.com','''109.251.164.84''','1988-08-24 10:50:57'),\n    ('blue',19,'Roger','rfrazieri@scribd.com','''38.145.218.108''','1985-12-31 15:17:15'),\n    ('blue',20,'Lillian','lstanleyj@goodreads.com','''47.57.236.17''','1970-06-08 02:09:05'),\n    ('blue',21,'Aaron','arodriguezk@nps.gov','''205.245.118.221''','1985-10-11 23:07:49'),\n    ('blue',22,'Patrick','pparkerl@techcrunch.com','''19.8.100.182''','2006-03-29 12:53:56'),\n    ('blue',23,'Phillip','pmorenom@intel.com','''41.38.254.103''','2011-11-07 15:35:43'),\n    ('blue',24,'Henry','hgarcian@newsvine.com','''1.191.216.252''','2008-08-28 08:30:44'),\n    ('blue',25,'Irene','iturnero@opera.com','''50.17.60.190''','1994-04-01 07:15:02'),\n    ('blue',26,'Andrew','adunnp@pen.io','''123.52.253.176''','2000-11-01 06:03:25'),\n    ('blue',27,'David','dgutierrezq@wp.com','''238.23.203.42''','1988-01-25 07:29:18'),\n    ('blue',28,'Henry','hsanchezr@cyberchimps.com','''248.102.2.185''','1983-01-01 13:36:37'),\n    ('blue',29,'Evelyn','epetersons@gizmodo.com','''32.80.46.119''','1979-07-16 17:24:12'),\n    ('blue',30,'Tammy','tmitchellt@purevolume.com','''249.246.167.88''','2001-04-03 10:00:23'),\n    ('blue',31,'Jacqueline','jlittleu@domainmarket.com','''127.181.97.47''','1986-02-11 21:35:50'),\n    ('blue',32,'Earl','eortizv@opera.com','''166.47.248.240''','1996-07-06 08:16:27'),\n    ('blue',33,'Juan','jgordonw@sciencedirect.com','''71.77.2.200''','1987-01-31 03:46:44'),\n    ('blue',34,'Diane','dhowellx@nyu.edu','''140.94.133.12''','1994-06-11 02:30:05'),\n    ('blue',35,'Randy','rkennedyy@microsoft.com','''73.255.34.196''','2005-05-26 20:28:39'),\n    ('blue',36,'Janice','jriveraz@time.com','''22.214.227.32''','1990-02-09 04:16:52'),\n    ('blue',37,'Laura','lperry10@diigo.com','''159.148.145.73''','2015-03-17 05:59:25'),\n    ('blue',38,'Gary','gray11@statcounter.com','''40.193.124.56''','1970-01-27 10:04:51'),\n    ('blue',39,'Jesse','jmcdonald12@typepad.com','''31.7.86.103''','2009-03-14 08:14:29'),\n    ('blue',40,'Sandra','sgonzalez13@goodreads.com','''223.80.168.239''','1993-05-21 14:08:54'),\n    ('blue',41,'Scott','smoore14@archive.org','''38.238.46.83''','1980-08-30 11:16:56'),\n    ('blue',42,'Phillip','pevans15@cisco.com','''158.234.59.34''','2011-12-15 23:26:31'),\n    ('blue',43,'Steven','sriley16@google.ca','''90.247.57.68''','2011-10-29 19:03:28'),\n    ('blue',44,'Deborah','dbrown17@hexun.com','''179.125.143.240''','1995-04-10 14:36:07'),\n    ('blue',45,'Lori','lross18@ow.ly','''64.80.162.180''','1980-12-27 16:49:15'),\n    ('blue',46,'Sean','sjackson19@tumblr.com','''240.116.183.69''','1988-06-12 21:24:45'),\n    ('blue',47,'Terry','tbarnes1a@163.com','''118.38.213.137''','1997-09-22 16:43:19'),\n    ('blue',48,'Dorothy','dross1b@ebay.com','''116.81.76.49''','2005-02-28 13:33:24'),\n    ('blue',49,'Samuel','swashington1c@house.gov','''38.191.253.40''','1989-01-19 21:15:48'),\n    ('blue',50,'Ralph','rcarter1d@tinyurl.com','''104.84.60.174''','2007-08-11 10:21:49'),\n    ('green',51,'Wayne','whudson1e@princeton.edu','''90.61.24.102''','1983-07-03 16:58:12'),\n    ('green',52,'Rose','rjames1f@plala.or.jp','''240.83.81.10''','1995-06-08 11:46:23'),\n    ('green',53,'Louise','lcox1g@theglobeandmail.com','''105.11.82.145''','2016-09-19 14:45:51'),\n    ('green',54,'Kenneth','kjohnson1h@independent.co.uk','''139.5.45.94''','1976-08-17 11:26:19'),\n    ('green',55,'Donna','dbrown1i@amazon.co.uk','''19.45.169.45''','2006-05-27 16:51:40'),\n    ('green',56,'Johnny','jvasquez1j@trellian.com','''118.202.238.23''','1975-11-17 08:42:32'),\n    ('green',57,'Patrick','pramirez1k@tamu.edu','''231.25.153.198''','1997-08-06 11:51:09'),\n    ('green',58,'Helen','hlarson1l@prweb.com','''8.40.21.39''','1993-08-04 19:53:40'),\n    ('green',59,'Patricia','pspencer1m@gmpg.org','''212.198.40.15''','1977-08-03 16:37:27'),\n    ('green',60,'Joseph','jspencer1n@marriott.com','''13.15.63.238''','2005-07-23 20:22:06'),\n    ('green',61,'Phillip','pschmidt1o@blogtalkradio.com','''177.98.201.190''','1976-05-19 21:47:44'),\n    ('green',62,'Joan','jwebb1p@google.ru','''105.229.170.71''','1972-09-07 17:53:47'),\n    ('green',63,'Phyllis','pkennedy1q@imgur.com','''35.145.8.244''','2000-01-01 22:33:37'),\n    ('green',64,'Katherine','khunter1r@smh.com.au','''248.168.205.32''','1991-01-09 06:40:24'),\n    ('green',65,'Laura','lvasquez1s@wiley.com','''128.129.115.152''','1997-10-23 12:04:56'),\n    ('green',66,'Juan','jdunn1t@state.gov','''44.228.124.51''','2004-11-10 05:07:35'),\n    ('green',67,'Judith','jholmes1u@wiley.com','''40.227.179.115''','1977-08-02 17:01:45'),\n    ('green',68,'Beverly','bbaker1v@wufoo.com','''208.34.84.59''','2016-03-06 20:07:23'),\n    ('green',69,'Lawrence','lcarr1w@flickr.com','''59.158.212.223''','1988-09-13 06:07:21'),\n    ('green',70,'Gloria','gwilliams1x@mtv.com','''245.231.88.33''','1995-03-18 22:32:46'),\n    ('green',71,'Steven','ssims1y@cbslocal.com','''104.50.58.255''','2001-08-05 21:26:20'),\n    ('green',72,'Betty','bmills1z@arstechnica.com','''103.177.214.220''','1981-12-14 21:26:54'),\n    ('green',73,'Mildred','mfuller20@prnewswire.com','''151.158.8.130''','2000-04-19 10:13:55'),\n    ('green',74,'Donald','dday21@icq.com','''9.178.102.255''','1972-12-03 00:58:24'),\n    ('green',75,'Eric','ethomas22@addtoany.com','''85.2.241.227''','1992-11-01 05:59:30'),\n    ('green',76,'Joyce','jarmstrong23@sitemeter.com','''169.224.20.36''','1985-10-24 06:50:01'),\n    ('green',77,'Maria','mmartinez24@amazonaws.com','''143.189.167.135''','2005-10-05 05:17:42'),\n    ('green',78,'Harry','hburton25@youtube.com','''156.47.176.237''','1978-03-26 05:53:33'),\n    ('green',79,'Kevin','klawrence26@hao123.com','''79.136.183.83''','1994-10-12 04:38:52'),\n    ('green',80,'David','dhall27@prweb.com','''133.149.172.153''','1976-12-15 16:24:24'),\n    ('green',81,'Kathy','kperry28@twitter.com','''229.242.72.228''','1979-03-04 02:58:56'),\n    ('green',82,'Adam','aprice29@elegantthemes.com','''13.145.21.10''','1982-11-07 11:46:59'),\n    ('green',83,'Brandon','bgriffin2a@va.gov','''73.249.128.212''','2013-10-30 05:30:36'),\n    ('green',84,'Henry','hnguyen2b@discovery.com','''211.36.214.242''','1985-01-09 06:37:27'),\n    ('green',85,'Eric','esanchez2c@edublogs.org','''191.166.188.251''','2004-05-01 23:21:42'),\n    ('green',86,'Jason','jlee2d@jimdo.com','''193.92.16.182''','1973-01-08 09:05:39'),\n    ('green',87,'Diana','drichards2e@istockphoto.com','''19.130.175.245''','1994-10-05 22:50:49'),\n    ('green',88,'Andrea','awelch2f@abc.net.au','''94.155.233.96''','2002-04-26 08:41:44'),\n    ('green',89,'Louis','lwagner2g@miitbeian.gov.cn','''26.217.34.111''','2003-08-25 07:56:39'),\n    ('green',90,'Jane','jsims2h@seesaa.net','''43.4.220.135''','1987-03-20 20:39:04'),\n    ('green',91,'Larry','lgrant2i@si.edu','''97.126.79.34''','2000-09-07 20:26:19'),\n    ('green',92,'Louis','ldean2j@prnewswire.com','''37.148.40.127''','2011-09-16 20:12:14'),\n    ('green',93,'Jennifer','jcampbell2k@xing.com','''38.106.254.142''','1988-07-15 05:06:49'),\n    ('green',94,'Wayne','wcunningham2l@google.com.hk','''223.28.26.187''','2009-12-15 06:16:54'),\n    ('green',95,'Lori','lstevens2m@icq.com','''181.250.181.58''','1984-10-28 03:29:19'),\n    ('green',96,'Judy','jsimpson2n@marriott.com','''180.121.239.219''','1986-02-07 15:18:10'),\n    ('green',97,'Phillip','phoward2o@usa.gov','''255.247.0.175''','2002-12-26 08:44:45'),\n    ('green',98,'Gloria','gwalker2p@usa.gov','''156.140.7.128''','1997-10-04 07:58:58'),\n    ('green',99,'Paul','pjohnson2q@umn.edu','''183.59.198.197''','1991-11-14 12:33:55'),\n    ('green',100,'Frank','fgreene2r@blogspot.com','''150.143.68.121''','2010-06-12 23:55:39');\n"
  },
  {
    "path": "tests/functional/sources/fixtures.py",
    "content": "error_models_schema_yml = \"\"\"version: 2\nsources:\n  - name: test_source\n    loader: custom\n    freshness:\n      warn_after: {count: 10, period: hour}\n      error_after: {count: 1, period: day}\n    schema: invalid\n    tables:\n      - name: test_table\n        identifier: source\n        loaded_at_field: updated_at\n\"\"\"\n\nerror_models_model_sql = \"\"\"select * from {{ source('test_source', 'test_table') }}\n\"\"\"\n\noverride_freshness_models_schema_yml = \"\"\"version: 2\nsources:\n  - name: test_source\n    loader: custom\n    freshness:\n      warn_after: {count: 18, period: hour}\n      error_after: {count: 24, period: hour}\n    config:\n      freshness: # default freshness, takes precedence over top-level key above\n        warn_after: {count: 12, period: hour}\n    schema: \"{{ var(env_var('DBT_TEST_SCHEMA_NAME_VARIABLE')) }}\"\n    loaded_at_field: loaded_at\n    quoting:\n      identifier: True\n    tags:\n      - my_test_source_tag\n    tables:\n      - name: source_a\n        identifier: source\n        loaded_at_field: \"{{ var('test_loaded_at') | as_text }}\"\n        config:\n          freshness:\n            warn_after: {count: 6, period: hour}\n            # use default error_after, takes precedence over top-level key above\n        freshness:\n          warn_after: {count: 9, period: hour}\n      - name: source_b\n        identifier: source\n        loaded_at_field: \"{{ var('test_loaded_at') | as_text }}\"\n        freshness:\n          warn_after: {count: 6, period: hour}\n          error_after: {} # use the default error_after defined above\n      - name: source_c\n        identifier: source\n        loaded_at_field: \"{{ var('test_loaded_at') | as_text }}\"\n        freshness:\n          warn_after: {count: 6, period: hour}\n          error_after: null # override: disable error_after for this table\n      - name: source_d\n        identifier: source\n        loaded_at_field: \"{{ var('test_loaded_at') | as_text }}\"\n        freshness:\n          warn_after: {count: 6, period: hour}\n          error_after: {count: 144, period: hour}\n        config:\n          freshness:\n            error_after: {count: 72, period: hour} # override: use this new behavior instead of error_after defined above\n      - name: source_e\n        identifier: source\n        loaded_at_field: \"{{ var('test_loaded_at') | as_text }}\"\n        freshness: null # override: disable freshness for this table\n\"\"\"\n\nmodels_schema_yml = \"\"\"version: 2\nmodels:\n  - name: descendant_model\n    columns:\n      - name: favorite_color\n        data_tests:\n          - relationships:\n             to: source('test_source', 'test_table')\n             field: favorite_color\n      - name: id\n        data_tests:\n          - unique\n          - not_null\n\nsources:\n  - name: test_source\n    loader: custom\n    freshness:\n      warn_after: {count: 10, period: hour}\n      error_after: {count: 1, period: day}\n    schema: \"{{ var(env_var('DBT_TEST_SCHEMA_NAME_VARIABLE')) }}\"\n    quoting:\n      identifier: True\n    tags:\n      - my_test_source_tag\n    tables:\n      - name: test_table\n        identifier: source\n        loaded_at_field: \"{{ var('test_loaded_at') | as_text }}\"\n        freshness:\n          error_after: {count: 18, period: hour}\n        tags:\n          - my_test_source_table_tag\n        columns:\n          - name: favorite_color\n            description: The favorite color\n          - name: id\n            description: The user ID\n            data_tests:\n              - unique\n              - not_null\n            tags:\n              - id_column\n          - name: first_name\n            description: The first name of the user\n            data_tests: []\n          - name: email\n            description: The email address of the user\n          - name: ip_address\n            description: The last IP address the user logged in from\n          - name: updated_at\n            description: The last update time for this user\n        data_tests:\n          - relationships:\n              # do this as a table-level test, just to test out that aspect\n              column_name: favorite_color\n              to: ref('descendant_model')\n              field: favorite_color\n      - name: other_test_table\n        identifier: other_table\n        freshness: null\n        columns:\n          - name: id\n            data_tests:\n              - not_null\n              - unique\n            tags:\n              - id_column\n      - name: disabled_test_table\n        freshness: null\n        loaded_at_field: \"{{ var('test_loaded_at') | as_text }}\"\n  - name: other_source\n    schema: \"{{ var('test_run_schema') }}\"\n    quoting:\n      identifier: True\n    tables:\n      - name: test_table\n        identifier: other_source_table\n  - name: external_source\n    schema: \"{{ var('test_run_alt_schema', var('test_run_schema')) }}\"\n    tables:\n      - name: table\n\"\"\"\n\nmodels_view_model_sql = \"\"\"{# See here: https://github.com/dbt-labs/dbt-core/pull/1729 #}\n\nselect * from {{ ref('ephemeral_model') }}\n\"\"\"\n\nmodels_ephemeral_model_sql = \"\"\"{{ config(materialized='ephemeral') }}\n\nselect 1 as id\n\"\"\"\n\nmodels_descendant_model_sql = \"\"\"select * from {{ source('test_source', 'test_table') }}\n\"\"\"\n\nmodels_multi_source_model_sql = \"\"\"select * from {{ source('test_source', 'other_test_table')}}\n  join {{ source('other_source', 'test_table')}} using (id)\n\"\"\"\n\nmodels_nonsource_descendant_sql = \"\"\"select * from {{ schema }}.source\n\"\"\"\n\nmodels_newly_added_model_sql = \"\"\"select 2 as id\"\"\"\n\nmodels_newly_added_error_model_sql = \"\"\"select error from fake_table\"\"\"\n\nmalformed_models_schema_yml = \"\"\"version: 2\nsources:\n  - name: test_source\n    loader: custom\n    schema: \"{{ var('test_run_schema') }}\"\n    tables:\n      - name: test_table\n        identifier: source\n        data_tests:\n          - relationships:\n            # this is invalid (list of 3 1-key dicts instead of a single 3-key dict)\n              - column_name: favorite_color\n              - to: ref('descendant_model')\n              - field: favorite_color\n\"\"\"\n\nmalformed_models_descendant_model_sql = \"\"\"select * from {{ source('test_source', 'test_table') }}\n\"\"\"\n\nfiltered_models_schema_yml = \"\"\"version: 2\nsources:\n  - name: test_source\n    loader: custom\n    freshness:\n      warn_after: {count: 10, period: hour}\n      error_after: {count: 1, period: day}\n      filter: id > 1\n    schema: \"{{ var(env_var('DBT_TEST_SCHEMA_NAME_VARIABLE')) }}\"\n    quoting:\n      identifier: True\n    tables:\n      - name: test_table\n        identifier: source\n        loaded_at_field: updated_at\n        freshness:\n          error_after: {count: 18, period: hour}\n          filter: id > 101\n\"\"\"\n\nmacros_macro_sql = \"\"\"{% macro override_me() -%}\n    {{ exceptions.raise_compiler_error('this is a bad macro') }}\n{%- endmacro %}\n\n{% macro happy_little_macro() -%}\n    {{ override_me() }}\n{%- endmacro %}\n\n\n{% macro vacuum_source(source_name, table_name) -%}\n    {% call statement('stmt', auto_begin=false, fetch_result=false) %}\n        vacuum {{ source(source_name, table_name) }}\n    {% endcall %}\n{%- endmacro %}\n\"\"\"\n\nseeds_source_csv = \"\"\"favorite_color,id,first_name,email,ip_address,updated_at\nblue,1,Larry,lking0@miitbeian.gov.cn,'69.135.206.194',2008-09-12 19:08:31\nblue,2,Larry,lperkins1@toplist.cz,'64.210.133.162',1978-05-09 04:15:14\nblue,3,Anna,amontgomery2@miitbeian.gov.cn,'168.104.64.114',2011-10-16 04:07:57\nblue,4,Sandra,sgeorge3@livejournal.com,'229.235.252.98',1973-07-19 10:52:43\nblue,5,Fred,fwoods4@google.cn,'78.229.170.124',2012-09-30 16:38:29\nblue,6,Stephen,shanson5@livejournal.com,'182.227.157.105',1995-11-07 21:40:50\nblue,7,William,wmartinez6@upenn.edu,'135.139.249.50',1982-09-05 03:11:59\nblue,8,Jessica,jlong7@hao123.com,'203.62.178.210',1991-10-16 11:03:15\nblue,9,Douglas,dwhite8@tamu.edu,'178.187.247.1',1979-10-01 09:49:48\nblue,10,Lisa,lcoleman9@nydailynews.com,'168.234.128.249',2011-05-26 07:45:49\nblue,11,Ralph,rfieldsa@home.pl,'55.152.163.149',1972-11-18 19:06:11\nblue,12,Louise,lnicholsb@samsung.com,'141.116.153.154',2014-11-25 20:56:14\nblue,13,Clarence,cduncanc@sfgate.com,'81.171.31.133',2011-11-17 07:02:36\nblue,14,Daniel,dfranklind@omniture.com,'8.204.211.37',1980-09-13 00:09:04\nblue,15,Katherine,klanee@auda.org.au,'176.96.134.59',1997-08-22 19:36:56\nblue,16,Billy,bwardf@wikia.com,'214.108.78.85',2003-10-19 02:14:47\nblue,17,Annie,agarzag@ocn.ne.jp,'190.108.42.70',1988-10-28 15:12:35\nblue,18,Shirley,scolemanh@fastcompany.com,'109.251.164.84',1988-08-24 10:50:57\nblue,19,Roger,rfrazieri@scribd.com,'38.145.218.108',1985-12-31 15:17:15\nblue,20,Lillian,lstanleyj@goodreads.com,'47.57.236.17',1970-06-08 02:09:05\nblue,21,Aaron,arodriguezk@nps.gov,'205.245.118.221',1985-10-11 23:07:49\nblue,22,Patrick,pparkerl@techcrunch.com,'19.8.100.182',2006-03-29 12:53:56\nblue,23,Phillip,pmorenom@intel.com,'41.38.254.103',2011-11-07 15:35:43\nblue,24,Henry,hgarcian@newsvine.com,'1.191.216.252',2008-08-28 08:30:44\nblue,25,Irene,iturnero@opera.com,'50.17.60.190',1994-04-01 07:15:02\nblue,26,Andrew,adunnp@pen.io,'123.52.253.176',2000-11-01 06:03:25\nblue,27,David,dgutierrezq@wp.com,'238.23.203.42',1988-01-25 07:29:18\nblue,28,Henry,hsanchezr@cyberchimps.com,'248.102.2.185',1983-01-01 13:36:37\nblue,29,Evelyn,epetersons@gizmodo.com,'32.80.46.119',1979-07-16 17:24:12\nblue,30,Tammy,tmitchellt@purevolume.com,'249.246.167.88',2001-04-03 10:00:23\nblue,31,Jacqueline,jlittleu@domainmarket.com,'127.181.97.47',1986-02-11 21:35:50\nblue,32,Earl,eortizv@opera.com,'166.47.248.240',1996-07-06 08:16:27\nblue,33,Juan,jgordonw@sciencedirect.com,'71.77.2.200',1987-01-31 03:46:44\nblue,34,Diane,dhowellx@nyu.edu,'140.94.133.12',1994-06-11 02:30:05\nblue,35,Randy,rkennedyy@microsoft.com,'73.255.34.196',2005-05-26 20:28:39\nblue,36,Janice,jriveraz@time.com,'22.214.227.32',1990-02-09 04:16:52\nblue,37,Laura,lperry10@diigo.com,'159.148.145.73',2015-03-17 05:59:25\nblue,38,Gary,gray11@statcounter.com,'40.193.124.56',1970-01-27 10:04:51\nblue,39,Jesse,jmcdonald12@typepad.com,'31.7.86.103',2009-03-14 08:14:29\nblue,40,Sandra,sgonzalez13@goodreads.com,'223.80.168.239',1993-05-21 14:08:54\nblue,41,Scott,smoore14@archive.org,'38.238.46.83',1980-08-30 11:16:56\nblue,42,Phillip,pevans15@cisco.com,'158.234.59.34',2011-12-15 23:26:31\nblue,43,Steven,sriley16@google.ca,'90.247.57.68',2011-10-29 19:03:28\nblue,44,Deborah,dbrown17@hexun.com,'179.125.143.240',1995-04-10 14:36:07\nblue,45,Lori,lross18@ow.ly,'64.80.162.180',1980-12-27 16:49:15\nblue,46,Sean,sjackson19@tumblr.com,'240.116.183.69',1988-06-12 21:24:45\nblue,47,Terry,tbarnes1a@163.com,'118.38.213.137',1997-09-22 16:43:19\nblue,48,Dorothy,dross1b@ebay.com,'116.81.76.49',2005-02-28 13:33:24\nblue,49,Samuel,swashington1c@house.gov,'38.191.253.40',1989-01-19 21:15:48\nblue,50,Ralph,rcarter1d@tinyurl.com,'104.84.60.174',2007-08-11 10:21:49\ngreen,51,Wayne,whudson1e@princeton.edu,'90.61.24.102',1983-07-03 16:58:12\ngreen,52,Rose,rjames1f@plala.or.jp,'240.83.81.10',1995-06-08 11:46:23\ngreen,53,Louise,lcox1g@theglobeandmail.com,'105.11.82.145',2016-09-19 14:45:51\ngreen,54,Kenneth,kjohnson1h@independent.co.uk,'139.5.45.94',1976-08-17 11:26:19\ngreen,55,Donna,dbrown1i@amazon.co.uk,'19.45.169.45',2006-05-27 16:51:40\ngreen,56,Johnny,jvasquez1j@trellian.com,'118.202.238.23',1975-11-17 08:42:32\ngreen,57,Patrick,pramirez1k@tamu.edu,'231.25.153.198',1997-08-06 11:51:09\ngreen,58,Helen,hlarson1l@prweb.com,'8.40.21.39',1993-08-04 19:53:40\ngreen,59,Patricia,pspencer1m@gmpg.org,'212.198.40.15',1977-08-03 16:37:27\ngreen,60,Joseph,jspencer1n@marriott.com,'13.15.63.238',2005-07-23 20:22:06\ngreen,61,Phillip,pschmidt1o@blogtalkradio.com,'177.98.201.190',1976-05-19 21:47:44\ngreen,62,Joan,jwebb1p@google.ru,'105.229.170.71',1972-09-07 17:53:47\ngreen,63,Phyllis,pkennedy1q@imgur.com,'35.145.8.244',2000-01-01 22:33:37\ngreen,64,Katherine,khunter1r@smh.com.au,'248.168.205.32',1991-01-09 06:40:24\ngreen,65,Laura,lvasquez1s@wiley.com,'128.129.115.152',1997-10-23 12:04:56\ngreen,66,Juan,jdunn1t@state.gov,'44.228.124.51',2004-11-10 05:07:35\ngreen,67,Judith,jholmes1u@wiley.com,'40.227.179.115',1977-08-02 17:01:45\ngreen,68,Beverly,bbaker1v@wufoo.com,'208.34.84.59',2016-03-06 20:07:23\ngreen,69,Lawrence,lcarr1w@flickr.com,'59.158.212.223',1988-09-13 06:07:21\ngreen,70,Gloria,gwilliams1x@mtv.com,'245.231.88.33',1995-03-18 22:32:46\ngreen,71,Steven,ssims1y@cbslocal.com,'104.50.58.255',2001-08-05 21:26:20\ngreen,72,Betty,bmills1z@arstechnica.com,'103.177.214.220',1981-12-14 21:26:54\ngreen,73,Mildred,mfuller20@prnewswire.com,'151.158.8.130',2000-04-19 10:13:55\ngreen,74,Donald,dday21@icq.com,'9.178.102.255',1972-12-03 00:58:24\ngreen,75,Eric,ethomas22@addtoany.com,'85.2.241.227',1992-11-01 05:59:30\ngreen,76,Joyce,jarmstrong23@sitemeter.com,'169.224.20.36',1985-10-24 06:50:01\ngreen,77,Maria,mmartinez24@amazonaws.com,'143.189.167.135',2005-10-05 05:17:42\ngreen,78,Harry,hburton25@youtube.com,'156.47.176.237',1978-03-26 05:53:33\ngreen,79,Kevin,klawrence26@hao123.com,'79.136.183.83',1994-10-12 04:38:52\ngreen,80,David,dhall27@prweb.com,'133.149.172.153',1976-12-15 16:24:24\ngreen,81,Kathy,kperry28@twitter.com,'229.242.72.228',1979-03-04 02:58:56\ngreen,82,Adam,aprice29@elegantthemes.com,'13.145.21.10',1982-11-07 11:46:59\ngreen,83,Brandon,bgriffin2a@va.gov,'73.249.128.212',2013-10-30 05:30:36\ngreen,84,Henry,hnguyen2b@discovery.com,'211.36.214.242',1985-01-09 06:37:27\ngreen,85,Eric,esanchez2c@edublogs.org,'191.166.188.251',2004-05-01 23:21:42\ngreen,86,Jason,jlee2d@jimdo.com,'193.92.16.182',1973-01-08 09:05:39\ngreen,87,Diana,drichards2e@istockphoto.com,'19.130.175.245',1994-10-05 22:50:49\ngreen,88,Andrea,awelch2f@abc.net.au,'94.155.233.96',2002-04-26 08:41:44\ngreen,89,Louis,lwagner2g@miitbeian.gov.cn,'26.217.34.111',2003-08-25 07:56:39\ngreen,90,Jane,jsims2h@seesaa.net,'43.4.220.135',1987-03-20 20:39:04\ngreen,91,Larry,lgrant2i@si.edu,'97.126.79.34',2000-09-07 20:26:19\ngreen,92,Louis,ldean2j@prnewswire.com,'37.148.40.127',2011-09-16 20:12:14\ngreen,93,Jennifer,jcampbell2k@xing.com,'38.106.254.142',1988-07-15 05:06:49\ngreen,94,Wayne,wcunningham2l@google.com.hk,'223.28.26.187',2009-12-15 06:16:54\ngreen,95,Lori,lstevens2m@icq.com,'181.250.181.58',1984-10-28 03:29:19\ngreen,96,Judy,jsimpson2n@marriott.com,'180.121.239.219',1986-02-07 15:18:10\ngreen,97,Phillip,phoward2o@usa.gov,'255.247.0.175',2002-12-26 08:44:45\ngreen,98,Gloria,gwalker2p@usa.gov,'156.140.7.128',1997-10-04 07:58:58\ngreen,99,Paul,pjohnson2q@umn.edu,'183.59.198.197',1991-11-14 12:33:55\ngreen,100,Frank,fgreene2r@blogspot.com,'150.143.68.121',2010-06-12 23:55:39\n\"\"\"\n\nseeds_other_table_csv = \"\"\"id,first_name\n1,Larry\n2,Curly\n3,Moe\n\"\"\"\n\nseeds_expected_multi_source_csv = \"\"\"id,first_name,color\n1,Larry,blue\n2,Curly,red\n3,Moe,green\n\"\"\"\n\nseeds_other_source_table_csv = \"\"\"id,color\n1,blue\n2,red\n3,green\n\"\"\"\n\nmalformed_schema_tests_schema_yml = \"\"\"version: 2\nsources:\n  - name: test_source\n    schema: \"{{ var('test_run_schema') }}\"\n    tables:\n      - name: test_table\n        identifier: source\n        columns:\n          - name: favorite_color\n            data_tests:\n              - relationships:\n                  to: ref('model')\n                  # this will get rendered as its literal\n                  field: \"{{ 'favorite' ~ 'color' }}\"\n\"\"\"\n\nmalformed_schema_tests_model_sql = \"\"\"select * from {{ source('test_source', 'test_table') }}\n\"\"\"\n\nbasic_source_schema_yml = \"\"\"version: 2\n\nsources:\n  - name: test_source\n    tables:\n      - name: test_table\n  - name: other_source\n    tables:\n      - name: test_table\n\"\"\"\n\ndisabled_source_level_schema_yml = \"\"\"version: 2\n\nsources:\n  - name: test_source\n    config:\n      enabled: False\n    tables:\n      - name: test_table\n      - name: disabled_test_table\n\"\"\"\n\ndisabled_source_table_schema_yml = \"\"\"version: 2\n\nsources:\n  - name: test_source\n    tables:\n      - name: test_table\n      - name: disabled_test_table\n        config:\n            enabled: False\n\"\"\"\n\nall_configs_everywhere_schema_yml = \"\"\"version: 2\n\nsources:\n  - name: test_source\n    config:\n        enabled: False\n    tables:\n      - name: test_table\n        config:\n            enabled: True\n      - name: other_test_table\n\"\"\"\n\nall_configs_not_table_schema_yml = \"\"\"version: 2\n\nsources:\n  - name: test_source\n    config:\n        enabled: True\n    tables:\n      - name: test_table\n      - name: other_test_table\n\"\"\"\n\nall_configs_project_source_schema_yml = \"\"\"version: 2\n\nsources:\n  - name: test_source\n    tables:\n      - name: test_table\n        config:\n            enabled: True\n      - name: other_test_table\n\"\"\"\n\ninvalid_config_source_schema_yml = \"\"\"version: 2\n\nsources:\n  - name: test_source\n    tables:\n      - name: test_table\n        config:\n            enabled: True and False\n      - name: other_test_table\n\"\"\"\n\n\ncollect_freshness_macro_override_previous_return_signature = \"\"\"\n{% macro collect_freshness(source, loaded_at_field, filter) %}\n  {% call statement('collect_freshness', fetch_result=True, auto_begin=False) -%}\n    select\n      max({{ loaded_at_field }}) as max_loaded_at,\n      {{ current_timestamp() }} as snapshotted_at\n    from {{ source }}\n    {% if filter %}\n    where {{ filter }}\n    {% endif %}\n  {% endcall %}\n  {{ return(load_result('collect_freshness').table) }}\n{% endmacro %}\n\"\"\"\n\n\nfreshness_via_metadata_schema_yml = \"\"\"version: 2\nsources:\n  - name: test_source\n    loader: custom\n    freshness:\n      warn_after: {count: 10, period: hour}\n      error_after: {count: 1, period: day}\n    schema: my_schema\n    quoting:\n      identifier: True\n    tables:\n      - name: test_table\n        identifier: source\n\"\"\"\n\nfreshness_via_custom_sql_schema_yml = \"\"\"version: 2\nsources:\n  - name: test_source\n    freshness:\n      warn_after: {count: 10, period: hour}\n    schema: \"{{ var(env_var('DBT_TEST_SCHEMA_NAME_VARIABLE')) }}\"\n    quoting:\n      identifier: True\n    tags:\n      - my_test_source_tag\n    tables:\n      - name: source_a\n        identifier: source\n        loaded_at_field: \"{{ var('test_loaded_at') | as_text }}\"\n      - name: source_b\n        identifier: source\n        loaded_at_query: \"select max({{ var('test_loaded_at') | as_text }}) from {{this}}\"\n      - name: source_c\n        identifier: source\n        loaded_at_query: \"select {{current_timestamp()}}\"\n\n\"\"\"\n\nfreshness_via_custom_sql_config_schema_yml = \"\"\"version: 2\nsources:\n  - name: test_source\n    config:\n      freshness:\n        warn_after: {count: 10, period: hour}\n    schema: \"{{ var(env_var('DBT_TEST_SCHEMA_NAME_VARIABLE')) }}\"\n    quoting:\n      identifier: True\n    tags:\n      - my_test_source_tag\n    tables:\n      - name: source_a\n        identifier: source\n        loaded_at_field: \"{{ var('test_loaded_at') | as_text }}\"\n      - name: source_b\n        identifier: source\n        config:\n          loaded_at_query: \"select max({{ var('test_loaded_at') | as_text }}) from {{this}}\"\n      - name: source_c\n        identifier: source\n        config:\n          loaded_at_query: \"select {{current_timestamp()}}\"\n\"\"\"\n\nfreshness_via_custom_sql_source_config_schema_yml = \"\"\"version: 2\nsources:\n  - name: test_source\n    config:\n      freshness:\n        warn_after: {count: 10, period: hour}\n      loaded_at_query: \"select {{current_timestamp()}}\"\n    schema: \"{{ var(env_var('DBT_TEST_SCHEMA_NAME_VARIABLE')) }}\"\n    quoting:\n      identifier: True\n    tags:\n      - my_test_source_tag\n    tables:\n      - name: source_c\n        identifier: source\n\"\"\"\n\n\nfreshness_with_explicit_null_in_table_schema_yml = \"\"\"version: 2\nsources:\n  - name: test_source\n    schema: \"{{ var(env_var('DBT_TEST_SCHEMA_NAME_VARIABLE')) }}\"\n    freshness:\n        warn_after:\n          count: 24\n          period: hour\n    quoting:\n      identifier: True\n    tables:\n      - name: source_a\n        loaded_at_field: \"{{ var('test_loaded_at') | as_text }}\"\n        config:\n          freshness: null\n\"\"\"\n\nfreshness_with_explicit_null_in_source_schema_yml = \"\"\"version: 2\nsources:\n  - name: test_source\n    schema: \"{{ var(env_var('DBT_TEST_SCHEMA_NAME_VARIABLE')) }}\"\n    config:\n      freshness: null\n    quoting:\n      identifier: True\n    tables:\n      - name: source_a\n        loaded_at_field: \"{{ var('test_loaded_at') | as_text }}\"\n\"\"\"\n\nsource_config_loaded_at_query_config_level = \"\"\"\nsources:\n  - name: test_source\n    config:\n      loaded_at_query: 'select 1'\n    tables:\n      - name: test_table\n\"\"\"\n\nsource_config_loaded_at_field_config_level = \"\"\"\nsources:\n  - name: test_source\n    config:\n      loaded_at_field: 'id'\n    tables:\n      - name: test_table\n\"\"\"\n\nsource_table_config_loaded_at_field_config_level = \"\"\"\nsources:\n  - name: test_source\n    tables:\n      - name: test_table\n        config:\n          loaded_at_field: 'id'\n\"\"\"\n\nsource_table_config_loaded_at_query_config_level = \"\"\"\nsources:\n  - name: test_source\n    tables:\n      - name: test_table\n        config:\n          loaded_at_query: 'select 1'\n\"\"\"\n\nsource_table_config_loaded_at_query_not_set_if_field_present = \"\"\"\nsources:\n  - name: test_source\n    config:\n      loaded_at_query: 'select 1'\n    tables:\n      - name: test_table\n        config:\n          loaded_at_field: 'id'\n\"\"\"\n\n# Legacy top-level support\nsource_config_loaded_at_field_top_level = \"\"\"\nsources:\n  - name: test_source\n    loaded_at_field: 'id'\n    tables:\n      - name: test_table\n\"\"\"\n\nsource_config_loaded_at_query_top_level = \"\"\"\nsources:\n  - name: test_source\n    loaded_at_query: 'select 1'\n    tables:\n      - name: test_table\n\"\"\"\n\ntable_config_loaded_at_field_top_level = \"\"\"\nsources:\n  - name: test_source\n    tables:\n      - name: test_table\n        loaded_at_field: 'id'\n\"\"\"\n\ntable_config_loaded_at_query_top_level = \"\"\"\nsources:\n  - name: test_source\n    loaded_at_query: 'select 1'\n    tables:\n      - name: test_table\n        loaded_at_query: 'select 1'\n\"\"\"\n\nsource_table_config_loaded_at_query_not_set_if_field_present_top_level = \"\"\"\nsources:\n  - name: test_source\n    loaded_at_query: 'select 1'\n    tables:\n      - name: test_table\n        loaded_at_field: 'id'\n\"\"\"\n"
  },
  {
    "path": "tests/functional/sources/test_name_chars.py",
    "content": "from dbt.tests.util import get_manifest, run_dbt, write_file\nfrom tests.fixtures.jaffle_shop import JaffleShopProject\n\n# Note: in an actual file (as opposed to a string that we write into a files)\n# there would only be a single backslash.\nsources_yml = \"\"\"\nsources:\n  - name: something_else\n    database: raw\n    schema: jaffle_shop\n    tables:\n      - name: \"\\\\\"/test/orders\\\\\"\"\n      - name: customers\n\"\"\"\n\n\nclass TestNameChars(JaffleShopProject):\n    def test_quotes_in_table_names(self, project):\n        # Write out a sources definition that includes a table name with quotes and a forward slash\n        # Note: forward slashes are not legal in filenames in Linux (or Windows),\n        # so we won't see forward slashes in model names, because they come from file names.\n        write_file(sources_yml, project.project_root, \"models\", \"sources.yml\")\n        manifest = run_dbt([\"parse\"])\n        assert len(manifest.sources) == 2\n        assert 'source.jaffle_shop.something_else.\"/test/orders\"' in manifest.sources.keys()\n        # We've written out the manifest.json artifact, we want to ensure\n        # that it can be read in again (the json is valid).\n        # Note: the key in the json actually looks like: \"source.jaffle_shop.something_else.\\\"/test/orders\\\"\"\n        new_manifest = get_manifest(project.project_root)\n        assert new_manifest\n        assert 'source.jaffle_shop.something_else.\"/test/orders\"' in new_manifest.sources.keys()\n"
  },
  {
    "path": "tests/functional/sources/test_simple_source.py",
    "content": "import os\n\nimport pytest\nimport yaml\n\nfrom dbt.exceptions import ParsingError\nfrom dbt.tests.util import (\n    check_relations_equal,\n    check_table_does_not_exist,\n    run_dbt,\n    update_config_file,\n)\nfrom tests.functional.sources.common_source_setup import BaseSourcesTest\nfrom tests.functional.sources.fixtures import (\n    macros_macro_sql,\n    malformed_models_descendant_model_sql,\n    malformed_models_schema_yml,\n    malformed_schema_tests_model_sql,\n    malformed_schema_tests_schema_yml,\n)\n\n\nclass SuccessfulSourcesTest(BaseSourcesTest):\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project):\n        self.run_dbt_with_vars(project, [\"seed\"])\n        os.environ[\"DBT_ENV_CUSTOM_ENV_key\"] = \"value\"\n\n        yield\n\n        del os.environ[\"DBT_ENV_CUSTOM_ENV_key\"]\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"macro.sql\": macros_macro_sql}\n\n    def _create_schemas(self, project):\n        schema = self.alternative_schema(project.test_schema)\n        project.run_sql(f\"drop schema if exists {schema} cascade\")\n        project.run_sql(f\"create schema {schema}\")\n\n    def alternative_schema(self, test_schema):\n        return test_schema + \"_other\"\n\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def createDummyTables(self, project):\n        self._create_schemas(project)\n        project.run_sql(\"create table {}.dummy_table (id int)\".format(project.test_schema))\n        project.run_sql(\n            \"create view {}.external_view as (select * from {}.dummy_table)\".format(\n                self.alternative_schema(project.test_schema), project.test_schema\n            )\n        )\n\n    def run_dbt_with_vars(self, project, cmd, *args, **kwargs):\n        vars_dict = {\n            \"test_run_schema\": project.test_schema,\n            \"test_run_alt_schema\": self.alternative_schema(project.test_schema),\n            \"test_loaded_at\": project.adapter.quote(\"updated_at\"),\n        }\n        cmd.extend([\"--vars\", yaml.safe_dump(vars_dict)])\n        return run_dbt(cmd, *args, **kwargs)\n\n\nclass TestBasicSource(SuccessfulSourcesTest):\n    def test_basic_source_def(self, project):\n        results = self.run_dbt_with_vars(project, [\"run\"])\n        assert len(results) == 4\n\n        check_relations_equal(\n            project.adapter, [\"source\", \"descendant_model\", \"nonsource_descendant\"]\n        )\n        check_relations_equal(project.adapter, [\"expected_multi_source\", \"multi_source_model\"])\n        results = self.run_dbt_with_vars(project, [\"test\"])\n        assert len(results) == 8\n\n\nclass TestSourceSelector(SuccessfulSourcesTest):\n    def test_source_selector(self, project):\n        # only one of our models explicitly depends upon a source\n        results = self.run_dbt_with_vars(\n            project, [\"run\", \"--models\", \"source:test_source.test_table+\"]\n        )\n        assert len(results) == 1\n        check_relations_equal(project.adapter, [\"source\", \"descendant_model\"])\n        check_table_does_not_exist(project.adapter, \"nonsource_descendant\")\n        check_table_does_not_exist(project.adapter, \"multi_source_model\")\n\n        # do the same thing, but with tags\n        results = self.run_dbt_with_vars(\n            project, [\"run\", \"--models\", \"tag:my_test_source_table_tag+\"]\n        )\n        assert len(results) == 1\n\n        results = self.run_dbt_with_vars(\n            project, [\"test\", \"--models\", \"source:test_source.test_table+\"]\n        )\n        assert len(results) == 6\n\n        results = self.run_dbt_with_vars(\n            project, [\"test\", \"--models\", \"tag:my_test_source_table_tag+\"]\n        )\n        assert len(results) == 6\n\n        results = self.run_dbt_with_vars(project, [\"test\", \"--models\", \"tag:my_test_source_tag+\"])\n        # test_table + other_test_table\n        assert len(results) == 8\n\n        results = self.run_dbt_with_vars(project, [\"test\", \"--models\", \"tag:id_column\"])\n        # all 4 id column tests\n        assert len(results) == 4\n\n\nclass TestEmptySource(SuccessfulSourcesTest):\n    def test_empty_source_def(self, project):\n        # sources themselves can never be selected, so nothing should be run\n        results = self.run_dbt_with_vars(\n            project, [\"run\", \"--models\", \"source:test_source.test_table\"]\n        )\n        check_table_does_not_exist(project.adapter, \"nonsource_descendant\")\n        check_table_does_not_exist(project.adapter, \"multi_source_model\")\n        check_table_does_not_exist(project.adapter, \"descendant_model\")\n        assert len(results) == 0\n\n\nclass TestSourceDef(SuccessfulSourcesTest):\n    def test_source_only_def(self, project):\n        results = self.run_dbt_with_vars(project, [\"run\", \"--models\", \"source:other_source+\"])\n        assert len(results) == 1\n        check_relations_equal(project.adapter, [\"expected_multi_source\", \"multi_source_model\"])\n        check_table_does_not_exist(project.adapter, \"nonsource_descendant\")\n        check_table_does_not_exist(project.adapter, \"descendant_model\")\n\n        results = self.run_dbt_with_vars(project, [\"run\", \"--models\", \"source:test_source+\"])\n        assert len(results) == 2\n        check_relations_equal(project.adapter, [\"source\", \"descendant_model\"])\n        check_relations_equal(project.adapter, [\"expected_multi_source\", \"multi_source_model\"])\n        check_table_does_not_exist(project.adapter, \"nonsource_descendant\")\n\n\nclass TestSourceChildrenParents(SuccessfulSourcesTest):\n    def test_source_childrens_parents(self, project):\n        results = self.run_dbt_with_vars(project, [\"run\", \"--models\", \"@source:test_source\"])\n        assert len(results) == 2\n        check_relations_equal(project.adapter, [\"source\", \"descendant_model\"])\n        check_relations_equal(project.adapter, [\"expected_multi_source\", \"multi_source_model\"])\n        check_table_does_not_exist(project.adapter, \"nonsource_descendant\")\n\n\nclass TestSourceRunOperation(SuccessfulSourcesTest):\n    def test_run_operation_source(self, project):\n        kwargs = '{\"source_name\": \"test_source\", \"table_name\": \"test_table\"}'\n        self.run_dbt_with_vars(project, [\"run-operation\", \"vacuum_source\", \"--args\", kwargs])\n\n\nclass TestMalformedSources(BaseSourcesTest):\n    # even seeds should fail, because parsing is what's raising\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": malformed_models_schema_yml,\n            \"descendant_model.sql\": malformed_models_descendant_model_sql,\n        }\n\n    def test_malformed_schema_will_break_run(self, project):\n        with pytest.raises(ParsingError):\n            self.run_dbt_with_vars(project, [\"seed\"])\n\n\nclass TestRenderingInSourceTests(BaseSourcesTest):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": malformed_schema_tests_schema_yml,\n            \"model.sql\": malformed_schema_tests_model_sql,\n        }\n\n    def test_render_in_source_tests(self, project):\n        self.run_dbt_with_vars(project, [\"seed\"])\n        self.run_dbt_with_vars(project, [\"run\"])\n        # syntax error at or near \"{\", because the test isn't rendered\n        self.run_dbt_with_vars(project, [\"test\"], expect_pass=False)\n\n\nclass TestUnquotedSources(SuccessfulSourcesTest):\n    def test_catalog(self, project):\n        new_quoting_config = {\n            \"quoting\": {\n                \"identifier\": False,\n                \"schema\": False,\n                \"database\": False,\n            }\n        }\n        update_config_file(new_quoting_config, project.project_root, \"dbt_project.yml\")\n        self.run_dbt_with_vars(project, [\"run\"])\n        self.run_dbt_with_vars(project, [\"docs\", \"generate\"])\n"
  },
  {
    "path": "tests/functional/sources/test_source_configs.py",
    "content": "import pytest\n\nfrom dbt.artifacts.resources import SourceConfig\nfrom dbt.tests.util import get_manifest, run_dbt, update_config_file\nfrom dbt_common.dataclass_schema import ValidationError\nfrom tests.functional.sources.fixtures import (\n    all_configs_everywhere_schema_yml,\n    all_configs_not_table_schema_yml,\n    all_configs_project_source_schema_yml,\n    basic_source_schema_yml,\n    disabled_source_level_schema_yml,\n    disabled_source_table_schema_yml,\n    invalid_config_source_schema_yml,\n    source_config_loaded_at_field_config_level,\n    source_config_loaded_at_field_top_level,\n    source_config_loaded_at_query_config_level,\n    source_config_loaded_at_query_top_level,\n    source_table_config_loaded_at_field_config_level,\n    source_table_config_loaded_at_query_config_level,\n    source_table_config_loaded_at_query_not_set_if_field_present,\n    source_table_config_loaded_at_query_not_set_if_field_present_top_level,\n    table_config_loaded_at_field_top_level,\n    table_config_loaded_at_query_top_level,\n)\n\n\nclass SourceConfigTests:\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self):\n        pytest.expected_config = SourceConfig(\n            enabled=True,\n        )\n\n\n# Test enabled config in dbt_project.yml\n# expect pass, already implemented\nclass TestSourceEnabledConfigProjectLevel(SourceConfigTests):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": basic_source_schema_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"sources\": {\n                \"test\": {\n                    \"test_source\": {\n                        \"enabled\": True,\n                    },\n                }\n            }\n        }\n\n    def test_enabled_source_config_dbt_project(self, project):\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n        assert \"source.test.test_source.test_table\" in manifest.sources\n\n        new_enabled_config = {\n            \"sources\": {\n                \"test\": {\n                    \"test_source\": {\n                        \"enabled\": False,\n                    },\n                }\n            }\n        }\n        update_config_file(new_enabled_config, project.project_root, \"dbt_project.yml\")\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n\n        assert (\n            \"source.test.test_source.test_table\" not in manifest.sources\n        )  # or should it be there with enabled: false??\n        assert \"source.test.other_source.test_table\" in manifest.sources\n\n\n# Test enabled config at sources level in yml file\nclass TestConfigYamlSourceLevel(SourceConfigTests):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": disabled_source_level_schema_yml,\n        }\n\n    def test_source_config_yaml_source_level(self, project):\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n        assert \"source.test.test_source.test_table\" not in manifest.sources\n        assert \"source.test.test_source.disabled_test_table\" not in manifest.sources\n\n\n# Test enabled config at source table level in yaml file\nclass TestConfigYamlSourceTable(SourceConfigTests):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": disabled_source_table_schema_yml,\n        }\n\n    def test_source_config_yaml_source_table(self, project):\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n        assert \"source.test.test_source.test_table\" in manifest.sources\n        assert \"source.test.test_source.disabled_test_table\" not in manifest.sources\n\n\n# Test inheritence - set configs at project, source, and source-table level - expect source-table level to win\nclass TestSourceConfigsInheritence1(SourceConfigTests):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"schema.yml\": all_configs_everywhere_schema_yml}\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\"sources\": {\"enabled\": True}}\n\n    def test_source_all_configs_source_table(self, project):\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n        assert \"source.test.test_source.test_table\" in manifest.sources\n        assert \"source.test.test_source.other_test_table\" not in manifest.sources\n        config_test_table = manifest.sources.get(\"source.test.test_source.test_table\").config\n\n        assert isinstance(config_test_table, SourceConfig)\n        assert config_test_table == pytest.expected_config\n\n\n# Test inheritence - set configs at project and source level - expect source level to win\nclass TestSourceConfigsInheritence2(SourceConfigTests):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"schema.yml\": all_configs_not_table_schema_yml}\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\"sources\": {\"enabled\": False}}\n\n    def test_source_two_configs_source_level(self, project):\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n        assert \"source.test.test_source.test_table\" in manifest.sources\n        assert \"source.test.test_source.other_test_table\" in manifest.sources\n        config_test_table = manifest.sources.get(\"source.test.test_source.test_table\").config\n        config_other_test_table = manifest.sources.get(\n            \"source.test.test_source.other_test_table\"\n        ).config\n\n        assert isinstance(config_test_table, SourceConfig)\n        assert isinstance(config_other_test_table, SourceConfig)\n\n        assert config_test_table == config_other_test_table\n        assert config_test_table == pytest.expected_config\n\n\n# Test inheritence - set configs at project and source-table level - expect source-table level to win\nclass TestSourceConfigsInheritence3(SourceConfigTests):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"schema.yml\": all_configs_project_source_schema_yml}\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\"sources\": {\"enabled\": False}}\n\n    def test_source_two_configs_source_table(self, project):\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n        assert \"source.test.test_source.test_table\" in manifest.sources\n        assert \"source.test.test_source.other_test_table\" not in manifest.sources\n        config_test_table = manifest.sources.get(\"source.test.test_source.test_table\").config\n\n        assert isinstance(config_test_table, SourceConfig)\n        assert config_test_table == pytest.expected_config\n\n\n# Test invalid source configs\nclass TestInvalidSourceConfig(SourceConfigTests):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": invalid_config_source_schema_yml,\n        }\n\n    def test_invalid_config_source(self, project):\n        with pytest.raises(ValidationError) as excinfo:\n            run_dbt([\"parse\"])\n        expected_msg = \"'True and False' is not of type 'boolean'\"\n        assert expected_msg in str(excinfo.value)\n\n\nclass TestSourceLoadedAtFieldConfigLevel:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": source_config_loaded_at_field_config_level,\n        }\n\n    def test_loaded_at_field_config(self, project):\n        manifest = run_dbt([\"parse\"])\n        source = manifest.sources[\"source.test.test_source.test_table\"]\n        assert source.loaded_at_field == \"id\"\n        assert source.config.loaded_at_field == \"id\"\n\n\nclass TestSourceLoadedAtQueryConfigLevel:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": source_config_loaded_at_query_config_level,\n        }\n\n    def test_loaded_at_field_config(self, project):\n        manifest = run_dbt([\"parse\"])\n        source = manifest.sources[\"source.test.test_source.test_table\"]\n        assert source.loaded_at_query == \"select 1\"\n        assert source.config.loaded_at_query == \"select 1\"\n\n\nclass TestTableLoadedAtFieldConfigLevel:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": source_table_config_loaded_at_field_config_level,\n        }\n\n    def test_loaded_at_field_config(self, project):\n        manifest = run_dbt([\"parse\"])\n        source = manifest.sources[\"source.test.test_source.test_table\"]\n        assert source.loaded_at_field == \"id\"\n        assert source.config.loaded_at_field == \"id\"\n\n\nclass TestTableLoadedAtQueryConfigLevel:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": source_table_config_loaded_at_query_config_level,\n        }\n\n    def test_loaded_at_field_config(self, project):\n        manifest = run_dbt([\"parse\"])\n        source = manifest.sources[\"source.test.test_source.test_table\"]\n        assert source.loaded_at_query == \"select 1\"\n        assert source.config.loaded_at_query == \"select 1\"\n\n\nclass TestSourceLoadedAtFieldTopLevel:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": source_config_loaded_at_field_top_level,\n        }\n\n    def test_loaded_at_field_config(self, project):\n        manifest = run_dbt([\"parse\"])\n        source = manifest.sources[\"source.test.test_source.test_table\"]\n        assert source.loaded_at_field == \"id\"\n        assert source.config.loaded_at_field == \"id\"\n\n\nclass TestSourceLoadedAtQueryTopLevel:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": source_config_loaded_at_query_top_level,\n        }\n\n    def test_loaded_at_query_config(self, project):\n        manifest = run_dbt([\"parse\"])\n        source = manifest.sources[\"source.test.test_source.test_table\"]\n        assert source.loaded_at_query == \"select 1\"\n        assert source.config.loaded_at_query == \"select 1\"\n\n\nclass TestTableLoadedAtFieldTopLevel:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": table_config_loaded_at_field_top_level,\n        }\n\n    def test_loaded_at_field_config(self, project):\n        manifest = run_dbt([\"parse\"])\n        source = manifest.sources[\"source.test.test_source.test_table\"]\n        assert source.loaded_at_field == \"id\"\n        assert source.config.loaded_at_field == \"id\"\n\n\nclass TestTableLoadedAtQueryTopLevel:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": table_config_loaded_at_query_top_level,\n        }\n\n    def test_loaded_at_query_config(self, project):\n        manifest = run_dbt([\"parse\"])\n        source = manifest.sources[\"source.test.test_source.test_table\"]\n        assert source.loaded_at_query == \"select 1\"\n        assert source.config.loaded_at_query == \"select 1\"\n\n\nclass TestTableLoadedAtQueryNoneWhenFieldSetConfigLevel:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": source_table_config_loaded_at_query_not_set_if_field_present,\n        }\n\n    def test_loaded_at_query_config(self, project):\n        manifest = run_dbt([\"parse\"])\n        source = manifest.sources[\"source.test.test_source.test_table\"]\n        assert source.loaded_at_field == \"id\"\n        assert source.config.loaded_at_field == \"id\"\n\n        assert source.loaded_at_query is None\n        assert source.config.loaded_at_query is None\n\n\nclass TestTableLoadedAtQueryNoneWhenFieldSetTopLevel:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": source_table_config_loaded_at_query_not_set_if_field_present_top_level,\n        }\n\n    def test_loaded_at_query_config(self, project):\n        manifest = run_dbt([\"parse\"])\n        source = manifest.sources[\"source.test.test_source.test_table\"]\n        assert source.loaded_at_field == \"id\"\n        assert source.config.loaded_at_field == \"id\"\n\n        assert source.loaded_at_query is None\n        assert source.config.loaded_at_query is None\n"
  },
  {
    "path": "tests/functional/sources/test_source_fresher_state.py",
    "content": "import json\nimport os\nimport shutil\nfrom datetime import datetime, timedelta, timezone\n\nimport pytest\n\nimport dbt.version\nfrom dbt.contracts.results import FreshnessExecutionResultArtifact\nfrom dbt.tests.util import AnyFloat, AnyStringWith\nfrom dbt_common.exceptions import DbtInternalError\nfrom tests.functional.sources.common_source_setup import BaseSourcesTest\nfrom tests.functional.sources.fixtures import (\n    error_models_schema_yml,\n    models_newly_added_error_model_sql,\n    models_newly_added_model_sql,\n)\n\n\n# TODO: We may create utility classes to handle reusable fixtures.\ndef copy_to_previous_state():\n    shutil.copyfile(\"target/manifest.json\", \"previous_state/manifest.json\")\n    shutil.copyfile(\"target/run_results.json\", \"previous_state/run_results.json\")\n\n\nclass SuccessfulSourceFreshnessTest(BaseSourcesTest):\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project):\n        self.run_dbt_with_vars(project, [\"seed\"])\n        pytest._id = 101\n        pytest.freshness_start_time = datetime.now(timezone.utc).replace(tzinfo=None)\n        # this is the db initial value\n        pytest.last_inserted_time = \"2016-09-19T14:45:51+00:00\"\n\n        os.environ[\"DBT_ENV_CUSTOM_ENV_key\"] = \"value\"\n\n        yield\n\n        del os.environ[\"DBT_ENV_CUSTOM_ENV_key\"]\n\n    def _set_updated_at_to(self, project, delta):\n        insert_time = datetime.now(timezone.utc).replace(tzinfo=None) + delta\n        timestr = insert_time.strftime(\"%Y-%m-%d %H:%M:%S\")\n        # favorite_color,id,first_name,email,ip_address,updated_at\n        insert_id = pytest._id\n        pytest._id += 1\n        quoted_columns = \",\".join(\n            project.adapter.quote(c)\n            for c in (\"favorite_color\", \"id\", \"first_name\", \"email\", \"ip_address\", \"updated_at\")\n        )\n        kwargs = {\n            \"schema\": project.test_schema,\n            \"time\": timestr,\n            \"id\": insert_id,\n            \"source\": project.adapter.quote(\"source\"),\n            \"quoted_columns\": quoted_columns,\n        }\n        raw_code = \"\"\"INSERT INTO {schema}.{source}\n            ({quoted_columns})\n        VALUES (\n            'blue',{id},'Jake','abc@example.com','192.168.1.1','{time}'\n        )\"\"\".format(\n            **kwargs\n        )\n        project.run_sql(raw_code)\n        pytest.last_inserted_time = insert_time.strftime(\"%Y-%m-%dT%H:%M:%S+00:00\")\n\n    def assertBetween(self, timestr, start, end=None):\n        datefmt = \"%Y-%m-%dT%H:%M:%S.%fZ\"\n        if end is None:\n            end = datetime.now(timezone.utc).replace(tzinfo=None)\n\n        parsed = datetime.strptime(timestr, datefmt)\n\n        assert start <= parsed\n        assert end >= parsed\n\n    def _assert_freshness_results(self, path, state):\n        assert os.path.exists(path)\n        with open(path) as fp:\n            data = json.load(fp)\n\n        try:\n            FreshnessExecutionResultArtifact.validate(data)\n        except Exception:\n            raise pytest.fail(\"FreshnessExecutionResultArtifact did not validate\")\n        assert set(data) == {\"metadata\", \"results\", \"elapsed_time\"}\n        assert \"generated_at\" in data[\"metadata\"]\n        assert isinstance(data[\"elapsed_time\"], float)\n        self.assertBetween(data[\"metadata\"][\"generated_at\"], pytest.freshness_start_time)\n        assert (\n            data[\"metadata\"][\"dbt_schema_version\"]\n            == \"https://schemas.getdbt.com/dbt/sources/v3.json\"\n        )\n        assert data[\"metadata\"][\"dbt_version\"] == dbt.version.__version__\n        key = \"key\"\n        if os.name == \"nt\":\n            key = key.upper()\n        assert data[\"metadata\"][\"env\"] == {key: \"value\"}\n\n        last_inserted_time = pytest.last_inserted_time\n\n        assert len(data[\"results\"]) == 1\n\n        assert data[\"results\"] == [\n            {\n                \"unique_id\": \"source.test.test_source.test_table\",\n                \"max_loaded_at\": last_inserted_time,\n                \"snapshotted_at\": AnyStringWith(),\n                \"max_loaded_at_time_ago_in_s\": AnyFloat(),\n                \"status\": state,\n                \"criteria\": {\n                    \"filter\": None,\n                    \"warn_after\": {\"count\": 10, \"period\": \"hour\"},\n                    \"error_after\": {\"count\": 18, \"period\": \"hour\"},\n                },\n                \"adapter_response\": {\"_message\": \"SELECT 1\", \"code\": \"SELECT\", \"rows_affected\": 1},\n                \"thread_id\": AnyStringWith(\"Thread-\"),\n                \"execution_time\": AnyFloat(),\n                \"timing\": [\n                    {\n                        \"name\": \"compile\",\n                        \"started_at\": AnyStringWith(),\n                        \"completed_at\": AnyStringWith(),\n                    },\n                    {\n                        \"name\": \"execute\",\n                        \"started_at\": AnyStringWith(),\n                        \"completed_at\": AnyStringWith(),\n                    },\n                ],\n            }\n        ]\n\n\nclass TestSourceFresherNothingToDo(SuccessfulSourceFreshnessTest):\n    def test_source_fresher_nothing_to_do(self, project):\n        self.run_dbt_with_vars(project, [\"run\"])\n        self._set_updated_at_to(project, timedelta(hours=-2))\n        previous_state_results = self.run_dbt_with_vars(\n            project, [\"source\", \"freshness\", \"-o\", \"previous_state/sources.json\"]\n        )\n        self._assert_freshness_results(\"previous_state/sources.json\", \"pass\")\n        copy_to_previous_state()\n\n        current_state_results = self.run_dbt_with_vars(\n            project, [\"source\", \"freshness\", \"-o\", \"target/sources.json\"]\n        )\n        self._assert_freshness_results(\"target/sources.json\", \"pass\")\n\n        assert previous_state_results[0].max_loaded_at == current_state_results[0].max_loaded_at\n\n        source_fresher_results = self.run_dbt_with_vars(\n            project,\n            [\"test\", \"-s\", \"source_status:fresher+\", \"--defer\", \"--state\", \"./previous_state\"],\n        )\n        assert source_fresher_results.results == []\n\n\nclass TestSourceFresherRun(SuccessfulSourceFreshnessTest):\n    def test_source_fresher_run_error(self, project):\n        self.run_dbt_with_vars(project, [\"run\"])\n        previous_state_results = self.run_dbt_with_vars(\n            project,\n            [\"source\", \"freshness\", \"-o\", \"previous_state/sources.json\"],\n            expect_pass=False,\n        )\n        self._assert_freshness_results(\"previous_state/sources.json\", \"error\")\n        copy_to_previous_state()\n\n        self._set_updated_at_to(project, timedelta(hours=-20))\n        current_state_results = self.run_dbt_with_vars(\n            project,\n            [\"source\", \"freshness\", \"-o\", \"target/sources.json\"],\n            expect_pass=False,\n        )\n        self._assert_freshness_results(\"target/sources.json\", \"error\")\n\n        assert previous_state_results[0].max_loaded_at < current_state_results[0].max_loaded_at\n\n        source_fresher_results = self.run_dbt_with_vars(\n            project,\n            [\"run\", \"-s\", \"source_status:fresher\", \"--defer\", \"--state\", \"previous_state\"],\n        )\n        assert source_fresher_results.results == []\n\n        source_fresher_plus_results = self.run_dbt_with_vars(\n            project,\n            [\"run\", \"-s\", \"source_status:fresher+\", \"--defer\", \"--state\", \"previous_state\"],\n        )\n        nodes = set([elem.node.name for elem in source_fresher_plus_results])\n        assert nodes == {\"descendant_model\"}\n\n    def test_source_fresher_run_warn(self, project):\n        self.run_dbt_with_vars(project, [\"run\"])\n        self._set_updated_at_to(project, timedelta(hours=-17))\n        previous_state_results = self.run_dbt_with_vars(\n            project,\n            [\"source\", \"freshness\", \"-o\", \"previous_state/sources.json\"],\n            expect_pass=True,\n        )\n        self._assert_freshness_results(\"previous_state/sources.json\", \"warn\")\n        copy_to_previous_state()\n\n        self._set_updated_at_to(project, timedelta(hours=-11))\n        current_state_results = self.run_dbt_with_vars(\n            project, [\"source\", \"freshness\", \"-o\", \"target/sources.json\"]\n        )\n        self._assert_freshness_results(\"target/sources.json\", \"warn\")\n\n        assert previous_state_results[0].max_loaded_at < current_state_results[0].max_loaded_at\n\n        source_fresher_results = self.run_dbt_with_vars(\n            project,\n            [\"run\", \"-s\", \"source_status:fresher\", \"--defer\", \"--state\", \"previous_state\"],\n        )\n        assert source_fresher_results.results == []\n\n        source_fresher_plus_results = self.run_dbt_with_vars(\n            project,\n            [\"run\", \"-s\", \"source_status:fresher+\", \"--defer\", \"--state\", \"previous_state\"],\n        )\n        nodes = set([elem.node.name for elem in source_fresher_plus_results])\n        assert nodes == {\"descendant_model\"}\n\n    def test_source_fresher_run_pass(self, project):\n        self.run_dbt_with_vars(project, [\"run\"])\n        self._set_updated_at_to(project, timedelta(hours=-2))\n        previous_state_results = self.run_dbt_with_vars(\n            project, [\"source\", \"freshness\", \"-o\", \"previous_state/sources.json\"]\n        )\n        self._assert_freshness_results(\"previous_state/sources.json\", \"pass\")\n        copy_to_previous_state()\n\n        self._set_updated_at_to(project, timedelta(hours=-1))\n        current_state_results = self.run_dbt_with_vars(\n            project, [\"source\", \"freshness\", \"-o\", \"target/sources.json\"]\n        )\n        self._assert_freshness_results(\"target/sources.json\", \"pass\")\n\n        assert previous_state_results[0].max_loaded_at < current_state_results[0].max_loaded_at\n\n        source_fresher_results = self.run_dbt_with_vars(\n            project,\n            [\"run\", \"-s\", \"source_status:fresher\", \"--defer\", \"--state\", \"previous_state\"],\n        )\n        assert source_fresher_results.results == []\n\n        source_fresher_plus_results = self.run_dbt_with_vars(\n            project,\n            [\"run\", \"-s\", \"source_status:fresher+\", \"--defer\", \"--state\", \"previous_state\"],\n        )\n        nodes = set([elem.node.name for elem in source_fresher_plus_results])\n        assert nodes == {\"descendant_model\"}\n\n\nclass TestSourceFresherBuildStateModified(SuccessfulSourceFreshnessTest):\n    def test_source_fresher_build_state_modified_pass(self, project, project_root):\n        self.run_dbt_with_vars(project, [\"run\"])\n\n        self._set_updated_at_to(project, timedelta(hours=-2))\n        previous_state_results = self.run_dbt_with_vars(\n            project, [\"source\", \"freshness\", \"-o\", \"previous_state/sources.json\"]\n        )\n        self._assert_freshness_results(\"previous_state/sources.json\", \"pass\")\n\n        self._set_updated_at_to(project, timedelta(hours=-1))\n        current_state_results = self.run_dbt_with_vars(\n            project, [\"source\", \"freshness\", \"-o\", \"target/sources.json\"]\n        )\n        self._assert_freshness_results(\"target/sources.json\", \"pass\")\n\n        assert previous_state_results[0].max_loaded_at < current_state_results[0].max_loaded_at\n\n        models_path = project_root.join(\"models/\")\n        assert os.path.exists(models_path)\n        with open(f\"{models_path}/newly_added_model.sql\", \"w\") as fp:\n            fp.write(models_newly_added_model_sql)\n\n        copy_to_previous_state()\n        state_modified_results = self.run_dbt_with_vars(\n            project,\n            [\n                \"build\",\n                \"--select\",\n                \"source_status:fresher+\",\n                \"state:modified+\",\n                \"--defer\",\n                \"--state\",\n                \"previous_state\",\n            ],\n        )\n        nodes = set([elem.node.name for elem in state_modified_results])\n        assert nodes == {\n            \"newly_added_model\",\n            \"source_unique_test_source_test_table_id\",\n            \"unique_descendant_model_id\",\n            \"not_null_descendant_model_id\",\n            \"source_not_null_test_source_test_table_id\",\n            \"descendant_model\",\n            \"source_relationships_test_source_test_table_favorite_color__favorite_color__ref_descendant_model_\",\n            \"relationships_descendant_model_favorite_color__favorite_color__source_test_source_test_table_\",\n        }\n\n\nclass TestSourceFresherRuntimeError(SuccessfulSourceFreshnessTest):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": error_models_schema_yml,\n        }\n\n    def test_runtime_error_states(self, project):\n        self.run_dbt_with_vars(project, [\"run\"])\n        previous_state_results = self.run_dbt_with_vars(\n            project,\n            [\"source\", \"freshness\", \"-o\", \"previous_state/sources.json\"],\n            expect_pass=False,\n        )\n        assert len(previous_state_results) == 1\n        assert previous_state_results[0].status == \"runtime error\"\n        copy_to_previous_state()\n\n        self._set_updated_at_to(project, timedelta(hours=-1))\n        current_state_results = self.run_dbt_with_vars(\n            project,\n            [\"source\", \"freshness\", \"-o\", \"target/sources.json\"],\n            expect_pass=False,\n        )\n        assert len(current_state_results) == 1\n        assert current_state_results[0].status == \"runtime error\"\n\n        assert not hasattr(previous_state_results[0], \"max_loaded_at\")\n        assert not hasattr(current_state_results[0], \"max_loaded_at\")\n\n        source_fresher_results = self.run_dbt_with_vars(\n            project,\n            [\"test\", \"-s\", \"source_status:fresher\", \"--defer\", \"--state\", \"previous_state\"],\n        )\n        assert source_fresher_results.results == []\n\n\nclass TestSourceFresherTest(SuccessfulSourceFreshnessTest):\n    def test_source_fresher_run_error(self, project):\n        self.run_dbt_with_vars(project, [\"run\"])\n        previous_state_results = self.run_dbt_with_vars(\n            project,\n            [\"source\", \"freshness\", \"-o\", \"previous_state/sources.json\"],\n            expect_pass=False,\n        )\n        self._assert_freshness_results(\"previous_state/sources.json\", \"error\")\n        copy_to_previous_state()\n\n        self._set_updated_at_to(project, timedelta(hours=-20))\n        current_state_results = self.run_dbt_with_vars(\n            project,\n            [\"source\", \"freshness\", \"-o\", \"target/sources.json\"],\n            expect_pass=False,\n        )\n        self._assert_freshness_results(\"target/sources.json\", \"error\")\n\n        assert previous_state_results[0].max_loaded_at < current_state_results[0].max_loaded_at\n\n        source_fresher_results = self.run_dbt_with_vars(\n            project,\n            [\"test\", \"-s\", \"source_status:fresher\", \"--defer\", \"--state\", \"previous_state\"],\n        )\n        nodes = set([elem.node.name for elem in source_fresher_results])\n        assert nodes == {\n            \"relationships_descendant_model_favorite_color__favorite_color__source_test_source_test_table_\",\n            \"source_not_null_test_source_test_table_id\",\n            \"source_relationships_test_source_test_table_favorite_color__favorite_color__ref_descendant_model_\",\n            \"source_unique_test_source_test_table_id\",\n        }\n\n        source_fresher_plus_results = self.run_dbt_with_vars(\n            project,\n            [\"test\", \"-s\", \"source_status:fresher+\", \"--defer\", \"--state\", \"previous_state\"],\n        )\n        nodes = set([elem.node.name for elem in source_fresher_plus_results])\n        assert nodes == {\n            \"relationships_descendant_model_favorite_color__favorite_color__source_test_source_test_table_\",\n            \"source_not_null_test_source_test_table_id\",\n            \"source_relationships_test_source_test_table_favorite_color__favorite_color__ref_descendant_model_\",\n            \"source_unique_test_source_test_table_id\",\n            \"unique_descendant_model_id\",\n            \"not_null_descendant_model_id\",\n        }\n\n    def test_source_fresher_test_warn(self, project):\n        self.run_dbt_with_vars(project, [\"run\"])\n        self._set_updated_at_to(project, timedelta(hours=-17))\n        previous_state_results = self.run_dbt_with_vars(\n            project,\n            [\"source\", \"freshness\", \"-o\", \"previous_state/sources.json\"],\n            expect_pass=True,\n        )\n        self._assert_freshness_results(\"previous_state/sources.json\", \"warn\")\n        copy_to_previous_state()\n\n        self._set_updated_at_to(project, timedelta(hours=-11))\n        current_state_results = self.run_dbt_with_vars(\n            project,\n            [\"source\", \"freshness\", \"-o\", \"target/sources.json\"],\n            expect_pass=True,\n        )\n        self._assert_freshness_results(\"target/sources.json\", \"warn\")\n\n        assert previous_state_results[0].max_loaded_at < current_state_results[0].max_loaded_at\n\n        source_fresher_results = self.run_dbt_with_vars(\n            project,\n            [\"test\", \"-s\", \"source_status:fresher\", \"--defer\", \"--state\", \"previous_state\"],\n        )\n        nodes = set([elem.node.name for elem in source_fresher_results])\n        assert nodes == {\n            \"relationships_descendant_model_favorite_color__favorite_color__source_test_source_test_table_\",\n            \"source_not_null_test_source_test_table_id\",\n            \"source_relationships_test_source_test_table_favorite_color__favorite_color__ref_descendant_model_\",\n            \"source_unique_test_source_test_table_id\",\n        }\n\n        source_fresher_plus_results = self.run_dbt_with_vars(\n            project,\n            [\"test\", \"-s\", \"source_status:fresher+\", \"--defer\", \"--state\", \"previous_state\"],\n        )\n        nodes = set([elem.node.name for elem in source_fresher_plus_results])\n        assert nodes == {\n            \"relationships_descendant_model_favorite_color__favorite_color__source_test_source_test_table_\",\n            \"source_not_null_test_source_test_table_id\",\n            \"source_relationships_test_source_test_table_favorite_color__favorite_color__ref_descendant_model_\",\n            \"source_unique_test_source_test_table_id\",\n            \"unique_descendant_model_id\",\n            \"not_null_descendant_model_id\",\n        }\n\n    def test_source_fresher_test_pass(self, project):\n        self.run_dbt_with_vars(project, [\"run\"])\n        self._set_updated_at_to(project, timedelta(hours=-2))\n        previous_state_results = self.run_dbt_with_vars(\n            project, [\"source\", \"freshness\", \"-o\", \"previous_state/sources.json\"]\n        )\n        self._assert_freshness_results(\"previous_state/sources.json\", \"pass\")\n        copy_to_previous_state()\n\n        self._set_updated_at_to(project, timedelta(hours=-1))\n        current_state_results = self.run_dbt_with_vars(\n            project, [\"source\", \"freshness\", \"-o\", \"target/sources.json\"]\n        )\n        self._assert_freshness_results(\"target/sources.json\", \"pass\")\n\n        assert previous_state_results[0].max_loaded_at < current_state_results[0].max_loaded_at\n\n        source_fresher_results = self.run_dbt_with_vars(\n            project,\n            [\"test\", \"-s\", \"source_status:fresher\", \"--defer\", \"--state\", \"previous_state\"],\n        )\n        nodes = set([elem.node.name for elem in source_fresher_results])\n        assert nodes == {\n            \"relationships_descendant_model_favorite_color__favorite_color__source_test_source_test_table_\",\n            \"source_not_null_test_source_test_table_id\",\n            \"source_relationships_test_source_test_table_favorite_color__favorite_color__ref_descendant_model_\",\n            \"source_unique_test_source_test_table_id\",\n        }\n\n        source_fresher_plus_results = self.run_dbt_with_vars(\n            project,\n            [\"test\", \"-s\", \"source_status:fresher+\", \"--defer\", \"--state\", \"previous_state\"],\n        )\n        nodes = set([elem.node.name for elem in source_fresher_plus_results])\n        assert nodes == {\n            \"relationships_descendant_model_favorite_color__favorite_color__source_test_source_test_table_\",\n            \"source_not_null_test_source_test_table_id\",\n            \"source_relationships_test_source_test_table_favorite_color__favorite_color__ref_descendant_model_\",\n            \"source_unique_test_source_test_table_id\",\n            \"unique_descendant_model_id\",\n            \"not_null_descendant_model_id\",\n        }\n\n\nclass TestSourceFresherBuild(SuccessfulSourceFreshnessTest):\n    def test_source_fresher_build_error(self, project):\n        self.run_dbt_with_vars(project, [\"build\"])\n        previous_state_results = self.run_dbt_with_vars(\n            project,\n            [\"source\", \"freshness\", \"-o\", \"previous_state/sources.json\"],\n            expect_pass=False,\n        )\n        self._assert_freshness_results(\"previous_state/sources.json\", \"error\")\n        copy_to_previous_state()\n\n        self._set_updated_at_to(project, timedelta(hours=-20))\n        current_state_results = self.run_dbt_with_vars(\n            project,\n            [\"source\", \"freshness\", \"-o\", \"target/sources.json\"],\n            expect_pass=False,\n        )\n        self._assert_freshness_results(\"target/sources.json\", \"error\")\n\n        assert previous_state_results[0].max_loaded_at < current_state_results[0].max_loaded_at\n\n        source_fresher_results = self.run_dbt_with_vars(\n            project,\n            [\"build\", \"-s\", \"source_status:fresher\", \"--defer\", \"--state\", \"previous_state\"],\n        )\n        nodes = set([elem.node.name for elem in source_fresher_results])\n        assert nodes == {\n            \"relationships_descendant_model_favorite_color__favorite_color__source_test_source_test_table_\",\n            \"source_not_null_test_source_test_table_id\",\n            \"source_relationships_test_source_test_table_favorite_color__favorite_color__ref_descendant_model_\",\n            \"source_unique_test_source_test_table_id\",\n        }\n\n        source_fresher_plus_results = self.run_dbt_with_vars(\n            project,\n            [\"build\", \"-s\", \"source_status:fresher+\", \"--defer\", \"--state\", \"previous_state\"],\n        )\n        nodes = set([elem.node.name for elem in source_fresher_plus_results])\n        assert nodes == {\n            \"descendant_model\",\n            \"relationships_descendant_model_favorite_color__favorite_color__source_test_source_test_table_\",\n            \"source_not_null_test_source_test_table_id\",\n            \"source_relationships_test_source_test_table_favorite_color__favorite_color__ref_descendant_model_\",\n            \"source_unique_test_source_test_table_id\",\n            \"unique_descendant_model_id\",\n            \"not_null_descendant_model_id\",\n        }\n\n    def test_source_fresher_build_warn(self, project):\n        self.run_dbt_with_vars(project, [\"build\"])\n        self._set_updated_at_to(project, timedelta(hours=-17))\n        previous_state_results = self.run_dbt_with_vars(\n            project,\n            [\"source\", \"freshness\", \"-o\", \"previous_state/sources.json\"],\n            expect_pass=True,\n        )\n        self._assert_freshness_results(\"previous_state/sources.json\", \"warn\")\n        copy_to_previous_state()\n\n        self._set_updated_at_to(project, timedelta(hours=-11))\n        current_state_results = self.run_dbt_with_vars(\n            project, [\"source\", \"freshness\", \"-o\", \"target/sources.json\"]\n        )\n        self._assert_freshness_results(\"target/sources.json\", \"warn\")\n\n        assert previous_state_results[0].max_loaded_at < current_state_results[0].max_loaded_at\n\n        source_fresher_results = self.run_dbt_with_vars(\n            project,\n            [\"build\", \"-s\", \"source_status:fresher\", \"--defer\", \"--state\", \"previous_state\"],\n        )\n        nodes = set([elem.node.name for elem in source_fresher_results])\n        assert nodes == {\n            \"relationships_descendant_model_favorite_color__favorite_color__source_test_source_test_table_\",\n            \"source_not_null_test_source_test_table_id\",\n            \"source_relationships_test_source_test_table_favorite_color__favorite_color__ref_descendant_model_\",\n            \"source_unique_test_source_test_table_id\",\n        }\n\n        source_fresher_plus_results = self.run_dbt_with_vars(\n            project,\n            [\"build\", \"-s\", \"source_status:fresher+\", \"--defer\", \"--state\", \"previous_state\"],\n        )\n        nodes = set([elem.node.name for elem in source_fresher_plus_results])\n        assert nodes == {\n            \"descendant_model\",\n            \"relationships_descendant_model_favorite_color__favorite_color__source_test_source_test_table_\",\n            \"source_not_null_test_source_test_table_id\",\n            \"source_relationships_test_source_test_table_favorite_color__favorite_color__ref_descendant_model_\",\n            \"source_unique_test_source_test_table_id\",\n            \"unique_descendant_model_id\",\n            \"not_null_descendant_model_id\",\n        }\n\n    def test_source_fresher_build_pass(self, project):\n        self.run_dbt_with_vars(project, [\"build\"])\n        self._set_updated_at_to(project, timedelta(hours=-2))\n        previous_state_results = self.run_dbt_with_vars(\n            project, [\"source\", \"freshness\", \"-o\", \"previous_state/sources.json\"]\n        )\n        self._assert_freshness_results(\"previous_state/sources.json\", \"pass\")\n        copy_to_previous_state()\n\n        self._set_updated_at_to(project, timedelta(hours=-1))\n        current_state_results = self.run_dbt_with_vars(\n            project, [\"source\", \"freshness\", \"-o\", \"target/sources.json\"]\n        )\n        self._assert_freshness_results(\"target/sources.json\", \"pass\")\n\n        assert previous_state_results[0].max_loaded_at < current_state_results[0].max_loaded_at\n\n        source_fresher_results = self.run_dbt_with_vars(\n            project,\n            [\"build\", \"-s\", \"source_status:fresher\", \"--defer\", \"--state\", \"previous_state\"],\n        )\n        nodes = set([elem.node.name for elem in source_fresher_results])\n        assert nodes == {\n            \"relationships_descendant_model_favorite_color__favorite_color__source_test_source_test_table_\",\n            \"source_not_null_test_source_test_table_id\",\n            \"source_relationships_test_source_test_table_favorite_color__favorite_color__ref_descendant_model_\",\n            \"source_unique_test_source_test_table_id\",\n        }\n\n        source_fresher_plus_results = self.run_dbt_with_vars(\n            project,\n            [\"build\", \"-s\", \"source_status:fresher+\", \"--defer\", \"--state\", \"previous_state\"],\n        )\n        nodes = set([elem.node.name for elem in source_fresher_plus_results])\n        assert nodes == {\n            \"descendant_model\",\n            \"relationships_descendant_model_favorite_color__favorite_color__source_test_source_test_table_\",\n            \"source_not_null_test_source_test_table_id\",\n            \"source_relationships_test_source_test_table_favorite_color__favorite_color__ref_descendant_model_\",\n            \"source_unique_test_source_test_table_id\",\n            \"unique_descendant_model_id\",\n            \"not_null_descendant_model_id\",\n        }\n\n\nclass TestSourceFresherNoPreviousState(SuccessfulSourceFreshnessTest):\n    def test_intentional_failure_no_previous_state(self, project):\n        self.run_dbt_with_vars(project, [\"run\"])\n        # TODO add the current and previous but with previous as null\n        with pytest.raises(DbtInternalError) as excinfo:\n            self.run_dbt_with_vars(\n                project,\n                [\"run\", \"-s\", \"source_status:fresher\", \"--state\", \"previous_state\"],\n            )\n        assert \"No previous state comparison freshness results in sources.json\" in str(\n            excinfo.value\n        )\n\n\nclass TestSourceFresherNoCurrentState(SuccessfulSourceFreshnessTest):\n    def test_intentional_failure_no_previous_state(self, project):\n        self.run_dbt_with_vars(project, [\"run\"])\n        previous_state_results = self.run_dbt_with_vars(\n            project,\n            [\"source\", \"freshness\", \"-o\", \"previous_state/sources.json\"],\n            expect_pass=False,\n        )\n        self._assert_freshness_results(\"previous_state/sources.json\", \"error\")\n        copy_to_previous_state()\n        assert previous_state_results[0].max_loaded_at is not None\n\n        with pytest.raises(DbtInternalError) as excinfo:\n            self.run_dbt_with_vars(\n                project,\n                [\"run\", \"-s\", \"source_status:fresher\", \"--defer\", \"--state\", \"previous_state\"],\n            )\n        assert \"No current state comparison freshness results in sources.json\" in str(\n            excinfo.value\n        )\n\n\nclass TestSourceFresherBuildResultSelectors(SuccessfulSourceFreshnessTest):\n    def test_source_fresher_build_state_modified_pass(self, project, project_root):\n        models_path = project_root.join(\"models/\")\n        assert os.path.exists(models_path)\n        with open(f\"{models_path}/newly_added_error_model.sql\", \"w\") as fp:\n            fp.write(models_newly_added_error_model_sql)\n\n        self.run_dbt_with_vars(project, [\"run\"], expect_pass=False)\n\n        self._set_updated_at_to(project, timedelta(hours=-2))\n        previous_state_results = self.run_dbt_with_vars(\n            project, [\"source\", \"freshness\", \"-o\", \"previous_state/sources.json\"]\n        )\n\n        self._assert_freshness_results(\"previous_state/sources.json\", \"pass\")\n        copy_to_previous_state()\n\n        self._set_updated_at_to(project, timedelta(hours=-1))\n        current_state_results = self.run_dbt_with_vars(\n            project, [\"source\", \"freshness\", \"-o\", \"target/sources.json\"]\n        )\n\n        self._assert_freshness_results(\"target/sources.json\", \"pass\")\n\n        assert previous_state_results[0].max_loaded_at < current_state_results[0].max_loaded_at\n\n        state_modified_results = self.run_dbt_with_vars(\n            project,\n            [\n                \"build\",\n                \"--select\",\n                \"source_status:fresher+\",\n                \"result:error+\",\n                \"--defer\",\n                \"--state\",\n                \"previous_state\",\n            ],\n            expect_pass=False,\n        )\n        nodes = set([elem.node.name for elem in state_modified_results])\n        assert nodes == {\n            \"newly_added_error_model\",\n            \"source_unique_test_source_test_table_id\",\n            \"unique_descendant_model_id\",\n            \"not_null_descendant_model_id\",\n            \"source_not_null_test_source_test_table_id\",\n            \"descendant_model\",\n            \"source_relationships_test_source_test_table_favorite_color__favorite_color__ref_descendant_model_\",\n            \"relationships_descendant_model_favorite_color__favorite_color__source_test_source_test_table_\",\n        }\n"
  },
  {
    "path": "tests/functional/sources/test_source_freshness.py",
    "content": "import json\nimport os\nfrom collections import defaultdict\nfrom datetime import datetime, timedelta, timezone\n\nimport pytest\nimport yaml\n\nimport dbt.version\nfrom dbt import deprecations\nfrom dbt.artifacts.schemas.freshness import FreshnessResult\nfrom dbt.artifacts.schemas.results import FreshnessStatus\nfrom dbt.cli.main import dbtRunner\nfrom dbt.tests.util import AnyFloat, AnyStringWith\nfrom tests.functional.sources.common_source_setup import BaseSourcesTest\nfrom tests.functional.sources.fixtures import (\n    collect_freshness_macro_override_previous_return_signature,\n    error_models_model_sql,\n    error_models_schema_yml,\n    filtered_models_schema_yml,\n    freshness_via_custom_sql_config_schema_yml,\n    freshness_via_custom_sql_schema_yml,\n    freshness_via_custom_sql_source_config_schema_yml,\n    freshness_via_metadata_schema_yml,\n    freshness_with_explicit_null_in_source_schema_yml,\n    freshness_with_explicit_null_in_table_schema_yml,\n    override_freshness_models_schema_yml,\n)\n\n\nclass SuccessfulSourceFreshnessTest(BaseSourcesTest):\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project):\n        self.run_dbt_with_vars(project, [\"seed\"])\n        pytest._id = 101\n        pytest.freshness_start_time = datetime.now(timezone.utc).replace(tzinfo=None)\n        # this is the db initial value\n        pytest.last_inserted_time = \"2016-09-19T14:45:51+00:00\"\n\n        os.environ[\"DBT_ENV_CUSTOM_ENV_key\"] = \"value\"\n\n        yield\n\n        del os.environ[\"DBT_ENV_CUSTOM_ENV_key\"]\n\n    def _set_updated_at_to(self, project, delta):\n        insert_time = datetime.now(timezone.utc).replace(tzinfo=None) + delta\n        timestr = insert_time.strftime(\"%Y-%m-%d %H:%M:%S\")\n        # favorite_color,id,first_name,email,ip_address,updated_at\n        insert_id = pytest._id\n        pytest._id += 1\n        quoted_columns = \",\".join(\n            project.adapter.quote(c)\n            for c in (\"favorite_color\", \"id\", \"first_name\", \"email\", \"ip_address\", \"updated_at\")\n        )\n        kwargs = {\n            \"schema\": project.test_schema,\n            \"time\": timestr,\n            \"id\": insert_id,\n            \"source\": project.adapter.quote(\"source\"),\n            \"quoted_columns\": quoted_columns,\n        }\n        raw_code = \"\"\"INSERT INTO {schema}.{source}\n            ({quoted_columns})\n        VALUES (\n            'blue',{id},'Jake','abc@example.com','192.168.1.1','{time}'\n        )\"\"\".format(\n            **kwargs\n        )\n        project.run_sql(raw_code)\n        pytest.last_inserted_time = insert_time.strftime(\"%Y-%m-%dT%H:%M:%S+00:00\")\n\n    def assertBetween(self, timestr, start, end=None):\n        datefmt = \"%Y-%m-%dT%H:%M:%S.%fZ\"\n        if end is None:\n            end = datetime.now(timezone.utc).replace(tzinfo=None)\n\n        parsed = datetime.strptime(timestr, datefmt)\n\n        assert start <= parsed\n        assert end >= parsed\n\n    def _assert_freshness_results(self, path, state):\n        assert os.path.exists(path)\n        with open(path) as fp:\n            data = json.load(fp)\n\n        assert set(data) == {\"metadata\", \"results\", \"elapsed_time\"}\n        assert \"generated_at\" in data[\"metadata\"]\n        assert isinstance(data[\"elapsed_time\"], float)\n        self.assertBetween(data[\"metadata\"][\"generated_at\"], pytest.freshness_start_time)\n        assert (\n            data[\"metadata\"][\"dbt_schema_version\"]\n            == \"https://schemas.getdbt.com/dbt/sources/v3.json\"\n        )\n        assert data[\"metadata\"][\"dbt_version\"] == dbt.version.__version__\n        key = \"key\"\n        if os.name == \"nt\":\n            key = key.upper()\n        assert data[\"metadata\"][\"env\"] == {key: \"value\"}\n\n        last_inserted_time = pytest.last_inserted_time\n\n        assert len(data[\"results\"]) == 1\n\n        # TODO: replace below calls - could they be more sane?\n        assert data[\"results\"] == [\n            {\n                \"unique_id\": \"source.test.test_source.test_table\",\n                \"max_loaded_at\": last_inserted_time,\n                \"snapshotted_at\": AnyStringWith(),\n                \"max_loaded_at_time_ago_in_s\": AnyFloat(),\n                \"status\": state,\n                \"criteria\": {\n                    \"filter\": None,\n                    \"warn_after\": {\"count\": 10, \"period\": \"hour\"},\n                    \"error_after\": {\"count\": 18, \"period\": \"hour\"},\n                },\n                \"adapter_response\": {\"_message\": \"SELECT 1\", \"code\": \"SELECT\", \"rows_affected\": 1},\n                \"thread_id\": AnyStringWith(\"Thread-\"),\n                \"execution_time\": AnyFloat(),\n                \"timing\": [\n                    {\n                        \"name\": \"compile\",\n                        \"started_at\": AnyStringWith(),\n                        \"completed_at\": AnyStringWith(),\n                    },\n                    {\n                        \"name\": \"execute\",\n                        \"started_at\": AnyStringWith(),\n                        \"completed_at\": AnyStringWith(),\n                    },\n                ],\n            }\n        ]\n\n    def _assert_project_hooks_called(self, logs: str):\n        assert \"test.on-run-start.0\" in logs\n        assert \"test.on-run-start.0\" in logs\n\n    def _assert_project_hooks_not_called(self, logs: str):\n        assert \"test.on-run-end.0\" not in logs\n        assert \"test.on-run-end.0\" not in logs\n\n\nclass TestSourceFreshness(SuccessfulSourceFreshnessTest):\n    def test_source_freshness(self, project):\n        # test_source.test_table should have a loaded_at field of `updated_at`\n        # and a freshness of warn_after: 10 hours, error_after: 18 hours\n        # by default, our data set is way out of date!\n\n        results = self.run_dbt_with_vars(\n            project, [\"source\", \"freshness\", \"-o\", \"target/error_source.json\"], expect_pass=False\n        )\n        assert len(results) == 1\n        assert results[0].status == \"error\"\n        self._assert_freshness_results(\"target/error_source.json\", \"error\")\n\n        self._set_updated_at_to(project, timedelta(hours=-12))\n        results = self.run_dbt_with_vars(\n            project,\n            [\"source\", \"freshness\", \"-o\", \"target/warn_source.json\"],\n        )\n        assert len(results) == 1\n        assert results[0].status == \"warn\"\n        self._assert_freshness_results(\"target/warn_source.json\", \"warn\")\n\n        self._set_updated_at_to(project, timedelta(hours=-2))\n        results = self.run_dbt_with_vars(\n            project,\n            [\"source\", \"freshness\", \"-o\", \"target/pass_source.json\"],\n        )\n        assert len(results) == 1\n        assert results[0].status == \"pass\"\n        self._assert_freshness_results(\"target/pass_source.json\", \"pass\")\n\n\nclass TestSourceSnapshotFreshness(SuccessfulSourceFreshnessTest):\n    def test_source_snapshot_freshness(self, project):\n        \"\"\"Ensures that the deprecated command `source snapshot-freshness`\n        aliases to `source freshness` command.\n        \"\"\"\n        results = self.run_dbt_with_vars(\n            project,\n            [\"source\", \"snapshot-freshness\", \"-o\", \"target/error_source.json\"],\n            expect_pass=False,\n        )\n        assert len(results) == 1\n        assert results[0].status == \"error\"\n        self._assert_freshness_results(\"target/error_source.json\", \"error\")\n\n        self._set_updated_at_to(project, timedelta(hours=-12))\n        results = self.run_dbt_with_vars(\n            project,\n            [\"source\", \"snapshot-freshness\", \"-o\", \"target/warn_source.json\"],\n        )\n        assert len(results) == 1\n        assert results[0].status == \"warn\"\n        self._assert_freshness_results(\"target/warn_source.json\", \"warn\")\n\n        self._set_updated_at_to(project, timedelta(hours=-2))\n        results = self.run_dbt_with_vars(\n            project,\n            [\"source\", \"snapshot-freshness\", \"-o\", \"target/pass_source.json\"],\n        )\n        assert len(results) == 1\n        assert results[0].status == \"pass\"\n        self._assert_freshness_results(\"target/pass_source.json\", \"pass\")\n\n\nclass TestSourceFreshnessSelection(SuccessfulSourceFreshnessTest):\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self, logs_dir):\n        return {\n            \"target-path\": logs_dir,\n        }\n\n    def test_source_freshness_selection_select(self, project, logs_dir):\n        \"\"\"Tests node selection using the --select argument.\"\"\"\n        \"\"\"Also validate that specify a target-path works as expected.\"\"\"\n        self._set_updated_at_to(project, timedelta(hours=-2))\n        # select source directly\n        results = self.run_dbt_with_vars(\n            project,\n            [\n                \"source\",\n                \"freshness\",\n                \"--select\",\n                \"source:test_source.test_table\",\n            ],\n        )\n        assert len(results) == 1\n        assert results[0].status == \"pass\"\n        self._assert_freshness_results(f\"{logs_dir}/sources.json\", \"pass\")\n\n\nclass TestSourceFreshnessExclude(SuccessfulSourceFreshnessTest):\n    def test_source_freshness_selection_exclude(self, project):\n        \"\"\"Tests node selection using the --select argument. It 'excludes' the\n        only source in the project so it should return no results.\"\"\"\n        self._set_updated_at_to(project, timedelta(hours=-2))\n        # exclude source directly\n        results = self.run_dbt_with_vars(\n            project,\n            [\n                \"source\",\n                \"freshness\",\n                \"--exclude\",\n                \"source:test_source.test_table\",\n                \"-o\",\n                \"target/exclude_source.json\",\n            ],\n        )\n        assert len(results) == 0\n\n\nclass TestSourceFreshnessGraph(SuccessfulSourceFreshnessTest):\n    def test_source_freshness_selection_graph_operation(self, project):\n        \"\"\"Tests node selection using the --select argument with graph\n        operations. `+descendant_model` == select all nodes `descendant_model`\n        depends on.\n        \"\"\"\n        self._set_updated_at_to(project, timedelta(hours=-2))\n        # select model ancestors\n        results = self.run_dbt_with_vars(\n            project,\n            [\n                \"source\",\n                \"freshness\",\n                \"--select\",\n                \"+descendant_model\",\n                \"-o\",\n                \"target/ancestor_source.json\",\n            ],\n        )\n        assert len(results) == 1\n        assert results[0].status == \"pass\"\n        self._assert_freshness_results(\"target/ancestor_source.json\", \"pass\")\n\n\nclass TestSourceFreshnessErrors(SuccessfulSourceFreshnessTest):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": error_models_schema_yml,\n            \"model.sql\": error_models_model_sql,\n        }\n\n    def test_source_freshness_error(self, project):\n        results = self.run_dbt_with_vars(project, [\"source\", \"freshness\"], expect_pass=False)\n        assert len(results) == 1\n        assert results[0].status == \"runtime error\"\n\n\nclass TestSourceFreshnessFilter(SuccessfulSourceFreshnessTest):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"schema.yml\": filtered_models_schema_yml}\n\n    def test_source_freshness_all_records(self, project):\n        # all records are filtered out\n        self.run_dbt_with_vars(project, [\"source\", \"freshness\"], expect_pass=False)\n        # we should insert a record with _id=101 that's fresh, but will still fail\n        # because the filter excludes it\n        self._set_updated_at_to(project, timedelta(hours=-2))\n        self.run_dbt_with_vars(project, [\"source\", \"freshness\"], expect_pass=False)\n\n        # we should now insert a record with _id=102 that's fresh, and the filter\n        # includes it\n        self._set_updated_at_to(project, timedelta(hours=-2))\n        self.run_dbt_with_vars(project, [\"source\", \"freshness\"], expect_pass=True)\n\n\nclass TestOverrideSourceFreshness(SuccessfulSourceFreshnessTest):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"schema.yml\": override_freshness_models_schema_yml}\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\"sources\": {\"+freshness\": {\"error_after\": {\"count\": 24, \"period\": \"hour\"}}}}\n\n    @staticmethod\n    def get_result_from_unique_id(data, unique_id):\n        try:\n            return list(filter(lambda x: x[\"unique_id\"] == unique_id, data[\"results\"]))[0]\n        except IndexError:\n            raise f\"No result for the given unique_id. unique_id={unique_id}\"\n\n    def test_override_source_freshness(self, project):\n        self._set_updated_at_to(project, timedelta(hours=-30))\n\n        path = \"target/pass_source.json\"\n        results, log_output = self.run_dbt_and_capture_with_vars(\n            project, [\"source\", \"freshness\", \"-o\", path], expect_pass=False\n        )\n        assert len(results) == 4  # freshness disabled for source_e\n        assert \"Found `freshness` as a top-level property of `test_source` in file\"\n\n        assert os.path.exists(path)\n        with open(path) as fp:\n            data = json.load(fp)\n\n        result_source_a = self.get_result_from_unique_id(data, \"source.test.test_source.source_a\")\n        assert result_source_a[\"status\"] == \"error\"\n\n        expected = {\n            \"warn_after\": {\"count\": 6, \"period\": \"hour\"},\n            \"error_after\": {\"count\": 24, \"period\": \"hour\"},\n            \"filter\": None,\n        }\n        assert result_source_a[\"criteria\"] == expected\n\n        result_source_b = self.get_result_from_unique_id(data, \"source.test.test_source.source_b\")\n        assert result_source_b[\"status\"] == \"error\"\n\n        expected = {\n            \"warn_after\": {\"count\": 6, \"period\": \"hour\"},\n            \"error_after\": {\"count\": 24, \"period\": \"hour\"},\n            \"filter\": None,\n        }\n        assert result_source_b[\"criteria\"] == expected\n\n        result_source_c = self.get_result_from_unique_id(data, \"source.test.test_source.source_c\")\n        assert result_source_c[\"status\"] == \"warn\"\n\n        expected = {\n            \"warn_after\": {\"count\": 6, \"period\": \"hour\"},\n            \"error_after\": None,\n            \"filter\": None,\n        }\n        assert result_source_c[\"criteria\"] == expected\n\n        result_source_d = self.get_result_from_unique_id(data, \"source.test.test_source.source_d\")\n        assert result_source_d[\"status\"] == \"warn\"\n\n        expected = {\n            \"warn_after\": {\"count\": 6, \"period\": \"hour\"},\n            \"error_after\": {\"count\": 72, \"period\": \"hour\"},\n            \"filter\": None,\n        }\n        assert result_source_d[\"criteria\"] == expected\n\n\nclass TestSourceFreshnessMacroOverride(SuccessfulSourceFreshnessTest):\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\n            \"collect_freshness.sql\": collect_freshness_macro_override_previous_return_signature\n        }\n\n    def test_source_freshness(self, project):\n        # ensure that the deprecation warning is raised\n        vars_dict = {\n            \"test_run_schema\": project.test_schema,\n            \"test_loaded_at\": project.adapter.quote(\"updated_at\"),\n        }\n        events = []\n        dbtRunner(callbacks=[events.append]).invoke(\n            [\"source\", \"freshness\", \"--vars\", yaml.safe_dump(vars_dict)]\n        )\n        matches = list([e for e in events if e.info.name == \"CollectFreshnessReturnSignature\"])\n        assert matches\n\n\nclass TestMetadataFreshnessFails:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"schema.yml\": freshness_via_metadata_schema_yml}\n\n    def test_metadata_freshness_unsupported_parse_warning(self, project):\n        \"\"\"Since the default test adapter (postgres) does not support metadata\n        based source freshness checks, trying to use that mechanism should\n        result in a parse-time warning.\"\"\"\n        got_warning = False\n\n        def warning_probe(e):\n            nonlocal got_warning\n            if e.info.name == \"FreshnessConfigProblem\" and e.info.level == \"warn\":\n                got_warning = True\n\n        runner = dbtRunner(callbacks=[warning_probe])\n        runner.invoke([\"parse\"])\n\n        assert got_warning\n\n    def test_metadata_freshness_unsupported_error_when_run(self, project):\n\n        runner = dbtRunner()\n        result = runner.invoke([\"source\", \"freshness\"])\n        assert isinstance(result.result, FreshnessResult)\n        assert len(result.result.results) == 1\n        freshness_result = result.result.results[0]\n        assert freshness_result.status == FreshnessStatus.RuntimeErr\n        assert \"Could not compute freshness for source test_table\" in freshness_result.message\n\n\nclass TestSourceFreshnessProjectHooksNotRun(SuccessfulSourceFreshnessTest):\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"config-version\": 2,\n            \"on-run-start\": [\"{{ log('on-run-start hooks called') }}\"],\n            \"on-run-end\": [\"{{ log('on-run-end hooks called') }}\"],\n            \"flags\": {\n                \"source_freshness_run_project_hooks\": False,\n            },\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def global_deprecations(self):\n        deprecations.reset_deprecations()\n        yield\n        deprecations.reset_deprecations()\n\n    def test_hooks_do_run_for_source_freshness(\n        self,\n        project,\n        global_deprecations,\n    ):\n        assert deprecations.active_deprecations == defaultdict(int)\n        _, log_output = self.run_dbt_and_capture_with_vars(\n            project,\n            [\n                \"source\",\n                \"freshness\",\n            ],\n            expect_pass=False,\n        )\n        assert \"on-run-start hooks called\" not in log_output\n        assert \"on-run-end hooks called\" not in log_output\n        assert \"source-freshness-project-hooks\" in deprecations.active_deprecations\n\n\nclass TestHooksInSourceFreshness(SuccessfulSourceFreshnessTest):\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"config-version\": 2,\n            \"on-run-start\": [\"{{ log('on-run-start hooks called') }}\"],\n            \"on-run-end\": [\"{{ log('on-run-end hooks called') }}\"],\n            \"flags\": {\n                \"source_freshness_run_project_hooks\": True,\n            },\n        }\n\n    def test_hooks_do_run_for_source_freshness(\n        self,\n        project,\n    ):\n        _, log_output = self.run_dbt_and_capture_with_vars(\n            project,\n            [\n                \"source\",\n                \"freshness\",\n            ],\n            expect_pass=False,\n        )\n\n        self._assert_project_hooks_called(log_output)\n\n\nclass TestHooksInSourceFreshnessError:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"schema.yml\": error_models_schema_yml,\n            \"model.sql\": error_models_model_sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"config-version\": 2,\n            \"on-run-start\": [\"select fake_column from table_does_not_exist\"],\n            \"flags\": {\n                \"source_freshness_run_project_hooks\": True,\n            },\n        }\n\n    def test_hooks_do_not_run_for_source_freshness(\n        self,\n        project,\n    ):\n        run_result_error = None\n\n        def run_result_error_probe(e):\n            nonlocal run_result_error\n            if (\n                e.info.name == \"RunResultError\"\n                and e.info.level == \"error\"\n                and \"on-run-start\" in e.info.msg\n            ):\n                run_result_error = e.info.msg\n\n        runner = dbtRunner(callbacks=[run_result_error_probe])\n        runner.invoke([\"source\", \"freshness\"])\n        assert 'relation \"table_does_not_exist\" does not exist' in run_result_error\n\n\nclass TestHooksInSourceFreshnessDisabled(SuccessfulSourceFreshnessTest):\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"config-version\": 2,\n            \"on-run-start\": [\"{{ log('on-run-start hooks called') }}\"],\n            \"on-run-end\": [\"{{ log('on-run-end hooks called') }}\"],\n            \"flags\": {\n                \"source_freshness_run_project_hooks\": False,\n            },\n        }\n\n    def test_hooks_do_not_run_for_source_freshness(\n        self,\n        project,\n    ):\n        _, log_output = self.run_dbt_and_capture_with_vars(\n            project,\n            [\n                \"source\",\n                \"freshness\",\n            ],\n            expect_pass=False,\n        )\n        self._assert_project_hooks_not_called(log_output)\n\n\nclass TestHooksInSourceFreshnessDefault(SuccessfulSourceFreshnessTest):\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"config-version\": 2,\n            \"on-run-start\": [\"{{ log('on-run-start hooks called') }}\"],\n            \"on-run-end\": [\"{{ log('on-run-end hooks called') }}\"],\n        }\n\n    def test_hooks_do_not_run_for_source_freshness(\n        self,\n        project,\n    ):\n        _, log_output = self.run_dbt_and_capture_with_vars(\n            project,\n            [\n                \"source\",\n                \"freshness\",\n            ],\n            expect_pass=False,\n        )\n        # default behaviour - hooks are run in source freshness\n        self._assert_project_hooks_called(log_output)\n\n\nclass TestSourceFreshnessCustomSQL(SuccessfulSourceFreshnessTest):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"schema.yml\": freshness_via_custom_sql_schema_yml}\n\n    def test_source_freshness_custom_sql(self, project):\n        result = self.run_dbt_with_vars(project, [\"source\", \"freshness\"], expect_pass=True)\n        # They are the same source but different queries were executed for each\n        assert {r.node.name: r.status for r in result} == {\n            \"source_a\": \"warn\",\n            \"source_b\": \"warn\",\n            \"source_c\": \"pass\",\n        }\n\n\nclass TestSourceFreshnessCustomSQLConfig(TestSourceFreshnessCustomSQL):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"schema.yml\": freshness_via_custom_sql_config_schema_yml}\n\n\nclass TestSourceFreshnessCustomSQLSourceConfig(SuccessfulSourceFreshnessTest):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"schema.yml\": freshness_via_custom_sql_source_config_schema_yml}\n\n    def test_source_freshness_custom_sql(self, project):\n        result = self.run_dbt_with_vars(project, [\"source\", \"freshness\"], expect_pass=True)\n        assert {r.node.name: r.status for r in result} == {\n            \"source_c\": \"pass\",\n        }\n\n\nclass TestSourceFreshnessExplicitNullInTable(SuccessfulSourceFreshnessTest):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"schema.yml\": freshness_with_explicit_null_in_table_schema_yml}\n\n    def test_source_freshness_explicit_null_in_table(self, project):\n        result = self.run_dbt_with_vars(project, [\"source\", \"freshness\"], expect_pass=True)\n        assert {r.node.name: r.status for r in result} == {}\n\n\nclass TestSourceFreshnessExplicitNullInSource(SuccessfulSourceFreshnessTest):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"schema.yml\": freshness_with_explicit_null_in_source_schema_yml}\n\n    def test_source_freshness_explicit_null_in_source(self, project):\n        result = self.run_dbt_with_vars(project, [\"source\", \"freshness\"], expect_pass=True)\n        assert {r.node.name: r.status for r in result} == {}\n"
  },
  {
    "path": "tests/functional/sources/test_source_loaded_at_field.py",
    "content": "import pytest\n\nfrom dbt.exceptions import YamlParseDictError\nfrom dbt.tests.util import get_manifest, run_dbt, write_file\n\nloaded_at_field_null_schema_yml = \"\"\"\nsources:\n  - name: test_source\n    freshness:\n      warn_after:\n        count: 1\n        period: day\n      error_after:\n        count: 4\n        period: day\n    loaded_at_field: updated_at\n    tables:\n      - name: table1\n        loaded_at_field: null\n\"\"\"\n\nloaded_at_field_blank_schema_yml = \"\"\"\nsources:\n  - name: test_source\n    freshness:\n      warn_after:\n        count: 1\n        period: day\n      error_after:\n        count: 4\n        period: day\n    loaded_at_field: updated_at\n    tables:\n      - name: table1\n        loaded_at_field: null\n\"\"\"\n\nloaded_at_field_missing_schema_yml = \"\"\"\nsources:\n  - name: test_source\n    freshness:\n      warn_after:\n        count: 1\n        period: day\n      error_after:\n        count: 4\n        period: day\n    loaded_at_field: updated_at\n    tables:\n      - name: table1\n\"\"\"\n\nloaded_at_field_defined_schema_yml = \"\"\"\nsources:\n  - name: test_source\n    freshness:\n      warn_after:\n        count: 1\n        period: day\n      error_after:\n        count: 4\n        period: day\n    loaded_at_field: updated_at\n    tables:\n      - name: table1\n        loaded_at_field: updated_at_another_place\n\"\"\"\n\nloaded_at_field_empty_string_schema_yml = \"\"\"\nsources:\n  - name: test_source\n    freshness:\n      warn_after:\n        count: 1\n        period: day\n      error_after:\n        count: 4\n        period: day\n    loaded_at_field: updated_at\n    tables:\n      - name: table1\n        loaded_at_field: \"\"\n\"\"\"\n\n\nclass TestParsingLoadedAtField:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"schema.yml\": loaded_at_field_null_schema_yml}\n\n    def test_loaded_at_field(self, project):\n        # test setting loaded_at_field to null explicitly at table level\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n\n        assert \"source.test.test_source.table1\" in manifest.sources\n        assert manifest.sources.get(\"source.test.test_source.table1\").loaded_at_field is None\n\n        # test setting loaded_at_field at source level, do not set at table level\n        # end up with source level loaded_at_field\n        write_file(\n            loaded_at_field_missing_schema_yml, project.project_root, \"models\", \"schema.yml\"\n        )\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n        assert \"source.test.test_source.table1\" in manifest.sources\n        assert (\n            manifest.sources.get(\"source.test.test_source.table1\").loaded_at_field == \"updated_at\"\n        )\n\n        # test setting loaded_at_field to nothing, should override Source value for None\n        write_file(loaded_at_field_blank_schema_yml, project.project_root, \"models\", \"schema.yml\")\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n\n        assert \"source.test.test_source.table1\" in manifest.sources\n        assert manifest.sources.get(\"source.test.test_source.table1\").loaded_at_field is None\n\n        # test setting loaded_at_field at table level to a value - it should override source level\n        write_file(\n            loaded_at_field_defined_schema_yml, project.project_root, \"models\", \"schema.yml\"\n        )\n        run_dbt([\"parse\"])\n        manifest = get_manifest(project.project_root)\n        assert \"source.test.test_source.table1\" in manifest.sources\n        assert (\n            manifest.sources.get(\"source.test.test_source.table1\").loaded_at_field\n            == \"updated_at_another_place\"\n        )\n\n        # test setting loaded_at_field at table level to an empty string - should error\n        write_file(\n            loaded_at_field_empty_string_schema_yml, project.project_root, \"models\", \"schema.yml\"\n        )\n        with pytest.raises(YamlParseDictError):\n            run_dbt([\"parse\"])\n"
  },
  {
    "path": "tests/functional/statements/fixtures.py",
    "content": "#\n# Seeds\n#\nseeds__statement_expected = \"\"\"source,value\nmatrix,100\ntable,100\n\"\"\"\n\nseeds__statement_actual = \"\"\"id,first_name,last_name,email,gender,ip_address\n1,Jack,Hunter,jhunter0@pbs.org,Male,59.80.20.168\n2,Kathryn,Walker,kwalker1@ezinearticles.com,Female,194.121.179.35\n3,Gerald,Ryan,gryan2@com.com,Male,11.3.212.243\n4,Bonnie,Spencer,bspencer3@ameblo.jp,Female,216.32.196.175\n5,Harold,Taylor,htaylor4@people.com.cn,Male,253.10.246.136\n6,Jacqueline,Griffin,jgriffin5@t.co,Female,16.13.192.220\n7,Wanda,Arnold,warnold6@google.nl,Female,232.116.150.64\n8,Craig,Ortiz,cortiz7@sciencedaily.com,Male,199.126.106.13\n9,Gary,Day,gday8@nih.gov,Male,35.81.68.186\n10,Rose,Wright,rwright9@yahoo.co.jp,Female,236.82.178.100\n11,Raymond,Kelley,rkelleya@fc2.com,Male,213.65.166.67\n12,Gerald,Robinson,grobinsonb@disqus.com,Male,72.232.194.193\n13,Mildred,Martinez,mmartinezc@samsung.com,Female,198.29.112.5\n14,Dennis,Arnold,darnoldd@google.com,Male,86.96.3.250\n15,Judy,Gray,jgraye@opensource.org,Female,79.218.162.245\n16,Theresa,Garza,tgarzaf@epa.gov,Female,21.59.100.54\n17,Gerald,Robertson,grobertsong@csmonitor.com,Male,131.134.82.96\n18,Philip,Hernandez,phernandezh@adobe.com,Male,254.196.137.72\n19,Julia,Gonzalez,jgonzalezi@cam.ac.uk,Female,84.240.227.174\n20,Andrew,Davis,adavisj@patch.com,Male,9.255.67.25\n21,Kimberly,Harper,kharperk@foxnews.com,Female,198.208.120.253\n22,Mark,Martin,mmartinl@marketwatch.com,Male,233.138.182.153\n23,Cynthia,Ruiz,cruizm@google.fr,Female,18.178.187.201\n24,Samuel,Carroll,scarrolln@youtu.be,Male,128.113.96.122\n25,Jennifer,Larson,jlarsono@vinaora.com,Female,98.234.85.95\n26,Ashley,Perry,aperryp@rakuten.co.jp,Female,247.173.114.52\n27,Howard,Rodriguez,hrodriguezq@shutterfly.com,Male,231.188.95.26\n28,Amy,Brooks,abrooksr@theatlantic.com,Female,141.199.174.118\n29,Louise,Warren,lwarrens@adobe.com,Female,96.105.158.28\n30,Tina,Watson,twatsont@myspace.com,Female,251.142.118.177\n31,Janice,Kelley,jkelleyu@creativecommons.org,Female,239.167.34.233\n32,Terry,Mccoy,tmccoyv@bravesites.com,Male,117.201.183.203\n33,Jeffrey,Morgan,jmorganw@surveymonkey.com,Male,78.101.78.149\n34,Louis,Harvey,lharveyx@sina.com.cn,Male,51.50.0.167\n35,Philip,Miller,pmillery@samsung.com,Male,103.255.222.110\n36,Willie,Marshall,wmarshallz@ow.ly,Male,149.219.91.68\n37,Patrick,Lopez,plopez10@redcross.org,Male,250.136.229.89\n38,Adam,Jenkins,ajenkins11@harvard.edu,Male,7.36.112.81\n39,Benjamin,Cruz,bcruz12@linkedin.com,Male,32.38.98.15\n40,Ruby,Hawkins,rhawkins13@gmpg.org,Female,135.171.129.255\n41,Carlos,Barnes,cbarnes14@a8.net,Male,240.197.85.140\n42,Ruby,Griffin,rgriffin15@bravesites.com,Female,19.29.135.24\n43,Sean,Mason,smason16@icq.com,Male,159.219.155.249\n44,Anthony,Payne,apayne17@utexas.edu,Male,235.168.199.218\n45,Steve,Cruz,scruz18@pcworld.com,Male,238.201.81.198\n46,Anthony,Garcia,agarcia19@flavors.me,Male,25.85.10.18\n47,Doris,Lopez,dlopez1a@sphinn.com,Female,245.218.51.238\n48,Susan,Nichols,snichols1b@freewebs.com,Female,199.99.9.61\n49,Wanda,Ferguson,wferguson1c@yahoo.co.jp,Female,236.241.135.21\n50,Andrea,Pierce,apierce1d@google.co.uk,Female,132.40.10.209\n51,Lawrence,Phillips,lphillips1e@jugem.jp,Male,72.226.82.87\n52,Judy,Gilbert,jgilbert1f@multiply.com,Female,196.250.15.142\n53,Eric,Williams,ewilliams1g@joomla.org,Male,222.202.73.126\n54,Ralph,Romero,rromero1h@sogou.com,Male,123.184.125.212\n55,Jean,Wilson,jwilson1i@ocn.ne.jp,Female,176.106.32.194\n56,Lori,Reynolds,lreynolds1j@illinois.edu,Female,114.181.203.22\n57,Donald,Moreno,dmoreno1k@bbc.co.uk,Male,233.249.97.60\n58,Steven,Berry,sberry1l@eepurl.com,Male,186.193.50.50\n59,Theresa,Shaw,tshaw1m@people.com.cn,Female,120.37.71.222\n60,John,Stephens,jstephens1n@nationalgeographic.com,Male,191.87.127.115\n61,Richard,Jacobs,rjacobs1o@state.tx.us,Male,66.210.83.155\n62,Andrew,Lawson,alawson1p@over-blog.com,Male,54.98.36.94\n63,Peter,Morgan,pmorgan1q@rambler.ru,Male,14.77.29.106\n64,Nicole,Garrett,ngarrett1r@zimbio.com,Female,21.127.74.68\n65,Joshua,Kim,jkim1s@edublogs.org,Male,57.255.207.41\n66,Ralph,Roberts,rroberts1t@people.com.cn,Male,222.143.131.109\n67,George,Montgomery,gmontgomery1u@smugmug.com,Male,76.75.111.77\n68,Gerald,Alvarez,galvarez1v@flavors.me,Male,58.157.186.194\n69,Donald,Olson,dolson1w@whitehouse.gov,Male,69.65.74.135\n70,Carlos,Morgan,cmorgan1x@pbs.org,Male,96.20.140.87\n71,Aaron,Stanley,astanley1y@webnode.com,Male,163.119.217.44\n72,Virginia,Long,vlong1z@spiegel.de,Female,204.150.194.182\n73,Robert,Berry,rberry20@tripadvisor.com,Male,104.19.48.241\n74,Antonio,Brooks,abrooks21@unesco.org,Male,210.31.7.24\n75,Ruby,Garcia,rgarcia22@ovh.net,Female,233.218.162.214\n76,Jack,Hanson,jhanson23@blogtalkradio.com,Male,31.55.46.199\n77,Kathryn,Nelson,knelson24@walmart.com,Female,14.189.146.41\n78,Jason,Reed,jreed25@printfriendly.com,Male,141.189.89.255\n79,George,Coleman,gcoleman26@people.com.cn,Male,81.189.221.144\n80,Rose,King,rking27@ucoz.com,Female,212.123.168.231\n81,Johnny,Holmes,jholmes28@boston.com,Male,177.3.93.188\n82,Katherine,Gilbert,kgilbert29@altervista.org,Female,199.215.169.61\n83,Joshua,Thomas,jthomas2a@ustream.tv,Male,0.8.205.30\n84,Julie,Perry,jperry2b@opensource.org,Female,60.116.114.192\n85,Richard,Perry,rperry2c@oracle.com,Male,181.125.70.232\n86,Kenneth,Ruiz,kruiz2d@wikimedia.org,Male,189.105.137.109\n87,Jose,Morgan,jmorgan2e@webnode.com,Male,101.134.215.156\n88,Donald,Campbell,dcampbell2f@goo.ne.jp,Male,102.120.215.84\n89,Debra,Collins,dcollins2g@uol.com.br,Female,90.13.153.235\n90,Jesse,Johnson,jjohnson2h@stumbleupon.com,Male,225.178.125.53\n91,Elizabeth,Stone,estone2i@histats.com,Female,123.184.126.221\n92,Angela,Rogers,arogers2j@goodreads.com,Female,98.104.132.187\n93,Emily,Dixon,edixon2k@mlb.com,Female,39.190.75.57\n94,Albert,Scott,ascott2l@tinypic.com,Male,40.209.13.189\n95,Barbara,Peterson,bpeterson2m@ow.ly,Female,75.249.136.180\n96,Adam,Greene,agreene2n@fastcompany.com,Male,184.173.109.144\n97,Earl,Sanders,esanders2o@hc360.com,Male,247.34.90.117\n98,Angela,Brooks,abrooks2p@mtv.com,Female,10.63.249.126\n99,Harold,Foster,hfoster2q@privacy.gov.au,Male,139.214.40.244\n100,Carl,Meyer,cmeyer2r@disqus.com,Male,204.117.7.88\n\"\"\"\n\n#\n# Models\n#\nmodels__statement_actual = \"\"\"\n-- {{ ref('seed') }}\n\n{%- call statement('test_statement', fetch_result=True) -%}\n\n  select\n    count(*) as \"num_records\"\n\n  from {{ ref('seed') }}\n\n{%- endcall -%}\n\n{% set result = load_result('test_statement') %}\n\n{% set res_table = result['table'] %}\n{% set res_matrix = result['data'] %}\n\n{% set matrix_value = res_matrix[0][0] %}\n{% set table_value = res_table[0]['num_records'] %}\n\nselect 'matrix' as source, {{ matrix_value }} as value\nunion all\nselect 'table' as source, {{ table_value }} as value\n\"\"\"\n\nmodels__statement_duplicated_load = \"\"\"\n-- {{ ref('seed') }}\n\n{%- call statement('test_statement', fetch_result=True) -%}\n\n  select\n    count(*) as \"num_records\"\n\n  from {{ ref('seed') }}\n\n{%- endcall -%}\n\n{% set result = load_result('test_statement') %}\n{% set result = load_result('test_statement') %}\n\nselect 1\n\"\"\"\n\nmodels__statement_load_main_twice = \"\"\"\n-- {{ ref('seed') }}\n\n{%- call statement('main', fetch_result=True) -%}\n\n  select\n    count(*) as \"num_records\"\n\n  from {{ ref('seed') }}\n\n{%- endcall -%}\n\n{% set result = load_result('main') %}\n{% set result = load_result('main') %}\n\n{% set res_table = result['table'] %}\n{% set res_matrix = result['data'] %}\n\n{% set matrix_value = res_matrix[0][0] %}\n{% set table_value = res_table[0]['num_records'] %}\n\nselect 'matrix' as source, {{ matrix_value }} as value\nunion all\nselect 'table' as source, {{ table_value }} as value\n\"\"\"\n"
  },
  {
    "path": "tests/functional/statements/test_statements.py",
    "content": "import pathlib\n\nimport pytest\n\nfrom dbt.tests.util import check_relations_equal, run_dbt, write_file\nfrom tests.functional.statements.fixtures import (\n    models__statement_actual,\n    models__statement_duplicated_load,\n    models__statement_load_main_twice,\n    seeds__statement_actual,\n    seeds__statement_expected,\n)\n\n\nclass TestStatements:\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project):\n        # put seeds in 'seed' not 'seeds' directory\n        (pathlib.Path(project.project_root) / \"seed\").mkdir(parents=True, exist_ok=True)\n        write_file(seeds__statement_actual, project.project_root, \"seed\", \"seed.csv\")\n        write_file(\n            seeds__statement_expected, project.project_root, \"seed\", \"statement_expected.csv\"\n        )\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"statement_actual.sql\": models__statement_actual,\n            \"statement_duplicated_load.sql\": models__statement_duplicated_load,\n            \"statement_load_main_twice.sql\": models__statement_load_main_twice,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\n            \"seeds\": {\n                \"quote_columns\": False,\n            },\n            \"seed-paths\": [\"seed\"],\n        }\n\n    def test_postgres_statements(self, project):\n        results = run_dbt([\"seed\"])\n        assert len(results) == 2\n        results = run_dbt([\"run\", \"-m\", \"statement_actual\"])\n        assert len(results) == 1\n\n        check_relations_equal(project.adapter, [\"statement_actual\", \"statement_expected\"])\n\n    def test_duplicated_load_statements(self, project):\n        run_dbt([\"seed\"])\n        results = run_dbt([\"run\", \"-m\", \"statement_duplicated_load\"], False)\n        assert len(results) == 1\n        assert results.results[0].status == \"error\"\n        assert (\n            \"The 'statement' result named 'test_statement' has already been loaded into a variable\"\n            in results.results[0].message\n        )\n\n    def test_load_statement_on_main_twice(self, project):\n        run_dbt([\"seed\"])\n        results = run_dbt([\"run\", \"-m\", \"statement_load_main_twice\"])\n        assert len(results) == 1\n        check_relations_equal(project.adapter, [\"statement_load_main_twice\", \"statement_expected\"])\n"
  },
  {
    "path": "tests/functional/test_empty.py",
    "content": "import pytest\n\nfrom dbt.tests.util import relation_from_name, run_dbt\n\nmodel_input_sql = \"\"\"\nselect 1 as id\n\"\"\"\n\nephemeral_model_input_sql = \"\"\"\n{{ config(materialized='ephemeral') }}\nselect 2 as id\n\"\"\"\n\nraw_source_csv = \"\"\"id\n3\n\"\"\"\n\n\nmodel_sql = \"\"\"\nselect *\nfrom {{ ref('model_input') }}\nunion all\nselect *\nfrom {{ ref('ephemeral_model_input') }}\nunion all\nselect *\nfrom {{ source('seed_sources', 'raw_source') }}\n\"\"\"\n\nmodel_no_ephemeral_ref_sql = \"\"\"\nselect *\nfrom {{ ref('model_input') }}\nunion all\nselect *\nfrom {{ source('seed_sources', 'raw_source') }}\n\"\"\"\n\n\nschema_sources_yml = \"\"\"\nsources:\n  - name: seed_sources\n    schema: \"{{ target.schema }}\"\n    tables:\n      - name: raw_source\n\"\"\"\n\nunit_tests_yml = \"\"\"\nunit_tests:\n  - name: test_my_model\n    model: model_no_ephemeral_ref\n    given:\n      - input: ref('model_input')\n        format: csv\n        rows: |\n          id\n          1\n      - input: source('seed_sources', 'raw_source')\n        format: csv\n        rows: |\n          id\n          2\n    expect:\n      format: csv\n      rows: |\n        id\n        1\n        2\n\"\"\"\n\n\nclass TestEmptyFlag:\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\n            \"raw_source.csv\": raw_source_csv,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_input.sql\": model_input_sql,\n            \"ephemeral_model_input.sql\": ephemeral_model_input_sql,\n            \"model.sql\": model_sql,\n            \"model_no_ephemeral_ref.sql\": model_no_ephemeral_ref_sql,\n            \"sources.yml\": schema_sources_yml,\n            \"unit_tests.yml\": unit_tests_yml,\n        }\n\n    def assert_row_count(self, project, relation_name: str, expected_row_count: int):\n        relation = relation_from_name(project.adapter, relation_name)\n        result = project.run_sql(f\"select count(*) as num_rows from {relation}\", fetch=\"one\")\n        assert result[0] == expected_row_count\n\n    def test_run_with_empty(self, project):\n        # create source from seed\n        run_dbt([\"seed\"])\n\n        # run without empty - 3 expected rows in output - 1 from each input\n        run_dbt([\"run\"])\n        self.assert_row_count(project, \"model\", 3)\n\n        # run with empty - 0 expected rows in output\n        run_dbt([\"run\", \"--empty\"])\n        self.assert_row_count(project, \"model\", 0)\n\n        # build without empty - 3 expected rows in output - 1 from each input\n        run_dbt([\"build\"])\n        self.assert_row_count(project, \"model\", 3)\n\n        # build with empty - 0 expected rows in output\n        run_dbt([\"build\", \"--empty\"])\n        self.assert_row_count(project, \"model\", 0)\n\n        # ensure dbt compile supports --empty flag\n        run_dbt([\"compile\", \"--empty\"])\n"
  },
  {
    "path": "tests/functional/test_project.py",
    "content": "from unittest import mock\n\nimport yaml\nfrom pytest_mock import MockerFixture\n\nfrom dbt.deprecations import (\n    GenericJSONSchemaValidationDeprecation as GenericJSONSchemaValidationDeprecationCore,\n)\nfrom dbt.events.types import GenericJSONSchemaValidationDeprecation\nfrom dbt.tests.util import run_dbt, write_file\nfrom dbt_common.events.event_catcher import EventCatcher\nfrom dbt_common.events.types import Note\n\n\nclass TestProjectJsonschemaValidatedOnlyOnce:\n    \"\"\"Ensure that the dbt_project.yml file is validated only once, even if it is 'loaded' multiple times\"\"\"\n\n    def test_project(self, project, mocker: MockerFixture) -> None:\n        mocked_jsonschema_validate = mocker.patch(\n            \"dbt.jsonschemas.jsonschemas.jsonschema_validate\"\n        )\n        run_dbt([\"parse\"])\n        assert mocked_jsonschema_validate.call_count == 1\n\n\n@mock.patch(\"dbt.jsonschemas.jsonschemas._JSONSCHEMA_SUPPORTED_ADAPTERS\", {\"postgres\"})\nclass TestGenericJsonSchemaValidationDeprecation:\n    \"\"\"Ensure that the generic jsonschema validation deprecation can be fired\"\"\"\n\n    def test_project(self, project, project_root: str) -> None:\n\n        # `name` was already required prior to this deprecation, so this deprecation doesn't\n        # really add anything. However, this test shows that jsonschema validation issues raise\n        # deprecation warnings via the catchall `GenericJSONSchemaValidationDeprecation`\n        project_missing_name = {\n            \"profile\": \"test\",\n            \"flags\": {\"send_anonymous_usage_stats\": False},\n        }\n        write_file(yaml.safe_dump(project_missing_name), project_root, \"dbt_project.yml\")\n        event_catcher = EventCatcher(GenericJSONSchemaValidationDeprecation)\n        note_catcher = EventCatcher(Note)\n\n        try:\n            run_dbt(\n                [\"parse\"], callbacks=[event_catcher.catch, note_catcher.catch], expect_pass=False\n            )\n        except:  # noqa: E722\n            pass\n\n        if GenericJSONSchemaValidationDeprecationCore()._is_preview:\n            assert len(note_catcher.caught_events) == 1\n            assert len(event_catcher.caught_events) == 0\n            event = note_catcher.caught_events[0]\n        else:\n            assert len(event_catcher.caught_events) == 1\n            assert len(note_catcher.caught_events) == 0\n            event = event_catcher.caught_events[0]\n\n        assert \"'name' is a required property at top level\" in event.info.msg\n"
  },
  {
    "path": "tests/functional/test_selection/fixtures.py",
    "content": "import pytest\n\ntests__cf_a_b_sql = \"\"\"\nselect * from {{ ref('model_a') }}\ncross join {{ ref('model_b') }}\nwhere false\n\"\"\"\n\ntests__cf_a_src_sql = \"\"\"\nselect * from {{ ref('model_a') }}\ncross join {{ source('my_src', 'my_tbl') }}\nwhere false\n\"\"\"\n\ntests__just_a_sql = \"\"\"\n{{ config(tags = ['data_test_tag']) }}\n\nselect * from {{ ref('model_a') }}\nwhere false\n\"\"\"\n\nmodels__schema_yml = \"\"\"\nversion: 2\n\nsources:\n  - name: my_src\n    schema: \"{{ target.schema }}\"\n    tables:\n      - name: my_tbl\n        identifier: model_b\n        columns:\n          - name: fun\n            config:\n              tags: [source_column_config_tag]\n            data_tests:\n              - unique\n          - name: fun_2\n            config:\n              tags: [source_column_config_tag]\n            data_tests:\n              - unique\n\nmodels:\n  - name: model_a\n    columns:\n      - name: fun\n        tags: [column_level_tag]\n        config:\n          tags: [column_config_level_tag]\n        data_tests:\n          - unique\n          - relationships:\n              to: ref('model_b')\n              field: fun\n              tags: [test_level_tag]\n          - relationships:\n              to: source('my_src', 'my_tbl')\n              field: fun\n      - name: fun_2\n        tags: [column_level_tag]\n        config:\n          tags: column_config_level_tag\n        data_tests:\n          - unique\n\"\"\"\n\nmodels__model_b_sql = \"\"\"\n{{ config(\n    tags = ['a_or_b']\n) }}\n\nselect 1 as fun, 2 as fun_2\n\"\"\"\n\nmodels__model_a_sql = \"\"\"\n{{ config(\n    tags = ['a_or_b']\n) }}\n\nselect * FROM {{ref('model_b')}}\n\"\"\"\n\n\n@pytest.fixture(scope=\"class\")\ndef tests():\n    return {\n        \"cf_a_b.sql\": tests__cf_a_b_sql,\n        \"cf_a_src.sql\": tests__cf_a_src_sql,\n        \"just_a.sql\": tests__just_a_sql,\n    }\n\n\n@pytest.fixture(scope=\"class\")\ndef models():\n    return {\n        \"schema.yml\": models__schema_yml,\n        \"model_b.sql\": models__model_b_sql,\n        \"model_a.sql\": models__model_a_sql,\n    }\n"
  },
  {
    "path": "tests/functional/test_selection/test_selection_expansion.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt\nfrom tests.functional.test_selection.fixtures import models, tests  # noqa: F401\n\n\nclass TestSelectionExpansion:\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\"config-version\": 2, \"test-paths\": [\"tests\"]}\n\n    def list_tests_and_assert(\n        self,\n        include,\n        exclude,\n        expected_tests,\n        indirect_selection=\"eager\",\n        selector_name=None,\n    ):\n        list_args = [\"ls\", \"--resource-type\", \"test\"]\n        if include:\n            list_args.extend((\"--select\", include))\n        if exclude:\n            list_args.extend((\"--exclude\", exclude))\n        if indirect_selection:\n            list_args.extend((\"--indirect-selection\", indirect_selection))\n        if selector_name:\n            list_args.extend((\"--selector\", selector_name))\n\n        listed = run_dbt(list_args)\n        assert len(listed) == len(expected_tests)\n\n        test_names = [name.split(\".\")[-1] for name in listed]\n        assert sorted(test_names) == sorted(expected_tests)\n\n    def run_tests_and_assert(\n        self,\n        include,\n        exclude,\n        expected_tests,\n        indirect_selection=\"eager\",\n        selector_name=None,\n    ):\n        results = run_dbt([\"run\"])\n        assert len(results) == 2\n\n        test_args = [\"test\"]\n        if include:\n            test_args.extend((\"--models\", include))\n        if exclude:\n            test_args.extend((\"--exclude\", exclude))\n        if indirect_selection:\n            test_args.extend((\"--indirect-selection\", indirect_selection))\n        if selector_name:\n            test_args.extend((\"--selector\", selector_name))\n\n        results = run_dbt(test_args)\n        tests_run = [r.node.name for r in results]\n        assert len(tests_run) == len(expected_tests)\n\n        assert sorted(tests_run) == sorted(expected_tests)\n\n    def test_all_tests_no_specifiers(\n        self,\n        project,\n    ):\n        select = None\n        exclude = None\n        expected = [\n            \"cf_a_b\",\n            \"cf_a_src\",\n            \"just_a\",\n            \"relationships_model_a_fun__fun__ref_model_b_\",\n            \"relationships_model_a_fun__fun__source_my_src_my_tbl_\",\n            \"source_unique_my_src_my_tbl_fun\",\n            \"source_unique_my_src_my_tbl_fun_2\",\n            \"unique_model_a_fun\",\n            \"unique_model_a_fun_2\",\n        ]\n\n        self.list_tests_and_assert(select, exclude, expected)\n        self.run_tests_and_assert(select, exclude, expected)\n\n    def test_model_a_alone(\n        self,\n        project,\n    ):\n        select = \"model_a\"\n        exclude = None\n        expected = [\n            \"cf_a_b\",\n            \"cf_a_src\",\n            \"just_a\",\n            \"relationships_model_a_fun__fun__ref_model_b_\",\n            \"relationships_model_a_fun__fun__source_my_src_my_tbl_\",\n            \"unique_model_a_fun\",\n            \"unique_model_a_fun_2\",\n        ]\n\n        self.list_tests_and_assert(select, exclude, expected)\n        self.run_tests_and_assert(select, exclude, expected)\n\n    def test_model_a_model_b(\n        self,\n        project,\n    ):\n        select = \"model_a model_b\"\n        exclude = None\n        expected = [\n            \"cf_a_b\",\n            \"cf_a_src\",\n            \"just_a\",\n            \"unique_model_a_fun\",\n            \"unique_model_a_fun_2\",\n            \"relationships_model_a_fun__fun__ref_model_b_\",\n            \"relationships_model_a_fun__fun__source_my_src_my_tbl_\",\n        ]\n\n        self.list_tests_and_assert(select, exclude, expected)\n        self.run_tests_and_assert(select, exclude, expected)\n\n    def test_model_a_sources(\n        self,\n        project,\n    ):\n        select = \"model_a source:*\"\n        exclude = None\n        expected = [\n            \"cf_a_b\",\n            \"cf_a_src\",\n            \"just_a\",\n            \"unique_model_a_fun\",\n            \"unique_model_a_fun_2\",\n            \"source_unique_my_src_my_tbl_fun\",\n            \"source_unique_my_src_my_tbl_fun_2\",\n            \"relationships_model_a_fun__fun__ref_model_b_\",\n            \"relationships_model_a_fun__fun__source_my_src_my_tbl_\",\n        ]\n\n        self.list_tests_and_assert(select, exclude, expected)\n        self.run_tests_and_assert(select, exclude, expected)\n\n    def test_exclude_model_b(\n        self,\n        project,\n    ):\n        select = None\n        exclude = \"model_b\"\n        expected = [\n            \"cf_a_src\",\n            \"just_a\",\n            \"relationships_model_a_fun__fun__source_my_src_my_tbl_\",\n            \"source_unique_my_src_my_tbl_fun\",\n            \"source_unique_my_src_my_tbl_fun_2\",\n            \"unique_model_a_fun\",\n            \"unique_model_a_fun_2\",\n        ]\n\n        self.list_tests_and_assert(select, exclude, expected)\n        self.run_tests_and_assert(select, exclude, expected)\n\n    def test_model_a_exclude_specific_test(\n        self,\n        project,\n    ):\n        select = \"model_a\"\n        exclude = \"unique_model_a_fun\"\n        expected = [\n            \"cf_a_b\",\n            \"cf_a_src\",\n            \"just_a\",\n            \"relationships_model_a_fun__fun__ref_model_b_\",\n            \"relationships_model_a_fun__fun__source_my_src_my_tbl_\",\n            \"unique_model_a_fun_2\",\n        ]\n\n        self.list_tests_and_assert(select, exclude, expected)\n        self.run_tests_and_assert(select, exclude, expected)\n\n    def test_model_a_exclude_specific_test_cautious(\n        self,\n        project,\n    ):\n        select = \"model_a\"\n        exclude = \"unique_model_a_fun\"\n        expected = [\"just_a\", \"unique_model_a_fun_2\"]\n        indirect_selection = \"cautious\"\n\n        self.list_tests_and_assert(select, exclude, expected, indirect_selection)\n        self.run_tests_and_assert(select, exclude, expected, indirect_selection)\n\n    def test_model_a_exclude_specific_test_buildable(\n        self,\n        project,\n    ):\n        select = \"model_a\"\n        exclude = \"unique_model_a_fun\"\n        expected = [\n            \"just_a\",\n            \"cf_a_b\",\n            \"cf_a_src\",\n            \"relationships_model_a_fun__fun__ref_model_b_\",\n            \"relationships_model_a_fun__fun__source_my_src_my_tbl_\",\n            \"unique_model_a_fun_2\",\n        ]\n        indirect_selection = \"buildable\"\n\n        self.list_tests_and_assert(select, exclude, expected, indirect_selection)\n        self.run_tests_and_assert(select, exclude, expected, indirect_selection)\n\n    def test_only_generic(\n        self,\n        project,\n    ):\n        select = \"test_type:generic\"\n        exclude = None\n        expected = [\n            \"relationships_model_a_fun__fun__ref_model_b_\",\n            \"relationships_model_a_fun__fun__source_my_src_my_tbl_\",\n            \"source_unique_my_src_my_tbl_fun\",\n            \"source_unique_my_src_my_tbl_fun_2\",\n            \"unique_model_a_fun\",\n            \"unique_model_a_fun_2\",\n        ]\n\n        self.list_tests_and_assert(select, exclude, expected)\n        self.run_tests_and_assert(select, exclude, expected)\n\n    def test_model_a_only_singular_unset(\n        self,\n        project,\n    ):\n        select = \"model_a,test_type:singular\"\n        exclude = None\n        expected = [\"cf_a_b\", \"cf_a_src\", \"just_a\"]\n\n        self.list_tests_and_assert(select, exclude, expected)\n        self.run_tests_and_assert(select, exclude, expected)\n\n    def test_model_a_only_singular_eager(\n        self,\n        project,\n    ):\n        select = \"model_a,test_type:singular\"\n        exclude = None\n        expected = [\"cf_a_b\", \"cf_a_src\", \"just_a\"]\n\n        self.list_tests_and_assert(select, exclude, expected)\n        self.run_tests_and_assert(select, exclude, expected)\n\n    def test_model_a_only_singular_cautious(\n        self,\n        project,\n    ):\n        select = \"model_a,test_type:singular\"\n        exclude = None\n        expected = [\"just_a\"]\n        indirect_selection = \"cautious\"\n\n        self.list_tests_and_assert(\n            select, exclude, expected, indirect_selection=indirect_selection\n        )\n        self.run_tests_and_assert(select, exclude, expected, indirect_selection=indirect_selection)\n\n    def test_only_singular(\n        self,\n        project,\n    ):\n        select = \"test_type:singular\"\n        exclude = None\n        expected = [\"cf_a_b\", \"cf_a_src\", \"just_a\"]\n\n        self.list_tests_and_assert(select, exclude, expected)\n        self.run_tests_and_assert(select, exclude, expected)\n\n    def test_model_a_only_singular(\n        self,\n        project,\n    ):\n        select = \"model_a,test_type:singular\"\n        exclude = None\n        expected = [\"cf_a_b\", \"cf_a_src\", \"just_a\"]\n\n        self.list_tests_and_assert(select, exclude, expected)\n        self.run_tests_and_assert(select, exclude, expected)\n\n    def test_test_name_intersection(\n        self,\n        project,\n    ):\n        select = \"model_a,test_name:unique\"\n        exclude = None\n        expected = [\"unique_model_a_fun\", \"unique_model_a_fun_2\"]\n\n        self.list_tests_and_assert(select, exclude, expected)\n        self.run_tests_and_assert(select, exclude, expected)\n\n    def test_model_tag_test_name_intersection(\n        self,\n        project,\n    ):\n        select = \"tag:a_or_b,test_name:relationships\"\n        exclude = None\n        expected = [\n            \"relationships_model_a_fun__fun__ref_model_b_\",\n            \"relationships_model_a_fun__fun__source_my_src_my_tbl_\",\n        ]\n\n        self.list_tests_and_assert(select, exclude, expected)\n        self.run_tests_and_assert(select, exclude, expected)\n\n    def test_select_column_level_tag(\n        self,\n        project,\n    ):\n        select = \"tag:column_level_tag\"\n        exclude = None\n        expected = [\n            \"relationships_model_a_fun__fun__ref_model_b_\",\n            \"relationships_model_a_fun__fun__source_my_src_my_tbl_\",\n            \"unique_model_a_fun\",\n            \"unique_model_a_fun_2\",\n        ]\n\n        self.list_tests_and_assert(select, exclude, expected)\n        self.run_tests_and_assert(select, exclude, expected)\n\n    def test_exclude_column_level_tag(\n        self,\n        project,\n    ):\n        select = None\n        exclude = \"tag:column_level_tag\"\n        expected = [\n            \"cf_a_b\",\n            \"cf_a_src\",\n            \"just_a\",\n            \"source_unique_my_src_my_tbl_fun\",\n            \"source_unique_my_src_my_tbl_fun_2\",\n        ]\n\n        self.list_tests_and_assert(select, exclude, expected)\n        self.run_tests_and_assert(select, exclude, expected)\n\n    def test_select_column_config_level_tag(\n        self,\n        project,\n    ):\n        select = \"tag:column_config_level_tag\"\n        exclude = None\n        expected = [\n            \"relationships_model_a_fun__fun__ref_model_b_\",\n            \"relationships_model_a_fun__fun__source_my_src_my_tbl_\",\n            \"unique_model_a_fun\",\n            \"unique_model_a_fun_2\",\n        ]\n\n        self.list_tests_and_assert(select, exclude, expected)\n        self.run_tests_and_assert(select, exclude, expected)\n\n    def test_select_source_column_config_level_tag(\n        self,\n        project,\n    ):\n        select = \"tag:source_column_config_tag\"\n        exclude = None\n        expected = [\n            \"source_unique_my_src_my_tbl_fun\",\n            \"source_unique_my_src_my_tbl_fun_2\",\n        ]\n\n        self.list_tests_and_assert(select, exclude, expected)\n        self.run_tests_and_assert(select, exclude, expected)\n\n    def test_exclude_column_config_level_tag(\n        self,\n        project,\n    ):\n        select = None\n        exclude = \"tag:column_config_level_tag\"\n        expected = [\n            \"cf_a_b\",\n            \"cf_a_src\",\n            \"just_a\",\n            \"source_unique_my_src_my_tbl_fun\",\n            \"source_unique_my_src_my_tbl_fun_2\",\n        ]\n\n        self.list_tests_and_assert(select, exclude, expected)\n        self.run_tests_and_assert(select, exclude, expected)\n\n    def test_test_level_tag(\n        self,\n        project,\n    ):\n        select = \"tag:test_level_tag\"\n        exclude = None\n        expected = [\"relationships_model_a_fun__fun__ref_model_b_\"]\n\n        self.list_tests_and_assert(select, exclude, expected)\n        self.run_tests_and_assert(select, exclude, expected)\n\n    def test_exclude_data_test_tag(\n        self,\n        project,\n    ):\n        select = \"model_a\"\n        exclude = \"tag:data_test_tag\"\n        expected = [\n            \"cf_a_b\",\n            \"cf_a_src\",\n            \"relationships_model_a_fun__fun__ref_model_b_\",\n            \"relationships_model_a_fun__fun__source_my_src_my_tbl_\",\n            \"unique_model_a_fun\",\n            \"unique_model_a_fun_2\",\n        ]\n\n        self.list_tests_and_assert(select, exclude, expected)\n        self.run_tests_and_assert(select, exclude, expected)\n\n    def test_model_a_indirect_selection(\n        self,\n        project,\n    ):\n        select = \"model_a\"\n        exclude = None\n        expected = [\n            \"cf_a_b\",\n            \"cf_a_src\",\n            \"just_a\",\n            \"relationships_model_a_fun__fun__ref_model_b_\",\n            \"relationships_model_a_fun__fun__source_my_src_my_tbl_\",\n            \"unique_model_a_fun\",\n            \"unique_model_a_fun_2\",\n        ]\n\n        self.list_tests_and_assert(select, exclude, expected)\n        self.run_tests_and_assert(select, exclude, expected)\n\n    def test_model_a_indirect_selection_eager(\n        self,\n        project,\n    ):\n        select = \"model_a\"\n        exclude = None\n        expected = [\n            \"cf_a_b\",\n            \"cf_a_src\",\n            \"just_a\",\n            \"relationships_model_a_fun__fun__ref_model_b_\",\n            \"relationships_model_a_fun__fun__source_my_src_my_tbl_\",\n            \"unique_model_a_fun\",\n            \"unique_model_a_fun_2\",\n        ]\n        indirect_selection = \"eager\"\n\n        self.list_tests_and_assert(select, exclude, expected, indirect_selection)\n        self.run_tests_and_assert(select, exclude, expected, indirect_selection)\n\n    def test_model_a_indirect_selection_cautious(\n        self,\n        project,\n    ):\n        select = \"model_a\"\n        exclude = None\n        expected = [\n            \"just_a\",\n            \"unique_model_a_fun\",\n            \"unique_model_a_fun_2\",\n        ]\n        indirect_selection = \"cautious\"\n\n        self.list_tests_and_assert(select, exclude, expected, indirect_selection)\n        self.run_tests_and_assert(select, exclude, expected, indirect_selection)\n\n    def test_model_a_indirect_selection_buildable(\n        self,\n        project,\n    ):\n        select = \"model_a\"\n        exclude = None\n        expected = [\n            \"cf_a_b\",\n            \"cf_a_src\",\n            \"just_a\",\n            \"relationships_model_a_fun__fun__ref_model_b_\",\n            \"relationships_model_a_fun__fun__source_my_src_my_tbl_\",\n            \"unique_model_a_fun\",\n            \"unique_model_a_fun_2\",\n        ]\n        indirect_selection = \"buildable\"\n\n        self.list_tests_and_assert(select, exclude, expected, indirect_selection)\n        self.run_tests_and_assert(select, exclude, expected, indirect_selection)\n\n    def test_model_a_indirect_selection_exclude_unique_tests(\n        self,\n        project,\n    ):\n        select = \"model_a\"\n        exclude = \"test_name:unique\"\n        indirect_selection = \"eager\"\n        expected = [\n            \"cf_a_b\",\n            \"cf_a_src\",\n            \"just_a\",\n            \"relationships_model_a_fun__fun__ref_model_b_\",\n            \"relationships_model_a_fun__fun__source_my_src_my_tbl_\",\n        ]\n\n        self.list_tests_and_assert(select, exclude, expected, indirect_selection)\n        self.run_tests_and_assert(select, exclude, expected, indirect_selection=indirect_selection)\n\n    def test_model_a_indirect_selection_empty(self, project):\n        results = run_dbt([\"ls\", \"--indirect-selection\", \"empty\", \"--select\", \"model_a\"])\n        assert len(results) == 1\n\n\nclass TestExpansionWithSelectors(TestSelectionExpansion):\n    @pytest.fixture(scope=\"class\")\n    def selectors(self):\n        return \"\"\"\n            selectors:\n            - name: model_a_unset_indirect_selection\n              definition:\n                method: fqn\n                value: model_a\n            - name: model_a_cautious_indirect_selection\n              definition:\n                method: fqn\n                value: model_a\n                indirect_selection: \"cautious\"\n            - name: model_a_eager_indirect_selection\n              definition:\n                method: fqn\n                value: model_a\n                indirect_selection: \"eager\"\n            - name: model_a_buildable_indirect_selection\n              definition:\n                method: fqn\n                value: model_a\n                indirect_selection: \"buildable\"\n        \"\"\"\n\n    def test_selector_model_a_unset_indirect_selection(\n        self,\n        project,\n    ):\n        expected = [\n            \"cf_a_b\",\n            \"cf_a_src\",\n            \"just_a\",\n            \"relationships_model_a_fun__fun__ref_model_b_\",\n            \"relationships_model_a_fun__fun__source_my_src_my_tbl_\",\n            \"unique_model_a_fun\",\n            \"unique_model_a_fun_2\",\n        ]\n\n        self.list_tests_and_assert(\n            include=None,\n            exclude=None,\n            expected_tests=expected,\n            selector_name=\"model_a_unset_indirect_selection\",\n        )\n        self.run_tests_and_assert(\n            include=None,\n            exclude=None,\n            expected_tests=expected,\n            selector_name=\"model_a_unset_indirect_selection\",\n        )\n\n    def test_selector_model_a_cautious_indirect_selection(\n        self,\n        project,\n    ):\n        expected = [\"just_a\", \"unique_model_a_fun\", \"unique_model_a_fun_2\"]\n\n        self.list_tests_and_assert(\n            include=None,\n            exclude=None,\n            expected_tests=expected,\n            selector_name=\"model_a_cautious_indirect_selection\",\n        )\n        self.run_tests_and_assert(\n            include=None,\n            exclude=None,\n            expected_tests=expected,\n            selector_name=\"model_a_cautious_indirect_selection\",\n        )\n\n    def test_selector_model_a_eager_indirect_selection(\n        self,\n        project,\n    ):\n        expected = [\n            \"cf_a_b\",\n            \"cf_a_src\",\n            \"just_a\",\n            \"relationships_model_a_fun__fun__ref_model_b_\",\n            \"relationships_model_a_fun__fun__source_my_src_my_tbl_\",\n            \"unique_model_a_fun\",\n            \"unique_model_a_fun_2\",\n        ]\n\n        self.list_tests_and_assert(\n            include=None,\n            exclude=None,\n            expected_tests=expected,\n            selector_name=\"model_a_eager_indirect_selection\",\n        )\n        self.run_tests_and_assert(\n            include=None,\n            exclude=None,\n            expected_tests=expected,\n            selector_name=\"model_a_eager_indirect_selection\",\n        )\n\n    def test_selector_model_a_buildable_indirect_selection(\n        self,\n        project,\n    ):\n        expected = [\n            \"cf_a_b\",\n            \"cf_a_src\",\n            \"just_a\",\n            \"relationships_model_a_fun__fun__ref_model_b_\",\n            \"relationships_model_a_fun__fun__source_my_src_my_tbl_\",\n            \"unique_model_a_fun\",\n            \"unique_model_a_fun_2\",\n        ]\n\n        self.list_tests_and_assert(\n            include=None,\n            exclude=None,\n            expected_tests=expected,\n            selector_name=\"model_a_buildable_indirect_selection\",\n        )\n        self.run_tests_and_assert(\n            include=None,\n            exclude=None,\n            expected_tests=expected,\n            selector_name=\"model_a_buildable_indirect_selection\",\n        )\n"
  },
  {
    "path": "tests/functional/test_singular_tests.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt\n\nsingle_test_sql = \"\"\"\n{{ config(warn_if = '>0', error_if =\"> 10\") }}\n\nselect 1 as issue\n\"\"\"\n\n\nclass TestSingularTestWarnError:\n    @pytest.fixture(scope=\"class\")\n    def tests(self):\n        return {\"single_test.sql\": single_test_sql}\n\n    def test_singular_test_warn_error(self, project):\n        results = run_dbt([\"--warn-error\", \"test\"], expect_pass=False)\n        assert results.results[0].status == \"fail\"\n\n    def test_singular_test_warn_error_options(self, project):\n        results = run_dbt([\"--warn-error-options\", \"{'error': 'all'}\", \"test\"], expect_pass=False)\n        assert results.results[0].status == \"fail\"\n\n    def test_singular_test_equals_warn_error(self, project):\n        results = run_dbt([\"--warn-error\", \"test\"], expect_pass=False)\n        warn_error_result = results.results[0].status\n\n        results = run_dbt([\"--warn-error-options\", \"{'error': 'all'}\", \"test\"], expect_pass=False)\n        assert warn_error_result == results.results[0].status\n"
  },
  {
    "path": "tests/functional/threading/test_thread_count.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt\n\nmodels__do_nothing__sql = \"\"\"\nwith x as (select pg_sleep(1)) select 1\n\"\"\"\n\n\nclass TestThreadCount:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"do_nothing_1.sql\": models__do_nothing__sql,\n            \"do_nothing_2.sql\": models__do_nothing__sql,\n            \"do_nothing_3.sql\": models__do_nothing__sql,\n            \"do_nothing_4.sql\": models__do_nothing__sql,\n            \"do_nothing_5.sql\": models__do_nothing__sql,\n            \"do_nothing_6.sql\": models__do_nothing__sql,\n            \"do_nothing_7.sql\": models__do_nothing__sql,\n            \"do_nothing_8.sql\": models__do_nothing__sql,\n            \"do_nothing_9.sql\": models__do_nothing__sql,\n            \"do_nothing_10.sql\": models__do_nothing__sql,\n            \"do_nothing_11.sql\": models__do_nothing__sql,\n            \"do_nothing_12.sql\": models__do_nothing__sql,\n            \"do_nothing_13.sql\": models__do_nothing__sql,\n            \"do_nothing_14.sql\": models__do_nothing__sql,\n            \"do_nothing_15.sql\": models__do_nothing__sql,\n            \"do_nothing_16.sql\": models__do_nothing__sql,\n            \"do_nothing_17.sql\": models__do_nothing__sql,\n            \"do_nothing_18.sql\": models__do_nothing__sql,\n            \"do_nothing_19.sql\": models__do_nothing__sql,\n            \"do_nothing_20.sql\": models__do_nothing__sql,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\"config-version\": 2}\n\n    @pytest.fixture(scope=\"class\")\n    def profiles_config_update(self):\n        return {\"threads\": 2}\n\n    def test_threading_8x(self, project):\n        results = run_dbt(args=[\"run\", \"--threads\", \"16\"])\n        assert len(results), 20\n"
  },
  {
    "path": "tests/functional/time_spines/fixtures.py",
    "content": "models_people_sql = \"\"\"\nselect 1 as id, 'Drew' as first_name, 'Banin' as last_name, 'yellow' as favorite_color, true as loves_dbt, 5 as tenure, current_timestamp as created_at\nunion all\nselect 2 as id, 'Jeremy' as first_name, 'Cohen' as last_name, 'indigo' as favorite_color, true as loves_dbt, 4 as tenure, current_timestamp as created_at\nunion all\nselect 3 as id, 'Callum' as first_name, 'McCann' as last_name, 'emerald' as favorite_color, true as loves_dbt, 0 as tenure, current_timestamp as created_at\n\"\"\"\n\nsemantic_model_people_yml = \"\"\"\nversion: 2\n\nsemantic_models:\n  - name: semantic_people\n    model: ref('people')\n    dimensions:\n      - name: favorite_color\n        type: categorical\n      - name: created_at\n        type: TIME\n        type_params:\n          time_granularity: day\n    measures:\n      - name: years_tenure\n        agg: SUM\n        expr: tenure\n      - name: people\n        agg: count\n        expr: id\n    entities:\n      - name: id\n        type: primary\n    defaults:\n      agg_time_dimension: created_at\n\"\"\"\n\nmetricflow_time_spine_sql = \"\"\"\nSELECT to_date('02/20/2023, 'mm/dd/yyyy') as date_day\n\"\"\"\n\nmetricflow_time_spine_second_sql = \"\"\"\nSELECT to_datetime('02/20/2023, 'mm/dd/yyyy hh:mm:ss') as ts_second\n\"\"\"\n\nvalid_time_spines_yml = \"\"\"\nversion: 2\n\nmodels:\n  - name: metricflow_time_spine_second\n    time_spine:\n      standard_granularity_column: ts_second\n    columns:\n      - name: ts_second\n        granularity: second\n  - name: metricflow_time_spine\n    time_spine:\n      standard_granularity_column: date_day\n      custom_granularities:\n        - name: retail_month\n        - name: martian_year\n          column_name: martian__year_xyz\n    columns:\n      - name: date_day\n        granularity: day\n      - name: retail_month\n      - name: martian__year_xyz\n\n\"\"\"\n\nmissing_time_spine_yml = \"\"\"\nmodels:\n  - name: metricflow_time_spine\n    columns:\n      - name: ts_second\n        granularity: second\n\"\"\"\n\ntime_spine_missing_granularity_yml = \"\"\"\nmodels:\n  - name: metricflow_time_spine_second\n    time_spine:\n      standard_granularity_column: ts_second\n    columns:\n      - name: ts_second\n\"\"\"\n\ntime_spine_missing_standard_column_yml = \"\"\"\nmodels:\n  - name: metricflow_time_spine_second\n    time_spine:\n      standard_granularity_column: ts_second\n    columns:\n      - name: date_day\n\"\"\"\n\ntime_spine_missing_custom_column_yml = \"\"\"\nmodels:\n  - name: metricflow_time_spine_second\n    time_spine:\n      standard_granularity_column: date_day\n      custom_granularities:\n        - name: retail_month\n    columns:\n      - name: date_day\n        granularity: day\n\"\"\"\n\ntime_spine_yml = \"\"\"\nversion: 2\n\nmodels:\n  - name: metricflow_time_spine\n    time_spine:\n      standard_granularity_column: date_day\n      custom_granularities:\n        - name: retail_month\n        - name: martian_day\n          column_name: martian_day\n    columns:\n      - name: date_day\n        granularity: day\n      - name: retail_month\n      - name: martian_day\n\"\"\"\n"
  },
  {
    "path": "tests/functional/time_spines/test_time_spines.py",
    "content": "from typing import Set\n\nimport pytest\n\nfrom dbt.cli.main import dbtRunner\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.contracts.graph.semantic_manifest import SemanticManifest\nfrom dbt.exceptions import ParsingError\nfrom dbt.tests.util import get_manifest\nfrom dbt_semantic_interfaces.type_enums import TimeGranularity\nfrom tests.functional.time_spines.fixtures import (\n    metricflow_time_spine_second_sql,\n    metricflow_time_spine_sql,\n    models_people_sql,\n    semantic_model_people_yml,\n    time_spine_missing_custom_column_yml,\n    time_spine_missing_granularity_yml,\n    time_spine_missing_standard_column_yml,\n    valid_time_spines_yml,\n)\n\n\nclass TestValidTimeSpines:\n    \"\"\"Tests that YAML using current time spine configs parses as expected.\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"metricflow_time_spine_second.sql\": metricflow_time_spine_second_sql,\n            \"time_spines.yml\": valid_time_spines_yml,\n            \"semantic_model_people.yml\": semantic_model_people_yml,\n            \"people.sql\": models_people_sql,\n        }\n\n    def test_time_spines(self, project):\n        runner = dbtRunner()\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        assert isinstance(result.result, Manifest)\n\n        manifest = get_manifest(project.project_root)\n        assert manifest\n\n        # Test that models and columns are set as expected\n        time_spine_models = {\n            id.split(\".\")[-1]: node for id, node in manifest.nodes.items() if node.time_spine\n        }\n        day_model_name = \"metricflow_time_spine\"\n        second_model_name = \"metricflow_time_spine_second\"\n        day_column_name = \"date_day\"\n        second_column_name = \"ts_second\"\n        model_names_to_col_names = {\n            day_model_name: day_column_name,\n            second_model_name: second_column_name,\n        }\n        model_names_to_granularities = {\n            day_model_name: TimeGranularity.DAY,\n            second_model_name: TimeGranularity.SECOND,\n        }\n        assert len(time_spine_models) == 2\n        expected_time_spine_aliases = {second_model_name, day_model_name}\n        assert set(time_spine_models.keys()) == expected_time_spine_aliases\n        for model in time_spine_models.values():\n            assert (\n                model.time_spine.standard_granularity_column\n                == model_names_to_col_names[model.name]\n            )\n            if model.name == day_model_name:\n                assert len(model.time_spine.custom_granularities) == 2\n                assert {\n                    custom_granularity.name\n                    for custom_granularity in model.time_spine.custom_granularities\n                } == {\"retail_month\", \"martian_year\"}\n                for custom_granularity in model.time_spine.custom_granularities:\n                    if custom_granularity.name == \"martian_year\":\n                        assert custom_granularity.column_name == \"martian__year_xyz\"\n            else:\n                assert len(model.time_spine.custom_granularities) == 0\n            assert len(model.columns) > 0\n            assert (\n                list(model.columns.values())[0].granularity\n                == model_names_to_granularities[model.name]\n            )\n\n        # Test that project configs are set as expected in semantic manifest\n        semantic_manifest = SemanticManifest(manifest)\n        assert semantic_manifest.validate()\n        project_config = semantic_manifest._get_pydantic_semantic_manifest().project_configuration\n        # Current configs\n        assert len(project_config.time_spines) == 2\n        sl_time_spine_aliases: Set[str] = set()\n        for sl_time_spine in project_config.time_spines:\n            alias = sl_time_spine.node_relation.alias\n            sl_time_spine_aliases.add(alias)\n            assert sl_time_spine.primary_column.name == model_names_to_col_names[alias]\n            assert (\n                sl_time_spine.primary_column.time_granularity\n                == model_names_to_granularities[alias]\n            )\n        assert sl_time_spine_aliases == expected_time_spine_aliases\n\n\nclass TestValidLegacyTimeSpine:\n    \"\"\"Tests that YAML using only legacy time spine config parses as expected.\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"semantic_model_people.yml\": semantic_model_people_yml,\n            \"people.sql\": models_people_sql,\n        }\n\n    def test_time_spines(self, project):\n        runner = dbtRunner()\n        result = runner.invoke([\"parse\"])\n        assert result.success\n        assert isinstance(result.result, Manifest)\n\n        manifest = get_manifest(project.project_root)\n        assert manifest\n\n        # Test that project configs are set as expected in semantic manifest\n        semantic_manifest = SemanticManifest(manifest)\n        assert semantic_manifest.validate()\n        project_config = semantic_manifest._get_pydantic_semantic_manifest().project_configuration\n        # Legacy config\n        assert len(project_config.time_spine_table_configurations) == 1\n        legacy_time_spine_config = project_config.time_spine_table_configurations[0]\n        assert legacy_time_spine_config.column_name == \"date_day\"\n        assert (\n            legacy_time_spine_config.location.replace('\"', \"\").split(\".\")[-1]\n            == \"metricflow_time_spine\"\n        )\n        assert legacy_time_spine_config.grain == TimeGranularity.DAY\n        # Current configs\n        assert len(project_config.time_spines) == 0\n\n\nclass TestMissingTimeSpine:\n    \"\"\"Tests that YAML with semantic models but no time spines errors.\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"semantic_model_people.yml\": semantic_model_people_yml,\n            \"people.sql\": models_people_sql,\n        }\n\n    def test_time_spines(self, project):\n        runner = dbtRunner()\n        result = runner.invoke([\"parse\"])\n        assert isinstance(result.exception, ParsingError)\n        assert (\n            \"The semantic layer requires a time spine model with granularity DAY or smaller\"\n            in result.exception.msg\n        )\n\n\nclass TestTimeSpineStandardColumnMissing:\n    \"\"\"Tests that YAML with time spine standard granularity column not in model errors.\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"semantic_model_people.yml\": semantic_model_people_yml,\n            \"people.sql\": models_people_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"metricflow_time_spine_second.sql\": metricflow_time_spine_second_sql,\n            \"time_spines.yml\": time_spine_missing_standard_column_yml,\n        }\n\n    def test_time_spines(self, project):\n        runner = dbtRunner()\n        result = runner.invoke([\"parse\"])\n        assert isinstance(result.exception, ParsingError)\n        assert (\n            \"Time spine standard granularity column must be defined on the model.\"\n            in result.exception.msg\n        )\n\n\nclass TestTimeSpineCustomColumnMissing:\n    \"\"\"Tests that YAML with time spine custom granularity column not in model errors.\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"semantic_model_people.yml\": semantic_model_people_yml,\n            \"people.sql\": models_people_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"metricflow_time_spine_second.sql\": metricflow_time_spine_second_sql,\n            \"time_spines.yml\": time_spine_missing_custom_column_yml,\n        }\n\n    def test_time_spines(self, project):\n        runner = dbtRunner()\n        result = runner.invoke([\"parse\"])\n        assert isinstance(result.exception, ParsingError)\n        assert (\n            \"Time spine custom granularity columns do not exist in the model.\"\n            in result.exception.msg\n        )\n\n\nclass TestTimeSpineGranularityMissing:\n    \"\"\"Tests that YAML with time spine column without granularity errors.\"\"\"\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"semantic_model_people.yml\": semantic_model_people_yml,\n            \"people.sql\": models_people_sql,\n            \"metricflow_time_spine.sql\": metricflow_time_spine_sql,\n            \"metricflow_time_spine_second.sql\": metricflow_time_spine_second_sql,\n            \"time_spines.yml\": time_spine_missing_granularity_yml,\n        }\n\n    def test_time_spines(self, project):\n        runner = dbtRunner()\n        result = runner.invoke([\"parse\"])\n        assert isinstance(result.exception, ParsingError)\n        assert (\n            \"Time spine standard granularity column must have a granularity defined.\"\n            in result.exception.msg\n        )\n"
  },
  {
    "path": "tests/functional/timezones/test_timezones.py",
    "content": "import os\n\nimport pytest\n\nfrom dbt.tests.util import run_dbt\n\n# Canada/Saskatchewan does not observe DST so the time diff won't change depending on when it is in the year\nmodel_sql = \"\"\"\n{{\n    config(\n        materialized='table'\n    )\n}}\n\nselect\n    '{{ run_started_at.astimezone(modules.pytz.timezone(\"Canada/Saskatchewan\")) }}' as run_started_at_saskatchewan,\n    '{{ run_started_at }}' as run_started_at_utc\n\"\"\"\n\n\nclass TestTimezones:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"timezones.sql\": model_sql}\n\n    @pytest.fixture(scope=\"class\")\n    def dbt_profile_data(self, unique_schema):\n        return {\n            \"test\": {\n                \"outputs\": {\n                    \"dev\": {\n                        \"type\": \"postgres\",\n                        \"threads\": 1,\n                        \"host\": \"localhost\",\n                        \"port\": int(os.getenv(\"POSTGRES_TEST_PORT\", 5432)),\n                        \"user\": os.getenv(\"POSTGRES_TEST_USER\", \"root\"),\n                        \"pass\": os.getenv(\"POSTGRES_TEST_PASS\", \"password\"),\n                        \"dbname\": os.getenv(\"POSTGRES_TEST_DATABASE\", \"dbt\"),\n                        \"schema\": unique_schema,\n                    },\n                },\n                \"target\": \"dev\",\n            }\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def query(self, project):\n        return \"\"\"\n            select\n              run_started_at_saskatchewan,\n              run_started_at_utc\n            from {schema}.timezones\n        \"\"\".format(\n            schema=project.test_schema\n        )\n\n    # This test used to use freeze_time, but that doesn't work\n    # with our timestamp fields in proto messages.\n    def test_run_started_at(self, project, query):\n        results = run_dbt([\"run\"])\n\n        assert len(results) == 1\n\n        result = project.run_sql(query, fetch=\"all\")[0]\n        saskatchewan, utc = result\n\n        assert \"+00:00\" in utc\n        assert \"-06:00\" in saskatchewan\n"
  },
  {
    "path": "tests/functional/unit_testing/fixtures.py",
    "content": "import pytest\n\nmy_model_vars_sql = \"\"\"\nSELECT\na+b as c,\nconcat(string_a, string_b) as string_c,\nnot_testing, date_a,\n{{ dbt.string_literal(type_numeric()) }} as macro_call,\n{{ dbt.string_literal(var('my_test')) }} as var_call,\n{{ dbt.string_literal(env_var('MY_TEST', 'default')) }} as env_var_call,\n{{ dbt.string_literal(invocation_id) }} as invocation_id\nFROM {{ ref('my_model_a')}} my_model_a\nJOIN {{ ref('my_model_b' )}} my_model_b\nON my_model_a.id = my_model_b.id\n\"\"\"\n\nmy_model_sql = \"\"\"\nSELECT\na+b as c,\nconcat(string_a, string_b) as string_c,\nnot_testing, date_a\nFROM {{ ref('my_model_a')}} my_model_a\nJOIN {{ ref('my_model_b' )}} my_model_b\nON my_model_a.id = my_model_b.id\n\"\"\"\n\nmy_model_a_sql = \"\"\"\nSELECT\n1 as a,\n1 as id,\n2 as not_testing,\n'a' as string_a,\nDATE '2020-01-02' as date_a\n\"\"\"\n\nmy_model_b_sql = \"\"\"\nSELECT\n2 as b,\n1 as id,\n2 as c,\n'b' as string_b\n\"\"\"\n\nmy_model_check_null_sql = \"\"\"\nSELECT\nCASE\n  WHEN a IS null THEN True\n  ELSE False\nEND a_is_null\nFROM {{ ref('my_model_a') }}\n\"\"\"\n\ntest_my_model_a_yml = \"\"\"\nmodels:\n  - name: my_model_a\n    columns:\n      - name: a\n        tests:\n          - not_null\n      - name: id\n        tests:\n          - not_null\n\"\"\"\n\ntest_my_model_yml = \"\"\"\nunit_tests:\n  - name: test_my_model\n    model: my_model\n    given:\n      - input: ref('my_model_a')\n        rows:\n          - {id: 1, a: 1}\n      - input: ref('my_model_b')\n        rows:\n          - {id: 1, b: 2}\n          - {id: 2, b: 2}\n    expect:\n      rows:\n        - {c: 2}\n\n  - name: test_my_model_empty\n    model: my_model\n    given:\n      - input: ref('my_model_a')\n        rows: []\n      - input: ref('my_model_b')\n        rows:\n          - {id: 1, b: 2}\n          - {id: 2, b: 2}\n    expect:\n      rows: []\n\n  - name: test_my_model_overrides\n    model: my_model\n    given:\n      - input: ref('my_model_a')\n        rows:\n          - {id: 1, a: 1}\n      - input: ref('my_model_b')\n        rows:\n          - {id: 1, b: 2}\n          - {id: 2, b: 2}\n    overrides:\n      macros:\n        type_numeric: override\n        invocation_id: 123\n      vars:\n        my_test: var_override\n      env_vars:\n        MY_TEST: env_var_override\n    expect:\n      rows:\n        - {macro_call: override, var_call: var_override, env_var_call: env_var_override, invocation_id: 123}\n\n  - name: test_my_model_string_concat\n    model: my_model\n    given:\n      - input: ref('my_model_a')\n        rows:\n          - {id: 1, string_a: a}\n      - input: ref('my_model_b')\n        rows:\n          - {id: 1, string_b: b}\n    expect:\n      rows:\n        - {string_c: ab}\n    config:\n        tags: test_this\n\"\"\"\n\ntest_my_model_pass_yml = \"\"\"\nunit_tests:\n  - name: test_my_model\n    model: my_model\n    given:\n      - input: ref('my_model_a')\n        rows:\n          - {id: 1, a: 1}\n      - input: ref('my_model_b')\n        rows:\n          - {id: 1, b: 2}\n          - {id: 2, b: 2}\n    expect:\n      rows:\n        - {c: 3}\n\"\"\"\n\ntest_disabled_unit_test_my_model_yml = \"\"\"\nunit_tests:\n  - name: test_disabled_my_model\n    model: my_model\n    config:\n      enabled: false\n    given:\n      - input: ref('my_model_a')\n        rows:\n          - {id: 1, a: 1}\n      - input: ref('my_model_b')\n        rows:\n          - {id: 1, b: 2}\n          - {id: 2, b: 2}\n    expect:\n      rows:\n        - {c: 3}\n\"\"\"\n\nmy_model_disabled_sql = \"\"\"\n{{ config(enabled=false) }}\nselect 1 as id\n\"\"\"\n\nmy_model_disabled_yml = \"\"\"\nmodels:\n  - name: my_model_disabled_yml\n    config:\n      enabled: false\n\"\"\"\n\ndisabled_my_model_tests_yml = \"\"\"\nunit_tests:\n  - name: test_disabled_my_model_sql\n    model: my_model_disabled_sql\n    given: []\n    expect:\n      rows: [{\"id\": 1}]\n  - name: test_disabled_my_model_yml\n    model: my_model_disabled_yml\n    given: []\n    expect:\n      rows: [{\"id\": 1}]\n\"\"\"\n\ntest_my_model_simple_fixture_yml = \"\"\"\nunit_tests:\n  - name: test_my_model\n    model: my_model\n    given:\n      - input: ref('my_model_a')\n        rows:\n          - {id: 1, a: 1}\n      - input: ref('my_model_b')\n        rows:\n          - {id: 1, b: 2}\n          - {id: 2, b: 2}\n    expect:\n      rows:\n        - {c: 2}\n\n  - name: test_depends_on_fixture\n    model: my_model\n    given:\n      - input: ref('my_model_a')\n        rows: []\n      - input: ref('my_model_b')\n        format: csv\n        fixture: test_my_model_fixture\n    expect:\n      rows: []\n\n  - name: test_my_model_overrides\n    model: my_model\n    given:\n      - input: ref('my_model_a')\n        rows:\n          - {id: 1, a: 1}\n      - input: ref('my_model_b')\n        rows:\n          - {id: 1, b: 2}\n          - {id: 2, b: 2}\n    overrides:\n      macros:\n        type_numeric: override\n        invocation_id: 123\n      vars:\n        my_test: var_override\n      env_vars:\n        MY_TEST: env_var_override\n    expect:\n      rows:\n        - {macro_call: override, var_call: var_override, env_var_call: env_var_override, invocation_id: 123}\n\n  - name: test_has_string_c_ab\n    model: my_model\n    given:\n      - input: ref('my_model_a')\n        rows:\n          - {id: 1, string_a: a}\n      - input: ref('my_model_b')\n        rows:\n          - {id: 1, string_b: b}\n    expect:\n      rows:\n        - {string_c: ab}\n    config:\n        tags: test_this\n\"\"\"\n\n\ndatetime_test = \"\"\"\n  - name: test_my_model_datetime\n    model: my_model\n    given:\n      - input: ref('my_model_a')\n        rows:\n          - {id: 1, date_a: \"2020-01-01\"}\n      - input: ref('my_model_b')\n        rows:\n          - {id: 1}\n    expect:\n      rows:\n        - {date_a: \"2020-01-01\"}\n\"\"\"\n\nevent_sql = \"\"\"\nselect DATE '2020-01-01' as event_time, 1 as event\nunion all\nselect DATE '2020-01-02' as event_time, 2 as event\nunion all\nselect DATE '2020-01-03' as event_time, 3 as event\n\"\"\"\n\ndatetime_test_invalid_format_key = \"\"\"\n  - name: test_my_model_datetime\n    model: my_model\n    given:\n      - input: ref('my_model_a')\n        format: xxxx\n        rows:\n          - {id: 1, date_a: \"2020-01-01\"}\n      - input: ref('my_model_b')\n        rows:\n          - {id: 1}\n    expect:\n      rows:\n        - {date_a: \"2020-01-01\"}\n\"\"\"\n\ndatetime_test_invalid_csv_values = \"\"\"\n  - name: test_my_model_datetime\n    model: my_model\n    given:\n      - input: ref('my_model_a')\n        format: csv\n        rows:\n          - {id: 1, date_a: \"2020-01-01\"}\n      - input: ref('my_model_b')\n        rows:\n          - {id: 1}\n    expect:\n      rows:\n        - {date_a: \"2020-01-01\"}\n\"\"\"\n\ndatetime_test_invalid_csv_file_values = \"\"\"\n  - name: test_my_model_datetime\n    model: my_model\n    given:\n      - input: ref('my_model_a')\n        format: csv\n        rows:\n          - {id: 1, date_a: \"2020-01-01\"}\n      - input: ref('my_model_b')\n        rows:\n          - {id: 1}\n    expect:\n      rows:\n        - {date_a: \"2020-01-01\"}\n\"\"\"\n\nevent_sql = \"\"\"\nselect DATE '2020-01-01' as event_time, 1 as event\nunion all\nselect DATE '2020-01-02' as event_time, 2 as event\nunion all\nselect DATE '2020-01-03' as event_time, 3 as event\n\"\"\"\n\nmy_incremental_model_sql = \"\"\"\n{{\n    config(\n        materialized='incremental'\n    )\n}}\n\nselect * from {{ ref('events') }}\n{% if is_incremental() %}\nwhere event_time > (select max(event_time) from {{ this }})\n{% endif %}\n\"\"\"\n\nmy_incremental_model_with_alias_sql = \"\"\"\n{{\n    config(\n        materialized='incremental',\n        alias='alias_name'\n    )\n}}\n\nselect * from {{ ref('events') }}\n{% if is_incremental() %}\nwhere event_time > (select max(event_time) from {{ this }})\n{% endif %}\n\"\"\"\n\nmy_incremental_model_versioned_yml = \"\"\"\nmodels:\n  - name: my_incremental_model\n    latest_version: 1\n    versions:\n      - v: 1\n\"\"\"\n\ntest_my_model_incremental_yml_basic = \"\"\"\nunit_tests:\n  - name: incremental_false\n    model: my_incremental_model\n    overrides:\n      macros:\n        is_incremental: false\n    given:\n      - input: ref('events')\n        rows:\n          - {event_time: \"2020-01-01\", event: 1}\n    expect:\n      rows:\n        - {event_time: \"2020-01-01\", event: 1}\n  - name: incremental_true\n    model: my_incremental_model\n    overrides:\n      macros:\n        is_incremental: true\n    given:\n      - input: ref('events')\n        rows:\n          - {event_time: \"2020-01-01\", event: 1}\n          - {event_time: \"2020-01-02\", event: 2}\n          - {event_time: \"2020-01-03\", event: 3}\n      - input: this\n        rows:\n          - {event_time: \"2020-01-01\", event: 1}\n    expect:\n      rows:\n        - {event_time: \"2020-01-02\", event: 2}\n        - {event_time: \"2020-01-03\", event: 3}\n\"\"\"\n\ntest_my_model_incremental_yml_no_override = \"\"\"\nunit_tests:\n  - name: incremental_false\n    model: my_incremental_model\n    given:\n      - input: ref('events')\n        rows:\n          - {event_time: \"2020-01-01\", event: 1}\n    expect:\n      rows:\n        - {event_time: \"2020-01-01\", event: 1}\n\"\"\"\n\ntest_my_model_incremental_yml_wrong_override = \"\"\"\nunit_tests:\n  - name: incremental_false\n    model: my_incremental_model\n    overrides:\n      macros:\n        is_incremental: foobar\n    given:\n      - input: ref('events')\n        rows:\n          - {event_time: \"2020-01-01\", event: 1}\n    expect:\n      rows:\n        - {event_time: \"2020-01-01\", event: 1}\n\"\"\"\n\ntest_my_model_incremental_yml_no_this_input = \"\"\"\nunit_tests:\n  - name: incremental_true\n    model: my_incremental_model\n    overrides:\n      macros:\n        is_incremental: true\n    given:\n      - input: ref('events')\n        rows:\n          - {event_time: \"2020-01-01\", event: 1}\n          - {event_time: \"2020-01-02\", event: 2}\n          - {event_time: \"2020-01-03\", event: 3}\n    expect:\n      rows:\n        - {event_time: \"2020-01-02\", event: 2}\n        - {event_time: \"2020-01-03\", event: 3}\n\"\"\"\n\n# -- inline csv tests\n\ntest_my_model_csv_yml = \"\"\"\nunit_tests:\n  - name: test_my_model\n    model: my_model\n    given:\n      - input: ref('my_model_a')\n        format: csv\n        rows: |\n          id,a\n          1,1\n      - input: ref('my_model_b')\n        format: csv\n        rows: |\n          id,b\n          1,2\n          2,2\n    expect:\n      format: csv\n      rows: |\n        c\n        2\n\n  - name: test_my_model_empty\n    model: my_model\n    given:\n      - input: ref('my_model_a')\n        rows: []\n      - input: ref('my_model_b')\n        format: csv\n        rows: |\n          id,b\n          1,2\n          2,2\n    expect:\n      rows: []\n  - name: test_my_model_overrides\n    model: my_model\n    given:\n      - input: ref('my_model_a')\n        format: csv\n        rows: |\n          id,a\n          1,1\n      - input: ref('my_model_b')\n        format: csv\n        rows: |\n          id,b\n          1,2\n          2,2\n    overrides:\n      macros:\n        type_numeric: override\n        invocation_id: 123\n      vars:\n        my_test: var_override\n      env_vars:\n        MY_TEST: env_var_override\n    expect:\n      rows:\n        - {macro_call: override, var_call: var_override, env_var_call: env_var_override, invocation_id: 123}\n  - name: test_my_model_string_concat\n    model: my_model\n    given:\n      - input: ref('my_model_a')\n        format: csv\n        rows: |\n          id,string_a\n          1,a\n      - input: ref('my_model_b')\n        format: csv\n        rows: |\n          id,string_b\n          1,b\n    expect:\n      format: csv\n      rows: |\n        string_c\n        ab\n    config:\n        tags: test_this\n\"\"\"\n\n# -- csv file tests\ntest_my_model_file_csv_yml = \"\"\"\nunit_tests:\n  - name: test_my_model\n    model: my_model\n    given:\n      - input: ref('my_model_a')\n        format: csv\n        fixture: test_my_model_a_numeric_fixture\n      - input: ref('my_model_b')\n        format: csv\n        fixture: test_my_model_fixture\n    expect:\n      format: csv\n      fixture: test_my_model_basic_fixture\n\n  - name: test_my_model_empty\n    model: my_model\n    given:\n      - input: ref('my_model_a')\n        format: csv\n        fixture: test_my_model_a_empty_fixture\n      - input: ref('my_model_b')\n        format: csv\n        fixture: test_my_model_fixture\n    expect:\n      format: csv\n      fixture: test_my_model_a_empty_fixture\n\n  - name: test_my_model_overrides\n    model: my_model\n    given:\n      - input: ref('my_model_a')\n        format: csv\n        fixture: test_my_model_a_numeric_fixture\n      - input: ref('my_model_b')\n        format: csv\n        fixture: test_my_model_fixture\n    overrides:\n      macros:\n        type_numeric: override\n        invocation_id: 123\n      vars:\n        my_test: var_override\n      env_vars:\n        MY_TEST: env_var_override\n    expect:\n      rows:\n        - {macro_call: override, var_call: var_override, env_var_call: env_var_override, invocation_id: 123}\n\n  - name: test_my_model_string_concat\n    model: my_model\n    given:\n      - input: ref('my_model_a')\n        format: csv\n        fixture: test_my_model_a_fixture\n      - input: ref('my_model_b')\n        format: csv\n        fixture: test_my_model_b_fixture\n    expect:\n      format: csv\n      fixture: test_my_model_concat_fixture\n    config:\n      tags: test_this\n\"\"\"\n\ntest_my_model_fixture_csv = \"\"\"id,b\n1,2\n2,2\n\"\"\"\n\ntest_my_model_a_fixture_csv = \"\"\"id,string_a\n1,a\n\"\"\"\n\ntest_my_model_a_with_null_fixture_csv = \"\"\"id,a\n1,\n2,3\n\"\"\"\n\ntest_my_model_a_empty_fixture_csv = \"\"\"\n\"\"\"\n\ntest_my_model_a_numeric_fixture_csv = \"\"\"id,a\n1,1\n\"\"\"\n\ntest_my_model_b_fixture_csv = \"\"\"id,string_b\n1,b\n\"\"\"\n\ntest_my_model_basic_fixture_csv = \"\"\"c\n2\n\"\"\"\n\ntest_my_model_concat_fixture_csv = \"\"\"string_c\nab\n\"\"\"\n\n# -- mixed inline and file csv\ntest_my_model_mixed_csv_yml = \"\"\"\nunit_tests:\n  - name: test_my_model\n    model: my_model\n    given:\n      - input: ref('my_model_a')\n        format: csv\n        rows: |\n          id,a\n          1,1\n      - input: ref('my_model_b')\n        format: csv\n        rows: |\n          id,b\n          1,2\n          2,2\n    expect:\n      format: csv\n      fixture: test_my_model_basic_fixture\n\n  - name: test_my_model_empty\n    model: my_model\n    given:\n      - input: ref('my_model_a')\n        format: csv\n        fixture: test_my_model_a_empty_fixture\n      - input: ref('my_model_b')\n        format: csv\n        rows: |\n          id,b\n          1,2\n          2,2\n    expect:\n      format: csv\n      fixture: test_my_model_a_empty_fixture\n\n  - name: test_my_model_overrides\n    model: my_model\n    given:\n      - input: ref('my_model_a')\n        format: csv\n        rows: |\n          id,a\n          1,1\n      - input: ref('my_model_b')\n        format: csv\n        fixture: test_my_model_fixture\n    overrides:\n      macros:\n        type_numeric: override\n        invocation_id: 123\n      vars:\n        my_test: var_override\n      env_vars:\n        MY_TEST: env_var_override\n    expect:\n      rows:\n        - {macro_call: override, var_call: var_override, env_var_call: env_var_override, invocation_id: 123}\n\n  - name: test_my_model_string_concat\n    model: my_model\n    given:\n      - input: ref('my_model_a')\n        format: csv\n        fixture: test_my_model_a_fixture\n      - input: ref('my_model_b')\n        format: csv\n        fixture: test_my_model_b_fixture\n    expect:\n      format: csv\n      rows: |\n        string_c\n        ab\n    config:\n      tags: test_this\n\"\"\"\n\n# unit tests with errors\n\n# -- fixture file doesn't exist\ntest_my_model_missing_csv_yml = \"\"\"\nunit_tests:\n  - name: test_missing_csv_file\n    model: my_model\n    given:\n      - input: ref('my_model_a')\n        format: csv\n        rows: |\n          id,a\n          1,1\n      - input: ref('my_model_b')\n        format: csv\n        rows: |\n          id,b\n          1,2\n          2,2\n    expect:\n      format: csv\n      fixture: fake_fixture\n\"\"\"\n\ntest_my_model_duplicate_csv_yml = \"\"\"\nunit_tests:\n  - name: test_missing_csv_file\n    model: my_model\n    given:\n      - input: ref('my_model_a')\n        format: csv\n        rows: |\n          id,a\n          1,1\n      - input: ref('my_model_b')\n        format: csv\n        rows: |\n          id,b\n          1,2\n          2,2\n    expect:\n      format: csv\n      fixture: test_my_model_basic_fixture\n\"\"\"\n\ntest_model_a_b_yml = \"\"\"\nunit_tests:\n  - name: my_test_name\n    model: my_model_a\n    given: []\n    expect:\n      rows:\n        - {a: 1, id: 1, not_testing: 2, string_a: \"a\", date_a: \"2020-01-02\"}\n\n  - name: my_test_name\n    model: my_model_b\n    given: []\n    expect:\n      rows:\n        - {b: 2, id: 1, c: 2, string_b: \"b\"}\n\"\"\"\n\ntest_model_a_with_duplicate_test_name_yml = \"\"\"\nunit_tests:\n  - name: my_test_name\n    model: my_model_a\n    given: []\n    expect:\n      rows:\n        - {a: 1, id: 1, not_testing: 2, string_a: \"a\", date_a: \"2020-01-02\"}\n\n  - name: my_test_name\n    model: my_model_a\n    given: []\n    expect:\n      rows:\n        - {a: 1, id: 1, not_testing: 2, string_a: \"a\", date_a: \"2020-01-02\"}\n\"\"\"\n\ntest_my_model_yml_invalid = \"\"\"\nunit_tests:\n  - name: test_my_model\n    model: my_model\n    given:\n      - input: ref('my_model_a')\n        rows:\n          - {id: 1, a: \"a\"}\n      - input: ref('my_model_b')\n        rows:\n          - {id: 1, b: 2}\n          - {id: 2, b: 2}\n    expect:\n      rows:\n        - {c: 3}\n\"\"\"\n\ntest_my_model_yml_invalid_ref = \"\"\"\nunit_tests:\n  - name: test_my_model\n    model: my_model\n    given:\n      - input: ref('my_model_x')\n        rows:\n          - {id: 1, a: 1}\n      - input: ref('my_model_b')\n        rows:\n          - {id: 1, b: 2}\n          - {id: 2, b: 2}\n    expect:\n      rows:\n        - {c: 3}\n\"\"\"\n\n# -- unit testing versioned models\nmy_model_v1_sql = \"\"\"\nSELECT\na,\nb,\na+b as c,\nconcat(string_a, string_b) as string_c,\nnot_testing, date_a\nFROM {{ ref('my_model_a')}} my_model_a\nJOIN {{ ref('my_model_b' )}} my_model_b\nON my_model_a.id = my_model_b.id\n\"\"\"\n\nmy_model_v2_sql = \"\"\"\nSELECT\na,\nb,\na+b as c,\nconcat(string_a, string_b) as string_c,\ndate_a\nFROM {{ ref('my_model_a')}} my_model_a\nJOIN {{ ref('my_model_b' )}} my_model_b\nON my_model_a.id = my_model_b.id\n\"\"\"\n\nmy_model_v3_sql = \"\"\"\nSELECT\na,\nb,\na+b as c,\nconcat(string_a, string_b) as string_c\nFROM {{ ref('my_model_a')}} my_model_a\nJOIN {{ ref('my_model_b' )}} my_model_b\nON my_model_a.id = my_model_b.id\n\"\"\"\n\nmy_model_versioned_yml = \"\"\"\nmodels:\n  - name: my_model\n    latest_version: 1\n    access: public\n    config:\n      contract:\n        enforced: true\n    columns:\n      - name: a\n        data_type: integer\n      - name: b\n        data_type: integer\n      - name: c\n        data_type: integer\n      - name: string_c\n        data_type: string\n      - name: not_testing\n        data_type: integer\n      - name: date_a\n        data_type: date\n    versions:\n      - v: 1\n      - v: 2\n        columns:\n          # This means: use the 'columns' list from above, but exclude not_testing\n          - include: \"all\"\n            exclude:\n            - not_testing\n      - v: 3\n        # now exclude another column\n        columns:\n          - include: all\n            exclude:\n            - not_testing\n            - date_a\n\"\"\"\n\nmy_model_versioned_no_2_yml = \"\"\"\nmodels:\n  - name: my_model\n    latest_version: 1\n    access: public\n    config:\n      contract:\n        enforced: true\n    columns:\n      - name: a\n        data_type: integer\n      - name: b\n        data_type: integer\n      - name: c\n        data_type: integer\n      - name: string_c\n        data_type: string\n      - name: not_testing\n        data_type: integer\n      - name: date_a\n        data_type: date\n    versions:\n      - v: 1\n      - v: 3\n        # now exclude another column\n        columns:\n          - include: all\n            exclude:\n            - not_testing\n            - date_a\n\"\"\"\n\ntest_my_model_all_versions_yml = \"\"\"\nunit_tests:\n  - name: test_my_model\n    model: my_model\n    given:\n      - input: ref('my_model_a')\n        format: csv\n        rows: |\n          id,a\n          1,1\n          2,3\n      - input: ref('my_model_b')\n        format: csv\n        rows: |\n          id,b\n          1,2\n          2,2\n    expect:\n      format: csv\n      rows: |\n          a,b,c\n          1,2,3\n          3,2,5\n\"\"\"\n\ntest_my_model_exclude_versions_yml = \"\"\"\nunit_tests:\n  - name: test_my_model\n    model: my_model\n    versions:\n      exclude:\n        - 2\n    given:\n      - input: ref('my_model_a')\n        format: csv\n        rows: |\n          id,a\n          1,1\n          2,3\n      - input: ref('my_model_b')\n        format: csv\n        rows: |\n          id,b\n          1,2\n          2,2\n    expect:\n      format: csv\n      rows: |\n          a,b,c\n          1,2,3\n          3,2,5\n\"\"\"\n\ntest_my_model_include_versions_yml = \"\"\"\nunit_tests:\n  - name: test_my_model\n    model: my_model\n    versions:\n      include:\n        - 2\n    given:\n      - input: ref('my_model_a')\n        format: csv\n        rows: |\n          id,a\n          1,1\n          2,3\n      - input: ref('my_model_b')\n        format: csv\n        rows: |\n          id,b\n          1,2\n          2,2\n    expect:\n      format: csv\n      rows: |\n          a,b,c\n          1,2,3\n          3,2,5\n\"\"\"\n\ntest_my_model_include_exclude_versions_yml = \"\"\"\nunit_tests:\n  - name: test_my_model\n    model: my_model\n    versions:\n      include:\n        - 2\n      exclude:\n        - 3\n    given:\n      - input: ref('my_model_a')\n        format: csv\n        rows: |\n          id,a\n          1,1\n          2,3\n      - input: ref('my_model_b')\n        format: csv\n        rows: |\n          id,b\n          1,2\n          2,2\n    expect:\n      format: csv\n      rows: |\n          a,b,c\n          1,2,3\n          3,2,5\n\"\"\"\n\ntest_my_model_include_unversioned_yml = \"\"\"\nunit_tests:\n  - name: test_my_model\n    model: my_model\n    versions:\n      include:\n        - 2\n    given:\n      - input: ref('my_model_a')\n        rows:\n          - {id: 1, a: 1}\n      - input: ref('my_model_b')\n        rows:\n          - {id: 1, b: 2}\n          - {id: 2, b: 2}\n    expect:\n      rows:\n        - {c: 2}\n\"\"\"\n\nmy_model_version_ref_sql = \"\"\"\n   select * from {{ ref('my_model', version=2) }}\n\"\"\"\n\ntest_my_model_version_ref_yml = \"\"\"\nunit_tests:\n  - name: test_my_model_version_ref\n    model: my_model_version_ref\n    given:\n      - input: ref('my_model', version=2)\n        rows:\n          - {c: 2}\n    expect:\n      rows:\n        - {c: 2}\n\"\"\"\n\n\n# -- unit testing external models\ntop_level_domains_sql = \"\"\"\nSELECT 'example.com' AS tld\nUNION ALL\nSELECT 'gmail.com' AS tld\n\"\"\"\n\nvalid_emails_sql = \"\"\"\nWITH\naccounts AS (\n  SELECT user_id, email, email_top_level_domain\n  FROM {{ ref('external_package', 'external_model')}}\n),\ntop_level_domains AS (\n  SELECT tld FROM {{ ref('top_level_domains')}}\n),\njoined AS (\n  SELECT\n    accounts.user_id as user_id,\n    top_level_domains.tld as tld\n  FROM accounts\n  LEFT OUTER JOIN top_level_domains\n    ON   accounts.email_top_level_domain = top_level_domains.tld\n)\n\nSELECT\n  joined.user_id as user_id,\n  CASE WHEN joined.tld IS NULL THEN FALSE ELSE TRUE END AS is_valid_email_address\nfrom joined\n\"\"\"\n\nexternal_package__accounts_seed_csv = \"\"\"user_id,email,email_top_level_domain\n1,\"example@example.com\",\"example.com\"\n\"\"\"\n\nexternal_package__external_model_sql = \"\"\"\nSELECT user_id, email, email_top_level_domain FROM {{ ref('accounts_seed') }}\n\"\"\"\n\n\nexternal_package_project_yml = \"\"\"\nname: external_package\nversion: '1.0'\nconfig-version: 2\n\nmodel-paths: [\"models\"]    # paths to models\nanalysis-paths: [\"analyses\"] # path with analysis files which are compiled, but not run\ntarget-path: \"target\"      # path for compiled code\nclean-targets: [\"target\"]  # directories removed by the clean task\ntest-paths: [\"tests\"]       # where to store test results\nseed-paths: [\"seeds\"]       # load CSVs from this directory with `dbt seed`\nmacro-paths: [\"macros\"]    # where to find macros\n\nprofile: user\n\nmodels:\n    external_package:\n\"\"\"\n\n\n@pytest.fixture(scope=\"class\")\ndef external_package():\n    return {\n        \"dbt_project.yml\": external_package_project_yml,\n        \"seeds\": {\"accounts_seed.csv\": external_package__accounts_seed_csv},\n        \"models\": {\n            \"external_model.sql\": external_package__external_model_sql,\n        },\n    }\n\n\nmodel_select_1_sql = \"\"\"\nselect 1 as id\n\"\"\"\n\nmodel_select_2_sql = \"\"\"\nselect 2 as id\n\"\"\"\n\ntest_expect_2_yml = \"\"\"\nunit_tests:\n  - name: test_my_model\n    model: my_model\n    given: []\n    expect:\n      rows:\n        - {id: 2}\n\"\"\"\n\n\ntest_my_model_csv_null_yml = \"\"\"\nunit_tests:\n  - name: test_my_model_check_null\n    model: my_model_check_null\n    given:\n      - input: ref('my_model_a')\n        format: csv\n        rows: |\n          id,a\n          1,\n          2,3\n    expect:\n      format: csv\n      rows: |\n        a_is_null\n        True\n        False\n\"\"\"\n\ntest_my_model_file_csv_null_yml = \"\"\"\nunit_tests:\n  - name: test_my_model_check_null\n    model: my_model_check_null\n    given:\n      - input: ref('my_model_a')\n        format: csv\n        fixture: test_my_model_a_with_null_fixture\n    expect:\n      format: csv\n      rows: |\n        a_is_null\n        True\n        False\n\"\"\"\n"
  },
  {
    "path": "tests/functional/unit_testing/test_csv_fixtures.py",
    "content": "import pytest\nfrom fixtures import (\n    datetime_test,\n    datetime_test_invalid_csv_values,\n    datetime_test_invalid_format_key,\n    my_model_a_sql,\n    my_model_b_sql,\n    my_model_check_null_sql,\n    my_model_sql,\n    test_my_model_a_empty_fixture_csv,\n    test_my_model_a_fixture_csv,\n    test_my_model_a_numeric_fixture_csv,\n    test_my_model_a_with_null_fixture_csv,\n    test_my_model_b_fixture_csv,\n    test_my_model_basic_fixture_csv,\n    test_my_model_concat_fixture_csv,\n    test_my_model_csv_null_yml,\n    test_my_model_csv_yml,\n    test_my_model_duplicate_csv_yml,\n    test_my_model_file_csv_null_yml,\n    test_my_model_file_csv_yml,\n    test_my_model_fixture_csv,\n    test_my_model_missing_csv_yml,\n    test_my_model_mixed_csv_yml,\n)\n\nfrom dbt.exceptions import DuplicateResourceNameError, ParsingError, YamlParseDictError\nfrom dbt.tests.util import rm_file, run_dbt, write_file\n\n\nclass TestUnitTestsWithInlineCSV:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": my_model_sql,\n            \"my_model_a.sql\": my_model_a_sql,\n            \"my_model_b.sql\": my_model_b_sql,\n            \"test_my_model.yml\": test_my_model_csv_yml + datetime_test,\n        }\n\n    def test_unit_test(self, project):\n        results = run_dbt([\"run\"])\n        assert len(results) == 3\n\n        # Select by model name\n        results = run_dbt([\"test\", \"--select\", \"my_model\"], expect_pass=False)\n        assert len(results) == 5\n\n        # Check error with invalid format key\n        write_file(\n            test_my_model_csv_yml + datetime_test_invalid_format_key,\n            project.project_root,\n            \"models\",\n            \"test_my_model.yml\",\n        )\n        with pytest.raises(YamlParseDictError):\n            results = run_dbt([\"test\", \"--select\", \"my_model\"], expect_pass=False)\n\n        # Check error with csv format defined but dict on rows\n        write_file(\n            test_my_model_csv_yml + datetime_test_invalid_csv_values,\n            project.project_root,\n            \"models\",\n            \"test_my_model.yml\",\n        )\n        with pytest.raises(ParsingError):\n            results = run_dbt([\"test\", \"--select\", \"my_model\"], expect_pass=False)\n\n\nclass TestUnitTestsWithFileCSV:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": my_model_sql,\n            \"my_model_a.sql\": my_model_a_sql,\n            \"my_model_b.sql\": my_model_b_sql,\n            \"test_my_model.yml\": test_my_model_file_csv_yml + datetime_test,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def tests(self):\n        return {\n            \"fixtures\": {\n                \"test_my_model_fixture.csv\": test_my_model_fixture_csv,\n                \"test_my_model_a_fixture.csv\": test_my_model_a_fixture_csv,\n                \"test_my_model_b_fixture.csv\": test_my_model_b_fixture_csv,\n                \"test_my_model_basic_fixture.csv\": test_my_model_basic_fixture_csv,\n                \"test_my_model_a_numeric_fixture.csv\": test_my_model_a_numeric_fixture_csv,\n                \"test_my_model_a_empty_fixture.csv\": test_my_model_a_empty_fixture_csv,\n                \"test_my_model_concat_fixture.csv\": test_my_model_concat_fixture_csv,\n            }\n        }\n\n    def test_unit_test(self, project):\n        results = run_dbt([\"run\"])\n        assert len(results) == 3\n\n        manifest = run_dbt([\"parse\"])  # Note: this manifest is deserialized from msgpack\n        fixture = manifest.fixtures[\"fixture.test.test_my_model_a_fixture\"]\n        fixture_source_file = manifest.files[fixture.file_id]\n        assert fixture_source_file.fixture == \"fixture.test.test_my_model_a_fixture\"\n        assert fixture_source_file.unit_tests == [\n            \"unit_test.test.my_model.test_my_model_string_concat\"\n        ]\n\n        # Select by model name\n        results = run_dbt([\"test\", \"--select\", \"my_model\"], expect_pass=False)\n        assert len(results) == 5\n\n        # Check partial parsing remove fixture file\n        rm_file(project.project_root, \"tests\", \"fixtures\", \"test_my_model_a_fixture.csv\")\n        with pytest.raises(\n            ParsingError,\n            match=\"File not found for fixture 'test_my_model_a_fixture' in unit tests\",\n        ):\n            run_dbt([\"test\", \"--select\", \"my_model\"], expect_pass=False)\n        # put back file and check that it works\n        write_file(\n            test_my_model_a_fixture_csv,\n            project.project_root,\n            \"tests\",\n            \"fixtures\",\n            \"test_my_model_a_fixture.csv\",\n        )\n        results = run_dbt([\"test\", \"--select\", \"my_model\"], expect_pass=False)\n        assert len(results) == 5\n        # Now update file\n        write_file(\n            test_my_model_a_fixture_csv + \"2,2\",\n            project.project_root,\n            \"tests\",\n            \"fixtures\",\n            \"test_my_model_a_fixture.csv\",\n        )\n        manifest = run_dbt([\"parse\"])\n        fixture = manifest.fixtures[\"fixture.test.test_my_model_a_fixture\"]\n        fixture_source_file = manifest.files[fixture.file_id]\n        assert \"2,2\" in fixture_source_file.contents\n        assert fixture.rows == [{\"id\": \"1\", \"string_a\": \"a\"}, {\"id\": \"2\", \"string_a\": \"2\"}]\n\n        # Check error with invalid format key\n        write_file(\n            test_my_model_file_csv_yml + datetime_test_invalid_format_key,\n            project.project_root,\n            \"models\",\n            \"test_my_model.yml\",\n        )\n        with pytest.raises(YamlParseDictError):\n            results = run_dbt([\"test\", \"--select\", \"my_model\"], expect_pass=False)\n\n        # Check error with csv format defined but dict on rows\n        write_file(\n            test_my_model_file_csv_yml + datetime_test_invalid_csv_values,\n            project.project_root,\n            \"models\",\n            \"test_my_model.yml\",\n        )\n        with pytest.raises(ParsingError):\n            results = run_dbt([\"test\", \"--select\", \"my_model\"], expect_pass=False)\n\n\nclass TestUnitTestsWithMixedCSV:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": my_model_sql,\n            \"my_model_a.sql\": my_model_a_sql,\n            \"my_model_b.sql\": my_model_b_sql,\n            \"test_my_model.yml\": test_my_model_mixed_csv_yml + datetime_test,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def tests(self):\n        return {\n            \"fixtures\": {\n                \"test_my_model_fixture.csv\": test_my_model_fixture_csv,\n                \"test_my_model_a_fixture.csv\": test_my_model_a_fixture_csv,\n                \"test_my_model_b_fixture.csv\": test_my_model_b_fixture_csv,\n                \"test_my_model_basic_fixture.csv\": test_my_model_basic_fixture_csv,\n                \"test_my_model_a_numeric_fixture.csv\": test_my_model_a_numeric_fixture_csv,\n                \"test_my_model_a_empty_fixture.csv\": test_my_model_a_empty_fixture_csv,\n                \"test_my_model_concat_fixture.csv\": test_my_model_concat_fixture_csv,\n            }\n        }\n\n    def test_unit_test(self, project):\n        results = run_dbt([\"run\"])\n        assert len(results) == 3\n\n        # Select by model name\n        results = run_dbt([\"test\", \"--select\", \"my_model\"], expect_pass=False)\n        assert len(results) == 5\n\n        # Check error with invalid format key\n        write_file(\n            test_my_model_mixed_csv_yml + datetime_test_invalid_format_key,\n            project.project_root,\n            \"models\",\n            \"test_my_model.yml\",\n        )\n        with pytest.raises(YamlParseDictError):\n            results = run_dbt([\"test\", \"--select\", \"my_model\"], expect_pass=False)\n\n        # Check error with csv format defined but dict on rows\n        write_file(\n            test_my_model_mixed_csv_yml + datetime_test_invalid_csv_values,\n            project.project_root,\n            \"models\",\n            \"test_my_model.yml\",\n        )\n        with pytest.raises(ParsingError):\n            results = run_dbt([\"test\", \"--select\", \"my_model\"], expect_pass=False)\n\n\nclass TestUnitTestsInlineCSVEmptyValueIsNull:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model_a.sql\": my_model_a_sql,\n            \"my_model_check_null.sql\": my_model_check_null_sql,\n            \"test_my_model_csv_null.yml\": test_my_model_csv_null_yml,\n        }\n\n    def test_unit_test(self, project):\n        results = run_dbt([\"run\"])\n        assert len(results) == 2\n\n        # Select by model name\n        results = run_dbt([\"test\", \"--select\", \"my_model_check_null\"], expect_pass=True)\n        assert len(results) == 1\n\n\nclass TestUnitTestsFileCSVEmptyValueIsNull:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model_a.sql\": my_model_a_sql,\n            \"my_model_check_null.sql\": my_model_check_null_sql,\n            \"test_my_model_file_csv_null.yml\": test_my_model_file_csv_null_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def tests(self):\n        return {\n            \"fixtures\": {\n                \"test_my_model_a_with_null_fixture.csv\": test_my_model_a_with_null_fixture_csv,\n            }\n        }\n\n    def test_unit_test(self, project):\n        results = run_dbt([\"run\"])\n        assert len(results) == 2\n\n        # Select by model name\n        results = run_dbt([\"test\", \"--select\", \"my_model_check_null\"], expect_pass=True)\n        assert len(results) == 1\n\n\nclass TestUnitTestsMissingCSVFile:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": my_model_sql,\n            \"my_model_a.sql\": my_model_a_sql,\n            \"my_model_b.sql\": my_model_b_sql,\n            \"test_my_model.yml\": test_my_model_missing_csv_yml,\n        }\n\n    def test_missing(self, project):\n        with pytest.raises(ParsingError):\n            run_dbt([\"run\"])\n\n\nclass TestUnitTestsDuplicateCSVFile:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": my_model_sql,\n            \"my_model_a.sql\": my_model_a_sql,\n            \"my_model_b.sql\": my_model_b_sql,\n            \"test_my_model.yml\": test_my_model_duplicate_csv_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def tests(self):\n        return {\n            \"fixtures\": {\n                \"one-folder\": {\n                    \"test_my_model_basic_fixture.csv\": test_my_model_basic_fixture_csv,\n                },\n                \"another-folder\": {\n                    \"test_my_model_basic_fixture.csv\": test_my_model_basic_fixture_csv,\n                },\n            }\n        }\n\n    def test_duplicate(self, project):\n        with pytest.raises(DuplicateResourceNameError):\n            run_dbt([\"run\"])\n"
  },
  {
    "path": "tests/functional/unit_testing/test_sql_format.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt\n\nwizards_csv = \"\"\"id,w_name,email,email_tld,phone,world\n1,Albus Dumbledore,a.dumbledore@gmail.com,gmail.com,813-456-9087,1\n2,Gandalf,gandy811@yahoo.com,yahoo.com,551-329-8367,2\n3,Winifred Sanderson,winnie@hocuspocus.com,hocuspocus.com,,6\n4,Marnie Piper,cromwellwitch@gmail.com,gmail.com,,5\n5,Grace Goheen,grace.goheen@dbtlabs.com,dbtlabs.com,,3\n6,Glinda,glinda_good@hotmail.com,hotmail.com,912-458-3289,4\n\"\"\"\n\ntop_level_email_domains_csv = \"\"\"tld\ngmail.com\nyahoo.com\nhocuspocus.com\ndbtlabs.com\nhotmail.com\n\"\"\"\n\nworlds_csv = \"\"\"id,name\n1,The Wizarding World\n2,Middle-earth\n3,dbt Labs\n4,Oz\n5,Halloweentown\n6,Salem\n\"\"\"\n\nstg_wizards_sql = \"\"\"\nselect\n    id as wizard_id,\n    w_name as wizard_name,\n    email,\n    email_tld as email_top_level_domain,\n    phone as phone_number,\n    world as world_id\nfrom {{ ref('wizards') }}\n\"\"\"\n\nstg_worlds_sql = \"\"\"\nselect\n    id as world_id,\n    name as world_name\nfrom {{ ref('worlds') }}\n\"\"\"\n\ndim_wizards_sql = \"\"\"\nwith wizards as (\n\n    select * from {{ ref('stg_wizards') }}\n\n),\n\nworlds as (\n\n    select * from {{ ref('stg_worlds') }}\n\n),\n\naccepted_email_domains as (\n\n    select * from {{ ref('top_level_email_domains') }}\n\n),\n\ncheck_valid_emails as (\n\n    select\n        wizards.wizard_id,\n        wizards.wizard_name,\n        wizards.email,\n        wizards.phone_number,\n        wizards.world_id,\n\n        coalesce (\n            wizards.email ~ '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\\\.[A-Za-z]{2,}$'\n        = true\n        and accepted_email_domains.tld is not null,\n        false) as is_valid_email_address\n\n    from wizards\n    left join accepted_email_domains\n        on wizards.email_top_level_domain = lower(accepted_email_domains.tld)\n\n)\n\nselect\n    check_valid_emails.wizard_id,\n    check_valid_emails.wizard_name,\n    check_valid_emails.email,\n    check_valid_emails.is_valid_email_address,\n    check_valid_emails.phone_number,\n    worlds.world_name\nfrom check_valid_emails\nleft join worlds\n    on check_valid_emails.world_id = worlds.world_id\n\"\"\"\n\norig_schema_yml = \"\"\"\nunit_tests:\n  - name: test_valid_email_address\n    model: dim_wizards\n    given:\n      - input: ref('stg_wizards')\n        rows:\n          - {email: cool@example.com,     email_top_level_domain: example.com}\n          - {email: cool@unknown.com,     email_top_level_domain: unknown.com}\n          - {email: badgmail.com,         email_top_level_domain: gmail.com}\n          - {email: missingdot@gmailcom,  email_top_level_domain: gmail.com}\n      - input: ref('top_level_email_domains')\n        rows:\n          - {tld: example.com}\n          - {tld: gmail.com}\n      - input: ref('stg_worlds')\n        rows: []\n    expect:\n      rows:\n        - {email: cool@example.com,    is_valid_email_address: true}\n        - {email: cool@unknown.com,    is_valid_email_address: false}\n        - {email: badgmail.com,        is_valid_email_address: false}\n        - {email: missingdot@gmailcom, is_valid_email_address: false}\n\"\"\"\n\nschema_yml = \"\"\"\nunit_tests:\n  - name: test_valid_email_address\n    model: dim_wizards\n    given:\n      - input: ref('stg_wizards')\n        format: sql\n        rows: |\n          select 1 as wizard_id, 'joe' as wizard_name, 'cool@example.com' as email, 'example.com' as email_top_level_domain, '123' as phone_number, 1 as world_id  union all\n          select 2 as wizard_id, 'don' as wizard_name, 'cool@unknown.com' as email, 'unknown.com' as email_top_level_domain, '456' as phone_number, 2 as world_id  union all\n          select 3 as wizard_id, 'mary' as wizard_name, 'badgmail.com' as email, 'gmail.com' as email_top_level_domain, '789' as phone_number, 3 as world_id union all\n          select 4 as wizard_id, 'jane' as wizard_name, 'missingdot@gmailcom' as email, 'gmail.com' as email_top_level_domain, '102' as phone_number, 4 as world_id\n      - input: ref('top_level_email_domains')\n        format: sql\n        rows: |\n          select 'example.com' as tld union all\n          select 'gmail.com' as tld\n      - input: ref('stg_worlds')\n        rows: []\n    expect:\n      format: sql\n      rows: |\n        select 1 as wizard_id, 'joe' as wizard_name, 'cool@example.com' as email, true as is_valid_email_address, '123' as phone_number, null as world_name union all\n        select 2 as wizard_id, 'don' as wizard_name, 'cool@unknown.com' as email, false as is_valid_email_address, '456' as phone_number, null as world_name  union all\n        select 3 as wizard_id, 'mary' as wizard_name, 'badgmail.com' as email, false as is_valid_email_address, '789' as phone_number, null as world_name union all\n        select 4 as wizard_id, 'jane' as wizard_name, 'missingdot@gmailcom' as email, false as is_valid_email_address, '102' as phone_number, null as world_name\n\"\"\"\n\n\nclass TestSQLFormat:\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\n            \"wizards.csv\": wizards_csv,\n            \"top_level_email_domains.csv\": top_level_email_domains_csv,\n            \"worlds.csv\": worlds_csv,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"stg_wizards.sql\": stg_wizards_sql,\n            \"stg_worlds.sql\": stg_worlds_sql,\n            \"dim_wizards.sql\": dim_wizards_sql,\n            \"schema.yml\": schema_yml,\n        }\n\n    def test_sql_format(self, project):\n        results = run_dbt([\"build\"])\n        assert len(results) == 7\n\n\nstg_wizards_fixture_sql = \"\"\"\n    select 1 as wizard_id, 'joe' as wizard_name, 'cool@example.com' as email, 'example.com' as email_top_level_domain, '123' as phone_number, 1 as world_id  union all\n    select 2 as wizard_id, 'don' as wizard_name, 'cool@unknown.com' as email, 'unknown.com' as email_top_level_domain, '456' as phone_number, 2 as world_id  union all\n    select 3 as wizard_id, 'mary' as wizard_name, 'badgmail.com' as email, 'gmail.com' as email_top_level_domain, '789' as phone_number, 3 as world_id union all\n    select 4 as wizard_id, 'jane' as wizard_name, 'missingdot@gmailcom' as email, 'gmail.com' as email_top_level_domain, '102' as phone_number, 4 as world_id\n\"\"\"\n\ntop_level_email_domains_fixture_sql = \"\"\"\n    select 'example.com' as tld union all\n    select 'gmail.com' as tld\n\"\"\"\n\ntest_valid_email_address_fixture_sql = \"\"\"\n    select 1 as wizard_id, 'joe' as wizard_name, 'cool@example.com' as email, true as is_valid_email_address, '123' as phone_number, null as world_name union all\n    select 2 as wizard_id, 'don' as wizard_name, 'cool@unknown.com' as email, false as is_valid_email_address, '456' as phone_number, null as world_name  union all\n    select 3 as wizard_id, 'mary' as wizard_name, 'badgmail.com' as email, false as is_valid_email_address, '789' as phone_number, null as world_name union all\n    select 4 as wizard_id, 'jane' as wizard_name, 'missingdot@gmailcom' as email, false as is_valid_email_address, '102' as phone_number, null as world_name\n\"\"\"\n\nfixture_schema_yml = \"\"\"\nunit_tests:\n  - name: test_valid_email_address\n    model: dim_wizards\n    given:\n      - input: ref('stg_wizards')\n        format: sql\n        fixture: stg_wizards_fixture\n      - input: ref('top_level_email_domains')\n        format: sql\n        fixture: top_level_email_domains_fixture\n      - input: ref('stg_worlds')\n        rows: []\n    expect:\n      format: sql\n      fixture: test_valid_email_address_fixture\n\"\"\"\n\n\nclass TestSQLFormatFixtures:\n    @pytest.fixture(scope=\"class\")\n    def tests(self):\n        return {\n            \"fixtures\": {\n                \"test_valid_email_address_fixture.sql\": test_valid_email_address_fixture_sql,\n                \"top_level_email_domains_fixture.sql\": top_level_email_domains_fixture_sql,\n                \"stg_wizards_fixture.sql\": stg_wizards_fixture_sql,\n            }\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\n            \"wizards.csv\": wizards_csv,\n            \"top_level_email_domains.csv\": top_level_email_domains_csv,\n            \"worlds.csv\": worlds_csv,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"stg_wizards.sql\": stg_wizards_sql,\n            \"stg_worlds.sql\": stg_worlds_sql,\n            \"dim_wizards.sql\": dim_wizards_sql,\n            \"schema.yml\": fixture_schema_yml,\n        }\n\n    def test_sql_format_fixtures(self, project):\n        results = run_dbt([\"build\"])\n        assert len(results) == 7\n"
  },
  {
    "path": "tests/functional/unit_testing/test_state.py",
    "content": "import os\nimport shutil\nfrom copy import deepcopy\n\nimport pytest\nfrom fixtures import (\n    model_select_1_sql,\n    model_select_2_sql,\n    my_model_a_sql,\n    my_model_b_sql,\n    my_model_vars_sql,\n    test_expect_2_yml,\n)\nfrom fixtures import test_my_model_b_fixture_csv as test_my_model_fixture_csv_modified\nfrom fixtures import test_my_model_fixture_csv, test_my_model_simple_fixture_yml\n\nfrom dbt.tests.util import run_dbt, write_config_file, write_file\n\n\nclass UnitTestState:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": my_model_vars_sql,\n            \"my_model_a.sql\": my_model_a_sql,\n            \"my_model_b.sql\": my_model_b_sql,\n            \"test_my_model.yml\": test_my_model_simple_fixture_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def tests(self):\n        return {\n            \"fixtures\": {\n                \"test_my_model_fixture.csv\": test_my_model_fixture_csv,\n            }\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\"vars\": {\"my_test\": \"my_test_var\"}}\n\n    def copy_state(self, project_root):\n        state_path = os.path.join(project_root, \"state\")\n        if not os.path.exists(state_path):\n            os.makedirs(state_path)\n        shutil.copyfile(\n            f\"{project_root}/target/manifest.json\", f\"{project_root}/state/manifest.json\"\n        )\n        shutil.copyfile(\n            f\"{project_root}/target/run_results.json\", f\"{project_root}/state/run_results.json\"\n        )\n\n\nclass TestUnitTestStateModified(UnitTestState):\n    def test_state_modified(self, project):\n        run_dbt([\"run\"])\n        run_dbt([\"test\"], expect_pass=False)\n        self.copy_state(project.project_root)\n\n        # no changes\n        results = run_dbt([\"test\", \"--select\", \"state:modified\", \"--state\", \"state\"])\n        assert len(results) == 0\n\n        # change underlying fixture file\n        write_file(\n            test_my_model_fixture_csv_modified,\n            project.project_root,\n            \"tests\",\n            \"fixtures\",\n            \"test_my_model_fixture.csv\",\n        )\n        results = run_dbt(\n            [\"test\", \"--select\", \"state:modified\", \"--state\", \"state\"], expect_pass=True\n        )\n        assert len(results) == 1\n        assert results[0].node.name.endswith(\"test_depends_on_fixture\")\n        # reset changes\n        self.copy_state(project.project_root)\n\n        # change unit test definition of a single unit test\n        with_changes = test_my_model_simple_fixture_yml.replace(\"{string_c: ab}\", \"{string_c: bc}\")\n        write_config_file(with_changes, project.project_root, \"models\", \"test_my_model.yml\")\n        results = run_dbt(\n            [\"test\", \"--select\", \"state:modified\", \"--state\", \"state\"], expect_pass=False\n        )\n        assert len(results) == 1\n        assert results[0].node.name.endswith(\"test_has_string_c_ab\")\n\n        # change underlying model logic\n        write_config_file(\n            test_my_model_simple_fixture_yml, project.project_root, \"models\", \"test_my_model.yml\"\n        )\n        write_file(\n            my_model_vars_sql.replace(\"a+b as c,\", \"a + b as c,\"),\n            project.project_root,\n            \"models\",\n            \"my_model.sql\",\n        )\n        results = run_dbt(\n            [\"test\", \"--select\", \"state:modified\", \"--state\", \"state\"], expect_pass=False\n        )\n        assert len(results) == 4\n\n\nclass TestUnitTestRetry(UnitTestState):\n    def test_unit_test_retry(self, project):\n        run_dbt([\"run\"])\n        run_dbt([\"test\"], expect_pass=False)\n        self.copy_state(project.project_root)\n\n        results = run_dbt([\"retry\"], expect_pass=False)\n        assert len(results) == 1\n\n\nclass TestUnitTestDeferState(UnitTestState):\n    @pytest.fixture(scope=\"class\")\n    def other_schema(self, unique_schema):\n        return unique_schema + \"_other\"\n\n    @pytest.fixture(scope=\"class\")\n    def profiles_config_update(self, dbt_profile_target, unique_schema, other_schema):\n        outputs = {\"default\": dbt_profile_target, \"otherschema\": deepcopy(dbt_profile_target)}\n        outputs[\"default\"][\"schema\"] = unique_schema\n        outputs[\"otherschema\"][\"schema\"] = other_schema\n        return {\"test\": {\"outputs\": outputs, \"target\": \"default\"}}\n\n    def test_unit_test_defer_state(self, project):\n        run_dbt([\"run\", \"--target\", \"otherschema\"])\n        self.copy_state(project.project_root)\n        results = run_dbt([\"test\", \"--defer\", \"--state\", \"state\"], expect_pass=False)\n        assert len(results) == 4\n        assert sorted([r.status for r in results]) == [\"fail\", \"pass\", \"pass\", \"pass\"]\n\n\nclass TestUnitTestDeferDoesntOverwrite(UnitTestState):\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\"my_model.sql\": model_select_1_sql, \"test_my_model.yml\": test_expect_2_yml}\n\n    def test_unit_test_defer_state(self, project):\n        run_dbt([\"test\"], expect_pass=False)\n        self.copy_state(project.project_root)\n        write_file(\n            model_select_2_sql,\n            project.project_root,\n            \"models\",\n            \"my_model.sql\",\n        )\n        results = run_dbt([\"test\", \"--defer\", \"--state\", \"state\"])\n        assert len(results) == 1\n        assert sorted([r.status for r in results]) == [\"pass\"]\n"
  },
  {
    "path": "tests/functional/unit_testing/test_unit_testing.py",
    "content": "import os\nfrom unittest import mock\n\nimport pytest\nfrom fixtures import (  # noqa: F401\n    datetime_test,\n    event_sql,\n    external_package,\n    external_package__accounts_seed_csv,\n    my_incremental_model_sql,\n    my_incremental_model_versioned_yml,\n    my_incremental_model_with_alias_sql,\n    my_model_a_sql,\n    my_model_b_sql,\n    my_model_sql,\n    my_model_vars_sql,\n    test_my_model_incremental_yml_basic,\n    test_my_model_incremental_yml_no_override,\n    test_my_model_incremental_yml_no_this_input,\n    test_my_model_incremental_yml_wrong_override,\n    test_my_model_yml,\n    test_my_model_yml_invalid,\n    test_my_model_yml_invalid_ref,\n    top_level_domains_sql,\n    valid_emails_sql,\n)\n\nfrom dbt.contracts.results import NodeStatus\nfrom dbt.exceptions import DuplicateResourceNameError, ParsingError\nfrom dbt.plugins.manifest import ModelNodeArgs, PluginNodes\nfrom dbt.tests.fixtures.project import write_project_files\nfrom dbt.tests.util import (\n    file_exists,\n    get_manifest,\n    read_file,\n    run_dbt,\n    run_dbt_and_capture,\n    write_file,\n)\nfrom tests.unit.utils import normalize\n\n\nclass TestUnitTests:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": my_model_vars_sql,\n            \"my_model_a.sql\": my_model_a_sql,\n            \"my_model_b.sql\": my_model_b_sql,\n            \"test_my_model.yml\": test_my_model_yml + datetime_test,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\"vars\": {\"my_test\": \"my_test_var\"}}\n\n    def test_basic(self, project):\n        results = run_dbt([\"run\"])\n        assert len(results) == 3\n\n        # Select by model name\n        results = run_dbt([\"test\", \"--select\", \"my_model\"], expect_pass=False)\n        assert len(results) == 5\n\n        results = run_dbt(\n            [\"build\", \"--select\", \"my_model\", \"--resource-types\", \"model unit_test\"],\n            expect_pass=False,\n        )\n        assert len(results) == 6\n        for result in results:\n            if result.node.unique_id == \"model.test.my_model\":\n                result.status == NodeStatus.Skipped\n\n        # Run build command but specify no unit tests\n        results = run_dbt(\n            [\"build\", \"--select\", \"my_model\", \"--exclude-resource-types\", \"unit_test\"],\n            expect_pass=True,\n        )\n        assert len(results) == 1\n\n        # Exclude unit tests with environment variable for build command\n        os.environ[\"DBT_EXCLUDE_RESOURCE_TYPES\"] = \"unit_test\"\n        results = run_dbt([\"build\", \"--select\", \"my_model\"], expect_pass=True)\n        assert len(results) == 1\n\n        # Exclude unit tests with environment variable for test command\n        results = run_dbt([\"test\", \"--select\", \"my_model\"], expect_pass=True)\n        assert len(results) == 0\n\n        # Exclude unit tests with environment variable for list command\n        results = run_dbt([\"list\", \"--select\", \"my_model\"], expect_pass=True)\n        assert len(results) == 1\n\n        del os.environ[\"DBT_EXCLUDE_RESOURCE_TYPES\"]\n\n        # Test select by test name\n        results = run_dbt([\"test\", \"--select\", \"test_name:test_my_model_string_concat\"])\n        assert len(results) == 1\n\n        # Select, method not specified\n        results = run_dbt([\"test\", \"--select\", \"test_my_model_overrides\"])\n        assert len(results) == 1\n\n        # Select using tag\n        results = run_dbt([\"test\", \"--select\", \"tag:test_this\"])\n        assert len(results) == 1\n\n        # Partial parsing... remove test\n        write_file(test_my_model_yml, project.project_root, \"models\", \"test_my_model.yml\")\n        results = run_dbt([\"test\", \"--select\", \"my_model\"], expect_pass=False)\n        assert len(results) == 4\n\n        # Partial parsing... put back removed test\n        write_file(\n            test_my_model_yml + datetime_test, project.project_root, \"models\", \"test_my_model.yml\"\n        )\n        results = run_dbt([\"test\", \"--select\", \"my_model\"], expect_pass=False)\n        assert len(results) == 5\n\n        manifest = get_manifest(project.project_root)\n        assert len(manifest.unit_tests) == 5\n        # Every unit test has a depends_on to the model it tests\n        for unit_test_definition in manifest.unit_tests.values():\n            assert unit_test_definition.depends_on.nodes[0] == \"model.test.my_model\"\n\n        # Check for duplicate unit test name\n        # this doesn't currently pass with partial parsing because of the root problem\n        # described in https://github.com/dbt-labs/dbt-core/issues/8982\n        write_file(\n            test_my_model_yml + datetime_test + datetime_test,\n            project.project_root,\n            \"models\",\n            \"test_my_model.yml\",\n        )\n        with pytest.raises(DuplicateResourceNameError):\n            run_dbt([\"run\", \"--no-partial-parse\", \"--select\", \"my_model\"])\n\n\nclass TestUnitTestIncrementalModelBasic:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_incremental_model.sql\": my_incremental_model_sql,\n            \"events.sql\": event_sql,\n            \"schema.yml\": test_my_model_incremental_yml_basic,\n        }\n\n    def test_basic(self, project):\n        results = run_dbt([\"run\"])\n        assert len(results) == 2\n\n        # Select by model name\n        results = run_dbt([\"test\", \"--select\", \"my_incremental_model\"], expect_pass=True)\n        assert len(results) == 2\n\n\nclass TestUnitTestIncrementalModelNoOverride:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_incremental_model.sql\": my_incremental_model_sql,\n            \"events.sql\": event_sql,\n            \"schema.yml\": test_my_model_incremental_yml_no_override,\n        }\n\n    def test_no_override(self, project):\n        with pytest.raises(\n            ParsingError,\n            match=\"Boolean override for 'is_incremental' must be provided for unit test 'incremental_false' in model 'my_incremental_model'\",\n        ):\n            run_dbt([\"parse\"])\n\n\nclass TestUnitTestIncrementalModelWrongOverride:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_incremental_model.sql\": my_incremental_model_sql,\n            \"events.sql\": event_sql,\n            \"schema.yml\": test_my_model_incremental_yml_wrong_override,\n        }\n\n    def test_str_override(self, project):\n        with pytest.raises(\n            ParsingError,\n            match=\"Boolean override for 'is_incremental' must be provided for unit test 'incremental_false' in model 'my_incremental_model'\",\n        ):\n            run_dbt([\"parse\"])\n\n\nclass TestUnitTestIncrementalModelNoThisInput:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_incremental_model.sql\": my_incremental_model_sql,\n            \"events.sql\": event_sql,\n            \"schema.yml\": test_my_model_incremental_yml_no_this_input,\n        }\n\n    def test_no_this_input(self, project):\n        with pytest.raises(\n            ParsingError,\n            match=\"Unit test 'incremental_true' for incremental model 'my_incremental_model' must have a 'this' input\",\n        ):\n            run_dbt([\"parse\"])\n\n\nmy_new_model = \"\"\"\nselect\nmy_favorite_seed.id,\na + b as c\nfrom {{ ref('my_favorite_seed') }} as my_favorite_seed\ninner join {{ ref('my_favorite_model') }} as my_favorite_model\non my_favorite_seed.id = my_favorite_model.id\n\"\"\"\n\nmy_favorite_model = \"\"\"\nselect\n2 as id,\n3 as b\n\"\"\"\n\nseed_my_favorite_seed = \"\"\"id,a\n1,5\n2,4\n3,3\n4,2\n5,1\n\"\"\"\n\nschema_yml_explicit_seed = \"\"\"\nunit_tests:\n  - name: t\n    model: my_new_model\n    given:\n      - input: ref('my_favorite_seed')\n        rows:\n          - {id: 1, a: 10}\n      - input: ref('my_favorite_model')\n        rows:\n          - {id: 1, b: 2}\n    expect:\n      rows:\n        - {id: 1, c: 12}\n\"\"\"\n\nschema_yml_implicit_seed = \"\"\"\nunit_tests:\n  - name: t\n    model: my_new_model\n    given:\n      - input: ref('my_favorite_seed')\n      - input: ref('my_favorite_model')\n        rows:\n          - {id: 1, b: 2}\n    expect:\n      rows:\n        - {id: 1, c: 7}\n\"\"\"\n\nschema_yml_nonexistent_seed = \"\"\"\nunit_tests:\n  - name: t\n    model: my_new_model\n    given:\n      - input: ref('my_second_favorite_seed')\n      - input: ref('my_favorite_model')\n        rows:\n          - {id: 1, b: 2}\n    expect:\n      rows:\n        - {id: 1, c: 7}\n\"\"\"\n\n\nclass TestUnitTestIncrementalModelWithAlias:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_incremental_model.sql\": my_incremental_model_with_alias_sql,\n            \"events.sql\": event_sql,\n            \"schema.yml\": test_my_model_incremental_yml_basic,\n        }\n\n    def test_basic(self, project):\n        results = run_dbt([\"run\"])\n        assert len(results) == 2\n\n        # Select by model name\n        results = run_dbt([\"test\", \"--select\", \"my_incremental_model\"], expect_pass=True)\n        assert len(results) == 2\n\n\nclass TestUnitTestIncrementalModelWithVersion:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_incremental_model.sql\": my_incremental_model_sql,\n            \"events.sql\": event_sql,\n            \"schema.yml\": my_incremental_model_versioned_yml + test_my_model_incremental_yml_basic,\n        }\n\n    def test_basic(self, project):\n        results = run_dbt([\"run\"])\n        assert len(results) == 2\n\n        # Select by model name\n        results = run_dbt([\"test\", \"--select\", \"my_incremental_model\"], expect_pass=True)\n        assert len(results) == 2\n\n\nschema_ref_with_versioned_model = \"\"\"\nmodels:\n  - name: source\n    latest_version: {latest_version}\n    versions:\n        - v: 1\n        - v: 2\n  - name: model_to_test\nunit_tests:\n  - name: ref_versioned\n    model: 'model_to_test'\n    given:\n    - input: {input}\n      rows:\n        - {{result: 3}}\n    expect:\n      rows:\n        - {{result: 3}}\n\n\"\"\"\n\n\nclass TestUnitTestRefWithVersion:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_to_test.sql\": \"select result from {{ ref('source')}}\",\n            \"source.sql\": \"select 2 as result\",\n            \"source_v2.sql\": \"select 2 as result\",\n            \"schema.yml\": schema_ref_with_versioned_model.format(\n                **{\"latest_version\": 1, \"input\": \"ref('source')\"}\n            ),\n        }\n\n    def test_basic(self, project):\n        results = run_dbt([\"run\"])\n\n        results = run_dbt([\"test\", \"--select\", \"model_to_test\"], expect_pass=True)\n        assert len(results) == 1\n\n\nclass TestUnitTestRefMissingVersionModel:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_to_test.sql\": \"select result from {{ ref('source')}}\",\n            \"source_v1.sql\": \"select 2 as result\",\n            \"source_v2.sql\": \"select 2 as result\",\n            \"schema.yml\": schema_ref_with_versioned_model.format(\n                **{\"latest_version\": 1, \"input\": \"ref('source', v=1)\"}\n            ),\n        }\n\n    def test_basic(self, project):\n        results = run_dbt([\"run\"])\n\n        results = run_dbt([\"test\", \"--select\", \"model_to_test\"], expect_pass=True)\n        assert len(results) == 1\n\n\nclass TestUnitTestRefWithMissingVersionRef:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_to_test.sql\": \"select result from {{ ref('source', v=1)}}\",\n            \"source_v1.sql\": \"select 2 as result\",\n            \"source_v2.sql\": \"select 2 as result\",\n            \"schema.yml\": schema_ref_with_versioned_model.format(\n                **{\"latest_version\": 1, \"input\": \"ref('source')\"}\n            ),\n        }\n\n    def test_basic(self, project):\n        results = run_dbt([\"run\"])\n\n        results = run_dbt([\"test\", \"--select\", \"model_to_test\"], expect_pass=True)\n        assert len(results) == 1\n\n\nclass TestUnitTestRefWithVersionLatestSecond:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_to_test.sql\": \"select result from {{ ref('source')}}\",\n            \"source_v1.sql\": \"select 2 as result\",\n            \"source_v2.sql\": \"select 2 as result\",\n            \"schema.yml\": schema_ref_with_versioned_model.format(\n                **{\"latest_version\": 2, \"input\": \"ref('source')\"}\n            ),\n        }\n\n    def test_basic(self, project):\n        results = run_dbt([\"run\"])\n\n        results = run_dbt([\"test\", \"--select\", \"model_to_test\"], expect_pass=True)\n        assert len(results) == 1\n\n\nclass TestUnitTestRefWithVersionMissingRefTest:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_to_test.sql\": \"select result from {{ ref('source', v=2)}}\",\n            \"source_v1.sql\": \"select 2 as result\",\n            \"source_v2.sql\": \"select 2 as result\",\n            \"schema.yml\": schema_ref_with_versioned_model.format(\n                **{\"latest_version\": 1, \"input\": \"ref('source')\"}\n            ),\n        }\n\n    def test_basic(self, project):\n        results = run_dbt([\"run\"])\n\n        assert len(results) == 3\n        # run_dbt([\"test\", \"--select\", \"model_to_test\"], expect_pass=False)\n        exec_result, _ = run_dbt_and_capture(\n            [\"test\", \"--select\", \"model_to_test\"], expect_pass=False\n        )\n        msg_error = exec_result[0].message\n        assert msg_error.lower().lstrip().startswith(\"compilation error\")\n\n\nclass TestUnitTestRefWithVersionDiffLatest:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_to_test.sql\": \"select result from {{ ref('source', v=2)}}\",\n            \"source_v1.sql\": \"select 2 as result\",\n            \"source_v2.sql\": \"select 2 as result\",\n            \"schema.yml\": schema_ref_with_versioned_model.format(\n                **{\"latest_version\": 1, \"input\": \"ref('source', v=2)\"}\n            ),\n        }\n\n    def test_basic(self, project):\n        results = run_dbt([\"run\"])\n        assert len(results) == 3\n        run_dbt([\"test\", \"--select\", \"model_to_test\"], expect_pass=True)\n\n\nclass TestUnitTestExplicitSeed:\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\"my_favorite_seed.csv\": seed_my_favorite_seed}\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_new_model.sql\": my_new_model,\n            \"my_favorite_model.sql\": my_favorite_model,\n            \"schema.yml\": schema_yml_explicit_seed,\n        }\n\n    def test_explicit_seed(self, project):\n        run_dbt([\"seed\"])\n        run_dbt([\"run\"])\n\n        # Select by model name\n        results = run_dbt([\"test\", \"--select\", \"my_new_model\"], expect_pass=True)\n        assert len(results) == 1\n\n\nclass TestUnitTestImplicitSeed:\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\"my_favorite_seed.csv\": seed_my_favorite_seed}\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_new_model.sql\": my_new_model,\n            \"my_favorite_model.sql\": my_favorite_model,\n            \"schema.yml\": schema_yml_implicit_seed,\n        }\n\n    def test_implicit_seed(self, project):\n        run_dbt([\"seed\"])\n        run_dbt([\"run\"])\n\n        # Select by model name\n        results = run_dbt([\"test\", \"--select\", \"my_new_model\"], expect_pass=True)\n        assert len(results) == 1\n\n\nclass TestUnitTestNonexistentSeed:\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\"my_favorite_seed.csv\": seed_my_favorite_seed}\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_new_model.sql\": my_new_model,\n            \"my_favorite_model.sql\": my_favorite_model,\n            \"schema.yml\": schema_yml_nonexistent_seed,\n        }\n\n    def test_nonexistent_seed(self, project):\n        with pytest.raises(\n            ParsingError, match=\"Unable to find seed 'test.my_second_favorite_seed' for unit tests\"\n        ):\n            run_dbt([\"test\", \"--select\", \"my_new_model\"], expect_pass=False)\n\n\nclass TestUnitTestInvalidInputConfiguration:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": my_model_sql,\n            \"my_model_a.sql\": my_model_a_sql,\n            \"my_model_b.sql\": my_model_b_sql,\n            \"test_my_model.yml\": test_my_model_yml_invalid,\n        }\n\n    def test_invalid_input_configuration(self, project):\n        results = run_dbt([\"run\"])\n        assert len(results) == 3\n\n        # A data type in a given row is incorrect, and we'll get a runtime error\n        run_dbt([\"test\"], expect_pass=False)\n\n        # Test invalid model ref. Parsing error InvalidUnitTestGivenInput\n        write_file(\n            test_my_model_yml_invalid_ref, project.project_root, \"models\", \"test_my_model.yml\"\n        )\n        results = run_dbt([\"test\"], expect_pass=False)\n        result = results.results[0]\n        assert \"not found in the manifest\" in result.message\n\n\nunit_test_ext_node_yml = \"\"\"\nunit_tests:\n  - name: unit_test_ext_node\n    model: valid_emails\n    given:\n      - input: ref('external_package', 'external_model')\n        rows:\n          - {user_id: 1, email: cool@example.com,     email_top_level_domain: example.com}\n          - {user_id: 2, email: cool@unknown.com,     email_top_level_domain: unknown.com}\n          - {user_id: 3, email: badgmail.com,         email_top_level_domain: gmail.com}\n          - {user_id: 4, email: missingdot@gmailcom,  email_top_level_domain: gmail.com}\n      - input: ref('top_level_domains')\n        rows:\n          - {tld: example.com}\n          - {tld: gmail.com}\n    expect:\n      rows:\n        - {user_id: 1, is_valid_email_address: true}\n        - {user_id: 2, is_valid_email_address: false}\n        - {user_id: 3, is_valid_email_address: true}\n        - {user_id: 4, is_valid_email_address: true}\n\"\"\"\n\n\nclass TestUnitTestExternalPackageNode:\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project_root, external_package):  # noqa: F811\n        write_project_files(project_root, \"external_package\", external_package)\n\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\"packages\": [{\"local\": \"external_package\"}]}\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"top_level_domains.sql\": top_level_domains_sql,\n            \"valid_emails.sql\": valid_emails_sql,\n            \"unit_test_ext_node.yml\": unit_test_ext_node_yml,\n        }\n\n    def test_unit_test_ext_nodes(\n        self,\n        project,\n    ):\n        # `deps` to install the external package\n        run_dbt([\"deps\"], expect_pass=True)\n        # `seed` need so a table exists for `external_model` to point to\n        run_dbt([\"seed\"], expect_pass=True)\n        # `run` needed to ensure `top_level_domains` exists in database for column getting step\n        run_dbt([\"run\"], expect_pass=True)\n        results = run_dbt([\"test\", \"--select\", \"valid_emails\"], expect_pass=True)\n        assert len(results) == 1\n\n\nclass TestUnitTestExternalProjectNode:\n    @pytest.fixture(scope=\"class\")\n    def external_model_node(self, unique_schema):\n        return ModelNodeArgs(\n            name=\"external_model\",\n            package_name=\"external_package\",\n            identifier=\"external_node_seed\",\n            schema=unique_schema,\n        )\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\"external_node_seed.csv\": external_package__accounts_seed_csv}\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"top_level_domains.sql\": top_level_domains_sql,\n            \"valid_emails.sql\": valid_emails_sql,\n            \"unit_test_ext_node.yml\": unit_test_ext_node_yml,\n        }\n\n    @mock.patch(\"dbt.plugins.get_plugin_manager\")\n    def test_unit_test_ext_nodes(\n        self,\n        get_plugin_manager,\n        project,\n        external_model_node,\n    ):\n        # initial plugin - one external model\n        external_nodes = PluginNodes()\n        external_nodes.add_model(external_model_node)\n        get_plugin_manager.return_value.get_nodes.return_value = external_nodes\n\n        # `seed` need so a table exists for `external_model` to point to\n        run_dbt([\"seed\"], expect_pass=True)\n        # `run` needed to ensure `top_level_domains` exists in database for column getting step\n        run_dbt([\"run\"], expect_pass=True)\n        results = run_dbt([\"test\", \"--select\", \"valid_emails\"], expect_pass=True)\n        assert len(results) == 1\n\n\nsubfolder_model_a_sql = \"\"\"select 1 as id, 'blue' as color\"\"\"\n\nsubfolder_model_b_sql = \"\"\"\nselect\n    id,\n    color\nfrom {{ ref('model_a') }}\n\"\"\"\n\nsubfolder_my_model_yml = \"\"\"\nunit_tests:\n  - name: my_unit_test\n    model: model_b\n    given:\n      - input: ref('model_a')\n        rows:\n          - { id: 1, color: 'blue' }\n    expect:\n      rows:\n        - { id: 1, color: 'red' }\n\"\"\"\n\n\nclass TestUnitTestSubfolderPath:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"subfolder\": {\n                \"model_a.sql\": subfolder_model_a_sql,\n                \"model_b.sql\": subfolder_model_b_sql,\n                \"my_model.yml\": subfolder_my_model_yml,\n            }\n        }\n\n    def test_subfolder_unit_test(self, project):\n        results, output = run_dbt_and_capture([\"build\"], expect_pass=False)\n\n        # Test that input fixture doesn't overwrite the original model\n        assert (\n            read_file(\"target/compiled/test/models/subfolder/model_a.sql\").strip()\n            == subfolder_model_a_sql.strip()\n        )\n\n        # Test that correct path is written in logs\n        assert (\n            normalize(\n                \"target/compiled/test/models/subfolder/my_model.yml/models/subfolder/my_unit_test.sql\"\n            )\n            in output\n        )\n        assert file_exists(\n            normalize(\n                \"target/compiled/test/models/subfolder/my_model.yml/models/subfolder/my_unit_test.sql\"\n            )\n        )\n\n\nmy_model_with_function_sql = \"\"\"\nselect {{ function('double_it') }}(1) as doubled_value\n\"\"\"\n\ntest_my_model_with_function_yml = \"\"\"\nunit_tests:\n  - name: test_my_model\n    model: my_model\n    given: []\n    expect:\n      rows:\n        - {doubled_value: 2}\n\"\"\"\n\n\ndouble_it_sql = \"\"\"\nselect value * 2\n\"\"\"\n\ndouble_it_yml = \"\"\"\nfunctions:\n  - name: double_it\n    description: Doubles whatever number is passed in\n    arguments:\n      - name: value\n        data_type: float\n        description: A number to be doubled\n    returns:\n      data_type: float\n\"\"\"\n\n\nclass TestUnitTestModelWithFunction:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": my_model_with_function_sql,\n            \"test_my_model.yml\": test_my_model_with_function_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def functions(self):\n        return {\n            \"double_it.sql\": double_it_sql,\n            \"double_it.yml\": double_it_yml,\n        }\n\n    def test_model_with_function(self, project):\n        run_dbt([\"build\", \"--empty\"])\n        run_dbt([\"test\"])\n"
  },
  {
    "path": "tests/functional/unit_testing/test_ut_adapter_hooks.py",
    "content": "from unittest import mock\n\nimport pytest\n\nfrom dbt.tests.util import run_dbt, run_dbt_and_capture\nfrom dbt_common.exceptions import CompilationError\nfrom tests.functional.unit_testing.fixtures import (\n    my_model_a_sql,\n    my_model_b_sql,\n    my_model_sql,\n    test_my_model_pass_yml,\n)\n\n\nclass BaseUnitTestAdapterHook:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": my_model_sql,\n            \"my_model_a.sql\": my_model_a_sql,\n            \"my_model_b.sql\": my_model_b_sql,\n            \"test_my_model.yml\": test_my_model_pass_yml,\n        }\n\n\nclass TestUnitTestAdapterPreHook(BaseUnitTestAdapterHook):\n    def test_unit_test_runs_adapter_pre_hook_passes(self, project):\n        results = run_dbt([\"run\"])\n        assert len(results) == 3\n\n        mock_pre_model_hook = mock.Mock()\n        with mock.patch.object(type(project.adapter), \"pre_model_hook\", mock_pre_model_hook):\n            results = run_dbt([\"test\", \"--select\", \"test_name:test_my_model\"], expect_pass=True)\n\n            assert len(results) == 1\n            mock_pre_model_hook.assert_called_once()\n\n    def test_unit_test_runs_adapter_pre_hook_fails(self, project):\n        results = run_dbt([\"run\"])\n        assert len(results) == 3\n\n        mock_pre_model_hook = mock.Mock()\n        mock_pre_model_hook.side_effect = CompilationError(\"exception from adapter.pre_model_hook\")\n        with mock.patch.object(type(project.adapter), \"pre_model_hook\", mock_pre_model_hook):\n            (_, log_output) = run_dbt_and_capture(\n                [\"test\", \"--select\", \"test_name:test_my_model\"], expect_pass=False\n            )\n            assert \"exception from adapter.pre_model_hook\" in log_output\n\n\nclass TestUnitTestAdapterPostHook(BaseUnitTestAdapterHook):\n    def test_unit_test_runs_adapter_post_hook_pass(self, project):\n        results = run_dbt([\"run\"])\n        assert len(results) == 3\n\n        mock_post_model_hook = mock.Mock()\n        with mock.patch.object(type(project.adapter), \"post_model_hook\", mock_post_model_hook):\n            results = run_dbt([\"test\", \"--select\", \"test_name:test_my_model\"], expect_pass=True)\n\n            assert len(results) == 1\n            mock_post_model_hook.assert_called_once()\n\n    def test_unit_test_runs_adapter_post_hook_fails(self, project):\n        results = run_dbt([\"run\"])\n        assert len(results) == 3\n\n        mock_post_model_hook = mock.Mock()\n        mock_post_model_hook.side_effect = CompilationError(\n            \"exception from adapter.post_model_hook\"\n        )\n        with mock.patch.object(type(project.adapter), \"post_model_hook\", mock_post_model_hook):\n            (_, log_output) = run_dbt_and_capture(\n                [\"test\", \"--select\", \"test_name:test_my_model\"], expect_pass=False\n            )\n            assert \"exception from adapter.post_model_hook\" in log_output\n"
  },
  {
    "path": "tests/functional/unit_testing/test_ut_aliases.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt\n\nmodel_with_alias_sql = \"\"\"\n{{\n    config(\n        alias='beautiful_alias',\n        schema='events',\n        materialized='view'\n    )\n}}\n\nselect\n    'foo' as foo\n\"\"\"\n\nmodel_tested = \"\"\"\nselect * from {{ ref('model_with_alias') }}\n\"\"\"\n\nunit_test_yml = \"\"\"\nunit_tests:\n  - name: test_model_with_alias_input\n    model: model_tested\n    given:\n      - input: ref('model_with_alias')\n        rows:\n          - {foo: bar }\n          - {foo: foo }\n    expect:\n      rows:\n          - {foo: bar }\n          - {foo: foo }\n\"\"\"\n\n\nclass TestUnitTestInputWithAlias:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"model_with_alias.sql\": model_with_alias_sql,\n            \"model_tested.sql\": model_tested,\n            \"unit_test.yml\": unit_test_yml,\n        }\n\n    def test_input_with_alias(self, project):\n        results = run_dbt([\"run\"])\n        assert len(results) == 2\n\n        results = run_dbt([\"test\"])\n        assert len(results) == 1\n"
  },
  {
    "path": "tests/functional/unit_testing/test_ut_dependency.py",
    "content": "import pytest\n\nfrom dbt.tests.fixtures.project import write_project_files\nfrom dbt.tests.util import get_unique_ids_in_results, run_dbt\n\nlocal_dependency__dbt_project_yml = \"\"\"\n\nname: 'local_dep'\nversion: '1.0'\n\nseeds:\n  quote_columns: False\n\n\"\"\"\n\nlocal_dependency__schema_yml = \"\"\"\nsources:\n  - name: seed_source\n    schema: \"{{ var('schema_override', target.schema) }}\"\n    tables:\n      - name: \"seed\"\n        columns:\n          - name: id\n            data_tests:\n              - unique\n\nunit_tests:\n  - name: test_dep_model_id\n    model: dep_model\n    given:\n      - input: ref('seed')\n        rows:\n          - {id: 1, name: Joe}\n    expect:\n      rows:\n        - {name_id: Joe_1}\n\n\n\"\"\"\n\nlocal_dependency__dep_model_sql = \"\"\"\nselect name || '_' || id as name_id  from {{ ref('seed') }}\n\n\"\"\"\n\nlocal_dependency__seed_csv = \"\"\"id,name\n1,Mary\n2,Sam\n3,John\n\"\"\"\n\nmy_model_sql = \"\"\"\nselect * from {{ ref('dep_model') }}\n\"\"\"\n\nmy_model_schema_yml = \"\"\"\nunit_tests:\n  - name: test_my_model_name_id\n    model: my_model\n    given:\n      - input: ref('dep_model')\n        rows:\n          - {name_id: Joe_1}\n    expect:\n      rows:\n        - {name_id: Joe_1}\n\"\"\"\n\n\nclass TestUnitTestingInDependency:\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def setUp(self, project_root):\n        local_dependency_files = {\n            \"dbt_project.yml\": local_dependency__dbt_project_yml,\n            \"models\": {\n                \"schema.yml\": local_dependency__schema_yml,\n                \"dep_model.sql\": local_dependency__dep_model_sql,\n            },\n            \"seeds\": {\"seed.csv\": local_dependency__seed_csv},\n        }\n        write_project_files(project_root, \"local_dependency\", local_dependency_files)\n\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\"packages\": [{\"local\": \"local_dependency\"}]}\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": my_model_sql,\n            \"schema.yml\": my_model_schema_yml,\n        }\n\n    def test_unit_test_in_dependency(self, project):\n        run_dbt([\"deps\"])\n        run_dbt([\"seed\"])\n        results = run_dbt([\"run\"])\n        assert len(results) == 2\n\n        results = run_dbt([\"test\"])\n        assert len(results) == 3\n        unique_ids = get_unique_ids_in_results(results)\n        assert \"unit_test.local_dep.dep_model.test_dep_model_id\" in unique_ids\n\n        results = run_dbt([\"test\", \"--select\", \"test_type:unit\"])\n        # two unit tests, 1 in root package, one in local_dep package\n        assert len(results) == 2\n\n        results = run_dbt([\"test\", \"--select\", \"local_dep\"])\n        # 2 tests in local_dep package\n        assert len(results) == 2\n\n        results = run_dbt([\"test\", \"--select\", \"test\"])\n        # 1 test in root package\n        assert len(results) == 1\n"
  },
  {
    "path": "tests/functional/unit_testing/test_ut_diffing.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt\n\nmy_input_model = \"\"\"\nSELECT 1 as id, 'some string' as status\n\"\"\"\n\nmy_model = \"\"\"\nSELECT * FROM {{ ref(\"my_input_model\") }}\n\"\"\"\n\ntest_my_model_order_insensitive = \"\"\"\nunit_tests:\n  - name: unordered_no_nulls\n    model: my_model\n    given:\n      - input: ref(\"my_input_model\")\n        rows:\n          - {\"id\": 1, \"status\": 'B'}\n          - {\"id\": 2, \"status\": 'B'}\n          - {\"id\": 3, \"status\": 'A'}\n    expect:\n        rows:\n          - {\"id\": 3, \"status\": 'A'}\n          - {\"id\": 2, \"status\": 'B'}\n          - {\"id\": 1, \"status\": 'B'}\n\n  - name: unordered_with_nulls\n    model: my_model\n    given:\n      - input: ref(\"my_input_model\")\n        rows:\n          - {\"id\":  , \"status\": 'B'}\n          - {\"id\":  , \"status\": 'B'}\n          - {\"id\": 3, \"status\": 'A'}\n    expect:\n        rows:\n          - {\"id\": 3, \"status\": 'A'}\n          - {\"id\":  , \"status\": 'B'}\n          - {\"id\":  , \"status\": 'B'}\n\n  - name: unordered_with_nulls_2\n    model: my_model\n    given:\n      - input: ref(\"my_input_model\")\n        rows:\n          - {\"id\": 3, \"status\": 'A'}\n          - {\"id\":  , \"status\": 'B'}\n          - {\"id\":  , \"status\": 'B'}\n    expect:\n        rows:\n          - {\"id\":  , \"status\": 'B'}\n          - {\"id\":  , \"status\": 'B'}\n          - {\"id\": 3, \"status\": 'A'}\n\n  - name: unordered_with_nulls_mixed_columns\n    model: my_model\n    given:\n      - input: ref(\"my_input_model\")\n        rows:\n          - {\"id\": 3, \"status\": 'A'}\n          - {\"id\":  , \"status\": 'B'}\n          - {\"id\": 1, \"status\": }\n    expect:\n        rows:\n          - {\"id\": 1, \"status\": }\n          - {\"id\":  , \"status\": 'B'}\n          - {\"id\": 3, \"status\": 'A'}\n\n  - name: unordered_with_null\n    model: my_model\n    given:\n      - input: ref(\"my_input_model\")\n        rows:\n          - {\"id\": 3, \"status\": 'A'}\n          - {\"id\":  , \"status\": 'B'}\n    expect:\n        rows:\n          - {\"id\":  , \"status\": 'B'}\n          - {\"id\": 3, \"status\": 'A'}\n\n  - name: ordered_with_nulls\n    model: my_model\n    given:\n      - input: ref(\"my_input_model\")\n        rows:\n          - {\"id\": 3, \"status\": 'A'}\n          - {\"id\":  , \"status\": 'B'}\n          - {\"id\":  , \"status\": 'B'}\n    expect:\n        rows:\n          - {\"id\": 3, \"status\": 'A'}\n          - {\"id\":  , \"status\": 'B'}\n          - {\"id\":  , \"status\": 'B'}\n\"\"\"\n\n\nclass TestUnitTestingDiffIsOrderAgnostic:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_input_model.sql\": my_input_model,\n            \"my_model.sql\": my_model,\n            \"test_my_model.yml\": test_my_model_order_insensitive,\n        }\n\n    def test_unit_testing_diff_is_order_insensitive(self, project):\n        run_dbt([\"run\"])\n\n        # Select by model name\n        results = run_dbt([\"test\", \"--select\", \"my_model\"], expect_pass=True)\n        assert len(results) == 6\n"
  },
  {
    "path": "tests/functional/unit_testing/test_ut_ephemeral.py",
    "content": "import pytest\n\nfrom dbt.contracts.results import RunStatus, TestStatus\nfrom dbt.tests.util import run_dbt, write_file\n\nephemeral_model_sql = \"\"\"\n{{ config(materialized=\"ephemeral\") }}\nselect 1 as id, 'Emily' as first_name\n\"\"\"\n\nnested_ephemeral_model_sql = \"\"\"\n{{ config(materialized=\"ephemeral\") }}\nselect * from {{ ref('ephemeral_model') }}\n\"\"\"\n\ncustomers_sql = \"\"\"\nselect * from {{ ref('nested_ephemeral_model') }}\n\"\"\"\n\ntest_sql_format_yml = \"\"\"\nunit_tests:\n  - name: test_customers\n    model: customers\n    given:\n      - input: ref('nested_ephemeral_model')\n        format: sql\n        rows: |\n          select 1 as id, 'Emily' as first_name\n    expect:\n      rows:\n        - {id: 1, first_name: Emily}\n\"\"\"\n\nfailing_test_sql_format_yml = \"\"\"\n  - name: fail_test_customers\n    model: customers\n    given:\n      - input: ref('nested_ephemeral_model')\n        format: sql\n        rows: |\n          select 1 as id, 'Emily' as first_name\n    expect:\n      rows:\n        - {id: 1, first_name: Joan}\n\"\"\"\n\n\nclass TestUnitTestEphemeralInput:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"customers.sql\": customers_sql,\n            \"ephemeral_model.sql\": ephemeral_model_sql,\n            \"nested_ephemeral_model.sql\": nested_ephemeral_model_sql,\n            \"tests.yml\": test_sql_format_yml,\n        }\n\n    def test_ephemeral_input(self, project):\n        results = run_dbt([\"run\"])\n        len(results) == 1\n\n        results = run_dbt([\"test\", \"--select\", \"test_type:unit\"])\n        assert len(results) == 1\n\n        results = run_dbt([\"build\"])\n        assert len(results) == 2\n        result_unique_ids = [result.node.unique_id for result in results]\n        assert len(result_unique_ids) == 2\n        assert \"unit_test.test.customers.test_customers\" in result_unique_ids\n\n        # write failing unit test\n        write_file(\n            test_sql_format_yml + failing_test_sql_format_yml,\n            project.project_root,\n            \"models\",\n            \"tests.yml\",\n        )\n        results = run_dbt([\"build\"], expect_pass=False)\n        for result in results:\n            if result.node.unique_id == \"model.test.customers\":\n                assert result.status == RunStatus.Skipped\n            elif result.node.unique_id == \"unit_test.test.customers.fail_test_customers\":\n                assert result.status == TestStatus.Fail\n        assert len(results) == 3\n"
  },
  {
    "path": "tests/functional/unit_testing/test_ut_list.py",
    "content": "import json\nimport os\n\nimport pytest\nfrom fixtures import (  # noqa: F401\n    datetime_test,\n    disabled_my_model_tests_yml,\n    my_model_a_sql,\n    my_model_b_sql,\n    my_model_disabled_sql,\n    my_model_disabled_yml,\n    my_model_vars_sql,\n    test_disabled_unit_test_my_model_yml,\n    test_my_model_yml,\n)\n\nfrom dbt.tests.util import run_dbt\n\n\nclass TestUnitTestList:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": my_model_vars_sql,\n            \"my_model_a.sql\": my_model_a_sql,\n            \"my_model_b.sql\": my_model_b_sql,\n            \"test_my_model.yml\": test_my_model_yml + datetime_test,\n            \"test_disabled_my_model.yml\": test_disabled_unit_test_my_model_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return {\"vars\": {\"my_test\": \"my_test_var\"}}\n\n    def test_unit_test_list(self, project):\n        # make sure things are working\n        results = run_dbt([\"run\"])\n        assert len(results) == 3\n        results = run_dbt([\"test\"], expect_pass=False)\n        assert len(results) == 5\n\n        results = run_dbt([\"list\"])\n        expected = [\n            \"test.my_model\",\n            \"test.my_model_a\",\n            \"test.my_model_b\",\n            \"unit_test:test.test_my_model\",\n            \"unit_test:test.test_my_model_datetime\",\n            \"unit_test:test.test_my_model_empty\",\n            \"unit_test:test.test_my_model_overrides\",\n            \"unit_test:test.test_my_model_string_concat\",\n        ]\n        assert sorted(results) == sorted(expected)\n\n        results = run_dbt([\"list\", \"--select\", \"test_type:unit\"])\n        assert len(results) == 5\n\n        # Check json result\n        results = run_dbt([\"list\", \"--select\", \"test_type:unit\", \"--output\", \"json\"])\n        expected_test_my_model = {\n            \"name\": \"test_my_model\",\n            \"resource_type\": \"unit_test\",\n            \"package_name\": \"test\",\n            \"original_file_path\": os.path.join(\"models\", \"test_my_model.yml\"),\n            \"unique_id\": \"unit_test.test.my_model.test_my_model\",\n            \"depends_on\": {\"macros\": [], \"nodes\": [\"model.test.my_model\"]},\n            \"config\": {\"tags\": [], \"meta\": {}, \"enabled\": True},\n        }\n        for result in results:\n            json_result = json.loads(result)\n            if \"name\" in json_result and json_result[\"name\"] == \"test_my_model\":\n                assert json_result == expected_test_my_model\n\n        results = run_dbt(\n            [\n                \"list\",\n                \"--select\",\n                \"test_type:unit\",\n                \"--output\",\n                \"json\",\n                \"--output-keys\",\n                \"unique_id\",\n                \"model\",\n            ]\n        )\n        for result in results:\n            json_result = json.loads(result)\n            assert json_result[\"model\"] == \"my_model\"\n\n\nclass TestUnitTestListDisabled:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model_disabled_yml.sql\": \"select 1 as id\",\n            \"my_model_disabled_sql.sql\": my_model_disabled_sql,\n            \"my_model_disabled_yml.yml\": my_model_disabled_yml,\n            \"disabled_my_model_tests.yml\": disabled_my_model_tests_yml,\n        }\n\n    def test_disabled_unit_tests(self, project):\n        results = run_dbt([\"test\", \"--select\", \"test_type:unit\"])\n        assert len(results) == 0\n"
  },
  {
    "path": "tests/functional/unit_testing/test_ut_macros.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt\n\nmy_model_without_composition_sql = \"\"\"\n{{ config(materialized='table') }}\n{% set one = macro_one() %}\n{% set two = macro_two() %}\nselect 1 as id\n\"\"\"\n\nmy_model_with_composition_sql = \"\"\"\n{{ config(materialized='table') }}\n{% set one = macro_one() %}\n{% set two = macro_two() %}\n{% set one_plus_two = one + two %}\nselect 1 as id\n\"\"\"\n\nmy_macro_sql = \"\"\"\n{% macro macro_one() -%}\n    {{ return(1) }}\n{%- endmacro %}\n{% macro macro_two() -%}\n    {{ return(2) }}\n{%- endmacro %}\n\"\"\"\n\nmy_unit_test_yml = \"\"\"\nunit_tests:\n  - name: my_unit_test\n    model: my_model\n    given: []\n    expect:\n      rows:\n        - {id: 1}\n\"\"\"\n\n\nclass TestMacroWithoutComposition:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": my_model_without_composition_sql,\n            \"my_unit_test.yml\": my_unit_test_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"my_macros.sql\": my_macro_sql}\n\n    def test_macro_in_unit_test(self, project):\n        # Test that a model without macro composition properly resolves macro names in unit tests\n        run_dbt([\"test\"])\n\n\nclass TestMacroComposition:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": my_model_with_composition_sql,\n            \"my_unit_test.yml\": my_unit_test_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"my_macros.sql\": my_macro_sql}\n\n    def test_macro_composition_in_unit_test(self, project):\n        # Verify model works fine outside of unit testing\n        results = run_dbt([\"run\"])\n        assert len(results) == 1\n\n        # Test that a model with macro composition properly resolves macro names in unit tests\n        run_dbt([\"test\"])\n"
  },
  {
    "path": "tests/functional/unit_testing/test_ut_names.py",
    "content": "import pytest\nfrom fixtures import (\n    my_model_a_sql,\n    my_model_b_sql,\n    test_model_a_b_yml,\n    test_model_a_with_duplicate_test_name_yml,\n)\n\nfrom dbt.exceptions import DuplicateResourceNameError\nfrom dbt.tests.util import run_dbt, run_dbt_and_capture\n\n\nclass TestUnitTestDuplicateTestNamesAcrossModels:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model_a.sql\": my_model_a_sql,\n            \"my_model_b.sql\": my_model_b_sql,\n            \"test_model_a_b.yml\": test_model_a_b_yml,\n        }\n\n    def test_duplicate_test_names_across_models(self, project):\n        results = run_dbt([\"run\"])\n        assert len(results) == 2\n\n        # Select duplicate tests\n        results, log_output = run_dbt_and_capture([\"test\"], expect_pass=True)\n        assert len(results) == 2\n        assert {\"model.test.my_model_a\", \"model.test.my_model_b\"} == {\n            result.node.tested_node_unique_id for result in results\n        }\n        assert \"my_model_a::my_test_name\" in log_output\n        assert \"my_model_b::my_test_name\" in log_output\n\n        # Test select duplicates by by test name\n        results = run_dbt([\"test\", \"--select\", \"test_name:my_test_name\"])\n        assert len(results) == 2\n        assert {\"model.test.my_model_a\", \"model.test.my_model_b\"} == {\n            result.node.tested_node_unique_id for result in results\n        }\n        assert \"my_model_a::my_test_name\" in log_output\n        assert \"my_model_b::my_test_name\" in log_output\n\n        results = run_dbt([\"test\", \"--select\", \"my_model_a,test_name:my_test_name\"])\n        assert len(results) == 1\n        assert results[0].node.tested_node_unique_id == \"model.test.my_model_a\"\n\n        results = run_dbt([\"test\", \"--select\", \"my_model_b,test_name:my_test_name\"])\n        assert len(results) == 1\n        assert results[0].node.tested_node_unique_id == \"model.test.my_model_b\"\n\n        # Test select by model name\n        results = run_dbt([\"test\", \"--select\", \"my_model_a\"])\n        assert len(results) == 1\n        assert results[0].node.tested_node_unique_id == \"model.test.my_model_a\"\n\n        results = run_dbt([\"test\", \"--select\", \"my_model_b\"])\n        assert len(results) == 1\n        assert results[0].node.tested_node_unique_id == \"model.test.my_model_b\"\n\n\nclass TestUnitTestDuplicateTestNamesWithinModel:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model_a.sql\": my_model_a_sql,\n            \"test_model_a.yml\": test_model_a_with_duplicate_test_name_yml,\n        }\n\n    def test_duplicate_test_names_within_model(self, project):\n        with pytest.raises(DuplicateResourceNameError):\n            run_dbt([\"run\"])\n"
  },
  {
    "path": "tests/functional/unit_testing/test_ut_overrides.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt\n\nmy_model_with_macros = \"\"\"\nSELECT\n{{ current_timestamp() }} as global_current_timestamp,\n{{ dbt.current_timestamp() }} as dbt_current_timestamp,\n{{ dbt.type_int() }} as dbt_type_int,\n{{ my_macro() }} as user_defined_my_macro,\n{{ dbt_utils.generate_surrogate_key() }} as package_defined_macro\n\"\"\"\n\ntest_my_model_with_macros = \"\"\"\nunit_tests:\n  - name: test_macro_overrides\n    model: my_model_with_macros\n    overrides:\n      macros:\n        current_timestamp: \"'current_timestamp_override'\"\n        dbt.type_int: \"'dbt_macro_override'\"\n        my_macro: \"'global_user_defined_macro_override'\"\n        dbt_utils.generate_surrogate_key: \"'package_macro_override'\"\n    given: []\n    expect:\n      rows:\n        - global_current_timestamp: \"current_timestamp_override\"\n          dbt_current_timestamp: \"current_timestamp_override\"\n          dbt_type_int: \"dbt_macro_override\"\n          user_defined_my_macro: \"global_user_defined_macro_override\"\n          package_defined_macro: \"package_macro_override\"\n\"\"\"\n\nMY_MACRO_SQL = \"\"\"\n{% macro my_macro() -%}\n  {{ test }}\n{%- endmacro %}\n\"\"\"\n\n\nclass TestUnitTestingMacroOverrides:\n    @pytest.fixture(scope=\"class\")\n    def packages(self):\n        return {\n            \"packages\": [\n                {\n                    \"package\": \"dbt-labs/dbt_utils\",\n                    \"version\": \"1.1.1\",\n                },\n            ]\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model_with_macros.sql\": my_model_with_macros,\n            \"test_my_model_with_macros.yml\": test_my_model_with_macros,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"my_macro.sql\": MY_MACRO_SQL}\n\n    def test_macro_overrides(self, project):\n        run_dbt([\"deps\"])\n\n        # Select by model name\n        results = run_dbt([\"test\", \"--select\", \"my_model_with_macros\"], expect_pass=True)\n        assert len(results) == 1\n"
  },
  {
    "path": "tests/functional/unit_testing/test_ut_resource_types.py",
    "content": "import pytest\nfrom fixtures import (  # noqa: F401\n    my_model_a_sql,\n    my_model_b_sql,\n    my_model_sql,\n    test_my_model_a_yml,\n    test_my_model_pass_yml,\n)\n\nfrom dbt.tests.util import run_dbt\n\nEXPECTED_MODELS = [\n    \"test.my_model\",\n    \"test.my_model_a\",\n    \"test.my_model_b\",\n]\n\nEXPECTED_DATA_TESTS = [\n    \"test.not_null_my_model_a_a\",\n    \"test.not_null_my_model_a_id\",\n]\n\nEXPECTED_UNIT_TESTS = [\n    \"unit_test:test.test_my_model\",\n]\n\n\nclass TestUnitTestResourceTypes:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": my_model_sql,\n            \"my_model_a.sql\": my_model_a_sql,\n            \"my_model_b.sql\": my_model_b_sql,\n            \"test_my_model.yml\": test_my_model_pass_yml,\n            \"test_my_model_a.yml\": test_my_model_a_yml,\n        }\n\n    def test_unit_test_list(self, project):\n        results = run_dbt([\"run\"])\n\n        # unit tests\n        results = run_dbt([\"list\", \"--resource-type\", \"unit_test\"])\n        assert sorted(results) == EXPECTED_UNIT_TESTS\n\n        results = run_dbt([\"list\", \"--exclude-resource-types\", \"model\", \"test\"])\n        assert sorted(results) == EXPECTED_UNIT_TESTS\n\n        results = run_dbt([\"test\", \"--resource-type\", \"unit_test\"])\n        assert len(results) == len(EXPECTED_UNIT_TESTS)\n\n        results = run_dbt([\"test\", \"--exclude-resource-types\", \"model\", \"test\"])\n        assert len(results) == len(EXPECTED_UNIT_TESTS)\n\n        # data tests\n        results = run_dbt([\"list\", \"--resource-type\", \"test\"])\n        assert sorted(results) == EXPECTED_DATA_TESTS\n\n        results = run_dbt([\"list\", \"--exclude-resource-types\", \"unit_test\", \"model\"])\n        assert sorted(results) == EXPECTED_DATA_TESTS\n\n        results = run_dbt([\"test\", \"--resource-type\", \"test\"])\n        assert len(results) == len(EXPECTED_DATA_TESTS)\n\n        results = run_dbt([\"test\", \"--exclude-resource-types\", \"unit_test\", \"model\"])\n        assert len(results) == len(EXPECTED_DATA_TESTS)\n\n        results = run_dbt([\"build\", \"--resource-type\", \"test\"])\n        assert len(results) == len(EXPECTED_DATA_TESTS)\n\n        results = run_dbt([\"build\", \"--exclude-resource-types\", \"unit_test\", \"model\"])\n        assert len(results) == len(EXPECTED_DATA_TESTS)\n\n        # models\n        results = run_dbt([\"list\", \"--resource-type\", \"model\"])\n        assert sorted(results) == EXPECTED_MODELS\n\n        results = run_dbt([\"list\", \"--exclude-resource-type\", \"unit_test\", \"test\"])\n        assert sorted(results) == EXPECTED_MODELS\n\n        results = run_dbt([\"test\", \"--resource-type\", \"model\"])\n        assert len(results) == 0\n\n        results = run_dbt([\"test\", \"--exclude-resource-types\", \"unit_test\", \"test\"])\n        assert len(results) == 0\n\n        results = run_dbt([\"build\", \"--resource-type\", \"model\"])\n        assert len(results) == len(EXPECTED_MODELS)\n\n        results = run_dbt([\"build\", \"--exclude-resource-type\", \"unit_test\", \"test\"])\n        assert len(results) == len(EXPECTED_MODELS)\n"
  },
  {
    "path": "tests/functional/unit_testing/test_ut_snapshot_dependency.py",
    "content": "import pytest\n\nfrom dbt.contracts.results import RunStatus, TestStatus\nfrom dbt.tests.util import run_dbt\n\nraw_customers_csv = \"\"\"id,first_name,last_name,email,gender,ip_address,updated_at\n1,'Judith','Kennedy','(not provided)','Female','54.60.24.128','2015-12-24 12:19:28'\n2,'Arthur','Kelly','(not provided)','Male','62.56.24.215','2015-10-28 16:22:15'\n3,'Rachel','Moreno','rmoreno2@msu.edu','Female','31.222.249.23','2016-04-05 02:05:30'\n4,'Ralph','Turner','rturner3@hp.com','Male','157.83.76.114','2016-08-08 00:06:51'\n5,'Laura','Gonzales','lgonzales4@howstuffworks.com','Female','30.54.105.168','2016-09-01 08:25:38'\n6,'Katherine','Lopez','klopez5@yahoo.co.jp','Female','169.138.46.89','2016-08-30 18:52:11'\n7,'Jeremy','Hamilton','jhamilton6@mozilla.org','Male','231.189.13.133','2016-07-17 02:09:46'\n\"\"\"\n\ntop_level_domains_csv = \"\"\"id,domain\n3,'msu.edu'\n4,'hp.com'\n5,'howstuffworks.com'\n6,'yahoo.co.jp'\n7,'mozilla.org'\n\"\"\"\n\nsnapshots_users__snapshot_sql = \"\"\"\n{% snapshot snapshot_users %}\n\n    {{\n        config(\n            target_database=var('target_database', database),\n            target_schema=schema,\n            unique_key='id || ' ~ \"'-'\" ~ ' || first_name',\n            strategy='check',\n            check_cols=['email'],\n        )\n    }}\n    select *, split_part(email, '@', 2) as domain from {{target.database}}.{{schema}}.raw_customers\n\n{% endsnapshot %}\n\"\"\"\n\nunit_test_yml = \"\"\"\nsources:\n  - name: seed_sources\n    schema: \"{{ target.schema }}\"\n    tables:\n      - name: top_level_domains\n        columns:\n          - name: id\n          - name: domain\n\nunit_tests:\n  - name: test_is_valid_email_address\n    model: customers\n    given:\n      - input: ref('snapshot_users')\n        rows:\n         - {id: 1, email: cool@example.com,     domain: example.com}\n         - {id: 2, email: cool@unknown.com,     domain: unknown.com}\n         - {id: 3, email: badgmail.com,         domain: gmailcom}\n         - {id: 4, email: missingdot@gmailcom,  domain: gmailcom}\n      - input: source('seed_sources', 'top_level_domains')\n        rows:\n         - {domain: example.com}\n         - {domain: gmail.com}\n    expect:\n      rows:\n        - {id: 1, is_valid_email_address: true}\n        - {id: 2, is_valid_email_address: false}\n        - {id: 3, is_valid_email_address: false}\n        - {id: 4, is_valid_email_address: false}\n\n  - name: fail_is_valid_email_address\n    model: customers\n    given:\n      - input: ref('snapshot_users')\n        rows:\n        - {id: 1, email: cool@example.com,     domain: example.com}\n      - input: source('seed_sources', 'top_level_domains')\n        rows:\n        - {domain: example.com}\n        - {domain: gmail.com}\n    expect:\n      rows:\n        - {id: 1, is_valid_email_address: false}\n\"\"\"\n\ncustomers_sql = \"\"\"\nwith snapshot_users as (\nselect * from {{ ref('snapshot_users') }}\n),\n\ntop_level_domains as (\nselect * from {{ source('seed_sources', 'top_level_domains') }}\n),\nmatched_values as (\n    select\n        snapshot_users.*,\n        case when exists (\n            select 1 from top_level_domains\n            where top_level_domains.domain = snapshot_users.domain\n        ) then true else false end as is_valid_email_address\n    from\n        snapshot_users\n)\n\nselect * from matched_values\n\"\"\"\n\n\nclass TestUnitTestSnapshotDependency:\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\n            \"raw_customers.csv\": raw_customers_csv,\n            \"top_level_domains.csv\": top_level_domains_csv,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"customers.sql\": customers_sql,\n            \"unit_tests.yml\": unit_test_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def snapshots(self):\n        return {\n            \"snapshot_users.sql\": snapshots_users__snapshot_sql,\n        }\n\n    def test_snapshot_dependency(self, project):\n        seed_results = run_dbt([\"seed\"])\n        len(seed_results) == 2\n        snapshot_results = run_dbt([\"snapshot\"])\n        len(snapshot_results) == 1\n        model_results = run_dbt([\"run\"])\n        len(model_results) == 1\n\n        # test passing unit test\n        results = run_dbt([\"test\", \"--select\", \"test_name:test_is_valid_email_address\"])\n        assert len(results) == 1\n\n        # test failing unit test\n        results = run_dbt(\n            [\"test\", \"--select\", \"test_name:fail_is_valid_email_address\"], expect_pass=False\n        )\n        assert len(results) == 1\n        assert results[0].status == TestStatus.Fail\n\n        # test all with build\n        results = run_dbt([\"build\"], expect_pass=False)\n\n        for result in results:\n            if result.node.unique_id == \"unit_test.test.customers.fail_is_valid_email_address\":\n                # This will always fail, regarless of order executed\n                assert result.status == TestStatus.Fail\n            elif result.node.unique_id == \"unit_test.test.customers.test_is_valid_email_address\":\n                # there's no guarantee that the order of the results will be the same.  If the\n                # failed test runs first this one gets skipped.  If this runs first it passes.\n                assert result.status in [TestStatus.Pass, TestStatus.Skipped]\n            elif result.node.unique_id == \"model.test.customers\":\n                # This is always skipped because one test always fails\n                assert result.status == RunStatus.Skipped\n        assert len(results) == 6\n"
  },
  {
    "path": "tests/functional/unit_testing/test_ut_sources.py",
    "content": "from copy import deepcopy\n\nimport pytest\n\nfrom dbt.contracts.results import RunStatus, TestStatus\nfrom dbt.tests.util import run_dbt, write_file\n\nraw_customers_csv = \"\"\"id,first_name,last_name,email\n1,Michael,Perez,mperez0@chronoengine.com\n2,Shawn,Mccoy,smccoy1@reddit.com\n3,Kathleen,Payne,kpayne2@cargocollective.com\n4,Jimmy,Cooper,jcooper3@cargocollective.com\n5,Katherine,Rice,krice4@typepad.com\n6,Sarah,Ryan,sryan5@gnu.org\n7,Martin,Mcdonald,mmcdonald6@opera.com\n8,Frank,Robinson,frobinson7@wunderground.com\n9,Jennifer,Franklin,jfranklin8@mail.ru\n10,Henry,Welch,hwelch9@list-manage.com\n\"\"\"\n\nschema_sources_yml = \"\"\"\nsources:\n  - name: seed_sources\n    schema: \"{{ target.schema }}\"\n    tables:\n      - name: raw_customers\n        columns:\n          - name: id\n            data_tests:\n              - not_null:\n                  severity: \"{{ 'error' if target.name == 'prod' else 'warn' }}\"\n              - unique\n          - name: first_name\n          - name: last_name\n          - name: email\nunit_tests:\n  - name: test_customers\n    model: customers\n    given:\n      - input: source('seed_sources', 'raw_customers')\n        rows:\n          - {id: 1, first_name: Emily}\n    expect:\n      rows:\n        - {id: 1, first_name: Emily}\n\"\"\"\n\ncustomers_sql = \"\"\"\nselect * from {{ source('seed_sources', 'raw_customers') }}\n\"\"\"\n\nfailing_test_schema_yml = \"\"\"\n  - name: fail_test_customers\n    model: customers\n    given:\n      - input: source('seed_sources', 'raw_customers')\n        rows:\n          - {id: 1, first_name: Emily}\n    expect:\n      rows:\n        - {id: 1, first_name: Joan}\n\"\"\"\n\n\nschema_duplicate_source_names_yml = \"\"\"\nsources:\n  - name: seed_sources\n    schema: \"{{ target.schema }}\"\n    tables:\n      - name: raw_customers\n  - name: seed_sources_2\n    schema: \"{{ target.schema }}_other\"\n    tables:\n      - name: raw_customers\n\nunit_tests:\n  - name: test_customers\n    model: customers_duplicate_source_names\n    given:\n      - input: source('seed_sources', 'raw_customers')\n        rows:\n          - {id: 1, first_name: Emily}\n      - input: source('seed_sources_2', 'raw_customers')\n        rows:\n          - {id: 2, first_name: Michelle}\n    expect:\n      rows:\n        - {id: 1, first_name: Emily}\n        - {id: 2, first_name: Michelle}\n\"\"\"\n\ncustomers_duplicate_source_names_sql = \"\"\"\nselect * from {{ source('seed_sources', 'raw_customers') }}\nunion all\nselect * from {{ source('seed_sources_2', 'raw_customers') }}\n\"\"\"\n\n\nclass TestUnitTestSourceInput:\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\n            \"raw_customers.csv\": raw_customers_csv,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"customers.sql\": customers_sql,\n            \"sources.yml\": schema_sources_yml,\n        }\n\n    def test_source_input(self, project):\n        results = run_dbt([\"seed\"])\n        results = run_dbt([\"run\"])\n        len(results) == 1\n\n        results = run_dbt([\"test\", \"--select\", \"test_type:unit\"])\n        assert len(results) == 1\n\n        results = run_dbt([\"build\"])\n        assert len(results) == 5\n        result_unique_ids = [result.node.unique_id for result in results]\n        assert len(result_unique_ids) == 5\n        assert \"unit_test.test.customers.test_customers\" in result_unique_ids\n\n        # write failing unit test\n        write_file(\n            schema_sources_yml + failing_test_schema_yml,\n            project.project_root,\n            \"models\",\n            \"sources.yml\",\n        )\n        results = run_dbt([\"build\"], expect_pass=False)\n        for result in results:\n            if result.node.unique_id == \"model.test.customers\":\n                assert result.status == RunStatus.Skipped\n            elif result.node.unique_id == \"unit_test.test.customers.fail_test_customers\":\n                assert result.status == TestStatus.Fail\n        assert len(results) == 6\n\n\nclass TestUnitTestSourceInputSameNames:\n    @pytest.fixture(scope=\"class\")\n    def other_schema(self, unique_schema):\n        return unique_schema + \"_other\"\n\n    @pytest.fixture(scope=\"class\")\n    def profiles_config_update(self, dbt_profile_target, unique_schema, other_schema):\n        outputs = {\"default\": dbt_profile_target, \"otherschema\": deepcopy(dbt_profile_target)}\n        outputs[\"default\"][\"schema\"] = unique_schema\n        outputs[\"otherschema\"][\"schema\"] = other_schema\n        return {\"test\": {\"outputs\": outputs, \"target\": \"default\"}}\n\n    @pytest.fixture(scope=\"class\")\n    def seeds(self):\n        return {\n            \"raw_customers.csv\": raw_customers_csv,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"customers_duplicate_source_names.sql\": customers_duplicate_source_names_sql,\n            \"sources.yml\": schema_duplicate_source_names_yml,\n        }\n\n    def test_source_input_same_names(self, project, other_schema):\n        results = run_dbt([\"seed\"])\n\n        project.create_test_schema(schema_name=other_schema)\n        results = run_dbt([\"seed\", \"--target\", \"otherschema\"])\n\n        results = run_dbt([\"test\", \"--select\", \"test_type:unit\"])\n        assert len(results) == 1\n"
  },
  {
    "path": "tests/functional/unit_testing/test_ut_variables.py",
    "content": "import pytest\n\nfrom dbt.tests.util import run_dbt, run_dbt_and_capture\n\ndbt_project_yml = \"\"\"\nvars:\n  columns_list_one:\n    - column_a\n    - column_b\n\n  columns_list_two:\n    - column_c\n\"\"\"\n\nmy_model_one_variable_sql = \"\"\"\n{{ config(materialized='table') }}\n-- {{ get_columns(include=var('columns_list_one'))}}\nselect 1 as id\n\"\"\"\n\nmy_model_two_variables_sql = \"\"\"\n{{ config(materialized='table') }}\n-- {{ get_columns(include=var('columns_list_one') + var('columns_list_two'))}}\nselect 1 as id\n\"\"\"\n\nmy_macro_sql = \"\"\"\n{%- macro get_columns(include=[]) -%}\n    {%- for col in include -%}\n        {{ col }}{% if not loop.last %}, {% endif %}\n    {%- endfor -%}\n{%- endmacro -%}\n\"\"\"\n\nmy_unit_test_yml = \"\"\"\nunit_tests:\n  - name: my_unit_test\n    model: my_model\n    given: []\n    expect:\n      rows:\n        - {id: 1}\n\"\"\"\n\n\nclass TestUnitTestOneVariables:\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return dbt_project_yml\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": my_model_one_variable_sql,\n            \"my_unit_test.yml\": my_unit_test_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"my_macros.sql\": my_macro_sql}\n\n    def test_one_variable_as_input_to_macro(self, project):\n        run_dbt_and_capture([\"test\"], expect_pass=True)\n\n\nclass TestUnitTestTwoVariables:\n    @pytest.fixture(scope=\"class\")\n    def project_config_update(self):\n        return dbt_project_yml\n\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model.sql\": my_model_two_variables_sql,\n            \"my_unit_test.yml\": my_unit_test_yml,\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def macros(self):\n        return {\"my_macros.sql\": my_macro_sql}\n\n    def test_two_variables_as_input_to_macro(self, project):\n        # Verify model works fine outside of unit testing\n        results = run_dbt([\"run\"])\n        assert len(results) == 1\n\n        run_dbt([\"test\"])\n"
  },
  {
    "path": "tests/functional/unit_testing/test_ut_versions.py",
    "content": "import pytest\n\nfrom dbt.exceptions import ParsingError, YamlParseDictError\nfrom dbt.tests.util import get_unique_ids_in_results, run_dbt, write_file\nfrom tests.functional.unit_testing.fixtures import (\n    my_model_a_sql,\n    my_model_b_sql,\n    my_model_sql,\n    my_model_v1_sql,\n    my_model_v2_sql,\n    my_model_v3_sql,\n    my_model_version_ref_sql,\n    my_model_versioned_no_2_yml,\n    my_model_versioned_yml,\n    test_my_model_all_versions_yml,\n    test_my_model_exclude_versions_yml,\n    test_my_model_include_exclude_versions_yml,\n    test_my_model_include_unversioned_yml,\n    test_my_model_include_versions_yml,\n    test_my_model_version_ref_yml,\n)\n\n\n# test with no version specified, then add an exclude version, then switch\n# to include version and make sure the right unit tests are generated for each\nclass TestVersions:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model_a.sql\": my_model_a_sql,\n            \"my_model_b.sql\": my_model_b_sql,\n            \"my_model_v1.sql\": my_model_v1_sql,\n            \"my_model_v2.sql\": my_model_v2_sql,\n            \"my_model_v3.sql\": my_model_v3_sql,\n            \"schema.yml\": my_model_versioned_yml,\n            \"unit_tests.yml\": test_my_model_all_versions_yml,\n        }\n\n    def test_versions(self, project):\n        results = run_dbt([\"run\"])\n        assert len(results) == 5\n\n        # \"my_model\" has three versions: 1, 2, 3\n        # There is a single unit_test which doesn't specify a version,\n        # so it should run for all versions.\n        results = run_dbt([\"test\"])\n        assert len(results) == 3\n        unique_ids = get_unique_ids_in_results(results)\n        expected_ids = [\n            \"unit_test.test.my_model.test_my_model_v1\",\n            \"unit_test.test.my_model.test_my_model_v2\",\n            \"unit_test.test.my_model.test_my_model_v3\",\n        ]\n        assert sorted(expected_ids) == sorted(unique_ids)\n\n        # Select tests for a single versioned model\n        results = run_dbt([\"test\", \"--select\", \"my_model.v2\"])\n        assert len(results) == 1\n        unique_ids = get_unique_ids_in_results(results)\n        assert unique_ids == [\"unit_test.test.my_model.test_my_model_v2\"]\n\n        # select tests for all my_models\n        results = run_dbt([\"test\", \"--select\", \"my_model\"])\n        assert len(results) == 3\n        unique_ids = get_unique_ids_in_results(results)\n        assert sorted(expected_ids) == sorted(unique_ids)\n\n        # with an exclude version specified, should create a separate unit test\n        # for each version except the excluded version (v2)\n        write_file(\n            test_my_model_exclude_versions_yml, project.project_root, \"models\", \"unit_tests.yml\"\n        )\n\n        results = run_dbt([\"test\"])\n        assert len(results) == 2\n        unique_ids = get_unique_ids_in_results(results)\n        # v2 model should be excluded\n        expected_ids = [\n            \"unit_test.test.my_model.test_my_model_v1\",\n            \"unit_test.test.my_model.test_my_model_v3\",\n        ]\n        assert sorted(expected_ids) == sorted(unique_ids)\n\n        # test with an include version specified, should create a single unit test for\n        # only the version specified (2)\n        write_file(\n            test_my_model_include_versions_yml, project.project_root, \"models\", \"unit_tests.yml\"\n        )\n\n        results = run_dbt([\"test\"])\n        assert len(results) == 1\n        unique_ids = get_unique_ids_in_results(results)\n        # v2 model should be only one included\n        expected_ids = [\n            \"unit_test.test.my_model.test_my_model_v2\",\n        ]\n        assert sorted(expected_ids) == sorted(unique_ids)\n\n        # Change to remove version 2 of model and get an error\n        write_file(my_model_versioned_no_2_yml, project.project_root, \"models\", \"schema.yml\")\n        with pytest.raises(ParsingError):\n            run_dbt([\"test\"])\n\n\n# test with an include and exclude version specified, should raise an error\nclass TestIncludeExcludeSpecified:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model_a.sql\": my_model_a_sql,\n            \"my_model_b.sql\": my_model_b_sql,\n            \"my_model_v1.sql\": my_model_v1_sql,\n            \"my_model_v2.sql\": my_model_v2_sql,\n            \"my_model_v3.sql\": my_model_v3_sql,\n            \"schema.yml\": my_model_versioned_yml,\n            \"unit_tests.yml\": test_my_model_include_exclude_versions_yml,\n        }\n\n    def test_include_exclude_specified(self, project):\n        with pytest.raises(YamlParseDictError):\n            run_dbt([\"parse\"])\n\n\n# test with an include for an unversioned model, should error\nclass TestIncludeUnversioned:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model_a.sql\": my_model_a_sql,\n            \"my_model_b.sql\": my_model_b_sql,\n            \"my_model.sql\": my_model_sql,\n            \"unit_tests.yml\": test_my_model_include_unversioned_yml,\n        }\n\n    def test_include_unversioned(self, project):\n        with pytest.raises(ParsingError):\n            run_dbt([\"parse\"])\n\n\n# test specifying the fixture version with {{ ref(name, version) }}\nclass TestVersionedFixture:\n    @pytest.fixture(scope=\"class\")\n    def models(self):\n        return {\n            \"my_model_a.sql\": my_model_a_sql,\n            \"my_model_b.sql\": my_model_b_sql,\n            \"my_model_v1.sql\": my_model_v1_sql,\n            \"my_model_v2.sql\": my_model_v2_sql,\n            \"my_model_v3.sql\": my_model_v3_sql,\n            \"my_model_version_ref.sql\": my_model_version_ref_sql,\n            \"schema.yml\": my_model_versioned_yml,\n            \"unit_tests.yml\": test_my_model_version_ref_yml,\n        }\n\n    def test_versioned_fixture(self, project):\n        results = run_dbt([\"run\"])\n        assert len(results) == 6\n\n        results = run_dbt([\"test\"])\n        assert len(results) == 1\n\n        unique_ids = get_unique_ids_in_results(results)\n        # v2 model should be only one included\n        expected_ids = [\"unit_test.test.my_model_version_ref.test_my_model_version_ref\"]\n        assert expected_ids == unique_ids\n"
  },
  {
    "path": "tests/functional/utils.py",
    "content": "import os\nfrom contextlib import contextmanager\nfrom datetime import datetime\nfrom pathlib import Path\nfrom typing import Optional\n\n\n@contextmanager\ndef up_one(return_path: Optional[Path] = None):\n    current_path = Path.cwd()\n    os.chdir(\"../\")\n    try:\n        yield\n    finally:\n        os.chdir(return_path or current_path)\n\n\ndef is_aware(dt: datetime) -> bool:\n    return dt.tzinfo is not None and dt.tzinfo.utcoffset(dt) is not None\n"
  },
  {
    "path": "tests/unit/README.md",
    "content": "# Unit test README\n\n\n### The Why\nWe need to ensure that we can go from objects to dictionaries and back without any\nchanges. If some property or property value of an object gets dropped, added, or modified\nwhile transitioning between its different possible representations, that is problematic.\n\n### The How \nThe easiest way to ensure things don't get droped, added, or modified is by starting\nwith an object, dictifying it, moving back to an object, and then asserting that everything\nis equivalent. There are many potential edge cases though: what about optional fields, what\nabout lists of things, and etc. To address this we use hypothesis, which will build multiple\nversions of the object we're interested in testing, and run the different generated versions\nof the object through the test. This gives us confidence that for any allowable configuration\nof an object, state is not changed when moving back and forth betweeen the python object\nversion and the seralized version.\n\n### The What\n\n- We test concrete classes in the codebase and do not test abstract classes as they are implementation details. [reference](https://enterprisecraftsmanship.com/posts/how-to-unit-test-an-abstract-class/)\n"
  },
  {
    "path": "tests/unit/__init__.py",
    "content": "# Unit testing directory\n"
  },
  {
    "path": "tests/unit/artifacts/test_base_resource.py",
    "content": "from dataclasses import dataclass\n\nimport pytest\n\nfrom dbt.artifacts.resources.base import BaseResource\nfrom dbt.artifacts.resources.types import NodeType\n\n\n@dataclass\nclass BaseResourceWithDefaultField(BaseResource):\n    field_with_default: bool = True\n\n\nclass TestMinorSchemaChange:\n    @pytest.fixture\n    def base_resource(self):\n        return BaseResource(\n            name=\"test\",\n            resource_type=NodeType.Model,\n            package_name=\"test_package\",\n            path=\"test_path\",\n            original_file_path=\"test_original_file_path\",\n            unique_id=\"test_unique_id\",\n        )\n\n    @pytest.fixture\n    def base_resource_new_default_field(self):\n        return BaseResourceWithDefaultField(\n            name=\"test\",\n            resource_type=NodeType.Model,\n            package_name=\"test_package\",\n            path=\"test_path\",\n            original_file_path=\"test_original_file_path\",\n            unique_id=\"test_unique_id\",\n            field_with_default=False,\n        )\n\n    def test_serializing_new_default_field_is_backward_compatabile(\n        self, base_resource_new_default_field\n    ):\n        # old code (using old class) can create an instance of itself given new data (new class)\n        BaseResource.from_dict(base_resource_new_default_field.to_dict())\n\n    def test_serializing_new_default_field_is_forward_compatible(self, base_resource):\n        # new code (using new class) can create an instance of itself given old data (old class)\n        BaseResourceWithDefaultField.from_dict(base_resource.to_dict())\n\n    def test_serializing_removed_default_field_is_backward_compatabile(self, base_resource):\n        # old code (using old class with default field) can create an instance of itself given new data (class w/o default field)\n        old_resource = BaseResourceWithDefaultField.from_dict(base_resource.to_dict())\n        # set to the default value when not provided in data\n        assert old_resource.field_with_default is True\n\n    def test_serializing_removed_default_field_is_forward_compatible(\n        self, base_resource_new_default_field\n    ):\n        # new code (using class without default field) can create an instance of itself given old data (class with old field)\n        BaseResource.from_dict(base_resource_new_default_field.to_dict())\n"
  },
  {
    "path": "tests/unit/artifacts/test_run_execution_result.py",
    "content": "from dateutil.tz import tzutc\nfrom hypothesis import given\nfrom hypothesis.strategies import (\n    builds,\n    composite,\n    dictionaries,\n    floats,\n    lists,\n    sampled_from,\n    text,\n)\n\nfrom dbt.contracts.results import RunExecutionResult, RunResult, RunStatus, TimingInfo\nfrom tests.unit.fixtures import model_node\n\n\n@composite\ndef run_result_strategy(draw):\n    node = model_node()\n    status = draw(sampled_from(list(RunStatus)))\n    message = draw(text(min_size=0, max_size=30) | sampled_from([None]))\n    result = RunResult.from_node(node=node, status=status, message=message)\n    result.execution_time = draw(floats(min_value=0.0, max_value=30.0))\n    result.timing = draw(lists(builds(TimingInfo), max_size=2))\n\n    return result\n\n\n@given(\n    args=dictionaries(text(min_size=1, max_size=10), text(min_size=1, max_size=10)),\n    elapsed_time=floats(min_value=0.0, max_value=30.0),\n    results=lists(run_result_strategy(), min_size=1, max_size=3),\n)\ndef test_run_execution_result_serialization(args, elapsed_time, results):\n\n    obj = RunExecutionResult(results=results, elapsed_time=elapsed_time, args=args)\n    obj_from_dict = RunExecutionResult.from_dict(obj.to_dict())\n\n    assert obj_from_dict.args == obj.args\n    assert len(obj_from_dict.results) == len(obj.results)\n\n    assert obj.generated_at.tzinfo is None\n    assert obj_from_dict.generated_at.tzinfo == tzutc()\n    assert obj_from_dict.generated_at.replace(tzinfo=None) == obj.generated_at\n\n    for original, deserialized in zip(obj.results, obj_from_dict.results):\n        assert original.node.created_at == deserialized.node.created_at\n"
  },
  {
    "path": "tests/unit/cli/test_flags.py",
    "content": "from pathlib import Path\nfrom typing import List, Optional\n\nimport click\nimport pytest\n\nfrom dbt.cli.exceptions import DbtUsageException\nfrom dbt.cli.flags import Flags\nfrom dbt.cli.main import cli\nfrom dbt.cli.types import Command\nfrom dbt.contracts.project import ProjectFlags\nfrom dbt.tests.util import rm_file, write_file\nfrom dbt_common.exceptions import DbtInternalError\nfrom dbt_common.helper_types import WarnErrorOptionsV2\n\n\nclass TestFlags:\n    def make_dbt_context(\n        self, context_name: str, args: List[str], parent: Optional[click.Context] = None\n    ) -> click.Context:\n        ctx = cli.make_context(context_name, args.copy(), parent)\n        return ctx\n\n    @pytest.fixture(scope=\"class\")\n    def run_context(self) -> click.Context:\n        return self.make_dbt_context(\"run\", [\"run\"])\n\n    @pytest.fixture\n    def project_flags(self) -> ProjectFlags:\n        return ProjectFlags()\n\n    def test_cli_args_unmodified(self):\n        args = [\"--target\", \"my_target\"]\n        args_before = args.copy()\n        self.make_dbt_context(\"context\", args)\n\n        assert args == args_before\n\n    def test_which(self, run_context):\n        flags = Flags(run_context)\n        assert flags.WHICH == \"run\"\n\n    @pytest.mark.parametrize(\"param\", cli.params)\n    def test_cli_group_flags_from_params(self, run_context, param):\n        flags = Flags(run_context)\n\n        if \"DEPRECATED_\" in param.name.upper():\n            assert not hasattr(flags, param.name.upper())\n            return\n\n        if param.name.upper() in (\"VERSION\", \"LOG_PATH\"):\n            return\n\n        assert hasattr(flags, param.name.upper())\n        assert getattr(flags, param.name.upper()) == run_context.params[param.name.lower()]\n\n    def test_log_path_default(self, run_context):\n        flags = Flags(run_context)\n        assert hasattr(flags, \"LOG_PATH\")\n        assert getattr(flags, \"LOG_PATH\") == Path(\"logs\")\n\n    def test_log_file_max_size_default(self, run_context):\n        flags = Flags(run_context)\n        assert hasattr(flags, \"LOG_FILE_MAX_BYTES\")\n        assert getattr(flags, \"LOG_FILE_MAX_BYTES\") == 10 * 1024 * 1024\n\n    @pytest.mark.parametrize(\n        \"set_stats_param,do_not_track,expected_anonymous_usage_stats\",\n        [\n            # set_stats_param = default, DNT = True, expected = False\n            (\"default\", \"1\", False),\n            (\"default\", \"t\", False),\n            (\"default\", \"true\", False),\n            (\"default\", \"y\", False),\n            (\"default\", \"yes\", False),\n            # set_stats_param = default, DNT = false, expected = True\n            (\"default\", \"false\", True),\n            (\"default\", \"anything\", True),\n            # set_stats_param = True, DNT = True, expected = False\n            (True, \"1\", False),\n            (True, \"t\", False),\n            (True, \"true\", False),\n            (True, \"y\", False),\n            (True, \"yes\", False),\n            # set_stats_param = True, DNT = false, expected = True\n            (True, \"false\", True),\n            (True, \"anything\", True),\n            (True, \"2\", True),\n            # set_stats_param = False, DNT = True, expected = False\n            (False, \"1\", False),\n            (False, \"t\", False),\n            (False, \"true\", False),\n            (False, \"y\", False),\n            (False, \"yes\", False),\n            # set_stats_param = False, DNT = False, expected = False\n            (False, \"false\", False),\n            (False, \"anything\", False),\n            (False, \"2\", False),\n        ],\n    )\n    def test_anonymous_usage_state(\n        self,\n        monkeypatch,\n        run_context,\n        set_stats_param,\n        do_not_track,\n        expected_anonymous_usage_stats,\n    ):\n        monkeypatch.setenv(\"DO_NOT_TRACK\", do_not_track)\n        if set_stats_param != \"default\":\n            run_context.params[\"send_anonymous_usage_stats\"] = set_stats_param\n        flags = Flags(run_context)\n        assert flags.SEND_ANONYMOUS_USAGE_STATS == expected_anonymous_usage_stats\n\n    def test_resource_types(self, monkeypatch):\n        monkeypatch.setenv(\"DBT_RESOURCE_TYPES\", \"model\")\n        build_context = self.make_dbt_context(\"build\", [\"build\"])\n        build_context.params[\"resource_types\"] = (\"unit_test\",)\n        flags = Flags(build_context)\n        assert flags.resource_types == (\"unit_test\",)\n\n    def test_empty_project_flags_uses_default(self, run_context, project_flags):\n        flags = Flags(run_context, project_flags)\n        assert flags.USE_COLORS == run_context.params[\"use_colors\"]\n\n    def test_none_project_flags_uses_default(self, run_context):\n        flags = Flags(run_context, None)\n        assert flags.USE_COLORS == run_context.params[\"use_colors\"]\n\n    def test_prefer_project_flags_to_default(self, run_context, project_flags):\n        project_flags.use_colors = False\n        # ensure default value is not the same as user config\n        assert run_context.params[\"use_colors\"] is not project_flags.use_colors\n\n        flags = Flags(run_context, project_flags)\n        assert flags.USE_COLORS == project_flags.use_colors\n\n    def test_prefer_param_value_to_project_flags(self):\n        project_flags = ProjectFlags(use_colors=False)\n        context = self.make_dbt_context(\"run\", [\"--use-colors\", \"True\", \"run\"])\n\n        flags = Flags(context, project_flags)\n        assert flags.USE_COLORS\n\n    def test_prefer_env_to_project_flags(self, monkeypatch, project_flags):\n        project_flags.use_colors = False\n        monkeypatch.setenv(\"DBT_USE_COLORS\", \"True\")\n        context = self.make_dbt_context(\"run\", [\"run\"])\n\n        flags = Flags(context, project_flags)\n        assert flags.USE_COLORS\n\n    def test_mutually_exclusive_options_passed_separately(self):\n        \"\"\"Assert options that are mutually exclusive can be passed separately without error\"\"\"\n        warn_error_context = self.make_dbt_context(\"run\", [\"--warn-error\", \"run\"])\n\n        flags = Flags(warn_error_context)\n        assert flags.WARN_ERROR\n\n        warn_error_options_context = self.make_dbt_context(\n            \"run\", [\"--warn-error-options\", '{\"error\": \"all\"}', \"run\"]\n        )\n        flags = Flags(warn_error_options_context)\n        assert flags.WARN_ERROR_OPTIONS == WarnErrorOptionsV2(error=\"all\")\n\n    def test_mutually_exclusive_options_from_cli(self):\n        context = self.make_dbt_context(\n            \"run\", [\"--warn-error\", \"--warn-error-options\", '{\"error\": \"all\"}', \"run\"]\n        )\n\n        with pytest.raises(DbtUsageException):\n            Flags(context)\n\n    @pytest.mark.parametrize(\"warn_error\", [True, False])\n    def test_mutually_exclusive_options_from_project_flags(self, warn_error, project_flags):\n        project_flags.warn_error = warn_error\n        context = self.make_dbt_context(\"run\", [\"--warn-error-options\", '{\"error\": \"all\"}', \"run\"])\n\n        with pytest.raises(DbtUsageException):\n            Flags(context, project_flags)\n\n    @pytest.mark.parametrize(\"warn_error\", [\"True\", \"False\"])\n    def test_mutually_exclusive_options_from_envvar(self, warn_error, monkeypatch):\n        monkeypatch.setenv(\"DBT_WARN_ERROR\", warn_error)\n        monkeypatch.setenv(\"DBT_WARN_ERROR_OPTIONS\", '{\"error\":\"all\"}')\n        context = self.make_dbt_context(\"run\", [\"run\"])\n\n        with pytest.raises(DbtUsageException):\n            Flags(context)\n\n    @pytest.mark.parametrize(\"warn_error\", [True, False])\n    def test_mutually_exclusive_options_from_cli_and_project_flags(\n        self, warn_error, project_flags\n    ):\n        project_flags.warn_error = warn_error\n        context = self.make_dbt_context(\"run\", [\"--warn-error-options\", '{\"error\": \"all\"}', \"run\"])\n\n        with pytest.raises(DbtUsageException):\n            Flags(context, project_flags)\n\n    @pytest.mark.parametrize(\"warn_error\", [\"True\", \"False\"])\n    def test_mutually_exclusive_options_from_cli_and_envvar(self, warn_error, monkeypatch):\n        monkeypatch.setenv(\"DBT_WARN_ERROR\", warn_error)\n        context = self.make_dbt_context(\"run\", [\"--warn-error-options\", '{\"error\": \"all\"}', \"run\"])\n\n        with pytest.raises(DbtUsageException):\n            Flags(context)\n\n    @pytest.mark.parametrize(\"warn_error\", [\"True\", \"False\"])\n    def test_mutually_exclusive_options_from_project_flags_and_envvar(\n        self, project_flags, warn_error, monkeypatch\n    ):\n        project_flags.warn_error = warn_error\n        monkeypatch.setenv(\"DBT_WARN_ERROR_OPTIONS\", '{\"error\": \"all\"}')\n        context = self.make_dbt_context(\"run\", [\"run\"])\n\n        with pytest.raises(DbtUsageException):\n            Flags(context, project_flags)\n\n    @pytest.mark.parametrize(\n        \"cli_colors,cli_colors_file,flag_colors,flag_colors_file\",\n        [\n            (None, None, True, True),\n            (True, None, True, True),\n            (None, True, True, True),\n            (False, None, False, False),\n            (None, False, True, False),\n            (True, True, True, True),\n            (False, False, False, False),\n            (True, False, True, False),\n            (False, True, False, True),\n        ],\n    )\n    def test_no_color_interaction(\n        self, cli_colors, cli_colors_file, flag_colors, flag_colors_file\n    ):\n        cli_params = []\n\n        if cli_colors is not None:\n            cli_params.append(\"--use-colors\" if cli_colors else \"--no-use-colors\")\n\n        if cli_colors_file is not None:\n            cli_params.append(\"--use-colors-file\" if cli_colors_file else \"--no-use-colors-file\")\n\n        cli_params.append(\"run\")\n\n        context = self.make_dbt_context(\"run\", cli_params)\n\n        flags = Flags(context, None)\n\n        assert flags.USE_COLORS == flag_colors\n        assert flags.USE_COLORS_FILE == flag_colors_file\n\n    @pytest.mark.parametrize(\n        \"cli_log_level,cli_log_level_file,flag_log_level,flag_log_level_file\",\n        [\n            (None, None, \"info\", \"debug\"),\n            (\"error\", None, \"error\", \"error\"),  # explicit level overrides file level...\n            (\"info\", None, \"info\", \"info\"),  # ...but file level doesn't change console level\n            (\n                \"debug\",\n                \"warn\",\n                \"debug\",\n                \"warn\",\n            ),  # still, two separate explicit levels are applied independently\n        ],\n    )\n    def test_log_level_interaction(\n        self, cli_log_level, cli_log_level_file, flag_log_level, flag_log_level_file\n    ):\n        cli_params = []\n\n        if cli_log_level is not None:\n            cli_params.append(\"--log-level\")\n            cli_params.append(cli_log_level)\n\n        if cli_log_level_file is not None:\n            cli_params.append(\"--log-level-file\")\n            cli_params.append(cli_log_level_file)\n\n        cli_params.append(\"run\")\n\n        context = self.make_dbt_context(\"run\", cli_params)\n\n        flags = Flags(context, None)\n\n        assert flags.LOG_LEVEL == flag_log_level\n        assert flags.LOG_LEVEL_FILE == flag_log_level_file\n\n    @pytest.mark.parametrize(\n        \"cli_log_format,cli_log_format_file,flag_log_format,flag_log_format_file\",\n        [\n            (None, None, \"default\", \"debug\"),\n            (\"json\", None, \"json\", \"json\"),  # explicit format overrides file format...\n            (None, \"json\", \"default\", \"json\"),  # ...but file format doesn't change console format\n            (\n                \"debug\",\n                \"text\",\n                \"debug\",\n                \"text\",\n            ),  # still, two separate explicit formats are applied independently\n        ],\n    )\n    def test_log_format_interaction(\n        self, cli_log_format, cli_log_format_file, flag_log_format, flag_log_format_file\n    ):\n        cli_params = []\n\n        if cli_log_format is not None:\n            cli_params.append(\"--log-format\")\n            cli_params.append(cli_log_format)\n\n        if cli_log_format_file is not None:\n            cli_params.append(\"--log-format-file\")\n            cli_params.append(cli_log_format_file)\n\n        cli_params.append(\"run\")\n\n        context = self.make_dbt_context(\"run\", cli_params)\n\n        flags = Flags(context, None)\n\n        assert flags.LOG_FORMAT == flag_log_format\n        assert flags.LOG_FORMAT_FILE == flag_log_format_file\n\n    def test_log_settings_from_config(self):\n        \"\"\"Test that values set in ProjectFlags for log settings will set flags as expected\"\"\"\n        context = self.make_dbt_context(\"run\", [\"run\"])\n\n        config = ProjectFlags(log_format=\"json\", log_level=\"warn\", use_colors=False)\n\n        flags = Flags(context, config)\n\n        assert flags.LOG_FORMAT == \"json\"\n        assert flags.LOG_FORMAT_FILE == \"json\"\n        assert flags.LOG_LEVEL == \"warn\"\n        assert flags.LOG_LEVEL_FILE == \"warn\"\n        assert flags.USE_COLORS is False\n        assert flags.USE_COLORS_FILE is False\n\n    def test_log_file_settings_from_config(self):\n        \"\"\"Test that values set in ProjectFlags for log *file* settings will set flags as expected, leaving the console\n        logging flags with their default values\"\"\"\n        context = self.make_dbt_context(\"run\", [\"run\"])\n\n        config = ProjectFlags(log_format_file=\"json\", log_level_file=\"warn\", use_colors_file=False)\n\n        flags = Flags(context, config)\n\n        assert flags.LOG_FORMAT == \"default\"\n        assert flags.LOG_FORMAT_FILE == \"json\"\n        assert flags.LOG_LEVEL == \"info\"\n        assert flags.LOG_LEVEL_FILE == \"warn\"\n        assert flags.USE_COLORS is True\n        assert flags.USE_COLORS_FILE is False\n\n    def test_duplicate_flags_raises_error(self):\n        parent_context = self.make_dbt_context(\"parent\", [\"--version-check\"])\n        context = self.make_dbt_context(\"child\", [\"--version-check\"], parent_context)\n\n        with pytest.raises(DbtUsageException):\n            Flags(context)\n\n    def test_global_flag_at_child_context(self):\n        parent_context_a = self.make_dbt_context(\"parent_context_a\", [\"--no-use-colors\"])\n        child_context_a = self.make_dbt_context(\"child_context_a\", [\"run\"], parent_context_a)\n        flags_a = Flags(child_context_a)\n\n        parent_context_b = self.make_dbt_context(\"parent_context_b\", [\"run\"])\n        child_context_b = self.make_dbt_context(\n            \"child_context_b\", [\"--no-use-colors\"], parent_context_b\n        )\n        flags_b = Flags(child_context_b)\n\n        assert flags_a.USE_COLORS == flags_b.USE_COLORS\n\n    def test_global_flag_with_env_var(self, monkeypatch):\n        # The environment variable is used for whichever parent or child\n        # does not have a cli command.\n        # Test that \"child\" global flag overrides env var\n        monkeypatch.setenv(\"DBT_QUIET\", \"0\")\n        parent_context = self.make_dbt_context(\"parent\", [\"--no-use-colors\"])\n        child_context = self.make_dbt_context(\"child\", [\"--quiet\"], parent_context)\n        flags = Flags(child_context)\n        assert flags.QUIET is True\n\n        # Test that \"parent\" global flag overrides env var\n        parent_context = self.make_dbt_context(\"parent\", [\"--quiet\"])\n        child_context = self.make_dbt_context(\"child\", [\"--no-use-colors\"], parent_context)\n        flags = Flags(child_context)\n        assert flags.QUIET is True\n\n    def test_set_project_only_flags(self, project_flags, run_context):\n        flags = Flags(run_context, project_flags)\n\n        for project_only_flag, project_only_flag_value in project_flags.project_only_flags.items():\n            assert getattr(flags, project_only_flag) == project_only_flag_value\n            # sanity check: ensure project_only_flag is not part of the click context\n            assert project_only_flag not in run_context.params\n\n    def _create_flags_from_dict(self, cmd, d):\n        write_file(\"\", \"profiles.yml\")\n        result = Flags.from_dict(cmd, d)\n        assert result.which is cmd.value\n        rm_file(\"profiles.yml\")\n        return result\n\n    def test_from_dict__run(self):\n        args_dict = {\n            \"print\": False,\n            \"select\": [\"model_one\", \"model_two\"],\n        }\n        result = self._create_flags_from_dict(Command.RUN, args_dict)\n        assert \"model_one\" in result.select[0]\n        assert \"model_two\" in result.select[1]\n\n    def test_from_dict__build(self):\n        args_dict = {\n            \"print\": True,\n            \"state\": \"some/path\",\n            \"defer_state\": None,\n        }\n        result = self._create_flags_from_dict(Command.BUILD, args_dict)\n        assert result.print is True\n        assert \"some/path\" in str(result.state)\n        assert result.defer_state is None\n\n    def test_from_dict__seed(self):\n        args_dict = {\"use_colors\": False, \"exclude\": [\"model_three\"]}\n        result = self._create_flags_from_dict(Command.SEED, args_dict)\n        assert result.use_colors is False\n        assert \"model_three\" in result.exclude[0]\n\n    def test_from_dict__which_fails(self):\n        args_dict = {\"which\": \"some bad command\"}\n        with pytest.raises(DbtInternalError, match=r\"does not match value of which\"):\n            self._create_flags_from_dict(Command.RUN, args_dict)\n\n    def test_from_dict_0_value(self):\n        args_dict = {\"log_file_max_bytes\": 0}\n        flags = Flags.from_dict(Command.RUN, args_dict)\n        assert flags.LOG_FILE_MAX_BYTES == 0\n\n\ndef test_project_flag_defaults():\n    flags = ProjectFlags()\n    # From # 9183: Let's add a unit test that ensures that:\n    # every attribute of ProjectFlags that has a corresponding click option\n    # in params.py should be set to None by default (except for anon user\n    # tracking). Going forward, flags can have non-None defaults if they\n    # do not have a corresponding CLI option/env var. These will be used\n    # to control backwards incompatible interface or behaviour changes.\n\n    # List of all flags except send_anonymous_usage_stats\n    project_flags = [\n        \"cache_selected_only\",\n        \"debug\",\n        \"fail_fast\",\n        \"indirect_selection\",\n        \"log_format\",\n        \"log_format_file\",\n        \"log_level\",\n        \"log_level_file\",\n        \"partial_parse\",\n        \"populate_cache\",\n        \"printer_width\",\n        \"static_parser\",\n        \"use_colors\",\n        \"use_colors_file\",\n        \"use_experimental_parser\",\n        \"version_check\",\n        \"warn_error\",\n        \"warn_error_options\",\n        \"write_json\",\n    ]\n    for flag in project_flags:\n        assert getattr(flags, flag) is None\n"
  },
  {
    "path": "tests/unit/cli/test_main.py",
    "content": "import click\n\nfrom dbt.cli.flags import command_args\nfrom dbt.cli.main import cli\nfrom dbt.cli.types import Command\n\n\nclass TestCLI:\n    def _all_commands(self, group=cli, result=set()):\n        for command in group.commands.values():\n            result.add(command)\n            if isinstance(command, click.Group):\n                self._all_commands(command, result)\n                continue\n        return result\n\n    def test_commands_have_docstrings(self):\n        for command in self._all_commands():\n            assert command.__doc__ is not None\n\n    # TODO:  This isn't the ideal way to test params as\n    # they will be tested as many times as they are used as decorators.\n    # This is inefficent (obvs)\n    def test_unhidden_params_have_help_texts(self):\n        def run_test(command):\n            for param in command.params:\n                # arguments can't have help text\n                if not isinstance(param, click.Argument) and not param.hidden:\n                    assert param.help is not None\n            if type(command) is click.Group:\n                for command in command.commands.values():\n                    run_test(command)\n\n        run_test(cli)\n\n    def test_param_names_match_envvars(self):\n        def run_test(command):\n            for param in command.params:\n                # deprecated params are named \"deprecated_x\" and do not need to have\n                # a parallel name like \"DBT_\"\n                if isinstance(param.envvar, list):\n                    envvar = param.envvar[0]\n                else:\n                    envvar = param.envvar\n\n                if envvar is not None and \"deprecated_\" not in param.name:\n                    assert (\"DBT_\" + param.name.upper() == envvar) or (\n                        \"DBT_ENGINE_\" + param.name.upper() == envvar\n                    )\n            if type(command) is click.Group:\n                for command in command.commands.values():\n                    run_test(command)\n\n        run_test(cli)\n\n    def test_commands_in_enum_and_dict(self):\n        for command in self._all_commands(cli):\n            if isinstance(command, click.Group):\n                continue\n            cmd = Command.from_str(command.name)\n            command_args(cmd)\n"
  },
  {
    "path": "tests/unit/cli/test_option_types.py",
    "content": "from datetime import datetime\nfrom typing import Union\n\nimport freezegun\nimport pytest\nimport pytz\nfrom click import BadParameter, Option\n\nfrom dbt.cli.option_types import YAML, SampleType\nfrom dbt.event_time.sample_window import SampleWindow\n\n\nclass TestYAML:\n    @pytest.mark.parametrize(\n        \"raw_value,expected_converted_value\",\n        [\n            (\"{}\", {}),\n            (\"{'test_var_key': 'test_var_value'}\", {\"test_var_key\": \"test_var_value\"}),\n        ],\n    )\n    def test_yaml_init(self, raw_value, expected_converted_value):\n        converted_value = YAML().convert(raw_value, Option([\"--vars\"]), None)\n        assert converted_value == expected_converted_value\n\n    @pytest.mark.parametrize(\n        \"invalid_yaml_str\",\n        [\"{\", \"\"],\n    )\n    def test_yaml_init_invalid_yaml_str(self, invalid_yaml_str):\n        with pytest.raises(BadParameter) as e:\n            YAML().convert(invalid_yaml_str, Option([\"--vars\"]), None)\n        assert \"--vars\" in e.value.format_message()\n\n\nclass TestSampleType:\n    @pytest.mark.parametrize(\n        \"input,expected_result\",\n        [\n            (\n                \"{'start': '2025-01-24', 'end': '2025-01-27'}\",\n                SampleWindow(\n                    start=datetime(2025, 1, 24, 0, 0, 0, 0, pytz.UTC),\n                    end=datetime(2025, 1, 27, 0, 0, 0, 0, pytz.UTC),\n                ),\n            ),\n            (\n                \"{'tart': '2025-01-24', 'bend': '2025-01-27'}\",\n                BadParameter('Field \"start\" of type datetime is missing in SampleWindow instance'),\n            ),\n            (\n                \"{}\",\n                BadParameter('Field \"start\" of type datetime is missing in SampleWindow instance'),\n            ),\n            (\n                \"cats\",\n                BadParameter(\n                    \"Runtime Error\\n  Cannot load SAMPLE_WINDOW from 'cats'. Must be of form 'DAYS_INT GRAIN_SIZE'.\"\n                ),\n            ),\n        ],\n    )\n    def test_convert(self, input: str, expected_result: Union[SampleWindow, Exception]):\n        try:\n            result = SampleType().convert(input, Option([\"--sample\"]), None)\n            assert result == expected_result\n        except Exception as e:\n            assert str(e) == str(expected_result)\n\n    # this had to be a seprate test case because the @freezegun.freeze_time\n    # was screwing up the instantiation of SampleWindow.from_dict calls for the\n    # other test cases\n    @freezegun.freeze_time(\"2025-01-28T02:03:0Z\")\n    def test_convert_relative(self):\n        input = \"3 days\"\n        expected_result = SampleWindow(\n            start=datetime(2025, 1, 25, 2, 3, 0, 0, pytz.UTC),\n            end=datetime(2025, 1, 28, 2, 3, 0, 0, pytz.UTC),\n        )\n        result = SampleType().convert(input, Option([\"--sample\"]), None)\n        assert result == expected_result\n"
  },
  {
    "path": "tests/unit/clients/__init__.py",
    "content": ""
  },
  {
    "path": "tests/unit/clients/test_jinja.py",
    "content": "from contextlib import contextmanager\n\nimport pytest\nimport yaml\n\nfrom dbt.clients.jinja import get_rendered, get_template\nfrom dbt_common.exceptions import JinjaRenderingError\n\n\n@contextmanager\ndef returns(value):\n    yield value\n\n\n@contextmanager\ndef raises(value):\n    with pytest.raises(value) as exc:\n        yield exc\n\n\ndef expected_id(arg):\n    if isinstance(arg, list):\n        return \"_\".join(arg)\n\n\njinja_tests = [\n    # strings\n    (\n        \"\"\"foo: bar\"\"\",\n        returns(\"bar\"),\n        returns(\"bar\"),\n    ),\n    (\n        '''foo: \"bar\"''',\n        returns(\"bar\"),\n        returns(\"bar\"),\n    ),\n    (\n        '''foo: \"'bar'\"''',\n        returns(\"'bar'\"),\n        returns(\"'bar'\"),\n    ),\n    (\n        \"\"\"foo: '\"bar\"'\"\"\",\n        returns('\"bar\"'),\n        returns('\"bar\"'),\n    ),\n    (\n        '''foo: \"{{ 'bar' | as_text }}\"''',\n        returns(\"bar\"),\n        returns(\"bar\"),\n    ),\n    (\n        '''foo: \"{{ 'bar' | as_bool }}\"''',\n        returns(\"bar\"),\n        raises(JinjaRenderingError),\n    ),\n    (\n        '''foo: \"{{ 'bar' | as_number }}\"''',\n        returns(\"bar\"),\n        raises(JinjaRenderingError),\n    ),\n    (\n        '''foo: \"{{ 'bar' | as_native }}\"''',\n        returns(\"bar\"),\n        returns(\"bar\"),\n    ),\n    # ints\n    (\n        \"\"\"foo: 1\"\"\",\n        returns(\"1\"),\n        returns(\"1\"),\n    ),\n    (\n        '''foo: \"1\"''',\n        returns(\"1\"),\n        returns(\"1\"),\n    ),\n    (\n        '''foo: \"'1'\"''',\n        returns(\"'1'\"),\n        returns(\"'1'\"),\n    ),\n    (\n        \"\"\"foo: '\"1\"'\"\"\",\n        returns('\"1\"'),\n        returns('\"1\"'),\n    ),\n    (\n        '''foo: \"{{ 1 }}\"''',\n        returns(\"1\"),\n        returns(\"1\"),\n    ),\n    (\n        '''foo: \"{{ '1' }}\"''',\n        returns(\"1\"),\n        returns(\"1\"),\n    ),\n    (\n        '''foo: \"'{{ 1 }}'\"''',\n        returns(\"'1'\"),\n        returns(\"'1'\"),\n    ),\n    (\n        '''foo: \"'{{ '1' }}'\"''',\n        returns(\"'1'\"),\n        returns(\"'1'\"),\n    ),\n    (\n        '''foo: \"{{ 1 | as_text }}\"''',\n        returns(\"1\"),\n        returns(\"1\"),\n    ),\n    (\n        '''foo: \"{{ 1 | as_bool }}\"''',\n        returns(\"1\"),\n        raises(JinjaRenderingError),\n    ),\n    (\n        '''foo: \"{{ 1 | as_number }}\"''',\n        returns(\"1\"),\n        returns(1),\n    ),\n    (\n        '''foo: \"{{ 1 | as_native }}\"''',\n        returns(\"1\"),\n        returns(1),\n    ),\n    (\n        '''foo: \"{{ '1' | as_text }}\"''',\n        returns(\"1\"),\n        returns(\"1\"),\n    ),\n    (\n        '''foo: \"{{ '1' | as_bool }}\"''',\n        returns(\"1\"),\n        raises(JinjaRenderingError),\n    ),\n    (\n        '''foo: \"{{ '1' | as_number }}\"''',\n        returns(\"1\"),\n        returns(1),\n    ),\n    (\n        '''foo: \"{{ '1' | as_native }}\"''',\n        returns(\"1\"),\n        returns(1),\n    ),\n    # booleans.\n    # Note the discrepancy with true vs True: `true` is recognized by jinja but\n    # not literal_eval, but `True` is recognized by ast.literal_eval.\n    # For extra fun, yaml recognizes both.\n    # unquoted true\n    (\n        '''foo: \"{{ True }}\"''',\n        returns(\"True\"),\n        returns(\"True\"),\n    ),\n    (\n        '''foo: \"{{ True | as_text }}\"''',\n        returns(\"True\"),\n        returns(\"True\"),\n    ),\n    (\n        '''foo: \"{{ True | as_bool }}\"''',\n        returns(\"True\"),\n        returns(True),\n    ),\n    (\n        '''foo: \"{{ True | as_number }}\"''',\n        returns(\"True\"),\n        raises(JinjaRenderingError),\n    ),\n    (\n        '''foo: \"{{ True | as_native }}\"''',\n        returns(\"True\"),\n        returns(True),\n    ),\n    # unquoted true\n    (\n        '''foo: \"{{ true }}\"''',\n        returns(\"True\"),\n        returns(\"True\"),\n    ),\n    (\n        '''foo: \"{{ true | as_text }}\"''',\n        returns(\"True\"),\n        returns(\"True\"),\n    ),\n    (\n        '''foo: \"{{ true | as_bool }}\"''',\n        returns(\"True\"),\n        returns(True),\n    ),\n    (\n        '''foo: \"{{ true | as_number }}\"''',\n        returns(\"True\"),\n        raises(JinjaRenderingError),\n    ),\n    (\n        '''foo: \"{{ true | as_native }}\"''',\n        returns(\"True\"),\n        returns(True),\n    ),\n    (\n        '''foo: \"{{ 'true' | as_text }}\"''',\n        returns(\"true\"),\n        returns(\"true\"),\n    ),\n    # quoted 'true'\n    (\n        '''foo: \"'{{ true }}'\"''',\n        returns(\"'True'\"),\n        returns(\"'True'\"),\n    ),  # jinja true -> python True -> str(True) -> \"True\" -> quoted\n    (\n        '''foo: \"'{{ true | as_text }}'\"''',\n        returns(\"'True'\"),\n        returns(\"'True'\"),\n    ),\n    (\n        '''foo: \"'{{ true | as_bool }}'\"''',\n        returns(\"'True'\"),\n        returns(\"'True'\"),\n    ),\n    (\n        '''foo: \"'{{ true | as_number }}'\"''',\n        returns(\"'True'\"),\n        returns(\"'True'\"),\n    ),\n    (\n        '''foo: \"'{{ true | as_native }}'\"''',\n        returns(\"'True'\"),\n        returns(\"'True'\"),\n    ),\n    # unquoted True\n    (\n        '''foo: \"{{ True }}\"''',\n        returns(\"True\"),\n        returns(\"True\"),\n    ),\n    (\n        '''foo: \"{{ True | as_text }}\"''',\n        returns(\"True\"),\n        returns(\"True\"),\n    ),  # True -> string 'True' -> text -> str('True') -> 'True'\n    (\n        '''foo: \"{{ True | as_bool }}\"''',\n        returns(\"True\"),\n        returns(True),\n    ),\n    (\n        '''foo: \"{{ True | as_number }}\"''',\n        returns(\"True\"),\n        raises(JinjaRenderingError),\n    ),\n    (\n        '''foo: \"{{ True | as_native }}\"''',\n        returns(\"True\"),\n        returns(True),\n    ),\n    # quoted 'True' within rendering\n    (\n        '''foo: \"{{ 'True' | as_text }}\"''',\n        returns(\"True\"),\n        returns(\"True\"),\n    ),\n    # 'True' -> string 'True' -> text -> str('True') -> 'True'\n    (\n        '''foo: \"{{ 'True' | as_bool }}\"''',\n        returns(\"True\"),\n        returns(True),\n    ),\n    # quoted 'True' outside rendering\n    (\n        '''foo: \"'{{ True }}'\"''',\n        returns(\"'True'\"),\n        returns(\"'True'\"),\n    ),\n    (\n        '''foo: \"'{{ True | as_bool }}'\"''',\n        returns(\"'True'\"),\n        returns(\"'True'\"),\n    ),\n    # yaml turns 'yes' into a boolean true\n    (\n        \"\"\"foo: yes\"\"\",\n        returns(\"True\"),\n        returns(\"True\"),\n    ),\n    (\n        '''foo: \"yes\"''',\n        returns(\"yes\"),\n        returns(\"yes\"),\n    ),\n    # concatenation\n    (\n        '''foo: \"{{ (a_int + 100) | as_native }}\"''',\n        returns(\"200\"),\n        returns(200),\n    ),\n    (\n        '''foo: \"{{ (a_str ~ 100) | as_native }}\"''',\n        returns(\"100100\"),\n        returns(100100),\n    ),\n    (\n        '''foo: \"{{( a_int ~ 100) | as_native }}\"''',\n        returns(\"100100\"),\n        returns(100100),\n    ),\n    # multiple nodes -> always str\n    (\n        '''foo: \"{{ a_str | as_native }}{{ a_str | as_native }}\"''',\n        returns(\"100100\"),\n        returns(\"100100\"),\n    ),\n    (\n        '''foo: \"{{ a_int | as_native }}{{ a_int | as_native }}\"''',\n        returns(\"100100\"),\n        returns(\"100100\"),\n    ),\n    (\n        '''foo: \"'{{ a_int | as_native }}{{ a_int | as_native }}'\"''',\n        returns(\"'100100'\"),\n        returns(\"'100100'\"),\n    ),\n    (\n        \"\"\"foo:\"\"\",\n        returns(\"None\"),\n        returns(\"None\"),\n    ),\n    (\n        \"\"\"foo: null\"\"\",\n        returns(\"None\"),\n        returns(\"None\"),\n    ),\n    (\n        '''foo: \"\"''',\n        returns(\"\"),\n        returns(\"\"),\n    ),\n    (\n        '''foo: \"{{ '' | as_native }}\"''',\n        returns(\"\"),\n        returns(\"\"),\n    ),\n    # very annoying, but jinja 'none' is yaml 'null'.\n    (\n        '''foo: \"{{ none | as_native }}\"''',\n        returns(\"None\"),\n        returns(None),\n    ),\n    # make sure we don't include comments in the output (see #2707)\n    (\n        '''foo: \"{# #}hello\"''',\n        returns(\"hello\"),\n        returns(\"hello\"),\n    ),\n    (\n        '''foo: \"{% if false %}{% endif %}hello\"''',\n        returns(\"hello\"),\n        returns(\"hello\"),\n    ),\n]\n\n\n@pytest.mark.parametrize(\"value,text_expectation,native_expectation\", jinja_tests, ids=expected_id)\ndef test_jinja_rendering_string(value, text_expectation, native_expectation):\n    foo_value = yaml.safe_load(value)[\"foo\"]\n    ctx = {\"a_str\": \"100\", \"a_int\": 100, \"b_str\": \"hello\"}\n    with text_expectation as text_result:\n        assert text_result == get_rendered(foo_value, ctx, native=False)\n\n    with native_expectation as native_result:\n        assert native_result == get_rendered(foo_value, ctx, native=True)\n\n\ndef test_do():\n    s = \"{% set my_dict = {} %}\\n{% do my_dict.update(a=1) %}\"\n\n    template = get_template(s, {})\n    mod = template.make_module()\n    assert mod.my_dict == {\"a\": 1}\n\n\ndef test_regular_render():\n    s = '{{ \"some_value\" | as_native }}'\n    value = get_rendered(s, {}, native=False)\n    assert value == \"some_value\"\n    s = \"{{ 1991 | as_native }}\"\n    value = get_rendered(s, {}, native=False)\n    assert value == \"1991\"\n\n    s = '{{ \"some_value\" | as_text }}'\n    value = get_rendered(s, {}, native=False)\n    assert value == \"some_value\"\n    s = \"{{ 1991 | as_text }}\"\n    value = get_rendered(s, {}, native=False)\n    assert value == \"1991\"\n\n\ndef test_native_render():\n    s = '{{ \"some_value\" | as_native }}'\n    value = get_rendered(s, {}, native=True)\n    assert value == \"some_value\"\n    s = \"{{ 1991 | as_native }}\"\n    value = get_rendered(s, {}, native=True)\n    assert value == 1991\n\n    s = '{{ \"some_value\" | as_text }}'\n    value = get_rendered(s, {}, native=True)\n    assert value == \"some_value\"\n    s = \"{{ 1991 | as_text }}\"\n    value = get_rendered(s, {}, native=True)\n    assert value == \"1991\"\n"
  },
  {
    "path": "tests/unit/clients/test_jinja_static.py",
    "content": "import pytest\n\nfrom dbt.artifacts.resources import RefArgs\nfrom dbt.clients.jinja_static import (\n    statically_extract_has_name_this,\n    statically_extract_macro_calls,\n    statically_parse_ref_or_source,\n    statically_parse_unrendered_config,\n)\nfrom dbt.context.base import generate_base_context\nfrom dbt.exceptions import ParsingError\n\n\n@pytest.mark.parametrize(\n    \"macro_string,expected_possible_macro_calls\",\n    [\n        (\n            \"{% macro parent_macro() %} {% do return(nested_macro()) %} {% endmacro %}\",\n            [\"nested_macro\"],\n        ),\n        (\n            \"{% macro lr_macro() %} {{ return(load_result('relations').table) }} {% endmacro %}\",\n            [\"load_result\"],\n        ),\n        (\n            \"{% macro get_snapshot_unique_id() -%} {{ return(adapter.dispatch('get_snapshot_unique_id')()) }} {%- endmacro %}\",\n            [\"get_snapshot_unique_id\"],\n        ),\n        (\n            \"{% macro get_columns_in_query(select_sql) -%} {{ return(adapter.dispatch('get_columns_in_query')(select_sql)) }} {% endmacro %}\",\n            [\"get_columns_in_query\"],\n        ),\n        (\n            \"\"\"{% macro test_mutually_exclusive_ranges(model) %}\n            with base as (\n                select {{ get_snapshot_unique_id() }} as dbt_unique_id,\n                *\n                from {{ model }} )\n            {% endmacro %}\"\"\",\n            [\"get_snapshot_unique_id\"],\n        ),\n        (\n            \"{% macro test_my_test(model) %} select {{ current_timestamp_backcompat() }} {% endmacro %}\",\n            [\"current_timestamp_backcompat\"],\n        ),\n        (\n            \"{% macro some_test(model) -%} {{ return(adapter.dispatch('test_some_kind4', 'foo_utils4')) }} {%- endmacro %}\",\n            [\"test_some_kind4\", \"foo_utils4.test_some_kind4\"],\n        ),\n        (\n            \"{% macro some_test(model) -%} {{ return(adapter.dispatch('test_some_kind5', macro_namespace = 'foo_utils5')) }} {%- endmacro %}\",\n            [\"test_some_kind5\", \"foo_utils5.test_some_kind5\"],\n        ),\n    ],\n)\ndef test_extract_macro_calls(macro_string, expected_possible_macro_calls):\n    cli_vars = {\"local_utils_dispatch_list\": [\"foo_utils4\"]}\n    ctx = generate_base_context(cli_vars)\n\n    possible_macro_calls = statically_extract_macro_calls(macro_string, ctx)\n    assert possible_macro_calls == expected_possible_macro_calls\n\n\nclass TestStaticallyParseRefOrSource:\n    def test_invalid_expression(self):\n        with pytest.raises(ParsingError):\n            statically_parse_ref_or_source(\"invalid\")\n\n    @pytest.mark.parametrize(\n        \"expression,expected_ref_or_source\",\n        [\n            (\"ref('model')\", RefArgs(name=\"model\")),\n            (\"ref('package','model')\", RefArgs(name=\"model\", package=\"package\")),\n            (\"ref('model',v=3)\", RefArgs(name=\"model\", version=3)),\n            (\"ref('package','model',v=3)\", RefArgs(name=\"model\", package=\"package\", version=3)),\n            (\"source('schema', 'table')\", [\"schema\", \"table\"]),\n        ],\n    )\n    def test_valid_ref_expression(self, expression, expected_ref_or_source):\n        ref_or_source = statically_parse_ref_or_source(expression)\n        assert ref_or_source == expected_ref_or_source\n\n\nclass TestStaticallyParseUnrenderedConfig:\n    @pytest.mark.parametrize(\n        \"expression,expected_unrendered_config\",\n        [\n            (\n                \"{{ config(materialized='view') }}\",\n                {\"materialized\": \"Keyword(key='materialized', value=Const(value='view'))\"},\n            ),\n            (\n                \"{{ config(materialized='view', enabled=True) }}\",\n                {\n                    \"materialized\": \"Keyword(key='materialized', value=Const(value='view'))\",\n                    \"enabled\": \"Keyword(key='enabled', value=Const(value=True))\",\n                },\n            ),\n            (\n                \"{{ config(materialized=env_var('test')) }}\",\n                {\n                    \"materialized\": \"Keyword(key='materialized', value=Call(node=Name(name='env_var', ctx='load'), args=[Const(value='test')], kwargs=[], dyn_args=None, dyn_kwargs=None))\"\n                },\n            ),\n            (\n                \"{{ config(materialized=env_var('test', default='default')) }}\",\n                {\n                    \"materialized\": \"Keyword(key='materialized', value=Call(node=Name(name='env_var', ctx='load'), args=[Const(value='test')], kwargs=[Keyword(key='default', value=Const(value='default'))], dyn_args=None, dyn_kwargs=None))\"\n                },\n            ),\n            (\n                \"{{ config(materialized=env_var('test', default=env_var('default'))) }}\",\n                {\n                    \"materialized\": \"Keyword(key='materialized', value=Call(node=Name(name='env_var', ctx='load'), args=[Const(value='test')], kwargs=[Keyword(key='default', value=Call(node=Name(name='env_var', ctx='load'), args=[Const(value='default')], kwargs=[], dyn_args=None, dyn_kwargs=None))], dyn_args=None, dyn_kwargs=None))\"\n                },\n            ),\n        ],\n    )\n    def test_statically_parse_unrendered_config(self, expression, expected_unrendered_config):\n        unrendered_config = statically_parse_unrendered_config(expression)\n        assert unrendered_config == expected_unrendered_config\n\n\n@pytest.mark.parametrize(\n    \"raw_code,expected_result\",\n    [\n        (\"{{ this }}\", True),\n        (\"{{ this.variable }}\", True),\n        (\"{{ log(this) }}\", True),\n        (\"{{ some_other_this }}\", False),\n        (\"this\", False),\n        (\"{{ some_object.this }}\", False),\n    ],\n)\ndef test_statically_extract_has_name_this(raw_code: str, expected_result: bool) -> None:\n    assert statically_extract_has_name_this(raw_code) == expected_result\n"
  },
  {
    "path": "tests/unit/clients/test_registry.py",
    "content": "import unittest\n\nfrom dbt.clients.registry import _get_package_with_retries\nfrom dbt_common.exceptions import ConnectionError\n\n\nclass testRegistryGetRequestException(unittest.TestCase):\n    def test_registry_request_error_catching(self):\n        # using non routable IP to test connection error logic in the _get_package_with_retries function\n        self.assertRaises(ConnectionError, _get_package_with_retries, \"\", \"http://0.0.0.0\")\n"
  },
  {
    "path": "tests/unit/clients/test_yaml_helper.py",
    "content": "from dbt.clients.checked_load import checked_load\n\nno_dupe__yml = \"\"\"\na:\n  b: 1\n\nb:\n  a: 1\n\"\"\"\n\ntop_level_dupe__yml = \"\"\"\na:\n  b: 1\n\na:\n  c: 1\n  d: 2\n  e: 3\n\"\"\"\n\nnested_dupe__yml = \"\"\"\na:\n  b: 1\n\nc:\n  d: 1\n  e: 2\n  d: 3\n\"\"\"\n\nmultiple_dupes__yml = \"\"\"\na:\n  b:\n    c: 1\n\nd:\n  e:\n    f: 1\n    g: 2\n    f: 3\n    h: 4\n    f: 5\n\"\"\"\n\n# Overrides should not cause duplicate key warnings on the data_tests key below.\noverride__yml = \"\"\"\nversion: 2\n\nmodels:\n  - name: my_first_dbt_model\n    description: &description\n      \"A starter dbt model\"\n    columns:\n      - &copy_me\n        name: id\n        description: The ID.\n        data_tests:\n          - not_null\n\n  - name: my_second_dbt_model\n    description: *description\n    columns:\n      - <<: *copy_me\n        data_tests:\n          - unique\n\"\"\"\n\noverride_with_issue__yml = \"\"\"\nversion: 2\n\nmodels:\n  - name: my_first_dbt_model\n    description: &description\n      \"A starter dbt model\"\n    columns:\n      - &copy_me\n        name: id\n        description: The ID.\n        data_tests:\n          - not_null\n\n  - name: my_second_dbt_model\n    description: *description\n    columns:\n      - <<: *copy_me\n        data_tests:\n          - unique\n        data_tests:\n          - unique\n\"\"\"\n\n\ndef test_checked_load():\n\n    no_dupe_issues = checked_load(no_dupe__yml)[1]\n    assert no_dupe_issues == []\n\n    top_level_dupe_issues = checked_load(top_level_dupe__yml)[1]\n    assert len(top_level_dupe_issues) == 1\n\n    nested_dupe_issues = checked_load(nested_dupe__yml)[1]\n    assert len(nested_dupe_issues) == 1\n\n    multiple_dupes_issues = checked_load(multiple_dupes__yml)[1]\n    assert len(multiple_dupes_issues) == 2\n\n    override_dupes_issues = checked_load(override__yml)[1]\n    assert len(override_dupes_issues) == 0\n\n    # This currently fails. We are not checking for genuine duplicate keys\n    # in override anchors.\n    # real_override_dupes_issues = checked_load(override__yml)[1]\n    # assert len(real_override_dupes_issues) == 1\n"
  },
  {
    "path": "tests/unit/config/__init__.py",
    "content": "import os\nimport shutil\nimport tempfile\nimport unittest\nfrom argparse import Namespace\nfrom contextlib import contextmanager\n\nimport yaml\n\nimport dbt.config\nimport dbt.exceptions\nfrom dbt import flags\nfrom dbt.constants import PACKAGES_FILE_NAME\nfrom dbt.flags import set_from_args\nfrom tests.unit.utils import normalize\n\nINITIAL_ROOT = os.getcwd()\n\n\n@contextmanager\ndef temp_cd(path):\n    current_path = os.getcwd()\n    os.chdir(path)\n    try:\n        yield\n    finally:\n        os.chdir(current_path)\n\n\n@contextmanager\ndef raises_nothing():\n    yield\n\n\ndef empty_profile_renderer():\n    return dbt.config.renderer.ProfileRenderer({})\n\n\ndef empty_project_renderer():\n    return dbt.config.renderer.DbtProjectYamlRenderer()\n\n\nmodel_config = {\n    \"my_package_name\": {\n        \"enabled\": True,\n        \"adwords\": {\n            \"adwords_ads\": {\"materialized\": \"table\", \"enabled\": True, \"schema\": \"analytics\"}\n        },\n        \"snowplow\": {\n            \"snowplow_sessions\": {\n                \"sort\": \"timestamp\",\n                \"materialized\": \"incremental\",\n                \"dist\": \"user_id\",\n                \"unique_key\": \"id\",\n            },\n            \"base\": {\n                \"snowplow_events\": {\n                    \"sort\": [\"timestamp\", \"userid\"],\n                    \"materialized\": \"table\",\n                    \"sort_type\": \"interleaved\",\n                    \"dist\": \"userid\",\n                }\n            },\n        },\n    }\n}\n\nmodel_fqns = frozenset(\n    (\n        (\"my_package_name\", \"snowplow\", \"snowplow_sessions\"),\n        (\"my_package_name\", \"snowplow\", \"base\", \"snowplow_events\"),\n        (\"my_package_name\", \"adwords\", \"adwords_ads\"),\n    )\n)\n\n\nclass Args:\n    def __init__(\n        self,\n        profiles_dir=None,\n        threads=None,\n        profile=None,\n        cli_vars=None,\n        version_check=None,\n        project_dir=None,\n        target=None,\n    ):\n        self.profile = profile\n        self.threads = threads\n        self.target = target\n        if profiles_dir is not None:\n            self.profiles_dir = profiles_dir\n            flags.PROFILES_DIR = profiles_dir\n        if cli_vars is not None:\n            self.vars = cli_vars\n        if version_check is not None:\n            self.version_check = version_check\n        if project_dir is not None:\n            self.project_dir = project_dir\n\n\nclass BaseConfigTest(unittest.TestCase):\n    \"\"\"Subclass this, and before calling the superclass setUp, set\n    self.profiles_dir and self.project_dir.\n    \"\"\"\n\n    def setUp(self):\n        # Write project\n        self.project_dir = normalize(tempfile.mkdtemp())\n        self.default_project_data = {\n            \"version\": \"0.0.1\",\n            \"name\": \"my_test_project\",\n            \"profile\": \"default\",\n        }\n        self.write_project(self.default_project_data)\n\n        # Write profile\n        self.profiles_dir = normalize(tempfile.mkdtemp())\n        self.default_profile_data = {\n            \"default\": {\n                \"outputs\": {\n                    \"postgres\": {\n                        \"type\": \"postgres\",\n                        \"host\": \"postgres-db-hostname\",\n                        \"port\": 5555,\n                        \"user\": \"db_user\",\n                        \"pass\": \"db_pass\",\n                        \"dbname\": \"postgres-db-name\",\n                        \"schema\": \"postgres-schema\",\n                        \"threads\": 7,\n                    },\n                    \"with-vars\": {\n                        \"type\": \"{{ env_var('env_value_type') }}\",\n                        \"host\": \"{{ env_var('env_value_host') }}\",\n                        \"port\": \"{{ env_var('env_value_port') | as_number }}\",\n                        \"user\": \"{{ env_var('env_value_user') }}\",\n                        \"pass\": \"{{ env_var('env_value_pass') }}\",\n                        \"dbname\": \"{{ env_var('env_value_dbname') }}\",\n                        \"schema\": \"{{ env_var('env_value_schema') }}\",\n                    },\n                    \"cli-and-env-vars\": {\n                        \"type\": \"{{ env_var('env_value_type') }}\",\n                        \"host\": \"{{ var('cli_value_host') }}\",\n                        \"port\": \"{{ env_var('env_value_port') | as_number }}\",\n                        \"user\": \"{{ env_var('env_value_user') }}\",\n                        \"pass\": \"{{ env_var('env_value_pass') }}\",\n                        \"dbname\": \"{{ env_var('env_value_dbname') }}\",\n                        \"schema\": \"{{ env_var('env_value_schema') }}\",\n                    },\n                },\n                \"target\": \"postgres\",\n            },\n            \"other\": {\n                \"outputs\": {\n                    \"other-postgres\": {\n                        \"type\": \"postgres\",\n                        \"host\": \"other-postgres-db-hostname\",\n                        \"port\": 4444,\n                        \"user\": \"other_db_user\",\n                        \"pass\": \"other_db_pass\",\n                        \"dbname\": \"other-postgres-db-name\",\n                        \"schema\": \"other-postgres-schema\",\n                        \"threads\": 2,\n                    }\n                },\n                \"target\": \"other-postgres\",\n            },\n            \"empty_profile_data\": {},\n        }\n        self.write_profile(self.default_profile_data)\n\n        self.args = Namespace(\n            profiles_dir=self.profiles_dir,\n            cli_vars={},\n            version_check=True,\n            project_dir=self.project_dir,\n            target=None,\n            threads=None,\n            profile=None,\n        )\n        set_from_args(self.args, None)\n        self.env_override = {\n            \"env_value_type\": \"postgres\",\n            \"env_value_host\": \"env-postgres-host\",\n            \"env_value_port\": \"6543\",\n            \"env_value_user\": \"env-postgres-user\",\n            \"env_value_pass\": \"env-postgres-pass\",\n            \"env_value_dbname\": \"env-postgres-dbname\",\n            \"env_value_schema\": \"env-postgres-schema\",\n            \"env_value_profile\": \"default\",\n        }\n\n    def assertRaisesOrReturns(self, exc):\n        if exc is None:\n            return raises_nothing()\n        else:\n            return self.assertRaises(exc)\n\n    def tearDown(self):\n        try:\n            shutil.rmtree(self.project_dir)\n        except EnvironmentError:\n            pass\n        try:\n            shutil.rmtree(self.profiles_dir)\n        except EnvironmentError:\n            pass\n\n    def project_path(self, name):\n        return os.path.join(self.project_dir, name)\n\n    def profile_path(self, name):\n        return os.path.join(self.profiles_dir, name)\n\n    def write_project(self, project_data=None):\n        if project_data is None:\n            project_data = self.project_data\n        with open(self.project_path(\"dbt_project.yml\"), \"w\") as fp:\n            yaml.dump(project_data, fp)\n\n    def write_packages(self, package_data):\n        with open(self.project_path(\"packages.yml\"), \"w\") as fp:\n            yaml.dump(package_data, fp)\n\n    def write_profile(self, profile_data=None):\n        if profile_data is None:\n            profile_data = self.profile_data\n        with open(self.profile_path(\"profiles.yml\"), \"w\") as fp:\n            yaml.dump(profile_data, fp)\n\n    def write_empty_profile(self):\n        with open(self.profile_path(\"profiles.yml\"), \"w\") as fp:\n            yaml.dump(\"\", fp)\n\n\ndef project_from_config_norender(\n    cfg, packages=None, project_root=\"/invalid-root-path\", verify_version=False\n):\n    if packages is None:\n        packages = {}\n    partial = dbt.config.project.PartialProject.from_dicts(\n        project_root,\n        project_dict=cfg,\n        packages_dict=packages,\n        selectors_dict={},\n        verify_version=verify_version,\n    )\n    # no rendering ... Why?\n    partial.project_dict[\"project-root\"] = project_root\n    rendered = dbt.config.project.RenderComponents(\n        project_dict=partial.project_dict,\n        packages_dict=partial.packages_dict,\n        selectors_dict=partial.selectors_dict,\n    )\n    return partial.create_project(rendered)\n\n\ndef project_from_config_rendered(\n    cfg,\n    packages=None,\n    project_root=\"/invalid-root-path\",\n    verify_version=False,\n    packages_specified_path=PACKAGES_FILE_NAME,\n):\n    if packages is None:\n        packages = {}\n    partial = dbt.config.project.PartialProject.from_dicts(\n        project_root,\n        project_dict=cfg,\n        packages_dict=packages,\n        selectors_dict={},\n        verify_version=verify_version,\n        packages_specified_path=packages_specified_path,\n    )\n    return partial.render(empty_project_renderer())\n"
  },
  {
    "path": "tests/unit/config/test_profile.py",
    "content": "import os\nfrom copy import deepcopy\nfrom unittest import mock\n\nimport dbt.config\nimport dbt.exceptions\nfrom dbt.adapters.postgres import PostgresCredentials\nfrom dbt.flags import set_from_args\nfrom dbt.tests.util import safe_set_invocation_context\nfrom tests.unit.config import (\n    BaseConfigTest,\n    empty_profile_renderer,\n    project_from_config_norender,\n)\n\n\nclass TestProfile(BaseConfigTest):\n    def from_raw_profiles(self):\n        renderer = empty_profile_renderer()\n        return dbt.config.Profile.from_raw_profiles(self.default_profile_data, \"default\", renderer)\n\n    def test_from_raw_profiles(self):\n        profile = self.from_raw_profiles()\n        self.assertEqual(profile.profile_name, \"default\")\n        self.assertEqual(profile.target_name, \"postgres\")\n        self.assertEqual(profile.threads, 7)\n        self.assertTrue(isinstance(profile.credentials, PostgresCredentials))\n        self.assertEqual(profile.credentials.type, \"postgres\")\n        self.assertEqual(profile.credentials.host, \"postgres-db-hostname\")\n        self.assertEqual(profile.credentials.port, 5555)\n        self.assertEqual(profile.credentials.user, \"db_user\")\n        self.assertEqual(profile.credentials.password, \"db_pass\")\n        self.assertEqual(profile.credentials.schema, \"postgres-schema\")\n        self.assertEqual(profile.credentials.database, \"postgres-db-name\")\n\n    def test_missing_type(self):\n        del self.default_profile_data[\"default\"][\"outputs\"][\"postgres\"][\"type\"]\n        with self.assertRaises(dbt.exceptions.DbtProfileError) as exc:\n            self.from_raw_profiles()\n        self.assertIn(\"type\", str(exc.exception))\n        self.assertIn(\"postgres\", str(exc.exception))\n        self.assertIn(\"default\", str(exc.exception))\n\n    def test_bad_type(self):\n        self.default_profile_data[\"default\"][\"outputs\"][\"postgres\"][\"type\"] = \"invalid\"\n        with self.assertRaises(dbt.exceptions.DbtProfileError) as exc:\n            self.from_raw_profiles()\n        self.assertIn(\"Credentials\", str(exc.exception))\n        self.assertIn(\"postgres\", str(exc.exception))\n        self.assertIn(\"default\", str(exc.exception))\n\n    def test_invalid_credentials(self):\n        del self.default_profile_data[\"default\"][\"outputs\"][\"postgres\"][\"host\"]\n        with self.assertRaises(dbt.exceptions.DbtProfileError) as exc:\n            self.from_raw_profiles()\n        self.assertIn(\"Credentials\", str(exc.exception))\n        self.assertIn(\"postgres\", str(exc.exception))\n        self.assertIn(\"default\", str(exc.exception))\n\n    def test_missing_target(self):\n        profile = self.default_profile_data[\"default\"]\n        del profile[\"target\"]\n        profile[\"outputs\"][\"default\"] = profile[\"outputs\"][\"postgres\"]\n        profile = self.from_raw_profiles()\n        self.assertEqual(profile.profile_name, \"default\")\n        self.assertEqual(profile.target_name, \"default\")\n        self.assertEqual(profile.credentials.type, \"postgres\")\n\n    def test_extra_path(self):\n        self.default_project_data.update(\n            {\n                \"model-paths\": [\"models\"],\n                \"source-paths\": [\"other-models\"],\n            }\n        )\n        with self.assertRaises(dbt.exceptions.DbtProjectError) as exc:\n            project_from_config_norender(self.default_project_data, project_root=self.project_dir)\n\n        self.assertIn(\"source-paths and model-paths\", str(exc.exception))\n        self.assertIn(\"cannot both be defined.\", str(exc.exception))\n\n    def test_profile_invalid_project(self):\n        renderer = empty_profile_renderer()\n        with self.assertRaises(dbt.exceptions.DbtProjectError) as exc:\n            dbt.config.Profile.from_raw_profiles(\n                self.default_profile_data, \"invalid-profile\", renderer\n            )\n\n        self.assertEqual(exc.exception.result_type, \"invalid_project\")\n        self.assertIn(\"Could not find\", str(exc.exception))\n        self.assertIn(\"invalid-profile\", str(exc.exception))\n\n    def test_profile_invalid_target(self):\n        renderer = empty_profile_renderer()\n        with self.assertRaises(dbt.exceptions.DbtProfileError) as exc:\n            dbt.config.Profile.from_raw_profiles(\n                self.default_profile_data, \"default\", renderer, target_override=\"nope\"\n            )\n\n        self.assertIn(\"nope\", str(exc.exception))\n        self.assertIn(\"- postgres\", str(exc.exception))\n        self.assertIn(\"- with-vars\", str(exc.exception))\n\n    def test_no_outputs(self):\n        renderer = empty_profile_renderer()\n\n        with self.assertRaises(dbt.exceptions.DbtProfileError) as exc:\n            dbt.config.Profile.from_raw_profiles(\n                {\"some-profile\": {\"target\": \"blah\"}}, \"some-profile\", renderer\n            )\n        self.assertIn(\"outputs not specified\", str(exc.exception))\n        self.assertIn(\"some-profile\", str(exc.exception))\n\n    def test_neq(self):\n        profile = self.from_raw_profiles()\n        self.assertNotEqual(profile, object())\n\n    def test_eq(self):\n        renderer = empty_profile_renderer()\n        profile = dbt.config.Profile.from_raw_profiles(\n            deepcopy(self.default_profile_data), \"default\", renderer\n        )\n\n        other = dbt.config.Profile.from_raw_profiles(\n            deepcopy(self.default_profile_data), \"default\", renderer\n        )\n        self.assertEqual(profile, other)\n\n    def test_invalid_env_vars(self):\n        self.env_override[\"env_value_port\"] = \"hello\"\n        with mock.patch.dict(os.environ, self.env_override):\n            with self.assertRaises(dbt.exceptions.DbtProfileError) as exc:\n                safe_set_invocation_context()\n                renderer = empty_profile_renderer()\n                dbt.config.Profile.from_raw_profile_info(\n                    self.default_profile_data[\"default\"],\n                    \"default\",\n                    renderer,\n                    target_override=\"with-vars\",\n                )\n        self.assertIn(\"Could not convert value 'hello' into type 'number'\", str(exc.exception))\n\n\nclass TestProfileFile(BaseConfigTest):\n    def from_raw_profile_info(self, raw_profile=None, profile_name=\"default\", **kwargs):\n        if raw_profile is None:\n            raw_profile = self.default_profile_data[\"default\"]\n        renderer = empty_profile_renderer()\n        kw = {\n            \"raw_profile\": raw_profile,\n            \"profile_name\": profile_name,\n            \"renderer\": renderer,\n        }\n        kw.update(kwargs)\n        return dbt.config.Profile.from_raw_profile_info(**kw)\n\n    def from_args(self, project_profile_name=\"default\", **kwargs):\n        kw = {\n            \"project_profile_name\": project_profile_name,\n            \"renderer\": empty_profile_renderer(),\n            \"threads_override\": self.args.threads,\n            \"target_override\": self.args.target,\n            \"profile_name_override\": self.args.profile,\n        }\n        kw.update(kwargs)\n        return dbt.config.Profile.render(**kw)\n\n    def test_profile_simple(self):\n        profile = self.from_args()\n        from_raw = self.from_raw_profile_info()\n\n        self.assertEqual(profile.profile_name, \"default\")\n        self.assertEqual(profile.target_name, \"postgres\")\n        self.assertEqual(profile.threads, 7)\n        self.assertTrue(isinstance(profile.credentials, PostgresCredentials))\n        self.assertEqual(profile.credentials.type, \"postgres\")\n        self.assertEqual(profile.credentials.host, \"postgres-db-hostname\")\n        self.assertEqual(profile.credentials.port, 5555)\n        self.assertEqual(profile.credentials.user, \"db_user\")\n        self.assertEqual(profile.credentials.password, \"db_pass\")\n        self.assertEqual(profile.credentials.schema, \"postgres-schema\")\n        self.assertEqual(profile.credentials.database, \"postgres-db-name\")\n        self.assertEqual(profile, from_raw)\n\n    def test_profile_override(self):\n        self.args.profile = \"other\"\n        self.args.threads = 3\n        set_from_args(self.args, None)\n        profile = self.from_args()\n        from_raw = self.from_raw_profile_info(\n            self.default_profile_data[\"other\"],\n            \"other\",\n            threads_override=3,\n        )\n\n        self.assertEqual(profile.profile_name, \"other\")\n        self.assertEqual(profile.target_name, \"other-postgres\")\n        self.assertEqual(profile.threads, 3)\n        self.assertTrue(isinstance(profile.credentials, PostgresCredentials))\n        self.assertEqual(profile.credentials.type, \"postgres\")\n        self.assertEqual(profile.credentials.host, \"other-postgres-db-hostname\")\n        self.assertEqual(profile.credentials.port, 4444)\n        self.assertEqual(profile.credentials.user, \"other_db_user\")\n        self.assertEqual(profile.credentials.password, \"other_db_pass\")\n        self.assertEqual(profile.credentials.schema, \"other-postgres-schema\")\n        self.assertEqual(profile.credentials.database, \"other-postgres-db-name\")\n        self.assertEqual(profile, from_raw)\n\n    def test_env_vars(self):\n        self.args.target = \"with-vars\"\n        with mock.patch.dict(os.environ, self.env_override):\n            safe_set_invocation_context()  # reset invocation context with new env\n            profile = self.from_args()\n            from_raw = self.from_raw_profile_info(target_override=\"with-vars\")\n\n        self.assertEqual(profile.profile_name, \"default\")\n        self.assertEqual(profile.target_name, \"with-vars\")\n        self.assertEqual(profile.threads, 1)\n        self.assertEqual(profile.credentials.type, \"postgres\")\n        self.assertEqual(profile.credentials.host, \"env-postgres-host\")\n        self.assertEqual(profile.credentials.port, 6543)\n        self.assertEqual(profile.credentials.user, \"env-postgres-user\")\n        self.assertEqual(profile.credentials.password, \"env-postgres-pass\")\n        self.assertEqual(profile, from_raw)\n\n    def test_env_vars_env_target(self):\n        self.default_profile_data[\"default\"][\"target\"] = \"{{ env_var('env_value_target') }}\"\n        self.write_profile(self.default_profile_data)\n        self.env_override[\"env_value_target\"] = \"with-vars\"\n        with mock.patch.dict(os.environ, self.env_override):\n            safe_set_invocation_context()  # reset invocation context with new env\n            profile = self.from_args()\n            from_raw = self.from_raw_profile_info(target_override=\"with-vars\")\n\n        self.assertEqual(profile.profile_name, \"default\")\n        self.assertEqual(profile.target_name, \"with-vars\")\n        self.assertEqual(profile.threads, 1)\n        self.assertEqual(profile.credentials.type, \"postgres\")\n        self.assertEqual(profile.credentials.host, \"env-postgres-host\")\n        self.assertEqual(profile.credentials.port, 6543)\n        self.assertEqual(profile.credentials.user, \"env-postgres-user\")\n        self.assertEqual(profile.credentials.password, \"env-postgres-pass\")\n        self.assertEqual(profile, from_raw)\n\n    def test_invalid_env_vars(self):\n        self.env_override[\"env_value_port\"] = \"hello\"\n        self.args.target = \"with-vars\"\n        with mock.patch.dict(os.environ, self.env_override):\n            with self.assertRaises(dbt.exceptions.DbtProfileError) as exc:\n                safe_set_invocation_context()  # reset invocation context with new env\n                self.from_args()\n\n        self.assertIn(\"Could not convert value 'hello' into type 'number'\", str(exc.exception))\n\n    def test_cli_and_env_vars(self):\n        self.args.target = \"cli-and-env-vars\"\n        self.args.vars = {\"cli_value_host\": \"cli-postgres-host\"}\n        renderer = dbt.config.renderer.ProfileRenderer({\"cli_value_host\": \"cli-postgres-host\"})\n        with mock.patch.dict(os.environ, self.env_override):\n            safe_set_invocation_context()  # reset invocation context with new env\n            profile = self.from_args(renderer=renderer)\n            from_raw = self.from_raw_profile_info(\n                target_override=\"cli-and-env-vars\",\n                renderer=renderer,\n            )\n\n        self.assertEqual(profile.profile_name, \"default\")\n        self.assertEqual(profile.target_name, \"cli-and-env-vars\")\n        self.assertEqual(profile.threads, 1)\n        self.assertEqual(profile.credentials.type, \"postgres\")\n        self.assertEqual(profile.credentials.host, \"cli-postgres-host\")\n        self.assertEqual(profile.credentials.port, 6543)\n        self.assertEqual(profile.credentials.user, \"env-postgres-user\")\n        self.assertEqual(profile.credentials.password, \"env-postgres-pass\")\n        self.assertEqual(profile, from_raw)\n\n    def test_no_profile(self):\n        with self.assertRaises(dbt.exceptions.DbtProjectError) as exc:\n            self.from_args(project_profile_name=None)\n        self.assertIn(\"no profile was specified\", str(exc.exception))\n\n    def test_empty_profile(self):\n        self.write_empty_profile()\n        with self.assertRaises(dbt.exceptions.DbtProfileError) as exc:\n            self.from_args()\n        self.assertIn(\"profiles.yml is empty\", str(exc.exception))\n\n    def test_profile_with_empty_profile_data(self):\n        renderer = empty_profile_renderer()\n        with self.assertRaises(dbt.exceptions.DbtProfileError) as exc:\n            dbt.config.Profile.from_raw_profiles(\n                self.default_profile_data, \"empty_profile_data\", renderer\n            )\n        self.assertIn(\"Profile empty_profile_data in profiles.yml is empty\", str(exc.exception))\n"
  },
  {
    "path": "tests/unit/config/test_project.py",
    "content": "import json\nimport os\nimport unittest\nfrom copy import deepcopy\nfrom typing import Any, Dict\nfrom unittest import mock\n\nimport pytest\n\nimport dbt.config\nimport dbt.exceptions\nfrom dbt.adapters.contracts.connection import DEFAULT_QUERY_COMMENT, QueryComment\nfrom dbt.adapters.factory import load_plugin\nfrom dbt.config.project import Project, _get_required_version\nfrom dbt.constants import DEPENDENCIES_FILE_NAME\nfrom dbt.contracts.project import GitPackage, LocalPackage, PackageConfig\nfrom dbt.deprecations import (\n    GenericJSONSchemaValidationDeprecation as GenericJSONSchemaValidationDeprecationCore,\n)\nfrom dbt.events.types import GenericJSONSchemaValidationDeprecation\nfrom dbt.flags import set_from_args\nfrom dbt.jsonschemas.jsonschemas import project_schema\nfrom dbt.node_types import NodeType\nfrom dbt.tests.util import safe_set_invocation_context\nfrom dbt_common.events.event_catcher import EventCatcher\nfrom dbt_common.events.event_manager_client import get_event_manager\nfrom dbt_common.events.types import Note\nfrom dbt_common.exceptions import DbtRuntimeError\nfrom dbt_common.semver import VersionSpecifier\nfrom tests.unit.config import (\n    BaseConfigTest,\n    empty_project_renderer,\n    project_from_config_norender,\n    project_from_config_rendered,\n)\n\n\nclass TestProjectMethods:\n    def test_all_source_paths(self, project: Project):\n        assert (\n            project.all_source_paths.sort()\n            == [\"models\", \"seeds\", \"snapshots\", \"analyses\", \"macros\", \"tests\"].sort()\n        )\n\n    def test_generic_test_paths(self, project: Project):\n        assert project.generic_test_paths == [\"tests/generic\"]\n\n    def test_fixture_paths(self, project: Project):\n        assert project.fixture_paths == [\"tests/fixtures\"]\n\n    def test__str__(self, project: Project):\n        assert (\n            str(project)\n            == \"{'name': 'test_project', 'version': 1.0, 'project-root': 'doesnt/actually/exist', 'profile': 'test_profile', 'model-paths': ['models'], 'macro-paths': ['macros'], 'seed-paths': ['seeds'], 'test-paths': ['tests'], 'analysis-paths': ['analyses'], 'docs-paths': ['docs'], 'asset-paths': ['assets'], 'target-path': 'target', 'snapshot-paths': ['snapshots'], 'clean-targets': ['target'], 'log-path': 'path/to/project/logs', 'quoting': {}, 'models': {}, 'on-run-start': [], 'on-run-end': [], 'dispatch': [{'macro_namespace': 'dbt_utils', 'search_order': ['test_project', 'dbt_utils']}], 'seeds': {}, 'snapshots': {}, 'sources': {}, 'data_tests': {}, 'unit_tests': {}, 'metrics': {}, 'semantic-models': {}, 'saved-queries': {}, 'exposures': {}, 'functions': {}, 'vars': {}, 'require-dbt-version': ['=0.0.0'], 'restrict-access': False, 'dbt-cloud': {}, 'flags': {}, 'query-comment': {'comment': \\\"\\\\n{%- set comment_dict = {} -%}\\\\n{%- do comment_dict.update(\\\\n    app='dbt',\\\\n    dbt_version=dbt_version,\\\\n    profile_name=target.get('profile_name'),\\\\n    target_name=target.get('target_name'),\\\\n) -%}\\\\n{%- if node is not none -%}\\\\n  {%- do comment_dict.update(\\\\n    node_id=node.unique_id,\\\\n  ) -%}\\\\n{% else %}\\\\n  {# in the node context, the connection name is the node_id #}\\\\n  {%- do comment_dict.update(connection_name=connection_name) -%}\\\\n{%- endif -%}\\\\n{{ return(tojson(comment_dict)) }}\\\\n\\\", 'append': False, 'job-label': False}, 'packages': []}\"\n        )\n\n    def test_get_selector(self, project: Project):\n        selector = project.get_selector(\"my_selector\")\n        assert selector.raw == \"give me cats\"\n\n        with pytest.raises(DbtRuntimeError):\n            project.get_selector(\"doesnt_exist\")\n\n    def test_get_default_selector_name(self, project: Project):\n        default_selector_name = project.get_default_selector_name()\n        assert default_selector_name == \"my_selector\"\n\n        project.selectors[\"my_selector\"][\"default\"] = False\n        default_selector_name = project.get_default_selector_name()\n        assert default_selector_name is None\n\n    def test_get_macro_search_order(self, project: Project):\n        search_order = project.get_macro_search_order(\"dbt_utils\")\n        assert search_order == [\"test_project\", \"dbt_utils\"]\n\n        search_order = project.get_macro_search_order(\"doesnt_exist\")\n        assert search_order is None\n\n    def test_project_target_path(self, project: Project):\n        assert project.project_target_path == \"doesnt/actually/exist/target\"\n\n    def test_eq(self, project: Project):\n        other = deepcopy(project)\n        assert project == other\n\n    def test_neq(self, project: Project):\n        other = deepcopy(project)\n        other.project_name = \"other project\"\n        assert project != other\n\n    def test_hashed_name(self, project: Project):\n        assert project.hashed_name() == \"6e72a69d5c5cca8f0400338441c022e4\"\n\n\nclass TestProjectInitialization(BaseConfigTest):\n    def test_defaults(self):\n        project = project_from_config_norender(\n            self.default_project_data, project_root=self.project_dir\n        )\n        self.assertEqual(project.project_name, \"my_test_project\")\n        self.assertEqual(project.version, \"0.0.1\")\n        self.assertEqual(project.profile_name, \"default\")\n        self.assertEqual(project.project_root, self.project_dir)\n        self.assertEqual(project.model_paths, [\"models\"])\n        self.assertEqual(project.macro_paths, [\"macros\"])\n        self.assertEqual(project.seed_paths, [\"seeds\"])\n        self.assertEqual(project.test_paths, [\"tests\"])\n        self.assertEqual(project.analysis_paths, [\"analyses\"])\n        self.assertEqual(\n            set(project.docs_paths),\n            {\"models\", \"seeds\", \"snapshots\", \"analyses\", \"macros\", \"tests\", \"functions\"},\n        )\n        self.assertEqual(project.asset_paths, [])\n        self.assertEqual(project.target_path, \"target\")\n        self.assertEqual(project.clean_targets, [\"target\"])\n        self.assertEqual(project.log_path, \"logs\")\n        self.assertEqual(project.packages_install_path, \"dbt_packages\")\n        self.assertEqual(project.quoting, {})\n        self.assertEqual(project.models, {})\n        self.assertEqual(project.on_run_start, [])\n        self.assertEqual(project.on_run_end, [])\n        self.assertEqual(project.seeds, {})\n        self.assertEqual(project.dbt_version, [VersionSpecifier.from_version_string(\">=0.0.0\")])\n        self.assertEqual(project.packages, PackageConfig(packages=[]))\n        # just make sure str() doesn't crash anything, that's always\n        # embarrassing\n        str(project)\n\n    def test_implicit_overrides(self):\n        self.default_project_data.update(\n            {\n                \"model-paths\": [\"other-models\"],\n            }\n        )\n        project = project_from_config_norender(\n            self.default_project_data, project_root=self.project_dir\n        )\n        self.assertEqual(\n            set(project.docs_paths),\n            {\"other-models\", \"seeds\", \"snapshots\", \"analyses\", \"macros\", \"tests\", \"functions\"},\n        )\n\n    def test_all_overrides(self):\n        # log-path is not tested because it is set exclusively from flags, not cfg\n        self.default_project_data.update(\n            {\n                \"model-paths\": [\"other-models\"],\n                \"macro-paths\": [\"other-macros\"],\n                \"seed-paths\": [\"other-seeds\"],\n                \"test-paths\": [\"other-tests\"],\n                \"analysis-paths\": [\"other-analyses\"],\n                \"docs-paths\": [\"docs\"],\n                \"asset-paths\": [\"other-assets\"],\n                \"clean-targets\": [\"another-target\"],\n                \"packages-install-path\": \"other-dbt_packages\",\n                \"quoting\": {\"identifier\": False, \"snowflake_ignore_case\": True},\n                \"models\": {\n                    \"pre-hook\": [\"{{ logging.log_model_start_event() }}\"],\n                    \"post-hook\": [\"{{ logging.log_model_end_event() }}\"],\n                    \"my_test_project\": {\n                        \"first\": {\n                            \"enabled\": False,\n                            \"sub\": {\n                                \"enabled\": True,\n                            },\n                        },\n                        \"second\": {\n                            \"materialized\": \"table\",\n                        },\n                    },\n                    \"third_party\": {\n                        \"third\": {\n                            \"materialized\": \"view\",\n                        },\n                    },\n                },\n                \"on-run-start\": [\n                    \"{{ logging.log_run_start_event() }}\",\n                ],\n                \"on-run-end\": [\n                    \"{{ logging.log_run_end_event() }}\",\n                ],\n                \"seeds\": {\n                    \"my_test_project\": {\n                        \"enabled\": True,\n                        \"schema\": \"seed_data\",\n                        \"post-hook\": \"grant select on {{ this }} to bi_user\",\n                    },\n                },\n                \"data_tests\": {\"my_test_project\": {\"fail_calc\": \"sum(failures)\"}},\n                \"require-dbt-version\": \">=0.1.0\",\n            }\n        )\n        packages = {\n            \"packages\": [\n                {\n                    \"local\": \"foo\",\n                },\n                {\"git\": \"git@example.com:dbt-labs/dbt-utils.git\", \"revision\": \"test-rev\"},\n            ],\n        }\n        project = project_from_config_norender(\n            self.default_project_data, project_root=self.project_dir, packages=packages\n        )\n        self.assertEqual(project.project_name, \"my_test_project\")\n        self.assertEqual(project.version, \"0.0.1\")\n        self.assertEqual(project.profile_name, \"default\")\n        self.assertEqual(project.model_paths, [\"other-models\"])\n        self.assertEqual(project.macro_paths, [\"other-macros\"])\n        self.assertEqual(project.seed_paths, [\"other-seeds\"])\n        self.assertEqual(project.test_paths, [\"other-tests\"])\n        self.assertEqual(project.analysis_paths, [\"other-analyses\"])\n        self.assertEqual(project.docs_paths, [\"docs\"])\n        self.assertEqual(project.asset_paths, [\"other-assets\"])\n        self.assertEqual(project.clean_targets, [\"another-target\"])\n        self.assertEqual(project.packages_install_path, \"other-dbt_packages\")\n        self.assertEqual(project.quoting, {\"identifier\": False, \"snowflake_ignore_case\": True})\n        self.assertEqual(\n            project.models,\n            {\n                \"pre-hook\": [\"{{ logging.log_model_start_event() }}\"],\n                \"post-hook\": [\"{{ logging.log_model_end_event() }}\"],\n                \"my_test_project\": {\n                    \"first\": {\n                        \"enabled\": False,\n                        \"sub\": {\n                            \"enabled\": True,\n                        },\n                    },\n                    \"second\": {\n                        \"materialized\": \"table\",\n                    },\n                },\n                \"third_party\": {\n                    \"third\": {\n                        \"materialized\": \"view\",\n                    },\n                },\n            },\n        )\n        self.assertEqual(project.on_run_start, [\"{{ logging.log_run_start_event() }}\"])\n        self.assertEqual(project.on_run_end, [\"{{ logging.log_run_end_event() }}\"])\n        self.assertEqual(\n            project.seeds,\n            {\n                \"my_test_project\": {\n                    \"enabled\": True,\n                    \"schema\": \"seed_data\",\n                    \"post-hook\": \"grant select on {{ this }} to bi_user\",\n                },\n            },\n        )\n        self.assertEqual(\n            project.data_tests,\n            {\n                \"my_test_project\": {\"fail_calc\": \"sum(failures)\"},\n            },\n        )\n        self.assertEqual(project.dbt_version, [VersionSpecifier.from_version_string(\">=0.1.0\")])\n        self.assertEqual(\n            project.packages,\n            PackageConfig(\n                packages=[\n                    LocalPackage(local=\"foo\", unrendered={\"local\": \"foo\"}),\n                    GitPackage(\n                        git=\"git@example.com:dbt-labs/dbt-utils.git\",\n                        revision=\"test-rev\",\n                        unrendered={\n                            \"git\": \"git@example.com:dbt-labs/dbt-utils.git\",\n                            \"revision\": \"test-rev\",\n                        },\n                    ),\n                ]\n            ),\n        )\n        str(project)  # this does the equivalent of project.to_project_config(with_packages=True)\n        json.dumps(project.to_project_config())\n\n    def test_string_run_hooks(self):\n        self.default_project_data.update(\n            {\n                \"on-run-start\": \"{{ logging.log_run_start_event() }}\",\n                \"on-run-end\": \"{{ logging.log_run_end_event() }}\",\n            }\n        )\n        project = project_from_config_rendered(self.default_project_data)\n        self.assertEqual(project.on_run_start, [\"{{ logging.log_run_start_event() }}\"])\n        self.assertEqual(project.on_run_end, [\"{{ logging.log_run_end_event() }}\"])\n\n    def test_invalid_project_name(self):\n        self.default_project_data[\"name\"] = \"invalid-project-name\"\n        with self.assertRaises(dbt.exceptions.DbtProjectError) as exc:\n            project_from_config_norender(self.default_project_data, project_root=self.project_dir)\n\n        self.assertIn(\"invalid-project-name\", str(exc.exception))\n\n    def test_no_project(self):\n        os.remove(os.path.join(self.project_dir, \"dbt_project.yml\"))\n        renderer = empty_project_renderer()\n        with self.assertRaises(dbt.exceptions.DbtProjectError) as exc:\n            dbt.config.Project.from_project_root(self.project_dir, renderer)\n\n        self.assertIn(\"No dbt_project.yml\", str(exc.exception))\n\n    def test_invalid_version(self):\n        self.default_project_data[\"require-dbt-version\"] = \"hello!\"\n        with self.assertRaises(dbt.exceptions.DbtProjectError):\n            project_from_config_norender(self.default_project_data, project_root=self.project_dir)\n\n    def test_unsupported_version(self):\n        self.default_project_data[\"require-dbt-version\"] = \">99999.0.0\"\n        # allowed, because the RuntimeConfig checks, not the Project itself\n        project_from_config_norender(self.default_project_data, project_root=self.project_dir)\n\n    def test_none_values(self):\n        self.default_project_data.update(\n            {\n                \"models\": None,\n                \"seeds\": None,\n                \"on-run-end\": None,\n                \"on-run-start\": None,\n            }\n        )\n        project = project_from_config_rendered(self.default_project_data)\n        self.assertEqual(project.models, {})\n        self.assertEqual(project.on_run_start, [])\n        self.assertEqual(project.on_run_end, [])\n        self.assertEqual(project.seeds, {})\n\n    def test_nested_none_values(self):\n        self.default_project_data.update(\n            {\n                \"models\": {\"vars\": None, \"pre-hook\": None, \"post-hook\": None},\n                \"seeds\": {\"vars\": None, \"pre-hook\": None, \"post-hook\": None, \"column_types\": None},\n            }\n        )\n        project = project_from_config_rendered(self.default_project_data)\n        self.assertEqual(project.models, {\"vars\": {}, \"pre-hook\": [], \"post-hook\": []})\n        self.assertEqual(\n            project.seeds, {\"vars\": {}, \"pre-hook\": [], \"post-hook\": [], \"column_types\": {}}\n        )\n\n    @pytest.mark.skipif(os.name == \"nt\", reason=\"crashes CI for Windows\")\n    def test_cycle(self):\n        models = {}\n        models[\"models\"] = models\n        self.default_project_data.update(\n            {\n                \"models\": models,\n            }\n        )\n        with self.assertRaises(dbt.exceptions.DbtProjectError) as exc:\n            project_from_config_rendered(self.default_project_data)\n\n        assert \"Cycle detected\" in str(exc.exception)\n\n    def test_query_comment_empty(self):\n        self.default_project_data.update(\n            {\n                \"query-comment\": None,\n            }\n        )\n        project = project_from_config_norender(\n            self.default_project_data, project_root=self.project_dir\n        )\n        self.assertEqual(project.query_comment.comment, \"\")\n        self.assertEqual(project.query_comment.append, QueryComment().append)\n\n        self.default_project_data.update(\n            {\n                \"query-comment\": \"\",\n            }\n        )\n        project = project_from_config_norender(\n            self.default_project_data, project_root=self.project_dir\n        )\n        self.assertEqual(project.query_comment.comment, \"\")\n        self.assertEqual(project.query_comment.append, QueryComment().append)\n\n    def test_default_query_comment(self):\n        project = project_from_config_norender(\n            self.default_project_data, project_root=self.project_dir\n        )\n        self.assertEqual(project.query_comment, QueryComment())\n\n    def test_default_query_comment_append(self):\n        self.default_project_data.update(\n            {\n                \"query-comment\": {\"append\": True},\n            }\n        )\n        project = project_from_config_norender(\n            self.default_project_data, project_root=self.project_dir\n        )\n        self.assertEqual(project.query_comment.comment, DEFAULT_QUERY_COMMENT)\n        self.assertEqual(project.query_comment.append, True)\n\n    def test_custom_query_comment_append(self):\n        self.default_project_data.update(\n            {\n                \"query-comment\": {\"comment\": \"run by user test\", \"append\": True},\n            }\n        )\n        project = project_from_config_norender(\n            self.default_project_data, project_root=self.project_dir\n        )\n        self.assertEqual(project.query_comment.comment, \"run by user test\")\n        self.assertEqual(project.query_comment.append, True)\n\n    def test_default_query_comment_append_False(self):\n        self.default_project_data.update(\n            {\n                \"query-comment\": {\"append\": False},\n            }\n        )\n        project = project_from_config_norender(\n            self.default_project_data, project_root=self.project_dir\n        )\n        self.assertEqual(project.query_comment.comment, DEFAULT_QUERY_COMMENT)\n        self.assertEqual(project.query_comment.append, False)\n\n    def test_custom_query_comment_append_false(self):\n        self.default_project_data.update(\n            {\n                \"query-comment\": {\"comment\": \"run by user test\", \"append\": False},\n            }\n        )\n        project = project_from_config_norender(\n            self.default_project_data, project_root=self.project_dir\n        )\n        self.assertEqual(project.query_comment.comment, \"run by user test\")\n        self.assertEqual(project.query_comment.append, False)\n\n    def test_packages_from_dependencies(self):\n        packages = {\n            \"packages\": [\n                {\n                    \"git\": \"{{ env_var('some_package') }}\",\n                    \"warn-unpinned\": True,\n                }\n            ],\n        }\n\n        project = project_from_config_rendered(\n            self.default_project_data, packages, packages_specified_path=DEPENDENCIES_FILE_NAME\n        )\n        git_package = project.packages.packages[0]\n        # packages did not render because packages_specified_path=DEPENDENCIES_FILE_NAME\n        assert git_package.git == \"{{ env_var('some_package') }}\"\n\n\nclass TestProjectFile(BaseConfigTest):\n    def test_from_project_root(self):\n        renderer = empty_project_renderer()\n        project = dbt.config.Project.from_project_root(self.project_dir, renderer)\n        from_config = project_from_config_norender(\n            self.default_project_data, project_root=self.project_dir\n        )\n        self.assertEqual(project, from_config)\n        self.assertEqual(project.version, \"0.0.1\")\n        self.assertEqual(project.project_name, \"my_test_project\")\n\n    def test_with_invalid_package(self):\n        renderer = empty_project_renderer()\n        self.write_packages({\"invalid\": [\"not a package of any kind\"]})\n        with self.assertRaises(dbt.exceptions.DbtProjectError):\n            dbt.config.Project.from_project_root(self.project_dir, renderer)\n\n\nclass TestVariableProjectFile(BaseConfigTest):\n    def setUp(self):\n        super().setUp()\n        self.default_project_data[\"version\"] = \"{{ var('cli_version') }}\"\n        self.default_project_data[\"name\"] = \"blah\"\n        self.default_project_data[\"profile\"] = \"{{ env_var('env_value_profile') }}\"\n        self.write_project(self.default_project_data)\n\n    def test_cli_and_env_vars(self):\n        renderer = dbt.config.renderer.DbtProjectYamlRenderer(None, {\"cli_version\": \"0.1.2\"})\n        with mock.patch.dict(os.environ, self.env_override):\n            safe_set_invocation_context()  # reset invocation context with new env\n            project = dbt.config.Project.from_project_root(\n                self.project_dir,\n                renderer,\n            )\n\n        self.assertEqual(renderer.ctx_obj.env_vars, {\"env_value_profile\": \"default\"})\n        self.assertEqual(project.version, \"0.1.2\")\n        self.assertEqual(project.project_name, \"blah\")\n        self.assertEqual(project.profile_name, \"default\")\n\n\nclass TestVarLookups(unittest.TestCase):\n    def setUp(self):\n        self.initial_src_vars = {\n            # globals\n            \"foo\": 123,\n            \"bar\": \"hello\",\n            # project-scoped\n            \"my_project\": {\n                \"bar\": \"goodbye\",\n                \"baz\": True,\n            },\n            \"other_project\": {\n                \"foo\": 456,\n            },\n        }\n        self.src_vars = deepcopy(self.initial_src_vars)\n        self.dst = {\"vars\": deepcopy(self.initial_src_vars)}\n\n        self.projects = [\"my_project\", \"other_project\", \"third_project\"]\n        load_plugin(\"postgres\")\n        self.local_var_search = mock.MagicMock(\n            fqn=[\"my_project\", \"my_model\"], resource_type=NodeType.Model, package_name=\"my_project\"\n        )\n        self.other_var_search = mock.MagicMock(\n            fqn=[\"other_project\", \"model\"],\n            resource_type=NodeType.Model,\n            package_name=\"other_project\",\n        )\n        self.third_var_search = mock.MagicMock(\n            fqn=[\"third_project\", \"third_model\"],\n            resource_type=NodeType.Model,\n            package_name=\"third_project\",\n        )\n\n    def test_lookups(self):\n        vars_provider = dbt.config.project.VarProvider(self.initial_src_vars)\n\n        expected = [\n            (self.local_var_search, \"foo\", 123),\n            (self.other_var_search, \"foo\", 456),\n            (self.third_var_search, \"foo\", 123),\n            (self.local_var_search, \"bar\", \"goodbye\"),\n            (self.other_var_search, \"bar\", \"hello\"),\n            (self.third_var_search, \"bar\", \"hello\"),\n            (self.local_var_search, \"baz\", True),\n            (self.other_var_search, \"baz\", None),\n            (self.third_var_search, \"baz\", None),\n        ]\n        for node, key, expected_value in expected:\n            value = vars_provider.vars_for(node, \"postgres\").get(key)\n            assert value == expected_value\n\n\nclass TestMultipleProjectFlags(BaseConfigTest):\n    def setUp(self):\n        super().setUp()\n\n        self.default_project_data.update(\n            {\n                \"flags\": {\n                    \"send_anonymous_usage_data\": False,\n                }\n            }\n        )\n        self.write_project(self.default_project_data)\n\n        self.default_profile_data.update(\n            {\n                \"config\": {\n                    \"send_anonymous_usage_data\": False,\n                }\n            }\n        )\n        self.write_profile(self.default_profile_data)\n\n    def test_setting_multiple_flags(self):\n        with pytest.raises(dbt.exceptions.DbtProjectError):\n            set_from_args(self.args, None)\n\n\nclass TestGetRequiredVersion:\n    @pytest.fixture\n    def project_dict(self) -> Dict[str, Any]:\n        return {\n            \"name\": \"test_project\",\n            \"require-dbt-version\": \">0.0.0\",\n        }\n\n    def test_supported_version(self, project_dict: Dict[str, Any]) -> None:\n        specifiers = _get_required_version(project_dict=project_dict, verify_version=True)\n        assert set(x.to_version_string() for x in specifiers) == {\">0.0.0\"}\n\n    def test_unsupported_version(self, project_dict: Dict[str, Any]) -> None:\n        project_dict[\"require-dbt-version\"] = \">99999.0.0\"\n        with pytest.raises(\n            dbt.exceptions.DbtProjectError, match=\"This version of dbt is not supported\"\n        ):\n            _get_required_version(project_dict=project_dict, verify_version=True)\n\n    def test_unsupported_version_no_check(self, project_dict: Dict[str, Any]) -> None:\n        project_dict[\"require-dbt-version\"] = \">99999.0.0\"\n        specifiers = _get_required_version(project_dict=project_dict, verify_version=False)\n        assert set(x.to_version_string() for x in specifiers) == {\">99999.0.0\"}\n\n    def test_supported_version_range(self, project_dict: Dict[str, Any]) -> None:\n        project_dict[\"require-dbt-version\"] = [\">0.0.0\", \"<=99999.0.0\"]\n        specifiers = _get_required_version(project_dict=project_dict, verify_version=True)\n        assert set(x.to_version_string() for x in specifiers) == {\">0.0.0\", \"<=99999.0.0\"}\n\n    def test_unsupported_version_range(self, project_dict: Dict[str, Any]) -> None:\n        project_dict[\"require-dbt-version\"] = [\">0.0.0\", \"<=0.0.1\"]\n        with pytest.raises(\n            dbt.exceptions.DbtProjectError, match=\"This version of dbt is not supported\"\n        ):\n            _get_required_version(project_dict=project_dict, verify_version=True)\n\n    def test_unsupported_version_range_no_check(self, project_dict: Dict[str, Any]) -> None:\n        project_dict[\"require-dbt-version\"] = [\">0.0.0\", \"<=0.0.1\"]\n        specifiers = _get_required_version(project_dict=project_dict, verify_version=False)\n        assert set(x.to_version_string() for x in specifiers) == {\">0.0.0\", \"<=0.0.1\"}\n\n    def test_impossible_version_range(self, project_dict: Dict[str, Any]) -> None:\n        project_dict[\"require-dbt-version\"] = [\">99999.0.0\", \"<=0.0.1\"]\n        with pytest.raises(\n            dbt.exceptions.DbtProjectError,\n            match=\"The package version requirement can never be satisfied\",\n        ):\n            _get_required_version(project_dict=project_dict, verify_version=True)\n\n\nclass TestDeprecations:\n\n    def test_jsonschema_validate(self) -> None:\n        from dbt.jsonschemas.jsonschemas import jsonschema_validate\n\n        project_dict: Dict[str, Any] = {}\n\n        event_catcher = EventCatcher(GenericJSONSchemaValidationDeprecation)\n        note_catcher = EventCatcher(Note)\n        get_event_manager().add_callback(event_catcher.catch)\n        get_event_manager().add_callback(note_catcher.catch)\n\n        jsonschema_validate(\n            schema=project_schema(), json=project_dict, file_path=\"dbt_project.yml\"\n        )\n\n        if GenericJSONSchemaValidationDeprecationCore()._is_preview:\n            assert len(note_catcher.caught_events) == 1\n            assert len(event_catcher.caught_events) == 0\n            event = note_catcher.caught_events[0]\n        else:\n            assert len(event_catcher.caught_events) == 1\n            assert len(note_catcher.caught_events) == 0\n            event = event_catcher.caught_events[0]\n\n        assert \"'name' is a required property at top level\" in event.info.msg\n"
  },
  {
    "path": "tests/unit/config/test_renderer_with_vars.py",
    "content": "\"\"\"Unit tests for rendering dbt_project.yml with vars without defaults.\"\"\"\n\nimport pytest\n\nfrom dbt.config.renderer import DbtProjectYamlRenderer\nfrom dbt.context.base import BaseContext\n\n\nclass TestRendererWithRequiredVars:\n    \"\"\"Test that DbtProjectYamlRenderer doesn't raise errors for missing vars\"\"\"\n\n    def test_base_context_with_require_vars_false(self):\n        \"\"\"Test that BaseContext with require_vars=False returns None for missing vars\"\"\"\n        context = BaseContext(cli_vars={}, require_vars=False)\n        var_func = context.var\n\n        # Missing var should return None when require_vars=False\n        assert var_func(\"missing_var\") is None\n\n        # Missing var with default should return the default\n        assert var_func(\"missing_var\", \"default_value\") == \"default_value\"\n\n        # Existing var should return the value\n        context2 = BaseContext(cli_vars={\"existing_var\": \"value\"}, require_vars=False)\n        var_func2 = context2.var\n        assert var_func2(\"existing_var\") == \"value\"\n\n    def test_base_context_with_require_vars_true_raises_error(self):\n        \"\"\"Test that BaseContext with require_vars=True raises error for missing vars\"\"\"\n        from dbt.exceptions import RequiredVarNotFoundError\n\n        context = BaseContext(cli_vars={}, require_vars=True)\n        var_func = context.var\n\n        # Missing var should raise error when require_vars=True\n        with pytest.raises(RequiredVarNotFoundError):\n            var_func(\"missing_var\")\n\n    def test_dbt_project_yaml_renderer_doesnt_fail_on_missing_vars(self):\n        \"\"\"Test that DbtProjectYamlRenderer with require_vars=False can render configs with missing vars\"\"\"\n        # Pass require_vars=False to enable lenient mode (used by dbt deps)\n        renderer = DbtProjectYamlRenderer(profile=None, cli_vars={}, require_vars=False)\n\n        # This project config uses a var without a default value\n        project_dict = {\n            \"name\": \"test_project\",\n            \"version\": \"1.0\",\n            \"models\": {\"test_project\": {\"+dataset\": \"dqm_{{ var('my_dataset') }}\"}},\n        }\n\n        # This should not raise an error in lenient mode\n        rendered = renderer.render_data(project_dict)\n\n        # The var should be rendered as None (which becomes \"dqm_None\" in the string)\n        assert \"models\" in rendered\n        assert \"test_project\" in rendered[\"models\"]\n        # When var returns None, it gets stringified in the template\n        assert rendered[\"models\"][\"test_project\"][\"+dataset\"] == \"dqm_None\"\n\n    def test_dbt_project_yaml_renderer_with_provided_var(self):\n        \"\"\"Test that DbtProjectYamlRenderer works correctly when var is provided\"\"\"\n        renderer = DbtProjectYamlRenderer(profile=None, cli_vars={\"my_dataset\": \"prod\"})\n\n        project_dict = {\n            \"name\": \"test_project\",\n            \"version\": \"1.0\",\n            \"models\": {\"test_project\": {\"+dataset\": \"dqm_{{ var('my_dataset') }}\"}},\n        }\n\n        # This should render correctly with the provided var\n        rendered = renderer.render_data(project_dict)\n\n        # The var should be properly rendered\n        assert rendered[\"models\"][\"test_project\"][\"+dataset\"] == \"dqm_prod\"\n"
  },
  {
    "path": "tests/unit/config/test_runtime.py",
    "content": "import os\nimport tempfile\nfrom argparse import Namespace\nfrom typing import Any, Dict\nfrom unittest import mock\n\nimport pytest\nfrom pytest_mock import MockerFixture\n\nimport dbt.config\nimport dbt.exceptions\nfrom dbt import tracking\nfrom dbt.config.profile import Profile\nfrom dbt.config.project import Project\nfrom dbt.config.runtime import RuntimeConfig\nfrom dbt.contracts.project import PackageConfig\nfrom dbt.events.types import UnusedResourceConfigPath\nfrom dbt.flags import set_from_args\nfrom dbt.tests.util import safe_set_invocation_context\nfrom dbt_common.events.event_catcher import EventCatcher\nfrom dbt_common.events.event_manager_client import add_callback_to_manager\nfrom tests.unit.config import BaseConfigTest, temp_cd\n\n\nclass TestRuntimeConfig:\n    @pytest.fixture\n    def args(self) -> Namespace:\n        return Namespace(\n            profiles_dir=tempfile.mkdtemp(),\n            cli_vars={},\n            version_check=True,\n            project_dir=tempfile.mkdtemp(),\n            target=None,\n            threads=None,\n            profile=None,\n        )\n\n    def test_str(self, profile: Profile, project: Project) -> None:\n        config = dbt.config.RuntimeConfig.from_parts(project, profile, {})\n\n        # to make sure nothing terrible happens\n        str(config)\n\n    def test_from_parts(self, args: Namespace, profile: Profile, project: Project):\n        config = dbt.config.RuntimeConfig.from_parts(project, profile, args)\n\n        assert config.cli_vars == {}\n        assert config.to_profile_info() == profile.to_profile_info()\n        # we should have the default quoting set in the full config, but not in\n        # the project\n        # TODO(jeb): Adapters must assert that quoting is populated?\n        expected_project = project.to_project_config()\n        assert expected_project[\"quoting\"] == {}\n\n        expected_project[\"quoting\"] = {\n            \"database\": True,\n            \"identifier\": True,\n            \"schema\": True,\n        }\n        assert config.to_project_config() == expected_project\n\n    def test_get_metadata(self, mocker: MockerFixture, runtime_config: RuntimeConfig) -> None:\n        mock_user = mocker.patch.object(tracking, \"active_user\")\n        mock_user.id = \"cfc9500f-dc7f-4c83-9ea7-2c581c1b38cf\"\n        set_from_args(Namespace(SEND_ANONYMOUS_USAGE_STATS=False), None)\n\n        metadata = runtime_config.get_metadata()\n        # ensure user_id and send_anonymous_usage_stats are set correctly\n        assert metadata.user_id == mock_user.id\n        assert not metadata.send_anonymous_usage_stats\n\n    @pytest.fixture\n    def used_fqns(self) -> Dict[str, Any]:\n        return {\"models\": frozenset(((\"my_test_project\", \"foo\", \"bar\"),))}\n\n    def test_warn_for_unused_resource_config_paths(\n        self,\n        runtime_config: RuntimeConfig,\n        used_fqns: Dict[str, Any],\n    ):\n        catcher = EventCatcher(event_to_catch=UnusedResourceConfigPath)\n        add_callback_to_manager(catcher.catch)\n\n        runtime_config.models = {\n            \"my_test_project\": {\n                \"foo\": {\n                    \"materialized\": \"view\",\n                    \"bar\": {\n                        \"materialized\": \"table\",\n                    },\n                    \"baz\": {\n                        \"materialized\": \"table\",\n                    },\n                }\n            }\n        }\n\n        runtime_config.warn_for_unused_resource_config_paths(used_fqns, [])\n        len(catcher.caught_events) == 1\n        expected_msg = \"models.my_test_project.foo.baz\"\n        assert expected_msg in str(catcher.caught_events[0].data)\n\n    def test_warn_for_unused_resource_config_paths_empty_models(\n        self,\n        runtime_config: RuntimeConfig,\n        used_fqns: Dict[str, Any],\n    ) -> None:\n        catcher = EventCatcher(event_to_catch=UnusedResourceConfigPath)\n        add_callback_to_manager(catcher.catch)\n\n        # models should already be empty, but lets ensure it\n        runtime_config.models = {}\n\n        runtime_config.warn_for_unused_resource_config_paths(used_fqns, ())\n        assert len(catcher.caught_events) == 0\n\n\nclass TestRuntimeConfigFiles(BaseConfigTest):\n    def test_from_args(self):\n        with temp_cd(self.project_dir):\n            config = dbt.config.RuntimeConfig.from_args(self.args)\n        self.assertEqual(config.version, \"0.0.1\")\n        self.assertEqual(config.profile_name, \"default\")\n        # on osx, for example, these are not necessarily equal due to /private\n        self.assertTrue(os.path.samefile(config.project_root, self.project_dir))\n        self.assertEqual(config.model_paths, [\"models\"])\n        self.assertEqual(config.macro_paths, [\"macros\"])\n        self.assertEqual(config.seed_paths, [\"seeds\"])\n        self.assertEqual(config.test_paths, [\"tests\"])\n        self.assertEqual(config.analysis_paths, [\"analyses\"])\n        self.assertEqual(\n            set(config.docs_paths),\n            {\"models\", \"seeds\", \"snapshots\", \"analyses\", \"macros\", \"tests\", \"functions\"},\n        )\n        self.assertEqual(config.asset_paths, [])\n        self.assertEqual(config.target_path, \"target\")\n        self.assertEqual(config.clean_targets, [\"target\"])\n        self.assertEqual(config.log_path, \"logs\")\n        self.assertEqual(config.packages_install_path, \"dbt_packages\")\n        self.assertEqual(config.quoting, {\"database\": True, \"identifier\": True, \"schema\": True})\n        self.assertEqual(config.models, {})\n        self.assertEqual(config.on_run_start, [])\n        self.assertEqual(config.on_run_end, [])\n        self.assertEqual(config.seeds, {})\n        self.assertEqual(config.packages, PackageConfig(packages=[]))\n        self.assertEqual(config.project_name, \"my_test_project\")\n\n\nclass TestVariableRuntimeConfigFiles(BaseConfigTest):\n    def setUp(self):\n        super().setUp()\n        self.default_project_data.update(\n            {\n                \"version\": \"{{ var('cli_version') }}\",\n                \"name\": \"blah\",\n                \"profile\": \"{{ env_var('env_value_profile') }}\",\n                \"on-run-end\": [\n                    \"{{ env_var('env_value_profile') }}\",\n                ],\n                \"models\": {\n                    \"foo\": {\n                        \"post-hook\": \"{{ env_var('env_value_profile') }}\",\n                    },\n                    \"bar\": {\n                        # just gibberish, make sure it gets interpreted\n                        \"materialized\": \"{{ env_var('env_value_profile') }}\",\n                    },\n                },\n                \"seeds\": {\n                    \"foo\": {\n                        \"post-hook\": \"{{ env_var('env_value_profile') }}\",\n                    },\n                    \"bar\": {\n                        # just gibberish, make sure it gets interpreted\n                        \"materialized\": \"{{ env_var('env_value_profile') }}\",\n                    },\n                },\n            }\n        )\n        self.write_project(self.default_project_data)\n\n    def test_cli_and_env_vars(self):\n        self.args.target = \"cli-and-env-vars\"\n        self.args.vars = {\"cli_value_host\": \"cli-postgres-host\", \"cli_version\": \"0.1.2\"}\n        self.args.project_dir = self.project_dir\n        set_from_args(self.args, None)\n        with mock.patch.dict(os.environ, self.env_override):\n            safe_set_invocation_context()  # reset invocation context with new env\n            config = dbt.config.RuntimeConfig.from_args(self.args)\n\n        self.assertEqual(config.version, \"0.1.2\")\n        self.assertEqual(config.project_name, \"blah\")\n        self.assertEqual(config.profile_name, \"default\")\n        self.assertEqual(config.credentials.host, \"cli-postgres-host\")\n        self.assertEqual(config.credentials.user, \"env-postgres-user\")\n        # make sure hooks are not interpreted\n        self.assertEqual(config.on_run_end, [\"{{ env_var('env_value_profile') }}\"])\n        self.assertEqual(config.models[\"foo\"][\"post-hook\"], \"{{ env_var('env_value_profile') }}\")\n        self.assertEqual(config.models[\"bar\"][\"materialized\"], \"default\")  # rendered!\n        self.assertEqual(config.seeds[\"foo\"][\"post-hook\"], \"{{ env_var('env_value_profile') }}\")\n        self.assertEqual(config.seeds[\"bar\"][\"materialized\"], \"default\")  # rendered!\n"
  },
  {
    "path": "tests/unit/config/test_selectors.py",
    "content": "import textwrap\nimport unittest\n\nimport yaml\n\nimport dbt.exceptions\nfrom dbt.config.selectors import SelectorConfig, SelectorDict, selector_config_from_data\n\n\ndef get_selector_dict(txt: str) -> dict:\n    txt = textwrap.dedent(txt)\n    dct = yaml.safe_load(txt)\n    return dct\n\n\nclass SelectorUnitTest(unittest.TestCase):\n    def test_parse_multiple_excludes(self):\n        dct = get_selector_dict(\n            \"\"\"\\\n            selectors:\n                - name: mult_excl\n                  definition:\n                    union:\n                      - method: tag\n                        value: nightly\n                      - exclude:\n                         - method: tag\n                           value: hourly\n                      - exclude:\n                         - method: tag\n                           value: daily\n            \"\"\"\n        )\n        with self.assertRaisesRegex(\n            dbt.exceptions.DbtSelectorsError, \"cannot provide multiple exclude arguments\"\n        ):\n            selector_config_from_data(dct)\n\n    def test_parse_set_op_plus(self):\n        dct = get_selector_dict(\n            \"\"\"\\\n            selectors:\n                - name: union_plus\n                  definition:\n                    - union:\n                       - method: tag\n                         value: nightly\n                       - exclude:\n                          - method: tag\n                            value: hourly\n                    - method: tag\n                      value: foo\n            \"\"\"\n        )\n        with self.assertRaisesRegex(\n            dbt.exceptions.DbtSelectorsError, \"Valid root-level selector definitions\"\n        ):\n            selector_config_from_data(dct)\n\n    def test_parse_multiple_methods(self):\n        dct = get_selector_dict(\n            \"\"\"\\\n            selectors:\n                - name: mult_methods\n                  definition:\n                    - tag:hourly\n                    - tag:nightly\n                    - fqn:start\n            \"\"\"\n        )\n        with self.assertRaisesRegex(\n            dbt.exceptions.DbtSelectorsError, \"Valid root-level selector definitions\"\n        ):\n            selector_config_from_data(dct)\n\n    def test_parse_set_with_method(self):\n        dct = get_selector_dict(\n            \"\"\"\\\n                selectors:\n                  - name: mixed_syntaxes\n                    definition:\n                      key: value\n                      method: tag\n                      value: foo\n                      union:\n                        - method: tag\n                          value: m1234\n                        - exclude:\n                          - method: tag\n                            value: m5678\n            \"\"\"\n        )\n        with self.assertRaisesRegex(\n            dbt.exceptions.DbtSelectorsError,\n            \"Only a single 'union' or 'intersection' key is allowed\",\n        ):\n            selector_config_from_data(dct)\n\n    def test_complex_sector(self):\n        dct = get_selector_dict(\n            \"\"\"\\\n                selectors:\n                  - name: nightly_diet_snowplow\n                    definition:\n                      union:\n                        - intersection:\n                            - method: source\n                              value: snowplow\n                              childrens_parents: true\n                            - method: tag\n                              value: nightly\n                        - method: path\n                          value: models/export\n                        - exclude:\n                            - intersection:\n                                - method: package\n                                  value: snowplow\n                                - method: config.materialized\n                                  value: incremental\n                            - method: fqn\n                              value: export_performance_timing\n            \"\"\"\n        )\n        selectors = selector_config_from_data(dct)\n        assert isinstance(selectors, SelectorConfig)\n\n    def test_exclude_not_list(self):\n        dct = get_selector_dict(\n            \"\"\"\\\n                selectors:\n                  - name: summa_exclude\n                    definition:\n                      union:\n                        - method: tag\n                          value: nightly\n                        - exclude:\n                            method: tag\n                            value: daily\n            \"\"\"\n        )\n        with self.assertRaisesRegex(dbt.exceptions.DbtSelectorsError, \"Expected a list\"):\n            selector_config_from_data(dct)\n\n    def test_invalid_key(self):\n        dct = get_selector_dict(\n            \"\"\"\\\n                selectors:\n                  - name: summa_nothing\n                    definition:\n                      method: tag\n                      key: nightly\n            \"\"\"\n        )\n        with self.assertRaisesRegex(dbt.exceptions.DbtSelectorsError, \"Expected either 1 key\"):\n            selector_config_from_data(dct)\n\n    def test_invalid_single_def(self):\n        dct = get_selector_dict(\n            \"\"\"\\\n                selectors:\n                  - name: summa_nothing\n                    definition:\n                      fubar: tag\n            \"\"\"\n        )\n        with self.assertRaisesRegex(dbt.exceptions.DbtSelectorsError, \"not a valid method name\"):\n            selector_config_from_data(dct)\n\n    def test_method_no_value(self):\n        dct = get_selector_dict(\n            \"\"\"\\\n                selectors:\n                  - name: summa_nothing\n                    definition:\n                      method: tag\n            \"\"\"\n        )\n        with self.assertRaisesRegex(dbt.exceptions.DbtSelectorsError, \"not a valid method name\"):\n            selector_config_from_data(dct)\n\n    def test_multiple_default_true(self):\n        \"\"\"Test selector_config_from_data returns the correct error when multiple\n        default values are set\n        \"\"\"\n        dct = get_selector_dict(\n            \"\"\"\\\n                selectors:\n                  - name: summa_nothing\n                    definition:\n                      method: tag\n                      value: nightly\n                    default: true\n                  - name: summa_something\n                    definition:\n                      method: tag\n                      value: daily\n                    default: true\n        \"\"\"\n        )\n        with self.assertRaisesRegex(\n            dbt.exceptions.DbtSelectorsError, \"Found multiple selectors with `default: true`:\"\n        ):\n            selector_config_from_data(dct)\n\n    def test_compare_cli_non_cli(self):\n        dct = get_selector_dict(\n            \"\"\"\\\n            selectors:\n              - name: nightly_diet_snowplow\n                description: \"This uses more CLI-style syntax\"\n                definition:\n                  union:\n                    - intersection:\n                        - '@source:snowplow'\n                        - 'tag:nightly'\n                    - 'models/export'\n                    - exclude:\n                        - intersection:\n                            - 'package:snowplow'\n                            - 'config.materialized:incremental'\n                        - export_performance_timing\n              - name: nightly_diet_snowplow_full\n                description: \"This is a fuller YAML specification\"\n                definition:\n                  union:\n                    - intersection:\n                        - method: source\n                          value: snowplow\n                          childrens_parents: true\n                        - method: tag\n                          value: nightly\n                    - method: path\n                      value: models/export\n                    - exclude:\n                        - intersection:\n                            - method: package\n                              value: snowplow\n                            - method: config.materialized\n                              value: incremental\n                        - method: fqn\n                          value: export_performance_timing\n            \"\"\"\n        )\n\n        sel_dict = SelectorDict.parse_from_selectors_list(dct[\"selectors\"])\n        assert sel_dict\n        with_strings = sel_dict[\"nightly_diet_snowplow\"][\"definition\"]\n        no_strings = sel_dict[\"nightly_diet_snowplow_full\"][\"definition\"]\n        self.assertEqual(with_strings, no_strings)\n\n    def test_single_string_definition(self):\n        dct = get_selector_dict(\n            \"\"\"\\\n            selectors:\n              - name: nightly_selector\n                definition:\n                  'tag:nightly'\n            \"\"\"\n        )\n\n        sel_dict = SelectorDict.parse_from_selectors_list(dct[\"selectors\"])\n        assert sel_dict\n        expected = {\"method\": \"tag\", \"value\": \"nightly\"}\n        definition = sel_dict[\"nightly_selector\"][\"definition\"]\n        self.assertEqual(expected, definition)\n\n    def test_single_key_value_definition(self):\n        dct = get_selector_dict(\n            \"\"\"\\\n            selectors:\n              - name: nightly_selector\n                definition:\n                  tag: nightly\n            \"\"\"\n        )\n\n        sel_dict = SelectorDict.parse_from_selectors_list(dct[\"selectors\"])\n        assert sel_dict\n        expected = {\"method\": \"tag\", \"value\": \"nightly\"}\n        definition = sel_dict[\"nightly_selector\"][\"definition\"]\n        self.assertEqual(expected, definition)\n\n    def test_parent_definition(self):\n        dct = get_selector_dict(\n            \"\"\"\\\n            selectors:\n              - name: kpi_nightly_selector\n                definition:\n                  '+exposure:kpi_nightly'\n            \"\"\"\n        )\n\n        sel_dict = SelectorDict.parse_from_selectors_list(dct[\"selectors\"])\n        assert sel_dict\n        expected = {\"method\": \"exposure\", \"value\": \"kpi_nightly\", \"parents\": True}\n        definition = sel_dict[\"kpi_nightly_selector\"][\"definition\"]\n        self.assertEqual(expected, definition)\n\n    def test_plus_definition(self):\n        dct = get_selector_dict(\n            \"\"\"\\\n            selectors:\n              - name: my_model_children_selector\n                definition:\n                  'my_model+2'\n            \"\"\"\n        )\n\n        sel_dict = SelectorDict.parse_from_selectors_list(dct[\"selectors\"])\n        assert sel_dict\n        expected = {\"method\": \"fqn\", \"value\": \"my_model\", \"children\": True, \"children_depth\": \"2\"}\n        definition = sel_dict[\"my_model_children_selector\"][\"definition\"]\n        self.assertEqual(expected, definition)\n"
  },
  {
    "path": "tests/unit/config/test_utils.py",
    "content": "import pytest\n\nfrom dbt.config.utils import (\n    exclusive_primary_alt_value_setting,\n    normalize_warn_error_options,\n)\nfrom dbt.exceptions import DbtExclusivePropertyUseError\n\n\nclass TestExclusivePrimaryAltValueSetting:\n    @pytest.fixture(scope=\"class\")\n    def primary_key(self) -> str:\n        return \"key_a\"\n\n    @pytest.fixture(scope=\"class\")\n    def alt_key(self) -> str:\n        return \"key_b\"\n\n    @pytest.fixture(scope=\"class\")\n    def value(self) -> str:\n        return \"I LIKE CATS\"\n\n    def test_primary_set(self, primary_key: str, alt_key: str, value: str):\n        test_dict = {primary_key: value}\n        exclusive_primary_alt_value_setting(test_dict, primary_key, alt_key)\n        assert test_dict.get(primary_key) == value\n        assert test_dict.get(alt_key) is None\n\n    def test_alt_set(self, primary_key: str, alt_key: str, value: str):\n        test_dict = {alt_key: value}\n        exclusive_primary_alt_value_setting(test_dict, primary_key, alt_key)\n        assert test_dict.get(primary_key) == value\n\n    def test_primary_and_alt_set(self, primary_key: str, alt_key: str, value: str):\n        test_dict = {primary_key: value, alt_key: value}\n        with pytest.raises(DbtExclusivePropertyUseError):\n            exclusive_primary_alt_value_setting(test_dict, primary_key, alt_key)\n\n    def test_neither_primary_nor_alt_set(self, primary_key: str, alt_key: str):\n        test_dict = {}\n        exclusive_primary_alt_value_setting(test_dict, primary_key, alt_key)\n        assert test_dict.get(primary_key) is None\n        assert test_dict.get(alt_key) is None\n\n\nclass TestNormalizeWarnErrorOptions:\n    def test_primary_set(self):\n        test_dict = {\n            \"include\": [\"SomeWarning\"],\n        }\n        normalize_warn_error_options(test_dict)\n        assert len(test_dict) == 1\n        assert test_dict[\"error\"] == [\"SomeWarning\"]\n\n    def test_convert(self):\n        test_dict = {\"exclude\": None, \"silence\": None, \"error\": [\"SomeWarning\"]}\n        normalize_warn_error_options(test_dict)\n        assert test_dict[\"warn\"] == []\n        assert test_dict[\"error\"] == [\"SomeWarning\"]\n        assert test_dict[\"silence\"] == []\n\n    def test_both_keys_set(self):\n        test_dict = {\n            \"warn\": [\"SomeWarning\"],\n            \"exclude\": [\"SomeWarning\"],\n        }\n        with pytest.raises(DbtExclusivePropertyUseError):\n            normalize_warn_error_options(test_dict)\n\n    def test_empty_dict(self):\n        test_dict = {}\n        normalize_warn_error_options(test_dict)\n        assert test_dict.get(\"error\") is None\n        assert test_dict.get(\"warn\") is None\n"
  },
  {
    "path": "tests/unit/config/test_vars_file.py",
    "content": "from typing import Any, Dict\n\nimport pytest\nimport yaml\n\nfrom dbt.config.project import (\n    VarProvider,\n    validate_vars_not_in_both,\n    vars_data_from_root,\n)\nfrom dbt.constants import VARS_FILE_NAME\nfrom dbt.exceptions import DbtProjectError\n\n\nclass TestVarsDataFromRoot:\n    \"\"\"Tests for vars_data_from_root function.\"\"\"\n\n    def test_returns_empty_dict_when_file_missing(self, tmp_path) -> None:\n        \"\"\"Should return empty dict when vars.yml doesn't exist.\"\"\"\n        result = vars_data_from_root(str(tmp_path))\n        assert result == {}\n\n    def test_returns_empty_dict_when_file_empty(self, tmp_path) -> None:\n        \"\"\"Should return empty dict when vars.yml is empty.\"\"\"\n        vars_path = tmp_path / VARS_FILE_NAME\n        vars_path.write_text(\"\")\n        result = vars_data_from_root(str(tmp_path))\n        assert result == {}\n\n    def test_returns_empty_dict_when_no_vars_key(self, tmp_path) -> None:\n        \"\"\"Should return empty dict when vars.yml has no 'vars' key.\"\"\"\n        vars_path = tmp_path / VARS_FILE_NAME\n        vars_path.write_text(\"other_key: value\\n\")\n        result = vars_data_from_root(str(tmp_path))\n        assert result == {}\n\n    def test_returns_vars_from_file(self, tmp_path) -> None:\n        \"\"\"Should return contents of 'vars' key from vars.yml.\"\"\"\n        vars_path = tmp_path / VARS_FILE_NAME\n        vars_data = {\n            \"vars\": {\n                \"my_var\": \"my_value\",\n                \"another_var\": 123,\n            }\n        }\n        with open(vars_path, \"w\") as f:\n            yaml.dump(vars_data, f)\n\n        result = vars_data_from_root(str(tmp_path))\n        assert result == {\"my_var\": \"my_value\", \"another_var\": 123}\n\n    def test_returns_package_scoped_vars(self, tmp_path) -> None:\n        \"\"\"Should support package-scoped vars.\"\"\"\n        vars_path = tmp_path / VARS_FILE_NAME\n        vars_data = {\n            \"vars\": {\n                \"global_var\": \"global_value\",\n                \"my_package\": {\n                    \"package_var\": \"package_value\",\n                },\n            }\n        }\n        with open(vars_path, \"w\") as f:\n            yaml.dump(vars_data, f)\n\n        result = vars_data_from_root(str(tmp_path))\n        assert result == {\n            \"global_var\": \"global_value\",\n            \"my_package\": {\"package_var\": \"package_value\"},\n        }\n\n\nclass TestValidateVarsNotInBoth:\n    \"\"\"Tests for validate_vars_not_in_both function.\"\"\"\n\n    def test_no_error_when_no_vars_file_and_no_project_vars(self) -> None:\n        \"\"\"Should not raise when neither vars.yml nor dbt_project.yml have vars.\"\"\"\n        project_dict: Dict[str, Any] = {\"name\": \"test_project\"}\n        validate_vars_not_in_both(project_dict, has_vars_file=False)\n\n    def test_no_error_when_only_vars_file_has_vars(self) -> None:\n        \"\"\"Should not raise when only vars.yml has vars.\"\"\"\n        project_dict: Dict[str, Any] = {\"name\": \"test_project\"}\n        validate_vars_not_in_both(project_dict, has_vars_file=True)\n\n    def test_no_error_when_only_project_has_vars(self) -> None:\n        \"\"\"Should not raise when only dbt_project.yml has vars.\"\"\"\n        project_dict: Dict[str, Any] = {\n            \"name\": \"test_project\",\n            \"vars\": {\"my_var\": \"my_value\"},\n        }\n        validate_vars_not_in_both(project_dict, has_vars_file=False)\n\n    def test_error_when_both_have_vars(self) -> None:\n        \"\"\"Should raise DbtProjectError when both sources have vars.\"\"\"\n        project_dict: Dict[str, Any] = {\n            \"name\": \"test_project\",\n            \"vars\": {\"my_var\": \"my_value\"},\n        }\n        with pytest.raises(DbtProjectError) as exc_info:\n            validate_vars_not_in_both(project_dict, has_vars_file=True)\n\n        assert \"vars.yml\" in str(exc_info.value)\n        assert \"dbt_project.yml\" in str(exc_info.value)\n\n    def test_no_error_when_project_vars_is_empty(self) -> None:\n        \"\"\"Should not raise when dbt_project.yml vars is empty dict.\"\"\"\n        project_dict: Dict[str, Any] = {\n            \"name\": \"test_project\",\n            \"vars\": {},\n        }\n        # Empty vars dict is falsy, so this should not raise\n        validate_vars_not_in_both(project_dict, has_vars_file=True)\n\n    def test_no_error_when_project_vars_is_none(self) -> None:\n        \"\"\"Should not raise when dbt_project.yml vars is None.\"\"\"\n        project_dict: Dict[str, Any] = {\n            \"name\": \"test_project\",\n            \"vars\": None,\n        }\n        validate_vars_not_in_both(project_dict, has_vars_file=True)\n\n\nclass TestVarProviderWithVarsFromFile:\n    \"\"\"Tests for VarProvider with vars from file.\"\"\"\n\n    def test_vars_from_file_only(self) -> None:\n        \"\"\"VarProvider should work with vars from file.\"\"\"\n        vars_dict = {\"my_var\": \"my_value\", \"another_var\": 123}\n        provider = VarProvider(vars_dict)\n        assert provider.to_dict() == vars_dict\n\n    def test_vars_from_file_with_package_scoped(self) -> None:\n        \"\"\"VarProvider should handle package-scoped vars from file.\"\"\"\n        vars_dict = {\n            \"global_var\": \"global_value\",\n            \"my_package\": {\"package_var\": \"package_value\"},\n        }\n        provider = VarProvider(vars_dict)\n        assert provider.to_dict() == vars_dict\n"
  },
  {
    "path": "tests/unit/conftest.py",
    "content": "import pytest\n\nfrom dbt.artifacts.resources import Quoting, SourceConfig\nfrom dbt.artifacts.resources.types import NodeType\nfrom dbt.contracts.graph.nodes import SourceDefinition\n\n# All manifest related fixtures.\nfrom tests.unit.utils.adapter import *  # noqa\nfrom tests.unit.utils.config import *  # noqa\nfrom tests.unit.utils.event_manager import *  # noqa\nfrom tests.unit.utils.flags import *  # noqa\nfrom tests.unit.utils.manifest import *  # noqa\nfrom tests.unit.utils.project import *  # noqa\n\n\n@pytest.fixture\ndef basic_parsed_source_definition_object():\n    return SourceDefinition(\n        columns={},\n        database=\"some_db\",\n        description=\"\",\n        fqn=[\"test\", \"source\", \"my_source\", \"my_source_table\"],\n        identifier=\"my_source_table\",\n        loader=\"stitch\",\n        name=\"my_source_table\",\n        original_file_path=\"/root/models/sources.yml\",\n        package_name=\"test\",\n        path=\"/root/models/sources.yml\",\n        quoting=Quoting(),\n        resource_type=NodeType.Source,\n        schema=\"some_schema\",\n        source_description=\"my source description\",\n        source_name=\"my_source\",\n        unique_id=\"test.source.my_source.my_source_table\",\n        tags=[],\n        config=SourceConfig(),\n    )\n"
  },
  {
    "path": "tests/unit/context/__init__.py",
    "content": ""
  },
  {
    "path": "tests/unit/context/test_base.py",
    "content": "import os\n\nfrom jinja2.runtime import Undefined\n\nfrom dbt.context.base import BaseContext\n\n\nclass TestBaseContext:\n    def test_log_jinja_undefined(self):\n        # regression test for CT-2259\n        try:\n            os.environ[\"DBT_ENV_SECRET_LOG_TEST\"] = \"cats_are_cool\"\n            BaseContext.log(msg=Undefined(), info=True)\n        except Exception as e:\n            assert False, f\"Logging an jinja2.Undefined object raises an exception: {e}\"\n\n    def test_log_with_dbt_env_secret(self):\n        # regression test for CT-1783\n        try:\n            os.environ[\"DBT_ENV_SECRET_LOG_TEST\"] = \"cats_are_cool\"\n            BaseContext.log({\"fact1\": \"I like cats\"}, info=True)\n        except Exception as e:\n            assert False, f\"Logging while a `DBT_ENV_SECRET` was set raised an exception: {e}\"\n\n    def test_flags(self):\n        expected_context_flags = {\n            \"use_experimental_parser\",\n            \"static_parser\",\n            \"warn_error\",\n            \"warn_error_options\",\n            \"write_json\",\n            \"partial_parse\",\n            \"use_colors\",\n            \"profiles_dir\",\n            \"debug\",\n            \"log_format\",\n            \"version_check\",\n            \"fail_fast\",\n            \"send_anonymous_usage_stats\",\n            \"printer_width\",\n            \"indirect_selection\",\n            \"log_cache_events\",\n            \"quiet\",\n            \"no_print\",\n            \"cache_selected_only\",\n            \"introspect\",\n            \"target_path\",\n            \"log_path\",\n            \"invocation_command\",\n            \"empty\",\n        }\n        flags = BaseContext(cli_vars={}).flags\n        for expected_flag in expected_context_flags:\n            assert hasattr(flags, expected_flag.upper())\n"
  },
  {
    "path": "tests/unit/context/test_context.py",
    "content": "import os\nfrom typing import Any, Dict, Set\nfrom unittest import mock\n\nimport pytest\n\nimport dbt_common.exceptions\nfrom dbt.adapters import factory, postgres\nfrom dbt.clients.jinja import MacroStack\nfrom dbt.config.project import VarProvider\nfrom dbt.context import base, docs, macros, providers, query_header\nfrom dbt.contracts.files import FileHash\nfrom dbt.contracts.graph.nodes import (\n    DependsOn,\n    Macro,\n    ModelNode,\n    NodeConfig,\n    UnitTestNode,\n    UnitTestOverrides,\n)\nfrom dbt.node_types import NodeType\nfrom dbt_common.events.functions import reset_metadata_vars\nfrom tests.unit.mock_adapter import adapter_factory\nfrom tests.unit.utils import clear_plugin, config_from_parts_or_dicts, inject_adapter\n\n\nclass TestVar:\n    @pytest.fixture\n    def model(self):\n        return ModelNode(\n            alias=\"model_one\",\n            name=\"model_one\",\n            database=\"dbt\",\n            schema=\"analytics\",\n            resource_type=NodeType.Model,\n            unique_id=\"model.root.model_one\",\n            fqn=[\"root\", \"model_one\"],\n            package_name=\"root\",\n            original_file_path=\"model_one.sql\",\n            refs=[],\n            sources=[],\n            depends_on=DependsOn(),\n            config=NodeConfig.from_dict(\n                {\n                    \"enabled\": True,\n                    \"materialized\": \"view\",\n                    \"persist_docs\": {},\n                    \"post-hook\": [],\n                    \"pre-hook\": [],\n                    \"vars\": {},\n                    \"quoting\": {},\n                    \"column_types\": {},\n                    \"tags\": [],\n                }\n            ),\n            tags=[],\n            path=\"model_one.sql\",\n            language=\"sql\",\n            raw_code=\"\",\n            description=\"\",\n            columns={},\n            checksum=FileHash.from_contents(\"\"),\n        )\n\n    @pytest.fixture\n    def context(self):\n        return mock.MagicMock()\n\n    @pytest.fixture\n    def provider(self):\n        return VarProvider({})\n\n    @pytest.fixture\n    def config(self, provider):\n        return mock.MagicMock(config_version=2, vars=provider, cli_vars={}, project_name=\"root\")\n\n    def test_var_default_something(self, model, config, context):\n        config.cli_vars = {\"foo\": \"baz\"}\n        var = providers.RuntimeVar(context, config, model)\n\n        assert var(\"foo\") == \"baz\"\n        assert var(\"foo\", \"bar\") == \"baz\"\n\n    def test_var_default_none(self, model, config, context):\n        config.cli_vars = {\"foo\": None}\n        var = providers.RuntimeVar(context, config, model)\n\n        assert var(\"foo\") is None\n        assert var(\"foo\", \"bar\") is None\n\n    def test_var_not_defined(self, model, config, context):\n        var = providers.RuntimeVar(self.context, config, model)\n\n        assert var(\"foo\", \"bar\") == \"bar\"\n        with pytest.raises(dbt_common.exceptions.CompilationError):\n            var(\"foo\")\n\n    def test_parser_var_default_something(self, model, config, context):\n        config.cli_vars = {\"foo\": \"baz\"}\n        var = providers.ParseVar(context, config, model)\n        assert var(\"foo\") == \"baz\"\n        assert var(\"foo\", \"bar\") == \"baz\"\n\n    def test_parser_var_default_none(self, model, config, context):\n        config.cli_vars = {\"foo\": None}\n        var = providers.ParseVar(context, config, model)\n        assert var(\"foo\") is None\n        assert var(\"foo\", \"bar\") is None\n\n    def test_parser_var_not_defined(self, model, config, context):\n        # at parse-time, we should not raise if we encounter a missing var\n        # that way disabled models don't get parse errors\n        var = providers.ParseVar(context, config, model)\n\n        assert var(\"foo\", \"bar\") == \"bar\"\n        assert var(\"foo\") is None\n\n\nclass TestParseWrapper:\n    @pytest.fixture\n    def mock_adapter(self):\n        mock_config = mock.MagicMock()\n        mock_mp_context = mock.MagicMock()\n        adapter_class = adapter_factory()\n        return adapter_class(mock_config, mock_mp_context)\n\n    @pytest.fixture\n    def wrapper(self, mock_adapter):\n        namespace = mock.MagicMock()\n        return providers.ParseDatabaseWrapper(mock_adapter, namespace)\n\n    @pytest.fixture\n    def responder(self, mock_adapter):\n        return mock_adapter.responder\n\n    def test_unwrapped_method(self, wrapper, responder):\n        assert wrapper.quote(\"test_value\") == '\"test_value\"'\n        responder.quote.assert_called_once_with(\"test_value\")\n\n    def test_wrapped_method(self, wrapper, responder):\n        found = wrapper.get_relation(\"database\", \"schema\", \"identifier\")\n        assert found is None\n        responder.get_relation.assert_not_called()\n\n\nclass TestRuntimeWrapper:\n    @pytest.fixture\n    def mock_adapter(self):\n        mock_config = mock.MagicMock()\n        mock_config.quoting = {\n            \"database\": True,\n            \"schema\": True,\n            \"identifier\": True,\n        }\n        mock_mp_context = mock.MagicMock()\n        adapter_class = adapter_factory()\n        return adapter_class(mock_config, mock_mp_context)\n\n    @pytest.fixture\n    def wrapper(self, mock_adapter):\n        namespace = mock.MagicMock()\n        return providers.RuntimeDatabaseWrapper(mock_adapter, namespace)\n\n    @pytest.fixture\n    def responder(self, mock_adapter):\n        return mock_adapter.responder\n\n    def test_unwrapped_method(self, wrapper, responder):\n        # the 'quote' method isn't wrapped, we should get our expected inputs\n        assert wrapper.quote(\"test_value\") == '\"test_value\"'\n        responder.quote.assert_called_once_with(\"test_value\")\n\n\ndef assert_has_keys(required_keys: Set[str], maybe_keys: Set[str], ctx: Dict[str, Any]):\n    keys = set(ctx)\n    for key in required_keys:\n        assert key in keys, f\"{key} in required keys but not in context\"\n        keys.remove(key)\n    extras = keys.difference(maybe_keys)\n    assert not extras, f\"got extra keys in context: {extras}\"\n\n\nREQUIRED_BASE_KEYS = frozenset(\n    {\n        \"context\",\n        \"builtins\",\n        \"dbt_version\",\n        \"var\",\n        \"env_var\",\n        \"return\",\n        \"fromjson\",\n        \"tojson\",\n        \"fromyaml\",\n        \"toyaml\",\n        \"set\",\n        \"set_strict\",\n        \"zip\",\n        \"zip_strict\",\n        \"log\",\n        \"run_started_at\",\n        \"invocation_id\",\n        \"thread_id\",\n        \"modules\",\n        \"flags\",\n        \"print\",\n        \"diff_of_two_dicts\",\n        \"local_md5\",\n    }\n)\n\nREQUIRED_TARGET_KEYS = REQUIRED_BASE_KEYS | {\"target\"}\nREQUIRED_DOCS_KEYS = REQUIRED_TARGET_KEYS | {\"project_name\"} | {\"doc\"}\nMACROS = frozenset({\"macro_a\", \"macro_b\", \"root\", \"dbt\"})\nREQUIRED_QUERY_HEADER_KEYS = (\n    REQUIRED_TARGET_KEYS | {\"project_name\", \"context_macro_stack\"} | MACROS\n)\nREQUIRED_MACRO_KEYS = REQUIRED_QUERY_HEADER_KEYS | {\n    \"_sql_results\",\n    \"load_result\",\n    \"store_result\",\n    \"store_raw_result\",\n    \"validation\",\n    \"write\",\n    \"render\",\n    \"try_or_compiler_error\",\n    \"load_agate_table\",\n    \"ref\",\n    \"source\",\n    \"metric\",\n    \"config\",\n    \"execute\",\n    \"exceptions\",\n    \"database\",\n    \"schema\",\n    \"adapter\",\n    \"api\",\n    \"column\",\n    \"env\",\n    \"graph\",\n    \"model\",\n    \"pre_hooks\",\n    \"post_hooks\",\n    \"sql\",\n    \"sql_now\",\n    \"adapter_macro\",\n    \"selected_resources\",\n    \"invocation_args_dict\",\n    \"submit_python_job\",\n    \"dbt_metadata_envs\",\n    \"function\",\n}\nREQUIRED_MODEL_KEYS = REQUIRED_MACRO_KEYS | {\"this\", \"compiled_code\"}\nMAYBE_KEYS = frozenset({\"debug\", \"defer_relation\"})\n\n\nPOSTGRES_PROFILE_DATA = {\n    \"target\": \"test\",\n    \"quoting\": {},\n    \"outputs\": {\n        \"test\": {\n            \"type\": \"postgres\",\n            \"host\": \"localhost\",\n            \"schema\": \"analytics\",\n            \"user\": \"test\",\n            \"pass\": \"test\",\n            \"dbname\": \"test\",\n            \"port\": 1,\n        }\n    },\n}\n\nPROJECT_DATA = {\n    \"name\": \"root\",\n    \"version\": \"0.1\",\n    \"profile\": \"test\",\n    \"project-root\": os.getcwd(),\n    \"config-version\": 2,\n}\n\n\ndef model():\n    return ModelNode(\n        alias=\"model_one\",\n        name=\"model_one\",\n        database=\"dbt\",\n        schema=\"analytics\",\n        resource_type=NodeType.Model,\n        unique_id=\"model.root.model_one\",\n        fqn=[\"root\", \"model_one\"],\n        package_name=\"root\",\n        original_file_path=\"model_one.sql\",\n        refs=[],\n        sources=[],\n        depends_on=DependsOn(),\n        config=NodeConfig.from_dict(\n            {\n                \"enabled\": True,\n                \"materialized\": \"view\",\n                \"persist_docs\": {},\n                \"post-hook\": [],\n                \"pre-hook\": [],\n                \"vars\": {},\n                \"quoting\": {},\n                \"column_types\": {},\n                \"tags\": [],\n            }\n        ),\n        tags=[],\n        path=\"model_one.sql\",\n        language=\"sql\",\n        raw_code=\"\",\n        description=\"\",\n        columns={},\n    )\n\n\ndef test_base_context():\n    ctx = base.generate_base_context({})\n    assert_has_keys(REQUIRED_BASE_KEYS, MAYBE_KEYS, ctx)\n\n\ndef mock_macro(name, package_name):\n    macro = mock.MagicMock(\n        __class__=Macro,\n        package_name=package_name,\n        resource_type=\"macro\",\n        unique_id=f\"macro.{package_name}.{name}\",\n    )\n    # Mock(name=...) does not set the `name` attribute, this does.\n    macro.name = name\n    return macro\n\n\ndef mock_manifest(config, additional_macros=None):\n    default_macro_names = [\"macro_a\", \"macro_b\"]\n    default_macros = [mock_macro(name, config.project_name) for name in default_macro_names]\n    additional_macros = additional_macros or []\n    all_macros = default_macros + additional_macros\n\n    manifest_macros = {}\n    macros_by_package = {}\n    for macro in all_macros:\n        manifest_macros[macro.unique_id] = macro\n        if macro.package_name not in macros_by_package:\n            macros_by_package[macro.package_name] = {}\n        macro_package = macros_by_package[macro.package_name]\n        macro_package[macro.name] = macro\n\n    def gmbp():\n        return macros_by_package\n\n    m = mock.MagicMock(macros=manifest_macros)\n    m.get_macros_by_package = gmbp\n    return m\n\n\ndef mock_model():\n    return mock.MagicMock(\n        __class__=ModelNode,\n        alias=\"model_one\",\n        name=\"model_one\",\n        database=\"dbt\",\n        schema=\"analytics\",\n        resource_type=NodeType.Model,\n        unique_id=\"model.root.model_one\",\n        fqn=[\"root\", \"model_one\"],\n        package_name=\"root\",\n        original_file_path=\"model_one.sql\",\n        refs=[],\n        sources=[],\n        depends_on=DependsOn(),\n        config=NodeConfig.from_dict(\n            {\n                \"enabled\": True,\n                \"materialized\": \"view\",\n                \"persist_docs\": {},\n                \"post-hook\": [],\n                \"pre-hook\": [],\n                \"vars\": {},\n                \"quoting\": {},\n                \"column_types\": {},\n                \"tags\": [],\n            }\n        ),\n        tags=[],\n        path=\"model_one.sql\",\n        language=\"sql\",\n        raw_code=\"\",\n        description=\"\",\n        columns={},\n    )\n\n\ndef mock_unit_test_node():\n    return mock.MagicMock(\n        __class__=UnitTestNode,\n        resource_type=NodeType.Unit,\n        tested_node_unique_id=\"model.root.model_one\",\n    )\n\n\n@pytest.fixture\ndef get_adapter():\n    with mock.patch.object(providers, \"get_adapter\") as patch:\n        yield patch\n\n\n@pytest.fixture\ndef get_include_paths():\n    with mock.patch.object(factory, \"get_include_paths\") as patch:\n        patch.return_value = []\n        yield patch\n\n\n@pytest.fixture\ndef config_postgres():\n    return config_from_parts_or_dicts(PROJECT_DATA, POSTGRES_PROFILE_DATA)\n\n\n@pytest.fixture\ndef manifest_fx(config_postgres):\n    return mock_manifest(config_postgres)\n\n\n@pytest.fixture\ndef postgres_adapter(config_postgres, get_adapter):\n    adapter = postgres.PostgresAdapter(config_postgres)\n    inject_adapter(adapter, postgres.Plugin)\n    get_adapter.return_value = adapter\n    yield adapter\n    clear_plugin(postgres.Plugin)\n\n\ndef test_query_header_context(config_postgres, manifest_fx):\n    ctx = query_header.generate_query_header_context(\n        config=config_postgres,\n        manifest=manifest_fx,\n    )\n    assert_has_keys(REQUIRED_QUERY_HEADER_KEYS, MAYBE_KEYS, ctx)\n\n\ndef test_macro_runtime_context(config_postgres, manifest_fx, get_adapter, get_include_paths):\n    ctx = providers.generate_runtime_macro_context(\n        macro=manifest_fx.macros[\"macro.root.macro_a\"],\n        config=config_postgres,\n        manifest=manifest_fx,\n        package_name=\"root\",\n    )\n    assert_has_keys(REQUIRED_MACRO_KEYS, MAYBE_KEYS, ctx)\n\n\ndef test_invocation_args_to_dict_in_macro_runtime_context(\n    config_postgres, manifest_fx, get_adapter, get_include_paths\n):\n    ctx = providers.generate_runtime_macro_context(\n        macro=manifest_fx.macros[\"macro.root.macro_a\"],\n        config=config_postgres,\n        manifest=manifest_fx,\n        package_name=\"root\",\n    )\n\n    # Comes from dbt/flags.py as they are the only values set that aren't None at default\n    assert ctx[\"invocation_args_dict\"][\"printer_width\"] == 80\n\n    # Comes from unit/utils.py config_from_parts_or_dicts method\n    assert ctx[\"invocation_args_dict\"][\"profile_dir\"] == \"/dev/null\"\n\n    assert isinstance(ctx[\"invocation_args_dict\"][\"warn_error_options\"], Dict)\n    assert ctx[\"invocation_args_dict\"][\"warn_error_options\"] == {\n        \"error\": [],\n        \"warn\": [],\n        \"silence\": [],\n    }\n\n\ndef test_model_parse_context(config_postgres, manifest_fx, get_adapter, get_include_paths):\n    ctx = providers.generate_parser_model_context(\n        model=mock_model(),\n        config=config_postgres,\n        manifest=manifest_fx,\n        context_config=mock.MagicMock(),\n    )\n    assert_has_keys(REQUIRED_MODEL_KEYS, MAYBE_KEYS, ctx)\n\n\ndef test_model_runtime_context(config_postgres, manifest_fx, get_adapter, get_include_paths):\n    ctx = providers.generate_runtime_model_context(\n        model=mock_model(),\n        config=config_postgres,\n        manifest=manifest_fx,\n    )\n    assert_has_keys(REQUIRED_MODEL_KEYS, MAYBE_KEYS, ctx)\n\n\ndef test_docs_runtime_context(config_postgres):\n    ctx = docs.generate_runtime_docs_context(config_postgres, mock_model(), [], \"root\")\n    assert_has_keys(REQUIRED_DOCS_KEYS, MAYBE_KEYS, ctx)\n\n\ndef test_macro_namespace_duplicates(config_postgres, manifest_fx):\n    mn = macros.MacroNamespaceBuilder(\"root\", \"search\", MacroStack(), [\"dbt_postgres\", \"dbt\"])\n    mn.add_macros(manifest_fx.macros.values(), {})\n\n    # same pkg, same name: error\n    with pytest.raises(dbt_common.exceptions.CompilationError):\n        mn.add_macro(mock_macro(\"macro_a\", \"root\"), {})\n\n    # different pkg, same name: no error\n    mn.add_macros(mock_macro(\"macro_a\", \"dbt\"), {})\n\n\ndef test_macro_namespace(config_postgres, manifest_fx):\n    mn = macros.MacroNamespaceBuilder(\"root\", \"search\", MacroStack(), [\"dbt_postgres\", \"dbt\"])\n\n    mbp = manifest_fx.get_macros_by_package()\n    dbt_macro = mock_macro(\"some_macro\", \"dbt\")\n    mbp[\"dbt\"] = {\"some_macro\": dbt_macro}\n\n    # same namespace, same name, different pkg!\n    pg_macro = mock_macro(\"some_macro\", \"dbt_postgres\")\n    mbp[\"dbt_postgres\"] = {\"some_macro\": pg_macro}\n\n    # same name, different package\n    package_macro = mock_macro(\"some_macro\", \"root\")\n    mbp[\"root\"][\"some_macro\"] = package_macro\n\n    namespace = mn.build_namespace(mbp, {})\n    dct = dict(namespace)\n    for result in [dct, namespace]:\n        assert \"dbt\" in result\n        assert \"root\" in result\n        assert \"some_macro\" in result\n        assert \"dbt_postgres\" not in result\n        # tests __len__\n        assert len(result) == 5\n        # tests __iter__\n        assert set(result) == {\"dbt\", \"root\", \"some_macro\", \"macro_a\", \"macro_b\"}\n        assert len(result[\"dbt\"]) == 1\n        # from the regular manifest + some_macro\n        assert len(result[\"root\"]) == 3\n        assert result[\"dbt\"][\"some_macro\"].macro is pg_macro\n        assert result[\"root\"][\"some_macro\"].macro is package_macro\n        assert result[\"some_macro\"].macro is package_macro\n\n\ndef test_dbt_metadata_envs(\n    monkeypatch, config_postgres, manifest_fx, get_adapter, get_include_paths\n):\n    reset_metadata_vars()\n\n    envs = {\n        \"DBT_ENV_CUSTOM_ENV_RUN_ID\": 1234,\n        \"DBT_ENV_CUSTOM_ENV_JOB_ID\": 5678,\n        \"DBT_ENV_RUN_ID\": 91011,\n        \"RANDOM_ENV\": 121314,\n    }\n    monkeypatch.setattr(os, \"environ\", envs)\n\n    ctx = providers.generate_runtime_macro_context(\n        macro=manifest_fx.macros[\"macro.root.macro_a\"],\n        config=config_postgres,\n        manifest=manifest_fx,\n        package_name=\"root\",\n    )\n\n    assert ctx[\"dbt_metadata_envs\"] == {\"JOB_ID\": 5678, \"RUN_ID\": 1234}\n\n    # cleanup\n    reset_metadata_vars()\n\n\ndef test_unit_test_runtime_context(config_postgres, manifest_fx, get_adapter, get_include_paths):\n    ctx = providers.generate_runtime_unit_test_context(\n        unit_test=mock_unit_test_node(),\n        config=config_postgres,\n        manifest=manifest_fx,\n    )\n    assert_has_keys(REQUIRED_MODEL_KEYS, MAYBE_KEYS, ctx)\n\n\ndef test_unit_test_runtime_context_macro_overrides_global(\n    config_postgres, manifest_fx, get_adapter, get_include_paths\n):\n    unit_test = mock_unit_test_node()\n    unit_test.overrides = UnitTestOverrides(macros={\"macro_a\": \"override\"})\n    ctx = providers.generate_runtime_unit_test_context(\n        unit_test=unit_test,\n        config=config_postgres,\n        manifest=manifest_fx,\n    )\n    assert ctx[\"macro_a\"]() == \"override\"\n\n\ndef test_unit_test_runtime_context_macro_overrides_package(\n    config_postgres, manifest_fx, get_adapter, get_include_paths\n):\n    unit_test = mock_unit_test_node()\n    unit_test.overrides = UnitTestOverrides(macros={\"some_package.some_macro\": \"override\"})\n\n    dbt_macro = mock_macro(\"some_macro\", \"some_package\")\n    manifest_with_dbt_macro = mock_manifest(config_postgres, additional_macros=[dbt_macro])\n\n    ctx = providers.generate_runtime_unit_test_context(\n        unit_test=unit_test,\n        config=config_postgres,\n        manifest=manifest_with_dbt_macro,\n    )\n    assert ctx[\"some_package\"][\"some_macro\"]() == \"override\"\n\n\n@pytest.mark.parametrize(\n    \"overrides,expected_override_value\",\n    [\n        # override dbt macro at global level\n        ({\"some_macro\": \"override\"}, \"override\"),\n        # # override dbt macro at dbt-namespaced level level\n        ({\"dbt.some_macro\": \"override\"}, \"override\"),\n        # override dbt macro at both levels - global override should win\n        (\n            {\"some_macro\": \"dbt_global_override\", \"dbt.some_macro\": \"dbt_namespaced_override\"},\n            \"dbt_global_override\",\n        ),\n        # override dbt macro at both levels - global override should win, regardless of order\n        (\n            {\"dbt.some_macro\": \"dbt_namespaced_override\", \"some_macro\": \"dbt_global_override\"},\n            \"dbt_global_override\",\n        ),\n    ],\n)\ndef test_unit_test_runtime_context_macro_overrides_dbt_macro(\n    overrides,\n    expected_override_value,\n    config_postgres,\n    manifest_fx,\n    get_adapter,\n    get_include_paths,\n):\n    unit_test = mock_unit_test_node()\n    unit_test.overrides = UnitTestOverrides(macros=overrides)\n\n    dbt_macro = mock_macro(\"some_macro\", \"dbt\")\n    manifest_with_dbt_macro = mock_manifest(config_postgres, additional_macros=[dbt_macro])\n\n    ctx = providers.generate_runtime_unit_test_context(\n        unit_test=unit_test,\n        config=config_postgres,\n        manifest=manifest_with_dbt_macro,\n    )\n    assert ctx[\"some_macro\"]() == expected_override_value\n    assert ctx[\"dbt\"][\"some_macro\"]() == expected_override_value\n"
  },
  {
    "path": "tests/unit/context/test_macro_resolver.py",
    "content": "import unittest\nfrom unittest import mock\n\nfrom dbt.context.macro_resolver import MacroResolver\nfrom dbt.contracts.graph.nodes import Macro\n\n\ndef mock_macro(name, package_name):\n    macro = mock.MagicMock(\n        __class__=Macro,\n        package_name=package_name,\n        resource_type=\"macro\",\n        unique_id=f\"macro.{package_name}.{name}\",\n    )\n    # Mock(name=...) does not set the `name` attribute, this does.\n    macro.name = name\n    return macro\n\n\nclass TestMacroResolver(unittest.TestCase):\n    def test_resolver(self):\n        data = [\n            {\"package_name\": \"my_test\", \"name\": \"unique\"},\n            {\"package_name\": \"my_test\", \"name\": \"macro_xx\"},\n            {\"package_name\": \"one\", \"name\": \"unique\"},\n            {\"package_name\": \"one\", \"name\": \"not_null\"},\n            {\"package_name\": \"two\", \"name\": \"macro_a\"},\n            {\"package_name\": \"two\", \"name\": \"macro_b\"},\n        ]\n        macros = {}\n        for mdata in data:\n            macro = mock_macro(mdata[\"name\"], mdata[\"package_name\"])\n            macros[macro.unique_id] = macro\n        resolver = MacroResolver(macros, \"my_test\", [\"one\"])\n        assert resolver\n        self.assertEqual(resolver.get_macro_id(\"one\", \"not_null\"), \"macro.one.not_null\")\n"
  },
  {
    "path": "tests/unit/context/test_providers.py",
    "content": "from argparse import Namespace\nfrom datetime import datetime\nfrom typing import Any, Optional, Type, Union\nfrom unittest import mock\n\nimport pytest\nimport pytz\n\nfrom dbt.adapters.base import BaseRelation\nfrom dbt.artifacts.resources import NodeConfig, Quoting, SeedConfig, SnapshotConfig\nfrom dbt.artifacts.resources.types import BatchSize\nfrom dbt.context.providers import (\n    BaseResolver,\n    EventTimeFilter,\n    RuntimeRefResolver,\n    RuntimeSourceResolver,\n)\nfrom dbt.contracts.graph.nodes import BatchContext, ModelNode, SnapshotNode\nfrom dbt.event_time.sample_window import SampleWindow\nfrom dbt.flags import set_from_args\n\n\nclass TestBaseResolver:\n    class ResolverSubclass(BaseResolver):\n        def __call__(self, *args: str):\n            pass\n\n    @pytest.fixture\n    def resolver(self):\n        return self.ResolverSubclass(\n            db_wrapper=mock.Mock(),\n            model=mock.Mock(),\n            config=mock.Mock(),\n            manifest=mock.Mock(),\n        )\n\n    @pytest.mark.parametrize(\n        \"empty,expected_resolve_limit\",\n        [(False, None), (True, 0)],\n    )\n    def test_resolve_limit(self, resolver, empty, expected_resolve_limit):\n        resolver.config.args.EMPTY = empty\n\n        assert resolver.resolve_limit == expected_resolve_limit\n\n    @pytest.mark.parametrize(\n        \"event_time_column,column_quote,source_quote,expected_field_name\",\n        [\n            # Simple column name, no quoting needed\n            (\"simple_column\", None, None, \"simple_column\"),\n            (\"no_quote_column\", False, None, \"no_quote_column\"),\n            (\"source_no_quote\", None, False, \"source_no_quote\"),\n            (\"both_no_quote\", False, False, \"both_no_quote\"),\n            # Column-level quote configuration (takes precedence)\n            (\"column_quoted\", True, None, '\"column_quoted\"'),\n            (\"column_quoted_source_no\", True, False, '\"column_quoted_source_no\"'),\n            (\"column_quoted_source_yes\", True, True, '\"column_quoted_source_yes\"'),\n            # Source-level quote configuration (fallback when column-level is None)\n            (\"source_quoted\", None, True, '\"source_quoted\"'),\n            (\n                \"source_quoted_override\",\n                False,\n                True,\n                \"source_quoted_override\",\n            ),  # False overrides True\n            # Camel case and spaced column names\n            (\"camelCaseColumn\", None, None, \"camelCaseColumn\"),\n            (\"camelCaseQuoted\", True, None, '\"camelCaseQuoted\"'),\n            (\"snake_case_column\", None, None, \"snake_case_column\"),\n            (\"snake_case_quoted\", True, None, '\"snake_case_quoted\"'),\n            (\"Spaced Column Name\", None, None, \"Spaced Column Name\"),\n            (\"Spaced Column Quoted\", True, None, '\"Spaced Column Quoted\"'),\n            (\"Spaced Column Source Quoted\", None, True, '\"Spaced Column Source Quoted\"'),\n            # Edge cases\n            (\"\", None, None, \"\"),\n            (\"\", True, None, '\"\"'),\n            (\"edge_case_column\", None, None, \"edge_case_column\"),\n            (\"edge_case_quoted\", True, None, '\"edge_case_quoted\"'),\n        ],\n    )\n    def test_resolve_event_time_field_name(\n        self, resolver, event_time_column, column_quote, source_quote, expected_field_name\n    ):\n        \"\"\"Test the _resolve_event_time_field_name method with various quoting configurations.\"\"\"\n        # Create a mock target with columns\n        target = mock.Mock()\n        target.config = mock.Mock()\n        target.config.event_time = event_time_column\n\n        # Mock columns dictionary\n        mock_column = mock.Mock()\n        mock_column.name = event_time_column\n        mock_column.data_type = \"timestamp\"\n\n        # Set column-level quote configuration\n        if column_quote is not None:\n            mock_column.quote = column_quote\n        else:\n            # Explicitly set to None to avoid Mock object being returned\n            mock_column.quote = None\n\n        target.columns = {event_time_column: mock_column}\n\n        # Set source-level quote configuration\n        if source_quote is not None:\n            target.quoting = mock.Mock()\n            target.quoting.column = source_quote\n        else:\n            # Explicitly set to None to avoid Mock object being returned\n            target.quoting = mock.Mock()\n            target.quoting.column = None\n\n        # Call the method\n        result = resolver._resolve_event_time_field_name(target)\n\n        # Assert the result\n        assert result == expected_field_name\n\n    @pytest.mark.parametrize(\n        \"event_time_column,column_quote,source_quote,expected_field_name\",\n        [\n            # Column not found in columns dict - should fall back to source-level quoting\n            (\"missing_column\", None, None, \"missing_column\"),\n            (\"missing_column_source_quoted\", None, True, '\"missing_column_source_quoted\"'),\n            (\"missing_column_source_no_quote\", None, False, \"missing_column_source_no_quote\"),\n            # Column found but no quote attribute - should fall back to source-level quoting\n            (\"found_no_quote_attr\", None, None, \"found_no_quote_attr\"),\n            (\n                \"found_no_quote_attr_source_quoted\",\n                None,\n                True,\n                '\"found_no_quote_attr_source_quoted\"',\n            ),\n            (\n                \"found_no_quote_attr_source_no_quote\",\n                None,\n                False,\n                \"found_no_quote_attr_source_no_quote\",\n            ),\n        ],\n    )\n    def test_resolve_event_time_field_name_column_not_found(\n        self, resolver, event_time_column, column_quote, source_quote, expected_field_name\n    ):\n        \"\"\"Test _resolve_event_time_field_name when column is not found or has no quote attribute.\"\"\"\n        # Create a mock target with different columns\n        target = mock.Mock()\n        target.config = mock.Mock()\n        target.config.event_time = event_time_column\n\n        # Mock columns dictionary with different column\n        mock_column = mock.Mock()\n        mock_column.name = \"different_column_name\"\n        mock_column.data_type = \"timestamp\"\n\n        # Set column-level quote configuration (but for different column)\n        if column_quote is not None:\n            mock_column.quote = column_quote\n        else:\n            # Explicitly set to None to avoid Mock object being returned\n            mock_column.quote = None\n\n        target.columns = {\"different_column_name\": mock_column}\n\n        # Set source-level quote configuration\n        if source_quote is not None:\n            target.quoting = mock.Mock()\n            target.quoting.column = source_quote\n        else:\n            # Explicitly set to None to avoid Mock object being returned\n            target.quoting = mock.Mock()\n            target.quoting.column = None\n\n        # Call the method\n        result = resolver._resolve_event_time_field_name(target)\n\n        # Assert the result\n        assert result == expected_field_name\n\n    def test_resolve_event_time_field_name_no_columns(self, resolver):\n        \"\"\"Test _resolve_event_time_field_name when target has no columns attribute.\"\"\"\n        # Create a mock target without columns\n        target = mock.Mock()\n        target.config = mock.Mock()\n        target.config.event_time = \"no_columns_column\"\n\n        # No columns attribute\n        target.columns = {}\n\n        # Set source-level quote configuration\n        target.quoting = mock.Mock()\n        target.quoting.column = True\n\n        # Call the method\n        result = resolver._resolve_event_time_field_name(target)\n\n        # Should return quoted column name when source-level quoting is True\n        assert result == '\"no_columns_column\"'\n\n    def test_resolve_event_time_field_name_no_quoting_attribute(self, resolver):\n        \"\"\"Test _resolve_event_time_field_name when target has no quoting attribute.\"\"\"\n        # Create a mock target without quoting\n        target = mock.Mock()\n        target.config = mock.Mock()\n        target.config.event_time = \"no_quoting_attr_column\"\n\n        # Mock columns dictionary\n        mock_column = mock.Mock()\n        mock_column.name = \"no_quoting_attr_column\"\n        mock_column.data_type = \"timestamp\"\n        # No quote attribute - explicitly set to None\n        mock_column.quote = None\n\n        target.columns = {\"no_quoting_attr_column\": mock_column}\n\n        # No quoting attribute - explicitly set to None\n        target.quoting = mock.Mock()\n        target.quoting.column = None\n\n        # Call the method\n        result = resolver._resolve_event_time_field_name(target)\n\n        # Should return unquoted column name\n        assert result == \"no_quoting_attr_column\"\n\n    @pytest.mark.parametrize(\n        \"use_microbatch_batches,materialized,incremental_strategy,sample,resolver_model_node,target_type,resolver_model_type,expect_filter\",\n        [\n            # Microbatch model without sample\n            (\n                True,\n                \"incremental\",\n                \"microbatch\",\n                None,\n                True,\n                NodeConfig,\n                ModelNode,\n                True,\n            ),\n            # Microbatch model with sample\n            (\n                True,\n                \"incremental\",\n                \"microbatch\",\n                SampleWindow(\n                    start=datetime(2024, 1, 1, tzinfo=pytz.UTC),\n                    end=datetime(2025, 1, 1, tzinfo=pytz.UTC),\n                ),\n                True,\n                NodeConfig,\n                ModelNode,\n                True,\n            ),\n            # Normal model with sample\n            (\n                False,\n                \"table\",\n                None,\n                SampleWindow(\n                    start=datetime(2024, 1, 1, tzinfo=pytz.UTC),\n                    end=datetime(2025, 1, 1, tzinfo=pytz.UTC),\n                ),\n                True,\n                NodeConfig,\n                ModelNode,\n                True,\n            ),\n            # Incremental merge model with sample\n            (\n                True,\n                \"incremental\",\n                \"merge\",\n                SampleWindow(\n                    start=datetime(2024, 1, 1, tzinfo=pytz.UTC),\n                    end=datetime(2025, 1, 1, tzinfo=pytz.UTC),\n                ),\n                True,\n                NodeConfig,\n                ModelNode,\n                True,\n            ),\n            # Sample, but not model node\n            (\n                False,\n                \"table\",\n                None,\n                SampleWindow(\n                    start=datetime(2024, 1, 1, tzinfo=pytz.UTC),\n                    end=datetime(2025, 1, 1, tzinfo=pytz.UTC),\n                ),\n                False,\n                NodeConfig,\n                ModelNode,\n                False,\n            ),\n            # Microbatch, but not model node\n            (\n                True,\n                \"incremental\",\n                \"microbatch\",\n                None,\n                False,\n                NodeConfig,\n                ModelNode,\n                False,\n            ),\n            # Mircrobatch model, but not using batches\n            (\n                False,\n                \"incremental\",\n                \"microbatch\",\n                None,\n                True,\n                NodeConfig,\n                ModelNode,\n                False,\n            ),\n            # Non microbatch model, but supposed to use batches\n            (\n                True,\n                \"table\",\n                \"microbatch\",\n                None,\n                True,\n                NodeConfig,\n                ModelNode,\n                False,\n            ),\n            # Incremental merge\n            (True, \"incremental\", \"merge\", None, True, NodeConfig, ModelNode, False),\n            # Target seed node, with sample\n            (\n                False,\n                \"table\",\n                None,\n                SampleWindow.from_relative_string(\"2 days\"),\n                True,\n                SeedConfig,\n                ModelNode,\n                True,\n            ),\n            # Target seed node, without sample\n            (False, \"table\", None, None, True, SeedConfig, ModelNode, False),\n            # Sample model from snapshot node\n            (\n                False,\n                \"table\",\n                None,\n                SampleWindow.from_relative_string(\"2 days\"),\n                True,\n                NodeConfig,\n                SnapshotNode,\n                True,\n            ),\n            # Target model from snapshot, without sample\n            (False, \"table\", None, None, True, NodeConfig, SnapshotNode, False),\n            # Target snapshot from model, with sample\n            (\n                False,\n                \"table\",\n                None,\n                SampleWindow.from_relative_string(\"2 days\"),\n                True,\n                SnapshotConfig,\n                ModelNode,\n                True,\n            ),\n        ],\n    )\n    def test_resolve_event_time_filter(\n        self,\n        resolver: ResolverSubclass,\n        use_microbatch_batches: bool,\n        materialized: str,\n        incremental_strategy: Optional[str],\n        sample: Optional[SampleWindow],\n        resolver_model_node: bool,\n        target_type: Any,\n        resolver_model_type: Union[Type[ModelNode], Type[SnapshotNode]],\n        expect_filter: bool,\n    ) -> None:\n        # Target mocking\n        target = mock.Mock()\n        target.config = mock.MagicMock(target_type)\n        target.config.event_time = \"created_at\"\n\n        # Resolver mocking\n        resolver.config.args.EVENT_TIME_END = None\n        resolver.config.args.EVENT_TIME_START = None\n        resolver.config.args.sample = sample\n        if resolver_model_node:\n            resolver.model = mock.MagicMock(spec=resolver_model_type)\n        resolver.model.batch = BatchContext(\n            id=\"1\",\n            event_time_start=datetime(2024, 1, 1, tzinfo=pytz.UTC),\n            event_time_end=datetime(2025, 1, 1, tzinfo=pytz.UTC),\n        )\n        resolver.model.config = mock.MagicMock(NodeConfig)\n        resolver.model.config.materialized = materialized\n        resolver.model.config.incremental_strategy = incremental_strategy\n        resolver.model.config.batch_size = BatchSize.day\n        resolver.model.config.lookback = 1\n        resolver.manifest.use_microbatch_batches = mock.Mock()\n        resolver.manifest.use_microbatch_batches.return_value = use_microbatch_batches\n\n        # Try to get an EventTimeFilter\n        event_time_filter = resolver.resolve_event_time_filter(target=target)\n\n        if expect_filter:\n            assert isinstance(event_time_filter, EventTimeFilter)\n        else:\n            assert event_time_filter is None\n\n\nclass TestRuntimeRefResolver:\n    @pytest.fixture\n    def resolver(self):\n        mock_db_wrapper = mock.Mock()\n        mock_db_wrapper.Relation = BaseRelation\n\n        return RuntimeRefResolver(\n            db_wrapper=mock_db_wrapper,\n            model=mock.Mock(),\n            config=mock.Mock(),\n            manifest=mock.Mock(),\n        )\n\n    @pytest.mark.parametrize(\n        \"empty,is_ephemeral_model,expected_limit\",\n        [\n            (False, False, None),\n            (True, False, 0),\n            (False, True, None),\n            (True, True, 0),\n        ],\n    )\n    def test_create_relation_with_empty(self, resolver, empty, is_ephemeral_model, expected_limit):\n        # setup resolver and input node\n        resolver.config.args.EMPTY = empty\n        resolver.config.quoting = {}\n        mock_node = mock.Mock()\n        mock_node.database = \"test\"\n        mock_node.schema = \"test\"\n        mock_node.identifier = \"test\"\n        mock_node.quoting_dict = {}\n        mock_node.alias = \"test\"\n        mock_node.is_ephemeral_model = is_ephemeral_model\n        mock_node.defer_relation = None\n\n        set_from_args(\n            Namespace(require_batched_execution_for_custom_microbatch_strategy=False), None\n        )\n\n        # create limited relation\n        with mock.patch(\"dbt.contracts.graph.nodes.ParsedNode\", new=mock.Mock):\n            relation = resolver.create_relation(mock_node)\n        assert relation.limit == expected_limit\n\n\nclass TestRuntimeSourceResolver:\n    @pytest.fixture\n    def resolver(self):\n        mock_db_wrapper = mock.Mock()\n        mock_db_wrapper.Relation = BaseRelation\n\n        return RuntimeSourceResolver(\n            db_wrapper=mock_db_wrapper,\n            model=mock.Mock(),\n            config=mock.Mock(),\n            manifest=mock.Mock(),\n        )\n\n    @pytest.mark.parametrize(\n        \"empty,expected_limit\",\n        [\n            (False, None),\n            (True, 0),\n        ],\n    )\n    def test_create_relation_with_empty(self, resolver, empty, expected_limit):\n        # setup resolver and input source\n        resolver.config.args.EMPTY = empty\n        resolver.config.quoting = {}\n\n        mock_source = mock.Mock()\n        mock_source.database = \"test\"\n        mock_source.schema = \"test\"\n        mock_source.identifier = \"test\"\n        mock_source.quoting = Quoting()\n        mock_source.quoting_dict = {}\n        resolver.manifest.resolve_source.return_value = mock_source\n\n        set_from_args(\n            Namespace(require_batched_execution_for_custom_microbatch_strategy=False), None\n        )\n\n        # create limited relation\n        relation = resolver.resolve(\"test\", \"test\")\n        assert relation.limit == expected_limit\n"
  },
  {
    "path": "tests/unit/context/test_query_header.py",
    "content": "import re\nfrom unittest import mock\n\nimport pytest\n\nfrom dbt.adapters.base.query_headers import MacroQueryStringSetter\nfrom dbt.context.query_header import generate_query_header_context\nfrom tests.unit.utils import config_from_parts_or_dicts\n\n\nclass TestQueryHeaderContext:\n    @pytest.fixture\n    def profile_cfg(self):\n        return {\n            \"outputs\": {\n                \"test\": {\n                    \"type\": \"postgres\",\n                    \"dbname\": \"postgres\",\n                    \"user\": \"test\",\n                    \"host\": \"test\",\n                    \"pass\": \"test\",\n                    \"port\": 5432,\n                    \"schema\": \"test\",\n                },\n            },\n            \"target\": \"test\",\n        }\n\n    @pytest.fixture\n    def project_cfg(self):\n        return {\n            \"name\": \"query_headers\",\n            \"version\": \"0.1\",\n            \"profile\": \"test\",\n            \"config-version\": 2,\n        }\n\n    @pytest.fixture\n    def query(self):\n        return \"SELECT 1;\"\n\n    def test_comment_should_prepend_query_by_default(self, profile_cfg, project_cfg, query):\n        config = config_from_parts_or_dicts(project_cfg, profile_cfg)\n\n        query_header_context = generate_query_header_context(config, mock.MagicMock(macros={}))\n        query_header = MacroQueryStringSetter(config, query_header_context)\n        sql = query_header.add(query)\n        assert re.match(f\"^\\/\\*.*\\*\\/\\n{query}$\", sql)  # noqa: [W605]\n\n    def test_append_comment(self, profile_cfg, project_cfg, query):\n        project_cfg.update({\"query-comment\": {\"comment\": \"executed by dbt\", \"append\": True}})\n        config = config_from_parts_or_dicts(project_cfg, profile_cfg)\n\n        query_header_context = generate_query_header_context(config, mock.MagicMock(macros={}))\n        query_header = MacroQueryStringSetter(config, query_header_context)\n        sql = query_header.add(query)\n\n        assert sql == f\"{query[:-1]}\\n/* executed by dbt */;\"\n\n    def test_disable_query_comment(self, profile_cfg, project_cfg, query):\n        project_cfg.update({\"query-comment\": \"\"})\n        config = config_from_parts_or_dicts(project_cfg, profile_cfg)\n        query_header = MacroQueryStringSetter(config, mock.MagicMock(macros={}))\n        assert query_header.add(query) == query\n"
  },
  {
    "path": "tests/unit/contracts/__init__.py",
    "content": ""
  },
  {
    "path": "tests/unit/contracts/files/test_schema_source_file.py",
    "content": "from dbt.contracts.files import SchemaSourceFile\n\n\ndef test_fix_metrics_from_measure():\n    # This is a test for converting \"generated_metrics\" to \"metrics_from_measures\"\n    schema_source_file = {\n        \"path\": {\n            \"searched_path\": \"models\",\n            \"relative_path\": \"schema.yml\",\n            \"modification_time\": 1721228094.7544806,\n            \"project_root\": \"/Users/a_user/sample_project\",\n        },\n        \"checksum\": {\n            \"name\": \"sha256\",\n            \"checksum\": \"63130d480a44a481aa0adc0a8469dccbb72ea36cc09f06683a584a31339f362e\",\n        },\n        \"project_name\": \"test\",\n        \"parse_file_type\": \"schema\",\n        \"dfy\": {\n            \"models\": [{\"name\": \"fct_revenue\", \"description\": \"This is the model fct_revenue.\"}],\n            \"semantic_models\": [\n                {\n                    \"name\": \"revenue\",\n                    \"description\": \"This is the FIRST semantic model.\",\n                    \"model\": \"ref('fct_revenue')\",\n                    \"defaults\": {\"agg_time_dimension\": \"ds\"},\n                    \"measures\": [\n                        {\n                            \"name\": \"txn_revenue\",\n                            \"expr\": \"revenue\",\n                            \"agg\": \"sum\",\n                            \"agg_time_dimension\": \"ds\",\n                            \"create_metric\": True,\n                        },\n                        {\n                            \"name\": \"sum_of_things\",\n                            \"expr\": 2,\n                            \"agg\": \"sum\",\n                            \"agg_time_dimension\": \"ds\",\n                        },\n                    ],\n                    \"dimensions\": [\n                        {\n                            \"name\": \"ds\",\n                            \"type\": \"time\",\n                            \"expr\": \"created_at\",\n                            \"type_params\": {\"time_granularity\": \"day\"},\n                        }\n                    ],\n                    \"entities\": [\n                        {\"name\": \"user\", \"type\": \"foreign\", \"expr\": \"user_id\"},\n                        {\"name\": \"id\", \"type\": \"primary\"},\n                    ],\n                },\n                {\n                    \"name\": \"alt_revenue\",\n                    \"description\": \"This is the second revenue semantic model.\",\n                    \"model\": \"ref('fct_revenue')\",\n                    \"defaults\": {\"agg_time_dimension\": \"ads\"},\n                    \"measures\": [\n                        {\n                            \"name\": \"alt_txn_revenue\",\n                            \"expr\": \"revenue\",\n                            \"agg\": \"sum\",\n                            \"agg_time_dimension\": \"ads\",\n                            \"create_metric\": True,\n                        },\n                        {\n                            \"name\": \"alt_sum_of_things\",\n                            \"expr\": 2,\n                            \"agg\": \"sum\",\n                            \"agg_time_dimension\": \"ads\",\n                        },\n                    ],\n                    \"dimensions\": [\n                        {\n                            \"name\": \"ads\",\n                            \"type\": \"time\",\n                            \"expr\": \"created_at\",\n                            \"type_params\": {\"time_granularity\": \"day\"},\n                        }\n                    ],\n                    \"entities\": [\n                        {\"name\": \"user\", \"type\": \"foreign\", \"expr\": \"user_id\"},\n                        {\"name\": \"id\", \"type\": \"primary\"},\n                    ],\n                },\n            ],\n            \"metrics\": [\n                {\n                    \"name\": \"simple_metric\",\n                    \"label\": \"Simple Metric\",\n                    \"type\": \"simple\",\n                    \"type_params\": {\"measure\": \"sum_of_things\"},\n                }\n            ],\n        },\n        \"data_tests\": {},\n        \"metrics\": [\"metric.test.simple_metric\"],\n        \"generated_metrics\": [\"metric.test.txn_revenue\", \"metric.test.alt_txn_revenue\"],\n        \"metrics_from_measures\": {},\n        \"ndp\": [\"model.test.fct_revenue\"],\n        \"semantic_models\": [\"semantic_model.test.revenue\", \"semantic_model.test.alt_revenue\"],\n        \"mcp\": {},\n        \"env_vars\": {},\n    }\n\n    expected_metrics_from_measures = {\n        \"revenue\": [\"metric.test.txn_revenue\"],\n        \"alt_revenue\": [\"metric.test.alt_txn_revenue\"],\n    }\n    ssf = SchemaSourceFile.from_dict(schema_source_file)\n    assert ssf\n    ssf.fix_metrics_from_measures()\n    assert ssf.generated_metrics == []\n    assert ssf.metrics_from_measures == expected_metrics_from_measures\n"
  },
  {
    "path": "tests/unit/contracts/graph/__init__.py",
    "content": ""
  },
  {
    "path": "tests/unit/contracts/graph/test_manifest.py",
    "content": "import os\nimport unittest\nfrom argparse import Namespace\nfrom collections import namedtuple\nfrom copy import deepcopy\nfrom datetime import datetime, timezone\nfrom itertools import product\nfrom unittest import mock\n\nimport freezegun\nimport pytest\n\nimport dbt.version\nimport dbt_common.invocation\nfrom dbt import tracking\nfrom dbt.adapters.base.plugin import AdapterPlugin\nfrom dbt.artifacts.resources import (\n    ExposureType,\n    MaturityType,\n    MetricInputMeasure,\n    MetricTypeParams,\n    Owner,\n    RefArgs,\n    UnitTestOutputFixture,\n    WhereFilter,\n    WhereFilterIntersection,\n)\nfrom dbt.contracts.files import FileHash\nfrom dbt.contracts.graph.manifest import DisabledLookup, Manifest, ManifestMetadata\nfrom dbt.contracts.graph.nodes import (\n    DependsOn,\n    Exposure,\n    Group,\n    Metric,\n    ModelConfig,\n    ModelNode,\n    SeedNode,\n    SourceDefinition,\n    UnitTestDefinition,\n)\nfrom dbt.exceptions import AmbiguousResourceNameRefError, ParsingError\nfrom dbt.flags import set_from_args\nfrom dbt.node_types import NodeType\nfrom dbt_common.events.functions import reset_metadata_vars\nfrom dbt_semantic_interfaces.type_enums import MetricType\nfrom tests.unit.utils import (\n    MockDocumentation,\n    MockGenerateMacro,\n    MockMacro,\n    MockMaterialization,\n    MockNode,\n    MockSource,\n    inject_plugin,\n    make_manifest,\n)\n\nREQUIRED_PARSED_NODE_KEYS = frozenset(\n    {\n        \"alias\",\n        \"tags\",\n        \"config\",\n        \"unique_id\",\n        \"refs\",\n        \"sources\",\n        \"metrics\",\n        \"functions\",\n        \"meta\",\n        \"depends_on\",\n        \"database\",\n        \"schema\",\n        \"name\",\n        \"resource_type\",\n        \"group\",\n        \"package_name\",\n        \"path\",\n        \"original_file_path\",\n        \"raw_code\",\n        \"language\",\n        \"description\",\n        \"primary_key\",\n        \"columns\",\n        \"fqn\",\n        \"build_path\",\n        \"compiled_path\",\n        \"patch_path\",\n        \"docs\",\n        \"doc_blocks\",\n        \"checksum\",\n        \"unrendered_config\",\n        \"unrendered_config_call_dict\",\n        \"created_at\",\n        \"config_call_dict\",\n        \"relation_name\",\n        \"contract\",\n        \"access\",\n        \"version\",\n        \"latest_version\",\n        \"constraints\",\n        \"deprecation_date\",\n        \"defer_relation\",\n        \"time_spine\",\n        \"batch\",\n    }\n)\n\nREQUIRED_COMPILED_NODE_KEYS = frozenset(\n    REQUIRED_PARSED_NODE_KEYS\n    | {\"compiled\", \"extra_ctes_injected\", \"extra_ctes\", \"compiled_code\", \"relation_name\"}\n)\n\nENV_KEY_NAME = \"KEY\" if os.name == \"nt\" else \"key\"\n\n\nclass ManifestTest(unittest.TestCase):\n    def setUp(self):\n        reset_metadata_vars()\n\n        # TODO: why is this needed for tests in this module to pass?\n        tracking.active_user = None\n\n        self.maxDiff = None\n\n        self.model_config = ModelConfig.from_dict(\n            {\n                \"enabled\": True,\n                \"materialized\": \"view\",\n                \"persist_docs\": {},\n                \"post-hook\": [],\n                \"pre-hook\": [],\n                \"vars\": {},\n                \"quoting\": {},\n                \"column_types\": {},\n                \"tags\": [],\n            }\n        )\n\n        self.exposures = {\n            \"exposure.root.my_exposure\": Exposure(\n                name=\"my_exposure\",\n                type=ExposureType.Dashboard,\n                owner=Owner(email=\"some@email.com\"),\n                resource_type=NodeType.Exposure,\n                description=\"Test description\",\n                maturity=MaturityType.High,\n                url=\"hhtp://mydashboard.com\",\n                depends_on=DependsOn(nodes=[\"model.root.multi\"]),\n                refs=[RefArgs(name=\"multi\")],\n                sources=[],\n                fqn=[\"root\", \"my_exposure\"],\n                unique_id=\"exposure.root.my_exposure\",\n                package_name=\"root\",\n                path=\"my_exposure.sql\",\n                original_file_path=\"my_exposure.sql\",\n            )\n        }\n\n        self.metrics = {\n            \"metric.root.my_metric\": Metric(\n                name=\"new_customers\",\n                label=\"New Customers\",\n                description=\"New customers\",\n                meta={\"is_okr\": True},\n                tags=[\"okrs\"],\n                type=MetricType.SIMPLE,\n                type_params=MetricTypeParams(\n                    measure=MetricInputMeasure(\n                        name=\"customers\",\n                        filter=WhereFilterIntersection(\n                            [WhereFilter(where_sql_template=\"is_new = True\")]\n                        ),\n                    )\n                ),\n                resource_type=NodeType.Metric,\n                depends_on=DependsOn(nodes=[\"semantic_model.root.customers\"]),\n                refs=[RefArgs(name=\"customers\")],\n                fqn=[\"root\", \"my_metric\"],\n                unique_id=\"metric.root.my_metric\",\n                package_name=\"root\",\n                path=\"my_metric.yml\",\n                original_file_path=\"my_metric.yml\",\n            )\n        }\n\n        self.groups = {\n            \"group.root.my_group\": Group(\n                name=\"my_group\",\n                owner=Owner(email=\"some@email.com\"),\n                resource_type=NodeType.Group,\n                unique_id=\"group.root.my_group\",\n                package_name=\"root\",\n                path=\"my_metric.yml\",\n                original_file_path=\"my_metric.yml\",\n            )\n        }\n\n        self.nested_nodes = {\n            \"model.snowplow.events\": ModelNode(\n                name=\"events\",\n                database=\"dbt\",\n                schema=\"analytics\",\n                alias=\"events\",\n                resource_type=NodeType.Model,\n                unique_id=\"model.snowplow.events\",\n                fqn=[\"snowplow\", \"events\"],\n                package_name=\"snowplow\",\n                refs=[],\n                sources=[],\n                metrics=[],\n                depends_on=DependsOn(),\n                config=self.model_config,\n                tags=[],\n                path=\"events.sql\",\n                original_file_path=\"events.sql\",\n                meta={},\n                language=\"sql\",\n                raw_code=\"does not matter\",\n                checksum=FileHash.empty(),\n            ),\n            \"model.root.events\": ModelNode(\n                name=\"events\",\n                database=\"dbt\",\n                schema=\"analytics\",\n                alias=\"events\",\n                resource_type=NodeType.Model,\n                unique_id=\"model.root.events\",\n                fqn=[\"root\", \"events\"],\n                package_name=\"root\",\n                refs=[],\n                sources=[],\n                metrics=[],\n                depends_on=DependsOn(),\n                config=self.model_config,\n                tags=[],\n                path=\"events.sql\",\n                original_file_path=\"events.sql\",\n                meta={},\n                language=\"sql\",\n                raw_code=\"does not matter\",\n                checksum=FileHash.empty(),\n            ),\n            \"model.root.dep\": ModelNode(\n                name=\"dep\",\n                database=\"dbt\",\n                schema=\"analytics\",\n                alias=\"dep\",\n                resource_type=NodeType.Model,\n                unique_id=\"model.root.dep\",\n                fqn=[\"root\", \"dep\"],\n                package_name=\"root\",\n                refs=[RefArgs(name=\"events\")],\n                sources=[],\n                metrics=[],\n                depends_on=DependsOn(nodes=[\"model.root.events\"]),\n                config=self.model_config,\n                tags=[],\n                path=\"multi.sql\",\n                original_file_path=\"multi.sql\",\n                meta={},\n                language=\"sql\",\n                raw_code=\"does not matter\",\n                checksum=FileHash.empty(),\n            ),\n            \"model.root.nested\": ModelNode(\n                name=\"nested\",\n                database=\"dbt\",\n                schema=\"analytics\",\n                alias=\"nested\",\n                resource_type=NodeType.Model,\n                unique_id=\"model.root.nested\",\n                fqn=[\"root\", \"nested\"],\n                package_name=\"root\",\n                refs=[RefArgs(name=\"events\")],\n                sources=[],\n                metrics=[],\n                depends_on=DependsOn(nodes=[\"model.root.dep\"]),\n                config=self.model_config,\n                tags=[],\n                path=\"multi.sql\",\n                original_file_path=\"multi.sql\",\n                meta={},\n                language=\"sql\",\n                raw_code=\"does not matter\",\n                checksum=FileHash.empty(),\n            ),\n            \"model.root.sibling\": ModelNode(\n                name=\"sibling\",\n                database=\"dbt\",\n                schema=\"analytics\",\n                alias=\"sibling\",\n                resource_type=NodeType.Model,\n                unique_id=\"model.root.sibling\",\n                fqn=[\"root\", \"sibling\"],\n                package_name=\"root\",\n                refs=[RefArgs(name=\"events\")],\n                sources=[],\n                metrics=[],\n                depends_on=DependsOn(nodes=[\"model.root.events\"]),\n                config=self.model_config,\n                tags=[],\n                path=\"multi.sql\",\n                original_file_path=\"multi.sql\",\n                meta={},\n                language=\"sql\",\n                raw_code=\"does not matter\",\n                checksum=FileHash.empty(),\n            ),\n            \"model.root.multi\": ModelNode(\n                name=\"multi\",\n                database=\"dbt\",\n                schema=\"analytics\",\n                alias=\"multi\",\n                resource_type=NodeType.Model,\n                unique_id=\"model.root.multi\",\n                fqn=[\"root\", \"multi\"],\n                package_name=\"root\",\n                refs=[RefArgs(name=\"events\")],\n                sources=[],\n                metrics=[],\n                depends_on=DependsOn(nodes=[\"model.root.nested\", \"model.root.sibling\"]),\n                config=self.model_config,\n                tags=[],\n                path=\"multi.sql\",\n                original_file_path=\"multi.sql\",\n                meta={},\n                language=\"sql\",\n                raw_code=\"does not matter\",\n                checksum=FileHash.empty(),\n            ),\n        }\n\n        self.sources = {\n            \"source.root.my_source.my_table\": SourceDefinition(\n                database=\"raw\",\n                schema=\"analytics\",\n                resource_type=NodeType.Source,\n                identifier=\"some_source\",\n                name=\"my_table\",\n                source_name=\"my_source\",\n                source_description=\"My source description\",\n                description=\"Table description\",\n                loader=\"a_loader\",\n                unique_id=\"source.test.my_source.my_table\",\n                fqn=[\"test\", \"my_source\", \"my_table\"],\n                package_name=\"root\",\n                path=\"schema.yml\",\n                original_file_path=\"schema.yml\",\n            ),\n        }\n\n        self.semantic_models = {}\n        self.saved_queries = {}\n\n        for exposure in self.exposures.values():\n            exposure.validate(exposure.to_dict(omit_none=True))\n        for metric in self.metrics.values():\n            metric.validate(metric.to_dict(omit_none=True))\n        for node in self.nested_nodes.values():\n            node.validate(node.to_dict(omit_none=True))\n        for source in self.sources.values():\n            source.validate(source.to_dict(omit_none=True))\n\n        os.environ[\"DBT_ENV_CUSTOM_ENV_key\"] = \"value\"\n\n    def tearDown(self):\n        del os.environ[\"DBT_ENV_CUSTOM_ENV_key\"]\n        reset_metadata_vars()\n\n    @mock.patch.object(tracking, \"active_user\")\n    @freezegun.freeze_time(\"2018-02-14T09:15:13Z\")\n    def test_no_nodes(self, mock_user):\n        manifest = Manifest(\n            nodes={},\n            sources={},\n            macros={},\n            docs={},\n            disabled={},\n            files={},\n            exposures={},\n            functions={},\n            metrics={},\n            selectors={},\n            metadata=ManifestMetadata(\n                generated_at=datetime.now(timezone.utc).replace(tzinfo=None)\n            ),\n            semantic_models={},\n            saved_queries={},\n        )\n\n        invocation_id = dbt_common.invocation._INVOCATION_ID\n        invocation_started_at = dbt_common.invocation._INVOCATION_STARTED_AT\n        mock_user.id = \"cfc9500f-dc7f-4c83-9ea7-2c581c1b38cf\"\n        set_from_args(Namespace(SEND_ANONYMOUS_USAGE_STATS=False), None)\n        self.assertEqual(\n            manifest.writable_manifest().to_dict(omit_none=True),\n            {\n                \"nodes\": {},\n                \"sources\": {},\n                \"macros\": {},\n                \"exposures\": {},\n                \"functions\": {},\n                \"metrics\": {},\n                \"groups\": {},\n                \"selectors\": {},\n                \"parent_map\": {},\n                \"child_map\": {},\n                \"group_map\": {},\n                \"metadata\": {\n                    \"generated_at\": \"2018-02-14T09:15:13Z\",\n                    \"dbt_schema_version\": \"https://schemas.getdbt.com/dbt/manifest/v12.json\",\n                    \"dbt_version\": dbt.version.__version__,\n                    \"env\": {ENV_KEY_NAME: \"value\"},\n                    \"invocation_id\": invocation_id,\n                    \"invocation_started_at\": str(invocation_started_at).replace(\" \", \"T\") + \"Z\",\n                    \"send_anonymous_usage_stats\": False,\n                    \"user_id\": \"cfc9500f-dc7f-4c83-9ea7-2c581c1b38cf\",\n                    \"quoting\": {},\n                },\n                \"docs\": {},\n                \"disabled\": {},\n                \"semantic_models\": {},\n                \"unit_tests\": {},\n                \"saved_queries\": {},\n            },\n        )\n\n    @freezegun.freeze_time(\"2018-02-14T09:15:13Z\")\n    @mock.patch.object(tracking, \"active_user\")\n    def test_nested_nodes(self, mock_user):\n        set_from_args(Namespace(SEND_ANONYMOUS_USAGE_STATS=False), None)\n        mock_user.id = \"cfc9500f-dc7f-4c83-9ea7-2c581c1b38cf\"\n        nodes = deepcopy(self.nested_nodes)\n        manifest = Manifest(\n            nodes=nodes,\n            sources={},\n            macros={},\n            docs={},\n            disabled={},\n            files={},\n            exposures={},\n            metrics={},\n            selectors={},\n            metadata=ManifestMetadata(\n                generated_at=datetime.now(timezone.utc).replace(tzinfo=None)\n            ),\n        )\n        serialized = manifest.writable_manifest().to_dict(omit_none=True)\n        self.assertEqual(serialized[\"metadata\"][\"generated_at\"], \"2018-02-14T09:15:13Z\")\n        self.assertEqual(serialized[\"metadata\"][\"user_id\"], mock_user.id)\n        self.assertFalse(serialized[\"metadata\"][\"send_anonymous_usage_stats\"])\n        self.assertEqual(serialized[\"docs\"], {})\n        self.assertEqual(serialized[\"disabled\"], {})\n        parent_map = serialized[\"parent_map\"]\n        child_map = serialized[\"child_map\"]\n        # make sure there aren't any extra/missing keys.\n        self.assertEqual(set(parent_map), set(nodes))\n        self.assertEqual(set(child_map), set(nodes))\n        self.assertEqual(parent_map[\"model.root.sibling\"], [\"model.root.events\"])\n        self.assertEqual(parent_map[\"model.root.nested\"], [\"model.root.dep\"])\n        self.assertEqual(parent_map[\"model.root.dep\"], [\"model.root.events\"])\n        # order doesn't matter.\n        self.assertEqual(\n            set(parent_map[\"model.root.multi\"]), set([\"model.root.nested\", \"model.root.sibling\"])\n        )\n        self.assertEqual(\n            parent_map[\"model.root.events\"],\n            [],\n        )\n        self.assertEqual(\n            parent_map[\"model.snowplow.events\"],\n            [],\n        )\n\n        self.assertEqual(\n            child_map[\"model.root.sibling\"],\n            [\"model.root.multi\"],\n        )\n        self.assertEqual(\n            child_map[\"model.root.nested\"],\n            [\"model.root.multi\"],\n        )\n        self.assertEqual(child_map[\"model.root.dep\"], [\"model.root.nested\"])\n        self.assertEqual(child_map[\"model.root.multi\"], [])\n        self.assertEqual(\n            set(child_map[\"model.root.events\"]), set([\"model.root.dep\", \"model.root.sibling\"])\n        )\n        self.assertEqual(child_map[\"model.snowplow.events\"], [])\n\n    def test_build_flat_graph(self):\n        exposures = deepcopy(self.exposures)\n        metrics = deepcopy(self.metrics)\n        groups = deepcopy(self.groups)\n        nodes = deepcopy(self.nested_nodes)\n        sources = deepcopy(self.sources)\n        manifest = Manifest(\n            nodes=nodes,\n            sources=sources,\n            macros={},\n            docs={},\n            disabled={},\n            files={},\n            exposures=exposures,\n            metrics=metrics,\n            groups=groups,\n            selectors={},\n        )\n        manifest.build_flat_graph()\n        flat_graph = manifest.flat_graph\n        flat_exposures = flat_graph[\"exposures\"]\n        flat_groups = flat_graph[\"groups\"]\n        flat_metrics = flat_graph[\"metrics\"]\n        flat_nodes = flat_graph[\"nodes\"]\n        flat_sources = flat_graph[\"sources\"]\n        flat_semantic_models = flat_graph[\"semantic_models\"]\n        flat_saved_queries = flat_graph[\"saved_queries\"]\n        flat_unit_tests = flat_graph[\"unit_tests\"]\n        self.assertEqual(\n            set(flat_graph),\n            set(\n                [\n                    \"exposures\",\n                    \"functions\",\n                    \"groups\",\n                    \"nodes\",\n                    \"sources\",\n                    \"metrics\",\n                    \"semantic_models\",\n                    \"saved_queries\",\n                    \"unit_tests\",\n                ]\n            ),\n        )\n        self.assertEqual(set(flat_exposures), set(self.exposures))\n        self.assertEqual(set(flat_groups), set(self.groups))\n        self.assertEqual(set(flat_metrics), set(self.metrics))\n        self.assertEqual(set(flat_nodes), set(self.nested_nodes))\n        self.assertEqual(set(flat_sources), set(self.sources))\n        self.assertEqual(set(flat_semantic_models), set(self.semantic_models))\n        self.assertEqual(set(flat_saved_queries), set(self.saved_queries))\n        self.assertEqual(set(flat_unit_tests), set())\n        for node in flat_nodes.values():\n            self.assertEqual(frozenset(node), REQUIRED_PARSED_NODE_KEYS)\n\n    def test_build_flat_graph_with_unit_tests(self):\n        \"\"\"Test that unit tests are included in flat_graph.\"\"\"\n        nodes = deepcopy(self.nested_nodes)\n        # Create a unit test for the events model\n        unit_test = UnitTestDefinition(\n            name=\"test_events\",\n            model=\"events\",\n            package_name=\"root\",\n            resource_type=NodeType.Unit,\n            path=\"unit_tests.yml\",\n            original_file_path=\"models/unit_tests.yml\",\n            unique_id=\"unit_test.root.events.test_events\",\n            given=[],\n            expect=UnitTestOutputFixture(rows=[{\"id\": 1}]),\n            fqn=[\"root\", \"events\", \"test_events\"],\n            depends_on=DependsOn(nodes=[\"model.root.events\"]),\n        )\n        unit_tests = {unit_test.unique_id: unit_test}\n\n        manifest = Manifest(\n            nodes=nodes,\n            sources=deepcopy(self.sources),\n            macros={},\n            docs={},\n            disabled={},\n            files={},\n            exposures=deepcopy(self.exposures),\n            metrics=deepcopy(self.metrics),\n            groups=deepcopy(self.groups),\n            selectors={},\n            unit_tests=unit_tests,\n        )\n        manifest.build_flat_graph()\n        flat_graph = manifest.flat_graph\n\n        # Verify unit_tests key exists\n        self.assertIn(\"unit_tests\", flat_graph)\n        flat_unit_tests = flat_graph[\"unit_tests\"]\n\n        # Verify the unit test is in flat_graph\n        self.assertEqual(set(flat_unit_tests), set(unit_tests))\n        self.assertIn(\"unit_test.root.events.test_events\", flat_unit_tests)\n\n        # Verify the unit test data is serialized correctly\n        flat_unit_test = flat_unit_tests[\"unit_test.root.events.test_events\"]\n        self.assertEqual(flat_unit_test[\"name\"], \"test_events\")\n        self.assertEqual(flat_unit_test[\"model\"], \"events\")\n        self.assertEqual(flat_unit_test[\"package_name\"], \"root\")\n\n    @mock.patch.object(tracking, \"active_user\")\n    @freezegun.freeze_time(\"2018-02-14T09:15:13Z\")\n    def test_no_nodes_with_metadata(self, mock_user):\n        mock_user.id = \"cfc9500f-dc7f-4c83-9ea7-2c581c1b38cf\"\n        dbt_common.invocation._INVOCATION_ID = \"01234567-0123-0123-0123-0123456789ab\"\n        dbt_common.invocation._INVOCATION_STARTED_AT = datetime.now(timezone.utc).replace(\n            tzinfo=None\n        )\n        set_from_args(Namespace(SEND_ANONYMOUS_USAGE_STATS=False), None)\n        metadata = ManifestMetadata(\n            project_id=\"098f6bcd4621d373cade4e832627b4f6\",\n            adapter_type=\"postgres\",\n            generated_at=datetime.now(timezone.utc).replace(tzinfo=None),\n            invocation_started_at=dbt_common.invocation._INVOCATION_STARTED_AT,\n            user_id=\"cfc9500f-dc7f-4c83-9ea7-2c581c1b38cf\",\n            send_anonymous_usage_stats=False,\n        )\n        manifest = Manifest(\n            nodes={},\n            sources={},\n            macros={},\n            docs={},\n            disabled={},\n            selectors={},\n            metadata=metadata,\n            files={},\n            exposures={},\n            functions={},\n            semantic_models={},\n            saved_queries={},\n        )\n\n        invocation_started_at = (\n            str(dbt_common.invocation._INVOCATION_STARTED_AT).replace(\" \", \"T\") + \"Z\"\n        )\n        self.assertEqual(\n            manifest.writable_manifest().to_dict(omit_none=True),\n            {\n                \"nodes\": {},\n                \"sources\": {},\n                \"macros\": {},\n                \"exposures\": {},\n                \"functions\": {},\n                \"metrics\": {},\n                \"groups\": {},\n                \"selectors\": {},\n                \"parent_map\": {},\n                \"child_map\": {},\n                \"group_map\": {},\n                \"docs\": {},\n                \"metadata\": {\n                    \"generated_at\": \"2018-02-14T09:15:13Z\",\n                    \"dbt_schema_version\": \"https://schemas.getdbt.com/dbt/manifest/v12.json\",\n                    \"dbt_version\": dbt.version.__version__,\n                    \"project_id\": \"098f6bcd4621d373cade4e832627b4f6\",\n                    \"user_id\": \"cfc9500f-dc7f-4c83-9ea7-2c581c1b38cf\",\n                    \"send_anonymous_usage_stats\": False,\n                    \"adapter_type\": \"postgres\",\n                    \"invocation_id\": \"01234567-0123-0123-0123-0123456789ab\",\n                    \"invocation_started_at\": invocation_started_at,\n                    \"env\": {ENV_KEY_NAME: \"value\"},\n                    \"quoting\": {},\n                },\n                \"disabled\": {},\n                \"semantic_models\": {},\n                \"unit_tests\": {},\n                \"saved_queries\": {},\n            },\n        )\n\n    def test_get_resource_fqns_empty(self):\n        manifest = Manifest(\n            nodes={},\n            sources={},\n            macros={},\n            docs={},\n            disabled={},\n            files={},\n            exposures={},\n            selectors={},\n        )\n        self.assertEqual(manifest.get_resource_fqns(), {})\n\n    def test_get_resource_fqns(self):\n        nodes = deepcopy(self.nested_nodes)\n        nodes[\"seed.root.seed\"] = SeedNode(\n            name=\"seed\",\n            database=\"dbt\",\n            schema=\"analytics\",\n            alias=\"seed\",\n            resource_type=NodeType.Seed,\n            unique_id=\"seed.root.seed\",\n            fqn=[\"root\", \"seed\"],\n            package_name=\"root\",\n            config=self.model_config,\n            tags=[],\n            path=\"seed.csv\",\n            original_file_path=\"seed.csv\",\n            checksum=FileHash.empty(),\n        )\n        manifest = Manifest(\n            nodes=nodes,\n            sources=self.sources,\n            macros={},\n            docs={},\n            disabled={},\n            files={},\n            exposures=self.exposures,\n            metrics=self.metrics,\n            selectors={},\n        )\n        expect = {\n            \"metrics\": frozenset([(\"root\", \"my_metric\")]),\n            \"exposures\": frozenset([(\"root\", \"my_exposure\")]),\n            \"models\": frozenset(\n                [\n                    (\"snowplow\", \"events\"),\n                    (\"root\", \"events\"),\n                    (\"root\", \"dep\"),\n                    (\"root\", \"nested\"),\n                    (\"root\", \"sibling\"),\n                    (\"root\", \"multi\"),\n                ]\n            ),\n            \"seeds\": frozenset([(\"root\", \"seed\")]),\n            \"sources\": frozenset([(\"test\", \"my_source\", \"my_table\")]),\n        }\n        resource_fqns = manifest.get_resource_fqns()\n        self.assertEqual(resource_fqns, expect)\n\n    def test_deepcopy_copies_flat_graph(self):\n        test_node = ModelNode(\n            name=\"events\",\n            database=\"dbt\",\n            schema=\"analytics\",\n            alias=\"events\",\n            resource_type=NodeType.Model,\n            unique_id=\"model.snowplow.events\",\n            fqn=[\"snowplow\", \"events\"],\n            package_name=\"snowplow\",\n            refs=[],\n            sources=[],\n            metrics=[],\n            depends_on=DependsOn(),\n            config=self.model_config,\n            tags=[],\n            path=\"events.sql\",\n            original_file_path=\"events.sql\",\n            meta={},\n            language=\"sql\",\n            raw_code=\"does not matter\",\n            checksum=FileHash.empty(),\n        )\n\n        original = make_manifest(nodes=[test_node])\n        original.build_flat_graph()\n        copy = original.deepcopy()\n        self.assertEqual(original.flat_graph, copy.flat_graph)\n\n\nclass MixedManifestTest(unittest.TestCase):\n    def setUp(self):\n        self.maxDiff = None\n\n        self.model_config = ModelConfig.from_dict(\n            {\n                \"enabled\": True,\n                \"materialized\": \"view\",\n                \"persist_docs\": {},\n                \"post-hook\": [],\n                \"pre-hook\": [],\n                \"vars\": {},\n                \"quoting\": {},\n                \"column_types\": {},\n                \"tags\": [],\n            }\n        )\n\n        self.nested_nodes = {\n            \"model.snowplow.events\": ModelNode(\n                name=\"events\",\n                database=\"dbt\",\n                schema=\"analytics\",\n                alias=\"events\",\n                resource_type=NodeType.Model,\n                unique_id=\"model.snowplow.events\",\n                fqn=[\"snowplow\", \"events\"],\n                package_name=\"snowplow\",\n                refs=[],\n                sources=[],\n                depends_on=DependsOn(),\n                config=self.model_config,\n                tags=[],\n                path=\"events.sql\",\n                original_file_path=\"events.sql\",\n                language=\"sql\",\n                raw_code=\"does not matter\",\n                meta={},\n                compiled=True,\n                compiled_code=\"also does not matter\",\n                extra_ctes_injected=True,\n                relation_name='\"dbt\".\"analytics\".\"events\"',\n                extra_ctes=[],\n                checksum=FileHash.empty(),\n            ),\n            \"model.root.events\": ModelNode(\n                name=\"events\",\n                database=\"dbt\",\n                schema=\"analytics\",\n                alias=\"events\",\n                resource_type=NodeType.Model,\n                unique_id=\"model.root.events\",\n                fqn=[\"root\", \"events\"],\n                package_name=\"root\",\n                refs=[],\n                sources=[],\n                depends_on=DependsOn(),\n                config=self.model_config,\n                tags=[],\n                path=\"events.sql\",\n                original_file_path=\"events.sql\",\n                raw_code=\"does not matter\",\n                meta={},\n                compiled=True,\n                compiled_code=\"also does not matter\",\n                language=\"sql\",\n                extra_ctes_injected=True,\n                relation_name='\"dbt\".\"analytics\".\"events\"',\n                extra_ctes=[],\n                checksum=FileHash.empty(),\n            ),\n            \"model.root.dep\": ModelNode(\n                name=\"dep\",\n                database=\"dbt\",\n                schema=\"analytics\",\n                alias=\"dep\",\n                resource_type=NodeType.Model,\n                unique_id=\"model.root.dep\",\n                fqn=[\"root\", \"dep\"],\n                package_name=\"root\",\n                refs=[RefArgs(name=\"events\")],\n                sources=[],\n                depends_on=DependsOn(nodes=[\"model.root.events\"]),\n                config=self.model_config,\n                tags=[],\n                path=\"multi.sql\",\n                original_file_path=\"multi.sql\",\n                meta={},\n                language=\"sql\",\n                raw_code=\"does not matter\",\n                checksum=FileHash.empty(),\n            ),\n            \"model.root.versioned.v1\": ModelNode(\n                name=\"versioned\",\n                database=\"dbt\",\n                schema=\"analytics\",\n                alias=\"dep\",\n                resource_type=NodeType.Model,\n                unique_id=\"model.root.versioned.v1\",\n                fqn=[\"root\", \"dep\"],\n                package_name=\"root\",\n                refs=[],\n                sources=[],\n                depends_on=DependsOn(),\n                config=self.model_config,\n                tags=[],\n                path=\"versioned.sql\",\n                original_file_path=\"versioned.sql\",\n                meta={},\n                language=\"sql\",\n                raw_code=\"does not matter\",\n                checksum=FileHash.empty(),\n                version=1,\n            ),\n            \"model.root.dep_version\": ModelNode(\n                name=\"dep_version\",\n                database=\"dbt\",\n                schema=\"analytics\",\n                alias=\"dep\",\n                resource_type=NodeType.Model,\n                unique_id=\"model.root.dep_version\",\n                fqn=[\"root\", \"dep\"],\n                package_name=\"root\",\n                refs=[RefArgs(name=\"versioned\", version=1)],\n                sources=[],\n                depends_on=DependsOn(nodes=[\"model.root.versioned.v1\"]),\n                config=self.model_config,\n                tags=[],\n                path=\"dep_version.sql\",\n                original_file_path=\"dep_version.sql\",\n                meta={},\n                language=\"sql\",\n                raw_code=\"does not matter\",\n                checksum=FileHash.empty(),\n            ),\n            \"model.root.nested\": ModelNode(\n                name=\"nested\",\n                database=\"dbt\",\n                schema=\"analytics\",\n                alias=\"nested\",\n                resource_type=NodeType.Model,\n                unique_id=\"model.root.nested\",\n                fqn=[\"root\", \"nested\"],\n                package_name=\"root\",\n                refs=[RefArgs(name=\"events\")],\n                sources=[],\n                depends_on=DependsOn(nodes=[\"model.root.dep\"]),\n                config=self.model_config,\n                tags=[],\n                path=\"multi.sql\",\n                original_file_path=\"multi.sql\",\n                meta={},\n                language=\"sql\",\n                raw_code=\"does not matter\",\n                checksum=FileHash.empty(),\n            ),\n            \"model.root.sibling\": ModelNode(\n                name=\"sibling\",\n                database=\"dbt\",\n                schema=\"analytics\",\n                alias=\"sibling\",\n                resource_type=NodeType.Model,\n                unique_id=\"model.root.sibling\",\n                fqn=[\"root\", \"sibling\"],\n                package_name=\"root\",\n                refs=[RefArgs(name=\"events\")],\n                sources=[],\n                depends_on=DependsOn(nodes=[\"model.root.events\"]),\n                config=self.model_config,\n                tags=[],\n                path=\"multi.sql\",\n                original_file_path=\"multi.sql\",\n                meta={},\n                language=\"sql\",\n                raw_code=\"does not matter\",\n                checksum=FileHash.empty(),\n            ),\n            \"model.root.multi\": ModelNode(\n                name=\"multi\",\n                database=\"dbt\",\n                schema=\"analytics\",\n                alias=\"multi\",\n                resource_type=NodeType.Model,\n                unique_id=\"model.root.multi\",\n                fqn=[\"root\", \"multi\"],\n                package_name=\"root\",\n                refs=[RefArgs(name=\"events\")],\n                sources=[],\n                depends_on=DependsOn(nodes=[\"model.root.nested\", \"model.root.sibling\"]),\n                config=self.model_config,\n                tags=[],\n                path=\"multi.sql\",\n                original_file_path=\"multi.sql\",\n                meta={},\n                language=\"sql\",\n                raw_code=\"does not matter\",\n                checksum=FileHash.empty(),\n            ),\n        }\n        os.environ[\"DBT_ENV_CUSTOM_ENV_key\"] = \"value\"\n\n    def tearDown(self):\n        del os.environ[\"DBT_ENV_CUSTOM_ENV_key\"]\n\n    @mock.patch.object(tracking, \"active_user\")\n    @freezegun.freeze_time(\"2018-02-14T09:15:13Z\")\n    def test_no_nodes(self, mock_user):\n        mock_user.id = \"cfc9500f-dc7f-4c83-9ea7-2c581c1b38cf\"\n        set_from_args(Namespace(SEND_ANONYMOUS_USAGE_STATS=False), None)\n        invocation_started_at = datetime.now(timezone.utc).replace(tzinfo=None)\n        metadata = ManifestMetadata(\n            generated_at=datetime.now(timezone.utc).replace(tzinfo=None),\n            invocation_id=\"01234567-0123-0123-0123-0123456789ab\",\n            invocation_started_at=invocation_started_at,\n        )\n        manifest = Manifest(\n            nodes={},\n            sources={},\n            macros={},\n            docs={},\n            selectors={},\n            disabled={},\n            metadata=metadata,\n            files={},\n            exposures={},\n            semantic_models={},\n            saved_queries={},\n        )\n        self.assertEqual(\n            manifest.writable_manifest().to_dict(omit_none=True),\n            {\n                \"nodes\": {},\n                \"macros\": {},\n                \"sources\": {},\n                \"exposures\": {},\n                \"functions\": {},\n                \"metrics\": {},\n                \"groups\": {},\n                \"selectors\": {},\n                \"parent_map\": {},\n                \"child_map\": {},\n                \"group_map\": {},\n                \"metadata\": {\n                    \"generated_at\": \"2018-02-14T09:15:13Z\",\n                    \"dbt_schema_version\": \"https://schemas.getdbt.com/dbt/manifest/v12.json\",\n                    \"dbt_version\": dbt.version.__version__,\n                    \"invocation_id\": \"01234567-0123-0123-0123-0123456789ab\",\n                    \"invocation_started_at\": str(invocation_started_at).replace(\" \", \"T\") + \"Z\",\n                    \"env\": {ENV_KEY_NAME: \"value\"},\n                    \"send_anonymous_usage_stats\": False,\n                    \"user_id\": \"cfc9500f-dc7f-4c83-9ea7-2c581c1b38cf\",\n                    \"quoting\": {},\n                },\n                \"docs\": {},\n                \"disabled\": {},\n                \"semantic_models\": {},\n                \"unit_tests\": {},\n                \"saved_queries\": {},\n            },\n        )\n\n    @freezegun.freeze_time(\"2018-02-14T09:15:13Z\")\n    def test_nested_nodes(self):\n        nodes = deepcopy(self.nested_nodes)\n        manifest = Manifest(\n            nodes=nodes,\n            sources={},\n            macros={},\n            docs={},\n            disabled={},\n            selectors={},\n            metadata=ManifestMetadata(\n                generated_at=datetime.now(timezone.utc).replace(tzinfo=None)\n            ),\n            files={},\n            exposures={},\n        )\n        serialized = manifest.writable_manifest().to_dict(omit_none=True)\n        self.assertEqual(serialized[\"metadata\"][\"generated_at\"], \"2018-02-14T09:15:13Z\")\n        self.assertEqual(serialized[\"disabled\"], {})\n        parent_map = serialized[\"parent_map\"]\n        child_map = serialized[\"child_map\"]\n        # make sure there aren't any extra/missing keys.\n        self.assertEqual(set(parent_map), set(nodes))\n        self.assertEqual(set(child_map), set(nodes))\n        self.assertEqual(parent_map[\"model.root.sibling\"], [\"model.root.events\"])\n        self.assertEqual(parent_map[\"model.root.nested\"], [\"model.root.dep\"])\n        self.assertEqual(parent_map[\"model.root.dep\"], [\"model.root.events\"])\n        # order doesn't matter.\n        self.assertEqual(\n            set(parent_map[\"model.root.multi\"]), set([\"model.root.nested\", \"model.root.sibling\"])\n        )\n        self.assertEqual(\n            parent_map[\"model.root.events\"],\n            [],\n        )\n        self.assertEqual(\n            parent_map[\"model.snowplow.events\"],\n            [],\n        )\n\n        self.assertEqual(\n            child_map[\"model.root.sibling\"],\n            [\"model.root.multi\"],\n        )\n        self.assertEqual(\n            child_map[\"model.root.nested\"],\n            [\"model.root.multi\"],\n        )\n        self.assertEqual(child_map[\"model.root.dep\"], [\"model.root.nested\"])\n        self.assertEqual(child_map[\"model.root.multi\"], [])\n        self.assertEqual(\n            set(child_map[\"model.root.events\"]), set([\"model.root.dep\", \"model.root.sibling\"])\n        )\n        self.assertEqual(child_map[\"model.snowplow.events\"], [])\n\n    def test_build_flat_graph(self):\n        nodes = deepcopy(self.nested_nodes)\n        manifest = Manifest(\n            nodes=nodes,\n            sources={},\n            functions={},\n            macros={},\n            docs={},\n            disabled={},\n            selectors={},\n            files={},\n            exposures={},\n            semantic_models={},\n            saved_queries={},\n        )\n        manifest.build_flat_graph()\n        flat_graph = manifest.flat_graph\n        flat_nodes = flat_graph[\"nodes\"]\n        self.assertEqual(\n            set(flat_graph),\n            set(\n                [\n                    \"exposures\",\n                    \"functions\",\n                    \"groups\",\n                    \"metrics\",\n                    \"nodes\",\n                    \"sources\",\n                    \"semantic_models\",\n                    \"saved_queries\",\n                    \"unit_tests\",\n                ]\n            ),\n        )\n        self.assertEqual(set(flat_nodes), set(self.nested_nodes))\n        self.assertEqual(set(flat_graph[\"unit_tests\"]), set())\n        compiled_count = 0\n        for node in flat_nodes.values():\n            if node.get(\"compiled\"):\n                self.assertEqual(frozenset(node), REQUIRED_COMPILED_NODE_KEYS)\n                compiled_count += 1\n            else:\n                self.assertEqual(frozenset(node), REQUIRED_PARSED_NODE_KEYS)\n        self.assertEqual(compiled_count, 2)\n\n    def test_merge_from_artifact(self):\n        original_nodes = deepcopy(self.nested_nodes)\n        other_nodes = deepcopy(self.nested_nodes)\n\n        nested2 = other_nodes.pop(\"model.root.nested\")\n        nested2.name = \"nested2\"\n        nested2.alias = \"nested2\"\n        nested2.fqn = [\"root\", \"nested2\"]\n\n        other_nodes[\"model.root.nested2\"] = nested2\n\n        for k, v in other_nodes.items():\n            v.database = \"other_\" + v.database\n            v.schema = \"other_\" + v.schema\n            v.alias = \"other_\" + v.alias\n            if v.relation_name:\n                v.relation_name = \"other_\" + v.relation_name\n\n            other_nodes[k] = v\n\n        original_manifest = Manifest(nodes=original_nodes)\n        other_manifest = Manifest(nodes=other_nodes)\n        original_manifest.merge_from_artifact(other_manifest)\n\n        # new node added should not be in original manifest\n        assert \"model.root.nested2\" not in original_manifest.nodes\n\n        # old node removed should not have defer_relation in original manifest\n        assert original_manifest.nodes[\"model.root.nested\"].defer_relation is None\n\n        # for all other nodes, check that defer_relation is updated\n        for k, v in original_manifest.nodes.items():\n            if v.defer_relation:\n                self.assertEqual(\"other_\" + v.database, v.defer_relation.database)\n                self.assertEqual(\"other_\" + v.schema, v.defer_relation.schema)\n                self.assertEqual(\"other_\" + v.alias, v.defer_relation.alias)\n                if v.relation_name:\n                    self.assertEqual(\"other_\" + v.relation_name, v.defer_relation.relation_name)\n\n\n# Tests of the manifest search code (find_X_by_Y)\n\n\nclass TestManifestSearch(unittest.TestCase):\n    _macros: list = []\n    _nodes: list = []\n    _docs: list = []\n\n    @property\n    def macros(self):\n        return self._macros\n\n    @property\n    def nodes(self):\n        return self._nodes\n\n    @property\n    def docs(self):\n        return self._docs\n\n    def setUp(self):\n        self.manifest = Manifest(\n            nodes={n.unique_id: n for n in self.nodes},\n            macros={m.unique_id: m for m in self.macros},\n            docs={d.unique_id: d for d in self.docs},\n            disabled={},\n            files={},\n            exposures={},\n            metrics={},\n            selectors={},\n        )\n\n\nFindMacroSpec = namedtuple(\"FindMacroSpec\", \"macros,expected\")\n\nmacro_parameter_sets = [\n    # empty\n    FindMacroSpec(\n        macros=[],\n        expected={None: None, \"root\": None, \"dep\": None, \"dbt\": None},\n    ),\n    # just root\n    FindMacroSpec(\n        macros=[MockMacro(\"root\")],\n        expected={None: \"root\", \"root\": \"root\", \"dep\": None, \"dbt\": None},\n    ),\n    # just dep\n    FindMacroSpec(\n        macros=[MockMacro(\"dep\")],\n        expected={None: \"dep\", \"root\": None, \"dep\": \"dep\", \"dbt\": None},\n    ),\n    # just dbt\n    FindMacroSpec(\n        macros=[MockMacro(\"dbt\")],\n        expected={None: \"dbt\", \"root\": None, \"dep\": None, \"dbt\": \"dbt\"},\n    ),\n    # root overrides dep\n    FindMacroSpec(\n        macros=[MockMacro(\"root\"), MockMacro(\"dep\")],\n        expected={None: \"root\", \"root\": \"root\", \"dep\": \"dep\", \"dbt\": None},\n    ),\n    # root overrides core\n    FindMacroSpec(\n        macros=[MockMacro(\"root\"), MockMacro(\"dbt\")],\n        expected={None: \"root\", \"root\": \"root\", \"dep\": None, \"dbt\": \"dbt\"},\n    ),\n    # dep overrides core\n    FindMacroSpec(\n        macros=[MockMacro(\"dep\"), MockMacro(\"dbt\")],\n        expected={None: \"dep\", \"root\": None, \"dep\": \"dep\", \"dbt\": \"dbt\"},\n    ),\n    # root overrides dep overrides core\n    FindMacroSpec(\n        macros=[MockMacro(\"root\"), MockMacro(\"dep\"), MockMacro(\"dbt\")],\n        expected={None: \"root\", \"root\": \"root\", \"dep\": \"dep\", \"dbt\": \"dbt\"},\n    ),\n]\n\n\ndef id_macro(arg):\n    if isinstance(arg, list):\n        macro_names = \"__\".join(f\"{m.package_name}\" for m in arg)\n        return f\"m_[{macro_names}]\"\n    if isinstance(arg, dict):\n        arg_names = \"__\".join(f\"{k}_{v}\" for k, v in arg.items())\n        return f\"exp_{{{arg_names}}}\"\n\n\n@pytest.mark.parametrize(\"macros,expectations\", macro_parameter_sets, ids=id_macro)\ndef test_find_macro_by_name(macros, expectations):\n    manifest = make_manifest(macros=macros)\n    for package, expected in expectations.items():\n        result = manifest.find_macro_by_name(\n            name=\"my_macro\", root_project_name=\"root\", package=package\n        )\n        if expected is None:\n            assert result is expected\n        else:\n            assert result.package_name == expected\n\n\ngenerate_name_parameter_sets = [\n    # empty\n    FindMacroSpec(\n        macros=[],\n        expected={None: None, \"root\": None, \"dep\": None, \"dbt\": None},\n    ),\n    # just root\n    FindMacroSpec(\n        macros=[MockGenerateMacro(\"root\")],\n        # \"root\" is not imported\n        expected={None: \"root\", \"root\": None, \"dep\": None, \"dbt\": None},\n    ),\n    # just dep\n    FindMacroSpec(\n        macros=[MockGenerateMacro(\"dep\")],\n        expected={None: None, \"root\": None, \"dep\": \"dep\", \"dbt\": None},\n    ),\n    # just dbt\n    FindMacroSpec(\n        macros=[MockGenerateMacro(\"dbt\")],\n        # \"dbt\" is not imported\n        expected={None: \"dbt\", \"root\": None, \"dep\": None, \"dbt\": None},\n    ),\n    # root overrides dep\n    FindMacroSpec(\n        macros=[MockGenerateMacro(\"root\"), MockGenerateMacro(\"dep\")],\n        expected={None: \"root\", \"root\": None, \"dep\": \"dep\", \"dbt\": None},\n    ),\n    # root overrides core\n    FindMacroSpec(\n        macros=[MockGenerateMacro(\"root\"), MockGenerateMacro(\"dbt\")],\n        expected={None: \"root\", \"root\": None, \"dep\": None, \"dbt\": None},\n    ),\n    # dep overrides core\n    FindMacroSpec(\n        macros=[MockGenerateMacro(\"dep\"), MockGenerateMacro(\"dbt\")],\n        expected={None: \"dbt\", \"root\": None, \"dep\": \"dep\", \"dbt\": None},\n    ),\n    # root overrides dep overrides core\n    FindMacroSpec(\n        macros=[MockGenerateMacro(\"root\"), MockGenerateMacro(\"dep\"), MockGenerateMacro(\"dbt\")],\n        expected={None: \"root\", \"root\": None, \"dep\": \"dep\", \"dbt\": None},\n    ),\n]\n\n\n@pytest.mark.parametrize(\"macros,expectations\", generate_name_parameter_sets, ids=id_macro)\ndef test_find_generate_macros_by_name(macros, expectations):\n    manifest = make_manifest(macros=macros)\n    result = manifest.find_generate_macro_by_name(\n        component=\"some_component\", root_project_name=\"root\"\n    )\n    for package, expected in expectations.items():\n        result = manifest.find_generate_macro_by_name(\n            component=\"some_component\", root_project_name=\"root\", imported_package=package\n        )\n        if expected is None:\n            assert result is expected\n        else:\n            assert result.package_name == expected\n\n\nFindMaterializationSpec = namedtuple(\"FindMaterializationSpec\", \"macros,adapter_type,expected\")\n\n\ndef _materialization_parameter_sets_legacy():\n    # inject the plugins used for materialization parameter tests\n    FooPlugin = AdapterPlugin(\n        adapter=mock.MagicMock(),\n        credentials=mock.MagicMock(),\n        include_path=\"/path/to/root/plugin\",\n        project_name=\"foo\",\n    )\n    FooPlugin.adapter.type.return_value = \"foo\"\n    inject_plugin(FooPlugin)\n\n    BarPlugin = AdapterPlugin(\n        adapter=mock.MagicMock(),\n        credentials=mock.MagicMock(),\n        include_path=\"/path/to/root/plugin\",\n        dependencies=[\"foo\"],\n        project_name=\"bar\",\n    )\n    BarPlugin.adapter.type.return_value = \"bar\"\n    inject_plugin(BarPlugin)\n\n    sets = [\n        FindMaterializationSpec(macros=[], adapter_type=\"foo\", expected=None),\n    ]\n\n    # default only, each project\n    sets.extend(\n        FindMaterializationSpec(\n            macros=[MockMaterialization(project, adapter_type=None)],\n            adapter_type=\"foo\",\n            expected=(project, \"default\"),\n        )\n        for project in [\"root\", \"dep\", \"dbt\"]\n    )\n\n    # other type only, each project\n    sets.extend(\n        FindMaterializationSpec(\n            macros=[MockMaterialization(project, adapter_type=\"bar\")],\n            adapter_type=\"foo\",\n            expected=None,\n        )\n        for project in [\"root\", \"dep\", \"dbt\"]\n    )\n\n    # matching type only, each project\n    sets.extend(\n        FindMaterializationSpec(\n            macros=[MockMaterialization(project, adapter_type=\"foo\")],\n            adapter_type=\"foo\",\n            expected=(project, \"foo\"),\n        )\n        for project in [\"root\", \"dep\", \"dbt\"]\n    )\n\n    sets.extend(\n        [\n            # matching type and default everywhere\n            FindMaterializationSpec(\n                macros=[\n                    MockMaterialization(project, adapter_type=atype)\n                    for (project, atype) in product([\"root\", \"dep\", \"dbt\"], [\"foo\", None])\n                ],\n                adapter_type=\"foo\",\n                expected=(\"root\", \"foo\"),\n            ),\n            # default in core, override is in dep, and root has unrelated override\n            # should find the dep override.\n            FindMaterializationSpec(\n                macros=[\n                    MockMaterialization(\"root\", adapter_type=\"bar\"),\n                    MockMaterialization(\"dep\", adapter_type=\"foo\"),\n                    MockMaterialization(\"dbt\", adapter_type=None),\n                ],\n                adapter_type=\"foo\",\n                expected=(\"dep\", \"foo\"),\n            ),\n            # default in core, unrelated override is in dep, and root has an override\n            # should find the root override.\n            FindMaterializationSpec(\n                macros=[\n                    MockMaterialization(\"root\", adapter_type=\"foo\"),\n                    MockMaterialization(\"dep\", adapter_type=\"bar\"),\n                    MockMaterialization(\"dbt\", adapter_type=None),\n                ],\n                adapter_type=\"foo\",\n                expected=(\"root\", \"foo\"),\n            ),\n            # default in core, override is in dep, and root has an override too.\n            # should find the root override.\n            FindMaterializationSpec(\n                macros=[\n                    MockMaterialization(\"root\", adapter_type=\"foo\"),\n                    MockMaterialization(\"dep\", adapter_type=\"foo\"),\n                    MockMaterialization(\"dbt\", adapter_type=None),\n                ],\n                adapter_type=\"foo\",\n                expected=(\"root\", \"foo\"),\n            ),\n            # core has default + adapter, dep has adapter, root has default\n            # should find the dependency implementation, because it's the most specific\n            FindMaterializationSpec(\n                macros=[\n                    MockMaterialization(\"root\", adapter_type=None),\n                    MockMaterialization(\"dep\", adapter_type=\"foo\"),\n                    MockMaterialization(\"dbt\", adapter_type=None),\n                    MockMaterialization(\"dbt\", adapter_type=\"foo\"),\n                ],\n                adapter_type=\"foo\",\n                expected=(\"dep\", \"foo\"),\n            ),\n        ]\n    )\n\n    # inherit from parent adapter\n    sets.extend(\n        FindMaterializationSpec(\n            macros=[MockMaterialization(project, adapter_type=\"foo\")],\n            adapter_type=\"bar\",\n            expected=(project, \"foo\"),\n        )\n        for project in [\"root\", \"dep\", \"dbt\"]\n    )\n    sets.extend(\n        FindMaterializationSpec(\n            macros=[\n                MockMaterialization(project, adapter_type=\"foo\"),\n                MockMaterialization(project, adapter_type=\"bar\"),\n            ],\n            adapter_type=\"bar\",\n            expected=(project, \"bar\"),\n        )\n        for project in [\"root\", \"dep\", \"dbt\"]\n    )\n\n    return sets\n\n\ndef id_mat(arg):\n    if isinstance(arg, list):\n        macro_names = \"__\".join(f\"{m.package_name}_{m.adapter_type}\" for m in arg)\n        return f\"m_[{macro_names}]\"\n    elif isinstance(arg, tuple):\n        return \"_\".join(arg)\n\n\n@pytest.mark.parametrize(\n    \"macros,adapter_type,expected\",\n    _materialization_parameter_sets_legacy(),\n    ids=id_mat,\n)\ndef test_find_materialization_by_name_legacy(macros, adapter_type, expected):\n    set_from_args(\n        Namespace(\n            SEND_ANONYMOUS_USAGE_STATS=False,\n            REQUIRE_EXPLICIT_PACKAGE_OVERRIDES_FOR_BUILTIN_MATERIALIZATIONS=False,\n        ),\n        None,\n    )\n\n    manifest = make_manifest(macros=macros)\n    result = manifest.find_materialization_macro_by_name(\n        project_name=\"root\",\n        materialization_name=\"my_materialization\",\n        adapter_type=adapter_type,\n    )\n    if expected is None:\n        assert result is expected\n    else:\n        expected_package, expected_adapter_type = expected\n        assert result.adapter_type == expected_adapter_type\n        assert result.package_name == expected_package\n\n\ndef _materialization_parameter_sets():\n    # inject the plugins used for materialization parameter tests\n    FooPlugin = AdapterPlugin(\n        adapter=mock.MagicMock(),\n        credentials=mock.MagicMock(),\n        include_path=\"/path/to/root/plugin\",\n        project_name=\"foo\",\n    )\n    FooPlugin.adapter.type.return_value = \"foo\"\n    inject_plugin(FooPlugin)\n\n    BarPlugin = AdapterPlugin(\n        adapter=mock.MagicMock(),\n        credentials=mock.MagicMock(),\n        include_path=\"/path/to/root/plugin\",\n        dependencies=[\"foo\"],\n        project_name=\"bar\",\n    )\n    BarPlugin.adapter.type.return_value = \"bar\"\n    inject_plugin(BarPlugin)\n\n    sets = [\n        FindMaterializationSpec(macros=[], adapter_type=\"foo\", expected=None),\n    ]\n\n    # default only, each project\n    sets.extend(\n        FindMaterializationSpec(\n            macros=[MockMaterialization(project, adapter_type=None)],\n            adapter_type=\"foo\",\n            expected=(project, \"default\"),\n        )\n        for project in [\"root\", \"dep\", \"dbt\"]\n    )\n\n    # other type only, each project\n    sets.extend(\n        FindMaterializationSpec(\n            macros=[MockMaterialization(project, adapter_type=\"bar\")],\n            adapter_type=\"foo\",\n            expected=None,\n        )\n        for project in [\"root\", \"dep\", \"dbt\"]\n    )\n\n    # matching type only, each project\n    sets.extend(\n        FindMaterializationSpec(\n            macros=[MockMaterialization(project, adapter_type=\"foo\")],\n            adapter_type=\"foo\",\n            expected=(project, \"foo\"),\n        )\n        for project in [\"root\", \"dep\", \"dbt\"]\n    )\n\n    sets.extend(\n        [\n            # matching type and default everywhere\n            FindMaterializationSpec(\n                macros=[\n                    MockMaterialization(project, adapter_type=atype)\n                    for (project, atype) in product([\"root\", \"dep\", \"dbt\"], [\"foo\", None])\n                ],\n                adapter_type=\"foo\",\n                expected=(\"root\", \"foo\"),\n            ),\n            # default in core, override is in dep, and root has unrelated override\n            # should find the dbt default because default materializations cannot be overwritten by packages.\n            FindMaterializationSpec(\n                macros=[\n                    MockMaterialization(\"root\", adapter_type=\"bar\"),\n                    MockMaterialization(\"dep\", adapter_type=\"foo\"),\n                    MockMaterialization(\"dbt\", adapter_type=None),\n                ],\n                adapter_type=\"foo\",\n                expected=(\"dbt\", \"default\"),\n            ),\n            # default in core, unrelated override is in dep, and root has an override\n            # should find the root override.\n            FindMaterializationSpec(\n                macros=[\n                    MockMaterialization(\"root\", adapter_type=\"foo\"),\n                    MockMaterialization(\"dep\", adapter_type=\"bar\"),\n                    MockMaterialization(\"dbt\", adapter_type=None),\n                ],\n                adapter_type=\"foo\",\n                expected=(\"root\", \"foo\"),\n            ),\n            # default in core, override is in dep, and root has an override too.\n            # should find the root override.\n            FindMaterializationSpec(\n                macros=[\n                    MockMaterialization(\"root\", adapter_type=\"foo\"),\n                    MockMaterialization(\"dep\", adapter_type=\"foo\"),\n                    MockMaterialization(\"dbt\", adapter_type=None),\n                ],\n                adapter_type=\"foo\",\n                expected=(\"root\", \"foo\"),\n            ),\n            # core has default + adapter, dep has adapter, root has default\n            # should find the default adapter implementation, because it's the most specific\n            # and default materializations cannot be overwritten by packages\n            FindMaterializationSpec(\n                macros=[\n                    MockMaterialization(\"root\", adapter_type=None),\n                    MockMaterialization(\"dep\", adapter_type=\"foo\"),\n                    MockMaterialization(\"dbt\", adapter_type=None),\n                    MockMaterialization(\"dbt\", adapter_type=\"foo\"),\n                ],\n                adapter_type=\"foo\",\n                expected=(\"dbt\", \"foo\"),\n            ),\n        ]\n    )\n\n    # inherit from parent adapter\n    sets.extend(\n        FindMaterializationSpec(\n            macros=[MockMaterialization(project, adapter_type=\"foo\")],\n            adapter_type=\"bar\",\n            expected=(project, \"foo\"),\n        )\n        for project in [\"root\", \"dep\", \"dbt\"]\n    )\n    sets.extend(\n        FindMaterializationSpec(\n            macros=[\n                MockMaterialization(project, adapter_type=\"foo\"),\n                MockMaterialization(project, adapter_type=\"bar\"),\n            ],\n            adapter_type=\"bar\",\n            expected=(project, \"bar\"),\n        )\n        for project in [\"root\", \"dep\", \"dbt\"]\n    )\n\n    return sets\n\n\n@pytest.mark.parametrize(\n    \"macros,adapter_type,expected\",\n    _materialization_parameter_sets(),\n    ids=id_mat,\n)\ndef test_find_materialization_by_name(macros, adapter_type, expected):\n    set_from_args(\n        Namespace(\n            SEND_ANONYMOUS_USAGE_STATS=False,\n            REQUIRE_EXPLICIT_PACKAGE_OVERRIDES_FOR_BUILTIN_MATERIALIZATIONS=True,\n        ),\n        None,\n    )\n\n    manifest = make_manifest(macros=macros)\n    result = manifest.find_materialization_macro_by_name(\n        project_name=\"root\",\n        materialization_name=\"my_materialization\",\n        adapter_type=adapter_type,\n    )\n    if expected is None:\n        assert result is expected\n    else:\n        expected_package, expected_adapter_type = expected\n        assert result.adapter_type == expected_adapter_type\n        assert result.package_name == expected_package\n\n\nFindNodeSpec = namedtuple(\"FindNodeSpec\", \"nodes,sources,package,version,expected\")\n\n\ndef _refable_parameter_sets():\n    sets = [\n        # empties\n        FindNodeSpec(nodes=[], sources=[], package=None, version=None, expected=None),\n        FindNodeSpec(nodes=[], sources=[], package=\"root\", version=None, expected=None),\n    ]\n    sets.extend(\n        # only one model, no package specified -> find it in any package\n        FindNodeSpec(\n            nodes=[MockNode(project, \"my_model\")],\n            sources=[],\n            package=None,\n            version=None,\n            expected=(project, \"my_model\"),\n        )\n        for project in [\"root\", \"dep\"]\n    )\n    # only one model, no package specified -> find it in any package\n    sets.extend(\n        [\n            FindNodeSpec(\n                nodes=[MockNode(\"root\", \"my_model\")],\n                sources=[],\n                package=\"root\",\n                version=None,\n                expected=(\"root\", \"my_model\"),\n            ),\n            FindNodeSpec(\n                nodes=[MockNode(\"dep\", \"my_model\")],\n                sources=[],\n                package=\"root\",\n                version=None,\n                expected=None,\n            ),\n            # versioned model lookups\n            FindNodeSpec(\n                nodes=[MockNode(\"root\", \"my_model\", version=\"2\")],\n                sources=[],\n                package=\"root\",\n                version=\"2\",\n                expected=(\"root\", \"my_model\", \"2\"),\n            ),\n            FindNodeSpec(\n                nodes=[MockNode(\"root\", \"my_model\", version=\"2\")],\n                sources=[],\n                package=\"root\",\n                version=2,\n                expected=(\"root\", \"my_model\", \"2\"),\n            ),\n            FindNodeSpec(\n                nodes=[MockNode(\"root\", \"my_model\", version=\"3\")],\n                sources=[],\n                package=\"root\",\n                version=\"2\",\n                expected=None,\n            ),\n            FindNodeSpec(\n                nodes=[MockNode(\"root\", \"my_model\", version=\"3\", is_latest_version=True)],\n                sources=[],\n                package=\"root\",\n                version=None,\n                expected=(\"root\", \"my_model\", \"3\"),\n            ),\n            FindNodeSpec(\n                nodes=[MockNode(\"root\", \"my_model\", version=\"3\", is_latest_version=False)],\n                sources=[],\n                package=\"root\",\n                version=None,\n                expected=None,\n            ),\n            FindNodeSpec(\n                nodes=[MockNode(\"root\", \"my_model\", version=\"0\", is_latest_version=False)],\n                sources=[],\n                package=\"root\",\n                version=None,\n                expected=None,\n            ),\n            FindNodeSpec(\n                nodes=[MockNode(\"root\", \"my_model\", version=\"0\", is_latest_version=True)],\n                sources=[],\n                package=\"root\",\n                version=None,\n                expected=(\"root\", \"my_model\", \"0\"),\n            ),\n            # a source with that name exists, but not a refable\n            FindNodeSpec(\n                nodes=[],\n                sources=[MockSource(\"root\", \"my_source\", \"my_model\")],\n                package=None,\n                version=None,\n                expected=None,\n            ),\n            # a source with that name exists, and a refable\n            FindNodeSpec(\n                nodes=[MockNode(\"root\", \"my_model\")],\n                sources=[MockSource(\"root\", \"my_source\", \"my_model\")],\n                package=None,\n                version=None,\n                expected=(\"root\", \"my_model\"),\n            ),\n            FindNodeSpec(\n                nodes=[MockNode(\"root\", \"my_model\")],\n                sources=[MockSource(\"root\", \"my_source\", \"my_model\")],\n                package=\"root\",\n                version=None,\n                expected=(\"root\", \"my_model\"),\n            ),\n            FindNodeSpec(\n                nodes=[MockNode(\"root\", \"my_model\")],\n                sources=[MockSource(\"root\", \"my_source\", \"my_model\")],\n                package=\"dep\",\n                version=None,\n                expected=None,\n            ),\n            # duplicate node name across package\n            FindNodeSpec(\n                nodes=[MockNode(\"project_a\", \"my_model\"), MockNode(\"project_b\", \"my_model\")],\n                sources=[],\n                package=\"project_a\",\n                version=None,\n                expected=(\"project_a\", \"my_model\"),\n            ),\n            # duplicate node name across package: root node preferred to package node\n            FindNodeSpec(\n                nodes=[MockNode(\"root\", \"my_model\"), MockNode(\"project_a\", \"my_model\")],\n                sources=[],\n                package=None,\n                version=None,\n                expected=(\"root\", \"my_model\"),\n            ),\n            FindNodeSpec(\n                nodes=[MockNode(\"root\", \"my_model\"), MockNode(\"project_a\", \"my_model\")],\n                sources=[],\n                package=\"root\",\n                version=None,\n                expected=(\"root\", \"my_model\"),\n            ),\n            FindNodeSpec(\n                nodes=[MockNode(\"root\", \"my_model\"), MockNode(\"project_a\", \"my_model\")],\n                sources=[],\n                package=\"project_a\",\n                version=None,\n                expected=(\"project_a\", \"my_model\"),\n            ),\n            # duplicate node name across package: resolved by version\n            FindNodeSpec(\n                nodes=[\n                    MockNode(\"project_a\", \"my_model\", version=\"1\"),\n                    MockNode(\"project_b\", \"my_model\", version=\"2\"),\n                ],\n                sources=[],\n                package=None,\n                version=\"1\",\n                expected=(\"project_a\", \"my_model\", \"1\"),\n            ),\n        ]\n    )\n    return sets\n\n\ndef _ambiguous_ref_parameter_sets():\n    sets = [\n        FindNodeSpec(\n            nodes=[MockNode(\"project_a\", \"my_model\"), MockNode(\"project_b\", \"my_model\")],\n            sources=[],\n            package=None,\n            version=None,\n            expected=None,\n        ),\n        FindNodeSpec(\n            nodes=[\n                MockNode(\"project_a\", \"my_model\", version=\"2\", is_latest_version=True),\n                MockNode(\"project_b\", \"my_model\", version=\"1\", is_latest_version=True),\n            ],\n            sources=[],\n            package=None,\n            version=None,\n            expected=None,\n        ),\n    ]\n    return sets\n\n\ndef _duplicate_node_name_across_packages_ref_parameter_sets():\n    sets = [\n        FindNodeSpec(\n            nodes=[MockNode(\"project_a\", \"my_model\"), MockNode(\"root\", \"my_model\")],\n            sources=[],\n            package=None,\n            version=None,\n            expected=(\"project_a\", \"my_model\"),\n        ),\n    ]\n    return sets\n\n\ndef id_nodes(arg):\n    if isinstance(arg, list):\n        node_names = \"__\".join(f\"{n.package_name}_{n.search_name}\" for n in arg)\n        return f\"m_[{node_names}]\"\n    elif isinstance(arg, tuple):\n        return \"_\".join(arg)\n\n\n@pytest.mark.parametrize(\n    \"nodes,sources,package,version,expected\",\n    _refable_parameter_sets(),\n    ids=id_nodes,\n)\ndef test_resolve_ref(nodes, sources, package, version, expected):\n    manifest = make_manifest(nodes=nodes, sources=sources)\n    result = manifest.resolve_ref(\n        source_node=None,\n        target_model_name=\"my_model\",\n        target_model_package=package,\n        target_model_version=version,\n        current_project=\"root\",\n        node_package=\"root\",\n    )\n    if expected is None:\n        assert result is expected\n    else:\n        assert result is not None\n        assert len(expected) in (2, 3)\n\n        if len(expected) == 2:\n            expected_package, expected_name = expected\n        elif len(expected) == 3:\n            expected_package, expected_name, expected_version = expected\n            assert result.version == expected_version\n        assert result.name == expected_name\n        assert result.package_name == expected_package\n\n\n@pytest.mark.parametrize(\n    \"nodes,sources,package,version,expected\",\n    _ambiguous_ref_parameter_sets(),\n    ids=id_nodes,\n)\ndef test_resolve_ref_ambiguous_resource_name_across_packages(\n    nodes, sources, package, version, expected\n):\n    manifest = make_manifest(\n        nodes=nodes,\n        sources=sources,\n    )\n    with pytest.raises(AmbiguousResourceNameRefError):\n        manifest.resolve_ref(\n            source_node=None,\n            target_model_name=\"my_model\",\n            target_model_package=None,\n            target_model_version=version,\n            current_project=\"root\",\n            node_package=\"root\",\n        )\n\n\n@pytest.mark.parametrize(\n    \"nodes,sources,package,version,expected\",\n    _duplicate_node_name_across_packages_ref_parameter_sets(),\n    ids=id_nodes,\n)\ndef test_resolve_ref_with_node_package_legacy(nodes, sources, package, version, expected):\n    set_from_args(\n        Namespace(\n            SEND_ANONYMOUS_USAGE_STATS=False,\n            REQUIRE_REF_SEARCHES_NODE_PACKAGE_BEFORE_ROOT=False,\n        ),\n        None,\n    )\n    manifest = make_manifest(nodes=nodes, sources=sources)\n    result = manifest.resolve_ref(\n        source_node=None,\n        target_model_name=\"my_model\",\n        target_model_package=package,\n        target_model_version=version,\n        current_project=\"root\",\n        node_package=\"project_a\",\n    )\n\n    assert result.name == \"my_model\"\n    assert result.package_name == \"root\"\n\n\n@pytest.mark.parametrize(\n    \"nodes,sources,package,version,expected\",\n    _duplicate_node_name_across_packages_ref_parameter_sets(),\n    ids=id_nodes,\n)\ndef test_resolve_ref_with_node_package(nodes, sources, package, version, expected):\n    set_from_args(\n        Namespace(\n            SEND_ANONYMOUS_USAGE_STATS=False,\n            REQUIRE_REF_SEARCHES_NODE_PACKAGE_BEFORE_ROOT=True,\n        ),\n        None,\n    )\n    manifest = make_manifest(nodes=nodes, sources=sources)\n    result = manifest.resolve_ref(\n        source_node=None,\n        target_model_name=\"my_model\",\n        target_model_package=package,\n        target_model_version=version,\n        current_project=\"root\",\n        node_package=\"project_a\",\n    )\n\n    assert result.name == \"my_model\"\n    assert result.package_name == \"project_a\"\n\n\ndef _source_parameter_sets():\n    sets = [\n        # empties\n        FindNodeSpec(nodes=[], sources=[], package=\"dep\", version=None, expected=None),\n        FindNodeSpec(nodes=[], sources=[], package=\"root\", version=None, expected=None),\n    ]\n    sets.extend(\n        # models with the name, but not sources\n        FindNodeSpec(\n            nodes=[MockNode(\"root\", name)],\n            sources=[],\n            package=project,\n            version=None,\n            expected=None,\n        )\n        for project in (\"root\", \"dep\")\n        for name in (\"my_source\", \"my_table\")\n    )\n    # exists in root alongside nodes with name parts\n    sets.extend(\n        FindNodeSpec(\n            nodes=[MockNode(\"root\", \"my_source\"), MockNode(\"root\", \"my_table\")],\n            sources=[MockSource(\"root\", \"my_source\", \"my_table\")],\n            package=project,\n            version=None,\n            expected=(\"root\", \"my_source\", \"my_table\"),\n        )\n        for project in (\"root\", \"dep\")\n    )\n    sets.extend(\n        # wrong source name\n        FindNodeSpec(\n            nodes=[],\n            sources=[MockSource(\"root\", \"my_other_source\", \"my_table\")],\n            package=project,\n            version=None,\n            expected=None,\n        )\n        for project in (\"root\", \"dep\")\n    )\n    sets.extend(\n        # wrong table name\n        FindNodeSpec(\n            nodes=[],\n            sources=[MockSource(\"root\", \"my_source\", \"my_other_table\")],\n            package=project,\n            version=None,\n            expected=None,\n        )\n        for project in (\"root\", \"dep\")\n    )\n    sets.append(\n        # should be found by the package=None search\n        FindNodeSpec(\n            nodes=[],\n            sources=[MockSource(\"other\", \"my_source\", \"my_table\")],\n            package=\"root\",\n            version=None,\n            expected=(\"other\", \"my_source\", \"my_table\"),\n        )\n    )\n    sets.extend(\n        # exists in root check various projects (other project -> not found)\n        FindNodeSpec(\n            nodes=[],\n            sources=[MockSource(\"root\", \"my_source\", \"my_table\")],\n            package=project,\n            version=None,\n            expected=(\"root\", \"my_source\", \"my_table\"),\n        )\n        for project in (\"root\", \"dep\")\n    )\n\n    return sets\n\n\n@pytest.mark.parametrize(\n    \"nodes,sources,package,version,expected\",\n    _source_parameter_sets(),\n    ids=id_nodes,\n)\ndef test_resolve_source(nodes, sources, package, version, expected):\n    set_from_args(\n        Namespace(\n            SEND_ANONYMOUS_USAGE_STATS=False,\n            REQUIRE_REF_SEARCHES_NODE_PACKAGE_BEFORE_ROOT=False,\n        ),\n        None,\n    )\n    manifest = make_manifest(nodes=nodes, sources=sources)\n    result = manifest.resolve_source(\n        target_source_name=\"my_source\",\n        target_table_name=\"my_table\",\n        current_project=package,\n        node_package=\"dep\",\n    )\n    if expected is None:\n        assert result is expected\n    else:\n        assert result is not None\n        assert len(expected) == 3\n        expected_package, expected_source_name, expected_name = expected\n        assert result.source_name == expected_source_name\n        assert result.name == expected_name\n        assert result.package_name == expected_package\n\n\nFindDocSpec = namedtuple(\"FindDocSpec\", \"docs,package,expected\")\n\n\ndef _docs_parameter_sets():\n    sets = []\n    sets.extend(\n        # empty\n        FindDocSpec(docs=[], package=project, expected=None)\n        for project in (\"root\", None)\n    )\n    sets.extend(\n        # basic: exists in root\n        FindDocSpec(\n            docs=[MockDocumentation(\"root\", \"my_doc\")],\n            package=project,\n            expected=(\"root\", \"my_doc\"),\n        )\n        for project in (\"root\", None)\n    )\n    sets.extend(\n        [\n            # exists in other\n            FindDocSpec(docs=[MockDocumentation(\"dep\", \"my_doc\")], package=\"root\", expected=None),\n            FindDocSpec(\n                docs=[MockDocumentation(\"dep\", \"my_doc\")], package=None, expected=(\"dep\", \"my_doc\")\n            ),\n        ]\n    )\n    return sets\n\n\n@pytest.mark.parametrize(\n    \"docs,package,expected\",\n    _docs_parameter_sets(),\n    ids=id_nodes,\n)\ndef test_resolve_doc(docs, package, expected):\n    manifest = make_manifest(docs=docs)\n    result = manifest.resolve_doc(\n        name=\"my_doc\", package=package, current_project=\"root\", node_package=\"root\"\n    )\n    if expected is None:\n        assert result is expected\n    else:\n        assert result is not None\n        assert len(expected) == 2\n        expected_package, expected_name = expected\n        assert result.name == expected_name\n        assert result.package_name == expected_package\n\n\nclass TestManifestFindNodeFromRefOrSource:\n    @pytest.fixture\n    def mock_node(self):\n        return MockNode(\"my_package\", \"my_model\")\n\n    @pytest.fixture\n    def mock_disabled_node(self):\n        return MockNode(\"my_package\", \"disabled_node\", config={\"enabled\": False})\n\n    @pytest.fixture\n    def mock_source(self):\n        return MockSource(\"root\", \"my_source\", \"source_table\")\n\n    @pytest.fixture\n    def mock_disabled_source(self):\n        return MockSource(\"root\", \"my_source\", \"disabled_source_table\", config={\"enabled\": False})\n\n    @pytest.fixture\n    def mock_manifest(self, mock_node, mock_source, mock_disabled_node, mock_disabled_source):\n        return make_manifest(\n            nodes=[mock_node, mock_disabled_node], sources=[mock_source, mock_disabled_source]\n        )\n\n    @pytest.mark.parametrize(\n        \"expression,expected_node\",\n        [\n            (\"ref('my_package', 'my_model')\", \"mock_node\"),\n            (\"ref('my_package', 'doesnt_exist')\", None),\n            (\"ref('my_package', 'disabled_node')\", \"mock_disabled_node\"),\n            (\"source('my_source', 'source_table')\", \"mock_source\"),\n            (\"source('my_source', 'doesnt_exist')\", None),\n            (\"source('my_source', 'disabled_source_table')\", \"mock_disabled_source\"),\n        ],\n    )\n    def test_find_node_from_ref_or_source(self, expression, expected_node, mock_manifest, request):\n        node = mock_manifest.find_node_from_ref_or_source(expression)\n\n        if expected_node is None:\n            assert node is None\n        else:\n            assert node == request.getfixturevalue(expected_node)\n\n    @pytest.mark.parametrize(\"invalid_expression\", [\"invalid\", \"ref(')\"])\n    def test_find_node_from_ref_or_source_invalid_expression(\n        self, invalid_expression, mock_manifest\n    ):\n        with pytest.raises(ParsingError):\n            mock_manifest.find_node_from_ref_or_source(invalid_expression)\n\n\nclass TestDisabledLookup:\n    @pytest.fixture(scope=\"class\")\n    def manifest(self):\n        return Manifest(\n            nodes={},\n            sources={},\n            macros={},\n            docs={},\n            disabled={},\n            files={},\n            exposures={},\n            selectors={},\n        )\n\n    @pytest.fixture(scope=\"class\")\n    def mock_model(self):\n        return MockNode(\"package\", \"name\", NodeType.Model)\n\n    @pytest.fixture(scope=\"class\")\n    def mock_model_with_version(self):\n        return MockNode(\"package\", \"name\", NodeType.Model, version=3)\n\n    @pytest.fixture(scope=\"class\")\n    def mock_seed(self):\n        return MockNode(\"package\", \"name\", NodeType.Seed)\n\n    def test_find(self, manifest, mock_model):\n        manifest.disabled = {\"model.package.name\": [mock_model]}\n        lookup = DisabledLookup(manifest)\n\n        assert lookup.find(\"name\", \"package\") == [mock_model]\n\n    def test_find_wrong_name(self, manifest, mock_model):\n        manifest.disabled = {\"model.package.name\": [mock_model]}\n        lookup = DisabledLookup(manifest)\n\n        assert lookup.find(\"missing_name\", \"package\") is None\n\n    def test_find_wrong_package(self, manifest, mock_model):\n        manifest.disabled = {\"model.package.name\": [mock_model]}\n        lookup = DisabledLookup(manifest)\n\n        assert lookup.find(\"name\", \"missing_package\") is None\n\n    def test_find_wrong_version(self, manifest, mock_model):\n        manifest.disabled = {\"model.package.name\": [mock_model]}\n        lookup = DisabledLookup(manifest)\n\n        assert lookup.find(\"name\", \"package\", version=3) is None\n\n    def test_find_wrong_resource_types(self, manifest, mock_model):\n        manifest.disabled = {\"model.package.name\": [mock_model]}\n        lookup = DisabledLookup(manifest)\n\n        assert lookup.find(\"name\", \"package\", resource_types=[NodeType.Analysis]) is None\n\n    def test_find_no_package(self, manifest, mock_model):\n        manifest.disabled = {\"model.package.name\": [mock_model]}\n        lookup = DisabledLookup(manifest)\n\n        assert lookup.find(\"name\", None) == [mock_model]\n\n    def test_find_versioned_node(self, manifest, mock_model_with_version):\n        manifest.disabled = {\"model.package.name\": [mock_model_with_version]}\n        lookup = DisabledLookup(manifest)\n\n        assert lookup.find(\"name\", \"package\", version=3) == [mock_model_with_version]\n\n    def test_find_versioned_node_no_package(self, manifest, mock_model_with_version):\n        manifest.disabled = {\"model.package.name\": [mock_model_with_version]}\n        lookup = DisabledLookup(manifest)\n\n        assert lookup.find(\"name\", None, version=3) == [mock_model_with_version]\n\n    def test_find_versioned_node_no_version(self, manifest, mock_model_with_version):\n        manifest.disabled = {\"model.package.name\": [mock_model_with_version]}\n        lookup = DisabledLookup(manifest)\n\n        assert lookup.find(\"name\", \"package\") is None\n\n    def test_find_versioned_node_wrong_version(self, manifest, mock_model_with_version):\n        manifest.disabled = {\"model.package.name\": [mock_model_with_version]}\n        lookup = DisabledLookup(manifest)\n\n        assert lookup.find(\"name\", \"package\", version=2) is None\n\n    def test_find_versioned_node_wrong_name(self, manifest, mock_model_with_version):\n        manifest.disabled = {\"model.package.name\": [mock_model_with_version]}\n        lookup = DisabledLookup(manifest)\n\n        assert lookup.find(\"wrong_name\", \"package\", version=3) is None\n\n    def test_find_versioned_node_wrong_package(self, manifest, mock_model_with_version):\n        manifest.disabled = {\"model.package.name\": [mock_model_with_version]}\n        lookup = DisabledLookup(manifest)\n\n        assert lookup.find(\"name\", \"wrong_package\", version=3) is None\n\n    def test_find_multiple_nodes(self, manifest, mock_model, mock_seed):\n        manifest.disabled = {\"model.package.name\": [mock_model, mock_seed]}\n        lookup = DisabledLookup(manifest)\n\n        assert lookup.find(\"name\", \"package\") == [mock_model, mock_seed]\n\n    def test_find_multiple_nodes_with_resource_types(self, manifest, mock_model, mock_seed):\n        manifest.disabled = {\"model.package.name\": [mock_model, mock_seed]}\n        lookup = DisabledLookup(manifest)\n\n        assert lookup.find(\"name\", \"package\", resource_types=[NodeType.Model]) == [mock_model]\n\n    def test_find_multiple_nodes_with_wrong_resource_types(self, manifest, mock_model, mock_seed):\n        manifest.disabled = {\"model.package.name\": [mock_model, mock_seed]}\n        lookup = DisabledLookup(manifest)\n\n        assert lookup.find(\"name\", \"package\", resource_types=[NodeType.Analysis]) is None\n\n    def test_find_multiple_nodes_with_resource_types_empty(self, manifest, mock_model, mock_seed):\n        manifest.disabled = {\"model.package.name\": [mock_model, mock_seed]}\n        lookup = DisabledLookup(manifest)\n\n        assert lookup.find(\"name\", \"package\", resource_types=[]) is None\n"
  },
  {
    "path": "tests/unit/contracts/graph/test_node_args.py",
    "content": "from dbt.contracts.graph.node_args import ModelNodeArgs\n\n\nclass TestModelNodeArgs:\n    def test_model_node_args_unique_id(self) -> None:\n        model_node_args = ModelNodeArgs(\n            name=\"name\", package_name=\"package\", identifier=\"identifier\", schema=\"schema\"\n        )\n        assert model_node_args.unique_id == \"model.package.name\"\n\n    def test_model_node_args_unique_id_with_version(self) -> None:\n        model_node_args = ModelNodeArgs(\n            name=\"name\",\n            package_name=\"package\",\n            identifier=\"identifier\",\n            schema=\"schema\",\n            version=1,\n        )\n        assert model_node_args.unique_id == \"model.package.name.v1\"\n\n    def test_model_node_args_fqn(self) -> None:\n        model_node_args = ModelNodeArgs(\n            name=\"name\",\n            package_name=\"package\",\n            identifier=\"identifier\",\n            schema=\"schema\",\n        )\n        assert model_node_args.fqn == [\"package\", \"name\"]\n\n    def test_model_node_args_fqn_with_version(self) -> None:\n        model_node_args = ModelNodeArgs(\n            name=\"name\",\n            package_name=\"package\",\n            identifier=\"identifier\",\n            schema=\"schema\",\n            version=1,\n        )\n        assert model_node_args.fqn == [\"package\", \"name\", \"v1\"]\n\n    def test_model_node_args_fqn_with_version_zero(self) -> None:\n        model_node_args = ModelNodeArgs(\n            name=\"name\",\n            package_name=\"package\",\n            identifier=\"identifier\",\n            schema=\"schema\",\n            version=0,\n        )\n        assert model_node_args.fqn == [\"package\", \"name\", \"v0\"]\n"
  },
  {
    "path": "tests/unit/contracts/graph/test_nodes.py",
    "content": "import pickle\nimport re\nfrom argparse import Namespace\nfrom dataclasses import replace\n\nimport pytest\n\nfrom dbt.artifacts.resources import ColumnInfo, TestConfig, TestMetadata\nfrom dbt.compilation import inject_ctes_into_sql\nfrom dbt.contracts.files import FileHash\nfrom dbt.contracts.graph.nodes import (\n    DependsOn,\n    GenericTestNode,\n    InjectedCTE,\n    ModelConfig,\n    ModelNode,\n)\nfrom dbt.node_types import NodeType\nfrom tests.unit.fixtures import generic_test_node, model_node\nfrom tests.unit.utils import (\n    assert_fails_validation,\n    assert_from_dict,\n    assert_symmetric,\n    replace_config,\n)\n\n\n@pytest.fixture\ndef args_for_flags() -> Namespace:\n    return Namespace(state_modified_compare_vars=False)\n\n\ndef norm_whitespace(string):\n    _RE_COMBINE_WHITESPACE = re.compile(r\"\\s+\")\n    string = _RE_COMBINE_WHITESPACE.sub(\" \", string).strip()\n    return string\n\n\n@pytest.fixture\ndef basic_uncompiled_model():\n    return ModelNode(\n        package_name=\"test\",\n        path=\"/root/models/foo.sql\",\n        original_file_path=\"models/foo.sql\",\n        language=\"sql\",\n        raw_code='select * from {{ ref(\"other\") }}',\n        name=\"foo\",\n        resource_type=NodeType.Model,\n        unique_id=\"model.test.foo\",\n        fqn=[\"test\", \"models\", \"foo\"],\n        refs=[],\n        sources=[],\n        metrics=[],\n        depends_on=DependsOn(),\n        description=\"\",\n        database=\"test_db\",\n        schema=\"test_schema\",\n        alias=\"bar\",\n        tags=[],\n        config=ModelConfig(),\n        meta={},\n        compiled=False,\n        extra_ctes=[],\n        extra_ctes_injected=False,\n        checksum=FileHash.from_contents(\"\"),\n        unrendered_config={},\n    )\n\n\n@pytest.fixture\ndef basic_compiled_model():\n    return model_node()\n\n\n@pytest.fixture\ndef minimal_uncompiled_dict():\n    return {\n        \"name\": \"foo\",\n        \"created_at\": 1,\n        \"resource_type\": str(NodeType.Model),\n        \"path\": \"/root/models/foo.sql\",\n        \"original_file_path\": \"models/foo.sql\",\n        \"package_name\": \"test\",\n        \"language\": \"sql\",\n        \"raw_code\": 'select * from {{ ref(\"other\") }}',\n        \"unique_id\": \"model.test.foo\",\n        \"fqn\": [\"test\", \"models\", \"foo\"],\n        \"database\": \"test_db\",\n        \"schema\": \"test_schema\",\n        \"alias\": \"bar\",\n        \"compiled\": False,\n        \"checksum\": {\n            \"name\": \"sha256\",\n            \"checksum\": \"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\",\n        },\n        \"unrendered_config\": {},\n    }\n\n\n@pytest.fixture\ndef basic_uncompiled_dict():\n    return {\n        \"name\": \"foo\",\n        \"created_at\": 1,\n        \"resource_type\": str(NodeType.Model),\n        \"path\": \"/root/models/foo.sql\",\n        \"original_file_path\": \"models/foo.sql\",\n        \"package_name\": \"test\",\n        \"language\": \"sql\",\n        \"raw_code\": 'select * from {{ ref(\"other\") }}',\n        \"unique_id\": \"model.test.foo\",\n        \"fqn\": [\"test\", \"models\", \"foo\"],\n        \"refs\": [],\n        \"sources\": [],\n        \"metrics\": [],\n        \"depends_on\": {\"macros\": [], \"nodes\": []},\n        \"database\": \"test_db\",\n        \"description\": \"\",\n        \"schema\": \"test_schema\",\n        \"alias\": \"bar\",\n        \"tags\": [],\n        \"config\": {\n            \"column_types\": {},\n            \"enabled\": True,\n            \"materialized\": \"view\",\n            \"persist_docs\": {},\n            \"post-hook\": [],\n            \"pre-hook\": [],\n            \"quoting\": {},\n            \"tags\": [],\n            \"on_schema_change\": \"ignore\",\n            \"on_configuration_change\": \"apply\",\n            \"meta\": {},\n            \"grants\": {},\n            \"packages\": [],\n        },\n        \"docs\": {\"show\": True},\n        \"columns\": {},\n        \"meta\": {},\n        \"compiled\": False,\n        \"extra_ctes\": [],\n        \"extra_ctes_injected\": False,\n        \"checksum\": {\n            \"name\": \"sha256\",\n            \"checksum\": \"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\",\n        },\n        \"unrendered_config\": {},\n        \"unrendered_config_call_dict\": {},\n        \"config_call_dict\": {},\n    }\n\n\n@pytest.fixture\ndef basic_compiled_dict():\n    return {\n        \"name\": \"foo\",\n        \"created_at\": 1,\n        \"resource_type\": str(NodeType.Model),\n        \"path\": \"/root/models/foo.sql\",\n        \"original_file_path\": \"models/foo.sql\",\n        \"package_name\": \"test\",\n        \"language\": \"sql\",\n        \"raw_code\": 'select * from {{ ref(\"other\") }}',\n        \"unique_id\": \"model.test.foo\",\n        \"fqn\": [\"test\", \"models\", \"foo\"],\n        \"refs\": [],\n        \"sources\": [],\n        \"metrics\": [],\n        \"functions\": [],\n        \"depends_on\": {\"macros\": [], \"nodes\": []},\n        \"database\": \"test_db\",\n        \"description\": \"\",\n        \"primary_key\": [],\n        \"schema\": \"test_schema\",\n        \"alias\": \"bar\",\n        \"tags\": [],\n        \"config\": {\n            \"column_types\": {},\n            \"enabled\": True,\n            \"materialized\": \"view\",\n            \"persist_docs\": {},\n            \"post-hook\": [],\n            \"pre-hook\": [],\n            \"quoting\": {},\n            \"tags\": [],\n            \"on_schema_change\": \"ignore\",\n            \"on_configuration_change\": \"apply\",\n            \"meta\": {},\n            \"grants\": {},\n            \"packages\": [],\n            \"contract\": {\"enforced\": False, \"alias_types\": True},\n            \"docs\": {\"show\": True},\n            \"access\": \"protected\",\n            \"lookback\": 1,\n        },\n        \"docs\": {\"show\": True},\n        \"columns\": {},\n        \"contract\": {\"enforced\": False, \"alias_types\": True},\n        \"meta\": {},\n        \"compiled\": True,\n        \"extra_ctes\": [{\"id\": \"whatever\", \"sql\": \"select * from other\"}],\n        \"extra_ctes_injected\": True,\n        \"compiled_code\": \"with whatever as (select * from other) select * from whatever\",\n        \"checksum\": {\n            \"name\": \"sha256\",\n            \"checksum\": \"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\",\n        },\n        \"unrendered_config\": {},\n        \"unrendered_config_call_dict\": {},\n        \"config_call_dict\": {},\n        \"access\": \"protected\",\n        \"constraints\": [],\n        \"doc_blocks\": [],\n    }\n\n\n@pytest.mark.skip(\"Haven't found where we would use uncompiled node\")\ndef test_basic_uncompiled_model(\n    minimal_uncompiled_dict, basic_uncompiled_dict, basic_uncompiled_model\n):\n    node_dict = basic_uncompiled_dict\n    node = basic_uncompiled_model\n    assert_symmetric(node, node_dict, ModelNode)\n    assert node.empty is False\n    assert node.is_refable is True\n    assert node.is_ephemeral is False\n\n    assert_from_dict(node, minimal_uncompiled_dict, ModelNode)\n    pickle.loads(pickle.dumps(node))\n\n\ndef test_basic_compiled_model(basic_compiled_dict, basic_compiled_model):\n    node_dict = basic_compiled_dict\n    node = basic_compiled_model\n    assert_symmetric(node, node_dict, ModelNode)\n    assert node.empty is False\n    assert node.is_refable is True\n    assert node.is_ephemeral is False\n\n\ndef test_extra_fields_model_okay(minimal_uncompiled_dict):\n    extra = minimal_uncompiled_dict\n    extra[\"notvalid\"] = \"nope\"\n    # Model still load fine with extra fields\n    loaded_model = ModelNode.from_dict(extra)\n    assert not hasattr(loaded_model, \"notvalid\")\n\n\ndef test_invalid_bad_type_model(minimal_uncompiled_dict):\n    bad_type = minimal_uncompiled_dict\n    bad_type[\"resource_type\"] = str(NodeType.Macro)\n    assert_fails_validation(bad_type, ModelNode)\n\n\nunchanged_compiled_models = [\n    lambda u: (u, replace(u, description=\"a description\")),\n    lambda u: (u, replace(u, tags=[\"mytag\"])),\n    lambda u: (u, replace(u, meta={\"cool_key\": \"cool value\"})),\n    # changing the final alias/schema/datbase isn't a change - could just be target changing!\n    lambda u: (u, replace(u, database=\"nope\")),\n    lambda u: (u, replace(u, schema=\"nope\")),\n    lambda u: (u, replace(u, alias=\"nope\")),\n    # None -> False is a config change even though it's pretty much the same\n    lambda u: (\n        replace(u, config=replace(u.config, persist_docs={\"relation\": False})),\n        replace(u, config=replace(u.config, persist_docs={\"relation\": False})),\n    ),\n    lambda u: (\n        replace(u, config=replace(u.config, persist_docs={\"columns\": False})),\n        replace(u, config=replace(u.config, persist_docs={\"columns\": False})),\n    ),\n    # True -> True\n    lambda u: (\n        replace(u, config=replace(u.config, persist_docs={\"relation\": True})),\n        replace(u, config=replace(u.config, persist_docs={\"relation\": True})),\n    ),\n    lambda u: (\n        replace(u, config=replace(u.config, persist_docs={\"columns\": True})),\n        replace(u, config=replace(u.config, persist_docs={\"columns\": True})),\n    ),\n    # only columns docs enabled, but description changed\n    lambda u: (\n        replace(u, config=replace(u.config, persist_docs={\"columns\": True})),\n        replace(\n            u,\n            config=replace(u.config, persist_docs={\"columns\": True}),\n            description=\"a model description\",\n        ),\n    ),\n    # only relation docs eanbled, but columns changed\n    lambda u: (\n        replace(u, config=replace(u.config, persist_docs={\"relation\": True})),\n        replace(\n            u,\n            config=replace(u.config, persist_docs={\"relation\": True}),\n            columns={\"a\": ColumnInfo(name=\"a\", description=\"a column description\")},\n        ),\n    ),\n]\n\n\nchanged_compiled_models = [\n    lambda u: (u, None),\n    lambda u: (u, replace(u, raw_code=\"select * from wherever\")),\n    lambda u: (\n        u,\n        replace(\n            u,\n            fqn=[\"test\", \"models\", \"subdir\", \"foo\"],\n            original_file_path=\"models/subdir/foo.sql\",\n            path=\"/root/models/subdir/foo.sql\",\n        ),\n    ),\n    lambda u: (u, replace_config(u, full_refresh=True)),\n    lambda u: (u, replace_config(u, post_hook=[\"select 1 as id\"])),\n    lambda u: (u, replace_config(u, pre_hook=[\"select 1 as id\"])),\n    lambda u: (\n        u,\n        replace_config(u, quoting={\"database\": True, \"schema\": False, \"identifier\": False}),\n    ),\n    # we changed persist_docs values\n    lambda u: (u, replace_config(u, persist_docs={\"relation\": True})),\n    lambda u: (u, replace_config(u, persist_docs={\"columns\": True})),\n    lambda u: (u, replace_config(u, persist_docs={\"columns\": True, \"relation\": True})),\n    # None -> False is a config change even though it's pretty much the same\n    lambda u: (u, replace_config(u, persist_docs={\"relation\": False})),\n    lambda u: (u, replace_config(u, persist_docs={\"columns\": False})),\n    # persist docs was true for the relation and we changed the model description\n    lambda u: (\n        replace_config(u, persist_docs={\"relation\": True}),\n        replace_config(u, persist_docs={\"relation\": True}, description=\"a model description\"),\n    ),\n    # persist docs was true for columns and we changed the model description\n    lambda u: (\n        replace_config(u, persist_docs={\"columns\": True}),\n        replace_config(\n            u,\n            persist_docs={\"columns\": True},\n            columns={\"a\": ColumnInfo(name=\"a\", description=\"a column description\")},\n        ),\n    ),\n    # changing alias/schema/database on the config level is a change\n    lambda u: (u, replace_config(u, database=\"nope\")),\n    lambda u: (u, replace_config(u, schema=\"nope\")),\n    lambda u: (u, replace_config(u, alias=\"nope\")),\n]\n\n\n@pytest.mark.parametrize(\"func\", unchanged_compiled_models)\ndef test_compare_unchanged_model(func, basic_uncompiled_model):\n    node, compare = func(basic_uncompiled_model)\n    assert node.same_contents(compare, \"postgres\")\n\n\n@pytest.mark.parametrize(\"func\", changed_compiled_models)\ndef test_compare_changed_model(func, basic_uncompiled_model):\n    node, compare = func(basic_uncompiled_model)\n    assert not node.same_contents(compare, \"postgres\")\n\n\n@pytest.fixture\ndef minimal_schema_test_dict():\n    return {\n        \"name\": \"foo\",\n        \"created_at\": 1,\n        \"resource_type\": str(NodeType.Test),\n        \"path\": \"/root/x/path.sql\",\n        \"original_file_path\": \"/root/path.sql\",\n        \"package_name\": \"test\",\n        \"language\": \"sql\",\n        \"raw_code\": 'select * from {{ ref(\"other\") }}',\n        \"unique_id\": \"model.test.foo\",\n        \"fqn\": [\"test\", \"models\", \"foo\"],\n        \"database\": \"test_db\",\n        \"schema\": \"dbt_test__audit\",\n        \"alias\": \"bar\",\n        \"test_metadata\": {\n            \"name\": \"foo\",\n            \"kwargs\": {},\n        },\n        \"compiled\": False,\n        \"checksum\": {\n            \"name\": \"sha256\",\n            \"checksum\": \"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\",\n        },\n    }\n\n\n@pytest.fixture\ndef basic_uncompiled_schema_test_node():\n    return GenericTestNode(\n        package_name=\"test\",\n        path=\"/root/x/path.sql\",\n        original_file_path=\"/root/path.sql\",\n        language=\"sql\",\n        raw_code='select * from {{ ref(\"other\") }}',\n        name=\"foo\",\n        resource_type=NodeType.Test,\n        unique_id=\"model.test.foo\",\n        fqn=[\"test\", \"models\", \"foo\"],\n        refs=[],\n        sources=[],\n        metrics=[],\n        depends_on=DependsOn(),\n        description=\"\",\n        database=\"test_db\",\n        schema=\"dbt_test__audit\",\n        alias=\"bar\",\n        tags=[],\n        config=TestConfig(),\n        meta={},\n        compiled=False,\n        extra_ctes=[],\n        extra_ctes_injected=False,\n        test_metadata=TestMetadata(namespace=None, name=\"foo\", kwargs={}),\n        checksum=FileHash.from_contents(\"\"),\n        unrendered_config={},\n    )\n\n\n@pytest.fixture\ndef basic_compiled_schema_test_node():\n    return generic_test_node()\n\n\n@pytest.fixture\ndef basic_uncompiled_schema_test_dict():\n    return {\n        \"name\": \"foo\",\n        \"created_at\": 1,\n        \"resource_type\": str(NodeType.Test),\n        \"path\": \"/root/x/path.sql\",\n        \"original_file_path\": \"/root/path.sql\",\n        \"package_name\": \"test\",\n        \"language\": \"sql\",\n        \"raw_code\": 'select * from {{ ref(\"other\") }}',\n        \"unique_id\": \"model.test.foo\",\n        \"fqn\": [\"test\", \"models\", \"foo\"],\n        \"refs\": [],\n        \"sources\": [],\n        \"metrics\": [],\n        \"depends_on\": {\"macros\": [], \"nodes\": []},\n        \"database\": \"test_db\",\n        \"description\": \"\",\n        \"schema\": \"dbt_test__audit\",\n        \"alias\": \"bar\",\n        \"tags\": [],\n        \"config\": {\n            \"enabled\": True,\n            \"materialized\": \"test\",\n            \"tags\": [],\n            \"severity\": \"ERROR\",\n            \"schema\": \"dbt_test__audit\",\n            \"warn_if\": \"!= 0\",\n            \"error_if\": \"!= 0\",\n            \"fail_calc\": \"count(*)\",\n            \"meta\": {},\n        },\n        \"docs\": {\"show\": True},\n        \"columns\": {},\n        \"meta\": {},\n        \"compiled\": False,\n        \"extra_ctes\": [],\n        \"extra_ctes_injected\": False,\n        \"test_metadata\": {\n            \"name\": \"foo\",\n            \"kwargs\": {},\n        },\n        \"checksum\": {\n            \"name\": \"sha256\",\n            \"checksum\": \"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\",\n        },\n        \"unrendered_config\": {},\n        \"unrendered_config_call_dict\": {},\n        \"config_call_dict\": {},\n    }\n\n\n@pytest.fixture\ndef basic_compiled_schema_test_dict():\n    return {\n        \"name\": \"foo\",\n        \"created_at\": 1,\n        \"resource_type\": str(NodeType.Test),\n        \"path\": \"/root/x/path.sql\",\n        \"original_file_path\": \"/root/path.sql\",\n        \"package_name\": \"test\",\n        \"language\": \"sql\",\n        \"raw_code\": 'select * from {{ ref(\"other\") }}',\n        \"unique_id\": \"model.test.foo\",\n        \"fqn\": [\"test\", \"models\", \"foo\"],\n        \"refs\": [],\n        \"sources\": [],\n        \"metrics\": [],\n        \"functions\": [],\n        \"depends_on\": {\"macros\": [], \"nodes\": []},\n        \"database\": \"test_db\",\n        \"description\": \"\",\n        \"schema\": \"dbt_test__audit\",\n        \"alias\": \"bar\",\n        \"tags\": [],\n        \"config\": {\n            \"enabled\": True,\n            \"materialized\": \"test\",\n            \"tags\": [],\n            \"severity\": \"warn\",\n            \"schema\": \"dbt_test__audit\",\n            \"warn_if\": \"!= 0\",\n            \"error_if\": \"!= 0\",\n            \"fail_calc\": \"count(*)\",\n            \"meta\": {},\n        },\n        \"docs\": {\"show\": True},\n        \"columns\": {},\n        \"contract\": {\"enforced\": False, \"alias_types\": True},\n        \"meta\": {},\n        \"compiled\": True,\n        \"extra_ctes\": [{\"id\": \"whatever\", \"sql\": \"select * from other\"}],\n        \"extra_ctes_injected\": True,\n        \"compiled_code\": \"with whatever as (select * from other) select * from whatever\",\n        \"column_name\": \"id\",\n        \"test_metadata\": {\n            \"name\": \"foo\",\n            \"kwargs\": {},\n        },\n        \"checksum\": {\n            \"name\": \"sha256\",\n            \"checksum\": \"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\",\n        },\n        \"unrendered_config\": {\n            \"severity\": \"warn\",\n        },\n        \"unrendered_config_call_dict\": {},\n        \"config_call_dict\": {},\n        \"doc_blocks\": [],\n    }\n\n\n@pytest.mark.skip(\"Haven't found where we would use uncompiled node\")\ndef test_basic_uncompiled_schema_test(\n    basic_uncompiled_schema_test_node, basic_uncompiled_schema_test_dict, minimal_schema_test_dict\n):\n    node = basic_uncompiled_schema_test_node\n    node_dict = basic_uncompiled_schema_test_dict\n    minimum = minimal_schema_test_dict\n    assert_symmetric(node, node_dict, GenericTestNode)\n    assert node.empty is False\n    assert node.is_refable is False\n    assert node.is_ephemeral is False\n\n    assert_from_dict(node, minimum, GenericTestNode)\n\n\ndef test_basic_compiled_schema_test(\n    basic_compiled_schema_test_node, basic_compiled_schema_test_dict\n):\n    node = basic_compiled_schema_test_node\n    node_dict = basic_compiled_schema_test_dict\n\n    assert_symmetric(node, node_dict, GenericTestNode)\n    assert node.empty is False\n    assert node.is_refable is False\n    assert node.is_ephemeral is False\n\n\ndef test_invalid_extra_schema_test_fields(minimal_schema_test_dict):\n    bad_extra = minimal_schema_test_dict\n    bad_extra[\"extra\"] = \"extra value\"\n    assert_fails_validation(bad_extra, GenericTestNode)\n\n\ndef test_invalid_resource_type_schema_test(minimal_schema_test_dict):\n    bad_type = minimal_schema_test_dict\n    bad_type[\"resource_type\"] = str(NodeType.Model)\n    assert_fails_validation(bad_type, GenericTestNode)\n\n\nunchanged_schema_tests = [\n    # for tests, raw_code isn't a change (because it's always the same for a given test macro)\n    lambda u: replace(u, raw_code=\"select * from wherever\"),\n    lambda u: replace(u, description=\"a description\"),\n    lambda u: replace(u, tags=[\"mytag\"]),\n    lambda u: replace(u, meta={\"cool_key\": \"cool value\"}),\n    # these values don't even mean anything on schema tests!\n    lambda u: replace_config(u, alias=\"nope\"),\n    lambda u: replace_config(u, database=\"nope\"),\n    lambda u: replace_config(u, schema=\"nope\"),\n    lambda u: replace(u, database=\"other_db\"),\n    lambda u: replace(u, schema=\"other_schema\"),\n    lambda u: replace(u, alias=\"foo\"),\n    lambda u: replace_config(u, full_refresh=True),\n    lambda u: replace_config(u, post_hook=[\"select 1 as id\"]),\n    lambda u: replace_config(u, pre_hook=[\"select 1 as id\"]),\n    lambda u: replace_config(u, quoting={\"database\": True, \"schema\": False, \"identifier\": False}),\n]\n\n\nchanged_schema_tests = [\n    lambda u: None,\n    lambda u: replace(\n        u,\n        fqn=[\"test\", \"models\", \"subdir\", \"foo\"],\n        original_file_path=\"models/subdir/foo.sql\",\n        path=\"/root/models/subdir/foo.sql\",\n    ),\n    lambda u: replace_config(u, severity=\"warn\"),\n    # If we checked test metadata, these would caount. But we don't, because these changes would all change the unique ID, so it's irrelevant.\n    # lambda u: replace(u, test_metadata=replace(u.test_metadata, namespace='something')),\n    # lambda u: replace(u, test_metadata=replace(u.test_metadata, name='bar')),\n    # lambda u: replace(u, test_metadata=replace(u.test_metadata, kwargs={'arg': 'value'})),\n]\n\n\n@pytest.mark.parametrize(\"func\", unchanged_schema_tests)\ndef test_compare_unchanged_schema_test(func, basic_uncompiled_schema_test_node):\n    value = func(basic_uncompiled_schema_test_node)\n    assert basic_uncompiled_schema_test_node.same_contents(value, \"postgres\")\n\n\n@pytest.mark.parametrize(\"func\", changed_schema_tests)\ndef test_compare_changed_schema_test(func, basic_uncompiled_schema_test_node):\n    value = func(basic_uncompiled_schema_test_node)\n    assert not basic_uncompiled_schema_test_node.same_contents(value, \"postgres\")\n\n\ndef test_compare_to_compiled(basic_uncompiled_schema_test_node, basic_compiled_schema_test_node):\n    # if you fix the severity, they should be the \"same\".\n    uncompiled = basic_uncompiled_schema_test_node\n    compiled = basic_compiled_schema_test_node\n    assert not uncompiled.same_contents(compiled, \"postgres\")\n    fixed_config = replace(compiled.config, severity=uncompiled.config.severity)\n    fixed_compiled = replace(\n        compiled, config=fixed_config, unrendered_config=uncompiled.unrendered_config\n    )\n    assert uncompiled.same_contents(fixed_compiled, \"postgres\")\n\n\ndef test_inject_ctes_simple1():\n    starting_sql = \"select * from __dbt__cte__base\"\n    ctes = [\n        InjectedCTE(\n            id=\"model.test.base\",\n            sql=\" __dbt__cte__base as (\\n\\n\\nselect * from test16873767336887004702_test_ephemeral.seed\\n)\",\n        )\n    ]\n    expected_sql = \"\"\"with __dbt__cte__base as (\n        select * from test16873767336887004702_test_ephemeral.seed\n        ) select * from __dbt__cte__base\"\"\"\n\n    generated_sql = inject_ctes_into_sql(starting_sql, ctes)\n    assert norm_whitespace(generated_sql) == norm_whitespace(expected_sql)\n\n\ndef test_inject_ctes_simple2():\n    starting_sql = \"select * from __dbt__cte__ephemeral_level_two\"\n    ctes = [\n        InjectedCTE(\n            id=\"model.test.ephemeral_level_two\",\n            sql=' __dbt__cte__ephemeral_level_two as (\\n\\nselect * from \"dbt\".\"test16873757769710148165_test_ephemeral\".\"source_table\"\\n)',\n        )\n    ]\n    expected_sql = \"\"\"with __dbt__cte__ephemeral_level_two as (\n        select * from \"dbt\".\"test16873757769710148165_test_ephemeral\".\"source_table\"\n        ) select * from __dbt__cte__ephemeral_level_two\"\"\"\n\n    generated_sql = inject_ctes_into_sql(starting_sql, ctes)\n    assert norm_whitespace(generated_sql) == norm_whitespace(expected_sql)\n\n\ndef test_inject_ctes_multiple_ctes():\n\n    starting_sql = \"select * from __dbt__cte__ephemeral\"\n    ctes = [\n        InjectedCTE(\n            id=\"model.test.ephemeral_level_two\",\n            sql=' __dbt__cte__ephemeral_level_two as (\\n\\nselect * from \"dbt\".\"test16873735573223965828_test_ephemeral\".\"source_table\"\\n)',\n        ),\n        InjectedCTE(\n            id=\"model.test.ephemeral\",\n            sql=\" __dbt__cte__ephemeral as (\\n\\nselect * from __dbt__cte__ephemeral_level_two\\n)\",\n        ),\n    ]\n    expected_sql = \"\"\"with __dbt__cte__ephemeral_level_two as (\n            select * from \"dbt\".\"test16873735573223965828_test_ephemeral\".\"source_table\"\n        ),  __dbt__cte__ephemeral as (\n            select * from __dbt__cte__ephemeral_level_two\n        ) select * from __dbt__cte__ephemeral\"\"\"\n\n    generated_sql = inject_ctes_into_sql(starting_sql, ctes)\n    assert norm_whitespace(generated_sql) == norm_whitespace(expected_sql)\n\n\ndef test_inject_ctes_multiple_ctes_more_complex():\n    starting_sql = \"\"\"select * from __dbt__cte__female_only\n        union all\n        select * from \"dbt\".\"test16873757723266827902_test_ephemeral\".\"double_dependent\" where gender = 'Male'\"\"\"\n    ctes = [\n        InjectedCTE(\n            id=\"model.test.base\",\n            sql=\" __dbt__cte__base as (\\n\\n\\nselect * from test16873757723266827902_test_ephemeral.seed\\n)\",\n        ),\n        InjectedCTE(\n            id=\"model.test.base_copy\",\n            sql=\" __dbt__cte__base_copy as (\\n\\n\\nselect * from __dbt__cte__base\\n)\",\n        ),\n        InjectedCTE(\n            id=\"model.test.female_only\",\n            sql=\" __dbt__cte__female_only as (\\n\\n\\nselect * from __dbt__cte__base_copy where gender = 'Female'\\n)\",\n        ),\n    ]\n    expected_sql = \"\"\"with __dbt__cte__base as (\n            select * from test16873757723266827902_test_ephemeral.seed\n        ),  __dbt__cte__base_copy as (\n            select * from __dbt__cte__base\n        ),  __dbt__cte__female_only as (\n            select * from __dbt__cte__base_copy where gender = 'Female'\n        ) select * from __dbt__cte__female_only\n        union all\n        select * from \"dbt\".\"test16873757723266827902_test_ephemeral\".\"double_dependent\" where gender = 'Male'\"\"\"\n\n    generated_sql = inject_ctes_into_sql(starting_sql, ctes)\n    assert norm_whitespace(generated_sql) == norm_whitespace(expected_sql)\n\n\ndef test_inject_ctes_starting_with1():\n    starting_sql = \"\"\"\n       with internal_cte as (select * from sessions)\n       select * from internal_cte\n    \"\"\"\n    ctes = [\n        InjectedCTE(\n            id=\"cte_id_1\",\n            sql=\"__dbt__cte__ephemeral as (select * from table)\",\n        ),\n        InjectedCTE(\n            id=\"cte_id_2\",\n            sql=\"__dbt__cte__events as (select id, type from events)\",\n        ),\n    ]\n    expected_sql = \"\"\"with __dbt__cte__ephemeral as (select * from table),\n       __dbt__cte__events as (select id, type from events),\n       internal_cte as (select * from sessions)\n       select * from internal_cte\"\"\"\n\n    generated_sql = inject_ctes_into_sql(starting_sql, ctes)\n    assert norm_whitespace(generated_sql) == norm_whitespace(expected_sql)\n\n\ndef test_inject_ctes_starting_with2():\n    starting_sql = \"\"\"with my_other_cool_cte as (\n        select id, name from __dbt__cte__ephemeral\n        where id > 1000\n    )\n    select name, id from my_other_cool_cte\"\"\"\n    ctes = [\n        InjectedCTE(\n            id=\"model.singular_tests_ephemeral.ephemeral\",\n            sql=' __dbt__cte__ephemeral as (\\n\\n\\nwith my_cool_cte as (\\n  select name, id from \"dbt\".\"test16873917221900185954_test_singular_tests_ephemeral\".\"base\"\\n)\\nselect id, name from my_cool_cte where id is not null\\n)',\n        )\n    ]\n    expected_sql = \"\"\"with  __dbt__cte__ephemeral as (\n        with my_cool_cte as (\n          select name, id from \"dbt\".\"test16873917221900185954_test_singular_tests_ephemeral\".\"base\"\n        )\n        select id, name from my_cool_cte where id is not null\n        ), my_other_cool_cte as (\n            select id, name from __dbt__cte__ephemeral\n            where id > 1000\n        )\n        select name, id from my_other_cool_cte\"\"\"\n\n    generated_sql = inject_ctes_into_sql(starting_sql, ctes)\n    assert norm_whitespace(generated_sql) == norm_whitespace(expected_sql)\n\n\ndef test_inject_ctes_comment_with():\n    # Test injection with a comment containing \"with\"\n    starting_sql = \"\"\"\n        --- This is sql with a comment\n        select * from __dbt__cte__base\n    \"\"\"\n    ctes = [\n        InjectedCTE(\n            id=\"model.test.base\",\n            sql=\" __dbt__cte__base as (\\n\\n\\nselect * from test16873767336887004702_test_ephemeral.seed\\n)\",\n        )\n    ]\n    expected_sql = \"\"\"with __dbt__cte__base as (\n        select * from test16873767336887004702_test_ephemeral.seed\n        ) --- This is sql with a comment\n        select * from __dbt__cte__base\"\"\"\n\n    generated_sql = inject_ctes_into_sql(starting_sql, ctes)\n    assert norm_whitespace(generated_sql) == norm_whitespace(expected_sql)\n\n\ndef test_inject_ctes_with_recursive():\n    # Test injection with \"recursive\" keyword\n    starting_sql = \"\"\"\n        with recursive t(n) as (\n            select * from __dbt__cte__first_ephemeral_model\n          union all\n            select n+1 from t where n < 100\n        )\n        select sum(n) from t\n    \"\"\"\n    ctes = [\n        InjectedCTE(\n            id=\"model.test.first_ephemeral_model\",\n            sql=\" __dbt__cte__first_ephemeral_model as (\\n\\nselect 1 as fun\\n)\",\n        )\n    ]\n    expected_sql = \"\"\"with recursive  __dbt__cte__first_ephemeral_model as (\n        select 1 as fun\n        ), t(n) as (\n            select * from __dbt__cte__first_ephemeral_model\n          union all\n            select n+1 from t where n < 100\n        )\n        select sum(n) from t\n    \"\"\"\n    generated_sql = inject_ctes_into_sql(starting_sql, ctes)\n    assert norm_whitespace(generated_sql) == norm_whitespace(expected_sql)\n"
  },
  {
    "path": "tests/unit/contracts/graph/test_nodes_parsed.py",
    "content": "import pickle\nfrom argparse import Namespace\nfrom dataclasses import replace\n\nimport pytest\nfrom hypothesis import given\nfrom hypothesis.strategies import builds, lists\n\nfrom dbt.artifacts.resources import (\n    ColumnInfo,\n    Dimension,\n    Entity,\n    ExposureConfig,\n    ExposureType,\n    FreshnessThreshold,\n    Hook,\n    MacroConfig,\n    MacroDependsOn,\n    MaturityType,\n    Measure,\n    MetricInputMeasure,\n    MetricTypeParams,\n    Owner,\n    Quoting,\n    RefArgs,\n    SourceConfig,\n)\nfrom dbt.artifacts.resources import SourceDefinition as SourceDefinitionResource\nfrom dbt.artifacts.resources import TestMetadata, Time\nfrom dbt.artifacts.resources.types import TimePeriod\nfrom dbt.contracts.files import FileHash\nfrom dbt.contracts.graph.model_config import (\n    ModelConfig,\n    NodeConfig,\n    SeedConfig,\n    SnapshotConfig,\n    TestConfig,\n)\nfrom dbt.contracts.graph.nodes import (\n    DependsOn,\n    Docs,\n    Documentation,\n    Exposure,\n    GenericTestNode,\n    HookNode,\n    Macro,\n    Metric,\n    ModelNode,\n    SeedNode,\n    SemanticModel,\n    SnapshotNode,\n    SourceDefinition,\n)\nfrom dbt.node_types import AccessType, NodeType\nfrom dbt_common.dataclass_schema import ValidationError\nfrom dbt_semantic_interfaces.type_enums import MetricType\nfrom tests.unit.utils import (\n    ContractTestCase,\n    assert_fails_validation,\n    assert_from_dict,\n    assert_symmetric,\n    compare_dicts,\n    dict_replace,\n    replace_config,\n)\n\n\n@pytest.fixture\ndef args_for_flags() -> Namespace:\n    return Namespace(\n        send_anonymous_usage_stats=False,\n        state_modified_compare_more_unrendered_values=False,\n        state_modified_compare_vars=False,\n    )\n\n\n@pytest.fixture\ndef populated_node_config_object():\n    result = ModelConfig(\n        column_types={\"a\": \"text\"},\n        materialized=\"table\",\n        post_hook=[Hook(sql='insert into blah(a, b) select \"1\", 1')],\n    )\n    result._extra[\"extra\"] = \"even more\"\n    return result\n\n\n@pytest.fixture\ndef populated_node_config_dict():\n    return {\n        \"column_types\": {\"a\": \"text\"},\n        \"enabled\": True,\n        \"materialized\": \"table\",\n        \"persist_docs\": {},\n        \"post-hook\": [{\"sql\": 'insert into blah(a, b) select \"1\", 1', \"transaction\": True}],\n        \"pre-hook\": [],\n        \"quoting\": {},\n        \"tags\": [],\n        \"extra\": \"even more\",\n        \"on_schema_change\": \"ignore\",\n        \"on_configuration_change\": \"apply\",\n        \"meta\": {},\n        \"grants\": {},\n        \"packages\": [],\n        \"docs\": {\"show\": True},\n        \"contract\": {\"enforced\": False, \"alias_types\": True},\n        \"access\": \"protected\",\n        \"lookback\": 1,\n    }\n\n\ndef test_config_populated(populated_node_config_object, populated_node_config_dict):\n    assert_symmetric(populated_node_config_object, populated_node_config_dict, ModelConfig)\n    pickle.loads(pickle.dumps(populated_node_config_object))\n\n\n@pytest.fixture\ndef unrendered_node_config_dict():\n    return {\n        \"column_types\": {\"a\": \"text\"},\n        \"materialized\": \"table\",\n        \"post_hook\": 'insert into blah(a, b) select \"1\", 1',\n    }\n\n\ndifferent_node_configs = [\n    lambda c: dict_replace(c, post_hook=[]),\n    lambda c: dict_replace(c, materialized=\"view\"),\n    lambda c: dict_replace(c, quoting={\"database\": True}),\n    lambda c: dict_replace(c, extra=\"different extra\"),\n    lambda c: dict_replace(c, column_types={\"a\": \"varchar(256)\"}),\n]\n\n\nsame_node_configs = [\n    lambda c: dict_replace(c, tags=[\"mytag\"]),\n    lambda c: dict_replace(c, alias=\"changed\"),\n    lambda c: dict_replace(c, schema=\"changed\"),\n    lambda c: dict_replace(c, database=\"changed\"),\n]\n\n\n@pytest.mark.parametrize(\"func\", different_node_configs)\ndef test_config_different(unrendered_node_config_dict, func):\n    value = func(unrendered_node_config_dict)\n    assert not ModelConfig.same_contents(unrendered_node_config_dict, value)\n\n\n@pytest.mark.parametrize(\"func\", same_node_configs)\ndef test_config_same(unrendered_node_config_dict, func):\n    value = func(unrendered_node_config_dict)\n    assert unrendered_node_config_dict != value\n    assert ModelConfig.same_contents(unrendered_node_config_dict, value)\n\n\n@pytest.fixture\ndef base_parsed_model_dict():\n    return {\n        \"name\": \"foo\",\n        \"created_at\": 1.0,\n        \"resource_type\": str(NodeType.Model),\n        \"path\": \"/root/x/path.sql\",\n        \"original_file_path\": \"/root/path.sql\",\n        \"package_name\": \"test\",\n        \"language\": \"sql\",\n        \"raw_code\": \"select * from wherever\",\n        \"unique_id\": \"model.test.foo\",\n        \"fqn\": [\"test\", \"models\", \"foo\"],\n        \"refs\": [],\n        \"sources\": [],\n        \"metrics\": [],\n        \"functions\": [],\n        \"depends_on\": {\"macros\": [], \"nodes\": []},\n        \"database\": \"test_db\",\n        \"description\": \"\",\n        \"primary_key\": [],\n        \"schema\": \"test_schema\",\n        \"alias\": \"bar\",\n        \"tags\": [],\n        \"config\": {\n            \"column_types\": {},\n            \"enabled\": True,\n            \"materialized\": \"view\",\n            \"persist_docs\": {},\n            \"post-hook\": [],\n            \"pre-hook\": [],\n            \"quoting\": {},\n            \"tags\": [],\n            \"on_schema_change\": \"ignore\",\n            \"on_configuration_change\": \"apply\",\n            \"meta\": {},\n            \"grants\": {},\n            \"docs\": {\"show\": True},\n            \"contract\": {\"enforced\": False, \"alias_types\": True},\n            \"packages\": [],\n            \"access\": \"protected\",\n            \"lookback\": 1,\n        },\n        \"docs\": {\"show\": True},\n        \"contract\": {\"enforced\": False, \"alias_types\": True},\n        \"columns\": {},\n        \"meta\": {},\n        \"checksum\": {\n            \"name\": \"sha256\",\n            \"checksum\": \"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\",\n        },\n        \"unrendered_config\": {},\n        \"unrendered_config_call_dict\": {},\n        \"config_call_dict\": {},\n        \"access\": AccessType.Protected.value,\n        \"constraints\": [],\n        \"doc_blocks\": [],\n    }\n\n\n@pytest.fixture\ndef basic_parsed_model_object():\n    return ModelNode(\n        package_name=\"test\",\n        path=\"/root/x/path.sql\",\n        original_file_path=\"/root/path.sql\",\n        language=\"sql\",\n        raw_code=\"select * from wherever\",\n        name=\"foo\",\n        resource_type=NodeType.Model,\n        unique_id=\"model.test.foo\",\n        fqn=[\"test\", \"models\", \"foo\"],\n        refs=[],\n        sources=[],\n        metrics=[],\n        depends_on=DependsOn(),\n        description=\"\",\n        primary_key=[],\n        database=\"test_db\",\n        schema=\"test_schema\",\n        alias=\"bar\",\n        tags=[],\n        config=ModelConfig(),\n        meta={},\n        checksum=FileHash.from_contents(\"\"),\n        created_at=1.0,\n    )\n\n\n@pytest.fixture\ndef minimal_parsed_model_dict():\n    return {\n        \"name\": \"foo\",\n        \"created_at\": 1.0,\n        \"resource_type\": str(NodeType.Model),\n        \"path\": \"/root/x/path.sql\",\n        \"original_file_path\": \"/root/path.sql\",\n        \"package_name\": \"test\",\n        \"language\": \"sql\",\n        \"raw_code\": \"select * from wherever\",\n        \"unique_id\": \"model.test.foo\",\n        \"fqn\": [\"test\", \"models\", \"foo\"],\n        \"database\": \"test_db\",\n        \"schema\": \"test_schema\",\n        \"alias\": \"bar\",\n        \"checksum\": {\n            \"name\": \"sha256\",\n            \"checksum\": \"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\",\n        },\n        \"unrendered_config\": {},\n    }\n\n\n@pytest.fixture\ndef complex_parsed_model_dict():\n    return {\n        \"name\": \"foo\",\n        \"created_at\": 1.0,\n        \"resource_type\": str(NodeType.Model),\n        \"path\": \"/root/x/path.sql\",\n        \"original_file_path\": \"/root/path.sql\",\n        \"package_name\": \"test\",\n        \"language\": \"sql\",\n        \"raw_code\": 'select * from {{ ref(\"bar\") }}',\n        \"unique_id\": \"model.test.foo\",\n        \"fqn\": [\"test\", \"models\", \"foo\"],\n        \"refs\": [],\n        \"sources\": [],\n        \"metrics\": [],\n        \"functions\": [],\n        \"depends_on\": {\"macros\": [], \"nodes\": [\"model.test.bar\"]},\n        \"database\": \"test_db\",\n        \"description\": \"My parsed node\",\n        \"primary_key\": [],\n        \"schema\": \"test_schema\",\n        \"alias\": \"bar\",\n        \"tags\": [\"tag\"],\n        \"meta\": {},\n        \"config\": {\n            \"column_types\": {\"a\": \"text\"},\n            \"enabled\": True,\n            \"materialized\": \"ephemeral\",\n            \"persist_docs\": {},\n            \"post-hook\": [{\"sql\": 'insert into blah(a, b) select \"1\", 1', \"transaction\": True}],\n            \"pre-hook\": [],\n            \"quoting\": {},\n            \"tags\": [],\n            \"on_schema_change\": \"ignore\",\n            \"on_configuration_change\": \"apply\",\n            \"meta\": {},\n            \"grants\": {},\n            \"docs\": {\"show\": True},\n            \"contract\": {\"enforced\": False, \"alias_types\": True},\n            \"packages\": [],\n            \"access\": \"protected\",\n            \"lookback\": 1,\n        },\n        \"docs\": {\"show\": True},\n        \"contract\": {\"enforced\": False, \"alias_types\": True},\n        \"columns\": {\n            \"a\": {\n                \"name\": \"a\",\n                \"description\": \"a text field\",\n                \"meta\": {},\n                \"tags\": [],\n                \"constraints\": [],\n                \"doc_blocks\": [],\n                \"config\": {\"meta\": {}, \"tags\": []},\n            },\n        },\n        \"checksum\": {\n            \"name\": \"sha256\",\n            \"checksum\": \"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\",\n        },\n        \"unrendered_config\": {\n            \"column_types\": {\"a\": \"text\"},\n            \"materialized\": \"ephemeral\",\n            \"post_hook\": ['insert into blah(a, b) select \"1\", 1'],\n        },\n        \"unrendered_config_call_dict\": {},\n        \"config_call_dict\": {},\n        \"access\": AccessType.Protected.value,\n        \"constraints\": [],\n        \"doc_blocks\": [],\n    }\n\n\n@pytest.fixture\ndef complex_parsed_model_object():\n    return ModelNode(\n        package_name=\"test\",\n        path=\"/root/x/path.sql\",\n        original_file_path=\"/root/path.sql\",\n        language=\"sql\",\n        raw_code='select * from {{ ref(\"bar\") }}',\n        name=\"foo\",\n        resource_type=NodeType.Model,\n        unique_id=\"model.test.foo\",\n        fqn=[\"test\", \"models\", \"foo\"],\n        refs=[],\n        sources=[],\n        metrics=[],\n        depends_on=DependsOn(nodes=[\"model.test.bar\"]),\n        description=\"My parsed node\",\n        database=\"test_db\",\n        schema=\"test_schema\",\n        alias=\"bar\",\n        tags=[\"tag\"],\n        meta={},\n        config=ModelConfig(\n            column_types={\"a\": \"text\"},\n            materialized=\"ephemeral\",\n            post_hook=[Hook(sql='insert into blah(a, b) select \"1\", 1')],\n        ),\n        columns={\"a\": ColumnInfo(\"a\", \"a text field\", {})},\n        checksum=FileHash.from_contents(\"\"),\n        unrendered_config={\n            \"column_types\": {\"a\": \"text\"},\n            \"materialized\": \"ephemeral\",\n            \"post_hook\": ['insert into blah(a, b) select \"1\", 1'],\n        },\n    )\n\n\ndef test_model_basic(basic_parsed_model_object, base_parsed_model_dict, minimal_parsed_model_dict):\n    node = basic_parsed_model_object\n    node_dict = base_parsed_model_dict\n    compare_dicts(node.to_dict(), node_dict)\n    assert_symmetric(node, node_dict)\n    assert node.empty is False\n    assert node.is_refable is True\n    assert node.is_ephemeral is False\n\n    minimum = minimal_parsed_model_dict\n    assert_from_dict(node, minimum)\n    pickle.loads(pickle.dumps(node))\n\n\ndef test_model_complex(complex_parsed_model_object, complex_parsed_model_dict):\n    node = complex_parsed_model_object\n    node_dict = complex_parsed_model_dict\n    assert_symmetric(node, node_dict)\n    assert node.empty is False\n    assert node.is_refable is True\n    assert node.is_ephemeral is True\n\n\ndef test_invalid_bad_tags(base_parsed_model_dict):\n    # bad top-level field\n    bad_tags = base_parsed_model_dict\n    bad_tags[\"tags\"] = 100\n    assert_fails_validation(bad_tags, ModelNode)\n\n\ndef test_invalid_bad_materialized(base_parsed_model_dict):\n    # bad nested field\n    bad_materialized = base_parsed_model_dict\n    bad_materialized[\"config\"][\"materialized\"] = None\n    assert_fails_validation(bad_materialized, ModelNode)\n\n\nunchanged_nodes = [\n    lambda u: (u, replace(u, tags=[\"mytag\"])),\n    lambda u: (u, replace(u, meta={\"something\": 1000})),\n    # True -> True\n    lambda u: (\n        replace_config(u, persist_docs={\"relation\": True}),\n        replace_config(u, persist_docs={\"relation\": True}),\n    ),\n    lambda u: (\n        replace_config(u, persist_docs={\"columns\": True}),\n        replace_config(u, persist_docs={\"columns\": True}),\n    ),\n    # only columns docs enabled, but description changed\n    lambda u: (\n        replace_config(u, persist_docs={\"columns\": True}),\n        replace(\n            replace_config(u, persist_docs={\"columns\": True}), description=\"a model description\"\n        ),\n    ),\n    # only relation docs eanbled, but columns changed\n    lambda u: (\n        replace_config(u, persist_docs={\"relation\": True}),\n        replace(\n            replace_config(u, persist_docs={\"relation\": True}),\n            columns={\"a\": ColumnInfo(name=\"a\", description=\"a column description\")},\n        ),\n    ),\n    # not tracked, we track config.alias/config.schema/config.database\n    lambda u: (u, replace(u, alias=\"other\")),\n    lambda u: (u, replace(u, schema=\"other\")),\n    lambda u: (u, replace(u, database=\"other\")),\n    # unchanged ref representations - protected is default\n    lambda u: (u, replace(u, access=AccessType.Protected)),\n]\n\n\nchanged_nodes = [\n    lambda u: (\n        u,\n        replace(\n            u,\n            fqn=[\"test\", \"models\", \"subdir\", \"foo\"],\n            original_file_path=\"models/subdir/foo.sql\",\n            path=\"/root/models/subdir/foo.sql\",\n        ),\n    ),\n    # None -> False is a config change even though it's pretty much the same\n    lambda u: (u, replace_config(u, persist_docs={\"relation\": False})),\n    lambda u: (u, replace_config(u, persist_docs={\"columns\": False})),\n    # persist docs was true for the relation and we changed the model description\n    lambda u: (\n        replace_config(u, persist_docs={\"relation\": True}),\n        replace(\n            replace_config(u, persist_docs={\"relation\": True}), description=\"a model description\"\n        ),\n    ),\n    # persist docs was true for columns and we changed the model description\n    lambda u: (\n        replace_config(u, persist_docs={\"columns\": True}),\n        replace(\n            replace_config(u, persist_docs={\"columns\": True}),\n            columns={\"a\": ColumnInfo(name=\"a\", description=\"a column description\")},\n        ),\n    ),\n    # not tracked, we track config.alias/config.schema/config.database\n    lambda u: (u, replace_config(u, alias=\"other\")),\n    lambda u: (u, replace_config(u, schema=\"other\")),\n    lambda u: (u, replace_config(u, database=\"other\")),\n    # changed ref representations\n    lambda u: (u, replace_config(u, access=AccessType.Public)),\n    lambda u: (u, replace_config(u, latest_version=2)),\n    lambda u: (u, replace_config(u, version=2)),\n]\n\n\n@pytest.mark.parametrize(\"func\", unchanged_nodes)\ndef test_compare_unchanged_parsed_model(func, basic_parsed_model_object):\n    node, compare = func(basic_parsed_model_object)\n    assert node.same_contents(compare, \"postgres\")\n\n\n@pytest.mark.parametrize(\"func\", changed_nodes)\ndef test_compare_changed_model(func, basic_parsed_model_object):\n    node, compare = func(basic_parsed_model_object)\n    assert not node.same_contents(compare, \"postgres\")\n\n\n@pytest.fixture\ndef basic_parsed_seed_dict():\n    return {\n        \"name\": \"foo\",\n        \"created_at\": 1.0,\n        \"resource_type\": str(NodeType.Seed),\n        \"path\": \"/root/seeds/seed.csv\",\n        \"original_file_path\": \"seeds/seed.csv\",\n        \"package_name\": \"test\",\n        \"raw_code\": \"\",\n        \"unique_id\": \"seed.test.foo\",\n        \"fqn\": [\"test\", \"seeds\", \"foo\"],\n        \"database\": \"test_db\",\n        \"depends_on\": {\"macros\": []},\n        \"description\": \"\",\n        \"schema\": \"test_schema\",\n        \"tags\": [],\n        \"alias\": \"foo\",\n        \"config\": {\n            \"column_types\": {},\n            \"delimiter\": \",\",\n            \"enabled\": True,\n            \"materialized\": \"seed\",\n            \"persist_docs\": {},\n            \"post-hook\": [],\n            \"pre-hook\": [],\n            \"quoting\": {},\n            \"tags\": [],\n            \"on_schema_change\": \"ignore\",\n            \"on_configuration_change\": \"apply\",\n            \"meta\": {},\n            \"grants\": {},\n            \"docs\": {\"show\": True},\n            \"contract\": {\"enforced\": False, \"alias_types\": True},\n            \"packages\": [],\n            \"lookback\": 1,\n        },\n        \"docs\": {\"show\": True},\n        \"columns\": {},\n        \"meta\": {},\n        \"checksum\": {\"name\": \"path\", \"checksum\": \"seeds/seed.csv\"},\n        \"unrendered_config\": {},\n        \"unrendered_config_call_dict\": {},\n        \"config_call_dict\": {},\n        \"doc_blocks\": [],\n    }\n\n\n@pytest.fixture\ndef basic_parsed_seed_object():\n    return SeedNode(\n        name=\"foo\",\n        resource_type=NodeType.Seed,\n        path=\"/root/seeds/seed.csv\",\n        original_file_path=\"seeds/seed.csv\",\n        package_name=\"test\",\n        raw_code=\"\",\n        unique_id=\"seed.test.foo\",\n        fqn=[\"test\", \"seeds\", \"foo\"],\n        database=\"test_db\",\n        description=\"\",\n        schema=\"test_schema\",\n        tags=[],\n        alias=\"foo\",\n        config=SeedConfig(),\n        # config=SeedConfig(quote_columns=True),\n        docs=Docs(show=True),\n        columns={},\n        meta={},\n        checksum=FileHash(name=\"path\", checksum=\"seeds/seed.csv\"),\n        unrendered_config={},\n    )\n\n\n@pytest.fixture\ndef minimal_parsed_seed_dict():\n    return {\n        \"name\": \"foo\",\n        \"created_at\": 1.0,\n        \"resource_type\": str(NodeType.Seed),\n        \"path\": \"/root/seeds/seed.csv\",\n        \"original_file_path\": \"seeds/seed.csv\",\n        \"package_name\": \"test\",\n        \"raw_code\": \"\",\n        \"unique_id\": \"seed.test.foo\",\n        \"fqn\": [\"test\", \"seeds\", \"foo\"],\n        \"database\": \"test_db\",\n        \"schema\": \"test_schema\",\n        \"alias\": \"foo\",\n        \"checksum\": {\"name\": \"path\", \"checksum\": \"seeds/seed.csv\"},\n    }\n\n\n@pytest.fixture\ndef complex_parsed_seed_dict():\n    return {\n        \"name\": \"foo\",\n        \"created_at\": 1.0,\n        \"resource_type\": str(NodeType.Seed),\n        \"path\": \"/root/seeds/seed.csv\",\n        \"original_file_path\": \"seeds/seed.csv\",\n        \"package_name\": \"test\",\n        \"raw_code\": \"\",\n        \"unique_id\": \"seed.test.foo\",\n        \"fqn\": [\"test\", \"seeds\", \"foo\"],\n        \"database\": \"test_db\",\n        \"depends_on\": {\"macros\": []},\n        \"description\": \"a description\",\n        \"schema\": \"test_schema\",\n        \"tags\": [\"mytag\"],\n        \"alias\": \"foo\",\n        \"config\": {\n            \"column_types\": {},\n            \"delimiter\": \",\",\n            \"enabled\": True,\n            \"materialized\": \"seed\",\n            \"persist_docs\": {\"relation\": True, \"columns\": True},\n            \"post-hook\": [],\n            \"pre-hook\": [],\n            \"quoting\": {},\n            \"tags\": [],\n            \"quote_columns\": True,\n            \"on_schema_change\": \"ignore\",\n            \"on_configuration_change\": \"apply\",\n            \"meta\": {},\n            \"grants\": {},\n            \"docs\": {\"show\": True},\n            \"contract\": {\"enforced\": False, \"alias_types\": True},\n            \"packages\": [],\n            \"lookback\": 1,\n        },\n        \"docs\": {\"show\": True},\n        \"columns\": {\n            \"a\": {\n                \"name\": \"a\",\n                \"description\": \"a column description\",\n                \"meta\": {},\n                \"tags\": [],\n                \"constraints\": [],\n                \"doc_blocks\": [],\n                \"config\": {\"meta\": {}, \"tags\": []},\n            }\n        },\n        \"meta\": {\"foo\": 1000},\n        \"checksum\": {\n            \"name\": \"sha256\",\n            \"checksum\": \"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\",\n        },\n        \"unrendered_config\": {\n            \"persist_docs\": {\"relation\": True, \"columns\": True},\n        },\n        \"unrendered_config_call_dict\": {},\n        \"config_call_dict\": {},\n        \"doc_blocks\": [],\n    }\n\n\n@pytest.fixture\ndef complex_parsed_seed_object():\n    return SeedNode(\n        name=\"foo\",\n        resource_type=NodeType.Seed,\n        path=\"/root/seeds/seed.csv\",\n        original_file_path=\"seeds/seed.csv\",\n        package_name=\"test\",\n        raw_code=\"\",\n        unique_id=\"seed.test.foo\",\n        fqn=[\"test\", \"seeds\", \"foo\"],\n        database=\"test_db\",\n        depends_on=MacroDependsOn(),\n        description=\"a description\",\n        schema=\"test_schema\",\n        tags=[\"mytag\"],\n        alias=\"foo\",\n        config=SeedConfig(\n            quote_columns=True,\n            delimiter=\",\",\n            persist_docs={\"relation\": True, \"columns\": True},\n        ),\n        docs=Docs(show=True),\n        columns={\"a\": ColumnInfo(name=\"a\", description=\"a column description\")},\n        meta={\"foo\": 1000},\n        checksum=FileHash.from_contents(\"\"),\n        unrendered_config={\n            \"persist_docs\": {\"relation\": True, \"columns\": True},\n        },\n    )\n\n\ndef test_seed_basic(basic_parsed_seed_dict, basic_parsed_seed_object, minimal_parsed_seed_dict):\n    assert_symmetric(basic_parsed_seed_object, basic_parsed_seed_dict)\n\n    assert basic_parsed_seed_object.get_materialization() == \"seed\"\n\n    assert_from_dict(basic_parsed_seed_object, minimal_parsed_seed_dict, SeedNode)\n\n\ndef test_seed_complex(complex_parsed_seed_dict, complex_parsed_seed_object):\n    assert_symmetric(complex_parsed_seed_object, complex_parsed_seed_dict)\n    assert complex_parsed_seed_object.get_materialization() == \"seed\"\n\n\nunchanged_seeds = [\n    lambda u: (u, replace(u, tags=[\"mytag\"])),\n    lambda u: (u, replace(u, meta={\"something\": 1000})),\n    # True -> True\n    lambda u: (\n        replace_config(u, persist_docs={\"relation\": True}),\n        replace_config(u, persist_docs={\"relation\": True}),\n    ),\n    lambda u: (\n        replace_config(u, persist_docs={\"columns\": True}),\n        replace_config(u, persist_docs={\"columns\": True}),\n    ),\n    # only columns docs enabled, but description changed\n    lambda u: (\n        replace_config(u, persist_docs={\"columns\": True}),\n        replace(\n            replace_config(u, persist_docs={\"columns\": True}), description=\"a model description\"\n        ),\n    ),\n    # only relation docs eanbled, but columns changed\n    lambda u: (\n        replace_config(u, persist_docs={\"relation\": True}),\n        replace(\n            replace_config(u, persist_docs={\"relation\": True}),\n            columns={\"a\": ColumnInfo(name=\"a\", description=\"a column description\")},\n        ),\n    ),\n    lambda u: (u, replace(u, alias=\"other\")),\n    lambda u: (u, replace(u, schema=\"other\")),\n    lambda u: (u, replace(u, database=\"other\")),\n]\n\n\nchanged_seeds = [\n    lambda u: (\n        u,\n        replace(\n            u,\n            fqn=[\"test\", \"models\", \"subdir\", \"foo\"],\n            original_file_path=\"models/subdir/foo.sql\",\n            path=\"/root/models/subdir/foo.sql\",\n        ),\n    ),\n    # None -> False is a config change even though it's pretty much the same\n    lambda u: (u, replace_config(u, persist_docs={\"relation\": False})),\n    lambda u: (u, replace_config(u, persist_docs={\"columns\": False})),\n    # persist docs was true for the relation and we changed the model description\n    lambda u: (\n        replace_config(u, persist_docs={\"relation\": True}),\n        replace(\n            replace_config(u, persist_docs={\"relation\": True}), description=\"a model description\"\n        ),\n    ),\n    # persist docs was true for columns and we changed the model description\n    lambda u: (\n        replace_config(u, persist_docs={\"columns\": True}),\n        replace(\n            replace_config(u, persist_docs={\"columns\": True}),\n            columns={\"a\": ColumnInfo(name=\"a\", description=\"a column description\")},\n        ),\n    ),\n    lambda u: (u, replace_config(u, alias=\"other\")),\n    lambda u: (u, replace_config(u, schema=\"other\")),\n    lambda u: (u, replace_config(u, database=\"other\")),\n]\n\n\n@pytest.mark.parametrize(\"func\", unchanged_seeds)\ndef test_compare_unchanged_parsed_seed(func, basic_parsed_seed_object):\n    node, compare = func(basic_parsed_seed_object)\n    assert node.same_contents(compare, \"postgres\")\n\n\n@pytest.mark.parametrize(\"func\", changed_seeds)\ndef test_compare_changed_seed(func, basic_parsed_seed_object):\n    node, compare = func(basic_parsed_seed_object)\n    assert not node.same_contents(compare, \"postgres\")\n\n\n@pytest.fixture\ndef minimal_parsed_hook_dict():\n    return {\n        \"name\": \"foo\",\n        \"resource_type\": str(NodeType.Operation),\n        \"path\": \"/root/x/path.sql\",\n        \"original_file_path\": \"/root/path.sql\",\n        \"package_name\": \"test\",\n        \"language\": \"sql\",\n        \"raw_code\": \"select * from wherever\",\n        \"unique_id\": \"model.test.foo\",\n        \"fqn\": [\"test\", \"models\", \"foo\"],\n        \"database\": \"test_db\",\n        \"schema\": \"test_schema\",\n        \"alias\": \"bar\",\n        \"checksum\": {\n            \"name\": \"sha256\",\n            \"checksum\": \"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\",\n        },\n    }\n\n\n@pytest.fixture\ndef base_parsed_hook_dict():\n    return {\n        \"name\": \"foo\",\n        \"created_at\": 1.0,\n        \"resource_type\": str(NodeType.Operation),\n        \"path\": \"/root/x/path.sql\",\n        \"original_file_path\": \"/root/path.sql\",\n        \"package_name\": \"test\",\n        \"language\": \"sql\",\n        \"raw_code\": \"select * from wherever\",\n        \"unique_id\": \"model.test.foo\",\n        \"fqn\": [\"test\", \"models\", \"foo\"],\n        \"refs\": [],\n        \"sources\": [],\n        \"metrics\": [],\n        \"functions\": [],\n        \"depends_on\": {\"macros\": [], \"nodes\": []},\n        \"database\": \"test_db\",\n        \"description\": \"\",\n        \"schema\": \"test_schema\",\n        \"alias\": \"bar\",\n        \"tags\": [],\n        \"config\": {\n            \"column_types\": {},\n            \"enabled\": True,\n            \"materialized\": \"view\",\n            \"persist_docs\": {},\n            \"post-hook\": [],\n            \"pre-hook\": [],\n            \"quoting\": {},\n            \"tags\": [],\n            \"on_schema_change\": \"ignore\",\n            \"on_configuration_change\": \"apply\",\n            \"meta\": {},\n            \"grants\": {},\n            \"docs\": {\"show\": True},\n            \"contract\": {\"enforced\": False, \"alias_types\": True},\n            \"packages\": [],\n            \"lookback\": 1,\n        },\n        \"docs\": {\"show\": True},\n        \"contract\": {\"enforced\": False, \"alias_types\": True},\n        \"columns\": {},\n        \"meta\": {},\n        \"checksum\": {\n            \"name\": \"sha256\",\n            \"checksum\": \"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\",\n        },\n        \"unrendered_config\": {},\n        \"unrendered_config_call_dict\": {},\n        \"config_call_dict\": {},\n        \"doc_blocks\": [],\n    }\n\n\n@pytest.fixture\ndef base_parsed_hook_object():\n    return HookNode(\n        package_name=\"test\",\n        path=\"/root/x/path.sql\",\n        original_file_path=\"/root/path.sql\",\n        language=\"sql\",\n        raw_code=\"select * from wherever\",\n        name=\"foo\",\n        resource_type=NodeType.Operation,\n        unique_id=\"model.test.foo\",\n        fqn=[\"test\", \"models\", \"foo\"],\n        refs=[],\n        sources=[],\n        metrics=[],\n        depends_on=DependsOn(),\n        description=\"\",\n        database=\"test_db\",\n        schema=\"test_schema\",\n        alias=\"bar\",\n        tags=[],\n        config=NodeConfig(),\n        index=None,\n        checksum=FileHash.from_contents(\"\"),\n        unrendered_config={},\n    )\n\n\n@pytest.fixture\ndef complex_parsed_hook_dict():\n    return {\n        \"name\": \"foo\",\n        \"created_at\": 1.0,\n        \"resource_type\": str(NodeType.Operation),\n        \"path\": \"/root/x/path.sql\",\n        \"original_file_path\": \"/root/path.sql\",\n        \"package_name\": \"test\",\n        \"language\": \"sql\",\n        \"raw_code\": 'select * from {{ ref(\"bar\") }}',\n        \"unique_id\": \"model.test.foo\",\n        \"fqn\": [\"test\", \"models\", \"foo\"],\n        \"refs\": [],\n        \"sources\": [],\n        \"metrics\": [],\n        \"functions\": [],\n        \"depends_on\": {\"macros\": [], \"nodes\": [\"model.test.bar\"]},\n        \"database\": \"test_db\",\n        \"description\": \"My parsed node\",\n        \"schema\": \"test_schema\",\n        \"alias\": \"bar\",\n        \"tags\": [\"tag\"],\n        \"meta\": {},\n        \"config\": {\n            \"column_types\": {\"a\": \"text\"},\n            \"enabled\": True,\n            \"materialized\": \"table\",\n            \"persist_docs\": {},\n            \"post-hook\": [],\n            \"pre-hook\": [],\n            \"quoting\": {},\n            \"tags\": [],\n            \"on_schema_change\": \"ignore\",\n            \"on_configuration_change\": \"apply\",\n            \"meta\": {},\n            \"grants\": {},\n            \"docs\": {\"show\": True},\n            \"contract\": {\"enforced\": False, \"alias_types\": True},\n            \"packages\": [],\n            \"lookback\": 1,\n        },\n        \"docs\": {\"show\": True},\n        \"contract\": {\"enforced\": False, \"alias_types\": True},\n        \"columns\": {\n            \"a\": {\n                \"name\": \"a\",\n                \"description\": \"a text field\",\n                \"meta\": {},\n                \"tags\": [],\n                \"constraints\": [],\n                \"doc_blocks\": [],\n                \"config\": {\n                    \"meta\": {},\n                    \"tags\": [],\n                },\n            },\n        },\n        \"index\": 13,\n        \"checksum\": {\n            \"name\": \"sha256\",\n            \"checksum\": \"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\",\n        },\n        \"unrendered_config\": {\n            \"column_types\": {\"a\": \"text\"},\n            \"materialized\": \"table\",\n        },\n        \"unrendered_config_call_dict\": {},\n        \"config_call_dict\": {},\n        \"doc_blocks\": [],\n    }\n\n\n@pytest.fixture\ndef complex_parsed_hook_object():\n    return HookNode(\n        package_name=\"test\",\n        path=\"/root/x/path.sql\",\n        original_file_path=\"/root/path.sql\",\n        language=\"sql\",\n        raw_code='select * from {{ ref(\"bar\") }}',\n        name=\"foo\",\n        resource_type=NodeType.Operation,\n        unique_id=\"model.test.foo\",\n        fqn=[\"test\", \"models\", \"foo\"],\n        refs=[],\n        sources=[],\n        metrics=[],\n        depends_on=DependsOn(nodes=[\"model.test.bar\"]),\n        description=\"My parsed node\",\n        database=\"test_db\",\n        schema=\"test_schema\",\n        alias=\"bar\",\n        tags=[\"tag\"],\n        meta={},\n        config=NodeConfig(column_types={\"a\": \"text\"}, materialized=\"table\", post_hook=[]),\n        columns={\"a\": ColumnInfo(\"a\", \"a text field\", {})},\n        index=13,\n        checksum=FileHash.from_contents(\"\"),\n        unrendered_config={\n            \"column_types\": {\"a\": \"text\"},\n            \"materialized\": \"table\",\n        },\n    )\n\n\ndef test_basic_parsed_hook(\n    minimal_parsed_hook_dict, base_parsed_hook_dict, base_parsed_hook_object\n):\n    node = base_parsed_hook_object\n    node_dict = base_parsed_hook_dict\n    minimum = minimal_parsed_hook_dict\n\n    assert_symmetric(node, node_dict, HookNode)\n    assert node.empty is False\n    assert node.is_refable is False\n    assert node.get_materialization() == \"view\"\n    assert_from_dict(node, minimum, HookNode)\n    pickle.loads(pickle.dumps(node))\n\n\ndef test_complex_parsed_hook(complex_parsed_hook_dict, complex_parsed_hook_object):\n    node = complex_parsed_hook_object\n    node_dict = complex_parsed_hook_dict\n    # what's different?\n    assert_symmetric(node, node_dict)\n    assert node.empty is False\n    assert node.is_refable is False\n    assert node.get_materialization() == \"table\"\n\n\ndef test_invalid_hook_index_type(base_parsed_hook_dict):\n    bad_index = base_parsed_hook_dict\n    bad_index[\"index\"] = \"a string!?\"\n    assert_fails_validation(bad_index, HookNode)\n\n\n@pytest.fixture\ndef minimal_parsed_schema_test_dict():\n    return {\n        \"name\": \"foo\",\n        \"created_at\": 1.0,\n        \"resource_type\": str(NodeType.Test),\n        \"path\": \"/root/x/path.sql\",\n        \"original_file_path\": \"/root/path.sql\",\n        \"package_name\": \"test\",\n        \"language\": \"sql\",\n        \"raw_code\": \"select * from wherever\",\n        \"unique_id\": \"test.test.foo\",\n        \"fqn\": [\"test\", \"models\", \"foo\"],\n        \"database\": \"test_db\",\n        \"schema\": \"test_schema\",\n        \"alias\": \"bar\",\n        \"meta\": {},\n        \"test_metadata\": {\n            \"name\": \"foo\",\n            \"kwargs\": {},\n        },\n        \"checksum\": {\n            \"name\": \"sha256\",\n            \"checksum\": \"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\",\n        },\n        \"unrendered_config_call_dict\": {},\n        \"config_call_dict\": {},\n    }\n\n\n@pytest.fixture\ndef basic_parsed_schema_test_dict():\n    return {\n        \"name\": \"foo\",\n        \"created_at\": 1.0,\n        \"resource_type\": str(NodeType.Test),\n        \"path\": \"/root/x/path.sql\",\n        \"original_file_path\": \"/root/path.sql\",\n        \"package_name\": \"test\",\n        \"language\": \"sql\",\n        \"raw_code\": \"select * from wherever\",\n        \"unique_id\": \"test.test.foo\",\n        \"fqn\": [\"test\", \"models\", \"foo\"],\n        \"refs\": [],\n        \"sources\": [],\n        \"metrics\": [],\n        \"functions\": [],\n        \"depends_on\": {\"macros\": [], \"nodes\": []},\n        \"database\": \"test_db\",\n        \"description\": \"\",\n        \"schema\": \"test_schema\",\n        \"alias\": \"bar\",\n        \"tags\": [],\n        \"meta\": {},\n        \"config\": {\n            \"enabled\": True,\n            \"materialized\": \"test\",\n            \"tags\": [],\n            \"severity\": \"ERROR\",\n            \"warn_if\": \"!= 0\",\n            \"error_if\": \"!= 0\",\n            \"fail_calc\": \"count(*)\",\n            \"meta\": {},\n            \"schema\": \"dbt_test__audit\",\n        },\n        \"docs\": {\"show\": True},\n        \"contract\": {\"enforced\": False, \"alias_types\": True},\n        \"columns\": {},\n        \"test_metadata\": {\n            \"name\": \"foo\",\n            \"kwargs\": {},\n        },\n        \"checksum\": {\n            \"name\": \"sha256\",\n            \"checksum\": \"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\",\n        },\n        \"unrendered_config\": {},\n        \"unrendered_config_call_dict\": {},\n        \"config_call_dict\": {},\n        \"doc_blocks\": [],\n    }\n\n\n@pytest.fixture\ndef basic_parsed_schema_test_object():\n    return GenericTestNode(\n        package_name=\"test\",\n        path=\"/root/x/path.sql\",\n        original_file_path=\"/root/path.sql\",\n        language=\"sql\",\n        raw_code=\"select * from wherever\",\n        name=\"foo\",\n        resource_type=NodeType.Test,\n        unique_id=\"test.test.foo\",\n        fqn=[\"test\", \"models\", \"foo\"],\n        refs=[],\n        sources=[],\n        metrics=[],\n        depends_on=DependsOn(),\n        description=\"\",\n        database=\"test_db\",\n        schema=\"test_schema\",\n        alias=\"bar\",\n        tags=[],\n        meta={},\n        config=TestConfig(),\n        test_metadata=TestMetadata(namespace=None, name=\"foo\", kwargs={}),\n        checksum=FileHash.from_contents(\"\"),\n    )\n\n\n@pytest.fixture\ndef complex_parsed_schema_test_dict():\n    return {\n        \"name\": \"foo\",\n        \"created_at\": 1.0,\n        \"resource_type\": str(NodeType.Test),\n        \"path\": \"/root/x/path.sql\",\n        \"original_file_path\": \"/root/path.sql\",\n        \"package_name\": \"test\",\n        \"language\": \"sql\",\n        \"raw_code\": 'select * from {{ ref(\"bar\") }}',\n        \"unique_id\": \"test.test.foo\",\n        \"fqn\": [\"test\", \"models\", \"foo\"],\n        \"refs\": [],\n        \"sources\": [],\n        \"metrics\": [],\n        \"functions\": [],\n        \"depends_on\": {\"macros\": [], \"nodes\": [\"model.test.bar\"]},\n        \"database\": \"test_db\",\n        \"description\": \"My parsed node\",\n        \"schema\": \"test_schema\",\n        \"alias\": \"bar\",\n        \"tags\": [\"tag\"],\n        \"meta\": {},\n        \"config\": {\n            \"enabled\": True,\n            \"materialized\": \"table\",\n            \"tags\": [],\n            \"severity\": \"WARN\",\n            \"warn_if\": \"!= 0\",\n            \"error_if\": \"!= 0\",\n            \"fail_calc\": \"count(*)\",\n            \"extra_key\": \"extra value\",\n            \"meta\": {},\n            \"schema\": \"dbt_test__audit\",\n        },\n        \"docs\": {\"show\": False},\n        \"contract\": {\"enforced\": False, \"alias_types\": True},\n        \"columns\": {\n            \"a\": {\n                \"name\": \"a\",\n                \"description\": \"a text field\",\n                \"meta\": {},\n                \"tags\": [],\n                \"constraints\": [],\n                \"doc_blocks\": [],\n                \"config\": {\"meta\": {}, \"tags\": []},\n            },\n        },\n        \"column_name\": \"id\",\n        \"test_metadata\": {\n            \"name\": \"foo\",\n            \"kwargs\": {},\n        },\n        \"checksum\": {\n            \"name\": \"sha256\",\n            \"checksum\": \"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\",\n        },\n        \"unrendered_config\": {\"materialized\": \"table\", \"severity\": \"WARN\"},\n        \"unrendered_config_call_dict\": {},\n        \"config_call_dict\": {},\n        \"doc_blocks\": [],\n    }\n\n\n@pytest.fixture\ndef complex_parsed_schema_test_object():\n    cfg = TestConfig(materialized=\"table\", severity=\"WARN\")\n    cfg._extra.update({\"extra_key\": \"extra value\"})\n    return GenericTestNode(\n        package_name=\"test\",\n        path=\"/root/x/path.sql\",\n        original_file_path=\"/root/path.sql\",\n        language=\"sql\",\n        raw_code='select * from {{ ref(\"bar\") }}',\n        name=\"foo\",\n        resource_type=NodeType.Test,\n        unique_id=\"test.test.foo\",\n        fqn=[\"test\", \"models\", \"foo\"],\n        refs=[],\n        sources=[],\n        metrics=[],\n        depends_on=DependsOn(nodes=[\"model.test.bar\"]),\n        description=\"My parsed node\",\n        database=\"test_db\",\n        schema=\"test_schema\",\n        alias=\"bar\",\n        tags=[\"tag\"],\n        meta={},\n        config=cfg,\n        columns={\"a\": ColumnInfo(\"a\", \"a text field\", {})},\n        column_name=\"id\",\n        docs=Docs(show=False),\n        test_metadata=TestMetadata(namespace=None, name=\"foo\", kwargs={}),\n        checksum=FileHash.from_contents(\"\"),\n        unrendered_config={\"materialized\": \"table\", \"severity\": \"WARN\"},\n    )\n\n\ndef test_basic_schema_test_node(\n    minimal_parsed_schema_test_dict, basic_parsed_schema_test_dict, basic_parsed_schema_test_object\n):\n    node = basic_parsed_schema_test_object\n    node_dict = basic_parsed_schema_test_dict\n    minimum = minimal_parsed_schema_test_dict\n    assert_symmetric(node, node_dict, GenericTestNode)\n\n    assert node.empty is False\n    assert node.is_ephemeral is False\n    assert node.is_refable is False\n    assert node.get_materialization() == \"test\"\n\n    assert_from_dict(node, minimum, GenericTestNode)\n    pickle.loads(pickle.dumps(node))\n\n\ndef test_complex_schema_test_node(\n    complex_parsed_schema_test_dict, complex_parsed_schema_test_object\n):\n    # this tests for the presence of _extra keys\n    node = complex_parsed_schema_test_object  # GenericTestNode\n    assert node.config._extra[\"extra_key\"]\n    node_dict = complex_parsed_schema_test_dict\n    assert_symmetric(node, node_dict)\n    assert node.empty is False\n\n\ndef test_invalid_column_name_type(complex_parsed_schema_test_dict):\n    # bad top-level field\n    bad_column_name = complex_parsed_schema_test_dict\n    bad_column_name[\"column_name\"] = {}\n    assert_fails_validation(bad_column_name, GenericTestNode)\n\n\ndef test_invalid_severity(complex_parsed_schema_test_dict):\n    invalid_config_value = complex_parsed_schema_test_dict\n    invalid_config_value[\"config\"][\"severity\"] = \"WERROR\"\n    assert_fails_validation(invalid_config_value, GenericTestNode)\n\n\n@pytest.fixture\ndef basic_timestamp_snapshot_config_dict():\n    return {\n        \"column_types\": {},\n        \"enabled\": True,\n        \"materialized\": \"snapshot\",\n        \"persist_docs\": {},\n        \"post-hook\": [],\n        \"pre-hook\": [],\n        \"quoting\": {},\n        \"tags\": [],\n        \"unique_key\": \"id\",\n        \"snapshot_meta_column_names\": {},\n        \"strategy\": \"timestamp\",\n        \"updated_at\": \"last_update\",\n        \"target_database\": \"some_snapshot_db\",\n        \"target_schema\": \"some_snapshot_schema\",\n        \"on_schema_change\": \"ignore\",\n        \"on_configuration_change\": \"apply\",\n        \"meta\": {},\n        \"grants\": {},\n        \"packages\": [],\n        \"docs\": {\"show\": True},\n        \"contract\": {\"enforced\": False, \"alias_types\": True},\n        \"lookback\": 1,\n    }\n\n\n@pytest.fixture\ndef basic_timestamp_snapshot_config_object():\n    return SnapshotConfig(\n        strategy=\"timestamp\",\n        updated_at=\"last_update\",\n        unique_key=\"id\",\n        target_database=\"some_snapshot_db\",\n        target_schema=\"some_snapshot_schema\",\n    )\n\n\n@pytest.fixture\ndef complex_timestamp_snapshot_config_dict():\n    return {\n        \"column_types\": {\"a\": \"text\"},\n        \"enabled\": True,\n        \"materialized\": \"snapshot\",\n        \"persist_docs\": {},\n        \"post-hook\": [{\"sql\": 'insert into blah(a, b) select \"1\", 1', \"transaction\": True}],\n        \"pre-hook\": [],\n        \"quoting\": {},\n        \"snapshot_meta_column_names\": {},\n        \"tags\": [],\n        \"target_database\": \"some_snapshot_db\",\n        \"target_schema\": \"some_snapshot_schema\",\n        \"unique_key\": \"id\",\n        \"extra\": \"even more\",\n        \"strategy\": \"timestamp\",\n        \"updated_at\": \"last_update\",\n        \"on_schema_change\": \"ignore\",\n        \"on_configuration_change\": \"apply\",\n        \"meta\": {},\n        \"grants\": {},\n        \"packages\": [],\n        \"docs\": {\"show\": True},\n        \"contract\": {\"enforced\": False, \"alias_types\": True},\n        \"lookback\": 1,\n    }\n\n\n@pytest.fixture\ndef complex_timestamp_snapshot_config_object():\n    cfg = SnapshotConfig(\n        column_types={\"a\": \"text\"},\n        materialized=\"snapshot\",\n        post_hook=[Hook(sql='insert into blah(a, b) select \"1\", 1')],\n        strategy=\"timestamp\",\n        target_database=\"some_snapshot_db\",\n        target_schema=\"some_snapshot_schema\",\n        updated_at=\"last_update\",\n        unique_key=\"id\",\n    )\n    cfg._extra[\"extra\"] = \"even more\"\n    return cfg\n\n\ndef test_basic_timestamp_snapshot_config(\n    basic_timestamp_snapshot_config_dict, basic_timestamp_snapshot_config_object\n):\n    cfg = basic_timestamp_snapshot_config_object\n    cfg_dict = basic_timestamp_snapshot_config_dict\n    assert_symmetric(cfg, cfg_dict)\n    pickle.loads(pickle.dumps(cfg))\n\n\ndef test_complex_timestamp_snapshot_config(\n    complex_timestamp_snapshot_config_dict, complex_timestamp_snapshot_config_object\n):\n    cfg = complex_timestamp_snapshot_config_object\n    cfg_dict = complex_timestamp_snapshot_config_dict\n    assert_symmetric(cfg, cfg_dict, SnapshotConfig)\n\n\ndef test_invalid_missing_updated_at(basic_timestamp_snapshot_config_dict):\n    bad_fields = basic_timestamp_snapshot_config_dict\n    del bad_fields[\"updated_at\"]\n    bad_fields[\"check_cols\"] = \"all\"\n    assert_snapshot_config_fails_validation(bad_fields)\n\n\n@pytest.fixture\ndef basic_check_snapshot_config_dict():\n    return {\n        \"column_types\": {},\n        \"enabled\": True,\n        \"materialized\": \"snapshot\",\n        \"persist_docs\": {},\n        \"post-hook\": [],\n        \"pre-hook\": [],\n        \"quoting\": {},\n        \"snapshot_meta_column_names\": {},\n        \"tags\": [],\n        \"target_database\": \"some_snapshot_db\",\n        \"target_schema\": \"some_snapshot_schema\",\n        \"unique_key\": \"id\",\n        \"strategy\": \"check\",\n        \"check_cols\": \"all\",\n        \"on_schema_change\": \"ignore\",\n        \"on_configuration_change\": \"apply\",\n        \"meta\": {},\n        \"grants\": {},\n        \"packages\": [],\n        \"docs\": {\"show\": True},\n        \"contract\": {\"enforced\": False, \"alias_types\": True},\n        \"lookback\": 1,\n    }\n\n\n@pytest.fixture\ndef basic_check_snapshot_config_object():\n    return SnapshotConfig(\n        strategy=\"check\",\n        check_cols=\"all\",\n        unique_key=\"id\",\n        target_database=\"some_snapshot_db\",\n        target_schema=\"some_snapshot_schema\",\n    )\n\n\n@pytest.fixture\ndef complex_set_snapshot_config_dict():\n    return {\n        \"column_types\": {\"a\": \"text\"},\n        \"enabled\": True,\n        \"materialized\": \"snapshot\",\n        \"persist_docs\": {},\n        \"post-hook\": [{\"sql\": 'insert into blah(a, b) select \"1\", 1', \"transaction\": True}],\n        \"pre-hook\": [],\n        \"quoting\": {},\n        \"snapshot_meta_column_names\": {},\n        \"tags\": [],\n        \"target_database\": \"some_snapshot_db\",\n        \"target_schema\": \"some_snapshot_schema\",\n        \"unique_key\": \"id\",\n        \"extra\": \"even more\",\n        \"strategy\": \"check\",\n        \"check_cols\": [\"a\", \"b\"],\n        \"on_schema_change\": \"ignore\",\n        \"on_configuration_change\": \"apply\",\n        \"meta\": {},\n        \"grants\": {},\n        \"packages\": [],\n        \"docs\": {\"show\": True},\n        \"contract\": {\"enforced\": False, \"alias_types\": True},\n        \"lookback\": 1,\n    }\n\n\n@pytest.fixture\ndef complex_set_snapshot_config_object():\n    cfg = SnapshotConfig(\n        column_types={\"a\": \"text\"},\n        materialized=\"snapshot\",\n        post_hook=[Hook(sql='insert into blah(a, b) select \"1\", 1')],\n        strategy=\"check\",\n        check_cols=[\"a\", \"b\"],\n        target_database=\"some_snapshot_db\",\n        target_schema=\"some_snapshot_schema\",\n        unique_key=\"id\",\n    )\n    cfg._extra[\"extra\"] = \"even more\"\n    return cfg\n\n\ndef test_basic_snapshot_config(\n    basic_check_snapshot_config_dict, basic_check_snapshot_config_object\n):\n    cfg_dict = basic_check_snapshot_config_dict\n    cfg = basic_check_snapshot_config_object\n    assert_symmetric(cfg, cfg_dict, SnapshotConfig)\n    pickle.loads(pickle.dumps(cfg))\n\n\ndef test_complex_snapshot_config(\n    complex_set_snapshot_config_dict, complex_set_snapshot_config_object\n):\n    cfg_dict = complex_set_snapshot_config_dict\n    cfg = complex_set_snapshot_config_object\n    assert_symmetric(cfg, cfg_dict)\n    pickle.loads(pickle.dumps(cfg))\n\n\ndef test_invalid_check_wrong_strategy(basic_check_snapshot_config_dict):\n    wrong_strategy = basic_check_snapshot_config_dict\n    wrong_strategy[\"strategy\"] = \"timestamp\"\n    assert_snapshot_config_fails_validation(wrong_strategy)\n\n\ndef test_invalid_missing_check_cols(basic_check_snapshot_config_dict):\n    wrong_fields = basic_check_snapshot_config_dict\n    del wrong_fields[\"check_cols\"]\n    with pytest.raises(ValidationError, match=r\"A snapshot configured with the check strategy\"):\n        SnapshotConfig.validate(wrong_fields)\n        cfg = SnapshotConfig.from_dict(wrong_fields)\n        cfg.final_validate()\n\n\ndef test_missing_snapshot_configs(basic_check_snapshot_config_dict):\n    wrong_fields = basic_check_snapshot_config_dict\n    del wrong_fields[\"strategy\"]\n    with pytest.raises(ValidationError, match=r\"Snapshots must be configured with a 'strategy'\"):\n        SnapshotConfig.validate(wrong_fields)\n        cfg = SnapshotConfig.from_dict(wrong_fields)\n        cfg.final_validate()\n\n    wrong_fields[\"strategy\"] = \"timestamp\"\n    del wrong_fields[\"unique_key\"]\n    with pytest.raises(ValidationError, match=r\"Snapshots must be configured with a 'strategy'\"):\n        SnapshotConfig.validate(wrong_fields)\n        cfg = SnapshotConfig.from_dict(wrong_fields)\n        cfg.final_validate()\n\n\ndef assert_snapshot_config_fails_validation(dct):\n    with pytest.raises(ValidationError):\n        SnapshotConfig.validate(dct)\n        obj = SnapshotConfig.from_dict(dct)\n        obj.final_validate()\n\n\ndef test_invalid_check_value(basic_check_snapshot_config_dict):\n    invalid_check_type = basic_check_snapshot_config_dict\n    invalid_check_type[\"check_cols\"] = \"some\"\n    assert_snapshot_config_fails_validation(invalid_check_type)\n\n\n@pytest.fixture\ndef basic_timestamp_snapshot_dict():\n    return {\n        \"name\": \"foo\",\n        \"created_at\": 1.0,\n        \"resource_type\": str(NodeType.Snapshot),\n        \"path\": \"/root/x/path.sql\",\n        \"original_file_path\": \"/root/path.sql\",\n        \"package_name\": \"test\",\n        \"language\": \"sql\",\n        \"raw_code\": \"select * from wherever\",\n        \"unique_id\": \"model.test.foo\",\n        \"fqn\": [\"test\", \"models\", \"foo\"],\n        \"refs\": [],\n        \"sources\": [],\n        \"metrics\": [],\n        \"functions\": [],\n        \"depends_on\": {\"macros\": [], \"nodes\": []},\n        \"database\": \"test_db\",\n        \"description\": \"\",\n        \"schema\": \"test_schema\",\n        \"alias\": \"bar\",\n        \"tags\": [],\n        \"config\": {\n            \"column_types\": {},\n            \"enabled\": True,\n            \"materialized\": \"snapshot\",\n            \"persist_docs\": {},\n            \"post-hook\": [],\n            \"pre-hook\": [],\n            \"quoting\": {},\n            \"snapshot_meta_column_names\": {},\n            \"tags\": [],\n            \"target_database\": \"some_snapshot_db\",\n            \"target_schema\": \"some_snapshot_schema\",\n            \"unique_key\": \"id\",\n            \"strategy\": \"timestamp\",\n            \"updated_at\": \"last_update\",\n            \"on_schema_change\": \"ignore\",\n            \"on_configuration_change\": \"apply\",\n            \"meta\": {},\n            \"grants\": {},\n            \"docs\": {\"show\": True},\n            \"contract\": {\"enforced\": False, \"alias_types\": True},\n            \"packages\": [],\n            \"lookback\": 1,\n        },\n        \"docs\": {\"show\": True},\n        \"contract\": {\"enforced\": False, \"alias_types\": True},\n        \"columns\": {},\n        \"meta\": {},\n        \"checksum\": {\n            \"name\": \"sha256\",\n            \"checksum\": \"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\",\n        },\n        \"unrendered_config\": {\n            \"strategy\": \"timestamp\",\n            \"unique_key\": \"id\",\n            \"updated_at\": \"last_update\",\n            \"target_database\": \"some_snapshot_db\",\n            \"target_schema\": \"some_snapshot_schema\",\n        },\n        \"unrendered_config_call_dict\": {},\n        \"config_call_dict\": {},\n        \"doc_blocks\": [],\n    }\n\n\n@pytest.fixture\ndef basic_timestamp_snapshot_object():\n    return SnapshotNode(\n        package_name=\"test\",\n        path=\"/root/x/path.sql\",\n        original_file_path=\"/root/path.sql\",\n        language=\"sql\",\n        raw_code=\"select * from wherever\",\n        name=\"foo\",\n        resource_type=NodeType.Snapshot,\n        unique_id=\"model.test.foo\",\n        fqn=[\"test\", \"models\", \"foo\"],\n        refs=[],\n        sources=[],\n        metrics=[],\n        depends_on=DependsOn(),\n        description=\"\",\n        database=\"test_db\",\n        schema=\"test_schema\",\n        alias=\"bar\",\n        tags=[],\n        config=SnapshotConfig(\n            strategy=\"timestamp\",\n            unique_key=\"id\",\n            updated_at=\"last_update\",\n            target_database=\"some_snapshot_db\",\n            target_schema=\"some_snapshot_schema\",\n        ),\n        checksum=FileHash.from_contents(\"\"),\n        unrendered_config={\n            \"strategy\": \"timestamp\",\n            \"unique_key\": \"id\",\n            \"updated_at\": \"last_update\",\n            \"target_database\": \"some_snapshot_db\",\n            \"target_schema\": \"some_snapshot_schema\",\n        },\n    )\n\n\n@pytest.fixture\ndef basic_check_snapshot_dict():\n    return {\n        \"name\": \"foo\",\n        \"created_at\": 1.0,\n        \"resource_type\": str(NodeType.Snapshot),\n        \"path\": \"/root/x/path.sql\",\n        \"original_file_path\": \"/root/path.sql\",\n        \"package_name\": \"test\",\n        \"language\": \"sql\",\n        \"raw_code\": \"select * from wherever\",\n        \"unique_id\": \"model.test.foo\",\n        \"fqn\": [\"test\", \"models\", \"foo\"],\n        \"refs\": [],\n        \"sources\": [],\n        \"metrics\": [],\n        \"functions\": [],\n        \"depends_on\": {\"macros\": [], \"nodes\": []},\n        \"database\": \"test_db\",\n        \"description\": \"\",\n        \"schema\": \"test_schema\",\n        \"alias\": \"bar\",\n        \"tags\": [],\n        \"config\": {\n            \"column_types\": {},\n            \"enabled\": True,\n            \"materialized\": \"snapshot\",\n            \"persist_docs\": {},\n            \"post-hook\": [],\n            \"pre-hook\": [],\n            \"quoting\": {},\n            \"snapshot_meta_column_names\": {},\n            \"tags\": [],\n            \"target_database\": \"some_snapshot_db\",\n            \"target_schema\": \"some_snapshot_schema\",\n            \"unique_key\": \"id\",\n            \"strategy\": \"check\",\n            \"check_cols\": \"all\",\n            \"on_schema_change\": \"ignore\",\n            \"on_configuration_change\": \"apply\",\n            \"meta\": {},\n            \"grants\": {},\n            \"docs\": {\"show\": True},\n            \"contract\": {\"enforced\": False, \"alias_types\": True},\n            \"packages\": [],\n            \"lookback\": 1,\n        },\n        \"docs\": {\"show\": True},\n        \"contract\": {\"enforced\": False, \"alias_types\": True},\n        \"columns\": {},\n        \"meta\": {},\n        \"checksum\": {\n            \"name\": \"sha256\",\n            \"checksum\": \"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\",\n        },\n        \"unrendered_config\": {\n            \"target_database\": \"some_snapshot_db\",\n            \"target_schema\": \"some_snapshot_schema\",\n            \"unique_key\": \"id\",\n            \"strategy\": \"check\",\n            \"check_cols\": \"all\",\n        },\n        \"unrendered_config_call_dict\": {},\n        \"config_call_dict\": {},\n        \"doc_blocks\": [],\n    }\n\n\n@pytest.fixture\ndef basic_check_snapshot_object():\n    return SnapshotNode(\n        package_name=\"test\",\n        path=\"/root/x/path.sql\",\n        original_file_path=\"/root/path.sql\",\n        language=\"sql\",\n        raw_code=\"select * from wherever\",\n        name=\"foo\",\n        resource_type=NodeType.Snapshot,\n        unique_id=\"model.test.foo\",\n        fqn=[\"test\", \"models\", \"foo\"],\n        refs=[],\n        sources=[],\n        metrics=[],\n        depends_on=DependsOn(),\n        description=\"\",\n        database=\"test_db\",\n        schema=\"test_schema\",\n        alias=\"bar\",\n        tags=[],\n        config=SnapshotConfig(\n            strategy=\"check\",\n            unique_key=\"id\",\n            check_cols=\"all\",\n            target_database=\"some_snapshot_db\",\n            target_schema=\"some_snapshot_schema\",\n        ),\n        checksum=FileHash.from_contents(\"\"),\n        unrendered_config={\n            \"target_database\": \"some_snapshot_db\",\n            \"target_schema\": \"some_snapshot_schema\",\n            \"unique_key\": \"id\",\n            \"strategy\": \"check\",\n            \"check_cols\": \"all\",\n        },\n    )\n\n\ndef test_timestamp_snapshot_ok(\n    basic_timestamp_snapshot_dict,\n    basic_timestamp_snapshot_object,\n):\n    node_dict = basic_timestamp_snapshot_dict\n    node = basic_timestamp_snapshot_object\n\n    assert_symmetric(node, node_dict, SnapshotNode)\n    assert node.is_refable is True\n    assert node.is_ephemeral is False\n    pickle.loads(pickle.dumps(node))\n\n\ndef test_check_snapshot_ok(\n    basic_check_snapshot_dict,\n    basic_check_snapshot_object,\n):\n    node_dict = basic_check_snapshot_dict\n    node = basic_check_snapshot_object\n\n    assert_symmetric(node, node_dict, SnapshotNode)\n    assert node.is_refable is True\n    assert node.is_ephemeral is False\n    pickle.loads(pickle.dumps(node))\n\n\ndef test_invalid_snapshot_bad_resource_type(basic_timestamp_snapshot_dict):\n    bad_resource_type = basic_timestamp_snapshot_dict\n    bad_resource_type[\"resource_type\"] = str(NodeType.Model)\n    assert_fails_validation(bad_resource_type, SnapshotNode)\n\n\nclass TestParsedMacro(ContractTestCase):\n    ContractType = Macro\n\n    def _ok_dict(self):\n        return {\n            \"name\": \"foo\",\n            \"path\": \"/root/path.sql\",\n            \"original_file_path\": \"/root/path.sql\",\n            \"created_at\": 1.0,\n            \"package_name\": \"test\",\n            \"macro_sql\": \"{% macro foo() %}select 1 as id{% endmacro %}\",\n            \"resource_type\": \"macro\",\n            \"unique_id\": \"macro.test.foo\",\n            \"depends_on\": {\"macros\": []},\n            \"meta\": {},\n            \"config\": {\n                \"meta\": {},\n                \"docs\": {\"show\": True},\n            },\n            \"description\": \"my macro description\",\n            \"docs\": {\"show\": True},\n            \"arguments\": [],\n        }\n\n    def test_ok(self):\n        macro_dict = self._ok_dict()\n        macro = self.ContractType(\n            name=\"foo\",\n            path=\"/root/path.sql\",\n            original_file_path=\"/root/path.sql\",\n            package_name=\"test\",\n            macro_sql=\"{% macro foo() %}select 1 as id{% endmacro %}\",\n            resource_type=NodeType.Macro,\n            unique_id=\"macro.test.foo\",\n            depends_on=MacroDependsOn(),\n            meta={},\n            config=MacroConfig(),\n            description=\"my macro description\",\n            arguments=[],\n        )\n        assert_symmetric(macro, macro_dict)\n        pickle.loads(pickle.dumps(macro))\n\n    def test_invalid_missing_unique_id(self):\n        bad_missing_uid = self._ok_dict()\n        del bad_missing_uid[\"unique_id\"]\n        self.assert_fails_validation(bad_missing_uid)\n\n    def test_invalid_extra_field(self):\n        bad_extra_field = self._ok_dict()\n        bad_extra_field[\"extra\"] = \"too many fields\"\n        self.assert_fails_validation(bad_extra_field)\n\n\nclass TestParsedDocumentation(ContractTestCase):\n    ContractType = Documentation\n\n    def _ok_dict(self):\n        return {\n            \"block_contents\": \"some doc contents\",\n            \"name\": \"foo\",\n            \"resource_type\": \"doc\",\n            \"original_file_path\": \"/root/docs/doc.md\",\n            \"package_name\": \"test\",\n            \"path\": \"/root/docs\",\n            \"unique_id\": \"test.foo\",\n        }\n\n    def test_ok(self):\n        doc_dict = self._ok_dict()\n        doc = self.ContractType(\n            package_name=\"test\",\n            path=\"/root/docs\",\n            original_file_path=\"/root/docs/doc.md\",\n            name=\"foo\",\n            unique_id=\"test.foo\",\n            block_contents=\"some doc contents\",\n            resource_type=NodeType.Documentation,\n        )\n        self.assert_symmetric(doc, doc_dict)\n        pickle.loads(pickle.dumps(doc))\n\n    def test_invalid_missing(self):\n        bad_missing_contents = self._ok_dict()\n        del bad_missing_contents[\"block_contents\"]\n        self.assert_fails_validation(bad_missing_contents)\n\n    def test_invalid_extra(self):\n        bad_extra_field = self._ok_dict()\n        bad_extra_field[\"extra\"] = \"more\"\n        self.assert_fails_validation(bad_extra_field)\n\n\n@pytest.fixture\ndef minimum_parsed_source_definition_dict():\n    return {\n        \"package_name\": \"test\",\n        \"path\": \"/root/models/sources.yml\",\n        \"original_file_path\": \"/root/models/sources.yml\",\n        \"created_at\": 1.0,\n        \"database\": \"some_db\",\n        \"schema\": \"some_schema\",\n        \"fqn\": [\"test\", \"source\", \"my_source\", \"my_source_table\"],\n        \"source_name\": \"my_source\",\n        \"name\": \"my_source_table\",\n        \"source_description\": \"my source description\",\n        \"loader\": \"stitch\",\n        \"identifier\": \"my_source_table\",\n        \"resource_type\": str(NodeType.Source),\n        \"unique_id\": \"test.source.my_source.my_source_table\",\n    }\n\n\n@pytest.fixture\ndef basic_parsed_source_definition_dict():\n    return {\n        \"package_name\": \"test\",\n        \"path\": \"/root/models/sources.yml\",\n        \"original_file_path\": \"/root/models/sources.yml\",\n        \"created_at\": 1.0,\n        \"database\": \"some_db\",\n        \"schema\": \"some_schema\",\n        \"fqn\": [\"test\", \"source\", \"my_source\", \"my_source_table\"],\n        \"source_name\": \"my_source\",\n        \"name\": \"my_source_table\",\n        \"source_description\": \"my source description\",\n        \"loader\": \"stitch\",\n        \"identifier\": \"my_source_table\",\n        \"resource_type\": str(NodeType.Source),\n        \"description\": \"\",\n        \"columns\": {},\n        \"quoting\": {},\n        \"unique_id\": \"test.source.my_source.my_source_table\",\n        \"meta\": {},\n        \"source_meta\": {},\n        \"tags\": [],\n        \"config\": {\n            \"enabled\": True,\n            \"freshness\": {\n                \"warn_after\": {},\n                \"error_after\": {},\n            },\n            \"tags\": [],\n            \"meta\": {},\n        },\n        \"unrendered_config\": {},\n        \"doc_blocks\": [],\n    }\n\n\n@pytest.fixture\ndef complex_parsed_source_definition_dict():\n    return {\n        \"package_name\": \"test\",\n        \"path\": \"/root/models/sources.yml\",\n        \"original_file_path\": \"/root/models/sources.yml\",\n        \"created_at\": 1.0,\n        \"database\": \"some_db\",\n        \"schema\": \"some_schema\",\n        \"fqn\": [\"test\", \"source\", \"my_source\", \"my_source_table\"],\n        \"source_name\": \"my_source\",\n        \"name\": \"my_source_table\",\n        \"source_description\": \"my source description\",\n        \"loader\": \"stitch\",\n        \"identifier\": \"my_source_table\",\n        \"resource_type\": str(NodeType.Source),\n        \"description\": \"\",\n        \"columns\": {},\n        \"quoting\": {},\n        \"unique_id\": \"test.source.my_source.my_source_table\",\n        \"meta\": {},\n        \"source_meta\": {},\n        \"tags\": [\"my_tag\"],\n        \"config\": {\n            \"enabled\": True,\n            \"freshness\": {\n                \"warn_after\": {},\n                \"error_after\": {},\n            },\n            \"tags\": [],\n            \"meta\": {},\n        },\n        \"freshness\": {\"warn_after\": {\"period\": \"hour\", \"count\": 1}, \"error_after\": {}},\n        \"loaded_at_field\": \"loaded_at\",\n        \"unrendered_config\": {},\n        \"doc_blocks\": [],\n    }\n\n\n@pytest.fixture\ndef complex_parsed_source_definition_object():\n    return SourceDefinition(\n        columns={},\n        database=\"some_db\",\n        description=\"\",\n        fqn=[\"test\", \"source\", \"my_source\", \"my_source_table\"],\n        identifier=\"my_source_table\",\n        loader=\"stitch\",\n        name=\"my_source_table\",\n        original_file_path=\"/root/models/sources.yml\",\n        package_name=\"test\",\n        path=\"/root/models/sources.yml\",\n        quoting=Quoting(),\n        resource_type=NodeType.Source,\n        schema=\"some_schema\",\n        source_description=\"my source description\",\n        source_name=\"my_source\",\n        unique_id=\"test.source.my_source.my_source_table\",\n        tags=[\"my_tag\"],\n        config=SourceConfig(),\n        freshness=FreshnessThreshold(warn_after=Time(period=TimePeriod.hour, count=1)),\n        loaded_at_field=\"loaded_at\",\n    )\n\n\ndef test_basic_source_definition(\n    minimum_parsed_source_definition_dict,\n    basic_parsed_source_definition_dict,\n    basic_parsed_source_definition_object,\n):\n    node = basic_parsed_source_definition_object\n    node_dict = basic_parsed_source_definition_dict\n    minimum = minimum_parsed_source_definition_dict\n\n    assert_symmetric(node.to_resource(), node_dict, SourceDefinitionResource)\n\n    assert node.is_ephemeral is False\n    assert node.is_refable is False\n    assert node.has_freshness is False\n\n    assert_from_dict(node.to_resource(), minimum, SourceDefinitionResource)\n    pickle.loads(pickle.dumps(node))\n\n\ndef test_extra_fields_source_definition_okay(minimum_parsed_source_definition_dict):\n    extra = minimum_parsed_source_definition_dict\n    extra[\"notvalid\"] = \"nope\"\n    # Model still load fine with extra fields\n    loaded_source = SourceDefinition.from_dict(extra)\n    assert not hasattr(loaded_source, \"notvalid\")\n\n\ndef test_invalid_missing(minimum_parsed_source_definition_dict):\n    bad_missing_name = minimum_parsed_source_definition_dict\n    del bad_missing_name[\"name\"]\n    assert_fails_validation(bad_missing_name, SourceDefinition)\n\n\ndef test_invalid_bad_resource_type(minimum_parsed_source_definition_dict):\n    bad_resource_type = minimum_parsed_source_definition_dict\n    bad_resource_type[\"resource_type\"] = str(NodeType.Model)\n    assert_fails_validation(bad_resource_type, SourceDefinition)\n\n\ndef test_complex_source_definition(\n    complex_parsed_source_definition_dict, complex_parsed_source_definition_object\n):\n    node = complex_parsed_source_definition_object\n    node_dict = complex_parsed_source_definition_dict\n    assert_symmetric(node.to_resource(), node_dict, SourceDefinitionResource)\n\n    assert node.is_ephemeral is False\n    assert node.is_refable is False\n    assert node.has_freshness is True\n\n    pickle.loads(pickle.dumps(node))\n\n\ndef test_source_no_freshness(complex_parsed_source_definition_object):\n    node = complex_parsed_source_definition_object\n    assert node.has_freshness is True\n    node.freshness = None\n    assert node.has_freshness is False\n\n\nunchanged_source_definitions = [\n    lambda u: (u, replace(u, tags=[\"mytag\"])),\n    lambda u: (u, replace(u, meta={\"a\": 1000})),\n]\n\nchanged_source_definitions = [\n    lambda u: (\n        u,\n        replace(\n            u,\n            freshness=FreshnessThreshold(warn_after=Time(period=TimePeriod.hour, count=1)),\n            loaded_at_field=\"loaded_at\",\n        ),\n    ),\n    lambda u: (u, replace(u, loaded_at_field=\"loaded_at\")),\n    lambda u: (\n        u,\n        replace(\n            u, freshness=FreshnessThreshold(error_after=Time(period=TimePeriod.hour, count=1))\n        ),\n    ),\n    lambda u: (u, replace(u, quoting=Quoting(identifier=True))),\n    lambda u: (u, replace(u, database=\"other_database\")),\n    lambda u: (u, replace(u, schema=\"other_schema\")),\n    lambda u: (u, replace(u, identifier=\"identifier\")),\n]\n\n\n@pytest.mark.parametrize(\"func\", unchanged_source_definitions)\ndef test_compare_unchanged_parsed_source_definition(func, basic_parsed_source_definition_object):\n    node, compare = func(basic_parsed_source_definition_object)\n    assert node.same_contents(compare)\n\n\n@pytest.mark.parametrize(\"func\", changed_source_definitions)\ndef test_compare_changed_source_definition(func, basic_parsed_source_definition_object):\n    node, compare = func(basic_parsed_source_definition_object)\n    assert not node.same_contents(compare)\n\n\n@pytest.fixture\ndef minimal_parsed_exposure_dict():\n    return {\n        \"name\": \"my_exposure\",\n        \"type\": \"notebook\",\n        \"owner\": {\n            \"email\": \"test@example.com\",\n        },\n        \"fqn\": [\"test\", \"exposures\", \"my_exposure\"],\n        \"unique_id\": \"exposure.test.my_exposure\",\n        \"package_name\": \"test\",\n        \"meta\": {},\n        \"tags\": [],\n        \"path\": \"models/something.yml\",\n        \"original_file_path\": \"models/something.yml\",\n        \"description\": \"\",\n        \"created_at\": 1.0,\n        \"resource_type\": \"exposure\",\n    }\n\n\n@pytest.fixture\ndef basic_parsed_exposure_dict():\n    return {\n        \"name\": \"my_exposure\",\n        \"type\": \"notebook\",\n        \"owner\": {\n            \"email\": \"test@example.com\",\n        },\n        \"resource_type\": \"exposure\",\n        \"depends_on\": {\n            \"nodes\": [],\n            \"macros\": [],\n        },\n        \"refs\": [],\n        \"sources\": [],\n        \"metrics\": [],\n        \"fqn\": [\"test\", \"exposures\", \"my_exposure\"],\n        \"unique_id\": \"exposure.test.my_exposure\",\n        \"package_name\": \"test\",\n        \"path\": \"models/something.yml\",\n        \"original_file_path\": \"models/something.yml\",\n        \"description\": \"\",\n        \"meta\": {},\n        \"tags\": [],\n        \"created_at\": 1.0,\n        \"config\": {\n            \"enabled\": True,\n            \"tags\": [],\n            \"meta\": {},\n        },\n        \"unrendered_config\": {},\n    }\n\n\n@pytest.fixture\ndef basic_parsed_exposure_object():\n    return Exposure(\n        name=\"my_exposure\",\n        resource_type=NodeType.Exposure,\n        type=ExposureType.Notebook,\n        fqn=[\"test\", \"exposures\", \"my_exposure\"],\n        unique_id=\"exposure.test.my_exposure\",\n        package_name=\"test\",\n        path=\"models/something.yml\",\n        original_file_path=\"models/something.yml\",\n        owner=Owner(email=\"test@example.com\"),\n        description=\"\",\n        meta={},\n        tags=[],\n        config=ExposureConfig(),\n        unrendered_config={},\n    )\n\n\n@pytest.fixture\ndef complex_parsed_exposure_dict():\n    return {\n        \"name\": \"my_exposure\",\n        \"type\": \"analysis\",\n        \"created_at\": 1.0,\n        \"owner\": {\n            \"email\": \"test@example.com\",\n            \"name\": \"A Name\",\n        },\n        \"resource_type\": \"exposure\",\n        \"maturity\": \"low\",\n        \"url\": \"https://example.com/analyses/1\",\n        \"description\": \"my description\",\n        \"meta\": {\"tool\": \"my_tool\", \"is_something\": False},\n        \"tags\": [\"my_department\"],\n        \"depends_on\": {\n            \"nodes\": [\"models.test.my_model\"],\n            \"macros\": [],\n        },\n        \"refs\": [],\n        \"sources\": [],\n        \"metrics\": [],\n        \"fqn\": [\"test\", \"exposures\", \"my_exposure\"],\n        \"unique_id\": \"exposure.test.my_exposure\",\n        \"package_name\": \"test\",\n        \"path\": \"models/something.yml\",\n        \"original_file_path\": \"models/something.yml\",\n        \"config\": {\n            \"enabled\": True,\n            \"tags\": [],\n            \"meta\": {},\n        },\n        \"unrendered_config\": {},\n    }\n\n\n@pytest.fixture\ndef complex_parsed_exposure_object():\n    return Exposure(\n        name=\"my_exposure\",\n        resource_type=NodeType.Exposure,\n        type=ExposureType.Analysis,\n        owner=Owner(email=\"test@example.com\", name=\"A Name\"),\n        maturity=MaturityType.Low,\n        url=\"https://example.com/analyses/1\",\n        description=\"my description\",\n        meta={\"tool\": \"my_tool\", \"is_something\": False},\n        tags=[\"my_department\"],\n        depends_on=DependsOn(nodes=[\"models.test.my_model\"]),\n        fqn=[\"test\", \"exposures\", \"my_exposure\"],\n        unique_id=\"exposure.test.my_exposure\",\n        package_name=\"test\",\n        path=\"models/something.yml\",\n        original_file_path=\"models/something.yml\",\n        config=ExposureConfig(),\n        unrendered_config={},\n    )\n\n\ndef test_basic_parsed_exposure(\n    minimal_parsed_exposure_dict, basic_parsed_exposure_dict, basic_parsed_exposure_object\n):\n    assert_symmetric(basic_parsed_exposure_object, basic_parsed_exposure_dict, Exposure)\n    assert_from_dict(basic_parsed_exposure_object, minimal_parsed_exposure_dict, Exposure)\n    pickle.loads(pickle.dumps(basic_parsed_exposure_object))\n\n\ndef test_complex_parsed_exposure(complex_parsed_exposure_dict, complex_parsed_exposure_object):\n    assert_symmetric(complex_parsed_exposure_object, complex_parsed_exposure_dict, Exposure)\n\n\nunchanged_parsed_exposures = [\n    lambda u: (u, u),\n]\n\n\nchanged_parsed_exposures = [\n    lambda u: (u, replace(u, fqn=u.fqn[:-1] + [\"something\", u.fqn[-1]])),\n    lambda u: (u, replace(u, type=ExposureType.ML)),\n    lambda u: (u, replace(u, owner=replace(u.owner, name=\"My Name\"))),\n    lambda u: (u, replace(u, maturity=MaturityType.Medium)),\n    lambda u: (u, replace(u, url=\"https://example.com/dashboard/1\")),\n    lambda u: (u, replace(u, description=\"My description\")),\n    lambda u: (u, replace(u, depends_on=DependsOn(nodes=[\"model.test.blah\"]))),\n]\n\n\n@pytest.mark.parametrize(\"func\", unchanged_parsed_exposures)\ndef test_compare_unchanged_parsed_exposure(func, basic_parsed_exposure_object):\n    node, compare = func(basic_parsed_exposure_object)\n    assert node.same_contents(compare)\n\n\n@pytest.mark.parametrize(\"func\", changed_parsed_exposures)\ndef test_compare_changed_exposure(func, basic_parsed_exposure_object):\n    node, compare = func(basic_parsed_exposure_object)\n    assert not node.same_contents(compare)\n\n\n# METRICS\n@pytest.fixture\ndef minimal_parsed_metric_dict():\n    return {\n        \"name\": \"my_metric\",\n        \"type\": \"simple\",\n        \"type_params\": {\"measure\": {\"name\": \"my_measure\"}},\n        \"timestamp\": \"created_at\",\n        \"time_grains\": [\"day\"],\n        \"fqn\": [\"test\", \"metrics\", \"my_metric\"],\n        \"unique_id\": \"metric.test.my_metric\",\n        \"package_name\": \"test\",\n        \"meta\": {},\n        \"tags\": [],\n        \"path\": \"models/something.yml\",\n        \"original_file_path\": \"models/something.yml\",\n        \"description\": \"\",\n        \"created_at\": 1.0,\n    }\n\n\n@pytest.fixture\ndef basic_parsed_metric_dict():\n    return {\n        \"name\": \"new_customers\",\n        \"label\": \"New Customers\",\n        \"type\": \"simple\",\n        \"type_params\": {\n            \"measure\": {\"name\": \"customers\", \"filter\": {\"where_sql_template\": \"is_new = true\"}},\n        },\n        \"resource_type\": \"metric\",\n        \"refs\": [[\"dim_customers\"]],\n        \"sources\": [],\n        \"metrics\": [],\n        \"fqn\": [\"test\", \"metrics\", \"my_metric\"],\n        \"unique_id\": \"metric.test.my_metric\",\n        \"package_name\": \"test\",\n        \"path\": \"models/something.yml\",\n        \"original_file_path\": \"models/something.yml\",\n        \"description\": \"New Customers\",\n        \"meta\": {},\n        \"tags\": [],\n        \"created_at\": 1.0,\n        \"depends_on\": {\n            \"nodes\": [],\n            \"macros\": [],\n        },\n    }\n\n\n@pytest.fixture\ndef basic_parsed_metric_object():\n    return Metric(\n        name=\"my_metric\",\n        resource_type=NodeType.Metric,\n        type=MetricType.SIMPLE,\n        type_params=MetricTypeParams(measure=MetricInputMeasure(name=\"a_measure\")),\n        fqn=[\"test\", \"metrics\", \"myq_metric\"],\n        unique_id=\"metric.test.my_metric\",\n        package_name=\"test\",\n        path=\"models/something.yml\",\n        original_file_path=\"models/something.yml\",\n        description=\"\",\n        meta={},\n        tags=[],\n    )\n\n\n@given(\n    builds(\n        SemanticModel,\n        depends_on=builds(DependsOn),\n        dimensions=lists(builds(Dimension)),\n        entities=lists(builds(Entity)),\n        measures=lists(builds(Measure)),\n        refs=lists(builds(RefArgs)),\n    )\n)\ndef test_semantic_model_symmetry(semantic_model: SemanticModel):\n    assert semantic_model == SemanticModel.from_dict(semantic_model.to_dict())\n    assert semantic_model == pickle.loads(pickle.dumps(semantic_model))\n"
  },
  {
    "path": "tests/unit/contracts/graph/test_semantic_manifest.py",
    "content": "from unittest.mock import patch\n\nimport pytest\n\nfrom core.dbt.contracts.graph.manifest import Manifest\nfrom dbt.artifacts.resources.types import NodeType\nfrom dbt.artifacts.resources.v1.metric import (\n    CumulativeTypeParams,\n    MetricTimeWindow,\n    MetricTypeParams,\n)\nfrom dbt.artifacts.resources.v1.model import ModelConfig, TimeSpine\nfrom dbt.artifacts.resources.v1.semantic_model import DimensionType\nfrom dbt.constants import LEGACY_TIME_SPINE_MODEL_NAME\nfrom dbt.contracts.files import FileHash\nfrom dbt.contracts.graph.nodes import (\n    ColumnInfo,\n    DependsOn,\n    Metric,\n    ModelNode,\n    SemanticModel,\n)\nfrom dbt.contracts.graph.semantic_manifest import SemanticManifest\nfrom dbt.events.types import TimeDimensionsRequireGranularityDeprecation\nfrom dbt_common.events.event_catcher import EventCatcher\nfrom dbt_common.events.event_manager_client import add_callback_to_manager\nfrom dbt_semantic_interfaces.type_enums import TimeGranularity\nfrom dbt_semantic_interfaces.type_enums.metric_type import MetricType\n\n\n# Overwrite the default nods to construct the manifest\n@pytest.fixture\ndef nodes(metricflow_time_spine_model):\n    return [metricflow_time_spine_model]\n\n\n@pytest.fixture\ndef semantic_models(\n    semantic_model,\n) -> list:\n    return [semantic_model]\n\n\n@pytest.fixture\ndef metrics(\n    metric,\n) -> list:\n    return [metric]\n\n\nclass TestSemanticManifest:\n\n    def test_validate(self, manifest):\n        with patch(\"dbt.contracts.graph.semantic_manifest.get_flags\") as patched_get_flags:\n            patched_get_flags.return_value.require_yaml_configuration_for_mf_time_spines = True\n            sm_manifest = SemanticManifest(manifest)\n            assert sm_manifest.validate()\n\n    def test_require_yaml_configuration_for_mf_time_spines(\n        self, manifest: Manifest, metricflow_time_spine_model: ModelNode\n    ):\n        with patch(\"dbt.contracts.graph.semantic_manifest.get_flags\") as patched_get_flags, patch(\n            \"dbt.contracts.graph.semantic_manifest.deprecations\"\n        ) as patched_deprecations:\n            patched_get_flags.return_value.require_yaml_configuration_for_mf_time_spines = False\n            manifest.nodes[metricflow_time_spine_model.unique_id] = metricflow_time_spine_model\n            sm_manifest = SemanticManifest(manifest)\n            assert sm_manifest.validate()\n            assert patched_deprecations.warn.call_count == 1\n\n    def test_metricflow_time_spine_non_day_grain_deprecation_warning(\n        self, manifest: Manifest, metricflow_time_spine_model: ModelNode\n    ):\n        \"\"\"Test that a metricflow_time_spine with non-day grain does not trigger deprecation warning.\"\"\"\n        # Create a metricflow_time_spine model with HOUR granularity\n        metricflow_time_spine_hour = ModelNode(\n            name=LEGACY_TIME_SPINE_MODEL_NAME,\n            database=\"dbt\",\n            schema=\"analytics\",\n            alias=LEGACY_TIME_SPINE_MODEL_NAME,\n            resource_type=NodeType.Model,\n            unique_id=\"model.test.metricflow_time_spine\",\n            fqn=[\"test\", \"metricflow_time_spine\"],\n            package_name=\"test\",\n            refs=[],\n            sources=[],\n            metrics=[],\n            depends_on=DependsOn(),\n            config=ModelConfig(),\n            tags=[],\n            path=\"metricflow_time_spine.sql\",\n            original_file_path=\"metricflow_time_spine.sql\",\n            meta={},\n            language=\"sql\",\n            raw_code=\"SELECT DATEADD(hour, ROW_NUMBER() OVER (ORDER BY 1), '2020-01-01'::timestamp) as ts_hour\",\n            checksum=FileHash.empty(),\n            relation_name=\"\",\n            columns={\n                \"ts_hour\": ColumnInfo(\n                    name=\"ts_hour\",\n                    description=\"\",\n                    meta={},\n                    data_type=\"timestamp\",\n                    constraints=[],\n                    quote=None,\n                    tags=[],\n                    granularity=TimeGranularity.HOUR,\n                )\n            },\n            time_spine=TimeSpine(standard_granularity_column=\"ts_hour\"),\n        )\n\n        with patch(\"dbt.contracts.graph.semantic_manifest.get_flags\") as patched_get_flags, patch(\n            \"dbt.contracts.graph.semantic_manifest.deprecations\"\n        ) as patched_deprecations:\n            patched_get_flags.return_value.require_yaml_configuration_for_mf_time_spines = False\n            manifest.nodes[metricflow_time_spine_hour.unique_id] = metricflow_time_spine_hour\n            sm_manifest = SemanticManifest(manifest)\n            assert sm_manifest.validate()\n            assert patched_deprecations.warn.call_count == 0\n\n    @pytest.mark.parametrize(\n        \"metric_type_params, num_warns, should_error, flag_value\",\n        [\n            (\n                MetricTypeParams(grain_to_date=TimeGranularity.MONTH),\n                1,\n                False,\n                False,\n            ),\n            (\n                MetricTypeParams(\n                    window=MetricTimeWindow(count=1, granularity=TimeGranularity.MONTH.value)\n                ),\n                1,\n                False,\n                False,\n            ),\n            (\n                MetricTypeParams(\n                    cumulative_type_params=CumulativeTypeParams(\n                        grain_to_date=TimeGranularity.MONTH.value,\n                    )\n                ),\n                0,\n                False,\n                False,\n            ),\n            (\n                MetricTypeParams(\n                    cumulative_type_params=CumulativeTypeParams(\n                        window=MetricTimeWindow(count=1, granularity=TimeGranularity.MONTH.value),\n                    )\n                ),\n                0,\n                False,\n                False,\n            ),\n            (\n                MetricTypeParams(grain_to_date=TimeGranularity.MONTH),\n                0,\n                True,\n                True,\n            ),\n            (\n                MetricTypeParams(\n                    window=MetricTimeWindow(count=1, granularity=TimeGranularity.MONTH.value)\n                ),\n                0,\n                True,\n                True,\n            ),\n            (\n                MetricTypeParams(\n                    cumulative_type_params=CumulativeTypeParams(\n                        grain_to_date=TimeGranularity.MONTH.value,\n                    )\n                ),\n                0,\n                False,\n                True,\n            ),\n            (\n                MetricTypeParams(\n                    cumulative_type_params=CumulativeTypeParams(\n                        window=MetricTimeWindow(count=1, granularity=TimeGranularity.MONTH.value),\n                    )\n                ),\n                0,\n                False,\n                True,\n            ),\n        ],\n    )\n    def test_deprecate_cumulative_type_params(\n        self,\n        manifest: Manifest,\n        metric_type_params: MetricTypeParams,\n        num_warns: int,\n        should_error: bool,\n        flag_value: bool,\n    ):\n        with patch(\"dbt.contracts.graph.semantic_manifest.get_flags\") as patched_get_flags, patch(\n            \"dbt.contracts.graph.semantic_manifest.deprecations\"\n        ) as patched_deprecations:\n            patched_get_flags.return_value.require_nested_cumulative_type_params = flag_value\n            manifest.metrics[\"metric.test.my_metric\"] = Metric(\n                name=\"my_metric\",\n                type=MetricType.CUMULATIVE,\n                type_params=metric_type_params,\n                resource_type=NodeType.Metric,\n                package_name=\"test\",\n                path=\"models/test/my_metric.yml\",\n                original_file_path=\"models/test/my_metric.yml\",\n                unique_id=\"metric.test.my_metric\",\n                fqn=[\"test\", \"my_metric\"],\n                description=\"My metric\",\n                label=\"My Metric\",\n            )\n            sm_manifest = SemanticManifest(manifest)\n            assert sm_manifest.validate() != should_error\n            assert patched_deprecations.warn.call_count == num_warns\n\n    def test_time_dimensions_require_granularity_deprecation(\n        self, manifest: Manifest, semantic_model: SemanticModel\n    ):\n        # we only do this patch because the semantic manifest validation requires the flag to be set\n        with patch(\"dbt.contracts.graph.semantic_manifest.get_flags\") as patched_get_flags:\n            patched_get_flags.return_value.require_yaml_configuration_for_mf_time_spines = False\n\n            event_catcher = EventCatcher(TimeDimensionsRequireGranularityDeprecation)\n            add_callback_to_manager(event_catcher.catch)\n            sm_manifest = SemanticManifest(manifest)\n            assert sm_manifest.validate() is True, \"Semantic manifest should validate successfully\"\n            assert len(event_catcher.caught_events) == 0\n\n            # Set the time dimension granularity to None\n            dimension = semantic_model.dimensions[0]\n            assert dimension.type == DimensionType.TIME\n            dimension.type_params = None  # This also removes the time granularity\n            sm_manifest = SemanticManifest(manifest)\n            assert sm_manifest.validate() is True, \"Semantic manifest should validate successfully\"\n            assert len(event_catcher.caught_events) == 1\n"
  },
  {
    "path": "tests/unit/contracts/graph/test_udfs.py",
    "content": "from dataclasses import dataclass\nfrom typing import Optional\n\nimport pytest\n\nfrom dbt.contracts.files import FileHash\nfrom dbt.contracts.graph.nodes import FunctionNode, FunctionReturns, NodeType\nfrom dbt.task.function import FunctionRunner\n\n\n@dataclass\nclass StubRelation:\n    database: Optional[str] = None\n    schema: Optional[str] = None\n    name: Optional[str] = None\n\n    def __str__(self):\n        parts = [self.database, self.schema, self.name]\n        return \".\".join(part for part in parts if part is not None)\n\n    def include(self, database: bool = True, schema: bool = True, name: bool = True):\n        if not database:\n            self.database = None\n        if not schema:\n            self.schema = None\n        if not name:\n            self.name = None\n        return self\n\n\n@pytest.fixture\ndef function_node():\n    return FunctionNode(\n        resource_type=NodeType.Function,\n        name=\"name\",\n        returns=FunctionReturns(data_type=\"int\"),\n        database=\"db\",\n        schema=\"schema\",\n        package_name=\"pkg\",\n        path=\"path/to/file.sql\",\n        original_file_path=\"path/to/original/file.sql\",\n        unique_id=\"pkg.schema.name\",\n        fqn=[\"pkg\", \"schema\", \"name\"],\n        alias=\"alias\",\n        checksum=FileHash.from_contents(\"test\"),\n    )\n\n\ndef test_function_node_description(mock_adapter, runtime_config, function_node):\n    mock_adapter.Relation.create_from.return_value = StubRelation(\n        database=\"db\", schema=\"schema\", name=\"name\"\n    )\n\n    runner = FunctionRunner(\n        config=runtime_config,\n        adapter=mock_adapter,\n        node=function_node,\n        node_index=0,\n        num_nodes=1,\n    )\n\n    assert runner.describe_node() == \"function db.schema.name\"\n\n\ndef test_function_node_description_with_default_database(\n    mock_adapter, runtime_config, function_node\n):\n    mock_adapter.Relation.create_from.return_value = StubRelation(\n        database=None, schema=\"schema\", name=\"name\"\n    )\n\n    function_node.database = runtime_config.credentials.database\n\n    runner = FunctionRunner(\n        config=runtime_config,\n        adapter=mock_adapter,\n        node=function_node,\n        node_index=0,\n        num_nodes=1,\n    )\n\n    assert runner.describe_node() == \"function schema.name\"\n"
  },
  {
    "path": "tests/unit/contracts/graph/test_unparsed.py",
    "content": "import pickle\nfrom abc import abstractmethod\nfrom datetime import timedelta\nfrom typing import Any, Dict\n\nimport pytest\nfrom typing_extensions import override\n\nfrom dbt.artifacts.resources import (\n    ExposureType,\n    FreshnessThreshold,\n    MaturityType,\n    Owner,\n    Quoting,\n    Time,\n)\nfrom dbt.artifacts.resources.types import TimePeriod\nfrom dbt.artifacts.schemas.results import FreshnessStatus\nfrom dbt.contracts.graph.unparsed import (\n    Docs,\n    HasColumnTests,\n    UnparsedColumn,\n    UnparsedConversionTypeParams,\n    UnparsedDerivedDimensionV2,\n    UnparsedDocumentationFile,\n    UnparsedExposure,\n    UnparsedMacro,\n    UnparsedMetric,\n    UnparsedMetricInputMeasure,\n    UnparsedMetricTypeParams,\n    UnparsedMetricV2,\n    UnparsedModelUpdate,\n    UnparsedNode,\n    UnparsedNodeUpdate,\n    UnparsedRunHook,\n    UnparsedSourceDefinition,\n    UnparsedSourceTableDefinition,\n    UnparsedVersion,\n)\nfrom dbt.exceptions import ParsingError\nfrom dbt.node_types import NodeType\nfrom dbt.parser.schemas import ParserRef\nfrom dbt_semantic_interfaces.type_enums.conversion_calculation_type import (\n    ConversionCalculationType,\n)\nfrom tests.unit.utils import ContractTestCase\n\n\nclass TestUnparsedMacro(ContractTestCase):\n    ContractType = UnparsedMacro\n\n    def test_ok(self):\n        macro_dict = {\n            \"path\": \"/root/path.sql\",\n            \"original_file_path\": \"/root/path.sql\",\n            \"package_name\": \"test\",\n            \"language\": \"sql\",\n            \"raw_code\": \"{% macro foo() %}select 1 as id{% endmacro %}\",\n            \"resource_type\": \"macro\",\n        }\n        macro = self.ContractType(\n            path=\"/root/path.sql\",\n            original_file_path=\"/root/path.sql\",\n            package_name=\"test\",\n            language=\"sql\",\n            raw_code=\"{% macro foo() %}select 1 as id{% endmacro %}\",\n            resource_type=NodeType.Macro,\n        )\n        self.assert_symmetric(macro, macro_dict)\n        pickle.loads(pickle.dumps(macro))\n\n    def test_invalid_missing_field(self):\n        macro_dict = {\n            \"path\": \"/root/path.sql\",\n            \"original_file_path\": \"/root/path.sql\",\n            # 'package_name': 'test',\n            \"language\": \"sql\",\n            \"raw_code\": \"{% macro foo() %}select 1 as id{% endmacro %}\",\n            \"resource_type\": \"macro\",\n        }\n        self.assert_fails_validation(macro_dict)\n\n    def test_invalid_extra_field(self):\n        macro_dict = {\n            \"path\": \"/root/path.sql\",\n            \"original_file_path\": \"/root/path.sql\",\n            \"package_name\": \"test\",\n            \"language\": \"sql\",\n            \"raw_code\": \"{% macro foo() %}select 1 as id{% endmacro %}\",\n            \"extra\": \"extra\",\n            \"resource_type\": \"macro\",\n        }\n        self.assert_fails_validation(macro_dict)\n\n\nclass TestUnparsedNode(ContractTestCase):\n    ContractType = UnparsedNode\n\n    def test_ok(self):\n        node_dict = {\n            \"name\": \"foo\",\n            \"resource_type\": NodeType.Model,\n            \"path\": \"/root/x/path.sql\",\n            \"original_file_path\": \"/root/path.sql\",\n            \"package_name\": \"test\",\n            \"language\": \"sql\",\n            \"raw_code\": 'select * from {{ ref(\"thing\") }}',\n        }\n        node = self.ContractType(\n            package_name=\"test\",\n            path=\"/root/x/path.sql\",\n            original_file_path=\"/root/path.sql\",\n            language=\"sql\",\n            raw_code='select * from {{ ref(\"thing\") }}',\n            name=\"foo\",\n            resource_type=NodeType.Model,\n        )\n        self.assert_symmetric(node, node_dict)\n        self.assertFalse(node.empty)\n\n        self.assert_fails_validation(node_dict, cls=UnparsedRunHook)\n        self.assert_fails_validation(node_dict, cls=UnparsedMacro)\n        pickle.loads(pickle.dumps(node))\n\n    def test_empty(self):\n        node_dict = {\n            \"name\": \"foo\",\n            \"resource_type\": NodeType.Model,\n            \"path\": \"/root/x/path.sql\",\n            \"original_file_path\": \"/root/path.sql\",\n            \"package_name\": \"test\",\n            \"language\": \"sql\",\n            \"raw_code\": \"  \\n\",\n        }\n        node = UnparsedNode(\n            package_name=\"test\",\n            path=\"/root/x/path.sql\",\n            original_file_path=\"/root/path.sql\",\n            language=\"sql\",\n            raw_code=\"  \\n\",\n            name=\"foo\",\n            resource_type=NodeType.Model,\n        )\n        self.assert_symmetric(node, node_dict)\n        self.assertTrue(node.empty)\n\n        self.assert_fails_validation(node_dict, cls=UnparsedRunHook)\n        self.assert_fails_validation(node_dict, cls=UnparsedMacro)\n\n\nclass TestUnparsedRunHook(ContractTestCase):\n    ContractType = UnparsedRunHook\n\n    def test_ok(self):\n        node_dict = {\n            \"name\": \"foo\",\n            \"resource_type\": NodeType.Operation,\n            \"path\": \"/root/dbt_project.yml\",\n            \"original_file_path\": \"/root/dbt_project.yml\",\n            \"package_name\": \"test\",\n            \"language\": \"sql\",\n            \"raw_code\": \"GRANT select on dbt_postgres\",\n            \"index\": 4,\n        }\n        node = self.ContractType(\n            package_name=\"test\",\n            path=\"/root/dbt_project.yml\",\n            original_file_path=\"/root/dbt_project.yml\",\n            language=\"sql\",\n            raw_code=\"GRANT select on dbt_postgres\",\n            name=\"foo\",\n            resource_type=NodeType.Operation,\n            index=4,\n        )\n        self.assert_symmetric(node, node_dict)\n        self.assert_fails_validation(node_dict, cls=UnparsedNode)\n        pickle.loads(pickle.dumps(node))\n\n    def test_bad_type(self):\n        node_dict = {\n            \"name\": \"foo\",\n            \"resource_type\": NodeType.Model,  # invalid\n            \"path\": \"/root/dbt_project.yml\",\n            \"original_file_path\": \"/root/dbt_project.yml\",\n            \"package_name\": \"test\",\n            \"language\": \"sql\",\n            \"raw_code\": \"GRANT select on dbt_postgres\",\n            \"index\": 4,\n        }\n        self.assert_fails_validation(node_dict)\n\n\nclass TestFreshnessThreshold(ContractTestCase):\n    ContractType = FreshnessThreshold\n\n    def test_empty(self):\n        empty = self.ContractType()\n        self.assert_symmetric(empty, {\"error_after\": {}, \"warn_after\": {}})\n        self.assertEqual(empty.status(float(\"Inf\")), FreshnessStatus.Pass)\n        self.assertEqual(empty.status(0), FreshnessStatus.Pass)\n\n    def test_both(self):\n        threshold = self.ContractType(\n            warn_after=Time(count=18, period=TimePeriod.hour),\n            error_after=Time(count=2, period=TimePeriod.day),\n        )\n        dct = {\n            \"error_after\": {\"count\": 2, \"period\": \"day\"},\n            \"warn_after\": {\"count\": 18, \"period\": \"hour\"},\n        }\n        self.assert_symmetric(threshold, dct)\n\n        error_seconds = timedelta(days=3).total_seconds()\n        warn_seconds = timedelta(days=1).total_seconds()\n        pass_seconds = timedelta(hours=3).total_seconds()\n        self.assertEqual(threshold.status(error_seconds), FreshnessStatus.Error)\n        self.assertEqual(threshold.status(warn_seconds), FreshnessStatus.Warn)\n        self.assertEqual(threshold.status(pass_seconds), FreshnessStatus.Pass)\n        pickle.loads(pickle.dumps(threshold))\n\n    def test_merged(self):\n        t1 = self.ContractType(\n            warn_after=Time(count=36, period=TimePeriod.hour),\n            error_after=Time(count=2, period=TimePeriod.day),\n        )\n        t2 = self.ContractType(\n            warn_after=Time(count=18, period=TimePeriod.hour),\n        )\n        threshold = self.ContractType(\n            warn_after=Time(count=18, period=TimePeriod.hour),\n            error_after=Time(count=None, period=None),\n        )\n        self.assertEqual(threshold, t1.merged(t2))\n\n        warn_seconds = timedelta(days=1).total_seconds()\n        pass_seconds = timedelta(hours=3).total_seconds()\n        self.assertEqual(threshold.status(warn_seconds), FreshnessStatus.Warn)\n        self.assertEqual(threshold.status(pass_seconds), FreshnessStatus.Pass)\n\n\nclass TestQuoting(ContractTestCase):\n    ContractType = Quoting\n\n    def test_empty(self):\n        empty = self.ContractType()\n        self.assert_symmetric(empty, {})\n\n    def test_partial(self):\n        a = self.ContractType(None, True, False)\n        b = self.ContractType(True, False, None)\n        self.assert_symmetric(a, {\"schema\": True, \"identifier\": False})\n        self.assert_symmetric(b, {\"database\": True, \"schema\": False})\n\n        c = a.merged(b)\n        self.assertEqual(c, self.ContractType(True, False, False))\n        self.assert_symmetric(c, {\"database\": True, \"schema\": False, \"identifier\": False})\n        pickle.loads(pickle.dumps(c))\n\n\nclass TestUnparsedSourceDefinition(ContractTestCase):\n    ContractType = UnparsedSourceDefinition\n\n    def test_defaults(self):\n        minimum = self.ContractType(name=\"foo\")\n        from_dict = {\"name\": \"foo\"}\n        to_dict = {\n            \"name\": \"foo\",\n            \"description\": \"\",\n            \"freshness\": {\"error_after\": {}, \"warn_after\": {}},\n            \"quoting\": {},\n            \"tables\": [],\n            \"loader\": \"\",\n            \"meta\": {},\n            \"tags\": [],\n            \"config\": {},\n        }\n        self.assert_from_dict(minimum, from_dict)\n        self.assert_to_dict(minimum, to_dict)\n\n    def test_contents(self):\n        empty = self.ContractType(\n            name=\"foo\",\n            description=\"a description\",\n            quoting=Quoting(database=False),\n            loader=\"some_loader\",\n            freshness=FreshnessThreshold(),\n            tables=[],\n            meta={},\n        )\n        dct = {\n            \"name\": \"foo\",\n            \"description\": \"a description\",\n            \"quoting\": {\"database\": False},\n            \"loader\": \"some_loader\",\n            \"freshness\": {\"error_after\": {}, \"warn_after\": {}},\n            \"tables\": [],\n            \"meta\": {},\n            \"tags\": [],\n            \"config\": {},\n        }\n        self.assert_symmetric(empty, dct)\n\n    def test_table_defaults(self):\n        table_1 = UnparsedSourceTableDefinition(name=\"table1\")\n        table_2 = UnparsedSourceTableDefinition(\n            name=\"table2\",\n            description=\"table 2\",\n            quoting=Quoting(database=True),\n        )\n        source = self.ContractType(name=\"foo\", tables=[table_1, table_2])\n        from_dict = {\n            \"name\": \"foo\",\n            \"tables\": [\n                {\"name\": \"table1\"},\n                {\n                    \"name\": \"table2\",\n                    \"description\": \"table 2\",\n                    \"quoting\": {\"database\": True},\n                },\n            ],\n        }\n        to_dict = {\n            \"name\": \"foo\",\n            \"description\": \"\",\n            \"config\": {},\n            \"loader\": \"\",\n            \"freshness\": {\"error_after\": {}, \"warn_after\": {}},\n            \"quoting\": {},\n            \"meta\": {},\n            \"tables\": [\n                {\n                    \"name\": \"table1\",\n                    \"description\": \"\",\n                    \"config\": {},\n                    \"docs\": {\"show\": True},\n                    \"data_tests\": [],\n                    \"tests\": [],\n                    \"columns\": [],\n                    \"constraints\": [],\n                    \"quoting\": {},\n                    \"freshness\": {\"error_after\": {}, \"warn_after\": {}},\n                    \"meta\": {},\n                    \"tags\": [],\n                },\n                {\n                    \"name\": \"table2\",\n                    \"description\": \"table 2\",\n                    \"config\": {},\n                    \"docs\": {\"show\": True},\n                    \"data_tests\": [],\n                    \"tests\": [],\n                    \"columns\": [],\n                    \"constraints\": [],\n                    \"quoting\": {\"database\": True},\n                    \"freshness\": {\"error_after\": {}, \"warn_after\": {}},\n                    \"meta\": {},\n                    \"tags\": [],\n                },\n            ],\n            \"tags\": [],\n        }\n        self.assert_from_dict(source, from_dict)\n        self.assert_symmetric(source, to_dict)\n        pickle.loads(pickle.dumps(source))\n\n\nclass TestUnparsedDocumentationFile(ContractTestCase):\n    ContractType = UnparsedDocumentationFile\n\n    def test_ok(self):\n        doc = self.ContractType(\n            package_name=\"test\",\n            path=\"/root/docs\",\n            original_file_path=\"/root/docs/doc.md\",\n            file_contents=\"blah blah blah\",\n        )\n        doc_dict = {\n            \"package_name\": \"test\",\n            \"path\": \"/root/docs\",\n            \"original_file_path\": \"/root/docs/doc.md\",\n            \"file_contents\": \"blah blah blah\",\n        }\n        self.assert_symmetric(doc, doc_dict)\n        self.assertEqual(doc.resource_type, NodeType.Documentation)\n        self.assert_fails_validation(doc_dict, UnparsedNode)\n        pickle.loads(pickle.dumps(doc))\n\n    def test_extra_field(self):\n        self.assert_fails_validation({})\n        doc_dict = {\n            \"package_name\": \"test\",\n            \"path\": \"/root/docs\",\n            \"original_file_path\": \"/root/docs/doc.md\",\n            \"file_contents\": \"blah blah blah\",\n            \"resource_type\": \"docs\",\n        }\n        self.assert_fails_validation(doc_dict)\n\n\nclass TestUnparsedNodeUpdate(ContractTestCase):\n    ContractType = UnparsedNodeUpdate\n\n    def test_defaults(self):\n        minimum = self.ContractType(\n            name=\"foo\",\n            yaml_key=\"models\",\n            original_file_path=\"/some/fake/path\",\n            package_name=\"test\",\n        )\n        from_dict = {\n            \"name\": \"foo\",\n            \"yaml_key\": \"models\",\n            \"original_file_path\": \"/some/fake/path\",\n            \"package_name\": \"test\",\n        }\n        to_dict = {\n            \"name\": \"foo\",\n            \"yaml_key\": \"models\",\n            \"original_file_path\": \"/some/fake/path\",\n            \"package_name\": \"test\",\n            \"columns\": [],\n            \"description\": \"\",\n            \"docs\": {\"show\": True},\n            \"data_tests\": [],\n            \"tests\": [],\n            \"meta\": {},\n            \"config\": {},\n            \"constraints\": [],\n        }\n        self.assert_from_dict(minimum, from_dict)\n        self.assert_to_dict(minimum, to_dict)\n\n    def test_contents(self):\n        update = self.ContractType(\n            name=\"foo\",\n            yaml_key=\"models\",\n            original_file_path=\"/some/fake/path\",\n            package_name=\"test\",\n            description=\"a description\",\n            data_tests=[\"table_test\"],\n            meta={\"key\": [\"value1\", \"value2\"]},\n            columns=[\n                UnparsedColumn(\n                    name=\"x\",\n                    description=\"x description\",\n                    meta={\"key2\": \"value3\"},\n                ),\n                UnparsedColumn(\n                    name=\"y\",\n                    description=\"y description\",\n                    data_tests=[\"unique\", {\"accepted_values\": {\"values\": [\"blue\", \"green\"]}}],\n                    meta={},\n                    tags=[\"a\", \"b\"],\n                ),\n            ],\n            docs=Docs(show=False),\n        )\n        dct = {\n            \"name\": \"foo\",\n            \"yaml_key\": \"models\",\n            \"original_file_path\": \"/some/fake/path\",\n            \"package_name\": \"test\",\n            \"description\": \"a description\",\n            \"data_tests\": [\"table_test\"],\n            \"tests\": [],\n            \"meta\": {\"key\": [\"value1\", \"value2\"]},\n            \"constraints\": [],\n            \"columns\": [\n                {\n                    \"name\": \"x\",\n                    \"description\": \"x description\",\n                    \"docs\": {\"show\": True},\n                    \"data_tests\": [],\n                    \"tests\": [],\n                    \"meta\": {\"key2\": \"value3\"},\n                    \"tags\": [],\n                    \"constraints\": [],\n                    \"config\": {},\n                },\n                {\n                    \"name\": \"y\",\n                    \"description\": \"y description\",\n                    \"docs\": {\"show\": True},\n                    \"data_tests\": [\"unique\", {\"accepted_values\": {\"values\": [\"blue\", \"green\"]}}],\n                    \"tests\": [],\n                    \"meta\": {},\n                    \"tags\": [\"a\", \"b\"],\n                    \"constraints\": [],\n                    \"config\": {},\n                },\n            ],\n            \"docs\": {\"show\": False},\n            \"config\": {},\n        }\n        self.assert_symmetric(update, dct)\n        pickle.loads(pickle.dumps(update))\n\n    def test_bad_test_type(self):\n        dct = {\n            \"name\": \"foo\",\n            \"yaml_key\": \"models\",\n            \"original_file_path\": \"/some/fake/path\",\n            \"package_name\": \"test\",\n            \"description\": \"a description\",\n            \"data_tests\": [\"table_test\"],\n            \"tests\": [],\n            \"meta\": {\"key\": [\"value1\", \"value2\"]},\n            \"columns\": [\n                {\n                    \"name\": \"x\",\n                    \"description\": \"x description\",\n                    \"docs\": {\"show\": True},\n                    \"data_tests\": [],\n                    \"tests\": [],\n                    \"meta\": {\"key2\": \"value3\"},\n                },\n                {\n                    \"name\": \"y\",\n                    \"description\": \"y description\",\n                    \"docs\": {\"show\": True},\n                    \"data_tests\": [100, {\"accepted_values\": {\"values\": [\"blue\", \"green\"]}}],\n                    \"tests\": [],\n                    \"meta\": {},\n                    \"yaml_key\": \"models\",\n                    \"original_file_path\": \"/some/fake/path\",\n                },\n            ],\n            \"docs\": {\"show\": True},\n        }\n        self.assert_fails_validation(dct)\n\n        dct = {\n            \"name\": \"foo\",\n            \"yaml_key\": \"models\",\n            \"original_file_path\": \"/some/fake/path\",\n            \"package_name\": \"test\",\n            \"description\": \"a description\",\n            \"data_tests\": [\"table_test\"],\n            \"tests\": [],\n            \"meta\": {\"key\": [\"value1\", \"value2\"]},\n            \"columns\": [\n                # column missing a name\n                {\n                    \"description\": \"x description\",\n                    \"docs\": {\"show\": True},\n                    \"data_tests\": [],\n                    \"tests\": [],\n                    \"meta\": {\"key2\": \"value3\"},\n                },\n                {\n                    \"name\": \"y\",\n                    \"description\": \"y description\",\n                    \"docs\": {\"show\": True},\n                    \"data_tests\": [\"unique\", {\"accepted_values\": {\"values\": [\"blue\", \"green\"]}}],\n                    \"tests\": [],\n                    \"meta\": {},\n                    \"yaml_key\": \"models\",\n                    \"original_file_path\": \"/some/fake/path\",\n                },\n            ],\n            \"docs\": {\"show\": True},\n        }\n        self.assert_fails_validation(dct)\n\n        # missing a name\n        dct = {\n            \"yaml_key\": \"models\",\n            \"original_file_path\": \"/some/fake/path\",\n            \"package_name\": \"test\",\n            \"description\": \"a description\",\n            \"data_tests\": [\"table_test\"],\n            \"tests\": [],\n            \"meta\": {\"key\": [\"value1\", \"value2\"]},\n            \"columns\": [\n                {\n                    \"name\": \"x\",\n                    \"description\": \"x description\",\n                    \"docs\": {\"show\": True},\n                    \"data_tests\": [],\n                    \"tests\": [],\n                    \"meta\": {\"key2\": \"value3\"},\n                },\n                {\n                    \"name\": \"y\",\n                    \"description\": \"y description\",\n                    \"docs\": {\"show\": True},\n                    \"data_tests\": [\"unique\", {\"accepted_values\": {\"values\": [\"blue\", \"green\"]}}],\n                    \"tests\": [],\n                    \"meta\": {},\n                    \"yaml_key\": \"models\",\n                    \"original_file_path\": \"/some/fake/path\",\n                },\n            ],\n            \"docs\": {\"show\": True},\n        }\n        self.assert_fails_validation(dct)\n\n\nclass TestUnparsedModelUpdate(ContractTestCase):\n    ContractType = UnparsedModelUpdate\n\n    def test_defaults(self):\n        minimum = self.ContractType(\n            name=\"foo\",\n            yaml_key=\"models\",\n            original_file_path=\"/some/fake/path\",\n            package_name=\"test\",\n        )\n        from_dict = {\n            \"name\": \"foo\",\n            \"yaml_key\": \"models\",\n            \"original_file_path\": \"/some/fake/path\",\n            \"package_name\": \"test\",\n        }\n        to_dict = {\n            \"name\": \"foo\",\n            \"yaml_key\": \"models\",\n            \"original_file_path\": \"/some/fake/path\",\n            \"package_name\": \"test\",\n            \"columns\": [],\n            \"description\": \"\",\n            \"docs\": {\"show\": True},\n            \"data_tests\": [],\n            \"tests\": [],\n            \"meta\": {},\n            \"config\": {},\n            \"constraints\": [],\n            \"versions\": [],\n        }\n        self.assert_from_dict(minimum, from_dict)\n        self.assert_to_dict(minimum, to_dict)\n\n    def test_contents(self):\n        update = self.ContractType(\n            name=\"foo\",\n            yaml_key=\"models\",\n            original_file_path=\"/some/fake/path\",\n            package_name=\"test\",\n            description=\"a description\",\n            data_tests=[\"table_test\"],\n            meta={\"key\": [\"value1\", \"value2\"]},\n            columns=[\n                UnparsedColumn(\n                    name=\"x\",\n                    description=\"x description\",\n                    meta={\"key2\": \"value3\"},\n                ),\n                UnparsedColumn(\n                    name=\"y\",\n                    description=\"y description\",\n                    data_tests=[\"unique\", {\"accepted_values\": {\"values\": [\"blue\", \"green\"]}}],\n                    meta={},\n                    tags=[\"a\", \"b\"],\n                ),\n            ],\n            docs=Docs(show=False),\n            versions=[UnparsedVersion(v=2)],\n        )\n        dct = {\n            \"name\": \"foo\",\n            \"yaml_key\": \"models\",\n            \"original_file_path\": \"/some/fake/path\",\n            \"package_name\": \"test\",\n            \"description\": \"a description\",\n            \"data_tests\": [\"table_test\"],\n            \"tests\": [],\n            \"meta\": {\"key\": [\"value1\", \"value2\"]},\n            \"constraints\": [],\n            \"versions\": [\n                {\n                    \"v\": 2,\n                    \"description\": \"\",\n                    \"columns\": [],\n                    \"config\": {},\n                    \"constraints\": [],\n                    \"docs\": {\"show\": True},\n                }\n            ],\n            \"columns\": [\n                {\n                    \"name\": \"x\",\n                    \"description\": \"x description\",\n                    \"docs\": {\"show\": True},\n                    \"data_tests\": [],\n                    \"tests\": [],\n                    \"meta\": {\"key2\": \"value3\"},\n                    \"tags\": [],\n                    \"constraints\": [],\n                    \"config\": {},\n                },\n                {\n                    \"name\": \"y\",\n                    \"description\": \"y description\",\n                    \"docs\": {\"show\": True},\n                    \"data_tests\": [\"unique\", {\"accepted_values\": {\"values\": [\"blue\", \"green\"]}}],\n                    \"tests\": [],\n                    \"meta\": {},\n                    \"tags\": [\"a\", \"b\"],\n                    \"constraints\": [],\n                    \"config\": {},\n                },\n            ],\n            \"docs\": {\"show\": False},\n            \"config\": {},\n        }\n        self.assert_symmetric(update, dct)\n        pickle.loads(pickle.dumps(update))\n\n    def test_bad_test_type(self):\n        dct = {\n            \"name\": \"foo\",\n            \"yaml_key\": \"models\",\n            \"original_file_path\": \"/some/fake/path\",\n            \"package_name\": \"test\",\n            \"description\": \"a description\",\n            \"data_tests\": [\"table_test\"],\n            \"tests\": [],\n            \"meta\": {\"key\": [\"value1\", \"value2\"]},\n            \"columns\": [\n                {\n                    \"name\": \"x\",\n                    \"description\": \"x description\",\n                    \"docs\": {\"show\": True},\n                    \"data_tests\": [],\n                    \"tests\": [],\n                    \"meta\": {\"key2\": \"value3\"},\n                },\n                {\n                    \"name\": \"y\",\n                    \"description\": \"y description\",\n                    \"docs\": {\"show\": True},\n                    \"data_tests\": [100, {\"accepted_values\": {\"values\": [\"blue\", \"green\"]}}],\n                    \"tests\": [],\n                    \"meta\": {},\n                    \"yaml_key\": \"models\",\n                    \"original_file_path\": \"/some/fake/path\",\n                },\n            ],\n            \"docs\": {\"show\": True},\n        }\n        self.assert_fails_validation(dct)\n\n        dct = {\n            \"name\": \"foo\",\n            \"yaml_key\": \"models\",\n            \"original_file_path\": \"/some/fake/path\",\n            \"package_name\": \"test\",\n            \"description\": \"a description\",\n            \"data_tests\": [\"table_test\"],\n            \"tests\": [],\n            \"meta\": {\"key\": [\"value1\", \"value2\"]},\n            \"columns\": [\n                # column missing a name\n                {\n                    \"description\": \"x description\",\n                    \"docs\": {\"show\": True},\n                    \"data_tests\": [],\n                    \"tests\": [],\n                    \"meta\": {\"key2\": \"value3\"},\n                },\n                {\n                    \"name\": \"y\",\n                    \"description\": \"y description\",\n                    \"docs\": {\"show\": True},\n                    \"data_tests\": [\"unique\", {\"accepted_values\": {\"values\": [\"blue\", \"green\"]}}],\n                    \"tests\": [],\n                    \"meta\": {},\n                    \"yaml_key\": \"models\",\n                    \"original_file_path\": \"/some/fake/path\",\n                },\n            ],\n            \"docs\": {\"show\": True},\n        }\n        self.assert_fails_validation(dct)\n\n        # missing a name\n        dct = {\n            \"yaml_key\": \"models\",\n            \"original_file_path\": \"/some/fake/path\",\n            \"package_name\": \"test\",\n            \"description\": \"a description\",\n            \"data_tests\": [\"table_test\"],\n            \"tests\": [],\n            \"meta\": {\"key\": [\"value1\", \"value2\"]},\n            \"columns\": [\n                {\n                    \"name\": \"x\",\n                    \"description\": \"x description\",\n                    \"docs\": {\"show\": True},\n                    \"data_tests\": [],\n                    \"tests\": [],\n                    \"meta\": {\"key2\": \"value3\"},\n                },\n                {\n                    \"name\": \"y\",\n                    \"description\": \"y description\",\n                    \"docs\": {\"show\": True},\n                    \"data_tests\": [\"unique\", {\"accepted_values\": {\"values\": [\"blue\", \"green\"]}}],\n                    \"tests\": [],\n                    \"meta\": {},\n                    \"yaml_key\": \"models\",\n                    \"original_file_path\": \"/some/fake/path\",\n                },\n            ],\n            \"docs\": {\"show\": True},\n        }\n        self.assert_fails_validation(dct)\n\n\nclass TestUnparsedExposure(ContractTestCase):\n    ContractType = UnparsedExposure\n\n    def get_ok_dict(self):\n        return {\n            \"name\": \"my_exposure\",\n            \"type\": \"dashboard\",\n            \"owner\": {\"name\": \"example\", \"email\": \"name@example.com\", \"slack\": \"#channel\"},\n            \"maturity\": \"medium\",\n            \"meta\": {\"tool\": \"my_tool\"},\n            \"tags\": [\"my_department\"],\n            \"url\": \"https://example.com/dashboards/1\",\n            \"description\": \"A exposure\",\n            \"config\": {},\n            \"depends_on\": [\n                'ref(\"my_model\")',\n                'source(\"raw\", \"source_table\")',\n            ],\n        }\n\n    def test_ok(self):\n        exposure = self.ContractType(\n            name=\"my_exposure\",\n            type=ExposureType.Dashboard,\n            owner=Owner(name=\"example\", email=\"name@example.com\", _extra={\"slack\": \"#channel\"}),\n            maturity=MaturityType.Medium,\n            url=\"https://example.com/dashboards/1\",\n            description=\"A exposure\",\n            config={},\n            meta={\"tool\": \"my_tool\"},\n            tags=[\"my_department\"],\n            depends_on=['ref(\"my_model\")', 'source(\"raw\", \"source_table\")'],\n        )\n        dct = self.get_ok_dict()\n        self.assert_symmetric(exposure, dct)\n        pickle.loads(pickle.dumps(exposure))\n\n    def test_ok_exposures(self):\n        for exposure_allowed in (\"dashboard\", \"notebook\", \"analysis\", \"ml\", \"application\"):\n            tst = self.get_ok_dict()\n            tst[\"type\"] = exposure_allowed\n            assert self.ContractType.from_dict(tst).type == exposure_allowed\n\n    def test_bad_exposure(self):\n        # bad exposure: None isn't allowed\n        for exposure_not_allowed in (None, \"not an exposure\"):\n            tst = self.get_ok_dict()\n            tst[\"type\"] = exposure_not_allowed\n            self.assert_fails_validation(tst)\n\n    def test_no_exposure(self):\n        tst = self.get_ok_dict()\n        del tst[\"type\"]\n        self.assert_fails_validation(tst)\n\n    def test_ok_maturities(self):\n        for maturity_allowed in (None, \"low\", \"medium\", \"high\"):\n            tst = self.get_ok_dict()\n            tst[\"maturity\"] = maturity_allowed\n            assert self.ContractType.from_dict(tst).maturity == maturity_allowed\n\n        tst = self.get_ok_dict()\n        del tst[\"maturity\"]\n        assert self.ContractType.from_dict(tst).maturity is None\n\n    def test_bad_maturity(self):\n        tst = self.get_ok_dict()\n        tst[\"maturity\"] = \"invalid maturity\"\n        self.assert_fails_validation(tst)\n\n    def test_bad_owner_missing_things(self):\n        tst = self.get_ok_dict()\n        del tst[\"owner\"][\"email\"]\n        del tst[\"owner\"][\"name\"]\n        self.assert_fails_validation(tst)\n\n        del tst[\"owner\"]\n        self.assert_fails_validation(tst)\n\n    def test_bad_tags(self):\n        tst = self.get_ok_dict()\n        tst[\"tags\"] = [123]\n        self.assert_fails_validation(tst)\n\n\nclass TestUnparsedConversionTypeParams(ContractTestCase):\n    \"\"\"Only Applies to v1 Semantic Metrics.\"\"\"\n\n    ContractType = UnparsedConversionTypeParams\n\n    def get_old_style_ok_dict(self):\n        return {\n            \"entity\": \"customers\",\n            \"base_measure\": {\n                \"name\": \"customers\",\n                \"filter\": \"is_new = true\",\n                \"join_to_timespine\": False,\n            },\n            \"conversion_measure\": \"orders\",\n            \"calculation\": \"conversion_rate\",\n            \"window\": \"7d\",\n        }\n\n    def test_old_style_ok(self):\n        params = self.ContractType.from_dict(self.get_old_style_ok_dict())\n        assert params.base_measure is not None\n        assert params.conversion_measure is not None\n        assert params.calculation == ConversionCalculationType.CONVERSION_RATE.value\n        assert params.window == \"7d\"\n\n    def test_old_style_bad_no_base_measure(self):\n        tst = self.get_old_style_ok_dict()\n        del tst[\"base_measure\"]\n        self.assert_fails_validation(tst)\n\n    def test_old_style_bad_no_conversion_measure(self):\n        tst = self.get_old_style_ok_dict()\n        del tst[\"conversion_measure\"]\n        self.assert_fails_validation(tst)\n\n\nclass BaseTestUnparsedMetric:\n\n    @abstractmethod\n    def get_ok_dict(self) -> Dict[str, Any]:\n        raise NotImplementedError()\n\n    def test_bad_tags(self):\n        tst = self.get_ok_dict()\n        tst[\"tags\"] = [123]\n        self.assert_fails_validation(tst)\n\n    def test_bad_metric_name_with_spaces(self):\n        tst = self.get_ok_dict()\n        tst[\"name\"] = \"metric name with spaces\"\n        self.assert_fails_validation(tst)\n\n    def test_bad_metric_name_too_long(self):\n        tst = self.get_ok_dict()\n        tst[\"name\"] = \"a\" * 251\n        self.assert_fails_validation(tst)\n\n    def test_bad_metric_name_does_not_start_with_letter(self):\n        tst = self.get_ok_dict()\n        tst[\"name\"] = \"123metric\"\n        self.assert_fails_validation(tst)\n\n        tst[\"name\"] = \"_metric\"\n        self.assert_fails_validation(tst)\n\n    def test_bad_metric_name_contains_special_characters(self):\n        tst = self.get_ok_dict()\n        tst[\"name\"] = \"metric!name\"\n        self.assert_fails_validation(tst)\n\n        tst[\"name\"] = \"metric@name\"\n        self.assert_fails_validation(tst)\n\n        tst[\"name\"] = \"metric#name\"\n        self.assert_fails_validation(tst)\n\n        tst[\"name\"] = \"metric$name\"\n        self.assert_fails_validation(tst)\n\n        tst[\"name\"] = \"metric-name\"\n        self.assert_fails_validation(tst)\n\n\nclass TestUnparsedMetric(BaseTestUnparsedMetric, ContractTestCase):\n    ContractType = UnparsedMetric\n\n    @override\n    def get_ok_dict(self):\n        return {\n            \"name\": \"new_customers\",\n            \"label\": \"New Customers\",\n            \"description\": \"New customers\",\n            \"type\": \"simple\",\n            \"type_params\": {\n                \"measure\": {\n                    \"name\": \"customers\",\n                    \"filter\": \"is_new = true\",\n                    \"join_to_timespine\": False,\n                },\n            },\n            \"config\": {},\n            \"tags\": [],\n            \"meta\": {\"is_okr\": True},\n        }\n\n    def test_ok(self):\n        metric = self.ContractType(\n            name=\"new_customers\",\n            label=\"New Customers\",\n            description=\"New customers\",\n            type=\"simple\",\n            type_params=UnparsedMetricTypeParams(\n                measure=UnparsedMetricInputMeasure(\n                    name=\"customers\",\n                    filter=\"is_new = true\",\n                )\n            ),\n            config={},\n            meta={\"is_okr\": True},\n        )\n        dct = self.get_ok_dict()\n        self.assert_symmetric(metric, dct)\n        pickle.loads(pickle.dumps(metric))\n\n    def test_bad_metric_no_type_params(self):\n        tst = self.get_ok_dict()\n        del tst[\"type_params\"]\n        self.assert_fails_validation(tst)\n\n\nclass TestUnparsedMetricV2(BaseTestUnparsedMetric, ContractTestCase):\n    ContractType = UnparsedMetricV2\n\n    @override\n    def get_ok_dict(self):\n        return {\n            \"name\": \"new_customers\",\n            \"label\": \"New Customers\",\n            \"description\": \"New customers\",\n            \"type\": \"simple\",\n            \"agg\": \"sum\",\n            \"filter\": \"is_new = true\",\n            \"join_to_timespine\": False,\n            \"config\": {\n                \"tags\": [],\n                \"meta\": {\"is_okr\": True},\n            },\n        }\n\n    def get_ok_dict_with_defaults(self):\n        dct = self.get_ok_dict()\n        dct[\"hidden\"] = False\n        dct[\"period_agg\"] = \"first\"\n        return dct\n\n    def test_ok(self):\n        metric = self.ContractType(\n            name=\"new_customers\",\n            label=\"New Customers\",\n            description=\"New customers\",\n            agg=\"sum\",\n            filter=\"is_new = true\",\n            join_to_timespine=False,\n            config={\n                \"tags\": [],\n                \"meta\": {\"is_okr\": True},\n            },\n        )\n        dct = self.get_ok_dict()\n        # add defaults:\n        dct[\"hidden\"] = False\n        dct[\"period_agg\"] = \"first\"\n        self.assert_symmetric(metric, dct)\n        pickle.loads(pickle.dumps(metric))\n\n    def test_simple_metric_with_no_agg_fails_validation(self):\n        tst = self.get_ok_dict_with_defaults()\n        del tst[\"agg\"]\n        self.assert_fails_validation(tst)\n\n\nclass TestUnparsedVersion(ContractTestCase):\n    ContractType = UnparsedVersion\n\n    def get_ok_dict(self):\n        return {\n            \"v\": 2,\n            \"defined_in\": \"test_defined_in\",\n            \"description\": \"A version\",\n            \"config\": {},\n            \"constraints\": [],\n            \"docs\": {\"show\": False},\n            \"data_tests\": [],\n            \"columns\": [],\n        }\n\n    def test_ok(self):\n        version = self.ContractType(\n            v=2,\n            defined_in=\"test_defined_in\",\n            description=\"A version\",\n            config={},\n            constraints=[],\n            docs=Docs(show=False),\n            data_tests=[],\n            columns=[],\n        )\n        dct = self.get_ok_dict()\n        self.assert_symmetric(version, dct)\n        pickle.loads(pickle.dumps(version))\n\n    def test_bad_version_no_v(self):\n        version = self.get_ok_dict()\n        del version[\"v\"]\n        self.assert_fails_validation(version)\n\n\n@pytest.mark.parametrize(\n    \"left,right,expected_lt\",\n    [\n        # same types\n        (2, 12, True),\n        (12, 2, False),\n        (\"a\", \"b\", True),\n        (\"b\", \"a\", False),\n        # mismatched types - numeric\n        (2, 12.0, True),\n        (12.0, 2, False),\n        (2, \"12\", True),\n        (\"12\", 2, False),\n        # mismatched types\n        (1, \"test\", True),\n        (\"test\", 1, False),\n    ],\n)\ndef test_unparsed_version_lt(left, right, expected_lt):\n    assert (UnparsedVersion(left) < UnparsedVersion(right)) == expected_lt\n\n\ndef test_column_parse():\n    unparsed_col = HasColumnTests(\n        columns=[UnparsedColumn(name=\"TestCol\", constraints=[{\"type\": \"!INVALID!\"}])]\n    )\n\n    with pytest.raises(ParsingError):\n        ParserRef.from_target(unparsed_col)\n\n\nclass TestUnparsedColumnTimeDimensionGranularityValidation(ContractTestCase):\n    \"\"\"Test validation that SL YAML V2 column with time dimension must specify granularity,\n    and that dimension validity_params require granularity.\"\"\"\n\n    ContractType = UnparsedColumn\n\n    def test_time_dimension_without_granularity_fails_validation(self):\n        column_dict = {\n            \"name\": \"created_at\",\n            \"dimension\": {\"type\": \"time\", \"name\": \"created_at_dim\"},\n        }\n        self.assert_fails_validation(column_dict)\n\n    def test_time_dimension_with_granularity_passes_validation(self):\n        column_dict = {\n            \"name\": \"created_at\",\n            \"granularity\": \"day\",\n            \"dimension\": {\"type\": \"time\", \"name\": \"created_at_dim\"},\n        }\n        col = self.ContractType.from_dict(column_dict)\n        self.assertEqual(col.granularity, \"day\")\n        self.assertEqual(col.name, \"created_at\")\n\n    def test_time_dimension_string_without_granularity_fails_validation(self):\n        \"\"\"Dimension as string 'time' without granularity must fail.\"\"\"\n        column_dict = {\n            \"name\": \"created_at\",\n            \"dimension\": \"time\",\n        }\n        self.assert_fails_validation(column_dict)\n\n    def test_time_dimension_string_with_granularity_passes_validation(self):\n        \"\"\"Dimension as string 'time' with granularity must pass.\"\"\"\n        column_dict = {\n            \"name\": \"created_at\",\n            \"granularity\": \"day\",\n            \"dimension\": \"time\",\n        }\n        col = self.ContractType.from_dict(column_dict)\n        self.assertEqual(col.granularity, \"day\")\n        self.assertEqual(col.name, \"created_at\")\n\n    def test_non_time_dimension_string_passes_without_granularity(self):\n        \"\"\"Dimension as string (e.g. categorical) does not require granularity.\"\"\"\n        column_dict = {\n            \"name\": \"category\",\n            \"dimension\": \"categorical\",\n        }\n        col = self.ContractType.from_dict(column_dict)\n        self.assertEqual(col.name, \"category\")\n        self.assertIsNone(col.granularity)\n\n    def test_dimension_with_validity_params_without_granularity_fails_validation(self):\n        \"\"\"Dimension (dict) with validity_params must have column granularity.\"\"\"\n        column_dict = {\n            \"name\": \"valid_from\",\n            \"dimension\": {\n                \"type\": \"time\",\n                \"name\": \"valid_from_dim\",\n                \"validity_params\": {\"is_start\": True, \"is_end\": False},\n            },\n        }\n        self.assert_fails_validation(column_dict)\n\n    def test_dimension_with_validity_params_with_granularity_passes_validation(self):\n        \"\"\"Dimension (dict) with validity_params and granularity passes.\"\"\"\n        column_dict = {\n            \"name\": \"valid_from\",\n            \"granularity\": \"day\",\n            \"dimension\": {\n                \"type\": \"time\",\n                \"name\": \"valid_from_dim\",\n                \"validity_params\": {\"is_start\": True, \"is_end\": True},\n            },\n        }\n        col = self.ContractType.from_dict(column_dict)\n        self.assertEqual(col.granularity, \"day\")\n        self.assertEqual(col.name, \"valid_from\")\n\n    def test_dimension_without_validity_params_passes_without_granularity_when_not_time(self):\n        \"\"\"Dimension (dict) without validity_params and not time does not require granularity.\"\"\"\n        column_dict = {\n            \"name\": \"category\",\n            \"dimension\": {\"type\": \"categorical\", \"name\": \"category_dim\"},\n        }\n        col = self.ContractType.from_dict(column_dict)\n        self.assertEqual(col.name, \"category\")\n        self.assertIsNone(col.granularity)\n\n\nclass TestUnparsedDerivedDimensionV2ValidityParamsValidation(ContractTestCase):\n    \"\"\"Test validation that UnparsedDerivedDimensionV2 only has validity_params when it has granularity.\"\"\"\n\n    ContractType = UnparsedDerivedDimensionV2\n\n    def test_derived_dimension_with_validity_params_without_granularity_fails_validation(self):\n        \"\"\"Derived dimension with validity_params must have granularity.\"\"\"\n        dimension_dict = {\n            \"type\": \"time\",\n            \"name\": \"valid_from_dim\",\n            \"expr\": \"valid_from\",\n            \"validity_params\": {\"is_start\": True, \"is_end\": False},\n        }\n        self.assert_fails_validation(dimension_dict)\n\n    def test_derived_dimension_with_validity_params_with_granularity_passes_validation(self):\n        \"\"\"Derived dimension with validity_params and granularity passes.\"\"\"\n        dimension_dict = {\n            \"type\": \"time\",\n            \"name\": \"valid_from_dim\",\n            \"expr\": \"valid_from\",\n            \"granularity\": \"day\",\n            \"validity_params\": {\"is_start\": True, \"is_end\": True},\n        }\n        dim = self.ContractType.from_dict(dimension_dict)\n        self.assertEqual(dim.granularity, \"day\")\n        self.assertEqual(dim.name, \"valid_from_dim\")\n\n    def test_derived_dimension_without_validity_params_passes_without_granularity(self):\n        \"\"\"Derived dimension without validity_params does not require granularity.\"\"\"\n        dimension_dict = {\n            \"type\": \"time\",\n            \"name\": \"some_dim\",\n            \"expr\": \"some_column\",\n        }\n        dim = self.ContractType.from_dict(dimension_dict)\n        self.assertEqual(dim.name, \"some_dim\")\n        self.assertIsNone(dim.granularity)\n"
  },
  {
    "path": "tests/unit/contracts/test_project.py",
    "content": "from dbt.contracts.project import Project\nfrom dbt_common.dataclass_schema import ValidationError\nfrom tests.unit.utils import ContractTestCase\n\n\nclass TestProject(ContractTestCase):\n    ContractType = Project\n\n    def test_minimal(self):\n        dct = {\n            \"name\": \"test\",\n            \"version\": \"1.0\",\n            \"profile\": \"test\",\n            \"project-root\": \"/usr/src/app\",\n            \"config-version\": 2,\n        }\n        project = self.ContractType(\n            name=\"test\",\n            version=\"1.0\",\n            profile=\"test\",\n            project_root=\"/usr/src/app\",\n            config_version=2,\n        )\n        self.assert_from_dict(project, dct)\n\n    def test_invalid_name(self):\n        dct = {\n            \"name\": \"log\",\n            \"version\": \"1.0\",\n            \"profile\": \"test\",\n            \"project-root\": \"/usr/src/app\",\n            \"config-version\": 2,\n        }\n        with self.assertRaises(ValidationError):\n            self.ContractType.validate(dct)\n"
  },
  {
    "path": "tests/unit/deps/__init__.py",
    "content": ""
  },
  {
    "path": "tests/unit/deps/test_deps.py",
    "content": "import unittest\nfrom argparse import Namespace\nfrom copy import deepcopy\nfrom unittest import mock\n\nimport dbt.deps\nimport dbt.exceptions\nfrom dbt.clients.registry import is_compatible_version\nfrom dbt.config.project import PartialProject\nfrom dbt.config.renderer import DbtProjectYamlRenderer\nfrom dbt.contracts.project import (\n    GitPackage,\n    LocalPackage,\n    PackageConfig,\n    RegistryPackage,\n    TarballPackage,\n)\nfrom dbt.deps.git import GitUnpinnedPackage\nfrom dbt.deps.local import LocalPinnedPackage, LocalUnpinnedPackage\nfrom dbt.deps.registry import RegistryUnpinnedPackage\nfrom dbt.deps.resolver import resolve_packages\nfrom dbt.deps.tarball import TarballUnpinnedPackage\nfrom dbt.flags import set_from_args\nfrom dbt.task.deps import DepsTask\nfrom dbt.version import get_installed_version\nfrom dbt_common.dataclass_schema import ValidationError\nfrom dbt_common.semver import VersionSpecifier\n\nset_from_args(Namespace(WARN_ERROR=False), None)\n\n\nclass TestLocalPackage(unittest.TestCase):\n    def test_init(self):\n        a_contract = LocalPackage.from_dict({\"local\": \"/path/to/package\"})\n        self.assertEqual(a_contract.local, \"/path/to/package\")\n        a = LocalUnpinnedPackage.from_contract(a_contract)\n        self.assertEqual(a.local, \"/path/to/package\")\n        a_pinned = a.resolved()\n        self.assertEqual(a_pinned.local, \"/path/to/package\")\n        self.assertEqual(str(a_pinned), \"/path/to/package\")\n\n\nclass TestTarballPackage(unittest.TestCase):\n    class MockMetadata:\n        name = \"mock_metadata_name\"\n\n    @mock.patch(\"dbt.config.project.PartialProject.from_project_root\")\n    @mock.patch(\"os.listdir\")\n    @mock.patch(\"dbt.deps.tarball.get_downloads_path\")\n    @mock.patch(\"dbt_common.clients.system.untar_package\")\n    @mock.patch(\"dbt_common.clients.system.download\")\n    def test_fetch_metadata(\n        self,\n        mock_download,\n        mock_untar_package,\n        mock_get_downloads_path,\n        mock_listdir,\n        mock_from_project_root,\n    ):\n        mock_listdir.return_value = [\"one_directory/\"]\n        mock_get_downloads_path.return_value = \"downloads_path\"\n        mock_from_project_root.return_value = object()\n        mock_from_project_root.return_value\n        dict_well_formed_contract = {\n            \"tarball\": \"http://example.com/invalid_url@/package.tar.gz\",\n            \"name\": \"my_package\",\n        }\n\n        a_contract = TarballPackage.from_dict(dict_well_formed_contract)\n        a = TarballUnpinnedPackage.from_contract(a_contract)\n\n        a_pinned = a.resolved()\n        with mock.patch.object(PartialProject, \"from_project_root\", return_value=PartialProject):\n            with mock.patch.object(\n                PartialProject, \"render_package_metadata\", return_value=self.MockMetadata\n            ):\n                metadata = a_pinned.fetch_metadata(\"\", DbtProjectYamlRenderer())\n\n        assert metadata == self.MockMetadata\n        mock_download.assert_called_once_with(\n            \"http://example.com/invalid_url@/package.tar.gz\", \"downloads_path/my_package\"\n        )\n        mock_untar_package.assert_called_once_with(\n            \"downloads_path/my_package\", \"downloads_path/my_package_untarred\", \"my_package\"\n        )\n\n    @mock.patch(\"dbt.config.project.PartialProject.from_project_root\")\n    @mock.patch(\"os.listdir\")\n    @mock.patch(\"dbt.deps.tarball.get_downloads_path\")\n    @mock.patch(\"dbt_common.clients.system.untar_package\")\n    @mock.patch(\"dbt_common.clients.system.download\")\n    def test_fetch_metadata_fails_on_incorrect_tar_folder_structure(\n        self,\n        mock_download,\n        mock_untar_package,\n        mock_get_downloads_path,\n        mock_listdir,\n        mock_from_project_root,\n    ):\n        mock_listdir.return_value = [\"one_directory/\", \"another_directory/\"]\n\n        mock_get_downloads_path.return_value = \"downloads_path\"\n        mock_from_project_root.return_value = object()\n        mock_from_project_root.return_value\n        dict_well_formed_contract = {\n            \"tarball\": \"http://example.com/invalid_url@/package.tar.gz\",\n            \"name\": \"my_package\",\n        }\n\n        a_contract = TarballPackage.from_dict(dict_well_formed_contract)\n        a = TarballUnpinnedPackage.from_contract(a_contract)\n\n        a_pinned = a.resolved()\n        with mock.patch.object(PartialProject, \"from_project_root\", return_value=PartialProject):\n            with mock.patch.object(\n                PartialProject, \"render_package_metadata\", return_value=self.MockMetadata\n            ):\n                with self.assertRaises(dbt.exceptions.DependencyError):\n                    a_pinned.fetch_metadata(\"\", DbtProjectYamlRenderer())\n\n    @mock.patch(\"dbt.deps.tarball.get_downloads_path\")\n    def test_tarball_package_contract(self, mock_get_downloads_path):\n        dict_well_formed_contract = {\n            \"tarball\": \"http://example.com/invalid_url@/package.tar.gz\",\n            \"name\": \"my_cool_package\",\n        }\n        a_contract = TarballPackage.from_dict(dict_well_formed_contract)\n\n        # check contract and resolver\n        self.assertEqual(a_contract.tarball, \"http://example.com/invalid_url@/package.tar.gz\")\n        self.assertEqual(a_contract.name, \"my_cool_package\")\n\n        a = TarballUnpinnedPackage.from_contract(a_contract)\n        self.assertEqual(a.tarball, \"http://example.com/invalid_url@/package.tar.gz\")\n        self.assertEqual(a.package, \"my_cool_package\")\n\n        a_pinned = a.resolved()\n        self.assertEqual(a_pinned.source_type(), \"tarball\")\n\n        a_pinned_dict = a_pinned.to_dict()\n        self.assertEqual(\n            a_pinned_dict,\n            {\n                \"tarball\": \"http://example.com/invalid_url@/package.tar.gz\",\n                \"name\": \"my_cool_package\",\n            },\n        )\n\n    @mock.patch(\"dbt.deps.tarball.get_downloads_path\")\n    def test_tarball_pinned_package_contract_with_unrendered(self, mock_get_downloads_path):\n        contract = TarballPackage(\n            tarball=\"http://example.com/invalid_url@/package.tar.gz\",\n            name=\"my_cool_package\",\n            unrendered={\"tarball\": \"tarball_unrendered\"},\n        )\n        tarball_unpinned_package = TarballUnpinnedPackage.from_contract(contract)\n\n        self.assertEqual(\n            tarball_unpinned_package.tarball, \"http://example.com/invalid_url@/package.tar.gz\"\n        )\n        self.assertEqual(tarball_unpinned_package.package, \"my_cool_package\")\n        self.assertEqual(tarball_unpinned_package.tarball_unrendered, \"tarball_unrendered\")\n\n        tarball_pinned_package = tarball_unpinned_package.resolved()\n        tarball_unpinned_package_dict = tarball_pinned_package.to_dict()\n        self.assertEqual(\n            tarball_unpinned_package_dict,\n            {\"tarball\": \"tarball_unrendered\", \"name\": \"my_cool_package\"},\n        )\n\n    def test_tarball_package_contract_fails_on_no_name(self):\n        from mashumaro.exceptions import MissingField\n\n        # check bad contract (no name) fails\n        a_contract = {\"tarball\": \"http://example.com\"}\n        with self.assertRaises(MissingField):\n            TarballPackage.from_dict(a_contract)\n\n\nclass TestGitPackage(unittest.TestCase):\n    def test_init(self):\n        a_contract = GitPackage.from_dict(\n            {\"git\": \"http://example.com\", \"revision\": \"0.0.1\"},\n        )\n        self.assertEqual(a_contract.git, \"http://example.com\")\n        self.assertEqual(a_contract.revision, \"0.0.1\")\n        self.assertIs(a_contract.warn_unpinned, None)\n\n        a = GitUnpinnedPackage.from_contract(a_contract)\n        self.assertEqual(a.git, \"http://example.com\")\n        self.assertEqual(a.revisions, [\"0.0.1\"])\n        self.assertIs(a.warn_unpinned, True)\n\n        a_pinned = a.resolved()\n        self.assertEqual(a_pinned.name, \"http://example.com\")\n        self.assertEqual(a_pinned.get_version(), \"0.0.1\")\n        self.assertEqual(a_pinned.source_type(), \"git\")\n        self.assertIs(a_pinned.warn_unpinned, True)\n\n        a_pinned_dict = a_pinned.to_dict()\n        self.assertEqual(a_pinned_dict, {\"git\": \"http://example.com\", \"revision\": \"0.0.1\"})\n\n    def test_init_with_unrendered(self):\n        contract = GitPackage(\n            git=\"http://example.com\", revision=\"0.0.1\", unrendered={\"git\": \"git_unrendered\"}\n        )\n\n        git_unpinned_package = GitUnpinnedPackage.from_contract(contract)\n        self.assertEqual(git_unpinned_package.git, \"http://example.com\")\n        self.assertEqual(git_unpinned_package.revisions, [\"0.0.1\"])\n        self.assertIs(git_unpinned_package.git_unrendered, \"git_unrendered\")\n\n        git_pinned_package = git_unpinned_package.resolved()\n        git_pinned_package_dict = git_pinned_package.to_dict()\n        self.assertEqual(git_pinned_package_dict, {\"git\": \"git_unrendered\", \"revision\": \"0.0.1\"})\n\n    @mock.patch(\"shutil.copytree\")\n    @mock.patch(\"dbt.deps.local.system.make_symlink\")\n    @mock.patch(\"dbt.deps.local.LocalPinnedPackage.get_installation_path\")\n    @mock.patch(\"dbt.deps.local.LocalPinnedPackage.resolve_path\")\n    def test_deps_install(\n        self, mock_resolve_path, mock_get_installation_path, mock_symlink, mock_shutil\n    ):\n        mock_resolve_path.return_value = \"/tmp/source\"\n        mock_get_installation_path.return_value = \"/tmp/dest\"\n        mock_symlink.side_effect = OSError(\"Install deps symlink error\")\n\n        LocalPinnedPackage(\"local\").install(\"dummy\", \"dummy\")\n        self.assertEqual(mock_shutil.call_count, 1)\n        mock_shutil.assert_called_once_with(\"/tmp/source\", \"/tmp/dest\")\n\n    def test_invalid(self):\n        with self.assertRaises(ValidationError):\n            GitPackage.validate(\n                {\"git\": \"http://example.com\", \"version\": \"0.0.1\"},\n            )\n\n    def test_resolve_ok(self):\n        a_contract = GitPackage.from_dict(\n            {\"git\": \"http://example.com\", \"revision\": \"0.0.1\"},\n        )\n        b_contract = GitPackage.from_dict(\n            {\"git\": \"http://example.com\", \"revision\": \"0.0.1\", \"warn-unpinned\": False},\n        )\n        d_contract = GitPackage.from_dict(\n            {\"git\": \"http://example.com\", \"revision\": \"0.0.1\", \"subdirectory\": \"foo-bar\"},\n        )\n        a = GitUnpinnedPackage.from_contract(a_contract)\n        b = GitUnpinnedPackage.from_contract(b_contract)\n        c = a.incorporate(b)\n        d = GitUnpinnedPackage.from_contract(d_contract)\n\n        self.assertTrue(a.warn_unpinned)\n        self.assertFalse(b.warn_unpinned)\n        self.assertTrue(d.warn_unpinned)\n\n        c_pinned = c.resolved()\n        self.assertEqual(c_pinned.name, \"http://example.com\")\n        self.assertEqual(c_pinned.get_version(), \"0.0.1\")\n        self.assertEqual(c_pinned.source_type(), \"git\")\n        self.assertFalse(c_pinned.warn_unpinned)\n\n        d_pinned = d.resolved()\n        self.assertEqual(d_pinned.name, \"http://example.com/foo-bar\")\n        self.assertEqual(d_pinned.get_version(), \"0.0.1\")\n        self.assertEqual(d_pinned.source_type(), \"git\")\n        self.assertEqual(d_pinned.subdirectory, \"foo-bar\")\n\n    def test_resolve_fail(self):\n        a_contract = GitPackage.from_dict(\n            {\"git\": \"http://example.com\", \"revision\": \"0.0.1\"},\n        )\n        b_contract = GitPackage.from_dict(\n            {\"git\": \"http://example.com\", \"revision\": \"0.0.2\"},\n        )\n        a = GitUnpinnedPackage.from_contract(a_contract)\n        b = GitUnpinnedPackage.from_contract(b_contract)\n        c = a.incorporate(b)\n        self.assertEqual(c.git, \"http://example.com\")\n        self.assertEqual(c.revisions, [\"0.0.1\", \"0.0.2\"])\n\n        with self.assertRaises(dbt.exceptions.DependencyError):\n            c.resolved()\n\n    def test_default_revision(self):\n        a_contract = GitPackage.from_dict({\"git\": \"http://example.com\"})\n        self.assertEqual(a_contract.revision, None)\n        self.assertIs(a_contract.warn_unpinned, None)\n\n        a = GitUnpinnedPackage.from_contract(a_contract)\n        self.assertEqual(a.git, \"http://example.com\")\n        self.assertEqual(a.revisions, [])\n        self.assertIs(a.warn_unpinned, True)\n\n        a_pinned = a.resolved()\n        self.assertEqual(a_pinned.name, \"http://example.com\")\n        self.assertEqual(a_pinned.get_version(), \"HEAD\")\n        self.assertEqual(a_pinned.source_type(), \"git\")\n        self.assertIs(a_pinned.warn_unpinned, True)\n\n\nclass TestHubPackage(unittest.TestCase):\n    def setUp(self):\n        self.patcher = mock.patch(\"dbt.deps.registry.registry\")\n        self.registry = self.patcher.start()\n        self.index_cached = self.registry.index_cached\n        self.get_compatible_versions = self.registry.get_compatible_versions\n        self.package_version = self.registry.package_version\n\n        self.index_cached.return_value = [\n            \"dbt-labs-test/a\",\n        ]\n        self.get_compatible_versions.return_value = [\"0.1.2\", \"0.1.3\", \"0.1.4a1\"]\n        self.package_version.return_value = {\n            \"id\": \"dbt-labs-test/a/0.1.2\",\n            \"name\": \"a\",\n            \"version\": \"0.1.2\",\n            \"packages\": [],\n            \"_source\": {\n                \"blahblah\": \"asdfas\",\n            },\n            \"downloads\": {\n                \"tarball\": \"https://example.com/invalid-url!\",\n                \"extra\": \"field\",\n            },\n            \"newfield\": [\"another\", \"value\"],\n        }\n\n    def tearDown(self):\n        self.patcher.stop()\n\n    def test_init(self):\n        a_contract = RegistryPackage(\n            package=\"dbt-labs-test/a\",\n            version=\"0.1.2\",\n        )\n        self.assertEqual(a_contract.package, \"dbt-labs-test/a\")\n        self.assertEqual(a_contract.version, \"0.1.2\")\n\n        a = RegistryUnpinnedPackage.from_contract(a_contract)\n        self.assertEqual(a.package, \"dbt-labs-test/a\")\n        self.assertEqual(\n            a.versions,\n            [\n                VersionSpecifier(\n                    build=None, major=\"0\", matcher=\"=\", minor=\"1\", patch=\"2\", prerelease=None\n                )\n            ],\n        )\n\n        a_pinned = a.resolved()\n        self.assertEqual(a_contract.package, \"dbt-labs-test/a\")\n        self.assertEqual(a_contract.version, \"0.1.2\")\n        self.assertEqual(a_pinned.source_type(), \"hub\")\n\n    def test_invalid(self):\n        with self.assertRaises(ValidationError):\n            RegistryPackage.validate(\n                {\"package\": \"namespace/name\", \"key\": \"invalid\"},\n            )\n\n    def test_resolve_ok(self):\n        a_contract = RegistryPackage(package=\"dbt-labs-test/a\", version=\"0.1.2\")\n        b_contract = RegistryPackage(package=\"dbt-labs-test/a\", version=\"0.1.2\")\n        a = RegistryUnpinnedPackage.from_contract(a_contract)\n        b = RegistryUnpinnedPackage.from_contract(b_contract)\n        c = a.incorporate(b)\n\n        self.assertEqual(c.package, \"dbt-labs-test/a\")\n        self.assertEqual(\n            c.versions,\n            [\n                VersionSpecifier(\n                    build=None,\n                    major=\"0\",\n                    matcher=\"=\",\n                    minor=\"1\",\n                    patch=\"2\",\n                    prerelease=None,\n                ),\n                VersionSpecifier(\n                    build=None,\n                    major=\"0\",\n                    matcher=\"=\",\n                    minor=\"1\",\n                    patch=\"2\",\n                    prerelease=None,\n                ),\n            ],\n        )\n\n        c_pinned = c.resolved()\n        self.assertEqual(c_pinned.package, \"dbt-labs-test/a\")\n        self.assertEqual(c_pinned.version, \"0.1.2\")\n        self.assertEqual(c_pinned.source_type(), \"hub\")\n\n    def test_resolve_missing_package(self):\n        a = RegistryUnpinnedPackage.from_contract(\n            RegistryPackage(package=\"dbt-labs-test/b\", version=\"0.1.2\")\n        )\n        with self.assertRaises(dbt.exceptions.DependencyError) as exc:\n            a.resolved()\n\n        msg = \"Package dbt-labs-test/b was not found in the package index\"\n        self.assertIn(msg, str(exc.exception))\n\n    def test_resolve_missing_version(self):\n        a = RegistryUnpinnedPackage.from_contract(\n            RegistryPackage(package=\"dbt-labs-test/a\", version=\"0.1.4\")\n        )\n\n        with self.assertRaises(dbt.exceptions.DependencyError) as exc:\n            a.resolved()\n\n        # Check that key parts of the error message are present and avoid spacing failures\n        error_msg = str(exc.exception)\n        assert (\n            \"Could not find a matching compatible version for package dbt-labs-test/a\" in error_msg\n        )\n        assert \"Requested range: =0.1.4, =0.1.4\" in error_msg\n        assert \"Compatible versions: ['0.1.2', '0.1.3']\" in error_msg\n\n    def test_resolve_conflict(self):\n        a_contract = RegistryPackage(package=\"dbt-labs-test/a\", version=\"0.1.2\")\n        b_contract = RegistryPackage(package=\"dbt-labs-test/a\", version=\"0.1.3\")\n        a = RegistryUnpinnedPackage.from_contract(a_contract)\n        b = RegistryUnpinnedPackage.from_contract(b_contract)\n        c = a.incorporate(b)\n\n        with self.assertRaises(dbt.exceptions.DependencyError) as exc:\n            c.resolved()\n        msg = (\n            \"Version error for package dbt-labs-test/a: Could not \"\n            \"find a satisfactory version from options: ['=0.1.2', '=0.1.3']\"\n        )\n        self.assertIn(msg, str(exc.exception))\n\n    def test_dependency_error_inherits_from_dbt_runtime_error(self):\n        \"\"\"\n        Test that DependencyError is a DbtRuntimeError (not plain Exception).\n\n        Related to issue #12049 - DependencyError MUST inherit from DbtRuntimeError\n        so that the CLI's exception handler (core/dbt/cli/requires.py line 186)\n        catches it WITHOUT printing Python stack traces.\n\n        The CLI has two exception handlers:\n        - Line 186-188: Catches DbtBaseException -> NO stack trace (desired)\n        - Line 189-192: Catches BaseException -> SHOWS stack trace (undesired)\n\n        If DependencyError inherits from Exception, it's caught by the BaseException\n        handler which prints full stack traces. If it inherits from DbtRuntimeError,\n        it's caught by the DbtBaseException handler which shows clean error messages.\n\n        This is an implementation test (checking inheritance) because the actual\n        behavior (stack trace vs no stack trace) happens in the CLI layer, not here.\n        \"\"\"\n        from dbt_common.exceptions import DbtRuntimeError\n\n        # This is the critical assertion - DependencyError MUST be a DbtRuntimeError\n        self.assertTrue(\n            issubclass(dbt.exceptions.DependencyError, DbtRuntimeError),\n            \"DependencyError must inherit from DbtRuntimeError (not plain Exception) \"\n            \"to avoid stack traces in CLI output. See issue #12049.\",\n        )\n\n        # Verify this applies to actual raised exceptions from version conflicts\n        a_contract = RegistryPackage(package=\"dbt-labs-test/a\", version=\"0.1.2\")\n        b_contract = RegistryPackage(package=\"dbt-labs-test/a\", version=\"0.1.3\")\n        a = RegistryUnpinnedPackage.from_contract(a_contract)\n        b = RegistryUnpinnedPackage.from_contract(b_contract)\n        c = a.incorporate(b)\n\n        with self.assertRaises(dbt.exceptions.DependencyError) as exc:\n            c.resolved()\n\n        # The raised exception instance must be a DbtRuntimeError\n        self.assertIsInstance(\n            exc.exception,\n            DbtRuntimeError,\n            \"Raised DependencyError must be instance of DbtRuntimeError\",\n        )\n\n        # Verify the error message is still clean and user-friendly\n        error_msg = str(exc.exception)\n        self.assertIn(\"Version error for package dbt-labs-test/a\", error_msg)\n        self.assertIn(\"Could not find a satisfactory version\", error_msg)\n\n    def test_resolve_ranges(self):\n        a_contract = RegistryPackage(package=\"dbt-labs-test/a\", version=\"0.1.2\")\n        b_contract = RegistryPackage(package=\"dbt-labs-test/a\", version=\"<0.1.4\")\n        a = RegistryUnpinnedPackage.from_contract(a_contract)\n        b = RegistryUnpinnedPackage.from_contract(b_contract)\n        c = a.incorporate(b)\n\n        self.assertEqual(c.package, \"dbt-labs-test/a\")\n        self.assertEqual(\n            c.versions,\n            [\n                VersionSpecifier(\n                    build=None,\n                    major=\"0\",\n                    matcher=\"=\",\n                    minor=\"1\",\n                    patch=\"2\",\n                    prerelease=None,\n                ),\n                VersionSpecifier(\n                    build=None,\n                    major=\"0\",\n                    matcher=\"<\",\n                    minor=\"1\",\n                    patch=\"4\",\n                    prerelease=None,\n                ),\n            ],\n        )\n\n        c_pinned = c.resolved()\n        self.assertEqual(c_pinned.package, \"dbt-labs-test/a\")\n        self.assertEqual(c_pinned.version, \"0.1.2\")\n        self.assertEqual(c_pinned.source_type(), \"hub\")\n\n    def test_resolve_ranges_install_prerelease_default_false(self):\n        a_contract = RegistryPackage(package=\"dbt-labs-test/a\", version=\">0.1.2\")\n        b_contract = RegistryPackage(package=\"dbt-labs-test/a\", version=\"<0.1.5\")\n        a = RegistryUnpinnedPackage.from_contract(a_contract)\n        b = RegistryUnpinnedPackage.from_contract(b_contract)\n        c = a.incorporate(b)\n\n        self.assertEqual(c.package, \"dbt-labs-test/a\")\n        self.assertEqual(\n            c.versions,\n            [\n                VersionSpecifier(\n                    build=None,\n                    major=\"0\",\n                    matcher=\">\",\n                    minor=\"1\",\n                    patch=\"2\",\n                    prerelease=None,\n                ),\n                VersionSpecifier(\n                    build=None,\n                    major=\"0\",\n                    matcher=\"<\",\n                    minor=\"1\",\n                    patch=\"5\",\n                    prerelease=None,\n                ),\n            ],\n        )\n\n        c_pinned = c.resolved()\n        self.assertEqual(c_pinned.package, \"dbt-labs-test/a\")\n        self.assertEqual(c_pinned.version, \"0.1.3\")\n        self.assertEqual(c_pinned.source_type(), \"hub\")\n\n    def test_resolve_ranges_install_prerelease_true(self):\n        a_contract = RegistryPackage(\n            package=\"dbt-labs-test/a\", version=\">0.1.2\", install_prerelease=True\n        )\n        b_contract = RegistryPackage(package=\"dbt-labs-test/a\", version=\"<0.1.5\")\n        a = RegistryUnpinnedPackage.from_contract(a_contract)\n        b = RegistryUnpinnedPackage.from_contract(b_contract)\n        c = a.incorporate(b)\n\n        self.assertEqual(c.package, \"dbt-labs-test/a\")\n        self.assertEqual(\n            c.versions,\n            [\n                VersionSpecifier(\n                    build=None,\n                    major=\"0\",\n                    matcher=\">\",\n                    minor=\"1\",\n                    patch=\"2\",\n                    prerelease=None,\n                ),\n                VersionSpecifier(\n                    build=None,\n                    major=\"0\",\n                    matcher=\"<\",\n                    minor=\"1\",\n                    patch=\"5\",\n                    prerelease=None,\n                ),\n            ],\n        )\n\n        c_pinned = c.resolved()\n        self.assertEqual(c_pinned.package, \"dbt-labs-test/a\")\n        self.assertEqual(c_pinned.version, \"0.1.4a1\")\n        self.assertEqual(c_pinned.source_type(), \"hub\")\n\n    def test_get_version_latest_prelease_true(self):\n        a_contract = RegistryPackage(\n            package=\"dbt-labs-test/a\", version=\">0.1.0\", install_prerelease=True\n        )\n        b_contract = RegistryPackage(package=\"dbt-labs-test/a\", version=\"<0.1.4\")\n        a = RegistryUnpinnedPackage.from_contract(a_contract)\n        b = RegistryUnpinnedPackage.from_contract(b_contract)\n        c = a.incorporate(b)\n\n        self.assertEqual(c.package, \"dbt-labs-test/a\")\n        self.assertEqual(\n            c.versions,\n            [\n                VersionSpecifier(\n                    build=None,\n                    major=\"0\",\n                    matcher=\">\",\n                    minor=\"1\",\n                    patch=\"0\",\n                    prerelease=None,\n                ),\n                VersionSpecifier(\n                    build=None,\n                    major=\"0\",\n                    matcher=\"<\",\n                    minor=\"1\",\n                    patch=\"4\",\n                    prerelease=None,\n                ),\n            ],\n        )\n\n        c_pinned = c.resolved()\n        self.assertEqual(c_pinned.package, \"dbt-labs-test/a\")\n        self.assertEqual(c_pinned.version, \"0.1.3\")\n        self.assertEqual(c_pinned.get_version_latest(), \"0.1.4a1\")\n        self.assertEqual(c_pinned.source_type(), \"hub\")\n\n    def test_get_version_latest_prelease_false(self):\n        a_contract = RegistryPackage(\n            package=\"dbt-labs-test/a\", version=\">0.1.0\", install_prerelease=False\n        )\n        b_contract = RegistryPackage(package=\"dbt-labs-test/a\", version=\"<0.1.4\")\n        a = RegistryUnpinnedPackage.from_contract(a_contract)\n        b = RegistryUnpinnedPackage.from_contract(b_contract)\n        c = a.incorporate(b)\n\n        self.assertEqual(c.package, \"dbt-labs-test/a\")\n        self.assertEqual(\n            c.versions,\n            [\n                VersionSpecifier(\n                    build=None,\n                    major=\"0\",\n                    matcher=\">\",\n                    minor=\"1\",\n                    patch=\"0\",\n                    prerelease=None,\n                ),\n                VersionSpecifier(\n                    build=None,\n                    major=\"0\",\n                    matcher=\"<\",\n                    minor=\"1\",\n                    patch=\"4\",\n                    prerelease=None,\n                ),\n            ],\n        )\n\n        c_pinned = c.resolved()\n        self.assertEqual(c_pinned.package, \"dbt-labs-test/a\")\n        self.assertEqual(c_pinned.version, \"0.1.3\")\n        self.assertEqual(c_pinned.get_version_latest(), \"0.1.3\")\n        self.assertEqual(c_pinned.source_type(), \"hub\")\n\n    def test_get_version_prerelease_explicitly_requested(self):\n        a_contract = RegistryPackage(\n            package=\"dbt-labs-test/a\", version=\"0.1.4a1\", install_prerelease=None\n        )\n\n        a = RegistryUnpinnedPackage.from_contract(a_contract)\n\n        self.assertEqual(a.package, \"dbt-labs-test/a\")\n        self.assertEqual(\n            a.versions,\n            [\n                VersionSpecifier(\n                    build=None,\n                    major=\"0\",\n                    matcher=\"=\",\n                    minor=\"1\",\n                    patch=\"4\",\n                    prerelease=\"a1\",\n                ),\n            ],\n        )\n\n        a_pinned = a.resolved()\n        self.assertEqual(a_pinned.package, \"dbt-labs-test/a\")\n        self.assertEqual(a_pinned.version, \"0.1.4a1\")\n        self.assertEqual(a_pinned.get_version_latest(), \"0.1.4a1\")\n        self.assertEqual(a_pinned.source_type(), \"hub\")\n\n\nclass MockRegistry:\n    def __init__(self, packages):\n        self.packages = packages\n\n    def index_cached(self, registry_base_url=None):\n        return sorted(self.packages)\n\n    def package(self, package_name, registry_base_url=None):\n        try:\n            pkg = self.packages[package_name]\n        except KeyError:\n            return []\n        return pkg\n\n    def get_compatible_versions(self, package_name, dbt_version, should_version_check):\n        packages = self.package(package_name)\n        return [\n            pkg_version\n            for pkg_version, info in packages.items()\n            if is_compatible_version(info, dbt_version)\n        ]\n\n    def package_version(self, name, version):\n        try:\n            return self.packages[name][version]\n        except KeyError:\n            return None\n\n\nclass TestPackageSpec(unittest.TestCase):\n    def setUp(self):\n        dbt_version = get_installed_version()\n        next_version = deepcopy(dbt_version)\n        next_version.minor = str(int(next_version.minor) + 1)\n        next_version.prerelease = None\n        require_next_version = \">\" + next_version.to_version_string()\n\n        self.patcher = mock.patch(\"dbt.deps.registry.registry\")\n        self.registry = self.patcher.start()\n        self.mock_registry = MockRegistry(\n            packages={\n                \"dbt-labs-test/a\": {\n                    \"0.1.2\": {\n                        \"id\": \"dbt-labs-test/a/0.1.2\",\n                        \"name\": \"a\",\n                        \"version\": \"0.1.2\",\n                        \"packages\": [],\n                        \"_source\": {\n                            \"blahblah\": \"asdfas\",\n                        },\n                        \"downloads\": {\n                            \"tarball\": \"https://example.com/invalid-url!\",\n                            \"extra\": \"field\",\n                        },\n                        \"newfield\": [\"another\", \"value\"],\n                    },\n                    \"0.1.3\": {\n                        \"id\": \"dbt-labs-test/a/0.1.3\",\n                        \"name\": \"a\",\n                        \"version\": \"0.1.3\",\n                        \"packages\": [],\n                        \"_source\": {\n                            \"blahblah\": \"asdfas\",\n                        },\n                        \"downloads\": {\n                            \"tarball\": \"https://example.com/invalid-url!\",\n                            \"extra\": \"field\",\n                        },\n                        \"newfield\": [\"another\", \"value\"],\n                    },\n                    \"0.1.4a1\": {\n                        \"id\": \"dbt-labs-test/a/0.1.3a1\",\n                        \"name\": \"a\",\n                        \"version\": \"0.1.4a1\",\n                        \"packages\": [],\n                        \"_source\": {\n                            \"blahblah\": \"asdfas\",\n                        },\n                        \"downloads\": {\n                            \"tarball\": \"https://example.com/invalid-url!\",\n                            \"extra\": \"field\",\n                        },\n                        \"newfield\": [\"another\", \"value\"],\n                    },\n                    \"0.2.0\": {\n                        \"id\": \"dbt-labs-test/a/0.2.0\",\n                        \"name\": \"a\",\n                        \"version\": \"0.2.0\",\n                        \"packages\": [],\n                        \"_source\": {\n                            \"blahblah\": \"asdfas\",\n                        },\n                        # this one shouldn't be picked!\n                        \"require_dbt_version\": require_next_version,\n                        \"downloads\": {\n                            \"tarball\": \"https://example.com/invalid-url!\",\n                            \"extra\": \"field\",\n                        },\n                        \"newfield\": [\"another\", \"value\"],\n                    },\n                },\n                \"dbt-labs-test/b\": {\n                    \"0.2.1\": {\n                        \"id\": \"dbt-labs-test/b/0.2.1\",\n                        \"name\": \"b\",\n                        \"version\": \"0.2.1\",\n                        \"packages\": [{\"package\": \"dbt-labs-test/a\", \"version\": \">=0.1.3\"}],\n                        \"_source\": {\n                            \"blahblah\": \"asdfas\",\n                        },\n                        \"downloads\": {\n                            \"tarball\": \"https://example.com/invalid-url!\",\n                            \"extra\": \"field\",\n                        },\n                        \"newfield\": [\"another\", \"value\"],\n                    },\n                },\n            }\n        )\n\n        self.registry.index_cached.side_effect = self.mock_registry.index_cached\n        self.registry.get_compatible_versions.side_effect = (\n            self.mock_registry.get_compatible_versions\n        )\n        self.registry.package_version.side_effect = self.mock_registry.package_version\n\n    def tearDown(self):\n        self.patcher.stop()\n\n    def test_dependency_resolution(self):\n        package_config = PackageConfig.from_dict(\n            {\n                \"packages\": [\n                    {\"package\": \"dbt-labs-test/a\", \"version\": \">0.1.2\"},\n                    {\"package\": \"dbt-labs-test/b\", \"version\": \"0.2.1\"},\n                ],\n            }\n        )\n        resolved = resolve_packages(\n            package_config.packages, mock.MagicMock(project_name=\"test\"), {}\n        )\n        self.assertEqual(len(resolved), 2)\n        self.assertEqual(resolved[0].name, \"dbt-labs-test/a\")\n        self.assertEqual(resolved[0].version, \"0.1.3\")\n        self.assertEqual(resolved[1].name, \"dbt-labs-test/b\")\n        self.assertEqual(resolved[1].version, \"0.2.1\")\n\n    def test_private_package_raise_error(self):\n        package_config = PackageConfig.from_dict(\n            {\n                \"packages\": [\n                    {\"private\": \"dbt-labs-test/a\", \"subdirectory\": \"foo-bar\"},\n                ],\n            }\n        )\n        with self.assertRaisesRegex(\n            dbt.exceptions.DependencyError, \"Cannot resolve private package\"\n        ):\n            resolve_packages(package_config.packages, mock.MagicMock(project_name=\"test\"), {})\n\n    def test_dependency_resolution_allow_prerelease(self):\n        package_config = PackageConfig.from_dict(\n            {\n                \"packages\": [\n                    {\n                        \"package\": \"dbt-labs-test/a\",\n                        \"version\": \">0.1.2\",\n                        \"install_prerelease\": True,\n                    },\n                    {\"package\": \"dbt-labs-test/b\", \"version\": \"0.2.1\"},\n                ],\n            }\n        )\n        resolved = resolve_packages(\n            package_config.packages, mock.MagicMock(project_name=\"test\"), {}\n        )\n        self.assertEqual(resolved[0].name, \"dbt-labs-test/a\")\n        self.assertEqual(resolved[0].version, \"0.1.4a1\")\n\n    def test_validation_error_when_version_is_missing_from_package_config(self):\n        packages_data = {\"packages\": [{\"package\": \"dbt-labs-test/b\", \"version\": None}]}\n\n        with self.assertRaises(ValidationError) as exc:\n            PackageConfig.validate(data=packages_data)\n\n        msg = \"dbt-labs-test/b is missing the version. When installing from the Hub package index, version is a required property\"\n        assert msg in str(exc.exception)\n\n    def test_validation_error_when_namespace_is_missing_from_package_config(self):\n        packages_data = {\"packages\": [{\"package\": \"dbt-labs\", \"version\": \"1.0.0\"}]}\n\n        with self.assertRaises(ValidationError) as exc:\n            PackageConfig.validate(data=packages_data)\n\n        msg = \"dbt-labs was not found in the package index. Packages on the index require a namespace, e.g dbt-labs/dbt_utils\"\n        assert msg in str(exc.exception)\n\n\nclass TestCheckForDuplicatePackagesWithBooleans(unittest.TestCase):\n    \"\"\"Unit test for check_for_duplicate_packages method with boolean values.\n\n    This is a regression test for issue #9104 where the method would fail with\n    \"TypeError: argument of type 'bool' is not iterable\" when package entries\n    contained boolean fields like warn-unpinned: false.\n    \"\"\"\n\n    def test_check_duplicate_with_warn_unpinned_false(self):\n        \"\"\"Test that check_for_duplicate_packages handles warn-unpinned: false\"\"\"\n        # Create a mock DepsTask with minimal setup\n        mock_args = Namespace(\n            add_package={\"name\": \"audit_helper\", \"version\": \"0.9.0\"}, source=\"hub\"\n        )\n\n        # Mock project - we don't need a real one for this test\n        with mock.patch(\"dbt.task.deps.BaseTask.__init__\"):\n            task = DepsTask.__new__(DepsTask)\n            task.args = mock_args\n\n        # Test data: packages.yml with warn-unpinned: false\n        packages_yml = {\n            \"packages\": [\n                {\n                    \"git\": \"https://github.com/dbt-labs/dbt-utils.git\",\n                    \"revision\": \"1.0.0\",\n                    \"warn-unpinned\": False,  # This is the problematic boolean\n                },\n            ]\n        }\n\n        # This should not raise TypeError\n        result = task.check_for_duplicate_packages(packages_yml)\n\n        # Verify the result is returned (not None)\n        self.assertIsNotNone(result)\n        self.assertIn(\"packages\", result)\n        # Original package should still be there (no duplicate)\n        self.assertEqual(len(result[\"packages\"]), 1)\n\n    def test_check_duplicate_with_warn_unpinned_true(self):\n        \"\"\"Test that check_for_duplicate_packages handles warn-unpinned: true\"\"\"\n        mock_args = Namespace(\n            add_package={\"name\": \"audit_helper\", \"version\": \"0.9.0\"}, source=\"hub\"\n        )\n\n        with mock.patch(\"dbt.task.deps.BaseTask.__init__\"):\n            task = DepsTask.__new__(DepsTask)\n            task.args = mock_args\n\n        packages_yml = {\n            \"packages\": [\n                {\n                    \"git\": \"https://github.com/dbt-labs/dbt-utils.git\",\n                    \"revision\": \"1.0.0\",\n                    \"warn-unpinned\": True,  # Another boolean value\n                },\n            ]\n        }\n\n        # This should not raise TypeError\n        result = task.check_for_duplicate_packages(packages_yml)\n        self.assertIsNotNone(result)\n        self.assertEqual(len(result[\"packages\"]), 1)\n\n    def test_check_duplicate_with_subdirectory_and_warn_unpinned(self):\n        \"\"\"Test with multiple non-string values (subdirectory string + warn-unpinned bool)\"\"\"\n        mock_args = Namespace(\n            add_package={\"name\": \"audit_helper\", \"version\": \"0.9.0\"}, source=\"hub\"\n        )\n\n        with mock.patch(\"dbt.task.deps.BaseTask.__init__\"):\n            task = DepsTask.__new__(DepsTask)\n            task.args = mock_args\n\n        packages_yml = {\n            \"packages\": [\n                {\n                    \"git\": \"https://github.com/dbt-labs/dbt-utils.git\",\n                    \"revision\": \"1.0.0\",\n                    \"subdirectory\": \"some_dir\",\n                    \"warn-unpinned\": False,\n                },\n            ]\n        }\n\n        # This should not raise TypeError\n        result = task.check_for_duplicate_packages(packages_yml)\n        self.assertIsNotNone(result)\n        self.assertEqual(len(result[\"packages\"]), 1)\n\n    def test_check_duplicate_detects_git_match(self):\n        \"\"\"Test that duplicate detection still works for git packages\"\"\"\n        mock_args = Namespace(add_package={\"name\": \"dbt-utils\", \"version\": \"1.1.0\"}, source=\"git\")\n\n        with mock.patch(\"dbt.task.deps.BaseTask.__init__\"):\n            task = DepsTask.__new__(DepsTask)\n            task.args = mock_args\n\n        packages_yml = {\n            \"packages\": [\n                {\n                    \"git\": \"https://github.com/dbt-labs/dbt-utils.git\",\n                    \"revision\": \"1.0.0\",\n                    \"warn-unpinned\": False,\n                },\n            ]\n        }\n\n        # The package name \"dbt-utils\" should match in the git URL\n        with mock.patch(\"dbt_common.events.functions.fire_event\"):\n            result = task.check_for_duplicate_packages(packages_yml)\n\n        # The duplicate should be removed\n        self.assertIsNotNone(result)\n        self.assertEqual(len(result[\"packages\"]), 0)\n\n    def test_check_duplicate_with_hub_package(self):\n        \"\"\"Test with hub package (which don't have warn-unpinned)\"\"\"\n        mock_args = Namespace(\n            add_package={\"name\": \"another_package\", \"version\": \"1.0.0\"}, source=\"hub\"\n        )\n\n        with mock.patch(\"dbt.task.deps.BaseTask.__init__\"):\n            task = DepsTask.__new__(DepsTask)\n            task.args = mock_args\n\n        packages_yml = {\n            \"packages\": [\n                {\n                    \"package\": \"dbt-labs/dbt_utils\",\n                    \"version\": \"1.0.0\",\n                },\n            ]\n        }\n\n        # This should work fine\n        result = task.check_for_duplicate_packages(packages_yml)\n        self.assertIsNotNone(result)\n        self.assertEqual(len(result[\"packages\"]), 1)\n\n    def test_check_duplicate_with_mixed_package_types(self):\n        \"\"\"Test with mixed package types (hub + git with warn-unpinned)\"\"\"\n        mock_args = Namespace(\n            add_package={\"name\": \"audit_helper\", \"version\": \"0.9.0\"}, source=\"hub\"\n        )\n\n        with mock.patch(\"dbt.task.deps.BaseTask.__init__\"):\n            task = DepsTask.__new__(DepsTask)\n            task.args = mock_args\n\n        packages_yml = {\n            \"packages\": [\n                {\n                    \"package\": \"dbt-labs/dbt_utils\",\n                    \"version\": \"1.0.0\",\n                },\n                {\n                    \"git\": \"https://github.com/example/some-package.git\",\n                    \"revision\": \"0.5.0\",\n                    \"warn-unpinned\": False,\n                },\n            ]\n        }\n\n        # This should not raise TypeError\n        result = task.check_for_duplicate_packages(packages_yml)\n        self.assertIsNotNone(result)\n        # Both packages should remain (no duplicates)\n        self.assertEqual(len(result[\"packages\"]), 2)\n\n    def test_check_duplicate_cross_source_hub_removes_git(self):\n        \"\"\"Test that adding a hub package removes a git package with the same name\"\"\"\n        # When adding \"dbt-labs/dbt_utils\", it should match git URLs containing \"dbt_utils\"\n        # Note: The full package name \"dbt-labs/dbt_utils\" is what gets checked\n        mock_args = Namespace(\n            add_package={\"name\": \"dbt-labs/dbt_utils\", \"version\": \"1.0.0\"}, source=\"hub\"\n        )\n\n        with mock.patch(\"dbt.task.deps.BaseTask.__init__\"):\n            task = DepsTask.__new__(DepsTask)\n            task.args = mock_args\n\n        packages_yml = {\n            \"packages\": [\n                {\n                    \"git\": \"https://github.com/dbt-labs/dbt_utils.git\",\n                    \"revision\": \"1.0.0\",\n                    \"warn-unpinned\": False,\n                },\n            ]\n        }\n\n        # The hub package name \"dbt-labs/dbt_utils\" should match in the git URL\n        # because \"dbt_utils\" appears in both\n        with mock.patch(\"dbt_common.events.functions.fire_event\"):\n            result = task.check_for_duplicate_packages(packages_yml)\n\n        # The git package should be removed (cross-source duplicate)\n        self.assertIsNotNone(result)\n        self.assertEqual(len(result[\"packages\"]), 0)\n\n    def test_check_duplicate_multiple_matches(self):\n        \"\"\"Test that all duplicate packages are removed, not just the first one\"\"\"\n        # When adding \"dbt-labs/dbt_utils\", it should match any identifier containing \"dbt_utils\"\n        mock_args = Namespace(\n            add_package={\"name\": \"dbt-labs/dbt_utils\", \"version\": \"1.0.0\"}, source=\"hub\"\n        )\n\n        with mock.patch(\"dbt.task.deps.BaseTask.__init__\"):\n            task = DepsTask.__new__(DepsTask)\n            task.args = mock_args\n\n        packages_yml = {\n            \"packages\": [\n                {\n                    \"git\": \"https://github.com/dbt-labs/dbt_utils.git\",\n                    \"revision\": \"0.9.0\",\n                },\n                {\n                    \"git\": \"https://github.com/fivetran/dbt_amplitude\",\n                    \"revision\": \"1.0.0\",\n                },\n                {\n                    \"package\": \"dbt-labs/dbt_utils\",  # Exact match\n                    \"version\": \"0.8.0\",\n                },\n            ]\n        }\n\n        # Should remove both packages that contain \"dbt_utils\"\n        with mock.patch(\"dbt_common.events.functions.fire_event\"):\n            result = task.check_for_duplicate_packages(packages_yml)\n\n        # Only the dbt_amplitude package should remain\n        self.assertIsNotNone(result)\n        self.assertEqual(len(result[\"packages\"]), 1)\n        self.assertIn(\"dbt_amplitude\", result[\"packages\"][0][\"git\"])\n\n    def test_check_duplicate_underscore_hyphen_matching(self):\n        \"\"\"Test that underscore and hyphen variants match (dbt_utils matches dbt-utils)\"\"\"\n        # Adding hub package with underscore should match git package with hyphen\n        mock_args = Namespace(\n            add_package={\"name\": \"dbt-labs/dbt_utils\", \"version\": \"1.0.0\"}, source=\"hub\"\n        )\n\n        with mock.patch(\"dbt.task.deps.BaseTask.__init__\"):\n            task = DepsTask.__new__(DepsTask)\n            task.args = mock_args\n\n        packages_yml = {\n            \"packages\": [\n                {\n                    \"git\": \"https://github.com/dbt-labs/dbt-utils.git\",  # hyphen in URL\n                    \"revision\": \"1.0.0\",\n                },\n            ]\n        }\n\n        # Should match because \"dbt-utils\" variant matches the git URL\n        with mock.patch(\"dbt_common.events.functions.fire_event\"):\n            result = task.check_for_duplicate_packages(packages_yml)\n\n        self.assertIsNotNone(result)\n        self.assertEqual(len(result[\"packages\"]), 0)  # Git package removed\n\n    def test_check_duplicate_no_partial_word_match(self):\n        \"\"\"Test that partial word matches are rejected (dbt-core shouldn't match dbt-core-utils)\"\"\"\n        mock_args = Namespace(\n            add_package={\"name\": \"dbt-labs/dbt-core\", \"version\": \"1.0.0\"}, source=\"hub\"\n        )\n\n        with mock.patch(\"dbt.task.deps.BaseTask.__init__\"):\n            task = DepsTask.__new__(DepsTask)\n            task.args = mock_args\n\n        packages_yml = {\n            \"packages\": [\n                {\n                    \"git\": \"https://github.com/dbt-labs/dbt-core-utils.git\",\n                    \"revision\": \"1.0.0\",\n                },\n                {\n                    \"package\": \"other-org/my-dbt-core-fork\",\n                    \"version\": \"2.0.0\",\n                },\n            ]\n        }\n\n        # Should NOT match because \"dbt-core\" is part of a larger word\n        with mock.patch(\"dbt_common.events.functions.fire_event\"):\n            result = task.check_for_duplicate_packages(packages_yml)\n\n        # Both packages should remain (no matches)\n        self.assertIsNotNone(result)\n        self.assertEqual(len(result[\"packages\"]), 2)\n\n    def test_check_duplicate_exact_word_boundary_match(self):\n        \"\"\"Test that exact matches with word boundaries work correctly\"\"\"\n        mock_args = Namespace(\n            add_package={\"name\": \"dbt-labs/dbt-utils\", \"version\": \"1.0.0\"}, source=\"hub\"\n        )\n\n        with mock.patch(\"dbt.task.deps.BaseTask.__init__\"):\n            task = DepsTask.__new__(DepsTask)\n            task.args = mock_args\n\n        packages_yml = {\n            \"packages\": [\n                {\n                    \"git\": \"https://github.com/dbt-labs/dbt-utils.git\",  # Should match\n                    \"revision\": \"1.0.0\",\n                },\n                {\n                    \"git\": \"https://github.com/other/dbt-utils-extra.git\",  # Should NOT match\n                    \"revision\": \"2.0.0\",\n                },\n                {\n                    \"package\": \"dbt-labs/dbt_utils\",  # Should match (underscore variant)\n                    \"version\": \"0.9.0\",\n                },\n            ]\n        }\n\n        with mock.patch(\"dbt_common.events.functions.fire_event\"):\n            result = task.check_for_duplicate_packages(packages_yml)\n\n        # Only dbt-utils-extra should remain\n        self.assertIsNotNone(result)\n        self.assertEqual(len(result[\"packages\"]), 1)\n        self.assertIn(\"dbt-utils-extra\", result[\"packages\"][0][\"git\"])\n"
  },
  {
    "path": "tests/unit/event_time/test_event_time.py",
    "content": "from datetime import datetime\n\nimport pytest\nimport pytz\n\nfrom dbt.artifacts.resources.types import BatchSize\nfrom dbt.event_time.event_time import offset_timestamp\n\n\nclass TestEventTime:\n\n    @pytest.mark.parametrize(\n        \"timestamp,batch_size,offset,expected_timestamp\",\n        [\n            (\n                datetime(2024, 9, 5, 3, 56, 1, 1, pytz.UTC),\n                BatchSize.year,\n                1,\n                datetime(2025, 9, 5, 3, 56, 1, 1, pytz.UTC),\n            ),\n            (\n                datetime(2024, 9, 5, 3, 56, 1, 1, pytz.UTC),\n                BatchSize.year,\n                -1,\n                datetime(2023, 9, 5, 3, 56, 1, 1, pytz.UTC),\n            ),\n            (\n                datetime(2024, 9, 5, 3, 56, 1, 1, pytz.UTC),\n                BatchSize.month,\n                1,\n                datetime(2024, 10, 5, 3, 56, 1, 1, pytz.UTC),\n            ),\n            (\n                datetime(2024, 9, 5, 3, 56, 1, 1, pytz.UTC),\n                BatchSize.month,\n                -1,\n                datetime(2024, 8, 5, 3, 56, 1, 1, pytz.UTC),\n            ),\n            (\n                datetime(2024, 9, 5, 3, 56, 1, 1, pytz.UTC),\n                BatchSize.day,\n                1,\n                datetime(2024, 9, 6, 3, 56, 1, 1, pytz.UTC),\n            ),\n            (\n                datetime(2024, 9, 5, 3, 56, 1, 1, pytz.UTC),\n                BatchSize.day,\n                -1,\n                datetime(2024, 9, 4, 3, 56, 1, 1, pytz.UTC),\n            ),\n            (\n                datetime(2024, 9, 5, 3, 56, 1, 1, pytz.UTC),\n                BatchSize.hour,\n                1,\n                datetime(2024, 9, 5, 4, 56, 1, 1, pytz.UTC),\n            ),\n            (\n                datetime(2024, 9, 5, 3, 56, 1, 1, pytz.UTC),\n                BatchSize.hour,\n                -1,\n                datetime(2024, 9, 5, 2, 56, 1, 1, pytz.UTC),\n            ),\n            (\n                datetime(2024, 1, 31, 16, 6, 0, 0, pytz.UTC),\n                BatchSize.month,\n                1,\n                datetime(2024, 2, 29, 16, 6, 0, 0, pytz.UTC),\n            ),\n            (\n                datetime(2024, 2, 29, 16, 6, 0, 0, pytz.UTC),\n                BatchSize.year,\n                1,\n                datetime(2025, 2, 28, 16, 6, 0, 0, pytz.UTC),\n            ),\n        ],\n    )\n    def test_offset_timestamp(self, timestamp, batch_size, offset, expected_timestamp):\n        assert offset_timestamp(timestamp, batch_size, offset) == expected_timestamp\n"
  },
  {
    "path": "tests/unit/event_time/test_sample_mode.py",
    "content": "from datetime import datetime\nfrom typing import Union\n\nimport freezegun\nimport pytest\nimport pytz\n\nfrom dbt.event_time.sample_window import SampleWindow\nfrom dbt_common.exceptions import DbtRuntimeError\n\n\n@pytest.mark.parametrize(\n    \"relative_string,expected_result\",\n    [\n        (\n            \"4 years\",\n            SampleWindow(\n                start=datetime(2021, 1, 28, 18, 4, 0, 0, pytz.UTC),\n                end=datetime(2025, 1, 28, 18, 4, 0, 0, pytz.UTC),\n            ),\n        ),\n        (\n            \"1 year\",\n            SampleWindow(\n                start=datetime(2024, 1, 28, 18, 4, 0, 0, pytz.UTC),\n                end=datetime(2025, 1, 28, 18, 4, 0, 0, pytz.UTC),\n            ),\n        ),\n        (\n            \"4 YEARS\",\n            SampleWindow(\n                start=datetime(2021, 1, 28, 18, 4, 0, 0, pytz.UTC),\n                end=datetime(2025, 1, 28, 18, 4, 0, 0, pytz.UTC),\n            ),\n        ),\n        (\n            \"1 YEAR\",\n            SampleWindow(\n                start=datetime(2024, 1, 28, 18, 4, 0, 0, pytz.UTC),\n                end=datetime(2025, 1, 28, 18, 4, 0, 0, pytz.UTC),\n            ),\n        ),\n        (\n            \"4 months\",\n            SampleWindow(\n                start=datetime(2024, 9, 28, 18, 4, 0, 0, pytz.UTC),\n                end=datetime(2025, 1, 28, 18, 4, 0, 0, pytz.UTC),\n            ),\n        ),\n        (\n            \"1 month\",\n            SampleWindow(\n                start=datetime(2024, 12, 28, 18, 4, 0, 0, pytz.UTC),\n                end=datetime(2025, 1, 28, 18, 4, 0, 0, pytz.UTC),\n            ),\n        ),\n        (\n            \"4 MONTHS\",\n            SampleWindow(\n                start=datetime(2024, 9, 28, 18, 4, 0, 0, pytz.UTC),\n                end=datetime(2025, 1, 28, 18, 4, 0, 0, pytz.UTC),\n            ),\n        ),\n        (\n            \"1 MONTH\",\n            SampleWindow(\n                start=datetime(2024, 12, 28, 18, 4, 0, 0, pytz.UTC),\n                end=datetime(2025, 1, 28, 18, 4, 0, 0, pytz.UTC),\n            ),\n        ),\n        (\n            \"4 days\",\n            SampleWindow(\n                start=datetime(2025, 1, 24, 18, 4, 0, 0, pytz.UTC),\n                end=datetime(2025, 1, 28, 18, 4, 0, 0, pytz.UTC),\n            ),\n        ),\n        (\n            \"1 day\",\n            SampleWindow(\n                start=datetime(2025, 1, 27, 18, 4, 0, 0, pytz.UTC),\n                end=datetime(2025, 1, 28, 18, 4, 0, 0, pytz.UTC),\n            ),\n        ),\n        (\n            \"4 DAYS\",\n            SampleWindow(\n                start=datetime(2025, 1, 24, 18, 4, 0, 0, pytz.UTC),\n                end=datetime(2025, 1, 28, 18, 4, 0, 0, pytz.UTC),\n            ),\n        ),\n        (\n            \"1 DAY\",\n            SampleWindow(\n                start=datetime(2025, 1, 27, 18, 4, 0, 0, pytz.UTC),\n                end=datetime(2025, 1, 28, 18, 4, 0, 0, pytz.UTC),\n            ),\n        ),\n        (\n            \"4 hours\",\n            SampleWindow(\n                start=datetime(2025, 1, 28, 14, 4, 0, 0, pytz.UTC),\n                end=datetime(2025, 1, 28, 18, 4, 0, 0, pytz.UTC),\n            ),\n        ),\n        (\n            \"1 hour\",\n            SampleWindow(\n                start=datetime(2025, 1, 28, 17, 4, 0, 0, pytz.UTC),\n                end=datetime(2025, 1, 28, 18, 4, 0, 0, pytz.UTC),\n            ),\n        ),\n        (\n            \"4 HOURS\",\n            SampleWindow(\n                start=datetime(2025, 1, 28, 14, 4, 0, 0, pytz.UTC),\n                end=datetime(2025, 1, 28, 18, 4, 0, 0, pytz.UTC),\n            ),\n        ),\n        (\n            \"1 HOUR\",\n            SampleWindow(\n                start=datetime(2025, 1, 28, 17, 4, 0, 0, pytz.UTC),\n                end=datetime(2025, 1, 28, 18, 4, 0, 0, pytz.UTC),\n            ),\n        ),\n        (\n            \"1 week\",\n            DbtRuntimeError(\n                \"Invalid grain size 'week'. Must be one of ['hour', 'day', 'month', 'year', 'hours', 'days', 'months', 'years'].\"\n            ),\n        ),\n        (\"an hour\", DbtRuntimeError(\"Unable to convert 'an' to an integer.\")),\n        (\n            \"3\",\n            DbtRuntimeError(\n                \"Cannot load SAMPLE_WINDOW from '3'. Must be of form 'DAYS_INT GRAIN_SIZE'.\"\n            ),\n        ),\n        (\n            \"True\",\n            DbtRuntimeError(\n                \"Cannot load SAMPLE_WINDOW from 'True'. Must be of form 'DAYS_INT GRAIN_SIZE'.\"\n            ),\n        ),\n        (\"days 3\", DbtRuntimeError(\"Unable to convert 'days' to an integer.\")),\n        (\n            \"{}\",\n            DbtRuntimeError(\n                \"Cannot load SAMPLE_WINDOW from '{}'. Must be of form 'DAYS_INT GRAIN_SIZE'.\"\n            ),\n        ),\n    ],\n)\n@freezegun.freeze_time(\"2025-01-28T18:04:0Z\")\ndef test_from_relative_string(\n    relative_string: str, expected_result: Union[SampleWindow, Exception]\n):\n    try:\n        result = SampleWindow.from_relative_string(relative_string)\n        assert result == expected_result\n    except Exception as e:\n        assert str(e) == str(expected_result)\n"
  },
  {
    "path": "tests/unit/events/__init__.py",
    "content": ""
  },
  {
    "path": "tests/unit/events/test_logging.py",
    "content": "from argparse import Namespace\n\nfrom pytest_mock import MockerFixture\n\nfrom dbt.events.logging import setup_event_logger\nfrom dbt.flags import get_flags, set_from_args\nfrom dbt_common.events.base_types import BaseEvent\nfrom dbt_common.events.event_catcher import EventCatcher\nfrom dbt_common.events.event_manager_client import get_event_manager\nfrom dbt_common.events.logger import LoggerConfig\n\n\nclass TestSetupEventLogger:\n    def test_clears_preexisting_event_manager_state(self) -> None:\n        manager = get_event_manager()\n        manager.add_logger(LoggerConfig(name=\"test_logger\"))\n        manager.callbacks.append(EventCatcher(BaseEvent).catch)\n        assert len(manager.loggers) == 1\n        assert len(manager.callbacks) == 1\n\n        args = Namespace(log_level=\"none\", log_level_file=\"none\")\n        set_from_args(args, {})\n\n        setup_event_logger(get_flags())\n        assert len(manager.loggers) == 0\n        assert len(manager.callbacks) == 1  # snowplow tracker for behavior flags\n\n    def test_specify_max_bytes(\n        self,\n        mocker: MockerFixture,\n    ) -> None:\n        patched_file_handler = mocker.patch(\"dbt_common.events.logger.RotatingFileHandler\")\n        args = Namespace(log_file_max_bytes=1234567)\n        set_from_args(args, {})\n        setup_event_logger(get_flags())\n        patched_file_handler.assert_called_once_with(\n            filename=\"logs/dbt.log\", encoding=\"utf8\", maxBytes=1234567, backupCount=5\n        )\n"
  },
  {
    "path": "tests/unit/events/test_types.py",
    "content": "from dbtlabs.proto.public.v1.fields import core_types_pb2\nfrom google.protobuf.json_format import MessageToDict\n\nfrom dbt.adapters.events.types import PluginLoadError, RollbackFailed\nfrom dbt.events.types import (\n    LogNodeResult,\n    LogStartLine,\n    LogTestResult,\n    MainEncounteredError,\n    MainReportArgs,\n    MainReportVersion,\n)\nfrom dbt.version import installed\nfrom dbt_common.events import types_pb2\nfrom dbt_common.events.base_types import EventLevel, msg_from_base_event\nfrom dbt_common.events.functions import (\n    LOG_VERSION,\n    msg_to_dict,\n    msg_to_json,\n    reset_metadata_vars,\n)\n\ninfo_keys = {\n    \"name\",\n    \"code\",\n    \"msg\",\n    \"level\",\n    \"invocation_id\",\n    \"pid\",\n    \"thread\",\n    \"ts\",\n    \"extra\",\n    \"category\",\n}\n\n\ndef test_events():\n\n    # A001 event\n    event = MainReportVersion(version=str(installed), log_version=LOG_VERSION)\n    msg = msg_from_base_event(event)\n    msg_dict = msg_to_dict(msg)\n    msg_json = msg_to_json(msg)\n    serialized = msg.SerializeToString()\n    assert \"Running with dbt=\" in str(serialized)\n    assert set(msg_dict.keys()) == {\"info\", \"data\"}\n    assert set(msg_dict[\"data\"].keys()) == {\"version\", \"log_version\"}\n    assert set(msg_dict[\"info\"].keys()) == info_keys\n    assert msg_json\n    assert msg.info.code == \"A001\"\n\n    # Extract EventInfo from serialized message\n    generic_msg = types_pb2.GenericMessage()\n    generic_msg.ParseFromString(serialized)\n    assert generic_msg.info.code == \"A001\"\n    # get the message class for the real message from the generic message\n    message_class = getattr(core_types_pb2, f\"{generic_msg.info.name}Msg\")\n    new_msg = message_class()\n    new_msg.ParseFromString(serialized)\n    assert new_msg.info.code == msg.info.code\n    assert new_msg.data.version == msg.data.version\n\n    # A002 event\n    event = MainReportArgs(args={\"one\": \"1\", \"two\": \"2\"})\n    msg = msg_from_base_event(event)\n    msg_dict = msg_to_dict(msg)\n    msg_json = msg_to_json(msg)\n\n    assert set(msg_dict.keys()) == {\"info\", \"data\"}\n    assert set(msg_dict[\"data\"].keys()) == {\"args\"}\n    assert set(msg_dict[\"info\"].keys()) == info_keys\n    assert msg_json\n    assert msg.info.code == \"A002\"\n\n\ndef test_exception_events():\n    event = RollbackFailed(conn_name=\"test\", exc_info=\"something failed\")\n    msg = msg_from_base_event(event)\n    msg_dict = msg_to_dict(msg)\n    msg_json = msg_to_json(msg)\n    assert set(msg_dict.keys()) == {\"info\", \"data\"}\n    assert set(msg_dict[\"data\"].keys()) == {\"conn_name\", \"exc_info\"}\n    assert set(msg_dict[\"info\"].keys()) == info_keys\n    assert msg_json\n    assert msg.info.code == \"E009\"\n\n    event = PluginLoadError(exc_info=\"something failed\")\n    msg = msg_from_base_event(event)\n    msg_dict = msg_to_dict(msg)\n    msg_json = msg_to_json(msg)\n    assert set(msg_dict[\"data\"].keys()) == {\"exc_info\"}\n    assert set(msg_dict[\"info\"].keys()) == info_keys\n    assert msg_json\n    assert msg.info.code == \"E036\"\n    assert msg.info.msg == \"something failed\"\n\n    # Z002 event\n    event = MainEncounteredError(exc=\"Rollback failed\")\n    msg = msg_from_base_event(event)\n    msg_dict = msg_to_dict(msg)\n    msg_json = msg_to_json(msg)\n\n    assert set(msg_dict[\"data\"].keys()) == {\"exc\"}\n    assert set(msg_dict[\"info\"].keys()) == info_keys\n    assert msg_json\n    assert msg.info.code == \"Z002\"\n\n\ndef test_node_info_events():\n    meta_dict = {\n        \"key1\": [\"value1\", 2],\n        \"key2\": {\"nested-dict-key\": \"value2\"},\n        \"key3\": 1,\n        \"key4\": [\"string1\", 1, \"string2\", 2],\n    }\n    node_info = {\n        \"node_path\": \"some_path\",\n        \"node_name\": \"some_name\",\n        \"unique_id\": \"some_id\",\n        \"resource_type\": \"model\",\n        \"materialized\": \"table\",\n        \"node_status\": \"started\",\n        \"node_started_at\": \"some_time\",\n        \"node_finished_at\": \"another_time\",\n        \"meta\": meta_dict,\n        \"node_relation\": {\n            \"database\": \"some_database\",\n            \"schema\": \"some_schema\",\n            \"alias\": \"some_alias\",\n            \"relation_name\": \"some.relation.name\",\n        },\n        \"node_checksum\": \"some_checksum\",\n    }\n    event = LogStartLine(\n        description=\"some description\",\n        index=123,\n        total=111,\n        node_info=node_info,\n    )\n    assert event\n    assert event.node_info.node_path == \"some_path\"\n    assert event.to_dict()[\"node_info\"][\"meta\"] == meta_dict\n\n    node_info[\"node_relation\"][\"database\"] = None\n    node_info[\"node_relation\"][\"relation_name\"] = \"some_schema.some_alias\"\n    event = LogStartLine(\n        description=\"some description\",\n        index=123,\n        total=111,\n        node_info=node_info,\n    )\n    assert event.node_info.node_relation.database == \"\"\n    assert event.node_info.node_relation.relation_name == \"some_schema.some_alias\"\n\n    assert event.node_info.node_checksum == \"some_checksum\"\n\n\ndef test_extra_dict_on_event(monkeypatch):\n\n    monkeypatch.setenv(\"DBT_ENV_CUSTOM_ENV_env_key\", \"env_value\")\n\n    reset_metadata_vars()\n\n    event = MainReportVersion(version=str(installed), log_version=LOG_VERSION)\n    msg = msg_from_base_event(event)\n    msg_dict = msg_to_dict(msg)\n    assert set(msg_dict[\"info\"].keys()) == info_keys\n    extra_dict = {\"env_key\": \"env_value\"}\n    assert msg.info.extra == extra_dict\n    serialized = msg.SerializeToString()\n\n    # Extract EventInfo from serialized message\n    generic_msg = types_pb2.GenericMessage()\n    generic_msg.ParseFromString(serialized)\n    assert generic_msg.info.code == \"A001\"\n    # get the message class for the real message from the generic message\n    message_class = getattr(core_types_pb2, f\"{generic_msg.info.name}Msg\")\n    new_msg = message_class()\n    new_msg.ParseFromString(serialized)\n    new_msg_dict = MessageToDict(new_msg)\n    assert new_msg_dict[\"info\"][\"extra\"] == msg.info.extra\n\n    # clean up\n    reset_metadata_vars()\n\n\ndef test_dynamic_level_events():\n    event = LogTestResult(name=\"model_name\", status=\"pass\", index=1, num_models=3, num_failures=0)\n    msg = msg_from_base_event(event, level=EventLevel.INFO)\n    assert msg\n    assert msg.info.level == \"info\"\n\n\ndef test_log_node_result():\n    event = LogNodeResult(\n        node_info={},\n        status=\"error\",\n        index=1,\n        total=0,\n        msg=\"some message\",\n    )\n    msg = msg_from_base_event(event, level=EventLevel.ERROR)\n    assert msg\n    assert msg.info.msg == \"some message\"\n    assert msg.info.level == \"error\"\n"
  },
  {
    "path": "tests/unit/fixtures.py",
    "content": "from dbt.artifacts.resources import Contract, TestConfig, TestMetadata\nfrom dbt.contracts.files import FileHash\nfrom dbt.contracts.graph.nodes import (\n    DependsOn,\n    GenericTestNode,\n    InjectedCTE,\n    ModelConfig,\n    ModelNode,\n)\nfrom dbt.node_types import NodeType\n\n\ndef model_node():\n    return ModelNode(\n        package_name=\"test\",\n        path=\"/root/models/foo.sql\",\n        original_file_path=\"models/foo.sql\",\n        language=\"sql\",\n        raw_code='select * from {{ ref(\"other\") }}',\n        name=\"foo\",\n        resource_type=NodeType.Model,\n        unique_id=\"model.test.foo\",\n        fqn=[\"test\", \"models\", \"foo\"],\n        refs=[],\n        sources=[],\n        metrics=[],\n        depends_on=DependsOn(),\n        description=\"\",\n        primary_key=[],\n        database=\"test_db\",\n        schema=\"test_schema\",\n        alias=\"bar\",\n        tags=[],\n        config=ModelConfig(),\n        contract=Contract(),\n        meta={},\n        compiled=True,\n        extra_ctes=[InjectedCTE(\"whatever\", \"select * from other\")],\n        extra_ctes_injected=True,\n        compiled_code=\"with whatever as (select * from other) select * from whatever\",\n        checksum=FileHash.from_contents(\"\"),\n        unrendered_config={},\n    )\n\n\ndef generic_test_node():\n    return GenericTestNode(\n        package_name=\"test\",\n        path=\"/root/x/path.sql\",\n        original_file_path=\"/root/path.sql\",\n        language=\"sql\",\n        raw_code='select * from {{ ref(\"other\") }}',\n        name=\"foo\",\n        resource_type=NodeType.Test,\n        unique_id=\"model.test.foo\",\n        fqn=[\"test\", \"models\", \"foo\"],\n        refs=[],\n        sources=[],\n        metrics=[],\n        depends_on=DependsOn(),\n        description=\"\",\n        database=\"test_db\",\n        schema=\"dbt_test__audit\",\n        alias=\"bar\",\n        tags=[],\n        config=TestConfig(severity=\"warn\"),\n        contract=Contract(),\n        meta={},\n        compiled=True,\n        extra_ctes=[InjectedCTE(\"whatever\", \"select * from other\")],\n        extra_ctes_injected=True,\n        compiled_code=\"with whatever as (select * from other) select * from whatever\",\n        column_name=\"id\",\n        test_metadata=TestMetadata(namespace=None, name=\"foo\", kwargs={}),\n        checksum=FileHash.from_contents(\"\"),\n        unrendered_config={\n            \"severity\": \"warn\",\n        },\n    )\n"
  },
  {
    "path": "tests/unit/graph/__init__.py",
    "content": ""
  },
  {
    "path": "tests/unit/graph/test_cli.py",
    "content": "import textwrap\n\nimport yaml\n\nfrom dbt.contracts.selection import SelectorFile\nfrom dbt.graph import (\n    SelectionCriteria,\n    SelectionDifference,\n    SelectionIntersection,\n    SelectionUnion,\n    cli,\n)\nfrom dbt.graph.selector_methods import MethodName\n\n\ndef parse_file(txt: str) -> SelectorFile:\n    txt = textwrap.dedent(txt)\n    dct = yaml.safe_load(txt)\n    sf = SelectorFile.from_dict(dct)\n    return sf\n\n\nclass Union:\n    def __init__(self, *args):\n        self.components = args\n\n    def __str__(self):\n        return f\"Union(components={self.components})\"\n\n    def __repr__(self):\n        return f\"Union(components={self.components!r})\"\n\n    def __eq__(self, other):\n        if not isinstance(other, SelectionUnion):\n            return False\n\n        return all(mine == theirs for mine, theirs in zip(self.components, other.components))\n\n\nclass Intersection:\n    def __init__(self, *args):\n        self.components = args\n\n    def __str__(self):\n        return f\"Intersection(components={self.components})\"\n\n    def __repr__(self):\n        return f\"Intersection(components={self.components!r})\"\n\n    def __eq__(self, other):\n        if not isinstance(other, SelectionIntersection):\n            return False\n\n        return all(mine == theirs for mine, theirs in zip(self.components, other.components))\n\n\nclass Difference:\n    def __init__(self, *args):\n        self.components = args\n\n    def __str__(self):\n        return f\"Difference(components={self.components})\"\n\n    def __repr__(self):\n        return f\"Difference(components={self.components!r})\"\n\n    def __eq__(self, other):\n        if not isinstance(other, SelectionDifference):\n            return False\n\n        return all(mine == theirs for mine, theirs in zip(self.components, other.components))\n\n\nclass Criteria:\n    def __init__(self, method, value, **kwargs):\n        self.method = method\n        self.value = value\n        self.kwargs = kwargs\n\n    def __str__(self):\n        return f\"Criteria(method={self.method}, value={self.value}, **{self.kwargs})\"\n\n    def __repr__(self):\n        return f\"Criteria(method={self.method!r}, value={self.value!r}, **{self.kwargs!r})\"\n\n    def __eq__(self, other):\n        if not isinstance(other, SelectionCriteria):\n            return False\n        return (\n            self.method == other.method\n            and self.value == other.value\n            and all(getattr(other, k) == v for k, v in self.kwargs.items())\n        )\n\n\ndef test_parse_simple():\n    sf = parse_file(\n        \"\"\"\\\n        selectors:\n          - name: tagged_foo\n            description: Selector for foo-tagged models\n            definition:\n              tag: foo\n    \"\"\"\n    )\n\n    assert len(sf.selectors) == 1\n    assert sf.selectors[0].description == \"Selector for foo-tagged models\"\n    parsed = cli.parse_from_selectors_definition(sf)\n    assert len(parsed) == 1\n    assert \"tagged_foo\" in parsed\n    assert (\n        Criteria(\n            method=MethodName.Tag,\n            method_arguments=[],\n            value=\"foo\",\n            children=False,\n            parents=False,\n            childrens_parents=False,\n            children_depth=None,\n            parents_depth=None,\n        )\n        == parsed[\"tagged_foo\"][\"definition\"]\n    )\n\n\ndef test_parse_simple_childrens_parents():\n    sf = parse_file(\n        \"\"\"\\\n        selectors:\n          - name: tagged_foo\n            definition:\n              method: tag\n              value: foo\n              childrens_parents: True\n    \"\"\"\n    )\n\n    assert len(sf.selectors) == 1\n    parsed = cli.parse_from_selectors_definition(sf)\n    assert len(parsed) == 1\n    assert \"tagged_foo\" in parsed\n    assert (\n        Criteria(\n            method=MethodName.Tag,\n            method_arguments=[],\n            value=\"foo\",\n            children=False,\n            parents=False,\n            childrens_parents=True,\n            children_depth=None,\n            parents_depth=None,\n        )\n        == parsed[\"tagged_foo\"][\"definition\"]\n    )\n\n\ndef test_parse_simple_arguments_with_modifiers():\n    sf = parse_file(\n        \"\"\"\\\n        selectors:\n          - name: configured_view\n            definition:\n              method: config.materialized\n              value: view\n              parents: True\n              children: True\n              children_depth: 2\n    \"\"\"\n    )\n\n    assert len(sf.selectors) == 1\n    parsed = cli.parse_from_selectors_definition(sf)\n    assert len(parsed) == 1\n    assert \"configured_view\" in parsed\n    assert (\n        Criteria(\n            method=MethodName.Config,\n            method_arguments=[\"materialized\"],\n            value=\"view\",\n            children=True,\n            parents=True,\n            childrens_parents=False,\n            children_depth=2,\n            parents_depth=None,\n        )\n        == parsed[\"configured_view\"][\"definition\"]\n    )\n\n\ndef test_parse_union():\n    sf = parse_file(\n        \"\"\"\\\n        selectors:\n            - name: views-or-foos\n              definition:\n                union:\n                  - method: config.materialized\n                    value: view\n                  - tag: foo\n    \"\"\"\n    )\n    assert len(sf.selectors) == 1\n    parsed = cli.parse_from_selectors_definition(sf)\n    assert \"views-or-foos\" in parsed\n    assert (\n        Union(\n            Criteria(method=MethodName.Config, value=\"view\", method_arguments=[\"materialized\"]),\n            Criteria(method=MethodName.Tag, value=\"foo\", method_arguments=[]),\n        )\n        == parsed[\"views-or-foos\"][\"definition\"]\n    )\n\n\ndef test_parse_intersection():\n    sf = parse_file(\n        \"\"\"\\\n        selectors:\n            - name: views-and-foos\n              definition:\n                intersection:\n                  - method: config.materialized\n                    value: view\n                  - tag: foo\n    \"\"\"\n    )\n    assert len(sf.selectors) == 1\n    parsed = cli.parse_from_selectors_definition(sf)\n\n    assert \"views-and-foos\" in parsed\n    assert (\n        Intersection(\n            Criteria(method=MethodName.Config, value=\"view\", method_arguments=[\"materialized\"]),\n            Criteria(method=MethodName.Tag, value=\"foo\", method_arguments=[]),\n        )\n        == parsed[\"views-and-foos\"][\"definition\"]\n    )\n\n\ndef test_parse_union_excluding():\n    sf = parse_file(\n        \"\"\"\\\n        selectors:\n            - name: views-or-foos-not-bars\n              definition:\n                union:\n                  - method: config.materialized\n                    value: view\n                  - tag: foo\n                  - exclude:\n                    - tag: bar\n    \"\"\"\n    )\n    assert len(sf.selectors) == 1\n    parsed = cli.parse_from_selectors_definition(sf)\n    assert \"views-or-foos-not-bars\" in parsed\n    assert (\n        Difference(\n            Union(\n                Criteria(\n                    method=MethodName.Config, value=\"view\", method_arguments=[\"materialized\"]\n                ),\n                Criteria(method=MethodName.Tag, value=\"foo\", method_arguments=[]),\n            ),\n            Criteria(method=MethodName.Tag, value=\"bar\", method_arguments=[]),\n        )\n        == parsed[\"views-or-foos-not-bars\"][\"definition\"]\n    )\n\n\ndef test_parse_yaml_complex():\n    sf = parse_file(\n        \"\"\"\\\n        selectors:\n            - name: test_name\n              definition:\n                union:\n                - intersection:\n                  - tag: foo\n                  - tag: bar\n                  - union:\n                    - package: snowplow\n                    - config.materialized: incremental\n                - union:\n                  - path: \"models/snowplow/marketing/custom_events.sql\"\n                  - fqn: \"snowplow.marketing\"\n                - intersection:\n                  - resource_type: seed\n                  - package: snowplow\n                  - exclude:\n                    - country_codes\n                    - intersection:\n                      - tag: baz\n                      - config.materialized: ephemeral\n            - name: weeknights\n              definition:\n                union:\n                - tag: nightly\n                - tag:weeknights_only\n        \"\"\"\n    )\n\n    assert len(sf.selectors) == 2\n    parsed = cli.parse_from_selectors_definition(sf)\n    assert \"test_name\" in parsed\n    assert \"weeknights\" in parsed\n    assert (\n        Union(\n            Criteria(method=MethodName.Tag, value=\"nightly\"),\n            Criteria(method=MethodName.Tag, value=\"weeknights_only\"),\n        )\n        == parsed[\"weeknights\"][\"definition\"]\n    )\n\n    assert (\n        Union(\n            Intersection(\n                Criteria(method=MethodName.Tag, value=\"foo\"),\n                Criteria(method=MethodName.Tag, value=\"bar\"),\n                Union(\n                    Criteria(method=MethodName.Package, value=\"snowplow\"),\n                    Criteria(\n                        method=MethodName.Config,\n                        value=\"incremental\",\n                        method_arguments=[\"materialized\"],\n                    ),\n                ),\n            ),\n            Union(\n                Criteria(\n                    method=MethodName.Path, value=\"models/snowplow/marketing/custom_events.sql\"\n                ),\n                Criteria(method=MethodName.FQN, value=\"snowplow.marketing\"),\n            ),\n            Difference(\n                Intersection(\n                    Criteria(method=MethodName.ResourceType, value=\"seed\"),\n                    Criteria(method=MethodName.Package, value=\"snowplow\"),\n                ),\n                Union(\n                    Criteria(method=MethodName.FQN, value=\"country_codes\"),\n                    Intersection(\n                        Criteria(method=MethodName.Tag, value=\"baz\"),\n                        Criteria(\n                            method=MethodName.Config,\n                            value=\"ephemeral\",\n                            method_arguments=[\"materialized\"],\n                        ),\n                    ),\n                ),\n            ),\n        )\n        == parsed[\"test_name\"][\"definition\"]\n    )\n\n\ndef test_parse_selection():\n    sf = parse_file(\n        \"\"\"\\\n        selectors:\n            - name: default\n              definition:\n                union:\n                  - tag: foo\n                  - tag: bar\n            - name: inherited\n              definition:\n                method: selector\n                value: default\n    \"\"\"\n    )\n    assert len(sf.selectors) == 2\n    parsed = cli.parse_from_selectors_definition(sf)\n    assert \"default\" in parsed\n    assert \"inherited\" in parsed\n    assert (\n        Union(\n            Criteria(method=MethodName.Tag, value=\"foo\"),\n            Criteria(method=MethodName.Tag, value=\"bar\"),\n        )\n        == parsed[\"default\"][\"definition\"]\n    )\n    assert (\n        Criteria(method=MethodName.Selector, value=\"default\") == parsed[\"inherited\"][\"definition\"]\n    )\n\n\ndef test_parse_selection_with_exclusion():\n    sf = parse_file(\n        \"\"\"\\\n        selectors:\n            - name: default\n              definition:\n                union:\n                  - tag: foo\n                  - tag: bar\n            - name: inherited\n              definition:\n                union:\n                  - method: selector\n                    value: default\n                  - exclude:\n                    - tag: bar\n    \"\"\"\n    )\n    assert len(sf.selectors) == 2\n    parsed = cli.parse_from_selectors_definition(sf)\n    assert \"default\" in parsed\n    assert \"inherited\" in parsed\n    assert (\n        Union(\n            Criteria(method=MethodName.Tag, value=\"foo\"),\n            Criteria(method=MethodName.Tag, value=\"bar\"),\n        )\n        == parsed[\"default\"][\"definition\"]\n    )\n    assert (\n        Difference(\n            Union(\n                Criteria(method=MethodName.Selector, value=\"default\"),\n            ),\n            Criteria(method=MethodName.Tag, value=\"bar\"),\n        )\n        == parsed[\"inherited\"][\"definition\"]\n    )\n"
  },
  {
    "path": "tests/unit/graph/test_graph.py",
    "content": "import pytest\n\nfrom dbt.compilation import Linker\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.contracts.graph.nodes import ModelNode\nfrom dbt.graph.graph import Graph\nfrom tests.unit.utils.manifest import make_model\n\n\nclass TestGraph:\n    @pytest.fixture\n    def extra_parent_model(self) -> ModelNode:\n        return make_model(pkg=\"pkg\", name=\"extra_parent_model\", code=\"SELECT 'cats' as interests\")\n\n    @pytest.fixture\n    def non_shared_child_of_extra(self, extra_parent_model: ModelNode) -> ModelNode:\n        return make_model(\n            pkg=\"pkg\",\n            name=\"non_shared_child_of_extra\",\n            code='SELECT * FROM {{ ref(\"extra_parent_model\") }}',\n            refs=[extra_parent_model],\n        )\n\n    @pytest.fixture\n    def model_with_two_direct_parents(\n        self, extra_parent_model: ModelNode, ephemeral_model: ModelNode\n    ) -> ModelNode:\n        return make_model(\n            pkg=\"pkg\",\n            name=\"model_with_two_direct_parents\",\n            code='SELECT * FROM {{ ref(\"ephemeral_model\") }} UNION ALL SELECT * FROM {{ ref(\"extra_parent_model\") }}',\n            refs=[extra_parent_model, ephemeral_model],\n        )\n\n    @pytest.fixture(autouse=True)\n    def local_manifest_extensions(\n        self,\n        manifest: Manifest,\n        model_with_two_direct_parents: ModelNode,\n        non_shared_child_of_extra: ModelNode,\n        extra_parent_model: ModelNode,\n    ) -> Manifest:\n        manifest.add_node_nofile(extra_parent_model)\n        manifest.add_node_nofile(non_shared_child_of_extra)\n        manifest.add_node_nofile(model_with_two_direct_parents)\n\n    @pytest.fixture\n    def graph(self, manifest: Manifest, local_manifest_extensions) -> Graph:\n        # We include the `local_manifest_extensions` in the arguments to ensure\n        # that fixture adds our extra node sbefore creating the graph\n        linker = Linker()\n        linker.link_graph(manifest=manifest)\n        return Graph(graph=linker.graph)\n\n    def test_nodes(self, graph: Graph, manifest: Manifest):\n        graph_nodes = graph.nodes()\n        all_manifest_nodes = []\n        for resources in manifest.get_resource_fqns().values():\n            all_manifest_nodes.extend(list(resources))\n\n        # Assert that it is a set, thus no duplicates\n        assert isinstance(graph_nodes, set)\n        assert len(graph_nodes) == len(all_manifest_nodes)\n\n    def test_descendantcs(self, graph: Graph, manifest: Manifest) -> None:\n        model: ModelNode = manifest.nodes[\"model.pkg.ephemeral_model\"]\n\n        # check result when not limiting the depth\n        descendants = graph.descendants(node=model.unique_id)\n        assert descendants == {\n            \"model.pkg.model_with_two_direct_parents\",\n            \"test.pkg.view_test_nothing\",\n            \"model.pkg.view_model\",\n            \"model.pkg.table_model\",\n        }\n\n        # check that result excludes nodes that are out of depth\n        descendants = graph.descendants(node=model.unique_id, max_depth=1)\n        assert descendants == {\n            \"model.pkg.model_with_two_direct_parents\",\n            \"model.pkg.table_model\",\n            \"model.pkg.view_model\",\n        }\n\n    def test_ancestors(self, graph: Graph, manifest: Manifest) -> None:\n        model: ModelNode = manifest.nodes[\"model.pkg.table_model\"]\n\n        # check result when not limiting the depth\n        ancestors = graph.ancestors(node=model.unique_id)\n\n        assert ancestors == {\n            \"model.pkg.ephemeral_model\",\n            \"source.pkg.raw.seed\",\n        }\n\n        # check that result excludes nodes that are out of depth\n        ancestors = graph.ancestors(node=model.unique_id, max_depth=1)\n        assert ancestors == {\"model.pkg.ephemeral_model\"}\n\n    @pytest.mark.skip(reason=\"I haven't figured out how to add edge types to nodes\")\n    def test_exclude_edge_type(self) -> None:\n        # I though something like the following would produce\n        # linker = Linker()\n        # linker.link_graph(manifest=manifest)\n        # linker.add_test_edges(manifest=manifest)\n        # graph = Graph(graph=linker.graph)\n        pass\n\n    def test_select_childrens_parents(\n        self,\n        graph: Graph,\n        model_with_two_direct_parents: ModelNode,\n        extra_parent_model: ModelNode,\n        ephemeral_model: ModelNode,\n    ) -> None:\n        # `select_childrens_parents` should return\n        # * all children of the selected node (without depth limit)\n        # * all parents of the children of the selected node (without depth limit)\n        childrens_parents = graph.select_childrens_parents(\n            selected={\n                extra_parent_model.unique_id,\n            }\n        )\n\n        assert model_with_two_direct_parents.unique_id in childrens_parents\n        assert extra_parent_model.unique_id in childrens_parents\n        assert ephemeral_model.unique_id in childrens_parents\n        assert len(childrens_parents) == 5\n\n    def test_select_children(\n        self,\n        graph: Graph,\n        ephemeral_model: ModelNode,\n        extra_parent_model: ModelNode,\n    ) -> None:\n        ephemerals_children = graph.select_children(selected={ephemeral_model.unique_id})\n        extras_children = graph.select_children(selected={extra_parent_model.unique_id})\n        joint_children = graph.select_children(\n            selected={extra_parent_model.unique_id, ephemeral_model.unique_id}\n        )\n\n        assert joint_children == ephemerals_children.union(extras_children)\n        # These additional assertions are because we intentionally setup the test such that\n        # neither nodes children set is a subset of the other\n        assert not ephemerals_children.issubset(extras_children)\n        assert not extras_children.issubset(ephemerals_children)\n\n    def test_select_parents(\n        self,\n        graph: Graph,\n        non_shared_child_of_extra: ModelNode,\n        table_model: ModelNode,\n    ) -> None:\n        non_shareds_parents = graph.select_parents(selected={non_shared_child_of_extra.unique_id})\n        tables_parents = graph.select_parents(selected={table_model.unique_id})\n        joint_parents = graph.select_parents(\n            selected={table_model.unique_id, non_shared_child_of_extra.unique_id}\n        )\n\n        assert joint_parents == tables_parents.union(non_shareds_parents)\n        # These additional assertions are because we intentionally setup the test such that\n        # neither nodes parents set is a subset of the other\n        assert not non_shareds_parents.issubset(tables_parents)\n        assert not tables_parents.issubset(non_shareds_parents)\n"
  },
  {
    "path": "tests/unit/graph/test_nodes.py",
    "content": "from copy import deepcopy\nfrom datetime import datetime\nfrom typing import List\n\nimport pytest\nfrom freezegun import freeze_time\n\nfrom dbt.artifacts.resources import (\n    Defaults,\n    Dimension,\n    Entity,\n    FileHash,\n    Measure,\n    Metric,\n    MetricAggregationParams,\n    MetricTypeParams,\n    TestMetadata,\n)\nfrom dbt.artifacts.resources.v1.semantic_model import NodeRelation\nfrom dbt.contracts.graph.model_config import TestConfig\nfrom dbt.contracts.graph.nodes import ColumnInfo, ModelNode, ParsedNode, SemanticModel\nfrom dbt.node_types import NodeType\nfrom dbt_common.contracts.constraints import (\n    ColumnLevelConstraint,\n    ConstraintType,\n    ModelLevelConstraint,\n)\nfrom dbt_semantic_interfaces.references import MeasureReference, TimeDimensionReference\nfrom dbt_semantic_interfaces.type_enums import (\n    AggregationType,\n    DimensionType,\n    EntityType,\n    MetricType,\n)\nfrom tests.unit.fixtures import generic_test_node, model_node\n\n\nclass TestModelNode:\n    @pytest.fixture(scope=\"class\")\n    def default_model_node(self):\n        return ModelNode(\n            resource_type=NodeType.Model,\n            unique_id=\"model.test_package.test_name\",\n            name=\"test_name\",\n            package_name=\"test_package\",\n            schema=\"test_schema\",\n            alias=\"test_alias\",\n            fqn=[\"models\", \"test_name\"],\n            original_file_path=\"test_original_file_path\",\n            checksum=FileHash.from_contents(\"checksum\"),\n            path=\"test_path\",\n            database=None,\n        )\n\n    @pytest.mark.parametrize(\n        \"deprecation_date,current_date,expected_is_past_deprecation_date\",\n        [\n            (None, \"2024-05-02\", False),\n            (\"2024-05-01\", \"2024-05-02\", True),\n            (\"2024-05-01\", \"2024-05-01\", False),\n            (\"2024-05-01\", \"2024-04-30\", False),\n        ],\n    )\n    def test_is_past_deprecation_date(\n        self, default_model_node, deprecation_date, current_date, expected_is_past_deprecation_date\n    ):\n        with freeze_time(current_date):\n            if deprecation_date is not None:\n                default_model_node.deprecation_date = datetime.strptime(\n                    deprecation_date, \"%Y-%m-%d\"\n                ).astimezone()\n\n            assert default_model_node.is_past_deprecation_date is expected_is_past_deprecation_date\n\n    @pytest.mark.parametrize(\n        \"model_constraints,columns,expected_all_constraints\",\n        [\n            ([], {}, []),\n            (\n                [ModelLevelConstraint(type=ConstraintType.foreign_key)],\n                {},\n                [ModelLevelConstraint(type=ConstraintType.foreign_key)],\n            ),\n            (\n                [],\n                {\n                    \"id\": ColumnInfo(\n                        name=\"id\",\n                        constraints=[ColumnLevelConstraint(type=ConstraintType.foreign_key)],\n                    )\n                },\n                [ColumnLevelConstraint(type=ConstraintType.foreign_key)],\n            ),\n            (\n                [ModelLevelConstraint(type=ConstraintType.foreign_key)],\n                {\n                    \"id\": ColumnInfo(\n                        name=\"id\",\n                        constraints=[ColumnLevelConstraint(type=ConstraintType.foreign_key)],\n                    )\n                },\n                [\n                    ModelLevelConstraint(type=ConstraintType.foreign_key),\n                    ColumnLevelConstraint(type=ConstraintType.foreign_key),\n                ],\n            ),\n        ],\n    )\n    def test_all_constraints(\n        self, default_model_node, model_constraints, columns, expected_all_constraints\n    ):\n        default_model_node.constraints = model_constraints\n        default_model_node.columns = columns\n\n        assert default_model_node.all_constraints == expected_all_constraints\n\n\nclass TestSemanticModel:\n    @pytest.fixture(scope=\"function\")\n    def dimensions(self) -> List[Dimension]:\n        return [Dimension(name=\"ds\", type=DimensionType)]\n\n    @pytest.fixture(scope=\"function\")\n    def entities(self) -> List[Entity]:\n        return [Entity(name=\"test_entity\", type=EntityType.PRIMARY, expr=\"id\")]\n\n    @pytest.fixture(scope=\"function\")\n    def measures(self) -> List[Measure]:\n        return [Measure(name=\"test_measure\", agg=AggregationType.COUNT, expr=\"id\")]\n\n    @pytest.fixture(scope=\"function\")\n    def default_semantic_model(\n        self, dimensions: List[Dimension], entities: List[Entity], measures: List[Measure]\n    ) -> SemanticModel:\n        return SemanticModel(\n            name=\"test_semantic_model\",\n            resource_type=NodeType.SemanticModel,\n            model=\"ref('test_model')\",\n            package_name=\"test\",\n            path=\"test_path\",\n            original_file_path=\"test_fixture\",\n            unique_id=f\"{NodeType.SemanticModel}.test.test_semantic_model\",\n            fqn=[],\n            defaults=Defaults(agg_time_dimension=\"ds\"),\n            dimensions=dimensions,\n            entities=entities,\n            measures=measures,\n            node_relation=NodeRelation(\n                alias=\"test_alias\", schema_name=\"test_schema\", database=\"test_database\"\n            ),\n        )\n\n    @pytest.fixture(scope=\"function\")\n    def default_simple_metric(self) -> Metric:\n        return Metric(\n            name=\"test_metric\",\n            resource_type=NodeType.Metric,\n            package_name=\"test\",\n            path=\"test_path\",\n            original_file_path=\"test_fixture\",\n            unique_id=f\"{NodeType.Metric}.test.test_metric\",\n            fqn=[],\n            description=\"\",\n            label=\"\",\n            type=MetricType.SIMPLE,\n            type_params=MetricTypeParams(\n                metric_aggregation_params=MetricAggregationParams(\n                    semantic_model=\"test_semantic_model\",\n                    agg=AggregationType.COUNT,\n                )\n            ),\n        )\n\n    def test_checked_agg_time_dimension_for_measure_via_defaults(\n        self,\n        default_semantic_model: SemanticModel,\n    ):\n        assert default_semantic_model.defaults.agg_time_dimension is not None\n        measure = default_semantic_model.measures[0]\n        measure.agg_time_dimension = None\n        default_semantic_model.checked_agg_time_dimension_for_measure(\n            MeasureReference(element_name=measure.name)\n        )\n\n    def test_checked_agg_time_dimension_for_measure_via_measure(\n        self, default_semantic_model: SemanticModel\n    ):\n        default_semantic_model.defaults = None\n        measure = default_semantic_model.measures[0]\n        measure.agg_time_dimension = default_semantic_model.dimensions[0].name\n        default_semantic_model.checked_agg_time_dimension_for_measure(\n            MeasureReference(element_name=measure.name)\n        )\n\n    def test_checked_agg_time_dimension_for_measure_exception(\n        self, default_semantic_model: SemanticModel\n    ):\n        default_semantic_model.defaults = None\n        measure = default_semantic_model.measures[0]\n        measure.agg_time_dimension = None\n\n        with pytest.raises(AssertionError) as execinfo:\n            default_semantic_model.checked_agg_time_dimension_for_measure(\n                MeasureReference(measure.name)\n            )\n\n        assert (\n            f\"Aggregation time dimension for measure {measure.name} on semantic model {default_semantic_model.name}\"\n            in str(execinfo.value)\n        )\n\n    def test_checked_agg_time_dimension_for_simple_metric(\n        self, default_semantic_model: SemanticModel, default_simple_metric: Metric\n    ):\n        time_dimension_reference = (\n            default_semantic_model.checked_agg_time_dimension_for_simple_metric(\n                default_simple_metric\n            )\n        )\n        assert time_dimension_reference == TimeDimensionReference(element_name=\"ds\")\n\n    def test_checked_agg_time_dimension_for_simple_metric_missing_metric_aggregation_params(\n        self, default_semantic_model: SemanticModel, default_simple_metric: Metric\n    ):\n        default_simple_metric.type_params.metric_aggregation_params = None\n        with pytest.raises(AssertionError) as execinfo:\n            default_semantic_model.checked_agg_time_dimension_for_simple_metric(\n                default_simple_metric\n            )\n\n        assert \"Simple metrics must have metric_aggregation_params.\" in str(execinfo.value)\n\n    def test_check_agg_time_dimension_for_simple_metric_missing_agg_time_dimension(\n        self, default_semantic_model: SemanticModel, default_simple_metric: Metric\n    ):\n        default_semantic_model.defaults.agg_time_dimension = None\n        with pytest.raises(AssertionError) as execinfo:\n            default_semantic_model.checked_agg_time_dimension_for_simple_metric(\n                default_simple_metric\n            )\n\n        assert (\n            f\"Aggregation time dimension for metric {default_simple_metric.name} is not set!\"\n            in str(execinfo.value)\n        )\n\n    def test_semantic_model_same_contents(self, default_semantic_model: SemanticModel):\n        default_semantic_model_copy = deepcopy(default_semantic_model)\n\n        assert default_semantic_model.same_contents(default_semantic_model_copy)\n\n    def test_semantic_model_same_contents_update_model(\n        self, default_semantic_model: SemanticModel\n    ):\n        default_semantic_model_copy = deepcopy(default_semantic_model)\n        default_semantic_model_copy.model = \"ref('test_another_model')\"\n\n        assert not default_semantic_model.same_contents(default_semantic_model_copy)\n\n    def test_semantic_model_same_contents_different_node_relation(\n        self,\n        default_semantic_model: SemanticModel,\n    ):\n        default_semantic_model_copy = deepcopy(default_semantic_model)\n        default_semantic_model_copy.node_relation.alias = \"test_another_alias\"\n        # Relation should not be consided in same_contents\n        assert default_semantic_model.same_contents(default_semantic_model_copy)\n\n\n# Infer primary key\ndef test_no_primary_key():\n    model = model_node()\n    assert model.infer_primary_key([]) == []\n\n\ndef test_primary_key_model_constraint():\n    model = model_node()\n    model.constraints = [ModelLevelConstraint(type=ConstraintType.primary_key, columns=[\"pk\"])]\n    assertSameContents(model.infer_primary_key([]), [\"pk\"])\n\n    model.constraints = [\n        ModelLevelConstraint(type=ConstraintType.primary_key, columns=[\"pk1\", \"pk2\"])\n    ]\n    assertSameContents(model.infer_primary_key([]), [\"pk1\", \"pk2\"])\n\n\ndef test_primary_key_column_constraint():\n    model = model_node()\n    model.columns = {\n        \"column1\": ColumnInfo(\n            \"column1\", constraints=[ColumnLevelConstraint(type=ConstraintType.primary_key)]\n        ),\n        \"column2\": ColumnInfo(\"column2\"),\n    }\n    assertSameContents(model.infer_primary_key([]), [\"column1\"])\n\n\ndef test_unique_non_null_single():\n    model = model_node()\n    test1 = generic_test_node()\n    test1.test_metadata = TestMetadata(name=\"unique\", kwargs={\"column_name\": \"column1\"})\n    test2 = generic_test_node()\n    test2.test_metadata = TestMetadata(name=\"not_null\", kwargs={\"column_name\": \"column1\"})\n    test3 = generic_test_node()\n    test3.test_metadata = TestMetadata(name=\"unique\", kwargs={\"column_name\": \"column2\"})\n    tests = [test1, test2]\n    assertSameContents(model.infer_primary_key(tests), [\"column1\"])\n\n\ndef test_unique_non_null_multiple():\n    model = model_node()\n    tests = []\n    for i in range(2):\n        for enabled in [True, False]:\n            test1 = generic_test_node()\n            test1.test_metadata = TestMetadata(\n                name=\"unique\", kwargs={\"column_name\": \"column\" + str(i) + str(enabled)}\n            )\n            test1.config = TestConfig(enabled=enabled)\n            test2 = generic_test_node()\n            test2.test_metadata = TestMetadata(\n                name=\"not_null\", kwargs={\"column_name\": \"column\" + str(i) + str(enabled)}\n            )\n            test2.config = TestConfig(enabled=enabled)\n            tests.extend([test1, test2])\n\n    assertSameContents(\n        model.infer_primary_key(tests),\n        [\"column0True\", \"column1True\", \"column0False\", \"column1False\"],\n    )\n\n\ndef test_enabled_unique_single():\n    model = model_node()\n    test1 = generic_test_node()\n    test1.test_metadata = TestMetadata(name=\"unique\", kwargs={\"column_name\": \"column1\"})\n    test2 = generic_test_node()\n    test2.config = TestConfig(enabled=False)\n    test2.test_metadata = TestMetadata(name=\"unique\", kwargs={\"column_name\": \"column3\"})\n\n    tests = [test1, test2]\n    assertSameContents(model.infer_primary_key(tests), [\"column1\"])\n\n\ndef test_enabled_unique_multiple():\n    model = model_node()\n    test1 = generic_test_node()\n    test1.test_metadata = TestMetadata(name=\"unique\", kwargs={\"column_name\": \"column1\"})\n    test2 = generic_test_node()\n    test2.test_metadata = TestMetadata(name=\"unique\", kwargs={\"column_name\": \"column2 || column3\"})\n\n    tests = [test1, test2]\n    assertSameContents(model.infer_primary_key(tests), [\"column1\", \"column2 || column3\"])\n\n\ndef test_enabled_unique_combo_single():\n    model = model_node()\n    test1 = generic_test_node()\n    test1.test_metadata = TestMetadata(\n        name=\"unique_combination_of_columns\",\n        kwargs={\"combination_of_columns\": [\"column1\", \"column2\"]},\n    )\n    test2 = generic_test_node()\n    test2.config = TestConfig(enabled=False)\n    test2.test_metadata = TestMetadata(\n        name=\"unique_combination_of_columns\",\n        kwargs={\"combination_of_columns\": [\"column3\", \"column4\"]},\n    )\n\n    tests = [test1, test2]\n    assertSameContents(model.infer_primary_key(tests), [\"column1\", \"column2\"])\n\n\ndef test_enabled_unique_combo_multiple():\n    model = model_node()\n    test1 = generic_test_node()\n    test1.test_metadata = TestMetadata(\n        name=\"unique\", kwargs={\"combination_of_columns\": [\"column1\", \"column2\"]}\n    )\n    test2 = generic_test_node()\n    test2.test_metadata = TestMetadata(\n        name=\"unique\", kwargs={\"combination_of_columns\": [\"column3\", \"column4\"]}\n    )\n\n    tests = [test1, test2]\n    assertSameContents(\n        model.infer_primary_key(tests), [\"column1\", \"column2\", \"column3\", \"column4\"]\n    )\n\n\ndef test_disabled_unique_single():\n    model = model_node()\n    test1 = generic_test_node()\n    test1.config = TestConfig(enabled=False)\n    test1.test_metadata = TestMetadata(name=\"unique\", kwargs={\"column_name\": \"column1\"})\n    test2 = generic_test_node()\n    test2.test_metadata = TestMetadata(name=\"not_null\", kwargs={\"column_name\": \"column2\"})\n\n    tests = [test1, test2]\n    assertSameContents(model.infer_primary_key(tests), [\"column1\"])\n\n\ndef test_disabled_unique_multiple():\n    model = model_node()\n    test1 = generic_test_node()\n    test1.config = TestConfig(enabled=False)\n    test1.test_metadata = TestMetadata(name=\"unique\", kwargs={\"column_name\": \"column1\"})\n    test2 = generic_test_node()\n    test2.config = TestConfig(enabled=False)\n    test2.test_metadata = TestMetadata(name=\"unique\", kwargs={\"column_name\": \"column2 || column3\"})\n\n    tests = [test1, test2]\n    assertSameContents(model.infer_primary_key(tests), [\"column1\", \"column2 || column3\"])\n\n\ndef test_disabled_unique_combo_single():\n    model = model_node()\n    test1 = generic_test_node()\n    test1.config = TestConfig(enabled=False)\n    test1.test_metadata = TestMetadata(\n        name=\"unique\", kwargs={\"combination_of_columns\": [\"column1\", \"column2\"]}\n    )\n    test2 = generic_test_node()\n    test2.config = TestConfig(enabled=False)\n    test2.test_metadata = TestMetadata(\n        name=\"random\", kwargs={\"combination_of_columns\": [\"column3\", \"column4\"]}\n    )\n\n    tests = [test1, test2]\n    assertSameContents(model.infer_primary_key(tests), [\"column1\", \"column2\"])\n\n\ndef test_disabled_unique_combo_multiple():\n    model = model_node()\n    test1 = generic_test_node()\n    test1.config = TestConfig(enabled=False)\n    test1.test_metadata = TestMetadata(\n        name=\"unique\", kwargs={\"combination_of_columns\": [\"column1\", \"column2\"]}\n    )\n    test2 = generic_test_node()\n    test2.config = TestConfig(enabled=False)\n    test2.test_metadata = TestMetadata(\n        name=\"unique\", kwargs={\"combination_of_columns\": [\"column3\", \"column4\"]}\n    )\n\n    tests = [test1, test2]\n    assertSameContents(\n        model.infer_primary_key(tests), [\"column1\", \"column2\", \"column3\", \"column4\"]\n    )\n\n\ndef assertSameContents(list1, list2):\n    assert sorted(list1) == sorted(list2)\n\n\nclass TestParsedNode:\n    @pytest.fixture(scope=\"class\")\n    def parsed_node(self) -> ParsedNode:\n        return ParsedNode(\n            resource_type=NodeType.Model,\n            unique_id=\"model.test_package.test_name\",\n            name=\"test_name\",\n            package_name=\"test_package\",\n            schema=\"test_schema\",\n            alias=\"test_alias\",\n            fqn=[\"models\", \"test_name\"],\n            original_file_path=\"test_original_file_path\",\n            checksum=FileHash.from_contents(\"checksum\"),\n            path=\"test_path.sql\",\n            database=None,\n        )\n\n    def test_get_target_write_path(self, parsed_node):\n        write_path = parsed_node.get_target_write_path(\"target_path\", \"subdirectory\")\n        assert (\n            write_path\n            == \"target_path/subdirectory/test_package/test_original_file_path/test_path.sql\"\n        )\n\n    def test_get_target_write_path_split(self, parsed_node):\n        write_path = parsed_node.get_target_write_path(\"target_path\", \"subdirectory\", \"split\")\n        assert (\n            write_path\n            == \"target_path/subdirectory/test_package/test_original_file_path/test_path/test_path_split.sql\"\n        )\n"
  },
  {
    "path": "tests/unit/graph/test_queue.py",
    "content": "import networkx as nx\nimport pytest\n\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.graph.queue import GraphQueue\nfrom tests.unit.utils import MockNode, make_manifest\n\n\nclass TestGraphQueue:\n    @pytest.fixture(scope=\"class\")\n    def manifest(self) -> Manifest:\n        return make_manifest(\n            nodes=[\n                MockNode(package=\"test_package\", name=\"upstream_model\"),\n                MockNode(package=\"test_package\", name=\"downstream_model\"),\n            ]\n        )\n\n    @pytest.fixture(scope=\"class\")\n    def graph(self) -> nx.DiGraph:\n        graph = nx.DiGraph()\n        graph.add_edge(\"model.test_package.upstream_model\", \"model.test_package.downstream_model\")\n        return graph\n\n    def test_init_graph_queue(self, manifest, graph):\n        graph_queue = GraphQueue(graph=graph, manifest=manifest, selected={})\n\n        assert graph_queue.manifest == manifest\n        assert graph_queue.graph == graph\n        assert graph_queue.inner.queue == [(0, \"model.test_package.upstream_model\")]\n        assert graph_queue.in_progress == set()\n        assert graph_queue.queued == {\"model.test_package.upstream_model\"}\n        assert graph_queue.lock\n\n    def test_init_graph_queue_preserve_edges_false(self, manifest, graph):\n        graph_queue = GraphQueue(graph=graph, manifest=manifest, selected={}, preserve_edges=False)\n\n        # when preserve_edges is set to false, dependencies between nodes are no longer tracked in the priority queue\n        assert list(graph_queue.graph.edges) == []\n        assert graph_queue.inner.queue == [\n            (0, \"model.test_package.downstream_model\"),\n            (0, \"model.test_package.upstream_model\"),\n        ]\n        assert graph_queue.queued == {\n            \"model.test_package.upstream_model\",\n            \"model.test_package.downstream_model\",\n        }\n"
  },
  {
    "path": "tests/unit/graph/test_selector.py",
    "content": "import string\nfrom argparse import Namespace\nfrom queue import Empty\nfrom typing import List\nfrom unittest.mock import MagicMock\n\nimport networkx as nx\nimport pytest\n\nimport dbt.compilation\nimport dbt.config\nimport dbt.exceptions\nimport dbt.graph.cli as graph_cli\nimport dbt.graph.selector as graph_selector\nimport dbt.parser\nimport dbt.parser.manifest\nimport dbt.utils\nimport dbt_common.exceptions\nfrom dbt.config.runtime import RuntimeConfig\nfrom dbt.flags import set_from_args\nfrom dbt.graph import NodeSelector, parse_difference\nfrom dbt.node_types import NodeType\nfrom tests.unit.utils.manifest import make_manifest, make_model\n\nset_from_args(Namespace(WARN_ERROR=False), None)\n\n\ndef _get_graph():\n    integer_graph = nx.balanced_tree(2, 2, nx.DiGraph())\n\n    package_mapping = {\n        i: \"m.\" + (\"X\" if i % 2 == 0 else \"Y\") + \".\" + letter\n        for (i, letter) in enumerate(string.ascii_lowercase)\n    }\n\n    # Edges: [(X.a, Y.b), (X.a, X.c), (Y.b, Y.d), (Y.b, X.e), (X.c, Y.f), (X.c, X.g)]\n    return graph_selector.Graph(nx.relabel_nodes(integer_graph, package_mapping))\n\n\ndef _get_manifest(graph):\n    nodes = {}\n    for unique_id in graph:\n        fqn = unique_id.split(\".\")\n        node = MagicMock(\n            unique_id=unique_id,\n            fqn=fqn,\n            package_name=fqn[0],\n            tags=[],\n            resource_type=NodeType.Model,\n            empty=False,\n            config=MagicMock(enabled=True),\n            is_versioned=False,\n        )\n        nodes[unique_id] = node\n\n    nodes[\"m.X.a\"].tags = [\"abc\"]\n    nodes[\"m.Y.b\"].tags = [\"abc\", \"bcef\"]\n    nodes[\"m.X.c\"].tags = [\"abc\", \"bcef\"]\n    nodes[\"m.Y.d\"].tags = []\n    nodes[\"m.X.e\"].tags = [\"efg\", \"bcef\"]\n    nodes[\"m.Y.f\"].tags = [\"efg\", \"bcef\"]\n    nodes[\"m.X.g\"].tags = [\"efg\"]\n    return MagicMock(nodes=nodes)\n\n\n@pytest.fixture\ndef graph():\n    return _get_graph()\n\n\n@pytest.fixture\ndef mock_manifest_with_mock_graph(graph):\n    return _get_manifest(graph)\n\n\ndef id_macro(arg):\n    if isinstance(arg, str):\n        return arg\n    try:\n        return \"_\".join(arg)\n    except TypeError:\n        return arg\n\n\nrun_specs = [\n    # include by fqn\n    ([\"X.a\"], [], {\"m.X.a\"}),\n    # include by tag\n    ([\"tag:abc\"], [], {\"m.X.a\", \"m.Y.b\", \"m.X.c\"}),\n    # exclude by tag\n    ([\"*\"], [\"tag:abc\"], {\"m.Y.d\", \"m.X.e\", \"m.Y.f\", \"m.X.g\"}),\n    # tag + fqn\n    ([\"tag:abc\", \"a\"], [], {\"m.X.a\", \"m.Y.b\", \"m.X.c\"}),\n    ([\"tag:abc\", \"d\"], [], {\"m.X.a\", \"m.Y.b\", \"m.X.c\", \"m.Y.d\"}),\n    # multiple node selection across packages\n    ([\"X.a\", \"b\"], [], {\"m.X.a\", \"m.Y.b\"}),\n    ([\"X.a+\"], [\"b\"], {\"m.X.a\", \"m.X.c\", \"m.Y.d\", \"m.X.e\", \"m.Y.f\", \"m.X.g\"}),\n    # children\n    ([\"X.c+\"], [], {\"m.X.c\", \"m.Y.f\", \"m.X.g\"}),\n    ([\"X.a+1\"], [], {\"m.X.a\", \"m.Y.b\", \"m.X.c\"}),\n    ([\"X.a+\"], [\"tag:efg\"], {\"m.X.a\", \"m.Y.b\", \"m.X.c\", \"m.Y.d\"}),\n    # parents\n    ([\"+Y.f\"], [], {\"m.X.c\", \"m.Y.f\", \"m.X.a\"}),\n    ([\"1+Y.f\"], [], {\"m.X.c\", \"m.Y.f\"}),\n    # childrens parents\n    ([\"@X.c\"], [], {\"m.X.a\", \"m.X.c\", \"m.Y.f\", \"m.X.g\"}),\n    # multiple selection/exclusion\n    ([\"tag:abc\", \"tag:bcef\"], [], {\"m.X.a\", \"m.Y.b\", \"m.X.c\", \"m.X.e\", \"m.Y.f\"}),\n    ([\"tag:abc\", \"tag:bcef\"], [\"tag:efg\"], {\"m.X.a\", \"m.Y.b\", \"m.X.c\"}),\n    ([\"tag:abc\", \"tag:bcef\"], [\"tag:efg\", \"a\"], {\"m.Y.b\", \"m.X.c\"}),\n    # intersections\n    ([\"a,a\"], [], {\"m.X.a\"}),\n    ([\"+c,c+\"], [], {\"m.X.c\"}),\n    ([\"a,b\"], [], set()),\n    ([\"tag:abc,tag:bcef\"], [], {\"m.Y.b\", \"m.X.c\"}),\n    ([\"*,tag:abc,a\"], [], {\"m.X.a\"}),\n    ([\"a,tag:abc,*\"], [], {\"m.X.a\"}),\n    ([\"tag:abc,tag:bcef\"], [\"c\"], {\"m.Y.b\"}),\n    ([\"tag:bcef,tag:efg\"], [\"tag:bcef,@b\"], {\"m.Y.f\"}),\n    ([\"tag:bcef,tag:efg\"], [\"tag:bcef,@a\"], set()),\n    ([\"*,@a,+b\"], [\"*,tag:abc,tag:bcef\"], {\"m.X.a\"}),\n    ([\"tag:bcef,tag:efg\", \"*,tag:abc\"], [], {\"m.X.a\", \"m.Y.b\", \"m.X.c\", \"m.X.e\", \"m.Y.f\"}),\n    ([\"tag:bcef,tag:efg\", \"*,tag:abc\"], [\"e\"], {\"m.X.a\", \"m.Y.b\", \"m.X.c\", \"m.Y.f\"}),\n    ([\"tag:bcef,tag:efg\", \"*,tag:abc\"], [\"e\"], {\"m.X.a\", \"m.Y.b\", \"m.X.c\", \"m.Y.f\"}),\n    ([\"tag:bcef,tag:efg\", \"*,tag:abc\"], [\"e\", \"f\"], {\"m.X.a\", \"m.Y.b\", \"m.X.c\"}),\n    ([\"tag:bcef,tag:efg\", \"*,tag:abc\"], [\"tag:abc,tag:bcef\"], {\"m.X.a\", \"m.X.e\", \"m.Y.f\"}),\n    ([\"tag:bcef,tag:efg\", \"*,tag:abc\"], [\"tag:abc,tag:bcef\", \"tag:abc,a\"], {\"m.X.e\", \"m.Y.f\"}),\n]\n\n\n@pytest.mark.parametrize(\"include,exclude,expected\", run_specs, ids=id_macro)\ndef test_run_specs(include, exclude, expected, graph, mock_manifest_with_mock_graph):\n    selector = graph_selector.NodeSelector(graph, mock_manifest_with_mock_graph)\n    spec = graph_cli.parse_difference(include, exclude)\n    selected, _ = selector.select_nodes(spec)\n\n    assert selected == expected\n\n\nparam_specs = [\n    (\"a\", False, None, False, None, \"fqn\", \"a\", False),\n    (\"+a\", True, None, False, None, \"fqn\", \"a\", False),\n    (\"256+a\", True, 256, False, None, \"fqn\", \"a\", False),\n    (\"a+\", False, None, True, None, \"fqn\", \"a\", False),\n    (\"a+256\", False, None, True, 256, \"fqn\", \"a\", False),\n    (\"+a+\", True, None, True, None, \"fqn\", \"a\", False),\n    (\"16+a+32\", True, 16, True, 32, \"fqn\", \"a\", False),\n    (\"@a\", False, None, False, None, \"fqn\", \"a\", True),\n    (\"a.b\", False, None, False, None, \"fqn\", \"a.b\", False),\n    (\"+a.b\", True, None, False, None, \"fqn\", \"a.b\", False),\n    (\"256+a.b\", True, 256, False, None, \"fqn\", \"a.b\", False),\n    (\"a.b+\", False, None, True, None, \"fqn\", \"a.b\", False),\n    (\"a.b+256\", False, None, True, 256, \"fqn\", \"a.b\", False),\n    (\"+a.b+\", True, None, True, None, \"fqn\", \"a.b\", False),\n    (\"16+a.b+32\", True, 16, True, 32, \"fqn\", \"a.b\", False),\n    (\"@a.b\", False, None, False, None, \"fqn\", \"a.b\", True),\n    (\"a.b.*\", False, None, False, None, \"fqn\", \"a.b.*\", False),\n    (\"+a.b.*\", True, None, False, None, \"fqn\", \"a.b.*\", False),\n    (\"256+a.b.*\", True, 256, False, None, \"fqn\", \"a.b.*\", False),\n    (\"a.b.*+\", False, None, True, None, \"fqn\", \"a.b.*\", False),\n    (\"a.b.*+256\", False, None, True, 256, \"fqn\", \"a.b.*\", False),\n    (\"+a.b.*+\", True, None, True, None, \"fqn\", \"a.b.*\", False),\n    (\"16+a.b.*+32\", True, 16, True, 32, \"fqn\", \"a.b.*\", False),\n    (\"@a.b.*\", False, None, False, None, \"fqn\", \"a.b.*\", True),\n    (\"tag:a\", False, None, False, None, \"tag\", \"a\", False),\n    (\"+tag:a\", True, None, False, None, \"tag\", \"a\", False),\n    (\"256+tag:a\", True, 256, False, None, \"tag\", \"a\", False),\n    (\"tag:a+\", False, None, True, None, \"tag\", \"a\", False),\n    (\"tag:a+256\", False, None, True, 256, \"tag\", \"a\", False),\n    (\"+tag:a+\", True, None, True, None, \"tag\", \"a\", False),\n    (\"16+tag:a+32\", True, 16, True, 32, \"tag\", \"a\", False),\n    (\"@tag:a\", False, None, False, None, \"tag\", \"a\", True),\n    (\"source:a\", False, None, False, None, \"source\", \"a\", False),\n    (\"source:a+\", False, None, True, None, \"source\", \"a\", False),\n    (\"source:a+1\", False, None, True, 1, \"source\", \"a\", False),\n    (\"source:a+32\", False, None, True, 32, \"source\", \"a\", False),\n    (\"@source:a\", False, None, False, None, \"source\", \"a\", True),\n]\n\n\n@pytest.mark.parametrize(\n    \"spec,parents,parents_depth,children,children_depth,filter_type,filter_value,childrens_parents\",\n    param_specs,\n    ids=id_macro,\n)\ndef test_parse_specs(\n    spec,\n    parents,\n    parents_depth,\n    children,\n    children_depth,\n    filter_type,\n    filter_value,\n    childrens_parents,\n):\n    parsed = graph_selector.SelectionCriteria.from_single_spec(spec)\n    assert parsed.parents == parents\n    assert parsed.parents_depth == parents_depth\n    assert parsed.children == children\n    assert parsed.children_depth == children_depth\n    assert parsed.method == filter_type\n    assert parsed.value == filter_value\n    assert parsed.childrens_parents == childrens_parents\n\n\ninvalid_specs = [\n    \"@a+\",\n    \"@a.b+\",\n    \"@a.b*+\",\n    \"@tag:a+\",\n    \"@source:a+\",\n]\n\n\n@pytest.mark.parametrize(\"invalid\", invalid_specs, ids=lambda k: str(k))\ndef test_invalid_specs(invalid):\n    with pytest.raises(dbt_common.exceptions.DbtRuntimeError):\n        graph_selector.SelectionCriteria.from_single_spec(invalid)\n\n\nclass TestCompiler:\n    def test_single_model(self, runtime_config: RuntimeConfig):\n        model = make_model(pkg=\"pkg\", name=\"model_one\", code=\"SELECT * FROM events\")\n        manifest = make_manifest(nodes=[model])\n\n        compiler = dbt.compilation.Compiler(config=runtime_config)\n        linker = compiler.compile(manifest)\n\n        assert linker.nodes() == {model.unique_id}\n        assert linker.edges() == set()\n\n    def test_two_models_simple_ref(self, runtime_config: RuntimeConfig):\n        model_one = make_model(pkg=\"pkg\", name=\"model_one\", code=\"SELECT * FROM events\")\n        model_two = make_model(\n            pkg=\"pkg\",\n            name=\"model_two\",\n            code=\"SELECT * FROM {{ref('model_one')}}\",\n            refs=[model_one],\n        )\n        models = [model_one, model_two]\n        manifest = make_manifest(nodes=models)\n\n        compiler = dbt.compilation.Compiler(config=runtime_config)\n        linker = compiler.compile(manifest)\n\n        expected_nodes: List[str] = [model.unique_id for model in models]\n        assert linker.nodes() == set(expected_nodes)\n        assert list(linker.edges()) == [tuple(expected_nodes)]\n\n\nclass TestNodeSelector:\n    def test_dependency_list(self, runtime_config: RuntimeConfig):\n        model_one = make_model(pkg=\"pkg\", name=\"model_one\", code=\"SELECT * FROM events\")\n        model_two = make_model(\n            pkg=\"pkg\",\n            name=\"model_two\",\n            code=\"SELECT * FROM {{ref('model_one')}}\",\n            refs=[model_one],\n        )\n        model_three = make_model(\n            pkg=\"pkg\",\n            name=\"model_three\",\n            code=\"\"\"\n                SELECT * FROM {{ ref(\"model_1\") }}\n                union all\n                SELECT * FROM {{ ref(\"model_2\") }}\n            \"\"\",\n            refs=[model_one, model_two],\n        )\n        model_four = make_model(\n            pkg=\"pkg\",\n            name=\"model_four\",\n            code=\"SELECT * FROM {{ref('model_three')}}\",\n            refs=[model_three],\n        )\n        models = [model_one, model_two, model_three, model_four]\n        manifest = make_manifest(nodes=models)\n\n        # Get the graph\n        compiler = dbt.compilation.Compiler(runtime_config)\n        graph = compiler.compile(manifest)\n\n        # Create the selector and get the queue\n        selector = NodeSelector(graph, manifest)\n        queue = selector.get_graph_queue(\n            parse_difference(\n                None,\n                None,\n            )\n        )\n\n        for model in models:\n            assert not queue.empty()\n            got = queue.get(block=False)\n            assert got.unique_id == model.unique_id\n            with pytest.raises(Empty):\n                queue.get(block=False)\n            queue.mark_done(got.unique_id)\n        assert queue.empty()\n\n    def test_select_downstream_of_empty_model(self, runtime_config: RuntimeConfig):\n        # empty model\n        model_one = make_model(pkg=\"other\", name=\"model_one\", code=\"\")\n        # non-empty model\n        model_two = make_model(\n            pkg=\"pkg\",\n            name=\"model_two\",\n            code=\"\"\"select * from {{ref('model_one')}}\"\"\",\n            refs=[model_one],\n        )\n        models = [model_one, model_two]\n        manifest = make_manifest(nodes=models)\n\n        # Get the graph\n        compiler = dbt.compilation.Compiler(runtime_config)\n        graph = compiler.compile(manifest)\n\n        # Ensure that model_two is selected as downstream of model_one\n        selector = NodeSelector(graph, manifest)\n        spec = graph_selector.SelectionCriteria.from_single_spec(\"model_one+\")\n        assert selector.get_selected(spec) == {\"model.pkg.model_two\"}\n\n        # Ensure that --indirect-selection empty returns the same result\n        spec.indirect_selection = graph_selector.IndirectSelection.Empty\n        assert selector.get_selected(spec) == {\"model.pkg.model_two\"}\n"
  },
  {
    "path": "tests/unit/graph/test_selector_methods.py",
    "content": "import copy\nfrom argparse import Namespace\nfrom dataclasses import replace\nfrom pathlib import Path\nfrom unittest import mock\n\nimport pytest\n\nimport dbt.compilation\nimport dbt_common.exceptions\nfrom dbt.artifacts.resources import ColumnInfo, FileHash\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.contracts.state import PreviousState\nfrom dbt.graph import NodeSelector\nfrom dbt.graph.selector_methods import (\n    AccessSelectorMethod,\n    ConfigSelectorMethod,\n    ExposureSelectorMethod,\n    FileSelectorMethod,\n    GroupSelectorMethod,\n    MethodManager,\n    MetricSelectorMethod,\n    PackageSelectorMethod,\n    PathSelectorMethod,\n    QualifiedNameSelectorMethod,\n    SavedQuerySelectorMethod,\n    SelectorSelectorMethod,\n    SemanticModelSelectorMethod,\n    SourceSelectorMethod,\n    StateSelectorMethod,\n    TagSelectorMethod,\n    TestNameSelectorMethod,\n    TestTypeSelectorMethod,\n    UnitTestSelectorMethod,\n    VersionSelectorMethod,\n)\nfrom dbt.graph.selector_spec import (\n    SelectionCriteria,\n    SelectionIntersection,\n    SelectionUnion,\n)\nfrom dbt_common.ui import warning_tag\nfrom tests.unit.utils import replace_config\nfrom tests.unit.utils.manifest import (\n    make_exposure,\n    make_group,\n    make_macro,\n    make_metric,\n    make_model,\n    make_saved_query,\n    make_seed,\n    make_semantic_model,\n    make_unit_test,\n)\n\n\ndef search_manifest_using_method(manifest, method, selection):\n    selected = method.search(\n        set(manifest.nodes)\n        | set(manifest.sources)\n        | set(manifest.exposures)\n        | set(manifest.metrics)\n        | set(manifest.semantic_models)\n        | set(manifest.saved_queries)\n        | set(manifest.unit_tests),\n        selection,\n    )\n    results = {manifest.expect(uid).search_name for uid in selected}\n    return results\n\n\ndef test_select_fqn(manifest):\n    methods = MethodManager(manifest, None)\n    method = methods.get_method(\"fqn\", [])\n    assert isinstance(method, QualifiedNameSelectorMethod)\n    assert method.arguments == []\n\n    assert search_manifest_using_method(manifest, method, \"pkg.unions\") == {\n        \"union_model\",\n        \"mynamespace.union_model\",\n    }\n    assert not search_manifest_using_method(manifest, method, \"ext.unions\")\n    # sources don't show up, because selection pretends they have no FQN. Should it?\n    assert search_manifest_using_method(manifest, method, \"pkg\") == {\n        \"union_model\",\n        \"versioned_model.v1\",\n        \"versioned_model.v2\",\n        \"versioned_model.v3\",\n        \"versioned_model.v4\",\n        \"versioned_model.v12\",\n        \"table_model\",\n        \"table_model_py\",\n        \"table_model_csv\",\n        \"view_model\",\n        \"ephemeral_model\",\n        \"seed\",\n        \"mynamespace.union_model\",\n        \"mynamespace.ephemeral_model\",\n        \"mynamespace.seed\",\n        \"unit_test_table_model\",\n    }\n    assert search_manifest_using_method(manifest, method, \"ext\") == {\"ext_model\"}\n    # versions\n    assert search_manifest_using_method(manifest, method, \"versioned_model\") == {\n        \"versioned_model.v1\",\n        \"versioned_model.v2\",\n        \"versioned_model.v3\",\n        \"versioned_model.v4\",\n        \"versioned_model.v12\",\n    }\n    assert search_manifest_using_method(manifest, method, \"versioned_model.v1\") == {\n        \"versioned_model.v1\"\n    }\n    # version selection with _ instead of '.'\n    assert search_manifest_using_method(manifest, method, \"versioned_model_v1\") == {\n        \"versioned_model.v1\"\n    }\n    # version selection with _ instead of '.' - latest version\n    assert search_manifest_using_method(manifest, method, \"versioned_model_v2\") == {\n        \"versioned_model.v2\"\n    }\n    # wildcards\n    assert search_manifest_using_method(manifest, method, \"*.*.*_model\") == {\n        \"mynamespace.union_model\",\n        \"mynamespace.ephemeral_model\",\n        \"test_semantic_model\",\n        \"union_model\",\n        \"unit_test_table_model\",\n    }\n    # multiple wildcards\n    assert search_manifest_using_method(manifest, method, \"*unions*\") == {\n        \"union_model\",\n        \"mynamespace.union_model\",\n    }\n    # negation\n    assert not search_manifest_using_method(manifest, method, \"!pkg*\")\n    # single wildcard\n    assert search_manifest_using_method(manifest, method, \"pkg.t*\") == {\n        \"table_model\",\n        \"table_model_py\",\n        \"table_model_csv\",\n        \"unit_test_table_model\",\n    }\n    # wildcard and ? (matches exactly one character)\n    assert search_manifest_using_method(manifest, method, \"*ext_m?del\") == {\"ext_model\"}\n    # multiple ?\n    assert search_manifest_using_method(manifest, method, \"*.?????_model\") == {\n        \"union_model\",\n        \"table_model\",\n        \"mynamespace.union_model\",\n    }\n    # multiple ranges\n    assert search_manifest_using_method(manifest, method, \"*.[t-u][a-n][b-i][l-o][e-n]_model\") == {\n        \"union_model\",\n        \"table_model\",\n        \"mynamespace.union_model\",\n    }\n\n\ndef test_select_tag(manifest):\n    methods = MethodManager(manifest, None)\n    method = methods.get_method(\"tag\", [])\n    assert isinstance(method, TagSelectorMethod)\n    assert method.arguments == []\n\n    assert search_manifest_using_method(manifest, method, \"uses_ephemeral\") == {\n        \"view_model\",\n        \"table_model\",\n    }\n    assert not search_manifest_using_method(manifest, method, \"missing\")\n    assert search_manifest_using_method(manifest, method, \"uses_eph*\") == {\n        \"view_model\",\n        \"table_model\",\n    }\n\n\ndef test_select_selector(manifest, runtime_config):\n    compiler = dbt.compilation.Compiler(runtime_config)\n    graph = compiler.compile(manifest)\n    selectors = {\n        \"union_selector\": {\n            \"definition\": SelectionUnion(\n                components=[\n                    SelectionCriteria.from_single_spec(\"fqn:table_model\"),\n                    SelectionCriteria.from_single_spec(\"fqn:view_model\"),\n                ]\n            ),\n        },\n        \"intersection_selector\": {\n            \"definition\": SelectionIntersection(\n                components=[\n                    SelectionCriteria.from_single_spec(\"selector:union_selector\"),\n                    SelectionCriteria.from_single_spec(\"fqn:table_model\"),\n                ]\n            ),\n        },\n    }\n    selector = NodeSelector(graph, manifest, selectors=selectors)\n    methods = MethodManager(manifest, None)\n    method = methods.get_method(\n        \"selector\", [], selectors=selectors, get_selected_callback=selector.get_selected\n    )\n    assert isinstance(method, SelectorSelectorMethod)\n\n    assert search_manifest_using_method(manifest, method, \"union_selector\").issuperset(\n        {\n            \"table_model\",\n            \"view_model\",\n        }\n    )\n    assert search_manifest_using_method(manifest, method, \"intersection_selector\").issuperset(\n        {\n            \"table_model\",\n        }\n    )\n\n\ndef test_select_group(manifest, view_model):\n    group_name = \"my_group\"\n    group = make_group(\"test\", group_name)\n    manifest.groups[group.unique_id] = group\n    change_node(\n        manifest,\n        replace(view_model, config={\"materialized\": \"view\", \"group\": group_name}),\n    )\n    methods = MethodManager(manifest, None)\n    method = methods.get_method(\"group\", [])\n    assert isinstance(method, GroupSelectorMethod)\n    assert method.arguments == []\n\n    assert search_manifest_using_method(manifest, method, group_name) == {\"view_model\"}\n    assert search_manifest_using_method(manifest, method, \"my?group\") == {\"view_model\"}\n    assert not search_manifest_using_method(manifest, method, \"not_my_group\")\n\n\ndef test_select_access(manifest, view_model):\n    change_node(\n        manifest,\n        replace(view_model, access=\"public\"),\n    )\n    methods = MethodManager(manifest, None)\n    method = methods.get_method(\"access\", [])\n    assert isinstance(method, AccessSelectorMethod)\n    assert method.arguments == []\n\n    assert search_manifest_using_method(manifest, method, \"public\") == {\"view_model\"}\n    assert not search_manifest_using_method(manifest, method, \"private\")\n\n\ndef test_select_source(manifest):\n    methods = MethodManager(manifest, None)\n    method = methods.get_method(\"source\", [])\n    assert isinstance(method, SourceSelectorMethod)\n    assert method.arguments == []\n\n    # the lookup is based on how many components you provide: source, source.table, package.source.table\n    assert search_manifest_using_method(manifest, method, \"raw\") == {\n        \"raw.seed\",\n        \"raw.ext_source\",\n        \"raw.ext_source_2\",\n    }\n    assert search_manifest_using_method(manifest, method, \"raw.seed\") == {\"raw.seed\"}\n    assert search_manifest_using_method(manifest, method, \"pkg.raw.seed\") == {\"raw.seed\"}\n    assert search_manifest_using_method(manifest, method, \"pkg.*.*\") == {\"raw.seed\"}\n    assert search_manifest_using_method(manifest, method, \"raw.*\") == {\n        \"raw.seed\",\n        \"raw.ext_source\",\n        \"raw.ext_source_2\",\n    }\n    assert search_manifest_using_method(manifest, method, \"ext.raw.*\") == {\n        \"raw.ext_source\",\n        \"raw.ext_source_2\",\n    }\n    assert not search_manifest_using_method(manifest, method, \"missing\")\n    assert not search_manifest_using_method(manifest, method, \"raw.missing\")\n    assert not search_manifest_using_method(manifest, method, \"missing.raw.seed\")\n\n    assert search_manifest_using_method(manifest, method, \"ext.*.*\") == {\n        \"ext_raw.ext_source\",\n        \"ext_raw.ext_source_2\",\n        \"raw.ext_source\",\n        \"raw.ext_source_2\",\n    }\n    assert search_manifest_using_method(manifest, method, \"ext_raw\") == {\n        \"ext_raw.ext_source\",\n        \"ext_raw.ext_source_2\",\n    }\n    assert search_manifest_using_method(manifest, method, \"ext.ext_raw.*\") == {\n        \"ext_raw.ext_source\",\n        \"ext_raw.ext_source_2\",\n    }\n    assert not search_manifest_using_method(manifest, method, \"pkg.ext_raw.*\")\n    assert search_manifest_using_method(manifest, method, \"*.ext_[s]ourc?\") == {\n        \"ext_raw.ext_source\",\n        \"raw.ext_source\",\n    }\n\n\n# TODO: this requires writing out files\n@pytest.mark.skip(\"TODO: write manifest files to disk\")\ndef test_select_path(manifest):\n    methods = MethodManager(manifest, None)\n    method = methods.get_method(\"path\", [])\n    assert isinstance(method, PathSelectorMethod)\n    assert method.arguments == []\n\n    assert search_manifest_using_method(manifest, method, \"subdirectory/*.sql\") == {\n        \"union_model\",\n        \"table_model\",\n    }\n    assert search_manifest_using_method(manifest, method, \"subdirectory/union_model.sql\") == {\n        \"union_model\"\n    }\n    assert search_manifest_using_method(manifest, method, \"models/*.sql\") == {\n        \"view_model\",\n        \"ephemeral_model\",\n    }\n    assert not search_manifest_using_method(manifest, method, \"missing\")\n    assert not search_manifest_using_method(manifest, method, \"models/missing.sql\")\n    assert not search_manifest_using_method(manifest, method, \"models/missing*\")\n\n\ndef test_select_file(manifest):\n    methods = MethodManager(manifest, None)\n    method = methods.get_method(\"file\", [])\n    assert isinstance(method, FileSelectorMethod)\n    assert method.arguments == []\n\n    assert search_manifest_using_method(manifest, method, \"table_model.sql\") == {\"table_model\"}\n    assert search_manifest_using_method(manifest, method, \"table_model.py\") == {\"table_model_py\"}\n    assert search_manifest_using_method(manifest, method, \"table_model.csv\") == {\"table_model_csv\"}\n    assert search_manifest_using_method(manifest, method, \"union_model.sql\") == {\n        \"union_model\",\n        \"mynamespace.union_model\",\n    }\n    assert not search_manifest_using_method(manifest, method, \"missing.sql\")\n    assert not search_manifest_using_method(manifest, method, \"missing.py\")\n    assert search_manifest_using_method(manifest, method, \"table_*.csv\") == {\"table_model_csv\"}\n\n    # stem selector match\n    assert search_manifest_using_method(manifest, method, \"union_model\") == {\n        \"union_model\",\n        \"mynamespace.union_model\",\n    }\n    assert search_manifest_using_method(manifest, method, \"versioned_model_v1\") == {\n        \"versioned_model.v1\"\n    }\n\n\ndef test_select_package(manifest):\n    methods = MethodManager(manifest, None)\n    method = methods.get_method(\"package\", [])\n    assert isinstance(method, PackageSelectorMethod)\n    assert method.arguments == []\n\n    assert search_manifest_using_method(manifest, method, \"pkg\") == {\n        \"union_model\",\n        \"versioned_model.v1\",\n        \"versioned_model.v2\",\n        \"versioned_model.v3\",\n        \"versioned_model.v4\",\n        \"versioned_model.v12\",\n        \"table_model\",\n        \"table_model_py\",\n        \"table_model_csv\",\n        \"view_model\",\n        \"ephemeral_model\",\n        \"seed\",\n        \"raw.seed\",\n        \"unique_table_model_id\",\n        \"not_null_table_model_id\",\n        \"unique_view_model_id\",\n        \"view_test_nothing\",\n        \"mynamespace.seed\",\n        \"mynamespace.ephemeral_model\",\n        \"mynamespace.union_model\",\n        \"unit_test_table_model\",\n    }\n    assert search_manifest_using_method(manifest, method, \"ext\") == {\n        \"ext_model\",\n        \"ext_raw.ext_source\",\n        \"ext_raw.ext_source_2\",\n        \"raw.ext_source\",\n        \"raw.ext_source_2\",\n        \"unique_ext_raw_ext_source_id\",\n    }\n\n    assert not search_manifest_using_method(manifest, method, \"missing\")\n\n    assert search_manifest_using_method(manifest, method, \"ex*\") == {\n        \"ext_model\",\n        \"ext_raw.ext_source\",\n        \"ext_raw.ext_source_2\",\n        \"raw.ext_source\",\n        \"raw.ext_source_2\",\n        \"unique_ext_raw_ext_source_id\",\n    }\n\n\ndef test_select_package_this(manifest):\n    new_manifest = copy.deepcopy(manifest)\n\n    # change the package name for all nodes except ones where the unique_id contains \"table_model\"\n    for id, node in new_manifest.nodes.items():\n        if \"table_model\" not in id:\n            node.package_name = \"foo\"\n\n    for source in new_manifest.sources.values():\n        if \"table_model\" not in source.unique_id:\n            source.package_name = \"foo\"\n\n    methods = MethodManager(new_manifest, None)\n    method = methods.get_method(\"package\", [])\n    assert isinstance(method, PackageSelectorMethod)\n    assert method.arguments == []\n\n    assert search_manifest_using_method(new_manifest, method, \"this\") == {\n        \"not_null_table_model_id\",\n        \"table_model\",\n        \"table_model_csv\",\n        \"table_model_py\",\n        \"unique_table_model_id\",\n        \"unit_test_table_model\",\n    }\n\n\ndef test_select_config_materialized(manifest):\n    methods = MethodManager(manifest, None)\n    method = methods.get_method(\"config\", [\"materialized\"])\n    assert isinstance(method, ConfigSelectorMethod)\n    assert method.arguments == [\"materialized\"]\n\n    assert search_manifest_using_method(manifest, method, \"view\") == {\"view_model\", \"ext_model\"}\n    assert search_manifest_using_method(manifest, method, \"table\") == {\n        \"table_model\",\n        \"table_model_py\",\n        \"table_model_csv\",\n        \"union_model\",\n        \"versioned_model.v1\",\n        \"versioned_model.v2\",\n        \"versioned_model.v3\",\n        \"versioned_model.v4\",\n        \"versioned_model.v12\",\n        \"mynamespace.union_model\",\n    }\n\n\ndef test_select_config_meta(manifest):\n    methods = MethodManager(manifest, None)\n\n    string_method = methods.get_method(\"config\", [\"meta\", \"string_property\"])\n    assert search_manifest_using_method(manifest, string_method, \"some_string\") == {\"table_model\"}\n    assert not search_manifest_using_method(manifest, string_method, \"other_string\") == {\n        \"table_model\"\n    }\n\n    truthy_bool_method = methods.get_method(\"config\", [\"meta\", \"truthy_bool_property\"])\n    assert search_manifest_using_method(manifest, truthy_bool_method, \"true\") == {\"table_model\"}\n    assert not search_manifest_using_method(manifest, truthy_bool_method, \"false\") == {\n        \"table_model\"\n    }\n    assert not search_manifest_using_method(manifest, truthy_bool_method, \"other\") == {\n        \"table_model\"\n    }\n\n    falsy_bool_method = methods.get_method(\"config\", [\"meta\", \"falsy_bool_property\"])\n    assert search_manifest_using_method(manifest, falsy_bool_method, \"false\") == {\"table_model\"}\n    assert not search_manifest_using_method(manifest, falsy_bool_method, \"true\") == {\"table_model\"}\n    assert not search_manifest_using_method(manifest, falsy_bool_method, \"other\") == {\n        \"table_model\"\n    }\n\n    list_method = methods.get_method(\"config\", [\"meta\", \"list_property\"])\n    assert search_manifest_using_method(manifest, list_method, \"some_value\") == {\"table_model\"}\n    assert search_manifest_using_method(manifest, list_method, \"true\") == {\"table_model\"}\n    assert search_manifest_using_method(manifest, list_method, \"false\") == {\"table_model\"}\n    assert not search_manifest_using_method(manifest, list_method, \"other\") == {\"table_model\"}\n\n\ndef test_select_test_name(manifest):\n    methods = MethodManager(manifest, None)\n    method = methods.get_method(\"test_name\", [])\n    assert isinstance(method, TestNameSelectorMethod)\n    assert method.arguments == []\n\n    assert search_manifest_using_method(manifest, method, \"unique\") == {\n        \"unique_table_model_id\",\n        \"unique_view_model_id\",\n        \"unique_ext_raw_ext_source_id\",\n    }\n    assert search_manifest_using_method(manifest, method, \"not_null\") == {\n        \"not_null_table_model_id\"\n    }\n    assert not search_manifest_using_method(manifest, method, \"notatest\")\n    assert search_manifest_using_method(manifest, method, \"not_*\") == {\"not_null_table_model_id\"}\n\n\ndef test_select_test_type(manifest):\n    methods = MethodManager(manifest, None)\n    method = methods.get_method(\"test_type\", [])\n    assert isinstance(method, TestTypeSelectorMethod)\n    assert method.arguments == []\n    assert search_manifest_using_method(manifest, method, \"generic\") == {\n        \"unique_table_model_id\",\n        \"not_null_table_model_id\",\n        \"unique_view_model_id\",\n        \"unique_ext_raw_ext_source_id\",\n    }\n    assert search_manifest_using_method(manifest, method, \"singular\") == {\"view_test_nothing\"}\n    # test backwards compatibility\n    assert search_manifest_using_method(manifest, method, \"schema\") == {\n        \"unique_table_model_id\",\n        \"not_null_table_model_id\",\n        \"unique_view_model_id\",\n        \"unique_ext_raw_ext_source_id\",\n    }\n    assert search_manifest_using_method(manifest, method, \"data\") == {\n        \"view_test_nothing\",\n        \"unique_table_model_id\",\n        \"not_null_table_model_id\",\n        \"unique_view_model_id\",\n        \"unique_ext_raw_ext_source_id\",\n    }\n    assert search_manifest_using_method(manifest, method, \"unit\") == {\n        \"unit_test_table_model\",\n    }\n\n\ndef test_select_version(manifest):\n    methods = MethodManager(manifest, None)\n    method = methods.get_method(\"version\", [])\n    assert isinstance(method, VersionSelectorMethod)\n    assert method.arguments == []\n    assert search_manifest_using_method(manifest, method, \"latest\") == {\"versioned_model.v2\"}\n    assert search_manifest_using_method(manifest, method, \"old\") == {\"versioned_model.v1\"}\n    assert search_manifest_using_method(manifest, method, \"prerelease\") == {\n        \"versioned_model.v3\",\n        \"versioned_model.v4\",\n        \"versioned_model.v12\",\n    }\n    assert search_manifest_using_method(manifest, method, \"none\") == {\n        \"table_model_py\",\n        \"union_model\",\n        \"view_model\",\n        \"mynamespace.ephemeral_model\",\n        \"table_model_csv\",\n        \"ephemeral_model\",\n        \"mynamespace.union_model\",\n        \"table_model\",\n        \"ext_model\",\n    }\n\n\ndef test_select_exposure(manifest):\n    exposure = make_exposure(\"test\", \"my_exposure\")\n    manifest.exposures[exposure.unique_id] = exposure\n    methods = MethodManager(manifest, None)\n    method = methods.get_method(\"exposure\", [])\n    assert isinstance(method, ExposureSelectorMethod)\n    assert search_manifest_using_method(manifest, method, \"my_exposure\") == {\"my_exposure\"}\n    assert not search_manifest_using_method(manifest, method, \"not_my_exposure\")\n    assert search_manifest_using_method(manifest, method, \"my_e*e\") == {\"my_exposure\"}\n\n\ndef test_select_metric(manifest):\n    metric = make_metric(\"test\", \"my_metric\")\n    manifest.metrics[metric.unique_id] = metric\n    methods = MethodManager(manifest, None)\n    method = methods.get_method(\"metric\", [])\n    assert isinstance(method, MetricSelectorMethod)\n    assert search_manifest_using_method(manifest, method, \"my_metric\") == {\"my_metric\"}\n    assert not search_manifest_using_method(manifest, method, \"not_my_metric\")\n    assert search_manifest_using_method(manifest, method, \"*_metric\") == {\"my_metric\"}\n\n\ndef test_select_semantic_model(manifest, table_model):\n    semantic_model = make_semantic_model(\n        \"pkg\",\n        \"customer\",\n        model=table_model,\n        path=\"_semantic_models.yml\",\n    )\n    manifest.semantic_models[semantic_model.unique_id] = semantic_model\n    methods = MethodManager(manifest, None)\n    method = methods.get_method(\"semantic_model\", [])\n    assert isinstance(method, SemanticModelSelectorMethod)\n    assert search_manifest_using_method(manifest, method, \"customer\") == {\"customer\"}\n    assert not search_manifest_using_method(manifest, method, \"not_customer\")\n    assert search_manifest_using_method(manifest, method, \"*omer\") == {\"customer\"}\n\n\ndef test_select_semantic_model_by_tag(manifest, table_model):\n    semantic_model = make_semantic_model(\n        \"pkg\",\n        \"customer\",\n        model=table_model,\n        path=\"_semantic_models.yml\",\n    )\n    manifest.semantic_models[semantic_model.unique_id] = semantic_model\n    methods = MethodManager(manifest, None)\n    method = methods.get_method(\"tag\", [])\n    assert isinstance(method, TagSelectorMethod)\n    assert method.arguments == []\n    search_manifest_using_method(manifest, method, \"any_tag\")\n\n\ndef test_select_saved_query(manifest: Manifest) -> None:\n    metric = make_metric(\"test\", \"my_metric\")\n    saved_query = make_saved_query(\n        \"pkg\",\n        \"test_saved_query\",\n        \"my_metric\",\n    )\n    manifest.metrics[metric.unique_id] = metric\n    manifest.saved_queries[saved_query.unique_id] = saved_query\n    methods = MethodManager(manifest, None)\n    method = methods.get_method(\"saved_query\", [])\n    assert isinstance(method, SavedQuerySelectorMethod)\n    assert search_manifest_using_method(manifest, method, \"test_saved_query\") == {\n        \"test_saved_query\"\n    }\n    assert not search_manifest_using_method(manifest, method, \"not_test_saved_query\")\n    assert search_manifest_using_method(manifest, method, \"*uery\") == {\"test_saved_query\"}\n\n\ndef test_select_saved_query_by_tag(manifest: Manifest) -> None:\n    metric = make_metric(\"test\", \"my_metric\")\n    saved_query = make_saved_query(\n        \"pkg\",\n        \"test_saved_query\",\n        \"my_metric\",\n    )\n    manifest.metrics[metric.unique_id] = metric\n    manifest.saved_queries[saved_query.unique_id] = saved_query\n    methods = MethodManager(manifest, None)\n    method = methods.get_method(\"tag\", [])\n    assert isinstance(method, TagSelectorMethod)\n    assert method.arguments == []\n    search_manifest_using_method(manifest, method, \"any_tag\")\n\n\ndef test_modified_saved_query(manifest: Manifest) -> None:\n    metric = make_metric(\"test\", \"my_metric\")\n    saved_query = make_saved_query(\n        \"pkg\",\n        \"test_saved_query\",\n        \"my_metric\",\n    )\n    manifest.metrics[metric.unique_id] = metric\n    manifest.saved_queries[saved_query.unique_id] = saved_query\n    # Create PreviousState with a saved query, this deepcopies manifest\n    previous_state = create_previous_state(manifest)\n    method = statemethod(manifest, previous_state)\n\n    # create another metric and add to saved query\n    alt_metric = make_metric(\"test\", \"alt_metric\")\n    manifest.metrics[alt_metric.unique_id] = alt_metric\n    saved_query.query_params.metrics.append(\"alt_metric\")\n\n    assert search_manifest_using_method(manifest, method, \"modified\") == {\"test_saved_query\"}\n\n\ndef test_select_unit_test(manifest: Manifest) -> None:\n    test_model = make_model(\"test\", \"my_model\", \"select 1 as id\")\n    unit_test = make_unit_test(\"test\", \"my_unit_test\", test_model)\n    manifest.unit_tests[unit_test.unique_id] = unit_test\n    methods = MethodManager(manifest, None)\n    method = methods.get_method(\"unit_test\", [])\n\n    assert isinstance(method, UnitTestSelectorMethod)\n    assert not search_manifest_using_method(manifest, method, \"not_test_unit_test\")\n    assert search_manifest_using_method(manifest, method, \"*nit_test\") == {unit_test.search_name}\n    assert search_manifest_using_method(manifest, method, \"test.my_unit_test\") == {\n        unit_test.search_name\n    }\n    assert search_manifest_using_method(manifest, method, \"my_unit_test\") == {\n        unit_test.search_name\n    }\n\n\ndef create_previous_state(manifest):\n    writable = copy.deepcopy(manifest).writable_manifest()\n    state = PreviousState(\n        state_path=Path(\"/path/does/not/exist\"),\n        target_path=Path(\"/path/does/not/exist\"),\n        project_root=Path(\"/path/does/not/exist\"),\n    )\n    state.manifest = Manifest.from_writable_manifest(writable)\n    return state\n\n\n@pytest.fixture\ndef previous_state(manifest):\n    return create_previous_state(manifest)\n\n\n@pytest.fixture\ndef args_for_flags():\n    return Namespace(\n        state_modified_compare_more_unrendered_values=False, state_modified_compare_vars=False\n    )\n\n\ndef add_node(manifest, node):\n    manifest.nodes[node.unique_id] = node\n\n\ndef add_macro(manifest, macro):\n    manifest.macros[macro.unique_id] = macro\n\n\ndef change_node(manifest, node, change=None):\n    if change is not None:\n        node = change(node)\n    manifest.nodes[node.unique_id] = node\n\n\ndef statemethod(manifest, previous_state):\n    methods = MethodManager(manifest, previous_state)\n    method = methods.get_method(\"state\", [])\n    assert isinstance(method, StateSelectorMethod)\n    assert method.arguments == []\n    return method\n\n\ndef test_select_state_no_change(manifest, previous_state):\n    method = statemethod(manifest, previous_state)\n    assert not search_manifest_using_method(manifest, method, \"modified\")\n    assert not search_manifest_using_method(manifest, method, \"new\")\n    assert not search_manifest_using_method(manifest, method, \"modified.configs\")\n    assert not search_manifest_using_method(manifest, method, \"modified.persisted_descriptions\")\n    assert not search_manifest_using_method(manifest, method, \"modified.relation\")\n    assert not search_manifest_using_method(manifest, method, \"modified.macros\")\n\n\ndef test_select_state_nothing(manifest, previous_state):\n    previous_state.manifest = None\n    method = statemethod(manifest, previous_state)\n    with pytest.raises(dbt_common.exceptions.DbtRuntimeError) as exc:\n        search_manifest_using_method(manifest, method, \"modified\")\n    assert \"no comparison manifest\" in str(exc.value)\n\n    with pytest.raises(dbt_common.exceptions.DbtRuntimeError) as exc:\n        search_manifest_using_method(manifest, method, \"new\")\n    assert \"no comparison manifest\" in str(exc.value)\n\n    with pytest.raises(dbt_common.exceptions.DbtRuntimeError) as exc:\n        search_manifest_using_method(manifest, method, \"unmodified\")\n    assert \"no comparison manifest\" in str(exc.value)\n\n    with pytest.raises(dbt_common.exceptions.DbtRuntimeError) as exc:\n        search_manifest_using_method(manifest, method, \"old\")\n    assert \"no comparison manifest\" in str(exc.value)\n\n\ndef test_select_state_added_model(manifest, previous_state):\n    add_node(manifest, make_model(\"pkg\", \"another_model\", \"select 1 as id\"))\n    method = statemethod(manifest, previous_state)\n    assert search_manifest_using_method(manifest, method, \"modified\") == {\"another_model\"}\n    assert search_manifest_using_method(manifest, method, \"new\") == {\"another_model\"}\n    assert search_manifest_using_method(manifest, method, \"modified.body\") == {\"another_model\"}\n\n    # none of these\n    assert not {\"another_model\"} in search_manifest_using_method(manifest, method, \"old\")\n    assert not {\"another_model\"} in search_manifest_using_method(manifest, method, \"unmodified\")\n\n\ndef test_select_state_changed_model_sql(manifest, previous_state, view_model):\n    change_node(manifest, replace(view_model, raw_code=\"select 1 as id\"))\n    method = statemethod(manifest, previous_state)\n\n    # both of these\n    assert search_manifest_using_method(manifest, method, \"modified\") == {\"view_model\"}\n    assert search_manifest_using_method(manifest, method, \"modified.body\") == {\"view_model\"}\n\n    # none of these\n    assert not search_manifest_using_method(manifest, method, \"new\")\n    assert not {\"view_model\"} in search_manifest_using_method(manifest, method, \"old\")\n    assert not {\"view_model\"} in search_manifest_using_method(manifest, method, \"unmodified\")\n    assert not search_manifest_using_method(manifest, method, \"modified.configs\")\n    assert not search_manifest_using_method(manifest, method, \"modified.persisted_descriptions\")\n    assert not search_manifest_using_method(manifest, method, \"modified.relation\")\n    assert not search_manifest_using_method(manifest, method, \"modified.macros\")\n\n\ndef test_select_state_changed_model_fqn(manifest, previous_state, view_model):\n    change_node(\n        manifest, replace(view_model, fqn=view_model.fqn[:-1] + [\"nested\"] + view_model.fqn[-1:])\n    )\n    method = statemethod(manifest, previous_state)\n    assert search_manifest_using_method(manifest, method, \"modified\") == {\"view_model\"}\n    assert not search_manifest_using_method(manifest, method, \"new\")\n\n    # none of these\n    assert not {\"view_model\"} in search_manifest_using_method(manifest, method, \"old\")\n    assert not {\"view_model\"} in search_manifest_using_method(manifest, method, \"unmodified\")\n\n\ndef test_select_state_added_seed(manifest, previous_state):\n    add_node(manifest, make_seed(\"pkg\", \"another_seed\"))\n    method = statemethod(manifest, previous_state)\n    assert search_manifest_using_method(manifest, method, \"modified\") == {\"another_seed\"}\n    assert search_manifest_using_method(manifest, method, \"new\") == {\"another_seed\"}\n\n    # none of these\n    assert not {\"another_seed\"} in search_manifest_using_method(manifest, method, \"old\")\n    assert not {\"another_seed\"} in search_manifest_using_method(manifest, method, \"unmodified\")\n\n\ndef test_select_state_changed_seed_checksum_sha_to_sha(manifest, previous_state, seed):\n    change_node(manifest, replace(seed, checksum=FileHash.from_contents(\"changed\")))\n    method = statemethod(manifest, previous_state)\n    assert search_manifest_using_method(manifest, method, \"modified\") == {\"seed\"}\n    assert not search_manifest_using_method(manifest, method, \"new\")\n    assert \"seed\" not in search_manifest_using_method(manifest, method, \"unmodified\")\n\n\ndef test_select_state_changed_seed_checksum_path_to_path(manifest, previous_state, seed):\n    change_node(\n        previous_state.manifest,\n        replace(seed, checksum=FileHash(name=\"path\", checksum=seed.original_file_path)),\n    )\n    change_node(\n        manifest, replace(seed, checksum=FileHash(name=\"path\", checksum=seed.original_file_path))\n    )\n    method = statemethod(manifest, previous_state)\n    with mock.patch(\"dbt.contracts.graph.nodes.warn_or_error\") as warn_or_error_patch:\n        assert not search_manifest_using_method(manifest, method, \"modified\")\n        warn_or_error_patch.assert_called_once()\n        event = warn_or_error_patch.call_args[0][0]\n        assert type(event).__name__ == \"SeedExceedsLimitSamePath\"\n        msg = event.message()\n        assert msg.startswith(warning_tag(\"Found a seed (pkg.seed) >1MB in size\"))\n    with mock.patch(\"dbt.contracts.graph.nodes.warn_or_error\") as warn_or_error_patch:\n        assert not search_manifest_using_method(manifest, method, \"new\")\n        warn_or_error_patch.assert_not_called()\n    with mock.patch(\"dbt.contracts.graph.nodes.warn_or_error\") as warn_or_error_patch:\n        assert search_manifest_using_method(manifest, method, \"old\")\n        warn_or_error_patch.assert_not_called()\n    with mock.patch(\"dbt.contracts.graph.nodes.warn_or_error\") as warn_or_error_patch:\n        assert search_manifest_using_method(manifest, method, \"unmodified\")\n        warn_or_error_patch.assert_called_once()\n        event = warn_or_error_patch.call_args[0][0]\n        assert type(event).__name__ == \"SeedExceedsLimitSamePath\"\n        msg = event.message()\n        assert msg.startswith(warning_tag(\"Found a seed (pkg.seed) >1MB in size\"))\n\n\ndef test_select_state_changed_seed_checksum_sha_to_path(manifest, previous_state, seed):\n    change_node(\n        manifest, replace(seed, checksum=FileHash(name=\"path\", checksum=seed.original_file_path))\n    )\n    method = statemethod(manifest, previous_state)\n    with mock.patch(\"dbt.contracts.graph.nodes.warn_or_error\") as warn_or_error_patch:\n        assert search_manifest_using_method(manifest, method, \"modified\") == {\"seed\"}\n        warn_or_error_patch.assert_called_once()\n        event = warn_or_error_patch.call_args[0][0]\n        assert type(event).__name__ == \"SeedIncreased\"\n        msg = event.message()\n        assert msg.startswith(warning_tag(\"Found a seed (pkg.seed) >1MB in size\"))\n    with mock.patch(\"dbt.contracts.graph.nodes.warn_or_error\") as warn_or_error_patch:\n        assert not search_manifest_using_method(manifest, method, \"new\")\n        warn_or_error_patch.assert_not_called()\n    with mock.patch(\"dbt.contracts.graph.nodes.warn_or_error\") as warn_or_error_patch:\n        assert search_manifest_using_method(manifest, method, \"old\")\n        warn_or_error_patch.assert_not_called()\n    with mock.patch(\"dbt.contracts.graph.nodes.warn_or_error\") as warn_or_error_patch:\n        assert search_manifest_using_method(manifest, method, \"unmodified\")\n        warn_or_error_patch.assert_called_once()\n        event = warn_or_error_patch.call_args[0][0]\n        assert type(event).__name__ == \"SeedIncreased\"\n        msg = event.message()\n        assert msg.startswith(warning_tag(\"Found a seed (pkg.seed) >1MB in size\"))\n\n\ndef test_select_state_changed_seed_checksum_path_to_sha(manifest, previous_state, seed):\n    change_node(\n        previous_state.manifest,\n        replace(seed, checksum=FileHash(name=\"path\", checksum=seed.original_file_path)),\n    )\n    method = statemethod(manifest, previous_state)\n    with mock.patch(\"dbt.contracts.graph.nodes.warn_or_error\") as warn_or_error_patch:\n        assert search_manifest_using_method(manifest, method, \"modified\") == {\"seed\"}\n        warn_or_error_patch.assert_not_called()\n    with mock.patch(\"dbt.contracts.graph.nodes.warn_or_error\") as warn_or_error_patch:\n        assert not search_manifest_using_method(manifest, method, \"new\")\n        warn_or_error_patch.assert_not_called()\n    with mock.patch(\"dbt.contracts.graph.nodes.warn_or_error\") as warn_or_error_patch:\n        assert \"seed\" not in search_manifest_using_method(manifest, method, \"unmodified\")\n        warn_or_error_patch.assert_not_called()\n    with mock.patch(\"dbt.contracts.graph.nodes.warn_or_error\") as warn_or_error_patch:\n        assert \"seed\" in search_manifest_using_method(manifest, method, \"old\")\n        warn_or_error_patch.assert_not_called()\n\n\ndef test_select_state_changed_seed_fqn(manifest, previous_state, seed):\n    change_node(manifest, replace(seed, fqn=seed.fqn[:-1] + [\"nested\"] + seed.fqn[-1:]))\n    method = statemethod(manifest, previous_state)\n    assert search_manifest_using_method(manifest, method, \"modified\") == {\"seed\"}\n    assert not search_manifest_using_method(manifest, method, \"new\")\n    assert \"seed\" not in search_manifest_using_method(manifest, method, \"unmodified\")\n    assert \"seed\" in search_manifest_using_method(manifest, method, \"old\")\n\n\ndef test_select_state_changed_seed_relation_documented(manifest, previous_state, seed):\n    seed_doc_relation = replace_config(seed, persist_docs={\"relation\": True})\n    change_node(manifest, seed_doc_relation)\n    method = statemethod(manifest, previous_state)\n    assert search_manifest_using_method(manifest, method, \"modified\") == {\"seed\"}\n    assert search_manifest_using_method(manifest, method, \"modified.configs\") == {\"seed\"}\n    assert \"seed\" in search_manifest_using_method(manifest, method, \"old\")\n    assert not search_manifest_using_method(manifest, method, \"new\")\n    assert \"seed\" not in search_manifest_using_method(manifest, method, \"unmodified\")\n    assert not search_manifest_using_method(manifest, method, \"modified.body\")\n    assert not search_manifest_using_method(manifest, method, \"modified.persisted_descriptions\")\n\n\ndef test_select_state_changed_seed_relation_documented_nodocs(manifest, previous_state, seed):\n    seed_doc_relation = replace_config(seed, persist_docs={\"relation\": True})\n    seed_doc_relation_documented = replace(seed_doc_relation, description=\"a description\")\n    change_node(previous_state.manifest, seed_doc_relation)\n    change_node(manifest, seed_doc_relation_documented)\n    method = statemethod(manifest, previous_state)\n    assert search_manifest_using_method(manifest, method, \"modified\") == {\"seed\"}\n    assert search_manifest_using_method(manifest, method, \"modified.persisted_descriptions\") == {\n        \"seed\"\n    }\n    assert \"seed\" in search_manifest_using_method(manifest, method, \"old\")\n    assert not search_manifest_using_method(manifest, method, \"new\")\n    assert \"seed\" not in search_manifest_using_method(manifest, method, \"unmodified\")\n    assert not search_manifest_using_method(manifest, method, \"modified.configs\")\n\n\ndef test_select_state_changed_seed_relation_documented_withdocs(manifest, previous_state, seed):\n    seed_doc_relation = replace_config(seed, persist_docs={\"relation\": True})\n    seed_doc_relation_documented = replace(seed_doc_relation, description=\"a description\")\n    change_node(previous_state.manifest, seed_doc_relation_documented)\n    change_node(manifest, seed_doc_relation)\n    method = statemethod(manifest, previous_state)\n    assert search_manifest_using_method(manifest, method, \"modified\") == {\"seed\"}\n    assert search_manifest_using_method(manifest, method, \"modified.persisted_descriptions\") == {\n        \"seed\"\n    }\n    assert \"seed\" in search_manifest_using_method(manifest, method, \"old\")\n    assert not search_manifest_using_method(manifest, method, \"new\")\n    assert \"seed\" not in search_manifest_using_method(manifest, method, \"unmodified\")\n\n\ndef test_select_state_changed_seed_columns_documented(manifest, previous_state, seed):\n    # changing persist_docs, even without changing the description -> changed\n    seed_doc_columns = replace_config(seed, persist_docs={\"columns\": True})\n    change_node(manifest, seed_doc_columns)\n    method = statemethod(manifest, previous_state)\n    assert search_manifest_using_method(manifest, method, \"modified\") == {\"seed\"}\n    assert search_manifest_using_method(manifest, method, \"modified.configs\") == {\"seed\"}\n    assert \"seed\" in search_manifest_using_method(manifest, method, \"old\")\n    assert not search_manifest_using_method(manifest, method, \"new\")\n    assert \"seed\" not in search_manifest_using_method(manifest, method, \"unmodified\")\n    assert not search_manifest_using_method(manifest, method, \"modified.persisted_descriptions\")\n\n\ndef test_select_state_changed_seed_columns_documented_nodocs(manifest, previous_state, seed):\n    seed_doc_columns = replace_config(seed, persist_docs={\"columns\": True})\n    seed_doc_columns_documented_columns = replace(\n        seed_doc_columns,\n        columns={\"a\": ColumnInfo(name=\"a\", description=\"a description\")},\n    )\n\n    change_node(previous_state.manifest, seed_doc_columns)\n    change_node(manifest, seed_doc_columns_documented_columns)\n\n    method = statemethod(manifest, previous_state)\n    assert search_manifest_using_method(manifest, method, \"modified\") == {\"seed\"}\n    assert search_manifest_using_method(manifest, method, \"modified.persisted_descriptions\") == {\n        \"seed\"\n    }\n    assert \"seed\" in search_manifest_using_method(manifest, method, \"old\")\n    assert not search_manifest_using_method(manifest, method, \"new\")\n    assert \"seed\" not in search_manifest_using_method(manifest, method, \"unmodified\")\n    assert not search_manifest_using_method(manifest, method, \"modified.configs\")\n\n\ndef test_select_state_changed_seed_columns_documented_withdocs(manifest, previous_state, seed):\n    seed_doc_columns = replace_config(seed, persist_docs={\"columns\": True})\n    seed_doc_columns_documented_columns = replace(\n        seed_doc_columns,\n        columns={\"a\": ColumnInfo(name=\"a\", description=\"a description\")},\n    )\n\n    change_node(manifest, seed_doc_columns)\n    change_node(previous_state.manifest, seed_doc_columns_documented_columns)\n\n    method = statemethod(manifest, previous_state)\n    assert search_manifest_using_method(manifest, method, \"modified\") == {\"seed\"}\n    assert search_manifest_using_method(manifest, method, \"modified.persisted_descriptions\") == {\n        \"seed\"\n    }\n    assert \"seed\" in search_manifest_using_method(manifest, method, \"old\")\n    assert not search_manifest_using_method(manifest, method, \"new\")\n    assert \"seed\" not in search_manifest_using_method(manifest, method, \"unmodified\")\n    assert not search_manifest_using_method(manifest, method, \"modified.configs\")\n\n\ndef test_select_state_changed_test_macro_sql(\n    manifest, previous_state, macro_default_test_not_null\n):\n    manifest.macros[macro_default_test_not_null.unique_id] = replace(\n        macro_default_test_not_null, macro_sql=\"lalala\"\n    )\n    method = statemethod(manifest, previous_state)\n    assert search_manifest_using_method(manifest, method, \"modified\") == {\n        \"not_null_table_model_id\"\n    }\n    assert search_manifest_using_method(manifest, method, \"modified.macros\") == {\n        \"not_null_table_model_id\"\n    }\n    assert \"not_null_table_model_id\" in search_manifest_using_method(manifest, method, \"old\")\n    assert not search_manifest_using_method(manifest, method, \"new\")\n    assert \"not_null_table_model_id\" not in search_manifest_using_method(\n        manifest, method, \"unmodified\"\n    )\n\n\ndef test_select_state_changed_test_macros(manifest, previous_state):\n    changed_macro = make_macro(\"dbt\", \"changed_macro\", \"blablabla\")\n    add_macro(manifest, changed_macro)\n    add_macro(previous_state.manifest, replace(changed_macro, macro_sql=\"something different\"))\n\n    unchanged_macro = make_macro(\"dbt\", \"unchanged_macro\", \"blablabla\")\n    add_macro(manifest, unchanged_macro)\n    add_macro(previous_state.manifest, unchanged_macro)\n\n    model1 = make_model(\n        \"dbt\",\n        \"model1\",\n        \"blablabla\",\n        depends_on_macros=[changed_macro.unique_id, unchanged_macro.unique_id],\n    )\n    add_node(manifest, model1)\n    add_node(previous_state.manifest, model1)\n\n    model2 = make_model(\n        \"dbt\",\n        \"model2\",\n        \"blablabla\",\n        depends_on_macros=[unchanged_macro.unique_id, changed_macro.unique_id],\n    )\n    add_node(manifest, model2)\n    add_node(previous_state.manifest, model2)\n\n    method = statemethod(manifest, previous_state)\n\n    assert search_manifest_using_method(manifest, method, \"modified\") == {\"model1\", \"model2\"}\n    assert search_manifest_using_method(manifest, method, \"modified.macros\") == {\n        \"model1\",\n        \"model2\",\n    }\n    assert \"model1\" and \"model2\" in search_manifest_using_method(manifest, method, \"old\")\n    assert not search_manifest_using_method(manifest, method, \"new\")\n    assert \"model1\" and \"model2\" not in search_manifest_using_method(\n        manifest, method, \"unmodified\"\n    )\n\n\ndef test_select_state_changed_test_macros_with_upstream_change(manifest, previous_state):\n    changed_macro = make_macro(\"dbt\", \"changed_macro\", \"blablabla\")\n    add_macro(manifest, changed_macro)\n    add_macro(previous_state.manifest, replace(changed_macro, macro_sql=\"something different\"))\n\n    unchanged_macro1 = make_macro(\"dbt\", \"unchanged_macro\", \"blablabla\")\n    add_macro(manifest, unchanged_macro1)\n    add_macro(previous_state.manifest, unchanged_macro1)\n\n    unchanged_macro2 = make_macro(\n        \"dbt\",\n        \"unchanged_macro\",\n        \"blablabla\",\n        depends_on_macros=[unchanged_macro1.unique_id, changed_macro.unique_id],\n    )\n    add_macro(manifest, unchanged_macro2)\n    add_macro(previous_state.manifest, unchanged_macro2)\n\n    unchanged_macro3 = make_macro(\n        \"dbt\",\n        \"unchanged_macro\",\n        \"blablabla\",\n        depends_on_macros=[changed_macro.unique_id, unchanged_macro1.unique_id],\n    )\n    add_macro(manifest, unchanged_macro3)\n    add_macro(previous_state.manifest, unchanged_macro3)\n\n    model1 = make_model(\n        \"dbt\", \"model1\", \"blablabla\", depends_on_macros=[unchanged_macro1.unique_id]\n    )\n    add_node(manifest, model1)\n    add_node(previous_state.manifest, model1)\n\n    model2 = make_model(\n        \"dbt\", \"model2\", \"blablabla\", depends_on_macros=[unchanged_macro3.unique_id]\n    )\n    add_node(manifest, model2)\n    add_node(previous_state.manifest, model2)\n\n    method = statemethod(manifest, previous_state)\n\n    assert search_manifest_using_method(manifest, method, \"modified\") == {\"model1\", \"model2\"}\n    assert search_manifest_using_method(manifest, method, \"modified.macros\") == {\n        \"model1\",\n        \"model2\",\n    }\n    assert \"model1\" and \"model2\" in search_manifest_using_method(manifest, method, \"old\")\n    assert not search_manifest_using_method(manifest, method, \"new\")\n    assert \"model1\" and \"model2\" not in search_manifest_using_method(\n        manifest, method, \"unmodified\"\n    )\n"
  },
  {
    "path": "tests/unit/graph/test_selector_spec.py",
    "content": "import os\nfrom unittest.mock import patch\n\nimport pytest\n\nfrom dbt.exceptions import DbtRuntimeError\nfrom dbt.graph.selector_methods import MethodName\nfrom dbt.graph.selector_spec import (\n    IndirectSelection,\n    SelectionCriteria,\n    SelectionDifference,\n    SelectionIntersection,\n    SelectionUnion,\n)\n\n\n@pytest.mark.parametrize(\n    \"indirect_selection_value,expected_value\",\n    [(v, v) for v in IndirectSelection],\n)\ndef test_selection_criteria_default_indirect_value(indirect_selection_value, expected_value):\n    # Check selection criteria with indirect selection value would follow the resolved value in flags\n    # if indirect selection is not specified in the selection criteria.\n    with patch(\"dbt.graph.selector_spec.get_flags\") as patched_get_flags:\n        patched_get_flags.return_value.INDIRECT_SELECTION = indirect_selection_value\n        patched_get_flags.INDIRECT_SELECTION = indirect_selection_value\n        selection_dict_without_indirect_selection_specified = {\n            \"method\": \"path\",\n            \"value\": \"models/marts/orders.sql\",\n            \"children\": False,\n            \"parents\": False,\n        }\n        selection_criteria_without_indirect_selection_specified = (\n            SelectionCriteria.selection_criteria_from_dict(\n                selection_dict_without_indirect_selection_specified,\n                selection_dict_without_indirect_selection_specified,\n            )\n        )\n        assert (\n            selection_criteria_without_indirect_selection_specified.indirect_selection\n            == expected_value\n        )\n        selection_dict_without_indirect_selection_specified = {\n            \"method\": \"path\",\n            \"value\": \"models/marts/orders.sql\",\n            \"children\": False,\n            \"parents\": False,\n            \"indirect_selection\": \"buildable\",\n        }\n        selection_criteria_with_indirect_selection_specified = (\n            SelectionCriteria.selection_criteria_from_dict(\n                selection_dict_without_indirect_selection_specified,\n                selection_dict_without_indirect_selection_specified,\n            )\n        )\n        assert (\n            selection_criteria_with_indirect_selection_specified.indirect_selection == \"buildable\"\n        )\n\n\ndef test_raw_parse_simple():\n    raw = \"asdf\"\n    result = SelectionCriteria.from_single_spec(raw)\n    assert result.raw == raw\n    assert result.method == MethodName.FQN\n    assert result.method_arguments == []\n    assert result.value == raw\n    assert not result.childrens_parents\n    assert not result.children\n    assert not result.parents\n    assert result.parents_depth is None\n    assert result.children_depth is None\n\n\ndef test_raw_parse_simple_infer_path():\n    raw = os.path.join(\"asdf\", \"*\")\n    result = SelectionCriteria.from_single_spec(raw)\n    assert result.raw == raw\n    assert result.method == MethodName.Path\n    assert result.method_arguments == []\n    assert result.value == raw\n    assert not result.childrens_parents\n    assert not result.children\n    assert not result.parents\n    assert result.parents_depth is None\n    assert result.children_depth is None\n\n\ndef test_raw_parse_simple_infer_path_modified():\n    raw = \"@\" + os.path.join(\"asdf\", \"*\")\n    result = SelectionCriteria.from_single_spec(raw)\n    assert result.raw == raw\n    assert result.method == MethodName.Path\n    assert result.method_arguments == []\n    assert result.value == raw[1:]\n    assert result.childrens_parents\n    assert not result.children\n    assert not result.parents\n    assert result.parents_depth is None\n    assert result.children_depth is None\n\n\ndef test_raw_parse_simple_infer_fqn_parents():\n    raw = \"+asdf\"\n    result = SelectionCriteria.from_single_spec(raw)\n    assert result.raw == raw\n    assert result.method == MethodName.FQN\n    assert result.method_arguments == []\n    assert result.value == \"asdf\"\n    assert not result.childrens_parents\n    assert not result.children\n    assert result.parents\n    assert result.parents_depth is None\n    assert result.children_depth is None\n\n\ndef test_raw_parse_simple_infer_fqn_children():\n    raw = \"asdf+\"\n    result = SelectionCriteria.from_single_spec(raw)\n    assert result.raw == raw\n    assert result.method == MethodName.FQN\n    assert result.method_arguments == []\n    assert result.value == \"asdf\"\n    assert not result.childrens_parents\n    assert result.children\n    assert not result.parents\n    assert result.parents_depth is None\n    assert result.children_depth is None\n\n\ndef test_raw_parse_complex():\n    raw = \"2+config.arg.secondarg:argument_value+4\"\n    result = SelectionCriteria.from_single_spec(raw)\n    assert result.raw == raw\n    assert result.method == MethodName.Config\n    assert result.method_arguments == [\"arg\", \"secondarg\"]\n    assert result.value == \"argument_value\"\n    assert not result.childrens_parents\n    assert result.children\n    assert result.parents\n    assert result.parents_depth == 2\n    assert result.children_depth == 4\n\n\ndef test_raw_parse_weird():\n    # you can have an empty method name (defaults to FQN/path) and you can have\n    # an empty value, so you can also have this...\n    result = SelectionCriteria.from_single_spec(\"\")\n    assert result.raw == \"\"\n    assert result.method == MethodName.FQN\n    assert result.method_arguments == []\n    assert result.value == \"\"\n    assert not result.childrens_parents\n    assert not result.children\n    assert not result.parents\n    assert result.parents_depth is None\n    assert result.children_depth is None\n\n\ndef test_raw_parse_selector_method():\n    \"\"\"selector:foo parses as method=Selector, value=foo (for combining YAML selectors with --select/--exclude).\"\"\"\n    raw = \"1+selector:staging+2\"\n    result = SelectionCriteria.from_single_spec(raw)\n    assert result.raw == raw\n    assert result.method == MethodName.Selector\n    assert not result.childrens_parents\n    assert result.children\n    assert result.parents\n    assert result.method_arguments == []\n    assert result.value == \"staging\"\n    assert result.children_depth == 2\n    assert result.parents_depth == 1\n\n\ndef test_raw_parse_invalid():\n    with pytest.raises(DbtRuntimeError):\n        SelectionCriteria.from_single_spec(\"invalid_method:something\")\n\n    with pytest.raises(DbtRuntimeError):\n        SelectionCriteria.from_single_spec(\"@foo+\")\n\n\ndef test_intersection():\n    fqn_a = SelectionCriteria.from_single_spec(\"fqn:model_a\")\n    fqn_b = SelectionCriteria.from_single_spec(\"fqn:model_b\")\n    intersection = SelectionIntersection(components=[fqn_a, fqn_b])\n    assert list(intersection) == [fqn_a, fqn_b]\n    combined = intersection.combine_selections(\n        [{\"model_a\", \"model_b\", \"model_c\"}, {\"model_c\", \"model_d\"}]\n    )\n    assert combined == {\"model_c\"}\n\n\ndef test_difference():\n    fqn_a = SelectionCriteria.from_single_spec(\"fqn:model_a\")\n    fqn_b = SelectionCriteria.from_single_spec(\"fqn:model_b\")\n    difference = SelectionDifference(components=[fqn_a, fqn_b])\n    assert list(difference) == [fqn_a, fqn_b]\n    combined = difference.combine_selections(\n        [{\"model_a\", \"model_b\", \"model_c\"}, {\"model_c\", \"model_d\"}]\n    )\n    assert combined == {\"model_a\", \"model_b\"}\n\n    fqn_c = SelectionCriteria.from_single_spec(\"fqn:model_c\")\n    difference = SelectionDifference(components=[fqn_a, fqn_b, fqn_c])\n    assert list(difference) == [fqn_a, fqn_b, fqn_c]\n    combined = difference.combine_selections(\n        [{\"model_a\", \"model_b\", \"model_c\"}, {\"model_c\", \"model_d\"}, {\"model_a\"}]\n    )\n    assert combined == {\"model_b\"}\n\n\ndef test_union():\n    fqn_a = SelectionCriteria.from_single_spec(\"fqn:model_a\")\n    fqn_b = SelectionCriteria.from_single_spec(\"fqn:model_b\")\n    fqn_c = SelectionCriteria.from_single_spec(\"fqn:model_c\")\n    difference = SelectionUnion(components=[fqn_a, fqn_b, fqn_c])\n    combined = difference.combine_selections(\n        [{\"model_a\", \"model_b\"}, {\"model_b\", \"model_c\"}, {\"model_d\"}]\n    )\n    assert combined == {\"model_a\", \"model_b\", \"model_c\", \"model_d\"}\n"
  },
  {
    "path": "tests/unit/materializations/incremental/test_microbatch.py",
    "content": "from datetime import datetime\nfrom unittest import mock\n\nimport pytest\nimport pytz\nfrom freezegun import freeze_time\n\nfrom dbt.artifacts.resources import NodeConfig\nfrom dbt.artifacts.resources.types import BatchSize\nfrom dbt.materializations.incremental.microbatch import MicrobatchBuilder\n\nMODEL_CONFIG_BEGIN = datetime(2024, 1, 1, 0, 0, 0, 0, pytz.UTC)\n\n\nclass TestMicrobatchBuilder:\n    @pytest.fixture(scope=\"class\")\n    def microbatch_model(self):\n        model = mock.Mock()\n        model.config = mock.MagicMock(NodeConfig)\n        model.config.materialized = \"incremental\"\n        model.config.incremental_strategy = \"microbatch\"\n        model.config.begin = MODEL_CONFIG_BEGIN\n        model.config.batch_size = BatchSize.day\n\n        return model\n\n    @freeze_time(\"2024-09-05 08:56:00\")\n    @pytest.mark.parametrize(\n        \"is_incremental,event_time_end,expected_end_time\",\n        [\n            (\n                False,\n                None,\n                datetime(2024, 9, 6, 0, 0, 0, 0, pytz.UTC),\n            ),\n            (\n                True,\n                None,\n                datetime(2024, 9, 6, 0, 0, 0, 0, pytz.UTC),\n            ),\n            (\n                False,\n                datetime(2024, 10, 1, 0, 0, 0, 0, pytz.UTC),\n                datetime(2024, 10, 1, 0, 0, 0, 0, pytz.UTC),\n            ),\n            (\n                True,\n                datetime(2024, 10, 1, 0, 0, 0, 0, pytz.UTC),\n                datetime(2024, 10, 1, 0, 0, 0, 0, pytz.UTC),\n            ),\n        ],\n    )\n    def test_build_end_time(\n        self, microbatch_model, is_incremental, event_time_end, expected_end_time\n    ):\n        microbatch_builder = MicrobatchBuilder(\n            model=microbatch_model,\n            is_incremental=is_incremental,\n            event_time_start=None,\n            event_time_end=event_time_end,\n        )\n\n        assert microbatch_builder.build_end_time() == expected_end_time\n\n    @pytest.mark.parametrize(\n        \"is_incremental,event_time_start,checkpoint,batch_size,lookback,expected_start_time\",\n        [\n            (\n                False,\n                None,\n                datetime(2024, 9, 5, 8, 56, 0, 0, pytz.UTC),\n                BatchSize.day,\n                0,\n                # is_incremental: False => model.config.begin\n                MODEL_CONFIG_BEGIN,\n            ),\n            # BatchSize.year\n            (\n                False,\n                datetime(2024, 9, 5, 8, 56, 0, 0, pytz.UTC),\n                datetime(2024, 9, 5, 8, 56, 0, 0, pytz.UTC),\n                BatchSize.year,\n                0,\n                datetime(2024, 1, 1, 0, 0, 0, 0, pytz.UTC),\n            ),\n            (\n                False,\n                datetime(2024, 9, 5, 8, 56, 0, 0, pytz.UTC),\n                datetime(2024, 9, 5, 8, 56, 0, 0, pytz.UTC),\n                BatchSize.year,\n                # Offset not applied when event_time_start provided\n                1,\n                datetime(2024, 1, 1, 0, 0, 0, 0, pytz.UTC),\n            ),\n            (\n                False,\n                None,\n                datetime(2024, 9, 5, 8, 56, 0, 0, pytz.UTC),\n                BatchSize.year,\n                0,\n                # is_incremental=False + no start_time -> model.config.begin\n                MODEL_CONFIG_BEGIN,\n            ),\n            (\n                True,\n                None,\n                datetime(2024, 9, 5, 8, 56, 0, 0, pytz.UTC),\n                BatchSize.year,\n                0,\n                datetime(2024, 1, 1, 0, 0, 0, 0, pytz.UTC),\n            ),\n            (\n                True,\n                None,\n                datetime(2024, 9, 5, 8, 56, 0, 0, pytz.UTC),\n                BatchSize.year,\n                1,\n                datetime(2023, 1, 1, 0, 0, 0, 0, pytz.UTC),\n            ),\n            # BatchSize.month\n            (\n                False,\n                datetime(2024, 9, 5, 8, 56, 0, 0, pytz.UTC),\n                datetime(2024, 9, 5, 8, 56, 0, 0, pytz.UTC),\n                BatchSize.month,\n                0,\n                datetime(2024, 9, 1, 0, 0, 0, 0, pytz.UTC),\n            ),\n            (\n                False,\n                datetime(2024, 9, 5, 8, 56, 0, 0, pytz.UTC),\n                datetime(2024, 9, 5, 8, 56, 0, 0, pytz.UTC),\n                BatchSize.month,\n                # Offset not applied when event_time_start provided\n                1,\n                datetime(2024, 9, 1, 0, 0, 0, 0, pytz.UTC),\n            ),\n            (\n                False,\n                None,\n                datetime(2024, 9, 5, 8, 56, 0, 0, pytz.UTC),\n                BatchSize.month,\n                0,\n                # is_incremental=False + no start_time -> model.config.begin\n                MODEL_CONFIG_BEGIN,\n            ),\n            (\n                True,\n                None,\n                datetime(2024, 9, 5, 8, 56, 0, 0, pytz.UTC),\n                BatchSize.month,\n                0,\n                datetime(2024, 9, 1, 0, 0, 0, 0, pytz.UTC),\n            ),\n            (\n                True,\n                None,\n                datetime(2024, 9, 5, 8, 56, 0, 0, pytz.UTC),\n                BatchSize.month,\n                1,\n                datetime(2024, 8, 1, 0, 0, 0, 0, pytz.UTC),\n            ),\n            # BatchSize.day\n            (\n                False,\n                datetime(2024, 9, 5, 8, 56, 0, 0, pytz.UTC),\n                datetime(2024, 9, 5, 8, 56, 0, 0, pytz.UTC),\n                BatchSize.day,\n                0,\n                datetime(2024, 9, 5, 0, 0, 0, 0, pytz.UTC),\n            ),\n            (\n                False,\n                datetime(2024, 9, 5, 8, 56, 0, 0, pytz.UTC),\n                datetime(2024, 9, 5, 8, 56, 0, 0, pytz.UTC),\n                BatchSize.day,\n                # Offset not applied when event_time_start provided\n                1,\n                datetime(2024, 9, 5, 0, 0, 0, 0, pytz.UTC),\n            ),\n            (\n                False,\n                None,\n                datetime(2024, 9, 5, 8, 56, 0, 0, pytz.UTC),\n                BatchSize.day,\n                0,\n                # is_incremental=False + no start_time -> model.config.begin\n                MODEL_CONFIG_BEGIN,\n            ),\n            (\n                True,\n                None,\n                datetime(2024, 9, 5, 8, 56, 0, 0, pytz.UTC),\n                BatchSize.day,\n                0,\n                datetime(2024, 9, 5, 0, 0, 0, 0, pytz.UTC),\n            ),\n            (\n                True,\n                None,\n                datetime(2024, 9, 5, 8, 56, 0, 0, pytz.UTC),\n                BatchSize.day,\n                1,\n                datetime(2024, 9, 4, 0, 0, 0, 0, pytz.UTC),\n            ),\n            # BatchSize.hour\n            (\n                False,\n                datetime(2024, 9, 5, 8, 56, 0, 0, pytz.UTC),\n                datetime(2024, 9, 5, 8, 56, 0, 0, pytz.UTC),\n                BatchSize.hour,\n                0,\n                datetime(2024, 9, 5, 8, 0, 0, 0, pytz.UTC),\n            ),\n            (\n                False,\n                datetime(2024, 9, 5, 8, 56, 0, 0, pytz.UTC),\n                datetime(2024, 9, 5, 8, 56, 0, 0, pytz.UTC),\n                BatchSize.hour,\n                # Offset not applied when event_time_start provided\n                1,\n                datetime(2024, 9, 5, 8, 0, 0, 0, pytz.UTC),\n            ),\n            (\n                False,\n                None,\n                datetime(2024, 9, 5, 8, 56, 0, 0, pytz.UTC),\n                BatchSize.hour,\n                0,\n                # is_incremental=False + no start_time -> model.config.begin\n                MODEL_CONFIG_BEGIN,\n            ),\n            (\n                True,\n                None,\n                datetime(2024, 9, 5, 8, 56, 0, 0, pytz.UTC),\n                BatchSize.hour,\n                0,\n                datetime(2024, 9, 5, 8, 0, 0, 0, pytz.UTC),\n            ),\n            (\n                True,\n                None,\n                datetime(2024, 9, 5, 8, 56, 0, 0, pytz.UTC),\n                BatchSize.hour,\n                1,\n                datetime(2024, 9, 5, 7, 0, 0, 0, pytz.UTC),\n            ),\n            (\n                True,\n                None,\n                datetime(2024, 9, 5, 0, 0, 0, 0, pytz.UTC),\n                BatchSize.hour,\n                0,\n                datetime(2024, 9, 4, 23, 0, 0, 0, pytz.UTC),\n            ),\n            (\n                True,\n                None,\n                datetime(2024, 9, 5, 0, 0, 0, 0, pytz.UTC),\n                BatchSize.hour,\n                1,\n                datetime(2024, 9, 4, 22, 0, 0, 0, pytz.UTC),\n            ),\n            (\n                True,\n                None,\n                datetime(2024, 9, 5, 0, 0, 0, 0, pytz.UTC),\n                BatchSize.day,\n                0,\n                datetime(2024, 9, 4, 0, 0, 0, 0, pytz.UTC),\n            ),\n            (\n                True,\n                None,\n                datetime(2024, 9, 5, 0, 0, 0, 0, pytz.UTC),\n                BatchSize.day,\n                1,\n                datetime(2024, 9, 3, 0, 0, 0, 0, pytz.UTC),\n            ),\n            (\n                True,\n                None,\n                datetime(2024, 9, 1, 0, 0, 0, 0, pytz.UTC),\n                BatchSize.month,\n                0,\n                datetime(2024, 8, 1, 0, 0, 0, 0, pytz.UTC),\n            ),\n            (\n                True,\n                None,\n                datetime(2024, 9, 1, 0, 0, 0, 0, pytz.UTC),\n                BatchSize.month,\n                1,\n                datetime(2024, 7, 1, 0, 0, 0, 0, pytz.UTC),\n            ),\n            (\n                True,\n                None,\n                datetime(2024, 1, 1, 0, 0, 0, 0, pytz.UTC),\n                BatchSize.year,\n                0,\n                datetime(2023, 1, 1, 0, 0, 0, 0, pytz.UTC),\n            ),\n            (\n                True,\n                None,\n                datetime(2024, 1, 1, 0, 0, 0, 0, pytz.UTC),\n                BatchSize.year,\n                1,\n                datetime(2022, 1, 1, 0, 0, 0, 0, pytz.UTC),\n            ),\n        ],\n    )\n    def test_build_start_time(\n        self,\n        microbatch_model,\n        is_incremental,\n        event_time_start,\n        checkpoint,\n        batch_size,\n        lookback,\n        expected_start_time,\n    ):\n        microbatch_model.config.batch_size = batch_size\n        microbatch_model.config.lookback = lookback\n        microbatch_builder = MicrobatchBuilder(\n            model=microbatch_model,\n            is_incremental=is_incremental,\n            event_time_start=event_time_start,\n            event_time_end=None,\n        )\n\n        assert microbatch_builder.build_start_time(checkpoint) == expected_start_time\n\n    @pytest.mark.parametrize(\n        \"start,end,batch_size,expected_batches\",\n        [\n            # BatchSize.year\n            (\n                datetime(2024, 1, 1, 0, 0, 0, 0, pytz.UTC),\n                datetime(2026, 1, 7, 3, 56, 0, 0, pytz.UTC),\n                BatchSize.year,\n                [\n                    (\n                        datetime(2024, 1, 1, 0, 0, 0, 0, pytz.UTC),\n                        datetime(2025, 1, 1, 0, 0, 0, 0, pytz.UTC),\n                    ),\n                    (\n                        datetime(2025, 1, 1, 0, 0, 0, 0, pytz.UTC),\n                        datetime(2026, 1, 1, 0, 0, 0, 0, pytz.UTC),\n                    ),\n                    (\n                        datetime(2026, 1, 1, 0, 0, 0, 0, pytz.UTC),\n                        datetime(2026, 1, 7, 3, 56, 0, 0, pytz.UTC),\n                    ),\n                ],\n            ),\n            # BatchSize.month\n            (\n                datetime(2024, 9, 1, 0, 0, 0, 0, pytz.UTC),\n                datetime(2024, 11, 7, 3, 56, 0, 0, pytz.UTC),\n                BatchSize.month,\n                [\n                    (\n                        datetime(2024, 9, 1, 0, 0, 0, 0, pytz.UTC),\n                        datetime(2024, 10, 1, 0, 0, 0, 0, pytz.UTC),\n                    ),\n                    (\n                        datetime(2024, 10, 1, 0, 0, 0, 0, pytz.UTC),\n                        datetime(2024, 11, 1, 0, 0, 0, 0, pytz.UTC),\n                    ),\n                    (\n                        datetime(2024, 11, 1, 0, 0, 0, 0, pytz.UTC),\n                        datetime(2024, 11, 7, 3, 56, 0, 0, pytz.UTC),\n                    ),\n                ],\n            ),\n            # BatchSize.day\n            (\n                datetime(2024, 9, 5, 0, 0, 0, 0, pytz.UTC),\n                datetime(2024, 9, 7, 3, 56, 0, 0, pytz.UTC),\n                BatchSize.day,\n                [\n                    (\n                        datetime(2024, 9, 5, 0, 0, 0, 0, pytz.UTC),\n                        datetime(2024, 9, 6, 0, 0, 0, 0, pytz.UTC),\n                    ),\n                    (\n                        datetime(2024, 9, 6, 0, 0, 0, 0, pytz.UTC),\n                        datetime(2024, 9, 7, 0, 0, 0, 0, pytz.UTC),\n                    ),\n                    (\n                        datetime(2024, 9, 7, 0, 0, 0, 0, pytz.UTC),\n                        datetime(2024, 9, 7, 3, 56, 0, 0, pytz.UTC),\n                    ),\n                ],\n            ),\n            # BatchSize.hour\n            (\n                datetime(2024, 9, 5, 1, 0, 0, 0, pytz.UTC),\n                datetime(2024, 9, 5, 3, 56, 0, 0, pytz.UTC),\n                BatchSize.hour,\n                [\n                    (\n                        datetime(2024, 9, 5, 1, 0, 0, 0, pytz.UTC),\n                        datetime(2024, 9, 5, 2, 0, 0, 0, pytz.UTC),\n                    ),\n                    (\n                        datetime(2024, 9, 5, 2, 0, 0, 0, pytz.UTC),\n                        datetime(2024, 9, 5, 3, 0, 0, 0, pytz.UTC),\n                    ),\n                    (\n                        datetime(2024, 9, 5, 3, 0, 0, 0, pytz.UTC),\n                        datetime(2024, 9, 5, 3, 56, 0, 0, pytz.UTC),\n                    ),\n                ],\n            ),\n            # Test when event_time_end matches the truncated batch size\n            (\n                datetime(2024, 1, 1, 0, 0, 0, 0, pytz.UTC),\n                datetime(2026, 1, 1, 0, 0, 0, 0, pytz.UTC),\n                BatchSize.year,\n                [\n                    (\n                        datetime(2024, 1, 1, 0, 0, 0, 0, pytz.UTC),\n                        datetime(2025, 1, 1, 0, 0, 0, 0, pytz.UTC),\n                    ),\n                    (\n                        datetime(2025, 1, 1, 0, 0, 0, 0, pytz.UTC),\n                        datetime(2026, 1, 1, 0, 0, 0, 0, pytz.UTC),\n                    ),\n                ],\n            ),\n            (\n                datetime(2024, 9, 1, 0, 0, 0, 0, pytz.UTC),\n                datetime(2024, 11, 1, 0, 0, 0, 0, pytz.UTC),\n                BatchSize.month,\n                [\n                    (\n                        datetime(2024, 9, 1, 0, 0, 0, 0, pytz.UTC),\n                        datetime(2024, 10, 1, 0, 0, 0, 0, pytz.UTC),\n                    ),\n                    (\n                        datetime(2024, 10, 1, 0, 0, 0, 0, pytz.UTC),\n                        datetime(2024, 11, 1, 0, 0, 0, 0, pytz.UTC),\n                    ),\n                ],\n            ),\n            (\n                datetime(2024, 9, 5, 0, 0, 0, 0, pytz.UTC),\n                datetime(2024, 9, 7, 0, 0, 0, 0, pytz.UTC),\n                BatchSize.day,\n                [\n                    (\n                        datetime(2024, 9, 5, 0, 0, 0, 0, pytz.UTC),\n                        datetime(2024, 9, 6, 0, 0, 0, 0, pytz.UTC),\n                    ),\n                    (\n                        datetime(2024, 9, 6, 0, 0, 0, 0, pytz.UTC),\n                        datetime(2024, 9, 7, 0, 0, 0, 0, pytz.UTC),\n                    ),\n                ],\n            ),\n            (\n                datetime(2024, 9, 5, 1, 0, 0, 0, pytz.UTC),\n                datetime(2024, 9, 5, 3, 0, 0, 0, pytz.UTC),\n                BatchSize.hour,\n                [\n                    (\n                        datetime(2024, 9, 5, 1, 0, 0, 0, pytz.UTC),\n                        datetime(2024, 9, 5, 2, 0, 0, 0, pytz.UTC),\n                    ),\n                    (\n                        datetime(2024, 9, 5, 2, 0, 0, 0, pytz.UTC),\n                        datetime(2024, 9, 5, 3, 0, 0, 0, pytz.UTC),\n                    ),\n                ],\n            ),\n        ],\n    )\n    def test_build_batches(self, microbatch_model, start, end, batch_size, expected_batches):\n        microbatch_model.config.batch_size = batch_size\n        microbatch_builder = MicrobatchBuilder(\n            model=microbatch_model, is_incremental=True, event_time_start=None, event_time_end=None\n        )\n\n        actual_batches = microbatch_builder.build_batches(start, end)\n        assert len(actual_batches) == len(expected_batches)\n        assert actual_batches == expected_batches\n\n    def test_build_jinja_context_for_incremental_batch(self, microbatch_model):\n        context = MicrobatchBuilder.build_jinja_context_for_batch(\n            model=microbatch_model,\n            incremental_batch=True,\n        )\n\n        assert context[\"model\"] == microbatch_model.to_dict()\n        assert context[\"sql\"] == microbatch_model.compiled_code\n        assert context[\"compiled_code\"] == microbatch_model.compiled_code\n\n        assert context[\"is_incremental\"]() is True\n        assert context[\"should_full_refresh\"]() is False\n\n    def test_build_jinja_context_for_incremental_batch_false(self, microbatch_model):\n        context = MicrobatchBuilder.build_jinja_context_for_batch(\n            model=microbatch_model,\n            incremental_batch=False,\n        )\n\n        assert context[\"model\"] == microbatch_model.to_dict()\n        assert context[\"sql\"] == microbatch_model.compiled_code\n        assert context[\"compiled_code\"] == microbatch_model.compiled_code\n\n        # Only build is_incremental callables when not first batch\n        assert \"is_incremental\" not in context\n        assert \"should_full_refresh\" not in context\n\n    @pytest.mark.parametrize(\n        \"timestamp,batch_size,offset,expected_timestamp\",\n        [\n            (\n                datetime(2024, 9, 5, 3, 56, 1, 1, pytz.UTC),\n                BatchSize.year,\n                1,\n                datetime(2025, 1, 1, 0, 0, 0, 0, pytz.UTC),\n            ),\n            (\n                datetime(2024, 9, 5, 3, 56, 1, 1, pytz.UTC),\n                BatchSize.year,\n                -1,\n                datetime(2023, 1, 1, 0, 0, 0, 0, pytz.UTC),\n            ),\n            (\n                datetime(2024, 9, 5, 3, 56, 1, 1, pytz.UTC),\n                BatchSize.month,\n                1,\n                datetime(2024, 10, 1, 0, 0, 0, 0, pytz.UTC),\n            ),\n            (\n                datetime(2024, 9, 5, 3, 56, 1, 1, pytz.UTC),\n                BatchSize.month,\n                -1,\n                datetime(2024, 8, 1, 0, 0, 0, 0, pytz.UTC),\n            ),\n            (\n                datetime(2024, 9, 5, 3, 56, 1, 1, pytz.UTC),\n                BatchSize.day,\n                1,\n                datetime(2024, 9, 6, 0, 0, 0, 0, pytz.UTC),\n            ),\n            (\n                datetime(2024, 9, 5, 3, 56, 1, 1, pytz.UTC),\n                BatchSize.day,\n                -1,\n                datetime(2024, 9, 4, 0, 0, 0, 0, pytz.UTC),\n            ),\n            (\n                datetime(2024, 9, 5, 3, 56, 1, 1, pytz.UTC),\n                BatchSize.hour,\n                1,\n                datetime(2024, 9, 5, 4, 0, 0, 0, pytz.UTC),\n            ),\n            (\n                datetime(2024, 9, 5, 3, 56, 1, 1, pytz.UTC),\n                BatchSize.hour,\n                -1,\n                datetime(2024, 9, 5, 2, 0, 0, 0, pytz.UTC),\n            ),\n        ],\n    )\n    def test_offset_timestamp(self, timestamp, batch_size, offset, expected_timestamp):\n        assert (\n            MicrobatchBuilder.offset_timestamp(timestamp, batch_size, offset) == expected_timestamp\n        )\n\n    @pytest.mark.parametrize(\n        \"timestamp,batch_size,expected_timestamp\",\n        [\n            (\n                datetime(2024, 9, 5, 3, 56, 1, 1, pytz.UTC),\n                BatchSize.year,\n                datetime(2024, 1, 1, 0, 0, 0, 0, pytz.UTC),\n            ),\n            (\n                datetime(2024, 9, 5, 3, 56, 1, 1, pytz.UTC),\n                BatchSize.month,\n                datetime(2024, 9, 1, 0, 0, 0, 0, pytz.UTC),\n            ),\n            (\n                datetime(2024, 9, 5, 3, 56, 1, 1, pytz.UTC),\n                BatchSize.day,\n                datetime(2024, 9, 5, 0, 0, 0, 0, pytz.UTC),\n            ),\n            (\n                datetime(2024, 9, 5, 3, 56, 1, 1, pytz.UTC),\n                BatchSize.hour,\n                datetime(2024, 9, 5, 3, 0, 0, 0, pytz.UTC),\n            ),\n        ],\n    )\n    def test_truncate_timestamp(self, timestamp, batch_size, expected_timestamp):\n        assert MicrobatchBuilder.truncate_timestamp(timestamp, batch_size) == expected_timestamp\n\n    @pytest.mark.parametrize(\n        \"batch_size,start_time,expected_formatted_start_time\",\n        [\n            (BatchSize.year, datetime(2020, 1, 1, 1), \"2020\"),\n            (BatchSize.month, datetime(2020, 1, 1, 1), \"202001\"),\n            (BatchSize.day, datetime(2020, 1, 1, 1), \"20200101\"),\n            (BatchSize.hour, datetime(2020, 1, 1, 1), \"20200101T01\"),\n        ],\n    )\n    def test_batch_id(\n        self, batch_size: BatchSize, start_time: datetime, expected_formatted_start_time: str\n    ) -> None:\n        assert MicrobatchBuilder.batch_id(start_time, batch_size) == expected_formatted_start_time\n\n    @pytest.mark.parametrize(\n        \"batch_size,batch_start,expected_formatted_batch_start\",\n        [\n            (BatchSize.year, datetime(2020, 1, 1, 1), \"2020\"),\n            (BatchSize.month, datetime(2020, 1, 1, 1), \"2020-01\"),\n            (BatchSize.day, datetime(2020, 1, 1, 1), \"2020-01-01\"),\n            (BatchSize.hour, datetime(2020, 1, 1, 1), \"2020-01-01T01\"),\n        ],\n    )\n    def test_format_batch_start(\n        self, batch_size: BatchSize, batch_start: datetime, expected_formatted_batch_start: str\n    ) -> None:\n        assert (\n            MicrobatchBuilder.format_batch_start(batch_start, batch_size)\n            == expected_formatted_batch_start\n        )\n\n    @pytest.mark.parametrize(\n        \"timestamp,batch_size,expected_datetime\",\n        [\n            (\n                datetime(2024, 9, 17, 16, 6, 0, 0, pytz.UTC),\n                BatchSize.hour,\n                datetime(2024, 9, 17, 17, 0, 0, 0, pytz.UTC),\n            ),\n            (\n                datetime(2024, 9, 17, 16, 0, 0, 0, pytz.UTC),\n                BatchSize.hour,\n                datetime(2024, 9, 17, 16, 0, 0, 0, pytz.UTC),\n            ),\n            (\n                datetime(2024, 9, 17, 16, 6, 0, 0, pytz.UTC),\n                BatchSize.day,\n                datetime(2024, 9, 18, 0, 0, 0, 0, pytz.UTC),\n            ),\n            (\n                datetime(2024, 9, 17, 0, 0, 0, 0, pytz.UTC),\n                BatchSize.day,\n                datetime(2024, 9, 17, 0, 0, 0, 0, pytz.UTC),\n            ),\n            (\n                datetime(2024, 9, 17, 16, 6, 0, 0, pytz.UTC),\n                BatchSize.month,\n                datetime(2024, 10, 1, 0, 0, 0, 0, pytz.UTC),\n            ),\n            (\n                datetime(2024, 9, 1, 0, 0, 0, 0, pytz.UTC),\n                BatchSize.month,\n                datetime(2024, 9, 1, 0, 0, 0, 0, pytz.UTC),\n            ),\n            (\n                datetime(2024, 9, 17, 16, 6, 0, 0, pytz.UTC),\n                BatchSize.year,\n                datetime(2025, 1, 1, 0, 0, 0, 0, pytz.UTC),\n            ),\n            (\n                datetime(2024, 1, 1, 0, 0, 0, 0, pytz.UTC),\n                BatchSize.year,\n                datetime(2024, 1, 1, 0, 0, 0, 0, pytz.UTC),\n            ),\n        ],\n    )\n    def test_ceiling_timestamp(\n        self, timestamp: datetime, batch_size: BatchSize, expected_datetime: datetime\n    ) -> None:\n        ceilinged = MicrobatchBuilder.ceiling_timestamp(timestamp, batch_size)\n        assert ceilinged == expected_datetime\n"
  },
  {
    "path": "tests/unit/mock_adapter.py",
    "content": "from contextlib import contextmanager\nfrom unittest import mock\n\nfrom dbt.adapters.base import BaseAdapter\n\n\ndef adapter_factory():\n    class MockAdapter(BaseAdapter):\n        ConnectionManager = mock.MagicMock(TYPE=\"mock\")\n        responder = mock.MagicMock()\n        # some convenient defaults\n        responder.quote.side_effect = lambda identifier: '\"{}\"'.format(identifier)\n        responder.date_function.side_effect = lambda: \"unitdate()\"\n        responder.is_cancelable.side_effect = lambda: False\n\n        @contextmanager\n        def exception_handler(self, *args, **kwargs):\n            self.responder.exception_handler(*args, **kwargs)\n            yield\n\n        def execute(self, *args, **kwargs):\n            return self.responder.execute(*args, **kwargs)\n\n        def drop_relation(self, *args, **kwargs):\n            return self.responder.drop_relation(*args, **kwargs)\n\n        def truncate_relation(self, *args, **kwargs):\n            return self.responder.truncate_relation(*args, **kwargs)\n\n        def rename_relation(self, *args, **kwargs):\n            return self.responder.rename_relation(*args, **kwargs)\n\n        def get_columns_in_relation(self, *args, **kwargs):\n            return self.responder.get_columns_in_relation(*args, **kwargs)\n\n        def get_catalog_for_single_relation(self, *args, **kwargs):\n            return self.responder.get_catalog_for_single_relation(*args, **kwargs)\n\n        def expand_column_types(self, *args, **kwargs):\n            return self.responder.expand_column_types(*args, **kwargs)\n\n        def list_relations_without_caching(self, *args, **kwargs):\n            return self.responder.list_relations_without_caching(*args, **kwargs)\n\n        def create_schema(self, *args, **kwargs):\n            return self.responder.create_schema(*args, **kwargs)\n\n        def drop_schema(self, *args, **kwargs):\n            return self.responder.drop_schema(*args, **kwargs)\n\n        @classmethod\n        def quote(cls, identifier):\n            return cls.responder.quote(identifier)\n\n        def convert_text_type(self, *args, **kwargs):\n            return self.responder.convert_text_type(*args, **kwargs)\n\n        def convert_number_type(self, *args, **kwargs):\n            return self.responder.convert_number_type(*args, **kwargs)\n\n        def convert_integer_type(self, *args, **kwargs):\n            return self.responder.convert_integer_type(*args, **kwargs)\n\n        def convert_boolean_type(self, *args, **kwargs):\n            return self.responder.convert_boolean_type(*args, **kwargs)\n\n        def convert_datetime_type(self, *args, **kwargs):\n            return self.responder.convert_datetime_type(*args, **kwargs)\n\n        def convert_date_type(self, *args, **kwargs):\n            return self.responder.convert_date_type(*args, **kwargs)\n\n        def convert_time_type(self, *args, **kwargs):\n            return self.responder.convert_time_type(*args, **kwargs)\n\n        def list_schemas(self, *args, **kwargs):\n            return self.responder.list_schemas(*args, **kwargs)\n\n        @classmethod\n        def date_function(cls):\n            return cls.responder.date_function()\n\n        @classmethod\n        def is_cancelable(cls):\n            return cls.responder.is_cancelable()\n\n    return MockAdapter\n"
  },
  {
    "path": "tests/unit/parser/__init__.py",
    "content": ""
  },
  {
    "path": "tests/unit/parser/test_docs.py",
    "content": "import os\nimport unittest\nfrom argparse import Namespace\n\nfrom dbt.contracts.files import FileHash, FilePath, SourceFile\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.contracts.graph.nodes import Documentation\nfrom dbt.flags import set_from_args\nfrom dbt.node_types import NodeType\nfrom dbt.parser import docs\nfrom dbt.parser.search import FileBlock\nfrom tests.unit.utils import config_from_parts_or_dicts\n\nset_from_args(Namespace(WARN_ERROR=False), None)\n\nSNOWPLOW_SESSIONS_DOCS = r\"\"\"\nThis table contains one record for every session recorded by Snowplow.\nA session is itself comprised of pageviews that all occur within 30 minutes\nof each other. If more than 30 minutes elapse between pageviews, then a\nnew session is created. Given the following pageviews:\n\n| session_id | page_view_id | page_title |\n| ---------- | ------------ | ---------- |\n| abc        | 123          | Home       |\n| abc        | 456          | About      |\n| abc        | 789          | Home       |\n\nThe following sessions will be created:\n\n| session_id | first_page_title | count_pageviews |\n| ---------- | ---------------- | --------------- |\n| abc        | 123              | 2               |\n| abc        | 789              | 1               |\n\"\"\"\n\nSNOWPLOW_SESSIONS_SESSION_ID_DOCS = r\"\"\"\nThis column is the unique identifier for a Snowplow session. It is generated by\na cookie then expires after 30 minutes of inactivity.\n\"\"\"\n\nSNOWPLOW_SESSIONS_BLOCK = r\"\"\"\n{{% docs snowplow_sessions %}}\n{snowplow_sessions_docs}\n{{% enddocs %}}\n\"\"\".format(\n    snowplow_sessions_docs=SNOWPLOW_SESSIONS_DOCS\n).strip()\n\n\nSNOWPLOW_SESSIONS_SESSION_ID_BLOCK = r\"\"\"\n{{% docs snowplow_sessions__session_id %}}\n{snowplow_sessions_session_id_docs}\n{{% enddocs %}}\n\"\"\".format(\n    snowplow_sessions_session_id_docs=SNOWPLOW_SESSIONS_SESSION_ID_DOCS\n).strip()\n\n\nTEST_DOCUMENTATION_FILE = r\"\"\"\n{sessions_block}\n\n{session_id_block}\n\"\"\".format(\n    sessions_block=SNOWPLOW_SESSIONS_BLOCK,\n    session_id_block=SNOWPLOW_SESSIONS_SESSION_ID_BLOCK,\n)\n\n\nMULTIPLE_RAW_BLOCKS = r\"\"\"\n{% docs some_doc %}\n{% raw %}\n    ```\n    {% docs %}some doc{% enddocs %}\n    ```\n{% endraw %}\n{% enddocs %}\n\n{% docs other_doc %}\n{% raw %}\n    ```\n    {% docs %}other doc{% enddocs %}\n    ```\n{% endraw %}\n{% enddocs %}\n\"\"\"\n\n\nclass DocumentationParserTest(unittest.TestCase):\n    def setUp(self):\n        if os.name == \"nt\":\n            self.root_path = \"C:\\\\test_root\"\n            self.subdir_path = \"C:\\\\test_root\\\\test_subdir\"\n            self.testfile_path = \"C:\\\\test_root\\\\test_subdir\\\\test_file.md\"\n        else:\n            self.root_path = \"/test_root\"\n            self.subdir_path = \"/test_root/test_subdir\"\n            self.testfile_path = \"/test_root/test_subdir/test_file.md\"\n\n        profile_data = {\n            \"outputs\": {\n                \"test\": {\n                    \"type\": \"postgres\",\n                    \"host\": \"localhost\",\n                    \"schema\": \"analytics\",\n                    \"user\": \"test\",\n                    \"pass\": \"test\",\n                    \"dbname\": \"test\",\n                    \"port\": 1,\n                }\n            },\n            \"target\": \"test\",\n        }\n        root_project = {\n            \"name\": \"root\",\n            \"version\": \"0.1\",\n            \"profile\": \"test\",\n            \"project-root\": self.root_path,\n            \"config-version\": 2,\n        }\n\n        subdir_project = {\n            \"name\": \"some_package\",\n            \"version\": \"0.1\",\n            \"profile\": \"test\",\n            \"project-root\": self.subdir_path,\n            \"quoting\": {},\n            \"config-version\": 2,\n        }\n        self.root_project_config = config_from_parts_or_dicts(\n            project=root_project, profile=profile_data\n        )\n        self.subdir_project_config = config_from_parts_or_dicts(\n            project=subdir_project, profile=profile_data\n        )\n\n    def _build_file(self, contents, relative_path) -> FileBlock:\n        match = FilePath(\n            relative_path=relative_path,\n            project_root=self.root_path,\n            searched_path=self.subdir_path,\n            modification_time=0.0,\n        )\n        source_file = SourceFile(path=match, checksum=FileHash.empty())\n        source_file.contents = contents\n        return FileBlock(file=source_file)\n\n    def test_load_file(self):\n        parser = docs.DocumentationParser(\n            root_project=self.root_project_config,\n            manifest=Manifest(),\n            project=self.subdir_project_config,\n        )\n\n        file_block = self._build_file(TEST_DOCUMENTATION_FILE, \"test_file.md\")\n\n        parser.parse_file(file_block)\n        docs_values = sorted(parser.manifest.docs.values(), key=lambda n: n.name)\n        self.assertEqual(len(docs_values), 2)\n        for result in docs_values:\n            self.assertIsInstance(result, Documentation)\n            self.assertEqual(result.package_name, \"some_package\")\n            self.assertEqual(result.original_file_path, self.testfile_path)\n            self.assertEqual(result.resource_type, NodeType.Documentation)\n            self.assertEqual(result.path, \"test_file.md\")\n\n        self.assertEqual(docs_values[0].name, \"snowplow_sessions\")\n        self.assertEqual(docs_values[1].name, \"snowplow_sessions__session_id\")\n\n    def test_load_file_extras(self):\n        TEST_DOCUMENTATION_FILE + \"{% model foo %}select 1 as id{% endmodel %}\"\n\n        parser = docs.DocumentationParser(\n            root_project=self.root_project_config,\n            manifest=Manifest(),\n            project=self.subdir_project_config,\n        )\n\n        file_block = self._build_file(TEST_DOCUMENTATION_FILE, \"test_file.md\")\n\n        parser.parse_file(file_block)\n        docs_values = sorted(parser.manifest.docs.values(), key=lambda n: n.name)\n        self.assertEqual(len(docs_values), 2)\n        for result in docs_values:\n            self.assertIsInstance(result, Documentation)\n        self.assertEqual(docs_values[0].name, \"snowplow_sessions\")\n        self.assertEqual(docs_values[1].name, \"snowplow_sessions__session_id\")\n\n    def test_multiple_raw_blocks(self):\n        parser = docs.DocumentationParser(\n            root_project=self.root_project_config,\n            manifest=Manifest(),\n            project=self.subdir_project_config,\n        )\n\n        file_block = self._build_file(MULTIPLE_RAW_BLOCKS, \"test_file.md\")\n\n        parser.parse_file(file_block)\n        docs_values = sorted(parser.manifest.docs.values(), key=lambda n: n.name)\n        self.assertEqual(len(docs_values), 2)\n        for result in docs_values:\n            self.assertIsInstance(result, Documentation)\n            self.assertEqual(result.package_name, \"some_package\")\n            self.assertEqual(result.original_file_path, self.testfile_path)\n            self.assertEqual(result.resource_type, NodeType.Documentation)\n            self.assertEqual(result.path, \"test_file.md\")\n\n        self.assertEqual(docs_values[0].name, \"other_doc\")\n        self.assertEqual(\n            docs_values[0].block_contents, \"```\\n    {% docs %}other doc{% enddocs %}\\n    ```\"\n        )\n        self.assertEqual(docs_values[1].name, \"some_doc\")\n        self.assertEqual(\n            docs_values[1].block_contents,\n            \"```\\n    {% docs %}some doc{% enddocs %}\\n    ```\",\n        )\n"
  },
  {
    "path": "tests/unit/parser/test_get_doc_blocks.py",
    "content": "from unittest.mock import MagicMock\n\nfrom dbt.parser.manifest import _get_doc_blocks\n\n\nclass TestGetDocBlocks:\n    def test_name_node_arg_does_not_raise(self):\n        \"\"\"doc() with a variable reference (Name node, no .value) must not raise AttributeError.\"\"\"\n        manifest = MagicMock()\n        # {{ doc(my_variable) }} produces a jinja2.nodes.Name arg, not a Const\n        result = _get_doc_blocks(\"{{ doc(my_variable) }}\", manifest, \"my_package\")\n        assert result == []\n\n    def test_const_arg_resolves_doc_block(self):\n        \"\"\"doc() with a string literal still resolves to a doc_block unique_id.\"\"\"\n        manifest = MagicMock()\n        manifest.metadata.project_name = \"my_project\"\n        resolved = MagicMock()\n        resolved.unique_id = \"doc.my_project.my_doc\"\n        manifest.resolve_doc.return_value = resolved\n\n        result = _get_doc_blocks(\"{{ doc('my_doc') }}\", manifest, \"my_package\")\n\n        assert result == [\"doc.my_project.my_doc\"]\n        manifest.resolve_doc.assert_called_once_with(\"my_doc\", None, \"my_project\", \"my_package\")\n\n    def test_mixed_args_skips_name_nodes(self):\n        \"\"\"When one arg is a Name node and others are Const, only Const values are used.\"\"\"\n        manifest = MagicMock()\n        manifest.metadata.project_name = \"my_project\"\n        manifest.resolve_doc.return_value = None\n\n        # doc(my_var) — one Name arg → doc_args becomes [] → falls through to else: continue\n        result = _get_doc_blocks(\"{{ doc(my_var) }}\", manifest, \"my_package\")\n        assert result == []\n        manifest.resolve_doc.assert_not_called()\n"
  },
  {
    "path": "tests/unit/parser/test_manifest.py",
    "content": "from argparse import Namespace\nfrom typing import Optional\nfrom unittest.mock import MagicMock, patch\n\nimport jinja2\nimport msgpack\nimport pytest\nfrom pytest_mock import MockerFixture\n\nfrom dbt.adapters.postgres import PostgresAdapter\nfrom dbt.artifacts.resources.base import FileHash\nfrom dbt.artifacts.resources.v1.semantic_model import NodeRelation\nfrom dbt.config import RuntimeConfig\nfrom dbt.contracts.graph.manifest import Manifest, ManifestStateCheck\nfrom dbt.events.types import InvalidConcurrentBatchesConfig, UnusedResourceConfigPath\nfrom dbt.flags import set_from_args\nfrom dbt.parser.manifest import (\n    ManifestLoader,\n    _warn_for_unused_resource_config_paths,\n    extended_mashumaro_encoder,\n    extended_msgpack_encoder,\n)\nfrom dbt.parser.read_files import FileDiff\nfrom dbt.tracking import User\nfrom dbt_common.events.event_catcher import EventCatcher\nfrom dbt_common.events.event_manager_client import add_callback_to_manager\nfrom tests.unit.fixtures import model_node\n\n\nclass TestPartialParse:\n    @patch(\"dbt.parser.manifest.ManifestLoader.build_manifest_state_check\")\n    @patch(\"dbt.parser.manifest.os.path.exists\")\n    @patch(\"dbt.parser.manifest.open\")\n    def test_partial_parse_file_path(self, patched_open, patched_os_exist, patched_state_check):\n        mock_project = MagicMock(RuntimeConfig)\n        mock_project.project_target_path = \"mock_target_path\"\n        patched_os_exist.return_value = True\n        ManifestLoader(mock_project, {})\n        # by default we use the project_target_path\n        patched_open.assert_called_with(\"mock_target_path/partial_parse.msgpack\", \"rb\")\n        set_from_args(Namespace(partial_parse_file_path=\"specified_partial_parse_path\"), {})\n        ManifestLoader(mock_project, {})\n        # if specified in flags, we use the specified path\n        patched_open.assert_called_with(\"specified_partial_parse_path\", \"rb\")\n\n    def test_profile_hash_change(self, mock_project):\n        # This test validate that the profile_hash is updated when the connection keys change\n        profile_hash = \"750bc99c1d64ca518536ead26b28465a224be5ffc918bf2a490102faa5a1bcf5\"\n        mock_project.credentials.connection_info.return_value = \"test\"\n        manifest = ManifestLoader(mock_project, {})\n        assert manifest.manifest.state_check.profile_hash.checksum == profile_hash\n        mock_project.credentials.connection_info.return_value = \"test1\"\n        manifest = ManifestLoader(mock_project, {})\n        assert manifest.manifest.state_check.profile_hash.checksum != profile_hash\n\n    @patch(\"dbt.parser.manifest.ManifestLoader.build_manifest_state_check\")\n    @patch(\"dbt.parser.manifest.os.path.exists\")\n    @patch(\"dbt.parser.manifest.open\")\n    def test_partial_parse_by_version(\n        self,\n        patched_open,\n        patched_os_exist,\n        patched_state_check,\n        runtime_config: RuntimeConfig,\n        manifest: Manifest,\n    ):\n        file_hash = FileHash.from_contents(\"test contests\")\n        manifest.state_check = ManifestStateCheck(\n            vars_hash=file_hash,\n            profile_hash=file_hash,\n            profile_env_vars_hash=file_hash,\n            project_env_vars_hash=file_hash,\n        )\n        # we need a loader to compare the two manifests\n        loader = ManifestLoader(runtime_config, {runtime_config.project_name: runtime_config})\n        loader.manifest = manifest.deepcopy()\n\n        is_partial_parsable, _ = loader.is_partial_parsable(manifest)\n        assert is_partial_parsable\n\n        manifest.metadata.dbt_version = \"0.0.1a1\"\n        is_partial_parsable, _ = loader.is_partial_parsable(manifest)\n        assert not is_partial_parsable\n\n        manifest.metadata.dbt_version = \"99999.99.99\"\n        is_partial_parsable, _ = loader.is_partial_parsable(manifest)\n        assert not is_partial_parsable\n\n\nclass TestFailedPartialParse:\n    @patch(\"dbt.tracking.track_partial_parser\")\n    @patch(\"dbt.tracking.active_user\")\n    @patch(\"dbt.parser.manifest.PartialParsing\")\n    @patch(\"dbt.parser.manifest.ManifestLoader.read_manifest_for_partial_parse\")\n    @patch(\"dbt.parser.manifest.ManifestLoader.build_manifest_state_check\")\n    def test_partial_parse_safe_update_project_parser_files_partially(\n        self,\n        patched_state_check,\n        patched_read_manifest_for_partial_parse,\n        patched_partial_parsing,\n        patched_active_user,\n        patched_track_partial_parser,\n    ):\n        mock_instance = MagicMock()\n        mock_instance.skip_parsing.return_value = False\n        mock_instance.get_parsing_files.side_effect = KeyError(\"Whoopsie!\")\n        patched_partial_parsing.return_value = mock_instance\n\n        mock_project = MagicMock(RuntimeConfig)\n        mock_project.project_target_path = \"mock_target_path\"\n\n        mock_saved_manifest = MagicMock(Manifest)\n        mock_saved_manifest.files = {}\n        patched_read_manifest_for_partial_parse.return_value = mock_saved_manifest\n\n        loader = ManifestLoader(mock_project, {})\n        loader.safe_update_project_parser_files_partially({})\n\n        patched_track_partial_parser.assert_called_once()\n        exc_info = patched_track_partial_parser.call_args[0][0]\n        assert \"traceback\" in exc_info\n        assert \"exception\" in exc_info\n        assert \"code\" in exc_info\n        assert \"location\" in exc_info\n        assert \"full_reparse_reason\" in exc_info\n        assert \"KeyError: 'Whoopsie!'\" == exc_info[\"exception\"]\n        assert isinstance(exc_info[\"code\"], str) or isinstance(exc_info[\"code\"], type(None))\n\n\nclass TestGetFullManifest:\n    @pytest.fixture\n    def set_required_mocks(\n        self, mocker: MockerFixture, manifest: Manifest, mock_adapter: MagicMock\n    ):\n        mocker.patch(\"dbt.parser.manifest.get_adapter\").return_value = mock_adapter\n        mocker.patch(\"dbt.parser.manifest.ManifestLoader.load\").return_value = manifest\n        mocker.patch(\"dbt.parser.manifest._check_manifest\").return_value = None\n        mocker.patch(\"dbt.parser.manifest.ManifestLoader.save_macros_to_adapter\").return_value = (\n            None\n        )\n        mocker.patch(\"dbt.tracking.active_user\").return_value = User(None)\n\n    def test_write_perf_info(\n        self,\n        mock_project: MagicMock,\n        mocker: MockerFixture,\n        set_required_mocks,\n    ) -> None:\n        write_perf_info = mocker.patch(\"dbt.parser.manifest.ManifestLoader.write_perf_info\")\n\n        ManifestLoader.get_full_manifest(\n            config=mock_project,\n            # write_perf_info=False let it default instead\n        )\n        assert not write_perf_info.called\n\n        ManifestLoader.get_full_manifest(config=mock_project, write_perf_info=False)\n        assert not write_perf_info.called\n\n        ManifestLoader.get_full_manifest(config=mock_project, write_perf_info=True)\n        assert write_perf_info.called\n\n    def test_reset(\n        self,\n        mock_project: MagicMock,\n        mock_adapter: MagicMock,\n        set_required_mocks,\n    ) -> None:\n\n        ManifestLoader.get_full_manifest(\n            config=mock_project,\n            # reset=False let it default instead\n        )\n        assert not mock_project.clear_dependencies.called\n        assert not mock_adapter.clear_macro_resolver.called\n\n        ManifestLoader.get_full_manifest(config=mock_project, reset=False)\n        assert not mock_project.clear_dependencies.called\n        assert not mock_adapter.clear_macro_resolver.called\n\n        ManifestLoader.get_full_manifest(config=mock_project, reset=True)\n        assert mock_project.clear_dependencies.called\n        assert mock_adapter.clear_macro_resolver.called\n\n    def test_partial_parse_file_diff_flag(\n        self,\n        mock_project: MagicMock,\n        mocker: MockerFixture,\n        set_required_mocks,\n    ) -> None:\n\n        # FileDiff.from_dict is only called if PARTIAL_PARSE_FILE_DIFF == False\n        # So we can track this function call to check if setting PARTIAL_PARSE_FILE_DIFF\n        # works appropriately\n        mock_file_diff = mocker.patch(\"dbt.parser.read_files.FileDiff.from_dict\")\n        mock_file_diff.return_value = FileDiff([], [], [])\n\n        ManifestLoader.get_full_manifest(config=mock_project)\n        assert not mock_file_diff.called\n\n        set_from_args(Namespace(PARTIAL_PARSE_FILE_DIFF=True), {})\n        ManifestLoader.get_full_manifest(config=mock_project)\n        assert not mock_file_diff.called\n\n        set_from_args(Namespace(PARTIAL_PARSE_FILE_DIFF=False), {})\n        ManifestLoader.get_full_manifest(config=mock_project)\n        assert mock_file_diff.called\n\n\nclass TestWarnUnusedConfigs:\n    @pytest.mark.parametrize(\n        \"resource_type,path,expect_used\",\n        [\n            (\"data_tests\", \"unused_path\", False),\n            (\"data_tests\", \"minimal\", True),\n            (\"metrics\", \"unused_path\", False),\n            (\"metrics\", \"test\", True),\n            (\"models\", \"unused_path\", False),\n            (\"models\", \"pkg\", True),\n            (\"saved_queries\", \"unused_path\", False),\n            (\"saved_queries\", \"test\", True),\n            (\"seeds\", \"unused_path\", False),\n            (\"seeds\", \"pkg\", True),\n            (\"semantic_models\", \"unused_path\", False),\n            (\"semantic_models\", \"test\", True),\n            (\"sources\", \"unused_path\", False),\n            (\"sources\", \"pkg\", True),\n            (\"unit_tests\", \"unused_path\", False),\n            (\"unit_tests\", \"pkg\", True),\n        ],\n    )\n    def test_warn_for_unused_resource_config_paths(\n        self,\n        resource_type: str,\n        path: str,\n        expect_used: bool,\n        manifest: Manifest,\n        runtime_config: RuntimeConfig,\n    ) -> None:\n        catcher = EventCatcher(UnusedResourceConfigPath)\n        add_callback_to_manager(catcher.catch)\n\n        setattr(runtime_config, resource_type, {path: {\"+materialized\": \"table\"}})\n\n        _warn_for_unused_resource_config_paths(manifest=manifest, config=runtime_config)\n\n        if expect_used:\n            assert len(catcher.caught_events) == 0\n        else:\n            assert len(catcher.caught_events) == 1\n            assert f\"{resource_type}.{path}\" in str(catcher.caught_events[0].data)\n\n\nclass TestCheckForcingConcurrentBatches:\n    @pytest.fixture\n    @patch(\"dbt.parser.manifest.ManifestLoader.build_manifest_state_check\")\n    @patch(\"dbt.parser.manifest.os.path.exists\")\n    @patch(\"dbt.parser.manifest.open\")\n    def manifest_loader(\n        self, patched_open, patched_os_exist, patched_state_check\n    ) -> ManifestLoader:\n        mock_project = MagicMock(RuntimeConfig)\n        mock_project.project_target_path = \"mock_target_path\"\n        mock_project.project_name = \"mock_project_name\"\n        return ManifestLoader(mock_project, {})\n\n    @pytest.fixture\n    def event_catcher(self) -> EventCatcher:\n        return EventCatcher(InvalidConcurrentBatchesConfig)\n\n    @pytest.mark.parametrize(\n        \"adapter_support,concurrent_batches_config,expect_warning\",\n        [\n            (False, True, True),\n            (False, False, False),\n            (False, None, False),\n            (True, True, False),\n            (True, False, False),\n            (True, None, False),\n        ],\n    )\n    def test_check_forcing_concurrent_batches(\n        self,\n        mocker: MockerFixture,\n        manifest_loader: ManifestLoader,\n        postgres_adapter: PostgresAdapter,\n        event_catcher: EventCatcher,\n        adapter_support: bool,\n        concurrent_batches_config: Optional[bool],\n        expect_warning: bool,\n    ):\n        add_callback_to_manager(event_catcher.catch)\n        model = model_node()\n        model.config.concurrent_batches = concurrent_batches_config\n        mocker.patch.object(postgres_adapter, \"supports\").return_value = adapter_support\n        mocker.patch(\"dbt.parser.manifest.get_adapter\").return_value = postgres_adapter\n        mocker.patch.object(manifest_loader.manifest, \"use_microbatch_batches\").return_value = True\n\n        manifest_loader.manifest.add_node_nofile(model)\n        manifest_loader.check_forcing_batch_concurrency()\n\n        if expect_warning:\n            assert len(event_catcher.caught_events) == 1\n            assert \"Batches will be run sequentially\" in event_catcher.caught_events[0].info.msg  # type: ignore\n        else:\n            assert len(event_catcher.caught_events) == 0\n\n\nclass TestUpdateSemanticModel:\n    \"\"\"Tests for ManifestLoader.update_semantic_model.\"\"\"\n\n    @pytest.fixture\n    @patch(\"dbt.parser.manifest.ManifestLoader.build_manifest_state_check\")\n    @patch(\"dbt.parser.manifest.os.path.exists\")\n    @patch(\"dbt.parser.manifest.open\")\n    def loader(self, patched_open, patched_os_exist, patched_state_check):\n        mock_project = MagicMock(RuntimeConfig)\n        mock_project.project_target_path = \"mock_target_path\"\n        return ManifestLoader(mock_project, {})\n\n    def test_no_index_error_when_depends_on_nodes_is_empty(self, loader):\n        \"\"\"Regression: update_semantic_model must not raise IndexError when\n        depends_on_nodes is empty (e.g. referenced model is disabled).\"\"\"\n        semantic_model = MagicMock()\n        semantic_model.depends_on_nodes = []\n\n        # Before the fix this raised: IndexError: list index out of range\n        loader.update_semantic_model(semantic_model)\n\n        # node_relation must not have been assigned\n        assert \"node_relation\" not in semantic_model.__dict__\n\n    def test_node_relation_set_when_depends_on_nodes_has_entry(self, loader):\n        \"\"\"When depends_on_nodes is non-empty, node_relation is populated.\"\"\"\n        refd_node = MagicMock()\n        refd_node.relation_name = '\"db\".\"schema\".\"my_model\"'\n        refd_node.alias = \"my_model\"\n        refd_node.schema = \"schema\"\n        refd_node.database = \"db\"\n        loader.manifest.nodes[\"model.pkg.my_model\"] = refd_node\n\n        semantic_model = MagicMock()\n        semantic_model.depends_on_nodes = [\"model.pkg.my_model\"]\n\n        loader.update_semantic_model(semantic_model)\n\n        assert semantic_model.node_relation == NodeRelation(\n            relation_name='\"db\".\"schema\".\"my_model\"',\n            alias=\"my_model\",\n            schema_name=\"schema\",\n            database=\"db\",\n        )\n\n\nclass TestExtendedMsgpackEncoder:\n    \"\"\"\n    Unit tests for extended_msgpack_encoder and extended_mashumaro_encoder.\n\n    The key regression being guarded: jinja2.Undefined objects that end up in\n    manifest node fields (e.g. meta values rendered from schema.yml with an\n    undefined Jinja variable) must be serialisable to msgpack.  Without the\n    isinstance(obj, jinja2.Undefined) branch in extended_msgpack_encoder the\n    packer raises:\n        TypeError: can not serialize 'Undefined' object\n    \"\"\"\n\n    def test_undefined_returns_none(self):\n        \"\"\"extended_msgpack_encoder converts jinja2.Undefined to None.\"\"\"\n        undefined = jinja2.Undefined(name=\"some_undefined_var\")\n        result = extended_msgpack_encoder(undefined)\n        assert result is None\n\n    def test_undefined_subclass_returns_none(self):\n        \"\"\"extended_msgpack_encoder handles jinja2.Undefined subclasses.\"\"\"\n\n        class MyUndefined(jinja2.Undefined):\n            pass\n\n        result = extended_msgpack_encoder(MyUndefined())\n        assert result is None\n\n    def test_non_undefined_passthrough(self):\n        \"\"\"extended_msgpack_encoder passes through unknown types unchanged.\"\"\"\n        # msgpack itself will raise for truly unserializable objects; the\n        # encoder just returns them so msgpack can raise its own error.\n        obj = object()\n        assert extended_msgpack_encoder(obj) is obj\n\n    def test_mashumaro_encoder_with_undefined_in_dict(self):\n        \"\"\"\n        extended_mashumaro_encoder can pack a dict containing jinja2.Undefined.\n\n        This is the direct reproduction of the production traceback: a manifest\n        node with a meta dict like {\"key\": <jinja2.Undefined>} must serialise\n        without raising TypeError.\n        \"\"\"\n        undefined = jinja2.Undefined(name=\"undefined_jinja_var\")\n        data = {\"meta\": {\"key\": undefined}}\n        # Must not raise TypeError\n        packed = extended_mashumaro_encoder(data)\n        unpacked = msgpack.unpackb(packed, raw=False)\n        assert unpacked == {\"meta\": {\"key\": None}}\n\n    def test_mashumaro_encoder_without_undefined_unchanged(self):\n        \"\"\"extended_mashumaro_encoder round-trips plain data correctly.\"\"\"\n        data = {\"meta\": {\"key\": \"value\"}, \"count\": 42}\n        packed = extended_mashumaro_encoder(data)\n        unpacked = msgpack.unpackb(packed, raw=False)\n        assert unpacked == data\n"
  },
  {
    "path": "tests/unit/parser/test_parser.py",
    "content": "import os\nimport unittest\nfrom argparse import Namespace\nfrom copy import deepcopy\nfrom unittest import mock\n\nimport yaml\n\nimport dbt_common.events.functions\nfrom dbt import tracking\nfrom dbt.artifacts.resources import ModelConfig, RefArgs\nfrom dbt.artifacts.resources.v1.model import (\n    ModelBuildAfter,\n    ModelFreshnessUpdatesOnOptions,\n)\nfrom dbt.context.context_config import ContextConfig\nfrom dbt.contracts.files import FileHash, FilePath, SchemaSourceFile, SourceFile\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.contracts.graph.model_config import NodeConfig, SnapshotConfig, TestConfig\nfrom dbt.contracts.graph.nodes import (\n    AnalysisNode,\n    DependsOn,\n    Macro,\n    ModelNode,\n    SingularTestNode,\n    SnapshotNode,\n    UnpatchedSourceDefinition,\n)\nfrom dbt.events.types import FreshnessConfigProblem\nfrom dbt.exceptions import CompilationError, ParsingError, SchemaConfigError\nfrom dbt.flags import set_from_args\nfrom dbt.node_types import NodeType\nfrom dbt.parser import (\n    AnalysisParser,\n    GenericTestParser,\n    MacroParser,\n    ModelParser,\n    SchemaParser,\n    SingularTestParser,\n    SnapshotParser,\n)\nfrom dbt.parser.common import YamlBlock\nfrom dbt.parser.models import (\n    _get_config_call_dict,\n    _get_exp_sample_result,\n    _get_sample_result,\n    _get_stable_sample_result,\n    _shift_sources,\n)\nfrom dbt.parser.schemas import (\n    AnalysisPatchParser,\n    MacroPatchParser,\n    ModelPatchParser,\n    SourceParser,\n    TestablePatchParser,\n    yaml_from_file,\n)\nfrom dbt.parser.search import FileBlock\nfrom dbt.parser.sources import SourcePatcher\nfrom dbt.tests.util import safe_set_invocation_context\nfrom dbt_common.events.event_catcher import EventCatcher\nfrom dbt_common.events.event_manager_client import add_callback_to_manager\nfrom tests.unit.utils import (\n    MockNode,\n    config_from_parts_or_dicts,\n    generate_name_macros,\n    normalize,\n)\n\nset_from_args(\n    Namespace(\n        warn_error=False,\n        state_modified_compare_more_unrendered_values=False,\n        require_generic_test_arguments_property=False,\n    ),\n    None,\n)\n\n\ndef get_abs_os_path(unix_path):\n    return normalize(os.path.abspath(unix_path))\n\n\nclass BaseParserTest(unittest.TestCase):\n    maxDiff = None\n\n    def _generate_macros(self):\n        name_sql = {}\n        for component in (\"database\", \"schema\", \"alias\"):\n            if component == \"alias\":\n                source = \"node.name\"\n            else:\n                source = f\"target.{component}\"\n            name = f\"generate_{component}_name\"\n            sql = f\"{{% macro {name}(value, node) %}} {{% if value %}} {{{{ value }}}} {{% else %}} {{{{ {source} }}}} {{% endif %}} {{% endmacro %}}\"\n            name_sql[name] = sql\n\n        for name, sql in name_sql.items():\n            pm = Macro(\n                name=name,\n                resource_type=NodeType.Macro,\n                unique_id=f\"macro.root.{name}\",\n                package_name=\"root\",\n                original_file_path=normalize(\"macros/macro.sql\"),\n                path=normalize(\"macros/macro.sql\"),\n                macro_sql=sql,\n            )\n            yield pm\n\n    def setUp(self):\n        set_from_args(\n            Namespace(\n                warn_error=True,\n                state_modified_compare_more_unrendered_values=False,\n                require_generic_test_arguments_property=False,\n            ),\n            None,\n        )\n\n        safe_set_invocation_context()\n        # HACK: this is needed since tracking events can\n        # be sent when using the model parser\n        tracking.do_not_track()\n\n        self.maxDiff = None\n\n        profile_data = {\n            \"target\": \"test\",\n            \"quoting\": {},\n            \"outputs\": {\n                \"test\": {\n                    \"type\": \"postgres\",\n                    \"host\": \"localhost\",\n                    \"schema\": \"analytics\",\n                    \"user\": \"test\",\n                    \"pass\": \"test\",\n                    \"dbname\": \"test\",\n                    \"port\": 1,\n                }\n            },\n        }\n\n        root_project = {\n            \"name\": \"root\",\n            \"version\": \"0.1\",\n            \"profile\": \"test\",\n            \"project-root\": normalize(\"/usr/src/app\"),\n            \"config-version\": 2,\n        }\n\n        self.root_project_config = config_from_parts_or_dicts(\n            project=root_project, profile=profile_data, cli_vars={\"test_schema_name\": \"foo\"}\n        )\n\n        snowplow_project = {\n            \"name\": \"snowplow\",\n            \"version\": \"0.1\",\n            \"profile\": \"test\",\n            \"project-root\": get_abs_os_path(\"./dbt_packages/snowplow\"),\n            \"config-version\": 2,\n        }\n\n        self.snowplow_project_config = config_from_parts_or_dicts(\n            project=snowplow_project, profile=profile_data\n        )\n\n        self.all_projects = {\n            \"root\": self.root_project_config,\n            \"snowplow\": self.snowplow_project_config,\n        }\n\n        self.root_project_config.dependencies = self.all_projects\n        self.snowplow_project_config.dependencies = self.all_projects\n        self.patcher = mock.patch(\"dbt.context.providers.get_adapter\")\n        self.factory = self.patcher.start()\n\n        self.parser_patcher = mock.patch(\"dbt.parser.base.get_adapter\")\n        self.factory_parser = self.parser_patcher.start()\n\n        self.manifest = Manifest(\n            macros={m.unique_id: m for m in generate_name_macros(\"root\")},\n        )\n\n    def tearDown(self):\n        self.parser_patcher.stop()\n        self.patcher.stop()\n\n    def source_file_for(self, data: str, filename: str, searched: str):\n        root_dir = get_abs_os_path(\"./dbt_packages/snowplow\")\n        filename = normalize(filename)\n        path = FilePath(\n            searched_path=searched,\n            relative_path=filename,\n            project_root=root_dir,\n            modification_time=0.0,\n        )\n        sf_cls = SchemaSourceFile if filename.endswith(\".yml\") else SourceFile\n        source_file = sf_cls(\n            path=path,\n            checksum=FileHash.from_contents(data),\n            project_name=\"snowplow\",\n        )\n        source_file.contents = data\n        return source_file\n\n    def file_block_for(self, data: str, filename: str, searched: str):\n        source_file = self.source_file_for(data, filename, searched)\n        return FileBlock(file=source_file)\n\n    def assert_has_manifest_lengths(\n        self, manifest, macros=3, nodes=0, sources=0, docs=0, disabled=0, unit_tests=0\n    ):\n        self.assertEqual(len(manifest.macros), macros)\n        self.assertEqual(len(manifest.nodes), nodes)\n        self.assertEqual(len(manifest.sources), sources)\n        self.assertEqual(len(manifest.docs), docs)\n        self.assertEqual(len(manifest.disabled), disabled)\n        self.assertEqual(len(manifest.unit_tests), unit_tests)\n\n\ndef assertEqualNodes(node_one, node_two):\n    node_one_dict = node_one.to_dict()\n    if \"created_at\" in node_one_dict:\n        del node_one_dict[\"created_at\"]\n    if \"relation_name\" in node_one_dict:\n        del node_one_dict[\"relation_name\"]\n    node_two_dict = node_two.to_dict()\n    if \"created_at\" in node_two_dict:\n        del node_two_dict[\"created_at\"]\n    if \"relation_name\" in node_two_dict:\n        del node_two_dict[\"relation_name\"]\n    # we don't reall care the order of packages, doing this because it is hard to\n    # make config.packages a set instead of a list\n    if \"config\" in node_one_dict and \"packages\" in node_one_dict[\"config\"]:\n        if \"config\" not in node_two_dict and \"packages\" in node_two_dict[\"config\"]:\n            return False\n        node_one_dict[\"config\"][\"packages\"] = set(node_one_dict[\"config\"][\"packages\"])\n        node_two_dict[\"config\"][\"packages\"] = set(node_two_dict[\"config\"][\"packages\"])\n        node_one_dict[\"unrendered_config\"][\"packages\"] = set(node_one_dict[\"config\"][\"packages\"])\n        node_two_dict[\"unrendered_config\"][\"packages\"] = set(node_two_dict[\"config\"][\"packages\"])\n        if \"packages\" in node_one_dict[\"config_call_dict\"]:\n            node_one_dict[\"config_call_dict\"][\"packages\"] = set(\n                node_one_dict[\"config_call_dict\"][\"packages\"]\n            )\n            node_two_dict[\"config_call_dict\"][\"packages\"] = set(\n                node_two_dict[\"config_call_dict\"][\"packages\"]\n            )\n\n    assert node_one_dict == node_two_dict\n\n\nSINGLE_TABLE_SOURCE = \"\"\"\nsources:\n    - name: my_source\n      tables:\n        - name: my_table\n\"\"\"\n\n\nMULTIPLE_TABLE_SOURCE_META = \"\"\"\nsources:\n    - name: my_source\n      meta:\n        source_field: source_value\n        shared_field: shared_field_default\n      tables:\n        - name: my_table_shared_field_default\n          meta:\n            table_field: table_value\n        - name: my_table_shared_field_override\n          meta:\n            shared_field: shared_field_table_override\n            table_field: table_value\n\"\"\"\n\nSINGLE_TABLE_SOURCE_TESTS = \"\"\"\nsources:\n    - name: my_source\n      tables:\n        - name: my_table\n          description: A description of my table\n          columns:\n            - name: color\n              data_tests:\n                - not_null:\n                    severity: WARN\n                - accepted_values:\n                    values: ['red', 'blue', 'green']\n\"\"\"\n\nSINGLE_TABLE_MODEL_TESTS = \"\"\"\nmodels:\n    - name: my_model\n      description: A description of my model\n      columns:\n        - name: color\n          description: The color value\n          data_tests:\n            - not_null:\n                severity: WARN\n            - accepted_values:\n                description: Only primary colors are allowed in here\n                values: ['red', 'blue', 'green']\n            - foreign_package.test_case:\n                arg: 100\n\"\"\"\n\nSINGLE_TABLE_MODEL_TESTS_WRONG_SEVERITY = \"\"\"\nmodels:\n    - name: my_model\n      description: A description of my model\n      columns:\n        - name: color\n          description: The color value\n          data_tests:\n            - not_null:\n                severity: WARNING\n            - accepted_values:\n                values: ['red', 'blue', 'green']\n            - foreign_package.test_case:\n                arg: 100\n\"\"\"\n\nSINGLE_TABLE_MODEL_FRESHNESS = \"\"\"\nmodels:\n    - name: my_model\n      description: A description of my model\n      config:\n        freshness:\n          build_after: {count: 1, period: day, updates_on: all}\n\"\"\"\n\nSINGLE_TABLE_MODEL_TOP_LEVEL_FRESHNESS = \"\"\"\nmodels:\n    - name: my_model\n      description: A description of my model\n      freshness:\n        build_after: {count: 1, period: day, updates_on: any}\n\"\"\"\n\nSINGLE_TABLE_MODEL_FRESHNESS_ONLY_DEPEND_ON = \"\"\"\nmodels:\n    - name: my_model\n      description: A description of my model\n      config:\n        freshness:\n          build_after:\n            updates_on: all\n            period: hour\n            count: 5\n\"\"\"\n\n\nMULTIPLE_TABLE_VERSIONED_MODEL_TESTS = \"\"\"\nmodels:\n    - name: my_model\n      description: A description of my model\n      data_tests:\n        - unique:\n            column_name: color\n      columns:\n        - name: color\n          description: The color value\n          data_tests:\n            - not_null:\n                severity: WARN\n        - name: location_id\n          data_type: int\n      versions:\n        - v: 1\n          defined_in: arbitrary_file_name\n          data_tests: []\n          columns:\n            - include: '*'\n            - name: extra\n        - v: 2\n          columns:\n            - include: '*'\n              exclude: ['location_id']\n            - name: extra\n\"\"\"\n\nMULTIPLE_TABLE_VERSIONED_MODEL = \"\"\"\nmodels:\n    - name: my_model\n      description: A description of my model\n      config:\n        materialized: table\n        sql_header: test_sql_header\n      columns:\n        - name: color\n          description: The color value\n        - name: location_id\n          data_type: int\n      versions:\n        - v: 1\n          defined_in: arbitrary_file_name\n          columns:\n            - include: '*'\n            - name: extra\n        - v: 2\n          config:\n            materialized: view\n          columns:\n            - include: '*'\n              exclude: ['location_id']\n            - name: extra\n\"\"\"\n\nMULTIPLE_TABLE_VERSIONED_MODEL_CONTRACT_ENFORCED = \"\"\"\nmodels:\n    - name: my_model\n      config:\n        contract:\n            enforced: true\n      versions:\n        - v: 0\n          defined_in: arbitrary_file_name\n        - v: 2\n\"\"\"\n\nMULTIPLE_TABLE_VERSIONED_MODEL_V0 = \"\"\"\nmodels:\n    - name: my_model\n      versions:\n        - v: 0\n          defined_in: arbitrary_file_name\n        - v: 2\n\"\"\"\n\n\nMULTIPLE_TABLE_VERSIONED_MODEL_V0_LATEST_VERSION = \"\"\"\nmodels:\n    - name: my_model\n      latest_version: 0\n      versions:\n        - v: 0\n          defined_in: arbitrary_file_name\n        - v: 2\n\"\"\"\n\n\nSINGLE_TABLE_SOURCE_PATCH = \"\"\"\nsources:\n  - name: my_source\n    overrides: snowplow\n    tables:\n      - name: my_table\n        columns:\n          - name: id\n            data_tests:\n              - not_null\n              - unique\n\"\"\"\n\nSOURCE_CUSTOM_FRESHNESS_AT_SOURCE = \"\"\"\nsources:\n  - name: my_source\n    loaded_at_query: \"select 1 as id\"\n    tables:\n      - name: my_table\n\"\"\"\nSOURCE_CUSTOM_FRESHNESS_AT_SOURCE_FIELD_AT_TABLE = \"\"\"\nsources:\n  - name: my_source\n    loaded_at_query: \"select 1 as id\"\n    tables:\n      - name: my_table\n        loaded_at_field: test\n\"\"\"\nSOURCE_FIELD_AT_SOURCE_CUSTOM_FRESHNESS_AT_TABLE = \"\"\"\nsources:\n  - name: my_source\n    loaded_at_field: test\n    tables:\n      - name: my_table\n        loaded_at_query: \"select 1 as id\"\n\"\"\"\n\nSOURCE_FRESHNESS_AT_TABLE_AND_CONFIG = \"\"\"\nsources:\n  - name: my_source\n    loaded_at_field: test\n    tables:\n      - name: my_table\n        freshness:\n            warn_after: {count: 1, period: hour}\n            error_after: {count: 1, period: day}\n        config:\n            freshness:\n                warn_after: {count: 2, period: hour}\n                error_after: {count: 2, period: day}\n\"\"\"\n\nSOURCE_FIELD_AT_CUSTOM_FRESHNESS_BOTH_AT_TABLE = \"\"\"\nsources:\n  - name: my_source\n    loaded_at_field: test\n    tables:\n      - name: my_table\n        loaded_at_query: \"select 1 as id\"\n        loaded_at_field: test\n\"\"\"\nSOURCE_FIELD_AT_CUSTOM_FRESHNESS_BOTH_AT_SOURCE = \"\"\"\nsources:\n  - name: my_source\n    loaded_at_field: test\n    loaded_at_query: \"select 1 as id\"\n    tables:\n      - name: my_table\n        loaded_at_field: test\n\"\"\"\nSOURCE_FRESHNESS_WITH_LOADED_AT_QUERY = \"\"\"\nsources:\n  - name: my_source\n    tables:\n      - name: my_table\n        config:\n            loaded_at_query: \"select 1 as id\"\n            freshness:\n                warn_after: {count: 1, period: hour}\n                error_after: {count: 1, period: day}\n\"\"\"\n\n\nclass SchemaParserTest(BaseParserTest):\n    def setUp(self):\n        super().setUp()\n        # Reset `warn_error` to False so we don't raise warnigns about top level freshness as errors\n        set_from_args(\n            Namespace(\n                warn_error=False,\n                state_modified_compare_more_unrendered_values=False,\n                require_generic_test_arguments_property=False,\n            ),\n            None,\n        )\n\n        self.parser = SchemaParser(\n            project=self.snowplow_project_config,\n            manifest=self.manifest,\n            root_project=self.root_project_config,\n        )\n        self.source_patcher = SourcePatcher(\n            root_project=self.root_project_config,\n            manifest=self.manifest,\n        )\n\n    def file_block_for(self, data, filename, searched=\"models\"):\n        return super().file_block_for(data, filename, searched)\n\n    def yaml_block_for(self, test_yml: str, filename: str):\n        file_block = self.file_block_for(data=test_yml, filename=filename)\n        return YamlBlock.from_file_block(\n            src=file_block,\n            data=yaml.safe_load(test_yml),\n        )\n\n\nclass SchemaParserSourceTest(SchemaParserTest):\n    def test__read_basic_source(self):\n        block = self.yaml_block_for(SINGLE_TABLE_SOURCE, \"test_one.yml\")\n        analysis_blocks = AnalysisPatchParser(self.parser, block, \"analyses\").parse().test_blocks\n        model_blocks = ModelPatchParser(self.parser, block, \"models\").parse().test_blocks\n        source_blocks = SourceParser(self.parser, block, \"sources\").parse().test_blocks\n        macro_blocks = MacroPatchParser(self.parser, block, \"macros\").parse().test_blocks\n        self.assertEqual(len(analysis_blocks), 0)\n        self.assertEqual(len(model_blocks), 0)\n        self.assertEqual(len(source_blocks), 0)\n        self.assertEqual(len(macro_blocks), 0)\n        self.assertEqual(len(list(self.parser.manifest.nodes)), 0)\n        source_values = list(self.parser.manifest.sources.values())\n        self.assertEqual(len(source_values), 1)\n        self.assertEqual(source_values[0].source.name, \"my_source\")\n        self.assertEqual(source_values[0].table.name, \"my_table\")\n        self.assertEqual(source_values[0].table.description, \"\")\n        self.assertEqual(len(source_values[0].table.columns), 0)\n\n    @mock.patch(\"dbt.parser.sources.get_adapter\")\n    def test_parse_source_custom_freshness_at_source(self, _):\n        block = self.file_block_for(SOURCE_CUSTOM_FRESHNESS_AT_SOURCE, \"test_one.yml\")\n        dct = yaml_from_file(block.file, validate=True)\n        self.parser.parse_file(block, dct)\n        unpatched_src_default = self.parser.manifest.sources[\"source.snowplow.my_source.my_table\"]\n        src_default = self.source_patcher.parse_source(unpatched_src_default)\n        assert src_default.loaded_at_query == \"select 1 as id\"\n\n    @mock.patch(\"dbt.parser.sources.get_adapter\")\n    def test_parse_source_custom_freshness_at_source_field_at_table(self, _):\n        block = self.file_block_for(\n            SOURCE_CUSTOM_FRESHNESS_AT_SOURCE_FIELD_AT_TABLE, \"test_one.yml\"\n        )\n        dct = yaml_from_file(block.file, validate=True)\n        self.parser.parse_file(block, dct)\n        unpatched_src_default = self.parser.manifest.sources[\"source.snowplow.my_source.my_table\"]\n        src_default = self.source_patcher.parse_source(unpatched_src_default)\n        # source loaded_at_query not propagate to table since there's loaded_at_field defined\n        assert src_default.loaded_at_query is None\n\n    @mock.patch(\"dbt.parser.sources.get_adapter\")\n    def test_parse_source_field_at_source_custom_freshness_at_table(self, _):\n        block = self.file_block_for(\n            SOURCE_FIELD_AT_SOURCE_CUSTOM_FRESHNESS_AT_TABLE, \"test_one.yml\"\n        )\n        dct = yaml_from_file(block.file, validate=True)\n        self.parser.parse_file(block, dct)\n        unpatched_src_default = self.parser.manifest.sources[\"source.snowplow.my_source.my_table\"]\n        src_default = self.source_patcher.parse_source(unpatched_src_default)\n        assert src_default.loaded_at_query == \"select 1 as id\"\n\n    @mock.patch(\"dbt.parser.sources.get_adapter\")\n    def test_parse_source_field_at_custom_freshness_both_at_table_fails(self, _):\n        block = self.file_block_for(SOURCE_FIELD_AT_CUSTOM_FRESHNESS_BOTH_AT_TABLE, \"test_one.yml\")\n        dct = yaml_from_file(block.file, validate=True)\n        self.parser.parse_file(block, dct)\n        unpatched_src_default = self.parser.manifest.sources[\"source.snowplow.my_source.my_table\"]\n        with self.assertRaises(ParsingError):\n            self.source_patcher.parse_source(unpatched_src_default)\n\n    @mock.patch(\"dbt.parser.sources.get_adapter\")\n    def test_parse_source_resulting_node_freshness_matches_config_freshness(self, _):\n        block = self.file_block_for(SOURCE_FRESHNESS_AT_TABLE_AND_CONFIG, \"test_one.yml\")\n        dct = yaml_from_file(block.file, validate=True)\n        self.parser.parse_file(block, dct)\n        unpatched_src_default = self.parser.manifest.sources[\"source.snowplow.my_source.my_table\"]\n        src_default = self.source_patcher.parse_source(unpatched_src_default)\n        assert src_default.freshness == src_default.config.freshness\n        assert src_default.freshness.warn_after.count == 2\n        assert src_default.freshness.warn_after.period == \"hour\"\n        assert src_default.freshness.error_after.count == 2\n        assert src_default.freshness.error_after.period == \"day\"\n\n    @mock.patch(\"dbt.parser.sources.get_adapter\")\n    def test_parse_source_field_at_custom_freshness_both_at_source_fails(self, _):\n        block = self.file_block_for(\n            SOURCE_FIELD_AT_CUSTOM_FRESHNESS_BOTH_AT_SOURCE, \"test_one.yml\"\n        )\n        dct = yaml_from_file(block.file, validate=True)\n        self.parser.parse_file(block, dct)\n        unpatched_src_default = self.parser.manifest.sources[\"source.snowplow.my_source.my_table\"]\n        with self.assertRaises(ParsingError):\n            self.source_patcher.parse_source(unpatched_src_default)\n\n    def test__parse_basic_source(self):\n        block = self.file_block_for(SINGLE_TABLE_SOURCE, \"test_one.yml\")\n        dct = yaml_from_file(block.file, validate=True)\n        self.parser.parse_file(block, dct)\n        self.assert_has_manifest_lengths(self.parser.manifest, sources=1)\n        src = list(self.parser.manifest.sources.values())[0]\n        assert isinstance(src, UnpatchedSourceDefinition)\n        assert src.package_name == \"snowplow\"\n        assert src.source.name == \"my_source\"\n        assert src.table.name == \"my_table\"\n        assert src.resource_type == NodeType.Source\n        assert src.fqn == [\"snowplow\", \"my_source\", \"my_table\"]\n\n    @mock.patch(\"dbt.parser.sources.get_adapter\")\n    def test__parse_basic_source_meta(self, mock_get_adapter):\n        block = self.file_block_for(MULTIPLE_TABLE_SOURCE_META, \"test_one.yml\")\n        dct = yaml_from_file(block.file, validate=True)\n        self.parser.parse_file(block, dct)\n        self.assert_has_manifest_lengths(self.parser.manifest, sources=2)\n\n        unpatched_src_default = self.parser.manifest.sources[\n            \"source.snowplow.my_source.my_table_shared_field_default\"\n        ]\n        src_default = self.source_patcher.parse_source(unpatched_src_default)\n        assert src_default.meta == {\n            \"source_field\": \"source_value\",\n            \"shared_field\": \"shared_field_default\",\n            \"table_field\": \"table_value\",\n        }\n        assert src_default.source_meta == {\n            \"source_field\": \"source_value\",\n            \"shared_field\": \"shared_field_default\",\n        }\n\n        unpatched_src_override = self.parser.manifest.sources[\n            \"source.snowplow.my_source.my_table_shared_field_override\"\n        ]\n        src_override = self.source_patcher.parse_source(unpatched_src_override)\n        assert src_override.meta == {\n            \"source_field\": \"source_value\",\n            \"shared_field\": \"shared_field_table_override\",\n            \"table_field\": \"table_value\",\n        }\n        assert src_override.source_meta == {\n            \"source_field\": \"source_value\",\n            \"shared_field\": \"shared_field_default\",\n        }\n\n    def test__read_basic_source_tests(self):\n        block = self.yaml_block_for(SINGLE_TABLE_SOURCE_TESTS, \"test_one.yml\")\n        analysis_tests = AnalysisPatchParser(self.parser, block, \"analyses\").parse().test_blocks\n        model_tests = ModelPatchParser(self.parser, block, \"models\").parse().test_blocks\n        source_tests = SourceParser(self.parser, block, \"sources\").parse().test_blocks\n        macro_tests = MacroPatchParser(self.parser, block, \"macros\").parse().test_blocks\n        self.assertEqual(len(analysis_tests), 0)\n        self.assertEqual(len(model_tests), 0)\n        self.assertEqual(len(source_tests), 0)\n        self.assertEqual(len(macro_tests), 0)\n        self.assertEqual(len(list(self.parser.manifest.nodes)), 0)\n        self.assertEqual(len(list(self.parser.manifest.source_patches)), 0)\n        source_values = list(self.parser.manifest.sources.values())\n        self.assertEqual(len(source_values), 1)\n        self.assertEqual(source_values[0].source.name, \"my_source\")\n        self.assertEqual(source_values[0].table.name, \"my_table\")\n        self.assertEqual(source_values[0].table.description, \"A description of my table\")\n        self.assertEqual(len(source_values[0].table.columns), 1)\n\n    def test__parse_basic_source_tests(self):\n        block = self.file_block_for(SINGLE_TABLE_SOURCE_TESTS, \"test_one.yml\")\n        self.parser.manifest.files[block.file.file_id] = block.file\n        dct = yaml_from_file(block.file, validate=True)\n        self.parser.parse_file(block, dct)\n        self.assertEqual(len(self.parser.manifest.nodes), 0)\n        self.assertEqual(len(self.parser.manifest.sources), 1)\n        src = list(self.parser.manifest.sources.values())[0]\n        self.assertEqual(src.source.name, \"my_source\")\n        self.assertEqual(src.source.schema, None)\n        self.assertEqual(src.table.name, \"my_table\")\n        self.assertEqual(src.table.description, \"A description of my table\")\n\n        tests = [\n            self.source_patcher.parse_source_test(src, test, col) for test, col in src.get_tests()\n        ]\n        tests.sort(key=lambda n: n.unique_id)\n\n        self.assertEqual(tests[0].config.severity, \"ERROR\")\n        self.assertEqual(tests[0].tags, [])\n        self.assertEqual(tests[0].sources, [[\"my_source\", \"my_table\"]])\n        self.assertEqual(tests[0].column_name, \"color\")\n        self.assertEqual(tests[0].fqn, [\"snowplow\", tests[0].name])\n        self.assertEqual(tests[1].config.severity, \"WARN\")\n        self.assertEqual(tests[1].tags, [])\n        self.assertEqual(tests[1].sources, [[\"my_source\", \"my_table\"]])\n        self.assertEqual(tests[1].column_name, \"color\")\n        self.assertEqual(tests[1].fqn, [\"snowplow\", tests[1].name])\n\n        file_id = \"snowplow://\" + normalize(\"models/test_one.yml\")\n        self.assertIn(file_id, self.parser.manifest.files)\n        self.assertEqual(self.parser.manifest.files[file_id].data_tests, {})\n        self.assertEqual(\n            self.parser.manifest.files[file_id].sources, [\"source.snowplow.my_source.my_table\"]\n        )\n        self.assertEqual(self.parser.manifest.files[file_id].source_patches, [])\n\n    def test__read_source_patch(self):\n\n        # TODO: There needs to be a better way to disable warnings being fired\n        # during unit tests, but all we have today is this global variable.\n        dbt_common.events.functions.WARN_ERROR = False\n\n        block = self.yaml_block_for(SINGLE_TABLE_SOURCE_PATCH, \"test_one.yml\")\n        analysis_tests = AnalysisPatchParser(self.parser, block, \"analyses\").parse().test_blocks\n        model_tests = TestablePatchParser(self.parser, block, \"models\").parse().test_blocks\n        source_tests = SourceParser(self.parser, block, \"sources\").parse().test_blocks\n        macro_tests = MacroPatchParser(self.parser, block, \"macros\").parse().test_blocks\n        self.assertEqual(len(analysis_tests), 0)\n        self.assertEqual(len(model_tests), 0)\n        self.assertEqual(len(source_tests), 0)\n        self.assertEqual(len(macro_tests), 0)\n        self.assertEqual(len(list(self.parser.manifest.nodes)), 0)\n        self.assertEqual(len(list(self.parser.manifest.sources)), 0)\n        source_patches = list(self.parser.manifest.source_patches.values())\n        self.assertEqual(len(source_patches), 1)\n        self.assertEqual(source_patches[0].name, \"my_source\")\n        self.assertEqual(source_patches[0].overrides, \"snowplow\")\n        self.assertIsNone(source_patches[0].description)\n        self.assertEqual(len(source_patches[0].tables), 1)\n        table = source_patches[0].tables[0]\n        self.assertEqual(table.name, \"my_table\")\n        self.assertIsNone(table.description)\n        self.assertEqual(len(table.columns), 1)\n        self.assertEqual(len(table.columns[0].data_tests), 2)\n\n    @mock.patch(\n        \"dbt.parser.sources.get_adapter\",\n        return_value=mock.MagicMock(supports=mock.MagicMock(return_value=False)),\n    )\n    def test__loaded_at_query_does_not_fire_config_problem_event(self, _):\n        \"\"\"Test where we have a loaded_at_query defined but no loaded_at_field and the adapter does not support metadata-based freshness.\n        We should not fire a config problem event.\n        \"\"\"\n        catcher = EventCatcher(FreshnessConfigProblem)\n        add_callback_to_manager(catcher.catch)\n\n        block = self.file_block_for(SOURCE_FRESHNESS_WITH_LOADED_AT_QUERY, \"test_one.yml\")\n        dct = yaml_from_file(block.file, validate=True)\n        self.parser.parse_file(block, dct)\n        unpatched_src_default = self.parser.manifest.sources[\"source.snowplow.my_source.my_table\"]\n        self.source_patcher.parse_source(unpatched_src_default)\n\n        assert len(catcher.caught_events) == 0\n\n\nclass SchemaParserModelsTest(SchemaParserTest):\n    def setUp(self):\n        super().setUp()\n        my_model_node = MockNode(\n            package=\"root\",\n            name=\"my_model\",\n            config=ModelConfig(enabled=True),\n            refs=[],\n            sources=[],\n            patch_path=None,\n        )\n        source_file = self.source_file_for(\"\", \"my_model.sql\", \"models\")\n        nodes = {my_model_node.unique_id: my_model_node}\n        macros = {m.unique_id: m for m in generate_name_macros(\"root\")}\n        self.manifest = Manifest(nodes=nodes, macros=macros)\n        self.manifest.files[source_file.file_id] = source_file\n        self.manifest.ref_lookup\n        self.parser = SchemaParser(\n            project=self.snowplow_project_config,\n            manifest=self.manifest,\n            root_project=self.root_project_config,\n        )\n\n    def test__read_basic_model_tests(self):\n        block = self.yaml_block_for(SINGLE_TABLE_MODEL_TESTS, \"test_one.yml\")\n        dct = yaml_from_file(block.file, validate=True)\n        self.parser.parse_file(block, dct)\n        self.assertEqual(len(list(self.parser.manifest.sources)), 0)\n        self.assertEqual(len(list(self.parser.manifest.nodes)), 4)\n\n    def test__parse_model_freshness(self):\n        block = self.file_block_for(SINGLE_TABLE_MODEL_FRESHNESS, \"test_one.yml\")\n        self.parser.manifest.files[block.file.file_id] = block.file\n        dct = yaml_from_file(block.file, validate=True)\n        self.parser.parse_file(block, dct)\n        self.assert_has_manifest_lengths(self.parser.manifest, nodes=1)\n\n        assert self.parser.manifest.nodes[\n            \"model.root.my_model\"\n        ].config.freshness.build_after == ModelBuildAfter(\n            count=1, period=\"day\", updates_on=ModelFreshnessUpdatesOnOptions.all\n        )\n\n    def test__parse_model_ignores_top_level_freshness(self):\n        block = self.file_block_for(SINGLE_TABLE_MODEL_TOP_LEVEL_FRESHNESS, \"test_one.yml\")\n        self.parser.manifest.files[block.file.file_id] = block.file\n        dct = yaml_from_file(block.file, validate=True)\n        self.parser.parse_file(block, dct)\n        self.assert_has_manifest_lengths(self.parser.manifest, nodes=1)\n\n        # we can't use hasattr because the model node is a mock, and checking with hasattr will add it to the mock\n        assert \"freshness\" not in self.parser.manifest.nodes[\"model.root.my_model\"].__dir__()\n\n        # should be None because nothing set it\n        assert self.parser.manifest.nodes[\"model.root.my_model\"].config.freshness is None\n\n    def test__parse_model_freshness_depend_on(self):\n        block = self.file_block_for(SINGLE_TABLE_MODEL_FRESHNESS_ONLY_DEPEND_ON, \"test_one.yml\")\n        self.parser.manifest.files[block.file.file_id] = block.file\n        dct = yaml_from_file(block.file, validate=True)\n        self.parser.parse_file(block, dct)\n        self.assert_has_manifest_lengths(self.parser.manifest, nodes=1)\n        assert self.parser.manifest.nodes[\n            \"model.root.my_model\"\n        ].config.freshness.build_after == ModelBuildAfter(\n            count=5, period=\"hour\", updates_on=ModelFreshnessUpdatesOnOptions.all\n        )\n\n    def test__read_basic_model_tests_wrong_severity(self):\n        block = self.yaml_block_for(SINGLE_TABLE_MODEL_TESTS_WRONG_SEVERITY, \"test_one.yml\")\n        dct = yaml_from_file(block.file, validate=True)\n        with self.assertRaisesRegex(\n            SchemaConfigError, \"Severity must be either 'warn' or 'error'. Got 'WARNING'\"\n        ):\n            self.parser.parse_file(block, dct)\n\n    def test__parse_basic_model_tests(self):\n        block = self.file_block_for(SINGLE_TABLE_MODEL_TESTS, \"test_one.yml\")\n        self.parser.manifest.files[block.file.file_id] = block.file\n        dct = yaml_from_file(block.file, validate=True)\n        self.parser.parse_file(block, dct)\n        self.assert_has_manifest_lengths(self.parser.manifest, nodes=4)\n\n        all_nodes = sorted(self.parser.manifest.nodes.values(), key=lambda n: n.unique_id)\n        tests = []\n        for node in all_nodes:\n            if node.resource_type != NodeType.Test:\n                continue\n            tests.append(node)\n        self.assertEqual(tests[0].config.severity, \"ERROR\")\n        self.assertEqual(tests[0].tags, [])\n        self.assertEqual(tests[0].refs, [RefArgs(name=\"my_model\")])\n        self.assertEqual(tests[0].column_name, \"color\")\n        self.assertEqual(tests[0].description, \"Only primary colors are allowed in here\")\n        self.assertEqual(tests[0].package_name, \"snowplow\")\n        self.assertTrue(tests[0].name.startswith(\"accepted_values_\"))\n        self.assertEqual(tests[0].fqn, [\"snowplow\", tests[0].name])\n        self.assertEqual(\n            tests[0].unique_id.split(\".\"), [\"test\", \"snowplow\", tests[0].name, \"9d4814efde\"]\n        )\n        self.assertEqual(tests[0].test_metadata.name, \"accepted_values\")\n        self.assertIsNone(tests[0].test_metadata.namespace)\n        self.assertEqual(\n            tests[0].test_metadata.kwargs,\n            {\n                \"column_name\": \"color\",\n                \"model\": \"{{ get_where_subquery(ref('my_model')) }}\",\n                \"values\": [\"red\", \"blue\", \"green\"],\n            },\n        )\n\n        # foreign packages are a bit weird, they include the macro package\n        # name in the test name\n        self.assertEqual(tests[1].config.severity, \"ERROR\")\n        self.assertEqual(tests[1].tags, [])\n        self.assertEqual(tests[1].refs, [RefArgs(name=\"my_model\")])\n        self.assertEqual(tests[1].column_name, \"color\")\n        self.assertEqual(tests[1].description, \"\")\n        self.assertEqual(tests[1].fqn, [\"snowplow\", tests[1].name])\n        self.assertTrue(tests[1].name.startswith(\"foreign_package_test_case_\"))\n        self.assertEqual(tests[1].package_name, \"snowplow\")\n        self.assertEqual(\n            tests[1].unique_id.split(\".\"), [\"test\", \"snowplow\", tests[1].name, \"13958f62f7\"]\n        )\n        self.assertEqual(tests[1].test_metadata.name, \"test_case\")\n        self.assertEqual(tests[1].test_metadata.namespace, \"foreign_package\")\n        self.assertEqual(\n            tests[1].test_metadata.kwargs,\n            {\n                \"column_name\": \"color\",\n                \"model\": \"{{ get_where_subquery(ref('my_model')) }}\",\n                \"arg\": 100,\n            },\n        )\n\n        self.assertEqual(tests[2].config.severity, \"WARN\")\n        self.assertEqual(tests[2].tags, [])\n        self.assertEqual(tests[2].refs, [RefArgs(name=\"my_model\")])\n        self.assertEqual(tests[2].column_name, \"color\")\n        self.assertEqual(tests[2].package_name, \"snowplow\")\n        self.assertTrue(tests[2].name.startswith(\"not_null_\"))\n        self.assertEqual(tests[2].fqn, [\"snowplow\", tests[2].name])\n        self.assertEqual(\n            tests[2].unique_id.split(\".\"), [\"test\", \"snowplow\", tests[2].name, \"2f61818750\"]\n        )\n        self.assertEqual(tests[2].test_metadata.name, \"not_null\")\n        self.assertIsNone(tests[2].test_metadata.namespace)\n        self.assertEqual(\n            tests[2].test_metadata.kwargs,\n            {\n                \"column_name\": \"color\",\n                \"model\": \"{{ get_where_subquery(ref('my_model')) }}\",\n            },\n        )\n\n        file_id = \"snowplow://\" + normalize(\"models/test_one.yml\")\n        self.assertIn(file_id, self.parser.manifest.files)\n        schema_file_test_ids = self.parser.manifest.files[file_id].get_all_test_ids()\n        self.assertEqual(sorted(schema_file_test_ids), [t.unique_id for t in tests])\n        self.assertEqual(self.parser.manifest.files[file_id].node_patches, [\"model.root.my_model\"])\n\n\nclass SchemaParserVersionedModels(SchemaParserTest):\n    def setUp(self):\n        super().setUp()\n        my_model_v1_node = MockNode(\n            package=\"snowplow\",\n            name=\"arbitrary_file_name\",\n            config=mock.MagicMock(enabled=True),\n            refs=[],\n            sources=[],\n            patch_path=None,\n            file_id=\"snowplow://models/arbitrary_file_name.sql\",\n        )\n        my_model_v1_source_file = self.source_file_for(\"\", \"arbitrary_file_name.sql\", \"models\")\n        my_model_v2_node = MockNode(\n            package=\"snowplow\",\n            name=\"my_model_v2\",\n            config=mock.MagicMock(enabled=True),\n            refs=[],\n            sources=[],\n            patch_path=None,\n            file_id=\"snowplow://models/my_model_v2.sql\",\n        )\n        my_model_v2_source_file = self.source_file_for(\"\", \"my_model_v2.sql\", \"models\")\n        nodes = {\n            my_model_v1_node.unique_id: my_model_v1_node,\n            my_model_v2_node.unique_id: my_model_v2_node,\n        }\n        macros = {m.unique_id: m for m in generate_name_macros(\"root\")}\n        files = {\n            my_model_v1_source_file.file_id: my_model_v1_source_file,\n            my_model_v2_source_file.file_id: my_model_v2_source_file,\n        }\n        self.manifest = Manifest(nodes=nodes, macros=macros, files=files)\n        self.manifest.ref_lookup\n        self.parser = SchemaParser(\n            project=self.snowplow_project_config,\n            manifest=self.manifest,\n            root_project=self.root_project_config,\n        )\n\n    def test__read_versioned_model_tests(self):\n        block = self.yaml_block_for(MULTIPLE_TABLE_VERSIONED_MODEL_TESTS, \"test_one.yml\")\n        dct = yaml_from_file(block.file, validate=True)\n        self.parser.parse_file(block, dct)\n        self.assertEqual(len(list(self.parser.manifest.sources)), 0)\n        self.assertEqual(len(list(self.parser.manifest.nodes)), 5)\n\n    def test__parse_versioned_model_tests(self):\n        block = self.file_block_for(MULTIPLE_TABLE_VERSIONED_MODEL_TESTS, \"test_one.yml\")\n        self.parser.manifest.files[block.file.file_id] = block.file\n        dct = yaml_from_file(block.file, validate=True)\n        self.parser.parse_file(block, dct)\n        self.assert_has_manifest_lengths(self.parser.manifest, nodes=5)\n\n        all_nodes = sorted(self.parser.manifest.nodes.values(), key=lambda n: n.unique_id)\n        tests = [node for node in all_nodes if node.resource_type == NodeType.Test]\n\n        # test on color column on my_model v1\n        self.assertEqual(tests[0].config.severity, \"WARN\")\n        self.assertEqual(tests[0].tags, [])\n        self.assertEqual(tests[0].refs, [RefArgs(name=\"my_model\", version=\"1\")])\n        self.assertEqual(tests[0].column_name, \"color\")\n        self.assertEqual(tests[0].package_name, \"snowplow\")\n        self.assertTrue(tests[0].name.startswith(\"not_null\"))\n        self.assertEqual(tests[0].fqn, [\"snowplow\", tests[0].name])\n        self.assertEqual(\n            tests[0].unique_id.split(\".\"), [\"test\", \"snowplow\", tests[0].name, \"b704420587\"]\n        )\n        self.assertEqual(tests[0].test_metadata.name, \"not_null\")\n        self.assertIsNone(tests[0].test_metadata.namespace)\n        self.assertEqual(\n            tests[0].test_metadata.kwargs,\n            {\n                \"column_name\": \"color\",\n                \"model\": \"{{ get_where_subquery(ref('my_model', version='1')) }}\",\n            },\n        )\n\n        # test on color column on my_model v2\n        self.assertEqual(tests[1].config.severity, \"WARN\")\n        self.assertEqual(tests[1].tags, [])\n        self.assertEqual(tests[1].refs, [RefArgs(name=\"my_model\", version=\"2\")])\n        self.assertEqual(tests[1].column_name, \"color\")\n        self.assertEqual(tests[1].fqn, [\"snowplow\", tests[1].name])\n        self.assertTrue(tests[1].name.startswith(\"not_null\"))\n        self.assertEqual(tests[1].package_name, \"snowplow\")\n        self.assertEqual(\n            tests[1].unique_id.split(\".\"), [\"test\", \"snowplow\", tests[1].name, \"3375708d04\"]\n        )\n        self.assertEqual(tests[1].test_metadata.name, \"not_null\")\n        self.assertIsNone(tests[0].test_metadata.namespace)\n        self.assertEqual(\n            tests[1].test_metadata.kwargs,\n            {\n                \"column_name\": \"color\",\n                \"model\": \"{{ get_where_subquery(ref('my_model', version='2')) }}\",\n            },\n        )\n\n        # model uniqueness test on column on my_model v2\n        self.assertEqual(tests[2].config.severity, \"ERROR\")\n        self.assertEqual(tests[2].tags, [])\n        self.assertEqual(tests[2].refs, [RefArgs(name=\"my_model\", version=\"2\")])\n        self.assertIsNone(tests[2].column_name)\n        self.assertEqual(tests[2].package_name, \"snowplow\")\n        self.assertTrue(tests[2].name.startswith(\"unique\"))\n        self.assertEqual(tests[2].fqn, [\"snowplow\", tests[2].name])\n        self.assertEqual(\n            tests[2].unique_id.split(\".\"), [\"test\", \"snowplow\", tests[2].name, \"29b09359d1\"]\n        )\n        self.assertEqual(tests[2].test_metadata.name, \"unique\")\n        self.assertIsNone(tests[2].test_metadata.namespace)\n        self.assertEqual(\n            tests[2].test_metadata.kwargs,\n            {\n                \"column_name\": \"color\",\n                \"model\": \"{{ get_where_subquery(ref('my_model', version='2')) }}\",\n            },\n        )\n\n        file_id = \"snowplow://\" + normalize(\"models/test_one.yml\")\n        self.assertIn(file_id, self.parser.manifest.files)\n        schema_file_test_ids = self.parser.manifest.files[file_id].get_all_test_ids()\n        self.assertEqual(sorted(schema_file_test_ids), [t.unique_id for t in tests])\n        self.assertEqual(\n            self.parser.manifest.files[file_id].node_patches,\n            [\"model.snowplow.my_model.v1\", \"model.snowplow.my_model.v2\"],\n        )\n\n    def test__parsed_versioned_models(self):\n        block = self.file_block_for(MULTIPLE_TABLE_VERSIONED_MODEL, \"test_one.yml\")\n        self.parser.manifest.files[block.file.file_id] = block.file\n        dct = yaml_from_file(block.file, validate=True)\n        self.parser.parse_file(block, dct)\n        self.assert_has_manifest_lengths(self.parser.manifest, nodes=2)\n\n    def test__parsed_versioned_models_contract_enforced(self):\n        block = self.file_block_for(\n            MULTIPLE_TABLE_VERSIONED_MODEL_CONTRACT_ENFORCED, \"test_one.yml\"\n        )\n        self.parser.manifest.files[block.file.file_id] = block.file\n        dct = yaml_from_file(block.file, validate=True)\n        self.parser.parse_file(block, dct)\n        self.assert_has_manifest_lengths(self.parser.manifest, nodes=2)\n        for node in self.parser.manifest.nodes.values():\n            assert node.contract.enforced\n            node.build_contract_checksum.assert_called()\n\n    def test__parsed_versioned_models_v0(self):\n        block = self.file_block_for(MULTIPLE_TABLE_VERSIONED_MODEL_V0, \"test_one.yml\")\n        self.parser.manifest.files[block.file.file_id] = block.file\n        dct = yaml_from_file(block.file, validate=True)\n        self.parser.parse_file(block, dct)\n        self.assert_has_manifest_lengths(self.parser.manifest, nodes=2)\n\n    def test__parsed_versioned_models_v0_latest_version(self):\n        block = self.file_block_for(\n            MULTIPLE_TABLE_VERSIONED_MODEL_V0_LATEST_VERSION, \"test_one.yml\"\n        )\n        self.parser.manifest.files[block.file.file_id] = block.file\n        dct = yaml_from_file(block.file, validate=True)\n        self.parser.parse_file(block, dct)\n        self.assert_has_manifest_lengths(self.parser.manifest, nodes=2)\n\n\nsql_model = \"\"\"\n{{ config(materialized=\"table\") }}\nselect 1 as id\n\"\"\"\n\nsql_model_parse_error = \"{{ SYNTAX ERROR }}\"\n\npython_model = \"\"\"\nimport textblob\nimport text as a\nfrom torch import b\nimport textblob.text\nimport sklearn\n\ndef model(dbt, session):\n    dbt.config(\n        materialized='table',\n        packages=['sklearn==0.1.0']\n    )\n    df0 = dbt.ref(\"a_model\").to_pandas()\n    df1 = dbt.ref(\"my_sql_model\").task.limit(2)\n    df2 = dbt.ref(\"my_sql_model_1\")\n    df3 = dbt.ref(\"my_sql_model_2\")\n    df4 = dbt.source(\"test\", 'table1').limit(max=[max(dbt.ref('something'))])\n    df5 = [dbt.ref('test1')]\n\n    a_dict = {'test2': dbt.ref('test2')}\n    df5 = {'test2': dbt.ref('test3')}\n    df6 = [dbt.ref(\"test4\")]\n    f\"{dbt.ref('test5')}\"\n\n    df = df0.limit(2)\n    return df\n\"\"\"\n\npython_model_config = \"\"\"\ndef model(dbt, session):\n    dbt.config.get(\"param_1\")\n    dbt.config.get(\"param_2\")\n    return dbt.ref(\"some_model\")\n\"\"\"\n\npython_model_config_with_defaults = \"\"\"\ndef model(dbt, session):\n    dbt.config.get(\"param_None\", None)\n    dbt.config.get(\"param_Str\", \"default\")\n    dbt.config.get(\"param_List\", [1, 2])\n    return dbt.ref(\"some_model\")\n\"\"\"\n\npython_model_single_argument = \"\"\"\ndef model(dbt):\n     dbt.config(materialized=\"table\")\n     return dbt.ref(\"some_model\")\n\"\"\"\n\npython_model_no_argument = \"\"\"\nimport pandas as pd\n\ndef model():\n    return pd.dataframe([1, 2])\n\"\"\"\n\npython_model_incorrect_argument_name = \"\"\"\ndef model(tbd, session):\n    tbd.config(materialized=\"table\")\n    return tbd.ref(\"some_model\")\n\"\"\"\n\npython_model_multiple_models = \"\"\"\ndef model(dbt, session):\n    dbt.config(materialized='table')\n    return dbt.ref(\"some_model\")\n\ndef model(dbt, session):\n    dbt.config(materialized='table')\n    return dbt.ref(\"some_model\")\n\"\"\"\n\npython_model_incorrect_function_name = \"\"\"\ndef model1(dbt, session):\n    dbt.config(materialized='table')\n    return dbt.ref(\"some_model\")\n\"\"\"\n\npython_model_empty_file = \"\"\"    \"\"\"\n\npython_model_multiple_returns = \"\"\"\ndef model(dbt, session):\n    dbt.config(materialized='table')\n    return dbt.ref(\"some_model\"), dbt.ref(\"some_other_model\")\n\"\"\"\n\npython_model_f_string = \"\"\"\n# my_python_model.py\nimport pandas as pd\n\ndef model(dbt, fal):\n    dbt.config(materialized=\"table\")\n    print(f\"my var: {dbt.config.get('my_var')}\") # Prints \"my var: None\"\n    df: pd.DataFrame = dbt.ref(\"some_model\")\n    return df\n\"\"\"\n\npython_model_no_return = \"\"\"\ndef model(dbt, session):\n    dbt.config(materialized='table')\n\"\"\"\n\npython_model_single_return = \"\"\"\nimport pandas as pd\n\ndef model(dbt, session):\n    dbt.config(materialized='table')\n    return pd.dataframe([1, 2])\n\"\"\"\n\npython_model_incorrect_ref = \"\"\"\ndef model(dbt, session):\n    model_names = [\"orders\", \"customers\"]\n    models = []\n\n    for model_name in model_names:\n        models.extend(dbt.ref(model_name))\n\n    return models[0]\n\"\"\"\n\npython_model_default_materialization = \"\"\"\nimport pandas as pd\n\ndef model(dbt, session):\n    return pd.dataframe([1, 2])\n\"\"\"\n\npython_model_custom_materialization = \"\"\"\nimport pandas as pd\n\ndef model(dbt, session):\n    dbt.config(materialized=\"incremental\")\n    return pd.dataframe([1, 2])\n\"\"\"\n\npython_model_meta_get = \"\"\"\ndef model(dbt, session):\n    dbt.config(\n        materialized='table',\n        meta={'owner': 'data-team', 'priority': 'high'}\n    )\n    owner = dbt.config.meta_get('owner')\n    priority = dbt.config.meta_get('priority')\n    return dbt.ref(\"some_model\")\n\"\"\"\n\npython_model_meta_get_with_defaults = \"\"\"\ndef model(dbt, session):\n    dbt.config(\n        materialized='table',\n        meta={'owner': 'data-team'}\n    )\n    owner = dbt.config.meta_get('owner', 'default-owner')\n    priority = dbt.config.meta_get('priority', 'low')\n    env = dbt.config.meta_get('environment', 'dev')\n    return dbt.ref(\"some_model\")\n\"\"\"\n\npython_model_mixed_config_and_meta_get = \"\"\"\ndef model(dbt, session):\n    dbt.config(\n        materialized='table',\n        meta={'owner': 'data-team', 'priority': 'high'}\n    )\n    # Regular config access\n    mat = dbt.config.get('materialized')\n    # Meta access\n    owner = dbt.config.meta_get('owner')\n    priority = dbt.config.meta_get('priority', 'low')\n    return dbt.ref(\"some_model\")\n\"\"\"\n\npython_model_meta_get_no_args = \"\"\"\ndef model(dbt, session):\n    dbt.config(materialized='table')\n    value = dbt.config.meta_get()\n    return dbt.ref(\"some_model\")\n\"\"\"\n\npython_model_meta_get_too_many_args = \"\"\"\ndef model(dbt, session):\n    dbt.config(materialized='table')\n    value = dbt.config.meta_get('key', 'default', 'extra')\n    return dbt.ref(\"some_model\")\n\"\"\"\n\n\nclass ModelParserTest(BaseParserTest):\n    def setUp(self):\n        super().setUp()\n        set_from_args(\n            Namespace(\n                warn_error=False,\n                state_modified_compare_more_unrendered_values=False,\n                require_generic_test_arguments_property=False,\n            ),\n            None,\n        )\n\n        self.parser = ModelParser(\n            project=self.snowplow_project_config,\n            manifest=self.manifest,\n            root_project=self.root_project_config,\n        )\n\n    def file_block_for(self, data, filename):\n        return super().file_block_for(data, filename, \"models\")\n\n    def test_basic(self):\n        block = self.file_block_for(sql_model, \"nested/model_1.sql\")\n        self.parser.manifest.files[block.file.file_id] = block.file\n        self.parser.parse_file(block)\n        self.assert_has_manifest_lengths(self.parser.manifest, nodes=1)\n        node = list(self.parser.manifest.nodes.values())[0]\n        expected = ModelNode(\n            alias=\"model_1\",\n            name=\"model_1\",\n            database=\"test\",\n            schema=\"analytics\",\n            resource_type=NodeType.Model,\n            unique_id=\"model.snowplow.model_1\",\n            fqn=[\"snowplow\", \"nested\", \"model_1\"],\n            package_name=\"snowplow\",\n            original_file_path=normalize(\"models/nested/model_1.sql\"),\n            config=ModelConfig(materialized=\"table\"),\n            path=normalize(\"nested/model_1.sql\"),\n            language=\"sql\",\n            raw_code=sql_model,\n            checksum=block.file.checksum,\n            unrendered_config={\"materialized\": \"table\"},\n            config_call_dict={\n                \"materialized\": \"table\",\n            },\n        )\n        assertEqualNodes(node, expected)\n        file_id = \"snowplow://\" + normalize(\"models/nested/model_1.sql\")\n        self.assertIn(file_id, self.parser.manifest.files)\n        self.assertEqual(self.parser.manifest.files[file_id].nodes, [\"model.snowplow.model_1\"])\n\n    def test_sql_model_parse_error(self):\n        block = self.file_block_for(sql_model_parse_error, \"nested/model_1.sql\")\n        with self.assertRaises(CompilationError):\n            self.parser.parse_file(block)\n\n    def test_python_model_parse(self):\n        block = self.file_block_for(python_model, \"nested/py_model.py\")\n        self.parser.manifest.files[block.file.file_id] = block.file\n        self.parser.parse_file(block)\n        self.assert_has_manifest_lengths(self.parser.manifest, nodes=1)\n        node = list(self.parser.manifest.nodes.values())[0]\n        # we decided to not detect and auto supply for now since import name doesn't always match library name\n        python_packages = [\"sklearn==0.1.0\"]\n        expected = ModelNode(\n            alias=\"py_model\",\n            name=\"py_model\",\n            database=\"test\",\n            schema=\"analytics\",\n            resource_type=NodeType.Model,\n            unique_id=\"model.snowplow.py_model\",\n            fqn=[\"snowplow\", \"nested\", \"py_model\"],\n            package_name=\"snowplow\",\n            original_file_path=normalize(\"models/nested/py_model.py\"),\n            config=ModelConfig(materialized=\"table\", packages=python_packages),\n            # config.packages = ['textblob']\n            path=normalize(\"nested/py_model.py\"),\n            language=\"python\",\n            raw_code=python_model,\n            checksum=block.file.checksum,\n            unrendered_config={\"materialized\": \"table\", \"packages\": python_packages},\n            config_call_dict={\"materialized\": \"table\", \"packages\": python_packages},\n            refs=[\n                RefArgs(name=\"a_model\"),\n                RefArgs(\"my_sql_model\"),\n                RefArgs(\"my_sql_model_1\"),\n                RefArgs(\"my_sql_model_2\"),\n                RefArgs(\"something\"),\n                RefArgs(\"test1\"),\n                RefArgs(\"test2\"),\n                RefArgs(\"test3\"),\n                RefArgs(\"test4\"),\n                RefArgs(\"test5\"),\n            ],\n            sources=[[\"test\", \"table1\"]],\n        )\n        assertEqualNodes(node, expected)\n        file_id = \"snowplow://\" + normalize(\"models/nested/py_model.py\")\n        self.assertIn(file_id, self.parser.manifest.files)\n        self.assertEqual(self.parser.manifest.files[file_id].nodes, [\"model.snowplow.py_model\"])\n\n    def test_python_model_config(self):\n        block = self.file_block_for(python_model_config, \"nested/py_model.py\")\n        self.parser.manifest.files[block.file.file_id] = block.file\n\n        self.parser.parse_file(block)\n        node = list(self.parser.manifest.nodes.values())[0]\n        self.assertEqual(node.config.to_dict()[\"config_keys_used\"], [\"param_1\", \"param_2\"])\n\n    def test_python_model_f_string_config(self):\n        block = self.file_block_for(python_model_f_string, \"nested/py_model.py\")\n        self.parser.manifest.files[block.file.file_id] = block.file\n\n        self.parser.parse_file(block)\n        node = list(self.parser.manifest.nodes.values())[0]\n        self.assertEqual(node.config.to_dict()[\"config_keys_used\"], [\"my_var\"])\n\n    def test_python_model_config_with_defaults(self):\n        block = self.file_block_for(python_model_config_with_defaults, \"nested/py_model.py\")\n        self.parser.manifest.files[block.file.file_id] = block.file\n\n        self.parser.parse_file(block)\n        node = list(self.parser.manifest.nodes.values())[0]\n        default_values = node.config.to_dict()[\"config_keys_defaults\"]\n        self.assertIsNone(default_values[0])\n        self.assertEqual(default_values[1], \"default\")\n        self.assertEqual(default_values[2], [1, 2])\n\n    def test_python_model_single_argument(self):\n        block = self.file_block_for(python_model_single_argument, \"nested/py_model.py\")\n        self.parser.manifest.files[block.file.file_id] = block.file\n        with self.assertRaises(ParsingError):\n            self.parser.parse_file(block)\n\n    def test_python_model_no_argument(self):\n        block = self.file_block_for(python_model_no_argument, \"nested/py_model.py\")\n        self.parser.manifest.files[block.file.file_id] = block.file\n        with self.assertRaises(ParsingError):\n            self.parser.parse_file(block)\n\n    def test_python_model_incorrect_argument_name(self):\n        block = self.file_block_for(python_model_incorrect_argument_name, \"nested/py_model.py\")\n        self.parser.manifest.files[block.file.file_id] = block.file\n        with self.assertRaises(ParsingError):\n            self.parser.parse_file(block)\n\n    def test_python_model_multiple_models(self):\n        block = self.file_block_for(python_model_multiple_models, \"nested/py_model.py\")\n        self.parser.manifest.files[block.file.file_id] = block.file\n        with self.assertRaises(ParsingError):\n            self.parser.parse_file(block)\n\n    def test_python_model_incorrect_function_name(self):\n        block = self.file_block_for(python_model_incorrect_function_name, \"nested/py_model.py\")\n        self.parser.manifest.files[block.file.file_id] = block.file\n        with self.assertRaises(ParsingError):\n            self.parser.parse_file(block)\n\n    def test_python_model_empty_file(self):\n        block = self.file_block_for(python_model_empty_file, \"nested/py_model.py\")\n        self.parser.manifest.files[block.file.file_id] = block.file\n        self.assertIsNone(self.parser.parse_file(block))\n\n    def test_python_model_multiple_returns(self):\n        block = self.file_block_for(python_model_multiple_returns, \"nested/py_model.py\")\n        self.parser.manifest.files[block.file.file_id] = block.file\n        with self.assertRaises(ParsingError):\n            self.parser.parse_file(block)\n\n    def test_python_model_no_return(self):\n        block = self.file_block_for(python_model_no_return, \"nested/py_model.py\")\n        self.parser.manifest.files[block.file.file_id] = block.file\n        with self.assertRaises(ParsingError):\n            self.parser.parse_file(block)\n\n    def test_python_model_single_return(self):\n        block = self.file_block_for(python_model_single_return, \"nested/py_model.py\")\n        self.parser.manifest.files[block.file.file_id] = block.file\n        self.assertIsNone(self.parser.parse_file(block))\n\n    def test_python_model_incorrect_ref(self):\n        block = self.file_block_for(python_model_incorrect_ref, \"nested/py_model.py\")\n        self.parser.manifest.files[block.file.file_id] = block.file\n        with self.assertRaises(ParsingError):\n            self.parser.parse_file(block)\n\n    def test_python_model_default_materialization(self):\n        block = self.file_block_for(python_model_default_materialization, \"nested/py_model.py\")\n        self.parser.manifest.files[block.file.file_id] = block.file\n        self.parser.parse_file(block)\n        node = list(self.parser.manifest.nodes.values())[0]\n        self.assertEqual(node.get_materialization(), \"table\")\n\n    def test_python_model_custom_materialization(self):\n        block = self.file_block_for(python_model_custom_materialization, \"nested/py_model.py\")\n        self.parser.manifest.files[block.file.file_id] = block.file\n        self.parser.parse_file(block)\n        node = list(self.parser.manifest.nodes.values())[0]\n        self.assertEqual(node.get_materialization(), \"incremental\")\n\n    def test_python_model_meta_get(self):\n        \"\"\"Test that dbt.config.meta_get() calls are tracked correctly\"\"\"\n        block = self.file_block_for(python_model_meta_get, \"nested/py_model.py\")\n        self.parser.manifest.files[block.file.file_id] = block.file\n        self.parser.parse_file(block)\n        node = list(self.parser.manifest.nodes.values())[0]\n        config_dict = node.config.to_dict()\n        self.assertEqual(config_dict[\"meta_keys_used\"], [\"owner\", \"priority\"])\n        # Both keys should have None as default since no explicit default was provided\n        self.assertIsNone(config_dict[\"meta_keys_defaults\"][0])\n        self.assertIsNone(config_dict[\"meta_keys_defaults\"][1])\n\n    def test_python_model_meta_get_with_defaults(self):\n        \"\"\"Test that dbt.config.meta_get() default values are tracked correctly\"\"\"\n        block = self.file_block_for(python_model_meta_get_with_defaults, \"nested/py_model.py\")\n        self.parser.manifest.files[block.file.file_id] = block.file\n        self.parser.parse_file(block)\n        node = list(self.parser.manifest.nodes.values())[0]\n        config_dict = node.config.to_dict()\n        self.assertEqual(config_dict[\"meta_keys_used\"], [\"owner\", \"priority\", \"environment\"])\n        default_values = config_dict[\"meta_keys_defaults\"]\n        self.assertEqual(default_values[0], \"default-owner\")\n        self.assertEqual(default_values[1], \"low\")\n        self.assertEqual(default_values[2], \"dev\")\n\n    def test_python_model_mixed_config_and_meta_get(self):\n        \"\"\"Test that config.get() and config.meta_get() can be used together\"\"\"\n        block = self.file_block_for(python_model_mixed_config_and_meta_get, \"nested/py_model.py\")\n        self.parser.manifest.files[block.file.file_id] = block.file\n        self.parser.parse_file(block)\n        node = list(self.parser.manifest.nodes.values())[0]\n        config_dict = node.config.to_dict()\n        # Should track both config.get and meta_get calls\n        self.assertEqual(config_dict[\"config_keys_used\"], [\"materialized\"])\n        self.assertEqual(config_dict[\"meta_keys_used\"], [\"owner\", \"priority\"])\n        self.assertIsNone(config_dict[\"config_keys_defaults\"][0])\n        self.assertIsNone(config_dict[\"meta_keys_defaults\"][0])\n        self.assertEqual(config_dict[\"meta_keys_defaults\"][1], \"low\")\n\n    def test_python_model_meta_get_no_args(self):\n        \"\"\"Test that meta_get() with no arguments raises an error\"\"\"\n        block = self.file_block_for(python_model_meta_get_no_args, \"nested/py_model.py\")\n        self.parser.manifest.files[block.file.file_id] = block.file\n        with self.assertRaises(ParsingError) as exc:\n            self.parser.parse_file(block)\n        self.assertIn(\"dbt.config.meta_get() requires at least one argument\", str(exc.exception))\n\n    def test_python_model_meta_get_too_many_args(self):\n        \"\"\"Test that meta_get() with more than 2 arguments raises an error\"\"\"\n        block = self.file_block_for(python_model_meta_get_too_many_args, \"nested/py_model.py\")\n        self.parser.manifest.files[block.file.file_id] = block.file\n        with self.assertRaises(ParsingError) as exc:\n            self.parser.parse_file(block)\n        self.assertIn(\"dbt.config.meta_get() takes at most 2 arguments\", str(exc.exception))\n\n\nclass StaticModelParserTest(BaseParserTest):\n    def setUp(self):\n        super().setUp()\n        self.parser = ModelParser(\n            project=self.snowplow_project_config,\n            manifest=self.manifest,\n            root_project=self.root_project_config,\n        )\n\n    def file_block_for(self, data, filename):\n        return super().file_block_for(data, filename, \"models\")\n\n    # tests that when the ref built-in is overriden with a macro definition\n    # that the ModelParser can detect it. This does not test that the static\n    # parser does not run in this case. That test is in integration test suite 072\n    def test_built_in_macro_override_detection(self):\n        macro_unique_id = \"macro.root.ref\"\n        self.parser.manifest.macros[macro_unique_id] = Macro(\n            name=\"ref\",\n            resource_type=NodeType.Macro,\n            unique_id=macro_unique_id,\n            package_name=\"root\",\n            original_file_path=normalize(\"macros/macro.sql\"),\n            path=normalize(\"macros/macro.sql\"),\n            macro_sql='{% macro ref(model_name) %}{% set x = raise(\"boom\") %}{% endmacro %}',\n        )\n\n        raw_code = '{{ config(materialized=\"table\") }}select 1 as id'\n        block = self.file_block_for(raw_code, \"nested/model_1.sql\")\n        node = ModelNode(\n            alias=\"model_1\",\n            name=\"model_1\",\n            database=\"test\",\n            schema=\"analytics\",\n            resource_type=NodeType.Model,\n            unique_id=\"model.snowplow.model_1\",\n            fqn=[\"snowplow\", \"nested\", \"model_1\"],\n            package_name=\"snowplow\",\n            original_file_path=normalize(\"models/nested/model_1.sql\"),\n            config=ModelConfig(materialized=\"table\"),\n            path=normalize(\"nested/model_1.sql\"),\n            language=\"sql\",\n            raw_code=raw_code,\n            checksum=block.file.checksum,\n            unrendered_config={\"materialized\": \"table\"},\n        )\n\n        assert self.parser._has_banned_macro(node)\n\n\n# TODO\nclass StaticModelParserUnitTest(BaseParserTest):\n    # _get_config_call_dict\n    # _shift_sources\n    # _get_exp_sample_result\n    # _get_stable_sample_result\n    # _get_sample_result\n\n    def setUp(self):\n        super().setUp()\n        self.parser = ModelParser(\n            project=self.snowplow_project_config,\n            manifest=self.manifest,\n            root_project=self.root_project_config,\n        )\n        self.example_node = ModelNode(\n            alias=\"model_1\",\n            name=\"model_1\",\n            database=\"test\",\n            schema=\"analytics\",\n            resource_type=NodeType.Model,\n            unique_id=\"model.snowplow.model_1\",\n            fqn=[\"snowplow\", \"nested\", \"model_1\"],\n            package_name=\"snowplow\",\n            original_file_path=normalize(\"models/nested/model_1.sql\"),\n            config=ModelConfig(materialized=\"table\"),\n            path=normalize(\"nested/model_1.sql\"),\n            language=\"sql\",\n            raw_code='{{ config(materialized=\"table\") }}select 1 as id',\n            checksum=None,\n            unrendered_config={\"materialized\": \"table\"},\n        )\n        self.example_config = ContextConfig(\n            self.root_project_config,\n            self.example_node.fqn,\n            self.example_node.resource_type,\n            self.snowplow_project_config,\n        )\n\n    def file_block_for(self, data, filename):\n        return super().file_block_for(data, filename, \"models\")\n\n    # tests that configs get extracted properly. the function should respect merge behavior,\n    # but becuase it's only reading from one dictionary it won't matter except in edge cases\n    # like this example with tags changing type to a list.\n    def test_config_shifting(self):\n        static_parser_result = {\n            \"configs\": [(\"hello\", \"world\"), (\"flag\", True), (\"tags\", \"tag1\"), (\"tags\", \"tag2\")]\n        }\n        expected = {\"hello\": \"world\", \"flag\": True, \"tags\": [\"tag1\", \"tag2\"]}\n        got = _get_config_call_dict(static_parser_result)\n        self.assertEqual(expected, got)\n\n    def test_source_shifting(self):\n        static_parser_result = {\"sources\": [(\"abc\", \"def\"), (\"x\", \"y\")]}\n        expected = {\"sources\": [[\"abc\", \"def\"], [\"x\", \"y\"]]}\n        got = _shift_sources(static_parser_result)\n        self.assertEqual(expected, got)\n\n    def test_sample_results(self):\n        # --- missed ref --- #\n        node = deepcopy(self.example_node)\n        config = deepcopy(self.example_config)\n        sample_node = deepcopy(self.example_node)\n        sample_config = deepcopy(self.example_config)\n\n        sample_node.refs = []\n        node.refs = [\"myref\"]\n\n        result = _get_sample_result(sample_node, sample_config, node, config)\n        self.assertEqual([(7, \"missed_ref_value\")], result)\n\n        # --- false positive ref --- #\n        node = deepcopy(self.example_node)\n        config = deepcopy(self.example_config)\n        sample_node = deepcopy(self.example_node)\n        sample_config = deepcopy(self.example_config)\n\n        sample_node.refs = [\"myref\"]\n        node.refs = []\n\n        result = _get_sample_result(sample_node, sample_config, node, config)\n        self.assertEqual([(6, \"false_positive_ref_value\")], result)\n\n        # --- missed source --- #\n        node = deepcopy(self.example_node)\n        config = deepcopy(self.example_config)\n        sample_node = deepcopy(self.example_node)\n        sample_config = deepcopy(self.example_config)\n\n        sample_node.sources = []\n        node.sources = [[\"abc\", \"def\"]]\n\n        result = _get_sample_result(sample_node, sample_config, node, config)\n        self.assertEqual([(5, \"missed_source_value\")], result)\n\n        # --- false positive source --- #\n        node = deepcopy(self.example_node)\n        config = deepcopy(self.example_config)\n        sample_node = deepcopy(self.example_node)\n        sample_config = deepcopy(self.example_config)\n\n        sample_node.sources = [[\"abc\", \"def\"]]\n        node.sources = []\n\n        result = _get_sample_result(sample_node, sample_config, node, config)\n        self.assertEqual([(4, \"false_positive_source_value\")], result)\n\n        # --- missed config --- #\n        node = deepcopy(self.example_node)\n        config = deepcopy(self.example_config)\n        sample_node = deepcopy(self.example_node)\n        sample_config = deepcopy(self.example_config)\n\n        sample_config._config_call_dict = {}\n        config._config_call_dict = {\"key\": \"value\"}\n\n        result = _get_sample_result(sample_node, sample_config, node, config)\n        self.assertEqual([(3, \"missed_config_value\")], result)\n\n        # --- false positive config --- #\n        node = deepcopy(self.example_node)\n        config = deepcopy(self.example_config)\n        sample_node = deepcopy(self.example_node)\n        sample_config = deepcopy(self.example_config)\n\n        sample_config._config_call_dict = {\"key\": \"value\"}\n        config._config_call_dict = {}\n\n        result = _get_sample_result(sample_node, sample_config, node, config)\n        self.assertEqual([(2, \"false_positive_config_value\")], result)\n\n    def test_exp_sample_results(self):\n        node = deepcopy(self.example_node)\n        config = deepcopy(self.example_config)\n        sample_node = deepcopy(self.example_node)\n        sample_config = deepcopy(self.example_config)\n        result = _get_exp_sample_result(sample_node, sample_config, node, config)\n        self.assertEqual([\"00_experimental_exact_match\"], result)\n\n    def test_stable_sample_results(self):\n        node = deepcopy(self.example_node)\n        config = deepcopy(self.example_config)\n        sample_node = deepcopy(self.example_node)\n        sample_config = deepcopy(self.example_config)\n        result = _get_stable_sample_result(sample_node, sample_config, node, config)\n        self.assertEqual([\"80_stable_exact_match\"], result)\n\n\nclass SnapshotParserTest(BaseParserTest):\n    def setUp(self):\n        super().setUp()\n        self.parser = SnapshotParser(\n            project=self.snowplow_project_config,\n            manifest=self.manifest,\n            root_project=self.root_project_config,\n        )\n\n    def file_block_for(self, data, filename):\n        return super().file_block_for(data, filename, \"snapshots\")\n\n    def test_parse_error(self):\n        block = self.file_block_for(\n            \"{% snapshot foo %}select 1 as id{%snapshot bar %}{% endsnapshot %}\",\n            \"nested/snap_1.sql\",\n        )\n        with self.assertRaises(CompilationError):\n            self.parser.parse_file(block)\n\n    def test_single_block(self):\n        raw_code = \"\"\"{{\n                config(unique_key=\"id\", target_schema=\"analytics\",\n                       target_database=\"dbt\", strategy=\"timestamp\",\n                       updated_at=\"last_update\")\n            }}\n            select 1 as id, now() as last_update\"\"\"\n        full_file = \"\"\"\n        {{% snapshot foo %}}{}{{% endsnapshot %}}\n        \"\"\".format(\n            raw_code\n        )\n        block = self.file_block_for(full_file, \"nested/snap_1.sql\")\n        self.parser.manifest.files[block.file.file_id] = block.file\n        self.parser.parse_file(block)\n        self.assert_has_manifest_lengths(self.parser.manifest, nodes=1)\n        node = list(self.parser.manifest.nodes.values())[0]\n        expected = SnapshotNode(\n            alias=\"foo\",\n            name=\"foo\",\n            # the `database` entry is overrridden by the target_database config\n            database=\"dbt\",\n            schema=\"analytics\",\n            resource_type=NodeType.Snapshot,\n            unique_id=\"snapshot.snowplow.foo\",\n            fqn=[\"snowplow\", \"nested\", \"snap_1\", \"foo\"],\n            package_name=\"snowplow\",\n            original_file_path=normalize(\"snapshots/nested/snap_1.sql\"),\n            config=SnapshotConfig(\n                strategy=\"timestamp\",\n                updated_at=\"last_update\",\n                target_database=\"dbt\",\n                target_schema=\"analytics\",\n                unique_key=\"id\",\n                materialized=\"snapshot\",\n            ),\n            path=\"foo.sql\",\n            language=\"sql\",\n            raw_code=raw_code,\n            checksum=block.file.checksum,\n            unrendered_config={\n                \"unique_key\": \"id\",\n                \"target_schema\": \"analytics\",\n                \"target_database\": \"dbt\",\n                \"strategy\": \"timestamp\",\n                \"updated_at\": \"last_update\",\n            },\n            config_call_dict={\n                \"strategy\": \"timestamp\",\n                \"target_database\": \"dbt\",\n                \"target_schema\": \"analytics\",\n                \"unique_key\": \"id\",\n                \"updated_at\": \"last_update\",\n            },\n            unrendered_config_call_dict={},\n        )\n        assertEqualNodes(expected, node)\n        file_id = \"snowplow://\" + normalize(\"snapshots/nested/snap_1.sql\")\n        self.assertIn(file_id, self.parser.manifest.files)\n        self.assertEqual(self.parser.manifest.files[file_id].nodes, [\"snapshot.snowplow.foo\"])\n\n    def test_multi_block(self):\n        raw_1 = \"\"\"\n            {{\n                config(unique_key=\"id\", target_schema=\"analytics\",\n                       target_database=\"dbt\", strategy=\"timestamp\",\n                       updated_at=\"last_update\")\n            }}\n            select 1 as id, now() as last_update\n        \"\"\"\n        raw_2 = \"\"\"\n            {{\n                config(unique_key=\"id\", target_schema=\"analytics\",\n                       target_database=\"dbt\", strategy=\"timestamp\",\n                       updated_at=\"last_update\")\n            }}\n            select 2 as id, now() as last_update\n        \"\"\"\n        full_file = \"\"\"\n        {{% snapshot foo %}}{}{{% endsnapshot %}}\n        {{% snapshot bar %}}{}{{% endsnapshot %}}\n        \"\"\".format(\n            raw_1, raw_2\n        )\n        block = self.file_block_for(full_file, \"nested/snap_1.sql\")\n        self.parser.manifest.files[block.file.file_id] = block.file\n        self.parser.parse_file(block)\n        self.assert_has_manifest_lengths(self.parser.manifest, nodes=2)\n        nodes = sorted(self.parser.manifest.nodes.values(), key=lambda n: n.name)\n        expect_foo = SnapshotNode(\n            alias=\"foo\",\n            name=\"foo\",\n            database=\"dbt\",\n            schema=\"analytics\",\n            resource_type=NodeType.Snapshot,\n            unique_id=\"snapshot.snowplow.foo\",\n            fqn=[\"snowplow\", \"nested\", \"snap_1\", \"foo\"],\n            package_name=\"snowplow\",\n            original_file_path=normalize(\"snapshots/nested/snap_1.sql\"),\n            config=SnapshotConfig(\n                strategy=\"timestamp\",\n                updated_at=\"last_update\",\n                target_database=\"dbt\",\n                target_schema=\"analytics\",\n                unique_key=\"id\",\n                materialized=\"snapshot\",\n            ),\n            path=\"foo.sql\",\n            language=\"sql\",\n            raw_code=raw_1,\n            checksum=block.file.checksum,\n            unrendered_config={\n                \"unique_key\": \"id\",\n                \"target_schema\": \"analytics\",\n                \"target_database\": \"dbt\",\n                \"strategy\": \"timestamp\",\n                \"updated_at\": \"last_update\",\n            },\n            config_call_dict={\n                \"strategy\": \"timestamp\",\n                \"target_database\": \"dbt\",\n                \"target_schema\": \"analytics\",\n                \"unique_key\": \"id\",\n                \"updated_at\": \"last_update\",\n            },\n            # Empty until state_modified_compare_more_unrendered_values=True\n            unrendered_config_call_dict={},\n        )\n        expect_bar = SnapshotNode(\n            alias=\"bar\",\n            name=\"bar\",\n            database=\"dbt\",\n            schema=\"analytics\",\n            resource_type=NodeType.Snapshot,\n            unique_id=\"snapshot.snowplow.bar\",\n            fqn=[\"snowplow\", \"nested\", \"snap_1\", \"bar\"],\n            package_name=\"snowplow\",\n            original_file_path=normalize(\"snapshots/nested/snap_1.sql\"),\n            config=SnapshotConfig(\n                strategy=\"timestamp\",\n                updated_at=\"last_update\",\n                target_database=\"dbt\",\n                target_schema=\"analytics\",\n                unique_key=\"id\",\n                materialized=\"snapshot\",\n            ),\n            path=\"bar.sql\",\n            language=\"sql\",\n            raw_code=raw_2,\n            checksum=block.file.checksum,\n            unrendered_config={\n                \"unique_key\": \"id\",\n                \"target_schema\": \"analytics\",\n                \"target_database\": \"dbt\",\n                \"strategy\": \"timestamp\",\n                \"updated_at\": \"last_update\",\n            },\n            config_call_dict={\n                \"strategy\": \"timestamp\",\n                \"target_database\": \"dbt\",\n                \"target_schema\": \"analytics\",\n                \"unique_key\": \"id\",\n                \"updated_at\": \"last_update\",\n            },\n            # Empty until state_modified_compare_more_unrendered_values=True\n            unrendered_config_call_dict={},\n        )\n        assertEqualNodes(nodes[0], expect_bar)\n        assertEqualNodes(nodes[1], expect_foo)\n        file_id = \"snowplow://\" + normalize(\"snapshots/nested/snap_1.sql\")\n        self.assertIn(file_id, self.parser.manifest.files)\n        self.assertEqual(\n            sorted(self.parser.manifest.files[file_id].nodes),\n            [\"snapshot.snowplow.bar\", \"snapshot.snowplow.foo\"],\n        )\n\n\nclass MacroParserTest(BaseParserTest):\n    def setUp(self):\n        super().setUp()\n        self.parser = MacroParser(project=self.snowplow_project_config, manifest=Manifest())\n\n    def file_block_for(self, data, filename):\n        return super().file_block_for(data, filename, \"macros\")\n\n    def test_single_block(self):\n        raw_code = \"{% macro foo(a, b) %}a ~ b{% endmacro %}\"\n        block = self.file_block_for(raw_code, \"macro.sql\")\n        self.parser.manifest.files[block.file.file_id] = block.file\n        self.parser.parse_file(block)\n        self.assertEqual(len(self.parser.manifest.macros), 1)\n        macro = list(self.parser.manifest.macros.values())[0]\n        expected = Macro(\n            name=\"foo\",\n            resource_type=NodeType.Macro,\n            unique_id=\"macro.snowplow.foo\",\n            package_name=\"snowplow\",\n            original_file_path=normalize(\"macros/macro.sql\"),\n            path=normalize(\"macros/macro.sql\"),\n            macro_sql=raw_code,\n        )\n        assertEqualNodes(macro, expected)\n        file_id = \"snowplow://\" + normalize(\"macros/macro.sql\")\n        self.assertIn(file_id, self.parser.manifest.files)\n        self.assertEqual(self.parser.manifest.files[file_id].macros, [\"macro.snowplow.foo\"])\n\n    def test_multiple_blocks(self):\n        raw_code = (\n            \"{% macro foo(a, b) %}a ~ b{% endmacro %}\\n{% macro bar(c, d) %}c + d{% endmacro %}\"\n        )\n        block = self.file_block_for(raw_code, \"macro.sql\")\n        self.parser.manifest.files[block.file.file_id] = block.file\n        self.parser.parse_file(block)\n        self.assertEqual(len(self.parser.manifest.macros), 2)\n        macros = sorted(self.parser.manifest.macros.values(), key=lambda m: m.name)\n        expected_bar = Macro(\n            name=\"bar\",\n            resource_type=NodeType.Macro,\n            unique_id=\"macro.snowplow.bar\",\n            package_name=\"snowplow\",\n            original_file_path=normalize(\"macros/macro.sql\"),\n            path=normalize(\"macros/macro.sql\"),\n            macro_sql=\"{% macro bar(c, d) %}c + d{% endmacro %}\",\n        )\n        expected_foo = Macro(\n            name=\"foo\",\n            resource_type=NodeType.Macro,\n            unique_id=\"macro.snowplow.foo\",\n            package_name=\"snowplow\",\n            original_file_path=normalize(\"macros/macro.sql\"),\n            path=normalize(\"macros/macro.sql\"),\n            macro_sql=\"{% macro foo(a, b) %}a ~ b{% endmacro %}\",\n        )\n        assertEqualNodes(macros[0], expected_bar)\n        assertEqualNodes(macros[1], expected_foo)\n        file_id = \"snowplow://\" + normalize(\"macros/macro.sql\")\n        self.assertIn(file_id, self.parser.manifest.files)\n        self.assertEqual(\n            sorted(self.parser.manifest.files[file_id].macros),\n            [\"macro.snowplow.bar\", \"macro.snowplow.foo\"],\n        )\n\n\nclass SingularTestParserTest(BaseParserTest):\n    def setUp(self):\n        super().setUp()\n        self.parser = SingularTestParser(\n            project=self.snowplow_project_config,\n            manifest=self.manifest,\n            root_project=self.root_project_config,\n        )\n\n    def file_block_for(self, data, filename):\n        return super().file_block_for(data, filename, \"tests\")\n\n    def test_basic(self):\n        raw_code = 'select * from {{ ref(\"blah\") }} limit 0'\n        block = self.file_block_for(raw_code, \"test_1.sql\")\n        self.manifest.files[block.file.file_id] = block.file\n        self.parser.parse_file(block)\n        self.assert_has_manifest_lengths(self.parser.manifest, nodes=1)\n        node = list(self.parser.manifest.nodes.values())[0]\n        expected = SingularTestNode(\n            alias=\"test_1\",\n            name=\"test_1\",\n            database=\"test\",\n            schema=\"dbt_test__audit\",\n            resource_type=NodeType.Test,\n            unique_id=\"test.snowplow.test_1\",\n            fqn=[\"snowplow\", \"test_1\"],\n            package_name=\"snowplow\",\n            original_file_path=normalize(\"tests/test_1.sql\"),\n            refs=[RefArgs(name=\"blah\")],\n            config=TestConfig(severity=\"ERROR\"),\n            tags=[],\n            path=normalize(\"test_1.sql\"),\n            language=\"sql\",\n            raw_code=raw_code,\n            checksum=block.file.checksum,\n            unrendered_config={},\n        )\n        assertEqualNodes(node, expected)\n        file_id = \"snowplow://\" + normalize(\"tests/test_1.sql\")\n        self.assertIn(file_id, self.parser.manifest.files)\n        self.assertEqual(self.parser.manifest.files[file_id].nodes, [\"test.snowplow.test_1\"])\n\n\nclass GenericTestParserTest(BaseParserTest):\n    # generic tests in the test-paths directory currently leverage the macro parser\n    def setUp(self):\n        super().setUp()\n        self.parser = GenericTestParser(project=self.snowplow_project_config, manifest=Manifest())\n\n    def file_block_for(self, data, filename):\n        return super().file_block_for(data, filename, \"tests/generic\")\n\n    def test_basic(self):\n        raw_code = \"{% test not_null(model, column_name) %}select * from {{ model }} where {{ column_name }} is null {% endtest %}\"\n        block = self.file_block_for(raw_code, \"test_1.sql\")\n        self.parser.manifest.files[block.file.file_id] = block.file\n        self.parser.parse_file(block)\n        node = list(self.parser.manifest.macros.values())[0]\n        expected = Macro(\n            name=\"test_not_null\",\n            resource_type=NodeType.Macro,\n            unique_id=\"macro.snowplow.test_not_null\",\n            package_name=\"snowplow\",\n            original_file_path=normalize(\"tests/generic/test_1.sql\"),\n            path=normalize(\"tests/generic/test_1.sql\"),\n            macro_sql=raw_code,\n        )\n        assertEqualNodes(node, expected)\n        file_id = \"snowplow://\" + normalize(\"tests/generic/test_1.sql\")\n        self.assertIn(file_id, self.parser.manifest.files)\n        self.assertEqual(\n            self.parser.manifest.files[file_id].macros, [\"macro.snowplow.test_not_null\"]\n        )\n\n\nclass AnalysisParserTest(BaseParserTest):\n    def setUp(self):\n        super().setUp()\n        self.parser = AnalysisParser(\n            project=self.snowplow_project_config,\n            manifest=self.manifest,\n            root_project=self.root_project_config,\n        )\n\n    def file_block_for(self, data, filename):\n        return super().file_block_for(data, filename, \"analyses\")\n\n    def test_basic(self):\n        raw_code = \"select 1 as id\"\n        block = self.file_block_for(raw_code, \"nested/analysis_1.sql\")\n        self.manifest.files[block.file.file_id] = block.file\n        self.parser.parse_file(block)\n        self.assert_has_manifest_lengths(self.parser.manifest, nodes=1)\n        node = list(self.parser.manifest.nodes.values())[0]\n        expected = AnalysisNode(\n            alias=\"analysis_1\",\n            name=\"analysis_1\",\n            database=\"test\",\n            schema=\"analytics\",\n            resource_type=NodeType.Analysis,\n            unique_id=\"analysis.snowplow.analysis_1\",\n            fqn=[\"snowplow\", \"analysis\", \"nested\", \"analysis_1\"],\n            package_name=\"snowplow\",\n            original_file_path=normalize(\"analyses/nested/analysis_1.sql\"),\n            depends_on=DependsOn(),\n            config=NodeConfig(),\n            path=normalize(\"analysis/nested/analysis_1.sql\"),\n            language=\"sql\",\n            raw_code=raw_code,\n            checksum=block.file.checksum,\n            unrendered_config={},\n            relation_name=None,\n        )\n        assertEqualNodes(node, expected)\n        file_id = \"snowplow://\" + normalize(\"analyses/nested/analysis_1.sql\")\n        self.assertIn(file_id, self.parser.manifest.files)\n        self.assertEqual(\n            self.parser.manifest.files[file_id].nodes, [\"analysis.snowplow.analysis_1\"]\n        )\n"
  },
  {
    "path": "tests/unit/parser/test_partial.py",
    "content": "import time\nfrom copy import deepcopy\nfrom typing import Dict, List\nfrom unittest import mock\n\nimport pytest\n\nfrom dbt.contracts.files import (\n    BaseSourceFile,\n    FileHash,\n    FilePath,\n    ParseFileType,\n    SchemaSourceFile,\n    SourceFile,\n)\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.contracts.graph.nodes import SnapshotNode, SourceDefinition\nfrom dbt.node_types import NodeType\nfrom dbt.parser.partial import PartialParsing\nfrom dbt.tests.util import safe_set_invocation_context\nfrom tests.unit.utils import normalize\nfrom tests.unit.utils.manifest import (\n    make_generic_test,\n    make_manifest,\n    make_model,\n    make_singular_test,\n    make_source,\n    make_source_snapshot,\n)\n\nPROJECT_NAME = \"my_test\"\n\n\n@pytest.fixture\ndef singular_test():\n    st = make_singular_test(\n        PROJECT_NAME, \"my_singular_test\", \"select 1 where false\", path=\"tests/my_singular_test.sql\"\n    )\n    st.patch_path = \"my_test://tests/tests.yml\"\n    return st\n\n\n@pytest.fixture\ndef source() -> SourceDefinition:\n    return make_source(PROJECT_NAME, \"my_source\", \"my_source_table\", path=\"models/schema.yml\")\n\n\n@pytest.fixture\ndef source_snapshot(source) -> SnapshotNode:\n    return make_source_snapshot(\n        PROJECT_NAME, \"my_test_source_snapshot\", source, path=\"models/schema.yml\"\n    )\n\n\n@pytest.fixture\ndef files(singular_test, source, source_snapshot) -> Dict[str, BaseSourceFile]:\n    project_root = \"/users/root\"\n    sql_model_file = SourceFile(\n        path=FilePath(\n            project_root=project_root,\n            searched_path=\"models\",\n            relative_path=\"my_model.sql\",\n            modification_time=time.time(),\n        ),\n        checksum=FileHash.from_contents(\"abcdef\"),\n        project_name=PROJECT_NAME,\n        parse_file_type=ParseFileType.Model,\n        nodes=[\"model.my_test.my_model\"],\n        env_vars=[],\n    )\n    sql_model_file_untouched = SourceFile(\n        path=FilePath(\n            project_root=project_root,\n            searched_path=\"models\",\n            relative_path=\"my_model_untouched.sql\",\n            modification_time=time.time(),\n        ),\n        checksum=FileHash.from_contents(\"abcdef\"),\n        project_name=PROJECT_NAME,\n        parse_file_type=ParseFileType.Model,\n        nodes=[\"model.my_test.my_model_untouched\"],\n        env_vars=[],\n    )\n\n    python_model_file = SourceFile(\n        path=FilePath(\n            project_root=project_root,\n            searched_path=\"models\",\n            relative_path=\"python_model.py\",\n            modification_time=time.time(),\n        ),\n        checksum=FileHash.from_contents(\"lalala\"),\n        project_name=PROJECT_NAME,\n        parse_file_type=ParseFileType.Model,\n        nodes=[\"model.my_test.python_model\"],\n        env_vars=[],\n    )\n    python_model_file_untouched = SourceFile(\n        path=FilePath(\n            project_root=project_root,\n            searched_path=\"models\",\n            relative_path=\"python_model_untouched.py\",\n            modification_time=time.time(),\n        ),\n        checksum=FileHash.from_contents(\"lalala\"),\n        project_name=PROJECT_NAME,\n        parse_file_type=ParseFileType.Model,\n        nodes=[\"model.my_test.python_model_untouched\"],\n        env_vars=[],\n    )\n    schema_file = SchemaSourceFile(\n        path=FilePath(\n            project_root=project_root,\n            searched_path=\"models\",\n            relative_path=\"schema.yml\",\n            modification_time=time.time(),\n        ),\n        checksum=FileHash.from_contents(\"ghijkl\"),\n        project_name=PROJECT_NAME,\n        parse_file_type=ParseFileType.Schema,\n        dfy={\n            \"version\": 2,\n            \"models\": [\n                {\"name\": \"my_model\", \"description\": \"Test model\"},\n                {\"name\": \"python_model\", \"description\": \"python\"},\n                {\"name\": \"not_null\", \"model\": \"test.my_test.test_my_model\"},\n            ],\n            \"sources\": [\n                {\"name\": source.source_name, \"tables\": [{\"name\": source.name}]},\n            ],\n            \"snapshots\": [\n                {\n                    \"name\": source_snapshot.name,\n                    \"relation\": f\"source('{source.source_name}', '{source.name}')\",\n                },\n            ],\n        },\n        ndp=[\"model.my_test.my_model\"],\n        env_vars={},\n        data_tests={\"models\": {\"not_null\": {\"test.my_test.test_my_model\": []}}},\n        snapshots=[f\"snapshot.{PROJECT_NAME}.{source_snapshot.name}\"],\n        sources=[f\"source.{PROJECT_NAME}.{source.source_name}.{source.name}\"],\n    )\n    singular_test_sql_file = SourceFile(\n        path=FilePath(\n            project_root=project_root,\n            searched_path=\"tests\",\n            relative_path=f\"{singular_test.name}.sql\",\n            modification_time=time.time(),\n        ),\n        checksum=FileHash.from_contents(\"a test\"),\n        project_name=PROJECT_NAME,\n        parse_file_type=ParseFileType.SingularTest,\n        nodes=[f\"test.{PROJECT_NAME}.{singular_test.name}\"],\n        env_vars=[],\n    )\n    singular_test_yml_file = SourceFile(\n        path=FilePath(\n            project_root=project_root,\n            searched_path=\"tests\",\n            relative_path=\"tests.yml\",\n            modification_time=time.time(),\n        ),\n        checksum=FileHash.from_contents(\"a test\"),\n        project_name=PROJECT_NAME,\n        parse_file_type=ParseFileType.Schema,\n        env_vars=[],\n    )\n    return {\n        schema_file.file_id: schema_file,\n        sql_model_file.file_id: sql_model_file,\n        sql_model_file_untouched.file_id: sql_model_file_untouched,\n        python_model_file.file_id: python_model_file,\n        python_model_file_untouched.file_id: python_model_file_untouched,\n        singular_test_sql_file.file_id: singular_test_sql_file,\n        singular_test_yml_file.file_id: singular_test_yml_file,\n    }\n\n\n@pytest.fixture\ndef nodes(singular_test, source, source_snapshot) -> List[NodeType]:\n    patch_path = \"my_test://\" + normalize(\"models/schema.yml\")\n    my_model = make_model(PROJECT_NAME, \"my_model\", \"\", patch_path=patch_path)\n    return [\n        my_model,\n        make_model(PROJECT_NAME, \"my_model_untouched\", \"\", patch_path=patch_path),\n        make_model(PROJECT_NAME, \"python_model\", \"\", language=\"python\", patch_path=patch_path),\n        make_model(\n            PROJECT_NAME, \"python_model_untouched\", \"\", language=\"python\", patch_path=patch_path\n        ),\n        make_generic_test(PROJECT_NAME, \"test\", my_model, {}),\n        singular_test,\n        source,\n        source_snapshot,\n    ]\n\n\n@pytest.fixture\ndef manifest(files, nodes, source) -> Manifest:\n    return make_manifest(files=files, nodes=nodes, sources=[source])\n\n\n@pytest.fixture\ndef partial_parsing(manifest, files):\n    safe_set_invocation_context()\n    return PartialParsing(manifest, deepcopy(files))\n\n\ndef test_simple(partial_parsing, files, nodes):\n    # Nothing has changed\n    assert partial_parsing is not None\n    assert partial_parsing.skip_parsing() is True\n\n    # Change a model file\n    sql_model_file_id = \"my_test://\" + normalize(\"models/my_model.sql\")\n    partial_parsing.new_files[sql_model_file_id].checksum = FileHash.from_contents(\"xyzabc\")\n\n    python_model_file_id = \"my_test://\" + normalize(\"models/python_model.py\")\n    partial_parsing.new_files[python_model_file_id].checksum = FileHash.from_contents(\"ohohoh\")\n\n    partial_parsing.build_file_diff()\n    assert partial_parsing.skip_parsing() is False\n    pp_files = partial_parsing.get_parsing_files()\n    pp_files[\"my_test\"][\"ModelParser\"] = set(pp_files[\"my_test\"][\"ModelParser\"])\n    # models has 'patch_path' so we expect to see a SchemaParser file listed\n    schema_file_id = \"my_test://\" + normalize(\"models/schema.yml\")\n    expected_pp_files = {\n        \"my_test\": {\n            \"ModelParser\": set([sql_model_file_id, python_model_file_id]),\n            \"SchemaParser\": [schema_file_id],\n        }\n    }\n    assert pp_files == expected_pp_files\n    schema_file = files[schema_file_id]\n    schema_file_model_names = set([model[\"name\"] for model in schema_file.pp_dict[\"models\"]])\n    expected_model_names = set([\"python_model\", \"my_model\"])\n    assert schema_file_model_names == expected_model_names\n    schema_file_model_descriptions = set(\n        [model[\"description\"] for model in schema_file.pp_dict[\"models\"]]\n    )\n    expected_model_descriptions = set([\"Test model\", \"python\"])\n    assert schema_file_model_descriptions == expected_model_descriptions\n\n\ndef test_schedule_nodes_for_parsing_basic(partial_parsing, nodes):\n    assert partial_parsing.file_diff[\"deleted\"] == []\n    assert partial_parsing.project_parser_files == {}\n    partial_parsing.schedule_nodes_for_parsing([nodes[0].unique_id])\n    assert partial_parsing.project_parser_files == {\n        \"my_test\": {\n            \"ModelParser\": [\"my_test://models/my_model.sql\"],\n            \"SchemaParser\": [\"my_test://models/schema.yml\"],\n        }\n    }\n\n\ndef test_schedule_macro_nodes_for_parsing_basic(partial_parsing):\n    # XXX it seems kind of confusing what exactly this function does.\n    # Whoever Changes this function please add more comment.\n\n    # this rely on the dfy and data_tests fields in schema node to add schema file to reparse\n    partial_parsing.schedule_macro_nodes_for_parsing([\"test.my_test.test_my_model\"])\n    assert partial_parsing.project_parser_files == {\n        \"my_test\": {\"SchemaParser\": [\"my_test://models/schema.yml\"]}\n    }\n\n\ndef test_schedule_nodes_for_parsing_versioning(partial_parsing, source) -> None:\n    # Modify schema file to add versioning\n    schema_file_id = \"my_test://\" + normalize(\"models/schema.yml\")\n    partial_parsing.new_files[schema_file_id].checksum = FileHash.from_contents(\"changed\")\n    partial_parsing.new_files[schema_file_id].dfy = {\n        \"version\": 2,\n        \"models\": [\n            {\n                \"name\": \"my_model\",\n                \"description\": \"Test model\",\n                \"latest_version\": 1,\n                \"versions\": [{\"v\": 1}],\n            },\n            {\"name\": \"python_model\", \"description\": \"python\"},\n            {\"name\": \"not_null\", \"model\": \"test.my_test.test_my_model\"},\n        ],\n        \"sources\": [\n            {\"name\": source.source_name, \"tables\": [{\"name\": source.name}]},\n        ],\n    }\n    with mock.patch.object(\n        partial_parsing, \"schedule_referencing_nodes_for_parsing\"\n    ) as mock_schedule_referencing_nodes_for_parsing:\n        partial_parsing.build_file_diff()\n        partial_parsing.get_parsing_files()\n\n        mock_schedule_referencing_nodes_for_parsing.assert_called_once_with(\n            \"model.my_test.my_model\"\n        )\n\n\nclass TestFileDiff:\n    @pytest.fixture\n    def partial_parsing(self, manifest, files):\n        safe_set_invocation_context()\n        saved_files = deepcopy(files)\n        saved_files[\"my_test://models/python_model_untouched.py\"].checksum = (\n            FileHash.from_contents(\"something new\")\n        )\n        saved_files[\"my_test://models/schema.yml\"].dfy[\"sources\"][0][\"tables\"][0][\n            \"description\"\n        ] = \"test\"\n        saved_files[\"my_test://models/schema.yml\"].checksum = FileHash.from_contents(\n            \"something new\"\n        )\n        saved_files[\"my_test://tests/my_singular_test.sql\"].checksum = FileHash.from_contents(\n            \"something new\"\n        )\n        return PartialParsing(manifest, saved_files)\n\n    def test_build_file_diff_basic(self, partial_parsing):\n        partial_parsing.build_file_diff()\n        assert set(partial_parsing.file_diff[\"unchanged\"]) == {\n            \"my_test://models/my_model_untouched.sql\",\n            \"my_test://models/my_model.sql\",\n            \"my_test://models/python_model.py\",\n            \"my_test://tests/tests.yml\",\n        }\n        assert set(partial_parsing.file_diff[\"changed\"]) == {\n            \"my_test://models/python_model_untouched.py\",\n            \"my_test://tests/my_singular_test.sql\",\n        }\n        assert partial_parsing.file_diff[\"changed_schema_files\"] == [\n            \"my_test://models/schema.yml\",\n        ]\n\n    def test_get_parsing_files(self, partial_parsing):\n        project_parser_files = partial_parsing.get_parsing_files()\n        assert project_parser_files == {\n            PROJECT_NAME: {\n                \"ModelParser\": [\"my_test://models/python_model_untouched.py\"],\n                \"SchemaParser\": [\"my_test://models/schema.yml\"],\n                \"SingularTestParser\": [\"my_test://tests/my_singular_test.sql\"],\n            },\n        }\n"
  },
  {
    "path": "tests/unit/parser/test_read_files.py",
    "content": "import pytest\n\nfrom dbt.parser.read_files import normalize_file_contents\n\n\n@pytest.mark.parametrize(\n    \"file_contents,expected_normalized_file_contents\",\n    [\n        (\"\", \"\"),\n        (\" \", \"\"),\n        (\"  \", \"\"),\n        (\"\\n\", \"\"),\n        (\"a b\", \"a b\"),\n        (\"a  b\", \"a b\"),\n        (\"a\\nb\", \"a b\"),\n        (\"a\\n b\", \"a b\"),\n        (\"a b \", \"a b\"),\n        (\"  a b  \", \"a b\"),\n        (\"\\na b\\n\", \"a b\"),\n        (\"\\n\\na b\\n\\n\", \"a b\"),\n    ],\n)\ndef test_normalize_file_contents(file_contents: str, expected_normalized_file_contents: str):\n    assert normalize_file_contents(file_contents) == expected_normalized_file_contents\n"
  },
  {
    "path": "tests/unit/parser/test_schema_renderer.py",
    "content": "import unittest\n\nfrom dbt.parser.schema_renderer import SchemaYamlRenderer\n\n\nclass TestYamlRendering(unittest.TestCase):\n    def test__models(self):\n\n        context = {\n            \"test_var\": \"1234\",\n            \"alt_var\": \"replaced\",\n        }\n        renderer = SchemaYamlRenderer(context, \"models\")\n\n        # Verify description is not rendered and misc attribute is rendered\n        dct = {\n            \"name\": \"my_model\",\n            \"description\": \"{{ test_var }}\",\n            \"attribute\": \"{{ test_var }}\",\n        }\n        expected = {\n            \"name\": \"my_model\",\n            \"description\": \"{{ test_var }}\",\n            \"attribute\": \"1234\",\n        }\n        dct = renderer.render_data(dct)\n        self.assertEqual(expected, dct)\n\n        # Verify description in columns is not rendered\n        dct = {\n            \"name\": \"my_test\",\n            \"attribute\": \"{{ test_var }}\",\n            \"columns\": [\n                {\"description\": \"{{ test_var }}\", \"name\": \"id\"},\n            ],\n        }\n        expected = {\n            \"name\": \"my_test\",\n            \"attribute\": \"1234\",\n            \"columns\": [\n                {\"description\": \"{{ test_var }}\", \"name\": \"id\"},\n            ],\n        }\n        dct = renderer.render_data(dct)\n        self.assertEqual(expected, dct)\n\n    def test__sources(self):\n\n        context = {\n            \"test_var\": \"1234\",\n            \"alt_var\": \"replaced\",\n        }\n        renderer = SchemaYamlRenderer(context, \"sources\")\n\n        # Only descriptions have jinja, none should be rendered\n        dct = {\n            \"name\": \"my_source\",\n            \"description\": \"{{ alt_var }}\",\n            \"loaded_at_query\": \"select max(ordered_at) from {{ this }}\",\n            \"tables\": [\n                {\n                    \"name\": \"my_table\",\n                    \"description\": \"{{ alt_var }}\",\n                    \"loaded_at_query\": \"select max(ordered_at) from {{ this }}\",\n                    \"columns\": [\n                        {\n                            \"name\": \"id\",\n                            \"description\": \"{{ alt_var }}\",\n                        }\n                    ],\n                }\n            ],\n        }\n        rendered = renderer.render_data(dct)\n        self.assertEqual(dct, rendered)\n\n    def test__macros(self):\n\n        context = {\n            \"test_var\": \"1234\",\n            \"alt_var\": \"replaced\",\n        }\n        renderer = SchemaYamlRenderer(context, \"macros\")\n\n        # Look for description in arguments\n        dct = {\n            \"name\": \"my_macro\",\n            \"arguments\": [\n                {\"name\": \"my_arg\", \"attr\": \"{{ alt_var }}\"},\n                {\"name\": \"an_arg\", \"description\": \"{{ alt_var}}\"},\n            ],\n        }\n        expected = {\n            \"name\": \"my_macro\",\n            \"arguments\": [\n                {\"name\": \"my_arg\", \"attr\": \"replaced\"},\n                {\"name\": \"an_arg\", \"description\": \"{{ alt_var}}\"},\n            ],\n        }\n        dct = renderer.render_data(dct)\n        self.assertEqual(dct, expected)\n\n    def test__metrics(self):\n        context = {\"metric_name_end\": \"_metric\"}\n        renderer = SchemaYamlRenderer(context, \"metrics\")\n\n        dct = {\n            \"name\": \"test{{ metric_name_end }}\",\n            \"description\": \"{{ docs('my_doc') }}\",\n            \"filter\": \"{{ Dimension('my_entity__my_dim') }} = false\",\n        }\n        # We expect the expression and description will not be rendered, but\n        # other fields will be\n        expected = {\n            \"name\": \"test_metric\",\n            \"description\": \"{{ docs('my_doc') }}\",\n            \"filter\": \"{{ Dimension('my_entity__my_dim') }} = false\",\n        }\n        dct = renderer.render_data(dct)\n        self.assertEqual(dct, expected)\n\n    def test__metrics_list_filter(self):\n        \"\"\"Test that list-type filters with Dimension jinja are not rendered for standalone metrics.\"\"\"\n        context = {\"metric_name_end\": \"_metric\"}\n        renderer = SchemaYamlRenderer(context, \"metrics\")\n\n        dct = {\n            \"name\": \"test{{ metric_name_end }}\",\n            \"filter\": [\n                \"{{ Dimension('my_entity__is_fraud') }} = false\",\n                \"{{ Dimension('my_entity__is_employee') }} = false\",\n            ],\n        }\n        expected = {\n            \"name\": \"test_metric\",\n            \"filter\": [\n                \"{{ Dimension('my_entity__is_fraud') }} = false\",\n                \"{{ Dimension('my_entity__is_employee') }} = false\",\n            ],\n        }\n        dct = renderer.render_data(dct)\n        self.assertEqual(dct, expected)\n\n    def test__metrics_nested_filter(self):\n        \"\"\"Test that deeply nested filters in standalone metrics (type_params) are not rendered.\"\"\"\n        context = {\"metric_name_end\": \"_metric\"}\n        renderer = SchemaYamlRenderer(context, \"metrics\")\n\n        # type_params.numerator.filter as string\n        dct = {\n            \"name\": \"test{{ metric_name_end }}\",\n            \"type_params\": {\n                \"numerator\": {\n                    \"name\": \"some_metric\",\n                    \"filter\": \"{{ Dimension('my_entity__my_dim') }} > 0\",\n                },\n            },\n        }\n        expected = {\n            \"name\": \"test_metric\",\n            \"type_params\": {\n                \"numerator\": {\n                    \"name\": \"some_metric\",\n                    \"filter\": \"{{ Dimension('my_entity__my_dim') }} > 0\",\n                },\n            },\n        }\n        dct = renderer.render_data(dct)\n        self.assertEqual(dct, expected)\n\n        # type_params.numerator.filter as list\n        dct = {\n            \"name\": \"test{{ metric_name_end }}\",\n            \"type_params\": {\n                \"numerator\": {\n                    \"name\": \"some_metric\",\n                    \"filter\": [\n                        \"{{ Dimension('my_entity__is_fraud') }} = false\",\n                        \"{{ Dimension('my_entity__is_employee') }} = false\",\n                    ],\n                },\n            },\n        }\n        expected = {\n            \"name\": \"test_metric\",\n            \"type_params\": {\n                \"numerator\": {\n                    \"name\": \"some_metric\",\n                    \"filter\": [\n                        \"{{ Dimension('my_entity__is_fraud') }} = false\",\n                        \"{{ Dimension('my_entity__is_employee') }} = false\",\n                    ],\n                },\n            },\n        }\n        dct = renderer.render_data(dct)\n        self.assertEqual(dct, expected)\n\n    def test__models_v2_metric_filter_string(self):\n        \"\"\"Test that string filters on v2 metrics (models key) are not rendered.\"\"\"\n        context = {\"test_var\": \"1234\"}\n        renderer = SchemaYamlRenderer(context, \"models\")\n\n        dct = {\n            \"name\": \"my_model\",\n            \"attribute\": \"{{ test_var }}\",\n            \"metrics\": [\n                {\n                    \"name\": \"my_metric\",\n                    \"filter\": \"{{ Dimension('my_entity__my_dim') }} > 0\",\n                },\n            ],\n        }\n        expected = {\n            \"name\": \"my_model\",\n            \"attribute\": \"1234\",\n            \"metrics\": [\n                {\n                    \"name\": \"my_metric\",\n                    \"filter\": \"{{ Dimension('my_entity__my_dim') }} > 0\",\n                },\n            ],\n        }\n        dct = renderer.render_data(dct)\n        self.assertEqual(dct, expected)\n\n    def test__models_v2_metric_filter_list(self):\n        \"\"\"Test that list-type filters on v2 metrics (models key) are not rendered.\n\n        This is the critical regression test: before the fix, list filters\n        like filter: [\"{{ Dimension(...) }} = False\", \"{{ Dimension(...) }} = False\"]\n        would be rendered at parse time, causing 'Dimension is undefined' errors.\n        \"\"\"\n        context = {\"test_var\": \"1234\"}\n        renderer = SchemaYamlRenderer(context, \"models\")\n\n        dct = {\n            \"name\": \"my_model\",\n            \"attribute\": \"{{ test_var }}\",\n            \"metrics\": [\n                {\n                    \"name\": \"my_metric\",\n                    \"filter\": [\n                        \"{{ Dimension('my_entity__is_fraud') }} = false\",\n                        \"{{ Dimension('my_entity__is_employee') }} = false\",\n                    ],\n                },\n            ],\n        }\n        expected = {\n            \"name\": \"my_model\",\n            \"attribute\": \"1234\",\n            \"metrics\": [\n                {\n                    \"name\": \"my_metric\",\n                    \"filter\": [\n                        \"{{ Dimension('my_entity__is_fraud') }} = false\",\n                        \"{{ Dimension('my_entity__is_employee') }} = false\",\n                    ],\n                },\n            ],\n        }\n        dct = renderer.render_data(dct)\n        self.assertEqual(dct, expected)\n\n    def test__models_v2_nested_metric_filters(self):\n        \"\"\"Test that nested metric filters (numerator, denominator, input_metrics, etc.)\n        are not rendered for both string and list forms under the models key.\"\"\"\n        context = {\"test_var\": \"1234\"}\n        renderer = SchemaYamlRenderer(context, \"models\")\n\n        # numerator.filter (string)\n        dct = {\n            \"name\": \"my_model\",\n            \"metrics\": [\n                {\n                    \"name\": \"ratio_metric\",\n                    \"numerator\": {\n                        \"name\": \"base\",\n                        \"filter\": \"{{ Dimension('my_entity__my_dim') }} > 0\",\n                    },\n                },\n            ],\n        }\n        expected_filter = \"{{ Dimension('my_entity__my_dim') }} > 0\"\n        rendered = renderer.render_data(dct)\n        self.assertEqual(rendered[\"metrics\"][0][\"numerator\"][\"filter\"], expected_filter)\n\n        # numerator.filter (list)\n        dct = {\n            \"name\": \"my_model\",\n            \"metrics\": [\n                {\n                    \"name\": \"ratio_metric\",\n                    \"numerator\": {\n                        \"name\": \"base\",\n                        \"filter\": [\n                            \"{{ Dimension('my_entity__is_fraud') }} = false\",\n                            \"{{ Dimension('my_entity__is_employee') }} = false\",\n                        ],\n                    },\n                },\n            ],\n        }\n        expected_filters = [\n            \"{{ Dimension('my_entity__is_fraud') }} = false\",\n            \"{{ Dimension('my_entity__is_employee') }} = false\",\n        ]\n        rendered = renderer.render_data(dct)\n        self.assertEqual(rendered[\"metrics\"][0][\"numerator\"][\"filter\"], expected_filters)\n\n        # input_metrics[].filter (list)\n        dct = {\n            \"name\": \"my_model\",\n            \"metrics\": [\n                {\n                    \"name\": \"derived_metric\",\n                    \"input_metrics\": [\n                        {\n                            \"name\": \"base\",\n                            \"filter\": [\n                                \"{{ Dimension('my_entity__is_fraud') }} = false\",\n                            ],\n                        },\n                    ],\n                },\n            ],\n        }\n        rendered = renderer.render_data(dct)\n        self.assertEqual(\n            rendered[\"metrics\"][0][\"input_metrics\"][0][\"filter\"],\n            [\"{{ Dimension('my_entity__is_fraud') }} = false\"],\n        )\n\n        # base_metric.filter (list, conversion metric)\n        dct = {\n            \"name\": \"my_model\",\n            \"metrics\": [\n                {\n                    \"name\": \"conversion_metric\",\n                    \"base_metric\": {\n                        \"name\": \"base\",\n                        \"filter\": [\n                            \"{{ Dimension('my_entity__is_fraud') }} = false\",\n                        ],\n                    },\n                },\n            ],\n        }\n        rendered = renderer.render_data(dct)\n        self.assertEqual(\n            rendered[\"metrics\"][0][\"base_metric\"][\"filter\"],\n            [\"{{ Dimension('my_entity__is_fraud') }} = false\"],\n        )\n\n    def test__derived_semantics_descriptions(self):\n        context = {\n            \"test_var\": \"1234\",\n        }\n        renderer = SchemaYamlRenderer(context, \"models\")\n\n        # Verify descriptions inside derived_semantics.dimensions and\n        # derived_semantics.entities are not rendered (they contain doc()\n        # Jinja that is resolved later in process_docs)\n        dct = {\n            \"name\": \"my_model\",\n            \"attribute\": \"{{ test_var }}\",\n            \"derived_semantics\": {\n                \"dimensions\": [\n                    {\n                        \"name\": \"my_dim\",\n                        \"description\": \"{{ test_var }}\",\n                        \"type\": \"categorical\",\n                    },\n                ],\n                \"entities\": [\n                    {\n                        \"name\": \"my_entity\",\n                        \"description\": \"{{ test_var }}\",\n                        \"type\": \"foreign\",\n                    },\n                ],\n            },\n        }\n        expected = {\n            \"name\": \"my_model\",\n            \"attribute\": \"1234\",\n            \"derived_semantics\": {\n                \"dimensions\": [\n                    {\n                        \"name\": \"my_dim\",\n                        \"description\": \"{{ test_var }}\",\n                        \"type\": \"categorical\",\n                    },\n                ],\n                \"entities\": [\n                    {\n                        \"name\": \"my_entity\",\n                        \"description\": \"{{ test_var }}\",\n                        \"type\": \"foreign\",\n                    },\n                ],\n            },\n        }\n        dct = renderer.render_data(dct)\n        self.assertEqual(expected, dct)\n"
  },
  {
    "path": "tests/unit/parser/test_sources.py",
    "content": "from typing import List, Optional\n\nimport pytest\n\nfrom core.dbt.artifacts.resources.v1.components import FreshnessThreshold, Time\nfrom core.dbt.parser.sources import merge_source_freshness\n\n\nclass TestMergeSourceFreshness:\n    @pytest.mark.parametrize(\n        \"thresholds,expected_result\",\n        [\n            ([None, None], None),\n            (\n                [\n                    FreshnessThreshold(\n                        warn_after=Time(count=1, period=\"hour\"),\n                        error_after=Time(count=1, period=\"day\"),\n                    ),\n                    None,\n                ],\n                None,\n            ),\n            (\n                [\n                    FreshnessThreshold(\n                        warn_after=Time(count=1, period=\"hour\"),\n                        error_after=Time(count=1, period=\"day\"),\n                    ),\n                    None,\n                    FreshnessThreshold(),\n                ],\n                None,\n            ),\n            (\n                [\n                    FreshnessThreshold(warn_after=Time(count=1, period=\"hour\")),\n                    FreshnessThreshold(error_after=Time(count=1, period=\"day\")),\n                ],\n                FreshnessThreshold(\n                    warn_after=Time(count=1, period=\"hour\"),\n                    error_after=Time(count=1, period=\"day\"),\n                ),\n            ),\n            (\n                [\n                    None,\n                    FreshnessThreshold(warn_after=Time(count=1, period=\"hour\")),\n                    FreshnessThreshold(error_after=Time(count=1, period=\"day\")),\n                ],\n                FreshnessThreshold(\n                    warn_after=Time(count=1, period=\"hour\"),\n                    error_after=Time(count=1, period=\"day\"),\n                ),\n            ),\n            (\n                [\n                    FreshnessThreshold(\n                        warn_after=Time(count=1, period=\"hour\"),\n                        error_after=Time(count=1, period=\"day\"),\n                    ),\n                    FreshnessThreshold(error_after=Time(count=48, period=\"hour\")),\n                ],\n                FreshnessThreshold(\n                    warn_after=Time(count=1, period=\"hour\"),\n                    error_after=Time(count=48, period=\"hour\"),\n                ),\n            ),\n        ],\n    )\n    def test_merge_source_freshness(\n        self,\n        thresholds: List[Optional[FreshnessThreshold]],\n        expected_result: Optional[FreshnessThreshold],\n    ):\n        result = merge_source_freshness(*thresholds)\n        assert result == expected_result\n"
  },
  {
    "path": "tests/unit/parser/test_unit_tests.py",
    "content": "from unittest import mock\n\nfrom dbt.artifacts.resources import DependsOn, UnitTestConfig, UnitTestFormat\nfrom dbt.contracts.graph.nodes import NodeType, UnitTestDefinition\nfrom dbt.contracts.graph.unparsed import UnitTestOutputFixture\nfrom dbt.parser import SchemaParser\nfrom dbt.parser.unit_tests import UnitTestParser\nfrom dbt_common.events.event_catcher import EventCatcher\nfrom dbt_common.events.event_manager_client import add_callback_to_manager\nfrom dbt_common.events.types import SystemStdErr\nfrom tests.unit.parser.test_parser import SchemaParserTest, assertEqualNodes\nfrom tests.unit.utils import MockNode\n\nUNIT_TEST_MODEL_NOT_FOUND_SOURCE = \"\"\"\nunit_tests:\n    - name: test_my_model_doesnt_exist\n      model: my_model_doesnt_exist\n      description: \"unit test description\"\n      given: []\n      expect:\n        rows:\n          - {a: 1}\n\"\"\"\n\n\nUNIT_TEST_SOURCE = \"\"\"\nunit_tests:\n    - name: test_my_model\n      model: my_model\n      description: \"unit test description\"\n      given: []\n      expect:\n        rows:\n          - {a: 1}\n\"\"\"\n\n\nUNIT_TEST_VERSIONED_MODEL_SOURCE = \"\"\"\nunit_tests:\n    - name: test_my_model_versioned\n      model: my_model_versioned.v1\n      description: \"unit test description\"\n      given: []\n      expect:\n        rows:\n          - {a: 1}\n\"\"\"\n\n\nUNIT_TEST_CONFIG_SOURCE = \"\"\"\nunit_tests:\n    - name: test_my_model\n      model: my_model\n      config:\n        tags: \"schema_tag\"\n        meta:\n          meta_key: meta_value\n          meta_jinja_key: '{{ 1 + 1 }}'\n      description: \"unit test description\"\n      given: []\n      expect:\n        rows:\n          - {a: 1}\n\"\"\"\n\n\nUNIT_TEST_MULTIPLE_SOURCE = \"\"\"\nunit_tests:\n    - name: test_my_model\n      model: my_model\n      description: \"unit test description\"\n      given: []\n      expect:\n        rows:\n          - {a: 1}\n    - name: test_my_model2\n      model: my_model\n      description: \"unit test description\"\n      given: []\n      expect:\n        rows:\n          - {a: 1}\n\"\"\"\n\nUNIT_TEST_NONE_ROWS_SORT = \"\"\"\nunit_tests:\n  - name: test_my_model_null_handling\n    model: my_model\n    description: \"unit test description\"\n    given: []\n    expect:\n        rows:\n        - {\"id\":  , \"col1\": \"d\"}\n        - {\"id\":  , \"col1\": \"e\"}\n        - {\"id\": 6, \"col1\": \"f\"}\n\"\"\"\n\nUNIT_TEST_NONE_ROWS_SORT_CSV = \"\"\"\nunit_tests:\n  - name: test_my_model_null_handling\n    model: my_model\n    description: \"unit test description\"\n    given: []\n    expect:\n        format: csv\n        rows: |\n          id,col1\n          ,d\n          ,e\n          6,f\n\"\"\"\n\nUNIT_TEST_NONE_ROWS_SORT_SQL = \"\"\"\nunit_tests:\n  - name: test_my_model_null_handling\n    model: my_model\n    description: \"unit test description\"\n    given: []\n    expect:\n        format: sql\n        rows: |\n          select null\n          select 1\n\"\"\"\n\nUNIT_TEST_NONE_ROWS_SORT_FAILS = \"\"\"\nunit_tests:\n  - name: test_my_model_null_handling\n    model: my_model\n    description: \"this unit test needs one non-None value row\"\n    given: []\n    expect:\n        rows:\n        - {\"id\":  , \"col1\": \"d\"}\n        - {\"id\":  , \"col1\": \"e\"}\n\"\"\"\n\nUNIT_TEST_DISABLED = \"\"\"\nunit_tests:\n    - name: test_my_model_disabled\n      model: my_model\n      description: \"this unit test is disabled\"\n      config:\n        enabled: false\n      given: []\n      expect:\n        rows:\n          - {a: 1}\n\"\"\"\n\n\nclass UnitTestParserTest(SchemaParserTest):\n    def setUp(self):\n        super().setUp()\n        my_model_node = MockNode(\n            package=\"snowplow\",\n            name=\"my_model\",\n            config=mock.MagicMock(enabled=True),\n            schema=\"test_schema\",\n            refs=[],\n            sources=[],\n            patch_path=None,\n        )\n        self.manifest.nodes = {my_model_node.unique_id: my_model_node}\n        self.parser = SchemaParser(\n            project=self.snowplow_project_config,\n            manifest=self.manifest,\n            root_project=self.root_project_config,\n        )\n\n    def file_block_for(self, data, filename):\n        return super().file_block_for(data, filename, \"unit_tests\")\n\n    def test_basic(self):\n        block = self.yaml_block_for(UNIT_TEST_SOURCE, \"test_my_model.yml\")\n\n        UnitTestParser(self.parser, block).parse()\n\n        self.assert_has_manifest_lengths(self.parser.manifest, nodes=1, unit_tests=1)\n        unit_test = list(self.parser.manifest.unit_tests.values())[0]\n        expected = UnitTestDefinition(\n            name=\"test_my_model\",\n            model=\"my_model\",\n            resource_type=NodeType.Unit,\n            package_name=\"snowplow\",\n            path=block.path.relative_path,\n            original_file_path=block.path.original_file_path,\n            unique_id=\"unit_test.snowplow.my_model.test_my_model\",\n            given=[],\n            expect=UnitTestOutputFixture(rows=[{\"a\": 1}]),\n            description=\"unit test description\",\n            overrides=None,\n            depends_on=DependsOn(nodes=[\"model.snowplow.my_model\"]),\n            fqn=[\"snowplow\", \"my_model\", \"test_my_model\"],\n            config=UnitTestConfig(),\n            schema=\"test_schema\",\n        )\n        expected.build_unit_test_checksum()\n        assertEqualNodes(unit_test, expected)\n\n    def test_unit_test_config(self):\n        block = self.yaml_block_for(UNIT_TEST_CONFIG_SOURCE, \"test_my_model.yml\")\n        self.root_project_config.unit_tests = {\n            \"snowplow\": {\"my_model\": {\"+tags\": [\"project_tag\"]}}\n        }\n\n        UnitTestParser(self.parser, block).parse()\n\n        self.assert_has_manifest_lengths(self.parser.manifest, nodes=1, unit_tests=1)\n        unit_test = self.parser.manifest.unit_tests[\"unit_test.snowplow.my_model.test_my_model\"]\n        self.assertEqual(sorted(unit_test.config.tags), sorted([\"schema_tag\", \"project_tag\"]))\n        self.assertEqual(unit_test.config.meta, {\"meta_key\": \"meta_value\", \"meta_jinja_key\": \"2\"})\n\n    def test_unit_test_disabled(self):\n        block = self.yaml_block_for(UNIT_TEST_DISABLED, \"test_my_model.yml\")\n        self.root_project_config.unit_tests = {\n            \"snowplow\": {\"my_model\": {\"+tags\": [\"project_tag\"]}}\n        }\n\n        UnitTestParser(self.parser, block).parse()\n\n        self.assert_has_manifest_lengths(self.parser.manifest, nodes=1, unit_tests=0, disabled=1)\n        unit_test_disabled_list = self.parser.manifest.disabled[\n            \"unit_test.snowplow.my_model.test_my_model_disabled\"\n        ]\n        self.assertEqual(len(unit_test_disabled_list), 1)\n        unit_test_disabled = unit_test_disabled_list[0]\n        self.assertEqual(unit_test_disabled.config.enabled, False)\n\n    def test_unit_test_versioned_model(self):\n        block = self.yaml_block_for(UNIT_TEST_VERSIONED_MODEL_SOURCE, \"test_my_model.yml\")\n        my_model_versioned_node = MockNode(\n            package=\"snowplow\",\n            name=\"my_model_versioned\",\n            config=mock.MagicMock(enabled=True),\n            refs=[],\n            sources=[],\n            patch_path=None,\n            version=1,\n        )\n        self.manifest.nodes[my_model_versioned_node.unique_id] = my_model_versioned_node\n\n        UnitTestParser(self.parser, block).parse()\n\n        self.assert_has_manifest_lengths(self.parser.manifest, nodes=2, unit_tests=1)\n        unit_test = self.parser.manifest.unit_tests[\n            \"unit_test.snowplow.my_model_versioned.v1.test_my_model_versioned\"\n        ]\n        self.assertEqual(len(unit_test.depends_on.nodes), 1)\n        self.assertEqual(unit_test.depends_on.nodes[0], \"model.snowplow.my_model_versioned.v1\")\n\n    def test_multiple_unit_tests(self):\n        block = self.yaml_block_for(UNIT_TEST_MULTIPLE_SOURCE, \"test_my_model.yml\")\n\n        UnitTestParser(self.parser, block).parse()\n\n        self.assert_has_manifest_lengths(self.parser.manifest, nodes=1, unit_tests=2)\n        for unit_test in self.parser.manifest.unit_tests.values():\n            self.assertEqual(len(unit_test.depends_on.nodes), 1)\n            self.assertEqual(unit_test.depends_on.nodes[0], \"model.snowplow.my_model\")\n\n    def _assert_fixture_yml_reorders_to_expected_rows(\n        self, unit_test_fixture_yml, fixture_expected_field_format, expected_rows\n    ):\n        block = self.yaml_block_for(unit_test_fixture_yml, \"test_my_model.yml\")\n\n        UnitTestParser(self.parser, block).parse()\n\n        self.assert_has_manifest_lengths(self.parser.manifest, nodes=1, unit_tests=1)\n        unit_test = list(self.parser.manifest.unit_tests.values())[0]\n        expected = UnitTestDefinition(\n            name=\"test_my_model_null_handling\",\n            model=\"my_model\",\n            resource_type=NodeType.Unit,\n            package_name=\"snowplow\",\n            path=block.path.relative_path,\n            original_file_path=block.path.original_file_path,\n            unique_id=\"unit_test.snowplow.my_model.test_my_model_null_handling\",\n            given=[],\n            expect=UnitTestOutputFixture(format=fixture_expected_field_format, rows=expected_rows),\n            description=\"unit test description\",\n            overrides=None,\n            depends_on=DependsOn(nodes=[\"model.snowplow.my_model\"]),\n            fqn=[\"snowplow\", \"my_model\", \"test_my_model_null_handling\"],\n            config=UnitTestConfig(),\n            schema=\"test_schema\",\n        )\n        expected.build_unit_test_checksum()\n        assertEqualNodes(unit_test, expected)\n\n    def test_expected_promote_non_none_row_dct(self):\n        expected_rows = [\n            {\"id\": 6, \"col1\": \"f\"},\n            {\"id\": None, \"col1\": \"e\"},\n            {\"id\": None, \"col1\": \"d\"},\n        ]\n        self._assert_fixture_yml_reorders_to_expected_rows(\n            UNIT_TEST_NONE_ROWS_SORT, UnitTestFormat.Dict, expected_rows\n        )\n\n    def test_expected_promote_non_none_row_csv(self):\n        expected_rows = [\n            {\"id\": \"6\", \"col1\": \"f\"},\n            {\"id\": None, \"col1\": \"e\"},\n            {\"id\": None, \"col1\": \"d\"},\n        ]\n        self._assert_fixture_yml_reorders_to_expected_rows(\n            UNIT_TEST_NONE_ROWS_SORT_CSV, UnitTestFormat.CSV, expected_rows\n        )\n\n    def test_expected_promote_non_none_row_sql(self):\n        expected_rows = \"select null\\n\" + \"select 1\"\n        self._assert_fixture_yml_reorders_to_expected_rows(\n            UNIT_TEST_NONE_ROWS_SORT_SQL, UnitTestFormat.SQL, expected_rows\n        )\n\n    def test_no_full_row_does_not_raise_exception(self):\n        catcher = EventCatcher(SystemStdErr)\n        add_callback_to_manager(catcher.catch)\n\n        block = self.yaml_block_for(UNIT_TEST_NONE_ROWS_SORT_FAILS, \"test_my_model.yml\")\n        UnitTestParser(self.parser, block).parse()\n\n        assert len(catcher.caught_events) == 1\n"
  },
  {
    "path": "tests/unit/parser/test_v2_column_semantic_parsing.py",
    "content": "\"\"\"Unit tests for _parse_v2_column_dimensions and _parse_v2_column_entities.\n\nThese methods transform column-level dimension/entity definitions into Dimension\nand Entity objects for the semantic manifest. When a dimension or entity name\ndiffers from the column name, the resulting object must have expr set to the\ncolumn name so that MetricFlow generates SQL against the correct warehouse column.\n\"\"\"\n\nfrom collections import OrderedDict\n\nfrom dbt.artifacts.resources import ColumnDimension, ColumnEntity, ColumnInfo\nfrom dbt.parser.schema_yaml_readers import SemanticModelParser\nfrom dbt_semantic_interfaces.type_enums import DimensionType, EntityType\n\n\ndef _make_column(name, description=\"\", dimension=None, entity=None, granularity=None, config=None):\n    \"\"\"Helper to construct a ColumnInfo with only the fields we need.\"\"\"\n    return ColumnInfo(\n        name=name,\n        description=description,\n        dimension=dimension,\n        entity=entity,\n        granularity=granularity,\n        config=config or {},\n    )\n\n\ndef _make_columns_dict(*columns):\n    \"\"\"Build an OrderedDict of ColumnInfo keyed by name, as the parser expects.\"\"\"\n    return OrderedDict((col.name, col) for col in columns)\n\n\nclass TestParseV2ColumnDimensionsExpr:\n    \"\"\"Test that _parse_v2_column_dimensions sets expr correctly.\"\"\"\n\n    def test_dimension_name_override_sets_expr_to_column_name(self):\n        \"\"\"When dimension.name differs from column.name, expr must be the column name.\"\"\"\n        columns = _make_columns_dict(\n            _make_column(\n                name=\"afe_number\",\n                description=\"AFE identifier\",\n                dimension=ColumnDimension(\n                    name=\"approval_afe_number\",\n                    type=DimensionType.CATEGORICAL,\n                ),\n            ),\n        )\n        dimensions = SemanticModelParser._parse_v2_column_dimensions(None, columns)\n        assert len(dimensions) == 1\n        dim = dimensions[0]\n        assert dim.name == \"approval_afe_number\"\n        assert dim.expr == \"afe_number\"\n\n    def test_dimension_name_matches_column_name_expr_is_none(self):\n        \"\"\"When dimension.name matches column.name, expr should be None.\"\"\"\n        columns = _make_columns_dict(\n            _make_column(\n                name=\"status\",\n                dimension=ColumnDimension(\n                    name=\"status\",\n                    type=DimensionType.CATEGORICAL,\n                ),\n            ),\n        )\n        dimensions = SemanticModelParser._parse_v2_column_dimensions(None, columns)\n        assert len(dimensions) == 1\n        assert dimensions[0].name == \"status\"\n        assert dimensions[0].expr is None\n\n    def test_dimension_empty_name_defaults_to_column_name(self):\n        \"\"\"When dimension.name is empty string, name defaults to column.name and expr is None.\"\"\"\n        columns = _make_columns_dict(\n            _make_column(\n                name=\"category\",\n                dimension=ColumnDimension(\n                    name=\"\",\n                    type=DimensionType.CATEGORICAL,\n                ),\n            ),\n        )\n        dimensions = SemanticModelParser._parse_v2_column_dimensions(None, columns)\n        assert len(dimensions) == 1\n        assert dimensions[0].name == \"category\"\n        assert dimensions[0].expr is None\n\n    def test_dimension_shorthand_type_expr_is_none(self):\n        \"\"\"When dimension is just a DimensionType (shorthand), expr should be None.\"\"\"\n        columns = _make_columns_dict(\n            _make_column(\n                name=\"color\",\n                dimension=DimensionType.CATEGORICAL,\n            ),\n        )\n        dimensions = SemanticModelParser._parse_v2_column_dimensions(None, columns)\n        assert len(dimensions) == 1\n        assert dimensions[0].name == \"color\"\n        assert dimensions[0].expr is None\n\n\nclass TestParseV2ColumnEntitiesExpr:\n    \"\"\"Test that _parse_v2_column_entities sets expr correctly.\"\"\"\n\n    def test_entity_name_override_sets_expr_to_column_name(self):\n        \"\"\"When entity.name differs from column.name, expr must be the column name.\"\"\"\n        columns = _make_columns_dict(\n            _make_column(\n                name=\"id\",\n                description=\"Primary key\",\n                entity=ColumnEntity(\n                    name=\"id_entity\",\n                    type=EntityType.PRIMARY,\n                ),\n            ),\n        )\n        entities = SemanticModelParser._parse_v2_column_entities(None, columns)\n        assert len(entities) == 1\n        ent = entities[0]\n        assert ent.name == \"id_entity\"\n        assert ent.expr == \"id\"\n\n    def test_entity_name_matches_column_name_expr_is_none(self):\n        \"\"\"When entity.name matches column.name, expr should be None.\"\"\"\n        columns = _make_columns_dict(\n            _make_column(\n                name=\"user_id\",\n                entity=ColumnEntity(\n                    name=\"user_id\",\n                    type=EntityType.FOREIGN,\n                ),\n            ),\n        )\n        entities = SemanticModelParser._parse_v2_column_entities(None, columns)\n        assert len(entities) == 1\n        assert entities[0].name == \"user_id\"\n        assert entities[0].expr is None\n\n    def test_entity_shorthand_type_expr_is_none(self):\n        \"\"\"When entity is just an EntityType (shorthand), name defaults to column.name and expr is None.\"\"\"\n        columns = _make_columns_dict(\n            _make_column(\n                name=\"foreign_id_col\",\n                entity=EntityType.FOREIGN,\n            ),\n        )\n        entities = SemanticModelParser._parse_v2_column_entities(None, columns)\n        assert len(entities) == 1\n        assert entities[0].name == \"foreign_id_col\"\n        assert entities[0].expr is None\n"
  },
  {
    "path": "tests/unit/plugins/test_manager.py",
    "content": "from unittest import mock\n\nimport pytest\n\nfrom dbt.exceptions import DbtRuntimeError\nfrom dbt.plugins import PluginManager, dbt_hook, dbtPlugin\nfrom dbt.plugins.contracts import PluginArtifact, PluginArtifacts\nfrom dbt.plugins.exceptions import dbtPluginError\nfrom dbt.plugins.manifest import ModelNodeArgs, PluginNodes\n\n\nclass ExceptionInitializePlugin(dbtPlugin):\n    def initialize(self) -> None:\n        raise Exception(\"plugin error message\")\n\n\nclass dbtRuntimeErrorInitializePlugin(dbtPlugin):\n    def initialize(self) -> None:\n        raise dbtPluginError(\"plugin error message\")\n\n\nclass GetNodesPlugin(dbtPlugin):\n    @dbt_hook\n    def get_nodes(self) -> PluginNodes:\n        nodes = PluginNodes()\n        nodes.add_model(\n            ModelNodeArgs(\n                name=\"test_name\",\n                package_name=self.project_name,\n                identifier=\"test_identifier\",\n                schema=\"test_schema\",\n            )\n        )\n        return nodes\n\n\nclass GetArtifactsPlugin(dbtPlugin):\n    @dbt_hook\n    def get_manifest_artifacts(self, manifest) -> PluginArtifacts:\n        return {self.project_name: PluginArtifact()}\n\n\nclass TestPluginManager:\n    @pytest.fixture\n    def get_nodes_plugin(self):\n        return GetNodesPlugin(project_name=\"test\")\n\n    @pytest.fixture\n    def get_nodes_plugins(self, get_nodes_plugin):\n        return [get_nodes_plugin, GetNodesPlugin(project_name=\"test2\")]\n\n    @pytest.fixture\n    def get_artifacts_plugin(self):\n        return GetArtifactsPlugin(project_name=\"test\")\n\n    @pytest.fixture\n    def get_artifacts_plugins(self, get_artifacts_plugin):\n        return [get_artifacts_plugin, GetArtifactsPlugin(project_name=\"test2\")]\n\n    def test_plugin_manager_init_exception(self):\n        with pytest.raises(DbtRuntimeError, match=\"plugin error message\"):\n            PluginManager(plugins=[ExceptionInitializePlugin(project_name=\"test\")])\n\n    def test_plugin_manager_init_plugin_exception(self):\n        with pytest.raises(DbtRuntimeError, match=\"^Runtime Error\\n    plugin error message\"):\n            PluginManager(plugins=[dbtRuntimeErrorInitializePlugin(project_name=\"test\")])\n\n    def test_plugin_manager_init_single_hook(self, get_nodes_plugin):\n        pm = PluginManager(plugins=[get_nodes_plugin])\n        assert len(pm.hooks) == 1\n\n        assert \"get_nodes\" in pm.hooks\n        assert len(pm.hooks[\"get_nodes\"]) == 1\n        assert pm.hooks[\"get_nodes\"][0] == get_nodes_plugin.get_nodes\n\n    def test_plugin_manager_init_single_hook_multiple_methods(self, get_nodes_plugins):\n        pm = PluginManager(plugins=get_nodes_plugins)\n        assert len(pm.hooks) == 1\n\n        assert \"get_nodes\" in pm.hooks\n        assert len(pm.hooks[\"get_nodes\"]) == 2\n        assert pm.hooks[\"get_nodes\"][0] == get_nodes_plugins[0].get_nodes\n        assert pm.hooks[\"get_nodes\"][1] == get_nodes_plugins[1].get_nodes\n\n    def test_plugin_manager_init_multiple_hooks(self, get_nodes_plugin, get_artifacts_plugin):\n        pm = PluginManager(plugins=[get_nodes_plugin, get_artifacts_plugin])\n        assert len(pm.hooks) == 2\n\n        assert \"get_nodes\" in pm.hooks\n        assert len(pm.hooks[\"get_nodes\"]) == 1\n        assert pm.hooks[\"get_nodes\"][0] == get_nodes_plugin.get_nodes\n\n        assert \"get_manifest_artifacts\" in pm.hooks\n        assert len(pm.hooks[\"get_manifest_artifacts\"]) == 1\n        assert pm.hooks[\"get_manifest_artifacts\"][0] == get_artifacts_plugin.get_manifest_artifacts\n\n    @mock.patch(\"dbt.tracking\")\n    def test_get_nodes(self, tracking, get_nodes_plugins):\n        tracking.active_user = mock.Mock()\n        pm = PluginManager(plugins=get_nodes_plugins)\n\n        nodes = pm.get_nodes()\n\n        assert len(nodes.models) == 2\n\n        expected_calls = [\n            mock.call(\n                {\n                    \"plugin_name\": get_nodes_plugins[0].name,\n                    \"num_model_nodes\": 1,\n                    \"num_model_packages\": 1,\n                }\n            ),\n            mock.call(\n                {\n                    \"plugin_name\": get_nodes_plugins[1].name,\n                    \"num_model_nodes\": 1,\n                    \"num_model_packages\": 1,\n                }\n            ),\n        ]\n\n        tracking.track_plugin_get_nodes.assert_has_calls(expected_calls)\n\n    def test_get_manifest_artifact(self, get_artifacts_plugins):\n        pm = PluginManager(plugins=get_artifacts_plugins)\n        artifacts = pm.get_manifest_artifacts(None)\n        assert len(artifacts) == 2\n"
  },
  {
    "path": "tests/unit/task/__init__.py",
    "content": ""
  },
  {
    "path": "tests/unit/task/docs/__init__.py",
    "content": ""
  },
  {
    "path": "tests/unit/task/docs/test_serve.py",
    "content": "from http.server import SimpleHTTPRequestHandler\nfrom unittest.mock import MagicMock, patch\n\nimport pytest\n\nfrom dbt.task.docs.serve import ServeTask\n\n\n@pytest.fixture\ndef serve_task():\n    # Set up\n    task = ServeTask(config=MagicMock(), args=MagicMock())\n    task.config.project_target_path = \".\"\n    task.args.port = 8000\n    task.args.host = \"127.0.0.1\"\n    return task\n\n\ndef test_serve_bind_to_127(serve_task):\n    serve_task.args.browser = False\n    with patch(\"dbt.task.docs.serve.socketserver.TCPServer\") as patched_TCPServer:\n        patched_TCPServer.return_value = MagicMock()\n        serve_task.run()\n        patched_TCPServer.assert_called_once_with((\"127.0.0.1\", 8000), SimpleHTTPRequestHandler)\n\n\ndef test_serve_bind_to_all(serve_task):\n    serve_task.args.browser = False\n    serve_task.args.host = \"\"\n\n    with patch(\"dbt.task.docs.serve.socketserver.TCPServer\") as patched_TCPServer:\n        patched_TCPServer.return_value = MagicMock()\n        serve_task.run()\n        patched_TCPServer.assert_called_once_with((\"\", 8000), SimpleHTTPRequestHandler)\n"
  },
  {
    "path": "tests/unit/task/test_base.py",
    "content": "import os\n\nimport dbt_common.exceptions\nfrom dbt.contracts.graph.nodes import SourceDefinition\nfrom dbt.task.base import BaseRunner, ConfiguredTask\nfrom tests.unit.config import BaseConfigTest\n\nINITIAL_ROOT = os.getcwd()\n\n\nclass MockRunner(BaseRunner):\n    def compile(self):\n        pass\n\n\nclass TestBaseRunner:\n    def test_handle_generic_exception_handles_nodes_without_build_path(\n        self, basic_parsed_source_definition_object: SourceDefinition\n    ):\n        # Source definition nodes don't have `build_path` attributes. Thus, this\n        # test will fail if _handle_generic_exception doesn't account for this\n        runner = MockRunner(\n            config=None,\n            adapter=None,\n            node=basic_parsed_source_definition_object,\n            node_index=None,\n            num_nodes=None,\n        )\n        assert not hasattr(basic_parsed_source_definition_object, \"build_path\")\n        runner._handle_generic_exception(Exception(\"bad thing happened\"), ctx=None)\n\n\nclass InheritsFromConfiguredTask(ConfiguredTask):\n    def run(self):\n        pass\n\n\nclass TestConfiguredTask(BaseConfigTest):\n    def tearDown(self):\n        super().tearDown()\n        # These tests will change the directory to the project path,\n        # so it's necessary to change it back at the end.\n        os.chdir(INITIAL_ROOT)\n\n    def test_configured_task_dir_change(self):\n        self.assertEqual(os.getcwd(), INITIAL_ROOT)\n        self.assertNotEqual(INITIAL_ROOT, self.project_dir)\n        InheritsFromConfiguredTask.from_args(self.args)\n        self.assertEqual(os.path.realpath(os.getcwd()), os.path.realpath(self.project_dir))\n\n    def test_configured_task_dir_change_with_bad_path(self):\n        self.args.project_dir = \"bad_path\"\n        with self.assertRaises(dbt_common.exceptions.DbtRuntimeError):\n            InheritsFromConfiguredTask.from_args(self.args)\n"
  },
  {
    "path": "tests/unit/task/test_build.py",
    "content": "from dbt.contracts.graph.nodes import SavedQuery\nfrom dbt.runners import SavedQueryRunner\n\n\ndef test_saved_query_runner_on_skip(saved_query: SavedQuery):\n    runner = SavedQueryRunner(\n        config=None,\n        adapter=None,\n        node=saved_query,\n        node_index=None,\n        num_nodes=None,\n    )\n    # on_skip would work\n    runner.on_skip()\n"
  },
  {
    "path": "tests/unit/task/test_clone.py",
    "content": "from unittest.mock import MagicMock, patch\n\nfrom dbt.flags import get_flags\nfrom dbt.task.clone import CloneTask\n\n\ndef test_clone_task_not_preserve_edges():\n    mock_node_selector = MagicMock()\n    mock_spec = MagicMock()\n    with patch.object(\n        CloneTask, \"get_node_selector\", return_value=mock_node_selector\n    ), patch.object(CloneTask, \"get_selection_spec\", return_value=mock_spec):\n        task = CloneTask(get_flags(), None, None)\n        task.get_graph_queue()\n        # when we get the graph queue, preserve_edges is False\n        mock_node_selector.get_graph_queue.assert_called_with(mock_spec, False)\n"
  },
  {
    "path": "tests/unit/task/test_docs.py",
    "content": "import unittest\nfrom decimal import Decimal\nfrom unittest import mock\n\nfrom dbt.task.docs import generate\n\n\nclass GenerateTest(unittest.TestCase):\n    def setUp(self):\n        self.maxDiff = None\n        self.manifest = mock.MagicMock()\n        self.patcher = mock.patch(\"dbt.task.docs.generate.get_unique_id_mapping\")\n        self.mock_get_unique_id_mapping = self.patcher.start()\n\n    def tearDown(self):\n        self.patcher.stop()\n\n    def map_uids(self, effects):\n        results = {generate.CatalogKey(db, sch, tbl): uid for db, sch, tbl, uid in effects}\n        self.mock_get_unique_id_mapping.return_value = results, {}\n\n    def generate_catalog_dict(self, columns):\n        nodes, sources = generate.Catalog(columns).make_unique_id_map(self.manifest)\n        result = generate.CatalogResults(\n            nodes=nodes,\n            sources=sources,\n            errors=None,\n        )\n        return result.to_dict(omit_none=False)[\"nodes\"]\n\n    def test__unflatten_empty(self):\n        columns = {}\n        expected = {}\n        self.map_uids([])\n\n        result = self.generate_catalog_dict(columns)\n\n        self.mock_get_unique_id_mapping.assert_called_once_with(self.manifest)\n        self.assertEqual(result, expected)\n\n    def test__unflatten_one_column(self):\n        columns = [\n            {\n                \"column_comment\": None,\n                \"column_index\": Decimal(\"1\"),\n                \"column_name\": \"id\",\n                \"column_type\": \"integer\",\n                \"table_comment\": None,\n                \"table_name\": \"test_table\",\n                \"table_schema\": \"test_schema\",\n                \"table_type\": \"BASE TABLE\",\n                \"table_database\": \"test_database\",\n            }\n        ]\n        expected = {\n            \"test.model.test_table\": {\n                \"metadata\": {\n                    \"owner\": None,\n                    \"comment\": None,\n                    \"name\": \"test_table\",\n                    \"type\": \"BASE TABLE\",\n                    \"schema\": \"test_schema\",\n                    \"database\": \"test_database\",\n                },\n                \"columns\": {\n                    \"id\": {\"type\": \"integer\", \"comment\": None, \"index\": 1, \"name\": \"id\"},\n                },\n                \"stats\": {\n                    \"has_stats\": {\n                        \"id\": \"has_stats\",\n                        \"label\": \"Has Stats?\",\n                        \"value\": False,\n                        \"description\": \"Indicates whether there are statistics for this table\",\n                        \"include\": False,\n                    },\n                },\n                \"unique_id\": \"test.model.test_table\",\n            },\n        }\n        self.map_uids([(\"test_database\", \"test_schema\", \"test_table\", \"test.model.test_table\")])\n\n        result = self.generate_catalog_dict(columns)\n\n        self.mock_get_unique_id_mapping.assert_called_once_with(self.manifest)\n        self.assertEqual(result, expected)\n\n    def test__unflatten_multiple_schemas_dbs(self):\n        columns = [\n            {\n                \"column_comment\": None,\n                \"column_index\": Decimal(\"1\"),\n                \"column_name\": \"id\",\n                \"column_type\": \"integer\",\n                \"table_comment\": None,\n                \"table_name\": \"test_table\",\n                \"table_schema\": \"test_schema\",\n                \"table_type\": \"BASE TABLE\",\n                \"table_database\": \"test_database\",\n                \"table_owner\": None,\n            },\n            {\n                \"column_comment\": None,\n                \"column_index\": Decimal(\"2\"),\n                \"column_name\": \"name\",\n                \"column_type\": \"text\",\n                \"table_comment\": None,\n                \"table_name\": \"test_table\",\n                \"table_schema\": \"test_schema\",\n                \"table_type\": \"BASE TABLE\",\n                \"table_database\": \"test_database\",\n                \"table_owner\": None,\n            },\n            {\n                \"column_comment\": None,\n                \"column_index\": Decimal(\"1\"),\n                \"column_name\": \"id\",\n                \"column_type\": \"integer\",\n                \"table_comment\": None,\n                \"table_name\": \"other_test_table\",\n                \"table_schema\": \"test_schema\",\n                \"table_type\": \"BASE TABLE\",\n                \"table_database\": \"test_database\",\n                \"table_owner\": None,\n            },\n            {\n                \"column_comment\": None,\n                \"column_index\": Decimal(\"2\"),\n                \"column_name\": \"email\",\n                \"column_type\": \"character varying\",\n                \"table_comment\": None,\n                \"table_name\": \"other_test_table\",\n                \"table_schema\": \"test_schema\",\n                \"table_type\": \"BASE TABLE\",\n                \"table_database\": \"test_database\",\n                \"table_owner\": None,\n            },\n            {\n                \"column_comment\": None,\n                \"column_index\": Decimal(\"1\"),\n                \"column_name\": \"id\",\n                \"column_type\": \"integer\",\n                \"table_comment\": None,\n                \"table_name\": \"test_table\",\n                \"table_schema\": \"other_test_schema\",\n                \"table_type\": \"BASE TABLE\",\n                \"table_database\": \"test_database\",\n                \"table_owner\": None,\n            },\n            {\n                \"column_comment\": None,\n                \"column_index\": Decimal(\"2\"),\n                \"column_name\": \"name\",\n                \"column_type\": \"text\",\n                \"table_comment\": None,\n                \"table_name\": \"test_table\",\n                \"table_schema\": \"other_test_schema\",\n                \"table_type\": \"BASE TABLE\",\n                \"table_database\": \"test_database\",\n                \"table_owner\": None,\n            },\n            {\n                \"column_comment\": None,\n                \"column_index\": Decimal(\"1\"),\n                \"column_name\": \"id\",\n                \"column_type\": \"integer\",\n                \"table_comment\": None,\n                \"table_name\": \"test_table\",\n                \"table_schema\": \"test_schema\",\n                \"table_type\": \"BASE TABLE\",\n                \"table_database\": \"other_test_database\",\n                \"table_owner\": None,\n            },\n            {\n                \"column_comment\": None,\n                \"column_index\": Decimal(\"2\"),\n                \"column_name\": \"name\",\n                \"column_type\": \"text\",\n                \"table_comment\": None,\n                \"table_name\": \"test_table\",\n                \"table_schema\": \"test_schema\",\n                \"table_type\": \"BASE TABLE\",\n                \"table_database\": \"other_test_database\",\n                \"table_owner\": None,\n            },\n        ]\n        expected = {\n            \"test.model.test_table\": {\n                \"metadata\": {\n                    \"owner\": None,\n                    \"comment\": None,\n                    \"name\": \"test_table\",\n                    \"type\": \"BASE TABLE\",\n                    \"schema\": \"test_schema\",\n                    \"database\": \"test_database\",\n                },\n                \"columns\": {\n                    \"id\": {\"type\": \"integer\", \"comment\": None, \"index\": 1, \"name\": \"id\"},\n                    \"name\": {\n                        \"type\": \"text\",\n                        \"comment\": None,\n                        \"index\": 2,\n                        \"name\": \"name\",\n                    },\n                },\n                \"stats\": {\n                    \"has_stats\": {\n                        \"id\": \"has_stats\",\n                        \"label\": \"Has Stats?\",\n                        \"value\": False,\n                        \"description\": \"Indicates whether there are statistics for this table\",\n                        \"include\": False,\n                    },\n                },\n                \"unique_id\": \"test.model.test_table\",\n            },\n            \"test.model.other_test_table\": {\n                \"metadata\": {\n                    \"owner\": None,\n                    \"comment\": None,\n                    \"name\": \"other_test_table\",\n                    \"type\": \"BASE TABLE\",\n                    \"schema\": \"test_schema\",\n                    \"database\": \"test_database\",\n                },\n                \"columns\": {\n                    \"id\": {\"type\": \"integer\", \"comment\": None, \"index\": 1, \"name\": \"id\"},\n                    \"email\": {\n                        \"type\": \"character varying\",\n                        \"comment\": None,\n                        \"index\": 2,\n                        \"name\": \"email\",\n                    },\n                },\n                \"stats\": {\n                    \"has_stats\": {\n                        \"id\": \"has_stats\",\n                        \"label\": \"Has Stats?\",\n                        \"value\": False,\n                        \"description\": \"Indicates whether there are statistics for this table\",\n                        \"include\": False,\n                    },\n                },\n                \"unique_id\": \"test.model.other_test_table\",\n            },\n            \"test.model.test_table_otherschema\": {\n                \"metadata\": {\n                    \"owner\": None,\n                    \"comment\": None,\n                    \"name\": \"test_table\",\n                    \"type\": \"BASE TABLE\",\n                    \"schema\": \"other_test_schema\",\n                    \"database\": \"test_database\",\n                },\n                \"columns\": {\n                    \"id\": {\"type\": \"integer\", \"comment\": None, \"index\": 1, \"name\": \"id\"},\n                    \"name\": {\n                        \"type\": \"text\",\n                        \"comment\": None,\n                        \"index\": 2,\n                        \"name\": \"name\",\n                    },\n                },\n                \"stats\": {\n                    \"has_stats\": {\n                        \"id\": \"has_stats\",\n                        \"label\": \"Has Stats?\",\n                        \"value\": False,\n                        \"description\": \"Indicates whether there are statistics for this table\",\n                        \"include\": False,\n                    },\n                },\n                \"unique_id\": \"test.model.test_table_otherschema\",\n            },\n            \"test.model.test_table_otherdb\": {\n                \"metadata\": {\n                    \"owner\": None,\n                    \"comment\": None,\n                    \"name\": \"test_table\",\n                    \"type\": \"BASE TABLE\",\n                    \"schema\": \"test_schema\",\n                    \"database\": \"other_test_database\",\n                },\n                \"columns\": {\n                    \"id\": {\"type\": \"integer\", \"comment\": None, \"index\": 1, \"name\": \"id\"},\n                    \"name\": {\n                        \"type\": \"text\",\n                        \"comment\": None,\n                        \"index\": 2,\n                        \"name\": \"name\",\n                    },\n                },\n                \"stats\": {\n                    \"has_stats\": {\n                        \"id\": \"has_stats\",\n                        \"label\": \"Has Stats?\",\n                        \"value\": False,\n                        \"description\": \"Indicates whether there are statistics for this table\",\n                        \"include\": False,\n                    },\n                },\n                \"unique_id\": \"test.model.test_table_otherdb\",\n            },\n        }\n        self.map_uids(\n            [\n                (\"test_database\", \"test_schema\", \"test_table\", \"test.model.test_table\"),\n                (\n                    \"test_database\",\n                    \"test_schema\",\n                    \"other_test_table\",\n                    \"test.model.other_test_table\",\n                ),\n                (\n                    \"test_database\",\n                    \"other_test_schema\",\n                    \"test_table\",\n                    \"test.model.test_table_otherschema\",\n                ),\n                (\n                    \"other_test_database\",\n                    \"test_schema\",\n                    \"test_table\",\n                    \"test.model.test_table_otherdb\",\n                ),\n            ]\n        )\n\n        result = self.generate_catalog_dict(columns)\n\n        self.mock_get_unique_id_mapping.assert_called_once_with(self.manifest)\n        self.assertEqual(result, expected)\n"
  },
  {
    "path": "tests/unit/task/test_freshness.py",
    "content": "import datetime\nfrom unittest import mock\n\nimport pytest\n\nfrom dbt.task.freshness import FreshnessResponse, FreshnessTask\n\n\nclass TestFreshnessTaskMetadataCache:\n    @pytest.fixture(scope=\"class\")\n    def args(self):\n        mock_args = mock.Mock()\n        mock_args.state = None\n        mock_args.defer_state = None\n        mock_args.write_json = None\n\n        return mock_args\n\n    @pytest.fixture(scope=\"class\")\n    def config(self):\n        mock_config = mock.Mock()\n        mock_config.threads = 1\n        mock_config.target_name = \"mock_config_target_name\"\n\n    @pytest.fixture(scope=\"class\")\n    def manifest(self):\n        return mock.Mock()\n\n    @pytest.fixture(scope=\"class\")\n    def source_with_loaded_at_field(self):\n        mock_source = mock.Mock()\n        mock_source.unique_id = \"source_with_loaded_at_field\"\n        mock_source.loaded_at_field = \"loaded_at_field\"\n        return mock_source\n\n    @pytest.fixture(scope=\"class\")\n    def source_no_loaded_at_field(self):\n        mock_source = mock.Mock()\n        mock_source.unique_id = \"source_no_loaded_at_field\"\n        return mock_source\n\n    @pytest.fixture(scope=\"class\")\n    def source_no_loaded_at_field2(self):\n        mock_source = mock.Mock()\n        mock_source.unique_id = \"source_no_loaded_at_field2\"\n        return mock_source\n\n    @pytest.fixture(scope=\"class\")\n    def adapter(self):\n        return mock.Mock()\n\n    @pytest.fixture(scope=\"class\")\n    def freshness_response(self):\n        return FreshnessResponse(\n            max_loaded_at=datetime.datetime(2020, 5, 2),\n            snapshotted_at=datetime.datetime(2020, 5, 4),\n            age=2,\n        )\n\n    def test_populate_metadata_freshness_cache(\n        self, args, config, manifest, adapter, source_no_loaded_at_field, freshness_response\n    ):\n        manifest.sources = {source_no_loaded_at_field.unique_id: source_no_loaded_at_field}\n        adapter.Relation.create_from.return_value = \"source_relation\"\n        adapter.calculate_freshness_from_metadata_batch.return_value = (\n            [],\n            {\"source_relation\": freshness_response},\n        )\n        task = FreshnessTask(args=args, config=config, manifest=manifest)\n\n        task.populate_metadata_freshness_cache(adapter, {source_no_loaded_at_field.unique_id})\n\n        assert task.get_freshness_metadata_cache() == {\"source_relation\": freshness_response}\n\n    def test_populate_metadata_freshness_cache_multiple_sources(\n        self,\n        args,\n        config,\n        manifest,\n        adapter,\n        source_no_loaded_at_field,\n        source_no_loaded_at_field2,\n        freshness_response,\n    ):\n        manifest.sources = {\n            source_no_loaded_at_field.unique_id: source_no_loaded_at_field,\n            source_no_loaded_at_field2.unique_id: source_no_loaded_at_field2,\n        }\n        adapter.Relation.create_from.side_effect = [\"source_relation1\", \"source_relation2\"]\n        adapter.calculate_freshness_from_metadata_batch.return_value = (\n            [],\n            {\"source_relation1\": freshness_response, \"source_relation2\": freshness_response},\n        )\n        task = FreshnessTask(args=args, config=config, manifest=manifest)\n\n        task.populate_metadata_freshness_cache(adapter, {source_no_loaded_at_field.unique_id})\n\n        assert task.get_freshness_metadata_cache() == {\n            \"source_relation1\": freshness_response,\n            \"source_relation2\": freshness_response,\n        }\n\n    def test_populate_metadata_freshness_cache_with_loaded_at_field(\n        self, args, config, manifest, adapter, source_with_loaded_at_field, freshness_response\n    ):\n        manifest.sources = {\n            source_with_loaded_at_field.unique_id: source_with_loaded_at_field,\n        }\n        adapter.Relation.create_from.return_value = \"source_relation\"\n        adapter.calculate_freshness_from_metadata_batch.return_value = (\n            [],\n            {\"source_relation\": freshness_response},\n        )\n        task = FreshnessTask(args=args, config=config, manifest=manifest)\n\n        task.populate_metadata_freshness_cache(adapter, {source_with_loaded_at_field.unique_id})\n\n        assert task.get_freshness_metadata_cache() == {\"source_relation\": freshness_response}\n\n    def test_populate_metadata_freshness_cache_multiple_sources_mixed(\n        self,\n        args,\n        config,\n        manifest,\n        adapter,\n        source_no_loaded_at_field,\n        source_with_loaded_at_field,\n        freshness_response,\n    ):\n        manifest.sources = {\n            source_no_loaded_at_field.unique_id: source_no_loaded_at_field,\n            source_with_loaded_at_field.unique_id: source_with_loaded_at_field,\n        }\n        adapter.Relation.create_from.return_value = \"source_relation\"\n        adapter.calculate_freshness_from_metadata_batch.return_value = (\n            [],\n            {\"source_relation\": freshness_response},\n        )\n        task = FreshnessTask(args=args, config=config, manifest=manifest)\n\n        task.populate_metadata_freshness_cache(adapter, {source_no_loaded_at_field.unique_id})\n\n        assert task.get_freshness_metadata_cache() == {\"source_relation\": freshness_response}\n\n    def test_populate_metadata_freshness_cache_adapter_exception(\n        self, args, config, manifest, adapter, source_no_loaded_at_field, freshness_response\n    ):\n        manifest.sources = {source_no_loaded_at_field.unique_id: source_no_loaded_at_field}\n        adapter.Relation.create_from.return_value = \"source_relation\"\n        adapter.calculate_freshness_from_metadata_batch.side_effect = Exception()\n        task = FreshnessTask(args=args, config=config, manifest=manifest)\n\n        task.populate_metadata_freshness_cache(adapter, {source_no_loaded_at_field.unique_id})\n\n        assert task.get_freshness_metadata_cache() == {}\n"
  },
  {
    "path": "tests/unit/task/test_list.py",
    "content": "from argparse import Namespace\nfrom unittest.mock import patch\n\nfrom dbt.flags import get_flags, set_from_args\nfrom dbt.task.list import ListTask\nfrom dbt_common.events.types import PrintEvent\n\n\ndef test_list_output_results():\n    set_from_args(Namespace(models=None), {})\n    task = ListTask(get_flags(), None, None)\n    results = [\"node1\", \"node2\", \"node3\"]\n    expected_node_results = [\"node1\", \"node2\", \"node3\"]\n\n    with patch(\"dbt.task.list.fire_event\") as mock_fire_event:\n        node_results = task.output_results(results)\n\n    assert node_results == expected_node_results\n    # assert called with PrintEvent type object and message 'node1', 'node2', 'node3'\n    for call_args in mock_fire_event.call_args_list:\n        assert isinstance(call_args[0][0], PrintEvent)\n        assert call_args[0][0].msg in expected_node_results\n\n\nclass TestGetNestedValue:\n    \"\"\"Unit tests for the _get_nested_value method\"\"\"\n\n    def setup_method(self):\n        set_from_args(Namespace(models=None), {})\n        self.task = ListTask(get_flags(), None, None)\n\n    def test_get_nested_value_simple_key(self):\n        \"\"\"Test getting a simple top-level key\"\"\"\n        data = {\"name\": \"test_model\", \"type\": \"model\"}\n        result = self.task._get_nested_value(data, \"name\")\n        assert result == \"test_model\"\n\n    def test_get_nested_value_nested_key(self):\n        \"\"\"Test getting a nested key\"\"\"\n        data = {\"name\": \"test_model\", \"config\": {\"materialized\": \"table\", \"tags\": [\"important\"]}}\n        result = self.task._get_nested_value(data, \"config.materialized\")\n        assert result == \"table\"\n\n    def test_get_nested_value_deep_nested_key(self):\n        \"\"\"Test getting a deeply nested key\"\"\"\n        data = {\n            \"name\": \"test_model\",\n            \"config\": {\"meta\": {\"owner\": \"data-team\", \"contact\": {\"email\": \"team@company.com\"}}},\n        }\n        result = self.task._get_nested_value(data, \"config.meta.owner\")\n        assert result == \"data-team\"\n\n        result = self.task._get_nested_value(data, \"config.meta.contact.email\")\n        assert result == \"team@company.com\"\n\n    def test_get_nested_value_nonexistent_top_level(self):\n        \"\"\"Test getting a non-existent top-level key returns None\"\"\"\n        data = {\"name\": \"test_model\", \"type\": \"model\"}\n        result = self.task._get_nested_value(data, \"nonexistent\")\n        assert result is None\n\n    def test_get_nested_value_nonexistent_nested(self):\n        \"\"\"Test getting a non-existent nested key returns None\"\"\"\n        data = {\"name\": \"test_model\", \"config\": {\"materialized\": \"table\"}}\n        result = self.task._get_nested_value(data, \"config.nonexistent\")\n        assert result is None\n\n    def test_get_nested_value_nonexistent_parent(self):\n        \"\"\"Test getting a nested key where parent doesn't exist returns None\"\"\"\n        data = {\"name\": \"test_model\", \"type\": \"model\"}\n        result = self.task._get_nested_value(data, \"nonexistent.child\")\n        assert result is None\n\n    def test_get_nested_value_non_dict_parent(self):\n        \"\"\"Test getting a nested key where parent is not a dict returns None\"\"\"\n        data = {\"name\": \"test_model\", \"config\": \"not_a_dict\"}\n        result = self.task._get_nested_value(data, \"config.materialized\")\n        assert result is None\n\n    def test_get_nested_value_none_parent(self):\n        \"\"\"Test getting a nested key where parent is None returns None\"\"\"\n        data = {\"name\": \"test_model\", \"config\": None}\n        result = self.task._get_nested_value(data, \"config.materialized\")\n        assert result is None\n\n    def test_get_nested_value_list_value(self):\n        \"\"\"Test getting a nested key that contains a list\"\"\"\n        data = {\"name\": \"test_model\", \"config\": {\"tags\": [\"important\", \"daily\"]}}\n        result = self.task._get_nested_value(data, \"config.tags\")\n        assert result == [\"important\", \"daily\"]\n\n    def test_get_nested_value_dict_value(self):\n        \"\"\"Test getting a nested key that contains a dict\"\"\"\n        data = {\n            \"name\": \"test_model\",\n            \"config\": {\"meta\": {\"owner\": \"data-team\", \"criticality\": \"high\"}},\n        }\n        result = self.task._get_nested_value(data, \"config.meta\")\n        assert result == {\"owner\": \"data-team\", \"criticality\": \"high\"}\n\n\nclass TestGenerateJson:\n    \"\"\"Unit tests for the generate_json method to ensure coverage of nested key logic\"\"\"\n\n    def setup_method(self):\n        set_from_args(Namespace(models=None, output_keys=None), {})\n        self.task = ListTask(get_flags(), None, None)\n\n    def create_mock_node(self, name=\"test_model\", materialized=\"table\", meta=None):\n        \"\"\"Helper to create a mock node with specified properties\"\"\"\n        from unittest.mock import Mock\n\n        node = Mock()\n        node.to_dict.return_value = {\n            \"name\": name,\n            \"resource_type\": \"model\",\n            \"unique_id\": f\"model.test.{name}\",\n            \"config\": {\n                \"materialized\": materialized,\n                \"tags\": [],\n                \"meta\": meta or {},\n            },\n            \"original_file_path\": f\"models/{name}.sql\",\n        }\n        return node\n\n    def test_generate_json_with_nested_keys(self):\n        \"\"\"Test generate_json with nested output keys\"\"\"\n        # Mock args to have nested output keys\n        with patch.object(self.task, \"args\") as mock_args:\n            mock_args.output_keys = [\"name\", \"config.materialized\"]\n\n            # Mock _iterate_selected_nodes to return our test node\n            with patch.object(self.task, \"_iterate_selected_nodes\") as mock_iterate:\n                node = self.create_mock_node(\"test_model\", \"table\")\n                mock_iterate.return_value = [node]\n\n                # Get the result\n                results = list(self.task.generate_json())\n\n                assert len(results) == 1\n                import json\n\n                result_data = json.loads(results[0])\n                assert result_data[\"name\"] == \"test_model\"\n                assert result_data[\"config.materialized\"] == \"table\"\n\n    def test_generate_json_with_nonexistent_nested_keys(self):\n        \"\"\"Test generate_json with non-existent nested keys\"\"\"\n        # Mock args to have non-existent nested key\n        with patch.object(self.task, \"args\") as mock_args:\n            mock_args.output_keys = [\"name\", \"config.nonexistent\"]\n\n            # Mock _iterate_selected_nodes to return our test node\n            with patch.object(self.task, \"_iterate_selected_nodes\") as mock_iterate:\n                node = self.create_mock_node(\"test_model\", \"table\")\n                mock_iterate.return_value = [node]\n\n                # Get the result\n                results = list(self.task.generate_json())\n\n                assert len(results) == 1\n                import json\n\n                result_data = json.loads(results[0])\n                assert result_data[\"name\"] == \"test_model\"\n                # Non-existent key should not be in result\n                assert \"config.nonexistent\" not in result_data\n\n    def test_generate_json_with_mixed_keys(self):\n        \"\"\"Test generate_json with mix of regular and nested keys\"\"\"\n        # Mock args to have mixed keys\n        with patch.object(self.task, \"args\") as mock_args:\n            mock_args.output_keys = [\n                \"name\",\n                \"resource_type\",\n                \"config.materialized\",\n                \"config.meta.owner\",\n            ]\n\n            # Mock _iterate_selected_nodes to return our test node\n            with patch.object(self.task, \"_iterate_selected_nodes\") as mock_iterate:\n                node = self.create_mock_node(\"test_model\", \"incremental\", {\"owner\": \"data-team\"})\n                mock_iterate.return_value = [node]\n\n                # Get the result\n                results = list(self.task.generate_json())\n\n                assert len(results) == 1\n                import json\n\n                result_data = json.loads(results[0])\n                assert result_data[\"name\"] == \"test_model\"\n                assert result_data[\"resource_type\"] == \"model\"\n                assert result_data[\"config.materialized\"] == \"incremental\"\n                assert result_data[\"config.meta.owner\"] == \"data-team\"\n\n    def test_generate_json_with_no_output_keys(self):\n        \"\"\"Test generate_json without output_keys (default behavior)\"\"\"\n        # Mock args to have None output_keys\n        with patch.object(self.task, \"args\") as mock_args:\n            mock_args.output_keys = None\n\n            # Mock _iterate_selected_nodes to return our test node\n            with patch.object(self.task, \"_iterate_selected_nodes\") as mock_iterate:\n                node = self.create_mock_node(\"test_model\", \"table\")\n                mock_iterate.return_value = [node]\n\n                # Get the result\n                results = list(self.task.generate_json())\n\n                assert len(results) == 1\n                import json\n\n                result_data = json.loads(results[0])\n                # Should contain ALLOWED_KEYS\n                for allowed_key in self.task.ALLOWED_KEYS:\n                    if allowed_key in node.to_dict.return_value:\n                        assert allowed_key in result_data\n\n    def test_generate_json_deep_nested_path(self):\n        \"\"\"Test generate_json with deeply nested paths\"\"\"\n        # Mock args to have deep nested key\n        with patch.object(self.task, \"args\") as mock_args:\n            mock_args.output_keys = [\"config.meta.contact.email\"]\n\n            # Mock _iterate_selected_nodes to return our test node\n            with patch.object(self.task, \"_iterate_selected_nodes\") as mock_iterate:\n                node = self.create_mock_node(\n                    \"test_model\", \"table\", {\"contact\": {\"email\": \"team@company.com\"}}\n                )\n                mock_iterate.return_value = [node]\n\n                # Get the result\n                results = list(self.task.generate_json())\n\n                assert len(results) == 1\n                import json\n\n                result_data = json.loads(results[0])\n                assert result_data[\"config.meta.contact.email\"] == \"team@company.com\"\n"
  },
  {
    "path": "tests/unit/task/test_retry.py",
    "content": "from dbt.cli.types import Command\nfrom dbt.task.retry import CMD_DICT, TASK_DICT\n\nEXCLUDED_COMMANDS = {\n    \"clean\",\n    \"debug\",\n    \"deps\",\n    \"freshness\",\n    \"init\",\n    \"list\",\n    \"parse\",\n    \"retry\",\n    \"show\",\n    \"serve\",\n}\n\n\ndef test_task_cmd_dicts():\n    assert TASK_DICT.keys() == CMD_DICT.keys()\n\n\ndef test_exhaustive_commands():\n    assert set(TASK_DICT.keys()).union(EXCLUDED_COMMANDS) == set(i.value.lower() for i in Command)\n"
  },
  {
    "path": "tests/unit/task/test_run.py",
    "content": "from argparse import Namespace\nfrom dataclasses import dataclass\nfrom datetime import datetime\nfrom importlib import import_module\nfrom typing import Optional, Type, Union\nfrom unittest import mock\nfrom unittest.mock import MagicMock, patch\n\nimport pytest\nfrom psycopg2 import DatabaseError\nfrom pytest_mock import MockerFixture\n\nfrom core.dbt.task.run import MicrobatchBatchRunner\nfrom dbt.adapters.contracts.connection import AdapterResponse\nfrom dbt.adapters.postgres import PostgresAdapter\nfrom dbt.artifacts.resources.base import FileHash\nfrom dbt.artifacts.resources.types import NodeType, RunHookType\nfrom dbt.artifacts.resources.v1.components import DependsOn\nfrom dbt.artifacts.resources.v1.config import NodeConfig\nfrom dbt.artifacts.resources.v1.model import ModelConfig\nfrom dbt.artifacts.schemas.results import RunStatus\nfrom dbt.artifacts.schemas.run import RunResult\nfrom dbt.config.runtime import RuntimeConfig\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt.contracts.graph.nodes import HookNode, ModelNode\nfrom dbt.events.types import LogModelResult\nfrom dbt.exceptions import DbtRuntimeError\nfrom dbt.flags import get_flags, set_from_args\nfrom dbt.task.run import MicrobatchModelRunner, ModelRunner, RunTask, _get_adapter_info\nfrom dbt.tests.util import safe_set_invocation_context\nfrom dbt_common.events.base_types import EventLevel\nfrom dbt_common.events.event_catcher import EventCatcher\nfrom dbt_common.events.event_manager_client import add_callback_to_manager\n\n\n@pytest.mark.parametrize(\n    \"exception_to_raise, expected_cancel_connections\",\n    [\n        (SystemExit, True),\n        (KeyboardInterrupt, True),\n        (Exception, False),\n    ],\n)\ndef test_run_task_cancel_connections(\n    exception_to_raise, expected_cancel_connections, runtime_config: RuntimeConfig\n):\n    safe_set_invocation_context()\n\n    def mock_run_queue(*args, **kwargs):\n        raise exception_to_raise(\"Test exception\")\n\n    with patch.object(RunTask, \"run_queue\", mock_run_queue), patch.object(\n        RunTask, \"_cancel_connections\"\n    ) as mock_cancel_connections:\n\n        set_from_args(Namespace(write_json=False), None)\n        task = RunTask(\n            get_flags(),\n            runtime_config,\n            None,\n        )\n        with pytest.raises(exception_to_raise):\n            task.execute_nodes()\n        assert mock_cancel_connections.called == expected_cancel_connections\n\n\ndef test_run_task_preserve_edges():\n    mock_node_selector = MagicMock()\n    mock_spec = MagicMock()\n    with patch.object(RunTask, \"get_node_selector\", return_value=mock_node_selector), patch.object(\n        RunTask, \"get_selection_spec\", return_value=mock_spec\n    ):\n        task = RunTask(get_flags(), None, None)\n        task.get_graph_queue()\n        # when we get the graph queue, preserve_edges is True\n        mock_node_selector.get_graph_queue.assert_called_with(mock_spec, True)\n\n\ndef test_tracking_fails_safely_for_missing_adapter():\n    assert {} == _get_adapter_info(None, {})\n\n\ndef test_adapter_info_tracking():\n    mock_run_result = MagicMock()\n    mock_run_result.node = MagicMock()\n    mock_run_result.node.config = {}\n    assert _get_adapter_info(PostgresAdapter, mock_run_result) == {\n        \"model_adapter_details\": {},\n        \"adapter_name\": PostgresAdapter.__name__.split(\"Adapter\")[0].lower(),\n        \"adapter_version\": import_module(\"dbt.adapters.postgres.__version__\").version,\n        \"base_adapter_version\": import_module(\"dbt.adapters.__about__\").version,\n    }\n\n\nclass TestModelRunner:\n    @pytest.fixture\n    def log_model_result_catcher(self) -> EventCatcher:\n        catcher = EventCatcher(event_to_catch=LogModelResult)\n        add_callback_to_manager(catcher.catch)\n        return catcher\n\n    @pytest.fixture\n    def model_runner(\n        self,\n        postgres_adapter: PostgresAdapter,\n        table_model: ModelNode,\n        runtime_config: RuntimeConfig,\n    ) -> ModelRunner:\n        return ModelRunner(\n            config=runtime_config,\n            adapter=postgres_adapter,\n            node=table_model,\n            node_index=1,\n            num_nodes=1,\n        )\n\n    @pytest.fixture\n    def run_result(self, table_model: ModelNode) -> RunResult:\n        return RunResult(\n            status=RunStatus.Success,\n            timing=[],\n            thread_id=\"an_id\",\n            execution_time=0,\n            adapter_response={},\n            message=\"It did it\",\n            failures=None,\n            batch_results=None,\n            node=table_model,\n        )\n\n    def test_print_result_line(\n        self,\n        log_model_result_catcher: EventCatcher,\n        model_runner: ModelRunner,\n        run_result: RunResult,\n    ) -> None:\n        # Check `print_result_line` with \"successful\" RunResult\n        model_runner.print_result_line(run_result)\n        assert len(log_model_result_catcher.caught_events) == 1\n        assert log_model_result_catcher.caught_events[0].info.level == EventLevel.INFO\n        assert log_model_result_catcher.caught_events[0].data.status == run_result.message\n\n        # reset event catcher\n        log_model_result_catcher.flush()\n\n        # Check `print_result_line` with \"error\" RunResult\n        run_result.status = RunStatus.Error\n        model_runner.print_result_line(run_result)\n        assert len(log_model_result_catcher.caught_events) == 1\n        assert log_model_result_catcher.caught_events[0].info.level == EventLevel.ERROR\n        assert log_model_result_catcher.caught_events[0].data.status == EventLevel.ERROR\n\n    @pytest.mark.skip(\n        reason=\"Default and adapter macros aren't being appropriately populated, leading to a runtime error\"\n    )\n    def test_execute(\n        self, table_model: ModelNode, manifest: Manifest, model_runner: ModelRunner\n    ) -> None:\n        model_runner.execute(model=table_model, manifest=manifest)\n        # TODO: Assert that the model was executed\n\n\nclass TestMicrobatchModelRunner:\n    @pytest.fixture\n    def model_runner(\n        self,\n        postgres_adapter: PostgresAdapter,\n        table_model: ModelNode,\n        runtime_config: RuntimeConfig,\n    ) -> MicrobatchModelRunner:\n        return MicrobatchModelRunner(\n            config=runtime_config,\n            adapter=postgres_adapter,\n            node=table_model,\n            node_index=1,\n            num_nodes=1,\n        )\n\n    @pytest.fixture\n    def batch_runner(\n        self,\n        postgres_adapter: PostgresAdapter,\n        table_model: ModelNode,\n        runtime_config: RuntimeConfig,\n    ) -> MicrobatchBatchRunner:\n        return MicrobatchBatchRunner(\n            config=runtime_config,\n            adapter=postgres_adapter,\n            node=table_model,\n            node_index=1,\n            num_nodes=1,\n            batch_idx=0,\n            batches=[],\n            relation_exists=False,\n            incremental_batch=False,\n        )\n\n    @pytest.mark.parametrize(\n        \"has_relation,relation_type,materialized,full_refresh_config,full_refresh_flag,expectation\",\n        [\n            (False, \"table\", \"incremental\", None, False, False),\n            (True, \"other\", \"incremental\", None, False, False),\n            (True, \"table\", \"other\", None, False, False),\n            # model config takes precendence\n            (True, \"table\", \"incremental\", True, False, False),\n            # model config takes precendence\n            (True, \"table\", \"incremental\", True, True, False),\n            # model config takes precendence\n            (True, \"table\", \"incremental\", False, False, True),\n            # model config takes precendence\n            (True, \"table\", \"incremental\", False, True, True),\n            # model config is none, so opposite flag value\n            (True, \"table\", \"incremental\", None, True, False),\n            # model config is none, so opposite flag value\n            (True, \"table\", \"incremental\", None, False, True),\n        ],\n    )\n    def test__is_incremental(\n        self,\n        mocker: MockerFixture,\n        model_runner: MicrobatchModelRunner,\n        has_relation: bool,\n        relation_type: str,\n        materialized: str,\n        full_refresh_config: Optional[bool],\n        full_refresh_flag: bool,\n        expectation: bool,\n    ) -> None:\n\n        # Setup adapter relation getting\n        @dataclass\n        class RelationInfo:\n            database: str = \"database\"\n            schema: str = \"schema\"\n            name: str = \"name\"\n\n        @dataclass\n        class Relation:\n            type: str\n\n        model_runner.adapter = mocker.Mock()\n        model_runner.adapter.Relation.create_from.return_value = RelationInfo()\n\n        if has_relation:\n            model_runner.adapter.get_relation.return_value = Relation(type=relation_type)\n        else:\n            model_runner.adapter.get_relation.return_value = None\n\n        # Set ModelRunner configs\n        model_runner.config.args = Namespace(FULL_REFRESH=full_refresh_flag)\n\n        # Create model with configs\n        model = model_runner.node\n        model.config = ModelConfig(materialized=materialized, full_refresh=full_refresh_config)\n\n        # Assert result of _is_incremental\n        assert model_runner._is_incremental(model) == expectation\n\n    @pytest.mark.parametrize(\n        \"adapter_microbatch_concurrency,has_relation,concurrent_batches,has_this,expectation\",\n        [\n            (True, True, None, False, True),\n            (True, True, None, True, False),\n            (True, True, True, False, True),\n            (True, True, True, True, True),\n            (True, True, False, False, False),\n            (True, True, False, True, False),\n            (True, False, None, False, False),\n            (True, False, None, True, False),\n            (True, False, True, False, False),\n            (True, False, True, True, False),\n            (True, False, False, False, False),\n            (True, False, False, True, False),\n            (False, True, None, False, False),\n            (False, True, None, True, False),\n            (False, True, True, False, False),\n            (False, True, True, True, False),\n            (False, True, False, False, False),\n            (False, True, False, True, False),\n            (False, False, None, False, False),\n            (False, False, None, True, False),\n            (False, False, True, False, False),\n            (False, False, True, True, False),\n            (False, False, False, False, False),\n            (False, False, False, True, False),\n        ],\n    )\n    def test_should_run_in_parallel(\n        self,\n        mocker: MockerFixture,\n        batch_runner: MicrobatchBatchRunner,\n        adapter_microbatch_concurrency: bool,\n        has_relation: bool,\n        concurrent_batches: Optional[bool],\n        has_this: bool,\n        expectation: bool,\n    ) -> None:\n        batch_runner.node._has_this = has_this\n        batch_runner.node.config = ModelConfig(concurrent_batches=concurrent_batches)\n        batch_runner.relation_exists = has_relation\n\n        mocked_supports = mocker.patch.object(batch_runner.adapter, \"supports\")\n        mocked_supports.return_value = adapter_microbatch_concurrency\n\n        # Assert result of should_run_in_parallel\n        assert batch_runner.should_run_in_parallel() == expectation\n\n    def test_get_microbatch_builder_uses_original_invocation_time_on_retry(\n        self,\n        mocker: MockerFixture,\n        model_runner: MicrobatchModelRunner,\n    ) -> None:\n        \"\"\"When retrying, get_microbatch_builder should use the original invocation\n        time from the previous run rather than the current invocation time.\"\"\"\n        original_time = datetime(2025, 3, 21, 7, 55, 0)\n        current_time = datetime(2025, 3, 25, 1, 4, 0)\n\n        # Set up a mock parent task with original_invocation_started_at\n        mock_parent = mocker.Mock(spec=RunTask)\n        mock_parent.original_invocation_started_at = original_time\n        model_runner._parent_task = mock_parent\n\n        # Mock _is_incremental to avoid adapter calls\n        mocker.patch.object(model_runner, \"_is_incremental\", return_value=True)\n\n        # Mock get_invocation_started_at to return the \"current\" (retry) time\n        mocker.patch(\n            \"dbt.task.run.get_invocation_started_at\",\n            return_value=current_time,\n        )\n\n        model = model_runner.node\n        model.config.materialized = \"incremental\"\n        model.config.incremental_strategy = \"microbatch\"\n        model.config.batch_size = \"day\"\n        model.config.begin = \"2024-12-01\"\n        model.config.event_time = \"_event_date\"\n        model_runner.config.args = Namespace(\n            EVENT_TIME_START=None, EVENT_TIME_END=None, SAMPLE=None\n        )\n\n        builder = model_runner.get_microbatch_builder(model)\n        assert builder.default_end_time == original_time\n\n    def test_get_microbatch_builder_uses_current_time_without_retry(\n        self,\n        mocker: MockerFixture,\n        model_runner: MicrobatchModelRunner,\n    ) -> None:\n        \"\"\"When not retrying (normal run), get_microbatch_builder should use\n        the current invocation time.\"\"\"\n        current_time = datetime(2025, 3, 25, 1, 4, 0)\n\n        # Set up a mock parent task with no original_invocation_started_at\n        mock_parent = mocker.Mock(spec=RunTask)\n        mock_parent.original_invocation_started_at = None\n        model_runner._parent_task = mock_parent\n\n        # Mock _is_incremental to avoid adapter calls\n        mocker.patch.object(model_runner, \"_is_incremental\", return_value=True)\n\n        mocker.patch(\n            \"dbt.task.run.get_invocation_started_at\",\n            return_value=current_time,\n        )\n\n        model = model_runner.node\n        model.config.materialized = \"incremental\"\n        model.config.incremental_strategy = \"microbatch\"\n        model.config.batch_size = \"day\"\n        model.config.begin = \"2024-12-01\"\n        model.config.event_time = \"_event_date\"\n        model_runner.config.args = Namespace(\n            EVENT_TIME_START=None, EVENT_TIME_END=None, SAMPLE=None\n        )\n\n        builder = model_runner.get_microbatch_builder(model)\n        assert builder.default_end_time == current_time\n\n\nclass TestRunTask:\n    @pytest.fixture\n    def hook_node(self) -> HookNode:\n        return HookNode(\n            package_name=\"test\",\n            path=\"/root/x/path.sql\",\n            original_file_path=\"/root/path.sql\",\n            language=\"sql\",\n            raw_code=\"select * from wherever\",\n            name=\"foo\",\n            resource_type=NodeType.Operation,\n            unique_id=\"model.test.foo\",\n            fqn=[\"test\", \"models\", \"foo\"],\n            refs=[],\n            sources=[],\n            metrics=[],\n            depends_on=DependsOn(),\n            description=\"\",\n            database=\"test_db\",\n            schema=\"test_schema\",\n            alias=\"bar\",\n            tags=[],\n            config=NodeConfig(),\n            index=None,\n            checksum=FileHash.from_contents(\"\"),\n            unrendered_config={},\n        )\n\n    @pytest.mark.parametrize(\n        \"error_to_raise,expected_result\",\n        [\n            (None, RunStatus.Success),\n            (DbtRuntimeError, RunStatus.Error),\n            (DatabaseError, RunStatus.Error),\n            (KeyboardInterrupt, KeyboardInterrupt),\n        ],\n    )\n    def test_safe_run_hooks(\n        self,\n        mocker: MockerFixture,\n        runtime_config: RuntimeConfig,\n        manifest: Manifest,\n        hook_node: HookNode,\n        error_to_raise: Optional[Type[Exception]],\n        expected_result: Union[RunStatus, Type[Exception]],\n    ):\n        mocker.patch(\"dbt.task.run.RunTask.get_hooks_by_type\").return_value = [hook_node]\n        mocker.patch(\"dbt.task.run.RunTask.get_hook_sql\").return_value = hook_node.raw_code\n\n        flags = mock.Mock()\n        flags.state = None\n        flags.defer_state = None\n\n        run_task = RunTask(\n            args=flags,\n            config=runtime_config,\n            manifest=manifest,\n        )\n\n        adapter = mock.Mock()\n        adapter_execute = mock.Mock()\n        adapter_execute.return_value = (AdapterResponse(_message=\"Success\"), None)\n\n        if error_to_raise:\n            adapter_execute.side_effect = error_to_raise(\"Oh no!\")\n\n        adapter.execute = adapter_execute\n\n        try:\n            result = run_task.safe_run_hooks(\n                adapter=adapter,\n                hook_type=RunHookType.End,\n                extra_context={},\n            )\n            assert isinstance(expected_result, RunStatus)\n            assert result == expected_result\n        except BaseException as e:\n            assert not isinstance(expected_result, RunStatus)\n            assert issubclass(expected_result, BaseException)\n            assert type(e) == expected_result\n"
  },
  {
    "path": "tests/unit/task/test_test.py",
    "content": "import agate\nimport pytest\n\nfrom dbt.task.test import list_rows_from_table\n\n\nclass TestListRowsFromTable:\n    @pytest.mark.parametrize(\n        \"agate_table_cols,agate_table_rows,expected_list_rows\",\n        [\n            ([\"a\", \"b\", \"c\"], [], [[\"a\", \"b\", \"c\"]]),  # no rows\n            ([\"a\", \"b\", \"c\"], [[1, 2, 3]], [[\"a\", \"b\", \"c\"], [1, 2, 3]]),  # single row, no nulls\n            (\n                [\"a\", \"b\", \"c\"],\n                [[1, 2, 3], [2, 3, 4]],\n                [[\"a\", \"b\", \"c\"], [1, 2, 3], [2, 3, 4]],\n            ),  # multiple rows\n            (\n                [\"a\", \"b\", \"c\"],\n                [[None, 2, 3], [2, None, 4]],\n                [[\"a\", \"b\", \"c\"], [None, 2, 3], [2, None, 4]],\n            ),  # multiple rows, with nulls\n        ],\n    )\n    def test_list_rows_from_table_no_sort(\n        self, agate_table_cols, agate_table_rows, expected_list_rows\n    ):\n        table = agate.Table(rows=agate_table_rows, column_names=agate_table_cols)\n\n        list_rows = list_rows_from_table(table)\n        assert list_rows == expected_list_rows\n\n    @pytest.mark.parametrize(\n        \"agate_table_cols,agate_table_rows,expected_list_rows\",\n        [\n            ([\"a\", \"b\", \"c\"], [], [[\"a\", \"b\", \"c\"]]),  # no rows\n            ([\"a\", \"b\", \"c\"], [[1, 2, 3]], [[\"a\", \"b\", \"c\"], [1, 2, 3]]),  # single row, no nulls\n            (\n                [\"a\", \"b\", \"c\"],\n                [[1, 2, 3], [2, 3, 4]],\n                [[\"a\", \"b\", \"c\"], [1, 2, 3], [2, 3, 4]],\n            ),  # multiple rows, in order\n            (\n                [\"a\", \"b\", \"c\"],\n                [[2, 3, 4], [1, 2, 3]],\n                [[\"a\", \"b\", \"c\"], [1, 2, 3], [2, 3, 4]],\n            ),  # multiple rows, out of order\n            (\n                [\"a\", \"b\", \"c\"],\n                [[None, 2, 3], [2, 3, 4]],\n                [[\"a\", \"b\", \"c\"], [2, 3, 4], [None, 2, 3]],\n            ),  # multiple rows, out of order with nulls in first position\n            (\n                [\"a\", \"b\", \"c\"],\n                [[4, 5, 6], [1, None, 3]],\n                [[\"a\", \"b\", \"c\"], [1, None, 3], [4, 5, 6]],\n            ),  # multiple rows, out of order with null in non-first position\n            (\n                [\"a\", \"b\", \"c\"],\n                [[None, 5, 6], [1, None, 3]],\n                [[\"a\", \"b\", \"c\"], [1, None, 3], [None, 5, 6]],\n            ),  # multiple rows, out of order with nulls in many positions\n        ],\n    )\n    def test_list_rows_from_table_with_sort(\n        self, agate_table_cols, agate_table_rows, expected_list_rows\n    ):\n        table = agate.Table(rows=agate_table_rows, column_names=agate_table_cols)\n\n        list_rows = list_rows_from_table(table, sort=True)\n        assert list_rows == expected_list_rows\n"
  },
  {
    "path": "tests/unit/test_artifact_upload.py",
    "content": "import os\nimport unittest\nimport uuid\nfrom unittest import mock\nfrom unittest.mock import MagicMock, call, patch\n\nfrom dbt.constants import MANIFEST_FILE_NAME, RUN_RESULTS_FILE_NAME\nfrom dbt.exceptions import DbtProjectError\nfrom dbt.utils.artifact_upload import (\n    ArtifactUploadConfig,\n    _retry_with_backoff,\n    add_artifact_produced,\n    upload_artifacts,\n)\nfrom dbt_common.exceptions import DbtBaseException\n\n\nclass TestArtifactUploadConfig(unittest.TestCase):\n    def setUp(self):\n        self.config = ArtifactUploadConfig(\n            tenant_hostname=\"test-tenant.dbt.com\",\n            DBT_CLOUD_TOKEN=\"test-token\",\n            DBT_CLOUD_ACCOUNT_ID=\"1234\",\n            DBT_CLOUD_ENVIRONMENT_ID=\"5678\",\n        )\n        self.test_invocation_id = str(uuid.uuid4())\n\n    def test_get_ingest_url(self):\n        expected_url = (\n            \"https://test-tenant.dbt.com/api/private/accounts/1234/environments/5678/ingests/\"\n        )\n        self.assertEqual(self.config.get_ingest_url(), expected_url)\n\n    def test_get_complete_url(self):\n        ingest_id = \"9012\"\n        expected_url = (\n            \"https://test-tenant.dbt.com/api/private/accounts/1234/environments/5678/ingests/9012/\"\n        )\n        self.assertEqual(self.config.get_complete_url(ingest_id), expected_url)\n\n    def test_get_headers_with_invocation_id(self):\n        expected_headers = {\n            \"Accept\": \"application/json\",\n            \"X-Invocation-Id\": self.test_invocation_id,\n            \"Authorization\": \"Token test-token\",\n        }\n        self.assertEqual(\n            self.config.get_headers(invocation_id=self.test_invocation_id),\n            expected_headers,\n        )\n\n    def test_get_headers_without_invocation_id(self):\n        with mock.patch(\"uuid.uuid4\") as mock_uuid:\n            mock_uuid.return_value = uuid.UUID(\"12345678-1234-1234-1234-123456789012\")\n            expected_headers = {\n                \"Accept\": \"application/json\",\n                \"X-Invocation-Id\": \"12345678-1234-1234-1234-123456789012\",\n                \"Authorization\": \"Token test-token\",\n            }\n            self.assertEqual(self.config.get_headers(), expected_headers)\n\n\nclass TestRetryWithBackoff(unittest.TestCase):\n    def setUp(self):\n        self.time_sleep_patcher = patch(\"dbt.utils.artifact_upload.time.sleep\")\n        self.mock_sleep = self.time_sleep_patcher.start()\n\n    def tearDown(self):\n        self.time_sleep_patcher.stop()\n\n    def test_successful_first_try(self):\n        \"\"\"Test that function returns immediately on success.\"\"\"\n        func = MagicMock(return_value=(True, \"success\"))\n        result = _retry_with_backoff(\"operation\", func)\n        self.assertEqual(result, \"success\")\n        func.assert_called_once()\n        self.mock_sleep.assert_not_called()\n\n    def test_successful_after_retry(self):\n        \"\"\"Test that function retries and succeeds.\"\"\"\n        mock_response = MagicMock()\n        mock_response.status_code = 503\n        func = MagicMock(side_effect=[(False, mock_response), (True, \"success\")])\n        result = _retry_with_backoff(\"operation\", func)\n        self.assertEqual(result, \"success\")\n        self.assertEqual(func.call_count, 2)\n        self.mock_sleep.assert_called_once_with(1)  # First retry delay\n\n    def test_failure_after_max_retries(self):\n        \"\"\"Test that function raises exception after max retries.\"\"\"\n        mock_response = MagicMock()\n        mock_response.status_code = 503\n        func = MagicMock(return_value=(False, mock_response))\n        with self.assertRaises(DbtBaseException) as context:\n            _retry_with_backoff(\"operation\", func, max_retries=3)\n        self.assertIn(\"Error operation\", str(context.exception))\n        self.assertEqual(func.call_count, 4)\n        # Sleep should be called twice (after first and second attempts)\n        self.assertEqual(self.mock_sleep.call_count, 3)\n        self.assertEqual(\n            self.mock_sleep.call_args_list, [call(1), call(2), call(4)]\n        )  # Exponential backoff\n\n    def test_non_retryable_status_code(self):\n        \"\"\"Test that non-retryable status codes raise immediately.\"\"\"\n        mock_response = MagicMock()\n        mock_response.status_code = 400  # Not in retry_codes\n        func = MagicMock(return_value=(False, mock_response))\n        with self.assertRaises(DbtBaseException) as context:\n            _retry_with_backoff(\"operation\", func)\n        self.assertIn(\"Error operation\", str(context.exception))\n        self.assertEqual(func.call_count, 1)\n        self.mock_sleep.assert_not_called()\n\n    def test_request_exception_handling(self):\n        \"\"\"Test that RequestException is caught and retried.\"\"\"\n        import requests\n\n        func = MagicMock(\n            side_effect=[requests.RequestException(\"Network error\"), (True, \"success\")]\n        )\n        result = _retry_with_backoff(\"operation\", func)\n        self.assertEqual(result, \"success\")\n        self.assertEqual(func.call_count, 2)\n        self.mock_sleep.assert_called_once_with(1)\n\n    def test_request_exception_max_retries(self):\n        \"\"\"Test that RequestException raises after max retries.\"\"\"\n        import requests\n\n        func = MagicMock(side_effect=requests.RequestException(\"Network error\"))\n        with self.assertRaises(DbtBaseException) as context:\n            _retry_with_backoff(\"operation\", func, max_retries=3)\n        self.assertIn(\"Error operation: Network error\", str(context.exception))\n        self.assertEqual(func.call_count, 4)\n        self.assertEqual(self.mock_sleep.call_count, 3)\n\n    def test_custom_retry_codes(self):\n        \"\"\"Test that custom retry codes are respected.\"\"\"\n        mock_response = MagicMock()\n        mock_response.status_code = 429  # Too Many Requests\n        func = MagicMock(side_effect=[(False, mock_response), (True, \"success\")])\n        result = _retry_with_backoff(\"operation\", func, retry_codes=[429, 503])\n        self.assertEqual(result, \"success\")\n        self.assertEqual(func.call_count, 2)\n        self.mock_sleep.assert_called_once_with(1)\n\n\nclass TestUploadArtifacts(unittest.TestCase):\n    def setUp(self):\n        self.project_dir = \"/fake/project/dir\"\n        self.target_path = \"/fake/project/dir/target\"\n        self.command = \"run\"\n\n        # Create patchers\n        self.load_project_patcher = patch(\"dbt.utils.artifact_upload.load_project\")\n        self.zipfile_patcher = patch(\"dbt.utils.artifact_upload.zipfile.ZipFile\")\n        self.requests_post_patcher = patch(\"dbt.utils.artifact_upload.requests.post\")\n        self.requests_put_patcher = patch(\"dbt.utils.artifact_upload.requests.put\")\n        self.requests_patch_patcher = patch(\"dbt.utils.artifact_upload.requests.patch\")\n        self.open_patcher = patch(\"builtins.open\", mock.mock_open(read_data=b\"test data\"))\n        self.fire_event_patcher = patch(\"dbt.utils.artifact_upload.fire_event\")\n        self.retry_patcher = patch(\"dbt.utils.artifact_upload._retry_with_backoff\")\n        self.time_sleep_patcher = patch(\"dbt.utils.artifact_upload.time.sleep\")\n\n        # Start patchers\n        self.mock_load_project = self.load_project_patcher.start()\n        self.mock_zipfile = self.zipfile_patcher.start()\n        self.mock_requests_post = self.requests_post_patcher.start()\n        self.mock_requests_put = self.requests_put_patcher.start()\n        self.mock_requests_patch = self.requests_patch_patcher.start()\n        self.mock_open = self.open_patcher.start()\n        self.mock_fire_event = self.fire_event_patcher.start()\n        self.mock_retry = self.retry_patcher.start()\n        self.mock_sleep = self.time_sleep_patcher.start()\n\n        # Configure mocks\n        self.mock_project = MagicMock()\n        self.mock_project.dbt_cloud = {\"tenant_hostname\": \"test-tenant\"}\n        self.mock_load_project.return_value = self.mock_project\n\n        # Mock response for POST request (create ingest)\n        self.mock_post_response = MagicMock()\n        self.mock_post_response.status_code = 200\n        self.mock_post_response.json.return_value = {\n            \"data\": {\"id\": \"ingest123\", \"upload_url\": \"https://test-upload-url.com\"}\n        }\n        self.mock_requests_post.return_value = self.mock_post_response\n\n        # Mock response for PUT request (upload artifacts)\n        self.mock_put_response = MagicMock()\n        self.mock_put_response.status_code = 200\n        self.mock_requests_put.return_value = self.mock_put_response\n\n        # Mock response for PATCH request (complete ingest)\n        self.mock_patch_response = MagicMock()\n        self.mock_patch_response.status_code = 204\n        self.mock_requests_patch.return_value = self.mock_patch_response\n\n        # Mock retry to pass through to the first result\n        self.mock_retry.side_effect = lambda operation_name, func, max_retries=3: func()[1]\n\n        # Setup the env var for the test\n        self.original_token = os.environ.get(\"DBT_CLOUD_TOKEN\")\n        self.original_account_id = os.environ.get(\"DBT_CLOUD_ACCOUNT_ID\")\n        self.original_environment_id = os.environ.get(\"DBT_CLOUD_ENVIRONMENT_ID\")\n\n        os.environ[\"DBT_CLOUD_TOKEN\"] = \"test-token\"\n        os.environ[\"DBT_CLOUD_ACCOUNT_ID\"] = \"1234\"\n        os.environ[\"DBT_CLOUD_ENVIRONMENT_ID\"] = \"5678\"\n\n    def tearDown(self):\n        self.load_project_patcher.stop()\n        self.zipfile_patcher.stop()\n        self.requests_post_patcher.stop()\n        self.requests_put_patcher.stop()\n        self.requests_patch_patcher.stop()\n        self.open_patcher.stop()\n        self.fire_event_patcher.stop()\n        self.retry_patcher.stop()\n        self.time_sleep_patcher.stop()\n        if self.original_token:\n            os.environ[\"DBT_CLOUD_TOKEN\"] = self.original_token\n        if self.original_account_id:\n            os.environ[\"DBT_CLOUD_ACCOUNT_ID\"] = self.original_account_id\n        if self.original_environment_id:\n            os.environ[\"DBT_CLOUD_ENVIRONMENT_ID\"] = self.original_environment_id\n\n    def test_upload_artifacts_successful_upload(self):\n        # Set up mock for ZipFile context manager\n        mock_zipfile_instance = MagicMock()\n        self.mock_zipfile.return_value.__enter__.return_value = mock_zipfile_instance\n        add_artifact_produced(os.path.join(self.target_path, MANIFEST_FILE_NAME))\n        add_artifact_produced(os.path.join(self.target_path, RUN_RESULTS_FILE_NAME))\n\n        # Call the function\n        upload_artifacts(self.project_dir, self.target_path, self.command)\n\n        # Verify the project was loaded\n        self.mock_load_project.assert_called_once_with(\n            self.project_dir, version_check=False, profile=mock.ANY, cli_vars=None\n        )\n\n        # Verify zip file was created and artifacts were added\n        self.mock_zipfile.assert_called_once_with(\"target.zip\", \"w\")\n        expected_artifact_calls = [\n            call(f\"{self.target_path}/{RUN_RESULTS_FILE_NAME}\", RUN_RESULTS_FILE_NAME),\n            call(f\"{self.target_path}/{MANIFEST_FILE_NAME}\", MANIFEST_FILE_NAME),\n        ]\n        mock_zipfile_instance.write.assert_has_calls(expected_artifact_calls, any_order=True)\n\n        # Verify retry was called for each step\n        self.assertEqual(self.mock_retry.call_count, 3)\n        retry_calls = [call_args[0][0] for call_args in self.mock_retry.call_args_list]\n        self.assertIn(\"creating ingest request\", retry_calls)\n        self.assertIn(\"uploading artifacts\", retry_calls)\n        self.assertIn(\"completing ingest\", retry_calls)\n\n        # Verify fire_event was called with ArtifactUploadSuccess\n        success_event_call = [\n            call\n            for call in self.mock_fire_event.call_args_list\n            if \"completed successfully\" in call[0][0].msg\n        ]\n        self.assertTrue(len(success_event_call) > 0)\n\n    def test_upload_artifacts_default_target_path(self):\n        # Call the function with target_path=None\n        mock_zipfile_instance = MagicMock()\n        self.mock_zipfile.return_value.__enter__.return_value = mock_zipfile_instance\n        add_artifact_produced(os.path.join(self.target_path, MANIFEST_FILE_NAME))\n        add_artifact_produced(os.path.join(self.target_path, RUN_RESULTS_FILE_NAME))\n\n        upload_artifacts(self.project_dir, None, self.command)\n\n        # Verify the default target path was used\n        expected_artifact_calls = [\n            call(f\"{self.target_path}/{RUN_RESULTS_FILE_NAME}\", RUN_RESULTS_FILE_NAME),\n            call(f\"{self.target_path}/{MANIFEST_FILE_NAME}\", MANIFEST_FILE_NAME),\n        ]\n        mock_zipfile_instance.write.assert_has_calls(expected_artifact_calls, any_order=True)\n\n    def test_upload_artifacts_missing_tenant_config(self):\n        # Set up project without dbt_cloud config\n        self.mock_project.dbt_cloud = {}\n        add_artifact_produced(os.path.join(self.target_path, MANIFEST_FILE_NAME))\n\n        # Verify that the function raises an exception\n        with self.assertRaises(DbtProjectError) as context:\n            upload_artifacts(self.project_dir, self.target_path, self.command)\n\n        self.assertIn(\"tenant_hostname not found\", str(context.exception))\n        self.mock_retry.assert_not_called()\n\n    def test_upload_artifacts_with_retry_failures(self):\n        # Set up mock for ZipFile context manager\n        mock_zipfile_instance = MagicMock()\n        self.mock_zipfile.return_value.__enter__.return_value = mock_zipfile_instance\n\n        # Make retry raise exceptions for each step\n        self.mock_retry.side_effect = [\n            DbtBaseException(\"Error creating ingest request: Mock failure\"),\n            DbtBaseException(\"Error uploading artifacts: Mock failure\"),\n            DbtBaseException(\"Error completing ingest: Mock failure\"),\n        ]\n        add_artifact_produced(os.path.join(self.target_path, MANIFEST_FILE_NAME))\n\n        # Test each step failing\n        # 1. Create ingest failure\n        with self.assertRaises(DbtBaseException) as context:\n            upload_artifacts(self.project_dir, self.target_path, self.command)\n        self.assertIn(\"Error creating ingest request\", str(context.exception))\n        self.mock_retry.reset_mock()\n\n        # Reset the side effect for the next test\n        self.mock_retry.side_effect = [\n            self.mock_post_response,  # First call succeeds\n            DbtBaseException(\"Error uploading artifacts: Mock failure\"),\n            DbtBaseException(\"Error completing ingest: Mock failure\"),\n        ]\n\n        # 2. Upload failure\n        with self.assertRaises(DbtBaseException) as context:\n            upload_artifacts(self.project_dir, self.target_path, self.command)\n        self.assertIn(\"Error uploading artifacts\", str(context.exception))\n        self.mock_retry.reset_mock()\n\n        # Reset the side effect for the next test\n        self.mock_retry.side_effect = [\n            self.mock_post_response,  # First call succeeds\n            self.mock_put_response,  # Second call succeeds\n            DbtBaseException(\"Error completing ingest: Mock failure\"),\n        ]\n\n        # 3. Complete failure\n        with self.assertRaises(DbtBaseException) as context:\n            upload_artifacts(self.project_dir, self.target_path, self.command)\n        self.assertIn(\"Error completing ingest\", str(context.exception))\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "tests/unit/test_behavior_flags.py",
    "content": "import pytest\n\nfrom dbt.tracking import (\n    disable_tracking,\n    initialize_from_flags,\n    track_behavior_change_warn,\n)\nfrom dbt_common.behavior_flags import Behavior\nfrom dbt_common.events.event_manager_client import (\n    add_callback_to_manager,\n    cleanup_event_logger,\n)\n\n\n@pytest.fixture\ndef snowplow_tracker(mocker):\n    # initialize `active_user` without writing the cookie to disk\n    initialize_from_flags(True, \"\")\n    mocker.patch(\"dbt.tracking.User.set_cookie\").return_value = {\"id\": 42}\n\n    # add the relevant callback to the event manager\n    add_callback_to_manager(track_behavior_change_warn)\n\n    # don't make a call, catch the request\n    # to avoid confusion, this is snowplow_tracker's track, not our wrapper that's also named track\n    snowplow_tracker = mocker.patch(\"dbt.tracking.tracker.track\")\n\n    yield snowplow_tracker\n\n    # teardown\n    cleanup_event_logger()\n    disable_tracking()\n\n\ndef test_false_evaluation_triggers_snowplow_tracking(snowplow_tracker):\n    behavior = Behavior(\n        [{\"name\": \"my_flag\", \"default\": False, \"description\": \"This is a false flag.\"}], {}\n    )\n    if behavior.my_flag:\n        # trigger a False evaluation\n        assert False, \"This flag should evaluate to false and skip this line\"\n    assert snowplow_tracker.called\n\n\ndef test_true_evaluation_does_not_trigger_snowplow_tracking(snowplow_tracker):\n    behavior = Behavior(\n        [{\"name\": \"my_flag\", \"default\": True, \"description\": \"This is a true flag.\"}], {}\n    )\n    if behavior.my_flag:\n        pass\n    else:\n        # trigger a True evaluation\n        assert False, \"This flag should evaluate to false and skip this line\"\n    assert not snowplow_tracker.called\n\n\ndef test_false_evaluation_does_not_trigger_snowplow_tracking_when_disabled(snowplow_tracker):\n    disable_tracking()\n\n    behavior = Behavior(\n        [{\"name\": \"my_flag\", \"default\": False, \"description\": \"This is a false flag.\"}], {}\n    )\n    if behavior.my_flag:\n        # trigger a False evaluation\n        assert False, \"This flag should evaluate to false and skip this line\"\n    assert not snowplow_tracker.called\n"
  },
  {
    "path": "tests/unit/test_compilation.py",
    "content": "import os\nimport tempfile\nfrom queue import Empty\nfrom unittest import mock\n\nimport pytest\n\nfrom dbt.compilation import Graph, Linker\nfrom dbt.graph.cli import parse_difference\nfrom dbt.graph.queue import GraphQueue\nfrom dbt.graph.selector import NodeSelector\n\n\ndef _mock_manifest(nodes):\n    config = mock.MagicMock(enabled=True)\n    manifest = mock.MagicMock(\n        nodes={\n            n: mock.MagicMock(\n                unique_id=n,\n                package_name=\"pkg\",\n                name=n,\n                empty=False,\n                config=config,\n                fqn=[\"pkg\", n],\n                is_versioned=False,\n            )\n            for n in nodes\n        }\n    )\n    manifest.expect.side_effect = lambda n: mock.MagicMock(unique_id=n)\n    return manifest\n\n\nclass TestLinker:\n    @pytest.fixture\n    def linker(self) -> Linker:\n        return Linker()\n\n    def test_linker_add_node(self, linker: Linker) -> None:\n        expected_nodes = [\"A\", \"B\", \"C\"]\n        for node in expected_nodes:\n            linker.add_node(node)\n\n        actual_nodes = linker.nodes()\n        for node in expected_nodes:\n            assert node in actual_nodes\n\n        assert len(actual_nodes) == len(expected_nodes)\n\n    def test_linker_write_graph(self, linker: Linker) -> None:\n        expected_nodes = [\"A\", \"B\", \"C\"]\n        for node in expected_nodes:\n            linker.add_node(node)\n\n        manifest = _mock_manifest(\"ABC\")\n        (fd, fname) = tempfile.mkstemp()\n        os.close(fd)\n        try:\n            linker.write_graph(fname, manifest)\n            assert os.path.exists(fname)\n        finally:\n            os.unlink(fname)\n\n    def assert_would_join(self, queue: GraphQueue) -> None:\n        \"\"\"test join() without timeout risk\"\"\"\n        assert queue.inner.unfinished_tasks == 0\n\n    def _get_graph_queue(\n        self,\n        manifest,\n        linker: Linker,\n        include=None,\n        exclude=None,\n    ) -> GraphQueue:\n        graph = Graph(linker.graph)\n        selector = NodeSelector(graph, manifest)\n        # TODO:  The \"eager\" string below needs to be replaced with programatic access\n        #  to the default value for the indirect selection parameter in\n        # dbt.cli.params.indirect_selection\n        #\n        # Doing that is actually a little tricky, so I'm punting it to a new ticket GH #6397\n        spec = parse_difference(include, exclude)\n        return selector.get_graph_queue(spec)\n\n    def test_linker_add_dependency(self, linker: Linker) -> None:\n        actual_deps = [(\"A\", \"B\"), (\"A\", \"C\"), (\"B\", \"C\")]\n\n        for l, r in actual_deps:\n            linker.dependency(l, r)\n\n        queue = self._get_graph_queue(_mock_manifest(\"ABC\"), linker)\n\n        got = queue.get(block=False)\n        assert got.unique_id == \"C\"\n        with pytest.raises(Empty):\n            queue.get(block=False)\n        assert not queue.empty()\n        queue.mark_done(\"C\")\n        assert not queue.empty()\n\n        got = queue.get(block=False)\n        assert got.unique_id == \"B\"\n        with pytest.raises(Empty):\n            queue.get(block=False)\n        assert not queue.empty()\n        queue.mark_done(\"B\")\n        assert not queue.empty()\n\n        got = queue.get(block=False)\n        assert got.unique_id == \"A\"\n        with pytest.raises(Empty):\n            queue.get(block=False)\n        assert queue.empty()\n        queue.mark_done(\"A\")\n        self.assert_would_join(queue)\n        assert queue.empty()\n\n    def test_linker_add_disjoint_dependencies(self, linker: Linker) -> None:\n        actual_deps = [(\"A\", \"B\")]\n        additional_node = \"Z\"\n\n        for l, r in actual_deps:\n            linker.dependency(l, r)\n        linker.add_node(additional_node)\n\n        queue = self._get_graph_queue(_mock_manifest(\"ABCZ\"), linker)\n        # the first one we get must be B, it has the longest dep chain\n        first = queue.get(block=False)\n        assert first.unique_id == \"B\"\n        assert not queue.empty()\n        queue.mark_done(\"B\")\n        assert not queue.empty()\n\n        second = queue.get(block=False)\n        assert second.unique_id in {\"A\", \"Z\"}\n        assert not queue.empty()\n        queue.mark_done(second.unique_id)\n        assert not queue.empty()\n\n        third = queue.get(block=False)\n        assert third.unique_id in {\"A\", \"Z\"}\n        with pytest.raises(Empty):\n            queue.get(block=False)\n        assert second.unique_id != third.unique_id\n        assert queue.empty()\n        queue.mark_done(third.unique_id)\n        self.assert_would_join(queue)\n        assert queue.empty()\n\n    def test_linker_dependencies_limited_to_some_nodes(self, linker: Linker) -> None:\n        actual_deps = [(\"A\", \"B\"), (\"B\", \"C\"), (\"C\", \"D\")]\n\n        for l, r in actual_deps:\n            linker.dependency(l, r)\n\n        queue = self._get_graph_queue(_mock_manifest(\"ABCD\"), linker, [\"B\"])\n        got = queue.get(block=False)\n        assert got.unique_id == \"B\"\n        assert queue.empty()\n        queue.mark_done(\"B\")\n        self.assert_would_join(queue)\n\n        queue_2 = queue = self._get_graph_queue(_mock_manifest(\"ABCD\"), linker, [\"A\", \"B\"])\n        got = queue_2.get(block=False)\n        assert got.unique_id == \"B\"\n        assert not queue_2.empty()\n        with pytest.raises(Empty):\n            queue_2.get(block=False)\n        queue_2.mark_done(\"B\")\n        assert not queue_2.empty()\n\n        got = queue_2.get(block=False)\n        assert got.unique_id == \"A\"\n        assert queue_2.empty()\n        with pytest.raises(Empty):\n            queue_2.get(block=False)\n        assert queue_2.empty()\n        queue_2.mark_done(\"A\")\n        self.assert_would_join(queue_2)\n\n    def test__find_cycles__cycles(self, linker: Linker) -> None:\n        actual_deps = [(\"A\", \"B\"), (\"B\", \"C\"), (\"C\", \"A\")]\n\n        for l, r in actual_deps:\n            linker.dependency(l, r)\n\n        assert linker.find_cycles() is not None\n\n    def test__find_cycles__no_cycles(self, linker: Linker) -> None:\n        actual_deps = [(\"A\", \"B\"), (\"B\", \"C\"), (\"C\", \"D\")]\n\n        for l, r in actual_deps:\n            linker.dependency(l, r)\n\n        assert linker.find_cycles() is None\n"
  },
  {
    "path": "tests/unit/test_compilation_threading.py",
    "content": "import threading\n\nfrom dbt.artifacts.resources import Contract\nfrom dbt.contracts.files import FileHash\nfrom dbt.contracts.graph.nodes import DependsOn, ModelConfig, ModelNode\nfrom dbt.node_types import NodeType\n\n\ndef _make_model_node(unique_id=\"model.test.foo\", compiled=False, extra_ctes=None):\n    return ModelNode(\n        package_name=\"test\",\n        path=\"/root/models/foo.sql\",\n        original_file_path=\"models/foo.sql\",\n        language=\"sql\",\n        raw_code=\"select 1\",\n        name=unique_id.split(\".\")[-1],\n        resource_type=NodeType.Model,\n        unique_id=unique_id,\n        fqn=[\"test\", \"models\", unique_id.split(\".\")[-1]],\n        refs=[],\n        sources=[],\n        metrics=[],\n        depends_on=DependsOn(),\n        description=\"\",\n        primary_key=[],\n        database=\"test_db\",\n        schema=\"test_schema\",\n        alias=unique_id.split(\".\")[-1],\n        tags=[],\n        config=ModelConfig(),\n        contract=Contract(),\n        meta={},\n        compiled=compiled,\n        extra_ctes=extra_ctes or [],\n        extra_ctes_injected=False,\n        compiled_code=\"select 1\" if compiled else None,\n        checksum=FileHash.from_contents(\"\"),\n        unrendered_config={},\n    )\n\n\nclass TestConcurrentEphemeralCompilation:\n    def test_concurrent_ephemeral_compilation(self):\n        \"\"\"Two threads compile nodes sharing an ephemeral dep.\n        The ephemeral should only be compiled once (compiled flag set once).\"\"\"\n        ephemeral = _make_model_node(unique_id=\"model.test.ephemeral\", compiled=False)\n        compile_count = {\"count\": 0}\n        lock = threading.Lock()\n        barrier = threading.Barrier(2)\n\n        def simulate_compile():\n            barrier.wait(timeout=5)\n            with ephemeral._lock:\n                if ephemeral.compiled is True and ephemeral.extra_ctes_injected is True:\n                    return\n                # Simulate compilation\n                with lock:\n                    compile_count[\"count\"] += 1\n                ephemeral.compiled = True\n                ephemeral.compiled_code = \"select 1\"\n                ephemeral.extra_ctes_injected = True\n\n        threads = [threading.Thread(target=simulate_compile) for _ in range(2)]\n        for t in threads:\n            t.start()\n        for t in threads:\n            t.join(timeout=10)\n\n        assert (\n            compile_count[\"count\"] == 1\n        ), f\"Ephemeral compiled {compile_count['count']} times, expected 1\"\n        assert ephemeral.compiled is True\n        assert ephemeral.extra_ctes_injected is True\n\n\nclass TestNoDeadlockOnRecursiveLocking:\n    def test_recursive_lock_pattern_does_not_deadlock(self):\n        \"\"\"Simulate the lock acquisition pattern from _recursively_prepend_ctes\n        for an ephemeral chain: model_a refs ephemeral_b.\n\n        The real code acquires ephemeral_b._lock for compilation, releases it,\n        then re-acquires ephemeral_b._lock for CTE injection during the\n        recursive call. If the recursion happened *inside* the first lock,\n        this would deadlock with a non-reentrant Lock. This test verifies\n        the current code structure avoids that.\"\"\"\n        model_a = _make_model_node(unique_id=\"model.test.a\", compiled=True)\n        ephemeral_b = _make_model_node(unique_id=\"model.test.b\", compiled=False)\n\n        deadlocked = {\"value\": False}\n\n        def simulate_recursively_prepend_ctes():\n            # -- Processing model_a's extra_ctes, found ephemeral_b --\n\n            # Critical section A: compile ephemeral_b (scoped to just compilation)\n            needs_recursion = False\n            with ephemeral_b._lock:\n                if not ephemeral_b.compiled:\n                    ephemeral_b.compiled = True\n                    ephemeral_b.compiled_code = \"select 1\"\n                    needs_recursion = True\n\n            # Recursive call for ephemeral_b happens OUTSIDE the lock above.\n            # Inside that recursive call, we'd hit critical section B for\n            # ephemeral_b (CTE injection). This would deadlock if we were\n            # still inside the `with ephemeral_b._lock` above.\n            if needs_recursion:\n                # Simulate the CTE injection lock from the recursive call\n                acquired = ephemeral_b._lock.acquire(timeout=2)\n                if not acquired:\n                    deadlocked[\"value\"] = True\n                    return\n                ephemeral_b.extra_ctes_injected = True\n                ephemeral_b._lock.release()\n\n            # Critical section B for model_a (CTE injection)\n            acquired = model_a._lock.acquire(timeout=2)\n            if not acquired:\n                deadlocked[\"value\"] = True\n                return\n            model_a.extra_ctes_injected = True\n            model_a._lock.release()\n\n        t = threading.Thread(target=simulate_recursively_prepend_ctes)\n        t.start()\n        t.join(timeout=5)\n\n        assert not t.is_alive(), \"Thread is still alive — deadlock detected\"\n        assert not deadlocked[\"value\"], \"Failed to acquire lock — possible deadlock\"\n        assert ephemeral_b.compiled is True\n        assert ephemeral_b.extra_ctes_injected is True\n        assert model_a.extra_ctes_injected is True\n\n\nclass TestLockSerialization:\n    def test_lock_excluded_from_serialization(self):\n        \"\"\"Serialize a node and assert _lock is not in the output.\"\"\"\n        node = _make_model_node(compiled=True)\n        node.extra_ctes_injected = True\n        dct = node.to_dict()\n        assert \"_lock\" not in dct\n\n    def test_lock_restored_after_deserialization(self):\n        \"\"\"Round-trip serialize/deserialize, assert _lock is a working Lock.\"\"\"\n        node = _make_model_node(compiled=True)\n        node.extra_ctes_injected = True\n        dct = node.to_dict()\n        restored = ModelNode.from_dict(dct)\n        assert hasattr(restored, \"_lock\")\n        assert isinstance(restored._lock, type(threading.Lock()))\n        # Verify the lock actually works\n        assert restored._lock.acquire(timeout=1)\n        restored._lock.release()\n\n    def test_lock_survives_pickle_roundtrip(self):\n        \"\"\"Pickle/unpickle a node, assert _lock is a working Lock.\"\"\"\n        import pickle\n\n        node = _make_model_node(compiled=True)\n        node.extra_ctes_injected = True\n        data = pickle.dumps(node)\n        restored = pickle.loads(data)\n        assert hasattr(restored, \"_lock\")\n        assert isinstance(restored._lock, type(threading.Lock()))\n        assert restored._lock.acquire(timeout=1)\n        restored._lock.release()\n"
  },
  {
    "path": "tests/unit/test_deprecations.py",
    "content": "import pytest\n\nimport dbt.deprecations as deprecations\nfrom dbt.events.types import ProjectFlagsMovedDeprecation\nfrom dbt_common.events.event_catcher import EventCatcher\nfrom dbt_common.events.event_manager_client import add_callback_to_manager\nfrom dbt_common.events.types import Note\n\n\n@pytest.fixture(scope=\"function\")\ndef active_deprecations():\n    deprecations.reset_deprecations()\n    assert len(deprecations.active_deprecations) == 0\n\n    yield deprecations.active_deprecations\n\n    deprecations.reset_deprecations()\n\n\n@pytest.fixture(scope=\"function\")\ndef buffered_deprecations():\n    deprecations.buffered_deprecations.clear()\n    assert not deprecations.buffered_deprecations\n\n    yield deprecations.buffered_deprecations\n\n    deprecations.buffered_deprecations.clear()\n\n\ndef test_buffer_deprecation(active_deprecations, buffered_deprecations):\n    deprecations.buffer(\"project-flags-moved\")\n\n    assert len(active_deprecations) == 0\n    assert len(buffered_deprecations) == 1\n\n\ndef test_fire_buffered_deprecations(active_deprecations, buffered_deprecations):\n    deprecations.buffer(\"project-flags-moved\")\n    deprecations.fire_buffered_deprecations()\n\n    assert \"project-flags-moved\" in active_deprecations\n    assert len(buffered_deprecations) == 0\n\n\ndef test_can_reset_active_deprecations():\n    deprecations.warn(\"project-flags-moved\")\n    assert \"project-flags-moved\" in deprecations.active_deprecations\n\n    deprecations.reset_deprecations()\n    assert \"project-flags-moved\" not in deprecations.active_deprecations\n\n\ndef test_number_of_occurances_is_tracked():\n    assert \"project-flags-moved\" not in deprecations.active_deprecations\n\n    deprecations.warn(\"project-flags-moved\")\n    assert \"project-flags-moved\" in deprecations.active_deprecations\n    assert deprecations.active_deprecations[\"project-flags-moved\"] == 1\n\n    deprecations.warn(\"project-flags-moved\")\n    assert \"project-flags-moved\" in deprecations.active_deprecations\n    assert deprecations.active_deprecations[\"project-flags-moved\"] == 2\n\n\nclass PreviewedDeprecation(deprecations.DBTDeprecation):\n    _name = \"previewed-deprecation\"\n    _event = \"ProjectFlagsMovedDeprecation\"\n    _is_preview = True\n\n\nclass TestPreviewDeprecation:\n\n    @pytest.fixture(scope=\"class\", autouse=True)\n    def deprecations_list_and_deprecations(self):\n        deprecations.deprecations_list.append(PreviewedDeprecation())\n        deprecations.deprecations[\"previewed-deprecation\"] = PreviewedDeprecation()\n\n        yield\n\n        for dep in deprecations.deprecations_list:\n            if dep._name == \"previewed-deprecation\":\n                deprecations.deprecations_list.remove(dep)\n                break\n        deprecations.deprecations.pop(\"previewed-deprecation\")\n\n    def test_preview_deprecation(self):\n        pfmd_catcher = EventCatcher(event_to_catch=ProjectFlagsMovedDeprecation)\n        add_callback_to_manager(pfmd_catcher.catch)\n        note_catcher = EventCatcher(event_to_catch=Note)\n        add_callback_to_manager(note_catcher.catch)\n\n        deprecations.warn(\n            \"previewed-deprecation\",\n        )\n        assert \"previewed-deprecation\" not in deprecations.active_deprecations\n        assert len(pfmd_catcher.caught_events) == 0\n        assert len(note_catcher.caught_events) == 1\n"
  },
  {
    "path": "tests/unit/test_env_vars.py",
    "content": "import os\nfrom unittest import mock\n\nfrom dbt.deprecations import EnvironmentVariableNamespaceDeprecation as EVND\nfrom dbt.deprecations import active_deprecations\nfrom dbt.env_vars import KNOWN_ENGINE_ENV_VARS, validate_engine_env_vars\nfrom dbt.events.types import EnvironmentVariableNamespaceDeprecation\nfrom dbt.tests.util import safe_set_invocation_context\nfrom dbt_common.events.event_catcher import EventCatcher\nfrom dbt_common.events.event_manager_client import add_callback_to_manager\n\n\n@mock.patch.dict(\n    os.environ,\n    {\n        \"DBT_ENGINE_PARTIAL_PARSE\": \"False\",\n        \"DBT_ENGINE_MY_CUSTOM_ENV_VAR_FOR_TESTING\": \"True\",\n    },\n)\ndef test_validate_engine_env_vars():\n    safe_set_invocation_context()\n    event_catcher = EventCatcher(event_to_catch=EnvironmentVariableNamespaceDeprecation)\n    add_callback_to_manager(event_catcher.catch)\n\n    validate_engine_env_vars()\n    # If it's zero, then we _failed_ to notice the deprecation instance (and we should look why the custom engine env var wasn't noticed)\n    # If it's more than one, then we're getting too many deprecation instances (and we should check what the other env vars identified were)\n    assert active_deprecations[EVND().name] == 1\n    assert (\n        \"DBT_ENGINE_MY_CUSTOM_ENV_VAR_FOR_TESTING\" == event_catcher.caught_events[0].data.env_var\n    )\n\n\ndef test_engine_env_vars_with_old_names_has_not_increased():\n    engine_env_vars_with_old_names = sum(\n        1 for env_var in KNOWN_ENGINE_ENV_VARS if env_var.old_name is not None\n    )\n\n    # This failing means we either:\n    # 1. incorrectly created a new engine environment variable without using the `DBT_ENGINE` prefix\n    # 2. we've identified, and added, an existing but previously unknown engine env var to the _ADDITIONAL_ENGINE_ENV_VARS list.\n    # 3. we've _removed_ an existing engine env var with an old name (unlikely)\n    #\n    # In the case of (1), we should correct the new engine environent variable name\n    # In the case of (2), we should increase the number here.\n    # In the case of (3), we should decrease the number here.\n    assert (\n        engine_env_vars_with_old_names == 65\n    ), \"We've added a new engine env var _without_ using the new naming scheme\"\n"
  },
  {
    "path": "tests/unit/test_events.py",
    "content": "import logging\nimport re\nfrom typing import TypeVar\n\nimport pytest\n\nfrom dbt.adapters.events import types as adapter_types\nfrom dbt.adapters.events.logging import AdapterLogger\nfrom dbt.artifacts.schemas.results import RunStatus, TimingInfo\nfrom dbt.artifacts.schemas.run import RunResult\nfrom dbt.events import types as core_types\nfrom dbt.events.base_types import (\n    CoreBaseEvent,\n    DebugLevel,\n    DynamicLevel,\n    ErrorLevel,\n    InfoLevel,\n    TestLevel,\n    WarnLevel,\n)\nfrom dbt.task.printer import print_run_end_messages\nfrom dbt_common.events import types\nfrom dbt_common.events.base_types import msg_from_base_event\nfrom dbt_common.events.event_manager import EventManager, TestEventManager\nfrom dbt_common.events.event_manager_client import ctx_set_event_manager\nfrom dbt_common.events.functions import msg_to_dict, msg_to_json\nfrom dbt_common.events.helpers import get_json_string_utcnow\n\n\n# takes in a class and finds any subclasses for it\ndef get_all_subclasses(cls):\n    all_subclasses = []\n    for subclass in cls.__subclasses__():\n        if subclass not in [TestLevel, DebugLevel, WarnLevel, InfoLevel, ErrorLevel, DynamicLevel]:\n            all_subclasses.append(subclass)\n        all_subclasses.extend(get_all_subclasses(subclass))\n    return set(all_subclasses)\n\n\nclass TestAdapterLogger:\n    # this interface is documented for adapter maintainers to plug into\n    # so we should test that it at the very least doesn't explode.\n    def test_basic_adapter_logging_interface(self):\n        logger = AdapterLogger(\"dbt_tests\")\n        logger.debug(\"debug message\")\n        logger.info(\"info message\")\n        logger.warning(\"warning message\")\n        logger.error(\"error message\")\n        logger.exception(\"exception message\")\n        logger.critical(\"exception message\")\n\n    # python loggers allow deferring string formatting via this signature:\n    def test_formatting(self):\n        logger = AdapterLogger(\"dbt_tests\")\n        # tests that it doesn't throw\n        logger.debug(\"hello {}\", \"world\")\n\n        # enters lower in the call stack to test that it formats correctly\n        event = adapter_types.AdapterEventDebug(\n            name=\"dbt_tests\", base_msg=\"hello {}\", args=[\"world\"]\n        )\n        assert \"hello world\" in event.message()\n\n        # tests that it doesn't throw\n        logger.debug(\"1 2 {}\", \"3\")\n\n        # enters lower in the call stack to test that it formats correctly\n        event = adapter_types.AdapterEventDebug(name=\"dbt_tests\", base_msg=\"1 2 {}\", args=[3])\n        assert \"1 2 3\" in event.message()\n\n        # tests that it doesn't throw\n        logger.debug(\"boop{x}boop\")\n\n        # enters lower in the call stack to test that it formats correctly\n        # in this case it's that we didn't attempt to replace anything since there\n        # were no args passed after the initial message\n        event = adapter_types.AdapterEventDebug(name=\"dbt_tests\", base_msg=\"boop{x}boop\", args=[])\n        assert \"boop{x}boop\" in event.message()\n\n        # ensure AdapterLogger and subclasses makes all base_msg members\n        # of type string; when someone writes logger.debug(a) where a is\n        # any non-string object\n        event = adapter_types.AdapterEventDebug(name=\"dbt_tests\", base_msg=[1, 2, 3], args=[3])\n        assert isinstance(event.base_msg, str)\n\n        event = core_types.JinjaLogDebug(msg=[1, 2, 3])\n        assert isinstance(event.msg, str)\n\n    def test_set_adapter_dependency_log_level(self):\n        logger = AdapterLogger(\"dbt_tests\")\n        package_log = logging.getLogger(\"test_package_log\")\n        logger.set_adapter_dependency_log_level(\"test_package_log\", \"DEBUG\")\n        package_log.debug(\"debug message\")\n\n\nclass TestEventCodes:\n\n    # checks to see if event codes are duplicated to keep codes singluar and clear.\n    # also checks that event codes follow correct namming convention ex. E001\n    def test_event_codes(self):\n        all_concrete = get_all_subclasses(CoreBaseEvent)\n        all_codes = set()\n\n        for event_cls in all_concrete:\n            code = event_cls.code(event_cls)\n            # must be in the form 1 capital letter, 3 digits\n            assert re.match(\"^[A-Z][0-9]{3}\", code)\n            # cannot have been used already\n            assert (\n                code not in all_codes\n            ), f\"{code} is assigned more than once. Check types.py for duplicates.\"\n            all_codes.add(code)\n\n\nsample_values = [\n    # N.B. Events instantiated here include the module prefix in order to\n    # avoid having the entire list twice in the code.\n    # A - pre-project loading\n    core_types.MainReportVersion(version=\"\"),\n    core_types.MainReportArgs(args={}),\n    core_types.MainTrackingUserState(user_state=\"\"),\n    core_types.MissingProfileTarget(profile_name=\"\", target_name=\"\"),\n    core_types.InvalidOptionYAML(option_name=\"vars\"),\n    core_types.LogDbtProjectError(),\n    core_types.LogDbtProfileError(),\n    core_types.StarterProjectPath(dir=\"\"),\n    core_types.ConfigFolderDirectory(dir=\"\"),\n    core_types.NoSampleProfileFound(adapter=\"\"),\n    core_types.ProfileWrittenWithSample(name=\"\", path=\"\"),\n    core_types.ProfileWrittenWithTargetTemplateYAML(name=\"\", path=\"\"),\n    core_types.ProfileWrittenWithProjectTemplateYAML(name=\"\", path=\"\"),\n    core_types.SettingUpProfile(),\n    core_types.InvalidProfileTemplateYAML(),\n    core_types.ProjectNameAlreadyExists(name=\"\"),\n    core_types.ProjectCreated(project_name=\"\"),\n    # D - Deprecations ======================\n    core_types.PackageRedirectDeprecation(old_name=\"\", new_name=\"\"),\n    core_types.PackageInstallPathDeprecation(),\n    core_types.ConfigSourcePathDeprecation(deprecated_path=\"\", exp_path=\"\"),\n    core_types.ConfigDataPathDeprecation(deprecated_path=\"\", exp_path=\"\"),\n    adapter_types.AdapterDeprecationWarning(old_name=\"\", new_name=\"\"),\n    core_types.MetricAttributesRenamed(metric_name=\"\"),\n    core_types.ExposureNameDeprecation(exposure=\"\"),\n    core_types.InternalDeprecation(name=\"\", reason=\"\", suggested_action=\"\", version=\"\"),\n    core_types.EnvironmentVariableRenamed(old_name=\"\", new_name=\"\"),\n    core_types.ConfigLogPathDeprecation(deprecated_path=\"\"),\n    core_types.ConfigTargetPathDeprecation(deprecated_path=\"\"),\n    adapter_types.CollectFreshnessReturnSignature(),\n    core_types.TestsConfigDeprecation(deprecated_path=\"\", exp_path=\"\"),\n    core_types.ProjectFlagsMovedDeprecation(),\n    core_types.SpacesInResourceNameDeprecation(unique_id=\"\", level=\"\"),\n    core_types.ResourceNamesWithSpacesDeprecation(\n        count_invalid_names=1, show_debug_hint=True, level=\"\"\n    ),\n    core_types.PackageMaterializationOverrideDeprecation(\n        package_name=\"my_package\", materialization_name=\"view\"\n    ),\n    core_types.SourceFreshnessProjectHooksNotRun(),\n    core_types.MFTimespineWithoutYamlConfigurationDeprecation(),\n    core_types.MFCumulativeTypeParamsDeprecation(),\n    core_types.MicrobatchMacroOutsideOfBatchesDeprecation(),\n    core_types.GenericJSONSchemaValidationDeprecation(violation=\"\", key_path=\"\", file=\"\"),\n    core_types.UnexpectedJinjaBlockDeprecation(msg=\"\", file=\"\"),\n    core_types.DuplicateYAMLKeysDeprecation(duplicate_description=\"\", file=\"\"),\n    core_types.CustomTopLevelKeyDeprecation(msg=\"\", file=\"\"),\n    core_types.CustomKeyInConfigDeprecation(key=\"\", key_path=\"\", file=\"\"),\n    core_types.CustomKeyInObjectDeprecation(key=\"\", key_path=\"\", file=\"\"),\n    core_types.DeprecationsSummary(summaries=[], show_all_hint=True),\n    core_types.CustomOutputPathInSourceFreshnessDeprecation(path=\"\"),\n    core_types.SourceOverrideDeprecation(file=\"\", source_name=\"\"),\n    core_types.PropertyMovedToConfigDeprecation(key=\"\", key_path=\"\", file=\"\"),\n    core_types.WEOIncludeExcludeDeprecation(found_include=True, found_exclude=True),\n    core_types.ModelParamUsageDeprecation(),\n    core_types.EnvironmentVariableNamespaceDeprecation(env_var=\"\", reserved_prefix=\"\"),\n    core_types.MissingPlusPrefixDeprecation(key=\"\", key_path=\"\", file=\"\"),\n    core_types.ArgumentsPropertyInGenericTestDeprecation(test_name=\"\"),\n    core_types.MissingArgumentsPropertyInGenericTestDeprecation(test_name=\"\"),\n    core_types.ModulesItertoolsUsageDeprecation(),\n    core_types.DuplicateNameDistinctNodeTypesDeprecation(\n        resource_name=\"\", package_name=\"\", unique_id1=\"\", unique_id2=\"\"\n    ),\n    core_types.TimeDimensionsRequireGranularityDeprecation(msg=\"\"),\n    core_types.GenericSemanticLayerDeprecation(msg=\"\"),\n    core_types.GenerateSchemaNameNullValueDeprecation(resource_unique_id=\"\"),\n    # E - DB Adapter ======================\n    adapter_types.AdapterEventDebug(),\n    adapter_types.AdapterEventInfo(),\n    adapter_types.AdapterEventWarning(),\n    adapter_types.AdapterEventError(),\n    adapter_types.AdapterRegistered(adapter_name=\"dbt-awesome\", adapter_version=\"1.2.3\"),\n    adapter_types.NewConnection(conn_type=\"\", conn_name=\"\"),\n    adapter_types.ConnectionReused(conn_name=\"\"),\n    adapter_types.ConnectionLeftOpenInCleanup(conn_name=\"\"),\n    adapter_types.ConnectionClosedInCleanup(conn_name=\"\"),\n    adapter_types.RollbackFailed(conn_name=\"\"),\n    adapter_types.ConnectionClosed(conn_name=\"\"),\n    adapter_types.ConnectionLeftOpen(conn_name=\"\"),\n    adapter_types.Rollback(conn_name=\"\"),\n    adapter_types.CacheMiss(conn_name=\"\", database=\"\", schema=\"\"),\n    adapter_types.ListRelations(database=\"\", schema=\"\"),\n    adapter_types.ConnectionUsed(conn_type=\"\", conn_name=\"\"),\n    adapter_types.SQLQuery(conn_name=\"\", sql=\"\"),\n    adapter_types.SQLQueryStatus(status=\"\", elapsed=0.1),\n    adapter_types.SQLCommit(conn_name=\"\"),\n    adapter_types.ColTypeChange(\n        orig_type=\"\",\n        new_type=\"\",\n        table={\"database\": \"\", \"schema\": \"\", \"identifier\": \"\"},\n    ),\n    adapter_types.SchemaCreation(relation={\"database\": \"\", \"schema\": \"\", \"identifier\": \"\"}),\n    adapter_types.SchemaDrop(relation={\"database\": \"\", \"schema\": \"\", \"identifier\": \"\"}),\n    adapter_types.CacheAction(\n        action=\"adding_relation\",\n        ref_key={\"database\": \"\", \"schema\": \"\", \"identifier\": \"\"},\n        ref_key_2={\"database\": \"\", \"schema\": \"\", \"identifier\": \"\"},\n    ),\n    adapter_types.CacheDumpGraph(before_after=\"before\", action=\"rename\", dump=dict()),\n    adapter_types.AdapterImportError(exc=\"\"),\n    adapter_types.PluginLoadError(exc_info=\"\"),\n    adapter_types.NewConnectionOpening(connection_state=\"\"),\n    adapter_types.CodeExecution(conn_name=\"\", code_content=\"\"),\n    adapter_types.CodeExecutionStatus(status=\"\", elapsed=0.1),\n    adapter_types.CatalogGenerationError(exc=\"\"),\n    adapter_types.WriteCatalogFailure(num_exceptions=0),\n    adapter_types.CatalogWritten(path=\"\"),\n    adapter_types.CannotGenerateDocs(),\n    adapter_types.BuildingCatalog(),\n    adapter_types.DatabaseErrorRunningHook(hook_type=\"\"),\n    adapter_types.HooksRunning(num_hooks=0, hook_type=\"\"),\n    adapter_types.FinishedRunningStats(stat_line=\"\", execution=\"\", execution_time=0),\n    adapter_types.ConstraintNotEnforced(constraint=\"\", adapter=\"\"),\n    adapter_types.ConstraintNotSupported(constraint=\"\", adapter=\"\"),\n    # I - Project parsing ======================\n    core_types.InputFileDiffError(category=\"testing\", file_id=\"my_file\"),\n    core_types.InvalidValueForField(field_name=\"test\", field_value=\"test\"),\n    core_types.ValidationWarning(resource_type=\"model\", field_name=\"access\", node_name=\"my_macro\"),\n    core_types.ParsePerfInfoPath(path=\"\"),\n    core_types.PartialParsingErrorProcessingFile(file=\"\"),\n    core_types.PartialParsingFile(file_id=\"\"),\n    core_types.PartialParsingError(exc_info={}),\n    core_types.PartialParsingSkipParsing(),\n    core_types.UnableToPartialParse(reason=\"something went wrong\"),\n    core_types.StateCheckVarsHash(vars=\"testing\", target=\"testing\", profile=\"testing\"),\n    core_types.PartialParsingNotEnabled(),\n    core_types.ParsedFileLoadFailed(path=\"\", exc=\"\", exc_info=\"\"),\n    core_types.PartialParsingEnabled(deleted=0, added=0, changed=0),\n    core_types.PartialParsingFile(file_id=\"\"),\n    core_types.InvalidDisabledTargetInTestNode(\n        resource_type_title=\"\",\n        unique_id=\"\",\n        original_file_path=\"\",\n        target_kind=\"\",\n        target_name=\"\",\n        target_package=\"\",\n    ),\n    core_types.UnusedResourceConfigPath(unused_config_paths=[]),\n    core_types.SeedIncreased(package_name=\"\", name=\"\"),\n    core_types.SeedExceedsLimitSamePath(package_name=\"\", name=\"\"),\n    core_types.SeedExceedsLimitAndPathChanged(package_name=\"\", name=\"\"),\n    core_types.SeedExceedsLimitChecksumChanged(package_name=\"\", name=\"\", checksum_name=\"\"),\n    core_types.UnusedTables(unused_tables=[]),\n    core_types.WrongResourceSchemaFile(\n        patch_name=\"\", resource_type=\"\", file_path=\"\", plural_resource_type=\"\"\n    ),\n    core_types.NoNodeForYamlKey(patch_name=\"\", yaml_key=\"\", file_path=\"\"),\n    core_types.MacroNotFoundForPatch(patch_name=\"\"),\n    core_types.NodeNotFoundOrDisabled(\n        original_file_path=\"\",\n        unique_id=\"\",\n        resource_type_title=\"\",\n        target_name=\"\",\n        target_kind=\"\",\n        target_package=\"\",\n        disabled=\"\",\n    ),\n    core_types.JinjaLogWarning(),\n    core_types.JinjaLogInfo(msg=\"\"),\n    core_types.JinjaLogDebug(msg=\"\"),\n    core_types.UnpinnedRefNewVersionAvailable(\n        ref_node_name=\"\", ref_node_package=\"\", ref_node_version=\"\", ref_max_version=\"\"\n    ),\n    core_types.DeprecatedModel(model_name=\"\", model_version=\"\", deprecation_date=\"\"),\n    core_types.DeprecatedReference(\n        model_name=\"\",\n        ref_model_name=\"\",\n        ref_model_package=\"\",\n        ref_model_deprecation_date=\"\",\n        ref_model_latest_version=\"\",\n    ),\n    core_types.UpcomingReferenceDeprecation(\n        model_name=\"\",\n        ref_model_name=\"\",\n        ref_model_package=\"\",\n        ref_model_deprecation_date=\"\",\n        ref_model_latest_version=\"\",\n    ),\n    core_types.UnsupportedConstraintMaterialization(materialized=\"\"),\n    core_types.ParseInlineNodeError(exc=\"\"),\n    core_types.SemanticValidationFailure(msg=\"\"),\n    core_types.UnversionedBreakingChange(\n        breaking_changes=[],\n        model_name=\"\",\n        model_file_path=\"\",\n        contract_enforced_disabled=True,\n        columns_removed=[],\n        column_type_changes=[],\n        enforced_column_constraint_removed=[],\n        enforced_model_constraint_removed=[],\n        materialization_changed=[],\n    ),\n    core_types.WarnStateTargetEqual(state_path=\"\"),\n    core_types.FreshnessConfigProblem(msg=\"\"),\n    core_types.SemanticValidationFailure(msg=\"\"),\n    core_types.MicrobatchModelNoEventTimeInputs(model_name=\"\"),\n    core_types.InvalidConcurrentBatchesConfig(num_models=1, adapter_type=\"\"),\n    core_types.InvalidMacroAnnotation(msg=\"\", macro_file_path=\"\", macro_unique_id=\"\"),\n    core_types.PackageNodeDependsOnRootProjectNode(\n        node_name=\"\", node_package=\"\", root_project_unique_id=\"\"\n    ),\n    # M - Deps generation ======================\n    core_types.GitSparseCheckoutSubdirectory(subdir=\"\"),\n    core_types.GitProgressCheckoutRevision(revision=\"\"),\n    core_types.GitProgressUpdatingExistingDependency(dir=\"\"),\n    core_types.GitProgressPullingNewDependency(dir=\"\"),\n    core_types.GitNothingToDo(sha=\"\"),\n    core_types.GitProgressUpdatedCheckoutRange(start_sha=\"\", end_sha=\"\"),\n    core_types.GitProgressCheckedOutAt(end_sha=\"\"),\n    core_types.RegistryProgressGETRequest(url=\"\"),\n    core_types.RegistryProgressGETResponse(url=\"\", resp_code=1234),\n    core_types.SelectorReportInvalidSelector(valid_selectors=\"\", spec_method=\"\", raw_spec=\"\"),\n    core_types.DepsNoPackagesFound(),\n    core_types.DepsStartPackageInstall(package_name=\"\"),\n    core_types.DepsInstallInfo(version_name=\"\"),\n    core_types.DepsUpdateAvailable(version_latest=\"\"),\n    core_types.DepsUpToDate(),\n    core_types.DepsListSubdirectory(subdirectory=\"\"),\n    core_types.DepsNotifyUpdatesAvailable(packages=[\"my_pkg\", \"other_pkg\"]),\n    types.RetryExternalCall(attempt=0, max=0),\n    types.RecordRetryException(exc=\"\"),\n    core_types.RegistryIndexProgressGETRequest(url=\"\"),\n    core_types.RegistryIndexProgressGETResponse(url=\"\", resp_code=1234),\n    core_types.RegistryResponseUnexpectedType(response=\"\"),\n    core_types.RegistryResponseMissingTopKeys(response=\"\"),\n    core_types.RegistryResponseMissingNestedKeys(response=\"\"),\n    core_types.RegistryResponseExtraNestedKeys(response=\"\"),\n    core_types.DepsSetDownloadDirectory(path=\"\"),\n    core_types.DepsLockUpdating(lock_filepath=\"\"),\n    core_types.DepsAddPackage(package_name=\"\", version=\"\", packages_filepath=\"\"),\n    core_types.DepsFoundDuplicatePackage(removed_package={}),\n    core_types.DepsScrubbedPackageName(package_name=\"\"),\n    core_types.DepsUnpinned(revision=\"\", git=\"\"),\n    core_types.NoNodesForSelectionCriteria(spec_raw=\"\"),\n    # P - Artifacts ======================\n    core_types.ArtifactWritten(artifact_type=\"manifest\", artifact_path=\"path/to/artifact.json\"),\n    # Q - Node execution ======================\n    core_types.RunningOperationCaughtError(exc=\"\"),\n    core_types.CompileComplete(),\n    core_types.FreshnessCheckComplete(),\n    core_types.SeedHeader(header=\"\"),\n    core_types.SQLRunnerException(exc=\"\"),\n    core_types.LogTestResult(\n        name=\"\",\n        index=0,\n        num_models=0,\n        execution_time=0,\n        num_failures=0,\n    ),\n    core_types.LogNodeResult(\n        description=\"\",\n        status=\"\",\n        index=0,\n        total=0,\n        execution_time=0,\n        msg=\"\",\n    ),\n    core_types.LogStartLine(description=\"\", index=0, total=0),\n    core_types.LogModelResult(\n        description=\"\",\n        status=\"\",\n        index=0,\n        total=0,\n        execution_time=0,\n    ),\n    core_types.LogSnapshotResult(\n        status=\"\",\n        description=\"\",\n        cfg={},\n        index=0,\n        total=0,\n        execution_time=0,\n    ),\n    core_types.LogSeedResult(\n        status=\"\",\n        index=0,\n        total=0,\n        execution_time=0,\n        schema=\"\",\n        relation=\"\",\n    ),\n    core_types.LogFreshnessResult(\n        source_name=\"\",\n        table_name=\"\",\n        index=0,\n        total=0,\n        execution_time=0,\n    ),\n    core_types.LogNodeNoOpResult(\n        description=\"\",\n        status=\"\",\n        index=0,\n        total=0,\n        execution_time=0,\n    ),\n    core_types.LogCancelLine(conn_name=\"\"),\n    core_types.DefaultSelector(name=\"\"),\n    core_types.NodeStart(),\n    core_types.NodeFinished(),\n    core_types.QueryCancelationUnsupported(type=\"\"),\n    core_types.ConcurrencyLine(num_threads=0, target_name=\"\"),\n    core_types.WritingInjectedSQLForNode(),\n    core_types.NodeCompiling(),\n    core_types.NodeExecuting(),\n    core_types.LogHookStartLine(\n        statement=\"\",\n        index=0,\n        total=0,\n    ),\n    core_types.LogHookEndLine(\n        statement=\"\",\n        status=\"\",\n        index=0,\n        total=0,\n        execution_time=0,\n    ),\n    core_types.SkippingDetails(\n        resource_type=\"\",\n        schema=\"\",\n        node_name=\"\",\n        index=0,\n        total=0,\n    ),\n    core_types.NothingToDo(),\n    core_types.RunningOperationUncaughtError(exc=\"\"),\n    core_types.EndRunResult(),\n    core_types.NoNodesSelected(),\n    core_types.CommandCompleted(\n        command=\"\",\n        success=True,\n        elapsed=0.1,\n        completed_at=get_json_string_utcnow(),\n    ),\n    core_types.ShowNode(node_name=\"\", preview=\"\", is_inline=True, unique_id=\"model.test.my_model\"),\n    core_types.CompiledNode(\n        node_name=\"\", compiled=\"\", is_inline=True, unique_id=\"model.test.my_model\"\n    ),\n    core_types.SnapshotTimestampWarning(\n        snapshot_time_data_type=\"DATETIME\", updated_at_data_type=\"DATETIMEZ\"\n    ),\n    core_types.MicrobatchExecutionDebug(msg=\"\"),\n    core_types.LogStartBatch(description=\"\", batch_index=0, total_batches=0),\n    core_types.LogBatchResult(\n        description=\"\",\n        status=\"\",\n        batch_index=0,\n        total_batches=0,\n        execution_time=0,\n    ),\n    core_types.LogFunctionResult(\n        description=\"\",\n        status=\"\",\n        index=0,\n        total=0,\n        execution_time=0,\n    ),\n    # W - Node testing ======================\n    core_types.CatchableExceptionOnRun(exc=\"\"),\n    core_types.InternalErrorOnRun(build_path=\"\", exc=\"\"),\n    core_types.GenericExceptionOnRun(build_path=\"\", unique_id=\"\", exc=\"\"),\n    core_types.NodeConnectionReleaseError(node_name=\"\", exc=\"\"),\n    core_types.FoundStats(stat_line=\"\"),\n    # Z - misc ======================\n    core_types.MainKeyboardInterrupt(),\n    core_types.MainEncounteredError(exc=\"\"),\n    core_types.MainStackTrace(stack_trace=\"\"),\n    types.SystemCouldNotWrite(path=\"\", reason=\"\", exc=\"\"),\n    types.SystemExecutingCmd(cmd=[\"\"]),\n    types.SystemStdOut(bmsg=str(b\"\")),\n    types.SystemStdErr(bmsg=str(b\"\")),\n    types.SystemReportReturnCode(returncode=0),\n    core_types.TimingInfoCollected(),\n    core_types.LogDebugStackTrace(),\n    core_types.CheckCleanPath(path=\"\"),\n    core_types.ConfirmCleanPath(path=\"\"),\n    core_types.ProtectedCleanPath(path=\"\"),\n    core_types.FinishedCleanPaths(),\n    core_types.OpenCommand(open_cmd=\"\", profiles_dir=\"\"),\n    core_types.RunResultWarning(resource_type=\"\", node_name=\"\", path=\"\"),\n    core_types.RunResultFailure(resource_type=\"\", node_name=\"\", path=\"\"),\n    core_types.StatsLine(\n        stats={\"error\": 0, \"skip\": 0, \"pass\": 0, \"warn\": 0, \"noop\": 0, \"total\": 0}\n    ),\n    core_types.RunResultError(msg=\"\"),\n    core_types.RunResultErrorNoMessage(status=\"\"),\n    core_types.SQLCompiledPath(path=\"\"),\n    core_types.CheckNodeTestFailure(relation_name=\"\"),\n    core_types.EndOfRunSummary(num_errors=0, num_warnings=0, keyboard_interrupt=False),\n    core_types.MarkSkippedChildren(unique_id=\"\", status=\"skipped\"),\n    core_types.LogSkipBecauseError(schema=\"\", relation=\"\", index=0, total=0),\n    core_types.EnsureGitInstalled(),\n    core_types.DepsCreatingLocalSymlink(),\n    core_types.DepsSymlinkNotAvailable(),\n    core_types.DisableTracking(),\n    core_types.SendingEvent(kwargs=\"\"),\n    core_types.SendEventFailure(),\n    core_types.FlushEvents(),\n    core_types.FlushEventsFailure(),\n    types.Formatting(),\n    core_types.TrackingInitializeFailure(),\n    core_types.RunResultWarningMessage(),\n    core_types.DebugCmdOut(),\n    core_types.DebugCmdResult(),\n    core_types.ListCmdOut(),\n    types.Note(msg=\"This is a note.\"),\n    core_types.ResourceReport(),\n    core_types.ArtifactUploadSuccess(),\n    core_types.ArtifactUploadError(),\n    core_types.ArtifactUploadSkipped(),\n    core_types.SelectExcludeIgnoredWithSelectorWarning(),\n]\n\n\nclass TestEventJSONSerialization:\n\n    # attempts to test that every event is serializable to json.\n    # event types that take `Any` are not possible to test in this way since some will serialize\n    # just fine and others won't.\n    def test_all_serializable(self):\n        all_non_abstract_events = set(\n            get_all_subclasses(CoreBaseEvent),\n        )\n        all_event_values_list = list(map(lambda x: x.__class__, sample_values))\n        diff = all_non_abstract_events.difference(set(all_event_values_list))\n        assert (\n            not diff\n        ), f\"{diff}test is missing concrete values in `sample_values`. Please add the values for the aforementioned event classes\"\n\n        # make sure everything in the list is a value not a type\n        for event in sample_values:\n            assert type(event) != type\n\n        # if we have everything we need to test, try to serialize everything\n        count = 0\n        for event in sample_values:\n            msg = msg_from_base_event(event)\n            print(f\"--- msg: {msg.info.name}\")\n            # Serialize to dictionary\n            try:\n                msg_to_dict(msg)\n            except Exception as e:\n                raise Exception(\n                    f\"{event} can not be converted to a dict. Originating exception: {e}\"\n                )\n            # Serialize to json\n            try:\n                msg_to_json(msg)\n            except Exception as e:\n                raise Exception(f\"{event} is not serializable to json. Originating exception: {e}\")\n            # Serialize to binary\n            try:\n                msg.SerializeToString()\n            except Exception as e:\n                raise Exception(\n                    f\"{event} is not serializable to binary protobuf. Originating exception: {e}\"\n                )\n            count += 1\n        print(f\"--- Found {count} events\")\n\n\nT = TypeVar(\"T\")\n\n\ndef test_date_serialization():\n    ti = TimingInfo(\"compile\")\n    ti.begin()\n    ti.end()\n    ti_dict = ti.to_dict()\n    assert ti_dict[\"started_at\"].endswith(\"Z\")\n    assert ti_dict[\"completed_at\"].endswith(\"Z\")\n\n\ndef test_bad_serialization():\n    \"\"\"Tests that bad serialization enters the proper exception handling\n\n    When pytest is in use the exception handling of `BaseEvent` raises an\n    exception. When pytest isn't present, it fires a Note event. Thus to test\n    that bad serializations are properly handled, the best we can do is test\n    that the exception handling path is used.\n    \"\"\"\n\n    with pytest.raises(Exception) as excinfo:\n        types.Note(param_event_doesnt_have=\"This should break\")\n\n    assert 'has no field named \"param_event_doesnt_have\" at \"Note\"' in str(excinfo.value)\n\n\ndef test_single_run_error():\n\n    try:\n        # Add a recording event manager to the context, so we can test events.\n        event_mgr = TestEventManager()\n        ctx_set_event_manager(event_mgr)\n\n        class MockNode:\n            unique_id: str = \"\"\n            node_info = None\n            resource_type: str = \"model\"\n            name: str = \"my_model\"\n            original_file_path: str = \"path/to/model.sql\"\n\n        error_result = RunResult(\n            status=RunStatus.Error,\n            timing=[],\n            thread_id=\"\",\n            execution_time=0.0,\n            node=MockNode(),\n            adapter_response=dict(),\n            message=\"oh no!\",\n            failures=1,\n            batch_results=None,\n        )\n        results = [error_result]\n        print_run_end_messages(results)\n\n        summary_event = [\n            e for e in event_mgr.event_history if isinstance(e[0], core_types.EndOfRunSummary)\n        ]\n        run_result_error_events = [\n            e for e in event_mgr.event_history if isinstance(e[0], core_types.RunResultError)\n        ]\n\n        # expect correct plural\n        assert \"partial successes\" in summary_event[0][0].message()\n\n        # expect one error to show up\n        assert len(run_result_error_events) == 1\n        assert run_result_error_events[0][0].msg == \"oh no!\"\n\n    finally:\n        # Set an empty event manager unconditionally on exit. This is an early\n        # attempt at unit testing events, and we need to think about how it\n        # could be done in a thread safe way in the long run.\n        ctx_set_event_manager(EventManager())\n"
  },
  {
    "path": "tests/unit/test_functions.py",
    "content": "from argparse import Namespace\n\nimport pytest\n\nimport dbt.flags as flags\nfrom dbt.adapters.events.types import AdapterDeprecationWarning\nfrom dbt.events.types import NoNodesForSelectionCriteria\nfrom dbt_common.events.functions import msg_to_dict, warn_or_error\nfrom dbt_common.events.types import InfoLevel, RetryExternalCall\nfrom dbt_common.exceptions import EventCompilationError\n\n\n@pytest.mark.parametrize(\n    \"warn_error_options,expect_compilation_exception\",\n    [\n        ({\"error\": \"all\"}, True),\n        ({\"error\": [\"NoNodesForSelectionCriteria\"]}, True),\n        ({\"error\": []}, False),\n        ({}, False),\n        ({\"error\": [\"MainTrackingUserState\"]}, False),\n        ({\"error\": \"all\", \"warn\": [\"NoNodesForSelectionCriteria\"]}, False),\n    ],\n)\ndef test_warn_or_error_warn_error_options(warn_error_options, expect_compilation_exception):\n    args = Namespace(warn_error_options=warn_error_options)\n    flags.set_from_args(args, {})\n    if expect_compilation_exception:\n        with pytest.raises(EventCompilationError):\n            warn_or_error(NoNodesForSelectionCriteria())\n    else:\n        warn_or_error(NoNodesForSelectionCriteria())\n\n\n@pytest.mark.parametrize(\n    \"error_cls\",\n    [\n        NoNodesForSelectionCriteria,  # core event\n        AdapterDeprecationWarning,  # adapter event\n        RetryExternalCall,  # common event\n    ],\n)\ndef test_warn_error_options_captures_all_events(error_cls):\n    args = Namespace(warn_error_options={\"error\": [error_cls.__name__]})\n    flags.set_from_args(args, {})\n    with pytest.raises(EventCompilationError):\n        warn_or_error(error_cls())\n\n    args = Namespace(warn_error_options={\"error\": \"*\", \"warn\": [error_cls.__name__]})\n    flags.set_from_args(args, {})\n    warn_or_error(error_cls())\n\n\n@pytest.mark.parametrize(\n    \"warn_error,expect_compilation_exception\",\n    [\n        (True, True),\n        (False, False),\n    ],\n)\ndef test_warn_or_error_warn_error(warn_error, expect_compilation_exception):\n    args = Namespace(warn_error=warn_error)\n    flags.set_from_args(args, {})\n    if expect_compilation_exception:\n        with pytest.raises(EventCompilationError):\n            warn_or_error(NoNodesForSelectionCriteria())\n    else:\n        warn_or_error(NoNodesForSelectionCriteria())\n\n\ndef test_msg_to_dict_handles_exceptions_gracefully():\n    class BadEvent(InfoLevel):\n        \"\"\"A spoof Note event which breaks dictification\"\"\"\n\n        def __init__(self):\n            self.__class__.__name__ = \"Note\"\n\n    event = BadEvent()\n    try:\n        msg_to_dict(event)\n    except Exception as exc:\n        assert (\n            False\n        ), f\"We expect `msg_to_dict` to gracefully handle exceptions, but it raised {exc}\"\n"
  },
  {
    "path": "tests/unit/test_graph_selection.py",
    "content": "import string\nfrom unittest import mock\n\nimport networkx as nx\nimport pytest\n\nimport dbt.graph.cli as graph_cli\nimport dbt.graph.selector as graph_selector\nimport dbt_common.exceptions\nfrom dbt.node_types import NodeType\n\n\ndef _get_graph():\n    integer_graph = nx.balanced_tree(2, 2, nx.DiGraph())\n\n    package_mapping = {\n        i: \"m.\" + (\"X\" if i % 2 == 0 else \"Y\") + \".\" + letter\n        for (i, letter) in enumerate(string.ascii_lowercase)\n    }\n\n    # Edges: [(X.a, Y.b), (X.a, X.c), (Y.b, Y.d), (Y.b, X.e), (X.c, Y.f), (X.c, X.g)]\n    return graph_selector.Graph(nx.relabel_nodes(integer_graph, package_mapping))\n\n\ndef _get_manifest(graph):\n    nodes = {}\n    for unique_id in graph:\n        fqn = unique_id.split(\".\")\n        node = mock.MagicMock(\n            unique_id=unique_id,\n            fqn=fqn,\n            package_name=fqn[0],\n            tags=[],\n            resource_type=NodeType.Model,\n            empty=False,\n            config=mock.MagicMock(enabled=True),\n            is_versioned=False,\n        )\n        nodes[unique_id] = node\n\n    nodes[\"m.X.a\"].tags = [\"abc\"]\n    nodes[\"m.Y.b\"].tags = [\"abc\", \"bcef\"]\n    nodes[\"m.X.c\"].tags = [\"abc\", \"bcef\"]\n    nodes[\"m.Y.d\"].tags = []\n    nodes[\"m.X.e\"].tags = [\"efg\", \"bcef\"]\n    nodes[\"m.Y.f\"].tags = [\"efg\", \"bcef\"]\n    nodes[\"m.X.g\"].tags = [\"efg\"]\n    return mock.MagicMock(nodes=nodes)\n\n\n@pytest.fixture\ndef graph():\n    return _get_graph()\n\n\n@pytest.fixture\ndef manifest(graph):\n    return _get_manifest(graph)\n\n\ndef id_macro(arg):\n    if isinstance(arg, str):\n        return arg\n    try:\n        return \"_\".join(arg)\n    except TypeError:\n        return arg\n\n\nrun_specs = [\n    # include by fqn\n    ([\"X.a\"], [], {\"m.X.a\"}),\n    # include by tag\n    ([\"tag:abc\"], [], {\"m.X.a\", \"m.Y.b\", \"m.X.c\"}),\n    # exclude by tag\n    ([\"*\"], [\"tag:abc\"], {\"m.Y.d\", \"m.X.e\", \"m.Y.f\", \"m.X.g\"}),\n    # tag + fqn\n    ([\"tag:abc\", \"a\"], [], {\"m.X.a\", \"m.Y.b\", \"m.X.c\"}),\n    ([\"tag:abc\", \"d\"], [], {\"m.X.a\", \"m.Y.b\", \"m.X.c\", \"m.Y.d\"}),\n    # multiple node selection across packages\n    ([\"X.a\", \"b\"], [], {\"m.X.a\", \"m.Y.b\"}),\n    ([\"X.a+\"], [\"b\"], {\"m.X.a\", \"m.X.c\", \"m.Y.d\", \"m.X.e\", \"m.Y.f\", \"m.X.g\"}),\n    # children\n    ([\"X.c+\"], [], {\"m.X.c\", \"m.Y.f\", \"m.X.g\"}),\n    ([\"X.a+1\"], [], {\"m.X.a\", \"m.Y.b\", \"m.X.c\"}),\n    ([\"X.a+\"], [\"tag:efg\"], {\"m.X.a\", \"m.Y.b\", \"m.X.c\", \"m.Y.d\"}),\n    # parents\n    ([\"+Y.f\"], [], {\"m.X.c\", \"m.Y.f\", \"m.X.a\"}),\n    ([\"1+Y.f\"], [], {\"m.X.c\", \"m.Y.f\"}),\n    # childrens parents\n    ([\"@X.c\"], [], {\"m.X.a\", \"m.X.c\", \"m.Y.f\", \"m.X.g\"}),\n    # multiple selection/exclusion\n    ([\"tag:abc\", \"tag:bcef\"], [], {\"m.X.a\", \"m.Y.b\", \"m.X.c\", \"m.X.e\", \"m.Y.f\"}),\n    ([\"tag:abc\", \"tag:bcef\"], [\"tag:efg\"], {\"m.X.a\", \"m.Y.b\", \"m.X.c\"}),\n    ([\"tag:abc\", \"tag:bcef\"], [\"tag:efg\", \"a\"], {\"m.Y.b\", \"m.X.c\"}),\n    # intersections\n    ([\"a,a\"], [], {\"m.X.a\"}),\n    ([\"+c,c+\"], [], {\"m.X.c\"}),\n    ([\"a,b\"], [], set()),\n    ([\"tag:abc,tag:bcef\"], [], {\"m.Y.b\", \"m.X.c\"}),\n    ([\"*,tag:abc,a\"], [], {\"m.X.a\"}),\n    ([\"a,tag:abc,*\"], [], {\"m.X.a\"}),\n    ([\"tag:abc,tag:bcef\"], [\"c\"], {\"m.Y.b\"}),\n    ([\"tag:bcef,tag:efg\"], [\"tag:bcef,@b\"], {\"m.Y.f\"}),\n    ([\"tag:bcef,tag:efg\"], [\"tag:bcef,@a\"], set()),\n    ([\"*,@a,+b\"], [\"*,tag:abc,tag:bcef\"], {\"m.X.a\"}),\n    ([\"tag:bcef,tag:efg\", \"*,tag:abc\"], [], {\"m.X.a\", \"m.Y.b\", \"m.X.c\", \"m.X.e\", \"m.Y.f\"}),\n    ([\"tag:bcef,tag:efg\", \"*,tag:abc\"], [\"e\"], {\"m.X.a\", \"m.Y.b\", \"m.X.c\", \"m.Y.f\"}),\n    ([\"tag:bcef,tag:efg\", \"*,tag:abc\"], [\"e\"], {\"m.X.a\", \"m.Y.b\", \"m.X.c\", \"m.Y.f\"}),\n    ([\"tag:bcef,tag:efg\", \"*,tag:abc\"], [\"e\", \"f\"], {\"m.X.a\", \"m.Y.b\", \"m.X.c\"}),\n    ([\"tag:bcef,tag:efg\", \"*,tag:abc\"], [\"tag:abc,tag:bcef\"], {\"m.X.a\", \"m.X.e\", \"m.Y.f\"}),\n    ([\"tag:bcef,tag:efg\", \"*,tag:abc\"], [\"tag:abc,tag:bcef\", \"tag:abc,a\"], {\"m.X.e\", \"m.Y.f\"}),\n]\n\n\n@pytest.mark.parametrize(\"include,exclude,expected\", run_specs, ids=id_macro)\ndef test_run_specs(include, exclude, expected, graph, manifest):\n    selector = graph_selector.NodeSelector(graph, manifest)\n    spec = graph_cli.parse_difference(include, exclude)\n    selected, _ = selector.select_nodes(spec)\n\n    assert selected == expected\n\n\nparam_specs = [\n    (\"a\", False, None, False, None, \"fqn\", \"a\", False),\n    (\"+a\", True, None, False, None, \"fqn\", \"a\", False),\n    (\"256+a\", True, 256, False, None, \"fqn\", \"a\", False),\n    (\"a+\", False, None, True, None, \"fqn\", \"a\", False),\n    (\"a+256\", False, None, True, 256, \"fqn\", \"a\", False),\n    (\"+a+\", True, None, True, None, \"fqn\", \"a\", False),\n    (\"16+a+32\", True, 16, True, 32, \"fqn\", \"a\", False),\n    (\"@a\", False, None, False, None, \"fqn\", \"a\", True),\n    (\"a.b\", False, None, False, None, \"fqn\", \"a.b\", False),\n    (\"+a.b\", True, None, False, None, \"fqn\", \"a.b\", False),\n    (\"256+a.b\", True, 256, False, None, \"fqn\", \"a.b\", False),\n    (\"a.b+\", False, None, True, None, \"fqn\", \"a.b\", False),\n    (\"a.b+256\", False, None, True, 256, \"fqn\", \"a.b\", False),\n    (\"+a.b+\", True, None, True, None, \"fqn\", \"a.b\", False),\n    (\"16+a.b+32\", True, 16, True, 32, \"fqn\", \"a.b\", False),\n    (\"@a.b\", False, None, False, None, \"fqn\", \"a.b\", True),\n    (\"a.b.*\", False, None, False, None, \"fqn\", \"a.b.*\", False),\n    (\"+a.b.*\", True, None, False, None, \"fqn\", \"a.b.*\", False),\n    (\"256+a.b.*\", True, 256, False, None, \"fqn\", \"a.b.*\", False),\n    (\"a.b.*+\", False, None, True, None, \"fqn\", \"a.b.*\", False),\n    (\"a.b.*+256\", False, None, True, 256, \"fqn\", \"a.b.*\", False),\n    (\"+a.b.*+\", True, None, True, None, \"fqn\", \"a.b.*\", False),\n    (\"16+a.b.*+32\", True, 16, True, 32, \"fqn\", \"a.b.*\", False),\n    (\"@a.b.*\", False, None, False, None, \"fqn\", \"a.b.*\", True),\n    (\"tag:a\", False, None, False, None, \"tag\", \"a\", False),\n    (\"+tag:a\", True, None, False, None, \"tag\", \"a\", False),\n    (\"256+tag:a\", True, 256, False, None, \"tag\", \"a\", False),\n    (\"tag:a+\", False, None, True, None, \"tag\", \"a\", False),\n    (\"tag:a+256\", False, None, True, 256, \"tag\", \"a\", False),\n    (\"+tag:a+\", True, None, True, None, \"tag\", \"a\", False),\n    (\"16+tag:a+32\", True, 16, True, 32, \"tag\", \"a\", False),\n    (\"@tag:a\", False, None, False, None, \"tag\", \"a\", True),\n    (\"source:a\", False, None, False, None, \"source\", \"a\", False),\n    (\"source:a+\", False, None, True, None, \"source\", \"a\", False),\n    (\"source:a+1\", False, None, True, 1, \"source\", \"a\", False),\n    (\"source:a+32\", False, None, True, 32, \"source\", \"a\", False),\n    (\"@source:a\", False, None, False, None, \"source\", \"a\", True),\n]\n\n\n@pytest.mark.parametrize(\n    \"spec,parents,parents_depth,children,children_depth,filter_type,filter_value,childrens_parents\",\n    param_specs,\n    ids=id_macro,\n)\ndef test_parse_specs(\n    spec,\n    parents,\n    parents_depth,\n    children,\n    children_depth,\n    filter_type,\n    filter_value,\n    childrens_parents,\n):\n    parsed = graph_selector.SelectionCriteria.from_single_spec(spec)\n    assert parsed.parents == parents\n    assert parsed.parents_depth == parents_depth\n    assert parsed.children == children\n    assert parsed.children_depth == children_depth\n    assert parsed.method == filter_type\n    assert parsed.value == filter_value\n    assert parsed.childrens_parents == childrens_parents\n\n\ninvalid_specs = [\n    \"@a+\",\n    \"@a.b+\",\n    \"@a.b*+\",\n    \"@tag:a+\",\n    \"@source:a+\",\n]\n\n\n@pytest.mark.parametrize(\"invalid\", invalid_specs, ids=lambda k: str(k))\ndef test_invalid_specs(invalid):\n    with pytest.raises(dbt_common.exceptions.DbtRuntimeError):\n        graph_selector.SelectionCriteria.from_single_spec(invalid)\n"
  },
  {
    "path": "tests/unit/test_internal_deprecations.py",
    "content": "from dbt.internal_deprecations import deprecated\n\n\n@deprecated(reason=\"just because\", version=\"1.23.0\", suggested_action=\"Make some updates\")\ndef to_be_decorated():\n    return 5\n\n\n# simple test that the return value is not modified\ndef test_deprecated_func():\n    assert hasattr(to_be_decorated, \"__wrapped__\")\n    assert to_be_decorated() == 5\n"
  },
  {
    "path": "tests/unit/test_invocation_id.py",
    "content": "from dbt.cli.main import dbtRunner\n\n\nclass TestInvocationId:\n    def test_invocation_id(self):\n        \"\"\"Runs dbt programmatically twice, checking that invocation_id is\n        consistent within an invocation, but changes for the second invocation.\"\"\"\n\n        runner = dbtRunner()\n\n        # Run once...\n        first_ids = set()\n        runner.callbacks = [lambda e: first_ids.add(e.info.invocation_id)]\n        runner.invoke([\"debug\"])\n\n        # ...run twice...\n        second_ids = set()\n        runner.callbacks = [lambda e: second_ids.add(e.info.invocation_id)]\n        runner.invoke([\"debug\"])\n\n        # ...check that the results were nice.\n        assert len(first_ids) == 1  # There was one consistent invocation_id for first run...\n        assert len(second_ids) == 1  # ...as well as the second...\n        assert len(first_ids.intersection(second_ids)) == 0\n"
  },
  {
    "path": "tests/unit/test_jsonschemas.py",
    "content": "import pytest\n\nfrom dbt.deprecations import (\n    CustomKeyInConfigDeprecation,\n    CustomKeyInObjectDeprecation,\n    GenericJSONSchemaValidationDeprecation,\n    active_deprecations,\n    reset_deprecations,\n)\nfrom dbt.jsonschemas.jsonschemas import (\n    jsonschema_validate,\n    resources_schema,\n    validate_model_config,\n)\nfrom dbt.tests.util import safe_set_invocation_context\nfrom dbt_common.context import get_invocation_context\nfrom dbt_common.events.event_catcher import EventCatcher\nfrom dbt_common.events.event_manager_client import add_callback_to_manager\n\n\nclass TestValidateModelConfigNoError:\n    def test_validate_model_config_no_error(self):\n        safe_set_invocation_context()\n        get_invocation_context().uses_adapter(\"snowflake\")\n        caught_events = []\n        add_callback_to_manager(caught_events.append)\n\n        config = {\n            \"enabled\": True,\n        }\n        validate_model_config(config, \"test.yml\")\n        assert len(caught_events) == 0\n\n    def test_validate_model_config_error(self):\n        safe_set_invocation_context()\n        get_invocation_context().uses_adapter(\"snowflake\")\n        ckiod_catcher = EventCatcher(CustomKeyInObjectDeprecation)\n        ckicd_catcher = EventCatcher(CustomKeyInConfigDeprecation)\n        gjsvd_catcher = EventCatcher(GenericJSONSchemaValidationDeprecation)\n        add_callback_to_manager(ckiod_catcher.catch)\n        add_callback_to_manager(ckicd_catcher.catch)\n        add_callback_to_manager(gjsvd_catcher.catch)\n\n        config = {\n            \"non_existent_config\": True,  # this config key doesn't exist\n            \"docs\": {\n                \"show\": True,  # this is a valid config key\n                \"color\": \"red\",  # this is an invalid config key, as it should be `node_color`\n            },\n        }\n\n        validate_model_config(config, \"test.yml\")\n\n        assert len(ckiod_catcher.caught_events) == 1\n        assert ckiod_catcher.caught_events[0].data.key == \"color\"\n        assert len(ckicd_catcher.caught_events) == 1\n        assert ckicd_catcher.caught_events[0].data.key == \"non_existent_config\"\n        assert len(gjsvd_catcher.caught_events) == 0\n\n\nclass TestValidateJsonSchema:\n    @pytest.fixture(scope=\"class\")\n    def model_bigquery_alias_config_contents(self):\n        return {\n            \"models\": [\n                {\n                    \"name\": \"model_1\",\n                    \"config\": {\n                        \"dataset\": \"dataset_1\",\n                        \"project\": \"project_1\",\n                    },\n                }\n            ],\n        }\n\n    def test_validate_json_schema_no_error_aliases(self, model_bigquery_alias_config_contents):\n        reset_deprecations()\n\n        safe_set_invocation_context()\n        get_invocation_context().uses_adapter(\"bigquery\")\n\n        jsonschema_validate(resources_schema(), model_bigquery_alias_config_contents, \"test.yml\")\n        assert active_deprecations == {}\n\n    def test_validate_json_schema_has_error_aliases(self, model_bigquery_alias_config_contents):\n        reset_deprecations()\n\n        safe_set_invocation_context()\n        # Set to adapter that doesn't support aliases specified\n        get_invocation_context().uses_adapter(\"snowflake\")\n\n        jsonschema_validate(resources_schema(), model_bigquery_alias_config_contents, \"test.yml\")\n        assert active_deprecations == {\"custom-key-in-config-deprecation\": 2}\n\n\nclass TestSourceBigQueryAliases:\n    @pytest.fixture(scope=\"class\")\n    def source_with_dataset(self):\n        return {\n            \"sources\": [\n                {\n                    \"name\": \"my_source\",\n                    \"dataset\": \"my_dataset\",\n                    \"tables\": [{\"name\": \"my_table\"}],\n                }\n            ]\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def source_with_project(self):\n        return {\n            \"sources\": [\n                {\n                    \"name\": \"my_source\",\n                    \"project\": \"my-gcp-project\",\n                    \"tables\": [{\"name\": \"my_table\"}],\n                }\n            ]\n        }\n\n    @pytest.fixture(scope=\"class\")\n    def source_with_both_aliases(self):\n        return {\n            \"sources\": [\n                {\n                    \"name\": \"my_source\",\n                    \"project\": \"my-gcp-project\",\n                    \"dataset\": \"my_dataset\",\n                    \"tables\": [{\"name\": \"my_table\"}],\n                }\n            ]\n        }\n\n    def test_bigquery_source_dataset_no_warning(self, source_with_dataset):\n        reset_deprecations()\n\n        safe_set_invocation_context()\n        get_invocation_context().uses_adapter(\"bigquery\")\n\n        jsonschema_validate(resources_schema(), source_with_dataset, \"test.yml\")\n        assert active_deprecations == {}\n\n    def test_bigquery_source_project_no_warning(self, source_with_project):\n        reset_deprecations()\n\n        safe_set_invocation_context()\n        get_invocation_context().uses_adapter(\"bigquery\")\n\n        jsonschema_validate(resources_schema(), source_with_project, \"test.yml\")\n        assert active_deprecations == {}\n\n    def test_bigquery_source_both_aliases_no_warning(self, source_with_both_aliases):\n        reset_deprecations()\n\n        safe_set_invocation_context()\n        get_invocation_context().uses_adapter(\"bigquery\")\n\n        jsonschema_validate(resources_schema(), source_with_both_aliases, \"test.yml\")\n        assert active_deprecations == {}\n\n    def test_snowflake_source_dataset_warns(self, source_with_dataset):\n        reset_deprecations()\n\n        safe_set_invocation_context()\n        get_invocation_context().uses_adapter(\"snowflake\")\n\n        jsonschema_validate(resources_schema(), source_with_dataset, \"test.yml\")\n        assert active_deprecations == {\"custom-key-in-object-deprecation\": 1}\n"
  },
  {
    "path": "tests/unit/test_macro_types.py",
    "content": "from dbt.parser.schemas import is_valid_type\n\n\ndef test_valid_names() -> None:\n    valid_names = [\n        \"str\",\n        \"string\",\n        \"bool\",\n        \"int\",\n        \"integer\",\n        \"float\",\n        \"any\",\n        \"list[int]\",\n        \"dict[str, int]\",\n        \"optional[any]\",\n        \"relation\",\n        \"column\",\n        \"list[dict[str, any]]\",\n        \"dict[str, list[int]]\",\n    ]\n\n    for name in valid_names:\n        assert is_valid_type(name)\n\n\ndef test_invalid_names() -> None:\n    invalid_names = [\n        \"strang\",  # Not a valid name\n        \"int int\",  # Repeat not allowed\n        \"intint\",  # No repeat, even with no space\n        \"list[dict[any]]\",  # dict needs two args\n        \"dict[str, list[int]]]\",  # Can't have extra closing brace\n        \"dict[str, list[[int]]\",  # Can't have extra opening brace\n        \"dict[str,]\",  # Can't have blank nexted type\n        \"dict[str,,str]\",  # Can't have extra comma\n    ]\n\n    for name in invalid_names:\n        assert not is_valid_type(name)\n"
  },
  {
    "path": "tests/unit/test_node_types.py",
    "content": "import pytest\n\nfrom dbt.node_types import NodeType\n\nnode_type_pluralizations = {\n    NodeType.Model: \"models\",\n    NodeType.Analysis: \"analyses\",\n    NodeType.Test: \"data_tests\",\n    NodeType.Snapshot: \"snapshots\",\n    NodeType.Operation: \"operations\",\n    NodeType.Seed: \"seeds\",\n    NodeType.RPCCall: \"rpcs\",\n    NodeType.SqlOperation: \"sql_operations\",\n    NodeType.Documentation: \"docs\",\n    NodeType.Source: \"sources\",\n    NodeType.Macro: \"macros\",\n    NodeType.Exposure: \"exposures\",\n    NodeType.Metric: \"metrics\",\n    NodeType.Group: \"groups\",\n    NodeType.SemanticModel: \"semantic_models\",\n    NodeType.Unit: \"unit_tests\",\n    NodeType.SavedQuery: \"saved_queries\",\n    NodeType.Fixture: \"fixtures\",\n    NodeType.Function: \"functions\",\n}\n\n\ndef test_all_types_have_pluralizations():\n    assert set(NodeType) == set(node_type_pluralizations)\n\n\n@pytest.mark.parametrize(\"node_type, pluralization\", node_type_pluralizations.items())\ndef test_pluralizes_correctly(node_type, pluralization):\n    assert node_type.pluralize() == pluralization\n"
  },
  {
    "path": "tests/unit/test_semantic_layer_nodes_satisfy_protocols.py",
    "content": "import copy\nfrom typing import Protocol, runtime_checkable\n\nimport pytest\nfrom hypothesis import HealthCheck, given, settings\nfrom hypothesis.strategies import builds, none, text\n\nfrom dbt.artifacts.resources import (\n    ConstantPropertyInput,\n    ConversionTypeParams,\n    CumulativeTypeParams,\n    Defaults,\n    Dimension,\n    DimensionTypeParams,\n    DimensionValidityParams,\n    Entity,\n    FileSlice,\n    Measure,\n    MeasureAggregationParameters,\n    MetricInput,\n    MetricInputMeasure,\n    MetricTimeWindow,\n    MetricTypeParams,\n    NodeRelation,\n    NonAdditiveDimension,\n    SourceFileMetadata,\n    WhereFilter,\n)\nfrom dbt.contracts.graph.nodes import Metric, SavedQuery, SemanticModel\nfrom dbt.node_types import NodeType\nfrom dbt_semantic_interfaces.protocols import WhereFilter as WhereFilterProtocol\nfrom dbt_semantic_interfaces.protocols import dimension as DimensionProtocols\nfrom dbt_semantic_interfaces.protocols import entity as EntityProtocols\nfrom dbt_semantic_interfaces.protocols import measure as MeasureProtocols\nfrom dbt_semantic_interfaces.protocols import metadata as MetadataProtocols\nfrom dbt_semantic_interfaces.protocols import metric as MetricProtocols\nfrom dbt_semantic_interfaces.protocols import saved_query as SavedQueryProtocols\nfrom dbt_semantic_interfaces.protocols import semantic_model as SemanticModelProtocols\nfrom dbt_semantic_interfaces.type_enums import (\n    AggregationType,\n    DimensionType,\n    EntityType,\n    MetricType,\n    TimeGranularity,\n)\n\n\n@runtime_checkable\nclass RuntimeCheckableSemanticModel(SemanticModelProtocols.SemanticModel, Protocol):\n    pass\n\n\n@runtime_checkable\nclass RuntimeCheckableDimension(DimensionProtocols.Dimension, Protocol):\n    pass\n\n\n@runtime_checkable\nclass RuntimeCheckableEntity(EntityProtocols.Entity, Protocol):\n    pass\n\n\n@runtime_checkable\nclass RuntimeCheckableMeasure(MeasureProtocols.Measure, Protocol):\n    pass\n\n\n@runtime_checkable\nclass RuntimeCheckableMetric(MetricProtocols.Metric, Protocol):\n    pass\n\n\n@runtime_checkable\nclass RuntimeCheckableMetricInput(MetricProtocols.MetricInput, Protocol):\n    pass\n\n\n@runtime_checkable\nclass RuntimeCheckableMetricInputMeasure(MetricProtocols.MetricInputMeasure, Protocol):\n    pass\n\n\n@runtime_checkable\nclass RuntimeCheckableMetricTypeParams(MetricProtocols.MetricTypeParams, Protocol):\n    pass\n\n\n@runtime_checkable\nclass RuntimeCheckableWhereFilter(WhereFilterProtocol, Protocol):\n    pass\n\n\n@runtime_checkable\nclass RuntimeCheckableNonAdditiveDimension(\n    MeasureProtocols.NonAdditiveDimensionParameters, Protocol\n):\n    pass\n\n\n@runtime_checkable\nclass RuntimeCheckableFileSlice(MetadataProtocols.FileSlice, Protocol):\n    pass\n\n\n@runtime_checkable\nclass RuntimeCheckableSourceFileMetadata(MetadataProtocols.Metadata, Protocol):\n    pass\n\n\n@runtime_checkable\nclass RuntimeCheckableSemanticModelDefaults(\n    SemanticModelProtocols.SemanticModelDefaults, Protocol\n):\n    pass\n\n\n@runtime_checkable\nclass RuntimeCheckableDimensionValidityParams(\n    DimensionProtocols.DimensionValidityParams, Protocol\n):\n    pass\n\n\n@runtime_checkable\nclass RuntimeCheckableDimensionTypeParams(DimensionProtocols.DimensionTypeParams, Protocol):\n    pass\n\n\n@runtime_checkable\nclass RuntimeCheckableMeasureAggregationParams(\n    MeasureProtocols.MeasureAggregationParameters, Protocol\n):\n    pass\n\n\n@runtime_checkable\nclass RuntimeCheckableMetricTimeWindow(MetricProtocols.MetricTimeWindow, Protocol):\n    pass\n\n\n@runtime_checkable\nclass RuntimeCheckableSavedQuery(SavedQueryProtocols.SavedQuery, Protocol):\n    pass\n\n\n@pytest.fixture(scope=\"session\")\ndef file_slice() -> FileSlice:\n    return FileSlice(\n        filename=\"test_filename\", content=\"test content\", start_line_number=0, end_line_number=1\n    )\n\n\n@pytest.fixture(scope=\"session\")\ndef source_file_metadata(file_slice) -> SourceFileMetadata:\n    return SourceFileMetadata(\n        repo_file_path=\"test/file/path.yml\",\n        file_slice=file_slice,\n    )\n\n\n@pytest.fixture(scope=\"session\")\ndef semantic_model_defaults() -> Defaults:\n    return Defaults(agg_time_dimension=\"test_time_dimension\")\n\n\n@pytest.fixture(scope=\"session\")\ndef dimension_validity_params() -> DimensionValidityParams:\n    return DimensionValidityParams()\n\n\n@pytest.fixture(scope=\"session\")\ndef dimension_type_params() -> DimensionTypeParams:\n    return DimensionTypeParams(time_granularity=TimeGranularity.DAY)\n\n\n@pytest.fixture(scope=\"session\")\ndef measure_agg_params() -> MeasureAggregationParameters:\n    return MeasureAggregationParameters()\n\n\n@pytest.fixture(scope=\"session\")\ndef non_additive_dimension() -> NonAdditiveDimension:\n    return NonAdditiveDimension(\n        name=\"dimension_name\",\n        window_choice=AggregationType.MIN,\n        window_groupings=[\"entity_name\"],\n    )\n\n\n@pytest.fixture(scope=\"session\")\ndef where_filter() -> WhereFilter:\n    return WhereFilter(\n        where_sql_template=\"{{ Dimension('enity_name__dimension_name') }} AND {{ TimeDimension('entity_name__time_dimension_name', 'month') }} AND {{ Entity('entity_name') }}\"\n    )\n\n\n@pytest.fixture(scope=\"session\")\ndef metric_time_window() -> MetricTimeWindow:\n    return MetricTimeWindow(count=1, granularity=TimeGranularity.DAY.value)\n\n\n@pytest.fixture(scope=\"session\")\ndef simple_metric_input() -> MetricInput:\n    return MetricInput(name=\"test_simple_metric_input\")\n\n\n@pytest.fixture(scope=\"session\")\ndef complex_metric_input(metric_time_window, where_filter) -> MetricInput:\n    return MetricInput(\n        name=\"test_complex_metric_input\",\n        filter=where_filter,\n        alias=\"aliased_metric_input\",\n        offset_window=metric_time_window,\n        offset_to_grain=TimeGranularity.DAY.value,\n    )\n\n\n@pytest.fixture(scope=\"session\")\ndef simple_metric_input_measure() -> MetricInputMeasure:\n    return MetricInputMeasure(name=\"test_simple_metric_input_measure\")\n\n\n@pytest.fixture(scope=\"session\")\ndef complex_metric_input_measure(where_filter) -> MetricInputMeasure:\n    return MetricInputMeasure(\n        name=\"test_complex_metric_input_measure\",\n        filter=where_filter,\n        alias=\"complex_alias\",\n        join_to_timespine=True,\n        fill_nulls_with=0,\n    )\n\n\n@pytest.fixture(scope=\"session\")\ndef conversion_type_params(\n    simple_metric_input_measure, metric_time_window\n) -> ConversionTypeParams:\n    return ConversionTypeParams(\n        base_measure=simple_metric_input_measure,\n        conversion_measure=simple_metric_input_measure,\n        entity=\"entity\",\n        window=metric_time_window,\n        constant_properties=[\n            ConstantPropertyInput(base_property=\"base\", conversion_property=\"conversion\")\n        ],\n    )\n\n\n@pytest.fixture(scope=\"session\")\ndef cumulative_type_params() -> CumulativeTypeParams:\n    return CumulativeTypeParams()\n\n\n@pytest.fixture(scope=\"session\")\ndef complex_metric_type_params(\n    metric_time_window,\n    simple_metric_input,\n    simple_metric_input_measure,\n    conversion_type_params,\n    cumulative_type_params,\n) -> MetricTypeParams:\n    return MetricTypeParams(\n        measure=simple_metric_input_measure,\n        numerator=simple_metric_input,\n        denominator=simple_metric_input,\n        expr=\"1 = 1\",\n        window=metric_time_window,\n        grain_to_date=TimeGranularity.DAY,\n        metrics=[simple_metric_input],\n        conversion_type_params=conversion_type_params,\n        cumulative_type_params=cumulative_type_params,\n    )\n\n\ndef test_file_slice_obj_satisfies_protocol(file_slice):\n    assert isinstance(file_slice, RuntimeCheckableFileSlice)\n\n\ndef test_metadata_obj_satisfies_protocol(source_file_metadata):\n    assert isinstance(source_file_metadata, RuntimeCheckableSourceFileMetadata)\n\n\ndef test_defaults_obj_satisfies_protocol(semantic_model_defaults):\n    assert isinstance(semantic_model_defaults, RuntimeCheckableSemanticModelDefaults)\n    assert isinstance(Defaults(), RuntimeCheckableSemanticModelDefaults)\n\n\ndef test_dimension_validity_params_satisfies_protocol(dimension_validity_params):\n    assert isinstance(dimension_validity_params, RuntimeCheckableDimensionValidityParams)\n\n\ndef test_dimension_type_params_satisfies_protocol(\n    dimension_type_params, dimension_validity_params\n):\n    assert isinstance(dimension_type_params, RuntimeCheckableDimensionTypeParams)\n\n    # check with validity params specified\n    optionals_specified_type_params = copy.deepcopy(dimension_type_params)\n    optionals_specified_type_params.validity_params = dimension_validity_params\n    assert isinstance(optionals_specified_type_params, RuntimeCheckableDimensionTypeParams)\n\n\ndef test_measure_aggregation_params_satisfies_protocol(measure_agg_params):\n    assert isinstance(measure_agg_params, RuntimeCheckableMeasureAggregationParams)\n\n    # check with optionals specified\n    optionals_specified_measure_agg_params = copy.deepcopy(measure_agg_params)\n    optionals_specified_measure_agg_params.percentile = 0.5\n    assert isinstance(\n        optionals_specified_measure_agg_params, RuntimeCheckableMeasureAggregationParams\n    )\n\n\ndef test_semantic_model_node_satisfies_protocol_optionals_unspecified():\n    test_semantic_model = SemanticModel(\n        name=\"test_semantic_model\",\n        resource_type=NodeType.SemanticModel,\n        package_name=\"package_name\",\n        path=\"path.to.semantic_model\",\n        original_file_path=\"path/to/file\",\n        unique_id=\"not_like_the_other_semantic_models\",\n        fqn=[\"fully\", \"qualified\", \"name\"],\n        model=\"ref('a_model')\",\n        # Technically NodeRelation is optional on our SemanticModel implementation\n        # however, it's functionally always loaded, it's just delayed.\n        # This will type/state mismatch will likely bite us at some point\n        node_relation=NodeRelation(\n            alias=\"test_alias\",\n            schema_name=\"test_schema_name\",\n        ),\n    )\n    assert isinstance(test_semantic_model, RuntimeCheckableSemanticModel)\n\n\ndef test_semantic_model_node_satisfies_protocol_optionals_specified(\n    semantic_model_defaults, source_file_metadata\n):\n    test_semantic_model = SemanticModel(\n        name=\"test_semantic_model\",\n        resource_type=NodeType.SemanticModel,\n        package_name=\"package_name\",\n        path=\"path.to.semantic_model\",\n        original_file_path=\"path/to/file\",\n        unique_id=\"not_like_the_other_semantic_models\",\n        fqn=[\"fully\", \"qualified\", \"name\"],\n        model=\"ref('a_model')\",\n        node_relation=NodeRelation(\n            alias=\"test_alias\",\n            schema_name=\"test_schema_name\",\n        ),\n        description=\"test_description\",\n        label=\"test label\",\n        defaults=semantic_model_defaults,\n        metadata=source_file_metadata,\n        primary_entity=\"test_primary_entity\",\n    )\n    assert isinstance(test_semantic_model, RuntimeCheckableSemanticModel)\n\n\ndef test_dimension_satisfies_protocol_optionals_unspecified():\n    dimension = Dimension(\n        name=\"test_dimension\",\n        type=DimensionType.TIME,\n    )\n    assert isinstance(dimension, RuntimeCheckableDimension)\n\n\ndef test_dimension_satisfies_protocol_optionals_specified(\n    dimension_type_params, source_file_metadata\n):\n    dimension = Dimension(\n        name=\"test_dimension\",\n        type=DimensionType.TIME,\n        description=\"test_description\",\n        label=\"test_label\",\n        type_params=dimension_type_params,\n        expr=\"1\",\n        metadata=source_file_metadata,\n    )\n    assert isinstance(dimension, RuntimeCheckableDimension)\n\n\ndef test_entity_satisfies_protocol_optionals_unspecified():\n    entity = Entity(\n        name=\"test_entity\",\n        type=EntityType.PRIMARY,\n    )\n    assert isinstance(entity, RuntimeCheckableEntity)\n\n\ndef test_entity_satisfies_protocol_optionals_specified():\n    entity = Entity(\n        name=\"test_entity\",\n        description=\"a test entity\",\n        label=\"A test entity\",\n        type=EntityType.PRIMARY,\n        expr=\"id\",\n        role=\"a_role\",\n    )\n    assert isinstance(entity, RuntimeCheckableEntity)\n\n\ndef test_measure_satisfies_protocol_optionals_unspecified():\n    measure = Measure(\n        name=\"test_measure\",\n        agg=\"sum\",\n    )\n    assert isinstance(measure, RuntimeCheckableMeasure)\n\n\ndef test_measure_satisfies_protocol_optionals_specified(\n    measure_agg_params, non_additive_dimension\n):\n    measure = Measure(\n        name=\"test_measure\",\n        description=\"a test measure\",\n        label=\"A test measure\",\n        agg=\"sum\",\n        create_metric=True,\n        expr=\"amount\",\n        agg_params=measure_agg_params,\n        non_additive_dimension=non_additive_dimension,\n        agg_time_dimension=\"a_time_dimension\",\n    )\n    assert isinstance(measure, RuntimeCheckableMeasure)\n\n\n@pytest.mark.skip(reason=\"Overly sensitive to non-breaking changes\")\ndef test_metric_node_satisfies_protocol_optionals_unspecified():\n    metric = Metric(\n        name=\"a_metric\",\n        resource_type=NodeType.Metric,\n        package_name=\"package_name\",\n        path=\"path.to.semantic_model\",\n        original_file_path=\"path/to/file\",\n        unique_id=\"not_like_the_other_semantic_models\",\n        fqn=[\"fully\", \"qualified\", \"name\"],\n        description=\"a test metric\",\n        label=\"A test metric\",\n        type=MetricType.SIMPLE,\n        type_params=MetricTypeParams(\n            measure=MetricInputMeasure(\n                name=\"a_test_measure\", filter=WhereFilter(where_sql_template=\"a_dimension is true\")\n            )\n        ),\n    )\n    assert isinstance(metric, RuntimeCheckableMetric)\n\n\n@pytest.mark.skip(reason=\"Overly sensitive to non-breaking changes\")\ndef test_metric_node_satisfies_protocol_optionals_specified(\n    complex_metric_type_params, source_file_metadata, where_filter\n):\n    metric = Metric(\n        name=\"a_metric\",\n        resource_type=NodeType.Metric,\n        package_name=\"package_name\",\n        path=\"path.to.semantic_model\",\n        original_file_path=\"path/to/file\",\n        unique_id=\"not_like_the_other_semantic_models\",\n        fqn=[\"fully\", \"qualified\", \"name\"],\n        description=\"a test metric\",\n        label=\"A test metric\",\n        type=MetricType.SIMPLE,\n        type_params=complex_metric_type_params,\n        filter=where_filter,\n        metadata=source_file_metadata,\n        group=\"test_group\",\n    )\n    assert isinstance(metric, RuntimeCheckableMetric)\n\n\ndef test_where_filter_satisfies_protocol(where_filter):\n    assert isinstance(where_filter, RuntimeCheckableWhereFilter)\n\n\ndef test_metric_time_window(metric_time_window):\n    assert isinstance(metric_time_window, RuntimeCheckableMetricTimeWindow)\n\n\ndef test_metric_input(simple_metric_input, complex_metric_input):\n    assert isinstance(simple_metric_input, RuntimeCheckableMetricInput)\n    assert isinstance(complex_metric_input, RuntimeCheckableMetricInput)\n\n\ndef test_metric_input_measure(simple_metric_input_measure, complex_metric_input_measure):\n    assert isinstance(simple_metric_input_measure, RuntimeCheckableMetricInputMeasure)\n    assert isinstance(complex_metric_input_measure, RuntimeCheckableMetricInputMeasure)\n\n\n@pytest.mark.skip(reason=\"Overly sensitive to non-breaking changes\")\ndef test_metric_type_params_satisfies_protocol(complex_metric_type_params):\n    assert isinstance(MetricTypeParams(), RuntimeCheckableMetricTypeParams)\n    assert isinstance(complex_metric_type_params, RuntimeCheckableMetricTypeParams)\n\n\ndef test_non_additive_dimension_satisfies_protocol(non_additive_dimension):\n    assert isinstance(non_additive_dimension, RuntimeCheckableNonAdditiveDimension)\n\n\n@given(\n    builds(\n        SavedQuery,\n        description=text() | none(),\n        label=text() | none(),\n        metadata=builds(SourceFileMetadata) | none(),\n    )\n)\n@settings(suppress_health_check=(HealthCheck.too_slow,))\ndef test_saved_query_satisfies_protocol(saved_query: SavedQuery):\n    assert isinstance(saved_query, SavedQuery)\n"
  },
  {
    "path": "tests/unit/test_tracking.py",
    "content": "import datetime\nimport tempfile\n\nimport pytest\n\nimport dbt.tracking\n\n\n@pytest.fixture(scope=\"function\")\ndef active_user_none() -> None:\n    dbt.tracking.active_user = None\n\n\n@pytest.fixture(scope=\"function\")\ndef tempdir(active_user_none) -> str:\n    return tempfile.mkdtemp()\n\n\nclass TestTracking:\n    def test_tracking_initial(self, tempdir):\n        assert dbt.tracking.active_user is None\n        dbt.tracking.initialize_from_flags(True, tempdir)\n        assert isinstance(dbt.tracking.active_user, dbt.tracking.User)\n\n        invocation_id = dbt.tracking.active_user.invocation_id\n        run_started_at = dbt.tracking.active_user.run_started_at\n\n        assert dbt.tracking.active_user.do_not_track is False\n        assert isinstance(dbt.tracking.active_user.id, str)\n        assert isinstance(invocation_id, str)\n        assert isinstance(run_started_at, datetime.datetime)\n\n        dbt.tracking.disable_tracking()\n        assert isinstance(dbt.tracking.active_user, dbt.tracking.User)\n\n        assert dbt.tracking.active_user.do_not_track is True\n        assert dbt.tracking.active_user.id is None\n        assert dbt.tracking.active_user.invocation_id == invocation_id\n        assert dbt.tracking.active_user.run_started_at == run_started_at\n\n        # this should generate a whole new user object -> new run_started_at\n        dbt.tracking.do_not_track()\n        assert isinstance(dbt.tracking.active_user, dbt.tracking.User)\n\n        assert dbt.tracking.active_user.do_not_track is True\n        assert dbt.tracking.active_user.id is None\n        assert isinstance(dbt.tracking.active_user.invocation_id, str)\n        assert isinstance(dbt.tracking.active_user.run_started_at, datetime.datetime)\n        # invocation_id no longer only linked to active_user so it doesn't change\n        assert dbt.tracking.active_user.invocation_id == invocation_id\n        # if you use `!=`, you might hit a race condition (especially on windows)\n        assert dbt.tracking.active_user.run_started_at is not run_started_at\n\n    def test_tracking_never_ok(self, active_user_none):\n        assert dbt.tracking.active_user is None\n\n        # this should generate a whole new user object -> new invocation_id/run_started_at\n        dbt.tracking.do_not_track()\n        assert isinstance(dbt.tracking.active_user, dbt.tracking.User)\n\n        assert dbt.tracking.active_user.do_not_track is True\n        assert dbt.tracking.active_user.id is None\n        assert isinstance(dbt.tracking.active_user.invocation_id, str)\n        assert isinstance(dbt.tracking.active_user.run_started_at, datetime.datetime)\n\n    def test_disable_never_enabled(self, active_user_none):\n        assert dbt.tracking.active_user is None\n\n        # this should generate a whole new user object -> new invocation_id/run_started_at\n        dbt.tracking.disable_tracking()\n        assert isinstance(dbt.tracking.active_user, dbt.tracking.User)\n\n        assert dbt.tracking.active_user.do_not_track is True\n        assert dbt.tracking.active_user.id is None\n        assert isinstance(dbt.tracking.active_user.invocation_id, str)\n        assert isinstance(dbt.tracking.active_user.run_started_at, datetime.datetime)\n\n    @pytest.mark.parametrize(\"send_anonymous_usage_stats\", [True, False])\n    def test_initialize_from_flags(self, tempdir, send_anonymous_usage_stats):\n        dbt.tracking.initialize_from_flags(send_anonymous_usage_stats, tempdir)\n        assert dbt.tracking.active_user.do_not_track != send_anonymous_usage_stats\n"
  },
  {
    "path": "tests/unit/test_utils.py",
    "content": "import unittest\n\nimport dbt.exceptions\nimport dbt.utils\n\n\nclass TestMultiDict(unittest.TestCase):\n    def test_one_member(self):\n        dct = {\"a\": 1, \"b\": 2, \"c\": 3}\n        md = dbt.utils.MultiDict([dct])\n        assert len(md) == 3\n        for key in \"abc\":\n            assert key in md\n        assert md[\"a\"] == 1\n        assert md[\"b\"] == 2\n        assert md[\"c\"] == 3\n\n    def test_two_members_no_overlap(self):\n        first = {\"a\": 1, \"b\": 2, \"c\": 3}\n        second = {\"d\": 1, \"e\": 2, \"f\": 3}\n        md = dbt.utils.MultiDict([first, second])\n        assert len(md) == 6\n        for key in \"abcdef\":\n            assert key in md\n        assert md[\"a\"] == 1\n        assert md[\"b\"] == 2\n        assert md[\"c\"] == 3\n        assert md[\"d\"] == 1\n        assert md[\"e\"] == 2\n        assert md[\"f\"] == 3\n\n    def test_two_members_overlap(self):\n        first = {\"a\": 1, \"b\": 2, \"c\": 3}\n        second = {\"c\": 1, \"d\": 2, \"e\": 3}\n        md = dbt.utils.MultiDict([first, second])\n        assert len(md) == 5\n        for key in \"abcde\":\n            assert key in md\n        assert md[\"a\"] == 1\n        assert md[\"b\"] == 2\n        assert md[\"c\"] == 1\n        assert md[\"d\"] == 2\n        assert md[\"e\"] == 3\n\n\nclass TestHumanizeExecutionTime(unittest.TestCase):\n    def test_humanzing_execution_time_with_integer(self):\n\n        result = dbt.utils.humanize_execution_time(execution_time=9460)\n\n        assert result == \" in 2 hours 37 minutes and 40.00 seconds\"\n\n    def test_humanzing_execution_time_with_two_decimal_place_float(self):\n\n        result = dbt.utils.humanize_execution_time(execution_time=0.32)\n\n        assert result == \" in 0 hours 0 minutes and 0.32 seconds\"\n\n    def test_humanzing_execution_time_with_four_decimal_place_float(self):\n\n        result = dbt.utils.humanize_execution_time(execution_time=0.3254)\n\n        assert result == \" in 0 hours 0 minutes and 0.33 seconds\"\n"
  },
  {
    "path": "tests/unit/test_version.py",
    "content": "import dbt.version\nfrom dbt_common.ui import green, yellow\n\n\nclass TestGetVersionInformation:\n    def test_all_versions_equal(self, mocker):\n        mock_versions(\n            mocker,\n            installed=\"1.0.0\",\n            latest=\"1.0.0\",\n            plugins={\n                \"foobar\": (\"1.0.0\", \"1.0.0\"),\n            },\n        )\n\n        actual = dbt.version.get_version_information()\n        expected = \"\\n\".join(\n            [\n                \"Core:\",\n                \"  - installed: 1.0.0\",\n                f\"  - latest:    1.0.0 - {green('Up to date!')}\",\n                \"\",\n                \"Plugins:\",\n                f\"  - foobar: 1.0.0 - {green('Up to date!')}\",\n                \"\",\n                \"\",\n            ]\n        )\n\n        assert expected == actual\n\n    def test_core_ahead(self, mocker):\n        mock_versions(\n            mocker,\n            installed=\"1.0.1\",\n            latest=\"1.0.0\",\n            plugins={\n                \"foobar\": (\"1.0.0\", \"1.0.0\"),\n            },\n        )\n\n        actual = dbt.version.get_version_information()\n        expected = \"\\n\".join(\n            [\n                \"Core:\",\n                \"  - installed: 1.0.1\",\n                f\"  - latest:    1.0.0 - {yellow('Ahead of latest version!')}\",\n                \"\",\n                \"Plugins:\",\n                f\"  - foobar: 1.0.0 - {green('Up to date!')}\",\n                \"\",\n                \"\",\n            ]\n        )\n\n        assert expected == actual\n\n    def test_core_behind(self, mocker):\n        mock_versions(\n            mocker,\n            installed=\"1.0.0\",\n            latest=\"1.0.1\",\n            plugins={\n                \"foobar\": (\"1.0.0\", \"1.0.0\"),\n            },\n        )\n\n        actual = dbt.version.get_version_information()\n        expected = \"\\n\".join(\n            [\n                \"Core:\",\n                \"  - installed: 1.0.0\",\n                f\"  - latest:    1.0.1 - {yellow('Update available!')}\",\n                \"\",\n                \"  Your version of dbt-core is out of date!\",\n                \"  You can find instructions for upgrading here:\",\n                \"  https://docs.getdbt.com/docs/installation\",\n                \"\",\n                \"Plugins:\",\n                f\"  - foobar: 1.0.0 - {green('Up to date!')}\",\n                \"\",\n                \"\",\n            ]\n        )\n\n        assert expected == actual\n\n    def test_core_no_latest(self, mocker):\n        mock_versions(\n            mocker,\n            installed=\"1.0.0\",\n            plugins={\n                \"foobar\": (\"1.0.0\", \"1.0.0\"),\n            },\n        )\n\n        actual = dbt.version.get_version_information()\n        expected = \"\\n\".join(\n            [\n                \"Core:\",\n                \"  - installed: 1.0.0\",\n                \"\",\n                \"  The latest version of dbt-core could not be determined!\",\n                \"  Make sure that the following URL is accessible:\",\n                \"  https://pypi.org/pypi/dbt-core/json\",\n                \"\",\n                \"Plugins:\",\n                f\"  - foobar: 1.0.0 - {green('Up to date!')}\",\n                \"\",\n                \"\",\n            ]\n        )\n\n        assert expected == actual\n\n    def test_plugins_none(self, mocker):\n        mock_versions(\n            mocker,\n            installed=\"1.0.0\",\n            latest=\"1.0.0\",\n        )\n\n        actual = dbt.version.get_version_information()\n        expected = \"\\n\".join(\n            [\n                \"Core:\",\n                \"  - installed: 1.0.0\",\n                f\"  - latest:    1.0.0 - {green('Up to date!')}\",\n                \"\",\n                \"Plugins:\",\n                \"\",\n                \"\",\n            ]\n        )\n\n        assert expected == actual\n\n    def test_plugins_multiple(self, mocker):\n        mock_versions(\n            mocker,\n            installed=\"1.0.0\",\n            latest=\"1.0.0\",\n            plugins={\n                \"foobar\": (\"1.0.0\", \"1.0.0\"),\n                \"bazqux\": (\"1.0.0\", \"1.0.0\"),\n                \"quuxcorge\": (\"1.0.0\", \"1.0.0\"),\n                \"graultgarply\": (\"1.0.0\", \"1.0.0\"),\n            },\n        )\n\n        actual = dbt.version.get_version_information()\n        expected = \"\\n\".join(\n            [\n                \"Core:\",\n                \"  - installed: 1.0.0\",\n                f\"  - latest:    1.0.0 - {green('Up to date!')}\",\n                \"\",\n                \"Plugins:\",\n                f\"  - foobar:       1.0.0 - {green('Up to date!')}\",\n                f\"  - bazqux:       1.0.0 - {green('Up to date!')}\",\n                f\"  - quuxcorge:    1.0.0 - {green('Up to date!')}\",\n                f\"  - graultgarply: 1.0.0 - {green('Up to date!')}\",\n                \"\",\n                \"\",\n            ]\n        )\n\n        assert expected == actual\n\n    def test_plugin_match_core_match_latest(self, mocker):\n        mock_versions(\n            mocker,\n            installed=\"1.0.0\",\n            latest=\"1.0.0\",\n            plugins={\n                \"foobar\": (\"1.0.0\", \"1.0.0\"),\n            },\n        )\n\n        actual = dbt.version.get_version_information()\n        expected = \"\\n\".join(\n            [\n                \"Core:\",\n                \"  - installed: 1.0.0\",\n                f\"  - latest:    1.0.0 - {green('Up to date!')}\",\n                \"\",\n                \"Plugins:\",\n                f\"  - foobar: 1.0.0 - {green('Up to date!')}\",\n                \"\",\n                \"\",\n            ]\n        )\n\n        assert expected == actual\n\n    def test_plugin_match_core_no_latest(self, mocker):\n        mock_versions(\n            mocker,\n            installed=\"1.0.0\",\n            latest=\"1.0.0\",\n            plugins={\n                \"foobar\": (\"1.0.0\", None),\n            },\n        )\n\n        actual = dbt.version.get_version_information()\n        expected = \"\\n\".join(\n            [\n                \"Core:\",\n                \"  - installed: 1.0.0\",\n                f\"  - latest:    1.0.0 - {green('Up to date!')}\",\n                \"\",\n                \"Plugins:\",\n                f\"  - foobar: 1.0.0 - {yellow('Could not determine latest version')}\",\n                \"\",\n                \"\",\n            ]\n        )\n\n        assert expected == actual\n\n    def test_plugin_match_core_behind_latest(self, mocker):\n        mock_versions(\n            mocker,\n            installed=\"1.0.0\",\n            latest=\"1.0.0\",\n            plugins={\n                \"foobar\": (\"1.0.0\", \"2.0.0\"),\n            },\n        )\n\n        actual = dbt.version.get_version_information()\n        expected = \"\\n\".join(\n            [\n                \"Core:\",\n                \"  - installed: 1.0.0\",\n                f\"  - latest:    1.0.0 - {green('Up to date!')}\",\n                \"\",\n                \"Plugins:\",\n                f\"  - foobar: 1.0.0 - {yellow('Update available!')}\",\n                \"\",\n                \"  At least one plugin is out of date with dbt-core.\",\n                \"  You can find instructions for upgrading here:\",\n                \"  https://docs.getdbt.com/docs/installation\",\n                \"\",\n                \"\",\n            ]\n        )\n\n        assert expected == actual\n\n    def test_plugin_match_core_ahead_latest(self, mocker):\n        mock_versions(\n            mocker,\n            installed=\"1.0.0\",\n            latest=\"1.0.0\",\n            plugins={\n                \"foobar\": (\"1.0.0\", \"2.0.0\"),\n            },\n        )\n\n        actual = dbt.version.get_version_information()\n        expected = \"\\n\".join(\n            [\n                \"Core:\",\n                \"  - installed: 1.0.0\",\n                f\"  - latest:    1.0.0 - {green('Up to date!')}\",\n                \"\",\n                \"Plugins:\",\n                f\"  - foobar: 1.0.0 - {yellow('Update available!')}\",\n                \"\",\n                \"  At least one plugin is out of date with dbt-core.\",\n                \"  You can find instructions for upgrading here:\",\n                \"  https://docs.getdbt.com/docs/installation\",\n                \"\",\n                \"\",\n            ]\n        )\n\n        assert expected == actual\n\n    def test_plugin_diff_core_minor_match_latest(self, mocker):\n        mock_versions(\n            mocker,\n            installed=\"1.1.0\",\n            latest=\"1.1.0\",\n            plugins={\n                \"foobar\": (\"1.0.0\", \"1.0.0\"),\n            },\n        )\n\n        actual = dbt.version.get_version_information()\n        expected = \"\\n\".join(\n            [\n                \"Core:\",\n                \"  - installed: 1.1.0\",\n                f\"  - latest:    1.1.0 - {green('Up to date!')}\",\n                \"\",\n                \"Plugins:\",\n                f\"  - foobar: 1.0.0 - {green('Up to date!')}\",\n                \"\",\n                \"\",\n            ]\n        )\n\n        assert expected == actual\n\n    def test_plugin_diff_core_minor_no_latest(self, mocker):\n        mock_versions(\n            mocker,\n            installed=\"1.1.0\",\n            latest=\"1.1.0\",\n            plugins={\n                \"foobar\": (\"1.0.0\", None),\n            },\n        )\n\n        actual = dbt.version.get_version_information()\n        expected = \"\\n\".join(\n            [\n                \"Core:\",\n                \"  - installed: 1.1.0\",\n                f\"  - latest:    1.1.0 - {green('Up to date!')}\",\n                \"\",\n                \"Plugins:\",\n                f\"  - foobar: 1.0.0 - {yellow('Could not determine latest version')}\",\n                \"\",\n                \"\",\n            ]\n        )\n\n        assert expected == actual\n\n    def test_plugin_diff_core_minor_ahead_latest(self, mocker):\n        mock_versions(\n            mocker,\n            installed=\"1.1.0\",\n            latest=\"1.1.0\",\n            plugins={\n                \"foobar\": (\"1.0.0\", \"0.0.1\"),\n            },\n        )\n\n        actual = dbt.version.get_version_information()\n        expected = \"\\n\".join(\n            [\n                \"Core:\",\n                \"  - installed: 1.1.0\",\n                f\"  - latest:    1.1.0 - {green('Up to date!')}\",\n                \"\",\n                \"Plugins:\",\n                f\"  - foobar: 1.0.0 - {yellow('Ahead of latest version!')}\",\n                \"\",\n                \"\",\n            ]\n        )\n\n        assert expected == actual\n\n    def test_plugin_diff_plugin_minor_ahead_latest(self, mocker):\n        \"\"\"\n        Now that adapters are decoupled from core, a higher minor version of a plugin\n        is compatible with a lower minor version of core.\n        \"\"\"\n\n        mock_versions(\n            mocker,\n            installed=\"1.8.0\",\n            latest=\"1.8.0\",\n            plugins={\n                \"foobar\": (\"1.9.0\", \"1.9.0\"),\n            },\n        )\n\n        actual = dbt.version.get_version_information()\n        expected = \"\\n\".join(\n            [\n                \"Core:\",\n                \"  - installed: 1.8.0\",\n                f\"  - latest:    1.8.0 - {green('Up to date!')}\",\n                \"\",\n                \"Plugins:\",\n                f\"  - foobar: 1.9.0 - {green('Up to date!')}\",\n                \"\",\n                \"\",\n            ]\n        )\n\n        assert expected == actual\n\n    def test_plugin_diff_plugin_patch_ahead_latest(self, mocker):\n        \"\"\"\n        Now that adapters are decoupled from core, a higher minor version of a plugin\n        is compatible with a lower minor version of core.\n        \"\"\"\n\n        mock_versions(\n            mocker,\n            installed=\"1.8.0\",\n            latest=\"1.8.0\",\n            plugins={\n                \"foobar\": (\"1.8.4\", \"1.8.4\"),\n            },\n        )\n\n        actual = dbt.version.get_version_information()\n        expected = \"\\n\".join(\n            [\n                \"Core:\",\n                \"  - installed: 1.8.0\",\n                f\"  - latest:    1.8.0 - {green('Up to date!')}\",\n                \"\",\n                \"Plugins:\",\n                f\"  - foobar: 1.8.4 - {green('Up to date!')}\",\n                \"\",\n                \"\",\n            ]\n        )\n\n        assert expected == actual\n\n    def test_plugin_diff_plugin_minor_ahead_no_latest(self, mocker):\n        \"\"\"\n        Now that adapters are decoupled from core, a higher minor version of a plugin\n        is compatible with a lower minor version of core.\n        \"\"\"\n\n        mock_versions(\n            mocker,\n            installed=\"1.8.0\",\n            latest=\"1.8.0\",\n            plugins={\n                \"foobar\": (\"1.9.0\", None),\n            },\n        )\n\n        actual = dbt.version.get_version_information()\n        expected = \"\\n\".join(\n            [\n                \"Core:\",\n                \"  - installed: 1.8.0\",\n                f\"  - latest:    1.8.0 - {green('Up to date!')}\",\n                \"\",\n                \"Plugins:\",\n                f\"  - foobar: 1.9.0 - {yellow('Could not determine latest version')}\",\n                \"\",\n                \"\",\n            ]\n        )\n\n        assert expected == actual\n\n    def test_plugin_diff_plugin_minor_behind_core_no_latest(self, mocker):\n        \"\"\"\n        Now that adapters are decoupled from core, a lower minor version of a plugin (1.8)\n        is compatible with a higher minor version of core. (1.9)\n        \"\"\"\n\n        mock_versions(\n            mocker,\n            installed=\"1.9.0\",\n            latest=\"1.9.0\",\n            plugins={\n                \"foobar\": (\"1.8.0\", \"1.8.0\"),\n            },\n        )\n\n        actual = dbt.version.get_version_information()\n        expected = \"\\n\".join(\n            [\n                \"Core:\",\n                \"  - installed: 1.9.0\",\n                f\"  - latest:    1.9.0 - {green('Up to date!')}\",\n                \"\",\n                \"Plugins:\",\n                f\"  - foobar: 1.8.0 - {green('Up to date!')}\",\n                \"\",\n                \"\",\n            ]\n        )\n\n        assert expected == actual\n\n    def test_plugin_diff_core_minor_behind_latest(self, mocker):\n        mock_versions(\n            mocker,\n            installed=\"1.1.0\",\n            latest=\"1.1.0\",\n            plugins={\n                \"foobar\": (\"1.0.0\", \"1.0.1\"),\n            },\n        )\n\n        actual = dbt.version.get_version_information()\n        expected = \"\\n\".join(\n            [\n                \"Core:\",\n                \"  - installed: 1.1.0\",\n                f\"  - latest:    1.1.0 - {green('Up to date!')}\",\n                \"\",\n                \"Plugins:\",\n                f\"  - foobar: 1.0.0 - {yellow('Update available!')}\",\n                \"\",\n                \"  At least one plugin is out of date with dbt-core.\",\n                \"  You can find instructions for upgrading here:\",\n                \"  https://docs.getdbt.com/docs/installation\",\n                \"\",\n                \"\",\n            ]\n        )\n\n        assert expected == actual\n\n    def test_plugins_various(self, mocker):\n        mock_versions(\n            mocker,\n            installed=\"2.1.0\",\n            latest=\"2.1.0\",\n            plugins={\n                \"foobar\": (\"2.1.0\", \"2.1.0\"),\n                \"bazqux\": (\"2.1.0\", None),\n                \"quuux\": (\"2.1.0\", \"2.1.0\"),\n                \"grault\": (\"2.1.0\", \"2.1.1\"),\n                \"garply\": (\"2.1.0-b1\", None),\n            },\n        )\n\n        actual = dbt.version.get_version_information()\n        expected = \"\\n\".join(\n            [\n                \"Core:\",\n                \"  - installed: 2.1.0\",\n                f\"  - latest:    2.1.0 - {green('Up to date!')}\",\n                \"\",\n                \"Plugins:\",\n                f\"  - foobar: 2.1.0    - {green('Up to date!')}\",\n                f\"  - bazqux: 2.1.0    - {yellow('Could not determine latest version')}\",\n                f\"  - quuux:  2.1.0    - {green('Up to date!')}\",\n                f\"  - grault: 2.1.0    - {yellow('Update available!')}\",\n                f\"  - garply: 2.1.0-b1 - {yellow('Could not determine latest version')}\",\n                \"\",\n                \"  At least one plugin is out of date with dbt-core.\",\n                \"  You can find instructions for upgrading here:\",\n                \"  https://docs.getdbt.com/docs/installation\",\n                \"\",\n                \"\",\n            ]\n        )\n\n        assert expected == actual\n\n    def test_plugins_alignment(self, mocker):\n        mock_versions(\n            mocker,\n            installed=\"1.1.1-b123\",\n            latest=\"1.1.1-b123\",\n            plugins={\n                \"foobar\": (\"1.1.0-b1\", \"1.1.0-b1\"),\n                \"bazqux\": (\"1.1.1-b123\", \"1.1.1-b123\"),\n                \"quuux\": (\"1.1.0\", \"1.1.0\"),\n            },\n        )\n\n        actual = dbt.version.get_version_information()\n        expected = \"\\n\".join(\n            [\n                \"Core:\",\n                \"  - installed: 1.1.1-b123\",\n                f\"  - latest:    1.1.1-b123 - {green('Up to date!')}\",\n                \"\",\n                \"Plugins:\",\n                f\"  - foobar: 1.1.0-b1   - {green('Up to date!')}\",\n                f\"  - bazqux: 1.1.1-b123 - {green('Up to date!')}\",\n                f\"  - quuux:  1.1.0      - {green('Up to date!')}\",\n                \"\",\n                \"\",\n            ]\n        )\n\n        assert expected == actual\n\n    def test_file_globbing(self, mocker):\n        mocker.patch(\"dbt.version.__version__\", \"1.0.0\")\n        mock_latest_versions(mocker, core_latest=\"1.0.0\")\n\n        mocked_spec = mocker.Mock()\n        mocker.patch(\"importlib.util.find_spec\").return_value = mocked_spec\n\n        paths = [\n            \"/some/sort/of/path\",\n            \"/another/path\",\n            \"/yet/another/type/of/path\",\n        ]\n        mocked_spec.submodule_search_locations = paths\n\n        plugins = [\n            \"foobar\",\n            \"bazqux\",\n            \"quuux\",\n            \"corge\",\n            \"grault\",\n            \"garply\",\n        ]\n\n        version_paths = [\n            [\n                f\"/some/sort/of/path/{plugins[0]}/__version__.py\",\n                f\"/some/sort/of/path/{plugins[1]}/__version__.py\",\n            ],\n            [\n                f\"/another/path/{plugins[2]}/__version__.py\",\n                f\"/another/path/{plugins[3]}/__version__.py\",\n            ],\n            [\n                f\"/yet/another/type/of/path/{plugins[4]}/__version__.py\",\n                f\"/yet/another/type/of/path/{plugins[5]}/__version__.py\",\n            ],\n        ]\n\n        def mock_glob(*args, **kwargs):\n            version_glob = args[0]\n            for i, path in enumerate(paths):\n                if path in version_glob:\n                    return version_paths[i]\n\n        mocker.patch(\"glob.glob\").side_effect = mock_glob\n\n        def mock_import(*args, **kwargs):\n            mock_module = mocker.Mock()\n            mock_module.version = \"1.0.0\"\n\n            import_path = args[0]\n\n            for plugin in plugins:\n                if plugin in import_path:\n                    return mock_module\n\n            raise ImportError\n\n        mocker.patch(\"importlib.import_module\").side_effect = mock_import\n\n        actual = dbt.version.get_version_information()\n        expected = \"\\n\".join(\n            [\n                \"Core:\",\n                \"  - installed: 1.0.0\",\n                f\"  - latest:    1.0.0 - {green('Up to date!')}\",\n                \"\",\n                \"Plugins:\",\n                f\"  - foobar: 1.0.0 - {yellow('Could not determine latest version')}\",\n                f\"  - bazqux: 1.0.0 - {yellow('Could not determine latest version')}\",\n                f\"  - quuux:  1.0.0 - {yellow('Could not determine latest version')}\",\n                f\"  - corge:  1.0.0 - {yellow('Could not determine latest version')}\",\n                f\"  - grault: 1.0.0 - {yellow('Could not determine latest version')}\",\n                f\"  - garply: 1.0.0 - {yellow('Could not determine latest version')}\",\n                \"\",\n                \"\",\n            ]\n        )\n\n        assert expected == actual\n\n\ndef mock_versions(mocker, installed=\"1.0.0\", latest=None, plugins={}):\n    mocker.patch(\"dbt.version.__version__\", installed)\n    mock_latest_versions(mocker, latest, plugins)\n    # mock_plugins must be called last to avoid erronously raising an ImportError.\n    mock_plugins(mocker, plugins)\n\n\n# NOTE: mock_plugins patches importlib.import_module, and should always be the last\n# patch to be mocked in order to avoid erronously raising an ImportError.\n# Explanation: As of Python 3.11, mock.patch indirectly uses importlib.import_module\n# and thus uses the mocked object (in this case, mock_import) instead of the real\n# implementation in subsequent mock.patch calls. Issue: https://github.com/python/cpython/issues/98771\ndef mock_plugins(mocker, plugins):\n    mock_find_spec = mocker.patch(\"importlib.util.find_spec\")\n    path = \"/tmp/dbt/adapters\"\n    mock_find_spec.return_value.submodule_search_locations = [path]\n\n    mocker.patch(\"glob.glob\").return_value = [f\"{path}/{name}/__version__.py\" for name in plugins]\n\n    def mock_import(*args, **kwargs):\n        import_path = args[0]\n\n        for plugin_name in plugins:\n            if plugin_name in import_path:\n                plugin_version = plugins.get(plugin_name)[0]\n\n                module_mock = mocker.Mock()\n                module_mock.version = plugin_version\n\n                return module_mock\n\n        raise ImportError\n\n    mocker.patch(\"importlib.import_module\").side_effect = mock_import\n\n\ndef mock_latest_versions(mocker, core_latest=None, plugins={}):\n    def mock_get(*args, **kwargs):\n        mocked_response = mocker.Mock()\n        mocked_response.json.return_value = {\"bad object\": None}\n\n        version_url = args[0]\n\n        if version_url is dbt.version.PYPI_VERSION_URL:\n            if core_latest:\n                mocked_response.json.return_value = {\"info\": {\"version\": core_latest}}\n\n            return mocked_response\n\n        for plugin_name in plugins:\n            if plugin_name in version_url:\n                plugin_latest = plugins.get(plugin_name)[1]\n\n                if plugin_latest:\n                    mocked_response.json.return_value = {\"info\": {\"version\": plugin_latest}}\n\n                return mocked_response\n\n        return mocked_response\n\n    mocker.patch(\"requests.get\").side_effect = mock_get\n"
  },
  {
    "path": "tests/unit/utils/__init__.py",
    "content": "\"\"\"Unit test utility functions.\n\nNote that all imports should be inside the functions to avoid import/mocking\nissues.\n\"\"\"\n\nimport os\nimport string\nfrom unittest import TestCase, mock\n\nimport agate\nimport pytest\n\nfrom dbt.config.project import PartialProject\nfrom dbt.contracts.graph.manifest import Manifest\nfrom dbt_common.dataclass_schema import ValidationError\n\n\ndef normalize(path):\n    \"\"\"On windows, neither is enough on its own:\n\n    >>> normcase('C:\\\\documents/ALL CAPS/subdir\\\\..')\n    'c:\\\\documents\\\\all caps\\\\subdir\\\\..'\n    >>> normpath('C:\\\\documents/ALL CAPS/subdir\\\\..')\n    'C:\\\\documents\\\\ALL CAPS'\n    >>> normpath(normcase('C:\\\\documents/ALL CAPS/subdir\\\\..'))\n    'c:\\\\documents\\\\all caps'\n    \"\"\"\n    return os.path.normcase(os.path.normpath(path))\n\n\nclass Obj:\n    which = \"blah\"\n    single_threaded = False\n\n\ndef mock_connection(name, state=\"open\"):\n    conn = mock.MagicMock()\n    conn.name = name\n    conn.state = state\n    return conn\n\n\ndef profile_from_dict(profile, profile_name, cli_vars=\"{}\"):\n    from dbt.config import Profile\n    from dbt.config.renderer import ProfileRenderer\n    from dbt.config.utils import parse_cli_vars\n\n    if not isinstance(cli_vars, dict):\n        cli_vars = parse_cli_vars(cli_vars)\n\n    renderer = ProfileRenderer(cli_vars)\n    return Profile.from_raw_profile_info(\n        profile,\n        profile_name,\n        renderer,\n    )\n\n\ndef project_from_dict(project, profile, packages=None, selectors=None, cli_vars=\"{}\"):\n    from dbt.config.renderer import DbtProjectYamlRenderer\n    from dbt.config.utils import parse_cli_vars\n\n    if not isinstance(cli_vars, dict):\n        cli_vars = parse_cli_vars(cli_vars)\n\n    renderer = DbtProjectYamlRenderer(profile, cli_vars)\n\n    project_root = project.pop(\"project-root\", os.getcwd())\n\n    partial = PartialProject.from_dicts(\n        project_root=project_root,\n        project_dict=project,\n        packages_dict=packages,\n        selectors_dict=selectors,\n    )\n    return partial.render(renderer)\n\n\ndef config_from_parts_or_dicts(project, profile, packages=None, selectors=None, cli_vars={}):\n    from copy import deepcopy\n\n    from dbt.config import Profile, Project, RuntimeConfig\n\n    if isinstance(project, Project):\n        profile_name = project.profile_name\n    else:\n        profile_name = project.get(\"profile\")\n\n    if not isinstance(profile, Profile):\n        profile = profile_from_dict(\n            deepcopy(profile),\n            profile_name,\n            cli_vars,\n        )\n\n    if not isinstance(project, Project):\n        project = project_from_dict(\n            deepcopy(project),\n            profile,\n            packages,\n            selectors,\n            cli_vars,\n        )\n\n    args = Obj()\n    args.vars = cli_vars\n    args.profile_dir = \"/dev/null\"\n    return RuntimeConfig.from_parts(project=project, profile=profile, args=args)\n\n\ndef inject_plugin(plugin):\n    from dbt.adapters.factory import FACTORY\n\n    key = plugin.adapter.type()\n    FACTORY.plugins[key] = plugin\n\n\ndef inject_plugin_for(config):\n    # from dbt.adapters.postgres import Plugin, PostgresAdapter\n    from dbt.adapters.factory import FACTORY\n\n    FACTORY.load_plugin(config.credentials.type)\n    adapter = FACTORY.get_adapter(config)\n    return adapter\n\n\ndef inject_adapter(value, plugin):\n    \"\"\"Inject the given adapter into the adapter factory, so your hand-crafted\n    artisanal adapter will be available from get_adapter() as if dbt loaded it.\n    \"\"\"\n    inject_plugin(plugin)\n    from dbt.adapters.factory import FACTORY\n\n    key = value.type()\n    FACTORY.adapters[key] = value\n\n\ndef clear_plugin(plugin):\n    from dbt.adapters.factory import FACTORY\n\n    key = plugin.adapter.type()\n    FACTORY.plugins.pop(key, None)\n    FACTORY.adapters.pop(key, None)\n\n\nclass ContractTestCase(TestCase):\n    ContractType = None\n\n    def setUp(self):\n        self.maxDiff = None\n        super().setUp()\n\n    def assert_to_dict(self, obj, dct):\n        self.assertEqual(obj.to_dict(omit_none=True), dct)\n\n    def assert_from_dict(self, obj, dct, cls=None):\n        if cls is None:\n            cls = self.ContractType\n        cls.validate(dct)\n        self.assertEqual(cls.from_dict(dct), obj)\n\n    def assert_symmetric(self, obj, dct, cls=None):\n        self.assert_to_dict(obj, dct)\n        self.assert_from_dict(obj, dct, cls)\n\n    def assert_fails_validation(self, dct, cls=None):\n        if cls is None:\n            cls = self.ContractType\n\n        with self.assertRaises(ValidationError):\n            cls.validate(dct)\n            cls.from_dict(dct)\n\n\ndef compare_dicts(dict1, dict2):\n    first_set = set(dict1.keys())\n    second_set = set(dict2.keys())\n    print(f\"--- Difference between first and second keys: {first_set.difference(second_set)}\")\n    print(f\"--- Difference between second and first keys: {second_set.difference(first_set)}\")\n    common_keys = set(first_set).intersection(set(second_set))\n    found_differences = False\n    for key in common_keys:\n        if dict1[key] != dict2[key]:\n            print(f\"--- --- first dict: {key}: {str(dict1[key])}\")\n            print(f\"--- --- second dict: {key}: {str(dict2[key])}\")\n            found_differences = True\n    if found_differences:\n        print(\"--- Found differences in dictionaries\")\n    else:\n        print(\"--- Found no differences in dictionaries\")\n\n\ndef assert_from_dict(obj, dct, cls=None):\n    if cls is None:\n        cls = obj.__class__\n    cls.validate(dct)\n\n    obj_from_dict = cls.from_dict(dct)\n\n    if hasattr(obj, \"created_at\"):\n        obj_from_dict.created_at = 1\n        obj.created_at = 1\n\n    assert obj_from_dict == obj\n\n\ndef assert_to_dict(obj, dct):\n    obj_to_dict = obj.to_dict(omit_none=True)\n    if \"created_at\" in obj_to_dict:\n        obj_to_dict[\"created_at\"] = 1\n    if \"created_at\" in dct:\n        dct[\"created_at\"] = 1\n    if obj_to_dict != dct:\n        compare_dicts(obj_to_dict, dct)\n    assert obj_to_dict == dct\n\n\ndef assert_symmetric(obj, dct, cls=None):\n    assert_to_dict(obj, dct)\n    assert_from_dict(obj, dct, cls)\n\n\ndef assert_fails_validation(dct, cls):\n    with pytest.raises(ValidationError):\n        cls.validate(dct)\n        cls.from_dict(dct)\n\n\ndef generate_name_macros(package):\n    from dbt.contracts.graph.nodes import Macro\n    from dbt.node_types import NodeType\n\n    name_sql = {}\n    for component in (\"database\", \"schema\", \"alias\"):\n        if component == \"alias\":\n            source = \"node.name\"\n        else:\n            source = f\"target.{component}\"\n        name = f\"generate_{component}_name\"\n        sql = f\"{{% macro {name}(value, node) %}} {{% if value %}} {{{{ value }}}} {{% else %}} {{{{ {source} }}}} {{% endif %}} {{% endmacro %}}\"\n        name_sql[name] = sql\n\n    for name, sql in name_sql.items():\n        pm = Macro(\n            name=name,\n            resource_type=NodeType.Macro,\n            unique_id=f\"macro.{package}.{name}\",\n            package_name=package,\n            original_file_path=normalize(\"macros/macro.sql\"),\n            path=normalize(\"macros/macro.sql\"),\n            macro_sql=sql,\n        )\n        yield pm\n\n\nclass TestAdapterConversions(TestCase):\n    def _get_tester_for(self, column_type):\n        from dbt_common.clients import agate_helper\n\n        if column_type is agate.TimeDelta:  # dbt never makes this!\n            return agate.TimeDelta()\n\n        for instance in agate_helper.DEFAULT_TYPE_TESTER._possible_types:\n            if isinstance(instance, column_type):  # include child types\n                return instance\n\n        raise ValueError(f\"no tester for {column_type}\")\n\n    def _make_table_of(self, rows, column_types):\n        column_names = list(string.ascii_letters[: len(rows[0])])\n        if isinstance(column_types, type):\n            column_types = [self._get_tester_for(column_types) for _ in column_names]\n        else:\n            column_types = [self._get_tester_for(typ) for typ in column_types]\n        table = agate.Table(rows, column_names=column_names, column_types=column_types)\n        return table\n\n\ndef MockMacro(package, name=\"my_macro\", **kwargs):\n    from dbt.contracts.graph.nodes import Macro\n    from dbt.node_types import NodeType\n\n    mock_kwargs = dict(\n        resource_type=NodeType.Macro,\n        package_name=package,\n        unique_id=f\"macro.{package}.{name}\",\n        original_file_path=\"/dev/null\",\n    )\n\n    mock_kwargs.update(kwargs)\n\n    macro = mock.MagicMock(spec=Macro, **mock_kwargs)\n    macro.name = name\n    return macro\n\n\ndef MockMaterialization(package, name=\"my_materialization\", adapter_type=None, **kwargs):\n    if adapter_type is None:\n        adapter_type = \"default\"\n    kwargs[\"adapter_type\"] = adapter_type\n    return MockMacro(package, f\"materialization_{name}_{adapter_type}\", **kwargs)\n\n\ndef MockGenerateMacro(package, component=\"some_component\", **kwargs):\n    name = f\"generate_{component}_name\"\n    return MockMacro(package, name=name, **kwargs)\n\n\ndef MockSource(package, source_name, name, **kwargs):\n    from dbt.contracts.graph.nodes import SourceDefinition\n    from dbt.node_types import NodeType\n\n    src = mock.MagicMock(\n        __class__=SourceDefinition,\n        resource_type=NodeType.Source,\n        source_name=source_name,\n        package_name=package,\n        unique_id=f\"source.{package}.{source_name}.{name}\",\n        search_name=f\"{source_name}.{name}\",\n        **kwargs,\n    )\n    src.name = name\n    return src\n\n\ndef MockNode(package, name, resource_type=None, **kwargs):\n    from dbt.contracts.graph.nodes import ModelNode, SeedNode\n    from dbt.node_types import NodeType\n\n    if resource_type is None:\n        resource_type = NodeType.Model\n    if resource_type == NodeType.Model:\n        cls = ModelNode\n    elif resource_type == NodeType.Seed:\n        cls = SeedNode\n    else:\n        raise ValueError(f\"I do not know how to handle {resource_type}\")\n\n    version = kwargs.get(\"version\")\n    search_name = name if version is None else f\"{name}.v{version}\"\n    unique_id = f\"{str(resource_type)}.{package}.{search_name}\"\n    node = mock.MagicMock(\n        __class__=cls,\n        resource_type=resource_type,\n        package_name=package,\n        unique_id=unique_id,\n        search_name=search_name,\n        **kwargs,\n    )\n    node.name = name\n    node.is_versioned = resource_type is NodeType.Model and version is not None\n    return node\n\n\ndef MockDocumentation(package, name, **kwargs):\n    from dbt.contracts.graph.nodes import Documentation\n    from dbt.node_types import NodeType\n\n    doc = mock.MagicMock(\n        __class__=Documentation,\n        resource_type=NodeType.Documentation,\n        package_name=package,\n        search_name=name,\n        unique_id=f\"{package}.{name}\",\n        **kwargs,\n    )\n    doc.name = name\n    return doc\n\n\ndef load_internal_manifest_macros(config, macro_hook=lambda m: None):\n    from dbt.parser.manifest import ManifestLoader\n\n    return ManifestLoader.load_macros(config, macro_hook)\n\n\ndef dict_replace(dct, **kwargs):\n    dct = dct.copy()\n    dct.update(kwargs)\n    return dct\n\n\ndef replace_config(n, **kwargs):\n    from dataclasses import replace\n\n    return replace(\n        n,\n        config=n.config.replace(**kwargs),\n        unrendered_config=dict_replace(n.unrendered_config, **kwargs),\n    )\n\n\ndef make_manifest(nodes=[], sources=[], macros=[], docs=[]) -> Manifest:\n    return Manifest(\n        nodes={n.unique_id: n for n in nodes},\n        macros={m.unique_id: m for m in macros},\n        sources={s.unique_id: s for s in sources},\n        docs={d.unique_id: d for d in docs},\n        disabled={},\n        files={},\n        exposures={},\n        metrics={},\n        selectors={},\n    )\n"
  },
  {
    "path": "tests/unit/utils/adapter.py",
    "content": "import sys\nfrom unittest.mock import MagicMock\n\nimport pytest\nfrom pytest_mock import MockerFixture\n\nfrom dbt.adapters.factory import get_adapter, register_adapter, reset_adapters\nfrom dbt.adapters.postgres import PostgresAdapter\nfrom dbt.adapters.sql import SQLConnectionManager\nfrom dbt.config.runtime import RuntimeConfig\nfrom dbt.context.providers import generate_runtime_macro_context\nfrom dbt.contracts.graph.manifest import ManifestStateCheck\nfrom dbt.mp_context import get_mp_context\nfrom dbt.parser.manifest import ManifestLoader\n\nif sys.version_info < (3, 9):\n    from typing import Generator\nelse:\n    from collections.abc import Generator\n\n\n@pytest.fixture\ndef mock_connection_manager() -> MagicMock:\n    mock_connection_manager = MagicMock(SQLConnectionManager)\n    mock_connection_manager.set_query_header = lambda query_header_context: None\n    return mock_connection_manager\n\n\n@pytest.fixture\ndef mock_adapter(mock_connection_manager: MagicMock) -> MagicMock:\n    mock_adapter = MagicMock(PostgresAdapter)\n    mock_adapter.connections = mock_connection_manager\n    mock_adapter.clear_macro_resolver = MagicMock()\n    return mock_adapter\n\n\n@pytest.fixture\ndef postgres_adapter(\n    mocker: MockerFixture, runtime_config: RuntimeConfig\n) -> Generator[PostgresAdapter, None, None]:\n    register_adapter(runtime_config, get_mp_context())\n    adapter = get_adapter(runtime_config)\n    assert isinstance(adapter, PostgresAdapter)\n\n    mocker.patch(\"dbt.parser.manifest.ManifestLoader.build_manifest_state_check\").return_value = (\n        ManifestStateCheck()\n    )\n    manifest = ManifestLoader.load_macros(\n        runtime_config,\n        adapter.connections.set_query_header,\n        base_macros_only=True,\n    )\n\n    adapter.set_macro_resolver(manifest)\n    adapter.set_macro_context_generator(generate_runtime_macro_context)\n\n    yield adapter\n    adapter.cleanup_connections()\n    reset_adapters()\n"
  },
  {
    "path": "tests/unit/utils/config.py",
    "content": "import pytest\n\nfrom dbt.adapters.postgres.connections import PostgresCredentials\nfrom dbt.config.profile import Profile\nfrom dbt.config.project import Project\nfrom dbt.config.renderer import ProfileRenderer\nfrom dbt.config.runtime import RuntimeConfig\nfrom dbt.flags import get_flags\n\n\n@pytest.fixture\ndef credentials() -> PostgresCredentials:\n    return PostgresCredentials(\n        database=\"test_database\",\n        schema=\"test_schema\",\n        host=\"test_host\",\n        user=\"test_user\",\n        port=1337,\n        password=\"test_password\",\n    )\n\n\n@pytest.fixture\ndef profile() -> Profile:\n    profile_yaml = {\n        \"target\": \"postgres\",\n        \"outputs\": {\n            \"postgres\": {\n                \"type\": \"postgres\",\n                \"host\": \"postgres-db-hostname\",\n                \"port\": 5555,\n                \"user\": \"db_user\",\n                \"pass\": \"db_pass\",\n                \"dbname\": \"postgres-db-name\",\n                \"schema\": \"postgres-schema\",\n                \"threads\": 7,\n            },\n        },\n    }\n    return Profile.from_raw_profile_info(\n        raw_profile=profile_yaml, profile_name=\"test_profile\", renderer=ProfileRenderer({})\n    )\n\n\n@pytest.fixture\ndef runtime_config(project: Project, profile: Profile, set_test_flags) -> RuntimeConfig:\n    args = get_flags()\n    return RuntimeConfig.from_parts(\n        project=project,\n        profile=profile,\n        args=args,\n    )\n"
  },
  {
    "path": "tests/unit/utils/event_manager.py",
    "content": "import pytest\n\nfrom dbt_common.events.event_manager_client import cleanup_event_logger\n\n\n@pytest.fixture(autouse=True)\ndef always_clean_event_manager() -> None:\n    cleanup_event_logger()\n"
  },
  {
    "path": "tests/unit/utils/flags.py",
    "content": "import sys\nfrom argparse import Namespace\n\nif sys.version_info < (3, 9):\n    from typing import Generator\nelse:\n    from collections.abc import Generator\n\nimport pytest\n\nfrom dbt.flags import set_from_args\n\n\n@pytest.fixture\ndef args_for_flags() -> Namespace:\n    \"\"\"Defines the namespace args to be used in `set_from_args` of `set_test_flags` fixture.\n\n    This fixture is meant to be overrided by tests that need specific flags to be set.\n    \"\"\"\n    return Namespace()\n\n\n@pytest.fixture(autouse=True)\ndef set_test_flags(args_for_flags: Namespace) -> Generator[None, None, None]:\n    \"\"\"Sets up and tears down the global flags for every pytest unit test\n\n    Override `args_for_flags` fixture as needed to set any specific flags.\n    \"\"\"\n    set_from_args(args_for_flags, {})\n    # fixtures stop setup upon yield\n    yield None\n    # everything after yield is run at test teardown\n    set_from_args(Namespace(), {})\n"
  },
  {
    "path": "tests/unit/utils/manifest.py",
    "content": "from typing import Any, Dict, List\n\nimport pytest\n\nfrom dbt.artifacts.resources import (\n    ExposureType,\n    MacroDependsOn,\n    MetricInputMeasure,\n    MetricTypeParams,\n    NodeRelation,\n    Owner,\n    QueryParams,\n    RefArgs,\n    SnapshotConfig,\n    TestConfig,\n    TestMetadata,\n    WhereFilter,\n    WhereFilterIntersection,\n)\nfrom dbt.artifacts.resources.types import ModelLanguage\nfrom dbt.artifacts.resources.v1.model import ModelConfig\nfrom dbt.artifacts.resources.v1.semantic_model import (\n    Defaults,\n    Dimension,\n    DimensionTypeParams,\n    Measure,\n)\nfrom dbt.contracts.files import AnySourceFile, FileHash\nfrom dbt.contracts.graph.manifest import Manifest, ManifestMetadata\nfrom dbt.contracts.graph.nodes import (\n    AccessType,\n    DependsOn,\n    Documentation,\n    Exposure,\n    GenericTestNode,\n    GraphMemberNode,\n    Group,\n    Macro,\n    ManifestNode,\n    Metric,\n    ModelNode,\n    NodeConfig,\n    SavedQuery,\n    SeedNode,\n    SemanticModel,\n    SingularTestNode,\n    SnapshotNode,\n    SourceDefinition,\n    UnitTestDefinition,\n)\nfrom dbt.contracts.graph.unparsed import UnitTestInputFixture, UnitTestOutputFixture\nfrom dbt.node_types import NodeType\nfrom dbt_semantic_interfaces.type_enums import (\n    AggregationType,\n    DimensionType,\n    MetricType,\n    TimeGranularity,\n)\n\n\ndef make_model(\n    pkg,\n    name,\n    code,\n    language=\"sql\",\n    refs=None,\n    sources=None,\n    tags=None,\n    path=None,\n    alias=None,\n    config_kwargs=None,\n    fqn_extras=None,\n    depends_on_macros=None,\n    version=None,\n    latest_version=None,\n    access=None,\n    patch_path=None,\n):\n    if refs is None:\n        refs = []\n    if sources is None:\n        sources = []\n    if tags is None:\n        tags = []\n    if path is None:\n        if language == \"sql\":\n            path = f\"{name}.sql\"\n        elif language == \"python\":\n            path = f\"{name}.py\"\n        else:\n            raise ValueError(f\"Unknown language: {language}\")\n    if alias is None:\n        alias = name\n    if config_kwargs is None:\n        config_kwargs = {}\n    if depends_on_macros is None:\n        depends_on_macros = []\n\n    if fqn_extras is None:\n        fqn_extras = []\n\n    fqn = [pkg] + fqn_extras + [name]\n    if version:\n        fqn.append(f\"v{version}\")\n\n    depends_on_nodes = []\n    source_values = []\n    ref_values = []\n    for ref in refs:\n        ref_version = ref.version if hasattr(ref, \"version\") else None\n        ref_values.append(RefArgs(name=ref.name, package=ref.package_name, version=ref_version))\n        depends_on_nodes.append(ref.unique_id)\n    for src in sources:\n        source_values.append([src.source_name, src.name])\n        depends_on_nodes.append(src.unique_id)\n\n    return ModelNode(\n        language=\"sql\",\n        raw_code=code,\n        database=\"dbt\",\n        schema=\"dbt_schema\",\n        alias=alias,\n        name=name,\n        fqn=fqn,\n        unique_id=f\"model.{pkg}.{name}\" if not version else f\"model.{pkg}.{name}.v{version}\",\n        package_name=pkg,\n        path=path,\n        original_file_path=f\"models/{path}\",\n        config=NodeConfig(**config_kwargs),\n        tags=tags,\n        refs=ref_values,\n        sources=source_values,\n        depends_on=DependsOn(\n            nodes=depends_on_nodes,\n            macros=depends_on_macros,\n        ),\n        resource_type=NodeType.Model,\n        checksum=FileHash.from_contents(\"\"),\n        version=version,\n        latest_version=latest_version,\n        access=access or AccessType.Protected,\n        patch_path=patch_path,\n    )\n\n\ndef make_seed(\n    pkg, name, path=None, loader=None, alias=None, tags=None, fqn_extras=None, checksum=None\n):\n    if alias is None:\n        alias = name\n    if tags is None:\n        tags = []\n    if path is None:\n        path = f\"{name}.csv\"\n\n    if fqn_extras is None:\n        fqn_extras = []\n\n    if checksum is None:\n        checksum = FileHash.from_contents(\"\")\n\n    fqn = [pkg] + fqn_extras + [name]\n    return SeedNode(\n        database=\"dbt\",\n        schema=\"dbt_schema\",\n        alias=alias,\n        name=name,\n        fqn=fqn,\n        unique_id=f\"seed.{pkg}.{name}\",\n        package_name=pkg,\n        path=path,\n        original_file_path=f\"data/{path}\",\n        tags=tags,\n        resource_type=NodeType.Seed,\n        checksum=FileHash.from_contents(\"\"),\n    )\n\n\ndef make_source(\n    pkg, source_name, table_name, path=None, loader=None, identifier=None, fqn_extras=None\n):\n    if path is None:\n        path = \"models/schema.yml\"\n    if loader is None:\n        loader = \"my_loader\"\n    if identifier is None:\n        identifier = table_name\n\n    if fqn_extras is None:\n        fqn_extras = []\n\n    fqn = [pkg] + fqn_extras + [source_name, table_name]\n\n    return SourceDefinition(\n        fqn=fqn,\n        database=\"dbt\",\n        schema=\"dbt_schema\",\n        unique_id=f\"source.{pkg}.{source_name}.{table_name}\",\n        package_name=pkg,\n        path=path,\n        original_file_path=path,\n        name=table_name,\n        source_name=source_name,\n        loader=\"my_loader\",\n        identifier=identifier,\n        resource_type=NodeType.Source,\n        loaded_at_field=\"loaded_at\",\n        tags=[],\n        source_description=\"\",\n    )\n\n\ndef make_macro(pkg, name, macro_sql, path=None, depends_on_macros=None):\n    if path is None:\n        path = \"macros/macros.sql\"\n\n    if depends_on_macros is None:\n        depends_on_macros = []\n\n    return Macro(\n        name=name,\n        macro_sql=macro_sql,\n        unique_id=f\"macro.{pkg}.{name}\",\n        package_name=pkg,\n        path=path,\n        original_file_path=path,\n        resource_type=NodeType.Macro,\n        depends_on=MacroDependsOn(macros=depends_on_macros),\n    )\n\n\ndef make_unique_test(pkg, test_model, column_name, path=None, refs=None, sources=None, tags=None):\n    return make_generic_test(pkg, \"unique\", test_model, {}, column_name=column_name)\n\n\ndef make_not_null_test(\n    pkg, test_model, column_name, path=None, refs=None, sources=None, tags=None\n):\n    return make_generic_test(pkg, \"not_null\", test_model, {}, column_name=column_name)\n\n\ndef make_generic_test(\n    pkg,\n    test_name,\n    test_model,\n    test_kwargs,\n    path=None,\n    refs=None,\n    sources=None,\n    tags=None,\n    column_name=None,\n):\n    kwargs = test_kwargs.copy()\n    ref_values = []\n    source_values = []\n    # this doesn't really have to be correct\n    if isinstance(test_model, SourceDefinition):\n        kwargs[\"model\"] = (\n            \"{{ source('\" + test_model.source_name + \"', '\" + test_model.name + \"') }}\"\n        )\n        source_values.append([test_model.source_name, test_model.name])\n    else:\n        kwargs[\"model\"] = \"{{ ref('\" + test_model.name + \"')}}\"\n        ref_values.append(\n            RefArgs(\n                name=test_model.name, package=test_model.package_name, version=test_model.version\n            )\n        )\n    if column_name is not None:\n        kwargs[\"column_name\"] = column_name\n\n    # whatever\n    args_name = test_model.search_name.replace(\".\", \"_\")\n    if column_name is not None:\n        args_name += \"_\" + column_name\n    node_name = f\"{test_name}_{args_name}\"\n    raw_code = (\n        '{{ config(severity=\"ERROR\") }}{{ test_' + test_name + \"(**dbt_schema_test_kwargs) }}\"\n    )\n    name_parts = test_name.split(\".\")\n\n    if len(name_parts) == 2:\n        namespace, test_name = name_parts\n        macro_depends = f\"macro.{namespace}.test_{test_name}\"\n    elif len(name_parts) == 1:\n        namespace = None\n        macro_depends = f\"macro.dbt.test_{test_name}\"\n    else:\n        assert False, f\"invalid test name: {test_name}\"\n\n    if path is None:\n        path = \"schema.yml\"\n    if tags is None:\n        tags = [\"schema\"]\n\n    if refs is None:\n        refs = []\n    if sources is None:\n        sources = []\n\n    depends_on_nodes = []\n    for ref in refs:\n        ref_version = ref.version if hasattr(ref, \"version\") else None\n        ref_values.append(RefArgs(name=ref.name, package=ref.package_name, version=ref_version))\n        depends_on_nodes.append(ref.unique_id)\n\n    for source in sources:\n        source_values.append([source.source_name, source.name])\n        depends_on_nodes.append(source.unique_id)\n\n    return GenericTestNode(\n        language=\"sql\",\n        raw_code=raw_code,\n        test_metadata=TestMetadata(\n            namespace=namespace,\n            name=test_name,\n            kwargs=kwargs,\n        ),\n        database=\"dbt\",\n        schema=\"dbt_postgres\",\n        name=node_name,\n        alias=node_name,\n        fqn=[\"minimal\", \"schema_test\", node_name],\n        unique_id=f\"test.{pkg}.{node_name}\",\n        package_name=pkg,\n        path=f\"schema_test/{node_name}.sql\",\n        original_file_path=f\"models/{path}\",\n        resource_type=NodeType.Test,\n        tags=tags,\n        refs=ref_values,\n        sources=[],\n        depends_on=DependsOn(macros=[macro_depends], nodes=depends_on_nodes),\n        column_name=column_name,\n        checksum=FileHash.from_contents(\"\"),\n    )\n\n\ndef make_unit_test(\n    pkg,\n    test_name,\n    test_model,\n):\n    input_fixture = UnitTestInputFixture(\n        input=\"ref('table_model')\",\n        rows=[{\"id\": 1, \"string_a\": \"a\"}],\n    )\n    output_fixture = UnitTestOutputFixture(\n        rows=[{\"id\": 1, \"string_a\": \"a\"}],\n    )\n    return UnitTestDefinition(\n        name=test_name,\n        model=test_model,\n        package_name=pkg,\n        resource_type=NodeType.Unit,\n        path=\"unit_tests.yml\",\n        original_file_path=\"models/unit_tests.yml\",\n        unique_id=f\"unit.{pkg}.{test_model.name}__{test_name}\",\n        given=[input_fixture],\n        expect=output_fixture,\n        fqn=[pkg, test_model.name, test_name],\n    )\n\n\ndef make_singular_test(\n    pkg, name, sql, refs=None, sources=None, tags=None, path=None, config_kwargs=None\n):\n    if refs is None:\n        refs = []\n    if sources is None:\n        sources = []\n    if tags is None:\n        tags = [\"data\"]\n    if path is None:\n        path = f\"{name}.sql\"\n\n    if config_kwargs is None:\n        config_kwargs = {}\n\n    fqn = [\"minimal\", \"data_test\", name]\n\n    depends_on_nodes = []\n    source_values = []\n    ref_values = []\n    for ref in refs:\n        ref_version = ref.version if hasattr(ref, \"version\") else None\n        ref_values.append(RefArgs(name=ref.name, package=ref.package_name, version=ref_version))\n        depends_on_nodes.append(ref.unique_id)\n    for src in sources:\n        source_values.append([src.source_name, src.name])\n        depends_on_nodes.append(src.unique_id)\n\n    return SingularTestNode(\n        language=\"sql\",\n        raw_code=sql,\n        database=\"dbt\",\n        schema=\"dbt_schema\",\n        name=name,\n        alias=name,\n        fqn=fqn,\n        unique_id=f\"test.{pkg}.{name}\",\n        package_name=pkg,\n        path=path,\n        original_file_path=f\"tests/{path}\",\n        config=TestConfig(**config_kwargs),\n        tags=tags,\n        refs=ref_values,\n        sources=source_values,\n        depends_on=DependsOn(nodes=depends_on_nodes, macros=[]),\n        resource_type=NodeType.Test,\n        checksum=FileHash.from_contents(\"\"),\n    )\n\n\ndef make_exposure(pkg, name, path=None, fqn_extras=None, owner=None):\n    if path is None:\n        path = \"schema.yml\"\n\n    if fqn_extras is None:\n        fqn_extras = []\n\n    if owner is None:\n        owner = Owner(email=\"test@example.com\")\n\n    fqn = [pkg, \"exposures\"] + fqn_extras + [name]\n    return Exposure(\n        name=name,\n        resource_type=NodeType.Exposure,\n        type=ExposureType.Notebook,\n        fqn=fqn,\n        unique_id=f\"exposure.{pkg}.{name}\",\n        package_name=pkg,\n        path=path,\n        original_file_path=path,\n        owner=owner,\n    )\n\n\ndef make_metric(pkg, name, path=None):\n    if path is None:\n        path = \"schema.yml\"\n\n    return Metric(\n        name=name,\n        resource_type=NodeType.Metric,\n        path=path,\n        package_name=pkg,\n        original_file_path=path,\n        unique_id=f\"metric.{pkg}.{name}\",\n        fqn=[pkg, \"metrics\", name],\n        label=\"New Customers\",\n        description=\"New customers\",\n        type=MetricType.SIMPLE,\n        type_params=MetricTypeParams(measure=MetricInputMeasure(name=\"count_cats\")),\n        meta={\"is_okr\": True},\n        tags=[\"okrs\"],\n    )\n\n\ndef make_group(pkg, name, path=None):\n    if path is None:\n        path = \"schema.yml\"\n\n    return Group(\n        name=name,\n        resource_type=NodeType.Group,\n        path=path,\n        package_name=pkg,\n        original_file_path=path,\n        unique_id=f\"group.{pkg}.{name}\",\n        owner=\"email@gmail.com\",\n    )\n\n\ndef make_semantic_model(\n    pkg: str,\n    name: str,\n    model,\n    path=None,\n):\n    if path is None:\n        path = \"schema.yml\"\n\n    return SemanticModel(\n        name=name,\n        resource_type=NodeType.SemanticModel,\n        model=model,\n        node_relation=NodeRelation(\n            alias=model.alias,\n            schema_name=\"dbt\",\n            relation_name=model.name,\n        ),\n        package_name=pkg,\n        path=path,\n        description=\"Customer entity\",\n        primary_entity=\"customer\",\n        unique_id=f\"semantic_model.{pkg}.{name}\",\n        original_file_path=path,\n        fqn=[pkg, \"semantic_models\", name],\n        defaults=Defaults(agg_time_dimension=\"created_at\"),\n        dimensions=[\n            Dimension(\n                name=\"created_at\",\n                type=DimensionType.TIME,\n                type_params=DimensionTypeParams(time_granularity=TimeGranularity.DAY),\n            )\n        ],\n        measures=[\n            Measure(\n                name=\"a_measure\",\n                agg=AggregationType.COUNT,\n                expr=\"1\",\n            )\n        ],\n    )\n\n\ndef make_saved_query(pkg: str, name: str, metric: str, path=None):\n    if path is None:\n        path = \"schema.yml\"\n\n    return SavedQuery(\n        name=name,\n        resource_type=NodeType.SavedQuery,\n        package_name=pkg,\n        path=path,\n        description=\"Test Saved Query\",\n        query_params=QueryParams(\n            metrics=[metric],\n            group_by=[],\n            where=None,\n        ),\n        exports=[],\n        unique_id=f\"saved_query.{pkg}.{name}\",\n        original_file_path=path,\n        fqn=[pkg, \"saved_queries\", name],\n    )\n\n\ndef make_source_snapshot(pkg: str, name: str, source: SourceDefinition, path=None) -> SnapshotNode:\n    if path is None:\n        path = \"schema.yml\"\n\n    return SnapshotNode(\n        database=source.database,\n        schema=source.schema,\n        name=name,\n        resource_type=NodeType.Snapshot,\n        package_name=source.package_name,\n        path=path,\n        original_file_path=path,\n        unique_id=f\"snapshot.{pkg}.{name}\",\n        fqn=[pkg, \"snapshot\", name],\n        alias=None,\n        checksum=\"\",\n        sources=[[source.source_name, source.name]],\n        depends_on=DependsOn(\n            nodes=[source.unique_id],\n            macros=[],\n        ),\n        config=SnapshotConfig(\n            strategy=\"check\",\n            unique_key=\"'dummy'\",\n            check_cols=\"all\",\n        ),\n    )\n\n\n@pytest.fixture\ndef macro_test_unique() -> Macro:\n    return make_macro(\n        \"dbt\", \"test_unique\", \"blablabla\", depends_on_macros=[\"macro.dbt.default__test_unique\"]\n    )\n\n\n@pytest.fixture\ndef macro_default_test_unique() -> Macro:\n    return make_macro(\"dbt\", \"default__test_unique\", \"blablabla\")\n\n\n@pytest.fixture\ndef macro_test_not_null() -> Macro:\n    return make_macro(\n        \"dbt\", \"test_not_null\", \"blablabla\", depends_on_macros=[\"macro.dbt.default__test_not_null\"]\n    )\n\n\n@pytest.fixture\ndef macro_materialization_table_default() -> Macro:\n    macro = make_macro(\"dbt\", \"materialization_table_default\", \"SELECT 1\")\n    macro.supported_languages = [ModelLanguage.sql]\n    return macro\n\n\n@pytest.fixture\ndef macro_default_test_not_null() -> Macro:\n    return make_macro(\"dbt\", \"default__test_not_null\", \"blabla\")\n\n\n@pytest.fixture\ndef seed() -> SeedNode:\n    return make_seed(\"pkg\", \"seed\")\n\n\n@pytest.fixture\ndef source() -> SourceDefinition:\n    return make_source(\"pkg\", \"raw\", \"seed\", identifier=\"seed\")\n\n\n@pytest.fixture\ndef ephemeral_model(source) -> ModelNode:\n    return make_model(\n        \"pkg\",\n        \"ephemeral_model\",\n        'select * from {{ source(\"raw\", \"seed\") }}',\n        config_kwargs={\"materialized\": \"ephemeral\"},\n        sources=[source],\n    )\n\n\n@pytest.fixture\ndef view_model(ephemeral_model) -> ModelNode:\n    return make_model(\n        \"pkg\",\n        \"view_model\",\n        'select * from {{ ref(\"ephemeral_model\") }}',\n        config_kwargs={\"materialized\": \"view\"},\n        refs=[ephemeral_model],\n        tags=[\"uses_ephemeral\"],\n    )\n\n\n@pytest.fixture\ndef table_model(ephemeral_model) -> ModelNode:\n    return make_model(\n        \"pkg\",\n        \"table_model\",\n        'select * from {{ ref(\"ephemeral_model\") }}',\n        config_kwargs={\n            \"materialized\": \"table\",\n            \"meta\": {\n                # Other properties to test in test_select_config_meta\n                \"string_property\": \"some_string\",\n                \"truthy_bool_property\": True,\n                \"falsy_bool_property\": False,\n                \"list_property\": [\"some_value\", True, False],\n            },\n        },\n        refs=[ephemeral_model],\n        tags=[\"uses_ephemeral\"],\n        path=\"subdirectory/table_model.sql\",\n    )\n\n\n@pytest.fixture\ndef table_model_py(seed) -> ModelNode:\n    return make_model(\n        \"pkg\",\n        \"table_model_py\",\n        'select * from {{ ref(\"seed\") }}',\n        config_kwargs={\"materialized\": \"table\"},\n        refs=[seed],\n        tags=[],\n        path=\"subdirectory/table_model.py\",\n    )\n\n\n@pytest.fixture\ndef table_model_csv(seed) -> ModelNode:\n    return make_model(\n        \"pkg\",\n        \"table_model_csv\",\n        'select * from {{ ref(\"seed\") }}',\n        config_kwargs={\"materialized\": \"table\"},\n        refs=[seed],\n        tags=[],\n        path=\"subdirectory/table_model.csv\",\n    )\n\n\n@pytest.fixture\ndef ext_source() -> SourceDefinition:\n    return make_source(\n        \"ext\",\n        \"ext_raw\",\n        \"ext_source\",\n    )\n\n\n@pytest.fixture\ndef ext_source_2() -> SourceDefinition:\n    return make_source(\n        \"ext\",\n        \"ext_raw\",\n        \"ext_source_2\",\n    )\n\n\n@pytest.fixture\ndef ext_source_other() -> SourceDefinition:\n    return make_source(\n        \"ext\",\n        \"raw\",\n        \"ext_source\",\n    )\n\n\n@pytest.fixture\ndef ext_source_other_2() -> SourceDefinition:\n    return make_source(\n        \"ext\",\n        \"raw\",\n        \"ext_source_2\",\n    )\n\n\n@pytest.fixture\ndef ext_model(ext_source) -> ModelNode:\n    return make_model(\n        \"ext\",\n        \"ext_model\",\n        'select * from {{ source(\"ext_raw\", \"ext_source\") }}',\n        sources=[ext_source],\n    )\n\n\n@pytest.fixture\ndef union_model(seed, ext_source) -> ModelNode:\n    return make_model(\n        \"pkg\",\n        \"union_model\",\n        'select * from {{ ref(\"seed\") }} union all select * from {{ source(\"ext_raw\", \"ext_source\") }}',\n        config_kwargs={\"materialized\": \"table\"},\n        refs=[seed],\n        sources=[ext_source],\n        fqn_extras=[\"unions\"],\n        path=\"subdirectory/union_model.sql\",\n        tags=[\"unions\"],\n    )\n\n\n@pytest.fixture\ndef versioned_model_v1(seed) -> ModelNode:\n    return make_model(\n        \"pkg\",\n        \"versioned_model\",\n        'select * from {{ ref(\"seed\") }}',\n        config_kwargs={\"materialized\": \"table\"},\n        refs=[seed],\n        sources=[],\n        path=\"subdirectory/versioned_model_v1.sql\",\n        version=1,\n        latest_version=2,\n    )\n\n\n@pytest.fixture\ndef versioned_model_v2(seed) -> ModelNode:\n    return make_model(\n        \"pkg\",\n        \"versioned_model\",\n        'select * from {{ ref(\"seed\") }}',\n        config_kwargs={\"materialized\": \"table\"},\n        refs=[seed],\n        sources=[],\n        path=\"subdirectory/versioned_model_v2.sql\",\n        version=2,\n        latest_version=2,\n    )\n\n\n@pytest.fixture\ndef versioned_model_v3(seed) -> ModelNode:\n    return make_model(\n        \"pkg\",\n        \"versioned_model\",\n        'select * from {{ ref(\"seed\") }}',\n        config_kwargs={\"materialized\": \"table\"},\n        refs=[seed],\n        sources=[],\n        path=\"subdirectory/versioned_model_v3.sql\",\n        version=\"3\",\n        latest_version=2,\n    )\n\n\n@pytest.fixture\ndef versioned_model_v12_string(seed) -> ModelNode:\n    return make_model(\n        \"pkg\",\n        \"versioned_model\",\n        'select * from {{ ref(\"seed\") }}',\n        config_kwargs={\"materialized\": \"table\"},\n        refs=[seed],\n        sources=[],\n        path=\"subdirectory/versioned_model_v12.sql\",\n        version=\"12\",\n        latest_version=2,\n    )\n\n\n@pytest.fixture\ndef versioned_model_v4_nested_dir(seed) -> ModelNode:\n    return make_model(\n        \"pkg\",\n        \"versioned_model\",\n        'select * from {{ ref(\"seed\") }}',\n        config_kwargs={\"materialized\": \"table\"},\n        refs=[seed],\n        sources=[],\n        path=\"subdirectory/nested_dir/versioned_model_v3.sql\",\n        version=\"4\",\n        latest_version=2,\n        fqn_extras=[\"nested_dir\"],\n    )\n\n\n@pytest.fixture\ndef table_id_unique(table_model) -> GenericTestNode:\n    return make_unique_test(\"pkg\", table_model, \"id\")\n\n\n@pytest.fixture\ndef table_id_not_null(table_model) -> GenericTestNode:\n    return make_not_null_test(\"pkg\", table_model, \"id\")\n\n\n@pytest.fixture\ndef view_id_unique(view_model) -> GenericTestNode:\n    return make_unique_test(\"pkg\", view_model, \"id\")\n\n\n@pytest.fixture\ndef ext_source_id_unique(ext_source) -> GenericTestNode:\n    return make_unique_test(\"ext\", ext_source, \"id\")\n\n\n@pytest.fixture\ndef view_test_nothing(view_model) -> SingularTestNode:\n    return make_singular_test(\n        \"pkg\",\n        \"view_test_nothing\",\n        'select * from {{ ref(\"view_model\") }} limit 0',\n        refs=[view_model],\n    )\n\n\n@pytest.fixture\ndef unit_test_table_model(table_model) -> UnitTestDefinition:\n    return make_unit_test(\n        \"pkg\",\n        \"unit_test_table_model\",\n        table_model,\n    )\n\n\n# Support dots as namespace separators\n@pytest.fixture\ndef namespaced_seed() -> SeedNode:\n    return make_seed(\"pkg\", \"mynamespace.seed\")\n\n\n@pytest.fixture\ndef namespace_model(source) -> ModelNode:\n    return make_model(\n        \"pkg\",\n        \"mynamespace.ephemeral_model\",\n        'select * from {{ source(\"raw\", \"seed\") }}',\n        config_kwargs={\"materialized\": \"ephemeral\"},\n        sources=[source],\n    )\n\n\n@pytest.fixture\ndef namespaced_union_model(seed, ext_source) -> ModelNode:\n    return make_model(\n        \"pkg\",\n        \"mynamespace.union_model\",\n        'select * from {{ ref(\"mynamespace.seed\") }} union all select * from {{ ref(\"mynamespace.ephemeral_model\") }}',\n        config_kwargs={\"materialized\": \"table\"},\n        refs=[seed],\n        sources=[ext_source],\n        fqn_extras=[\"unions\"],\n        path=\"subdirectory/union_model.sql\",\n        tags=[\"unions\"],\n    )\n\n\n@pytest.fixture\ndef metric() -> Metric:\n    return Metric(\n        name=\"my_metric\",\n        resource_type=NodeType.Metric,\n        type=MetricType.SIMPLE,\n        type_params=MetricTypeParams(measure=MetricInputMeasure(name=\"a_measure\")),\n        fqn=[\"test\", \"metrics\", \"myq_metric\"],\n        unique_id=\"metric.test.my_metric\",\n        package_name=\"test\",\n        path=\"models/metric.yml\",\n        original_file_path=\"models/metric.yml\",\n        description=\"\",\n        meta={},\n        tags=[],\n        label=\"test_label\",\n    )\n\n\n@pytest.fixture\ndef saved_query() -> SavedQuery:\n    pkg = \"test\"\n    name = \"test_saved_query\"\n    path = \"test_path\"\n    return SavedQuery(\n        name=name,\n        resource_type=NodeType.SavedQuery,\n        package_name=pkg,\n        path=path,\n        description=\"Test Saved Query\",\n        query_params=QueryParams(\n            metrics=[\"my_metric\"],\n            group_by=[],\n            where=WhereFilterIntersection(\n                where_filters=[\n                    WhereFilter(where_sql_template=\"1=1\"),\n                ]\n            ),\n        ),\n        exports=[],\n        unique_id=f\"saved_query.{pkg}.{name}\",\n        original_file_path=path,\n        fqn=[pkg, \"saved_queries\", name],\n    )\n\n\n@pytest.fixture\ndef semantic_model(table_model) -> SemanticModel:\n    return make_semantic_model(\"test\", \"test_semantic_model\", model=table_model)\n\n\n@pytest.fixture\ndef metricflow_time_spine_model() -> ModelNode:\n    return ModelNode(\n        name=\"metricflow_time_spine\",\n        database=\"dbt\",\n        schema=\"analytics\",\n        alias=\"events\",\n        resource_type=NodeType.Model,\n        unique_id=\"model.test.metricflow_time_spine\",\n        fqn=[\"snowplow\", \"events\"],\n        package_name=\"snowplow\",\n        refs=[],\n        sources=[],\n        metrics=[],\n        depends_on=DependsOn(),\n        config=ModelConfig(),\n        tags=[],\n        path=\"events.sql\",\n        original_file_path=\"events.sql\",\n        meta={},\n        language=\"sql\",\n        raw_code=\"does not matter\",\n        checksum=FileHash.empty(),\n        relation_name=\"events\",\n    )\n\n\n@pytest.fixture\ndef nodes(\n    seed,\n    ephemeral_model,\n    view_model,\n    table_model,\n    table_model_py,\n    table_model_csv,\n    union_model,\n    versioned_model_v1,\n    versioned_model_v2,\n    versioned_model_v3,\n    versioned_model_v4_nested_dir,\n    versioned_model_v12_string,\n    ext_model,\n    table_id_unique,\n    table_id_not_null,\n    view_id_unique,\n    ext_source_id_unique,\n    view_test_nothing,\n    namespaced_seed,\n    namespace_model,\n    namespaced_union_model,\n) -> List[ManifestNode]:\n    return [\n        seed,\n        ephemeral_model,\n        view_model,\n        table_model,\n        table_model_py,\n        table_model_csv,\n        union_model,\n        versioned_model_v1,\n        versioned_model_v2,\n        versioned_model_v3,\n        versioned_model_v4_nested_dir,\n        versioned_model_v12_string,\n        ext_model,\n        table_id_unique,\n        table_id_not_null,\n        view_id_unique,\n        ext_source_id_unique,\n        view_test_nothing,\n        namespaced_seed,\n        namespace_model,\n        namespaced_union_model,\n    ]\n\n\n@pytest.fixture\ndef sources(\n    source,\n    ext_source,\n    ext_source_2,\n    ext_source_other,\n    ext_source_other_2,\n) -> list:\n    return [source, ext_source, ext_source_2, ext_source_other, ext_source_other_2]\n\n\n@pytest.fixture\ndef macros(\n    macro_test_unique,\n    macro_default_test_unique,\n    macro_test_not_null,\n    macro_default_test_not_null,\n    macro_materialization_table_default,\n) -> List[Macro]:\n    return [\n        macro_test_unique,\n        macro_default_test_unique,\n        macro_test_not_null,\n        macro_default_test_not_null,\n        macro_materialization_table_default,\n    ]\n\n\n@pytest.fixture\ndef unit_tests(unit_test_table_model) -> List[UnitTestDefinition]:\n    return [unit_test_table_model]\n\n\n@pytest.fixture\ndef metrics(metric: Metric) -> List[Metric]:\n    return [metric]\n\n\n@pytest.fixture\ndef semantic_models(semantic_model: SemanticModel) -> List[SemanticModel]:\n    return [semantic_model]\n\n\n@pytest.fixture\ndef saved_queries(saved_query: SavedQuery) -> List[SavedQuery]:\n    return [saved_query]\n\n\n@pytest.fixture\ndef files() -> Dict[str, AnySourceFile]:\n    return {}\n\n\ndef make_manifest(\n    disabled: Dict[str, List[GraphMemberNode]] = {},\n    docs: List[Documentation] = [],\n    exposures: List[Exposure] = [],\n    files: Dict[str, AnySourceFile] = {},\n    groups: List[Group] = [],\n    macros: List[Macro] = [],\n    metrics: List[Metric] = [],\n    nodes: List[ManifestNode] = [],\n    saved_queries: List[SavedQuery] = [],\n    selectors: Dict[str, Any] = {},\n    semantic_models: List[SemanticModel] = [],\n    sources: List[SourceDefinition] = [],\n    unit_tests: List[UnitTestDefinition] = [],\n) -> Manifest:\n    manifest = Manifest(\n        nodes={n.unique_id: n for n in nodes},\n        sources={s.unique_id: s for s in sources},\n        macros={m.unique_id: m for m in macros},\n        unit_tests={t.unique_id: t for t in unit_tests},\n        semantic_models={s.unique_id: s for s in semantic_models},\n        docs={d.unique_id: d for d in docs},\n        files=files,\n        exposures={e.unique_id: e for e in exposures},\n        metrics={m.unique_id: m for m in metrics},\n        disabled=disabled,\n        selectors=selectors,\n        groups={g.unique_id: g for g in groups},\n        metadata=ManifestMetadata(adapter_type=\"postgres\", project_name=\"pkg\"),\n        saved_queries={s.unique_id: s for s in saved_queries},\n    )\n    manifest.build_parent_and_child_maps()\n    return manifest\n\n\n@pytest.fixture\ndef manifest(\n    metric,\n    semantic_model,\n    nodes,\n    sources,\n    macros,\n    unit_tests,\n    metrics,\n    semantic_models,\n    files,\n    saved_queries,\n) -> Manifest:\n    return make_manifest(\n        nodes=nodes,\n        sources=sources,\n        macros=macros,\n        unit_tests=unit_tests,\n        semantic_models=semantic_models,\n        files=files,\n        metrics=metrics,\n        saved_queries=saved_queries,\n    )\n"
  },
  {
    "path": "tests/unit/utils/project.py",
    "content": "from unittest.mock import MagicMock\n\nimport pytest\n\nfrom dbt.adapters.contracts.connection import DEFAULT_QUERY_COMMENT, QueryComment\nfrom dbt.config import RuntimeConfig\nfrom dbt.config.project import Project, RenderComponents, VarProvider\nfrom dbt.config.selectors import SelectorConfig\nfrom dbt.contracts.project import PackageConfig\nfrom dbt_common.semver import VersionSpecifier\n\n\n@pytest.fixture(scope=\"function\")\ndef selector_config() -> SelectorConfig:\n    return SelectorConfig.selectors_from_dict(\n        data={\n            \"selectors\": [\n                {\n                    \"name\": \"my_selector\",\n                    \"definition\": \"give me cats\",\n                    \"default\": True,\n                }\n            ]\n        }\n    )\n\n\n@pytest.fixture(scope=\"function\")\ndef project(selector_config: SelectorConfig) -> Project:\n    return Project(\n        project_name=\"test_project\",\n        version=1.0,\n        project_root=\"doesnt/actually/exist\",\n        profile_name=\"test_profile\",\n        model_paths=[\"models\"],\n        macro_paths=[\"macros\"],\n        seed_paths=[\"seeds\"],\n        function_paths=[\"functions\"],\n        test_paths=[\"tests\"],\n        analysis_paths=[\"analyses\"],\n        docs_paths=[\"docs\"],\n        asset_paths=[\"assets\"],\n        target_path=\"target\",\n        snapshot_paths=[\"snapshots\"],\n        clean_targets=[\"target\"],\n        log_path=\"path/to/project/logs\",\n        packages_install_path=\"dbt_packages\",\n        packages_specified_path=\"packages.yml\",\n        quoting={},\n        models={},\n        on_run_start=[],\n        on_run_end=[],\n        dispatch=[{\"macro_namespace\": \"dbt_utils\", \"search_order\": [\"test_project\", \"dbt_utils\"]}],\n        seeds={},\n        snapshots={},\n        sources={},\n        data_tests={},\n        unit_tests={},\n        metrics={},\n        semantic_models={},\n        saved_queries={},\n        exposures={},\n        functions={},\n        vars=VarProvider({}),\n        dbt_version=[VersionSpecifier.from_version_string(\"0.0.0\")],\n        packages=PackageConfig([]),\n        manifest_selectors={},\n        selectors=selector_config,\n        # QueryComment contract defaults are defined by dbt-adapters, so not hard-coding this fixture to rely on particular settings of their defaults.\n        query_comment=QueryComment(comment=DEFAULT_QUERY_COMMENT, append=False, job_label=False),\n        config_version=1,\n        unrendered=RenderComponents({}, {}, {}),\n        project_env_vars={},\n        restrict_access=False,\n        dbt_cloud={},\n        flags={},\n        vars_from_file={},\n    )\n\n\n@pytest.fixture\ndef mock_project():\n    mock_project = MagicMock(RuntimeConfig)\n    mock_project.cli_vars = {}\n    mock_project.args = MagicMock()\n    mock_project.profile_name = \"test\"\n    mock_project.target_name = \"test\"\n    mock_project.args.profile = \"test\"\n    mock_project.args.target = \"test\"\n    mock_project.project_env_vars = {}\n    mock_project.profile_env_vars = {}\n    mock_project.project_target_path = \"mock_target_path\"\n    mock_project.credentials = MagicMock()\n    mock_project.clear_dependencies = MagicMock()\n    mock_project.vars_from_file = {}\n    return mock_project\n"
  },
  {
    "path": "third-party-stubs/agate/__init__.pyi",
    "content": "from collections.abc import Sequence\n\nfrom typing import Any, Optional, Callable, Iterable, Dict, Union\n\nfrom . import data_types as data_types\nfrom .data_types import (\n    Text as Text,\n    Number as Number,\n    Boolean as Boolean,\n    DateTime as DateTime,\n    Date as Date,\n    TimeDelta as TimeDelta,\n)\n\nclass MappedSequence(Sequence):\n    def __init__(self, values: Any, keys: Optional[Any] = ...) -> None: ...\n    def __unicode__(self): ...\n    def __getitem__(self, key: Any): ...\n    def __setitem__(self, key: Any, value: Any) -> None: ...\n    def __iter__(self): ...\n    def __len__(self): ...\n    def __eq__(self, other: Any): ...\n    def __ne__(self, other: Any): ...\n    def __contains__(self, value: Any): ...\n    def keys(self): ...\n    def values(self): ...\n    def items(self): ...\n    def get(self, key: Any, default: Optional[Any] = ...): ...\n    def dict(self): ...\n\nclass Row(MappedSequence): ...\n\nclass Table:\n    def __init__(\n        self,\n        rows: Any,\n        column_names: Optional[Any] = ...,\n        column_types: Optional[Any] = ...,\n        row_names: Optional[Any] = ...,\n        _is_fork: bool = ...,\n    ) -> None: ...\n    def __len__(self): ...\n    def __iter__(self): ...\n    def __getitem__(self, key: Any): ...\n    @property\n    def column_types(self): ...\n    @property\n    def column_names(self): ...\n    @property\n    def row_names(self): ...\n    @property\n    def columns(self): ...\n    @property\n    def rows(self): ...\n    def print_csv(self, **kwargs: Any) -> None: ...\n    def print_json(self, **kwargs: Any) -> None: ...\n    def where(self, test: Callable[[Row], bool]) -> \"Table\": ...\n    def select(self, key: Union[Iterable[str], str]) -> \"Table\": ...\n    # these definitions are much narrower than what's actually accepted\n    @classmethod\n    def from_object(\n        cls, obj: Iterable[Dict[str, Any]], *, column_types: Optional[\"TypeTester\"] = None\n    ) -> \"Table\": ...\n    @classmethod\n    def from_csv(\n        cls, path: Iterable[str], *, column_types: Optional[\"TypeTester\"] = None\n    ) -> \"Table\": ...\n    @classmethod\n    def merge(cls, tables: Iterable[\"Table\"]) -> \"Table\": ...\n    def rename(\n        self,\n        column_names: Optional[Iterable[str]] = None,\n        row_names: Optional[Any] = None,\n        slug_columns: bool = False,\n        slug_rows: bool = False,\n        **kwargs: Any,\n    ) -> \"Table\": ...\n\nclass TypeTester:\n    def __init__(\n        self, force: Any = ..., limit: Optional[Any] = ..., types: Optional[Any] = ...\n    ) -> None: ...\n    def run(self, rows: Any, column_names: Any): ...\n\nclass MaxPrecision:\n    def __init__(self, column_name: Any) -> None: ...\n\n# this is not strictly true, but it's all we care about.\ndef aggregate(self, aggregations: MaxPrecision) -> int: ...\n"
  },
  {
    "path": "third-party-stubs/agate/data_types.pyi",
    "content": "from typing import Any, Optional\n\nDEFAULT_NULL_VALUES: Any\n\nclass DataType:\n    null_values: Any = ...\n    def __init__(self, null_values: Any = ...) -> None: ...\n    def test(self, d: Any): ...\n    def cast(self, d: Any) -> None: ...\n    def csvify(self, d: Any): ...\n    def jsonify(self, d: Any): ...\n\nDEFAULT_TRUE_VALUES: Any\nDEFAULT_FALSE_VALUES: Any\n\nclass Boolean(DataType):\n    true_values: Any = ...\n    false_values: Any = ...\n    def __init__(\n        self, true_values: Any = ..., false_values: Any = ..., null_values: Any = ...\n    ) -> None: ...\n    def cast(self, d: Any): ...\n    def jsonify(self, d: Any): ...\n\nZERO_DT: Any\n\nclass Date(DataType):\n    date_format: Any = ...\n    parser: Any = ...\n    def __init__(self, date_format: Optional[Any] = ..., **kwargs: Any) -> None: ...\n    def cast(self, d: Any): ...\n    def csvify(self, d: Any): ...\n    def jsonify(self, d: Any): ...\n\nclass DateTime(DataType):\n    datetime_format: Any = ...\n    timezone: Any = ...\n    def __init__(\n        self, datetime_format: Optional[Any] = ..., timezone: Optional[Any] = ..., **kwargs: Any\n    ) -> None: ...\n    def cast(self, d: Any): ...\n    def csvify(self, d: Any): ...\n    def jsonify(self, d: Any): ...\n\nDEFAULT_CURRENCY_SYMBOLS: Any\nPOSITIVE: Any\nNEGATIVE: Any\n\nclass Number(DataType):\n    locale: Any = ...\n    currency_symbols: Any = ...\n    group_symbol: Any = ...\n    decimal_symbol: Any = ...\n    def __init__(\n        self,\n        locale: str = ...,\n        group_symbol: Optional[Any] = ...,\n        decimal_symbol: Optional[Any] = ...,\n        currency_symbols: Any = ...,\n        **kwargs: Any,\n    ) -> None: ...\n    def cast(self, d: Any): ...\n    def jsonify(self, d: Any): ...\n\nclass TimeDelta(DataType):\n    def cast(self, d: Any): ...\n\nclass Text(DataType):\n    cast_nulls: Any = ...\n    def __init__(self, cast_nulls: bool = ..., **kwargs: Any) -> None: ...\n    def cast(self, d: Any): ...\n"
  },
  {
    "path": "third-party-stubs/cdecimal/__init__.pyi",
    "content": "class Decimal:\n    pass\n"
  },
  {
    "path": "third-party-stubs/daff/__init__.pyi",
    "content": "import __builtin__  # type: ignore\nimport builtins\nimport functools\nfrom _typeshed import Incomplete\n\nbuiltins = __builtin__\nhxunicode: Incomplete\nhxunichr: Incomplete\n\ndef hxnext(x): ...\n\nhx_cmp_to_key = functools.cmp_to_key\nhxunicode = str\nhxrange = range\nhxunichr = chr\nunichr = chr\nunicode = str\nhx_cmp_to_key = functools.cmp_to_key\npython_lib_Builtin = builtins\nString = builtins.str\npython_lib_Dict = builtins.dict\npython_lib_Set = builtins.set\nimap: Incomplete\nifilter: Incomplete\n\nclass _hx_AnonObject:\n    __dict__: Incomplete\n    def __init__(self, fields) -> None: ...\n    def __contains__(self, item) -> bool: ...\n    def __getitem__(self, item): ...\n    def __getattr__(self, name) -> None: ...\n\nclass Enum:\n    tag: Incomplete\n    index: Incomplete\n    params: Incomplete\n    def __init__(self, tag, index, params) -> None: ...\n\nclass Alignment:\n    has_removal: Incomplete\n    has_addition: Incomplete\n    index_columns: Incomplete\n    order_cache: Incomplete\n    tb: Incomplete\n    ta: Incomplete\n    map_a2b: Incomplete\n    map_b2a: Incomplete\n    hb: int\n    ha: Incomplete\n    map_count: int\n    reference: Incomplete\n    meta: Incomplete\n    comp: Incomplete\n    order_cache_has_reference: bool\n    ia: int\n    ib: int\n    marked_as_identical: bool\n    def __init__(self) -> None: ...\n    def range(self, ha, hb) -> None: ...\n    def tables(self, ta, tb) -> None: ...\n    def headers(self, ia, ib) -> None: ...\n    def setRowlike(self, flag) -> None: ...\n    def link(self, a, b) -> None: ...\n    def addIndexColumns(self, unit) -> None: ...\n    def getIndexColumns(self): ...\n    def a2b(self, a): ...\n    def b2a(self, b): ...\n    def count(self): ...\n    def toString(self): ...\n    def toOrder(self): ...\n    def addToOrder(self, l, r, p: Incomplete | None = ...) -> None: ...\n    def getSource(self): ...\n    def getTarget(self): ...\n    def getSourceHeader(self): ...\n    def getTargetHeader(self): ...\n    def toOrder3(self): ...\n    def markIdentical(self) -> None: ...\n    def isMarkedAsIdentical(self): ...\n\nclass CellBuilder: ...\n\nclass CellInfo:\n    meta: Incomplete\n    rvalue: Incomplete\n    lvalue: Incomplete\n    pvalue: Incomplete\n    conflicted: Incomplete\n    updated: Incomplete\n    pretty_separator: Incomplete\n    separator: Incomplete\n    category_given_tr: Incomplete\n    category: Incomplete\n    pretty_value: Incomplete\n    value: Incomplete\n    raw: Incomplete\n    def __init__(self) -> None: ...\n    def toString(self): ...\n\nclass Class: ...\n\nclass ColumnChange:\n    props: Incomplete\n    name: Incomplete\n    prevName: Incomplete\n    def __init__(self) -> None: ...\n\nclass Table: ...\n\nclass CombinedTable:\n    meta: Incomplete\n    body: Incomplete\n    t: Incomplete\n    dx: int\n    dy: int\n    core: Incomplete\n    head: Incomplete\n    def __init__(self, t) -> None: ...\n    def all(self): ...\n    def getTable(self): ...\n    def get_width(self): ...\n    def get_height(self): ...\n    def getCell(self, x, y): ...\n    def setCell(self, x, y, c) -> None: ...\n    def toString(self): ...\n    def getCellView(self): ...\n    def isResizable(self): ...\n    def resize(self, w, h): ...\n    def clear(self) -> None: ...\n    def insertOrDeleteRows(self, fate, hfate): ...\n    def insertOrDeleteColumns(self, fate, wfate): ...\n    def trimBlank(self): ...\n    def getData(self) -> None: ...\n    def clone(self): ...\n    def create(self): ...\n    def getMeta(self): ...\n\nclass CombinedTableBody:\n    meta: Incomplete\n    parent: Incomplete\n    dx: Incomplete\n    dy: Incomplete\n    all: Incomplete\n    def __init__(self, parent, dx, dy) -> None: ...\n    def getTable(self): ...\n    def get_width(self): ...\n    def get_height(self): ...\n    def getCell(self, x, y): ...\n    def setCell(self, x, y, c) -> None: ...\n    def toString(self): ...\n    def getCellView(self): ...\n    def isResizable(self): ...\n    def resize(self, w, h): ...\n    def clear(self) -> None: ...\n    def insertOrDeleteRows(self, fate, hfate): ...\n    def insertOrDeleteColumns(self, fate, wfate): ...\n    def trimBlank(self): ...\n    def getData(self) -> None: ...\n    def clone(self): ...\n    def create(self): ...\n    def getMeta(self): ...\n\nclass CombinedTableHead:\n    parent: Incomplete\n    dx: Incomplete\n    dy: Incomplete\n    all: Incomplete\n    def __init__(self, parent, dx, dy) -> None: ...\n    def getTable(self): ...\n    def get_width(self): ...\n    def get_height(self): ...\n    def getCell(self, x, y): ...\n    def setCell(self, x, y, c) -> None: ...\n    def toString(self): ...\n    def getCellView(self): ...\n    def isResizable(self): ...\n    def resize(self, w, h): ...\n    def clear(self) -> None: ...\n    def insertOrDeleteRows(self, fate, hfate): ...\n    def insertOrDeleteColumns(self, fate, wfate): ...\n    def trimBlank(self): ...\n    def getData(self) -> None: ...\n    def clone(self) -> None: ...\n    def create(self) -> None: ...\n    def getMeta(self) -> None: ...\n\nclass CompareFlags:\n    padding_strategy: Incomplete\n    ordered: bool\n    show_unchanged: bool\n    unchanged_context: int\n    always_show_order: bool\n    never_show_order: bool\n    show_unchanged_columns: bool\n    unchanged_column_context: int\n    always_show_header: bool\n    acts: Incomplete\n    ids: Incomplete\n    columns_to_ignore: Incomplete\n    allow_nested_cells: bool\n    warnings: Incomplete\n    diff_strategy: Incomplete\n    show_meta: bool\n    show_unchanged_meta: bool\n    tables: Incomplete\n    parent: Incomplete\n    count_like_a_spreadsheet: bool\n    ignore_whitespace: bool\n    ignore_case: bool\n    ignore_epsilon: int\n    terminal_format: Incomplete\n    use_glyphs: bool\n    quote_html: bool\n    def __init__(self) -> None: ...\n    def filter(self, act, allow): ...\n    def allowUpdate(self): ...\n    def allowInsert(self): ...\n    def allowDelete(self): ...\n    def allowColumn(self): ...\n    def getIgnoredColumns(self): ...\n    def addPrimaryKey(self, column) -> None: ...\n    def ignoreColumn(self, column) -> None: ...\n    def addTable(self, table) -> None: ...\n    def addWarning(self, warn) -> None: ...\n    def getWarning(self): ...\n    def getNameByRole(self, name, role): ...\n    def getCanonicalName(self, name): ...\n    def getIdsByRole(self, role): ...\n\nclass CompareTable:\n    indexes: Incomplete\n    comp: Incomplete\n    def __init__(self, comp) -> None: ...\n    def run(self): ...\n    def align(self): ...\n    def getComparisonState(self): ...\n    def alignCore(self, align) -> None: ...\n    def alignCore2(self, align, a, b): ...\n    def alignColumns(self, align, a, b) -> None: ...\n    def testHasSameColumns(self): ...\n    def hasSameColumns2(self, a, b): ...\n    def testIsEqual(self): ...\n    def isEqual2(self, a, b): ...\n    def compareCore(self): ...\n    def storeIndexes(self) -> None: ...\n    def getIndexes(self): ...\n    def useSql(self): ...\n\nclass ConflictInfo:\n    row: Incomplete\n    col: Incomplete\n    pvalue: Incomplete\n    lvalue: Incomplete\n    rvalue: Incomplete\n    def __init__(self, row, col, pvalue, lvalue, rvalue) -> None: ...\n\nclass Coopy:\n    daff_cmd: Incomplete\n    status: Incomplete\n    mv: Incomplete\n    diffs_found: Incomplete\n    fail_if_diff: Incomplete\n    cache_txt: Incomplete\n    flags: Incomplete\n    fragment: Incomplete\n    css_output: Incomplete\n    strategy: Incomplete\n    io: Incomplete\n    order_preference: Incomplete\n    order_set: Incomplete\n    nested_output: Incomplete\n    output_format_set: Incomplete\n    output_format: Incomplete\n    extern_preference: Incomplete\n    csv_eol_preference: Incomplete\n    delim_preference: Incomplete\n    format_preference: Incomplete\n    def __init__(self, io: Incomplete | None = ...) -> None: ...\n    def init(self) -> None: ...\n    def checkFormat(self, name): ...\n    def setFormat(self, name) -> None: ...\n    def getRenderer(self): ...\n    def applyRenderer(self, name, renderer): ...\n    def renderTable(self, name, t): ...\n    def renderTables(self, name, t): ...\n    def saveTable(self, name, t, render: Incomplete | None = ...): ...\n    def encodeTable(self, name, t, render: Incomplete | None = ...): ...\n    def saveTables(self, name, os, use_color, is_diff): ...\n    def saveText(self, name, txt): ...\n    def jsonToTables(self, json): ...\n    def jsonToTable(self, json): ...\n    def useColor(self, flags, output): ...\n    def runDiff(self, parent, a, b, flags, output) -> None: ...\n    def loadTable(self, name, role): ...\n    def command(self, io, cmd, args): ...\n    def installGitDriver(self, io, formats): ...\n    def run(self, args, io: Incomplete | None = ...): ...\n    def coopyhx(self, io): ...\n    @staticmethod\n    def diffAsHtml(local, remote, flags: Incomplete | None = ...): ...\n    @staticmethod\n    def diffAsAnsi(local, remote, flags: Incomplete | None = ...): ...\n    @staticmethod\n    def diff(local, remote, flags: Incomplete | None = ...): ...\n    @staticmethod\n    def getBlankTable(td, comp): ...\n    @staticmethod\n    def align(local, remote, flags, comp): ...\n    @staticmethod\n    def patch(local, patch, flags: Incomplete | None = ...): ...\n    @staticmethod\n    def compareTables(local, remote, flags: Incomplete | None = ...): ...\n    @staticmethod\n    def compareTables3(parent, local, remote, flags: Incomplete | None = ...): ...\n    @staticmethod\n    def keepAround(): ...\n    @staticmethod\n    def cellFor(x): ...\n    @staticmethod\n    def main(): ...\n    @staticmethod\n    def show(t) -> None: ...\n    @staticmethod\n    def jsonify(t): ...\n    @staticmethod\n    def tablify(data): ...\n\nclass CrossMatch:\n    item_b: Incomplete\n    item_a: Incomplete\n    spot_b: Incomplete\n    spot_a: Incomplete\n    def __init__(self) -> None: ...\n\nclass Csv:\n    has_structure: Incomplete\n    cursor: int\n    row_ended: bool\n    delim: Incomplete\n    discovered_eol: Incomplete\n    preferred_eol: Incomplete\n    def __init__(self, delim: Incomplete | None = ..., eol: Incomplete | None = ...) -> None: ...\n    def renderTable(self, t): ...\n    def renderCell(self, v, d, force_quote: Incomplete | None = ...): ...\n    def parseTable(self, txt, tab): ...\n    def makeTable(self, txt): ...\n    def parseCellPart(self, txt): ...\n    def parseCell(self, txt): ...\n    def getDiscoveredEol(self): ...\n    def setPreferredEol(self, eol) -> None: ...\n\nclass Date:\n    dateUTC: Incomplete\n    date: Incomplete\n    def __init__(self, year, month, day, hour, _hx_min, sec) -> None: ...\n    def toString(self): ...\n    @staticmethod\n    def makeLocal(date): ...\n\nclass DiffRender:\n    section: Incomplete\n    td_close: Incomplete\n    td_open: Incomplete\n    text_to_insert: Incomplete\n    open: bool\n    pretty_arrows: bool\n    quote_html: bool\n    def __init__(self) -> None: ...\n    def usePrettyArrows(self, flag) -> None: ...\n    def quoteHtml(self, flag) -> None: ...\n    def insert(self, _hx_str) -> None: ...\n    def beginTable(self) -> None: ...\n    def setSection(self, _hx_str) -> None: ...\n    def beginRow(self, mode) -> None: ...\n    def insertCell(self, txt, mode) -> None: ...\n    def endRow(self) -> None: ...\n    def endTable(self) -> None: ...\n    def html(self): ...\n    def toString(self): ...\n    def render(self, tab): ...\n    def renderTables(self, tabs): ...\n    def sampleCss(self): ...\n    def completeHtml(self) -> None: ...\n    @staticmethod\n    def examineCell(\n        x, y, view, raw, vcol, vrow, vcorner, cell, offset: Incomplete | None = ...\n    ): ...\n    @staticmethod\n    def markSpaces(sl, sr): ...\n    @staticmethod\n    def renderCell(tab, view, x, y): ...\n\nclass DiffSummary:\n    different: Incomplete\n    col_count_final: Incomplete\n    col_count_initial: Incomplete\n    row_count_final: Incomplete\n    row_count_initial: Incomplete\n    row_count_final_with_header: Incomplete\n    row_count_initial_with_header: Incomplete\n    col_reorders: Incomplete\n    col_renames: Incomplete\n    col_updates: Incomplete\n    col_inserts: Incomplete\n    col_deletes: Incomplete\n    row_reorders: Incomplete\n    row_updates: Incomplete\n    row_inserts: Incomplete\n    row_deletes: Incomplete\n    def __init__(self) -> None: ...\n\nclass FlatCellBuilder:\n    conflict_separator: Incomplete\n    separator: Incomplete\n    view: Incomplete\n    flags: Incomplete\n    def __init__(self, flags) -> None: ...\n    def needSeparator(self): ...\n    def setSeparator(self, separator) -> None: ...\n    def setConflictSeparator(self, separator) -> None: ...\n    def setView(self, view) -> None: ...\n    def update(self, local, remote): ...\n    def conflict(self, parent, local, remote): ...\n    def marker(self, label): ...\n    def links(self, unit, row_like): ...\n    @staticmethod\n    def quoteForDiff(v, d): ...\n\nclass Row: ...\n\nclass HighlightPatch:\n    finished_columns: Incomplete\n    next_meta: Incomplete\n    prev_meta: Incomplete\n    process_meta: Incomplete\n    meta_change: Incomplete\n    preambleRow: Incomplete\n    headerRow: Incomplete\n    haveDroppedColumns: Incomplete\n    colPermutationRev: Incomplete\n    colPermutation: Incomplete\n    rowPermutationRev: Incomplete\n    rowPermutation: Incomplete\n    actions: Incomplete\n    lastSourceRow: Incomplete\n    patchInSourceRow: Incomplete\n    patchInDestCol: Incomplete\n    destInPatchCol: Incomplete\n    patchInSourceCol: Incomplete\n    sourceInPatchCol: Incomplete\n    indexes: Incomplete\n    rcOffset: Incomplete\n    cellInfo: Incomplete\n    rowInfo: Incomplete\n    cmods: Incomplete\n    mods: Incomplete\n    payloadTop: Incomplete\n    payloadCol: Incomplete\n    currentRow: Incomplete\n    modifier: Incomplete\n    headerMove: Incomplete\n    headerRename: Incomplete\n    headerPost: Incomplete\n    headerPre: Incomplete\n    header: Incomplete\n    csv: Incomplete\n    source: Incomplete\n    patch: Incomplete\n    flags: Incomplete\n    view: Incomplete\n    sourceView: Incomplete\n    meta: Incomplete\n    def __init__(self, source, patch, flags: Incomplete | None = ...) -> None: ...\n    def reset(self): ...\n    def processMeta(self) -> None: ...\n    def apply(self): ...\n    def needSourceColumns(self) -> None: ...\n    def needDestColumns(self) -> None: ...\n    def needSourceIndex(self) -> None: ...\n    def setMetaProp(self, target, column_name, prop_name, value) -> None: ...\n    def applyMetaRow(self, code) -> None: ...\n    def applyRow(self, r): ...\n    def getDatum(self, c): ...\n    def getString(self, c): ...\n    def getStringNull(self, c): ...\n    def applyMeta(self) -> None: ...\n    def applyHeader(self) -> None: ...\n    def lookUp(self, _hx_del: Incomplete | None = ...): ...\n    def applyActionExternal(self, code) -> None: ...\n    def applyAction(self, code): ...\n    def checkAct(self) -> None: ...\n    def getPreString(self, txt): ...\n    def getRowString(self, c): ...\n    def isPreamble(self): ...\n    def sortMods(self, a, b): ...\n    def processMods(self, rmods, fate, _hx_len): ...\n    def useMetaForColumnChanges(self): ...\n    def useMetaForRowChanges(self): ...\n    def computeOrdering(self, mods, permutation, permutationRev, dim) -> None: ...\n    def permuteRows(self) -> None: ...\n    def fillInNewColumns(self) -> None: ...\n    def finishRows(self) -> None: ...\n    def permuteColumns(self) -> None: ...\n    def finishColumns(self): ...\n\nclass HighlightPatchUnit:\n    add: bool\n    rem: bool\n    update: bool\n    sourceRow: int\n    sourceRowOffset: int\n    sourcePrevRow: int\n    sourceNextRow: int\n    destRow: int\n    patchRow: int\n    code: str\n    def __init__(self) -> None: ...\n    def toString(self): ...\n\nclass Index:\n    indexed_table: Incomplete\n    v: Incomplete\n    items: Incomplete\n    cols: Incomplete\n    keys: Incomplete\n    top_freq: int\n    height: int\n    hdr: int\n    ignore_whitespace: bool\n    ignore_case: bool\n    def __init__(self, flags) -> None: ...\n    def addColumn(self, i) -> None: ...\n    def indexTable(self, t, hdr) -> None: ...\n    def toKey(self, t, i): ...\n    def toKeyByContent(self, row): ...\n    def getTable(self): ...\n\nclass IndexItem:\n    lst: Incomplete\n    def __init__(self) -> None: ...\n    def add(self, i): ...\n    def length(self): ...\n    def value(self): ...\n    def asList(self): ...\n\nclass IndexPair:\n    flags: Incomplete\n    ia: Incomplete\n    ib: Incomplete\n    quality: int\n    hdr: int\n    def __init__(self, flags) -> None: ...\n    def addColumns(self, ca, cb) -> None: ...\n    def indexTables(self, a, b, hdr) -> None: ...\n    def queryByKey(self, ka): ...\n    def queryByContent(self, row): ...\n    def queryLocal(self, row): ...\n    def localKey(self, row): ...\n    def remoteKey(self, row): ...\n    def getTopFreq(self): ...\n    def getQuality(self): ...\n\nclass Meta: ...\n\nclass JsonTable:\n    name: Incomplete\n    idx2col: Incomplete\n    h: Incomplete\n    w: Incomplete\n    data: Incomplete\n    columns: Incomplete\n    rows: Incomplete\n    def __init__(self, data, name) -> None: ...\n    def getTable(self): ...\n    def get_width(self): ...\n    def get_height(self): ...\n    def getCell(self, x, y): ...\n    def setCell(self, x, y, c) -> None: ...\n    def toString(self): ...\n    def getCellView(self): ...\n    def isResizable(self): ...\n    def resize(self, w, h): ...\n    def clear(self) -> None: ...\n    def insertOrDeleteRows(self, fate, hfate): ...\n    def insertOrDeleteColumns(self, fate, wfate): ...\n    def trimBlank(self): ...\n    def getData(self) -> None: ...\n    def clone(self) -> None: ...\n    def setMeta(self, meta) -> None: ...\n    def getMeta(self): ...\n    def create(self) -> None: ...\n    def alterColumns(self, columns): ...\n    def changeRow(self, rc): ...\n    def applyFlags(self, flags): ...\n    def asTable(self) -> None: ...\n    def cloneMeta(self, table: Incomplete | None = ...) -> None: ...\n    def useForColumnChanges(self): ...\n    def useForRowChanges(self): ...\n    def getRowStream(self) -> None: ...\n    def isNested(self): ...\n    def isSql(self): ...\n    def getName(self): ...\n\nclass JsonTables:\n    flags: Incomplete\n    db: Incomplete\n    t: Incomplete\n    def __init__(self, json, flags) -> None: ...\n    def getCell(self, x, y): ...\n    def setCell(self, x, y, c) -> None: ...\n    def getCellView(self): ...\n    def isResizable(self): ...\n    def resize(self, w, h): ...\n    def clear(self) -> None: ...\n    def insertOrDeleteRows(self, fate, hfate): ...\n    def insertOrDeleteColumns(self, fate, wfate): ...\n    def trimBlank(self): ...\n    def get_width(self): ...\n    def get_height(self): ...\n    def getData(self) -> None: ...\n    def clone(self) -> None: ...\n    def getMeta(self): ...\n    def create(self) -> None: ...\n\nclass Lambda:\n    @staticmethod\n    def array(it): ...\n    @staticmethod\n    def has(it, elt): ...\n\nclass Merger:\n    conflict_infos: Incomplete\n    conflicts: Incomplete\n    column_mix_remote: Incomplete\n    column_mix_local: Incomplete\n    row_mix_remote: Incomplete\n    row_mix_local: Incomplete\n    column_units: Incomplete\n    column_order: Incomplete\n    units: Incomplete\n    order: Incomplete\n    parent: Incomplete\n    local: Incomplete\n    remote: Incomplete\n    flags: Incomplete\n    def __init__(self, parent, local, remote, flags) -> None: ...\n    def shuffleDimension(self, dim_units, _hx_len, fate, cl, cr): ...\n    def shuffleColumns(self) -> None: ...\n    def shuffleRows(self) -> None: ...\n    def apply(self): ...\n    def getConflictInfos(self): ...\n    def addConflictInfo(self, row, col, view, pcell, lcell, rcell) -> None: ...\n    @staticmethod\n    def makeConflictedCell(view, pcell, lcell, rcell): ...\n\nclass Mover:\n    @staticmethod\n    def moveUnits(units): ...\n    @staticmethod\n    def move(isrc, idest): ...\n    @staticmethod\n    def moveWithoutExtras(src, dest): ...\n\nclass Ndjson:\n    columns: Incomplete\n    tab: Incomplete\n    view: Incomplete\n    header_row: int\n    def __init__(self, tab) -> None: ...\n    def renderRow(self, r): ...\n    def render(self): ...\n    def addRow(self, r, txt) -> None: ...\n    def addHeaderRow(self, r) -> None: ...\n    def parse(self, txt) -> None: ...\n\nclass NestedCellBuilder:\n    view: Incomplete\n    def __init__(self) -> None: ...\n    def needSeparator(self): ...\n    def setSeparator(self, separator) -> None: ...\n    def setConflictSeparator(self, separator) -> None: ...\n    def setView(self, view) -> None: ...\n    def update(self, local, remote): ...\n    def conflict(self, parent, local, remote): ...\n    def marker(self, label): ...\n    def negToNull(self, x): ...\n    def links(self, unit, row_like): ...\n\nclass Ordering:\n    order: Incomplete\n    ignore_parent: bool\n    def __init__(self) -> None: ...\n    def add(self, l, r, p: Incomplete | None = ...) -> None: ...\n    def getList(self): ...\n    def setList(self, lst) -> None: ...\n    def toString(self): ...\n    def ignoreParent(self) -> None: ...\n\nclass PropertyChange:\n    val: Incomplete\n    name: Incomplete\n    prevName: Incomplete\n    def __init__(self) -> None: ...\n\nclass Reflect:\n    @staticmethod\n    def field(o, field): ...\n    @staticmethod\n    def isFunction(f): ...\n    @staticmethod\n    def compare(a, b): ...\n\nclass RowChange:\n    action: Incomplete\n    is_key: Incomplete\n    conflicted: Incomplete\n    conflicting_parent_val: Incomplete\n    conflicting_val: Incomplete\n    val: Incomplete\n    cond: Incomplete\n    def __init__(self) -> None: ...\n    def showMap(self, m): ...\n    def toString(self): ...\n\nclass RowStream: ...\n\nclass SimpleMeta:\n    may_be_nested: Incomplete\n    row_change_cache: Incomplete\n    row_active: Incomplete\n    keys: Incomplete\n    metadata: Incomplete\n    has_properties: Incomplete\n    name2col: Incomplete\n    name2row: Incomplete\n    t: Incomplete\n    def __init__(\n        self, t, has_properties: Incomplete | None = ..., may_be_nested: Incomplete | None = ...\n    ) -> None: ...\n    def storeRowChanges(self, changes) -> None: ...\n    def rowChange(self) -> None: ...\n    def colChange(self) -> None: ...\n    def col(self, key): ...\n    def row(self, key): ...\n    def alterColumns(self, columns): ...\n    def setCell(self, c, r, val): ...\n    def addMetaData(self, column, property, val) -> None: ...\n    def asTable(self): ...\n    def cloneMeta(self, table: Incomplete | None = ...): ...\n    def useForColumnChanges(self): ...\n    def useForRowChanges(self): ...\n    def changeRow(self, rc): ...\n    def applyFlags(self, flags): ...\n    def getRowStream(self): ...\n    def isNested(self): ...\n    def isSql(self): ...\n    def getName(self) -> None: ...\n\nclass SimpleTable:\n    data: Incomplete\n    w: Incomplete\n    h: Incomplete\n    meta: Incomplete\n    def __init__(self, w, h) -> None: ...\n    def getTable(self): ...\n    def get_width(self): ...\n    def get_height(self): ...\n    def getCell(self, x, y): ...\n    def setCell(self, x, y, c) -> None: ...\n    def toString(self): ...\n    def getCellView(self): ...\n    def isResizable(self): ...\n    def resize(self, w, h): ...\n    def clear(self) -> None: ...\n    def insertOrDeleteRows(self, fate, hfate): ...\n    def insertOrDeleteColumns(self, fate, wfate): ...\n    def trimBlank(self): ...\n    def getData(self) -> None: ...\n    def clone(self): ...\n    def create(self): ...\n    def setMeta(self, meta) -> None: ...\n    def getMeta(self): ...\n    @staticmethod\n    def tableToString(tab): ...\n    @staticmethod\n    def tableIsSimilar(tab1, tab2): ...\n\nclass View: ...\n\nclass SimpleView:\n    def __init__(self) -> None: ...\n    def toString(self, d): ...\n    def equals(self, d1, d2): ...\n    def toDatum(self, x): ...\n    def makeHash(self): ...\n    def hashSet(self, h, _hx_str, d) -> None: ...\n    def hashExists(self, h, _hx_str): ...\n    def hashGet(self, h, _hx_str): ...\n    def isHash(self, h): ...\n    def isTable(self, t): ...\n    def getTable(self, t): ...\n    def wrapTable(self, t): ...\n\nclass SparseSheet:\n    zero: Incomplete\n    row: Incomplete\n    w: int\n    h: Incomplete\n    def __init__(self) -> None: ...\n    def resize(self, w, h, zero) -> None: ...\n    def nonDestructiveResize(self, w, h, zero) -> None: ...\n    def get(self, x, y): ...\n    def set(self, x, y, val) -> None: ...\n\nclass SqlColumn:\n    name: str\n    primary: bool\n    type_value: Incomplete\n    type_family: Incomplete\n    def __init__(self) -> None: ...\n    def setName(self, name) -> None: ...\n    def setPrimaryKey(self, primary) -> None: ...\n    def setType(self, value, family) -> None: ...\n    def getName(self): ...\n    def isPrimaryKey(self): ...\n    def toString(self): ...\n\nclass SqlCompare:\n    needed: Incomplete\n    alt_peered: Incomplete\n    peered: Incomplete\n    diff_ct: Incomplete\n    at2: Incomplete\n    at1: Incomplete\n    at0: Incomplete\n    db: Incomplete\n    local: Incomplete\n    remote: Incomplete\n    alt: Incomplete\n    align: Incomplete\n    flags: Incomplete\n    def __init__(\n        self,\n        db,\n        local,\n        remote,\n        alt,\n        align: Incomplete | None = ...,\n        flags: Incomplete | None = ...,\n    ) -> None: ...\n    def equalArray(self, a1, a2): ...\n    def validateSchema(self): ...\n    def denull(self, x): ...\n    def link(self) -> None: ...\n    def linkQuery(self, query, order) -> None: ...\n    def where(self, txt): ...\n    def scanColumns(self, all_cols1, all_cols2, key_cols, present1, present2, align) -> None: ...\n    def apply(self): ...\n\nclass SqlDatabase: ...\nclass SqlHelper: ...\n\nclass SqlTable:\n    columnNames: Incomplete\n    quotedTableName: Incomplete\n    columns: Incomplete\n    db: Incomplete\n    name: Incomplete\n    helper: Incomplete\n    cache: Incomplete\n    h: int\n    id2rid: Incomplete\n    def __init__(self, db, name, helper: Incomplete | None = ...) -> None: ...\n    def getColumns(self) -> None: ...\n    def getPrimaryKey(self): ...\n    def getAllButPrimaryKey(self): ...\n    def getColumnNames(self): ...\n    def getQuotedTableName(self): ...\n    def getQuotedColumnName(self, name): ...\n    def getCell(self, x, y): ...\n    def setCellCache(self, x, y, c) -> None: ...\n    def setCell(self, x, y, c) -> None: ...\n    def getCellView(self): ...\n    def isResizable(self): ...\n    def resize(self, w, h): ...\n    def clear(self) -> None: ...\n    def insertOrDeleteRows(self, fate, hfate): ...\n    def insertOrDeleteColumns(self, fate, wfate): ...\n    def trimBlank(self): ...\n    def get_width(self): ...\n    def get_height(self): ...\n    def getData(self) -> None: ...\n    def clone(self) -> None: ...\n    def create(self) -> None: ...\n    def getMeta(self): ...\n    def alterColumns(self, columns): ...\n    def changeRow(self, rc): ...\n    def asTable(self): ...\n    def useForColumnChanges(self): ...\n    def useForRowChanges(self): ...\n    def cloneMeta(self, table: Incomplete | None = ...) -> None: ...\n    def applyFlags(self, flags): ...\n    def getDatabase(self): ...\n    def getRowStream(self): ...\n    def isNested(self): ...\n    def isSql(self): ...\n    def fetchRow(self): ...\n    def fetchColumns(self): ...\n    def getName(self): ...\n\nclass SqlTableName:\n    name: Incomplete\n    prefix: Incomplete\n    def __init__(self, name: Incomplete | None = ..., prefix: Incomplete | None = ...) -> None: ...\n    def toString(self): ...\n\nclass SqlTables:\n    flags: Incomplete\n    t: Incomplete\n    db: Incomplete\n    def __init__(self, db, flags, role) -> None: ...\n    def getCell(self, x, y): ...\n    def setCell(self, x, y, c) -> None: ...\n    def getCellView(self): ...\n    def isResizable(self): ...\n    def resize(self, w, h): ...\n    def clear(self) -> None: ...\n    def insertOrDeleteRows(self, fate, hfate): ...\n    def insertOrDeleteColumns(self, fate, wfate): ...\n    def trimBlank(self): ...\n    def get_width(self): ...\n    def get_height(self): ...\n    def getData(self) -> None: ...\n    def clone(self) -> None: ...\n    def create(self) -> None: ...\n    def getMeta(self): ...\n\nclass SqliteHelper:\n    def __init__(self) -> None: ...\n    def getTableNames(self, db): ...\n    def countRows(self, db, name): ...\n    def getRowIDs(self, db, name): ...\n    def update(self, db, name, conds, vals): ...\n    def delete(self, db, name, conds): ...\n    def insert(self, db, name, vals): ...\n    def attach(self, db, tag, resource_name): ...\n    def columnListSql(self, x): ...\n    def fetchSchema(self, db, name): ...\n    def splitSchema(self, db, name, sql): ...\n    def alterColumns(self, db, name, columns): ...\n\nclass Std:\n    @staticmethod\n    def isOfType(v, t): ...\n    @staticmethod\n    def string(s): ...\n    @staticmethod\n    def parseInt(x): ...\n    @staticmethod\n    def shortenPossibleNumber(x): ...\n    @staticmethod\n    def parseFloat(x): ...\n\nclass Float: ...\nclass Int: ...\nclass Bool: ...\nclass Dynamic: ...\n\nclass StringBuf:\n    b: Incomplete\n    def __init__(self) -> None: ...\n    def get_length(self): ...\n\nclass StringTools:\n    @staticmethod\n    def htmlEscape(s, quotes: Incomplete | None = ...): ...\n    @staticmethod\n    def isSpace(s, pos): ...\n    @staticmethod\n    def ltrim(s): ...\n    @staticmethod\n    def rtrim(s): ...\n    @staticmethod\n    def trim(s): ...\n    @staticmethod\n    def lpad(s, c, l): ...\n    @staticmethod\n    def replace(s, sub, by): ...\n\nclass sys_FileSystem:\n    @staticmethod\n    def exists(path): ...\n\nclass haxe_IMap: ...\n\nclass haxe_ds_StringMap:\n    h: Incomplete\n    def __init__(self) -> None: ...\n    def keys(self): ...\n    def iterator(self): ...\n\nclass python_HaxeIterator:\n    checked: bool\n    has: bool\n    x: Incomplete\n    it: Incomplete\n    def __init__(self, it) -> None: ...\n    def __next__(self): ...\n    def next(self): ...\n    def hasNext(self): ...\n\nclass Sys:\n    @staticmethod\n    def exit(code) -> None: ...\n    @staticmethod\n    def args(): ...\n    @staticmethod\n    def getEnv(s): ...\n    @staticmethod\n    def command(cmd, args: Incomplete | None = ...): ...\n    @staticmethod\n    def stdout(): ...\n    @staticmethod\n    def stderr(): ...\n\nclass TableComparisonState:\n    child_order: Incomplete\n    children: Incomplete\n    alignment: Incomplete\n    b_meta: Incomplete\n    a_meta: Incomplete\n    p_meta: Incomplete\n    compare_flags: Incomplete\n    has_same_columns_known: Incomplete\n    has_same_columns: Incomplete\n    is_equal_known: Incomplete\n    is_equal: Incomplete\n    run_to_completion: Incomplete\n    completed: Incomplete\n    b: Incomplete\n    a: Incomplete\n    p: Incomplete\n    def __init__(self) -> None: ...\n    def reset(self) -> None: ...\n    def getMeta(self) -> None: ...\n\nclass TableDiff:\n    nesting_present: Incomplete\n    nested: Incomplete\n    column_units_updated: Incomplete\n    col_reorders: Incomplete\n    col_renames: Incomplete\n    col_updates: Incomplete\n    col_inserts: Incomplete\n    col_deletes: Incomplete\n    row_reorders: Incomplete\n    row_updates: Incomplete\n    row_inserts: Incomplete\n    row_deletes: Incomplete\n    schema_diff_found: Incomplete\n    diff_found: Incomplete\n    publish: Incomplete\n    act: Incomplete\n    have_addition: Incomplete\n    top_line_done: Incomplete\n    have_schema: Incomplete\n    schema: Incomplete\n    conflict_sep: Incomplete\n    sep: Incomplete\n    v: Incomplete\n    allow_column: Incomplete\n    allow_update: Incomplete\n    allow_delete: Incomplete\n    allow_insert: Incomplete\n    active_column: Incomplete\n    active_row: Incomplete\n    col_moves: Incomplete\n    row_moves: Incomplete\n    show_rc_numbers: Incomplete\n    column_units: Incomplete\n    row_units: Incomplete\n    order: Incomplete\n    is_index_b: Incomplete\n    is_index_a: Incomplete\n    is_index_p: Incomplete\n    rb_header: Incomplete\n    ra_header: Incomplete\n    rp_header: Incomplete\n    p: Incomplete\n    b: Incomplete\n    a: Incomplete\n    has_parent: Incomplete\n    col_map: Incomplete\n    row_map: Incomplete\n    align: Incomplete\n    flags: Incomplete\n    builder: Incomplete\n    preserve_columns: bool\n    def __init__(self, align, flags) -> None: ...\n    def setCellBuilder(self, builder) -> None: ...\n    def getSeparator(self, t, t2, root): ...\n    def isReordered(self, m, ct): ...\n    def spreadContext(self, units, _hx_del, active) -> None: ...\n    def setIgnore(self, ignore, idx_ignore, tab, r_header) -> None: ...\n    def countActive(self, active): ...\n    def reset(self): ...\n    def setupTables(self) -> None: ...\n    def scanActivity(self) -> None: ...\n    def setupColumns(self) -> None: ...\n    def setupMoves(self) -> None: ...\n    def scanSchema(self) -> None: ...\n    def checkRcNumbers(self, w, h) -> None: ...\n    def addRcNumbers(self, output): ...\n    def elideColumns(self, output, admin_w) -> None: ...\n    def addSchema(self, output) -> None: ...\n    def addHeader(self, output) -> None: ...\n    def checkMeta(self, t, meta): ...\n    def getMetaTable(self, t): ...\n    def addMeta(self, output): ...\n    def refineActivity(self) -> None: ...\n    def normalizeString(self, v, _hx_str): ...\n    def isEqual(self, v, aa, bb): ...\n    def checkNesting(self, v, have_ll, ll, have_rr, rr, have_pp, pp, x, y): ...\n    def scanRow(self, unit, output, at, i, out) -> None: ...\n    def hilite(self, output): ...\n    def hiliteSingle(self, output): ...\n    def hiliteWithNesting(self, output): ...\n    def hasDifference(self): ...\n    def hasSchemaDifference(self): ...\n    def isNested(self): ...\n    def getComparisonState(self): ...\n    def getSummary(self): ...\n\nclass TableIO:\n    def __init__(self) -> None: ...\n    def valid(self): ...\n    def getContent(self, name): ...\n    def saveContent(self, name, txt): ...\n    def args(self): ...\n    def writeStdout(self, txt) -> None: ...\n    def writeStderr(self, txt) -> None: ...\n    def command(self, cmd, args): ...\n    def hasAsync(self): ...\n    def exists(self, path): ...\n    def isTtyKnown(self): ...\n    def isTty(self): ...\n    def openSqliteDatabase(self, path): ...\n    def sendToBrowser(self, html) -> None: ...\n\nclass TableModifier:\n    t: Incomplete\n    def __init__(self, t) -> None: ...\n    def removeColumn(self, at): ...\n\nclass TableStream:\n    row: Incomplete\n    columns: Incomplete\n    t: Incomplete\n    at: int\n    h: Incomplete\n    src: Incomplete\n    def __init__(self, t) -> None: ...\n    def fetchColumns(self): ...\n    def fetchRow(self): ...\n    def fetch(self): ...\n    def getCell(self, x): ...\n    def width(self): ...\n\nclass Tables:\n    alignment: Incomplete\n    template: Incomplete\n    tables: Incomplete\n    table_order: Incomplete\n    def __init__(self, template) -> None: ...\n    def add(self, name): ...\n    def getOrder(self): ...\n    def get(self, name): ...\n    def one(self): ...\n    def hasInsDel(self): ...\n\nclass TerminalDiffRender:\n    v: Incomplete\n    csv: Incomplete\n    t: Incomplete\n    codes: Incomplete\n    align_columns: bool\n    wide_columns: bool\n    use_glyphs: bool\n    flags: Incomplete\n    delim: Incomplete\n    diff: Incomplete\n    def __init__(\n        self,\n        flags: Incomplete | None = ...,\n        delim: Incomplete | None = ...,\n        diff: Incomplete | None = ...,\n    ) -> None: ...\n    def alignColumns(self, enable) -> None: ...\n    def render(self, t): ...\n    def getText(self, x, y, color): ...\n    def pickSizes(self, t): ...\n\nclass ValueType(Enum):\n    @staticmethod\n    def TClass(c): ...\n    @staticmethod\n    def TEnum(e): ...\n\nclass Type:\n    @staticmethod\n    def getClass(o): ...\n    @staticmethod\n    def typeof(v): ...\n\nclass Unit:\n    l: Incomplete\n    r: Incomplete\n    p: Incomplete\n    def __init__(\n        self, l: Incomplete | None = ..., r: Incomplete | None = ..., p: Incomplete | None = ...\n    ) -> None: ...\n    def lp(self): ...\n    def toString(self): ...\n    def fromString(self, txt): ...\n    def base26(self, num): ...\n    def toBase26String(self): ...\n    @staticmethod\n    def describe(i): ...\n\nclass Viterbi:\n    path: Incomplete\n    src: Incomplete\n    cost: Incomplete\n    best_cost: Incomplete\n    path_valid: Incomplete\n    mode: Incomplete\n    index: Incomplete\n    T: int\n    K: Incomplete\n    def __init__(self) -> None: ...\n    def reset(self) -> None: ...\n    def setSize(self, states, sequence_length) -> None: ...\n    def assertMode(self, next) -> None: ...\n    def addTransition(self, s0, s1, c) -> None: ...\n    def endTransitions(self) -> None: ...\n    def beginTransitions(self) -> None: ...\n    def calculatePath(self) -> None: ...\n    def toString(self): ...\n    def length(self): ...\n    def get(self, i): ...\n    def getCost(self): ...\n\nclass haxe_Exception(Exception):\n    def __init__(\n        self, message, previous: Incomplete | None = ..., native: Incomplete | None = ...\n    ) -> None: ...\n    def unwrap(self): ...\n    def get_native(self): ...\n    @staticmethod\n    def caught(value): ...\n    @staticmethod\n    def thrown(value): ...\n\nclass haxe_NativeStackTrace:\n    @staticmethod\n    def saveStack(exception) -> None: ...\n    @staticmethod\n    def exceptionStack(): ...\n\nclass haxe_ValueException(haxe_Exception):\n    value: Incomplete\n    def __init__(\n        self, value, previous: Incomplete | None = ..., native: Incomplete | None = ...\n    ) -> None: ...\n    def unwrap(self): ...\n\nclass haxe_ds_IntMap:\n    h: Incomplete\n    def __init__(self) -> None: ...\n    def set(self, key, value) -> None: ...\n    def remove(self, key): ...\n    def keys(self): ...\n    def toString(self): ...\n\nclass haxe_format_JsonPrinter:\n    replacer: Incomplete\n    indent: Incomplete\n    pretty: Incomplete\n    nind: int\n    buf: Incomplete\n    def __init__(self, replacer, space) -> None: ...\n    def write(self, k, v) -> None: ...\n    def classString(self, v) -> None: ...\n    def fieldsString(self, v, fields) -> None: ...\n    def quote(self, s) -> None: ...\n    @staticmethod\n    def print(o, replacer: Incomplete | None = ..., space: Incomplete | None = ...): ...\n\nclass haxe_io_Bytes:\n    length: Incomplete\n    b: Incomplete\n    def __init__(self, length, b) -> None: ...\n    @staticmethod\n    def ofString(s, encoding: Incomplete | None = ...): ...\n\nclass haxe_io_Encoding(Enum): ...\n\nclass haxe_io_Error(Enum):\n    @staticmethod\n    def Custom(e): ...\n\nclass haxe_io_Output:\n    def writeByte(self, c) -> None: ...\n    def writeBytes(self, s, pos, _hx_len): ...\n    bigEndian: Incomplete\n    def set_bigEndian(self, b): ...\n    def writeFullBytes(self, s, pos, _hx_len) -> None: ...\n    def writeString(self, s, encoding: Incomplete | None = ...) -> None: ...\n\nclass haxe_iterators_ArrayIterator:\n    current: int\n    array: Incomplete\n    def __init__(self, array) -> None: ...\n    def hasNext(self): ...\n    def __next__(self): ...\n    def next(self): ...\n\nclass haxe_iterators_ArrayKeyValueIterator:\n    current: int\n    array: Incomplete\n    def __init__(self, array) -> None: ...\n    def hasNext(self): ...\n    def __next__(self): ...\n    def next(self): ...\n\nclass python_Boot:\n    @staticmethod\n    def toString1(o, s): ...\n    @staticmethod\n    def fields(o): ...\n    @staticmethod\n    def simpleField(o, field): ...\n    @staticmethod\n    def hasField(o, field): ...\n    @staticmethod\n    def field(o, field): ...\n    @staticmethod\n    def getInstanceFields(c): ...\n    @staticmethod\n    def getSuperClass(c): ...\n    @staticmethod\n    def getClassFields(c): ...\n    @staticmethod\n    def unhandleKeywords(name): ...\n\nclass python__KwArgs_KwArgs_Impl_:\n    @staticmethod\n    def fromT(d): ...\n\nclass python_Lib:\n    @staticmethod\n    def dictToAnon(v): ...\n    @staticmethod\n    def anonToDict(o): ...\n    @staticmethod\n    def anonAsDict(o): ...\n\nclass python_internal_ArrayImpl:\n    @staticmethod\n    def concat(a1, a2): ...\n    @staticmethod\n    def copy(x): ...\n    @staticmethod\n    def iterator(x): ...\n    @staticmethod\n    def keyValueIterator(x): ...\n    @staticmethod\n    def indexOf(a, x, fromIndex: Incomplete | None = ...): ...\n    @staticmethod\n    def lastIndexOf(a, x, fromIndex: Incomplete | None = ...): ...\n    @staticmethod\n    def join(x, sep): ...\n    @staticmethod\n    def toString(x): ...\n    @staticmethod\n    def pop(x): ...\n    @staticmethod\n    def push(x, e): ...\n    @staticmethod\n    def unshift(x, e) -> None: ...\n    @staticmethod\n    def remove(x, e): ...\n    @staticmethod\n    def contains(x, e): ...\n    @staticmethod\n    def shift(x): ...\n    @staticmethod\n    def slice(x, pos, end: Incomplete | None = ...): ...\n    @staticmethod\n    def sort(x, f) -> None: ...\n    @staticmethod\n    def splice(x, pos, _hx_len): ...\n    @staticmethod\n    def map(x, f): ...\n    @staticmethod\n    def filter(x, f): ...\n    @staticmethod\n    def insert(a, pos, x) -> None: ...\n    @staticmethod\n    def reverse(a) -> None: ...\n\nclass HxOverrides:\n    @staticmethod\n    def iterator(x): ...\n    @staticmethod\n    def eq(a, b): ...\n    @staticmethod\n    def stringOrNull(s): ...\n    @staticmethod\n    def modf(a, b): ...\n    @staticmethod\n    def mod(a, b): ...\n    @staticmethod\n    def mapKwArgs(a, v): ...\n\nclass python_internal_MethodClosure:\n    obj: Incomplete\n    func: Incomplete\n    def __init__(self, obj, func) -> None: ...\n    def __call__(self, *args): ...\n\nclass HxString:\n    @staticmethod\n    def split(s, d): ...\n    @staticmethod\n    def charCodeAt(s, index): ...\n    @staticmethod\n    def charAt(s, index): ...\n    @staticmethod\n    def lastIndexOf(s, _hx_str, startIndex: Incomplete | None = ...): ...\n    @staticmethod\n    def toUpperCase(s): ...\n    @staticmethod\n    def toLowerCase(s): ...\n    @staticmethod\n    def indexOf(s, _hx_str, startIndex: Incomplete | None = ...): ...\n    @staticmethod\n    def indexOfImpl(s, _hx_str, startIndex): ...\n    @staticmethod\n    def toString(s): ...\n    @staticmethod\n    def substring(s, startIndex, endIndex: Incomplete | None = ...): ...\n    @staticmethod\n    def substr(s, startIndex, _hx_len: Incomplete | None = ...): ...\n\nclass python_io_NativeOutput(haxe_io_Output):\n    stream: Incomplete\n    def __init__(self, stream) -> None: ...\n\nclass python_io_IOutput: ...\nclass python_io_IFileOutput: ...\n\nclass python_io_NativeTextOutput(python_io_NativeOutput):\n    def __init__(self, stream) -> None: ...\n    def writeBytes(self, s, pos, _hx_len): ...\n    def writeByte(self, c) -> None: ...\n\nclass python_io_FileTextOutput(python_io_NativeTextOutput):\n    def __init__(self, stream) -> None: ...\n\nclass python_io_IoTools:\n    @staticmethod\n    def createFileOutputFromText(t): ...\n\nclass sys_io_File:\n    @staticmethod\n    def getContent(path): ...\n    @staticmethod\n    def saveContent(path, content) -> None: ...\n\nclass sys_io_FileOutput(haxe_io_Output):\n    impl: Incomplete\n    def __init__(self, impl) -> None: ...\n    def set_bigEndian(self, b): ...\n    def writeByte(self, c) -> None: ...\n    def writeBytes(self, s, pos, _hx_len): ...\n    def writeFullBytes(self, s, pos, _hx_len) -> None: ...\n    def writeString(self, s, encoding: Incomplete | None = ...) -> None: ...\n\nclass PythonCellView(View):\n    def __init__(self) -> None: ...\n    def toString(self, d): ...\n    def equals(self, d1, d2): ...\n    def toDatum(self, d): ...\n    def makeHash(self): ...\n    def isHash(self, d): ...\n    def hashSet(self, d, k, v) -> None: ...\n    def hashGet(self, d, k): ...\n    def hashExists(self, d, k): ...\n\nclass PythonTableView(Table):\n    data: Incomplete\n    height: Incomplete\n    width: int\n    def __init__(self, data) -> None: ...\n    def get_width(self): ...\n    def get_height(self): ...\n    def getCell(self, x, y): ...\n    def setCell(self, x, y, c) -> None: ...\n    def toString(self): ...\n    def getCellView(self): ...\n    def isResizable(self): ...\n    def resize(self, w, h): ...\n    def clear(self) -> None: ...\n    def trimBlank(self): ...\n    def getData(self): ...\n    def insertOrDeleteRows(self, fate, hfate): ...\n    def insertOrDeleteColumns(self, fate, wfate): ...\n    def isSimilar(self, alt): ...\n    def clone(self): ...\n    def create(self): ...\n    def getMeta(self) -> None: ...\n\nclass SqliteDatabase(SqlDatabase):\n    db: Incomplete\n    fname: Incomplete\n    cursor: Incomplete\n    row: Incomplete\n    quoter: Incomplete\n    view: Incomplete\n    def __init__(self, db, fname) -> None: ...\n    def getQuotedColumnName(self, name): ...\n    def getQuotedTableName(self, name): ...\n    def getColumns(self, name): ...\n    def begin(self, query, args=..., order=...): ...\n    def beginRow(self, tab, row, order=...): ...\n    def read(self): ...\n    def get(self, index): ...\n    def end(self) -> None: ...\n    def rowid(self): ...\n    def getHelper(self): ...\n    def getNameForAttachment(self): ...\n\ndef get_stdout(): ...\ndef stream_write(s): ...\ndef main() -> None: ...\n"
  },
  {
    "path": "third-party-stubs/mashumaro/__init__.pyi",
    "content": "from mashumaro.exceptions import MissingField as MissingField\nfrom mashumaro.helper import field_options as field_options, pass_through as pass_through\nfrom mashumaro.mixins.dict import DataClassDictMixin as DataClassDictMixin\n"
  },
  {
    "path": "third-party-stubs/mashumaro/config.pyi",
    "content": "from mashumaro.core.const import Sentinel\nfrom mashumaro.dialect import Dialect\nfrom mashumaro.types import Discriminator, SerializationStrategy\nfrom typing import Any, Callable, Dict, List, Optional, Type, Union\nfrom typing_extensions import Literal\n\nTO_DICT_ADD_BY_ALIAS_FLAG: str\nTO_DICT_ADD_OMIT_NONE_FLAG: str\nADD_DIALECT_SUPPORT: str\nADD_SERIALIZATION_CONTEXT: str\nSerializationStrategyValueType = Union[SerializationStrategy, Dict[str, Union[str, Callable]]]\n\nclass BaseConfig:\n    debug: bool\n    code_generation_options: List[str]\n    serialization_strategy: Dict[Any, SerializationStrategyValueType]\n    aliases: Dict[str, str]\n    serialize_by_alias: bool\n    namedtuple_as_dict: bool\n    allow_postponed_evaluation: bool\n    dialect: Optional[Type[Dialect]]\n    omit_none: Union[bool, Sentinel.MISSING]\n    orjson_options: Optional[int]\n    json_schema: Dict[str, Any]\n    discriminator: Optional[Discriminator]\n    lazy_compilation: bool\n"
  },
  {
    "path": "third-party-stubs/mashumaro/core/__init__.pyi",
    "content": ""
  },
  {
    "path": "third-party-stubs/mashumaro/core/const.pyi",
    "content": "import enum\nfrom _typeshed import Incomplete\n\nPY_37: Incomplete\nPY_38: Incomplete\nPY_39: Incomplete\nPY_310: Incomplete\nPY_311_MIN: Incomplete\nPY_310_MIN: Incomplete\nPY_39_MIN: Incomplete\nPY_38_MIN: Incomplete\nPY_37_MIN: Incomplete\nPEP_585_COMPATIBLE = PY_39_MIN\nPEP_586_COMPATIBLE = PY_38_MIN\n\nclass Sentinel(enum.Enum):\n    MISSING: Incomplete\n"
  },
  {
    "path": "third-party-stubs/mashumaro/core/helpers.pyi",
    "content": "import datetime\nfrom _typeshed import Incomplete\n\nUTC_OFFSET_PATTERN: str\n\ndef parse_timezone(s: str) -> datetime.timezone: ...\n\nclass ConfigValue:\n    name: Incomplete\n    def __init__(self, name: str) -> None: ...\n"
  },
  {
    "path": "third-party-stubs/mashumaro/core/meta/__init__.pyi",
    "content": ""
  },
  {
    "path": "third-party-stubs/mashumaro/core/meta/code/__init__.pyi",
    "content": ""
  },
  {
    "path": "third-party-stubs/mashumaro/core/meta/code/builder.pyi",
    "content": "import types\nimport typing\nfrom _typeshed import Incomplete\nfrom collections.abc import Generator\nfrom dataclasses import Field\nfrom mashumaro.config import (\n    ADD_DIALECT_SUPPORT as ADD_DIALECT_SUPPORT,\n    ADD_SERIALIZATION_CONTEXT as ADD_SERIALIZATION_CONTEXT,\n    BaseConfig as BaseConfig,\n    SerializationStrategyValueType as SerializationStrategyValueType,\n    TO_DICT_ADD_BY_ALIAS_FLAG as TO_DICT_ADD_BY_ALIAS_FLAG,\n    TO_DICT_ADD_OMIT_NONE_FLAG as TO_DICT_ADD_OMIT_NONE_FLAG,\n)\nfrom mashumaro.core.const import Sentinel as Sentinel\nfrom mashumaro.core.helpers import ConfigValue as ConfigValue\nfrom mashumaro.core.meta.code.lines import CodeLines as CodeLines\nfrom mashumaro.core.meta.helpers import (\n    get_args as get_args,\n    get_class_that_defines_field as get_class_that_defines_field,\n    get_class_that_defines_method as get_class_that_defines_method,\n    get_literal_values as get_literal_values,\n    get_name_error_name as get_name_error_name,\n    hash_type_args as hash_type_args,\n    is_class_var as is_class_var,\n    is_dataclass_dict_mixin as is_dataclass_dict_mixin,\n    is_dialect_subclass as is_dialect_subclass,\n    is_init_var as is_init_var,\n    is_literal as is_literal,\n    is_optional as is_optional,\n    is_type_var_any as is_type_var_any,\n    resolve_type_params as resolve_type_params,\n    substitute_type_params as substitute_type_params,\n    type_name as type_name,\n)\nfrom mashumaro.core.meta.types.common import FieldContext as FieldContext, ValueSpec as ValueSpec\nfrom mashumaro.core.meta.types.pack import PackerRegistry as PackerRegistry\nfrom mashumaro.core.meta.types.unpack import (\n    SubtypeUnpackerBuilder as SubtypeUnpackerBuilder,\n    UnpackerRegistry as UnpackerRegistry,\n)\nfrom mashumaro.dialect import Dialect as Dialect\nfrom mashumaro.exceptions import (\n    BadDialect as BadDialect,\n    BadHookSignature as BadHookSignature,\n    InvalidFieldValue as InvalidFieldValue,\n    MissingDiscriminatorError as MissingDiscriminatorError,\n    MissingField as MissingField,\n    SuitableVariantNotFoundError as SuitableVariantNotFoundError,\n    ThirdPartyModuleNotFoundError as ThirdPartyModuleNotFoundError,\n    UnresolvedTypeReferenceError as UnresolvedTypeReferenceError,\n    UnserializableDataError as UnserializableDataError,\n    UnserializableField as UnserializableField,\n    UnsupportedDeserializationEngine as UnsupportedDeserializationEngine,\n    UnsupportedSerializationEngine as UnsupportedSerializationEngine,\n)\nfrom mashumaro.types import Discriminator as Discriminator\n\n__PRE_SERIALIZE__: str\n__PRE_DESERIALIZE__: str\n__POST_SERIALIZE__: str\n__POST_DESERIALIZE__: str\n\nclass CodeBuilder:\n    cls: Incomplete\n    lines: Incomplete\n    globals: Incomplete\n    resolved_type_params: Incomplete\n    field_classes: Incomplete\n    initial_type_args: Incomplete\n    dialect: Incomplete\n    default_dialect: Incomplete\n    allow_postponed_evaluation: Incomplete\n    format_name: Incomplete\n    decoder: Incomplete\n    encoder: Incomplete\n    encoder_kwargs: Incomplete\n    def __init__(\n        self,\n        cls: typing.Type,\n        type_args: typing.Tuple[typing.Type, ...] = ...,\n        dialect: typing.Optional[typing.Type[Dialect]] = ...,\n        first_method: str = ...,\n        allow_postponed_evaluation: bool = ...,\n        format_name: str = ...,\n        decoder: typing.Optional[typing.Any] = ...,\n        encoder: typing.Optional[typing.Any] = ...,\n        encoder_kwargs: typing.Optional[typing.Dict[str, typing.Any]] = ...,\n        default_dialect: typing.Optional[typing.Type[Dialect]] = ...,\n    ) -> None: ...\n    def reset(self) -> None: ...\n    @property\n    def namespace(self) -> typing.Mapping[typing.Any, typing.Any]: ...\n    @property\n    def annotations(self) -> typing.Dict[str, typing.Any]: ...\n    def get_field_resolved_type_params(\n        self, field_name: str\n    ) -> typing.Dict[typing.Type, typing.Type]: ...\n    def get_field_types(self, include_extras: bool = ...) -> typing.Dict[str, typing.Any]: ...\n    @property\n    def dataclass_fields(self) -> typing.Dict[str, Field]: ...\n    @property\n    def metadatas(self) -> typing.Dict[str, typing.Mapping[str, typing.Any]]: ...\n    def get_field_default(self, name: str) -> typing.Any: ...\n    def add_type_modules(self, *types_: typing.Type) -> None: ...\n    def ensure_module_imported(self, module: types.ModuleType) -> None: ...\n    def ensure_object_imported(\n        self, obj: typing.Any, name: typing.Optional[str] = ...\n    ) -> None: ...\n    def add_line(self, line: str) -> None: ...\n    def indent(self, expr: typing.Optional[str] = ...) -> typing.Generator[None, None, None]: ...\n    def compile(self) -> None: ...\n    def get_declared_hook(self, method_name: str) -> typing.Any: ...\n    def add_unpack_method(self) -> None: ...\n    def get_config(self, cls: Incomplete | None = ..., look_in_parents: bool = ...): ...\n    def get_discriminator(self) -> typing.Optional[Discriminator]: ...\n    def get_pack_method_flags(\n        self, cls: typing.Optional[typing.Type] = ..., pass_encoder: bool = ...\n    ) -> str: ...\n    def get_unpack_method_flags(\n        self, cls: typing.Optional[typing.Type] = ..., pass_decoder: bool = ...\n    ) -> str: ...\n    def get_pack_method_default_flag_values(\n        self, cls: typing.Optional[typing.Type] = ..., pass_encoder: bool = ...\n    ) -> str: ...\n    def get_unpack_method_default_flag_values(self, pass_decoder: bool = ...) -> str: ...\n    def is_code_generation_option_enabled(\n        self, option: str, cls: typing.Optional[typing.Type] = ...\n    ) -> bool: ...\n    @classmethod\n    def get_unpack_method_name(\n        cls,\n        type_args: typing.Iterable = ...,\n        format_name: str = ...,\n        decoder: typing.Optional[typing.Any] = ...,\n    ) -> str: ...\n    @classmethod\n    def get_pack_method_name(\n        cls,\n        type_args: typing.Tuple[typing.Type, ...] = ...,\n        format_name: str = ...,\n        encoder: typing.Optional[typing.Any] = ...,\n    ) -> str: ...\n    def add_pack_method(self) -> None: ...\n    def iter_serialization_strategies(\n        self, metadata, ftype\n    ) -> Generator[Incomplete, None, None]: ...\n"
  },
  {
    "path": "third-party-stubs/mashumaro/core/meta/code/lines.pyi",
    "content": "from typing import Generator, Optional\n\nclass CodeLines:\n    def __init__(self) -> None: ...\n    def append(self, line: str) -> None: ...\n    def indent(self, expr: Optional[str] = ...) -> Generator[None, None, None]: ...\n    def as_text(self) -> str: ...\n    def reset(self) -> None: ...\n"
  },
  {
    "path": "third-party-stubs/mashumaro/core/meta/helpers.pyi",
    "content": "import typing\nfrom typing import Any, Dict, Optional, Sequence, Tuple, Type\n\ndef get_type_origin(typ: Type) -> Type: ...\ndef get_generic_name(typ: Type, short: bool = ...) -> str: ...\ndef get_args(typ: Optional[Type]) -> Tuple[Type, ...]: ...\ndef get_literal_values(typ: Type) -> Tuple[Any, ...]: ...\ndef type_name(\n    typ: Optional[Type],\n    short: bool = ...,\n    resolved_type_params: Optional[Dict[Type, Type]] = ...,\n    is_type_origin: bool = ...,\n    none_type_as_none: bool = ...,\n) -> str: ...\ndef is_special_typing_primitive(typ: Any) -> bool: ...\ndef is_generic(typ: Type) -> bool: ...\ndef is_typed_dict(typ: Type) -> bool: ...\ndef is_named_tuple(typ: Type) -> bool: ...\ndef is_new_type(typ: Type) -> bool: ...\ndef is_union(typ: Type) -> bool: ...\ndef is_optional(typ: Type, resolved_type_params: Optional[Dict[Type, Type]] = ...) -> bool: ...\ndef is_annotated(typ: Type) -> bool: ...\ndef get_type_annotations(typ: Type) -> Sequence[Any]: ...\ndef is_literal(typ: Type) -> bool: ...\ndef not_none_type_arg(\n    type_args: Tuple[Type, ...], resolved_type_params: Optional[Dict[Type, Type]] = ...\n) -> Optional[Type]: ...\ndef is_type_var(typ: Type) -> bool: ...\ndef is_type_var_any(typ: Type) -> bool: ...\ndef is_class_var(typ: Type) -> bool: ...\ndef is_final(typ: Type) -> bool: ...\ndef is_init_var(typ: Type) -> bool: ...\ndef get_class_that_defines_method(method_name: str, cls: Type) -> Optional[Type]: ...\ndef get_class_that_defines_field(field_name: str, cls: Type) -> Optional[Type]: ...\ndef is_dataclass_dict_mixin(typ: Type) -> bool: ...\ndef is_dataclass_dict_mixin_subclass(typ: Type) -> bool: ...\ndef collect_type_params(typ: Type) -> Sequence[Type]: ...\ndef resolve_type_params(\n    typ: Type, type_args: Sequence[Type] = ..., include_bases: bool = ...\n) -> Dict[Type, Dict[Type, Type]]: ...\ndef substitute_type_params(typ: Type, substitutions: Dict[Type, Type]) -> Type: ...\ndef get_name_error_name(e: NameError) -> str: ...\ndef is_dialect_subclass(typ: Type) -> bool: ...\ndef is_self(typ: Type) -> bool: ...\ndef is_required(typ: Type) -> bool: ...\ndef is_not_required(typ: Type) -> bool: ...\ndef get_function_arg_annotation(\n    function: typing.Callable[[Any], Any],\n    arg_name: typing.Optional[str] = ...,\n    arg_pos: typing.Optional[int] = ...,\n) -> typing.Type: ...\ndef get_function_return_annotation(\n    function: typing.Callable[[typing.Any], typing.Any]\n) -> typing.Type: ...\ndef is_unpack(typ: Type) -> bool: ...\ndef is_type_var_tuple(typ: Type) -> bool: ...\ndef hash_type_args(type_args: typing.Iterable[typing.Type]) -> str: ...\ndef iter_all_subclasses(cls) -> typing.Iterator[Type]: ...\n"
  },
  {
    "path": "third-party-stubs/mashumaro/core/meta/mixin.pyi",
    "content": "from mashumaro.dialect import Dialect\nfrom typing import Any, Dict, Optional, Tuple, Type\n\ndef compile_mixin_packer(\n    cls,\n    format_name: str = ...,\n    dialect: Optional[Type[Dialect]] = ...,\n    encoder: Any = ...,\n    encoder_kwargs: Optional[Dict[str, Dict[str, Tuple[str, Any]]]] = ...,\n) -> None: ...\ndef compile_mixin_unpacker(\n    cls, format_name: str = ..., dialect: Optional[Type[Dialect]] = ..., decoder: Any = ...\n) -> None: ...\n"
  },
  {
    "path": "third-party-stubs/mashumaro/core/meta/types/__init__.pyi",
    "content": ""
  },
  {
    "path": "third-party-stubs/mashumaro/core/meta/types/common.pyi",
    "content": "from _typeshed import Incomplete\nfrom functools import cached_property\nfrom mashumaro.core.const import PEP_585_COMPATIBLE as PEP_585_COMPATIBLE\nfrom mashumaro.core.meta.code.builder import CodeBuilder as CodeBuilder\nfrom mashumaro.core.meta.helpers import (\n    get_type_origin as get_type_origin,\n    is_annotated as is_annotated,\n    is_generic as is_generic,\n    type_name as type_name,\n)\nfrom mashumaro.exceptions import (\n    UnserializableDataError as UnserializableDataError,\n    UnserializableField as UnserializableField,\n)\nfrom typing import Any, Dict, Mapping, Optional, Sequence, Type, TypeVar\nfrom typing_extensions import TypeAlias\n\ncached_property = property\nNoneType: Incomplete\nExpression: TypeAlias\nP: Incomplete\nT = TypeVar(\"T\")\n\nclass ExpressionWrapper:\n    expression: Incomplete\n    def __init__(self, expression: str) -> None: ...\n\nPROPER_COLLECTION_TYPES: Dict[Type, str]\n\nclass FieldContext:\n    name: str\n    metadata: Mapping\n    def copy(self, **changes: Any) -> FieldContext: ...\n    def __init__(self, name, metadata) -> None: ...\n\nclass ValueSpec:\n    type: Type\n    origin_type: Type\n    expression: Expression\n    builder: CodeBuilder\n    field_ctx: FieldContext\n    could_be_none: bool\n    annotated_type: Optional[Type]\n    def __setattr__(self, key: str, value: Any) -> None: ...\n    def copy(self, **changes: Any) -> ValueSpec: ...\n    @cached_property\n    def annotations(self) -> Sequence[str]: ...\n    def __init__(\n        self, type, expression, builder, field_ctx, could_be_none, annotated_type\n    ) -> None: ...\n\nValueSpecExprCreator: TypeAlias\n\nclass Registry:\n    def register(self, function: ValueSpecExprCreator) -> ValueSpecExprCreator: ...\n    def get(self, spec: ValueSpec) -> Expression: ...\n    def __init__(self, _registry) -> None: ...\n\ndef ensure_generic_collection(spec: ValueSpec) -> bool: ...\ndef ensure_collection_type_args_supported(\n    collection_type: Type, type_args: Sequence[Type]\n) -> bool: ...\ndef ensure_generic_collection_subclass(spec: ValueSpec, *checked_types: Type) -> bool: ...\ndef ensure_generic_mapping(spec: ValueSpec, args: Sequence[Type], checked_type: Type) -> bool: ...\ndef expr_or_maybe_none(spec: ValueSpec, new_expr: Expression) -> Expression: ...\ndef random_hex() -> str: ...\ndef clean_id(value: str) -> str: ...\n"
  },
  {
    "path": "third-party-stubs/mashumaro/core/meta/types/pack.pyi",
    "content": "from _typeshed import Incomplete\n\nPackerRegistry: Incomplete\n"
  },
  {
    "path": "third-party-stubs/mashumaro/core/meta/types/unpack.pyi",
    "content": "import abc\nfrom _typeshed import Incomplete\nfrom abc import ABC, abstractmethod\nfrom mashumaro.core.meta.types.common import ValueSpec\nfrom mashumaro.types import Discriminator\nfrom typing import Optional, Tuple, Type\n\nUnpackerRegistry: Incomplete\n\nclass AbstractUnpackerBuilder(ABC, metaclass=abc.ABCMeta):\n    @abstractmethod\n    def get_method_prefix(self) -> str: ...\n    def build(self, spec: ValueSpec) -> str: ...\n\nclass UnionUnpackerBuilder(AbstractUnpackerBuilder):\n    union_args: Incomplete\n    def __init__(self, args: Tuple[Type, ...]) -> None: ...\n    def get_method_prefix(self) -> str: ...\n\nclass TypeVarUnpackerBuilder(UnionUnpackerBuilder):\n    def get_method_prefix(self) -> str: ...\n\nclass LiteralUnpackerBuilder(AbstractUnpackerBuilder):\n    def get_method_prefix(self) -> str: ...\n\nclass DiscriminatedUnionUnpackerBuilder(AbstractUnpackerBuilder):\n    discriminator: Incomplete\n    base_variants: Incomplete\n    def __init__(\n        self, discriminator: Discriminator, base_variants: Optional[Tuple[Type, ...]] = ...\n    ) -> None: ...\n    def get_method_prefix(self) -> str: ...\n\nclass SubtypeUnpackerBuilder(DiscriminatedUnionUnpackerBuilder): ...\n"
  },
  {
    "path": "third-party-stubs/mashumaro/dialect.pyi",
    "content": "from mashumaro.core.const import Sentinel\nfrom mashumaro.types import SerializationStrategy\nfrom typing import Callable, Dict, Union\nfrom typing_extensions import Literal\n\nSerializationStrategyValueType = Union[SerializationStrategy, Dict[str, Union[str, Callable]]]\n\nclass Dialect:\n    serialization_strategy: Dict[str, SerializationStrategyValueType]\n    omit_none: Union[bool, Sentinel.MISSING]\n"
  },
  {
    "path": "third-party-stubs/mashumaro/exceptions.pyi",
    "content": "from _typeshed import Incomplete\nfrom mashumaro.core.meta.helpers import type_name as type_name\nfrom typing import Any, Optional, Type\n\nclass MissingField(LookupError):\n    field_name: Incomplete\n    field_type: Incomplete\n    holder_class: Incomplete\n    def __init__(self, field_name: str, field_type: Type, holder_class: Type) -> None: ...\n    @property\n    def field_type_name(self) -> str: ...\n    @property\n    def holder_class_name(self) -> str: ...\n\nclass UnserializableDataError(TypeError): ...\n\nclass UnserializableField(UnserializableDataError):\n    field_name: Incomplete\n    field_type: Incomplete\n    holder_class: Incomplete\n    msg: Incomplete\n    def __init__(\n        self, field_name: str, field_type: Type, holder_class: Type, msg: Optional[str] = ...\n    ) -> None: ...\n    @property\n    def field_type_name(self) -> str: ...\n    @property\n    def holder_class_name(self) -> str: ...\n\nclass UnsupportedSerializationEngine(UnserializableField):\n    def __init__(\n        self, field_name: str, field_type: Type, holder_class: Type, engine: Any\n    ) -> None: ...\n\nclass UnsupportedDeserializationEngine(UnserializableField):\n    def __init__(\n        self, field_name: str, field_type: Type, holder_class: Type, engine: Any\n    ) -> None: ...\n\nclass InvalidFieldValue(ValueError):\n    field_name: Incomplete\n    field_type: Incomplete\n    field_value: Incomplete\n    holder_class: Incomplete\n    msg: Incomplete\n    def __init__(\n        self,\n        field_name: str,\n        field_type: Type,\n        field_value: Any,\n        holder_class: Type,\n        msg: Optional[str] = ...,\n    ) -> None: ...\n    @property\n    def field_type_name(self) -> str: ...\n    @property\n    def holder_class_name(self) -> str: ...\n\nclass MissingDiscriminatorError(LookupError):\n    field_name: Incomplete\n    def __init__(self, field_name: str) -> None: ...\n\nclass SuitableVariantNotFoundError(ValueError):\n    variants_type: Incomplete\n    discriminator_name: Incomplete\n    discriminator_value: Incomplete\n    def __init__(\n        self,\n        variants_type: Type,\n        discriminator_name: Optional[str] = ...,\n        discriminator_value: Any = ...,\n    ) -> None: ...\n\nclass BadHookSignature(TypeError): ...\n\nclass ThirdPartyModuleNotFoundError(ModuleNotFoundError):\n    module_name: Incomplete\n    field_name: Incomplete\n    holder_class: Incomplete\n    def __init__(self, module_name: str, field_name: str, holder_class: Type) -> None: ...\n    @property\n    def holder_class_name(self) -> str: ...\n\nclass UnresolvedTypeReferenceError(NameError):\n    holder_class: Incomplete\n    name: Incomplete\n    def __init__(self, holder_class: Type, unresolved_type_name: str) -> None: ...\n    @property\n    def holder_class_name(self) -> str: ...\n\nclass BadDialect(ValueError): ...\n"
  },
  {
    "path": "third-party-stubs/mashumaro/helper.pyi",
    "content": "from mashumaro.types import SerializationStrategy\nfrom typing import Any, Callable, Dict, Optional, TypeVar, Union\nfrom typing_extensions import Literal\n\nNamedTupleDeserializationEngine = Literal[\"as_dict\", \"as_list\"]\nDateTimeDeserializationEngine = Literal[\"ciso8601\", \"pendulum\"]\nAnyDeserializationEngine = Literal[NamedTupleDeserializationEngine, DateTimeDeserializationEngine]\n\nNamedTupleSerializationEngine = Literal[\"as_dict\", \"as_list\"]\nAnySerializationEngine = Union[NamedTupleSerializationEngine, OmitSerializationEngine]\nOmitSerializationEngine = Literal[\"omit\"]\n\nT = TypeVar(\"T\")\n\ndef field_options(\n    serialize: Optional[Union[AnySerializationEngine, Callable[[Any], Any]]] = ...,\n    deserialize: Optional[Union[AnyDeserializationEngine, Callable[[Any], Any]]] = ...,\n    serialization_strategy: Optional[SerializationStrategy] = ...,\n    alias: Optional[str] = ...,\n) -> Dict[str, Any]: ...\n\nclass _PassThrough(SerializationStrategy):\n    def __call__(self, *args: Any, **kwargs: Any) -> Any: ...\n    def serialize(self, value: T) -> T: ...\n    def deserialize(self, value: T) -> T: ...\n\npass_through: Any\n"
  },
  {
    "path": "third-party-stubs/mashumaro/jsonschema/__init__.pyi",
    "content": "from .builder import JSONSchemaBuilder as JSONSchemaBuilder, build_json_schema as build_json_schema\nfrom .dialects import DRAFT_2020_12 as DRAFT_2020_12, OPEN_API_3_1 as OPEN_API_3_1\n"
  },
  {
    "path": "third-party-stubs/mashumaro/jsonschema/annotations.pyi",
    "content": "from mashumaro.jsonschema.models import JSONSchema, Number\nfrom typing import Dict, Set\n\nclass Annotation: ...\nclass Constraint(Annotation): ...\nclass NumberConstraint(Constraint): ...\n\nclass Minimum(NumberConstraint):\n    value: Number\n    def __init__(self, value) -> None: ...\n\nclass Maximum(NumberConstraint):\n    value: Number\n    def __init__(self, value) -> None: ...\n\nclass ExclusiveMinimum(NumberConstraint):\n    value: Number\n    def __init__(self, value) -> None: ...\n\nclass ExclusiveMaximum(NumberConstraint):\n    value: Number\n    def __init__(self, value) -> None: ...\n\nclass MultipleOf(NumberConstraint):\n    value: Number\n    def __init__(self, value) -> None: ...\n\nclass StringConstraint(Constraint): ...\n\nclass MinLength(StringConstraint):\n    value: int\n    def __init__(self, value) -> None: ...\n\nclass MaxLength(StringConstraint):\n    value: int\n    def __init__(self, value) -> None: ...\n\nclass Pattern(StringConstraint):\n    value: str\n    def __init__(self, value) -> None: ...\n\nclass ArrayConstraint(Constraint): ...\n\nclass MinItems(ArrayConstraint):\n    value: int\n    def __init__(self, value) -> None: ...\n\nclass MaxItems(ArrayConstraint):\n    value: int\n    def __init__(self, value) -> None: ...\n\nclass UniqueItems(ArrayConstraint):\n    value: bool\n    def __init__(self, value) -> None: ...\n\nclass Contains(ArrayConstraint):\n    value: JSONSchema\n    def __init__(self, value) -> None: ...\n\nclass MinContains(ArrayConstraint):\n    value: int\n    def __init__(self, value) -> None: ...\n\nclass MaxContains(ArrayConstraint):\n    value: int\n    def __init__(self, value) -> None: ...\n\nclass ObjectConstraint(Constraint): ...\n\nclass MaxProperties(ObjectConstraint):\n    value: int\n    def __init__(self, value) -> None: ...\n\nclass MinProperties(ObjectConstraint):\n    value: int\n    def __init__(self, value) -> None: ...\n\nclass DependentRequired(ObjectConstraint):\n    value: Dict[str, Set[str]]\n    def __init__(self, value) -> None: ...\n"
  },
  {
    "path": "third-party-stubs/mashumaro/jsonschema/builder.pyi",
    "content": "from _typeshed import Incomplete\nfrom mashumaro.jsonschema.dialects import JSONSchemaDialect\nfrom mashumaro.jsonschema.models import Context, JSONSchema\nfrom mashumaro.mixins.json import DataClassJSONMixin\nfrom typing import Any, Dict, List, Optional, Type\n\ndef build_json_schema(\n    instance_type: Type,\n    context: Optional[Context] = ...,\n    with_definitions: bool = ...,\n    all_refs: Optional[bool] = ...,\n    with_dialect_uri: bool = ...,\n    dialect: Optional[JSONSchemaDialect] = ...,\n    ref_prefix: Optional[str] = ...,\n) -> JSONSchema: ...\n\nclass JSONSchemaDefinitions(DataClassJSONMixin):\n    definitions: Dict[str, JSONSchema]\n    def __post_serialize__(self, d: Dict[Any, Any], context: Optional[Dict]) -> List[Dict[str, Any]]: ...  # type: ignore\n    def __init__(self, definitions) -> None: ...\n\nclass JSONSchemaBuilder:\n    context: Incomplete\n    def __init__(\n        self,\n        dialect: JSONSchemaDialect = ...,\n        all_refs: Optional[bool] = ...,\n        ref_prefix: Optional[str] = ...,\n    ) -> None: ...\n    def build(self, instance_type: Type) -> JSONSchema: ...\n    def get_definitions(self) -> JSONSchemaDefinitions: ...\n"
  },
  {
    "path": "third-party-stubs/mashumaro/jsonschema/dialects.pyi",
    "content": "from _typeshed import Incomplete\n\nclass JSONSchemaDialect:\n    uri: str\n    definitions_root_pointer: str\n    all_refs: bool\n    def __init__(self, uri, definitions_root_pointer, all_refs) -> None: ...\n\nclass JSONSchemaDraft202012Dialect(JSONSchemaDialect):\n    uri: str\n    definitions_root_pointer: str\n    all_refs: bool\n    def __init__(self, uri, definitions_root_pointer, all_refs) -> None: ...\n\nclass OpenAPISchema31Dialect(JSONSchemaDialect):\n    uri: str\n    definitions_root_pointer: str\n    all_refs: bool\n    def __init__(self, uri, definitions_root_pointer, all_refs) -> None: ...\n\nDRAFT_2020_12: Incomplete\nOPEN_API_3_1: Incomplete\n"
  },
  {
    "path": "third-party-stubs/mashumaro/jsonschema/models.pyi",
    "content": "from _typeshed import Incomplete\nfrom enum import Enum\nfrom mashumaro.config import BaseConfig as BaseConfig\nfrom mashumaro.helper import pass_through as pass_through\nfrom mashumaro.jsonschema.dialects import (\n    DRAFT_2020_12 as DRAFT_2020_12,\n    JSONSchemaDialect as JSONSchemaDialect,\n)\nfrom mashumaro.mixins.json import DataClassJSONMixin as DataClassJSONMixin\nfrom typing import Any, Dict, List, Optional, Set, Union\nfrom typing_extensions import TypeAlias\n\nNumber: TypeAlias = Union[int, float]\nNull = object()\n\nclass JSONSchemaInstanceType(Enum):\n    NULL: str\n    BOOLEAN: str\n    OBJECT: str\n    ARRAY: str\n    NUMBER: str\n    STRING: str\n    INTEGER: str\n\nclass JSONSchemaInstanceFormat(Enum): ...\n\nclass JSONSchemaStringFormat(JSONSchemaInstanceFormat):\n    DATETIME: str\n    DATE: str\n    TIME: str\n    DURATION: str\n    EMAIL: str\n    IDN_EMAIL: str\n    HOSTNAME: str\n    IDN_HOSTNAME: str\n    IPV4ADDRESS: str\n    IPV6ADDRESS: str\n    URI: str\n    URI_REFERENCE: str\n    IRI: str\n    IRI_REFERENCE: str\n    UUID: str\n    URI_TEMPLATE: str\n    JSON_POINTER: str\n    RELATIVE_JSON_POINTER: str\n    REGEX: str\n\nclass JSONSchemaInstanceFormatExtension(JSONSchemaInstanceFormat):\n    TIMEDELTA: str\n    TIME_ZONE: str\n    IPV4NETWORK: str\n    IPV6NETWORK: str\n    IPV4INTERFACE: str\n    IPV6INTERFACE: str\n    DECIMAL: str\n    FRACTION: str\n    BASE64: str\n    PATH: str\n\nDATETIME_FORMATS: Incomplete\nIPADDRESS_FORMATS: Incomplete\n\nclass JSONSchema(DataClassJSONMixin):\n    schema: Optional[str]\n    type: Optional[JSONSchemaInstanceType]\n    enum: Optional[List[Any]]\n    const: Optional[Any]\n    format: Optional[\n        Union[JSONSchemaInstanceFormat, JSONSchemaStringFormat, JSONSchemaInstanceFormatExtension]\n    ]\n    title: Optional[str]\n    description: Optional[str]\n    anyOf: Optional[List[\"JSONSchema\"]]\n    reference: Optional[str]\n    definitions: Optional[Dict[str, \"JSONSchema\"]]\n    default: Optional[Any]\n    deprecated: Optional[bool]\n    examples: Optional[List[Any]]\n    properties: Optional[Dict[str, \"JSONSchema\"]]\n    patternProperties: Optional[Dict[str, \"JSONSchema\"]]\n    additionalProperties: Union[\"JSONSchema\", bool, None]\n    propertyNames: Optional[\"JSONSchema\"]\n    prefixItems: Optional[List[\"JSONSchema\"]]\n    items: Optional[\"JSONSchema\"]\n    contains: Optional[\"JSONSchema\"]\n    multipleOf: Optional[Number]\n    maximum: Optional[Number]\n    exclusiveMaximum: Optional[Number]\n    minimum: Optional[Number]\n    exclusiveMinimum: Optional[Number]\n    maxLength: Optional[int]\n    minLength: Optional[int]\n    pattern: Optional[str]\n    maxItems: Optional[int]\n    minItems: Optional[int]\n    uniqueItems: Optional[bool]\n    maxContains: Optional[int]\n    minContains: Optional[int]\n    maxProperties: Optional[int]\n    minProperties: Optional[int]\n    required: Optional[List[str]]\n    dependentRequired: Optional[Dict[str, Set[str]]]\n\n    class Config(BaseConfig):\n        omit_none: bool\n        serialize_by_alias: bool\n        aliases: Incomplete\n        serialization_strategy: Incomplete\n\n    def __pre_serialize__(self, context: Optional[Dict]) -> JSONSchema: ...\n    def __post_serialize__(self, d: Dict[Any, Any], context: Optional[Dict]) -> Dict[Any, Any]: ...\n    def __init__(\n        self,\n        schema,\n        type,\n        enum,\n        const,\n        format,\n        title,\n        description,\n        anyOf,\n        reference,\n        definitions,\n        default,\n        deprecated,\n        examples,\n        properties,\n        patternProperties,\n        additionalProperties,\n        propertyNames,\n        prefixItems,\n        items,\n        contains,\n        multipleOf,\n        maximum,\n        exclusiveMaximum,\n        minimum,\n        exclusiveMinimum,\n        maxLength,\n        minLength,\n        pattern,\n        maxItems,\n        minItems,\n        uniqueItems,\n        maxContains,\n        minContains,\n        maxProperties,\n        minProperties,\n        required,\n        dependentRequired,\n    ) -> None: ...\n\nclass JSONObjectSchema(JSONSchema):\n    type: JSONSchemaInstanceType\n    def __init__(\n        self,\n        schema,\n        type,\n        enum,\n        const,\n        format,\n        title,\n        description,\n        anyOf,\n        reference,\n        definitions,\n        default,\n        deprecated,\n        examples,\n        properties,\n        patternProperties,\n        additionalProperties,\n        propertyNames,\n        prefixItems,\n        items,\n        contains,\n        multipleOf,\n        maximum,\n        exclusiveMaximum,\n        minimum,\n        exclusiveMinimum,\n        maxLength,\n        minLength,\n        pattern,\n        maxItems,\n        minItems,\n        uniqueItems,\n        maxContains,\n        minContains,\n        maxProperties,\n        minProperties,\n        required,\n        dependentRequired,\n    ) -> None: ...\n\nclass JSONArraySchema(JSONSchema):\n    type: JSONSchemaInstanceType\n    def __init__(\n        self,\n        schema,\n        type,\n        enum,\n        const,\n        format,\n        title,\n        description,\n        anyOf,\n        reference,\n        definitions,\n        default,\n        deprecated,\n        examples,\n        properties,\n        patternProperties,\n        additionalProperties,\n        propertyNames,\n        prefixItems,\n        items,\n        contains,\n        multipleOf,\n        maximum,\n        exclusiveMaximum,\n        minimum,\n        exclusiveMinimum,\n        maxLength,\n        minLength,\n        pattern,\n        maxItems,\n        minItems,\n        uniqueItems,\n        maxContains,\n        minContains,\n        maxProperties,\n        minProperties,\n        required,\n        dependentRequired,\n    ) -> None: ...\n\nclass Context:\n    dialect: JSONSchemaDialect\n    definitions: Dict[str, JSONSchema]\n    all_refs: Optional[bool]\n    ref_prefix: Optional[str]\n    def __init__(self, dialect, definitions, all_refs, ref_prefix) -> None: ...\n"
  },
  {
    "path": "third-party-stubs/mashumaro/jsonschema/schema.pyi",
    "content": "from mashumaro.config import BaseConfig\nfrom mashumaro.jsonschema.annotations import Annotation\nfrom mashumaro.jsonschema.models import Context, JSONSchema\nfrom typing import Any, Callable, Iterable, List, Mapping, Optional, Tuple, Type, Union\n\nclass Instance:\n    type: Type\n    name: Optional[str]\n    origin_type: Type\n    annotations: List[Annotation]\n    @property\n    def metadata(self) -> Mapping[str, Any]: ...\n    @property\n    def alias(self) -> Optional[str]: ...\n    @property\n    def holder_class(self) -> Optional[Type]: ...\n    def copy(self, **changes: Any) -> Instance: ...\n    def __post_init__(self) -> None: ...\n    def update_type(self, new_type: Type) -> None: ...\n    def fields(self) -> Iterable[Tuple[str, Type, bool, Any]]: ...\n    def get_overridden_serialization_method(self) -> Optional[Union[Callable, str]]: ...\n    def get_config(self) -> Type[BaseConfig]: ...\n    def __init__(self, type, name, __builder) -> None: ...\n\nclass InstanceSchemaCreatorRegistry:\n    def register(self, func: InstanceSchemaCreator) -> InstanceSchemaCreator: ...\n    def iter(self) -> Iterable[InstanceSchemaCreator]: ...\n    def __init__(self, _registry) -> None: ...\n\nclass EmptyJSONSchema(JSONSchema):\n    def __init__(\n        self,\n        schema,\n        type,\n        enum,\n        const,\n        format,\n        title,\n        description,\n        anyOf,\n        reference,\n        definitions,\n        default,\n        deprecated,\n        examples,\n        properties,\n        patternProperties,\n        additionalProperties,\n        propertyNames,\n        prefixItems,\n        items,\n        contains,\n        multipleOf,\n        maximum,\n        exclusiveMaximum,\n        minimum,\n        exclusiveMinimum,\n        maxLength,\n        minLength,\n        pattern,\n        maxItems,\n        minItems,\n        uniqueItems,\n        maxContains,\n        minContains,\n        maxProperties,\n        minProperties,\n        required,\n        dependentRequired,\n    ) -> None: ...\n\ndef get_schema(instance: Instance, ctx: Context, with_dialect_uri: bool = ...) -> JSONSchema: ...\n"
  },
  {
    "path": "third-party-stubs/mashumaro/mixins/__init__.pyi",
    "content": ""
  },
  {
    "path": "third-party-stubs/mashumaro/mixins/dict.pyi",
    "content": "from typing import Any, Dict, Mapping, Type, TypeVar, Optional\n\nT = TypeVar(\"T\", bound=\"DataClassDictMixin\")\n\nclass DataClassDictMixin:\n    def __init_subclass__(cls: Type[T], **kwargs: Any) -> None: ...\n    def to_dict(self, **kwargs: Any) -> dict: ...\n    @classmethod\n    def from_dict(cls, d: Mapping, **kwargs: Any) -> Any: ...\n    @classmethod\n    def __pre_deserialize__(cls: Type[T], d: Dict[Any, Any]) -> Dict[Any, Any]: ...\n    @classmethod\n    def __post_deserialize__(cls: Type[T], obj: T) -> T: ...\n    def __pre_serialize__(self: T, context: Optional[Dict]) -> T: ...\n    def __post_serialize__(self, d: Dict[Any, Any], context: Optional[Dict]) -> Dict[Any, Any]: ...\n"
  },
  {
    "path": "third-party-stubs/mashumaro/mixins/json.pyi",
    "content": "from mashumaro.mixins.dict import DataClassDictMixin as DataClassDictMixin\nfrom typing import Any, Callable, Dict, TypeVar, Union, Type\n\nEncodedData = Union[str, bytes, bytearray]\nT = TypeVar(\"T\", bound=\"DataClassJSONMixin\")\n\nclass Encoder:\n    def __call__(self, obj: Any, **kwargs: Any) -> EncodedData: ...\n\nclass Decoder:\n    def __call__(self, s: EncodedData, **kwargs: Any) -> Dict[Any, Any]: ...\n\nclass DataClassJSONMixin(DataClassDictMixin):\n    def to_json(self, encoder: Encoder = ..., **to_dict_kwargs: Any) -> EncodedData: ...\n    @classmethod\n    def from_json(\n        cls: Type[T], data: EncodedData, decoder: Decoder = ..., **from_dict_kwargs: Any\n    ) -> T: ...\n"
  },
  {
    "path": "third-party-stubs/mashumaro/mixins/msgpack.pyi",
    "content": "from _typeshed import Incomplete\nfrom mashumaro.dialect import Dialect as Dialect\nfrom mashumaro.helper import pass_through as pass_through\nfrom mashumaro.mixins.dict import DataClassDictMixin as DataClassDictMixin\nfrom typing import Any, Callable, Dict, TypeVar, Type\n\nT = TypeVar(\"T\", bound=\"DataClassMessagePackMixin\")\nEncodedData = bytes\nEncoder = Callable[[Any], EncodedData]\nDecoder = Callable[[EncodedData], Dict[Any, Any]]\n\nclass MessagePackDialect(Dialect):\n    serialization_strategy: Incomplete\n\ndef default_encoder(data: Any) -> EncodedData: ...\ndef default_decoder(data: EncodedData) -> Dict[Any, Any]: ...\n\nclass DataClassMessagePackMixin(DataClassDictMixin):\n    def to_msgpack(self, encoder: Encoder = ..., **to_dict_kwargs: Any) -> EncodedData: ...\n    @classmethod\n    def from_msgpack(\n        cls: Type[T], data: EncodedData, decoder: Decoder = ..., **from_dict_kwargs: Any\n    ) -> T: ...\n"
  },
  {
    "path": "third-party-stubs/mashumaro/mixins/orjson.pyi",
    "content": "from mashumaro.dialect import Dialect as Dialect\nfrom mashumaro.mixins.dict import DataClassDictMixin as DataClassDictMixin\nfrom typing import Any, Callable, Dict, TypeVar, Union\n\nT = TypeVar(\"T\", bound=\"DataClassORJSONMixin\")\nEncodedData = Union[str, bytes, bytearray]\nEncoder = Callable[[Any], EncodedData]\nDecoder = Callable[[EncodedData], Dict[Any, Any]]\n\nclass OrjsonDialect(Dialect):\n    serialization_strategy: Any\n\nclass DataClassORJSONMixin(DataClassDictMixin):\n    def to_jsonb(\n        self, encoder: Encoder = ..., *, orjson_options: int = ..., **to_dict_kwargs: Any\n    ) -> bytes: ...\n    def to_json(\n        self, encoder: Encoder = ..., *, orjson_options: int = ..., **to_dict_kwargs: Any\n    ) -> bytes: ...\n    @classmethod\n    def from_json(\n        cls, data: EncodedData, decoder: Decoder = ..., **from_dict_kwargs: Any\n    ) -> T: ...\n"
  },
  {
    "path": "third-party-stubs/mashumaro/mixins/toml.pyi",
    "content": "from _typeshed import Incomplete\nfrom mashumaro.dialect import Dialect as Dialect\nfrom mashumaro.helper import pass_through as pass_through\nfrom mashumaro.mixins.dict import DataClassDictMixin as DataClassDictMixin\nfrom typing import Any, Callable, Dict, TypeVar\n\nT = TypeVar(\"T\", bound=\"DataClassTOMLMixin\")\nEncodedData = str\nEncoder = Callable[[Any], EncodedData]\nDecoder = Callable[[EncodedData], Dict[Any, Any]]\n\nclass TOMLDialect(Dialect):\n    omit_none: bool\n    serialization_strategy: Incomplete\n\nclass DataClassTOMLMixin(DataClassDictMixin):\n    def to_toml(self, encoder: Encoder = ..., **to_dict_kwargs: Any) -> EncodedData: ...\n    @classmethod\n    def from_toml(\n        cls, data: EncodedData, decoder: Decoder = ..., **from_dict_kwargs: Any\n    ) -> T: ...\n"
  },
  {
    "path": "third-party-stubs/mashumaro/mixins/yaml.pyi",
    "content": "from _typeshed import Incomplete\nfrom mashumaro.mixins.dict import DataClassDictMixin as DataClassDictMixin\nfrom typing import Any, Callable, Dict, TypeVar, Union\n\nT = TypeVar(\"T\", bound=\"DataClassYAMLMixin\")\nEncodedData = Union[str, bytes]\nEncoder = Callable[[Any], EncodedData]\nDecoder = Callable[[EncodedData], Dict[Any, Any]]\nDefaultLoader: Incomplete\nDefaultDumper: Incomplete\n\ndef default_encoder(data: Any) -> EncodedData: ...\ndef default_decoder(data: EncodedData) -> Dict[Any, Any]: ...\n\nclass DataClassYAMLMixin(DataClassDictMixin):\n    def to_yaml(self, encoder: Encoder = ..., **to_dict_kwargs: Any) -> EncodedData: ...\n    @classmethod\n    def from_yaml(\n        cls, data: EncodedData, decoder: Decoder = ..., **from_dict_kwargs: Any\n    ) -> T: ...\n"
  },
  {
    "path": "third-party-stubs/mashumaro/types.pyi",
    "content": "import decimal\nfrom _typeshed import Incomplete\nfrom mashumaro.core.const import Sentinel\nfrom typing import Any, Optional, Union\nfrom typing_extensions import Literal\n\nclass SerializableType: ...\nclass GenericSerializableType: ...\n\nclass SerializationStrategy:\n    def serialize(self, value: Any) -> Any: ...\n    def deserialize(self, value: Any) -> Any: ...\n\nclass RoundedDecimal(SerializationStrategy):\n    exp: Incomplete\n    rounding: Incomplete\n    def __init__(self, places: Optional[int] = ..., rounding: Optional[str] = ...) -> None: ...\n    def serialize(self, value: decimal.Decimal) -> str: ...\n    def deserialize(self, value: str) -> decimal.Decimal: ...\n\nclass Discriminator:\n    field: Optional[str]\n    include_supertypes: bool\n    include_subtypes: bool\n    def __post_init__(self) -> None: ...\n    def __init__(self, field, include_supertypes, include_subtypes) -> None: ...\n"
  },
  {
    "path": "third-party-stubs/msgpack/__init__.pyi",
    "content": "from __future__ import annotations\nfrom typing import Any, Callable, Dict, List, Optional, Tuple\nfrom msgpack.exceptions import (\n    BufferFull,\n    ExtraData,\n    FormatError,\n    OutOfData,\n    PackException,\n    PackOverflowError,\n    PackValueError,\n    StackError,\n    UnpackException,\n    UnpackValueError,\n)\nfrom typing_extensions import Protocol\nfrom msgpack.fallback import Packer, Unpacker, unpackb\nfrom msgpack import exceptions\nfrom msgpack.ext import ExtType\nfrom msgpack import ext\n\nclass _Stream(Protocol):\n    def read(self) -> bytes: ...\n\nclass _FileLike(Protocol):\n    def read(self, n: int) -> bytes: ...\n\ndef pack(\n    o: Any,\n    stream: _Stream,\n    default: Optional[Callable[[Any], Any]] = ...,\n    use_single_float: bool = ...,\n    autoreset: bool = ...,\n    use_bin_type: bool = ...,\n    strict_types: bool = ...,\n    datetime: bool = ...,\n    unicode_errors: Optional[str] = ...,\n) -> None: ...\ndef packb(\n    o: Any,\n    default: Optional[Callable[[Any], Any]] = ...,\n    use_single_float: bool = ...,\n    autoreset: bool = ...,\n    use_bin_type: bool = ...,\n    strict_types: bool = ...,\n    datetime: bool = ...,\n    unicode_errors: Optional[str] = ...,\n) -> bytes: ...\ndef unpack(\n    stream: _Stream,\n    file_like: Optional[_FileLike] = ...,\n    read_size: int = ...,\n    use_list: bool = ...,\n    raw: bool = ...,\n    timestamp: int = ...,\n    strict_map_key: bool = ...,\n    object_hook: Optional[Callable[[Dict[Any, Any]], Any]] = ...,\n    object_pairs_hook: Optional[Callable[[List[Tuple[Any, Any]]], Any]] = ...,\n    list_hook: Optional[Callable[[List[Any]], Any]] = ...,\n    unicode_errors: Optional[str] = ...,\n    max_buffer_size: int = ...,\n    ext_hook: Callable[[int, bytes], Any] = ...,\n    max_str_len: int = ...,\n    max_bin_len: int = ...,\n    max_array_len: int = ...,\n    max_map_len: int = ...,\n    max_ext_len: int = ...,\n) -> Any: ...\n\nload = unpack\nloads = unpackb\n\ndump = pack\ndumps = packb\n\n__all__ = [\n    \"BufferFull\",\n    \"ExtType\",\n    \"ExtraData\",\n    \"FormatError\",\n    \"OutOfData\",\n    \"PackException\",\n    \"PackOverflowError\",\n    \"PackValueError\",\n    \"Packer\",\n    \"StackError\",\n    \"UnpackException\",\n    \"UnpackValueError\",\n    \"Unpacker\",\n    \"dump\",\n    \"dumps\",\n    \"exceptions\",\n    \"ext\",\n    \"load\",\n    \"loads\",\n    \"pack\",\n    \"packb\",\n    \"unpack\",\n    \"unpackb\",\n]\n"
  },
  {
    "path": "third-party-stubs/msgpack/_version.pyi",
    "content": "from typing import Tuple\n\nversion: Tuple[int, int, int]\n"
  },
  {
    "path": "third-party-stubs/msgpack/exceptions.pyi",
    "content": "from typing import Any\n\nclass UnpackException(Exception): ...\nclass BufferFull(UnpackException): ...\nclass OutOfData(UnpackException): ...\nclass FormatError(ValueError, UnpackException): ...\nclass StackError(ValueError, UnpackException): ...\n\nUnpackValueError = ValueError\n\nclass ExtraData(UnpackValueError):\n    def __init__(self, unpacked: Any, exta: Any) -> None: ...\n\nPackException = Exception\nPackValueError = ValueError\nPackOverflowError = OverflowError\n"
  },
  {
    "path": "third-party-stubs/msgpack/ext.pyi",
    "content": "from __future__ import annotations\nfrom typing import NamedTuple\nimport datetime\n\nclass _ExtType(NamedTuple):\n    code: int\n    data: bytes\n\nclass ExtType(_ExtType): ...\n\nclass TimeStamp:\n    def __init__(self, seconds: int, nanoseconds: int = ...) -> None: ...\n    def __eq__(self, o: object) -> bool: ...\n    def __ne__(self, o: object) -> bool: ...\n    @staticmethod\n    def from_bytes(b: bytes) -> TimeStamp: ...\n    @staticmethod\n    def to_bytes(self) -> bytes: ...\n    @staticmethod\n    def from_unix(self, unix_sec: float) -> TimeStamp: ...\n    def to_unix(self) -> float: ...\n    @staticmethod\n    def from_unix_nano(unix_ns: int) -> TimeStamp: ...\n    @staticmethod\n    def to_unix_nano(self) -> int: ...\n    def to_datetime(self) -> datetime.datetime: ...\n    @staticmethod\n    def from_datetime(dt: datetime.datetime) -> TimeStamp: ...\n"
  },
  {
    "path": "third-party-stubs/msgpack/fallback.pyi",
    "content": "from __future__ import annotations\nfrom typing import Any, Callable, Dict, List, Optional, Tuple\n\nfrom typing_extensions import Protocol\n\nclass _FileLike(Protocol):\n    def read(self, n: int) -> bytes: ...\n\ndef unpackb(\n    packed: bytes,\n    file_like: Optional[_FileLike] = ...,\n    read_size: int = ...,\n    use_list: bool = ...,\n    raw: bool = ...,\n    timestamp: int = ...,\n    strict_map_key: bool = ...,\n    object_hook: Optional[Callable[[Dict[Any, Any]], Any]] = ...,\n    object_pairs_hook: Optional[Callable[[List[Tuple[Any, Any]]], Any]] = ...,\n    unicode_errors: Optional[str] = ...,\n    max_buffer_size: int = ...,\n    ext_hook: Callable[[int, bytes], Any] = ...,\n    max_str_len: int = ...,\n    max_bin_len: int = ...,\n    max_array_len: int = ...,\n    max_map_len: int = ...,\n    max_ext_len: int = ...,\n) -> Any: ...\n\nclass Unpacker:\n    def __init__(\n        self,\n        file_like: Optional[_FileLike] = ...,\n        read_size: int = ...,\n        use_list: bool = ...,\n        raw: bool = ...,\n        timestamp: int = ...,\n        strict_map_key: bool = ...,\n        object_hook: Optional[Callable[[Dict[Any, Any]], Any]] = ...,\n        object_pairs_hook: Optional[Callable[[List[Tuple[Any, Any]]], Any]] = ...,\n        unicode_errors: Optional[str] = ...,\n        max_buffer_size: int = ...,\n        ext_hook: Callable[[int, bytes], Any] = ...,\n        max_str_len: int = ...,\n        max_bin_len: int = ...,\n        max_array_len: int = ...,\n        max_map_len: int = ...,\n        max_ext_len: int = ...,\n    ): ...\n    def feed(self, next_bytes: bytes) -> None: ...\n    def read_bytes(self, n: int) -> bytearray: ...\n    def __iter__(self) -> Unpacker: ...\n    def __next__(self) -> Any: ...\n    def next(self) -> Any: ...\n    def skip(self) -> None: ...\n    def unpack(self) -> Any: ...\n    def read_array_header(self) -> Any: ...\n    def read_map_header(self) -> Any: ...\n    def tell(self) -> int: ...\n\nclass Packer:\n    def __init__(\n        self,\n        default: Optional[Callable[[Any], Any]] = ...,\n        use_single_float: bool = ...,\n        autoreset: bool = ...,\n        use_bin_type: bool = ...,\n        strict_types: bool = ...,\n        datetime: bool = ...,\n        unicode_errors: Optional[str] = ...,\n    ): ...\n    def pack(self, obj: Any) -> bytes: ...\n    def pack_map_pairs(self, pairs: Any) -> bytes: ...\n    def pack_array_header(self, n: int) -> bytes: ...\n    def pack_map_header(self, n: int) -> bytes: ...\n    def pack_ext_type(self, typecode: int, data: bytes) -> None: ...\n    def bytes(self) -> bytes: ...\n    def reset(self) -> None: ...\n    def getbuffer(self) -> memoryview: ...\n"
  },
  {
    "path": "third-party-stubs/snowplow_tracker/__init__.pyi",
    "content": "import logging\nfrom typing import Union, Optional, List, Any, Dict\n\nclass Subject:\n    def __init__(self) -> None: ...\n    def set_platform(self, value: Any): ...\n    def set_user_id(self, user_id: Any): ...\n    def set_screen_resolution(self, width: Any, height: Any): ...\n    def set_viewport(self, width: Any, height: Any): ...\n    def set_color_depth(self, depth: Any): ...\n    def set_timezone(self, timezone: Any): ...\n    def set_lang(self, lang: Any): ...\n    def set_domain_user_id(self, duid: Any): ...\n    def set_ip_address(self, ip: Any): ...\n    def set_useragent(self, ua: Any): ...\n    def set_network_user_id(self, nuid: Any): ...\n\nlogger: logging.Logger\n\nclass Emitter:\n    endpoint: str\n    def __init__(\n        self,\n        endpoint: str,\n        protocol: str = ...,\n        port: Optional[int] = ...,\n        method: str = ...,\n        buffer_size: Optional[int] = ...,\n        on_success: Optional[Any] = ...,\n        on_failure: Optional[Any] = ...,\n        byte_limit: Optional[int] = ...,\n    ) -> None: ...\n    def is_good_status_code(self, status_code: int) -> bool: ...\n\nclass Tracker:\n    emitters: Union[List[Any], Any] = ...\n    subject: Optional[Subject] = ...\n    namespace: Optional[str] = ...\n    app_id: Optional[str] = ...\n    encode_base64: bool = ...\n    def __init__(\n        self,\n        emitters: Union[List[Any], Any],\n        subject: Optional[Subject] = ...,\n        namespace: Optional[str] = ...,\n        app_id: Optional[str] = ...,\n        encode_base64: bool = ...,\n    ) -> None: ...\n    def set_subject(self, subject: Optional[Subject]): ...\n    def track_struct_event(\n        self,\n        category: str,\n        action: str,\n        label: Optional[str] = None,\n        property_: Optional[str] = None,\n        value: Optional[float] = None,\n        context: Optional[List[Any]] = None,\n        tstamp: Optional[Any] = None,\n    ): ...\n    def flush(self, asynchronous: bool = False): ...\n\nclass SelfDescribingJson:\n    schema: Any = ...\n    data: Any = ...\n    def __init__(self, schema: Any, data: Any) -> None: ...\n    def to_json(self) -> Dict[str, Any]: ...\n    def to_string(self) -> str: ...\n"
  },
  {
    "path": "third-party-stubs/sqlparse/__init__.pyi",
    "content": "from typing import Tuple\nfrom . import sql\nfrom . import tokens\n\ndef parse(sql: str) -> Tuple[sql.Statement]: ...\n"
  },
  {
    "path": "third-party-stubs/sqlparse/sql.pyi",
    "content": "from typing import Tuple, Iterable\n\nclass Token:\n    def __init__(self, ttype, value): ...\n    is_keyword: bool\n    is_whitespace: bool\n    normalized: str\n\nclass TokenList(Token):\n    tokens: Tuple[Token]\n    def __getitem__(self, key) -> Token: ...\n    def __iter__(self) -> Iterable[Token]: ...\n    def insert_before(self, where, token, skip_ws=True): ...\n    def insert_after(self, where, token, skip_ws=True): ...\n    def token_first(self) -> Token: ...\n\nclass Statement(TokenList): ...\n"
  },
  {
    "path": "third-party-stubs/sqlparse/tokens.pyi",
    "content": "class _TokenType(tuple): ...\n\nKeyword: _TokenType = _TokenType()\nPunctuation: _TokenType = _TokenType()\n"
  }
]